[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