avcodec/cuvid: Add support for P010/P016 as an output surface format
[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     ret = cuvid_load_functions(&ctx->cvdl);
668     if (ret < 0) {
669         av_log(avctx, AV_LOG_ERROR, "Failed loading nvcuvid.\n");
670         goto error;
671     }
672
673     ctx->frame_queue = av_fifo_alloc(ctx->nb_surfaces * sizeof(CuvidParsedFrame));
674     if (!ctx->frame_queue) {
675         ret = AVERROR(ENOMEM);
676         goto error;
677     }
678
679     if (avctx->hw_frames_ctx) {
680         ctx->hwframe = av_buffer_ref(avctx->hw_frames_ctx);
681         if (!ctx->hwframe) {
682             ret = AVERROR(ENOMEM);
683             goto error;
684         }
685
686         hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
687
688         ctx->hwdevice = av_buffer_ref(hwframe_ctx->device_ref);
689         if (!ctx->hwdevice) {
690             ret = AVERROR(ENOMEM);
691             goto error;
692         }
693     } else {
694         ret = av_hwdevice_ctx_create(&ctx->hwdevice, AV_HWDEVICE_TYPE_CUDA, ctx->cu_gpu, NULL, 0);
695         if (ret < 0)
696             goto error;
697
698         ctx->hwframe = av_hwframe_ctx_alloc(ctx->hwdevice);
699         if (!ctx->hwframe) {
700             av_log(avctx, AV_LOG_ERROR, "av_hwframe_ctx_alloc failed\n");
701             ret = AVERROR(ENOMEM);
702             goto error;
703         }
704
705         hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
706     }
707
708     device_ctx = hwframe_ctx->device_ctx;
709     device_hwctx = device_ctx->hwctx;
710
711     cuda_ctx = device_hwctx->cuda_ctx;
712     ctx->cudl = device_hwctx->internal->cuda_dl;
713
714     memset(&ctx->cuparseinfo, 0, sizeof(ctx->cuparseinfo));
715     memset(&ctx->cuparse_ext, 0, sizeof(ctx->cuparse_ext));
716     memset(&seq_pkt, 0, sizeof(seq_pkt));
717
718     ctx->cuparseinfo.pExtVideoInfo = &ctx->cuparse_ext;
719
720     switch (avctx->codec->id) {
721 #if CONFIG_H264_CUVID_DECODER
722     case AV_CODEC_ID_H264:
723         ctx->cuparseinfo.CodecType = cudaVideoCodec_H264;
724         break;
725 #endif
726 #if CONFIG_HEVC_CUVID_DECODER
727     case AV_CODEC_ID_HEVC:
728         ctx->cuparseinfo.CodecType = cudaVideoCodec_HEVC;
729         break;
730 #endif
731 #if CONFIG_MJPEG_CUVID_DECODER
732     case AV_CODEC_ID_MJPEG:
733         ctx->cuparseinfo.CodecType = cudaVideoCodec_JPEG;
734         break;
735 #endif
736 #if CONFIG_MPEG1_CUVID_DECODER
737     case AV_CODEC_ID_MPEG1VIDEO:
738         ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG1;
739         break;
740 #endif
741 #if CONFIG_MPEG2_CUVID_DECODER
742     case AV_CODEC_ID_MPEG2VIDEO:
743         ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG2;
744         break;
745 #endif
746 #if CONFIG_MPEG4_CUVID_DECODER
747     case AV_CODEC_ID_MPEG4:
748         ctx->cuparseinfo.CodecType = cudaVideoCodec_MPEG4;
749         break;
750 #endif
751 #if CONFIG_VP8_CUVID_DECODER
752     case AV_CODEC_ID_VP8:
753         ctx->cuparseinfo.CodecType = cudaVideoCodec_VP8;
754         break;
755 #endif
756 #if CONFIG_VP9_CUVID_DECODER
757     case AV_CODEC_ID_VP9:
758         ctx->cuparseinfo.CodecType = cudaVideoCodec_VP9;
759         break;
760 #endif
761 #if CONFIG_VC1_CUVID_DECODER
762     case AV_CODEC_ID_VC1:
763         ctx->cuparseinfo.CodecType = cudaVideoCodec_VC1;
764         break;
765 #endif
766     default:
767         av_log(avctx, AV_LOG_ERROR, "Invalid CUVID codec!\n");
768         return AVERROR_BUG;
769     }
770
771     if (avctx->codec->id == AV_CODEC_ID_H264 || avctx->codec->id == AV_CODEC_ID_HEVC) {
772         if (avctx->codec->id == AV_CODEC_ID_H264)
773             bsf = av_bsf_get_by_name("h264_mp4toannexb");
774         else
775             bsf = av_bsf_get_by_name("hevc_mp4toannexb");
776
777         if (!bsf) {
778             ret = AVERROR_BSF_NOT_FOUND;
779             goto error;
780         }
781         if (ret = av_bsf_alloc(bsf, &ctx->bsf)) {
782             goto error;
783         }
784         if (((ret = avcodec_parameters_from_context(ctx->bsf->par_in, avctx)) < 0) || ((ret = av_bsf_init(ctx->bsf)) < 0)) {
785             av_bsf_free(&ctx->bsf);
786             goto error;
787         }
788
789         ctx->cuparse_ext.format.seqhdr_data_length = ctx->bsf->par_out->extradata_size;
790         memcpy(ctx->cuparse_ext.raw_seqhdr_data,
791                ctx->bsf->par_out->extradata,
792                FFMIN(sizeof(ctx->cuparse_ext.raw_seqhdr_data), ctx->bsf->par_out->extradata_size));
793     } else if (avctx->extradata_size > 0) {
794         ctx->cuparse_ext.format.seqhdr_data_length = avctx->extradata_size;
795         memcpy(ctx->cuparse_ext.raw_seqhdr_data,
796                avctx->extradata,
797                FFMIN(sizeof(ctx->cuparse_ext.raw_seqhdr_data), avctx->extradata_size));
798     }
799
800     ctx->cuparseinfo.ulMaxNumDecodeSurfaces = ctx->nb_surfaces;
801     ctx->cuparseinfo.ulMaxDisplayDelay = 4;
802     ctx->cuparseinfo.pUserData = avctx;
803     ctx->cuparseinfo.pfnSequenceCallback = cuvid_handle_video_sequence;
804     ctx->cuparseinfo.pfnDecodePicture = cuvid_handle_picture_decode;
805     ctx->cuparseinfo.pfnDisplayPicture = cuvid_handle_picture_display;
806
807     ret = CHECK_CU(ctx->cudl->cuCtxPushCurrent(cuda_ctx));
808     if (ret < 0)
809         goto error;
810
811     ret = cuvid_test_dummy_decoder(avctx, &ctx->cuparseinfo);
812     if (ret < 0)
813         goto error;
814
815     ret = CHECK_CU(ctx->cvdl->cuvidCreateVideoParser(&ctx->cuparser, &ctx->cuparseinfo));
816     if (ret < 0)
817         goto error;
818
819     seq_pkt.payload = ctx->cuparse_ext.raw_seqhdr_data;
820     seq_pkt.payload_size = ctx->cuparse_ext.format.seqhdr_data_length;
821
822     if (seq_pkt.payload && seq_pkt.payload_size) {
823         ret = CHECK_CU(ctx->cvdl->cuvidParseVideoData(ctx->cuparser, &seq_pkt));
824         if (ret < 0)
825             goto error;
826     }
827
828     ret = CHECK_CU(ctx->cudl->cuCtxPopCurrent(&dummy));
829     if (ret < 0)
830         goto error;
831
832     ctx->prev_pts = INT64_MIN;
833
834     if (!avctx->pkt_timebase.num || !avctx->pkt_timebase.den)
835         av_log(avctx, AV_LOG_WARNING, "Invalid pkt_timebase, passing timestamps as-is.\n");
836
837     return 0;
838
839 error:
840     cuvid_decode_end(avctx);
841     return ret;
842 }
843
844 static void cuvid_flush(AVCodecContext *avctx)
845 {
846     CuvidContext *ctx = avctx->priv_data;
847     AVHWDeviceContext *device_ctx = (AVHWDeviceContext*)ctx->hwdevice->data;
848     AVCUDADeviceContext *device_hwctx = device_ctx->hwctx;
849     CUcontext dummy, cuda_ctx = device_hwctx->cuda_ctx;
850     CUVIDSOURCEDATAPACKET seq_pkt = { 0 };
851     int ret;
852
853     ret = CHECK_CU(ctx->cudl->cuCtxPushCurrent(cuda_ctx));
854     if (ret < 0)
855         goto error;
856
857     av_fifo_freep(&ctx->frame_queue);
858
859     ctx->frame_queue = av_fifo_alloc(ctx->nb_surfaces * sizeof(CuvidParsedFrame));
860     if (!ctx->frame_queue) {
861         av_log(avctx, AV_LOG_ERROR, "Failed to recreate frame queue on flush\n");
862         return;
863     }
864
865     if (ctx->cudecoder) {
866         ctx->cvdl->cuvidDestroyDecoder(ctx->cudecoder);
867         ctx->cudecoder = NULL;
868     }
869
870     if (ctx->cuparser) {
871         ctx->cvdl->cuvidDestroyVideoParser(ctx->cuparser);
872         ctx->cuparser = NULL;
873     }
874
875     ret = CHECK_CU(ctx->cvdl->cuvidCreateVideoParser(&ctx->cuparser, &ctx->cuparseinfo));
876     if (ret < 0)
877         goto error;
878
879     seq_pkt.payload = ctx->cuparse_ext.raw_seqhdr_data;
880     seq_pkt.payload_size = ctx->cuparse_ext.format.seqhdr_data_length;
881
882     if (seq_pkt.payload && seq_pkt.payload_size) {
883         ret = CHECK_CU(ctx->cvdl->cuvidParseVideoData(ctx->cuparser, &seq_pkt));
884         if (ret < 0)
885             goto error;
886     }
887
888     ret = CHECK_CU(ctx->cudl->cuCtxPopCurrent(&dummy));
889     if (ret < 0)
890         goto error;
891
892     ctx->prev_pts = INT64_MIN;
893     ctx->decoder_flushing = 0;
894
895     return;
896  error:
897     av_log(avctx, AV_LOG_ERROR, "CUDA reinit on flush failed\n");
898 }
899
900 #define OFFSET(x) offsetof(CuvidContext, x)
901 #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
902 static const AVOption options[] = {
903     { "deint",    "Set deinterlacing mode", OFFSET(deint_mode), AV_OPT_TYPE_INT,   { .i64 = cudaVideoDeinterlaceMode_Weave    }, cudaVideoDeinterlaceMode_Weave, cudaVideoDeinterlaceMode_Adaptive, VD, "deint" },
904     { "weave",    "Weave deinterlacing (do nothing)",        0, AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Weave    }, 0, 0, VD, "deint" },
905     { "bob",      "Bob deinterlacing",                       0, AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Bob      }, 0, 0, VD, "deint" },
906     { "adaptive", "Adaptive deinterlacing",                  0, AV_OPT_TYPE_CONST, { .i64 = cudaVideoDeinterlaceMode_Adaptive }, 0, 0, VD, "deint" },
907     { "gpu",      "GPU to be used for decoding", OFFSET(cu_gpu), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, VD },
908     { "surfaces", "Maximum surfaces to be used for decoding", OFFSET(nb_surfaces), AV_OPT_TYPE_INT, { .i64 = 25 }, 0, INT_MAX, VD },
909     { NULL }
910 };
911
912 #define DEFINE_CUVID_CODEC(x, X) \
913     static const AVClass x##_cuvid_class = { \
914         .class_name = #x "_cuvid", \
915         .item_name = av_default_item_name, \
916         .option = options, \
917         .version = LIBAVUTIL_VERSION_INT, \
918     }; \
919     AVHWAccel ff_##x##_cuvid_hwaccel = { \
920         .name           = #x "_cuvid", \
921         .type           = AVMEDIA_TYPE_VIDEO, \
922         .id             = AV_CODEC_ID_##X, \
923         .pix_fmt        = AV_PIX_FMT_CUDA, \
924     }; \
925     AVCodec ff_##x##_cuvid_decoder = { \
926         .name           = #x "_cuvid", \
927         .long_name      = NULL_IF_CONFIG_SMALL("Nvidia CUVID " #X " decoder"), \
928         .type           = AVMEDIA_TYPE_VIDEO, \
929         .id             = AV_CODEC_ID_##X, \
930         .priv_data_size = sizeof(CuvidContext), \
931         .priv_class     = &x##_cuvid_class, \
932         .init           = cuvid_decode_init, \
933         .close          = cuvid_decode_end, \
934         .decode         = cuvid_decode_frame, \
935         .send_packet    = cuvid_decode_packet, \
936         .receive_frame  = cuvid_output_frame, \
937         .flush          = cuvid_flush, \
938         .capabilities   = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING, \
939         .pix_fmts       = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, \
940                                                         AV_PIX_FMT_NV12, \
941                                                         AV_PIX_FMT_P010, \
942                                                         AV_PIX_FMT_P016, \
943                                                         AV_PIX_FMT_NONE }, \
944     };
945
946 #if CONFIG_HEVC_CUVID_DECODER
947 DEFINE_CUVID_CODEC(hevc, HEVC)
948 #endif
949
950 #if CONFIG_H264_CUVID_DECODER
951 DEFINE_CUVID_CODEC(h264, H264)
952 #endif
953
954 #if CONFIG_MJPEG_CUVID_DECODER
955 DEFINE_CUVID_CODEC(mjpeg, MJPEG)
956 #endif
957
958 #if CONFIG_MPEG1_CUVID_DECODER
959 DEFINE_CUVID_CODEC(mpeg1, MPEG1VIDEO)
960 #endif
961
962 #if CONFIG_MPEG2_CUVID_DECODER
963 DEFINE_CUVID_CODEC(mpeg2, MPEG2VIDEO)
964 #endif
965
966 #if CONFIG_MPEG4_CUVID_DECODER
967 DEFINE_CUVID_CODEC(mpeg4, MPEG4)
968 #endif
969
970 #if CONFIG_VP8_CUVID_DECODER
971 DEFINE_CUVID_CODEC(vp8, VP8)
972 #endif
973
974 #if CONFIG_VP9_CUVID_DECODER
975 DEFINE_CUVID_CODEC(vp9, VP9)
976 #endif
977
978 #if CONFIG_VC1_CUVID_DECODER
979 DEFINE_CUVID_CODEC(vc1, VC1)
980 #endif