| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/blink/video_frame_compositor.h" | 5 #include "media/blink/video_frame_compositor.h" |
| 6 | 6 |
| 7 #include "base/bind.h" |
| 8 #include "base/message_loop/message_loop.h" |
| 7 #include "media/base/video_frame.h" | 9 #include "media/base/video_frame.h" |
| 8 | 10 |
| 9 namespace media { | 11 namespace media { |
| 10 | 12 |
| 11 static bool IsOpaque(const scoped_refptr<VideoFrame>& frame) { | 13 static bool IsOpaque(const scoped_refptr<VideoFrame>& frame) { |
| 12 switch (frame->format()) { | 14 switch (frame->format()) { |
| 13 case VideoFrame::UNKNOWN: | 15 case VideoFrame::UNKNOWN: |
| 14 case VideoFrame::YV12: | 16 case VideoFrame::YV12: |
| 15 case VideoFrame::YV12J: | 17 case VideoFrame::YV12J: |
| 16 case VideoFrame::YV12HD: | 18 case VideoFrame::YV12HD: |
| 17 case VideoFrame::YV16: | 19 case VideoFrame::YV16: |
| 18 case VideoFrame::I420: | 20 case VideoFrame::I420: |
| 19 case VideoFrame::YV24: | 21 case VideoFrame::YV24: |
| 20 case VideoFrame::NV12: | 22 case VideoFrame::NV12: |
| 21 return true; | 23 return true; |
| 22 | 24 |
| 23 case VideoFrame::YV12A: | 25 case VideoFrame::YV12A: |
| 24 #if defined(VIDEO_HOLE) | 26 #if defined(VIDEO_HOLE) |
| 25 case VideoFrame::HOLE: | 27 case VideoFrame::HOLE: |
| 26 #endif // defined(VIDEO_HOLE) | 28 #endif // defined(VIDEO_HOLE) |
| 27 case VideoFrame::NATIVE_TEXTURE: | 29 case VideoFrame::NATIVE_TEXTURE: |
| 28 case VideoFrame::ARGB: | 30 case VideoFrame::ARGB: |
| 29 break; | 31 break; |
| 30 } | 32 } |
| 31 return false; | 33 return false; |
| 32 } | 34 } |
| 33 | 35 |
| 34 VideoFrameCompositor::VideoFrameCompositor( | 36 VideoFrameCompositor::VideoFrameCompositor( |
| 37 const scoped_refptr<base::SingleThreadTaskRunner>& compositor_task_runner, |
| 35 const base::Callback<void(gfx::Size)>& natural_size_changed_cb, | 38 const base::Callback<void(gfx::Size)>& natural_size_changed_cb, |
| 36 const base::Callback<void(bool)>& opacity_changed_cb) | 39 const base::Callback<void(bool)>& opacity_changed_cb) |
| 37 : natural_size_changed_cb_(natural_size_changed_cb), | 40 : compositor_task_runner_(compositor_task_runner), |
| 41 natural_size_changed_cb_(natural_size_changed_cb), |
| 38 opacity_changed_cb_(opacity_changed_cb), | 42 opacity_changed_cb_(opacity_changed_cb), |
| 39 client_(NULL) { | 43 client_(nullptr), |
| 44 callback_(nullptr), |
| 45 rendering_(false) { |
| 40 } | 46 } |
| 41 | 47 |
| 42 VideoFrameCompositor::~VideoFrameCompositor() { | 48 VideoFrameCompositor::~VideoFrameCompositor() { |
| 49 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); |
| 50 DCHECK(!callback_); |
| 51 DCHECK(!rendering_); |
| 43 if (client_) | 52 if (client_) |
| 44 client_->StopUsingProvider(); | 53 client_->StopUsingProvider(); |
| 45 } | 54 } |
| 46 | 55 |
| 56 void VideoFrameCompositor::StartRendering() { |
| 57 if (!compositor_task_runner_->BelongsToCurrentThread()) { |
| 58 compositor_task_runner_->PostTask( |
| 59 FROM_HERE, base::Bind(&VideoFrameCompositor::StartRendering, |
| 60 base::Unretained(this))); |
| 61 return; |
| 62 } |
| 63 |
| 64 base::AutoLock lock(lock_); |
| 65 if (client_ && !rendering_ && callback_) |
| 66 client_->StartRendering(); |
| 67 rendering_ = true; |
| 68 } |
| 69 |
| 70 void VideoFrameCompositor::OnRendererStateUpdate() { |
| 71 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); |
| 72 if (!client_) |
| 73 return; |
| 74 |
| 75 base::AutoLock lock(lock_); |
| 76 if (callback_) { |
| 77 if (rendering_) |
| 78 client_->StartRendering(); |
| 79 |
| 80 // TODO(dalecurtis): This will need to request the first frame so we have |
| 81 // something to show, even if playback hasn't started yet. |
| 82 } else if (rendering_) { |
| 83 client_->StopRendering(); |
| 84 } |
| 85 } |
| 86 |
| 87 void VideoFrameCompositor::StopRendering() { |
| 88 if (!compositor_task_runner_->BelongsToCurrentThread()) { |
| 89 compositor_task_runner_->PostTask( |
| 90 FROM_HERE, base::Bind(&VideoFrameCompositor::StopRendering, |
| 91 base::Unretained(this))); |
| 92 return; |
| 93 } |
| 94 |
| 95 if (client_ && rendering_) |
| 96 client_->StopRendering(); |
| 97 rendering_ = false; |
| 98 } |
| 99 |
| 47 void VideoFrameCompositor::SetVideoFrameProviderClient( | 100 void VideoFrameCompositor::SetVideoFrameProviderClient( |
| 48 cc::VideoFrameProvider::Client* client) { | 101 cc::VideoFrameProvider::Client* client) { |
| 102 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); |
| 49 if (client_) | 103 if (client_) |
| 50 client_->StopUsingProvider(); | 104 client_->StopUsingProvider(); |
| 51 client_ = client; | 105 client_ = client; |
| 106 OnRendererStateUpdate(); |
| 52 } | 107 } |
| 53 | 108 |
| 54 scoped_refptr<VideoFrame> VideoFrameCompositor::GetCurrentFrame() { | 109 scoped_refptr<VideoFrame> VideoFrameCompositor::GetCurrentFrame() { |
| 110 base::AutoLock lock(lock_); |
| 55 return current_frame_; | 111 return current_frame_; |
| 56 } | 112 } |
| 57 | 113 |
| 58 void VideoFrameCompositor::PutCurrentFrame( | 114 void VideoFrameCompositor::PutCurrentFrame() { |
| 59 const scoped_refptr<VideoFrame>& frame) { | 115 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); |
| 116 // TODO(dalecurtis): Wire up a flag for RenderCallback::OnFrameDropped(). |
| 60 } | 117 } |
| 61 | 118 |
| 62 void VideoFrameCompositor::UpdateCurrentFrame( | 119 void VideoFrameCompositor::SetVisible(bool visible) { |
| 120 DCHECK(compositor_task_runner_->BelongsToCurrentThread()); |
| 121 // TODO(dalecurtis): Schedule intermittent render callbacks when visilibity is |
| 122 // turned off. Perhaps once every 100ms? |
| 123 } |
| 124 |
| 125 bool VideoFrameCompositor::Render(base::TimeTicks deadline_min, |
| 126 base::TimeTicks deadline_max) { |
| 127 // TODO(dalecurtis): Wire this up to RenderCallback::Render(). |
| 128 base::AutoLock lock(lock_); |
| 129 return false; |
| 130 } |
| 131 |
| 132 void VideoFrameCompositor::Start(RenderCallback* callback) { |
| 133 NOTREACHED(); |
| 134 |
| 135 // Called from the media thread. |
| 136 base::AutoLock lock(lock_); |
| 137 callback_ = callback; |
| 138 compositor_task_runner_->PostTask( |
| 139 FROM_HERE, base::Bind(&VideoFrameCompositor::OnRendererStateUpdate, |
| 140 base::Unretained(this))); |
| 141 } |
| 142 |
| 143 void VideoFrameCompositor::Stop() { |
| 144 NOTREACHED(); |
| 145 |
| 146 base::AutoLock lock(lock_); |
| 147 callback_ = nullptr; |
| 148 compositor_task_runner_->PostTask( |
| 149 FROM_HERE, base::Bind(&VideoFrameCompositor::OnRendererStateUpdate, |
| 150 base::Unretained(this))); |
| 151 } |
| 152 |
| 153 void VideoFrameCompositor::PaintFrameUsingOldRenderingPath( |
| 63 const scoped_refptr<VideoFrame>& frame) { | 154 const scoped_refptr<VideoFrame>& frame) { |
| 155 if (!compositor_task_runner_->BelongsToCurrentThread()) { |
| 156 compositor_task_runner_->PostTask( |
| 157 FROM_HERE, |
| 158 base::Bind(&VideoFrameCompositor::PaintFrameUsingOldRenderingPath, |
| 159 base::Unretained(this), frame)); |
| 160 return; |
| 161 } |
| 162 |
| 64 if (current_frame_.get() && | 163 if (current_frame_.get() && |
| 65 current_frame_->natural_size() != frame->natural_size()) { | 164 current_frame_->natural_size() != frame->natural_size()) { |
| 66 natural_size_changed_cb_.Run(frame->natural_size()); | 165 natural_size_changed_cb_.Run(frame->natural_size()); |
| 67 } | 166 } |
| 68 | 167 |
| 69 if (!current_frame_.get() || IsOpaque(current_frame_) != IsOpaque(frame)) { | 168 if (!current_frame_.get() || IsOpaque(current_frame_) != IsOpaque(frame)) { |
| 70 opacity_changed_cb_.Run(IsOpaque(frame)); | 169 opacity_changed_cb_.Run(IsOpaque(frame)); |
| 71 } | 170 } |
| 72 | 171 |
| 73 current_frame_ = frame; | 172 current_frame_ = frame; |
| 74 | 173 |
| 75 if (client_) | 174 if (client_) |
| 76 client_->DidReceiveFrame(); | 175 client_->DidReceiveFrame(); |
| 77 } | 176 } |
| 78 | 177 |
| 79 } // namespace media | 178 } // namespace media |
| OLD | NEW |