[M120 Migration][MM] Modifications for basic operation of ME & MSE using espp. 72/305472/2
authorSun-woo Nam <sunny.nam@samsung.com>
Fri, 2 Feb 2024 04:15:11 +0000 (20:15 -0800)
committerSunwoo Nam <sunny.nam@samsung.com>
Thu, 15 Feb 2024 21:54:20 +0000 (21:54 +0000)
This patch migrates previous patches for media operations such as play, pause
and seek. And this patch categorizes them into several groups.

[Buffer logic]
- Reduce read requests
Avoid read request when player is not playing / seeking.
https://review.tizen.org/gerrit/#/c/292239/
https://review.tizen.org/gerrit/#/c/294027/

- Read data from demuxer during buffer underrun
https://review.tizen.org/gerrit/#/c/294082/

-Shrink unnecessary OnBufferingStateChange call.
The player doesn't need to transfer the same state (BUFFERING_HAVE_ENOUGH)
to the renderer side, so add the condition to shrink it.
https://review.tizen.org/gerrit/#/c/299653/

- Do not return the index -1 for the array.
The potential defect was reported by Coverity.
https://review.tizen.org/gerrit/#/c/293011/

- Remove unutilized code
Remove buffering based player state handling.
https://review.tizen.org/gerrit/#/c/294537/

[Seek]
- fixup! [M108 Migration][MM] Introduce renderer seek
for resume play scenario, app will seek to previous playtime
expected_seek_ is set true, if the player is not ready,
it will stop espp to read data from demuxer, so espp prepare never complete
https://review.tizen.org/gerrit/#/c/294960/
https://review.tizen.org/gerrit/#/c/295324/

- Ignore Flush before prepared
https://review.tizen.org/gerrit/#/c/298597/

- Prevent to esplsuplayer_seek twice.
https://review.tizen.org/gerrit/#/c/300869/

- Do not ignore seeking to 0 before prepared.
https://review.tizen.org/gerrit/#/c/301027/

- Skip the seek when the requested time is same as pending seek position.
https://review.tizen.org/gerrit/#/c/301630/

- Fix seeking after esplayer destroyed
https://review.tizen.org/gerrit/#/c/302426/

[Other]
- Fix video_000 video tct
Fix manual tests "video_000" that expects reference frame
to be displayed on the screen.
https://review.tizen.org/gerrit/#/c/292260/
https://review.tizen.org/gerrit/#/c/292315/

- Do not mute when the playback rate is 2.0.
https://review.tizen.org/gerrit/#/c/296453/

- Keep last frame when receive EOS event
https://review.tizen.org/gerrit/#/c/298157/

- Fix browser main thread stuck issue
player_get_play_position called before prepared.
This sync api will block browser thread.
Only prepare complete, then call this api
https://review.tizen.org/gerrit/#/c/300201/

- Check an espp status before setting the buffer type.
https://review.tizen.org/gerrit/#/c/299286/

- Fix svace warning
https://review.tizen.org/gerrit/#/c/297825/

- Fixup! [MM] Ensure player is destroyed before IEMEDrmBridge
https://review.tizen.org/gerrit/#/c/302624/

Change-Id: I6c77f75da170119892803d3d943cf3422ac5a9df
Signed-off-by: Sun-woo Nam <sunny.nam@samsung.com>
tizen_src/chromium_impl/media/filters/esplusplayer_util.cc
tizen_src/chromium_impl/media/filters/media_player_esplusplayer.cc
tizen_src/chromium_impl/media/filters/media_player_esplusplayer.h
tizen_src/chromium_impl/media/filters/media_player_esplusplayer_common.cc
tizen_src/chromium_impl/media/filters/media_player_esplusplayer_tv.cc
tizen_src/chromium_impl/media/filters/media_player_esplusplayer_tv.h

index a78563a..6094401 100644 (file)
@@ -132,14 +132,17 @@ esplusplayer_video_mime_type ConvertToESPlusVideoMimeType(
 }
 
 int GetElementryStreamIndex(DemuxerStream::Type type) {
+  DCHECK(type == DemuxerStream::AUDIO || type == DemuxerStream::VIDEO);
+
   switch (type) {
     case DemuxerStream::AUDIO:
       return 0;
     case DemuxerStream::VIDEO:
       return 1;
     default:
-      LOG(WARNING) << "Stream type [" << type << "] is not supported";
-      return -1;
+      LOG(ERROR) << "Stream type [" << type
+                 << "] is not supported. Returning 0 (Audio type).";
+      return 0;
   }
 }
 
