From 7ebfc0ea630e38a9c9653cdc9fe46f8b00e915a9 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 14 Dec 2003 01:42:00 +0000 Subject: [PATCH] error concealment regression test Originally committed as revision 2606 to svn://svn.ffmpeg.org/ffmpeg/trunk --- ffmpeg.c | 8 ++++++++ libavcodec/avcodec.h | 9 ++++++++- libavcodec/mpegvideo.c | 12 ++++++++++++ tests/ffmpeg.regression.ref | 3 +++ tests/regression.sh | 11 +++++++++++ tests/rotozoom.regression.ref | 3 +++ 6 files changed, 45 insertions(+), 1 deletion(-) diff --git a/ffmpeg.c b/ffmpeg.c index e8c557ccdc..86ee13bfd2 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -125,6 +125,7 @@ static int dct_algo = 0; static int idct_algo = 0; static int use_part = 0; static int packet_size = 0; +static int error_rate = 0; static int strict = 0; static int debug = 0; extern int loop_input; /* currently a hack */ @@ -1855,6 +1856,11 @@ static void opt_packet_size(const char *arg) packet_size= atoi(arg); } +static void opt_error_rate(const char *arg) +{ + error_rate= atoi(arg); +} + static void opt_strict(const char *arg) { strict= atoi(arg); @@ -2339,6 +2345,7 @@ static void opt_output_file(const char *filename) video_enc->dct_algo = dct_algo; video_enc->idct_algo = idct_algo; video_enc->strict_std_compliance = strict; + video_enc->error_rate = error_rate; if(packet_size){ video_enc->rtp_mode= 1; video_enc->rtp_payload_size= packet_size; @@ -2889,6 +2896,7 @@ const OptionDef options[] = { { "part", OPT_BOOL | OPT_EXPERT | OPT_VIDEO, {(void*)&use_part}, "use data partitioning (MPEG4)" }, { "bug", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_workaround_bugs}, "workaround not auto detected encoder bugs", "param" }, { "ps", HAS_ARG | OPT_EXPERT, {(void*)opt_packet_size}, "set packet size in bits", "size" }, + { "error", HAS_ARG | OPT_EXPERT, {(void*)opt_error_rate}, "error rate", "rate" }, { "strict", HAS_ARG | OPT_EXPERT | OPT_VIDEO, {(void*)opt_strict}, "how strictly to follow the standarts", "strictness" }, { "sameq", OPT_BOOL | OPT_VIDEO, {(void*)&same_quality}, "use same video quality as source (implies VBR)" }, diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 77942872fe..de4c3f03d8 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -17,7 +17,7 @@ extern "C" { #define FFMPEG_VERSION_INT 0x000408 #define FFMPEG_VERSION "0.4.8" -#define LIBAVCODEC_BUILD 4695 +#define LIBAVCODEC_BUILD 4696 #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT #define LIBAVCODEC_VERSION FFMPEG_VERSION @@ -1461,6 +1461,13 @@ typedef struct AVCodecContext { * - decoding: set by user. */ int flags2; + + /** + * simulates errors in the bitstream to test error concealment. + * - encoding: set by user. + * - decoding: unused. + */ + int error_rate; } AVCodecContext; diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 7c515aa7fc..5dbe9be91b 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -4002,6 +4002,18 @@ static void encode_picture(MpegEncContext *s, int picture_number) assert((get_bit_count(&s->pb)&7) == 0); current_packet_size= pbBufPtr(&s->pb) - s->ptr_lastgob; + + if(s->avctx->error_rate && s->resync_mb_x + s->resync_mb_y > 0){ + int r= get_bit_count(&s->pb)/8 + s->picture_number + s->codec_id + s->mb_x + s->mb_y; + int d= 100 / s->avctx->error_rate; + if(r % d == 0){ + current_packet_size=0; +#ifndef ALT_BITSTREAM_WRITER + s->pb.buf_ptr= s->ptr_lastgob; +#endif + assert(pbBufPtr(&s->pb) == s->ptr_lastgob); + } + } if (s->avctx->rtp_callback) s->avctx->rtp_callback(s->ptr_lastgob, current_packet_size, 0); diff --git a/tests/ffmpeg.regression.ref b/tests/ffmpeg.regression.ref index cc6738eb1f..211d907743 100644 --- a/tests/ffmpeg.regression.ref +++ b/tests/ffmpeg.regression.ref @@ -38,6 +38,9 @@ stddev: 10.18 bytes:7145472 b3f1425e266569d5d726b88eadc13dd4 *./data/a-mpeg4-adv.avi fb61365b22c947adbaeab74478579020 *./data/out.yuv stddev: 7.31 bytes:7602176 +25ec5ab399fd4db0c8aaea78cb692611 *./data/a-error-mpeg4-adv.avi +bd441fc1e2fb9a3c0bdc9c5f1ed25ef0 *./data/out.yuv +stddev: 13.57 bytes:7602176 328ebd044362116e274739e23c482ee7 *./data/a-mpeg1b.mpg 41b3baa7d8c17202e6577947ac37cad0 *./data/out.yuv stddev: 6.32 bytes:6842368 diff --git a/tests/regression.sh b/tests/regression.sh index d410da3a30..0a895f6f45 100755 --- a/tests/regression.sh +++ b/tests/regression.sh @@ -53,6 +53,7 @@ else do_asv2=y do_flv=y do_ffv1=y + do_error=y fi @@ -243,6 +244,16 @@ do_ffmpeg $file -y -qscale 9 -4mv -hq -part -ps 200 -aic -f pgmyuv -i $raw_src - do_ffmpeg $raw_dst -y -i $file -f rawvideo $raw_dst fi +################################### +if [ -n "$do_error" ] ; then +# damaged mpeg4 +file=${outfile}error-mpeg4-adv.avi +do_ffmpeg $file -y -qscale 7 -4mv -mbd 2 -part -ps 250 -error 10 -aic -f pgmyuv -i $raw_src -an -vcodec mpeg4 $file + +# damaged mpeg4 decoding +do_ffmpeg $raw_dst -y -i $file -f rawvideo $raw_dst +fi + ################################### if [ -n "$do_mpeg1b" ] ; then # mpeg1 diff --git a/tests/rotozoom.regression.ref b/tests/rotozoom.regression.ref index f5f2a09fdd..5173c00a46 100644 --- a/tests/rotozoom.regression.ref +++ b/tests/rotozoom.regression.ref @@ -38,6 +38,9 @@ stddev: 4.20 bytes:7145472 742ffadf3c309d2c4ac888a6a0905bf9 *./data/a-mpeg4-adv.avi b02f71e91e9368ce94814ab3d74f91ba *./data/out.yuv stddev: 4.97 bytes:7602176 +f2888ab759ac28aba85a16d3d54b80d0 *./data/a-error-mpeg4-adv.avi +93ab926aad2e658a5bb00c25b7cefdab *./data/out.yuv +stddev: 5.22 bytes:7602176 671802a2c5078e69f7f422765ea87f2a *./data/a-mpeg1b.mpg 71e80b8ff8da567f1bbff000cd925627 *./data/out.yuv stddev: 4.07 bytes:6842368