[FFmpeg-devel] [PATCH] Make decoding alpha optional for some codecs.

Reimar Döffinger Reimar.Doeffinger at gmx.de
Wed Sep 18 19:36:55 CEST 2013


For codecs where decoding of a whole plane can simply
be skipped, we should offer applications to not decode
alpha for better performance (ca. 30% less CPU usage
and 40% reduced memory bandwidth).
It also means applications do not need to implement support
(even if it is rather simple) for YUVA formats in order to be
able to play these files.
Tested by manually hacking avcodec_default_get_format,
suggestions for how to test in FATE welcome.

Signed-off-by: Reimar Döffinger <Reimar.Doeffinger at gmx.de>
---
 Changelog                               |  2 +
 libavcodec/avcodec.h                    |  1 +
 libavcodec/ffv1dec.c                    |  1 +
 libavcodec/options_table.h              |  1 +
 libavcodec/proresdec2.c                 |  1 +
 libavcodec/proresdec_lgpl.c             |  3 +-
 libavcodec/vp56.c                       |  7 +--
 tests/fate/prores.mak                   |  4 ++
 tests/fate/vpx.mak                      |  3 ++
 tests/ref/fate/prores-alpha_skip        |  3 ++
 tests/ref/fate/prores-transparency_skip |  5 ++
 tests/ref/fate/vp6a-skip_alpha          | 94 +++++++++++++++++++++++++++++++++
 12 files changed, 121 insertions(+), 4 deletions(-)
 create mode 100644 tests/ref/fate/prores-alpha_skip
 create mode 100644 tests/ref/fate/prores-transparency_skip
 create mode 100644 tests/ref/fate/vp6a-skip_alpha

diff --git a/Changelog b/Changelog
index 3e4653b..4ffbc5a 100644
--- a/Changelog
+++ b/Changelog
@@ -25,6 +25,8 @@ version <next>
   more consistent with other muxers.
 - adelay filter
 - pullup filter ported from libmpcodecs
+- 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 23fba4f..505283b 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -720,6 +720,7 @@ typedef struct RcOverride{
 
 #define CODEC_FLAG2_CHUNKS        0x00008000 ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries.
 #define CODEC_FLAG2_SHOW_ALL      0x00400000 ///< Show all frames before the first keyframe
+#define CODEC_FLAG2_SKIP_ALPHA    0x00800000 ///< Skip processing alpha if supported by codec
 
 /* Unsupported options :
  *              Syntax Arithmetic coding (SAC)
diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c
index 87cc2ca..769a664 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->flags2 & CODEC_FLAG2_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 e9cdfc4..82d94ca 100644
--- a/libavcodec/options_table.h
+++ b/libavcodec/options_table.h
@@ -76,6 +76,7 @@ static const AVOption avcodec_options[] = {
 {"local_header", "place global headers at every keyframe instead of in extradata", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_LOCAL_HEADER }, INT_MIN, INT_MAX, V|E, "flags2"},
 {"chunks", "Frame data might be split into multiple chunks", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_CHUNKS }, INT_MIN, INT_MAX, V|D, "flags2"},
 {"showall", "Show all frames before the first keyframe", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_SHOW_ALL }, INT_MIN, INT_MAX, V|D, "flags2"},
+{"skip_alpha", "Skip processing alpha", 0, AV_OPT_TYPE_CONST, {.i64 = CODEC_FLAG2_SKIP_ALPHA }, INT_MIN, INT_MAX, V|D, "flags2"},
 {"me_method", "set motion estimation method", OFFSET(me_method), AV_OPT_TYPE_INT, {.i64 = ME_EPZS }, INT_MIN, INT_MAX, V|E, "me_method"},
 {"zero", "zero motion estimation (fastest)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ZERO }, INT_MIN, INT_MAX, V|E, "me_method" },
 {"full", "full motion estimation (slowest)", 0, AV_OPT_TYPE_CONST, {.i64 = ME_FULL }, INT_MIN, INT_MAX, V|E, "me_method" },
diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c
index 9a8861c..39a868f 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->flags2 & CODEC_FLAG2_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 2fef2c6..9869848 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->flags2 & CODEC_FLAG2_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 25801ea..5f985ad 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->flags2 & CODEC_FLAG2_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 c608aef..32da090 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 -flags2 +skip_alpha -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 -flags2 +skip_alpha -i $(TARGET_SAMPLES)/prores/prores4444_with_transparency.mov
diff --git a/tests/fate/vpx.mak b/tests/fate/vpx.mak
index ba53a2a..075c5c9 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 -flags2 +skip_alpha -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 0000000..bdb5c6e
--- /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 0000000..a2921a4
--- /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 0000000..91a099c
--- /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
-- 
1.8.4.rc3



More information about the ffmpeg-devel mailing list