[FFmpeg-devel] [PATCH] ffmpeg: count packets when queued
James Almer
jamrial at gmail.com
Tue May 2 04:59:42 EEST 2017
On 5/1/2017 9:51 PM, Muhammad Faiz wrote:
> 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
>
> Signed-off-by: Muhammad Faiz <mfcc64 at gmail.com>
> ---
> ffmpeg.c | 39 +++++++++++++++++++++++----------------
> 1 file changed, 23 insertions(+), 16 deletions(-)
>
> diff --git a/ffmpeg.c b/ffmpeg.c
> index bf04a6c..023cb98 100644
> --- a/ffmpeg.c
> +++ b/ffmpeg.c
> @@ -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_packet2(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
> {
> AVFormatContext *s = of->ctx;
> AVStream *st = ost->st;
> 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) {
> AVPacket tmp_pkt = {0};
> /* 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))
> 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) {
> int i;
> uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS,
> @@ -802,6 +804,11 @@ static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost)
> av_packet_unref(pkt);
> }
>
> +static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost)
> +{
> + write_packet2(of, pkt, ost, 0);
> +}
It would be better to instead change the signature of write_packet()
with the addition of the unqueue parameter and update all three calls to
it rather than turning it into a wrapper.
Can confirm in any case that this fixes the packet dropping behavior.
> +
> static void close_output_stream(OutputStream *ost)
> {
> OutputFile *of = output_files[ost->file_index];
> @@ -2972,7 +2979,7 @@ static int check_init_output_file(OutputFile *of, int file_index)
> while (av_fifo_size(ost->muxing_queue)) {
> AVPacket pkt;
> av_fifo_generic_read(ost->muxing_queue, &pkt, sizeof(pkt), NULL);
> - write_packet(of, &pkt, ost);
> + write_packet2(of, &pkt, ost, 1);
> }
> }
>
>
More information about the ffmpeg-devel
mailing list