Add support for the rocDecGetDecoderCaps API (#21)

* Add support for the rocDecGetDecoderCaps API

* move the RocDecVcnCodecSpec class to a new header file
This commit is contained in:
Aryan Salmanpour
2023-10-24 08:40:58 -04:00
committed by GitHub
parent 1a06c45b7d
commit bf830a2678
4 changed files with 140 additions and 4 deletions
+2
View File
@@ -145,6 +145,8 @@ typedef enum rocDecodeStatus_enum {
//! This structure is used in rocDecGetDecoderCaps API
/**************************************************************************************************************/
typedef struct _RocdecDecodeCaps {
uint8_t deviceid; /**< IN: the device id for which query the decode capability
0 for the first device, 1 for the second device on the system, etc.*/
rocDecVideoCodec eCodecType; /**< IN: rocDecVideoCodec_XXX */
rocDecVideoChromaFormat eChromaFormat; /**< IN: rocDecVideoChromaFormat_XXX */
uint32_t nBitDepthMinus8; /**< IN: The Value "BitDepth minus 8" */
+1 -3
View File
@@ -33,7 +33,6 @@ THE SOFTWARE.
#include "../api/rocdecode.h"
#include <hip/hip_runtime.h>
class RocDecoder {
public:
RocDecoder(int device_id = 0);
@@ -47,10 +46,9 @@ public:
private:
rocDecStatus initHIP(int device_id);
void initDRMnodes();
int num_devices_;
int device_id_;
hipDeviceProp_t hip_dev_prop_;
hipStream_t hip_stream_;
std::vector<std::string> drm_nodes_;
};
};
+108
View File
@@ -0,0 +1,108 @@
/*
Copyright (c) 2023 - 2023 Advanced Micro Devices, Inc. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#pragma once
#include <vector>
#include <string>
#include <unordered_map>
#include <mutex>
#include "../commons.h"
#include "../../api/rocdecode.h"
// The CodecSpec struct contains information for an individual codec (e.g., rocDecVideoCodec_HEVC)
struct CodecSpec {
std::vector<rocDecVideoChromaFormat> chroma_format;
std::vector<int> bitdepth_minus8;
uint16_t output_format_mask;
uint32_t max_width;
uint32_t max_height;
uint16_t min_width;
uint16_t min_height;
};
// The VcnCodecsSpec struct contains information for all supported codecs and number of vcn instances per device
struct VcnCodecsSpec {
std::unordered_map<rocDecVideoCodec, CodecSpec> codecs_spec;
uint8_t num_decoders;
};
// The RocDecVcnCodecSpec singleton class for providing access to the the vcn_spec_table
class RocDecVcnCodecSpec {
public:
static RocDecVcnCodecSpec& GetInastance() {
static RocDecVcnCodecSpec instance;
return instance;
}
rocDecStatus GetDecoderCaps(std::string gcn_arch_name, RocdecDecodeCaps *pdc) {
std::lock_guard<std::mutex> lock(mutex);
auto it = vcn_spec_table.find(gcn_arch_name);
if (it != vcn_spec_table.end()) {
const VcnCodecsSpec& vcn_spec = it->second;
auto it1 = vcn_spec.codecs_spec.find(pdc->eCodecType);
if (it1 != vcn_spec.codecs_spec.end()) {
const CodecSpec& codec_spec = it1->second;
auto it_chroma_format = std::find(codec_spec.chroma_format.begin(), codec_spec.chroma_format.end(), pdc->eChromaFormat);
auto it_bitdepth_minus8 = std::find(codec_spec.bitdepth_minus8.begin(), codec_spec.bitdepth_minus8.end(), pdc->nBitDepthMinus8);
if (it_chroma_format != codec_spec.chroma_format.end() && it_bitdepth_minus8 != codec_spec.bitdepth_minus8.end()) {
pdc->bIsSupported = 1;
pdc->nNumDecoders = vcn_spec.num_decoders;
pdc->nOutputFormatMask = codec_spec.output_format_mask;
pdc->nMaxWidth = codec_spec.max_width;
pdc->nMaxHeight = codec_spec.max_height;
pdc->nMinWidth = codec_spec.min_width;
pdc->nMinHeight = codec_spec.min_height;
return ROCDEC_SUCCESS;
} else {
return ROCDEC_NOT_SUPPORTED;
}
} else {
return ROCDEC_NOT_SUPPORTED;
}
} else {
return ROCDEC_DEVICE_INVALID;
}
}
private:
std::unordered_map<std::string, VcnCodecsSpec> vcn_spec_table;
std::mutex mutex;
RocDecVcnCodecSpec() {
//vcn lookup table format:
//{"gcn_arch_name1",{{{codec1, {{chroma_format1_for_codec1, chroma_format2_for_codec1, ...}, {bit_depth1_minus8_for_codec1, bit_depth2_minus8_for_codec1, ...}, output_format_mask_for_codec1, max_width_for_codec1, max_height_for_codec1, min_width_for_codec1, min_height_for_codec1}},
// {codec2, {{chroma_format1_for_codec2, chroma_format2_for_codec2, ...}, {bit_depth1_minus8_for_codec2, bit_depth2_minus8_for_codec2, ...}, output_format_mask_for_codec2, max_width_for_codec2, max_height_for_codec2, min_width_for_codec2, min_height_for_codec2}}}
// , vcn_instances_for_gcn_arch_name1}},
vcn_spec_table = {
{"gfx803",{}},
{"gfx900",{}},
{"gfx906",{}},
{"gfx908",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 4096, 2176, 64, 64}}, {rocDecVideoCodec_H264, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2160, 64, 64}}}, 2}},
{"gfx90a",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 4096, 2176, 64, 64}}, {rocDecVideoCodec_H264, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2160, 64, 64}}}, 2}},
{"gfx940",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_H264, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}}, 3}},
{"gfx941",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_H264, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}}, 4}},
{"gfx1030",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_H264, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}}, 2}},
{"gfx1031",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_H264, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}}, 2}},
{"gfx1032",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_H264, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}}, 2}},};
}
RocDecVcnCodecSpec(const RocDecVcnCodecSpec&) = delete;
RocDecVcnCodecSpec& operator = (const RocDecVcnCodecSpec) = delete;
~RocDecVcnCodecSpec() = default;
};
+29 -1
View File
@@ -21,8 +21,10 @@ THE SOFTWARE.
*/
#include "dec_handle.h"
#include "rocdecode.h"
#include "roc_decoder_caps.h"
#include "../commons.h"
/*****************************************************************************************************/
//! \fn rocDecStatus ROCDECAPI rocDecCreateDecoder(rocDecDecoderHandle *phDecoder, RocdecDecoderCreateInfo *pdci)
//! Create the decoder object based on pdci. A handle to the created decoder is returned
@@ -60,7 +62,33 @@ rocDecDestroyDecoder(rocDecDecoderHandle hDecoder) {
/**********************************************************************************************************************/
rocDecStatus ROCDECAPI
rocDecGetDecoderCaps(RocdecDecodeCaps *pdc) {
return ROCDEC_NOT_IMPLEMENTED;
if (pdc == nullptr) {
return ROCDEC_INVALID_PARAMETER;
}
hipError_t hip_status = hipSuccess;
int num_devices = 0;
hipDeviceProp_t hip_dev_prop;
hip_status = hipGetDeviceCount(&num_devices);
if (hip_status != hipSuccess) {
ERR("ERROR: hipGetDeviceCount failed!" + TOSTR(hip_status));
return ROCDEC_DEVICE_INVALID;
}
if (num_devices < 1) {
ERR("ERROR: didn't find any GPU!");
return ROCDEC_DEVICE_INVALID;
}
if (pdc->deviceid >= num_devices) {
ERR("ERROR: the requested device_id is not found! ");
return ROCDEC_DEVICE_INVALID;
}
hip_status = hipGetDeviceProperties(&hip_dev_prop, pdc->deviceid);
if (hip_status != hipSuccess) {
ERR("ERROR: hipGetDeviceProperties for device (" +TOSTR(pdc->deviceid) + " ) failed! (" + TOSTR(hip_status) + ")" );
return ROCDEC_DEVICE_INVALID;
}
RocDecVcnCodecSpec& vcn_codec_spec = RocDecVcnCodecSpec::GetInastance();
return vcn_codec_spec.GetDecoderCaps(hip_dev_prop.gcnArchName, pdc);
}
/*****************************************************************************************************/