[PATCH] examples/demuxing_decoding: Fix invalidd API usage
We are not technically allowed to reuse the codec context found inside the AVStream in the format context. Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com> --- doc/examples/demuxing_decoding.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/doc/examples/demuxing_decoding.c b/doc/examples/demuxing_decoding.c index 0ef5df7..c69e07b 100644 --- a/doc/examples/demuxing_decoding.c +++ b/doc/examples/demuxing_decoding.c @@ -135,12 +135,11 @@ static int decode_packet(int *got_frame, int cached) return decoded; } -static int open_codec_context(int *stream_idx, - AVFormatContext *fmt_ctx, enum AVMediaType type) +static int open_codec_context(int *stream_idx, AVFormatContext *fmt_ctx, + enum AVMediaType type, AVCodecContext **dec_ctx) { int ret; AVStream *st; - AVCodecContext *dec_ctx = NULL; AVCodec *dec = NULL; AVDictionary *opts = NULL; @@ -153,19 +152,37 @@ static int open_codec_context(int *stream_idx, *stream_idx = ret; st = fmt_ctx->streams[*stream_idx]; - /* find decoder for the stream */ - dec_ctx = st->codec; - dec = avcodec_find_decoder(dec_ctx->codec_id); + /* find decoder for the stream as a sanity check */ + dec = avcodec_find_decoder(st->codec->codec_id); if (!dec) { fprintf(stderr, "Failed to find %s codec\n", av_get_media_type_string(type)); return AVERROR(EINVAL); } + /* + * Allocate our decoding context, since we are not allowed + * to reuse the one from the AVStream + */ + *dec_ctx = avcodec_alloc_context3(NULL); + if (!*dec_ctx) { + fprintf(stderr, "Failed to allocate %s codec context.\n", + av_get_media_type_string(type)); + return AVERROR(ENOMEM); + } + + /* Copy the properties over */ + ret = avcodec_copy_context(*dec_ctx, st->codec); + if (ret < 0) { + fprintf(stderr, "Failed to copy %s codec context.\n", + av_get_media_type_string(type)); + return AVERROR(EINVAL); + } + /* Init the decoders, with or without reference counting */ if (api_mode == API_MODE_NEW_API_REF_COUNT) av_dict_set(&opts, "refcounted_frames", "1", 0); - if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) { + if ((ret = avcodec_open2(*dec_ctx, dec, &opts)) < 0) { fprintf(stderr, "Failed to open %s codec\n", av_get_media_type_string(type)); return ret; @@ -252,9 +269,8 @@ int main (int argc, char **argv) exit(1); } - if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) { + if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO, &video_dec_ctx) >= 0) { video_stream = fmt_ctx->streams[video_stream_idx]; - video_dec_ctx = video_stream->codec; video_dst_file = fopen(video_dst_filename, "wb"); if (!video_dst_file) { @@ -274,9 +290,8 @@ int main (int argc, char **argv) video_dst_bufsize = ret; } - if (open_codec_context(&audio_stream_idx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) { + if (open_codec_context(&audio_stream_idx, fmt_ctx, AVMEDIA_TYPE_AUDIO, &audio_dec_ctx) >= 0) { audio_stream = fmt_ctx->streams[audio_stream_idx]; - audio_dec_ctx = audio_stream->codec; audio_dst_file = fopen(audio_dst_filename, "wb"); if (!audio_dst_file) { fprintf(stderr, "Could not open destination file %s\n", video_dst_filename); -- 1.9.rc1
On 2/6/2014 1:03 PM, Derek Buitenhuis wrote:
We are not technically allowed to reuse the codec context found inside the AVStream in the format context.
Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com> --- doc/examples/demuxing_decoding.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-)
Ping. - Derek
On Thu, Feb 06, 2014 at 01:03:44PM +0000, Derek Buitenhuis wrote:
We are not technically allowed to reuse the codec context found inside the AVStream in the format context.
AFAIK It was originally intended that such reuse is safe. iam not sure it actually is always with parsers and decoders did you had a specific case in mind where its not safe ? Iam asking because this makes the API more complex [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB The bravest are surely those who have the clearest vision of what is before them, glory and danger alike, and yet notwithstanding go out to meet it. -- Thucydides
On 2/28/2014 8:22 PM, Michael Niedermayer wrote:
AFAIK It was originally intended that such reuse is safe. iam not sure it actually is always with parsers and decoders did you had a specific case in mind where its not safe ? Iam asking because this makes the API more complex
Somehow I completely forgot about this patch. According to Anton, we should never reuse it from there. He give me the reason why, but it is buried in my IRC logs somewhere (old patch is old). I think this example update would also be nice, since it shows off another API func, but that's only my opinion. - Derek
On Fri, Feb 28, 2014 at 09:22:08PM +0100, Michael Niedermayer wrote:
On Thu, Feb 06, 2014 at 01:03:44PM +0000, Derek Buitenhuis wrote:
We are not technically allowed to reuse the codec context found inside the AVStream in the format context.
AFAIK It was originally intended that such reuse is safe. iam not sure it actually is always with parsers and decoders
did you had a specific case in mind where its not safe ? Iam asking because this makes the API more complex
ping [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB I do not agree with what you have to say, but I'll defend to the death your right to say it. -- Voltaire
On 2/6/2014 1:03 PM, Derek Buitenhuis wrote:
We are not technically allowed to reuse the codec context found inside the AVStream in the format context.
Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com> --- doc/examples/demuxing_decoding.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-)
Ping again. - Derek
On Thu, 6 Feb 2014 13:03:44 +0000 Derek Buitenhuis <derek.buitenhuis@gmail.com> wrote:
We are not technically allowed to reuse the codec context found inside the AVStream in the format context.
Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com> --- doc/examples/demuxing_decoding.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-)
diff --git a/doc/examples/demuxing_decoding.c b/doc/examples/demuxing_decoding.c index 0ef5df7..c69e07b 100644 --- a/doc/examples/demuxing_decoding.c +++ b/doc/examples/demuxing_decoding.c @@ -135,12 +135,11 @@ static int decode_packet(int *got_frame, int cached) return decoded; }
-static int open_codec_context(int *stream_idx, - AVFormatContext *fmt_ctx, enum AVMediaType type) +static int open_codec_context(int *stream_idx, AVFormatContext *fmt_ctx, + enum AVMediaType type, AVCodecContext **dec_ctx) { int ret; AVStream *st; - AVCodecContext *dec_ctx = NULL; AVCodec *dec = NULL; AVDictionary *opts = NULL;
@@ -153,19 +152,37 @@ static int open_codec_context(int *stream_idx, *stream_idx = ret; st = fmt_ctx->streams[*stream_idx];
- /* find decoder for the stream */ - dec_ctx = st->codec; - dec = avcodec_find_decoder(dec_ctx->codec_id); + /* find decoder for the stream as a sanity check */ + dec = avcodec_find_decoder(st->codec->codec_id); if (!dec) { fprintf(stderr, "Failed to find %s codec\n", av_get_media_type_string(type)); return AVERROR(EINVAL); }
What exactly does this sanity check? What happens if this code is removed, and there's no codec? Shouldn't one of the functions below simply fail?
+ /* + * Allocate our decoding context, since we are not allowed + * to reuse the one from the AVStream + */ + *dec_ctx = avcodec_alloc_context3(NULL); + if (!*dec_ctx) { + fprintf(stderr, "Failed to allocate %s codec context.\n", + av_get_media_type_string(type)); + return AVERROR(ENOMEM); + } + + /* Copy the properties over */ + ret = avcodec_copy_context(*dec_ctx, st->codec); + if (ret < 0) { + fprintf(stderr, "Failed to copy %s codec context.\n", + av_get_media_type_string(type)); + return AVERROR(EINVAL); + } + /* Init the decoders, with or without reference counting */ if (api_mode == API_MODE_NEW_API_REF_COUNT) av_dict_set(&opts, "refcounted_frames", "1", 0); - if ((ret = avcodec_open2(dec_ctx, dec, &opts)) < 0) { + if ((ret = avcodec_open2(*dec_ctx, dec, &opts)) < 0) { fprintf(stderr, "Failed to open %s codec\n", av_get_media_type_string(type)); return ret; @@ -252,9 +269,8 @@ int main (int argc, char **argv) exit(1); }
- if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO) >= 0) { + if (open_codec_context(&video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO, &video_dec_ctx) >= 0) { video_stream = fmt_ctx->streams[video_stream_idx]; - video_dec_ctx = video_stream->codec;
video_dst_file = fopen(video_dst_filename, "wb"); if (!video_dst_file) { @@ -274,9 +290,8 @@ int main (int argc, char **argv) video_dst_bufsize = ret; }
- if (open_codec_context(&audio_stream_idx, fmt_ctx, AVMEDIA_TYPE_AUDIO) >= 0) { + if (open_codec_context(&audio_stream_idx, fmt_ctx, AVMEDIA_TYPE_AUDIO, &audio_dec_ctx) >= 0) { audio_stream = fmt_ctx->streams[audio_stream_idx]; - audio_dec_ctx = audio_stream->codec; audio_dst_file = fopen(audio_dst_filename, "wb"); if (!audio_dst_file) { fprintf(stderr, "Could not open destination file %s\n", video_dst_filename);
On 6/12/2014 6:00 PM, wm4 wrote:
What exactly does this sanity check? What happens if this code is removed, and there's no codec? Shouldn't one of the functions below simply fail?
Not sure, but it's irrelevant to this patch. - Derek
participants (3)
-
Derek Buitenhuis -
Michael Niedermayer -
wm4