Signed-off-by: James Almer <jamr...@gmail.com> --- libavcodec/amfenc.c | 45 ++++++++++++++++++++-------------------- libavcodec/amfenc.h | 2 ++ libavcodec/amfenc_h264.c | 1 - libavcodec/amfenc_hevc.c | 1 - 4 files changed, 25 insertions(+), 24 deletions(-)
diff --git a/libavcodec/amfenc.c b/libavcodec/amfenc.c index 876fddd2b6..d318c21978 100644 --- a/libavcodec/amfenc.c +++ b/libavcodec/amfenc.c @@ -33,6 +33,7 @@ #include "libavutil/time.h" #include "amfenc.h" +#include "encode.h" #include "internal.h" #if CONFIG_D3D11VA @@ -112,6 +113,10 @@ static int amf_load_library(AVCodecContext *avctx) AMFQueryVersion_Fn version_fun; AMF_RESULT res; + ctx->frame = av_frame_alloc(); + if (!ctx->frame) { + return AVERROR(ENOMEM); + } ctx->delayed_frame = av_frame_alloc(); if (!ctx->delayed_frame) { return AVERROR(ENOMEM); @@ -401,6 +406,7 @@ int av_cold ff_amf_encode_close(AVCodecContext *avctx) ctx->factory = NULL; ctx->version = 0; ctx->delayed_drain = 0; + av_frame_free(&ctx->frame); av_frame_free(&ctx->delayed_frame); av_fifo_freep(&ctx->timestamp_list); @@ -588,17 +594,27 @@ static void amf_release_buffer_with_frame_ref(AMFBuffer *frame_ref_storage_buffe frame_ref_storage_buffer->pVtbl->Release(frame_ref_storage_buffer); } -int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame) +int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) { AmfContext *ctx = avctx->priv_data; AMFSurface *surface; AMF_RESULT res; int ret; + AMF_RESULT res_query; + AMFData *data = NULL; + AVFrame *frame = ctx->frame; + int block_and_wait; if (!ctx->encoder) return AVERROR(EINVAL); - if (!frame) { // submit drain + if (!frame->buf[0]) { + ret = ff_encode_get_frame(avctx, frame); + if (ret < 0 && ret != AVERROR_EOF) + return ret; + } + + if (!frame->buf[0]) { // submit drain if (!ctx->eof) { // submit drain one time only if (ctx->delayed_surface != NULL) { ctx->delayed_drain = 1; // input queue is full: resubmit Drain() in ff_amf_receive_packet @@ -613,15 +629,10 @@ int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame) AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "Drain() failed with error %d\n", res); } } - } else{ - return AVERROR_EOF; } - } else { // submit frame + } else if (!ctx->delayed_surface) { // submit frame int hw_surface = 0; - if (ctx->delayed_surface != NULL) { - return AVERROR(EAGAIN); // should not happen when called from ffmpeg, other clients may resubmit - } // prepare surface from frame switch (frame->format) { #if CONFIG_D3D11VA @@ -693,38 +704,28 @@ int ff_amf_send_frame(AVCodecContext *avctx, const AVFrame *frame) break; } - // submit surface res = ctx->encoder->pVtbl->SubmitInput(ctx->encoder, (AMFData*)surface); if (res == AMF_INPUT_FULL) { // handle full queue //store surface for later submission ctx->delayed_surface = surface; if (surface->pVtbl->GetMemoryType(surface) == AMF_MEMORY_DX11) { - av_frame_ref(ctx->delayed_frame, frame); + av_frame_move_ref(ctx->delayed_frame, frame); } } else { surface->pVtbl->Release(surface); AMF_RETURN_IF_FALSE(ctx, res == AMF_OK, AVERROR_UNKNOWN, "SubmitInput() failed with error %d\n", res); if ((ret = timestamp_queue_enqueue(avctx, frame->pts)) < 0) { + av_frame_unref(frame); return ret; } } + + av_frame_unref(frame); } - return 0; -} -int ff_amf_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) -{ - int ret; - AMF_RESULT res; - AMF_RESULT res_query; - AmfContext *ctx = avctx->priv_data; - AMFData *data = NULL; - int block_and_wait; - if (!ctx->encoder) - return AVERROR(EINVAL); do { block_and_wait = 0; diff --git a/libavcodec/amfenc.h b/libavcodec/amfenc.h index b1361842bd..39cbdc881c 100644 --- a/libavcodec/amfenc.h +++ b/libavcodec/amfenc.h @@ -65,6 +65,8 @@ typedef struct AmfContext { int hwsurfaces_in_queue; int hwsurfaces_in_queue_max; + AVFrame *frame; + // helpers to handle async calls int delayed_drain; AMFSurface *delayed_surface; diff --git a/libavcodec/amfenc_h264.c b/libavcodec/amfenc_h264.c index 7f2817f115..7a8029f3b7 100644 --- a/libavcodec/amfenc_h264.c +++ b/libavcodec/amfenc_h264.c @@ -383,7 +383,6 @@ AVCodec ff_h264_amf_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_H264, .init = amf_encode_init_h264, - .send_frame = ff_amf_send_frame, .receive_packet = ff_amf_receive_packet, .close = ff_amf_encode_close, .priv_data_size = sizeof(AmfContext), diff --git a/libavcodec/amfenc_hevc.c b/libavcodec/amfenc_hevc.c index 77e57d2461..8b2302f2af 100644 --- a/libavcodec/amfenc_hevc.c +++ b/libavcodec/amfenc_hevc.c @@ -313,7 +313,6 @@ AVCodec ff_hevc_amf_encoder = { .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_HEVC, .init = amf_encode_init_hevc, - .send_frame = ff_amf_send_frame, .receive_packet = ff_amf_receive_packet, .close = ff_amf_encode_close, .priv_data_size = sizeof(AmfContext), -- 2.26.0 _______________________________________________ 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".