• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(&params, 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, &params));
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