[FFmpeg-cvslog] avcodec/nvdec: check hardware capabilities
Timo Rothenpieler
git at videolan.org
Sun Nov 12 16:52:58 EET 2017
ffmpeg | branch: master | Timo Rothenpieler <timo at rothenpieler.org> | Sat Nov 11 16:08:53 2017 +0100| [c60bc02bf4bc4f6f57fd0fd4c5b2e63253623185] | committer: Timo Rothenpieler
avcodec/nvdec: check hardware capabilities
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=c60bc02bf4bc4f6f57fd0fd4c5b2e63253623185
---
libavcodec/nvdec.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 56 insertions(+)
diff --git a/libavcodec/nvdec.c b/libavcodec/nvdec.c
index 58ebeeb9c1..6287897343 100644
--- a/libavcodec/nvdec.c
+++ b/libavcodec/nvdec.c
@@ -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);
More information about the ffmpeg-cvslog
mailing list