• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "av_sync_manager.h"
17 
18 #include <set>
19 #include "nlohmann/json.hpp"
20 
21 #include "av_trans_control_center.h"
22 #include "av_trans_log.h"
23 
24 namespace OHOS {
25 namespace DistributedHardware {
26 #undef DH_LOG_TAG
27 #define DH_LOG_TAG "AVSyncManager"
28 
AVSyncManager()29 AVSyncManager::AVSyncManager()
30 {
31     AVTRANS_LOGI("AVSyncManager ctor.");
32     sourceMemory_ = { 0, 0, "" };
33     sinkMemory_ = { 0, 0, "" };
34 }
35 
~AVSyncManager()36 AVSyncManager::~AVSyncManager()
37 {
38     AVTRANS_LOGI("AVSyncManager dctor.");
39     streamInfoList_.clear();
40     CloseAVTransSharedMemory(sourceMemory_);
41     CloseAVTransSharedMemory(sinkMemory_);
42 }
43 
AddStreamInfo(const AVStreamInfo & stream)44 void AVSyncManager::AddStreamInfo(const AVStreamInfo &stream)
45 {
46     AVTRANS_LOGI("add new stream info: sceneType=%s, peerDevId=%s", stream.sceneType.c_str(),
47         GetAnonyString(stream.peerDevId).c_str());
48     {
49         std::lock_guard<std::mutex> lock(listMutex_);
50         streamInfoList_.push_back(stream);
51 
52         if (streamInfoList_.size() < AV_SYNC_STREAM_COUNT) {
53             AVTRANS_LOGI("No need enable sender av sync, stream info list size=%zu", streamInfoList_.size());
54             return;
55         }
56     }
57     EnableSenderAVSync();
58 }
59 
RemoveStreamInfo(const AVStreamInfo & stream)60 void AVSyncManager::RemoveStreamInfo(const AVStreamInfo &stream)
61 {
62     AVTRANS_LOGI("remove stream info: sceneType=%s, peerDevId=%s", stream.sceneType.c_str(),
63         GetAnonyString(stream.peerDevId).c_str());
64     {
65         std::lock_guard<std::mutex> lock(listMutex_);
66         for (auto iter = streamInfoList_.begin(); iter != streamInfoList_.end();) {
67             if (((*iter).sceneType == stream.sceneType) && ((*iter).peerDevId == stream.peerDevId)) {
68                 iter = streamInfoList_.erase(iter);
69             } else {
70                 iter++;
71             }
72         }
73     }
74     DisableSenderAVSync();
75 }
76 
EnableSenderAVSync()77 void AVSyncManager::EnableSenderAVSync()
78 {
79     std::string syncGroupInfo;
80     if (!MergeGroupInfo(syncGroupInfo)) {
81         AVTRANS_LOGI("No need start av sync.");
82         return;
83     }
84     AVTRANS_LOGI("merged av sync group info=%s", GetAnonyString(syncGroupInfo).c_str());
85     {
86         std::lock_guard<std::mutex> lock(listMutex_);
87         for (const auto &item : streamInfoList_) {
88             auto avMessage = std::make_shared<AVTransMessage>((uint32_t)AVTransTag::START_AV_SYNC,
89                 syncGroupInfo, item.peerDevId);
90             AVTransControlCenter::GetInstance().SendMessage(avMessage);
91         }
92     }
93 
94     sourceMemory_ = CreateAVTransSharedMemory("sourceSharedMemory", sizeof(uint32_t) + sizeof(int64_t));
95     AVTransControlCenter::GetInstance().SetParam2Engines(sourceMemory_);
96 }
97 
DisableSenderAVSync()98 void AVSyncManager::DisableSenderAVSync()
99 {
100     {
101         std::lock_guard<std::mutex> lock(listMutex_);
102         if (streamInfoList_.size() >= AV_SYNC_STREAM_COUNT) {
103             AVTRANS_LOGI("Cannot disable sender av sync, stream info list size=%zu", streamInfoList_.size());
104             return;
105         }
106         for (const auto &item : streamInfoList_) {
107             auto avMessage = std::make_shared<AVTransMessage>((uint32_t)AVTransTag::STOP_AV_SYNC, "", item.peerDevId);
108             AVTransControlCenter::GetInstance().SendMessage(avMessage);
109         }
110     }
111     CloseAVTransSharedMemory(sourceMemory_);
112     AVTransControlCenter::GetInstance().SetParam2Engines(AVTransSharedMemory{0, 0, "sourceSharedMemory"});
113 }
114 
HandleAvSyncMessage(const std::shared_ptr<AVTransMessage> & message)115 void AVSyncManager::HandleAvSyncMessage(const std::shared_ptr<AVTransMessage> &message)
116 {
117     if (message->type_ == (uint32_t)AVTransTag::START_AV_SYNC) {
118         EnableReceiverAVSync(message->content_);
119     } else if (message->type_ == (uint32_t)AVTransTag::STOP_AV_SYNC) {
120         DisableReceiverAVSync(message->content_);
121     }
122 }
123 
EnableReceiverAVSync(const std::string & groupInfo)124 void AVSyncManager::EnableReceiverAVSync(const std::string &groupInfo)
125 {
126     size_t size = (sizeof(uint32_t) + sizeof(int64_t)) * MAX_CLOCK_UNIT_COUNT;
127     sinkMemory_ = CreateAVTransSharedMemory("sinkSharedMemory", size);
128 
129     AVTransControlCenter::GetInstance().SetParam2Engines(sinkMemory_);
130     AVTransControlCenter::GetInstance().SetParam2Engines(AVTransTag::START_AV_SYNC, groupInfo);
131 }
132 
DisableReceiverAVSync(const std::string & groupInfo)133 void AVSyncManager::DisableReceiverAVSync(const std::string &groupInfo)
134 {
135     (void)groupInfo;
136     CloseAVTransSharedMemory(sinkMemory_);
137     AVTransControlCenter::GetInstance().SetParam2Engines(AVTransTag::STOP_AV_SYNC, "");
138     AVTransControlCenter::GetInstance().SetParam2Engines(AVTransSharedMemory{0, 0, "sinkSharedMemory"});
139 }
140 
MergeGroupInfo(std::string & syncGroupInfo)141 bool AVSyncManager::MergeGroupInfo(std::string &syncGroupInfo)
142 {
143     std::set<std::string> sceneTypeSet;
144     {
145         std::lock_guard<std::mutex> lock(listMutex_);
146         for (const auto &item : streamInfoList_) {
147             sceneTypeSet.insert(item.sceneType);
148         }
149     }
150     if (sceneTypeSet.size() < AV_SYNC_STREAM_COUNT) {
151         AVTRANS_LOGI("Can not merge av sync group info, because scene type count less than threshold.");
152         return false;
153     }
154 
155     if ((sceneTypeSet.find(SCENE_TYPE_D_MIC) != sceneTypeSet.end()) &&
156         (sceneTypeSet.find(SCENE_TYPE_D_SPEAKER) != sceneTypeSet.end())) {
157         AVTRANS_LOGI("Can not merge av sync group info, because scene type are conflicting.");
158         return false;
159     }
160 
161     bool source2Sink = (sceneTypeSet.find(SCENE_TYPE_D_SCREEN) != sceneTypeSet.end()) &&
162         (sceneTypeSet.find(SCENE_TYPE_D_SPEAKER) != sceneTypeSet.end());
163     bool sink2Source = (sceneTypeSet.find(SCENE_TYPE_D_CAMERA_STR) != sceneTypeSet.end()) &&
164         (sceneTypeSet.find(SCENE_TYPE_D_MIC) != sceneTypeSet.end());
165     if (!source2Sink && !sink2Source) {
166         AVTRANS_LOGI("Can not merge av sync group info, because scene type do not meet conditions.");
167         return false;
168     }
169 
170     std::set<std::string> groupInfoSet;
171     for (const auto &item : streamInfoList_) {
172         if ((item.sceneType == SCENE_TYPE_D_MIC) || (item.sceneType == SCENE_TYPE_D_SPEAKER)) {
173             nlohmann::json masterStr;
174             masterStr[KEY_SCENE_TYPE] = item.sceneType;
175             masterStr[KEY_PEER_DEV_ID] = item.peerDevId;
176             masterStr[KEY_START_FRAME_NUM] = 0;
177             masterStr[KEY_AV_SYNC_FLAG] = AvSyncFlag::MASTER;
178             groupInfoSet.insert(masterStr.dump());
179         } else if ((item.sceneType == SCENE_TYPE_D_SCREEN) || (item.sceneType == SCENE_TYPE_D_CAMERA_STR)) {
180             nlohmann::json slaveStr;
181             slaveStr[KEY_SCENE_TYPE] = item.sceneType;
182             slaveStr[KEY_PEER_DEV_ID] = item.peerDevId;
183             slaveStr[KEY_START_FRAME_NUM] = 0;
184             slaveStr[KEY_AV_SYNC_FLAG] = AvSyncFlag::SLAVE;
185             groupInfoSet.insert(slaveStr.dump());
186         } else {
187             continue;
188         }
189     }
190 
191     nlohmann::json jsonStr = {
192         { KEY_MY_DEV_ID, "" },
193         { KEY_GROUP_INFO_ARRAY, groupInfoSet },
194     };
195     syncGroupInfo = jsonStr.dump();
196     return true;
197 }
198 }
199 }