From 3c7fa664af5b3c2abbedd489142a0f9b6690b364 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 17 Jul 2011 13:59:04 +0200 Subject: [PATCH 01/10] lavf: add forgotten attribute_deprecated to av_find_stream_info() --- libavformat/avformat.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 38bb86592e..cfdbd11b36 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1114,6 +1114,7 @@ AVFormatContext *avformat_alloc_context(void); * * @deprecated use avformat_find_stream_info. */ +attribute_deprecated int av_find_stream_info(AVFormatContext *ic); #endif From 7cea06d135c91bf21f3d2a095c2f610594bed7df Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sun, 17 Jul 2011 01:30:43 +0200 Subject: [PATCH 02/10] cmdutils: clarify documentation for setup_find_stream_info_opts() Signed-off-by: Anton Khirnov --- cmdutils.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cmdutils.h b/cmdutils.h index a47f15785d..90e0a25850 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -153,8 +153,16 @@ void parse_options(int argc, char **argv, const OptionDef *options, */ AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, int encoder); -/* - * Setup AVCodecContext options for avformat_find_stream_info. +/** + * Setup AVCodecContext options for avformat_find_stream_info(). + * + * Create an array of dictionaries, one dictionary for each stream + * contained in s. + * Each dictionary will contain the options from codec_opts which can + * be applied to the corresponding stream codec context. + * + * @return pointer to the created array of dictionaries, NULL if it + * cannot be created */ AVDictionary **setup_find_stream_info_opts(AVFormatContext *s); From ce23ca814b0fa6327b21e03be09b81f9b0d7113d Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sun, 17 Jul 2011 01:20:50 +0200 Subject: [PATCH 03/10] cmdutils: clarify documentation for filter_codec_opts() Signed-off-by: Anton Khirnov --- cmdutils.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmdutils.h b/cmdutils.h index 90e0a25850..dcd0b79a1f 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -150,6 +150,12 @@ void parse_options(int argc, char **argv, const OptionDef *options, /** * Filter out options for given codec. + * + * Create a new options dictionary containing only the options from + * opts which apply to the codec with ID codec_id. + * + * @param encoder if non-zero the codec is an encoder, otherwise is a decoder + * @return a pointer to the created dictionary */ AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, int encoder); From 8ec19f84e12283dd79c16782ab55dd3b4e1ded66 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sun, 17 Jul 2011 16:19:28 +0200 Subject: [PATCH 04/10] cmdutils: add codec_opts parameter to setup_find_stream_info_opts() Avoid brittle and obfuscating reference to a global. Signed-off-by: Anton Khirnov --- cmdutils.c | 2 +- cmdutils.h | 2 +- ffmpeg.c | 2 +- ffplay.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cmdutils.c b/cmdutils.c index 19c5d72857..f6e50fa534 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -806,7 +806,7 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, int e return ret; } -AVDictionary **setup_find_stream_info_opts(AVFormatContext *s) +AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts) { int i; AVDictionary **opts; diff --git a/cmdutils.h b/cmdutils.h index dcd0b79a1f..7769194b9c 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -170,7 +170,7 @@ AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id, int e * @return pointer to the created array of dictionaries, NULL if it * cannot be created */ -AVDictionary **setup_find_stream_info_opts(AVFormatContext *s); +AVDictionary **setup_find_stream_info_opts(AVFormatContext *s, AVDictionary *codec_opts); /** * Print an error message to stderr, indicating filename and a human diff --git a/ffmpeg.c b/ffmpeg.c index 776cfabacd..c76aeacbe6 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -3252,7 +3252,7 @@ static int opt_input_file(const char *opt, const char *filename) } /* Set AVCodecContext options for avformat_find_stream_info */ - opts = setup_find_stream_info_opts(ic); + opts = setup_find_stream_info_opts(ic, codec_opts); orig_nb_streams = ic->nb_streams; /* If not enough info to get the stream parameters, we decode the diff --git a/ffplay.c b/ffplay.c index 77c9d4b2f3..bef75fe574 100644 --- a/ffplay.c +++ b/ffplay.c @@ -2343,7 +2343,7 @@ static int decode_thread(void *arg) if(genpts) ic->flags |= AVFMT_FLAG_GENPTS; - opts = setup_find_stream_info_opts(ic); + opts = setup_find_stream_info_opts(ic, codec_opts); orig_nb_streams = ic->nb_streams; err = avformat_find_stream_info(ic, opts); From 22b203baf81f8efcf134d2d27732ee6e842fdcb6 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 17 Jul 2011 14:54:20 +0200 Subject: [PATCH 05/10] doc: document using AVOptions in fftools. --- doc/fftools-common-opts.texi | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi index 3a1cb3b23c..fec61cf8c9 100644 --- a/doc/fftools-common-opts.texi +++ b/doc/fftools-common-opts.texi @@ -91,3 +91,28 @@ The use of the environment variable @env{NO_COLOR} is deprecated and will be dropped in a following Libav version. @end table + +@section AVOptions + +These options are provided directly by the libavformat and libavcodec +libraries. To see the list of available AVOptions, use the +@option{-help} option. They are separated into two categories: +@table @option +@item generic +Can be set for any container or codec. Generic options are listed under +AVFormatContext options for containers and under AVCodecContext options +for codecs. +@item private +Are specific to the given container or codec. Private options are listed +under their corresponding containers/codecs. +@end table + +For example to write an ID3v2.3 header instead of a default ID3v2.4 to +an MP3 file, use the @option{id3v2_version} private option of the MP3 +muxer: +@example +ffmpeg -i input.flac -id3v2_version 3 out.mp3 +@end example + +Note -nooption syntax cannot be used for boolean AVOptions, use -option +0/-option 1. From e0e65ddb883427aafbcef1ae52248f4d1e087963 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 28 Jul 2011 17:43:24 +0200 Subject: [PATCH 06/10] doc/fftools-common-opts: wording fixes missing from the previous commit. --- doc/fftools-common-opts.texi | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi index fec61cf8c9..ba91b87e72 100644 --- a/doc/fftools-common-opts.texi +++ b/doc/fftools-common-opts.texi @@ -94,17 +94,17 @@ will be dropped in a following Libav version. @section AVOptions -These options are provided directly by the libavformat and libavcodec -libraries. To see the list of available AVOptions, use the +These options are provided directly by the libavformat, libavdevice and +libavcodec libraries. To see the list of available AVOptions, use the @option{-help} option. They are separated into two categories: @table @option @item generic -Can be set for any container or codec. Generic options are listed under -AVFormatContext options for containers and under AVCodecContext options -for codecs. +These options can be set for any container, codec or device. Generic options are +listed under AVFormatContext options for containers/devices and under +AVCodecContext options for codecs. @item private -Are specific to the given container or codec. Private options are listed -under their corresponding containers/codecs. +These options are specific to the given container, device or codec. Private +options are listed under their corresponding containers/devices/codecs. @end table For example to write an ID3v2.3 header instead of a default ID3v2.4 to From 8dcf5184307f072d55fb29373be05ef8b0fd02df Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 26 Jul 2011 10:58:29 -0700 Subject: [PATCH 07/10] vp3/theora: flush after seek. --- libavcodec/vp3.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index c3dff7f89f..c117a64084 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -2321,6 +2321,26 @@ static av_cold int theora_decode_init(AVCodecContext *avctx) return vp3_decode_init(avctx); } +static void vp3_decode_flush(AVCodecContext *avctx) +{ + Vp3DecodeContext *s = avctx->priv_data; + + if (s->golden_frame.data[0]) { + if (s->golden_frame.data[0] == s->last_frame.data[0]) + memset(&s->last_frame, 0, sizeof(AVFrame)); + if (s->current_frame.data[0] == s->golden_frame.data[0]) + memset(&s->current_frame, 0, sizeof(AVFrame)); + ff_thread_release_buffer(avctx, &s->golden_frame); + } + if (s->last_frame.data[0]) { + if (s->current_frame.data[0] == s->last_frame.data[0]) + memset(&s->current_frame, 0, sizeof(AVFrame)); + ff_thread_release_buffer(avctx, &s->last_frame); + } + if (s->current_frame.data[0]) + ff_thread_release_buffer(avctx, &s->current_frame); +} + AVCodec ff_theora_decoder = { "theora", AVMEDIA_TYPE_VIDEO, @@ -2332,6 +2352,7 @@ AVCodec ff_theora_decoder = { vp3_decode_frame, CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS, NULL, + .flush = vp3_decode_flush, .long_name = NULL_IF_CONFIG_SMALL("Theora"), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context) }; @@ -2348,6 +2369,7 @@ AVCodec ff_vp3_decoder = { vp3_decode_frame, CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_FRAME_THREADS, NULL, + .flush = vp3_decode_flush, .long_name = NULL_IF_CONFIG_SMALL("On2 VP3"), .update_thread_context = ONLY_IF_THREADS_ENABLED(vp3_update_thread_context) }; From 6c3257654801d525aa61e6fb46022a2a3b12c074 Mon Sep 17 00:00:00 2001 From: Jason Garrett-Glaser Date: Tue, 26 Jul 2011 19:08:05 -0700 Subject: [PATCH 08/10] H.264: optimize CABAC x86 asm for Atom --- libavcodec/h264_cabac.c | 2 +- libavcodec/x86/cabac.h | 15 +++++++-------- libavcodec/x86/h264_i386.h | 11 ++++------- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index f7cec5d03e..065b6e85e1 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -1649,7 +1649,7 @@ static av_always_inline void decode_cabac_residual_internal( H264Context *h, DCT const uint8_t *sig_off = significant_coeff_flag_offset_8x8[MB_FIELD]; #if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) coeff_count= decode_significance_8x8_x86(CC, significant_coeff_ctx_base, index, - last_coeff_ctx_base-significant_coeff_ctx_base, sig_off); + last_coeff_ctx_base, sig_off); } else { coeff_count= decode_significance_x86(CC, max_coeff, significant_coeff_ctx_base, index, last_coeff_ctx_base-significant_coeff_ctx_base); diff --git a/libavcodec/x86/cabac.h b/libavcodec/x86/cabac.h index 52bea9c53d..1ad74ff3e0 100644 --- a/libavcodec/x86/cabac.h +++ b/libavcodec/x86/cabac.h @@ -34,8 +34,8 @@ "cmova %%ecx , "range" \n\t"\ "sbb %%ecx , %%ecx \n\t"\ "and %%ecx , "tmp" \n\t"\ - "sub "tmp" , "low" \n\t"\ - "xor %%ecx , "ret" \n\t" + "xor %%ecx , "ret" \n\t"\ + "sub "tmp" , "low" \n\t" #else /* HAVE_FAST_CMOV */ #define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp)\ "mov "tmp" , %%ecx \n\t"\ @@ -62,21 +62,20 @@ "movzbl " MANGLE(ff_h264_norm_shift) "("range"), %%ecx \n\t"\ "shl %%cl , "range" \n\t"\ "movzbl "MANGLE(ff_h264_mlps_state)"+128("ret"), "tmp" \n\t"\ - "mov "tmpbyte" , "statep" \n\t"\ "shl %%cl , "low" \n\t"\ + "mov "tmpbyte" , "statep" \n\t"\ "test "lowword" , "lowword" \n\t"\ " jnz 1f \n\t"\ "mov "byte"("cabac"), %%"REG_c" \n\t"\ + "add $2 , "byte "("cabac") \n\t"\ "movzwl (%%"REG_c") , "tmp" \n\t"\ - "bswap "tmp" \n\t"\ - "shr $15 , "tmp" \n\t"\ - "sub $0xFFFF , "tmp" \n\t"\ - "add $2 , %%"REG_c" \n\t"\ - "mov %%"REG_c" , "byte "("cabac") \n\t"\ "lea -1("low") , %%ecx \n\t"\ "xor "low" , %%ecx \n\t"\ "shr $15 , %%ecx \n\t"\ + "bswap "tmp" \n\t"\ + "shr $15 , "tmp" \n\t"\ "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t"\ + "sub $0xFFFF , "tmp" \n\t"\ "neg %%ecx \n\t"\ "add $7 , %%ecx \n\t"\ "shl %%cl , "tmp" \n\t"\ diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h index 9c86210371..0151cd59a8 100644 --- a/libavcodec/x86/h264_i386.h +++ b/libavcodec/x86/h264_i386.h @@ -72,8 +72,7 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, "test $1, %4 \n\t" " jnz 4f \n\t" - "add $4, %0 \n\t" - "mov %0, %2 \n\t" + "add $4, %2 \n\t" "3: \n\t" "add $1, %1 \n\t" @@ -101,7 +100,7 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, static int decode_significance_8x8_x86(CABACContext *c, uint8_t *significant_coeff_ctx_base, - int *index, x86_reg last_off, const uint8_t *sig_off){ + int *index, uint8_t *last_coeff_ctx_base, const uint8_t *sig_off){ int minusindex= 4-(intptr_t)index; int bit; x86_reg coeff_count; @@ -128,7 +127,6 @@ static int decode_significance_8x8_x86(CABACContext *c, " jz 3f \n\t" "movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%k6), %k6\n\t" - "add %9, %6 \n\t" "add %11, %6 \n\t" BRANCHLESS_GET_CABAC("%4", "%7", "(%6)", "%3", @@ -141,8 +139,7 @@ static int decode_significance_8x8_x86(CABACContext *c, "test $1, %4 \n\t" " jnz 4f \n\t" - "add $4, %0 \n\t" - "mov %0, %2 \n\t" + "add $4, %2 \n\t" "3: \n\t" "addl $1, %k6 \n\t" @@ -159,7 +156,7 @@ static int decode_significance_8x8_x86(CABACContext *c, "movl %3, %a13(%7) \n\t" :"=&q"(coeff_count),"+m"(last), "+m"(index), "=&r"(low), "=&r"(bit), "=&r"(range), "=&r"(state) - :"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_off), + :"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_coeff_ctx_base), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) : "%"REG_c, "memory" From f5f004bc5a40e5a5de62bd5e2818ab5de7f6bf21 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Thu, 28 Jul 2011 20:21:33 +0100 Subject: [PATCH 09/10] x86: cabac: don't load/store context values in asm Inspection of compiled code shows gcc handles these fine on its own. Benchmarking also shows no measurable speed difference. Removing the remaining cases in get_cabac_bypass_sign_x86() does cause more substantial changes to the compiled code with uncertain impact. Signed-off-by: Mans Rullgard --- libavcodec/x86/cabac.h | 12 +++--------- libavcodec/x86/h264_i386.h | 32 +++++++------------------------- 2 files changed, 10 insertions(+), 34 deletions(-) diff --git a/libavcodec/x86/cabac.h b/libavcodec/x86/cabac.h index 1ad74ff3e0..ae3f4b6e9e 100644 --- a/libavcodec/x86/cabac.h +++ b/libavcodec/x86/cabac.h @@ -87,19 +87,13 @@ static av_always_inline int get_cabac_inline_x86(CABACContext *c, uint8_t *const state) { - int bit, low, range, tmp; + int bit, tmp; __asm__ volatile( - "movl %a6(%5), %2 \n\t" - "movl %a7(%5), %1 \n\t" BRANCHLESS_GET_CABAC("%0", "%5", "(%4)", "%1", "%w1", "%2", - "%3", "%b3", "%a8") - "movl %2, %a6(%5) \n\t" - "movl %1, %a7(%5) \n\t" - - :"=&r"(bit), "=&r"(low), "=&r"(range), "=&q"(tmp) + "%3", "%b3", "%a6") + :"=&r"(bit), "+&r"(c->low), "+&r"(c->range), "=&q"(tmp) :"r"(state), "r"(c), - "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) : "%"REG_c, "memory" ); diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h index 0151cd59a8..eb77002ce0 100644 --- a/libavcodec/x86/h264_i386.h +++ b/libavcodec/x86/h264_i386.h @@ -45,23 +45,18 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, int minusindex= 4-(intptr_t)index; int bit; x86_reg coeff_count; - int low; - int range; __asm__ volatile( - "movl %a11(%6), %5 \n\t" - "movl %a12(%6), %3 \n\t" - "2: \n\t" BRANCHLESS_GET_CABAC("%4", "%6", "(%1)", "%3", - "%w3", "%5", "%k0", "%b0", "%a13") + "%w3", "%5", "%k0", "%b0", "%a11") "test $1, %4 \n\t" " jz 3f \n\t" "add %10, %1 \n\t" BRANCHLESS_GET_CABAC("%4", "%6", "(%1)", "%3", - "%w3", "%5", "%k0", "%b0", "%a13") + "%w3", "%5", "%k0", "%b0", "%a11") "sub %10, %1 \n\t" "mov %2, %0 \n\t" @@ -85,13 +80,9 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, "4: \n\t" "add %9, %k0 \n\t" "shr $2, %k0 \n\t" - - "movl %5, %a11(%6) \n\t" - "movl %3, %a12(%6) \n\t" :"=&q"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index), - "=&r"(low), "=&r"(bit), "=&r"(range) + "+&r"(c->low), "=&r"(bit), "+&r"(c->range) :"r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off), - "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) : "%"REG_c, "memory" ); @@ -104,14 +95,9 @@ static int decode_significance_8x8_x86(CABACContext *c, int minusindex= 4-(intptr_t)index; int bit; x86_reg coeff_count; - int low; - int range; x86_reg last=0; x86_reg state; __asm__ volatile( - "movl %a12(%7), %5 \n\t" - "movl %a13(%7), %3 \n\t" - "mov %1, %6 \n\t" "2: \n\t" @@ -120,7 +106,7 @@ static int decode_significance_8x8_x86(CABACContext *c, "add %9, %6 \n\t" BRANCHLESS_GET_CABAC("%4", "%7", "(%6)", "%3", - "%w3", "%5", "%k0", "%b0", "%a14") + "%w3", "%5", "%k0", "%b0", "%a12") "mov %1, %k6 \n\t" "test $1, %4 \n\t" @@ -130,7 +116,7 @@ static int decode_significance_8x8_x86(CABACContext *c, "add %11, %6 \n\t" BRANCHLESS_GET_CABAC("%4", "%7", "(%6)", "%3", - "%w3", "%5", "%k0", "%b0", "%a14") + "%w3", "%5", "%k0", "%b0", "%a12") "mov %2, %0 \n\t" "mov %1, %k6 \n\t" @@ -151,13 +137,9 @@ static int decode_significance_8x8_x86(CABACContext *c, "4: \n\t" "addl %8, %k0 \n\t" "shr $2, %k0 \n\t" - - "movl %5, %a12(%7) \n\t" - "movl %3, %a13(%7) \n\t" - :"=&q"(coeff_count),"+m"(last), "+m"(index), "=&r"(low), "=&r"(bit), - "=&r"(range), "=&r"(state) + :"=&q"(coeff_count),"+m"(last), "+m"(index), "+&r"(c->low), "=&r"(bit), + "+&r"(c->range), "=&r"(state) :"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_coeff_ctx_base), - "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) : "%"REG_c, "memory" ); From 2a11952f457658d58303c8e5b4e10fb4599eef4f Mon Sep 17 00:00:00 2001 From: Dustin Brody Date: Wed, 27 Jul 2011 19:09:45 -0400 Subject: [PATCH 10/10] h263dec: Propagate AV_LOG_ERRORs from slice decoding through frame decoding with sufficient error recognition Signed-off-by: Ronald S. Bultje --- doc/ffmpeg.texi | 2 ++ libavcodec/avcodec.h | 1 + libavcodec/h263dec.c | 6 +++--- libavcodec/options.c | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 5a783e3c15..4dca5d8991 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -470,6 +470,8 @@ FF_ER_COMPLIANT FF_ER_AGGRESSIVE @item 4 FF_ER_VERY_AGGRESSIVE +@item 5 +FF_ER_EXPLODE @end table @item -ec @var{bit_mask} diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index b6cac7c77d..75c107c159 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1446,6 +1446,7 @@ typedef struct AVCodecContext { #define FF_ER_COMPLIANT 2 #define FF_ER_AGGRESSIVE 3 #define FF_ER_VERY_AGGRESSIVE 4 +#define FF_ER_EXPLODE 5 /** * Called at the beginning of each frame to get a buffer for it. diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 6eea8def11..a19e55c6ac 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -638,7 +638,7 @@ retry: s->mb_x=0; s->mb_y=0; - decode_slice(s); + ret = decode_slice(s); while(s->mb_ymb_height){ if(s->msmpeg4_version){ if(s->slice_height==0 || s->mb_x!=0 || (s->mb_y%s->slice_height)!=0 || get_bits_count(&s->gb) > s->gb.size_in_bits) @@ -654,7 +654,7 @@ retry: if(s->msmpeg4_version<4 && s->h263_pred) ff_mpeg4_clean_buffers(s); - decode_slice(s); + if (decode_slice(s) < 0) ret = AVERROR_INVALIDDATA; } if (s->msmpeg4_version && s->msmpeg4_version<4 && s->pict_type==AV_PICTURE_TYPE_I) @@ -722,7 +722,7 @@ assert(s->current_picture.pict_type == s->pict_type); av_log(avctx, AV_LOG_DEBUG, "%"PRId64"\n", rdtsc()-time); #endif - return get_consumed_bytes(s, buf_size); + return (ret && avctx->error_recognition >= FF_ER_EXPLODE)?ret:get_consumed_bytes(s, buf_size); } AVCodec ff_h263_decoder = { diff --git a/libavcodec/options.c b/libavcodec/options.c index 4869046665..0f0ca2aaa3 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -184,6 +184,7 @@ static const AVOption options[]={ {"compliant", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_ER_COMPLIANT }, INT_MIN, INT_MAX, V|D, "er"}, {"aggressive", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_ER_AGGRESSIVE }, INT_MIN, INT_MAX, V|D, "er"}, {"very_aggressive", NULL, 0, FF_OPT_TYPE_CONST, {.dbl = FF_ER_VERY_AGGRESSIVE }, INT_MIN, INT_MAX, V|D, "er"}, +{"explode", "abort decoding on error recognition", 0, FF_OPT_TYPE_CONST, {.dbl = FF_ER_EXPLODE }, INT_MIN, INT_MAX, V|D, "er"}, {"has_b_frames", NULL, OFFSET(has_b_frames), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX}, {"block_align", NULL, OFFSET(block_align), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX}, {"parse_only", NULL, OFFSET(parse_only), FF_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX},