Libav
nvenc.c
Go to the documentation of this file.
1 /*
2  * NVIDIA NVENC Support
3  * Copyright (C) 2015 Luca Barbato
4  * Copyright (C) 2015 Philip Langdale <philipl@overt.org>
5  * Copyright (C) 2014 Timo Rothenpieler <timo@rothenpieler.org>
6  *
7  * This file is part of Libav.
8  *
9  * Libav is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * Libav is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with Libav; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 #include "config.h"
25 
26 #include <nvEncodeAPI.h>
27 #include <string.h>
28 
29 #define CUDA_LIBNAME "libcuda.so"
30 
31 #if HAVE_DLFCN_H
32 #include <dlfcn.h>
33 
34 #define NVENC_LIBNAME "libnvidia-encode.so"
35 
36 #elif HAVE_WINDOWS_H
37 #include <windows.h>
38 
39 #if ARCH_X86_64
40 #define NVENC_LIBNAME "nvEncodeAPI64.dll"
41 #else
42 #define NVENC_LIBNAME "nvEncodeAPI.dll"
43 #endif
44 
45 #define dlopen(filename, flags) LoadLibrary((filename))
46 #define dlsym(handle, symbol) GetProcAddress(handle, symbol)
47 #define dlclose(handle) FreeLibrary(handle)
48 #endif
49 
50 #include "libavutil/common.h"
51 #include "libavutil/hwcontext.h"
52 #include "libavutil/imgutils.h"
53 #include "libavutil/mem.h"
54 #include "avcodec.h"
55 #include "internal.h"
56 #include "nvenc.h"
57 
58 #if CONFIG_CUDA
60 #endif
61 
62 #define NVENC_CAP 0x30
63 #define BITSTREAM_BUFFER_SIZE 1024 * 1024
64 #define IS_CBR(rc) (rc == NV_ENC_PARAMS_RC_CBR || \
65  rc == NV_ENC_PARAMS_RC_2_PASS_QUALITY || \
66  rc == NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP)
67 
68 #define LOAD_LIBRARY(l, path) \
69  do { \
70  if (!((l) = dlopen(path, RTLD_LAZY))) { \
71  av_log(avctx, AV_LOG_ERROR, \
72  "Cannot load %s\n", \
73  path); \
74  return AVERROR_UNKNOWN; \
75  } \
76  } while (0)
77 
78 #define LOAD_SYMBOL(fun, lib, symbol) \
79  do { \
80  if (!((fun) = dlsym(lib, symbol))) { \
81  av_log(avctx, AV_LOG_ERROR, \
82  "Cannot load %s\n", \
83  symbol); \
84  return AVERROR_UNKNOWN; \
85  } \
86  } while (0)
87 
92 #if CONFIG_CUDA
94 #endif
96 };
97 
98 static const struct {
99  NVENCSTATUS nverr;
100  int averr;
101  const char *desc;
102 } nvenc_errors[] = {
103  { NV_ENC_SUCCESS, 0, "success" },
104  { NV_ENC_ERR_NO_ENCODE_DEVICE, AVERROR(ENOENT), "no encode device" },
105  { NV_ENC_ERR_UNSUPPORTED_DEVICE, AVERROR(ENOSYS), "unsupported device" },
106  { NV_ENC_ERR_INVALID_ENCODERDEVICE, AVERROR(EINVAL), "invalid encoder device" },
107  { NV_ENC_ERR_INVALID_DEVICE, AVERROR(EINVAL), "invalid device" },
108  { NV_ENC_ERR_DEVICE_NOT_EXIST, AVERROR(EIO), "device does not exist" },
109  { NV_ENC_ERR_INVALID_PTR, AVERROR(EFAULT), "invalid ptr" },
110  { NV_ENC_ERR_INVALID_EVENT, AVERROR(EINVAL), "invalid event" },
111  { NV_ENC_ERR_INVALID_PARAM, AVERROR(EINVAL), "invalid param" },
112  { NV_ENC_ERR_INVALID_CALL, AVERROR(EINVAL), "invalid call" },
113  { NV_ENC_ERR_OUT_OF_MEMORY, AVERROR(ENOMEM), "out of memory" },
114  { NV_ENC_ERR_ENCODER_NOT_INITIALIZED, AVERROR(EINVAL), "encoder not initialized" },
115  { NV_ENC_ERR_UNSUPPORTED_PARAM, AVERROR(ENOSYS), "unsupported param" },
116  { NV_ENC_ERR_LOCK_BUSY, AVERROR(EBUSY), "lock busy" },
117  { NV_ENC_ERR_NOT_ENOUGH_BUFFER, AVERROR(ENOBUFS), "not enough buffer" },
118  { NV_ENC_ERR_INVALID_VERSION, AVERROR(EINVAL), "invalid version" },
119  { NV_ENC_ERR_MAP_FAILED, AVERROR(EIO), "map failed" },
120  /* this is error should always be treated specially, so this "mapping"
121  * is for completeness only */
122  { NV_ENC_ERR_NEED_MORE_INPUT, AVERROR_UNKNOWN, "need more input" },
123  { NV_ENC_ERR_ENCODER_BUSY, AVERROR(EBUSY), "encoder busy" },
124  { NV_ENC_ERR_EVENT_NOT_REGISTERD, AVERROR(EBADF), "event not registered" },
125  { NV_ENC_ERR_GENERIC, AVERROR_UNKNOWN, "generic error" },
126  { NV_ENC_ERR_INCOMPATIBLE_CLIENT_KEY, AVERROR(EINVAL), "incompatible client key" },
127  { NV_ENC_ERR_UNIMPLEMENTED, AVERROR(ENOSYS), "unimplemented" },
128  { NV_ENC_ERR_RESOURCE_REGISTER_FAILED, AVERROR(EIO), "resource register failed" },
129  { NV_ENC_ERR_RESOURCE_NOT_REGISTERED, AVERROR(EBADF), "resource not registered" },
130  { NV_ENC_ERR_RESOURCE_NOT_MAPPED, AVERROR(EBADF), "resource not mapped" },
131 };
132 
133 static int nvenc_map_error(NVENCSTATUS err, const char **desc)
134 {
135  int i;
136  for (i = 0; i < FF_ARRAY_ELEMS(nvenc_errors); i++) {
137  if (nvenc_errors[i].nverr == err) {
138  if (desc)
139  *desc = nvenc_errors[i].desc;
140  return nvenc_errors[i].averr;
141  }
142  }
143  if (desc)
144  *desc = "unknown error";
145  return AVERROR_UNKNOWN;
146 }
147 
148 static int nvenc_print_error(void *log_ctx, NVENCSTATUS err,
149  const char *error_string)
150 {
151  const char *desc;
152  int ret;
153  ret = nvenc_map_error(err, &desc);
154  av_log(log_ctx, AV_LOG_ERROR, "%s: %s (%d)\n", error_string, desc, err);
155  return ret;
156 }
157 
159 {
160  NVENCContext *ctx = avctx->priv_data;
161  NVENCLibraryContext *nvel = &ctx->nvel;
162  PNVENCODEAPICREATEINSTANCE nvenc_create_instance;
163  NVENCSTATUS err;
164 
165 #if CONFIG_CUDA
166  nvel->cu_init = cuInit;
167  nvel->cu_device_get_count = cuDeviceGetCount;
168  nvel->cu_device_get = cuDeviceGet;
169  nvel->cu_device_get_name = cuDeviceGetName;
170  nvel->cu_device_compute_capability = cuDeviceComputeCapability;
171  nvel->cu_ctx_create = cuCtxCreate_v2;
172  nvel->cu_ctx_pop_current = cuCtxPopCurrent_v2;
173  nvel->cu_ctx_destroy = cuCtxDestroy_v2;
174 #else
176 
177  LOAD_SYMBOL(nvel->cu_init, nvel->cuda, "cuInit");
178  LOAD_SYMBOL(nvel->cu_device_get_count, nvel->cuda, "cuDeviceGetCount");
179  LOAD_SYMBOL(nvel->cu_device_get, nvel->cuda, "cuDeviceGet");
180  LOAD_SYMBOL(nvel->cu_device_get_name, nvel->cuda, "cuDeviceGetName");
182  "cuDeviceComputeCapability");
183  LOAD_SYMBOL(nvel->cu_ctx_create, nvel->cuda, "cuCtxCreate_v2");
184  LOAD_SYMBOL(nvel->cu_ctx_pop_current, nvel->cuda, "cuCtxPopCurrent_v2");
185  LOAD_SYMBOL(nvel->cu_ctx_destroy, nvel->cuda, "cuCtxDestroy_v2");
186 #endif
187 
188  LOAD_LIBRARY(nvel->nvenc, NVENC_LIBNAME);
189 
190  LOAD_SYMBOL(nvenc_create_instance, nvel->nvenc,
191  "NvEncodeAPICreateInstance");
192 
193  nvel->nvenc_funcs.version = NV_ENCODE_API_FUNCTION_LIST_VER;
194 
195  err = nvenc_create_instance(&nvel->nvenc_funcs);
196  if (err != NV_ENC_SUCCESS)
197  return nvenc_print_error(avctx, err, "Cannot create the NVENC instance");
198 
199  return 0;
200 }
201 
203 {
204  NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS params = { 0 };
205  NVENCContext *ctx = avctx->priv_data;
206  NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs;
207  int ret;
208 
209  params.version = NV_ENC_OPEN_ENCODE_SESSION_EX_PARAMS_VER;
210  params.apiVersion = NVENCAPI_VERSION;
211  params.device = ctx->cu_context;
212  params.deviceType = NV_ENC_DEVICE_TYPE_CUDA;
213 
214  ret = nv->nvEncOpenEncodeSessionEx(&params, &ctx->nvenc_ctx);
215  if (ret != NV_ENC_SUCCESS) {
216  ctx->nvenc_ctx = NULL;
217  return nvenc_print_error(avctx, ret, "Cannot open the NVENC Session");
218  }
219 
220  return 0;
221 }
222 
224 {
225  NVENCContext *ctx = avctx->priv_data;
226  NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs;
227  int i, ret, count = 0;
228  GUID *guids = NULL;
229 
230  ret = nv->nvEncGetEncodeGUIDCount(ctx->nvenc_ctx, &count);
231 
232  if (ret != NV_ENC_SUCCESS || !count)
233  return AVERROR(ENOSYS);
234 
235  guids = av_malloc(count * sizeof(GUID));
236  if (!guids)
237  return AVERROR(ENOMEM);
238 
239  ret = nv->nvEncGetEncodeGUIDs(ctx->nvenc_ctx, guids, count, &count);
240  if (ret != NV_ENC_SUCCESS) {
241  ret = AVERROR(ENOSYS);
242  goto fail;
243  }
244 
245  ret = AVERROR(ENOSYS);
246  for (i = 0; i < count; i++) {
247  if (!memcmp(&guids[i], &ctx->params.encodeGUID, sizeof(*guids))) {
248  ret = 0;
249  break;
250  }
251  }
252 
253 fail:
254  av_free(guids);
255 
256  return ret;
257 }
258 
259 static int nvenc_check_cap(AVCodecContext *avctx, NV_ENC_CAPS cap)
260 {
261  NVENCContext *ctx = avctx->priv_data;
262  NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs;
263  NV_ENC_CAPS_PARAM params = { 0 };
264  int ret, val = 0;
265 
266  params.version = NV_ENC_CAPS_PARAM_VER;
267  params.capsToQuery = cap;
268 
269  ret = nv->nvEncGetEncodeCaps(ctx->nvenc_ctx, ctx->params.encodeGUID, &params, &val);
270 
271  if (ret == NV_ENC_SUCCESS)
272  return val;
273  return 0;
274 }
275 
277 {
278  NVENCContext *ctx = avctx->priv_data;
279  int ret;
280 
281  ret = nvenc_check_codec_support(avctx);
282  if (ret < 0) {
283  av_log(avctx, AV_LOG_VERBOSE, "Codec not supported\n");
284  return ret;
285  }
286 
287  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_YUV444_ENCODE);
288  if (ctx->data_pix_fmt == AV_PIX_FMT_YUV444P && ret <= 0) {
289  av_log(avctx, AV_LOG_VERBOSE, "YUV444P not supported\n");
290  return AVERROR(ENOSYS);
291  }
292 
293  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_WIDTH_MAX);
294  if (ret < avctx->width) {
295  av_log(avctx, AV_LOG_VERBOSE, "Width %d exceeds %d\n",
296  avctx->width, ret);
297  return AVERROR(ENOSYS);
298  }
299 
300  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_HEIGHT_MAX);
301  if (ret < avctx->height) {
302  av_log(avctx, AV_LOG_VERBOSE, "Height %d exceeds %d\n",
303  avctx->height, ret);
304  return AVERROR(ENOSYS);
305  }
306 
307  ret = nvenc_check_cap(avctx, NV_ENC_CAPS_NUM_MAX_BFRAMES);
308  if (ret < avctx->max_b_frames) {
309  av_log(avctx, AV_LOG_VERBOSE, "Max B-frames %d exceed %d\n",
310  avctx->max_b_frames, ret);
311 
312  return AVERROR(ENOSYS);
313  }
314 
315  return 0;
316 }
317 
318 static int nvenc_check_device(AVCodecContext *avctx, int idx)
319 {
320  NVENCContext *ctx = avctx->priv_data;
321  NVENCLibraryContext *nvel = &ctx->nvel;
322  char name[128] = { 0 };
323  int major, minor, ret;
324  CUdevice cu_device;
325  CUcontext dummy;
326  int loglevel = AV_LOG_VERBOSE;
327 
328  if (ctx->device == LIST_DEVICES)
329  loglevel = AV_LOG_INFO;
330 
331  ret = nvel->cu_device_get(&cu_device, idx);
332  if (ret != CUDA_SUCCESS) {
333  av_log(avctx, AV_LOG_ERROR,
334  "Cannot access the CUDA device %d\n",
335  idx);
336  return -1;
337  }
338 
339  ret = nvel->cu_device_get_name(name, sizeof(name), cu_device);
340  if (ret != CUDA_SUCCESS)
341  return -1;
342 
343  ret = nvel->cu_device_compute_capability(&major, &minor, cu_device);
344  if (ret != CUDA_SUCCESS)
345  return -1;
346 
347  av_log(avctx, loglevel, "Device %d [%s] ", cu_device, name);
348 
349  if (((major << 4) | minor) < NVENC_CAP)
350  goto fail;
351 
352  ret = nvel->cu_ctx_create(&ctx->cu_context_internal, 0, cu_device);
353  if (ret != CUDA_SUCCESS)
354  goto fail;
355 
356  ctx->cu_context = ctx->cu_context_internal;
357 
358  ret = nvel->cu_ctx_pop_current(&dummy);
359  if (ret != CUDA_SUCCESS)
360  goto fail2;
361 
362  if ((ret = nvenc_open_session(avctx)) < 0)
363  goto fail2;
364 
365  if ((ret = nvenc_check_capabilities(avctx)) < 0)
366  goto fail3;
367 
368  av_log(avctx, loglevel, "supports NVENC\n");
369 
370  if (ctx->device == cu_device || ctx->device == ANY_DEVICE)
371  return 0;
372 
373 fail3:
374  nvel->nvenc_funcs.nvEncDestroyEncoder(ctx->nvenc_ctx);
375  ctx->nvenc_ctx = NULL;
376 
377 fail2:
379  ctx->cu_context_internal = NULL;
380 
381 fail:
382  if (ret != 0)
383  av_log(avctx, loglevel, "does not support NVENC (major %d minor %d)\n",
384  major, minor);
385 
386  return AVERROR(ENOSYS);
387 }
388 
390 {
391  NVENCContext *ctx = avctx->priv_data;
392  NVENCLibraryContext *nvel = &ctx->nvel;
393 
394  switch (avctx->codec->id) {
395  case AV_CODEC_ID_H264:
396  ctx->params.encodeGUID = NV_ENC_CODEC_H264_GUID;
397  break;
398  case AV_CODEC_ID_HEVC:
399  ctx->params.encodeGUID = NV_ENC_CODEC_HEVC_GUID;
400  break;
401  default:
402  return AVERROR_BUG;
403  }
404 
405  if (avctx->pix_fmt == AV_PIX_FMT_CUDA) {
406 #if CONFIG_CUDA
407  AVHWFramesContext *frames_ctx;
408  AVCUDADeviceContext *device_hwctx;
409  int ret;
410 
411  if (!avctx->hw_frames_ctx)
412  return AVERROR(EINVAL);
413 
414  frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
415  device_hwctx = frames_ctx->device_ctx->hwctx;
416 
417  ctx->cu_context = device_hwctx->cuda_ctx;
418 
419  ret = nvenc_open_session(avctx);
420  if (ret < 0)
421  return ret;
422 
423  ret = nvenc_check_capabilities(avctx);
424  if (ret < 0)
425  return ret;
426 #else
427  return AVERROR_BUG;
428 #endif
429  } else {
430  int i, nb_devices = 0;
431 
432  if ((nvel->cu_init(0)) != CUDA_SUCCESS) {
433  av_log(avctx, AV_LOG_ERROR,
434  "Cannot init CUDA\n");
435  return AVERROR_UNKNOWN;
436  }
437 
438  if ((nvel->cu_device_get_count(&nb_devices)) != CUDA_SUCCESS) {
439  av_log(avctx, AV_LOG_ERROR,
440  "Cannot enumerate the CUDA devices\n");
441  return AVERROR_UNKNOWN;
442  }
443 
444 
445  for (i = 0; i < nb_devices; ++i) {
446  if ((nvenc_check_device(avctx, i)) >= 0 && ctx->device != LIST_DEVICES)
447  return 0;
448  }
449 
450  if (ctx->device == LIST_DEVICES)
451  return AVERROR_EXIT;
452 
453  return AVERROR(ENOSYS);
454  }
455 
456  return 0;
457 }
458 
459 typedef struct GUIDTuple {
460  const GUID guid;
461  int flags;
462 } GUIDTuple;
463 
465 {
466  GUIDTuple presets[] = {
467  { NV_ENC_PRESET_DEFAULT_GUID },
468  { NV_ENC_PRESET_HP_GUID },
469  { NV_ENC_PRESET_HQ_GUID },
470  { NV_ENC_PRESET_BD_GUID },
471  { NV_ENC_PRESET_LOW_LATENCY_DEFAULT_GUID, NVENC_LOWLATENCY },
472  { NV_ENC_PRESET_LOW_LATENCY_HP_GUID, NVENC_LOWLATENCY },
473  { NV_ENC_PRESET_LOW_LATENCY_HQ_GUID, NVENC_LOWLATENCY },
474  { NV_ENC_PRESET_LOSSLESS_DEFAULT_GUID, NVENC_LOSSLESS },
475  { NV_ENC_PRESET_LOSSLESS_HP_GUID, NVENC_LOSSLESS },
476  { { 0 } }
477  };
478 
479  GUIDTuple *t = &presets[ctx->preset];
480 
481  ctx->params.presetGUID = t->guid;
482  ctx->flags = t->flags;
483 
484  return AVERROR(EINVAL);
485 }
486 
487 static void set_constqp(AVCodecContext *avctx, NV_ENC_RC_PARAMS *rc)
488 {
489  rc->rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
490  rc->constQP.qpInterB = avctx->global_quality;
491  rc->constQP.qpInterP = avctx->global_quality;
492  rc->constQP.qpIntra = avctx->global_quality;
493 }
494 
495 static void set_vbr(AVCodecContext *avctx, NV_ENC_RC_PARAMS *rc)
496 {
497  if (avctx->qmin >= 0) {
498  rc->enableMinQP = 1;
499  rc->minQP.qpInterB = avctx->qmin;
500  rc->minQP.qpInterP = avctx->qmin;
501  rc->minQP.qpIntra = avctx->qmin;
502  }
503 
504  if (avctx->qmax >= 0) {
505  rc->enableMaxQP = 1;
506  rc->maxQP.qpInterB = avctx->qmax;
507  rc->maxQP.qpInterP = avctx->qmax;
508  rc->maxQP.qpIntra = avctx->qmax;
509  }
510 }
511 
512 static void set_lossless(AVCodecContext *avctx, NV_ENC_RC_PARAMS *rc)
513 {
514  rc->rateControlMode = NV_ENC_PARAMS_RC_CONSTQP;
515  rc->constQP.qpInterB = 0;
516  rc->constQP.qpInterP = 0;
517  rc->constQP.qpIntra = 0;
518 }
519 
521  NV_ENC_RC_PARAMS *rc)
522 {
523  NVENCContext *ctx = avctx->priv_data;
524 
525  switch (ctx->rc) {
526  case NV_ENC_PARAMS_RC_CONSTQP:
527  if (avctx->global_quality < 0) {
528  av_log(avctx, AV_LOG_WARNING,
529  "The constant quality rate-control requires "
530  "the 'global_quality' option set.\n");
531  return;
532  }
533  set_constqp(avctx, rc);
534  return;
535  case NV_ENC_PARAMS_RC_2_PASS_VBR:
536  case NV_ENC_PARAMS_RC_VBR:
537  if (avctx->qmin < 0 && avctx->qmax < 0) {
538  av_log(avctx, AV_LOG_WARNING,
539  "The variable bitrate rate-control requires "
540  "the 'qmin' and/or 'qmax' option set.\n");
541  return;
542  }
543  case NV_ENC_PARAMS_RC_VBR_MINQP:
544  if (avctx->qmin < 0) {
545  av_log(avctx, AV_LOG_WARNING,
546  "The variable bitrate rate-control requires "
547  "the 'qmin' option set.\n");
548  return;
549  }
550  set_vbr(avctx, rc);
551  break;
552  case NV_ENC_PARAMS_RC_CBR:
553  break;
554  case NV_ENC_PARAMS_RC_2_PASS_QUALITY:
555  case NV_ENC_PARAMS_RC_2_PASS_FRAMESIZE_CAP:
556  if (!(ctx->flags & NVENC_LOWLATENCY)) {
557  av_log(avctx, AV_LOG_WARNING,
558  "The multipass rate-control requires "
559  "a low-latency preset.\n");
560  return;
561  }
562  }
563 
564  rc->rateControlMode = ctx->rc;
565 }
566 
568 {
569  NVENCContext *ctx = avctx->priv_data;
570  NV_ENC_RC_PARAMS *rc = &ctx->config.rcParams;
571 
572  if (avctx->bit_rate > 0)
573  rc->averageBitRate = avctx->bit_rate;
574 
575  if (avctx->rc_max_rate > 0)
576  rc->maxBitRate = avctx->rc_max_rate;
577 
578  if (ctx->rc > 0) {
579  nvenc_override_rate_control(avctx, rc);
580  } else if (ctx->flags & NVENC_LOSSLESS) {
581  set_lossless(avctx, rc);
582  } else if (avctx->global_quality > 0) {
583  set_constqp(avctx, rc);
584  } else if (avctx->qmin >= 0 && avctx->qmax >= 0) {
585  rc->rateControlMode = NV_ENC_PARAMS_RC_VBR;
586  set_vbr(avctx, rc);
587  }
588 
589  if (avctx->rc_buffer_size > 0)
590  rc->vbvBufferSize = avctx->rc_buffer_size;
591 
592  if (rc->averageBitRate > 0)
593  avctx->bit_rate = rc->averageBitRate;
594 }
595 
597 {
598  NVENCContext *ctx = avctx->priv_data;
599  NV_ENC_CONFIG *cc = &ctx->config;
600  NV_ENC_CONFIG_H264 *h264 = &cc->encodeCodecConfig.h264Config;
601  NV_ENC_CONFIG_H264_VUI_PARAMETERS *vui = &h264->h264VUIParameters;
602 
603  vui->colourDescriptionPresentFlag = avctx->colorspace != AVCOL_SPC_UNSPECIFIED ||
606 
607  vui->colourMatrix = avctx->colorspace;
608  vui->colourPrimaries = avctx->color_primaries;
609  vui->transferCharacteristics = avctx->color_trc;
610 
611  vui->videoFullRangeFlag = avctx->color_range == AVCOL_RANGE_JPEG;
612 
613  vui->videoSignalTypePresentFlag = vui->colourDescriptionPresentFlag ||
614  vui->videoFullRangeFlag;
615 
616  h264->disableSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0;
617  h264->repeatSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1;
618  h264->outputAUD = 1;
619 
620  h264->maxNumRefFrames = avctx->refs;
621  h264->idrPeriod = cc->gopLength;
622 
623  h264->sliceMode = 3;
624  h264->sliceModeData = FFMAX(avctx->slices, 1);
625 
626  if (ctx->flags & NVENC_LOSSLESS)
627  h264->qpPrimeYZeroTransformBypassFlag = 1;
628 
629  if (IS_CBR(cc->rcParams.rateControlMode)) {
630  h264->outputBufferingPeriodSEI = 1;
631  h264->outputPictureTimingSEI = 1;
632  }
633 
634  if (ctx->profile)
635  avctx->profile = ctx->profile;
636 
637  if (ctx->data_pix_fmt == AV_PIX_FMT_YUV444P)
638  h264->chromaFormatIDC = 3;
639  else
640  h264->chromaFormatIDC = 1;
641 
642  switch (ctx->profile) {
644  cc->profileGUID = NV_ENC_H264_PROFILE_BASELINE_GUID;
645  break;
647  cc->profileGUID = NV_ENC_H264_PROFILE_MAIN_GUID;
648  break;
650  cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_GUID;
651  break;
653  cc->profileGUID = NV_ENC_H264_PROFILE_HIGH_444_GUID;
654  break;
656  cc->profileGUID = NV_ENC_H264_PROFILE_CONSTRAINED_HIGH_GUID;
657  break;
658  }
659 
660  h264->level = ctx->level;
661 
662  return 0;
663 }
664 
666 {
667  NVENCContext *ctx = avctx->priv_data;
668  NV_ENC_CONFIG *cc = &ctx->config;
669  NV_ENC_CONFIG_HEVC *hevc = &cc->encodeCodecConfig.hevcConfig;
670  NV_ENC_CONFIG_HEVC_VUI_PARAMETERS *vui = &hevc->hevcVUIParameters;
671 
672  vui->colourDescriptionPresentFlag = avctx->colorspace != AVCOL_SPC_UNSPECIFIED ||
675 
676  vui->colourMatrix = avctx->colorspace;
677  vui->colourPrimaries = avctx->color_primaries;
678  vui->transferCharacteristics = avctx->color_trc;
679 
680  vui->videoFullRangeFlag = avctx->color_range == AVCOL_RANGE_JPEG;
681 
682  vui->videoSignalTypePresentFlag = vui->colourDescriptionPresentFlag ||
683  vui->videoFullRangeFlag;
684 
685  hevc->disableSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 1 : 0;
686  hevc->repeatSPSPPS = (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) ? 0 : 1;
687  hevc->outputAUD = 1;
688 
689  hevc->maxNumRefFramesInDPB = avctx->refs;
690  hevc->idrPeriod = cc->gopLength;
691 
692  if (IS_CBR(cc->rcParams.rateControlMode)) {
693  hevc->outputBufferingPeriodSEI = 1;
694  hevc->outputPictureTimingSEI = 1;
695  }
696 
697  /* No other profile is supported in the current SDK version 5 */
698  cc->profileGUID = NV_ENC_HEVC_PROFILE_MAIN_GUID;
699  avctx->profile = FF_PROFILE_HEVC_MAIN;
700 
701  hevc->sliceMode = 3;
702  hevc->sliceModeData = FFMAX(avctx->slices, 1);
703 
704  if (ctx->level) {
705  hevc->level = ctx->level;
706  } else {
707  hevc->level = NV_ENC_LEVEL_AUTOSELECT;
708  }
709 
710  if (ctx->tier) {
711  hevc->tier = ctx->tier;
712  }
713 
714  return 0;
715 }
717 {
718  switch (avctx->codec->id) {
719  case AV_CODEC_ID_H264:
720  return nvenc_setup_h264_config(avctx);
721  case AV_CODEC_ID_HEVC:
722  return nvenc_setup_hevc_config(avctx);
723  }
724  return 0;
725 }
726 
728 {
729  NVENCContext *ctx = avctx->priv_data;
730  NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs;
731  NV_ENC_PRESET_CONFIG preset_cfg = { 0 };
732  AVCPBProperties *cpb_props;
733  int ret;
734 
735  ctx->params.version = NV_ENC_INITIALIZE_PARAMS_VER;
736 
737  ctx->params.encodeHeight = avctx->height;
738  ctx->params.encodeWidth = avctx->width;
739 
740  if (avctx->sample_aspect_ratio.num &&
741  avctx->sample_aspect_ratio.den &&
742  (avctx->sample_aspect_ratio.num != 1 ||
743  avctx->sample_aspect_ratio.den != 1)) {
744  av_reduce(&ctx->params.darWidth,
745  &ctx->params.darHeight,
746  avctx->width * avctx->sample_aspect_ratio.num,
747  avctx->height * avctx->sample_aspect_ratio.den,
748  INT_MAX / 8);
749  } else {
750  ctx->params.darHeight = avctx->height;
751  ctx->params.darWidth = avctx->width;
752  }
753 
754  // De-compensate for hardware, dubiously, trying to compensate for
755  // playback at 704 pixel width.
756  if (avctx->width == 720 && (avctx->height == 480 || avctx->height == 576)) {
757  av_reduce(&ctx->params.darWidth, &ctx->params.darHeight,
758  ctx->params.darWidth * 44,
759  ctx->params.darHeight * 45,
760  1024 * 1024);
761  }
762 
763  ctx->params.frameRateNum = avctx->time_base.den;
764  ctx->params.frameRateDen = avctx->time_base.num * avctx->ticks_per_frame;
765 
766  ctx->params.enableEncodeAsync = 0;
767  ctx->params.enablePTD = 1;
768 
769  ctx->params.encodeConfig = &ctx->config;
770 
771  nvec_map_preset(ctx);
772 
773  preset_cfg.version = NV_ENC_PRESET_CONFIG_VER;
774  preset_cfg.presetCfg.version = NV_ENC_CONFIG_VER;
775 
776  ret = nv->nvEncGetEncodePresetConfig(ctx->nvenc_ctx,
777  ctx->params.encodeGUID,
778  ctx->params.presetGUID,
779  &preset_cfg);
780  if (ret != NV_ENC_SUCCESS)
781  return nvenc_print_error(avctx, ret, "Cannot get the preset configuration");
782 
783  memcpy(&ctx->config, &preset_cfg.presetCfg, sizeof(ctx->config));
784 
785  ctx->config.version = NV_ENC_CONFIG_VER;
786 
787  if (avctx->gop_size > 0) {
788  if (avctx->max_b_frames > 0) {
789  /* 0 is intra-only,
790  * 1 is I/P only,
791  * 2 is one B-Frame,
792  * 3 two B-frames, and so on. */
793  ctx->config.frameIntervalP = avctx->max_b_frames + 1;
794  } else if (avctx->max_b_frames == 0) {
795  ctx->config.frameIntervalP = 1;
796  }
797  ctx->config.gopLength = avctx->gop_size;
798  } else if (avctx->gop_size == 0) {
799  ctx->config.frameIntervalP = 0;
800  ctx->config.gopLength = 1;
801  }
802 
803  if (ctx->config.frameIntervalP > 1)
804  avctx->max_b_frames = ctx->config.frameIntervalP - 1;
805 
806  ctx->initial_pts[0] = AV_NOPTS_VALUE;
807  ctx->initial_pts[1] = AV_NOPTS_VALUE;
808 
810 
811  if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
812  ctx->config.frameFieldMode = NV_ENC_PARAMS_FRAME_FIELD_MODE_FIELD;
813  } else {
814  ctx->config.frameFieldMode = NV_ENC_PARAMS_FRAME_FIELD_MODE_FRAME;
815  }
816 
817  if ((ret = nvenc_setup_codec_config(avctx)) < 0)
818  return ret;
819 
820  ret = nv->nvEncInitializeEncoder(ctx->nvenc_ctx, &ctx->params);
821  if (ret != NV_ENC_SUCCESS)
822  return nvenc_print_error(avctx, ret, "Cannot initialize the decoder");
823 
824  cpb_props = ff_add_cpb_side_data(avctx);
825  if (!cpb_props)
826  return AVERROR(ENOMEM);
827  cpb_props->max_bitrate = avctx->rc_max_rate;
828  cpb_props->min_bitrate = avctx->rc_min_rate;
829  cpb_props->avg_bitrate = avctx->bit_rate;
830  cpb_props->buffer_size = avctx->rc_buffer_size;
831 
832  return 0;
833 }
834 
835 static int nvenc_alloc_surface(AVCodecContext *avctx, int idx)
836 {
837  NVENCContext *ctx = avctx->priv_data;
838  NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs;
839  int ret;
840  NV_ENC_CREATE_BITSTREAM_BUFFER out_buffer = { 0 };
841 
842  switch (ctx->data_pix_fmt) {
843  case AV_PIX_FMT_YUV420P:
844  ctx->frames[idx].format = NV_ENC_BUFFER_FORMAT_YV12_PL;
845  break;
846  case AV_PIX_FMT_NV12:
847  ctx->frames[idx].format = NV_ENC_BUFFER_FORMAT_NV12_PL;
848  break;
849  case AV_PIX_FMT_YUV444P:
850  ctx->frames[idx].format = NV_ENC_BUFFER_FORMAT_YUV444_PL;
851  break;
852  default:
853  return AVERROR_BUG;
854  }
855 
856  if (avctx->pix_fmt == AV_PIX_FMT_CUDA) {
857  ctx->frames[idx].in_ref = av_frame_alloc();
858  if (!ctx->frames[idx].in_ref)
859  return AVERROR(ENOMEM);
860  } else {
861  NV_ENC_CREATE_INPUT_BUFFER in_buffer = { 0 };
862 
863  in_buffer.version = NV_ENC_CREATE_INPUT_BUFFER_VER;
864 
865  in_buffer.width = avctx->width;
866  in_buffer.height = avctx->height;
867 
868  in_buffer.bufferFmt = ctx->frames[idx].format;
869  in_buffer.memoryHeap = NV_ENC_MEMORY_HEAP_SYSMEM_UNCACHED;
870 
871  ret = nv->nvEncCreateInputBuffer(ctx->nvenc_ctx, &in_buffer);
872  if (ret != NV_ENC_SUCCESS)
873  return nvenc_print_error(avctx, ret, "CreateInputBuffer failed");
874 
875  ctx->frames[idx].in = in_buffer.inputBuffer;
876  }
877 
878  out_buffer.version = NV_ENC_CREATE_BITSTREAM_BUFFER_VER;
879  /* 1MB is large enough to hold most output frames.
880  * NVENC increases this automatically if it is not enough. */
881  out_buffer.size = BITSTREAM_BUFFER_SIZE;
882 
883  out_buffer.memoryHeap = NV_ENC_MEMORY_HEAP_SYSMEM_UNCACHED;
884 
885  ret = nv->nvEncCreateBitstreamBuffer(ctx->nvenc_ctx, &out_buffer);
886  if (ret != NV_ENC_SUCCESS)
887  return nvenc_print_error(avctx, ret, "CreateBitstreamBuffer failed");
888 
889  ctx->frames[idx].out = out_buffer.bitstreamBuffer;
890 
891  return 0;
892 }
893 
895 {
896  NVENCContext *ctx = avctx->priv_data;
897  int i, ret;
898 
899  ctx->nb_surfaces = FFMAX(4 + avctx->max_b_frames,
900  ctx->nb_surfaces);
901  ctx->async_depth = FFMIN(ctx->async_depth, ctx->nb_surfaces - 1);
902 
903 
904  ctx->frames = av_mallocz_array(ctx->nb_surfaces, sizeof(*ctx->frames));
905  if (!ctx->frames)
906  return AVERROR(ENOMEM);
907 
908  ctx->timestamps = av_fifo_alloc(ctx->nb_surfaces * sizeof(int64_t));
909  if (!ctx->timestamps)
910  return AVERROR(ENOMEM);
911  ctx->pending = av_fifo_alloc(ctx->nb_surfaces * sizeof(*ctx->frames));
912  if (!ctx->pending)
913  return AVERROR(ENOMEM);
914  ctx->ready = av_fifo_alloc(ctx->nb_surfaces * sizeof(*ctx->frames));
915  if (!ctx->ready)
916  return AVERROR(ENOMEM);
917 
918  for (i = 0; i < ctx->nb_surfaces; i++) {
919  if ((ret = nvenc_alloc_surface(avctx, i)) < 0)
920  return ret;
921  }
922 
923  return 0;
924 }
925 
926 #define EXTRADATA_SIZE 512
927 
929 {
930  NVENCContext *ctx = avctx->priv_data;
931  NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs;
932  NV_ENC_SEQUENCE_PARAM_PAYLOAD payload = { 0 };
933  int ret;
934 
936  if (!avctx->extradata)
937  return AVERROR(ENOMEM);
938 
939  payload.version = NV_ENC_SEQUENCE_PARAM_PAYLOAD_VER;
940  payload.spsppsBuffer = avctx->extradata;
941  payload.inBufferSize = EXTRADATA_SIZE;
942  payload.outSPSPPSPayloadSize = &avctx->extradata_size;
943 
944  ret = nv->nvEncGetSequenceParams(ctx->nvenc_ctx, &payload);
945  if (ret != NV_ENC_SUCCESS)
946  return nvenc_print_error(avctx, ret, "Cannot get the extradata");
947 
948  return 0;
949 }
950 
952 {
953  NVENCContext *ctx = avctx->priv_data;
954  NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs;
955  int i;
956 
957  /* the encoder has to be flushed before it can be closed */
958  if (ctx->nvenc_ctx) {
959  NV_ENC_PIC_PARAMS params = { .version = NV_ENC_PIC_PARAMS_VER,
960  .encodePicFlags = NV_ENC_PIC_FLAG_EOS };
961 
962  nv->nvEncEncodePicture(ctx->nvenc_ctx, &params);
963  }
964 
965  av_fifo_free(ctx->timestamps);
966  av_fifo_free(ctx->pending);
967  av_fifo_free(ctx->ready);
968 
969  if (ctx->frames) {
970  for (i = 0; i < ctx->nb_surfaces; ++i) {
971  if (avctx->pix_fmt != AV_PIX_FMT_CUDA) {
972  nv->nvEncDestroyInputBuffer(ctx->nvenc_ctx, ctx->frames[i].in);
973  } else if (ctx->frames[i].in) {
974  nv->nvEncUnmapInputResource(ctx->nvenc_ctx, ctx->frames[i].in_map.mappedResource);
975  }
976 
977  av_frame_free(&ctx->frames[i].in_ref);
978  nv->nvEncDestroyBitstreamBuffer(ctx->nvenc_ctx, ctx->frames[i].out);
979  }
980  }
981  for (i = 0; i < ctx->nb_registered_frames; i++) {
982  if (ctx->registered_frames[i].regptr)
983  nv->nvEncUnregisterResource(ctx->nvenc_ctx, ctx->registered_frames[i].regptr);
984  }
985  ctx->nb_registered_frames = 0;
986 
987  av_freep(&ctx->frames);
988 
989  if (ctx->nvenc_ctx)
990  nv->nvEncDestroyEncoder(ctx->nvenc_ctx);
991 
992  if (ctx->cu_context_internal)
994 
995  if (ctx->nvel.nvenc)
996  dlclose(ctx->nvel.nvenc);
997 
998 #if !CONFIG_CUDA
999  if (ctx->nvel.cuda)
1000  dlclose(ctx->nvel.cuda);
1001 #endif
1002 
1003  return 0;
1004 }
1005 
1007 {
1008  NVENCContext *ctx = avctx->priv_data;
1009  int ret;
1010 
1011  if (avctx->pix_fmt == AV_PIX_FMT_CUDA) {
1012  AVHWFramesContext *frames_ctx;
1013  if (!avctx->hw_frames_ctx) {
1014  av_log(avctx, AV_LOG_ERROR,
1015  "hw_frames_ctx must be set when using GPU frames as input\n");
1016  return AVERROR(EINVAL);
1017  }
1018  frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
1019  ctx->data_pix_fmt = frames_ctx->sw_format;
1020  } else {
1021  ctx->data_pix_fmt = avctx->pix_fmt;
1022  }
1023 
1024  if ((ret = nvenc_load_libraries(avctx)) < 0)
1025  return ret;
1026 
1027  if ((ret = nvenc_setup_device(avctx)) < 0)
1028  return ret;
1029 
1030  if ((ret = nvenc_setup_encoder(avctx)) < 0)
1031  return ret;
1032 
1033  if ((ret = nvenc_setup_surfaces(avctx)) < 0)
1034  return ret;
1035 
1036  if (avctx->flags & AV_CODEC_FLAG_GLOBAL_HEADER) {
1037  if ((ret = nvenc_setup_extradata(avctx)) < 0)
1038  return ret;
1039  }
1040 
1041  return 0;
1042 }
1043 
1045 {
1046  int i;
1047 
1048  for (i = 0; i < ctx->nb_surfaces; i++) {
1049  if (!ctx->frames[i].locked) {
1050  ctx->frames[i].locked = 1;
1051  return &ctx->frames[i];
1052  }
1053  }
1054 
1055  return NULL;
1056 }
1057 
1058 static int nvenc_copy_frame(NV_ENC_LOCK_INPUT_BUFFER *in, const AVFrame *frame)
1059 {
1060  uint8_t *buf = in->bufferDataPtr;
1061  int off = frame->height * in->pitch;
1062 
1063  switch (frame->format) {
1064  case AV_PIX_FMT_YUV420P:
1065  av_image_copy_plane(buf, in->pitch,
1066  frame->data[0], frame->linesize[0],
1067  frame->width, frame->height);
1068  buf += off;
1069 
1070  av_image_copy_plane(buf, in->pitch >> 1,
1071  frame->data[2], frame->linesize[2],
1072  frame->width >> 1, frame->height >> 1);
1073 
1074  buf += off >> 2;
1075 
1076  av_image_copy_plane(buf, in->pitch >> 1,
1077  frame->data[1], frame->linesize[1],
1078  frame->width >> 1, frame->height >> 1);
1079  break;
1080  case AV_PIX_FMT_NV12:
1081  av_image_copy_plane(buf, in->pitch,
1082  frame->data[0], frame->linesize[0],
1083  frame->width, frame->height);
1084  buf += off;
1085 
1086  av_image_copy_plane(buf, in->pitch,
1087  frame->data[1], frame->linesize[1],
1088  frame->width, frame->height >> 1);
1089  break;
1090  case AV_PIX_FMT_YUV444P:
1091  av_image_copy_plane(buf, in->pitch,
1092  frame->data[0], frame->linesize[0],
1093  frame->width, frame->height);
1094  buf += off;
1095 
1096  av_image_copy_plane(buf, in->pitch,
1097  frame->data[1], frame->linesize[1],
1098  frame->width, frame->height);
1099  buf += off;
1100 
1101  av_image_copy_plane(buf, in->pitch,
1102  frame->data[2], frame->linesize[2],
1103  frame->width, frame->height);
1104  break;
1105  default:
1106  return AVERROR_BUG;
1107  }
1108 
1109  return 0;
1110 }
1111 
1113 {
1114  NVENCContext *ctx = avctx->priv_data;
1115  NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs;
1116  int i;
1117 
1119  for (i = 0; i < ctx->nb_registered_frames; i++) {
1120  if (!ctx->registered_frames[i].mapped) {
1121  if (ctx->registered_frames[i].regptr) {
1122  nv->nvEncUnregisterResource(ctx->nvenc_ctx,
1123  ctx->registered_frames[i].regptr);
1124  ctx->registered_frames[i].regptr = NULL;
1125  }
1126  return i;
1127  }
1128  }
1129  } else {
1130  return ctx->nb_registered_frames++;
1131  }
1132 
1133  av_log(avctx, AV_LOG_ERROR, "Too many registered CUDA frames\n");
1134  return AVERROR(ENOMEM);
1135 }
1136 
1137 static int nvenc_register_frame(AVCodecContext *avctx, const AVFrame *frame)
1138 {
1139  NVENCContext *ctx = avctx->priv_data;
1140  NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs;
1141  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
1142  NV_ENC_REGISTER_RESOURCE reg;
1143  int i, idx, ret;
1144 
1145  for (i = 0; i < ctx->nb_registered_frames; i++) {
1146  if (ctx->registered_frames[i].ptr == (CUdeviceptr)frame->data[0])
1147  return i;
1148  }
1149 
1150  idx = nvenc_find_free_reg_resource(avctx);
1151  if (idx < 0)
1152  return idx;
1153 
1154  reg.version = NV_ENC_REGISTER_RESOURCE_VER;
1155  reg.resourceType = NV_ENC_INPUT_RESOURCE_TYPE_CUDADEVICEPTR;
1156  reg.width = frames_ctx->width;
1157  reg.height = frames_ctx->height;
1158  reg.bufferFormat = ctx->frames[0].format;
1159  reg.pitch = frame->linesize[0];
1160  reg.resourceToRegister = frame->data[0];
1161 
1162  ret = nv->nvEncRegisterResource(ctx->nvenc_ctx, &reg);
1163  if (ret != NV_ENC_SUCCESS) {
1164  nvenc_print_error(avctx, ret, "Error registering an input resource");
1165  return AVERROR_UNKNOWN;
1166  }
1167 
1168  ctx->registered_frames[idx].ptr = (CUdeviceptr)frame->data[0];
1169  ctx->registered_frames[idx].regptr = reg.registeredResource;
1170  return idx;
1171 }
1172 
1173 static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame,
1174  NVENCFrame *nvenc_frame)
1175 {
1176  NVENCContext *ctx = avctx->priv_data;
1177  NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs;
1178  int ret;
1179 
1180  if (avctx->pix_fmt == AV_PIX_FMT_CUDA) {
1181  int reg_idx;
1182 
1183  ret = nvenc_register_frame(avctx, frame);
1184  if (ret < 0) {
1185  av_log(avctx, AV_LOG_ERROR, "Could not register an input CUDA frame\n");
1186  return ret;
1187  }
1188  reg_idx = ret;
1189 
1190  ret = av_frame_ref(nvenc_frame->in_ref, frame);
1191  if (ret < 0)
1192  return ret;
1193 
1194  nvenc_frame->in_map.version = NV_ENC_MAP_INPUT_RESOURCE_VER;
1195  nvenc_frame->in_map.registeredResource = ctx->registered_frames[reg_idx].regptr;
1196 
1197  ret = nv->nvEncMapInputResource(ctx->nvenc_ctx, &nvenc_frame->in_map);
1198  if (ret != NV_ENC_SUCCESS) {
1199  av_frame_unref(nvenc_frame->in_ref);
1200  return nvenc_print_error(avctx, ret, "Error mapping an input resource");
1201  }
1202 
1203  ctx->registered_frames[reg_idx].mapped = 1;
1204  nvenc_frame->reg_idx = reg_idx;
1205  nvenc_frame->in = nvenc_frame->in_map.mappedResource;
1206  } else {
1207  NV_ENC_LOCK_INPUT_BUFFER params = { 0 };
1208 
1209  params.version = NV_ENC_LOCK_INPUT_BUFFER_VER;
1210  params.inputBuffer = nvenc_frame->in;
1211 
1212  ret = nv->nvEncLockInputBuffer(ctx->nvenc_ctx, &params);
1213  if (ret != NV_ENC_SUCCESS)
1214  return nvenc_print_error(avctx, ret, "Cannot lock the buffer");
1215 
1216  ret = nvenc_copy_frame(&params, frame);
1217  if (ret < 0) {
1218  nv->nvEncUnlockInputBuffer(ctx->nvenc_ctx, nvenc_frame->in);
1219  return ret;
1220  }
1221 
1222  ret = nv->nvEncUnlockInputBuffer(ctx->nvenc_ctx, nvenc_frame->in);
1223  if (ret != NV_ENC_SUCCESS)
1224  return nvenc_print_error(avctx, ret, "Cannot unlock the buffer");
1225  }
1226 
1227  return 0;
1228 }
1229 
1231  NV_ENC_PIC_PARAMS *params)
1232 {
1233  NVENCContext *ctx = avctx->priv_data;
1234 
1235  switch (avctx->codec->id) {
1236  case AV_CODEC_ID_H264:
1237  params->codecPicParams.h264PicParams.sliceMode =
1238  ctx->config.encodeCodecConfig.h264Config.sliceMode;
1239  params->codecPicParams.h264PicParams.sliceModeData =
1240  ctx->config.encodeCodecConfig.h264Config.sliceModeData;
1241  break;
1242  case AV_CODEC_ID_HEVC:
1243  params->codecPicParams.hevcPicParams.sliceMode =
1244  ctx->config.encodeCodecConfig.hevcConfig.sliceMode;
1245  params->codecPicParams.hevcPicParams.sliceModeData =
1246  ctx->config.encodeCodecConfig.hevcConfig.sliceModeData;
1247  break;
1248  }
1249 }
1250 
1251 static inline int nvenc_enqueue_timestamp(AVFifoBuffer *f, int64_t pts)
1252 {
1253  return av_fifo_generic_write(f, &pts, sizeof(pts), NULL);
1254 }
1255 
1256 static inline int nvenc_dequeue_timestamp(AVFifoBuffer *f, int64_t *pts)
1257 {
1258  return av_fifo_generic_read(f, pts, sizeof(*pts), NULL);
1259 }
1260 
1262  NV_ENC_LOCK_BITSTREAM *params,
1263  AVPacket *pkt)
1264 {
1265  NVENCContext *ctx = avctx->priv_data;
1266 
1267  pkt->pts = params->outputTimeStamp;
1268  pkt->duration = params->outputDuration;
1269 
1270  /* generate the first dts by linearly extrapolating the
1271  * first two pts values to the past */
1272  if (avctx->max_b_frames > 0 && !ctx->first_packet_output &&
1273  ctx->initial_pts[1] != AV_NOPTS_VALUE) {
1274  int64_t ts0 = ctx->initial_pts[0], ts1 = ctx->initial_pts[1];
1275  int64_t delta;
1276 
1277  if ((ts0 < 0 && ts1 > INT64_MAX + ts0) ||
1278  (ts0 > 0 && ts1 < INT64_MIN + ts0))
1279  return AVERROR(ERANGE);
1280  delta = ts1 - ts0;
1281 
1282  if ((delta < 0 && ts0 > INT64_MAX + delta) ||
1283  (delta > 0 && ts0 < INT64_MIN + delta))
1284  return AVERROR(ERANGE);
1285  pkt->dts = ts0 - delta;
1286 
1287  ctx->first_packet_output = 1;
1288  return 0;
1289  }
1290  return nvenc_dequeue_timestamp(ctx->timestamps, &pkt->dts);
1291 }
1292 
1293 static int nvenc_get_output(AVCodecContext *avctx, AVPacket *pkt)
1294 {
1295  NVENCContext *ctx = avctx->priv_data;
1296  NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs;
1297  NV_ENC_LOCK_BITSTREAM params = { 0 };
1298  NVENCFrame *frame;
1299  int ret;
1300 
1301  ret = av_fifo_generic_read(ctx->ready, &frame, sizeof(frame), NULL);
1302  if (ret)
1303  return ret;
1304 
1305  params.version = NV_ENC_LOCK_BITSTREAM_VER;
1306  params.outputBitstream = frame->out;
1307 
1308  ret = nv->nvEncLockBitstream(ctx->nvenc_ctx, &params);
1309  if (ret < 0)
1310  return nvenc_print_error(avctx, ret, "Cannot lock the bitstream");
1311 
1312  ret = ff_alloc_packet(pkt, params.bitstreamSizeInBytes);
1313  if (ret < 0)
1314  return ret;
1315 
1316  memcpy(pkt->data, params.bitstreamBufferPtr, pkt->size);
1317 
1318  ret = nv->nvEncUnlockBitstream(ctx->nvenc_ctx, frame->out);
1319  if (ret < 0)
1320  return nvenc_print_error(avctx, ret, "Cannot unlock the bitstream");
1321 
1322  if (avctx->pix_fmt == AV_PIX_FMT_CUDA) {
1323  nv->nvEncUnmapInputResource(ctx->nvenc_ctx, frame->in_map.mappedResource);
1324  av_frame_unref(frame->in_ref);
1325  ctx->registered_frames[frame->reg_idx].mapped = 0;
1326 
1327  frame->in = NULL;
1328  }
1329 
1330  frame->locked = 0;
1331 
1332  ret = nvenc_set_timestamp(avctx, &params, pkt);
1333  if (ret < 0)
1334  return ret;
1335 
1336  switch (params.pictureType) {
1337  case NV_ENC_PIC_TYPE_IDR:
1338  pkt->flags |= AV_PKT_FLAG_KEY;
1339 #if FF_API_CODED_FRAME
1341  case NV_ENC_PIC_TYPE_INTRA_REFRESH:
1342  case NV_ENC_PIC_TYPE_I:
1344  break;
1345  case NV_ENC_PIC_TYPE_P:
1347  break;
1348  case NV_ENC_PIC_TYPE_B:
1350  break;
1351  case NV_ENC_PIC_TYPE_BI:
1353  break;
1355 #endif
1356  }
1357 
1358  return 0;
1359 }
1360 
1361 static int output_ready(AVCodecContext *avctx, int flush)
1362 {
1363  NVENCContext *ctx = avctx->priv_data;
1364  int nb_ready, nb_pending;
1365 
1366  /* when B-frames are enabled, we wait for two initial timestamps to
1367  * calculate the first dts */
1368  if (!flush && avctx->max_b_frames > 0 &&
1369  (ctx->initial_pts[0] == AV_NOPTS_VALUE || ctx->initial_pts[1] == AV_NOPTS_VALUE))
1370  return 0;
1371 
1372  nb_ready = av_fifo_size(ctx->ready) / sizeof(NVENCFrame*);
1373  nb_pending = av_fifo_size(ctx->pending) / sizeof(NVENCFrame*);
1374  if (flush)
1375  return nb_ready > 0;
1376  return (nb_ready > 0) && (nb_ready + nb_pending >= ctx->async_depth);
1377 }
1378 
1380  const AVFrame *frame, int *got_packet)
1381 {
1382  NVENCContext *ctx = avctx->priv_data;
1383  NV_ENCODE_API_FUNCTION_LIST *nv = &ctx->nvel.nvenc_funcs;
1384  NV_ENC_PIC_PARAMS params = { 0 };
1385  NVENCFrame *nvenc_frame = NULL;
1386  int enc_ret, ret;
1387 
1388  params.version = NV_ENC_PIC_PARAMS_VER;
1389 
1390  if (frame) {
1391  nvenc_frame = get_free_frame(ctx);
1392  if (!nvenc_frame) {
1393  av_log(avctx, AV_LOG_ERROR, "No free surfaces\n");
1394  return AVERROR_BUG;
1395  }
1396 
1397  ret = nvenc_upload_frame(avctx, frame, nvenc_frame);
1398  if (ret < 0)
1399  return ret;
1400 
1401  params.inputBuffer = nvenc_frame->in;
1402  params.bufferFmt = nvenc_frame->format;
1403  params.inputWidth = frame->width;
1404  params.inputHeight = frame->height;
1405  params.outputBitstream = nvenc_frame->out;
1406  params.inputTimeStamp = frame->pts;
1407 
1408  if (avctx->flags & AV_CODEC_FLAG_INTERLACED_DCT) {
1409  if (frame->top_field_first)
1410  params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_TOP_BOTTOM;
1411  else
1412  params.pictureStruct = NV_ENC_PIC_STRUCT_FIELD_BOTTOM_TOP;
1413  } else {
1414  params.pictureStruct = NV_ENC_PIC_STRUCT_FRAME;
1415  }
1416 
1417  nvenc_codec_specific_pic_params(avctx, &params);
1418 
1419  ret = nvenc_enqueue_timestamp(ctx->timestamps, frame->pts);
1420  if (ret < 0)
1421  return ret;
1422 
1423  if (ctx->initial_pts[0] == AV_NOPTS_VALUE)
1424  ctx->initial_pts[0] = frame->pts;
1425  else if (ctx->initial_pts[1] == AV_NOPTS_VALUE)
1426  ctx->initial_pts[1] = frame->pts;
1427  } else {
1428  params.encodePicFlags = NV_ENC_PIC_FLAG_EOS;
1429  }
1430 
1431  enc_ret = nv->nvEncEncodePicture(ctx->nvenc_ctx, &params);
1432  if (enc_ret != NV_ENC_SUCCESS &&
1433  enc_ret != NV_ENC_ERR_NEED_MORE_INPUT)
1434  return nvenc_print_error(avctx, enc_ret, "Error encoding the frame");
1435 
1436  if (nvenc_frame) {
1437  ret = av_fifo_generic_write(ctx->pending, &nvenc_frame, sizeof(nvenc_frame), NULL);
1438  if (ret < 0)
1439  return ret;
1440  }
1441 
1442  /* all the pending buffers are now ready for output */
1443  if (enc_ret == NV_ENC_SUCCESS) {
1444  while (av_fifo_size(ctx->pending) > 0) {
1445  av_fifo_generic_read(ctx->pending, &nvenc_frame, sizeof(nvenc_frame), NULL);
1446  av_fifo_generic_write(ctx->ready, &nvenc_frame, sizeof(nvenc_frame), NULL);
1447  }
1448  }
1449 
1450  if (output_ready(avctx, !frame)) {
1451  ret = nvenc_get_output(avctx, pkt);
1452  if (ret < 0)
1453  return ret;
1454  *got_packet = 1;
1455  } else {
1456  *got_packet = 0;
1457  }
1458 
1459  return 0;
1460 }
const GUID guid
Definition: nvenc.c:460
static int nvenc_setup_extradata(AVCodecContext *avctx)
Definition: nvenc.c:928
const struct AVCodec * codec
Definition: avcodec.h:1418
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:62
BI type.
Definition: avutil.h:266
av_cold int ff_nvenc_encode_close(AVCodecContext *avctx)
Definition: nvenc.c:951
static int nvenc_setup_encoder(AVCodecContext *avctx)
Definition: nvenc.c:727
This structure describes decoded (raw) audio or video data.
Definition: frame.h:140
static void set_vbr(AVCodecContext *avctx, NV_ENC_RC_PARAMS *rc)
Definition: nvenc.c:495
#define AV_CODEC_FLAG_INTERLACED_DCT
Use interlaced DCT.
Definition: avcodec.h:776
void * nvenc_ctx
Definition: nvenc.h:153
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:64
misc image utilities
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:130
int locked
Definition: nvenc.h:59
memory handling functions
const char * desc
Definition: nvenc.c:101
int max_bitrate
Maximum bitrate of the stream, in bits per second.
Definition: avcodec.h:1145
int max_b_frames
maximum number of B-frames between non-B-frames Note: The output will be delayed by max_b_frames+1 re...
Definition: avcodec.h:1679
static int nvec_map_preset(NVENCContext *ctx)
Definition: nvenc.c:464
AVFifoBuffer * ready
Definition: nvenc.h:135
int CUdevice
Definition: nvenc.h:44
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:2127
int num
numerator
Definition: rational.h:44
int size
Definition: avcodec.h:1347
av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (%s)\, len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic ? ac->func_descr_generic :ac->func_descr)
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel...
Definition: avcodec.h:1804
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:222
struct NVENCContext::@60 registered_frames[MAX_REGISTERED_FRAMES]
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1621
NV_ENC_REGISTERED_PTR regptr
Definition: nvenc.h:139
#define FF_ARRAY_ELEMS(a)
int nb_registered_frames
Definition: nvenc.h:142
int profile
profile
Definition: avcodec.h:2880
PCUDEVICEGET cu_device_get
Definition: nvenc.h:82
int min_bitrate
Minimum bitrate of the stream, in bits per second.
Definition: avcodec.h:1150
int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int(*func)(void *, void *, int))
Feed data from a user-supplied callback to an AVFifoBuffer.
Definition: fifo.c:84
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented...
Definition: avcodec.h:1535
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:202
NVENCSTATUS nverr
Definition: nvenc.c:99
static int nvenc_setup_h264_config(AVCodecContext *avctx)
Definition: nvenc.c:596
NV_ENC_MAP_INPUT_RESOURCE in_map
Definition: nvenc.h:54
uint8_t
int nb_surfaces
Definition: nvenc.h:132
#define av_cold
Definition: attributes.h:66
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:68
float delta
PCUDEVICECOMPUTECAPABILITY cu_device_compute_capability
Definition: nvenc.h:84
int flags
Definition: nvenc.h:161
int device
Definition: nvenc.h:160
enum AVPixelFormat ff_nvenc_pix_fmts[]
Definition: nvenc.c:88
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: avcodec.h:1364
static int nvenc_setup_device(AVCodecContext *avctx)
Definition: nvenc.c:389
#define FF_PROFILE_HEVC_MAIN
Definition: avcodec.h:2961
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:199
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:211
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1523
NVENCLibraryContext nvel
Definition: nvenc.h:124
static void nvenc_setup_rate_control(AVCodecContext *avctx)
Definition: nvenc.c:567
#define LOAD_LIBRARY(l, path)
Definition: nvenc.c:68
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:85
static int nvenc_open_session(AVCodecContext *avctx)
Definition: nvenc.c:202
uint8_t * data
Definition: avcodec.h:1346
int reg_idx
Definition: nvenc.h:55
int64_t initial_pts[2]
Definition: nvenc.h:150
PCUDEVICEGETNAME cu_device_get_name
Definition: nvenc.h:83
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:140
void av_fifo_free(AVFifoBuffer *f)
Free an AVFifoBuffer.
Definition: fifo.c:38
static int nvenc_check_capabilities(AVCodecContext *avctx)
Definition: nvenc.c:276
AVFrame * in_ref
Definition: nvenc.h:53
static int nvenc_register_frame(AVCodecContext *avctx, const AVFrame *frame)
Definition: nvenc.c:1137
int buffer_size
The size of the buffer to which the ratecontrol is applied, in bits.
Definition: avcodec.h:1161
static const struct @55 nvenc_errors[]
static int nvenc_alloc_surface(AVCodecContext *avctx, int idx)
Definition: nvenc.c:835
An API-specific header for AV_HWDEVICE_TYPE_CUDA.
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1378
static int nvenc_dequeue_timestamp(AVFifoBuffer *f, int64_t *pts)
Definition: nvenc.c:1256
enum AVCodecID id
Definition: avcodec.h:3134
NV_ENC_BUFFER_FORMAT format
Definition: nvenc.h:58
int width
width and height of the video frame
Definition: frame.h:179
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:124
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:190
NV_ENC_INPUT_PTR in
Definition: nvenc.h:52
AVFifoBuffer * pending
Definition: nvenc.h:135
#define LOAD_SYMBOL(fun, lib, symbol)
Definition: nvenc.c:78
#define AVERROR(e)
Definition: error.h:43
NV_ENCODE_API_FUNCTION_LIST nvenc_funcs
Definition: nvenc.h:89
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:80
int qmax
maximum quantizer
Definition: avcodec.h:2337
static int nvenc_map_error(NVENCSTATUS err, const char **desc)
Definition: nvenc.c:133
int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void(*func)(void *, void *, int))
Feed data from an AVFifoBuffer to a user-supplied callback.
Definition: fifo.c:107
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1503
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:86
int rc_max_rate
maximum bitrate
Definition: avcodec.h:2387
static int nvenc_copy_frame(NV_ENC_LOCK_INPUT_BUFFER *in, const AVFrame *frame)
Definition: nvenc.c:1058
#define FFMAX(a, b)
Definition: common.h:64
#define fail()
Definition: checkasm.h:80
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1352
#define BITSTREAM_BUFFER_SIZE
Definition: nvenc.c:63
int rc_buffer_size
decoder bitstream buffer size
Definition: avcodec.h:2364
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
Definition: rational.c:35
static int nvenc_check_codec_support(AVCodecContext *avctx)
Definition: nvenc.c:223
int async_depth
Definition: nvenc.h:162
int refs
number of reference frames
Definition: avcodec.h:2071
int profile
Definition: nvenc.h:156
const char * name
Definition: qsvenc.c:44
int bit_rate
the average bitrate
Definition: avcodec.h:1473
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:201
PCUINIT cu_init
Definition: nvenc.h:80
NV_ENC_OUTPUT_PTR out
Definition: nvenc.h:57
#define FFMIN(a, b)
Definition: common.h:66
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:142
av_cold int ff_nvenc_encode_init(AVCodecContext *avctx)
Definition: nvenc.c:1006
int ff_nvenc_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet)
Definition: nvenc.c:1379
int width
picture width / height.
Definition: avcodec.h:1580
PCUCTXDESTROY cu_ctx_destroy
Definition: nvenc.h:87
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames...
Definition: avcodec.h:3102
#define NVENC_CAP
Definition: nvenc.c:62
AVFormatContext * ctx
Definition: movenc.c:48
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:2106
#define EXTRADATA_SIZE
Definition: nvenc.c:926
int ff_alloc_packet(AVPacket *avpkt, int size)
Check AVPacket size and/or allocate data.
Definition: utils.c:1211
static NVENCFrame * get_free_frame(NVENCContext *ctx)
Definition: nvenc.c:1044
int ticks_per_frame
For some codecs, the time base is closer to the field rate than the frame rate.
Definition: avcodec.h:1544
int first_packet_output
Definition: nvenc.h:151
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:52
HW acceleration through CUDA.
Definition: pixfmt.h:228
static void set_constqp(AVCodecContext *avctx, NV_ENC_RC_PARAMS *rc)
Definition: nvenc.c:487
the normal 2^n-1 "JPEG" YUV ranges
Definition: pixfmt.h:365
static int nvenc_print_error(void *log_ctx, NVENCSTATUS err, const char *error_string)
Definition: nvenc.c:148
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:191
This structure describes the bitrate properties of an encoded bitstream.
Definition: avcodec.h:1140
NULL
Definition: eval.c:55
static int width
Definition: utils.c:156
#define AV_LOG_INFO
Standard information.
Definition: log.h:135
Libavcodec external API header.
NV_ENC_INITIALIZE_PARAMS params
Definition: nvenc.h:126
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:158
main external API structure.
Definition: avcodec.h:1409
static int nvenc_setup_surfaces(AVCodecContext *avctx)
Definition: nvenc.c:894
uint8_t * data
The data buffer.
Definition: buffer.h:89
int qmin
minimum quantizer
Definition: avcodec.h:2330
static int nvenc_upload_frame(AVCodecContext *avctx, const AVFrame *frame, NVENCFrame *nvenc_frame)
Definition: nvenc.c:1173
static int nvenc_setup_hevc_config(AVCodecContext *avctx)
Definition: nvenc.c:665
static int nvenc_get_output(AVCodecContext *avctx, AVPacket *pkt)
Definition: nvenc.c:1293
NVENCFrame * frames
Definition: nvenc.h:133
CUcontext cu_context_internal
Definition: nvenc.h:130
int extradata_size
Definition: avcodec.h:1524
#define AVERROR_BUG
Bug detected, please report the issue.
Definition: error.h:60
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
void * CUdeviceptr
Definition: nvenc.h:46
This struct is allocated as AVHWDeviceContext.hwctx.
static int nvenc_check_cap(AVCodecContext *avctx, NV_ENC_CAPS cap)
Definition: nvenc.c:259
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:2120
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:2113
int tier
Definition: nvenc.h:158
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:117
CUdeviceptr ptr
Definition: nvenc.h:138
CUcontext cu_context
Definition: nvenc.h:129
static void nvenc_codec_specific_pic_params(AVCodecContext *avctx, NV_ENC_PIC_PARAMS *params)
Definition: nvenc.c:1230
#define IS_CBR(rc)
Definition: nvenc.c:64
static int nvenc_enqueue_timestamp(AVFifoBuffer *f, int64_t pts)
Definition: nvenc.c:1251
int flags
Definition: nvenc.c:461
static void nvenc_override_rate_control(AVCodecContext *avctx, NV_ENC_RC_PARAMS *rc)
Definition: nvenc.c:520
static int nvenc_find_free_reg_resource(AVCodecContext *avctx)
Definition: nvenc.c:1112
int averr
Definition: nvenc.c:100
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:302
int global_quality
Global quality for codecs which cannot change it per frame.
Definition: avcodec.h:1489
static int64_t pts
Global timestamp for the audio frames.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:146
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
Definition: avcodec.h:784
int height
Definition: gxfenc.c:72
int level
Definition: nvenc.h:157
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition: avcodec.h:1606
int av_fifo_size(AVFifoBuffer *f)
Return the amount of data in bytes in the AVFifoBuffer, that is the amount of data you can read from ...
Definition: fifo.c:52
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:59
#define FF_DISABLE_DEPRECATION_WARNINGS
Definition: internal.h:77
common internal api header.
common internal and external API header
PCUCTXPOPCURRENT cu_ctx_pop_current
Definition: nvenc.h:86
static av_cold void flush(AVCodecContext *avctx)
Flush (reset) the frame ID after seeking.
Definition: alsdec.c:1797
PCUCTXCREATE cu_ctx_create
Definition: nvenc.h:85
NVENCSTATUS(NVENCAPI * PNVENCODEAPICREATEINSTANCE)(NV_ENCODE_API_FUNCTION_LIST *functionList)
Definition: nvenc.h:71
static int output_ready(AVCodecContext *avctx, int flush)
Definition: nvenc.c:1361
Bi-dir predicted.
Definition: avutil.h:262
PCUDEVICEGETCOUNT cu_device_get_count
Definition: nvenc.h:81
attribute_deprecated AVFrame * coded_frame
the picture in the bitstream
Definition: avcodec.h:2797
int den
denominator
Definition: rational.h:45
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:61
AVCPBProperties * ff_add_cpb_side_data(AVCodecContext *avctx)
Add a CPB properties side data to an encoding context.
Definition: utils.c:2754
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding...
Definition: avcodec.h:638
int slices
Number of slices.
Definition: avcodec.h:2143
void * priv_data
Definition: avcodec.h:1451
static int nvenc_set_timestamp(AVCodecContext *avctx, NV_ENC_LOCK_BITSTREAM *params, AVPacket *pkt)
Definition: nvenc.c:1261
void * nvenc
Definition: nvenc.h:78
#define FF_ENABLE_DEPRECATION_WARNINGS
Definition: internal.h:78
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
Definition: fifo.c:25
int top_field_first
If the content is interlaced, is top field displayed first.
Definition: frame.h:268
static av_cold int nvenc_load_libraries(AVCodecContext *avctx)
Definition: nvenc.c:158
int avg_bitrate
Average bitrate of the stream, in bits per second.
Definition: avcodec.h:1155
NV_ENC_CONFIG config
Definition: nvenc.h:127
#define CUDA_LIBNAME
Definition: nvenc.c:29
static void set_lossless(AVCodecContext *avctx, NV_ENC_RC_PARAMS *rc)
Definition: nvenc.c:512
int preset
Definition: nvenc.h:155
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed...
Definition: avcodec.h:1345
static int nvenc_check_device(AVCodecContext *avctx, int idx)
Definition: nvenc.c:318
static void * av_mallocz_array(size_t nmemb, size_t size)
Definition: mem.h:205
int height
Definition: frame.h:179
int rc
Definition: nvenc.h:159
void av_image_copy_plane(uint8_t *dst, int dst_linesize, const uint8_t *src, int src_linesize, int bytewidth, int height)
Copy image plane from src to dst.
Definition: imgutils.c:255
void * CUcontext
Definition: nvenc.h:45
int rc_min_rate
minimum bitrate
Definition: avcodec.h:2394
int mapped
Definition: nvenc.h:140
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:215
AVPixelFormat
Pixel format.
Definition: pixfmt.h:57
AVFifoBuffer * timestamps
Definition: nvenc.h:134
This structure stores compressed data.
Definition: avcodec.h:1323
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:211
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1339
static int nvenc_setup_codec_config(AVCodecContext *avctx)
Definition: nvenc.c:716
for(j=16;j >0;--j)
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:235
Predicted.
Definition: avutil.h:261
enum AVPixelFormat data_pix_fmt
Definition: nvenc.h:146