3 * Copyright (C) 2015 Luca Barbato
5 * This file is part of Libav.
7 * Libav is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * Libav is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with Libav; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include <nvEncodeAPI.h>
28 #define CUDA_LIBNAME "libcuda.so"
33 #define NVENC_LIBNAME "libnvidia-encode.so"
39 #define NVENC_LIBNAME "nvEncodeAPI64.dll"
41 #define NVENC_LIBNAME "nvEncodeAPI.dll"
44 #define dlopen(filename, flags) LoadLibrary((filename))
45 #define dlsym(handle, symbol) GetProcAddress(handle, symbol)
46 #define dlclose(handle) FreeLibrary(handle)
49 #include "libavutil/common.h"
50 #include "libavutil/imgutils.h"
51 #include "libavutil/mem.h"
56 #define NVENC_CAP 0x30
57 #define BITSTREAM_BUFFER_SIZE 1024 * 1024
59 #define LOAD_LIBRARY(l, path) \
61 if (!((l) = dlopen(path, RTLD_LAZY))) { \
62 av_log(avctx, AV_LOG_ERROR, \
65 return AVERROR_UNKNOWN; \
69 #define LOAD_SYMBOL(fun, lib, symbol) \
71 if (!((fun) = dlsym(lib, symbol))) { \
72 av_log(avctx, AV_LOG_ERROR, \
75 return AVERROR_UNKNOWN; \
84 { NV_ENC_SUCCESS
, 0, "success" },
85 { NV_ENC_ERR_NO_ENCODE_DEVICE
, AVERROR(ENOENT
), "no encode device" },
86 { NV_ENC_ERR_UNSUPPORTED_DEVICE
, AVERROR(ENOSYS
), "unsupported device" },
87 { NV_ENC_ERR_INVALID_ENCODERDEVICE
, AVERROR(EINVAL
), "invalid encoder device" },
88 { NV_ENC_ERR_INVALID_DEVICE
, AVERROR(EINVAL
), "invalid device" },
89 { NV_ENC_ERR_DEVICE_NOT_EXIST
, AVERROR(EIO
), "device does not exist" },
90 { NV_ENC_ERR_INVALID_PTR
, AVERROR(EFAULT
), "invalid ptr" },
91 { NV_ENC_ERR_INVALID_EVENT
, AVERROR(EINVAL
), "invalid event" },
92 { NV_ENC_ERR_INVALID_PARAM
, AVERROR(EINVAL
), "invalid param" },
93 { NV_ENC_ERR_INVALID_CALL
, AVERROR(EINVAL
), "invalid call" },
94 { NV_ENC_ERR_OUT_OF_MEMORY
, AVERROR(ENOMEM
), "out of memory" },
95 { NV_ENC_ERR_ENCODER_NOT_INITIALIZED
, AVERROR(EINVAL
), "encoder not initialized" },
96 { NV_ENC_ERR_UNSUPPORTED_PARAM
, AVERROR(ENOSYS
), "unsupported param" },
97 { NV_ENC_ERR_LOCK_BUSY
, AVERROR(EAGAIN
), "lock busy" },
98 { NV_ENC_ERR_NOT_ENOUGH_BUFFER
, AVERROR(ENOBUFS
), "not enough buffer" },
99 { NV_ENC_ERR_INVALID_VERSION
, AVERROR(EINVAL
), "invalid version" },
100 { NV_ENC_ERR_MAP_FAILED
, AVERROR(EIO
), "map failed" },
101 { NV_ENC_ERR_NEED_MORE_INPUT
, AVERROR(EAGAIN
), "need more input" },
102 { NV_ENC_ERR_ENCODER_BUSY
, AVERROR(EAGAIN
), "encoder busy" },
103 { NV_ENC_ERR_EVENT_NOT_REGISTERD
, AVERROR(EBADF
), "event not registered" },
104 { NV_ENC_ERR_GENERIC
, AVERROR_UNKNOWN
, "generic error" },
105 { NV_ENC_ERR_INCOMPATIBLE_CLIENT_KEY
, AVERROR(EINVAL
), "incompatible client key" },
106 { NV_ENC_ERR_UNIMPLEMENTED
, AVERROR(ENOSYS
), "unimplemented" },
107 { NV_ENC_ERR_RESOURCE_REGISTER_FAILED
, AVERROR(EIO
), "resource register failed" },
108 { NV_ENC_ERR_RESOURCE_NOT_REGISTERED
, AVERROR(EBADF
), "resource not registered" },
109 { NV_ENC_ERR_RESOURCE_NOT_MAPPED
, AVERROR(EBADF
), "resource not mapped" },
112 static int nvenc_map_error(NVENCSTATUS err
, const char **desc
)
115 for (i
= 0; i
< FF_ARRAY_ELEMS(nvenc_errors
); i
++) {
116 if (nvenc_errors
[i
].nverr
== err
) {
118 *desc
= nvenc_errors
[i
].desc
;
119 return nvenc_errors
[i
].averr
;
123 *desc
= "unknown error";
124 return AVERROR_UNKNOWN
;
127 static int nvenc_print_error(void *log_ctx
, NVENCSTATUS err
,
128 const char *error_string
)
132 ret
= nvenc_map_error(err
, &desc
);
133 av_log(log_ctx
, AV_LOG_ERROR
, "%s: %s (%d)\n", error_string
, desc
, err
);
137 static av_cold
int nvenc_load_libraries(AVCodecContext
*avctx
)
139 NVENCContext
*ctx
= avctx
->priv_data
;
140 NVENCLibraryContext
*nvel
= &ctx
->nvel
;
141 PNVENCODEAPICREATEINSTANCE nvenc_create_instance
;
144 LOAD_LIBRARY(nvel
->cuda
, CUDA_LIBNAME
);
146 LOAD_SYMBOL(nvel
->cu_init
, nvel
->cuda
, "cuInit");
147 LOAD_SYMBOL(nvel
->cu_device_get_count
, nvel
->cuda
, "cuDeviceGetCount");
148 LOAD_SYMBOL(nvel
->cu_device_get
, nvel
->cuda
, "cuDeviceGet");
149 LOAD_SYMBOL(nvel
->cu_device_get_name
, nvel
->cuda
, "cuDeviceGetName");
150 LOAD_SYMBOL(nvel
->cu_device_compute_capability
, nvel
->cuda
,
151 "cuDeviceComputeCapability");
152 LOAD_SYMBOL(nvel
->cu_ctx_create
, nvel
->cuda
, "cuCtxCreate_v2");
153 LOAD_SYMBOL(nvel
->cu_ctx_pop_current
, nvel
->cuda
, "cuCtxPopCurrent_v2");
154 LOAD_SYMBOL(nvel
->cu_ctx_destroy
, nvel
->cuda
, "cuCtxDestroy_v2");
156 LOAD_LIBRARY(nvel
->nvenc
, NVENC_LIBNAME
);
158 LOAD_SYMBOL(nvenc_create_instance
, nvel
->nvenc
,
159 "NvEncodeAPICreateInstance");
161 nvel
->nvenc_funcs
.version
= NV_ENCODE_API_FUNCTION_LIST_VER
;
163 err
= nvenc_create_instance(&nvel
->nvenc_funcs
);
164 if (err
!= NV_ENC_SUCCESS
)
165 return nvenc_print_error(avctx
, err
, "Cannot create the NVENC instance");
170 static int nvenc_open_session(AVCodecContext
*avctx
)
172 NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS params
= { 0 };
173 NVENCContext
*ctx
= avctx
->priv_data
;
174 NV_ENCODE_API_FUNCTION_LIST
*nv
= &ctx
->nvel
.nvenc_funcs
;
177 params
.version
= NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER
;
178 params
.apiVersion
= NVENCAPI_VERSION
;
179 params
.device
= ctx
->cu_context
;
180 params
.deviceType
= NV_ENC_DEVICE_TYPE_CUDA
;
182 ret
= nv
->nvEncOpenEncodeSessionEx(¶ms
, &ctx
->nvenc_ctx
);
183 if (ret
!= NV_ENC_SUCCESS
) {
184 ctx
->nvenc_ctx
= NULL
;
185 return nvenc_print_error(avctx
, ret
, "Cannot open the NVENC Session");
191 static int nvenc_check_codec_support(AVCodecContext
*avctx
)
193 NVENCContext
*ctx
= avctx
->priv_data
;
194 NV_ENCODE_API_FUNCTION_LIST
*nv
= &ctx
->nvel
.nvenc_funcs
;
195 int i
, ret
, count
= 0;
198 ret
= nv
->nvEncGetEncodeGUIDCount(ctx
->nvenc_ctx
, &count
);
200 if (ret
!= NV_ENC_SUCCESS
|| !count
)
201 return AVERROR(ENOSYS
);
203 guids
= av_malloc(count
* sizeof(GUID
));
205 return AVERROR(ENOMEM
);
207 ret
= nv
->nvEncGetEncodeGUIDs(ctx
->nvenc_ctx
, guids
, count
, &count
);
208 if (ret
!= NV_ENC_SUCCESS
) {
209 ret
= AVERROR(ENOSYS
);
213 ret
= AVERROR(ENOSYS
);
214 for (i
= 0; i
< count
; i
++) {
215 if (!memcmp(&guids
[i
], &ctx
->params
.encodeGUID
, sizeof(*guids
))) {
227 static int nvenc_check_cap(AVCodecContext
*avctx
, NV_ENC_CAPS cap
)
229 NVENCContext
*ctx
= avctx
->priv_data
;
230 NV_ENCODE_API_FUNCTION_LIST
*nv
= &ctx
->nvel
.nvenc_funcs
;
231 NV_ENC_CAPS_PARAM params
= { 0 };
234 params
.version
= NV_ENC_CAPS_PARAM_VER
;
235 params
.capsToQuery
= cap
;
237 ret
= nv
->nvEncGetEncodeCaps(ctx
->nvenc_ctx
, ctx
->params
.encodeGUID
, ¶ms
, &val
);
239 if (ret
== NV_ENC_SUCCESS
)
244 static int nvenc_check_capabilities(AVCodecContext
*avctx
)
248 ret
= nvenc_check_codec_support(avctx
);
250 av_log(avctx
, AV_LOG_VERBOSE
, "Codec not supported\n");
254 ret
= nvenc_check_cap(avctx
, NV_ENC_CAPS_SUPPORT_YUV444_ENCODE
);
255 if (avctx
->pix_fmt
== AV_PIX_FMT_YUV444P
&& ret
<= 0) {
256 av_log(avctx
, AV_LOG_VERBOSE
, "YUV444P not supported\n");
257 return AVERROR(ENOSYS
);
260 ret
= nvenc_check_cap(avctx
, NV_ENC_CAPS_WIDTH_MAX
);
261 if (ret
< avctx
->width
) {
262 av_log(avctx
, AV_LOG_VERBOSE
, "Width %d exceeds %d\n",
264 return AVERROR(ENOSYS
);
267 ret
= nvenc_check_cap(avctx
, NV_ENC_CAPS_HEIGHT_MAX
);
268 if (ret
< avctx
->height
) {
269 av_log(avctx
, AV_LOG_VERBOSE
, "Height %d exceeds %d\n",
271 return AVERROR(ENOSYS
);
274 ret
= nvenc_check_cap(avctx
, NV_ENC_CAPS_NUM_MAX_BFRAMES
);
275 if (ret
< avctx
->max_b_frames
) {
276 av_log(avctx
, AV_LOG_VERBOSE
, "Max b-frames %d exceed %d\n",
277 avctx
->max_b_frames
, ret
);
279 return AVERROR(ENOSYS
);
285 static int nvenc_check_device(AVCodecContext
*avctx
, int idx
)
287 NVENCContext
*ctx
= avctx
->priv_data
;
288 NVENCLibraryContext
*nvel
= &ctx
->nvel
;
289 char name
[128] = { 0 };
290 int major
, minor
, ret
;
293 int loglevel
= AV_LOG_VERBOSE
;
295 if (ctx
->device
== LIST_DEVICES
)
296 loglevel
= AV_LOG_INFO
;
298 ret
= nvel
->cu_device_get(&cu_device
, idx
);
299 if (ret
!= CUDA_SUCCESS
) {
300 av_log(avctx
, AV_LOG_ERROR
,
301 "Cannot access the CUDA device %d\n",
306 ret
= nvel
->cu_device_get_name(name
, sizeof(name
), cu_device
);
307 if (ret
!= CUDA_SUCCESS
)
310 ret
= nvel
->cu_device_compute_capability(&major
, &minor
, cu_device
);
311 if (ret
!= CUDA_SUCCESS
)
314 av_log(avctx
, loglevel
, "Device %d [%s] ", cu_device
, name
);
316 if (((major
<< 4) | minor
) < NVENC_CAP
)
319 ret
= nvel
->cu_ctx_create(&ctx
->cu_context
, 0, cu_device
);
320 if (ret
!= CUDA_SUCCESS
)
323 ret
= nvel
->cu_ctx_pop_current(&dummy
);
324 if (ret
!= CUDA_SUCCESS
)
327 if ((ret
= nvenc_open_session(avctx
)) < 0)
330 if ((ret
= nvenc_check_capabilities(avctx
)) < 0)
333 av_log(avctx
, loglevel
, "supports NVENC\n");
335 if (ctx
->device
== cu_device
|| ctx
->device
== ANY_DEVICE
)
339 nvel
->nvenc_funcs
.nvEncDestroyEncoder(ctx
->nvenc_ctx
);
340 ctx
->nvenc_ctx
= NULL
;
343 nvel
->cu_ctx_destroy(ctx
->cu_context
);
344 ctx
->cu_context
= NULL
;
348 av_log(avctx
, loglevel
, "does not support NVENC (major %d minor %d)\n",
351 return AVERROR(ENOSYS
);
354 static int nvenc_setup_device(AVCodecContext
*avctx
)
356 NVENCContext
*ctx
= avctx
->priv_data
;
357 NVENCLibraryContext
*nvel
= &ctx
->nvel
;
358 int i
, nb_devices
= 0;
360 if ((nvel
->cu_init(0)) != CUDA_SUCCESS
) {
361 av_log(avctx
, AV_LOG_ERROR
,
362 "Cannot init CUDA\n");
363 return AVERROR_UNKNOWN
;
366 if ((nvel
->cu_device_get_count(&nb_devices
)) != CUDA_SUCCESS
) {
367 av_log(avctx
, AV_LOG_ERROR
,
368 "Cannot enumerate the CUDA devices\n");
369 return AVERROR_UNKNOWN
;
372 switch (avctx
->codec
->id
) {
373 case AV_CODEC_ID_H264
:
374 ctx
->params
.encodeGUID
= NV_ENC_CODEC_H264_GUID
;
376 case AV_CODEC_ID_HEVC
:
377 ctx
->params
.encodeGUID
= NV_ENC_CODEC_HEVC_GUID
;
383 for (i
= 0; i
< nb_devices
; ++i
) {
384 if ((nvenc_check_device(avctx
, i
)) >= 0 && ctx
->device
!= LIST_DEVICES
)
388 if (ctx
->device
== LIST_DEVICES
)
391 return AVERROR(ENOSYS
);
394 typedef struct GUIDTuple
{
399 static int nvec_map_preset(NVENCContext
*ctx
)
401 GUIDTuple presets
[] = {
402 { NV_ENC_PRESET_DEFAULT_GUID
},
403 { NV_ENC_PRESET_HP_GUID
},
404 { NV_ENC_PRESET_HQ_GUID
},
405 { NV_ENC_PRESET_BD_GUID
},
406 { NV_ENC_PRESET_LOW_LATENCY_DEFAULT_GUID
, NVENC_LOWLATENCY
},
407 { NV_ENC_PRESET_LOW_LATENCY_HP_GUID
, NVENC_LOWLATENCY
},
408 { NV_ENC_PRESET_LOW_LATENCY_HQ_GUID
, NVENC_LOWLATENCY
},
409 { NV_ENC_PRESET_LOSSLESS_DEFAULT_GUID
, NVENC_LOSSLESS
},
410 { NV_ENC_PRESET_LOSSLESS_HP_GUID
, NVENC_LOSSLESS
},
414 GUIDTuple
*t
= &presets
[ctx
->preset
];
416 ctx
->params
.presetGUID
= t
->guid
;
417 ctx
->flags
= t
->flags
;
419 return AVERROR(EINVAL
);
422 static void set_constqp(AVCodecContext
*avctx
, NV_ENC_RC_PARAMS
*rc
)
424 rc
->rateControlMode
= NV_ENC_PARAMS_RC_CONSTQP
;
425 rc
->constQP
.qpInterB
= avctx
->global_quality
;
426 rc
->constQP
.qpInterP
= avctx
->global_quality
;
427 rc
->constQP
.qpIntra
= avctx
->global_quality
;
430 static void set_vbr(AVCodecContext
*avctx
, NV_ENC_RC_PARAMS
*rc
)
432 if (avctx
->qmin
>= 0) {
434 rc
->minQP
.qpInterB
= avctx
->qmin
;
435 rc
->minQP
.qpInterP
= avctx
->qmin
;
436 rc
->minQP
.qpIntra
= avctx
->qmin
;
439 if (avctx
->qmax
>= 0) {
441 rc
->maxQP
.qpInterB
= avctx
->qmax
;
442 rc
->maxQP
.qpInterP
= avctx
->qmax
;
443 rc
->maxQP
.qpIntra
= avctx
->qmax
;
447 static void nvenc_override_rate_control(AVCodecContext
*avctx
,
448 NV_ENC_RC_PARAMS
*rc
)
450 NVENCContext
*ctx
= avctx
->priv_data
;
453 case NV_ENC_PARAMS_RC_CONSTQP
:
454 if (avctx
->global_quality
< 0) {
455 av_log(avctx
, AV_LOG_WARNING
,
456 "The constant quality rate-control requires "
457 "the 'global_quality' option set.\n");
460 set_constqp(avctx
, rc
);
462 case NV_ENC_PARAMS_RC_2_PASS_VBR
:
463 case NV_ENC_PARAMS_RC_VBR
:
464 if (avctx
->qmin
< 0 && avctx
->qmax
< 0) {
465 av_log(avctx
, AV_LOG_WARNING
,
466 "The variable bitrate rate-control requires "
467 "the 'qmin' and/or 'qmax' option set.\n");
470 case NV_ENC_PARAMS_RC_VBR_MINQP
:
471 if (avctx
->qmin
< 0) {
472 av_log(avctx
, AV_LOG_WARNING
,
473 "The variable bitrate rate-control requires "
474 "the 'qmin' option set.\n");
479 case NV_ENC_PARAMS_RC_CBR
:
481 case NV_ENC_PARAMS_RC_2_PASS_QUALITY
:
482 case NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP
:
483 if (!(ctx
->flags
& NVENC_LOWLATENCY
)) {
484 av_log(avctx
, AV_LOG_WARNING
,
485 "The multipass rate-control requires "
486 "a low-latency preset.\n");
491 rc
->rateControlMode
= ctx
->rc
;
494 static void nvenc_setup_rate_control(AVCodecContext
*avctx
)
496 NVENCContext
*ctx
= avctx
->priv_data
;
497 NV_ENC_RC_PARAMS
*rc
= &ctx
->config
.rcParams
;
499 if (avctx
->bit_rate
> 0)
500 rc
->averageBitRate
= avctx
->bit_rate
;
502 if (avctx
->rc_max_rate
> 0)
503 rc
->maxBitRate
= avctx
->rc_max_rate
;
506 nvenc_override_rate_control(avctx
, rc
);
507 } else if (avctx
->global_quality
> 0) {
508 set_constqp(avctx
, rc
);
509 } else if (avctx
->qmin
>= 0 && avctx
->qmax
>= 0) {
510 rc
->rateControlMode
= NV_ENC_PARAMS_RC_VBR
;
514 if (avctx
->rc_buffer_size
> 0)
515 rc
->vbvBufferSize
= avctx
->rc_buffer_size
;
517 if (rc
->averageBitRate
> 0)
518 avctx
->bit_rate
= rc
->averageBitRate
;
521 static int nvenc_setup_h264_config(AVCodecContext
*avctx
)
523 NVENCContext
*ctx
= avctx
->priv_data
;
524 NV_ENC_CONFIG
*cc
= &ctx
->config
;
525 NV_ENC_CONFIG_H264
*h264
= &cc
->encodeCodecConfig
.h264Config
;
526 NV_ENC_CONFIG_H264_VUI_PARAMETERS
*vui
= &h264
->h264VUIParameters
;
528 vui
->colourDescriptionPresentFlag
= 1;
529 vui
->videoSignalTypePresentFlag
= 1;
531 vui
->colourMatrix
= avctx
->colorspace
;
532 vui
->colourPrimaries
= avctx
->color_primaries
;
533 vui
->transferCharacteristics
= avctx
->color_trc
;
535 vui
->videoFullRangeFlag
= avctx
->color_range
== AVCOL_RANGE_JPEG
;
537 h264
->disableSPSPPS
= (avctx
->flags
& AV_CODEC_FLAG_GLOBAL_HEADER
) ?
1 : 0;
538 h264
->repeatSPSPPS
= (avctx
->flags
& AV_CODEC_FLAG_GLOBAL_HEADER
) ?
0 : 1;
540 h264
->maxNumRefFrames
= avctx
->refs
;
541 h264
->idrPeriod
= cc
->gopLength
;
544 avctx
->profile
= ctx
->profile
;
546 if (avctx
->pix_fmt
== AV_PIX_FMT_YUV444P
)
547 h264
->chromaFormatIDC
= 3;
549 h264
->chromaFormatIDC
= 1;
551 switch (ctx
->profile
) {
552 case NV_ENC_H264_PROFILE_BASELINE
:
553 cc
->profileGUID
= NV_ENC_H264_PROFILE_BASELINE_GUID
;
555 case NV_ENC_H264_PROFILE_MAIN
:
556 cc
->profileGUID
= NV_ENC_H264_PROFILE_MAIN_GUID
;
558 case NV_ENC_H264_PROFILE_HIGH
:
559 cc
->profileGUID
= NV_ENC_H264_PROFILE_HIGH_GUID
;
561 case NV_ENC_H264_PROFILE_HIGH_444
:
562 cc
->profileGUID
= NV_ENC_H264_PROFILE_HIGH_444_GUID
;
564 case NV_ENC_H264_PROFILE_CONSTRAINED_HIGH
:
565 cc
->profileGUID
= NV_ENC_H264_PROFILE_CONSTRAINED_HIGH_GUID
;
569 h264
->level
= ctx
->level
;
574 static int nvenc_setup_hevc_config(AVCodecContext
*avctx
)
576 NVENCContext
*ctx
= avctx
->priv_data
;
577 NV_ENC_CONFIG
*cc
= &ctx
->config
;
578 NV_ENC_CONFIG_HEVC
*hevc
= &cc
->encodeCodecConfig
.hevcConfig
;
580 hevc
->disableSPSPPS
= (avctx
->flags
& AV_CODEC_FLAG_GLOBAL_HEADER
) ?
1 : 0;
581 hevc
->repeatSPSPPS
= (avctx
->flags
& AV_CODEC_FLAG_GLOBAL_HEADER
) ?
0 : 1;
583 hevc
->maxNumRefFramesInDPB
= avctx
->refs
;
584 hevc
->idrPeriod
= cc
->gopLength
;
586 /* No other profile is supported in the current SDK version 5 */
587 cc
->profileGUID
= NV_ENC_HEVC_PROFILE_MAIN_GUID
;
588 avctx
->profile
= FF_PROFILE_HEVC_MAIN
;
591 hevc
->level
= ctx
->level
;
593 hevc
->level
= NV_ENC_LEVEL_AUTOSELECT
;
597 hevc
->tier
= ctx
->tier
;
602 static int nvenc_setup_codec_config(AVCodecContext
*avctx
)
604 switch (avctx
->codec
->id
) {
605 case AV_CODEC_ID_H264
:
606 return nvenc_setup_h264_config(avctx
);
607 case AV_CODEC_ID_HEVC
:
608 return nvenc_setup_hevc_config(avctx
);
613 static int nvenc_setup_encoder(AVCodecContext
*avctx
)
615 NVENCContext
*ctx
= avctx
->priv_data
;
616 NV_ENCODE_API_FUNCTION_LIST
*nv
= &ctx
->nvel
.nvenc_funcs
;
617 NV_ENC_PRESET_CONFIG preset_cfg
= { 0 };
618 AVCPBProperties
*cpb_props
;
621 ctx
->params
.version
= NV_ENC_INITIALIZE_PARAMS_VER
;
623 ctx
->params
.encodeHeight
= avctx
->height
;
624 ctx
->params
.encodeWidth
= avctx
->width
;
626 if (avctx
->sample_aspect_ratio
.num
&&
627 avctx
->sample_aspect_ratio
.den
&&
628 (avctx
->sample_aspect_ratio
.num
!= 1 ||
629 avctx
->sample_aspect_ratio
.den
!= 1)) {
630 av_reduce(&ctx
->params
.darWidth
,
631 &ctx
->params
.darHeight
,
632 avctx
->width
* avctx
->sample_aspect_ratio
.num
,
633 avctx
->height
* avctx
->sample_aspect_ratio
.den
,
636 ctx
->params
.darHeight
= avctx
->height
;
637 ctx
->params
.darWidth
= avctx
->width
;
640 ctx
->params
.frameRateNum
= avctx
->time_base
.den
;
641 ctx
->params
.frameRateDen
= avctx
->time_base
.num
* avctx
->ticks_per_frame
;
643 ctx
->params
.enableEncodeAsync
= 0;
644 ctx
->params
.enablePTD
= 1;
646 ctx
->params
.encodeConfig
= &ctx
->config
;
648 nvec_map_preset(ctx
);
650 preset_cfg
.version
= NV_ENC_PRESET_CONFIG_VER
;
651 preset_cfg
.presetCfg
.version
= NV_ENC_CONFIG_VER
;
653 ret
= nv
->nvEncGetEncodePresetConfig(ctx
->nvenc_ctx
,
654 ctx
->params
.encodeGUID
,
655 ctx
->params
.presetGUID
,
657 if (ret
!= NV_ENC_SUCCESS
)
658 return nvenc_print_error(avctx
, ret
, "Cannot get the preset configuration");
660 memcpy(&ctx
->config
, &preset_cfg
.presetCfg
, sizeof(ctx
->config
));
662 ctx
->config
.version
= NV_ENC_CONFIG_VER
;
664 if (avctx
->gop_size
> 0) {
665 if (avctx
->max_b_frames
> 0) {
670 * 3 two B frames, and so on. */
671 ctx
->config
.frameIntervalP
= avctx
->max_b_frames
+ 1;
672 } else if (avctx
->max_b_frames
== 0) {
673 ctx
->config
.frameIntervalP
= 1;
675 ctx
->config
.gopLength
= avctx
->gop_size
;
676 } else if (avctx
->gop_size
== 0) {
677 ctx
->config
.frameIntervalP
= 0;
678 ctx
->config
.gopLength
= 1;
681 if (ctx
->config
.frameIntervalP
> 1)
682 avctx
->max_b_frames
= ctx
->config
.frameIntervalP
- 1;
684 nvenc_setup_rate_control(avctx
);
686 if (avctx
->flags
& AV_CODEC_FLAG_INTERLACED_DCT
) {
687 ctx
->config
.frameFieldMode
= NV_ENC_PARAMS_FRAME_FIELD_MODE_FIELD
;
689 ctx
->config
.frameFieldMode
= NV_ENC_PARAMS_FRAME_FIELD_MODE_FRAME
;
692 if ((ret
= nvenc_setup_codec_config(avctx
)) < 0)
695 ret
= nv
->nvEncInitializeEncoder(ctx
->nvenc_ctx
, &ctx
->params
);
696 if (ret
!= NV_ENC_SUCCESS
)
697 return nvenc_print_error(avctx
, ret
, "Cannot initialize the decoder");
699 cpb_props
= ff_add_cpb_side_data(avctx
);
701 return AVERROR(ENOMEM
);
702 cpb_props
->max_bitrate
= avctx
->rc_max_rate
;
703 cpb_props
->min_bitrate
= avctx
->rc_min_rate
;
704 cpb_props
->avg_bitrate
= avctx
->bit_rate
;
705 cpb_props
->buffer_size
= avctx
->rc_buffer_size
;
710 static int nvenc_alloc_surface(AVCodecContext
*avctx
, int idx
)
712 NVENCContext
*ctx
= avctx
->priv_data
;
713 NV_ENCODE_API_FUNCTION_LIST
*nv
= &ctx
->nvel
.nvenc_funcs
;
715 NV_ENC_CREATE_INPUT_BUFFER in_buffer
= { 0 };
716 NV_ENC_CREATE_BITSTREAM_BUFFER out_buffer
= { 0 };
718 in_buffer
.version
= NV_ENC_CREATE_INPUT_BUFFER_VER
;
719 out_buffer
.version
= NV_ENC_CREATE_BITSTREAM_BUFFER_VER
;
721 in_buffer
.width
= avctx
->width
;
722 in_buffer
.height
= avctx
->height
;
724 in_buffer
.memoryHeap
= NV_ENC_MEMORY_HEAP_SYSMEM_UNCACHED
;
726 switch (avctx
->pix_fmt
) {
727 case AV_PIX_FMT_YUV420P
:
728 in_buffer
.bufferFmt
= NV_ENC_BUFFER_FORMAT_YV12_PL
;
730 case AV_PIX_FMT_NV12
:
731 in_buffer
.bufferFmt
= NV_ENC_BUFFER_FORMAT_NV12_PL
;
733 case AV_PIX_FMT_YUV444P
:
734 in_buffer
.bufferFmt
= NV_ENC_BUFFER_FORMAT_YUV444_PL
;
740 ret
= nv
->nvEncCreateInputBuffer(ctx
->nvenc_ctx
, &in_buffer
);
741 if (ret
!= NV_ENC_SUCCESS
)
742 return nvenc_print_error(avctx
, ret
, "CreateInputBuffer failed");
744 ctx
->in
[idx
].in
= in_buffer
.inputBuffer
;
745 ctx
->in
[idx
].format
= in_buffer
.bufferFmt
;
747 /* 1MB is large enough to hold most output frames.
748 * NVENC increases this automaticaly if it's not enough. */
749 out_buffer
.size
= BITSTREAM_BUFFER_SIZE
;
751 out_buffer
.memoryHeap
= NV_ENC_MEMORY_HEAP_SYSMEM_UNCACHED
;
753 ret
= nv
->nvEncCreateBitstreamBuffer(ctx
->nvenc_ctx
, &out_buffer
);
754 if (ret
!= NV_ENC_SUCCESS
)
755 return nvenc_print_error(avctx
, ret
, "CreateBitstreamBuffer failed");
757 ctx
->out
[idx
].out
= out_buffer
.bitstreamBuffer
;
758 ctx
->out
[idx
].busy
= 0;
763 static int nvenc_setup_surfaces(AVCodecContext
*avctx
)
765 NVENCContext
*ctx
= avctx
->priv_data
;
768 ctx
->nb_surfaces
= FFMAX(4 + avctx
->max_b_frames
,
771 ctx
->in
= av_mallocz(ctx
->nb_surfaces
* sizeof(*ctx
->in
));
773 return AVERROR(ENOMEM
);
775 ctx
->out
= av_mallocz(ctx
->nb_surfaces
* sizeof(*ctx
->out
));
777 return AVERROR(ENOMEM
);
779 ctx
->timestamps
= av_fifo_alloc(ctx
->nb_surfaces
* sizeof(int64_t));
780 if (!ctx
->timestamps
)
781 return AVERROR(ENOMEM
);
782 ctx
->pending
= av_fifo_alloc(ctx
->nb_surfaces
* sizeof(ctx
->out
));
784 return AVERROR(ENOMEM
);
785 ctx
->ready
= av_fifo_alloc(ctx
->nb_surfaces
* sizeof(ctx
->out
));
787 return AVERROR(ENOMEM
);
789 for (i
= 0; i
< ctx
->nb_surfaces
; i
++) {
790 if ((ret
= nvenc_alloc_surface(avctx
, i
)) < 0)
797 #define EXTRADATA_SIZE 512
799 static int nvenc_setup_extradata(AVCodecContext
*avctx
)
801 NVENCContext
*ctx
= avctx
->priv_data
;
802 NV_ENCODE_API_FUNCTION_LIST
*nv
= &ctx
->nvel
.nvenc_funcs
;
803 NV_ENC_SEQUENCE_PARAM_PAYLOAD payload
= { 0 };
806 avctx
->extradata
= av_mallocz(EXTRADATA_SIZE
+ AV_INPUT_BUFFER_PADDING_SIZE
);
807 if (!avctx
->extradata
)
808 return AVERROR(ENOMEM
);
810 payload
.version
= NV_ENC_SEQUENCE_PARAM_PAYLOAD_VER
;
811 payload
.spsppsBuffer
= avctx
->extradata
;
812 payload
.inBufferSize
= EXTRADATA_SIZE
;
813 payload
.outSPSPPSPayloadSize
= &avctx
->extradata_size
;
815 ret
= nv
->nvEncGetSequenceParams(ctx
->nvenc_ctx
, &payload
);
816 if (ret
!= NV_ENC_SUCCESS
)
817 return nvenc_print_error(avctx
, ret
, "Cannot get the extradata");
822 av_cold
int ff_nvenc_encode_close(AVCodecContext
*avctx
)
824 NVENCContext
*ctx
= avctx
->priv_data
;
825 NV_ENCODE_API_FUNCTION_LIST
*nv
= &ctx
->nvel
.nvenc_funcs
;
828 av_fifo_free(ctx
->timestamps
);
829 av_fifo_free(ctx
->pending
);
830 av_fifo_free(ctx
->ready
);
833 for (i
= 0; i
< ctx
->nb_surfaces
; ++i
) {
834 nv
->nvEncDestroyInputBuffer(ctx
->nvenc_ctx
, ctx
->in
[i
].in
);
835 nv
->nvEncDestroyBitstreamBuffer(ctx
->nvenc_ctx
, ctx
->out
[i
].out
);
843 nv
->nvEncDestroyEncoder(ctx
->nvenc_ctx
);
846 ctx
->nvel
.cu_ctx_destroy(ctx
->cu_context
);
849 dlclose(ctx
->nvel
.nvenc
);
852 dlclose(ctx
->nvel
.cuda
);
857 av_cold
int ff_nvenc_encode_init(AVCodecContext
*avctx
)
861 if ((ret
= nvenc_load_libraries(avctx
)) < 0)
864 if ((ret
= nvenc_setup_device(avctx
)) < 0)
867 if ((ret
= nvenc_setup_encoder(avctx
)) < 0)
870 if ((ret
= nvenc_setup_surfaces(avctx
)) < 0)
873 if (avctx
->flags
& AV_CODEC_FLAG_GLOBAL_HEADER
) {
874 if ((ret
= nvenc_setup_extradata(avctx
)) < 0)
881 static NVENCInputSurface
*get_input_surface(NVENCContext
*ctx
)
885 for (i
= 0; i
< ctx
->nb_surfaces
; i
++) {
886 if (!ctx
->in
[i
].locked
) {
887 ctx
->in
[i
].locked
= 1;
895 static NVENCOutputSurface
*get_output_surface(NVENCContext
*ctx
)
899 for (i
= 0; i
< ctx
->nb_surfaces
; i
++) {
900 if (!ctx
->out
[i
].busy
) {
908 static int nvenc_copy_frame(NV_ENC_LOCK_INPUT_BUFFER
*in
, const AVFrame
*frame
)
910 uint8_t *buf
= in
->bufferDataPtr
;
911 int off
= frame
->height
* in
->pitch
;
913 switch (frame
->format
) {
914 case AV_PIX_FMT_YUV420P
:
915 av_image_copy_plane(buf
, in
->pitch
,
916 frame
->data
[0], frame
->linesize
[0],
917 frame
->width
, frame
->height
);
920 av_image_copy_plane(buf
, in
->pitch
>> 1,
921 frame
->data
[2], frame
->linesize
[2],
922 frame
->width
>> 1, frame
->height
>> 1);
926 av_image_copy_plane(buf
, in
->pitch
>> 1,
927 frame
->data
[1], frame
->linesize
[1],
928 frame
->width
>> 1, frame
->height
>> 1);
930 case AV_PIX_FMT_NV12
:
931 av_image_copy_plane(buf
, in
->pitch
,
932 frame
->data
[0], frame
->linesize
[0],
933 frame
->width
, frame
->height
);
936 av_image_copy_plane(buf
, in
->pitch
,
937 frame
->data
[1], frame
->linesize
[1],
938 frame
->width
, frame
->height
>> 1);
940 case AV_PIX_FMT_YUV444P
:
941 av_image_copy_plane(buf
, in
->pitch
,
942 frame
->data
[0], frame
->linesize
[0],
943 frame
->width
, frame
->height
);
946 av_image_copy_plane(buf
, in
->pitch
,
947 frame
->data
[1], frame
->linesize
[1],
948 frame
->width
, frame
->height
);
951 av_image_copy_plane(buf
, in
->pitch
,
952 frame
->data
[2], frame
->linesize
[2],
953 frame
->width
, frame
->height
);
962 static int nvenc_enqueue_frame(AVCodecContext
*avctx
, const AVFrame
*frame
,
963 NVENCInputSurface
**in_surf
)
965 NVENCContext
*ctx
= avctx
->priv_data
;
966 NV_ENCODE_API_FUNCTION_LIST
*nv
= &ctx
->nvel
.nvenc_funcs
;
967 NV_ENC_LOCK_INPUT_BUFFER params
= { 0 };
968 NVENCInputSurface
*in
= get_input_surface(ctx
);
974 params
.version
= NV_ENC_LOCK_INPUT_BUFFER_VER
;
975 params
.inputBuffer
= in
->in
;
978 ret
= nv
->nvEncLockInputBuffer(ctx
->nvenc_ctx
, ¶ms
);
979 if (ret
!= NV_ENC_SUCCESS
)
980 return nvenc_print_error(avctx
, ret
, "Cannot lock the buffer");
982 ret
= nvenc_copy_frame(¶ms
, frame
);
986 ret
= nv
->nvEncUnlockInputBuffer(ctx
->nvenc_ctx
, in
->in
);
987 if (ret
!= NV_ENC_SUCCESS
)
988 return nvenc_print_error(avctx
, ret
, "Cannot unlock the buffer");
995 nv
->nvEncUnlockInputBuffer(ctx
->nvenc_ctx
, in
->in
);
1000 static void nvenc_codec_specific_pic_params(AVCodecContext
*avctx
,
1001 NV_ENC_PIC_PARAMS
*params
)
1003 NVENCContext
*ctx
= avctx
->priv_data
;
1005 switch (avctx
->codec
->id
) {
1006 case AV_CODEC_ID_H264
:
1007 params
->codecPicParams
.h264PicParams
.sliceMode
=
1008 ctx
->config
.encodeCodecConfig
.h264Config
.sliceMode
;
1009 params
->codecPicParams
.h264PicParams
.sliceModeData
=
1010 ctx
->config
.encodeCodecConfig
.h264Config
.sliceModeData
;
1012 case AV_CODEC_ID_HEVC
:
1013 params
->codecPicParams
.hevcPicParams
.sliceMode
=
1014 ctx
->config
.encodeCodecConfig
.hevcConfig
.sliceMode
;
1015 params
->codecPicParams
.hevcPicParams
.sliceModeData
=
1016 ctx
->config
.encodeCodecConfig
.hevcConfig
.sliceModeData
;
1021 static inline int nvenc_enqueue_timestamp(AVFifoBuffer
*f
, int64_t pts
)
1023 return av_fifo_generic_write(f
, &pts
, sizeof(pts
), NULL
);
1026 static inline int nvenc_dequeue_timestamp(AVFifoBuffer
*f
, int64_t *pts
)
1028 return av_fifo_generic_read(f
, pts
, sizeof(*pts
), NULL
);
1031 static inline int nvenc_enqueue_surface(AVFifoBuffer
*f
,
1032 NVENCOutputSurface
*surf
)
1035 return av_fifo_generic_write(f
, &surf
, sizeof(surf
), NULL
);
1038 static inline int nvenc_dequeue_surface(AVFifoBuffer
*f
,
1039 NVENCOutputSurface
**surf
)
1041 return av_fifo_generic_read(f
, surf
, sizeof(*surf
), NULL
);
1044 static int nvenc_set_timestamp(NVENCContext
*ctx
,
1045 NV_ENC_LOCK_BITSTREAM
*params
,
1048 pkt
->pts
= params
->outputTimeStamp
;
1049 pkt
->duration
= params
->outputDuration
;
1051 return nvenc_dequeue_timestamp(ctx
->timestamps
, &pkt
->dts
);
1054 static int nvenc_get_frame(AVCodecContext
*avctx
, AVPacket
*pkt
)
1056 NVENCContext
*ctx
= avctx
->priv_data
;
1057 NV_ENCODE_API_FUNCTION_LIST
*nv
= &ctx
->nvel
.nvenc_funcs
;
1058 NV_ENC_LOCK_BITSTREAM params
= { 0 };
1059 NVENCOutputSurface
*out
= NULL
;
1062 ret
= nvenc_dequeue_surface(ctx
->pending
, &out
);
1066 params
.version
= NV_ENC_LOCK_BITSTREAM_VER
;
1067 params
.outputBitstream
= out
->out
;
1069 ret
= nv
->nvEncLockBitstream(ctx
->nvenc_ctx
, ¶ms
);
1071 return nvenc_print_error(avctx
, ret
, "Cannot lock the bitstream");
1073 ret
= ff_alloc_packet(pkt
, params
.bitstreamSizeInBytes
);
1077 memcpy(pkt
->data
, params
.bitstreamBufferPtr
, pkt
->size
);
1079 ret
= nv
->nvEncUnlockBitstream(ctx
->nvenc_ctx
, out
->out
);
1081 return nvenc_print_error(avctx
, ret
, "Cannot unlock the bitstream");
1083 out
->busy
= out
->in
->locked
= 0;
1085 ret
= nvenc_set_timestamp(ctx
, ¶ms
, pkt
);
1089 switch (params
.pictureType
) {
1090 case NV_ENC_PIC_TYPE_IDR
:
1091 pkt
->flags
|= AV_PKT_FLAG_KEY
;
1092 #if FF_API_CODED_FRAME
1093 FF_DISABLE_DEPRECATION_WARNINGS
1094 case NV_ENC_PIC_TYPE_INTRA_REFRESH
:
1095 case NV_ENC_PIC_TYPE_I
:
1096 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_I
;
1098 case NV_ENC_PIC_TYPE_P
:
1099 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_P
;
1101 case NV_ENC_PIC_TYPE_B
:
1102 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_B
;
1104 case NV_ENC_PIC_TYPE_BI
:
1105 avctx
->coded_frame
->pict_type
= AV_PICTURE_TYPE_BI
;
1107 FF_ENABLE_DEPRECATION_WARNINGS
1114 int ff_nvenc_encode_frame(AVCodecContext
*avctx
, AVPacket
*pkt
,
1115 const AVFrame
*frame
, int *got_packet
)
1117 NVENCContext
*ctx
= avctx
->priv_data
;
1118 NV_ENCODE_API_FUNCTION_LIST
*nv
= &ctx
->nvel
.nvenc_funcs
;
1119 NV_ENC_PIC_PARAMS params
= { 0 };
1120 NVENCInputSurface
*in
= NULL
;
1121 NVENCOutputSurface
*out
= NULL
;
1124 params
.version
= NV_ENC_PIC_PARAMS_VER
;
1127 ret
= nvenc_enqueue_frame(avctx
, frame
, &in
);
1130 out
= get_output_surface(ctx
);
1136 params
.inputBuffer
= in
->in
;
1137 params
.bufferFmt
= in
->format
;
1138 params
.inputWidth
= frame
->width
;
1139 params
.inputHeight
= frame
->height
;
1140 params
.outputBitstream
= out
->out
;
1141 params
.inputTimeStamp
= frame
->pts
;
1143 if (avctx
->flags
& AV_CODEC_FLAG_INTERLACED_DCT
) {
1144 if (frame
->top_field_first
)
1145 params
.pictureStruct
= NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM
;
1147 params
.pictureStruct
= NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP
;
1149 params
.pictureStruct
= NV_ENC_PIC_STRUCT_FRAME
;
1152 nvenc_codec_specific_pic_params(avctx
, ¶ms
);
1154 ret
= nvenc_enqueue_timestamp(ctx
->timestamps
, frame
->pts
);
1158 params
.encodePicFlags
= NV_ENC_PIC_FLAG_EOS
;
1161 ret
= nv
->nvEncEncodePicture(ctx
->nvenc_ctx
, ¶ms
);
1162 if (ret
!= NV_ENC_SUCCESS
&&
1163 ret
!= NV_ENC_ERR_NEED_MORE_INPUT
)
1164 return nvenc_print_error(avctx
, ret
, "Error encoding the frame");
1167 ret
= nvenc_enqueue_surface(ctx
->pending
, out
);
1172 if (ret
!= NV_ENC_ERR_NEED_MORE_INPUT
&&
1173 av_fifo_size(ctx
->pending
)) {
1174 ret
= nvenc_get_frame(avctx
, pkt
);