diff --git a/samples/videoDecodeRGB/videodecrgb.cpp b/samples/videoDecodeRGB/videodecrgb.cpp index c07437cd0a..ac97bf03d8 100644 --- a/samples/videoDecodeRGB/videodecrgb.cpp +++ b/samples/videoDecodeRGB/videodecrgb.cpp @@ -21,6 +21,7 @@ THE SOFTWARE. */ #include +#include #include #include #include @@ -160,7 +161,7 @@ std::mutex mutex[frame_buffers_size]; std::condition_variable cv[frame_buffers_size]; void ColorSpaceConversionThread(std::atomic& continue_processing, bool convert_to_rgb, Dim *p_resize_dim, OutputSurfaceInfo **surf_info, OutputSurfaceInfo **res_surf_info, - OutputFormatEnum e_output_format, uint8_t *p_rgb_dev_mem, uint8_t *p_resize_dev_mem, bool dump_output_frames, std::string &output_file_path, RocVideoDecoder &viddec) { + OutputFormatEnum e_output_format, uint8_t *p_rgb_dev_mem, uint8_t *p_resize_dev_mem, bool dump_output_frames, std::string &output_file_path, RocVideoDecoder &viddec, bool b_generate_md5) { size_t rgb_image_size, resize_image_size; hipError_t hip_status = hipSuccess; @@ -239,6 +240,10 @@ void ColorSpaceConversionThread(std::atomic& continue_processing, bool con else viddec.SaveFrameToFile(output_file_path, out_frame, p_surf_info); } + if(b_generate_md5 && convert_to_rgb){ + viddec.UpdateMd5ForDataBuffer(p_rgb_dev_mem, rgb_image_size); + } + cv[current_frame_index].notify_one(); current_frame_index = (current_frame_index + 1) % frame_buffers_size; @@ -247,7 +252,10 @@ void ColorSpaceConversionThread(std::atomic& continue_processing, bool con int main(int argc, char **argv) { - std::string input_file_path, output_file_path; + std::string input_file_path, output_file_path, md5_file_path; + std::fstream ref_md5_file; + bool b_generate_md5 = false; + bool b_md5_check = false; bool dump_output_frames = false; bool convert_to_rgb = false; int device_id = 0; @@ -264,6 +272,7 @@ int main(int argc, char **argv) { int rgb_width; uint8_t* frame_buffers[frame_buffers_size] = {0}; int current_frame_index = 0; + // Parse command-line arguments if(argc <= 1) { @@ -327,6 +336,22 @@ int main(int argc, char **argv) { e_output_format = (OutputFormatEnum)(it - st_output_format_name.begin()); continue; } + if (!strcmp(argv[i], "-md5")) { + if (i == argc) { + ShowHelpAndExit("-md5"); + } + b_generate_md5 = true; + continue; + } + if (!strcmp(argv[i], "-md5_check")) { + if (++i == argc) { + ShowHelpAndExit("-md5_check"); + } + b_generate_md5 = true; + b_md5_check = true; + md5_file_path = argv[i]; + continue; + } ShowHelpAndExit(argv[i]); } @@ -345,6 +370,13 @@ int main(int argc, char **argv) { std::right << std::hex << pci_domain_id << "." << pci_device_id << std::dec << std::endl; std::cout << "info: decoding started, please wait!" << std::endl; + if (b_generate_md5) { + viddec.InitMd5(); + } + if (b_md5_check) { + ref_md5_file.open(md5_file_path.c_str(), std::ios::in); + } + int n_video_bytes = 0, n_frames_returned = 0, n_frame = 0; uint8_t *p_video = nullptr; uint8_t *p_frame = nullptr; @@ -356,7 +388,7 @@ int main(int argc, char **argv) { convert_to_rgb = e_output_format != native; std::atomic continue_processing(true); std::thread color_space_conversion_thread(ColorSpaceConversionThread, std::ref(continue_processing), std::ref(convert_to_rgb), &resize_dim, &surf_info, &resize_surf_info, std::ref(e_output_format), - std::ref(p_rgb_dev_mem), std::ref(p_resize_dev_mem), std::ref(dump_output_frames), std::ref(output_file_path), std::ref(viddec)); + std::ref(p_rgb_dev_mem), std::ref(p_resize_dev_mem), std::ref(dump_output_frames), std::ref(output_file_path), std::ref(viddec), b_generate_md5); auto startTime = std::chrono::high_resolution_clock::now(); do { @@ -441,6 +473,39 @@ int main(int argc, char **argv) { if (resize_surf_info != nullptr) { delete resize_surf_info; } + if (b_generate_md5) { + uint8_t *digest; + viddec.FinalizeMd5(&digest); + std::cout << "MD5 message digest: "; + for (int i = 0; i < 16; i++) { + std::cout << std::setfill('0') << std::setw(2) << std::hex << static_cast(digest[i]); + } + std::cout << std::endl; + + if (b_md5_check) { + char ref_md5_string[33], c2[2]; + uint8_t ref_md5[16]; + std::string str; + + for (int i = 0; i < 16; i++) { + int c; + ref_md5_file.get(c2[0]); + ref_md5_file.get(c2[1]); + str = c2; + c = std::stoi(str, nullptr, 16); + ref_md5[i] = c; + } + if (memcmp(digest, ref_md5, 16) == 0) { + std::cout << "MD5 digest matches the reference MD5 digest: " << std::endl; + } else { + std::cout << "MD5 digest does not match the reference MD5 digest: " << std::endl; + } + ref_md5_file.seekg(0, std::ios_base::beg); + ref_md5_file.getline(ref_md5_string, 33); + std::cout << ref_md5_string << std::endl; + ref_md5_file.close(); + } + } } catch (const std::exception &ex) { std::cout << ex.what() << std::endl; exit(1); diff --git a/utils/rocvideodecode/roc_video_dec.cpp b/utils/rocvideodecode/roc_video_dec.cpp index cda50e334e..ff5a471d36 100644 --- a/utils/rocvideodecode/roc_video_dec.cpp +++ b/utils/rocvideodecode/roc_video_dec.cpp @@ -989,6 +989,22 @@ void RocVideoDecoder::InitMd5() { av_md5_init(md5_ctx_); } +void RocVideoDecoder::UpdateMd5ForDataBuffer(void *pDevMem, int rgb_image_size){ + uint8_t *hstPtr = nullptr; + hstPtr = new uint8_t [rgb_image_size]; + hipError_t hip_status = hipSuccess; + hip_status = hipMemcpyDtoH((void *)hstPtr, pDevMem, rgb_image_size); + if (hip_status != hipSuccess) { + std::cout << "ERROR: hipMemcpyDtoH failed! (" << hip_status << ")" << std::endl; + delete [] hstPtr; + return; + } + av_md5_update(md5_ctx_, hstPtr, rgb_image_size); + if(hstPtr){ + delete [] hstPtr; + } +} + void RocVideoDecoder::UpdateMd5ForFrame(void *surf_mem, OutputSurfaceInfo *surf_info) { int i; uint8_t *hst_ptr = nullptr; diff --git a/utils/rocvideodecode/roc_video_dec.h b/utils/rocvideodecode/roc_video_dec.h index 7426a1056c..6cf7add6c1 100644 --- a/utils/rocvideodecode/roc_video_dec.h +++ b/utils/rocvideodecode/roc_video_dec.h @@ -332,6 +332,8 @@ class RocVideoDecoder { */ void InitMd5(); + void UpdateMd5ForDataBuffer(void *pDevMem, int rgb_image_size); + /** * @brief Helper function to dump decoded output surface to file *