/*
 * Copyright (C) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @addtogroup VideoEncoder
 * @{
 *
 * @brief The VideoEncoder module provides interfaces for video encoding.
 *
 * @syscap SystemCapability.Multimedia.VideoEncoder
 * @since 9
 */

/**
 * @file native_avcodec_videoencoder.h
 *
 * @brief Declare the interface used for video encoding.
 *
 * @kit AVCodecKit
 * @library libnative_media_venc.so
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @since 9
 */

#ifndef NATIVE_AVCODEC_VIDEOENCODER_H
#define NATIVE_AVCODEC_VIDEOENCODER_H

#include <stdint.h>
#include <stdio.h>
#include "native_avcodec_base.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Configure frame parameters. This interface can be used to set the encode parameters
 * of the frame corresponding to the index, take effect only in Surface mode.
 * It is need to call {@link OH_VideoEncoder_RegisterParametercallbacks} interface to register before use.
 * In Buffer mode, OH_AVBuffer can directly carry the encoding parameters of frames.
 * Currently, frame level QPMin/QPMax parameters are supported, and specify LTR to set the reference frame.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec OH_AVCodec instance
 * @param index The index corresponding to the encode frame
 * @param parameter Encode parameter
 * @param userData The data that the user rely on to execute the callback
 * @since 12
 */
typedef void (*OH_VideoEncoder_OnNeedInputParameter)(OH_AVCodec *codec, uint32_t index, OH_AVFormat *parameter,
                                                     void *userData);

/**
 * @brief Creates a video encoder instance from the mime type, it is recommended to use.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param mime mime type description string, refer to {@link AVCODEC_MIME_TYPE}
 * @return Returns a Pointer to an OH_AVCodec instance.
 * Return NULL if memory ran out or the mime type is not supported.
 * @since 9
 * @version 1.0
 */
OH_AVCodec *OH_VideoEncoder_CreateByMime(const char *mime);

/**
 * @brief Create a video encoder instance through the video encoder name.
 * The premise of using this interface is to know the exact name of the encoder.
 * The encoder name can be obtained through capability query.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param name Video encoder name
 * @return Returns a Pointer to an OH_AVCodec instance.
 * Return NULL if memory ran out or the encoder name is not supported.
 * @since 9
 * @version 1.0
 */
OH_AVCodec *OH_VideoEncoder_CreateByName(const char *name);

/**
 * @brief Creates a primary video encoder with preprocessor.
 *
 * Creates a primary video encoder instance that supports:
 * 1. Preprocessing features (downsampling, cropping, drop frame)
 * 2. Creating a secondary encoder for one-input-dual-output encoding
 *
 * @param mime Mime type description string, refer to {@link AVCODEC_MIME_TYPE}.
 *             Cannot be NULL, must be a supported MIME type
 *             (e.g., {@link OH_AVCODEC_MIMETYPE_VIDEO_AVC}, {@link OH_AVCODEC_MIMETYPE_VIDEO_HEVC}).
 * @param codec Double pointer to an OH_AVCodec instance, used to receive the created encoder.
 *              Cannot be NULL. If creation is successful, the encoder needs to be released
 *              by calling {@link OH_VideoEncoder_Destroy}.
 *
 * @return Returns {@link AV_ERR_OK} if the execution is successful.
 *         For other error codes, refer to {@link OH_AVErrCode}.
 *         Returns {@link AV_ERR_INVALID_VAL} if:
 *         - mime is NULL.
 *         - codec is NULL.
 *         - mime type is not supported.
 *         Returns {@link AV_ERR_NO_MEMORY} if memory allocation fails.
 *
 * @since 26.0.0
 */
OH_AVErrCode OH_VideoEncoder_CreatePrimaryWithPreproc(const char *mime, OH_AVCodec **codec);

