}
-int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat,
+int avformat_alloc_output_context2(AVFormatContext **avctx, ff_const59 AVOutputFormat *oformat,
const char *format, const char *filename)
{
AVFormatContext *s = avformat_alloc_context();
AVStream *st;
AVDictionary *tmp = NULL;
AVCodecParameters *par = NULL;
- AVOutputFormat *of = s->oformat;
+ const AVOutputFormat *of = s->oformat;
const AVCodecDescriptor *desc;
AVDictionaryEntry *e;
}
}
+static void deinit_muxer(AVFormatContext *s)
+{
+ if (s->oformat && s->oformat->deinit && s->internal->initialized)
+ s->oformat->deinit(s);
+ s->internal->initialized =
+ s->internal->streams_initialized = 0;
+}
+
int avformat_init_output(AVFormatContext *s, AVDictionary **options)
{
int ret = 0;
return streams_already_initialized;
fail:
- if (s->oformat->deinit)
- s->oformat->deinit(s);
+ deinit_muxer(s);
return ret;
}
#define AV_PKT_FLAG_UNCODED_FRAME 0x2000
-/* Note: using sizeof(AVFrame) from outside lavu is unsafe in general, but
- it is only being used internally to this file as a consistency check.
- The value is chosen to be very unlikely to appear on its own and to cause
- immediate failure if used anywhere as a real size. */
-#define UNCODED_FRAME_PACKET_SIZE (INT_MIN / 3 * 2 + (int)sizeof(AVFrame))
-
#if FF_API_COMPUTE_PKT_FIELDS2 && FF_API_LAVF_AVCTX
FF_DISABLE_DEPRECATION_WARNINGS
switch (st->codecpar->codec_type) {
case AVMEDIA_TYPE_AUDIO:
frame_size = (pkt->flags & AV_PKT_FLAG_UNCODED_FRAME) ?
- ((AVFrame *)pkt->data)->nb_samples :
+ (*(AVFrame **)pkt->data)->nb_samples :
av_get_audio_frame_duration(st->codec, pkt->size);
/* HACK/FIXME, we skip the initial 0 size packets as they are most
}
if ((pkt->flags & AV_PKT_FLAG_UNCODED_FRAME)) {
- AVFrame *frame = (AVFrame *)pkt->data;
- av_assert0(pkt->size == UNCODED_FRAME_PACKET_SIZE);
- ret = s->oformat->write_uncoded_frame(s, pkt->stream_index, &frame, 0);
- av_frame_free(&frame);
+ AVFrame **frame = (AVFrame **)pkt->data;
+ av_assert0(pkt->size == sizeof(*frame));
+ ret = s->oformat->write_uncoded_frame(s, pkt->stream_index, frame, 0);
+ av_packet_unref(pkt);
} else {
ret = s->oformat->write_packet(s, pkt);
}
if (ret < 0) {
pkt->pts = pts_backup;
pkt->dts = dts_backup;
- }
+ } else
+ s->streams[pkt->stream_index]->nb_frames++;
return ret;
}
static int check_packet(AVFormatContext *s, AVPacket *pkt)
{
- if (!pkt)
- return 0;
-
if (pkt->stream_index < 0 || pkt->stream_index >= s->nb_streams) {
av_log(s, AV_LOG_ERROR, "Invalid packet stream index: %d\n",
pkt->stream_index);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
return 0;
av_log(ctx, AV_LOG_ERROR,
- "Failed to send packet to filter %s for stream %d\n",
+ "Failed to receive packet from filter %s for stream %d\n",
ctx->filter->name, pkt->stream_index);
if (s->error_recognition & AV_EF_EXPLODE)
return ret;
{
int ret;
- ret = prepare_input_packet(s, pkt);
- if (ret < 0)
- return ret;
-
if (!pkt) {
if (s->oformat->flags & AVFMT_ALLOW_FLUSH) {
ret = s->oformat->write_packet(s, NULL);
return 1;
}
+ ret = prepare_input_packet(s, pkt);
+ if (ret < 0)
+ return ret;
+
ret = do_packet_auto_bsf(s, pkt);
if (ret <= 0)
return ret;
return ret;
#endif
- ret = write_packet(s, pkt);
- if (ret >= 0 && s->pb && s->pb->error < 0)
- ret = s->pb->error;
-
- if (ret >= 0)
- s->streams[pkt->stream_index]->nb_frames++;
- return ret;
+ return write_packet(s, pkt);
}
#define CHUNK_START 0x1000
int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
- int (*compare)(AVFormatContext *, AVPacket *, AVPacket *))
+ int (*compare)(AVFormatContext *, const AVPacket *, const AVPacket *))
{
int ret;
AVPacketList **next_point, *this_pktl;
- AVStream *st = s->streams[pkt->stream_index];
- int chunked = s->max_chunk_size || s->max_chunk_duration;
+ AVStream *st = s->streams[pkt->stream_index];
+ int chunked = s->max_chunk_size || s->max_chunk_duration;
- this_pktl = av_mallocz(sizeof(AVPacketList));
+ this_pktl = av_malloc(sizeof(AVPacketList));
if (!this_pktl)
return AVERROR(ENOMEM);
- if ((pkt->flags & AV_PKT_FLAG_UNCODED_FRAME)) {
- av_assert0(pkt->size == UNCODED_FRAME_PACKET_SIZE);
- av_assert0(((AVFrame *)pkt->data)->buf);
- this_pktl->pkt = *pkt;
- pkt->buf = NULL;
- pkt->side_data = NULL;
- pkt->side_data_elems = 0;
- } else {
- if ((ret = av_packet_ref(&this_pktl->pkt, pkt)) < 0) {
- av_free(this_pktl);
- return ret;
- }
+ if ((ret = av_packet_make_refcounted(pkt)) < 0) {
+ av_free(this_pktl);
+ return ret;
}
- if (s->streams[pkt->stream_index]->last_in_packet_buffer) {
+ av_packet_move_ref(&this_pktl->pkt, pkt);
+ pkt = &this_pktl->pkt;
+
+ if (st->last_in_packet_buffer) {
next_point = &(st->last_in_packet_buffer->next);
} else {
next_point = &s->internal->packet_buffer;
st->interleaver_chunk_duration += pkt->duration;
if ( (s->max_chunk_size && st->interleaver_chunk_size > s->max_chunk_size)
|| (max && st->interleaver_chunk_duration > max)) {
- st->interleaver_chunk_size = 0;
- this_pktl->pkt.flags |= CHUNK_START;
+ st->interleaver_chunk_size = 0;
+ pkt->flags |= CHUNK_START;
if (max && st->interleaver_chunk_duration > max) {
int64_t syncoffset = (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)*max/2;
int64_t syncto = av_rescale(pkt->dts + syncoffset, 1, max)*max - syncoffset;
}
}
if (*next_point) {
- if (chunked && !(this_pktl->pkt.flags & CHUNK_START))
+ if (chunked && !(pkt->flags & CHUNK_START))
goto next_non_null;
if (compare(s, &s->internal->packet_buffer_end->pkt, pkt)) {
this_pktl->next = *next_point;
- s->streams[pkt->stream_index]->last_in_packet_buffer =
- *next_point = this_pktl;
-
- av_packet_unref(pkt);
+ st->last_in_packet_buffer = *next_point = this_pktl;
return 0;
}
-static int interleave_compare_dts(AVFormatContext *s, AVPacket *next,
- AVPacket *pkt)
+static int interleave_compare_dts(AVFormatContext *s, const AVPacket *next,
+ const AVPacket *pkt)
{
AVStream *st = s->streams[pkt->stream_index];
AVStream *st2 = s->streams[next->stream_index];
int comp = av_compare_ts(next->dts, st2->time_base, pkt->dts,
st->time_base);
- if (s->audio_preload && ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) != (st2->codecpar->codec_type == AVMEDIA_TYPE_AUDIO))) {
- int64_t ts = av_rescale_q(pkt ->dts, st ->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st ->codecpar->codec_type == AVMEDIA_TYPE_AUDIO);
- int64_t ts2= av_rescale_q(next->dts, st2->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st2->codecpar->codec_type == AVMEDIA_TYPE_AUDIO);
- if (ts == ts2) {
- ts= ( pkt ->dts* st->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st ->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)* st->time_base.den)*st2->time_base.den
- -( next->dts*st2->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st2->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)*st2->time_base.den)* st->time_base.den;
- ts2=0;
+ if (s->audio_preload) {
+ int preload = st ->codecpar->codec_type == AVMEDIA_TYPE_AUDIO;
+ int preload2 = st2->codecpar->codec_type == AVMEDIA_TYPE_AUDIO;
+ if (preload != preload2) {
+ int64_t ts, ts2;
+ preload *= s->audio_preload;
+ preload2 *= s->audio_preload;
+ ts = av_rescale_q(pkt ->dts, st ->time_base, AV_TIME_BASE_Q) - preload;
+ ts2= av_rescale_q(next->dts, st2->time_base, AV_TIME_BASE_Q) - preload2;
+ if (ts == ts2) {
+ ts = ((uint64_t)pkt ->dts*st ->time_base.num*AV_TIME_BASE - (uint64_t)preload *st ->time_base.den)*st2->time_base.den
+ - ((uint64_t)next->dts*st2->time_base.num*AV_TIME_BASE - (uint64_t)preload2*st2->time_base.den)*st ->time_base.den;
+ ts2 = 0;
+ }
+ comp = (ts2 > ts) - (ts2 < ts);
}
- comp= (ts>ts2) - (ts<ts2);
}
if (comp == 0)
{
int ret, flush = 0;
- ret = prepare_input_packet(s, pkt);
- if (ret < 0)
- goto fail;
-
if (pkt) {
AVStream *st = s->streams[pkt->stream_index];
+ ret = prepare_input_packet(s, pkt);
+ if (ret < 0)
+ goto fail;
+
ret = do_packet_auto_bsf(s, pkt);
if (ret == 0)
return 0;
return ret;
ret = write_packet(s, &opkt);
- if (ret >= 0)
- s->streams[opkt.stream_index]->nb_frames++;
av_packet_unref(&opkt);
if (ret < 0)
return ret;
- if(s->pb && s->pb->error)
- return s->pb->error;
}
fail:
av_packet_unref(pkt);
break;
ret = write_packet(s, &pkt);
- if (ret >= 0)
- s->streams[pkt.stream_index]->nb_frames++;
av_packet_unref(&pkt);
if (ret < 0)
goto fail;
- if(s->pb && s->pb->error)
- goto fail;
}
fail:
}
}
- if (s->oformat->deinit)
- s->oformat->deinit(s);
-
- s->internal->initialized =
- s->internal->streams_initialized = 0;
+ deinit_muxer(s);
if (s->pb)
avio_flush(s->pb);
local_pkt = *pkt;
local_pkt.stream_index = dst_stream;
- if (pkt->pts != AV_NOPTS_VALUE)
- local_pkt.pts = av_rescale_q(pkt->pts,
- src->streams[pkt->stream_index]->time_base,
- dst->streams[dst_stream]->time_base);
- if (pkt->dts != AV_NOPTS_VALUE)
- local_pkt.dts = av_rescale_q(pkt->dts,
- src->streams[pkt->stream_index]->time_base,
- dst->streams[dst_stream]->time_base);
- if (pkt->duration)
- local_pkt.duration = av_rescale_q(pkt->duration,
- src->streams[pkt->stream_index]->time_base,
- dst->streams[dst_stream]->time_base);
+
+ av_packet_rescale_ts(&local_pkt,
+ src->streams[pkt->stream_index]->time_base,
+ dst->streams[dst_stream]->time_base);
if (interleave) ret = av_interleaved_write_frame(dst, &local_pkt);
else ret = av_write_frame(dst, &local_pkt);
return ret;
}
-static int av_write_uncoded_frame_internal(AVFormatContext *s, int stream_index,
- AVFrame *frame, int interleaved)
+static void uncoded_frame_free(void *unused, uint8_t *data)
+{
+ av_frame_free((AVFrame **)data);
+ av_free(data);
+}
+
+static int write_uncoded_frame_internal(AVFormatContext *s, int stream_index,
+ AVFrame *frame, int interleaved)
{
AVPacket pkt, *pktp;
av_assert0(s->oformat);
- if (!s->oformat->write_uncoded_frame)
+ if (!s->oformat->write_uncoded_frame) {
+ av_frame_free(&frame);
return AVERROR(ENOSYS);
+ }
if (!frame) {
pktp = NULL;
} else {
+ size_t bufsize = sizeof(frame) + AV_INPUT_BUFFER_PADDING_SIZE;
+ AVFrame **framep = av_mallocz(bufsize);
+
+ if (!framep)
+ goto fail;
pktp = &pkt;
av_init_packet(&pkt);
- pkt.data = (void *)frame;
- pkt.size = UNCODED_FRAME_PACKET_SIZE;
+ pkt.buf = av_buffer_create((void *)framep, bufsize,
+ uncoded_frame_free, NULL, 0);
+ if (!pkt.buf) {
+ av_free(framep);
+ fail:
+ av_frame_free(&frame);
+ return AVERROR(ENOMEM);
+ }
+ *framep = frame;
+
+ pkt.data = (void *)framep;
+ pkt.size = sizeof(frame);
pkt.pts =
pkt.dts = frame->pts;
pkt.duration = frame->pkt_duration;
int av_write_uncoded_frame(AVFormatContext *s, int stream_index,
AVFrame *frame)
{
- return av_write_uncoded_frame_internal(s, stream_index, frame, 0);
+ return write_uncoded_frame_internal(s, stream_index, frame, 0);
}
int av_interleaved_write_uncoded_frame(AVFormatContext *s, int stream_index,
AVFrame *frame)
{
- return av_write_uncoded_frame_internal(s, stream_index, frame, 1);
+ return write_uncoded_frame_internal(s, stream_index, frame, 1);
}
int av_write_uncoded_frame_query(AVFormatContext *s, int stream_index)