FFmpeg
nvdec.c
Go to the documentation of this file.
1 /*
2  * HW decode acceleration through NVDEC
3  *
4  * Copyright (c) 2016 Anton Khirnov
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 #include "config.h"
24 #include "config_components.h"
25 
26 #include "libavutil/common.h"
27 #include "libavutil/error.h"
28 #include "libavutil/hwcontext.h"
30 #include "libavutil/cuda_check.h"
31 #include "libavutil/pixdesc.h"
32 #include "libavutil/pixfmt.h"
33 
34 #include "avcodec.h"
35 #include "decode.h"
36 #include "nvdec.h"
37 #include "internal.h"
38 #include "refstruct.h"
39 
40 #if !NVDECAPI_CHECK_VERSION(9, 0)
41 #define cudaVideoSurfaceFormat_YUV444 2
42 #define cudaVideoSurfaceFormat_YUV444_16Bit 3
43 #endif
44 
45 typedef struct NVDECDecoder {
46  CUvideodecoder decoder;
47 
50  CUcontext cuda_ctx;
51  CUstream stream;
52 
53  CudaFunctions *cudl;
54  CuvidFunctions *cvdl;
55 
57 } NVDECDecoder;
58 
59 typedef struct NVDECFramePool {
60  unsigned int dpb_size;
61  unsigned int nb_allocated;
63 
64 #define CHECK_CU(x) FF_CUDA_CHECK_DL(logctx, decoder->cudl, x)
65 
66 static int map_avcodec_id(enum AVCodecID id)
67 {
68  switch (id) {
69 #if CONFIG_AV1_NVDEC_HWACCEL
70  case AV_CODEC_ID_AV1: return cudaVideoCodec_AV1;
71 #endif
72  case AV_CODEC_ID_H264: return cudaVideoCodec_H264;
73  case AV_CODEC_ID_HEVC: return cudaVideoCodec_HEVC;
74  case AV_CODEC_ID_MJPEG: return cudaVideoCodec_JPEG;
75  case AV_CODEC_ID_MPEG1VIDEO: return cudaVideoCodec_MPEG1;
76  case AV_CODEC_ID_MPEG2VIDEO: return cudaVideoCodec_MPEG2;
77  case AV_CODEC_ID_MPEG4: return cudaVideoCodec_MPEG4;
78  case AV_CODEC_ID_VC1: return cudaVideoCodec_VC1;
79  case AV_CODEC_ID_VP8: return cudaVideoCodec_VP8;
80  case AV_CODEC_ID_VP9: return cudaVideoCodec_VP9;
81  case AV_CODEC_ID_WMV3: return cudaVideoCodec_VC1;
82  }
83  return -1;
84 }
85 
87 {
88  int shift_h = 0, shift_v = 0;
89 
91  return cudaVideoChromaFormat_Monochrome;
92 
93  av_pix_fmt_get_chroma_sub_sample(pix_fmt, &shift_h, &shift_v);
94 
95  if (shift_h == 1 && shift_v == 1)
96  return cudaVideoChromaFormat_420;
97  else if (shift_h == 1 && shift_v == 0)
98  return cudaVideoChromaFormat_422;
99  else if (shift_h == 0 && shift_v == 0)
100  return cudaVideoChromaFormat_444;
101 
102  return -1;
103 }
104 
106  CUVIDDECODECREATEINFO *params, void *logctx)
107 {
108  int ret;
109  CUVIDDECODECAPS caps = { 0 };
110 
111  caps.eCodecType = params->CodecType;
112  caps.eChromaFormat = params->ChromaFormat;
113  caps.nBitDepthMinus8 = params->bitDepthMinus8;
114 
115  if (!decoder->cvdl->cuvidGetDecoderCaps) {
116  av_log(logctx, AV_LOG_WARNING, "Used Nvidia driver is too old to perform a capability check.\n");
117  av_log(logctx, AV_LOG_WARNING, "The minimum required version is "
118 #if defined(_WIN32) || defined(__CYGWIN__)
119  "378.66"
120 #else
121  "378.13"
122 #endif
123  ". Continuing blind.\n");
124  return 0;
125  }
126 
127  ret = CHECK_CU(decoder->cvdl->cuvidGetDecoderCaps(&caps));
128  if (ret < 0)
129  return ret;
130 
131  av_log(logctx, AV_LOG_VERBOSE, "NVDEC capabilities:\n");
132  av_log(logctx, AV_LOG_VERBOSE, "format supported: %s, max_mb_count: %d\n",
133  caps.bIsSupported ? "yes" : "no", caps.nMaxMBCount);
134  av_log(logctx, AV_LOG_VERBOSE, "min_width: %d, max_width: %d\n",
135  caps.nMinWidth, caps.nMaxWidth);
136  av_log(logctx, AV_LOG_VERBOSE, "min_height: %d, max_height: %d\n",
137  caps.nMinHeight, caps.nMaxHeight);
138 
139  if (!caps.bIsSupported) {
140  av_log(logctx, AV_LOG_ERROR, "Hardware is lacking required capabilities\n");
141  return AVERROR(EINVAL);
142  }
143 
144  if (params->ulWidth > caps.nMaxWidth || params->ulWidth < caps.nMinWidth) {
145  av_log(logctx, AV_LOG_ERROR, "Video width %d not within range from %d to %d\n",
146  (int)params->ulWidth, caps.nMinWidth, caps.nMaxWidth);
147  return AVERROR(EINVAL);
148  }
149 
150  if (params->ulHeight > caps.nMaxHeight || params->ulHeight < caps.nMinHeight) {
151  av_log(logctx, AV_LOG_ERROR, "Video height %d not within range from %d to %d\n",
152  (int)params->ulHeight, caps.nMinHeight, caps.nMaxHeight);
153  return AVERROR(EINVAL);
154  }
155 
156  if ((params->ulWidth * params->ulHeight) / 256 > caps.nMaxMBCount) {
157  av_log(logctx, AV_LOG_ERROR, "Video macroblock count %d exceeds maximum of %d\n",
158  (int)(params->ulWidth * params->ulHeight) / 256, caps.nMaxMBCount);
159  return AVERROR(EINVAL);
160  }
161 
162  return 0;
163 }
164 
165 static void nvdec_decoder_free(FFRefStructOpaque unused, void *obj)
166 {
167  NVDECDecoder *decoder = obj;
168 
169  if (decoder->decoder) {
170  void *logctx = decoder->hw_device_ref->data;
171  CUcontext dummy;
172  CHECK_CU(decoder->cudl->cuCtxPushCurrent(decoder->cuda_ctx));
173  CHECK_CU(decoder->cvdl->cuvidDestroyDecoder(decoder->decoder));
174  CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy));
175  }
176 
177  av_buffer_unref(&decoder->real_hw_frames_ref);
178  av_buffer_unref(&decoder->hw_device_ref);
179 
180  cuvid_free_functions(&decoder->cvdl);
181 }
182 
183 static int nvdec_decoder_create(NVDECDecoder **out, AVBufferRef *hw_device_ref,
184  CUVIDDECODECREATEINFO *params, void *logctx)
185 {
187  AVCUDADeviceContext *device_hwctx = hw_device_ctx->hwctx;
188 
190 
191  CUcontext dummy;
192  int ret;
193 
194  decoder = ff_refstruct_alloc_ext(sizeof(*decoder), 0,
196  if (!decoder)
197  return AVERROR(ENOMEM);
198 
199  decoder->hw_device_ref = av_buffer_ref(hw_device_ref);
200  if (!decoder->hw_device_ref) {
201  ret = AVERROR(ENOMEM);
202  goto fail;
203  }
204  decoder->cuda_ctx = device_hwctx->cuda_ctx;
205  decoder->cudl = device_hwctx->internal->cuda_dl;
206  decoder->stream = device_hwctx->stream;
207 
208  ret = cuvid_load_functions(&decoder->cvdl, logctx);
209  if (ret < 0) {
210  av_log(logctx, AV_LOG_ERROR, "Failed loading nvcuvid.\n");
211  goto fail;
212  }
213 
214  ret = CHECK_CU(decoder->cudl->cuCtxPushCurrent(decoder->cuda_ctx));
215  if (ret < 0)
216  goto fail;
217 
218  ret = nvdec_test_capabilities(decoder, params, logctx);
219  if (ret < 0) {
220  CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy));
221  goto fail;
222  }
223 
224  ret = CHECK_CU(decoder->cvdl->cuvidCreateDecoder(&decoder->decoder, params));
225 
226  CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy));
227 
228  if (ret < 0) {
229  goto fail;
230  }
231 
232  *out = decoder;
233 
234  return 0;
235 fail:
237  return ret;
238 }
239 
240 static int nvdec_decoder_frame_init(FFRefStructOpaque opaque, void *obj)
241 {
242  NVDECFramePool *pool = opaque.nc;
243  unsigned int *intp = obj;
244 
245  if (pool->nb_allocated >= pool->dpb_size)
246  return AVERROR(ENOMEM);
247 
248  *intp = pool->nb_allocated++;
249 
250  return 0;
251 }
252 
254 {
255  av_free(opaque.nc);
256 }
257 
259 {
261 
262  av_freep(&ctx->bitstream_internal);
263  ctx->bitstream = NULL;
264  ctx->bitstream_len = 0;
265  ctx->bitstream_allocated = 0;
266 
267  av_freep(&ctx->slice_offsets);
268  ctx->nb_slices = 0;
269  ctx->slice_offsets_allocated = 0;
270 
271  ff_refstruct_unref(&ctx->decoder);
272  ff_refstruct_pool_uninit(&ctx->decoder_pool);
273 
274  return 0;
275 }
276 
278 {
279  av_buffer_pool_uninit(&ctx->pool);
280 }
281 
283 {
284  return av_buffer_create(NULL, 0, NULL, NULL, 0);
285 }
286 
287 static int nvdec_init_hwframes(AVCodecContext *avctx, AVBufferRef **out_frames_ref, int dummy)
288 {
289  AVHWFramesContext *frames_ctx;
290  int ret;
291 
293  avctx->hw_device_ctx,
294  avctx->hwaccel->pix_fmt,
295  out_frames_ref);
296  if (ret < 0)
297  return ret;
298 
299  frames_ctx = (AVHWFramesContext*)(*out_frames_ref)->data;
300 
301  if (dummy) {
302  // Copied from ff_decode_get_hw_frames_ctx for compatibility
303  frames_ctx->initial_pool_size += 3;
304 
305  frames_ctx->free = nvdec_free_dummy;
306  frames_ctx->pool = av_buffer_pool_init(0, nvdec_alloc_dummy);
307 
308  if (!frames_ctx->pool) {
309  av_buffer_unref(out_frames_ref);
310  return AVERROR(ENOMEM);
311  }
312  } else {
313  // This is normally not used to actually allocate frames from
314  frames_ctx->initial_pool_size = 0;
315  }
316 
317  ret = av_hwframe_ctx_init(*out_frames_ref);
318  if (ret < 0) {
319  av_buffer_unref(out_frames_ref);
320  return ret;
321  }
322 
323  return 0;
324 }
325 
327 {
329 
331  AVBufferRef *real_hw_frames_ref;
332  NVDECFramePool *pool;
333  AVHWFramesContext *frames_ctx;
334  const AVPixFmtDescriptor *sw_desc;
335 
336  CUVIDDECODECREATEINFO params = { 0 };
337 
338  cudaVideoSurfaceFormat output_format;
339  int cuvid_codec_type, cuvid_chroma_format, chroma_444;
340  int ret = 0;
341 
342  int unsafe_output = !!(avctx->hwaccel_flags & AV_HWACCEL_FLAG_UNSAFE_OUTPUT);
343 
344  sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
345  if (!sw_desc)
346  return AVERROR_BUG;
347 
348  cuvid_codec_type = map_avcodec_id(avctx->codec_id);
349  if (cuvid_codec_type < 0) {
350  av_log(avctx, AV_LOG_ERROR, "Unsupported codec ID\n");
351  return AVERROR_BUG;
352  }
353 
354  cuvid_chroma_format = map_chroma_format(avctx->sw_pix_fmt);
355  if (cuvid_chroma_format < 0) {
356  av_log(avctx, AV_LOG_ERROR, "Unsupported chroma format\n");
357  return AVERROR(ENOSYS);
358  }
359  chroma_444 = ctx->supports_444 && cuvid_chroma_format == cudaVideoChromaFormat_444;
360 
361  if (!avctx->hw_frames_ctx) {
362  ret = nvdec_init_hwframes(avctx, &avctx->hw_frames_ctx, 1);
363  if (ret < 0)
364  return ret;
365 
366  ret = nvdec_init_hwframes(avctx, &real_hw_frames_ref, 0);
367  if (ret < 0)
368  return ret;
369  } else {
370  real_hw_frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
371  if (!real_hw_frames_ref)
372  return AVERROR(ENOMEM);
373  }
374 
375  switch (sw_desc->comp[0].depth) {
376  case 8:
378  cudaVideoSurfaceFormat_NV12;
379  break;
380  case 10:
381  case 12:
383  cudaVideoSurfaceFormat_P016;
384  break;
385  default:
386  av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth\n");
387  av_buffer_unref(&real_hw_frames_ref);
388  return AVERROR(ENOSYS);
389  }
390 
391  frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
392 
393  params.ulWidth = avctx->coded_width;
394  params.ulHeight = avctx->coded_height;
395  params.ulTargetWidth = avctx->coded_width;
396  params.ulTargetHeight = avctx->coded_height;
397  params.bitDepthMinus8 = sw_desc->comp[0].depth - 8;
398  params.OutputFormat = output_format;
399  params.CodecType = cuvid_codec_type;
400  params.ChromaFormat = cuvid_chroma_format;
401  params.ulNumDecodeSurfaces = frames_ctx->initial_pool_size;
402  params.ulNumOutputSurfaces = unsafe_output ? frames_ctx->initial_pool_size : 1;
403 
404  ret = nvdec_decoder_create(&ctx->decoder, frames_ctx->device_ref, &params, avctx);
405  if (ret < 0) {
406  if (params.ulNumDecodeSurfaces > 32) {
407  av_log(avctx, AV_LOG_WARNING, "Using more than 32 (%d) decode surfaces might cause nvdec to fail.\n",
408  (int)params.ulNumDecodeSurfaces);
409  av_log(avctx, AV_LOG_WARNING, "Try lowering the amount of threads. Using %d right now.\n",
410  avctx->thread_count);
411  }
412  av_buffer_unref(&real_hw_frames_ref);
413  return ret;
414  }
415 
416  decoder = ctx->decoder;
417  decoder->unsafe_output = unsafe_output;
418  decoder->real_hw_frames_ref = real_hw_frames_ref;
419  real_hw_frames_ref = NULL;
420 
421  pool = av_mallocz(sizeof(*pool));
422  if (!pool) {
423  ret = AVERROR(ENOMEM);
424  goto fail;
425  }
426  pool->dpb_size = frames_ctx->initial_pool_size;
427 
428  ctx->decoder_pool = ff_refstruct_pool_alloc_ext(sizeof(unsigned int), 0, pool,
431  if (!ctx->decoder_pool) {
432  ret = AVERROR(ENOMEM);
433  goto fail;
434  }
435 
436  return 0;
437 fail:
438  ff_nvdec_decode_uninit(avctx);
439  return ret;
440 }
441 
442 static void nvdec_fdd_priv_free(void *priv)
443 {
444  NVDECFrame *cf = priv;
445 
446  if (!cf)
447  return;
448 
452 
453  av_freep(&priv);
454 }
455 
456 static void nvdec_unmap_mapped_frame(void *opaque, uint8_t *data)
457 {
458  NVDECFrame *unmap_data = (NVDECFrame*)data;
459  NVDECDecoder *decoder = unmap_data->decoder;
460  void *logctx = decoder->hw_device_ref->data;
461  CUdeviceptr devptr = (CUdeviceptr)opaque;
462  int ret;
463  CUcontext dummy;
464 
465  ret = CHECK_CU(decoder->cudl->cuCtxPushCurrent(decoder->cuda_ctx));
466  if (ret < 0)
467  goto finish;
468 
469  CHECK_CU(decoder->cvdl->cuvidUnmapVideoFrame(decoder->decoder, devptr));
470 
471  CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy));
472 
473 finish:
474  ff_refstruct_unref(&unmap_data->idx_ref);
475  ff_refstruct_unref(&unmap_data->ref_idx_ref);
476  ff_refstruct_unref(&unmap_data->decoder);
477  av_free(unmap_data);
478 }
479 
480 static int nvdec_retrieve_data(void *logctx, AVFrame *frame)
481 {
483  NVDECFrame *cf = (NVDECFrame*)fdd->hwaccel_priv;
484  NVDECDecoder *decoder = cf->decoder;
485 
487 
488  CUVIDPROCPARAMS vpp = { 0 };
489  NVDECFrame *unmap_data = NULL;
490 
491  CUcontext dummy;
492  CUdeviceptr devptr;
493 
494  unsigned int pitch, i;
495  unsigned int offset = 0;
496  int shift_h = 0, shift_v = 0;
497  int ret = 0;
498 
499  vpp.progressive_frame = 1;
500  vpp.output_stream = decoder->stream;
501 
502  ret = CHECK_CU(decoder->cudl->cuCtxPushCurrent(decoder->cuda_ctx));
503  if (ret < 0)
504  return ret;
505 
506  ret = CHECK_CU(decoder->cvdl->cuvidMapVideoFrame(decoder->decoder,
507  cf->idx, &devptr,
508  &pitch, &vpp));
509  if (ret < 0)
510  goto finish;
511 
512  unmap_data = av_mallocz(sizeof(*unmap_data));
513  if (!unmap_data) {
514  ret = AVERROR(ENOMEM);
515  goto copy_fail;
516  }
517 
518  frame->buf[1] = av_buffer_create((uint8_t *)unmap_data, sizeof(*unmap_data),
519  nvdec_unmap_mapped_frame, (void*)devptr,
521  if (!frame->buf[1]) {
522  ret = AVERROR(ENOMEM);
523  goto copy_fail;
524  }
525 
526  ret = av_buffer_replace(&frame->hw_frames_ctx, decoder->real_hw_frames_ref);
527  if (ret < 0)
528  goto copy_fail;
529 
530  unmap_data->idx = cf->idx;
531  unmap_data->idx_ref = ff_refstruct_ref(cf->idx_ref);
532  unmap_data->decoder = ff_refstruct_ref(cf->decoder);
533 
534  av_pix_fmt_get_chroma_sub_sample(hwctx->sw_format, &shift_h, &shift_v);
535  for (i = 0; frame->linesize[i]; i++) {
536  frame->data[i] = (uint8_t*)(devptr + offset);
537  frame->linesize[i] = pitch;
538  offset += pitch * (frame->height >> (i ? shift_v : 0));
539  }
540 
541  goto finish;
542 
543 copy_fail:
544  if (!frame->buf[1]) {
545  CHECK_CU(decoder->cvdl->cuvidUnmapVideoFrame(decoder->decoder, devptr));
546  av_freep(&unmap_data);
547  } else {
548  av_buffer_unref(&frame->buf[1]);
549  }
550 
551 finish:
552  CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy));
553 
554  if (ret < 0 || decoder->unsafe_output)
555  return ret;
556 
558 }
559 
561 {
564  NVDECFrame *cf = NULL;
565  int ret;
566 
567  ctx->bitstream_len = 0;
568  ctx->nb_slices = 0;
569 
570  if (fdd->hwaccel_priv)
571  return 0;
572 
573  cf = av_mallocz(sizeof(*cf));
574  if (!cf)
575  return AVERROR(ENOMEM);
576 
577  cf->decoder = ff_refstruct_ref(ctx->decoder);
578 
579  cf->idx_ref = ff_refstruct_pool_get(ctx->decoder_pool);
580  if (!cf->idx_ref) {
581  av_log(avctx, AV_LOG_ERROR, "No decoder surfaces left\n");
582  ret = AVERROR(ENOMEM);
583  goto fail;
584  }
585  cf->ref_idx = cf->idx = *cf->idx_ref;
586 
587  fdd->hwaccel_priv = cf;
590 
591  return 0;
592 fail:
594  return ret;
595 
596 }
597 
599 {
602  NVDECFrame *cf;
603  int ret;
604 
605  ret = ff_nvdec_start_frame(avctx, frame);
606  if (ret < 0)
607  return ret;
608 
609  cf = fdd->hwaccel_priv;
610 
611  if (has_sep_ref) {
612  if (!cf->ref_idx_ref) {
613  cf->ref_idx_ref = ff_refstruct_pool_get(ctx->decoder_pool);
614  if (!cf->ref_idx_ref) {
615  av_log(avctx, AV_LOG_ERROR, "No decoder surfaces left\n");
616  ret = AVERROR(ENOMEM);
617  goto fail;
618  }
619  }
620  cf->ref_idx = *cf->ref_idx_ref;
621  } else {
622  ff_refstruct_unref(&cf->ref_idx_ref);
623  cf->ref_idx = cf->idx;
624  }
625 
626  return 0;
627 fail:
629  return ret;
630 }
631 
633 {
635  NVDECDecoder *decoder = ctx->decoder;
636  void *logctx = avctx;
637  CUVIDPICPARAMS *pp = &ctx->pic_params;
638 
639  CUcontext dummy;
640 
641  int ret = 0;
642 
643  pp->nBitstreamDataLen = ctx->bitstream_len;
644  pp->pBitstreamData = ctx->bitstream;
645  pp->nNumSlices = ctx->nb_slices;
646  pp->pSliceDataOffsets = ctx->slice_offsets;
647 
648  ret = CHECK_CU(decoder->cudl->cuCtxPushCurrent(decoder->cuda_ctx));
649  if (ret < 0)
650  return ret;
651 
652  ret = CHECK_CU(decoder->cvdl->cuvidDecodePicture(decoder->decoder, &ctx->pic_params));
653  if (ret < 0)
654  goto finish;
655 
656 finish:
657  CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy));
658 
659  return ret;
660 }
661 
663 {
665  int ret = ff_nvdec_end_frame(avctx);
666  ctx->bitstream = NULL;
667  ctx->bitstream_len = 0;
668  ctx->nb_slices = 0;
669  return ret;
670 }
671 
673  uint32_t size)
674 {
676  void *tmp;
677 
678  tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated,
679  (ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets));
680  if (!tmp)
681  return AVERROR(ENOMEM);
682  ctx->slice_offsets = tmp;
683 
684  if (!ctx->bitstream)
685  ctx->bitstream = buffer;
686 
687  ctx->slice_offsets[ctx->nb_slices] = buffer - ctx->bitstream;
688  ctx->bitstream_len += size;
689  ctx->nb_slices++;
690 
691  return 0;
692 }
693 
695  AVBufferRef *hw_frames_ctx,
696  int dpb_size,
697  int supports_444)
698 {
699  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data;
700  const AVPixFmtDescriptor *sw_desc;
701  int cuvid_codec_type, cuvid_chroma_format, chroma_444;
702 
703  sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
704  if (!sw_desc)
705  return AVERROR_BUG;
706 
707  cuvid_codec_type = map_avcodec_id(avctx->codec_id);
708  if (cuvid_codec_type < 0) {
709  av_log(avctx, AV_LOG_ERROR, "Unsupported codec ID\n");
710  return AVERROR_BUG;
711  }
712 
713  cuvid_chroma_format = map_chroma_format(avctx->sw_pix_fmt);
714  if (cuvid_chroma_format < 0) {
715  av_log(avctx, AV_LOG_VERBOSE, "Unsupported chroma format\n");
716  return AVERROR(EINVAL);
717  }
718  chroma_444 = supports_444 && cuvid_chroma_format == cudaVideoChromaFormat_444;
719 
720  frames_ctx->format = AV_PIX_FMT_CUDA;
721  frames_ctx->width = (avctx->coded_width + 1) & ~1;
722  frames_ctx->height = (avctx->coded_height + 1) & ~1;
723  /*
724  * We add two extra frames to the pool to account for deinterlacing filters
725  * holding onto their frames.
726  */
727  frames_ctx->initial_pool_size = dpb_size + 2;
728 
729  switch (sw_desc->comp[0].depth) {
730  case 8:
731  frames_ctx->sw_format = chroma_444 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_NV12;
732  break;
733  case 10:
734  frames_ctx->sw_format = chroma_444 ? AV_PIX_FMT_YUV444P16 : AV_PIX_FMT_P010;
735  break;
736  case 12:
737  frames_ctx->sw_format = chroma_444 ? AV_PIX_FMT_YUV444P16 : AV_PIX_FMT_P016;
738  break;
739  default:
740  return AVERROR(EINVAL);
741  }
742 
743  return 0;
744 }
745 
747 {
748  FrameDecodeData *fdd;
749  NVDECFrame *cf;
750 
751  if (!frame || !frame->private_ref)
752  return -1;
753 
755  cf = (NVDECFrame*)fdd->hwaccel_priv;
756  if (!cf)
757  return -1;
758 
759  return cf->ref_idx;
760 }
AVCodecContext::hwaccel
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition: avcodec.h:1427
av_buffer_pool_init
AVBufferPool * av_buffer_pool_init(size_t size, AVBufferRef *(*alloc)(size_t size))
Allocate and initialize a buffer pool.
Definition: buffer.c:283
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:186
AV_PIX_FMT_CUDA
@ AV_PIX_FMT_CUDA
HW acceleration through CUDA.
Definition: pixfmt.h:260
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:71
ff_refstruct_ref
void * ff_refstruct_ref(void *obj)
Create a new reference to an object managed via this API, i.e.
Definition: refstruct.c:140
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
map_avcodec_id
static int map_avcodec_id(enum AVCodecID id)
Definition: nvdec.c:66
hwcontext_cuda_internal.h
out
FILE * out
Definition: movenc.c:54
av_pix_fmt_desc_get
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2962
AVBufferRef::data
uint8_t * data
The data buffer.
Definition: buffer.h:90
map_chroma_format
static int map_chroma_format(enum AVPixelFormat pix_fmt)
Definition: nvdec.c:86
NVDECFramePool
Definition: nvdec.c:59
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:197
NVDECDecoder::stream
CUstream stream
Definition: nvdec.c:51
ff_refstruct_alloc_ext
static void * ff_refstruct_alloc_ext(size_t size, unsigned flags, void *opaque, void(*free_cb)(FFRefStructOpaque opaque, void *obj))
A wrapper around ff_refstruct_alloc_ext_c() for the common case of a non-const qualified opaque.
Definition: refstruct.h:94
ff_nvdec_get_ref_idx
int ff_nvdec_get_ref_idx(AVFrame *frame)
Definition: nvdec.c:746
AV_CODEC_ID_MPEG4
@ AV_CODEC_ID_MPEG4
Definition: codec_id.h:64
FrameDecodeData
This struct stores per-frame lavc-internal data and is attached to it via private_ref.
Definition: decode.h:33
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:322
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:344
tmp
static uint8_t tmp[11]
Definition: aes_ctr.c:28
av_frame_make_writable
int av_frame_make_writable(AVFrame *frame)
Ensure that the frame data is writable, avoiding data copy if possible.
Definition: frame.c:632
pixdesc.h
internal.h
AVHWFramesContext::free
void(* free)(struct AVHWFramesContext *ctx)
This field may be set by the caller before calling av_hwframe_ctx_init().
Definition: hwcontext.h:158
AVComponentDescriptor::depth
int depth
Number of bits in the component.
Definition: pixdesc.h:57
NVDECDecoder::unsafe_output
int unsafe_output
Definition: nvdec.c:56
data
const char data[16]
Definition: mxf.c:148
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
FrameDecodeData::hwaccel_priv_free
void(* hwaccel_priv_free)(void *priv)
Definition: decode.h:52
FFRefStructOpaque
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition: refstruct.h:58
NVDECDecoder::decoder
CUvideodecoder decoder
Definition: nvdec.c:46
av_buffer_ref
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:103
AVHWFramesContext::width
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:217
AVFrame::buf
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:557
nvdec_decoder_frame_init
static int nvdec_decoder_frame_init(FFRefStructOpaque opaque, void *obj)
Definition: nvdec.c:240
NVDECDecoder::cvdl
CuvidFunctions * cvdl
Definition: nvdec.c:54
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:365
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3002
decoder
static const chunk_decoder decoder[8]
Definition: dfa.c:331
finish
static void finish(void)
Definition: movenc.c:342
NVDECFrame::idx_ref
unsigned int * idx_ref
RefStruct reference.
Definition: nvdec.h:47
ff_nvdec_start_frame
int ff_nvdec_start_frame(AVCodecContext *avctx, AVFrame *frame)
Definition: nvdec.c:560
NVDECFrame::ref_idx
unsigned int ref_idx
Definition: nvdec.h:46
fail
#define fail()
Definition: checkasm.h:179
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1582
ff_refstruct_pool_uninit
static void ff_refstruct_pool_uninit(FFRefStructPool **poolp)
Mark the pool as being available for freeing.
Definition: refstruct.h:292
dummy
int dummy
Definition: motion.c:66
av_pix_fmt_get_chroma_sub_sample
int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
Utility function to access log2_chroma_w log2_chroma_h from the pixel format AVPixFmtDescriptor.
Definition: pixdesc.c:2990
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:633
refstruct.h
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:60
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
cudaVideoSurfaceFormat_YUV444
#define cudaVideoSurfaceFormat_YUV444
Definition: nvdec.c:41
AV_HWACCEL_FLAG_UNSAFE_OUTPUT
#define AV_HWACCEL_FLAG_UNSAFE_OUTPUT
Some hardware decoders (namely nvdec) can either output direct decoder surfaces, or make an on-device...
Definition: avcodec.h:2174
AVHWFramesContext::height
int height
Definition: hwcontext.h:217
AVHWFramesContext::pool
AVBufferPool * pool
A pool from which the frames are allocated by av_hwframe_get_buffer().
Definition: hwcontext.h:178
ff_nvdec_start_frame_sep_ref
int ff_nvdec_start_frame_sep_ref(AVCodecContext *avctx, AVFrame *frame, int has_sep_ref)
Definition: nvdec.c:598
av_fast_realloc
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition: mem.c:495
nvdec_decoder_frame_pool_free
static void nvdec_decoder_frame_pool_free(FFRefStructOpaque opaque)
Definition: nvdec.c:253
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:491
AV_BUFFER_FLAG_READONLY
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
Definition: buffer.h:114
nvdec_decoder_free
static void nvdec_decoder_free(FFRefStructOpaque unused, void *obj)
Definition: nvdec.c:165
pix_fmt
static enum AVPixelFormat pix_fmt
Definition: demux_decode.c:41
AV_CODEC_ID_VP9
@ AV_CODEC_ID_VP9
Definition: codec_id.h:220
NVDECFrame
Definition: nvdec.h:44
ctx
AVFormatContext * ctx
Definition: movenc.c:48
decode.h
AV_CODEC_ID_H264
@ AV_CODEC_ID_H264
Definition: codec_id.h:79
frame
static AVFrame * frame
Definition: demux_decode.c:54
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:455
NVDECDecoder::cudl
CudaFunctions * cudl
Definition: nvdec.c:53
dpb_size
int dpb_size
Definition: h264_levels.c:111
if
if(ret)
Definition: filter_design.txt:179
AV_CODEC_ID_WMV3
@ AV_CODEC_ID_WMV3
Definition: codec_id.h:123
ff_nvdec_simple_end_frame
int ff_nvdec_simple_end_frame(AVCodecContext *avctx)
Definition: nvdec.c:662
NULL
#define NULL
Definition: coverity.c:32
AVHWFramesContext::sw_format
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:210
av_buffer_unref
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
Definition: buffer.c:139
AV_CODEC_ID_AV1
@ AV_CODEC_ID_AV1
Definition: codec_id.h:280
ff_nvdec_decode_init
int ff_nvdec_decode_init(AVCodecContext *avctx)
Definition: nvdec.c:326
AVHWFramesContext::device_ref
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:126
NVDECDecoder::hw_device_ref
AVBufferRef * hw_device_ref
Definition: nvdec.c:48
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:480
av_buffer_pool_uninit
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
Definition: buffer.c:328
nvdec_decoder_create
static int nvdec_decoder_create(NVDECDecoder **out, AVBufferRef *hw_device_ref, CUVIDDECODECREATEINFO *params, void *logctx)
Definition: nvdec.c:183
AV_CODEC_ID_MPEG1VIDEO
@ AV_CODEC_ID_MPEG1VIDEO
Definition: codec_id.h:53
av_buffer_create
AVBufferRef * av_buffer_create(uint8_t *data, size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
Definition: buffer.c:55
error.h
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: codec_id.h:49
cudaVideoSurfaceFormat_YUV444_16Bit
#define cudaVideoSurfaceFormat_YUV444_16Bit
Definition: nvdec.c:42
nvdec_alloc_dummy
static AVBufferRef * nvdec_alloc_dummy(size_t size)
Definition: nvdec.c:282
CHECK_CU
#define CHECK_CU(x)
Definition: nvdec.c:64
NVDECDecoder::real_hw_frames_ref
AVBufferRef * real_hw_frames_ref
Definition: nvdec.c:49
FrameDecodeData::post_process
int(* post_process)(void *logctx, AVFrame *frame)
The callback to perform some delayed processing on the frame right before it is returned to the calle...
Definition: decode.h:44
AVCodecInternal::hwaccel_priv_data
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:121
NVDECFrame::ref_idx_ref
unsigned int * ref_idx_ref
RefStruct reference.
Definition: nvdec.h:48
size
int size
Definition: twinvq_data.h:10344
FFRefStructOpaque::nc
void * nc
Definition: refstruct.h:59
nvdec_test_capabilities
static int nvdec_test_capabilities(NVDECDecoder *decoder, CUVIDDECODECREATEINFO *params, void *logctx)
Definition: nvdec.c:105
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
nvdec.h
nvdec_free_dummy
static void nvdec_free_dummy(struct AVHWFramesContext *ctx)
Definition: nvdec.c:277
ff_nvdec_decode_uninit
int ff_nvdec_decode_uninit(AVCodecContext *avctx)
Definition: nvdec.c:258
AVFrame::private_ref
AVBufferRef * private_ref
AVBufferRef for internal use by a single libav* library.
Definition: frame.h:740
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:59
NVDECFrame::decoder
struct NVDECDecoder * decoder
RefStruct reference.
Definition: nvdec.h:49
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
hw_device_ctx
static AVBufferRef * hw_device_ctx
Definition: hw_decode.c:44
NVDECDecoder::cuda_ctx
CUcontext cuda_ctx
Definition: nvdec.c:50
nvdec_fdd_priv_free
static void nvdec_fdd_priv_free(void *priv)
Definition: nvdec.c:442
ff_nvdec_end_frame
int ff_nvdec_end_frame(AVCodecContext *avctx)
Definition: nvdec.c:632
common.h
AVCodecContext::hwaccel_flags
int hwaccel_flags
Bit set of AV_HWACCEL_FLAG_* flags, which affect hardware accelerated decoding (if active).
Definition: avcodec.h:1506
AV_CODEC_ID_HEVC
@ AV_CODEC_ID_HEVC
Definition: codec_id.h:226
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:254
AVCodecContext::hw_device_ctx
AVBufferRef * hw_device_ctx
A reference to the AVHWDeviceContext describing the device which will be used by a hardware encoder/d...
Definition: avcodec.h:1497
AV_CODEC_ID_VC1
@ AV_CODEC_ID_VC1
Definition: codec_id.h:122
av_buffer_replace
int av_buffer_replace(AVBufferRef **pdst, const AVBufferRef *src)
Ensure dst refers to the same data as src.
Definition: buffer.c:233
NVDECDecoder
Definition: nvdec.c:45
AV_PIX_FMT_P016
#define AV_PIX_FMT_P016
Definition: pixfmt.h:530
AVCodecContext::hw_frames_ctx
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
Definition: avcodec.h:1475
avcodec.h
nvdec_retrieve_data
static int nvdec_retrieve_data(void *logctx, AVFrame *frame)
Definition: nvdec.c:480
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:115
AVCUDADeviceContext
This struct is allocated as AVHWDeviceContext.hwctx.
Definition: hwcontext_cuda.h:42
avcodec_get_hw_frames_parameters
int avcodec_get_hw_frames_parameters(AVCodecContext *avctx, AVBufferRef *device_ref, enum AVPixelFormat hw_pix_fmt, AVBufferRef **out_frames_ref)
Create and return a AVHWFramesContext with values adequate for hardware decoding.
Definition: decode.c:1115
ret
ret
Definition: filter_design.txt:187
pixfmt.h
AV_PIX_FMT_NV12
@ AV_PIX_FMT_NV12
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:96
cuda_check.h
NVDECFramePool::dpb_size
unsigned int dpb_size
Definition: nvdec.c:60
nvdec_init_hwframes
static int nvdec_init_hwframes(AVCodecContext *avctx, AVBufferRef **out_frames_ref, int dummy)
Definition: nvdec.c:287
AVFrame::hw_frames_ctx
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame.
Definition: frame.h:695
NVDECFramePool::nb_allocated
unsigned int nb_allocated
Definition: nvdec.c:61
AVCodecContext
main external API structure.
Definition: avcodec.h:445
AVFrame::height
int height
Definition: frame.h:416
ff_nvdec_simple_decode_slice
int ff_nvdec_simple_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: nvdec.c:672
nvdec_unmap_mapped_frame
static void nvdec_unmap_mapped_frame(void *opaque, uint8_t *data)
Definition: nvdec.c:456
buffer
the frame and frame reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFrame structures Several references can point to the same frame buffer
Definition: filter_design.txt:49
ff_nvdec_frame_params
int ff_nvdec_frame_params(AVCodecContext *avctx, AVBufferRef *hw_frames_ctx, int dpb_size, int supports_444)
Definition: nvdec.c:694
ff_refstruct_pool_alloc_ext
static FFRefStructPool * ff_refstruct_pool_alloc_ext(size_t size, unsigned flags, void *opaque, int(*init_cb)(FFRefStructOpaque opaque, void *obj), void(*reset_cb)(FFRefStructOpaque opaque, void *obj), void(*free_entry_cb)(FFRefStructOpaque opaque, void *obj), void(*free_cb)(FFRefStructOpaque opaque))
A wrapper around ff_refstruct_pool_alloc_ext_c() for the common case of a non-const qualified opaque.
Definition: refstruct.h:258
output_format
static char * output_format
Definition: ffprobe.c:149
AVPixFmtDescriptor::comp
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:105
AV_PIX_FMT_YUV444P
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition: pixfmt.h:78
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:528
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:633
AVHWFramesContext::initial_pool_size
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:187
AVBufferRef
A reference to a data buffer.
Definition: buffer.h:82
AVPixFmtDescriptor
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
av_free
#define av_free(p)
Definition: tableprint_vlc.h:33
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
FrameDecodeData::hwaccel_priv
void * hwaccel_priv
Per-frame private data for hwaccels.
Definition: decode.h:51
AV_CODEC_ID_VP8
@ AV_CODEC_ID_VP8
Definition: codec_id.h:192
hwcontext.h
AVERROR_BUG
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:52
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition: frame.h:389
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
AVCodecContext::sw_pix_fmt
enum AVPixelFormat sw_pix_fmt
Nominal unaccelerated pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:664
NVDECContext
Definition: nvdec.h:52
AV_CODEC_ID_MPEG2VIDEO
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition: codec_id.h:54
AVHWAccel::pix_fmt
enum AVPixelFormat pix_fmt
Supported pixel format.
Definition: avcodec.h:2115
ff_refstruct_unref
void ff_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
ff_refstruct_pool_get
void * ff_refstruct_pool_get(FFRefStructPool *pool)
Get an object from the pool, reusing an old one from the pool when available.
Definition: refstruct.c:297