Skip to content

Commit 63637ce

Browse files
Add support for multiple regions of interest (ROI) for batch JPEG decoding (#126)
[ROCm/rocjpeg commit: 692d4bb]
1 parent 9bcf240 commit 63637ce

File tree

8 files changed

+43
-46
lines changed

8 files changed

+43
-46
lines changed

projects/rocjpeg/CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
Documentation for rocJPEG is available at
44
[https://rocm.docs.amd.com/projects/rocJPEG/en/latest/](https://rocm.docs.amd.com/projects/rocJPEG/en/latest/)
55

6-
## (Unreleased) rocJPEG 0.9.0
6+
## (Unreleased) rocJPEG 0.10.0
77

88
## Changed
99
* Readme - cleanup and updates to pre-reqs
10+
* 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.
1011

1112
## Removed
1213
* Dev Package - No longer installs pkg-config

projects/rocjpeg/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ set(CMAKE_CXX_STANDARD 17)
4040
set(CMAKE_CXX_STANDARD_REQUIRED On)
4141

4242
# NOTE: Match version with api/rocjpeg_version.h
43-
set(VERSION "0.9.0")
43+
set(VERSION "0.10.0")
4444
# Set Project Version and Language
4545
project(rocjpeg VERSION ${VERSION} LANGUAGES CXX)
4646

projects/rocjpeg/api/rocjpeg.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,12 +319,12 @@ RocJpegStatus ROCJPEGAPI rocJpegDecode(RocJpegHandle handle, RocJpegStreamHandle
319319
* @ingroup group_amd_rocjpeg
320320
* @brief Decodes a batch of JPEG images using the rocJPEG library.
321321
*
322-
* Decodes a batch of JPEG images using the rocJPEG library.
322+
* This function decodes a batch of JPEG images using the rocJPEG library.
323323
*
324324
* @param handle The rocJPEG handle.
325325
* @param jpeg_stream_handles An array of rocJPEG stream handles representing the input JPEG streams.
326326
* @param batch_size The number of JPEG streams in the batch.
327-
* @param decode_params The decode parameters for the JPEG decoding process.
327+
* @param decode_params An array of RocJpegDecodeParams structs representing the decode parameters for the batch of JPEG images.
328328
* @param destinations An array of rocJPEG images representing the output decoded images.
329329
* @return The status of the JPEG decoding operation.
330330
*/

projects/rocjpeg/api/rocjpeg_version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ THE SOFTWARE.
3434
extern "C" {
3535
#endif
3636
#define ROCJPEG_MAJOR_VERSION 0
37-
#define ROCJPEG_MINOR_VERSION 9
37+
#define ROCJPEG_MINOR_VERSION 10
3838
#define ROCJPEG_MICRO_VERSION 0
3939

4040

projects/rocjpeg/samples/jpegDecodeBatched/jpegdecodebatched.cpp

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ int main(int argc, char **argv) {
4949
RocJpegImage output_image = {};
5050
std::vector<RocJpegImage> output_images;
5151
RocJpegDecodeParams decode_params = {};
52+
std::vector<RocJpegDecodeParams> decode_params_batch;
5253
RocJpegUtils rocjpeg_utils;
5354
std::vector<std::string> base_file_names;
5455
std::vector<RocJpegStreamHandle> rocjpeg_stream_handles_for_current_batch;
@@ -61,15 +62,11 @@ int main(int argc, char **argv) {
6162
uint64_t num_jpegs_with_unknown_subsampling = 0;
6263
uint64_t num_jpegs_with_unsupported_resolution = 0;
6364
int current_batch_size = 0;
64-
65-
RocJpegUtils::ParseCommandLine(input_path, output_file_path, save_images, device_id, rocjpeg_backend, decode_params, nullptr, &batch_size, argc, argv);
66-
6765
bool is_roi_valid = false;
6866
uint32_t roi_width;
6967
uint32_t roi_height;
70-
roi_width = decode_params.crop_rectangle.right - decode_params.crop_rectangle.left;
71-
roi_height = decode_params.crop_rectangle.bottom - decode_params.crop_rectangle.top;
72-
68+
69+
RocJpegUtils::ParseCommandLine(input_path, output_file_path, save_images, device_id, rocjpeg_backend, decode_params, nullptr, &batch_size, argc, argv);
7370
if (!RocJpegUtils::GetFilePaths(input_path, file_paths, is_dir, is_file)) {
7471
std::cerr << "ERROR: Failed to get input file paths!" << std::endl;
7572
return EXIT_FAILURE;
@@ -89,6 +86,7 @@ int main(int argc, char **argv) {
8986

9087
batch_images.resize(batch_size);
9188
output_images.resize(batch_size);
89+
decode_params_batch.resize(batch_size, decode_params);
9290
prior_channel_sizes.resize(batch_size, std::vector<uint32_t>(ROCJPEG_MAX_COMPONENT, 0));
9391
widths.resize(batch_size, std::vector<uint32_t>(ROCJPEG_MAX_COMPONENT, 0));
9492
heights.resize(batch_size, std::vector<uint32_t>(ROCJPEG_MAX_COMPONENT, 0));
@@ -134,10 +132,6 @@ int main(int argc, char **argv) {
134132

135133
CHECK_ROCJPEG(rocJpegGetImageInfo(rocjpeg_handle, rocjpeg_stream_handles[index], &num_components, &temp_subsampling, temp_widths.data(), temp_heights.data()));
136134

137-
if (roi_width > 0 && roi_height > 0 && roi_width <= widths[index][0] && roi_height <= heights[index][0]) {
138-
is_roi_valid = true;
139-
}
140-
141135
rocjpeg_utils.GetChromaSubsamplingStr(temp_subsampling, chroma_sub_sampling);
142136
if (temp_widths[0] < 64 || temp_heights[0] < 64) {
143137
if (is_dir) {
@@ -164,7 +158,7 @@ int main(int argc, char **argv) {
164158
}
165159
}
166160

167-
if (rocjpeg_utils.GetChannelPitchAndSizes(decode_params, temp_subsampling, temp_widths.data(), temp_heights.data(), num_channels, output_images[current_batch_size], channel_sizes)) {
161+
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)) {
168162
std::cerr << "ERROR: Failed to get the channel pitch and sizes" << std::endl;
169163
return EXIT_FAILURE;
170164
}
@@ -191,7 +185,7 @@ int main(int argc, char **argv) {
191185
double time_per_batch_in_milli_sec = 0;
192186
if (current_batch_size > 0) {
193187
auto start_time = std::chrono::high_resolution_clock::now();
194-
CHECK_ROCJPEG(rocJpegDecodeBatched(rocjpeg_handle, rocjpeg_stream_handles_for_current_batch.data(), current_batch_size, &decode_params, output_images.data()));
188+
CHECK_ROCJPEG(rocJpegDecodeBatched(rocjpeg_handle, rocjpeg_stream_handles_for_current_batch.data(), current_batch_size, decode_params_batch.data(), output_images.data()));
195189
auto end_time = std::chrono::high_resolution_clock::now();
196190
time_per_batch_in_milli_sec = std::chrono::duration<double, std::milli>(end_time - start_time).count();
197191
}
@@ -207,12 +201,15 @@ int main(int argc, char **argv) {
207201
for (int b = 0; b < current_batch_size; b++) {
208202
std::string image_save_path = output_file_path;
209203
//if ROI is present, need to pass roi_width and roi_height
204+
roi_width = decode_params_batch[b].crop_rectangle.right - decode_params_batch[b].crop_rectangle.left;
205+
roi_height = decode_params_batch[b].crop_rectangle.bottom - decode_params_batch[b].crop_rectangle.top;
206+
is_roi_valid = (roi_width > 0 && roi_height > 0 && roi_width <= widths[b][0] && roi_height <= heights[b][0]) ? true : false;
210207
uint32_t width = is_roi_valid ? roi_width : widths[b][0];
211208
uint32_t height = is_roi_valid ? roi_height : heights[b][0];
212209
if (is_dir) {
213-
rocjpeg_utils.GetOutputFileExt(decode_params.output_format, base_file_names[b], width, height, subsamplings[b], image_save_path);
210+
rocjpeg_utils.GetOutputFileExt(decode_params_batch[b].output_format, base_file_names[b], width, height, subsamplings[b], image_save_path);
214211
}
215-
rocjpeg_utils.SaveImage(image_save_path, &output_images[b], width, height, subsamplings[b], decode_params.output_format);
212+
rocjpeg_utils.SaveImage(image_save_path, &output_images[b], width, height, subsamplings[b], decode_params_batch[b].output_format);
216213
}
217214
}
218215

projects/rocjpeg/samples/jpegDecodePerf/jpegdecodeperf.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ void DecodeImages(DecodeInfo &decode_info, RocJpegUtils rocjpeg_utils, RocJpegDe
5050
bool is_roi_valid = false;
5151
uint32_t roi_width;
5252
uint32_t roi_height;
53-
roi_width = decode_params.crop_rectangle.right - decode_params.crop_rectangle.left;
54-
roi_height = decode_params.crop_rectangle.bottom - decode_params.crop_rectangle.top;
5553
uint8_t num_components;
5654
uint32_t channel_sizes[ROCJPEG_MAX_COMPONENT] = {};
5755
std::string chroma_sub_sampling = "";
@@ -65,6 +63,7 @@ void DecodeImages(DecodeInfo &decode_info, RocJpegUtils rocjpeg_utils, RocJpegDe
6563
std::vector<std::vector<uint32_t>> prior_channel_sizes(batch_size, std::vector<uint32_t>(ROCJPEG_MAX_COMPONENT, 0));
6664
std::vector<RocJpegChromaSubsampling> subsamplings(batch_size);
6765
std::vector<RocJpegImage> output_images(batch_size);
66+
std::vector<RocJpegDecodeParams> decode_params_batch(batch_size, decode_params);
6867
std::vector<std::string> base_file_names(batch_size);
6968
std::vector<RocJpegStreamHandle> rocjpeg_stream_handles(batch_size);
7069
std::vector<uint32_t> temp_widths(ROCJPEG_MAX_COMPONENT, 0);
@@ -105,9 +104,6 @@ void DecodeImages(DecodeInfo &decode_info, RocJpegUtils rocjpeg_utils, RocJpegDe
105104
}
106105

107106
CHECK_ROCJPEG(rocJpegGetImageInfo(decode_info.rocjpeg_handle, decode_info.rocjpeg_stream_handles[index], &num_components, &temp_subsampling, temp_widths.data(), temp_heights.data()));
108-
if (roi_width > 0 && roi_height > 0 && roi_width <= temp_widths[0] && roi_height <= temp_heights[0]) {
109-
is_roi_valid = true;
110-
}
111107

112108
rocjpeg_utils.GetChromaSubsamplingStr(temp_subsampling, chroma_sub_sampling);
113109
if (temp_widths[0] < 64 || temp_heights[0] < 64) {
@@ -125,7 +121,7 @@ void DecodeImages(DecodeInfo &decode_info, RocJpegUtils rocjpeg_utils, RocJpegDe
125121
continue;
126122
}
127123

128-
if (rocjpeg_utils.GetChannelPitchAndSizes(decode_params, temp_subsampling, temp_widths.data(), temp_heights.data(), num_channels, output_images[current_batch_size], channel_sizes)) {
124+
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)) {
129125
std::cerr << "ERROR: Failed to get the channel pitch and sizes" << std::endl;
130126
return;
131127
}
@@ -153,7 +149,7 @@ void DecodeImages(DecodeInfo &decode_info, RocJpegUtils rocjpeg_utils, RocJpegDe
153149
double time_per_batch_in_milli_sec = 0;
154150
if (current_batch_size > 0) {
155151
auto start_time = std::chrono::high_resolution_clock::now();
156-
CHECK_ROCJPEG(rocJpegDecodeBatched(decode_info.rocjpeg_handle, rocjpeg_stream_handles.data(), current_batch_size, &decode_params, output_images.data()));
152+
CHECK_ROCJPEG(rocJpegDecodeBatched(decode_info.rocjpeg_handle, rocjpeg_stream_handles.data(), current_batch_size, decode_params_batch.data(), output_images.data()));
157153
auto end_time = std::chrono::high_resolution_clock::now();
158154
time_per_batch_in_milli_sec = std::chrono::duration<double, std::milli>(end_time - start_time).count();
159155
}
@@ -169,6 +165,9 @@ void DecodeImages(DecodeInfo &decode_info, RocJpegUtils rocjpeg_utils, RocJpegDe
169165
for (int b = 0; b < current_batch_size; b++) {
170166
std::string image_save_path = output_file_path;
171167
//if ROI is present, need to pass roi_width and roi_height
168+
roi_width = decode_params_batch[b].crop_rectangle.right - decode_params_batch[b].crop_rectangle.left;
169+
roi_height = decode_params_batch[b].crop_rectangle.bottom - decode_params_batch[b].crop_rectangle.top;
170+
is_roi_valid = (roi_width > 0 && roi_height > 0 && roi_width <= widths[b][0] && roi_height <= heights[b][0]) ? true : false;
172171
uint32_t width = is_roi_valid ? roi_width : widths[b][0];
173172
uint32_t height = is_roi_valid ? roi_height : heights[b][0];
174173
rocjpeg_utils.GetOutputFileExt(decode_params.output_format, base_file_names[b], width, height, subsamplings[b], image_save_path);

projects/rocjpeg/src/rocjpeg_decoder.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ RocJpegStatus RocJpegDecoder::DecodeBatched(RocJpegStreamHandle *jpeg_streams, i
216216
jpeg_streams_params[j] = std::move(*jpeg_stream_params);
217217
}
218218

219-
CHECK_ROCJPEG(jpeg_vaapi_decoder_.SubmitDecodeBatched(jpeg_streams_params.data() + i, current_batch_size, decode_params, current_surface_ids.data() + i));
219+
CHECK_ROCJPEG(jpeg_vaapi_decoder_.SubmitDecodeBatched(jpeg_streams_params.data() + i, current_batch_size, &decode_params[i], current_surface_ids.data() + i));
220220

221221
for (int k = 0; k < current_batch_size; k++) {
222222
HipInteropDeviceMem hip_interop_dev_mem = {};
@@ -231,8 +231,8 @@ RocJpegStatus RocJpegDecoder::DecodeBatched(RocJpegStreamHandle *jpeg_streams, i
231231
bool is_roi_valid = false;
232232
uint32_t roi_width;
233233
uint32_t roi_height;
234-
roi_width = decode_params->crop_rectangle.right - decode_params->crop_rectangle.left;
235-
roi_height = decode_params->crop_rectangle.bottom - decode_params->crop_rectangle.top;
234+
roi_width = decode_params[k + i].crop_rectangle.right - decode_params[k + i].crop_rectangle.left;
235+
roi_height = decode_params[k + i].crop_rectangle.bottom - decode_params[k + i].crop_rectangle.top;
236236

237237
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) {
238238
is_roi_valid = true;
@@ -247,38 +247,38 @@ RocJpegStatus RocJpegDecoder::DecodeBatched(RocJpegStreamHandle *jpeg_streams, i
247247
is_roi_valid = false;
248248
}
249249

250-
switch (decode_params->output_format) {
250+
switch (decode_params[k + i].output_format) {
251251
case ROCJPEG_OUTPUT_NATIVE:
252252
// Copy the native decoded output buffers from interop memory directly to the destination buffers
253253
CHECK_ROCJPEG(GetChromaHeight(hip_interop_dev_mem.surface_format, picture_height, chroma_height));
254254
// Copy Luma (first channel) for any surface format
255-
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, picture_height, 0, &destinations[k + i], decode_params, is_roi_valid));
255+
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, picture_height, 0, &destinations[k + i], &decode_params[k + i], is_roi_valid));
256256
if (hip_interop_dev_mem.surface_format == VA_FOURCC_NV12) {
257257
// Copy the second channel (UV interleaved) for NV12
258-
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 1, &destinations[k + i], decode_params, is_roi_valid));
258+
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 1, &destinations[k + i], &decode_params[k + i], is_roi_valid));
259259
} else if (hip_interop_dev_mem.surface_format == VA_FOURCC_444P ||
260260
hip_interop_dev_mem.surface_format == VA_FOURCC_422V) {
261261
// Copy the second and third channels for YUV444 and YUV440 (i.e., YUV422V)
262-
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 1, &destinations[k + i], decode_params, is_roi_valid));
263-
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 2, &destinations[k + i], decode_params, is_roi_valid));
262+
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 1, &destinations[k + i], &decode_params[k + i], is_roi_valid));
263+
CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 2, &destinations[k + i], &decode_params[k + i], is_roi_valid));
264264
}
265265
break;
266266
case ROCJPEG_OUTPUT_YUV_PLANAR:
267267
CHECK_ROCJPEG(GetChromaHeight(hip_interop_dev_mem.surface_format, picture_height, chroma_height));
268268
CHECK_ROCJPEG(GetPlanarYUVOutputFormat(hip_interop_dev_mem, picture_width,
269-
picture_height, chroma_height, &destinations[k + i], decode_params, is_roi_valid));
269+
picture_height, chroma_height, &destinations[k + i], &decode_params[k + i], is_roi_valid));
270270
break;
271271
case ROCJPEG_OUTPUT_Y:
272272
CHECK_ROCJPEG(GetYOutputFormat(hip_interop_dev_mem, picture_width,
273-
picture_height, &destinations[k + i], decode_params, is_roi_valid));
273+
picture_height, &destinations[k + i], &decode_params[k + i], is_roi_valid));
274274
break;
275275
case ROCJPEG_OUTPUT_RGB:
276276
CHECK_ROCJPEG(ColorConvertToRGB(hip_interop_dev_mem, picture_width,
277-
picture_height, &destinations[k + i], decode_params, is_roi_valid));
277+
picture_height, &destinations[k + i], &decode_params[k + i], is_roi_valid));
278278
break;
279279
case ROCJPEG_OUTPUT_RGB_PLANAR:
280280
CHECK_ROCJPEG(ColorConvertToRGBPlanar(hip_interop_dev_mem, picture_width,
281-
picture_height, &destinations[k + i], decode_params, is_roi_valid));
281+
picture_height, &destinations[k + i], &decode_params[k + i], is_roi_valid));
282282
break;
283283
default:
284284
break;

0 commit comments

Comments
 (0)