fixup! [MM] Handle buffering and playback
[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/bind.h"
11 #include "base/callback.h"
12 #include "base/location.h"
13 #include "base/logging.h"
14 #include "media/base/decoder_buffer.h"
15 #include "media/base/renderer_client.h"
16 #include "third_party/libyuv/include/libyuv/convert.h"
17 #include "tizen_src/chromium_impl/media/filters/media_player_registry.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 using player_buffer_size_t = unsigned long long;
26
27 // Limit of platform player's total (audio and video) buffer size in bytes
28 const media::player_buffer_size_t kPlayerTotalBufferSize = 64 * 1024 * 1024;
29 // Limit of platform player's audio buffer in bytes
30 const media::player_buffer_size_t kPlayerAudioBufferSize = 768 * 1024;
31
32 // The delay time before retrying ReadBuffer.
33 // Wait until there is space in the buffer.
34 const base::TimeDelta kBufferQueueReadDelay = base::Milliseconds(100);
35
36 espp_buffer_size_t GetMaxAudioBufferSize() {
37   return kPlayerAudioBufferSize;
38 }
39
40 espp_buffer_size_t GetMaxVideoBufferSize(gfx::Size size) {
41   return kPlayerTotalBufferSize - kPlayerAudioBufferSize;
42 }
43
44 void ReadyToPrepareCallback(const esplusplayer_stream_type stream_type,
45                             void* user_data) {
46   MediaPlayerESPlusPlayer* player =
47       static_cast<MediaPlayerESPlusPlayer*>(user_data);
48   if (!player)
49     return;
50
51   player->OnReadyToPrepare(stream_type);
52 }
53
54 void PrepareCompleteCallback(bool result, void* user_data) {
55   MediaPlayerESPlusPlayer* player =
56       static_cast<MediaPlayerESPlusPlayer*>(user_data);
57   if (!player)
58     return;
59
60   player->OnPrepareComplete(result);
61 }
62
63 void EosCallback(void* user_data) {
64   MediaPlayerESPlusPlayer* player =
65       static_cast<MediaPlayerESPlusPlayer*>(user_data);
66   if (!player)
67     return;
68
69   player->OnEos();
70 }
71
72 void FrameReadyCallback(const esplusplayer_decoded_video_packet* packet,
73                         void* user_data) {
74   MediaPlayerESPlusPlayer* player =
75       static_cast<MediaPlayerESPlusPlayer*>(user_data);
76   if (!player)
77     return;
78
79   player->OnFrameReady(packet);
80 }
81
82 void FlushCompleteCallback(void* user_data) {
83   MediaPlayerESPlusPlayer* player =
84       static_cast<MediaPlayerESPlusPlayer*>(user_data);
85   if (!player)
86     return;
87
88   player->OnFlushComplete();
89 }
90
91 void ReadyToSeekCallback(const esplusplayer_stream_type stream_type,
92                          const uint64_t seek_time,
93                          void* user_data) {
94   MediaPlayerESPlusPlayer* player =
95       static_cast<MediaPlayerESPlusPlayer*>(user_data);
96   if (!player)
97     return;
98
99   player->OnReadyToSeek(stream_type, seek_time);
100 }
101
102 void SeekCompleteCallback(void* user_data) {
103   MediaPlayerESPlusPlayer* player =
104       static_cast<MediaPlayerESPlusPlayer*>(user_data);
105   if (!player)
106     return;
107
108   player->OnSeekComplete();
109 }
110
111 void ResourceConflictCallback(void* user_data) {
112   MediaPlayerESPlusPlayer* player =
113       static_cast<MediaPlayerESPlusPlayer*>(user_data);
114   if (!player)
115     return;
116
117   player->OnResourceConflict();
118 }
119
120 void ErrorCallback(const esplusplayer_error_type error_type, void* user_data) {
121   MediaPlayerESPlusPlayer* player =
122       static_cast<MediaPlayerESPlusPlayer*>(user_data);
123   if (!player)
124     return;
125
126   player->OnError(error_type);
127 }
128
129 MediaPlayerESPlusPlayer::MediaPlayerESPlusPlayer() {
130   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
131   player_id_ = MediaPlayerRegistry::GetInstance()->RegisterMediaPlayer(this);
132 }
133
134 MediaPlayerESPlusPlayer::~MediaPlayerESPlusPlayer() {
135   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
136   weak_factory_.InvalidateWeakPtrs();
137
138   MediaPlayerRegistry::GetInstance()->UnregisterMediaPlayer(player_id_);
139
140   // Player should be released before destroyed.
141   Release();
142
143   int error = esplusplayer_destroy(esplayer_);
144   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE)
145     LOG(ERROR) << "esplusplayer_destroy failed, error #"
146                << esplusplayer_get_error_string(
147                       static_cast<esplusplayer_error_type>(error));
148   esplayer_ = nullptr;
149 }
150
151 bool MediaPlayerESPlusPlayer::CreatePlayer() {
152   if (esplayer_)
153     return true;
154
155   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
156   esplayer_ = esplusplayer_create();
157   if (!esplayer_) {
158     LOG(ERROR) << "Cannot create esplus player!";
159     return false;
160   }
161
162   last_frames_.get<DemuxerStream::AUDIO>().first = media::kNoTimestamp;
163   last_frames_.get<DemuxerStream::AUDIO>().second = media::kNoTimestamp;
164   last_frames_.get<DemuxerStream::VIDEO>().first = media::kNoTimestamp;
165   last_frames_.get<DemuxerStream::VIDEO>().second = media::kNoTimestamp;
166
167   buffer_observer_.reset(BufferObserver::CreateBufferObserver());
168
169 #if defined(TIZEN_VIDEO_HOLE)
170   LOG(INFO) << __func__ << " is_video_hole_: " << is_video_hole_;
171   if (is_video_hole_) {
172     video_plane_controller_.reset(
173         new VideoPlaneControllerESPlusPlayer(esplayer_));
174   }
175 #endif
176
177   return true;
178 }
179
180 void MediaPlayerESPlusPlayer::Initialize(VideoRendererSink* sink) {
181   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
182   esplusplayer_set_ready_to_prepare_cb(esplayer_, &ReadyToPrepareCallback,
183                                        this);
184   esplusplayer_set_prepare_async_done_cb(esplayer_, &PrepareCompleteCallback,
185                                          this);
186   esplusplayer_set_eos_cb(esplayer_, &EosCallback, this);
187   esplusplayer_set_media_packet_video_decoded_cb(esplayer_, &FrameReadyCallback,
188                                                  this);
189   esplusplayer_set_flush_done_cb(esplayer_, &FlushCompleteCallback, this);
190   esplusplayer_set_ready_to_seek_cb(esplayer_, &ReadyToSeekCallback, this);
191   esplusplayer_set_seek_done_cb(esplayer_, &SeekCompleteCallback, this);
192   esplusplayer_set_resource_conflicted_cb(esplayer_, &ResourceConflictCallback,
193                                           this);
194   esplusplayer_set_error_cb(esplayer_, &ErrorCallback, this);
195   buffer_observer_->SetBufferingCallback(
196       base::BindRepeating(&MediaPlayerESPlusPlayer::OnBufferingStatusChanged,
197                           weak_factory_.GetWeakPtr()));
198
199   int error = esplusplayer_open(esplayer_);
200   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
201     LOG(ERROR) << "esplusplayer_open failed. error #"
202                << esplusplayer_get_error_string(
203                       static_cast<esplusplayer_error_type>(error));
204     return;
205   }
206
207   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
208             << " state:" << GetString(GetPlayerState());
209
210   esplusplayer_decoded_video_frame_buffer_type video_frame_buffer_type =
211       ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_COPY;
212 #if defined(TIZEN_VIDEO_HOLE)
213   if (is_video_hole_)
214     video_frame_buffer_type = ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_NONE;
215 #endif
216
217   error = esplusplayer_set_video_frame_buffer_type(esplayer_,
218                                                    video_frame_buffer_type);
219   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
220     LOG(ERROR) << "esplusplayer_set_video_frame_buffer_type failed. error #"
221                << esplusplayer_get_error_string(
222                       static_cast<esplusplayer_error_type>(error));
223     return;
224   }
225
226   sink_ = sink;
227 }
228
229 bool MediaPlayerESPlusPlayer::IsInitialized() {
230   return (GetPlayerState() >= ESPLUSPLAYER_STATE_IDLE);
231 }
232
233 void MediaPlayerESPlusPlayer::SetTaskRunner(
234     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
235   task_runner_ = task_runner.get();
236 }
237
238 void MediaPlayerESPlusPlayer::SetStreamInfo(DemuxerStream::Type type,
239                                             DemuxerStream* stream,
240                                             RendererClient* client) {
241   if (!esplayer_) {
242     LOG(ERROR) << "Invalid player handle. Send error to client.";
243     client->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
244     return;
245   }
246
247   SetDemuxerStream(type, stream);
248   SetRendererClient(type, client);
249   InitializeStreamConfig(type);
250 }
251
252 void MediaPlayerESPlusPlayer::SetRendererClientExtension(
253     media::MediaPlayerTizenClientExtension* client_extension) {
254   NOTIMPLEMENTED();
255 }
256
257 void MediaPlayerESPlusPlayer::Prepare() {
258   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
259   if (is_prepared_ || is_preparing_)
260     return;
261
262   if (GetPlayerState() != ESPLUSPLAYER_STATE_IDLE) {
263     LOG(ERROR) << "(" << static_cast<void*>(this) << ") " << __func__
264                << " Prepare called on invalid state : "
265                << GetString(GetPlayerState());
266     return;
267   }
268
269 #if defined(TIZEN_VIDEO_HOLE)
270   if (is_video_hole_ && video_plane_controller_) {
271     if (video_plane_controller_->Initialize() != TIZEN_ERROR_NONE) {
272       LOG(ERROR) << "video_plane_controller init error";
273       return;
274     }
275     LOG(INFO) << __func__ << " set ESPLUSPLAYER_DISPLAY_TYPE_OVERLAY";
276     int player_error = ESPLUSPLAYER_ERROR_TYPE_NONE;
277     if (video_plane_controller_->rendering_mode() ==
278         VideoPlaneController::RenderingMode::OFFSCREEN) {
279       player_error = esplusplayer_set_display(
280           esplayer_, ESPLUSPLAYER_DISPLAY_TYPE_OVERLAY,
281           video_plane_controller_->GetVideoPlaneHandle());
282     } else {
283       int wl_w, wl_h, wl_x, wl_y;
284       ecore_wl2_window_geometry_get(
285           static_cast<Ecore_Wl2_Window*>(
286               video_plane_controller_->GetVideoPlaneHandle()),
287           &wl_x, &wl_y, &wl_w, &wl_h);
288
289       player_error = esplusplayer_set_ecore_display(
290           esplayer_, ESPLUSPLAYER_DISPLAY_TYPE_OVERLAY,
291           static_cast<Ecore_Wl2_Window*>(
292               video_plane_controller_->GetVideoPlaneHandle()),
293           wl_x, wl_y, wl_w, wl_h);
294     }
295     if (player_error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
296       LOG(ERROR) << "player_error #"
297                  << esplusplayer_get_error_string(
298                         static_cast<esplusplayer_error_type>(player_error));
299       return;
300     }
301   }
302 #endif
303
304   int error = esplusplayer_prepare_async(esplayer_);
305   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
306     LOG(ERROR) << "player prepare failed! error #"
307                << esplusplayer_get_error_string(
308                       static_cast<esplusplayer_error_type>(error));
309
310     if (IsValid(DemuxerStream::AUDIO))
311       GetRendererClient(DemuxerStream::AUDIO)
312           ->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
313     else if (IsValid(DemuxerStream::VIDEO))
314       GetRendererClient(DemuxerStream::VIDEO)
315           ->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
316     return;
317   }
318   is_preparing_ = true;
319 }
320
321 bool MediaPlayerESPlusPlayer::IsPrepared() {
322   return (GetPlayerState() >= ESPLUSPLAYER_STATE_READY);
323 }
324
325 void MediaPlayerESPlusPlayer::Release() {
326   if (!esplayer_)
327     return;
328
329   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
330   SetIsEos(DemuxerStream::AUDIO, false);
331   SetShouldFeed(DemuxerStream::AUDIO, false);
332   SetIsValid(DemuxerStream::AUDIO, false);
333   SetReadRequested(DemuxerStream::AUDIO, false);
334
335   SetIsEos(DemuxerStream::VIDEO, false);
336   SetShouldFeed(DemuxerStream::VIDEO, false);
337   SetIsValid(DemuxerStream::VIDEO, false);
338   SetReadRequested(DemuxerStream::VIDEO, false);
339
340   esplusplayer_set_ready_to_prepare_cb(esplayer_, nullptr, this);
341   esplusplayer_set_prepare_async_done_cb(esplayer_, nullptr, this);
342   esplusplayer_set_eos_cb(esplayer_, nullptr, this);
343   esplusplayer_set_media_packet_video_decoded_cb(esplayer_, nullptr, this);
344   esplusplayer_set_flush_done_cb(esplayer_, nullptr, this);
345   esplusplayer_set_ready_to_seek_cb(esplayer_, nullptr, this);
346   esplusplayer_set_seek_done_cb(esplayer_, nullptr, this);
347   esplusplayer_set_resource_conflicted_cb(esplayer_, nullptr, this);
348   esplusplayer_set_error_cb(esplayer_, nullptr, this);
349
350   buffer_observer_->ResetBufferStatus();
351   buffer_observer_->ResetBufferStatusCallbacks(esplayer_);
352
353   volume_ = 1.0;
354   playback_rate_ = 0.0;
355   is_prepared_ = false;
356   is_preparing_ = false;
357   is_paused_ = true;
358   is_buffering_ = false;
359   current_position_ = base::TimeDelta();
360   is_flushing_ = false;
361   is_seeking_ = false;
362   seek_position_ = base::TimeDelta();
363   pending_seek_ = false;
364   pending_seek_position_ = base::TimeDelta();
365   should_set_playback_rate_ = false;
366
367   GetBufferQueue(DemuxerStream::VIDEO).clear();
368   GetBufferQueue(DemuxerStream::AUDIO).clear();
369   data_cb_.Reset();
370   sink_ = nullptr;
371
372   if (GetPlayerState() == ESPLUSPLAYER_STATE_NONE) {
373     LOG(ERROR) << "(" << static_cast<void*>(this) << ") " << __func__
374                << " Release called on invalid state : "
375                << GetString(GetPlayerState());
376     return;
377   }
378
379   esplusplayer_close(esplayer_);
380 }
381
382 void MediaPlayerESPlusPlayer::Play() {
383   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
384   int error = ESPLUSPLAYER_ERROR_TYPE_NONE;
385   esplusplayer_state state = GetPlayerState();
386
387   is_paused_ = false;
388   if (state < ESPLUSPLAYER_STATE_READY || !is_prepared_ || is_seeking_) {
389     LOG(INFO) << "state : " << GetString(state)
390               << " is_prepared : " << is_prepared_
391               << " is_seeking : " << is_seeking_
392               << " is_buffering : " << is_buffering_;
393     return;
394   }
395
396   if (is_buffering_) {
397     LOG(INFO) << "state : " << GetString(state) << " is_paused : " << is_paused_
398               << " is_buffering : " << is_buffering_;
399     // return;
400   }
401
402   SetVolume(volume_);
403   if (should_set_playback_rate_)
404     SetRate(playback_rate_);
405
406   if (state == ESPLUSPLAYER_STATE_READY)
407     error = esplusplayer_start(esplayer_);
408   else if (state == ESPLUSPLAYER_STATE_PAUSED ||
409            state == ESPLUSPLAYER_STATE_PLAYING)
410     error = esplusplayer_resume(esplayer_);
411
412   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
413     LOG(ERROR) << "player play failed! state #" << GetString(state)
414                << " error #"
415                << esplusplayer_get_error_string(
416                       static_cast<esplusplayer_error_type>(error));
417     // TODO: handle error!
418     return;
419   }
420 }
421
422 void MediaPlayerESPlusPlayer::Pause(bool is_media_related_action) {
423   if (is_paused_) {
424     LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
425               << " already paused";
426     return;
427   }
428
429   if (!is_media_related_action)
430     is_paused_ = true;
431
432   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
433             << " is_buffering : " << is_buffering_
434             << " is_media_action : " << is_media_related_action;
435   esplusplayer_state state = GetPlayerState();
436   if (state != ESPLUSPLAYER_STATE_PLAYING) {
437     LOG(WARNING) << "Cannot pause in " << GetString(state) << " state";
438     return;
439   }
440
441   int error = esplusplayer_pause(esplayer_);
442   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
443     LOG(ERROR) << "player pause failed! error #"
444                << esplusplayer_get_error_string(
445                       static_cast<esplusplayer_error_type>(error));
446     // TODO: handle error!
447     return;
448   }
449 }
450
451 void MediaPlayerESPlusPlayer::SetRate(double rate) {
452   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__ << " : "
453             << rate;
454   if (playback_rate_ == rate)
455     return;
456
457   playback_rate_ = rate;
458   if (GetPlayerState() < ESPLUSPLAYER_STATE_READY) {
459     should_set_playback_rate_ = true;
460     return;
461   }
462
463   bool should_mute = rate >= 2.0;
464   int error =
465       esplusplayer_set_playback_rate(esplayer_, playback_rate_, should_mute);
466   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
467     LOG(ERROR) << "player set playback rate failed! error #"
468                << esplusplayer_get_error_string(
469                       static_cast<esplusplayer_error_type>(error));
470     return;
471   }
472   should_set_playback_rate_ = false;
473 }
474
475 void MediaPlayerESPlusPlayer::Seek(base::TimeDelta time) {
476   // Ignore seek to 0 during initialization.
477   if (GetPlayerState() < ESPLUSPLAYER_STATE_READY && time.InSecondsF() == 00) {
478     LOG(INFO) << __func__ << " Ignore seek to 0 during initialization.";
479     return;
480   }
481
482   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__ << " :"
483             << time;
484   if (GetPlayerState() < ESPLUSPLAYER_STATE_READY || !is_prepared_ ||
485       is_seeking_) {
486     LOG(INFO) << "Add to pending seek ("
487               << ") state: " << GetString(GetPlayerState())
488               << " is_prepared : " << is_prepared_
489               << " is_seeking : " << is_seeking_;
490     pending_seek_ = true;
491     pending_seek_position_ = time;
492     return;
493   }
494
495   last_frames_.get<DemuxerStream::AUDIO>().first = media::kNoTimestamp;
496   last_frames_.get<DemuxerStream::VIDEO>().first = media::kNoTimestamp;
497
498   UpdateBufferedDtsDifference();
499
500   SetShouldFeed(DemuxerStream::AUDIO, false);
501   SetShouldFeed(DemuxerStream::VIDEO, false);
502   GetBufferQueue(DemuxerStream::VIDEO).clear();
503   GetBufferQueue(DemuxerStream::AUDIO).clear();
504   buffer_observer_->ResetBufferStatus();
505
506   LOG(INFO) << __func__ << " : " << time;
507   int error = esplusplayer_seek(esplayer_, time.InMilliseconds());
508   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
509     LOG(ERROR) << "Seek failed. Current time : " << time.InSecondsF()
510                << " error #"
511                << esplusplayer_get_error_string(
512                       static_cast<esplusplayer_error_type>(error));
513     return;
514   }
515
516   is_seeking_ = true;
517   seek_position_ = time;
518   pending_seek_ = false;
519   pending_seek_position_ = base::TimeDelta();
520 }
521
522 void MediaPlayerESPlusPlayer::Flush(base::OnceClosure flush_cb) {
523   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
524   last_frames_.get<DemuxerStream::AUDIO>().first = media::kNoTimestamp;
525   last_frames_.get<DemuxerStream::VIDEO>().first = media::kNoTimestamp;
526
527   UpdateBufferedDtsDifference();
528
529   NOTIMPLEMENTED();
530   std::move(flush_cb).Run();
531 }
532
533 void MediaPlayerESPlusPlayer::SetVolume(double volume) {
534   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__ << " :"
535             << volume;
536   volume_ = volume;
537   if (GetPlayerState() == ESPLUSPLAYER_STATE_NONE)
538     return;
539
540   int error = esplusplayer_set_volume(esplayer_, 100 * volume_);
541   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE)
542     LOG(ERROR) << "esplusplayer_set_volume failed, error #"
543                << esplusplayer_get_error_string(
544                       static_cast<esplusplayer_error_type>(error));
545 }
546
547 base::TimeDelta MediaPlayerESPlusPlayer::GetCurrentTime() {
548   if (pending_seek_)
549     return pending_seek_position_;
550
551   if (is_seeking_)
552     return seek_position_;
553
554   // Seek can be called before PLAY / PAUSE. Return last known time.
555   if (GetPlayerState() < ESPLUSPLAYER_STATE_PLAYING)
556     return current_position_;
557
558   uint64_t time = 0;  // In milliseconds.
559   int error = esplusplayer_get_playing_time(esplayer_, &time);
560   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
561     LOG(ERROR) << "esplusplayer_get_playing_time failed. error #"
562                << esplusplayer_get_error_string(
563                       static_cast<esplusplayer_error_type>(error));
564     return base::TimeDelta();
565   }
566
567   current_position_ = base::Milliseconds(time);
568   return current_position_;
569 }
570
571 #if defined(TIZEN_TBM_SUPPORT)
572 void MediaPlayerESPlusPlayer::DestroyMediaPacket(void* media_packet) {
573   if (!task_runner_->BelongsToCurrentThread()) {
574     task_runner_->PostTask(
575         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::DestroyMediaPacket,
576                                   weak_factory_.GetWeakPtr(), media_packet));
577     return;
578   }
579
580   esplusplayer_decoded_buffer_destroy(
581       esplayer_, static_cast<esplusplayer_decoded_video_packet*>(media_packet));
582 }
583 #endif
584
585 esplusplayer_state MediaPlayerESPlusPlayer::GetPlayerState() {
586   return (esplayer_ ? esplusplayer_get_state(esplayer_)
587                     : ESPLUSPLAYER_STATE_NONE);
588 }
589
590 void MediaPlayerESPlusPlayer::InitializeStreamConfig(DemuxerStream::Type type) {
591   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
592   DemuxerStream* stream = GetDemuxerStream(type);
593   CHECK(stream);
594
595   if (type == DemuxerStream::AUDIO) {
596     media::AudioDecoderConfig audio_config = stream->audio_decoder_config();
597     if (!audio_config.IsValidConfig()) {
598       LOG(INFO) << "Invalid audio config";
599       return;
600     }
601
602     LOG(INFO) << "Audio config : " << audio_config.AsHumanReadableString();
603     esplusplayer_audio_stream_info audio_stream_info;
604     memset(&audio_stream_info, 0, sizeof(esplusplayer_audio_stream_info));
605
606     audio_stream_info.mime_type =
607         ConvertToESPlusAudioMimeType(audio_config.codec());
608     audio_stream_info.bitrate = audio_config.bytes_per_channel() *
609                                 audio_config.samples_per_second() * 8;
610     audio_stream_info.channels =
611         media::ChannelLayoutToChannelCount(audio_config.channel_layout());
612     audio_stream_info.sample_rate = audio_config.samples_per_second();
613     audio_stream_info.codec_data_length = audio_config.extra_data().size();
614
615     if (audio_stream_info.codec_data_length > 0) {
616       audio_stream_info.codec_data =
617           (char*)(const_cast<unsigned char*>(audio_config.extra_data().data()));
618     } else {
619       audio_stream_info.codec_data = NULL;
620     }
621
622     int error;
623     if (!IsValid(type)) {
624       error = esplusplayer_set_audio_stream_info(esplayer_, &audio_stream_info);
625       if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
626         LOG(ERROR) << "esplusplayer_set_audio_stream_info failed. error code "
627                    << error;
628         GetRendererClient(type)->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
629         return;
630       }
631       buffer_observer_->SetMediaStreamStatusCallback(
632           esplayer_, ESPLUSPLAYER_STREAM_TYPE_AUDIO);
633     }
634
635     espp_buffer_size_t max_buffer_size = GetMaxAudioBufferSize();
636     buffer_observer_->SetBufferSize(type, max_buffer_size);
637     LOG(INFO) << "Audio Max buffer size " << max_buffer_size;
638     error = esplusplayer_set_buffer_size(
639         esplayer_, ESPLUSPLAYER_BUFFER_AUDIO_MAX_BYTE_SIZE, max_buffer_size);
640     if (error != ESPLUSPLAYER_ERROR_TYPE_NONE)
641       LOG(WARNING) << "Failed to set audio buffer to " << max_buffer_size / 1024
642                    << "KB";
643
644     SetIsValid(type, true);
645     GetRendererClient(type)->OnAudioConfigChange(audio_config);
646   }
647
648   if (type == DemuxerStream::VIDEO) {
649     media::VideoDecoderConfig video_config = stream->video_decoder_config();
650     if (!video_config.IsValidConfig()) {
651       LOG(ERROR) << "Invalid video config.";
652       return;
653     }
654
655     LOG(INFO) << "Video config : " << video_config.AsHumanReadableString();
656     esplusplayer_video_stream_info video_stream_info;
657     memset(&video_stream_info, 0, sizeof(esplusplayer_video_stream_info));
658
659     video_stream_info.width = video_config.coded_size().width();
660     video_stream_info.height = video_config.coded_size().height();
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 = NULL;
673     }
674     auto max_resolution =
675         GetMaxCodecResolution(video_stream_info.mime_type, is_video_hole_);
676
677     video_stream_info.max_width = max_resolution.width();
678     video_stream_info.max_height = max_resolution.height();
679
680     int error;
681     if (!IsValid(type)) {
682       error = esplusplayer_set_video_stream_info(esplayer_, &video_stream_info);
683       if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
684         LOG(ERROR) << "esplusplayer_set_video_stream_info failed. error code "
685                    << error;
686         GetRendererClient(type)->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
687         return;
688       }
689       buffer_observer_->SetMediaStreamStatusCallback(
690           esplayer_, ESPLUSPLAYER_STREAM_TYPE_VIDEO);
691     }
692
693     espp_buffer_size_t max_buffer_size =
694         GetMaxVideoBufferSize(video_config.coded_size());
695     buffer_observer_->SetBufferSize(type, max_buffer_size);
696
697     LOG(INFO) << "Video Max buffer size " << max_buffer_size;
698     error = esplusplayer_set_buffer_size(
699         esplayer_, ESPLUSPLAYER_BUFFER_VIDEO_MAX_BYTE_SIZE, max_buffer_size);
700     if (error != ESPLUSPLAYER_ERROR_TYPE_NONE)
701       LOG(WARNING) << "Failed to set video buffer to " << max_buffer_size / 1024
702                    << "KB";
703
704     SetIsValid(type, true);
705     GetRendererClient(type)->OnVideoConfigChange(video_config);
706   }
707 }
708
709 void MediaPlayerESPlusPlayer::ReadBuffer(DemuxerStream::Type type) {
710   if (!ReadFromBufferQueue(type))
711     return;
712
713   // Avoid unnecessary or redundant read requests.
714   if (!ShouldFeed(type) || ReadRequested(type) || IsEos(type))
715     return;
716
717   SetReadRequested(type, true);
718   GetDemuxerStream(type)->Read(
719       base::BindOnce(&MediaPlayerESPlusPlayer::OnBufferReady,
720                      weak_factory_.GetWeakPtr(), type));
721 }
722
723 void MediaPlayerESPlusPlayer::PostReadBuffer(DemuxerStream::Type type) {
724   task_runner_->PostDelayedTask(
725       FROM_HERE,
726       base::BindOnce(&MediaPlayerESPlusPlayer::ReadBuffer,
727                      weak_factory_.GetWeakPtr(), type),
728       kBufferQueueReadDelay);
729 }
730
731 void MediaPlayerESPlusPlayer::OnBufferReady(
732     DemuxerStream::Type type,
733     DemuxerStream::Status status,
734     scoped_refptr<DecoderBuffer> buffer) {
735   bool should_delay_read = false;
736   switch (status) {
737     case DemuxerStream::kAborted:
738     case DemuxerStream::kError:
739       GetBufferQueue(type).clear();
740       break;
741     case DemuxerStream::kNeedBuffer:
742       should_delay_read = true;
743       break;
744     case DemuxerStream::kConfigChanged:
745       // Clear pending buffer of older config
746       GetBufferQueue(type).clear();
747       InitializeStreamConfig(type);
748       break;
749     case DemuxerStream::kOk: {
750       GetBufferQueue(type).push_back(buffer);
751       break;
752     }
753   }
754
755   SetReadRequested(type, false);
756   if (should_delay_read)
757     PostReadBuffer(type);
758   else
759     ReadBuffer(type);
760 }
761
762 bool MediaPlayerESPlusPlayer::ReadFromBufferQueue(DemuxerStream::Type type) {
763   if (!GetBufferQueue(type).size())
764     return true;
765
766   esplusplayer_submit_status status = ESPLUSPLAYER_SUBMIT_STATUS_SUCCESS;
767   scoped_refptr<DecoderBuffer> buffer = GetBufferQueue(type).front();
768   if (buffer.get()->end_of_stream())
769     status = SubmitEosPacket(type);
770   else
771     status = SubmitEsPacket(type, buffer);
772
773   if (status == ESPLUSPLAYER_SUBMIT_STATUS_FULL) {
774     // If buffer is full, try again after a while.
775     PostReadBuffer(type);
776     return false;
777   }
778
779   if (status == ESPLUSPLAYER_SUBMIT_STATUS_NOT_PREPARED ||
780       status == ESPLUSPLAYER_SUBMIT_STATUS_OUT_OF_MEMORY)
781     return false;
782
783   UpdateBufferedDtsDifference();
784   GetBufferQueue(type).pop_front();
785   return true;
786 }
787
788 esplusplayer_submit_status MediaPlayerESPlusPlayer::SubmitEosPacket(
789     DemuxerStream::Type type) {
790   if (IsEos(type))
791     return ESPLUSPLAYER_SUBMIT_STATUS_SUCCESS;
792
793   last_frames_[type].first = base::TimeDelta::Max();
794
795   esplusplayer_submit_status status = esplusplayer_submit_eos_packet(
796       esplayer_, GetESPlusPlayerStreamType(type));
797   if (status != ESPLUSPLAYER_SUBMIT_STATUS_SUCCESS) {
798     LOG(ERROR) << "Submit Eos (" << DemuxerStream::GetTypeName(type)
799                << ") Packet failed, ret:" << GetString(status);
800     return status;
801   }
802   buffer_observer_->SetEos(type);
803   SetIsEos(type, true);
804   return status;
805 }
806
807 esplusplayer_submit_status MediaPlayerESPlusPlayer::SubmitEsPacket(
808     DemuxerStream::Type type,
809     scoped_refptr<DecoderBuffer> buffer) {
810   esplusplayer_es_packet packet;
811   memset(&packet, 0, sizeof(esplusplayer_es_packet));
812   packet.type = GetESPlusPlayerStreamType(type);
813
814   packet.buffer = (char*)(const_cast<unsigned char*>(buffer->data()));
815   packet.buffer_size = buffer->data_size();
816   packet.pts = buffer->timestamp().InMilliseconds();
817   packet.duration = buffer->duration().InMilliseconds();
818
819   // This filed only set when PushMediaPacket
820   packet.matroska_color_info = nullptr;
821   esplusplayer_submit_status status =
822       esplusplayer_submit_packet(esplayer_, &packet);
823   if (status != ESPLUSPLAYER_SUBMIT_STATUS_SUCCESS) {
824     LOG(WARNING) << "submit " << DemuxerStream::GetTypeName(type)
825                  << " packet : " << GetString(status);
826   }
827
828   last_frames_[type].first = base::Milliseconds(packet.pts);
829   last_frames_[type].second = base::Milliseconds(packet.duration);
830   return status;
831 }
832
833 void MediaPlayerESPlusPlayer::UpdateBufferedDtsDifference() {
834   // Ignore unless audio and video streams are valid.
835   if (!IsValid(DemuxerStream::AUDIO) || !IsValid(DemuxerStream::VIDEO))
836     return;
837
838   const auto& audio_ts = last_frames_.get<DemuxerStream::AUDIO>().first;
839   const auto& video_ts = last_frames_.get<DemuxerStream::VIDEO>().first;
840
841   if ((audio_ts != media::kNoTimestamp) && (video_ts != media::kNoTimestamp) &&
842       (audio_ts != base::TimeDelta::Max()) &&
843       (video_ts != base::TimeDelta::Max())) {
844     const auto av_diff = (audio_ts - video_ts).InMilliseconds();
845     buffer_observer_->SetAudioVideoDtsDifference(av_diff);
846   } else {
847     buffer_observer_->SetAudioVideoDtsDifference(0);
848   }
849 }
850
851 void MediaPlayerESPlusPlayer::OnBufferingStatusChanged(DemuxerStream::Type type,
852                                                        BufferStatus status) {
853   LOG(INFO) << __func__ << " " << DemuxerStream::GetTypeName(type) << " : "
854             << GetString(status);
855   const auto RequestStateChange = [this](esplusplayer_state state) {
856     LOG(INFO) << __func__ << " req. change state : " << GetString(state);
857     switch (state) {
858       case ESPLUSPLAYER_STATE_PLAYING:
859         Play();
860         break;
861       case ESPLUSPLAYER_STATE_PAUSED:
862         Pause(true);
863         break;
864       default:
865         NOTREACHED();
866     }
867   };
868
869   SetBufferStatus(type, status);
870   switch (status) {
871     case kBufferUnderrun:
872       //  RequestStateChange(ESPLUSPLAYER_STATE_PAUSED);
873       [[fallthrough]];
874     case kBufferMinThreshold:
875     case kBufferNormal:
876       is_buffering_ = true;
877       SetShouldFeed(type, true);
878       ReadBuffer(type);
879       break;
880     case kBufferMaxThreshold:
881     case kBufferOverflow:
882     case kBufferEos:
883     case kBufferAhead:
884       is_buffering_ = false;
885       SetShouldFeed(type, false);
886       //  if (!is_paused_)
887       //    RequestStateChange(ESPLUSPLAYER_STATE_PLAYING);
888       break;
889     case kBufferNone:
890       NOTREACHED();
891   }
892
893   // TODO: Check if controller can control underflow. Currently buffering
894   // related state changes are commented for the same (in Play and
895   // RequestStateChange).
896   if (status != kBufferNone) {
897     GetRendererClient(type)->OnBufferingStateChange(
898         BUFFERING_HAVE_ENOUGH, BUFFERING_CHANGE_REASON_UNKNOWN);
899   }
900 }
901
902 void MediaPlayerESPlusPlayer::OnReadyToPrepare(
903     const esplusplayer_stream_type stream_type) {
904   if (!task_runner_->BelongsToCurrentThread()) {
905     task_runner_->PostTask(
906         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::OnReadyToPrepare,
907                                   weak_factory_.GetWeakPtr(), stream_type));
908     return;
909   }
910
911   LOG(INFO) << "OnReadyToPrepare : "
912             << DemuxerStream::GetTypeName(GetDemuxerStreamType(stream_type));
913   if (stream_type != ESPLUSPLAYER_STREAM_TYPE_AUDIO &&
914       stream_type != ESPLUSPLAYER_STREAM_TYPE_VIDEO)
915     return;
916
917   DemuxerStream::Type type = GetDemuxerStreamType(stream_type);
918   if (IsValid(type)) {
919     SetShouldFeed(type, true);
920     ReadBuffer(type);
921   }
922 }
923
924 void MediaPlayerESPlusPlayer::OnPrepareComplete(bool result) {
925   if (!task_runner_->BelongsToCurrentThread()) {
926     task_runner_->PostTask(
927         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::OnPrepareComplete,
928                                   weak_factory_.GetWeakPtr(), result));
929     return;
930   }
931
932   if (!result) {
933     LOG(ERROR) << "OnPrepareComplete prepare_async failed.";
934     if (IsValid(DemuxerStream::AUDIO))
935       GetRendererClient(DemuxerStream::AUDIO)
936           ->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
937     else if (IsValid(DemuxerStream::VIDEO))
938       GetRendererClient(DemuxerStream::VIDEO)
939           ->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
940     return;
941   }
942
943   if (GetPlayerState() != ESPLUSPLAYER_STATE_READY) {
944     LOG(ERROR) << "Invalid state (" << GetString(GetPlayerState())
945                << ") change during prepare. Returning.";
946     return;
947   }
948
949   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
950             << " is_paused_ : " << is_paused_
951             << " seek_position : " << seek_position_
952             << " pending_seek_ : " << pending_seek_
953             << " pending_seek_position_ : " << pending_seek_position_;
954
955 #if defined(TIZEN_VIDEO_HOLE)
956   if (is_video_hole_)
957     video_plane_controller_->ResetMediaGeometry();
958 #endif
959
960   is_prepared_ = true;
961   if (pending_seek_) {
962     Seek(pending_seek_position_);
963   } else if (!is_paused_) {
964     Play();
965   }
966 }
967
968 void MediaPlayerESPlusPlayer::OnEos() {
969   if (!task_runner_->BelongsToCurrentThread()) {
970     task_runner_->PostTask(FROM_HERE,
971                            base::BindOnce(&MediaPlayerESPlusPlayer::OnEos,
972                                           weak_factory_.GetWeakPtr()));
973     return;
974   }
975
976   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
977   if (IsValid(DemuxerStream::VIDEO))
978     GetRendererClient(DemuxerStream::VIDEO)->OnEnded();
979   else if (IsValid(DemuxerStream::AUDIO))
980     GetRendererClient(DemuxerStream::AUDIO)->OnEnded();
981   Release();
982 }
983
984 void MediaPlayerESPlusPlayer::OnFrameReady(
985     const esplusplayer_decoded_video_packet* packet) {
986   if (!task_runner_->BelongsToCurrentThread()) {
987     task_runner_->PostTask(
988         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::OnFrameReady,
989                                   weak_factory_.GetWeakPtr(), packet));
990     return;
991   }
992   tbm_surface_info_s suf_info = {
993       0,
994   };
995   tbm_surface_h tbm_surface = static_cast<tbm_surface_h>(packet->surface_data);
996
997   if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &suf_info)) {
998     LOG(ERROR) << "|tbm_surface_get_info| failed";
999     return;
1000   }
1001
1002   int width = static_cast<int>(suf_info.width);
1003   int height = static_cast<int>(suf_info.height);
1004   gfx::Size size(width, height);
1005
1006   base::TimeDelta timestamp = base::Milliseconds(packet->pts);
1007   DLOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
1008              << " size:" << size.ToString()
1009              << ", timestamp:" << timestamp.InMilliseconds()
1010              << ", duration:" << packet->duration << ", Player(" << esplayer_
1011              << ", state:" << GetString(GetPlayerState());
1012
1013 #if defined(TIZEN_TBM_SUPPORT)
1014   gfx::TbmBufferHandle tbm_handle;
1015   tbm_handle.tbm_surface = reinterpret_cast<uint64_t>(tbm_surface);
1016   tbm_handle.media_packet = reinterpret_cast<uint64_t>(packet);
1017   tbm_handle.player_id = player_id_;
1018   tbm_handle.width = width;
1019   tbm_handle.height = height;
1020   data_cb_.Run(0, tbm_handle, timestamp);
1021 #else
1022   base::UnsafeSharedMemoryRegion shared_memory;
1023   uint32_t shared_memory_size =
1024       suf_info.planes[0].size + (suf_info.planes[0].size / 2);
1025   shared_memory = base::UnsafeSharedMemoryRegion::Create(shared_memory_size);
1026   if (!shared_memory.IsValid()) {
1027     LOG(ERROR) << "Shared Memory creation failed.";
1028     return;
1029   }
1030
1031   base::WritableSharedMemoryMapping memory_mapping;
1032   memory_mapping = shared_memory.Map();
1033   if (!memory_mapping.IsValid()) {
1034     LOG(ERROR) << "Shared Memory handle could not be obtained";
1035     return;
1036   }
1037
1038   unsigned char* y_ptr = static_cast<unsigned char*>(memory_mapping.memory());
1039
1040   // Video format will always be converted to I420
1041   switch (suf_info.format) {
1042     case TBM_FORMAT_NV12: {
1043       unsigned char* u_ptr = y_ptr + suf_info.planes[0].size;
1044       unsigned char* v_ptr = u_ptr + (suf_info.planes[0].size / 4);
1045       libyuv::NV12ToI420(suf_info.planes[0].ptr, suf_info.planes[0].stride,
1046                          suf_info.planes[1].ptr, suf_info.planes[1].stride,
1047                          y_ptr, suf_info.planes[0].stride, u_ptr,
1048                          suf_info.planes[1].stride / 2, v_ptr,
1049                          suf_info.planes[1].stride / 2, suf_info.width,
1050                          suf_info.height);
1051       break;
1052     }
1053     case TBM_FORMAT_YUV420: {
1054       unsigned char* u_ptr = y_ptr + suf_info.planes[0].size;
1055       unsigned char* v_ptr = u_ptr + suf_info.planes[1].size;
1056       libyuv::I420Copy(
1057           suf_info.planes[0].ptr, suf_info.planes[0].stride,
1058           suf_info.planes[1].ptr, suf_info.planes[1].stride,
1059           suf_info.planes[2].ptr, suf_info.planes[2].stride, y_ptr,
1060           suf_info.planes[0].stride, u_ptr, suf_info.planes[1].stride, v_ptr,
1061           suf_info.planes[2].stride, suf_info.width, suf_info.height);
1062       break;
1063     }
1064     default: {
1065       NOTIMPLEMENTED();
1066       LOG(WARNING) << "Not supported format";
1067       return;
1068     }
1069   }
1070   if (!sink_) {
1071     esplusplayer_decoded_buffer_destroy(
1072         esplayer_, const_cast<esplusplayer_decoded_video_packet*>(packet));
1073     data_cb_.Run(0, std::move(shared_memory), shared_memory_size, timestamp,
1074                  width, height);
1075   } else {
1076     uint8_t* const yuv_buffer = static_cast<uint8_t*>(memory_mapping.memory());
1077     scoped_refptr<VideoFrame> video_frame = VideoFrame::CreateFrame(
1078         media::PIXEL_FORMAT_I420, size, gfx::Rect(size), size, timestamp);
1079
1080     uint8_t* video_buf = yuv_buffer;
1081     const uint c_frm_size = shared_memory_size / 6;
1082     const uint y_frm_size = c_frm_size << 2;  // * 4;
1083
1084     // U Plane buffer.
1085     uint8_t* video_buf_u = video_buf + y_frm_size;
1086
1087     // V Plane buffer.
1088     uint8_t* video_buf_v = video_buf_u + c_frm_size;
1089
1090     libyuv::I420Copy(
1091         video_buf, video_frame.get()->stride(VideoFrame::kYPlane), video_buf_u,
1092         video_frame.get()->stride(VideoFrame::kYPlane) / 2, video_buf_v,
1093         video_frame.get()->stride(VideoFrame::kYPlane) / 2,
1094         video_frame.get()->GetWritableVisibleData(VideoFrame::kYPlane),
1095         video_frame.get()->stride(VideoFrame::kYPlane),
1096         video_frame.get()->GetWritableVisibleData(VideoFrame::kUPlane),
1097         video_frame.get()->stride(VideoFrame::kUPlane),
1098         video_frame.get()->GetWritableVisibleData(VideoFrame::kVPlane),
1099         video_frame.get()->stride(VideoFrame::kVPlane), width, height);
1100     esplusplayer_decoded_buffer_destroy(
1101         esplayer_, const_cast<esplusplayer_decoded_video_packet*>(packet));
1102
1103     sink_->PaintSingleFrame(video_frame);
1104   }
1105 #endif
1106 }
1107
1108 void MediaPlayerESPlusPlayer::OnFlushComplete() {
1109   NOTIMPLEMENTED();
1110 }
1111
1112 void MediaPlayerESPlusPlayer::OnReadyToSeek(
1113     const esplusplayer_stream_type stream_type,
1114     const uint64_t seek_time) {
1115   if (!task_runner_->BelongsToCurrentThread()) {
1116     task_runner_->PostTask(
1117         FROM_HERE,
1118         base::BindOnce(&MediaPlayerESPlusPlayer::OnReadyToSeek,
1119                        weak_factory_.GetWeakPtr(), stream_type, seek_time));
1120     return;
1121   }
1122   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__ << " : "
1123             << DemuxerStream::GetTypeName(GetDemuxerStreamType(stream_type))
1124             << " : " << seek_time;
1125
1126   SetShouldFeed(GetDemuxerStreamType(stream_type), true);
1127   SetIsEos(GetDemuxerStreamType(stream_type), false);
1128   ReadBuffer(GetDemuxerStreamType(stream_type));
1129 }
1130
1131 void MediaPlayerESPlusPlayer::OnSeekComplete() {
1132   if (!task_runner_->BelongsToCurrentThread()) {
1133     task_runner_->PostTask(
1134         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::OnSeekComplete,
1135                                   weak_factory_.GetWeakPtr()));
1136     return;
1137   }
1138
1139   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
1140             << " is_paused:" << is_paused_;
1141
1142   current_position_ = seek_position_;
1143   is_seeking_ = false;
1144   seek_position_ = base::TimeDelta();
1145   if (pending_seek_) {
1146     Seek(pending_seek_position_);
1147     pending_seek_position_ = base::TimeDelta();
1148     return;
1149   }
1150
1151   if (!is_paused_)
1152     Play();
1153 }
1154
1155 void MediaPlayerESPlusPlayer::OnResourceConflict() {
1156   if (!task_runner_->BelongsToCurrentThread()) {
1157     task_runner_->PostTask(
1158         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::OnResourceConflict,
1159                                   weak_factory_.GetWeakPtr()));
1160     return;
1161   }
1162
1163   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
1164   NOTIMPLEMENTED();
1165 }
1166
1167 void MediaPlayerESPlusPlayer::OnError(const esplusplayer_error_type error) {
1168   if (!task_runner_->BelongsToCurrentThread()) {
1169     task_runner_->PostTask(FROM_HERE,
1170                            base::BindOnce(&MediaPlayerESPlusPlayer::OnError,
1171                                           weak_factory_.GetWeakPtr(), error));
1172     return;
1173   }
1174
1175   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__ << " : "
1176             << esplusplayer_get_error_string(
1177                    static_cast<esplusplayer_error_type>(error));
1178
1179   if (IsValid(DemuxerStream::VIDEO))
1180     GetRendererClient(DemuxerStream::VIDEO)->OnError(GetPipelineError(error));
1181   else if (IsValid(DemuxerStream::AUDIO))
1182     GetRendererClient(DemuxerStream::AUDIO)->OnError(GetPipelineError(error));
1183   Release();
1184 }
1185
1186 MediaPlayerESPlusPlayer::ElementryStream&
1187 MediaPlayerESPlusPlayer::GetElementryStream(DemuxerStream::Type type) {
1188   return elementry_stream_[GetElementryStreamIndex(type)];
1189 }
1190
1191 const MediaPlayerESPlusPlayer::ElementryStream&
1192 MediaPlayerESPlusPlayer::GetElementryStream(DemuxerStream::Type type) const {
1193   return elementry_stream_[GetElementryStreamIndex(type)];
1194 }
1195
1196 bool MediaPlayerESPlusPlayer::IsValid(DemuxerStream::Type type) const {
1197   return GetElementryStream(type).is_valid_;
1198 }
1199
1200 void MediaPlayerESPlusPlayer::SetIsValid(DemuxerStream::Type type, bool value) {
1201   GetElementryStream(type).is_valid_ = value;
1202 }
1203
1204 bool MediaPlayerESPlusPlayer::IsEos(DemuxerStream::Type type) const {
1205   return GetElementryStream(type).is_eos_;
1206 }
1207
1208 void MediaPlayerESPlusPlayer::SetIsEos(DemuxerStream::Type type, bool value) {
1209   GetElementryStream(type).is_eos_ = value;
1210 }
1211
1212 bool MediaPlayerESPlusPlayer::ShouldFeed(DemuxerStream::Type type) const {
1213   return GetElementryStream(type).should_feed_;
1214 }
1215
1216 void MediaPlayerESPlusPlayer::SetShouldFeed(DemuxerStream::Type type,
1217                                             bool value) {
1218   GetElementryStream(type).should_feed_ = value;
1219 }
1220
1221 bool MediaPlayerESPlusPlayer::ReadRequested(DemuxerStream::Type type) const {
1222   return GetElementryStream(type).read_requested_;
1223 }
1224
1225 void MediaPlayerESPlusPlayer::SetReadRequested(DemuxerStream::Type type,
1226                                                bool value) {
1227   GetElementryStream(type).read_requested_ = value;
1228 }
1229
1230 BufferStatus MediaPlayerESPlusPlayer::GetBufferStatus(
1231     DemuxerStream::Type type) {
1232   return GetElementryStream(type).buffer_status_;
1233 }
1234
1235 void MediaPlayerESPlusPlayer::SetBufferStatus(DemuxerStream::Type type,
1236                                               BufferStatus status) {
1237   GetElementryStream(type).buffer_status_ = status;
1238 }
1239
1240 DemuxerStream* MediaPlayerESPlusPlayer::GetDemuxerStream(
1241     DemuxerStream::Type type) const {
1242   return GetElementryStream(type).input_stream_;
1243 }
1244
1245 void MediaPlayerESPlusPlayer::SetDemuxerStream(DemuxerStream::Type type,
1246                                                DemuxerStream* stream) {
1247   GetElementryStream(type).input_stream_ = stream;
1248 }
1249
1250 RendererClient* MediaPlayerESPlusPlayer::GetRendererClient(
1251     DemuxerStream::Type type) const {
1252   return GetElementryStream(type).renderer_client_;
1253 }
1254
1255 void MediaPlayerESPlusPlayer::SetRendererClient(DemuxerStream::Type type,
1256                                                 RendererClient* client) {
1257   GetElementryStream(type).renderer_client_ = client;
1258 }
1259
1260 Queue& MediaPlayerESPlusPlayer::GetBufferQueue(DemuxerStream::Type type) {
1261   return GetElementryStream(type).pending_buffers_;
1262 }
1263
1264 void MediaPlayerESPlusPlayer::SetFrameAvailableCallback(
1265     const DataRequestCB& datacb) {
1266   data_cb_ = datacb;
1267 }
1268
1269 #if defined(TIZEN_VIDEO_HOLE)
1270 void MediaPlayerESPlusPlayer::SetVideoHole(bool is_video_hole) {
1271   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
1272             << " is_video_hole : " << is_video_hole;
1273   is_video_hole_ = is_video_hole;
1274   if (is_video_hole_ && esplayer_ && !video_plane_controller_) {
1275     LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
1276               << " pended set video_plane_controller";
1277     video_plane_controller_.reset(
1278         new VideoPlaneControllerESPlusPlayer(esplayer_));
1279   }
1280 }
1281
1282 void MediaPlayerESPlusPlayer::SetMediaGeometry(const gfx::Rect& viewport_rect,
1283                                                const gfx::RectF& rect) {
1284   if (!is_video_hole_)
1285     return;
1286
1287   LOG(INFO) << __func__ << " viewport_rect: " << viewport_rect.ToString()
1288             << " rect : " << rect.ToString();
1289   video_plane_controller_->SetMediaGeometry(viewport_rect, rect);
1290 }
1291
1292 #endif
1293
1294 }  // namespace media