5.12. Audio and Video Codec - Codec

5.12.1. Module Description

5.12.1.1. Specifications

H.265/HEVC Encoder

  • Supports HEVC Main and Main Still Picture Profile @L5.1 High Tier

  • Maximum resolution is 8192x4096

  • Performance: 4K60fps @500MHz

  • Minimum resolution: 256x128

  • The width or height of input images must be a multiple of 8

  • Image format: YUV420

  • Supports I-frames and P-frames, does not support B-frames

  • Fully compliant with ISO/IEC 23008-2 High Efficiency Video Coding Main Profile standard

H.264/AVC Encoder

  • Supports encoding capabilities of Baseline/Constrained Baseline/Main/High Profile @5.2

  • Performance: 4K60fps @500MHz

  • Maximum resolution is 8192x4096

  • Minimum resolution: 256x128

  • The width or height of input images must be a multiple of 8

  • Image format: YUV420

  • Supports I-frames and P-frames, does not support B-frames

  • Fully compliant with ITU-T H.264 specification, supports all encoding tools in Baseline, Constrained Baseline, Main, and High profiles, except for the following exceptions:

    • Interlaced Coding Tools are not supported

    • H.264 FMO/ASO tools are not supported

H.265/HEVC Decoder

  • Supports HEVC Main and Main Still Picture Profile @L5.1 High Tier

  • Maximum supported resolution: 8K (8192 x 4096)

  • Performance: 4K60fps @500MHz

  • Minimum supported resolution: 8x8

  • Image format: YUV420

  • Fully compliant with ISO/IEC 23008-2 High Efficiency Video Coding Main/MSP (Main Still Picture)

H.264/AVC Decoder

  • Supports encoding capabilities of Baseline/Constrained Baseline/Main/High Profile @5.2

  • Maximum supported resolution: 8K (8192 x 4096)

  • Performance: 4K60fps @500MHz

  • Minimum supported resolution: 64x64

  • Image format: YUV420

  • Fully compliant with ITU-T H.264 specification, supports all encoding tools in Baseline, Constrained Baseline, Main, and High profiles, except for the following exceptions:

    • Interlaced Coding Tools are not supported

    • H.264 FMO/ASO tools are not supported

JPEG and MJPEG Encoder/Decoder

  • Supports JPEG baseline/extended sequential and M-JPEG encoding/decoding

  • Maximum resolution: 32768x32768

  • Minimum supported encoding resolution: 16x16 pixels

  • Supports YUV444/YUV422/YUV420/YUV400/YUV440 color formats

  • Performance: Simultaneous encoding and decoding at 4K30fps @500MHz

    • For 4:2:2 color format images, supports up to 210M pixels/sec encoding

    • For 4:0:0 color format images, supports up to 430M pixels/sec encoding

  • Compliant with ISO/IEC 10918-1 JPEG standard Baseline and Extended Sequential profiles

Audio Codec

The X5 chip does not have hardware acceleration units for audio codec, but its MediaCodec interface is based on the FFMPEG software library, implementing various codecs through software, as follows:

  1. Lossless compression: FLAC

  2. Lossy compression: G.711 A-law/Mu-law, G.726 ADPCM, ADPCM IMA WAV,

    • AAC series: AAC LC, AAC Main, AAC SSR, AAC LTP, AAC LD, AAC HE, AAC HEv2

Note: AAC series codecs require obtaining an AAC license from the AAC technology management organization.

5.12.1.2. Usage Instructions

Input and Output Buffer Management

MediaCodec buffers include input and output buffers. There are two cases for the source of input buffers:

  1. Internal input buffer mode: Input source comes from memory allocated internally by MediaCodec via the hbmem interface

  2. External input buffer mode: Input source comes from output memory of other modules, which must also be allocated via the hbmem interface, such as memory output from the VSE module

Notes:

  • The source of input buffers is controlled by the external_frame_buf member in the mc_video_codec_enc_params_t structure

  • The specific source of input buffers can be any physically contiguous memory, such as memory output from the hbn framework. For specific examples, refer to the source code of sunrise_camera.

Internal Input Buffer Mode

Users do not need to manage buffer allocation. They only need to perform a dequeue operation before processing to obtain a free buffer, and then perform a queue operation to return the buffer after processing. As shown in the diagram below:

Block Diagram

External Input Buffer Mode

The purpose of external input buffer mode is to reduce copy operations of input buffers. For example:
When the output buffer from VSE is used for encoding, this buffer is allocated internally by VSE via the hbmem interface and can be directly used as the input buffer for MediaCodec.

Note: Even when users use external input buffers, they still need to perform a dequeue operation to obtain queue information, assign values to the information in the queue (mainly virtual and physical addresses), and then perform a queue operation.

GOP

H.264/H.265 encoding supports GOP structure configuration. Users can select from 9 preset GOP structures (X5 supports 2 types) or define custom GOP structures.

Note:

  1. X5 encoding only supports I-frame and P-frame encoding, does not support B-frames or multi-frame reference. Therefore, among the 9 GOP presets, only GOP Preset 1 and GOP Preset 9 are supported (described in detail later).
    The gop_params.gop_preset_idx member in the mc_video_codec_enc_params_t structure can only take values 1 and 9.

  2. The following table and descriptions only cover these two supported GOP Presets.

GOP Structure Table

The GOP structure table defines a periodic GOP structure that will be used throughout the encoding process.

  1. Elements in a single structure table are shown in the table below, where reference frames for each image can be specified.

  2. If frames after an IDR frame specify reference frames from before the IDR frame, the encoder internally handles this situation to avoid referencing other frames; users do not need to handle this case.

  3. When defining a custom GOP structure, users need to specify the number of structure tables, with a maximum of 3 tables. The order of the structure tables must follow decoding order.

Element Description
Type Slice type (I, P)
POC Display order of the frame within a GOP, ranging from 1 to GOP size
QPoffset A quantization parameter of the picture in the custom GOP
NUM_REF_PIC_L0 Flag to use multi-reference picture for P picture. It is valid only if PIC_TYPE is P
temporal_id Temporal layer of the frame. A frame cannot predict from a frame with a higher temporal id (0~6).
1st_ref_POC The POC of the 1st reference picture of L0
2nd_ref_POC The POC of 1st reference picture of L1 in case that Type is equal to B
The POC of 2nd reference picture of L0 in case that Type is equal to P
Note that reference_L1 can have the same POC as reference in B slice. But for
compression efficiency it is recommended that reference_L1 have
a different POC from reference_L0
GOP Preset Structures
Index GOP Structure Low Delay
(encoding order and
display order are same)
GOP Size Encoding Order Minimum
Source Frame Buffer
Minimum
Decoded Picture Buffer
Intra Period
(I Frame Interval)
Requirement
1 I Yes 1 I0-I1-I2 … 1 1 -
9 P Yes 1 P0 1 2 -
GOP Preset 1
  • Contains only I-frames, no inter-frame references;

  • Low latency;

Block Diagram Block Diagram

GOP Preset 9
  • Contains only I-frames and P-frames;

  • P-frames reference one forward reference frame;

  • Low latency;

Block Diagram Block Diagram

Long-term Reference Frames

Users can specify the long-term reference frame mode:

  1. Mode definition: hb_mm_mc_set_longterm_ref_mode

  2. Reference example: hb_mm_mc_get_longterm_ref_mode_demo

As shown in the diagram below:

Block Diagram

Intra Refresh

Intra Refresh mode improves error resilience by periodically inserting intra-coded MBs/CTUs within non-I frames. It provides more recovery points for decoders to avoid image damage caused by temporal errors.

  1. Users can specify the number of consecutive rows, columns, or step size of MBs/CTUs to force the encoder to insert intra-coded units. Details: mc_video_intra_refresh_params_t

  2. Users can also let the encoder decide internally which block needs intra-coding.

ROI

ROI encoding implementation is similar to QPMAP, requiring users to set QP values for each block in raster scan order, as shown in the diagram below:

Block Diagram

In H.264 encoding, each block is 16x16 pixels, while in H.265 encoding, block size extends to 32x32 pixels. In the ROI (Region of Interest) map, each QP (Quantization Parameter) value occupies 1 byte, with values ranging from 0 to 51.
ROI encoding can work with CBR and AVBR. When CBR or AVBR is disabled, the actual QP value for each block region equals the value specified in the ROI map. When CBR or AVBR is enabled, the actual value for each block region is determined by the following formula:

QP(i) = MQP(i) + RQP(i) - ROIAvgQP

Where MQP is the value from the ROI map, RQP is the value obtained from internal rate control of the encoder, and ROIAvgQP is the average QP value in the ROI map.

For sample code, please refer to: hb_mm_mc_get_longterm_ref_mode

Frame Skip Setting

Users can call hb_mm_mc_skip_pic to set the encoding mode of the next queued input image to skip mode.

  1. This mode is only effective for non-I-frame encoding;

  2. In skip mode, the encoder ignores the input frame and uses the reconstructed frame from the previous frame to generate the reconstructed frame for the current input, encoding the input frame as a P-frame.

5.12.2. Reference Examples

5.12.3. API Reference

5.12.3.1. MediaCodec API

API Interface Function
hb_mm_mc_get_descriptor Retrieves codec information supported by MediaCodec based on codec_id, including codec name, detailed description, MIME type, and supported profile types
hb_mm_mc_get_default_context Retrieves default attributes for the specified codec
hb_mm_mc_initialize Initializes the encoder or decoder. Upon successful call, MediaCodec enters MEDIA_CODEC_STATE_INITIALIZED state
hb_mm_mc_set_callback Sets callback function pointer. After calling, MediaCodec enters asynchronous operation mode
hb_mm_mc_set_input_buffer_listener Sets callback function pointer. After the application queues an input buffer, it can attach a corresponding user ptr in media_codec_buffer_t
hb_mm_mc_configure Configures the encoder or decoder based on input information. Upon successful call, MediaCodec enters MEDIA_CODEC_STATE_CONFIGURED state
hb_mm_mc_start Starts the encoding/decoding process. MediaCodec creates codec instances, sets sequences or parses data streams, registers Framebuffer, encodes header information, etc. Upon successful call, MediaCodec enters MEDIA_CODEC_STATE_STARTED state
hb_mm_mc_stop Stops the encoding/decoding process, exits all sub-threads and releases related resources. Upon successful call, MediaCodec returns to MEDIA_CODEC_STATE_INITIALIZED state
hb_mm_mc_pause Stops the encoding/decoding process, pauses all sub-threads. Upon successful call, MediaCodec enters MEDIA_CODEC_STATE_PAUSED state
hb_mm_mc_flush Flushes input and output buffer queues, forcing the encoder/decoder to flush unprocessed input/output buffers. After calling, MediaCodec enters MEDIA_CODEC_STATE_FLUSHING state. After successful operation, MediaCodec re-enters MEDIA_CODEC_STATE_STARTED state
hb_mm_mc_release Releases all internal resources of MediaCodec. Users must call hb_mm_mc_stop before calling this function to stop encoding/decoding. After successful operation, MediaCodec enters MEDIA_CODEC_STATE_UNINITIALIZED state
hb_mm_mc_get_state Retrieves the current state of MediaCodec
hb_mm_mc_get_status Retrieves the current internal status information of MediaCodec
hb_mm_mc_queue_input_buffer Fills the buffer to be processed into MediaCodec
hb_mm_mc_dequeue_input_buffer Retrieves an input buffer
hb_mm_mc_queue_output_buffer Returns the processed output buffer to MediaCodec
hb_mm_mc_dequeue_output_buffer Retrieves an output buffer
hb_mm_mc_get_longterm_ref_mode Retrieves long-term reference frame mode parameters, applicable to H.264/H.265
hb_mm_mc_set_longterm_ref_mode Sets long-term reference frame mode parameters. This is a dynamic parameter, applicable to H.264/H.265
hb_mm_mc_get_intra_refresh_config Retrieves intra-refresh parameters, applicable to H.264/H.265
hb_mm_mc_set_intra_refresh_config Sets intra-refresh mode parameters. This is a static parameter, applicable to H.264/H.265
hb_mm_mc_get_rate_control_config Retrieves rate control parameters. This is a dynamic parameter, applicable to H.264/H.265/MJPEG
hb_mm_mc_set_rate_control_config Sets rate control parameters. This is a dynamic parameter, applicable to H.264/H.265/MJPEG
hb_mm_mc_get_deblk_filter_config Retrieves deblocking filter parameters, applicable to H.264/H.265
hb_mm_mc_set_deblk_filter_config Sets deblocking filter parameters. This is a dynamic parameter, applicable to H.264/H.265
hb_mm_mc_get_sao_config Retrieves SAO parameters, applicable to H.265
hb_mm_mc_set_sao_config Sets SAO parameters. This is a static parameter, applicable to H.265
hb_mm_mc_get_entropy_config Retrieves entropy parameters, applicable to H.264
hb_mm_mc_set_entropy_config Sets entropy parameters, applicable to H.264
hb_mm_mc_get_vui_timing_config Retrieves VUI Timing parameters, applicable to H.264/H.265
hb_mm_mc_set_vui_timing_config Sets VUI Timing parameters. This is a static parameter, applicable to H.264/H.265
hb_mm_mc_get_slice_config Retrieves slice encoding parameters, applicable to H.264/H.265
hb_mm_mc_set_slice_config Sets slice encoding parameters. This is a dynamic parameter, applicable to H.264/H.265. Limits the number of slices per frame to ≤ 1500
hb_mm_mc_insert_user_data Inserts user data into the encoded stream. This is a dynamic parameter, applicable to H.264/H.265
hb_mm_mc_request_idr_frame Requests an IDR frame. This interface can be dynamically set, applicable to H.264/H.265
hb_mm_mc_skip_pic Enables skip mode encoding for the specified image. This interface can be dynamically set, applicable to H.264/H.265
hb_mm_mc_get_smart_bg_enc_config Retrieves smart background encoding parameters, applicable to H.264/H.265
hb_mm_mc_set_smart_bg_enc_config Sets smart background encoding parameters. This is a dynamic parameter, applicable to H.264/H.265
hb_mm_mc_get_pred_unit_config Retrieves prediction unit parameters, applicable to H.264/H.265
hb_mm_mc_set_pred_unit_config Sets prediction unit parameters. This is a dynamic parameter, applicable to H.264/H.265
hb_mm_mc_get_transform_config Retrieves Transform parameters, applicable to H.264/H.265
hb_mm_mc_set_transform_config Sets Transform parameters. This is a dynamic parameter, applicable to H.264/H.265
hb_mm_mc_get_roi_config Retrieves ROI encoding parameters, applicable to H.264/H.265
hb_mm_mc_set_roi_config Sets ROI encoding parameters. This is a dynamic parameter, applicable to H.264/H.265
hb_mm_mc_get_mode_decision_config Retrieves ROI encoding parameters, applicable to H.265
hb_mm_mc_set_mode_decision_config Sets mode decision parameters. This is a dynamic parameter, applicable to H.265
hb_mm_mc_get_user_data Retrieves user data from the decoded stream, applicable to H.264/H.265
hb_mm_mc_release_user_data Releases user data from the decoded stream, applicable to H.264/H.265
hb_mm_mc_get_mjpeg_config Retrieves MJPEG encoding parameters, applicable to MJPEG
hb_mm_mc_set_mjpeg_config Sets MJPEG encoding parameters. This is a dynamic parameter, applicable to MJPEG
hb_mm_mc_get_jpeg_config Retrieves JPEG encoding parameters, applicable to JPEG
hb_mm_mc_set_jpeg_config Sets JPEG encoding parameters. This is a dynamic parameter, applicable to JPEG
hb_mm_mc_get_fd Retrieves device node fd, which can be used for select operations to monitor codec results
hb_mm_mc_close_fd Closes the device node
hb_mm_mc_get_vui_config Retrieves VUI parameters
hb_mm_mc_set_vui_config Sets VUI parameters. This is a static parameter
hb_mm_mc_get_3dnr_enc_config Retrieves 3DNR parameters. This is a dynamic parameter, applicable to H.265
hb_mm_mc_set_3dnr_enc_config Sets 3DNR parameters. This is a dynamic parameter, applicable to H.265
hb_mm_mc_request_idr_header Requests IDR frame header information, applicable to H.264/H.265
hb_mm_mc_enable_idr_frame Enables IDR frame, applicable to H.264/H.265
hb_mm_mc_register_audio_encoder Registers audio encoder, applicable to Audio
hb_mm_mc_unregister_audio_encoder Unregisters audio encoder, applicable to Audio
hb_mm_mc_register_audio_decoder Registers audio decoder, applicable to Audio
hb_mm_mc_unregister_audio_decoder Unregisters audio decoder, applicable to Audio
hb_mm_mc_get_explicit_header_config Retrieves configuration for whether header information and IDR frame are encoded as one frame: 0 – IDR and header are separate; 1 – IDR and header are combined into one frame, applicable to H.264/H.265
hb_mm_mc_set_explicit_header_config Enables/disables encoding header information and I-frame as one frame. This is a static parameter: 0 – IDR and header are separate; 1 – IDR and header are combined into one frame, applicable to H.264/H.265
hb_mm_mc_get_roi_avg_qp Retrieves average ROI QP value, applicable to H.264/H.265
hb_mm_mc_set_roi_avg_qp Sets average ROI encoding QP value. This is a dynamic parameter, indicating the use of the specified QPMap

5.12.3.2. MediaMuxer API

API Interface Function
hb_mm_mx_get_default_context Retrieves default context parameter values
hb_mm_mx_initialize Initializes internal state of MediaMuxer. Upon successful call, MediaMuxer enters MEDIA_MUXER_STATE_INITIALIZED state
hb_mm_mx_add_stream Adds audio/video tracks
hb_mm_mx_start Starts internal process of MediaMuxer. Upon successful call, enters MEDIA_MUXER_STATE_STARTED state
hb_mm_mx_stop Stops internal process of MediaMuxer. Upon successful call, enters MEDIA_MUXER_STATE_UNINITIALIZED state
hb_mm_mx_write_stream Writes audio or video data
hb_mm_mx_get_state Retrieves current state of MediaMuxer
hb_mm_mx_probe_stream Checks if MP4 file is abnormal
hb_mm_mx_repair_stream Repairs abnormal MP4 file and generates normal MP4

5.12.4. Interface Descriptions

5.12.4.1. hb_mm_mc_get_descriptor

【Function Declaration】

const media_codec_descriptor_t* hb_mm_mc_get_descriptor(media_codec_id_t codec_id);

【Parameter Description】

  • [IN] media_codec_id_t codec_id: Indicates codec type

【Return Value】

  • Non-null: codec descriptor information

  • NULL: Indicates no descriptor found for the given codec ID

【Function Description】

Retrieves codec information supported by MediaCodec based on codec_id, including codec name, detailed description, MIME type, and supported profile types.

【Example Code】

    #include "hb_media_codec.h"
    #include "hb_media_error.h"
    int main(int argc, char *argv[])
    {
        const media_codec_descriptor_t *desc = NULL;
        desc = hb_mm_mc_get_descriptor(MEDIA_CODEC_ID_H265);
        return 0;
    }

5.12.4.2. hb_mm_mc_get_default_context

【Function Declaration】

hb_s32 hb_mm_mc_get_default_context(media_codec_id_t codec_id, hb_bool encoder, media_codec_context_t *context)

【Parameter Description】

  • [IN] media_codec_id_t codec_id: Indicates codec type

  • [IN] hb_bool encoder: Specifies whether codec is encoder or decoder

  • [OUT] media_codec_context_t *context: Default context for specified codec type

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Retrieves default attributes for the specified codec.

【Example Code】

    #include "hb_media_codec.h"
    #include "hb_media_error.h"
    int main(int argc, char *argv[])
    {
        int ret = 0;
        media_codec_context_t context;
        memset(&context, 0x00, sizeof(context));
        ret = hb_mm_mc_get_default_context(MEDIA_CODEC_ID_H265, 1, &context);
        return 0;
    }

5.12.4.3. hb_mm_mc_initialize

【Function Declaration】

hb_s32 hb_mm_mc_initialize(media_codec_context_t *context)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context for specified codec type

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INSUFFICIENT_RES: Insufficient internal memory resources

  • HB_MEDIA_ERR_NO_FREE_INSTANCE: No available instance (maximum 32 for Video, 64 for MJPEG/JPEG, 32 for Audio)

【Function Description】

Initializes the encoder or decoder. Upon successful call, MediaCodec enters MEDIA_CODEC_STATE_INITIALIZED state.

