Video Encoding

Function Description

You can implement video encoding by constructing an instance of the VideoEncoder class. For details about the encoding configuration items and restrictions, see VideoEncodeConfig.

Video encoding supports customized output data formats. You can use a customized callback function to input the encoding configuration items to use the encoded data. For details, see VencCallBacker.

For details about video encoding APIs, see VideoEncoder.

API Calling Process

Define the output data combination mode as required, refer to VencCallBacker to define the callback function, and input encoding configuration items. Instantiate the VideoEncoder class, and call the member function of encode to complete encoding and obtain data.

The following figure shows the process of calling APIs of video encoding.

Figure 1 Process of calling APIs of video encoding

Vision SDK provides the VideoEncoder class for video encoding. The key steps are described as follows:

  1. Perform global initialization by calling mx_init().
  2. Define the output data combination mode.
    • The output data includes the Image class data obtained after video frames are encoded, frameId of the current encoded frame, and channelId.
    • Determine the preceding data to be obtained as required.
  3. Define the output callback function.
    • Define the callback function based on the data to be obtained and assemble the customized data in the function.
    • The input parameter of the callback function is fixed in callback_func format. The output is optional in the function.
    • You are advised to use the custom userData to receive the video encoding callback result, and not to perform complex operations in the callback function. Otherwise, the callback thread is suspended, and the video encoding speed becomes slow.
  4. Construct video encoding configuration items.

    For details about the configuration items and restrictions, see the data structure description of VideoEncodeConfig.

  5. Instantiate the video encoding class.

    Input the configured VideoEncodeConfig to the constructor API to instantiate the video encoding class.

  6. Call the encode API to encode the video.
  7. Perform deinitialization by calling mx_deinit().

Sample Code

The following is a code example of key steps, which is for reference only and cannot be directly copied for execution.
 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
import os
import numpy as np
import time
from mindx.sdk import base
from mindx.sdk.base import Image, ImageProcessor
from mindx.sdk.base import VideoEncoder, VideoEncodeConfig, VencCallBacker 

# Video encoding callback function
def venc_callback(pyChar, outDataSize, channelId, frameId):
    with open('video_save_data/output.h264', 'ab') as file:  
        file.write(pyChar)
  
def process():
    # Initialize the VencCallBacker class and register the callback function.
    vencCallBacker = VencCallBacker()  
    vencCallBacker.registerVencCallBack(venc_callback)  
    # Initialize VideoEncodeConfig.
    venc_conf = VideoEncodeConfig()  
    venc_conf.keyFrameInterval = 50  # I-frame interval.
   venc_conf.srcRate = 30 # Frame rate of the input stream, in fps.
    venc_conf.maxBitRate = 6000  # Output bit rate, in kbps.
    venc_conf.ipProp = 30 # Ratio of the number of bits in an I-frame to the number of bits in a P-frame in a GOP.
    venc_conf.rcMode = 0 # Bit rate control mode, which can be cbr 0/1, vbr 2, avbr 3, qvbr 4, or cvbr 5.
    venc_conf.sceneMode = 0  # 0: a scene in which the camera does not move or moves periodically and continuously; H.264 and H.265 are supported. 1: a motion scene in which the bit rate is high; H.265 is supported.
    venc_conf.displayRate = 30 # Display rate of the output video
    venc_conf.shortTermStatsTime = 40  # Short-term statistical time of the bit rate (in seconds). The value range is [1, 120]. It takes effect when rcMode is set to 5.
    venc_conf.longTermStatsTime = 240  # Long-term statistical time of the bit rate (in minutes). The value range is [1, 1440]. It takes effect when rcMode is set to 5.
    venc_conf.longTermMaxBitRate = 200  # Maximum long-term output bit rate of the encoder, in kbps. The value range is [2, max_bit_rate]. It takes effect when rcMode is set to 5
    venc_conf.longTermMinBitRate = 1  # Minimum long-term output bit rate of the encoder, in kbps. The value range is [0, long_term_max_bit_rate]. It takes effect when rcMode is set to 5
    venc_conf.SetThresholdI(threshold_i=[0, 0, 0, 0, 3, 3, 5, 5, 8, 8, 8, 15, 15, 20, 25, 25])
    venc_conf.SetThresholdP(threshold_p=[0, 0, 0, 0, 3, 3, 5, 5, 8, 8, 8, 15, 15, 20, 25, 25])
    venc_conf.SetThresholdB(threshold_b=[0, 0, 0, 0, 3, 3, 5, 5, 8, 8, 8, 15, 15, 20, 25, 25])
    venc_conf.direction = 8 # Addition or subtraction direction control during texture-based macroblock-level bit rate control
    venc_conf.rowQpDelta = 1# Maximum row-level adjustment range within one frame. The unit is the macroblock row. A greater adjustment amplitude signifies a wider allowable QP row-level adjustment range and a more stable bit rate.
    venc_conf.firstFrameStartQp = 32 # Start QP value of the first frame.
    # Initialize VideoEncoder.
    videoEncoder = VideoEncoder(venc_conf, vencCallBacker, device_id)  
    # Save the encoded data as a local video. If the video file already exists, delete it.
    venc_save_path = os.path.join(save_path, 'output.h264')  
    video_encode_exists = os.path.exists(venc_save_path)  
    if video_encode_exists:  
        os.remove(venc_save_path)  
    # Obtain the Image class repeatedly from decoded_data_list for encoding.
    for i, img in enumerate(decoded_data_list):  
        videoEncoder.encode(img, i) 

if __name__ == "__main__":
    base.mx_init()    # Initialize resources.
    process()
    base.mx_deinit()  # Deinitialize resources.