JPEGD

This section describes the API call sequence of JPEGD, and sample code is also provided to help you better understand the process.

The JPEG decoder (JPEGD) can decode .jpg, .jpeg, .JPG, and .JPEG images into YUV images. For details about the JPEGD functions and restrictions, see DVPP Media Acceleration Library.

API Call Sequence

Figure 1 Process of calling the JPEGD image decoding function

The current system supports decoding JPEG images. The key APIs are described as follows:

  1. Call aclInit to initialize the system.
  2. Call aclrtSetDevice to specify the compute device.
  3. Call hi_mpi_sys_init to initialize the media data processing system.
  4. Call hi_mpi_vdec_create_chn to create a channel.
  5. Call hi_mpi_dvpp_malloc to allocate the device memory to store the input or output data.
  6. Before decoding, call hi_mpi_vdec_start_recv_stream to notify the decoder to start receiving streams, and then call hi_mpi_vdec_send_stream to send the streams to be decoded. hi_mpi_vdec_send_stream is an asynchronous API. The API call only delivers a task. You also need to call hi_mpi_vdec_get_frame to obtain the decoding result data. You can call hi_mpi_vdec_release_frame to release frame-related resources. After the decoding is complete, call hi_mpi_vdec_stop_recv_stream to notify the decoder to stop receiving streams.
  7. Call hi_mpi_dvpp_free to free the input and output buffers.
  8. Call hi_mpi_vdec_destroy_chn to destroy the channel.
  9. Call hi_mpi_sys_exit to deinitialize the media data processing system.
  10. Call aclrtResetDevice to reset the device and free the resources on the device.
  11. Call aclFinalize to deinitialize the system and free the resources used by the acl API in the process.

Sample Code

The following is a code snippet of key steps for JPEGD image decoding. It is for reference only. Do not copy, build, or run it directly. Following the API calls, add exception handling branches and specify log printing of error and information levels.

You can click jpegd_sample to obtain the sample.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
// ....

// 1. Initialize the media data processing system.
int32_t ret = hi_mpi_sys_init();

// 2. Create a channel.
hi_vdec_chn chnId;
hi_vdec_chn_attr chnAttr;

chnAttr.type = HI_PT_JPEG;
chnAttr.mode = HI_VDEC_SEND_MODE_FRAME;
chnAttr.pic_width = 1920;
chnAttr.pic_height = 1080;
chnAttr.stream_buf_size = 1920 * 1080;

ret = hi_mpi_vdec_create_chn(chnId, &chnAttr);

// 3. Set channel attributes.
hi_vdec_chn_param chnParam;
ret = hi_mpi_vdec_get_chn_param(chnId, &chnParam);

chnParam.pic_param.pixel_format = HI_PIXEL_FORMAT_YUV_SEMIPLANAR_420;
chnParam.pic_param.alpha = 255;
chnParam.display_frame_num = 0;
ret = hi_mpi_vdec_set_chn_param(chnId, &chnParam);

// 4. The decoder starts receiving streams.
ret = hi_mpi_vdec_start_recv_stream(chnId);

// 5. Send streams.
// 5.1 Allocate input buffer.
uint8_t* inputAddr = nullptr;
// inputsize indicates the buffer size occupied by the input image. The following uses 1024 bytes as an example. You need to calculate the actual buffer size.
int32_t inputSize = 1024;
ret = hi_mpi_dvpp_malloc(0, &inputAddr, inputSize);
    // Load the input image into the buffer. The ReadStreamFile function is defined by the user.
ReadStreamFile(fileName, inputAddr, inputSize);

// 5.2 Construct a struct for storing input image information.
hi_vdec_stream stStream{};
hi_img_info stImgInfo{};
stStream.pts = 0;
if (g_runMode == ACL_HOST) {
    stStream.addr  = (uint8_t *)hostInputAddr;
} else {
    stStream.addr  = (uint8_t *)inputAddr;
}
stStream.len = inputSize;
stStream.end_of_frame = HI_TRUE;
stStream.end_of_stream = HI_FALSE;
stStream.need_display  = HI_TRUE;

ret = hi_mpi_dvpp_get_image_info(HI_PT_JPEG, &stStream, &stImgInfo);
if (g_runMode == ACL_HOST) {
    // If the data on the host is not used, free the host buffer in a timely manner.
   aclrtFreeHost(hostInputAddr);
    hostInputAddr = nullptr;
}
stStream.addr = (uint8_t *)inputAddr;

// 5.3 Construct the struct for storing output image information and allocate output buffer.
hi_vdec_pic_info outPicInfo{};
void *outBuffer = nullptr;
outPicInfo.width  = stImgInfo.width;
outPicInfo.height = stImgInfo.height;
outPicInfo.width_stride  = stImgInfo.width_stride;
outPicInfo.height_stride = stImgInfo.height_stride;
outPicInfo.buffer_size   = stImgInfo.img_buf_size;
outPicInfo.pixel_format  = HI_PIXEL_FORMAT_UNKNOWN;

ret = hi_mpi_dvpp_malloc(0, &outBuffer, outPicInfo.buffer_size);

outPicInfo.vir_addr = (uint64_t)outBuffer;

// 5.4 Send the input image to be decoded.
ret = hi_mpi_vdec_send_stream(chnId, &stStream, &outPicInfo, 0);

// 6. Receive the decoding result.
// 6.1 Obtain the decoding result.
hi_video_frame_info frame;    
hi_vdec_stream stream;
hi_vdec_supplement_info stSupplement;
ret = hi_mpi_vdec_get_frame(chnId, &frame, &stSupplement, &stream, 0);
if (ret == HI_SUCCESS) {
   decResult = frame.v_frame.frame_flag;
   if (decResult == 0) { // 0: Decode success
       printf("[%s][%d] Chn %u GetFrame Success, Decode Success \n",__FUNCTION__, __LINE__, chnId);
   } else { // Decode fail
       printf("[%s][%d] Chn %u GetFrame Success, Decode Fail \n",__FUNCTION__, __LINE__, chnId);
   }
}

// 6.2 Obtain the JPEGD output image data from the memory to which frame.v_frame.virt_addr[0] points.
......

// 6.3 Free the input and output buffers.
ret = hi_mpi_dvpp_free(frame.v_frame.virt_addr[0]);
ret = hi_mpi_dvpp_free(stream.addr);

// 6.4 Free resources.
ret = hi_mpi_vdec_release_frame(chnId, &frame);

// 7. The decoder stops receiving streams.
ret = hi_mpi_vdec_stop_recv_stream(chnId);

// 8. Destroy the channel.
ret = hi_mpi_vdec_destroy_chn(chnId);

// 9. Deinitialize the media data processing system.
ret = hi_mpi_sys_exit();

....