/**
 * @brief Creates a secondary video encoder from a primary video encoder.
 *
 * Creates a secondary video encoder instance from a primary encoder created by
 * {@link OH_VideoEncoder_CreatePrimaryWithPreproc}. The secondary encoder:
 * 1. Shares the input source with the primary encoder
 * 2. Can be configured with independent encoding parameters
 * 3. Can use different preprocessing parameters
 * 4. Can be started/stopped independently from the primary encoder
 * 5. The lifecycle of primary encoder must be longer than secondary encoder
 * 6. One primary encoder can only have one secondary encoder at the same time
 *
 * @param primary Pointer to a primary OH_AVCodec instance created by
 *                {@link OH_VideoEncoder_CreatePrimaryWithPreproc}. Cannot be NULL.
 * @param codec Double pointer to an OH_AVCodec instance, used to receive the created encoder.
 *              Cannot be NULL. If creation is successful, the encoder needs to be released
 *              by calling {@link OH_VideoEncoder_Destroy}.
 *
 * @return Returns {@link AV_ERR_OK} if the execution is successful.
 *         For other error codes, refer to {@link OH_AVErrCode}.
 *         Returns {@link AV_ERR_INVALID_VAL} if:
 *         - primary is NULL.
 *         - codec is NULL.
 *         - primary is not a valid primary encoder.
 *         Returns {@link AV_ERR_OPERATE_NOT_PERMIT} if primary encoder already has an existing secondary encoder.
 *         Returns {@link AV_ERR_NO_MEMORY} if memory allocation fails.
 *
 * @note Lifecycle management:
 *       - The lifecycle of primary encoder must be longer than secondary encoder.
 *       - Recommended destruction order: destroy secondary encoder first, then primary encoder.
 *       - If primary encoder is destroyed before secondary encoder, the system will automatically
 *         destroy the secondary encoder before releasing the primary encoder.
 *       - Both encoders must be destroyed by calling {@link OH_VideoEncoder_Destroy}.
 *       - One primary encoder can only have one secondary encoder at the same time.
 *         After the secondary encoder is destroyed, a new secondary encoder can be created
 *         from the same primary encoder again.
 *
 * @since 26.0.0
 */
OH_AVErrCode OH_VideoEncoder_CreateSecondaryFromPrimary(OH_AVCodec *primary, OH_AVCodec **codec);

/**
 * @brief Clear the internal resources of the encoder and destroy the encoder instance.
 * Can not be destroyed repeatedly.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}, the input codec pointer is non encoder instance or NULL.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoEncoder_Destroy(OH_AVCodec *codec);

/**
 * @brief Set the OH_AVCodecCallback callback function so that the application can respond to the events
 * generated by the video encoder. This interface must be called before Prepare is called.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param callback A collection of all callback functions, see {@link OH_AVCodecAsyncCallback}
 * @param userData The data that the user rely on to execute the callback
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}, the input codec pointer is non encoder instance or NULL.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * @deprecated since 11
 * @useinstead OH_VideoEncoder_RegisterCallback
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoEncoder_SetCallback(OH_AVCodec *codec, OH_AVCodecAsyncCallback callback, void *userData);

/**
 * @brief Set the OH_AVCodecCallback callback function so that the application can respond to the events
 * generated by the video encoder. This interface must be called before Prepare is called.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param callback A collection of all callback functions, see {@link OH_AVCodecCallback}
 * @param userData The data that the user rely on to execute the callback
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}, the input codec pointer is non encoder instance or NULL.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * @since 11
 */
OH_AVErrCode OH_VideoEncoder_RegisterCallback(OH_AVCodec *codec, OH_AVCodecCallback callback, void *userData);

/**
 * @brief Set the OH_AVCodecCallback callback function so that the application can respond to the events
 * generated by the video encoder. In encode Surface mode, this interface is used to set frame-specific
 * parameters. If this interface is used, it must be invoked before {@link OH_VideoEncoder_Configure}.
 *
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param onInputParameter A callback functions, see {@link OH_VideoEncoder_OnNeedInputParameter}
 * @param userData The data that the user rely on to execute the callback
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}, the input codec pointer is non encoder instance or NULL.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state, must be called before Prepare.
 * @since 12
 */
OH_AVErrCode OH_VideoEncoder_RegisterParameterCallback(OH_AVCodec *codec,
                                                       OH_VideoEncoder_OnNeedInputParameter onInputParameter,
                                                       void *userData);

