@@ -50,6 +50,19 @@ int main(int argc, char **argv) {
|
||||
std::vector<RocJpegImage> output_images;
|
||||
RocJpegDecodeParams decode_params = {};
|
||||
RocJpegUtils rocjpeg_utils;
|
||||
std::vector<std::string> base_file_names;
|
||||
std::vector<int> bad_image_indices;
|
||||
std::vector<RocJpegStreamHandle> valid_rocjpeg_stream_handles;
|
||||
std::vector<RocJpegChromaSubsampling> valid_subsamplings;
|
||||
std::vector<std::vector<uint32_t>> valid_widths;
|
||||
std::vector<std::vector<uint32_t>> valid_heights;
|
||||
std::vector<std::vector<uint32_t>> valid_prior_channel_sizes;
|
||||
std::vector<RocJpegImage> valid_output_images;
|
||||
std::vector<std::string> valid_base_file_names;
|
||||
uint64_t num_bad_jpegs = 0;
|
||||
uint64_t num_jpegs_with_411_subsampling = 0;
|
||||
uint64_t num_jpegs_with_unknown_subsampling = 0;
|
||||
uint64_t num_jpegs_with_unsupported_resolution = 0;
|
||||
|
||||
RocJpegUtils::ParseCommandLine(input_path, output_file_path, save_images, device_id, rocjpeg_backend, decode_params, nullptr, &batch_size, argc, argv);
|
||||
|
||||
@@ -82,7 +95,15 @@ int main(int argc, char **argv) {
|
||||
widths.resize(batch_size, std::vector<uint32_t>(ROCJPEG_MAX_COMPONENT, 0));
|
||||
heights.resize(batch_size, std::vector<uint32_t>(ROCJPEG_MAX_COMPONENT, 0));
|
||||
subsamplings.resize(batch_size);
|
||||
std::vector<std::string> base_file_names(batch_size);
|
||||
base_file_names.resize(batch_size);
|
||||
valid_rocjpeg_stream_handles.resize(batch_size);
|
||||
valid_output_images.resize(batch_size);
|
||||
valid_prior_channel_sizes.resize(batch_size, std::vector<uint32_t>(ROCJPEG_MAX_COMPONENT, 0));
|
||||
valid_widths.resize(batch_size, std::vector<uint32_t>(ROCJPEG_MAX_COMPONENT, 0));
|
||||
valid_heights.resize(batch_size, std::vector<uint32_t>(ROCJPEG_MAX_COMPONENT, 0));
|
||||
valid_subsamplings.resize(batch_size);
|
||||
valid_base_file_names.resize(batch_size);
|
||||
|
||||
std::cout << "Decoding started, please wait! ... " << std::endl;
|
||||
for (int i = 0; i < file_paths.size(); i += batch_size) {
|
||||
int batch_end = std::min(i + batch_size, static_cast<int>(file_paths.size()));
|
||||
@@ -107,7 +128,19 @@ int main(int argc, char **argv) {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
CHECK_ROCJPEG(rocJpegStreamParse(reinterpret_cast<uint8_t*>(batch_images[index].data()), file_size, rocjpeg_stream_handles[index]));
|
||||
RocJpegStatus rocjpeg_status = rocJpegStreamParse(reinterpret_cast<uint8_t*>(batch_images[index].data()), file_size, rocjpeg_stream_handles[index]);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_SUCCESS) {
|
||||
if (is_dir) {
|
||||
bad_image_indices.push_back(index);
|
||||
num_bad_jpegs++;
|
||||
std::cerr << "Skipping decoding input file: " << file_paths[j] << std::endl;
|
||||
continue;
|
||||
} else {
|
||||
std::cerr << "ERROR: Failed to parse the input jpeg stream with " << rocJpegGetErrorName(rocjpeg_status) << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_ROCJPEG(rocJpegGetImageInfo(rocjpeg_handle, rocjpeg_stream_handles[index], &num_components, &subsamplings[index], widths[index].data(), heights[index].data()));
|
||||
|
||||
if (roi_width > 0 && roi_height > 0 && roi_width <= widths[index][0] && roi_height <= heights[index][0]) {
|
||||
@@ -116,21 +149,30 @@ int main(int argc, char **argv) {
|
||||
|
||||
rocjpeg_utils.GetChromaSubsamplingStr(subsamplings[index], chroma_sub_sampling);
|
||||
if (widths[index][0] < 64 || heights[index][0] < 64) {
|
||||
std::cerr << "The image resolution is not supported by VCN Hardware" << std::endl;
|
||||
if (is_dir) {
|
||||
std::cout << std::endl;
|
||||
bad_image_indices.push_back(index);
|
||||
num_jpegs_with_unsupported_resolution++;
|
||||
continue;
|
||||
} else
|
||||
} else {
|
||||
std::cerr << "The image resolution is not supported by VCN Hardware" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (subsamplings[index] == ROCJPEG_CSS_411 || subsamplings[index] == ROCJPEG_CSS_UNKNOWN) {
|
||||
std::cerr << "The chroma sub-sampling is not supported by VCN Hardware" << std::endl;
|
||||
if (is_dir) {
|
||||
std::cout << std::endl;
|
||||
continue;
|
||||
} else
|
||||
bad_image_indices.push_back(index);
|
||||
if (subsamplings[index] == ROCJPEG_CSS_411) {
|
||||
num_jpegs_with_411_subsampling++;
|
||||
}
|
||||
if (subsamplings[index] == ROCJPEG_CSS_UNKNOWN) {
|
||||
num_jpegs_with_unknown_subsampling++;
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
std::cerr << "The chroma sub-sampling is not supported by VCN Hardware" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (rocjpeg_utils.GetChannelPitchAndSizes(decode_params, subsamplings[index], widths[index].data(), heights[index].data(), num_channels, output_images[index], channel_sizes)) {
|
||||
@@ -150,16 +192,50 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
}
|
||||
int current_batch_size = batch_end - i;
|
||||
int current_batch_size = batch_end - i - bad_image_indices.size();
|
||||
|
||||
auto start_time = std::chrono::high_resolution_clock::now();
|
||||
CHECK_ROCJPEG(rocJpegDecodeBatched(rocjpeg_handle, rocjpeg_stream_handles.data(), current_batch_size, &decode_params, output_images.data()));
|
||||
auto end_time = std::chrono::high_resolution_clock::now();
|
||||
double time_per_batch_in_milli_sec = std::chrono::duration<double, std::milli>(end_time - start_time).count();
|
||||
// Select valid images for decoding
|
||||
if (current_batch_size > 0) {
|
||||
if (!bad_image_indices.empty()) {
|
||||
// Iterate through the batch images and select only the valid ones
|
||||
int valid_idx = 0;
|
||||
for (int idx = 0; idx < batch_size; idx++) {
|
||||
// Check if the current image index is not in the list of bad image indices
|
||||
if (std::find(bad_image_indices.begin(), bad_image_indices.end(), idx) == bad_image_indices.end()) {
|
||||
// Add the valid image index to the corresponding vectors
|
||||
valid_rocjpeg_stream_handles[valid_idx] = rocjpeg_stream_handles[idx];
|
||||
valid_subsamplings[valid_idx] = subsamplings[idx];
|
||||
valid_widths[valid_idx] = widths[idx];
|
||||
valid_heights[valid_idx] = heights[idx];
|
||||
valid_prior_channel_sizes[valid_idx] = prior_channel_sizes[idx];
|
||||
valid_output_images[valid_idx] = output_images[idx];
|
||||
valid_base_file_names[valid_idx] = base_file_names[idx];
|
||||
valid_idx++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If there are no bad images, select all the batch images
|
||||
valid_rocjpeg_stream_handles = rocjpeg_stream_handles;
|
||||
valid_subsamplings = subsamplings;
|
||||
valid_widths = widths;
|
||||
valid_heights = heights;
|
||||
valid_prior_channel_sizes = prior_channel_sizes;
|
||||
valid_output_images = output_images;
|
||||
valid_base_file_names = base_file_names;
|
||||
}
|
||||
}
|
||||
|
||||
double time_per_batch_in_milli_sec = 0;
|
||||
if (current_batch_size > 0) {
|
||||
auto start_time = std::chrono::high_resolution_clock::now();
|
||||
CHECK_ROCJPEG(rocJpegDecodeBatched(rocjpeg_handle, valid_rocjpeg_stream_handles.data(), current_batch_size, &decode_params, valid_output_images.data()));
|
||||
auto end_time = std::chrono::high_resolution_clock::now();
|
||||
time_per_batch_in_milli_sec = std::chrono::duration<double, std::milli>(end_time - start_time).count();
|
||||
}
|
||||
|
||||
double image_size_in_mpixels = 0;
|
||||
for (int b = 0; b < current_batch_size; b++) {
|
||||
image_size_in_mpixels += (static_cast<double>(widths[b][0]) * static_cast<double>(heights[b][0]) / 1000000);
|
||||
image_size_in_mpixels += (static_cast<double>(valid_widths[b][0]) * static_cast<double>(valid_heights[b][0]) / 1000000);
|
||||
}
|
||||
|
||||
total_images += current_batch_size;
|
||||
@@ -168,12 +244,12 @@ int main(int argc, char **argv) {
|
||||
for (int b = 0; b < current_batch_size; b++) {
|
||||
std::string image_save_path = output_file_path;
|
||||
//if ROI is present, need to pass roi_width and roi_height
|
||||
uint32_t width = is_roi_valid ? roi_width : widths[b][0];
|
||||
uint32_t height = is_roi_valid ? roi_height : heights[b][0];
|
||||
uint32_t width = is_roi_valid ? roi_width : valid_widths[b][0];
|
||||
uint32_t height = is_roi_valid ? roi_height : valid_heights[b][0];
|
||||
if (is_dir) {
|
||||
rocjpeg_utils.GetOutputFileExt(decode_params.output_format, base_file_names[b], width, height, subsamplings[b], image_save_path);
|
||||
rocjpeg_utils.GetOutputFileExt(decode_params.output_format, valid_base_file_names[b], width, height, valid_subsamplings[b], image_save_path);
|
||||
}
|
||||
rocjpeg_utils.SaveImage(image_save_path, &output_images[b], width, height, subsamplings[b], decode_params.output_format);
|
||||
rocjpeg_utils.SaveImage(image_save_path, &valid_output_images[b], width, height, valid_subsamplings[b], decode_params.output_format);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,10 +258,7 @@ int main(int argc, char **argv) {
|
||||
mpixels_all += image_size_in_mpixels;
|
||||
}
|
||||
|
||||
// Clear the batch_images vector after processing each batch
|
||||
for (int j = i; j < batch_end; j++) {
|
||||
batch_images[j - i].clear();
|
||||
}
|
||||
bad_image_indices.clear();
|
||||
}
|
||||
|
||||
if (is_dir) {
|
||||
@@ -193,6 +266,22 @@ int main(int argc, char **argv) {
|
||||
images_per_sec = 1000 / time_per_image_all;
|
||||
double mpixels_per_sec = mpixels_all * images_per_sec / total_images;
|
||||
std::cout << "Total decoded images: " << total_images << std::endl;
|
||||
if (num_bad_jpegs || num_jpegs_with_411_subsampling || num_jpegs_with_unknown_subsampling || num_jpegs_with_unsupported_resolution) {
|
||||
std::cout << "Total skipped images: " << num_bad_jpegs + num_jpegs_with_411_subsampling + num_jpegs_with_unknown_subsampling + num_jpegs_with_unsupported_resolution;
|
||||
if (num_bad_jpegs) {
|
||||
std::cout << " ,total images that cannot be parsed: " << num_bad_jpegs;
|
||||
}
|
||||
if (num_jpegs_with_411_subsampling) {
|
||||
std::cout << " ,total images with YUV 4:1:1 chroam subsampling: " << num_jpegs_with_411_subsampling;
|
||||
}
|
||||
if (num_jpegs_with_unknown_subsampling) {
|
||||
std::cout << " ,total images with unknwon chroam subsampling: " << num_jpegs_with_unknown_subsampling;
|
||||
}
|
||||
if (num_jpegs_with_unsupported_resolution) {
|
||||
std::cout << " ,total images with unsupported_resolution: " << num_jpegs_with_unsupported_resolution;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
if (total_images) {
|
||||
std::cout << "Average processing time per image (ms): " << time_per_image_all << std::endl;
|
||||
std::cout << "Average decoded images per sec (Images/Sec): " << images_per_sec << std::endl;
|
||||
|
||||
@@ -23,7 +23,8 @@ THE SOFTWARE.
|
||||
#include "../rocjpeg_samples_utils.h"
|
||||
|
||||
void ThreadFunction(std::vector<std::string>& jpegFiles, RocJpegHandle rocjpeg_handle, RocJpegStreamHandle rocjpeg_stream, RocJpegUtils rocjpeg_util, RocJpegImage *output_image, std::mutex &mutex,
|
||||
RocJpegDecodeParams &decode_params, bool save_images, std::string &output_file_path, uint64_t *num_decoded_images, double *image_size_in_mpixels) {
|
||||
RocJpegDecodeParams &decode_params, bool save_images, std::string &output_file_path, uint64_t *num_decoded_images, double *image_size_in_mpixels, uint64_t *num_bad_jpegs, uint64_t *num_jpegs_with_411_subsampling,
|
||||
uint64_t *num_jpegs_with_unknown_subsampling, uint64_t *num_jpegs_with_unsupported_resolution) {
|
||||
|
||||
bool is_roi_valid = false;
|
||||
uint32_t roi_width;
|
||||
@@ -75,22 +76,32 @@ void ThreadFunction(std::vector<std::string>& jpegFiles, RocJpegHandle rocjpeg_h
|
||||
return;
|
||||
}
|
||||
|
||||
CHECK_ROCJPEG(rocJpegStreamParse(reinterpret_cast<uint8_t *>(file_data.data()), file_size, rocjpeg_stream));
|
||||
RocJpegStatus rocjpeg_status = rocJpegStreamParse(reinterpret_cast<uint8_t *>(file_data.data()), file_size, rocjpeg_stream);
|
||||
if (rocjpeg_status != ROCJPEG_STATUS_SUCCESS) {
|
||||
std::cerr << "Skipping decoding input file: " << file_path << std::endl;
|
||||
*num_bad_jpegs += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
CHECK_ROCJPEG(rocJpegGetImageInfo(rocjpeg_handle, rocjpeg_stream, &num_components, &subsampling, widths, heights));
|
||||
if (roi_width > 0 && roi_height > 0 && roi_width <= widths[0] && roi_height <= heights[0]) {
|
||||
is_roi_valid = true;
|
||||
}
|
||||
|
||||
if (widths[0] < 64 || heights[0] < 64) {
|
||||
std::cerr << "The image resolution is not supported by VCN Hardware" << std::endl;
|
||||
std::cout << "Skipping decoding file " << base_file_name << std::endl;
|
||||
return;
|
||||
*num_jpegs_with_unsupported_resolution += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (subsampling == ROCJPEG_CSS_411 || subsampling == ROCJPEG_CSS_UNKNOWN) {
|
||||
std::cerr << "The chroma sub-sampling is not supported by VCN Hardware" << std::endl;
|
||||
std::cout << "Skipping decoding file " << base_file_name << std::endl;
|
||||
return;
|
||||
if (subsampling == ROCJPEG_CSS_411) {
|
||||
*num_jpegs_with_411_subsampling += 1;
|
||||
}
|
||||
if (subsampling == ROCJPEG_CSS_UNKNOWN) {
|
||||
*num_jpegs_with_unknown_subsampling += 1;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rocjpeg_util.GetChannelPitchAndSizes(decode_params, subsampling, widths, heights, num_channels, *output_image, channel_sizes)) {
|
||||
@@ -150,6 +161,10 @@ int main(int argc, char **argv) {
|
||||
std::vector<RocJpegImage> rocjpeg_images;
|
||||
RocJpegUtils rocjpeg_utils;
|
||||
std::vector<std::thread> threads;
|
||||
std::vector<uint64_t> num_bad_jpegs;
|
||||
std::vector<uint64_t> num_jpegs_with_411_subsampling;
|
||||
std::vector<uint64_t> num_jpegs_with_unknown_subsampling;
|
||||
std::vector<uint64_t> num_jpegs_with_unsupported_resolution;
|
||||
|
||||
RocJpegUtils::ParseCommandLine(input_path, output_file_path, save_images, device_id, rocjpeg_backend, decode_params, &num_threads, nullptr, argc, argv);
|
||||
if (!RocJpegUtils::GetFilePaths(input_path, file_paths, is_dir, is_file)) {
|
||||
@@ -177,12 +192,16 @@ int main(int argc, char **argv) {
|
||||
num_decoded_images_per_thread.resize(num_threads, 0);
|
||||
image_size_in_mpixels_per_thread.resize(num_threads, 0);
|
||||
rocjpeg_images.resize(num_threads, {0});
|
||||
num_bad_jpegs.resize(num_threads, 0);
|
||||
num_jpegs_with_411_subsampling.resize(num_threads, 0);
|
||||
num_jpegs_with_unknown_subsampling.resize(num_threads, 0);
|
||||
num_jpegs_with_unsupported_resolution.resize(num_threads, 0);
|
||||
|
||||
std::cout << "Decoding started with " << num_threads << " threads, please wait!" << std::endl;
|
||||
auto start_time = std::chrono::high_resolution_clock::now();
|
||||
for (int i = 0; i < num_threads; ++i) {
|
||||
threads.emplace_back(ThreadFunction, std::ref(file_paths), rocjpeg_handles[i], rocjpeg_streams[i], rocjpeg_utils, &rocjpeg_images[i], std::ref(mutex), std::ref(decode_params), save_images, std::ref(output_file_path),
|
||||
&num_decoded_images_per_thread[i], &image_size_in_mpixels_per_thread[i]);
|
||||
&num_decoded_images_per_thread[i], &image_size_in_mpixels_per_thread[i], &num_bad_jpegs[i], &num_jpegs_with_411_subsampling[i], &num_jpegs_with_unknown_subsampling[i], &num_jpegs_with_unsupported_resolution[i]);
|
||||
}
|
||||
for (auto& thread : threads) {
|
||||
thread.join();
|
||||
@@ -192,9 +211,18 @@ int main(int argc, char **argv) {
|
||||
|
||||
uint64_t total_decoded_images = 0;
|
||||
double total_image_size_in_mpixels = 0;
|
||||
uint64_t total_num_bad_jpegs = 0;
|
||||
uint64_t total_num_jpegs_with_411_subsampling = 0;
|
||||
uint64_t total_num_jpegs_with_unknown_subsampling = 0;
|
||||
uint64_t total_num_jpegs_with_unsupported_resolution = 0;
|
||||
|
||||
for (auto i = 0 ; i < num_threads; i++) {
|
||||
total_decoded_images += num_decoded_images_per_thread[i];
|
||||
total_image_size_in_mpixels += image_size_in_mpixels_per_thread[i];
|
||||
total_num_bad_jpegs += num_bad_jpegs[i];
|
||||
total_num_jpegs_with_411_subsampling += num_jpegs_with_411_subsampling[i];
|
||||
total_num_jpegs_with_unknown_subsampling += num_jpegs_with_unknown_subsampling[i];
|
||||
total_num_jpegs_with_unsupported_resolution += num_jpegs_with_unsupported_resolution[i];
|
||||
for (int j = 0; j < ROCJPEG_MAX_COMPONENT; j++) {
|
||||
if (rocjpeg_images[i].channel[j] != nullptr) {
|
||||
CHECK_HIP(hipFree((void *)rocjpeg_images[i].channel[j]));
|
||||
@@ -208,9 +236,28 @@ int main(int argc, char **argv) {
|
||||
double avg_image_size_in_mpixels_per_sec = total_image_size_in_mpixels * avg_images_per_sec / total_decoded_images;
|
||||
std::cout << "Total elapsed time (ms): " << total_time_in_milli_sec << std::endl;
|
||||
std::cout << "Total decoded images: " << total_decoded_images << std::endl;
|
||||
std::cout << "Average processing time per image (ms): " << average_decoding_time_in_milli_sec << std::endl;
|
||||
std::cout << "Average decoded images per sec (Images/Sec): " << avg_images_per_sec << std::endl;
|
||||
std::cout << "Average decoded images size (Mpixels/Sec): " << avg_image_size_in_mpixels_per_sec << std::endl;
|
||||
if (total_num_bad_jpegs || total_num_jpegs_with_411_subsampling || total_num_jpegs_with_unknown_subsampling || total_num_jpegs_with_unsupported_resolution) {
|
||||
std::cout << "Total skipped images: " << total_num_bad_jpegs + total_num_jpegs_with_411_subsampling + total_num_jpegs_with_unknown_subsampling + total_num_jpegs_with_unsupported_resolution;
|
||||
if (total_num_bad_jpegs) {
|
||||
std::cout << " ,total images that cannot be parsed: " << total_num_bad_jpegs;
|
||||
}
|
||||
if (total_num_jpegs_with_411_subsampling) {
|
||||
std::cout << " ,total images with YUV 4:1:1 chroam subsampling: " << total_num_jpegs_with_411_subsampling;
|
||||
}
|
||||
if (total_num_jpegs_with_unknown_subsampling) {
|
||||
std::cout << " ,total images with unknwon chroam subsampling: " << total_num_jpegs_with_unknown_subsampling;
|
||||
}
|
||||
if (total_num_jpegs_with_unsupported_resolution) {
|
||||
std::cout << " ,total images with unsupported_resolution: " << total_num_jpegs_with_unsupported_resolution;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
if (total_decoded_images > 0) {
|
||||
std::cout << "Average processing time per image (ms): " << average_decoding_time_in_milli_sec << std::endl;
|
||||
std::cout << "Average decoded images per sec (Images/Sec): " << avg_images_per_sec << std::endl;
|
||||
std::cout << "Average decoded images size (Mpixels/Sec): " << avg_image_size_in_mpixels_per_sec << std::endl;
|
||||
}
|
||||
|
||||
for (auto& handle : rocjpeg_handles) {
|
||||
CHECK_ROCJPEG(rocJpegDestroy(handle));
|
||||
|
||||
@@ -30,6 +30,7 @@ THE SOFTWARE.
|
||||
#include <vector>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <algorithm>
|
||||
#if __cplusplus >= 201703L && __has_include(<filesystem>)
|
||||
#include <filesystem>
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
مرجع در شماره جدید
Block a user