[FFmpeg-devel] [PATCH v5] avformat/mov: Memory optimization with QuickTime/MP4
Jörg Beckmann
Joerg.Beckmann at scisys.com
Mon Dec 16 09:46:14 EET 2019
Is there still something wrong with this patch?
Cheers,
Jörg
> -----Ursprüngliche Nachricht-----
> Von: ffmpeg-devel <ffmpeg-devel-bounces at ffmpeg.org> Im Auftrag von Jörg
> Beckmann
> Gesendet: Montag, 9. Dezember 2019 16:05
> An: ffmpeg-devel at ffmpeg.org
> Betreff: [FFmpeg-devel] [PATCH v5] avformat/mov: Memory optimization with
> QuickTime/MP4
>
> Invents a new option "discard_fragments" for the MP4/Quicktime/MOV decoder.
>
> If the option is not set, nothing changes at all. If it is set, old fragments are
> discarded as far as possible on each call to switch_root. For pure audio streams,
> the memory usage is now constant. For video streams, the memory usage is
> reduced. It's tested with audio streams received from a professional DAB+
> receiver and with video streams created on my own with "ffmpeg -i <video>.m4v -
> c:a:0 copy -c:v copy -c:s copy -f ismv -movflags \ frag_keyframe -movflags
> faststart tcp://localhost:1234?listen" and "ffmpeg -i tcp://localhost:1234 -c:a copy -
> c:v copy -c:s copy -y <output>".
>
> Signed-off-by: Jörg Beckmann <joerg.beckmann at scisys.com>
> ---
> libavformat/isom.h | 1 +
> libavformat/mov.c | 49
> ++++++++++++++++++++++++++++++++++++++++++++++++-
> 2 files changed, 49 insertions(+), 1 deletion(-)
>
> 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..deb3ff5508
> 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,43 @@ static int mov_switch_root(AVFormatContext *s, int64_t
> target, int index)
>
> mov->found_mdat = 0;
>
> + 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_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 +8015,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 +8106,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",
> + "Discard fragments after they have been read to support live streams.",
> + OFFSET(discard_fragments), AV_OPT_TYPE_BOOL, { .i64 = 0 },
> + 0, 1, FLAGS },
>
> { NULL },
> };
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email ffmpeg-devel-request at ffmpeg.org with
> subject "unsubscribe".
More information about the ffmpeg-devel
mailing list