From ec93fc2a642172d066881953c41d93dc0152656f Mon Sep 17 00:00:00 2001 From: w30042960 Date: Mon, 30 Dec 2024 16:56:41 +0800 Subject: [PATCH 1/2] Add outputFilter Signed-off-by: w30042960 --- .../daudio_output_filter.cpp | 314 ++++++++++++++ .../daudio_output_filter.h | 90 ++++ .../dsoftbus_output_audio_filter.cpp | 393 ++++++++++++++++++ .../dsoftbus_output_audio_filter.h | 94 +++++ 4 files changed, 891 insertions(+) create mode 100644 av_transport/av_trans_engine/filters/daudio_output_filter/daudio_output_filter.cpp create mode 100644 av_transport/av_trans_engine/filters/daudio_output_filter/daudio_output_filter.h create mode 100644 av_transport/av_trans_engine/filters/dsoftbus_output_audio_filter/dsoftbus_output_audio_filter.cpp create mode 100644 av_transport/av_trans_engine/filters/dsoftbus_output_audio_filter/dsoftbus_output_audio_filter.h diff --git a/av_transport/av_trans_engine/filters/daudio_output_filter/daudio_output_filter.cpp b/av_transport/av_trans_engine/filters/daudio_output_filter/daudio_output_filter.cpp new file mode 100644 index 00000000..bb84c82c --- /dev/null +++ b/av_transport/av_trans_engine/filters/daudio_output_filter/daudio_output_filter.cpp @@ -0,0 +1,314 @@ +/* + * Copyright (c) 2024 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 "daudio_output_filter.h" + +#include + +#include "av_trans_log.h" +#include "filter_factory.h" + +#include "cJSON.h" +#include "av_trans_errno.h" +#include "av_trans_log.h" +#include "av_trans_constants.h" + +#undef DH_LOG_TAG +#define DH_LOG_TAG "DAudioOutputFilter" + +namespace OHOS { +namespace DistributedHardware { +namespace Pipeline { +constexpr int32_t DEFAULT_BUFFER_NUM = 8; +const std::string OUTPUT_BUFFER_QUEUE_NAME = "AVTransAudioOutputBufferQueue"; + +static AutoRegisterFilter g_registerAudioEncoderFilter("builtin.daudio.output", + FilterType::FILTERTYPE_ASINK, + [](const std::string& name, const FilterType type) { + return std::make_shared(name, FilterType::FILTERTYPE_SINK); + }); + +class DAudioOutoutFilterLinkCallback : public FilterLinkCallback { +public: + explicit DAudioOutoutFilterLinkCallback(std::shared_ptr filter) + : outFilter_(std::move(filter)) {} + ~DAudioOutoutFilterLinkCallback() = default; + + void OnLinkedResult(const sptr &queue, std::shared_ptr &meta) override + { + if (auto filter = outFilter_.lock()) { + filter->OnLinkedResult(queue, meta); + } else { + AVTRANS_LOGI("invalid dAudioOutputFilter"); + } + } + + void OnUnlinkedResult(std::shared_ptr &meta) override + { + if (auto filter = outFilter_.lock()) { + filter->OnUnlinkedResult(meta); + } else { + AVTRANS_LOGI("invalid dAudioOutputFilter"); + } + } + + void OnUpdatedResult(std::shared_ptr &meta) override + { + if (auto filter = outFilter_.lock()) { + filter->OnUpdatedResult(meta); + } else { + AVTRANS_LOGI("invalid dAudioOutputFilter"); + } + } + +private: + std::weak_ptr outFilter_ {}; +}; + +class AVBufferAvailableListener : public Media::IConsumerListener { +public: + AVBufferAvailableListener(std::weak_ptr outputFilter) + { + outputFilter_ = outputFilter; + } + + void OnBufferAvailable() override + { + auto outputFilter = outputFilter_.lock(); + if (outputFilter != nullptr) { + outputFilter->ProcessInputBuffer(); + } + } + +private: + std::weak_ptr outputFilter_; +}; + +DAudioOutputFilter::DAudioOutputFilter(std::string name, FilterType type) + : Filter(name, type) +{ + +} + +DAudioOutputFilter::~DAudioOutputFilter() +{ + nextFiltersMap_.clear(); +} + +void DAudioOutputFilter::Init(const std::shared_ptr& receiver, const std::shared_ptr& callback) +{ + eventReceiver_ = receiver; + filterCallback_ = callback; +} + +Status DAudioOutputFilter::DoInitAfterLink() +{ + return Status::OK; +} + +void DAudioOutputFilter::PrepareInputBuffer() +{ + AVTRANS_LOGI("Preparing input buffer."); + int32_t outputBufNum = DEFAULT_BUFFER_NUM; + Media::MemoryType memoryType = Media::MemoryType::VIRTUAL_MEMORY; + if (outputBufQue_ == nullptr) { + outputBufQue_ = Media::AVBufferQueue::Create(outputBufNum, memoryType, OUTPUT_BUFFER_QUEUE_NAME); + } + if (outputBufQue_ == nullptr) { + AVTRANS_LOGE("Create buffer queue failed."); + return; + } + inputBufQueProducer_ = outputBufQue_->GetProducer(); + TRUE_RETURN((inputBufQueProducer_ == nullptr), "Get producer failed"); + + inputBufQueConsumer_ = outputBufQue_->GetConsumer(); + TRUE_RETURN((inputBufQueConsumer_ == nullptr), "Get consumer failed"); + + sptr listener(new AVBufferAvailableListener(shared_from_this())); + inputBufQueConsumer_->SetBufferAvailableListener(listener); +} + +Status DAudioOutputFilter::DoPrepare() +{ + PrepareInputBuffer(); + int32_t inputBufNum = DEFAULT_BUFFER_NUM; + sptr producer = nullptr; + Media::MemoryType memoryType = Media::MemoryType::UNKNOWN_MEMORY; + if (outputBufQue_ == nullptr) { + outputBufQue_ = Media::AVBufferQueue::Create(inputBufNum, memoryType, OUTPUT_BUFFER_QUEUE_NAME); + } + if (outputBufQue_ == nullptr) { + AVTRANS_LOGE("Create buffer queue failed."); + return; + } + producer = outputBufQue_->GetProducer(); + TRUE_RETURN_V_MSG_E((producer == nullptr), Status::ERROR_NULL_POINTER, "Get producer failed"); + sptr consumer = outputBufQue_->GetConsumer(); + sptr lister(new AVBufferAvailableListener(shared_from_this())); + consumer->SetBufferAvailableListener(listener); + + std::shared_ptr meta = std::make_shared() + if (onLinkedResultCallback_ != nullptr) { + onLinkedResultCallback_->OnLinkedResult(producer, meta); + } + return Status::OK; +} + +Status DAudioOutputFilter::DoStart() +{ + AVTRANS_LOGI("Do Start"); + return Status::OK; +} + +Status DAudioOutputFilter::DoPause() +{ + return Status::OK; +} + +Status DAudioOutputFilter::DoPauseDragging() +{ + return Status::OK; +} + +Status DAudioOutputFilter::DoResume() +{ + return Status::OK; +} + +Status DAudioOutputFilter::DoResumeDragging() +{ + return Status::OK; +} + +Status DAudioOutputFilter::DoStop() +{ + return Status::OK; +} + +Status DAudioOutputFilter::DoFlush() +{ + return Status::OK; +} + +Status DAudioOutputFilter::DoRelease() +{ + return Status::OK; +} + +Status DAudioOutputFilter::DoProcessInputBuffer(int recvArg, bool dropFrame) +{ + (void)recvArg; + (void)dropFrame; + std::shared_ptr filledBuffer = nullptr; + Media::Status ret = inputBufQueConsumer_->AcquireBuffer(filledBuffer); + if (ret != Media::Status::OK) { + AVTRANS_LOGE("Acquire buffer err: %{public}d.", ret); + return Status::ERROR_INVALID_OPERATION; + } + ProcessAndSendBuffer(filledBuffer); + inputBufQueConsumer_->ReleaseBuffer(filledBuffer); + return Status::OK; +} + +Status DAudioOutputFilter::DoProcessOutputBuffer(int recvArg, bool dropFrame, bool byIdx, + uint32_t idx, int64_t renderTimee) +{ + return Status::OK; +} + +Status DAudioOutputFilter::ProcessAndSendBuffer(const std::shared_ptr buffer) +{ + //拿到buffer数据 todo 传递数据到接收引擎 + if (buffer == nullptr) { + AVTRANS_LOGE("ProcessAndSendBuffer buffer is nullptr"); + return Status::ERROR_INVALID_OPERATION; + } + AVTRANS_LOGI("ProcessAndSendBuffer buffer is ok"); + return Status::OK; +} + +void DAudioOutputFilter::SetParameter(const std::shared_ptr& meta) +{ + meta_ = meta; +} + +void DAudioOutputFilter::GetParameter(std::shared_ptr& meta) +{ + meta = meta_; +} + +Status DAudioOutputFilter::LinkNext(const std::shared_ptr& nextFilter, StreamType outType) +{ + nextFilter_ = nextFilter; + nextFiltersMap_[outType].push_back(nextFilter_); + auto filterLinkCallback = std::make_shared(shared_from_this()); + auto ret = nextFilter->OnLinked(outType, meta_, filterLinkCallback); + if (ret != Status::OK) { + AVTRANS_LOGE("Onlinked failed, status: %{public}d.", ret); + return ret; + } + return Status::OK; +} + +Status DAudioOutputFilter::UpdateNext(const std::shared_ptr&, StreamType) +{ + return Status::OK; +} + +Status DAudioOutputFilter::UnLinkNext(const std::shared_ptr&, StreamType) +{ + AVTRANS_LOGI("cur: DAudioOutputFilter, unlink next filter.."); + return Status::OK; +} + +Status DAudioOutputFilter::OnLinked(StreamType inType, const std::shared_ptr &meta, + const std::shared_ptr &callback) +{ + AVTRANS_LOGI("cur: DAudioOutputFilter, OnLinked"); + onLinkedResultCallback_ = callback; + SetParameter(meta); + return Status::OK; +}; + +Status DAudioOutputFilter::OnUpdated(StreamType, const std::shared_ptr&, + const std::shared_ptr&) +{ + return Status::OK; +} + +Status DAudioOutputFilter::OnUnLinked(StreamType, const std::shared_ptr&) +{ + AVTRANS_LOGI("cur: DAudioOutputFilter, OnUnLinked."); + return Status::OK; +} + +void DAudioOutputFilter::OnLinkedResult(const sptr& queue, + std::shared_ptr& meta) +{ + outputBufQueProducer_ = queue; +} + +void DAudioOutputFilter::OnUnlinkedResult(std::shared_ptr& meta) +{ + +} + +void DAudioOutputFilter::OnUpdatedResult(std::shared_ptr& meta) +{ + +} +} // namespace Pipeline +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/av_transport/av_trans_engine/filters/daudio_output_filter/daudio_output_filter.h b/av_transport/av_trans_engine/filters/daudio_output_filter/daudio_output_filter.h new file mode 100644 index 00000000..0fef8062 --- /dev/null +++ b/av_transport/av_trans_engine/filters/daudio_output_filter/daudio_output_filter.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2024 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 OHOS_DAUDIO_OUTPUT_FILTER_H +#define OHOS_DAUDIO_OUTPUT_FILTER_H + +#include +#include +#include + +#include "buffer/avbuffer_queue.h" +#include "buffer/avbuffer_queue_consumer.h" +#include "buffer/avbuffer_queue_producer.h" +#include "softbus_channel_adapter.h" + +#include "pipeline_status.h" +#include "filter.h" + +namespace OHOS { +namespace DistributedHardware { +namespace Pipeline { +class DAudioOutputFilter : public Filter, public std::enable_shared_from_this { +public: + DAudioOutputFilter(std::string name, FilterType type); + virtual ~DAudioOutputFilter(); + + void Init(const std::shared_ptr& receiver, const std::shared_ptr& callback) override; + Status DoInitAfterLink() override; + Status DoPrepare() override; + Status DoStart() override; + Status DoPause() override; + Status DoPauseDragging() override; + Status DoResume() override; + Status DoResumeDragging() override; + Status DoStop() override; + Status DoFlush() override; + Status DoRelease() override; + + Status DoProcessInputBuffer(int recvArg, bool dropFrame) override; + Status DoProcessOutputBuffer(int recvArg, bool dropFrame, bool byIdx, uint32_t idx, int64_t renderTime) override; + void SetParameter(const std::shared_ptr& meta) override; + void GetParameter(std::shared_ptr& meta) override; + + Status LinkNext(const std::shared_ptr& nextFilter, StreamType outType) override; + Status UpdateNext(const std::shared_ptr& nextFilter, StreamType outType) override; + Status UnLinkNext(const std::shared_ptr& nextFilter, StreamType outType) override; + + Status OnLinked(StreamType inType, const std::shared_ptr& meta, + const std::shared_ptr& callback) override; + Status OnUpdated(StreamType inType, const std::shared_ptr& meta, + const std::shared_ptr& callback) override; + Status OnUnLinked(StreamType inType, const std::shared_ptr& callback) override; + + // PipeLinked 后处理 + void OnLinkedResult(const sptr& queue, std::shared_ptr& meta); + void OnUnlinkedResult(std::shared_ptr& meta); + void OnUpdatedResult(std::shared_ptr& meta); + +private: + void PrepareInputBuffer(); + Status ProcessAndSendBuffer(const std::shared_ptr buffer); + +private: + std::shared_ptr meta_ {nullptr}; + std::shared_ptr nextFilter_ {nullptr}; + std::shared_ptr eventReceiver_ {nullptr}; + std::shared_ptr filterCallback_ {nullptr}; + std::shared_ptr onLinkedResultCallback_ {nullptr}; + + std::shared_ptr outputBufQue_ {nullptr}; + sptr inputBufQueProducer_ {nullptr}; + sptr inputBufQueConsumer_ {nullptr}; + sptr outputBufQueProducer_ {nullptr}; +}; +} // namespace Pipeline +} // namespace DistributedHardware +} // namespace OHOS +#endif //OHOS_DAUDIO_OUTPUT_FILTER_H diff --git a/av_transport/av_trans_engine/filters/dsoftbus_output_audio_filter/dsoftbus_output_audio_filter.cpp b/av_transport/av_trans_engine/filters/dsoftbus_output_audio_filter/dsoftbus_output_audio_filter.cpp new file mode 100644 index 00000000..18f5b0d4 --- /dev/null +++ b/av_transport/av_trans_engine/filters/dsoftbus_output_audio_filter/dsoftbus_output_audio_filter.cpp @@ -0,0 +1,393 @@ +/* + * Copyright (c) 2024 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 "dsoftbus_output_audio_filter.h" + +#include + +#include "av_trans_log.h" +#include "filter_factory.h" +#include "cJSON.h" +#include "av_trans_errno.h" +#include "av_trans_log.h" +#include "av_trans_constants.h" + +#undef DH_LOG_TAG +#define DH_LOG_TAG "DSoftbusOutputFilter" + +namespace OHOS { +namespace DistributedHardware { +namespace Pipeline { +constexpr int32_t DEFAULT_BUFFER_NUM = 8; +const uint32_t DEFAULT_FRAME_NUMBER = 100; +const std::string META_DATA_TYPE = "meta_data_type"; +const std::string META_TIMESTAMP = "meta_timestamp"; +const std::string META_FRAME_NUMBER = "meta_frame_number"; +const std::string META_EXT_TIMESTAMP = "meta_ext_timestamp"; +const std::string META_EXT_FRAME_NUMBER = "meta_ext_frame_number"; +const std::string INPUT_BUFFER_QUEUE_NAME = "buffer_queue_input"; +const std::string SENDER_DATA_SESSION_NAME_SUFFIX = "sender.avtrans.data"; +const std::string RECEIVER_DATA_SESSION_NAME_SUFFIX = "receiver.avtrans.data"; +const std::string OUTPUT_BUFFER_QUEUE_NAME = "AVTransAudioOutputBufferQueue"; + +static AutoRegisterFilter g_registerAudioEncoderFilter("builtin.avtransport.avoutput", + FilterType::FILTERTYPE_ASINK, + [](const std::string& name, const FilterType type) { + return std::make_shared(name, FilterType::FILTERTYPE_ASINK); + }); + +class DAudioSoftbusFilterLinkCallback : public FilterLinkCallback { +public: + explicit DAudioSoftbusFilterLinkCallback(std::shared_ptr filter) + : outFilter_(std::move(filter)) {} + ~DAudioSoftbusFilterLinkCallback() = default; + + void OnLinkedResult(const sptr &queue, std::shared_ptr &meta) override + { + if (auto filter = outFilter_.lock()) { + filter->OnLinkedResult(queue, meta); + } else { + AVTRANS_LOGI("invalid DSoftbusOutputFilter"); + } + } + + void OnUnlinkedResult(std::shared_ptr &meta) override + { + if (auto filter = outFilter_.lock()) { + filter->OnUnlinkedResult(meta); + } else { + AVTRANS_LOGI("invalid DSoftbusOutputFilter"); + } + } + + void OnUpdatedResult(std::shared_ptr &meta) override + { + if (auto filter = outFilter_.lock()) { + filter->OnUpdatedResult(meta); + } else { + AVTRANS_LOGI("invalid daudioSoftbusOutputFilter"); + } + } + +private: + std::weak_ptr outFilter_ {}; +}; + +class AVBufferAvailableListener : public Media::IConsumerListener { +public: + AVBufferAvailableListener(std::weak_ptr dsoftbusFilter) + { + dsoftbusFilter_ = dsoftbusFilter; + } + + void OnBufferAvailable() override + { + auto dsoftbusFilter = dsoftbusFilter_.lock(); + if (dsoftbusFilter != nullptr) { + dsoftbusFilter->ProcessInputBuffer(); + } + } + +private: + std::weak_ptr dsoftbusFilter_; +}; + +DSoftbusOutputFilter::DSoftbusOutputFilter(std::string name, FilterType type) + : Filter(name, type) +{ + +} + +DSoftbusOutputFilter::~DSoftbusOutputFilter() +{ + nextFiltersMap_.clear(); +} + +void DSoftbusOutputFilter::Init(const std::shared_ptr& receiver, const std::shared_ptr& callback) +{ + eventReceiver_ = receiver; + filterCallback_ = callback; +} + +Status DSoftbusOutputFilter::DoInitAfterLink() +{ + return Status::OK; +} + +void DSoftbusOutputFilter::PrepareInputBuffer() +{ + AVTRANS_LOGI("Preparing input buffer."); + int32_t outputBufNum = DEFAULT_BUFFER_NUM; + Media::MemoryType memoryType = Media::MemoryType::VIRTUAL_MEMORY; + if (outputBufQue_ == nullptr) { + outputBufQue_ = Media::AVBufferQueue::Create(outputBufNum, memoryType, OUTPUT_BUFFER_QUEUE_NAME); + } + if (outputBufQue_ == nullptr) { + AVTRANS_LOGE("Create buffer queue failed."); + return; + } + inputBufQueProducer_ = outputBufQue_->GetProducer(); + TRUE_RETURN((inputBufQueProducer_ == nullptr), "Get producer failed"); + + inputBufQueConsumer_ = outputBufQue_->GetConsumer(); + TRUE_RETURN((inputBufQueConsumer_ == nullptr), "Get consumer failed"); + + sptr listener(new AVBufferAvailableListener(shared_from_this())); + inputBufQueConsumer_->SetBufferAvailableListener(listener); +} + +Status DSoftbusOutputFilter::DoPrepare() +{ + std::string str; + if (meta_ != nullptr) { + meta_->GetData(Media::Tag::MEDIA_DESCRIPTION, str); + } + cJSON *jParam = cJSON_Parse(str.c_str()); + if (jParam == nullptr) { + AVTRANS_LOGE("Failed to parse json."); + return Status::ERROR_NULL_POINTER; + } + cJSON *ownerName = cJSON_GetObjectItem(jParam, "ownerName"); + if (ownerName == nullptr || !cJSON_IsString(ownerName)) { + AVTRANS_LOGE("The key ownerName is null."); + cJSON_Delete(jParam); + return Status::ERROR_NULL_POINTER; + } + AVTRANS_LOGI("RegData type is : %{public}s.", ownerName->valuestring); + ownerName_ = std::string(ownerName->valuestring); + + cJSON *peerDevId = cJSON_GetObjectItem(jParam, "peerDevId"); + if (peerDevId == nullptr || !cJSON_IsString(peerDevId)) { + AVTRANS_LOGE("The key peerDevId is null."); + cJSON_Delete(jParam); + return Status::ERROR_NULL_POINTER; + } + AVTRANS_LOGI("RegData type is : %{public}s.", peerDevId->valuestring); + peerDevId_ = std::string(peerDevId->valuestring); + sessionName_ = ownerName_ + "_" + SENDER_DATA_SESSION_NAME_SUFFIX; + PrepareInputBuffer(); + AVTRAN_LOGI("OnLinkedResult."); + + + int32_t inputBufNum = DEFAULT_BUFFER_NUM; + sptr producer = nullptr; + Media::MemoryType memoryType = Media::MemoryType::UNKNOWN_MEMORY; + if (outputBufQue_ == nullptr) { + outputBufQue_ = Media::AVBufferQueue::Create(inputBufNum, memoryType, OUTPUT_BUFFER_QUEUE_NAME); + } + if (outputBufQue_ == nullptr) { + AVTRANS_LOGE("Create buffer queue failed."); + return Status::ERROR_NULL_POINTER; + } + producer = outputBufQue_->GetProducer(); + TRUE_RETURN_V_MSG_E((producer == nullptr), Status::ERROR_NULL_POINTER, "Get producer failed"); + sptr consumer = outputBufQue_->GetConsumer(); + sptr lister(new AVBufferAvailableListener(shared_from_this())); + consumer->SetBufferAvailableListener(listener); + + std::shared_ptr meta = std::make_shared() + if (onLinkedResultCallback_ != nullptr) { + onLinkedResultCallback_->OnLinkedResult(producer, meta); + } + return Status::OK; +} + +Status DSoftbusOutputFilter::DoStart() +{ + std::string peerSessName = ownerName_ + "_" + RECEIVER_DATA_SESSION_NAME_SUFFIX; + int32_t ret = SoftbusChannelAdapter::GetInstance().OpenSoftbusChannel(sessionName_, peerSessName, peerDevId_); + if ((ret != DH_AVT_SUCCESS) && (ret != ERR_DH_AVT_SESSION_HAS_OPENED)) { + AVTRANS_LOGE("Open softbus channel failed ret: %{public}d.", ret); + return Status::ERROR_INVALID_OPERATION; + } + return Status::OK; +} + +Status DSoftbusOutputFilter::DoPause() +{ + return Status::OK; +} + +Status DSoftbusOutputFilter::DoPauseDragging() +{ + return Status::OK; +} + +Status DSoftbusOutputFilter::DoResume() +{ + return Status::OK; +} + +Status DSoftbusOutputFilter::DoResumeDragging() +{ + return Status::OK; +} + +Status DSoftbusOutputFilter::DoStop() +{ + int32_t ret = SoftbusChannelAdapter::GetInstance().CloseSoftbusChannel(sessionName_, peerDevId_); + if (ret != DH_AVT_SUCCESS) { + AVTRANS_LOGE("Close softbus channel failed ret: %{public}d.", ret); + return Status::ERROR_NULL_POINTER; + } + return Status::OK; +} + +Status DSoftbusOutputFilter::DoFlush() +{ + return Status::OK; +} + +Status DSoftbusOutputFilter::DoRelease() +{ + return Status::OK; +} + +Status DSoftbusOutputFilter::DoProcessInputBuffer(int recvArg, bool dropFrame) +{ + /* + if (curState_ != FilterState::RUNNING) { + AVTRANS_LOGE("Current status is not running."); + return Status::ERROR_WRONG_STATE; + } + */ + (void)recvArg; + (void)dropFrame; + std::shared_ptr filledBuffer = nullptr; + Media::Status ret = inputBufQueConsumer_->AcquireBuffer(filledBuffer); + if (ret != Media::Status::OK) { + AVTRANS_LOGE("Acquire buffer err: %{public}d.", ret); + return Status::ERROR_INVALID_OPERATION; + } + ProcessAndSendBuffer(filledBuffer); + inputBufQueConsumer_->ReleaseBuffer(filledBuffer); + return Status::OK; +} + +Status DSoftbusOutputFilter::DoProcessOutputBuffer(int recvArg, bool dropFrame, bool byIdx, + uint32_t idx, int64_t renderTimee) +{ + return Status::OK; +} + +Status DSoftbusOutputFilter::ProcessAndSendBuffer(const std::shared_ptr buffer) +{ + + if (buffer == nullptr || buffer->memory_ == nullptr) { + AVTRANS_LOGE("AVBuffer is nullptr"); + return Status::ERROR_NULL_POINTER; + } + auto bufferData = buffer->memory_; + int64_t pts = 0; + buffer->meta_->GetData(Media::Tag::USER_FRAME_PTS, pts); + //uint32_t frameNum = 0; + //buffer->meta_->GetData(Media::Tag::USER_FRAME_NUMBER, frameNum); + cJSON *jsonObj = cJSON_CreateObject(); + if (jsonObj == nullptr) { + return Status::ERROR_NULL_POINTER; + } + cJSON_AddNumberToObject(jsonObj, META_DATA_TYPE.c_str(), 0); //audio + cJSON_AddNumberToObject(jsonObj, META_TIMESTAMP.c_str(), pts); + cJSON_AddNumberToObject(jsonObj, META_FRAME_NUMBER.c_str(), DEFAULT_FRAME_NUMBER); + char *str = cJSON_PrintUnformatted(jsonObj); + if (str == nullptr) { + cJSON_Delete(jsonObj); + return Status::ERROR_NULL_POINTER; + } + std::string jsonStr = std::string(str); + StreamData data = {reinterpret_cast(const_cast(bufferData->GetAddr())), + bufferData->GetSize()}; + StreamData ext = {const_cast(jsonStr.c_str()), jsonStr.length()}; + int32_t ret = SoftbusChannelAdapter::GetInstance().SendStreamData(sessionName_, peerDevId_, &data, &ext); + if (ret != DH_AVT_SUCCESS) { + AVTRANS_LOGE("Send data to softbus failed."); + } + cJSON_free(str); + cJSON_Delete(jsonObj); + return Status::OK; +} + +void DSoftbusOutputFilter::SetParameter(const std::shared_ptr& meta) +{ + meta_ = meta; +} + +void DSoftbusOutputFilter::GetParameter(std::shared_ptr& meta) +{ + meta = meta_; +} + +Status DSoftbusOutputFilter::LinkNext(const std::shared_ptr& nextFilter, StreamType outType) +{ + nextFilter_ = nextFilter; + nextFiltersMap_[outType].push_back(nextFilter_); + auto filterLinkCallback = std::make_shared(shared_from_this()); + auto ret = nextFilter->OnLinked(outType, meta_, filterLinkCallback); + if (ret != Status::OK) { + AVTRANS_LOGE("Onlinked failed, status: %{public}d.", ret); + return ret; + } + return Status::OK; +} + +Status DSoftbusOutputFilter::UpdateNext(const std::shared_ptr&, StreamType outType) +{ + return Status::OK; +} + +Status DSoftbusOutputFilter::UnLinkNext(const std::shared_ptr&, StreamType outType) +{ + AVTRANS_LOGI("cur: DSoftbusOutputFilter, unlink next filter.."); + return Status::OK; +} + +Status DSoftbusOutputFilter::OnLinked(StreamType inType, const std::shared_ptr &meta, + const std::shared_ptr &callback) +{ + AVTRANS_LOGI("DSoftbusOutputFilter, OnLinked"); + onLinkedResultCallback_ = callback; + return Status::OK; +}; + +Status DSoftbusOutputFilter::OnUpdated(StreamType inType, const std::shared_ptr& meta, + const std::shared_ptr& callback) +{ + AVTRANS_LOGI("DSoftbusOutputFilter, OnUpdated"); + return Status::OK; +} + +Status DSoftbusOutputFilter::OnUnLinked(StreamType, const std::shared_ptr& callback) +{ + return Status::OK; +} + +void DSoftbusOutputFilter::OnLinkedResult(const sptr& queue, + std::shared_ptr& meta) +{ + outputBufQueProducer_ = queue; +} + +void DSoftbusOutputFilter::OnUpdatedResult(std::shared_ptr& meta) +{ + +} + +void DSoftbusOutputFilter::OnUnlinkedResult(std::shared_ptr& meta) +{ + +} +} // namespace Pipeline +} // namespace DistributedHardware +} // namespace OHOS \ No newline at end of file diff --git a/av_transport/av_trans_engine/filters/dsoftbus_output_audio_filter/dsoftbus_output_audio_filter.h b/av_transport/av_trans_engine/filters/dsoftbus_output_audio_filter/dsoftbus_output_audio_filter.h new file mode 100644 index 00000000..7c69e703 --- /dev/null +++ b/av_transport/av_trans_engine/filters/dsoftbus_output_audio_filter/dsoftbus_output_audio_filter.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2024 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 OHOS_DSOFTFBUS_OUTPUT_AUDIO_FILTER_H +#define OHOS_DSOFTFBUS_OUTPUT_AUDIO_FILTER_H + +#include +#include +#include + +#include "buffer/avbuffer_queue.h" +#include "buffer/avbuffer_queue_consumer.h" +#include "buffer/avbuffer_queue_producer.h" +#include "softbus_channel_adapter.h" + +#include "pipeline_status.h" +#include "filter.h" + +namespace OHOS { +namespace DistributedHardware { +namespace Pipeline { +class DSoftbusOutputFilter : public Filter, public std::enable_shared_from_this { +public: + DSoftbusOutputFilter(std::string name, FilterType type); + virtual ~DSoftbusOutputFilter(); + + void Init(const std::shared_ptr& receiver, const std::shared_ptr& callback) override; + Status DoInitAfterLink() override; + Status DoPrepare() override; + Status DoStart() override; + Status DoPause() override; + Status DoPauseDragging() override; + Status DoResume() override; + Status DoResumeDragging() override; + Status DoStop() override; + Status DoFlush() override; + Status DoRelease() override; + + Status DoProcessInputBuffer(int recvArg, bool dropFrame) override; + Status DoProcessOutputBuffer(int recvArg, bool dropFrame, bool byIdx, uint32_t idx, int64_t renderTime) override; + + void SetParameter(const std::shared_ptr& meta) override; + void GetParameter(std::shared_ptr& meta) override; + + Status LinkNext(const std::shared_ptr& nextFilter, StreamType outType) override; + Status UpdateNext(const std::shared_ptr& nextFilter, StreamType outType) override; + Status UnLinkNext(const std::shared_ptr& nextFilter, StreamType outType) override; + + Status OnLinked(StreamType inType, const std::shared_ptr& meta, + const std::shared_ptr& callback) override; + Status OnUpdated(StreamType inType, const std::shared_ptr& meta, + const std::shared_ptr& callback) override; + Status OnUnLinked(StreamType inType, const std::shared_ptr& callback) override; + + // PipeLinked 后处理 + void OnLinkedResult(const sptr& queue, std::shared_ptr& meta); + void OnUnlinkedResult(std::shared_ptr& meta); + void OnUpdatedResult(std::shared_ptr& meta); + +private: + void PrepareInputBuffer(); + Status ProcessAndSendBuffer(const std::shared_ptr buffer); + std::shared_ptr meta_ {nullptr}; + std::shared_ptr nextFilter_ {nullptr}; + + std::shared_ptr eventReceiver_ {nullptr}; + std::shared_ptr filterCallback_ {nullptr}; + std::shared_ptr onLinkedResultCallback_ {nullptr}; + + std::shared_ptr outputBufQue_ {nullptr}; + sptr inputBufQueProducer_ {nullptr}; + sptr inputBufQueConsumer_ {nullptr}; + sptr outputBufQueProducer_ {nullptr}; + std::mutex paramsMapMutex_; + std::string ownerName_; + std::string sessionName_; + std::string peerDevId_; +}; +} // namespace Pipeline +} // namespace DistributedHardware +} // namespace OHOS +#endif //OHOS_DSODTFBUS_OUTPUT_AUDIO_FILTER_H -- Gitee From d366657ef5b470558eb42e306dcb34cf798c69ea Mon Sep 17 00:00:00 2001 From: w30042960 Date: Mon, 30 Dec 2024 21:40:04 +0800 Subject: [PATCH 2/2] senderengine Signed-off-by: w30042960 --- .../av_sender/include/av_sender_engine.h | 23 +- .../av_sender/src/av_sender_engine.cpp | 226 ++++++++++++------ 2 files changed, 173 insertions(+), 76 deletions(-) diff --git a/av_transport/av_trans_engine/av_sender/include/av_sender_engine.h b/av_transport/av_trans_engine/av_sender/include/av_sender_engine.h index 56f6ad8a..0093d155 100644 --- a/av_transport/av_trans_engine/av_sender/include/av_sender_engine.h +++ b/av_transport/av_trans_engine/av_sender/include/av_sender_engine.h @@ -28,8 +28,12 @@ #include "av_transport_output_filter.h" #include "distributed_hardware_fwk_kit.h" #include "event.h" +#include "filter.h" +#include "pipeline.h" #include "i_av_sender_engine.h" #include "softbus_channel_adapter.h" +#include "av_trans_audio_input_filter.h" +#include "dsoftbus_output_audio_filter.h" // follwing head files depends on histreamer #include "audio_encoder_filter.h" @@ -43,7 +47,6 @@ namespace DistributedHardware { class AVSenderEngine : public IAVSenderEngine, public ISoftbusChannelListener, - public OHOS::Media::Pipeline::EventReceiver, public std::enable_shared_from_this { public: AVSenderEngine(const std::string &ownerName, const std::string &peerDevId); @@ -72,6 +75,12 @@ public: // interfaces from OHOS::Media::Pipeline::EventReceiver void OnEvent(const OHOS::Media::Event &event) override; + Status Oncallback(std::shared_ptr filter, const FilterCallbackCommand cmd, + StreamType outType) + int32_t LinkAudioEncoderFilter(const std::shared_ptr& preFilter, StreamType type); + int32_t LinkAudioSinkFilter(const std::shared_ptr& preFilter, Stream type); + + Status Prepare(); private: int32_t InitPipeline(); @@ -116,6 +125,7 @@ private: std::string ownerName_; std::string sessionName_; std::string peerDevId_; + constexpr uint8_t TIME_OUT_MS = 50; std::mutex stateMutex_; std::atomic isInitialized_ = false; @@ -124,12 +134,15 @@ private: sptr ctlCenCallback_ = nullptr; std::shared_ptr dhFwkKit_ = nullptr; std::shared_ptr senderCallback_ = nullptr; - std::shared_ptr pipeline_ = nullptr; - - std::shared_ptr avInput_ = nullptr; - std::shared_ptr avOutput_ = nullptr; + std::shared_ptr pipeline_ = nullptr; std::shared_ptr audioEncoder_ = nullptr; std::shared_ptr videoEncoder_ = nullptr; + std::shared_ptr playEventReceiver_ = nullptr; + std::shared_ptr playFilterCallback_ = nullptr; + std::string demoId_ = ""; + std::shared_ptr avInput_ = nullptr; + std::shared_ptr avOutput_ = nullptr; + std::shared_ptr meta_ = nullptr; using SetParaFunc = void (AVSenderEngine::*)(const std::string &value); std::map funcMap_; diff --git a/av_transport/av_trans_engine/av_sender/src/av_sender_engine.cpp b/av_transport/av_trans_engine/av_sender/src/av_sender_engine.cpp index 69e4363d..56ed7ee3 100644 --- a/av_transport/av_trans_engine/av_sender/src/av_sender_engine.cpp +++ b/av_transport/av_trans_engine/av_sender/src/av_sender_engine.cpp @@ -28,6 +28,44 @@ using AVBuffer = OHOS::Media::Plugin::Buffer; #undef DH_LOG_TAG #define DH_LOG_TAG "AVSenderEngine" +class PlayerEventReceiver : public EventReceiver { +public: + explicit PlayerEventReceiver(std::shared_ptr sender, std::string playerId) + { + AVTRANS_LOGI("PlayerEventReceiver ctor called."); + sender_ = sender; + } + + void OnEvent(const Event &event) override + { + AVTRANS_LOGI("PlayerEventReceiver OnEvent."); + } + +private: + std::weak_ptr sender_; +} + +class PlayerFilterCallback : public FilterCallback { +public: + explicit PlayerFilterCallback(std::shared_ptr sender) + { + AVTRANS_LOGI("PlayerEventReceiver ctor called."); + sender_ = sender; + } + + void OnCallback(std::shared_ptr filter, const FilterCallbackCommand cmd, + StreamType outType) override + { + AVTRANS_LOGI("PlayerFilterCallback OnCallback."); + if (sender_ == nullptr) { + return Status::ERROR_NULL_POINTER; + } + return sender_->OnCallback(filter, cmd, outType); + } + +private: + std::weak_ptr sender_; +} AVSenderEngine::AVSenderEngine(const std::string &ownerName, const std::string &peerDevId) : ownerName_(ownerName), peerDevId_(peerDevId) @@ -72,41 +110,30 @@ int32_t AVSenderEngine::Initialize() int32_t AVSenderEngine::InitPipeline() { AVTRANS_LOGI("InitPipeline enter."); - FilterFactory::Instance().Init(); - avInput_ = FilterFactory::Instance().CreateFilterWithType(AVINPUT_NAME, "avinput"); - TRUE_RETURN_V_MSG_E(avInput_ == nullptr, ERR_DH_AVT_NULL_POINTER, "create av input filter failed"); - - avOutput_ = FilterFactory::Instance().CreateFilterWithType(AVOUTPUT_NAME, "avoutput"); - TRUE_RETURN_V_MSG_E(avOutput_ == nullptr, ERR_DH_AVT_NULL_POINTER, "create av output filter failed"); + demoId_ = std::string("AVSenderEngine") + std::to_string(Pipeline::GetNextPipelineId()); + playEventReceiver_ = std::make_shared(this, demoId_); + playFilterCallback_ = std::make_shared(this); + pipeline_ = std::make_shared(); + pipeline_->Init(playEventReceiver_, playFilterCallback_, demoId_); - videoEncoder_ = FilterFactory::Instance().CreateFilterWithType(VENCODER_NAME, "videoencoder"); - TRUE_RETURN_V_MSG_E(videoEncoder_ == nullptr, ERR_DH_AVT_NULL_POINTER, "create av video encoder filter failed"); - - audioEncoder_ = FilterFactory::Instance().CreateFilterWithType(AENCODER_NAME, "audioencoder"); - TRUE_RETURN_V_MSG_E(audioEncoder_ == nullptr, ERR_DH_AVT_NULL_POINTER, "create av audio encoder filter failed"); + avInput_ = std::make_shared("builtin.avtranport.avinput", FilterType::FILTERTYPE_SOURCE); + TRUE_RETURN_V_MSG_E(avInput_ == nullptr, ERR_DH_AVT_NULL_POINTER, "create av input filter failed"); + avInput_->Init(playEventReceiver_, playFilterCallback_); + meta_ = std::make_shared(); - ErrorCode ret; pipeline_ = std::make_shared(); pipeline_->Init(this, nullptr); - if ((ownerName_ == OWNER_NAME_D_SCREEN) || (ownerName_ == OWNER_NAME_D_CAMERA)) { - ret = pipeline_->AddFilters({avInput_.get(), videoEncoder_.get(), avOutput_.get()}); - if (ret == ErrorCode::SUCCESS) { - ret = pipeline_->LinkFilters({avInput_.get(), videoEncoder_.get(), avOutput_.get()}); - } - } else if ((ownerName_ == OWNER_NAME_D_MIC) || (ownerName_ == OWNER_NAME_D_SPEAKER) || - (ownerName_ == OWNER_NAME_D_VIRMODEM_MIC) || (ownerName_ == OWNER_NAME_D_VIRMODEM_SPEAKER)) { - ret = pipeline_->AddFilters({avInput_.get(), avOutput_.get()}); - if (ret == ErrorCode::SUCCESS) { - ret = pipeline_->LinkFilters({avInput_.get(), avOutput_.get()}); - } + Status ret = pipeline_->AddHeadFilters({avInput_}); + if (ret == Status::OK) { + AVTRANS_LOGI("Add head filters success."); } else { AVTRANS_LOGI("unsupport ownerName:%{public}s", ownerName_.c_str()); return ERR_DH_AVT_INVALID_PARAM_VALUE; } - if (ret != ErrorCode::SUCCESS) { + if (ret != Status::OK) { pipeline_->RemoveFilterChain(avInput_.get()); } - return (ret == ErrorCode::SUCCESS) ? DH_AVT_SUCCESS : ERR_DH_AVT_INVALID_OPERATION; + return (ret == Status::OK) ? DH_AVT_SUCCESS : ERR_DH_AVT_INVALID_OPERATION; } int32_t AVSenderEngine::InitControlCenter() @@ -322,62 +349,61 @@ void AVSenderEngine::RegRespFunMap() void AVSenderEngine::SetVideoWidth(const std::string &value) { - if (avInput_ == nullptr) { - AVTRANS_LOGE("avInput_ is nullptr."); + if (meta_ == nullptr) { + AVTRANS_LOGE("meta_ is nullptr."); return; } - avInput_->SetParameter(static_cast(Plugin::Tag::VIDEO_WIDTH), std::stoi(value)); + meta_->SetData(Media::Tag::VIDEO_WIDTH, std::stoi(value)); AVTRANS_LOGI("SetParameter VIDEO_WIDTH success, video width = %{public}s", value.c_str()); } void AVSenderEngine::SetVideoHeight(const std::string &value) { - if (avInput_ == nullptr) { - AVTRANS_LOGE("avInput_ is nullptr."); + if (meta_ == nullptr) { + AVTRANS_LOGE("meta_ is nullptr."); return; } - avInput_->SetParameter(static_cast(Plugin::Tag::VIDEO_HEIGHT), std::stoi(value)); + meta_->SetData(Media::Tag::VIDEO_HEIGHT, std::stoi(value)); AVTRANS_LOGI("SetParameter VIDEO_HEIGHT success, video height = %{public}s", value.c_str()); } void AVSenderEngine::SetVideoPixelFormat(const std::string &value) { - if (avInput_ == nullptr) { + if (meta_ == nullptr) { AVTRANS_LOGE("avInput_ is nullptr."); return; } - avInput_->SetParameter(static_cast(Plugin::Tag::VIDEO_PIXEL_FORMAT), Plugin::VideoPixelFormat::RGBA); + meta_->SetData(Media::Tag::VIDEO_PIXEL_FORMAT, Plugin::VideoPixelFormat::RGBA); AVTRANS_LOGI("SetParameter VIDEO_PIXEL_FORMAT success, pixel format = %{public}s", value.c_str()); } void AVSenderEngine::SetVideoFrameRate(const std::string &value) { - if (avInput_ == nullptr || avOutput_ == nullptr) { - AVTRANS_LOGE("avInput_ or avOutput_ is nullptr."); + if (meta_ == nullptr) { + AVTRANS_LOGE("meta_ is nullptr."); return; } - avInput_->SetParameter(static_cast(Plugin::Tag::VIDEO_FRAME_RATE), std::stoi(value)); - avOutput_->SetParameter(static_cast(Plugin::Tag::VIDEO_FRAME_RATE), std::stoi(value)); + meta_->SetData(Media::Tag::VIDEO_FRAME_RATE, std::stoi(value)); AVTRANS_LOGI("SetParameter VIDEO_FRAME_RATE success, frame rate = %{public}s", value.c_str()); } void AVSenderEngine::SetAudioBitRate(const std::string &value) { - if (avInput_ == nullptr) { - AVTRANS_LOGE("avInput_ is nullptr."); + if (meta_ == nullptr) { + AVTRANS_LOGE("meta_ is nullptr."); return; } - avInput_->SetParameter(static_cast(Plugin::Tag::MEDIA_BITRATE), std::stoi(value)); + meta_->SetData(Media::Tag::MEDIA_BITRATE, std::stoi(value)); AVTRANS_LOGI("SetParameter MEDIA_BITRATE success, bit rate = %{public}s", value.c_str()); } void AVSenderEngine::SetVideoBitRate(const std::string &value) { - if (avInput_ == nullptr) { - AVTRANS_LOGE("avInput_ is nullptr."); + if (meta_ == nullptr) { + AVTRANS_LOGE("meta_ is nullptr."); return; } - avInput_->SetParameter(static_cast(Plugin::Tag::MEDIA_BITRATE), std::stoi(value)); + meta_->SetData(Media::Tag::MEDIA_BITRATE, std::stoi(value)); AVTRANS_LOGI("SetParameter MEDIA_BITRATE success, bit rate = %{public}s", value.c_str()); } @@ -416,7 +442,7 @@ void AVSenderEngine::SetVideoCodecType(const std::string &value) void AVSenderEngine::SetAudioCodecType(const std::string &value) { - if (avInput_ == nullptr || avOutput_ == nullptr || audioEncoder_ == nullptr) { + if (meta_ == nullptr) { AVTRANS_LOGE("avInput_ or avOutput_ or audioEncoder_ is nullptr."); return; } @@ -426,7 +452,7 @@ void AVSenderEngine::SetAudioCodecType(const std::string &value) audioEncoder_->SetAudioEncoder(0, std::make_shared(encoderMeta)); std::string mime = MEDIA_MIME_AUDIO_RAW; - avInput_->SetParameter(static_cast(Plugin::Tag::MIME), mime); + meta_->SetData(Plugin::Tag::MIME, mime); mime = MEDIA_MIME_AUDIO_AAC; avOutput_->SetParameter(static_cast(Plugin::Tag::MIME), mime); AVTRANS_LOGI("SetParameter AUDIO_CODEC_TYPE = ACC success"); @@ -434,64 +460,61 @@ void AVSenderEngine::SetAudioCodecType(const std::string &value) void AVSenderEngine::SetAudioChannelMask(const std::string &value) { - if (avInput_ == nullptr || avOutput_ == nullptr) { - AVTRANS_LOGE("avInput_ or avOutput_ is nullptr."); + if (meta_ == nullptr) { + AVTRANS_LOGE("meta_ is nullptr."); return; } - avInput_->SetParameter(static_cast(Plugin::Tag::AUDIO_CHANNELS), std::stoi(value)); - avOutput_->SetParameter(static_cast(Plugin::Tag::AUDIO_CHANNELS), std::stoi(value)); + meta_->SetData(Media::Tag::AUDIO_CHANNELS, std::stoi(value)); AVTRANS_LOGI("SetParameter AUDIO_CHANNELS success, audio channels = %{public}s", value.c_str()); } void AVSenderEngine::SetAudioSampleRate(const std::string &value) { - if (avInput_ == nullptr || avOutput_ == nullptr) { - AVTRANS_LOGE("avInput_ or avOutput_ is nullptr."); + if (meta_ == nullptr) { + AVTRANS_LOGE("meta_ is nullptr."); return; } - avInput_->SetParameter(static_cast(Plugin::Tag::AUDIO_SAMPLE_RATE), std::stoi(value)); - avOutput_->SetParameter(static_cast(Plugin::Tag::AUDIO_SAMPLE_RATE), std::stoi(value)); + meta_->SetData(Media::Tag::AUDIO_SAMPLE_RATE, std::stoi(value)); AVTRANS_LOGI("SetParameter AUDIO_SAMPLE_RATE success, audio sample rate = %{public}s", value.c_str()); } void AVSenderEngine::SetAudioChannelLayout(const std::string &value) { - if (avInput_ == nullptr || avOutput_ == nullptr) { + if (meta_ == nullptr) { AVTRANS_LOGE("avInput_ or avOutput_ is nullptr."); return; } - avInput_->SetParameter(static_cast(Plugin::Tag::AUDIO_CHANNEL_LAYOUT), std::stoi(value)); - avOutput_->SetParameter(static_cast(Plugin::Tag::AUDIO_CHANNEL_LAYOUT), std::stoi(value)); + meta_->SetData(Media::Tag::AUDIO_CHANNEL_LAYOUT, std::stoi(value)); AVTRANS_LOGI("SetParameter AUDIO_CHANNEL_LAYOUT success, audio channel layout = %{public}s", value.c_str()); } void AVSenderEngine::SetAudioSampleFormat(const std::string &value) { - if (avInput_ == nullptr) { - AVTRANS_LOGE("avInput_ is nullptr."); + if (meta_ == nullptr) { + AVTRANS_LOGE("meta_ is nullptr."); return; } - avInput_->SetParameter(static_cast(Plugin::Tag::AUDIO_SAMPLE_FORMAT), std::stoi(value)); + meta_->SetData(Media::Tag::AUDIO_SAMPLE_FORMAT, std::stoi(value)); AVTRANS_LOGI("SetParameter AUDIO_SAMPLE_FORMAT success, audio sample format = %{public}s", value.c_str()); } void AVSenderEngine::SetAudioFrameSize(const std::string &value) { - if (avInput_ == nullptr) { - AVTRANS_LOGE("avInput_ is nullptr."); + if (meta_ == nullptr) { + AVTRANS_LOGE("meta_ is nullptr."); return; } - avInput_->SetParameter(static_cast(Plugin::Tag::AUDIO_SAMPLE_PER_FRAME), std::stoi(value)); + meta_->SetData(Media::Tag::AUDIO_SAMPLE_PER_FRAME, std::stoi(value)); AVTRANS_LOGI("SetParameter AUDIO_SAMPLE_PER_FRAME success, audio sample per frame = %{public}s", value.c_str()); } void AVSenderEngine::SetSharedMemoryFd(const std::string &value) { - if (avInput_ == nullptr) { - AVTRANS_LOGE("avInput_ is nullptr."); + if (meta_ == nullptr) { + AVTRANS_LOGE("meta_ is nullptr."); return; } - avInput_->SetParameter(static_cast(Plugin::Tag::USER_SHARED_MEMORY_FD), value); + meta_->SetData(Media::Tag::USER_SHARED_MEMORY_FD, value); AVTRANS_LOGI("SetParameter USER_SHARED_MEMORY_FD success, shared memory info = %{public}s", value.c_str()); } @@ -534,12 +557,20 @@ int32_t AVSenderEngine::PushData(const std::shared_ptr &buffer) NotifyStreamChange(EventType::EVENT_ADD_STREAM); } TRUE_RETURN_V_MSG_E(avInput_ == nullptr, ERR_DH_AVT_PUSH_DATA_FAILED, "av input filter is null"); - - std::shared_ptr hisBuffer = TransBuffer2HiSBuffer(buffer); - TRUE_RETURN_V(hisBuffer == nullptr, ERR_DH_AVT_PUSH_DATA_FAILED); - - ErrorCode ret = avInput_->PushData(avInput_->GetName(), hisBuffer, -1); - TRUE_RETURN_V(ret != ErrorCode::SUCCESS, ERR_DH_AVT_PUSH_DATA_FAILED); + sptr producer = avInput_->GetinputBufQueProducer(); + auto data = transBuffer->GetBufferData(); + if (data == nullptr) { + return ERR_DH_AVT_PUSH_DATA_FAILED; + } + Media::AVBufferConfig config; + const int buffersize = data->GetSize(); + config.size = buffersize; + config.memoryType = Media::MemoryType::VIRTUAL_MEMORY; + config.memoryFlag = Media::MemoryFlag::MEMORY_READ_WRITE; + std::shared_ptr outBuffer = TransBuffer2HiSBuffer(buffer); + Status status = producer->RequestBuffer(outBuffer, config, TIME_OUT_MS); + TRUE_RETURN_V_MSG_E(status == Status::OK, ERR_DH_AVT_PUSH_DATA_FAILED, "RequestBuffer fail"); + producer->PushBuffer(outBuffer, true) SetCurrentState(StateId::PLAYING); return DH_AVT_SUCCESS; @@ -711,5 +742,58 @@ void AVSenderEngine::OnEvent(const Event &event) AVTRANS_LOGE("Invalid event type."); } } + +Status AVSenderEngine::Oncallback(std::shared_ptr filter, const FilterCallbackCommand cmd, + StreamType outType) //根据outType类型 申请节点 +{ + AVTRANS_LOGI("PipeDemo::OnCallback filter, outType: %{public}d", outType); + if (cmd == FilterCallBackCommand::NEXT_FILTER_NEEDED) { + switch (outType) { + case StreamType::STREAMTYPE_RAW_AUDIO: + return LinkAudioSinkFilter(filter, outType); + case StreamType::STREAMTYPE_ENCODED_AUDIO: + return LinkAudioEncoderFilter(filter, outType); + default: + break; + } + } + return Status::OK; +} + +int32_t AVSenderEngine::LinkAudioEncoderFilter(const std::shared_ptr& preFilter, StreamType type) +{ + return Status::OK; +} + +int32_t AVSenderEngine::LinkAudioSinkFilter(const std::shared_ptr& preFilter, Stream type) +{ + AVTRANS_LOGI("PipeDemo::LinkAudioDecoderFilter"); + TRUE_RETURN_V(avOutput_ != nullptr, Status::OK); + avOutput_ = std::make_shared("builtin.avtransport.avoutput", FilterType::FILTERTYPE_ASINK); + TRUE_RETURN_V(avOutput_ == nullptr, Status::ERROR_NULL_POINTER); + avOutput_->Init(playerEventReceiver_, playerFilterCallback_); + if (pipeline_ == nullptr) { + AVTRANS_LOGE("Pipeline_ is nullptr"); + return ERR_DH_AVT_START_FAILED; + } + pipeline_->LinkFilters(preFilter, {avOutput_}, type); + return DH_AVT_SUCCESS; +} + +Status AVSenderEngine::Prepare() +{ + if (avInput_ == nullptr) { + AVTRANS_LOGE("avInput_ is nullptr"); + return ERR_DH_AVT_START_FAILED; + } + avInput_->SetParameter(meta_); + if (pipeline_ == nullptr) { + AVTRANS_LOGE("Pipeline_ is nullptr"); + return ERR_DH_AVT_START_FAILED; + } + Status ret = pipeline_->Prepare(); + TRUE_RETURN_V_MSG_E(ret != Status::ok, ERR_DH_AVT_PREPARE_FAILED, "pipeline prepare failed"); + return Status::OK; +} } // namespace DistributedHardware } // namespace OHOS \ No newline at end of file -- Gitee