[FFmpeg-devel,v2] Patch for memory optimization with QuickTime/MP4

Submitted by Jörg Beckmann on Dec. 2, 2019, 2:12 p.m.

Details

Message ID e89042e4e8194af39309b75b9f700473@scisys.com
State New
Headers show

Commit Message

Jörg Beckmann Dec. 2, 2019, 2:12 p.m.
After discussion with Carl Eugen, I replaced the "if" in line 7737 with an assert().

There is still the question, whether mov_switch_root() might be called when reading from a file. If someone is really really sure that it cannot happen at all, the check in mov_read_seek() could be removed.

Jörg

---
libavformat/isom.h |  1 +
libavformat/mov.c  | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 50 insertions(+), 1 deletion(-)

+    if (mov->discard_fragments) {
+        frag = &mov->fragment;
+
+        for (i = 0; i < mov->fc->nb_streams; i++) {
+            if (mov->fc->streams[i]->id == frag->track_id) {
+                st = mov->fc->streams[i];
+                break;
+            }
+        }
+
+        av_assert0(st);
+
+        sc = st->priv_data;
+
+        switch (st->codecpar->codec_type) {
+            case AVMEDIA_TYPE_AUDIO:
+            case AVMEDIA_TYPE_SUBTITLE:
+                /* Freeing VIDEO tables leads to corrupted video when writing to eg. MKV */
+                av_freep(&st->index_entries);
+                st->nb_index_entries = 0;
+                st->index_entries_allocated_size = 0;
+
+                sc->current_index = 0;
+                sc->current_sample = 0;
+
+                av_freep(&sc->ctts_data);
+                sc->ctts_data = NULL;
+                sc->ctts_allocated_size = 0;
+                sc->ctts_count = 0;
+                break;
+        }
+
+        av_free(mov->frag_index.item->stream_info);
+        av_freep(&mov->frag_index.item);
+        mov->frag_index.allocated_size = 0;
+        mov->frag_index.nb_items = 0;
+    }
+
     ret = mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX });
     if (ret < 0)
         return ret;
@@ -7975,6 +8016,9 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti
     int sample;
     int i;
+    if (mc->discard_fragments)  // Seeking is not possible if fragments are discarded.
+        return AVERROR(ENOTSUP);
+
     if (stream_index >= s->nb_streams)
         return AVERROR_INVALIDDATA;
@@ -8063,6 +8107,10 @@ static const AVOption mov_options[] = {
     { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM },
     { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL,
         {.i64 = 0}, 0, 1, FLAGS },
+    {"discard_fragments",
+            "Discards fragments after they have been read to support live streams.",
+            OFFSET(discard_fragments), AV_OPT_TYPE_BOOL, { .i64 = 0 },
+            0, 1, FLAGS },
     { NULL },
};

Comments

Michael Niedermayer Dec. 2, 2019, 8:53 p.m.
On Mon, Dec 02, 2019 at 02:12:14PM +0000, Jörg Beckmann wrote:
> After discussion with Carl Eugen, I replaced the "if" in line 7737 with an assert().
> 
> There is still the question, whether mov_switch_root() might be called when reading from a file. If someone is really really sure that it cannot happen at all, the check in mov_read_seek() could be removed.
> 
> Jörg
> 
> ---
> libavformat/isom.h |  1 +
> libavformat/mov.c  | 50 +++++++++++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 50 insertions(+), 1 deletion(-)

this patch seems to have been damaged

Applying: Patch for memory optimization with QuickTime/MP4
error: corrupt patch at line 24
error: could not build fake ancestor
Patch failed at 0001 Patch for memory optimization with QuickTime/MP4


[...]
Jörg Beckmann Dec. 3, 2019, 7:50 a.m.
> -----Ursprüngliche Nachricht-----
> Von: ffmpeg-devel <ffmpeg-devel-bounces@ffmpeg.org> Im Auftrag von Michael
> Niedermayer
> Gesendet: Montag, 2. Dezember 2019 21:54
> An: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org>
> Betreff: Re: [FFmpeg-devel] [PATCH v2] Patch for memory optimization with
> QuickTime/MP4
> 
> On Mon, Dec 02, 2019 at 02:12:14PM +0000, Jörg Beckmann wrote:
> > After discussion with Carl Eugen, I replaced the "if" in line 7737 with an assert().
> >
> > There is still the question, whether mov_switch_root() might be called when
> reading from a file. If someone is really really sure that it cannot happen at all, the
> check in mov_read_seek() could be removed.
> >
> > Jörg
> >
> > ---
> > libavformat/isom.h |  1 +
> > libavformat/mov.c  | 50
> > +++++++++++++++++++++++++++++++++++++++++++++++++-
> > 2 files changed, 50 insertions(+), 1 deletion(-)
> 
> this patch seems to have been damaged
> 

I'll try it again. Thank you.

> Applying: Patch for memory optimization with QuickTime/MP4
> error: corrupt patch at line 24
> error: could not build fake ancestor
> Patch failed at 0001 Patch for memory optimization with QuickTime/MP4
> 
> 
> [...]
> --
> Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
> 
> "Nothing to hide" only works if the folks in power share the values of you and
> everyone you know entirely and always will -- Tom Scott

Patch hide | download patch | download mbox

diff --git a/libavformat/isom.h b/libavformat/isom.h
index 4943b80ccf..9b4753f4d7 100644
--- a/libavformat/isom.h
+++ b/libavformat/isom.h
@@ -268,6 +268,7 @@  typedef struct MOVContext {
     int advanced_editlist;
     int ignore_chapters;
     int seek_individually;
+    int discard_fragments;
     int64_t next_root_atom; ///< offset of the next root atom
     int export_all;
     int export_xmp;
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 7553a7fdfc..97c02725c5 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -7698,8 +7698,11 @@  static int should_retry(AVIOContext *pb, int error_code) {
 static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
{
-    int ret;
+    int ret, i;
     MOVContext *mov = s->priv_data;
+    AVStream *st = NULL;
+    MOVStreamContext *sc;
+    MOVFragment *frag;
     if (index >= 0 && index < mov->frag_index.nb_items)
         target = mov->frag_index.item[index].moof_offset;
@@ -7721,6 +7724,44 @@  static int mov_switch_root(AVFormatContext *s, int64_t target, int index)
     mov->found_mdat = 0;