Am Mo., 2. Dez. 2019 um 10:05 Uhr schrieb Jörg Beckmann <joerg.beckm...@scisys.com>: > > Hi, > > this patch 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. I've tested it 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>". Does someone > know sources for MP4 video streams? I could not find any with more than a few > minutes. That's not sufficient to test memory usage. > > Cheers, > Jörg > --- > libavformat/isom.h | 1 + > libavformat/mov.c | 52 +++++++++++++++++++++++++++++++++++++++++++++- > 2 files changed, 52 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..3a5cfa23f8 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,46 @@ 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; > + } > + } > +
> + if (!st) { > + av_log(mov->fc, AV_LOG_WARNING, "could not find corresponding > track id %u\n", frag->track_id); How can this happen? > + } else { > + 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 +8018,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); I guess this is only true if the stream actually is fragmented. > + > if (stream_index >= s->nb_streams) > return AVERROR_INVALIDDATA; > @@ -8063,6 +8109,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 }, Carl Eugen _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".