forked from FFmpeg/FFmpeg
lavf: move muxing-specific fields from FFFormatContext to FormatContextInternal
This commit is contained in:
parent
772911d3a8
commit
6d05e7e314
5 changed files with 78 additions and 68 deletions
|
@ -147,13 +147,15 @@ void ff_flush_packet_queue(AVFormatContext *s)
|
||||||
|
|
||||||
void avformat_free_context(AVFormatContext *s)
|
void avformat_free_context(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
|
FormatContextInternal *fci;
|
||||||
FFFormatContext *si;
|
FFFormatContext *si;
|
||||||
|
|
||||||
if (!s)
|
if (!s)
|
||||||
return;
|
return;
|
||||||
si = ffformatcontext(s);
|
fci = ff_fc_internal(s);
|
||||||
|
si = &fci->fc;
|
||||||
|
|
||||||
if (s->oformat && ffofmt(s->oformat)->deinit && si->initialized)
|
if (s->oformat && ffofmt(s->oformat)->deinit && fci->initialized)
|
||||||
ffofmt(s->oformat)->deinit(s);
|
ffofmt(s->oformat)->deinit(s);
|
||||||
|
|
||||||
av_opt_free(s);
|
av_opt_free(s);
|
||||||
|
|
|
@ -32,6 +32,45 @@
|
||||||
|
|
||||||
typedef struct FormatContextInternal {
|
typedef struct FormatContextInternal {
|
||||||
FFFormatContext fc;
|
FFFormatContext fc;
|
||||||
|
|
||||||
|
union {
|
||||||
|
// muxing only
|
||||||
|
struct {
|
||||||
|
/**
|
||||||
|
* Whether or not avformat_init_output has already been called
|
||||||
|
*/
|
||||||
|
int initialized;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether or not avformat_init_output fully initialized streams
|
||||||
|
*/
|
||||||
|
int streams_initialized;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of streams relevant for interleaving.
|
||||||
|
* Muxing only.
|
||||||
|
*/
|
||||||
|
int nb_interleaved_streams;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The interleavement function in use. Always set.
|
||||||
|
*/
|
||||||
|
int (*interleave_packet)(struct AVFormatContext *s, AVPacket *pkt,
|
||||||
|
int flush, int has_packet);
|
||||||
|
|
||||||
|
#if FF_API_COMPUTE_PKT_FIELDS2
|
||||||
|
int missing_ts_warning;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
#if FF_API_LAVF_SHORTEST
|
||||||
|
/**
|
||||||
|
* Timestamp of the end of the shortest stream.
|
||||||
|
*/
|
||||||
|
int64_t shortest_end;
|
||||||
|
#endif
|
||||||
} FormatContextInternal;
|
} FormatContextInternal;
|
||||||
|
|
||||||
static av_always_inline FormatContextInternal *ff_fc_internal(AVFormatContext *s)
|
static av_always_inline FormatContextInternal *ff_fc_internal(AVFormatContext *s)
|
||||||
|
|
|
@ -67,12 +67,6 @@ typedef struct FFFormatContext {
|
||||||
*/
|
*/
|
||||||
AVFormatContext pub;
|
AVFormatContext pub;
|
||||||
|
|
||||||
/**
|
|
||||||
* Number of streams relevant for interleaving.
|
|
||||||
* Muxing only.
|
|
||||||
*/
|
|
||||||
int nb_interleaved_streams;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the timestamp shift offset has already been determined.
|
* Whether the timestamp shift offset has already been determined.
|
||||||
* -1: disabled, 0: not yet determined, 1: determined.
|
* -1: disabled, 0: not yet determined, 1: determined.
|
||||||
|
@ -84,12 +78,6 @@ typedef struct FFFormatContext {
|
||||||
} avoid_negative_ts_status;
|
} avoid_negative_ts_status;
|
||||||
#define AVOID_NEGATIVE_TS_ENABLED(status) ((status) >= 0)
|
#define AVOID_NEGATIVE_TS_ENABLED(status) ((status) >= 0)
|
||||||
|
|
||||||
/**
|
|
||||||
* The interleavement function in use. Always set for muxers.
|
|
||||||
*/
|
|
||||||
int (*interleave_packet)(struct AVFormatContext *s, AVPacket *pkt,
|
|
||||||
int flush, int has_packet);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This buffer is only needed when packets were already buffered but
|
* This buffer is only needed when packets were already buffered but
|
||||||
* not decoded, for example to get the codec parameters in MPEG
|
* not decoded, for example to get the codec parameters in MPEG
|
||||||
|
@ -137,33 +125,12 @@ typedef struct FFFormatContext {
|
||||||
*/
|
*/
|
||||||
int raw_packet_buffer_size;
|
int raw_packet_buffer_size;
|
||||||
|
|
||||||
#if FF_API_COMPUTE_PKT_FIELDS2
|
|
||||||
int missing_ts_warning;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if FF_API_AVSTREAM_SIDE_DATA
|
#if FF_API_AVSTREAM_SIDE_DATA
|
||||||
int inject_global_side_data;
|
int inject_global_side_data;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int avoid_negative_ts_use_pts;
|
int avoid_negative_ts_use_pts;
|
||||||
|
|
||||||
#if FF_API_LAVF_SHORTEST
|
|
||||||
/**
|
|
||||||
* Timestamp of the end of the shortest stream.
|
|
||||||
*/
|
|
||||||
int64_t shortest_end;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not avformat_init_output has already been called
|
|
||||||
*/
|
|
||||||
int initialized;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not avformat_init_output fully initialized streams
|
|
||||||
*/
|
|
||||||
int streams_initialized;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID3v2 tag useful for MP3 demuxing
|
* ID3v2 tag useful for MP3 demuxing
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -186,7 +186,7 @@ static int validate_codec_tag(const AVFormatContext *s, const AVStream *st)
|
||||||
|
|
||||||
static int init_muxer(AVFormatContext *s, AVDictionary **options)
|
static int init_muxer(AVFormatContext *s, AVDictionary **options)
|
||||||
{
|
{
|
||||||
FFFormatContext *const si = ffformatcontext(s);
|
FormatContextInternal *const fci = ff_fc_internal(s);
|
||||||
AVDictionary *tmp = NULL;
|
AVDictionary *tmp = NULL;
|
||||||
const FFOutputFormat *of = ffofmt(s->oformat);
|
const FFOutputFormat *of = ffofmt(s->oformat);
|
||||||
AVDictionaryEntry *e;
|
AVDictionaryEntry *e;
|
||||||
|
@ -347,13 +347,13 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||||
|
|
||||||
if (par->codec_type != AVMEDIA_TYPE_ATTACHMENT &&
|
if (par->codec_type != AVMEDIA_TYPE_ATTACHMENT &&
|
||||||
par->codec_id != AV_CODEC_ID_SMPTE_2038)
|
par->codec_id != AV_CODEC_ID_SMPTE_2038)
|
||||||
si->nb_interleaved_streams++;
|
fci->nb_interleaved_streams++;
|
||||||
}
|
}
|
||||||
si->interleave_packet = of->interleave_packet;
|
fci->interleave_packet = of->interleave_packet;
|
||||||
if (!si->interleave_packet)
|
if (!fci->interleave_packet)
|
||||||
si->interleave_packet = si->nb_interleaved_streams > 1 ?
|
fci->interleave_packet = fci->nb_interleaved_streams > 1 ?
|
||||||
ff_interleave_packet_per_dts :
|
ff_interleave_packet_per_dts :
|
||||||
ff_interleave_packet_passthrough;
|
ff_interleave_packet_passthrough;
|
||||||
|
|
||||||
if (!s->priv_data && of->priv_data_size > 0) {
|
if (!s->priv_data && of->priv_data_size > 0) {
|
||||||
s->priv_data = av_mallocz(of->priv_data_size);
|
s->priv_data = av_mallocz(of->priv_data_size);
|
||||||
|
@ -456,24 +456,24 @@ static void flush_if_needed(AVFormatContext *s)
|
||||||
|
|
||||||
static void deinit_muxer(AVFormatContext *s)
|
static void deinit_muxer(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
FFFormatContext *const si = ffformatcontext(s);
|
FormatContextInternal *const fci = ff_fc_internal(s);
|
||||||
const FFOutputFormat *const of = ffofmt(s->oformat);
|
const FFOutputFormat *const of = ffofmt(s->oformat);
|
||||||
if (of && of->deinit && si->initialized)
|
if (of && of->deinit && fci->initialized)
|
||||||
of->deinit(s);
|
of->deinit(s);
|
||||||
si->initialized =
|
fci->initialized =
|
||||||
si->streams_initialized = 0;
|
fci->streams_initialized = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int avformat_init_output(AVFormatContext *s, AVDictionary **options)
|
int avformat_init_output(AVFormatContext *s, AVDictionary **options)
|
||||||
{
|
{
|
||||||
FFFormatContext *const si = ffformatcontext(s);
|
FormatContextInternal *const fci = ff_fc_internal(s);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if ((ret = init_muxer(s, options)) < 0)
|
if ((ret = init_muxer(s, options)) < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
si->initialized = 1;
|
fci->initialized = 1;
|
||||||
si->streams_initialized = ret;
|
fci->streams_initialized = ret;
|
||||||
|
|
||||||
if (ffofmt(s->oformat)->init && ret) {
|
if (ffofmt(s->oformat)->init && ret) {
|
||||||
if ((ret = init_pts(s)) < 0)
|
if ((ret = init_pts(s)) < 0)
|
||||||
|
@ -487,9 +487,9 @@ int avformat_init_output(AVFormatContext *s, AVDictionary **options)
|
||||||
|
|
||||||
int avformat_write_header(AVFormatContext *s, AVDictionary **options)
|
int avformat_write_header(AVFormatContext *s, AVDictionary **options)
|
||||||
{
|
{
|
||||||
FFFormatContext *const si = ffformatcontext(s);
|
FormatContextInternal *const fci = ff_fc_internal(s);
|
||||||
int already_initialized = si->initialized;
|
int already_initialized = fci->initialized;
|
||||||
int streams_already_initialized = si->streams_initialized;
|
int streams_already_initialized = fci->streams_initialized;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (!already_initialized)
|
if (!already_initialized)
|
||||||
|
@ -509,7 +509,7 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options)
|
||||||
if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
|
if (!(s->oformat->flags & AVFMT_NOFILE) && s->pb)
|
||||||
avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_UNKNOWN);
|
avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_UNKNOWN);
|
||||||
|
|
||||||
if (!si->streams_initialized) {
|
if (!fci->streams_initialized) {
|
||||||
if ((ret = init_pts(s)) < 0)
|
if ((ret = init_pts(s)) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
@ -529,12 +529,12 @@ FF_DISABLE_DEPRECATION_WARNINGS
|
||||||
//FIXME merge with compute_pkt_fields
|
//FIXME merge with compute_pkt_fields
|
||||||
static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket *pkt)
|
static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket *pkt)
|
||||||
{
|
{
|
||||||
FFFormatContext *const si = ffformatcontext(s);
|
FormatContextInternal *const fci = ff_fc_internal(s);
|
||||||
FFStream *const sti = ffstream(st);
|
FFStream *const sti = ffstream(st);
|
||||||
int delay = st->codecpar->video_delay;
|
int delay = st->codecpar->video_delay;
|
||||||
int frame_size;
|
int frame_size;
|
||||||
|
|
||||||
if (!si->missing_ts_warning &&
|
if (!fci->missing_ts_warning &&
|
||||||
!(s->oformat->flags & AVFMT_NOTIMESTAMPS) &&
|
!(s->oformat->flags & AVFMT_NOTIMESTAMPS) &&
|
||||||
(!(st->disposition & AV_DISPOSITION_ATTACHED_PIC) || (st->disposition & AV_DISPOSITION_TIMED_THUMBNAILS)) &&
|
(!(st->disposition & AV_DISPOSITION_ATTACHED_PIC) || (st->disposition & AV_DISPOSITION_TIMED_THUMBNAILS)) &&
|
||||||
(pkt->pts == AV_NOPTS_VALUE || pkt->dts == AV_NOPTS_VALUE)) {
|
(pkt->pts == AV_NOPTS_VALUE || pkt->dts == AV_NOPTS_VALUE)) {
|
||||||
|
@ -542,7 +542,7 @@ static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket *
|
||||||
"Timestamps are unset in a packet for stream %d. "
|
"Timestamps are unset in a packet for stream %d. "
|
||||||
"This is deprecated and will stop working in the future. "
|
"This is deprecated and will stop working in the future. "
|
||||||
"Fix your code to set the timestamps properly\n", st->index);
|
"Fix your code to set the timestamps properly\n", st->index);
|
||||||
si->missing_ts_warning = 1;
|
fci->missing_ts_warning = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->debug & FF_FDEBUG_TS)
|
if (s->debug & FF_FDEBUG_TS)
|
||||||
|
@ -960,7 +960,8 @@ static int interleave_compare_dts(AVFormatContext *s, const AVPacket *next,
|
||||||
int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *pkt,
|
int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *pkt,
|
||||||
int flush, int has_packet)
|
int flush, int has_packet)
|
||||||
{
|
{
|
||||||
FFFormatContext *const si = ffformatcontext(s);
|
FormatContextInternal *const fci = ff_fc_internal(s);
|
||||||
|
FFFormatContext *const si = &fci->fc;
|
||||||
int stream_count = 0;
|
int stream_count = 0;
|
||||||
int noninterleaved_count = 0;
|
int noninterleaved_count = 0;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -985,14 +986,14 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *pkt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (si->nb_interleaved_streams == stream_count)
|
if (fci->nb_interleaved_streams == stream_count)
|
||||||
flush = 1;
|
flush = 1;
|
||||||
|
|
||||||
if (s->max_interleave_delta > 0 &&
|
if (s->max_interleave_delta > 0 &&
|
||||||
si->packet_buffer.head &&
|
si->packet_buffer.head &&
|
||||||
si->packet_buffer.head->pkt.dts != AV_NOPTS_VALUE &&
|
si->packet_buffer.head->pkt.dts != AV_NOPTS_VALUE &&
|
||||||
!flush &&
|
!flush &&
|
||||||
si->nb_interleaved_streams == stream_count+noninterleaved_count
|
fci->nb_interleaved_streams == stream_count+noninterleaved_count
|
||||||
) {
|
) {
|
||||||
AVPacket *const top_pkt = &si->packet_buffer.head->pkt;
|
AVPacket *const top_pkt = &si->packet_buffer.head->pkt;
|
||||||
int64_t delta_dts = INT64_MIN;
|
int64_t delta_dts = INT64_MIN;
|
||||||
|
@ -1028,15 +1029,15 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *pkt,
|
||||||
if (si->packet_buffer.head &&
|
if (si->packet_buffer.head &&
|
||||||
eof &&
|
eof &&
|
||||||
(s->flags & AVFMT_FLAG_SHORTEST) &&
|
(s->flags & AVFMT_FLAG_SHORTEST) &&
|
||||||
si->shortest_end == AV_NOPTS_VALUE) {
|
fci->shortest_end == AV_NOPTS_VALUE) {
|
||||||
AVPacket *const top_pkt = &si->packet_buffer.head->pkt;
|
AVPacket *const top_pkt = &si->packet_buffer.head->pkt;
|
||||||
|
|
||||||
si->shortest_end = av_rescale_q(top_pkt->dts,
|
fci->shortest_end = av_rescale_q(top_pkt->dts,
|
||||||
s->streams[top_pkt->stream_index]->time_base,
|
s->streams[top_pkt->stream_index]->time_base,
|
||||||
AV_TIME_BASE_Q);
|
AV_TIME_BASE_Q);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (si->shortest_end != AV_NOPTS_VALUE) {
|
if (fci->shortest_end != AV_NOPTS_VALUE) {
|
||||||
while (si->packet_buffer.head) {
|
while (si->packet_buffer.head) {
|
||||||
PacketListEntry *pktl = si->packet_buffer.head;
|
PacketListEntry *pktl = si->packet_buffer.head;
|
||||||
AVPacket *const top_pkt = &pktl->pkt;
|
AVPacket *const top_pkt = &pktl->pkt;
|
||||||
|
@ -1045,7 +1046,7 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *pkt,
|
||||||
int64_t top_dts = av_rescale_q(top_pkt->dts, st->time_base,
|
int64_t top_dts = av_rescale_q(top_pkt->dts, st->time_base,
|
||||||
AV_TIME_BASE_Q);
|
AV_TIME_BASE_Q);
|
||||||
|
|
||||||
if (si->shortest_end + 1 >= top_dts)
|
if (fci->shortest_end + 1 >= top_dts)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
si->packet_buffer.head = pktl->next;
|
si->packet_buffer.head = pktl->next;
|
||||||
|
@ -1134,9 +1135,10 @@ static int check_bitstream(AVFormatContext *s, FFStream *sti, AVPacket *pkt)
|
||||||
static int interleaved_write_packet(AVFormatContext *s, AVPacket *pkt,
|
static int interleaved_write_packet(AVFormatContext *s, AVPacket *pkt,
|
||||||
int flush, int has_packet)
|
int flush, int has_packet)
|
||||||
{
|
{
|
||||||
FFFormatContext *const si = ffformatcontext(s);
|
FormatContextInternal *const fci = ff_fc_internal(s);
|
||||||
|
|
||||||
for (;; ) {
|
for (;; ) {
|
||||||
int ret = si->interleave_packet(s, pkt, flush, has_packet);
|
int ret = fci->interleave_packet(s, pkt, flush, has_packet);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|
|
@ -185,7 +185,7 @@ AVFormatContext *avformat_alloc_context(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if FF_API_LAVF_SHORTEST
|
#if FF_API_LAVF_SHORTEST
|
||||||
si->shortest_end = AV_NOPTS_VALUE;
|
fci->shortest_end = AV_NOPTS_VALUE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
|
|
Loading…
Add table
Reference in a new issue