xref: /third_party/ffmpeg/libavcodec/cuviddec.c (revision cabdff1a)
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
53typedef 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
109typedef 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
118static 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
340static 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
357static 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
383static 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
394static 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
446error:
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
459static 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
640error:
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
655static 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
689static 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
783static 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
1029error:
1030    cuvid_decode_end(avctx);
1031    return ret;
1032}
1033
1034static 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
1086static 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
1099static 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)
1143DEFINE_CUVID_CODEC(av1, AV1, NULL)
1144#endif
1145
1146#if CONFIG_HEVC_CUVID_DECODER
1147DEFINE_CUVID_CODEC(hevc, HEVC, "hevc_mp4toannexb")
1148#endif
1149
1150#if CONFIG_H264_CUVID_DECODER
1151DEFINE_CUVID_CODEC(h264, H264, "h264_mp4toannexb")
1152#endif
1153
1154#if CONFIG_MJPEG_CUVID_DECODER
1155DEFINE_CUVID_CODEC(mjpeg, MJPEG, NULL)
1156#endif
1157
1158#if CONFIG_MPEG1_CUVID_DECODER
1159DEFINE_CUVID_CODEC(mpeg1, MPEG1VIDEO, NULL)
1160#endif
1161
1162#if CONFIG_MPEG2_CUVID_DECODER
1163DEFINE_CUVID_CODEC(mpeg2, MPEG2VIDEO, NULL)
1164#endif
1165
1166#if CONFIG_MPEG4_CUVID_DECODER
1167DEFINE_CUVID_CODEC(mpeg4, MPEG4, NULL)
1168#endif
1169
1170#if CONFIG_VP8_CUVID_DECODER
1171DEFINE_CUVID_CODEC(vp8, VP8, NULL)
1172#endif
1173
1174#if CONFIG_VP9_CUVID_DECODER
1175DEFINE_CUVID_CODEC(vp9, VP9, NULL)
1176#endif
1177
1178#if CONFIG_VC1_CUVID_DECODER
1179DEFINE_CUVID_CODEC(vc1, VC1, NULL)
1180#endif
1181