diff options
author | Nicolas George <george@nsup.org> | 2013-12-31 14:09:48 +0100 |
---|---|---|
committer | Nicolas George <george@nsup.org> | 2014-02-11 10:29:02 +0100 |
commit | 1b05ac220ef1370cb6ba805b82ca764e4c5bed25 (patch) | |
tree | fd45a2be18ee8ab1ebc2c610019666db9b7522c8 /libavformat/mux.c | |
parent | 6c12b1de064d2604d19cb4c238a788cfed9679ac (diff) | |
download | ffmpeg-streaming-1b05ac220ef1370cb6ba805b82ca764e4c5bed25.zip ffmpeg-streaming-1b05ac220ef1370cb6ba805b82ca764e4c5bed25.tar.gz |
lavf: add write_uncoded_frame() API.
Diffstat (limited to 'libavformat/mux.c')
-rw-r--r-- | libavformat/mux.c | 79 |
1 files changed, 75 insertions, 4 deletions
diff --git a/libavformat/mux.c b/libavformat/mux.c index 14e72e8..c535c82 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -417,6 +417,15 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options) return 0; } +#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)) + + //FIXME merge with compute_pkt_fields static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt) { @@ -482,7 +491,9 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt) /* update pts */ switch (st->codec->codec_type) { case AVMEDIA_TYPE_AUDIO: - frame_size = ff_get_audio_frame_size(st->codec, pkt->size, 1); + frame_size = (pkt->flags & AV_PKT_FLAG_UNCODED_FRAME) ? + ((AVFrame *)pkt->data)->nb_samples : + ff_get_audio_frame_size(st->codec, pkt->size, 1); /* HACK/FIXME, we skip the initial 0 size packets as they are most * likely equal to the encoder delay, but it would be better if we @@ -549,7 +560,14 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) } did_split = av_packet_split_side_data(pkt); - ret = s->oformat->write_packet(s, pkt); + 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); + } else { + ret = s->oformat->write_packet(s, pkt); + } if (s->flush_packets && s->pb && ret >= 0 && s->flags & AVFMT_FLAG_FLUSH_PACKETS) avio_flush(s->pb); @@ -632,8 +650,13 @@ FF_DISABLE_DEPRECATION_WARNINGS FF_ENABLE_DEPRECATION_WARNINGS #endif pkt->buf = NULL; - av_dup_packet(&this_pktl->pkt); // duplicate the packet if it uses non-allocated memory - av_copy_packet_side_data(&this_pktl->pkt, &this_pktl->pkt); // copy side data + if ((pkt->flags & AV_PKT_FLAG_UNCODED_FRAME)) { + av_assert0(pkt->size == UNCODED_FRAME_PACKET_SIZE); + av_assert0(((AVFrame *)pkt->data)->buf); + } else { + av_dup_packet(&this_pktl->pkt); // duplicate the packet if it uses non-allocated memory + av_copy_packet_side_data(&this_pktl->pkt, &this_pktl->pkt); // copy side data + } if (s->streams[pkt->stream_index]->last_in_packet_buffer) { next_point = &(st->last_in_packet_buffer->next); @@ -932,3 +955,51 @@ int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt, dst->streams[dst_stream]->time_base); return av_write_frame(dst, &local_pkt); } + +static int av_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) + return AVERROR(ENOSYS); + + if (!frame) { + pktp = NULL; + } else { + pktp = &pkt; + av_init_packet(&pkt); + pkt.data = (void *)frame; + pkt.size = UNCODED_FRAME_PACKET_SIZE; + pkt.pts = + pkt.dts = frame->pts; + pkt.duration = av_frame_get_pkt_duration(frame); + pkt.stream_index = stream_index; + pkt.flags |= AV_PKT_FLAG_UNCODED_FRAME; + } + + return interleaved ? av_interleaved_write_frame(s, pktp) : + av_write_frame(s, pktp); +} + +int av_write_uncoded_frame(AVFormatContext *s, int stream_index, + AVFrame *frame) +{ + return av_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); +} + +int av_write_uncoded_frame_query(AVFormatContext *s, int stream_index) +{ + av_assert0(s->oformat); + if (!s->oformat->write_uncoded_frame) + return AVERROR(ENOSYS); + return s->oformat->write_uncoded_frame(s, stream_index, NULL, + AV_WRITE_UNCODED_FRAME_QUERY); +} |