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 "config_components.h"
23
24 #include "compat/cuda/dynlink_loader.h"
25
26 #include "libavutil/buffer.h"
27 #include "libavutil/mathematics.h"
28 #include "libavutil/hwcontext.h"
29 #include "libavutil/hwcontext_cuda_internal.h"
30 #include "libavutil/cuda_check.h"
31 #include "libavutil/fifo.h"
32 #include "libavutil/log.h"
33 #include "libavutil/opt.h"
34 #include "libavutil/pixdesc.h"
35
36 #include "avcodec.h"
37 #include "bsf.h"
38 #include "codec_internal.h"
39 #include "decode.h"
40 #include "hwconfig.h"
41 #include "nvdec.h"
42 #include "internal.h"
43
44 #if !NVDECAPI_CHECK_VERSION(9, 0)
45 #define cudaVideoSurfaceFormat_YUV444 2
46 #define cudaVideoSurfaceFormat_YUV444_16Bit 3
47 #endif
48
49 #if NVDECAPI_CHECK_VERSION(11, 0)
50 #define CUVID_HAS_AV1_SUPPORT
51 #endif
52
53 typedef struct CuvidContext
54 {
55 AVClass *avclass;
56
57 CUvideodecoder cudecoder;
58 CUvideoparser cuparser;
59
60 /* This packet coincides with AVCodecInternal.in_pkt
61 * and is not owned by us. */
62 AVPacket *pkt;
63
64 char *cu_gpu;
65 int nb_surfaces;
66 int drop_second_field;
67 char *crop_expr;
68 char *resize_expr;
69
70 struct {
71 int left;
72 int top;
73 int right;
74 int bottom;
75 } crop;
76
77 struct {
78 int width;
79 int height;
80 } resize;
81
82 AVBufferRef *hwdevice;
83 AVBufferRef *hwframe;
84
85 AVFifo *frame_queue;
86
87 int deint_mode;
88 int deint_mode_current;
89 int64_t prev_pts;
90 int progressive_sequence;
91
92 int internal_error;
93 int decoder_flushing;
94
95 int *key_frame;
96
97 cudaVideoCodec codec_type;
98 cudaVideoChromaFormat chroma_format;
99
100 CUVIDDECODECAPS caps8, caps10, caps12;
101
102 CUVIDPARSERPARAMS cuparseinfo;
103 CUVIDEOFORMATEX *cuparse_ext;
104
105 CudaFunctions *cudl;
106 CuvidFunctions *cvdl;
107 } CuvidContext;
108
109 typedef struct CuvidParsedFrame
110 {
111 CUVIDPARSERDISPINFO dispinfo;
112 int second_field;
113 int is_deinterlacing;
114 } CuvidParsedFrame;
115
116 #define CHECK_CU(x) FF_CUDA_CHECK_DL(avctx, ctx->cudl, x)
117
cuvid_handle_video_sequence(void * opaque,CUVIDEOFORMAT * format)118 static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* format)
119 {
120 AVCodecContext *avctx = opaque;
121 CuvidContext *ctx = avctx->priv_data;
122 AVHWFramesContext *hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
123 CUVIDDECODECAPS *caps = NULL;
124 CUVIDDECODECREATEINFO cuinfo;
125 int surface_fmt;
126 int chroma_444;
127
128 int old_width = avctx->width;
129 int old_height = avctx->height;
130
131 enum AVPixelFormat pix_fmts[3] = { AV_PIX_FMT_CUDA,
132 AV_PIX_FMT_NONE, // Will be updated below
133 AV_PIX_FMT_NONE };
134
135 av_log(avctx, AV_LOG_TRACE, "pfnSequenceCallback, progressive_sequence=%d\n", format->progressive_sequence);
136
137 memset(&cuinfo, 0, sizeof(cuinfo));
138
139 ctx->internal_error = 0;
140
141 avctx->coded_width = cuinfo.ulWidth = format->coded_width;
142 avctx->coded_height = cuinfo.ulHeight = format->coded_height;
143
144 // apply cropping
145 cuinfo.display_area.left = format->display_area.left + ctx->crop.left;
146 cuinfo.display_area.top = format->display_area.top + ctx->crop.top;
147 cuinfo.display_area.right = format->display_area.right - ctx->crop.right;
148 cuinfo.display_area.bottom = format->display_area.bottom - ctx->crop.bottom;
149
150 // width and height need to be set before calling ff_get_format
151 if (ctx->resize_expr) {
152 avctx->width = ctx->resize.width;
153 avctx->height = ctx->resize.height;
154 } else {
155 avctx->width = cuinfo.display_area.right - cuinfo.display_area.left;
156 avctx->height = cuinfo.display_area.bottom - cuinfo.display_area.top;
157 }
158
159 // target width/height need to be multiples of two
160 cuinfo.ulTargetWidth = avctx->width = (avctx->width + 1) & ~1;
161 cuinfo.ulTargetHeight = avctx->height = (avctx->height + 1) & ~1;
162
163 // aspect ratio conversion, 1:1, depends on scaled resolution
164 cuinfo.target_rect.left = 0;
165 cuinfo.target_rect.top = 0;
166 cuinfo.target_rect.right = cuinfo.ulTargetWidth;
167 cuinfo.target_rect.bottom = cuinfo.ulTargetHeight;
168
169 chroma_444 = format->chroma_format == cudaVideoChromaFormat_444;
170
171 switch (format->bit_depth_luma_minus8) {
172 case 0: // 8-bit
173 pix_fmts[1] = chroma_444 ? AV_PIX_FMT_YUV444P : AV_PIX_FMT_NV12;
174 caps = &ctx->caps8;
175 break;
176 case 2: // 10-bit
177 pix_fmts[1] = chroma_444 ? AV_PIX_FMT_YUV444P16 : AV_PIX_FMT_P010;
178 caps = &ctx->caps10;
179 break;
180 case 4: // 12-bit
181 pix_fmts[1] = chroma_444 ? AV_PIX_FMT_YUV444P16 : AV_PIX_FMT_P016;
182 caps = &ctx->caps12;
183 break;
184 default:
185 break;
186 }
187
188 if (!caps || !caps->bIsSupported) {
189 av_log(avctx, AV_LOG_ERROR, "unsupported bit depth: %d\n",
190 format->bit_depth_luma_minus8 + 8);
191 ctx->internal_error = AVERROR(EINVAL);
192 return 0;
193 }
194
195 surface_fmt = ff_get_format(avctx, pix_fmts);
196 if (surface_fmt < 0) {
197 av_log(avctx, AV_LOG_ERROR, "ff_get_format failed: %d\n", surface_fmt);
198 ctx->internal_error = AVERROR(EINVAL);
199 return 0;
200 }
201
202 av_log(avctx, AV_LOG_VERBOSE, "Formats: Original: %s | HW: %s | SW: %s\n",
203 av_get_pix_fmt_name(avctx->pix_fmt),
204 av_get_pix_fmt_name(surface_fmt),
205 av_get_pix_fmt_name(avctx->sw_pix_fmt));
206
207 avctx->pix_fmt = surface_fmt;
208
209 // Update our hwframe ctx, as the get_format callback might have refreshed it!
210 if (avctx->hw_frames_ctx) {
211 av_buffer_unref(&ctx->hwframe);
212
213 ctx->hwframe = av_buffer_ref(avctx->hw_frames_ctx);
214 if (!ctx->hwframe) {
215 ctx->internal_error = AVERROR(ENOMEM);
216 return 0;
217 }
218
219 hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
220 }
221
222 ff_set_sar(avctx, av_div_q(
223 (AVRational){ format->display_aspect_ratio.x, format->display_aspect_ratio.y },
224 (AVRational){ avctx->width, avctx->height }));
225
226 ctx->deint_mode_current = format->progressive_sequence
227 ? cudaVideoDeinterlaceMode_Weave
228 : ctx->deint_mode;
229
230 ctx->progressive_sequence = format->progressive_sequence;
231
232 if (!format->progressive_sequence && ctx->deint_mode_current == cudaVideoDeinterlaceMode_Weave)
233 avctx->flags |= AV_CODEC_FLAG_INTERLACED_DCT;
234 else
235 avctx->flags &= ~AV_CODEC_FLAG_INTERLACED_DCT;
236
237 if (format->video_signal_description.video_full_range_flag)
238 avctx->color_range = AVCOL_RANGE_JPEG;
239 else
240 avctx->color_range = AVCOL_RANGE_MPEG;
241
242 avctx->color_primaries = format->video_signal_description.color_primaries;
243 avctx->color_trc = format->video_signal_description.transfer_characteristics;
244 avctx->colorspace = format->video_signal_description.matrix_coefficients;
245
246 if (format->bitrate)
247 avctx->bit_rate = format->bitrate;
248
249 if (format->frame_rate.numerator && format->frame_rate.denominator) {
250 avctx->framerate.num = format->frame_rate.numerator;
251 avctx->framerate.den = format->frame_rate.denominator;
252 }
253
254 if (ctx->cudecoder
255 && avctx->coded_width == format->coded_width
256 && avctx->coded_height == format->coded_height
257 && avctx->width == old_width
258 && avctx->height == old_height
259 && ctx->chroma_format == format->chroma_format
260 && ctx->codec_type == format->codec)
261 return 1;
262
263 if (ctx->cudecoder) {
264 av_log(avctx, AV_LOG_TRACE, "Re-initializing decoder\n");
265 ctx->internal_error = CHECK_CU(ctx->cvdl->cuvidDestroyDecoder(ctx->cudecoder));
266 if (ctx->internal_error < 0)
267 return 0;
268 ctx->cudecoder = NULL;
269 }
270
271 if (hwframe_ctx->pool && (
272 hwframe_ctx->width < avctx->width ||
273 hwframe_ctx->height < avctx->height ||
274 hwframe_ctx->format != AV_PIX_FMT_CUDA ||
275 hwframe_ctx->sw_format != avctx->sw_pix_fmt)) {
276 av_log(avctx, AV_LOG_ERROR, "AVHWFramesContext is already initialized with incompatible parameters\n");
277 av_log(avctx, AV_LOG_DEBUG, "width: %d <-> %d\n", hwframe_ctx->width, avctx->width);
278 av_log(avctx, AV_LOG_DEBUG, "height: %d <-> %d\n", hwframe_ctx->height, avctx->height);
279 av_log(avctx, AV_LOG_DEBUG, "format: %s <-> cuda\n", av_get_pix_fmt_name(hwframe_ctx->format));
280 av_log(avctx, AV_LOG_DEBUG, "sw_format: %s <-> %s\n",
281 av_get_pix_fmt_name(hwframe_ctx->sw_format), av_get_pix_fmt_name(avctx->sw_pix_fmt));
282 ctx->internal_error = AVERROR(EINVAL);
283 return 0;
284 }
285
286 ctx->chroma_format = format->chroma_format;
287
288 cuinfo.CodecType = ctx->codec_type = format->codec;
289 cuinfo.ChromaFormat = format->chroma_format;
290
291 switch (avctx->sw_pix_fmt) {
292 case AV_PIX_FMT_NV12:
293 cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12;
294 break;
295 case AV_PIX_FMT_P010:
296 case AV_PIX_FMT_P016:
297 cuinfo.OutputFormat = cudaVideoSurfaceFormat_P016;
298 break;
299 case AV_PIX_FMT_YUV444P:
300 cuinfo.OutputFormat = cudaVideoSurfaceFormat_YUV444;
301 break;
302 case AV_PIX_FMT_YUV444P16:
303 cuinfo.OutputFormat = cudaVideoSurfaceFormat_YUV444_16Bit;
304 break;
305 default:
306 av_log(avctx, AV_LOG_ERROR, "Unsupported output format: %s\n",
307 av_get_pix_fmt_name(avctx->sw_pix_fmt));
308 ctx->internal_error = AVERROR(EINVAL);
309 return 0;
310 }
311
312 cuinfo.ulNumDecodeSurfaces = ctx->nb_surfaces;
313 cuinfo.ulNumOutputSurfaces = 1;
314 cuinfo.ulCreationFlags = cudaVideoCreate_PreferCUVID;
315 cuinfo.bitDepthMinus8 = format->bit_depth_luma_minus8;
316 cuinfo.DeinterlaceMode = ctx->deint_mode_current;
317
318 if (ctx->deint_mode_current != cudaVideoDeinterlaceMode_Weave && !ctx->drop_second_field)
319 avctx->framerate = av_mul_q(avctx->framerate, (AVRational){2, 1});
320
321 ctx->internal_error = CHECK_CU(ctx->cvdl->cuvidCreateDecoder(&ctx->cudecoder, &cuinfo));
322 if (ctx->internal_error < 0)
323 return 0;
324
325 if (!hwframe_ctx->pool) {
326 hwframe_ctx->format = AV_PIX_FMT_CUDA;
327 hwframe_ctx->sw_format = avctx->sw_pix_fmt;
328 hwframe_ctx->width = avctx->width;
329 hwframe_ctx->height = avctx->height;
330
331 if ((ctx->internal_error = av_hwframe_ctx_init(ctx->hwframe)) < 0) {
332 av_log(avctx, AV_LOG_ERROR, "av_hwframe_ctx_init failed\n");
333 return 0;
334 }
335 }
336
337 return 1;
338 }
339
cuvid_handle_picture_decode(void * opaque,CUVIDPICPARAMS * picparams)340 static int CUDAAPI cuvid_handle_picture_decode(void *opaque, CUVIDPICPARAMS* picparams)
341 {
342 AVCodecContext *avctx = opaque;
343 CuvidContext *ctx = avctx->priv_data;
344
345 av_log(avctx, AV_LOG_TRACE, "pfnDecodePicture\n");
346
347 if(picparams->intra_pic_flag)
348 ctx->key_frame[picparams->CurrPicIdx] = picparams->intra_pic_flag;
349
350 ctx->internal_error = CHECK_CU(ctx->cvdl->cuvidDecodePicture(ctx->cudecoder, picparams));
351 if (ctx->internal_error < 0)
352 return 0;
353
354 return 1;
355 }
356
cuvid_handle_picture_display(void * opaque,CUVIDPARSERDISPINFO * dispinfo)357 static int CUDAAPI cuvid_handle_picture_display(void *opaque, CUVIDPARSERDISPINFO* dispinfo)
358 {
359 AVCodecContext *avctx = opaque;
360 CuvidContext *ctx = avctx->priv_data;
361 CuvidParsedFrame parsed_frame = { { 0 } };
362
363 parsed_frame.dispinfo = *dispinfo;
364 ctx->internal_error = 0;
365
366 // For some reason, dispinfo->progressive_frame is sometimes wrong.
367 parsed_frame.dispinfo.progressive_frame = ctx->progressive_sequence;
368
369 if (ctx->deint_mode_current == cudaVideoDeinterlaceMode_Weave) {
370 av_fifo_write(ctx->frame_queue, &parsed_frame, 1);
371 } else {
372 parsed_frame.is_deinterlacing = 1;
373 av_fifo_write(ctx->frame_queue, &parsed_frame, 1);
374 if (!ctx->drop_second_field) {
375 parsed_frame.second_field = 1;
376 av_fifo_write(ctx->frame_queue, &parsed_frame, 1);
377 }
378 }
379
380 return 1;
381 }
382
cuvid_is_buffer_full(AVCodecContext * avctx)383 static int cuvid_is_buffer_full(AVCodecContext *avctx)
384 {
385 CuvidContext *ctx = avctx->priv_data;
386
387 int delay = ctx->cuparseinfo.ulMaxDisplayDelay;
388 if (ctx->deint_mode != cudaVideoDeinterlaceMode_Weave && !ctx->drop_second_field)
389 delay *= 2;
390
391 return av_fifo_can_read(ctx->frame_queue) + delay >= ctx->nb_surfaces;
392 }
393
cuvid_decode_packet(AVCodecContext * avctx,const AVPacket * avpkt)394 static int cuvid_decode_packet(AVCodecContext *avctx, const AVPacket *avpkt)
395 {
396 CuvidContext *ctx = avctx->priv_data;
397 AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)ctx->hwdevice->data;
398 AVCUDADeviceContext *device_hwctx = device_ctx->hwctx;
399 CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx;
400 CUVIDSOURCEDATAPACKET cupkt;
401 int ret = 0, eret = 0, is_flush = ctx->decoder_flushing;
402
403 av_log(avctx, AV_LOG_TRACE, "cuvid_decode_packet\n");
404
405 if (is_flush && avpkt && avpkt->size)
406 return AVERROR_EOF;
407
408 if (cuvid_is_buffer_full(avctx) && avpkt && avpkt->size)
409 return AVERROR(EAGAIN);
410
411 ret = CHECK_CU(ctx->cudl->cuCtxPushCurrent(cuda_ctx));
412 if (ret < 0) {
413 return ret;
414 }
415
416 memset(&cupkt, 0, sizeof(cupkt));
417
418 if (avpkt && avpkt->size) {
419 cupkt.payload_size = avpkt->size;
420 cupkt.payload = avpkt->data;
421
422 if (avpkt->pts != AV_NOPTS_VALUE) {
423 cupkt.flags = CUVID_PKT_TIMESTAMP;
424 if (avctx->pkt_timebase.num && avctx->pkt_timebase.den)
425 cupkt.timestamp = av_rescale_q(avpkt->pts, avctx->pkt_timebase, (AVRational){1, 10000000});
426 else
427 cupkt.timestamp = avpkt->pts;
428 }
429 } else {
430 cupkt.flags = CUVID_PKT_ENDOFSTREAM;
431 ctx->decoder_flushing = 1;
432 }
433
434 ret = CHECK_CU(ctx->cvdl->cuvidParseVideoData(ctx->cuparser, &cupkt));
435
436 if (ret < 0)
437 goto error;
438
439 // cuvidParseVideoData doesn't return an error just because stuff failed...
440 if (ctx->internal_error) {
441 av_log(avctx, AV_LOG_ERROR, "cuvid decode callback error\n");
442 ret = ctx->internal_error;
443 goto error;
444 }
445
446 error:
447 eret = CHECK_CU(ctx->cudl->cuCtxPopCurrent(&dummy));
448
449 if (eret < 0)
450 return eret;
451 else if (ret < 0)
452 return ret;
453 else if (is_flush)
454 return AVERROR_EOF;
455 else
456 return 0;
457 }
458
cuvid_output_frame(AVCodecContext * avctx,AVFrame * frame)459 static int cuvid_output_frame(AVCodecContext *avctx, AVFrame *frame)
460 {
461 CuvidContext *ctx = avctx->priv_data;
462 AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)ctx->hwdevice->data;
463 AVCUDADeviceContext *device_hwctx = device_ctx->hwctx;
464 CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx;
465 CuvidParsedFrame parsed_frame;
466 CUdeviceptr mapped_frame = 0;
467 int ret = 0, eret = 0;
468
469 av_log(avctx, AV_LOG_TRACE, "cuvid_output_frame\n");
470
471 if (ctx->decoder_flushing) {
472 ret = cuvid_decode_packet(avctx, NULL);
473 if (ret < 0 && ret != AVERROR_EOF)
474 return ret;
475 }
476
477 if (!cuvid_is_buffer_full(avctx)) {
478 AVPacket *const pkt = ctx->pkt;
479 ret = ff_decode_get_packet(avctx, pkt);
480 if (ret < 0 && ret != AVERROR_EOF)
481 return ret;
482 ret = cuvid_decode_packet(avctx, pkt);
483 av_packet_unref(pkt);
484 // cuvid_is_buffer_full() should avoid this.
485 if (ret == AVERROR(EAGAIN))
486 ret = AVERROR_EXTERNAL;
487 if (ret < 0 && ret != AVERROR_EOF)
488 return ret;
489 }
490
491 ret = CHECK_CU(ctx->cudl->cuCtxPushCurrent(cuda_ctx));
492 if (ret < 0)
493 return ret;
494
495 if (av_fifo_read(ctx->frame_queue, &parsed_frame, 1) >= 0) {
496 const AVPixFmtDescriptor *pixdesc;
497 CUVIDPROCPARAMS params;
498 unsigned int pitch = 0;
499 int offset = 0;
500 int i;
501
502 memset(¶ms, 0, sizeof(params));
503 params.progressive_frame = parsed_frame.dispinfo.progressive_frame;
504 params.second_field = parsed_frame.second_field;
505 params.top_field_first = parsed_frame.dispinfo.top_field_first;
506
507 ret = CHECK_CU(ctx->cvdl->cuvidMapVideoFrame(ctx->cudecoder, parsed_frame.dispinfo.picture_index, &mapped_frame, &pitch, ¶ms));
508 if (ret < 0)
509 goto error;
510
511 if (avctx->pix_fmt == AV_PIX_FMT_CUDA) {
512 ret = av_hwframe_get_buffer(ctx->hwframe, frame, 0);
513 if (ret < 0) {
514 av_log(avctx, AV_LOG_ERROR, "av_hwframe_get_buffer failed\n");
515 goto error;
516 }
517
518 ret = ff_decode_frame_props(avctx, frame);
519 if (ret < 0) {
520 av_log(avctx, AV_LOG_ERROR, "ff_decode_frame_props failed\n");
521 goto error;
522 }
523
524 pixdesc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
525
526 for (i = 0; i < pixdesc->nb_components; i++) {
527 int height = avctx->height >> (i ? pixdesc->log2_chroma_h : 0);
528 CUDA_MEMCPY2D cpy = {
529 .srcMemoryType = CU_MEMORYTYPE_DEVICE,
530 .dstMemoryType = CU_MEMORYTYPE_DEVICE,
531 .srcDevice = mapped_frame,
532 .dstDevice = (CUdeviceptr)frame->data[i],
533 .srcPitch = pitch,
534 .dstPitch = frame->linesize[i],
535 .srcY = offset,
536 .WidthInBytes = FFMIN(pitch, frame->linesize[i]),
537 .Height = height,
538 };
539
540 ret = CHECK_CU(ctx->cudl->cuMemcpy2DAsync(&cpy, device_hwctx->stream));
541 if (ret < 0)
542 goto error;
543
544 offset += height;
545 }
546 } else if (avctx->pix_fmt == AV_PIX_FMT_NV12 ||
547 avctx->pix_fmt == AV_PIX_FMT_P010 ||
548 avctx->pix_fmt == AV_PIX_FMT_P016 ||
549 avctx->pix_fmt == AV_PIX_FMT_YUV444P ||
550 avctx->pix_fmt == AV_PIX_FMT_YUV444P16) {
551 unsigned int offset = 0;
552 AVFrame *tmp_frame = av_frame_alloc();
553 if (!tmp_frame) {
554 av_log(avctx, AV_LOG_ERROR, "av_frame_alloc failed\n");
555 ret = AVERROR(ENOMEM);
556 goto error;
557 }
558
559 pixdesc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
560
561 tmp_frame->format = AV_PIX_FMT_CUDA;
562 tmp_frame->hw_frames_ctx = av_buffer_ref(ctx->hwframe);
563 if (!tmp_frame->hw_frames_ctx) {
564 ret = AVERROR(ENOMEM);
565 av_frame_free(&tmp_frame);
566 goto error;
567 }
568
569 tmp_frame->width = avctx->width;
570 tmp_frame->height = avctx->height;
571
572 /*
573 * Note that the following logic would not work for three plane
574 * YUV420 because the pitch value is different for the chroma
575 * planes.
576 */
577 for (i = 0; i < pixdesc->nb_components; i++) {
578 tmp_frame->data[i] = (uint8_t*)mapped_frame + offset;
579 tmp_frame->linesize[i] = pitch;
580 offset += pitch * (avctx->height >> (i ? pixdesc->log2_chroma_h : 0));
581 }
582
583 ret = ff_get_buffer(avctx, frame, 0);
584 if (ret < 0) {
585 av_log(avctx, AV_LOG_ERROR, "ff_get_buffer failed\n");
586 av_frame_free(&tmp_frame);
587 goto error;
588 }
589
590 ret = av_hwframe_transfer_data(frame, tmp_frame, 0);
591 if (ret) {
592 av_log(avctx, AV_LOG_ERROR, "av_hwframe_transfer_data failed\n");
593 av_frame_free(&tmp_frame);
594 goto error;
595 }
596 av_frame_free(&tmp_frame);
597 } else {
598 ret = AVERROR_BUG;
599 goto error;
600 }
601
602 frame->key_frame = ctx->key_frame[parsed_frame.dispinfo.picture_index];
603 ctx->key_frame[parsed_frame.dispinfo.picture_index] = 0;
604
605 frame->width = avctx->width;
606 frame->height = avctx->height;
607 if (avctx->pkt_timebase.num && avctx->pkt_timebase.den)
608 frame->pts = av_rescale_q(parsed_frame.dispinfo.timestamp, (AVRational){1, 10000000}, avctx->pkt_timebase);
609 else
610 frame->pts = parsed_frame.dispinfo.timestamp;
611
612 if (parsed_frame.second_field) {
613 if (ctx->prev_pts == INT64_MIN) {
614 ctx->prev_pts = frame->pts;
615 frame->pts += (avctx->pkt_timebase.den * avctx->framerate.den) / (avctx->pkt_timebase.num * avctx->framerate.num);
616 } else {
617 int pts_diff = (frame->pts - ctx->prev_pts) / 2;
618 ctx->prev_pts = frame->pts;
619 frame->pts += pts_diff;
620 }
621 }
622
623 /* CUVIDs opaque reordering breaks the internal pkt logic.
624 * So set pkt_pts and clear all the other pkt_ fields.
625 */
626 frame->pkt_pos = -1;
627 frame->pkt_duration = 0;
628 frame->pkt_size = -1;
629
630 frame->interlaced_frame = !parsed_frame.is_deinterlacing && !parsed_frame.dispinfo.progressive_frame;
631
632 if (frame->interlaced_frame)
633 frame->top_field_first = parsed_frame.dispinfo.top_field_first;
634 } else if (ctx->decoder_flushing) {
635 ret = AVERROR_EOF;
636 } else {
637 ret = AVERROR(EAGAIN);
638 }
639
640 error:
641 if (ret < 0)
642 av_frame_unref(frame);
643
644 if (mapped_frame)
645 eret = CHECK_CU(ctx->cvdl->cuvidUnmapVideoFrame(ctx->cudecoder, mapped_frame));
646
647 eret = CHECK_CU(ctx->cudl->cuCtxPopCurrent(&dummy));
648
649 if (eret < 0)
650 return eret;
651 else
652 return ret;
653 }
654
cuvid_decode_end(AVCodecContext * avctx)655 static av_cold int cuvid_decode_end(AVCodecContext *avctx)
656 {
657 CuvidContext *ctx = avctx->priv_data;
658 AVHWDeviceContext *device_ctx = ctx->hwdevice ? (AVHWDeviceContext *)ctx->hwdevice->data : NULL;
659 AVCUDADeviceContext *device_hwctx = device_ctx ? device_ctx->hwctx : NULL;
660 CUcontext dummy, cuda_ctx = device_hwctx ? device_hwctx->cuda_ctx : NULL;
661
662 av_fifo_freep2(&ctx->frame_queue);
663
664 if (cuda_ctx) {
665 ctx->cudl->cuCtxPushCurrent(cuda_ctx);
666
667 if (ctx->cuparser)
668 ctx->cvdl->cuvidDestroyVideoParser(ctx->cuparser);
669
670 if (ctx->cudecoder)
671 ctx->cvdl->cuvidDestroyDecoder(ctx->cudecoder);
672
673 ctx->cudl->cuCtxPopCurrent(&dummy);
674 }
675
676 ctx->cudl = NULL;
677
678 av_buffer_unref(&ctx->hwframe);
679 av_buffer_unref(&ctx->hwdevice);
680
681 av_freep(&ctx->key_frame);
682 av_freep(&ctx->cuparse_ext);
683
684 cuvid_free_functions(&ctx->cvdl);
685
686 return 0;
687 }
688
cuvid_test_capabilities(AVCodecContext * avctx,const CUVIDPARSERPARAMS * cuparseinfo,int probed_width,int probed_height,int bit_depth)689 static int cuvid_test_capabilities(AVCodecContext *avctx,
690 const CUVIDPARSERPARAMS *cuparseinfo,
691 int probed_width,
692 int probed_height,
693 int bit_depth)
694 {
695 CuvidContext *ctx = avctx->priv_data;
696 CUVIDDECODECAPS *caps;
697 int res8 = 0, res10 = 0, res12 = 0;
698
699 if (!ctx->cvdl->cuvidGetDecoderCaps) {
700 av_log(avctx, AV_LOG_WARNING, "Used Nvidia driver is too old to perform a capability check.\n");
701 av_log(avctx, AV_LOG_WARNING, "The minimum required version is "
702 #if defined(_WIN32) || defined(__CYGWIN__)
703 "378.66"
704 #else
705 "378.13"
706 #endif
707 ". Continuing blind.\n");
708 ctx->caps8.bIsSupported = ctx->caps10.bIsSupported = 1;
709 // 12 bit was not supported before the capability check was introduced, so disable it.
710 ctx->caps12.bIsSupported = 0;
711 return 0;
712 }
713
714 ctx->caps8.eCodecType = ctx->caps10.eCodecType = ctx->caps12.eCodecType
715 = cuparseinfo->CodecType;
716 ctx->caps8.eChromaFormat = ctx->caps10.eChromaFormat = ctx->caps12.eChromaFormat
717 = cudaVideoChromaFormat_420;
718
719 ctx->caps8.nBitDepthMinus8 = 0;
720 ctx->caps10.nBitDepthMinus8 = 2;
721 ctx->caps12.nBitDepthMinus8 = 4;
722
723 res8 = CHECK_CU(ctx->cvdl->cuvidGetDecoderCaps(&ctx->caps8));
724 res10 = CHECK_CU(ctx->cvdl->cuvidGetDecoderCaps(&ctx->caps10));
725 res12 = CHECK_CU(ctx->cvdl->cuvidGetDecoderCaps(&ctx->caps12));
726
727 av_log(avctx, AV_LOG_VERBOSE, "CUVID capabilities for %s:\n", avctx->codec->name);
728 av_log(avctx, AV_LOG_VERBOSE, "8 bit: supported: %d, min_width: %d, max_width: %d, min_height: %d, max_height: %d\n",
729 ctx->caps8.bIsSupported, ctx->caps8.nMinWidth, ctx->caps8.nMaxWidth, ctx->caps8.nMinHeight, ctx->caps8.nMaxHeight);
730 av_log(avctx, AV_LOG_VERBOSE, "10 bit: supported: %d, min_width: %d, max_width: %d, min_height: %d, max_height: %d\n",
731 ctx->caps10.bIsSupported, ctx->caps10.nMinWidth, ctx->caps10.nMaxWidth, ctx->caps10.nMinHeight, ctx->caps10.nMaxHeight);
732 av_log(avctx, AV_LOG_VERBOSE, "12 bit: supported: %d, min_width: %d, max_width: %d, min_height: %d, max_height: %d\n",
733 ctx->caps12.bIsSupported, ctx->caps12.nMinWidth, ctx->caps12.nMaxWidth, ctx->caps12.nMinHeight, ctx->caps12.nMaxHeight);
734
735 switch (bit_depth) {
736 case 10:
737 caps = &ctx->caps10;
738 if (res10 < 0)
739 return res10;
740 break;
741 case 12:
742 caps = &ctx->caps12;
743 if (res12 < 0)
744 return res12;
745 break;
746 default:
747 caps = &ctx->caps8;
748 if (res8 < 0)
749 return res8;
750 }
751
752 if (!ctx->caps8.bIsSupported) {
753 av_log(avctx, AV_LOG_ERROR, "Codec %s is not supported.\n", avctx->codec->name);
754 return AVERROR(EINVAL);
755 }
756
757 if (!caps->bIsSupported) {
758 av_log(avctx, AV_LOG_ERROR, "Bit depth %d is not supported.\n", bit_depth);
759 return AVERROR(EINVAL);
760 }
761
762 if (probed_width > caps->nMaxWidth || probed_width < caps->nMinWidth) {
763 av_log(avctx, AV_LOG_ERROR, "Video width %d not within range from %d to %d\n",
764 probed_width, caps->nMinWidth, caps->nMaxWidth);
765 return AVERROR(EINVAL);
766 }
767
768 if (probed_height > caps->nMaxHeight || probed_height < caps->nMinHeight) {
769 av_log(avctx, AV_LOG_ERROR, "Video height %d not within range from %d to %d\n",
770 probed_height, caps->nMinHeight, caps->nMaxHeight);
771 return AVERROR(EINVAL);
772 }
773
774 if ((probed_width * probed_height) / 256 > caps->nMaxMBCount) {
775 av_log(avctx, AV_LOG_ERROR, "Video macroblock count %d exceeds maximum of %d\n",
776 (int)(probed_width * probed_height) / 256, caps->nMaxMBCount);
777 return AVERROR(EINVAL);
778 }
779
780 return 0;
781 }
782
cuvid_decode_init(AVCodecContext * avctx)783 static av_cold int cuvid_decode_init(AVCodecContext *avctx)
784 {
785 CuvidContext *ctx = avctx->priv_data;
786 AVCUDADeviceContext *device_hwctx;
787 AVHWDeviceContext *device_ctx;
788 AVHWFramesContext *hwframe_ctx;
789 CUVIDSOURCEDATAPACKET seq_pkt;
790 CUcontext cuda_ctx = NULL;
791 CUcontext dummy;
792 uint8_t *extradata;
793 int extradata_size;
794 int ret = 0;
795
796 enum AVPixelFormat pix_fmts[3] = { AV_PIX_FMT_CUDA,
797 AV_PIX_FMT_NV12,
798 AV_PIX_FMT_NONE };
799
800 int probed_width = avctx->coded_width ? avctx->coded_width : 1280;
801 int probed_height = avctx->coded_height ? avctx->coded_height : 720;
802 int probed_bit_depth = 8;
803
804 const AVPixFmtDescriptor *probe_desc = av_pix_fmt_desc_get(avctx->pix_fmt);
805 if (probe_desc && probe_desc->nb_components)
806 probed_bit_depth = probe_desc->comp[0].depth;
807
808 ctx->pkt = avctx->internal->in_pkt;
809 // Accelerated transcoding scenarios with 'ffmpeg' require that the
810 // pix_fmt be set to AV_PIX_FMT_CUDA early. The sw_pix_fmt, and the
811 // pix_fmt for non-accelerated transcoding, do not need to be correct
812 // but need to be set to something. We arbitrarily pick NV12.
813 ret = ff_get_format(avctx, pix_fmts);
814 if (ret < 0) {
815 av_log(avctx, AV_LOG_ERROR, "ff_get_format failed: %d\n", ret);
816 return ret;
817 }
818 avctx->pix_fmt = ret;
819
820 if (ctx->resize_expr && sscanf(ctx->resize_expr, "%dx%d",
821 &ctx->resize.width, &ctx->resize.height) != 2) {
822 av_log(avctx, AV_LOG_ERROR, "Invalid resize expressions\n");
823 ret = AVERROR(EINVAL);
824 goto error;
825 }
826
827 if (ctx->crop_expr && sscanf(ctx->crop_expr, "%dx%dx%dx%d",
828 &ctx->crop.top, &ctx->crop.bottom,
829 &ctx->crop.left, &ctx->crop.right) != 4) {
830 av_log(avctx, AV_LOG_ERROR, "Invalid cropping expressions\n");
831 ret = AVERROR(EINVAL);
832 goto error;
833 }
834
835 ret = cuvid_load_functions(&ctx->cvdl, avctx);
836 if (ret < 0) {
837 av_log(avctx, AV_LOG_ERROR, "Failed loading nvcuvid.\n");
838 goto error;
839 }
840
841 ctx->frame_queue = av_fifo_alloc2(ctx->nb_surfaces, sizeof(CuvidParsedFrame), 0);
842 if (!ctx->frame_queue) {
843 ret = AVERROR(ENOMEM);
844 goto error;
845 }
846
847 if (avctx->hw_frames_ctx) {
848 ctx->hwframe = av_buffer_ref(avctx->hw_frames_ctx);
849 if (!ctx->hwframe) {
850 ret = AVERROR(ENOMEM);
851 goto error;
852 }
853
854 hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
855
856 ctx->hwdevice = av_buffer_ref(hwframe_ctx->device_ref);
857 if (!ctx->hwdevice) {
858 ret = AVERROR(ENOMEM);
859 goto error;
860 }
861 } else {
862 if (avctx->hw_device_ctx) {
863 ctx->hwdevice = av_buffer_ref(avctx->hw_device_ctx);
864 if (!ctx->hwdevice) {
865 ret = AVERROR(ENOMEM);
866 goto error;
867 }
868 } else {
869 ret = av_hwdevice_ctx_create(&ctx->hwdevice, AV_HWDEVICE_TYPE_CUDA, ctx->cu_gpu, NULL, 0);
870 if (ret < 0)
871 goto error;
872 }
873
874 ctx->hwframe = av_hwframe_ctx_alloc(ctx->hwdevice);
875 if (!ctx->hwframe) {
876 av_log(avctx, AV_LOG_ERROR, "av_hwframe_ctx_alloc failed\n");
877 ret = AVERROR(ENOMEM);
878 goto error;
879 }
880
881 hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
882 }
883
884 device_ctx = hwframe_ctx->device_ctx;
885 device_hwctx = device_ctx->hwctx;
886
887 cuda_ctx = device_hwctx->cuda_ctx;
888 ctx->cudl = device_hwctx->internal->cuda_dl;
889
890 memset(&ctx->cuparseinfo, 0, sizeof(ctx->cuparseinfo));
891 memset(&seq_pkt, 0, sizeof(seq_pkt));
892
893 switch (avctx->codec->id) {
894 #if CONFIG_H264_CUVID_DECODER
895 case AV_CODEC_ID_H264:
896 ctx->cuparseinfo.CodecType = cudaVideoCodec_H264;
897 break;
898 #endif
899 #if CONFIG_HEVC_CUVID_DECODER
900 case AV_CODEC_ID_HEVC:
901 ctx->cuparseinfo.CodecType = cudaVideoCodec_HEVC;
902 break;
903 #endif
904 #if CONFIG_MJPEG_CUVID_DECODER
905 case AV_CODEC_ID_MJPEG:
906 ctx->cuparseinfo.CodecType = cudaVideoCodec_JPEG;
907 break;
908 #endif
909 #if CONFIG_MPEG1_CUVID_DECODER
910 case AV_CODEC_ID_MPEG1VIDEO:
911 ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG1;
912 break;
913 #endif
914 #if CONFIG_MPEG2_CUVID_DECODER
915 case AV_CODEC_ID_MPEG2VIDEO:
916 ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG2;
917 break;
918 #endif
919 #if CONFIG_MPEG4_CUVID_DECODER
920 case AV_CODEC_ID_MPEG4:
921 ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG4;
922 break;
923 #endif
924 #if CONFIG_VP8_CUVID_DECODER
925 case AV_CODEC_ID_VP8:
926 ctx->cuparseinfo.CodecType = cudaVideoCodec_VP8;
927 break;
928 #endif
929 #if CONFIG_VP9_CUVID_DECODER
930 case AV_CODEC_ID_VP9:
931 ctx->cuparseinfo.CodecType = cudaVideoCodec_VP9;
932 break;
933 #endif
934 #if CONFIG_VC1_CUVID_DECODER
935 case AV_CODEC_ID_VC1:
936 ctx->cuparseinfo.CodecType = cudaVideoCodec_VC1;
937 break;
938 #endif
939 #if CONFIG_AV1_CUVID_DECODER && defined(CUVID_HAS_AV1_SUPPORT)
940 case AV_CODEC_ID_AV1:
941 ctx->cuparseinfo.CodecType = cudaVideoCodec_AV1;
942 break;
943 #endif
944 default:
945 av_log(avctx, AV_LOG_ERROR, "Invalid CUVID codec!\n");
946 return AVERROR_BUG;
947 }
948
949 if (ffcodec(avctx->codec)->bsfs) {
950 const AVCodecParameters *par = avctx->internal->bsf->par_out;
951 extradata = par->extradata;
952 extradata_size = par->extradata_size;
953 } else {
954 extradata = avctx->extradata;
955 extradata_size = avctx->extradata_size;
956 }
957
958 // Check first bit to determine whether it's AV1CodecConfigurationRecord.
959 // Skip first 4 bytes of AV1CodecConfigurationRecord to keep configOBUs
960 // only, otherwise cuvidParseVideoData report unknown error.
961 if (avctx->codec->id == AV_CODEC_ID_AV1 &&
962 extradata_size > 4 &&
963 extradata[0] & 0x80) {
964 extradata += 4;
965 extradata_size -= 4;
966 }
967
968 ctx->cuparse_ext = av_mallocz(sizeof(*ctx->cuparse_ext)
969 + FFMAX(extradata_size - (int)sizeof(ctx->cuparse_ext->raw_seqhdr_data), 0));
970 if (!ctx->cuparse_ext) {
971 ret = AVERROR(ENOMEM);
972 goto error;
973 }
974
975 if (extradata_size > 0)
976 memcpy(ctx->cuparse_ext->raw_seqhdr_data, extradata, extradata_size);
977 ctx->cuparse_ext->format.seqhdr_data_length = extradata_size;
978
979 ctx->cuparseinfo.pExtVideoInfo = ctx->cuparse_ext;
980
981 ctx->key_frame = av_mallocz(ctx->nb_surfaces * sizeof(int));
982 if (!ctx->key_frame) {
983 ret = AVERROR(ENOMEM);
984 goto error;
985 }
986
987 ctx->cuparseinfo.ulMaxNumDecodeSurfaces = ctx->nb_surfaces;
988 ctx->cuparseinfo.ulMaxDisplayDelay = (avctx->flags & AV_CODEC_FLAG_LOW_DELAY) ? 0 : 4;
989 ctx->cuparseinfo.pUserData = avctx;
990 ctx->cuparseinfo.pfnSequenceCallback = cuvid_handle_video_sequence;
991 ctx->cuparseinfo.pfnDecodePicture = cuvid_handle_picture_decode;
992 ctx->cuparseinfo.pfnDisplayPicture = cuvid_handle_picture_display;
993
994 ret = CHECK_CU(ctx->cudl->cuCtxPushCurrent(cuda_ctx));
995 if (ret < 0)
996 goto error;
997
998 ret = cuvid_test_capabilities(avctx, &ctx->cuparseinfo,
999 probed_width,
1000 probed_height,
1001 probed_bit_depth);
1002 if (ret < 0)
1003 goto error;
1004
1005 ret = CHECK_CU(ctx->cvdl->cuvidCreateVideoParser(&ctx->cuparser, &ctx->cuparseinfo));
1006 if (ret < 0)
1007 goto error;
1008
1009 seq_pkt.payload = ctx->cuparse_ext->raw_seqhdr_data;
1010 seq_pkt.payload_size = ctx->cuparse_ext->format.seqhdr_data_length;
1011
1012 if (seq_pkt.payload && seq_pkt.payload_size) {
1013 ret = CHECK_CU(ctx->cvdl->cuvidParseVideoData(ctx->cuparser, &seq_pkt));
1014 if (ret < 0)
1015 goto error;
1016 }
1017
1018 ret = CHECK_CU(ctx->cudl->cuCtxPopCurrent(&dummy));
1019 if (ret < 0)
1020 goto error;
1021
1022 ctx->prev_pts = INT64_MIN;
1023
1024 if (!avctx->pkt_timebase.num || !avctx->pkt_timebase.den)
1025 av_log(avctx, AV_LOG_WARNING, "Invalid pkt_timebase, passing timestamps as-is.\n");
1026
1027 return 0;
1028
1029 error:
1030 cuvid_decode_end(avctx);
1031 return ret;
1032 }
1033
cuvid_flush(AVCodecContext * avctx)1034 static void cuvid_flush(AVCodecContext *avctx)
1035 {
1036 CuvidContext *ctx = avctx->priv_data;
1037 AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)ctx->hwdevice->data;
1038 AVCUDADeviceContext *device_hwctx = device_ctx->hwctx;
1039 CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx;
1040 CUVIDSOURCEDATAPACKET seq_pkt = { 0 };
1041 int ret;
1042
1043 ret = CHECK_CU(ctx->cudl->cuCtxPushCurrent(cuda_ctx));
1044 if (ret < 0)
1045 goto error;
1046
1047 av_fifo_reset2(ctx->frame_queue);
1048
1049 if (ctx->cudecoder) {
1050 ctx->cvdl->cuvidDestroyDecoder(ctx->cudecoder);
1051 ctx->cudecoder = NULL;
1052 }
1053
1054 if (ctx->cuparser) {
1055 ctx->cvdl->cuvidDestroyVideoParser(ctx->cuparser);
1056 ctx->cuparser = NULL;
1057 }
1058
1059 ret = CHECK_CU(ctx->cvdl->cuvidCreateVideoParser(&ctx->cuparser, &ctx->cuparseinfo));
1060 if (ret < 0)
1061 goto error;
1062
1063 seq_pkt.payload = ctx->cuparse_ext->raw_seqhdr_data;
1064 seq_pkt.payload_size = ctx->cuparse_ext->format.seqhdr_data_length;
1065
1066 if (seq_pkt.payload && seq_pkt.payload_size) {
1067 ret = CHECK_CU(ctx->cvdl->cuvidParseVideoData(ctx->cuparser, &seq_pkt));
1068 if (ret < 0)
1069 goto error;
1070 }
1071
1072 ret = CHECK_CU(ctx->cudl->cuCtxPopCurrent(&dummy));
1073 if (ret < 0)
1074 goto error;
1075
1076 ctx->prev_pts = INT64_MIN;
1077 ctx->decoder_flushing = 0;
1078
1079 return;
1080 error:
1081 av_log(avctx, AV_LOG_ERROR, "CUDA reinit on flush failed\n");
1082 }
1083
1084 #define OFFSET(x) offsetof(CuvidContext, x)
1085 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
1086 static const AVOption options[] = {
1087 { "deint", "Set deinterlacing mode", OFFSET(deint_mode), AV_OPT_TYPE_INT, { .i64 = cudaVideoDeinterlaceMode_Weave }, cudaVideoDeinterlaceMode_Weave, cudaVideoDeinterlaceMode_Adaptive, VD, "deint" },
1088 { "weave", "Weave deinterlacing (do nothing)", 0, AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Weave }, 0, 0, VD, "deint" },
1089 { "bob", "Bob deinterlacing", 0, AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Bob }, 0, 0, VD, "deint" },
1090 { "adaptive", "Adaptive deinterlacing", 0, AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Adaptive }, 0, 0, VD, "deint" },
1091 { "gpu", "GPU to be used for decoding", OFFSET(cu_gpu), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD },
1092 { "surfaces", "Maximum surfaces to be used for decoding", OFFSET(nb_surfaces), AV_OPT_TYPE_INT, { .i64 = 25 }, 0, INT_MAX, VD },
1093 { "drop_second_field", "Drop second field when deinterlacing", OFFSET(drop_second_field), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VD },
1094 { "crop", "Crop (top)x(bottom)x(left)x(right)", OFFSET(crop_expr), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD },
1095 { "resize", "Resize (width)x(height)", OFFSET(resize_expr), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD },
1096 { NULL }
1097 };
1098
1099 static const AVCodecHWConfigInternal *const cuvid_hw_configs[] = {
1100 &(const AVCodecHWConfigInternal) {
1101 .public = {
1102 .pix_fmt = AV_PIX_FMT_CUDA,
1103 .methods = AV_CODEC_HW_CONFIG_METHOD_HW_DEVICE_CTX |
1104 AV_CODEC_HW_CONFIG_METHOD_INTERNAL,
1105 .device_type = AV_HWDEVICE_TYPE_CUDA
1106 },
1107 .hwaccel = NULL,
1108 },
1109 NULL
1110 };
1111
1112 #define DEFINE_CUVID_CODEC(x, X, bsf_name) \
1113 static const AVClass x##_cuvid_class = { \
1114 .class_name = #x "_cuvid", \
1115 .item_name = av_default_item_name, \
1116 .option = options, \
1117 .version = LIBAVUTIL_VERSION_INT, \
1118 }; \
1119 const FFCodec ff_##x##_cuvid_decoder = { \
1120 .p.name = #x "_cuvid", \
1121 .p.long_name = NULL_IF_CONFIG_SMALL("Nvidia CUVID " #X " decoder"), \
1122 .p.type = AVMEDIA_TYPE_VIDEO, \
1123 .p.id = AV_CODEC_ID_##X, \
1124 .priv_data_size = sizeof(CuvidContext), \
1125 .p.priv_class = &x##_cuvid_class, \
1126 .init = cuvid_decode_init, \
1127 .close = cuvid_decode_end, \
1128 FF_CODEC_RECEIVE_FRAME_CB(cuvid_output_frame), \
1129 .flush = cuvid_flush, \
1130 .bsfs = bsf_name, \
1131 .p.capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \
1132 .caps_internal = FF_CODEC_CAP_SETS_FRAME_PROPS, \
1133 .p.pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, \
1134 AV_PIX_FMT_NV12, \
1135 AV_PIX_FMT_P010, \
1136 AV_PIX_FMT_P016, \
1137 AV_PIX_FMT_NONE }, \
1138 .hw_configs = cuvid_hw_configs, \
1139 .p.wrapper_name = "cuvid", \
1140 };
1141
1142 #if CONFIG_AV1_CUVID_DECODER && defined(CUVID_HAS_AV1_SUPPORT)
1143 DEFINE_CUVID_CODEC(av1, AV1, NULL)
1144 #endif
1145
1146 #if CONFIG_HEVC_CUVID_DECODER
1147 DEFINE_CUVID_CODEC(hevc, HEVC, "hevc_mp4toannexb")
1148 #endif
1149
1150 #if CONFIG_H264_CUVID_DECODER
1151 DEFINE_CUVID_CODEC(h264, H264, "h264_mp4toannexb")
1152 #endif
1153
1154 #if CONFIG_MJPEG_CUVID_DECODER
1155 DEFINE_CUVID_CODEC(mjpeg, MJPEG, NULL)
1156 #endif
1157
1158 #if CONFIG_MPEG1_CUVID_DECODER
1159 DEFINE_CUVID_CODEC(mpeg1, MPEG1VIDEO, NULL)
1160 #endif
1161
1162 #if CONFIG_MPEG2_CUVID_DECODER
1163 DEFINE_CUVID_CODEC(mpeg2, MPEG2VIDEO, NULL)
1164 #endif
1165
1166 #if CONFIG_MPEG4_CUVID_DECODER
1167 DEFINE_CUVID_CODEC(mpeg4, MPEG4, NULL)
1168 #endif
1169
1170 #if CONFIG_VP8_CUVID_DECODER
1171 DEFINE_CUVID_CODEC(vp8, VP8, NULL)
1172 #endif
1173
1174 #if CONFIG_VP9_CUVID_DECODER
1175 DEFINE_CUVID_CODEC(vp9, VP9, NULL)
1176 #endif
1177
1178 #if CONFIG_VC1_CUVID_DECODER
1179 DEFINE_CUVID_CODEC(vc1, VC1, NULL)
1180 #endif
1181