From 76203202f6f509e23bf8249d4f78802cabb9ea0d Mon Sep 17 00:00:00 2001 From: nyanmisaka Date: Wed, 13 Mar 2024 21:45:36 +0800 Subject: [PATCH] lavc/rkmppenc: add low_delay flag support for RKMPP encoders Signed-off-by: nyanmisaka --- libavcodec/rkmppenc.c | 14 ++++++++++---- libavcodec/rkmppenc.h | 6 ++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/libavcodec/rkmppenc.c b/libavcodec/rkmppenc.c index 62cf63280e..bc1471f2e5 100644 --- a/libavcodec/rkmppenc.c +++ b/libavcodec/rkmppenc.c @@ -681,7 +681,7 @@ static void rkmpp_free_packet_buf(void *opaque, uint8_t *data) mpp_packet_deinit(&mpp_pkt); } -static int rkmpp_get_packet(AVCodecContext *avctx, AVPacket *packet) +static int rkmpp_get_packet(AVCodecContext *avctx, AVPacket *packet, int timeout) { RKMPPEncContext *r = avctx->priv_data; MppPacket mpp_pkt = NULL; @@ -690,6 +690,11 @@ static int rkmpp_get_packet(AVCodecContext *avctx, AVPacket *packet) MppBuffer mpp_buf = NULL; int ret, key_frame = 0; + if ((ret = r->mapi->control(r->mctx, MPP_SET_OUTPUT_TIMEOUT, (MppParam)&timeout)) != MPP_OK) { + av_log(avctx, AV_LOG_ERROR, "Failed to set output timeout: %d\n", ret); + return AVERROR_EXTERNAL; + } + if ((ret = r->mapi->encode_get_packet(r->mctx, &mpp_pkt)) != MPP_OK) { int log_level = (ret == MPP_NOK) ? AV_LOG_DEBUG : AV_LOG_ERROR; ret = (ret == MPP_NOK) ? AVERROR(EAGAIN) : AVERROR_EXTERNAL; @@ -759,10 +764,11 @@ static int rkmpp_encode_frame(AVCodecContext *avctx, AVPacket *packet, { RKMPPEncContext *r = avctx->priv_data; MPPEncFrame *mpp_enc_frame = NULL; - int surfaces = r->surfaces; int ret; + int timeout = (avctx->flags & AV_CODEC_FLAG_LOW_DELAY) + ? MPP_TIMEOUT_BLOCK : MPP_TIMEOUT_NON_BLOCK; - if (get_used_frame_count(r->frame_list) > surfaces) + if (get_used_frame_count(r->frame_list) > H26X_ASYNC_FRAMES) goto get; mpp_enc_frame = rkmpp_submit_frame(avctx, (AVFrame *)frame); @@ -779,7 +785,7 @@ send: return ret; get: - ret = rkmpp_get_packet(avctx, packet); + ret = rkmpp_get_packet(avctx, packet, timeout); if (!frame && ret == AVERROR(EAGAIN)) goto send; if (ret == AVERROR_EOF || diff --git a/libavcodec/rkmppenc.h b/libavcodec/rkmppenc.h index 3ad8662b3e..e34c227b30 100644 --- a/libavcodec/rkmppenc.h +++ b/libavcodec/rkmppenc.h @@ -38,7 +38,8 @@ #include "libavutil/opt.h" #include "libavutil/pixdesc.h" -#define H26X_HEADER_SIZE 1024 +#define H26X_HEADER_SIZE 1024 +#define H26X_ASYNC_FRAMES 4 #define ALIGN_DOWN(a, b) ((a) & ~((b)-1)) typedef struct MPPEncFrame { @@ -70,7 +71,6 @@ typedef struct RKMPPEncContext { int qp_min; int qp_max_i; int qp_min_i; - int surfaces; int profile; int tier; int level; @@ -106,8 +106,6 @@ static const AVRational mpp_tb = { 1, 1000000 }; { .i64 = -1 }, -1, 51, VE, "qp_max_i" }, \ { "qp_min_i", "Set the min QP value for I frame", OFFSET(qp_min_i), AV_OPT_TYPE_INT, \ { .i64 = -1 }, -1, 51, VE, "qp_min_i" }, \ - { "surfaces", "Set the maximum surfaces to be used for encoding", OFFSET(surfaces), AV_OPT_TYPE_INT, \ - { .i64 = 4 }, 1, 16, VE, "surfaces" }, static const AVOption h264_options[] = { RKMPP_ENC_COMMON_OPTS