diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c55834f63..92d3ff18e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,11 @@ Documentation for rocJPEG is available at [https://rocm.docs.amd.com/projects/rocJPEG/en/latest/](https://rocm.docs.amd.com/projects/rocJPEG/en/latest/) -## (Unreleased) rocJPEG 0.9.0 +## (Unreleased) rocJPEG 0.10.0 ## Changed * Readme - cleanup and updates to pre-reqs +* The `decode_params` argument of the `rocJpegDecodeBatched` API is now an array of `RocJpegDecodeParams` structs representing the decode parameters for the batch of JPEG images. ## Removed * Dev Package - No longer installs pkg-config diff --git a/CMakeLists.txt b/CMakeLists.txt index 46d2e74528..4d9dfdcbbb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,7 +40,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED On) # NOTE: Match version with api/rocjpeg_version.h -set(VERSION "0.9.0") +set(VERSION "0.10.0") # Set Project Version and Language project(rocjpeg VERSION ${VERSION} LANGUAGES CXX) diff --git a/api/rocjpeg.h b/api/rocjpeg.h index bf819fa7f3..11a675fd2d 100644 --- a/api/rocjpeg.h +++ b/api/rocjpeg.h @@ -319,12 +319,12 @@ RocJpegStatus ROCJPEGAPI rocJpegDecode(RocJpegHandle handle, RocJpegStreamHandle * @ingroup group_amd_rocjpeg * @brief Decodes a batch of JPEG images using the rocJPEG library. * - * Decodes a batch of JPEG images using the rocJPEG library. + * This function decodes a batch of JPEG images using the rocJPEG library. * * @param handle The rocJPEG handle. * @param jpeg_stream_handles An array of rocJPEG stream handles representing the input JPEG streams. * @param batch_size The number of JPEG streams in the batch. - * @param decode_params The decode parameters for the JPEG decoding process. + * @param decode_params An array of RocJpegDecodeParams structs representing the decode parameters for the batch of JPEG images. * @param destinations An array of rocJPEG images representing the output decoded images. * @return The status of the JPEG decoding operation. */ diff --git a/api/rocjpeg_version.h b/api/rocjpeg_version.h index bb627246ae..f640ee1b45 100644 --- a/api/rocjpeg_version.h +++ b/api/rocjpeg_version.h @@ -34,7 +34,7 @@ THE SOFTWARE. extern "C" { #endif #define ROCJPEG_MAJOR_VERSION 0 -#define ROCJPEG_MINOR_VERSION 9 +#define ROCJPEG_MINOR_VERSION 10 #define ROCJPEG_MICRO_VERSION 0 diff --git a/samples/jpegDecodeBatched/jpegdecodebatched.cpp b/samples/jpegDecodeBatched/jpegdecodebatched.cpp index 0b09bdfcd2..5121b3200f 100644 --- a/samples/jpegDecodeBatched/jpegdecodebatched.cpp +++ b/samples/jpegDecodeBatched/jpegdecodebatched.cpp @@ -49,6 +49,7 @@ int main(int argc, char **argv) { RocJpegImage output_image = {}; std::vector output_images; RocJpegDecodeParams decode_params = {}; + std::vector decode_params_batch; RocJpegUtils rocjpeg_utils; std::vector base_file_names; std::vector rocjpeg_stream_handles_for_current_batch; @@ -61,15 +62,11 @@ int main(int argc, char **argv) { uint64_t num_jpegs_with_unknown_subsampling = 0; uint64_t num_jpegs_with_unsupported_resolution = 0; int current_batch_size = 0; - - RocJpegUtils::ParseCommandLine(input_path, output_file_path, save_images, device_id, rocjpeg_backend, decode_params, nullptr, &batch_size, argc, argv); - bool is_roi_valid = false; uint32_t roi_width; uint32_t roi_height; - roi_width = decode_params.crop_rectangle.right - decode_params.crop_rectangle.left; - roi_height = decode_params.crop_rectangle.bottom - decode_params.crop_rectangle.top; - + + RocJpegUtils::ParseCommandLine(input_path, output_file_path, save_images, device_id, rocjpeg_backend, decode_params, nullptr, &batch_size, argc, argv); if (!RocJpegUtils::GetFilePaths(input_path, file_paths, is_dir, is_file)) { std::cerr << "ERROR: Failed to get input file paths!" << std::endl; return EXIT_FAILURE; @@ -89,6 +86,7 @@ int main(int argc, char **argv) { batch_images.resize(batch_size); output_images.resize(batch_size); + decode_params_batch.resize(batch_size, decode_params); prior_channel_sizes.resize(batch_size, std::vector(ROCJPEG_MAX_COMPONENT, 0)); widths.resize(batch_size, std::vector(ROCJPEG_MAX_COMPONENT, 0)); heights.resize(batch_size, std::vector(ROCJPEG_MAX_COMPONENT, 0)); @@ -134,10 +132,6 @@ int main(int argc, char **argv) { CHECK_ROCJPEG(rocJpegGetImageInfo(rocjpeg_handle, rocjpeg_stream_handles[index], &num_components, &temp_subsampling, temp_widths.data(), temp_heights.data())); - if (roi_width > 0 && roi_height > 0 && roi_width <= widths[index][0] && roi_height <= heights[index][0]) { - is_roi_valid = true; - } - rocjpeg_utils.GetChromaSubsamplingStr(temp_subsampling, chroma_sub_sampling); if (temp_widths[0] < 64 || temp_heights[0] < 64) { if (is_dir) { @@ -164,7 +158,7 @@ int main(int argc, char **argv) { } } - if (rocjpeg_utils.GetChannelPitchAndSizes(decode_params, temp_subsampling, temp_widths.data(), temp_heights.data(), num_channels, output_images[current_batch_size], channel_sizes)) { + if (rocjpeg_utils.GetChannelPitchAndSizes(decode_params_batch[index], temp_subsampling, temp_widths.data(), temp_heights.data(), num_channels, output_images[current_batch_size], channel_sizes)) { std::cerr << "ERROR: Failed to get the channel pitch and sizes" << std::endl; return EXIT_FAILURE; } @@ -191,7 +185,7 @@ int main(int argc, char **argv) { 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, rocjpeg_stream_handles_for_current_batch.data(), current_batch_size, &decode_params, output_images.data())); + CHECK_ROCJPEG(rocJpegDecodeBatched(rocjpeg_handle, rocjpeg_stream_handles_for_current_batch.data(), current_batch_size, decode_params_batch.data(), output_images.data())); auto end_time = std::chrono::high_resolution_clock::now(); time_per_batch_in_milli_sec = std::chrono::duration(end_time - start_time).count(); } @@ -207,12 +201,15 @@ 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 + roi_width = decode_params_batch[b].crop_rectangle.right - decode_params_batch[b].crop_rectangle.left; + roi_height = decode_params_batch[b].crop_rectangle.bottom - decode_params_batch[b].crop_rectangle.top; + is_roi_valid = (roi_width > 0 && roi_height > 0 && roi_width <= widths[b][0] && roi_height <= heights[b][0]) ? true : false; uint32_t width = is_roi_valid ? roi_width : widths[b][0]; uint32_t height = is_roi_valid ? roi_height : 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_batch[b].output_format, base_file_names[b], width, height, 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, &output_images[b], width, height, subsamplings[b], decode_params_batch[b].output_format); } } diff --git a/samples/jpegDecodePerf/jpegdecodeperf.cpp b/samples/jpegDecodePerf/jpegdecodeperf.cpp index 21a4b457cc..5f71fe3811 100644 --- a/samples/jpegDecodePerf/jpegdecodeperf.cpp +++ b/samples/jpegDecodePerf/jpegdecodeperf.cpp @@ -50,8 +50,6 @@ void DecodeImages(DecodeInfo &decode_info, RocJpegUtils rocjpeg_utils, RocJpegDe bool is_roi_valid = false; uint32_t roi_width; uint32_t roi_height; - roi_width = decode_params.crop_rectangle.right - decode_params.crop_rectangle.left; - roi_height = decode_params.crop_rectangle.bottom - decode_params.crop_rectangle.top; uint8_t num_components; uint32_t channel_sizes[ROCJPEG_MAX_COMPONENT] = {}; std::string chroma_sub_sampling = ""; @@ -65,6 +63,7 @@ void DecodeImages(DecodeInfo &decode_info, RocJpegUtils rocjpeg_utils, RocJpegDe std::vector> prior_channel_sizes(batch_size, std::vector(ROCJPEG_MAX_COMPONENT, 0)); std::vector subsamplings(batch_size); std::vector output_images(batch_size); + std::vector decode_params_batch(batch_size, decode_params); std::vector base_file_names(batch_size); std::vector rocjpeg_stream_handles(batch_size); std::vector temp_widths(ROCJPEG_MAX_COMPONENT, 0); @@ -105,9 +104,6 @@ void DecodeImages(DecodeInfo &decode_info, RocJpegUtils rocjpeg_utils, RocJpegDe } CHECK_ROCJPEG(rocJpegGetImageInfo(decode_info.rocjpeg_handle, decode_info.rocjpeg_stream_handles[index], &num_components, &temp_subsampling, temp_widths.data(), temp_heights.data())); - if (roi_width > 0 && roi_height > 0 && roi_width <= temp_widths[0] && roi_height <= temp_heights[0]) { - is_roi_valid = true; - } rocjpeg_utils.GetChromaSubsamplingStr(temp_subsampling, chroma_sub_sampling); if (temp_widths[0] < 64 || temp_heights[0] < 64) { @@ -125,7 +121,7 @@ void DecodeImages(DecodeInfo &decode_info, RocJpegUtils rocjpeg_utils, RocJpegDe continue; } - if (rocjpeg_utils.GetChannelPitchAndSizes(decode_params, temp_subsampling, temp_widths.data(), temp_heights.data(), num_channels, output_images[current_batch_size], channel_sizes)) { + if (rocjpeg_utils.GetChannelPitchAndSizes(decode_params_batch[index], temp_subsampling, temp_widths.data(), temp_heights.data(), num_channels, output_images[current_batch_size], channel_sizes)) { std::cerr << "ERROR: Failed to get the channel pitch and sizes" << std::endl; return; } @@ -153,7 +149,7 @@ void DecodeImages(DecodeInfo &decode_info, RocJpegUtils rocjpeg_utils, RocJpegDe 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(decode_info.rocjpeg_handle, rocjpeg_stream_handles.data(), current_batch_size, &decode_params, output_images.data())); + CHECK_ROCJPEG(rocJpegDecodeBatched(decode_info.rocjpeg_handle, rocjpeg_stream_handles.data(), current_batch_size, decode_params_batch.data(), output_images.data())); auto end_time = std::chrono::high_resolution_clock::now(); time_per_batch_in_milli_sec = std::chrono::duration(end_time - start_time).count(); } @@ -169,6 +165,9 @@ void DecodeImages(DecodeInfo &decode_info, RocJpegUtils rocjpeg_utils, RocJpegDe 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 + roi_width = decode_params_batch[b].crop_rectangle.right - decode_params_batch[b].crop_rectangle.left; + roi_height = decode_params_batch[b].crop_rectangle.bottom - decode_params_batch[b].crop_rectangle.top; + is_roi_valid = (roi_width > 0 && roi_height > 0 && roi_width <= widths[b][0] && roi_height <= heights[b][0]) ? true : false; uint32_t width = is_roi_valid ? roi_width : widths[b][0]; uint32_t height = is_roi_valid ? roi_height : heights[b][0]; rocjpeg_utils.GetOutputFileExt(decode_params.output_format, base_file_names[b], width, height, subsamplings[b], image_save_path); diff --git a/src/rocjpeg_decoder.cpp b/src/rocjpeg_decoder.cpp index 6f6b7c62bd..85ff7b47dc 100644 --- a/src/rocjpeg_decoder.cpp +++ b/src/rocjpeg_decoder.cpp @@ -216,7 +216,7 @@ RocJpegStatus RocJpegDecoder::DecodeBatched(RocJpegStreamHandle *jpeg_streams, i jpeg_streams_params[j] = std::move(*jpeg_stream_params); } - CHECK_ROCJPEG(jpeg_vaapi_decoder_.SubmitDecodeBatched(jpeg_streams_params.data() + i, current_batch_size, decode_params, current_surface_ids.data() + i)); + CHECK_ROCJPEG(jpeg_vaapi_decoder_.SubmitDecodeBatched(jpeg_streams_params.data() + i, current_batch_size, &decode_params[i], current_surface_ids.data() + i)); for (int k = 0; k < current_batch_size; k++) { HipInteropDeviceMem hip_interop_dev_mem = {}; @@ -231,8 +231,8 @@ RocJpegStatus RocJpegDecoder::DecodeBatched(RocJpegStreamHandle *jpeg_streams, i bool is_roi_valid = false; uint32_t roi_width; uint32_t roi_height; - roi_width = decode_params->crop_rectangle.right - decode_params->crop_rectangle.left; - roi_height = decode_params->crop_rectangle.bottom - decode_params->crop_rectangle.top; + roi_width = decode_params[k + i].crop_rectangle.right - decode_params[k + i].crop_rectangle.left; + roi_height = decode_params[k + i].crop_rectangle.bottom - decode_params[k + i].crop_rectangle.top; if (roi_width > 0 && roi_height > 0 && roi_width <= jpeg_stream_params->picture_parameter_buffer.picture_width && roi_height <= jpeg_stream_params->picture_parameter_buffer.picture_height) { is_roi_valid = true; @@ -247,38 +247,38 @@ RocJpegStatus RocJpegDecoder::DecodeBatched(RocJpegStreamHandle *jpeg_streams, i is_roi_valid = false; } - switch (decode_params->output_format) { + switch (decode_params[k + i].output_format) { case ROCJPEG_OUTPUT_NATIVE: // Copy the native decoded output buffers from interop memory directly to the destination buffers CHECK_ROCJPEG(GetChromaHeight(hip_interop_dev_mem.surface_format, picture_height, chroma_height)); // Copy Luma (first channel) for any surface format - CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, picture_height, 0, &destinations[k + i], decode_params, is_roi_valid)); + CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, picture_height, 0, &destinations[k + i], &decode_params[k + i], is_roi_valid)); if (hip_interop_dev_mem.surface_format == VA_FOURCC_NV12) { // Copy the second channel (UV interleaved) for NV12 - CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 1, &destinations[k + i], decode_params, is_roi_valid)); + CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 1, &destinations[k + i], &decode_params[k + i], is_roi_valid)); } else if (hip_interop_dev_mem.surface_format == VA_FOURCC_444P || hip_interop_dev_mem.surface_format == VA_FOURCC_422V) { // Copy the second and third channels for YUV444 and YUV440 (i.e., YUV422V) - CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 1, &destinations[k + i], decode_params, is_roi_valid)); - CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 2, &destinations[k + i], decode_params, is_roi_valid)); + CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 1, &destinations[k + i], &decode_params[k + i], is_roi_valid)); + CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 2, &destinations[k + i], &decode_params[k + i], is_roi_valid)); } break; case ROCJPEG_OUTPUT_YUV_PLANAR: CHECK_ROCJPEG(GetChromaHeight(hip_interop_dev_mem.surface_format, picture_height, chroma_height)); CHECK_ROCJPEG(GetPlanarYUVOutputFormat(hip_interop_dev_mem, picture_width, - picture_height, chroma_height, &destinations[k + i], decode_params, is_roi_valid)); + picture_height, chroma_height, &destinations[k + i], &decode_params[k + i], is_roi_valid)); break; case ROCJPEG_OUTPUT_Y: CHECK_ROCJPEG(GetYOutputFormat(hip_interop_dev_mem, picture_width, - picture_height, &destinations[k + i], decode_params, is_roi_valid)); + picture_height, &destinations[k + i], &decode_params[k + i], is_roi_valid)); break; case ROCJPEG_OUTPUT_RGB: CHECK_ROCJPEG(ColorConvertToRGB(hip_interop_dev_mem, picture_width, - picture_height, &destinations[k + i], decode_params, is_roi_valid)); + picture_height, &destinations[k + i], &decode_params[k + i], is_roi_valid)); break; case ROCJPEG_OUTPUT_RGB_PLANAR: CHECK_ROCJPEG(ColorConvertToRGBPlanar(hip_interop_dev_mem, picture_width, - picture_height, &destinations[k + i], decode_params, is_roi_valid)); + picture_height, &destinations[k + i], &decode_params[k + i], is_roi_valid)); break; default: break; diff --git a/src/rocjpeg_vaapi_decoder.cpp b/src/rocjpeg_vaapi_decoder.cpp index 14cf5d2756..cf4be1cfd0 100644 --- a/src/rocjpeg_vaapi_decoder.cpp +++ b/src/rocjpeg_vaapi_decoder.cpp @@ -711,11 +711,11 @@ RocJpegStatus RocJpegVappiDecoder::SubmitDecodeBatched(JpegStreamParameters *jpe return ROCJPEG_STATUS_JPEG_NOT_SUPPORTED; } - if ((decode_params->output_format == ROCJPEG_OUTPUT_RGB || decode_params->output_format == ROCJPEG_OUTPUT_RGB_PLANAR) && current_vcn_jpeg_spec_.can_convert_to_rgb && jpeg_streams_params[i].chroma_subsampling != CSS_440) { - if (decode_params->output_format == ROCJPEG_OUTPUT_RGB) { + if ((decode_params[i].output_format == ROCJPEG_OUTPUT_RGB || decode_params[i].output_format == ROCJPEG_OUTPUT_RGB_PLANAR) && current_vcn_jpeg_spec_.can_convert_to_rgb && jpeg_streams_params[i].chroma_subsampling != CSS_440) { + if (decode_params[i].output_format == ROCJPEG_OUTPUT_RGB) { jpeg_stream_key.surface_format = VA_RT_FORMAT_RGB32; jpeg_stream_key.pixel_format = VA_FOURCC_RGBA; - } else if (decode_params->output_format == ROCJPEG_OUTPUT_RGB_PLANAR) { + } else if (decode_params[i].output_format == ROCJPEG_OUTPUT_RGB_PLANAR) { jpeg_stream_key.surface_format = VA_RT_FORMAT_RGBP; jpeg_stream_key.pixel_format = VA_FOURCC_RGBP; } @@ -770,8 +770,6 @@ RocJpegStatus RocJpegVappiDecoder::SubmitDecodeBatched(JpegStreamParameters *jpe uint32_t roi_width; uint32_t roi_height; - roi_width = decode_params->crop_rectangle.right - decode_params->crop_rectangle.left; - roi_height = decode_params->crop_rectangle.bottom - decode_params->crop_rectangle.top; // Iterate through all entries of jpeg_stream_groups. // Check if there is a matching entry in the memory pool. @@ -805,16 +803,18 @@ RocJpegStatus RocJpegVappiDecoder::SubmitDecodeBatched(JpegStreamParameters *jpe for (int idx : indices) { // if the HW JPEG decoder has a built-in ROI-decode capability then fill the requested crop rectangle to the picture parameter buffer void* picture_parameter_buffer = &jpeg_streams_params[idx].picture_parameter_buffer; + roi_width = decode_params[idx].crop_rectangle.right - decode_params[idx].crop_rectangle.left; + roi_height = decode_params[idx].crop_rectangle.bottom - decode_params[idx].crop_rectangle.top; if (current_vcn_jpeg_spec_.can_roi_decode && roi_width > 0 && roi_height > 0 && roi_width <= jpeg_streams_params[idx].picture_parameter_buffer.picture_width && roi_height <= jpeg_streams_params[idx].picture_parameter_buffer.picture_height) { #if VA_CHECK_VERSION(1, 21, 0) - reinterpret_cast(picture_parameter_buffer)->crop_rectangle.x = decode_params->crop_rectangle.left; - reinterpret_cast(picture_parameter_buffer)->crop_rectangle.y = decode_params->crop_rectangle.top; + reinterpret_cast(picture_parameter_buffer)->crop_rectangle.x = decode_params[idx].crop_rectangle.left; + reinterpret_cast(picture_parameter_buffer)->crop_rectangle.y = decode_params[idx].crop_rectangle.top; reinterpret_cast(picture_parameter_buffer)->crop_rectangle.width = roi_width; reinterpret_cast(picture_parameter_buffer)->crop_rectangle.height = roi_height; #else - reinterpret_cast(picture_parameter_buffer)->va_reserved[0] = decode_params->crop_rectangle.top << 16 | decode_params->crop_rectangle.left; + reinterpret_cast(picture_parameter_buffer)->va_reserved[0] = decode_params[idx].crop_rectangle.top << 16 | decode_params[idx].crop_rectangle.left; reinterpret_cast(picture_parameter_buffer)->va_reserved[1] = roi_height << 16 | roi_width; #endif }