[FFmpeg-devel] [PATCH] mov hacks: Fix ulaw-in-mov sample.

Reimar Döffinger Reimar.Doeffinger at gmx.de
Sun Mar 25 14:06:39 CEST 2012


This patch fixes the sample from trac issue #522.
One issue is that the size of the trak elements is coded
too large, so that the next trak element would be parsed
as part of the first and truncated incorrectly.
The second issue is that the mov demuxer insists on using its
calculated sample_size (which is nonsense) instead of the one
encoded in the track.
The old raw audio code should be using the value in stsz, because
the size of a single sample never makes sense for the size of
a full audio packet, whereas the new code will multiply the
sample size by the chunk size, so it should use the calculated value.

Signed-off-by: Reimar Döffinger <Reimar.Doeffinger at gmx.de>
---
 libavformat/isom.h |    1 +
 libavformat/mov.c  |   13 ++++++++++++-
 2 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/libavformat/isom.h b/libavformat/isom.h
index cd70c03..2d58443 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -104,6 +104,7 @@ typedef struct MOVStreamContext {
     int ctts_index;
     int ctts_sample;
     unsigned int sample_size;
+    unsigned int alt_sample_size;
     unsigned int sample_count;
     int *sample_sizes;
     unsigned int keyframe_count;
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 30bb622..775ab5a 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -319,6 +319,16 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         if (atom.size >= 8) {
             a.size = avio_rb32(pb);
             a.type = avio_rl32(pb);
+            if (atom.type != MKTAG('r','o','o','t') &&
+                atom.type != MKTAG('m','o','o','v'))
+            {
+                if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
+                {
+                    av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
+                    avio_skip(pb, -8);
+                    return 0;
+                }
+            }
             total_size += 8;
             if (a.size == 1) { /* 64 bit extended size */
                 a.size = avio_rb64(pb) - 8;
@@ -1634,6 +1644,7 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
         sample_size = avio_rb32(pb);
         if (!sc->sample_size) /* do not overwrite value computed in stsd */
             sc->sample_size = sample_size;
+        sc->alt_sample_size = sample_size;
         field_size = 32;
     } else {
         sample_size = 0;
@@ -1862,7 +1873,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st)
                 }
                 if (keyframe)
                     distance = 0;
-                sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];
+                sample_size = sc->alt_sample_size > 0 ? sc->alt_sample_size : sc->sample_sizes[current_sample];
                 if (sc->pseudo_stream_id == -1 ||
                    sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
                     AVIndexEntry *e = &st->index_entries[st->nb_index_entries++];
-- 
1.7.9.1



More information about the ffmpeg-devel mailing list