PNGD
This section describes the API call sequence of PNGD, and sample code is also provided to help you better understand the process.
The PNG decoder (PNGD) decodes images in PNG format. For details about the PNGD functions and restrictions, see PNG Decoder (PNGD).
API Call Sequence
If PNG 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 API Call Sequence.
The system supports decoding PNG images. The key APIs are described as follows:
- Call hi_mpi_sys_init to initialize the media data processing system.
- Call hi_mpi_pngd_create_chn to create a channel.
- Call hi_mpi_dvpp_malloc to allocate the device buffer to store the input or output data.
On the
Atlas 200I/500 A2 inference products , aclrtMalloc can be used to allocate buffers.On the
Atlas A2 training products /Atlas A2 inference products , aclrtMalloc can be used to allocate buffers.hi_mpi_dvpp_malloc allocates a dedicated buffer for processing media data. However, the address space of the dedicated buffer is limited. If buffer planning is cared or buffer resources are limited, you are advised to allocate buffer by calling aclrtMalloc.
- Call hi_mpi_pngd_send_stream to send the streams to be decoded. hi_mpi_pngd_send_stream is an asynchronous API. The API call only delivers a task. You also need to call hi_mpi_pngd_get_image_data to obtain the decode result data.
- Call hi_mpi_dvpp_free to free the input and output buffers.
On the
Atlas 200I/500 A2 inference products , if aclrtMalloc is used to allocate buffers, aclrtFree needs to be used to free buffers.On the
Atlas A2 training products /Atlas A2 inference products , if aclrtMalloc is used to allocate buffers, aclrtFree needs to be used to free buffers. - Call hi_mpi_pngd_destroy_chn to destroy the channel.
- Call hi_mpi_sys_exit to deinitialize the media data processing system.
Sample Code
You can view the complete code in Media Data Processing V2 (PNGD Image Decoding).
This section focuses on the code logic for decoding PNGD images. For details about how to perform initialization and deinitialization, see Initialization and Deinitialization. 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 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 113 |
// 1. Perform initialization. // 2. Allocate runtime resources. // 3. Initialize the media data processing system. int32_t ret = hi_mpi_sys_init(); // 4. Create a channel. hi_pngd_chn chnId; hi_pngd_chn_attr chnAttr; // hi_pngd_chn_attr is a reserved parameter and does not need to be set. ret = hi_mpi_pngd_create_chn(chnId, &chnAttr); // 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); //If the run mode is ACL_HOST, allocate the host buffer, load the input image data into the host buffer, and call aclrtMemcpy to transfer the host image data to the device. After the data transfer is complete, free the host buffer in a timely manner. In other modes, directly load the input image data into the device buffer. // runMode indicates the running mode of the software stack, which can be obtained through aclrtGetRunMode. if (runMode == ACL_HOST) { void* hostInputAddr = nullptr; //Allocate the host buffer. aclRet = aclrtMallocHost(&hostInputAddr, inputSize); // Load the input image into the buffer. The ReadStreamFile function is defined by the user. ReadStreamFile(fileName, hostInputAddr, inputSize); // Transfer data. aclRet = aclrtMemcpy(inputAddr, inputSize, hostInputAddr, inputSize, ACL_MEMCPY_HOST_TO_DEVICE); } else { // 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_img_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.type = HI_PT_PNG; ret = hi_mpi_png_get_image_info(&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_pic_info outPicInfo{}; void *outBuffer = nullptr; outPicInfo.picture_width = stImgInfo.width; outPicInfo.picture_height = stImgInfo.height; outPicInfo.picture_width_stride = stImgInfo.width_stride; outPicInfo.picture_height_stride = stImgInfo.height_stride; outPicInfo.picture_buffer_size = stImgInfo.img_buf_size; outPicInfo.picture_format = HI_PIXEL_FORMAT_UNKNOWN; ret = hi_mpi_dvpp_malloc(0, &outBuffer, outPicInfo.buffer_size); outPicInfo.picture_address = (uint64_t)outBuffer; // 5.4 Send the input image to be decoded. ret = hi_mpi_pngd_send_stream(chnId, &stream, &outPicInfo, 0); // 6. Receive the decoding result. // 6.1 Obtain the decoding result. hi_pic_info picInfo; hi_img_stream stream; ret = hi_mpi_pngd_get_image_data(chnId, &picInfo, &stream, 0); if (ret == HI_SUCCESS) { // Decode success printf("[%s][%d] Chn %u GetFrame Success, Decode Success \n",__FUNCTION__, __LINE__, chnId); } else if (ret == HI_ERR_PNGD_BUF_EMPTY){ // Decoding printf("[%s][%d] Chn %u Decoding, try again \n",__FUNCTION__, __LINE__, chnId); } else { // Decode fail printf("[%s][%d] Chn %u GetFrame Success, Decode Fail \n",__FUNCTION__, __LINE__, chnId); } // 6.2 If the run mode is ACL_HOST and the image data output by PNGD needs to be displayed on the host, allocate the host buffer and call aclrtMemcpy to transfer the output image data from the device to the host. if (g_runMode == ACL_HOST) { void* hostOutputAddr = nullptr; aclRet = aclrtMallocHost(&hostOutputAddr, outputSize); aclRet = aclrtMemcpy(hostOutputAddr, outputSize, frame.v_frame.virt_addr[0], outputSize, ACL_MEMCPY_DEVICE_TO_HOST); // ...... // After data is used, free the buffer in a timely manner. aclrtFreeHost(hostOutputAddr); hostOutputAddr = nullptr; } else { // You can directly use the output image data of PNGD in the buffer specified by outputPic.picture_address. // ...... } // 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); // 7. Destroy the channel. ret = hi_mpi_pngd_destroy_chn(chnId); // 8. Deinitialize the media data processing system. ret = hi_mpi_sys_exit(); // 9. Deallocate runtime resources. // 10. Perform deinitialization. // .... |