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