fix for hipOutOfMem bug when decoding large videos (#189)
* fix for issue 441908
[ROCm/rocdecode commit: 51ecd8fccf]
This commit is contained in:
1 förälder
5527ee0b79
incheckning
9afce4a03a
4 files changed
+108
-109
No files matched your search
@@ -59,8 +59,6 @@ void ShowHelpAndExit(const char *option = NULL) {
|
|||||||
<< "-f Number of forks (>= 1) - optional; default: 4" << std::endl
|
<< "-f Number of forks (>= 1) - optional; default: 4" << std::endl
|
||||||
<< "-d Device ID (>= 0) - optional; default: 0" << std::endl
|
<< "-d Device ID (>= 0) - optional; default: 0" << std::endl
|
||||||
<< "-z force_zero_latency (force_zero_latency, Decoded frames will be flushed out for display immediately); optional;" << std::endl
|
<< "-z force_zero_latency (force_zero_latency, Decoded frames will be flushed out for display immediately); optional;" << std::endl
|
||||||
<< "-m output_surface_memory_type - decoded surface memory; optional; default - 0"
|
|
||||||
<< " [0 : OUT_SURFACE_MEM_DEV_INTERNAL/ 1 : OUT_SURFACE_MEM_DEV_COPIED/ 2 : OUT_SURFACE_MEM_HOST_COPIED]" << std::endl;
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +68,7 @@ int main(int argc, char **argv) {
|
|||||||
int n_fork = 4;
|
int n_fork = 4;
|
||||||
int device_id = 0;
|
int device_id = 0;
|
||||||
Rect *p_crop_rect = nullptr;
|
Rect *p_crop_rect = nullptr;
|
||||||
OutputSurfaceMemoryType mem_type = OUT_SURFACE_MEM_DEV_INTERNAL; // set to internal
|
OutputSurfaceMemoryType mem_type = OUT_SURFACE_MEM_NOT_MAPPED; // set to unmapped: output frames are not mapped for performance
|
||||||
bool b_force_zero_latency = false;
|
bool b_force_zero_latency = false;
|
||||||
// Parse command-line arguments
|
// Parse command-line arguments
|
||||||
if(argc <= 1) {
|
if(argc <= 1) {
|
||||||
@@ -114,13 +112,6 @@ int main(int argc, char **argv) {
|
|||||||
b_force_zero_latency = true;
|
b_force_zero_latency = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(argv[i], "-m")) {
|
|
||||||
if (++i == argc) {
|
|
||||||
ShowHelpAndExit("-m");
|
|
||||||
}
|
|
||||||
mem_type = static_cast<OutputSurfaceMemoryType>(atoi(argv[i]));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ShowHelpAndExit(argv[i]);
|
ShowHelpAndExit(argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,9 +65,7 @@ void ShowHelpAndExit(const char *option = NULL) {
|
|||||||
<< "-i Input File Path - required" << std::endl
|
<< "-i Input File Path - required" << std::endl
|
||||||
<< "-t Number of threads (>= 1) - optional; default: 4" << std::endl
|
<< "-t Number of threads (>= 1) - optional; default: 4" << std::endl
|
||||||
<< "-d Device ID (>= 0) - optional; default: 0" << std::endl
|
<< "-d Device ID (>= 0) - optional; default: 0" << std::endl
|
||||||
<< "-z force_zero_latency (force_zero_latency, Decoded frames will be flushed out for display immediately); optional;" << std::endl
|
<< "-z force_zero_latency (force_zero_latency, Decoded frames will be flushed out for display immediately); optional;" << std::endl;
|
||||||
<< "-m output_surface_memory_type - decoded surface memory; optional; default - 0"
|
|
||||||
<< " [0 : OUT_SURFACE_MEM_DEV_INTERNAL/ 1 : OUT_SURFACE_MEM_DEV_COPIED/ 2 : OUT_SURFACE_MEM_HOST_COPIED]" << std::endl;
|
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +75,7 @@ int main(int argc, char **argv) {
|
|||||||
int device_id = 0;
|
int device_id = 0;
|
||||||
int n_thread = 4;
|
int n_thread = 4;
|
||||||
Rect *p_crop_rect = nullptr;
|
Rect *p_crop_rect = nullptr;
|
||||||
OutputSurfaceMemoryType mem_type = OUT_SURFACE_MEM_DEV_INTERNAL; // set to internal
|
OutputSurfaceMemoryType mem_type = OUT_SURFACE_MEM_NOT_MAPPED; // set to decode only for performance
|
||||||
bool b_force_zero_latency = false;
|
bool b_force_zero_latency = false;
|
||||||
// Parse command-line arguments
|
// Parse command-line arguments
|
||||||
if(argc <= 1) {
|
if(argc <= 1) {
|
||||||
@@ -121,13 +119,6 @@ int main(int argc, char **argv) {
|
|||||||
b_force_zero_latency = true;
|
b_force_zero_latency = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(argv[i], "-m")) {
|
|
||||||
if (++i == argc) {
|
|
||||||
ShowHelpAndExit("-m");
|
|
||||||
}
|
|
||||||
mem_type = static_cast<OutputSurfaceMemoryType>(atoi(argv[i]));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ShowHelpAndExit(argv[i]);
|
ShowHelpAndExit(argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ RocVideoDecoder::~RocVideoDecoder() {
|
|||||||
if (out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) {
|
if (out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) {
|
||||||
hipError_t hip_status = hipFree(p_frame.frame_ptr);
|
hipError_t hip_status = hipFree(p_frame.frame_ptr);
|
||||||
if (hip_status != hipSuccess) {
|
if (hip_status != hipSuccess) {
|
||||||
std::cout << "ERROR: hipFree failed! (" << hip_status << ")" << std::endl;
|
std::cerr << "ERROR: hipFree failed! (" << hip_status << ")" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -92,7 +92,7 @@ RocVideoDecoder::~RocVideoDecoder() {
|
|||||||
hipError_t hip_status = hipSuccess;
|
hipError_t hip_status = hipSuccess;
|
||||||
hip_status = hipStreamDestroy(hip_stream_);
|
hip_status = hipStreamDestroy(hip_stream_);
|
||||||
if (hip_status != hipSuccess) {
|
if (hip_status != hipSuccess) {
|
||||||
std::cout << "ERROR: hipStream_Destroy failed! (" << hip_status << ")" << std::endl;
|
std::cerr << "ERROR: hipStream_Destroy failed! (" << hip_status << ")" << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fp_out_) {
|
if (fp_out_) {
|
||||||
@@ -375,7 +375,7 @@ int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *p_video_format) {
|
|||||||
chroma_height_ = (int)(ceil(disp_height_ * GetChromaHeightFactor(video_surface_format_)));
|
chroma_height_ = (int)(ceil(disp_height_ * GetChromaHeightFactor(video_surface_format_)));
|
||||||
num_chroma_planes_ = GetChromaPlaneCount(video_surface_format_);
|
num_chroma_planes_ = GetChromaPlaneCount(video_surface_format_);
|
||||||
if (p_video_format->chroma_format == rocDecVideoChromaFormat_Monochrome) num_chroma_planes_ = 0;
|
if (p_video_format->chroma_format == rocDecVideoChromaFormat_Monochrome) num_chroma_planes_ = 0;
|
||||||
if (out_mem_type_ == OUT_SURFACE_MEM_DEV_INTERNAL)
|
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_);
|
GetSurfaceStrideInternal(video_surface_format_, p_video_format->coded_width, p_video_format->coded_height, &surface_stride_, &surface_vstride_);
|
||||||
else {
|
else {
|
||||||
surface_stride_ = videoDecodeCreateInfo.ulTargetWidth * byte_per_pixel_; // todo:: check if we need pitched memory for faster copy
|
surface_stride_ = videoDecodeCreateInfo.ulTargetWidth * byte_per_pixel_; // todo:: check if we need pitched memory for faster copy
|
||||||
@@ -396,9 +396,12 @@ int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *p_video_format) {
|
|||||||
} else if (out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) {
|
} else if (out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) {
|
||||||
output_surface_info_.output_surface_size_in_bytes = GetFrameSizePitched();
|
output_surface_info_.output_surface_size_in_bytes = GetFrameSizePitched();
|
||||||
output_surface_info_.mem_type = OUT_SURFACE_MEM_DEV_COPIED;
|
output_surface_info_.mem_type = OUT_SURFACE_MEM_DEV_COPIED;
|
||||||
} else {
|
} else if (out_mem_type_ == OUT_SURFACE_MEM_HOST_COPIED){
|
||||||
output_surface_info_.output_surface_size_in_bytes = GetFrameSize();
|
output_surface_info_.output_surface_size_in_bytes = GetFrameSize();
|
||||||
output_surface_info_.mem_type = OUT_SURFACE_MEM_HOST_COPIED;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
disp_rect_.b = videoDecodeCreateInfo.display_area.bottom;
|
disp_rect_.b = videoDecodeCreateInfo.display_area.bottom;
|
||||||
@@ -428,7 +431,7 @@ int RocVideoDecoder::HandleVideoSequence(RocdecVideoFormat *p_video_format) {
|
|||||||
*/
|
*/
|
||||||
bool RocVideoDecoder::SetReconfigParams(ReconfigParams *p_reconfig_params) {
|
bool RocVideoDecoder::SetReconfigParams(ReconfigParams *p_reconfig_params) {
|
||||||
if (!p_reconfig_params) {
|
if (!p_reconfig_params) {
|
||||||
std::cout << "ERROR: Invalid reconfig struct passed! "<< std::endl;
|
std::cerr << "ERROR: Invalid reconfig struct passed! "<< std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//save it
|
//save it
|
||||||
@@ -456,7 +459,6 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) {
|
|||||||
ROCDEC_THROW("Reconfigure Not supported for bit depth change", ROCDEC_NOT_SUPPORTED);
|
ROCDEC_THROW("Reconfigure Not supported for bit depth change", ROCDEC_NOT_SUPPORTED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_decode_res_changed = !(p_video_format->coded_width == coded_width_ && p_video_format->coded_height == coded_height_);
|
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_.b &&
|
bool is_display_rect_changed = !(p_video_format->display_area.bottom == disp_rect_.b &&
|
||||||
p_video_format->display_area.top == disp_rect_.t &&
|
p_video_format->display_area.top == disp_rect_.t &&
|
||||||
@@ -482,7 +484,7 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) {
|
|||||||
if (p_frame->frame_ptr) {
|
if (p_frame->frame_ptr) {
|
||||||
if (out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) {
|
if (out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) {
|
||||||
hipError_t hip_status = hipFree(p_frame->frame_ptr);
|
hipError_t hip_status = hipFree(p_frame->frame_ptr);
|
||||||
if (hip_status != hipSuccess) std::cout << "ERROR: hipFree failed! (" << hip_status << ")" << std::endl;
|
if (hip_status != hipSuccess) std::cerr << "ERROR: hipFree failed! (" << hip_status << ")" << std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
delete [] (p_frame->frame_ptr);
|
delete [] (p_frame->frame_ptr);
|
||||||
@@ -521,7 +523,7 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) {
|
|||||||
reconfig_params.target_rect.right = p_video_format->display_area.right;
|
reconfig_params.target_rect.right = p_video_format->display_area.right;
|
||||||
reconfig_params.target_rect.bottom = p_video_format->display_area.bottom;
|
reconfig_params.target_rect.bottom = p_video_format->display_area.bottom;
|
||||||
|
|
||||||
if (out_mem_type_ == OUT_SURFACE_MEM_DEV_INTERNAL) {
|
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_);
|
GetSurfaceStrideInternal(video_surface_format_, p_video_format->coded_width, p_video_format->coded_height, &surface_stride_, &surface_vstride_);
|
||||||
} else {
|
} else {
|
||||||
surface_stride_ = reconfig_params.ulTargetWidth * byte_per_pixel_;
|
surface_stride_ = reconfig_params.ulTargetWidth * byte_per_pixel_;
|
||||||
@@ -545,9 +547,12 @@ int RocVideoDecoder::ReconfigureDecoder(RocdecVideoFormat *p_video_format) {
|
|||||||
} else if (out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) {
|
} else if (out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) {
|
||||||
output_surface_info_.output_surface_size_in_bytes = GetFrameSizePitched();
|
output_surface_info_.output_surface_size_in_bytes = GetFrameSizePitched();
|
||||||
output_surface_info_.mem_type = OUT_SURFACE_MEM_DEV_COPIED;
|
output_surface_info_.mem_type = OUT_SURFACE_MEM_DEV_COPIED;
|
||||||
} else {
|
} else if (out_mem_type_ == OUT_SURFACE_MEM_HOST_COPIED) {
|
||||||
output_surface_info_.output_surface_size_in_bytes = GetFrameSize();
|
output_surface_info_.output_surface_size_in_bytes = GetFrameSize();
|
||||||
output_surface_info_.mem_type = OUT_SURFACE_MEM_HOST_COPIED;
|
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 (roc_decoder_ == nullptr) {
|
if (roc_decoder_ == nullptr) {
|
||||||
@@ -643,88 +648,97 @@ int RocVideoDecoder::HandlePictureDisplay(RocdecParserDispInfo *pDispInfo) {
|
|||||||
sei_message_display_q_[pDispInfo->picture_index].pSEIMessage = NULL; // to avoid double free
|
sei_message_display_q_[pDispInfo->picture_index].pSEIMessage = NULL; // to avoid double free
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (out_mem_type_ != OUT_SURFACE_MEM_NOT_MAPPED) {
|
||||||
void * src_dev_ptr[3] = { 0 };
|
void * src_dev_ptr[3] = { 0 };
|
||||||
uint32_t src_pitch[3] = { 0 };
|
uint32_t src_pitch[3] = { 0 };
|
||||||
ROCDEC_API_CALL(rocDecMapVideoFrame(roc_decoder_, pDispInfo->picture_index, src_dev_ptr, src_pitch, &video_proc_params));
|
ROCDEC_API_CALL(rocDecMapVideoFrame(roc_decoder_, pDispInfo->picture_index, src_dev_ptr, src_pitch, &video_proc_params));
|
||||||
RocdecDecodeStatus dec_status;
|
RocdecDecodeStatus dec_status;
|
||||||
memset(&dec_status, 0, sizeof(dec_status));
|
memset(&dec_status, 0, sizeof(dec_status));
|
||||||
rocDecStatus result = rocDecGetDecodeStatus(roc_decoder_, pDispInfo->picture_index, &dec_status);
|
rocDecStatus result = rocDecGetDecodeStatus(roc_decoder_, pDispInfo->picture_index, &dec_status);
|
||||||
if (result == ROCDEC_SUCCESS && (dec_status.decodeStatus == rocDecodeStatus_Error || dec_status.decodeStatus == rocDecodeStatus_Error_Concealed)) {
|
if (result == ROCDEC_SUCCESS && (dec_status.decodeStatus == rocDecodeStatus_Error || dec_status.decodeStatus == rocDecodeStatus_Error_Concealed)) {
|
||||||
std::cerr << "Decode Error occurred for picture: " << pic_num_in_dec_order_[pDispInfo->picture_index] << std::endl;
|
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 = { 0 };
|
|
||||||
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<std::mutex> lock(mtx_vp_frame_);
|
|
||||||
vp_frames_q_.push(dec_frame);
|
|
||||||
decoded_frame_cnt_++;
|
|
||||||
} else {
|
|
||||||
// copy the decoded surface info device or host
|
|
||||||
uint8_t *p_dec_frame = nullptr;
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(mtx_vp_frame_);
|
|
||||||
// if not enough frames in stock, allocate
|
|
||||||
if ((unsigned)++decoded_frame_cnt_ > vp_frames_.size()) {
|
|
||||||
num_alloced_frames_++;
|
|
||||||
DecFrameBuffer dec_frame = { 0 };
|
|
||||||
if (out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) {
|
|
||||||
// allocate device memory
|
|
||||||
HIP_API_CALL(hipMalloc((void **)&dec_frame.frame_ptr, GetFrameSizePitched()));
|
|
||||||
} 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_[decoded_frame_cnt_ - 1].frame_ptr;
|
|
||||||
}
|
}
|
||||||
// Copy luma data
|
if (out_mem_type_ == OUT_SURFACE_MEM_DEV_INTERNAL) {
|
||||||
int dst_pitch = surface_stride_;
|
DecFrameBuffer dec_frame = { 0 };
|
||||||
if (out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) {
|
dec_frame.frame_ptr = (uint8_t *)(src_dev_ptr[0]);
|
||||||
if (src_pitch[0] == dst_pitch) {
|
dec_frame.pts = pDispInfo->pts;
|
||||||
int luma_size = src_pitch[0] * coded_height_;
|
dec_frame.picture_index = pDispInfo->picture_index;
|
||||||
HIP_API_CALL(hipMemcpyDtoDAsync(p_dec_frame, src_dev_ptr[0], luma_size, hip_stream_));
|
std::lock_guard<std::mutex> lock(mtx_vp_frame_);
|
||||||
} else {
|
vp_frames_q_.push(dec_frame);
|
||||||
// use 2d copy to copy an ROI
|
decoded_frame_cnt_++;
|
||||||
HIP_API_CALL(hipMemcpy2DAsync(p_dec_frame, dst_pitch, src_dev_ptr[0], src_pitch[0], coded_width_ * byte_per_pixel_, coded_height_, hipMemcpyDeviceToDevice, hip_stream_));
|
} else {
|
||||||
|
// copy the decoded surface info device or host
|
||||||
|
uint8_t *p_dec_frame = nullptr;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mtx_vp_frame_);
|
||||||
|
// if not enough frames in stock, allocate
|
||||||
|
if ((unsigned)++decoded_frame_cnt_ > vp_frames_.size()) {
|
||||||
|
num_alloced_frames_++;
|
||||||
|
DecFrameBuffer dec_frame = { 0 };
|
||||||
|
if (out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) {
|
||||||
|
// allocate device memory
|
||||||
|
HIP_API_CALL(hipMalloc((void **)&dec_frame.frame_ptr, GetFrameSizePitched()));
|
||||||
|
} 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_[decoded_frame_cnt_ - 1].frame_ptr;
|
||||||
}
|
}
|
||||||
} else
|
// Copy luma data
|
||||||
HIP_API_CALL(hipMemcpy2DAsync(p_dec_frame, coded_width_ * byte_per_pixel_, src_dev_ptr[0], src_pitch[0], coded_width_ * byte_per_pixel_, coded_height_, hipMemcpyDeviceToHost, hip_stream_));
|
int dst_pitch = surface_stride_;
|
||||||
|
|
||||||
// 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 * coded_height_;
|
|
||||||
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, src_dev_ptr[1], chroma_size, hip_stream_));
|
|
||||||
} else {
|
|
||||||
// use 2d copy to copy an ROI
|
|
||||||
HIP_API_CALL(hipMemcpy2DAsync(p_frame_uv, dst_pitch, src_dev_ptr[1], src_pitch[1], coded_width_ * byte_per_pixel_, chroma_height_, hipMemcpyDeviceToDevice, hip_stream_));
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
HIP_API_CALL(hipMemcpy2DAsync(p_frame_uv, dst_pitch, src_dev_ptr[1], src_pitch[1], coded_width_ * byte_per_pixel_, chroma_height_, hipMemcpyDeviceToHost, hip_stream_));
|
|
||||||
|
|
||||||
if (num_chroma_planes_ == 2) {
|
|
||||||
uint8_t *p_frame_uv = p_dec_frame + dst_pitch * (coded_height_ + chroma_height_);
|
|
||||||
if (out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) {
|
if (out_mem_type_ == OUT_SURFACE_MEM_DEV_COPIED) {
|
||||||
if (src_pitch[2] == dst_pitch) {
|
if (src_pitch[0] == dst_pitch) {
|
||||||
int chroma_size = chroma_height_ * dst_pitch;
|
int luma_size = src_pitch[0] * coded_height_;
|
||||||
HIP_API_CALL(hipMemcpyDtoDAsync(p_frame_uv, src_dev_ptr[2], chroma_size, hip_stream_));
|
HIP_API_CALL(hipMemcpyDtoDAsync(p_dec_frame, src_dev_ptr[0], luma_size, hip_stream_));
|
||||||
} else {
|
} else {
|
||||||
// use 2d copy to copy an ROI
|
// use 2d copy to copy an ROI
|
||||||
HIP_API_CALL(hipMemcpy2DAsync(p_frame_uv, dst_pitch, src_dev_ptr[2], src_pitch[2], coded_width_ * byte_per_pixel_, chroma_height_, hipMemcpyDeviceToDevice, hip_stream_));
|
HIP_API_CALL(hipMemcpy2DAsync(p_dec_frame, dst_pitch, src_dev_ptr[0], src_pitch[0], coded_width_ * byte_per_pixel_, coded_height_, hipMemcpyDeviceToDevice, hip_stream_));
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
HIP_API_CALL(hipMemcpy2DAsync(p_frame_uv, dst_pitch, src_dev_ptr[2], src_pitch[2], coded_width_ * byte_per_pixel_, chroma_height_, hipMemcpyDeviceToHost, hip_stream_));
|
HIP_API_CALL(hipMemcpy2DAsync(p_dec_frame, coded_width_ * byte_per_pixel_, src_dev_ptr[0], src_pitch[0], coded_width_ * byte_per_pixel_, coded_height_, hipMemcpyDeviceToHost, hip_stream_));
|
||||||
}
|
|
||||||
|
|
||||||
HIP_API_CALL(hipStreamSynchronize(hip_stream_));
|
// Copy chroma plane ( )
|
||||||
ROCDEC_API_CALL(rocDecUnMapVideoFrame(roc_decoder_, pDispInfo->picture_index));
|
// rocDec output gives pointer to luma and chroma pointers seperated for the decoded frame
|
||||||
|
uint8_t *p_frame_uv = p_dec_frame + dst_pitch * coded_height_;
|
||||||
|
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, src_dev_ptr[1], chroma_size, hip_stream_));
|
||||||
|
} else {
|
||||||
|
// use 2d copy to copy an ROI
|
||||||
|
HIP_API_CALL(hipMemcpy2DAsync(p_frame_uv, dst_pitch, src_dev_ptr[1], src_pitch[1], coded_width_ * byte_per_pixel_, chroma_height_, hipMemcpyDeviceToDevice, hip_stream_));
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
HIP_API_CALL(hipMemcpy2DAsync(p_frame_uv, dst_pitch, src_dev_ptr[1], src_pitch[1], coded_width_ * byte_per_pixel_, chroma_height_, hipMemcpyDeviceToHost, hip_stream_));
|
||||||
|
|
||||||
|
if (num_chroma_planes_ == 2) {
|
||||||
|
uint8_t *p_frame_uv = p_dec_frame + dst_pitch * (coded_height_ + chroma_height_);
|
||||||
|
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_uv, src_dev_ptr[2], chroma_size, hip_stream_));
|
||||||
|
} else {
|
||||||
|
// use 2d copy to copy an ROI
|
||||||
|
HIP_API_CALL(hipMemcpy2DAsync(p_frame_uv, dst_pitch, src_dev_ptr[2], src_pitch[2], coded_width_ * byte_per_pixel_, chroma_height_, hipMemcpyDeviceToDevice, hip_stream_));
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
HIP_API_CALL(hipMemcpy2DAsync(p_frame_uv, dst_pitch, src_dev_ptr[2], src_pitch[2], coded_width_ * byte_per_pixel_, chroma_height_, hipMemcpyDeviceToHost, hip_stream_));
|
||||||
|
}
|
||||||
|
|
||||||
|
HIP_API_CALL(hipStreamSynchronize(hip_stream_));
|
||||||
|
ROCDEC_API_CALL(rocDecUnMapVideoFrame(roc_decoder_, pDispInfo->picture_index));
|
||||||
|
}
|
||||||
|
} 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.decodeStatus == rocDecodeStatus_Error || dec_status.decodeStatus == rocDecodeStatus_Error_Concealed)) {
|
||||||
|
std::cerr << "Decode Error occurred for picture: " << pic_num_in_dec_order_[pDispInfo->picture_index] << std::endl;
|
||||||
|
}
|
||||||
|
decoded_frame_cnt_++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -789,7 +803,7 @@ uint8_t* RocVideoDecoder::GetFrame(int64_t *pts) {
|
|||||||
DecFrameBuffer *fb = &vp_frames_q_.front();
|
DecFrameBuffer *fb = &vp_frames_q_.front();
|
||||||
if (pts) *pts = fb->pts;
|
if (pts) *pts = fb->pts;
|
||||||
return fb->frame_ptr;
|
return fb->frame_ptr;
|
||||||
} else {
|
} else if (vp_frames_.size() > 0){
|
||||||
if (pts) *pts = vp_frames_[decoded_frame_cnt_ret_].pts;
|
if (pts) *pts = vp_frames_[decoded_frame_cnt_ret_].pts;
|
||||||
return vp_frames_[decoded_frame_cnt_ret_++].frame_ptr;
|
return vp_frames_[decoded_frame_cnt_ret_++].frame_ptr;
|
||||||
}
|
}
|
||||||
@@ -808,6 +822,8 @@ uint8_t* RocVideoDecoder::GetFrame(int64_t *pts) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
bool RocVideoDecoder::ReleaseFrame(int64_t pTimestamp, bool b_flushing) {
|
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 (out_mem_type_ != OUT_SURFACE_MEM_DEV_INTERNAL) {
|
||||||
if (!b_flushing) // if not flushing the buffers are re-used, so keep them
|
if (!b_flushing) // if not flushing the buffers are re-used, so keep them
|
||||||
return true; // nothing to do
|
return true; // nothing to do
|
||||||
@@ -845,7 +861,7 @@ bool RocVideoDecoder::ReleaseFrame(int64_t pTimestamp, bool b_flushing) {
|
|||||||
* @return false - falied
|
* @return false - falied
|
||||||
*/
|
*/
|
||||||
bool RocVideoDecoder::ReleaseInternalFrames() {
|
bool RocVideoDecoder::ReleaseInternalFrames() {
|
||||||
if (out_mem_type_ != OUT_SURFACE_MEM_DEV_INTERNAL)
|
if (out_mem_type_ != OUT_SURFACE_MEM_DEV_INTERNAL || out_mem_type_ == OUT_SURFACE_MEM_NOT_MAPPED)
|
||||||
return true; // nothing to do
|
return true; // nothing to do
|
||||||
// only needed when using internal mapped buffer
|
// only needed when using internal mapped buffer
|
||||||
while (!vp_frames_q_.empty()) {
|
while (!vp_frames_q_.empty()) {
|
||||||
@@ -869,7 +885,7 @@ void RocVideoDecoder::SaveFrameToFile(std::string output_file_name, void *surf_m
|
|||||||
hipError_t hip_status = hipSuccess;
|
hipError_t hip_status = hipSuccess;
|
||||||
hip_status = hipMemcpyDtoH((void *)hst_ptr, surf_mem, output_image_size);
|
hip_status = hipMemcpyDtoH((void *)hst_ptr, surf_mem, output_image_size);
|
||||||
if (hip_status != hipSuccess) {
|
if (hip_status != hipSuccess) {
|
||||||
std::cout << "ERROR: hipMemcpyDtoH failed! (" << hip_status << ")" << std::endl;
|
std::cerr << "ERROR: hipMemcpyDtoH failed! (" << hip_status << ")" << std::endl;
|
||||||
delete [] hst_ptr;
|
delete [] hst_ptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -978,7 +994,7 @@ void RocVideoDecoder::UpdateMd5ForFrame(void *surf_mem, OutputSurfaceInfo *surf_
|
|||||||
hipError_t hip_status = hipSuccess;
|
hipError_t hip_status = hipSuccess;
|
||||||
hip_status = hipMemcpyDtoH((void *)hst_ptr, surf_mem, output_image_size);
|
hip_status = hipMemcpyDtoH((void *)hst_ptr, surf_mem, output_image_size);
|
||||||
if (hip_status != hipSuccess) {
|
if (hip_status != hipSuccess) {
|
||||||
std::cout << "ERROR: hipMemcpyDtoH failed! (" << hip_status << ")" << std::endl;
|
std::cerr << "ERROR: hipMemcpyDtoH failed! (" << hip_status << ")" << std::endl;
|
||||||
delete [] hst_ptr;
|
delete [] hst_ptr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,7 +61,8 @@ typedef enum SeiH264HevcPayloadType_enum {
|
|||||||
typedef enum OutputSurfaceMemoryType_enum {
|
typedef enum OutputSurfaceMemoryType_enum {
|
||||||
OUT_SURFACE_MEM_DEV_INTERNAL = 0, /**< Internal interopped decoded surface memory(original mapped decoded surface) */
|
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_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_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;
|
} OutputSurfaceMemoryType;
|
||||||
|
|
||||||
#define TOSTR(X) std::to_string(static_cast<int>(X))
|
#define TOSTR(X) std::to_string(static_cast<int>(X))
|
||||||
|
|||||||
Reference in new issue
Block a user