/**
 * @brief To configure the encode parameters of video encoder, typically, you need to configure
 * the description information of the encoded video track, such as the width, height, and pixel format.
 * This interface must be called before Prepare is called.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param format A pointer to an OH_AVFormat that gives the description of the video track to be encoded
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}
 * 1. the input codec pointer is non encoder instance or NULL;
 * 2. unsupported input format parameters.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state, must be called before Prepare.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoEncoder_Configure(OH_AVCodec *codec, OH_AVFormat *format);

/**
 * @brief Prepare the internal resources of the encoder.The Configure interface must be called before
 * calling this interface.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_INVALID_VAL}, the input codec pointer is non encoder instance or NULL.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoEncoder_Prepare(OH_AVCodec *codec);

/**
 * @brief Start the encoder, this interface must be called after the Prepare is successful. After being
 * successfully started, the encoder will start reporting NeedInputData events. In Surface mode, OnNewOutputBuffer
 * will be triggered for each completed frame encoding after a correct input is received on the surface.
 * In Buffer mode, the encoder trigger an input callback immediately. Each time the caller completes an input,
 * the encoder performs encoding, OnNewOutputBuffer will be triggered for each completed frame encoding.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}, the input codec pointer is non encoder instance or NULL.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoEncoder_Start(OH_AVCodec *codec);

/**
 * @brief Stop the encoder and release the input and output buffer. After stopping,
 * you can re-enter the Running state through Start.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}, the input codec pointer is non encoder instance or NULL.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoEncoder_Stop(OH_AVCodec *codec);

/**
 * @brief Clear the input and output data buffered and parameters in the encoder,
 * for example, PPS/SPS in H264 format. After this interface is called,
 * all the buffer indexes previously reported through the asynchronous callback will be invalidated,
 * make sure not to access the buffers corresponding to these indexes. This interface cannot be called continuously.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}, the input codec pointer is non encoder instance or NULL.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoEncoder_Flush(OH_AVCodec *codec);

/**
 * @brief Reset the encoder. The encoder returns to the Initialized state. To continue encoding,
 * you need to call the Configure interface again to configure the encoder instance.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}, the input codec pointer is non encoder instance or NULL.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoEncoder_Reset(OH_AVCodec *codec);

/**
 * @brief Get the OH_AVFormat of the output data of the encoder, refer to {@link OH_AVFormat} for details.
 * It should be noted that the life cycle of the OH_AVFormat instance pointed to by the return value * needs to
 * be released by {@link OH_AVFormat_Destroy}.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @return Returns a pointer to an OH_AVFormat instance.
 * Return NULL if the codec is NULL or invalid.
 * @since 9
 * @version 1.0
 */
OH_AVFormat *OH_VideoEncoder_GetOutputDescription(OH_AVCodec *codec);

/**
 * @brief Set encoder parameters when encoder running. Note: This interface can only be called after
 * the encoder is started. At the same time, incorrect parameter settings may cause the encoding to fail.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param format OH_AVFormat handle pointer
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}
 * 1. the input codec pointer is non encoder instance or NULL;
 * 2. unsupported input format parameters.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoEncoder_SetParameter(OH_AVCodec *codec, OH_AVFormat *format);

/**
 * @brief Get the input surface from the video encoder, this interface must be called before Prepare is called.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param window A pointer to a OHNativeWindow instance, see {@link OHNativeWindow}, the application is responsible
 * for managing the life cycle of the window, call OH_NativeWindow_DestroyNativeWindow() when done.
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_INVALID_VAL}, the input codec pointer is non encoder instance or NULL.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoEncoder_GetSurface(OH_AVCodec *codec, OHNativeWindow **window);

/**
 * @brief Return the processed output buffer to the encoder.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param index The index value corresponding to the output buffer
 * should be given by {@link OH_AVCodecOnNewOutputData}
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}, the input codec pointer is non encoder instance or NULL.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state.
 * @deprecated since 11
 * @useinstead OH_VideoEncoder_FreeOutputBuffer
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoEncoder_FreeOutputData(OH_AVCodec *codec, uint32_t index);

/**
 * @brief Notifies the video encoder that the input stream has ended. This interface is only used in Surface mode.
 * In Buffer mode, the OH_AVBuffer carries the EOS information to notify the end of the stream.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}, the input codec pointer is non encoder instance or NULL.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state.
 * @since 9
 * @version 1.0
 */
