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 
39 #if !NVDECAPI_CHECK_VERSION(9, 0)
40 #define cudaVideoSurfaceFormat_YUV444 2
41 #define cudaVideoSurfaceFormat_YUV444_16Bit 3
42 #endif
43 
44 typedef struct NVDECDecoder {
45  CUvideodecoder decoder;
46 
49  CUcontext cuda_ctx;
50  CUstream stream;
51 
52  CudaFunctions *cudl;
53  CuvidFunctions *cvdl;
54 
56 } NVDECDecoder;
57 
58 typedef struct NVDECFramePool {
59  unsigned int dpb_size;
60  unsigned int nb_allocated;
62 
63 #define CHECK_CU(x) FF_CUDA_CHECK_DL(logctx, decoder->cudl, x)
64 
65 static int map_avcodec_id(enum AVCodecID id)
66 {
67  switch (id) {
68 #if CONFIG_AV1_NVDEC_HWACCEL
69  case AV_CODEC_ID_AV1: return cudaVideoCodec_AV1;
70 #endif
71  case AV_CODEC_ID_H264: return cudaVideoCodec_H264;
72  case AV_CODEC_ID_HEVC: return cudaVideoCodec_HEVC;
73  case AV_CODEC_ID_MJPEG: return cudaVideoCodec_JPEG;
74  case AV_CODEC_ID_MPEG1VIDEO: return cudaVideoCodec_MPEG1;
75  case AV_CODEC_ID_MPEG2VIDEO: return cudaVideoCodec_MPEG2;
76  case AV_CODEC_ID_MPEG4: return cudaVideoCodec_MPEG4;
77  case AV_CODEC_ID_VC1: return cudaVideoCodec_VC1;
78  case AV_CODEC_ID_VP8: return cudaVideoCodec_VP8;
79  case AV_CODEC_ID_VP9: return cudaVideoCodec_VP9;
80  case AV_CODEC_ID_WMV3: return cudaVideoCodec_VC1;
81  }
82  return -1;
83 }
84 
86 {
87  int shift_h = 0, shift_v = 0;
88 
90  return cudaVideoChromaFormat_Monochrome;
91 
92  av_pix_fmt_get_chroma_sub_sample(pix_fmt, &shift_h, &shift_v);
93 
94  if (shift_h == 1 && shift_v == 1)
95  return cudaVideoChromaFormat_420;
96  else if (shift_h == 1 && shift_v == 0)
97  return cudaVideoChromaFormat_422;
98  else if (shift_h == 0 && shift_v == 0)
99  return cudaVideoChromaFormat_444;
100 
101  return -1;
102 }
103 
105  CUVIDDECODECREATEINFO *params, void *logctx)
106 {
107  int ret;
108  CUVIDDECODECAPS caps = { 0 };
109 
110  caps.eCodecType = params->CodecType;
111  caps.eChromaFormat = params->ChromaFormat;
112  caps.nBitDepthMinus8 = params->bitDepthMinus8;
113 
114  if (!decoder->cvdl->cuvidGetDecoderCaps) {
115  av_log(logctx, AV_LOG_WARNING, "Used Nvidia driver is too old to perform a capability check.\n");
116  av_log(logctx, AV_LOG_WARNING, "The minimum required version is "
117 #if defined(_WIN32) || defined(__CYGWIN__)
118  "378.66"
119 #else
120  "378.13"
121 #endif
122  ". Continuing blind.\n");
123  return 0;
124  }
125 
126  ret = CHECK_CU(decoder->cvdl->cuvidGetDecoderCaps(&caps));
127  if (ret < 0)
128  return ret;
129 
130  av_log(logctx, AV_LOG_VERBOSE, "NVDEC capabilities:\n");
131  av_log(logctx, AV_LOG_VERBOSE, "format supported: %s, max_mb_count: %d\n",
132  caps.bIsSupported ? "yes" : "no", caps.nMaxMBCount);
133  av_log(logctx, AV_LOG_VERBOSE, "min_width: %d, max_width: %d\n",
134  caps.nMinWidth, caps.nMaxWidth);
135  av_log(logctx, AV_LOG_VERBOSE, "min_height: %d, max_height: %d\n",
136  caps.nMinHeight, caps.nMaxHeight);
137 
138  if (!caps.bIsSupported) {
139  av_log(logctx, AV_LOG_ERROR, "Hardware is lacking required capabilities\n");
140  return AVERROR(EINVAL);
141  }
142 
143  if (params->ulWidth > caps.nMaxWidth || params->ulWidth < caps.nMinWidth) {
144  av_log(logctx, AV_LOG_ERROR, "Video width %d not within range from %d to %d\n",
145  (int)params->ulWidth, caps.nMinWidth, caps.nMaxWidth);
146  return AVERROR(EINVAL);
147  }
148 
149  if (params->ulHeight > caps.nMaxHeight || params->ulHeight < caps.nMinHeight) {
150  av_log(logctx, AV_LOG_ERROR, "Video height %d not within range from %d to %d\n",
151  (int)params->ulHeight, caps.nMinHeight, caps.nMaxHeight);
152  return AVERROR(EINVAL);
153  }
154 
155  if ((params->ulWidth * params->ulHeight) / 256 > caps.nMaxMBCount) {
156  av_log(logctx, AV_LOG_ERROR, "Video macroblock count %d exceeds maximum of %d\n",
157  (int)(params->ulWidth * params->ulHeight) / 256, caps.nMaxMBCount);
158  return AVERROR(EINVAL);
159  }
160 
161  return 0;
162 }
163 
164 static void nvdec_decoder_free(void *opaque, uint8_t *data)
165 {
167 
168  if (decoder->decoder) {
169  void *logctx = decoder->hw_device_ref->data;
170  CUcontext dummy;
171  CHECK_CU(decoder->cudl->cuCtxPushCurrent(decoder->cuda_ctx));
172  CHECK_CU(decoder->cvdl->cuvidDestroyDecoder(decoder->decoder));
173  CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy));
174  }
175 
176  av_buffer_unref(&decoder->real_hw_frames_ref);
177  av_buffer_unref(&decoder->hw_device_ref);
178 
179  cuvid_free_functions(&decoder->cvdl);
180 
181  av_freep(&decoder);
182 }
183 
184 static int nvdec_decoder_create(AVBufferRef **out, AVBufferRef *hw_device_ref,
185  CUVIDDECODECREATEINFO *params, void *logctx)
186 {
188  AVCUDADeviceContext *device_hwctx = hw_device_ctx->hwctx;
189 
190  AVBufferRef *decoder_ref;
192 
193  CUcontext dummy;
194  int ret;
195 
196  decoder = av_mallocz(sizeof(*decoder));
197  if (!decoder)
198  return AVERROR(ENOMEM);
199 
200  decoder_ref = av_buffer_create((uint8_t*)decoder, sizeof(*decoder),
202  if (!decoder_ref) {
203  av_freep(&decoder);
204  return AVERROR(ENOMEM);
205  }
206 
207  decoder->hw_device_ref = av_buffer_ref(hw_device_ref);
208  if (!decoder->hw_device_ref) {
209  ret = AVERROR(ENOMEM);
210  goto fail;
211  }
212  decoder->cuda_ctx = device_hwctx->cuda_ctx;
213  decoder->cudl = device_hwctx->internal->cuda_dl;
214  decoder->stream = device_hwctx->stream;
215 
216  ret = cuvid_load_functions(&decoder->cvdl, logctx);
217  if (ret < 0) {
218  av_log(logctx, AV_LOG_ERROR, "Failed loading nvcuvid.\n");
219  goto fail;
220  }
221 
222  ret = CHECK_CU(decoder->cudl->cuCtxPushCurrent(decoder->cuda_ctx));
223  if (ret < 0)
224  goto fail;
225 
226  ret = nvdec_test_capabilities(decoder, params, logctx);
227  if (ret < 0) {
228  CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy));
229  goto fail;
230  }
231 
232  ret = CHECK_CU(decoder->cvdl->cuvidCreateDecoder(&decoder->decoder, params));
233 
234  CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy));
235 
236  if (ret < 0) {
237  goto fail;
238  }
239 
240  *out = decoder_ref;
241 
242  return 0;
243 fail:
244  av_buffer_unref(&decoder_ref);
245  return ret;
246 }
247 
248 static AVBufferRef *nvdec_decoder_frame_alloc(void *opaque, size_t size)
249 {
250  NVDECFramePool *pool = opaque;
251  AVBufferRef *ret;
252 
253  if (pool->nb_allocated >= pool->dpb_size)
254  return NULL;
255 
256  ret = av_buffer_alloc(sizeof(unsigned int));
257  if (!ret)
258  return NULL;
259 
260  *(unsigned int*)ret->data = pool->nb_allocated++;
261 
262  return ret;
263 }
264 
266 {
268 
269  av_freep(&ctx->bitstream);
270  av_freep(&ctx->bitstream_internal);
271  ctx->bitstream_len = 0;
272  ctx->bitstream_allocated = 0;
273 
274  av_freep(&ctx->slice_offsets);
275  ctx->nb_slices = 0;
276  ctx->slice_offsets_allocated = 0;
277 
278  av_buffer_unref(&ctx->decoder_ref);
279  av_buffer_pool_uninit(&ctx->decoder_pool);
280 
281  return 0;
282 }
283 
285 {
286  av_buffer_pool_uninit(&ctx->pool);
287 }
288 
290 {
291  return av_buffer_create(NULL, 0, NULL, NULL, 0);
292 }
293 
294 static int nvdec_init_hwframes(AVCodecContext *avctx, AVBufferRef **out_frames_ref, int dummy)
295 {
296  AVHWFramesContext *frames_ctx;
297  int ret;
298 
300  avctx->hw_device_ctx,
301  avctx->hwaccel->pix_fmt,
302  out_frames_ref);
303  if (ret < 0)
304  return ret;
305 
306  frames_ctx = (AVHWFramesContext*)(*out_frames_ref)->data;
307 
308  if (dummy) {
309  // Copied from ff_decode_get_hw_frames_ctx for compatibility
310  frames_ctx->initial_pool_size += 3;
311 
312  frames_ctx->free = nvdec_free_dummy;
313  frames_ctx->pool = av_buffer_pool_init(0, nvdec_alloc_dummy);
314 
315  if (!frames_ctx->pool) {
316  av_buffer_unref(out_frames_ref);
317  return AVERROR(ENOMEM);
318  }
319  } else {
320  // This is normally not used to actually allocate frames from
321  frames_ctx->initial_pool_size = 0;
322  }
323 
324  ret = av_hwframe_ctx_init(*out_frames_ref);
325  if (ret < 0) {
326  av_buffer_unref(out_frames_ref);
327  return ret;
328  }
329 
330  return 0;
331 }
332 
334 {
336 
338  AVBufferRef *real_hw_frames_ref;
339  NVDECFramePool *pool;
340  AVHWFramesContext *frames_ctx;
341  const AVPixFmtDescriptor *sw_desc;
342 
343  CUVIDDECODECREATEINFO params = { 0 };
344 
345  cudaVideoSurfaceFormat output_format;
346  int cuvid_codec_type, cuvid_chroma_format, chroma_444;
347  int ret = 0;
348 
349  int unsafe_output = !!(avctx->hwaccel_flags & AV_HWACCEL_FLAG_UNSAFE_OUTPUT);
350 
351  sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
352  if (!sw_desc)
353  return AVERROR_BUG;
354 
355  cuvid_codec_type = map_avcodec_id(avctx->codec_id);
356  if (cuvid_codec_type < 0) {
357  av_log(avctx, AV_LOG_ERROR, "Unsupported codec ID\n");
358  return AVERROR_BUG;
359  }
360 
361  cuvid_chroma_format = map_chroma_format(avctx->sw_pix_fmt);
362  if (cuvid_chroma_format < 0) {
363  av_log(avctx, AV_LOG_ERROR, "Unsupported chroma format\n");
364  return AVERROR(ENOSYS);
365  }
366  chroma_444 = ctx->supports_444 && cuvid_chroma_format == cudaVideoChromaFormat_444;
367 
368  if (!avctx->hw_frames_ctx) {
369  ret = nvdec_init_hwframes(avctx, &avctx->hw_frames_ctx, 1);
370  if (ret < 0)
371  return ret;
372 
373  ret = nvdec_init_hwframes(avctx, &real_hw_frames_ref, 0);
374  if (ret < 0)
375  return ret;
376  } else {
377  real_hw_frames_ref = av_buffer_ref(avctx->hw_frames_ctx);
378  if (!real_hw_frames_ref)
379  return AVERROR(ENOMEM);
380  }
381 
382  switch (sw_desc->comp[0].depth) {
383  case 8:
384  output_format = chroma_444 ? cudaVideoSurfaceFormat_YUV444 :
385  cudaVideoSurfaceFormat_NV12;
386  break;
387  case 10:
388  case 12:
389  output_format = chroma_444 ? cudaVideoSurfaceFormat_YUV444_16Bit :
390  cudaVideoSurfaceFormat_P016;
391  break;
392  default:
393  av_log(avctx, AV_LOG_ERROR, "Unsupported bit depth\n");
394  av_buffer_unref(&real_hw_frames_ref);
395  return AVERROR(ENOSYS);
396  }
397 
398  frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
399 
400  params.ulWidth = avctx->coded_width;
401  params.ulHeight = avctx->coded_height;
402  params.ulTargetWidth = avctx->coded_width;
403  params.ulTargetHeight = avctx->coded_height;
404  params.bitDepthMinus8 = sw_desc->comp[0].depth - 8;
405  params.OutputFormat = output_format;
406  params.CodecType = cuvid_codec_type;
407  params.ChromaFormat = cuvid_chroma_format;
408  params.ulNumDecodeSurfaces = frames_ctx->initial_pool_size;
409  params.ulNumOutputSurfaces = unsafe_output ? frames_ctx->initial_pool_size : 1;
410 
411  ret = nvdec_decoder_create(&ctx->decoder_ref, frames_ctx->device_ref, &params, avctx);
412  if (ret < 0) {
413  if (params.ulNumDecodeSurfaces > 32) {
414  av_log(avctx, AV_LOG_WARNING, "Using more than 32 (%d) decode surfaces might cause nvdec to fail.\n",
415  (int)params.ulNumDecodeSurfaces);
416  av_log(avctx, AV_LOG_WARNING, "Try lowering the amount of threads. Using %d right now.\n",
417  avctx->thread_count);
418  }
419  av_buffer_unref(&real_hw_frames_ref);
420  return ret;
421  }
422 
423  decoder = (NVDECDecoder*)ctx->decoder_ref->data;
424  decoder->unsafe_output = unsafe_output;
425  decoder->real_hw_frames_ref = real_hw_frames_ref;
426  real_hw_frames_ref = NULL;
427 
428  pool = av_mallocz(sizeof(*pool));
429  if (!pool) {
430  ret = AVERROR(ENOMEM);
431  goto fail;
432  }
433  pool->dpb_size = frames_ctx->initial_pool_size;
434 
435  ctx->decoder_pool = av_buffer_pool_init2(sizeof(int), pool,
437  if (!ctx->decoder_pool) {
438  ret = AVERROR(ENOMEM);
439  goto fail;
440  }
441 
442  return 0;
443 fail:
444  ff_nvdec_decode_uninit(avctx);
445  return ret;
446 }
447 
448 static void nvdec_fdd_priv_free(void *priv)
449 {
450  NVDECFrame *cf = priv;
451 
452  if (!cf)
453  return;
454 
455  av_buffer_unref(&cf->idx_ref);
458 
459  av_freep(&priv);
460 }
461 
462 static void nvdec_unmap_mapped_frame(void *opaque, uint8_t *data)
463 {
464  NVDECFrame *unmap_data = (NVDECFrame*)data;
466  void *logctx = decoder->hw_device_ref->data;
467  CUdeviceptr devptr = (CUdeviceptr)opaque;
468  int ret;
469  CUcontext dummy;
470 
471  ret = CHECK_CU(decoder->cudl->cuCtxPushCurrent(decoder->cuda_ctx));
472  if (ret < 0)
473  goto finish;
474 
475  CHECK_CU(decoder->cvdl->cuvidUnmapVideoFrame(decoder->decoder, devptr));
476 
477  CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy));
478 
479 finish:
480  av_buffer_unref(&unmap_data->idx_ref);
481  av_buffer_unref(&unmap_data->decoder_ref);
482  av_buffer_unref(&unmap_data->ref_idx_ref);
483  av_free(unmap_data);
484 }
485 
486 static int nvdec_retrieve_data(void *logctx, AVFrame *frame)
487 {
488  FrameDecodeData *fdd = (FrameDecodeData*)frame->private_ref->data;
489  NVDECFrame *cf = (NVDECFrame*)fdd->hwaccel_priv;
490  NVDECDecoder *decoder = (NVDECDecoder*)cf->decoder_ref->data;
491 
492  AVHWFramesContext *hwctx = (AVHWFramesContext *)frame->hw_frames_ctx->data;
493 
494  CUVIDPROCPARAMS vpp = { 0 };
495  NVDECFrame *unmap_data = NULL;
496 
497  CUcontext dummy;
498  CUdeviceptr devptr;
499 
500  unsigned int pitch, i;
501  unsigned int offset = 0;
502  int shift_h = 0, shift_v = 0;
503  int ret = 0;
504 
505  vpp.progressive_frame = 1;
506  vpp.output_stream = decoder->stream;
507 
508  ret = CHECK_CU(decoder->cudl->cuCtxPushCurrent(decoder->cuda_ctx));
509  if (ret < 0)
510  return ret;
511 
512  ret = CHECK_CU(decoder->cvdl->cuvidMapVideoFrame(decoder->decoder,
513  cf->idx, &devptr,
514  &pitch, &vpp));
515  if (ret < 0)
516  goto finish;
517 
518  unmap_data = av_mallocz(sizeof(*unmap_data));
519  if (!unmap_data) {
520  ret = AVERROR(ENOMEM);
521  goto copy_fail;
522  }
523 
524  frame->buf[1] = av_buffer_create((uint8_t *)unmap_data, sizeof(*unmap_data),
525  nvdec_unmap_mapped_frame, (void*)devptr,
527  if (!frame->buf[1]) {
528  ret = AVERROR(ENOMEM);
529  goto copy_fail;
530  }
531 
532  ret = av_buffer_replace(&frame->hw_frames_ctx, decoder->real_hw_frames_ref);
533  if (ret < 0)
534  goto copy_fail;
535 
536  unmap_data->idx = cf->idx;
537  if (!(unmap_data->idx_ref = av_buffer_ref(cf->idx_ref)) ||
538  !(unmap_data->decoder_ref = av_buffer_ref(cf->decoder_ref))) {
539  ret = AVERROR(ENOMEM);
540  goto copy_fail;
541  }
542 
543  av_pix_fmt_get_chroma_sub_sample(hwctx->sw_format, &shift_h, &shift_v);
544  for (i = 0; frame->linesize[i]; i++) {
545  frame->data[i] = (uint8_t*)(devptr + offset);
546  frame->linesize[i] = pitch;
547  offset += pitch * (frame->height >> (i ? shift_v : 0));
548  }
549 
550  goto finish;
551 
552 copy_fail:
553  if (!frame->buf[1]) {
554  CHECK_CU(decoder->cvdl->cuvidUnmapVideoFrame(decoder->decoder, devptr));
555  av_freep(&unmap_data);
556  } else {
557  av_buffer_unref(&frame->buf[1]);
558  }
559 
560 finish:
561  CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy));
562 
563  if (ret < 0 || decoder->unsafe_output)
564  return ret;
565 
567 }
568 
570 {
572  FrameDecodeData *fdd = (FrameDecodeData*)frame->private_ref->data;
573  NVDECFrame *cf = NULL;
574  int ret;
575 
576  ctx->bitstream_len = 0;
577  ctx->nb_slices = 0;
578 
579  if (fdd->hwaccel_priv)
580  return 0;
581 
582  cf = av_mallocz(sizeof(*cf));
583  if (!cf)
584  return AVERROR(ENOMEM);
585 
586  cf->decoder_ref = av_buffer_ref(ctx->decoder_ref);
587  if (!cf->decoder_ref) {
588  ret = AVERROR(ENOMEM);
589  goto fail;
590  }
591 
592  cf->idx_ref = av_buffer_pool_get(ctx->decoder_pool);
593  if (!cf->idx_ref) {
594  av_log(avctx, AV_LOG_ERROR, "No decoder surfaces left\n");
595  ret = AVERROR(ENOMEM);
596  goto fail;
597  }
598  cf->ref_idx = cf->idx = *(unsigned int*)cf->idx_ref->data;
599 
600  fdd->hwaccel_priv = cf;
603 
604  return 0;
605 fail:
607  return ret;
608 
609 }
610 
612 {
614  FrameDecodeData *fdd = (FrameDecodeData*)frame->private_ref->data;
615  NVDECFrame *cf;
616  int ret;
617 
618  ret = ff_nvdec_start_frame(avctx, frame);
619  if (ret < 0)
620  return ret;
621 
622  cf = fdd->hwaccel_priv;
623 
624  if (has_sep_ref) {
625  if (!cf->ref_idx_ref) {
626  cf->ref_idx_ref = av_buffer_pool_get(ctx->decoder_pool);
627  if (!cf->ref_idx_ref) {
628  av_log(avctx, AV_LOG_ERROR, "No decoder surfaces left\n");
629  ret = AVERROR(ENOMEM);
630  goto fail;
631  }
632  }
633  cf->ref_idx = *(unsigned int*)cf->ref_idx_ref->data;
634  } else {
635  av_buffer_unref(&cf->ref_idx_ref);
636  cf->ref_idx = cf->idx;
637  }
638 
639  return 0;
640 fail:
642  return ret;
643 }
644 
646 {
648  NVDECDecoder *decoder = (NVDECDecoder*)ctx->decoder_ref->data;
649  void *logctx = avctx;
650  CUVIDPICPARAMS *pp = &ctx->pic_params;
651 
652  CUcontext dummy;
653 
654  int ret = 0;
655 
656  pp->nBitstreamDataLen = ctx->bitstream_len;
657  pp->pBitstreamData = ctx->bitstream;
658  pp->nNumSlices = ctx->nb_slices;
659  pp->pSliceDataOffsets = ctx->slice_offsets;
660 
661  ret = CHECK_CU(decoder->cudl->cuCtxPushCurrent(decoder->cuda_ctx));
662  if (ret < 0)
663  return ret;
664 
665  ret = CHECK_CU(decoder->cvdl->cuvidDecodePicture(decoder->decoder, &ctx->pic_params));
666  if (ret < 0)
667  goto finish;
668 
669 finish:
670  CHECK_CU(decoder->cudl->cuCtxPopCurrent(&dummy));
671 
672  return ret;
673 }
674 
676 {
678  int ret = ff_nvdec_end_frame(avctx);
679  ctx->bitstream = NULL;
680  return ret;
681 }
682 
684  uint32_t size)
685 {
687  void *tmp;
688 
689  tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated,
690  (ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets));
691  if (!tmp)
692  return AVERROR(ENOMEM);
693  ctx->slice_offsets = tmp;
694 
695  if (!ctx->bitstream)
696  ctx->bitstream = (uint8_t*)buffer;
697 
698  ctx->slice_offsets[ctx->nb_slices] = buffer - ctx->bitstream;
699  ctx->bitstream_len += size;
700  ctx->nb_slices++;
701 
702  return 0;
703 }
704 
706  AVBufferRef *hw_frames_ctx,
707  int dpb_size,
708  int supports_444)
709 {
710  AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data;
711  const AVPixFmtDescriptor *sw_desc;
712  int cuvid_codec_type, cuvid_chroma_format, chroma_444;
713 
714  sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
715  if (!sw_desc)
716  return AVERROR_BUG;
717 
718  cuvid_codec_type = map_avcodec_id(avctx->codec_id);
719  if (cuvid_codec_type < 0) {
720  av_log(avctx, AV_LOG_ERROR, "Unsupported codec ID\n");
721  return AVERROR_BUG;
722  }
723 
724  cuvid_chroma_format = map_chroma_format(avctx->sw_pix_fmt);
725  if (cuvid_chroma_format < 0) {
726  av_log(avctx, AV_LOG_VERBOSE, "Unsupported chroma format\n");
727  return AVERROR(EINVAL);
728  }
729  chroma_444 = supports_444 && cuvid_chroma_format == cudaVideoChromaFormat_444;
730 
731  frames_ctx->format = AV_PIX_FMT_CUDA;
732  frames_ctx->width = (avctx->coded_width + 1) & ~1;
733  frames_ctx->height = (avctx->coded_height + 1) & ~1;
734  /*
735  * We add two extra frames to the pool to account for deinterlacing filters
736  * holding onto their frames.
737  */
738  frames_ctx->initial_pool_size = dpb_size + 2;
739 
740  switch (sw_desc->comp[0].depth) {
741  case 8:
742  frames_ctx->sw_format = chroma_444 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_NV12;
743  break;
744  case 10:
745  frames_ctx->sw_format = chroma_444 ? AV_PIX_FMT_YUV444P16 : AV_PIX_FMT_P010;
746  break;
747  case 12:
748  frames_ctx->sw_format = chroma_444 ? AV_PIX_FMT_YUV444P16 : AV_PIX_FMT_P016;
749  break;
750  default:
751  return AVERROR(EINVAL);
752  }
753 
754  return 0;
755 }
756 
758 {
759  FrameDecodeData *fdd;
760  NVDECFrame *cf;
761 
762  if (!frame || !frame->private_ref)
763  return -1;
764 
765  fdd = (FrameDecodeData*)frame->private_ref->data;
766  cf = (NVDECFrame*)fdd->hwaccel_priv;
767  if (!cf)
768  return -1;
769 
770  return cf->ref_idx;
771 }
AVCodecContext::hwaccel
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition: avcodec.h:1405
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:280
nvdec_decoder_create
static int nvdec_decoder_create(AVBufferRef **out, AVBufferRef *hw_device_ref, CUVIDDECODECREATEINFO *params, void *logctx)
Definition: nvdec.c:184
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:253
AVPixelFormat
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
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:65
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:2888
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:85
NVDECFramePool
Definition: nvdec.c:58
AVHWFramesContext::format
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:209
NVDECDecoder::stream
CUstream stream
Definition: nvdec.c:50
ff_nvdec_get_ref_idx
int ff_nvdec_get_ref_idx(AVFrame *frame)
Definition: nvdec.c:757
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:34
av_hwframe_ctx_init
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:334
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:330
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:541
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:170
AVComponentDescriptor::depth
int depth
Number of bits in the component.
Definition: pixdesc.h:57
NVDECDecoder::unsafe_output
int unsafe_output
Definition: nvdec.c:55
data
const char data[16]
Definition: mxf.c:146
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:53
NVDECDecoder::decoder
CUvideodecoder decoder
Definition: nvdec.c:45
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:229
NVDECDecoder::cvdl
CuvidFunctions * cvdl
Definition: nvdec.c:53
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2928
decoder
static const chunk_decoder decoder[8]
Definition: dfa.c:331
finish
static void finish(void)
Definition: movenc.c:342
ff_nvdec_start_frame
int ff_nvdec_start_frame(AVCodecContext *avctx, AVFrame *frame)
Definition: nvdec.c:569
NVDECFrame::ref_idx
unsigned int ref_idx
Definition: nvdec.h:46
fail
#define fail()
Definition: checkasm.h:134
AVCodecContext::thread_count
int thread_count
thread count is used to decide how many independent tasks should be passed to execute()
Definition: avcodec.h:1502
dummy
int dummy
Definition: motion.c:65
av_buffer_pool_init2
AVBufferPool * av_buffer_pool_init2(size_t size, void *opaque, AVBufferRef *(*alloc)(void *opaque, size_t size), void(*pool_free)(void *opaque))
Allocate and initialize a buffer pool with a more complex allocator.
Definition: buffer.c:259
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:2916
AVCodecContext::coded_height
int coded_height
Definition: avcodec.h:613
AVHWDeviceContext
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:61
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:40
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:2276
AVHWFramesContext::height
int height
Definition: hwcontext.h:229
av_buffer_pool_get
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
Definition: buffer.c:384
AVHWFramesContext::pool
AVBufferPool * pool
A pool from which the frames are allocated by av_hwframe_get_buffer().
Definition: hwcontext.h:190
ff_nvdec_start_frame_sep_ref
int ff_nvdec_start_frame_sep_ref(AVCodecContext *avctx, AVFrame *frame, int has_sep_ref)
Definition: nvdec.c:611
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
AV_PIX_FMT_YUV444P16
#define AV_PIX_FMT_YUV444P16
Definition: pixfmt.h:472
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
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
nvdec_decoder_free
static void nvdec_decoder_free(void *opaque, uint8_t *data)
Definition: nvdec.c:164
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
AVCodecContext::codec_id
enum AVCodecID codec_id
Definition: avcodec.h:436
NVDECDecoder::cudl
CudaFunctions * cudl
Definition: nvdec.c:52
dpb_size
int dpb_size
Definition: h264_levels.c:107
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:675
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:222
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:283
ff_nvdec_decode_init
int ff_nvdec_decode_init(AVCodecContext *avctx)
Definition: nvdec.c:333
AVHWFramesContext::device_ref
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:141
NVDECDecoder::hw_device_ref
AVBufferRef * hw_device_ref
Definition: nvdec.c:47
AVCodecContext::internal
struct AVCodecInternal * internal
Private context used for internal data.
Definition: avcodec.h:461
av_buffer_pool_uninit
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
Definition: buffer.c:322
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:41
nvdec_alloc_dummy
static AVBufferRef * nvdec_alloc_dummy(size_t size)
Definition: nvdec.c:289
CHECK_CU
#define CHECK_CU(x)
Definition: nvdec.c:63
NVDECDecoder::real_hw_frames_ref
AVBufferRef * real_hw_frames_ref
Definition: nvdec.c:48
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:45
AVCodecInternal::hwaccel_priv_data
void * hwaccel_priv_data
hwaccel-specific private data
Definition: internal.h:137
size
int size
Definition: twinvq_data.h:10344
nvdec_decoder_frame_alloc
static AVBufferRef * nvdec_decoder_frame_alloc(void *opaque, size_t size)
Definition: nvdec.c:248
nvdec_test_capabilities
static int nvdec_test_capabilities(NVDECDecoder *decoder, CUVIDDECODECREATEINFO *params, void *logctx)
Definition: nvdec.c:104
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
av_buffer_alloc
AVBufferRef * av_buffer_alloc(size_t size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:77
nvdec_free_dummy
static void nvdec_free_dummy(struct AVHWFramesContext *ctx)
Definition: nvdec.c:284
ff_nvdec_decode_uninit
int ff_nvdec_decode_uninit(AVCodecContext *avctx)
Definition: nvdec.c:265
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:59
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
hw_device_ctx
static AVBufferRef * hw_device_ctx
Definition: hw_decode.c:44
NVDECDecoder::cuda_ctx
CUcontext cuda_ctx
Definition: nvdec.c:49
nvdec_fdd_priv_free
static void nvdec_fdd_priv_free(void *priv)
Definition: nvdec.c:448
ff_nvdec_end_frame
int ff_nvdec_end_frame(AVCodecContext *avctx)
Definition: nvdec.c:645
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:1937
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:1928
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:44
AV_PIX_FMT_P016
#define AV_PIX_FMT_P016
Definition: pixfmt.h:510
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:1887
avcodec.h
nvdec_retrieve_data
static int nvdec_retrieve_data(void *logctx, AVFrame *frame)
Definition: nvdec.c:486
AVHWFramesContext
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:124
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:1049
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:89
frame
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
Definition: filter_design.txt:264
cuda_check.h
NVDECFramePool::dpb_size
unsigned int dpb_size
Definition: nvdec.c:59
nvdec_init_hwframes
static int nvdec_init_hwframes(AVCodecContext *avctx, AVBufferRef **out_frames_ref, int dummy)
Definition: nvdec.c:294
NVDECFramePool::nb_allocated
unsigned int nb_allocated
Definition: nvdec.c:60
AVCodecContext
main external API structure.
Definition: avcodec.h:426
ff_nvdec_simple_decode_slice
int ff_nvdec_simple_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)
Definition: nvdec.c:683
nvdec_unmap_mapped_frame
static void nvdec_unmap_mapped_frame(void *opaque, uint8_t *data)
Definition: nvdec.c:462
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:705
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:71
NVDECFrame::idx_ref
AVBufferRef * idx_ref
Definition: nvdec.h:47
AV_PIX_FMT_P010
#define AV_PIX_FMT_P010
Definition: pixfmt.h:508
AVCodecContext::coded_width
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:613
AVHWFramesContext::initial_pool_size
int initial_pool_size
Initial size of the frame pool.
Definition: hwcontext.h:199
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:52
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
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:1757
NVDECContext
Definition: nvdec.h:52
NVDECFrame::ref_idx_ref
AVBufferRef * ref_idx_ref
Definition: nvdec.h:48
NVDECFrame::decoder_ref
AVBufferRef * decoder_ref
Definition: nvdec.h:49
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:2103