/*
 * 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 VideoDecoder
 * @{
 *
 * @brief The VideoDecoder module provides interfaces for video decoding.
 *
 * @since 9
 */

/**
 * @file native_avcodec_videodecoder.h
 *
 * @brief The file declares the native APIs used for video decoding.
 *
 * @kit AVCodecKit
 * @library libnative_media_vdec.so
 * @syscap SystemCapability.Multimedia.Media.VideoDecoder
 * @since 9
 */
#ifndef NATIVE_AVCODEC_VIDEODECODER_H
#define NATIVE_AVCODEC_VIDEODECODER_H
#include <stdint.h>
#include <stdio.h>
#include "native_avcodec_base.h"
#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Describes a native object for MediaKeySession.
 *
 * @since 11
 */
typedef struct MediaKeySession MediaKeySession;

/**
 * @brief Creates a video decoder instance based on a MIME type. This function is recommended in most cases.
 *
 * @param mime Pointer to a string that describes the MIME type. For details, see {@link AVCODEC_MIME_TYPE}.
 * @return Pointer to the video decoder instance.
 *     <br> If the decoder type is not supported or the memory is insufficient, NULL is returned.
 * @since 9
 */
OH_AVCodec *OH_VideoDecoder_CreateByMime(const char *mime);

/**
 * @brief Creates a video decoder instance based on a decoder name. To use this function, you must know the exact name
 * of the decoder. The decoder name can be obtained through capability query.
 *
 * For details, see [Obtaining Supported Codecs](docroot://media/avcodec/obtain-supported-codecs.md#Creating a Codec with the Specified Name).
 * 
 * @param name Pointer to a video decoder name.
 * @return Pointer to the video decoder instance.
 *     <br>If the decoder name is not supported or the memory is insufficient, NULL is returned.
 * @since 9
 */
OH_AVCodec *OH_VideoDecoder_CreateByName(const char *name);

/**
 * @brief Clears the internal resources of a video decoder and destroys the decoder instance. You only need to call the
 * function once.
 *
 * @param codec Pointer to a video decoder instance.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The operation is not allowed.
 * @since 9
 */
OH_AVErrCode OH_VideoDecoder_Destroy(OH_AVCodec *codec);

/**
 * @brief Sets an asynchronous callback so that your application can respond to events generated by a video decoder.
 * This function must be called prior to {@link OH_VideoDecoder_Prepare}.
 *
 * @param codec Pointer to a video decoder instance.
 * @param callback All callback functions.
 * @param userData Pointer to the data on which the caller depends when executing the callback.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The operation is not allowed.
 * @deprecated since 11
 * @useinstead OH_VideoDecoder_RegisterCallback
 * @since 9
 */
OH_AVErrCode OH_VideoDecoder_SetCallback(OH_AVCodec *codec, OH_AVCodecAsyncCallback callback, void *userData);

/**
 * @brief Registers an asynchronous callback so that your application can respond to events generated by a video
 * decoder. This function must be called prior to {@link OH_VideoDecoder_Prepare}.
 *
 * @param codec Pointer to a video decoder instance.
 * @param callback All callback functions.
 * @param userData Pointer to the data on which the caller depends when executing the callback.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The operation is not allowed.
 * @since 11
 */
OH_AVErrCode OH_VideoDecoder_RegisterCallback(OH_AVCodec *codec, OH_AVCodecCallback callback, void *userData);

/**
 * @brief Sets an output surface for a video decoder.
 *
 * In the initialization phase, this function must be called prior to {@link OH_VideoDecoder_Prepare}. In the executing
 * state, it can be called directly.
 *
 * @param codec Pointer to a video decoder instance.
 * @param window Pointer to an OHNativeWindow instance.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The function is called in the buffer mode.
 *     It can be called only in the surface mode.
 *     <br>{@link AV_ERR_INVALID_VAL}: <br>1. The value of **codec** is nullptr or does not point
 *     to a decoder instance. <br>2. The value of **window** is nullptr.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_INVALID_STATE}: This API cannot be called in the current decoder state.
 * @since 9
 */
