LCOV - code coverage report
Current view: top level - libavcodec - nvdec.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 319 0.0 %
Date: 2017-12-15 18:13:28 Functions: 0 16 0.0 %

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

Generated by: LCOV version 1.13