lavf: move demuxing-specific fields from FFFormatContext to FormatContextInternal

This commit is contained in:
Anton Khirnov 2024-10-13 10:31:51 +02:00
parent 6d05e7e314
commit cb80ec0b6c
5 changed files with 85 additions and 68 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)