I've attached a unified diff of the latest Git version of matroskadec.c that 
does two things:
1. It allows FFmpeg to recognize QuickTime version 0 sound sample descriptions 
by using 36 instead of 86 as the minimum private data size for A_QUICKTIME.
2. The palette, in QuickTime video that has one, is put in extradata, to make 
MPlayer recognize it and tack it to the end of its "fake" BITMAPINFOHEADER.
This patch is an improvement and tidying-up of a proposed patch by Martin 
Storsjö, for the record. The version 0 sound sample description stuff is made 
by me long ago, though.

Comments welcome.

Mats
 -- 
Mats Peterson
http://matsp888.no-ip.org/~mats/
--- matroskadec.c.orig	2015-12-08 11:01:40.640478749 +0100
+++ matroskadec.c	2015-12-08 13:56:46.000000000 +0100
@@ -310,10 +310,12 @@
     /* File has SSA subtitles which prevent incremental cluster parsing. */
     int contains_ssa;
 
     /* WebM DASH Manifest live flag/ */
     int is_live;
+
+    uint8_t *pal;
 } MatroskaDemuxContext;
 
 typedef struct MatroskaBlock {
     uint64_t duration;
     int64_t  reference;
@@ -1853,22 +1855,27 @@
             if (ret < 0)
                 return ret;
             codec_id         = st->codec->codec_id;
             extradata_offset = FFMIN(track->codec_priv.size, 18);
         } else if (!strcmp(track->codec_id, "A_QUICKTIME")
-                   && (track->codec_priv.size >= 86)
+                   && (track->codec_priv.size >= 36)
                    && (track->codec_priv.data)) {
             fourcc = AV_RL32(track->codec_priv.data + 4);
             codec_id = ff_codec_get_id(ff_codec_movaudio_tags, fourcc);
             if (ff_codec_get_id(ff_codec_movaudio_tags, AV_RL32(track->codec_priv.data))) {
                 fourcc = AV_RL32(track->codec_priv.data);
                 codec_id = ff_codec_get_id(ff_codec_movaudio_tags, fourcc);
             }
         } else if (!strcmp(track->codec_id, "V_QUICKTIME") &&
                    (track->codec_priv.size >= 21)          &&
                    (track->codec_priv.data)) {
-            fourcc   = AV_RL32(track->codec_priv.data + 4);
+            AVIOContext pb;
+            MOVContext *mc;
+            MOVStreamContext *msc;
+            void *priv_data;
+            int nb_streams;
+            fourcc = AV_RL32(track->codec_priv.data + 4);
             codec_id = ff_codec_get_id(ff_codec_movvideo_tags, fourcc);
             if (ff_codec_get_id(ff_codec_movvideo_tags, AV_RL32(track->codec_priv.data))) {
                 fourcc   = AV_RL32(track->codec_priv.data);
                 codec_id = ff_codec_get_id(ff_codec_movvideo_tags, fourcc);
             }
@@ -1878,10 +1885,49 @@
                 char buf[32];
                 av_get_codec_tag_string(buf, sizeof(buf), fourcc);
                 av_log(matroska->ctx, AV_LOG_ERROR,
                        "mov FourCC not found %s.\n", buf);
             }
+            priv_data = st->priv_data;
+            nb_streams = s->nb_streams;
+            mc = av_mallocz(sizeof(*mc));
+            if (! mc)
+                return AVERROR(ENOMEM);
+            mc->fc = s;
+            st->priv_data = msc = av_mallocz(sizeof(MOVStreamContext));
+            if (!msc) {
+                av_free(mc);
+                st->priv_data = priv_data;
+                return AVERROR(ENOMEM);
+            }
+            ffio_init_context(&pb, track->codec_priv.data, track->codec_priv.size, 0, NULL, NULL, NULL, NULL);
+            /* ff_mov_read_stsd_entries updates stream s->nb_streams-1,
+             * so set it temporarily to indicate which stream to update. */
+            s->nb_streams = st->index + 1;
+            ff_mov_read_stsd_entries(mc, &pb, 1);
+            if (msc->has_palette) {
+                if ((matroska->pal = av_malloc(AVPALETTE_SIZE))) {
+                    memcpy(matroska->pal, msc->palette, AVPALETTE_SIZE);
+                    if ((extradata = av_malloc(AVPALETTE_SIZE))) {
+                        memcpy(extradata, msc->palette, AVPALETTE_SIZE);
+                        extradata_size = AVPALETTE_SIZE;
+                    }
+                }
+                if (!matroska->pal || !extradata) {
+                    av_free(msc);
+                    av_free(mc);
+                    if (matroska->pal) av_freep(&matroska->pal);
+                    if (extradata) av_freep(&extradata);
+                    st->priv_data = priv_data;
+                    s->nb_streams = nb_streams;
+                    return AVERROR(ENOMEM);
+                }
+            }
+            av_free(msc);
+            av_free(mc);
+            st->priv_data = priv_data;
+            s->nb_streams = nb_streams;
         } else if (codec_id == AV_CODEC_ID_PCM_S16BE) {
             switch (track->audio.bitdepth) {
             case  8:
                 codec_id = AV_CODEC_ID_PCM_U8;
                 break;
@@ -2322,10 +2368,19 @@
                                    AVPacket *pkt)
 {
     if (matroska->num_packets > 0) {
         memcpy(pkt, matroska->packets[0], sizeof(AVPacket));
         av_freep(&matroska->packets[0]);
+        if (matroska->pal) {
+            uint8_t *pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
+            if (!pal) {
+                av_log(matroska->ctx, AV_LOG_ERROR, "Cannot append palette to packet\n");
+            } else {
+                memcpy(pal, matroska->pal, AVPALETTE_SIZE);
+            }
+            av_freep(&matroska->pal);
+        }
         if (matroska->num_packets > 1) {
             void *newpackets;
             memmove(&matroska->packets[0], &matroska->packets[1],
                     (matroska->num_packets - 1) * sizeof(AVPacket *));
             newpackets = av_realloc(matroska->packets,
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to