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 aclmdlCreateAndGetOpDesc.
API Call Sequence
If JPEG image decoding is involved during app development, ensure that your app contains the code logic for such image decoding. For details about the API call sequence, see AscendCL API Call Sequence.
The current system supports .jpg, .jpeg, .JPG, and .JPEG image decoding. Different source image encoding formats lead to different output formats. The key APIs are described as follows:
- Call acldvppCreateChannel to create an image processing channel.
Before creating a channel, call acldvppCreateChannelDesc to create a channel description.
- Before JPEG decoding, call acldvppMalloc to allocate device memory as input and output buffers.
Before allocating output buffer, call acldvppJpegPredictDecSize to predict the required output allocation size based on the JPEG image size.
The actual size may be different from the size predicated by using the acldvppJpegPredictDecSize call. To obtain the actual output allocation size, call acldvppGetPicDescSize of type acldvppPicDesc.
- Call acldvppJpegDecodeAsync to run asynchronous decoding.
Call aclrtSynchronizeStream to wait for the stream tasks to complete.
- After the decoding is complete, call acldvppFree to free the input and output buffers in a timely manner.
- Call acldvppDestroyChannel to destroy the image processing channel.
After destroying the channel, call acldvppDestroyChannelDesc to destroy the channel description.
Sample Code
You can view the complete code in Image Classification with ResNet-50 (Image Decoding+Cropping and Resizing+Image Encoding+Synchronous Inference).
This section focuses on the code logic for decoding JPEGD images. For details about how to initialize and deinitialize AscendCL, see Initializing AscendCL. For details about how to allocate and deallocate runtime resources, see Runtime Resource Allocation and Deallocation.
After APIs are called, you need to add exception handling branches and record error logs and info logs. The following is a code snippet of key steps only, which is not ready to be built or run.
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 |
// 1. Initialize AscendCL. // 2. Allocate runtime resources. // 3. Create description of the data processing channel. dvppChannelDesc_ is of type acldvppChannelDesc. dvppChannelDesc_ = acldvppCreateChannelDesc(); // 4. Create a data processing channel. aclError ret = acldvppCreateChannel(dvppChannelDesc_); // 5. Allocate input buffer (run mode specific). // Call aclrtGetRunMode to obtain the run mode of the software stack. If ACL_DEVICE is returned, allocate and use the device buffer. If ACL_HOST is returned, transfer the input image data to the device by using the aclrtMemcpy call. After the data transfer is complete, the buffer needs to be freed in a timely manner. aclrtRunMode runMode; ret = aclrtGetRunMode(&runMode); if(runMode == ACL_HOST){ // Allocate the host buffer inputHostBuff and read the input image to this address. inDevBufferSize is the size of the read image. void* inputHostBuff = nullptr; inputHostBuff = malloc(inDevBufferSize); // Load the input image into the buffer. The ReadPicFile function is defined by the user. ReadPicFile(picName, inputHostBuff, inDevBufferSize); // Allocate the device buffer inDevBuffer_. ret = acldvppMalloc(&inDevBuffer_, inDevBufferSize); // Transfer the input image data to the device by using the aclrtMemcpy call. ret = aclrtMemcpy(inDevBuffer_, inDevBufferSize, inputHostBuff, inDevBufferSize, ACL_MEMCPY_HOST_TO_DEVICE); } else { // Allocate input buffer inDevBuffer_ on the device. ret = acldvppMalloc(&inDevBuffer_, inBufferSize); // Load the input image into the buffer. The ReadPicFile function is defined by the user. ReadPicFile(picName, inDevBuffer_, inBufferSize); } // 6. Allocate decoding output buffer decodeOutDevBuffer_. // Predict the buffer size required for the JPEGD result. uint32_t decodeOutBufferSize = 0; ret = acldvppJpegPredictDecSize(inputHostBuff, inDevBufferSize, PIXEL_FORMAT_YVU_SEMIPLANAR_420, &decodeOutBufferSize) ret = acldvppMalloc(&decodeOutDevBuffer_, decodeOutBufferSize); // Free the buffer in a timely manner. free(inputHostBuff); // 7. Create the description of the decoded image and set the attribute values. // decodeOutputDesc is of type acldvppPicDesc. decodeOutputDesc_ = acldvppCreatePicDesc(); acldvppSetPicDescData(decodeOutputDesc_, decodeOutDevBuffer_); acldvppSetPicDescFormat(decodeOutputDesc_, PIXEL_FORMAT_YUV_SEMIPLANAR_420); acldvppSetPicDescWidth(decodeOutputDesc_, inputWidth_); acldvppSetPicDescHeight(decodeOutputDesc_, inputHeight_); acldvppSetPicDescWidthStride(decodeOutputDesc_, decodeOutWidthStride); acldvppSetPicDescHeightStride(decodeOutputDesc_, decodeOutHeightStride); acldvppSetPicDescSize(decodeOutputDesc_, decodeOutBufferSize); // 8. Perform asynchronous decoding and call aclrtSynchronizeStream to wait for the stream tasks to complete. ret = acldvppJpegDecodeAsync(dvppChannelDesc_, inDevBuffer_, inDevBufferSize, decodeOutputDesc_, stream_); ret = aclrtSynchronizeStream(stream_); // 9. Destroy the allocations, including the description of the output image, output buffer, channel description, and channel. acldvppDestroyPicDesc(decodeOutputDesc_); if(runMode == ACL_HOST){ // In this mode, the processing result is on the device. Therefore, you need to call the memory copy API to transfer the result data, and then free the device buffer. // Allocate host buffer vpcOutHostBuffer. void* vpcOutHostBuffer = nullptr; vpcOutHostBuffer = malloc(decodeOutBufferSize); // Transfer the processing result of the device to the host by using the aclrtMemcpy call. ret = aclrtMemcpy(vpcOutHostBuffer, decodeOutBufferSize, decodeOutDevBuffer_, decodeOutBufferSize, ACL_MEMCPY_DEVICE_TO_HOST); // Free the input and output buffer on the device. (void)acldvppFree(inDevBuffer_); (void)acldvppFree(decodeOutDevBuffer_); // Free the buffer after the data is used. free(vpcOutHostBuffer); } else { // The process is running on the device, and the processing result is also on the device. Free the device buffer when the data is no longer needed. (void)acldvppFree(inDevBuffer_); (void)acldvppFree(decodeOutDevBuffer_); } acldvppDestroyChannel(dvppChannelDesc_); (void)acldvppDestroyChannelDesc(dvppChannelDesc_); dvppChannelDesc_ = nullptr; // 10. Deallocate runtime resources. // 11. Deinitialize AscendCL. // .... |