diff mbox series

[FFmpeg-devel,1/3] avformat/mov: skip moof and sidx before found moov

Message ID tencent_A99C5A8B9AA60A9086E6C567CEAA9A531506@qq.com
State New
Headers show
Series [FFmpeg-devel,1/3] avformat/mov: skip moof and sidx before found moov | expand

Checks

Context Check Description
andriy/make_x86 success Make finished
andriy/make_fate_x86 success Make fate finished
andriy/make_ppc success Make finished
andriy/make_fate_ppc fail Make fate failed

Commit Message

Zhao Zhili Dec. 24, 2021, 9:58 a.m. UTC
---
 libavformat/mov.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

Comments

Derek Buitenhuis Dec. 24, 2021, 7:09 p.m. UTC | #1
On 12/24/2021 9:58 AM, Zhao Zhili wrote:
> ---
>  libavformat/mov.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)

When do such files exist? They're not valid.

- Derek
Zhao Zhili Dec. 25, 2021, 2:17 a.m. UTC | #2
> On Dec 25, 2021, at 3:09 AM, Derek Buitenhuis <derek.buitenhuis@gmail.com> wrote:
> 
> On 12/24/2021 9:58 AM, Zhao Zhili wrote:
>> ---
>> libavformat/mov.c | 16 ++++++++++++++++
>> 1 file changed, 16 insertions(+)
> 
> When do such files exist? They're not valid.

File from Steven, and another one from ticket 8883.
https://trac.ffmpeg.org/ticket/8883

Put moov after moof doesn't make sense, but I’m not sure they are
valid or not. Those files are generated like this:

1. Use hoov as moov to create a fragmented mp4.
2. At last, create a normal moov box.

For demuxer which doesn’t know hoov (maybe don’t know moof neither),
they are normal files. VLC and quicktime player can playback those
samples. FFmpeg only handle the first fragment because it treat
hoov as moov.

gstreamer has a similar strategy but not the same:

> isomp4/mux: add a fragment mode for initial moov with data
> 
> Used by some proprietary software for their fragmented files.
> 
> Adds some support for multi-stream fragmented files
> 
> Flow is as follows.
> 1. The first 'fragment' is written as a self-contained fragmented
>    mdat+moov complete with an edit list and durations, tags, etc.
> 2. Subsequent fragments are written with a mdat+moof and each stream is
>    interleaved as data arrives (currently ignoring the interleave-*
>    properties).  data-offsets in both the traf and the trun ensure
>    data is read from the correct place on demuxing.  Data/chunk offsets
>    are also kept for writing out the final moov.
> 3. On finalisation, the initial moov is invalidated to a hoov and the
>    size of the first mdat is extended to cover the entire file contents.
>    Then a moov is written as regularly would in moov-at-end mode (the
>    default).
> 
> This results in a file that is playable throughout while leaving a
> finalised file on completion for players that do not understand
> fragmented mp4.


https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/643

I’m really interested to know where do those hoov files come from, so
we don’t fix a case and failed for another case.

> 
> - Derek
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff mbox series

Patch

diff --git a/libavformat/mov.c b/libavformat/mov.c
index 2aed6e80ef..ea2f010aa0 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -7366,6 +7366,21 @@  static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
             break;
         a.size = FFMIN(a.size, atom.size - total_size);
 
+        if (!c->found_moov) {
+            static uint32_t skip_before_moov[] = {
+                MKTAG('m', 'o', 'o', 'f'),
+                MKTAG('s', 'i', 'd', 'x'),
+            };
+            for (size_t i = 0; i < FF_ARRAY_ELEMS(skip_before_moov); i++) {
+                if (a.type == skip_before_moov[i]) {
+                    av_log(c->fc, AV_LOG_WARNING, "Skip %s atom before moov.\n",
+                           av_fourcc2str(a.type));
+                    parse = NULL;
+                    goto skip;
+                }
+            }
+        }
+
         for (i = 0; mov_default_parse_table[i].type; i++)
             if (mov_default_parse_table[i].type == a.type) {
                 parse = mov_default_parse_table[i].parse;
@@ -7386,6 +7401,7 @@  static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
             parse = mov_read_keys;
         }
 
+skip:
         if (!parse) { /* skip leaf atoms data */
             avio_skip(pb, a.size);
         } else {