OH_AVErrCode OH_VideoDecoder_SetSurface(OH_AVCodec *codec, OHNativeWindow *window);

/**
 * @brief Configures a video decoder. It is typically necessary to provide the information about the video to decode,
 * which can be extracted from {@link OH_AVSource}. This function must be called prior to
 * {@link OH_VideoDecoder_Prepare}.
 *
 * The value ranges of the following parameters can be obtained
 * from [Capability Query](docroot://media/avcodec/obtain-supported-codecs.md).
 * All the values of **OH_MD_KEY_ROTATION** are supported.
 *
 * If the current platform does not support **OH_MD_KEY_VIDEO_ENABLE_LOW_LATENCY**, no error is reported and the normal
 * decoding process is used.
 * Parameter verification rules are as follows:
 * | Key    | Value Within the Range| Value Out of Range| No Value Configured|
 * | ----------| -------- | -------- | ------ |
 * | OH_MD_KEY_WIDTH      | AV_ERR_OK       | AV_ERR_INVALID_VAL      | AV_ERR_INVALID_VAL  |
 * | OH_MD_KEY_HEIGHT     | AV_ERR_OK       | AV_ERR_INVALID_VAL       | AV_ERR_INVALID_VAL     |
 * | OH_MD_KEY_PIXEL_FORMAT {@link OH_AVPixelFormat}   | AV_ERR_OK       | AV_ERR_UNSUPPORT       | AV_ERR_OK      |
 * | OH_MD_KEY_FRAME_RATE | AV_ERR_OK       | AV_ERR_INVALID_VAL       | AV_ERR_OK     |
 * | {@link OH_MD_KEY_ROTATION}| AV_ERR_OK       | AV_ERR_INVALID_VAL       | AV_ERR_OK      |
 * @note You are advised to set the parameters based on the maximum resolution supported by the instance.
 * Otherwise, an exception may occur when streams with the resolution higher than the maximum resolution
 * are to be decoded. This setting directly affects the memory usage of the application.
 *
 * @param codec Pointer to a video decoder instance.
 * @param format Pointer to an OH_AVFormat instance, which provides the description information about the video track
 *     to be decoded.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}:<br>1. The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>2. The format is not supported.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The operation is not allowed.
 *     <br>{@link AV_ERR_INVALID_STATE}: The function is not called prior to {@link OH_VideoDecoder_Prepare}.
 *     <br>{@link AV_ERR_VIDEO_UNSUPPORTED_COLOR_SPACE_CONVERSION}: Color Space Conversion is not supported.
 *     <br>{@link AV_ERR_UNSUPPORT}: The pixel format is not supported.
 * @since 9
 */
OH_AVErrCode OH_VideoDecoder_Configure(OH_AVCodec *codec, OH_AVFormat *format);

/**
 * @brief Prepares internal resources for a video decoder. This function must be called after
 * {@link OH_VideoDecoder_Configure}.
 *
 * @param codec Pointer to a video decoder instance.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_INVALID_STATE}: This API cannot be called in the current decoder state.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}:<br>1. The operation is not allowed.
 *     <br>2. Color Space Conversion is configured, but the decoder is in buffer mode.
 * @since 9
 */
OH_AVErrCode OH_VideoDecoder_Prepare(OH_AVCodec *codec);

/**
 * @brief Starts a video decoder. This function should be called after a successful call of
 * {@link OH_VideoDecoder_Prepare}.
 * After being started, the decoder starts to report the registered event.
 *
 * @param codec Pointer to a video decoder instance.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_INVALID_STATE}: This API cannot be called in the current decoder state.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}:<br>1. The operation is not allowed.
 *     <br>2. Color Space Conversion is configured, but {@link OH_VideoDecoder_Prepare} is not called.
 * @since 9
 */
OH_AVErrCode OH_VideoDecoder_Start(OH_AVCodec *codec);

