[FFmpeg-devel] [PATCH 3/5] wtvenc: mux thumbnail picture

Peter Ross pross at xvid.org
Sun Dec 30 13:35:39 CET 2012


---
 libavformat/wtvenc.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 69 insertions(+), 5 deletions(-)

diff --git a/libavformat/wtvenc.c b/libavformat/wtvenc.c
index 304bd14..664f5fc 100644
--- a/libavformat/wtvenc.c
+++ b/libavformat/wtvenc.c
@@ -378,6 +378,13 @@ static int write_header(AVFormatContext *s)
 
     for (i = 0; i < s->nb_streams; i++) {
         st = s->streams[i];
+        if ((st->disposition & AV_DISPOSITION_ATTACHED_PIC)) {
+	    if (st->codec->codec_id != AV_CODEC_ID_MJPEG) {
+                av_log(s, AV_LOG_ERROR, "expecting JPEG thumbnail image\n");
+                return AVERROR(EDOM);
+	    }
+            continue;
+        }
         ret = write_stream_codec(s, st);
         if (ret < 0) {
             av_log(s, AV_LOG_ERROR, "write stream codec failed codec_type(0x%x)\n", st->codec->codec_type);
@@ -389,6 +396,8 @@ static int write_header(AVFormatContext *s)
 
     for (i = 0; i < s->nb_streams; i++) {
         st = s->streams[i];
+        if ((st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+            continue;
         ret  = write_stream_data(s, st);
         if (ret < 0) {
             av_log(s, AV_LOG_ERROR, "write stream data failed codec_type(0x%x)\n", st->codec->codec_type);
@@ -425,6 +434,9 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
     AVIOContext *pb = s->pb;
     WtvContext  *wctx = s->priv_data;
 
+    if ((s->streams[pkt->stream_index]->disposition & AV_DISPOSITION_ATTACHED_PIC))
+        return 0;
+
     /* emit sync chunk and 'timeline.table.0.entries.Event' record every 50 frames */
     if (wctx->serial - (wctx->nb_sp_pairs ? wctx->sp_pairs[wctx->nb_sp_pairs - 1].serial : 0) >= 50)
         write_sync(s);
@@ -590,23 +602,63 @@ static void write_table_entries_time(AVFormatContext *s)
     avio_wl64(pb, wctx->last_serial);
 }
 
-static void write_tag(AVIOContext *pb, const char *key, const char *value)
+static void write_metadata_header(AVIOContext *pb, int type, const char *key, int value_size)
 {
     ff_put_guid(pb, &ff_metadata_guid);
-    avio_wl32(pb, 1);
-    avio_wl32(pb, strlen(value)*2 + 2);
+    avio_wl32(pb, type);
+    avio_wl32(pb, value_size);
     avio_put_str16le(pb, key);
+}
+
+static int metadata_header_size(const char *key)
+{
+    return 16 + 4 + 4 + strlen(key)*2 + 2;
+}
+
+static void write_tag_int32(AVIOContext *pb, const char *key, int value)
+{
+    write_metadata_header(pb, 0, key, 4);
+    avio_wl32(pb, value);
+}
+
+static void write_tag(AVIOContext *pb, const char *key, const char *value)
+{
+    write_metadata_header(pb, 1, key, strlen(value)*2 + 2);
     avio_put_str16le(pb, value);
 }
 
+static int attachment_value_size(const AVPacket *pkt, const AVDictionaryEntry *e)
+{
+    return strlen("image/jpeg")*2 + 2 + 1 + (e ? strlen(e->value)*2 : 0) + 2 + 4 + pkt->size;
+}
+
 static void write_table_entries_attrib(AVFormatContext *s)
 {
+    AVIOContext *pb = s->pb;
     AVDictionaryEntry *tag = 0;
+    int i;
 
     //FIXME: translate special tags (e.g. WM/Bitrate) to binary representation
     ff_metadata_conv(&s->metadata, ff_asf_metadata_conv, NULL);
     while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
-        write_tag(s->pb, tag->key, tag->value);
+        write_tag(pb, tag->key, tag->value);
+
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st = s->streams[i];
+        if (!(st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+            continue;
+        tag = av_dict_get(st->metadata, "title", NULL, 0);
+        write_metadata_header(pb, 2, "WM/Picture", attachment_value_size(&st->attached_pic, tag));
+
+        avio_put_str16le(pb, "image/jpeg");
+        avio_w8(pb, 0x10);
+        avio_put_str16le(pb, tag ? tag->value : "");
+
+        avio_wl32(pb, st->attached_pic.size);
+        avio_write(pb, st->attached_pic.data, st->attached_pic.size);
+
+        write_tag_int32(pb, "WM/MediaThumbType", 2);
+    }
 }
 
 static void write_table_redirector_legacy_attrib(AVFormatContext *s)
@@ -614,11 +666,23 @@ static void write_table_redirector_legacy_attrib(AVFormatContext *s)
     AVIOContext *pb = s->pb;
     AVDictionaryEntry *tag = 0;
     int64_t pos = 0;
+    int i;
 
     //FIXME: translate special tags to binary representation
     while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
         avio_wl64(pb, pos);
-        pos += 16 + 4 + 4 + strlen(tag->key)*2 + 2 + strlen(tag->value)*2 + 2;
+        pos += metadata_header_size(tag->key) + strlen(tag->value)*2 + 2;
+    }
+
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st = s->streams[i];
+        if (!(st->disposition & AV_DISPOSITION_ATTACHED_PIC))
+            continue;
+        avio_wl64(pb, pos);
+        pos += metadata_header_size("WM/Picture") + attachment_value_size(&st->attached_pic, av_dict_get(st->metadata, "title", NULL, 0));
+
+        avio_wl64(pb, pos);
+        pos += metadata_header_size("WM/MediaThumbType") + 4;
     }
 }
 
-- 
1.8.0

-- Peter
(A907 E02F A6E5 0CD2 34CD 20D2 6760 79C5 AC40 DD6B)
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20121230/cdd5bf70/attachment.asc>


More information about the ffmpeg-devel mailing list