Thanks Cameron, your patch timeout mechanism has been tested and improves performance. But still works with some issues when B-frames are presented. This issue was resolved in the attached data, please update your patch with information below:
diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c > index 41eaef9758..4c6ee58639 100644 > --- a/libavcodec/amfenc.c > +++ b/libavcodec/amfenc.c > @@ -426,6 +426,8 @@ static int amf_init_encoder(AVCodecContext *avctx) > res = ctx->factory->pVtbl->CreateComponent(ctx->factory, > ctx->context, codec_id, &ctx->encoder); > AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_ENCODER_NOT_FOUND, > "CreateComponent(%ls) failed with error %d\n", codec_id, res); > > + ctx->submitted_frame = 0; > + > return 0; > } > > @@ -541,7 +543,6 @@ static int amf_copy_buffer(AVCodecContext *avctx, > AVPacket *pkt, AMFBuffer *buff > if ((ctx->max_b_frames > 0 || ((ctx->pa_adaptive_mini_gop == 1) ? > true : false)) && ctx->dts_delay == 0) { > int64_t timestamp_last = AV_NOPTS_VALUE; > size_t can_read = av_fifo_can_read(ctx->timestamp_list); > - > AMF_RETURN_IF_FALSE(ctx, can_read > 0, AVERROR_UNKNOWN, > "timestamp_list is empty while max_b_frames = %d\n", > avctx->max_b_frames); > av_fifo_peek(ctx->timestamp_list, ×tamp_last, 1, can_read - > 1); > @@ -787,6 +788,13 @@ int ff_amf_receive_packet(AVCodecContext *avctx, > AVPacket *avpkt) > > av_frame_unref(frame); > ret = av_fifo_write(ctx->timestamp_list, &pts, 1); > + > + if (ctx->submitted_frame == 0) > + { > + ctx->use_b_frame = (ctx->max_b_frames > 0 || > ((ctx->pa_adaptive_mini_gop == 1) ? true : false)); > + } > + ctx->submitted_frame++; > + > if (ret < 0) > return ret; > } > @@ -796,7 +804,7 @@ int ff_amf_receive_packet(AVCodecContext *avctx, > AVPacket *avpkt) > do { > block_and_wait = 0; > // poll data > - if (!avpkt->data && !avpkt->buf) { > + if (!avpkt->data && !avpkt->buf && (ctx->use_b_frame ? > (ctx->submitted_frame >= 2) : true) ) { > res_query = ctx->encoder->pVtbl->QueryOutput(ctx->encoder, > &data); > if (data) { > // copy data to packet > @@ -806,6 +814,7 @@ int ff_amf_receive_packet(AVCodecContext *avctx, > AVPacket *avpkt) > data->pVtbl->QueryInterface(data, &guid, > (void**)&buffer); // query for buffer interface > ret = amf_copy_buffer(avctx, avpkt, buffer); > > + ctx->submitted_frame++; > buffer->pVtbl->Release(buffer); > > if (data->pVtbl->HasProperty(data, L"av_frame_ref")) { > @@ -843,6 +852,7 @@ int ff_amf_receive_packet(AVCodecContext *avctx, > AVPacket *avpkt) > av_frame_unref(ctx->delayed_frame); > AMF_RETURN_IF_FALSE(ctx, res_resubmit == AMF_OK, > AVERROR_UNKNOWN, "Repeated SubmitInput() failed with error %d\n", > res_resubmit); > > + ctx->submitted_frame++; > ret = av_fifo_write(ctx->timestamp_list, &pts, 1); > if (ret < 0) > return ret; > @@ -861,7 +871,12 @@ int ff_amf_receive_packet(AVCodecContext *avctx, > AVPacket *avpkt) > if (query_output_data_flag == 0) { > if (res_resubmit == AMF_INPUT_FULL || ctx->delayed_drain || > (ctx->eof && res_query != AMF_EOF) || (ctx->hwsurfaces_in_queue >= > ctx->hwsurfaces_in_queue_max)) { > block_and_wait = 1; > - av_usleep(1000); > + > + // Only sleep if the driver doesn't support waiting in > QueryOutput() > + // or if we already have output data so we will skip > calling it. > + if (!ctx->query_timeout_supported || avpkt->data || > avpkt->buf) { > + av_usleep(1000); > + } > } > } > } while (block_and_wait); > diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h > index d985d01bb1..0b8ddd99ed 100644 > --- a/libavcodec/amfenc.h > +++ b/libavcodec/amfenc.h > @@ -68,6 +68,7 @@ typedef struct AmfContext { > > int hwsurfaces_in_queue; > int hwsurfaces_in_queue_max; > + int query_timeout_supported; > > // helpers to handle async calls > int delayed_drain; > @@ -77,6 +78,8 @@ typedef struct AmfContext { > // shift dts back by max_b_frames in timing > AVFifo *timestamp_list; > int64_t dts_delay; > + int submitted_frame; > + amf_bool use_b_frame; > > // common encoder option options > > diff --git a/libavcodec/amfenc_av1.c b/libavcodec/amfenc_av1.c > index 2a7a782063..f3058c5b96 100644 > --- a/libavcodec/amfenc_av1.c > +++ b/libavcodec/amfenc_av1.c > @@ -467,6 +467,11 @@ FF_ENABLE_DEPRECATION_WARNINGS > } > } > > + // Wait inside QueryOutput() if supported by the driver > + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, > AMF_VIDEO_ENCODER_AV1_QUERY_TIMEOUT, 1); > + res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, > AMF_VIDEO_ENCODER_AV1_QUERY_TIMEOUT, &var); > + ctx->query_timeout_supported = res == AMF_OK && var.int64Value; > + > // init encoder > res = ctx->encoder->pVtbl->Init(ctx->encoder, ctx->format, > avctx->width, avctx->height); > AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "encoder->Init() > failed with error %d\n", res); > diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c > index 8edd39c633..6d7c5808ee 100644 > --- a/libavcodec/amfenc_h264.c > +++ b/libavcodec/amfenc_h264.c > @@ -482,6 +482,11 @@ FF_ENABLE_DEPRECATION_WARNINGS > AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, > AMF_VIDEO_ENCODER_REF_B_PIC_DELTA_QP, ctx->ref_b_frame_delta_qp); > } > > + // Wait inside QueryOutput() if supported by the driver > + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, > AMF_VIDEO_ENCODER_QUERY_TIMEOUT, 1); > + res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, > AMF_VIDEO_ENCODER_QUERY_TIMEOUT, &var); > + ctx->query_timeout_supported = res == AMF_OK && var.int64Value; > + > // Initialize Encoder > res = ctx->encoder->pVtbl->Init(ctx->encoder, ctx->format, > avctx->width, avctx->height); > AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "encoder->Init() > failed with error %d\n", res); > diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c > index 4898824f3a..4457990247 100644 > --- a/libavcodec/amfenc_hevc.c > +++ b/libavcodec/amfenc_hevc.c > @@ -429,6 +429,11 @@ FF_ENABLE_DEPRECATION_WARNINGS > } > } > > + // Wait inside QueryOutput() if supported by the driver > + AMF_ASSIGN_PROPERTY_INT64(res, ctx->encoder, > AMF_VIDEO_ENCODER_HEVC_QUERY_TIMEOUT, 1); > + res = ctx->encoder->pVtbl->GetProperty(ctx->encoder, > AMF_VIDEO_ENCODER_HEVC_QUERY_TIMEOUT, &var); > + ctx->query_timeout_supported = res == AMF_OK && var.int64Value; > + > // init encoder > res = ctx->encoder->pVtbl->Init(ctx->encoder, ctx->format, > avctx->width, avctx->height); > AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_BUG, "encoder->Init() > failed with error %d\n", res); > _______________________________________________ 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".