diff --git a/CMakeLists.txt b/CMakeLists.txt index c3026a375b..2a3888663e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,7 +47,11 @@ find_package(HIP QUIET) find_package(Libva QUIET) if(HIP_FOUND AND Libva_FOUND) - list(APPEND SOURCES ${PROJECT_SOURCE_DIR} src/rocdecode_api.cpp src/rocdecoder.cpp) + include_directories(./api + ./src + ./src/vaapi + ) + file(GLOB_RECURSE SOURCES "./src/*.cpp") add_library(${PROJECT_NAME} SHARED ${SOURCES}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++17") target_link_libraries(${PROJECT_NAME} Libva::va Libva::va_drm hip::device) diff --git a/api/rocdecode.h b/api/rocdecode.h index 449d23909a..5f13c3c3b0 100644 --- a/api/rocdecode.h +++ b/api/rocdecode.h @@ -28,6 +28,9 @@ THE SOFTWARE. #endif #endif +#pragma once +#include "hip/hip_runtime.h" + /*****************************************************************************************************/ //! \file rocdecode.h //! rocDecode API provides video decoding interface to AMD GPU devices. @@ -55,9 +58,10 @@ typedef void *rocDecDecoderHandle; typedef enum rocDecStatus_enum{ ROCDEC_DEVICE_INVALID = -1, ROCDEC_CONTEXT_INVALID = -2, - ROCDEC_RUNTIME_ERROR = 3, + ROCDEC_RUNTIME_ERROR = -3, ROCDEC_OUTOF_MEMORY = -4, ROCDEC_INVALID_PARAMETER = -5, + ROCDEC_NOT_IMPLEMENTED = -6, ROCDEC_SUCCESS = 0, }rocDecStatus; @@ -317,6 +321,29 @@ typedef struct _ROCDECPICPARAMS { } CodecSpecific; } ROCDECPICPARAMS; +/******************************************************/ +//! \struct ROCDECPROCPARAMS +//! Picture parameters for postprocessing +//! This structure is used in rocDecMapVideoFrame API +/******************************************************/ +typedef struct _ROCDECPROCPARAMS +{ + int progressive_frame; /**< IN: Input is progressive (deinterlace_mode will be ignored) */ + int top_field_first; /**< IN: Input frame is top field first (1st field is top, 2nd field is bottom) */ + unsigned int reserved_flags[2]; /**< Reserved for future use (set to zero) */ + + // The fields below are used for raw YUV input + unsigned long long raw_input_dptr; /**< IN: Input HIP device ptr for raw YUV extensions */ + unsigned int raw_input_pitch; /**< IN: pitch in bytes of raw YUV input (should be aligned appropriately) */ + unsigned int raw_input_format; /**< IN: Input YUV format (rocDecVideoCodec_enum) */ + unsigned long long raw_output_dptr; /**< IN: Output HIP device mem ptr for raw YUV extensions */ + unsigned int raw_output_pitch; /**< IN: pitch in bytes of raw YUV output (should be aligned appropriately) */ + unsigned int raw_output_format; /**< IN: Output YUV format (rocDecVideoCodec_enum) */ + hipStream_t output_hstream; /**< IN: stream object used by rocDecMapVideoFrame */ + unsigned int Reserved[16]; /**< Reserved for future use (set to zero) */ +} ROCDECPROCPARAMS; + + /***********************************************************************************************************/ //! ROCVIDEO_DECODER @@ -343,15 +370,6 @@ typedef struct _ROCDECPICPARAMS { //! in the decode queue /***********************************************************************************************************/ -/**********************************************************************************************************************/ -//! \fn rocDecStatus ROCDECAPI rocdecGetDecoderCaps(ROCDECDECODECAPS *pdc) -//! Queries decode capabilities of AMD's VCN decoder based on CodecType, ChromaFormat and BitDepthMinus8 parameters. -//! 1. Application fills IN parameters CodecType, ChromaFormat and BitDepthMinus8 of ROCDECDECODECAPS structure -//! 2. On calling rocdecGetDecoderCaps, driver fills OUT parameters if the IN parameters are supported -//! If IN parameters passed to the driver are not supported by AMD-VCN-HW, then all OUT params are set to 0. -/**********************************************************************************************************************/ -extern rocDecStatus ROCDECAPI rocDecGetDecoderCaps(ROCDECDECODECAPS *pdc); - /*****************************************************************************************************/ //! \fn rocDecStatus ROCDECAPI rocDecCreateDecoder(rocDecDecoderHandle *phDecoder, ROCDECDECODECREATEINFO *pdci) //! Create the decoder object based on pdci. A handle to the created decoder is returned @@ -364,6 +382,15 @@ extern rocDecStatus ROCDECAPI rocDecCreateDecoder(rocDecDecoderHandle *phDecoder /*****************************************************************************************************/ extern rocDecStatus ROCDECAPI rocDecDestroyDecoder(rocDecDecoderHandle hDecoder); +/**********************************************************************************************************************/ +//! \fn rocDecStatus ROCDECAPI rocdecGetDecoderCaps(ROCDECDECODECAPS *pdc) +//! Queries decode capabilities of AMD's VCN decoder based on CodecType, ChromaFormat and BitDepthMinus8 parameters. +//! 1. Application fills IN parameters CodecType, ChromaFormat and BitDepthMinus8 of ROCDECDECODECAPS structure +//! 2. On calling rocdecGetDecoderCaps, driver fills OUT parameters if the IN parameters are supported +//! If IN parameters passed to the driver are not supported by AMD-VCN-HW, then all OUT params are set to 0. +/**********************************************************************************************************************/ +extern rocDecStatus ROCDECAPI rocDecGetDecoderCaps(rocDecDecoderHandle hDecoder, ROCDECDECODECAPS *pdc); + /*****************************************************************************************************/ //! \fn rocDecStatus ROCDECAPI rocDecDecodeFrame(rocDecDecoderHandle hDecoder, ROCDECPICPARAMS *pPicParams) //! Decodes a single picture @@ -386,6 +413,22 @@ extern rocDecStatus ROCDECAPI rocDecGetDecodeStatus(rocDecDecoderHandle hDecoder /*********************************************************************************************************/ extern rocDecStatus ROCDECAPI rocDecReconfigureDecoder(rocDecDecoderHandle hDecoder, ROCDECRECONFIGUREDECODERINFO *pDecReconfigParams); +/************************************************************************************************************************/ +//! \fn extern rocDecStatus ROCDECAPI rocDecMapVideoFrame(rocDecDecoderHandle hDecoder, int nPicIdx, +//! unsigned int *pDevMemPtr, unsigned int *pHorizontalPitch, +//! ROCDECPROCPARAMS *pVidPostprocParams); +//! Post-process and map video frame corresponding to nPicIdx for use in HIP. Returns HIP device pointer and associated +//! pitch(horizontal stride) of the video frame. Returns device memory pointers for each plane (Y, U and V) seperately +/************************************************************************************************************************/ +extern rocDecStatus ROCDECAPI rocDecMapVideoFrame(rocDecDecoderHandle hDecoder, int nPicIdx, + void *pDevMemPtr[3], unsigned int *pHorizontalPitch[3], + ROCDECPROCPARAMS *pVidPostprocParams); + +/*****************************************************************************************************/ +//! \fn rocDecStatus ROCDECAPI rocDecUnMapVideoFrame(rocDecDecoderHandle hDecoder, void *pMappedDevPtr) +//! Unmap a previously mapped video frame with the associated mapped raw pointer (pMappedDevPtr) +/*****************************************************************************************************/ +extern rocDecStatus ROCDECAPI rocDecUnMapVideoFrame(rocDecDecoderHandle hDecoder, void *pMappedDevPtr); #ifdef __cplusplus } diff --git a/src/commons.h b/src/commons.h new file mode 100644 index 0000000000..81851e2daa --- /dev/null +++ b/src/commons.h @@ -0,0 +1,54 @@ +/* +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 +#include +#include +#include + +#define TOSTR(X) std::to_string(static_cast(X)) +#define STR(X) std::string(X) + +#if DBGINFO +#define INFO(X) std::clog << "[INF] " << " {" << __func__ <<"} " << " " << X << std::endl; +#else +#define INFO(X) ; +#endif +#define ERR(X) std::cerr << "[ERR] " << " {" << __func__ <<"} " << " " << X << std::endl; + + +class rocDecodeException : public std::exception +{ +public: + + explicit rocDecodeException(const std::string& message):_message(message) + {} + virtual const char* what() const throw() override + { + return _message.c_str(); + } +private: + std::string _message; +}; + +#define THROW(X) throw rocDecodeException(" { "+std::string(__func__)+" } " + X); diff --git a/src/dec_handle.h b/src/dec_handle.h new file mode 100644 index 0000000000..8b44526a85 --- /dev/null +++ b/src/dec_handle.h @@ -0,0 +1,39 @@ +/* +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 +#include +#include "rocdecoder.h" + +struct decHandle { + + explicit decHandle(); //constructor + ~decHandle() { clear_errors(); } + std::shared_ptr roc_decoder; // class intantiation + bool no_error() { return error.empty(); } + const char* error_msg() { return error.c_str(); } + void capture_error(const std::string& err_msg) { error = err_msg; } + +private: + void clear_errors() { error = "";} + std::string error; +}; \ No newline at end of file diff --git a/src/rocdecode_api.cpp b/src/rocdecode_api.cpp index d1b9877593..bbbbcd4a02 100644 --- a/src/rocdecode_api.cpp +++ b/src/rocdecode_api.cpp @@ -19,3 +19,160 @@ 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. */ +#include "dec_handle.h" +#include "rocdecode.h" +#include "commons.h" + +/*****************************************************************************************************/ +//! \fn rocDecStatus ROCDECAPI rocDecCreateDecoder(rocDecDecoderHandle *phDecoder, ROCDECDECODECREATEINFO *pdci) +//! Create the decoder object based on pdci. A handle to the created decoder is returned +/*****************************************************************************************************/ +rocDecStatus ROCDECAPI +rocDecCreateDecoder(rocDecDecoderHandle *phDecoder, ROCDECDECODECREATEINFO *pdci) { + rocDecDecoderHandle handle = nullptr; + try { + handle = new decHandle(); + } + catch(const std::exception& e) + { + ERR( STR("Failed to init the rocDecode handle, ") + STR(e.what())) + } + *phDecoder = handle; + return ROCDEC_SUCCESS; +} + +/*****************************************************************************************************/ +//! \fn rocDecStatus ROCDECAPI rocDecDestroyDecoder(rocDecDecoderHandle hDecoder) +//! Destroy the decoder object +/*****************************************************************************************************/ +rocDecStatus ROCDECAPI +rocDecDestroyDecoder(rocDecDecoderHandle hDecoder) { + auto handle = static_cast (hDecoder); + delete handle; + return ROCDEC_SUCCESS; +} + +/**********************************************************************************************************************/ +//! \fn rocDecStatus ROCDECAPI rocdecGetDecoderCaps(rocDecDecoderHandle hDecoder, ROCDECDECODECAPS *pdc) +//! Queries decode capabilities of AMD's VCN decoder based on CodecType, ChromaFormat and BitDepthMinus8 parameters. +//! 1. Application fills IN parameters CodecType, ChromaFormat and BitDepthMinus8 of ROCDECDECODECAPS structure +//! 2. On calling rocdecGetDecoderCaps, driver fills OUT parameters if the IN parameters are supported +//! If IN parameters passed to the driver are not supported by AMD-VCN-HW, then all OUT params are set to 0. +/**********************************************************************************************************************/ +rocDecStatus ROCDECAPI +rocDecGetDecoderCaps(rocDecDecoderHandle hDecoder, ROCDECDECODECAPS *pdc) { + auto handle = static_cast (hDecoder); + rocDecStatus ret; + try { + ret = handle->roc_decoder->getDecoderCaps(pdc); + } + catch(const std::exception& e) { + handle->capture_error(e.what()); + ERR(e.what()) + return ROCDEC_RUNTIME_ERROR; + } + return ret; +} + +/*****************************************************************************************************/ +//! \fn rocDecStatus ROCDECAPI rocDecDecodeFrame(rocDecDecoderHandle hDecoder, ROCDECPICPARAMS *pPicParams) +//! Decodes a single picture +//! Submits the frame for HW decoding +/*****************************************************************************************************/ +rocDecStatus ROCDECAPI +rocDecDecodeFrame(rocDecDecoderHandle hDecoder, ROCDECPICPARAMS *pPicParams) { + auto handle = static_cast (hDecoder); + rocDecStatus ret; + try { + ret = handle->roc_decoder->decodeFrame(pPicParams); + } + catch(const std::exception& e) { + handle->capture_error(e.what()); + ERR(e.what()) + return ROCDEC_RUNTIME_ERROR; + } + return ret; +} + +/************************************************************************************************************/ +//! \fn rocDecStatus ROCDECAPI rocDecGetDecodeStatus(rocDecDecoderHandle hDecoder, int nPicIdx, ROCDECGETDECODESTATUS* pDecodeStatus); +//! Get the decode status for frame corresponding to nPicIdx +//! API is currently supported for HEVC, H264 and JPEG codecs. +//! API returns CUDA_ERROR_NOT_SUPPORTED error code for unsupported GPU or codec. +/************************************************************************************************************/ +rocDecStatus ROCDECAPI +rocDecGetDecodeStatus(rocDecDecoderHandle hDecoder, int nPicIdx, ROCDECGETDECODESTATUS* pDecodeStatus) { + auto handle = static_cast (hDecoder); + rocDecStatus ret; + try { + ret = handle->roc_decoder->getDecodeStatus(nPicIdx, pDecodeStatus); + } + catch(const std::exception& e) { + handle->capture_error(e.what()); + ERR(e.what()) + return ROCDEC_RUNTIME_ERROR; + } + return ret; +} + +/*********************************************************************************************************/ +//! \fn rocDecStatus ROCDECAPI rocDecReconfigureDecoder(rocDecDecoderHandle hDecoder, ROCDECRECONFIGUREDECODERINFO *pDecReconfigParams) +//! Used to reuse single decoder for multiple clips. Currently supports resolution change, resize params +//! params, target area params change for same codec. Must be called during ROCDECPARSERPARAMS::pfnSequenceCallback +/*********************************************************************************************************/ +rocDecStatus ROCDECAPI +rocDecReconfigureDecoder(rocDecDecoderHandle hDecoder, ROCDECRECONFIGUREDECODERINFO *pDecReconfigParams) { + auto handle = static_cast (hDecoder); + rocDecStatus ret; + try { + ret = handle->roc_decoder->reconfigureDecoder(pDecReconfigParams); + } + catch(const std::exception& e) { + handle->capture_error(e.what()); + ERR(e.what()) + return ROCDEC_RUNTIME_ERROR; + } + return ret; +} + +/************************************************************************************************************************/ +//! \fn extern rocDecStatus ROCDECAPI rocDecMapVideoFrame(rocDecDecoderHandle hDecoder, int nPicIdx, +//! unsigned int *pDevMemPtr, unsigned int *pHorizontalPitch, +//! ROCDECPROCPARAMS *pVidPostprocParams); +//! Post-process and map video frame corresponding to nPicIdx for use in HIP. Returns HIP device pointer and associated +//! pitch(horizontal stride) of the video frame. Returns device memory pointers for each plane (Y, U and V) seperately +/************************************************************************************************************************/ +rocDecStatus ROCDECAPI +rocDecMapVideoFrame(rocDecDecoderHandle hDecoder, int nPicIdx, + void *pDevMemPtr[3], unsigned int *pHorizontalPitch[3], ROCDECPROCPARAMS *pVidPostprocParams) { + auto handle = static_cast (hDecoder); + rocDecStatus ret; + try { + ret = handle->roc_decoder->mapVideoFrame(nPicIdx, pDevMemPtr, pHorizontalPitch, pVidPostprocParams); + } + catch(const std::exception& e) { + handle->capture_error(e.what()); + ERR(e.what()) + return ROCDEC_RUNTIME_ERROR; + } + return ret; +} + +/*****************************************************************************************************/ +//! \fn rocDecStatus ROCDECAPI rocDecUnMapVideoFrame(rocDecDecoderHandle hDecoder, void *pMappedDevPtr) +//! Unmap a previously mapped video frame with the associated mapped raw pointer (pMappedDevPtr) +/*****************************************************************************************************/ +rocDecStatus ROCDECAPI +rocDecUnMapVideoFrame(rocDecDecoderHandle hDecoder, void *pMappedDevPtr) { + auto handle = static_cast (hDecoder); + rocDecStatus ret; + try { + ret = handle->roc_decoder->unMapVideoFrame(pMappedDevPtr); + } + catch(const std::exception& e) { + handle->capture_error(e.what()); + ERR(e.what()) + return ROCDEC_RUNTIME_ERROR; + } + return ret; +} diff --git a/src/rocdecoder.cpp b/src/rocdecoder.cpp index d1b9877593..c60e767aaa 100644 --- a/src/rocdecoder.cpp +++ b/src/rocdecoder.cpp @@ -19,3 +19,105 @@ 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. */ + + +#include "rocdecoder.h" +#include "commons.h" + +rocDecoder::rocDecoder(int device_id, int num_devices):device_id_ {device_id}, num_devices_{num_devices} { + // todo:: + if (ROCDEC_SUCCESS != initHIP(device_id_)) { + THROW("Failed to initilize the HIP"); + } + initDRMnodes(); + +} + +rocDecStatus rocDecoder::getDecoderCaps(ROCDECDECODECAPS *pdc) { + // todo:: return appropriate decStatus if fails + //vaQueryConfigProfiles + // fill the ROCDECDECODECAPS struct + // return status + return ROCDEC_NOT_IMPLEMENTED; +} + +rocDecStatus rocDecoder::decodeFrame(ROCDECPICPARAMS *pPicParams) { + // todo:: return appropriate decStatus if fails + // call funsction to do va-api decoding using the picture parameters structure + // return status + return ROCDEC_NOT_IMPLEMENTED; +} + +rocDecStatus rocDecoder::getDecodeStatus(int nPicIdx, ROCDECGETDECODESTATUS* pDecodeStatus) { + // todo:: return appropriate decStatus + // init vaapi decoder to get the decoding status of the picture specified by nPicIndex + // return status + return ROCDEC_NOT_IMPLEMENTED; +} + +rocDecStatus rocDecoder::reconfigureDecoder(ROCDECRECONFIGUREDECODERINFO *pDecReconfigParams) { + // todo:: return appropriate decStatus + // this will be called when the current configuration is changed during decoding + // release the current va-api decoder instance and create a new one with the new parameters (or reinit if available) + // return status + return ROCDEC_NOT_IMPLEMENTED; +} + +rocDecStatus rocDecoder::mapVideoFrame(int nPicIdx, void *pDevMemPtr[3], + unsigned int *pHorizontalPitch[3], ROCDECPROCPARAMS *pVidPostprocParams) { + // todo:: return appropriate decStatus + // Post-process and map video frame corresponding to nPicIdx for use in HIP. Returns HIP device pointer and associated + // pitch(horizontal stride) of the video frame. Returns device memory pointers for each plane (Y, U and V) seperately + return ROCDEC_NOT_IMPLEMENTED; +} + +rocDecStatus rocDecoder::unMapVideoFrame(void *pMappedDevPtr) { + // todo:: return appropriate decStatus + // Unmap a previously mapped video frame with the associated mapped raw pointer (pMappedDevPtr) + return ROCDEC_NOT_IMPLEMENTED; +} + + +rocDecStatus rocDecoder::initHIP(int device_id) { + hipError_t hipStatus = hipSuccess; + hipStatus = hipGetDeviceCount(&num_devices_); + rocDecStatus decStatus = ROCDEC_SUCCESS; + if (hipStatus != hipSuccess) { + ERR("ERROR: hipGetDeviceCount failed!" + TOSTR(hipStatus)); + decStatus = ROCDEC_DEVICE_INVALID; + } + if (num_devices_ < 1) { + ERR("ERROR: didn't find any GPU!"); + decStatus = ROCDEC_DEVICE_INVALID; + } + if (device_id >= num_devices_) { + ERR("ERROR: the requested device_id is not found! "); + decStatus = ROCDEC_DEVICE_INVALID; + } + hipStatus = hipSetDevice(device_id); + if (hipStatus != hipSuccess) { + ERR("ERROR: hipSetDevice( " + TOSTR(device_id) + ") failed! (" + TOSTR(hipStatus) + ")" ); + decStatus = ROCDEC_DEVICE_INVALID; + } + + hipStatus = hipGetDeviceProperties(&hip_dev_prop_, device_id); + if (hipStatus != hipSuccess) { + ERR("ERROR: hipGetDeviceProperties for device (" +TOSTR(device_id) + " ) failed! (" + TOSTR(hipStatus) + ")" ); + decStatus = ROCDEC_DEVICE_INVALID; + } + + hipStatus = hipStreamCreate(&hip_stream_); + if (hipStatus != hipSuccess) { + ERR("ERROR: hipStream_Create failed! (" + TOSTR(hipStatus) + ")"); + decStatus = ROCDEC_DEVICE_INVALID; + } + return decStatus; +} + +void rocDecoder::initDRMnodes() { + // build the DRM render node names + for (int i = 0; i < num_devices_; i++) { + drm_nodes_.push_back("/dev/dri/renderD" + std::to_string(128 + i)); + } +} + diff --git a/src/rocdecoder.h b/src/rocdecoder.h new file mode 100644 index 0000000000..4b14110738 --- /dev/null +++ b/src/rocdecoder.h @@ -0,0 +1,57 @@ +/* +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 +#include +#include +#include +#include +#include +#include +#include +#include "../api/rocdecode.h" +#include + + +class rocDecoder { +public: + rocDecoder(int device_id, int num_devices); + ~rocDecoder(); + rocDecStatus getDecoderCaps(ROCDECDECODECAPS *pdc); + rocDecStatus decodeFrame(ROCDECPICPARAMS *pPicParams); + rocDecStatus getDecodeStatus(int nPicIdx, ROCDECGETDECODESTATUS* pDecodeStatus); + rocDecStatus reconfigureDecoder(ROCDECRECONFIGUREDECODERINFO *pDecReconfigParams); + rocDecStatus mapVideoFrame(int nPicIdx, void *pDevMemPtr[3], unsigned int *pHorizontalPitch[3], ROCDECPROCPARAMS *pVidPostprocParams); + rocDecStatus unMapVideoFrame(void *pMappedDevPtr); + +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 drm_nodes_; +}; \ No newline at end of file diff --git a/src/rocdecoder.hpp b/src/vaapi/vaapi_videodecoder.cpp similarity index 95% rename from src/rocdecoder.hpp rename to src/vaapi/vaapi_videodecoder.cpp index 247c5ab27e..9f526fbecf 100644 --- a/src/rocdecoder.hpp +++ b/src/vaapi/vaapi_videodecoder.cpp @@ -20,8 +20,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#pragma once - #include #include #include @@ -29,5 +27,6 @@ THE SOFTWARE. #include #include #include -#include "../api/rocdecode.h" -#include + +#include "commons.h" +#include "vaapi_videodecoder.h" diff --git a/src/vaapi/vaapi_videodecoder.h b/src/vaapi/vaapi_videodecoder.h new file mode 100644 index 0000000000..70c82c8c19 --- /dev/null +++ b/src/vaapi/vaapi_videodecoder.h @@ -0,0 +1,69 @@ +/* +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 +#include +#include +#include +#include +#include +#include + +#include "commons.h" +#include "vaapi_videodecoder.h" + +// class implementing highlevel vaapi decoder +/***********************************************************************************************************/ +//! requirement is as follows +//! +//! In order to minimize decode latencies, there should be always at least enough pictures (min 2) in the decode +//! queue at any time, in order to make sure that all VCN decode engines are always busy. +//! In addition to the reqular create and destroy: the decoder needs to have a task-Q for submitting decoding jobs from the high level +//! +//! Overall data flow: +//! - GetCaps(...) +//! - CreateVideoDecoder(...) +//! - For each picture: +//! + submitDecodeTask(0) /* submit first frame for decoding */ +//! + ... /* submit next frame for decoding */ +//! + submitDecodeTask(N) /* N is determined based on available HW decode engines in the system */ +//! +//! + QueryStatus(N-4) /* Query the decode status of N-4 frame */ +//! + MapVideoFrame(N-4) +//! + do some processing in HIP +//! + UnmapVideoFrame(N-4) +//! + submitDecodeTask(N+1) +//! + MapVideoFrame(N-3) +//! + ... +//! - DestroyVideoDecoder(...) +//! +//! NOTE: +//! - The decoder has to maintain a Q for decode jobs with associated picture buffers +//! - An intenal thread has to pick up the next available job: If none wait for the Q to fill +/***********************************************************************************************************/ + +class vaapiVideoDecoder { +public: + +}; \ No newline at end of file