diff --git a/Changelog b/Changelog index 80f72c91a7..5d02019758 100644 --- a/Changelog +++ b/Changelog @@ -33,6 +33,8 @@ version - SFTP protocol (via libssh) - libx264: add ability to encode in YUVJ422P and YUVJ444P - Fraps: use BT.709 colorspace by default for yuv, as reference fraps decoder does +- make decoding alpha optional for prores, ffv1 and vp6 by setting + the skip_alpha flag. version 2.0: diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 997a00cbf6..61048f4dcf 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -2865,6 +2865,19 @@ typedef struct AVCodecContext { #define FF_SUB_CHARENC_MODE_AUTOMATIC 0 ///< libavcodec will select the mode itself #define FF_SUB_CHARENC_MODE_PRE_DECODER 1 ///< the AVPacket data needs to be recoded to UTF-8 before being fed to the decoder, requires iconv + /** + * Skip processing alpha if supported by codec. + * Note that if the format uses pre-multiplied alpha (common with VP6, + * and recommended due to better video quality/compression) + * the image will look as if alpha-blended onto a black background. + * However for formats that do not use pre-multiplied alpha + * there might be serious artefacts (though e.g. libswscale currently + * assumes pre-multiplied alpha anyway). + * + * - decoding: set by user + * - encoding: unused + */ + int skip_alpha; } AVCodecContext; AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx); diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index 87cc2ca450..57a566bb62 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -641,6 +641,7 @@ static int read_header(FFV1Context *f) } if (f->colorspace == 0) { + if (f->avctx->skip_alpha) f->transparency = 0; if (!f->transparency && !f->chroma_planes) { if (f->avctx->bits_per_raw_sample <= 8) f->avctx->pix_fmt = AV_PIX_FMT_GRAY8; diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index e9cdfc4ac4..8c025fe076 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -380,6 +380,7 @@ static const AVOption avcodec_options[] = { {"auto", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_AUTOMATIC}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"}, {"pre_decoder", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_SUB_CHARENC_MODE_PRE_DECODER}, INT_MIN, INT_MAX, S|D, "sub_charenc_mode"}, {"refcounted_frames", NULL, OFFSET(refcounted_frames), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, A|V|D }, +{"skip_alpha", "Skip processing alpha", OFFSET(skip_alpha), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, V|D }, {NULL}, }; diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c index 9a8861cb22..4950652ed9 100644 --- a/libavcodec/proresdec2.c +++ b/libavcodec/proresdec2.c @@ -97,6 +97,7 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, av_log(avctx, AV_LOG_ERROR, "Invalid alpha mode %d\n", ctx->alpha_info); return AVERROR_INVALIDDATA; } + if (avctx->skip_alpha) ctx->alpha_info = 0; av_dlog(avctx, "frame type %d\n", ctx->frame_type); diff --git a/libavcodec/proresdec_lgpl.c b/libavcodec/proresdec_lgpl.c index 2fef2c6e43..04aeb16ab5 100644 --- a/libavcodec/proresdec_lgpl.c +++ b/libavcodec/proresdec_lgpl.c @@ -140,6 +140,7 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, av_log(avctx, AV_LOG_ERROR, "Invalid alpha mode %d\n", ctx->alpha_info); return AVERROR_INVALIDDATA; } + if (avctx->skip_alpha) ctx->alpha_info = 0; switch (ctx->chroma_factor) { case 2: @@ -609,7 +610,7 @@ static int decode_slice(AVCodecContext *avctx, void *tdata) coff[2] = coff[1] + u_data_size; v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) : slice_data_size - coff[2]; coff[3] = coff[2] + v_data_size; - a_data_size = slice_data_size - coff[3]; + a_data_size = ctx->alpha_info ? slice_data_size - coff[3] : 0; /* if V or alpha component size is negative that means that previous component sizes are too large */ diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c index 25801ea6c0..d67eaa6b0d 100644 --- a/libavcodec/vp56.c +++ b/libavcodec/vp56.c @@ -530,7 +530,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF) < 0) return -1; - if (s->has_alpha) { + if (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) { av_frame_unref(s->alpha_context->frames[VP56_FRAME_CURRENT]); if ((ret = av_frame_ref(s->alpha_context->frames[VP56_FRAME_CURRENT], p)) < 0) { av_frame_unref(p); @@ -545,7 +545,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } } - if (s->has_alpha) { + if (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) { int bak_w = avctx->width; int bak_h = avctx->height; int bak_cw = avctx->coded_width; @@ -567,7 +567,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } } - avctx->execute2(avctx, ff_vp56_decode_mbs, 0, 0, s->has_alpha + 1); + avctx->execute2(avctx, ff_vp56_decode_mbs, 0, 0, (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) + 1); if ((res = av_frame_ref(data, p)) < 0) return res; @@ -690,6 +690,7 @@ av_cold int ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s, s->avctx = avctx; avctx->pix_fmt = has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P; + if (avctx->skip_alpha) avctx->pix_fmt = AV_PIX_FMT_YUV420P; ff_h264chroma_init(&s->h264chroma, 8); ff_hpeldsp_init(&s->hdsp, avctx->flags); diff --git a/tests/fate/prores.mak b/tests/fate/prores.mak index c608aef6fc..716f4e3741 100644 --- a/tests/fate/prores.mak +++ b/tests/fate/prores.mak @@ -3,7 +3,9 @@ FATE_PRORES = fate-prores-422 \ fate-prores-422_lt \ fate-prores-422_proxy \ fate-prores-alpha \ + fate-prores-alpha_skip \ fate-prores-transparency \ + fate-prores-transparency_skip \ FATE_SAMPLES_AVCONV-$(call DEMDEC, MOV, PRORES) += $(FATE_PRORES) fate-prores: $(FATE_PRORES) @@ -13,4 +15,6 @@ fate-prores-422_hq: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/pror fate-prores-422_lt: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422_LT.mov -pix_fmt yuv422p10le fate-prores-422_proxy: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_422_Proxy.mov -pix_fmt yuv422p10le fate-prores-alpha: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_with_Alpha.mov -pix_fmt yuva444p10le +fate-prores-alpha_skip: CMD = framecrc -flags +bitexact -skip_alpha 1 -i $(TARGET_SAMPLES)/prores/Sequence_1-Apple_ProRes_with_Alpha.mov fate-prores-transparency: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/prores/prores4444_with_transparency.mov -pix_fmt yuva444p10le +fate-prores-transparency_skip: CMD = framecrc -flags +bitexact -skip_alpha 1 -i $(TARGET_SAMPLES)/prores/prores4444_with_transparency.mov diff --git a/tests/fate/vpx.mak b/tests/fate/vpx.mak index ba53a2aa49..99a58559e4 100644 --- a/tests/fate/vpx.mak +++ b/tests/fate/vpx.mak @@ -19,6 +19,9 @@ fate-vp61: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/ea-vp6/MovieSkir FATE_VP6-$(call DEMDEC, FLV, VP6A) += fate-vp6a fate-vp6a: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/flash-vp6/300x180-Scr-f8-056alpha.flv +FATE_VP6-$(call DEMDEC, FLV, VP6A) += fate-vp6a-skip_alpha +fate-vp6a-skip_alpha: CMD = framecrc -flags +bitexact -skip_alpha 1 -i $(TARGET_SAMPLES)/flash-vp6/300x180-Scr-f8-056alpha.flv + FATE_VP6-$(call DEMDEC, FLV, VP6F) += fate-vp6f fate-vp6f: CMD = framecrc -flags +bitexact -i $(TARGET_SAMPLES)/flash-vp6/clip1024.flv diff --git a/tests/ref/fate/prores-alpha_skip b/tests/ref/fate/prores-alpha_skip new file mode 100644 index 0000000000..bdb5c6ee70 --- /dev/null +++ b/tests/ref/fate/prores-alpha_skip @@ -0,0 +1,3 @@ +#tb 0: 100/2997 +0, 0, 0, 1, 12441600, 0x254d8f95 +0, 1, 1, 1, 12441600, 0x254d8f95 diff --git a/tests/ref/fate/prores-transparency_skip b/tests/ref/fate/prores-transparency_skip new file mode 100644 index 0000000000..a2921a4e41 --- /dev/null +++ b/tests/ref/fate/prores-transparency_skip @@ -0,0 +1,5 @@ +#tb 0: 1/25 +#tb 1: 1/48000 +0, 0, 0, 1, 12441600, 0x58bff47d +1, 0, 0, 1024, 4096, 0x00000000 +1, 1024, 1024, 896, 3584, 0x00000000 diff --git a/tests/ref/fate/vp6a-skip_alpha b/tests/ref/fate/vp6a-skip_alpha new file mode 100644 index 0000000000..91a099c58b --- /dev/null +++ b/tests/ref/fate/vp6a-skip_alpha @@ -0,0 +1,94 @@ +#tb 0: 1/4 +0, 0, 0, 1, 81000, 0xcb92962d +0, 1, 1, 1, 81000, 0xae381904 +0, 2, 2, 1, 81000, 0x1fcc0c75 +0, 3, 3, 1, 81000, 0x023f0c21 +0, 4, 4, 1, 81000, 0xad691402 +0, 5, 5, 1, 81000, 0x42390be0 +0, 6, 6, 1, 81000, 0xc1c10a4e +0, 7, 7, 1, 81000, 0x9c0315ac +0, 8, 8, 1, 81000, 0xc2a315a7 +0, 9, 9, 1, 81000, 0x3a631392 +0, 10, 10, 1, 81000, 0x11591414 +0, 11, 11, 1, 81000, 0x1a551125 +0, 12, 12, 1, 81000, 0x2e1efa4f +0, 13, 13, 1, 81000, 0x4aa3f016 +0, 14, 14, 1, 81000, 0x74c029d8 +0, 15, 15, 1, 81000, 0xdee9a98b +0, 16, 16, 1, 81000, 0xdf3502d5 +0, 17, 17, 1, 81000, 0x4653536b +0, 18, 18, 1, 81000, 0x7f658c75 +0, 19, 19, 1, 81000, 0xab18ff13 +0, 20, 20, 1, 81000, 0xac2b8f3b +0, 21, 21, 1, 81000, 0xd61ff094 +0, 22, 22, 1, 81000, 0x425bfc2b +0, 23, 23, 1, 81000, 0x6be7ecd3 +0, 24, 24, 1, 81000, 0x0b0ee65b +0, 25, 25, 1, 81000, 0x3c6f146b +0, 26, 26, 1, 81000, 0x27c4e9c8 +0, 27, 27, 1, 81000, 0x174022c4 +0, 28, 28, 1, 81000, 0x3320fe81 +0, 29, 29, 1, 81000, 0x7a3c342e +0, 30, 30, 1, 81000, 0x448b4346 +0, 31, 31, 1, 81000, 0xd285b23d +0, 32, 32, 1, 81000, 0x852ed590 +0, 33, 33, 1, 81000, 0xc9d3df17 +0, 34, 34, 1, 81000, 0x4d23727b +0, 35, 35, 1, 81000, 0x1fae66cd +0, 36, 36, 1, 81000, 0x384d54ab +0, 37, 37, 1, 81000, 0x2fee6ba3 +0, 38, 38, 1, 81000, 0xd7ad6f59 +0, 39, 39, 1, 81000, 0xaf5e3e76 +0, 40, 40, 1, 81000, 0x10fceda4 +0, 41, 41, 1, 81000, 0xb26df92b +0, 42, 42, 1, 81000, 0xd6676e08 +0, 43, 43, 1, 81000, 0xff6b1b95 +0, 44, 44, 1, 81000, 0x6196d598 +0, 45, 45, 1, 81000, 0x833ebf1b +0, 46, 46, 1, 81000, 0x7b085af1 +0, 47, 47, 1, 81000, 0xe8f583b4 +0, 48, 48, 1, 81000, 0x3426d5e4 +0, 49, 49, 1, 81000, 0x214069ed +0, 50, 50, 1, 81000, 0x7dbdfd3f +0, 51, 51, 1, 81000, 0xf19b3f45 +0, 52, 52, 1, 81000, 0x0f05c7e2 +0, 53, 53, 1, 81000, 0xba94e323 +0, 54, 54, 1, 81000, 0x0de7b0c2 +0, 55, 55, 1, 81000, 0xfcf93c55 +0, 56, 56, 1, 81000, 0x8a8dbd55 +0, 57, 57, 1, 81000, 0xddf22b97 +0, 58, 58, 1, 81000, 0x49a830ff +0, 59, 59, 1, 81000, 0x82ab2a4b +0, 60, 60, 1, 81000, 0xd23420e5 +0, 61, 61, 1, 81000, 0x7c1017d1 +0, 62, 62, 1, 81000, 0x9aa61b38 +0, 63, 63, 1, 81000, 0x2a724a18 +0, 64, 64, 1, 81000, 0xc18055f2 +0, 65, 65, 1, 81000, 0xecba3855 +0, 66, 66, 1, 81000, 0x0eed6b0f +0, 67, 67, 1, 81000, 0x4be73816 +0, 68, 68, 1, 81000, 0xa681214e +0, 69, 69, 1, 81000, 0x4958f83d +0, 70, 70, 1, 81000, 0xca0f0d61 +0, 71, 71, 1, 81000, 0x3c453de1 +0, 72, 72, 1, 81000, 0xff60360a +0, 73, 73, 1, 81000, 0xdcef0949 +0, 74, 74, 1, 81000, 0xe5e3732d +0, 75, 75, 1, 81000, 0x39747fd4 +0, 76, 76, 1, 81000, 0x6bec70e6 +0, 77, 77, 1, 81000, 0x7026a8c0 +0, 78, 78, 1, 81000, 0x92de5b61 +0, 79, 79, 1, 81000, 0x3f00507f +0, 80, 80, 1, 81000, 0x5620c377 +0, 81, 81, 1, 81000, 0x39f5ed38 +0, 82, 82, 1, 81000, 0x6ee35d67 +0, 83, 83, 1, 81000, 0x4f99a409 +0, 84, 84, 1, 81000, 0x0a05b6ea +0, 85, 85, 1, 81000, 0xd6c442d9 +0, 86, 86, 1, 81000, 0x0bb3d2f0 +0, 87, 87, 1, 81000, 0x6891c5b1 +0, 88, 88, 1, 81000, 0xf16ba9be +0, 89, 89, 1, 81000, 0xba53528e +0, 90, 90, 1, 81000, 0xc847de49 +0, 91, 91, 1, 81000, 0xc5b2e2b0 +0, 92, 92, 1, 81000, 0xb0b497ff