From a1e215ea0157360261e856eea2cd468136a68da0 Mon Sep 17 00:00:00 2001 From: Timo Rothenpieler Date: Sat, 25 Jul 2015 23:20:28 +0200 Subject: nvenc: Delay frame output to increase encoding speed Signed-off-by: Anton Khirnov --- libavcodec/nvenc.c | 10 +++++++++- libavcodec/nvenc.h | 1 + libavcodec/nvenc_h264.c | 2 ++ libavcodec/nvenc_hevc.c | 2 ++ 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index 97922453f7..bd704a76ad 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -840,6 +840,8 @@ static int nvenc_setup_surfaces(AVCodecContext *avctx) ctx->nb_surfaces = FFMAX(4 + avctx->max_b_frames, ctx->nb_surfaces); + ctx->async_depth = FFMIN(ctx->async_depth, ctx->nb_surfaces - 1); + ctx->frames = av_mallocz_array(ctx->nb_surfaces, sizeof(*ctx->frames)); if (!ctx->frames) @@ -1301,13 +1303,19 @@ FF_ENABLE_DEPRECATION_WARNINGS static int output_ready(AVCodecContext *avctx, int flush) { NVENCContext *ctx = avctx->priv_data; + int nb_ready, nb_pending; /* when B-frames are enabled, we wait for two initial timestamps to * calculate the first dts */ if (!flush && avctx->max_b_frames > 0 && (ctx->initial_pts[0] == AV_NOPTS_VALUE || ctx->initial_pts[1] == AV_NOPTS_VALUE)) return 0; - return av_fifo_size(ctx->ready) > 0; + + nb_ready = av_fifo_size(ctx->ready) / sizeof(NVENCFrame*); + nb_pending = av_fifo_size(ctx->pending) / sizeof(NVENCFrame*); + if (flush) + return nb_ready > 0; + return (nb_ready > 0) && (nb_ready + nb_pending >= ctx->async_depth); } int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index 866099789c..8cd5991f4c 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -142,6 +142,7 @@ typedef struct NVENCContext { int rc; int device; int flags; + int async_depth; } NVENCContext; int ff_nvenc_encode_init(AVCodecContext *avctx); diff --git a/libavcodec/nvenc_h264.c b/libavcodec/nvenc_h264.c index 829ce90cd6..ea91e077c0 100644 --- a/libavcodec/nvenc_h264.c +++ b/libavcodec/nvenc_h264.c @@ -72,6 +72,8 @@ static const AVOption options[] = { { "device", "Select a specific NVENC device", OFFSET(device), AV_OPT_TYPE_INT, { .i64 = -1 }, -2, INT_MAX, VE, "device" }, { "any", "Pick the first device available", 0, AV_OPT_TYPE_CONST, { .i64 = ANY_DEVICE }, 0, 0, VE, "device" }, { "list", "List the available devices", 0, AV_OPT_TYPE_CONST, { .i64 = LIST_DEVICES }, 0, 0, VE, "device" }, + { "async_depth", "Delay frame output by the given amount of frames", OFFSET(async_depth), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 0, INT_MAX, VE }, + { "delay", "Delay frame output by the given amount of frames", OFFSET(async_depth), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 0, INT_MAX, VE }, { NULL } }; diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c index d49ae62502..6ff350698c 100644 --- a/libavcodec/nvenc_hevc.c +++ b/libavcodec/nvenc_hevc.c @@ -68,6 +68,8 @@ static const AVOption options[] = { { "device", "Select a specific NVENC device", OFFSET(device), AV_OPT_TYPE_INT, { .i64 = -1 }, -2, INT_MAX, VE, "device" }, { "any", "Pick the first device available", 0, AV_OPT_TYPE_CONST, { .i64 = ANY_DEVICE }, 0, 0, VE, "device" }, { "list", "List the available devices", 0, AV_OPT_TYPE_CONST, { .i64 = LIST_DEVICES }, 0, 0, VE, "device" }, + { "async_depth", "Delay frame output by the given amount of frames", OFFSET(async_depth), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 0, INT_MAX, VE }, + { "delay", "Delay frame output by the given amount of frames", OFFSET(async_depth), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 0, INT_MAX, VE }, { NULL } }; -- cgit v1.2.3