/**
 * @brief Stops a video decoder and releases the input and output buffers. After the video decoder is stopped, you can
 * call {@link OH_VideoDecoder_Start} to enter the running state again.
 *
 * If you have passed codec-specific data in the previous **Start** for the decoder, you must pass it again.
 *
 * @param codec Pointer to a video decoder instance.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_INVALID_STATE}: This API cannot be called in the current decoder state.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The operation is not allowed.
 * @since 9
 */
OH_AVErrCode OH_VideoDecoder_Stop(OH_AVCodec *codec);

/**
 * @brief Clears the input and output data and parameters, for example, H.264 PPS/SPS, cached in a video decoder.
 * This function invalidates the indexes of all buffers previously reported through the asynchronous callback.
 *
 * Therefore, before calling this function, ensure that the buffers with the specified indexes are no longer required.
 *
 * @param codec Pointer to a video decoder instance.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_INVALID_STATE}: This API cannot be called in the current decoder state.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The operation is not allowed.
 * @since 9
 */
OH_AVErrCode OH_VideoDecoder_Flush(OH_AVCodec *codec);

/**
 * @brief Resets a video decoder. The decoder returns to the initial state. To continue decoding, you must call
 * {@link OH_VideoDecoder_Configure} to configure the decoder again.
 *
 * @param codec Pointer to a video decoder instance.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The operation is not allowed.
 * @since 9
 */
OH_AVErrCode OH_VideoDecoder_Reset(OH_AVCodec *codec);

/**
 * @brief Obtains the {@link OH_AVFormat} information about the decoder's output data.
 *
 * For details, see {@link OH_AVFormat}. You must call {@link OH_AVFormat_Destroy} to
 * release the {@link OH_AVFormat} instance when its lifecycle ends.
 * 
 * @param codec Pointer to a video decoder instance.
 * @return Pointer to an OH_AVFormat instance.
 *    <br>If the value of **codec** is nullptr or does not point to a decoder instance, NULL is returned.
 * @since 9
 */
OH_AVFormat *OH_VideoDecoder_GetOutputDescription(OH_AVCodec *codec);

/**
 * @brief Sets dynamic parameters for a video decoder.
 *
 * This function can be called only after the decoder is started. Incorrect parameter settings may cause decoding
 * failure.
 *
 * @param codec Pointer to a video decoder instance.
 * @param format Pointer to an OH_AVFormat instance.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}:<br>1. The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>2. The format is not supported.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_INVALID_STATE}: This API cannot be called in the current decoder state.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The operation is not allowed.
 * @since 9
 */
OH_AVErrCode OH_VideoDecoder_SetParameter(OH_AVCodec *codec, OH_AVFormat *format);

/**
 * @brief Pushes the input buffer filled with data to a video decoder.
 *
 * The input callback reports the available input buffer and the index. For details,
 * see {@link OH_AVCodecOnNeedInputData}.
 * After being pushed to the decoder, a buffer is not accessible until the buffer with the same index is reported
 * again through the input callback. In addition, some decoders require the input of codec-specific data, such as PPS/
 * SPS data in H.264 format, to initialize the decoding process.
 *
 * @param codec Pointer to a video decoder instance.
 * @param index Index of an input buffer. The value is provided by {@link OH_AVCodecOnNeedInputData}.
 * @param attr Description information about the data in the buffer.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: <br>1. The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>2. The index is invalid. This error does not affect the subsequent decoding process.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_INVALID_STATE}: This API cannot be called in the current decoder state.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The operation is not allowed.
 * @deprecated since 11
 * @useinstead OH_VideoDecoder_PushInputBuffer
 * @since 9
 */
OH_AVErrCode OH_VideoDecoder_PushInputData(OH_AVCodec *codec, uint32_t index, OH_AVCodecBufferAttr attr);

/**
 * @brief Returns the processed output buffer to a video decoder and instructs the decoder to render the decoded data
 * in the buffer on the output surface.
 *
 * If no output surface is configured, calling this API only returns the output buffer corresponding to
 * the specified index to the decoder.
 * 
 * @param codec Pointer to a video decoder instance.
 * @param index Index of an output buffer. The value is provided by {@link OH_AVCodecOnNewOutputData}.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: <br>1. The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>2. The index is invalid. This error does not affect the subsequent decoding process.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_INVALID_STATE}: This API cannot be called in the current decoder state.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The operation is not allowed.
 * @deprecated since 11
 * @useinstead OH_VideoDecoder_RenderOutputBuffer
 * @since 9
 */
