Added the new GPU VA context class to handle VA connections to GPU. Removed the hard coded HW decoder capability info. (#415)
* * rocDecode: Removed the hard coded HW decoder capability info. - We now probe HW decoder capabilities through VA-API from the driver. * * rocDecode: Added number of decoder prob and a few missing tear down calls. * * rocDecode/HW cap change: Added a new singleton class, GpuVaContext, to handle HIP and VA initialization and VA attributes probe for both HW capability check and decoder initialization. * * rocDecode/HW caps: Removed GpuVaContext class out of vaapi_videodecoder.h and into a new file. Removed debug logs. Removed roc_decoder_caps.h. * * rocDecode/HW caps: Fixed a crash issue with multi-thread cases. Called to vaInitialize() and vaTerminte() should be paired. * * rocDecode/HW caps: Added multi-GPU support. * * rocDecode/HW cap: Moved GpuVaContext class implementation back to VAAPI layer. * * rocDecode/HW cap: Added changed based on review comments. * * rocDecode/HW cap: Added changes based on review comments. * * rocDecode/HW cap: GPU VA context class name change based on review comment. --------- Co-authored-by: Kiriti Gowda <kiritigowda@gmail.com>
This commit is contained in:
@@ -45,11 +45,6 @@ RocDecoder::RocDecoder(RocDecoderCreateInfo& decoder_create_info): va_video_deco
|
||||
|
||||
rocDecStatus RocDecoder::InitializeDecoder() {
|
||||
rocDecStatus rocdec_status = ROCDEC_SUCCESS;
|
||||
rocdec_status = InitHIP(decoder_create_info_.device_id);
|
||||
if (rocdec_status != ROCDEC_SUCCESS) {
|
||||
ERR("Failed to initilize the HIP.");
|
||||
return rocdec_status;
|
||||
}
|
||||
if (decoder_create_info_.num_decode_surfaces < 1) {
|
||||
ERR("Invalid number of decode surfaces.");
|
||||
return ROCDEC_INVALID_PARAMETER;
|
||||
@@ -58,8 +53,7 @@ RocDecoder::RocDecoder(RocDecoderCreateInfo& decoder_create_info): va_video_deco
|
||||
for (auto i = 0; i < hip_interop_.size(); i++) {
|
||||
memset((void *)&hip_interop_[i], 0, sizeof(hip_interop_[i]));
|
||||
}
|
||||
std::string gpu_uuid(hip_dev_prop_.uuid.bytes, sizeof(hip_dev_prop_.uuid.bytes));
|
||||
rocdec_status = va_video_decoder_.InitializeDecoder(hip_dev_prop_.name, hip_dev_prop_.gcnArchName, gpu_uuid);
|
||||
rocdec_status = va_video_decoder_.InitializeDecoder();
|
||||
if (rocdec_status != ROCDEC_SUCCESS) {
|
||||
ERR("Failed to initilize the VAAPI Video decoder.");
|
||||
return rocdec_status;
|
||||
@@ -186,16 +180,3 @@ rocDecStatus RocDecoder::FreeVideoFrame(int pic_idx) {
|
||||
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
rocDecStatus RocDecoder::InitHIP(int device_id) {
|
||||
CHECK_HIP(hipGetDeviceCount(&num_devices_));
|
||||
if (num_devices_ < 1) {
|
||||
ERR("Didn't find any GPU.");
|
||||
return ROCDEC_DEVICE_INVALID;
|
||||
}
|
||||
CHECK_HIP(hipSetDevice(device_id));
|
||||
CHECK_HIP(hipGetDeviceProperties(&hip_dev_prop_, device_id));
|
||||
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -34,14 +34,6 @@ THE SOFTWARE.
|
||||
#include <hip/hip_runtime.h>
|
||||
#include "vaapi/vaapi_videodecoder.h"
|
||||
|
||||
#define CHECK_HIP(call) {\
|
||||
hipError_t hip_status = call;\
|
||||
if (hip_status != hipSuccess) {\
|
||||
std::cout << "HIP failure: " << #call << " failed with 'status: " << hipGetErrorName(hip_status) << "' at " << __FILE__ << ":" << __LINE__ << std::endl;\
|
||||
return ROCDEC_RUNTIME_ERROR;\
|
||||
}\
|
||||
}
|
||||
|
||||
struct HipInteropDeviceMem {
|
||||
hipExternalMemory_t hip_ext_mem; // Interface to the vaapi-hip interop
|
||||
uint8_t* hip_mapped_device_mem; // Mapped device memory for the YUV plane
|
||||
@@ -63,11 +55,9 @@ public:
|
||||
rocDecStatus GetVideoFrame(int pic_idx, void *dev_mem_ptr[3], uint32_t horizontal_pitch[3], RocdecProcParams *vid_postproc_params);
|
||||
|
||||
private:
|
||||
rocDecStatus InitHIP(int device_id);
|
||||
rocDecStatus FreeVideoFrame(int pic_idx);
|
||||
int num_devices_;
|
||||
RocDecoderCreateInfo decoder_create_info_;
|
||||
VaapiVideoDecoder va_video_decoder_;
|
||||
hipDeviceProp_t hip_dev_prop_;
|
||||
std::vector<HipInteropDeviceMem> hip_interop_;
|
||||
};
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2023 - 2025 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 <algorithm>
|
||||
#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& GetInstance() {
|
||||
static RocDecVcnCodecSpec instance;
|
||||
return instance;
|
||||
}
|
||||
rocDecStatus GetDecoderCaps(std::string gcn_arch_name, RocdecDecodeCaps *pdc) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::size_t pos = gcn_arch_name.find_first_of(":");
|
||||
std::string gcn_arch_name_base = (pos != std::string::npos) ? gcn_arch_name.substr(0, pos) : gcn_arch_name;
|
||||
auto it = vcn_spec_table.find(gcn_arch_name_base);
|
||||
if (it != vcn_spec_table.end()) {
|
||||
const VcnCodecsSpec& vcn_spec = it->second;
|
||||
auto it1 = vcn_spec.codecs_spec.find(pdc->codec_type);
|
||||
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->chroma_format);
|
||||
auto it_bitdepth_minus8 = std::find(codec_spec.bitdepth_minus8.begin(), codec_spec.bitdepth_minus8.end(), pdc->bit_depth_minus_8);
|
||||
if (it_chroma_format != codec_spec.chroma_format.end() && it_bitdepth_minus8 != codec_spec.bitdepth_minus8.end()) {
|
||||
pdc->is_supported = 1;
|
||||
pdc->num_decoders = vcn_spec.num_decoders;
|
||||
pdc->output_format_mask = codec_spec.output_format_mask;
|
||||
pdc->max_width = codec_spec.max_width;
|
||||
pdc->max_height = codec_spec.max_height;
|
||||
pdc->min_width = codec_spec.min_width;
|
||||
pdc->min_height = codec_spec.min_height;
|
||||
return ROCDEC_SUCCESS;
|
||||
} else {
|
||||
return ROCDEC_NOT_SUPPORTED;
|
||||
}
|
||||
} else {
|
||||
return ROCDEC_NOT_SUPPORTED;
|
||||
}
|
||||
} else {
|
||||
ERR("Didn't find the decoder capability for " + gcn_arch_name + " GPU!");
|
||||
return ROCDEC_NOT_IMPLEMENTED;
|
||||
}
|
||||
}
|
||||
bool IsCodecConfigSupported(std::string gcn_arch_name, rocDecVideoCodec codec_type, rocDecVideoChromaFormat chroma_format, uint32_t bit_depth_minus8, rocDecVideoSurfaceFormat output_format) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
std::size_t pos = gcn_arch_name.find_first_of(":");
|
||||
std::string gcn_arch_name_base = (pos != std::string::npos) ? gcn_arch_name.substr(0, pos) : gcn_arch_name;
|
||||
auto it = vcn_spec_table.find(gcn_arch_name_base);
|
||||
if (it != vcn_spec_table.end()) {
|
||||
const VcnCodecsSpec& vcn_spec = it->second;
|
||||
auto it1 = vcn_spec.codecs_spec.find(codec_type);
|
||||
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(), chroma_format);
|
||||
auto it_bitdepth_minus8 = std::find(codec_spec.bitdepth_minus8.begin(), codec_spec.bitdepth_minus8.end(), bit_depth_minus8);
|
||||
if (it_chroma_format != codec_spec.chroma_format.end() && it_bitdepth_minus8 != codec_spec.bitdepth_minus8.end()) {
|
||||
return (codec_spec.output_format_mask & (static_cast<int>(output_format) + 1));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
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}},
|
||||
// av1 is available only on VCN3.0 and above
|
||||
vcn_spec_table = {
|
||||
{"gfx908",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AVC, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2160, 64, 64}}, {rocDecVideoCodec_VP9, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}}, 2}},
|
||||
{"gfx90a",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AVC, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2160, 64, 64}}, {rocDecVideoCodec_VP9, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}}, 2}},
|
||||
{"gfx940",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AVC, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}, {rocDecVideoCodec_VP9, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AV1, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 8192, 4352, 64, 64}}}, 3}},
|
||||
{"gfx941",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AVC, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}, {rocDecVideoCodec_VP9, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AV1, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 8192, 4352, 64, 64}}}, 4}},
|
||||
{"gfx942",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AVC, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}, {rocDecVideoCodec_VP9, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AV1, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 8192, 4352, 64, 64}}}, 3}},
|
||||
{"gfx1030",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AVC, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}, {rocDecVideoCodec_VP9, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AV1, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 8192, 4352, 64, 64}}}, 2}},
|
||||
{"gfx1031",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AVC, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}, {rocDecVideoCodec_VP9, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AV1, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 8192, 4352, 64, 64}}}, 2}},
|
||||
{"gfx1032",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AVC, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}, {rocDecVideoCodec_VP9, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AV1, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 8192, 4352, 64, 64}}}, 2}},
|
||||
{"gfx1100",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AVC, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}, {rocDecVideoCodec_VP9, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AV1, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 8192, 4352, 64, 64}}}, 2}},
|
||||
{"gfx1101",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AVC, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}, {rocDecVideoCodec_VP9, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AV1, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 8192, 4352, 64, 64}}}, 1}},
|
||||
{"gfx1102",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AVC, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}, {rocDecVideoCodec_VP9, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AV1, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 8192, 4352, 64, 64}}}, 2}},
|
||||
{"gfx1200",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AVC, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}, {rocDecVideoCodec_VP9, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 8192, 4352, 64, 64}}, {rocDecVideoCodec_AV1, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 8192, 4352, 64, 64}}}, 2}},
|
||||
{"gfx1201",{{{rocDecVideoCodec_HEVC, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 7680, 4320, 64, 64}}, {rocDecVideoCodec_AVC, {{rocDecVideoChromaFormat_420}, {0}, 1, 4096, 2176, 64, 64}}, {rocDecVideoCodec_VP9, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 8192, 4352, 64, 64}}, {rocDecVideoCodec_AV1, {{rocDecVideoChromaFormat_420}, {0, 2}, 3, 8192, 4352, 64, 64}}}, 2}},
|
||||
};
|
||||
}
|
||||
RocDecVcnCodecSpec(const RocDecVcnCodecSpec&) = delete;
|
||||
RocDecVcnCodecSpec& operator = (const RocDecVcnCodecSpec) = delete;
|
||||
~RocDecVcnCodecSpec() = default;
|
||||
};
|
||||
@@ -21,7 +21,7 @@ THE SOFTWARE.
|
||||
*/
|
||||
#include "dec_handle.h"
|
||||
#include "rocdecode.h"
|
||||
#include "roc_decoder_caps.h"
|
||||
#include "vaapi_videodecoder.h"
|
||||
#include "../commons.h"
|
||||
|
||||
namespace rocdecode {
|
||||
@@ -72,30 +72,14 @@ rocDecGetDecoderCaps(RocdecDecodeCaps *pdc) {
|
||||
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;
|
||||
VaContext& va_ctx = VaContext::GetInstance();
|
||||
rocDecStatus ret = ROCDEC_SUCCESS;
|
||||
if ((ret = va_ctx.CheckDecCapForCodecType(pdc)) != ROCDEC_SUCCESS) {
|
||||
ERR("Failed to obtain decoder capabilities from driver.");
|
||||
return ret;
|
||||
} else {
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
if (num_devices < 1) {
|
||||
ERR("ERROR: didn't find any GPU!");
|
||||
return ROCDEC_DEVICE_INVALID;
|
||||
}
|
||||
if (pdc->device_id >= num_devices) {
|
||||
ERR("ERROR: the requested device_id is not found! ");
|
||||
return ROCDEC_DEVICE_INVALID;
|
||||
}
|
||||
hip_status = hipGetDeviceProperties(&hip_dev_prop, pdc->device_id);
|
||||
if (hip_status != hipSuccess) {
|
||||
ERR("ERROR: hipGetDeviceProperties for device (" +TOSTR(pdc->device_id) + " ) failed! (" + TOSTR(hip_status) + ")" );
|
||||
return ROCDEC_DEVICE_INVALID;
|
||||
}
|
||||
|
||||
RocDecVcnCodecSpec& vcn_codec_spec = RocDecVcnCodecSpec::GetInstance();
|
||||
return vcn_codec_spec.GetDecoderCaps(hip_dev_prop.gcnArchName, pdc);
|
||||
}
|
||||
|
||||
/*****************************************************************************************************/
|
||||
|
||||
@@ -52,46 +52,27 @@ VaapiVideoDecoder::~VaapiVideoDecoder() {
|
||||
if (va_status != VA_STATUS_SUCCESS) {
|
||||
ERR("vaDestroyConfig failed");
|
||||
}
|
||||
va_status = vaTerminate(va_display_);
|
||||
if (va_status != VA_STATUS_SUCCESS) {
|
||||
ERR("vaTerminate failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rocDecStatus VaapiVideoDecoder::InitializeDecoder(std::string device_name, std::string gcn_arch_name, std::string& gpu_uuid) {
|
||||
rocDecStatus VaapiVideoDecoder::InitializeDecoder() {
|
||||
rocDecStatus rocdec_status = ROCDEC_SUCCESS;
|
||||
|
||||
//Before initializing the VAAPI, first check to see if the requested codec config is supported
|
||||
RocDecVcnCodecSpec& vcn_codec_spec = RocDecVcnCodecSpec::GetInstance();
|
||||
if (!vcn_codec_spec.IsCodecConfigSupported(gcn_arch_name, decoder_create_info_.codec_type, decoder_create_info_.chroma_format,
|
||||
// Before initializing the VAAPI, first check to see if the requested codec config is supported
|
||||
if (!IsCodecConfigSupported(decoder_create_info_.device_id, decoder_create_info_.codec_type, decoder_create_info_.chroma_format,
|
||||
decoder_create_info_.bit_depth_minus_8, decoder_create_info_.output_format)) {
|
||||
ERR("The codec config combination is not supported.");
|
||||
return ROCDEC_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
std::size_t pos = gcn_arch_name.find_first_of(":");
|
||||
std::string gcn_arch_name_base = (pos != std::string::npos) ? gcn_arch_name.substr(0, pos) : gcn_arch_name;
|
||||
|
||||
std::vector<int> visible_devices;
|
||||
GetVisibleDevices(visible_devices);
|
||||
GetGpuUuids();
|
||||
int offset = 0;
|
||||
if (gcn_arch_name_base.compare("gfx942") == 0) {
|
||||
std::vector<ComputePartition> current_compute_partitions;
|
||||
GetCurrentComputePartition(current_compute_partitions);
|
||||
if (!current_compute_partitions.empty()) {
|
||||
GetDrmNodeOffset(device_name, decoder_create_info_.device_id, visible_devices, current_compute_partitions, offset);
|
||||
}
|
||||
}
|
||||
|
||||
std::string drm_node = "/dev/dri/renderD";
|
||||
int render_node_id = (gpu_uuids_to_render_nodes_map_.find(gpu_uuid) != gpu_uuids_to_render_nodes_map_.end()) ? gpu_uuids_to_render_nodes_map_[gpu_uuid] : 128;
|
||||
drm_node += std::to_string(render_node_id + offset);
|
||||
|
||||
rocdec_status = InitVAAPI(drm_node);
|
||||
if (rocdec_status != ROCDEC_SUCCESS) {
|
||||
ERR("Failed to initilize the VAAPI.");
|
||||
VaContext& va_ctx = VaContext::GetInstance();
|
||||
uint32_t va_ctx_id;
|
||||
if ((rocdec_status = va_ctx.GetVaContext(decoder_create_info_.device_id, &va_ctx_id)) != ROCDEC_SUCCESS) {
|
||||
ERR("Failed to get VA context.");
|
||||
return rocdec_status;
|
||||
}
|
||||
if ((rocdec_status = va_ctx.GetVaDisplay(va_ctx_id, &va_display_)) != ROCDEC_SUCCESS) {
|
||||
ERR("Failed to get VA display.");
|
||||
return rocdec_status;
|
||||
}
|
||||
rocdec_status = CreateDecoderConfig();
|
||||
@@ -112,157 +93,6 @@ rocDecStatus VaapiVideoDecoder::InitializeDecoder(std::string device_name, std::
|
||||
return rocdec_status;
|
||||
}
|
||||
|
||||
rocDecStatus VaapiVideoDecoder::InitVAAPI(std::string drm_node) {
|
||||
drm_fd_ = open(drm_node.c_str(), O_RDWR);
|
||||
if (drm_fd_ < 0) {
|
||||
ERR("Failed to open drm node." + drm_node);
|
||||
return ROCDEC_NOT_INITIALIZED;
|
||||
}
|
||||
va_display_ = vaGetDisplayDRM(drm_fd_);
|
||||
if (!va_display_) {
|
||||
ERR("Failed to create va_display.");
|
||||
return ROCDEC_NOT_INITIALIZED;
|
||||
}
|
||||
vaSetInfoCallback(va_display_, NULL, NULL);
|
||||
int major_version = 0, minor_version = 0;
|
||||
CHECK_VAAPI(vaInitialize(va_display_, &major_version, &minor_version));
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
rocDecStatus VaapiVideoDecoder::CreateDecoderConfig() {
|
||||
switch (decoder_create_info_.codec_type) {
|
||||
case rocDecVideoCodec_HEVC:
|
||||
if (decoder_create_info_.bit_depth_minus_8 == 0) {
|
||||
va_profile_ = VAProfileHEVCMain;
|
||||
} else if (decoder_create_info_.bit_depth_minus_8 == 2) {
|
||||
va_profile_ = VAProfileHEVCMain10;
|
||||
}
|
||||
break;
|
||||
case rocDecVideoCodec_AVC:
|
||||
va_profile_ = VAProfileH264Main;
|
||||
break;
|
||||
case rocDecVideoCodec_VP9:
|
||||
if (decoder_create_info_.bit_depth_minus_8 == 0) {
|
||||
va_profile_ = VAProfileVP9Profile0;
|
||||
} else if (decoder_create_info_.bit_depth_minus_8 == 2) {
|
||||
va_profile_ = VAProfileVP9Profile2;
|
||||
}
|
||||
break;
|
||||
case rocDecVideoCodec_AV1:
|
||||
#if VA_CHECK_VERSION(1,6,0)
|
||||
va_profile_ = VAProfileAV1Profile0;
|
||||
#else
|
||||
va_profile_ = static_cast<VAProfile>(32); // VAProfileAV1Profile0;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
ERR("The codec type is not supported.");
|
||||
return ROCDEC_NOT_SUPPORTED;
|
||||
}
|
||||
va_config_attrib_.type = VAConfigAttribRTFormat;
|
||||
CHECK_VAAPI(vaGetConfigAttributes(va_display_, va_profile_, VAEntrypointVLD, &va_config_attrib_, 1));
|
||||
CHECK_VAAPI(vaCreateConfig(va_display_, va_profile_, VAEntrypointVLD, &va_config_attrib_, 1, &va_config_id_));
|
||||
unsigned int num_attribs = 0;
|
||||
CHECK_VAAPI(vaQuerySurfaceAttributes(va_display_, va_config_id_, nullptr, &num_attribs));
|
||||
std::vector<VASurfaceAttrib> attribs(num_attribs);
|
||||
CHECK_VAAPI(vaQuerySurfaceAttributes(va_display_, va_config_id_, attribs.data(), &num_attribs));
|
||||
for (auto attrib : attribs) {
|
||||
if (attrib.type == VASurfaceAttribDRMFormatModifiers) {
|
||||
supports_modifiers_ = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
rocDecStatus VaapiVideoDecoder::CreateSurfaces() {
|
||||
if (decoder_create_info_.num_decode_surfaces < 1) {
|
||||
ERR("Invalid number of decode surfaces.");
|
||||
return ROCDEC_INVALID_PARAMETER;
|
||||
}
|
||||
va_surface_ids_.resize(decoder_create_info_.num_decode_surfaces);
|
||||
std::vector<VASurfaceAttrib> surf_attribs;
|
||||
VASurfaceAttrib surf_attrib;
|
||||
surf_attrib.type = VASurfaceAttribPixelFormat;
|
||||
surf_attrib.flags = VA_SURFACE_ATTRIB_SETTABLE;
|
||||
surf_attrib.value.type = VAGenericValueTypeInteger;
|
||||
uint32_t surface_format;
|
||||
switch (decoder_create_info_.chroma_format) {
|
||||
case rocDecVideoChromaFormat_Monochrome:
|
||||
surface_format = VA_RT_FORMAT_YUV400;
|
||||
surf_attrib.value.value.i = VA_FOURCC_Y800;
|
||||
break;
|
||||
case rocDecVideoChromaFormat_420:
|
||||
if (decoder_create_info_.bit_depth_minus_8 == 2) {
|
||||
surface_format = VA_RT_FORMAT_YUV420_10;
|
||||
surf_attrib.value.value.i = VA_FOURCC_P010;
|
||||
} else if (decoder_create_info_.bit_depth_minus_8 == 4) {
|
||||
surface_format = VA_RT_FORMAT_YUV420_12;
|
||||
#if VA_CHECK_VERSION(1,8,0)
|
||||
surf_attrib.value.value.i = VA_FOURCC_P012;
|
||||
#else
|
||||
surf_attrib.value.value.i = 0x32313050; // VA_FOURCC_P012
|
||||
#endif
|
||||
} else {
|
||||
surface_format = VA_RT_FORMAT_YUV420;
|
||||
surf_attrib.value.value.i = VA_FOURCC_NV12;
|
||||
}
|
||||
break;
|
||||
case rocDecVideoChromaFormat_422:
|
||||
surface_format = VA_RT_FORMAT_YUV422;
|
||||
break;
|
||||
case rocDecVideoChromaFormat_444:
|
||||
surface_format = VA_RT_FORMAT_YUV444;
|
||||
break;
|
||||
default:
|
||||
ERR("The surface type is not supported");
|
||||
return ROCDEC_NOT_SUPPORTED;
|
||||
}
|
||||
surf_attribs.push_back(surf_attrib);
|
||||
uint64_t mod_linear = 0;
|
||||
VADRMFormatModifierList modifier_list = {
|
||||
.num_modifiers = 1,
|
||||
.modifiers = &mod_linear,
|
||||
};
|
||||
if (supports_modifiers_) {
|
||||
surf_attrib.type = VASurfaceAttribDRMFormatModifiers;
|
||||
surf_attrib.value.type = VAGenericValueTypePointer;
|
||||
surf_attrib.value.value.p = &modifier_list;
|
||||
surf_attribs.push_back(surf_attrib);
|
||||
}
|
||||
CHECK_VAAPI(vaCreateSurfaces(va_display_, surface_format, decoder_create_info_.width,
|
||||
decoder_create_info_.height, va_surface_ids_.data(), va_surface_ids_.size(), surf_attribs.data(), surf_attribs.size()));
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
rocDecStatus VaapiVideoDecoder::CreateContext() {
|
||||
CHECK_VAAPI(vaCreateContext(va_display_, va_config_id_, decoder_create_info_.width, decoder_create_info_.height,
|
||||
VA_PROGRESSIVE, va_surface_ids_.data(), va_surface_ids_.size(), &va_context_id_));
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
rocDecStatus VaapiVideoDecoder::DestroyDataBuffers() {
|
||||
if (pic_params_buf_id_) {
|
||||
CHECK_VAAPI(vaDestroyBuffer(va_display_, pic_params_buf_id_));
|
||||
pic_params_buf_id_ = 0;
|
||||
}
|
||||
if (iq_matrix_buf_id_) {
|
||||
CHECK_VAAPI(vaDestroyBuffer(va_display_, iq_matrix_buf_id_));
|
||||
iq_matrix_buf_id_ = 0;
|
||||
}
|
||||
for (int i = 0; i < num_slices_; i++) {
|
||||
if (slice_params_buf_id_[i]) {
|
||||
CHECK_VAAPI(vaDestroyBuffer(va_display_, slice_params_buf_id_[i]));
|
||||
slice_params_buf_id_[i] = 0;
|
||||
}
|
||||
}
|
||||
if (slice_data_buf_id_) {
|
||||
CHECK_VAAPI(vaDestroyBuffer(va_display_, slice_data_buf_id_));
|
||||
slice_data_buf_id_ = 0;
|
||||
}
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
rocDecStatus VaapiVideoDecoder::SubmitDecode(RocdecPicParams *pPicParams) {
|
||||
void *pic_params_ptr, *iq_matrix_ptr, *slice_params_ptr;
|
||||
uint32_t pic_params_size, iq_matrix_size, slice_params_size;
|
||||
@@ -483,6 +313,18 @@ rocDecStatus VaapiVideoDecoder::ExportSurface(int pic_idx, VADRMPRIMESurfaceDesc
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
rocDecStatus VaapiVideoDecoder::SyncSurface(int pic_idx) {
|
||||
if (pic_idx >= va_surface_ids_.size()) {
|
||||
return ROCDEC_INVALID_PARAMETER;
|
||||
}
|
||||
VASurfaceStatus surface_status;
|
||||
CHECK_VAAPI(vaQuerySurfaceStatus(va_display_, va_surface_ids_[pic_idx], &surface_status));
|
||||
if (surface_status != VASurfaceReady) {
|
||||
CHECK_VAAPI(vaSyncSurface(va_display_, va_surface_ids_[pic_idx]));
|
||||
}
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
rocDecStatus VaapiVideoDecoder::ReconfigureDecoder(RocdecReconfigureDecoderInfo *reconfig_params) {
|
||||
if (reconfig_params == nullptr) {
|
||||
return ROCDEC_INVALID_PARAMETER;
|
||||
@@ -514,19 +356,480 @@ rocDecStatus VaapiVideoDecoder::ReconfigureDecoder(RocdecReconfigureDecoderInfo
|
||||
return rocdec_status;
|
||||
}
|
||||
|
||||
rocDecStatus VaapiVideoDecoder::SyncSurface(int pic_idx) {
|
||||
if (pic_idx >= va_surface_ids_.size()) {
|
||||
return ROCDEC_INVALID_PARAMETER;
|
||||
bool VaapiVideoDecoder::IsCodecConfigSupported(int device_id, rocDecVideoCodec codec_type, rocDecVideoChromaFormat chroma_format, uint32_t bit_depth_minus8, rocDecVideoSurfaceFormat output_format) {
|
||||
RocdecDecodeCaps decode_caps;
|
||||
decode_caps.device_id = device_id;
|
||||
decode_caps.codec_type = codec_type;
|
||||
decode_caps.chroma_format = chroma_format;
|
||||
decode_caps.bit_depth_minus_8 = bit_depth_minus8;
|
||||
if((rocDecGetDecoderCaps(&decode_caps) != ROCDEC_SUCCESS) || (decode_caps.is_supported == false) || ((decode_caps.output_format_mask & (1 << output_format)) == 0)) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
VASurfaceStatus surface_status;
|
||||
CHECK_VAAPI(vaQuerySurfaceStatus(va_display_, va_surface_ids_[pic_idx], &surface_status));
|
||||
if (surface_status != VASurfaceReady) {
|
||||
CHECK_VAAPI(vaSyncSurface(va_display_, va_surface_ids_[pic_idx]));
|
||||
}
|
||||
|
||||
rocDecStatus VaapiVideoDecoder::CreateDecoderConfig() {
|
||||
switch (decoder_create_info_.codec_type) {
|
||||
case rocDecVideoCodec_HEVC:
|
||||
if (decoder_create_info_.bit_depth_minus_8 == 0) {
|
||||
va_profile_ = VAProfileHEVCMain;
|
||||
} else if (decoder_create_info_.bit_depth_minus_8 == 2) {
|
||||
va_profile_ = VAProfileHEVCMain10;
|
||||
}
|
||||
break;
|
||||
case rocDecVideoCodec_AVC:
|
||||
va_profile_ = VAProfileH264Main;
|
||||
break;
|
||||
case rocDecVideoCodec_VP9:
|
||||
if (decoder_create_info_.bit_depth_minus_8 == 0) {
|
||||
va_profile_ = VAProfileVP9Profile0;
|
||||
} else if (decoder_create_info_.bit_depth_minus_8 == 2) {
|
||||
va_profile_ = VAProfileVP9Profile2;
|
||||
}
|
||||
break;
|
||||
case rocDecVideoCodec_AV1:
|
||||
#if VA_CHECK_VERSION(1,6,0)
|
||||
va_profile_ = VAProfileAV1Profile0;
|
||||
#else
|
||||
va_profile_ = static_cast<VAProfile>(32); // VAProfileAV1Profile0;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
ERR("The codec type is not supported.");
|
||||
return ROCDEC_NOT_SUPPORTED;
|
||||
}
|
||||
va_config_attrib_.type = VAConfigAttribRTFormat;
|
||||
CHECK_VAAPI(vaGetConfigAttributes(va_display_, va_profile_, VAEntrypointVLD, &va_config_attrib_, 1));
|
||||
CHECK_VAAPI(vaCreateConfig(va_display_, va_profile_, VAEntrypointVLD, &va_config_attrib_, 1, &va_config_id_));
|
||||
unsigned int num_attribs = 0;
|
||||
CHECK_VAAPI(vaQuerySurfaceAttributes(va_display_, va_config_id_, nullptr, &num_attribs));
|
||||
std::vector<VASurfaceAttrib> attribs(num_attribs);
|
||||
CHECK_VAAPI(vaQuerySurfaceAttributes(va_display_, va_config_id_, attribs.data(), &num_attribs));
|
||||
for (auto attrib : attribs) {
|
||||
if (attrib.type == VASurfaceAttribDRMFormatModifiers) {
|
||||
supports_modifiers_ = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
void VaapiVideoDecoder::GetVisibleDevices(std::vector<int>& visible_devices_vetor) {
|
||||
rocDecStatus VaapiVideoDecoder::CreateSurfaces() {
|
||||
if (decoder_create_info_.num_decode_surfaces < 1) {
|
||||
ERR("Invalid number of decode surfaces.");
|
||||
return ROCDEC_INVALID_PARAMETER;
|
||||
}
|
||||
va_surface_ids_.resize(decoder_create_info_.num_decode_surfaces);
|
||||
std::vector<VASurfaceAttrib> surf_attribs;
|
||||
VASurfaceAttrib surf_attrib;
|
||||
surf_attrib.type = VASurfaceAttribPixelFormat;
|
||||
surf_attrib.flags = VA_SURFACE_ATTRIB_SETTABLE;
|
||||
surf_attrib.value.type = VAGenericValueTypeInteger;
|
||||
uint32_t surface_format;
|
||||
switch (decoder_create_info_.chroma_format) {
|
||||
case rocDecVideoChromaFormat_Monochrome:
|
||||
surface_format = VA_RT_FORMAT_YUV400;
|
||||
surf_attrib.value.value.i = VA_FOURCC_Y800;
|
||||
break;
|
||||
case rocDecVideoChromaFormat_420:
|
||||
if (decoder_create_info_.bit_depth_minus_8 == 2) {
|
||||
surface_format = VA_RT_FORMAT_YUV420_10;
|
||||
surf_attrib.value.value.i = VA_FOURCC_P010;
|
||||
} else if (decoder_create_info_.bit_depth_minus_8 == 4) {
|
||||
surface_format = VA_RT_FORMAT_YUV420_12;
|
||||
#if VA_CHECK_VERSION(1,8,0)
|
||||
surf_attrib.value.value.i = VA_FOURCC_P012;
|
||||
#else
|
||||
surf_attrib.value.value.i = 0x32313050; // VA_FOURCC_P012
|
||||
#endif
|
||||
} else {
|
||||
surface_format = VA_RT_FORMAT_YUV420;
|
||||
surf_attrib.value.value.i = VA_FOURCC_NV12;
|
||||
}
|
||||
break;
|
||||
case rocDecVideoChromaFormat_422:
|
||||
surface_format = VA_RT_FORMAT_YUV422;
|
||||
break;
|
||||
case rocDecVideoChromaFormat_444:
|
||||
surface_format = VA_RT_FORMAT_YUV444;
|
||||
break;
|
||||
default:
|
||||
ERR("The surface type is not supported");
|
||||
return ROCDEC_NOT_SUPPORTED;
|
||||
}
|
||||
surf_attribs.push_back(surf_attrib);
|
||||
uint64_t mod_linear = 0;
|
||||
VADRMFormatModifierList modifier_list = {
|
||||
.num_modifiers = 1,
|
||||
.modifiers = &mod_linear,
|
||||
};
|
||||
if (supports_modifiers_) {
|
||||
surf_attrib.type = VASurfaceAttribDRMFormatModifiers;
|
||||
surf_attrib.value.type = VAGenericValueTypePointer;
|
||||
surf_attrib.value.value.p = &modifier_list;
|
||||
surf_attribs.push_back(surf_attrib);
|
||||
}
|
||||
CHECK_VAAPI(vaCreateSurfaces(va_display_, surface_format, decoder_create_info_.width,
|
||||
decoder_create_info_.height, va_surface_ids_.data(), va_surface_ids_.size(), surf_attribs.data(), surf_attribs.size()));
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
rocDecStatus VaapiVideoDecoder::CreateContext() {
|
||||
CHECK_VAAPI(vaCreateContext(va_display_, va_config_id_, decoder_create_info_.width, decoder_create_info_.height,
|
||||
VA_PROGRESSIVE, va_surface_ids_.data(), va_surface_ids_.size(), &va_context_id_));
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
rocDecStatus VaapiVideoDecoder::DestroyDataBuffers() {
|
||||
if (pic_params_buf_id_) {
|
||||
CHECK_VAAPI(vaDestroyBuffer(va_display_, pic_params_buf_id_));
|
||||
pic_params_buf_id_ = 0;
|
||||
}
|
||||
if (iq_matrix_buf_id_) {
|
||||
CHECK_VAAPI(vaDestroyBuffer(va_display_, iq_matrix_buf_id_));
|
||||
iq_matrix_buf_id_ = 0;
|
||||
}
|
||||
for (int i = 0; i < num_slices_; i++) {
|
||||
if (slice_params_buf_id_[i]) {
|
||||
CHECK_VAAPI(vaDestroyBuffer(va_display_, slice_params_buf_id_[i]));
|
||||
slice_params_buf_id_[i] = 0;
|
||||
}
|
||||
}
|
||||
if (slice_data_buf_id_) {
|
||||
CHECK_VAAPI(vaDestroyBuffer(va_display_, slice_data_buf_id_));
|
||||
slice_data_buf_id_ = 0;
|
||||
}
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
VaContext::VaContext() {
|
||||
GetGpuUuids();
|
||||
}
|
||||
|
||||
VaContext::~VaContext() {
|
||||
for (int i = 0; i < va_contexts_.size(); i++) {
|
||||
if (va_contexts_[i].va_display) {
|
||||
if (vaTerminate(va_contexts_[i].va_display) != VA_STATUS_SUCCESS) {
|
||||
ERR("Failed to termiate VA");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
rocDecStatus VaContext::GetVaContext(int device_id, uint32_t *va_ctx_id) {
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
bool found_existing = false;
|
||||
uint32_t va_ctx_idx = 0;
|
||||
hipDeviceProp_t hip_dev_prop;
|
||||
rocDecStatus rocdec_status = ROCDEC_SUCCESS;
|
||||
rocdec_status = InitHIP(device_id, hip_dev_prop);
|
||||
if (rocdec_status != ROCDEC_SUCCESS) {
|
||||
ERR("Failed to initilize the HIP.");
|
||||
return rocdec_status;
|
||||
}
|
||||
std::string gpu_uuid(hip_dev_prop.uuid.bytes, sizeof(hip_dev_prop.uuid.bytes));
|
||||
|
||||
if (!va_contexts_.empty()) {
|
||||
for (va_ctx_idx = 0; va_ctx_idx < va_contexts_.size(); va_ctx_idx++) {
|
||||
if (gpu_uuid.compare(va_contexts_[va_ctx_idx].gpu_uuid) == 0) {
|
||||
found_existing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (found_existing) {
|
||||
*va_ctx_id = va_ctx_idx;
|
||||
return ROCDEC_SUCCESS;
|
||||
} else {
|
||||
va_contexts_.resize(va_contexts_.size() + 1);
|
||||
va_ctx_idx = va_contexts_.size() - 1;
|
||||
|
||||
va_contexts_[va_ctx_idx].device_id = device_id;
|
||||
va_contexts_[va_ctx_idx].gpu_uuid.assign(gpu_uuid);
|
||||
va_contexts_[va_ctx_idx].hip_dev_prop = hip_dev_prop;
|
||||
va_contexts_[va_ctx_idx].drm_fd = -1;
|
||||
va_contexts_[va_ctx_idx].va_display = 0;
|
||||
va_contexts_[va_ctx_idx].num_dec_engines = 1;
|
||||
va_contexts_[va_ctx_idx].va_profile = VAProfileNone;
|
||||
va_contexts_[va_ctx_idx].config_attributes_probed = false;
|
||||
|
||||
std::string gcn_arch_name = va_contexts_[va_ctx_idx].hip_dev_prop.gcnArchName;
|
||||
std::size_t pos = gcn_arch_name.find_first_of(":");
|
||||
std::string gcn_arch_name_base = (pos != std::string::npos) ? gcn_arch_name.substr(0, pos) : gcn_arch_name;
|
||||
std::vector<int> visible_devices;
|
||||
GetVisibleDevices(visible_devices);
|
||||
|
||||
int offset = 0;
|
||||
if (gcn_arch_name_base.compare("gfx942") == 0) {
|
||||
std::vector<ComputePartition> current_compute_partitions;
|
||||
GetCurrentComputePartition(current_compute_partitions);
|
||||
if (!current_compute_partitions.empty()) {
|
||||
GetDrmNodeOffset(va_contexts_[va_ctx_idx].hip_dev_prop.name, va_contexts_[va_ctx_idx].device_id, visible_devices, current_compute_partitions, offset);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
std::string drm_node = "/dev/dri/renderD";
|
||||
int render_node_id = (gpu_uuids_to_render_nodes_map_.find(gpu_uuid) != gpu_uuids_to_render_nodes_map_.end()) ? gpu_uuids_to_render_nodes_map_[gpu_uuid] : 128;
|
||||
drm_node += std::to_string(render_node_id + offset);
|
||||
rocdec_status = InitVAAPI(va_ctx_idx, drm_node);
|
||||
if (rocdec_status != ROCDEC_SUCCESS) {
|
||||
ERR("Failed to initilize the VAAPI.");
|
||||
return rocdec_status;
|
||||
}
|
||||
|
||||
amdgpu_device_handle dev_handle;
|
||||
uint32_t major_version = 0, minor_version = 0;
|
||||
if (amdgpu_device_initialize(va_contexts_[va_ctx_idx].drm_fd, &major_version, &minor_version, &dev_handle)) {
|
||||
ERR("GPU device initialization failed: " + drm_node);
|
||||
return ROCDEC_DEVICE_INVALID;
|
||||
}
|
||||
if (amdgpu_query_hw_ip_count(dev_handle, AMDGPU_HW_IP_VCN_DEC, &va_contexts_[va_ctx_idx].num_dec_engines)) {
|
||||
ERR("Failed to get the number of video decode engines.");
|
||||
}
|
||||
amdgpu_device_deinitialize(dev_handle);
|
||||
|
||||
// Prob VA profiles
|
||||
va_contexts_[va_ctx_idx].num_va_profiles = vaMaxNumProfiles(va_contexts_[va_ctx_idx].va_display);
|
||||
va_contexts_[va_ctx_idx].va_profile_list.resize(va_contexts_[va_ctx_idx].num_va_profiles);
|
||||
CHECK_VAAPI(vaQueryConfigProfiles(va_contexts_[va_ctx_idx].va_display, va_contexts_[va_ctx_idx].va_profile_list.data(), &va_contexts_[va_ctx_idx].num_va_profiles));
|
||||
|
||||
*va_ctx_id = va_ctx_idx;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
rocDecStatus VaContext::GetVaDisplay(uint32_t va_ctx_id, VADisplay *va_display) {
|
||||
if (va_ctx_id >= va_contexts_.size()) {
|
||||
ERR("Invalid VA context Id.");
|
||||
*va_display = 0;
|
||||
return ROCDEC_INVALID_PARAMETER;
|
||||
} else {
|
||||
*va_display = va_contexts_[va_ctx_id].va_display;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
rocDecStatus VaContext::CheckDecCapForCodecType(RocdecDecodeCaps *dec_cap) {
|
||||
if (dec_cap == nullptr) {
|
||||
ERR("Null decode capability struct pointer.");
|
||||
return ROCDEC_INVALID_PARAMETER;
|
||||
}
|
||||
rocDecStatus rocdec_status = ROCDEC_SUCCESS;
|
||||
uint32_t va_ctx_id;
|
||||
rocdec_status = GetVaContext(dec_cap->device_id, &va_ctx_id);
|
||||
if (rocdec_status != ROCDEC_SUCCESS) {
|
||||
ERR("Failed to initilize.");
|
||||
return rocdec_status;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
dec_cap->is_supported = 1; // init value
|
||||
VAProfile va_profile = VAProfileNone;
|
||||
switch (dec_cap->codec_type) {
|
||||
case rocDecVideoCodec_HEVC: {
|
||||
if (dec_cap->bit_depth_minus_8 == 0) {
|
||||
va_profile = VAProfileHEVCMain;
|
||||
} else if (dec_cap->bit_depth_minus_8 == 2) {
|
||||
va_profile = VAProfileHEVCMain10;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case rocDecVideoCodec_AVC: {
|
||||
va_profile = VAProfileH264Main;
|
||||
break;
|
||||
}
|
||||
case rocDecVideoCodec_VP9: {
|
||||
if (dec_cap->bit_depth_minus_8 == 0) {
|
||||
va_profile = VAProfileVP9Profile0;
|
||||
} else if (dec_cap->bit_depth_minus_8 == 2) {
|
||||
va_profile = VAProfileVP9Profile2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case rocDecVideoCodec_AV1: {
|
||||
#if VA_CHECK_VERSION(1,6,0)
|
||||
va_profile = VAProfileAV1Profile0;
|
||||
#else
|
||||
va_profile = static_cast<VAProfile>(32); // VAProfileAV1Profile0;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
dec_cap->is_supported = 0;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = 0; i < va_contexts_[va_ctx_id].num_va_profiles; i++) {
|
||||
if (va_contexts_[va_ctx_id].va_profile_list[i] == va_profile) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == va_contexts_[va_ctx_id].num_va_profiles) {
|
||||
dec_cap->is_supported = 0;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
// Check if the config attributes of the profile have been probed before
|
||||
if (va_profile != va_contexts_[va_ctx_id].va_profile || va_contexts_[va_ctx_id].config_attributes_probed == false) {
|
||||
va_contexts_[va_ctx_id].va_profile = va_profile;
|
||||
|
||||
VAConfigAttrib va_config_attrib;
|
||||
unsigned int attr_count;
|
||||
std::vector<VASurfaceAttrib> attr_list;
|
||||
va_config_attrib.type = VAConfigAttribRTFormat;
|
||||
CHECK_VAAPI(vaGetConfigAttributes(va_contexts_[va_ctx_id].va_display, va_contexts_[va_ctx_id].va_profile, VAEntrypointVLD, &va_config_attrib, 1));
|
||||
va_contexts_[va_ctx_id].rt_format_attrib = va_config_attrib.value;
|
||||
|
||||
CHECK_VAAPI(vaCreateConfig(va_contexts_[va_ctx_id].va_display, va_contexts_[va_ctx_id].va_profile, VAEntrypointVLD, &va_config_attrib, 1, &va_contexts_[va_ctx_id].va_config_id));
|
||||
CHECK_VAAPI(vaQuerySurfaceAttributes(va_contexts_[va_ctx_id].va_display, va_contexts_[va_ctx_id].va_config_id, 0, &attr_count));
|
||||
attr_list.resize(attr_count);
|
||||
CHECK_VAAPI(vaQuerySurfaceAttributes(va_contexts_[va_ctx_id].va_display, va_contexts_[va_ctx_id].va_config_id, attr_list.data(), &attr_count));
|
||||
va_contexts_[va_ctx_id].output_format_mask = 0;
|
||||
CHECK_VAAPI(vaDestroyConfig(va_contexts_[va_ctx_id].va_display, va_contexts_[va_ctx_id].va_config_id));
|
||||
for (int k = 0; k < attr_count; k++) {
|
||||
switch (attr_list[k].type) {
|
||||
case VASurfaceAttribPixelFormat: {
|
||||
switch (attr_list[k].value.value.i) {
|
||||
case VA_FOURCC_NV12:
|
||||
va_contexts_[va_ctx_id].output_format_mask |= 1 << rocDecVideoSurfaceFormat_NV12;
|
||||
break;
|
||||
case VA_FOURCC_P016:
|
||||
va_contexts_[va_ctx_id].output_format_mask |= 1 << rocDecVideoSurfaceFormat_P016;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VASurfaceAttribMinWidth:
|
||||
va_contexts_[va_ctx_id].min_width = attr_list[k].value.value.i;
|
||||
break;
|
||||
case VASurfaceAttribMinHeight:
|
||||
va_contexts_[va_ctx_id].min_height = attr_list[k].value.value.i;
|
||||
break;
|
||||
case VASurfaceAttribMaxWidth:
|
||||
va_contexts_[va_ctx_id].max_width = attr_list[k].value.value.i;
|
||||
break;
|
||||
case VASurfaceAttribMaxHeight:
|
||||
va_contexts_[va_ctx_id].max_height = attr_list[k].value.value.i;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
va_contexts_[va_ctx_id].config_attributes_probed = true;
|
||||
}
|
||||
|
||||
// Check chroma format
|
||||
switch (dec_cap->chroma_format) {
|
||||
case rocDecVideoChromaFormat_Monochrome: {
|
||||
if ((va_contexts_[va_ctx_id].rt_format_attrib & VA_RT_FORMAT_YUV400) == 0) {
|
||||
dec_cap->is_supported = 0;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case rocDecVideoChromaFormat_420: {
|
||||
if ((va_contexts_[va_ctx_id].rt_format_attrib & (VA_RT_FORMAT_YUV420 | VA_RT_FORMAT_YUV420_10 | VA_RT_FORMAT_YUV420_12)) == 0) {
|
||||
dec_cap->is_supported = 0;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case rocDecVideoChromaFormat_422: {
|
||||
if ((va_contexts_[va_ctx_id].rt_format_attrib & (VA_RT_FORMAT_YUV422 | VA_RT_FORMAT_YUV422_10 | VA_RT_FORMAT_YUV422_12)) == 0) {
|
||||
dec_cap->is_supported = 0;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case rocDecVideoChromaFormat_444: {
|
||||
if ((va_contexts_[va_ctx_id].rt_format_attrib & (VA_RT_FORMAT_YUV444 | VA_RT_FORMAT_YUV444_10 | VA_RT_FORMAT_YUV444_12)) == 0) {
|
||||
dec_cap->is_supported = 0;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
dec_cap->is_supported = 0;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
}
|
||||
// Check bit depth
|
||||
switch (dec_cap->bit_depth_minus_8) {
|
||||
case 0: {
|
||||
if ((va_contexts_[va_ctx_id].rt_format_attrib & (VA_RT_FORMAT_YUV420 | VA_RT_FORMAT_YUV422 | VA_RT_FORMAT_YUV444 | VA_RT_FORMAT_YUV400)) == 0) {
|
||||
dec_cap->is_supported = 0;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
if ((va_contexts_[va_ctx_id].rt_format_attrib & (VA_RT_FORMAT_YUV420_10 | VA_RT_FORMAT_YUV422_10 | VA_RT_FORMAT_YUV444_10)) == 0) {
|
||||
dec_cap->is_supported = 0;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
if ((va_contexts_[va_ctx_id].rt_format_attrib & (VA_RT_FORMAT_YUV420_12 | VA_RT_FORMAT_YUV422_12 | VA_RT_FORMAT_YUV444_12)) == 0) {
|
||||
dec_cap->is_supported = 0;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
dec_cap->is_supported = 0;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
dec_cap->num_decoders = va_contexts_[va_ctx_id].num_dec_engines;
|
||||
dec_cap->output_format_mask = va_contexts_[va_ctx_id].output_format_mask;
|
||||
dec_cap->max_width = va_contexts_[va_ctx_id].max_width;
|
||||
dec_cap->max_height = va_contexts_[va_ctx_id].max_height;
|
||||
dec_cap->min_width = va_contexts_[va_ctx_id].min_width;
|
||||
dec_cap->min_height = va_contexts_[va_ctx_id].min_height;
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
rocDecStatus VaContext::InitHIP(int device_id, hipDeviceProp_t& hip_dev_prop) {
|
||||
CHECK_HIP(hipGetDeviceCount(&num_devices_));
|
||||
if (num_devices_ < 1) {
|
||||
ERR("Didn't find any GPU.");
|
||||
return ROCDEC_DEVICE_INVALID;
|
||||
}
|
||||
if (device_id >= num_devices_) {
|
||||
ERR("ERROR: the requested device_id is not found! ");
|
||||
return ROCDEC_DEVICE_INVALID;
|
||||
}
|
||||
CHECK_HIP(hipSetDevice(device_id));
|
||||
CHECK_HIP(hipGetDeviceProperties(&hip_dev_prop, device_id));
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
rocDecStatus VaContext::InitVAAPI(int va_ctx_idx, std::string drm_node) {
|
||||
va_contexts_[va_ctx_idx].drm_fd = open(drm_node.c_str(), O_RDWR);
|
||||
if (va_contexts_[va_ctx_idx].drm_fd < 0) {
|
||||
ERR("Failed to open drm node." + drm_node);
|
||||
return ROCDEC_NOT_INITIALIZED;
|
||||
}
|
||||
va_contexts_[va_ctx_idx].va_display = vaGetDisplayDRM(va_contexts_[va_ctx_idx].drm_fd);
|
||||
if (!va_contexts_[va_ctx_idx].va_display) {
|
||||
ERR("Failed to create VA display.");
|
||||
return ROCDEC_NOT_INITIALIZED;
|
||||
}
|
||||
vaSetInfoCallback(va_contexts_[va_ctx_idx].va_display, NULL, NULL);
|
||||
int major_version = 0, minor_version = 0;
|
||||
CHECK_VAAPI(vaInitialize(va_contexts_[va_ctx_idx].va_display, &major_version, &minor_version));
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
void VaContext::GetVisibleDevices(std::vector<int>& visible_devices_vetor) {
|
||||
// First, check if the ROCR_VISIBLE_DEVICES environment variable is present
|
||||
char *visible_devices = std::getenv("ROCR_VISIBLE_DEVICES");
|
||||
// If ROCR_VISIBLE_DEVICES is not present, check if HIP_VISIBLE_DEVICES is present
|
||||
@@ -539,11 +842,11 @@ void VaapiVideoDecoder::GetVisibleDevices(std::vector<int>& visible_devices_veto
|
||||
visible_devices_vetor.push_back(std::atoi(token));
|
||||
token = std::strtok(nullptr,",");
|
||||
}
|
||||
std::sort(visible_devices_vetor.begin(), visible_devices_vetor.end());
|
||||
std::sort(visible_devices_vetor.begin(), visible_devices_vetor.end());
|
||||
}
|
||||
}
|
||||
|
||||
void VaapiVideoDecoder::GetCurrentComputePartition(std::vector<ComputePartition> ¤t_compute_partitions) {
|
||||
void VaContext::GetCurrentComputePartition(std::vector<ComputePartition> ¤t_compute_partitions) {
|
||||
std::string search_path = "/sys/devices/";
|
||||
std::string partition_file = "current_compute_partition";
|
||||
std::error_code ec;
|
||||
@@ -577,9 +880,7 @@ void VaapiVideoDecoder::GetCurrentComputePartition(std::vector<ComputePartition>
|
||||
}
|
||||
}
|
||||
|
||||
void VaapiVideoDecoder::GetDrmNodeOffset(std::string device_name, uint8_t device_id, std::vector<int>& visible_devices,
|
||||
std::vector<ComputePartition> ¤t_compute_partitions, int &offset) {
|
||||
|
||||
void VaContext::GetDrmNodeOffset(std::string device_name, uint8_t device_id, std::vector<int>& visible_devices, std::vector<ComputePartition> ¤t_compute_partitions, int &offset) {
|
||||
if (!current_compute_partitions.empty()) {
|
||||
switch (current_compute_partitions[0]) {
|
||||
case kSpx:
|
||||
@@ -638,7 +939,7 @@ void VaapiVideoDecoder::GetDrmNodeOffset(std::string device_name, uint8_t device
|
||||
* UUID from the corresponding sysfs path. It maps each unique GPU UUID to its
|
||||
* corresponding render node ID and stores this mapping in the gpu_uuids_to_render_nodes_map_.
|
||||
*/
|
||||
void VaapiVideoDecoder::GetGpuUuids() {
|
||||
void VaContext::GetGpuUuids() {
|
||||
std::string dri_path = "/dev/dri";
|
||||
// Iterate through all render nodes
|
||||
for (const auto& entry : fs::directory_iterator(dri_path, fs::directory_options::skip_permission_denied)) {
|
||||
|
||||
@@ -29,6 +29,9 @@ THE SOFTWARE.
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <algorithm>
|
||||
#include <unordered_map>
|
||||
#if __cplusplus >= 201703L && __has_include(<filesystem>)
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
@@ -36,13 +39,22 @@ THE SOFTWARE.
|
||||
#include <experimental/filesystem>
|
||||
namespace fs = std::experimental::filesystem;
|
||||
#endif
|
||||
#include <libdrm/amdgpu_drm.h>
|
||||
#include <libdrm/amdgpu.h>
|
||||
#include <va/va.h>
|
||||
#include <va/va_drm.h>
|
||||
#include <va/va_drmcommon.h>
|
||||
#include "../roc_decoder_caps.h"
|
||||
#include "../../commons.h"
|
||||
#include "../../../api/rocdecode.h"
|
||||
|
||||
#define CHECK_HIP(call) {\
|
||||
hipError_t hip_status = call;\
|
||||
if (hip_status != hipSuccess) {\
|
||||
std::cout << "HIP failure: " << #call << " failed with 'status: " << hipGetErrorName(hip_status) << "' at " << __FILE__ << ":" << __LINE__ << std::endl;\
|
||||
return ROCDEC_RUNTIME_ERROR;\
|
||||
}\
|
||||
}
|
||||
|
||||
#define CHECK_VAAPI(call) {\
|
||||
VAStatus va_status = call;\
|
||||
if (va_status != VA_STATUS_SUCCESS) {\
|
||||
@@ -61,23 +73,44 @@ typedef enum {
|
||||
kCpx = 4, // Core Partition Accelerator
|
||||
} ComputePartition;
|
||||
|
||||
typedef struct {
|
||||
int device_id;
|
||||
std::string gpu_uuid;
|
||||
int drm_fd;
|
||||
VADisplay va_display;
|
||||
hipDeviceProp_t hip_dev_prop;
|
||||
uint32_t num_dec_engines;
|
||||
int num_va_profiles;
|
||||
std::vector<VAProfile> va_profile_list; // supported profiles by the current GPU
|
||||
VAProfile va_profile; // current profile used
|
||||
VAConfigID va_config_id;
|
||||
bool config_attributes_probed;
|
||||
uint32_t rt_format_attrib;
|
||||
uint32_t output_format_mask;
|
||||
uint32_t max_width;
|
||||
uint32_t max_height;
|
||||
uint32_t min_width;
|
||||
uint32_t min_height;
|
||||
} VaContextInfo;
|
||||
|
||||
class VaapiVideoDecoder {
|
||||
public:
|
||||
VaapiVideoDecoder(RocDecoderCreateInfo &decoder_create_info);
|
||||
~VaapiVideoDecoder();
|
||||
rocDecStatus InitializeDecoder(std::string device_name, std::string gcn_arch_name, std::string& gpu_uuid);
|
||||
rocDecStatus InitializeDecoder();
|
||||
rocDecStatus SubmitDecode(RocdecPicParams *pPicParams);
|
||||
rocDecStatus GetDecodeStatus(int pic_idx, RocdecDecodeStatus* decode_status);
|
||||
rocDecStatus ExportSurface(int pic_idx, VADRMPRIMESurfaceDescriptor &va_drm_prime_surface_desc);
|
||||
rocDecStatus SyncSurface(int pic_idx);
|
||||
rocDecStatus ReconfigureDecoder(RocdecReconfigureDecoderInfo *reconfig_params);
|
||||
|
||||
private:
|
||||
RocDecoderCreateInfo decoder_create_info_;
|
||||
int drm_fd_;
|
||||
VADisplay va_display_;
|
||||
VAProfile va_profile_;
|
||||
VAConfigAttrib va_config_attrib_;
|
||||
VAConfigID va_config_id_;
|
||||
VAProfile va_profile_;
|
||||
VAContextID va_context_id_;
|
||||
std::vector<VASurfaceID> va_surface_ids_;
|
||||
bool supports_modifiers_;
|
||||
@@ -88,6 +121,30 @@ private:
|
||||
uint32_t num_slices_;
|
||||
VABufferID slice_data_buf_id_;
|
||||
uint32_t slice_data_buf_size_;
|
||||
|
||||
bool IsCodecConfigSupported(int device_id, rocDecVideoCodec codec_type, rocDecVideoChromaFormat chroma_format, uint32_t bit_depth_minus8, rocDecVideoSurfaceFormat output_format);
|
||||
rocDecStatus CreateDecoderConfig();
|
||||
rocDecStatus CreateSurfaces();
|
||||
rocDecStatus CreateContext();
|
||||
rocDecStatus DestroyDataBuffers();
|
||||
};
|
||||
|
||||
// The VaContext singleton class providing access to the the GPU VA services
|
||||
class VaContext {
|
||||
public:
|
||||
int num_devices_;
|
||||
std::vector<VaContextInfo> va_contexts_;
|
||||
|
||||
static VaContext& GetInstance() {
|
||||
static VaContext instance;
|
||||
return instance;
|
||||
}
|
||||
rocDecStatus GetVaContext(int device_id, uint32_t *va_ctx_id);
|
||||
rocDecStatus GetVaDisplay(uint32_t va_ctx_id, VADisplay *va_display);
|
||||
rocDecStatus CheckDecCapForCodecType(RocdecDecodeCaps *dec_cap);
|
||||
|
||||
private:
|
||||
std::mutex mutex;
|
||||
/**
|
||||
* @brief A map that associates GPU UUIDs with their corresponding render node indices.
|
||||
*
|
||||
@@ -97,14 +154,15 @@ private:
|
||||
*/
|
||||
std::unordered_map<std::string, int> gpu_uuids_to_render_nodes_map_;
|
||||
|
||||
rocDecStatus InitVAAPI(std::string drm_node);
|
||||
rocDecStatus CreateDecoderConfig();
|
||||
rocDecStatus CreateSurfaces();
|
||||
rocDecStatus CreateContext();
|
||||
rocDecStatus DestroyDataBuffers();
|
||||
VaContext();
|
||||
VaContext(const VaContext&) = delete;
|
||||
VaContext& operator = (const VaContext) = delete;
|
||||
~VaContext();
|
||||
|
||||
rocDecStatus InitHIP(int device_id, hipDeviceProp_t& hip_dev_prop);
|
||||
rocDecStatus InitVAAPI(int va_ctx_idx, std::string drm_node);
|
||||
void GetVisibleDevices(std::vector<int>& visible_devices_vetor);
|
||||
void GetCurrentComputePartition(std::vector<ComputePartition> ¤t_compute_partitions);
|
||||
void GetDrmNodeOffset(std::string device_name, uint8_t device_id, std::vector<int>& visible_devices, std::vector<ComputePartition> ¤t_compute_partitions, int &offset);
|
||||
void GetGpuUuids();
|
||||
void GetVisibleDevices(std::vector<int>& visible_devices);
|
||||
void GetCurrentComputePartition(std::vector<ComputePartition> &currnet_compute_partitions);
|
||||
void GetDrmNodeOffset(std::string device_name, uint8_t device_id, std::vector<int>& visible_devices,
|
||||
std::vector<ComputePartition> ¤t_compute_partitions, int &offset);
|
||||
};
|
||||
@@ -26,7 +26,6 @@ RocVideoDecoder::RocVideoDecoder(int device_id, OutputSurfaceMemoryType out_mem_
|
||||
const Rect *p_crop_rect, bool extract_user_sei_Message, uint32_t disp_delay, int max_width, int max_height, uint32_t clk_rate) :
|
||||
device_id_{device_id}, out_mem_type_(out_mem_type), codec_id_(codec), b_force_zero_latency_(force_zero_latency),
|
||||
b_extract_sei_message_(extract_user_sei_Message), disp_delay_(disp_delay), max_width_ (max_width), max_height_(max_height) {
|
||||
|
||||
if (!InitHIP(device_id_)) {
|
||||
THROW("Failed to initilize the HIP");
|
||||
}
|
||||
@@ -1059,10 +1058,11 @@ bool RocVideoDecoder::CodecSupported(int device_id, rocDecVideoCodec codec_id, u
|
||||
decode_caps.codec_type = codec_id;
|
||||
decode_caps.chroma_format = rocDecVideoChromaFormat_420;
|
||||
decode_caps.bit_depth_minus_8 = bit_depth - 8;
|
||||
if(rocDecGetDecoderCaps(&decode_caps) != ROCDEC_SUCCESS) {
|
||||
if((rocDecGetDecoderCaps(&decode_caps) != ROCDEC_SUCCESS) || !decode_caps.is_supported) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RocVideoDecoder::WaitForDecodeCompletion() {
|
||||
|
||||
Reference in New Issue
Block a user