From 7bdd495214cf90abc614830a1a2f8252202240f5 Mon Sep 17 00:00:00 2001 From: Aryan Salmanpour Date: Wed, 8 May 2024 11:30:36 -0400 Subject: [PATCH] Add support for adding a new struct RocJpegDecodeParams for passing the decode parameters to rocJpegDecode API (#22) --- CHANGELOG.md | 3 +- CMakeLists.txt | 2 +- api/rocjpeg.h | 27 +++++- docs/how-to/using-rocjpeg.rst | 9 +- samples/jpegDecode/jpegdecode.cpp | 12 +-- .../jpegdecodemultithreads.cpp | 16 ++-- samples/rocjpeg_samples_utils.h | 14 ++-- src/rocjpeg_api.cpp | 8 +- src/rocjpeg_decoder.cpp | 83 +++++++++---------- src/rocjpeg_decoder.h | 2 +- 10 files changed, 100 insertions(+), 76 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ad51a43fc..de58f80711 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ Documentation for rocJPEG is available at [https://rocm.docs.amd.com/projects/rocJPEG/en/latest/](TBD) -## rocJPEG 0.2.0 (Unreleased) +## rocJPEG 0.3.0 (Unreleased) ## Additions @@ -18,6 +18,7 @@ Documentation for rocJPEG is available at * Dependencies - Updates to core dependencies * LibVA Headers - Use public headers * mesa-amdgpu-va-drivers - RPM Package available on RPM from ROCm 6.2 +* add the RocJpegDecodeParams struct for passing the decode parameters ### Fixes diff --git a/CMakeLists.txt b/CMakeLists.txt index 834709b9a0..f3ead49fc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ cmake_minimum_required (VERSION 3.5) -set(VERSION "0.2.0") +set(VERSION "0.3.0") set(CMAKE_CXX_STANDARD 17) # Set Project Version and Language diff --git a/api/rocjpeg.h b/api/rocjpeg.h index 41bee611b8..e267859284 100644 --- a/api/rocjpeg.h +++ b/api/rocjpeg.h @@ -117,6 +117,29 @@ typedef enum { ROCJPEG_OUTPUT_FORMAT_MAX = 5 } RocJpegOutputFormat; +/*****************************************************/ +//! \struct RocJpegDecodeParams +//! The RocJpegDecodeParams structure contains the decoding parameters that specify the RocJpegOutputFormat. +//! It also defines the crop rectangle for the region of interest (ROI) and the target width and height for the decoded picture to be resized. +//! Note that if both the crop rectangle and target dimensions are defined, cropping is done first, followed by resizing the resulting ROI to +//! the target dimension. +//! \ingroup group_amd_rocjpeg +/*****************************************************/ +typedef struct { + RocJpegOutputFormat output_format; // Output data format. See RocJpegOutputFormat for description + struct { + int16_t left; + int16_t top; + int16_t right; + int16_t bottom; + } crop_rectangle; // (future use) Defines the region of interest (ROI) to be copied into the RocJpegImage output buffers. + struct { + uint32_t width; + uint32_t height; + } target_dimension; // (future use) Defines the target width and height of the picture to be resized. Both should be even. + // if specified, allocate the RocJpegImage buffers based on these dimensions. +} RocJpegDecodeParams; + /*****************************************************/ //! \enum RocJpegBackend //! \ingroup group_amd_rocjpeg @@ -185,11 +208,11 @@ RocJpegStatus ROCJPEGAPI rocJpegGetImageInfo(RocJpegHandle handle, const uint8_t //! IN handle : rocJpeg handle //! IN data : Pointer to the buffer containing the jpeg stream to be decoded. //! IN length : Length of the jpeg image buffer. -//! IN output_format : Output data format. See RocJpegOutputFormat for description +//! IN decode_params : Decode parameters. See RocJpegDecodeParams for description //! IN/OUT destination : Pointer to structure with information about output buffers. See RocJpegImage description. //! \return ROCJPEG_STATUS_SUCCESS if successful /*****************************************************************************************************/ -RocJpegStatus ROCJPEGAPI rocJpegDecode(RocJpegHandle handle, const uint8_t *data, size_t length, RocJpegOutputFormat output_format, RocJpegImage *destination); +RocJpegStatus ROCJPEGAPI rocJpegDecode(RocJpegHandle handle, const uint8_t *data, size_t length, const RocJpegDecodeParams *decode_params, RocJpegImage *destination); /*****************************************************************************************************/ //! \fn RocJpegStatus ROCJPEGAPI rocJpegDecodeBatchedInitialize(RocJpegHandle handle, int batch_size, int max_cpu_threads, RocJpegOutputFormat output_format); diff --git a/docs/how-to/using-rocjpeg.rst b/docs/how-to/using-rocjpeg.rst index 328cc0c113..5648ac614f 100644 --- a/docs/how-to/using-rocjpeg.rst +++ b/docs/how-to/using-rocjpeg.rst @@ -88,13 +88,14 @@ See the signature of this function below: RocJpegHandle handle, const uint8_t *data, size_t length, - RocJpegOutputFormat output_format, + const RocJpegDecodeParams *decode_params, RocJpegImage *destination); -In the above ``rocJpegDecode()`` function, you can use the parameters ``RocJpegOutputFormat`` and ``RocJpegImage`` to set +In the above ``rocJpegDecode()`` function, you can use the parameters ``RocJpegDecodeParams`` and ``RocJpegImage`` to set the output behavior of the ``rocJpegDecode()`` function. The ``RocJpegImage`` structure is JPEG image descriptor used to return the decoded output image. User must allocate device memories for each channel for this structure and pass it to the -``rocJpegDecode()`` API. This API then copies the decoded image to this struct based on the requested output format ``RocJpegOutputFormat``. +``rocJpegDecode()`` API. This API then copies the decoded image to this struct based on the requested output format ``RocJpegOutputFormat`` +defined in the ``RocJpegDecodeParams``. Below is the ``RocJpegImage`` structure. .. code:: cpp @@ -104,7 +105,7 @@ Below is the ``RocJpegImage`` structure. uint32_t pitch[ROCJPEG_MAX_COMPONENT]; } RocJpegImage; -You can set the ``RocJpegOutputFormat`` parameter to one of the ``output_format`` settings below: +You can set the ``RocJpegOutputFormat`` parameter of the ``RocJpegDecodeParams`` to one of the ``output_format`` settings below: .. csv-table:: :header: "output_format", "Meaning" diff --git a/samples/jpegDecode/jpegdecode.cpp b/samples/jpegDecode/jpegdecode.cpp index 2240838687..92d6ec1c5b 100644 --- a/samples/jpegDecode/jpegdecode.cpp +++ b/samples/jpegDecode/jpegdecode.cpp @@ -44,10 +44,10 @@ int main(int argc, char **argv) { RocJpegBackend rocjpeg_backend = ROCJPEG_BACKEND_HARDWARE; RocJpegHandle rocjpeg_handle = nullptr; RocJpegImage output_image = {}; - RocJpegOutputFormat output_format = ROCJPEG_OUTPUT_NATIVE; + RocJpegDecodeParams decode_params = {}; RocJpegUtils rocjpeg_utils; - RocJpegUtils::ParseCommandLine(input_path, output_file_path, save_images, device_id, rocjpeg_backend, output_format, nullptr, argc, argv); + RocJpegUtils::ParseCommandLine(input_path, output_file_path, save_images, device_id, rocjpeg_backend, decode_params, nullptr, 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; @@ -97,7 +97,7 @@ int main(int argc, char **argv) { return EXIT_FAILURE; } - if (rocjpeg_utils.GetChannelPitchAndSizes(output_format, subsampling, widths, heights, num_channels, output_image, channel_sizes)) { + if (rocjpeg_utils.GetChannelPitchAndSizes(decode_params.output_format, subsampling, widths, heights, num_channels, output_image, channel_sizes)) { std::cerr << "ERROR: Failed to get the channel pitch and sizes" << std::endl; return EXIT_FAILURE; } @@ -115,7 +115,7 @@ int main(int argc, char **argv) { std::cout << "Decoding started, please wait! ... " << std::endl; auto start_time = std::chrono::high_resolution_clock::now(); - CHECK_ROCJPEG(rocJpegDecode(rocjpeg_handle, reinterpret_cast(file_data.data()), file_size, output_format, &output_image)); + CHECK_ROCJPEG(rocJpegDecode(rocjpeg_handle, reinterpret_cast(file_data.data()), file_size, &decode_params, &output_image)); auto end_time = std::chrono::high_resolution_clock::now(); double time_per_image_in_milli_sec = std::chrono::duration(end_time - start_time).count(); double image_size_in_mpixels = (static_cast(widths[0]) * static_cast(heights[0]) / 1000000); @@ -124,9 +124,9 @@ int main(int argc, char **argv) { if (save_images) { std::string image_save_path = output_file_path; if (is_dir) { - rocjpeg_utils.GetOutputFileExt(output_format, base_file_name, widths[0], heights[0], image_save_path); + rocjpeg_utils.GetOutputFileExt(decode_params.output_format, base_file_name, widths[0], heights[0], image_save_path); } - rocjpeg_utils.SaveImage(image_save_path, &output_image, widths[0], heights[0], subsampling, output_format); + rocjpeg_utils.SaveImage(image_save_path, &output_image, widths[0], heights[0], subsampling, decode_params.output_format); } std::cout << "Average processing time per image (ms): " << time_per_image_in_milli_sec << std::endl; diff --git a/samples/jpegDecodeMultiThreads/jpegdecodemultithreads.cpp b/samples/jpegDecodeMultiThreads/jpegdecodemultithreads.cpp index f124109769..b7f76f3855 100644 --- a/samples/jpegDecodeMultiThreads/jpegdecodemultithreads.cpp +++ b/samples/jpegDecodeMultiThreads/jpegdecodemultithreads.cpp @@ -23,7 +23,7 @@ THE SOFTWARE. #include "../rocjpeg_samples_utils.h" void ThreadFunction(std::vector& jpegFiles, RocJpegHandle rocjpeg_handle, RocJpegUtils rocjpeg_util, RocJpegImage *output_image, std::mutex &mutex, - RocJpegOutputFormat output_format, 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) { std::vector file_data; uint8_t num_components; @@ -76,7 +76,7 @@ void ThreadFunction(std::vector& jpegFiles, RocJpegHandle rocjpeg_h return; } - if (rocjpeg_util.GetChannelPitchAndSizes(output_format, subsampling, widths, heights, num_channels, *output_image, channel_sizes)) { + if (rocjpeg_util.GetChannelPitchAndSizes(decode_params.output_format, subsampling, widths, heights, num_channels, *output_image, channel_sizes)) { std::cerr << "ERROR: Failed to get the channel pitch and sizes" << std::endl; return; } @@ -92,14 +92,14 @@ void ThreadFunction(std::vector& jpegFiles, RocJpegHandle rocjpeg_h } } - CHECK_ROCJPEG(rocJpegDecode(rocjpeg_handle, reinterpret_cast(file_data.data()), file_size, output_format, output_image)); + CHECK_ROCJPEG(rocJpegDecode(rocjpeg_handle, reinterpret_cast(file_data.data()), file_size, &decode_params, output_image)); *image_size_in_mpixels += (static_cast(widths[0]) * static_cast(heights[0]) / 1000000); *num_decoded_images += 1; if (save_images) { std::string image_save_path = output_file_path; - rocjpeg_util.GetOutputFileExt(output_format, base_file_name, widths[0], heights[0], image_save_path); - rocjpeg_util.SaveImage(image_save_path, output_image, widths[0], heights[0], subsampling, output_format); + rocjpeg_util.GetOutputFileExt(decode_params.output_format, base_file_name, widths[0], heights[0], image_save_path); + rocjpeg_util.SaveImage(image_save_path, output_image, widths[0], heights[0], subsampling, decode_params.output_format); } for (int i = 0; i < ROCJPEG_MAX_COMPONENT; i++) { @@ -121,7 +121,7 @@ int main(int argc, char **argv) { bool is_file = false; RocJpegChromaSubsampling subsampling; RocJpegBackend rocjpeg_backend = ROCJPEG_BACKEND_HARDWARE; - RocJpegOutputFormat output_format = ROCJPEG_OUTPUT_NATIVE; + RocJpegDecodeParams decode_params = {}; std::vector rocjpeg_handles; std::mutex mutex; std::vector num_decoded_images_per_thread; @@ -130,7 +130,7 @@ int main(int argc, char **argv) { RocJpegUtils rocjpeg_utils; std::vector threads; - RocJpegUtils::ParseCommandLine(input_path, output_file_path, save_images, device_id, rocjpeg_backend, output_format, &num_threads, argc, argv); + RocJpegUtils::ParseCommandLine(input_path, output_file_path, save_images, device_id, rocjpeg_backend, decode_params, &num_threads, 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; @@ -157,7 +157,7 @@ int main(int argc, char **argv) { 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_utils, &rocjpeg_images[i], std::ref(mutex), output_format, save_images, std::ref(output_file_path), + threads.emplace_back(ThreadFunction, std::ref(file_paths), rocjpeg_handles[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]); } for (auto& thread : threads) { diff --git a/samples/rocjpeg_samples_utils.h b/samples/rocjpeg_samples_utils.h index 029821564a..2164d0a898 100644 --- a/samples/rocjpeg_samples_utils.h +++ b/samples/rocjpeg_samples_utils.h @@ -58,7 +58,7 @@ class RocJpegUtils { public: RocJpegUtils() {}; static void ParseCommandLine(std::string &input_path, std::string &output_file_path, bool &save_images, int &device_id, - RocJpegBackend &rocjpeg_backend, RocJpegOutputFormat &output_format, int *num_threads, int argc, char *argv[]); + RocJpegBackend &rocjpeg_backend, RocJpegDecodeParams &decode_params, int *num_threads, int argc, char *argv[]); static bool GetFilePaths(std::string &input_path, std::vector &file_paths, bool &is_dir, bool &is_file); static bool InitHipDevice(int device_id); void GetChromaSubsamplingStr(RocJpegChromaSubsampling subsampling, std::string &chroma_sub_sampling); @@ -86,7 +86,7 @@ void RocJpegUtils::ShowHelpAndExit(const char *option, bool show_threads) { } void RocJpegUtils::ParseCommandLine(std::string &input_path, std::string &output_file_path, bool &save_images, int &device_id, - RocJpegBackend &rocjpeg_backend, RocJpegOutputFormat &output_format, int *num_threads, int argc, char *argv[]) { + RocJpegBackend &rocjpeg_backend, RocJpegDecodeParams &decode_params, int *num_threads, int argc, char *argv[]) { if(argc <= 1) { ShowHelpAndExit("", num_threads != nullptr); } @@ -129,15 +129,15 @@ void RocJpegUtils::ParseCommandLine(std::string &input_path, std::string &output } std::string selected_output_format = argv[i]; if (selected_output_format == "native") { - output_format = ROCJPEG_OUTPUT_NATIVE; + decode_params.output_format = ROCJPEG_OUTPUT_NATIVE; } else if (selected_output_format == "yuv") { - output_format = ROCJPEG_OUTPUT_YUV_PLANAR; + decode_params.output_format = ROCJPEG_OUTPUT_YUV_PLANAR; } else if (selected_output_format == "y") { - output_format = ROCJPEG_OUTPUT_Y; + decode_params.output_format = ROCJPEG_OUTPUT_Y; } else if (selected_output_format == "rgb") { - output_format = ROCJPEG_OUTPUT_RGB; + decode_params.output_format = ROCJPEG_OUTPUT_RGB; } else if (selected_output_format == "rgb_planar") { - output_format = ROCJPEG_OUTPUT_RGB_PLANAR; + decode_params.output_format = ROCJPEG_OUTPUT_RGB_PLANAR; } else { ShowHelpAndExit(argv[i], num_threads != nullptr); } diff --git a/src/rocjpeg_api.cpp b/src/rocjpeg_api.cpp index 267ba67e51..520798de10 100644 --- a/src/rocjpeg_api.cpp +++ b/src/rocjpeg_api.cpp @@ -80,7 +80,7 @@ RocJpegStatus ROCJPEGAPI rocJpegGetImageInfo(RocJpegHandle handle, const uint8_t } /*****************************************************************************************************/ -//! \fn RocJpegStatus ROCJPEGAPI rocJpegDecode(RocJpegHandle handle, const uint8_t *data, size_t length, RocJpegOutputFormat output_format, RocJpegImage *destination, hipStream_t stream); +//! \fn RocJpegStatus ROCJPEGAPI rocJpegDecode(RocJpegHandle handle, const uint8_t *data, size_t length, const RocJpegDecodeParams *decode_params, RocJpegImage *destination); //! \ingroup group_amd_rocjpeg //! Decodes single image based on the backend used to create the rocJpeg handle in rocJpegCreate API. //! Destination buffers should be large enough to be able to store output of specified format. These buffers should be pre-allocted by the user in the device memories. @@ -88,16 +88,16 @@ RocJpegStatus ROCJPEGAPI rocJpegGetImageInfo(RocJpegHandle handle, const uint8_t //! and minimum required memory buffer for each plane is plane_height * plane_pitch where plane_pitch >= plane_width for //! planar output formats and plane_pitch >= plane_width * num_components for interleaved output format. /*****************************************************************************************************/ -RocJpegStatus ROCJPEGAPI rocJpegDecode(RocJpegHandle handle, const uint8_t *data, size_t length, RocJpegOutputFormat output_format, +RocJpegStatus ROCJPEGAPI rocJpegDecode(RocJpegHandle handle, const uint8_t *data, size_t length, const RocJpegDecodeParams *decode_params, RocJpegImage *destination) { - if (handle == nullptr || data == nullptr) { + if (handle == nullptr || data == nullptr || decode_params == nullptr || destination == nullptr) { return ROCJPEG_STATUS_INVALID_PARAMETER; } RocJpegStatus rocjpeg_status = ROCJPEG_STATUS_SUCCESS; auto rocjpeg_handle = static_cast(handle); try { - rocjpeg_status = rocjpeg_handle->rocjpeg_decoder->Decode(data, length, output_format, destination); + rocjpeg_status = rocjpeg_handle->rocjpeg_decoder->Decode(data, length, decode_params, destination); } catch (const std::exception& e) { rocjpeg_handle->CaptureError(e.what()); ERR(e.what()); diff --git a/src/rocjpeg_decoder.cpp b/src/rocjpeg_decoder.cpp index a4fef891a5..4d87769ee8 100644 --- a/src/rocjpeg_decoder.cpp +++ b/src/rocjpeg_decoder.cpp @@ -67,7 +67,7 @@ RocJpegStatus ROCJpegDecoder::InitializeDecoder() { return rocjpeg_status; } -RocJpegStatus ROCJpegDecoder::Decode(const uint8_t *data, size_t length, RocJpegOutputFormat output_format, RocJpegImage *destination) { +RocJpegStatus ROCJpegDecoder::Decode(const uint8_t *data, size_t length, const RocJpegDecodeParams *decode_params, RocJpegImage *destination) { std::lock_guard lock(mutex_); RocJpegStatus rocjpeg_status = ROCJPEG_STATUS_SUCCESS; @@ -78,54 +78,53 @@ RocJpegStatus ROCJpegDecoder::Decode(const uint8_t *data, size_t length, RocJpeg const JpegStreamParameters *jpeg_stream_params = jpeg_parser_.GetJpegStreamParameters(); VASurfaceID current_surface_id; - CHECK_ROCJPEG(jpeg_vaapi_decoder_.SubmitDecode(jpeg_stream_params, current_surface_id, output_format)); + CHECK_ROCJPEG(jpeg_vaapi_decoder_.SubmitDecode(jpeg_stream_params, current_surface_id, decode_params->output_format)); - if (destination != nullptr) { - HipInteropDeviceMem hip_interop_dev_mem = {}; - CHECK_ROCJPEG(jpeg_vaapi_decoder_.SyncSurface(current_surface_id)); - CHECK_ROCJPEG(jpeg_vaapi_decoder_.GetHipInteropMem(current_surface_id, hip_interop_dev_mem)); + HipInteropDeviceMem hip_interop_dev_mem = {}; + CHECK_ROCJPEG(jpeg_vaapi_decoder_.SyncSurface(current_surface_id)); + CHECK_ROCJPEG(jpeg_vaapi_decoder_.GetHipInteropMem(current_surface_id, hip_interop_dev_mem)); - uint16_t chroma_height = 0; + uint16_t chroma_height = 0; - switch (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, jpeg_stream_params->picture_parameter_buffer.picture_height, chroma_height)); - // Copy Luma (first channel) for any surface format - CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, jpeg_stream_params->picture_parameter_buffer.picture_height, 0, destination)); - 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, destination)); - } else if (hip_interop_dev_mem.surface_format == VA_FOURCC_444P) { - // Copy the second and third channels for YUV444 - CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 1, destination)); - CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 2, destination)); - } - break; - case ROCJPEG_OUTPUT_YUV_PLANAR: - CHECK_ROCJPEG(GetChromaHeight(hip_interop_dev_mem.surface_format, jpeg_stream_params->picture_parameter_buffer.picture_height, chroma_height)); - CHECK_ROCJPEG(GetPlanarYUVOutputFormat(hip_interop_dev_mem, jpeg_stream_params->picture_parameter_buffer.picture_width, - jpeg_stream_params->picture_parameter_buffer.picture_height, chroma_height, destination)); - break; - case ROCJPEG_OUTPUT_Y: - CHECK_ROCJPEG(GetYOutputFormat(hip_interop_dev_mem, jpeg_stream_params->picture_parameter_buffer.picture_width, - jpeg_stream_params->picture_parameter_buffer.picture_height, destination)); - break; - case ROCJPEG_OUTPUT_RGB: - CHECK_ROCJPEG(ColorConvertToRGB(hip_interop_dev_mem, jpeg_stream_params->picture_parameter_buffer.picture_width, + switch (decode_params->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, jpeg_stream_params->picture_parameter_buffer.picture_height, chroma_height)); + // Copy Luma (first channel) for any surface format + CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, jpeg_stream_params->picture_parameter_buffer.picture_height, 0, destination)); + 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, destination)); + } else if (hip_interop_dev_mem.surface_format == VA_FOURCC_444P) { + // Copy the second and third channels for YUV444 + CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 1, destination)); + CHECK_ROCJPEG(CopyChannel(hip_interop_dev_mem, chroma_height, 2, destination)); + } + break; + case ROCJPEG_OUTPUT_YUV_PLANAR: + CHECK_ROCJPEG(GetChromaHeight(hip_interop_dev_mem.surface_format, jpeg_stream_params->picture_parameter_buffer.picture_height, chroma_height)); + CHECK_ROCJPEG(GetPlanarYUVOutputFormat(hip_interop_dev_mem, jpeg_stream_params->picture_parameter_buffer.picture_width, + jpeg_stream_params->picture_parameter_buffer.picture_height, chroma_height, destination)); + break; + case ROCJPEG_OUTPUT_Y: + CHECK_ROCJPEG(GetYOutputFormat(hip_interop_dev_mem, jpeg_stream_params->picture_parameter_buffer.picture_width, + jpeg_stream_params->picture_parameter_buffer.picture_height, destination)); + break; + case ROCJPEG_OUTPUT_RGB: + CHECK_ROCJPEG(ColorConvertToRGB(hip_interop_dev_mem, jpeg_stream_params->picture_parameter_buffer.picture_width, jpeg_stream_params->picture_parameter_buffer.picture_height, destination)); - break; - case ROCJPEG_OUTPUT_RGB_PLANAR: - CHECK_ROCJPEG(ColorConvertToRGBPlanar(hip_interop_dev_mem, jpeg_stream_params->picture_parameter_buffer.picture_width, + break; + case ROCJPEG_OUTPUT_RGB_PLANAR: + CHECK_ROCJPEG(ColorConvertToRGBPlanar(hip_interop_dev_mem, jpeg_stream_params->picture_parameter_buffer.picture_width, jpeg_stream_params->picture_parameter_buffer.picture_height, destination)); - break; - default: - break; - } - - CHECK_HIP(hipStreamSynchronize(hip_stream_)); + break; + default: + break; } + CHECK_HIP(hipStreamSynchronize(hip_stream_)); + + return ROCJPEG_STATUS_SUCCESS; } diff --git a/src/rocjpeg_decoder.h b/src/rocjpeg_decoder.h index a811701661..ce6265bae3 100644 --- a/src/rocjpeg_decoder.h +++ b/src/rocjpeg_decoder.h @@ -39,7 +39,7 @@ class ROCJpegDecoder { ~ROCJpegDecoder(); RocJpegStatus InitializeDecoder(); RocJpegStatus GetImageInfo(const uint8_t *data, size_t length, uint8_t *num_components, RocJpegChromaSubsampling *subsampling, uint32_t *widths, uint32_t *heights); - RocJpegStatus Decode(const uint8_t *data, size_t length, RocJpegOutputFormat output_format, RocJpegImage *destination); + RocJpegStatus Decode(const uint8_t *data, size_t length, const RocJpegDecodeParams *decode_params, RocJpegImage *destination); private: RocJpegStatus InitHIP(int device_id); RocJpegStatus GetChromaHeight(uint32_t surface_format, uint16_t picture_height, uint16_t &chroma_height);