From 4f7d6d7f1c531d040cf2bc4fc46df1624635a803 Mon Sep 17 00:00:00 2001 From: "Trowbridge, Ian" Date: Thu, 12 Jun 2025 10:49:08 -0500 Subject: [PATCH] Removed roc_video_dec files due to reoccurring errors (#439) * Removed roc_video_dec files due to reoccurring errors * Added back rocDecCreateVideoParser * Fix remaining errors with rocdecode.cpp [ROCm/rocprofiler-sdk commit: 72b97a8b7e8322e78314f8b9164b96bec7d1c044] --- .../tests/bin/rocdecode/CMakeLists.txt | 4 +- .../tests/bin/rocdecode/roc_video_dec.cpp | 1464 ----------------- .../tests/bin/rocdecode/roc_video_dec.h | 658 -------- .../tests/bin/rocdecode/rocdecode.cpp | 77 +- .../tests/rocdecode/validate.py | 1 - .../rocprofv3/rocdecode-trace/validate.py | 1 - 6 files changed, 53 insertions(+), 2152 deletions(-) delete mode 100644 projects/rocprofiler-sdk/tests/bin/rocdecode/roc_video_dec.cpp delete mode 100644 projects/rocprofiler-sdk/tests/bin/rocdecode/roc_video_dec.h diff --git a/projects/rocprofiler-sdk/tests/bin/rocdecode/CMakeLists.txt b/projects/rocprofiler-sdk/tests/bin/rocdecode/CMakeLists.txt index c0f54f517a..fd2ad275ed 100644 --- a/projects/rocprofiler-sdk/tests/bin/rocdecode/CMakeLists.txt +++ b/projects/rocprofiler-sdk/tests/bin/rocdecode/CMakeLists.txt @@ -32,9 +32,9 @@ set(CMAKE_HIP_STANDARD 17) set(CMAKE_HIP_EXTENSIONS OFF) set(CMAKE_HIP_STANDARD_REQUIRED ON) -set_source_files_properties(rocdecode.cpp roc_video_dec.cpp PROPERTIES LANGUAGE HIP) +set_source_files_properties(rocdecode.cpp PROPERTIES LANGUAGE HIP) add_executable(rocdecode-demo) -target_sources(rocdecode-demo PRIVATE rocdecode.cpp roc_video_dec.cpp) +target_sources(rocdecode-demo PRIVATE rocdecode.cpp) find_package(Threads REQUIRED) find_package(rocDecode REQUIRED) diff --git a/projects/rocprofiler-sdk/tests/bin/rocdecode/roc_video_dec.cpp b/projects/rocprofiler-sdk/tests/bin/rocdecode/roc_video_dec.cpp deleted file mode 100644 index 36582e791b..0000000000 --- a/projects/rocprofiler-sdk/tests/bin/rocdecode/roc_video_dec.cpp +++ /dev/null @@ -1,1464 +0,0 @@ -/* -Copyright (c) 2024 - 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. -*/ - -#include "roc_video_dec.h" - -RocVideoDecoder::RocVideoDecoder(int device_id, - OutputSurfaceMemoryType out_mem_type, - rocDecVideoCodec codec, - bool force_zero_latency, - 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) -, b_extract_sei_message_(extract_user_sei_Message) -, b_force_zero_latency_(force_zero_latency) -, disp_delay_(disp_delay) -, codec_id_(codec) -, max_width_(max_width) -, max_height_(max_height) -{ - if(!InitHIP(device_id_)) - { - THROW("Failed to initilize the HIP"); - } - if(p_crop_rect) crop_rect_ = *p_crop_rect; - if(b_extract_sei_message_) - { - fp_sei_ = fopen("rocdec_sei_message.txt", "wb"); - curr_sei_message_ptr_ = new RocdecSeiMessageInfo; - memset(&sei_message_display_q_, 0, sizeof(sei_message_display_q_)); - } - // create rocdec videoparser - RocdecParserParams parser_params = {}; - parser_params.codec_type = codec_id_; - parser_params.max_num_decode_surfaces = - 1; // let the parser to determine the decode buffer pool size - parser_params.clock_rate = clk_rate; - parser_params.max_display_delay = disp_delay_; - parser_params.user_data = this; - parser_params.pfn_sequence_callback = HandleVideoSequenceProc; - parser_params.pfn_decode_picture = HandlePictureDecodeProc; - parser_params.pfn_display_picture = b_force_zero_latency_ ? NULL : HandlePictureDisplayProc; - parser_params.pfn_get_sei_msg = b_extract_sei_message_ ? HandleSEIMessagesProc : NULL; - ROCDEC_API_CALL(rocDecCreateVideoParser(&rocdec_parser_, &parser_params)); -} - -RocVideoDecoder::~RocVideoDecoder() -{ - auto start_time = StartTimer(); - if(curr_sei_message_ptr_) - { - delete curr_sei_message_ptr_; - curr_sei_message_ptr_ = nullptr; - } - - if(fp_sei_) - { - fclose(fp_sei_); - fp_sei_ = nullptr; - } - - if(rocdec_parser_) - { - rocDecDestroyVideoParser(rocdec_parser_); - rocdec_parser_ = nullptr; - } - - if(roc_decoder_) - { - rocDecDestroyDecoder(roc_decoder_); - roc_decoder_ = nullptr; - } - - if(curr_video_format_ptr_) - { - delete curr_video_format_ptr_; - curr_video_format_ptr_ = nullptr; - } - - std::lock_guard lock(mtx_vp_frame_); - if(out_mem_type_ != OUT_SURFACE_MEM_DEV_INTERNAL) - { - for(auto& p_frame : vp_frames_) - { - if(p_frame.frame_ptr) - { - if(out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) - { - hipError_t hip_status = hipFree(p_frame.frame_ptr); - if(hip_status != hipSuccess) - { - std::cerr << "ERROR: hipFree failed! (" << hip_status << ")" << std::endl; - } - } - else - delete[](p_frame.frame_ptr); - p_frame.frame_ptr = nullptr; - } - } - } - if(hip_stream_) - { - hipError_t hip_status = hipSuccess; - hip_status = hipStreamDestroy(hip_stream_); - if(hip_status != hipSuccess) - { - std::cerr << "ERROR: hipStream_Destroy failed! (" << hip_status << ")" << std::endl; - } - } - if(fp_out_) - { - fclose(fp_out_); - fp_out_ = nullptr; - } - - double elapsed_time = StopTimer(start_time); - AddDecoderSessionOverHead(std::this_thread::get_id(), elapsed_time); -} - -static const char* -GetVideoCodecString(rocDecVideoCodec e_codec) -{ - static struct - { - rocDecVideoCodec e_codec; - const char* name; - } aCodecName[] = { - {rocDecVideoCodec_MPEG1, "MPEG-1"}, - {rocDecVideoCodec_MPEG2, "MPEG-2"}, - {rocDecVideoCodec_MPEG4, "MPEG-4 (ASP)"}, - {rocDecVideoCodec_AVC, "AVC/H.264"}, - {rocDecVideoCodec_HEVC, "H.265/HEVC"}, - {rocDecVideoCodec_AV1, "AV1"}, - {rocDecVideoCodec_VP8, "VP8"}, - {rocDecVideoCodec_VP9, "VP9"}, - {rocDecVideoCodec_JPEG, "M-JPEG"}, - {rocDecVideoCodec_NumCodecs, "Invalid"}, - }; - - if(e_codec >= 0 && e_codec <= rocDecVideoCodec_NumCodecs) - { - return aCodecName[e_codec].name; - } - for(size_t i = rocDecVideoCodec_NumCodecs + 1; i < sizeof(aCodecName) / sizeof(aCodecName[0]); - i++) - { - if(e_codec == aCodecName[i].e_codec) - { - return aCodecName[e_codec].name; - } - } - return "Unknown"; -} - -/** - * @brief function to return the name from codec_id - * - * @param codec_id - * @return const char* - */ -const char* -RocVideoDecoder::GetCodecFmtName(rocDecVideoCodec codec_id) -{ - return GetVideoCodecString(codec_id); -} - -static const char* -GetSurfaceFormatString(rocDecVideoSurfaceFormat surface_format_id) -{ - static struct - { - rocDecVideoSurfaceFormat surf_fmt; - const char* name; - } SurfName[] = { - {rocDecVideoSurfaceFormat_NV12, "NV12"}, - {rocDecVideoSurfaceFormat_P016, "P016"}, - {rocDecVideoSurfaceFormat_YUV444, "YUV444"}, - {rocDecVideoSurfaceFormat_YUV444_16Bit, "YUV444_16Bit"}, - }; - - if(surface_format_id >= rocDecVideoSurfaceFormat_NV12 && - surface_format_id <= rocDecVideoSurfaceFormat_YUV444_16Bit) - return SurfName[surface_format_id].name; - else - return "Unknown"; -} - -/** - * @brief function to return the name from surface_format_id - * - * @param surface_format_id - enum for surface format - * @return const char* - */ -const char* -RocVideoDecoder::GetSurfaceFmtName(rocDecVideoSurfaceFormat surface_format_id) -{ - return GetSurfaceFormatString(surface_format_id); -} - -static const char* -GetVideoChromaFormatName(rocDecVideoChromaFormat e_chroma_format) -{ - static struct - { - rocDecVideoChromaFormat chroma_fmt; - const char* name; - } ChromaFormatName[] = { - {rocDecVideoChromaFormat_Monochrome, "YUV 400 (Monochrome)"}, - {rocDecVideoChromaFormat_420, "YUV 420"}, - {rocDecVideoChromaFormat_422, "YUV 422"}, - {rocDecVideoChromaFormat_444, "YUV 444"}, - }; - - if(e_chroma_format >= 0 && e_chroma_format <= rocDecVideoChromaFormat_444) - { - return ChromaFormatName[e_chroma_format].name; - } - return "Unknown"; -} - -static void -GetSurfaceStrideInternal(rocDecVideoSurfaceFormat surface_format, - uint32_t width, - uint32_t height, - uint32_t* pitch, - uint32_t* vstride) -{ - switch(surface_format) - { - case rocDecVideoSurfaceFormat_NV12: - *pitch = align(width, 256); - *vstride = align(height, 16); - break; - case rocDecVideoSurfaceFormat_P016: - *pitch = align(width, 128) * 2; - *vstride = align(height, 16); - break; - case rocDecVideoSurfaceFormat_YUV444: - *pitch = align(width, 256); - *vstride = align(height, 16); - break; - case rocDecVideoSurfaceFormat_YUV444_16Bit: - *pitch = align(width, 128) * 2; - *vstride = align(height, 16); - break; - case rocDecVideoSurfaceFormat_YUV420: - *pitch = align(width, 256); - *vstride = align(height, 16); - break; - case rocDecVideoSurfaceFormat_YUV420_16Bit: - *pitch = align(width, 128) * 2; - *vstride = align(height, 16); - break; - case rocDecVideoSurfaceFormat_YUV422: - *pitch = align(width, 256); - *vstride = align(height, 16); - break; - case rocDecVideoSurfaceFormat_YUV422_16Bit: - *pitch = align(width, 128) * 2; - *vstride = align(height, 16); - break; - } - return; -} - -/* Return value from HandleVideoSequence() are interpreted as : - * 0: fail, 1: succeeded, > 1: override dpb size of parser (set by - * CUVIDPARSERPARAMS::max_num_decode_surfaces while creating parser) - */ -int -RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat* p_video_format) -{ - if(p_video_format == nullptr) - { - ROCDEC_THROW("Rocdec:: Invalid video format in HandleVideoSequence: ", - ROCDEC_INVALID_PARAMETER); - return 0; - } - auto start_time = StartTimer(); - input_video_info_str_.str(""); - input_video_info_str_.clear(); - input_video_info_str_ << "Input Video Information" << std::endl - << "\tCodec : " << GetCodecFmtName(p_video_format->codec) - << std::endl; - if(p_video_format->frame_rate.numerator && p_video_format->frame_rate.denominator) - { - input_video_info_str_ << "\tFrame rate : " << p_video_format->frame_rate.numerator << "/" - << p_video_format->frame_rate.denominator << " = " - << 1.0 * p_video_format->frame_rate.numerator / - p_video_format->frame_rate.denominator - << " fps" << std::endl; - } - input_video_info_str_ << "\tSequence : " - << (p_video_format->progressive_sequence ? "Progressive" : "Interlaced") - << std::endl - << "\tCoded size : [" << p_video_format->coded_width << ", " - << p_video_format->coded_height << "]" << std::endl - << "\tDisplay area : [" << p_video_format->display_area.left << ", " - << p_video_format->display_area.top << ", " - << p_video_format->display_area.right << ", " - << p_video_format->display_area.bottom << "]" << std::endl - << "\tChroma : " - << GetVideoChromaFormatName(p_video_format->chroma_format) << std::endl - << "\tBit depth : " << p_video_format->bit_depth_luma_minus8 + 8; - input_video_info_str_ << std::endl; - - int num_decode_surfaces = p_video_format->min_num_decode_surfaces; - - RocdecDecodeCaps decode_caps; - memset(&decode_caps, 0, sizeof(decode_caps)); - decode_caps.codec_type = p_video_format->codec; - decode_caps.chroma_format = p_video_format->chroma_format; - decode_caps.bit_depth_minus_8 = p_video_format->bit_depth_luma_minus8; - - rocDecGetDecoderCaps(&decode_caps); - if(!decode_caps.is_supported) - { - ROCDEC_THROW("rocDecode:: Codec not supported on this GPU ", ROCDEC_NOT_SUPPORTED); - return 0; - } - if((p_video_format->coded_width > decode_caps.max_width) || - (p_video_format->coded_height > decode_caps.max_height)) - { - std::ostringstream errorString; - errorString << std::endl - << "Resolution : " << p_video_format->coded_width << "x" - << p_video_format->coded_height << std::endl - << "Max Supported (wxh) : " << decode_caps.max_width << "x" - << decode_caps.max_height << std::endl - << "Resolution not supported on this GPU "; - const std::string cErr = errorString.str(); - ROCDEC_THROW(cErr, ROCDEC_NOT_SUPPORTED); - return 0; - } - if(curr_video_format_ptr_ == nullptr) - { - curr_video_format_ptr_ = new RocdecVideoFormat(); - } - // store current video format: this is required to call reconfigure from application in case of - // random seek - if(curr_video_format_ptr_) - memcpy(curr_video_format_ptr_, p_video_format, sizeof(RocdecVideoFormat)); - - if(coded_width_ && coded_height_) - { - // rocdecCreateDecoder() has been called before, and now there's possible config change - return ReconfigureDecoder(p_video_format); - } - // e_codec has been set in the constructor (for parser). Here it's set again for potential - // correction - codec_id_ = p_video_format->codec; - video_chroma_format_ = p_video_format->chroma_format; - bitdepth_minus_8_ = p_video_format->bit_depth_luma_minus8; - byte_per_pixel_ = bitdepth_minus_8_ > 0 ? 2 : 1; - - // Set the output surface format same as chroma format - if(video_chroma_format_ == rocDecVideoChromaFormat_420 || rocDecVideoChromaFormat_Monochrome) - video_surface_format_ = - bitdepth_minus_8_ ? rocDecVideoSurfaceFormat_P016 : rocDecVideoSurfaceFormat_NV12; - else if(video_chroma_format_ == rocDecVideoChromaFormat_444) - video_surface_format_ = bitdepth_minus_8_ ? rocDecVideoSurfaceFormat_YUV444_16Bit - : rocDecVideoSurfaceFormat_YUV444; - else if(video_chroma_format_ == rocDecVideoChromaFormat_422) - video_surface_format_ = rocDecVideoSurfaceFormat_NV12; - - // Check if output format supported. If not, check falback options - if(!(decode_caps.output_format_mask & (1 << video_surface_format_))) - { - if(decode_caps.output_format_mask & (1 << rocDecVideoSurfaceFormat_NV12)) - video_surface_format_ = rocDecVideoSurfaceFormat_NV12; - else if(decode_caps.output_format_mask & (1 << rocDecVideoSurfaceFormat_P016)) - video_surface_format_ = rocDecVideoSurfaceFormat_P016; - else if(decode_caps.output_format_mask & (1 << rocDecVideoSurfaceFormat_YUV444)) - video_surface_format_ = rocDecVideoSurfaceFormat_YUV444; - else if(decode_caps.output_format_mask & (1 << rocDecVideoSurfaceFormat_YUV444_16Bit)) - video_surface_format_ = rocDecVideoSurfaceFormat_YUV444_16Bit; - else - ROCDEC_THROW("No supported output format found", ROCDEC_NOT_SUPPORTED); - } - - coded_width_ = p_video_format->coded_width; - coded_height_ = p_video_format->coded_height; - disp_rect_.top = p_video_format->display_area.top; - disp_rect_.bottom = p_video_format->display_area.bottom; - disp_rect_.left = p_video_format->display_area.left; - disp_rect_.right = p_video_format->display_area.right; - disp_width_ = p_video_format->display_area.right - p_video_format->display_area.left; - disp_height_ = p_video_format->display_area.bottom - p_video_format->display_area.top; - - // AV1 has max width/height of sequence in sequence header - if(codec_id_ == rocDecVideoCodec_AV1 && p_video_format->seqhdr_data_length > 0) - { - // dont overwrite if it is already set from cmdline or reconfig.txt - if(!(static_cast(max_width_) > p_video_format->coded_width || - static_cast(max_height_) > p_video_format->coded_height)) - { - RocdecVideoFormatEx* vidFormatEx = (RocdecVideoFormatEx*) p_video_format; - max_width_ = vidFormatEx->max_width; - max_height_ = vidFormatEx->max_height; - } - } - if(max_width_ < (int) p_video_format->coded_width) max_width_ = p_video_format->coded_width; - if(max_height_ < (int) p_video_format->coded_height) max_height_ = p_video_format->coded_height; - - RocDecoderCreateInfo videoDecodeCreateInfo = {}; - videoDecodeCreateInfo.device_id = device_id_; - videoDecodeCreateInfo.codec_type = codec_id_; - videoDecodeCreateInfo.chroma_format = video_chroma_format_; - videoDecodeCreateInfo.output_format = video_surface_format_; - videoDecodeCreateInfo.bit_depth_minus_8 = bitdepth_minus_8_; - videoDecodeCreateInfo.num_decode_surfaces = num_decode_surfaces; - videoDecodeCreateInfo.width = coded_width_; - videoDecodeCreateInfo.height = coded_height_; - videoDecodeCreateInfo.max_width = max_width_; - videoDecodeCreateInfo.max_height = max_height_; - if(!(crop_rect_.right && crop_rect_.bottom)) - { - videoDecodeCreateInfo.display_rect.top = disp_rect_.top; - videoDecodeCreateInfo.display_rect.bottom = disp_rect_.bottom; - videoDecodeCreateInfo.display_rect.left = disp_rect_.left; - videoDecodeCreateInfo.display_rect.right = disp_rect_.right; - target_width_ = (disp_width_ + 1) & ~1; - target_height_ = (disp_height_ + 1) & ~1; - } - else - { - videoDecodeCreateInfo.display_rect.top = crop_rect_.top; - videoDecodeCreateInfo.display_rect.bottom = crop_rect_.bottom; - videoDecodeCreateInfo.display_rect.left = crop_rect_.left; - videoDecodeCreateInfo.display_rect.right = crop_rect_.right; - target_width_ = (crop_rect_.right - crop_rect_.left + 1) & ~1; - target_height_ = (crop_rect_.bottom - crop_rect_.top + 1) & ~1; - } - videoDecodeCreateInfo.target_width = target_width_; - videoDecodeCreateInfo.target_height = target_height_; - - chroma_height_ = (int) (ceil(target_height_ * GetChromaHeightFactor(video_surface_format_))); - num_chroma_planes_ = GetChromaPlaneCount(video_surface_format_); - if(video_chroma_format_ == rocDecVideoChromaFormat_Monochrome) num_chroma_planes_ = 0; - if(out_mem_type_ == OUT_SURFACE_MEM_DEV_INTERNAL || out_mem_type_ == OUT_SURFACE_MEM_NOT_MAPPED) - GetSurfaceStrideInternal(video_surface_format_, - p_video_format->coded_width, - p_video_format->coded_height, - &surface_stride_, - &surface_vstride_); - else - { - surface_stride_ = - videoDecodeCreateInfo.target_width * - byte_per_pixel_; // todo:: check if we need pitched memory for faster copy - } - chroma_vstride_ = (int) (ceil(surface_vstride_ * GetChromaHeightFactor(video_surface_format_))); - // fill output_surface_info_ - output_surface_info_.output_width = target_width_; - output_surface_info_.output_height = target_height_; - output_surface_info_.output_pitch = surface_stride_; - output_surface_info_.output_vstride = (out_mem_type_ == OUT_SURFACE_MEM_DEV_INTERNAL) - ? surface_vstride_ - : videoDecodeCreateInfo.target_height; - output_surface_info_.disp_rect = disp_rect_; - output_surface_info_.chroma_height = chroma_height_; - output_surface_info_.bit_depth = bitdepth_minus_8_ + 8; - output_surface_info_.bytes_per_pixel = byte_per_pixel_; - output_surface_info_.surface_format = video_surface_format_; - output_surface_info_.num_chroma_planes = num_chroma_planes_; - if(out_mem_type_ == OUT_SURFACE_MEM_DEV_INTERNAL) - { - output_surface_info_.output_surface_size_in_bytes = - surface_stride_ * (surface_vstride_ + (chroma_vstride_ * num_chroma_planes_)); - output_surface_info_.mem_type = OUT_SURFACE_MEM_DEV_INTERNAL; - } - else if(out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) - { - output_surface_info_.output_surface_size_in_bytes = GetFrameSize(); - output_surface_info_.mem_type = OUT_SURFACE_MEM_DEV_COPIED; - } - else if(out_mem_type_ == OUT_SURFACE_MEM_HOST_COPIED) - { - output_surface_info_.output_surface_size_in_bytes = GetFrameSize(); - output_surface_info_.mem_type = OUT_SURFACE_MEM_HOST_COPIED; - } - else - { - output_surface_info_.output_surface_size_in_bytes = - surface_stride_ * (surface_vstride_ + (chroma_vstride_ * num_chroma_planes_)); - output_surface_info_.mem_type = OUT_SURFACE_MEM_NOT_MAPPED; - } - - input_video_info_str_ << "Video Decoding Params:" << std::endl - << "\tNum Surfaces : " << videoDecodeCreateInfo.num_decode_surfaces - << std::endl - << "\tCrop : [" << videoDecodeCreateInfo.display_rect.left << ", " - << videoDecodeCreateInfo.display_rect.top << ", " - << videoDecodeCreateInfo.display_rect.right << ", " - << videoDecodeCreateInfo.display_rect.bottom << "]" << std::endl - << "\tResize : " << videoDecodeCreateInfo.target_width << "x" - << videoDecodeCreateInfo.target_height << std::endl; - input_video_info_str_ << std::endl; - std::cout << input_video_info_str_.str(); - - ROCDEC_API_CALL(rocDecCreateDecoder(&roc_decoder_, &videoDecodeCreateInfo)); - double elapsed_time = StopTimer(start_time); - AddDecoderSessionOverHead(std::this_thread::get_id(), elapsed_time); - return num_decode_surfaces; -} - -/** - * @brief Function to set the Reconfig Params object - * - * @param p_reconfig_params: pointer to reconfig params struct - * @return true : success - * @return false : fail - */ -bool -RocVideoDecoder::SetReconfigParams(ReconfigParams* p_reconfig_params, bool b_force_reconfig_flush) -{ - if(!p_reconfig_params) - { - std::cerr << "ERROR: Invalid reconfig struct passed! " << std::endl; - return false; - } - // save it - p_reconfig_params_ = p_reconfig_params; - b_force_recofig_flush_ = b_force_reconfig_flush; - return true; -} - -/** - * @brief Function to force Reconfigure Flush: needed for random seeking to key frames - * - * @return int 1: Success 0: Fail - */ -int -RocVideoDecoder::FlushAndReconfigure() -{ - if(!p_reconfig_params_) - { - std::cerr << "ERROR: Reconfig params is not set! " << std::endl; - return 0; - } - if(!curr_video_format_ptr_) - { - std::cerr << "ERROR: video format is not initialized! " << std::endl; - return 0; - } - // call reconfigure - b_force_recofig_flush_ = true; // if not already set to force reconfigure - ReconfigureDecoder(curr_video_format_ptr_); - return true; -} - -/** - * @brief function to reconfigure decoder if there is a change in sequence params. - * - * @param p_video_format - * @return int 1: success 0: fail - */ -int -RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat* p_video_format) -{ - if(p_video_format->codec != codec_id_) - { - ROCDEC_THROW("Reconfigure Not supported for codec change", ROCDEC_NOT_SUPPORTED); - return 0; - } - if(p_video_format->chroma_format != video_chroma_format_) - { - ROCDEC_THROW("Reconfigure Not supported for chroma format change", ROCDEC_NOT_SUPPORTED); - return 0; - } - if(p_video_format->bit_depth_luma_minus8 != bitdepth_minus_8_) - { - ROCDEC_THROW("Reconfigure Not supported for bit depth change", ROCDEC_NOT_SUPPORTED); - return 0; - } - bool is_decode_res_changed = !(p_video_format->coded_width == coded_width_ && - p_video_format->coded_height == coded_height_); - bool is_display_rect_changed = !(p_video_format->display_area.bottom == disp_rect_.bottom && - p_video_format->display_area.top == disp_rect_.top && - p_video_format->display_area.left == disp_rect_.left && - p_video_format->display_area.right == disp_rect_.right); - - if(!is_decode_res_changed && !is_display_rect_changed && !b_force_recofig_flush_) - { - return 1; - } - - // Flush and clear internal frame store to reconfigure when either coded size or display size - // has changed. - if(p_reconfig_params_ && p_reconfig_params_->p_fn_reconfigure_flush) - num_frames_flushed_during_reconfig_ += p_reconfig_params_->p_fn_reconfigure_flush( - this, - p_reconfig_params_->reconfig_flush_mode, - static_cast(p_reconfig_params_->p_reconfig_user_struct)); - // clear the existing output buffers of different size - // note that app lose the remaining frames in the vp_frames/vp_frames_q in case application - // didn't set p_fn_reconfigure_flush_ callback - if(out_mem_type_ == OUT_SURFACE_MEM_DEV_INTERNAL) - { - ReleaseInternalFrames(); - } - else - { - std::lock_guard lock(mtx_vp_frame_); - while(!vp_frames_.empty()) - { - DecFrameBuffer* p_frame = &vp_frames_.back(); - // pop decoded frame - vp_frames_.pop_back(); - if(p_frame->frame_ptr) - { - if(out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) - { - hipError_t hip_status = hipFree(p_frame->frame_ptr); - if(hip_status != hipSuccess) - std::cerr << "ERROR: hipFree failed! (" << hip_status << ")" << std::endl; - } - else - delete[](p_frame->frame_ptr); - } - } - } - output_frame_cnt_ = 0; // reset frame_count - if(is_decode_res_changed) - { - coded_width_ = p_video_format->coded_width; - coded_height_ = p_video_format->coded_height; - } - if(is_display_rect_changed) - { - disp_rect_.left = p_video_format->display_area.left; - disp_rect_.right = p_video_format->display_area.right; - disp_rect_.top = p_video_format->display_area.top; - disp_rect_.bottom = p_video_format->display_area.bottom; - disp_width_ = p_video_format->display_area.right - p_video_format->display_area.left; - disp_height_ = p_video_format->display_area.bottom - p_video_format->display_area.top; - chroma_height_ = static_cast( - std::ceil(target_height_ * GetChromaHeightFactor(video_surface_format_))); - if(!(crop_rect_.right && crop_rect_.bottom)) - { - target_width_ = (disp_width_ + 1) & ~1; - target_height_ = (disp_height_ + 1) & ~1; - } - else - { - target_width_ = (crop_rect_.right - crop_rect_.left + 1) & ~1; - target_height_ = (crop_rect_.bottom - crop_rect_.top + 1) & ~1; - } - } - - if(out_mem_type_ == OUT_SURFACE_MEM_DEV_INTERNAL || out_mem_type_ == OUT_SURFACE_MEM_NOT_MAPPED) - { - GetSurfaceStrideInternal(video_surface_format_, - coded_width_, - coded_height_, - &surface_stride_, - &surface_vstride_); - } - else - { - surface_stride_ = target_width_ * byte_per_pixel_; - } - chroma_height_ = - static_cast(ceil(target_height_ * GetChromaHeightFactor(video_surface_format_))); - num_chroma_planes_ = GetChromaPlaneCount(video_surface_format_); - if(p_video_format->chroma_format == rocDecVideoChromaFormat_Monochrome) num_chroma_planes_ = 0; - chroma_vstride_ = static_cast( - std::ceil(surface_vstride_ * GetChromaHeightFactor(video_surface_format_))); - // Fill output_surface_info_ - output_surface_info_.output_width = target_width_; - output_surface_info_.output_height = target_height_; - output_surface_info_.output_pitch = surface_stride_; - output_surface_info_.output_vstride = - (out_mem_type_ == OUT_SURFACE_MEM_DEV_INTERNAL) ? surface_vstride_ : target_height_; - output_surface_info_.disp_rect = disp_rect_; - output_surface_info_.chroma_height = chroma_height_; - output_surface_info_.bit_depth = bitdepth_minus_8_ + 8; - output_surface_info_.bytes_per_pixel = byte_per_pixel_; - output_surface_info_.surface_format = video_surface_format_; - output_surface_info_.num_chroma_planes = num_chroma_planes_; - if(out_mem_type_ == OUT_SURFACE_MEM_DEV_INTERNAL) - { - output_surface_info_.output_surface_size_in_bytes = - surface_stride_ * (surface_vstride_ + (chroma_vstride_ * num_chroma_planes_)); - output_surface_info_.mem_type = OUT_SURFACE_MEM_DEV_INTERNAL; - } - else if(out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) - { - output_surface_info_.output_surface_size_in_bytes = GetFrameSize(); - output_surface_info_.mem_type = OUT_SURFACE_MEM_DEV_COPIED; - } - else if(out_mem_type_ == OUT_SURFACE_MEM_HOST_COPIED) - { - output_surface_info_.output_surface_size_in_bytes = GetFrameSize(); - output_surface_info_.mem_type = OUT_SURFACE_MEM_HOST_COPIED; - } - else - { - output_surface_info_.output_surface_size_in_bytes = - surface_stride_ * (surface_vstride_ + (chroma_vstride_ * num_chroma_planes_)); - output_surface_info_.mem_type = OUT_SURFACE_MEM_NOT_MAPPED; - } - - // If the coded_width or coded_height hasn't changed but display resolution has changed, then - // need to update width and height for correct output with cropping. There is no need to - // reconfigure the decoder. - if(!is_decode_res_changed && is_display_rect_changed) - { - return 1; - } - - RocdecReconfigureDecoderInfo reconfig_params = {}; - reconfig_params.width = coded_width_; - reconfig_params.height = coded_height_; - reconfig_params.target_width = target_width_; - reconfig_params.target_height = target_height_; - reconfig_params.num_decode_surfaces = p_video_format->min_num_decode_surfaces; - if(!(crop_rect_.right && crop_rect_.bottom)) - { - reconfig_params.display_rect.top = disp_rect_.top; - reconfig_params.display_rect.bottom = disp_rect_.bottom; - reconfig_params.display_rect.left = disp_rect_.left; - reconfig_params.display_rect.right = disp_rect_.right; - } - else - { - reconfig_params.display_rect.top = crop_rect_.top; - reconfig_params.display_rect.bottom = crop_rect_.bottom; - reconfig_params.display_rect.left = crop_rect_.left; - reconfig_params.display_rect.right = crop_rect_.right; - } - - if(roc_decoder_ == nullptr) - { - ROCDEC_THROW("Reconfigurition of the decoder detected but the decoder was not initialized " - "previoulsy!", - ROCDEC_NOT_SUPPORTED); - return 0; - } - ROCDEC_API_CALL(rocDecReconfigureDecoder(roc_decoder_, &reconfig_params)); - - input_video_info_str_.str(""); - input_video_info_str_.clear(); - input_video_info_str_ << "Input Video Resolution Changed:" << std::endl - << "\tCoded size : [" << p_video_format->coded_width << ", " - << p_video_format->coded_height << "]" << std::endl - << "\tDisplay area : [" << p_video_format->display_area.left << ", " - << p_video_format->display_area.top << ", " - << p_video_format->display_area.right << ", " - << p_video_format->display_area.bottom << "]" << std::endl; - input_video_info_str_ << std::endl; - input_video_info_str_ << "Video Decoding Params:" << std::endl - << "\tNum Surfaces : " << reconfig_params.num_decode_surfaces << std::endl - << "\tResize : " << reconfig_params.target_width << "x" - << reconfig_params.target_height << std::endl; - input_video_info_str_ << std::endl; - std::cout << input_video_info_str_.str(); - - is_decoder_reconfigured_ = true; - return 1; -} - -/** - * @brief - * - * @param pPicParams - * @return int 1: success 0: fail - */ -int -RocVideoDecoder::HandlePictureDecode(RocdecPicParams* pPicParams) -{ - if(!roc_decoder_) - { - THROW("RocDecoder not initialized: failed with ErrCode: " + TOSTR(ROCDEC_NOT_INITIALIZED)); - } - pic_num_in_dec_order_[pPicParams->curr_pic_idx] = decode_poc_++; - ROCDEC_API_CALL(rocDecDecodeFrame(roc_decoder_, pPicParams)); - last_decode_surf_idx_ = pPicParams->curr_pic_idx; - decoded_pic_cnt_++; - if(b_force_zero_latency_ && ((!pPicParams->field_pic_flag) || (pPicParams->second_field))) - { - RocdecParserDispInfo disp_info; - memset(&disp_info, 0, sizeof(disp_info)); - disp_info.picture_index = pPicParams->curr_pic_idx; - disp_info.progressive_frame = !pPicParams->field_pic_flag; - disp_info.top_field_first = pPicParams->bottom_field_flag ^ 1; - HandlePictureDisplay(&disp_info); - } - return 1; -} - -/** - * @brief function to handle display picture - * - * @param pDispInfo - * @return int 0:fail 1: success - */ -int -RocVideoDecoder::HandlePictureDisplay(RocdecParserDispInfo* pDispInfo) -{ - RocdecProcParams video_proc_params = {}; - video_proc_params.progressive_frame = pDispInfo->progressive_frame; - video_proc_params.top_field_first = pDispInfo->top_field_first; - - if(b_extract_sei_message_) - { - if(sei_message_display_q_[pDispInfo->picture_index].sei_data) - { - // Write SEI Message - uint8_t* sei_buffer = - (uint8_t*) (sei_message_display_q_[pDispInfo->picture_index].sei_data); - uint32_t sei_num_messages = - sei_message_display_q_[pDispInfo->picture_index].sei_message_count; - RocdecSeiMessage* sei_message = - sei_message_display_q_[pDispInfo->picture_index].sei_message; - if(fp_sei_) - { - for(uint32_t i = 0; i < sei_num_messages; i++) - { - if(codec_id_ == rocDecVideoCodec_AVC || codec_id_ == rocDecVideoCodec_HEVC) - { - switch(sei_message[i].sei_message_type) - { - case SEI_TYPE_TIME_CODE: - { - // todo:: check if we need to write timecode - } - break; - case SEI_TYPE_USER_DATA_UNREGISTERED: - { - fwrite(sei_buffer, sei_message[i].sei_message_size, 1, fp_sei_); - } - break; - } - } - if(codec_id_ == rocDecVideoCodec_AV1) - { - fwrite(sei_buffer, sei_message[i].sei_message_size, 1, fp_sei_); - } - sei_buffer += sei_message[i].sei_message_size; - } - } - free(sei_message_display_q_[pDispInfo->picture_index].sei_data); - sei_message_display_q_[pDispInfo->picture_index].sei_data = - NULL; // to avoid double free - free(sei_message_display_q_[pDispInfo->picture_index].sei_message); - sei_message_display_q_[pDispInfo->picture_index].sei_message = - NULL; // to avoid double free - } - } - if(out_mem_type_ != OUT_SURFACE_MEM_NOT_MAPPED) - { - void* src_dev_ptr[3] = {0}; - uint32_t src_pitch[3] = {0}; - ROCDEC_API_CALL(rocDecGetVideoFrame( - roc_decoder_, pDispInfo->picture_index, src_dev_ptr, src_pitch, &video_proc_params)); - RocdecDecodeStatus dec_status; - memset(&dec_status, 0, sizeof(dec_status)); - rocDecStatus result = - rocDecGetDecodeStatus(roc_decoder_, pDispInfo->picture_index, &dec_status); - if(result == ROCDEC_SUCCESS && - (dec_status.decode_status == rocDecodeStatus_Error || - dec_status.decode_status == rocDecodeStatus_Error_Concealed)) - { - std::cerr << "Decode Error occurred for picture: " - << pic_num_in_dec_order_[pDispInfo->picture_index] << std::endl; - } - if(out_mem_type_ == OUT_SURFACE_MEM_DEV_INTERNAL) - { - DecFrameBuffer dec_frame = {}; - dec_frame.frame_ptr = (uint8_t*) (src_dev_ptr[0]); - dec_frame.pts = pDispInfo->pts; - dec_frame.picture_index = pDispInfo->picture_index; - std::lock_guard lock(mtx_vp_frame_); - vp_frames_q_.push(dec_frame); - output_frame_cnt_++; - } - else - { - // copy the decoded surface info device or host - uint8_t* p_dec_frame = nullptr; - { - std::lock_guard lock(mtx_vp_frame_); - // if not enough frames in stock, allocate - if((unsigned) ++output_frame_cnt_ > vp_frames_.size()) - { - num_alloced_frames_++; - DecFrameBuffer dec_frame = {}; - if(out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) - { - // allocate device memory - HIP_API_CALL(hipMalloc((void**) &dec_frame.frame_ptr, GetFrameSize())); - } - else - { - dec_frame.frame_ptr = new uint8_t[GetFrameSize()]; - } - dec_frame.pts = pDispInfo->pts; - dec_frame.picture_index = pDispInfo->picture_index; - vp_frames_.push_back(dec_frame); - } - p_dec_frame = vp_frames_[output_frame_cnt_ - 1].frame_ptr; - } - // Copy luma data - uint32_t dst_pitch = disp_width_ * byte_per_pixel_; - uint8_t* p_src_ptr_y = static_cast(src_dev_ptr[0]) + - (disp_rect_.top + crop_rect_.top) * src_pitch[0] + - (disp_rect_.left + crop_rect_.left) * byte_per_pixel_; - if(out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) - { - if(src_pitch[0] == dst_pitch) - { - int luma_size = src_pitch[0] * coded_height_; - HIP_API_CALL( - hipMemcpyDtoDAsync(p_dec_frame, p_src_ptr_y, luma_size, hip_stream_)); - } - else - { - // use 2d copy to copy an ROI - HIP_API_CALL(hipMemcpy2DAsync(p_dec_frame, - dst_pitch, - p_src_ptr_y, - src_pitch[0], - dst_pitch, - disp_height_, - hipMemcpyDeviceToDevice, - hip_stream_)); - } - } - else - HIP_API_CALL(hipMemcpy2DAsync(p_dec_frame, - dst_pitch, - p_src_ptr_y, - src_pitch[0], - dst_pitch, - disp_height_, - hipMemcpyDeviceToHost, - hip_stream_)); - - // Copy chroma plane ( ) - // rocDec output gives pointer to luma and chroma pointers seperated for the decoded - // frame - uint8_t* p_frame_uv = p_dec_frame + dst_pitch * disp_height_; - uint8_t* p_src_ptr_uv = - (num_chroma_planes_ == 1) - ? static_cast(src_dev_ptr[1]) + - ((disp_rect_.top + crop_rect_.top) >> 1) * src_pitch[1] + - (disp_rect_.left + crop_rect_.left) * byte_per_pixel_ - : static_cast(src_dev_ptr[1]) + - (disp_rect_.top + crop_rect_.top) * src_pitch[1] + - (disp_rect_.left + crop_rect_.left) * byte_per_pixel_; - if(out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) - { - if(src_pitch[1] == dst_pitch) - { - int chroma_size = chroma_height_ * dst_pitch; - HIP_API_CALL( - hipMemcpyDtoDAsync(p_frame_uv, p_src_ptr_uv, chroma_size, hip_stream_)); - } - else - { - // use 2d copy to copy an ROI - HIP_API_CALL(hipMemcpy2DAsync(p_frame_uv, - dst_pitch, - p_src_ptr_uv, - src_pitch[1], - dst_pitch, - chroma_height_, - hipMemcpyDeviceToDevice, - hip_stream_)); - } - } - else - HIP_API_CALL(hipMemcpy2DAsync(p_frame_uv, - dst_pitch, - p_src_ptr_uv, - src_pitch[1], - dst_pitch, - chroma_height_, - hipMemcpyDeviceToHost, - hip_stream_)); - - if(num_chroma_planes_ == 2) - { - uint8_t* p_frame_v = p_dec_frame + dst_pitch * (disp_height_ + chroma_height_); - uint8_t* p_src_ptr_v = static_cast(src_dev_ptr[2]) + - (disp_rect_.top + crop_rect_.top) * src_pitch[2] + - (disp_rect_.left + crop_rect_.left) * byte_per_pixel_; - if(out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) - { - if(src_pitch[2] == dst_pitch) - { - int chroma_size = chroma_height_ * dst_pitch; - HIP_API_CALL( - hipMemcpyDtoDAsync(p_frame_v, p_src_ptr_v, chroma_size, hip_stream_)); - } - else - { - // use 2d copy to copy an ROI - HIP_API_CALL(hipMemcpy2DAsync(p_frame_v, - dst_pitch, - p_src_ptr_v, - src_pitch[2], - dst_pitch, - chroma_height_, - hipMemcpyDeviceToDevice, - hip_stream_)); - } - } - else - HIP_API_CALL(hipMemcpy2DAsync(p_frame_v, - dst_pitch, - p_src_ptr_v, - src_pitch[2], - dst_pitch, - chroma_height_, - hipMemcpyDeviceToHost, - hip_stream_)); - } - - HIP_API_CALL(hipStreamSynchronize(hip_stream_)); - } - } - else - { - RocdecDecodeStatus dec_status; - memset(&dec_status, 0, sizeof(dec_status)); - rocDecStatus result = - rocDecGetDecodeStatus(roc_decoder_, pDispInfo->picture_index, &dec_status); - if(result == ROCDEC_SUCCESS && - (dec_status.decode_status == rocDecodeStatus_Error || - dec_status.decode_status == rocDecodeStatus_Error_Concealed)) - { - std::cerr << "Decode Error occurred for picture: " - << pic_num_in_dec_order_[pDispInfo->picture_index] << std::endl; - } - output_frame_cnt_++; - } - - return 1; -} - -int -RocVideoDecoder::GetSEIMessage(RocdecSeiMessageInfo* pSEIMessageInfo) -{ - uint32_t sei_num_mesages = pSEIMessageInfo->sei_message_count; - if(sei_num_mesages) - { - RocdecSeiMessage* p_sei_msg_info = pSEIMessageInfo->sei_message; - size_t total_SEI_buff_size = 0; - if((pSEIMessageInfo->picIdx < 0) || (pSEIMessageInfo->picIdx >= MAX_FRAME_NUM)) - { - ERR("Invalid picture index for SEI message: " + TOSTR(pSEIMessageInfo->picIdx)); - return 0; - } - for(uint32_t i = 0; i < sei_num_mesages; i++) - { - total_SEI_buff_size += p_sei_msg_info[i].sei_message_size; - } - if(!curr_sei_message_ptr_) - { - ERR("Out of Memory, Allocation failed for m_pCurrSEIMessage"); - return 0; - } - curr_sei_message_ptr_->sei_data = malloc(total_SEI_buff_size); - if(!curr_sei_message_ptr_->sei_data) - { - ERR("Out of Memory, Allocation failed for SEI Buffer"); - return 0; - } - memcpy(curr_sei_message_ptr_->sei_data, pSEIMessageInfo->sei_data, total_SEI_buff_size); - curr_sei_message_ptr_->sei_message = - (RocdecSeiMessage*) malloc(sizeof(RocdecSeiMessage) * sei_num_mesages); - if(!curr_sei_message_ptr_->sei_message) - { - free(curr_sei_message_ptr_->sei_data); - curr_sei_message_ptr_->sei_data = NULL; - return 0; - } - memcpy(curr_sei_message_ptr_->sei_message, - pSEIMessageInfo->sei_message, - sizeof(RocdecSeiMessage) * sei_num_mesages); - curr_sei_message_ptr_->sei_message_count = pSEIMessageInfo->sei_message_count; - sei_message_display_q_[pSEIMessageInfo->picIdx] = *curr_sei_message_ptr_; - } - return 1; -} - -int -RocVideoDecoder::DecodeFrame(const uint8_t* data, - size_t size, - int pkt_flags, - int64_t pts, - int* num_decoded_pics) -{ - output_frame_cnt_ = 0, output_frame_cnt_ret_ = 0; - decoded_pic_cnt_ = 0; - RocdecSourceDataPacket packet = {}; - packet.payload = data; - packet.payload_size = size; - packet.flags = pkt_flags | ROCDEC_PKT_TIMESTAMP; - packet.pts = pts; - if(!data || size == 0) - { - packet.flags |= ROCDEC_PKT_ENDOFSTREAM; - } - ROCDEC_API_CALL(rocDecParseVideoData(rocdec_parser_, &packet)); - if(num_decoded_pics) - { - *num_decoded_pics = decoded_pic_cnt_; - } - return output_frame_cnt_; -} - -uint8_t* -RocVideoDecoder::GetFrame(int64_t* pts) -{ - if(output_frame_cnt_ > 0) - { - std::lock_guard lock(mtx_vp_frame_); - output_frame_cnt_--; - if(out_mem_type_ == OUT_SURFACE_MEM_DEV_INTERNAL && !vp_frames_q_.empty()) - { - DecFrameBuffer* fb = &vp_frames_q_.front(); - if(pts) *pts = fb->pts; - return fb->frame_ptr; - } - else if(vp_frames_.size() > 0) - { - if(pts) *pts = vp_frames_[output_frame_cnt_ret_].pts; - return vp_frames_[output_frame_cnt_ret_++].frame_ptr; - } - } - return nullptr; -} - -/** - * @brief function to release frame after use by the application: Only used with - * "OUT_SURFACE_MEM_DEV_INTERNAL" - * - * @param pTimestamp - timestamp of the frame to be released (unmapped) - * @return true - success - * @return false - falied - */ - -bool -RocVideoDecoder::ReleaseFrame(int64_t pTimestamp, bool b_flushing) -{ - if(out_mem_type_ == OUT_SURFACE_MEM_NOT_MAPPED) return true; // nothing to do - if(out_mem_type_ != OUT_SURFACE_MEM_DEV_INTERNAL) - { - if(!b_flushing) // if not flushing the buffers are re-used, so keep them - return true; // nothing to do - else - { - DecFrameBuffer* fb = &vp_frames_[0]; - if(pTimestamp != fb->pts) - { - std::cerr << "Decoded Frame is released out of order" << std::endl; - return false; - } - vp_frames_.erase(vp_frames_.begin()); // get rid of the frames from the framestore - } - } - // only needed when using internal mapped buffer - if(!vp_frames_q_.empty()) - { - std::lock_guard lock(mtx_vp_frame_); - DecFrameBuffer* fb = &vp_frames_q_.front(); - - if(pTimestamp != fb->pts) - { - std::cerr << "Decoded Frame is released out of order" << std::endl; - return false; - } - // pop decoded frame - vp_frames_q_.pop(); - } - return true; -} - -/** - * @brief function to release all internal frames and clear the q (used with reconfigure): Only used - * with "OUT_SURFACE_MEM_DEV_INTERNAL" - * - * @return true - success - * @return false - falied - */ -bool -RocVideoDecoder::ReleaseInternalFrames() -{ - if(out_mem_type_ != OUT_SURFACE_MEM_DEV_INTERNAL || out_mem_type_ == OUT_SURFACE_MEM_NOT_MAPPED) - return true; // nothing to do - // only needed when using internal mapped buffer - while(!vp_frames_q_.empty()) - { - std::lock_guard lock(mtx_vp_frame_); - // pop decoded frame - vp_frames_q_.pop(); - } - return true; -} - -void -RocVideoDecoder::SaveFrameToFile(std::string output_file_name, - void* surf_mem, - OutputSurfaceInfo* surf_info, - size_t rgb_image_size) -{ - uint8_t* hst_ptr = nullptr; - bool is_rgb = (rgb_image_size != 0); - uint64_t output_image_size = is_rgb ? rgb_image_size : surf_info->output_surface_size_in_bytes; - if(surf_info->mem_type == OUT_SURFACE_MEM_DEV_INTERNAL || - surf_info->mem_type == OUT_SURFACE_MEM_DEV_COPIED) - { - if(hst_ptr == nullptr) - { - hst_ptr = new uint8_t[output_image_size]; - } - hipError_t hip_status = hipSuccess; - hip_status = hipMemcpyDtoH((void*) hst_ptr, surf_mem, output_image_size); - if(hip_status != hipSuccess) - { - std::cerr << "ERROR: hipMemcpyDtoH failed! (" << hipGetErrorName(hip_status) << ")" - << std::endl; - delete[] hst_ptr; - return; - } - } - else - hst_ptr = static_cast(surf_mem); - - if(current_output_filename.empty()) - { - current_output_filename = output_file_name; - } - - // don't overwrite to the same file if reconfigure is detected for a resolution changes. - if(is_decoder_reconfigured_) - { - if(fp_out_) - { - fclose(fp_out_); - fp_out_ = nullptr; - } - // Append the width and height of the new stream to the old file name to create a file name - // to save the new frames do this only if resolution changes within a stream (e.g., decoding - // a multi-resolution stream using the videoDecode app) don't append to the output_file_name - // if multiple output file name is provided (e.g., decoding multi-files using the - // videDecodeMultiFiles) - if(!current_output_filename.compare(output_file_name)) - { - std::string::size_type const pos(output_file_name.find_last_of('.')); - extra_output_file_count_++; - std::string to_append = "_" + std::to_string(surf_info->output_width) + "_" + - std::to_string(surf_info->output_height) + "_" + - std::to_string(extra_output_file_count_); - if(pos != std::string::npos) - { - output_file_name.insert(pos, to_append); - } - else - { - output_file_name += to_append; - } - } - is_decoder_reconfigured_ = false; - } - - if(fp_out_ == nullptr) - { - fp_out_ = fopen(output_file_name.c_str(), "wb"); - } - if(fp_out_) - { - if(!is_rgb) - { - uint8_t* tmp_hst_ptr = hst_ptr; - if(surf_info->mem_type == OUT_SURFACE_MEM_DEV_INTERNAL) - { - tmp_hst_ptr += ((disp_rect_.top + crop_rect_.top) * surf_info->output_pitch) + - (disp_rect_.left + crop_rect_.left) * surf_info->bytes_per_pixel; - } - auto img_width = surf_info->output_width; - auto img_height = surf_info->output_height; - auto output_stride = surf_info->output_pitch; - if(img_width * surf_info->bytes_per_pixel == output_stride && - img_height == surf_info->output_vstride) - { - fwrite(hst_ptr, 1, output_image_size, fp_out_); - } - else - { - uint32_t width = surf_info->output_width * surf_info->bytes_per_pixel; - if(surf_info->bit_depth <= 16) - { - for(uint32_t i = 0; i < surf_info->output_height; i++) - { - fwrite(tmp_hst_ptr, 1, width, fp_out_); - tmp_hst_ptr += output_stride; - } - // dump chroma - uint8_t* uv_hst_ptr = hst_ptr + output_stride * surf_info->output_vstride; - if(surf_info->mem_type == OUT_SURFACE_MEM_DEV_INTERNAL) - { - uv_hst_ptr += - (num_chroma_planes_ == 1) - ? (((disp_rect_.top + crop_rect_.top) >> 1) * - surf_info->output_pitch) + - ((disp_rect_.left + crop_rect_.left) * - surf_info->bytes_per_pixel) - : ((disp_rect_.top + crop_rect_.top) * surf_info->output_pitch) + - ((disp_rect_.left + crop_rect_.left) * - surf_info->bytes_per_pixel); - } - for(uint32_t i = 0; i < chroma_height_; i++) - { - fwrite(uv_hst_ptr, 1, width, fp_out_); - uv_hst_ptr += output_stride; - } - if(num_chroma_planes_ == 2) - { - uv_hst_ptr = - hst_ptr + output_stride * (surf_info->output_vstride + chroma_vstride_); - if(surf_info->mem_type == OUT_SURFACE_MEM_DEV_INTERNAL) - { - uv_hst_ptr += - ((disp_rect_.top + crop_rect_.top) * surf_info->output_pitch) + - ((disp_rect_.left + crop_rect_.left) * surf_info->bytes_per_pixel); - } - for(uint32_t i = 0; i < chroma_height_; i++) - { - fwrite(uv_hst_ptr, 1, width, fp_out_); - uv_hst_ptr += output_stride; - } - } - } - } - } - else - { - fwrite(hst_ptr, 1, rgb_image_size, fp_out_); - } - } - - if(hst_ptr && (surf_info->mem_type != OUT_SURFACE_MEM_HOST_COPIED)) - { - delete[] hst_ptr; - } -} - -void -RocVideoDecoder::ResetSaveFrameToFile() -{ - if(fp_out_) - { - fclose(fp_out_); - fp_out_ = nullptr; - } -} - -void -RocVideoDecoder::GetDeviceinfo(std::string& device_name, - std::string& gcn_arch_name, - int& pci_bus_id, - int& pci_domain_id, - int& pci_device_id) -{ - device_name = hip_dev_prop_.name; - gcn_arch_name = hip_dev_prop_.gcnArchName; - pci_bus_id = hip_dev_prop_.pciBusID; - pci_domain_id = hip_dev_prop_.pciDomainID; - pci_device_id = hip_dev_prop_.pciDeviceID; -} - -bool -RocVideoDecoder::GetOutputSurfaceInfo(OutputSurfaceInfo** surface_info) -{ - if(!disp_width_ || !disp_height_) - { - std::cerr << "ERROR: RocVideoDecoder is not intialized" << std::endl; - return false; - } - *surface_info = &output_surface_info_; - return true; -} - -bool -RocVideoDecoder::InitHIP(int device_id) -{ - HIP_API_CALL(hipGetDeviceCount(&num_devices_)); - if(num_devices_ < 1) - { - std::cerr << "ERROR: didn't find any GPU!" << std::endl; - return false; - } - HIP_API_CALL(hipSetDevice(device_id)); - HIP_API_CALL(hipGetDeviceProperties(&hip_dev_prop_, device_id)); - HIP_API_CALL(hipStreamCreate(&hip_stream_)); - return true; -} - -std::chrono::_V2::system_clock::time_point -RocVideoDecoder::StartTimer() -{ - return std::chrono::_V2::system_clock::now(); -} - -double -RocVideoDecoder::StopTimer(const std::chrono::_V2::system_clock::time_point& start_time) -{ - return std::chrono::duration(std::chrono::_V2::system_clock::now() - - start_time) - .count(); -} - -bool -RocVideoDecoder::CodecSupported(int device_id, rocDecVideoCodec codec_id, uint32_t bit_depth) -{ - RocdecDecodeCaps decode_caps; - decode_caps.device_id = device_id; - 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) - { - return false; - } - return true; -} - -void -RocVideoDecoder::WaitForDecodeCompletion() -{ - RocdecDecodeStatus dec_status; - memset(&dec_status, 0, sizeof(dec_status)); - do - { - rocDecGetDecodeStatus(roc_decoder_, last_decode_surf_idx_, &dec_status); - } while(dec_status.decode_status == rocDecodeStatus_InProgress); -} diff --git a/projects/rocprofiler-sdk/tests/bin/rocdecode/roc_video_dec.h b/projects/rocprofiler-sdk/tests/bin/rocdecode/roc_video_dec.h deleted file mode 100644 index 5297d35cc8..0000000000 --- a/projects/rocprofiler-sdk/tests/bin/rocdecode/roc_video_dec.h +++ /dev/null @@ -1,658 +0,0 @@ -/* -Copyright (c) 2024 - 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/*! - * \file - * \brief The AMD Video Decode Library. - * - * \defgroup group_amd_roc_video_dec rocDecode Video Decode: AMD Video Decode API - * \brief AMD The rocDecode video decoder for AMD’s GPUs. - */ - -#define MAX_FRAME_NUM 16 - -typedef int(ROCDECAPI* PFNRECONFIGUEFLUSHCALLBACK)(void*, uint32_t, void*); - -typedef enum SeiAvcHevcPayloadType_enum -{ - SEI_TYPE_TIME_CODE = 136, - SEI_TYPE_USER_DATA_UNREGISTERED = 5 -} SeiAvcHevcPayloadType; - -typedef enum OutputSurfaceMemoryType_enum -{ - OUT_SURFACE_MEM_DEV_INTERNAL = - 0, /**< Internal interopped decoded surface memory(original mapped decoded surface) */ - OUT_SURFACE_MEM_DEV_COPIED = 1, /**< decoded output will be copied to a separate device memory - (the user doesn't need to call release) **/ - OUT_SURFACE_MEM_HOST_COPIED = 2, /**< decoded output will be copied to a separate host memory - (the user doesn't need to call release) **/ - OUT_SURFACE_MEM_NOT_MAPPED = 3 /**< < decoded output is not available (interop won't be used): - useful for decode only performance app*/ -} OutputSurfaceMemoryType; - -#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; - -inline int -GetChromaPlaneCount(rocDecVideoSurfaceFormat surface_format) -{ - int num_planes = 1; - switch(surface_format) - { - case rocDecVideoSurfaceFormat_NV12: - case rocDecVideoSurfaceFormat_P016: num_planes = 1; break; - // All YUV formats have 2 planes (to my knowledge). - case rocDecVideoSurfaceFormat_YUV444: - case rocDecVideoSurfaceFormat_YUV444_16Bit: num_planes = 2; break; - case rocDecVideoSurfaceFormat_YUV422: - case rocDecVideoSurfaceFormat_YUV422_16Bit: - case rocDecVideoSurfaceFormat_YUV420: - case rocDecVideoSurfaceFormat_YUV420_16Bit: num_planes = 2; break; - } - - return num_planes; -}; - -inline float -GetChromaHeightFactor(rocDecVideoSurfaceFormat surface_format) -{ - float factor = 0.5; - switch(surface_format) - { - // NV12 and P016 have 1/2 vertical resolution, 1/2 horizontal resolution - // (different 420 sampling techniques across a single plane) - case rocDecVideoSurfaceFormat_NV12: - case rocDecVideoSurfaceFormat_P016: - // 420 pulldown has 1/2 vertical resolution, 1/2 horizontal resolution - case rocDecVideoSurfaceFormat_YUV420: - case rocDecVideoSurfaceFormat_YUV420_16Bit: factor = 0.5; break; - // 422 pulldown has full vertical resolution, 1/2 horizontal resolution - case rocDecVideoSurfaceFormat_YUV422: - case rocDecVideoSurfaceFormat_YUV422_16Bit: - // 444 pulldown has full vertical and horizontal resolution - case rocDecVideoSurfaceFormat_YUV444: - case rocDecVideoSurfaceFormat_YUV444_16Bit: factor = 1.0; break; - } - - return factor; -}; - -class RocVideoDecodeException : public std::exception -{ -public: - explicit RocVideoDecodeException(const std::string& message, const int err_code) - : _message(message) - , _err_code(err_code) - {} - explicit RocVideoDecodeException(const std::string& message) - : _message(message) - , _err_code(-1) - {} - virtual const char* what() const throw() override { return _message.c_str(); } - int Geterror_code() const { return _err_code; } - -private: - std::string _message; - int _err_code; -}; - -#define ROCDEC_THROW(X, CODE) \ - throw RocVideoDecodeException(" { " + std::string(__func__) + " } " + X, CODE); -#define THROW(X) throw RocVideoDecodeException(" { " + std::string(__func__) + " } " + X); - -#define ROCDEC_API_CALL(rocDecAPI) \ - do \ - { \ - rocDecStatus error_code = rocDecAPI; \ - if(error_code != ROCDEC_SUCCESS) \ - { \ - std::ostringstream error_log; \ - error_log << #rocDecAPI << " returned " << rocDecGetErrorName(error_code) << " at " \ - << __FILE__ << ":" << __LINE__; \ - ROCDEC_THROW(error_log.str(), error_code); \ - } \ - } while(0) - -#define HIP_API_CALL(call) \ - do \ - { \ - hipError_t hip_status = call; \ - if(hip_status != hipSuccess) \ - { \ - const char* sz_err_name = NULL; \ - sz_err_name = hipGetErrorName(hip_status); \ - std::ostringstream error_log; \ - error_log << "hip API error " << sz_err_name; \ - ROCDEC_THROW(error_log.str(), hip_status); \ - } \ - } while(0) - -struct Rect -{ - int left; - int top; - int right; - int bottom; -}; - -struct Dim -{ - int w, h; -}; - -static inline int -align(int value, int alignment) -{ - return (value + alignment - 1) & ~(alignment - 1); -} - -typedef struct DecFrameBuffer_ -{ - uint8_t* frame_ptr; /**< device memory pointer for the decoded frame */ - int64_t pts; /**< timestamp for the decoded frame */ - int picture_index; /**< surface index for the decoded frame */ -} DecFrameBuffer; - -typedef struct OutputSurfaceInfoType -{ - uint32_t output_width; /**< Output width of decoded surface*/ - uint32_t output_height; /**< Output height of decoded surface*/ - uint32_t output_pitch; /**< Output pitch in bytes of luma plane, chroma pitch can be inferred - based on chromaFormat*/ - uint32_t output_vstride; /**< Output vertical stride in case of using internal mem pointer **/ - uint32_t chroma_height; /**< Chroma plane height **/ - Rect disp_rect; /**< Display area **/ - uint32_t bytes_per_pixel; /**< Output BytesPerPixel of decoded image*/ - uint32_t bit_depth; /**< Output BitDepth of the image*/ - uint32_t num_chroma_planes; /**< Output Chroma number of planes*/ - uint64_t output_surface_size_in_bytes; /**< Output Image Size in Bytes; including both luma and - chroma planes*/ - rocDecVideoSurfaceFormat surface_format; /**< Chroma format of the decoded image*/ - OutputSurfaceMemoryType mem_type; /**< Output mem_type of the surface*/ -} OutputSurfaceInfo; - -typedef struct ReconfigParams_t -{ - PFNRECONFIGUEFLUSHCALLBACK p_fn_reconfigure_flush; - void* p_reconfig_user_struct; - uint32_t reconfig_flush_mode; -} ReconfigParams; - -class RocVideoDecoder -{ -public: - /** - * @brief Construct a new Roc Video Decoder object - * - * @param device_id : device_id to initialize HIP and VCN - * @param out_mem_type : out_mem_type for the decoded surface - * @param codec : codec type - * @param force_zero_latency : to force zero latency (output in decoding orde) - * @param p_crop_rect : to crop output - * @param extract_user_SEI_Message : enable to extract SEI - * @param disp_delay : output delayed by #disp_delay surfaces - * @param max_width : Max. width for the output surface - * @param max_height : Max. height for the output surface - * @param clk_rate : FPS clock-rate - */ - RocVideoDecoder(int device_id, - OutputSurfaceMemoryType out_mem_type, - rocDecVideoCodec codec, - bool force_zero_latency = false, - const Rect* p_crop_rect = nullptr, - bool extract_user_SEI_Message = false, - uint32_t disp_delay = 0, - int max_width = 0, - int max_height = 0, - uint32_t clk_rate = 1000); - ~RocVideoDecoder(); - - rocDecVideoCodec GetCodecId() { return codec_id_; } - - hipStream_t GetStream() { return hip_stream_; } - - /** - * @brief Get the output frame width - */ - uint32_t GetWidth() - { - assert(disp_width_); - return disp_width_; - } - - /** - * @brief This function is used to get the actual decode width - */ - int GetDecodeWidth() - { - assert(coded_width_); - return coded_width_; - } - - /** - * @brief Get the output frame height - */ - uint32_t GetHeight() - { - assert(disp_height_); - return disp_height_; - } - - /** - * @brief This function is used to get the current chroma height. - */ - int GetChromaHeight() - { - assert(chroma_height_); - return chroma_height_; - } - - /** - * @brief This function is used to get the number of chroma planes. - */ - int GetNumChromaPlanes() - { - assert(num_chroma_planes_); - return num_chroma_planes_; - } - - /** - * @brief This function is used to get the current frame size based on pixel format. - */ - virtual int GetFrameSize() - { - assert(disp_width_); - return disp_width_ * (disp_height_ + (chroma_height_ * num_chroma_planes_)) * - byte_per_pixel_; - } - - /** - * @brief Get the Bit Depth and BytesPerPixel associated with the pixel format - * - * @return uint32_t - */ - uint32_t GetBitDepth() - { - assert(bitdepth_minus_8_); - return (bitdepth_minus_8_ + 8); - } - uint32_t GetBytePerPixel() - { - assert(byte_per_pixel_); - return byte_per_pixel_; - } - /** - * @brief Functions to get the output surface attributes - */ - size_t GetSurfaceSize() - { - assert(surface_size_); - return surface_size_; - } - uint32_t GetSurfaceStride() - { - assert(surface_stride_); - return surface_stride_; - } - // RocDecImageFormat GetSubsampling() { return subsampling_; } - /** - * @brief Get the name of the output format - * - * @param codec_id - * @return std::string - */ - const char* GetCodecFmtName(rocDecVideoCodec codec_id); - - /** - * @brief function to return the name from surface_format_id - * - * @param surface_format_id - enum for surface format - * @return const char* - */ - const char* GetSurfaceFmtName(rocDecVideoSurfaceFormat surface_format_id); - - /** - * @brief Get the pointer to the Output Image Info - * - * @param surface_info ptr to output surface info - * @return true - * @return false - */ - bool GetOutputSurfaceInfo(OutputSurfaceInfo** surface_info); - - /** - * @brief Function to set the Reconfig Params object - * - * @param p_reconfig_params: pointer to reconfig params struct - * @return true : success - * @return false : fail - */ - bool SetReconfigParams(ReconfigParams* p_reconfig_params, bool b_force_reconfig_flush = false); - - /** - * @brief Function to force Reconfigure Flush: needed for random seeking to key frames - * - * @return int 1: Success 0: Fail - */ - int FlushAndReconfigure(); - /** - * @brief this function decodes a frame and returns the number of frames avalable for display - * - * @param data - pointer to the data buffer that is to be decode - * @param size - size of the data buffer in bytes - * @param pts - presentation timestamp - * @param flags - video packet flags - * @param num_decoded_pics - nummber of pictures decoded in this call - * @return int - num of frames to display - */ - virtual int DecodeFrame(const uint8_t* data, - size_t size, - int pkt_flags, - int64_t pts = 0, - int* num_decoded_pics = nullptr); - /** - * @brief This function returns a decoded frame and timestamp. This should be called in a loop - * fetching all the available frames - * - */ - virtual uint8_t* GetFrame(int64_t* pts); - - /** - * @brief function to release frame after use by the application: Only used with - * "OUT_SURFACE_MEM_DEV_INTERNAL" - * - * @param pTimestamp - timestamp of the frame to be released (unmapped) - * @param b_flushing - true when flushing - * @return true - success - * @return false - falied - */ - virtual bool ReleaseFrame(int64_t pTimestamp, bool b_flushing = false); - - /** - * @brief utility function to save image to a file - * - * @param output_file_name - file to write - * @param dev_mem - dev_memory pointer of the frame - * @param image_info - output image info - * @param is_output_RGB - to write in RGB - */ - // void SaveImage(std::string output_file_name, void* dev_mem, OutputImageInfo* image_info, bool - // is_output_RGB = 0); - - /** - * @brief Get the Device info for the current device - * - * @param device_name - * @param gcn_arch_name - * @param pci_bus_id - * @param pci_domain_id - * @param pci_device_id - */ - void GetDeviceinfo(std::string& device_name, - std::string& gcn_arch_name, - int& pci_bus_id, - int& pci_domain_id, - int& pci_device_id); - - /** - * @brief Helper function to dump decoded output surface to file - * - * @param output_file_name - Output file name - * @param dev_mem - pointer to surface memory - * @param surf_info - surface info - * @param rgb_image_size - image size for rgb (optional). A non_zero value indicates the - * surf_mem holds an rgb interleaved image and the entire size will be dumped to file - */ - virtual void SaveFrameToFile(std::string output_file_name, - void* surf_mem, - OutputSurfaceInfo* surf_info, - size_t rgb_image_size = 0); - - /** - * @brief Helper funtion to close a existing file and dump to new file in case of multiple files - * using same decoder - */ - virtual void ResetSaveFrameToFile(); - - /** - * @brief Get the Num Of Flushed Frames from video decoder object - * - * @return int32_t - */ - int32_t GetNumOfFlushedFrames() { return num_frames_flushed_during_reconfig_; } - - /*! \brief Function to wait for the decode completion of the last submitted picture - */ - void WaitForDecodeCompletion(); - - // Session overhead refers to decoder initialization and deinitialization time - void AddDecoderSessionOverHead(std::thread::id session_id, double duration) - { - session_overhead_[session_id] += duration; - } - double GetDecoderSessionOverHead(std::thread::id session_id) - { - if(session_overhead_.find(session_id) != session_overhead_.end()) - { - return session_overhead_[session_id]; - } - else - { - return 0; - } - } - - /** - * @brief Check if the given Video Codec is supported on the given GPU - * - * @return rocDecStatus - */ - bool CodecSupported(int device_id, rocDecVideoCodec codec_id, uint32_t bit_depth); - - /** - * @brief This function reconfigure decoder if there is a change in sequence params. - */ - virtual int ReconfigureDecoder(RocdecVideoFormat* p_video_format); - -protected: - /** - * @brief Callback function to be registered for getting a callback when decoding of sequence - * starts - */ - static int ROCDECAPI HandleVideoSequenceProc(void* p_user_data, - RocdecVideoFormat* p_video_format) - { - return ((RocVideoDecoder*) p_user_data)->HandleVideoSequence(p_video_format); - } - - /** - * @brief Callback function to be registered for getting a callback when a decoded frame is - * ready to be decoded - */ - static int ROCDECAPI HandlePictureDecodeProc(void* p_user_data, RocdecPicParams* p_pic_params) - { - return ((RocVideoDecoder*) p_user_data)->HandlePictureDecode(p_pic_params); - } - - /** - * @brief Callback function to be registered for getting a callback when a decoded frame is - * available for display - */ - static int ROCDECAPI HandlePictureDisplayProc(void* p_user_data, - RocdecParserDispInfo* p_disp_info) - { - return ((RocVideoDecoder*) p_user_data)->HandlePictureDisplay(p_disp_info); - } - - /** - * @brief Callback function to be registered for getting a callback when all the unregistered - * user SEI Messages are parsed for a frame. - */ - static int ROCDECAPI HandleSEIMessagesProc(void* p_user_data, - RocdecSeiMessageInfo* p_sei_message_info) - { - return ((RocVideoDecoder*) p_user_data)->GetSEIMessage(p_sei_message_info); - } - - /** - * @brief This function gets called when a sequence is ready to be decoded. The function also - gets called when there is format change - */ - int HandleVideoSequence(RocdecVideoFormat* p_video_format); - - /** - * @brief This function gets called when a picture is ready to be decoded. cuvidDecodePicture - * is called from this function to decode the picture - */ - int HandlePictureDecode(RocdecPicParams* p_pic_params); - - /** - * @brief This function gets called after a picture is decoded and available for display. - Frames are fetched and stored in internal buffer - */ - int HandlePictureDisplay(RocdecParserDispInfo* p_disp_info); - /** - * @brief This function gets called when all unregistered user SEI messages are parsed for a - * frame - */ - int GetSEIMessage(RocdecSeiMessageInfo* p_sei_message_info); - - /** - * @brief function to release all internal frames and clear the vp_frames_q_ (used with - * reconfigure): Only used with "OUT_SURFACE_MEM_DEV_INTERNAL" - * - * @return true - success - * @return false - falied - */ - bool ReleaseInternalFrames(); - - /** - * @brief Function to Initialize GPU-HIP - * - */ - bool InitHIP(int device_id); - - /** - * @brief Function to get start time - * - */ - std::chrono::_V2::system_clock::time_point StartTimer(); - - /** - * @brief Function to get elapsed time - * - */ - double StopTimer(const std::chrono::_V2::system_clock::time_point& start_time); - - int num_devices_; - int device_id_; - RocdecVideoParser rocdec_parser_ = nullptr; - rocDecDecoderHandle roc_decoder_ = nullptr; - OutputSurfaceMemoryType out_mem_type_ = OUT_SURFACE_MEM_DEV_INTERNAL; - bool b_extract_sei_message_ = false; - bool b_force_zero_latency_ = false; - uint32_t disp_delay_; - ReconfigParams* p_reconfig_params_ = nullptr; - bool b_force_recofig_flush_ = false; - int32_t num_frames_flushed_during_reconfig_ = 0; - hipDeviceProp_t hip_dev_prop_; - hipStream_t hip_stream_; - rocDecVideoCodec codec_id_ = rocDecVideoCodec_NumCodecs; - rocDecVideoChromaFormat video_chroma_format_ = rocDecVideoChromaFormat_420; - rocDecVideoSurfaceFormat video_surface_format_ = rocDecVideoSurfaceFormat_NV12; - RocdecSeiMessageInfo* curr_sei_message_ptr_ = nullptr; - RocdecSeiMessageInfo sei_message_display_q_[MAX_FRAME_NUM]; - RocdecVideoFormat* curr_video_format_ptr_ = nullptr; - int output_frame_cnt_ = 0, output_frame_cnt_ret_ = 0; - int decoded_pic_cnt_ = 0; - int decode_poc_ = 0, pic_num_in_dec_order_[MAX_FRAME_NUM]; - int num_alloced_frames_ = 0; - int last_decode_surf_idx_ = 0; - std::ostringstream input_video_info_str_; - int bitdepth_minus_8_ = 0; - uint32_t byte_per_pixel_ = 1; - uint32_t coded_width_ = 0; - uint32_t disp_width_ = 0; - uint32_t coded_height_ = 0; - uint32_t disp_height_ = 0; - uint32_t target_width_ = 0; - uint32_t target_height_ = 0; - int max_width_ = 0, max_height_ = 0; - uint32_t chroma_height_ = 0, chroma_width_ = 0; - uint32_t num_chroma_planes_ = 0; - uint32_t num_components_ = 0; - uint32_t surface_stride_ = 0; - uint32_t surface_vstride_ = 0, - chroma_vstride_ = - 0; // vertical stride between planes: used when using internal dev memory - size_t surface_size_ = 0; - OutputSurfaceInfo output_surface_info_ = {}; - std::mutex mtx_vp_frame_; - std::vector vp_frames_; // vector of decoded frames - std::queue vp_frames_q_; - Rect disp_rect_ = {}; // displayable area specified in the bitstream - Rect crop_rect_ = {}; // user specified region of interest within diplayable area disp_rect_ - FILE* fp_sei_ = NULL; - FILE* fp_out_ = NULL; - bool is_decoder_reconfigured_ = false; - std::string current_output_filename = ""; - uint32_t extra_output_file_count_ = 0; - std::thread::id - decoder_session_id_; // Decoder session identifier. Used to gather session level stats. - std::unordered_map - session_overhead_; // Records session overhead of initialization+deinitialization time. - // Format is (thread id, duration) -}; diff --git a/projects/rocprofiler-sdk/tests/bin/rocdecode/rocdecode.cpp b/projects/rocprofiler-sdk/tests/bin/rocdecode/rocdecode.cpp index 06cdf9defa..8ef8fa1ffb 100644 --- a/projects/rocprofiler-sdk/tests/bin/rocdecode/rocdecode.cpp +++ b/projects/rocprofiler-sdk/tests/bin/rocdecode/rocdecode.cpp @@ -23,8 +23,8 @@ THE SOFTWARE. #include #include #include +#include #include -#include "roc_video_dec.h" int main(int argc, char** argv) @@ -69,39 +69,64 @@ main(int argc, char** argv) return 1; } - // Set up video decoder - int device_id = 0; - OutputSurfaceMemoryType mem_type = OUT_SURFACE_MEM_DEV_INTERNAL; - bool b_force_zero_latency = false; - Rect* p_crop_rect = nullptr; - int disp_delay = 1; - bool b_extract_sei_messages = false; - RocVideoDecoder* viddec = new RocVideoDecoder(device_id, - mem_type, - rocdec_codec_id, - b_force_zero_latency, - p_crop_rect, - b_extract_sei_messages, - disp_delay); - uint8_t* pvideo = nullptr; int n_video_bytes = 0; int64_t pts = 0; - int pkg_flags = 0; - int decoded_pics = 0; if(rocDecGetBitstreamPicData(bs_reader, &pvideo, &n_video_bytes, &pts) != ROCDEC_SUCCESS) { std::cerr << "Failed to get picture data." << std::endl; return 1; } - // Treat 0 bitstream size as end of stream indicator - if(n_video_bytes == 0) - { - pkg_flags |= ROCDEC_PKT_ENDOFSTREAM; - } - viddec->DecodeFrame(pvideo, n_video_bytes, pkg_flags, pts, &decoded_pics); - viddec->DecodeFrame(pvideo, n_video_bytes, pkg_flags, pts, &decoded_pics); - viddec->DecodeFrame(pvideo, n_video_bytes, pkg_flags, pts, &decoded_pics); + + // The following commands were originally used via the RocVideoDecoder from the + // roc_video_dec.cpp file from the rocDecode repository. However, this file kept causing + // compiler issues, so the file was removed. The following commands will return errors, but they + // should should be tracked for testing purposes + + // rocDecCreateVideoParser + RocdecVideoParser rocdec_parser_ = nullptr; + RocdecParserParams parser_params = {}; + parser_params.codec_type = rocdec_codec_id; + parser_params.max_num_decode_surfaces = 1; + parser_params.clock_rate = 0; + parser_params.max_display_delay = 1; + parser_params.pfn_sequence_callback = nullptr; + parser_params.pfn_decode_picture = nullptr; + rocDecCreateVideoParser(&rocdec_parser_, &parser_params); + + // rocDecGetDecoderCaps + RocdecDecodeCaps decode_caps{}; + decode_caps.codec_type = rocdec_codec_id; + decode_caps.chroma_format = rocDecVideoChromaFormat_420; + decode_caps.bit_depth_minus_8 = 0; + rocDecGetDecoderCaps(&decode_caps); + + // rocDecCreateDecoder + rocDecDecoderHandle roc_decoder_ = nullptr; + RocDecoderCreateInfo videoDecodeCreateInfo = {}; + videoDecodeCreateInfo.device_id = 0; + videoDecodeCreateInfo.codec_type = rocdec_codec_id; + videoDecodeCreateInfo.chroma_format = rocDecVideoChromaFormat_420; + videoDecodeCreateInfo.bit_depth_minus_8 = 0; + rocDecCreateDecoder(&roc_decoder_, &videoDecodeCreateInfo); + + // rocDecDecodeFrame + RocdecPicParams* pPicParams = nullptr; + rocDecDecodeFrame(roc_decoder_, pPicParams); + + // rocDecParseVideoData + RocdecSourceDataPacket packet = {}; + rocDecParseVideoData(rocdec_parser_, &packet); + + // rocDecGetVideoFrame + void* src_dev_ptr[3] = {0}; + uint32_t src_pitch[3] = {0}; + RocdecProcParams video_proc_params = {}; + rocDecGetVideoFrame(roc_decoder_, 0, src_dev_ptr, src_pitch, &video_proc_params); + + // rocDecGetDecodeStatus + RocdecDecodeStatus dec_status{}; + rocDecGetDecodeStatus(roc_decoder_, 0, &dec_status); if(bs_reader) { rocDecDestroyBitstreamReader(bs_reader); diff --git a/projects/rocprofiler-sdk/tests/rocdecode/validate.py b/projects/rocprofiler-sdk/tests/rocdecode/validate.py index c601d78789..04ffbaa87f 100644 --- a/projects/rocprofiler-sdk/tests/rocdecode/validate.py +++ b/projects/rocprofiler-sdk/tests/rocdecode/validate.py @@ -191,7 +191,6 @@ def test_rocdecode_traces(input_data): ) for api_call in rocdecode_ext_bf_traces: assert len(api_call["args"]) > 0 - assert (api_call.retval.uint64_t_retval in [0, 1], "Unexpected return values") def test_retired_correlation_ids(input_data): diff --git a/projects/rocprofiler-sdk/tests/rocprofv3/rocdecode-trace/validate.py b/projects/rocprofiler-sdk/tests/rocprofv3/rocdecode-trace/validate.py index dc6deb7ecd..76b94b4b26 100755 --- a/projects/rocprofiler-sdk/tests/rocprofv3/rocdecode-trace/validate.py +++ b/projects/rocprofiler-sdk/tests/rocprofv3/rocdecode-trace/validate.py @@ -64,7 +64,6 @@ def test_rocdeocde(json_data): assert node.end_timestamp > 0 assert node.start_timestamp < node.end_timestamp assert len(node.args) > 0 - assert node.retval.uint64_t_retval in [0, 1], "Unexpected return values" assert ( data.strings.buffer_records[node.kind].kind == "ROCDECODE_API"