OH_AVErrCode OH_VideoDecoder_RenderOutputData(OH_AVCodec *codec, uint32_t index);

/**
 * @brief Frees an output buffer of a video decoder.
 *
 * @param codec Pointer to a video decoder instance.
 * @param index Index of an output buffer. The value is provided by {@link OH_AVCodecOnNewOutputData}.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: <br>1. The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>2. The index is invalid. This error does not affect the subsequent decoding process.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_INVALID_STATE}: This API cannot be called in the current decoder state.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The operation is not allowed.
 * @deprecated since 11
 * @useinstead OH_VideoDecoder_FreeOutputBuffer
 * @since 9
 */
OH_AVErrCode OH_VideoDecoder_FreeOutputData(OH_AVCodec *codec, uint32_t index);

/**
 * @brief Notifies a video decoder that the buffer corresponding to the index has been filled with input data.
 *
 * The input callback reports the available input buffer and the index.
 * For details, see {@link OH_AVCodecOnNeedInputBuffer}.
 * After being pushed to the decoder, a buffer is not accessible until the buffer with the same index is reported
 * again through the input callback. In addition, some decoders require the input of codec-specific data, such as PPS/
 * SPS data in H.264 format, to initialize the decoding process.
 *
 * This function is used to transfer the parameters (such as H.264 PPS/SPS) required for decoding to the decoder. The
 * parameters can be transferred to the decoder separately or together with the data to be decoded.
 *
 * @param codec Pointer to a video decoder instance.
 * @param index Index of an input buffer. The value is provided by {@link OH_AVCodecOnNeedInputBuffer}.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: <br>1. The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>2. The index is invalid. This error does not affect the subsequent decoding process.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_INVALID_STATE}: This API cannot be called in the current decoder state.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The operation is not allowed.
 *     <br>{@link AV_ERR_DRM_DECRYPT_FAILED}: The DRM-protected video buffer fails to be decrypted.
 *     You are advised to view logs.
 * @since 11
 */
OH_AVErrCode OH_VideoDecoder_PushInputBuffer(OH_AVCodec *codec, uint32_t index);

/**
 * @brief Returns the output buffer corresponding to the index to a video decoder. The buffer carries the decoded data
 * and is used to instruct the decoder to finish rendering on the output surface.
 *
 * If no output surface is configured, calling this API only returns the output buffer corresponding to
 * the specified index to the decoder.
 * 
 * @param codec Pointer to a video decoder instance.
 * @param index Index of an output buffer. The value is provided by {@link OH_AVCodecOnNewOutputBuffer}.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: <br>1. The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>2. The index is invalid. This error does not affect the subsequent decoding process.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_INVALID_STATE}: This API cannot be called in the current decoder state.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The operation is not allowed.
 * @since 11
 */
OH_AVErrCode OH_VideoDecoder_RenderOutputBuffer(OH_AVCodec *codec, uint32_t index);

