From ce0bc077b516d5e05dec45cb4fa8a8f3d2096b96 Mon Sep 17 00:00:00 2001 From: huangtianyu Date: Sat, 14 Jun 2025 20:24:24 +0800 Subject: [PATCH 1/2] LppNdk Signed-off-by: huangtianyu --- .../player_framework/lowpower_audio_sink.h | 415 +++++++++++++++ .../lowpower_audio_sink_base.h | 154 ++++++ .../player_framework/lowpower_avsink/BUILD.gn | 41 ++ .../liblowpower_avsink.ndk.json | 222 ++++++++ .../player_framework/lowpower_avsink_base.h | 85 +++ .../player_framework/lowpower_video_sink.h | 482 ++++++++++++++++++ .../lowpower_video_sink_base.h | 156 ++++++ ndk_targets.gni | 2 + 8 files changed, 1557 insertions(+) create mode 100644 multimedia/player_framework/lowpower_audio_sink.h create mode 100644 multimedia/player_framework/lowpower_audio_sink_base.h create mode 100644 multimedia/player_framework/lowpower_avsink/BUILD.gn create mode 100644 multimedia/player_framework/lowpower_avsink/liblowpower_avsink.ndk.json create mode 100644 multimedia/player_framework/lowpower_avsink_base.h create mode 100644 multimedia/player_framework/lowpower_video_sink.h create mode 100644 multimedia/player_framework/lowpower_video_sink_base.h diff --git a/multimedia/player_framework/lowpower_audio_sink.h b/multimedia/player_framework/lowpower_audio_sink.h new file mode 100644 index 000000000..1429dd217 --- /dev/null +++ b/multimedia/player_framework/lowpower_audio_sink.h @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2025 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 LowPowerAudioSink + * @{ + * + * @brief The LowPowerAudioSink sub module provides variables, properties, and functions + * for lowpower audio sink. + * + * @since 20 + */ + +/** + * @file lowpower_audio_sink.h + * + * @brief Declare the Native API used for lowpower audio sink. + * + * @library liblowpower_avsink.so + * @kit MediaKit + * @syscap SystemCapability.Multimedia.Media.LowPowerAVSink + * @since 20 + */ + +#ifndef NATIVE_LOWPOWER_AUDIO_SINK_H +#define NATIVE_LOWPOWER_AUDIO_SINK_H + +#include +#include +#include "native_averrors.h" +#include "native_avformat.h" +#include "lowpower_audio_sink_base.h" +#include "ohaudio/native_audiostream_base.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Creates a lowpower audio sink instance from the mime type, which is recommended in most cases. + * + * @param {const char*} mime mime type description string, refer to {@link AVCODEC_MIME_TYPE} + * @return Returns a Pointer to an LowPowerAudioSink instance. + * Return nullptr if memory ran out or the mime type is not supported. + * @since 20 + */ +OH_LowPowerAudioSink* OH_LowPowerAudioSink_CreateByMime(const char* mime); + +/** + * @brief To configure the lowpower audio sink, typically, you need to configure the description information of the + * decoded audio track, which can be extracted from the OH_AVSource. This interface must be called before Prepare + * is called. + * + * @param {OH_LowPowerAudioSink*} sink Pointer to an OH_LowPowerAudioSinkinstance + * @param {OH_AVFormat*} format A pointer to an OH_AVFormat to give the description of the audio track to be decoded + * @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 sink or format is nullptr or invalid. Invalid param in format. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state, must be called before Prepare. + * {@link AV_ERR_UNSUPPORTED_FORMAT}, unsupported format. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSink_Configure(OH_LowPowerAudioSink* sink, const OH_AVFormat* format); + +/** + * @brief Set dynamic parameters to the lowpower audio sink. + * Note: This interface can only be called after the decoder is started. + * At the same time, incorrect parameter settings may cause audio sink failure. + * + * @param {OH_LowPowerAudioSink*} sink Pointer to an OH_LowPowerAudioSink instance + * @param {OH_AVFormat*} format pointer to an OH_AVFormat 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 sink or format is nullptr or invalid. Invalid param in format. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * {@link AV_ERR_UNSUPPORTED_FORMAT}, unsupported format. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSink_SetParameter(OH_LowPowerAudioSink* sink, const OH_AVFormat* format); + +/** + * @brief Get parameter of current lowpower audio sink. + * + * @param {OH_LowPowerAudioSink*} sink Pointer to an OH_LowPowerAudioSink instance + * @param {OH_AVFormat*} format pointer to an OH_AVFormat 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 streamer or format is nullptr or invalid. Invalid param in format. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * {@link AV_ERR_UNSUPPORTED_FORMAT}, unsupported format. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSink_GetParameter(OH_LowPowerAudioSink* sink, OH_AVFormat* format); + +/** + * @brief To prepare the internal resources of the lowpower audio sink, the Configure interface must be called before + * calling this interface. + * + * @param {OH_LowPowerAudioSink*} sink Pointer to an OH_LowPowerAudioSink 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 streamer is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSink_Prepare(OH_LowPowerAudioSink* sink); + +/** + * @brief Start the lowpower audio sink, this interface must be called after the Prepare is successful. + * After being successfully started, the lowpower audio sink will start reporting DataNeeded events. + * + * @param {OH_LowPowerAudioSink*} sink Pointer to an OH_LowPowerAudioSink 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 streamer is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSink_Start(OH_LowPowerAudioSink* sink); + +/** + * @brief Pause the lowpower audio sink, this interface must be called after the Start or Resume is successful. + * After being successfully paused, the lowpower audio sink will pause reporting DataNeeded events.. + * + * @param {OH_LowPowerAudioSink*} sink Pointer to an OH_LowPowerAudioSink 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 streamer is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSink_Pause(OH_LowPowerAudioSink* sink); + +/** + * @brief Resume the lowpower audio sink, this interface must be called after the Pause is successful. + * After being successfully resumed, the lowpower audio sink will resume reporting DataNeeded events. + * + * @param {OH_LowPowerAudioSink*} sink Pointer to an OH_LowPowerAudioSink 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 streamer is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSink_Resume(OH_LowPowerAudioSink* sink); + +/** + * @brief Clear cache data in the lowpower audio sink, this interface is suggested to not be called after the Start + * or Resume. It should be noted that need to re-enter if the codec has been input before Codec-Specific-Data. + * + * @param {OH_LowPowerAudioSink*} sink Pointer to an OH_LowPowerAudioSink 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 streamer is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSink_Flush(OH_LowPowerAudioSink* sink); + +/** + * @brief Stop the lowpower audio sink. + * + * @param {OH_LowPowerAudioSink*} sink Pointer to an OH_LowPowerAudioSink 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 streamer is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSink_Stop(OH_LowPowerAudioSink* sink); + +/** + * @brief Reset the lowpower audio sink. Too reuse this instance, you need to call the Configure. + * + * @param {OH_LowPowerAudioSink*} sink Pointer to an OH_LowPowerAudioSink 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 streamer is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_INVALID_STATE}, the interface was called in an invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSink_Reset(OH_LowPowerAudioSink* sink); + +/** + * @brief Clear the internal resources of the lowpower audio sink and destroy the lowpower audio sink instance. + * + * @param {OH_LowPowerAudioSink*} sink Pointer to an OH_LowPowerAudioSink 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 codec is nullptr or invalid. + * {@link AV_ERR_INVALID_STATE}, the interface was called in an invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSink_Destroy(OH_LowPowerAudioSink* sink); + +/** + * @brief Set volume of current lowpower audio sink. + * + * @param {OH_LowPowerAudioSink*} sink Pointer to an OH_LowPowerAudioSink instance + * @param {const float} volume Volume to set which changes from 0.0 to 1.0 + * @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 codec is nullptr or invalid. + * {@link AV_ERR_INVALID_STATE}, the interface was called in an invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSink_SetVolume(OH_LowPowerAudioSink* sink, const float volume); + +/** + * @brief Set playback speed for the lowpower audio sink. + * + * @param {OH_LowPowerAudioSink*} sink Pointer to an OH_LowPowerAudioSink instance + * @param {const float} speed The playback speed value needs to be specified, the valid value is 0.1-4.0 + * @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 streamer is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSink_SetPlaybackSpeed(OH_LowPowerAudioSink* sink, const float speed); + +/** + * @brief Return frame packet buffer to lowpower audio sink. + * + * @param {OH_LowPowerAudioSink*} sink Pointer to an OH_LowPowerAudioSink instance + * @param {OH_AVSamplesBuffer*} samples Pointer to an OH_AVSamplesBuffer 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 streamer is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSink_ReturnSamples(OH_LowPowerAudioSink* sink, OH_AVSamplesBuffer* samples); + +/** + * @brief Regsister callback instance for lowpower audio sink. + * + * @param {OH_LowPowerAudioSink*} sink Pointer to an OH_LowPowerAudioSink instance + * @param {OH_LowPowerAudioSinkCallback*} callback Pointer to an OH_LowPowerAudioSinkCallback 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 streamer is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, the interface was called in an invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSink_RegisterCallback(OH_LowPowerAudioSink* sink, OH_LowPowerAudioSinkCallback* callback); + +/** + * @brief Creates a lowpower audio sink callback instance. + * + * @return Returns a Pointer to an OH_LowPowerAudioSinkCallback instance. + * Return nullptr if memory ran out. + * @since 20 + */ +OH_LowPowerAudioSinkCallback* OH_LowPowerAudioSinkCallback_Create(void); + +/** + * @brief Destroy the lowpower audio sink callback instance. + * + * @param {OH_LowPowerAudioSinkCallback*} callback Pointer to an OH_LowPowerAudioSinkCallback 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 callback is nullptr or invalid. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSinkCallback_Destroy(OH_LowPowerAudioSinkCallback* callback); + +/** + * @brief Add onPositionUpdated listener to the lowpower audio sink callback instance. + * + * @param {OH_LowPowerAudioSinkCallback*} callback Pointer to an OH_LowPowerAudioSinkCallback instance + * @param {OH_LowPowerAudioSink_OnPositionUpdated} onPositionUpdated OH_LowPowerAudioSink_OnPositionUpdated function, + * refer to {@link OH_LowPowerAudioSink_OnPositionUpdated} + * @param userData User specific data + * @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 callback is nullptr or invalid. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSinkCallback_SetPositionUpdateListener( + OH_LowPowerAudioSinkCallback* callback, + OH_LowPowerAudioSink_OnPositionUpdated onPositionUpdated, + void* userData); + +/** + * @brief Add onDataNeeded listener to the lowpower audio sink callback instance. + * + * @param {OH_LowPowerAudioSinkCallback*} callback Pointer to an OH_LowPowerAudioSinkCallback instance + * @param {OH_LowPowerAudioSink_OnDataNeeded} onDataNeeded OH_LowPowerAudioSink_OnDataNeeded function, + * refer to {@link OH_LowPowerAudioSink_OnDataNeeded} + * @param {void*} userData User specific data + * @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 callback is nullptr or invalid. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSinkCallback_SetDataNeededListener( + OH_LowPowerAudioSinkCallback* callback, + OH_LowPowerAudioSink_OnDataNeeded onDataNeeded, + void* userData); + +/** + * @brief Add onError listener to the lowpower audio sink callback instance. + * + * @param {OH_LowPowerAudioSinkCallback*} callback Pointer to an OH_LowPowerAudioSinkCallback instance + * @param {OH_LowPowerAudioSink_OnError} onError OH_LowPowerAudioSink_OnError function, + * refer to {@link OH_LowPowerAudioSink_OnError} + * @param {void*} userData User specific data + * @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 callback is nullptr or invalid. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSinkCallback_SetErrorListener( + OH_LowPowerAudioSinkCallback* callback, + OH_LowPowerAudioSink_OnError onError, + void* userData); + +/** + * @brief Add onInterrupted listener to the lowpower audio sink callback instance. + * + * @param {OH_LowPowerAudioSinkCallback*} callback Pointer to an OH_LowPowerAudioSinkCallback instance + * @param {OH_LowPowerAudioSink_OnInterrupted} onInterrupted OH_LowPowerAudioSink_OnInterrupted function, + * refer to {@link OH_LowPowerAudioSink_OnInterrupted} + * @param {void*} userData User specific data + * @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 callback is nullptr or invalid. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSinkCallback_SetInterruptListener( + OH_LowPowerAudioSinkCallback* callback, + OH_LowPowerAudioSink_OnInterrupted onInterrupted, + void* userData); + +/** + * @brief Add onDeviceChanged listener to the lowpower audio sink callback instance. + * + * @param {OH_LowPowerAudioSinkCallback*} callback Pointer to an OH_LowPowerAudioSink Callback instance + * @param {OH_LowPowerAudioSink_OnDeviceChanged} onDeviceChanged OH_LowPowerAudioSink_OnDeviceChanged function, + * refer to {@link OH_LowPowerAudioSink_OnDeviceChanged} + * @param {void*} userData User specific data + * @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 callback is nullptr or invalid. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSinkCallback_SetDeviceChangeListener( + OH_LowPowerAudioSinkCallback* callback, + OH_LowPowerAudioSink_OnDeviceChanged onDeviceChanged, + void* userData); + +/** + * @brief Add onEos listener to the lowpower audio sink callback instance. + * + * @param {OH_LowPowerAudioSinkCallback*} callback Pointer to an OH_LowPowerAudioSinkCallback instance + * @param {OH_LowPowerAudioSink_OnEos} onEos OH_LowPowerAudioSink_OnEos function, + * refer to {@link OH_LowPowerAudioSink_OnEos} + * @param {void*} userData User specific data + * @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 callback is nullptr or invalid. + * @since 20 + */ +OH_AVErrCode OH_LowPowerAudioSinkCallback_SetEosListener( + OH_LowPowerAudioSinkCallback *callback, + OH_LowPowerAudioSink_OnEos onEos, + void* userData); + +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_LOWPOWER_AUDIO_SINK_H + +/** @} */ diff --git a/multimedia/player_framework/lowpower_audio_sink_base.h b/multimedia/player_framework/lowpower_audio_sink_base.h new file mode 100644 index 000000000..f532f5c6d --- /dev/null +++ b/multimedia/player_framework/lowpower_audio_sink_base.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2025 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 LowPowerAudioSink + * @{ + * + * @brief The LowPowerAudioSink sub module provides variables, properties, + * and functions for lowpower audio sink. + * + * @since 20 + */ + +/** + * @file lowpower_audio_sink_base.h + * + * @brief Declare the Native API used for lowpower audio sink. + * + * @library liblowpower_avsink.so + * @kit MediaKit + * @syscap SystemCapability.Multimedia.Media.LowPowerAVSink + * @since 20 + */ + +#ifndef NATIVE_LOWPOWER_AUDIO_SINK_BASE_H +#define NATIVE_LOWPOWER_AUDIO_SINK_BASE_H + +#include +#include "lowpower_avsink_base.h" +#include "ohaudio/native_audiostream_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Forward declaration of OH_LowPowerAudioSink. + * + * @since 20 + */ +typedef struct OH_LowPowerAudioSink OH_LowPowerAudioSink; + +/** + * @brief Forward declaration of OH_LowPowerAudioSinkCallback. + * + * @since 20 + */ +typedef struct OH_LowPowerAudioSinkCallback OH_LowPowerAudioSinkCallback; + +/** + * @brief When an error occurs in the running of the OH_LowPowerAudioSink instance, the function pointer will be called + * to report specific error information. + * + * @param {OH_LowPowerAudioSink*} sink OH_LowPowerAudioSink instance + * @param {OH_AVErrCode} errorCode Error code when an error occurs + * @param {const char*} errorMsg Error description information + * @param {void*} userData User specific data + * @since 20 + */ +typedef void (*OH_LowPowerAudioSink_OnError)( + OH_LowPowerAudioSink* sink, + OH_AVErrCode errCode, + const char* errorMsg, + void* userData); + +/** + * @brief When the OH_LowPowerAudioSink instance report current play position, the function pointer will be called + * to report position information. + * + * @param {OH_LowPowerAudioSink*} sink OH_LowPowerAudioSink instance + * @param {int64_t} currentPosition Returns the current playback progress value of the service + * @param {void*} userData User specific data + * @since 20 + */ +typedef void (*OH_LowPowerAudioSink_OnPositionUpdated)( + OH_LowPowerAudioSink* sink, + int64_t currentPosition, + void* userData); + +/** + * @brief When the OH_LowPowerAudioSink instance report to need data, the function pointer will be called + * to request data. + * + * @param {OH_LowPowerAudioSink*} sink OH_LowPowerAudioSink instance + * @param {OH_AVSamplesBuffer*} samples OH_AVSamplesBuffer instance that will be written in + * @param {void*} userData User specific data + * @since 20 + */ +typedef void (*OH_LowPowerAudioSink_OnDataNeeded)( + OH_LowPowerAudioSink* sink, + OH_AVSamplesBuffer* samples, + void* userData); + +/** + * @brief This function pointer will point to the callback function that + * is used to handle audio interrupt events. + * + * @param {OH_LowPowerAudioSink*} sink OH_LowPowerAudioSink instance + * @param {OH_AudioInterrupt_ForceType} type The audio interrupt type, + * please refer to {@link OH_AudioInterrupt_ForceType} + * @param {OH_AudioInterrupt_Hint} hint The audio interrupt hint type, please refer to {@link OH_AudioInterrupt_Hint} + * @param {void*} userData User specific data + * @since 20 + */ +typedef void (*OH_LowPowerAudioSink_OnInterrupted)( + OH_LowPowerAudioSink* sink, + OH_AudioInterrupt_ForceType type, + OH_AudioInterrupt_Hint hint, + void* userData); + +/** + * @brief When the output device of an audio renderer changed, the function pointer will be called + * to report device change reason. + * + * @param {OH_LowPowerAudioSink*} sink OH_LowPowerAudioSink instance + * @param {OH_AudioStream_DeviceChangeReason} reason Indicates that why does the output device changes, + * please refer to {@link OH_AudioStream_DeviceChangeReason} + * @param {void*} userData User specific data + * @since 20 + */ +typedef void (*OH_LowPowerAudioSink_OnDeviceChanged)( + OH_LowPowerAudioSink* sink, + OH_AudioStream_DeviceChangeReason reason, + void* userData); + +/** + * @brief When the lowpower audio sink play to end of stream, the function pointer will be called + * to report play completed event. + * + * @param {OH_LowPowerAudioSink*} sink OH_LowPowerAudioSinkinstance + * @param {void*} userData User specific data + * @since 20 + */ +typedef void (*OH_LowPowerAudioSink_OnEos)(OH_LowPowerAudioSink* sink, void* userData); + +#ifdef __cplusplus +} +#endif +#endif // NATIVE_LOWERPOWER_AUDIOSINK_BASH_H + +/** @} */ diff --git a/multimedia/player_framework/lowpower_avsink/BUILD.gn b/multimedia/player_framework/lowpower_avsink/BUILD.gn new file mode 100644 index 000000000..36cdd222a --- /dev/null +++ b/multimedia/player_framework/lowpower_avsink/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (C) 2025 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. + +import("//build/ohos.gni") +import("//build/ohos/ndk/ndk.gni") +import("//foundation/multimedia/player_framework/config.gni") + +ohos_ndk_headers("lowpower_avsink_header") { + dest_dir = "$ndk_headers_out_dir/multimedia/player_framework" + sources = [ + "../lowpower_audio_sink_base.h", + "../lowpower_audio_sink.h", + "../lowpower_avsink_base.h", + "../lowpower_video_sink_base.h", + "../lowpower_video_sink.h", + ] +} + +ohos_ndk_library("liblowpower_avsink") { + ndk_description_file = "./liblowpower_avsink.ndk.json" + output_name = "lowpower_avsink" + output_extension = "so" + system_capability = "SystemCapability.Multimedia.Media.LowPowerAVSink" + system_capability_headers = [ + "multimedia/player_framework/lowpower_audio_sink_base.h", + "multimedia/player_framework/lowpower_audio_sink.h", + "multimedia/player_framework/lowpower_avsink_base.h", + "multimedia/player_framework/lowpower_video_sink_base.h", + "multimedia/player_framework/lowpower_video_sink.h", + ] +} diff --git a/multimedia/player_framework/lowpower_avsink/liblowpower_avsink.ndk.json b/multimedia/player_framework/lowpower_avsink/liblowpower_avsink.ndk.json new file mode 100644 index 000000000..1c624517d --- /dev/null +++ b/multimedia/player_framework/lowpower_avsink/liblowpower_avsink.ndk.json @@ -0,0 +1,222 @@ +[ + { + "first_introduced": "20", + "name": "OH_AVSamplesBuffer_AppendOneBuffer" + }, + { + "first_introduced": "20", + "name": "OH_AVSamplesBuffer_GetRemainedCapacity" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_CreateByMime" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_Configure" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_SetParameter" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_GetParameter" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_Prepare" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_Start" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_Pause" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_Resume" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_Flush" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_Stop" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_Reset" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_Destroy" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_SetVolume" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_SetPlaybackSpeed" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_ReturnSamples" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSink_RegisterCallback" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSinkCallback_Create" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSinkCallback_Destroy" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSinkCallback_SetPositionUpdateListener" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSinkCallback_SetDataNeededListener" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSinkCallback_SetErrorListener" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSinkCallback_SetInterruptListener" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSinkCallback_SetDeviceChangeListener" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerAudioSinkCallback_SetEosListener" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_CreateByMime" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_Configure" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_SetParameter" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_GetParameter" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_SetVideoSurface" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_Prepare" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_StartDecoder" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_RenderFirstFrame" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_StartRenderer" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_Pause" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_Resume" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_Flush" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_Stop" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_Reset" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_Destroy" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_SetSyncAudioSink" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_SetTargetStartFrame" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_SetPlaybackSpeed" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_ReturnSamples" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSink_RegisterCallback" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSinkCallback_Create" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSinkCallback_Destroy" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSinkCallback_SetDataNeededListener" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSinkCallback_SetAnchorUpdateListener" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSinkCallback_SetErrorListener" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSinkCallback_SetRenderStartListener" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSinkCallback_SetStreamChangedListener" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSinkCallback_SetFirstFrameDecodedListener" + }, + { + "first_introduced": "20", + "name": "OH_LowPowerVideoSinkCallback_SetEosListener" + } +] \ No newline at end of file diff --git a/multimedia/player_framework/lowpower_avsink_base.h b/multimedia/player_framework/lowpower_avsink_base.h new file mode 100644 index 000000000..b6171f4bb --- /dev/null +++ b/multimedia/player_framework/lowpower_avsink_base.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2025 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 AVSinkBase + * @{ + * + * @brief The AVSinkBase module provides variables, properties, and functions + * for lowpower audio sink and lowpower video sink. + * + * @since 20 + */ + +/** + * @file lowpower_avsink_base.h + * + * @brief Declare the Native API used for lowpower audio sink + * and lowpower video sink. + * + * @library liblowpower_avsink.so + * @kit MediaKit + * @syscap SystemCapability.Multimedia.Media.LowPowerAVSink + * @since 20 + */ + +#ifndef NATIVE_LOWPOWER_AVSINK_BASE_H +#define NATIVE_LOWPOWER_AVSINK_BASE_H + +#include +#include "native_averrors.h" +#include "native_avbuffer.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Forward declaration of OH_AVSamplesBuffer. + * + * @since 20 + */ +typedef struct OH_AVSamplesBuffer OH_AVSamplesBuffer; + +/** + * @brief Append one OH_AVBuffer data to framePacketBuffer instance. + * + * @param samplesBuffer OH_AVSamplesBuffer instance + * @param avBuffer OH_AVBuffer buffer will be appended to + * @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 samplesBuffer or the avBuffer or data pointer is nullptr or invalid. + * {@link AV_ERR_NO_MEMORY}, the framePacketBuffer has no enough remained capacity to append one OH_AVBuffer. + * {@link AV_ERR_UNKNOWN}, unknown error. + * @since 20 + */ +OH_AVErrCode OH_AVSamplesBuffer_AppendOneBuffer(OH_AVSamplesBuffer *samplesBuffer, OH_AVBuffer *avBuffer); + +/** + * @brief Get remained capacity of OH_AVSamplesBuffer instance. + * + * @param {OH_AVSamplesBuffer} samplesBuffer OH_AVSamplesBuffer instance + * @return Returns remained capacity of OH_AVSamplesBuffer instance, + * return -1 if samplesBuffer or data poniter is is nullptr or invalid. + * @since 20 + */ +int32_t OH_AVSamplesBuffer_GetRemainedCapacity(OH_AVSamplesBuffer *samplesBuffer); + +#ifdef __cplusplus +} +#endif +#endif // NATIVE_LOWPOWER_AVSINK_BASE_H + +/** @} */ \ No newline at end of file diff --git a/multimedia/player_framework/lowpower_video_sink.h b/multimedia/player_framework/lowpower_video_sink.h new file mode 100644 index 000000000..e9f123a27 --- /dev/null +++ b/multimedia/player_framework/lowpower_video_sink.h @@ -0,0 +1,482 @@ +/* + * Copyright (c) 2025 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 LowPowerVideoSink + * @{ + * + * @brief The LowPowerVideoSink sub module provides variables, properties, and functions + * for lowpower video sink. + * + * @since 20 + */ + +/** + * @file lowpower_video_sink.h + * + * @brief Declare the Native API used for lowpower video sink. + * + * @library liblowpower_avsink.so + * @kit MediaKit + * @syscap SystemCapability.Multimedia.Media.LowPowerAVSink + * @since 20 + */ + +#ifndef NATIVE_LOWPOWER_VIDEO_SINK_H +#define NATIVE_LOWPOWER_VIDEO_SINK_H + +#include +#include "native_averrors.h" +#include "native_avformat.h" +#include "lowpower_avsink_base.h" +#include "lowpower_video_sink_base.h" +#include "lowpower_audio_sink_base.h" +#include "native_window/external_window.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Creates a lowpower video sink instance from the mime type, which is recommended in most cases. + * + * @param {const char*} mime mime type description string, refer to {@link AVCODEC_MIME_TYPE} + * @return Returns a Pointer to an OH_LowPowerVideoSink instance. + * Return nullptr if memory ran out or the mime type is not supported. + * @since 20 + */ +OH_LowPowerVideoSink* OH_LowPowerVideoSink_CreateByMime(const char* mime); + +/** + * @brief To configure the lowpower video sink, typically, you need to configure the description information of the + * decoded video track, which can be extracted from the OH_AVSource. This interface must be called before Prepare + * is called. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink instance + * @param {OH_AVFormat*} format A pointer to an OH_AVFormat to give the description of the video track to be decoded, + * key of format refer to lowpower_avsink_base.h + * @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 sink or format is nullptr or invalid. Invalid param in format. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state, must be called before Prepare. + * {@link AV_ERR_UNSUPPORTED_FORMAT}, unsupported format. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_Configure(OH_LowPowerVideoSink* sink, const OH_AVFormat* format); + +/** + * @brief Set dynamic parameters to the lowpower video sink. + * Note: This interface can only be called after the decoder is started. + * At the same time, incorrect parameter settings may cause video sink failure. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink instance + * @param {OH_AVFormat*} format pointer to an OH_AVFormat instance, key of format refer to lowpower_avsink_base.h + * @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 sink or format is nullptr or invalid. Invalid param in format. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * {@link AV_ERR_UNSUPPORTED_FORMAT}, unsupported format. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_SetParameter(OH_LowPowerVideoSink* sink, const OH_AVFormat* format); + +/** + * @brief Get parameter of current lowpower video sink. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink instance + * @param {OH_AVFormat*} format pointer to an OH_AVFormat instance, key of format refer to lowpower_avsink_base.h + * @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 sink or format is nullptr or invalid. Invalid param in format. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * {@link AV_ERR_UNSUPPORTED_FORMAT}, unsupported format. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_GetParameter(OH_LowPowerVideoSink* sink, OH_AVFormat* format); + +/** + * @brief Specify the output Surface to provide decoded lowpower video sink, + * this interface must be called before Prepare is called. In the executing state, it can be called directly. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink instance + * @param {OHNativeWindow*} surface A pointer to a OHNativeWindow instance, see {@link OHNativeWindow} + * @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 sink or the surface is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_SetVideoSurface(OH_LowPowerVideoSink* sink, const OHNativeWindow* surface); + +/** + * @brief To prepare the internal resources of the lowpower video sink, the Configure interface must be called before + * calling this interface. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink 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 sink is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * {@link AV_ERR_OPERATE_NOT_PERMIT}, has not called SetVideoSurface. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_Prepare(OH_LowPowerVideoSink* sink); + +/** + * @brief Start decoder of the lowpower video sink, this interface must be called after the Prepare is successful. + * After being successfully started, the lowpower audio sink will start reporting DataNeeded events. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink 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 sink is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_StartDecoder(OH_LowPowerVideoSink* sink); + +/** + * @brief Render first frame of video sink, this interface must be called after the StartDecode is successful and + * onFirstFrameDecoded is called. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink 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 sink is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_RenderFirstFrame(OH_LowPowerVideoSink* sink); + +/** + * @brief Start renderer of the lowpower video sink, this interface must be called after the StartDecode is successful. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink 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 sink is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_StartRenderer(OH_LowPowerVideoSink* sink); + +/** + * @brief Pause the lowpower video sink, this interface must be called after the StartRender or Resume is successful. + * After being successfully paused, the lowpower video sink will pause reporting DataNeeded events.. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink 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 sink is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_Pause(OH_LowPowerVideoSink* sink); + +/** + * @brief Resume the lowpower video sink, this interface must be called after the Pause is successful. + * After being successfully resumed, the lowpower video sink will resume reporting DataNeeded events. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSinkinstance + * @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 sink is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_Resume(OH_LowPowerVideoSink* sink); + +/** + * @brief Clear cache data in the lowpower video sink, this interface is suggested to not be called after the Start + * or Resume. It should be noted that need to re-enter if the codec has been input before Codec-Specific-Data. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink 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 sink is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_Flush(OH_LowPowerVideoSink* sink); + +/** + * @brief Stop the lowpower video sink. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink 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 sink is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, this interface was called in invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_Stop(OH_LowPowerVideoSink* sink); + +/** + * @brief Reset the lowpower video sink. Too reuse this instance, you need to call the Configure. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink 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 sink is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, the interface was called in an invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_Reset(OH_LowPowerVideoSink* sink); + +/** + * @brief Clear the internal resources of the lowpower video sink and destroy the lowpower video sink instance. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink 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 sink is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_INVALID_STATE}, the interface was called in an invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_Destroy(OH_LowPowerVideoSink* sink); + +/** + * @brief Set the lowpower audio sink instance to the lowpower video sink instance for audio video sync. + * + * @param {OH_LowPowerVideoSink*} videoSink Pointer to an OH_LowPowerVideoSink instance + * @param {OH_LowPowerAudioSink*} audioSink Pointer to an OH_LowPowerAudioSink 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 videoSink or audioSink is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, the interface was called in an invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_SetSyncAudioSink( + OH_LowPowerVideoSink* videoSink, OH_LowPowerAudioSink* audioSink); + +/** + * @brief Set target start frame pts, and the video frame will be renderred from the target pts. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink instance + * @param {const int64_t} framePts target video frame pts + * @param {OH_LowPowerVideoSink_OnTargetArrived*} onTargetArrived OH_LowPowerVideoSink_OnTargetArrived func, + * will be called once, refer to {@link OH_LowPowerVideoSink_OnTargetArrived} + * @param {const int64_t} timeoutMs if wait first frame over timeoutMs, onTargetArrived will be called directly. + * @param {void *} userData User specific data + * @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 sink is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, the interface was called in an invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_SetTargetStartFrame( + OH_LowPowerVideoSink* sink, + const int64_t framePts, + OH_LowPowerVideoSink_OnTargetArrived onTargetArrived, + const int64_t timeoutMs, + void* userData); + +/** + * @brief Set playback speed for the lowpower video sink + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink instance + * @param {const float} speed Indicates the value of the playback rate. + * The current version is valid in the range of 0.1-4.0 + * @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 sink is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, the interface was called in an invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_SetPlaybackSpeed(OH_LowPowerVideoSink* sink, const float speed); + +/** + * @brief Return frame packet buffer to lowpower video sink. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink instance + * @param {OH_AVSamplesBuffer*} samples Pointer to an OH_AVSamplesBuffer 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 sink is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, the interface was called in an invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_ReturnSamples(OH_LowPowerVideoSink* sink, OH_AVSamplesBuffer* samples); + +/** + * @brief Regsister callback instance for lowpower video sink. + * + * @param {OH_LowPowerVideoSink*} sink Pointer to an OH_LowPowerVideoSink instance + * @param {OH_LowPowerVideoSinkCallback*} callback Pointer to an OH_LowPowerVideoSinkCallback 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 sink is nullptr or invalid. + * {@link AV_ERR_UNKNOWN}, unknown error. + * {@link AV_ERR_SERVICE_DIED}, media service is died. + * {@link AV_ERR_INVALID_STATE}, the interface was called in an invalid state. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSink_RegisterCallback(OH_LowPowerVideoSink* sink, OH_LowPowerVideoSinkCallback* callback); + +/** + * @brief Creates a lowpower video sink callback instance. + * + * @return Returns a Pointer to an OH_LowPowerVideoSinkCallback instance. + * Return nullptr if memory ran out. + * @since 20 + */ +OH_LowPowerVideoSinkCallback* OH_LowPowerVideoSinkCallback_Create(void); + +/** + * @brief Destroy the lowpower video sink callback instance. + * + * @param {OH_LowPowerVideoSinkCallback*} callback Pointer to an OH_LowPowerVideoSinkCallback 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 callback is nullptr or invalid. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSinkCallback_Destroy(OH_LowPowerVideoSinkCallback* callback); + +/** + * @brief Add onDataNeeded listener to the lowpower video sink callback instance. + * + * @param {OH_LowPowerVideoSinkCallback*} callback Pointer to an OH_LowPowerVideoSinkCallback instance + * @param {OH_LowPowerVideoSink_OnDataNeeded} onDataNeeded OH_LowPowerVideoSink_OnDataNeeded function, + * refer to {@link OH_LowPowerVideoSink_OnDataNeeded} + * @param {void*} userData User specific data + * @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 callback is nullptr or invalid. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSinkCallback_SetDataNeededListener( + OH_LowPowerVideoSinkCallback* callback, OH_LowPowerVideoSink_OnDataNeeded onDataNeeded, void* userData); + +/** + * @brief Add onError listener to the lowpower video sink callback instance. + * + * @param {OH_LowPowerVideoSinkCallback*} callback Pointer to an OH_LowPowerVideoSinkCallback instance + * @param {OH_LowPowerVideoSink_OnError} onError OH_LowPowerVideoSink_OnError function, + * refer to {@link OH_LowPowerVideoSink_OnError} + * @param {void*} userData User specific data + * @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 sink is nullptr or invalid. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSinkCallback_SetErrorListener( + OH_LowPowerVideoSinkCallback* callback, OH_LowPowerVideoSink_OnError onError, void* userData); + +/** + * @brief Add onRenderStarted listener to the lowpower video sink callback instance. + * + * @param {OH_LowPowerVideoSinkCallback*} callback Pointer to an OH_LowPowerVideoSinkCallback instance + * @param {OH_LowPowerVideoSink_OnRenderStarted} onRenderStarted OH_LowPowerVideoSink_OnRenderStarted function, + * refer to {@link OH_LowPowerVideoSink_OnRenderStarted} + * @param {void*} userData User specific data + * @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 sink is nullptr or invalid. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSinkCallback_SetRenderStartListener( + OH_LowPowerVideoSinkCallback* callback, OH_LowPowerVideoSink_OnRenderStarted onRenderStarted, void* userData); + +/** + * @brief Add onStreamChanged listener to the lowpower video sink callback instance. + * + * @param {OH_LowPowerVideoSinkCallback*} callback Pointer to an OH_LowPowerVideoSinkCallback instance + * @param {OH_LowPowerVideoSink_OnStreamChanged} onStreamChanged OH_LowPowerVideoSink_OnStreamChanged function, + * refer to {@link OH_LowPowerVideoSink_OnStreamChanged} + * @param {void*} userData User specific data + * @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 sink is nullptr or invalid. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSinkCallback_SetStreamChangedListener( + OH_LowPowerVideoSinkCallback* callback, OH_LowPowerVideoSink_OnStreamChanged onStreamChanged, void* userData); + +/** + * @brief Add onRenderStarted listener to the lowpower video sink callback instance. + * + * @param {OH_LowPowerVideoSinkCallback*} callback Pointer to an OH_LowPowerVideoSinkCallback instance + * @param {OH_LowPowerVideoSink_OnFirstFrameDecoded} onFirstFrameDecoded OH_LowPowerVideoSink_OnFirstFrameDecoded + * function, + * refer to {@link OH_LowPowerVideoSink_OnFirstFrameDecoded} + * @param {void*} userData User specific data + * @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 sink is nullptr or invalid. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSinkCallback_SetFirstFrameDecodedListener( + OH_LowPowerVideoSinkCallback* callback, + OH_LowPowerVideoSink_OnFirstFrameDecoded onFirstFrameDecoded, + void* userData); + +/** + * @brief Add onEos listener to the lowpower video sink callback instance. + * + * @param {OH_LowPowerVideoSinkCallback*} callback Pointer to an OH_LowPowerVideoSinkCallback instance + * @param {OH_LowPowerVideoSink_OnEos} onEos OH_LowPowerVideoSink_OnEos function, + * refer to {@link OH_LowPowerVideoSink_OnEos} + * @param {void*} userData User specific data + * @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 callback is nullptr or invalid. + * @since 20 + */ +OH_AVErrCode OH_LowPowerVideoSinkCallback_SetEosListener(OH_LowPowerVideoSinkCallback* callback, + OH_LowPowerVideoSink_OnEos onEos, void* userData); + +#ifdef __cplusplus +} +#endif + +#endif // NATIVE_LOWPOWER_VIDEOSINK_H + +/** @} */ diff --git a/multimedia/player_framework/lowpower_video_sink_base.h b/multimedia/player_framework/lowpower_video_sink_base.h new file mode 100644 index 000000000..7bf47f59f --- /dev/null +++ b/multimedia/player_framework/lowpower_video_sink_base.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2025 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 LowPowerVideoSink + * @{ + * + * @brief The LowPowerVideoSink submodule provides variables, properties, and functions + * for lowpower video sink. + * + * @since 20 + */ + +/** + * @file lowpower_video_sink_base.h + * + * @brief Declare the Native API used for lowpower video sink. + * + * @library liblowpower_avsink.so + * @kit MediaKit + * @syscap SystemCapability.Multimedia.Media.LowPowerAVSink + * @since 20 + */ + +#ifndef NATIVE_LOWPOWER_VIDEO_SINK_BASE_H +#define NATIVE_LOWPOWER_VIDEO_SINK_BASE_H + +#include +#include +#include "native_avformat.h" +#include "lowpower_avsink_base.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Forward declaration of OH_LowPowerVideoSink. + * + * @since 20 + */ +typedef struct OH_LowPowerVideoSink OH_LowPowerVideoSink; + +/** + * @brief Forward declaration of OH_LowPowerVideoSinkCallback. + * + * @since 20 + */ +typedef struct OH_LowPowerVideoSinkCallback OH_LowPowerVideoSinkCallback; + +/** + * @brief When the OH_LowPowerVideoSink instance report to need data, the function pointer will be called + * to request data. + * + * @param {OH_LowPowerVideoSink*} sink OH_LowPowerVideoSink instance + * @param {OH_AVSamplesBuffer*} buffer OH_AVSamplesBuffer instance that will be written in + * @param {void*} userData User specific data + * @since 20 + */ +typedef void (*OH_LowPowerVideoSink_OnDataNeeded)( + OH_LowPowerVideoSink* sink, + OH_AVSamplesBuffer* buffer, + void *userData); + +/** + * @brief When an error occurs in the running of the OH_LowPowerVideoSink instance, the function pointer will be called + * to report specific error information. + * + * @param {OH_LowPowerVideoSink*} sink OH_LowPowerVideoSink instance + * @param {OH_AVErrCode} errorCode The error code returned when an error occurs during service operation. + * See the definition of {@OH_AVErrCode} + * @param {const char*} errorMsg string of Error description information returned when an error occurs + * during service operation + * @param {void*} userData User specific data + * @since 20 + */ +typedef void (*OH_LowPowerVideoSink_OnError)( + OH_LowPowerVideoSink* sink, + OH_AVErrCode errCode, + const char* errMsg, + void* userData); + +/** + * @brief When the OH_LowPowerVideoSink instance report target video frame arrived, the function pointer will be called. + * + * @param {OH_LowPowerVideoSink*} sink OH_LowPowerVideoSink instance + * @param {const int64_t} targetPts Target pts of renderred frame + * @param {const bool} isTimeout If wait target pts timeout, it is false + * @param {void*} userData User specific data + * @since 20 + */ +typedef void (*OH_LowPowerVideoSink_OnTargetArrived)( + OH_LowPowerVideoSink* sink, + const int64_t targetPts, + const bool isTimeout, + void* userData); + +/** + * @brief When the OH_LowPowerVideoSink instance report first frame renderred, the function pointer will be called. + * + * @param {OH_LowPowerVideoSink*} sink OH_LowPowerVideoSink instance + * @param {void*} userData User specific data + * @since 20 + */ +typedef void (*OH_LowPowerVideoSink_OnRenderStarted)(OH_LowPowerVideoSink* sink, void* userData); + +/** + * @brief When the OH_LowPowerVideoSink instance reports that the parameters of the video stream have changed, + * the application is notified through this function + * + * @param {OH_LowPowerVideoSink*} sink OH_LowPowerVideoSink instance + * @param {OH_AVFormat*} format Carrying changing parameters and corresponding values + * @param {void*} userData User specific data + * @since 20 + */ +typedef void (*OH_LowPowerVideoSink_OnStreamChanged)(OH_LowPowerVideoSink* sink, OH_AVFormat* format, void* userData); + +/** + * @brief When the first frame of the OH_LowPowerVideoSink instance is decoded successfully, this function pointer will + * be called. + * + * @param {OH_LowPowerVideoSink*} sink OH_LowPowerVideoSink instance + * @param {void*} userData User specific data + * @since 20 + */ +typedef void (*OH_LowPowerVideoSink_OnFirstFrameDecoded)(OH_LowPowerVideoSink* sink, void* userData); + +/** + * @brief When the OH_LowPowerVideoSinkinstance play to end of stream, the function pointer will be called + * to report play completed event. + * + * @param {OH_LowPowerVideoSink*} sink OH_LowPowerVideoSink instance + * @param {void*} userData User specific data + * @since 20 + */ +typedef void (*OH_LowPowerVideoSink_OnEos)(OH_LowPowerVideoSink* sink, void* userData); + +#ifdef __cplusplus +} +#endif +#endif // NATIVE_LOWPOWER_VIDEOSINK_BASH_H + +/** @} */ diff --git a/ndk_targets.gni b/ndk_targets.gni index f937e3025..c0fa91865 100644 --- a/ndk_targets.gni +++ b/ndk_targets.gni @@ -142,6 +142,8 @@ _ndk_library_targets = [ "//interface/sdk_c/multimedia/player_framework/avscreen_capture:native_avscreen_capture_header", "//interface/sdk_c/multimedia/player_framework/avplayer:libavplayer", "//interface/sdk_c/multimedia/player_framework/avplayer:avplayer_header", + "//interface/sdk_c/multimedia/player_framework/lowpower_avsink:lowpower_avsink_header", + "//interface/sdk_c/multimedia/player_framework/lowpower_avsink:liblowpower_avsink", "//interface/sdk_c/multimedia/player_framework/avrecorder:libavrecorder", "//interface/sdk_c/multimedia/player_framework/avrecorder:avrecorder_header", "//interface/sdk_c/multimedia/player_framework/avmetadata_extractor:libavmetadata_extractor", -- Gitee From 32bb5d2d60495f0d9552e304557d11f257ec9a43 Mon Sep 17 00:00:00 2001 From: huangtianyu Date: Sat, 14 Jun 2025 13:15:10 +0000 Subject: [PATCH 2/2] update multimedia/player_framework/lowpower_avsink/BUILD.gn. Signed-off-by: huangtianyu --- multimedia/player_framework/lowpower_avsink/BUILD.gn | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/multimedia/player_framework/lowpower_avsink/BUILD.gn b/multimedia/player_framework/lowpower_avsink/BUILD.gn index 36cdd222a..3ddd00e45 100644 --- a/multimedia/player_framework/lowpower_avsink/BUILD.gn +++ b/multimedia/player_framework/lowpower_avsink/BUILD.gn @@ -10,22 +10,22 @@ # 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. - + import("//build/ohos.gni") import("//build/ohos/ndk/ndk.gni") import("//foundation/multimedia/player_framework/config.gni") - + ohos_ndk_headers("lowpower_avsink_header") { dest_dir = "$ndk_headers_out_dir/multimedia/player_framework" sources = [ - "../lowpower_audio_sink_base.h", "../lowpower_audio_sink.h", + "../lowpower_audio_sink_base.h", "../lowpower_avsink_base.h", - "../lowpower_video_sink_base.h", "../lowpower_video_sink.h", + "../lowpower_video_sink_base.h", ] } - + ohos_ndk_library("liblowpower_avsink") { ndk_description_file = "./liblowpower_avsink.ndk.json" output_name = "lowpower_avsink" @@ -38,4 +38,4 @@ ohos_ndk_library("liblowpower_avsink") { "multimedia/player_framework/lowpower_video_sink_base.h", "multimedia/player_framework/lowpower_video_sink.h", ] -} +} \ No newline at end of file -- Gitee