From cb80ec0b6cd7f954839427b4c86958d1475f2df4 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 13 Oct 2024 10:31:51 +0200 Subject: [PATCH] lavf: move demuxing-specific fields from FFFormatContext to FormatContextInternal --- libavformat/avformat.c | 12 +++--- libavformat/avformat_internal.h | 31 ++++++++++++++ libavformat/demux.c | 72 ++++++++++++++++++--------------- libavformat/demux_utils.c | 13 +++--- libavformat/internal.h | 25 ------------ 5 files changed, 85 insertions(+), 68 deletions(-) diff --git a/libavformat/avformat.c b/libavformat/avformat.c index 48acef72e5..eb9afad837 100644 --- a/libavformat/avformat.c +++ b/libavformat/avformat.c @@ -137,12 +137,13 @@ void ff_remove_stream_group(AVFormatContext *s, AVStreamGroup *stg) /* XXX: suppress the packet queue */ void ff_flush_packet_queue(AVFormatContext *s) { - FFFormatContext *const si = ffformatcontext(s); - avpriv_packet_list_free(&si->parse_queue); + FormatContextInternal *const fci = ff_fc_internal(s); + FFFormatContext *const si = &fci->fc; + avpriv_packet_list_free(&fci->parse_queue); avpriv_packet_list_free(&si->packet_buffer); - avpriv_packet_list_free(&si->raw_packet_buffer); + avpriv_packet_list_free(&fci->raw_packet_buffer); - si->raw_packet_buffer_size = 0; + fci->raw_packet_buffer_size = 0; } void avformat_free_context(AVFormatContext *s) @@ -191,7 +192,8 @@ void avformat_free_context(AVFormatContext *s) av_packet_free(&si->parse_pkt); av_freep(&s->streams); av_freep(&s->stream_groups); - ff_flush_packet_queue(s); + if (s->iformat) + ff_flush_packet_queue(s); av_freep(&s->url); av_free(s); } diff --git a/libavformat/avformat_internal.h b/libavformat/avformat_internal.h index c9c8ab60c5..b114dba659 100644 --- a/libavformat/avformat_internal.h +++ b/libavformat/avformat_internal.h @@ -63,6 +63,37 @@ typedef struct FormatContextInternal { int missing_ts_warning; #endif }; + + // demuxing only + struct { + /** + * Raw packets from the demuxer, prior to parsing and decoding. + * This buffer is used for buffering packets until the codec can + * be identified, as parsing cannot be done without knowing the + * codec. + */ + PacketList raw_packet_buffer; + + /** + * Sum of the size of packets in raw_packet_buffer, in bytes. + */ + int raw_packet_buffer_size; + + /** + * Packets split by the parser get queued here. + */ + PacketList parse_queue; + + /** + * Contexts and child contexts do not contain a metadata option + */ + int metafree; + + /** + * Set if chapter ids are strictly monotonic. + */ + int chapter_ids_monotonic; + }; }; #if FF_API_LAVF_SHORTEST diff --git a/libavformat/demux.c b/libavformat/demux.c index 902056452d..658981cab8 100644 --- a/libavformat/demux.c +++ b/libavformat/demux.c @@ -216,6 +216,7 @@ static int update_stream_avctx(AVFormatContext *s) int avformat_open_input(AVFormatContext **ps, const char *filename, const AVInputFormat *fmt, AVDictionary **options) { + FormatContextInternal *fci; AVFormatContext *s = *ps; FFFormatContext *si; AVDictionary *tmp = NULL; @@ -224,7 +225,8 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, if (!s && !(s = avformat_alloc_context())) return AVERROR(ENOMEM); - si = ffformatcontext(s); + fci = ff_fc_internal(s); + si = &fci->fc; if (!s->av_class) { av_log(NULL, AV_LOG_ERROR, "Input context has not been properly allocated by avformat_alloc_context() and is not NULL either\n"); return AVERROR(EINVAL); @@ -337,7 +339,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, if (s->pb && !si->data_offset) si->data_offset = avio_tell(s->pb); - si->raw_packet_buffer_size = 0; + fci->raw_packet_buffer_size = 0; update_stream_avctx(s); @@ -411,7 +413,7 @@ static void force_codec_ids(AVFormatContext *s, AVStream *st) static int probe_codec(AVFormatContext *s, AVStream *st, const AVPacket *pkt) { - FFFormatContext *const si = ffformatcontext(s); + FormatContextInternal *const fci = ff_fc_internal(s); FFStream *const sti = ffstream(st); if (sti->request_probe > 0) { @@ -441,8 +443,8 @@ no_packet: } } - end = si->raw_packet_buffer_size >= s->probesize - || sti->probe_packets <= 0; + end = fci->raw_packet_buffer_size >= s->probesize || + sti->probe_packets <= 0; if (end || av_log2(pd->buf_size) != av_log2(pd->buf_size - pkt->size)) { int score = set_codec_from_probe_data(s, st, pd); @@ -564,7 +566,7 @@ static void update_timestamps(AVFormatContext *s, AVStream *st, AVPacket *pkt) */ static int handle_new_packet(AVFormatContext *s, AVPacket *pkt, int allow_passthrough) { - FFFormatContext *const si = ffformatcontext(s); + FormatContextInternal *const fci = ff_fc_internal(s); AVStream *st; FFStream *sti; int err; @@ -588,17 +590,17 @@ static int handle_new_packet(AVFormatContext *s, AVPacket *pkt, int allow_passth update_timestamps(s, st, pkt); - if (sti->request_probe <= 0 && allow_passthrough && !si->raw_packet_buffer.head) + if (sti->request_probe <= 0 && allow_passthrough && !fci->raw_packet_buffer.head) return 0; - err = avpriv_packet_list_put(&si->raw_packet_buffer, pkt, NULL, 0); + err = avpriv_packet_list_put(&fci->raw_packet_buffer, pkt, NULL, 0); if (err < 0) { av_packet_unref(pkt); return err; } - pkt = &si->raw_packet_buffer.tail->pkt; - si->raw_packet_buffer_size += pkt->size; + pkt = &fci->raw_packet_buffer.tail->pkt; + fci->raw_packet_buffer_size += pkt->size; err = probe_codec(s, st, pkt); if (err < 0) @@ -616,7 +618,7 @@ int ff_buffer_packet(AVFormatContext *s, AVPacket *pkt) int ff_read_packet(AVFormatContext *s, AVPacket *pkt) { - FFFormatContext *const si = ffformatcontext(s); + FormatContextInternal *const fci = ff_fc_internal(s); int err; #if FF_API_INIT_PACKET @@ -630,16 +632,16 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif for (;;) { - PacketListEntry *pktl = si->raw_packet_buffer.head; + PacketListEntry *pktl = fci->raw_packet_buffer.head; if (pktl) { AVStream *const st = s->streams[pktl->pkt.stream_index]; - if (si->raw_packet_buffer_size >= s->probesize) + if (fci->raw_packet_buffer_size >= s->probesize) if ((err = probe_codec(s, st, NULL)) < 0) return err; if (ffstream(st)->request_probe <= 0) { - avpriv_packet_list_get(&si->raw_packet_buffer, pkt); - si->raw_packet_buffer_size -= pkt->size; + avpriv_packet_list_get(&fci->raw_packet_buffer, pkt); + fci->raw_packet_buffer_size -= pkt->size; return 0; } } @@ -766,11 +768,12 @@ static int has_decode_delay_been_guessed(AVStream *st) static PacketListEntry *get_next_pkt(AVFormatContext *s, AVStream *st, PacketListEntry *pktl) { - FFFormatContext *const si = ffformatcontext(s); + FormatContextInternal *const fci = ff_fc_internal(s); + FFFormatContext *const si = &fci->fc; if (pktl->next) return pktl->next; if (pktl == si->packet_buffer.tail) - return si->parse_queue.head; + return fci->parse_queue.head; return NULL; } @@ -850,10 +853,11 @@ static void update_dts_from_pts(AVFormatContext *s, int stream_index, static void update_initial_timestamps(AVFormatContext *s, int stream_index, int64_t dts, int64_t pts, AVPacket *pkt) { - FFFormatContext *const si = ffformatcontext(s); + FormatContextInternal *const fci = ff_fc_internal(s); + FFFormatContext *const si = &fci->fc; AVStream *const st = s->streams[stream_index]; FFStream *const sti = ffstream(st); - PacketListEntry *pktl = si->packet_buffer.head ? si->packet_buffer.head : si->parse_queue.head; + PacketListEntry *pktl = si->packet_buffer.head ? si->packet_buffer.head : fci->parse_queue.head; uint64_t shift; @@ -903,9 +907,10 @@ static void update_initial_timestamps(AVFormatContext *s, int stream_index, static void update_initial_durations(AVFormatContext *s, AVStream *st, int stream_index, int64_t duration) { - FFFormatContext *const si = ffformatcontext(s); + FormatContextInternal *const fci = ff_fc_internal(s); + FFFormatContext *const si = &fci->fc; FFStream *const sti = ffstream(st); - PacketListEntry *pktl = si->packet_buffer.head ? si->packet_buffer.head : si->parse_queue.head; + PacketListEntry *pktl = si->packet_buffer.head ? si->packet_buffer.head : fci->parse_queue.head; int64_t cur_dts = RELATIVE_TS_BASE; if (sti->first_dts != AV_NOPTS_VALUE) { @@ -931,7 +936,7 @@ static void update_initial_durations(AVFormatContext *s, AVStream *st, av_log(s, AV_LOG_DEBUG, "first_dts %s but no packet with dts in the queue\n", av_ts2str(sti->first_dts)); return; } - pktl = si->packet_buffer.head ? si->packet_buffer.head : si->parse_queue.head; + pktl = si->packet_buffer.head ? si->packet_buffer.head : fci->parse_queue.head; sti->first_dts = cur_dts; } else if (sti->cur_dts != RELATIVE_TS_BASE) return; @@ -963,7 +968,8 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, AVCodecParserContext *pc, AVPacket *pkt, int64_t next_dts, int64_t next_pts) { - FFFormatContext *const si = ffformatcontext(s); + FormatContextInternal *const fci = ff_fc_internal(s); + FFFormatContext *const si = &fci->fc; FFStream *const sti = ffstream(st); int num, den, presentation_delayed, delay; int64_t offset; @@ -1048,7 +1054,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, } } - if (pkt->duration > 0 && (si->packet_buffer.head || si->parse_queue.head)) + if (pkt->duration > 0 && (si->packet_buffer.head || fci->parse_queue.head)) update_initial_durations(s, st, pkt->stream_index, pkt->duration); /* Correct timestamps with byte offset if demuxers only have timestamps @@ -1156,7 +1162,8 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, static int parse_packet(AVFormatContext *s, AVPacket *pkt, int stream_index, int flush) { - FFFormatContext *const si = ffformatcontext(s); + FormatContextInternal *const fci = ff_fc_internal(s); + FFFormatContext *const si = &fci->fc; AVPacket *out_pkt = si->parse_pkt; AVStream *st = s->streams[stream_index]; FFStream *const sti = ffstream(st); @@ -1249,7 +1256,7 @@ static int parse_packet(AVFormatContext *s, AVPacket *pkt, compute_pkt_fields(s, st, sti->parser, out_pkt, next_dts, next_pts); - ret = avpriv_packet_list_put(&si->parse_queue, + ret = avpriv_packet_list_put(&fci->parse_queue, out_pkt, NULL, 0); if (ret < 0) goto fail; @@ -1324,11 +1331,12 @@ static int extract_extradata(FFFormatContext *si, AVStream *st, const AVPacket * static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) { - FFFormatContext *const si = ffformatcontext(s); + FormatContextInternal *const fci = ff_fc_internal(s); + FFFormatContext *const si = &fci->fc; int ret, got_packet = 0; AVDictionary *metadata = NULL; - while (!got_packet && !si->parse_queue.head) { + while (!got_packet && !fci->parse_queue.head) { AVStream *st; FFStream *sti; @@ -1456,8 +1464,8 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) } } - if (!got_packet && si->parse_queue.head) - ret = avpriv_packet_list_get(&si->parse_queue, pkt); + if (!got_packet && fci->parse_queue.head) + ret = avpriv_packet_list_get(&fci->parse_queue, pkt); if (ret >= 0) { AVStream *const st = s->streams[pkt->stream_index]; @@ -1508,7 +1516,7 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) #endif } - if (!si->metafree) { + if (!fci->metafree) { int metaret = av_opt_get_dict_val(s, "metadata", AV_OPT_SEARCH_CHILDREN, &metadata); if (metadata) { s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED; @@ -1516,7 +1524,7 @@ static int read_frame_internal(AVFormatContext *s, AVPacket *pkt) av_dict_free(&metadata); av_opt_set_dict_val(s, "metadata", NULL, AV_OPT_SEARCH_CHILDREN); } - si->metafree = metaret == AVERROR_OPTION_NOT_FOUND; + fci->metafree = metaret == AVERROR_OPTION_NOT_FOUND; } if (s->debug & FF_FDEBUG_TS) diff --git a/libavformat/demux_utils.c b/libavformat/demux_utils.c index 86f551245b..fd0424524b 100644 --- a/libavformat/demux_utils.c +++ b/libavformat/demux_utils.c @@ -25,6 +25,7 @@ #include "libavcodec/bytestream.h" #include "libavcodec/packet_internal.h" #include "avformat.h" +#include "avformat_internal.h" #include "avio_internal.h" #include "demux.h" #include "internal.h" @@ -42,7 +43,7 @@ void avpriv_stream_set_need_parsing(AVStream *st, enum AVStreamParseType type) AVChapter *avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title) { - FFFormatContext *const si = ffformatcontext(s); + FormatContextInternal *const fci = ff_fc_internal(s); AVChapter *chapter = NULL; int ret; @@ -52,13 +53,13 @@ AVChapter *avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_ba } if (!s->nb_chapters) { - si->chapter_ids_monotonic = 1; - } else if (!si->chapter_ids_monotonic || s->chapters[s->nb_chapters-1]->id >= id) { + fci->chapter_ids_monotonic = 1; + } else if (!fci->chapter_ids_monotonic || s->chapters[s->nb_chapters-1]->id >= id) { for (unsigned i = 0; i < s->nb_chapters; i++) if (s->chapters[i]->id == id) chapter = s->chapters[i]; if (!chapter) - si->chapter_ids_monotonic = 0; + fci->chapter_ids_monotonic = 0; } if (!chapter) { @@ -92,7 +93,7 @@ void av_format_inject_global_side_data(AVFormatContext *s) int avformat_queue_attached_pictures(AVFormatContext *s) { - FFFormatContext *const si = ffformatcontext(s); + FormatContextInternal *const fci = ff_fc_internal(s); int ret; for (unsigned i = 0; i < s->nb_streams; i++) if (s->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC && @@ -104,7 +105,7 @@ int avformat_queue_attached_pictures(AVFormatContext *s) continue; } - ret = avpriv_packet_list_put(&si->raw_packet_buffer, + ret = avpriv_packet_list_put(&fci->raw_packet_buffer, &s->streams[i]->attached_pic, av_packet_ref, 0); if (ret < 0) diff --git a/libavformat/internal.h b/libavformat/internal.h index 9abb5f100e..6599cf5c0c 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -88,17 +88,6 @@ typedef struct FFFormatContext { /* av_seek_frame() support */ int64_t data_offset; /**< offset of the first packet */ - /** - * Raw packets from the demuxer, prior to parsing and decoding. - * This buffer is used for buffering packets until the codec can - * be identified, as parsing cannot be done without knowing the - * codec. - */ - PacketList raw_packet_buffer; - /** - * Packets split by the parser get queued here. - */ - PacketList parse_queue; /** * The generic code uses this as a temporary packet * to parse packets or for muxing, especially flushing. @@ -120,10 +109,6 @@ typedef struct FFFormatContext { * permanent ones). */ AVPacket *pkt; - /** - * Sum of the size of packets in raw_packet_buffer, in bytes. - */ - int raw_packet_buffer_size; #if FF_API_AVSTREAM_SIDE_DATA int inject_global_side_data; @@ -140,16 +125,6 @@ typedef struct FFFormatContext { * Prefer the codec framerate for avg_frame_rate computation. */ int prefer_codec_framerate; - - /** - * Set if chapter ids are strictly monotonic. - */ - int chapter_ids_monotonic; - - /** - * Contexts and child contexts do not contain a metadata option - */ - int metafree; } FFFormatContext; static av_always_inline FFFormatContext *ffformatcontext(AVFormatContext *s)