Changed the name of get_qt_priv_data() to the more appropriate get_qt_codec(). 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 6031e4d9ca09aaa7befdf2f2d0e464965849547a Mon Sep 17 00:00:00 2001 From: Mats Peterson <matsp...@yahoo.com> Date: Fri, 8 Jan 2016 17:22:52 +0100 Subject: [PATCH v2] lavf/matroskadec: Normalize noncompliant A_QUICKTIME/V_QUICKTIME data Changed the name of get_qt_priv_data() to the more appropriate get_qt_codec(). 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..ff486c2 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(ff_codec_movvideo_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