• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 "media_controller.h"
17 #include <chrono>
18 #include "common/common_macro.h"
19 #include "common/const_def.h"
20 #include "common/event_comm.h"
21 #include "common/media_log.h"
22 #include "configuration/include/config.h"
23 #include "magic_enum.hpp"
24 #include "media_channel.h"
25 #include "protocol/frame/h264_frame.h"
26 #include "utils/data_buffer.h"
27 
28 namespace OHOS {
29 namespace Sharing {
30 
MediaController(uint32_t mediaChannelId)31 MediaController::MediaController(uint32_t mediaChannelId)
32 {
33     SHARING_LOGD("trace.");
34     mediachannelId_ = mediaChannelId;
35 }
36 
~MediaController()37 MediaController::~MediaController()
38 {
39     SHARING_LOGD("trace.");
40     Release();
41     SHARING_LOGD("delete media controller, mediachannelId: %{public}u.", mediachannelId_);
42 }
43 
Init(AudioTrack audioTrack,VideoTrack videoTrack)44 bool MediaController::Init(AudioTrack audioTrack, VideoTrack videoTrack)
45 {
46     SHARING_LOGD("trace.");
47     audioTrack_ = audioTrack;
48     videoTrack_ = videoTrack;
49     if (CODEC_NONE == audioTrack_.codecId && CODEC_NONE == videoTrack_.codecId) {
50         SHARING_LOGW("no need to play.");
51         return false;
52     }
53 
54     if (CODEC_NONE != audioTrack_.codecId) {
55         audioPlayController_ = std::make_shared<AudioPlayController>(mediachannelId_);
56         if (!audioPlayController_->Init(audioTrack_)) {
57             SHARING_LOGE("audio play init error.");
58             return false;
59         }
60     }
61 
62     return true;
63 }
64 
Start()65 void MediaController::Start()
66 {
67     SHARING_LOGD("trace.");
68     auto mediaChannel = mediaChannel_.lock();
69     RETURN_IF_NULL(mediaChannel);
70     SHARING_LOGI("media play start, mediachannelId: %{public}u.", mediachannelId_);
71     if (nullptr == audioPlayController_ && 0 == videoPlayerMap_.size()) {
72         SHARING_LOGE("start must be after init.");
73         return;
74     }
75 
76     auto dispatcher = mediaChannel->GetDispatcher();
77     RETURN_IF_NULL(dispatcher);
78     {
79         std::lock_guard<std::mutex> lock(playAudioMutex_);
80         if (nullptr != audioPlayController_) {
81             if (audioPlayController_->Start(dispatcher)) {
82                 isPlaying_ = true;
83             }
84         }
85     }
86 
87     if (videoPlayerMap_.size() > 0) {
88         std::lock_guard<std::mutex> lock(playVideoMutex_);
89         for (auto &item : videoPlayerMap_) {
90             if (item.second->Start(dispatcher)) {
91                 isPlaying_ = true;
92             }
93         }
94     }
95 
96     SHARING_LOGI("media play start done, mediachannelId: %{public}u.", mediachannelId_);
97 }
98 
Stop()99 void MediaController::Stop()
100 {
101     SHARING_LOGD("trace.");
102     auto mediaChannel = mediaChannel_.lock();
103     RETURN_IF_NULL(mediaChannel);
104     SHARING_LOGI("media play stop, mediachannelId: %{public}u.", mediachannelId_);
105     auto dispatcher = mediaChannel->GetDispatcher();
106     RETURN_IF_NULL(dispatcher);
107     {
108         std::lock_guard<std::mutex> lock(playAudioMutex_);
109         if (isPlaying_ && (nullptr != audioPlayController_)) {
110             audioPlayController_->Stop(dispatcher);
111         }
112     }
113 
114     {
115         std::lock_guard<std::mutex> lock(playVideoMutex_);
116         if (isPlaying_) {
117             for (auto &item : videoPlayerMap_) {
118                 item.second->Stop(dispatcher);
119             }
120         }
121     }
122 
123     isPlaying_ = false;
124     SHARING_LOGI("media play stop done, mediachannelId: %{public}u.", mediachannelId_);
125 }
126 
Release()127 void MediaController::Release()
128 {
129     SHARING_LOGD("trace.");
130     if (nullptr != audioPlayController_) {
131         audioPlayController_->Release();
132         audioPlayController_.reset();
133     }
134 
135     {
136         std::lock_guard<std::mutex> lock(playVideoMutex_);
137         for (auto &item : videoPlayerMap_) {
138             item.second->Release();
139         }
140         videoPlayerMap_.clear();
141     }
142 
143     SHARING_LOGI("media play release done, mediachannelId: %{public}u.", mediachannelId_);
144 }
145 
AppendSurface(sptr<Surface> surface,SceneType sceneType)146 bool MediaController::AppendSurface(sptr<Surface> surface, SceneType sceneType)
147 {
148     SHARING_LOGD("trace.");
149     RETURN_FALSE_IF_NULL(surface);
150     if (CODEC_NONE == videoTrack_.codecId) {
151         SHARING_LOGW("no need to play video.");
152         return false;
153     }
154 
155     auto videoPlayController = std::make_shared<VideoPlayController>(mediachannelId_);
156     uint64_t surfaceId = surface->GetUniqueId();
157     {
158         std::lock_guard<std::mutex> lock(playVideoMutex_);
159         if (videoPlayerMap_.count(surfaceId)) {
160             SHARING_LOGE("surface is in use, %{public}" PRIx64 ".", surfaceId);
161             return false;
162         }
163 
164         bool keyFrame = sceneType == SceneType::BACKGROUND ? true : false;
165         if (videoPlayController->Init(videoTrack_) && videoPlayController->SetSurface(surface, keyFrame)) {
166             videoPlayerMap_.emplace(surfaceId, videoPlayController);
167         } else {
168             SHARING_LOGD("videoPlayController init failed, mediachannelId: %{public}u.", mediachannelId_);
169             return false;
170         }
171 
172         if (isPlaying_) {
173             auto mediaChannel = mediaChannel_.lock();
174             auto dispatcher = mediaChannel->GetDispatcher();
175             videoPlayController->Start(dispatcher);
176         }
177 
178         videoPlayController->SetMediaController(shared_from_this());
179         SHARING_LOGI("media play append surface done, mediachannelId: %{public}u.", mediachannelId_);
180     }
181 
182     return true;
183 }
184 
RemoveSurface(uint64_t surfaceId)185 void MediaController::RemoveSurface(uint64_t surfaceId)
186 {
187     SHARING_LOGD("trace.");
188     {
189         std::lock_guard<std::mutex> lock(playVideoMutex_);
190         auto videoPlayController = videoPlayerMap_.find(surfaceId);
191         if (videoPlayController != videoPlayerMap_.end()) {
192             auto mediaChannel = mediaChannel_.lock();
193             auto dispatcher = mediaChannel->GetDispatcher();
194             videoPlayController->second->Stop(dispatcher);
195             videoPlayController->second->Release();
196             videoPlayerMap_.erase(surfaceId);
197         }
198         SHARING_LOGI("media play remove surface done, mediachannelId: %{public}u.", mediachannelId_);
199     }
200 }
201 
SetVolume(float volume)202 void MediaController::SetVolume(float volume)
203 {
204     SHARING_LOGD("Volume: %{public}f.", volume);
205     if (audioPlayController_) {
206         audioPlayController_->SetVolume(volume);
207     }
208 }
209 
SetKeyMode(uint64_t surfaceId,bool mode)210 void MediaController::SetKeyMode(uint64_t surfaceId, bool mode)
211 {
212     SHARING_LOGD("trace.");
213     {
214         std::lock_guard<std::mutex> lock(playVideoMutex_);
215         auto videoPlayController = videoPlayerMap_.find(surfaceId);
216         if (videoPlayController != videoPlayerMap_.end()) {
217             videoPlayController->second->SetKeyMode(mode);
218         }
219         SHARING_LOGI("media play set key mode done, mediachannelId: %{public}u.", mediachannelId_);
220     }
221 }
222 
SetKeyRedirect(uint64_t surfaceId,bool keyRedirect)223 void MediaController::SetKeyRedirect(uint64_t surfaceId, bool keyRedirect)
224 {
225     SHARING_LOGD("trace.");
226     {
227         std::lock_guard<std::mutex> lock(playVideoMutex_);
228         auto videoPlayController = videoPlayerMap_.find(surfaceId);
229         if (videoPlayController != videoPlayerMap_.end()) {
230             videoPlayController->second->SetKeyRedirect(keyRedirect);
231         }
232         SHARING_LOGI("media play set key redirect done, mediachannelId: %{public}u.", mediachannelId_);
233     }
234 }
235 
OnPlayControllerNotify(ProsumerStatusMsg::Ptr & statusMsg)236 void MediaController::OnPlayControllerNotify(ProsumerStatusMsg::Ptr &statusMsg)
237 {
238     SHARING_LOGD("trace.");
239     RETURN_IF_NULL(statusMsg);
240     auto mediaChannel = mediaChannel_.lock();
241     RETURN_IF_NULL(mediaChannel);
242 
243     statusMsg->agentId = mediaChannel->GetSinkAgentId();
244     mediaChannel->OnMediaControllerNotify(statusMsg);
245 }
246 
247 } // namespace Sharing
248 } // namespace OHOS