index 805adcd..60a8639 100644 (file)
@@ -11,7 +11,6 @@
 #include "base/functional/callback.h"
 #include "base/location.h"
 #include "base/logging.h"
-#include "media/base/buffering_state.h"
 #include "media/base/decoder_buffer.h"
 #include "third_party/libyuv/include/libyuv/convert.h"
 #include "tizen_src/chromium_impl/media/filters/esplusplayer_buffer_observer_impl.h"
@@ -169,6 +168,13 @@ bool MediaPlayerESPlusPlayer::CreatePlayer(int player_id) {
 
 void MediaPlayerESPlusPlayer::Initialize(VideoRendererSink* sink) {
   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
+
+  if (!esplayer_) {
+    LOG(INFO) << "(" << static_cast<void*>(this) << ") "
+                             << "esplayer is null.";
+    return;
+  }
+
   esplusplayer_set_ready_to_prepare_cb(esplayer_, &ReadyToPrepareCallback,
                                        this);
   esplusplayer_set_prepare_async_done_cb(esplayer_, &PrepareCompleteCallback,
@@ -226,7 +232,7 @@ void MediaPlayerESPlusPlayer::SetStreamInfo(DemuxerStream::Type type,
 
 void MediaPlayerESPlusPlayer::Prepare() {
   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
-  if (is_prepared_ || is_preparing_)
+  if (!esplayer_ || is_prepared_ || is_preparing_)
     return;
 
   if (GetPlayerState() != ESPLUSPLAYER_STATE_IDLE) {
@@ -236,7 +242,15 @@ void MediaPlayerESPlusPlayer::Prepare() {
     return;
   }
 
-  int error = esplusplayer_prepare_async(esplayer_);
+  int error = esplusplayer_set_display_visible(esplayer_, true);
+  if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
+    LOG(ERROR)
+        << "esplusplayer_set_display_visible failed! error #"
+        << esplusplayer_get_error_string(
+               static_cast<esplusplayer_error_type>(error));
+  }
+
+  error = esplusplayer_prepare_async(esplayer_);
   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
     LOG(ERROR) << "player prepare failed! error #"
                << esplusplayer_get_error_string(
@@ -264,11 +278,13 @@ void MediaPlayerESPlusPlayer::Release() {
   SetShouldFeed(DemuxerStream::AUDIO, false);
   SetIsValid(DemuxerStream::AUDIO, false);
   SetReadRequested(DemuxerStream::AUDIO, false);
+  SetBufferingState(DemuxerStream::AUDIO, BUFFERING_HAVE_NOTHING);
 
   SetIsEos(DemuxerStream::VIDEO, false);
   SetShouldFeed(DemuxerStream::VIDEO, false);
   SetIsValid(DemuxerStream::VIDEO, false);
   SetReadRequested(DemuxerStream::VIDEO, false);
+  SetBufferingState(DemuxerStream::VIDEO, BUFFERING_HAVE_NOTHING);
 
   esplusplayer_set_ready_to_prepare_cb(esplayer_, nullptr, this);
   esplusplayer_set_prepare_async_done_cb(esplayer_, nullptr, this);
@@ -349,6 +365,13 @@ bool MediaPlayerESPlusPlayer::Play() {
     // TODO: handle error!
     return false;
   }
+
+  // To submit packets when playback starts.
+  if (IsValid(DemuxerStream::VIDEO))
+    ReadBuffer(DemuxerStream::VIDEO);
+  if (IsValid(DemuxerStream::AUDIO))
+    ReadBuffer(DemuxerStream::AUDIO);
+
   return true;
 }
 
@@ -384,6 +407,14 @@ void MediaPlayerESPlusPlayer::Pause(bool is_media_related_action) {
 void MediaPlayerESPlusPlayer::SetRate(double rate) {
   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__ << " : "
             << rate;
+
+  // the playback rate from 0.0 to 2.0 in esplusplayer.
+  if (rate > 2.0) {
+    LOG(WARNING) << __func__ << " The playback rate value in esplusplayer "
+                 << " cannot exceed 2.0.";
+    rate = 2.0;
+  }
+
   if (playback_rate_ == rate)
     return;
 
@@ -393,9 +424,7 @@ void MediaPlayerESPlusPlayer::SetRate(double rate) {
     return;
   }
 
-  bool should_mute = rate >= 2.0;
-  int error =
-      esplusplayer_set_playback_rate(esplayer_, playback_rate_, should_mute);
+  int error = esplusplayer_set_playback_rate(esplayer_, playback_rate_, false);
   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
     LOG(ERROR) << "player set playback rate failed! error #"
                << esplusplayer_get_error_string(
@@ -407,6 +436,10 @@ void MediaPlayerESPlusPlayer::SetRate(double rate) {
 
 void MediaPlayerESPlusPlayer::Seek(base::TimeDelta time,
                                    base::OnceClosure seek_cb) {
+  LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__ << " :"
+            << time;
+
+  expected_seek_ = false;
   // Ignore seek in release state. Will catch-up later.
   if (GetPlayerState() == ESPLUSPLAYER_STATE_NONE) {
     LOG(INFO) << __func__ << " Ignore seek in release state.";
@@ -415,18 +448,15 @@ void MediaPlayerESPlusPlayer::Seek(base::TimeDelta time,
     return;
   }
 
-  // Ignore seek to 0 during initialization.
-  if (GetPlayerState() < ESPLUSPLAYER_STATE_READY && time.InSecondsF() == 00) {
-    LOG(INFO) << __func__ << " Ignore seek to 0 during initialization.";
-    if (seek_cb)
-      std::move(seek_cb).Run();
-    return;
-  }
-
-  LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__ << " :"
-            << time;
-
   if (GetPlayerState() < ESPLUSPLAYER_STATE_READY || !is_prepared_) {
+    // Prevent to set the same pending seek position and
+    // stop pushing again from 0sec when media starts 0.
+    if (time == pending_seek_position_) {
+      if (seek_cb)
+        std::move(seek_cb).Run();
+      return;
+    }
+
     LOG(INFO) << "Add to pending seek ("
               << ") state: " << GetString(GetPlayerState())
               << " is_prepared : " << is_prepared_;
@@ -437,6 +467,14 @@ void MediaPlayerESPlusPlayer::Seek(base::TimeDelta time,
       std::move(seek_cb).Run();
     return;
   }
+
+  if (is_seeking_ && seek_position_ == time) {
+    LOG(INFO) << __func__ << " Seeking the same position.";
+    if (seek_cb)
+      std::move(seek_cb).Run();
+    return;
+  }
+
   seek_cb_ = std::move(seek_cb);
 
   SeekInternal(time);
@@ -461,8 +499,9 @@ void MediaPlayerESPlusPlayer::SeekInternal(base::TimeDelta time) {
 }
 
 void MediaPlayerESPlusPlayer::Flush(base::OnceClosure flush_cb) {
-  // Ignore Flush in release state.
-  if (GetPlayerState() == ESPLUSPLAYER_STATE_NONE) {
+  // Ignore Flush before prepared state.
+  if (GetPlayerState() < ESPLUSPLAYER_STATE_READY) {
+    LOG(INFO) << "player is not ready, state:" << GetString(GetPlayerState());
     if (flush_cb)
       std::move(flush_cb).Run();
     return;
@@ -478,6 +517,8 @@ void MediaPlayerESPlusPlayer::Flush(base::OnceClosure flush_cb) {
   SetShouldFeed(DemuxerStream::VIDEO, false);
   GetBufferQueue(DemuxerStream::VIDEO).clear();
   GetBufferQueue(DemuxerStream::AUDIO).clear();
+  SetBufferingState(DemuxerStream::AUDIO, BUFFERING_HAVE_NOTHING);
+  SetBufferingState(DemuxerStream::VIDEO, BUFFERING_HAVE_NOTHING);
   buffer_observer_->ResetBufferStatus();
 
   std::move(flush_cb).Run();
@@ -508,6 +549,11 @@ base::TimeDelta MediaPlayerESPlusPlayer::GetCurrentTime() {
   if (GetPlayerState() < ESPLUSPLAYER_STATE_PLAYING)
     return current_position_;
 
+  // esplusplayer_get_playing_time is sync api, need called after prepared.
+  // Otherwise will block browser process.
+  if (!is_prepared_)
+    return base::TimeDelta();
+
   uint64_t time = 0;  // In milliseconds.
   int error = esplusplayer_get_playing_time(esplayer_, &time);
   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
@@ -541,12 +587,12 @@ esplusplayer_state MediaPlayerESPlusPlayer::GetPlayerState() {
 }
 
 player_buffer_size_t MediaPlayerESPlusPlayer::GetMaxVideoBufferSize(
-    media::VideoDecoderConfig video_config) {
+    const media::VideoDecoderConfig& video_config) {
   return kPlayerTotalBufferSize - kPlayerAudioBufferSize;
 }
 
 int MediaPlayerESPlusPlayer::SetVideoStreamInfo(
-    media::VideoDecoderConfig& video_config,
+    const media::VideoDecoderConfig& video_config,
     esplusplayer_video_stream_info& video_stream_info) {
   video_stream_info.width = video_config.coded_size().width();
   video_stream_info.height = video_config.coded_size().height();
@@ -681,8 +727,10 @@ void MediaPlayerESPlusPlayer::ReadBuffer(DemuxerStream::Type type) {
     return;
 
   // Avoid unnecessary or redundant read requests.
-  if (!ShouldFeed(type) || ReadRequested(type) || IsEos(type))
+  if (!ShouldFeed(type) || ReadRequested(type) || IsEos(type) ||
+      (is_prepared_ && is_paused_ && !is_seeking_)) {
     return;
+  }
 
   SetReadRequested(type, true);
   uint32_t buffer_read_count = 1;
@@ -831,30 +879,14 @@ void MediaPlayerESPlusPlayer::OnBufferingStatusChanged(DemuxerStream::Type type,
                                                        BufferStatus status) {
   DVLOG(INFO) << __func__ << " " << DemuxerStream::GetTypeName(type) << " : "
               << GetString(status);
-  const auto RequestStateChange = [this](esplusplayer_state state) {
-    LOG(INFO) << __func__ << " req. change state : " << GetString(state);
-    switch (state) {
-      case ESPLUSPLAYER_STATE_PLAYING:
-        Play();
-        break;
-      case ESPLUSPLAYER_STATE_PAUSED:
-        Pause(true);
-        break;
-      default:
-        NOTREACHED();
-    }
-  };
 
-  if (expected_seek_) {
+  if (expected_seek_ && is_prepared_) {
     LOG(INFO) << "Ignore the buffer updates while seek";
     return;
   }
 
-  SetBufferStatus(type, status);
   switch (status) {
     case kBufferUnderrun:
-      //  RequestStateChange(ESPLUSPLAYER_STATE_PAUSED);
-      [[fallthrough]];
     case kBufferMinThreshold:
     case kBufferNormal:
       is_buffering_ = true;
@@ -867,19 +899,19 @@ void MediaPlayerESPlusPlayer::OnBufferingStatusChanged(DemuxerStream::Type type,
     case kBufferAhead:
       is_buffering_ = false;
       SetShouldFeed(type, false);
-      //  if (!is_paused_)
-      //    RequestStateChange(ESPLUSPLAYER_STATE_PLAYING);
       break;
     case kBufferNone:
       NOTREACHED();
   }
 
-  // TODO: Check if controller can control underflow. Currently buffering
-  // related state changes are commented for the same (in Play and
-  // RequestStateChange).
   if (status != kBufferNone) {
-    GetMediaPlayerClient()->OnBufferingStateChange(
-        BUFFERING_HAVE_ENOUGH, BUFFERING_CHANGE_REASON_UNKNOWN);
+    if (GetBufferingState(type) != BUFFERING_HAVE_ENOUGH) {
+      SetBufferingState(type, BUFFERING_HAVE_ENOUGH);
+      GetMediaPlayerClient()->OnBufferingStateChange(
+          BUFFERING_HAVE_ENOUGH, BUFFERING_CHANGE_REASON_UNKNOWN);
+    }
+  } else {
+    SetBufferingState(type, BUFFERING_HAVE_NOTHING);
   }
 }
 
@@ -958,7 +990,6 @@ void MediaPlayerESPlusPlayer::OnEos() {
 
   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
   GetMediaPlayerClient()->OnEnded();
-  Release();
 }
 
 void MediaPlayerESPlusPlayer::OnFrameReady(
@@ -1105,6 +1136,11 @@ void MediaPlayerESPlusPlayer::OnReadyToSeek(
             << DemuxerStream::GetTypeName(GetDemuxerStreamType(stream_type))
             << " : " << seek_time;
 
+  if (!esplayer_) {
+    LOG(INFO) << "player is destroyed:" << (void*)this;
+    return;
+  }
+
   SetShouldFeed(GetDemuxerStreamType(stream_type), true);
   SetIsEos(GetDemuxerStreamType(stream_type), false);
   ReadBuffer(GetDemuxerStreamType(stream_type));
@@ -1202,14 +1238,14 @@ void MediaPlayerESPlusPlayer::SetReadRequested(DemuxerStream::Type type,
   GetElementryStream(type).read_requested_ = value;
 }
 
-BufferStatus MediaPlayerESPlusPlayer::GetBufferStatus(
+BufferingState MediaPlayerESPlusPlayer::GetBufferingState(
     DemuxerStream::Type type) {
-  return GetElementryStream(type).buffer_status_;
+  return GetElementryStream(type).buffering_state_;
 }
 
-void MediaPlayerESPlusPlayer::SetBufferStatus(DemuxerStream::Type type,
-                                              BufferStatus status) {
-  GetElementryStream(type).buffer_status_ = status;
+void MediaPlayerESPlusPlayer::SetBufferingState(DemuxerStream::Type type,
+                                                BufferingState state) {
+  GetElementryStream(type).buffering_state_ = state;
 }
 
 DemuxerStream* MediaPlayerESPlusPlayer::GetDemuxerStream(
@@ -1246,12 +1282,20 @@ void MediaPlayerESPlusPlayer::SetMediaGeometry(const gfx::Rect& viewport_rect,
 
   LOG(INFO) << __func__ << " viewport_rect: " << viewport_rect.ToString()
             << " rect : " << rect.ToString();
+
+  if (!esplayer_ || !video_plane_controller_) {
+    LOG(INFO)
+        << "(" << static_cast<void*>(this) << ") "
+        << "player is destroyed, or video plane controller not exist.";
+    return;
+  }
+
   video_plane_controller_->SetMediaGeometry(viewport_rect, rect);
 }
 
 void MediaPlayerESPlusPlayer::PrepareVideoHole() {
   LOG(INFO) << "(" << static_cast<void*>(this) << ") " << __func__;
-  if (is_prepared_ || is_preparing_)
+  if (!esplayer_ || is_prepared_ || is_preparing_)
     return;
 
   if (GetPlayerState() != ESPLUSPLAYER_STATE_IDLE) {
index ae21e88..e0541de 100644 (file)
@@ -11,6 +11,7 @@
 #include "base/memory/unsafe_shared_memory_region.h"
 #include "base/task/single_thread_task_runner.h"
 #include "base/time/time.h"
+#include "media/base/buffering_state.h"
 #include "media/base/demuxer_stream.h"
 #include "media/base/video_renderer_sink.h"
 #include "tizen_src/chromium_impl/base/tizen/static_map.h"
@@ -79,7 +80,7 @@ class MEDIA_EXPORT MediaPlayerESPlusPlayer : public MediaPlayerTizen {
   // Callback handler
   void OnReadyToPrepare(const esplusplayer_stream_type stream_type);
   virtual void OnPrepareComplete(bool result);
-  void OnEos();
+  virtual void OnEos();
   void OnFrameReady(const esplusplayer_decoded_video_packet* packet);
   void OnFlushComplete();
   void OnReadyToSeek(const esplusplayer_stream_type stream_type,
@@ -101,7 +102,7 @@ class MEDIA_EXPORT MediaPlayerESPlusPlayer : public MediaPlayerTizen {
  protected:
   // Product sepecific implementation.
   virtual int SetVideoStreamInfo(
-      media::VideoDecoderConfig& video_config,
+      const media::VideoDecoderConfig& video_config,
       esplusplayer_video_stream_info& video_stream_info);
   virtual void SetAudioStreamInfo(
       const media::AudioDecoderConfig& audio_config,
@@ -113,7 +114,7 @@ class MEDIA_EXPORT MediaPlayerESPlusPlayer : public MediaPlayerTizen {
       scoped_refptr<DecoderBuffer> buffer);
   virtual void PostPrepareComplete();
   virtual player_buffer_size_t GetMaxVideoBufferSize(
-      media::VideoDecoderConfig video_config);
+      const media::VideoDecoderConfig& video_config);
   virtual void InitializeStreamConfig(DemuxerStream::Type type);
   esplusplayer_state GetPlayerState();
   bool IsValid(DemuxerStream::Type type) const;
@@ -146,7 +147,7 @@ class MEDIA_EXPORT MediaPlayerESPlusPlayer : public MediaPlayerTizen {
     bool is_eos_ = false;
     bool should_feed_ = false;
     bool read_requested_ = false;
-    BufferStatus buffer_status_ = kBufferNone;  // Not used!
+    BufferingState buffering_state_ = BUFFERING_HAVE_NOTHING;
     DemuxerStream* input_stream_ = nullptr;
     base::circular_deque<scoped_refptr<DecoderBuffer>> pending_buffers_;
   };
@@ -166,8 +167,8 @@ class MEDIA_EXPORT MediaPlayerESPlusPlayer : public MediaPlayerTizen {
   ElementryStream& GetElementryStream(DemuxerStream::Type type);
   const ElementryStream& GetElementryStream(DemuxerStream::Type type) const;
   void SetReadRequested(DemuxerStream::Type type, bool value);
-  BufferStatus GetBufferStatus(DemuxerStream::Type type);
-  void SetBufferStatus(DemuxerStream::Type type, BufferStatus status);
+  BufferingState GetBufferingState(DemuxerStream::Type type);
+  void SetBufferingState(DemuxerStream::Type type, BufferingState state);
   DemuxerStream* GetDemuxerStream(DemuxerStream::Type type) const;
   void SetDemuxerStream(DemuxerStream::Type type, DemuxerStream* stream);
   Queue& GetBufferQueue(DemuxerStream::Type type);
index f0c441d..b2d26bc 100644 (file)
@@ -17,6 +17,9 @@ MediaPlayerESPlusPlayerCommon::~MediaPlayerESPlusPlayerCommon() {
 }
 
 bool MediaPlayerESPlusPlayerCommon::SetBufferType() {
+  if (GetPlayerState() != ESPLUSPLAYER_STATE_IDLE)
+    return true;
+
   int error = esplusplayer_set_video_frame_buffer_type(
       esplayer_, ESPLUSPLAYER_DECODED_VIDEO_FRAME_BUFFER_TYPE_COPY);
   if (error != ESPLUSPLAYER_ERROR_TYPE_NONE) {
index cec7e28..868c6e5 100644 (file)
@@ -40,7 +40,7 @@ void MediaPlayerESPlusPlayerTV::PostPrepareComplete() {
 }
 
 int MediaPlayerESPlusPlayerTV::SetVideoStreamInfo(
-    media::VideoDecoderConfig& video_config,
+    const media::VideoDecoderConfig& video_config,
     esplusplayer_video_stream_info& video_stream_info) {
   MediaPlayerESPlusPlayer::SetVideoStreamInfo(video_config, video_stream_info);
   return 0;
@@ -113,4 +113,8 @@ void MediaPlayerESPlusPlayerTV::OnPrepareComplete(bool result) {
   return MediaPlayerESPlusPlayer::OnPrepareComplete(result);
 }
 
+void MediaPlayerESPlusPlayerTV::OnEos() {
+  MediaPlayerESPlusPlayer::OnEos();
+}
+
 }  // namespace media
index 3eed7ab..8939087 100644 (file)
@@ -26,6 +26,7 @@ class MEDIA_EXPORT MediaPlayerESPlusPlayerTV : public MediaPlayerESPlusPlayer {
 
   void OnVideoFrameDropped(const uint64_t dropped_count);
   void OnPrepareComplete(bool result) override;
+  void OnEos() override;
 
 #if defined(TIZEN_VIDEO_HOLE)
   void ToggleFullscreenMode(bool is_fullscreen) override {}
@@ -34,7 +35,7 @@ class MEDIA_EXPORT MediaPlayerESPlusPlayerTV : public MediaPlayerESPlusPlayer {
  protected:
   void PostPrepareComplete() override;
   int SetVideoStreamInfo(
-      media::VideoDecoderConfig& video_config,
+      const media::VideoDecoderConfig& video_config,
       esplusplayer_video_stream_info& video_stream_info) override;
   void SetAudioStreamInfo(
       const media::AudioDecoderConfig& audio_config,