/**
 * @brief Returns the output buffer corresponding to the index to a video decoder. The buffer carries the decoded data
 * and is used to instruct the decoder to finish rendering within the specified duration on the output surface.
 *
 * If no output surface is configured, calling this API only returns the output buffer corresponding to
 * the specified index to the decoder.
 *
 * You can request the system to render the buffer at a specific time (after the VSYNC or buffer timestamp) based on
 * the timestamp. To render the buffer at the specified timestamp, that timestamp should approximate the current system
 * time within an acceptable margin of error. Pay attention to the following:
 *
 * 1. Buffers are processed sequentially, which may result in the display of subsequent buffers on the surface being
 * blocked. This is particularly important for interactive scenarios, such as responding to user actions like stopping,
 * fast-forwarding, or rewinding a video.
 *
 * 2. If multiple buffers are sent to the surface for rendering on a single VSYNC event, the last buffer is rendered
 * and other buffers are discarded.
 *
 * 3. If the difference between the timestamp and the current system time exceeds the acceptable margin of error, the
 * surface ignores the timestamp and renders the buffer at the earliest feasible time. In this case, no frames are
 * discarded.
 *
 * 4. If you want the system to handle frame-dropping based on the display's refresh rate, you have to use
 * this function. Otherwise, your application manages frame-dropping on its own.
 *
 * @param codec Pointer to a video decoder instance.
 * @param index Index of an output buffer. The value is provided by {@link OH_AVCodecOnNewOutputBuffer}.
 * @param renderTimestampNs Timestamp (in nanoseconds) when the output buffer is sent to the surface. The value must be
 *     greater than 0 and should be generated by the clock of the std::chrono::steady_clock standard library.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: <br>1. The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>2. The index is invalid. This error does not affect the subsequent decoding process.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_INVALID_STATE}: This API cannot be called in the current decoder state.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The operation is not allowed.
 * @since 12
 */
OH_AVErrCode OH_VideoDecoder_RenderOutputBufferAtTime(OH_AVCodec *codec, uint32_t index, int64_t renderTimestampNs);

/**
 * @brief Frees an output buffer of a video decoder. You need to call this function to release the output buffer in a
 * timely manner. Otherwise, the decoding process is blocked.
 *
 * For details,
 * see step 12 in surface mode or step 10 in buffer mode in [Video Decoding](docroot://media/avcodec/video-decoding.md).
 *
 * @param codec Pointer to a video decoder instance.
 * @param index Index of an output buffer. The value is provided by {@link OH_AVCodecOnNewOutputBuffer}.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: <br>1. The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>2. The index is invalid. This error does not affect the subsequent decoding process.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_INVALID_STATE}: This API cannot be called in the current decoder state.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: The operation is not allowed.
 * @since 11
 */
OH_AVErrCode OH_VideoDecoder_FreeOutputBuffer(OH_AVCodec *codec, uint32_t index);

/**
 * @brief Obtains the index of the next available input buffer.
 *
 * After calling this function, you must call {@link OH_VideoDecoder_GetInputBuffer} to obtain the buffer instance and
 * call {@link OH_VideoDecoder_PushInputBuffer} to pass the buffer instance to the decoder.
 *
 * Note that the preceding operations are supported only in synchronous mode.
 *
 * @param codec Pointer to an OH_AVCodec instance.
 * @param index The index of the input buffer.
 * @param timeoutUs Timeout duration, in microseconds. A negative value means to wait infinitely. The value **0** means
 *     to return immediately. A positive value means to wait for the specified time before exiting.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_INVALID_STATE}: This API cannot be called in the current decoder state.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: This function is called in asynchronous mode.
 *     <br>{@link AV_ERR_TRY_AGAIN_LATER}: The query fails. Try again after a short interval.
 * @since 20
 */
OH_AVErrCode OH_VideoDecoder_QueryInputBuffer(struct OH_AVCodec *codec, uint32_t *index, int64_t timeoutUs);

/**
 * @brief Obtains the instance of the available input buffer.
 *
 * Note that this function works only in synchronous mode.
 *
 * @param codec Pointer to a video decoder instance.
 * @param index Index of the input buffer. It can be obtained by calling {@link OH_VideoDecoder_QueryInputBuffer}.
 * @return Pointer to the OH_AVBuffer instance created. If the operation fails, NULL is returned.
 * @since 20
 */
OH_AVBuffer *OH_VideoDecoder_GetInputBuffer(struct OH_AVCodec *codec, uint32_t index);

