• 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     videoAudioSync_ = std::make_shared<VideoAudioSync>();
62     if (nullptr != videoAudioSync_) {
63         videoAudioSync_->SetAudioPlayController(audioPlayController_);
64     }
65 
66     return true;
67 }
68 
Start()69 void MediaController::Start()
70 {
71     SHARING_LOGD("trace.");
72     auto mediaChannel = mediaChannel_.lock();
73     RETURN_IF_NULL(mediaChannel);
74     SHARING_LOGI("media play start, mediachannelId: %{public}u.", mediachannelId_);
75     if (nullptr == audioPlayController_ && 0 == videoPlayerMap_.size()) {
76         SHARING_LOGE("start must be after init.");
77         return;
78     }
79 
80     auto dispatcher = mediaChannel->GetDispatcher();
81     RETURN_IF_NULL(dispatcher);
82     {
83         std::lock_guard<std::mutex> lock(playAudioMutex_);
84         if (nullptr != audioPlayController_) {
85             if (audioPlayController_->Start(dispatcher)) {
86                 isPlaying_ = true;
87             }
88         }
89     }
90 
91     if (videoPlayerMap_.size() > 0) {
92         std::lock_guard<std::mutex> lock(playVideoMutex_);
93         for (auto &item : videoPlayerMap_) {
94             if (item.second->Start(dispatcher)) {
95                 isPlaying_ = true;
96             }
97         }
98     }
99 
100     SHARING_LOGI("media play start done, mediachannelId: %{public}u.", mediachannelId_);
101 }
102 
Stop()103 void MediaController::Stop()
104 {
105     SHARING_LOGD("trace.");
106     auto mediaChannel = mediaChannel_.lock();
107     RETURN_IF_NULL(mediaChannel);
108     SHARING_LOGI("media play stop, mediachannelId: %{public}u.", mediachannelId_);
109     auto dispatcher = mediaChannel->GetDispatcher();
110     RETURN_IF_NULL(dispatcher);
111     {
112         std::lock_guard<std::mutex> lock(playAudioMutex_);
113         if (isPlaying_ && (nullptr != audioPlayController_)) {
114             audioPlayController_->Stop(dispatcher);
115         }
116     }
117 
118     {
119         std::lock_guard<std::mutex> lock(playVideoMutex_);
120         if (isPlaying_) {
121             for (auto &item : videoPlayerMap_) {
122                 item.second->Stop(dispatcher);
123             }
124         }
125     }
126 
127     isPlaying_ = false;
128     SHARING_LOGI("media play stop done, mediachannelId: %{public}u.", mediachannelId_);
129 }
130 
Release()131 void MediaController::Release()
132 {
133     SHARING_LOGD("trace.");
134     if (nullptr != audioPlayController_) {
135         audioPlayController_->Release();
136         audioPlayController_.reset();
137     }
138 
139     {
140         std::lock_guard<std::mutex> lock(playVideoMutex_);
141         for (auto &item : videoPlayerMap_) {
142             item.second->Release();
143         }
144         videoPlayerMap_.clear();
145     }
146 
147     SHARING_LOGI("media play release done, mediachannelId: %{public}u.", mediachannelId_);
148 }
149 
AppendSurface(sptr<Surface> surface,SceneType sceneType)150 bool MediaController::AppendSurface(sptr<Surface> surface, SceneType sceneType)
151 {
152     SHARING_LOGD("trace.");
153     RETURN_FALSE_IF_NULL(surface);
154     if (CODEC_NONE == videoTrack_.codecId) {
155         SHARING_LOGW("no need to play video.");
156         return false;
157     }
158 
159     auto videoPlayController = std::make_shared<VideoPlayController>(mediachannelId_);
160     uint64_t surfaceId = surface->GetUniqueId();
161     {
162         std::lock_guard<std::mutex> lock(playVideoMutex_);
163         if (videoPlayerMap_.count(surfaceId)) {
164             SHARING_LOGE("surface is in use, %{public}" PRIx64 ".", surfaceId);
165             return false;
166         }
167 
168         bool keyFrame = sceneType == SceneType::BACKGROUND ? true : false;
169         if (videoPlayController->Init(videoTrack_) && videoPlayController->SetSurface(surface, keyFrame)) {
170             videoPlayController->SetVideoAudioSync(videoAudioSync_);
171             videoPlayerMap_.emplace(surfaceId, videoPlayController);
172         } else {
173             SHARING_LOGD("videoPlayController init failed, mediachannelId: %{public}u.", mediachannelId_);
174             return false;
175         }
176 
177         if (isPlaying_) {
178             auto mediaChannel = mediaChannel_.lock();
179             auto dispatcher = mediaChannel->GetDispatcher();
180             videoPlayController->Start(dispatcher);
181         }
182 
183         videoPlayController->SetMediaController(shared_from_this());
184         SHARING_LOGI("media play append surface done, mediachannelId: %{public}u.", mediachannelId_);
185     }
186 
187     return true;
188 }
189 
RemoveSurface(uint64_t surfaceId)190 void MediaController::RemoveSurface(uint64_t surfaceId)
191 {
192     SHARING_LOGD("trace.");
193     {
194         std::lock_guard<std::mutex> lock(playVideoMutex_);
195         auto videoPlayController = videoPlayerMap_.find(surfaceId);
196         if (videoPlayController != videoPlayerMap_.end()) {
197             auto mediaChannel = mediaChannel_.lock();
198             auto dispatcher = mediaChannel->GetDispatcher();
199             videoPlayController->second->Stop(dispatcher);
200             videoPlayController->second->Release();
201             videoPlayerMap_.erase(surfaceId);
202         }
203         SHARING_LOGI("media play remove surface done, mediachannelId: %{public}u.", mediachannelId_);
204     }
205 }
206 
SetVolume(float volume)207 void MediaController::SetVolume(float volume)
208 {
209     SHARING_LOGD("Volume: %{public}f.", volume);
210     if (audioPlayController_) {
211         audioPlayController_->SetVolume(volume);
212     }
213 }
214 
SetKeyMode(uint64_t surfaceId,bool mode)215 void MediaController::SetKeyMode(uint64_t surfaceId, bool mode)
216 {
217     SHARING_LOGD("trace.");
218     {
219         std::lock_guard<std::mutex> lock(playVideoMutex_);
220         auto videoPlayController = videoPlayerMap_.find(surfaceId);
221         if (videoPlayController != videoPlayerMap_.end()) {
222             videoPlayController->second->SetKeyMode(mode);
223         }
224         SHARING_LOGI("media play set key mode done, mediachannelId: %{public}u.", mediachannelId_);
225     }
226 }
227 
SetKeyRedirect(uint64_t surfaceId,bool keyRedirect)228 void MediaController::SetKeyRedirect(uint64_t surfaceId, bool keyRedirect)
229 {
230     SHARING_LOGD("trace.");
231     {
232         std::lock_guard<std::mutex> lock(playVideoMutex_);
233         auto videoPlayController = videoPlayerMap_.find(surfaceId);
234         if (videoPlayController != videoPlayerMap_.end()) {
235             videoPlayController->second->SetKeyRedirect(keyRedirect);
236         }
237         SHARING_LOGI("media play set key redirect done, mediachannelId: %{public}u.", mediachannelId_);
238     }
239 }
240 
OnPlayControllerNotify(ProsumerStatusMsg::Ptr & statusMsg)241 void MediaController::OnPlayControllerNotify(ProsumerStatusMsg::Ptr &statusMsg)
242 {
243     SHARING_LOGD("trace.");
244     RETURN_IF_NULL(statusMsg);
245     auto mediaChannel = mediaChannel_.lock();
246     RETURN_IF_NULL(mediaChannel);
247 
248     statusMsg->agentId = mediaChannel->GetSinkAgentId();
249     mediaChannel->OnMediaControllerNotify(statusMsg);
250 }
251 
252 } // namespace Sharing
253 } // namespace OHOS