X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fnvenc.c;h=c5b63bf45d981464c1a6ab6471a5d5e9e2aa1004;hb=94d68a41fabb55dd8c7e59b88fe4a28a637d1e5f;hp=a63c779d61cf8202976dee2d5c9aa3b56b29c9e4;hpb=db3e12a828553171f37c98119679316720e4caed;p=ffmpeg diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index a63c779d61c..c5b63bf45d9 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -163,6 +163,7 @@ typedef struct NvencContext int cbr; int twopass; int gpu; + int buffer_delay; } NvencContext; static const NvencValuePair nvenc_h264_level_pairs[] = { @@ -563,12 +564,6 @@ static av_cold int nvenc_encode_init(AVCodecContext *avctx) if (!nvenc_dyload_nvenc(avctx)) return AVERROR_EXTERNAL; - avctx->coded_frame = av_frame_alloc(); - if (!avctx->coded_frame) { - res = AVERROR(ENOMEM); - goto error; - } - ctx->last_dts = AV_NOPTS_VALUE; ctx->encode_config.version = NV_ENC_CONFIG_VER; @@ -698,6 +693,9 @@ static av_cold int nvenc_encode_init(AVCodecContext *avctx) num_mbs = ((avctx->width + 15) >> 4) * ((avctx->height + 15) >> 4); ctx->max_surface_count = (num_mbs >= 8160) ? 32 : 48; + if (ctx->buffer_delay >= ctx->max_surface_count) + ctx->buffer_delay = ctx->max_surface_count - 1; + ctx->init_encode_params.enableEncodeAsync = 0; ctx->init_encode_params.enablePTD = 1; @@ -779,9 +777,6 @@ static av_cold int nvenc_encode_init(AVCodecContext *avctx) ctx->encode_config.encodeCodecConfig.h264Config.adaptiveTransformMode = NV_ENC_H264_ADAPTIVE_TRANSFORM_ENABLE; ctx->encode_config.encodeCodecConfig.h264Config.fmoMode = NV_ENC_H264_FMO_DISABLE; } - - if (!isLL) - av_log(avctx, AV_LOG_WARNING, "Twopass mode is only known to work with low latency (ll, llhq, llhp) presets.\n"); } else { ctx->encode_config.rcParams.rateControlMode = NV_ENC_PARAMS_RC_CBR; } @@ -811,7 +806,7 @@ static av_cold int nvenc_encode_init(AVCodecContext *avctx) if (avctx->rc_buffer_size > 0) ctx->encode_config.rcParams.vbvBufferSize = avctx->rc_buffer_size; - if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) { + if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) { ctx->encode_config.frameFieldMode = NV_ENC_PARAMS_FRAME_FIELD_MODE_FIELD; } else { ctx->encode_config.frameFieldMode = NV_ENC_PARAMS_FRAME_FIELD_MODE_FRAME; @@ -828,8 +823,8 @@ static av_cold int nvenc_encode_init(AVCodecContext *avctx) ctx->encode_config.encodeCodecConfig.h264Config.h264VUIParameters.videoFullRangeFlag = avctx->color_range == AVCOL_RANGE_JPEG; - ctx->encode_config.encodeCodecConfig.h264Config.disableSPSPPS = (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0; - ctx->encode_config.encodeCodecConfig.h264Config.repeatSPSPPS = (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1; + ctx->encode_config.encodeCodecConfig.h264Config.disableSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0; + ctx->encode_config.encodeCodecConfig.h264Config.repeatSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1; if (!ctx->profile) { switch (avctx->profile) { @@ -886,8 +881,8 @@ static av_cold int nvenc_encode_init(AVCodecContext *avctx) break; case AV_CODEC_ID_H265: - ctx->encode_config.encodeCodecConfig.hevcConfig.disableSPSPPS = (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0; - ctx->encode_config.encodeCodecConfig.hevcConfig.repeatSPSPPS = (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1; + ctx->encode_config.encodeCodecConfig.hevcConfig.disableSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0; + ctx->encode_config.encodeCodecConfig.hevcConfig.repeatSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1; /* No other profile is supported in the current SDK version 5 */ ctx->encode_config.profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID; @@ -1002,7 +997,7 @@ static av_cold int nvenc_encode_init(AVCodecContext *avctx) ctx->output_surfaces[surfaceCount].busy = 0; } - if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { + if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) { uint32_t outSize = 0; char tmpHeader[256]; NV_ENC_SEQUENCE_PARAM_PAYLOAD payload = { 0 }; @@ -1051,8 +1046,6 @@ error: if (ctx->cu_context) dl_fn->cu_ctx_destroy(ctx->cu_context); - av_frame_free(&avctx->coded_frame); - nvenc_unload_nvenc(avctx); ctx->nvencoder = NULL; @@ -1086,12 +1079,10 @@ static av_cold int nvenc_encode_close(AVCodecContext *avctx) nvenc_unload_nvenc(avctx); - av_frame_free(&avctx->coded_frame); - return 0; } -static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, AVFrame *coded_frame, NvencOutputSurface *tmpoutsurf) +static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, NvencOutputSurface *tmpoutsurf) { NvencContext *ctx = avctx->priv_data; NvencDynLoadFunctions *dl_fn = &ctx->nvenc_dload_funcs; @@ -1133,7 +1124,7 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, AVFrame goto error; } - if (res = ff_alloc_packet2(avctx, pkt, lock_params.bitstreamSizeInBytes)) { + if (res = ff_alloc_packet2(avctx, pkt, lock_params.bitstreamSizeInBytes, 0)) { p_nvenc->nvEncUnlockBitstream(ctx->nvencoder, tmpoutsurf->output_surface); goto error; } @@ -1147,6 +1138,8 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, AVFrame switch (lock_params.pictureType) { case NV_ENC_PIC_TYPE_IDR: pkt->flags |= AV_PKT_FLAG_KEY; +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS case NV_ENC_PIC_TYPE_I: avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; break; @@ -1164,6 +1157,8 @@ static int process_output_surface(AVCodecContext *avctx, AVPacket *pkt, AVFrame av_log(avctx, AV_LOG_ERROR, "Please report this error and include as much information on how to reproduce it as possible.\n"); res = AVERROR_EXTERNAL; goto error; +FF_ENABLE_DEPRECATION_WARNINGS +#endif } pkt->pts = lock_params.outputTimeStamp; @@ -1309,7 +1304,7 @@ static int nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, pic_params.outputBitstream = ctx->output_surfaces[i].output_surface; pic_params.completionEvent = 0; - if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) { + if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) { if (frame->top_field_first) { pic_params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM; } else { @@ -1379,10 +1374,10 @@ static int nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, } } - if (ctx->output_surface_ready_queue.count) { + if (ctx->output_surface_ready_queue.count && (!frame || ctx->output_surface_ready_queue.count + ctx->output_surface_queue.count >= ctx->buffer_delay)) { tmpoutsurf = out_surf_queue_dequeue(&ctx->output_surface_ready_queue); - res = process_output_surface(avctx, pkt, avctx->coded_frame, tmpoutsurf); + res = process_output_surface(avctx, pkt, tmpoutsurf); if (res) return res; @@ -1414,8 +1409,9 @@ static const AVOption options[] = { { "level", "Set the encoding level restriction (auto, 1.0, 1.0b, 1.1, 1.2, ..., 4.2, 5.0, 5.1)", OFFSET(level), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, { "tier", "Set the encoding tier (main or high)", OFFSET(tier), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, { "cbr", "Use cbr encoding mode", OFFSET(cbr), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE }, - { "2pass", "Use 2pass cbr encoding mode (low latency mode only)", OFFSET(twopass), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, + { "2pass", "Use 2pass cbr encoding mode", OFFSET(twopass), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, VE }, { "gpu", "Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on.", OFFSET(gpu), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, + { "delay", "Delays frame output by the given amount of frames.", OFFSET(buffer_delay), AV_OPT_TYPE_INT, { .i64 = INT_MAX }, 0, INT_MAX, VE }, { NULL } };