OH_AVErrCode OH_VideoEncoder_NotifyEndOfStream(OH_AVCodec *codec);

/**
 * @brief Submit the input buffer filled with data to the video encoder.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param index Enter the index value corresponding to the buffer,
 * should be given by {@link OH_AVCodecOnNeedInputData}.
 * @param attr Information describing the data contained in the buffer
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}, the input codec pointer is non encoder instance or NULL.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state.
 * @deprecated since 11
 * @useinstead OH_VideoEncoder_PushInputBuffer
 * @since 10
 */
OH_AVErrCode OH_VideoEncoder_PushInputData(OH_AVCodec *codec, uint32_t index, OH_AVCodecBufferAttr attr);

/**
 * @brief In Buffer mode, the OH_AVBuffer corresponding to the index is submitted to the encoder for encoding.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param index Enter the index value corresponding to the buffer,
 * should be given by {@link OH_AVCodecOnNeedInputBuffer}.
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}
 * 1. the input codec pointer is non encoder instance or NULL;
 * 2. unsupported input format parameters.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state.

 * @since 11
 */
OH_AVErrCode OH_VideoEncoder_PushInputBuffer(OH_AVCodec *codec, uint32_t index);

/**
 * @brief In Surface mode, the encode parameters of the frame corresponding to the
 * index is submitted to the encoder for encoding.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param index Enter the index value corresponding to the input parameter,
 * should be given by {@link OH_VideoEncoder_OnNeedInputParameter}
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}, the input codec pointer is non encoder instance or NULL.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state.
 * @since 12
 */
OH_AVErrCode OH_VideoEncoder_PushInputParameter(OH_AVCodec *codec, uint32_t index);

/**
 * @brief Return the OH_AVBuffer corresponding to the processed index to the encoder.
 * Need to call this interface to release output buffer immediately after using.
 * Otherwise, the encode process will be blocked.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param index The index value corresponding to the output buffer,
 * should be given by {@link OH_AVCodecOnNewOutputBuffer}.
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}
 * 1. the input codec pointer is non encoder instance or NULL;
 * 2. unsupported input format parameters;
 * 3. the index is vaild or consecutively assigned to the same index,
 * the error do not affect the subsequent encode process
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, internal execution error.
 * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state.
 * @since 11
 */
OH_AVErrCode OH_VideoEncoder_FreeOutputBuffer(OH_AVCodec *codec, uint32_t index);

/**
 * @brief Queries the index of the next available input buffer.
 *
 * This API must be followed by calling {@link OH_VideoEncoder_GetInputBuffer} to obtain the buffer handle,
 * which should then be passed to the encoder via {@link OH_VideoEncoder_PushInputBuffer}.\n
 * Note: This operation is only supported in synchronous mode.\n
 *
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param index The index of the input buffer
 * @param timeoutUs Timeout duration in microseconds, negative value indicates infinite wait.
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}, the encoder is nullptr or invalid.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_SERVICE_DIED}, avcodec service is died.
 * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, not permitted in asynchronous mode.
 * {@link AV_ERR_TRY_AGAIN_LATER}, query failed, recommended retry after delay..
 * @since 20
 */
OH_AVErrCode OH_VideoEncoder_QueryInputBuffer(struct OH_AVCodec *codec, uint32_t *index, int64_t timeoutUs);

/**
 * @brief Acquires the handle of an available input buffer.
 *
 * Note: It's only applicable in synchronous mode.\n
 *
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param index Buffer index obtained via {@link OH_VideoEncoder_QueryInputBuffer}.
 * @return Returns a Pointer to an OH_AVBuffer instance.
 * Return nullptr if no buffer available.
 * @since 20
 */
