• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 &currentTime)
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 &param)
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