Use QT format for audio sample descriptors depending on stsd version.
authorJustin Ruggles <justin.ruggles@gmail.com>
Wed, 5 Sep 2018 21:54:57 +0000 (17:54 -0400)
committerDerek Buitenhuis <derek.buitenhuis@gmail.com>
Sun, 9 Sep 2018 18:52:53 +0000 (19:52 +0100)
ISOBMFF does not allow AudioSampleEntryV1 in stsd version 0, so
assume the descriptor format is QTFF SoundDescriptionV1. ISOBMFF does
not define a version 2.

This fixes audio decoding for some MP4 files generated with Apple
tools. The additional fields present in SoundDescriptionV1/V2 need to
be read in order to correctly read additional boxes that contain
information required for decoding the stream.

Fixes #7376.

Also see: https://github.com/HandBrake/HandBrake/issues/1555

Signed-off-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
libavformat/isom.h
libavformat/mov.c

index f3a7a86..e629663 100644 (file)
@@ -218,6 +218,7 @@ typedef struct MOVStreamContext {
     int *extradata_size;
     int last_stsd_index;
     int stsd_count;
+    int stsd_version;
 
     int32_t *display_matrix;
     AVStereo3D *stereo3d;
index 02c8ec6..ec57a05 100644 (file)
@@ -2122,8 +2122,8 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
     // Read QT version 1 fields. In version 0 these do not exist.
     av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
     if (!c->isom ||
-        (compatible_brands && strstr(compatible_brands->value, "qt  "))) {
-
+        (compatible_brands && strstr(compatible_brands->value, "qt  ")) ||
+        (sc->stsd_version == 0 && version > 0)) {
         if (version == 1) {
             sc->samples_per_frame = avio_rb32(pb);
             avio_rb32(pb); /* bytes per packet */
@@ -2554,7 +2554,7 @@ static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
     st = c->fc->streams[c->fc->nb_streams - 1];
     sc = st->priv_data;
 
-    avio_r8(pb); /* version */
+    sc->stsd_version = avio_r8(pb);
     avio_rb24(pb); /* flags */
     entries = avio_rb32(pb);