int cbr;
int twopass;
int gpu;
+ int buffer_delay;
} NvencContext;
static const NvencValuePair nvenc_h264_level_pairs[] = {
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;
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;
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;
}
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;
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) {
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;
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 };
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;
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;
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;
}
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;
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;
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 {
}
}
- 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;
{ "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 }
};