| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 The Chromium Authors. 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 "webkit/glue/webmediaplayer_proxy.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/logging.h" | |
| 9 #include "base/message_loop.h" | |
| 10 #include "media/base/pipeline_status.h" | |
| 11 #include "media/filters/chunk_demuxer.h" | |
| 12 #include "webkit/glue/media/web_video_renderer.h" | |
| 13 #include "webkit/glue/webmediaplayer_impl.h" | |
| 14 | |
| 15 using media::PipelineStatus; | |
| 16 | |
| 17 namespace webkit_glue { | |
| 18 | |
| 19 // Limits the maximum outstanding repaints posted on render thread. | |
| 20 // This number of 50 is a guess, it does not take too much memory on the task | |
| 21 // queue but gives up a pretty good latency on repaint. | |
| 22 static const int kMaxOutstandingRepaints = 50; | |
| 23 | |
| 24 WebMediaPlayerProxy::WebMediaPlayerProxy(MessageLoop* render_loop, | |
| 25 WebMediaPlayerImpl* webmediaplayer) | |
| 26 : render_loop_(render_loop), | |
| 27 webmediaplayer_(webmediaplayer), | |
| 28 outstanding_repaints_(0) { | |
| 29 DCHECK(render_loop_); | |
| 30 DCHECK(webmediaplayer_); | |
| 31 } | |
| 32 | |
| 33 WebMediaPlayerProxy::~WebMediaPlayerProxy() { | |
| 34 Detach(); | |
| 35 } | |
| 36 | |
| 37 void WebMediaPlayerProxy::Repaint() { | |
| 38 base::AutoLock auto_lock(lock_); | |
| 39 if (outstanding_repaints_ < kMaxOutstandingRepaints) { | |
| 40 ++outstanding_repaints_; | |
| 41 | |
| 42 render_loop_->PostTask(FROM_HERE, | |
| 43 NewRunnableMethod(this, &WebMediaPlayerProxy::RepaintTask)); | |
| 44 } | |
| 45 } | |
| 46 | |
| 47 void WebMediaPlayerProxy::SetVideoRenderer( | |
| 48 scoped_refptr<WebVideoRenderer> video_renderer) { | |
| 49 video_renderer_ = video_renderer; | |
| 50 } | |
| 51 | |
| 52 WebDataSourceBuildObserverHack WebMediaPlayerProxy::GetBuildObserver() { | |
| 53 if (build_observer_.is_null()) | |
| 54 build_observer_ = base::Bind(&WebMediaPlayerProxy::AddDataSource, this); | |
| 55 return build_observer_; | |
| 56 } | |
| 57 | |
| 58 void WebMediaPlayerProxy::Paint(SkCanvas* canvas, const gfx::Rect& dest_rect) { | |
| 59 DCHECK(MessageLoop::current() == render_loop_); | |
| 60 if (video_renderer_) { | |
| 61 video_renderer_->Paint(canvas, dest_rect); | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 void WebMediaPlayerProxy::SetSize(const gfx::Rect& rect) { | |
| 66 DCHECK(MessageLoop::current() == render_loop_); | |
| 67 if (video_renderer_) { | |
| 68 video_renderer_->SetRect(rect); | |
| 69 } | |
| 70 } | |
| 71 | |
| 72 bool WebMediaPlayerProxy::HasSingleOrigin() { | |
| 73 DCHECK(MessageLoop::current() == render_loop_); | |
| 74 | |
| 75 base::AutoLock auto_lock(data_sources_lock_); | |
| 76 | |
| 77 for (DataSourceList::iterator itr = data_sources_.begin(); | |
| 78 itr != data_sources_.end(); | |
| 79 itr++) { | |
| 80 if (!(*itr)->HasSingleOrigin()) | |
| 81 return false; | |
| 82 } | |
| 83 return true; | |
| 84 } | |
| 85 | |
| 86 void WebMediaPlayerProxy::AbortDataSources() { | |
| 87 DCHECK(MessageLoop::current() == render_loop_); | |
| 88 base::AutoLock auto_lock(data_sources_lock_); | |
| 89 | |
| 90 for (DataSourceList::iterator itr = data_sources_.begin(); | |
| 91 itr != data_sources_.end(); | |
| 92 itr++) { | |
| 93 (*itr)->Abort(); | |
| 94 } | |
| 95 } | |
| 96 | |
| 97 void WebMediaPlayerProxy::Detach() { | |
| 98 DCHECK(MessageLoop::current() == render_loop_); | |
| 99 webmediaplayer_ = NULL; | |
| 100 video_renderer_ = NULL; | |
| 101 | |
| 102 { | |
| 103 base::AutoLock auto_lock(data_sources_lock_); | |
| 104 data_sources_.clear(); | |
| 105 } | |
| 106 } | |
| 107 | |
| 108 void WebMediaPlayerProxy::PipelineInitializationCallback( | |
| 109 PipelineStatus status) { | |
| 110 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( | |
| 111 this, &WebMediaPlayerProxy::PipelineInitializationTask, status)); | |
| 112 } | |
| 113 | |
| 114 void WebMediaPlayerProxy::PipelineSeekCallback(PipelineStatus status) { | |
| 115 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( | |
| 116 this, &WebMediaPlayerProxy::PipelineSeekTask, status)); | |
| 117 } | |
| 118 | |
| 119 void WebMediaPlayerProxy::PipelineEndedCallback(PipelineStatus status) { | |
| 120 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( | |
| 121 this, &WebMediaPlayerProxy::PipelineEndedTask, status)); | |
| 122 } | |
| 123 | |
| 124 void WebMediaPlayerProxy::PipelineErrorCallback(PipelineStatus error) { | |
| 125 DCHECK_NE(error, media::PIPELINE_OK); | |
| 126 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( | |
| 127 this, &WebMediaPlayerProxy::PipelineErrorTask, error)); | |
| 128 } | |
| 129 | |
| 130 void WebMediaPlayerProxy::NetworkEventCallback(bool is_downloading_data) { | |
| 131 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( | |
| 132 this, &WebMediaPlayerProxy::NetworkEventTask, is_downloading_data)); | |
| 133 } | |
| 134 | |
| 135 void WebMediaPlayerProxy::AddDataSource(WebDataSource* data_source) { | |
| 136 base::AutoLock auto_lock(data_sources_lock_); | |
| 137 data_sources_.push_back(make_scoped_refptr(data_source)); | |
| 138 } | |
| 139 | |
| 140 void WebMediaPlayerProxy::RepaintTask() { | |
| 141 DCHECK(MessageLoop::current() == render_loop_); | |
| 142 { | |
| 143 base::AutoLock auto_lock(lock_); | |
| 144 --outstanding_repaints_; | |
| 145 DCHECK_GE(outstanding_repaints_, 0); | |
| 146 } | |
| 147 if (webmediaplayer_) { | |
| 148 webmediaplayer_->Repaint(); | |
| 149 } | |
| 150 } | |
| 151 | |
| 152 void WebMediaPlayerProxy::PipelineInitializationTask(PipelineStatus status) { | |
| 153 DCHECK(MessageLoop::current() == render_loop_); | |
| 154 if (webmediaplayer_) | |
| 155 webmediaplayer_->OnPipelineInitialize(status); | |
| 156 } | |
| 157 | |
| 158 void WebMediaPlayerProxy::PipelineSeekTask(PipelineStatus status) { | |
| 159 DCHECK(MessageLoop::current() == render_loop_); | |
| 160 if (webmediaplayer_) | |
| 161 webmediaplayer_->OnPipelineSeek(status); | |
| 162 } | |
| 163 | |
| 164 void WebMediaPlayerProxy::PipelineEndedTask(PipelineStatus status) { | |
| 165 DCHECK(MessageLoop::current() == render_loop_); | |
| 166 if (webmediaplayer_) | |
| 167 webmediaplayer_->OnPipelineEnded(status); | |
| 168 } | |
| 169 | |
| 170 void WebMediaPlayerProxy::PipelineErrorTask(PipelineStatus error) { | |
| 171 DCHECK(MessageLoop::current() == render_loop_); | |
| 172 if (webmediaplayer_) | |
| 173 webmediaplayer_->OnPipelineError(error); | |
| 174 } | |
| 175 | |
| 176 void WebMediaPlayerProxy::NetworkEventTask(bool is_downloading_data) { | |
| 177 DCHECK(MessageLoop::current() == render_loop_); | |
| 178 if (webmediaplayer_) | |
| 179 webmediaplayer_->OnNetworkEvent(is_downloading_data); | |
| 180 } | |
| 181 | |
| 182 void WebMediaPlayerProxy::GetCurrentFrame( | |
| 183 scoped_refptr<media::VideoFrame>* frame_out) { | |
| 184 if (video_renderer_) | |
| 185 video_renderer_->GetCurrentFrame(frame_out); | |
| 186 } | |
| 187 | |
| 188 void WebMediaPlayerProxy::PutCurrentFrame( | |
| 189 scoped_refptr<media::VideoFrame> frame) { | |
| 190 if (video_renderer_) | |
| 191 video_renderer_->PutCurrentFrame(frame); | |
| 192 } | |
| 193 | |
| 194 void WebMediaPlayerProxy::DemuxerOpened(media::ChunkDemuxer* demuxer) { | |
| 195 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( | |
| 196 this, &WebMediaPlayerProxy::DemuxerOpenedTask, | |
| 197 scoped_refptr<media::ChunkDemuxer>(demuxer))); | |
| 198 } | |
| 199 | |
| 200 void WebMediaPlayerProxy::DemuxerClosed() { | |
| 201 render_loop_->PostTask(FROM_HERE, NewRunnableMethod( | |
| 202 this, &WebMediaPlayerProxy::DemuxerClosedTask)); | |
| 203 } | |
| 204 | |
| 205 void WebMediaPlayerProxy::DemuxerFlush() { | |
| 206 if (chunk_demuxer_.get()) | |
| 207 chunk_demuxer_->FlushData(); | |
| 208 } | |
| 209 | |
| 210 bool WebMediaPlayerProxy::DemuxerAppend(const uint8* data, size_t length) { | |
| 211 if (chunk_demuxer_.get()) | |
| 212 return chunk_demuxer_->AppendData(data, length); | |
| 213 return false; | |
| 214 } | |
| 215 | |
| 216 void WebMediaPlayerProxy::DemuxerEndOfStream(media::PipelineStatus status) { | |
| 217 if (chunk_demuxer_.get()) | |
| 218 chunk_demuxer_->EndOfStream(status); | |
| 219 } | |
| 220 | |
| 221 void WebMediaPlayerProxy::DemuxerShutdown() { | |
| 222 if (chunk_demuxer_.get()) | |
| 223 chunk_demuxer_->Shutdown(); | |
| 224 } | |
| 225 | |
| 226 void WebMediaPlayerProxy::DemuxerOpenedTask( | |
| 227 const scoped_refptr<media::ChunkDemuxer>& demuxer) { | |
| 228 DCHECK(MessageLoop::current() == render_loop_); | |
| 229 chunk_demuxer_ = demuxer; | |
| 230 if (webmediaplayer_) | |
| 231 webmediaplayer_->OnDemuxerOpened(); | |
| 232 } | |
| 233 | |
| 234 void WebMediaPlayerProxy::DemuxerClosedTask() { | |
| 235 chunk_demuxer_ = NULL; | |
| 236 } | |
| 237 | |
| 238 } // namespace webkit_glue | |
| OLD | NEW |