/**
 * @brief Obtains the index of the next available output buffer.
 *
 * You can perform the following operations to display or release the decoded frame of the buffer instance obtained
 * through {@link OH_VideoDecoder_GetOutputBuffer}:
 * 1. Return the processed output buffer to the decoder by calling {@link OH_VideoDecoder_FreeOutputBuffer}.
 *
 * 2. Render the output surface by calling {@link OH_VideoDecoder_RenderOutputBuffer}.
 *
 * 3. Render the output surface within the specified time by calling {@link OH_VideoDecoder_RenderOutputBufferAtTime}.
 *
 * Note that the preceding operations are supported only in synchronous mode.
 *
 * @param codec Pointer to a video decoder instance.
 * @param index Index of an output buffer.
 * @param timeoutUs Timeout duration, in microseconds. A negative value means to wait infinitely. The value **0** means
 *     to return immediately. A positive value means to wait for the specified time before exiting.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 *     <br>{@link AV_ERR_INVALID_VAL}: The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>{@link AV_ERR_UNKNOWN}: An unknown error occurs.
 *     <br>{@link AV_ERR_INVALID_STATE}: This API cannot be called in the current decoder state.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}: This function is called in asynchronous mode.
 *     <br>{@link AV_ERR_STREAM_CHANGED}: The stream format has changed. You can call
 *     {@link OH_VideoDecoder_GetOutputDescription} to obtain the new stream information.
 *     <br>{@link AV_ERR_TRY_AGAIN_LATER}: The query fails. Try again after a short interval.
 * @since 20
 */
OH_AVErrCode OH_VideoDecoder_QueryOutputBuffer(struct OH_AVCodec *codec, uint32_t *index, int64_t timeoutUs);

/**
 * @brief Obtains the instance of the available output buffer. Note that this function works only in synchronous mode.
 * 
 * @param codec Pointer to a video decoder instance.
 * @param index Index of the output buffer. It can be obtained by calling {@link OH_VideoDecoder_QueryOutputBuffer}.
 * @return Pointer to the OH_AVBuffer instance created. If the operation fails, NULL is returned.
 * @since 20
 */
OH_AVBuffer *OH_VideoDecoder_GetOutputBuffer(struct OH_AVCodec *codec, uint32_t index);

/**
 * @brief Checks whether the decoder service is valid when a decoder instance exists.
 *
 * @param codec Pointer to a video decoder instance.
 * @param isValid Pointer of the Boolean type. The value indicates the validity of the decoder service only when the
 *     function returns {@link AV_ERR_OK}. The value **true** means that the decoder service is valid,
 *     and **false** means the opposite. It is recommended that you initialize **isValid** to **false**.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_INVALID_VAL}: The value of **codec** is nullptr or does not point to a decoder instance.
 * @since 10
 */
OH_AVErrCode OH_VideoDecoder_IsValid(OH_AVCodec *codec, bool *isValid);

/**
 * @brief Sets the decryption configuration. This function can be called prior to {@link OH_VideoDecoder_Prepare}.
 *
 * @param codec Pointer to a video decoder instance.
 * @param mediaKeySession Pointer to a media key session instance with decryption capabilities.
 * @param secureVideoPath Whether a secure video channel is used. The value **true** means a secure video channel, and
 *     **false** means a non-secure video channel.
 *     In [surface mode](docroot://media/avcodec/video-decoding.md#surface-mode),
 *     both secure and non-secure video channels are supported.
 *     In [buffer mode](docroot://media/avcodec/video-decoding.md#buffer-mode),
 *     only non-secure video channels are supported.
 * @return {@link AV_ERR_OK}: The operation is successful.
 *     <br>{@link AV_ERR_OPERATE_NOT_PERMIT}:<br>1. The operation is not allowed.
 *     <br>2. The decoding service process is abnormal.<br>3.The media key session service is in an error state.
 *     <br>{@link AV_ERR_INVALID_VAL}:<br>1. The value of **codec** is nullptr or does not point to a decoder instance.
 *     <br>2. The valueof **mediaKeySession** is nullptr or invalid.
 *     <br>{@link AV_ERR_NO_MEMORY}: The decoder instance has been destroyed.
 * @since 11
 */
OH_AVErrCode OH_VideoDecoder_SetDecryptionConfig(OH_AVCodec *codec, MediaKeySession *mediaKeySession,
    bool secureVideoPath);
#ifdef __cplusplus
}
#endif
#endif // NATIVE_AVCODEC_VIDEODECODER_H

/** @} */