nvjpegEncodeImage returns error

hi experts,
i want use nvjpeg to encode cv::cuda::GpuMat to jpeg, but always got the NVJPEG_STATUS_INVALID_PARAMETER returned after calling nvjpegEncodeImage.
Following is my testing code, i am really confused:

#include <opencv2/opencv.hpp>

#include <nvjpeg.h>

#include "opencv2/cudaarithm.hpp"
//#include "opencv2/cudawarping.hpp"

#include <fstream>

int main(int argc, char** argv)
{
    cudaSetDevice(0);

    cv::Mat cpu = cv::imread("E:/Documents/Media/Images/backham.jpg");
    cv::cuda::GpuMat gpu(cpu);
    std::vector<cv::cuda::GpuMat> channels;
    cv::cuda::split(gpu, channels);

    cudaStream_t stream;
    cudaError_t cuRes = cudaStreamCreate(&stream);

    nvjpegHandle_t nv_handle;
    nvjpegEncoderState_t nv_enc_state;
    nvjpegEncoderParams_t nv_enc_params;

    // initialize nvjpeg structures
    nvjpegStatus_t nvRes = nvjpegCreateSimple(&nv_handle);
    nvRes = nvjpegEncoderStateCreate(nv_handle, &nv_enc_state, stream);
    nvRes = nvjpegEncoderParamsCreate(nv_handle, &nv_enc_params, stream);

    nvjpegImage_t nv_image;
    memset(&nv_image, 0, sizeof(nv_image));

#define INTERLEAVED 
#ifndef INTERLEAVED
    nv_image.channel[0] = channels[0].data;
    nv_image.channel[1] = channels[1].data;
    nv_image.channel[2] = channels[2].data;
    nv_image.pitch[0] = (unsigned int)channels[0].step;
    nv_image.pitch[1] = (unsigned int)channels[1].step;
    nv_image.pitch[2] = (unsigned int)channels[2].step;
    nvjpegInputFormat_t input_format = NVJPEG_INPUT_BGR;
#else
    nv_image.channel[0] = gpu.data;
    nv_image.pitch[0] = (unsigned int)gpu.step;
    nvjpegInputFormat_t input_format = NVJPEG_INPUT_BGRI;
#endif

    // Compress image
    nvRes = nvjpegEncodeImage(nv_handle, nv_enc_state, nv_enc_params,
        &nv_image, input_format, gpu.cols, gpu.rows, stream);

    // get compressed stream size
    size_t length;
    nvRes = nvjpegEncodeRetrieveBitstream(nv_handle, nv_enc_state, NULL, &length, stream);
    // get stream itself
    cuRes = cudaStreamSynchronize(stream);
    std::vector<unsigned char> jpeg(length);
    nvRes = nvjpegEncodeRetrieveBitstream(nv_handle, nv_enc_state, jpeg.data(), &length, 0);

    // write stream to file
    cuRes = cudaStreamSynchronize(stream);
    std::ofstream output_file("test.jpg", std::ios::out | std::ios::binary);
    output_file.write((const char*)jpeg.data(), length);
    output_file.close();

    return 0;
}

Any sugguesting would be great, thanks in advance!!

1 Like

Hi all
i found the reason: we must set all the encoder parameters.
and my problem is that nvjpegEncoderParamsSetSamplingFactors is not called to set the sampling information

1 Like