Incorrectly used ff_codec_movvideo_tags instead of codec_tags.
Description follows:

This patch adds a new static function get_qt_codec() that takes care of the initial retrieval of the fourcc and codec ID for A_QUICKTIME and V_QUICKTIME. It also normalizes noncompliant private data found in some older files that incorrectly starts with the fourcc by expanding/shifting the data by 4 bytes, and storing the data size at the start. This is important in order to make the private data work as expected and without false positives with the rest of the code in the A_QUICKTIME and V_QUICKTIME blocks (and most likely in other places as well).

Mats

--
Mats Peterson
http://matsp888.no-ip.org/~mats/
>From 3e4c8f4926b59b01cd945f3789dcc59b69f17bef Mon Sep 17 00:00:00 2001
From: Mats Peterson <matsp...@yahoo.com>
Date: Fri, 8 Jan 2016 17:57:27 +0100
Subject: [PATCH v3] lavf/matroskadec: Normalize noncompliant A_QUICKTIME/V_QUICKTIME private data

Incorrectly used ff_codec_movvideo_tags instead of codec_tags.
Description follows:

This patch adds a new static function get_qt_codec() that takes care of
the initial retrieval of the fourcc and codec ID for A_QUICKTIME and
V_QUICKTIME. It also normalizes noncompliant private data found in some
older files that incorrectly starts with the fourcc by expanding/shifting
the data by 4 bytes, and storing the data size at the start. This is
important in order to make the private data work as expected and without
false positives with the rest of the code in the A_QUICKTIME and
V_QUICKTIME blocks (and most likely in other places as well).

Mats

---
 libavformat/matroskadec.c |   49 +++++++++++++++++++++++++++++++++------------
 1 file changed, 36 insertions(+), 13 deletions(-)

diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index be4e300..a80df41 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -1708,6 +1708,34 @@ static void mkv_stereo_mode_display_mul(int stereo_mode, int *h_width, int *h_he
     }
 }
 
+static int get_qt_codec(MatroskaTrack *track, uint32_t *fourcc, enum AVCodecID *codec_id)
+{
+    const AVCodecTag *codec_tags;
+    
+    codec_tags = track->type == MATROSKA_TRACK_TYPE_VIDEO ?
+            ff_codec_movvideo_tags : ff_codec_movaudio_tags;
+
+    *fourcc = AV_RL32(track->codec_priv.data + 4);
+    *codec_id = ff_codec_get_id(codec_tags, *fourcc);
+
+    /* Normalize noncompliant private data that starts with the fourcc
+     * by expanding/shifting the data by 4 bytes and storing the data
+     * size at the start. */
+    if (ff_codec_get_id(codec_tags, AV_RL32(track->codec_priv.data))) {
+        if (!(track->codec_priv.data = av_realloc(track->codec_priv.data,
+                track->codec_priv.size + 4)))
+            return AVERROR(ENOMEM);
+        memmove(track->codec_priv.data + 4, track->codec_priv.data,
+                track->codec_priv.size);
+        track->codec_priv.size += 4;
+        AV_WB32(track->codec_priv.data, track->codec_priv.size);
+        *fourcc = AV_RL32(track->codec_priv.data + 4);
+        *codec_id = ff_codec_get_id(codec_tags, *fourcc);
+    }
+
+    return 0;
+}
+
 static int matroska_parse_tracks(AVFormatContext *s)
 {
     MatroskaDemuxContext *matroska = s->priv_data;
@@ -1861,14 +1889,12 @@ static int matroska_parse_tracks(AVFormatContext *s)
             fourcc           = st->codec->codec_tag;
             extradata_offset = FFMIN(track->codec_priv.size, 18);
         } else if (!strcmp(track->codec_id, "A_QUICKTIME")
-                   && (track->codec_priv.size >= 36)
+                   /* Normally 36, but allow noncompliant private data */
+                   && (track->codec_priv.size >= 32)
                    && (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);
-            }
+            int ret = get_qt_codec(track, &fourcc, &codec_id);
+            if (ret < 0)
+                return ret;
             if (fourcc == 0) {
                 if (track->audio.bitdepth == 8) {
                     fourcc = MKTAG('r','a','w',' ');
@@ -1881,12 +1907,9 @@ static int matroska_parse_tracks(AVFormatContext *s)
         } 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);
-            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);
-            }
+            int ret = get_qt_codec(track, &fourcc, &codec_id);
+            if (ret < 0)
+                return ret;
             if (codec_id == AV_CODEC_ID_NONE && AV_RL32(track->codec_priv.data+4) == AV_RL32("SMI ")) {
                 fourcc = MKTAG('S','V','Q','3');
                 codec_id = ff_codec_get_id(ff_codec_movvideo_tags, fourcc);
-- 
1.7.10.4

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to