diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index ce30182ae8..b202dcb092 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -83,6 +83,7 @@ void avcodec_register_all(void) register_avcodec(&pbm_encoder); register_avcodec(&pam_encoder); register_avcodec(&huffyuv_encoder); + register_avcodec(&ffvhuff_encoder); register_avcodec(&asv1_encoder); register_avcodec(&asv2_encoder); register_avcodec(&ffv1_encoder); @@ -143,6 +144,7 @@ void avcodec_register_all(void) register_avcodec(&mace3_decoder); register_avcodec(&mace6_decoder); register_avcodec(&huffyuv_decoder); + register_avcodec(&ffvhuff_decoder); register_avcodec(&ffv1_decoder); register_avcodec(&snow_decoder); register_avcodec(&cyuv_decoder); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index a2c633bfea..bbc3cedf1f 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -17,7 +17,7 @@ extern "C" { #define FFMPEG_VERSION_INT 0x000409 #define FFMPEG_VERSION "0.4.9-pre1" -#define LIBAVCODEC_BUILD 4733 +#define LIBAVCODEC_BUILD 4734 #define LIBAVCODEC_VERSION_INT FFMPEG_VERSION_INT #define LIBAVCODEC_VERSION FFMPEG_VERSION @@ -99,6 +99,7 @@ enum CodecID { CODEC_ID_PGM, CODEC_ID_PGMYUV, CODEC_ID_PAM, + CODEC_ID_FFVHUFF, /* various pcm "codecs" */ CODEC_ID_PCM_S16LE= 0x10000, @@ -1816,6 +1817,7 @@ extern AVCodec msmpeg4v3_encoder; extern AVCodec wmv1_encoder; extern AVCodec wmv2_encoder; extern AVCodec huffyuv_encoder; +extern AVCodec ffvhuff_encoder; extern AVCodec h264_encoder; extern AVCodec asv1_encoder; extern AVCodec asv2_encoder; @@ -1858,6 +1860,7 @@ extern AVCodec mp3_decoder; extern AVCodec mace3_decoder; extern AVCodec mace6_decoder; extern AVCodec huffyuv_decoder; +extern AVCodec ffvhuff_decoder; extern AVCodec oggvorbis_decoder; extern AVCodec cyuv_decoder; extern AVCodec h264_decoder; diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c index 99925dde96..d529268ada 100644 --- a/libavcodec/huffyuv.c +++ b/libavcodec/huffyuv.c @@ -495,10 +495,6 @@ static int encode_init(AVCodecContext *avctx) switch(avctx->pix_fmt){ case PIX_FMT_YUV420P: - if(avctx->strict_std_compliance>=0){ - av_log(avctx, AV_LOG_ERROR, "Warning: YV12-huffyuv is not supported by windows huffyuv use a different colorspace or use (v)strict=-1\n"); - return -1; - } s->bitstream_bpp= 12; break; case PIX_FMT_YUV422P: @@ -512,22 +508,30 @@ static int encode_init(AVCodecContext *avctx) s->decorrelate= s->bitstream_bpp >= 24; s->predictor= avctx->prediction_method; s->interlaced= avctx->flags&CODEC_FLAG_INTERLACED_ME ? 1 : 0; - if(s->interlaced != ( height > 288 )){ - av_log(avctx, AV_LOG_INFO, "using huffyuv 2.2.0 or newer interlacing flag\n"); - } if(avctx->context_model==1){ s->context= avctx->context_model; - if(avctx->strict_std_compliance>=0){ - av_log(avctx, AV_LOG_ERROR, "Warning: per-frame huffman tables are not supported by windows huffyuv; use context=0 or use (v)strict=-1\n"); - return -1; - } if(s->flags & (CODEC_FLAG_PASS1|CODEC_FLAG_PASS2)){ av_log(avctx, AV_LOG_ERROR, "context=1 is not compatible with 2 pass huffyuv encoding\n"); return -1; } - av_log(avctx, AV_LOG_INFO, "using per-frame huffman tables\n"); }else s->context= 0; + if(avctx->codec->id==CODEC_ID_HUFFYUV){ + if(avctx->pix_fmt==PIX_FMT_YUV420P){ + av_log(avctx, AV_LOG_ERROR, "Error: YV12 is not supported by huffyuv; use vcodec=ffvhuff or format=422p\n"); + return -1; + } + if(avctx->context_model){ + av_log(avctx, AV_LOG_ERROR, "Error: per-frame huffman tables are not supported by huffyuv; use vcodec=ffvhuff\n"); + return -1; + } + if(s->interlaced != ( height > 288 )) + av_log(avctx, AV_LOG_INFO, "using huffyuv 2.2.0 or newer interlacing flag\n"); + }else if(avctx->strict_std_compliance>=0){ + av_log(avctx, AV_LOG_ERROR, "This codec is under development; files encoded with it may not be decodeable with future versions!!! Set vstrict=-1 to use it anyway.\n"); + return -1; + } + ((uint8_t*)avctx->extradata)[0]= s->predictor; ((uint8_t*)avctx->extradata)[1]= s->bitstream_bpp; ((uint8_t*)avctx->extradata)[2]= 0x20 | (s->interlaced ? 0x10 : 0); @@ -1172,6 +1176,14 @@ static const AVOption huffyuv_options[] = AVOPTION_END() }; +static const AVOption ffvhuff_options[] = +{ + AVOPTION_CODEC_INT("prediction_method", "prediction_method", prediction_method, 0, 2, 0), + AVOPTION_CODEC_INT("context_model", "context_model", context_model, 0, 2, 0), + AVOPTION_END() +}; + + AVCodec huffyuv_decoder = { "huffyuv", CODEC_TYPE_VIDEO, @@ -1185,6 +1197,19 @@ AVCodec huffyuv_decoder = { NULL }; +AVCodec ffvhuff_decoder = { + "ffvhuff", + CODEC_TYPE_VIDEO, + CODEC_ID_FFVHUFF, + sizeof(HYuvContext), + decode_init, + NULL, + decode_end, + decode_frame, + CODEC_CAP_DR1 | CODEC_CAP_DRAW_HORIZ_BAND, + NULL +}; + #ifdef CONFIG_ENCODERS AVCodec huffyuv_encoder = { @@ -1198,4 +1223,15 @@ AVCodec huffyuv_encoder = { .options = huffyuv_options, }; +AVCodec ffvhuff_encoder = { + "ffvhuff", + CODEC_TYPE_VIDEO, + CODEC_ID_FFVHUFF, + sizeof(HYuvContext), + encode_init, + encode_frame, + encode_end, + .options = ffvhuff_options, +}; + #endif //CONFIG_ENCODERS diff --git a/libavformat/avienc.c b/libavformat/avienc.c index ff15eac162..12d2fd7019 100644 --- a/libavformat/avienc.c +++ b/libavformat/avienc.c @@ -140,6 +140,7 @@ const CodecTag codec_bmp_tags[] = { { CODEC_ID_LJPEG, MKTAG('L', 'J', 'P', 'G') }, { CODEC_ID_MJPEG, MKTAG('J', 'P', 'G', 'L') }, /* Pegasus lossless JPEG */ { CODEC_ID_HUFFYUV, MKTAG('H', 'F', 'Y', 'U') }, + { CODEC_ID_FFVHUFF, MKTAG('F', 'F', 'V', 'H') }, { CODEC_ID_CYUV, MKTAG('C', 'Y', 'U', 'V') }, { CODEC_ID_RAWVIDEO, MKTAG('Y', '4', '2', '2') }, { CODEC_ID_RAWVIDEO, MKTAG('I', '4', '2', '0') }, diff --git a/libavformat/utils.c b/libavformat/utils.c index 6b3bd5db48..a20169d5d2 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -627,6 +627,7 @@ static int is_intra_only(AVCodecContext *enc){ case CODEC_ID_RAWVIDEO: case CODEC_ID_DVVIDEO: case CODEC_ID_HUFFYUV: + case CODEC_ID_FFVHUFF: case CODEC_ID_ASV1: case CODEC_ID_ASV2: case CODEC_ID_VCR1: diff --git a/tests/ffmpeg.regression.ref b/tests/ffmpeg.regression.ref index 6ea270f71a..698e9391ce 100644 --- a/tests/ffmpeg.regression.ref +++ b/tests/ffmpeg.regression.ref @@ -55,8 +55,8 @@ stddev: 2.07 PSNR:41.76 bytes:7602176 554440 ./data/a-odivx.mp4 e400c9175dd1811cdeee7be5555d33f1 *./data/out.yuv stddev: 7.99 PSNR:30.06 bytes:7602176 -08fd4be8dfff31783f83bfc59f8a6cdd *./data/a-huffyuv.avi -5986168 ./data/a-huffyuv.avi +b415b4d46c0c693d973dd45b1898de52 *./data/a-huffyuv.avi +7932708 ./data/a-huffyuv.avi 799d3db687f6cdd7a837ec156efc171f *./data/out.yuv stddev: 0.00 PSNR:99.99 bytes:7602176 788092f090eb1b11b78369f83e430fba *./data/a-mpeg4-rc.avi diff --git a/tests/regression.sh b/tests/regression.sh index 61ede6714f..fff692a59f 100755 --- a/tests/regression.sh +++ b/tests/regression.sh @@ -279,7 +279,7 @@ fi if [ -n "$do_huffyuv" ] ; then # huffyuv file=${outfile}huffyuv.avi -do_ffmpeg $file -y -qscale 10 -f pgmyuv -i $raw_src -an -vcodec huffyuv -strict -1 $file +do_ffmpeg $file -y -f pgmyuv -i $raw_src -an -vcodec huffyuv -pix_fmt yuv422p $file # huffyuv decoding do_ffmpeg $raw_dst -y -i $file -f rawvideo -strict -1 $raw_dst diff --git a/tests/rotozoom.regression.ref b/tests/rotozoom.regression.ref index 5182102ceb..59f3242763 100644 --- a/tests/rotozoom.regression.ref +++ b/tests/rotozoom.regression.ref @@ -55,8 +55,8 @@ e47f46468b79641e13bb9609be2db5ca *./data/a-odivx.mp4 120196 ./data/a-odivx.mp4 8b7657a7f9fc7298cc016abb466d1d19 *./data/out.yuv stddev: 5.34 PSNR:33.56 bytes:7602176 -40ddd4437246784a9a7ffa582f99b8d9 *./data/a-huffyuv.avi -4987020 ./data/a-huffyuv.avi +eb6a67c8bc0df5dd1bef308e776fe193 *./data/a-huffyuv.avi +6454196 ./data/a-huffyuv.avi dde5895817ad9d219f79a52d0bdfb001 *./data/out.yuv stddev: 0.00 PSNR:99.99 bytes:7602176 e9ce342786f760b8e0a62a8fb2601628 *./data/a-mpeg4-rc.avi