diff --git a/bundle.json b/bundle.json index 0557ebc0d858eca75e0bf63cec7ff9ec6b425dcd..6d9f3e93813064aeb89e7596f28fafea7a4f8f4a 100644 --- a/bundle.json +++ b/bundle.json @@ -31,6 +31,7 @@ "access_token", "app_file_service", "audio_framework", + "av_codec", "av_session", "background_task_mgr", "battery_manager", diff --git a/config.gni b/config.gni index 5d780a120510d755e61e6ff3b7964c506726d138..722ac2df5523ffad12bc877af3b9db5bfefe6a03 100644 --- a/config.gni +++ b/config.gni @@ -20,6 +20,7 @@ declare_args() { webview_telephony_enable = true webview_battery_manager_enable = true webview_power_manager_enable = true + webview_avcodec_enable = true webview_enterprise_device_manager_enable = true if (defined(global_parts_info) && @@ -43,6 +44,10 @@ declare_args() { !defined(global_parts_info.multimedia_camera_framework)) { webview_camera_enable = false } + if (defined(global_parts_info) && + !defined(global_parts_info.multimedia_av_codec)) { + webview_avcodec_enable = false + } if (defined(global_parts_info) && (!defined(global_parts_info.telephony_cellular_data) || !defined(global_parts_info.telephony_core_service))) { diff --git a/ohos_adapter/BUILD.gn b/ohos_adapter/BUILD.gn index 272aff3197cb14ba15324f1b914813c032121f18..ae210f83254da983f709a1371f820a857d2727cf 100755 --- a/ohos_adapter/BUILD.gn +++ b/ohos_adapter/BUILD.gn @@ -181,6 +181,12 @@ ohos_shared_library("nweb_ohos_adapter") { sources += [ "location_adapter/src/location_proxy_adapter_mock.cpp" ] } + if (webview_avcodec_enable) { + sources += [ "media_adapter/src/media_codec_decoder_adapter_impl.cpp" ] + external_deps += [ "av_codec:av_codec_client" ] + defines += [ "NWEB_MEDIA_AVCODEC_ENABLE" ] + } + if (webview_media_player_enable) { sources += [ "media_adapter/src/player_framework_adapter_impl.cpp" ] external_deps += [ "player_framework:media_client" ] diff --git a/ohos_adapter/interfaces/media_codec_decoder_adapter.h b/ohos_adapter/interfaces/media_codec_decoder_adapter.h new file mode 100644 index 0000000000000000000000000000000000000000..05ab4fc1bc4212faff4fcc8f327fd5cbca5b210d --- /dev/null +++ b/ohos_adapter/interfaces/media_codec_decoder_adapter.h @@ -0,0 +1,128 @@ +/* + * 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. + */ + +#ifndef MEDIA_CODEC_DECODER_ADAPTER_H +#define MEDIA_CODEC_DECODER_ADAPTER_H + +#include +#include +#include +#include +#include +#include + +#include "graphic_adapter.h" + +namespace OHOS::NWeb { +enum class DecoderAdapterCode : int32_t { + DECODER_OK = 0, + DECODER_ERROR = 1, + DECODER_RETRY = 2 +}; + +class DecoderFormat { +public: + DecoderFormat(int32_t width, int32_t height) + : width_(width), height_(height) {}; + + virtual ~DecoderFormat() = default; + + virtual void SetFormatWidth(int32_t width) = 0; + + virtual void SetFormatHeight(int32_t height) = 0; + + int32_t width_; + + int32_t height_; +}; + +enum class ErrorType : int32_t { + CODEC_ERROR_INTERNAL, + CODEC_ERROR_EXTEND_START = 0X10000, +}; + +struct BufferInfo { + int64_t presentationTimeUs = 0; + int32_t size = 0; + int32_t offset = 0; +}; + +enum class BufferFlag : uint32_t { + CODEC_BUFFER_FLAG_NONE = 0, + CODEC_BUFFER_FLAG_EOS = 1 << 0, + CODEC_BUFFER_FLAG_SYNC_FRAME = 1 << 1, + CODEC_BUFFER_FLAG_PARTIAL_FRAME = 1 << 2, + CODEC_BUFFER_FLAG_CODEC_DATA = 1 << 3, +}; + +struct OhosBuffer { + uint8_t *addr; + uint32_t bufferSize; +}; + +class DecoderCallbackAdapter { +public: + DecoderCallbackAdapter() = default; + + virtual ~DecoderCallbackAdapter() = default; + + virtual void OnError(ErrorType errorType, int32_t errorCode) = 0; + + virtual void OnStreamChanged(const DecoderFormat &format) = 0; + + virtual void OnNeedInputData(uint32_t index, OhosBuffer buffer) = 0; + + virtual void OnNeedOutputData(uint32_t index, BufferInfo info, BufferFlag flag) = 0; +}; + +class MediaCodecDecoderAdapter { +public: + MediaCodecDecoderAdapter() = default; + + virtual ~MediaCodecDecoderAdapter() = default; + + virtual DecoderAdapterCode CreateVideoDecoderByMime(const std::string& mimetype) = 0; + + virtual DecoderAdapterCode CreateVideoDecoderByName(const std::string& name) = 0; + + virtual DecoderAdapterCode ConfigureDecoder(int32_t width, int32_t height, double framerate) = 0; + + virtual DecoderAdapterCode SetParameterDecoder(const DecoderFormat &format) = 0; + + virtual DecoderAdapterCode SetOutputSurface(void* window) = 0; + + virtual DecoderAdapterCode PrepareDecoder() = 0; + + virtual DecoderAdapterCode StartDecoder() = 0; + + virtual DecoderAdapterCode StopDecoder() = 0; + + virtual DecoderAdapterCode FlushDecoder() = 0; + + virtual DecoderAdapterCode ResetDecoder() = 0; + + virtual DecoderAdapterCode ReleaseDecoder() = 0; + + virtual DecoderAdapterCode QueueInputBufferDec(uint32_t index, BufferInfo info, BufferFlag flag) = 0; + + virtual DecoderAdapterCode GetOutputFormatDec(int32_t &width, int32_t &height) = 0; + + virtual DecoderAdapterCode ReleaseOutputBufferDec(uint32_t index, bool isRender) = 0; + + virtual DecoderAdapterCode SetCallbackDec(const std::shared_ptr &callback) = 0; +}; + +} +#endif \ No newline at end of file diff --git a/ohos_adapter/interfaces/ohos_adapter_helper.cpp b/ohos_adapter/interfaces/ohos_adapter_helper.cpp index 7d104b432f78435a3048896e27085fc107ef837d..95b0448452a15e2c832999663647397e94d9fc23 100644 --- a/ohos_adapter/interfaces/ohos_adapter_helper.cpp +++ b/ohos_adapter/interfaces/ohos_adapter_helper.cpp @@ -34,6 +34,9 @@ #include "hitrace_adapter_impl.h" #include "imf_adapter_impl.h" #include "keystore_adapter_impl.h" +#if defined(NWEB_MEDIA_AVCODEC_ENABLE) +#include "media_codec_decoder_adapter_impl.h" +#endif #include "mmi_adapter_impl.h" #include "native_image_adapter_impl.h" #if defined(NWEB_TEL_ENABLE) @@ -267,6 +270,15 @@ std::unique_ptr OhosAdapterHelper::CreateDateTimeFormatAd return std::make_unique(); } +std::unique_ptr OhosAdapterHelper::CreateMediaCodecDecoderAdapter() const +{ +#if defined(NWEB_MEDIA_AVCODEC_ENABLE) + return std::make_unique(); +#else + return nullptr; +#endif +} + std::unique_ptr OhosAdapterHelper::CreateNativeImageAdapter() const { return std::make_unique(); diff --git a/ohos_adapter/interfaces/ohos_adapter_helper.h b/ohos_adapter/interfaces/ohos_adapter_helper.h index d1e9ff1b75a1737338b3552806a686c8c59ef278..9f0efe08cbdbe86496772a73b1d71f1e0ce34edb 100644 --- a/ohos_adapter/interfaces/ohos_adapter_helper.h +++ b/ohos_adapter/interfaces/ohos_adapter_helper.h @@ -37,6 +37,7 @@ #include "imf_adapter.h" #include "keystore_adapter.h" #include "media_adapter.h" +#include "media_codec_decoder_adapter.h" #include "mmi_adapter.h" #include "net_connect_adapter.h" #include "net_proxy_adapter.h" @@ -125,6 +126,8 @@ public: std::unique_ptr CreateDateTimeFormatAdapter() const; + std::unique_ptr CreateMediaCodecDecoderAdapter() const; + std::unique_ptr CreateNativeImageAdapter() const; private: diff --git a/ohos_adapter/media_adapter/include/media_codec_decoder_adapter_impl.h b/ohos_adapter/media_adapter/include/media_codec_decoder_adapter_impl.h new file mode 100644 index 0000000000000000000000000000000000000000..b841b4607a21638e3dffcf3af4d728b02d5bdc11 --- /dev/null +++ b/ohos_adapter/media_adapter/include/media_codec_decoder_adapter_impl.h @@ -0,0 +1,111 @@ +/* + * 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. + */ + +#ifndef MEDIA_CODEC_DECODER_ADAPTER_IMPL_H +#define MEDIA_CODEC_DECODER_ADAPTER_IMPL_H + +#include +#include +#include +#include +#include +#include + +#include "avcodec_video_decoder.h" +#include "media_description.h" +#include "media_codec_decoder_adapter.h" + +namespace OHOS::NWeb { +using namespace OHOS::MediaAVCodec; + +class DecoderFormatImpl final : public DecoderFormat { +public: + DecoderFormatImpl(int32_t width, int32_t height) : DecoderFormat(width, height) {}; + + ~DecoderFormatImpl() override = default; + + void SetFormatWidth(int32_t width) override; + + void SetFormatHeight(int32_t height) override; +}; + +class DecoderCallbackImpl : public MediaAVCodec::AVCodecCallback { +public: + DecoderCallbackImpl(std::shared_ptr cb); + + ~DecoderCallbackImpl() override = default; + + void OnError(MediaAVCodec::AVCodecErrorType errorType, int32_t errorCode) override; + + void OnOutputFormatChanged(const MediaAVCodec::Format& format) override; + + void OnInputBufferAvailable(uint32_t index, std::shared_ptr buffer) override; + + void OnOutputBufferAvailable(uint32_t index, MediaAVCodec::AVCodecBufferInfo info, + MediaAVCodec::AVCodecBufferFlag flag, std::shared_ptr buffer) override; + +private: + std::shared_ptr cb_ = nullptr; +}; + +class MediaCodecDecoderAdapterImpl : public MediaCodecDecoderAdapter { +public: + MediaCodecDecoderAdapterImpl() = default; + + ~MediaCodecDecoderAdapterImpl() override = default; + + DecoderAdapterCode CreateVideoDecoderByMime(const std::string& mimetype) override; + + DecoderAdapterCode CreateVideoDecoderByName(const std::string& name) override; + + DecoderAdapterCode ConfigureDecoder(int32_t width, int32_t height, double framerate) override; + + DecoderAdapterCode SetParameterDecoder(const DecoderFormat& format) override; + + DecoderAdapterCode SetOutputSurface(void* window) override; + + DecoderAdapterCode PrepareDecoder() override; + + DecoderAdapterCode StartDecoder() override; + + DecoderAdapterCode StopDecoder() override; + + DecoderAdapterCode FlushDecoder() override; + + DecoderAdapterCode ResetDecoder() override; + + DecoderAdapterCode ReleaseDecoder() override; + + DecoderAdapterCode QueueInputBufferDec(uint32_t index, BufferInfo info, BufferFlag flag) override; + + DecoderAdapterCode GetOutputFormatDec(int32_t& width, int32_t& height) override; + + DecoderAdapterCode ReleaseOutputBufferDec(uint32_t index, bool isRender) override; + + DecoderAdapterCode SetCallbackDec(const std::shared_ptr& callback) override; + + static ErrorType GetErrorType(MediaAVCodec::AVCodecErrorType codecErrorType); + + static BufferFlag GetBufferFlag(MediaAVCodec::AVCodecBufferFlag codecBufferFlag); + + static MediaAVCodec::AVCodecBufferFlag GetAVBufferFlag(BufferFlag bufferFlag); + +private: + std::shared_ptr decoder_ = nullptr; + std::shared_ptr callback_ = nullptr; +}; + +} // namespace OHOS::NWeb +#endif \ No newline at end of file diff --git a/ohos_adapter/media_adapter/src/media_codec_decoder_adapter_impl.cpp b/ohos_adapter/media_adapter/src/media_codec_decoder_adapter_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d2ff734bd42984258ed18ba9c4a3a8407dcadcd2 --- /dev/null +++ b/ohos_adapter/media_adapter/src/media_codec_decoder_adapter_impl.cpp @@ -0,0 +1,404 @@ +/* + * 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. + */ + +#include "media_codec_decoder_adapter_impl.h" + +#include +#include +#include +#include +#include +#include + +#include "foundation/graphic/graphic_2d/interfaces/inner_api/surface/window.h" +#include "native_window.h" +#include "nweb_log.h" + +using namespace OHOS::NWeb; +using namespace std; +namespace { +const std::unordered_map ERROR_TYPE_MAP = { + { OHOS::MediaAVCodec::AVCodecErrorType::AVCODEC_ERROR_INTERNAL, ErrorType::CODEC_ERROR_INTERNAL }, + { OHOS::MediaAVCodec::AVCodecErrorType::AVCODEC_ERROR_EXTEND_START, ErrorType::CODEC_ERROR_EXTEND_START } +}; + +const std::unordered_map BUFFER_FLAG_MAP = { + { OHOS::MediaAVCodec::AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_NONE, BufferFlag::CODEC_BUFFER_FLAG_NONE }, + { OHOS::MediaAVCodec::AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_EOS, BufferFlag::CODEC_BUFFER_FLAG_EOS }, + { OHOS::MediaAVCodec::AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_SYNC_FRAME, BufferFlag::CODEC_BUFFER_FLAG_SYNC_FRAME }, + { OHOS::MediaAVCodec::AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_PARTIAL_FRAME, + BufferFlag::CODEC_BUFFER_FLAG_PARTIAL_FRAME }, + { OHOS::MediaAVCodec::AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_CODEC_DATA, BufferFlag::CODEC_BUFFER_FLAG_CODEC_DATA } +}; + +const std::unordered_map AV_BUFFER_FLAG_MAP = { + { BufferFlag::CODEC_BUFFER_FLAG_NONE, OHOS::MediaAVCodec::AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_NONE }, + { BufferFlag::CODEC_BUFFER_FLAG_EOS, OHOS::MediaAVCodec::AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_EOS }, + { BufferFlag::CODEC_BUFFER_FLAG_SYNC_FRAME, OHOS::MediaAVCodec::AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_SYNC_FRAME }, + { BufferFlag::CODEC_BUFFER_FLAG_PARTIAL_FRAME, + OHOS::MediaAVCodec::AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_PARTIAL_FRAME }, + { BufferFlag::CODEC_BUFFER_FLAG_CODEC_DATA, OHOS::MediaAVCodec::AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_CODEC_DATA } +}; +} // namespace + +void DecoderFormatImpl::SetFormatWidth(int32_t width) +{ + width_ = width; +} + +void DecoderFormatImpl::SetFormatHeight(int32_t height) +{ + height_ = height; +} + +DecoderCallbackImpl::DecoderCallbackImpl(std::shared_ptr cb) : cb_(cb) {}; + +DecoderAdapterCode MediaCodecDecoderAdapterImpl::CreateVideoDecoderByMime(const std::string& mimetype) +{ + decoder_ = VideoDecoderFactory::CreateByMime(mimetype); + if (decoder_ == nullptr) { + WVLOG_E("MediaCodecDecoder create failed."); + return DecoderAdapterCode::DECODER_ERROR; + } + + return DecoderAdapterCode::DECODER_OK; +} + +DecoderAdapterCode MediaCodecDecoderAdapterImpl::CreateVideoDecoderByName(const std::string& name) +{ + decoder_ = VideoDecoderFactory::CreateByName(name); + if (decoder_ == nullptr) { + WVLOG_E("MediaCodecDecoder create failed."); + return DecoderAdapterCode::DECODER_ERROR; + } + + return DecoderAdapterCode::DECODER_OK; +} + +DecoderAdapterCode MediaCodecDecoderAdapterImpl::ConfigureDecoder(int32_t width, int32_t height, double framerate) +{ + if (decoder_ == nullptr) { + WVLOG_E("MediaCodecDecoder is nullptr."); + return DecoderAdapterCode::DECODER_ERROR; + } + + OHOS::MediaAVCodec::Format format; + + format.PutIntValue(OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_WIDTH, width); + format.PutIntValue(OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_HEIGHT, height); + format.PutDoubleValue(OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_FRAME_RATE, framerate); + + int32_t ret = decoder_->Configure(format); + if (ret != 0) { + return DecoderAdapterCode::DECODER_ERROR; + } + return DecoderAdapterCode::DECODER_OK; +} + +DecoderAdapterCode MediaCodecDecoderAdapterImpl::SetParameterDecoder(const DecoderFormat& format) +{ + if (decoder_ == nullptr) { + WVLOG_E("MediaCodecDecoder is nullptr."); + return DecoderAdapterCode::DECODER_ERROR; + } + + OHOS::MediaAVCodec::Format format_; + + format_.PutIntValue(OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_WIDTH, format.width_); + format_.PutIntValue(OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_HEIGHT, format.height_); + + int32_t ret = decoder_->SetParameter(format_); + if (ret != 0) { + return DecoderAdapterCode::DECODER_ERROR; + } + return DecoderAdapterCode::DECODER_OK; +} + +DecoderAdapterCode MediaCodecDecoderAdapterImpl::SetOutputSurface(void* window) +{ + if (decoder_ == nullptr) { + WVLOG_E("MediaCodecDecoder is nullptr."); + return DecoderAdapterCode::DECODER_ERROR; + } + + if (window == nullptr) { + WVLOG_E("Window is nullptr."); + return DecoderAdapterCode::DECODER_ERROR; + } + + OHNativeWindow* window_ = reinterpret_cast(window); + + int32_t ret = decoder_->SetOutputSurface(window_->surface); + if (ret != 0) { + return DecoderAdapterCode::DECODER_ERROR; + } + return DecoderAdapterCode::DECODER_OK; +} + +DecoderAdapterCode MediaCodecDecoderAdapterImpl::PrepareDecoder() +{ + if (decoder_ == nullptr) { + WVLOG_E("MediaCodecDecoder is nullptr."); + return DecoderAdapterCode::DECODER_ERROR; + } + + int32_t ret = decoder_->Prepare(); + if (ret != 0) { + return DecoderAdapterCode::DECODER_ERROR; + } + return DecoderAdapterCode::DECODER_OK; +} + +DecoderAdapterCode MediaCodecDecoderAdapterImpl::StartDecoder() +{ + if (decoder_ == nullptr) { + WVLOG_E("MediaCodecDecoder is nullptr."); + return DecoderAdapterCode::DECODER_ERROR; + } + int32_t ret = decoder_->Start(); + if (ret != 0) { + return DecoderAdapterCode::DECODER_ERROR; + } + return DecoderAdapterCode::DECODER_OK; +} + +DecoderAdapterCode MediaCodecDecoderAdapterImpl::StopDecoder() +{ + if (decoder_ == nullptr) { + WVLOG_E("MediaCodecDecoder is nullptr."); + return DecoderAdapterCode::DECODER_ERROR; + } + int32_t ret = decoder_->Stop(); + if (ret != 0) { + return DecoderAdapterCode::DECODER_ERROR; + } + return DecoderAdapterCode::DECODER_OK; +} + +DecoderAdapterCode MediaCodecDecoderAdapterImpl::FlushDecoder() +{ + if (decoder_ == nullptr) { + WVLOG_E("MediaCodecDecoder is nullptr."); + return DecoderAdapterCode::DECODER_ERROR; + } + int32_t ret = decoder_->Flush(); + if (ret != 0) { + return DecoderAdapterCode::DECODER_ERROR; + } + return DecoderAdapterCode::DECODER_OK; +} + +DecoderAdapterCode MediaCodecDecoderAdapterImpl::ResetDecoder() +{ + if (decoder_ == nullptr) { + WVLOG_E("MediaCodecDecoder is nullptr."); + return DecoderAdapterCode::DECODER_ERROR; + } + int32_t ret = decoder_->Reset(); + if (ret != 0) { + return DecoderAdapterCode::DECODER_ERROR; + } + return DecoderAdapterCode::DECODER_OK; +} + +DecoderAdapterCode MediaCodecDecoderAdapterImpl::ReleaseDecoder() +{ + if (decoder_ == nullptr) { + WVLOG_E("MediaCodecDecoder is nullptr."); + return DecoderAdapterCode::DECODER_ERROR; + } + int32_t ret = decoder_->Release(); + if (ret != 0) { + return DecoderAdapterCode::DECODER_ERROR; + } + return DecoderAdapterCode::DECODER_OK; +} + +DecoderAdapterCode MediaCodecDecoderAdapterImpl::QueueInputBufferDec(uint32_t index, BufferInfo info, BufferFlag flag) +{ + struct OHOS::MediaAVCodec::AVCodecBufferInfo bufferInfo; + + bufferInfo.presentationTimeUs = info.presentationTimeUs; + bufferInfo.size = info.size; + bufferInfo.offset = info.offset; + + AVCodecBufferFlag bufferFlag = MediaCodecDecoderAdapterImpl::GetAVBufferFlag(flag); + + if (decoder_ == nullptr) { + WVLOG_E("MediaCodecDecoder is nullptr."); + return DecoderAdapterCode::DECODER_ERROR; + } + + int32_t ret = decoder_->QueueInputBuffer(index, bufferInfo, bufferFlag); + if (ret != 0) { + return DecoderAdapterCode::DECODER_ERROR; + } + return DecoderAdapterCode::DECODER_OK; +} + +DecoderAdapterCode MediaCodecDecoderAdapterImpl::GetOutputFormatDec(int32_t& width, int32_t& height) +{ + OHOS::MediaAVCodec::Format format; + + if (decoder_ == nullptr) { + WVLOG_E("MediaCodecDecoder is nullptr."); + return DecoderAdapterCode::DECODER_ERROR; + } + + int32_t ret = decoder_->GetOutputFormat(format); + if (ret != 0) { + return DecoderAdapterCode::DECODER_ERROR; + } + + format.GetIntValue(OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_WIDTH, width); + format.GetIntValue(OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_HEIGHT, height); + + return DecoderAdapterCode::DECODER_OK; +} + +DecoderAdapterCode MediaCodecDecoderAdapterImpl::ReleaseOutputBufferDec(uint32_t index, bool isRender) +{ + if (decoder_ == nullptr) { + WVLOG_E("MediaCodecDecoder is nullptr."); + return DecoderAdapterCode::DECODER_ERROR; + } + + int32_t ret = decoder_->ReleaseOutputBuffer(index, isRender); + if (ret != 0) { + return DecoderAdapterCode::DECODER_ERROR; + } + return DecoderAdapterCode::DECODER_OK; +} + +DecoderAdapterCode MediaCodecDecoderAdapterImpl::SetCallbackDec(const std::shared_ptr& callback) +{ + if (callback == nullptr) { + WVLOG_E("Media Callback is NULL."); + return DecoderAdapterCode::DECODER_ERROR; + } + + callback_ = std::make_shared(callback); + if (callback_ == nullptr) { + WVLOG_E("Create Callback failed."); + return DecoderAdapterCode::DECODER_ERROR; + } + + if (decoder_ == nullptr) { + WVLOG_E("MediaCodecDecoder is nullptr."); + return DecoderAdapterCode::DECODER_ERROR; + } + + int32_t ret = decoder_->SetCallback(callback_); + if (ret != 0) { + return DecoderAdapterCode::DECODER_ERROR; + } + return DecoderAdapterCode::DECODER_OK; +} + +ErrorType MediaCodecDecoderAdapterImpl::GetErrorType(AVCodecErrorType codecErrorType) +{ + auto type = ERROR_TYPE_MAP.find(codecErrorType); + if (type == ERROR_TYPE_MAP.end()) { + WVLOG_E("error type not found."); + return ErrorType::CODEC_ERROR_INTERNAL; + } + return type->second; +} + +BufferFlag MediaCodecDecoderAdapterImpl::GetBufferFlag(AVCodecBufferFlag codecBufferFlag) +{ + auto flag = BUFFER_FLAG_MAP.find(codecBufferFlag); + if (flag == BUFFER_FLAG_MAP.end()) { + WVLOG_E("buffer flag not found."); + return BufferFlag::CODEC_BUFFER_FLAG_NONE; + } + return flag->second; +} + +AVCodecBufferFlag MediaCodecDecoderAdapterImpl::GetAVBufferFlag(BufferFlag bufferFlag) +{ + auto flag = AV_BUFFER_FLAG_MAP.find(bufferFlag); + if (flag == AV_BUFFER_FLAG_MAP.end()) { + WVLOG_E("buffer flag not found."); + return AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_NONE; + } + return flag->second; +} + +void DecoderCallbackImpl::OnError(AVCodecErrorType errorType, int32_t errorCode) +{ + if (!cb_) { + WVLOG_E("callback is NULL."); + return; + } + + ErrorType errType = MediaCodecDecoderAdapterImpl::GetErrorType(errorType); + + cb_->OnError(errType, errorCode); +} + +void DecoderCallbackImpl::OnOutputFormatChanged(const Format& format) +{ + if (!cb_) { + WVLOG_E("callback is NULL."); + return; + } + + int32_t width; + format.GetIntValue(OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_WIDTH, width); + int32_t height; + format.GetIntValue(OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_HEIGHT, height); + + DecoderFormatImpl decoderFormat(width, height); + + cb_->OnStreamChanged(decoderFormat); +} + +void DecoderCallbackImpl::OnInputBufferAvailable(uint32_t index, std::shared_ptr buffer) +{ + if (!cb_) { + WVLOG_E("callback is NULL."); + return; + } + + OhosBuffer ohosBuffer_; + ohosBuffer_.addr = buffer->GetBase(); + ohosBuffer_.bufferSize = buffer->GetSize(); + if (ohosBuffer_.addr == nullptr) { + WVLOG_E("Get buffer failed."); + return; + } + + cb_->OnNeedInputData(index, ohosBuffer_); +} + +void DecoderCallbackImpl::OnOutputBufferAvailable( + uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag, std::shared_ptr buffer) +{ + if (!cb_) { + WVLOG_E("callback is NULL."); + return; + } + + BufferInfo info_; + info_.presentationTimeUs = info.presentationTimeUs; + info_.size = info.size; + info_.offset = info.offset; + + BufferFlag flag_; + + flag_ = MediaCodecDecoderAdapterImpl::GetBufferFlag(flag); + cb_->OnNeedOutputData(index, info_, flag_); +} \ No newline at end of file