dengxiaoyu 2024-11-07 15:37:04 +08:00
commit 7504ebe584
10 changed files with 1722 additions and 8 deletions

View File

@ -0,0 +1,68 @@
/*
* 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_AV_PIPELINE_EVENT_H
#define OHOS_AV_PIPELINE_EVENT_H
#include <map>
#include <string>
#include "meta/any.h"
namespace OHOS {
namespace DistributedHardware {
enum struct EventType : uint32_t {
EVENT_READY = 0,
EVENT_AUDIO_PROGRESS, // unit is HST_TIME_BASE
EVENT_VIDEO_PROGRESS, // unit is HST_TIME_BASE
EVENT_COMPLETE,
EVENT_ERROR,
EVENT_PLUGIN_ERROR,
EVENT_PLUGIN_EVENT,
EVENT_BUFFERING,
EVENT_BUFFER_PROGRESS,
EVENT_DECODER_ERROR,
EVENT_RESOLUTION_CHANGE,
EVENT_VIDEO_RENDERING_START,
EVENT_IS_LIVE_STREAM,
EVENT_DRM_INFO_UPDATED,
EVENT_AUDIO_INTERRUPT,
EVENT_AUDIO_STATE_CHANGE,
EVENT_AUDIO_FIRST_FRAME,
EVENT_AUDIO_DEVICE_CHANGE,
EVENT_AUDIO_SERVICE_DIED,
BUFFERING_START,
BUFFERING_END,
EVENT_CACHED_DURATION,
EVENT_SOURCE_BITRATE_START,
EVENT_SUBTITLE_TEXT_UPDATE,
EVENT_AUDIO_TRACK_CHANGE,
EVENT_VIDEO_TRACK_CHANGE,
EVENT_SUBTITLE_TRACK_CHANGE,
EVENT_VIDEO_LAG, // player lag event detected by video sink
EVENT_AUDIO_LAG, // player lag event detected by audio sink
EVENT_STREAM_LAG, // player lag event detected by sync manager
};
struct Event {
std::string srcFilter;
EventType type;
Media::Any param;
};
const char* GetEventName(EventType type);
} // namespace DistributedHardware
} // namespace OHOS
#endif //OHOS_AV_PIPELINE_EVENT_H

View File

@ -0,0 +1,72 @@
/*
* 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_AV_PIPELINE_STATUS_H
#define OHOS_AV_PIPELINE_STATUS_H
#include <cstdint>
namespace OHOS {
namespace DistributedHardware {
enum struct Status : int32_t {
END_OF_STREAM = 1, ///< Read source when end of stream
OK = 0, ///< The execution result is correct.
NO_ERROR = OK, ///< Same as Status::OK
ERROR_UNKNOWN = -1, ///< An unknown error occurred.
ERROR_PLUGIN_ALREADY_EXISTS = -2, ///< The plugin already exists, usually occurs when in plugin registered.
ERROR_INCOMPATIBLE_VERSION =
-3, ///< Incompatible version, may occur during plugin registration or function calling.
ERROR_NO_MEMORY = -4, ///< The system memory is insufficient.
ERROR_WRONG_STATE = -5, ///< The function is called in an invalid state.
ERROR_UNIMPLEMENTED = -6, ///< This method or interface is not implemented.
ERROR_INVALID_PARAMETER = -7, ///< The plugin does not support this parameter.
ERROR_INVALID_DATA = -8, ///< The value is not in the valid range.
ERROR_MISMATCHED_TYPE = -9, ///< Mismatched data type
ERROR_TIMED_OUT = -10, ///< Operation timeout.
ERROR_UNSUPPORTED_FORMAT = -11, ///< The plugin not support this format/name.
ERROR_NOT_ENOUGH_DATA = -12, ///< Not enough data when read from source.
ERROR_NOT_EXISTED = -13, ///< Source is not existed.
ERROR_AGAIN = -14, ///< Operation is not available right now, should try again later.
ERROR_PERMISSION_DENIED = -15, ///< Permission denied.
ERROR_NULL_POINTER = -16, ///< Null pointer.
ERROR_INVALID_OPERATION = -17, ///< Invalid operation.
ERROR_CLIENT = -18, ///< Http client error
ERROR_SERVER = -19, ///< Http server error
ERROR_DELAY_READY = -20, ///< Delay ready event
ERROR_INVALID_STATE = -21,
ERROR_AUDIO_INTERRUPT = -22,
ERROR_INVALID_BUFFER_SIZE = 0xF001,
ERROR_UNEXPECTED_MEMORY_TYPE = 0xF002,
ERROR_CREATE_BUFFER = 0xF003,
ERROR_NULL_POINT_BUFFER = 0xF004,
ERROR_INVALID_BUFFER_ID = 0xF005,
ERROR_INVALID_BUFFER_STATE = 0xF006,
ERROR_NO_FREE_BUFFER = 0xF007,
ERROR_NO_DIRTY_BUFFER = 0xF008,
ERROR_NO_CONSUMER_LISTENER = 0xF009,
ERROR_NULL_BUFFER_QUEUE = 0xF00A,
ERROR_WAIT_TIMEOUT = 0xF00B,
ERROR_OUT_OF_RANGE = 0xF00C,
ERROR_NULL_SURFACE = 0xF00D,
ERROR_SURFACE_INNER = 0xF00E,
ERROR_NULL_SURFACE_BUFFER = 0xF00F,
ERROR_DRM_DECRYPT_FAILED = 0xF010,
ERROR_IPC_WRITE_INTERFACE_TOKEN = 0xF101,
ERROR_IPC_SEND_REQUEST = 0xF102,
};
} // namespace DistributedHardware
} // namespace OHOS
#endif // OHOS_AV_PIPELINE_STATUS_H

View File

@ -0,0 +1,87 @@
# 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.
import("//build/ohos.gni")
import("../distributed_av_transport.gni")
config("av_pipeline_fwk_external_config") {
include_dirs = [
"${common_path}/include",
"${dh_fwk_sdk_path}/include",
"${interface_path}",
]
}
ohos_shared_library("distributed_av_pipeline_fwk") {
sanitize = {
cfi = true
cfi_cross_dso = true
cfi_no_nvcall = true
cfi_vcall_icall_only = true
debug = false
boundary_sanitize = true
integer_overflow = true
ubsan = true
}
branch_protector_ret = "pac_ret"
public_configs = [ ":av_pipeline_fwk_external_config" ]
include_dirs = [
"${dh_fwk_utils_path}/include",
"${distributed_av_transport_path}/framework",
"${distributed_av_transport_path}/framework/filter/include",
]
sources = [
"${common_path}/src/av_trans_log.cpp",
"${distributed_av_transport_path}/framework/filter/src/filter.cpp",
"${distributed_av_transport_path}/framework/filter/src/filter_factory.cpp",
"${distributed_av_transport_path}/framework/pipeline/src/pipeline.cpp",
]
deps = [ "${dh_fwk_sdk_path}:libdhfwk_sdk" ]
defines = [
"HI_LOG_ENABLE",
"DH_LOG_TAG=\"av_trans_fwk\"",
"LOG_DOMAIN=0xD004101",
]
external_deps = [
"bounds_checking_function:libsec_shared",
"c_utils:utils",
"hilog:libhilog",
"hisysevent:libhisysevent",
"hitrace:hitrace_meter",
"ipc:ipc_core",
"safwk:system_ability_fwk",
"samgr:samgr_proxy",
]
if (histreamer_compile_part) {
external_deps += [ "media_foundation:media_foundation" ]
}
cflags = [
"-fexceptions",
"-fno-rtti",
"-fPIC",
"-O2",
"-Wall",
"-Wno-c++20-extensions",
]
cflags_cc = cflags
part_name = "distributed_hardware_fwk"
subsystem_name = "distributedhardware"
}

View File

@ -0,0 +1,280 @@
/*
* 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_AV_PIPELINE_FILTER_BASE_H
#define OHOS_AV_PIPELINE_FILTER_BASE_H
#include <atomic>
#include <functional>
#include <list>
#include <memory>
#include "buffer/avbuffer_queue_producer.h"
#include "meta/meta.h"
#include "osal/task/condition_variable.h"
#include "osal/task/mutex.h"
#include "osal/task/task.h"
#include "pipeline_event.h"
#include "pipeline_status.h"
namespace OHOS {
namespace DistributedHardware {
namespace Pipeline {
class Filter;
enum class FilterType {
FILTERTYPE_SOURCE,
FILTERTYPE_DEMUXER,
FILTERTYPE_AENC,
FILTERTYPE_ADEC,
FILTERTYPE_VENC,
FILTERTYPE_VDEC,
FILTERTYPE_VIDEODEC,
FILTERTYPE_MUXER,
FILTERTYPE_ASINK,
FILTERTYPE_FSINK,
FILTERTYPE_SSINK,
AUDIO_CAPTURE,
AUDIO_DATA_SOURCE,
VIDEO_CAPTURE,
FILTERTYPE_VIDRESIZE,
TIMED_METADATA,
FILTERTYPE_MAX,
};
enum class StreamType {
STREAMTYPE_PACKED,
STREAMTYPE_ENCODED_AUDIO,
STREAMTYPE_ENCODED_VIDEO,
STREAMTYPE_RAW_AUDIO,
STREAMTYPE_RAW_VIDEO,
STREAMTYPE_SUBTITLE,
STREAMTYPE_MAX,
};
enum class FilterState {
CREATED, // Filter created
INITIALIZED, // Init called
PREPARING, // Prepare called
READY, // Ready Event reported
RUNNING, // Start called
PAUSED, // Pause called
STOPPED, // Stop called
RELEASED, // Release called
ERROR, // State fail
};
enum class FilterCallBackCommand {
NEXT_FILTER_NEEDED,
NEXT_FILTER_REMOVED,
NEXT_FILTER_UPDATE,
FILTER_CALLBACK_COMMAND_MAX,
};
class EventReceiver {
public:
virtual ~EventReceiver() = default;
virtual void OnEvent(const Event& event) = 0;
};
class FilterCallback {
public:
virtual ~FilterCallback() = default;
virtual Status OnCallback(const std::shared_ptr<Filter>& filter, FilterCallBackCommand cmd, StreamType outType) = 0;
};
class FilterLinkCallback {
public:
virtual ~FilterLinkCallback() = default;
virtual void OnLinkedResult(const sptr<Media::AVBufferQueueProducer>& queue,
std::shared_ptr<Media::Meta>& meta) = 0;
virtual void OnUnlinkedResult(std::shared_ptr<Media::Meta>& meta) = 0;
virtual void OnUpdatedResult(std::shared_ptr<Media::Meta>& meta) = 0;
};
class Filter {
public:
explicit Filter(std::string name, FilterType type, bool asyncMode = false);
virtual ~Filter();
virtual void Init(const std::shared_ptr<EventReceiver>& receiver, const std::shared_ptr<FilterCallback>& callback);
virtual void LinkPipeLine(const std::string& groupId) final;
virtual Status Prepare() final;
virtual Status Start() final;
virtual Status Pause() final;
virtual Status PauseDragging() final;
virtual Status Resume() final;
virtual Status ResumeDragging() final;
virtual Status Stop() final;
virtual Status Flush() final;
virtual Status Release() final;
virtual Status Preroll() final;
virtual Status WaitPrerollDone(bool render) final;
virtual void StartFilterTask() final;
virtual void PauseFilterTask() final;
virtual Status SetPlayRange(int64_t start, int64_t end) final;
virtual Status ProcessInputBuffer(int sendArg = 0, int64_t delayUs = 0) final;
virtual Status ProcessOutputBuffer(int sendArg = 0, int64_t delayUs = 0, bool byIdx = false, uint32_t idx = 0,
int64_t renderTime = -1) final;
virtual Status WaitAllState(FilterState state) final;
virtual Status DoInitAfterLink();
virtual Status DoPrepare();
virtual Status DoStart();
virtual Status DoPause();
virtual Status DoPauseDragging();
virtual Status DoResume();
virtual Status DoResumeDragging();
virtual Status DoStop();
virtual Status DoFlush();
virtual Status DoRelease();
virtual Status DoPreroll();
virtual Status DoWaitPrerollDone(bool render);
virtual Status DoSetPlayRange(int64_t start, int64_t end);
virtual Status DoProcessInputBuffer(int recvArg, bool dropFrame);
virtual Status DoProcessOutputBuffer(int recvArg, bool dropFrame, bool byIdx, uint32_t idx, int64_t renderTime);
virtual void SetParameter(const std::shared_ptr<Media::Meta>& meta);
virtual void GetParameter(std::shared_ptr<Media::Meta>& meta);
virtual Status LinkNext(const std::shared_ptr<Filter>& nextFilter, StreamType outType);
virtual Status UpdateNext(const std::shared_ptr<Filter>& nextFilter, StreamType outType);
virtual Status UnLinkNext(const std::shared_ptr<Filter>& nextFilter, StreamType outType);
FilterType GetFilterType();
virtual Status OnLinked(StreamType inType, const std::shared_ptr<Media::Meta>& meta,
const std::shared_ptr<FilterLinkCallback>& callback);
virtual Status OnUpdated(StreamType inType, const std::shared_ptr<Media::Meta>& meta,
const std::shared_ptr<FilterLinkCallback>& callback);
virtual Status OnUnLinked(StreamType inType, const std::shared_ptr<FilterLinkCallback>& callback);
virtual void ChangeState(FilterState state);
virtual void SetErrCode(Status errCode);
virtual Status GetErrCode();
virtual Status ClearAllNextFilters();
virtual Status SetMuted(bool isMuted)
{
(void)isMuted;
return Status::OK;
}
virtual bool IsDesignatedState(FilterState state);
protected:
virtual Status PrepareDone() final;
virtual Status StartDone() final;
virtual Status PauseDone() final;
virtual Status ResumeDone() final;
virtual Status StopDone() final;
virtual Status ReleaseDone() final;
std::string name_;
std::shared_ptr<Media::Meta> meta_;
FilterType filterType_;
FilterState curState_;
std::vector<StreamType> supportedInStreams_;
std::vector<StreamType> supportedOutStreams_;
OHOS::Media::Mutex stateMutex_{};
OHOS::Media::ConditionVariable cond_{};
std::map<StreamType, std::vector<std::shared_ptr<Filter>>> nextFiltersMap_;
std::shared_ptr<EventReceiver> receiver_;
std::shared_ptr<FilterCallback> callback_;
std::map<StreamType, std::vector<std::shared_ptr<FilterLinkCallback>>> linkCallbackMaps_;
Status errCode_ = Status::OK;
std::unique_ptr<Media::Task> filterTask_;
int64_t jobIdx_ = 0;
int64_t processIdx_ = 0;
int64_t jobIdxBase_ = 0;
std::string groupId_;
bool isAsyncMode_;
};
enum FilterPlaybackCommand {
INIT = 0,
PREPARE,
START,
PAUSE,
RESUME,
STOP,
RELEASE,
FLUSH,
PROCESS_INPUT_BUFFER,
PROCESS_OUTPUT_BUFFER,
};
} // namespace Pipeline
} // namespace DistributedHardware
} // namespace OHOS
#endif

View File

@ -0,0 +1,101 @@
/*
* 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_AV_PIPELINE_FILTER_FACTORY_H
#define OHOS_AV_PIPELINE_FILTER_FACTORY_H
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
#include "filter.h"
#include "cpp_ext/type_cast_ext.h"
namespace OHOS {
namespace DistributedHardware {
namespace Pipeline {
using InstanceGenerator = std::function<std::shared_ptr<Filter>(const std::string&, const FilterType type)>;
class FilterFactory {
public:
~FilterFactory() = default;
FilterFactory(const FilterFactory&) = delete;
FilterFactory operator=(const FilterFactory&) = delete;
static FilterFactory& Instance();
template <typename T>
std::shared_ptr<T> CreateFilter(const std::string& filterName, const FilterType type)
{
auto filter = CreateFilterPriv(filterName, type);
auto typedFilter = Media::ReinterpretPointerCast<T>(filter);
return typedFilter;
}
template <typename T>
void RegisterFilter(const std::string& name, const FilterType type, const InstanceGenerator& generator = nullptr)
{
RegisterFilterPriv<T>(name, type, generator);
}
private:
FilterFactory() = default;
std::shared_ptr<Filter> CreateFilterPriv(const std::string& filterName, const FilterType type);
template <typename T>
void RegisterFilterPriv(const std::string& name, const FilterType type, const InstanceGenerator& generator)
{
if (generator == nullptr) {
auto result = generators.emplace(
type, [](const std::string &aliaName, const FilterType type) {
return std::make_shared<T>(aliaName, type);
});
if (!result.second) {
result.first->second = generator;
}
} else {
auto result = generators.emplace(type, generator);
if (!result.second) {
result.first->second = generator;
}
}
}
std::unordered_map<FilterType, InstanceGenerator> generators;
};
template <typename T>
class AutoRegisterFilter {
public:
explicit AutoRegisterFilter(const std::string& name, const FilterType type)
{
FilterFactory::Instance().RegisterFilter<T>(name, type);
}
AutoRegisterFilter(const std::string& name, const FilterType type, const InstanceGenerator& generator)
{
FilterFactory::Instance().RegisterFilter<T>(name, type, generator);
}
~AutoRegisterFilter() = default;
};
} // namespace Pipeline
} // namespace DistributedHardware
} // namespace OHOS
#endif // OHOS_AV_PIPELINE_FILTER_FACTORY_H

View File

@ -0,0 +1,607 @@
/*
* 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 "filter.h"
#include <algorithm>
#include "osal/utils/util.h"
#include "av_trans_log.h"
#undef DH_LOG_TAG
#define DH_LOG_TAG "Filter"
namespace OHOS {
namespace DistributedHardware {
namespace Pipeline {
Filter::Filter(std::string name, FilterType type, bool isAsyncMode)
: name_(std::move(name)), filterType_(type), isAsyncMode_(isAsyncMode)
{
}
Filter::~Filter()
{
nextFiltersMap_.clear();
}
void Filter::Init(const std::shared_ptr<EventReceiver>& receiver, const std::shared_ptr<FilterCallback>& callback)
{
receiver_ = receiver;
callback_ = callback;
}
void Filter::LinkPipeLine(const std::string& groupId)
{
groupId_ = groupId;
if (isAsyncMode_) {
Media::TaskType taskType;
switch (filterType_) {
case FilterType::FILTERTYPE_VENC:
case FilterType::FILTERTYPE_VDEC:
case FilterType::VIDEO_CAPTURE:
taskType = Media::TaskType::SINGLETON;
break;
case FilterType::FILTERTYPE_ASINK:
case FilterType::AUDIO_CAPTURE:
taskType = Media::TaskType::AUDIO;
break;
default:
taskType = Media::TaskType::SINGLETON;
break;
}
filterTask_ = std::make_unique<Media::Task>(name_, groupId_, taskType, Media::TaskPriority::HIGH, false);
filterTask_->SubmitJobOnce([this] {
DoInitAfterLink();
ChangeState(FilterState::INITIALIZED);
});
} else {
DoInitAfterLink();
ChangeState(FilterState::INITIALIZED);
}
}
Status Filter::Prepare()
{
AVTRANS_LOGD("Prepare %{public}s, pState:%{public}d", name_.c_str(), curState_);
if (filterTask_) {
filterTask_->SubmitJobOnce([this] {
PrepareDone();
});
} else {
return PrepareDone();
}
return Status::OK;
}
Status Filter::PrepareDone()
{
AVTRANS_LOGI("Prepare in %{public}s", name_.c_str());
// next filters maybe added in DoPrepare, so we must DoPrepare first
Status ret = DoPrepare();
SetErrCode(ret);
if (ret != Status::OK) {
return ret;
}
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
if (filter != nullptr) {
filter->Prepare();
}
}
}
ChangeState(FilterState::READY);
return ret;
}
Status Filter::Start()
{
AVTRANS_LOGD("Start %{public}s, pState:%{public}d", name_.c_str(), curState_);
if (filterTask_) {
filterTask_->SubmitJobOnce([this] {
StartDone();
filterTask_->Start();
});
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
filter->Start();
}
}
return Status::OK;
}
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
if (filter != nullptr) {
filter->Start();
}
}
}
return StartDone();
}
Status Filter::StartDone()
{
AVTRANS_LOGI("Start in %{public}s", name_.c_str());
Status ret = DoStart();
SetErrCode(ret);
ChangeState(ret == Status::OK ? FilterState::RUNNING : FilterState::ERROR);
return ret;
}
Status Filter::Pause()
{
AVTRANS_LOGD("Pause %{public}s, pState:%{public}d", name_.c_str(), curState_);
// In offload case, we need pause to interrupt audio_sink_plugin write function, so do not use filterTask_
auto ret = PauseDone();
if (filterTask_) {
filterTask_->Pause();
}
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
if (filter != nullptr) {
filter->Pause();
}
}
}
return ret;
}
Status Filter::PauseDragging()
{
AVTRANS_LOGD("PauseDragging %{public}s, pState:%{public}d", name_.c_str(), curState_);
auto ret = DoPauseDragging();
if (filterTask_) {
filterTask_->Pause();
}
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
if (filter != nullptr) {
filter->PauseDragging();
}
}
}
return ret;
}
Status Filter::PauseDone()
{
AVTRANS_LOGI("Pause in %{public}s", name_.c_str());
Status ret = DoPause();
SetErrCode(ret);
ChangeState(ret == Status::OK ? FilterState::PAUSED : FilterState::ERROR);
return ret;
}
Status Filter::Resume()
{
AVTRANS_LOGD("Resume %{public}s, pState:%{public}d", name_.c_str(), curState_);
if (filterTask_) {
filterTask_->SubmitJobOnce([this]() {
ResumeDone();
filterTask_->Start();
});
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
filter->Resume();
}
}
return Status::OK;
}
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
if (filter != nullptr) {
filter->Resume();
}
}
}
return ResumeDone();
}
Status Filter::ResumeDone()
{
AVTRANS_LOGI("Resume in %{public}s", name_.c_str());
Status ret = DoResume();
SetErrCode(ret);
ChangeState(ret == Status::OK ? FilterState::RUNNING : FilterState::ERROR);
return ret;
}
Status Filter::ResumeDragging()
{
AVTRANS_LOGD("ResumeDragging %{public}s, pState:%{public}d", name_.c_str(), curState_);
if (filterTask_) {
filterTask_->SubmitJobOnce([this]() {
DoResumeDragging();
filterTask_->Start();
});
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
filter->ResumeDragging();
}
}
return Status::OK;
}
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
if (filter != nullptr) {
filter->ResumeDragging();
}
}
}
return DoResumeDragging();
}
Status Filter::Stop()
{
AVTRANS_LOGD("Stop %{public}s, pState:%{public}d", name_.c_str(), curState_);
// In offload case, we need stop to interrupt audio_sink_plugin write function, so do not use filterTask_
auto ret = StopDone();
if (filterTask_) {
filterTask_->Stop();
}
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
if (filter != nullptr) {
filter->Stop();
}
}
}
return ret;
}
Status Filter::StopDone()
{
AVTRANS_LOGI("Stop in %{public}s", name_.c_str());
Status ret = DoStop();
SetErrCode(ret);
ChangeState(ret == Status::OK ? FilterState::STOPPED : FilterState::ERROR);
return ret;
}
Status Filter::Flush()
{
AVTRANS_LOGD("Flush %{public}s, pState:%{public}d", name_.c_str(), curState_);
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
if (filter != nullptr) {
filter->Flush();
}
}
}
jobIdxBase_ = jobIdx_;
return DoFlush();
}
Status Filter::Release()
{
AVTRANS_LOGD("Release %{public}s, pState:%{public}d", name_.c_str(), curState_);
if (filterTask_) {
filterTask_->SubmitJobOnce([this]() {
ReleaseDone();
});
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
filter->Release();
}
}
return Status::OK;
}
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
if (filter != nullptr) {
filter->Release();
}
}
}
return ReleaseDone();
}
Status Filter::ReleaseDone()
{
AVTRANS_LOGI("Release in %{public}s", name_.c_str());
Status ret = DoRelease();
SetErrCode(ret);
ChangeState(ret == Status::OK ? FilterState::RELEASED : FilterState::ERROR);
return ret;
}
Status Filter::SetPlayRange(int64_t start, int64_t end)
{
AVTRANS_LOGD("SetPlayRange %{public}s, pState:%{public}d", name_.c_str(), curState_);
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
if (filter != nullptr) {
filter->SetPlayRange(start, end);
}
}
}
return DoSetPlayRange(start, end);
}
Status Filter::Preroll()
{
Status ret = DoPreroll();
if (ret != Status::OK) {
return ret;
}
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
if (filter == nullptr) {
continue;
}
ret = filter->Preroll();
if (ret != Status::OK) {
return ret;
}
}
}
return Status::OK;
}
Status Filter::WaitPrerollDone(bool render)
{
Status ret = Status::OK;
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
if (filter == nullptr) {
continue;
}
auto curRet = filter->WaitPrerollDone(render);
if (curRet != Status::OK) {
ret = curRet;
}
}
}
auto curRet = DoWaitPrerollDone(render);
if (curRet != Status::OK) {
ret = curRet;
}
return ret;
}
void Filter::StartFilterTask()
{
if (filterTask_) {
filterTask_->Start();
}
}
void Filter::PauseFilterTask()
{
if (filterTask_) {
filterTask_->Pause();
}
}
Status Filter::ClearAllNextFilters()
{
nextFiltersMap_.clear();
return Status::OK;
}
Status Filter::ProcessInputBuffer(int sendArg, int64_t delayUs)
{
AVTRANS_LOGD("Filter::ProcessInputBuffer %{public}s", name_.c_str());
if (filterTask_) {
jobIdx_++;
filterTask_->SubmitJob([this, sendArg]() {
processIdx_++;
DoProcessInputBuffer(sendArg, processIdx_ <= jobIdxBase_); // drop frame after flush
}, delayUs, false);
} else {
Media::Task::SleepInTask(delayUs / 1000); // 1000 convert to ms
DoProcessInputBuffer(sendArg, false);
}
return Status::OK;
}
Status Filter::ProcessOutputBuffer(int sendArg, int64_t delayUs, bool byIdx, uint32_t idx, int64_t renderTime)
{
AVTRANS_LOGD("Filter::ProcessOutputBuffer %{public}s", name_.c_str());
if (filterTask_) {
jobIdx_++;
int64_t processIdx = jobIdx_;
filterTask_->SubmitJob([this, sendArg, processIdx, byIdx, idx, renderTime]() {
processIdx_++;
// drop frame after flush
DoProcessOutputBuffer(sendArg, processIdx <= jobIdxBase_, byIdx, idx, renderTime);
}, delayUs, false);
} else {
Media::Task::SleepInTask(delayUs / 1000); // 1000 convert to ms
DoProcessOutputBuffer(sendArg, false, false, idx, renderTime);
}
return Status::OK;
}
Status Filter::DoInitAfterLink()
{
AVTRANS_LOGI("Filter::DoInitAfterLink");
return Status::OK;
}
Status Filter::DoPrepare()
{
return Status::OK;
}
Status Filter::DoStart()
{
return Status::OK;
}
Status Filter::DoPause()
{
return Status::OK;
}
Status Filter::DoPauseDragging()
{
return Status::OK;
}
Status Filter::DoResume()
{
return Status::OK;
}
Status Filter::DoResumeDragging()
{
return Status::OK;
}
Status Filter::DoStop()
{
return Status::OK;
}
Status Filter::DoFlush()
{
return Status::OK;
}
Status Filter::DoRelease()
{
return Status::OK;
}
Status Filter::DoPreroll()
{
return Status::OK;
}
Status Filter::DoWaitPrerollDone(bool render)
{
return Status::OK;
}
Status Filter::DoSetPlayRange(int64_t start, int64_t end)
{
return Status::OK;
}
Status Filter::DoProcessInputBuffer(int recvArg, bool dropFrame)
{
return Status::OK;
}
Status Filter::DoProcessOutputBuffer(int recvArg, bool dropFrame, bool byIdx, uint32_t idx, int64_t renderTimee)
{
return Status::OK;
}
// should only call in this cpp
void Filter::ChangeState(FilterState state)
{
AVTRANS_LOGI("%{public}s > %{public}d", name_.c_str(), state);
Media::AutoLock lock(stateMutex_);
curState_ = state;
cond_.NotifyOne();
}
Status Filter::WaitAllState(FilterState state)
{
Media::AutoLock lock(stateMutex_);
if (curState_ != state) {
cond_.WaitFor(lock, 30000, [this, state] { // 30000 ms timeout
return curState_ == state || curState_ == FilterState::ERROR;
});
if (curState_ != state) {
AVTRANS_LOGE("Filter(%{public}s) wait state %{public}d fail, curState %{public}d",
name_.c_str(), state, curState_);
return GetErrCode();
}
}
Status res = Status::OK;
for (auto iter : nextFiltersMap_) {
for (auto filter : iter.second) {
if (filter == nullptr) {
continue;
}
if (filter->WaitAllState(state) != Status::OK) {
res = filter->GetErrCode();
}
}
}
return res;
}
bool Filter::IsDesignatedState(FilterState state)
{
return curState_ == state;
}
void Filter::SetErrCode(Status errCode)
{
errCode_ = errCode;
}
Status Filter::GetErrCode()
{
return errCode_;
}
void Filter::SetParameter(const std::shared_ptr<Media::Meta>& meta)
{
meta_ = meta;
}
void Filter::GetParameter(std::shared_ptr<Media::Meta>& meta)
{
meta = meta_;
}
Status Filter::LinkNext(const std::shared_ptr<Filter>&, StreamType)
{
return Status::OK;
}
Status Filter::UpdateNext(const std::shared_ptr<Filter>&, StreamType)
{
return Status::OK;
}
Status Filter::UnLinkNext(const std::shared_ptr<Filter>&, StreamType)
{
return Status::OK;
}
FilterType Filter::GetFilterType()
{
return filterType_;
};
Status Filter::OnLinked(StreamType, const std::shared_ptr<Media::Meta>&, const std::shared_ptr<FilterLinkCallback>&)
{
return Status::OK;
};
Status Filter::OnUpdated(StreamType, const std::shared_ptr<Media::Meta>&, const std::shared_ptr<FilterLinkCallback>&)
{
return Status::OK;
}
Status Filter::OnUnLinked(StreamType, const std::shared_ptr<FilterLinkCallback>&)
{
return Status::OK;
}
} // namespace Pipeline
} // namespace DistributedHardware
} // namespace OHOS

View File

@ -0,0 +1,37 @@
/*
* 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 "filter_factory.h"
namespace OHOS {
namespace DistributedHardware {
namespace Pipeline {
FilterFactory& FilterFactory::Instance()
{
static FilterFactory instance;
return instance;
}
std::shared_ptr<Pipeline::Filter> FilterFactory::CreateFilterPriv(const std::string& filterName, const FilterType type)
{
auto it = generators.find(type);
if (it != generators.end()) {
return it->second(filterName, type);
}
return nullptr;
}
} // namespace Pipeline
} // namespace DistributedHardware
} // namespace OHOS

View File

@ -0,0 +1,84 @@
/*
* 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_AV_PIPELINE_H
#define OHOS_AV_PIPELINE_H
#include <string>
#include <vector>
#include <memory>
#include "osal/task/mutex.h"
#include "pipeline_status.h"
#include "filter.h"
namespace OHOS {
namespace DistributedHardware {
namespace Pipeline {
class FilterCallback;
class Pipeline : public EventReceiver {
public:
~Pipeline();
void Init(const std::shared_ptr<EventReceiver>& receiver,
const std::shared_ptr<FilterCallback>& callback, const std::string& groupId);
Status Prepare();
Status Start();
Status Pause();
Status Resume();
Status Stop();
Status Flush();
Status Release();
Status Preroll(bool render);
Status SetPlayRange(int64_t start, int64_t end);
Status AddHeadFilters(std::vector<std::shared_ptr<Filter>> filters);
Status RemoveHeadFilter(const std::shared_ptr<Filter>& filter);
Status LinkFilters(const std::shared_ptr<Filter>& preFilter,
const std::vector<std::shared_ptr<Filter>>& filters, StreamType type);
Status UpdateFilters(const std::shared_ptr<Filter>& preFilter,
const std::vector<std::shared_ptr<Filter>>& filters, StreamType type);
Status UnLinkFilters(const std::shared_ptr<Filter>& preFilter,
const std::vector<std::shared_ptr<Filter>>& filters, StreamType type);
void OnEvent(const Event& event) override;
static int32_t GetNextPipelineId();
private:
std::string groupId_;
Media::Mutex mutex_ {};
std::vector<std::shared_ptr<Filter>> filters_ {};
std::shared_ptr<EventReceiver> eventReceiver_ {nullptr};
std::shared_ptr<FilterCallback> filterCallback_ {nullptr};
};
} // namespace Pipeline
} // namespace DistributedHardware
} // namespace OHOS
#endif // OHOS_AV_PIPELINE_H

View File

@ -0,0 +1,377 @@
/*
* 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 "pipeline/include/pipeline.h"
#include <queue>
#include <stack>
#include "osal/task/autolock.h"
#include "osal/task/jobutils.h"
#include "av_trans_log.h"
#undef DH_LOG_TAG
#define DH_LOG_TAG "Pipeline"
namespace OHOS {
namespace DistributedHardware {
namespace Pipeline {
static std::atomic<uint16_t> pipeLineId = 0;
int32_t Pipeline::GetNextPipelineId()
{
return pipeLineId++;
}
Pipeline::~Pipeline()
{
}
void Pipeline::Init(const std::shared_ptr<EventReceiver>& receiver, const std::shared_ptr<FilterCallback>& callback,
const std::string& groupId)
{
AVTRANS_LOGI("Pipeline::Init");
eventReceiver_ = receiver;
filterCallback_ = callback;
groupId_ = groupId;
}
Status Pipeline::Prepare()
{
AVTRANS_LOGI("Prepare enter.");
Status ret = Status::OK;
Media::SubmitJobOnce([&] {
Media::AutoLock lock(mutex_);
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
continue;
}
ret = (*it)->Prepare();
if (ret != Status::OK) {
return;
}
}
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
continue;
}
ret = (*it)->WaitAllState(FilterState::READY);
if (ret != Status::OK) {
return;
}
}
});
AVTRANS_LOGI("Prepare done ret = %{public}d", ret);
return ret;
}
Status Pipeline::Start()
{
AVTRANS_LOGI("Start enter.");
Status ret = Status::OK;
Media::SubmitJobOnce([&] {
Media::AutoLock lock(mutex_);
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
continue;
}
ret = (*it)->Start();
if (ret != Status::OK) {
return;
}
}
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
continue;
}
ret = (*it)->WaitAllState(FilterState::RUNNING);
if (ret != Status::OK) {
return;
}
}
});
AVTRANS_LOGI("Start done ret = %{public}d", ret);
return ret;
}
Status Pipeline::Pause()
{
AVTRANS_LOGI("Pause enter.");
Status ret = Status::OK;
Media::SubmitJobOnce([&] {
Media::AutoLock lock(mutex_);
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
continue;
}
auto rtv = (*it)->Pause();
if (rtv != Status::OK) {
ret = rtv;
}
}
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
continue;
}
auto rtv = (*it)->WaitAllState(FilterState::PAUSED);
if (rtv != Status::OK) {
ret = rtv;
}
}
});
AVTRANS_LOGI("Pause done ret = %{public}d", ret);
return ret;
}
Status Pipeline::Resume()
{
AVTRANS_LOGI("Resume enter.");
Status ret = Status::OK;
Media::SubmitJobOnce([&] {
Media::AutoLock lock(mutex_);
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
continue;
}
ret = (*it)->Resume();
if (ret != Status::OK) {
return;
}
}
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
continue;
}
ret = (*it)->WaitAllState(FilterState::RUNNING);
if (ret != Status::OK) {
return;
}
}
});
AVTRANS_LOGI("Resume done ret = %{public}d", ret);
return ret;
}
Status Pipeline::Stop()
{
AVTRANS_LOGI("Stop enter.");
Status ret = Status::OK;
Media::SubmitJobOnce([&] {
Media::AutoLock lock(mutex_);
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
AVTRANS_LOGE("Pipeline error: %{public}zu", filters_.size());
continue;
}
auto rtv = (*it)->Stop();
if (rtv != Status::OK) {
ret = rtv;
}
}
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
continue;
}
auto rtv = (*it)->WaitAllState(FilterState::STOPPED);
if (rtv != Status::OK) {
ret = rtv;
}
}
filters_.clear();
});
AVTRANS_LOGI("Stop done ret = %{public}d", ret);
return ret;
}
Status Pipeline::Flush()
{
AVTRANS_LOGI("Flush enter.");
Media::SubmitJobOnce([&] {
Media::AutoLock lock(mutex_);
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
continue;
}
(*it)->Flush();
}
});
AVTRANS_LOGI("Flush end.");
return Status::OK;
}
Status Pipeline::Release()
{
AVTRANS_LOGI("Release enter.");
Media::SubmitJobOnce([&] {
Media::AutoLock lock(mutex_);
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
continue;
}
(*it)->Release();
}
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
continue;
}
(*it)->WaitAllState(FilterState::RELEASED);
}
filters_.clear();
});
AVTRANS_LOGI("Release done.");
return Status::OK;
}
Status Pipeline::Preroll(bool render)
{
AVTRANS_LOGI("Preroll enter.");
Status ret = Status::OK;
Media::AutoLock lock(mutex_);
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
continue;
}
auto rtv = (*it)->Preroll();
if (rtv != Status::OK) {
ret = rtv;
AVTRANS_LOGI("Preroll done ret = %{public}d", ret);
return ret;
}
}
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
continue;
}
auto rtv = (*it)->WaitPrerollDone(render);
if (rtv != Status::OK) {
ret = rtv;
AVTRANS_LOGI("Preroll done ret = %{public}d", ret);
return ret;
}
}
AVTRANS_LOGI("Preroll done ret = %{public}d", ret);
return ret;
}
Status Pipeline::SetPlayRange(int64_t start, int64_t end)
{
AVTRANS_LOGI("SetPlayRange enter.");
Media::SubmitJobOnce([&] {
Media::AutoLock lock(mutex_);
for (auto it = filters_.begin(); it != filters_.end(); ++it) {
if (*it == nullptr) {
continue;
}
(*it)->SetPlayRange(start, end);
}
});
AVTRANS_LOGI("SetPlayRange done.");
return Status::OK;
}
Status Pipeline::AddHeadFilters(std::vector<std::shared_ptr<Filter>> filtersIn)
{
AVTRANS_LOGI("AddHeadFilters enter.");
std::vector<std::shared_ptr<Filter>> filtersToAdd;
for (auto& filterIn : filtersIn) {
if (filterIn == nullptr) {
continue;
}
bool matched = false;
for (const auto& filter : filters_) {
if (filterIn == filter) {
matched = true;
break;
}
}
if (!matched) {
filtersToAdd.push_back(filterIn);
filterIn->LinkPipeLine(groupId_);
}
}
if (filtersToAdd.empty()) {
AVTRANS_LOGI("filter already exists");
return Status::OK;
}
Media::SubmitJobOnce([&] {
Media::AutoLock lock(mutex_);
this->filters_.insert(this->filters_.end(), filtersToAdd.begin(), filtersToAdd.end());
});
AVTRANS_LOGI("AddHeadFilters done.");
return Status::OK;
}
Status Pipeline::RemoveHeadFilter(const std::shared_ptr<Filter>& filter)
{
Media::SubmitJobOnce([&] {
Media::AutoLock lock(mutex_);
auto it = std::find_if(filters_.begin(), filters_.end(),
[&filter](const std::shared_ptr<Filter>& filterPtr) { return filterPtr == filter; });
if (it != filters_.end()) {
filters_.erase(it);
}
if (filter != nullptr) {
filter->Release();
filter->WaitAllState(FilterState::RELEASED);
filter->ClearAllNextFilters();
}
return Status::OK;
});
return Status::OK;
}
Status Pipeline::LinkFilters(const std::shared_ptr<Filter> &preFilter,
const std::vector<std::shared_ptr<Filter>> &nextFilters,
StreamType type)
{
TRUE_RETURN_V(preFilter == nullptr, Status::ERROR_NULL_POINTER);
for (auto nextFilter : nextFilters) {
TRUE_RETURN_V(nextFilter == nullptr, Status::ERROR_NULL_POINTER);
auto ret = preFilter->LinkNext(nextFilter, type);
nextFilter->LinkPipeLine(groupId_);
TRUE_RETURN_V(ret != Status::OK, ret);
}
return Status::OK;
}
Status Pipeline::UpdateFilters(const std::shared_ptr<Filter> &preFilter,
const std::vector<std::shared_ptr<Filter>> &nextFilters,
StreamType type)
{
TRUE_RETURN_V(preFilter == nullptr, Status::ERROR_NULL_POINTER);
for (auto nextFilter : nextFilters) {
preFilter->UpdateNext(nextFilter, type);
}
return Status::OK;
}
Status Pipeline::UnLinkFilters(const std::shared_ptr<Filter> &preFilter,
const std::vector<std::shared_ptr<Filter>> &nextFilters,
StreamType type)
{
TRUE_RETURN_V(preFilter == nullptr, Status::ERROR_NULL_POINTER);
for (auto nextFilter : nextFilters) {
preFilter->UnLinkNext(nextFilter, type);
}
return Status::OK;
}
void Pipeline::OnEvent(const Event& event)
{
}
} // namespace Pipeline
} // namespace DistributedHardware
} // namespace OHOS

View File

@ -62,16 +62,17 @@
},
"build": {
"sub_component": [
"//foundation/distributedhardware/distributed_hardware_fwk/utils:distributedhardwareutils",
"//foundation/distributedhardware/distributed_hardware_fwk/services/distributedhardwarefwkservice:distributedhardwarefwksvr",
"//foundation/distributedhardware/distributed_hardware_fwk/sa_profile:dhfwk_sa_profile",
"//foundation/distributedhardware/distributed_hardware_fwk/sa_profile:dhardware.cfg",
"//foundation/distributedhardware/distributed_hardware_fwk/application:DHardware_UI",
"//foundation/distributedhardware/distributed_hardware_fwk/av_transport/av_trans_engine/av_receiver:distributed_av_receiver",
"//foundation/distributedhardware/distributed_hardware_fwk/av_transport/av_trans_engine/av_sender:distributed_av_sender",
"//foundation/distributedhardware/distributed_hardware_fwk/av_transport/av_trans_handler/histreamer_ability_querier:histreamer_ability_querier",
"//foundation/distributedhardware/distributed_hardware_fwk/av_transport/framework:distributed_av_pipeline_fwk",
"//foundation/distributedhardware/distributed_hardware_fwk/interfaces/inner_kits:libdhfwk_sdk",
"//foundation/distributedhardware/distributed_hardware_fwk/interfaces/kits/napi:hardwaremanager",
"//foundation/distributedhardware/distributed_hardware_fwk/av_transport/av_trans_engine/av_sender:distributed_av_sender",
"//foundation/distributedhardware/distributed_hardware_fwk/av_transport/av_trans_engine/av_receiver:distributed_av_receiver",
"//foundation/distributedhardware/distributed_hardware_fwk/av_transport/av_trans_handler/histreamer_ability_querier:histreamer_ability_querier",
"//foundation/distributedhardware/distributed_hardware_fwk/application:DHardware_UI"
"//foundation/distributedhardware/distributed_hardware_fwk/sa_profile:dhardware.cfg",
"//foundation/distributedhardware/distributed_hardware_fwk/sa_profile:dhfwk_sa_profile",
"//foundation/distributedhardware/distributed_hardware_fwk/services/distributedhardwarefwkservice:distributedhardwarefwksvr",
"//foundation/distributedhardware/distributed_hardware_fwk/utils:distributedhardwareutils"
],
"inner_kits": [
{