OH_AVBuffer *OH_VideoEncoder_GetInputBuffer(struct OH_AVCodec *codec, uint32_t index);

/**
 * @brief Queries the index of the next available output buffer.
 *
 * The obtained buffer handle through {@link OH_VideoEncoder_GetOutputBuffer} must be
 * return to the encoder via {@link OH_VideoEncoder_FreeOutputBuffer}.\n
 * Note: This operation is only supported in synchronous mode.\n
 *
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param index The index value corresponding to the output buffer
 * @param timeoutUs Timeout duration in microseconds, negative value indicates infinite wait.
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_NO_MEMORY}, internal errors in the input encode instance, such as an abnormal NULL.
 * {@link AV_ERR_INVALID_VAL}, the encoder is nullptr or invalid.
 * {@link AV_ERR_UNKNOWN}, unknown error.
 * {@link AV_ERR_SERVICE_DIED}, avcodec service is died.
 * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state.
 * {@link AV_ERR_OPERATE_NOT_PERMIT}, not permitted in asynchronous mode.
 * {@link AV_ERR_STREAM_CHANGED}, stream format changed, call {@link OH_VideoEncoder_GetOutputDescription} to
 * retrieve new stream information.
 * {@link AV_ERR_TRY_AGAIN_LATER}, query failed, recommended retry after delay.
 * @since 20
 */
OH_AVErrCode OH_VideoEncoder_QueryOutputBuffer(struct OH_AVCodec *codec, uint32_t *index, int64_t timeoutUs);

/**
 * @brief Acquires the handle of an available output buffer.
 *
 * Note: It's only applicable in synchronous mode.\n
 *
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param index Buffer index obtained via {@link OH_VideoEncoder_QueryOutputBuffer}.
 * @return Returns a Pointer to an OH_AVBuffer instance.
 * Return nullptr if no buffer available.
 * @since 20
 */
OH_AVBuffer *OH_VideoEncoder_GetOutputBuffer(struct OH_AVCodec *codec, uint32_t index);

/**
 * @brief Description information of the image received by the encoder after call {@OH_VideoEncoder_Configure},
 * refer to {@link OH_AVFormat} for details. It should be noted that the life cycle of the OH_AVFormat
 * instance pointed to by the return value needs to be released by {@link OH_AVFormat_Destroy}.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @return Returns a pointer to an OH_AVFormat instance.
 * Return NULL if the encoder is NULL or invalid.
 * @since 10
 */
OH_AVFormat *OH_VideoEncoder_GetInputDescription(OH_AVCodec *codec);

/**
 * @brief Check whether the current codec instance is valid.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @param codec Pointer to an OH_AVCodec instance
 * @param isValid Output Parameter. A pointer to a boolean instance, it is true if the codec instance is valid,
 * false if the codec instance is invalid. It is recommended that the invoker initialize isValid to false.
 * @return Returns AV_ERR_OK if the execution is successful,
 * otherwise returns a specific error code, refer to {@link OH_AVErrCode}.
 * {@link AV_ERR_INVALID_VAL}, the input codec pointer is non encoder instance or NULL.
 * @since 10
 */
OH_AVErrCode OH_VideoEncoder_IsValid(OH_AVCodec *codec, bool *isValid);

/**
 * @brief The bitrate mode of video encoder.
 * @syscap SystemCapability.Multimedia.Media.VideoEncoder
 * @since 9
 * @version 1.0
 * @useinstead OH_BitrateMode
 */
typedef enum OH_VideoEncodeBitrateMode {
    /* constant bit rate mode. */
    CBR = 0,
    /* variable bit rate mode. */
    VBR = 1,
    /* constant quality mode. */
    CQ = 2,
    /* stable quality rate control mode. */
    SQR = 3,
    /* high quality rate control mode. */
    CBR_HIGH_QUALITY = 4
} OH_VideoEncodeBitrateMode;

#ifdef __cplusplus
}
#endif

#endif // NATIVE_AVCODEC_VIDEOENCODER_H
/** @} */