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