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 Functions and Restrictions.

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 AscendCL API Call Sequence.

Figure 1 PNG image decoding

The current system supports PNG image decoding and output of RGB and RGBA images. The key APIs are described as follows:

  1. Call acldvppCreateChannel to create an image processing channel.

    Before creating a channel, call acldvppCreateChannelDesc to create a channel description.

  2. Before PNG decoding, call acldvppMalloc to allocate device memory as input and output buffers.

    Before allocating output buffer, call acldvppPngPredictDecSize to predict the required buffer allocation for the decoding output based on the size of the PNG image.

  3. Call acldvppPngDecodeAsync to run asynchronous decoding.

    Call aclrtSynchronizeStream to wait for the stream tasks to complete.

  4. After the decoding is complete, call acldvppFree to free the input and output buffers in a timely manner.
  5. Call acldvppDestroyChannel to destroy the image processing channel.

    After destroying the channel, call acldvppDestroyChannelDesc to destroy the channel description.

Sample Code

This section focuses on the code logic for decoding PNGD 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
// 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_, inDevBufferSize);
    // Load the input image into the buffer. The ReadPicFile function is defined by the user.
    ReadPicFile(picName, inDevBuffer_, inDevBufferSize);
}

// 6. Allocate decoding output buffer decodeOutDevBuffer_.
// Calculate the buffer size required for the PNGD processing result.
uint32_t decodeOutBufferSize = 0;
ret = acldvppPngPredictDecSize(inputHostBuff, inDevBufferSize, PIXEL_FORMAT_RGB_888, &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_RGB_888); 
acldvppSetPicDescSize(decodeOutputDesc_, decodeOutBufferSize);

// 8. Perform asynchronous decoding and call aclrtSynchronizeStream to wait for the stream tasks to complete.
ret = acldvppPngDecodeAsync(dvppChannelDesc_, inDevBuffer_, inDevBufferSize, decodeOutputDesc_, stream_);
ret = aclrtSynchronizeStream(stream_);

// 9. Destroy the allocations, including the description of the output images, 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 OutHostBuffer.
    void* OutHostBuffer = nullptr;
    OutHostBuffer = malloc(decodeOutBufferSize);
    // Transfer the processing result of the device to the host by using the aclrtMemcpy call.
    ret = aclrtMemcpy(OutHostBuffer, 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(OutHostBuffer);
} 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.

// ....