[MM] Report BufferingState when player is prepared and seeked.
[platform/framework/web/chromium-efl.git] / tizen_src / chromium_impl / media / filters / media_player_esplusplayer.cc
1 // Copyright 2022 Samsung Electronics Inc. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "tizen_src/chromium_impl/media/filters/media_player_esplusplayer.h"
6
7 #include <esplusplayer_internal.h>
8 #include <tbm_surface.h>
9
10 #include "base/functional/bind.h"
11 #include "base/functional/callback.h"
12 #include "base/location.h"
13 #include "base/logging.h"
14 #include "media/base/decoder_buffer.h"
15 #include "third_party/libyuv/include/libyuv/convert.h"
16 #include "tizen_src/chromium_impl/media/filters/esplusplayer_buffer_observer_impl.h"
17 #include "tizen_src/chromium_impl/media/filters/media_player_tizen_client.h"
18
19 #if defined(TIZEN_VIDEO_HOLE)
20 #include <Ecore_Wl2.h>
21 #include "tizen_src/chromium_impl/media/base/tizen/video_plane_controller_esplusplayer.h"
22 #endif
23
24 namespace media {
25
26 // The delay time before retrying ReadBuffer.
27 // Wait until there is space in the buffer.
28 const base::TimeDelta kBufferQueueReadDelay = base::Milliseconds(100);
29
30 // The difference between the played timestamp and
31 // the time stamp of the buffered data.
32 const base::TimeDelta kMinWaitTimeForPlayback = base::Milliseconds(500);
33
34 // The delay time to check buffering and decide operations.
35 const base::TimeDelta kOperationDecisionDelay = base::Milliseconds(500);
36
37 player_buffer_size_t GetMaxAudioBufferSize() {
38   return kPlayerAudioBufferSize;
39 }
40
41 void ReadyToPrepareCallback(const esplusplayer_stream_type stream_type,
42                             void* user_data) {
43   MediaPlayerESPlusPlayer* player =
44       static_cast<MediaPlayerESPlusPlayer*>(user_data);
45   if (!player)
46     return;
47
48   player->OnReadyToPrepare(stream_type);
49 }
50
51 void PrepareCompleteCallback(bool result, void* user_data) {
52   MediaPlayerESPlusPlayer* player =
53       static_cast<MediaPlayerESPlusPlayer*>(user_data);
54   if (!player)
55     return;
56
57   player->OnPrepareComplete(result);
58 }
59
60 void EosCallback(void* user_data) {
61   MediaPlayerESPlusPlayer* player =
62       static_cast<MediaPlayerESPlusPlayer*>(user_data);
63   if (!player)
64     return;
65
66   player->OnEos();
67 }
68
69 void FrameReadyCallback(const esplusplayer_decoded_video_packet* packet,
70                         void* user_data) {
71   MediaPlayerESPlusPlayer* player =
72       static_cast<MediaPlayerESPlusPlayer*>(user_data);
73   if (!player)
74     return;
75
76   player->OnFrameReady(packet);
77 }
78
79 void FlushCompleteCallback(void* user_data) {
80   MediaPlayerESPlusPlayer* player =
81       static_cast<MediaPlayerESPlusPlayer*>(user_data);
82   if (!player)
83     return;
84
85   player->OnFlushComplete();
86 }
87
88 void ReadyToSeekCallback(const esplusplayer_stream_type stream_type,
89                          const uint64_t seek_time,
90                          void* user_data) {
91   MediaPlayerESPlusPlayer* player =
92       static_cast<MediaPlayerESPlusPlayer*>(user_data);
93   if (!player)
94     return;
95
96   player->OnReadyToSeek(stream_type, seek_time);
97 }
98
99 void SeekCompleteCallback(void* user_data) {
100   MediaPlayerESPlusPlayer* player =
101       static_cast<MediaPlayerESPlusPlayer*>(user_data);
102   if (!player)
103     return;
104
105   player->OnSeekComplete();
106 }
107
108 void ResourceConflictCallback(void* user_data) {
109   MediaPlayerESPlusPlayer* player =
110       static_cast<MediaPlayerESPlusPlayer*>(user_data);
111   if (!player)
112     return;
113
114   player->OnResourceConflict();
115 }
116
117 void ErrorCallback(const esplusplayer_error_type error_type, void* user_data) {
118   MediaPlayerESPlusPlayer* player =
119       static_cast<MediaPlayerESPlusPlayer*>(user_data);
120   if (!player)
121     return;
122
123   player->OnError(error_type);
124 }
125
126 MediaPlayerESPlusPlayer::MediaPlayerESPlusPlayer() {
127   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
128 }
129
130 MediaPlayerESPlusPlayer::~MediaPlayerESPlusPlayer() {
131 #if BUILDFLAG(IS_TIZEN_TV)
132   if (!esplayer_) {
133     LOG_ID(INFO, player_id_) << "player is already destroyed:" << (void*)this;
134     return;
135   }
136 #endif
137
138   LOG_ID(INFO, player_id_) << "(" << static_cast<void*>(this) << ") "
139                            << __func__;
140   weak_factory_.InvalidateWeakPtrs();
141
142   // Player should be released before destroyed.
143   Release();
144
145   int error = esplusplayer_destroy(esplayer_);
146   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE)
147     LOG(ERROR) << "esplusplayer_destroy failed, error #"
148                << esplusplayer_get_error_string(
149                       static_cast<esplusplayer_error_type>(error));
150   esplayer_ = nullptr;
151 }
152
153 #if BUILDFLAG(IS_TIZEN_TV)
154 void MediaPlayerESPlusPlayer::DestroyPlayerSync(base::OnceClosure destroy_cb) {
155   if (!esplayer_) {
156     LOG_ID(INFO, player_id_) << "player is already destroyed:" << (void*)this;
157     std::move(destroy_cb).Run();
158     return;
159   }
160
161   LOG_ID(INFO, player_id_) << "(" << static_cast<void*>(this) << ") "
162                            << __func__;
163   weak_factory_.InvalidateWeakPtrs();
164
165   Release();
166
167   int error = esplusplayer_destroy(esplayer_);
168   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE)
169     LOG_ID(ERROR, player_id_)
170         << "esplusplayer_destroy failed, error #"
171         << esplusplayer_get_error_string(
172                static_cast<esplusplayer_error_type>(error));
173   esplayer_ = nullptr;
174
175   std::move(destroy_cb).Run();
176 }
177 #endif
178
179 bool MediaPlayerESPlusPlayer::CreatePlayer(int player_id) {
180   player_id_ = player_id;
181
182   if (esplayer_)
183     return true;
184
185   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
186   esplayer_ = esplusplayer_create();
187   if (!esplayer_) {
188     LOG(ERROR) << "Cannot create esplus player!";
189     return false;
190   }
191
192   last_frames_.get<DemuxerStream::AUDIO>().first = media::kNoTimestamp;
193   last_frames_.get<DemuxerStream::AUDIO>().second = media::kNoTimestamp;
194   last_frames_.get<DemuxerStream::VIDEO>().first = media::kNoTimestamp;
195   last_frames_.get<DemuxerStream::VIDEO>().second = media::kNoTimestamp;
196
197   buffer_observer_.reset(new ESPlusPlayerBufferObserverImpl(esplayer_));
198
199 #if defined(TIZEN_VIDEO_HOLE)
200   LOG(INFO) << __func__ << " is_video_hole_: " << is_video_hole_;
201   if (is_video_hole_) {
202     video_plane_controller_.reset(
203         new VideoPlaneControllerESPlusPlayer(esplayer_));
204   }
205 #endif
206
207   return true;
208 }
209
210 void MediaPlayerESPlusPlayer::Initialize(VideoRendererSink* sink) {
211   LOG_ID(INFO, player_id_) << "(" << static_cast<void*>(this) << ") "
212                            << __func__;
213
214   if (!esplayer_) {
215     LOG_ID(INFO, player_id_) << "(" << static_cast<void*>(this) << ") "
216                              << "esplayer is null.";
217     return;
218   }
219
220   esplusplayer_set_ready_to_prepare_cb(esplayer_, &ReadyToPrepareCallback,
221                                        this);
222   esplusplayer_set_prepare_async_done_cb(esplayer_, &PrepareCompleteCallback,
223                                          this);
224   esplusplayer_set_eos_cb(esplayer_, &EosCallback, this);
225   esplusplayer_set_media_packet_video_decoded_cb(esplayer_, &FrameReadyCallback,
226                                                  this);
227   esplusplayer_set_flush_done_cb(esplayer_, &FlushCompleteCallback, this);
228   esplusplayer_set_ready_to_seek_cb(esplayer_, &ReadyToSeekCallback, this);
229   esplusplayer_set_seek_done_cb(esplayer_, &SeekCompleteCallback, this);
230   esplusplayer_set_resource_conflicted_cb(esplayer_, &ResourceConflictCallback,
231                                           this);
232   esplusplayer_set_error_cb(esplayer_, &ErrorCallback, this);
233   buffer_observer_->SetBufferingCallback(
234       base::BindRepeating(&MediaPlayerESPlusPlayer::OnBufferingStatusChanged,
235                           weak_factory_.GetWeakPtr()));
236
237   int error = esplusplayer_open(esplayer_);
238   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
239     LOG(ERROR) << "esplusplayer_open failed. error #"
240                << esplusplayer_get_error_string(
241                       static_cast<esplusplayer_error_type>(error));
242     return;
243   }
244
245   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
246             << " state:" << GetString(GetPlayerState());
247
248   if (!SetBufferType(VideoDecoderConfig{}))
249     return;
250
251   sink_ = sink;
252 }
253
254 bool MediaPlayerESPlusPlayer::IsInitialized() {
255   return (GetPlayerState() >= ESPLUSPLAYER_STATE_IDLE);
256 }
257
258 void MediaPlayerESPlusPlayer::SetTaskRunner(
259     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
260   task_runner_ = task_runner.get();
261 }
262
263 void MediaPlayerESPlusPlayer::SetStreamInfo(DemuxerStream::Type type,
264                                             DemuxerStream* stream) {
265   if (!esplayer_) {
266     LOG(ERROR) << "Invalid player handle. Send error to client.";
267     GetMediaPlayerClient()->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
268     return;
269   }
270
271   SetDemuxerStream(type, stream);
272   InitializeStreamConfig(type);
273 }
274
275 void MediaPlayerESPlusPlayer::Prepare() {
276   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
277   if (!esplayer_ || is_prepared_ || is_preparing_) {
278     LOG_ID(ERROR, player_id_)
279         << "(" << static_cast<void*>(this) << ") " << __func__
280         << ", esplayer_: " << static_cast<void*>(esplayer_)
281         << ", is_prepared_: " << is_prepared_
282         << ", is_preparing_: " << is_preparing_;
283     return;
284   }
285
286   if (GetPlayerState() != ESPLUSPLAYER_STATE_IDLE) {
287     LOG(ERROR) << "(" << static_cast<void*>(this) << ") " << __func__
288                << " Prepare called on invalid state : "
289                << GetString(GetPlayerState());
290     return;
291   }
292
293   int error = esplusplayer_set_display_visible(esplayer_, true);
294   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
295     LOG(ERROR)
296         << "esplusplayer_set_display_visible failed! error #"
297         << esplusplayer_get_error_string(
298                static_cast<esplusplayer_error_type>(error));
299   }
300
301   error = esplusplayer_prepare_async(esplayer_);
302   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
303     LOG(ERROR) << "player prepare failed! error #"
304                << esplusplayer_get_error_string(
305                       static_cast<esplusplayer_error_type>(error));
306
307     GetMediaPlayerClient()->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
308     return;
309   }
310   is_preparing_ = true;
311 }
312
313 bool MediaPlayerESPlusPlayer::IsPrepared() {
314   return (GetPlayerState() >= ESPLUSPLAYER_STATE_READY);
315 }
316
317 bool MediaPlayerESPlusPlayer::CanPrepare() {
318   return esplayer_ && !IsPrepared() && !is_preparing_;
319 }
320
321 void MediaPlayerESPlusPlayer::Release() {
322   if (!esplayer_)
323     return;
324
325   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
326   if (GetPlayerState() != ESPLUSPLAYER_STATE_NONE)
327     esplusplayer_stop(esplayer_);
328
329   SetIsEos(DemuxerStream::AUDIO, false);
330   SetShouldFeed(DemuxerStream::AUDIO, false);
331   SetIsValid(DemuxerStream::AUDIO, false);
332   SetReadRequested(DemuxerStream::AUDIO, false);
333
334   SetIsEos(DemuxerStream::VIDEO, false);
335   SetShouldFeed(DemuxerStream::VIDEO, false);
336   SetIsValid(DemuxerStream::VIDEO, false);
337   SetReadRequested(DemuxerStream::VIDEO, false);
338
339   esplusplayer_set_ready_to_prepare_cb(esplayer_, nullptr, this);
340   esplusplayer_set_prepare_async_done_cb(esplayer_, nullptr, this);
341   esplusplayer_set_eos_cb(esplayer_, nullptr, this);
342   esplusplayer_set_media_packet_video_decoded_cb(esplayer_, nullptr, this);
343   esplusplayer_set_flush_done_cb(esplayer_, nullptr, this);
344   esplusplayer_set_ready_to_seek_cb(esplayer_, nullptr, this);
345   esplusplayer_set_seek_done_cb(esplayer_, nullptr, this);
346   esplusplayer_set_resource_conflicted_cb(esplayer_, nullptr, this);
347   esplusplayer_set_error_cb(esplayer_, nullptr, this);
348
349   buffer_observer_->ResetBufferStatus();
350   buffer_observer_->ResetBufferStatusCallbacks();
351
352   reported_buffering_state_ = BUFFERING_HAVE_NOTHING;
353
354   volume_ = 1.0;
355   playback_rate_ = 0.0;
356   is_prepared_ = false;
357   is_preparing_ = false;
358   is_paused_ = true;
359   is_buffering_ = false;
360   current_position_ = base::TimeDelta();
361   is_seeking_ = false;
362   expected_seek_ = false;
363   seek_position_ = base::TimeDelta();
364   pending_seek_ = false;
365   pending_seek_position_ = base::TimeDelta();
366   should_set_playback_rate_ = false;
367
368   GetBufferQueue(DemuxerStream::VIDEO).clear();
369   GetBufferQueue(DemuxerStream::AUDIO).clear();
370   sink_ = nullptr;
371
372   StopOperationForDataTimer();
373
374   if (GetPlayerState() == ESPLUSPLAYER_STATE_NONE) {
375     LOG(ERROR) << "(" << static_cast<void*>(this) << ") " << __func__
376                << " Release called on invalid state : "
377                << GetString(GetPlayerState());
378     return;
379   }
380
381   esplusplayer_close(esplayer_);
382 }
383
384 bool MediaPlayerESPlusPlayer::Play() {
385   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
386   int error = ESPLUSPLAYER_ERROR_TYPE_NONE;
387   esplusplayer_state state = GetPlayerState();
388
389   is_paused_ = false;
390   if ((state < ESPLUSPLAYER_STATE_READY) || !is_prepared_ || is_seeking_) {
391     LOG(INFO) << "state : " << GetString(state)
392               << " is_prepared : " << is_prepared_
393               << " is_seeking : " << is_seeking_
394               << " is_buffering : " << is_buffering_;
395     return false;
396   }
397
398   if (is_buffering_) {
399     LOG(INFO) << "state : " << GetString(state) << " is_paused : " << is_paused_
400               << " is_buffering : " << is_buffering_;
401     // return;
402   }
403
404   SetVolume(volume_);
405   if (should_set_playback_rate_)
406     SetRate(playback_rate_);
407
408   if (state == ESPLUSPLAYER_STATE_READY)
409     error = esplusplayer_start(esplayer_);
410   else if ((state == ESPLUSPLAYER_STATE_PAUSED) ||
411            (state == ESPLUSPLAYER_STATE_PLAYING))
412     error = esplusplayer_resume(esplayer_);
413
414   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
415     LOG(ERROR) << "player play failed! state #" << GetString(state)
416                << " error #"
417                << esplusplayer_get_error_string(
418                       static_cast<esplusplayer_error_type>(error));
419     // TODO: handle error!
420     return false;
421   }
422
423   // To submit packets when playback starts.
424   if (IsValid(DemuxerStream::VIDEO))
425     ReadBuffer(DemuxerStream::VIDEO);
426   if (IsValid(DemuxerStream::AUDIO))
427     ReadBuffer(DemuxerStream::AUDIO);
428
429   return true;
430 }
431
432 void MediaPlayerESPlusPlayer::Pause(bool is_media_related_action) {
433   if (is_paused_) {
434     LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
435               << " already paused";
436     return;
437   }
438
439   if (!is_media_related_action)
440     is_paused_ = true;
441
442   // To decide operation is not needed in pause.
443   StopOperationForDataTimer();
444
445   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
446             << " is_buffering : " << is_buffering_
447             << " is_media_action : " << is_media_related_action;
448   esplusplayer_state state = GetPlayerState();
449   if (state != ESPLUSPLAYER_STATE_PLAYING) {
450     LOG(WARNING) << "Cannot pause in " << GetString(state) << " state";
451     return;
452   }
453
454   int error = esplusplayer_pause(esplayer_);
455   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
456     LOG(ERROR) << "player pause failed! error #"
457                << esplusplayer_get_error_string(
458                       static_cast<esplusplayer_error_type>(error));
459     // TODO: handle error!
460     return;
461   }
462 }
463
464 void MediaPlayerESPlusPlayer::SetRate(double rate) {
465   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__ << " : "
466             << rate;
467
468   // the playback rate from 0.0 to 2.0 in esplusplayer.
469   if (rate > 2.0) {
470     LOG(WARNING) << __func__ << " The playback rate value in esplusplayer "
471                  << " cannot exceed 2.0.";
472     rate = 2.0;
473   }
474
475   if (playback_rate_ == rate)
476     return;
477
478   playback_rate_ = rate;
479   if (GetPlayerState() < ESPLUSPLAYER_STATE_READY) {
480     should_set_playback_rate_ = true;
481     return;
482   }
483
484   int error = esplusplayer_set_playback_rate(esplayer_, playback_rate_, false);
485   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
486     LOG(ERROR) << "player set playback rate failed! error #"
487                << esplusplayer_get_error_string(
488                       static_cast<esplusplayer_error_type>(error));
489     return;
490   }
491   should_set_playback_rate_ = false;
492 }
493
494 void MediaPlayerESPlusPlayer::Seek(base::TimeDelta time,
495                                    base::OnceClosure seek_cb) {
496   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__ << " :"
497             << time;
498
499   expected_seek_ = false;
500   // Ignore seek in release state. Will catch-up later.
501   if (GetPlayerState() == ESPLUSPLAYER_STATE_NONE) {
502     LOG(INFO) << __func__ << " Ignore seek in release state.";
503     if (seek_cb)
504       std::move(seek_cb).Run();
505     return;
506   }
507
508   if ((GetPlayerState() < ESPLUSPLAYER_STATE_READY) || !is_prepared_) {
509     // Prevent to set the same pending seek position and
510     // stop pushing again from 0sec when media starts 0.
511     if (time == pending_seek_position_) {
512       if (seek_cb)
513         std::move(seek_cb).Run();
514       return;
515     }
516
517     LOG(INFO) << "Add to pending seek ("
518               << ") state: " << GetString(GetPlayerState())
519               << " is_prepared : " << is_prepared_;
520     pending_seek_ = true;
521     pending_seek_position_ = time;
522
523     if (seek_cb)
524       std::move(seek_cb).Run();
525     return;
526   }
527
528   if (is_seeking_ && seek_position_ == time) {
529     LOG(INFO) << __func__ << " Seeking the same position.";
530     if (seek_cb)
531       std::move(seek_cb).Run();
532     return;
533   }
534
535   seek_cb_ = std::move(seek_cb);
536
537   SeekInternal(time);
538 }
539
540 void MediaPlayerESPlusPlayer::SeekInternal(base::TimeDelta time) {
541   int error = esplusplayer_seek(esplayer_, time.InMilliseconds());
542   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
543     LOG(ERROR) << "Seek failed. Current time : " << time.InSecondsF()
544                << " error #"
545                << esplusplayer_get_error_string(
546                       static_cast<esplusplayer_error_type>(error));
547     return;
548   }
549
550   is_seeking_ = true;
551   seek_position_ = time;
552   pending_seek_ = false;
553   pending_seek_position_ = base::TimeDelta();
554   if (seek_cb_)
555     std::move(seek_cb_).Run();
556 }
557
558 void MediaPlayerESPlusPlayer::Flush(base::OnceClosure flush_cb) {
559   // Ignore Flush before prepared state.
560   if (GetPlayerState() < ESPLUSPLAYER_STATE_READY) {
561     LOG(INFO) << "player is not ready, state:" << GetString(GetPlayerState());
562     if (flush_cb)
563       std::move(flush_cb).Run();
564     return;
565   }
566   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
567
568   ReportBufferingStateIfNeeded(BUFFERING_HAVE_NOTHING,
569                                BUFFERING_CHANGE_REASON_UNKNOWN);
570
571   last_frames_.get<DemuxerStream::AUDIO>().first = media::kNoTimestamp;
572   last_frames_.get<DemuxerStream::VIDEO>().first = media::kNoTimestamp;
573
574   UpdateBufferedDtsDifference();
575
576   expected_seek_ = true;
577   SetShouldFeed(DemuxerStream::AUDIO, false);
578   SetShouldFeed(DemuxerStream::VIDEO, false);
579   GetBufferQueue(DemuxerStream::VIDEO).clear();
580   GetBufferQueue(DemuxerStream::AUDIO).clear();
581   buffer_observer_->ResetBufferStatus();
582
583   std::move(flush_cb).Run();
584 }
585
586 void MediaPlayerESPlusPlayer::SetVolume(double volume) {
587   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__ << " :"
588             << volume;
589   volume_ = volume;
590   if (GetPlayerState() == ESPLUSPLAYER_STATE_NONE)
591     return;
592
593   int error = esplusplayer_set_volume(esplayer_, 100 * volume_);
594   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE)
595     LOG(ERROR) << "esplusplayer_set_volume failed, error #"
596                << esplusplayer_get_error_string(
597                       static_cast<esplusplayer_error_type>(error));
598 }
599
600 base::TimeDelta MediaPlayerESPlusPlayer::GetCurrentTime() {
601   if (pending_seek_)
602     return pending_seek_position_;
603
604   if (is_seeking_)
605     return seek_position_;
606
607   // Seek can be called before PLAY / PAUSE. Return last known time.
608   if (GetPlayerState() < ESPLUSPLAYER_STATE_PLAYING)
609     return current_position_;
610
611   // esplusplayer_get_playing_time is sync api, need called after prepared.
612   // Otherwise will block browser process.
613   if (!is_prepared_)
614     return base::TimeDelta();
615
616   uint64_t time = 0;  // In milliseconds.
617   int error = esplusplayer_get_playing_time(esplayer_, &time);
618   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
619     LOG(ERROR) << "esplusplayer_get_playing_time failed. error #"
620                << esplusplayer_get_error_string(
621                       static_cast<esplusplayer_error_type>(error));
622     return base::TimeDelta();
623   }
624
625   current_position_ = base::Milliseconds(time);
626   return current_position_;
627 }
628
629 #if defined(TIZEN_TBM_SUPPORT)
630 void MediaPlayerESPlusPlayer::DestroyMediaPacket(void* media_packet) {
631   if (!task_runner_->BelongsToCurrentThread()) {
632     task_runner_->PostTask(
633         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::DestroyMediaPacket,
634                                   weak_factory_.GetWeakPtr(), media_packet));
635     return;
636   }
637
638   esplusplayer_decoded_buffer_destroy(
639       esplayer_, static_cast<esplusplayer_decoded_video_packet*>(media_packet));
640 }
641 #endif
642
643 esplusplayer_state MediaPlayerESPlusPlayer::GetPlayerState() {
644   return (esplayer_ ? esplusplayer_get_state(esplayer_)
645                     : ESPLUSPLAYER_STATE_NONE);
646 }
647
648 player_buffer_size_t MediaPlayerESPlusPlayer::GetMaxVideoBufferSize(
649     const media::VideoDecoderConfig& video_config) {
650   return kPlayerTotalBufferSize - kPlayerAudioBufferSize;
651 }
652
653 int MediaPlayerESPlusPlayer::SetVideoStreamInfo(
654     const media::VideoDecoderConfig& video_config,
655     esplusplayer_video_stream_info& video_stream_info) {
656   if (!SetBufferType(video_config)) {
657     LOG_ID(ERROR, player_id_) << "SetBufferType failed.";
658     return ESPLUSPLAYER_ERROR_TYPE_UNKNOWN;
659   }
660
661   video_stream_info.mime_type =
662       ConvertToESPlusVideoMimeType(video_config.codec());
663
664   // TODO: Fetch frame rate from demuxer?
665   video_stream_info.framerate_num = kVideoFramerateNum;
666   video_stream_info.framerate_den = kVideoFramerateDen;
667   video_stream_info.codec_data_length = video_config.extra_data().size();
668   if (video_stream_info.codec_data_length > 0) {
669     video_stream_info.codec_data =
670         (char*)(const_cast<unsigned char*>(video_config.extra_data().data()));
671   } else {
672     video_stream_info.codec_data = nullptr;
673   }
674   auto ri_max_resolution =
675       GetMaxResolution(video_stream_info.mime_type, is_video_hole_);
676   // |video_resolution| is the current video size, |video_max_resolution|
677   // is the potential max video size, it to say that the video source
678   // size may be changed to that size in playback state dynamically.
679   // for every video playback scenarios, the caller should set it to a
680   // suitable value to |video_max_resolution| to avoid decoder resource
681   // waste or resource conflicts.
682   auto video_max_resolution = video_config.max_coded_size();
683   auto video_resolution = video_config.coded_size();
684   LOG_ID(INFO, player_id_) << "Available max resolution from resource manager:"
685                            << ri_max_resolution.ToString()
686                            << " video max resolution:"
687                            << video_max_resolution.ToString()
688                            << " video resolution:"
689                            << video_resolution.ToString();
690
691   // Correct the video max resolution if it is smaller than video resolution.
692   video_max_resolution.SetToMax(video_resolution);
693
694   // Constrain the video resolution within the ri max resolution.
695   video_resolution.SetToMin(ri_max_resolution);
696
697   // Constrain the video max resolution within the ri max resolution.
698   video_max_resolution.SetToMin(ri_max_resolution);
699
700   video_stream_info.max_width = video_max_resolution.width();
701   video_stream_info.max_height = video_max_resolution.height();
702   video_stream_info.width = video_resolution.width();
703   video_stream_info.height = video_resolution.height();
704
705   return ESPLUSPLAYER_ERROR_TYPE_NONE;
706 }
707
708 void MediaPlayerESPlusPlayer::SetAudioStreamInfo(
709     const media::AudioDecoderConfig& audio_config,
710     esplusplayer_audio_stream_info* audio_stream_info) {
711   audio_stream_info->mime_type =
712       ConvertToESPlusAudioMimeType(audio_config.codec());
713   audio_stream_info->bitrate =
714       audio_config.bytes_per_channel() * audio_config.samples_per_second() * 8;
715   audio_stream_info->channels =
716       media::ChannelLayoutToChannelCount(audio_config.channel_layout());
717   audio_stream_info->sample_rate = audio_config.samples_per_second();
718   audio_stream_info->codec_data_length = audio_config.extra_data().size();
719
720   if (audio_stream_info->codec_data_length > 0) {
721     audio_stream_info->codec_data =
722         (char*)(const_cast<unsigned char*>(audio_config.extra_data().data()));
723   } else {
724     audio_stream_info->codec_data = nullptr;
725   }
726 }
727
728 void MediaPlayerESPlusPlayer::InitializeStreamConfig(DemuxerStream::Type type) {
729   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
730   DemuxerStream* stream = GetDemuxerStream(type);
731   CHECK(stream);
732
733   int error = ESPLUSPLAYER_ERROR_TYPE_NONE;
734   if (type == DemuxerStream::AUDIO) {
735     media::AudioDecoderConfig audio_config = stream->audio_decoder_config();
736     if (!audio_config.IsValidConfig()) {
737       LOG(INFO) << "Invalid audio config";
738       return;
739     }
740
741     LOG(INFO) << "Audio config : " << audio_config.AsHumanReadableString();
742     esplusplayer_audio_stream_info audio_stream_info;
743     memset(&audio_stream_info, 0, sizeof(esplusplayer_audio_stream_info));
744
745     SetAudioStreamInfo(audio_config, &audio_stream_info);
746     if (!IsValid(type)) {
747       error = esplusplayer_set_audio_stream_info(esplayer_, &audio_stream_info);
748       if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
749         LOG(ERROR) << "esplusplayer_set_audio_stream_info failed. error code "
750                    << error;
751         GetMediaPlayerClient()->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
752         return;
753       }
754       buffer_observer_->SetMediaStreamStatusCallback(DemuxerStream::AUDIO);
755     }
756
757     player_buffer_size_t max_buffer_size = GetMaxAudioBufferSize();
758     buffer_observer_->SetBufferSize(type, max_buffer_size);
759     LOG(INFO) << "Audio Max buffer size " << max_buffer_size;
760     error = esplusplayer_set_buffer_size(
761         esplayer_, ESPLUSPLAYER_BUFFER_AUDIO_MAX_BYTE_SIZE, max_buffer_size);
762     if (error != ESPLUSPLAYER_ERROR_TYPE_NONE)
763       LOG(WARNING) << "Failed to set audio buffer to " << max_buffer_size / 1024
764                    << "KB";
765
766     SetMediaType(GetMediaType() | MediaType::Audio);
767
768     SetIsValid(type, true);
769     GetMediaPlayerClient()->OnAudioConfigChange(audio_config);
770   }
771
772   if (type == DemuxerStream::VIDEO) {
773     media::VideoDecoderConfig video_config = stream->video_decoder_config();
774     if (!video_config.IsValidConfig()) {
775       LOG(ERROR) << "Invalid video config.";
776       return;
777     }
778
779     LOG(INFO) << "Video config : " << video_config.AsHumanReadableString();
780     esplusplayer_video_stream_info video_stream_info;
781     memset(&video_stream_info, 0, sizeof(esplusplayer_video_stream_info));
782
783     error = SetVideoStreamInfo(video_config, video_stream_info);
784     if (!IsValid(type)) {
785       error = esplusplayer_set_video_stream_info(esplayer_, &video_stream_info);
786       if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
787         LOG(ERROR) << "esplusplayer_set_video_stream_info failed. error code "
788                    << error;
789         GetMediaPlayerClient()->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
790         return;
791       }
792       buffer_observer_->SetMediaStreamStatusCallback(DemuxerStream::VIDEO);
793     }
794
795     player_buffer_size_t max_buffer_size = GetMaxVideoBufferSize(video_config);
796     buffer_observer_->SetBufferSize(type, max_buffer_size);
797     LOG(INFO) << "Video Max buffer size " << max_buffer_size;
798     error = esplusplayer_set_buffer_size(
799         esplayer_, ESPLUSPLAYER_BUFFER_VIDEO_MAX_BYTE_SIZE, max_buffer_size);
800     if (error != ESPLUSPLAYER_ERROR_TYPE_NONE)
801       LOG(WARNING) << "Failed to set video buffer to " << max_buffer_size / 1024
802                    << "KB";
803
804     SetMediaType(GetMediaType() | MediaType::Video);
805
806     SetIsValid(type, true);
807     GetMediaPlayerClient()->OnVideoConfigChange(video_config);
808   }
809 }
810
811 void MediaPlayerESPlusPlayer::ReadBuffer(DemuxerStream::Type type) {
812   if (!ReadFromBufferQueue(type))
813     return;
814
815   // Avoid unnecessary or redundant read requests.
816   if (!ShouldFeed(type) || ReadRequested(type) || IsEos(type) ||
817       (is_prepared_ && is_paused_ && !is_seeking_)) {
818     return;
819   }
820
821   // If the playing statue is expected,
822   // keep running a timer to decide play or pause with data.
823   if (!is_paused_) {
824     StartOperationForDataTimer();
825   }
826
827   SetReadRequested(type, true);
828   uint32_t buffer_read_count = 1;
829   // TODO: Set correct buffer read count.
830   GetDemuxerStream(type)->Read(buffer_read_count,
831       base::BindOnce(&MediaPlayerESPlusPlayer::OnBufferReady,
832                      weak_factory_.GetWeakPtr(), type));
833 }
834
835 void MediaPlayerESPlusPlayer::PostReadBuffer(DemuxerStream::Type type) {
836   task_runner_->PostDelayedTask(
837       FROM_HERE,
838       base::BindOnce(&MediaPlayerESPlusPlayer::ReadBuffer,
839                      weak_factory_.GetWeakPtr(), type),
840       kBufferQueueReadDelay);
841 }
842
843 void MediaPlayerESPlusPlayer::OnBufferReady(
844     DemuxerStream::Type type,
845     DemuxerStream::Status status,
846     DemuxerStream::DecoderBufferVector buffers) {
847   bool should_delay_read = false;
848   switch (status) {
849     case DemuxerStream::kAborted:
850     case DemuxerStream::kError:
851       GetBufferQueue(type).clear();
852       break;
853     case DemuxerStream::kNeedBuffer:
854       should_delay_read = true;
855       break;
856     case DemuxerStream::kConfigChanged:
857       // Clear pending buffer of older config
858       GetBufferQueue(type).clear();
859       InitializeStreamConfig(type);
860       break;
861     case DemuxerStream::kOk: {
862       GetBufferQueue(type).push_back(buffers[0]);
863       break;
864     }
865   }
866
867   SetReadRequested(type, false);
868   if (should_delay_read)
869     PostReadBuffer(type);
870   else
871     ReadBuffer(type);
872 }
873
874 bool MediaPlayerESPlusPlayer::ReadFromBufferQueue(DemuxerStream::Type type) {
875   if (!GetBufferQueue(type).size())
876     return true;
877
878   esplusplayer_submit_status status = ESPLUSPLAYER_SUBMIT_STATUS_SUCCESS;
879   scoped_refptr<DecoderBuffer> buffer = GetBufferQueue(type).front();
880   if (buffer.get()->end_of_stream())
881     status = SubmitEosPacket(type);
882   else
883     status = SubmitEsPacket(type, buffer);
884
885   if (status == ESPLUSPLAYER_SUBMIT_STATUS_FULL) {
886     // If buffer is full, try again after a while.
887     PostReadBuffer(type);
888     return false;
889   }
890
891   if ((status == ESPLUSPLAYER_SUBMIT_STATUS_NOT_PREPARED) ||
892       (status == ESPLUSPLAYER_SUBMIT_STATUS_OUT_OF_MEMORY))
893     return false;
894
895   UpdateBufferedDtsDifference();
896   GetBufferQueue(type).pop_front();
897   return true;
898 }
899
900 esplusplayer_submit_status MediaPlayerESPlusPlayer::SubmitEosPacket(
901     DemuxerStream::Type type) {
902   if (IsEos(type))
903     return ESPLUSPLAYER_SUBMIT_STATUS_SUCCESS;
904
905   last_frames_[type].first = base::TimeDelta::Max();
906
907   esplusplayer_submit_status status = esplusplayer_submit_eos_packet(
908       esplayer_, GetESPlusPlayerStreamType(type));
909   if (status != ESPLUSPLAYER_SUBMIT_STATUS_SUCCESS) {
910     LOG(ERROR) << "Submit Eos (" << DemuxerStream::GetTypeName(type)
911                << ") Packet failed, ret:" << GetString(status);
912     return status;
913   }
914   buffer_observer_->SetEos(type);
915   SetIsEos(type, true);
916   return status;
917 }
918
919 esplusplayer_submit_status MediaPlayerESPlusPlayer::SubmitEsPacket(
920     DemuxerStream::Type type,
921     scoped_refptr<DecoderBuffer> buffer) {
922   esplusplayer_es_packet packet;
923   memset(&packet, 0, sizeof(esplusplayer_es_packet));
924   packet.type = GetESPlusPlayerStreamType(type);
925
926   packet.buffer = (char*)(const_cast<unsigned char*>(buffer->data()));
927   packet.buffer_size = buffer->data_size();
928   packet.pts = buffer->timestamp().InMilliseconds();
929   packet.duration = buffer->duration().InMilliseconds();
930
931   LOG(INFO) << __func__ << " " << DemuxerStream::GetTypeName(type) << " : "
932             << "Pushing esplus timestamp: " << packet.pts
933             << ", duration: " << packet.duration
934             << ", size: " << packet.buffer_size
935             << ", is_key_frame: " << buffer->is_key_frame()
936             << ", this: " << this;
937
938   // This filed only set when PushMediaPacket
939   packet.matroska_color_info = nullptr;
940   esplusplayer_submit_status status =
941       esplusplayer_submit_packet(esplayer_, &packet);
942   if (status != ESPLUSPLAYER_SUBMIT_STATUS_SUCCESS) {
943     LOG(WARNING) << "submit " << DemuxerStream::GetTypeName(type)
944                  << " packet : " << GetString(status);
945   }
946
947   last_frames_[type].first = base::Milliseconds(packet.pts);
948   last_frames_[type].second = base::Milliseconds(packet.duration);
949   return status;
950 }
951
952 void MediaPlayerESPlusPlayer::UpdateBufferedDtsDifference() {
953   // Ignore unless audio and video streams are valid.
954   if (!IsValid(DemuxerStream::AUDIO) || !IsValid(DemuxerStream::VIDEO))
955     return;
956
957   const auto& audio_ts = last_frames_.get<DemuxerStream::AUDIO>().first;
958   const auto& video_ts = last_frames_.get<DemuxerStream::VIDEO>().first;
959
960   if ((audio_ts != media::kNoTimestamp) && (video_ts != media::kNoTimestamp) &&
961       (audio_ts != base::TimeDelta::Max()) &&
962       (video_ts != base::TimeDelta::Max())) {
963     const auto av_diff = (audio_ts - video_ts).InMilliseconds();
964     buffer_observer_->SetAudioVideoDtsDifference(av_diff);
965   } else {
966     buffer_observer_->SetAudioVideoDtsDifference(0);
967   }
968 }
969
970 void MediaPlayerESPlusPlayer::OnBufferingStatusChanged(DemuxerStream::Type type,
971                                                        BufferStatus status) {
972   LOG(INFO) << __func__ << " " << DemuxerStream::GetTypeName(type) << " : "
973             << GetString(status);
974   if (expected_seek_ && is_prepared_) {
975     LOG(INFO) << "Ignore the buffer updates while seek";
976     return;
977   }
978
979   switch (status) {
980     case kBufferUnderrun:
981     case kBufferMinThreshold:
982     case kBufferNormal:
983       is_buffering_ = true;
984       SetShouldFeed(type, true);
985       ReadBuffer(type);
986       break;
987     case kBufferMaxThreshold:
988     case kBufferOverflow:
989     case kBufferEos:
990     case kBufferAhead:
991       is_buffering_ = false;
992       SetShouldFeed(type, false);
993       break;
994     case kBufferNone:
995       NOTREACHED();
996   }
997
998   if (status != kBufferNone) {
999     if (GetOperationForData() == OperationForData::PLAY) {
1000       ReportBufferingStateIfNeeded(BUFFERING_HAVE_ENOUGH,
1001                                    BUFFERING_CHANGE_REASON_UNKNOWN);
1002     }
1003   } else {
1004     ReportBufferingStateIfNeeded(BUFFERING_HAVE_NOTHING,
1005                                  BUFFERING_CHANGE_REASON_UNKNOWN);
1006   }
1007 }
1008
1009 void MediaPlayerESPlusPlayer::ReportBufferingStateIfNeeded(
1010     BufferingState buffering_state,
1011     BufferingStateChangeReason reason) {
1012   if (reported_buffering_state_ != buffering_state) {
1013     LOG(INFO) << __func__ << " Report BufferingState : " << buffering_state
1014               << ", reason : " << reason;
1015     reported_buffering_state_ = buffering_state;
1016     GetMediaPlayerClient()->OnBufferingStateChange(buffering_state, reason);
1017   }
1018 }
1019
1020 void MediaPlayerESPlusPlayer::PerformOperationForData() {
1021   // The low latency mode doesn't buffer packets. It decodes and renders
1022   // a packet at once. WebRtc uses this feature.
1023   if (is_video_low_latency_)
1024     return;
1025
1026   if (is_seeking_ || is_preparing_)
1027     return;
1028
1029   OperationForData operation = GetOperationForData();
1030   switch (operation) {
1031     case OperationForData::PLAY:
1032       ReportBufferingStateIfNeeded(BUFFERING_HAVE_ENOUGH,
1033                                    BUFFERING_CHANGE_REASON_UNKNOWN);
1034       is_paused_by_buffering_ = false;
1035       Play();
1036       break;
1037     case OperationForData::PAUSE:
1038       ReportBufferingStateIfNeeded(BUFFERING_HAVE_NOTHING,
1039                                    BUFFERING_CHANGE_REASON_UNKNOWN);
1040       is_paused_by_buffering_ = true;
1041       Pause(true);
1042       break;
1043   }
1044 }
1045
1046 MediaPlayerESPlusPlayer::OperationForData
1047 MediaPlayerESPlusPlayer::GetOperationForData() {
1048   bool has_video_media_type = GetMediaType() & MediaType::Video;
1049   bool has_audio_media_type = GetMediaType() & MediaType::Audio;
1050
1051   bool has_video_data =
1052       !has_video_media_type ||
1053       (last_frames_.get<DemuxerStream::VIDEO>().first != media::kNoTimestamp);
1054   bool has_audio_data =
1055       !has_audio_media_type ||
1056       (last_frames_.get<DemuxerStream::AUDIO>().first != media::kNoTimestamp);
1057   if (!has_video_data || !has_audio_data) {
1058     LOG(INFO) << __func__
1059               << " Video or audio data has not yet been pushed. video "
1060               << has_video_data << ", audio " << has_audio_data;
1061     return OperationForData::NONE;
1062   }
1063
1064   base::TimeDelta current_position = GetCurrentTime();
1065
1066   if (is_paused_by_buffering_) {
1067     // Get the end position of pushed data.
1068     base::TimeDelta pushed_end_position =
1069         std::min(has_video_media_type
1070                      ? last_frames_.get<DemuxerStream::VIDEO>().first +
1071                            last_frames_.get<DemuxerStream::VIDEO>().second
1072                      : base::TimeDelta::Max(),
1073                  has_audio_media_type
1074                      ? last_frames_.get<DemuxerStream::AUDIO>().first +
1075                            last_frames_.get<DemuxerStream::AUDIO>().second
1076                      : base::TimeDelta::Max());
1077     base::TimeDelta time_diff = pushed_end_position - current_position;
1078
1079     // If data has been pushed enough (>= kMinWaitTimeForPlayback)
1080     if (time_diff >= kMinWaitTimeForPlayback) {
1081       LOG(INFO) << __func__ << " Data is enough to play,";
1082       return OperationForData::PLAY;
1083     }
1084   } else {
1085     bool should_pause = false;
1086     if (has_video_media_type &&
1087         current_position >= last_frames_.get<DemuxerStream::VIDEO>().first) {
1088       should_pause = true;
1089     }
1090     if (has_audio_media_type &&
1091         current_position >= last_frames_.get<DemuxerStream::AUDIO>().first) {
1092       should_pause = true;
1093     }
1094
1095     if (should_pause) {
1096       LOG(INFO) << __func__ << " Not enough data to play.";
1097       return OperationForData::PAUSE;
1098     }
1099   }
1100
1101   return OperationForData::NONE;
1102 }
1103
1104 void MediaPlayerESPlusPlayer::StartOperationForDataTimer() {
1105   if (!operation_for_data_timer_.IsRunning()) {
1106     operation_for_data_timer_.Start(
1107         FROM_HERE, kOperationDecisionDelay, this,
1108         &MediaPlayerESPlusPlayer::PerformOperationForData);
1109   }
1110 }
1111
1112 void MediaPlayerESPlusPlayer::StopOperationForDataTimer() {
1113   if (operation_for_data_timer_.IsRunning()) {
1114     operation_for_data_timer_.Stop();
1115   }
1116 }
1117
1118 void MediaPlayerESPlusPlayer::OnReadyToPrepare(
1119     const esplusplayer_stream_type stream_type) {
1120   if (!task_runner_->BelongsToCurrentThread()) {
1121     task_runner_->PostTask(
1122         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::OnReadyToPrepare,
1123                                   weak_factory_.GetWeakPtr(), stream_type));
1124     return;
1125   }
1126
1127   LOG(INFO) << "OnReadyToPrepare : "
1128             << DemuxerStream::GetTypeName(GetDemuxerStreamType(stream_type));
1129   if ((stream_type != ESPLUSPLAYER_STREAM_TYPE_AUDIO) &&
1130       (stream_type != ESPLUSPLAYER_STREAM_TYPE_VIDEO))
1131     return;
1132
1133   DemuxerStream::Type type = GetDemuxerStreamType(stream_type);
1134   if (IsValid(type)) {
1135     SetShouldFeed(type, true);
1136     ReadBuffer(type);
1137   }
1138 }
1139
1140 void MediaPlayerESPlusPlayer::OnPrepareComplete(bool result) {
1141   if (!task_runner_->BelongsToCurrentThread()) {
1142     task_runner_->PostTask(
1143         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::OnPrepareComplete,
1144                                   weak_factory_.GetWeakPtr(), result));
1145     return;
1146   }
1147
1148   if (!result) {
1149     LOG(ERROR) << "OnPrepareComplete prepare_async failed.";
1150     GetMediaPlayerClient()->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
1151     return;
1152   }
1153
1154   if (GetPlayerState() != ESPLUSPLAYER_STATE_READY) {
1155     LOG(ERROR) << "Invalid state (" << GetString(GetPlayerState())
1156                << ") change during prepare. Returning.";
1157     return;
1158   }
1159
1160   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
1161             << " is_paused_ : " << is_paused_
1162             << " seek_position : " << seek_position_
1163             << " pending_seek_ : " << pending_seek_
1164             << " pending_seek_position_ : " << pending_seek_position_;
1165
1166   PostPrepareComplete();
1167 }
1168
1169 void MediaPlayerESPlusPlayer::PostPrepareComplete() {
1170 #if defined(TIZEN_VIDEO_HOLE)
1171   if (is_video_hole_)
1172     video_plane_controller_->ApplyDeferredVideoRectIfNeeded();
1173 #endif
1174
1175   ReportBufferingStateIfNeeded(BUFFERING_HAVE_ENOUGH,
1176                                BUFFERING_CHANGE_REASON_UNKNOWN);
1177
1178   is_prepared_ = true;
1179   is_preparing_ = false;
1180   if (pending_seek_) {
1181     GetMediaPlayerClient()->OnRequestSeek(pending_seek_position_);
1182   } else if (!is_paused_) {
1183     Play();
1184   }
1185 }
1186
1187 void MediaPlayerESPlusPlayer::OnEos() {
1188   if (!task_runner_->BelongsToCurrentThread()) {
1189     task_runner_->PostTask(FROM_HERE,
1190                            base::BindOnce(&MediaPlayerESPlusPlayer::OnEos,
1191                                           weak_factory_.GetWeakPtr()));
1192     return;
1193   }
1194
1195   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
1196   GetMediaPlayerClient()->OnEnded();
1197 }
1198
1199 void MediaPlayerESPlusPlayer::OnFrameReady(
1200     const esplusplayer_decoded_video_packet* packet) {
1201   if (!task_runner_->BelongsToCurrentThread()) {
1202     task_runner_->PostTask(
1203         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::OnFrameReady,
1204                                   weak_factory_.GetWeakPtr(), packet));
1205     return;
1206   }
1207   tbm_surface_info_s suf_info = {
1208       0,
1209   };
1210   tbm_surface_h tbm_surface = static_cast<tbm_surface_h>(packet->surface_data);
1211
1212   if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &suf_info)) {
1213     LOG(ERROR) << "|tbm_surface_get_info| failed";
1214     return;
1215   }
1216
1217   int width = static_cast<int>(suf_info.width);
1218   int height = static_cast<int>(suf_info.height);
1219   gfx::Size size(width, height);
1220
1221   base::TimeDelta timestamp = base::Milliseconds(packet->pts);
1222   DLOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
1223              << " size:" << size.ToString()
1224              << ", timestamp:" << timestamp.InMilliseconds()
1225              << ", duration:" << packet->duration << ", Player(" << esplayer_
1226              << ", state:" << GetString(GetPlayerState());
1227
1228 #if defined(TIZEN_TBM_SUPPORT)
1229   gfx::TbmBufferHandle tbm_handle;
1230   tbm_handle.tbm_surface = reinterpret_cast<uint64_t>(tbm_surface);
1231   tbm_handle.media_packet = reinterpret_cast<uint64_t>(packet);
1232   tbm_handle.player_id = player_id_;
1233   tbm_handle.width = width;
1234   tbm_handle.height = height;
1235
1236   GetMediaPlayerClient()->OnNewTbmFrameAvailable(0, tbm_handle, timestamp);
1237 #else
1238   base::UnsafeSharedMemoryRegion shared_memory;
1239   uint32_t shared_memory_size =
1240       suf_info.planes[0].size + (suf_info.planes[0].size / 2);
1241   shared_memory = base::UnsafeSharedMemoryRegion::Create(shared_memory_size);
1242   if (!shared_memory.IsValid()) {
1243     LOG(ERROR) << "Shared Memory creation failed.";
1244     return;
1245   }
1246
1247   base::WritableSharedMemoryMapping memory_mapping;
1248   memory_mapping = shared_memory.Map();
1249   if (!memory_mapping.IsValid()) {
1250     LOG(ERROR) << "Shared Memory handle could not be obtained";
1251     return;
1252   }
1253
1254   unsigned char* y_ptr = static_cast<unsigned char*>(memory_mapping.memory());
1255
1256   // Video format will always be converted to I420
1257   switch (suf_info.format) {
1258     case TBM_FORMAT_NV12: {
1259       unsigned char* u_ptr = y_ptr + suf_info.planes[0].size;
1260       unsigned char* v_ptr = u_ptr + (suf_info.planes[0].size / 4);
1261       libyuv::NV12ToI420(suf_info.planes[0].ptr, suf_info.planes[0].stride,
1262                          suf_info.planes[1].ptr, suf_info.planes[1].stride,
1263                          y_ptr, suf_info.planes[0].stride, u_ptr,
1264                          suf_info.planes[1].stride / 2, v_ptr,
1265                          suf_info.planes[1].stride / 2, suf_info.width,
1266                          suf_info.height);
1267       break;
1268     }
1269     case TBM_FORMAT_YUV420: {
1270       unsigned char* u_ptr = y_ptr + suf_info.planes[0].size;
1271       unsigned char* v_ptr = u_ptr + suf_info.planes[1].size;
1272       libyuv::I420Copy(
1273           suf_info.planes[0].ptr, suf_info.planes[0].stride,
1274           suf_info.planes[1].ptr, suf_info.planes[1].stride,
1275           suf_info.planes[2].ptr, suf_info.planes[2].stride, y_ptr,
1276           suf_info.planes[0].stride, u_ptr, suf_info.planes[1].stride, v_ptr,
1277           suf_info.planes[2].stride, suf_info.width, suf_info.height);
1278       break;
1279     }
1280     default: {
1281       NOTIMPLEMENTED();
1282       LOG(WARNING) << "Not supported format";
1283       return;
1284     }
1285   }
1286   if (!sink_) {
1287     esplusplayer_decoded_buffer_destroy(
1288         esplayer_, const_cast<esplusplayer_decoded_video_packet*>(packet));
1289     GetMediaPlayerClient()->OnNewFrameAvailable(0, std::move(shared_memory),
1290                                                 shared_memory_size, timestamp,
1291                                                 width, height);
1292   } else {
1293     uint8_t* const yuv_buffer = static_cast<uint8_t*>(memory_mapping.memory());
1294     scoped_refptr<VideoFrame> video_frame = VideoFrame::CreateFrame(
1295         media::PIXEL_FORMAT_I420, size, gfx::Rect(size), size, timestamp);
1296
1297     uint8_t* video_buf = yuv_buffer;
1298     const uint c_frm_size = shared_memory_size / 6;
1299     const uint y_frm_size = c_frm_size << 2;  // * 4;
1300
1301     // U Plane buffer.
1302     uint8_t* video_buf_u = video_buf + y_frm_size;
1303
1304     // V Plane buffer.
1305     uint8_t* video_buf_v = video_buf_u + c_frm_size;
1306
1307     libyuv::I420Copy(
1308         video_buf, video_frame.get()->stride(VideoFrame::kYPlane), video_buf_u,
1309         video_frame.get()->stride(VideoFrame::kYPlane) / 2, video_buf_v,
1310         video_frame.get()->stride(VideoFrame::kYPlane) / 2,
1311         video_frame.get()->GetWritableVisibleData(VideoFrame::kYPlane),
1312         video_frame.get()->stride(VideoFrame::kYPlane),
1313         video_frame.get()->GetWritableVisibleData(VideoFrame::kUPlane),
1314         video_frame.get()->stride(VideoFrame::kUPlane),
1315         video_frame.get()->GetWritableVisibleData(VideoFrame::kVPlane),
1316         video_frame.get()->stride(VideoFrame::kVPlane), width, height);
1317     esplusplayer_decoded_buffer_destroy(
1318         esplayer_, const_cast<esplusplayer_decoded_video_packet*>(packet));
1319
1320     sink_->PaintSingleFrame(video_frame);
1321   }
1322 #endif
1323 }
1324
1325 void MediaPlayerESPlusPlayer::OnFlushComplete() {
1326   NOTIMPLEMENTED();
1327 }
1328
1329 void MediaPlayerESPlusPlayer::OnReadyToSeek(
1330     const esplusplayer_stream_type stream_type,
1331     const uint64_t seek_time) {
1332   if (!task_runner_->BelongsToCurrentThread()) {
1333     task_runner_->PostTask(
1334         FROM_HERE,
1335         base::BindOnce(&MediaPlayerESPlusPlayer::OnReadyToSeek,
1336                        weak_factory_.GetWeakPtr(), stream_type, seek_time));
1337     return;
1338   }
1339   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__ << " : "
1340             << DemuxerStream::GetTypeName(GetDemuxerStreamType(stream_type))
1341             << " : " << seek_time;
1342
1343   if (!esplayer_) {
1344     LOG(INFO) << "player is destroyed:" << (void*)this;
1345     return;
1346   }
1347
1348   SetShouldFeed(GetDemuxerStreamType(stream_type), true);
1349   SetIsEos(GetDemuxerStreamType(stream_type), false);
1350   ReadBuffer(GetDemuxerStreamType(stream_type));
1351 }
1352
1353 void MediaPlayerESPlusPlayer::OnSeekComplete() {
1354   if (!task_runner_->BelongsToCurrentThread()) {
1355     task_runner_->PostTask(
1356         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::OnSeekComplete,
1357                                   weak_factory_.GetWeakPtr()));
1358     return;
1359   }
1360
1361   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
1362             << " is_paused:" << is_paused_;
1363
1364   ReportBufferingStateIfNeeded(BUFFERING_HAVE_ENOUGH,
1365                                BUFFERING_CHANGE_REASON_UNKNOWN);
1366
1367   current_position_ = seek_position_;
1368   is_seeking_ = false;
1369   expected_seek_ = false;
1370   seek_position_ = base::TimeDelta();
1371
1372   if (!is_paused_)
1373     Play();
1374 }
1375
1376 void MediaPlayerESPlusPlayer::OnResourceConflict() {
1377   if (!task_runner_->BelongsToCurrentThread()) {
1378     task_runner_->PostTask(
1379         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::OnResourceConflict,
1380                                   weak_factory_.GetWeakPtr()));
1381     return;
1382   }
1383
1384   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
1385   RequestSuspend(true);
1386 }
1387
1388 void MediaPlayerESPlusPlayer::OnError(const esplusplayer_error_type error) {
1389   if (!task_runner_->BelongsToCurrentThread()) {
1390     task_runner_->PostTask(FROM_HERE,
1391                            base::BindOnce(&MediaPlayerESPlusPlayer::OnError,
1392                                           weak_factory_.GetWeakPtr(), error));
1393     return;
1394   }
1395
1396   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__ << " : "
1397             << esplusplayer_get_error_string(
1398                    static_cast<esplusplayer_error_type>(error));
1399
1400   GetMediaPlayerClient()->OnError(GetPipelineError(error));
1401   Release();
1402 }
1403
1404 MediaPlayerESPlusPlayer::ElementryStream&
1405 MediaPlayerESPlusPlayer::GetElementryStream(DemuxerStream::Type type) {
1406   return elementry_stream_[GetElementryStreamIndex(type)];
1407 }
1408
1409 const MediaPlayerESPlusPlayer::ElementryStream&
1410 MediaPlayerESPlusPlayer::GetElementryStream(DemuxerStream::Type type) const {
1411   return elementry_stream_[GetElementryStreamIndex(type)];
1412 }
1413
1414 bool MediaPlayerESPlusPlayer::IsValid(DemuxerStream::Type type) const {
1415   return GetElementryStream(type).is_valid_;
1416 }
1417
1418 void MediaPlayerESPlusPlayer::SetIsValid(DemuxerStream::Type type, bool value) {
1419   GetElementryStream(type).is_valid_ = value;
1420 }
1421
1422 bool MediaPlayerESPlusPlayer::IsEos(DemuxerStream::Type type) const {
1423   return GetElementryStream(type).is_eos_;
1424 }
1425
1426 void MediaPlayerESPlusPlayer::SetIsEos(DemuxerStream::Type type, bool value) {
1427   GetElementryStream(type).is_eos_ = value;
1428 }
1429
1430 bool MediaPlayerESPlusPlayer::ShouldFeed(DemuxerStream::Type type) const {
1431   return GetElementryStream(type).should_feed_;
1432 }
1433
1434 void MediaPlayerESPlusPlayer::SetShouldFeed(DemuxerStream::Type type,
1435                                             bool value) {
1436   GetElementryStream(type).should_feed_ = value;
1437 }
1438
1439 bool MediaPlayerESPlusPlayer::ReadRequested(DemuxerStream::Type type) const {
1440   return GetElementryStream(type).read_requested_;
1441 }
1442
1443 void MediaPlayerESPlusPlayer::SetReadRequested(DemuxerStream::Type type,
1444                                                bool value) {
1445   GetElementryStream(type).read_requested_ = value;
1446 }
1447
1448 DemuxerStream* MediaPlayerESPlusPlayer::GetDemuxerStream(
1449     DemuxerStream::Type type) const {
1450   return GetElementryStream(type).input_stream_;
1451 }
1452
1453 void MediaPlayerESPlusPlayer::SetDemuxerStream(DemuxerStream::Type type,
1454                                                DemuxerStream* stream) {
1455   GetElementryStream(type).input_stream_ = stream;
1456 }
1457
1458 Queue& MediaPlayerESPlusPlayer::GetBufferQueue(DemuxerStream::Type type) {
1459   return GetElementryStream(type).pending_buffers_;
1460 }
1461
1462 #if defined(TIZEN_VIDEO_HOLE)
1463 void MediaPlayerESPlusPlayer::SetVideoHole(bool is_video_hole) {
1464   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
1465             << " is_video_hole : " << is_video_hole;
1466   is_video_hole_ = is_video_hole;
1467   if (is_video_hole_ && esplayer_ && !video_plane_controller_) {
1468     LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
1469               << " pended set video_plane_controller";
1470     video_plane_controller_.reset(
1471         new VideoPlaneControllerESPlusPlayer(esplayer_));
1472   }
1473 }
1474
1475 void MediaPlayerESPlusPlayer::SetMediaGeometry(const gfx::Rect& viewport_rect,
1476                                                const gfx::RectF& rect) {
1477   if (!is_video_hole_)
1478     return;
1479
1480   LOG(INFO) << __func__ << " viewport_rect: " << viewport_rect.ToString()
1481             << " rect : " << rect.ToString();
1482
1483   if (!esplayer_ || !video_plane_controller_) {
1484     LOG_ID(INFO, player_id_)
1485         << "(" << static_cast<void*>(this) << ") "
1486         << "player is destroyed, or video plane controller not exist.";
1487     return;
1488   }
1489
1490   video_plane_controller_->SetMediaGeometry(viewport_rect, rect);
1491 }
1492
1493 void MediaPlayerESPlusPlayer::PrepareVideoHole() {
1494   LOG_ID(INFO, player_id_) << "(" << static_cast<void*>(this) << ") "
1495                            << __func__;
1496   if (!esplayer_ || is_prepared_ || is_preparing_) {
1497     LOG_ID(ERROR, player_id_)
1498         << "(" << static_cast<void*>(this) << ") " << __func__
1499         << ", esplayer_: " << static_cast<void*>(esplayer_)
1500         << ", is_prepared_: " << is_prepared_
1501         << ", is_preparing_: " << is_preparing_;
1502     return;
1503   }
1504   if (GetPlayerState() != ESPLUSPLAYER_STATE_IDLE) {
1505     LOG(ERROR) << "(" << static_cast<void*>(this) << ") " << __func__
1506                << " Prepare called on invalid state : "
1507                << GetString(GetPlayerState());
1508     return;
1509   }
1510
1511   if (!is_video_hole_ || !video_plane_controller_)
1512     return;
1513
1514   if (video_plane_controller_->Initialize() != TIZEN_ERROR_NONE) {
1515     LOG(ERROR) << "video_plane_controller init error";
1516     return;
1517   }
1518
1519   LOG(INFO) << __func__ << " set ESPLUSPLAYER_DISPLAY_TYPE_OVERLAY";
1520   int player_error = ESPLUSPLAYER_ERROR_TYPE_NONE;
1521   if (video_plane_controller_->rendering_mode() ==
1522       VideoPlaneController::RenderingMode::OFFSCREEN &&
1523       !video_plane_controller_->get_use_wayland_window()) {
1524     player_error = esplusplayer_set_display(
1525         esplayer_, ESPLUSPLAYER_DISPLAY_TYPE_OVERLAY,
1526         video_plane_controller_->GetVideoPlaneHandle());
1527   } else {
1528     int wl_w, wl_h, wl_x, wl_y;
1529     ecore_wl2_window_geometry_get(
1530         static_cast<Ecore_Wl2_Window*>(
1531             video_plane_controller_->GetVideoPlaneHandle()),
1532         &wl_x, &wl_y, &wl_w, &wl_h);
1533
1534     player_error = esplusplayer_set_ecore_display(
1535         esplayer_, ESPLUSPLAYER_DISPLAY_TYPE_OVERLAY,
1536         static_cast<Ecore_Wl2_Window*>(
1537             video_plane_controller_->GetVideoPlaneHandle()),
1538         wl_x, wl_y, wl_w, wl_h);
1539   }
1540   if (player_error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
1541     LOG(ERROR) << "player_error #"
1542                << esplusplayer_get_error_string(
1543                       static_cast<esplusplayer_error_type>(player_error));
1544     return;
1545   }
1546 }
1547 #endif
1548
1549 void MediaPlayerESPlusPlayer::RequestSuspend(bool resource_conflicted) {
1550   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
1551   GetMediaPlayerClient()->OnRequestSuspend(resource_conflicted);
1552   Release();
1553 }
1554
1555 void MediaPlayerESPlusPlayer::SetMediaType(DemuxerStream::Type type) {
1556   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
1557   if (type == DemuxerStream::AUDIO)
1558     SetMediaType(GetMediaType() | MediaType::Audio);
1559   else if (type == DemuxerStream::VIDEO)
1560     SetMediaType(GetMediaType() | MediaType::Video);
1561 }
1562
1563 PlayerRoleFlags MediaPlayerESPlusPlayer::GetRoles() const noexcept {
1564   return PlayerRole::ElementaryStreamBased;
1565 }
1566
1567 }  // namespace media