• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Concurrently Creating a Video Decoder and Initializing NativeWindow
2
3<!--Kit: AVCodec Kit-->
4<!--Subsystem: Multimedia-->
5<!--Owner: @zhanghongran-->
6<!--Designer: @dpy2650--->
7<!--Tester: @cyakee-->
8<!--Adviser: @zengyawen-->
9
10## When to Use
11
12To ensure that a video decoder can be created and run properly in surface mode, you can create an empty surface before the **XComponent** is created or the OpenGL post-processing (NativeImage) is initialized.
13
14
15## How to Develop
16
17The following describes how to concurrently create a video decoder and initialize NativeWindow. This approach ensures that the video decoder can be set up and executed properly, even before the surface consumer is ready.
18
19**Linking Dynamic Libraries**
20
21``` cmake
22target_link_libraries(sample PUBLIC libnative_image.so)
23target_link_libraries(sample PUBLIC libnative_window.so)
24target_link_libraries(sample PUBLIC libnative_buffer.so)
25target_link_libraries(sample PUBLIC libnative_media_vdec.so)
26```
27
28> **NOTE**
29>
30> The word **sample** in the preceding code snippet is only an example. Use the actual project directory name.
31>
32
33**Including Header Files**
34
35```c++
36#include <iostream>
37#include <string>
38#include <native_image/native_image.h>
39#include <native_window/external_window.h>
40#include <native_buffer/native_buffer.h>
41#include <multimedia/player_framework/native_avcodec_videodecoder.h>
42```
43
441. Create an OH_NativeImage instance.
45
46    ```c++
47    // Create a NativeImage instance as the surface consumer.
48    OH_NativeImage* image = OH_ConsumerSurface_Create();
49    ```
50
512. Obtain the NativeWindow instance that functions as the producer.
52
53    ```c++
54    // Obtain a NativeWindow instance.
55    OHNativeWindow* nativeImageWindow = OH_NativeImage_AcquireNativeWindow(image);
56    ```
57
583. Set the width and height of the NativeWindow instance.
59
60    ```c++
61    int code = SET_BUFFER_GEOMETRY;
62    int32_t width = 800;
63    int32_t height = 600;
64    int32_t ret = OH_NativeWindow_NativeWindowHandleOpt(nativeImageWindow, code, width, height);
65    if (ret != AV_ERR_OK) {
66        // Handle exceptions.
67    }
68    ```
69
704. Register a callback function for the NativeImage instance.
71
72    Register the **OH_OnFrameAvailableListener**, which contains the following parameters:
73
74    - **context**: user-defined context information.
75    - **onFrameAvailable**: callback function triggered when a frame is available.
76
77    ```c++
78    // Implement onFrameAvailable.
79    static void onFrameAvailable()
80    {
81      OHNativeWindowBuffer *buffer = nullptr;
82      int fenceFd;
83      // Obtain an OHNativeWindowBuffer instance through the OH_NativeImage instance on the consumer side.
84      OH_NativeImage_AcquireNativeWindowBuffer(image, &buffer, &fenceFd);
85      // Release the OHNativeWindowBuffer instance through the OH_NativeImage instance.
86      OH_NativeImage_ReleaseNativeWindowBuffer(image, buffer, fenceFd);
87    }
88
89    static void context()
90    {
91      // Customize the context information.
92    }
93
94    // Set a listener.
95    OH_OnFrameAvailableListener listener = {&onFrameAvailable, &context};
96    // Register the listener to listen for frame availability events.
97    ret = OH_NativeImage_SetOnFrameAvailableListener(image, listener);
98    if (ret != AV_ERR_OK) {
99        // Handle exceptions.
100    }
101    ```
102
103    > **NOTE**
104    >
105    > In this example, the callback function just retrieves and releases the buffer. You can customize and expand the callback function based on service requirements.
106    >
107
1085. Configure the decoder.
109
110    For details, see step 5 in [Video Decoding in Surface Mode](video-decoding.md#surface-mode).
111
1126. Set the surface.
113
114    Before the actual surface consumer is created, you can use the temporarily created consumer to connect to the decoder.
115
116    In the code snippet below, the following variables are used:
117    - **videoDec**: pointer to the video decoder instance. For details, see step 2 in [Video Decoding in Surface Mode](video-decoding.md#surface-mode).
118
119    ```c++
120
121    ret = OH_VideoDecoder_SetSurface(videoDec, nativeImageWindow);
122    if (ret != AV_ERR_OK) {
123        // Handle exceptions.
124    }
125    ```
126
1277. Start the decoder.
128
129    For details, see step 8 in [Video Decoding in Surface Mode](video-decoding.md#surface-mode).
130
131
1328. Set the surface.
133
134    After the actual surface consumer is created, call **OH_VideoDecoder_SetSurface** to redirect the decoded output to the new surface.
135
136    You can obtain NativeWindow in either of the following ways:
137    - If the image is directly displayed after being decoded, obtain NativeWindow from the **XComponent**. For details about the operation, see [XComponent](../../reference/apis-arkui/arkui-ts/ts-basic-components-xcomponent.md).
138    - If OpenGL post-processing is performed after decoding, obtain NativeWindow from NativeImage. For details about the operation, see [NativeImage](../../graphics/native-image-guidelines.md).
139
140    ```c++
141
142    ret = OH_VideoDecoder_SetSurface(videoDec, nativeWindow);
143    if (ret != AV_ERR_OK) {
144        // Handle exceptions.
145    }
146    ```
147
1489. Destroy the OH_NativeImage instance.
149
150   After calling **OH_VideoDecoder_Destroy**, call **OH_NativeImage_Destroy** to destroy the OH_NativeImage instance.
151   ```c++
152   // Destroy the OH_NativeImage instance.
153   OH_NativeImage_Destroy(&image);
154   ```
155