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;