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