NVIDIA / NVIDIA/CUDALibrarySamples

Related issues about using NvJPEG to implement image encoding and decoding on RTX3060

Open
#194 4 comments 1 reaction 1 assignee View on GitHub

@zohebk-nv is already working on this.

Since Jul 9, 2024.

nvJPEG
Dominant language
Cuda
Stars
2.5k
Forks
478
PR merge metrics
No merged PRs in 30d

Description

Thanks to the contribution of this warehouse, I am a beginner of NvJPEG, trying to use RTX 3060 to compress png or bmp images, and raise a few questions as follows:
Resolution of input image: 8432 * 40000
Experimental version: CUDA 11.6
image

  1. It takes about 334ms to encode and compress an image of this size on the 3060 GPU, and about 12xxms to decode. Is this time consumption normal?
  2. After I finish decoding, I try to convert the image from nvjpeg_image to cv::Mat format. In the getCVImage in the figure above, I use a loop for this process. Is there a faster way?
cv::Mat NvjpegCompressRunnerImpl::getCVImage(const unsigned char *d_chanB, int pitchB, \
                                             const unsigned char *d_chanG, int pitchG, \
                                             const unsigned char *d_chanR, int pitchR, \
                                             int width, int height) 
{
    cudaEvent_t start, end;
    float milliseconds = 0.0;
    CHECK_CUDA(cudaEventCreate(&start));
    CHECK_CUDA(cudaEventCreate(&end));

    CHECK_CUDA(cudaEventRecord(start));


    cv::Mat cvImage(height, width, CV_8UC3); //BGR
    std::vector<unsigned char> vchanR(height * width);
    std::vector<unsigned char> vchanG(height * width);
    std::vector<unsigned char> vchanB(height * width);
    unsigned char *chanR = vchanR.data();
    unsigned char *chanG = vchanG.data();
    unsigned char *chanB = vchanB.data();

    CHECK_CUDA(cudaMemcpy2D(chanR, (size_t)width, d_chanR, (size_t)pitchR, \
                    width, height, cudaMemcpyDeviceToHost));
    CHECK_CUDA(cudaMemcpy2D(chanG, (size_t)width, d_chanG, (size_t)pitchR, \
                    width, height, cudaMemcpyDeviceToHost));
    CHECK_CUDA(cudaMemcpy2D(chanB, (size_t)width, d_chanB, (size_t)pitchR, \
                    width, height, cudaMemcpyDeviceToHost));

    for (int y = 0; y < height; y++) 
    {
        for (int x = 0; x < width; x++) 
        {
            cvImage.at<cv::Vec3b>(y, x) = cv::Vec3b(chanB[y * width + x], chanG[y * width + x], chanR[y * width + x]);
        }
    }

    CHECK_CUDA(cudaEventRecord(end));
    CHECK_CUDA(cudaEventSynchronize(end));

    CHECK_CUDA(cudaEventElapsedTime(&milliseconds, start, end));

    CHECK_CUDA(cudaEventDestroy(start));
    CHECK_CUDA(cudaEventDestroy(end));

    std::cout << "=> getCVImage execution time: " << milliseconds << " ms" << std::endl;

    return cvImage;
}
  1. If I want to encode and decode the same picture on a RTX 1030 GPU, it will crash directly. Should the large picture be divided into small pictures? Can multiple small pictures be compressed asynchronously?
    Thank you again for your contribution, looking forward to your reply, thank you

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.