【Example Code】

    #include "hb_media_codec.h"
    #include "hb_media_error.h"
    static Uint64 osal_gettime(void)
    {
        struct timespec tp;
        clock_gettime(CLOCK_MONOTONIC, &tp);
        return ((Uint64)tp.tv_sec*1000 + tp.tv_nsec/1000000);
    }
    typedef struct MediaCodecTestContext {
        media_codec_context_t *context;
        char *inputFileName;
        char *outputFileName;
    } MediaCodecTestContext;
    typedef struct AsyncMediaCtx {
        media_codec_context_t *ctx;
        FILE *inFile;
        FILE *outFile;
        int lastStream;
        Uint64 startTime;
        int32_t duration;
    } AsyncMediaCtx;
    static void on_encoder_input_buffer_available(hb_ptr userdata,
    media_codec_buffer_t *inputBuffer) {
        AsyncMediaCtx *asyncCtx = (AsyncMediaCtx *)userdata;
        Int noMoreInput = 0;
        hb_s32 ret = 0;
        Uint64 curTime = 0;
        if (!noMoreInput) {
            curTime = osal_gettime();
            if ((curTime - asyncCtx->startTime)/1000 < (uint32_t)asyncCtx->duration) {
                ret = fread(inputBuffer->vframe_buf.vir_ptr[0], 1,
                inputBuffer->vframe_buf.size, asyncCtx->inFile);
                if (ret <= 0) {
                    if(fseek(asyncCtx->inFile, 0, SEEK_SET)) {
                    printf("Failed to rewind input file\n");
                } else {
                    ret = fread(inputBuffer->vframe_buf.vir_ptr[0], 1,
                    inputBuffer->vframe_buf.size, asyncCtx->inFile);
                    if (ret <= 0) {
                        printf("Failed to read input file\n");
                    }
                }
            }
        }
        if (!ret) {
            printf("%s There is no more input data!\n", TAG);
            inputBuffer->vframe_buf.frame_end = TRUE;
            noMoreInput = 1;
        } else {
            inputBuffer->vframe_buf.frame_end = TRUE;
            inputBuffer->vframe_buf.size = 0;
        }
    }
    static void on_encoder_output_buffer_available(hb_ptr userdata,
    media_codec_buffer_t *outputBuffer,
    media_codec_output_buffer_info_t *extraInfo) {
        AsyncMediaCtx *asyncCtx = (AsyncMediaCtx *)userdata;
        mc_265_output_stream_info_t info = extraInfo->video_stream_info;
        fwrite(outputBuffer->vstream_buf.vir_ptr,
        outputBuffer->vstream_buf.size, 1, asyncCtx->outFile);
        if (outputBuffer->vstream_buf.stream_end) {
            printf("There is no more output data!\n");
            asyncCtx->lastStream = 1;
        }
    }
    static void on_encoder_media_codec_message(hb_ptr userdata, hb_s32
           error) {
        AsyncMediaCtx *asyncCtx = (AsyncMediaCtx *)userdata;
        if (error) {
            asyncCtx->lastStream = 1;
            printf("ERROR happened!\n");
        }
    }
    static void on_vlc_buffer_message(hb_ptr userdata, hb_s32 * vlc_buf)
    {
        MediaCodecTestContext *ctx = (MediaCodecTestContext *)userdata;
        printf("%s %s VLC Buffer size = %d; Reset to %d.\n", TAG,
        __FUNCTION__,
        *vlc_buf, ctx->vlc_buf_size);
        *vlc_buf = ctx->vlc_buf_size;
    }
    static void do_async_encoding(void *arg) {
        hb_s32 ret = 0;
        FILE *outFile;
        FILE *inFile;
        int step = 0;
        AsyncMediaCtx asyncCtx;
        MediaCodecTestContext *ctx = (MediaCodecTestContext *)arg;
        media_codec_context_t *context = ctx->context;
        char *inputFileName = ctx->inputFileName;
        char *outputFileName = ctx->outputFileName;
        media_codec_state_t state = MEDIA_CODEC_STATE_NONE;
        inFile = fopen(inputFileName, "rb");
        if (!inFile) {
            goto ERR;
        }
        outFile = fopen(outputFileName, "wb");
        if (!outFile) {
            goto ERR;
        }
        memset(&asyncCtx, 0x00, sizeof(AsyncMediaCtx));
        asyncCtx.ctx = context;
        asyncCtx.inFile = inFile;
        asyncCtx.outFile = outFile;
        asyncCtx.lastStream = 0;
        asyncCtx.duration = 5;
        asyncCtx.startTime = osal_gettime();
        ret = hb_mm_mc_initialize(context);
        if (ret) {
            goto ERR;
        }
        media_codec_callback_t callback;
        callback.on_input_buffer_available =
        on_encoder_input_buffer_available;
        callback.on_output_buffer_available =
        on_encoder_output_buffer_available;
        callback.on_media_codec_message = on_encoder_media_codec_message;
        ret = hb_mm_mc_set_callback(context, &callback, &asyncCtx);
        if (ret) {
            goto ERR;
        }
        media_codec_callback_t callback2;
        callback2.on_vlc_buffer_message = on_vlc_buffer_message;
        if (ctx->vlc_buf_size > 0) {
            ret = hb_mm_mc_set_vlc_buffer_listener(context, &callback2, ctx);
            if (ret) {
                goto ERR;
            }
        }
        ret = hb_mm_mc_configure(context);
        if (ret) {
            goto ERR;
        }
        mc_av_codec_startup_params_t startup_params;
        startup_params.video_enc_startup_params.receive_frame_number = 0;
        ret = hb_mm_mc_start(context, &startup_params);
        if (ret) {
            goto ERR;
        }
        while(!asyncCtx.lastStream) {
            sleep(1);
        }
        hb_mm_mc_stop(context);
        hb_mm_mc_release(context);
        context = NULL;
    ERR:
        hb_mm_mc_get_state(context, &state);
        if (context && state !=
        MEDIA_CODEC_STATE_UNINITIALIZED) {
            hb_mm_mc_stop(context);
            hb_mm_mc_release(context);
        }
        if (inFile)
            fclose(inFile);
        if (outFile)
            fclose(outFile);
    }
    int main(int argc, char *argv[])
    {
        int ret = 0;
        char outputFileName[MAX_FILE_PATH] = "./tmp.yuv";
        char inputFileName[MAX_FILE_PATH] = "./output.h265";
        mc_video_codec_enc_params_t *params = NULL;
        media_codec_context_t context;
        memset(&context, 0x00, sizeof(media_codec_context_t));
        context.codec_id = MEDIA_CODEC_ID_H265;
        context.encoder = 1;
        params = &context.video_enc_params;
        params->width = 640;
        params->height = 480;
        params->pix_fmt = MC_PIXEL_FORMAT_YUV420P;
        params->frame_buf_count = 5;
        params->external_frame_buf = 0;
        params->bitstream_buf_count = 5;
        params->rc_params.mode = MC_AV_RC_MODE_H265CBR;
        ret = hb_mm_mc_get_rate_control_config(&context, &params->rc_params);
        if (ret) {
            return -1;
        }
        params->rc_params.h265_cbr_params.bit_rate = 5000;
        params->rc_params.h265_cbr_params.frame_rate = 30;
        params->rc_params.h265_cbr_params.intra_period = 30;
        params->gop_params.decoding_refresh_type = 2;
        params->gop_params.gop_preset_idx = 9;
        params->rot_degree = MC_CCW_0;
        params->mir_direction = MC_DIRECTION_NONE;
        params->frame_cropping_flag = FALSE;
        MediaCodecTestContext ctx;
        memset(&ctx, 0x00, sizeof(ctx));
        ctx.context = &context;
        ctx.inputFileName = inputFileName;
        ctx.outputFileName = outputFileName;
        do_async_encoding(&ctx);
        return 0;
    }

5.12.4.4. hb_mm_mc_set_callback

【Function Declaration】

hb_s32 hb_mm_mc_set_callback(media_codec_context_t *context, const
media_codec_callback_t *callback, hb_ptr userdata)

【Parameter Description】

  • [IN] media_codec_context_t *context: The context specifying the codec type

  • [IN] const media_codec_callback_t *callback: User-defined callback functions

  • [IN] hb_ptr userdata: Pointer to user data, which will be passed as a parameter when the callback is invoked

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

【Function Description】

Sets the callback function pointer. After calling this function, MediaCodec enters asynchronous mode.

【Example Code】

See: hb_mm_mc_initialize

5.12.4.5. hb_mm_mc_set_input_buffer_listener

【Function Declaration】

hb_s32 hb_mm_mc_set_input_buffer_listener(media_codec_context_t *context, const
media_codec_callback_t *callback, hb_ptr userdata)

【Parameter Description】

  • [IN] media_codec_context_t *context: The context specifying the codec type

  • [IN] const media_codec_callback_t *callback: User-defined callback functions

  • [IN] hb_ptr userdata: Pointer to user data, which will be passed as a parameter when the callback is invoked

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

【Function Description】

Sets the callback function pointer. After an application queues an input buffer with an associated user pointer (stored in the media_codec_buffer_t structure), this callback function on_input_buffer_consumed will be invoked automatically by MediaCodec once the internal processing of the input buffer is complete. Users can perform desired operations in the callback, such as releasing resources associated with the user pointer.

A typical use case: When using external buffers in a data pipeline like sensor → ISP → VSE → VPU → Ethernet, this callback mechanism can be used to release VSE resources after encoding, eliminating the need for the application to track and manage VSE data sent to the encoder.

【Example Code】

Refer to the sample_codec example code, which demonstrates the use of external buffers combined with the input buffer consumed callback mechanism.

5.12.4.6. hb_mm_mc_configure

【Function Declaration】

hb_s32 hb_mm_mc_configure(media_codec_context_t *context)

【Parameter Description】

  • [IN] media_codec_context_t *context: The context specifying the codec type

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INSUFFICIENT_RES: Insufficient internal memory resources

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

【Function Description】

Configures the encoder or decoder based on the provided context. Upon successful call, MediaCodec transitions to the MEDIA_CODEC_STATE_CONFIGURED state.

【Example Code】

See: hb_mm_mc_initialize

5.12.4.7. hb_mm_mc_start

【Function Declaration】

hb_s32 hb_mm_mc_start(media_codec_context_t *context, const
mc_av_codec_startup_params_t *info)

【Parameter Description】

  • [IN] media_codec_context_t *context: The context specifying the codec type

  • [IN] mc_av_codec_startup_params_t *info: Startup parameters for audio/video codec

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INSUFFICIENT_RES: Insufficient internal memory resources

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

【Function Description】

Starts the encoding/decoding process. MediaCodec creates a codec instance, sets up sequences or parses the data stream, registers Framebuffer, encodes header information, etc. Upon successful call, MediaCodec transitions to the MEDIA_CODEC_STATE_STARTED state.

【Example Code】

See: hb_mm_mc_initialize

5.12.4.8. hb_mm_mc_stop

【Function Declaration】

hb_s32 hb_mm_mc_stop(media_codec_context_t *context)

【Parameter Description】

  • [IN] media_codec_context_t *context: The context specifying the codec type

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

【Function Description】

Stops the encoding/decoding process, terminates all sub-threads, and releases related resources. Upon successful call, MediaCodec returns to the MEDIA_CODEC_STATE_INITIALIZED state.

【Example Code】

See: hb_mm_mc_initialize

5.12.4.9. hb_mm_mc_pause

【Function Declaration】

hb_s32 hb_mm_mc_pause(media_codec_context_t *context)

【Parameter Description】

  • [IN] media_codec_context_t *context: The context specifying the codec type

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

【Function Description】

Pauses the encoding/decoding process and suspends all sub-threads. Upon successful call, MediaCodec enters the MEDIA_CODEC_STATE_PAUSED state.

【Example Code】

See: hb_mm_mc_queue_input_buffer

5.12.4.10. hb_mm_mc_flush

【Function Declaration】

hb_s32 hb_mm_mc_flush(media_codec_context_t *context)

【Parameter Description】

  • [IN] media_codec_context_t *context: The context specifying the codec type

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

【Function Description】

Flushes the input and output buffer queues, forcing the encoder/decoder to process any remaining data. After the function call, MediaCodec enters the MEDIA_CODEC_STATE_FLUSHING state. Upon completion, it returns to the MEDIA_CODEC_STATE_STARTED state.

【Example Code】

See: hb_mm_mc_queue_input_buffer

5.12.4.11. hb_mm_mc_release

【Function Declaration】

hb_s32 hb_mm_mc_release(media_codec_context_t *context)

【Parameter Description】

  • [IN] media_codec_context_t *context: The context specifying the codec type

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

【Function Description】

Releases all internal resources of MediaCodec. The user must call hb_mm_mc_stop before invoking this function to stop encoding/decoding. Upon successful operation, MediaCodec transitions to the MEDIA_CODEC_STATE_UNINITIALIZED state.

【Example Code】

See: hb_mm_mc_initialize

5.12.4.12. hb_mm_mc_get_state

【Function Declaration】

hb_s32 hb_mm_mc_get_state(media_codec_context_t *context,
media_codec_state_t *state)

【Parameter Description】

  • [IN] media_codec_context_t *context: The context specifying the codec type

  • [OUT] media_codec_state_t *state: Current state of MediaCodec

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Retrieves the current state of MediaCodec.

【Example Code】

See: hb_mm_mc_initialize

5.12.4.13. hb_mm_mc_get_status

【Function Declaration】

hb_s32 hb_mm_mc_get_status(media_codec_context_t *context,
mc_inter_status_t *status)

【Parameter Description】

  • [IN] media_codec_context_t *context: The context specifying the codec type

  • [OUT] mc_inter_status_t *status: Current internal status of MediaCodec

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Retrieves the current internal status information of MediaCodec.

【Example Code】

See: hb_mm_mc_get_fd

5.12.4.14. hb_mm_mc_queue_input_buffer

【Function Declaration】

hb_s32 hb_mm_mc_queue_input_buffer(media_codec_context_t *context,
media_codec_buffer_t *buffer, hb_s32 timeout)

【Parameter Description】

  • [IN] media_codec_context_t *context: The context specifying the codec type

  • [IN] media_codec_buffer_t *buffer: Input buffer information

  • [IN] hb_s32 timeout: Timeout duration (in milliseconds)

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

  • HB_MEDIA_ERR_INVALID_BUFFER: Invalid buffer

  • HB_MEDIA_ERR_WAIT_TIMEOUT: Wait timeout

【Function Description】

Queues the input buffer for processing by MediaCodec.

【Example Code】

    #include "hb_media_codec.h"

    #include "hb_media_error.h"
    typedef struct MediaCodecTestContext {
        media_codec_context_t *context;
        char *inputFileName;
        char *outputFileName;
        int32_t duration; // s
    } MediaCodecTestContext;
    Uint64 osal_gettime(void)
    {
        struct timespec tp;
        clock_gettime(CLOCK_MONOTONIC, &tp);
        return ((Uint64)tp.tv_sec*1000 + tp.tv_nsec/1000000);
    }
    static void do_sync_encoding(void *arg) {
        hb_s32 ret = 0;
        FILE *inFile;
        FILE *outFile;
        int noMoreInput = 0;
        int lastStream = 0;
        Uint64 lastTime = 0;
        Uint64 curTime = 0;
        int needFlush = 1;
        MediaCodecTestContext *ctx = (MediaCodecTestContext *)arg;
        media_codec_context_t *context = ctx->context;
        char *inputFileName = ctx->inputFileName;
        char *outputFileName = ctx->outputFileName;
        media_codec_state_t state = MEDIA_CODEC_STATE_NONE;
        inFile = fopen(inputFileName, "rb");
        if (!inFile) {
            goto ERR;
        }
        outFile = fopen(outputFileName, "wb");
        if (!outFile) {
            goto ERR;
        }
        //get current time
        lastTime = osal_gettime();
        ret = hb_mm_mc_initialize(context);
        if (ret) {
            goto ERR;
        }
        ret = hb_mm_mc_configure(context);
        if (ret) {
            goto ERR;
        }
        mc_av_codec_startup_params_t startup_params;
        startup_params.video_enc_startup_params.receive_frame_number = 0;
        ret = hb_mm_mc_start(context, &startup_params);
        if (ret) {
            goto ERR;
        }
        ret = hb_mm_mc_pause(context);
        if (ret) {
            goto ERR;
        }
        do {
            if (!noMoreInput) {
                media_codec_buffer_t inputBuffer;
                memset(&inputBuffer, 0x00, sizeof(media_codec_buffer_t));
                ret = hb_mm_mc_dequeue_input_buffer(context, &inputBuffer, 100);
                if (!ret) {
                    curTime = osal_gettime();
                    if ((curTime - lastTime)/1000 < (uint32_t)ctx->duration) {
                        ret = fread(inputBuffer.vframe_buf.vir_ptr[0], 1,
                        inputBuffer.vframe_buf.size, inFile);
                        if (ret <= 0) {
                            if(fseek(inFile, 0, SEEK_SET)) {
                                printf("Failed to rewind input file\n");
                            } else {
                                ret = fread(inputBuffer.vframe_buf.vir_ptr[0], 1,
                                inputBuffer.vframe_buf.size, inFile);
                                if (ret <= 0) {
                                    printf("Failed to read input file\n");
                                }
                            }
                        }
                    } else {
                        printf("Time up(%d)\n",ctx->duration);
                        ret = 0;
                    }
                    if (!ret) {
                        printf("There is no more input data!\n");
                        inputBuffer.vframe_buf.frame_end = TRUE;
                        noMoreInput = 1;
                    }
                    ret = hb_mm_mc_queue_input_buffer(context, &inputBuffer, 100);
                    if (ret) {
                        printf("Queue input buffer fail.\n");
                        break;
                    }
                } else {
                    if (ret != (int32_t)HB_MEDIA_ERR_WAIT_TIMEOUT) {
                        printf("Dequeue input buffer fail.\n");
                        break;
                    }
                }

                if (!lastStream) {
                    media_codec_buffer_t outputBuffer;
                    media_codec_output_buffer_info_t info;
                    memset(&outputBuffer, 0x00, sizeof(media_codec_buffer_t));
                    memset(&info, 0x00, sizeof(media_codec_output_buffer_info_t));
                    ret = hb_mm_mc_dequeue_output_buffer(context, &outputBuffer, &info,
                    3000);
                    if (!ret && outFile) {
                        fwrite(outputBuffer.vstream_buf.vir_ptr,
                        outputBuffer.vstream_buf.size, 1, outFile);
                        ret = hb_mm_mc_queue_output_buffer(context, &outputBuffer, 100);
                        if (ret) {
                            printf("Queue output buffer fail.\n");
                            break;
                        }
                        if (outputBuffer.vstream_buf.stream_end) {
                            printf("There is no more output data!\n");
                            lastStream = 1;
                            break;
                        }
                    } else {
                        if (ret != (int32_t)HB_MEDIA_ERR_WAIT_TIMEOUT) {
                            printf("Dequeue output buffer fail.\n");
                            break;
                        }
                    }
                }
                if (needFlush) {
                    ret = hb_mm_mc_flush(context);
                    needFlush = 0;
                    if (ret) {
                        break;
                    }
                }
            }
        } while(TRUE);
        hb_mm_mc_stop(context);
        hb_mm_mc_release(context);
        context = NULL;
    ERR:
        hb_mm_mc_get_state(context, &state);
        if (context && state !=
            MEDIA_CODEC_STATE_UNINITIALIZED) {
            hb_mm_mc_stop(context);
            hb_mm_mc_release(context);
        }
        if (inFile)
            fclose(inFile);
        if (outFile)
            fclose(outFile);
    }
    int main(int argc, char *argv[])
    {
        hb_s32 ret = 0;
        char outputFileName[MAX_FILE_PATH] = "./tmp.yuv";
        char inputFileName[MAX_FILE_PATH] = "./output.stream";
        mc_video_codec_enc_params_t *params;
        media_codec_context_t context;
        memset(&context, 0x00, sizeof(media_codec_context_t));
        context.codec_id = MEDIA_CODEC_ID_H265;
        context.encoder = TRUE;
        params = &context.video_enc_params;
        params->width = 640;
        params->height = 480;
        params->pix_fmt = MC_PIXEL_FORMAT_YUV420P;
        params->frame_buf_count = 5;
        params->external_frame_buf = FALSE;
        params->bitstream_buf_count = 5;
        params->rc_params.mode = MC_AV_RC_MODE_H265CBR;
        ret = hb_mm_mc_get_rate_control_config(&context, &params->rc_params);
        if (ret) {
            return -1;
        }
        params->rc_params.h265_cbr_params.bit_rate = 5000;
        params->rc_params.h265_cbr_params.frame_rate = 30;
        params->rc_params.h265_cbr_params.intra_period = 30;
        params->gop_params.decoding_refresh_type = 2;
        params->gop_params.gop_preset_idx = 9;
        params->rot_degree = MC_CCW_0;
        params->mir_direction = MC_DIRECTION_NONE;
        params->frame_cropping_flag = FALSE;
        MediaCodecTestContext ctx;
        memset(&ctx, 0x00, sizeof(ctx));
        ctx.context = &context;
        ctx.inputFileName = inputFileName;
        ctx.outputFileName = outputFileName;
        ctx.duration = 5;
        do_sync_encoding(&ctx);
    }

5.12.4.15. hb_mm_mc_dequeue_input_buffer

【Function Declaration】

hb_s32 hb_mm_mc_dequeue_input_buffer(media_codec_context_t *context,
media_codec_buffer_t *buffer, hb_s32 timeout)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] hb_s32 timeout: Timeout duration

  • [OUT] media_codec_buffer_t *buffer: Input buffer information

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

  • HB_MEDIA_ERR_INVALID_BUFFER: Invalid buffer

  • HB_MEDIA_ERR_WAIT_TIMEOUT: Wait timeout

【Function Description】

Obtain an input buffer.

【Example Code】

See: hb_mm_mc_queue_input_buffer

5.12.4.16. hb_mm_mc_queue_output_buffer

【Function Declaration】

hb_s32 hb_mm_mc_queue_output_buffer(media_codec_context_t *context,
media_codec_buffer_t *buffer, hb_s32 timeout)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] media_codec_buffer_t *buffer: Output buffer information

  • [IN] hb_s32 timeout: Timeout duration

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

  • HB_MEDIA_ERR_INVALID_BUFFER: Invalid buffer

  • HB_MEDIA_ERR_WAIT_TIMEOUT: Wait timeout

【Function Description】

Return the processed output buffer back to MediaCodec.

【Example Code】

See: hb_mm_mc_queue_input_buffer

5.12.4.17. hb_mm_mc_dequeue_output_buffer

【Function Declaration】

hb_s32 hb_mm_mc_dequeue_output_buffer(media_codec_context_t *context,
media_codec_buffer_t *buffer, media_codec_output_buffer_info_t *info,
hb_s32 timeout)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] hb_s32 timeout: Timeout duration

  • [OUT] media_codec_buffer_t *buffer: Output buffer information

  • [IN] media_codec_output_buffer_info_t *info: Information about the output bitstream

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

  • HB_MEDIA_ERR_INVALID_BUFFER: Invalid buffer

  • HB_MEDIA_ERR_WAIT_TIMEOUT: Wait timeout

【Function Description】

Obtain an output buffer.

【Example Code】

See: hb_mm_mc_queue_input_buffer

5.12.4.18. hb_mm_mc_get_longterm_ref_mode

【Function Declaration】

