Browse Source

avcodec/nvdec: check hardware capabilities

tags/n4.0
Timo Rothenpieler 8 years ago
parent
commit
c60bc02bf4
1 changed files with 56 additions and 0 deletions
  1. +56
    -0
      libavcodec/nvdec.c

+ 56
- 0
libavcodec/nvdec.c View File

@@ -74,6 +74,56 @@ static int map_chroma_format(enum AVPixelFormat pix_fmt)
return -1;
}

static int nvdec_test_capabilities(NVDECDecoder *decoder,
CUVIDDECODECREATEINFO *params, void *logctx)
{
CUresult err;
CUVIDDECODECAPS caps = { 0 };

caps.eCodecType = params->CodecType;
caps.eChromaFormat = params->ChromaFormat;
caps.nBitDepthMinus8 = params->bitDepthMinus8;

err = decoder->cvdl->cuvidGetDecoderCaps(&caps);
if (err != CUDA_SUCCESS) {
av_log(logctx, AV_LOG_ERROR, "Failed querying decoder capabilities\n");
return AVERROR_UNKNOWN;
}

av_log(logctx, AV_LOG_VERBOSE, "NVDEC capabilities:\n");
av_log(logctx, AV_LOG_VERBOSE, "format supported: %s, max_mb_count: %d\n",
caps.bIsSupported ? "yes" : "no", caps.nMaxMBCount);
av_log(logctx, AV_LOG_VERBOSE, "min_width: %d, max_width: %d\n",
caps.nMinWidth, caps.nMaxWidth);
av_log(logctx, AV_LOG_VERBOSE, "min_height: %d, max_height: %d\n",
caps.nMinHeight, caps.nMaxHeight);

if (!caps.bIsSupported) {
av_log(logctx, AV_LOG_ERROR, "Hardware is lacking required capabilities\n");
return AVERROR(EINVAL);
}

if (params->ulWidth > caps.nMaxWidth || params->ulWidth < caps.nMinWidth) {
av_log(logctx, AV_LOG_ERROR, "Video width %d not within range from %d to %d\n",
(int)params->ulWidth, caps.nMinWidth, caps.nMaxWidth);
return AVERROR(EINVAL);
}

if (params->ulHeight > caps.nMaxHeight || params->ulHeight < caps.nMinHeight) {
av_log(logctx, AV_LOG_ERROR, "Video height %d not within range from %d to %d\n",
(int)params->ulHeight, caps.nMinHeight, caps.nMaxHeight);
return AVERROR(EINVAL);
}

if ((params->ulWidth * params->ulHeight) / 256 > caps.nMaxMBCount) {
av_log(logctx, AV_LOG_ERROR, "Video macroblock count %d exceeds maximum of %d\n",
(int)(params->ulWidth * params->ulHeight) / 256, caps.nMaxMBCount);
return AVERROR(EINVAL);
}

return 0;
}

static void nvdec_decoder_free(void *opaque, uint8_t *data)
{
NVDECDecoder *decoder = (NVDECDecoder*)data;
@@ -132,6 +182,12 @@ static int nvdec_decoder_create(AVBufferRef **out, AVBufferRef *hw_device_ref,
goto fail;
}

ret = nvdec_test_capabilities(decoder, params, logctx);
if (ret < 0) {
decoder->cudl->cuCtxPopCurrent(&dummy);
goto fail;
}

err = decoder->cvdl->cuvidCreateDecoder(&decoder->decoder, params);

decoder->cudl->cuCtxPopCurrent(&dummy);


Loading…
Cancel
Save