| OLD | NEW |
| 1 // Copyright (c) 2008-2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2008-2009 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 "webkit/glue/webmediaplayer_impl.h" | 5 #include "webkit/glue/webmediaplayer_impl.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "googleurl/src/gurl.h" | 8 #include "googleurl/src/gurl.h" |
| 9 #include "media/filters/ffmpeg_audio_decoder.h" | 9 #include "media/filters/ffmpeg_audio_decoder.h" |
| 10 #include "media/filters/ffmpeg_demuxer.h" | 10 #include "media/filters/ffmpeg_demuxer.h" |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 | 136 |
| 137 void WebMediaPlayerImpl::Proxy::PipelineInitializationCallback(bool success) { | 137 void WebMediaPlayerImpl::Proxy::PipelineInitializationCallback(bool success) { |
| 138 if (success) { | 138 if (success) { |
| 139 // Since we have initialized the pipeline, say we have everything. | 139 // Since we have initialized the pipeline, say we have everything. |
| 140 // TODO(hclam): change this to report the correct status. Should also post | 140 // TODO(hclam): change this to report the correct status. Should also post |
| 141 // a task to call to |webmediaplayer_|. | 141 // a task to call to |webmediaplayer_|. |
| 142 ReadyStateChanged(WebKit::WebMediaPlayer::HaveMetadata); | 142 ReadyStateChanged(WebKit::WebMediaPlayer::HaveMetadata); |
| 143 ReadyStateChanged(WebKit::WebMediaPlayer::HaveEnoughData); | 143 ReadyStateChanged(WebKit::WebMediaPlayer::HaveEnoughData); |
| 144 NetworkStateChanged(WebKit::WebMediaPlayer::Loaded); | 144 NetworkStateChanged(WebKit::WebMediaPlayer::Loaded); |
| 145 } else { | 145 } else { |
| 146 // TODO(hclam): should use pipeline_->GetError() to determine the state | 146 // TODO(hclam): should use pipeline_.GetError() to determine the state |
| 147 // properly and reports error using MediaError. | 147 // properly and reports error using MediaError. |
| 148 // WebKit uses FormatError to indicate an error for bogus URL or bad file. | 148 // WebKit uses FormatError to indicate an error for bogus URL or bad file. |
| 149 // Since we are at the initialization stage we can safely treat every error | 149 // Since we are at the initialization stage we can safely treat every error |
| 150 // as format error. Should post a task to call to |webmediaplayer_|. | 150 // as format error. Should post a task to call to |webmediaplayer_|. |
| 151 NetworkStateChanged(WebKit::WebMediaPlayer::FormatError); | 151 NetworkStateChanged(WebKit::WebMediaPlayer::FormatError); |
| 152 } | 152 } |
| 153 } | 153 } |
| 154 | 154 |
| 155 void WebMediaPlayerImpl::Proxy::PipelineSeekCallback(bool success) { | 155 void WebMediaPlayerImpl::Proxy::PipelineSeekCallback(bool success) { |
| 156 if (success) | 156 if (success) |
| 157 TimeChanged(); | 157 TimeChanged(); |
| 158 } | 158 } |
| 159 | 159 |
| 160 ///////////////////////////////////////////////////////////////////////////// | 160 ///////////////////////////////////////////////////////////////////////////// |
| 161 // WebMediaPlayerImpl implementation | 161 // WebMediaPlayerImpl implementation |
| 162 | 162 |
| 163 WebMediaPlayerImpl::WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client, | 163 WebMediaPlayerImpl::WebMediaPlayerImpl(WebKit::WebMediaPlayerClient* client, |
| 164 media::FilterFactoryCollection* factory) | 164 media::FilterFactoryCollection* factory) |
| 165 : network_state_(WebKit::WebMediaPlayer::Empty), | 165 : network_state_(WebKit::WebMediaPlayer::Empty), |
| 166 ready_state_(WebKit::WebMediaPlayer::HaveNothing), | 166 ready_state_(WebKit::WebMediaPlayer::HaveNothing), |
| 167 main_loop_(NULL), | 167 main_loop_(NULL), |
| 168 filter_factory_(factory), | 168 filter_factory_(factory), |
| 169 pipeline_thread_("PipelineThread"), | |
| 170 client_(client) { | 169 client_(client) { |
| 171 // Saves the current message loop. | 170 // Saves the current message loop. |
| 172 DCHECK(!main_loop_); | 171 DCHECK(!main_loop_); |
| 173 main_loop_ = MessageLoop::current(); | 172 main_loop_ = MessageLoop::current(); |
| 174 | 173 |
| 175 // Create the pipeline and its thread. | |
| 176 if (!pipeline_thread_.Start()) { | |
| 177 NOTREACHED() << "Could not start PipelineThread"; | |
| 178 } else { | |
| 179 pipeline_.reset(new media::PipelineImpl(pipeline_thread_.message_loop())); | |
| 180 } | |
| 181 | |
| 182 // Also we want to be notified of |main_loop_| destruction. | 174 // Also we want to be notified of |main_loop_| destruction. |
| 183 main_loop_->AddDestructionObserver(this); | 175 main_loop_->AddDestructionObserver(this); |
| 184 | 176 |
| 185 // Creates the proxy. | 177 // Creates the proxy. |
| 186 proxy_ = new Proxy(main_loop_, this); | 178 proxy_ = new Proxy(main_loop_, this); |
| 187 | 179 |
| 188 // Add in the default filter factories. | 180 // Add in the default filter factories. |
| 189 filter_factory_->AddFactory(media::FFmpegDemuxer::CreateFilterFactory()); | 181 filter_factory_->AddFactory(media::FFmpegDemuxer::CreateFilterFactory()); |
| 190 filter_factory_->AddFactory(media::FFmpegAudioDecoder::CreateFactory()); | 182 filter_factory_->AddFactory(media::FFmpegAudioDecoder::CreateFactory()); |
| 191 filter_factory_->AddFactory(media::FFmpegVideoDecoder::CreateFactory()); | 183 filter_factory_->AddFactory(media::FFmpegVideoDecoder::CreateFactory()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 203 } | 195 } |
| 204 } | 196 } |
| 205 | 197 |
| 206 void WebMediaPlayerImpl::load(const WebKit::WebURL& url) { | 198 void WebMediaPlayerImpl::load(const WebKit::WebURL& url) { |
| 207 DCHECK(MessageLoop::current() == main_loop_); | 199 DCHECK(MessageLoop::current() == main_loop_); |
| 208 DCHECK(proxy_); | 200 DCHECK(proxy_); |
| 209 | 201 |
| 210 // Initialize the pipeline. | 202 // Initialize the pipeline. |
| 211 SetNetworkState(WebKit::WebMediaPlayer::Loading); | 203 SetNetworkState(WebKit::WebMediaPlayer::Loading); |
| 212 SetReadyState(WebKit::WebMediaPlayer::HaveNothing); | 204 SetReadyState(WebKit::WebMediaPlayer::HaveNothing); |
| 213 pipeline_->Start( | 205 pipeline_.Start( |
| 214 filter_factory_.get(), | 206 filter_factory_.get(), |
| 215 url.spec(), | 207 url.spec(), |
| 216 NewCallback(proxy_.get(), | 208 NewCallback(proxy_.get(), |
| 217 &WebMediaPlayerImpl::Proxy::PipelineInitializationCallback)); | 209 &WebMediaPlayerImpl::Proxy::PipelineInitializationCallback)); |
| 218 } | 210 } |
| 219 | 211 |
| 220 void WebMediaPlayerImpl::cancelLoad() { | 212 void WebMediaPlayerImpl::cancelLoad() { |
| 221 DCHECK(MessageLoop::current() == main_loop_); | 213 DCHECK(MessageLoop::current() == main_loop_); |
| 222 } | 214 } |
| 223 | 215 |
| 224 void WebMediaPlayerImpl::play() { | 216 void WebMediaPlayerImpl::play() { |
| 225 DCHECK(MessageLoop::current() == main_loop_); | 217 DCHECK(MessageLoop::current() == main_loop_); |
| 226 | 218 |
| 227 // TODO(hclam): We should restore the previous playback rate rather than | 219 // TODO(hclam): We should restore the previous playback rate rather than |
| 228 // having it at 1.0. | 220 // having it at 1.0. |
| 229 pipeline_->SetPlaybackRate(1.0f); | 221 pipeline_.SetPlaybackRate(1.0f); |
| 230 } | 222 } |
| 231 | 223 |
| 232 void WebMediaPlayerImpl::pause() { | 224 void WebMediaPlayerImpl::pause() { |
| 233 DCHECK(MessageLoop::current() == main_loop_); | 225 DCHECK(MessageLoop::current() == main_loop_); |
| 234 | 226 |
| 235 pipeline_->SetPlaybackRate(0.0f); | 227 pipeline_.SetPlaybackRate(0.0f); |
| 236 } | 228 } |
| 237 | 229 |
| 238 void WebMediaPlayerImpl::seek(float seconds) { | 230 void WebMediaPlayerImpl::seek(float seconds) { |
| 239 DCHECK(MessageLoop::current() == main_loop_); | 231 DCHECK(MessageLoop::current() == main_loop_); |
| 240 | 232 |
| 241 // Try to preserve as much accuracy as possible. | 233 // Try to preserve as much accuracy as possible. |
| 242 float microseconds = seconds * base::Time::kMicrosecondsPerSecond; | 234 float microseconds = seconds * base::Time::kMicrosecondsPerSecond; |
| 243 if (seconds != 0) | 235 if (seconds != 0) |
| 244 pipeline_->Seek( | 236 pipeline_.Seek( |
| 245 base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds)), | 237 base::TimeDelta::FromMicroseconds(static_cast<int64>(microseconds)), |
| 246 NewCallback(proxy_.get(), | 238 NewCallback(proxy_.get(), |
| 247 &WebMediaPlayerImpl::Proxy::PipelineSeekCallback)); | 239 &WebMediaPlayerImpl::Proxy::PipelineSeekCallback)); |
| 248 } | 240 } |
| 249 | 241 |
| 250 void WebMediaPlayerImpl::setEndTime(float seconds) { | 242 void WebMediaPlayerImpl::setEndTime(float seconds) { |
| 251 DCHECK(MessageLoop::current() == main_loop_); | 243 DCHECK(MessageLoop::current() == main_loop_); |
| 252 | 244 |
| 253 // TODO(hclam): add method call when it has been implemented. | 245 // TODO(hclam): add method call when it has been implemented. |
| 254 return; | 246 return; |
| 255 } | 247 } |
| 256 | 248 |
| 257 void WebMediaPlayerImpl::setRate(float rate) { | 249 void WebMediaPlayerImpl::setRate(float rate) { |
| 258 DCHECK(MessageLoop::current() == main_loop_); | 250 DCHECK(MessageLoop::current() == main_loop_); |
| 259 | 251 |
| 260 pipeline_->SetPlaybackRate(rate); | 252 pipeline_.SetPlaybackRate(rate); |
| 261 } | 253 } |
| 262 | 254 |
| 263 void WebMediaPlayerImpl::setVolume(float volume) { | 255 void WebMediaPlayerImpl::setVolume(float volume) { |
| 264 DCHECK(MessageLoop::current() == main_loop_); | 256 DCHECK(MessageLoop::current() == main_loop_); |
| 265 | 257 |
| 266 pipeline_->SetVolume(volume); | 258 pipeline_.SetVolume(volume); |
| 267 } | 259 } |
| 268 | 260 |
| 269 void WebMediaPlayerImpl::setVisible(bool visible) { | 261 void WebMediaPlayerImpl::setVisible(bool visible) { |
| 270 DCHECK(MessageLoop::current() == main_loop_); | 262 DCHECK(MessageLoop::current() == main_loop_); |
| 271 | 263 |
| 272 // TODO(hclam): add appropriate method call when pipeline has it implemented. | 264 // TODO(hclam): add appropriate method call when pipeline has it implemented. |
| 273 return; | 265 return; |
| 274 } | 266 } |
| 275 | 267 |
| 276 bool WebMediaPlayerImpl::setAutoBuffer(bool autoBuffer) { | 268 bool WebMediaPlayerImpl::setAutoBuffer(bool autoBuffer) { |
| 277 DCHECK(MessageLoop::current() == main_loop_); | 269 DCHECK(MessageLoop::current() == main_loop_); |
| 278 | 270 |
| 279 return false; | 271 return false; |
| 280 } | 272 } |
| 281 | 273 |
| 282 bool WebMediaPlayerImpl::totalBytesKnown() { | 274 bool WebMediaPlayerImpl::totalBytesKnown() { |
| 283 DCHECK(MessageLoop::current() == main_loop_); | 275 DCHECK(MessageLoop::current() == main_loop_); |
| 284 | 276 |
| 285 return pipeline_->GetTotalBytes() != 0; | 277 return pipeline_.GetTotalBytes() != 0; |
| 286 } | 278 } |
| 287 | 279 |
| 288 bool WebMediaPlayerImpl::hasVideo() const { | 280 bool WebMediaPlayerImpl::hasVideo() const { |
| 289 DCHECK(MessageLoop::current() == main_loop_); | 281 DCHECK(MessageLoop::current() == main_loop_); |
| 290 | 282 |
| 291 size_t width, height; | 283 size_t width, height; |
| 292 pipeline_->GetVideoSize(&width, &height); | 284 pipeline_.GetVideoSize(&width, &height); |
| 293 return width != 0 && height != 0; | 285 return width != 0 && height != 0; |
| 294 } | 286 } |
| 295 | 287 |
| 296 WebKit::WebSize WebMediaPlayerImpl::naturalSize() const { | 288 WebKit::WebSize WebMediaPlayerImpl::naturalSize() const { |
| 297 DCHECK(MessageLoop::current() == main_loop_); | 289 DCHECK(MessageLoop::current() == main_loop_); |
| 298 | 290 |
| 299 size_t width, height; | 291 size_t width, height; |
| 300 pipeline_->GetVideoSize(&width, &height); | 292 pipeline_.GetVideoSize(&width, &height); |
| 301 return WebKit::WebSize(width, height); | 293 return WebKit::WebSize(width, height); |
| 302 } | 294 } |
| 303 | 295 |
| 304 bool WebMediaPlayerImpl::paused() const { | 296 bool WebMediaPlayerImpl::paused() const { |
| 305 DCHECK(MessageLoop::current() == main_loop_); | 297 DCHECK(MessageLoop::current() == main_loop_); |
| 306 | 298 |
| 307 return pipeline_->GetPlaybackRate() == 0.0f; | 299 return pipeline_.GetPlaybackRate() == 0.0f; |
| 308 } | 300 } |
| 309 | 301 |
| 310 bool WebMediaPlayerImpl::seeking() const { | 302 bool WebMediaPlayerImpl::seeking() const { |
| 311 DCHECK(MessageLoop::current() == main_loop_); | 303 DCHECK(MessageLoop::current() == main_loop_); |
| 312 | 304 |
| 313 return false; | 305 return false; |
| 314 } | 306 } |
| 315 | 307 |
| 316 float WebMediaPlayerImpl::duration() const { | 308 float WebMediaPlayerImpl::duration() const { |
| 317 DCHECK(MessageLoop::current() == main_loop_); | 309 DCHECK(MessageLoop::current() == main_loop_); |
| 318 | 310 |
| 319 return static_cast<float>(pipeline_->GetDuration().InSecondsF()); | 311 return static_cast<float>(pipeline_.GetDuration().InSecondsF()); |
| 320 } | 312 } |
| 321 | 313 |
| 322 float WebMediaPlayerImpl::currentTime() const { | 314 float WebMediaPlayerImpl::currentTime() const { |
| 323 DCHECK(MessageLoop::current() == main_loop_); | 315 DCHECK(MessageLoop::current() == main_loop_); |
| 324 | 316 |
| 325 return static_cast<float>(pipeline_->GetTime().InSecondsF()); | 317 return static_cast<float>(pipeline_.GetTime().InSecondsF()); |
| 326 } | 318 } |
| 327 | 319 |
| 328 int WebMediaPlayerImpl::dataRate() const { | 320 int WebMediaPlayerImpl::dataRate() const { |
| 329 DCHECK(MessageLoop::current() == main_loop_); | 321 DCHECK(MessageLoop::current() == main_loop_); |
| 330 | 322 |
| 331 // TODO(hclam): Add this method call if pipeline has it in the interface. | 323 // TODO(hclam): Add this method call if pipeline has it in the interface. |
| 332 return 0; | 324 return 0; |
| 333 } | 325 } |
| 334 | 326 |
| 335 float WebMediaPlayerImpl::maxTimeBuffered() const { | 327 float WebMediaPlayerImpl::maxTimeBuffered() const { |
| 336 DCHECK(MessageLoop::current() == main_loop_); | 328 DCHECK(MessageLoop::current() == main_loop_); |
| 337 | 329 |
| 338 return static_cast<float>(pipeline_->GetBufferedTime().InSecondsF()); | 330 return static_cast<float>(pipeline_.GetBufferedTime().InSecondsF()); |
| 339 } | 331 } |
| 340 | 332 |
| 341 float WebMediaPlayerImpl::maxTimeSeekable() const { | 333 float WebMediaPlayerImpl::maxTimeSeekable() const { |
| 342 DCHECK(MessageLoop::current() == main_loop_); | 334 DCHECK(MessageLoop::current() == main_loop_); |
| 343 | 335 |
| 344 // TODO(scherkus): move this logic down into the pipeline. | 336 // TODO(scherkus): move this logic down into the pipeline. |
| 345 if (pipeline_->GetTotalBytes() == 0) { | 337 if (pipeline_.GetTotalBytes() == 0) { |
| 346 return 0.0f; | 338 return 0.0f; |
| 347 } | 339 } |
| 348 double total_bytes = static_cast<double>(pipeline_->GetTotalBytes()); | 340 double total_bytes = static_cast<double>(pipeline_.GetTotalBytes()); |
| 349 double buffered_bytes = static_cast<double>(pipeline_->GetBufferedBytes()); | 341 double buffered_bytes = static_cast<double>(pipeline_.GetBufferedBytes()); |
| 350 double duration = static_cast<double>(pipeline_->GetDuration().InSecondsF()); | 342 double duration = static_cast<double>(pipeline_.GetDuration().InSecondsF()); |
| 351 return static_cast<float>(duration * (buffered_bytes / total_bytes)); | 343 return static_cast<float>(duration * (buffered_bytes / total_bytes)); |
| 352 } | 344 } |
| 353 | 345 |
| 354 unsigned long long WebMediaPlayerImpl::bytesLoaded() const { | 346 unsigned long long WebMediaPlayerImpl::bytesLoaded() const { |
| 355 DCHECK(MessageLoop::current() == main_loop_); | 347 DCHECK(MessageLoop::current() == main_loop_); |
| 356 | 348 |
| 357 return pipeline_->GetBufferedBytes(); | 349 return pipeline_.GetBufferedBytes(); |
| 358 } | 350 } |
| 359 | 351 |
| 360 unsigned long long WebMediaPlayerImpl::totalBytes() const { | 352 unsigned long long WebMediaPlayerImpl::totalBytes() const { |
| 361 DCHECK(MessageLoop::current() == main_loop_); | 353 DCHECK(MessageLoop::current() == main_loop_); |
| 362 | 354 |
| 363 return pipeline_->GetTotalBytes(); | 355 return pipeline_.GetTotalBytes(); |
| 364 } | 356 } |
| 365 | 357 |
| 366 void WebMediaPlayerImpl::setSize(const WebSize& size) { | 358 void WebMediaPlayerImpl::setSize(const WebSize& size) { |
| 367 DCHECK(MessageLoop::current() == main_loop_); | 359 DCHECK(MessageLoop::current() == main_loop_); |
| 368 DCHECK(proxy_); | 360 DCHECK(proxy_); |
| 369 | 361 |
| 370 proxy_->SetSize(gfx::Rect(0, 0, size.width, size.height)); | 362 proxy_->SetSize(gfx::Rect(0, 0, size.width, size.height)); |
| 371 } | 363 } |
| 372 | 364 |
| 373 void WebMediaPlayerImpl::paint(WebCanvas* canvas, | 365 void WebMediaPlayerImpl::paint(WebCanvas* canvas, |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 408 if (ready_state_ != state) { | 400 if (ready_state_ != state) { |
| 409 ready_state_ = state; | 401 ready_state_ = state; |
| 410 GetClient()->readyStateChanged(); | 402 GetClient()->readyStateChanged(); |
| 411 } | 403 } |
| 412 } | 404 } |
| 413 | 405 |
| 414 void WebMediaPlayerImpl::Destroy() { | 406 void WebMediaPlayerImpl::Destroy() { |
| 415 DCHECK(MessageLoop::current() == main_loop_); | 407 DCHECK(MessageLoop::current() == main_loop_); |
| 416 | 408 |
| 417 // Make sure to kill the pipeline so there's no more media threads running. | 409 // Make sure to kill the pipeline so there's no more media threads running. |
| 418 // TODO(hclam): stopping the pipeline might block for a long time. | 410 // TODO(hclam): stopping the pipeline is synchronous so it might block |
| 419 pipeline_->Stop(NULL); | 411 // stopping for a long time. |
| 420 pipeline_thread_.Stop(); | 412 pipeline_.Stop(); |
| 421 | 413 |
| 422 // And then detach the proxy, it may live on the render thread for a little | 414 // And then detach the proxy, it may live on the render thread for a little |
| 423 // longer until all the tasks are finished. | 415 // longer until all the tasks are finished. |
| 424 if (proxy_) { | 416 if (proxy_) { |
| 425 proxy_->Detach(); | 417 proxy_->Detach(); |
| 426 proxy_ = NULL; | 418 proxy_ = NULL; |
| 427 } | 419 } |
| 428 } | 420 } |
| 429 | 421 |
| 430 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { | 422 WebKit::WebMediaPlayerClient* WebMediaPlayerImpl::GetClient() { |
| 431 DCHECK(MessageLoop::current() == main_loop_); | 423 DCHECK(MessageLoop::current() == main_loop_); |
| 432 DCHECK(client_); | 424 DCHECK(client_); |
| 433 return client_; | 425 return client_; |
| 434 } | 426 } |
| 435 | 427 |
| 436 } // namespace webkit_glue | 428 } // namespace webkit_glue |
| OLD | NEW |