ffmpeg: count packets when queued

Because write_packet() fakely writes packets to muxer by queueing
them when muxer hasn't been initialized, it should also increment
frame_number fakely.
This is required because code in do_streamcopy() rely on
frame_number.

Should fix Ticket6227

Reviewed-by: James Almer <jamrial@gmail.com>
Reviewed-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: Muhammad Faiz <mfcc64@gmail.com>
This commit is contained in:
Muhammad Faiz 2017-05-02 07:22:31 +07:00
parent 9b4648a2cd
commit c4be288fdb
1 changed files with 20 additions and 18 deletions

View File

@ -669,12 +669,28 @@ static void close_all_output_streams(OutputStream *ost, OSTFinished this_stream,
} }
} }
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost) static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
{ {
AVFormatContext *s = of->ctx; AVFormatContext *s = of->ctx;
AVStream *st = ost->st; AVStream *st = ost->st;
int ret; int ret;
/*
* Audio encoders may split the packets -- #frames in != #packets out.
* But there is no reordering, so we can limit the number of output packets
* by simply dropping them here.
* Counting encoded video frames needs to be done separately because of
* reordering, see do_video_out().
* Do not count the packet when unqueued because it has been counted when queued.
*/
if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed) && !unqueue) {
if (ost->frame_number >= ost->max_frames) {
av_packet_unref(pkt);
return;
}
ost->frame_number++;
}
if (!of->header_written) { if (!of->header_written) {
AVPacket tmp_pkt = {0}; AVPacket tmp_pkt = {0};
/* the muxer is not initialized yet, buffer the packet */ /* the muxer is not initialized yet, buffer the packet */
@ -703,20 +719,6 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost)
(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0)) (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0))
pkt->pts = pkt->dts = AV_NOPTS_VALUE; pkt->pts = pkt->dts = AV_NOPTS_VALUE;
/*
* Audio encoders may split the packets -- #frames in != #packets out.
* But there is no reordering, so we can limit the number of output packets
* by simply dropping them here.
* Counting encoded video frames needs to be done separately because of
* reordering, see do_video_out()
*/
if (!(st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && ost->encoding_needed)) {
if (ost->frame_number >= ost->max_frames) {
av_packet_unref(pkt);
return;
}
ost->frame_number++;
}
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
int i; int i;
uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,
@ -861,10 +863,10 @@ static void output_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost)
goto finish; goto finish;
idx++; idx++;
} else } else
write_packet(of, pkt, ost); write_packet(of, pkt, ost, 0);
} }
} else } else
write_packet(of, pkt, ost); write_packet(of, pkt, ost, 0);
finish: finish:
if (ret < 0 && ret != AVERROR_EOF) { if (ret < 0 && ret != AVERROR_EOF) {
@ -2972,7 +2974,7 @@ static int check_init_output_file(OutputFile *of, int file_index)
while (av_fifo_size(ost->muxing_queue)) { while (av_fifo_size(ost->muxing_queue)) {
AVPacket pkt; AVPacket pkt;
av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL); av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL);
write_packet(of, &pkt, ost); write_packet(of, &pkt, ost, 1);
} }
} }