On Tue, 14 Mar 2017 01:37:16 +0000
Mark Thompson <[email protected]> wrote:

> Before this, output bitstream filters would never see EOF and
> therefore would not be able to flush any delayed packets.
> ---
> There might be a nicer way to achieve this result?  (Code is copied from 
> output_packet() and modified to flush.)
> 
> 
>  avtools/avconv.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
> 
> diff --git a/avtools/avconv.c b/avtools/avconv.c
> index 5c36761c1..1e5ccddb5 100644
> --- a/avtools/avconv.c
> +++ b/avtools/avconv.c
> @@ -1033,6 +1033,50 @@ FF_ENABLE_DEPRECATION_WARNINGS
>  
>  }
>  
> +static void flush_bsfs(OutputFile *of, OutputStream *ost)
> +{
> +    AVPacket pkt;
> +    int ret = 0, flush_idx;
> +
> +    for (flush_idx = 0; flush_idx < ost->nb_bitstream_filters; flush_idx++) {
> +        int idx;
> +
> +        ret = av_bsf_send_packet(ost->bsf_ctx[flush_idx], NULL);
> +        if (ret < 0)
> +            goto finish;
> +
> +        idx = flush_idx + 1;
> +        while (idx > flush_idx) {
> +            /* get a packet from the previous filter up the chain */
> +            ret = av_bsf_receive_packet(ost->bsf_ctx[idx - 1], &pkt);
> +            if (ret == AVERROR(EAGAIN)) {
> +                ret = 0;
> +                idx--;
> +                continue;
> +            } else if (ret == AVERROR(EOF) && idx - 1 == flush_idx) {
> +                break;
> +            } else if (ret < 0)
> +                goto finish;
> +
> +            /* send it to the next filter down the chain or to the muxer */
> +            if (idx < ost->nb_bitstream_filters) {
> +                ret = av_bsf_send_packet(ost->bsf_ctx[idx], &pkt);
> +                if (ret < 0)
> +                    goto finish;
> +                idx++;
> +            } else
> +                write_packet(of, &pkt, ost);
> +        }
> +    }
> +
> +finish:
> +    if (ret < 0 && ret != AVERROR_EOF) {
> +        av_log(NULL, AV_LOG_FATAL, "Error applying bitstream filters to an 
> output "
> +               "packet for stream #%d:%d.\n", ost->file_index, ost->index);
> +        exit_program(1);
> +    }
> +}
> +
>  static void flush_encoders(void)
>  {
>      int i, ret;
> @@ -1083,6 +1127,7 @@ static void flush_encoders(void)
>                      fprintf(ost->logfile, "%s", enc->stats_out);
>                  }
>                  if (ret == AVERROR_EOF) {
> +                    flush_bsfs(of, ost);
>                      stop_encoding = 1;
>                      break;
>                  }

I haven't looked at the avconv code, but is it really necessary to
(I assume) duplicate all the BSF filter data flow code just for
draining?
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to