[FFmpeg-devel] [PATCH 2/2] Copy VP8 BlockAdditional data to side_data of AVPacket

Vignesh Venkatasubramanian vigneshv at google.com
Tue Jan 29 23:56:48 CET 2013


Copy the data in BlockAdditional element of matroska container into
AVPacket's side data (with a new AVPacketSideDataType). This is being
done because alpha channel support for WebM is being added to chromium
and the per frame extra data needs to be demuxed and passed on to the
decoder. The design doc for alpha channel support in chromium can be
found here: http://goo.gl/wCP1y

Signed-off-by: Vignesh Venkatasubramanian <vigneshv at google.com>
---
 libavcodec/avcodec.h      |  5 +++++
 libavformat/matroskadec.c | 22 +++++++++++++++++++---
 2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index ca7764a..871db5b 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -983,6 +983,11 @@ enum AVPacketSideDataType {
      * @endcode
      */
     AV_PKT_DATA_SUBTITLE_POSITION,
+
+    /**
+     * Alpha Channel data for VP8
+     */
+    AV_PKT_DATA_VP8_ALPHA,
 };
 
 /**
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 8b6b8d0..dc21795 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -1783,6 +1783,10 @@ static int matroska_read_header(AVFormatContext *s)
             if (track->video.stereo_mode && track->video.stereo_mode < MATROSKA_VIDEO_STEREO_MODE_COUNT)
                 av_dict_set(&st->metadata, "stereo_mode", ff_matroska_video_stereo_mode[track->video.stereo_mode], 0);
 
+            /* export alpha mode flag as metadata tag */
+            if (track->max_block_additional_id && !strcmp(track->codec_id, "V_VP8"))
+                av_dict_set(&st->metadata, "alpha_mode", "1", 0);
+
             /* if we have virtual track, mark the real tracks */
             for (j=0; j < track->operation.combine_planes.nb_elem; j++) {
                 char buf[32];
@@ -2087,7 +2091,8 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
                                 AVStream *st,
                                 uint8_t *data, int pkt_size,
                                 uint64_t timecode, uint64_t lace_duration,
-                                int64_t pos, int is_keyframe)
+                                int64_t pos, int is_keyframe,
+                                uint8_t *additional, int additional_size)
 {
     MatroskaTrackEncoding *encodings = track->encodings.elem;
     uint8_t *pkt_data = data;
@@ -2124,6 +2129,11 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
     pkt->flags = is_keyframe;
     pkt->stream_index = st->index;
 
+    if (additional_size > 0 && !strcmp(track->codec_id, "V_VP8")) {
+        uint8_t *side_data = av_packet_new_side_data(pkt, AV_PKT_DATA_VP8_ALPHA, additional_size);
+        memcpy(side_data, additional, additional_size);
+    }
+
     if (track->ms_compat)
         pkt->dts = timecode;
     else
@@ -2173,6 +2183,7 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
 static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
                                 int size, int64_t pos, uint64_t cluster_time,
                                 uint64_t block_duration, int is_keyframe,
+                                uint8_t *additional, int additional_size,
                                 int64_t cluster_pos)
 {
     uint64_t timecode = AV_NOPTS_VALUE;
@@ -2266,7 +2277,8 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,
         } else {
             res = matroska_parse_frame(matroska, track, st, data, lace_size[n],
                                       timecode, lace_duration,
-                                      pos, !n? is_keyframe : 0);
+                                      pos, !n? is_keyframe : 0,
+                                      additional, additional_size);
             if (res)
                 goto end;
         }
@@ -2322,6 +2334,9 @@ static int matroska_parse_cluster_incremental(MatroskaDemuxContext *matroska)
         i = blocks_list->nb_elem - 1;
         if (blocks[i].bin.size > 0 && blocks[i].bin.data) {
             int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1;
+            int additional_size = blocks[i].additional.size;
+            uint8_t* additional = blocks[i].additional.size > 0 ?
+                                    blocks[i].additional.data : NULL;
             if (!blocks[i].non_simple)
                 blocks[i].duration = 0;
             res = matroska_parse_block(matroska,
@@ -2329,6 +2344,7 @@ static int matroska_parse_cluster_incremental(MatroskaDemuxContext *matroska)
                                        blocks[i].bin.pos,
                                        matroska->current_cluster.timecode,
                                        blocks[i].duration, is_keyframe,
+                                       additional, additional_size,
                                        matroska->current_cluster_pos);
         }
     }
@@ -2359,7 +2375,7 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska)
             res=matroska_parse_block(matroska,
                                      blocks[i].bin.data, blocks[i].bin.size,
                                      blocks[i].bin.pos,  cluster.timecode,
-                                     blocks[i].duration, is_keyframe,
+                                     blocks[i].duration, is_keyframe, NULL, 0,
                                      pos);
         }
     ebml_free(matroska_cluster, &cluster);
-- 
1.8.1



More information about the ffmpeg-devel mailing list