Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / media / filters / video_renderer_impl.cc
index 3b9851f..b86f661 100644 (file)
 
 namespace media {
 
-base::TimeDelta VideoRendererImpl::kMaxLastFrameDuration() {
-  return base::TimeDelta::FromMilliseconds(250);
-}
-
 VideoRendererImpl::VideoRendererImpl(
     const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
     ScopedVector<VideoDecoder> decoders,
     const SetDecryptorReadyCB& set_decryptor_ready_cb,
     const PaintCB& paint_cb,
-    const SetOpaqueCB& set_opaque_cb,
     bool drop_frames)
     : task_runner_(task_runner),
       video_frame_stream_(task_runner, decoders.Pass(), set_decryptor_ready_cb),
+      low_delay_(false),
       received_end_of_stream_(false),
+      rendered_end_of_stream_(false),
       frame_available_(&lock_),
       state_(kUninitialized),
       thread_(),
@@ -39,7 +36,6 @@ VideoRendererImpl::VideoRendererImpl(
       drop_frames_(drop_frames),
       playback_rate_(0),
       paint_cb_(paint_cb),
-      set_opaque_cb_(set_opaque_cb),
       last_timestamp_(kNoTimestamp()),
       frames_decoded_(0),
       frames_dropped_(0),
@@ -80,6 +76,7 @@ void VideoRendererImpl::Flush(const base::Closure& callback) {
   // stream and needs to drain it before flushing it.
   ready_frames_.clear();
   received_end_of_stream_ = false;
+  rendered_end_of_stream_ = false;
   video_frame_stream_.Reset(
       base::Bind(&VideoRendererImpl::OnVideoFrameStreamResetDone,
                  weak_factory_.GetWeakPtr()));
@@ -154,6 +151,7 @@ void VideoRendererImpl::Preroll(base::TimeDelta time,
 }
 
 void VideoRendererImpl::Initialize(DemuxerStream* stream,
+                                   bool low_delay,
                                    const PipelineStatusCB& init_cb,
                                    const StatisticsCB& statistics_cb,
                                    const TimeCB& max_time_cb,
@@ -173,6 +171,8 @@ void VideoRendererImpl::Initialize(DemuxerStream* stream,
   DCHECK(!get_duration_cb.is_null());
   DCHECK_EQ(kUninitialized, state_);
 
+  low_delay_ = low_delay;
+
   init_cb_ = init_cb;
   statistics_cb_ = statistics_cb;
   max_time_cb_ = max_time_cb;
@@ -184,13 +184,13 @@ void VideoRendererImpl::Initialize(DemuxerStream* stream,
 
   video_frame_stream_.Initialize(
       stream,
+      low_delay,
       statistics_cb,
       base::Bind(&VideoRendererImpl::OnVideoFrameStreamInitialized,
                  weak_factory_.GetWeakPtr()));
 }
 
-void VideoRendererImpl::OnVideoFrameStreamInitialized(bool success,
-                                                      bool has_alpha) {
+void VideoRendererImpl::OnVideoFrameStreamInitialized(bool success) {
   DCHECK(task_runner_->BelongsToCurrentThread());
   base::AutoLock auto_lock(lock_);
 
@@ -211,9 +211,6 @@ void VideoRendererImpl::OnVideoFrameStreamInitialized(bool success,
   // have not populated any buffers yet.
   state_ = kFlushed;
 
-  set_opaque_cb_.Run(!has_alpha);
-  set_opaque_cb_.Reset();
-
   // Create our video thread.
   if (!base::PlatformThread::Create(0, this, &thread_)) {
     NOTREACHED() << "Video thread creation failed";
@@ -258,12 +255,9 @@ void VideoRendererImpl::ThreadMain() {
 
     // Remain idle until we have the next frame ready for rendering.
     if (ready_frames_.empty()) {
-      if (received_end_of_stream_) {
-        state_ = kEnded;
+      if (received_end_of_stream_ && !rendered_end_of_stream_) {
+        rendered_end_of_stream_ = true;
         ended_cb_.Run();
-
-        // No need to sleep here as we idle when |state_ != kPlaying|.
-        continue;
       }
 
       UpdateStatsAndWait_Locked(kIdleTimeDelta);
@@ -294,8 +288,8 @@ void VideoRendererImpl::ThreadMain() {
     // the accuracy of our frame timing code. http://crbug.com/149829
     if (drop_frames_ && last_timestamp_ != kNoTimestamp()) {
       base::TimeDelta now = get_time_cb_.Run();
-      base::TimeDelta deadline = ready_frames_.front()->GetTimestamp() +
-          (ready_frames_.front()->GetTimestamp() - last_timestamp_) / 2;
+      base::TimeDelta deadline = ready_frames_.front()->timestamp() +
+          (ready_frames_.front()->timestamp() - last_timestamp_) / 2;
 
       if (now > deadline) {
         DropNextReadyFrame_Locked();
@@ -318,7 +312,7 @@ void VideoRendererImpl::PaintNextReadyFrame_Locked() {
   ready_frames_.pop_front();
   frames_decoded_++;
 
-  last_timestamp_ = next_frame->GetTimestamp();
+  last_timestamp_ = next_frame->timestamp();
 
   paint_cb_.Run(next_frame);
 
@@ -332,7 +326,7 @@ void VideoRendererImpl::DropNextReadyFrame_Locked() {
 
   lock_.AssertAcquired();
 
-  last_timestamp_ = ready_frames_.front()->GetTimestamp();
+  last_timestamp_ = ready_frames_.front()->timestamp();
   ready_frames_.pop_front();
   frames_decoded_++;
   frames_dropped_++;
@@ -396,7 +390,7 @@ void VideoRendererImpl::FrameReady(VideoFrameStream::Status status,
   // Maintain the latest frame decoded so the correct frame is displayed after
   // prerolling has completed.
   if (state_ == kPrerolling && preroll_timestamp_ != kNoTimestamp() &&
-      frame->GetTimestamp() <= preroll_timestamp_) {
+      frame->timestamp() <= preroll_timestamp_) {
     ready_frames_.clear();
   }
 
@@ -415,7 +409,8 @@ void VideoRendererImpl::FrameReady(VideoFrameStream::Status status,
 bool VideoRendererImpl::ShouldTransitionToPrerolled_Locked() {
   return state_ == kPrerolling &&
       (!video_frame_stream_.CanReadWithoutStalling() ||
-       ready_frames_.size() >= static_cast<size_t>(limits::kMaxVideoFrames));
+       ready_frames_.size() >= static_cast<size_t>(limits::kMaxVideoFrames) ||
+       (low_delay_ && ready_frames_.size() > 0));
 }
 
 void VideoRendererImpl::AddReadyFrame_Locked(
@@ -429,15 +424,15 @@ void VideoRendererImpl::AddReadyFrame_Locked(
   // frame rate.  Another way for this to happen is for the container to state
   // a smaller duration than the largest packet timestamp.
   base::TimeDelta duration = get_duration_cb_.Run();
-  if (frame->GetTimestamp() > duration) {
-    frame->SetTimestamp(duration);
+  if (frame->timestamp() > duration) {
+    frame->set_timestamp(duration);
   }
 
   ready_frames_.push_back(frame);
   DCHECK_LE(ready_frames_.size(),
             static_cast<size_t>(limits::kMaxVideoFrames));
 
-  max_time_cb_.Run(frame->GetTimestamp());
+  max_time_cb_.Run(frame->timestamp());
 
   // Avoid needlessly waking up |thread_| unless playing.
   if (state_ == kPlaying)
@@ -461,6 +456,7 @@ void VideoRendererImpl::AttemptRead_Locked() {
   switch (state_) {
     case kPaused:
     case kPrerolling:
+    case kPrerolled:
     case kPlaying:
       pending_read_ = true;
       video_frame_stream_.Read(base::Bind(&VideoRendererImpl::FrameReady,
@@ -469,10 +465,8 @@ void VideoRendererImpl::AttemptRead_Locked() {
 
     case kUninitialized:
     case kInitializing:
-    case kPrerolled:
     case kFlushing:
     case kFlushed:
-    case kEnded:
     case kStopped:
     case kError:
       return;
@@ -488,6 +482,7 @@ void VideoRendererImpl::OnVideoFrameStreamResetDone() {
   DCHECK(!pending_read_);
   DCHECK(ready_frames_.empty());
   DCHECK(!received_end_of_stream_);
+  DCHECK(!rendered_end_of_stream_);
 
   state_ = kFlushed;
   last_timestamp_ = kNoTimestamp();
@@ -499,7 +494,7 @@ base::TimeDelta VideoRendererImpl::CalculateSleepDuration(
     float playback_rate) {
   // Determine the current and next presentation timestamps.
   base::TimeDelta now = get_time_cb_.Run();
-  base::TimeDelta next_pts = next_frame->GetTimestamp();
+  base::TimeDelta next_pts = next_frame->timestamp();
 
   // Scale our sleep based on the playback rate.
   base::TimeDelta sleep = next_pts - now;