On Fri, Jul 16, 2021, at 10:06 PM, Timo Rothenpieler wrote: -- snip --
> Can you explain the logic this follows some more? I'm quite confused > what exactly changed, and how it broke this. > How do you trigger a flush, if calling flush does nothing? Since https://github.com/ffmpeg/ffmpeg/commit/3ea7057677 it was possible to flush nvenc buffers without sending a NULL frame like: // trigger ff_nvenc_encode_flush which will send a NULL frame internally // this doesn't set avctx->internal->draining avcodec_flush_buffers(encoder) // get remaining packets out of the buffer while ... { avcodec_receive_packet(encoder, &pkt) } // whenever next segment comes in, reuse encoder without closing & re-opening avcodec_send_frame(encoder, frame) But after the recent API changes [1] if someone tries to fetch packets after calling avcodec_flush_buffers() they won't receive any and hit EAGAIN. As the user ran out of frames to encode, no frame is present at avctx->internal->buffer_frame - and avctx->internal->draining is unset because the user didn't want to send a NULL frame. So ff_encode_get_frame returns EAGAIN, which is what the user gets without these changes: > > @@ -2384,8 +2390,11 @@ int ff_nvenc_receive_packet(AVCodecContext *avctx, > > AVPacket *pkt) > > > > if (!frame->buf[0]) { > > res = ff_encode_get_frame(avctx, frame); > > - if (res < 0 && res != AVERROR_EOF) > > + if (res == AVERROR_EOF || (ctx->encoder_flushing && res == > > AVERROR(EAGAIN))) { > > + // flushing mode, continue to send packets > > + } else if (res < 0) { > > return res; > > + } > > } ---- > > > > av_cold void ff_nvenc_encode_flush(AVCodecContext *avctx) > > { > > - NvencContext *ctx = avctx->priv_data; > > - > > nvenc_send_frame(avctx, NULL); > > - av_fifo_reset(ctx->timestamp_list); > > } > > Is it really correct for this to do absolutely nothing now? It's still sending the NULL frame internally - which will mark encoder_flushing as 1 here: > > @@ -2335,6 +2340,7 @@ static int nvenc_send_frame(AVCodecContext *avctx, > > const AVFrame *frame) > > nvenc_codec_specific_pic_params(avctx, &pic_params, > > ctx->sei_data, sei_count); > > } else { > > pic_params.encodePicFlags = NV_ENC_PIC_FLAG_EOS; > > + ctx->encoder_flushing = 1; We don't wanna cleanup ctx->timestamp_list until the user has retrieved all packets from the buffer after triggering a flush. [1]: https://github.com/ffmpeg/ffmpeg/commit/827d6fe73d#diff-ba8b555333cbe9c4d768147d8a7abb152281257770aa314cc057a31f43460fec _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".