From 2c940dd9d0ee4d3eb11e952ea1d0148d797a3f27 Mon Sep 17 00:00:00 2001 From: Aryan Salmanpour Date: Tue, 7 Nov 2023 13:47:53 -0500 Subject: [PATCH] Add support for creating a vaapi context and surfaces for decoding (#41) --- src/rocdecode/vaapi/vaapi_videodecoder.cpp | 52 +++++++++++++++++++++- src/rocdecode/vaapi/vaapi_videodecoder.h | 4 ++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/rocdecode/vaapi/vaapi_videodecoder.cpp b/src/rocdecode/vaapi/vaapi_videodecoder.cpp index cb423af28c..ada2a91e0b 100644 --- a/src/rocdecode/vaapi/vaapi_videodecoder.cpp +++ b/src/rocdecode/vaapi/vaapi_videodecoder.cpp @@ -23,13 +23,16 @@ THE SOFTWARE. #include "vaapi_videodecoder.h" VaapiVideoDecoder::VaapiVideoDecoder(RocDecoderCreateInfo &decoder_create_info) : decoder_create_info_{decoder_create_info}, - drm_fd_{-1}, va_display_{0}, va_config_attrib_{{}}, va_config_id_{0}, va_profile_ {VAProfileNone} {}; + drm_fd_{-1}, va_display_{0}, va_config_attrib_{{}}, va_config_id_{0}, va_profile_ {VAProfileNone}, va_context_id_{0}, va_surface_ids_{{}} {}; VaapiVideoDecoder::~VaapiVideoDecoder() { if (drm_fd_ != -1) { close(drm_fd_); } if (va_display_) { + vaDestroySurfaces(va_display_, va_surface_ids_.data(), va_surface_ids_.size()); + if (va_context_id_) + vaDestroyContext(va_display_, va_context_id_); if (va_config_id_) vaDestroyConfig(va_display_, va_config_id_); vaTerminate(va_display_); @@ -60,6 +63,16 @@ rocDecStatus VaapiVideoDecoder::InitializeDecoder(std::string gcn_arch_name) { ERR("ERROR: Failed to create a VAAPI decoder configuration" + TOSTR(rocdec_status)); return rocdec_status; } + rocdec_status = CreateSurfaces(); + if (rocdec_status != ROCDEC_SUCCESS) { + ERR("ERROR: Failed to create VAAPI surfaces " + TOSTR(rocdec_status)); + return rocdec_status; + } + rocdec_status = CreateContext(); + if (rocdec_status != ROCDEC_SUCCESS) { + ERR("ERROR: Failed to create a VAAPI context " + TOSTR(rocdec_status)); + return rocdec_status; + } return rocdec_status; } @@ -98,6 +111,43 @@ rocDecStatus VaapiVideoDecoder::CreateDecoderConfig() { return ROCDEC_SUCCESS; } +rocDecStatus VaapiVideoDecoder::CreateSurfaces() { + if (decoder_create_info_.ulNumDecodeSurfaces < 1) { + ERR("ERROR: invalid number of decode surfaces "); + return ROCDEC_INVALID_PARAMETER; + } + va_surface_ids_.resize(decoder_create_info_.ulNumDecodeSurfaces); + uint8_t surface_format; + switch (decoder_create_info_.ChromaFormat) { + case rocDecVideoChromaFormat_Monochrome: + surface_format = VA_RT_FORMAT_YUV400; + break; + case rocDecVideoChromaFormat_420: + surface_format = VA_RT_FORMAT_YUV420; + break; + case rocDecVideoChromaFormat_422: + surface_format = VA_RT_FORMAT_YUV422; + break; + case rocDecVideoChromaFormat_444: + surface_format = VA_RT_FORMAT_YUV444; + break; + default: + ERR("ERROR: the surface type is not supported!"); + return ROCDEC_NOT_SUPPORTED; + } + + CHECK_VAAPI(vaCreateSurfaces(va_display_, surface_format, decoder_create_info_.ulWidth, + decoder_create_info_.ulHeight, va_surface_ids_.data(), va_surface_ids_.size(), nullptr, 0)); + + return ROCDEC_SUCCESS; +} + +rocDecStatus VaapiVideoDecoder::CreateContext() { + CHECK_VAAPI(vaCreateContext(va_display_, va_config_id_, decoder_create_info_.ulWidth, decoder_create_info_.ulHeight, + VA_PROGRESSIVE, va_surface_ids_.data(), va_surface_ids_.size(), &va_context_id_)); + return ROCDEC_SUCCESS; +} + rocDecStatus VaapiVideoDecoder::SubmitDecode(RocdecPicParams *pPicParams) { // Todo copy pic param, slice param, IQ matrix and slice data from RocdecPicParams to VAAPI struct buffers, then submit to VAAPI driver. return ROCDEC_SUCCESS; diff --git a/src/rocdecode/vaapi/vaapi_videodecoder.h b/src/rocdecode/vaapi/vaapi_videodecoder.h index 680b1cbc02..1929aeb116 100644 --- a/src/rocdecode/vaapi/vaapi_videodecoder.h +++ b/src/rocdecode/vaapi/vaapi_videodecoder.h @@ -56,6 +56,10 @@ private: VAConfigAttrib va_config_attrib_; VAConfigID va_config_id_; VAProfile va_profile_; + VAContextID va_context_id_; + std::vector va_surface_ids_; rocDecStatus InitVAAPI(std::string drm_node); rocDecStatus CreateDecoderConfig(); + rocDecStatus CreateSurfaces(); + rocDecStatus CreateContext(); }; \ No newline at end of file