• 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 "gst_player_ctrl.h"
17 #include "media_log.h"
18 #include "audio_system_manager.h"
19 #include "media_errors.h"
20 #include "audio_errors.h"
21 
22 namespace {
23     constexpr float INVALID_VOLUME = -1.0;
24     constexpr double DEFAULT_RATE = 1.0;
25     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "GstPlayerCtrl"};
26     constexpr int MILLI = 1000;
27     constexpr int MICRO = MILLI * 1000;
28     // multiqueue property
29     constexpr int PLAYBIN_QUEUE_MAX_SIZE = 100 * 1024 * 1024; // 100 * 1024 * 1024 Bytes
30     constexpr int BUFFER_TIME_DEFAULT = 15000;  // 15s
31     constexpr int HTTP_TIME_OUT_DEFAULT = 15000;  // 15s
32     constexpr int BUFFER_LOW_PERCENT_DEFAULT = 1;
33     constexpr int BUFFER_HIGH_PERCENT_DEFAULT = 4;
34     constexpr int BUFFER_FULL_PERCENT_DEFAULT = 100;
35 
36     using namespace OHOS::Media;
37     using StreamToServiceErrFunc = void (*)(const gchar *name, int32_t &errorCode);
38     static const std::unordered_map<int32_t, StreamToServiceErrFunc> STREAM_TO_SERVICE_ERR_FUNC_TABLE = {
39         { GST_STREAM_ERROR_DECODE, GstPlayerCtrl::StreamDecErrorParse },
40     };
41     static const std::unordered_map<int32_t, MediaServiceErrCode> STREAM_TO_SERVICE_ERR_TABLE = {
42         { GST_STREAM_ERROR_FORMAT, MSERR_UNSUPPORT_CONTAINER_TYPE },
43         { GST_STREAM_ERROR_TYPE_NOT_FOUND, MSERR_NOT_FIND_CONTAINER },
44         /* Currently, audio decoding and video decoding cannot be distinguished which is not supported by msg.
45         * By default, we set video decoding is not supported.
46         * The identification method must be added when the new demux pulgin in is use.
47         */
48         { GST_STREAM_ERROR_CODEC_NOT_FOUND, MSERR_UNSUPPORT_VID_DEC_TYPE },
49         { GST_STREAM_ERROR_DEMUX, MSERR_DEMUXER_FAILED },
50     };
51     static const std::unordered_map<int32_t, MediaServiceErrCode> RESOURCE_TO_SERVICE_ERR_TABLE = {
52         { GST_RESOURCE_ERROR_NOT_FOUND, MSERR_OPEN_FILE_FAILED },
53         { GST_RESOURCE_ERROR_OPEN_READ, MSERR_OPEN_FILE_FAILED },
54         { GST_RESOURCE_ERROR_READ, MSERR_FILE_ACCESS_FAILED },
55         { GST_RESOURCE_ERROR_NOT_AUTHORIZED, MSERR_FILE_ACCESS_FAILED },
56         { GST_RESOURCE_ERROR_TIME_OUT, MSERR_NETWORK_TIMEOUT },
57     };
58 }
59 
60 namespace OHOS {
61 namespace Media {
GstPlayerCtrl(GstPlayer * gstPlayer)62 GstPlayerCtrl::GstPlayerCtrl(GstPlayer *gstPlayer)
63     : gstPlayer_(gstPlayer),
64       taskQue_("GstCtrlTask"),
65       volume_(INVALID_VOLUME),
66       rate_(DEFAULT_RATE)
67 {
68     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
69     (void)taskQue_.Start();
70     trackParse_ = GstPlayerTrackParse::Create();
71     if (trackParse_ == nullptr) {
72         MEDIA_LOGE("create track parse fail");
73     }
74 }
75 
~GstPlayerCtrl()76 GstPlayerCtrl::~GstPlayerCtrl()
77 {
78     condVarPlaySync_.notify_all();
79     condVarPauseSync_.notify_all();
80     condVarStopSync_.notify_all();
81     condVarSeekSync_.notify_all();
82     condVarPreparingSync_.notify_all();
83     (void)taskQue_.Stop();
84     for (auto &signalId : signalIds_) {
85         g_signal_handler_disconnect(gstPlayer_, signalId);
86     }
87     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
88 }
89 
SetRingBufferMaxSize(uint64_t size)90 void GstPlayerCtrl::SetRingBufferMaxSize(uint64_t size)
91 {
92     std::unique_lock<std::mutex> lock(mutex_);
93     CHECK_AND_RETURN_LOG(gstPlayer_ != nullptr, "gstPlayer_ is nullptr");
94     g_object_set(gstPlayer_, "ring-buffer-max-size", static_cast<guint64>(size), nullptr);
95 }
96 
SetBufferingInfo()97 void GstPlayerCtrl::SetBufferingInfo()
98 {
99     std::unique_lock<std::mutex> lock(mutex_);
100     CHECK_AND_RETURN_LOG(gstPlayer_ != nullptr, "gstPlayer_ is nullptr");
101     MEDIA_LOGD("SetBufferingInfo");
102 
103     bool flags = true;
104     g_object_set(gstPlayer_, "buffering-flags", flags, nullptr);
105 
106     uint64_t bufferDuration = static_cast<uint64_t>(BUFFER_TIME_DEFAULT) * static_cast<uint64_t>(MICRO);
107     g_object_set(gstPlayer_, "buffer-size", PLAYBIN_QUEUE_MAX_SIZE,
108         "buffer-duration", bufferDuration, "low-percent", BUFFER_LOW_PERCENT_DEFAULT,
109         "high-percent", BUFFER_HIGH_PERCENT_DEFAULT, nullptr);
110 }
111 
SetHttpTimeOut()112 void GstPlayerCtrl::SetHttpTimeOut()
113 {
114     std::unique_lock<std::mutex> lock(mutex_);
115     CHECK_AND_RETURN_LOG(gstPlayer_ != nullptr, "gstPlayer_ is nullptr");
116     MEDIA_LOGD("SetHttpTimeOut");
117 
118     g_object_set(gstPlayer_, "timeout", static_cast<uint32_t>(HTTP_TIME_OUT_DEFAULT / MILLI), nullptr);
119 }
120 
SetUrl(const std::string & url)121 int32_t GstPlayerCtrl::SetUrl(const std::string &url)
122 {
123     std::unique_lock<std::mutex> lock(mutex_);
124     CHECK_AND_RETURN_RET_LOG(gstPlayer_ != nullptr, MSERR_INVALID_VAL, "gstPlayer_ is nullptr");
125     gst_player_set_uri(gstPlayer_, url.c_str());
126     currentState_ = PLAYER_PREPARING;
127     return MSERR_OK;
128 }
129 
SetSource(const std::shared_ptr<GstAppsrcWarp> & appsrcWarp)130 int32_t GstPlayerCtrl::SetSource(const std::shared_ptr<GstAppsrcWarp> &appsrcWarp)
131 {
132     std::unique_lock<std::mutex> lock(mutex_);
133     CHECK_AND_RETURN_RET_LOG(gstPlayer_ != nullptr, MSERR_INVALID_OPERATION, "gstPlayer_ is nullptr");
134     appsrcWarp_ = appsrcWarp;
135     gst_player_set_uri(gstPlayer_, "appsrc://");
136     currentState_ = PLAYER_PREPARING;
137     return MSERR_OK;
138 }
139 
SetCallbacks(const std::weak_ptr<IPlayerEngineObs> & obs)140 int32_t GstPlayerCtrl::SetCallbacks(const std::weak_ptr<IPlayerEngineObs> &obs)
141 {
142     CHECK_AND_RETURN_RET_LOG(obs.lock() != nullptr,
143         MSERR_INVALID_OPERATION, "obs is nullptr, please set callback");
144     if (appsrcWarp_ != nullptr) {
145         CHECK_AND_RETURN_RET_LOG(appsrcWarp_->SetErrorCallback(obs) == MSERR_OK,
146             MSERR_INVALID_OPERATION, "set obs failed");
147     }
148 
149     signalIds_.push_back(g_signal_connect(gstPlayer_, "state-changed", G_CALLBACK(OnStateChangedCb), this));
150     signalIds_.push_back(g_signal_connect(gstPlayer_, "end-of-stream", G_CALLBACK(OnEndOfStreamCb), this));
151     signalIds_.push_back(g_signal_connect(gstPlayer_, "error-msg", G_CALLBACK(OnErrorCb), this));
152     signalIds_.push_back(g_signal_connect(gstPlayer_, "seek-done", G_CALLBACK(OnSeekDoneCb), this));
153     signalIds_.push_back(g_signal_connect(gstPlayer_, "position-updated", G_CALLBACK(OnPositionUpdatedCb), this));
154     signalIds_.push_back(g_signal_connect(gstPlayer_, "source-setup", G_CALLBACK(OnSourceSetupCb), this));
155     signalIds_.push_back(g_signal_connect(gstPlayer_, "buffering", G_CALLBACK(OnCachedPercentCb), this));
156     signalIds_.push_back(g_signal_connect(gstPlayer_, "buffering-time", G_CALLBACK(OnBufferingTimeCb), this));
157     signalIds_.push_back(g_signal_connect(gstPlayer_, "mq-num-use-buffering", G_CALLBACK(OnMqNumUseBufferingCb), this));
158     signalIds_.push_back(g_signal_connect(gstPlayer_, "resolution-changed", G_CALLBACK(OnResolutionChanegdCb), this));
159     signalIds_.push_back(g_signal_connect(gstPlayer_, "element-setup", G_CALLBACK(OnElementSetupCb), this));
160 
161     obs_ = obs;
162     currentState_ = PLAYER_PREPARING;
163     return MSERR_OK;
164 }
165 
OnElementSetupCb(const GstPlayer * player,GstElement * src,GstPlayerCtrl * playerGst)166 void GstPlayerCtrl::OnElementSetupCb(const GstPlayer *player, GstElement *src, GstPlayerCtrl *playerGst)
167 {
168     CHECK_AND_RETURN_LOG(player != nullptr, "player is null");
169     CHECK_AND_RETURN_LOG(playerGst != nullptr, "playerGst is null");
170     CHECK_AND_RETURN_LOG(src != nullptr, "src is null");
171 
172     const gchar *metadata = gst_element_get_metadata(src, GST_ELEMENT_METADATA_KLASS);
173     if (metadata == nullptr) {
174         MEDIA_LOGE("gst_element_get_metadata return nullptr");
175         return;
176     }
177 
178     MEDIA_LOGD("get element_name %{public}s, get metadata %{public}s", GST_ELEMENT_NAME(src), metadata);
179     std::string metaStr(metadata);
180 
181     if (metaStr.find("Codec/Demuxer") != std::string::npos || metaStr.find("Codec/Parser") != std::string::npos) {
182         if (playerGst->trackParse_->GetDemuxerElementFind() == false) {
183             playerGst->signalIds_.push_back(g_signal_connect(src,
184                 "pad-added", G_CALLBACK(GstPlayerTrackParse::OnPadAddedCb), playerGst->trackParse_.get()));
185             playerGst->trackParse_->SetDemuxerElementFind(true);
186         }
187     }
188 
189     if (metaStr.find("Codec/Decoder/Video/Hardware") != std::string::npos) {
190         playerGst->isHardWare_ = true;
191         return;
192     }
193 
194     if (metaStr.find("Sink/Video") != std::string::npos && playerGst->isHardWare_) {
195         GstCaps *caps = gst_caps_new_simple("video/x-raw", "format", G_TYPE_STRING, "NV12", nullptr);
196         g_object_set(G_OBJECT(src), "caps", caps, nullptr);
197         return;
198     }
199 }
200 
SetVideoTrack(bool enable)201 void GstPlayerCtrl::SetVideoTrack(bool enable)
202 {
203     std::unique_lock<std::mutex> lock(mutex_);
204     CHECK_AND_RETURN_LOG(gstPlayer_ != nullptr, "gstPlayer_ is nullptr");
205 
206     gst_player_set_video_track_enabled(gstPlayer_, static_cast<gboolean>(enable));
207     MEDIA_LOGI("SetVideoTrack Enabled %{public}d", enable);
208 }
209 
Prepare()210 void GstPlayerCtrl::Prepare()
211 {
212     isExit_ = false;
213     PauseSync();
214 }
215 
PrepareAsync()216 void GstPlayerCtrl::PrepareAsync()
217 {
218     isExit_ = false;
219     Pause();
220 }
221 
Pause()222 void GstPlayerCtrl::Pause()
223 {
224     std::unique_lock<std::mutex> lock(mutex_);
225     auto task = std::make_shared<TaskHandler<void>>([this] { PauseSync(); });
226     (void)taskQue_.EnqueueTask(task);
227 }
228 
PauseSync()229 void GstPlayerCtrl::PauseSync()
230 {
231     std::unique_lock<std::mutex> lock(mutex_);
232     if (appsrcWarp_ != nullptr) {
233         (void)appsrcWarp_->Prepare();
234     }
235 
236     if (isExit_ ||
237         currentState_ == PLAYER_PAUSED ||
238         currentState_ == PLAYER_PREPARED ||
239         currentState_ == PLAYER_PLAYBACK_COMPLETE) {
240         return;
241     }
242 
243     if (currentState_ == PLAYER_PREPARING) {
244         preparing_ = true;
245     }
246 
247     MEDIA_LOGD("Pause start!");
248     CHECK_AND_RETURN_LOG(gstPlayer_ != nullptr, "gstPlayer_ is nullptr");
249     gst_player_pause(gstPlayer_);
250 
251     {
252         condVarPauseSync_.wait(lock);
253         MEDIA_LOGD("Pause finised!");
254     }
255 }
256 
Play()257 void GstPlayerCtrl::Play()
258 {
259     std::unique_lock<std::mutex> lock(mutex_);
260     auto task = std::make_shared<TaskHandler<void>>([this] { PlaySync(); });
261     (void)taskQue_.EnqueueTask(task);
262 }
263 
PlaySync()264 void GstPlayerCtrl::PlaySync()
265 {
266     std::unique_lock<std::mutex> lock(mutex_);
267     if (currentState_ == PLAYER_STARTED || isExit_) {
268         return;
269     }
270     if (IsLiveMode() && currentState_ == PLAYER_PLAYBACK_COMPLETE) {
271         std::shared_ptr<IPlayerEngineObs> tempObs = obs_.lock();
272         if (tempObs != nullptr) {
273             tempObs->OnError(PLAYER_ERROR_UNKNOWN, MSERR_INVALID_STATE);
274         }
275         return;
276     }
277 
278     CHECK_AND_RETURN_LOG(gstPlayer_ != nullptr, "gstPlayer_ is nullptr");
279     gst_player_play(gstPlayer_);
280 
281     {
282         condVarPlaySync_.wait(lock);
283         MEDIA_LOGD("Play finised!");
284     }
285 }
286 
ChangeSeekModeToGstFlag(const PlayerSeekMode mode) const287 int32_t GstPlayerCtrl::ChangeSeekModeToGstFlag(const PlayerSeekMode mode) const
288 {
289     int32_t flag = 0;
290     switch (mode) {
291         case SEEK_PREVIOUS_SYNC:
292             flag = GST_SEEK_FLAG_SNAP_BEFORE | GST_SEEK_FLAG_KEY_UNIT;
293             break;
294         case SEEK_NEXT_SYNC:
295             flag = GST_SEEK_FLAG_SNAP_AFTER | GST_SEEK_FLAG_KEY_UNIT;
296             break;
297         case SEEK_CLOSEST_SYNC:
298             flag = GST_SEEK_FLAG_KEY_UNIT;
299             break;
300         case SEEK_CLOSEST:
301             break;
302         default:
303             MEDIA_LOGW("unknown seek mode");
304             break;
305     }
306     return flag;
307 }
308 
Seek(uint64_t position,const PlayerSeekMode mode)309 int32_t GstPlayerCtrl::Seek(uint64_t position, const PlayerSeekMode mode)
310 {
311     std::unique_lock<std::mutex> lock(mutex_);
312     if (IsLiveMode()) {
313         return MSERR_INVALID_OPERATION;
314     }
315 
316     if ((position == 0) && (position == GetPositionInner())) {
317         MEDIA_LOGW("Seek to the inner position");
318         return MSERR_OK;
319     }
320 
321     position = (position > sourceDuration_) ? sourceDuration_ : position;
322     auto task = std::make_shared<TaskHandler<void>>([this, position, mode] { SeekSync(position, mode); });
323     if (taskQue_.EnqueueTask(task) != 0) {
324         MEDIA_LOGE("Seek fail");
325         return MSERR_INVALID_OPERATION;
326     }
327 
328     if (seekTask_ != nullptr) {
329         MEDIA_LOGI("cancel pre seek Task");
330         seekTask_->Cancel();
331     }
332     seekTask_ = task;
333 
334     return MSERR_OK;
335 }
336 
SeekSync(uint64_t position,const PlayerSeekMode mode)337 void GstPlayerCtrl::SeekSync(uint64_t position, const PlayerSeekMode mode)
338 {
339     std::unique_lock<std::mutex> lock(mutex_);
340     seekTask_ = nullptr;
341     if (currentState_ == PLAYER_STOPPED || isExit_) {
342         return;
343     }
344 
345     if (currentState_ == PLAYER_PLAYBACK_COMPLETE) {
346         currentState_ = PLAYER_PAUSED;
347     }
348 
349     CHECK_AND_RETURN_LOG(gstPlayer_ != nullptr, "gstPlayer_ is nullptr");
350     // need keep the seek and seek modes consistent.
351     g_object_set(gstPlayer_, "seek-mode", static_cast<gint>(ChangeSeekModeToGstFlag(mode)), nullptr);
352     GstClockTime time = static_cast<GstClockTime>(position * MICRO);
353     (void)GetPositionInner();
354     seeking_ = true;
355     gst_player_seek(gstPlayer_, time);
356 
357     {
358         condVarSeekSync_.wait(lock);
359         MEDIA_LOGD("Seek finised!");
360     }
361 }
362 
Stop()363 void GstPlayerCtrl::Stop()
364 {
365     std::unique_lock<std::mutex> lock(mutex_);
366     if (currentState_ <= PLAYER_PREPARING && !preparing_) {
367         isExit_ = true;
368         return;
369     }
370 
371     if (currentState_ == PLAYER_PREPARING && preparing_) {
372         MEDIA_LOGD("begin wait stop for current status is preparing!");
373         static constexpr int32_t timeout = 1;
374         condVarPreparingSync_.wait_for(lock, std::chrono::seconds(timeout));
375         MEDIA_LOGD("end wait stop for current status is preparing!");
376     }
377 
378     if (appsrcWarp_ != nullptr) {
379         appsrcWarp_->Stop();
380     }
381     if (currentState_ == PLAYER_STOPPED) {
382         return;
383     }
384 
385     isExit_ = true;
386     userStop_ = true;
387     CHECK_AND_RETURN_LOG(gstPlayer_ != nullptr, "gstPlayer_ is nullptr");
388     MEDIA_LOGD("Stop start!");
389     g_object_set(gstPlayer_, "exit-block", 1, nullptr);
390     gst_player_stop(gstPlayer_);
391 
392     {
393         condVarStopSync_.wait(lock);
394         MEDIA_LOGD("Stop finised!");
395     }
396 
397     condVarPlaySync_.notify_all();
398     condVarPauseSync_.notify_all();
399     condVarSeekSync_.notify_all();
400     bufferingStart_ = false;
401     nextSeekFlag_ = false;
402     enableLooping_ = false;
403     speeding_ = false;
404     seeking_ = false;
405     rate_ = DEFAULT_RATE;
406     lastTime_ = 0;
407     if (audioSink_ != nullptr) {
408         g_signal_handler_disconnect(audioSink_, signalIdVolume_);
409         signalIdVolume_ = 0;
410         gst_object_unref(audioSink_);
411         audioSink_ = nullptr;
412     }
413     if (rateTask_ != nullptr) {
414         rateTask_->Cancel();
415         rateTask_ = nullptr;
416     }
417     if (seekTask_ != nullptr) {
418         seekTask_->Cancel();
419         seekTask_ = nullptr;
420     }
421 }
422 
SetLoop(bool loop)423 int32_t GstPlayerCtrl::SetLoop(bool loop)
424 {
425     std::unique_lock<std::mutex> lock(mutex_);
426     if (IsLiveMode()) {
427         return MSERR_INVALID_OPERATION;
428     }
429     enableLooping_ = loop;
430     return MSERR_OK;
431 }
432 
SetVolume(const float & leftVolume,const float & rightVolume)433 void GstPlayerCtrl::SetVolume(const float &leftVolume, const float &rightVolume)
434 {
435     (void)rightVolume;
436     std::unique_lock<std::mutex> lock(mutex_);
437     volume_ = leftVolume;
438     if (audioSink_ != nullptr) {
439         MEDIA_LOGI("SetVolume(%{public}f) to audio sink", volume_);
440         g_object_set(audioSink_, "volume", volume_, nullptr);
441     }
442 }
443 
SetParameter(const Format & param)444 int32_t GstPlayerCtrl::SetParameter(const Format &param)
445 {
446     std::unique_lock<std::mutex> lock(mutex_);
447     if (!SetAudioRendererInfo(param)) {
448         MEDIA_LOGE("unsupported params");
449         return MSERR_UNSUPPORT_AUD_PARAMS;
450     }
451 
452     return MSERR_OK;
453 }
454 
GetPosition()455 uint64_t GstPlayerCtrl::GetPosition()
456 {
457     std::unique_lock<std::mutex> lock(mutex_);
458     return GetPositionInner();
459 }
460 
GetPositionInner()461 uint64_t GstPlayerCtrl::GetPositionInner()
462 {
463     CHECK_AND_RETURN_RET_LOG(gstPlayer_ != nullptr, 0, "gstPlayer_ is nullptr");
464 
465     if (currentState_ == PLAYER_STOPPED) {
466         return 0;
467     }
468 
469     if (currentState_ == PLAYER_PLAYBACK_COMPLETE) {
470         if (IsLiveMode()) {
471             return lastTime_;
472         }
473         return sourceDuration_;
474     }
475 
476     if (seeking_ || speeding_) {
477         return lastTime_;
478     }
479 
480     GstClockTime position = gst_player_get_position(gstPlayer_);
481     uint64_t curTime = static_cast<uint64_t>(position) / MICRO;
482     curTime = std::min(curTime, sourceDuration_);
483     lastTime_ = curTime;
484     MEDIA_LOGD("GetPosition curTime(%{public}" PRIu64 ") duration(%{public}" PRIu64 ")", curTime, sourceDuration_);
485     return curTime;
486 }
487 
GetDuration()488 uint64_t GstPlayerCtrl::GetDuration()
489 {
490     std::unique_lock<std::mutex> lock(mutex_);
491     CHECK_AND_RETURN_RET_LOG(gstPlayer_ != nullptr, 0, "gstPlayer_ is nullptr");
492     if (IsLiveMode()) {
493         return GST_CLOCK_TIME_NONE;
494     }
495     if (currentState_ == PLAYER_STOPPED) {
496         return sourceDuration_;
497     }
498 
499     InitDuration();
500     return sourceDuration_;
501 }
502 
GetVideoTrackInfo(std::vector<Format> & videoTrack)503 int32_t GstPlayerCtrl::GetVideoTrackInfo(std::vector<Format> &videoTrack)
504 {
505     std::unique_lock<std::mutex> lock(mutex_);
506     CHECK_AND_RETURN_RET_LOG(trackParse_ != nullptr, 0, "trackParse_ is nullptr");
507 
508     return trackParse_->GetVideoTrackInfo(videoTrack);
509 }
510 
GetAudioTrackInfo(std::vector<Format> & audioTrack)511 int32_t GstPlayerCtrl::GetAudioTrackInfo(std::vector<Format> &audioTrack)
512 {
513     std::unique_lock<std::mutex> lock(mutex_);
514     CHECK_AND_RETURN_RET_LOG(trackParse_ != nullptr, 0, "trackParse_ is nullptr");
515 
516     return trackParse_->GetAudioTrackInfo(audioTrack);
517 }
518 
GetVideoWidth()519 int32_t GstPlayerCtrl::GetVideoWidth()
520 {
521     std::unique_lock<std::mutex> lock(mutex_);
522     return videoWidth_;
523 }
524 
GetVideoHeight()525 int32_t GstPlayerCtrl::GetVideoHeight()
526 {
527     std::unique_lock<std::mutex> lock(mutex_);
528     return videoHeight_;
529 }
530 
SetRate(double rate)531 int32_t GstPlayerCtrl::SetRate(double rate)
532 {
533     std::unique_lock<std::mutex> lock(mutex_);
534     if (IsLiveMode()) {
535         return MSERR_INVALID_OPERATION;
536     }
537     auto task = std::make_shared<TaskHandler<void>>([this, rate] { SetRateSync(rate); });
538     if (taskQue_.EnqueueTask(task) != 0) {
539         MEDIA_LOGE("set rate(%{public}lf) fail", rate);
540         return MSERR_INVALID_OPERATION;
541     }
542 
543     if (rateTask_ != nullptr) {
544         MEDIA_LOGI("cancel pre rate task(%{public}lf)", rate_);
545         rateTask_->Cancel();
546     }
547     rateTask_ = task;
548     rate_ = rate;
549     return MSERR_OK;
550 }
551 
SetRateSync(double rate)552 void GstPlayerCtrl::SetRateSync(double rate)
553 {
554     std::unique_lock<std::mutex> lock(mutex_);
555     if (isExit_) {
556         return;
557     }
558     rateTask_ = nullptr;
559 
560     CHECK_AND_RETURN_LOG(gstPlayer_ != nullptr, "gstPlayer_ is nullptr");
561     MEDIA_LOGD("SetRateSync in, rate=(%{public}lf)", rate);
562     (void)GetPositionInner();
563     speeding_ = true;
564     gst_player_set_rate(gstPlayer_, static_cast<gdouble>(rate));
565 
566     condVarSeekSync_.wait(lock);
567     MEDIA_LOGD("SetRateSync out, rate=(%{public}lf)", rate);
568 }
569 
GetRate()570 double GstPlayerCtrl::GetRate()
571 {
572     std::unique_lock<std::mutex> lock(mutex_);
573     CHECK_AND_RETURN_RET_LOG(gstPlayer_ != nullptr, 1.0, "gstPlayer_ is nullptr");
574 
575     MEDIA_LOGD("get rate=%{public}lf", rate_);
576     return rate_;
577 }
578 
GetState() const579 PlayerStates GstPlayerCtrl::GetState() const
580 {
581     return currentState_;
582 }
583 
GetAudioSink()584 void GstPlayerCtrl::GetAudioSink()
585 {
586     GstElement *playbin = gst_player_get_pipeline(gstPlayer_);
587     CHECK_AND_RETURN_LOG(playbin != nullptr, "playbin is null");
588 
589     if (audioSink_ != nullptr) {
590         gst_object_unref(audioSink_);
591         audioSink_ = nullptr;
592     }
593     g_object_get(playbin, "audio-sink", &audioSink_, nullptr);
594 
595     CHECK_AND_RETURN_LOG(audioSink_ != nullptr, "get audio sink fail");
596 
597     signalIdVolume_ = g_signal_connect(audioSink_, "notify::volume", G_CALLBACK(OnVolumeChangeCb), this);
598 
599     gst_object_unref(playbin);
600 }
601 
OnStateChangedCb(const GstPlayer * player,GstPlayerState state,GstPlayerCtrl * playerGst)602 void GstPlayerCtrl::OnStateChangedCb(const GstPlayer *player, GstPlayerState state, GstPlayerCtrl *playerGst)
603 {
604     MEDIA_LOGD("OnStateChangedCb gstplayer State changed: %{public}s", gst_player_state_get_name(state));
605     CHECK_AND_RETURN_LOG(player != nullptr, "player is null");
606     CHECK_AND_RETURN_LOG(playerGst != nullptr, "playerGst is null");
607     playerGst->ProcessStateChanged(player, state);
608 }
609 
ProcessStateChanged(const GstPlayer * cbPlayer,GstPlayerState state)610 void GstPlayerCtrl::ProcessStateChanged(const GstPlayer *cbPlayer, GstPlayerState state)
611 {
612     std::unique_lock<std::mutex> lock(mutex_);
613     if (cbPlayer != gstPlayer_) {
614         MEDIA_LOGE("gstplay cb object error: cbPlayer != gstPlayer_");
615         return;
616     }
617 
618     PlayerStates newState = PLAYER_IDLE;
619     switch (state) {
620         case GST_PLAYER_STATE_STOPPED: {
621             newState = ProcessStoppedState();
622             break;
623         }
624         case GST_PLAYER_STATE_BUFFERING: {
625             OnBufferingUpdate(std::string(PlayerKeys::PLAYER_BUFFERING_START));
626             bufferingStart_ = true;
627             percent_ = 0;
628             return;
629         }
630         case GST_PLAYER_STATE_PAUSED: {
631             newState = ProcessPausedState();
632             break;
633         }
634         case GST_PLAYER_STATE_PLAYING: {
635             newState = PLAYER_STARTED;
636             break;
637         }
638         default: {
639             return;
640         }
641     }
642 
643     if (bufferingStart_) {
644         OnBufferingUpdate(std::string(PlayerKeys::PLAYER_BUFFERING_END));
645         bufferingStart_ = false;
646     }
647 
648     MEDIA_LOGD("currentState_ = %{public}d, newState = %{public}d", currentState_, newState);
649     if (newState != PLAYER_IDLE && currentState_ != newState) {
650         OnStateChanged(newState);
651     }
652 
653     OnNotify(newState);
654     /* call back sequence: statecb > seekdonecb */
655     OnSeekDone();
656     OnEndOfStream();
657 }
658 
OnEndOfStreamCb(const GstPlayer * player,GstPlayerCtrl * playerGst)659 void GstPlayerCtrl::OnEndOfStreamCb(const GstPlayer *player, GstPlayerCtrl *playerGst)
660 {
661     CHECK_AND_RETURN_LOG(player != nullptr, "player is null");
662     CHECK_AND_RETURN_LOG(playerGst != nullptr, "playerGst is null");
663     return playerGst->ProcessEndOfStream(player);
664 }
665 
ProcessEndOfStream(const GstPlayer * cbPlayer)666 void GstPlayerCtrl::ProcessEndOfStream(const GstPlayer *cbPlayer)
667 {
668     if (cbPlayer != gstPlayer_) {
669         MEDIA_LOGE("gstplay cb object error: cbPlayer != gstPlayer_");
670         return;
671     }
672     MEDIA_LOGD("End of stream");
673     endOfStreamCb_ = true;
674     if (IsLiveMode()) {
675         return;
676     }
677 
678     if (enableLooping_) {
679         (void)Seek(0, SEEK_PREVIOUS_SYNC);
680     } else {
681         Pause();
682     }
683 }
684 
StreamDecErrorParse(const gchar * name,int32_t & errorCode)685 void GstPlayerCtrl::StreamDecErrorParse(const gchar *name, int32_t &errorCode)
686 {
687     if (strstr(name, "aac") != nullptr) {
688         MEDIA_LOGE("tag:MSERR_AUD_DEC_FAILED");
689         errorCode = MSERR_AUD_DEC_FAILED;
690     } else if (strstr(name, "h264") != nullptr || strstr(name, "h265") != nullptr) {
691         MEDIA_LOGE("tag:MSERR_VID_DEC_FAILED");
692         errorCode = MSERR_VID_DEC_FAILED;
693     } else {
694         MEDIA_LOGE("tag:MSERR_UNKNOWN");
695         errorCode = MSERR_UNKNOWN;
696     }
697 }
698 
StreamErrorParse(const gchar * name,const GError * err,int32_t & errorCode)699 void GstPlayerCtrl::StreamErrorParse(const gchar *name, const GError *err, int32_t &errorCode)
700 {
701     CHECK_AND_RETURN_LOG(name != nullptr, "name is null");
702     CHECK_AND_RETURN_LOG(err != nullptr, "err is null");
703     MEDIA_LOGE("domain:GST_STREAM_ERROR");
704     auto streamIter = STREAM_TO_SERVICE_ERR_TABLE.find(err->code);
705     if (streamIter != STREAM_TO_SERVICE_ERR_TABLE.end()) {
706         errorCode = streamIter->second;
707         return;
708     }
709     auto streamFuncIter = STREAM_TO_SERVICE_ERR_FUNC_TABLE.find(err->code);
710     if (streamFuncIter != STREAM_TO_SERVICE_ERR_FUNC_TABLE.end()) {
711         streamFuncIter->second(name, errorCode);
712         return;
713     }
714 
715     errorCode = MSERR_UNKNOWN;
716 }
717 
ResourceErrorParse(const GError * err,int32_t & errorCode)718 void GstPlayerCtrl::ResourceErrorParse(const GError *err, int32_t &errorCode)
719 {
720     CHECK_AND_RETURN_LOG(err != nullptr, "err is null");
721     MEDIA_LOGE("domain:GST_RESOURCE_ERROR");
722     auto resIter = RESOURCE_TO_SERVICE_ERR_TABLE.find(err->code);
723     if (resIter == RESOURCE_TO_SERVICE_ERR_TABLE.end()) {
724         errorCode = MSERR_UNKNOWN;
725         return;
726     }
727     errorCode = resIter->second;
728 }
729 
MessageErrorProcess(const char * name,const GError * err,PlayerErrorType & errorType,int32_t & errorCode)730 void GstPlayerCtrl::MessageErrorProcess(const char *name, const GError *err,
731     PlayerErrorType &errorType, int32_t &errorCode)
732 {
733     CHECK_AND_RETURN_LOG(err != nullptr, "err is null");
734     CHECK_AND_RETURN_LOG(name != nullptr, "name is null");
735     char *errMsg = gst_error_get_message(err->domain, err->code);
736     MEDIA_LOGE("errMsg:%{public}s", errMsg);
737     if (err->domain == GST_STREAM_ERROR) {
738         errorType = PLAYER_ERROR;
739         StreamErrorParse(name, err, errorCode);
740     } else if (err->domain == GST_RESOURCE_ERROR) {
741         errorType = PLAYER_ERROR;
742         ResourceErrorParse(err, errorCode);
743     } else {
744         errorType = PLAYER_ERROR_UNKNOWN;
745         errorCode = MSERR_UNKNOWN;
746     }
747     g_free(errMsg);
748 }
749 
ErrorProcess(const GstMessage * msg,PlayerErrorType & errorType,int32_t & errorCode)750 void GstPlayerCtrl::ErrorProcess(const GstMessage *msg, PlayerErrorType &errorType, int32_t &errorCode)
751 {
752     CHECK_AND_RETURN_LOG(msg != nullptr, "msg is null");
753     gchar *debug = nullptr;
754     GError *err = nullptr;
755     GstMessage *message = gst_message_copy(msg);
756     CHECK_AND_RETURN_LOG(message != nullptr, "msg copy failed");
757     gst_message_parse_error(message, &err, &debug);
758     if (msg->src == nullptr) {
759         g_clear_error(&err);
760         g_free(debug);
761         gst_message_unref(message);
762         MEDIA_LOGE("msg parse failed");
763         return;
764     }
765     gchar *name = gst_object_get_path_string(msg->src);
766     MessageErrorProcess(name, err, errorType, errorCode);
767     g_clear_error(&err);
768     g_free(debug);
769     g_free(name);
770     gst_message_unref(message);
771 }
772 
OnErrorCb(const GstPlayer * player,const GstMessage * msg,GstPlayerCtrl * playerGst)773 void GstPlayerCtrl::OnErrorCb(const GstPlayer *player, const GstMessage *msg, GstPlayerCtrl *playerGst)
774 {
775     MEDIA_LOGE("Received error signal from pipeline.");
776     CHECK_AND_RETURN_LOG(player != nullptr, "player is null");
777     CHECK_AND_RETURN_LOG(msg != nullptr, "msg is null");
778     CHECK_AND_RETURN_LOG(playerGst != nullptr, "playerGst is null");
779 
780     // If looping is enabled, then disable it else will keep looping forever
781     playerGst->enableLooping_ = false;
782     PlayerErrorType errorType = PLAYER_ERROR_UNKNOWN;
783     int32_t errorCode = MSERR_UNKNOWN;
784 
785     ErrorProcess(msg, errorType, errorCode);
786 
787     std::shared_ptr<IPlayerEngineObs> tempObs = playerGst->obs_.lock();
788     if (tempObs != nullptr) {
789         tempObs->OnError(errorType, errorCode);
790     }
791 
792     playerGst->errorFlag_ = true;
793 }
794 
OnResolutionChanegdCb(const GstPlayer * player,int32_t width,int32_t height,GstPlayerCtrl * playerGst)795 void GstPlayerCtrl::OnResolutionChanegdCb(const GstPlayer *player,
796     int32_t width, int32_t height, GstPlayerCtrl *playerGst)
797 {
798     CHECK_AND_RETURN_LOG(player != nullptr, "player is null");
799     CHECK_AND_RETURN_LOG(playerGst != nullptr, "playerGst is null");
800 
801     playerGst->OnResolutionChange(width, height);
802 }
803 
OnResolutionChange(int32_t width,int32_t height)804 void GstPlayerCtrl::OnResolutionChange(int32_t width, int32_t height)
805 {
806     Format format;
807     (void)format.PutIntValue(std::string(PlayerKeys::PLAYER_WIDTH), width);
808     (void)format.PutIntValue(std::string(PlayerKeys::PLAYER_HEIGHT), height);
809     std::shared_ptr<IPlayerEngineObs> tempObs = obs_.lock();
810     if (tempObs != nullptr) {
811         MEDIA_LOGD("OnResolutionChange width:%{public}d, height:%{public}d", width, height);
812         tempObs->OnInfo(INFO_TYPE_RESOLUTION_CHANGE, 0, format);
813     }
814     videoWidth_ = width;
815     videoHeight_ = height;
816 }
817 
OnSeekDoneCb(const GstPlayer * player,guint64 position,GstPlayerCtrl * playerGst)818 void GstPlayerCtrl::OnSeekDoneCb(const GstPlayer *player, guint64 position, GstPlayerCtrl *playerGst)
819 {
820     CHECK_AND_RETURN_LOG(player != nullptr, "player is null");
821     CHECK_AND_RETURN_LOG(playerGst != nullptr, "playerGst is null");
822     playerGst->ProcessSeekDone(player, static_cast<uint64_t>(position) / MICRO);
823 }
824 
ProcessSeekDone(const GstPlayer * cbPlayer,uint64_t position)825 void GstPlayerCtrl::ProcessSeekDone(const GstPlayer *cbPlayer, uint64_t position)
826 {
827     if (cbPlayer != gstPlayer_) {
828         MEDIA_LOGE("gstplay cb object error: cbPlayer != gstPlayer_");
829         return;
830     }
831 
832     position = std::min(position, sourceDuration_);
833     seekDoneNeedCb_ = true;
834     seekDonePosition_ = position;
835     MEDIA_LOGI("gstplay seek Done: (%{public}" PRIu64 ")", seekDonePosition_);
836 }
837 
OnSourceSetupCb(const GstPlayer * player,GstElement * src,GstPlayerCtrl * playerGst)838 void GstPlayerCtrl::OnSourceSetupCb(const GstPlayer *player, GstElement *src, GstPlayerCtrl *playerGst)
839 {
840     CHECK_AND_RETURN_LOG(player != nullptr, "player is null");
841     CHECK_AND_RETURN_LOG(playerGst != nullptr, "playerGst is null");
842     CHECK_AND_RETURN_LOG(src != nullptr, "self is null");
843     if (playerGst->appsrcWarp_ == nullptr) {
844         MEDIA_LOGD("appsrc is null, is not stream mode");
845         return;
846     }
847     GstElementFactory *elementFac = gst_element_get_factory(src);
848     const gchar *eleTypeName = g_type_name(gst_element_factory_get_element_type(elementFac));
849     if ((eleTypeName != nullptr) && (strstr(eleTypeName, "GstAppSrc") != nullptr)) {
850         (void)playerGst->appsrcWarp_->SetAppsrc(src);
851     }
852 }
853 
OnBufferingTimeCb(const GstPlayer * player,guint64 bufferingTime,guint mqNumId,GstPlayerCtrl * playerGst)854 void GstPlayerCtrl::OnBufferingTimeCb(const GstPlayer *player, guint64 bufferingTime,
855     guint mqNumId, GstPlayerCtrl *playerGst)
856 {
857     CHECK_AND_RETURN_LOG(player != nullptr, "player is null");
858     CHECK_AND_RETURN_LOG(playerGst != nullptr, "playerGst is null");
859     playerGst->ProcessBufferingTime(player, bufferingTime, mqNumId);
860 }
861 
ProcessBufferingTime(const GstPlayer * cbPlayer,guint64 bufferingTime,guint mqNumId)862 void GstPlayerCtrl::ProcessBufferingTime(const GstPlayer *cbPlayer, guint64 bufferingTime, guint mqNumId)
863 {
864     if (cbPlayer != gstPlayer_) {
865         MEDIA_LOGE("gstplay cb object error: cbPlayer != gstPlayer_");
866         return;
867     }
868 
869     if (currentState_ == PLAYER_PLAYBACK_COMPLETE) {
870         return;
871     }
872 
873     bufferingTime = bufferingTime / MICRO;
874     if (bufferingTime > BUFFER_TIME_DEFAULT) {
875         bufferingTime = BUFFER_TIME_DEFAULT;
876     }
877 
878     mqBufferingTime_[mqNumId] = bufferingTime;
879 
880     MEDIA_LOGD("ProcessBufferingTime(%{public}" PRIu64 "), mqNumId = %{public}u mqNumUseBuffering_ = %{public}u",
881         bufferingTime, mqNumId, mqNumUseBuffering_);
882 
883     if (mqBufferingTime_.size() != mqNumUseBuffering_) {
884         return;
885     }
886 
887     guint64 mqBufferingTime = BUFFER_TIME_DEFAULT;
888     for (auto iter = mqBufferingTime_.begin(); iter != mqBufferingTime_.end(); ++iter) {
889         if (iter->second < mqBufferingTime) {
890             mqBufferingTime = iter->second;
891         }
892     }
893 
894     if (bufferingTime_ != mqBufferingTime) {
895         bufferingTime_ = mqBufferingTime;
896         std::shared_ptr<IPlayerEngineObs> tempObs = obs_.lock();
897         if (tempObs != nullptr) {
898             Format format;
899             (void)format.PutIntValue(std::string(PlayerKeys::PLAYER_CACHED_DURATION),
900                                      static_cast<int32_t>(mqBufferingTime));
901             tempObs->OnInfo(INFO_TYPE_BUFFERING_UPDATE, 0, format);
902         }
903     }
904 }
905 
OnCachedPercentCb(const GstPlayer * player,guint percent,GstPlayerCtrl * playerGst)906 void GstPlayerCtrl::OnCachedPercentCb(const GstPlayer *player, guint percent, GstPlayerCtrl *playerGst)
907 {
908     CHECK_AND_RETURN_LOG(player != nullptr, "player is null");
909     CHECK_AND_RETURN_LOG(playerGst != nullptr, "playerGst is null");
910     playerGst->ProcessCachedPercent(player, percent);
911 }
912 
ProcessCachedPercent(const GstPlayer * cbPlayer,int32_t percent)913 void GstPlayerCtrl::ProcessCachedPercent(const GstPlayer *cbPlayer, int32_t percent)
914 {
915     if (cbPlayer != gstPlayer_) {
916         MEDIA_LOGE("gstplay cb object error: cbPlayer != gstPlayer_");
917         return;
918     }
919 
920     if (currentState_ == PLAYER_PLAYBACK_COMPLETE) {
921         return;
922     }
923 
924     int32_t lastPercent = percent_;
925     if (percent >= BUFFER_HIGH_PERCENT_DEFAULT) {
926         percent_ = BUFFER_FULL_PERCENT_DEFAULT;
927     } else {
928         int per = percent * BUFFER_FULL_PERCENT_DEFAULT / BUFFER_HIGH_PERCENT_DEFAULT;
929         if (percent_ < per) {
930             percent_ = per;
931         }
932     }
933 
934     if (lastPercent == percent_) {
935         return;
936     }
937 
938     std::shared_ptr<IPlayerEngineObs> tempObs = obs_.lock();
939     if (tempObs != nullptr) {
940         Format format;
941         (void)format.PutIntValue(std::string(PlayerKeys::PLAYER_BUFFERING_PERCENT), percent_);
942         MEDIA_LOGD("percent = (%{public}d), percent_ = %{public}d, 0x%{public}06" PRIXPTR "",
943             percent, percent_, FAKE_POINTER(this));
944         tempObs->OnInfo(INFO_TYPE_BUFFERING_UPDATE, 0, format);
945     }
946 }
947 
OnMqNumUseBufferingCb(const GstPlayer * player,guint mqNumUseBuffering,GstPlayerCtrl * playerGst)948 void GstPlayerCtrl::OnMqNumUseBufferingCb(const GstPlayer *player, guint mqNumUseBuffering, GstPlayerCtrl *playerGst)
949 {
950     CHECK_AND_RETURN_LOG(player != nullptr, "player is null");
951     CHECK_AND_RETURN_LOG(playerGst != nullptr, "playerGst is null");
952     playerGst->ProcessMqNumUseBuffering(player, mqNumUseBuffering);
953 }
954 
ProcessMqNumUseBuffering(const GstPlayer * cbPlayer,uint32_t mqNumUseBuffering)955 void GstPlayerCtrl::ProcessMqNumUseBuffering(const GstPlayer *cbPlayer, uint32_t mqNumUseBuffering)
956 {
957     if (cbPlayer != gstPlayer_) {
958         MEDIA_LOGE("gstplay cb object error: cbPlayer != gstPlayer_");
959         return;
960     }
961 
962     MEDIA_LOGD("mqNumUseBuffering = (%{public}u)", mqNumUseBuffering);
963     mqNumUseBuffering_ = mqNumUseBuffering;
964 }
965 
OnPositionUpdatedCb(const GstPlayer * player,guint64 position,GstPlayerCtrl * playerGst)966 void GstPlayerCtrl::OnPositionUpdatedCb(const GstPlayer *player, guint64 position, GstPlayerCtrl *playerGst)
967 {
968     CHECK_AND_RETURN_LOG(player != nullptr, "player is null");
969     CHECK_AND_RETURN_LOG(playerGst != nullptr, "playerGst is null");
970     playerGst->ProcessPositionUpdated(player, static_cast<uint64_t>(position) / MICRO);
971 }
972 
ProcessPositionUpdated(const GstPlayer * cbPlayer,uint64_t position)973 void GstPlayerCtrl::ProcessPositionUpdated(const GstPlayer *cbPlayer, uint64_t position)
974 {
975     if (cbPlayer != gstPlayer_) {
976         MEDIA_LOGE("gstplay cb object error: cbPlayer != gstPlayer_");
977         return;
978     }
979     lastTime_ = position;
980 
981     // position = 99643, duration_ = 99591
982     position = std::min(position, sourceDuration_);
983     Format format;
984     std::shared_ptr<IPlayerEngineObs> tempObs = obs_.lock();
985     if (tempObs != nullptr) {
986         MEDIA_LOGD("ProcessPositionUpdated(%{public}" PRIu64 "), 0x%{public}06" PRIXPTR "",
987             position, FAKE_POINTER(this));
988         tempObs->OnInfo(INFO_TYPE_POSITION_UPDATE, static_cast<int32_t>(position), format);
989     }
990 }
991 
OnVolumeChangeCb(const GObject * combiner,const GParamSpec * pspec,const GstPlayerCtrl * playerGst)992 void GstPlayerCtrl::OnVolumeChangeCb(const GObject *combiner, const GParamSpec *pspec, const GstPlayerCtrl *playerGst)
993 {
994     (void)combiner;
995     (void)pspec;
996 
997     MEDIA_LOGI("OnVolumeChangeCb in");
998     CHECK_AND_RETURN_LOG(playerGst != nullptr, "playerGst is null");
999     playerGst->OnVolumeChange();
1000 }
1001 
OnVolumeChange() const1002 void GstPlayerCtrl::OnVolumeChange() const
1003 {
1004     Format format;
1005     std::shared_ptr<IPlayerEngineObs> tempObs = obs_.lock();
1006     if (tempObs != nullptr) {
1007         MEDIA_LOGI("OnVolumeChange");
1008         tempObs->OnInfo(INFO_TYPE_VOLUME_CHANGE, 0, format);
1009     }
1010 }
1011 
OnStateChanged(PlayerStates state)1012 void GstPlayerCtrl::OnStateChanged(PlayerStates state)
1013 {
1014     if (state == PLAYER_PREPARED) {
1015         InitDuration();
1016         GetAudioSink();
1017         MEDIA_LOGW("KPI-TRACE: prepared");
1018     }
1019 
1020     currentState_ = state;
1021     MEDIA_LOGI("On State callback state: %{public}d", state);
1022     std::shared_ptr<IPlayerEngineObs> tempObs = obs_.lock();
1023     Format format;
1024     if (tempObs != nullptr) {
1025         MEDIA_LOGD("OnStateChanged %{public}d", state);
1026         tempObs->OnInfo(INFO_TYPE_STATE_CHANGE, static_cast<int32_t>(state), format);
1027     }
1028 }
1029 
OnNotify(PlayerStates state)1030 void GstPlayerCtrl::OnNotify(PlayerStates state)
1031 {
1032     switch (state) {
1033         case PLAYER_PREPARED:
1034             condVarPauseSync_.notify_all();
1035             condVarPreparingSync_.notify_all();
1036             preparing_ = false;
1037             break;
1038         case PLAYER_STARTED:
1039             condVarPlaySync_.notify_all();
1040             break;
1041         case PLAYER_PAUSED:
1042         case PLAYER_PLAYBACK_COMPLETE:
1043             condVarPauseSync_.notify_all();
1044             break;
1045         case PLAYER_STOPPED:
1046             condVarStopSync_.notify_all();
1047             break;
1048         default:
1049             break;
1050     }
1051 }
1052 
OnSeekDone()1053 void GstPlayerCtrl::OnSeekDone()
1054 {
1055     if (seekDoneNeedCb_) {
1056         MEDIA_LOGI("On Seek Done: (%{public}" PRIu64 ")", seekDonePosition_);
1057         std::shared_ptr<IPlayerEngineObs> tempObs = obs_.lock();
1058         Format format;
1059         if (tempObs != nullptr) {
1060             if (speeding_) {
1061                 tempObs->OnInfo(INFO_TYPE_SPEEDDONE, 0, format);
1062                 speeding_ = false;
1063             } else {
1064                 tempObs->OnInfo(INFO_TYPE_SEEKDONE, static_cast<int32_t>(seekDonePosition_), format);
1065                 seeking_ = false;
1066             }
1067         }
1068         seekDoneNeedCb_ = false;
1069         condVarSeekSync_.notify_all();
1070     }
1071 }
1072 
OnEndOfStream()1073 void GstPlayerCtrl::OnEndOfStream()
1074 {
1075     if (endOfStreamCb_) {
1076         MEDIA_LOGI("On EndOfStream: loop is %{public}d", enableLooping_);
1077         std::shared_ptr<IPlayerEngineObs> tempObs = obs_.lock();
1078         Format format;
1079         if (tempObs != nullptr) {
1080             tempObs->OnInfo(INFO_TYPE_EOS, static_cast<int32_t>(enableLooping_), format);
1081         }
1082         endOfStreamCb_ = false;
1083     }
1084 }
1085 
OnMessage(int32_t extra) const1086 void GstPlayerCtrl::OnMessage(int32_t extra) const
1087 {
1088     MEDIA_LOGI("On Message callback info: %{public}d", extra);
1089     std::shared_ptr<IPlayerEngineObs> tempObs = obs_.lock();
1090     Format format;
1091     if (tempObs != nullptr) {
1092         tempObs->OnInfo(INFO_TYPE_MESSAGE, extra, format);
1093     }
1094 }
1095 
OnBufferingUpdate(const std::string Message) const1096 void GstPlayerCtrl::OnBufferingUpdate(const std::string Message) const
1097 {
1098     MEDIA_LOGI("On Message callback info: %{public}s", Message.c_str());
1099     std::shared_ptr<IPlayerEngineObs> tempObs = obs_.lock();
1100     if (tempObs != nullptr) {
1101         Format format;
1102         (void)format.PutIntValue(Message, 0);
1103         tempObs->OnInfo(INFO_TYPE_BUFFERING_UPDATE, 0, format);
1104     }
1105 }
1106 
ProcessStoppedState()1107 PlayerStates GstPlayerCtrl::ProcessStoppedState()
1108 {
1109     PlayerStates newState = PLAYER_STOPPED;
1110     if (userStop_ || errorFlag_) {
1111         userStop_ = false;
1112     } else if (IsLiveMode()) {
1113         if (currentState_ == PLAYER_STARTED) {
1114             newState = PLAYER_PLAYBACK_COMPLETE;
1115         }
1116     } else {
1117         if (currentState_ == PLAYER_STARTED) {
1118             newState = PLAYER_STARTED;
1119             locatedInEos_ = enableLooping_ ? false : true;
1120         }
1121     }
1122 
1123     if (currentState_ == PLAYER_PREPARING) {
1124         // return stop when vidoe/audio prepare failed, notify pause finished
1125         condVarPauseSync_.notify_all();
1126         condVarPreparingSync_.notify_all();
1127         preparing_ = false;
1128     }
1129     return newState;
1130 }
1131 
ProcessPausedState()1132 PlayerStates GstPlayerCtrl::ProcessPausedState()
1133 {
1134     PlayerStates newState = PLAYER_PAUSED;
1135 
1136     if ((currentState_ == PLAYER_PREPARING) ||
1137         (currentState_ == PLAYER_STOPPED) ||
1138         (currentState_ == PLAYER_PREPARED)) {
1139         newState = PLAYER_PREPARED;
1140     } else if (currentState_ == PLAYER_PLAYBACK_COMPLETE) {
1141         newState = PLAYER_PLAYBACK_COMPLETE;
1142     } else if (currentState_ == PLAYER_STARTED && locatedInEos_) {
1143         newState = PLAYER_PLAYBACK_COMPLETE;
1144         locatedInEos_ = false;
1145     } else {
1146         newState = PLAYER_PAUSED;
1147     }
1148     MEDIA_LOGI("ProcessPausedState currentStatus: %{public}d, newState: %{public}d", currentState_, newState);
1149 
1150     return newState;
1151 }
1152 
InitDuration()1153 void GstPlayerCtrl::InitDuration()
1154 {
1155     CHECK_AND_RETURN_LOG(gstPlayer_ != nullptr, "gstPlayer_ is nullptr");
1156     GstClockTime time = gst_player_get_duration(gstPlayer_);
1157     if (time != GST_CLOCK_TIME_NONE) {
1158         sourceDuration_ = static_cast<uint64_t>(time) / MICRO;
1159     } else {
1160         sourceDuration_ = GST_CLOCK_TIME_NONE;
1161     }
1162 
1163     MEDIA_LOGD("InitDuration duration(%{public}" PRIu64 ")", sourceDuration_);
1164 }
1165 
IsLiveMode() const1166 bool GstPlayerCtrl::IsLiveMode() const
1167 {
1168     if (appsrcWarp_ != nullptr && appsrcWarp_->IsLiveMode()) {
1169         return true;
1170     }
1171 
1172     if (sourceDuration_ == GST_CLOCK_TIME_NONE) {
1173         return true;
1174     }
1175 
1176     return false;
1177 }
1178 
SetAudioRendererInfo(const Format & param)1179 bool GstPlayerCtrl::SetAudioRendererInfo(const Format &param)
1180 {
1181     CHECK_AND_RETURN_RET_LOG(audioSink_ != nullptr, false, "audioSink_ is nullptr");
1182 
1183     int32_t contentType = 0;
1184     int32_t streamUsage = 0;
1185 
1186     if (param.GetIntValue(PlayerKeys::CONTENT_TYPE, contentType) &&
1187         param.GetIntValue(PlayerKeys::STREAM_USAGE, streamUsage)) {
1188         int32_t rendererInfo(0);
1189         CHECK_AND_RETURN_RET(streamUsage >= 0 && contentType >= 0, false);
1190         rendererInfo |= (contentType | (static_cast<uint32_t>(streamUsage) <<
1191             AudioStandard::RENDERER_STREAM_USAGE_SHIFT));
1192         g_object_set(audioSink_, "audio-renderer-desc", rendererInfo, nullptr);
1193         return true;
1194     } else {
1195         MEDIA_LOGI("parameter doesn't contain content_type or stream_usage");
1196         return false;
1197     }
1198 }
1199 } // namespace Media
1200 } // namespace OHOS
1201