FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
cuvid.c
Go to the documentation of this file.
1 /*
2  * Nvidia CUVID decoder
3  * Copyright (c) 2016 Timo Rothenpieler <timo@rothenpieler.org>
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/buffer.h"
23 #include "libavutil/mathematics.h"
24 #include "libavutil/hwcontext.h"
26 #include "libavutil/fifo.h"
27 #include "libavutil/log.h"
28 
29 #include "avcodec.h"
30 #include "internal.h"
31 
32 #include <nvcuvid.h>
33 
34 #define MAX_FRAME_COUNT 20
35 
36 typedef struct CuvidContext
37 {
38  CUvideodecoder cudecoder;
39  CUvideoparser cuparser;
40 
43 
45 
47 
49 
50  cudaVideoCodec codec_type;
51  cudaVideoChromaFormat chroma_format;
52 } CuvidContext;
53 
54 static int check_cu(AVCodecContext *avctx, CUresult err, const char *func)
55 {
56  const char *err_name;
57  const char *err_string;
58 
59  av_log(avctx, AV_LOG_TRACE, "Calling %s\n", func);
60 
61  if (err == CUDA_SUCCESS)
62  return 0;
63 
64  cuGetErrorName(err, &err_name);
65  cuGetErrorString(err, &err_string);
66 
67  av_log(avctx, AV_LOG_ERROR, "%s failed", func);
68  if (err_name && err_string)
69  av_log(avctx, AV_LOG_ERROR, " -> %s: %s", err_name, err_string);
70  av_log(avctx, AV_LOG_ERROR, "\n");
71 
72  return AVERROR_EXTERNAL;
73 }
74 
75 #define CHECK_CU(x) check_cu(avctx, (x), #x)
76 
77 static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* format)
78 {
79  AVCodecContext *avctx = opaque;
80  CuvidContext *ctx = avctx->priv_data;
81  AVHWFramesContext *hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
82  CUVIDDECODECREATEINFO cuinfo;
83 
84  av_log(avctx, AV_LOG_TRACE, "pfnSequenceCallback\n");
85 
86  ctx->internal_error = 0;
87 
88  avctx->width = format->display_area.right;
89  avctx->height = format->display_area.bottom;
90 
91  ff_set_sar(avctx, av_div_q(
92  (AVRational){ format->display_aspect_ratio.x, format->display_aspect_ratio.y },
93  (AVRational){ avctx->width, avctx->height }));
94 
95  if (!format->progressive_sequence)
97  else
99 
100  if (format->video_signal_description.video_full_range_flag)
101  avctx->color_range = AVCOL_RANGE_JPEG;
102  else
103  avctx->color_range = AVCOL_RANGE_MPEG;
104 
105  avctx->color_primaries = format->video_signal_description.color_primaries;
106  avctx->color_trc = format->video_signal_description.transfer_characteristics;
107  avctx->colorspace = format->video_signal_description.matrix_coefficients;
108 
109  if (format->bitrate)
110  avctx->bit_rate = format->bitrate;
111 
112  if (format->frame_rate.numerator && format->frame_rate.denominator) {
113  avctx->framerate.num = format->frame_rate.numerator;
114  avctx->framerate.den = format->frame_rate.denominator;
115  }
116 
117  if (ctx->cudecoder
118  && avctx->coded_width == format->coded_width
119  && avctx->coded_height == format->coded_height
120  && ctx->chroma_format == format->chroma_format
121  && ctx->codec_type == format->codec)
122  return 1;
123 
124  if (ctx->cudecoder) {
125  av_log(avctx, AV_LOG_ERROR, "re-initializing decoder is not supported\n");
126  ctx->internal_error = AVERROR(EINVAL);
127  return 0;
128  }
129 
130  if (hwframe_ctx->pool) {
131  av_log(avctx, AV_LOG_ERROR, "AVHWFramesContext is already initialized\n");
132  ctx->internal_error = AVERROR(EINVAL);
133  return 0;
134  }
135 
136  avctx->coded_width = format->coded_width;
137  avctx->coded_height = format->coded_height;
138 
139  ctx->chroma_format = format->chroma_format;
140 
141  memset(&cuinfo, 0, sizeof(cuinfo));
142 
143  cuinfo.CodecType = ctx->codec_type = format->codec;
144  cuinfo.ChromaFormat = format->chroma_format;
145  cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12;
146 
147  cuinfo.ulWidth = avctx->coded_width;
148  cuinfo.ulHeight = avctx->coded_height;
149  cuinfo.ulTargetWidth = cuinfo.ulWidth;
150  cuinfo.ulTargetHeight = cuinfo.ulHeight;
151 
152  cuinfo.target_rect.left = 0;
153  cuinfo.target_rect.top = 0;
154  cuinfo.target_rect.right = cuinfo.ulWidth;
155  cuinfo.target_rect.bottom = cuinfo.ulHeight;
156 
157  cuinfo.ulNumDecodeSurfaces = MAX_FRAME_COUNT;
158  cuinfo.ulNumOutputSurfaces = 1;
159  cuinfo.ulCreationFlags = cudaVideoCreate_PreferCUVID;
160 
161  cuinfo.DeinterlaceMode = cudaVideoDeinterlaceMode_Weave;
162 
163  ctx->internal_error = CHECK_CU(cuvidCreateDecoder(&ctx->cudecoder, &cuinfo));
164  if (ctx->internal_error < 0)
165  return 0;
166 
167  hwframe_ctx->format = AV_PIX_FMT_CUDA;
168  hwframe_ctx->sw_format = AV_PIX_FMT_NV12;
169  hwframe_ctx->width = FFALIGN(avctx->coded_width, 32);
170  hwframe_ctx->height = FFALIGN(avctx->coded_height, 32);
171 
172  if ((ctx->internal_error = av_hwframe_ctx_init(ctx->hwframe)) < 0) {
173  av_log(avctx, AV_LOG_ERROR, "av_hwframe_ctx_init failed\n");
174  return 0;
175  }
176 
177  return 1;
178 }
179 
180 static int CUDAAPI cuvid_handle_picture_decode(void *opaque, CUVIDPICPARAMS* picparams)
181 {
182  AVCodecContext *avctx = opaque;
183  CuvidContext *ctx = avctx->priv_data;
184 
185  av_log(avctx, AV_LOG_TRACE, "pfnDecodePicture\n");
186 
187  ctx->internal_error = CHECK_CU(cuvidDecodePicture(ctx->cudecoder, picparams));
188  if (ctx->internal_error < 0)
189  return 0;
190 
191  return 1;
192 }
193 
194 static int CUDAAPI cuvid_handle_picture_display(void *opaque, CUVIDPARSERDISPINFO* dispinfo)
195 {
196  AVCodecContext *avctx = opaque;
197  CuvidContext *ctx = avctx->priv_data;
198 
199  av_log(avctx, AV_LOG_TRACE, "pfnDisplayPicture\n");
200 
201  ctx->internal_error = 0;
202 
203  av_fifo_generic_write(ctx->frame_queue, dispinfo, sizeof(CUVIDPARSERDISPINFO), NULL);
204 
205  return 1;
206 }
207 
208 static int cuvid_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
209 {
210  CuvidContext *ctx = avctx->priv_data;
211  AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)ctx->hwdevice->data;
212  AVCUDADeviceContext *device_hwctx = device_ctx->hwctx;
213  CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx;
214  AVFrame *frame = data;
215  CUVIDSOURCEDATAPACKET cupkt;
216  AVPacket filter_packet = { 0 };
217  AVPacket filtered_packet = { 0 };
218  CUdeviceptr mapped_frame = 0;
219  int ret = 0, eret = 0;
220 
221  if (ctx->bsf && avpkt->size) {
222  if ((ret = av_packet_ref(&filter_packet, avpkt)) < 0) {
223  av_log(avctx, AV_LOG_ERROR, "av_packet_ref failed\n");
224  return ret;
225  }
226 
227  if ((ret = av_bsf_send_packet(ctx->bsf, &filter_packet)) < 0) {
228  av_log(avctx, AV_LOG_ERROR, "av_bsf_send_packet failed\n");
230  return ret;
231  }
232 
233  if ((ret = av_bsf_receive_packet(ctx->bsf, &filtered_packet)) < 0) {
234  av_log(avctx, AV_LOG_ERROR, "av_bsf_receive_packet failed\n");
235  return ret;
236  }
237 
238  avpkt = &filtered_packet;
239  }
240 
241  ret = CHECK_CU(cuCtxPushCurrent(cuda_ctx));
242  if (ret < 0) {
243  av_packet_unref(&filtered_packet);
244  return ret;
245  }
246 
247  memset(&cupkt, 0, sizeof(cupkt));
248 
249  if (avpkt->size) {
250  cupkt.payload_size = avpkt->size;
251  cupkt.payload = avpkt->data;
252 
253  if (avpkt->pts != AV_NOPTS_VALUE) {
254  cupkt.flags = CUVID_PKT_TIMESTAMP;
255  cupkt.timestamp = av_rescale_q(avpkt->pts, avctx->time_base, (AVRational){1, 10000000});
256  }
257  } else {
258  cupkt.flags = CUVID_PKT_ENDOFSTREAM;
259  }
260 
261  ret = CHECK_CU(cuvidParseVideoData(ctx->cuparser, &cupkt));
262 
263  av_packet_unref(&filtered_packet);
264 
265  if (ret < 0) {
266  if (ctx->internal_error)
267  ret = ctx->internal_error;
268  goto error;
269  }
270 
271  if (av_fifo_size(ctx->frame_queue)) {
272  CUVIDPARSERDISPINFO dispinfo;
273  CUVIDPROCPARAMS params;
274  unsigned int pitch = 0;
275  int offset = 0;
276  int i;
277 
278  av_fifo_generic_read(ctx->frame_queue, &dispinfo, sizeof(CUVIDPARSERDISPINFO), NULL);
279 
280  memset(&params, 0, sizeof(params));
281  params.progressive_frame = dispinfo.progressive_frame;
282  params.second_field = 0;
283  params.top_field_first = dispinfo.top_field_first;
284 
285  ret = CHECK_CU(cuvidMapVideoFrame(ctx->cudecoder, dispinfo.picture_index, &mapped_frame, &pitch, &params));
286  if (ret < 0)
287  goto error;
288 
289  if (avctx->pix_fmt == AV_PIX_FMT_CUDA) {
290  ret = av_hwframe_get_buffer(ctx->hwframe, frame, 0);
291  if (ret < 0) {
292  av_log(avctx, AV_LOG_ERROR, "av_hwframe_get_buffer failed\n");
293  goto error;
294  }
295 
296  ret = ff_decode_frame_props(avctx, frame);
297  if (ret < 0) {
298  av_log(avctx, AV_LOG_ERROR, "ff_decode_frame_props failed\n");
299  goto error;
300  }
301 
302  for (i = 0; i < 2; i++) {
303  CUDA_MEMCPY2D cpy = {
304  .srcMemoryType = CU_MEMORYTYPE_DEVICE,
305  .dstMemoryType = CU_MEMORYTYPE_DEVICE,
306  .srcDevice = mapped_frame,
307  .dstDevice = (CUdeviceptr)frame->data[i],
308  .srcPitch = pitch,
309  .dstPitch = frame->linesize[i],
310  .srcY = offset,
311  .WidthInBytes = FFMIN(pitch, frame->linesize[i]),
312  .Height = avctx->coded_height >> (i ? 1 : 0),
313  };
314 
315  ret = CHECK_CU(cuMemcpy2D(&cpy));
316  if (ret < 0)
317  goto error;
318 
319  offset += avctx->coded_height;
320  }
321  } else if (avctx->pix_fmt == AV_PIX_FMT_NV12) {
322  AVFrame *tmp_frame = av_frame_alloc();
323  if (!tmp_frame) {
324  av_log(avctx, AV_LOG_ERROR, "av_frame_alloc failed\n");
325  ret = AVERROR(ENOMEM);
326  goto error;
327  }
328 
329  tmp_frame->format = AV_PIX_FMT_CUDA;
330  tmp_frame->hw_frames_ctx = av_buffer_ref(ctx->hwframe);
331  tmp_frame->data[0] = (uint8_t*)mapped_frame;
332  tmp_frame->linesize[0] = pitch;
333  tmp_frame->data[1] = (uint8_t*)(mapped_frame + avctx->coded_height * pitch);
334  tmp_frame->linesize[1] = pitch;
335  tmp_frame->width = avctx->width;
336  tmp_frame->height = avctx->height;
337 
338  ret = ff_get_buffer(avctx, frame, 0);
339  if (ret < 0) {
340  av_log(avctx, AV_LOG_ERROR, "ff_get_buffer failed\n");
341  av_frame_free(&tmp_frame);
342  goto error;
343  }
344 
345  ret = av_hwframe_transfer_data(frame, tmp_frame, 0);
346  if (ret) {
347  av_log(avctx, AV_LOG_ERROR, "av_hwframe_transfer_data failed\n");
348  av_frame_free(&tmp_frame);
349  goto error;
350  }
351 
352  av_frame_free(&tmp_frame);
353  } else {
354  ret = AVERROR_BUG;
355  goto error;
356  }
357 
358  frame->width = avctx->width;
359  frame->height = avctx->height;
360  frame->pts = av_rescale_q(dispinfo.timestamp, (AVRational){1, 10000000}, avctx->time_base);
361 
362  /* CUVIDs opaque reordering breaks the internal pkt logic.
363  * So set pkt_pts and clear all the other pkt_ fields.
364  */
365  frame->pkt_pts = frame->pts;
369 
370  frame->interlaced_frame = !dispinfo.progressive_frame;
371 
372  if (!dispinfo.progressive_frame)
373  frame->top_field_first = dispinfo.top_field_first;
374 
375  *got_frame = 1;
376  } else {
377  *got_frame = 0;
378  }
379 
380 error:
381  if (mapped_frame)
382  eret = CHECK_CU(cuvidUnmapVideoFrame(ctx->cudecoder, mapped_frame));
383 
384  eret = CHECK_CU(cuCtxPopCurrent(&dummy));
385 
386  if (eret < 0)
387  return eret;
388  else
389  return ret;
390 }
391 
393 {
394  CuvidContext *ctx = avctx->priv_data;
395 
396  av_fifo_freep(&ctx->frame_queue);
397 
398  if (ctx->bsf)
399  av_bsf_free(&ctx->bsf);
400 
401  if (ctx->cuparser)
402  cuvidDestroyVideoParser(ctx->cuparser);
403 
404  if (ctx->cudecoder)
405  cuvidDestroyDecoder(ctx->cudecoder);
406 
407  av_buffer_unref(&ctx->hwframe);
408  av_buffer_unref(&ctx->hwdevice);
409 
410  return 0;
411 }
412 
414 {
415  AVCUDADeviceContext *hwctx = ctx->hwctx;
416  cuCtxDestroy(hwctx->cuda_ctx);
417 }
418 
419 static int cuvid_test_dummy_decoder(AVCodecContext *avctx, CUVIDPARSERPARAMS *cuparseinfo)
420 {
421  CUVIDDECODECREATEINFO cuinfo;
422  CUvideodecoder cudec = 0;
423  int ret = 0;
424 
425  memset(&cuinfo, 0, sizeof(cuinfo));
426 
427  cuinfo.CodecType = cuparseinfo->CodecType;
428  cuinfo.ChromaFormat = cudaVideoChromaFormat_420;
429  cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12;
430 
431  cuinfo.ulWidth = 1280;
432  cuinfo.ulHeight = 720;
433  cuinfo.ulTargetWidth = cuinfo.ulWidth;
434  cuinfo.ulTargetHeight = cuinfo.ulHeight;
435 
436  cuinfo.target_rect.left = 0;
437  cuinfo.target_rect.top = 0;
438  cuinfo.target_rect.right = cuinfo.ulWidth;
439  cuinfo.target_rect.bottom = cuinfo.ulHeight;
440 
441  cuinfo.ulNumDecodeSurfaces = MAX_FRAME_COUNT;
442  cuinfo.ulNumOutputSurfaces = 1;
443  cuinfo.ulCreationFlags = cudaVideoCreate_PreferCUVID;
444 
445  cuinfo.DeinterlaceMode = cudaVideoDeinterlaceMode_Weave;
446 
447  ret = CHECK_CU(cuvidCreateDecoder(&cudec, &cuinfo));
448  if (ret < 0)
449  return ret;
450 
451  ret = CHECK_CU(cuvidDestroyDecoder(cudec));
452  if (ret < 0)
453  return ret;
454 
455  return 0;
456 }
457 
459 {
460  CuvidContext *ctx = avctx->priv_data;
461  AVCUDADeviceContext *device_hwctx;
462  AVHWDeviceContext *device_ctx;
463  AVHWFramesContext *hwframe_ctx;
464  CUVIDPARSERPARAMS cuparseinfo;
465  CUVIDEOFORMATEX cuparse_ext;
466  CUVIDSOURCEDATAPACKET seq_pkt;
467  CUdevice device;
468  CUcontext cuda_ctx = NULL;
470  const AVBitStreamFilter *bsf;
471  int ret = 0;
472 
475  AV_PIX_FMT_NONE };
476 
477  ret = ff_get_format(avctx, pix_fmts);
478  if (ret < 0) {
479  av_log(avctx, AV_LOG_ERROR, "ff_get_format failed: %d\n", ret);
480  return ret;
481  }
482 
483  ctx->frame_queue = av_fifo_alloc(MAX_FRAME_COUNT * sizeof(CUVIDPARSERDISPINFO));
484  if (!ctx->frame_queue) {
485  ret = AVERROR(ENOMEM);
486  goto error;
487  }
488 
489  avctx->pix_fmt = ret;
490 
491  if (avctx->hw_frames_ctx) {
492  ctx->hwframe = av_buffer_ref(avctx->hw_frames_ctx);
493  if (!ctx->hwframe) {
494  ret = AVERROR(ENOMEM);
495  goto error;
496  }
497 
498  hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
499 
500  ctx->hwdevice = av_buffer_ref(hwframe_ctx->device_ref);
501  if (!ctx->hwdevice) {
502  ret = AVERROR(ENOMEM);
503  goto error;
504  }
505 
506  device_ctx = hwframe_ctx->device_ctx;
507  device_hwctx = device_ctx->hwctx;
508  cuda_ctx = device_hwctx->cuda_ctx;
509  } else {
511  if (!ctx->hwdevice) {
512  av_log(avctx, AV_LOG_ERROR, "Error allocating hwdevice\n");
513  ret = AVERROR(ENOMEM);
514  goto error;
515  }
516 
517  ret = CHECK_CU(cuInit(0));
518  if (ret < 0)
519  goto error;
520 
521  ret = CHECK_CU(cuDeviceGet(&device, 0));
522  if (ret < 0)
523  goto error;
524 
525  ret = CHECK_CU(cuCtxCreate(&cuda_ctx, CU_CTX_SCHED_BLOCKING_SYNC, device));
526  if (ret < 0)
527  goto error;
528 
529  device_ctx = (AVHWDeviceContext*)ctx->hwdevice->data;
530  device_ctx->free = cuvid_ctx_free;
531 
532  device_hwctx = device_ctx->hwctx;
533  device_hwctx->cuda_ctx = cuda_ctx;
534 
535  ret = CHECK_CU(cuCtxPopCurrent(&dummy));
536  if (ret < 0)
537  goto error;
538 
539  ret = av_hwdevice_ctx_init(ctx->hwdevice);
540  if (ret < 0) {
541  av_log(avctx, AV_LOG_ERROR, "av_hwdevice_ctx_init failed\n");
542  goto error;
543  }
544 
546  if (!ctx->hwframe) {
547  av_log(avctx, AV_LOG_ERROR, "av_hwframe_ctx_alloc failed\n");
548  ret = AVERROR(ENOMEM);
549  goto error;
550  }
551  }
552 
553  memset(&cuparseinfo, 0, sizeof(cuparseinfo));
554  memset(&cuparse_ext, 0, sizeof(cuparse_ext));
555  memset(&seq_pkt, 0, sizeof(seq_pkt));
556 
557  cuparseinfo.pExtVideoInfo = &cuparse_ext;
558 
559  switch (avctx->codec->id) {
560 #if CONFIG_H264_CUVID_DECODER
561  case AV_CODEC_ID_H264:
562  cuparseinfo.CodecType = cudaVideoCodec_H264;
563  break;
564 #endif
565 #if CONFIG_HEVC_CUVID_DECODER
566  case AV_CODEC_ID_HEVC:
567  cuparseinfo.CodecType = cudaVideoCodec_HEVC;
568  break;
569 #endif
570 #if CONFIG_VP8_CUVID_DECODER
571  case AV_CODEC_ID_VP8:
572  cuparseinfo.CodecType = cudaVideoCodec_VP8;
573  break;
574 #endif
575 #if CONFIG_VP9_CUVID_DECODER
576  case AV_CODEC_ID_VP9:
577  cuparseinfo.CodecType = cudaVideoCodec_VP9;
578  break;
579 #endif
580 #if CONFIG_VC1_CUVID_DECODER
581  case AV_CODEC_ID_VC1:
582  cuparseinfo.CodecType = cudaVideoCodec_VC1;
583  break;
584 #endif
585  default:
586  av_log(avctx, AV_LOG_ERROR, "Invalid CUVID codec!\n");
587  return AVERROR_BUG;
588  }
589 
590  if (avctx->codec->id == AV_CODEC_ID_H264 || avctx->codec->id == AV_CODEC_ID_HEVC) {
591  if (avctx->codec->id == AV_CODEC_ID_H264)
592  bsf = av_bsf_get_by_name("h264_mp4toannexb");
593  else
594  bsf = av_bsf_get_by_name("hevc_mp4toannexb");
595 
596  if (!bsf) {
597  ret = AVERROR_BSF_NOT_FOUND;
598  goto error;
599  }
600  if (ret = av_bsf_alloc(bsf, &ctx->bsf)) {
601  goto error;
602  }
603  if (((ret = avcodec_parameters_from_context(ctx->bsf->par_in, avctx)) < 0) || ((ret = av_bsf_init(ctx->bsf)) < 0)) {
604  av_bsf_free(&ctx->bsf);
605  goto error;
606  }
607 
608  cuparse_ext.format.seqhdr_data_length = ctx->bsf->par_out->extradata_size;
609  memcpy(cuparse_ext.raw_seqhdr_data,
610  ctx->bsf->par_out->extradata,
611  FFMIN(sizeof(cuparse_ext.raw_seqhdr_data), ctx->bsf->par_out->extradata_size));
612  } else if (avctx->extradata_size > 0) {
613  cuparse_ext.format.seqhdr_data_length = avctx->extradata_size;
614  memcpy(cuparse_ext.raw_seqhdr_data,
615  avctx->extradata,
616  FFMIN(sizeof(cuparse_ext.raw_seqhdr_data), avctx->extradata_size));
617  }
618 
619  cuparseinfo.ulMaxNumDecodeSurfaces = MAX_FRAME_COUNT;
620  cuparseinfo.ulMaxDisplayDelay = 4;
621  cuparseinfo.pUserData = avctx;
622  cuparseinfo.pfnSequenceCallback = cuvid_handle_video_sequence;
623  cuparseinfo.pfnDecodePicture = cuvid_handle_picture_decode;
624  cuparseinfo.pfnDisplayPicture = cuvid_handle_picture_display;
625 
626  ret = CHECK_CU(cuCtxPushCurrent(cuda_ctx));
627  if (ret < 0)
628  goto error;
629 
630  ret = cuvid_test_dummy_decoder(avctx, &cuparseinfo);
631  if (ret < 0)
632  goto error;
633 
634  ret = CHECK_CU(cuvidCreateVideoParser(&ctx->cuparser, &cuparseinfo));
635  if (ret < 0)
636  goto error;
637 
638  seq_pkt.payload = cuparse_ext.raw_seqhdr_data;
639  seq_pkt.payload_size = cuparse_ext.format.seqhdr_data_length;
640 
641  if (seq_pkt.payload && seq_pkt.payload_size) {
642  ret = CHECK_CU(cuvidParseVideoData(ctx->cuparser, &seq_pkt));
643  if (ret < 0)
644  goto error;
645  }
646 
647  ret = CHECK_CU(cuCtxPopCurrent(&dummy));
648  if (ret < 0)
649  goto error;
650 
651  return 0;
652 
653 error:
654  cuvid_decode_end(avctx);
655  return ret;
656 }
657 
658 #define DEFINE_CUVID_CODEC(x, X) \
659  AVHWAccel ff_##x##_cuvid_hwaccel = { \
660  .name = #x "_cuvid", \
661  .type = AVMEDIA_TYPE_VIDEO, \
662  .id = AV_CODEC_ID_##X, \
663  .pix_fmt = AV_PIX_FMT_CUDA, \
664  }; \
665  AVCodec ff_##x##_cuvid_decoder = { \
666  .name = #x "_cuvid", \
667  .long_name = NULL_IF_CONFIG_SMALL("Nvidia CUVID " #X " decoder"), \
668  .type = AVMEDIA_TYPE_VIDEO, \
669  .id = AV_CODEC_ID_##X, \
670  .priv_data_size = sizeof(CuvidContext), \
671  .init = cuvid_decode_init, \
672  .close = cuvid_decode_end, \
673  .decode = cuvid_decode_frame, \
674  .capabilities = AV_CODEC_CAP_DELAY, \
675  .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, \
676  AV_PIX_FMT_NV12, \
677  AV_PIX_FMT_NONE }, \
678  };
679 
680 #if CONFIG_HEVC_CUVID_DECODER
681 DEFINE_CUVID_CODEC(hevc, HEVC)
682 #endif
683 
684 #if CONFIG_H264_CUVID_DECODER
685 DEFINE_CUVID_CODEC(h264, H264)
686 #endif
687 
688 #if CONFIG_VP8_CUVID_DECODER
689 DEFINE_CUVID_CODEC(vp8, VP8)
690 #endif
691 
692 #if CONFIG_VP9_CUVID_DECODER
693 DEFINE_CUVID_CODEC(vp9, VP9)
694 #endif
695 
696 #if CONFIG_VC1_CUVID_DECODER
697 DEFINE_CUVID_CODEC(vc1, VC1)
698 #endif
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
Definition: hwcontext.h:53
void av_bsf_free(AVBSFContext **ctx)
Free a bitstream filter context and everything associated with it; write NULL into the supplied point...
Definition: bsf.c:33
#define NULL
Definition: coverity.c:32
const struct AVCodec * codec
Definition: avcodec.h:1658
AVRational framerate
Definition: avcodec.h:3338
AVCodecParameters * par_out
Parameters of the output stream.
Definition: avcodec.h:5708
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:124
This structure describes decoded (raw) audio or video data.
Definition: frame.h:184
AVBufferRef * hwdevice
Definition: cuvid.c:41
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:101
#define AV_CODEC_FLAG_INTERLACED_DCT
Use interlaced DCT.
Definition: avcodec.h:871
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:1851
int64_t bit_rate
the average bitrate
Definition: avcodec.h:1714
#define MAX_FRAME_COUNT
Definition: cuvid.c:34
int CUdevice
Definition: nvenc.h:44
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:2385
int num
numerator
Definition: rational.h:44
The bitstream filter state.
Definition: avcodec.h:5677
static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT *format)
Definition: cuvid.c:77
const AVBitStreamFilter * av_bsf_get_by_name(const char *name)
int width
The allocated dimensions of the frames in this pool.
Definition: hwcontext.h:221
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1877
void av_frame_set_pkt_duration(AVFrame *frame, int64_t val)
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
Definition: hwcontext.h:201
#define DEFINE_CUVID_CODEC(x, X)
Definition: cuvid.c:658
void av_frame_set_pkt_size(AVFrame *frame, int val)
int av_bsf_init(AVBSFContext *ctx)
Prepare the filter for use, after all the parameters and options have been set.
Definition: bsf.c:132
static int check_cu(AVCodecContext *avctx, CUresult err, const char *func)
Definition: cuvid.c:54
int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, int(*func)(void *, void *, int))
Feed data from a user-supplied callback to an AVFifoBuffer.
Definition: fifo.c:122
AVBufferRef * hw_frames_ctx
For hwaccel-format frames, this should be a reference to the AVHWFramesContext describing the frame...
Definition: frame.h:434
int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **ctx)
Allocate a context for a given bitstream filter.
Definition: bsf.c:79
int av_bsf_receive_packet(AVBSFContext *ctx, AVPacket *pkt)
Retrieve a filtered packet.
Definition: bsf.c:194
static void cuvid_ctx_free(AVHWDeviceContext *ctx)
Definition: cuvid.c:413
uint8_t
#define av_cold
Definition: attributes.h:82
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:140
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
Definition: log.h:202
int internal_error
Definition: cuvid.c:48
CUvideoparser cuparser
Definition: cuvid.c:39
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
Set various frame properties from the codec context / packet data.
Definition: utils.c:851
static av_cold int cuvid_decode_init(AVCodecContext *avctx)
Definition: cuvid.c:458
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
Definition: frame.h:268
AVFifoBuffer * frame_queue
Definition: cuvid.c:46
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1764
static AVFrame * frame
void * hwctx
The format-specific data, allocated and freed by libavutil along with this context.
Definition: hwcontext.h:84
static av_cold int cuvid_decode_end(AVCodecContext *avctx)
Definition: cuvid.c:392
int ff_set_sar(AVCodecContext *avctx, AVRational sar)
Check that the provided sample aspect ratio is valid and set it on the codec context.
Definition: utils.c:225
int interlaced_frame
The content of the picture is interlaced.
Definition: frame.h:318
#define CUDAAPI
Definition: nvenc.h:38
#define FFALIGN(x, a)
Definition: macros.h:48
#define av_log(a,...)
int av_packet_ref(AVPacket *dst, const AVPacket *src)
Setup a new reference to the data described by a given packet.
Definition: avpacket.c:572
An API-specific header for AV_HWDEVICE_TYPE_CUDA.
int64_t av_rescale_q(int64_t a, AVRational bq, AVRational cq)
Rescale a 64-bit integer by 2 rational numbers.
Definition: mathematics.c:142
enum AVCodecID id
Definition: avcodec.h:3556
cudaVideoChromaFormat chroma_format
Definition: cuvid.c:51
int width
width and height of the video frame
Definition: frame.h:236
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
cudaVideoCodec codec_type
Definition: cuvid.c:50
void(* free)(struct AVHWDeviceContext *ctx)
This field may be set by the caller before calling av_hwdevice_ctx_init().
Definition: hwcontext.h:96
#define AVERROR(e)
Definition: error.h:43
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:153
AVRational av_div_q(AVRational b, AVRational c)
Divide one rational by another.
Definition: rational.c:88
int av_fifo_generic_read(AVFifoBuffer *f, void *dest, int buf_size, void(*func)(void *, void *, int))
Feed data from an AVFifoBuffer to a user-supplied callback.
Definition: fifo.c:213
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1744
GLenum GLint * params
Definition: opengl_enc.c:114
planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (firs...
Definition: pixfmt.h:90
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
Definition: hwcontext.c:260
static const uint8_t offset[127][2]
Definition: vf_spp.c:92
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
Definition: hwcontext.c:387
int extradata_size
Size of the extradata content in bytes.
Definition: avcodec.h:3940
static int cuvid_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: cuvid.c:208
int av_hwframe_transfer_data(AVFrame *dst, const AVFrame *src, int flags)
Copy data to or from a hw surface.
Definition: hwcontext.c:361
#define CHECK_CU(x)
Definition: cuvid.c:75
#define FFMIN(a, b)
Definition: common.h:96
AVHWDeviceContext * device_ctx
The parent AVHWDeviceContext.
Definition: hwcontext.h:141
int width
picture width / height.
Definition: avcodec.h:1836
static int filter_packet(AVFormatContext *avf, ConcatStream *cs, AVPacket *pkt)
Definition: concatdec.c:521
AVBufferRef * hw_frames_ctx
Encoding only.
Definition: avcodec.h:3495
AVBufferRef * hwframe
Definition: cuvid.c:42
int av_bsf_send_packet(AVBSFContext *ctx, AVPacket *pkt)
Submit a packet for filtering.
Definition: bsf.c:173
AVFormatContext * ctx
Definition: movenc.c:48
void av_frame_set_pkt_pos(AVFrame *frame, int64_t val)
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition: avcodec.h:2364
#define AVERROR_BSF_NOT_FOUND
Bitstream filter not found.
Definition: error.h:49
CUresult
Definition: nvenc.h:41
int dummy
Definition: motion.c:64
static int CUDAAPI cuvid_handle_picture_display(void *opaque, CUVIDPARSERDISPINFO *dispinfo)
Definition: cuvid.c:194
HW acceleration through CUDA.
Definition: pixfmt.h:248
the normal 2^n-1 "JPEG" YUV ranges
Definition: pixfmt.h:457
CUvideodecoder cudecoder
Definition: cuvid.c:38
int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt)
Select the (possibly hardware accelerated) pixel format.
Definition: utils.c:1090
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:248
AVBufferRef * av_hwdevice_ctx_alloc(enum AVHWDeviceType type)
Allocate an AVHWDeviceContext for a given pixel format.
Definition: hwcontext.c:71
static int cuvid_test_dummy_decoder(AVCodecContext *avctx, CUVIDPARSERPARAMS *cuparseinfo)
Definition: cuvid.c:419
Libavcodec external API header.
int av_fifo_size(const AVFifoBuffer *f)
Return the amount of data in bytes in the AVFifoBuffer, that is the amount of data you can read from ...
Definition: fifo.c:77
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:215
main external API structure.
Definition: avcodec.h:1649
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:563
uint8_t * data
The data buffer.
Definition: buffer.h:89
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: utils.c:928
a very simple circular buffer FIFO implementation
AVBSFContext * bsf
Definition: cuvid.c:44
int extradata_size
Definition: avcodec.h:1765
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
void * CUdeviceptr
Definition: nvenc.h:46
int av_hwdevice_ctx_init(AVBufferRef *ref)
Finalize the device context before use.
Definition: hwcontext.c:129
This struct is allocated as AVHWDeviceContext.hwctx.
int coded_height
Definition: avcodec.h:1851
static const char * format
Definition: movenc.c:47
enum AVColorSpace colorspace
YUV colorspace type.
Definition: avcodec.h:2378
rational number numerator/denominator
Definition: rational.h:43
enum AVColorTransferCharacteristic color_trc
Color Transfer Characteristic.
Definition: avcodec.h:2371
int avcodec_parameters_from_context(AVCodecParameters *par, const AVCodecContext *codec)
Fill the parameters struct based on the values from the supplied codec context.
Definition: utils.c:4077
This struct describes a set or pool of "hardware" frames (i.e.
Definition: hwcontext.h:116
int(* func)(AVBPrint *dst, const char *in, const char *arg)
Definition: jacosubdec.c:67
refcounted data buffer API
static enum AVPixelFormat pix_fmts[]
Definition: libkvazaar.c:262
int64_t pkt_pts
PTS copied from the AVPacket that was decoded to produce this frame.
Definition: frame.h:273
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:198
AVBufferRef * device_ref
A reference to the parent AVHWDeviceContext.
Definition: hwcontext.h:133
the normal 219*2^(n-8) "MPEG" YUV ranges
Definition: pixfmt.h:456
A reference to a data buffer.
Definition: buffer.h:81
common internal api header.
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
Definition: hwcontext.c:174
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:92
static int CUDAAPI cuvid_handle_picture_decode(void *opaque, CUVIDPICPARAMS *picparams)
Definition: cuvid.c:180
int den
denominator
Definition: rational.h:45
void * priv_data
Definition: avcodec.h:1691
AVBufferPool * pool
A pool from which the frames are allocated by av_hwframe_get_buffer().
Definition: hwcontext.h:182
AVFifoBuffer * av_fifo_alloc(unsigned int size)
Initialize an AVFifoBuffer.
Definition: fifo.c:43
int top_field_first
If the content is interlaced, is top field displayed first.
Definition: frame.h:323
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition: avcodec.h:3936
int height
Definition: frame.h:236
void av_fifo_freep(AVFifoBuffer **f)
Free an AVFifoBuffer and reset pointer to NULL.
Definition: fifo.c:63
void * CUcontext
Definition: nvenc.h:45
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
Definition: hwcontext.h:214
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition: error.h:57
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
This structure stores compressed data.
Definition: avcodec.h:1557
AVCodecParameters * par_in
Parameters of the input stream.
Definition: avcodec.h:5703
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:240