]> git.sesse.net Git - ffmpeg/blob - libavcodec/nvdec.c
Merge commit '8ca39b855a7b0e4d9f726fa9d285bc8edcb953e6'
[ffmpeg] / libavcodec / nvdec.c
1 /*
2  * HW decode acceleration through NVDEC
3  *
4  * Copyright (c) 2016 Anton Khirnov
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22
23 #include "config.h"
24
25 #include "libavutil/common.h"
26 #include "libavutil/error.h"
27 #include "libavutil/hwcontext.h"
28 #include "libavutil/hwcontext_cuda_internal.h"
29 #include "libavutil/pixdesc.h"
30 #include "libavutil/pixfmt.h"
31
32 #include "avcodec.h"
33 #include "decode.h"
34 #include "nvdec.h"
35 #include "internal.h"
36
37 typedef struct NVDECDecoder {
38     CUvideodecoder decoder;
39
40     AVBufferRef *hw_device_ref;
41     CUcontext    cuda_ctx;
42
43     CudaFunctions *cudl;
44     CuvidFunctions *cvdl;
45 } NVDECDecoder;
46
47 typedef struct NVDECFramePool {
48     unsigned int dpb_size;
49     unsigned int nb_allocated;
50 } NVDECFramePool;
51
52 static int map_avcodec_id(enum AVCodecID id)
53 {
54     switch (id) {
55     case AV_CODEC_ID_H264:       return cudaVideoCodec_H264;
56     case AV_CODEC_ID_HEVC:       return cudaVideoCodec_HEVC;
57     case AV_CODEC_ID_MJPEG:      return cudaVideoCodec_JPEG;
58     case AV_CODEC_ID_MPEG1VIDEO: return cudaVideoCodec_MPEG1;
59     case AV_CODEC_ID_MPEG2VIDEO: return cudaVideoCodec_MPEG2;
60     case AV_CODEC_ID_MPEG4:      return cudaVideoCodec_MPEG4;
61     case AV_CODEC_ID_VC1:        return cudaVideoCodec_VC1;
62     case AV_CODEC_ID_VP8:        return cudaVideoCodec_VP8;
63     case AV_CODEC_ID_VP9:        return cudaVideoCodec_VP9;
64     case AV_CODEC_ID_WMV3:       return cudaVideoCodec_VC1;
65     }
66     return -1;
67 }
68
69 static int map_chroma_format(enum AVPixelFormat pix_fmt)
70 {
71     int shift_h = 0, shift_v = 0;
72
73     av_pix_fmt_get_chroma_sub_sample(pix_fmt, &shift_h, &shift_v);
74
75     if (shift_h == 1 && shift_v == 1)
76         return cudaVideoChromaFormat_420;
77     else if (shift_h == 1 && shift_v == 0)
78         return cudaVideoChromaFormat_422;
79     else if (shift_h == 0 && shift_v == 0)
80         return cudaVideoChromaFormat_444;
81
82     return -1;
83 }
84
85 static int nvdec_test_capabilities(NVDECDecoder *decoder,
86                                    CUVIDDECODECREATEINFO *params, void *logctx)
87 {
88     CUresult err;
89     CUVIDDECODECAPS caps = { 0 };
90
91     caps.eCodecType      = params->CodecType;
92     caps.eChromaFormat   = params->ChromaFormat;
93     caps.nBitDepthMinus8 = params->bitDepthMinus8;
94
95     if (!decoder->cvdl->cuvidGetDecoderCaps) {
96         av_log(logctx, AV_LOG_WARNING, "Used Nvidia driver is too old to perform a capability check.\n");
97         av_log(logctx, AV_LOG_WARNING, "The minimum required version is "
98 #if defined(_WIN32) || defined(__CYGWIN__)
99             "378.66"
100 #else
101             "378.13"
102 #endif
103             ". Continuing blind.\n");
104         return 0;
105     }
106
107     err = decoder->cvdl->cuvidGetDecoderCaps(&caps);
108     if (err != CUDA_SUCCESS) {
109         av_log(logctx, AV_LOG_ERROR, "Failed querying decoder capabilities\n");
110         return AVERROR_UNKNOWN;
111     }
112
113     av_log(logctx, AV_LOG_VERBOSE, "NVDEC capabilities:\n");
114     av_log(logctx, AV_LOG_VERBOSE, "format supported: %s, max_mb_count: %d\n",
115            caps.bIsSupported ? "yes" : "no", caps.nMaxMBCount);
116     av_log(logctx, AV_LOG_VERBOSE, "min_width: %d, max_width: %d\n",
117            caps.nMinWidth, caps.nMaxWidth);
118     av_log(logctx, AV_LOG_VERBOSE, "min_height: %d, max_height: %d\n",
119            caps.nMinHeight, caps.nMaxHeight);
120
121     if (!caps.bIsSupported) {
122         av_log(logctx, AV_LOG_ERROR, "Hardware is lacking required capabilities\n");
123         return AVERROR(EINVAL);
124     }
125
126     if (params->ulWidth > caps.nMaxWidth || params->ulWidth < caps.nMinWidth) {
127         av_log(logctx, AV_LOG_ERROR, "Video width %d not within range from %d to %d\n",
128                (int)params->ulWidth, caps.nMinWidth, caps.nMaxWidth);
129         return AVERROR(EINVAL);
130     }
131
132     if (params->ulHeight > caps.nMaxHeight || params->ulHeight < caps.nMinHeight) {
133         av_log(logctx, AV_LOG_ERROR, "Video height %d not within range from %d to %d\n",
134                (int)params->ulHeight, caps.nMinHeight, caps.nMaxHeight);
135         return AVERROR(EINVAL);
136     }
137
138     if ((params->ulWidth * params->ulHeight) / 256 > caps.nMaxMBCount) {
139         av_log(logctx, AV_LOG_ERROR, "Video macroblock count %d exceeds maximum of %d\n",
140                (int)(params->ulWidth * params->ulHeight) / 256, caps.nMaxMBCount);
141         return AVERROR(EINVAL);
142     }
143
144     return 0;
145 }
146
147 static void nvdec_decoder_free(void *opaque, uint8_t *data)
148 {
149     NVDECDecoder *decoder = (NVDECDecoder*)data;
150
151     if (decoder->decoder)
152         decoder->cvdl->cuvidDestroyDecoder(decoder->decoder);
153
154     av_buffer_unref(&decoder->hw_device_ref);
155
156     cuvid_free_functions(&decoder->cvdl);
157
158     av_freep(&decoder);
159 }
160
161 static int nvdec_decoder_create(AVBufferRef **out, AVBufferRef *hw_device_ref,
162                                 CUVIDDECODECREATEINFO *params, void *logctx)
163 {
164     AVHWDeviceContext  *hw_device_ctx = (AVHWDeviceContext*)hw_device_ref->data;
165     AVCUDADeviceContext *device_hwctx = hw_device_ctx->hwctx;
166
167     AVBufferRef *decoder_ref;
168     NVDECDecoder *decoder;
169
170     CUcontext dummy;
171     CUresult err;
172     int ret;
173
174     decoder = av_mallocz(sizeof(*decoder));
175     if (!decoder)
176         return AVERROR(ENOMEM);
177
178     decoder_ref = av_buffer_create((uint8_t*)decoder, sizeof(*decoder),
179                                    nvdec_decoder_free, NULL, AV_BUFFER_FLAG_READONLY);
180     if (!decoder_ref) {
181         av_freep(&decoder);
182         return AVERROR(ENOMEM);
183     }
184
185     decoder->hw_device_ref = av_buffer_ref(hw_device_ref);
186     if (!decoder->hw_device_ref) {
187         ret = AVERROR(ENOMEM);
188         goto fail;
189     }
190     decoder->cuda_ctx = device_hwctx->cuda_ctx;
191     decoder->cudl = device_hwctx->internal->cuda_dl;
192
193     ret = cuvid_load_functions(&decoder->cvdl, logctx);
194     if (ret < 0) {
195         av_log(logctx, AV_LOG_ERROR, "Failed loading nvcuvid.\n");
196         goto fail;
197     }
198
199     err = decoder->cudl->cuCtxPushCurrent(decoder->cuda_ctx);
200     if (err != CUDA_SUCCESS) {
201         ret = AVERROR_UNKNOWN;
202         goto fail;
203     }
204
205     ret = nvdec_test_capabilities(decoder, params, logctx);
206     if (ret < 0) {
207         decoder->cudl->cuCtxPopCurrent(&dummy);
208         goto fail;
209     }
210
211     err = decoder->cvdl->cuvidCreateDecoder(&decoder->decoder, params);
212
213     decoder->cudl->cuCtxPopCurrent(&dummy);
214
215     if (err != CUDA_SUCCESS) {
216         av_log(logctx, AV_LOG_ERROR, "Error creating a NVDEC decoder: %d\n", err);
217         ret = AVERROR_UNKNOWN;
218         goto fail;
219     }
220
221     *out = decoder_ref;
222
223     return 0;
224 fail:
225     av_buffer_unref(&decoder_ref);
226     return ret;
227 }
228
229 static AVBufferRef *nvdec_decoder_frame_alloc(void *opaque, int size)
230 {
231     NVDECFramePool *pool = opaque;
232     AVBufferRef *ret;
233
234     if (pool->nb_allocated >= pool->dpb_size)
235         return NULL;
236
237     ret = av_buffer_alloc(sizeof(unsigned int));
238     if (!ret)
239         return NULL;
240
241     *(unsigned int*)ret->data = pool->nb_allocated++;
242
243     return ret;
244 }
245
246 int ff_nvdec_decode_uninit(AVCodecContext *avctx)
247 {
248     NVDECContext *ctx = avctx->internal->hwaccel_priv_data;
249
250     av_freep(&ctx->bitstream);
251     ctx->bitstream_len       = 0;
252     ctx->bitstream_allocated = 0;
253
254     av_freep(&ctx->slice_offsets);
255     ctx->nb_slices               = 0;
256     ctx->slice_offsets_allocated = 0;
257
258     av_buffer_unref(&ctx->decoder_ref);
259     av_buffer_pool_uninit(&ctx->decoder_pool);
260
261     return 0;
262 }
263
264 int ff_nvdec_decode_init(AVCodecContext *avctx)
265 {
266     NVDECContext *ctx = avctx->internal->hwaccel_priv_data;
267
268     NVDECFramePool      *pool;
269     AVHWFramesContext   *frames_ctx;
270     const AVPixFmtDescriptor *sw_desc;
271
272     CUVIDDECODECREATEINFO params = { 0 };
273
274     int cuvid_codec_type, cuvid_chroma_format;
275     int ret = 0;
276
277     sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
278     if (!sw_desc)
279         return AVERROR_BUG;
280
281     cuvid_codec_type = map_avcodec_id(avctx->codec_id);
282     if (cuvid_codec_type < 0) {
283         av_log(avctx, AV_LOG_ERROR, "Unsupported codec ID\n");
284         return AVERROR_BUG;
285     }
286
287     cuvid_chroma_format = map_chroma_format(avctx->sw_pix_fmt);
288     if (cuvid_chroma_format < 0) {
289         av_log(avctx, AV_LOG_ERROR, "Unsupported chroma format\n");
290         return AVERROR(ENOSYS);
291     }
292
293     if (!avctx->hw_frames_ctx) {
294         ret = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_CUDA);
295         if (ret < 0)
296             return ret;
297     }
298
299     frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data;
300
301     params.ulWidth             = avctx->coded_width;
302     params.ulHeight            = avctx->coded_height;
303     params.ulTargetWidth       = avctx->coded_width;
304     params.ulTargetHeight      = avctx->coded_height;
305     params.bitDepthMinus8      = sw_desc->comp[0].depth - 8;
306     params.OutputFormat        = params.bitDepthMinus8 ?
307                                  cudaVideoSurfaceFormat_P016 : cudaVideoSurfaceFormat_NV12;
308     params.CodecType           = cuvid_codec_type;
309     params.ChromaFormat        = cuvid_chroma_format;
310     params.ulNumDecodeSurfaces = frames_ctx->initial_pool_size;
311     params.ulNumOutputSurfaces = 1;
312
313     ret = nvdec_decoder_create(&ctx->decoder_ref, frames_ctx->device_ref, &params, avctx);
314     if (ret < 0) {
315         if (params.ulNumDecodeSurfaces > 32) {
316             av_log(avctx, AV_LOG_WARNING, "Using more than 32 (%d) decode surfaces might cause nvdec to fail.\n",
317                    (int)params.ulNumDecodeSurfaces);
318             av_log(avctx, AV_LOG_WARNING, "Try lowering the amount of threads. Using %d right now.\n",
319                    avctx->thread_count);
320         }
321         return ret;
322     }
323
324     pool = av_mallocz(sizeof(*pool));
325     if (!pool) {
326         ret = AVERROR(ENOMEM);
327         goto fail;
328     }
329     pool->dpb_size = frames_ctx->initial_pool_size;
330
331     ctx->decoder_pool = av_buffer_pool_init2(sizeof(int), pool,
332                                              nvdec_decoder_frame_alloc, av_free);
333     if (!ctx->decoder_pool) {
334         ret = AVERROR(ENOMEM);
335         goto fail;
336     }
337
338     return 0;
339 fail:
340     ff_nvdec_decode_uninit(avctx);
341     return ret;
342 }
343
344 static void nvdec_fdd_priv_free(void *priv)
345 {
346     NVDECFrame *cf = priv;
347
348     if (!cf)
349         return;
350
351     av_buffer_unref(&cf->idx_ref);
352     av_buffer_unref(&cf->decoder_ref);
353
354     av_freep(&priv);
355 }
356
357 static int nvdec_retrieve_data(void *logctx, AVFrame *frame)
358 {
359     FrameDecodeData  *fdd = (FrameDecodeData*)frame->private_ref->data;
360     NVDECFrame        *cf = (NVDECFrame*)fdd->hwaccel_priv;
361     NVDECDecoder *decoder = (NVDECDecoder*)cf->decoder_ref->data;
362
363     CUVIDPROCPARAMS vpp = { .progressive_frame = 1 };
364
365     CUresult err;
366     CUcontext dummy;
367     CUdeviceptr devptr;
368
369     unsigned int pitch, i;
370     unsigned int offset = 0;
371     int ret = 0;
372
373     err = decoder->cudl->cuCtxPushCurrent(decoder->cuda_ctx);
374     if (err != CUDA_SUCCESS)
375         return AVERROR_UNKNOWN;
376
377     err = decoder->cvdl->cuvidMapVideoFrame(decoder->decoder, cf->idx, &devptr,
378                                             &pitch, &vpp);
379     if (err != CUDA_SUCCESS) {
380         av_log(logctx, AV_LOG_ERROR, "Error mapping a picture with CUVID: %d\n",
381                err);
382         ret = AVERROR_UNKNOWN;
383         goto finish;
384     }
385
386     for (i = 0; frame->data[i]; i++) {
387         CUDA_MEMCPY2D cpy = {
388             .srcMemoryType = CU_MEMORYTYPE_DEVICE,
389             .dstMemoryType = CU_MEMORYTYPE_DEVICE,
390             .srcDevice     = devptr,
391             .dstDevice     = (CUdeviceptr)frame->data[i],
392             .srcPitch      = pitch,
393             .dstPitch      = frame->linesize[i],
394             .srcY          = offset,
395             .WidthInBytes  = FFMIN(pitch, frame->linesize[i]),
396             .Height        = frame->height >> (i ? 1 : 0),
397         };
398
399         err = decoder->cudl->cuMemcpy2D(&cpy);
400         if (err != CUDA_SUCCESS) {
401             av_log(logctx, AV_LOG_ERROR, "Error copying decoded frame: %d\n",
402                    err);
403             ret = AVERROR_UNKNOWN;
404             goto copy_fail;
405         }
406
407         offset += cpy.Height;
408     }
409
410 copy_fail:
411     decoder->cvdl->cuvidUnmapVideoFrame(decoder->decoder, devptr);
412
413 finish:
414     decoder->cudl->cuCtxPopCurrent(&dummy);
415     return ret;
416 }
417
418 int ff_nvdec_start_frame(AVCodecContext *avctx, AVFrame *frame)
419 {
420     NVDECContext *ctx = avctx->internal->hwaccel_priv_data;
421     FrameDecodeData *fdd = (FrameDecodeData*)frame->private_ref->data;
422     NVDECFrame *cf = NULL;
423     int ret;
424
425     ctx->bitstream_len = 0;
426     ctx->nb_slices     = 0;
427
428     if (fdd->hwaccel_priv)
429         return 0;
430
431     cf = av_mallocz(sizeof(*cf));
432     if (!cf)
433         return AVERROR(ENOMEM);
434
435     cf->decoder_ref = av_buffer_ref(ctx->decoder_ref);
436     if (!cf->decoder_ref) {
437         ret = AVERROR(ENOMEM);
438         goto fail;
439     }
440
441     cf->idx_ref = av_buffer_pool_get(ctx->decoder_pool);
442     if (!cf->idx_ref) {
443         av_log(avctx, AV_LOG_ERROR, "No decoder surfaces left\n");
444         ret = AVERROR(ENOMEM);
445         goto fail;
446     }
447     cf->idx = *(unsigned int*)cf->idx_ref->data;
448
449     fdd->hwaccel_priv      = cf;
450     fdd->hwaccel_priv_free = nvdec_fdd_priv_free;
451     fdd->post_process      = nvdec_retrieve_data;
452
453     return 0;
454 fail:
455     nvdec_fdd_priv_free(cf);
456     return ret;
457
458 }
459
460 int ff_nvdec_end_frame(AVCodecContext *avctx)
461 {
462     NVDECContext     *ctx = avctx->internal->hwaccel_priv_data;
463     NVDECDecoder *decoder = (NVDECDecoder*)ctx->decoder_ref->data;
464     CUVIDPICPARAMS    *pp = &ctx->pic_params;
465
466     CUresult err;
467     CUcontext dummy;
468
469     int ret = 0;
470
471     pp->nBitstreamDataLen = ctx->bitstream_len;
472     pp->pBitstreamData    = ctx->bitstream;
473     pp->nNumSlices        = ctx->nb_slices;
474     pp->pSliceDataOffsets = ctx->slice_offsets;
475
476     err = decoder->cudl->cuCtxPushCurrent(decoder->cuda_ctx);
477     if (err != CUDA_SUCCESS)
478         return AVERROR_UNKNOWN;
479
480     err = decoder->cvdl->cuvidDecodePicture(decoder->decoder, &ctx->pic_params);
481     if (err != CUDA_SUCCESS) {
482         av_log(avctx, AV_LOG_ERROR, "Error decoding a picture with NVDEC: %d\n",
483                err);
484         ret = AVERROR_UNKNOWN;
485         goto finish;
486     }
487
488 finish:
489     decoder->cudl->cuCtxPopCurrent(&dummy);
490
491     return ret;
492 }
493
494 int ff_nvdec_simple_end_frame(AVCodecContext *avctx)
495 {
496     NVDECContext *ctx = avctx->internal->hwaccel_priv_data;
497     int ret = ff_nvdec_end_frame(avctx);
498     ctx->bitstream = NULL;
499     return ret;
500 }
501
502 int ff_nvdec_simple_decode_slice(AVCodecContext *avctx, const uint8_t *buffer,
503                                  uint32_t size)
504 {
505     NVDECContext *ctx = avctx->internal->hwaccel_priv_data;
506     void *tmp;
507
508     tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated,
509                           (ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets));
510     if (!tmp)
511         return AVERROR(ENOMEM);
512     ctx->slice_offsets = tmp;
513
514     if (!ctx->bitstream)
515         ctx->bitstream = (uint8_t*)buffer;
516
517     ctx->slice_offsets[ctx->nb_slices] = buffer - ctx->bitstream;
518     ctx->bitstream_len += size;
519     ctx->nb_slices++;
520
521     return 0;
522 }
523
524 int ff_nvdec_frame_params(AVCodecContext *avctx,
525                           AVBufferRef *hw_frames_ctx,
526                           int dpb_size)
527 {
528     AVHWFramesContext *frames_ctx = (AVHWFramesContext*)hw_frames_ctx->data;
529     const AVPixFmtDescriptor *sw_desc;
530     int cuvid_codec_type, cuvid_chroma_format;
531
532     sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt);
533     if (!sw_desc)
534         return AVERROR_BUG;
535
536     cuvid_codec_type = map_avcodec_id(avctx->codec_id);
537     if (cuvid_codec_type < 0) {
538         av_log(avctx, AV_LOG_ERROR, "Unsupported codec ID\n");
539         return AVERROR_BUG;
540     }
541
542     cuvid_chroma_format = map_chroma_format(avctx->sw_pix_fmt);
543     if (cuvid_chroma_format < 0) {
544         av_log(avctx, AV_LOG_VERBOSE, "Unsupported chroma format\n");
545         return AVERROR(EINVAL);
546     }
547
548     frames_ctx->format            = AV_PIX_FMT_CUDA;
549     frames_ctx->width             = (avctx->coded_width + 1) & ~1;
550     frames_ctx->height            = (avctx->coded_height + 1) & ~1;
551     frames_ctx->initial_pool_size = dpb_size;
552
553     switch (sw_desc->comp[0].depth) {
554     case 8:
555         frames_ctx->sw_format = AV_PIX_FMT_NV12;
556         break;
557     case 10:
558         frames_ctx->sw_format = AV_PIX_FMT_P010;
559         break;
560     case 12:
561         frames_ctx->sw_format = AV_PIX_FMT_P016;
562         break;
563     default:
564         return AVERROR(EINVAL);
565     }
566
567     return 0;
568 }
569
570 int ff_nvdec_get_ref_idx(AVFrame *frame)
571 {
572     FrameDecodeData *fdd;
573     NVDECFrame *cf;
574
575     if (!frame || !frame->private_ref)
576         return -1;
577
578     fdd = (FrameDecodeData*)frame->private_ref->data;
579     cf  = (NVDECFrame*)fdd->hwaccel_priv;
580     if (!cf)
581         return -1;
582
583     return cf->idx;
584 }