af00b631f2fc126807839a2ae00275ea5d3a990a
[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   } else {
1003     ReportBufferingStateIfNeeded(BUFFERING_HAVE_NOTHING,
1004                                  BUFFERING_CHANGE_REASON_UNKNOWN);
1005   }
1006 }
1007
1008 void MediaPlayerESPlusPlayer::ReportBufferingStateIfNeeded(
1009     BufferingState buffering_state,
1010     BufferingStateChangeReason reason) {
1011   if (reported_buffering_state_ != buffering_state) {
1012     LOG(INFO) << __func__ << " Report BufferingState : " << buffering_state
1013               << ", reason : " << reason;
1014     reported_buffering_state_ = buffering_state;
1015     GetMediaPlayerClient()->OnBufferingStateChange(buffering_state, reason);
1016   }
1017 }
1018
1019 void MediaPlayerESPlusPlayer::PerformOperationForData() {
1020   // The low latency mode doesn't buffer packets. It decodes and renders
1021   // a packet at once. WebRtc uses this feature.
1022   if (is_video_low_latency_)
1023     return;
1024
1025   if (is_seeking_ || is_preparing_)
1026     return;
1027
1028   OperationForData operation = GetOperationForData();
1029   switch (operation) {
1030     case OperationForData::PLAY:
1031       is_paused_by_buffering_ = false;
1032       Play();
1033       break;
1034     case OperationForData::PAUSE:
1035       is_paused_by_buffering_ = true;
1036       Pause(true);
1037       break;
1038   }
1039 }
1040
1041 MediaPlayerESPlusPlayer::OperationForData
1042 MediaPlayerESPlusPlayer::GetOperationForData() {
1043   bool has_video_media_type = GetMediaType() & MediaType::Video;
1044   bool has_audio_media_type = GetMediaType() & MediaType::Audio;
1045
1046   bool has_video_data =
1047       !has_video_media_type ||
1048       (last_frames_.get<DemuxerStream::VIDEO>().first != media::kNoTimestamp);
1049   bool has_audio_data =
1050       !has_audio_media_type ||
1051       (last_frames_.get<DemuxerStream::AUDIO>().first != media::kNoTimestamp);
1052   if (!has_video_data || !has_audio_data) {
1053     LOG(INFO) << __func__
1054               << " Video or audio data has not yet been pushed. video "
1055               << has_video_data << ", audio " << has_audio_data;
1056     return OperationForData::NONE;
1057   }
1058
1059   base::TimeDelta current_position = GetCurrentTime();
1060
1061   if (is_paused_by_buffering_) {
1062     // Get the end position of pushed data.
1063     base::TimeDelta pushed_end_position =
1064         std::min(has_video_media_type
1065                      ? last_frames_.get<DemuxerStream::VIDEO>().first +
1066                            last_frames_.get<DemuxerStream::VIDEO>().second
1067                      : base::TimeDelta::Max(),
1068                  has_audio_media_type
1069                      ? last_frames_.get<DemuxerStream::AUDIO>().first +
1070                            last_frames_.get<DemuxerStream::AUDIO>().second
1071                      : base::TimeDelta::Max());
1072     base::TimeDelta time_diff = pushed_end_position - current_position;
1073
1074     // If data has been pushed enough (>= kMinWaitTimeForPlayback)
1075     if (time_diff >= kMinWaitTimeForPlayback) {
1076       LOG(INFO) << __func__ << " Data is enough to play,";
1077       ReportBufferingStateIfNeeded(BUFFERING_HAVE_ENOUGH,
1078                                    BUFFERING_CHANGE_REASON_UNKNOWN);
1079       return OperationForData::PLAY;
1080     }
1081   } else {
1082     bool should_pause = false;
1083     if (has_video_media_type &&
1084         current_position >= last_frames_.get<DemuxerStream::VIDEO>().first) {
1085       should_pause = true;
1086     }
1087     if (has_audio_media_type &&
1088         current_position >= last_frames_.get<DemuxerStream::AUDIO>().first) {
1089       should_pause = true;
1090     }
1091
1092     if (should_pause) {
1093       LOG(INFO) << __func__ << " Not enough data to play.";
1094       // If pushing pts smaller than current_position, should report
1095       // BUFFERING_HAVE_NOTHING to replace BUFFERING_HAVE_ENOUGH
1096       ReportBufferingStateIfNeeded(BUFFERING_HAVE_NOTHING,
1097                                    BUFFERING_CHANGE_REASON_UNKNOWN);
1098       return OperationForData::PAUSE;
1099     }
1100   }
1101
1102   return OperationForData::NONE;
1103 }
1104
1105 void MediaPlayerESPlusPlayer::StartOperationForDataTimer() {
1106   if (!operation_for_data_timer_.IsRunning()) {
1107     operation_for_data_timer_.Start(
1108         FROM_HERE, kOperationDecisionDelay, this,
1109         &MediaPlayerESPlusPlayer::PerformOperationForData);
1110   }
1111 }
1112
1113 void MediaPlayerESPlusPlayer::StopOperationForDataTimer() {
1114   if (operation_for_data_timer_.IsRunning()) {
1115     operation_for_data_timer_.Stop();
1116   }
1117 }
1118
1119 void MediaPlayerESPlusPlayer::OnReadyToPrepare(
1120     const esplusplayer_stream_type stream_type) {
1121   if (!task_runner_->BelongsToCurrentThread()) {
1122     task_runner_->PostTask(
1123         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::OnReadyToPrepare,
1124                                   weak_factory_.GetWeakPtr(), stream_type));
1125     return;
1126   }
1127
1128   LOG(INFO) << "OnReadyToPrepare : "
1129             << DemuxerStream::GetTypeName(GetDemuxerStreamType(stream_type));
1130   if ((stream_type != ESPLUSPLAYER_STREAM_TYPE_AUDIO) &&
1131       (stream_type != ESPLUSPLAYER_STREAM_TYPE_VIDEO))
1132     return;
1133
1134   DemuxerStream::Type type = GetDemuxerStreamType(stream_type);
1135   if (IsValid(type)) {
1136     SetShouldFeed(type, true);
1137     ReadBuffer(type);
1138   }
1139 }
1140
1141 void MediaPlayerESPlusPlayer::OnPrepareComplete(bool result) {
1142   if (!task_runner_->BelongsToCurrentThread()) {
1143     task_runner_->PostTask(
1144         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::OnPrepareComplete,
1145                                   weak_factory_.GetWeakPtr(), result));
1146     return;
1147   }
1148
1149   if (!result) {
1150     LOG(ERROR) << "OnPrepareComplete prepare_async failed.";
1151     GetMediaPlayerClient()->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
1152     return;
1153   }
1154
1155   if (GetPlayerState() != ESPLUSPLAYER_STATE_READY) {
1156     LOG(ERROR) << "Invalid state (" << GetString(GetPlayerState())
1157                << ") change during prepare. Returning.";
1158     return;
1159   }
1160
1161   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
1162             << " is_paused_ : " << is_paused_
1163             << " seek_position : " << seek_position_
1164             << " pending_seek_ : " << pending_seek_
1165             << " pending_seek_position_ : " << pending_seek_position_;
1166
1167   PostPrepareComplete();
1168 }
1169
1170 void MediaPlayerESPlusPlayer::PostPrepareComplete() {
1171 #if defined(TIZEN_VIDEO_HOLE)
1172   if (is_video_hole_)
1173     video_plane_controller_->ApplyDeferredVideoRectIfNeeded();
1174 #endif
1175
1176   is_prepared_ = true;
1177   is_preparing_ = false;
1178   if (pending_seek_) {
1179     GetMediaPlayerClient()->OnRequestSeek(pending_seek_position_);
1180   } else if (!is_paused_) {
1181     Play();
1182   }
1183 }
1184
1185 void MediaPlayerESPlusPlayer::OnEos() {
1186   if (!task_runner_->BelongsToCurrentThread()) {
1187     task_runner_->PostTask(FROM_HERE,
1188                            base::BindOnce(&MediaPlayerESPlusPlayer::OnEos,
1189                                           weak_factory_.GetWeakPtr()));
1190     return;
1191   }
1192
1193   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
1194   GetMediaPlayerClient()->OnEnded();
1195 }
1196
1197 void MediaPlayerESPlusPlayer::OnFrameReady(
1198     const esplusplayer_decoded_video_packet* packet) {
1199   if (!task_runner_->BelongsToCurrentThread()) {
1200     task_runner_->PostTask(
1201         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::OnFrameReady,
1202                                   weak_factory_.GetWeakPtr(), packet));
1203     return;
1204   }
1205   tbm_surface_info_s suf_info = {
1206       0,
1207   };
1208   tbm_surface_h tbm_surface = static_cast<tbm_surface_h>(packet->surface_data);
1209
1210   if (TBM_SURFACE_ERROR_NONE != tbm_surface_get_info(tbm_surface, &suf_info)) {
1211     LOG(ERROR) << "|tbm_surface_get_info| failed";
1212     return;
1213   }
1214
1215   int width = static_cast<int>(suf_info.width);
1216   int height = static_cast<int>(suf_info.height);
1217   gfx::Size size(width, height);
1218
1219   base::TimeDelta timestamp = base::Milliseconds(packet->pts);
1220   DLOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
1221              << " size:" << size.ToString()
1222              << ", timestamp:" << timestamp.InMilliseconds()
1223              << ", duration:" << packet->duration << ", Player(" << esplayer_
1224              << ", state:" << GetString(GetPlayerState());
1225
1226 #if defined(TIZEN_TBM_SUPPORT)
1227   gfx::TbmBufferHandle tbm_handle;
1228   tbm_handle.tbm_surface = reinterpret_cast<uint64_t>(tbm_surface);
1229   tbm_handle.media_packet = reinterpret_cast<uint64_t>(packet);
1230   tbm_handle.player_id = player_id_;
1231   tbm_handle.width = width;
1232   tbm_handle.height = height;
1233
1234   GetMediaPlayerClient()->OnNewTbmFrameAvailable(0, tbm_handle, timestamp);
1235 #else
1236   base::UnsafeSharedMemoryRegion shared_memory;
1237   uint32_t shared_memory_size =
1238       suf_info.planes[0].size + (suf_info.planes[0].size / 2);
1239   shared_memory = base::UnsafeSharedMemoryRegion::Create(shared_memory_size);
1240   if (!shared_memory.IsValid()) {
1241     LOG(ERROR) << "Shared Memory creation failed.";
1242     return;
1243   }
1244
1245   base::WritableSharedMemoryMapping memory_mapping;
1246   memory_mapping = shared_memory.Map();
1247   if (!memory_mapping.IsValid()) {
1248     LOG(ERROR) << "Shared Memory handle could not be obtained";
1249     return;
1250   }
1251
1252   unsigned char* y_ptr = static_cast<unsigned char*>(memory_mapping.memory());
1253
1254   // Video format will always be converted to I420
1255   switch (suf_info.format) {
1256     case TBM_FORMAT_NV12: {
1257       unsigned char* u_ptr = y_ptr + suf_info.planes[0].size;
1258       unsigned char* v_ptr = u_ptr + (suf_info.planes[0].size / 4);
1259       libyuv::NV12ToI420(suf_info.planes[0].ptr, suf_info.planes[0].stride,
1260                          suf_info.planes[1].ptr, suf_info.planes[1].stride,
1261                          y_ptr, suf_info.planes[0].stride, u_ptr,
1262                          suf_info.planes[1].stride / 2, v_ptr,
1263                          suf_info.planes[1].stride / 2, suf_info.width,
1264                          suf_info.height);
1265       break;
1266     }
1267     case TBM_FORMAT_YUV420: {
1268       unsigned char* u_ptr = y_ptr + suf_info.planes[0].size;
1269       unsigned char* v_ptr = u_ptr + suf_info.planes[1].size;
1270       libyuv::I420Copy(
1271           suf_info.planes[0].ptr, suf_info.planes[0].stride,
1272           suf_info.planes[1].ptr, suf_info.planes[1].stride,
1273           suf_info.planes[2].ptr, suf_info.planes[2].stride, y_ptr,
1274           suf_info.planes[0].stride, u_ptr, suf_info.planes[1].stride, v_ptr,
1275           suf_info.planes[2].stride, suf_info.width, suf_info.height);
1276       break;
1277     }
1278     default: {
1279       NOTIMPLEMENTED();
1280       LOG(WARNING) << "Not supported format";
1281       return;
1282     }
1283   }
1284   if (!sink_) {
1285     esplusplayer_decoded_buffer_destroy(
1286         esplayer_, const_cast<esplusplayer_decoded_video_packet*>(packet));
1287     GetMediaPlayerClient()->OnNewFrameAvailable(0, std::move(shared_memory),
1288                                                 shared_memory_size, timestamp,
1289                                                 width, height);
1290   } else {
1291     uint8_t* const yuv_buffer = static_cast<uint8_t*>(memory_mapping.memory());
1292     scoped_refptr<VideoFrame> video_frame = VideoFrame::CreateFrame(
1293         media::PIXEL_FORMAT_I420, size, gfx::Rect(size), size, timestamp);
1294
1295     uint8_t* video_buf = yuv_buffer;
1296     const uint c_frm_size = shared_memory_size / 6;
1297     const uint y_frm_size = c_frm_size << 2;  // * 4;
1298
1299     // U Plane buffer.
1300     uint8_t* video_buf_u = video_buf + y_frm_size;
1301
1302     // V Plane buffer.
1303     uint8_t* video_buf_v = video_buf_u + c_frm_size;
1304
1305     libyuv::I420Copy(
1306         video_buf, video_frame.get()->stride(VideoFrame::kYPlane), video_buf_u,
1307         video_frame.get()->stride(VideoFrame::kYPlane) / 2, video_buf_v,
1308         video_frame.get()->stride(VideoFrame::kYPlane) / 2,
1309         video_frame.get()->GetWritableVisibleData(VideoFrame::kYPlane),
1310         video_frame.get()->stride(VideoFrame::kYPlane),
1311         video_frame.get()->GetWritableVisibleData(VideoFrame::kUPlane),
1312         video_frame.get()->stride(VideoFrame::kUPlane),
1313         video_frame.get()->GetWritableVisibleData(VideoFrame::kVPlane),
1314         video_frame.get()->stride(VideoFrame::kVPlane), width, height);
1315     esplusplayer_decoded_buffer_destroy(
1316         esplayer_, const_cast<esplusplayer_decoded_video_packet*>(packet));
1317
1318     sink_->PaintSingleFrame(video_frame);
1319   }
1320 #endif
1321 }
1322
1323 void MediaPlayerESPlusPlayer::OnFlushComplete() {
1324   NOTIMPLEMENTED();
1325 }
1326
1327 void MediaPlayerESPlusPlayer::OnReadyToSeek(
1328     const esplusplayer_stream_type stream_type,
1329     const uint64_t seek_time) {
1330   if (!task_runner_->BelongsToCurrentThread()) {
1331     task_runner_->PostTask(
1332         FROM_HERE,
1333         base::BindOnce(&MediaPlayerESPlusPlayer::OnReadyToSeek,
1334                        weak_factory_.GetWeakPtr(), stream_type, seek_time));
1335     return;
1336   }
1337   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__ << " : "
1338             << DemuxerStream::GetTypeName(GetDemuxerStreamType(stream_type))
1339             << " : " << seek_time;
1340
1341   if (!esplayer_) {
1342     LOG(INFO) << "player is destroyed:" << (void*)this;
1343     return;
1344   }
1345
1346   SetShouldFeed(GetDemuxerStreamType(stream_type), true);
1347   SetIsEos(GetDemuxerStreamType(stream_type), false);
1348   ReadBuffer(GetDemuxerStreamType(stream_type));
1349 }
1350
1351 void MediaPlayerESPlusPlayer::OnSeekComplete() {
1352   if (!task_runner_->BelongsToCurrentThread()) {
1353     task_runner_->PostTask(
1354         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::OnSeekComplete,
1355                                   weak_factory_.GetWeakPtr()));
1356     return;
1357   }
1358
1359   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
1360             << " is_paused:" << is_paused_;
1361
1362   current_position_ = seek_position_;
1363   is_seeking_ = false;
1364   expected_seek_ = false;
1365   seek_position_ = base::TimeDelta();
1366
1367   if (!is_paused_)
1368     Play();
1369 }
1370
1371 void MediaPlayerESPlusPlayer::OnResourceConflict() {
1372   if (!task_runner_->BelongsToCurrentThread()) {
1373     task_runner_->PostTask(
1374         FROM_HERE, base::BindOnce(&MediaPlayerESPlusPlayer::OnResourceConflict,
1375                                   weak_factory_.GetWeakPtr()));
1376     return;
1377   }
1378
1379   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
1380   RequestSuspend(true);
1381 }
1382
1383 void MediaPlayerESPlusPlayer::OnError(const esplusplayer_error_type error) {
1384   if (!task_runner_->BelongsToCurrentThread()) {
1385     task_runner_->PostTask(FROM_HERE,
1386                            base::BindOnce(&MediaPlayerESPlusPlayer::OnError,
1387                                           weak_factory_.GetWeakPtr(), error));
1388     return;
1389   }
1390
1391   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__ << " : "
1392             << esplusplayer_get_error_string(
1393                    static_cast<esplusplayer_error_type>(error));
1394
1395   GetMediaPlayerClient()->OnError(GetPipelineError(error));
1396   Release();
1397 }
1398
1399 MediaPlayerESPlusPlayer::ElementryStream&
1400 MediaPlayerESPlusPlayer::GetElementryStream(DemuxerStream::Type type) {
1401   return elementry_stream_[GetElementryStreamIndex(type)];
1402 }
1403
1404 const MediaPlayerESPlusPlayer::ElementryStream&
1405 MediaPlayerESPlusPlayer::GetElementryStream(DemuxerStream::Type type) const {
1406   return elementry_stream_[GetElementryStreamIndex(type)];
1407 }
1408
1409 bool MediaPlayerESPlusPlayer::IsValid(DemuxerStream::Type type) const {
1410   return GetElementryStream(type).is_valid_;
1411 }
1412
1413 void MediaPlayerESPlusPlayer::SetIsValid(DemuxerStream::Type type, bool value) {
1414   GetElementryStream(type).is_valid_ = value;
1415 }
1416
1417 bool MediaPlayerESPlusPlayer::IsEos(DemuxerStream::Type type) const {
1418   return GetElementryStream(type).is_eos_;
1419 }
1420
1421 void MediaPlayerESPlusPlayer::SetIsEos(DemuxerStream::Type type, bool value) {
1422   GetElementryStream(type).is_eos_ = value;
1423 }
1424
1425 bool MediaPlayerESPlusPlayer::ShouldFeed(DemuxerStream::Type type) const {
1426   return GetElementryStream(type).should_feed_;
1427 }
1428
1429 void MediaPlayerESPlusPlayer::SetShouldFeed(DemuxerStream::Type type,
1430                                             bool value) {
1431   GetElementryStream(type).should_feed_ = value;
1432 }
1433
1434 bool MediaPlayerESPlusPlayer::ReadRequested(DemuxerStream::Type type) const {
1435   return GetElementryStream(type).read_requested_;
1436 }
1437
1438 void MediaPlayerESPlusPlayer::SetReadRequested(DemuxerStream::Type type,
1439                                                bool value) {
1440   GetElementryStream(type).read_requested_ = value;
1441 }
1442
1443 DemuxerStream* MediaPlayerESPlusPlayer::GetDemuxerStream(
1444     DemuxerStream::Type type) const {
1445   return GetElementryStream(type).input_stream_;
1446 }
1447
1448 void MediaPlayerESPlusPlayer::SetDemuxerStream(DemuxerStream::Type type,
1449                                                DemuxerStream* stream) {
1450   GetElementryStream(type).input_stream_ = stream;
1451 }
1452
1453 Queue& MediaPlayerESPlusPlayer::GetBufferQueue(DemuxerStream::Type type) {
1454   return GetElementryStream(type).pending_buffers_;
1455 }
1456
1457 #if defined(TIZEN_VIDEO_HOLE)
1458 void MediaPlayerESPlusPlayer::SetVideoHole(bool is_video_hole) {
1459   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
1460             << " is_video_hole : " << is_video_hole;
1461   is_video_hole_ = is_video_hole;
1462   if (is_video_hole_ && esplayer_ && !video_plane_controller_) {
1463     LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__
1464               << " pended set video_plane_controller";
1465     video_plane_controller_.reset(
1466         new VideoPlaneControllerESPlusPlayer(esplayer_));
1467   }
1468 }
1469
1470 void MediaPlayerESPlusPlayer::SetMediaGeometry(const gfx::Rect& viewport_rect,
1471                                                const gfx::RectF& rect) {
1472   if (!is_video_hole_)
1473     return;
1474
1475   LOG(INFO) << __func__ << " viewport_rect: " << viewport_rect.ToString()
1476             << " rect : " << rect.ToString();
1477
1478   if (!esplayer_ || !video_plane_controller_) {
1479     LOG_ID(INFO, player_id_)
1480         << "(" << static_cast<void*>(this) << ") "
1481         << "player is destroyed, or video plane controller not exist.";
1482     return;
1483   }
1484
1485   video_plane_controller_->SetMediaGeometry(viewport_rect, rect);
1486 }
1487
1488 void MediaPlayerESPlusPlayer::PrepareVideoHole() {
1489   LOG_ID(INFO, player_id_) << "(" << static_cast<void*>(this) << ") "
1490                            << __func__;
1491   if (!esplayer_ || is_prepared_ || is_preparing_) {
1492     LOG_ID(ERROR, player_id_)
1493         << "(" << static_cast<void*>(this) << ") " << __func__
1494         << ", esplayer_: " << static_cast<void*>(esplayer_)
1495         << ", is_prepared_: " << is_prepared_
1496         << ", is_preparing_: " << is_preparing_;
1497     return;
1498   }
1499   if (GetPlayerState() != ESPLUSPLAYER_STATE_IDLE) {
1500     LOG(ERROR) << "(" << static_cast<void*>(this) << ") " << __func__
1501                << " Prepare called on invalid state : "
1502                << GetString(GetPlayerState());
1503     return;
1504   }
1505
1506   if (!is_video_hole_ || !video_plane_controller_)
1507     return;
1508
1509   if (video_plane_controller_->Initialize() != TIZEN_ERROR_NONE) {
1510     LOG(ERROR) << "video_plane_controller init error";
1511     return;
1512   }
1513
1514   LOG(INFO) << __func__ << " set ESPLUSPLAYER_DISPLAY_TYPE_OVERLAY";
1515   int player_error = ESPLUSPLAYER_ERROR_TYPE_NONE;
1516   if (video_plane_controller_->rendering_mode() ==
1517       VideoPlaneController::RenderingMode::OFFSCREEN &&
1518       !video_plane_controller_->get_use_wayland_window()) {
1519     player_error = esplusplayer_set_display(
1520         esplayer_, ESPLUSPLAYER_DISPLAY_TYPE_OVERLAY,
1521         video_plane_controller_->GetVideoPlaneHandle());
1522   } else {
1523     int wl_w, wl_h, wl_x, wl_y;
1524     ecore_wl2_window_geometry_get(
1525         static_cast<Ecore_Wl2_Window*>(
1526             video_plane_controller_->GetVideoPlaneHandle()),
1527         &wl_x, &wl_y, &wl_w, &wl_h);
1528
1529     player_error = esplusplayer_set_ecore_display(
1530         esplayer_, ESPLUSPLAYER_DISPLAY_TYPE_OVERLAY,
1531         static_cast<Ecore_Wl2_Window*>(
1532             video_plane_controller_->GetVideoPlaneHandle()),
1533         wl_x, wl_y, wl_w, wl_h);
1534   }
1535   if (player_error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
1536     LOG(ERROR) << "player_error #"
1537                << esplusplayer_get_error_string(
1538                       static_cast<esplusplayer_error_type>(player_error));
1539     return;
1540   }
1541 }
1542 #endif
1543
1544 void MediaPlayerESPlusPlayer::RequestSuspend(bool resource_conflicted) {
1545   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
1546   GetMediaPlayerClient()->OnRequestSuspend(resource_conflicted);
1547   Release();
1548 }
1549
1550 void MediaPlayerESPlusPlayer::SetMediaType(DemuxerStream::Type type) {
1551   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
1552   if (type == DemuxerStream::AUDIO)
1553     SetMediaType(GetMediaType() | MediaType::Audio);
1554   else if (type == DemuxerStream::VIDEO)
1555     SetMediaType(GetMediaType() | MediaType::Video);
1556 }
1557
1558 PlayerRoleFlags MediaPlayerESPlusPlayer::GetRoles() const noexcept {
1559   return PlayerRole::ElementaryStreamBased;
1560 }
1561
1562 }  // namespace media