diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 9e6678a..b3299fa 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -15,4 +15,4 @@ python: build: os: ubuntu-22.04 tools: - python: "3.8" + python: "3.10" diff --git a/README.md b/README.md index 63912b4..8478855 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,9 @@ rocJPEG is a high performance JPEG decode SDK for AMD GPUs. Using the rocJPEG API, you can access the JPEG decoding features available on your GPU. +>[!Note] +>The published documentation is available at [rocJPEG](https://rocm.docs.amd.com/projects/rocJPEG/en/latest/) in an organized, easy-to-read format, with search and a table of contents. The documentation source files reside in the `docs` folder of this repository. As with all ROCm projects, the documentation is open source. For more information on contributing to the documentation, see [Contribute to ROCm documentation](https://rocm.docs.amd.com/en/latest/contribute/contributing.html) + ## Supported JPEG chroma subsampling * YUV 4:4:4 @@ -15,7 +18,7 @@ rocJPEG is a high performance JPEG decode SDK for AMD GPUs. Using the rocJPEG AP ## Prerequisites * Linux distribution - * Ubuntu - `20.04` / `22.04` / `24.04` + * Ubuntu - `22.04` / `24.04` * RHEL - `8` / `9` * SLES - `15-SP5` @@ -29,26 +32,29 @@ rocJPEG is a high performance JPEG decode SDK for AMD GPUs. Using the rocJPEG AP > [!IMPORTANT] > `sudo amdgpu-install --usecase=rocm` -* Video Acceleration API (VA-API) Version `2.16.0+` - `Libva` is an implementation for VA-API - ```shell - sudo apt install libva-amdgpu-dev - ``` - > [!NOTE] - > RPM Packages for `RHEL`/`SLES` - `libva-amdgpu-devel` +* Video Acceleration API - `libva-amdgpu-dev` is an AMD implementation for VA-API + ```shell + sudo apt install libva-amdgpu-dev + ``` +> [!NOTE] +> * RPM Packages for `RHEL`/`SLES` - `libva-amdgpu-devel` +> * `libva-amdgpu` is strongly recommended over system `libva` as it is used for building mesa-amdgpu-va-driver * AMD VA Drivers - ```shell - sudo apt install libva2-amdgpu libva-amdgpu-drm2 libva-amdgpu-wayland2 libva-amdgpu-x11-2 mesa-amdgpu-va-drivers - ``` - > [!NOTE] - > RPM Packages for `RHEL`/`SLES` - `libva-amdgpu mesa-amdgpu-va-drivers` + ```shell + sudo apt install libva2-amdgpu libva-amdgpu-drm2 libva-amdgpu-wayland2 libva-amdgpu-x11-2 mesa-amdgpu-va-drivers + ``` +> [!NOTE] +> RPM Packages for `RHEL`/`SLES` - `libva-amdgpu mesa-amdgpu-va-drivers` -* CMake `3.5` or later +* CMake `3.10` or later ```shell sudo apt install cmake ``` - + +* AMD Clang++ Version 18.0.0 or later - installed with ROCm + * pkg-config ```shell @@ -67,7 +73,6 @@ rocJPEG is a high performance JPEG decode SDK for AMD GPUs. Using the rocJPEG AP >[!NOTE] > > * All package installs are shown with the `apt` package manager. Use the appropriate package manager for your operating system. -> * To install rocJPEG with minimum requirements, follow the [quick-start](./docs/install/quick-start.rst) instructions ### Prerequisites setup script for Linux @@ -90,7 +95,8 @@ The installation process uses the following steps: * Install ROCm `6.3.0` or later with [amdgpu-install](https://rocm.docs.amd.com/projects/install-on-linux/en/latest/how-to/amdgpu-install.html) with `--usecase=rocm` -* Use either [Package install](#package-install) or [Source install](#source-install) as described below. +>[!IMPORTANT] +> Use **either** [package install](#package-install) **or** [source install](#source-install) as described below. ### Package install @@ -188,16 +194,3 @@ individual folders to build and run the samples. You can find rocJPEG Docker containers in our [GitHub repository](https://github.com/ROCm/rocJPEG/tree/develop/docker). -## Documentation - -Run the following code to build our documentation locally. - -```shell -cd docs -pip3 install -r sphinx/requirements.txt -python3 -m sphinx -T -E -b html -d _build/doctrees -D language=en . _build/html -``` - -For more information on documentation builds, refer to the -[Building documentation](https://rocm.docs.amd.com/en/latest/contribute/building.html) -page. \ No newline at end of file diff --git a/docs/how-to/rocjpeg-decoding-a-jpeg-stream.rst b/docs/how-to/rocjpeg-decoding-a-jpeg-stream.rst new file mode 100644 index 0000000..2c4ae15 --- /dev/null +++ b/docs/how-to/rocjpeg-decoding-a-jpeg-stream.rst @@ -0,0 +1,151 @@ +.. meta:: + :description: decoding a jpeg stream with rocJPEG + :keywords: rocJPEG, ROCm, API, documentation, decoding, jpeg + + +******************************************************************** +Decoding a JPEG stream with rocJPEG +******************************************************************** + +rocJPEG provides two functions, ``rocJpegDecode()`` and ``rocJpegDecodeBatched()``, for decoding JPEG image. + +.. code:: cpp + + RocJpegStatus rocJpegDecode( + RocJpegHandle handle, + RocJpegStreamHandle jpeg_stream_handle, + const RocJpegDecodeParams *decode_params, + RocJpegImage *destination); + + RocJpegStatus rocJpegDecodeBatched( + RocJpegHandle handle, + RocJpegStreamHandle *jpeg_stream_handles, + int batch_size, + const RocJpegDecodeParams *decode_params, + RocJpegImage *destinations); + +``rocJpegDecode()`` is used for decoding single images and ``rocJpegDecodeBatched()`` is used for decoding batches of JPEG images. ``rocJpegDecode()`` and ``rocJpegDecodeBatched()`` copy decoded images to a ``RocJpegImage`` struct. + +.. code:: cpp + + typedef struct { + uint8_t* channel[ROCJPEG_MAX_COMPONENT]; + uint32_t pitch[ROCJPEG_MAX_COMPONENT]; + } RocJpegImage; + +``rocJpegDecodeBatched()`` behaves the same way as ``rocJpegDecode()`` except that ``rocJpegDecodeBatched()`` takes an array of stream handles and an array of decode parameters as input, decodes the batch of JPEG images, and stores the decoded images in an output array of destination images. + +``rocJpegDecodeBatched()`` is suited for use on ASICs with multiple JPEG cores and is more efficient than multiple calls to ``rocJpegDecode()``. Choosing a batch size that is a multiple of available JPEG cores is recommended. + +Memory has to be allocate to each channel of ``RocJpegImage``, including every channel of every ``RocJpegImage`` in the destination image array passed to ``rocJpegDecodeBatched()``. Use |hipmalloc|_ to allocate memory. + +.. |hipmalloc| replace:: ``hipMalloc()`` +.. _hipmalloc: https://rocm.docs.amd.com/projects/HIP/en/latest/how-to/virtual_memory.html + +For example: + +.. code:: cpp + + // Allocate device memory for the decoded output image + RocJpegImage output_image = {}; + RocJpegDecodeParams decode_params = {}; + decode_params.output_format = ROCJPEG_OUTPUT_NATIVE; + + // For this sample assuming the input image has a YUV420 chroma subsampling. + // For YUV420 subsampling, the native decoded output image would be NV12 (i.e., the rocJPegDecode API copies Y to first channel and UV (interleaved) to second channel of RocJpegImage) + output_image.pitch[1] = output_image.pitch[0] = widths[0]; + hipError_t hip_status; + hip_status = hipMalloc(&output_image.channel[0], output_image.pitch[0] * heights[0]); + if (hip_status != hipSuccess) { + std::cerr << "Failed to allocate device memory for the first channel" << std::endl; + rocJpegStreamDestroy(rocjpeg_stream_handle); + rocJpegDestroy(handle); + return EXIT_FAILURE; + } + + hip_status = hipMalloc(&output_image.channel[1], output_image.pitch[1] * (heights[0] >> 1)); + if (hip_status != hipSuccess) { + std::cerr << "Failed to allocate device memory for the second channel" << std::endl; + hipFree((void *)output_image.channel[0]); + rocJpegStreamDestroy(rocjpeg_stream_handle); + rocJpegDestroy(handle); + return EXIT_FAILURE; + } + + // Decode the JPEG stream + status = rocJpegDecode(handle, rocjpeg_stream_handle, &decode_params, &output_image); + if (status != ROCJPEG_STATUS_SUCCESS) { + std::cerr << "Failed to decode JPEG stream with error code: " << rocJpegGetErrorName(status) << std::endl; + hipFree((void *)output_image.channel[0]); + hipFree((void *)output_image.channel[1]); + rocJpegStreamDestroy(rocjpeg_stream_handle); + rocJpegDestroy(handle); + return EXIT_FAILURE; + } + + +The behaviors of ``rocJpegDecode()`` and ``rocJpegDecodeBatched()`` depend on ``RocJpegOutputFormat`` and ``RocJpegDecodeParms``. + +``RocJpegOutputFormat`` specifies the output format to be used to decode the JPEG image. It can be set to any one of these output formats: + +.. csv-table:: + :header: "Output format", "Meaning" + + "ROCJPEG_OUTPUT_NATIVE", "Return native unchanged decoded YUV image from the VCN JPEG deocder." + "ROCJPEG_OUTPUT_YUV_PLANAR", "Return in the YUV planar format." + "ROCJPEG_OUTPUT_Y", "Return the Y component only." + "ROCJPEG_OUTPUT_RGB", "Convert to interleaved RGB." + "ROCJPEG_OUTPUT_RGB_PLANAR", "Convert to planar RGB." + +``RocJpegOutputFormat`` is a member of the ``RocJpegDecodeParams`` struct. ``RocJpegDecodeParams`` defines the output format, crop rectangle, and target dimensions to use when decoding the image. + +.. code:: cpp + + typedef struct { + RocJpegOutputFormat output_format; /**< Output data format. See RocJpegOutputFormat for description. */ + struct { + int16_t left; /**< Left coordinate of the crop rectangle. */ + int16_t top; /**< Top coordinate of the crop rectangle. */ + int16_t right; /**< Right coordinate of the crop rectangle. */ + int16_t bottom; /**< Bottom coordinate of the crop rectangle. */ + } crop_rectangle; /**< Defines the region of interest (ROI) to be copied into the RocJpegImage output buffers. */ + struct { + uint32_t width; /**< Target width of the picture to be resized. */ + uint32_t height; /**< Target height of the picture to be resized. */ + } 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; + + +For example, consider a situation where ``RocJpegOutputFormat`` is set to ``ROCJPEG_OUTPUT_NATIVE``. Based on the chroma subsampling of the input image, ``rocJpegDecode()`` does one of the following: + +* For ``ROCJPEG_CSS_444`` and ``ROCJPEG_CSS_440``: writes Y, U, and V to the first, second, and third channels of ``RocJpegImage``. +* For ``ROCJPEG_CSS_422``: writes YUYV (packed) to the first channel of ``RocJpegImage``. +* For ``ROCJPEG_CSS_420``: writes Y to the first channel and UV (interleaved) to the second channel of ``RocJpegImage``. +* For ``ROCJPEG_CSS_400``: writes Y to the first channel of ``RocJpegImage``. + +If ``RocJpegOutputFormat`` is set to ``ROCJPEG_OUTPUT_Y`` or ``ROCJPEG_OUTPUT_RGB``, then ``rocJpegDecode()`` copies the output to the first channel of ``RocJpegImage``. + +If ``RocJpegOutputFormat`` is set to ``ROCJPEG_OUTPUT_YUV_PLANAR`` or ``ROCJPEG_OUTPUT_RGB_PLANAR``, the data is written to the corresponding channels of the ``RocJpegImage`` destination structure. + +The destination images must be large enough to store the output. + +Use |rocjpegimageinfo|_ to extract information and calculate the required memory sizes for the destination image following these guidelines:. + +.. |rocjpegimageinfo| replace:: ``rocJpegGetImageInfo()`` +.. _rocjpegimageinfo: ./rocjpeg-retrieve-image-info.html + +.. csv-table:: + :header: "Output format", "Chroma subsampling", "Minimum size of destination.pitch[c]", "Minimum size of destination.channel[c]" + + "ROCJPEG_OUTPUT_NATIVE", "ROCJPEG_CSS_444", "destination.pitch[c] = widths[c] for c = 0, 1, 2", "destination.channel[c] = destination.pitch[c] * heights[0] for c = 0, 1, 2" + "ROCJPEG_OUTPUT_NATIVE", "ROCJPEG_CSS_440", "destination.pitch[c] = widths[c] for c = 0, 1, 2", "destination.channel[0] = destination.pitch[0] * heights[0], destination.channel[c] = destination.pitch[c] * heights[0] / 2 for c = 1, 2" + "ROCJPEG_OUTPUT_NATIVE", "ROCJPEG_CSS_422", "destination.pitch[0] = widths[0] * 2", "destination.channel[0] = destination.pitch[0] * heights[0]" + "ROCJPEG_OUTPUT_NATIVE", "ROCJPEG_CSS_420", "destination.pitch[1] = destination.pitch[0] = widths[0]", "destination.channel[0] = destination.pitch[0] * heights[0], destination.channel[1] = destination.pitch[1] * (heights[0] >> 1)" + "ROCJPEG_OUTPUT_NATIVE", "ROCJPEG_CSS_400", "destination.pitch[0] = widths[0]", "destination.channel[0] = destination.pitch[0] * heights[0]" + "ROCJPEG_OUTPUT_YUV_PLANAR", "ROCJPEG_CSS_444, ROCJPEG_CSS_440, ROCJPEG_CSS_422, ROCJPEG_CSS_420", "destination.pitch[c] = widths[c] for c = 0, 1, 2", "destination.channel[c] = destination.pitch[c] * heights[c] for c = 0, 1, 2" + "ROCJPEG_OUTPUT_YUV_PLANAR", "ROCJPEG_CSS_400", "destination.pitch[0] = widths[0]", "destination.channel[0] = destination.pitch[0] * heights[0]" + "ROCJPEG_OUTPUT_Y", "Any of the supported chroma subsampling", "destination.pitch[0] = widths[0]", "destination.channel[0] = destination.pitch[0] * heights[0]" + "ROCJPEG_OUTPUT_RGB", "Any of the supported chroma subsampling", "destination.pitch[0] = widths[0] * 3", "destination.channel[0] = destination.pitch[0] * heights[0]" + "ROCJPEG_OUTPUT_RGB_PLANAR", "Any of the supported chroma subsampling", "destination.pitch[c] = widths[c] for c = 0, 1, 2", "destination.channel[c] = destination.pitch[c] * heights[c] for c = 0, 1, 2" + diff --git a/docs/how-to/rocjpeg-retrieve-image-info.rst b/docs/how-to/rocjpeg-retrieve-image-info.rst new file mode 100644 index 0000000..91ce9ea --- /dev/null +++ b/docs/how-to/rocjpeg-retrieve-image-info.rst @@ -0,0 +1,63 @@ +.. meta:: + :description: retrieving image information with rocJPEG + :keywords: rocJPEG, ROCm, API, documentation, image information, jpeg + + +******************************************************************** +Retrieving image information with rocJPEG +******************************************************************** + +Retrieving image information is done using ``rocJpegGetImageInfo()``. + +.. code:: cpp + + RocJpegStatus rocJpegGetImageInfo( + RocJpegHandle handle, + RocJpegStreamHandle jpeg_stream_handle, + uint8_t *num_components, + RocJpegChromaSubsampling *subsampling, + uint32_t *widths, + uint32_t *heights); + +``rocJpegGetImageInfo()`` takes the ``RocJpegHandle`` and a ``RocJpegStreamHandle`` as inputs, and returns the subsampling, number of components, and widths and heights of the components. These are passed to the ``subsampling``, ``num_components``, and ``widths`` and ``heights`` output parameters. + +The ``subsampling`` output parameter is a ``RocJpegChromaSubsampling`` enum. + +.. code:: cpp + + typedef enum { + ROCJPEG_CSS_444 = 0, + ROCJPEG_CSS_440 = 1, + ROCJPEG_CSS_422 = 2, + ROCJPEG_CSS_420 = 3, + ROCJPEG_CSS_411 = 4, + ROCJPEG_CSS_400 = 5, + ROCJPEG_CSS_UNKNOWN = -1 + } RocJpegChromaSubsampling; + +Its value is set to the chroma subsampling retrieved from the image. + +For example: + +.. code:: cpp + + // Get the image info + uint8_t num_components; + RocJpegChromaSubsampling subsampling; + uint32_t widths[ROCJPEG_MAX_COMPONENT] = {}; + uint32_t heights[ROCJPEG_MAX_COMPONENT] = {}; + + status = rocJpegGetImageInfo(handle, rocjpeg_stream_handle, &num_components, &subsampling, widths, heights); + if (status != ROCJPEG_STATUS_SUCCESS) { + std::cerr << "Failed to get image info with error code: " << rocJpegGetErrorName(status) << std::endl; + rocJpegStreamDestroy(rocjpeg_stream_handle); + rocJpegDestroy(handle); + return EXIT_FAILURE; + } + + +``rocJpegGetImageInfo()`` is thread safe. + +.. note:: + + The VCN hardware-accelerated JPEG decoder in AMD GPUs only supports decoding JPEG images with ``ROCJPEG_CSS_444``, ``ROCJPEG_CSS_440``, ``ROCJPEG_CSS_422``, ``ROCJPEG_CSS_420``, and ``ROCJPEG_CSS_400`` chroma subsampling. diff --git a/docs/how-to/using-rocjpeg.rst b/docs/how-to/using-rocjpeg.rst index 01ab294..cd27a5e 100644 --- a/docs/how-to/using-rocjpeg.rst +++ b/docs/how-to/using-rocjpeg.rst @@ -6,20 +6,14 @@ Using rocJPEG ******************************************************************** -To learn how to use the rocJPEG SDK library, follow these instructions: +This document provides a high-level overview of how to do common operations using the rocJPEG APIs exposed in the ``rocjpeg.h`` header file. -1. API overview -==================================================== +Creating handles +================== -All rocJPEG APIs are exposed in the header file ``rocjpeg.h``. You can find -this file in the `api` folder in the rocJPEG repository. +Handles need to be created to decode and parse JPEG streams. -2. Create a decoder -==================================================== - -The ``rocJpegCreate()`` function creates a JPEG decoder object and returns a handle upon successful creation. - -Below is the signature of ``rocJpegCreate()`` function: +``rocJpegCreate()`` returns an instance of a ``RocJpegHandle`` based on the specified backend and GPU device ID. The ``RocJpegHandle`` instance must be retained for the entire decode session. .. code:: cpp @@ -28,53 +22,87 @@ Below is the signature of ``rocJpegCreate()`` function: int device_id, RocJpegHandle *handle); -The API takes in the following arguments: -* A ``RocJpegBackend`` type, which specifies the backend to use for creating a decoder handle. - Currently, the rocJPEG library only supports ``ROCJPEG_BACKEND_HARDWARE``, which creates a decoder - for baseline JPEG bitstream using VCN hardware-accelerated JPEG decoder in AMD GPUs. -* The GPU device ID for which a decoder should be created. The GPU device ID is a zero-based index, where 0 is for the first GPU on a system. -* A decoder handle, which is returned by ``rocJpegCreate()`` and must be retained for the entire decode session, - as it is passed along with the other decoding APIs. +``rocJpegStreamCreate()`` returns a ``rocJpegStreamHandle``, which is a pointer used to represent an instance of a JPEG stream. The instance of ``rocJpegStreamHandle`` is used to parse the JPEG stream and to store the JPEG stream parameters. -3. Create a JPEG stream parser -==================================================== +.. code:: cpp -The ``rocJpegStreamCreate`` function creates a JPEG stream parser object and returns a handle upon successful creation. This handle is used to parse and retrieve the information from the JPEG stream. + RocJpegStatus rocJpegStreamCreate(RocJpegStreamHandle *jpeg_stream_handle); -Below is the signature of the ``rocJpegStreamCreate`` function: +For example: .. code:: cpp - RocJpegStatus rocJpegStreamCreate(RocJpegStreamHandle *jpeg_stream_handle); + // Read the JPEG image file + std::ifstream input("mug_420.jpg", std::ios::in | std::ios::binary | std::ios::ate); + + // Get the JPEG image file size + std::streamsize file_size = input.tellg(); + input.seekg(0, std::ios::beg); + + std::vector file_data; + // resize if buffer is too small + if (file_data.size() < file_size) { + file_data.resize(file_size); + } + // Read the JPEG stream + if (!input.read(file_data.data(), file_size)) { + std::cerr << "ERROR: cannot read from file: " << std::endl; + return EXIT_FAILURE; + } + + // Initialize rocJPEG + RocJpegHandle handle; + RocJpegStatus status = rocJpegCreate(ROCJPEG_BACKEND_HARDWARE, 0, &handle); + if (status != ROCJPEG_STATUS_SUCCESS) { + std::cerr << "Failed to create rocJPEG handle with error code: " << rocJpegGetErrorName(status) << std::endl; + return EXIT_FAILURE; + } + + // Create a JPEG stream + RocJpegStreamHandle rocjpeg_stream_handle; + status = rocJpegStreamCreate(&rocjpeg_stream_handle); + if (status != ROCJPEG_STATUS_SUCCESS) { + std::cerr << "Failed to create JPEG stream with error code: " << rocJpegGetErrorName(status) << std::endl; + rocJpegDestroy(handle); + return EXIT_FAILURE; + } -The API takes in the following arguments: +``rocJpegGetErrorName()`` returns error codes in text format from rocJPEG APIs. -* A JPEG stream handle, which is returned by ``rocJpegStreamCreate``. This handle can be used by the user to parse the JPEG stream and retrieve the information from the stream. -4. Parse a JPEG stream and store its information -==================================================== +Parsing a stream +================= -The ``rocJpegStreamParse`` function parses a jpeg stream and stores the information from the stream to be used in subsequent API calls for retrieving the image information and decoding it. +``rocJpegStreamParse()`` is used to parse a JPEG stream. -Below is the signature of the ``rocJpegStreamParse`` function: +The stream data buffer is passed through the ``data`` input parameter. The length of the buffer is passed through the ``length`` input parameter. The parsed stream is returned through the ``jpeg_stream_handle`` provided. ``jpeg_stream_handle`` must have already been created with ``rocJpegStreamCreate()``. .. code:: cpp - RocJpegStatus rocJpegStreamParse(const unsigned char *data, size_t length, RocJpegStreamHandle jpeg_stream_handle); + RocJpegStatus rocJpegStreamParse(const unsigned char *data, + size_t length, + RocJpegStreamHandle jpeg_stream_handle); -The API takes in the following arguments: -* A pointer to the JPEG data buffer. -* The length of the JPEG data buffer. -* The JPEG stream handle, which is returned by ``rocJpegStreamCreate``. This handle is used to parse the JPEG stream and retrieve the information from the stream. +For example: -5. Retrieve the image info -==================================================== -``rocJpegGetImageInfo()`` retrieves the image info, including number of components, width and height of each component, and chroma subsampling. -For each image to be decoded, pass the JPEG data pointer and data length to the ``rocJpegGetImageInfo()`` function. This function is thread safe. +.. code:: cpp + + // Parse the JPEG stream + status = rocJpegStreamParse(reinterpret_cast(file_data.data()), file_size, rocjpeg_stream_handle); + if (status != ROCJPEG_STATUS_SUCCESS) { + std::cerr << "Failed to parse JPEG stream with error code: " << rocJpegGetErrorName(status) << std::endl; + rocJpegStreamDestroy(rocjpeg_stream_handle); + rocJpegDestroy(handle); + return EXIT_FAILURE; + } + + +Getting image information +=========================== -Below is the signature of ``rocJpegGetImageInfo()`` function: +``rocJpegGetImageInfo()`` is used to retrieve the number of components, the chroma subsampling, and the width and height of the JPEG image. .. code:: cpp @@ -86,32 +114,15 @@ Below is the signature of ``rocJpegGetImageInfo()`` function: uint32_t *widths, uint32_t *heights); -One of the outputs of the ``rocJpegGetImageInfo()`` function is ``RocJpegChromaSubsampling``. This parameter is an enum type, and its enumerator -list is composed of the chroma subsampling property retrieved from the JPEG image. See the ``RocJpegChromaSubsampling`` enum below. -.. code:: cpp - - typedef enum { - ROCJPEG_CSS_444 = 0, - ROCJPEG_CSS_440 = 1, - ROCJPEG_CSS_422 = 2, - ROCJPEG_CSS_420 = 3, - ROCJPEG_CSS_411 = 4, - ROCJPEG_CSS_400 = 5, - ROCJPEG_CSS_UNKNOWN = -1 - } RocJpegChromaSubsampling; - -.. note:: +For more information on ``rocJpegGetImageInfo()``, see `Retrieving image information with rocJPEG <./rocjpeg-retrieve-image-info.html>`_. - The VCN hardware-accelerated JPEG decoder in AMD GPUs only supports decoding JPEG images with ``ROCJPEG_CSS_444``, ``ROCJPEG_CSS_440``, ``ROCJPEG_CSS_422``, - ``ROCJPEG_CSS_420``, and ``ROCJPEG_CSS_400`` chroma subsampling. +Decoding a stream +==================== -6. Decode a JPEG stream -==================================================== -``rocJpegDecode()`` decodes single image based on the backend used to create the rocJpeg handle in rocJpegCreate API. For each image to be decoded, -pass the JPEG data pointer and data length to the ``rocJpegDecode()`` function. This function is thread safe. +``rocJpegDecode()`` takes the image passed to it through the ``jpeg_stream_handle`` input parameter and decodes it based on the backend used to create ``handle`` input parameter. -See the signature of this function below: +The ``decode_params`` input parameter is used to specify the decoding parameters. Memory needs to be allocated for each channel of the destination image. .. code:: cpp @@ -121,436 +132,32 @@ See the signature of this function below: const RocJpegDecodeParams *decode_params, RocJpegImage *destination); -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`` -defined in the ``RocJpegDecodeParams``. -Below is the ``RocJpegImage`` structure. - -.. code:: cpp - - typedef struct { - uint8_t* channel[ROCJPEG_MAX_COMPONENT]; - uint32_t pitch[ROCJPEG_MAX_COMPONENT]; - } RocJpegImage; +For more information on decoding streams, see `Decoding a JPEG stream with rocJPEG <./rocjpeg-decoding-a-jpeg-stream.html>`_. -You can set the ``RocJpegOutputFormat`` parameter of the ``RocJpegDecodeParams`` to one of the ``output_format`` settings below: -.. csv-table:: - :header: "output_format", "Meaning" +Destroying handles and freeing resources +========================================== - "ROCJPEG_OUTPUT_NATIVE", "Return native unchanged decoded YUV image from the VCN JPEG deocder." - "ROCJPEG_OUTPUT_YUV_PLANAR", "Return in the YUV planar format." - "ROCJPEG_OUTPUT_Y", "Return the Y component only." - "ROCJPEG_OUTPUT_RGB", "Convert to interleaved RGB." - "ROCJPEG_OUTPUT_RGB_PLANAR", "Convert to planar RGB." +Once the JPEG stream is decoded, resources need to be freed. -For example, if ``output_format`` is set to ``ROCJPEG_OUTPUT_NATIVE``, then based on the chroma subsampling of the input image, the -``rocJpegDecode()`` function does one of the following: +Use |hipfree|_ to release the memory previously allocated by ``hipMalloc()`` for each channel of the destination ``rocJpegImage``. -* For ``ROCJPEG_CSS_444`` and ``ROCJPEG_CSS_440`` write Y, U, and V to first, second, and third channels of ``RocJpegImage``. -* For ``ROCJPEG_CSS_422`` write YUYV (packed) to first channel of ``RocJpegImage``. -* For ``ROCJPEG_CSS_420`` write Y to first channel and UV (interleaved) to second channel of ``RocJpegImage``. -* For ``ROCJPEG_CSS_400`` write Y to first channel of ``RocJpegImage``. +.. |hipfree| replace:: ``hipFree()`` +.. _hipfree: https://rocm.docs.amd.com/projects/HIP/en/latest/how-to/virtual_memory.html -if ``output_format`` is set to ``ROCJPEG_OUTPUT_Y`` or ``ROCJPEG_OUTPUT_RGB`` then ``rocJpegDecode()`` copies the output to first channel of ``RocJpegImage``. -Alternately, in the case of ``ROCJPEG_OUTPUT_YUV_PLANAR`` or ``ROCJPEG_OUTPUT_RGB_PLANAR``, the data is written to the corresponding channels of the ``RocJpegImage`` destination structure. -The destination buffers should be large enough to be able to store output of specified format. These buffers should be -pre-allocated by the user in the device memories. For each color plane (channel), sizes could be retrieved for image using -``rocJpegGetImageInfo()`` API 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. - -As mentioned above, you can use the retrieved parameters, ``num_components``, ``subsampling``, ``widths``, and ``heights`` from the ``rocJpegGetImageInfo()`` API to calculate -the required size for the output buffers for a single decode JPEG. To optimally set the destination parameter for the ``rocJpegDecode()`` function, use the following guidelines: - -.. csv-table:: - :header: "output_format", "chroma subsampling", "destination.pitch[c] should be atleast:", "destination.channel[c] should be atleast:" - - "ROCJPEG_OUTPUT_NATIVE", "ROCJPEG_CSS_444", "destination.pitch[c] = widths[c] for c = 0, 1, 2", "destination.channel[c] = destination.pitch[c] * heights[0] for c = 0, 1, 2" - "ROCJPEG_OUTPUT_NATIVE", "ROCJPEG_CSS_440", "destination.pitch[c] = widths[c] for c = 0, 1, 2", "destination.channel[0] = destination.pitch[0] * heights[0], destination.channel[c] = destination.pitch[c] * heights[0] / 2 for c = 1, 2" - "ROCJPEG_OUTPUT_NATIVE", "ROCJPEG_CSS_422", "destination.pitch[0] = widths[0] * 2", "destination.channel[0] = destination.pitch[0] * heights[0]" - "ROCJPEG_OUTPUT_NATIVE", "ROCJPEG_CSS_420", "destination.pitch[1] = destination.pitch[0] = widths[0]", "destination.channel[0] = destination.pitch[0] * heights[0], destination.channel[1] = destination.pitch[1] * (heights[0] >> 1)" - "ROCJPEG_OUTPUT_NATIVE", "ROCJPEG_CSS_400", "destination.pitch[0] = widths[0]", "destination.channel[0] = destination.pitch[0] * heights[0]" - "ROCJPEG_OUTPUT_YUV_PLANAR", "ROCJPEG_CSS_444, ROCJPEG_CSS_440, ROCJPEG_CSS_422, ROCJPEG_CSS_420", "destination.pitch[c] = widths[c] for c = 0, 1, 2", "destination.channel[c] = destination.pitch[c] * heights[c] for c = 0, 1, 2" - "ROCJPEG_OUTPUT_YUV_PLANAR", "ROCJPEG_CSS_400", "destination.pitch[0] = widths[0]", "destination.channel[0] = destination.pitch[0] * heights[0]" - "ROCJPEG_OUTPUT_Y", "Any of the supported chroma subsampling", "destination.pitch[0] = widths[0]", "destination.channel[0] = destination.pitch[0] * heights[0]" - "ROCJPEG_OUTPUT_RGB", "Any of the supported chroma subsampling", "destination.pitch[0] = widths[0] * 3", "destination.channel[0] = destination.pitch[0] * heights[0]" - "ROCJPEG_OUTPUT_RGB_PLANAR", "Any of the supported chroma subsampling", "destination.pitch[c] = widths[c] for c = 0, 1, 2", "destination.channel[c] = destination.pitch[c] * heights[c] for c = 0, 1, 2" - -7. Decode a batch of JPEG streams -==================================================== -The ``rocJpegDecodeBatched()`` function decodes a batch of JPEG images using the rocJPEG library. - -Below is the signature of the ``rocJpegDecodeBatched()`` function: - -.. code:: cpp - - RocJpegStatus rocJpegDecodeBatched( - RocJpegHandle handle, - RocJpegStreamHandle *jpeg_stream_handles, - int batch_size, - const RocJpegDecodeParams *decode_params, - RocJpegImage *destinations); - -The ``rocJpegDecodeBatched()`` function takes the following arguments: - -* ``handle``: The rocJPEG handle. -* ``jpeg_stream_handles``: An array of rocJPEG stream handles, each representing a JPEG image. -* ``batch_size``: The number of images in the batch. -* ``decode_params``: The decode parameters for the JPEG images. -* ``destinations``: An array of rocJPEG images to store the decoded images. - -To use the ``rocJpegDecodeBatched()`` function, you need to provide the appropriate rocJPEG handles, stream handles, decode parameters, and destination images. The function will decode the batch of JPEG images and store the decoded images in the ``destinations`` array. -Remember to allocate device memories for each channel of the destination images and pass them to the ``rocJpegDecodeBatched()`` API. The API will then copy the decoded images to the destination images based on the requested output format specified in the ``RocJpegDecodeParams``. - -The ``rocJpegDecodeBatched()`` function provides optimal performance on ASICs with multiple JPEG cores, such as the MI300 series. It efficiently submits a batch of JPEG streams for decoding based on the available JPEG cores, resulting in better performance compared -to the single JPEG decode API ``rocJpegDecode``. To achieve the best performance, it is recommended to choose a batch size that is a multiple of the available JPEG cores. For example, the MI300X -has 32 independent JPEG cores, so a batch size that is a multiple of 32 will provide optimal performance. - -8. Destroy the decoder -==================================================== - -You must call the ``rocJpegDestroy()`` to destroy the session and free up resources. - -9. Destroy the JPEG stream handle -==================================================== - -You must call the ``rocJpegStreamDestroy()`` to release the stream parser object and resources. - -10. Get Error name -==================================================== - -You can call ``rocJpegGetErrorName`` to retrieve the name of the specified error code in text form returned from rocJPEG APIs. - -11. Sample code snippet for decoding a JPEG stream using the rocJPEG APIs -==================================================== - -The code snippet provided demonstrates how to decode a JPEG stream using the rocJPEG library. -First, the code reads the JPEG image file and stores the data in a vector. Then, it initializes the rocJPEG handle using the ``rocJpegCreate()`` function. If the handle creation is successful, it proceeds to create a JPEG stream using the ``rocJpegStreamCreate()`` function. -Next, the code parses the JPEG stream by calling the ``rocJpegStreamParse()`` function with the JPEG data and its size. If the parsing is successful, it retrieves the image information using the ``rocJpegGetImageInfo()`` function. -After obtaining the image information, the code allocates HIP device memory for the decoded image using the ``RocJpegImage`` structure. It sets the channel and pitch values based on the image width and height. -Finally, the code decodes the JPEG stream by calling the ``rocJpegDecode()`` function with the rocJPEG handle, stream handle, and the decoded image structure. If the decoding is successful, the decoded image can be further processed or displayed. +Use ``rocJpegStreamDestroy()`` to release the ``rocJpegStreamHandle`` and its resources, and use ``rocJPegDestroy()`` to release ``RocJpegHandle`` and destroy the session. .. code:: cpp - #include - #include - #include - #include "rocjpeg.h" - - int main() { - // Read the JPEG image file - std::ifstream input("mug_420.jpg", std::ios::in | std::ios::binary | std::ios::ate); - - // Get the JPEG image file size - std::streamsize file_size = input.tellg(); - input.seekg(0, std::ios::beg); - - std::vector file_data; - // resize if buffer is too small - if (file_data.size() < file_size) { - file_data.resize(file_size); - } - // Read the JPEG stream - if (!input.read(file_data.data(), file_size)) { - std::cerr << "ERROR: cannot read from file: " << std::endl; - return EXIT_FAILURE; - } - - // Initialize rocJPEG - RocJpegHandle handle; - RocJpegStatus status = rocJpegCreate(ROCJPEG_BACKEND_HARDWARE, 0, &handle); - if (status != ROCJPEG_STATUS_SUCCESS) { - std::cerr << "Failed to create rocJPEG handle with error code: " << rocJpegGetErrorName(status) << std::endl; - return EXIT_FAILURE; - } - - // Create a JPEG stream - RocJpegStreamHandle rocjpeg_stream_handle; - status = rocJpegStreamCreate(&rocjpeg_stream_handle); - if (status != ROCJPEG_STATUS_SUCCESS) { - std::cerr << "Failed to create JPEG stream with error code: " << rocJpegGetErrorName(status) << std::endl; - rocJpegDestroy(handle); - return EXIT_FAILURE; - } - - // Parse the JPEG stream - status = rocJpegStreamParse(reinterpret_cast(file_data.data()), file_size, rocjpeg_stream_handle); - if (status != ROCJPEG_STATUS_SUCCESS) { - std::cerr << "Failed to parse JPEG stream with error code: " << rocJpegGetErrorName(status) << std::endl; - rocJpegStreamDestroy(rocjpeg_stream_handle); - rocJpegDestroy(handle); - return EXIT_FAILURE; - } - - // Get the image info - uint8_t num_components; - RocJpegChromaSubsampling subsampling; - uint32_t widths[ROCJPEG_MAX_COMPONENT] = {}; - uint32_t heights[ROCJPEG_MAX_COMPONENT] = {}; - - status = rocJpegGetImageInfo(handle, rocjpeg_stream_handle, &num_components, &subsampling, widths, heights); - if (status != ROCJPEG_STATUS_SUCCESS) { - std::cerr << "Failed to get image info with error code: " << rocJpegGetErrorName(status) << std::endl; - rocJpegStreamDestroy(rocjpeg_stream_handle); - rocJpegDestroy(handle); - return EXIT_FAILURE; - } - - // Allocate device memory for the decoded output image - RocJpegImage output_image = {}; - RocJpegDecodeParams decode_params = {}; - decode_params.output_format = ROCJPEG_OUTPUT_NATIVE; - - // For this sample assuming the input image has a YUV420 chroma subsampling. - // For YUV420 subsampling, the native decoded output image would be NV12 (i.e., the rocJPegDecode API copies Y to first channel and UV (interleaved) to second channel of RocJpegImage) - output_image.pitch[1] = output_image.pitch[0] = widths[0]; - hipError_t hip_status; - hip_status = hipMalloc(&output_image.channel[0], output_image.pitch[0] * heights[0]); - if (hip_status != hipSuccess) { - std::cerr << "Failed to allocate device memory for the first channel" << std::endl; - rocJpegStreamDestroy(rocjpeg_stream_handle); - rocJpegDestroy(handle); - return EXIT_FAILURE; - } - - hip_status = hipMalloc(&output_image.channel[1], output_image.pitch[1] * (heights[0] >> 1)); - if (hip_status != hipSuccess) { - std::cerr << "Failed to allocate device memory for the second channel" << std::endl; - hipFree((void *)output_image.channel[0]); - rocJpegStreamDestroy(rocjpeg_stream_handle); - rocJpegDestroy(handle); - return EXIT_FAILURE; - } - - // Decode the JPEG stream - status = rocJpegDecode(handle, rocjpeg_stream_handle, &decode_params, &output_image); - if (status != ROCJPEG_STATUS_SUCCESS) { - std::cerr << "Failed to decode JPEG stream with error code: " << rocJpegGetErrorName(status) << std::endl; - hipFree((void *)output_image.channel[0]); - hipFree((void *)output_image.channel[1]); - rocJpegStreamDestroy(rocjpeg_stream_handle); - rocJpegDestroy(handle); - return EXIT_FAILURE; - } - - // Perform additional post-processing on the decoded image or optionally save it - // ... - - // Clean up resources - hipFree((void *)output_image.channel[0]); - hipFree((void *)output_image.channel[1]); - rocJpegStreamDestroy(rocjpeg_stream_handle); - rocJpegDestroy(handle); - - return EXIT_SUCCESS; - } + RocJpegStatus rocJpegStreamDestroy(RocJpegStreamHandle jpeg_stream_handle) -12. Sample code snippet for decoding a batch of JPEG streams using the rocJPEG APIs -==================================================== + RocJpegStatus rocJpegDestroy(RocJpegHandle handle) -The code snippet provided demonstrates how to decode a batch of JPEG streams using the rocJPEG library. +For example: .. code:: cpp - - #include - #include - #include - #include - #include "rocjpeg.h" - - int main() { - // the input path of a folder containing JPEG files - // note: replace the "path_to_a_folder_of_JPEG_files" with an actual path of a folder - std::string input_path = "path_to_a_folder_of_JPEG_files"; - - // vector of string to store the paths of the JPEG files - std::vector file_paths = {}; - - if (std::filesystem::is_directory(input_path)) { - for (const auto &entry : std::filesystem::recursive_directory_iterator(input_path)) { - if (std::filesystem::is_regular_file(entry)) { - file_paths.push_back(entry.path().string()); - } - } - } else { - std::cerr << "ERROR: the input path is not a directoy!" << std::endl; - return EXIT_FAILURE; - } - - // Initialize rocJPEG handle - RocJpegHandle handle; - RocJpegStatus status = rocJpegCreate(ROCJPEG_BACKEND_HARDWARE, 0, &handle); - if (status != ROCJPEG_STATUS_SUCCESS) { - std::cerr << "Failed to create rocJPEG handle with error code: " << rocJpegGetErrorName(status) << std::endl; - return EXIT_FAILURE; - } - - int batch_size = 32; - batch_size = std::min(batch_size, static_cast(file_paths.size())); - - std::vector rocjpeg_stream_handles; - rocjpeg_stream_handles.resize(batch_size); - // Create stream handles of batch_size - for (auto i = 0; i < batch_size; i++) { - status = rocJpegStreamCreate(&rocjpeg_stream_handles[i]); - if (status != ROCJPEG_STATUS_SUCCESS) { - std::cerr << "Failed to create rocJPEG stream handle with error code: " << rocJpegGetErrorName(status) << std::endl; - rocJpegDestroy(handle); - for (auto j = 0; j < i; j++) { - rocJpegStreamDestroy(rocjpeg_stream_handles[j]); - } - return EXIT_FAILURE; - } - } - - // Vector to store batch of raw JPEG data from files - std::vector> batch_images; - batch_images.resize(batch_size); - - // Vector to store widths of JPEG images - std::vector> widths; - widths.resize(batch_size, std::vector(ROCJPEG_MAX_COMPONENT, 0)); - - // Vector to store heights of JPEG images - std::vector> heights; - heights.resize(batch_size, std::vector(ROCJPEG_MAX_COMPONENT, 0)); - - // Vector to store chroma subsamplings of JPEG images - std::vector subsamplings; - subsamplings.resize(batch_size); - - // Vector to store output images - std::vector output_images; - output_images.resize(batch_size); - - uint8_t num_components; - RocJpegDecodeParams decode_params = {}; - decode_params.output_format = ROCJPEG_OUTPUT_NATIVE; - - // Start reading images from files and prepare a batch of JPEG streams for decoding - for (int i = 0; i < file_paths.size(); i += batch_size) { - int batch_end = std::min(i + batch_size, static_cast(file_paths.size())); - for (int j = i; j < batch_end; j++) { - int index = j - i; - // Read an image from disk - std::ifstream input(file_paths[j].c_str(), std::ios::in | std::ios::binary | std::ios::ate); - if (!(input.is_open())) { - std::cerr << "ERROR: Cannot open image: " << file_paths[j] << std::endl; - rocJpegDestroy(handle); - for (auto& it : rocjpeg_stream_handles) { - rocJpegStreamDestroy(it); - } - return EXIT_FAILURE; - } - // Get the size - std::streamsize file_size = input.tellg(); - input.seekg(0, std::ios::beg); - // Resize if buffer is too small - if (batch_images[index].size() < file_size) { - batch_images[index].resize(file_size); - } - if (!input.read(batch_images[index].data(), file_size)) { - std::cerr << "ERROR: Cannot read from file: " << file_paths[j] << std::endl; - rocJpegDestroy(handle); - for (auto& it : rocjpeg_stream_handles) { - rocJpegStreamDestroy(it); - } - return EXIT_FAILURE; - } - - status = rocJpegStreamParse(reinterpret_cast(batch_images[index].data()), file_size, rocjpeg_stream_handles[index]); - if (status != ROCJPEG_STATUS_SUCCESS) { - std::cerr << "Failed to parse a JPEG stream with error code: " << rocJpegGetErrorName(status) << std::endl; - rocJpegDestroy(handle); - for (auto& it : rocjpeg_stream_handles) { - rocJpegStreamDestroy(it); - } - return EXIT_FAILURE; - } - - status = rocJpegGetImageInfo(handle, rocjpeg_stream_handles[index], &num_components, &subsamplings[index], widths[index].data(), heights[index].data()); - if (status != ROCJPEG_STATUS_SUCCESS) { - std::cerr << "Failed to get image info with error code: " << rocJpegGetErrorName(status) << std::endl; - rocJpegDestroy(handle); - for (auto& it : rocjpeg_stream_handles) { - rocJpegStreamDestroy(it); - } - return EXIT_FAILURE; - } - - // Allocate memory for each channel of RocJpegImage - // For this sample assuming the all the input images have a YUV420 chroma subsampling (i.e., subsamplings[index] = ROCJPEG_CSS_420) - // For YUV420 subsampling, the native decoded output image would be NV12 (i.e., the rocJPegDecodeBatched API copies Y to first channel - // and UV (interleaved) to second channel of RocJpegImage for each image in the batch) - output_images[index].pitch[1] = output_images[index].pitch[0] = widths[index][0]; - hipError_t hip_status; - if (output_images[index].channel[0] != nullptr) { - hipFree((void *)output_images[index].channel[0]); - output_images[index].channel[0] = nullptr; - } - // Allocate device memory for the first channel (Y) - hip_status = hipMalloc(&output_images[index].channel[0], output_images[index].pitch[0] * heights[index][0]); - if (hip_status != hipSuccess) { - std::cerr << "Failed to allocate device memory for the first channel" << std::endl; - for (auto& it : rocjpeg_stream_handles) { - rocJpegStreamDestroy(it); - } - rocJpegDestroy(handle); - return EXIT_FAILURE; - } - - if (output_images[index].channel[1] != nullptr) { - hipFree((void *)output_images[index].channel[1]); - output_images[index].channel[1] = nullptr; - } - // Allocate device memory for the second channel (UV) - hip_status = hipMalloc(&output_images[index].channel[1], output_images[index].pitch[1] * (heights[index][0] >> 1)); - if (hip_status != hipSuccess) { - std::cerr << "Failed to allocate device memory for the second channel" << std::endl; - for (auto& it : rocjpeg_stream_handles) { - rocJpegStreamDestroy(it); - } - rocJpegDestroy(handle); - return EXIT_FAILURE; - } - } - int current_batch_size = batch_end - i; - status = rocJpegDecodeBatched(handle, rocjpeg_stream_handles.data(), current_batch_size, &decode_params, output_images.data()); - if (status != ROCJPEG_STATUS_SUCCESS) { - std::cerr << "Failed to decode a batch of JPEG streams with error code: " << rocJpegGetErrorName(status) << std::endl; - for (int b = 0; b < batch_size; b++) { - hipFree((void *)output_images[b].channel[0]); - hipFree((void *)output_images[b].channel[1]); - } - for (auto& it : rocjpeg_stream_handles) { - rocJpegStreamDestroy(it); - } - rocJpegDestroy(handle); - return EXIT_FAILURE; - } - // Perform additional post-processing on the decoded image or optionally save it - // ... - - // Clear the batch_images vector after processing each batch - for (int j = i; j < batch_end; j++) { - batch_images[j - i].clear(); - } - } - - // Clean up resources - for (auto& it : output_images) { - for (int i = 0; i < ROCJPEG_MAX_COMPONENT; i++) { - if (it.channel[i] != nullptr) { - hipFree((void *)it.channel[i]); - it.channel[i] = nullptr; - } - } - } - rocJpegDestroy(handle); - for (auto& it : rocjpeg_stream_handles) { - rocJpegStreamDestroy(it); - } - return EXIT_SUCCESS; - } \ No newline at end of file + + hipFree((void *)output_image.channel[0]); + hipFree((void *)output_image.channel[1]); + rocJpegStreamDestroy(rocjpeg_stream_handle); + rocJpegDestroy(handle); \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 924d55e..5ba1089 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,38 +10,37 @@ rocJPEG provides APIs and samples that you can use to easily access the JPEG dec features of your media engines (VCNs). It also allows interoperability with other compute engines on the GPU using Video Acceleration API (VA-API)/HIP. To learn more, see :doc:`what-is-rocJPEG` -The code is open and hosted at `GitHub repository `_. +The rocJPEG public repository is located at `https://github.com/ROCm/rocJPEG `_. .. grid:: 2 :gutter: 3 .. grid-item-card:: Install - * :doc:`Quick-start <./install/quick-start>` - * :doc:`rocJPEG installation <./install/install>` + * :doc:`rocJPEG installation prerequisites <./install/rocjpeg-prerequisites>` + * :doc:`Installing rocJPEG with the package installer <./install/rocjpeg-package-install>` + * :doc:`Building rocJPEG from source code <./install/rocjpeg-build-and-install>` -The documentation is structured as follows: - -.. grid:: 2 - :gutter: 3 - - .. grid-item-card:: Tutorials + .. grid-item-card:: How to - * `GitHub samples `_ + * :doc:`Using rocJPEG ` + * :doc:`Retrieving image information with rocJPEG ` + * :doc:`Decoding a JPEG stream with rocJPEG ` - .. grid-item-card:: How to + .. grid-item-card:: Samples - * :doc:`Use rocJPEG ` + * `rocJPEG samples on GitHub `_ - .. grid-item-card:: API reference + .. grid-item-card:: Reference - * :doc:`API library <../doxygen/html/files>` - * :doc:`Functions <../doxygen/html/globals>` - * :doc:`Data structures <../doxygen/html/annotated>` + * :doc:`rocJPEG subsampling and hardware capabilities <./reference/rocjpeg-formats-and-architectures>` + * :doc:`rocJPEG API library <../doxygen/html/files>` + * :doc:`rocJPEG Functions <../doxygen/html/globals>` + * :doc:`rocJPEG Data structures <../doxygen/html/annotated>` To contribute to the documentation, refer to -`Contributing to ROCm `_. +`Contributing to ROCm documentation `_. You can find licensing information on the `Licensing `_ page. \ No newline at end of file diff --git a/docs/install/install.rst b/docs/install/install.rst deleted file mode 100644 index 31a518a..0000000 --- a/docs/install/install.rst +++ /dev/null @@ -1,212 +0,0 @@ -.. meta:: - :description: Install rocJPEG - :keywords: install, rocJPEG, AMD, ROCm - -******************************************************************** -Installation -******************************************************************** - -rocJPEG is a high performance JPEG decode SDK for AMD GPUs. Using the rocJPEG API, -you can access the JPEG decoding features available on your GPU. - -Prerequisites -======================================== - -* Linux distribution - - * Ubuntu: 20.04/22.04 - * RHEL: 8/9 - * SLES: 15-SP5 - -* `ROCm-supported hardware `_ - (``gfx908`` or higher is required) - -* Install ROCm 6.3.0 or later with - `amdgpu-install `_ - - * Run: ``--usecase=rocm`` - * To install rocJPEG with minimum requirements, follow the :doc:`quick-start instructions <./quick-start>` - -* Video Acceleration API - Version `1.5.0+` - `Libva` is an implementation for VA-API - - .. code:: shell - - sudo apt install libva-dev - -* AMD VA Drivers - - .. code:: shell - - sudo apt install mesa-amdgpu-va-drivers - -* CMake 3.5 or later - - .. code:: shell - - sudo apt install cmake - -* pkg-config - - .. code:: shell - - sudo apt install pkg-config - -* If using Ubuntu 22.04, you must install ``libstdc++-12-dev`` - - .. code:: shell - - sudo apt install libstdc++-12-dev - -.. note:: - - All package installs are shown with the ``apt`` package manager. Use the appropriate package - manager for your operating system. - -Prerequisites setup script ----------------------------------------------------------------------------------------------------------- - -For your convenience, we provide the setup script, -`rocJPEG-setup.py `_, -which installs all required dependencies. Run this script only once. - -.. code:: shell - - python rocJPEG-setup.py --rocm_path [ ROCm Installation Path - optional (default:/opt/rocm)] - -Installation instructions -======================================== - -To install rocJPEG, you can use :ref:`package-install` or -:ref:`source-install`. - -.. _package-install: - -Package install ------------------------------------------------------------------------------------------------------------- - -To install rocJPEG runtime, development, and test packages, run the line of code for your operating -system. - -.. tab-set:: - - .. tab-item:: Ubuntu - - .. code:: shell - - sudo apt install rocjpeg rocjpeg-dev rocjpeg-test - - .. tab-item:: RHEL - - .. code:: shell - - sudo yum install rocjpeg rocjpeg-devel rocjpeg-test - - .. tab-item:: SLES - - .. code:: shell - - sudo zypper install rocjpeg rocjpeg-devel rocjpeg-test - -.. note:: - - Package install auto installs all dependencies. - -* Runtime package: ``rocjpeg`` only provides the rocjpeg library ``librocjpeg.so`` -* Development package: ``rocjpeg-dev``or ``rocjpeg-devel`` provides the library, header files, and samples -* Test package: ``rocjpeg-test`` provides CTest to verify installation - -.. _source-install: - -Source install ------------------------------------------------------------------------------------------------------------- - -To build rocJPEG from source, run: - -.. code:: shell - - git clone https://github.com/ROCm/rocJPEG.git - cd rocJPEG - mkdir build && cd build - cmake ../ - make -j8 - sudo make install - -Run tests: - -.. code:: shell - - make test - -To run tests with verbose option, use ``make test ARGS="-VV"``. - -Make package: - -.. code:: shell - - sudo make package - -Verify installation -======================================== - -The installer copies: - -* Libraries into ``/opt/rocm/lib`` -* Header files into ``/opt/rocm/include/rocjpeg`` -* Samples folder into ``/opt/rocm/share/rocjpeg`` -* Documents folder into ``/opt/rocm/share/doc/rocjpeg`` - -To verify your installation using a sample application, run: - -.. code:: shell - - mkdir rocjpeg-sample && cd rocjpeg-sample - cmake /opt/rocm/share/rocjpeg/samples/videoDecode/ - make -j8 - ./jpegdecode -i /opt/rocm/share/rocjpeg/images/ - -To verify your installation using the ``rocjpeg-test`` package, run: - -.. code:: shell - - mkdir rocjpeg-test && cd rocjpeg-test - cmake /opt/rocm/share/rocjpeg/test/ - ctest -VV - -This test package installs the CTest module. - -Samples -======================================== - -You can access samples to decode your JPEG images in our -`GitHub repository `_. Refer to the -individual folders to build and run the samples. - -Docker -======================================== - -You can find rocJPEG Docker containers in our -`GitHub repository `_. - -Hardware capabilities -=================================================== - -* Supported JPEG chroma subsampling - - * YUV 4:4:4 - * YUV 4:4:0 - * YUV 4:2:2 - * YUV 4:2:0 - * YUV 4:0:0 - -The following table shows the capabilities of the VCN and total number of JPEG cores for each supported GPU -architecture. - -.. csv-table:: - :header: "GPU Architecture", "VCN Generation", "Total number of JPEG cores", "Max width, Max height" - - "gfx908 - MI1xx", "VCN 2.5.0", "2", "4096, 4096" - "gfx90a - MI2xx", "VCN 2.6.0", "4", "4096, 4096" - "gfx940, gfx942 - MI300A", "VCN 3.0", "24", "16384, 16384" - "gfx941, gfx942 - MI300X", "VCN 3.0", "32", "16384, 16384" - "gfx1030, gfx1031, gfx1032 - Navi2x", "VCN 3.x", "1", "16384, 16384" - "gfx1100, gfx1101, gfx1102 - Navi3x", "VCN 4.0", "1", "16384, 16384" \ No newline at end of file diff --git a/docs/install/quick-start.rst b/docs/install/quick-start.rst deleted file mode 100644 index 40837d8..0000000 --- a/docs/install/quick-start.rst +++ /dev/null @@ -1,42 +0,0 @@ -.. meta:: - :description: Install rocJPEG - :keywords: install, rocJPEG, AMD, ROCm - -******************************************************************** -rocJPEG quick-start installation -******************************************************************** - -To install the rocJPEG runtime with minimum requirements, follow these steps: - -1. Install core ROCm components (ROCm 6.3.0 or later) using the -:doc:`native package manager ` -installation instructions. - -* Register repositories -* Register kernel-mode driver -* Register ROCm packages -* Install kernel driver (``amdgpu-dkms``)--only required on bare metal install. Docker runtime uses the - base ``dkms`` package irrespective of the version installed. - -2. Install rocJPEG runtime package. rocJPEG only provides the ``librocjpeg.so`` library (the -runtime package only installs the required core dependencies). - -.. tab-set:: - - .. tab-item:: Ubuntu - - .. code:: shell - - sudo apt install rocjpeg - - .. tab-item:: RHEL - - .. code:: shell - - sudo yum install rocjpeg - - .. tab-item:: SLES - - .. code:: shell - - sudo zypper install rocjpeg diff --git a/docs/install/rocjpeg-build-and-install.rst b/docs/install/rocjpeg-build-and-install.rst new file mode 100644 index 0000000..b616edb --- /dev/null +++ b/docs/install/rocjpeg-build-and-install.rst @@ -0,0 +1,42 @@ +.. meta:: + :description: Install rocJPEG with the source code + :keywords: install, building, rocJPEG, AMD, ROCm, source code, developer + +******************************************************************** +Building and installing rocJPEG from source code +******************************************************************** + +These instructions are for building rocJPEG from its source code. If you will not be contributing to the rocJPEG code base or previewing features, `package installers `_ are available. + +.. note:: + + ROCm 6.3.0 or later must be installed before installing rocJPEG. See `Quick start installation guide `_ for detailed ROCm installation instructions. + +Use `rocJPEG-setup.py `_ available from the rocJPEG GitHub repo to install the prerequisites: + +.. code:: shell + + python rocJPEG-setup.py --rocm_path [ ROCm Installation Path - optional (default:/opt/rocm)] + +Build and install rocJPEG using the following commands: + +.. code:: shell + + git clone https://github.com/ROCm/rocJPEG.git + cd rocJPEG + mkdir build && cd build + cmake ../ + make -j8 + sudo make install + +After installation, the rocJPEG libraries will be copied to ``/opt/rocm/lib`` and the rocJPEG header files will be copied to ``/opt/rocm/include/rocjpeg``. + +Install the CTest module: + +.. code:: shell + + mkdir rocjpeg-test && cd rocjpeg-test + cmake /opt/rocm/share/rocjpeg/test/ + ctest -VV + +To test your build, run ``make test``. To run the test with the verbose option, run ``make test ARGS=\"-VV\"``. diff --git a/docs/install/rocjpeg-package-install.rst b/docs/install/rocjpeg-package-install.rst new file mode 100644 index 0000000..ad3c27d --- /dev/null +++ b/docs/install/rocjpeg-package-install.rst @@ -0,0 +1,74 @@ +.. meta:: + :description: Installing rocJPEG with the package installer + :keywords: install, rocJPEG, AMD, ROCm, basic, development, package + +******************************************************************** +Installing rocJPEG with the package installer +******************************************************************** + +.. note:: + + ROCm 6.3.0 or later must be installed before installing rocJPEG. See `Quick start installation guide `_ for detailed ROCm installation instructions. + +There are three rocJPEG packages available: + +* ``rocjpeg``: The rocJPEG runtime package. This is the basic rocJPEG package. +* ``rocjpeg-dev``: The rocJPEG development package. This package installs a full suite of libraries, header files, and samples for contributing to the rocJPEG code base. +* ``rocjpeg-test``: A test package that provides a CTest to verify the installation. + +Developers who want to contribute to the rocJPEG code base must install both ``rocjpeg-dev`` and ``rocjpeg-test`` in addition to ``rocjpeg``. + +All the required prerequisites are installed when the package installation method is used. + +Basic installation +======================================== + +Use the following commands to install only the rocJPEG runtime package: + +.. tab-set:: + + .. tab-item:: Ubuntu + + .. code:: shell + + sudo apt install rocjpeg + + .. tab-item:: RHEL + + .. code:: shell + + sudo yum install rocjpeg + + .. tab-item:: SLES + + .. code:: shell + + sudo zypper install rocjpeg + + +Developer installation +======================================== + +All three rocJPEG packages, ``rocjpeg``, ``rocjpeg-dev``, and ``rocjpeg-test`` must be installed to develop for rocJPEG. + +Use the following commands to install ``rocjpeg``, ``rocjpeg-dev``, and ``rocjpeg-test``: + +.. tab-set:: + + .. tab-item:: Ubuntu + + .. code:: shell + + sudo apt install rocjpeg rocjpeg-dev rocjpeg-test + + .. tab-item:: RHEL + + .. code:: shell + + sudo yum install rocjpeg rocjpeg-devel rocjpeg-test + + .. tab-item:: SLES + + .. code:: shell + + sudo zypper install rocjpeg rocjpeg-devel rocjpeg-test \ No newline at end of file diff --git a/docs/install/rocjpeg-prerequisites.rst b/docs/install/rocjpeg-prerequisites.rst new file mode 100644 index 0000000..7408551 --- /dev/null +++ b/docs/install/rocjpeg-prerequisites.rst @@ -0,0 +1,25 @@ +.. meta:: + :description: rocJPEG Installation Prerequisites + :keywords: install, rocJPEG, AMD, ROCm, prerequisites, dependencies, requirements + +******************************************************************** +rocJPEG prerequisites +******************************************************************** + +rocJPEG requires ROCm 6.3 or later running on `accelerators based on the CDNA architecture `_. + +ROCm 6.3.0 or later must be installed before installing rocJPEG. See `Quick start installation guide `_ for detailed ROCm installation instructions. + +rocJPEG can be installed on the following Linux environments: + +* Ubuntu 20.04, 22.04, 24.04 +* RHEL 8 or 9 +* SLES: 15-SP5 + +The following prerequisites are installed by the package installer. If you are building and installing using the source code, use the `rocJPEG-setup.py `_ setup script available in the rocJPEG GitHub repository to install these prerequisites. + +* Libva, an implementation for Video Acceleration API (VA-API), version 1.16 or later +* AMD VA Drivers +* CMake version 3.5 or later +* pkg-config +* libstdc++-12-dev for installations on Ubuntu 22.04 diff --git a/docs/reference/rocjpeg-formats-and-architectures.rst b/docs/reference/rocjpeg-formats-and-architectures.rst new file mode 100644 index 0000000..fe4bdff --- /dev/null +++ b/docs/reference/rocjpeg-formats-and-architectures.rst @@ -0,0 +1,28 @@ +.. meta:: + :description: rocJPEG chroma subsampling and hardware capabilities + :keywords: install, rocJPEG, AMD, ROCm, GPU, chroma, subsampling, VCN + +******************************************************************** +rocJPEG chroma subsampling and hardware capabilities +******************************************************************** + +rocJPEG supports the following chroma subsamplings: + +* YUV 4:4:4 +* YUV 4:4:0 +* YUV 4:2:2 +* YUV 4:2:0 +* YUV 4:0:0 + +The following table shows the capabilities of the VCN and total number of JPEG cores for each supported GPU +architecture: + +.. csv-table:: + :header: "GPU Architecture", "VCN Generation", "Total number of JPEG cores", "Max width, Max height" + + "gfx908 - MI1xx", "VCN 2.5.0", "2", "4096, 4096" + "gfx90a - MI2xx", "VCN 2.6.0", "4", "4096, 4096" + "gfx940, gfx942 - MI300A", "VCN 3.0", "24", "16384, 16384" + "gfx941, gfx942 - MI300X", "VCN 3.0", "32", "16384, 16384" + "gfx1030, gfx1031, gfx1032 - Navi2x", "VCN 3.x", "1", "16384, 16384" + "gfx1100, gfx1101, gfx1102 - Navi3x", "VCN 4.0", "1", "16384, 16384" \ No newline at end of file diff --git a/docs/sphinx/_toc.yml.in b/docs/sphinx/_toc.yml.in index 923434a..5968406 100644 --- a/docs/sphinx/_toc.yml.in +++ b/docs/sphinx/_toc.yml.in @@ -8,29 +8,38 @@ subtrees: - caption: Install entries: - - file: install/quick-start.rst - title: Quick-start - - file: install/install.md - title: Installation guide - -- caption: API reference - entries: - - file: doxygen/html/files - title: API library - - file: doxygen/html/globals - title: Functions - - file: doxygen/html/annotated - title: Data structures + - file: install/rocjpeg-prerequisites.rst + title: rocJPEG installation prerequisites + - file: install/rocjpeg-package-install.rst + title: Installing rocJPEG with the package installer + - file: install/rocjpeg-build-and-install.rst + title: Building and installing rocJPEG from source code - caption: How to entries: - file: how-to/using-rocjpeg.rst - title: Use rocJPEG + title: Using rocJPEG + - file: how-to/rocjpeg-retrieve-image-info.rst + title: Retrieving image information with rocJPEG + - file: how-to/rocjpeg-decoding-a-jpeg-stream.rst + title: Decoding a JPEG stream with rocJPEG -- caption: Tutorials +- caption: Samples entries: - url: https://github.com/ROCm/rocJPEG/tree/develop/samples - title: GitHub samples + title: rocJPEG samples on GitHub + + +- caption: Reference + entries: + - file: reference/rocjpeg-formats-and-architectures.rst + title: rocJPEG subsampling and hardware capabilities + - file: doxygen/html/files + title: rocJPEG API library + - file: doxygen/html/globals + title: rocJPEG functions + - file: doxygen/html/annotated + title: rocJPEG data structures - caption: About entries: diff --git a/docs/sphinx/requirements.in b/docs/sphinx/requirements.in index 5671f15..0979906 100644 --- a/docs/sphinx/requirements.in +++ b/docs/sphinx/requirements.in @@ -1 +1 @@ -rocm-docs-core[api_reference]==0.38.1 +rocm-docs-core[api_reference]==1.10.0 diff --git a/docs/sphinx/requirements.txt b/docs/sphinx/requirements.txt index 31c8b6e..f03ffbd 100644 --- a/docs/sphinx/requirements.txt +++ b/docs/sphinx/requirements.txt @@ -1,14 +1,14 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.10 # by the following command: # -# pip-compile --resolver=backtracking requirements.in +# pip-compile requirements.in # -accessible-pygments==0.0.4 +accessible-pygments==0.0.5 # via pydata-sphinx-theme -alabaster==0.7.13 +alabaster==1.0.0 # via sphinx -babel==2.14.0 +babel==2.16.0 # via # pydata-sphinx-theme # sphinx @@ -16,13 +16,13 @@ beautifulsoup4==4.12.3 # via pydata-sphinx-theme breathe==4.35.0 # via rocm-docs-core -certifi==2024.2.2 +certifi==2024.8.30 # via requests -cffi==1.16.0 +cffi==1.17.1 # via # cryptography # pynacl -charset-normalizer==3.3.2 +charset-normalizer==3.4.0 # via requests click==8.1.7 # via @@ -31,102 +31,117 @@ click==8.1.7 # sphinx-external-toc click-log==0.4.0 # via doxysphinx -cryptography==42.0.5 +contourpy==1.3.1 + # via matplotlib +cryptography==44.0.0 # via pyjwt -deprecated==1.2.14 +cycler==0.12.1 + # via matplotlib +deprecated==1.2.15 # via pygithub -docutils==0.19 +docutils==0.21.2 # via # breathe # myst-parser # pydata-sphinx-theme # sphinx -doxysphinx==3.3.7 +doxysphinx==3.3.12 # via rocm-docs-core -fastjsonschema==2.19.1 +fastjsonschema==2.21.1 # via rocm-docs-core +fonttools==4.55.1 + # via matplotlib gitdb==4.0.11 # via gitpython -gitpython==3.1.42 +gitpython==3.1.43 # via rocm-docs-core -idna==3.6 +idna==3.10 # via requests imagesize==1.4.1 # via sphinx -importlib-metadata==7.1.0 - # via sphinx -importlib-resources==6.4.0 - # via - # mpire - # rocm-docs-core -jinja2==3.1.3 +jinja2==3.1.4 # via # myst-parser # sphinx +kiwisolver==1.4.7 + # via matplotlib libsass==0.22.0 # via doxysphinx -lxml==4.9.4 +lxml==5.2.1 # via doxysphinx -markdown-it-py==2.2.0 +markdown-it-py==3.0.0 # via # mdit-py-plugins # myst-parser -markupsafe==2.1.5 +markupsafe==3.0.2 # via jinja2 -mdit-py-plugins==0.3.5 +matplotlib==3.9.3 + # via doxysphinx +mdit-py-plugins==0.4.2 # via myst-parser mdurl==0.1.2 # via markdown-it-py -mpire==2.10.1 +mpire==2.10.2 # via doxysphinx -myst-parser==1.0.0 +myst-parser==4.0.0 # via rocm-docs-core -packaging==24.0 +numpy==1.26.4 # via - # pydata-sphinx-theme + # contourpy + # doxysphinx + # matplotlib +packaging==24.2 + # via + # matplotlib # sphinx -pycparser==2.21 +pillow==11.0.0 + # via matplotlib +pycparser==2.22 # via cffi -pydata-sphinx-theme==0.14.4 +pydata-sphinx-theme==0.16.0 # via # rocm-docs-core # sphinx-book-theme -pygithub==2.3.0 +pygithub==2.5.0 # via rocm-docs-core -pygments==2.17.2 +pygments==2.18.0 # via # accessible-pygments # mpire # pydata-sphinx-theme # sphinx -pyjson5==1.6.6 +pyjson5==1.6.7 # via doxysphinx -pyjwt[crypto]==2.8.0 +pyjwt[crypto]==2.10.1 # via pygithub pynacl==1.5.0 # via pygithub -pyparsing==3.1.2 - # via doxysphinx -pytz==2024.1 - # via babel -pyyaml==6.0.1 +pyparsing==3.2.0 + # via + # doxysphinx + # matplotlib +python-dateutil==2.9.0.post0 + # via matplotlib +pyyaml==6.0.2 # via # myst-parser # rocm-docs-core # sphinx-external-toc -requests==2.31.0 +requests==2.32.3 # via # pygithub # sphinx -rocm-docs-core[api-reference]==0.38.1 +rocm-docs-core[api-reference]==1.10.0 # via -r requirements.in +six==1.16.0 + # via python-dateutil smmap==5.0.1 # via gitdb snowballstemmer==2.2.0 # via sphinx -soupsieve==2.5 +soupsieve==2.6 # via beautifulsoup4 -sphinx==5.3.0 +sphinx==8.1.3 # via # breathe # myst-parser @@ -137,41 +152,39 @@ sphinx==5.3.0 # sphinx-design # sphinx-external-toc # sphinx-notfound-page -sphinx-book-theme==1.0.1 +sphinx-book-theme==1.1.3 # via rocm-docs-core sphinx-copybutton==0.5.2 # via rocm-docs-core -sphinx-design==0.5.0 +sphinx-design==0.6.1 # via rocm-docs-core -sphinx-external-toc==0.3.1 +sphinx-external-toc==1.0.1 # via rocm-docs-core -sphinx-notfound-page==1.0.0 +sphinx-notfound-page==1.0.4 # via rocm-docs-core -sphinxcontrib-applehelp==1.0.4 +sphinxcontrib-applehelp==2.0.0 # via sphinx -sphinxcontrib-devhelp==1.0.2 +sphinxcontrib-devhelp==2.0.0 # via sphinx -sphinxcontrib-htmlhelp==2.0.1 +sphinxcontrib-htmlhelp==2.1.0 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx -sphinxcontrib-qthelp==1.0.3 +sphinxcontrib-qthelp==2.0.0 + # via sphinx +sphinxcontrib-serializinghtml==2.0.0 # via sphinx -sphinxcontrib-serializinghtml==1.1.5 +tomli==2.2.1 # via sphinx -tqdm==4.66.2 +tqdm==4.67.1 # via mpire -typing-extensions==4.10.0 +typing-extensions==4.12.2 # via # pydata-sphinx-theme # pygithub -urllib3==2.2.1 +urllib3==2.2.3 # via # pygithub # requests -wrapt==1.16.0 +wrapt==1.17.0 # via deprecated -zipp==3.18.1 - # via - # importlib-metadata - # importlib-resources