hb_s32 hb_mm_mc_get_longterm_ref_mode(media_codec_context_t *context,
mc_video_longterm_ref_mode_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [OUT] mc_video_longterm_ref_mode_t *params: Parameters for long-term reference frame mode

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Get parameters of the long-term reference frame mode, applicable for H264/H265.

【Example Code】


    #include "hb_media_codec.h"
    #include "hb_media_error.h"

    typedef enum ENC_CONFIG_MESSAGE {
        ENC_CONFIG_NONE = (0 << 0),
        ENC_CONFIG_LONGTERM_REF = (1 << 0),
        ENC_CONFIG_INTRA_REFRESH = (1 << 1),
        ENC_CONFIG_RATE_CONTROL = (1 << 2),
        ENC_CONFIG_DEBLK_FILTER = (1 << 3),
        ENC_CONFIG_SAO = (1 << 4),
        ENC_CONFIG_ENTROPY = (1 << 5),
        ENC_CONFIG_VUI_TIMING = (1 << 6),
        ENC_CONFIG_SLICE = (1 << 7),
        ENC_CONFIG_REQUEST_IDR = (1 << 8),
        ENC_CONFIG_SKIP_PIC = (1 << 9),
        ENC_CONFIG_SMART_BG = (1 << 10),
        ENC_CONFIG_MONOCHROMA = (1 << 11),
        ENC_CONFIG_PRED_UNIT = (1 << 12),
        ENC_CONFIG_TRANSFORM = (1 << 13),
        ENC_CONFIG_ROI = (1 << 14),
        ENC_CONFIG_MODE_DECISION = (1 << 15),
        ENC_CONFIG_USER_DATA = (1 << 16),
        ENC_CONFIG_MJPEG = (1 << 17),
        ENC_CONFIG_JPEG = (1 << 18),
        ENC_CONFIG_CAMERA = (1 << 19),
        ENC_CONFIG_INSERT_USERDATA = (1 << 20),
        ENC_CONFIG_VUI = (1 << 21),
        ENC_CONFIG_3DNR = (1 << 22),
        ENC_CONFIG_REQUEST_IDR_HEADER = (1 << 23),
        ENC_CONFIG_ENABLE_IDR = (1 << 24),
        ENC_CONFIG_TOTAL = (1 << 25),
    } ENC_CONFIG_MESSAGE;

    typedef struct MediaCodecTestContext {
        media_codec_context_t *context;
        char *inputFileName;
        char *outputFileName;
        int32_t duration; // s
        ENC_CONFIG_MESSAGE message;
        mc_video_longterm_ref_mode_t ref_mode;
        mc_rate_control_params_t rc_params;
        mc_video_intra_refresh_params_t intra_refr;
        mc_video_deblk_filter_params_t deblk_filter;
        mc_h265_sao_params_t sao;
        mc_h264_entropy_params_t entropy;
        mc_video_vui_params_t vui;
        mc_video_vui_timing_params_t vui_timing;
        mc_video_slice_params_t slice;
        mc_video_3dnr_enc_params_t noise_reduction;
        mc_video_smart_bg_enc_params_t smart_bg;
        mc_video_pred_unit_params_t pred_unit;
        mc_video_transform_params_t transform;
        mc_video_roi_params_t roi;
        mc_video_mode_decision_params_t mode_decision;
    } MediaCodecTestContext;

    Uint64 osal_gettime(void)
    {
        struct timespec tp;

        clock_gettime(CLOCK_MONOTONIC, &tp);

        return ((Uint64)tp.tv_sec*1000 + tp.tv_nsec/1000000);
    }
    uint8_t uuid[] =
        "dc45e9bd-e6d948b7-962cd820-d923eeef+HorizonAI";
    static void set_message(MediaCodecTestContext *ctx) {
        int ret = 0;
        media_codec_context_t *context = ctx->context;

        mc_video_longterm_ref_mode_t *ref_mode = &ctx->ref_mode;
        hb_mm_mc_get_longterm_ref_mode(context, ref_mode);
        ref_mode->use_longterm = TRUE;
        ref_mode->longterm_pic_using_period = 20;
        ref_mode->longterm_pic_period = 30;
        //ctx->message = ENC_CONFIG_LONGTERM_REF;
        if (ctx->message & ENC_CONFIG_LONGTERM_REF) {
            ret = hb_mm_mc_set_longterm_ref_mode(context, &ctx->ref_mode);
        }
        if (ctx->message & ENC_CONFIG_INTRA_REFRESH) {
            hb_mm_mc_get_intra_refresh_config(context, &ctx->intra_refr);
            ret = hb_mm_mc_set_intra_refresh_config(context, &ctx->intra_refr);
        }
        if (ctx->message & ENC_CONFIG_SAO) {
            hb_mm_mc_get_sao_config(context, &ctx->sao);
            ret = hb_mm_mc_set_sao_config(context, &ctx->sao);
        }

        if (ctx->message & ENC_CONFIG_ENTROPY) {
            hb_mm_mc_get_entropy_config(context, &ctx->entropy);
            ret = hb_mm_mc_set_entropy_config(context, &ctx->entropy);
        }

        if (ctx->message & ENC_CONFIG_VUI) {
            hb_mm_mc_get_vui_config(context, &ctx->vui);
            ret = hb_mm_mc_set_vui_config(context, &ctx->vui);
        }

        if (ctx->message & ENC_CONFIG_VUI_TIMING) {
            hb_mm_mc_get_vui_timing_config(context, &ctx->vui_timing);
            ret = hb_mm_mc_set_vui_timing_config(context, &ctx->vui_timing);
        }
        mc_rate_control_params_t *rc_params = &ctx->rc_params;
        rc_params->mode = context->video_enc_params.rc_params.mode;
        hb_mm_mc_get_rate_control_config(context, rc_params);
        switch (rc_params->mode) {
        case MC_AV_RC_MODE_H264CBR:
            rc_params->h264_cbr_params.bit_rate = 5000;
            rc_params->h264_cbr_params.intra_period = 60;
            break;
        case MC_AV_RC_MODE_H264VBR:
            rc_params->h264_vbr_params.intra_qp = 20;
            rc_params->h264_vbr_params.intra_period = 30;
            break;
        case MC_AV_RC_MODE_H264AVBR:
            rc_params->h264_avbr_params.intra_period = 15;
            rc_params->h264_avbr_params.intra_qp = 25;
            rc_params->h264_avbr_params.bit_rate = 2000;
            rc_params->h264_avbr_params.vbv_buffer_size = 3000;
            rc_params->h264_avbr_params.min_qp_I = 15;
            rc_params->h264_avbr_params.max_qp_I = 50;
            rc_params->h264_avbr_params.min_qp_P = 15;
            rc_params->h264_avbr_params.max_qp_P = 45;
            rc_params->h264_avbr_params.min_qp_B = 15;
            rc_params->h264_avbr_params.max_qp_B = 48;
            rc_params->h264_avbr_params.hvs_qp_enable = 0;
            rc_params->h264_avbr_params.hvs_qp_scale = 2;
            rc_params->h264_avbr_params.max_delta_qp = 5;
            rc_params->h264_avbr_params.qp_map_enable = 0;
            break;
        case MC_AV_RC_MODE_H264FIXQP:
            rc_params->h264_fixqp_params.force_qp_I = 23;
            rc_params->h264_fixqp_params.force_qp_P = 23;
            rc_params->h264_fixqp_params.force_qp_B = 23;
            rc_params->h264_fixqp_params.intra_period = 23;
            break;
        case MC_AV_RC_MODE_H264QPMAP:
            break;
        case MC_AV_RC_MODE_H265CBR:
            rc_params->h265_cbr_params.bit_rate = 5000;
            rc_params->h265_cbr_params.intra_period = 60;
            break;
        case MC_AV_RC_MODE_H265VBR:
            rc_params->h265_vbr_params.intra_qp = 20;
            rc_params->h265_vbr_params.intra_period = 30;
            break;
        case MC_AV_RC_MODE_H265AVBR:
            rc_params->h265_avbr_params.intra_period = 15;
            rc_params->h265_avbr_params.intra_qp = 25;
            rc_params->h265_avbr_params.bit_rate = 2000;
            rc_params->h265_avbr_params.vbv_buffer_size = 3000;
            rc_params->h265_avbr_params.min_qp_I = 15;
            rc_params->h265_avbr_params.max_qp_I = 50;
            rc_params->h265_avbr_params.min_qp_P = 15;
            rc_params->h265_avbr_params.max_qp_P = 45;
            rc_params->h265_avbr_params.min_qp_B = 15;
            rc_params->h265_avbr_params.max_qp_B = 48;
            rc_params->h265_avbr_params.hvs_qp_enable = 0;
            rc_params->h265_avbr_params.hvs_qp_scale = 2;
            rc_params->h265_avbr_params.max_delta_qp = 5;
            rc_params->h265_avbr_params.qp_map_enable = 0;
            break;
        break;
        case MC_AV_RC_MODE_H265FIXQP:
            rc_params->h265_fixqp_params.force_qp_I = 23;
            rc_params->h265_fixqp_params.force_qp_P = 23;
            rc_params->h265_fixqp_params.force_qp_B = 23;
            rc_params->h265_fixqp_params.intra_period = 23;
            break;
        case MC_AV_RC_MODE_H265QPMAP:
            break;
        default:
            break;
        }
        //ctx->message = ENC_CONFIG_RATE_CONTROL;
        if (ctx->message & ENC_CONFIG_RATE_CONTROL) {
            ret = hb_mm_mc_set_rate_control_config(context, &ctx->rc_params);
        }

        mc_video_deblk_filter_params_t *deblk_filter = &ctx->deblk_filter;
        hb_mm_mc_get_deblk_filter_config(context, deblk_filter);
        if (context->codec_id == MEDIA_CODEC_ID_H264) {
            deblk_filter->h264_deblk.disable_deblocking_filter_idc = 2;
            deblk_filter->h264_deblk.slice_alpha_c0_offset_div2 = 6;
            deblk_filter->h264_deblk.slice_beta_offset_div2 = 6;
        } else {
            deblk_filter->h265_deblk.slice_deblocking_filter_disabled_flag = 1;
            deblk_filter->h265_deblk.slice_beta_offset_div2 = 6;
            deblk_filter->h265_deblk.slice_tc_offset_div2 = 6;
            deblk_filter->h265_deblk.slice_loop_filter_across_slices_enabled_flag = 1;
        }
        //ctx->message = ENC_CONFIG_DEBLK_FILTER;
        if (ctx->message & ENC_CONFIG_DEBLK_FILTER) {
            ret = hb_mm_mc_set_deblk_filter_config(context, &ctx->deblk_filter);
        }

        if (context->codec_id == MEDIA_CODEC_ID_H264) {
            mc_h264_entropy_params_t *entropy = &ctx->entropy;
            hb_mm_mc_get_entropy_config(context, entropy);
            entropy->entropy_coding_mode = 0;
            ctx->message = ENC_CONFIG_ENTROPY;
            if (ctx->message & ENC_CONFIG_ENTROPY) {
                ret = hb_mm_mc_set_entropy_config(context, &ctx->entropy);
            }
        }

        //ctx->message = ENC_CONFIG_SKIP_PIC;
        if (ctx->message & ENC_CONFIG_SKIP_PIC) {
            ret = hb_mm_mc_skip_pic(context, 0);
        }

        //ctx->message = ENC_CONFIG_REQUEST_IDR;
        if (ctx->message & ENC_CONFIG_REQUEST_IDR) {
            ret = hb_mm_mc_request_idr_frame(context);
        }

        mc_video_slice_params_t *slice = &ctx->slice;
        hb_mm_mc_get_slice_config(context, slice);
        if (context->codec_id == MEDIA_CODEC_ID_H264) {
            slice->h264_slice.h264_slice_mode = 0;
            slice->h264_slice.h264_slice_arg = 60;
        } else {
            slice->h265_slice.h265_dependent_slice_mode = 0;
            slice->h265_slice.h265_dependent_slice_arg = 80;
            slice->h265_slice.h265_independent_slice_mode = 1;
            slice->h265_slice.h265_independent_slice_arg = 100;
        }
        //ctx->message = ENC_CONFIG_SLICE;
        if (ctx->message & ENC_CONFIG_SLICE) {
            ret = hb_mm_mc_set_slice_config(context, &ctx->slice);
        }

        mc_video_smart_bg_enc_params_t *smart_bg = &ctx->smart_bg;
        hb_mm_mc_get_smart_bg_enc_config(context, smart_bg);
        smart_bg->bg_detect_enable = 0;
        smart_bg->bg_threshold_diff = 8;
        smart_bg->bg_threshold_mean_diff = 1;
        smart_bg->bg_lambda_qp = 32;
        smart_bg->bg_delta_qp = 3;
        smart_bg->s2fme_disable = 0;
        //ctx->message = ENC_CONFIG_SMART_BG;
        if (ctx->message & ENC_CONFIG_SMART_BG) {
            ret = hb_mm_mc_set_smart_bg_enc_config(context, &ctx->smart_bg);
        }

        mc_video_pred_unit_params_t *pred_unit = &ctx->pred_unit;
        hb_mm_mc_get_pred_unit_config(context, pred_unit);
        if (context->codec_id == MEDIA_CODEC_ID_H264) {
            pred_unit->h264_intra_pred.constrained_intra_pred_flag = 1;
        } else {
            pred_unit->h265_pred_unit.intra_nxn_enable = 1;
            pred_unit->h265_pred_unit.constrained_intra_pred_flag = 1;
            pred_unit->h265_pred_unit.strong_intra_smoothing_enabled_flag = 0;
            pred_unit->h265_pred_unit.max_num_merge = 2;
        }
        //ctx->message = ENC_CONFIG_PRED_UNIT;
        if (ctx->message & ENC_CONFIG_PRED_UNIT) {
            ret = hb_mm_mc_set_pred_unit_config(context, &ctx->pred_unit);
        }

        mc_video_transform_params_t *transform = &ctx->transform;
        hb_mm_mc_get_transform_config(context, transform);
        if (context->codec_id == MEDIA_CODEC_ID_H264) {
            transform->h264_transform.transform_8x8_enable = 1;
            transform->h264_transform.chroma_cb_qp_offset = 4;
            transform->h264_transform.chroma_cr_qp_offset = 3;
            transform->h264_transform.user_scaling_list_enable = 0;
        } else {
            transform->h265_transform.chroma_cb_qp_offset = 6;
            transform->h265_transform.chroma_cr_qp_offset = 5;
            transform->h265_transform.user_scaling_list_enable = 0;
        }
        //ctx->message = ENC_CONFIG_TRANSFORM;
        if (ctx->message & ENC_CONFIG_TRANSFORM) {
            ret = hb_mm_mc_set_transform_config(context, &ctx->transform);
        }

        mc_video_roi_params_t *roi = &ctx->roi;
        hb_mm_mc_get_roi_config(context, roi);
        roi->roi_enable = 0;
        //ctx->message = ENC_CONFIG_ROI;
        if (ctx->message & ENC_CONFIG_ROI) {
            ret = hb_mm_mc_set_roi_config(context, &ctx->roi);
        }

        mc_video_mode_decision_params_t *mode_decision = &ctx->mode_decision;
        hb_mm_mc_get_mode_decision_config(context, mode_decision);
        mode_decision->mode_decision_enable = FALSE;
        mode_decision->pu04_delta_rate = 76;
        mode_decision->pu08_delta_rate = 80;
        mode_decision->pu16_delta_rate = 86;
        mode_decision->pu32_delta_rate = 87;
        mode_decision->pu04_intra_planar_delta_rate = 0;
        mode_decision->pu04_intra_dc_delta_rate = 0;
        mode_decision->pu04_intra_angle_delta_rate = 0;
        mode_decision->pu08_intra_planar_delta_rate = 0;
        mode_decision->pu08_intra_dc_delta_rate = 0;
        mode_decision->pu08_intra_angle_delta_rate = 0;
        mode_decision->pu16_intra_planar_delta_rate = 0;
        mode_decision->pu16_intra_dc_delta_rate = 0;
        mode_decision->pu16_intra_angle_delta_rate = 0;
        mode_decision->pu32_intra_planar_delta_rate = 0;
        mode_decision->pu32_intra_dc_delta_rate = 0;
        mode_decision->pu32_intra_angle_delta_rate = 0;
        mode_decision->cu08_intra_delta_rate = 0;
        mode_decision->cu08_inter_delta_rate = 0;
        mode_decision->cu08_merge_delta_rate = 0;
        mode_decision->cu16_intra_delta_rate = 0;
        mode_decision->cu16_inter_delta_rate = 0;
        mode_decision->cu16_merge_delta_rate = 0;
        mode_decision->cu32_intra_delta_rate = 0;
        mode_decision->cu32_inter_delta_rate = 0;
        mode_decision->cu32_merge_delta_rate = 0;
        //ctx->message = ENC_CONFIG_MODE_DECISION;
        if (ctx->message & ENC_CONFIG_MODE_DECISION) {
            ret = hb_mm_mc_set_mode_decision_config(context, &ctx->mode_decision);
    }
        if (ctx->message & ENC_CONFIG_INSERT_USERDATA) {
            hb_u32 length = sizeof(uuid)/sizeof(uuid[0]);
            ret = hb_mm_mc_insert_user_data(context, uuid, length);
    }
    if (ctx->message & ENC_CONFIG_3DNR) {
    hb_mm_mc_get_3dnr_enc_config(context, &ctx->noise_reduction);
            ret = hb_mm_mc_set_3dnr_enc_config(context, &ctx->noise_reduction);
    }
        if (ctx->message & ENC_CONFIG_ENABLE_IDR) {
            // disable idr frame first
            if (ctx->enable_idr_num) {
                ret = hb_mm_mc_enable_idr_frame(context, 0);
            }
        }

        if (ctx->message & ENC_CONFIG_REQUEST_IDR_HEADER) {
            ret = hb_mm_mc_request_idr_header(context, ctx->force_idr_header);
        }
    }

    static void do_sync_encoding(void *arg) {
        hb_s32 ret = 0;
        FILE *inFile;
        FILE *outFile;
        int noMoreInput = 0;
        int lastStream = 0;
        Uint64 lastTime = 0;
        Uint64 curTime = 0;
        int needFlush = 1;
        MediaCodecTestContext *ctx = (MediaCodecTestContext *)arg;
        media_codec_context_t *context = ctx->context;
        char *inputFileName = ctx->inputFileName;
        char *outputFileName = ctx->outputFileName;
        media_codec_state_t state = MEDIA_CODEC_STATE_NONE;
        inFile = fopen(inputFileName, "rb");
        if (!inFile) {
            goto ERR;
        }
        outFile = fopen(outputFileName, "wb");
        if (!outFile) {
            goto ERR;
        }

        //get current time
        lastTime = osal_gettime();

        ret = hb_mm_mc_initialize(context);
        if (ret) {
            goto ERR;
        }

        ret = hb_mm_mc_configure(context);
        if (ret) {
            goto ERR;
        }

        mc_av_codec_startup_params_t startup_params;
        startup_params.video_enc_startup_params.receive_frame_number = 0;
        ret = hb_mm_mc_start(context, &startup_params);
        if (ret) {
            goto ERR;
        }

        ret = hb_mm_mc_pause(context);
        if (ret) {
            goto ERR;
        }

        do {
            set_message(ctx);
            if (!noMoreInput) {
                media_codec_buffer_t inputBuffer;
                memset(&inputBuffer, 0x00, sizeof(media_codec_buffer_t));
                ret = hb_mm_mc_dequeue_input_buffer(context, &inputBuffer, 100);
                if (!ret) {
                    curTime = osal_gettime();
                    if ((curTime - lastTime)/1000 < (uint32_t)ctx->duration) {
                        ret = fread(inputBuffer.vframe_buf.vir_ptr[0], 1,
                            inputBuffer.vframe_buf.size, inFile);
                        if (ret <= 0) {
                            if(fseek(inFile, 0, SEEK_SET)) {
                                printf("Failed to rewind input file\n");
                            } else {
                                ret = fread(inputBuffer.vframe_buf.vir_ptr[0], 1,
                                    inputBuffer.vframe_buf.size, inFile);
                                if (ret <= 0) {
                                    printf("Failed to read input file\n");
                                }
                            }
                        }
                    } else {
                        printf("Time up(%d)\n",ctx->duration);
                        ret = 0;
                    }
                    if (!ret) {
                        printf("There is no more input data!\n");
                        inputBuffer.vframe_buf.frame_end = TRUE;
                        noMoreInput = 1;
                    }
                    ret = hb_mm_mc_queue_input_buffer(context, &inputBuffer, 100);
                    if (ret) {
                        printf("Queue input buffer fail.\n");
                        break;
                    }
                } else {
                    if (ret != (int32_t)HB_MEDIA_ERR_WAIT_TIMEOUT) {
                        printf("Dequeue input buffer fail.\n");
                        break;
                    }
                }
            }

            if (!lastStream) {
                media_codec_buffer_t outputBuffer;
                media_codec_output_buffer_info_t info;
                memset(&outputBuffer, 0x00, sizeof(media_codec_buffer_t));
                memset(&info, 0x00, sizeof(media_codec_output_buffer_info_t));
                ret = hb_mm_mc_dequeue_output_buffer(context, &outputBuffer, &info, 3000);
                if (!ret && outFile) {
                    fwrite(outputBuffer.vstream_buf.vir_ptr, outputBuffer.vstream_buf.size, 1, outFile);

                    ret = hb_mm_mc_queue_output_buffer(context, &outputBuffer, 100);
                    if (ret) {
                        printf("Queue output buffer fail.\n");
                        break;
                    }
                    if (outputBuffer.vstream_buf.stream_end) {
                        printf("There is no more output data!\n");
                        lastStream = 1;
                        break;
                    }
                } else {
                    if (ret != (int32_t)HB_MEDIA_ERR_WAIT_TIMEOUT) {
                        printf("Dequeue output buffer fail.\n");
                        break;
                    }
                }
            }
            if (needFlush) {
                ret = hb_mm_mc_flush(context);
                needFlush = 0;
                if (ret) {
                    break;
                }
            }
        }while(TRUE);

        hb_mm_mc_stop(context);

        hb_mm_mc_release(context);
        context = NULL;

    ERR:
        hb_mm_mc_get_state(context, &state);
        if (context && state != MEDIA_CODEC_STATE_UNINITIALIZED) {
            hb_mm_mc_stop(context);
            hb_mm_mc_release(context);
        }

        if (inFile)
            fclose(inFile);

        if (outFile)
            fclose(outFile);
    }

    int main(int argc, char *argv[])
    {
        hb_s32 ret = 0;
        char outputFileName[MAX_FILE_PATH] = "./tmp.yuv";
        char inputFileName[MAX_FILE_PATH] = "./output.stream";
        mc_video_codec_enc_params_t *params;
        media_codec_context_t context;

        memset(&context, 0x00, sizeof(media_codec_context_t));
        context.codec_id = MEDIA_CODEC_ID_H265;
        context.encoder = TRUE;
        params = &context.video_enc_params;
        params->width = 640;
        params->height = 480;
        params->pix_fmt = MC_PIXEL_FORMAT_YUV420P;
        params->frame_buf_count = 5;
        params->external_frame_buf = FALSE;
        params->bitstream_buf_count = 5;
        params->rc_params.mode = MC_AV_RC_MODE_H265CBR;
        ret = hb_mm_mc_get_rate_control_config(&context, &params->rc_params);
        if (ret) {
            return -1;
        }
        params->rc_params.h265_cbr_params.bit_rate = 5000;
        params->rc_params.h265_cbr_params.frame_rate = 30;
        params->rc_params.h265_cbr_params.intra_period = 30;
        params->gop_params.decoding_refresh_type = 2;
        params->gop_params.gop_preset_idx = 9;
        params->rot_degree = MC_CCW_0;
        params->mir_direction = MC_DIRECTION_NONE;
        params->frame_cropping_flag = FALSE;

        MediaCodecTestContext ctx;
        memset(&ctx, 0x00, sizeof(ctx));
        ctx.context = &context;
        ctx.inputFileName = inputFileName;
        ctx.outputFileName = outputFileName;
        ctx.duration = 5;
        do_sync_encoding(&ctx);
    }

5.12.4.19. hb_mm_mc_set_longterm_ref_mode

【Function Declaration】

hb_s32 hb_mm_mc_set_longterm_ref_mode(media_codec_context_t *context,
const mc_video_longterm_ref_mode_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] const mc_video_longterm_ref_mode_t *params: Long-term reference frame mode parameters

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Sets the long-term reference frame mode parameters. This is a dynamic parameter applicable to H.264/H.265.

【Example Code】

See: hb_mm_mc_get_longterm_ref_mode

5.12.4.20. hb_mm_mc_get_intra_refresh_config

【Function Declaration】

hb_s32 hb_mm_mc_get_intra_refresh_config(media_codec_context_t
*context, mc_video_intra_refresh_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [OUT] mc_video_intra_refresh_params_t *params: Intra refresh parameters

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Retrieves intra refresh parameters, applicable to H.264/H.265.

【Example Code】

See: hb_mm_mc_get_longterm_ref_mode

5.12.4.21. hb_mm_mc_set_intra_refresh_config

【Function Declaration】

hb_s32 hb_mm_mc_set_intra_refresh_config(media_codec_context_t
*context, const mc_video_intra_refresh_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] const mc_video_intra_refresh_params_t *params: Intra refresh parameters

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Sets intra refresh mode parameters. This is a static parameter applicable to H.264/H.265.

【Example Code】

See: hb_mm_mc_get_longterm_ref_mode

5.12.4.22. hb_mm_mc_get_rate_control_config

【Function Declaration】

hb_s32 hb_mm_mc_get_rate_control_config(media_codec_context_t *context,
mc_rate_control_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [OUT] mc_rate_control_params_t *params: Rate control parameters

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Retrieves rate control parameters. This is a dynamic parameter applicable to H.264/H.265/MJPEG.

【Example Code】 Reference: hb_mm_mc_get_longterm_ref_mode

5.12.4.23. hb_mm_mc_set_rate_control_config

【Function Declaration】

hb_s32 hb_mm_mc_set_rate_control_config(media_codec_context_t *context,
const mc_rate_control_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] const mc_rate_control_params_t *params: Rate control parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Set rate control parameters. This is a dynamic parameter applicable to H264/H265/MJPEG.

【Example Code】

Reference: hb_mm_mc_get_longterm_ref_mode

5.12.4.24. hb_mm_mc_get_deblk_filter_config

【Function Declaration】

hb_s32 hb_mm_mc_get_deblk_filter_config(media_codec_context_t *context,
mc_video_deblk_filter_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [OUT] mc_video_deblk_filter_params_t *params: Deblocking filter parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Get deblocking filter parameters, applicable to H264/H265.

【Example Code】

Reference: hb_mm_mc_get_longterm_ref_mode

5.12.4.25. hb_mm_mc_set_deblk_filter_config

【Function Declaration】

hb_s32 hb_mm_mc_set_deblk_filter_config(media_codec_context_t *context,
const mc_video_deblk_filter_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] const mc_video_deblk_filter_params_t *params: Deblocking filter parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Set deblocking filter parameters. This is a dynamic parameter applicable to H264/H265.

【Example Code】

Reference: hb_mm_mc_get_longterm_ref_mode

5.12.4.26. hb_mm_mc_get_sao_config

【Function Declaration】

hb_s32 hb_mm_mc_get_sao_config(media_codec_context_t *context,
mc_h265_sao_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [OUT] mc_h265_sao_params_t *params: SAO parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Get SAO parameters, applicable to H265.

【Example Code】

Reference: hb_mm_mc_get_longterm_ref_mode

5.12.4.27. hb_mm_mc_set_sao_config

【Function Declaration】

hb_s32 hb_mm_mc_set_sao_config(media_codec_context_t *context, const
mc_h265_sao_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] const mc_h265_sao_params_t *params: SAO parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Set SAO parameters. This is a static parameter applicable to H265.

【Example Code】

Reference: hb_mm_mc_get_longterm_ref_mode

5.12.4.28. hb_mm_mc_get_entropy_config

【Function Declaration】

hb_s32 hb_mm_mc_get_entropy_config(media_codec_context_t *context, mc_h264_entropy_params_t *params);

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] mc_h264_entropy_params_t *params: Entropy parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Get entropy parameters, applicable to H264.

【Example Code】

Reference: hb_mm_mc_get_longterm_ref_mode

5.12.4.29. hb_mm_mc_set_entropy_config

【Function Declaration】

extern hb_s32 hb_mm_mc_set_entropy_config(media_codec_context_t *context, const mc_h264_entropy_params_t *params);

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] const mc_h264_entropy_params_t *params: Entropy parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Set entropy parameters, applicable to H264.

【Example Code】

Reference: hb_mm_mc_get_longterm_ref_mode

5.12.4.30. hb_mm_mc_get_vui_timing_config

【Function Declaration】

hb_s32 hb_mm_mc_get_vui_timing_config(media_codec_context_t *context,
mc_video_vui_timing_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [OUT] mc_video_vui_timing_params_t *params: VUI Timing parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Get VUI Timing parameters, applicable to H264/H265.

【Example Code】

Reference: hb_mm_mc_get_longterm_ref_mode

5.12.4.31. hb_mm_mc_set_vui_timing_config

【Function Declaration】

hb_s32 hb_mm_mc_set_vui_timing_config(media_codec_context_t *context,
const mc_video_vui_timing_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] const mc_video_vui_timing_params_t *params: VUI Timing parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Set VUI Timing parameters. This is a static parameter applicable to H264/H265.

【Example Code】

Reference: hb_mm_mc_get_longterm_ref_mode

5.12.4.32. hb_mm_mc_get_slice_config

【Function Declaration】

hb_s32 hb_mm_mc_get_slice_config(media_codec_context_t *context,
mc_video_slice_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [OUT] mc_video_slice_params_t *params: Slice encoding parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Get slice encoding parameters, applicable to H264/H265.

【Example Code】

Reference: hb_mm_mc_get_longterm_ref_mode

5.12.4.33. hb_mm_mc_set_slice_config

【Function Declaration】

hb_s32 hb_mm_mc_set_slice_config(media_codec_context_t *context, const
mc_video_slice_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] const mc_video_slice_params_t *params: Slice encoding parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Set slice encoding parameters. This is a dynamic parameter applicable to H264/H265. Limit the number of slices per frame to no more than 1500.

【Example Code】

Reference: hb_mm_mc_get_longterm_ref_mode

5.12.4.34. hb_mm_mc_insert_user_data

【Function Declaration】

hb_s32 hb_mm_mc_insert_user_data(media_codec_context_t * context, hb_u8
*data, hb_u32 length)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] hb_u8 *data: User data

  • [IN] hb_u32 length: Length of user data

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Insert user data into the encoded stream. This is a dynamic parameter applicable to H264/H265.

【Example Code】

Reference: hb_mm_mc_get_longterm_ref_mode

5.12.4.35. hb_mm_mc_request_idr_frame

【Function Declaration】

hb_s32 hb_mm_mc_request_idr_frame(media_codec_context_t *context)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

【Function Description】

Request an IDR frame. This interface can be dynamically set and is applicable to H264/H265.

【Example Code】

Reference: hb_mm_mc_get_longterm_ref_mode

5.12.4.36. hb_mm_mc_skip_pic

【Function Declaration】

hb_s32 hb_mm_mc_skip_pic(media_codec_context_t *context, hb_s32
src_idx)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] hb_s32 src_idx: Source buffer index

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Enable skip-mode encoding for the specified picture. This interface can be dynamically set and is applicable to H264/H265.

【Example Code】

Reference: hb_mm_mc_get_longterm_ref_mode

5.12.4.37. hb_mm_mc_get_smart_bg_enc_config

【Function Declaration】

extern hb_s32 hb_mm_mc_get_smart_bg_enc_config(media_codec_context_t *context, mc_video_smart_bg_enc_params_t *params);

【Parameter Description】

  • [IN] media_codec_context_t *context: context specifying the codec type

  • [OUT] mc_video_smart_bg_enc_params_t *params: parameters for smart background encoding mode

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Get smart background encoding parameters, applicable to H264/H265.

【Example Code】

See: hb_mm_mc_get_longterm_ref_mode

5.12.4.38. hb_mm_mc_set_smart_bg_enc_config

【Function Declaration】

hb_s32 hb_mm_mc_set_smart_bg_enc_config(media_codec_context_t *context, const mc_video_smart_bg_enc_params_t *params);

【Parameter Description】

  • [IN] media_codec_context_t *context: context specifying the codec type

  • [IN] const mc_video_smart_bg_enc_params_t *params: parameters for smart background encoding mode

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Set smart background encoding parameters. This is a dynamic parameter, applicable to H264/H265.

【Example Code】

See: hb_mm_mc_get_longterm_ref_mode

5.12.4.39. hb_mm_mc_get_pred_unit_config

【Function Declaration】

hb_s32 hb_mm_mc_get_pred_unit_config(media_codec_context_t *context,
mc_video_pred_unit_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: context specifying the codec type

  • [OUT] mc_video_pred_unit_params_t *params: prediction unit parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Get prediction unit parameters, applicable to H264/H265.

【Example Code】

See: hb_mm_mc_get_longterm_ref_mode

5.12.4.40. hb_mm_mc_set_pred_unit_config

【Function Declaration】

hb_s32 hb_mm_mc_set_pred_unit_config(media_codec_context_t *context,
const mc_video_pred_unit_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: context specifying the codec type

  • [IN] const mc_video_pred_unit_params_t *params: prediction unit parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Set prediction unit parameters. This is a dynamic parameter, applicable to H264/H265.

【Example Code】

See: hb_mm_mc_get_longterm_ref_mode

5.12.4.41. hb_mm_mc_get_transform_config

【Function Declaration】

hb_s32 hb_mm_mc_get_transform_config(media_codec_context_t *context,
mc_video_transform_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: context specifying the codec type

  • [OUT] mc_video_transform_params_t *params: Transform parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Get Transform parameters, applicable to H264/H265.

【Example Code】

See: hb_mm_mc_get_longterm_ref_mode

5.12.4.42. hb_mm_mc_set_transform_config

【Function Declaration】

hb_s32 hb_mm_mc_set_transform_config(media_codec_context_t *context,
const mc_video_transform_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: context specifying the codec type

  • [IN] const mc_video_transform_params_t *params: Transform parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Set Transform parameters. This is a dynamic parameter, applicable to H264/H265.

【Example Code】

See: hb_mm_mc_get_longterm_ref_mode

5.12.4.43. hb_mm_mc_get_roi_config

【Function Declaration】

hb_s32 hb_mm_mc_get_roi_config(media_codec_context_t *context,
mc_video_roi_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: context specifying the codec type

  • [OUT] mc_video_roi_params_t *params: ROI encoding parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Get ROI encoding parameters, applicable to H264/H265.

【Example Code】

See: hb_mm_mc_get_longterm_ref_mode

5.12.4.44. hb_mm_mc_set_roi_config

【Function Declaration】

hb_s32 hb_mm_mc_set_roi_config(media_codec_context_t *context, const
mc_video_roi_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: context specifying the codec type

  • [IN] const mc_video_roi_params_t *params: ROI encoding parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Set ROI encoding parameters. This is a dynamic parameter, applicable to H264/H265.

【Example Code】

See: hb_mm_mc_get_longterm_ref_mode

5.12.4.45. hb_mm_mc_get_mode_decision_config

【Function Declaration】

hb_s32 hb_mm_mc_get_mode_decision_config(media_codec_context_t *context, mc_video_mode_decision_params_t *params);

【Parameter Description】

  • [IN] media_codec_context_t *context: context specifying the codec type

  • [OUT] mc_video_mode_decision_params_t *params: mode decision parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Get ROI encoding parameters, applicable to H265.

【Example Code】

See: hb_mm_mc_get_longterm_ref_mode

5.12.4.46. hb_mm_mc_set_mode_decision_config

【Function Declaration】

hb_s32 hb_mm_mc_set_mode_decision_config(media_codec_context_t *context, const mc_video_mode_decision_params_t *params);

【Parameter Description】

  • [IN] media_codec_context_t *context: context specifying the codec type

  • [IN] const mc_video_mode_decision_params_t *params: mode decision parameters

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Set mode decision parameters. This is a dynamic parameter, applicable to H265.

【Example Code】

See: hb_mm_mc_get_longterm_ref_mode

5.12.4.47. hb_mm_mc_get_user_data

【Function Declaration】

hb_s32 hb_mm_mc_get_user_data(media_codec_context_t *context,
mc_user_data_buffer_t *params , hb_s32 timeout)

【Parameter Description】

  • [IN] media_codec_context_t *context: context specifying the codec type

  • [OUT] mc_user_data_buffer_t *params: user data

  • [IN] timeout: timeout duration

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Retrieve user data from the decoded stream, applicable to H264/H265.

【Example Code】


    #include "hb_media_codec.h"
    #include "hb_media_error.h"
    static int check_and_init_test(MediaCodecTestContext *ctx) {
        int32_t ret = 0;
        char *inputFileName, *outputFileName, *inputMd5FileName;
        EXPECT_NE(ctx, nullptr);
        EXPECT_NE(ctx->context, nullptr);
        if (ctx == NULL || ctx->context == NULL) {
            return -1;
        }
        inputFileName = ctx->inputFileName;
        outputFileName = ctx->outputFileName;
        inputMd5FileName = ctx->inputMd5FileName;
        printf("%s[%d:%d] Thread work in %s mode\n", TAG, getpid(), gettid(),
        ctx->workMode == THREAD_WORK_MODE_SYNC ? "sync" :
            (ctx->workMode == THREAD_WORK_MODE_ASYNC ? "async" : "poll"));
        printf("%s[%d:%d] InputFileName = %s\n", TAG, getpid(), gettid(), inputFileName);
        printf("%s[%d:%d] OutputFileName = %s\n", TAG, getpid(), gettid(), outputFileName);
        printf("%s[%d:%d] InputMd5File = %s\n", TAG, getpid(), gettid(), inputMd5FileName);
        EXPECT_NE(inputFileName, nullptr);
        EXPECT_NE(outputFileName, nullptr);
        if (inputFileName == NULL || outputFileName == NULL) {
            return -1;
        }
        ctx->inFile = fopen(inputFileName, "rb");
        EXPECT_NE(ctx->inFile, nullptr);
        ctx->outFile = fopen(outputFileName, "wb+");
        EXPECT_NE(ctx->outFile, nullptr);
        if (ctx->inFile == NULL || ctx->outFile == NULL) {
            return -1;
        }
        if (ctx->md5Test == TRUE) {
            if (inputMd5FileName) {
                ctx->inMd5File = fopen(inputMd5FileName, "rb");
            }
            EXPECT_NE(ctx->inMd5File, nullptr);
            if (ctx->inMd5File == NULL) {
                return -1;
            }
        }
        // allocate ion buffers
        ctx->ionFd = ion_open();
        EXPECT_GT(ctx->ionFd, 0);
        if (ctx->ionFd <= 0) {
            return -1;
        }
        if (ctx->context->encoder == TRUE) {
            printf("%s[%d:%d] Thread use %s buffer mode, %d rc mode\n", TAG, getpid(), gettid(),
            ctx->context->video_enc_params.external_frame_buf ?
            "external" : "internal",
            ctx->context->video_enc_params.rc_params.mode);
            if (ctx->context->video_enc_params.external_frame_buf) {
                ctx->exFb = (ExternalFrameBuffer *) malloc(
                ctx->context->video_enc_params.frame_buf_count * sizeof(ExternalFrameBuffer));
                EXPECT_NE(ctx->exFb, nullptr);
                if (ctx->exFb == NULL) {
                    return -1;
                }
                for (Uint32 i=0; i<ctx->context->video_enc_params.frame_buf_count; i++) {
                    ctx->exFb[i].buf.size = ctx->context->video_enc_params.width
                    * ctx->context->video_enc_params.height * 3/2; // only for yuv420;
                    ret = allocate_ion_mem(ctx->ionFd, &ctx->exFb[i].buf);
                    EXPECT_EQ(ret, 0);
                    if (ret != 0) {
                        return ret;
                    }
                    ctx->exFb[i].valid = 1;
                    ctx->exFb[i].src_idx = i;
                }
            }
        } else {
            printf("%s[%d:%d] Thread use %s buffer mode, %d feed mode.\n", TAG, getpid(), gettid(),
            ctx->context->video_dec_params.external_bitstream_buf ?
            "external" : "internal",
            ctx->context->video_dec_params.feed_mode);
            if (ctx->context->video_dec_params.external_bitstream_buf) {
                ctx->exBs = (ExternalStreamBuffer *) malloc(
                ctx->context->video_dec_params.bitstream_buf_count * sizeof(ExternalStreamBuffer));
                EXPECT_NE(ctx->exBs, nullptr);
                if (ctx->exBs == NULL) {
                    return -1;
                }
                for (Uint32 i=0; i<ctx->context->video_dec_params.bitstream_buf_count; i++) {
                    ctx->exBs[i].buf.size = ctx->context->video_dec_params.bitstream_buf_size;
                    ret = allocate_ion_mem(ctx->ionFd, &ctx->exBs[i].buf);
                    EXPECT_EQ(ret, 0);
                    if (ret != 0) {
                        return ret;
                    }
                    ctx->exBs[i].valid = 1;
                    ctx->exBs[i].src_idx = i;
                }
            }
        }
    // open decode files
        if (ctx->context->encoder != TRUE) {
        if (ctx->context->video_dec_params.feed_mode == MC_FEEDING_MODE_FRAME_SIZE) {
            ret = avformat_open_input(&ctx->avContext, ctx->inputFileName, 0, 0);
            EXPECT_GE(ret, 0);
            if (ret < 0) {
                return ret;
            }
            ret = avformat_find_stream_info(ctx->avContext, 0);
            EXPECT_GE(ret, 0);
            if (ret < 0) {
                return ret;
            }
            ctx->videoIndex = av_find_best_stream(ctx->avContext, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
            EXPECT_GE(ctx->videoIndex, 0);
            if (ctx->videoIndex < 0) {
                return -1;
            }
            av_init_packet(&ctx->avpacket);
        } else {
            if (ctx->feedingSize == 0) {
                uint32_t KB = 1024;
                int32_t probability10;
                srand((uint32_t)time(NULL));
                ctx->feedingSize = rand() % MAX_FEEDING_SIZE;
                probability10 = (ctx->feedingSize % 100) < 10;
                if (ctx->feedingSize < KB) {
                    if (probability10 == FALSE)
                        ctx->feedingSize *= 100;
                    }
                }
                printf("%s[%d:%d] Feeding size = %d\n", TAG,
                getpid(), gettid(), ctx->feedingSize);
            }
            ctx->firstPacket = 1;
        }
        return 0;
    }
    static int check_and_release_test(MediaCodecTestContext *ctx) {
        int32_t ret = 0;
        int md5Match, wholeFileSize = 0;
        uint8_t *md5Buffer = NULL;
        EXPECT_NE(ctx, nullptr);
        EXPECT_NE(ctx->context, nullptr);
        EXPECT_NE(ctx->inFile, nullptr);
        EXPECT_NE(ctx->outFile, nullptr);
        if (ctx == NULL || ctx->context == NULL || ctx->inFile == NULL ||
            ctx->outFile == NULL) {
            return -1;
        }
        if (ctx->context->encoder != TRUE) {
            if (ctx->context->video_dec_params.feed_mode == MC_FEEDING_MODE_FRAME_SIZE) {
                if (ctx->avContext) {
                    avformat_close_input(&ctx->avContext);
                }
            }
        }
        if (ctx->context->encoder == TRUE) {
            if (ctx->context->video_enc_params.external_frame_buf) {
                if (ctx->exFb) {
                    for (Uint32 i=0; i<ctx->context->video_enc_params.frame_buf_count; i++) {
                        ret = release_ion_mem(ctx->ionFd, &ctx->exFb[i].buf);
                        EXPECT_EQ(ret, 0);
                    }
                    free(ctx->exFb);
                }
            }
        } else {
            if (ctx->context->video_dec_params.external_bitstream_buf) {
                if (ctx->exBs) {
                    for (Uint32 i=0; i<ctx->context->video_dec_params.bitstream_buf_count; i++) {
                        ret = release_ion_mem(ctx->ionFd, &ctx->exBs[i].buf);
                        EXPECT_EQ(ret, 0);
                    }
                    free(ctx->exBs);
                }
            }
        }
        if (ctx->ionFd)
            ion_close(ctx->ionFd);
        if (ctx->md5Test && ctx->inMd5File) {
            fseek(ctx->outFile, 0, SEEK_END);
            wholeFileSize = ftell(ctx->outFile);
            fseek(ctx->outFile, 0, SEEK_SET);
            md5Buffer = (uint8_t *)malloc(wholeFileSize);
            EXPECT_NE(md5Buffer, nullptr);
            if (md5Buffer == NULL) {
                return -1;
            }
            fread(md5Buffer, wholeFileSize, 1, ctx->outFile);
            md5Match = compare_md5_value(MD5_SIZE, ctx->inMd5File,
            md5Buffer, wholeFileSize);
            free(md5Buffer);
            fclose(ctx->inMd5File);
            EXPECT_EQ(md5Match, 1);
            if (md5Match != 1) {
                return -1;
            }
        }
        if (ctx->outFile)
            fclose(ctx->outFile);
        if (ctx->inFile)
            fclose(ctx->inFile);
        return 0;
    }
    static void on_vlc_buffer_message(hb_ptr userdata, hb_s32 * vlc_buf) {
        MediaCodecTestContext *ctx = (MediaCodecTestContext *)userdata;
        ASSERT_NE(vlc_buf, nullptr);
        ASSERT_NE(ctx, nullptr);
        ASSERT_GE(ctx->vlc_buf_size, 0);
        if (ctx->testLog) {
            printf("%s %s VLC Buffer size = %d; Reset to %d.\n", TAG, __FUNCTION__,
            *vlc_buf, ctx->vlc_buf_size);
        }
        *vlc_buf = ctx->vlc_buf_size;
    }
    static int read_input_streams(MediaCodecTestContext *ctx,
        media_codec_buffer_t *inputBuffer) {
        Uint64 curTime = 0;
        int ret = 0, ret2 = 0;
        Uint32 bufIdx = 0, srcIdx = 0;
        Int32 doRead = TRUE, doRewind = FALSE;
        uint8_t *seqHeader = NULL;
        int seqHeaderSize = 0;
        void *bufPtr = NULL;
        int avalBufSize = 0;
        EXPECT_NE(ctx, nullptr);
        EXPECT_NE(ctx->context, nullptr);
        EXPECT_NE(ctx->inFile, nullptr);
        EXPECT_NE(ctx->outFile, nullptr);
        EXPECT_NE(inputBuffer, nullptr);
        if (ctx == NULL || ctx->context == NULL || ctx->inFile == NULL ||
            ctx->outFile == NULL || inputBuffer == NULL) {
            printf("%s[%d:%d] Invalid parameters(%s).\n",
            TAG, getpid(), gettid(), __FUNCTION__);
            return -1;
        }
        if (ctx->stabilityTest || ctx->pfTest) {
            doRewind = TRUE;
            curTime = osal_gettime();
            if ((curTime - ctx->testStartTime)/1000 < (uint32_t)ctx->duration) {
                doRead = TRUE;
            } else {
                printf("%s[%d:%d] Time up(%d)\n",
                TAG, getpid(), gettid(), ctx->duration);
                doRead = FALSE;
                ret = 0;
            }
        }
        if (ctx->context->video_dec_params.external_bitstream_buf) {
            // release input buffer and take it as the new input buffer
            for (bufIdx = 0;
                bufIdx < ctx->context->video_dec_params.bitstream_buf_count;
                bufIdx++) {
                if (ctx->exBs[bufIdx].valid &&
                    ctx->exBs[bufIdx].src_idx == inputBuffer->vstream_buf.src_idx) {
                    srcIdx = inputBuffer->vstream_buf.src_idx;
                    break;
                }
            }
            EXPECT_NE(bufIdx, ctx->context->video_dec_params.bitstream_buf_count);
            if (bufIdx == ctx->context->video_dec_params.bitstream_buf_count) {
                return -1;
            }
            bufPtr = (void *)ctx->exBs[srcIdx].buf.virt_addr;
            if (ctx->context->video_dec_params.feed_mode ==
                MC_FEEDING_MODE_FRAME_SIZE) {
                avalBufSize = ctx->exBs[srcIdx].buf.size;
            } else {
                avalBufSize = (ctx->exBs[srcIdx].buf.size < (int)ctx->feedingSize) ?
                ctx->exBs[srcIdx].buf.size : ctx->feedingSize;
            }
            inputBuffer->vstream_buf.fd = ctx->exBs[srcIdx].buf.fd;
            inputBuffer->vstream_buf.phy_ptr =
            ctx->exBs[srcIdx].buf.phys_addr;
            inputBuffer->vstream_buf.vir_ptr =
            (hb_u8 *)ctx->exBs[srcIdx].buf.virt_addr;
        } else {
            bufPtr = (void *)inputBuffer->vstream_buf.vir_ptr;
            if (ctx->context->video_dec_params.feed_mode ==
                MC_FEEDING_MODE_FRAME_SIZE) {
                avalBufSize = inputBuffer->vstream_buf.size;
            } else {
                avalBufSize = (inputBuffer->vstream_buf.size < ctx->feedingSize) ?
                inputBuffer->vstream_buf.size : ctx->feedingSize;
            }
        }
        if (doRead == FALSE) {
            return ret;
        }
        // MC_FEEDING_MODE_FRAME_SIZE mode
        if (ctx->context->video_dec_params.feed_mode == MC_FEEDING_MODE_FRAME_SIZE) {
            do {
                if (ctx->avpacket.size == 0) {
                    ret = av_read_frame(ctx->avContext, &ctx->avpacket);
                    if (ret < 0 && doRewind == FALSE) {
                        printf("%s[%d:%d] Failed to read input file (error=0x%x)\n",
                            TAG, getpid(), gettid(), ret);
                    }
                    if (ret < 0 && doRewind == TRUE) {
                        avformat_close_input(&ctx->avContext);
                        ret2 = avformat_open_input(&ctx->avContext, ctx->inputFileName, 0, 0);
                        EXPECT_GE(ret2, 0);
                        if (ret2 < 0) {
                            ret = ret2;
                            break;
                        }
                        av_init_packet(&ctx->avpacket);
                    }
                } else {
                    if (ctx->testLog) {
                        printf("%s[%d:%d] Reuse previous stream packet size %d\n",
                        TAG, getpid(), gettid(), ctx->avpacket.size);
                    }
                }
            } while (ret < 0 && doRewind == TRUE);
            if (ret < 0) {
                if (ret == AVERROR_EOF || ctx->avContext->pb->eof_reached == TRUE) {
                    printf("%s[%d:%d] End of file!\n", TAG, getpid(), gettid());
                    ret = 0;
                } else {
                    printf("%s[%d:%d] Failed to av_read_frame error(0x%08x)\n",
                    TAG, getpid(), gettid(), ret);
                }
                return ret;
            }
            if (ctx->testLog) {
                printf("%s[%d:%d] Read packet size %d\n",
                    TAG, getpid(), gettid(), ctx->avpacket.size);
            }
            seqHeaderSize = 0;
            if (ctx->firstPacket) {
                AVCodecParameters* codec;
                int retSize = 0;
                codec = ctx->avContext->streams[ctx->videoIndex]->codecpar;
                seqHeader = (uint8_t*)malloc(codec->extradata_size + 1024);
                if (seqHeader == NULL) {
                    printf("%s[%d:%d] Failed to malloc seqHeader\n",
                    TAG, getpid(), gettid());
                    ret = -1;
                    return ret;
                }
                memset((void*)seqHeader, 0x00, codec->extradata_size + 1024);
                seqHeaderSize = build_dec_seq_header(seqHeader,
                ctx->context->codec_id,
                ctx->avContext->streams[ctx->videoIndex], &retSize);
                if (seqHeaderSize < 0) {
                    printf("%s[%d:%d] Failed to build seqHeader\n",
                    TAG, getpid(), gettid());
                    ret = -1;
                    return ret;
                }
                ctx->firstPacket = 0;
            }
            if ((ctx->avpacket.size <= avalBufSize)
                && (seqHeaderSize <= avalBufSize)) {
                int bufSize = 0;
                if (seqHeaderSize) {
                    memcpy(bufPtr, seqHeader, seqHeaderSize);
                    bufSize = seqHeaderSize;
                } else {
                    memcpy(bufPtr,ctx->avpacket.data, ctx->avpacket.size);
                    bufSize = ctx->avpacket.size;
                    av_packet_unref(&ctx->avpacket);
                    ctx->avpacket.size = 0;
                }
                inputBuffer->vstream_buf.size = bufSize;
            } else {
                printf("%s[%d:%d] The stream buffer is too small!\n", TAG, getpid(), gettid());
                return -1;
            }
            if (seqHeader) {
                free(seqHeader);
                seqHeader = NULL;
            }
            return 1;
        }
        // MC_FEEDING_MODE_STREAM_SIZE mode
        do {
            ret = fread(bufPtr, 1, avalBufSize, ctx->inFile);
            if (ret <= 0 && doRewind == FALSE) {
                printf("%s[%d:%d] Failed to read input file (error=0x%x)\n",
                    TAG, getpid(), gettid(), ret);
            }
            if (ret <= 0 && doRewind == TRUE) {
                if(fseek(ctx->inFile, 0, SEEK_SET)) {
                    printf("%s Failed to rewind input file (pid=%d, tid=%d)\n",
                        TAG, getpid(), gettid());
                    break;
                }
            }
        } while (ret == 0 && doRewind == TRUE);
        inputBuffer->vstream_buf.size = ret > 0 ? ret : 0;
        return ret;
    }
    static int write_output_frames(MediaCodecTestContext *ctx,
        media_codec_buffer_t *outputBuffer) {
        int32_t ret = 0;
        EXPECT_NE(ctx, nullptr);
        EXPECT_NE(ctx->context, nullptr);
        EXPECT_NE(ctx->inFile, nullptr);
        EXPECT_NE(ctx->outFile, nullptr);
        EXPECT_NE(outputBuffer, nullptr);
        if (ctx == NULL || ctx->context == NULL || ctx->inFile == NULL ||
            ctx->outFile == NULL || outputBuffer == NULL) {
            printf("%s[%d:%d] Invalid parameters(%s).\n",
            TAG, getpid(), gettid(), __FUNCTION__);
            return -1;
        }
        if (!ctx->stabilityTest && !ctx->pfTest) {
            fwrite(outputBuffer->vframe_buf.vir_ptr[0], outputBuffer->vframe_buf.size,
                1, ctx->outFile);
        }
        return ret;
    }
    static int do_decode_params_checking(MediaCodecTestContext *ctx,
        media_codec_buffer_t *outputBuffer) {
        media_codec_context_t *context;
        int32_t ret = 0;
        EXPECT_NE(ctx, nullptr);
        EXPECT_NE(ctx->context, nullptr);
        if (ctx == NULL || ctx->context == NULL || ctx->inFile == NULL ||
            ctx->outFile == NULL || outputBuffer == NULL) {
            printf("%s[%d:%d] Invalid parameters(%s).\n",
            TAG, getpid(), gettid(), __FUNCTION__);
            return -1;
        }
        context = ctx->context;
        if (ctx->enable_get_userdata) {
            mc_user_data_buffer_t userdata = {0};
            ret = hb_mm_mc_get_user_data(context, &userdata, 0);
            if (!ret) {
                printf("%s[%d:%d] Get userdata %d:\n", TAG, getpid(), gettid(), userdata.size);
                for (uint32_t i = 0; i < userdata.size; i++) {
                    if (i < 16) {
                        printf("%s[%d:%d] userdata[i]:%x\n", TAG, getpid(), gettid(), userdata.virt_addr[i]);
                    } else {
                        printf("%s[%d:%d] userdata[i]:%c\n", TAG, getpid(), gettid(), userdata.virt_addr[i]);
                    }
                }
                ret = hb_mm_mc_release_user_data(context, &userdata);
            } else {
                ret = 0;
            }
        }
        return ret;
    }
    static void do_sync_decoding(void *arg) {
        int ret = 0;
        int step = 0;
        MediaCodecTestContext *ctx = (MediaCodecTestContext *)arg;
        media_codec_context_t *context;
        media_codec_callback_t callback;
        media_codec_buffer_t inputBuffer;
        media_codec_buffer_t outputBuffer;
        media_codec_output_buffer_info_t info;
        int32_t decStartTime = 0, decFinishTime = 0;
        ctx->workMode = THREAD_WORK_MODE_SYNC;
        ASSERT_EQ(check_and_init_test(ctx), 0);
        context = ctx->context;
        //get current time
        ctx->testStartTime = osal_gettime();
        if (ctx->testLog) {
            printf("%s[%d:%d] Step %d initialize (outFile=%s, FileFd=%p)\n",
                TAG, getpid(), gettid(), step++, ctx->outputFileName, ctx->outFile);
        }
        ret = hb_mm_mc_initialize(context);
        ASSERT_EQ(ret, (int32_t)0);
        callback.on_vlc_buffer_message = on_vlc_buffer_message;
        if (ctx->vlc_buf_size > 0) {
            ret = hb_mm_mc_set_vlc_buffer_listener(context, &callback, ctx);
            ASSERT_EQ(ret, (int32_t)0);
        }
        if (ctx->testLog) {
            printf("%s[%d:%d] Step %d configure\n", TAG, getpid(), gettid(), step++);
        }
        ret = hb_mm_mc_configure(context);
        EXPECT_EQ(ret, (int32_t)0);
        if (ctx->testLog) {
            printf("%s[%d:%d] Step %d start\n", TAG, getpid(), gettid(), step++);
        }
        mc_av_codec_startup_params_t startup_params;
        memset(&startup_params, 0x00, sizeof(mc_av_codec_startup_params_t));
        ret = hb_mm_mc_start(context, &startup_params);
        EXPECT_EQ(ret, (int32_t)0);
        do {
            if (!ctx->lastStream) {
                if (ctx->testLog) {
                    printf("%s[%d:%d] Step %d dequeue input\n", TAG, getpid(), gettid(), step++);
                }
                // process input buffers
                ret = hb_mm_mc_dequeue_input_buffer(context, &inputBuffer, 3000);
                if (!ret) {
                    if (ctx->testLog) {
                        printf("%s[%d:%d] input buffer viraddr %p phy addr %x, size = %d\n",
                        TAG, getpid(), gettid(), inputBuffer.vstream_buf.vir_ptr,
                        inputBuffer.vstream_buf.phy_ptr,
                        inputBuffer.vstream_buf.size);
                    }
                    if (ctx->testLog) {
                        printf("%s[%d:%d] Step %d feed input (pid=%d, tid=%d)\n", TAG, getpid(), gettid(), step++);
                    }
                    ret = read_input_streams(ctx, &inputBuffer);
                    if (ret <= 0) {
                        printf("%s[%d:%d] There is no more input data(ret=%d)!\n",
                        TAG, getpid(), gettid(), ret);
                        inputBuffer.vstream_buf.stream_end = TRUE;
                        inputBuffer.vstream_buf.size = 0;
                        ctx->lastStream = 1;
                    }
                    if (ctx->testLog) {
                        printf("%s[%d:%d] Step %d queue input(size=%d)\n",
                        TAG, getpid(), gettid(), step++, inputBuffer.vstream_buf.size);
                    }
                    ret = hb_mm_mc_queue_input_buffer(context, &inputBuffer, 100);
                    EXPECT_EQ(ret, (int32_t)0);
                    if (ret != 0) {
                        break;
                    }
                    if (ctx->delaytest) {
                        decStartTime = osal_gettime();
                    }
                } else {
                    if (ret != (int32_t)HB_MEDIA_ERR_WAIT_TIMEOUT) {
                        EXPECT_EQ(ret, (int32_t)0);
                        char info[256];
                        hb_mm_strerror(ret, info, 256);
                        printf("%s[%d:%d] dequeue input buffer fail.(%s)\n", TAG, getpid(), gettid(), info);
                        break;
                    }
                }
            }
            if (!ctx->lastFrame) {
                if (ctx->testLog) {
                printf("%s[%d:%d] Step %d dequeue output\n", TAG, getpid(), gettid(), step++);
                }
                // process output buffers
                memset(&outputBuffer, 0x00, sizeof(media_codec_buffer_t));
                memset(&info, 0x00, sizeof(media_codec_output_buffer_info_t));
                ret = hb_mm_mc_dequeue_output_buffer(context, &outputBuffer, &info, 100);
                if (!ret) {
                    if (ctx->testLog) {
                        printf("%s[%d:%d] output buffer viraddr %p phy addr %x, size = %d, outFile = %p\n",
                        TAG, getpid(), gettid(), outputBuffer.vframe_buf.vir_ptr[0],
                        outputBuffer.vframe_buf.phy_ptr[0],
                        outputBuffer.vframe_buf.size, ctx->outFile);
                    }
                    if (ctx->testLog) {
                        printf("%s[%d:%d] Step %d write output file\n", TAG, getpid(), gettid(), step++);
                    }
                    if (ctx->delaytest) {
                        decFinishTime = osal_gettime();
                        if ((decFinishTime - decStartTime) >= ctx->delaytime) {
                            printf("%s[%d:%d] Decoding time is %d, more than %dms\n",
                            TAG, getpid(), gettid(), (decFinishTime - decStartTime), ctx->delaytime);
                            ASSERT_LE((decFinishTime - decStartTime), ctx->delaytime);
                        }
                    }
                    ASSERT_EQ(write_output_frames(ctx, &outputBuffer), 0);
                    if (ctx->testLog) {
                        printf("%s[%d:%d] Step %d queue output\n", TAG, getpid(), gettid(), step++);
                    }
                    ASSERT_EQ(do_decode_params_checking(ctx, &outputBuffer), 0);
                    ret = hb_mm_mc_queue_output_buffer(context, &outputBuffer, 100);
                    EXPECT_EQ(ret, (int32_t)0);
                    if (outputBuffer.vframe_buf.frame_end) {
                        printf("%s[%d:%d] There is no more output data!\n", TAG, getpid(), gettid());
                        ctx->lastFrame = 1;
                        break;
                    }
                    if (ret) {
                        break;
                    }
                } else {
                    char info[256];
                    hb_mm_strerror(ret, info, 256);
                    printf("%s[%d:%d] dequeue output buffer fail.(%s)\n", TAG, getpid(), gettid(), info);
                    if (ret != (int32_t)HB_MEDIA_ERR_WAIT_TIMEOUT) {
                        EXPECT_EQ(ret, (int32_t)0);
                        break;
                    }
                    if (ctx->stabilityTest && ctx->lastStream ==1) {
                        break;
                    }
                }
            }
        }while(TRUE);
        ret = hb_mm_mc_stop(context);
        EXPECT_EQ(ret, (int32_t)0);
        ret = hb_mm_mc_release(context);
        EXPECT_EQ(ret, (int32_t)0);
        ASSERT_EQ(check_and_release_test(ctx), 0);
    }
    int main(int argc, char *argv[])
    {
        char outputFileName[MAX_FILE_PATH] = "input.h265";
        char inputFileName[MAX_FILE_PATH] = "output.yuv";
        mTestWidth = 640;
        mTestHeight = 480;
        mTestPixFmt = MC_PIXEL_FORMAT_YUV420P;
        mTestFeedMode = MC_FEEDING_MODE_FRAME_SIZE;
        mTestCodec = TEST_CODEC_ID_H265;
        mc_video_codec_dec_params_t *params;
        media_codec_context_t *context = (media_codec_context_t *)malloc(sizeof(media_codec_context_t ));
        ASSERT_NE(context, nullptr);
        memset(context, 0x00, sizeof(media_codec_context_t));
        context->codec_id = get_codec_id(mTestCodec);
        context->encoder = FALSE;
        params = &context->video_dec_params;
        params->feed_mode = mTestFeedMode;
        params->pix_fmt = mTestPixFmt;
        params->bitstream_buf_size = mTestWidth * mTestHeight * 3 / 2;
        params->bitstream_buf_count = 6;
        params->frame_buf_count = 8;
        if (context->codec_id == MEDIA_CODEC_ID_H265) {
            params->h265_dec_config.bandwidth_Opt = TRUE;
            params->h265_dec_config.reorder_enable = TRUE;
            params->h265_dec_config.skip_mode = 0;
            params->h265_dec_config.cra_as_bla = FALSE;
            params->h265_dec_config.dec_temporal_id_mode = 0;
            params->h265_dec_config.target_dec_temporal_id_plus1 = 0;
        }
        MediaCodecTestContext ctx;
        memset(&ctx, 0x00, sizeof(ctx));
        ctx.context = context;
        ctx.inputFileName = inputFileName;
        ctx.outputFileName = outputFileName;
        char inputMd5FileName[MAX_FILE_PATH];
        if (ctx.md5Test) {
            char inputMd5Suffix[MAX_FILE_PATH] = ".md5";
            snprintf(dedicatedSuffix, MAX_FILE_PATH, "%s", "dec");
            snprintf(inputMd5FileName, MAX_FILE_PATH, "%s%s_%s_%s%s",
            dedicatedInputPrefix, mGlobalPixFmtName[mTestPixFmt],
            dedicatedSuffix, mGlobalCodecName[mTestCodec], inputMd5Suffix);
            ctx.inputMd5FileName = inputMd5FileName;
        }
        do_sync_decoding(&ctx);
        if (context != NULL) {
            free(context);
        }
    }

5.12.4.48. hb_mm_mc_release_user_data

【Function Declaration】

hb_s32 hb_mm_mc_release_user_data(media_codec_context_t * context,
const mc_user_data_buffer_t * params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] const mc_user_data_buffer_t * params: User data

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Releases user data from the decoded stream, applicable to H264/H265.

【Example Code】

See: hb_mm_mc_get_user_data

5.12.4.49. hb_mm_mc_get_mjpeg_config

【Function Declaration】

hb_s32 hb_mm_mc_get_mjpeg_config(media_codec_context_t *context,
mc_mjpeg_enc_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [OUT] mc_mjpeg_enc_params_t *params: MJPEG encoding parameters

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Retrieves MJPEG encoding parameters, applicable to MJPEG.

【Example Code】


    #include "hb_media_codec.h"
    #include "hb_media_error.h"
    int main(int argc, char *argv[])
    {
        int ret = 0;
        char outputFileName[MAX_FILE_PATH];
        char inputFileName[MAX_FILE_PATH];
        mTestCodec = TEST_CODEC_ID_MJPEG;
        mTestPixFmt = MC_PIXEL_FORMAT_NV12;
        char dedicatedSuffix[MAX_FILE_PATH] = "_test";
        char inputSuffix[MAX_FILE_PATH] = ".yuv";
        char outputSuffixJpeg[MAX_FILE_PATH] = ".jpg";
        char outputSuffixMjpg[MAX_FILE_PATH] = ".mjpg";
        snprintf(inputFileName, MAX_FILE_PATH, "%s%s%s",
            mInputSpecPrefix, mTest12Bit ? mGlobal12BPixFmtName[mTestPixFmt]
            : mGlobalPixFmtName[mTestPixFmt], inputSuffix);
        snprintf(outputFileName, MAX_FILE_PATH, "%s%s%s%s",
            mOutputSpecPrefix, mTest12Bit ? mGlobal12BPixFmtName[mTestPixFmt]
            : mGlobalPixFmtName[mTestPixFmt], dedicatedSuffix,
        mTestCodec == TEST_CODEC_ID_JPEG ? outputSuffixJpeg : outputSuffixMjpg);
        mc_video_codec_enc_params_t *params;
        media_codec_context_t *context = (media_codec_context_t *)malloc(sizeof(media_codec_context_t ));
        ASSERT_NE(context, nullptr);
        memset(context, 0x00, sizeof(media_codec_context_t));
        context->codec_id = mTestCodec == TEST_CODEC_ID_JPEG ?
            MEDIA_CODEC_ID_JPEG : MEDIA_CODEC_ID_MJPEG;
        context->encoder = TRUE;
        params = &context->video_enc_params;
        params->width = mTestWidth;
        params->height = mTestHeight;
        params->pix_fmt = mTestPixFmt;
        params->frame_buf_count = 5;
        params->bitstream_buf_count = 5;
        params->rot_degree = MC_CCW_0;
        params->mir_direction = MC_DIRECTION_NONE;
        params->frame_cropping_flag = FALSE;
        params->external_frame_buf = FALSE;
        if (context->codec_id == MEDIA_CODEC_ID_MJPEG) {
            params->rc_params.mode = MC_AV_RC_MODE_MJPEGFIXQP;
            ret = hb_mm_mc_get_rate_control_config(context, &params->rc_params);
            ASSERT_EQ(ret, (int32_t)0);
            params->mjpeg_enc_config.restart_interval = mTestWidth/16;
            params->mjpeg_enc_config.extended_sequential = mTest12Bit;
        } else {
            params->jpeg_enc_config.restart_interval = mTestWidth/16;
            params->jpeg_enc_config.extended_sequential = mTest12Bit;
        }
        mc_mjpeg_enc_params_t mjpeg_params;
        memset(&mjpeg_params, 0x00, sizeof(mjpeg_params));
        ret = hb_mm_mc_get_mjpeg_config(context, &mjpeg_params);
        ASSERT_EQ(ret, (int32_t)0);
        ret = hb_mm_mc_initialize(context);
        ASSERT_EQ(ret, (int32_t)0);
        ret = hb_mm_mc_set_mjpeg_config(context, &mjpeg_params);
        ASSERT_EQ(ret, (int32_t)0);
        ret = hb_mm_mc_stop(context);
        ASSERT_EQ(ret, (int32_t)0);
        ret = hb_mm_mc_release(context);
        ASSERT_EQ(ret, (int32_t)0);
        if (context != NULL) {
            free(context);
        }
    }

5.12.4.50. hb_mm_mc_set_mjpeg_config

【Function Declaration】

hb_s32 hb_mm_mc_set_mjpeg_config(media_codec_context_t *context, const
mc_mjpeg_enc_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] const mc_mjpeg_enc_params_t *params: MJPEG encoding parameters

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Sets MJPEG encoding parameters. These are dynamic parameters and applicable to MJPEG.

【Example Code】

See: hb_mm_mc_get_mjpeg_config

5.12.4.51. hb_mm_mc_get_jpeg_config

【Function Declaration】

hb_s32 hb_mm_mc_get_jpeg_config(media_codec_context_t *context,
mc_jpeg_enc_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [OUT] mc_jpeg_enc_params_t *params: JPEG encoding parameters

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Retrieves JPEG encoding parameters, applicable to JPEG.

【Example Code】


    #include "hb_media_codec.h"
    #include "hb_media_error.h"
    int main(int argc, char *argv[])
    {
        int ret = 0;
        char outputFileName[MAX_FILE_PATH];
        char inputFileName[MAX_FILE_PATH];
        mTestCodec = TEST_CODEC_ID_JPEG;
        mTestPixFmt = MC_PIXEL_FORMAT_NV12;
        char dedicatedSuffix[MAX_FILE_PATH] = "_test";
        char inputSuffix[MAX_FILE_PATH] = ".yuv";
        char outputSuffixJpeg[MAX_FILE_PATH] = ".jpg";
        char outputSuffixMjpg[MAX_FILE_PATH] = ".mjpg";
        snprintf(inputFileName, MAX_FILE_PATH, "%s%s%s",
            mInputSpecPrefix, mTest12Bit ? mGlobal12BPixFmtName[mTestPixFmt]
            : mGlobalPixFmtName[mTestPixFmt], inputSuffix);
        snprintf(outputFileName, MAX_FILE_PATH, "%s%s%s%s",
            mOutputSpecPrefix, mTest12Bit ? mGlobal12BPixFmtName[mTestPixFmt]
            : mGlobalPixFmtName[mTestPixFmt], dedicatedSuffix,
            mTestCodec == TEST_CODEC_ID_JPEG ? outputSuffixJpeg : outputSuffixMjpg);
        mc_video_codec_enc_params_t *params;
        media_codec_context_t *context = (media_codec_context_t *)malloc(sizeof(media_codec_context_t ));
        ASSERT_NE(context, nullptr);
        memset(context, 0x00, sizeof(media_codec_context_t));
        context->codec_id = mTestCodec == TEST_CODEC_ID_JPEG ?
        MEDIA_CODEC_ID_JPEG : MEDIA_CODEC_ID_MJPEG;
        context->encoder = TRUE;
        params = &context->video_enc_params;
        params->width = mTestWidth;
        params->height = mTestHeight;
        params->pix_fmt = mTestPixFmt;
        params->frame_buf_count = 5;
        params->bitstream_buf_count = 5;
        params->rot_degree = MC_CCW_0;
        params->mir_direction = MC_DIRECTION_NONE;
        params->frame_cropping_flag = FALSE;
        params->external_frame_buf = FALSE;
        if (context->codec_id == MEDIA_CODEC_ID_MJPEG) {
            params->rc_params.mode = MC_AV_RC_MODE_MJPEGFIXQP;
            ret = hb_mm_mc_get_rate_control_config(context, &params->rc_params);
            ASSERT_EQ(ret, (int32_t)0);
            params->mjpeg_enc_config.restart_interval = mTestWidth/16;
            params->mjpeg_enc_config.extended_sequential = mTest12Bit;
        } else {
            params->jpeg_enc_config.restart_interval = mTestWidth/16;
            params->jpeg_enc_config.extended_sequential = mTest12Bit;
        }
        mc_jpeg_enc_params_t jpeg_params;
        memset(&jpeg_params, 0x00, sizeof(jpeg_params));
        ret = hb_mm_mc_get_jpeg_config(context, &jpeg_params);
        ASSERT_EQ(ret, (int32_t)0);
        ret = hb_mm_mc_initialize(context);
        ASSERT_EQ(ret, (int32_t)0);
        jpeg_params.quality_factor = 30;
        jpeg_params.restart_interval = (((params->width+15)>>4) *
            ((params->height+15)>>4) * 2) + 1;
        jpeg_params.crop_en = FALSE;
        ret = hb_mm_mc_set_jpeg_config(context, &jpeg_params);
        ASSERT_EQ(ret, (int32_t)HB_MEDIA_ERR_INVALID_PARAMS);
        jpeg_params.restart_interval = 70;
        ret = hb_mm_mc_set_jpeg_config(context, &jpeg_params);
        ASSERT_EQ(ret, (int32_t)0);
        ret = hb_mm_mc_stop(context);
        ASSERT_EQ(ret, (int32_t)0);
        ret = hb_mm_mc_release(context);
        ASSERT_EQ(ret, (int32_t)0);
        if (context != NULL) {
            free(context);
        }
    }

5.12.4.52. hb_mm_mc_set_jpeg_config

【Function Declaration】

hb_s32 hb_mm_mc_set_jpeg_config(media_codec_context_t *context, const
mc_jpeg_enc_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] const mc_jpeg_enc_params_t *params: JPEG encoding parameters

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Sets JPEG encoding parameters. These are dynamic parameters and applicable to JPEG.

【Example Code】

See: hb_mm_mc_get_jpeg_config

5.12.4.53. hb_mm_mc_get_fd

【Function Declaration】

hb_s32 hb_mm_mc_get_fd(media_codec_context_t * context, hb_s32 *fd)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [OUT] hb_s32 *fd: Device node file descriptor (fd)

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Retrieves the device node file descriptor (fd), which can be used for select operations to monitor encoding/decoding results.

【Example Code】


    #include "hb_media_codec.h"
    #include "hb_media_error.h"

    typedef struct MediaCodecTestContext {
        media_codec_context_t *context;
        char *inputFileName;
        char *outputFileName;
        int abnormal;
        int32_t duration; // s
    } MediaCodecTestContext;

    Uint64 osal_gettime(void)
    {
        struct timespec tp;

        clock_gettime(CLOCK_MONOTONIC, &tp);

        return ((Uint64)tp.tv_sec*1000 + tp.tv_nsec/1000000);
    }

    static void do_poll_encoding_select(void *arg) {
        hb_s32 ret = 0;
        int pollFd = -1;
        FILE *outFile;
        int lastStream = 0;
        fd_set readFds;
        MediaCodecTestContext *ctx = (MediaCodecTestContext *)arg;
        media_codec_context_t *context = ctx->context;
        char *outputFileName = ctx->outputFileName;
        mc_inter_status_t status;

        outFile = fopen(outputFileName, "wb");
        if (!outFile) {
            goto ERR;
        }

        ret = hb_mm_mc_get_fd(context, &pollFd);
        if (ret) {
            goto ERR;
        }

        do {
            FD_ZERO(&readFds);
            FD_SET(pollFd, &readFds);
            ret = select(pollFd+1, &readFds, NULL, NULL, NULL);
            if (ret < 0) {
                printf("Failed to select fd = %d.(err %s)\n", pollFd, strerror(errno));
                ctx->abnormal = TRUE;
                break;
            } else if (ret == 0) {
                printf("Time out to select fd = %d.\n", pollFd);
                ctx->abnormal = TRUE;
                break;
            } else {
                if (FD_ISSET(pollFd, &readFds)) {
                    ASSERT_EQ(hb_mm_mc_get_status(context, &status), (int32_t)0);
                    if (ctx->testLog) {
                        printf("%s[%d:%d] output count %d input count %d\n", TAG, getpid(), gettid(),
                        status.cur_output_buf_cnt, status.cur_input_buf_cnt);
                    }
                    media_codec_buffer_t outputBuffer;
                    media_codec_output_buffer_info_t info;
                    memset(&outputBuffer, 0x00, sizeof(media_codec_buffer_t));
                    memset(&info, 0x00, sizeof(media_codec_output_buffer_info_t));
                    ret = hb_mm_mc_dequeue_output_buffer(context, &outputBuffer, &info, 100);
                    if (!ret && outFile) {
                        fwrite(outputBuffer.vstream_buf.vir_ptr, outputBuffer.vstream_buf.size, 1, outFile);
                        ret = hb_mm_mc_queue_output_buffer(context, &outputBuffer, 100);

                        if (outputBuffer.vstream_buf.stream_end) {
                            printf("%There is no more output data!\n");
                            lastStream = 1;
                            break;
                        }
                        if (ret) {
                            ctx->abnormal = TRUE;
                            break;
                        }
                    } else {
                        if (ret != (int32_t)HB_MEDIA_ERR_WAIT_TIMEOUT) {
                            printf("Dequeue output buffer fail.\n");
                            break;
                        }
                    }
                }
            }
        } while (!lastStream && !ctx->abnormal);

    ERR:
        if (pollFd) {
            hb_mm_mc_close_fd(context, pollFd);
        }
        if (outFile)
            fclose(outFile);
    }

    static void do_poll_encoding(void *arg) {
        pthread_t thread_id;
        void* retVal;
        hb_s32 ret = 0;
        FILE *inFile;
        int noMoreInput = 0;
        MediaCodecTestContext *ctx = (MediaCodecTestContext *)arg;
        media_codec_context_t *context = ctx->context;

        char *inputFileName = ctx->inputFileName;
        char *outputFileName = ctx->outputFileName;
        media_codec_state_t state = MEDIA_CODEC_STATE_NONE;
        inFile = fopen(inputFileName, "rb");
        if (!inFile) {
            goto ERR;
        }

        ret = hb_mm_mc_initialize(context);
        if (ret) {
            goto ERR;
        }

        ret = hb_mm_mc_configure(context);
        if (ret) {
            goto ERR;
        }

        mc_av_codec_startup_params_t startup_params;
        startup_params.video_enc_startup_params.receive_frame_number = 0;
        ret = hb_mm_mc_start(context, &startup_params);
        if (ret) {
            goto ERR;
        }

        pthread_create(&thread_id, NULL, (void* (*)(void*))do_poll_encoding_select, ctx);

        do {
            media_codec_buffer_t inputBuffer;
            memset(&inputBuffer, 0x00, sizeof(media_codec_buffer_t));
            ret = hb_mm_mc_dequeue_input_buffer(context, &inputBuffer, 100);
            if (!ret) {
                ret = fread(inputBuffer.vframe_buf.vir_ptr[0], 1,
                    inputBuffer.vframe_buf.size, inFile);
                if (!ret) {
                    printf("There is no more input data!\n");
                    inputBuffer.vframe_buf.frame_end = TRUE;
                    noMoreInput = 1;
                }
                ret = hb_mm_mc_queue_input_buffer(context, &inputBuffer, 100);
                if (ret) {
                    printf("Queue input buffer fail.\n");
                    break;
                }
            } else {
                if (ret != (int32_t)HB_MEDIA_ERR_WAIT_TIMEOUT) {
                    printf("Dequeue input buffer fail.\n");
                    break;
                }
            }
        } while (!noMoreInput && !ctx->abnormal);

        pthread_join(thread_id, &retVal);

        hb_mm_mc_stop(context);

        hb_mm_mc_release(context);
        context = NULL;

    ERR:
        hb_mm_mc_get_state(context, &state);
        if (context && state != MEDIA_CODEC_STATE_UNINITIALIZED) {
            hb_mm_mc_stop(context);
            hb_mm_mc_release(context);
        }

        if (inFile)
            fclose(inFile);
    }

    int main(int argc, char *argv[])
    {
        hb_s32 ret = 0;
        char outputFileName[MAX_FILE_PATH] = "./tmp.yuv";
        char inputFileName[MAX_FILE_PATH] = "./output.stream";
        mc_video_codec_enc_params_t *params;
        media_codec_context_t context;

        memset(&context, 0x00, sizeof(media_codec_context_t));
        context.codec_id = MEDIA_CODEC_ID_H265;
        context.encoder = TRUE;
        params = &context.video_enc_params;
        params->width = 640;
        params->height = 480;
        params->pix_fmt = MC_PIXEL_FORMAT_YUV420P;
        params->frame_buf_count = 5;
        params->external_frame_buf = FALSE;
        params->bitstream_buf_count = 5;
        params->rc_params.mode = MC_AV_RC_MODE_H265CBR;
        ret = hb_mm_mc_get_rate_control_config(&context, &params->rc_params);
        if (ret) {
            return -1;
        }
        params->rc_params.h265_cbr_params.bit_rate = 5000;
        params->rc_params.h265_cbr_params.frame_rate = 30;
        params->rc_params.h265_cbr_params.intra_period = 30;
        params->gop_params.decoding_refresh_type = 2;
        params->gop_params.gop_preset_idx = 9;
        params->rot_degree = MC_CCW_0;
        params->mir_direction = MC_DIRECTION_NONE;
        params->frame_cropping_flag = FALSE;

        MediaCodecTestContext ctx;
        memset(&ctx, 0x00, sizeof(ctx));
        ctx.context = &context;
        ctx.inputFileName = inputFileName;
        ctx.outputFileName = outputFileName;
        ctx.duration = 5;
        do_poll_encoding(&ctx);
    }

5.12.4.54. hb_mm_mc_close_fd

【Function Declaration】

hb_s32 hb_mm_mc_close_fd(media_codec_context_t * context, hb_s32 fd)

【Parameter Description】

  • [IN] media_codec_context_t *context: The context specifying the codec type

  • [IN] hb_s32 fd: File descriptor of the device node

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Close the device node.

【Example Code】

See: hb_mm_mc_get_fd

5.12.4.55. hb_mm_mc_get_vui_config

【Function Declaration】

hb_s32 hb_mm_mc_get_vui_config(media_codec_context_t *context,
mc_video_vui_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: The context specifying the codec type

  • [OUT] mc_video_vui_params_t *params: VUI parameters

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Get VUI parameters.

【Additional Notes】

Currently, during video encoding, the default color range in the header information is set to full range mode. If limit range is desired, hb_mm_mc_set_vui_config must be explicitly called.

【Example Code】


    #include "hb_media_codec.h"
    #include "hb_media_error.h"
    typedef enum ENC_CONFIG_MESSAGE {
        ENC_CONFIG_NONE = (0 << 0),
        ENC_CONFIG_LONGTERM_REF = (1 << 0),
        ENC_CONFIG_INTRA_REFRESH = (1 << 1),
        ENC_CONFIG_RATE_CONTROL = (1 << 2),
        ENC_CONFIG_DEBLK_FILTER = (1 << 3),
        ENC_CONFIG_SAO = (1 << 4),
        ENC_CONFIG_ENTROPY = (1 << 5),
        ENC_CONFIG_VUI_TIMING = (1 << 6),
        ENC_CONFIG_SLICE = (1 << 7),
        ENC_CONFIG_REQUEST_IDR = (1 << 8),
        ENC_CONFIG_SKIP_PIC = (1 << 9),
        ENC_CONFIG_SMART_BG = (1 << 10),
        ENC_CONFIG_MONOCHROMA = (1 << 11),
        ENC_CONFIG_PRED_UNIT = (1 << 12),
        ENC_CONFIG_TRANSFORM = (1 << 13),
        ENC_CONFIG_ROI = (1 << 14),
        ENC_CONFIG_MODE_DECISION = (1 << 15),
        ENC_CONFIG_USER_DATA = (1 << 16),
        ENC_CONFIG_MJPEG = (1 << 17),
        ENC_CONFIG_JPEG = (1 << 18),
        ENC_CONFIG_CAMERA = (1 << 19),
        ENC_CONFIG_INSERT_USERDATA = (1 << 20),
        ENC_CONFIG_VUI = (1 << 21),
        ENC_CONFIG_3DNR = (1 << 22),
        ENC_CONFIG_REQUEST_IDR_HEADER = (1 << 23),
        ENC_CONFIG_ENABLE_IDR = (1 << 24),
        ENC_CONFIG_TOTAL = (1 << 25),
    } ENC_CONFIG_MESSAGE;
    typedef struct MediaCodecTestContext {
        media_codec_context_t *context;
        char *inputFileName;
        char *outputFileName;
        int32_t duration; // s
        ENC_CONFIG_MESSAGE message;
        mc_video_longterm_ref_mode_t ref_mode;
        mc_rate_control_params_t rc_params;
        mc_video_intra_refresh_params_t intra_refr;
        mc_video_deblk_filter_params_t deblk_filter;
        mc_h265_sao_params_t sao;
        mc_h264_entropy_params_t entropy;
        mc_video_vui_params_t vui;
        mc_video_vui_timing_params_t vui_timing;
        mc_video_slice_params_t slice;
        mc_video_3dnr_enc_params_t noise_reduction;
        mc_video_smart_bg_enc_params_t smart_bg;
        mc_video_pred_unit_params_t pred_unit;
        mc_video_transform_params_t transform;
        mc_video_roi_params_t roi;
        mc_video_mode_decision_params_t mode_decision;
    } MediaCodecTestContext;
    Uint64 osal_gettime(void)
    {
        struct timespec tp;
        clock_gettime(CLOCK_MONOTONIC, &tp);
        return ((Uint64)tp.tv_sec*1000 + tp.tv_nsec/1000000);
    }
    uint8_t uuid[] =
    "dc45e9bd-e6d948b7-962cd820-d923eeef+HorizonAI";
    static void set_message(MediaCodecTestContext *ctx) {
        int ret = 0;
        media_codec_context_t *context = ctx->context;
        if (ctx->message & ENC_CONFIG_VUI) {
            hb_mm_mc_get_vui_config(context, &ctx->vui);
            ret = hb_mm_mc_set_vui_config(context, &ctx->vui);
        }
    }
    static void do_sync_encoding(void *arg) {
        hb_s32 ret = 0;
        FILE *inFile;
        FILE *outFile;
        int noMoreInput = 0;
        int lastStream = 0;
        Uint64 lastTime = 0;
        Uint64 curTime = 0;
        int needFlush = 1;
        MediaCodecTestContext *ctx = (MediaCodecTestContext *)arg;
        media_codec_context_t *context = ctx->context;
        char *inputFileName = ctx->inputFileName;
        char *outputFileName = ctx->outputFileName;
        media_codec_state_t state = MEDIA_CODEC_STATE_NONE;
        inFile = fopen(inputFileName, "rb");
        if (!inFile) {
            goto ERR;
        }
        outFile = fopen(outputFileName, "wb");
        if (!outFile) {
            goto ERR;
        }
        //get current time
        lastTime = osal_gettime();
        ret = hb_mm_mc_initialize(context);
        if (ret) {
            goto ERR;
        }
        ret = hb_mm_mc_configure(context);
        if (ret) {
            goto ERR;
        }
        mc_av_codec_startup_params_t startup_params;
        startup_params.video_enc_startup_params.receive_frame_number = 0;
        ret = hb_mm_mc_start(context, &startup_params);
        if (ret) {
            goto ERR;
        }
        ret = hb_mm_mc_pause(context);
        if (ret) {
            goto ERR;
        }
        do {
        set_message(ctx);
        if (!noMoreInput) {
            media_codec_buffer_t inputBuffer;
            memset(&inputBuffer, 0x00, sizeof(media_codec_buffer_t));
            ret = hb_mm_mc_dequeue_input_buffer(context, &inputBuffer, 100);
            if (!ret) {
                curTime = osal_gettime();
                if ((curTime - lastTime)/1000 < (uint32_t)ctx->duration) {
                    ret = fread(inputBuffer.vframe_buf.vir_ptr[0], 1,
                    inputBuffer.vframe_buf.size, inFile);
                    if (ret <= 0) {
                        if(fseek(inFile, 0, SEEK_SET)) {
                            printf("Failed to rewind input file\n");
                        } else {
                            ret = fread(inputBuffer.vframe_buf.vir_ptr[0], 1,
                            inputBuffer.vframe_buf.size, inFile);
                            if (ret <= 0) {
                                printf("Failed to read input file\n");
                            }
                        }
                    }
                } else {
                    printf("Time up(%d)n",ctx->duration);
                    ret = 0;
                }
                if (!ret) {
                    printf("There is no more input data!n");
                    inputBuffer.vframe_buf.frame_end = TRUE;
                    noMoreInput = 1;
                }
                ret = hb_mm_mc_queue_input_buffer(context, &inputBuffer, 100);
                if (ret) {
                    printf("Queue input buffer fail.n");
                    break;
                }
            } else {
                if (ret != (int32_t)HB_MEDIA_ERR_WAIT_TIMEOUT) {
                    printf("Dequeue input buffer fail.n");
                    break;
                }
            }
        }
        if (!lastStream) {
            media_codec_buffer_t outputBuffer;
            media_codec_output_buffer_info_t info;
            memset(&outputBuffer, 0x00, sizeof(media_codec_buffer_t));
            memset(&info, 0x00, sizeof(media_codec_output_buffer_info_t));
            ret = hb_mm_mc_dequeue_output_buffer(context, &outputBuffer, &info,
            3000);
            if (!ret && outFile) {
                fwrite(outputBuffer.vstream_buf.vir_ptr,
                    outputBuffer.vstream_buf.size, 1, outFile);
                ret = hb_mm_mc_queue_output_buffer(context, &outputBuffer, 100);
                if (ret) {
                    printf("Queue output buffer fail.n");
                    break;
                }
                if (outputBuffer.vstream_buf.stream_end) {
                    printf("There is no more output data!n");
                    lastStream = 1;
                    break;
                }
            } else {
                if (ret != (int32_t)HB_MEDIA_ERR_WAIT_TIMEOUT) {
                    printf("Dequeue output buffer fail.n");
                    break;
                }
            }
        }
        if (needFlush) {
            ret = hb_mm_mc_flush(context);
            needFlush = 0;
            if (ret) {
                break;
            }
        }
    }while(TRUE);
    hb_mm_mc_stop(context);
    hb_mm_mc_release(context);
    context = NULL;
    ERR:
    hb_mm_mc_get_state(context, &state);
    if (context && state!=
        MEDIA_CODEC_STATE_UNINITIALIZED) {
        hb_mm_mc_stop(context);
        hb_mm_mc_release(context);
    }
    if (inFile)
        fclose(inFile);
    if (outFile)
        fclose(outFile);
    }
    int main(int argc, char *argv[])
    {
        hb_s32 ret = 0;
        char outputFileName[MAX_FILE_PATH] = "./tmp.yuv";
        char inputFileName[MAX_FILE_PATH] = "./output.stream";
        mc_video_codec_enc_params_t *params;
        media_codec_context_t context;
        memset(&context, 0x00, sizeof(media_codec_context_t));
        context.codec_id = MEDIA_CODEC_ID_H265;
        context.encoder = TRUE;
        params = &context.video_enc_params;
        params->width = 640;
        params->height = 480;
        params->pix_fmt = MC_PIXEL_FORMAT_YUV420P;
        params->frame_buf_count = 5;
        params->external_frame_buf = FALSE;
        params->bitstream_buf_count = 5;
        params->rc_params.mode = MC_AV_RC_MODE_H265CBR;
        ret = hb_mm_mc_get_rate_control_config(&context, &params->rc_params);
        if (ret) {
            return -1;
        }
        params->rc_params.h265_cbr_params.bit_rate = 5000;
        params->rc_params.h265_cbr_params.frame_rate = 30;
        params->rc_params.h265_cbr_params.intra_period = 30;
        params->gop_params.decoding_refresh_type = 2;
        params->gop_params.gop_preset_idx = 9;
        params->rot_degree = MC_CCW_0;
        params->mir_direction = MC_DIRECTION_NONE;
        params->frame_cropping_flag = FALSE;
        MediaCodecTestContext ctx;
        memset(&ctx, 0x00, sizeof(ctx));
        ctx.context = &context;
        ctx.inputFileName = inputFileName;
        ctx.outputFileName = outputFileName;
        mc_video_vui_params_t *vui = &ctx.vui;
        ret = hb_mm_mc_get_vui_config(context, vui);
        if (ret != 0) {
            return -1;
        }
        vui->h265_vui.video_signal_type_present_flag = 1;
        vui->h265_vui.video_format = 0;
        vui->h265_vui.video_full_range_flag = 0;
        ctx.message = ENC_CONFIG_VUI;
        do_sync_encoding(&ctx);
    }

5.12.4.56. hb_mm_mc_set_vui_config

【Function Declaration】

hb_s32 hb_mm_mc_set_vui_config(media_codec_context_t *context, const
mc_video_vui_params_t *params)

【Parameter Description】

  • [IN] media_codec_context_t *context: The context specifying the codec type

  • [IN] const mc_video_vui_params_t *params: VUI parameters

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Set VUI parameters. These are static parameters.

【Example Code】

See: hb_mm_mc_get_vui_config

5.12.4.57. hb_mm_mc_get_3dnr_enc_config

【Function Declaration】

hb_s32 hb_mm_mc_get_3dnr_enc_config(media_codec_context_t *context, mc_video_3dnr_enc_params_t *params);

【Parameter Description】

  • [IN] media_codec_context_t *context: The context specifying the codec type

  • [IN] mc_video_3dnr_enc_params_t *params: 3DNR parameters

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Get 3DNR parameters. These are dynamic parameters applicable to H.265.

【Example Code】

#include "hb_media_codec.h"
#include "hb_media_error.h"
typedef enum ENC_CONFIG_MESSAGE {
    ENC_CONFIG_NONE = (0 << 0),
    ENC_CONFIG_LONGTERM_REF = (1 << 0),
    ENC_CONFIG_INTRA_REFRESH = (1 << 1),
    ENC_CONFIG_RATE_CONTROL = (1 << 2),
    ENC_CONFIG_DEBLK_FILTER = (1 << 3),
    ENC_CONFIG_SAO = (1 << 4),
    ENC_CONFIG_ENTROPY = (1 << 5),
    ENC_CONFIG_VUI_TIMING = (1 << 6),
    ENC_CONFIG_SLICE = (1 << 7),
    ENC_CONFIG_REQUEST_IDR = (1 << 8),
    ENC_CONFIG_SKIP_PIC = (1 << 9),
    ENC_CONFIG_SMART_BG = (1 << 10),
    ENC_CONFIG_MONOCHROMA = (1 << 11),
    ENC_CONFIG_PRED_UNIT = (1 << 12),
    ENC_CONFIG_TRANSFORM = (1 << 13),
    ENC_CONFIG_ROI = (1 << 14),
    ENC_CONFIG_MODE_DECISION = (1 << 15),
    ENC_CONFIG_USER_DATA = (1 << 16),
    ENC_CONFIG_MJPEG = (1 << 17),
    ENC_CONFIG_JPEG = (1 << 18),
    ENC_CONFIG_CAMERA = (1 << 19),
    ENC_CONFIG_INSERT_USERDATA = (1 << 20),
    ENC_CONFIG_VUI = (1 << 21),
    ENC_CONFIG_3DNR = (1 << 22),
    ENC_CONFIG_REQUEST_IDR_HEADER = (1 << 23),
    ENC_CONFIG_ENABLE_IDR = (1 << 24),
    ENC_CONFIG_TOTAL = (1 << 25),
} ENC_CONFIG_MESSAGE;
typedef struct MediaCodecTestContext {
    media_codec_context_t *context;
    char *inputFileName;
    char *outputFileName;
    int32_t duration; // s
    ENC_CONFIG_MESSAGE message;
    mc_video_longterm_ref_mode_t ref_mode;
    mc_rate_control_params_t rc_params;
    mc_video_intra_refresh_params_t intra_refr;
    mc_video_deblk_filter_params_t deblk_filter;
    mc_h265_sao_params_t sao;
    mc_h264_entropy_params_t entropy;
    mc_video_vui_params_t vui;
    mc_video_vui_timing_params_t vui_timing;
    mc_video_slice_params_t slice;
    mc_video_3dnr_enc_params_t noise_reduction;
    mc_video_smart_bg_enc_params_t smart_bg;
    mc_video_pred_unit_params_t pred_unit;
    mc_video_transform_params_t transform;
    mc_video_roi_params_t roi;
    mc_video_mode_decision_params_t mode_decision;
} MediaCodecTestContext;
Uint64 osal_gettime(void)
{
    struct timespec tp;
    clock_gettime(CLOCK_MONOTONIC, &tp);
    return ((Uint64)tp.tv_sec*1000 + tp.tv_nsec/1000000);
}
uint8_t uuid[] =
"dc45e9bd-e6d948b7-962cd820-d923eeef+HorizonAI";
static void set_message(MediaCodecTestContext *ctx) {
    int ret = 0;
    media_codec_context_t *context = ctx->context;
    if (ctx->message & ENC_CONFIG_VUI) {
        hb_mm_mc_get_vui_config(context, &ctx->vui);
        ret = hb_mm_mc_set_vui_config(context, &ctx->vui);
    }
}
static void do_sync_encoding(void *arg) {
    hb_s32 ret = 0;
    FILE *inFile;
    FILE *outFile;
    int noMoreInput = 0;
    int lastStream = 0;
    Uint64 lastTime = 0;
    Uint64 curTime = 0;
    int needFlush = 1;
    MediaCodecTestContext *ctx = (MediaCodecTestContext *)arg;
    media_codec_context_t *context = ctx->context;
    char *inputFileName = ctx->inputFileName;
    char *outputFileName = ctx->outputFileName;
    media_codec_state_t state = MEDIA_CODEC_STATE_NONE;
    inFile = fopen(inputFileName, "rb");
    if (!inFile) {
        goto ERR;
    }
    outFile = fopen(outputFileName, "wb");
    if (!outFile) {
        goto ERR;
    }
    //get current time
    lastTime = osal_gettime();
    ret = hb_mm_mc_initialize(context);
    if (ret) {
        goto ERR;
    }
    ret = hb_mm_mc_configure(context);
    if (ret) {
        goto ERR;
    }
    mc_av_codec_startup_params_t startup_params;
    startup_params.video_enc_startup_params.receive_frame_number = 0;
    ret = hb_mm_mc_start(context, &startup_params);
    if (ret) {
        goto ERR;
    }
    ret = hb_mm_mc_pause(context);
    if (ret) {
        goto ERR;
    }
    do {
    set_message(ctx);
    if (!noMoreInput) {
        media_codec_buffer_t inputBuffer;
        memset(&inputBuffer, 0x00, sizeof(media_codec_buffer_t));
        ret = hb_mm_mc_dequeue_input_buffer(context, &inputBuffer, 100);
        if (!ret) {
            curTime = osal_gettime();
            if ((curTime - lastTime)/1000 < (uint32_t)ctx->duration) {
                ret = fread(inputBuffer.vframe_buf.vir_ptr[0], 1,
                inputBuffer.vframe_buf.size, inFile);
                if (ret <= 0) {
                    if(fseek(inFile, 0, SEEK_SET)) {
                        printf("Failed to rewind input file\n");
                    } else {
                        ret = fread(inputBuffer.vframe_buf.vir_ptr[0], 1,
                        inputBuffer.vframe_buf.size, inFile);
                        if (ret <= 0) {
                            printf("Failed to read input file\n");
                        }
                    }
                }
            } else {
                printf("Time up(%d)\n",ctx->duration);
                ret = 0;
            }
            if (!ret) {
                printf("There is no more input data!\n");
                inputBuffer.vframe_buf.frame_end = TRUE;
                noMoreInput = 1;
            }
            ret = hb_mm_mc_queue_input_buffer(context, &inputBuffer, 100);
            if (ret) {
                printf("Queue input buffer fail.\n");
                break;
            }
        } else {
            if (ret != (int32_t)HB_MEDIA_ERR_WAIT_TIMEOUT) {
                printf("Dequeue input buffer fail.\n");
                break;
            }
        }
    }
    if (!lastStream) {
        media_codec_buffer_t outputBuffer;
        media_codec_output_buffer_info_t info;
        memset(&outputBuffer, 0x00, sizeof(media_codec_buffer_t));
        memset(&info, 0x00, sizeof(media_codec_output_buffer_info_t));
        ret = hb_mm_mc_dequeue_output_buffer(context, &outputBuffer, &info,
        3000);
        if (!ret && outFile) {
            fwrite(outputBuffer.vstream_buf.vir_ptr,
                outputBuffer.vstream_buf.size, 1, outFile);
            ret = hb_mm_mc_queue_output_buffer(context, &outputBuffer, 100);
            if (ret) {
                printf("Queue output buffer fail.\n");
                break;
            }
            if (outputBuffer.vstream_buf.stream_end) {
                printf("There is no more output data!\n");
                lastStream = 1;
                break;
            }
        } else {
            if (ret != (int32_t)HB_MEDIA_ERR_WAIT_TIMEOUT) {
                printf("Dequeue output buffer fail.\n");
                break;
            }
        }
    }
    if (needFlush) {
        ret = hb_mm_mc_flush(context);
        needFlush = 0;
        if (ret) {
            break;
        }
    }
}while(TRUE);
hb_mm_mc_stop(context);
hb_mm_mc_release(context);
context = NULL;
ERR:
hb_mm_mc_get_state(context, &state);
if (context &&
    state != MEDIA_CODEC_STATE_UNINITIALIZED) {
    hb_mm_mc_stop(context);
    hb_mm_mc_release(context);
}
if (inFile)
    fclose(inFile);
if (outFile)
    fclose(outFile);
}
int main(int argc, char *argv[])
{
    hb_s32 ret = 0;
    char outputFileName[MAX_FILE_PATH] = "./tmp.yuv";
    char inputFileName[MAX_FILE_PATH] = "./output.stream";
    mc_video_codec_enc_params_t *params;
    media_codec_context_t context;
    memset(&context, 0x00, sizeof(media_codec_context_t));
    context.codec_id = MEDIA_CODEC_ID_H265;
    context.encoder = TRUE;
    params = &context.video_enc_params;
    params->width = 640;
    params->height = 480;
    params->pix_fmt = MC_PIXEL_FORMAT_YUV420P;
    params->frame_buf_count = 5;
    params->external_frame_buf = FALSE;
    params->bitstream_buf_count = 5;
    params->rc_params.mode = MC_AV_RC_MODE_H265CBR;
    ret = hb_mm_mc_get_rate_control_config(&context, &params->rc_params);
    if (ret) {
        return -1;
    }
    params->rc_params.h265_cbr_params.bit_rate = 5000;
    params->rc_params.h265_cbr_params.frame_rate = 30;
    params->rc_params.h265_cbr_params.intra_period = 30;
    params->gop_params.decoding_refresh_type = 2;
    params->gop_params.gop_preset_idx = 9;
    params->rot_degree = MC_CCW_0;
    params->mir_direction = MC_DIRECTION_NONE;
    params->frame_cropping_flag = FALSE;
    MediaCodecTestContext ctx;
    memset(&ctx, 0x00, sizeof(ctx));
    ctx.context = &context;
    ctx.inputFileName = inputFileName;
    ctx.outputFileName = outputFileName;
    mc_video_3dnr_enc_params_t *noise_rd = &ctx.noise_reduction;
    ret = hb_mm_mc_get_3dnr_enc_config(context, noise_rd);
    noise_rd->nr_y_enable = 0;
    noise_rd->nr_cb_enable = 0;
    noise_rd->nr_cr_enable = 0;
    noise_rd->nr_est_enable = 0;
    ctx.message = ENC_CONFIG_3DNR;
    do_sync_encoding(&ctx);
}

5.12.4.58. hb_mm_mc_set_3dnr_enc_config

【Function Declaration】

hb_s32 hb_mm_mc_set_3dnr_enc_config(media_codec_context_t *context, const mc_video_3dnr_enc_params_t *params);

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] const mc_video_3dnr_enc_params_t *params: 3DNR parameters

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Set 3DNR parameters. These are dynamic parameters applicable to H265.

【Example Code】

See: hb_mm_mc_get_3dnr_enc_config

5.12.4.59. hb_mm_mc_request_idr_header

【Function Declaration】

hb_s32 hb_mm_mc_request_idr_header(media_codec_context_t *context,
hb_u32 force_header)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] hb_u32 force_header:

    0: No forced header (VPS/SPS/PPS)

    1: Forced header before IDR frame

    2: Forced header before I frame for H264, or forced header before CRA and IDR frame for H265

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Request frame header (IDR frame header information), applicable to H264/H265.

【Example Code】

See: hb_mm_mc_get_longterm_ref_mode

5.12.4.60. hb_mm_mc_enable_idr_frame

【Function Declaration】

hb_s32 hb_mm_mc_enable_idr_frame(media_codec_context_t *context,
hb_bool enable)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] hb_bool enable: 0: Disable; 1: Enable

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Enable IDR frame, applicable to H264/H265.

【Example Code】

See: hb_mm_mc_get_longterm_ref_mode

5.12.4.61. hb_mm_mc_register_audio_encoder

【Function Declaration】

hb_s32 hb_mm_mc_register_audio_encoder(hb_s32 *handle,
mc_audio_encode_param_t *encoder)

【Parameter Description】

  • [IN] hb_s32 *handle: Encoder handle

  • [IN] mc_audio_encode_param_t *encoder: Audio encoder descriptor

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Register an audio encoder, applicable to Audio.

【Example Code】

#include "hb_media_codec.h"
#include "hb_media_error.h"
#include "include/aac.h"
int main(int argc, char *argv[])
{
    mc_audio_codec_enc_params_t *params;
    media_codec_context_t context;
    memset(&context, 0x00, sizeof(media_codec_context_t));
    context.codec_id = MEDIA_CODEC_ID_AAC;
    context.encoder = TRUE;
    params = &context.audio_enc_params;
    params->bit_rate = 128000;
    params->frame_buf_count = 5;
    params->packet_count = 5;
    params->sample_fmt = MC_AV_SAMPLE_FMT_S16;
    params->sample_rate = MC_AV_SAMPLE_RATE_16000;
    params->channel_layout = MC_AV_CHANNEL_LAYOUT_STEREO;
    params->channels = 2;
    mc_aac_enc_config_t config;
    config.profile = MC_AAC_PROFILE_LOW;
    config.type = MC_AAC_DATA_TYPE_ADTS;
    params->enc_config = &config;
    int ret;
    int handle;
    mc_audio_encode_param_t encoder;
    encoder.ff_type = MEDIA_CODEC_ID_AAC;
    snprintf(encoder.ff_codec_name, sizeof(encoder.ff_codec_name), "aacenc");
    encoder.ff_audio_open_encoder = ff_audio_aac_open_encoder;
    encoder.ff_audio_encode_frame = ff_audio_aac_encode_frm;
    encoder.ff_audio_close_encoder = ff_audio_aac_close_encoder;
    ret = hb_mm_mc_register_audio_encoder(&handle, &encoder);
    printf("handle = %d\n", handle);
    ASSERT_EQ(ret, 0);
    ret = hb_mm_mc_unregister_audio_encoder(handle);
    ASSERT_EQ(ret, 0);
}

5.12.4.62. hb_mm_mc_unregister_audio_encoder

【Function Declaration】

hb_s32 hb_mm_mc_unregister_audio_encoder(hb_s32 handle)

【Parameter Description】

  • [IN] hb_s32 handle: Encoder handle

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Unregister an audio encoder, applicable to Audio.

【Example Code】

See: hb_mm_mc_register_audio_encoder

5.12.4.63. hb_mm_mc_register_audio_decoder

【Function Declaration】

hb_s32 hb_mm_mc_register_audio_decoder(hb_s32 *handle,
mc_audio_decode_param_t *decoder)

【Parameter Description】

  • [IN] hb_s32 *handle: Decoder handle

  • [IN] mc_audio_decode_param_t *decoder: Audio decoder descriptor

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Register an audio decoder, applicable to Audio.

【Example Code】

    #include "hb_media_codec.h"
    #include "hb_media_error.h"
    #include "include/aac.h"
    int main(int argc, char *argv[])
    {
        mc_audio_codec_dec_params_t *params;
        media_codec_context_t context;
        memset(&context, 0x00, sizeof(media_codec_context_t));
        context.codec_id = MEDIA_CODEC_ID_AAC;
        context.encoder = FALSE;
        params = &context.audio_dec_params;
        params->feed_mode = MC_FEEDING_MODE_FRAME_SIZE;
        params->packet_buf_size = 1024;
        params->packet_count = 5;
        params->frame_cache_size = 5;
        params->frame_buf_count = 5;
        mc_aac_dec_config_t config;
        config.sample_rate = MC_AV_SAMPLE_RATE_8000;
        config.channels = 1;
        config.sample_fmt = MC_AV_SAMPLE_FMT_S16;
        params->dec_config = &config;
        mc_audio_decode_param_t decoder;
        decoder.ff_type = MEDIA_CODEC_ID_AAC;
        snprintf(decoder.ff_codec_name, sizeof(decoder.ff_codec_name), "aacdec");
        decoder.ff_audio_open_decoder = ff_audio_aac_open_decoder;
        decoder.ff_audio_decode_frame = ff_audio_aac_decode_frm;
        decoder.ff_audio_close_decoder = ff_audio_aac_close_decoder;
        ret = hb_mm_mc_register_audio_decoder(&handle, &decoder);
        ASSERT_EQ(ret, 0);
        ret = hb_mm_mc_unregister_audio_decoder(handle);
        ASSERT_EQ(ret, 0);
    }

5.12.4.64. hb_mm_mc_unregister_audio_decoder

【Function Declaration】

hb_s32 hb_mm_mc_unregister_audio_decoder(hb_s32 handle)

【Parameter Description】

  • [IN] hb_s32 *handle: Decoder handle;

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Unregister an audio decoder, applicable to Audio.

【Example Code】

Refer to: hb_mm_mc_register_audio_decoder

5.12.4.65. hb_mm_mc_get_explicit_header_config

【Function Declaration】

hb_s32 hb_mm_mc_get_explicit_header_config (media_codec_context_t
*context, hb_s32 *status)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [OUT] hb_s32 *status: Whether this feature is enabled (encoding header information and IDR frames into one frame)

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Get configuration indicating whether header information and IDR frames are encoded into one frame. 0: IDR and header are separate; 1: IDR and header are combined into one frame, applicable to H264/H265.

【Example Code】

Refer to: hb_mm_mc_get_longterm_ref_mode

5.12.4.66. hb_mm_mc_set_explicit_header_config

【Function Declaration】

hb_s32 hb_mm_mc_set_explicit_header_config (media_codec_context_t
*context, hb_s32 status)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] hb_s32 status: Enable/disable encoding header information and I-frames into one frame

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Enable/disable encoding header information and I-frames into one frame. This is a static parameter. 0: IDR and header are separate; 1: IDR and header are combined into one frame, applicable to H264/H265.

【Example Code】

Refer to: hb_mm_mc_get_longterm_ref_mode

5.12.4.67. hb_mm_mc_get_roi_avg_qp

【Function Declaration】

hb_s32 hb_mm_mc_get_roi_avg_qp(media_codec_context_t * context, hb_u32
* params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [OUT] hb_u32 *params: ROI average QP

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Get the average QP value for ROI, applicable to H264/H265.

【Example Code】

Refer to: hb_mm_mc_get_longterm_ref_mode

5.12.4.68. hb_mm_mc_set_roi_avg_qp

【Function Declaration】

hb_s32 hb_mm_mc_set_roi_avg_qp(media_codec_context_t * context, hb_u32
params)

【Parameter Description】

  • [IN] media_codec_context_t *context: Context specifying the codec type

  • [IN] hb_u32 params: ROI average QP value [0 - 51]

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Set the average QP value for ROI encoding. This is a dynamic parameter, representing the average of all values in the configured QPMap. This setting takes effect only when the rate control mode is CBR or AVBR, applicable to H264/H265.

【Example Code】

Refer to: hb_mm_mc_get_longterm_ref_mode

5.12.5. MediaMuxer Interface Description

The MediaMuxer module is primarily used to encapsulate encoded video and audio streams into an MP4 container. This module introduces a series of interfaces to support adding audio/video tracks and filling data streams. Users can add audio or video tracks to MediaMuxer and then feed audio or video streams, allowing MediaMuxer to multiplex the raw streams into an MP4 file. The table below lists the formats supported by MediaMuxer.

Module Audio Stream Format Track Count Video Stream Format Track Count Output Format
MediaMuxer FLAC/AAC 1 H264/H265 1 MP4

5.12.5.1. hb_mm_mx_get_default_context

【Function Declaration】

hb_s32 hb_mm_mx_get_default_context(media_muxer_context_t *context)

【Parameter Description】

  • [OUT] media_codec_context_t *context: Default muxer context

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Obtain default context parameter values.

【Example Code】

    #ifdef __cplusplus
    extern "C" {
    #endif				/* __cplusplus */
    #include <libavformat/avformat.h>
    #include <libavutil/timestamp.h>
    #ifdef __cplusplus
    }
    #endif				/* __cplusplus */
    #include "hb_media_codec.h"
    #include "hb_media_error.h"
    #include "hb_media_muxer.h"

    int main(int argc, char *argv[])
    {
        int ret = 0;
        char inputAudioFileName[256] = "./tmp.h265";
        char inputVideoFileName[256] = "./input.aac";
        char outputFileName[256] = "./output.mp4";
        int doAudioExit = 0, doVideoExit = 0;
        media_muxer_context_t muxerCtx;
        memset(&muxerCtx, 0x00, sizeof(media_muxer_context_t));
        ret = hb_mm_mx_get_default_context(&muxerCtx);
        if (ret) {
            return -1;
        }
        muxerCtx.output_file_name = outputFileName;
        media_muxer_state_t state = MEDIA_MUXER_STATE_NONE;
        hb_mm_mx_get_state(&muxerCtx, &state);
        mx_stream_params_t videoStream;
        memset(&videoStream, 0x00, sizeof(mx_stream_params_t));
        videoStream.codec_id = MEDIA_CODEC_ID_H265;
        videoStream.video_params.bit_rate = 5000;
        videoStream.video_params.frame_rate = 25;
        videoStream.video_params.pix_fmt = MC_PIXEL_FORMAT_YUV420P;
        videoStream.video_params.width = 640;
        videoStream.video_params.height = 480;
        videoStream.video_params.intra_period = 30;
        videoStream.numerator = 1;
        videoStream.denominator = videoStream.video_params.frame_rate;

        mx_stream_params_t audioStream;
        memset(&audioStream, 0x00, sizeof(mx_stream_params_t));
        audioStream.codec_id = MEDIA_CODEC_ID_AAC;
        audioStream.audio_params.bit_rate = 135000;
        audioStream.audio_params.sample_fmt = MC_AV_SAMPLE_FMT_FLTP;
        audioStream.audio_params.sample_rate = MC_AV_SAMPLE_RATE_48000;
        audioStream.audio_params.channel_layout =MC_AV_CHANNEL_LAYOUT_MONO;
        audioStream.audio_params.channels = 1;

        mx_stream_t mxStream;
        memset(&mxStream, 0x00, sizeof(mx_stream_t));

        AVFormatContext *iVFmtCtx = NULL;
        ret = avformat_open_input(&iVFmtCtx, inputVideoFileName, 0, 0);
        if (ret < 0) {
            goto ERR;
        }
        ret = avformat_find_stream_info(iVFmtCtx, 0);
        if (ret < 0) {
            goto ERR;
        }

        AVFormatContext *iAFmtCtx = NULL;
        ret = avformat_open_input(&iAFmtCtx, inputAudioFileName, 0, 0);
        if (ret < 0) {
            goto ERR;
        }
        ret = avformat_find_stream_info(iAFmtCtx, 0);
        if (ret < 0) {
            goto ERR;
        }
        if (iAFmtCtx->nb_streams != (unsigned int)1) {
            goto ERR;
        }
        audioStream.numerator = iAFmtCtx->streams[0]->time_base.num;
        audioStream.denominator = iAFmtCtx->streams[0]->time_base.den;

        ret hb_mm_mx_initialize(&muxerCtx);
        if (ret < 0) {
            goto ERR;
        }
        ret = hb_mm_mx_add_stream(&muxerCtx, &videoStream);
        if (ret < 0) {
            goto ERR;
        }
        ret = hb_mm_mx_add_stream(&muxerCtx, &audioStream);
        if (ret < 0) {
            goto ERR;
        }
        ret = hb_mm_mx_start(&muxerCtx);
        if (ret < 0) {
            goto ERR;
        }

        AVPacket pkt = {0};
        int64_t v_next_pts = 0, a_next_pts = 0;
        while (!doAudioExit || !doVideoExit) {
            if ((!doVideoExit) && (doAudioExit ||
                hb_mm_mx_compare_ts(&muxerCtx, v_next_pts,
                a_next_pts, COMPARE_PTS_VIDEO_AUDIO))) {
                if (av_read_frame(iVFmtCtx, &pkt) >= 0) {
                    static int count = 0;
                    mxStream.is_audio = 0;
                    mxStream.vir_ptr = (unsigned char*)pkt.data;
                    mxStream.phy_ptr = 0;
                    mxStream.size = pkt.size;
                    mxStream.pts = count++;//outputBuffer.vstream_buf.pts;
                    mxStream.is_key_frame = 0;
                    ret = hb_mm_mx_write_stream(&muxerCtx, &mxStream);
                    if (ret < 0) {
                        goto ERR;
                    }
                    v_next_pts += videoStream.denominator/videoStream.numerator/videoStream.video_params.frame_rate;
                    av_packet_unref(&pkt);
                } else {
                    doVideoExit = TRUE;
                }
            } else {
                if (av_read_frame(iAFmtCtx, &pkt) >= 0) {
                    mxStream.is_audio = 1;
                    mxStream.vir_ptr = (unsigned char*)pkt.data;
                    mxStream.phy_ptr = 0;
                    mxStream.size = pkt.size;
                    mxStream.pts = pkt.pts;
                    mxStream.is_key_frame = 0;
                    ret = hb_mm_mx_write_stream(&muxerCtx, &mxStream);
                    if (ret < 0) {
                        goto ERR;
                    }
                    a_next_pts += audioStream.denominator/audioStream.numerator/audioStream.audio_params.sample_rate;
                    av_packet_unref(&pkt);
                } else {
                    doAudioExit = TRUE;
                }
            }
        }

    ERR:
        if (muxerCtx)
            hb_mm_mx_stop(&muxerCtx);
        if (iVFmtCtx)
            avformat_close_input(&iVFmtCtx);
        if (iAFmtCtx)
        avformat_close_input(&iAFmtCtx);
        return -1;
    }

5.12.5.2. hb_mm_mx_initialize

【Function Declaration】

hb_s32 hb_mm_mx_initialize(media_muxer_context_t *context)

【Parameter Description】

  • [IN] media_muxer_context_t *context: Muxer context

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INSUFFICIENT_RES: Insufficient internal memory resources

  • HB_MEDIA_ERR_NO_FREE_INSTANCE: Unable to allocate more instances (maximum 32)

  • HB_MEDIA_ERR_FILE_OPERATION_FAILURE: Unable to open or create file

【Function Description】

Initialize internal state of MediaMuxer. After successful call, MediaMuxer enters MEDIA_MUXER_STATE_INITIALIZED state.

【Example Code】

Refer to: hb_mm_mx_get_default_context

5.12.5.3. hb_mm_mx_add_stream

【Function Declaration】

hb_s32 hb_mm_mx_add_stream(media_muxer_context_t *context, const
mx_stream_params_t *params)

【Parameter Description】

  • [IN] media_muxer_context_t *context: Muxer context

  • [IN] const mx_stream_params_t *params: Track information

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INSUFFICIENT_RES: Insufficient internal memory resources

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

【Function Description】

Add audio/video tracks.

【Example Code】

Refer to: hb_mm_mx_get_default_context

5.12.5.4. hb_mm_mx_start

【Function Declaration】

hb_s32 hb_mm_mx_start(media_muxer_context_t *context)

【Parameter Description】

  • [IN] media_muxer_context_t *context: Muxer context

【Return Value】

  • 0: Operation succeeded

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters- HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INSUFFICIENT_RES: Insufficient internal memory resources

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

【Function Description】

Start the internal process of MediaMuxer. After a successful call, the state transitions to MEDIA_MUXER_STATE_STARTED.

【Example Code】

See: hb_mm_mx_get_default_context

5.12.5.5. hb_mm_mx_stop

【Function Declaration】

hb_s32 hb_mm_mx_stop(media_muxer_context_t *context)

【Parameter Description】

  • [IN] media_muxer_context_t *context: muxer context

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

【Function Description】

Stop the internal process of MediaMuxer. After a successful call, the state transitions to MEDIA_MUXER_STATE_UNINITIALIZED.

【Example Code】

See: hb_mm_mx_get_default_context

5.12.5.6. hb_mm_mx_write_stream

【Function Declaration】

hb_s32 hb_mm_mx_write_stream(media_muxer_context_t *context, const
mx_stream_t *buffer)

【Parameter Description】

  • [IN] media_muxer_context_t *context: muxer context

  • [IN] const mx_stream_t *buffer: Audio or video data stream

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_OPERATION_NOT_ALLOWED: Operation not allowed

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

  • HB_MEDIA_ERR_INVALID_BUFFER: Invalid buffer

  • HB_MEDIA_ERR_FILE_OPERATION_FAILURE: File operation failed

【Function Description】

Write audio or video data.

【Example Code】

See: hb_mm_mx_get_default_context

5.12.5.7. hb_mm_mx_get_state

【Function Declaration】

hb_s32 hb_mm_mx_get_state (media_muxer_context_t *context,
media_muxer_state_t *state)

【Parameter Description】

  • [IN] media_muxer_context_t *context: muxer context

  • [OUT] media_muxer_state_t *state: Current state of the muxer

Note: The original Chinese comment mistakenly used const mx_stream_t *buffer as the second parameter, but based on the function signature and purpose, it should be media_muxer_state_t *state.

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_UNKNOWN: Unknown error

  • HB_MEDIA_ERR_INVALID_INSTANCE: Invalid instance

【Function Description】

Get the current state of MediaMuxer.

【Example Code】

See: hb_mm_mx_get_default_context

5.12.5.8. hb_mm_mx_probe_stream

【Function Declaration】

hb_s32 hb_mm_mx_probe_stream(hb_string input_file_name)

【Parameter Description】

  • [IN] hb_string input_file_name: Input file name

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Check whether an MP4 file is corrupted.

【Example Code】


    #ifdef __cplusplus
    extern "C" {
    #endif				/* __cplusplus */
    #include <libavformat/avformat.h>
    #include <libavutil/timestamp.h>
    #ifdef __cplusplus
    }
    #endif				/* __cplusplus */
    #include "hb_media_codec.h"
    #include "hb_media_error.h"
    #include "hb_media_muxer.h"
    int main(int argc, char *argv[])
    {
        int ret = 0;
        char inputFileName[256] = "./damaged.mp4";
        char outputFileName[256] = "./repaired.mp4";
        ASSERT_EQ(hb_mm_mx_probe_stream(inputFileName), (int32_t)0);
    }

5.12.5.9. hb_mm_mx_repair_stream

【Function Declaration】

hb_s32 hb_mm_mx_repair_stream(hb_string input_file_name, hb_string
output_file_name);

【Parameter Description】

  • [IN] hb_string input_file_name: MP4 file name to be checked

  • [IN] hb_string output_file_name: Repaired MP4 file name

【Return Value】

  • 0: Operation successful

  • HB_MEDIA_ERR_INVALID_PARAMS: Invalid parameters

【Function Description】

Repair a corrupted MP4 file and generate a valid MP4 file.

【Example Code】


    #ifdef __cplusplus
    extern "C" {
    #endif				/* __cplusplus */
    #include <libavformat/avformat.h>
    #include <libavutil/timestamp.h>
    #ifdef __cplusplus
    }
    #endif				/* __cplusplus */
    #include "hb_media_codec.h"
    #include "hb_media_error.h"
    #include "hb_media_muxer.h"
    int main(int argc, char *argv[])
    {
        int ret = 0;
        char inputFileName[256] = "./damaged.mp4";
        char outputFileName[256] = "./repaired.mp4";
        ASSERT_EQ(hb_mm_mx_repair_stream(inputFileName, outputFileName), (int32_t)0);
    }

5.12.6. Data Structures

5.12.6.1. media_codec_state_t

    typedef enum _media_codec_state {
        MEDIA_CODEC_STATE_NONE = -1,
        MEDIA_CODEC_STATE_UNINITIALIZED,
        MEDIA_CODEC_STATE_INITIALIZED,
        MEDIA_CODEC_STATE_CONFIGURED,
        MEDIA_CODEC_STATE_STARTED,
        MEDIA_CODEC_STATE_PAUSED,
        MEDIA_CODEC_STATE_FLUSHING,
        MEDIA_CODEC_STATE_ERROR,
        MEDIA_CODEC_STATE_TOTAL,
    } media_codec_state_t;

5.12.6.2. media_codec_id_t

    typedef enum _media_codec_id {
        MEDIA_CODEC_ID_NONE = -1,
        /* Video Codecs */
        MEDIA_CODEC_ID_H264,
        MEDIA_CODEC_ID_H265,
        MEDIA_CODEC_ID_MJPEG,
        MEDIA_CODEC_ID_JPEG,
        /* Audio Codecs */
        MEDIA_CODEC_ID_FLAC,
        MEDIA_CODEC_ID_PCM_MULAW,
        MEDIA_CODEC_ID_PCM_ALAW,
        MEDIA_CODEC_ID_ADPCM_G726,
        MEDIA_CODEC_ID_ADPCM,
        MEDIA_CODEC_ID_AAC,
        MEDIA_CODEC_ID_MP3,
        MEDIA_CODEC_ID_MP2,
        MEDIA_CODEC_ID_TAK,
        MEDIA_CODEC_ID_AC3,
        MEDIA_CODEC_ID_WMA,
        MEDIA_CODEC_ID_AMR,
        MEDIA_CODEC_ID_APE,
        MEDIA_CODEC_ID_G729,
        MEDIA_CODEC_ID_G723,
        MEDIA_CODEC_ID_G722,
        MEDIA_CODEC_ID_IAC,
        MEDIA_CODEC_ID_RALF,
        MEDIA_CODEC_ID_QDMC,
        MEDIA_CODEC_ID_DTS,
        MEDIA_CODEC_ID_GSM,
        MEDIA_CODEC_ID_TTA,
        MEDIA_CODEC_ID_QCELP,
        MEDIA_CODEC_ID_MLP,
        MEDIA_CODEC_ID_ATRAC1,
        MEDIA_CODEC_ID_IMC,
        MEDIA_CODEC_ID_EAC,
        MEDIA_CODEC_ID_MP1,
        MEDIA_CODEC_ID_SIPR,
        MEDIA_CODEC_ID_OPUS,
        MEDIA_CODEC_ID_CELT,
        MEDIA_CODEC_ID_MOV_TEXT,
        MEDIA_CODEC_ID_TOTAL,
    } media_codec_id_t;

5.12.6.3. mc_video_rate_control_mode_t

    typedef enum _mc_video_rate_control_mode {
        MC_AV_RC_MODE_NONE = -1,
        MC_AV_RC_MODE_H264CBR,
        MC_AV_RC_MODE_H264VBR,
        MC_AV_RC_MODE_H264AVBR,
        MC_AV_RC_MODE_H264FIXQP,
        MC_AV_RC_MODE_H264QPMAP,
        MC_AV_RC_MODE_H265CBR,
        MC_AV_RC_MODE_H265VBR,
        MC_AV_RC_MODE_H265AVBR,
        MC_AV_RC_MODE_H265FIXQP,
        MC_AV_RC_MODE_H265QPMAP,
        MC_AV_RC_MODE_MJPEGFIXQP,
        MC_AV_RC_MODE_TOTAL,
    } mc_video_rate_control_mode_t;

5.12.6.4. mc_h265_cbr_params_t

    typedef struct _mc_h265_cbr_params {
        hb_u32 intra_period;
        hb_u32 intra_qp;
        hb_u32 bit_rate;
        hb_u32 frame_rate;
        hb_u32 initial_rc_qp;
        hb_s32 vbv_buffer_size;
        hb_u32 ctu_level_rc_enable;
        hb_u32 min_qp_I;
        hb_u32 max_qp_I;
        hb_u32 min_qp_P;
        hb_u32 max_qp_P;
        hb_u32 min_qp_B;
        hb_u32 max_qp_B;
        hb_u32 hvs_qp_enable;
        hb_s32 hvs_qp_scale;
        hb_u32 max_delta_qp;
        hb_bool qp_map_enable;
    } mc_h265_cbr_params_t;

5.12.6.5. mc_h265_vbr_params_t

    typedef struct _mc_h265_vbr_params {
        hb_u32 intra_period;
        hb_u32 intra_qp;
        hb_u32 frame_rate;
        hb_bool qp_map_enable;
    } mc_h265_vbr_params_t;

5.12.6.6. mc_h265_avbr_params_t

    typedef struct _mc_h265_avbr_params {
        hb_u32 intra_period;
        hb_u32 intra_qp;
        hb_u32 bit_rate;
        hb_u32 frame_rate;
        hb_u32 initial_rc_qp;
        hb_s32 vbv_buffer_size;
        hb_u32 ctu_level_rc_enalbe;
        hb_u32 min_qp_I;
        hb_u32 max_qp_I;
        hb_u32 min_qp_P;
        hb_u32 max_qp_P;
        hb_u32 min_qp_B;
        hb_u32 max_qp_B;
        hb_u32 hvs_qp_enable;
        hb_s32 hvs_qp_scale;
        hb_u32 max_delta_qp;
        hb_bool qp_map_enable;
    } mc_h265_avbr_params_t;

5.12.6.7. mc_h265_fix_qp_params_t

    typedef struct _mc_h265_fix_qp_params {
        hb_u32 intra_period;
        hb_u32 frame_rate;
        hb_u32 force_qp_I;
        hb_u32 force_qp_P;
        hb_u32 force_qp_B;
    } mc_h265_fix_qp_params_t;

5.12.6.8. mc_h265_qp_map_params_t

    typedef struct _mc_h265_qp_map_params {
        hb_u32 intra_period;
        hb_u32 frame_rate;
        hb_byte qp_map_array;
        hb_u32 qp_map_array_count;
    } mc_h265_qp_map_params_t;

5.12.6.9. mc_video_longterm_ref_mode_t

/**
* Define the parameters of longterm reference mode.
**/
typedef struct _mc_video_longterm_ref_mode {
/**
 * It enables long-term reference mode.
 * The valid numbers are as follows.
 *     0 : disable
 *     1 : enable
 *
 * - Note: It's unchangable parameters in the same sequence.
 * - Encoding: Support.
 * - Decoding: Unsupport.
 * - Default: 0
 */
	hb_u32 use_longterm;

/**
 * It specifies the period of long-term reference picture.
 * Values[0,2 ^ 31-1]
 *
 * - Note: It's changable parameters in the same sequence.
 * - Encoding: Support.
 * - Decoding: Unsupport.
 * - Default: 0
 */
	hb_u32 longterm_pic_period;

/**
 * It specifies the period of using long-term reference picture.
 * Values[0,2 ^ 31-1]
 *
 * - Note: It's changable parameters in the same sequence.
 * - Encoding: Support.
 * - Decoding: Unsupport.
 * - Default: 0
 */
	hb_u32 longterm_pic_using_period;
} mc_video_longterm_ref_mode_t;

5.12.6.10. mc_video_intra_refresh_params_t

/**
* Define the parameters of H264/H265 intra refresh.
**/
typedef struct _mc_video_intra_refresh_params {
/**
 * An intra refresh mode, only applied in H264/H265.
 * IntraRefresh can be enabled for error robustness. Host application
 * can specify the number of intra MBs or CTBs in a non-intra picture and
 * IntraRefresh mode.
 * The valid IntraRefresh modes are as follows.
 *     0: no intra refresh
 *     1: row
 *     2: column
 *     3: step size in MB or CTU
 *     4: adaptive intra refresh (only for H265 of XJ3/J6)
 *
 * - Note: It's unchangable parameter in the same sequence.
 * - Encoding: Support.
 * - Decoding: Unsupport.
 * - Default: 0.
 */
	hb_s32 intra_refresh_mode;

/**
 * It specifies an intra MB or CTU refresh interval. Depending on
 * intra_refresh_mode, it can be one of the followings.
 *     intra_refresh_mode = 1: The number of consecutive MB/CTU rows.
 *         Values(0, Max Mb(16x16) or CTU(64x64) number in row]
 *     intra_refresh_mode = 2: The number of consecutive MB/CTU columns.
 *         Values(0, Max Mb(16x16) or CTU(64x64) number in column]
 *     intra_refresh_mode = 3: A step size in MB/CTU.
 *         Values(0, Max Mb(16x16) or CTU(64x64) number in picture]
 *     intra_refresh_mode = 4: The number of intra MB/CTU to be encoded
 *                             in a picture.
 *        Values(0, Max Mb(16x16) or CTU(64x64) number in picture]
 *
 * Values[0,2 ^ 31-1]
 *
 * - Note:It's unchangable parameter in the same sequence.
 *        The intra_refresh_mode 4 can't work with lossless and ROI mode.
 * - Encoding: Support.
 * - Decoding: Unsupport.
 * - Default: 0.
 */
	hb_u32 intra_refresh_arg;
} mc_video_intra_refresh_params_t;

5.12.6.11. mc_mjpeg_fix_qp_params_t

    typedef struct _mc_mjpeg_fix_qp_params {
        hb_u32 frame_rate;
        hb_u32 quality_factor;
    } mc_mjpeg_fix_qp_params_t;

5.12.6.12. mc_video_custom_gop_pic_params_t

    typedef struct _mc_video_custom_gop_pic_params {
        hb_u32 pic_type;
        hb_s32 poc_offset;
        hb_u32 pic_qp;
        hb_s32 num_ref_picL0;
        hb_s32 ref_pocL0;
        hb_s32 ref_pocL1;
        hb_u32 temporal_id;
    } mc_video_custom_gop_pic_params_t;

5.12.6.13. mc_inter_status_t

    typedef struct _mc_inter_status {
        hb_u32 cur_input_buf_cnt;
        hb_u64 cur_input_buf_size;
        hb_u32 cur_output_buf_cnt;
        hb_u64 cur_output_buf_size;
        hb_u32 left_recv_frame;
        hb_u32 left_enc_frame;
        hb_u32 total_input_buf_cnt;
        hb_u32 total_output_buf_cnt;
        hb_s32 pipeline;
        hb_s32 channel_port_id;
    } mc_inter_status_t;

5.12.6.14. media_codec_context_t

    typedef struct _media_codec_context {
        media_codec_id_t codec_id;
        hb_bool encoder;
        hb_s32 instance_index;
        union {
            mc_video_codec_enc_params_t video_enc_params;
            mc_video_codec_dec_params_t video_dec_params;
            mc_audio_codec_enc_params_t audio_enc_params;
            mc_audio_codec_dec_params_t audio_dec_params;
        };
        hb_ptr vpf_context;
        mc_video_cmd_prio_t priority;
    } media_codec_context_t;

5.12.6.15. mc_video_codec_enc_params_t

    typedef struct _mc_video_codec_enc_params {
        hb_s32 width, height;
        mc_pixel_format_t pix_fmt;
        hb_u32 frame_buf_count;
        hb_bool external_frame_buf;
        hb_u32 bitstream_buf_count;
        hb_u32 bitstream_buf_size;
        mc_rate_control_params_t rc_params;
        mc_video_gop_params_t gop_params;
        mc_rotate_degree_t rot_degree;
        mc_mirror_direction_t mir_direction;
        hb_u32 frame_cropping_flag;
        mc_av_codec_rect_t crop_rect;
        hb_bool enable_user_pts;
        union {
            mc_h264_enc_config_t h264_enc_config;
            mc_h265_enc_config_t h265_enc_config;
            mc_mjpeg_enc_config_t mjpeg_enc_config;
            mc_jpeg_enc_config_t jpeg_enc_config;
        };
    } mc_video_codec_enc_params_t;

5.12.6.16. mc_video_codec_dec_params_t

    typedef struct _mc_video_codec_dec_params {
        mc_av_stream_feeding_mode_t feed_mode;
        mc_pixel_format_t pix_fmt;
        hb_u32 bitstream_buf_size;
        hb_u32 bitstream_buf_count;
        hb_bool external_bitstream_buf;
        hb_u32 frame_buf_count;
        union {
            mc_h264_dec_config_t h264_dec_config;
            mc_h265_dec_config_t h265_dec_config;
            mc_mjpeg_dec_config_t mjpeg_dec_config;
            mc_jpeg_dec_config_t jpeg_dec_config;
        };
    } mc_video_codec_dec_params_t;

5.12.6.17. mc_audio_codec_enc_params_t

    typedef struct _mc_audio_codec_enc_params {
        hb_u32 bit_rate;
        hb_s32 frame_size;
        hb_s32 frame_buf_count;
        hb_s32 packet_count;
        mc_audio_sample_format_t sample_fmt;
        mc_audio_sample_rate_t sample_rate;
        mc_audio_channel_layout_t channel_layout;
        hb_s32 channels;
        hb_ptr enc_config;
    } mc_audio_codec_enc_params_t;

5.12.6.18. mc_audio_codec_dec_params_t

    typedef struct _mc_audio_codec_dec_params {
        mc_av_stream_feeding_mode_t feed_mode;
        hb_s32 packet_buf_size;
        hb_s32 packet_count;
        hb_s32 frame_cache_size;
        hb_s32 internal_frame_size;
        hb_s32 frame_buf_count;
        hb_ptr dec_config;
    } mc_audio_codec_dec_params_t;

5.12.6.19. media_muxer_state_t

    typedef enum _media_muxer_state {
        MEDIA_MUXER_STATE_NONE = -1,
        MEDIA_MUXER_STATE_UNINITIALIZED,
        MEDIA_MUXER_STATE_INITIALIZED,
        MEDIA_MUXER_STATE_STARTED,
        MEDIA_MUXER_STATE_ERROR,
        MEDIA_MUXER_STATE_TOTAL
    } media_muxer_state_t;

5.12.6.20. mx_audio_stream_input_params_t

    typedef struct _mx_audio_stream_input_params {
        hb_s64 bit_rate;
        mc_audio_sample_format_t sample_fmt;
        mc_audio_sample_rate_t sample_rate;
        mc_audio_channel_layout_t channel_layout;
        hb_s32 channels;
    } mx_audio_stream_input_params_t;

5.12.6.21. mx_video_stream_input_params_t

    typedef struct _mx_video_stream_input_params {
        hb_u32 bit_rate;
        hb_u32 frame_rate;
        mc_pixel_format_t pix_fmt;
        hb_s32 width, height;
        hb_s32 intra_period;
    } mx_video_stream_input_params_t;

5.12.6.22. mx_stream_params_t

    typedef struct _mx_stream_params {
        media_codec_id_t codec_id;
        hb_s32 numerator;
        hb_s32 denominator;
        union {
            mx_audio_stream_input_params_t audio_params;
            mx_video_stream_input_params_t video_params;
            mx_subtitle_stream_input_params_t subtitle_params;
        };
    } mx_stream_params_t;

5.12.6.23. mx_stream_t

    typedef struct _mx_stream {
        hb_s32 is_audio;
        hb_u8 *vir_ptr;
        hb_u64 phy_ptr;
        hb_u32 size;
        hb_u64 pts;
        hb_bool is_key_frame;
    } mx_stream_t;

5.12.6.24. media_muxer_context_t

    typedef struct _media_muxer_context {
        hb_string output_file_name;
        mx_output_format_t output_format;
        hb_s32 instance_index;
    } media_muxer_context_t;

5.12.7. Return Value Description

Error Code Macro Definition Description
0xF0000001 HB_MEDIA_ERR_UNKNOWN Unknown error
0xF0000002 HB_MEDIA_ERR_CODEC_NOT_FOUND Corresponding codec not found
0xF0000003 HB_MEDIA_ERR_CODEC_OPEN_FAIL Failed to open codec device
0xF0000004 HB_MEDIA_ERR_CODEC_RESPONSE_TIMEOUT Codec response timeout
0xF0000005 HB_MEDIA_ERR_CODEC_INIT_FAIL Codec initialization failed
0xF0000006 HB_MEDIA_ERR_OPERATION_NOT_ALLOWED Operation not allowed
0xF0000007 HB_MEDIA_ERR_INSUFFICIENT_RES Insufficient internal memory resources
0xF0000008 HB_MEDIA_ERR_NO_FREE_INSTANCE No free instance available (VPU up to 32, JPU up to 64, Audio up to 32)
0xF0000009 HB_MEDIA_ERR_INVALID_PARAMS Invalid parameters
0xF000000A HB_MEDIA_ERR_INVALID_INSTANCE Invalid instance
0xF000000B HB_MEDIA_ERR_INVALID_BUFFER Invalid buffer
0xF000000C HB_MEDIA_ERR_INVALID_COMMAND Invalid command
0xF000000D HB_MEDIA_ERR_WAIT_TIMEOUT Wait timeout
0xF000000E HB_MEDIA_ERR_FILE_OPERATION_FAILURE File operation failed
0xF000000F HB_MEDIA_ERR_PARAMS_SET_FAILURE Parameter setting failed
0xF0000010 HB_MEDIA_ERR_PARAMS_GET_FAILURE Parameter retrieval failed
0xF0000011 HB_MEDIA_ERR_CODING_FAILED Encoding/decoding failed
0xF0000012 HB_MEDIA_ERR_OUTPUT_BUF_FULL Output buffer full
0xF0000013 HB_MEDIA_ERR_UNSUPPORTED_FEATURE Unsupported feature
0xF0000014 HB_MEDIA_ERR_INVALID_PRIORITY Invalid priority