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