LCOV - code coverage report
Current view: top level - libavcodec - cuviddec.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 625 0.0 %
Date: 2017-12-18 06:23:41 Functions: 0 12 0.0 %

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

Generated by: LCOV version 1.13