1 /*
2 * Copyright (C) 2021 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 "player_engine_gst_impl.h"
17
18 #include <unistd.h>
19 #include "media_log.h"
20 #include "media_errors.h"
21 #include "directory_ex.h"
22 #include "audio_system_manager.h"
23 #include "player_sinkprovider.h"
24 #include "av_common.h"
25
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "PlayerEngineGstImpl"};
28 }
29
30 namespace OHOS {
31 namespace Media {
32 constexpr float EPSINON = 0.0001;
33 constexpr float SPEED_0_75_X = 0.75;
34 constexpr float SPEED_1_00_X = 1.00;
35 constexpr float SPEED_1_25_X = 1.25;
36 constexpr float SPEED_1_75_X = 1.75;
37 constexpr float SPEED_2_00_X = 2.00;
38 constexpr size_t MAX_URI_SIZE = 4096;
39 constexpr int32_t MSEC_PER_USEC = 1000;
40 constexpr int32_t MSEC_PER_NSEC = 1000000;
41 constexpr int32_t BUFFER_TIME_DEFAULT = 15000; // 15s
42 constexpr uint32_t INTERRUPT_EVENT_SHIFT = 8;
43 constexpr int32_t POSITION_REPORT_PER_TIMES = 1;
44
PlayerEngineGstImpl(int32_t uid,int32_t pid,uint32_t tokenId)45 PlayerEngineGstImpl::PlayerEngineGstImpl(int32_t uid, int32_t pid, uint32_t tokenId)
46 : appuid_(uid), apppid_(pid), apptokenid_(tokenId)
47 {
48 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
49 }
50
~PlayerEngineGstImpl()51 PlayerEngineGstImpl::~PlayerEngineGstImpl()
52 {
53 (void)OnReset();
54 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
55 }
56
IsFileUrl(const std::string & url) const57 bool PlayerEngineGstImpl::IsFileUrl(const std::string &url) const
58 {
59 return url.find("://") == std::string::npos || url.find("file://") == 0;
60 }
61
GetRealPath(const std::string & url,std::string & realUrlPath) const62 int32_t PlayerEngineGstImpl::GetRealPath(const std::string &url, std::string &realUrlPath) const
63 {
64 std::string fileHead = "file://";
65 std::string tempUrlPath;
66
67 if (url.find(fileHead) == 0 && url.size() > fileHead.size()) {
68 tempUrlPath = url.substr(fileHead.size());
69 } else {
70 tempUrlPath = url;
71 }
72
73 bool ret = PathToRealPath(tempUrlPath, realUrlPath);
74 CHECK_AND_RETURN_RET_LOG(ret, MSERR_OPEN_FILE_FAILED,
75 "invalid url. The Url (%{public}s) path may be invalid.", url.c_str());
76
77 if (access(realUrlPath.c_str(), R_OK) != 0) {
78 return MSERR_FILE_ACCESS_FAILED;
79 }
80
81 return MSERR_OK;
82 }
83
SetSource(const std::string & url)84 int32_t PlayerEngineGstImpl::SetSource(const std::string &url)
85 {
86 std::unique_lock<std::mutex> lock(mutex_);
87 CHECK_AND_RETURN_RET_LOG(!url.empty(), MSERR_INVALID_VAL, "input url is empty!");
88 CHECK_AND_RETURN_RET_LOG(url.length() <= MAX_URI_SIZE, MSERR_INVALID_VAL, "input url length is invalid!");
89
90 int32_t ret = MSERR_OK;
91 if (IsFileUrl(url)) {
92 std::string realUriPath;
93 ret = GetRealPath(url, realUriPath);
94 if (ret != MSERR_OK) {
95 return ret;
96 }
97 url_ = "file://" + realUriPath;
98 } else {
99 url_ = url;
100 }
101
102 MEDIA_LOGD("set player source: %{public}s", url_.c_str());
103 return ret;
104 }
105
SetSource(const std::shared_ptr<IMediaDataSource> & dataSrc)106 int32_t PlayerEngineGstImpl::SetSource(const std::shared_ptr<IMediaDataSource> &dataSrc)
107 {
108 std::unique_lock<std::mutex> lock(mutex_);
109 CHECK_AND_RETURN_RET_LOG(dataSrc != nullptr, MSERR_INVALID_VAL, "input dataSrc is empty!");
110 appsrcWrap_ = GstAppsrcEngine::Create(dataSrc);
111 CHECK_AND_RETURN_RET_LOG(appsrcWrap_ != nullptr, MSERR_NO_MEMORY, "new appsrcwrap failed!");
112 return MSERR_OK;
113 }
114
AddSubSource(const std::string & url)115 int32_t PlayerEngineGstImpl::AddSubSource(const std::string &url)
116 {
117 std::unique_lock<std::mutex> lock(mutex_);
118 CHECK_AND_RETURN_RET_LOG(playBinCtrler_ != nullptr, MSERR_INVALID_VAL, "playBinCtrler_ is nullptr");
119
120 std::string subUrl = url;
121 int32_t ret = MSERR_OK;
122
123 if (IsFileUrl(url)) {
124 std::string realUriPath;
125 ret = GetRealPath(url, realUriPath);
126 if (ret != MSERR_OK) {
127 return ret;
128 }
129 subUrl = "file://" + realUriPath;
130 }
131
132 MEDIA_LOGD("add subtitle source: %{public}s", subUrl.c_str());
133 return playBinCtrler_->AddSubSource(subUrl);
134 }
135
SetObs(const std::weak_ptr<IPlayerEngineObs> & obs)136 int32_t PlayerEngineGstImpl::SetObs(const std::weak_ptr<IPlayerEngineObs> &obs)
137 {
138 std::unique_lock<std::mutex> lock(mutex_);
139 obs_ = obs;
140 return MSERR_OK;
141 }
142
SetVideoSurface(sptr<Surface> surface)143 int32_t PlayerEngineGstImpl::SetVideoSurface(sptr<Surface> surface)
144 {
145 std::unique_lock<std::mutex> lock(mutex_);
146 CHECK_AND_RETURN_RET_LOG(surface != nullptr, MSERR_INVALID_VAL, "surface is nullptr");
147
148 producerSurface_ = surface;
149 if (appsrcWrap_) {
150 appsrcWrap_->SetVideoMode();
151 }
152 return MSERR_OK;
153 }
154
PrepareAsync()155 int32_t PlayerEngineGstImpl::PrepareAsync()
156 {
157 std::unique_lock<std::mutex> lock(mutex_);
158 MEDIA_LOGD("Prepare in");
159
160 int32_t ret = PlayBinCtrlerInit();
161 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_VAL, "PlayBinCtrlerInit failed");
162
163 CHECK_AND_RETURN_RET_LOG(playBinCtrler_ != nullptr, MSERR_INVALID_VAL, "playBinCtrler_ is nullptr");
164 ret = playBinCtrler_->PrepareAsync();
165 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, ret, "PrepareAsync failed");
166
167 // The duration of some resources without header information cannot be obtained.
168 MEDIA_LOGD("Prepared ok out");
169 return MSERR_OK;
170 }
171
HandleErrorMessage(const PlayBinMessage & msg)172 void PlayerEngineGstImpl::HandleErrorMessage(const PlayBinMessage &msg)
173 {
174 MEDIA_LOGE("error happended, cancel inprocessing job");
175
176 int32_t errorCode = msg.code;
177 std::string errorMsg = "Unknown Error";
178 if (msg.subType == PlayBinMsgErrorSubType::PLAYBIN_SUB_MSG_ERROR_WITH_MESSAGE) {
179 errorMsg = std::any_cast<std::string>(msg.extra);
180 }
181
182 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
183 Format format;
184 if (notifyObs != nullptr) {
185 notifyObs->OnErrorMessage(errorCode, errorMsg);
186 notifyObs->OnInfo(INFO_TYPE_STATE_CHANGE, PLAYER_STATE_ERROR, format);
187 }
188 }
189
HandleInfoMessage(const PlayBinMessage & msg)190 void PlayerEngineGstImpl::HandleInfoMessage(const PlayBinMessage &msg)
191 {
192 MEDIA_LOGI("info msg type:%{public}d, value:%{public}d", msg.type, msg.code);
193
194 int32_t status = msg.code;
195 Format format;
196 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
197 if (notifyObs != nullptr) {
198 notifyObs->OnInfo(static_cast<PlayerOnInfoType>(msg.type), status, format);
199 }
200 }
201
HandleSeekDoneMessage(const PlayBinMessage & msg)202 void PlayerEngineGstImpl::HandleSeekDoneMessage(const PlayBinMessage &msg)
203 {
204 MEDIA_LOGI("seek done, seek position = %{public}dms", msg.code);
205
206 codecCtrl_.EnhanceSeekPerformance(false);
207
208 int32_t status = msg.code;
209 Format format;
210 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
211 if (notifyObs != nullptr) {
212 notifyObs->OnInfo(INFO_TYPE_SEEKDONE, status, format);
213 }
214 }
215
HandleSpeedDoneMessage(const PlayBinMessage & msg)216 void PlayerEngineGstImpl::HandleSpeedDoneMessage(const PlayBinMessage &msg)
217 {
218 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
219 codecCtrl_.EnhanceSeekPerformance(false);
220 if (notifyObs != nullptr) {
221 Format format;
222 double rate = std::any_cast<double>(msg.extra);
223 PlaybackRateMode speedMode = ChangeSpeedToMode(rate);
224 notifyObs->OnInfo(INFO_TYPE_SPEEDDONE, speedMode, format);
225 }
226 }
227
HandleBufferingStart(const PlayBinMessage & msg)228 void PlayerEngineGstImpl::HandleBufferingStart(const PlayBinMessage &msg)
229 {
230 (void)msg;
231 Format format;
232 (void)format.PutIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_START), 0);
233 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
234 if (notifyObs != nullptr) {
235 notifyObs->OnInfo(INFO_TYPE_BUFFERING_UPDATE, 0, format);
236 }
237 }
238
HandleBufferingEnd(const PlayBinMessage & msg)239 void PlayerEngineGstImpl::HandleBufferingEnd(const PlayBinMessage &msg)
240 {
241 (void)msg;
242 Format format;
243 (void)format.PutIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_END), 0);
244 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
245 if (notifyObs != nullptr) {
246 notifyObs->OnInfo(INFO_TYPE_BUFFERING_UPDATE, 0, format);
247 }
248 updatePercent_ = -1; // invalid percent
249 }
250
HandleBufferingTime(const PlayBinMessage & msg)251 void PlayerEngineGstImpl::HandleBufferingTime(const PlayBinMessage &msg)
252 {
253 if (!isAdaptiveLiveStream_) {
254 std::pair<uint32_t, int64_t> bufferingTimePair = std::any_cast<std::pair<uint32_t, int64_t>>(msg.extra);
255 uint32_t mqNumId = bufferingTimePair.first;
256 uint64_t bufferingTime = bufferingTimePair.second / MSEC_PER_NSEC;
257
258 if (bufferingTime > BUFFER_TIME_DEFAULT) {
259 bufferingTime = BUFFER_TIME_DEFAULT;
260 }
261
262 mqBufferingTime_[mqNumId] = bufferingTime;
263 MEDIA_LOGD("ProcessBufferingTime(%{public}" PRIu64 " ms), mqNumId = %{public}u, "
264 "mqNum = %{public}u", bufferingTime, mqNumId, mqNum_);
265
266 if (mqBufferingTime_.size() == mqNum_) {
267 uint64_t mqBufferingTime = mqBufferingTime_[mqNumId];
268 if (bufferingTime_ != mqBufferingTime) {
269 bufferingTime_ = mqBufferingTime;
270 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
271 CHECK_AND_RETURN_LOG(notifyObs != nullptr, "notifyObs is nullptr");
272 Format format;
273 (void)format.PutIntValue(std::string(PlayerKeys::PLAYER_CACHED_DURATION),
274 static_cast<int32_t>(mqBufferingTime));
275 notifyObs->OnInfo(INFO_TYPE_BUFFERING_UPDATE, 0, format);
276 }
277 }
278 }
279 }
280
HandleBufferingPercent(const PlayBinMessage & msg)281 void PlayerEngineGstImpl::HandleBufferingPercent(const PlayBinMessage &msg)
282 {
283 int32_t curPercent = msg.code;
284 if (curPercent != updatePercent_) {
285 updatePercent_ = curPercent;
286 std::shared_ptr<IPlayerEngineObs> tempObs = obs_.lock();
287 if (tempObs != nullptr) {
288 Format format;
289 (void)format.PutIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT), updatePercent_);
290 MEDIA_LOGI("updatePercent_ = %{public}d, 0x%{public}06" PRIXPTR "", updatePercent_, FAKE_POINTER(this));
291 tempObs->OnInfo(INFO_TYPE_BUFFERING_UPDATE, 0, format);
292 }
293 }
294 }
295
HandleBufferingUsedMqNum(const PlayBinMessage & msg)296 void PlayerEngineGstImpl::HandleBufferingUsedMqNum(const PlayBinMessage &msg)
297 {
298 mqNum_ = std::any_cast<uint32_t>(msg.extra);
299 }
300
HandleVideoRenderingStart(const PlayBinMessage & msg)301 void PlayerEngineGstImpl::HandleVideoRenderingStart(const PlayBinMessage &msg)
302 {
303 (void)msg;
304 Format format;
305 MEDIA_LOGD("video rendering start");
306 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
307 if (notifyObs != nullptr) {
308 notifyObs->OnInfo(INFO_TYPE_MESSAGE, PlayerMessageType::PLAYER_INFO_VIDEO_RENDERING_START, format);
309 }
310 }
311
HandleVideoSizeChanged(const PlayBinMessage & msg)312 void PlayerEngineGstImpl::HandleVideoSizeChanged(const PlayBinMessage &msg)
313 {
314 std::pair<int32_t, int32_t> resolution = std::any_cast<std::pair<int32_t, int32_t>>(msg.extra);
315 Format format;
316 (void)format.PutIntValue(std::string(PlayerKeys::PLAYER_WIDTH), resolution.first);
317 (void)format.PutIntValue(std::string(PlayerKeys::PLAYER_HEIGHT), resolution.second);
318 MEDIA_LOGD("video size changed, width = %{public}d, height = %{public}d", resolution.first, resolution.second);
319 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
320 if (notifyObs != nullptr) {
321 notifyObs->OnInfo(INFO_TYPE_RESOLUTION_CHANGE, 0, format);
322 }
323 videoWidth_ = resolution.first;
324 videoHeight_ = resolution.second;
325 }
326
HandleBitRateCollect(const PlayBinMessage & msg)327 void PlayerEngineGstImpl::HandleBitRateCollect(const PlayBinMessage &msg)
328 {
329 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
330 if (notifyObs != nullptr) {
331 notifyObs->OnInfo(INFO_TYPE_BITRATE_COLLECT, 0, std::any_cast<Format>(msg.extra));
332 }
333 }
334
HandleIsLiveStream(const PlayBinMessage & msg)335 void PlayerEngineGstImpl::HandleIsLiveStream(const PlayBinMessage &msg)
336 {
337 (void)msg;
338 isAdaptiveLiveStream_ = true;
339 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
340 Format format;
341 if (notifyObs != nullptr) {
342 notifyObs->OnInfo(INFO_TYPE_IS_LIVE_STREAM, 0, format);
343 }
344 }
345
HandleTrackChanged(const PlayBinMessage & msg)346 void PlayerEngineGstImpl::HandleTrackChanged(const PlayBinMessage &msg)
347 {
348 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
349 if (notifyObs != nullptr) {
350 notifyObs->OnInfo(INFO_TYPE_TRACKCHANGE, 0, std::any_cast<Format>(msg.extra));
351 }
352 }
353
HandleDefaultTrack(const PlayBinMessage & msg)354 void PlayerEngineGstImpl::HandleDefaultTrack(const PlayBinMessage &msg)
355 {
356 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
357 if (notifyObs != nullptr) {
358 notifyObs->OnInfo(INFO_TYPE_DEFAULTTRACK, 0, std::any_cast<Format>(msg.extra));
359 }
360 }
361
HandleTrackDone(const PlayBinMessage & msg)362 void PlayerEngineGstImpl::HandleTrackDone(const PlayBinMessage &msg)
363 {
364 (void)msg;
365 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
366 if (notifyObs != nullptr) {
367 Format format;
368 notifyObs->OnInfo(INFO_TYPE_TRACK_DONE, 0, format);
369 }
370 }
371
HandleAddSubDone(const PlayBinMessage & msg)372 void PlayerEngineGstImpl::HandleAddSubDone(const PlayBinMessage &msg)
373 {
374 (void)msg;
375 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
376 if (notifyObs != nullptr) {
377 Format format;
378 notifyObs->OnInfo(INFO_TYPE_ADD_SUBTITLE_DONE, 0, format);
379 }
380 }
381
HandleOnError(const PlayBinMessage & msg)382 void PlayerEngineGstImpl::HandleOnError(const PlayBinMessage &msg)
383 {
384 Format format;
385 (void)format.PutIntValue(std::string(PlayerKeys::PLAYER_ERROR_TYPE), msg.code);
386 (void)format.PutStringValue(std::string(PlayerKeys::PLAYER_ERROR_MSG), std::any_cast<std::string>(msg.extra));
387
388 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
389 if (notifyObs != nullptr) {
390 notifyObs->OnInfo(INFO_TYPE_ERROR_MSG, 0, format);
391 }
392 }
393
HandleTrackNumUpdate(const PlayBinMessage & msg)394 void PlayerEngineGstImpl::HandleTrackNumUpdate(const PlayBinMessage &msg)
395 {
396 int32_t textTrackNum = msg.code;
397
398 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
399 if (notifyObs != nullptr) {
400 Format format;
401 MEDIA_LOGI("track num update, textTrackNum = %{public}d", textTrackNum);
402 notifyObs->OnInfo(INFO_TYPE_TRACK_NUM_UPDATE, textTrackNum, format);
403 }
404 }
405
HandleTrackInfoUpdate(const PlayBinMessage & msg)406 void PlayerEngineGstImpl::HandleTrackInfoUpdate(const PlayBinMessage &msg)
407 {
408 std::vector<Format> trackInfo = std::any_cast<std::vector<Format>>(msg.extra);
409 Format format;
410 format.PutFormatVector(std::string(PlayerKeys::PLAYER_TRACK_INFO), trackInfo);
411
412 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
413 if (notifyObs != nullptr) {
414 notifyObs->OnInfo(INFO_TYPE_TRACK_INFO_UPDATE, 0, format);
415 }
416 }
417
HandleSubtitleUpdate(const PlayBinMessage & msg)418 void PlayerEngineGstImpl::HandleSubtitleUpdate(const PlayBinMessage &msg)
419 {
420 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
421 if (notifyObs != nullptr) {
422 notifyObs->OnInfo(INFO_TYPE_SUBTITLE_UPDATE, 0, std::any_cast<Format>(msg.extra));
423 }
424 }
425
HandleSubTypeMessage(const PlayBinMessage & msg)426 void PlayerEngineGstImpl::HandleSubTypeMessage(const PlayBinMessage &msg)
427 {
428 if (subMsgHandler_.count(msg.subType) > 0) {
429 (this->*subMsgHandler_[msg.subType])(msg);
430 } else {
431 MEDIA_LOGI("No this sub msg handler, subType = %{public}d", msg.subType);
432 }
433 }
434
HandleAudioMessage(const PlayBinMessage & msg)435 void PlayerEngineGstImpl::HandleAudioMessage(const PlayBinMessage &msg)
436 {
437 if (msg.subType == PLAYBIN_MSG_INTERRUPT_EVENT) {
438 HandleInterruptMessage(msg);
439 }
440 }
441
HandleInterruptMessage(const PlayBinMessage & msg)442 void PlayerEngineGstImpl::HandleInterruptMessage(const PlayBinMessage &msg)
443 {
444 MEDIA_LOGI("Audio interrupt event in");
445 uint32_t value = std::any_cast<uint32_t>(msg.extra);
446 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
447 if (notifyObs != nullptr) {
448 Format format;
449 int32_t hintType = value & 0x000000FF;
450 int32_t forceType = (value >> INTERRUPT_EVENT_SHIFT) & 0x000000FF;
451 int32_t eventType = value >> (INTERRUPT_EVENT_SHIFT * 2);
452 (void)format.PutIntValue(PlayerKeys::AUDIO_INTERRUPT_TYPE, eventType);
453 (void)format.PutIntValue(PlayerKeys::AUDIO_INTERRUPT_FORCE, forceType);
454 (void)format.PutIntValue(PlayerKeys::AUDIO_INTERRUPT_HINT, hintType);
455 notifyObs->OnInfo(INFO_TYPE_INTERRUPT_EVENT, 0, format);
456 }
457 }
458
HandlePositionUpdateMessage(const PlayBinMessage & msg)459 void PlayerEngineGstImpl::HandlePositionUpdateMessage(const PlayBinMessage &msg)
460 {
461 if (!isAdaptiveLiveStream_) {
462 currentTime_ = msg.code;
463 int32_t duration = std::any_cast<int32_t>(msg.extra);
464 MEDIA_LOGD("update position %{public}d ms, duration %{public}d ms", currentTime_, duration);
465
466 if (duration != duration_) {
467 duration_ = duration;
468 Format format;
469 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
470 if (notifyObs != nullptr) {
471 notifyObs->OnInfo(INFO_TYPE_DURATION_UPDATE, duration_, format);
472 }
473 }
474
475 // 10: report once at 1000ms
476 if (currentTimeOnInfoCnt_ % POSITION_REPORT_PER_TIMES == 0 ||
477 msg.subType == PLAYBIN_SUB_MSG_POSITION_UPDATE_FORCE) {
478 Format format;
479 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
480 if (notifyObs != nullptr) {
481 notifyObs->OnInfo(INFO_TYPE_POSITION_UPDATE, currentTime_, format);
482 }
483 if (currentTimeOnInfoCnt_ % POSITION_REPORT_PER_TIMES == 0) {
484 currentTimeOnInfoCnt_ = 0;
485 }
486 }
487 if (msg.subType == PLAYBIN_SUB_MSG_POSITION_UPDATE_UNFORCE) {
488 currentTimeOnInfoCnt_++;
489 }
490 }
491 }
492
493 using MsgNotifyFunc = std::function<void(const PlayBinMessage&)>;
494
OnNotifyMessage(const PlayBinMessage & msg)495 void PlayerEngineGstImpl::OnNotifyMessage(const PlayBinMessage &msg)
496 {
497 const std::unordered_map<int32_t, MsgNotifyFunc> MSG_NOTIFY_FUNC_TABLE = {
498 { PLAYBIN_MSG_ERROR, std::bind(&PlayerEngineGstImpl::HandleErrorMessage, this, std::placeholders::_1) },
499 { PLAYBIN_MSG_SEEKDONE, std::bind(&PlayerEngineGstImpl::HandleSeekDoneMessage, this, std::placeholders::_1) },
500 { PLAYBIN_MSG_SPEEDDONE, std::bind(&PlayerEngineGstImpl::HandleSpeedDoneMessage, this, std::placeholders::_1) },
501 { PLAYBIN_MSG_BITRATEDONE, std::bind(&PlayerEngineGstImpl::HandleInfoMessage, this, std::placeholders::_1)},
502 { PLAYBIN_MSG_EOS, std::bind(&PlayerEngineGstImpl::HandleInfoMessage, this, std::placeholders::_1) },
503 { PLAYBIN_MSG_STATE_CHANGE, std::bind(&PlayerEngineGstImpl::HandleInfoMessage, this, std::placeholders::_1) },
504 { PLAYBIN_MSG_SUBTYPE, std::bind(&PlayerEngineGstImpl::HandleSubTypeMessage, this, std::placeholders::_1) },
505 { PLAYBIN_MSG_AUDIO_SINK, std::bind(&PlayerEngineGstImpl::HandleAudioMessage, this, std::placeholders::_1) },
506 { PLAYBIN_MSG_POSITION_UPDATE, std::bind(&PlayerEngineGstImpl::HandlePositionUpdateMessage, this,
507 std::placeholders::_1) },
508 };
509 if (MSG_NOTIFY_FUNC_TABLE.count(msg.type) != 0) {
510 MSG_NOTIFY_FUNC_TABLE.at(msg.type)(msg);
511 }
512 }
513
PlayBinCtrlerInit()514 int32_t PlayerEngineGstImpl::PlayBinCtrlerInit()
515 {
516 if (playBinCtrler_) {
517 return MSERR_OK;
518 }
519
520 MEDIA_LOGD("PlayBinCtrlerInit in");
521 int ret = PlayBinCtrlerPrepare();
522 if (ret != MSERR_OK) {
523 MEDIA_LOGE("PlayBinCtrlerPrepare failed");
524 PlayBinCtrlerDeInit();
525 return MSERR_INVALID_VAL;
526 }
527
528 subMsgHandler_[PLAYBIN_SUB_MSG_BUFFERING_START] = &PlayerEngineGstImpl::HandleBufferingStart;
529 subMsgHandler_[PLAYBIN_SUB_MSG_BUFFERING_END] = &PlayerEngineGstImpl::HandleBufferingEnd;
530 subMsgHandler_[PLAYBIN_SUB_MSG_BUFFERING_TIME] = &PlayerEngineGstImpl::HandleBufferingTime;
531 subMsgHandler_[PLAYBIN_SUB_MSG_BUFFERING_PERCENT] = &PlayerEngineGstImpl::HandleBufferingPercent;
532 subMsgHandler_[PLAYBIN_SUB_MSG_BUFFERING_USED_MQ_NUM] = &PlayerEngineGstImpl::HandleBufferingUsedMqNum;
533 subMsgHandler_[PLAYBIN_SUB_MSG_VIDEO_RENDERING_START] = &PlayerEngineGstImpl::HandleVideoRenderingStart;
534 subMsgHandler_[PLAYBIN_SUB_MSG_VIDEO_SIZE_CHANGED] = &PlayerEngineGstImpl::HandleVideoSizeChanged;
535 subMsgHandler_[PLAYBIN_SUB_MSG_BITRATE_COLLECT] = &PlayerEngineGstImpl::HandleBitRateCollect;
536 subMsgHandler_[PLAYBIN_SUB_MSG_IS_LIVE_STREAM] = &PlayerEngineGstImpl::HandleIsLiveStream;
537 subMsgHandler_[PLAYBIN_SUB_MSG_AUDIO_CHANGED] = &PlayerEngineGstImpl::HandleTrackChanged;
538 subMsgHandler_[PLAYBIN_SUB_MSG_SUBTITLE_CHANGED] = &PlayerEngineGstImpl::HandleTrackChanged;
539 subMsgHandler_[PLAYBIN_SUB_MSG_DEFAULE_TRACK] = &PlayerEngineGstImpl::HandleDefaultTrack;
540 subMsgHandler_[PLAYBIN_SUB_MSG_TRACK_DONE] = &PlayerEngineGstImpl::HandleTrackDone;
541 subMsgHandler_[PLAYBIN_SUB_MSG_ADD_SUBTITLE_DONE] = &PlayerEngineGstImpl::HandleAddSubDone;
542 subMsgHandler_[PLAYBIN_SUB_MSG_ONERROR] = &PlayerEngineGstImpl::HandleOnError;
543 subMsgHandler_[PLAYBIN_SUB_MSG_TRACK_NUM_UPDATE] = &PlayerEngineGstImpl::HandleTrackNumUpdate;
544 subMsgHandler_[PLAYBIN_SUB_MSG_TRACK_INFO_UPDATE] = &PlayerEngineGstImpl::HandleTrackInfoUpdate;
545 subMsgHandler_[PLAYBIN_SUB_MSG_SUBTITLE_UPDATED] = &PlayerEngineGstImpl::HandleSubtitleUpdate;
546
547 MEDIA_LOGD("PlayBinCtrlerInit out");
548 return MSERR_OK;
549 }
550
PlayBinCtrlerDeInit()551 void PlayerEngineGstImpl::PlayBinCtrlerDeInit()
552 {
553 url_.clear();
554 useSoftDec_ = false;
555 appsrcWrap_ = nullptr;
556
557 if (playBinCtrler_ != nullptr) {
558 playBinCtrler_->SetElemSetupListener(nullptr);
559 playBinCtrler_->SetElemUnSetupListener(nullptr);
560 playBinCtrler_->SetAutoPlugSortListener(nullptr);
561 playBinCtrler_ = nullptr;
562 }
563
564 {
565 std::unique_lock<std::mutex> lk(sinkProviderMutex_);
566 sinkProvider_ = nullptr;
567 }
568 }
569
PlayBinCtrlerPrepare()570 int32_t PlayerEngineGstImpl::PlayBinCtrlerPrepare()
571 {
572 uint8_t renderMode = IPlayBinCtrler::PlayBinRenderMode::DEFAULT_RENDER;
573 auto notifier = std::bind(&PlayerEngineGstImpl::OnNotifyMessage, this, std::placeholders::_1);
574
575 {
576 std::unique_lock<std::mutex> lk(sinkProviderMutex_);
577 sinkProvider_ = std::make_shared<PlayerSinkProvider>(producerSurface_);
578 sinkProvider_->SetAppInfo(appuid_, apppid_, apptokenid_);
579 }
580
581 IPlayBinCtrler::PlayBinCreateParam createParam = {
582 static_cast<IPlayBinCtrler::PlayBinRenderMode>(renderMode), notifier, sinkProvider_
583 };
584 playBinCtrler_ = IPlayBinCtrler::Create(IPlayBinCtrler::PlayBinKind::PLAYBIN2, createParam);
585 CHECK_AND_RETURN_RET_LOG(playBinCtrler_ != nullptr, MSERR_INVALID_VAL, "playBinCtrler_ is nullptr");
586
587 int32_t ret;
588 if (appsrcWrap_ == nullptr) {
589 ret = playBinCtrler_->SetSource(url_);
590 } else {
591 ret = playBinCtrler_->SetSource(appsrcWrap_);
592 }
593 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_VAL, "SetSource failed");
594
595 ret = SetVideoScaleType(videoScaleType_);
596 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_VAL, "SetVideoScaleType failed");
597
598 ret = SetAudioRendererInfo(contentType_, streamUsage_, rendererFlag_);
599 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, MSERR_INVALID_VAL, "SetAudioRendererInfo failed");
600
601 auto setupListener = std::bind(&PlayerEngineGstImpl::OnNotifyElemSetup, this, std::placeholders::_1);
602 playBinCtrler_->SetElemSetupListener(setupListener);
603
604 auto unSetupListener = std::bind(&PlayerEngineGstImpl::OnNotifyElemUnSetup, this, std::placeholders::_1);
605 playBinCtrler_->SetElemUnSetupListener(unSetupListener);
606
607 auto autoPlugSortListener = std::bind(&PlayerEngineGstImpl::OnNotifyAutoPlugSort, this, std::placeholders::_1);
608 playBinCtrler_->SetAutoPlugSortListener(autoPlugSortListener);
609
610 return MSERR_OK;
611 }
612
Play()613 int32_t PlayerEngineGstImpl::Play()
614 {
615 std::unique_lock<std::mutex> lock(mutex_);
616 CHECK_AND_RETURN_RET_LOG(playBinCtrler_ != nullptr, MSERR_INVALID_OPERATION, "playBinCtrler_ is nullptr");
617
618 MEDIA_LOGI("Play in");
619 playBinCtrler_->Play();
620 return MSERR_OK;
621 }
622
Pause()623 int32_t PlayerEngineGstImpl::Pause()
624 {
625 std::unique_lock<std::mutex> lock(mutex_);
626 CHECK_AND_RETURN_RET_LOG(playBinCtrler_ != nullptr, MSERR_INVALID_OPERATION, "playBinCtrler_ is nullptr");
627
628 MEDIA_LOGI("Pause in");
629 (void)playBinCtrler_->Pause();
630 return MSERR_OK;
631 }
632
GetCurrentTime(int32_t & currentTime)633 int32_t PlayerEngineGstImpl::GetCurrentTime(int32_t ¤tTime)
634 {
635 currentTime = currentTime_;
636 MEDIA_LOGD("Time in milliseconds: %{public}d", currentTime);
637 return MSERR_OK;
638 }
639
GetVideoTrackInfo(std::vector<Format> & videoTrack)640 int32_t PlayerEngineGstImpl::GetVideoTrackInfo(std::vector<Format> &videoTrack)
641 {
642 std::unique_lock<std::mutex> lock(mutex_);
643 CHECK_AND_RETURN_RET_LOG(playBinCtrler_ != nullptr, MSERR_INVALID_OPERATION, "playBinCtrler_ is nullptr");
644 return playBinCtrler_->GetVideoTrackInfo(videoTrack);
645 }
646
GetAudioTrackInfo(std::vector<Format> & audioTrack)647 int32_t PlayerEngineGstImpl::GetAudioTrackInfo(std::vector<Format> &audioTrack)
648 {
649 std::unique_lock<std::mutex> lock(mutex_);
650 CHECK_AND_RETURN_RET_LOG(playBinCtrler_ != nullptr, MSERR_INVALID_OPERATION, "playBinCtrler_ is nullptr");
651 return playBinCtrler_->GetAudioTrackInfo(audioTrack);
652 }
653
GetSubtitleTrackInfo(std::vector<Format> & subtitleTrack)654 int32_t PlayerEngineGstImpl::GetSubtitleTrackInfo(std::vector<Format> &subtitleTrack)
655 {
656 std::unique_lock<std::mutex> lock(mutex_);
657 CHECK_AND_RETURN_RET_LOG(playBinCtrler_ != nullptr, MSERR_INVALID_OPERATION, "playBinCtrler_ is nullptr");
658 return playBinCtrler_->GetSubtitleTrackInfo(subtitleTrack);
659 }
660
GetVideoWidth()661 int32_t PlayerEngineGstImpl::GetVideoWidth()
662 {
663 return videoWidth_;
664 }
665
GetVideoHeight()666 int32_t PlayerEngineGstImpl::GetVideoHeight()
667 {
668 return videoHeight_;
669 }
670
GetDuration(int32_t & duration)671 int32_t PlayerEngineGstImpl::GetDuration(int32_t &duration)
672 {
673 duration = duration_;
674 MEDIA_LOGD("Duration in milliseconds: %{public}d", duration);
675 return MSERR_OK;
676 }
677
ChangeModeToSpeed(const PlaybackRateMode & mode) const678 double PlayerEngineGstImpl::ChangeModeToSpeed(const PlaybackRateMode &mode) const
679 {
680 switch (mode) {
681 case SPEED_FORWARD_0_75_X:
682 return SPEED_0_75_X;
683 case SPEED_FORWARD_1_00_X:
684 return SPEED_1_00_X;
685 case SPEED_FORWARD_1_25_X:
686 return SPEED_1_25_X;
687 case SPEED_FORWARD_1_75_X:
688 return SPEED_1_75_X;
689 case SPEED_FORWARD_2_00_X:
690 return SPEED_2_00_X;
691 default:
692 MEDIA_LOGW("unknown mode:%{public}d, return default speed(SPEED_1_00_X)", mode);
693 }
694
695 return SPEED_1_00_X;
696 }
697
ChangeSpeedToMode(double rate) const698 PlaybackRateMode PlayerEngineGstImpl::ChangeSpeedToMode(double rate) const
699 {
700 if (abs(rate - SPEED_0_75_X) < EPSINON) {
701 return SPEED_FORWARD_0_75_X;
702 }
703 if (abs(rate - SPEED_1_00_X) < EPSINON) {
704 return SPEED_FORWARD_1_00_X;
705 }
706 if (abs(rate - SPEED_1_25_X) < EPSINON) {
707 return SPEED_FORWARD_1_25_X;
708 }
709 if (abs(rate - SPEED_1_75_X) < EPSINON) {
710 return SPEED_FORWARD_1_75_X;
711 }
712 if (abs(rate - SPEED_2_00_X) < EPSINON) {
713 return SPEED_FORWARD_2_00_X;
714 }
715
716 MEDIA_LOGW("unknown rate:%{public}lf, return default speed(SPEED_FORWARD_1_00_X)", rate);
717
718 return SPEED_FORWARD_1_00_X;
719 }
720
SetPlaybackSpeed(PlaybackRateMode mode)721 int32_t PlayerEngineGstImpl::SetPlaybackSpeed(PlaybackRateMode mode)
722 {
723 std::unique_lock<std::mutex> lock(mutex_);
724 if (playBinCtrler_ != nullptr) {
725 codecCtrl_.EnhanceSeekPerformance(true);
726 double rate = ChangeModeToSpeed(mode);
727 return playBinCtrler_->SetRate(rate);
728 }
729 return MSERR_OK;
730 }
731
GetPlaybackSpeed(PlaybackRateMode & mode)732 int32_t PlayerEngineGstImpl::GetPlaybackSpeed(PlaybackRateMode &mode)
733 {
734 // invliad api
735 (void)mode;
736 return MSERR_OK;
737 }
738
SetLooping(bool loop)739 int32_t PlayerEngineGstImpl::SetLooping(bool loop)
740 {
741 if (playBinCtrler_ != nullptr) {
742 MEDIA_LOGD("SetLooping in");
743 return playBinCtrler_->SetLoop(loop);
744 }
745 return MSERR_OK;
746 }
747
SetParameter(const Format & param)748 int32_t PlayerEngineGstImpl::SetParameter(const Format ¶m)
749 {
750 if (param.ContainKey(PlayerKeys::VIDEO_SCALE_TYPE)) {
751 int32_t videoScaleType = 0;
752 param.GetIntValue(PlayerKeys::VIDEO_SCALE_TYPE, videoScaleType);
753 return SetVideoScaleType(VideoScaleType(videoScaleType));
754 }
755 if (param.ContainKey(PlayerKeys::CONTENT_TYPE) && param.ContainKey(PlayerKeys::STREAM_USAGE)) {
756 param.GetIntValue(PlayerKeys::CONTENT_TYPE, contentType_);
757 param.GetIntValue(PlayerKeys::STREAM_USAGE, streamUsage_);
758 param.GetIntValue(PlayerKeys::RENDERER_FLAG, rendererFlag_);
759 return SetAudioRendererInfo(contentType_, streamUsage_, rendererFlag_);
760 }
761 if (param.ContainKey(PlayerKeys::AUDIO_INTERRUPT_MODE)) {
762 int32_t interruptMode = 0;
763 param.GetIntValue(PlayerKeys::AUDIO_INTERRUPT_MODE, interruptMode);
764 return SetAudioInterruptMode(interruptMode);
765 }
766 return MSERR_OK;
767 }
768
Stop()769 int32_t PlayerEngineGstImpl::Stop()
770 {
771 std::unique_lock<std::mutex> lock(mutex_);
772 CHECK_AND_RETURN_RET_LOG(playBinCtrler_ != nullptr, MSERR_INVALID_OPERATION, "playBinCtrler_ is nullptr");
773
774 MEDIA_LOGD("Stop in");
775 codecCtrl_.StopFormatChange();
776 playBinCtrler_->Stop(true);
777 return MSERR_OK;
778 }
779
Reset()780 int32_t PlayerEngineGstImpl::Reset()
781 {
782 MEDIA_LOGD("Reset in");
783 OnReset();
784 return MSERR_OK;
785 }
786
OnReset()787 void PlayerEngineGstImpl::OnReset()
788 {
789 if (taskQueue_ != nullptr) {
790 (void)taskQueue_->Stop();
791 }
792
793 std::unique_lock<std::mutex> lock(mutex_);
794 PlayBinCtrlerDeInit();
795 }
796
Seek(int32_t mSeconds,PlayerSeekMode mode)797 int32_t PlayerEngineGstImpl::Seek(int32_t mSeconds, PlayerSeekMode mode)
798 {
799 std::unique_lock<std::mutex> lock(mutex_);
800 CHECK_AND_RETURN_RET_LOG(playBinCtrler_ != nullptr, MSERR_INVALID_OPERATION, "playBinCtrler_ is nullptr");
801 MEDIA_LOGI("Seek in %{public}dms", mSeconds);
802
803 if (playBinCtrler_->QueryPosition() == mSeconds) {
804 MEDIA_LOGW("current time same to seek time, invalid seek");
805 Format format;
806 std::shared_ptr<IPlayerEngineObs> notifyObs = obs_.lock();
807 if (notifyObs != nullptr) {
808 notifyObs->OnInfo(INFO_TYPE_SEEKDONE, mSeconds, format);
809 }
810 return MSERR_OK;
811 }
812
813 codecCtrl_.EnhanceSeekPerformance(true);
814
815 int64_t position = static_cast<int64_t>(mSeconds) * MSEC_PER_USEC;
816 return playBinCtrler_->Seek(position, mode);
817 }
818
SetVolume(float leftVolume,float rightVolume)819 int32_t PlayerEngineGstImpl::SetVolume(float leftVolume, float rightVolume)
820 {
821 std::unique_lock<std::mutex> lock(mutex_);
822 if (playBinCtrler_ != nullptr) {
823 MEDIA_LOGD("SetVolume in");
824 playBinCtrler_->SetVolume(leftVolume, rightVolume);
825 }
826 return MSERR_OK;
827 }
828
SelectBitRate(uint32_t bitRate)829 int32_t PlayerEngineGstImpl::SelectBitRate(uint32_t bitRate)
830 {
831 std::unique_lock<std::mutex> lock(mutex_);
832 if (playBinCtrler_ != nullptr) {
833 MEDIA_LOGD("SelectBitRate in");
834 return playBinCtrler_->SelectBitRate(bitRate);
835 }
836 return MSERR_INVALID_OPERATION;
837 }
838
SetVideoScaleType(VideoScaleType videoScaleType)839 int32_t PlayerEngineGstImpl::SetVideoScaleType(VideoScaleType videoScaleType)
840 {
841 std::unique_lock<std::mutex> lock(mutex_, std::try_to_lock);
842 if (sinkProvider_ != nullptr) {
843 MEDIA_LOGD("SetVideoScaleType in");
844 sinkProvider_->SetVideoScaleType(static_cast<uint32_t>(videoScaleType));
845 }
846 videoScaleType_ = videoScaleType;
847 return MSERR_OK;
848 }
849
SetAudioRendererInfo(const int32_t contentType,const int32_t streamUsage,const int32_t rendererFlag)850 int32_t PlayerEngineGstImpl::SetAudioRendererInfo(const int32_t contentType,
851 const int32_t streamUsage, const int32_t rendererFlag)
852 {
853 std::unique_lock<std::mutex> lock(mutex_, std::try_to_lock);
854 contentType_ = contentType;
855 streamUsage_ = streamUsage;
856 rendererFlag_ = rendererFlag;
857 MEDIA_LOGI("content = %{public}d, usage = %{public}d, rendererFlags = %{public}d",
858 contentType, streamUsage, rendererFlag);
859 if (playBinCtrler_ != nullptr) {
860 MEDIA_LOGI("SetAudioRendererInfo in");
861 uint32_t rendererInfo(0);
862 rendererInfo |= (contentType | (static_cast<uint32_t>(streamUsage) <<
863 AudioStandard::RENDERER_STREAM_USAGE_SHIFT));
864 playBinCtrler_->SetAudioRendererInfo(rendererInfo, rendererFlag);
865 }
866 return MSERR_OK;
867 }
868
SetAudioInterruptMode(const int32_t interruptMode)869 int32_t PlayerEngineGstImpl::SetAudioInterruptMode(const int32_t interruptMode)
870 {
871 std::unique_lock<std::mutex> lock(mutex_);
872 if (playBinCtrler_ != nullptr) {
873 MEDIA_LOGD("SetAudioInterruptMode in");
874 playBinCtrler_->SetAudioInterruptMode(interruptMode);
875 }
876 return MSERR_OK;
877 }
878
SetAudioEffectMode(const int32_t effectMode)879 int32_t PlayerEngineGstImpl::SetAudioEffectMode(const int32_t effectMode)
880 {
881 MEDIA_LOGD("SetAudioEffectMode in");
882 std::unique_lock<std::mutex> lock(mutex_);
883 CHECK_AND_RETURN_RET_LOG(playBinCtrler_ != nullptr, MSERR_INVALID_OPERATION, "playBinCtrler_ is nullptr");
884 return playBinCtrler_->SetAudioEffectMode(effectMode);
885 }
886
GetHEBCMode()887 int32_t PlayerEngineGstImpl::GetHEBCMode()
888 {
889 return codecCtrl_.GetHEBCMode();
890 }
891
SelectTrack(int32_t index)892 int32_t PlayerEngineGstImpl::SelectTrack(int32_t index)
893 {
894 std::unique_lock<std::mutex> lock(mutex_);
895 CHECK_AND_RETURN_RET_LOG(playBinCtrler_ != nullptr, MSERR_INVALID_OPERATION, "playBinCtrler_ is nullptr");
896 return playBinCtrler_->SelectTrack(index);
897 }
898
DeselectTrack(int32_t index)899 int32_t PlayerEngineGstImpl::DeselectTrack(int32_t index)
900 {
901 std::unique_lock<std::mutex> lock(mutex_);
902 CHECK_AND_RETURN_RET_LOG(playBinCtrler_ != nullptr, MSERR_INVALID_OPERATION, "playBinCtrler_ is nullptr");
903 return playBinCtrler_->DeselectTrack(index);
904 }
905
GetCurrentTrack(int32_t trackType,int32_t & index)906 int32_t PlayerEngineGstImpl::GetCurrentTrack(int32_t trackType, int32_t &index)
907 {
908 std::unique_lock<std::mutex> lock(mutex_);
909 CHECK_AND_RETURN_RET_LOG(playBinCtrler_ != nullptr, MSERR_INVALID_OPERATION, "playBinCtrler_ is nullptr");
910 return playBinCtrler_->GetCurrentTrack(trackType, index);
911 }
912
OnNotifyAutoPlugSort(GValueArray & factories)913 GValueArray *PlayerEngineGstImpl::OnNotifyAutoPlugSort(GValueArray &factories)
914 {
915 if (isPlaySinkFlagsSet_) {
916 return nullptr;
917 }
918
919 if (useSoftDec_) {
920 GValueArray *result = g_value_array_new(factories.n_values);
921
922 for (uint32_t i = 0; i < factories.n_values; i++) {
923 GstElementFactory *factory =
924 static_cast<GstElementFactory *>(g_value_get_object(g_value_array_get_nth(&factories, i)));
925 if (strstr(gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS),
926 "Codec/Decoder/Video/Hardware")) {
927 MEDIA_LOGD("set remove hardware codec plugins from pipeline");
928 continue;
929 }
930 GValue val = G_VALUE_INIT;
931 g_value_init(&val, G_TYPE_OBJECT);
932 g_value_set_object(&val, factory);
933 result = g_value_array_append(result, &val);
934 g_value_unset(&val);
935 }
936 return result;
937 } else {
938 for (uint32_t i = 0; i < factories.n_values; i++) {
939 GstElementFactory *factory =
940 static_cast<GstElementFactory *>(g_value_get_object(g_value_array_get_nth(&factories, i)));
941 if (strstr(gst_element_factory_get_metadata(factory, GST_ELEMENT_METADATA_KLASS),
942 "Codec/Decoder/Video/Hardware")) {
943 MEDIA_LOGD("set remove GstPlaySinkVideoConvert plugins from pipeline");
944 playBinCtrler_->RemoveGstPlaySinkVideoConvertPlugin();
945 isPlaySinkFlagsSet_ = true;
946 break;
947 }
948 }
949 }
950
951 return nullptr;
952 }
953
OnNotifyElemSetup(GstElement & elem)954 void PlayerEngineGstImpl::OnNotifyElemSetup(GstElement &elem)
955 {
956 std::unique_lock<std::mutex> lock(sinkProviderMutex_);
957
958 const gchar *metadata = gst_element_get_metadata(&elem, GST_ELEMENT_METADATA_KLASS);
959 CHECK_AND_RETURN_LOG(metadata != nullptr, "gst_element_get_metadata return nullptr");
960
961 MEDIA_LOGD("get element_name %{public}s, get metadata %{public}s", GST_ELEMENT_NAME(&elem), metadata);
962 std::string metaStr(metadata);
963
964 if (metaStr.find("Codec/Decoder/Video") != std::string::npos || metaStr.find("Sink/Video") != std::string::npos) {
965 if (producerSurface_ != nullptr) {
966 CHECK_AND_RETURN_LOG(sinkProvider_ != nullptr, "sinkProvider_ is nullptr");
967 GstElement *videoSink = sinkProvider_->GetVideoSink();
968 CHECK_AND_RETURN_LOG(videoSink != nullptr, "videoSink is nullptr");
969 auto notifier = std::bind(&PlayerEngineGstImpl::OnCapsFixError, this);
970 codecCtrl_.DetectCodecSetup(metaStr, &elem, videoSink, notifier);
971 }
972 }
973 }
974
OnNotifyElemUnSetup(GstElement & elem)975 void PlayerEngineGstImpl::OnNotifyElemUnSetup(GstElement &elem)
976 {
977 std::unique_lock<std::mutex> lock(sinkProviderMutex_);
978
979 const gchar *metadata = gst_element_get_metadata(&elem, GST_ELEMENT_METADATA_KLASS);
980 CHECK_AND_RETURN_LOG(metadata != nullptr, "gst_element_get_metadata return nullptr");
981
982 MEDIA_LOGD("get element_name %{public}s, get metadata %{public}s", GST_ELEMENT_NAME(&elem), metadata);
983 std::string metaStr(metadata);
984
985 if (metaStr.find("Codec/Decoder/Video") != std::string::npos) {
986 if (producerSurface_ != nullptr) {
987 CHECK_AND_RETURN_LOG(sinkProvider_ != nullptr, "sinkProvider_ is nullptr");
988 GstElement *videoSink = sinkProvider_->GetVideoSink();
989 CHECK_AND_RETURN_LOG(videoSink != nullptr, "videoSink is nullptr");
990 codecCtrl_.DetectCodecUnSetup(&elem, videoSink);
991 }
992 }
993 }
994
OnCapsFixError()995 void PlayerEngineGstImpl::OnCapsFixError()
996 {
997 MEDIA_LOGD("OnCapsFixError in");
998
999 if (taskQueue_ == nullptr) {
1000 taskQueue_ = std::make_unique<TaskQueue>("reset-playbin-task");
1001 int32_t ret = taskQueue_->Start();
1002 CHECK_AND_RETURN_LOG(ret == MSERR_OK, "task queue start failed");
1003 }
1004
1005 useSoftDec_ = true;
1006 auto resetTask = std::make_shared<TaskHandler<void>>([this]() {
1007 ResetPlaybinToSoftDec();
1008 });
1009 (void)taskQueue_->EnqueueTask(resetTask);
1010 }
1011
1012 // fix video with small resolution cannot play in hardware decoding
1013 // reset pipeline to use software decoder
ResetPlaybinToSoftDec()1014 void PlayerEngineGstImpl::ResetPlaybinToSoftDec()
1015 {
1016 std::unique_lock<std::mutex> lock(mutex_);
1017 CHECK_AND_RETURN_LOG(playBinCtrler_ != nullptr, "playBinCtrler_ is nullptr");
1018
1019 MEDIA_LOGD("ResetPlaybinToSoftDec in");
1020 isPlaySinkFlagsSet_ = false;
1021
1022 if (playBinCtrler_ != nullptr) {
1023 playBinCtrler_->SetNotifier(nullptr);
1024 if (appsrcWrap_) {
1025 appsrcWrap_->DecoderSwitch();
1026 }
1027 playBinCtrler_->Stop(false);
1028 playBinCtrler_->SetElemSetupListener(nullptr);
1029 playBinCtrler_->SetElemUnSetupListener(nullptr);
1030 playBinCtrler_->SetAutoPlugSortListener(nullptr);
1031 playBinCtrler_ = nullptr;
1032 }
1033
1034 {
1035 std::unique_lock<std::mutex> lk(sinkProviderMutex_);
1036 sinkProvider_ = nullptr;
1037 }
1038
1039 lock.unlock();
1040 PrepareAsync();
1041 }
1042
HandleCodecBuffers(bool enable)1043 int32_t PlayerEngineGstImpl::HandleCodecBuffers(bool enable)
1044 {
1045 std::unique_lock<std::mutex> lock(mutex_);
1046 MEDIA_LOGD("HandleCodecBuffers in, enable:%{public}d", enable);
1047 return codecCtrl_.HandleCodecBuffers(enable);
1048 }
1049
SeekToCurrentTime(int32_t mSeconds,PlayerSeekMode mode)1050 int32_t PlayerEngineGstImpl::SeekToCurrentTime(int32_t mSeconds, PlayerSeekMode mode)
1051 {
1052 std::unique_lock<std::mutex> lock(mutex_);
1053 CHECK_AND_RETURN_RET_LOG(playBinCtrler_ != nullptr, MSERR_INVALID_OPERATION, "playBinCtrler_ is nullptr");
1054 MEDIA_LOGI("SeekToCurrentTime in %{public}dms", mSeconds);
1055
1056 codecCtrl_.EnhanceSeekPerformance(true);
1057
1058 int64_t position = static_cast<int64_t>(mSeconds) * MSEC_PER_USEC;
1059 return playBinCtrler_->Seek(position, mode);
1060 }
1061 } // namespace Media
1062 } // namespace OHOS
1063