From 904100e5fc13dacc954b1d093bf87bc44f4e7a7b Mon Sep 17 00:00:00 2001 From: Jindrich Makovicka Date: Wed, 21 Mar 2012 11:42:32 +0100 Subject: [PATCH] make av_interleaved_write_frame() flush packets when pkt is NULL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch allows the user to force flushing of all queued packets by calling av_interleaved_write_frame() with pkt set to NULL. Signed-off-by: Jindrich Makovicka Signed-off-by: Martin Storsjö --- libavformat/avformat.h | 2 ++ libavformat/utils.c | 30 ++++++++++++++++++------------ 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index cd7ece8458..087b0b45e1 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1436,6 +1436,8 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt); * @param s media file handle * @param pkt The packet containing the data to be written. Libavformat takes * ownership of the data and will free it when it sees fit using the packet's + * This can be NULL (at any time, not just at the end), to flush the + * interleaving queues. * @ref AVPacket.destruct "destruct" field. The caller must not access the data * after this function returns, as it may already be freed. * Packet's @ref AVPacket.stream_index "stream_index" field must be set to the diff --git a/libavformat/utils.c b/libavformat/utils.c index 6c985af1a0..cb708addf4 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3128,24 +3128,30 @@ static int interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, in } int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){ - AVStream *st= s->streams[ pkt->stream_index]; - int ret; + int ret, flush = 0; - //FIXME/XXX/HACK drop zero sized packets - if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->size==0) - return 0; + if (pkt) { + AVStream *st= s->streams[ pkt->stream_index]; - av_dlog(s, "av_interleaved_write_frame size:%d dts:%"PRId64" pts:%"PRId64"\n", - pkt->size, pkt->dts, pkt->pts); - if((ret = compute_pkt_fields2(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) - return ret; + //FIXME/XXX/HACK drop zero sized packets + if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->size==0) + return 0; - if(pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) - return AVERROR(EINVAL); + av_dlog(s, "av_interleaved_write_frame size:%d dts:%"PRId64" pts:%"PRId64"\n", + pkt->size, pkt->dts, pkt->pts); + if((ret = compute_pkt_fields2(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) + return ret; + + if(pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) + return AVERROR(EINVAL); + } else { + av_dlog(s, "av_interleaved_write_frame FLUSH\n"); + flush = 1; + } for(;;){ AVPacket opkt; - int ret= interleave_packet(s, &opkt, pkt, 0); + int ret= interleave_packet(s, &opkt, pkt, flush); if(ret<=0) //FIXME cleanup needed for ret<0 ? return ret;