1e41f4b71Sopenharmony_ci# Temporally Scalable Video Coding
2e41f4b71Sopenharmony_ci
3e41f4b71Sopenharmony_ci## Basic Concepts
4e41f4b71Sopenharmony_ci
5e41f4b71Sopenharmony_ci### Introduction to Temporally Scalable Video Coding
6e41f4b71Sopenharmony_ci
7e41f4b71Sopenharmony_ciScalable video coding is an extended standard for video coding. SVC (short for Scalable Video Coding, an extension of the H.264 standard) and SHVC (short for Scalable High Efficiency Video Coding, an extension of the H.265 standard) are popular nowadays.
8e41f4b71Sopenharmony_ci
9e41f4b71Sopenharmony_ciScalable video coding allows conveyance of information structured in a hierarchical manner of spatial scalability, temporal scalability, and quality scalability.
10e41f4b71Sopenharmony_ci
11e41f4b71Sopenharmony_ciTemporally scalable video coding refers to the process of encoding a video sequence into a set of layers that provide an increasing temporal resolution. The following figure shows the structure of a bitstream that contains four temporal layers and is constructed based on the reference relationship.
12e41f4b71Sopenharmony_ci
13e41f4b71Sopenharmony_ci![Temporal scalability 4 layers](figures/temporal-scalability-4layers.png)
14e41f4b71Sopenharmony_ci
15e41f4b71Sopenharmony_ciIn scenarios where the channel condition is poor, frames can be dropped layer by layer in descending order (L3- > L2- > L1) to meet the changing requirements of transmission and decoding capabilities.
16e41f4b71Sopenharmony_ci
17e41f4b71Sopenharmony_ciThe figure below shows the new bitstream structure when the frames at L3 are dropped. The bitstream can be normally decoded while the frame rate is reduced by half. Dropping can occur at other layers in a similar way.
18e41f4b71Sopenharmony_ci
19e41f4b71Sopenharmony_ci![Temporal scalability 4 layers L3 dropped](figures/temporal-scalability-4layers-L3-dropped.png)
20e41f4b71Sopenharmony_ci
21e41f4b71Sopenharmony_ci### Structure of a Temporally Scalable Bitstream
22e41f4b71Sopenharmony_ciA bitstream is organized by one or more Group of Pictures (GOPs). A GOP is a collection of consecutive pictures that can be independently decoded. It measures the distance between two I-frames (also named key frames).
23e41f4b71Sopenharmony_ci
24e41f4b71Sopenharmony_ciA GOP can be further divided into one or more Temporal Group of Pictures (TGOPs), and each TGOP is composed by a base layer (BL) and one or more associated enhancement layers (ELs). For example, frame 0 to frame 7 in the foregoing four-layer temporally scalable bitstream form a TGOP.
25e41f4b71Sopenharmony_ci
26e41f4b71Sopenharmony_ci- BL: bottom layer (L0) in the GOP. In temporal scalability, this layer is encoded at the lowest frame rate.
27e41f4b71Sopenharmony_ci
28e41f4b71Sopenharmony_ci- EL: layers above the BL. There are L1, L2, and L3 in ascending order. In temporal scalability, the lowest EL encodes, based on encoding information obtained from the BL, the frames at a higher frame rate; a higher EL encodes, based on the BL or a lower EL, the frames at a higher frame rate.
29e41f4b71Sopenharmony_ci
30e41f4b71Sopenharmony_ci### How to Implement the Structure of a Temporally Scalable Bitstream
31e41f4b71Sopenharmony_ci
32e41f4b71Sopenharmony_ciThe temporally scalable bitstream structure is implemented by specifying reference frames, which are classified into the following types based on the duration of residence in a Decoded Picture Buffer (DPB):
33e41f4b71Sopenharmony_ci
34e41f4b71Sopenharmony_ci- Short-Term Reference (STR): a reference frame that cannot reside in the DPB for a long period of time. It adopts the First In First Out (FIFO) approach, which means that the oldest STR is removed from the DPB once the DPB is full.
35e41f4b71Sopenharmony_ci
36e41f4b71Sopenharmony_ci- Long-Term Reference (LTR): a reference frame that can reside in the DPB for a long period of time. It stays in the DPB until it is replaced by another decoded picture with the same ID.
37e41f4b71Sopenharmony_ci
38e41f4b71Sopenharmony_ciAlthough a specific cross-frame reference structure can be implemented when there is more than one STR, the span supported by temporal scalability is limited due to an excessively short validity period. This problem does not exist when coming to the LTR, which also covers the cross-frame scenario of the STR. Therefore, the LTR is preferably used to implement the structure of a temporally scalable bitstream.
39e41f4b71Sopenharmony_ci
40e41f4b71Sopenharmony_ci## When to Use
41e41f4b71Sopenharmony_ciYou are advised to use temporal scalability in the following scenarios:
42e41f4b71Sopenharmony_ci
43e41f4b71Sopenharmony_ci- Real-time encoding and transmission scenarios with no cache or low cache on the playback side, for example, video conferencing, live streaming, and collaborative office.
44e41f4b71Sopenharmony_ci
45e41f4b71Sopenharmony_ci- Video encoding and recording scenario that requires video preview or multi-speed playback.
46e41f4b71Sopenharmony_ci
47e41f4b71Sopenharmony_ciIf your development scenario does not involve dynamic adjustment of the temporal reference structure and the hierarchical structure is simple, you are advised to use [global temporal scalability](#global-temporal-scalability). Otherwise, enable [LTR](#ltr).
48e41f4b71Sopenharmony_ci
49e41f4b71Sopenharmony_ci## Constraints
50e41f4b71Sopenharmony_ci
51e41f4b71Sopenharmony_ci- The global temporal scalability and LTR features are mutually exclusive.
52e41f4b71Sopenharmony_ci
53e41f4b71Sopenharmony_ci  The two features cannot be both enabled because they have normalized bottom-layer implementation.
54e41f4b71Sopenharmony_ci
55e41f4b71Sopenharmony_ci- When using the forcible IDR configuration along with the two features, use the frame channel configuration.
56e41f4b71Sopenharmony_ci
57e41f4b71Sopenharmony_ci  The reference frame is valid only in the GOP. After an I-frame is refreshed, the DPB is cleared, so does the reference frame. In other words, the I-frame refresh location has a great impact on the reference relationship.
58e41f4b71Sopenharmony_ci
59e41f4b71Sopenharmony_ci  When temporal scalability is enabled, to temporarily request the I-frame through **OH_MD_KEY_REQUEST_I_FRAME**, you must configure the frame channel with a determined effective time to notify the framework of the I-frame refresh location, so as to avoid disorder of the reference relationship. For details, see the configuration guide of the frame channel. Do not use **OH_VideoEncoder_SetParameter**, which uses an uncertain effective time.
60e41f4b71Sopenharmony_ci
61e41f4b71Sopenharmony_ci- The callback using **OH_AVBuffer** is supported, but the callback using **OH_AVMemory** is not.
62e41f4b71Sopenharmony_ci
63e41f4b71Sopenharmony_ci  Temporal scalability depends on the frame feature. Do not use **OH_AVMemory** to trigger **OH_AVCodecAsyncCallback**. Instead, use **OH_AVBuffer** to trigger **OH_AVCodecCallback**.
64e41f4b71Sopenharmony_ci
65e41f4b71Sopenharmony_ci- Temporal scalability employs P-pictures, but not B-pictures.
66e41f4b71Sopenharmony_ci
67e41f4b71Sopenharmony_ci  Temporal scalability can be hierarchical-P or hierarchical-B. Currently, this feature can only be hierarchical-P.
68e41f4b71Sopenharmony_ci
69e41f4b71Sopenharmony_ci- In the case of **UNIFORMLY_SCALED_REFERENCE**, TGOP can only be 2 or 4.
70e41f4b71Sopenharmony_ci
71e41f4b71Sopenharmony_ci## Global Temporal Scalability
72e41f4b71Sopenharmony_ci
73e41f4b71Sopenharmony_ci### Available APIs
74e41f4b71Sopenharmony_ci
75e41f4b71Sopenharmony_ciGlobal temporal scalability is suitable for encoding frames into a stable and simple temporal structure. Its initial configuration takes effect globally and cannot be dynamically modified. The configuration parameters are as follows:
76e41f4b71Sopenharmony_ci
77e41f4b71Sopenharmony_ci| Parameter| Description                        |
78e41f4b71Sopenharmony_ci| -------- | ---------------------------- |
79e41f4b71Sopenharmony_ci| OH_MD_KEY_VIDEO_ENCODER_ENABLE_TEMPORAL_SCALABILITY  |  Enabled status of the global temporal scalability feature.|
80e41f4b71Sopenharmony_ci| OH_MD_KEY_VIDEO_ENCODER_TEMPORAL_GOP_SIZE  | TGOP size of the global temporal scalability feature.|
81e41f4b71Sopenharmony_ci| OH_MD_KEY_VIDEO_ENCODER_TEMPORAL_GOP_REFERENCE_MODE  | TGOP reference mode of the global temporal scalability feature. |
82e41f4b71Sopenharmony_ci
83e41f4b71Sopenharmony_ci- **OH_MD_KEY_VIDEO_ENCODER_ENABLE_TEMPORAL_SCALABILITY**: This parameter is set in the configuration phase. The feature can be successfully enabled only when it is supported.
84e41f4b71Sopenharmony_ci
85e41f4b71Sopenharmony_ci- **OH_MD_KEY_VIDEO_ENCODER_TEMPORAL_GOP_SIZE**: This parameter is optional and specifies the distance between two I-frames. You need to customize the I-frame density based on the frame extraction requirements. The value range is [2, GopSize). If no value is passed in, the default value is used.
86e41f4b71Sopenharmony_ci
87e41f4b71Sopenharmony_ci- **OH_MD_KEY_VIDEO_ENCODER_TEMPORAL_GOP_REFERENCE_MODE**: This parameter is optional and affects the reference mode of non-I-frames. The value can be **ADJACENT_REFERENCE**, **JUMP_REFERENCE**, or **UNIFORMLY_SCALED_REFERENCE**. **ADJACENT_REFERENCE** provides better compression performance, whereas **JUMP_REFERENCE** is more flexible in dropping frames. **UNIFORMLY_SCALED_REFERENCE** enables streams to be distributed more evenly in the case of frame loss. If no value is passed in, the default value is used.
88e41f4b71Sopenharmony_ci
89e41f4b71Sopenharmony_ci    > **NOTE**
90e41f4b71Sopenharmony_ci    >
91e41f4b71Sopenharmony_ci    > In the case of **UNIFORMLY_SCALED_REFERENCE**, TGOP can only be 2 or 4.
92e41f4b71Sopenharmony_ci
93e41f4b71Sopenharmony_ciExample 1: TGOP=4, ADJACENT_REFERENCE
94e41f4b71Sopenharmony_ci
95e41f4b71Sopenharmony_ci![Temporal gop 4 adjacent reference](figures/temporal-scalability-tgop4-adjacent.png)
96e41f4b71Sopenharmony_ci
97e41f4b71Sopenharmony_ciExample 2: TGOP=4, JUMP_REFERENCE
98e41f4b71Sopenharmony_ci
99e41f4b71Sopenharmony_ci![TGOP4 jump reference](figures/temporal-scalability-tgop4-jump.png)
100e41f4b71Sopenharmony_ci
101e41f4b71Sopenharmony_ciExample 3: TGOP = 4, UNIFORMLY_SCALED_REFERENCE
102e41f4b71Sopenharmony_ci
103e41f4b71Sopenharmony_ci![TGOP4 uniformly scaled reference](figures/temporal-scalability-tgop4-uniformly.png)
104e41f4b71Sopenharmony_ci
105e41f4b71Sopenharmony_ci### How to Develop
106e41f4b71Sopenharmony_ci
107e41f4b71Sopenharmony_ciThis section describes only the steps that are different from the basic encoding process. You can learn the basic encoding process in [Video Encoding](video-encoding.md).
108e41f4b71Sopenharmony_ci
109e41f4b71Sopenharmony_ci1. When creating an encoder instance, check whether the video encoder supports the global temporal scalability feature.
110e41f4b71Sopenharmony_ci
111e41f4b71Sopenharmony_ci    ```c++
112e41f4b71Sopenharmony_ci    // 1.1 Obtain the handle to the capability of the video encoder. The following uses H.264 as an example.
113e41f4b71Sopenharmony_ci    OH_AVCapability *cap = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true);
114e41f4b71Sopenharmony_ci    // 1.2 Check whether the global temporal scalability feature is supported.
115e41f4b71Sopenharmony_ci    bool isSupported = OH_AVCapability_isFeatureSupported(cap, VIDEO_ENCODER_TEMPORAL_SCALABILITY);
116e41f4b71Sopenharmony_ci    ```
117e41f4b71Sopenharmony_ci
118e41f4b71Sopenharmony_ci    If the feature is supported, it can be enabled.
119e41f4b71Sopenharmony_ci
120e41f4b71Sopenharmony_ci2. In the configuration phase, configure the parameters related to the global temporal scalability feature.
121e41f4b71Sopenharmony_ci
122e41f4b71Sopenharmony_ci    ```c++
123e41f4b71Sopenharmony_ci    constexpr int32_t TGOP_SIZE = 3; 
124e41f4b71Sopenharmony_ci    // 2.1 Create a temporary AV format used for configuration.
125e41f4b71Sopenharmony_ci    OH_AVFormat *format = OH_AVFormat_Create();
126e41f4b71Sopenharmony_ci    // 2.2 Fill in the key-value pair of the parameter used to enable the feature.
127e41f4b71Sopenharmony_ci    OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_ENABLE_TEMPORAL_SCALABILITY, 1);
128e41f4b71Sopenharmony_ci    // 2.3 (Optional) Fill in the key-value pairs of the parameters that specify the TGOP size and reference mode.
129e41f4b71Sopenharmony_ci    OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_TEMPORAL_GOP_SIZE, TGOP_SIZE);
130e41f4b71Sopenharmony_ci    OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_TEMPORAL_GOP_REFERENCE_MODE, ADJACENT_REFERENCE);
131e41f4b71Sopenharmony_ci    // 2.4 Configure the parameters.
132e41f4b71Sopenharmony_ci    int32_t ret = OH_VideoEncoder_Configure(videoEnc, format);
133e41f4b71Sopenharmony_ci    if (ret != AV_ERR_OK) {
134e41f4b71Sopenharmony_ci        // Exception handling.
135e41f4b71Sopenharmony_ci    }
136e41f4b71Sopenharmony_ci    // 2.5 Destroy the temporary AV format after the configuration is complete.
137e41f4b71Sopenharmony_ci    OH_AVFormat_Destroy(format);
138e41f4b71Sopenharmony_ci    ```
139e41f4b71Sopenharmony_ci
140e41f4b71Sopenharmony_ci3. (Optional) During output rotation in the running phase, obtain the temporal layer information corresponding to the bitstream.
141e41f4b71Sopenharmony_ci
142e41f4b71Sopenharmony_ci    You can periodically obtain the number of encoded frames based on the configured TGOP parameters.
143e41f4b71Sopenharmony_ci
144e41f4b71Sopenharmony_ci    The sample code is as follows:
145e41f4b71Sopenharmony_ci
146e41f4b71Sopenharmony_ci    ```c++
147e41f4b71Sopenharmony_ci    uint32_t outPoc = 0;
148e41f4b71Sopenharmony_ci    // Obtain the relative position in the TGOP based on the number of valid frames in the output callback and determine the layer based on the configuration.
149e41f4b71Sopenharmony_ci    static void OnNewOutputBuffer(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData)
150e41f4b71Sopenharmony_ci    {
151e41f4b71Sopenharmony_ci        // Note: If complex processing is involved, you are advised to create an association.
152e41f4b71Sopenharmony_ci        struct OH_AVCodecBufferAttr attr;
153e41f4b71Sopenharmony_ci        (void)buffer->GetBufferAttr(attr);
154e41f4b71Sopenharmony_ci        // Set POC to 0 after the I-frame is refreshed.
155e41f4b71Sopenharmony_ci        if (attr.flags & AVCODEC_BUFFER_FLAG_KEY_FRAME) {
156e41f4b71Sopenharmony_ci            outPoc = 0;
157e41f4b71Sopenharmony_ci        }
158e41f4b71Sopenharmony_ci        // Skip the process when there is only the XPS output, but no frame stream.
159e41f4b71Sopenharmony_ci        if (attr.flags != AVCODEC_BUFFER_FLAG_CODEC_DATA) {
160e41f4b71Sopenharmony_ci            int32_t tGopInner = outPoc % TGOP_SIZE;
161e41f4b71Sopenharmony_ci            if (tGopInner == 0) {
162e41f4b71Sopenharmony_ci                // I-frames cannot be dropped in subsequent transmission and decoding processes.
163e41f4b71Sopenharmony_ci            } else {
164e41f4b71Sopenharmony_ci                // Non-I-frames can be dropped in subsequent transmission and decoding processes.
165e41f4b71Sopenharmony_ci            }
166e41f4b71Sopenharmony_ci            outPoc++;
167e41f4b71Sopenharmony_ci        }
168e41f4b71Sopenharmony_ci    }
169e41f4b71Sopenharmony_ci    ```
170e41f4b71Sopenharmony_ci
171e41f4b71Sopenharmony_ci4. (Optional) During output rotation in the running phase, use the temporal layer information obtained for adaptive transmission or decoding.
172e41f4b71Sopenharmony_ci
173e41f4b71Sopenharmony_ci    Based on the temporally scalable bitstream and layer information, select a required layer for transmission, or carry the information to the peer for adaptive decoding.
174e41f4b71Sopenharmony_ci
175e41f4b71Sopenharmony_ci## LTR
176e41f4b71Sopenharmony_ci
177e41f4b71Sopenharmony_ci### Available APIs
178e41f4b71Sopenharmony_ci
179e41f4b71Sopenharmony_ciThe LTR feature provides a flexible configuration of the frame-level reference relationship. It is suitable for flexible and complex temporally hierarchical structures.
180e41f4b71Sopenharmony_ci
181e41f4b71Sopenharmony_ci| Parameter| Description                |
182e41f4b71Sopenharmony_ci| -------- | ---------------------------- |
183e41f4b71Sopenharmony_ci| OH_MD_KEY_VIDEO_ENCODER_LTR_FRAME_COUNT  |  Number of LTR frames.|
184e41f4b71Sopenharmony_ci| OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_MARK_LTR  | Marked as an LTR frame.|
185e41f4b71Sopenharmony_ci| OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_USE_LTR   | Number of the LTR frame referenced by the current frame. |
186e41f4b71Sopenharmony_ci
187e41f4b71Sopenharmony_ci- **OH_MD_KEY_VIDEO_ENCODER_LTR_FRAME_COUNT**: This parameter is set in the configuration phase and must be less than or equal to the maximum number of LTR frames supported.
188e41f4b71Sopenharmony_ci- **OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_MARK_LTR **: The BL layer is marked as an LTR frame, and the EL layer to skip is also marked as an LTR frame.
189e41f4b71Sopenharmony_ci- **OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_USE_LTR **: Number of the frame marked as the LTR frame.
190e41f4b71Sopenharmony_ci
191e41f4b71Sopenharmony_ciFor example, to implement the four-layer temporally hierarchical structure described in [Introduction to Temporally Scalable Video Coding](#introduction-to-temporally-scalable-video-coding), perform the following steps:
192e41f4b71Sopenharmony_ci
193e41f4b71Sopenharmony_ci1. In the configuration phase, set **OH_MD_KEY_VIDEO_ENCODER_LTR_FRAME_COUNT** to **5**.
194e41f4b71Sopenharmony_ci
195e41f4b71Sopenharmony_ci2. In the input rotation of the running phase, configure the LTR parameters according to the following table, where **\** means that no configuration is required.
196e41f4b71Sopenharmony_ci
197e41f4b71Sopenharmony_ci    | Configuration\POC| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
198e41f4b71Sopenharmony_ci    | -------- |---|---|---|---|---|---|---|---|---|---|----|----|----|----|----|----|----|
199e41f4b71Sopenharmony_ci    | MARK_LTR | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0  | 0  | 1  | 0  | 0  | 0  | 1  |
200e41f4b71Sopenharmony_ci    | USE_LTR  | \ | \ | 0 | \ | 0 | \ | 4 | \ | 0 | \ | 8  | \  | 8  | \  | 12 | 0  | 8  |
201e41f4b71Sopenharmony_ci
202e41f4b71Sopenharmony_ci### How to Develop
203e41f4b71Sopenharmony_ci
204e41f4b71Sopenharmony_ciThis section describes only the steps that are different from the basic encoding process. You can learn the basic encoding process in [Video Encoding](video-encoding.md).
205e41f4b71Sopenharmony_ci
206e41f4b71Sopenharmony_ci1. When creating an encoder instance, check whether the video encoder supports the LTR feature.
207e41f4b71Sopenharmony_ci
208e41f4b71Sopenharmony_ci    ```c++
209e41f4b71Sopenharmony_ci    constexpr int32_t NEEDED_LTR_COUNT = 5;
210e41f4b71Sopenharmony_ci    bool isSupported = false;
211e41f4b71Sopenharmony_ci    int32_t supportedLTRCount = 0;
212e41f4b71Sopenharmony_ci    // 1.1 Obtain the handle to the capability of the encoder. The following uses H.264 as an example.
213e41f4b71Sopenharmony_ci    OH_AVCapability *cap = OH_AVCodec_GetCapability(OH_AVCODEC_MIMETYPE_VIDEO_AVC, true);
214e41f4b71Sopenharmony_ci    // 1.2 Check whether the LTR feature is supported.
215e41f4b71Sopenharmony_ci    isSupported = OH_AVCapability_isFeatureSupported(cap, VIDEO_ENCODER_LONG_TERM_REFERENCE);
216e41f4b71Sopenharmony_ci    // 1.3 Determine the number of supported LTR frames.
217e41f4b71Sopenharmony_ci    if (isSupported) {
218e41f4b71Sopenharmony_ci        OH_AVFormat *properties = OH_AVCapability_GetFeatureProperties(cap, VIDEO_ENCODER_LONG_TERM_REFERENCE);
219e41f4b71Sopenharmony_ci        OH_AVFormat_GetIntValue(properties, OH_FEATURE_PROPERTY_KEY_VIDEO_ENCODER_MAX_LTR_FRAME_COUNT, &supportedLTRCount);
220e41f4b71Sopenharmony_ci        OH_AVFormat_Destroy(properties);
221e41f4b71Sopenharmony_ci        // 1.4 Check whether the number of supported LTR frames meets the structure requirements.
222e41f4b71Sopenharmony_ci        isSupported = supportedLTRCount >= NEEDED_LTR_COUNT;
223e41f4b71Sopenharmony_ci    }
224e41f4b71Sopenharmony_ci    ```
225e41f4b71Sopenharmony_ci
226e41f4b71Sopenharmony_ci    If the LTR feature is supported and the number of supported LTR frames meets the requirements, the feature can be enabled.
227e41f4b71Sopenharmony_ci
228e41f4b71Sopenharmony_ci2. Register the frame channel callback functions.
229e41f4b71Sopenharmony_ci
230e41f4b71Sopenharmony_ci    The following is an example of the configuration in buffer input mode:
231e41f4b71Sopenharmony_ci
232e41f4b71Sopenharmony_ci    ```c++
233e41f4b71Sopenharmony_ci    // 2.1 Implement the OH_AVCodecOnNeedInputBuffer callback function.
234e41f4b71Sopenharmony_ci    static void OnNeedInputBuffer(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData)
235e41f4b71Sopenharmony_ci    {
236e41f4b71Sopenharmony_ci        // The index of the input frame buffer is sent to InIndexQueue.
237e41f4b71Sopenharmony_ci        // The input frame data (specified by buffer) is sent to InBufferQueue.
238e41f4b71Sopenharmony_ci        // Perform data processing. For details, see:
239e41f4b71Sopenharmony_ci        // - Write the stream to encode.
240e41f4b71Sopenharmony_ci        // - Notify the encoder of EOS.
241e41f4b71Sopenharmony_ci        // - Write the frame parameter.
242e41f4b71Sopenharmony_ci        OH_AVFormat *format = OH_AVBuffer_GetParameter(buffer);
243e41f4b71Sopenharmony_ci        OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_MARK_LTR, 1);
244e41f4b71Sopenharmony_ci        OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_USE_LTR, 4);
245e41f4b71Sopenharmony_ci        OH_AVBuffer_SetParameter(buffer, format);
246e41f4b71Sopenharmony_ci        // Notify the encoder that the buffer input is complete.
247e41f4b71Sopenharmony_ci        OH_VideoEncoder_PushInputBuffer(codec, index);
248e41f4b71Sopenharmony_ci    }
249e41f4b71Sopenharmony_ci
250e41f4b71Sopenharmony_ci    // 2.2 Implement the OH_AVCodecOnNewOutputBuffer callback function.
251e41f4b71Sopenharmony_ci    static void OnNewOutputBuffer(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData)
252e41f4b71Sopenharmony_ci    {
253e41f4b71Sopenharmony_ci        // The index of the output frame buffer is sent to outIndexQueue.
254e41f4b71Sopenharmony_ci        // The encoded frame data (specified by buffer) is sent to outBufferQueue.
255e41f4b71Sopenharmony_ci        // Perform data processing. For details, see:
256e41f4b71Sopenharmony_ci        // - Release the encoded frame.
257e41f4b71Sopenharmony_ci        // - Record POC and the enabled status of LTR.
258e41f4b71Sopenharmony_ci    }
259e41f4b71Sopenharmony_ci
260e41f4b71Sopenharmony_ci    // 2.3 Register the callback functions.
261e41f4b71Sopenharmony_ci    OH_AVCodecCallback cb;
262e41f4b71Sopenharmony_ci    cb.onNeedInputBuffer = OnNeedInputBuffer;
263e41f4b71Sopenharmony_ci    cb.onNewOutputBuffer = OnNewOutputBuffer;
264e41f4b71Sopenharmony_ci    OH_VideoEncoder_RegisterCallback(codec, cb, nullptr);
265e41f4b71Sopenharmony_ci    ```
266e41f4b71Sopenharmony_ci
267e41f4b71Sopenharmony_ci    The following is an example of the configuration in surface input mode:
268e41f4b71Sopenharmony_ci
269e41f4b71Sopenharmony_ci    ```c++
270e41f4b71Sopenharmony_ci    // 2.1 Implement the OH_VideoEncoder_OnNeedInputParameter callback function.
271e41f4b71Sopenharmony_ci    static void OnNeedInputParameter(OH_AVCodec *codec, uint32_t index, OH_AVFormat *parameter, void *userData)
272e41f4b71Sopenharmony_ci    {
273e41f4b71Sopenharmony_ci        // The index of the input frame buffer is sent to InIndexQueue.
274e41f4b71Sopenharmony_ci        // The input frame data (specified by avformat) is sent to InFormatQueue.
275e41f4b71Sopenharmony_ci        // Perform data processing. For details, see:
276e41f4b71Sopenharmony_ci        // - Write the stream to encode.
277e41f4b71Sopenharmony_ci        // - Notify the encoder of EOS.
278e41f4b71Sopenharmony_ci        // - Write the frame parameter.
279e41f4b71Sopenharmony_ci        OH_AVFormat_SetIntValue(parameter, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_MARK_LTR, 1);
280e41f4b71Sopenharmony_ci        OH_AVFormat_SetIntValue(parameter, OH_MD_KEY_VIDEO_ENCODER_PER_FRAME_USE_LTR, 4);
281e41f4b71Sopenharmony_ci        // Notify the encoder that the frame input is complete.
282e41f4b71Sopenharmony_ci        OH_VideoEncoder_PushInputParameter(codec, index);
283e41f4b71Sopenharmony_ci    }
284e41f4b71Sopenharmony_ci
285e41f4b71Sopenharmony_ci    // 2.2 Implement the OH_AVCodecOnNewOutputBuffer callback function.
286e41f4b71Sopenharmony_ci    static void OnNewOutputBuffer(OH_AVCodec *codec, uint32_t index, OH_AVBuffer *buffer, void *userData)
287e41f4b71Sopenharmony_ci    {
288e41f4b71Sopenharmony_ci        // The index of the output frame buffer is sent to outIndexQueue.
289e41f4b71Sopenharmony_ci        // The encoded frame data (specified by buffer) is sent to outBufferQueue.
290e41f4b71Sopenharmony_ci        // Perform data processing. For details, see:
291e41f4b71Sopenharmony_ci        // - Release the encoded frame.
292e41f4b71Sopenharmony_ci        // - Record POC and the enabled status of LTR.
293e41f4b71Sopenharmony_ci    }
294e41f4b71Sopenharmony_ci
295e41f4b71Sopenharmony_ci    // 2.3 Register the callback functions.
296e41f4b71Sopenharmony_ci    OH_AVCodecCallback cb;
297e41f4b71Sopenharmony_ci    cb.onNewOutputBuffer = OnNewOutputBuffer;
298e41f4b71Sopenharmony_ci    OH_VideoEncoder_RegisterCallback(codec, cb, nullptr);
299e41f4b71Sopenharmony_ci    // 2.4 Register the frame channel callback functions.
300e41f4b71Sopenharmony_ci    OH_VideoEncoder_OnNeedInputParameter inParaCb = OnNeedInputParameter;
301e41f4b71Sopenharmony_ci    OH_VideoEncoder_RegisterParameterCallback(codec, inParaCb, nullptr);
302e41f4b71Sopenharmony_ci    ```
303e41f4b71Sopenharmony_ci
304e41f4b71Sopenharmony_ci3. In the configuration phase, configure the maximum number of LTR frames.
305e41f4b71Sopenharmony_ci
306e41f4b71Sopenharmony_ci    ```c++
307e41f4b71Sopenharmony_ci    constexpr int32_t TGOP_SIZE = 3;
308e41f4b71Sopenharmony_ci    // 3.1 Create a temporary AV format used for configuration.
309e41f4b71Sopenharmony_ci    OH_AVFormat *format = OH_AVFormat_Create();
310e41f4b71Sopenharmony_ci    // 3.2 Fill in the key-value pair of the parameter that specifies the number of LTR frames.
311e41f4b71Sopenharmony_ci    OH_AVFormat_SetIntValue(format, OH_MD_KEY_VIDEO_ENCODER_LTR_FRAME_COUNT, NEEDED_LTR_COUNT);
312e41f4b71Sopenharmony_ci    // 3.3 Configure the parameters.
313e41f4b71Sopenharmony_ci    int32_t ret = OH_VideoEncoder_Configure(videoEnc, format);
314e41f4b71Sopenharmony_ci    if (ret != AV_ERR_OK) {
315e41f4b71Sopenharmony_ci        // Exception handling.
316e41f4b71Sopenharmony_ci    }
317e41f4b71Sopenharmony_ci    // 3.4 Destroy the temporary AV format after the configuration is complete.
318e41f4b71Sopenharmony_ci    OH_AVFormat_Destroy(format);
319e41f4b71Sopenharmony_ci    ```
320e41f4b71Sopenharmony_ci
321e41f4b71Sopenharmony_ci4. (Optional) During output rotation in the running phase, obtain the temporal layer information corresponding to the bitstream.
322e41f4b71Sopenharmony_ci
323e41f4b71Sopenharmony_ci    This procedure is the same as that described in the global temporal scalability feature.
324e41f4b71Sopenharmony_ci
325e41f4b71Sopenharmony_ci    The LTR parameters are configured in the input rotation. You can also record the LTR parameters in the input rotation and find the corresponding input parameters in the output rotation.
326e41f4b71Sopenharmony_ci
327e41f4b71Sopenharmony_ci5. (Optional) During output rotation in the running phase, use the temporal layer information obtained for adaptive transmission or decoding.
328e41f4b71Sopenharmony_ci
329e41f4b71Sopenharmony_ci    This procedure is the same as that described in the global temporal scalability feature.
330