| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/media/buffered_data_source.h" | 5 #include "webkit/media/buffered_data_source.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "media/base/media_log.h" | 9 #include "media/base/media_log.h" |
| 10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 25 BufferedDataSource::BufferedDataSource( | 25 BufferedDataSource::BufferedDataSource( |
| 26 MessageLoop* render_loop, | 26 MessageLoop* render_loop, |
| 27 WebFrame* frame, | 27 WebFrame* frame, |
| 28 media::MediaLog* media_log) | 28 media::MediaLog* media_log) |
| 29 : total_bytes_(kPositionNotSpecified), | 29 : total_bytes_(kPositionNotSpecified), |
| 30 buffered_bytes_(0), | 30 buffered_bytes_(0), |
| 31 streaming_(false), | 31 streaming_(false), |
| 32 frame_(frame), | 32 frame_(frame), |
| 33 loader_(NULL), | 33 loader_(NULL), |
| 34 is_downloading_data_(false), | 34 is_downloading_data_(false), |
| 35 read_position_(0), | |
| 36 read_size_(0), | 35 read_size_(0), |
| 37 read_buffer_(NULL), | 36 read_buffer_(NULL), |
| 37 last_read_start_(0), |
| 38 intermediate_read_buffer_(new uint8[kInitialReadBufferSize]), | 38 intermediate_read_buffer_(new uint8[kInitialReadBufferSize]), |
| 39 intermediate_read_buffer_size_(kInitialReadBufferSize), | 39 intermediate_read_buffer_size_(kInitialReadBufferSize), |
| 40 render_loop_(render_loop), | 40 render_loop_(render_loop), |
| 41 stop_signal_received_(false), | 41 stop_signal_received_(false), |
| 42 stopped_on_render_loop_(false), | 42 stopped_on_render_loop_(false), |
| 43 media_has_played_(false), | 43 media_has_played_(false), |
| 44 preload_(AUTO), | 44 preload_(AUTO), |
| 45 cache_miss_retries_left_(kNumCacheMissRetries), | 45 cache_miss_retries_left_(kNumCacheMissRetries), |
| 46 bitrate_(0), | 46 bitrate_(0), |
| 47 playback_rate_(0.0), | 47 playback_rate_(0.0), |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 200 DCHECK(MessageLoop::current() == render_loop_); | 200 DCHECK(MessageLoop::current() == render_loop_); |
| 201 { | 201 { |
| 202 base::AutoLock auto_lock(lock_); | 202 base::AutoLock auto_lock(lock_); |
| 203 if (stopped_on_render_loop_) | 203 if (stopped_on_render_loop_) |
| 204 return; | 204 return; |
| 205 | 205 |
| 206 DCHECK(!read_cb_.is_null()); | 206 DCHECK(!read_cb_.is_null()); |
| 207 } | 207 } |
| 208 | 208 |
| 209 // Saves the read parameters. | 209 // Saves the read parameters. |
| 210 read_position_ = position; | 210 last_read_start_ = position; |
| 211 read_size_ = read_size; | 211 read_size_ = read_size; |
| 212 read_buffer_ = buffer; | 212 read_buffer_ = buffer; |
| 213 cache_miss_retries_left_ = kNumCacheMissRetries; | 213 cache_miss_retries_left_ = kNumCacheMissRetries; |
| 214 | 214 |
| 215 // Call to read internal to perform the actual read. | 215 // Call to read internal to perform the actual read. |
| 216 ReadInternal(); | 216 ReadInternal(); |
| 217 } | 217 } |
| 218 | 218 |
| 219 void BufferedDataSource::CleanupTask() { | 219 void BufferedDataSource::CleanupTask() { |
| 220 DCHECK(MessageLoop::current() == render_loop_); | 220 DCHECK(MessageLoop::current() == render_loop_); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 232 | 232 |
| 233 if (!read_cb_.is_null()) | 233 if (!read_cb_.is_null()) |
| 234 DoneRead_Locked(kReadError); | 234 DoneRead_Locked(kReadError); |
| 235 } | 235 } |
| 236 | 236 |
| 237 // We just need to stop the loader, so it stops activity. | 237 // We just need to stop the loader, so it stops activity. |
| 238 if (loader_.get()) | 238 if (loader_.get()) |
| 239 loader_->Stop(); | 239 loader_->Stop(); |
| 240 | 240 |
| 241 // Reset the parameters of the current read request. | 241 // Reset the parameters of the current read request. |
| 242 read_position_ = 0; | |
| 243 read_size_ = 0; | 242 read_size_ = 0; |
| 244 read_buffer_ = 0; | 243 read_buffer_ = 0; |
| 245 } | 244 } |
| 246 | 245 |
| 247 void BufferedDataSource::RestartLoadingTask() { | 246 void BufferedDataSource::RestartLoadingTask() { |
| 248 DCHECK(MessageLoop::current() == render_loop_); | 247 DCHECK(MessageLoop::current() == render_loop_); |
| 249 if (stopped_on_render_loop_) | 248 if (stopped_on_render_loop_) |
| 250 return; | 249 return; |
| 251 | 250 |
| 252 { | 251 { |
| 253 // If there's no outstanding read then return early. | 252 // If there's no outstanding read then return early. |
| 254 base::AutoLock auto_lock(lock_); | 253 base::AutoLock auto_lock(lock_); |
| 255 if (read_cb_.is_null()) | 254 if (read_cb_.is_null()) |
| 256 return; | 255 return; |
| 257 } | 256 } |
| 258 | 257 |
| 259 loader_.reset(CreateResourceLoader(read_position_, kPositionNotSpecified)); | 258 loader_.reset( |
| 259 CreateResourceLoader(last_read_start_, kPositionNotSpecified)); |
| 260 loader_->Start( | 260 loader_->Start( |
| 261 base::Bind(&BufferedDataSource::PartialReadStartCallback, this), | 261 base::Bind(&BufferedDataSource::PartialReadStartCallback, this), |
| 262 base::Bind(&BufferedDataSource::NetworkEventCallback, this), | 262 base::Bind(&BufferedDataSource::NetworkEventCallback, this), |
| 263 frame_); | 263 frame_); |
| 264 } | 264 } |
| 265 | 265 |
| 266 void BufferedDataSource::SetPlaybackRateTask(float playback_rate) { | 266 void BufferedDataSource::SetPlaybackRateTask(float playback_rate) { |
| 267 DCHECK(MessageLoop::current() == render_loop_); | 267 DCHECK(MessageLoop::current() == render_loop_); |
| 268 DCHECK(loader_.get()); | 268 DCHECK(loader_.get()); |
| 269 | 269 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 DCHECK(MessageLoop::current() == render_loop_); | 306 DCHECK(MessageLoop::current() == render_loop_); |
| 307 DCHECK(loader_.get()); | 307 DCHECK(loader_.get()); |
| 308 | 308 |
| 309 // First we prepare the intermediate read buffer for BufferedResourceLoader | 309 // First we prepare the intermediate read buffer for BufferedResourceLoader |
| 310 // to write to. | 310 // to write to. |
| 311 if (read_size_ > intermediate_read_buffer_size_) { | 311 if (read_size_ > intermediate_read_buffer_size_) { |
| 312 intermediate_read_buffer_.reset(new uint8[read_size_]); | 312 intermediate_read_buffer_.reset(new uint8[read_size_]); |
| 313 } | 313 } |
| 314 | 314 |
| 315 // Perform the actual read with BufferedResourceLoader. | 315 // Perform the actual read with BufferedResourceLoader. |
| 316 loader_->Read(read_position_, read_size_, intermediate_read_buffer_.get(), | 316 loader_->Read( |
| 317 base::Bind(&BufferedDataSource::ReadCallback, this)); | 317 last_read_start_, read_size_, intermediate_read_buffer_.get(), |
| 318 base::Bind(&BufferedDataSource::ReadCallback, this)); |
| 318 } | 319 } |
| 319 | 320 |
| 320 void BufferedDataSource::DoneRead_Locked(int bytes_read) { | 321 void BufferedDataSource::DoneRead_Locked(int bytes_read) { |
| 321 DVLOG(1) << "DoneRead: " << bytes_read << " bytes"; | 322 DVLOG(1) << "DoneRead: " << bytes_read << " bytes"; |
| 322 DCHECK(MessageLoop::current() == render_loop_); | 323 DCHECK(MessageLoop::current() == render_loop_); |
| 323 DCHECK(!read_cb_.is_null()); | 324 DCHECK(!read_cb_.is_null()); |
| 324 DCHECK(bytes_read >= 0 || bytes_read == kReadError); | 325 DCHECK(bytes_read >= 0 || bytes_read == kReadError); |
| 325 lock_.AssertAcquired(); | 326 lock_.AssertAcquired(); |
| 326 | 327 |
| 327 read_cb_.Run(bytes_read); | 328 read_cb_.Run(bytes_read); |
| 328 read_cb_.Reset(); | 329 read_cb_.Reset(); |
| 329 read_position_ = 0; | |
| 330 read_size_ = 0; | 330 read_size_ = 0; |
| 331 read_buffer_ = 0; | 331 read_buffer_ = 0; |
| 332 } | 332 } |
| 333 | 333 |
| 334 void BufferedDataSource::DoneInitialization_Locked( | 334 void BufferedDataSource::DoneInitialization_Locked( |
| 335 media::PipelineStatus status) { | 335 media::PipelineStatus status) { |
| 336 DCHECK(MessageLoop::current() == render_loop_); | 336 DCHECK(MessageLoop::current() == render_loop_); |
| 337 DCHECK(!initialize_cb_.is_null()); | 337 DCHECK(!initialize_cb_.is_null()); |
| 338 lock_.AssertAcquired(); | 338 lock_.AssertAcquired(); |
| 339 | 339 |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 if (bytes_read > 0) { | 519 if (bytes_read > 0) { |
| 520 memcpy(read_buffer_, intermediate_read_buffer_.get(), bytes_read); | 520 memcpy(read_buffer_, intermediate_read_buffer_.get(), bytes_read); |
| 521 } else if (bytes_read == 0 && total_bytes_ == kPositionNotSpecified) { | 521 } else if (bytes_read == 0 && total_bytes_ == kPositionNotSpecified) { |
| 522 // We've reached the end of the file and we didn't know the total size | 522 // We've reached the end of the file and we didn't know the total size |
| 523 // before. Update the total size so Read()s past the end of the file will | 523 // before. Update the total size so Read()s past the end of the file will |
| 524 // fail like they would if we had known the file size at the beginning. | 524 // fail like they would if we had known the file size at the beginning. |
| 525 total_bytes_ = loader_->instance_size(); | 525 total_bytes_ = loader_->instance_size(); |
| 526 | 526 |
| 527 if (host() && total_bytes_ != kPositionNotSpecified) { | 527 if (host() && total_bytes_ != kPositionNotSpecified) { |
| 528 host()->SetTotalBytes(total_bytes_); | 528 host()->SetTotalBytes(total_bytes_); |
| 529 host()->SetBufferedBytes(total_bytes_); | 529 host()->AddBufferedByteRange(last_read_start_, total_bytes_); |
| 530 } | 530 } |
| 531 } | 531 } |
| 532 DoneRead_Locked(bytes_read); | 532 DoneRead_Locked(bytes_read); |
| 533 } | 533 } |
| 534 | 534 |
| 535 void BufferedDataSource::NetworkEventCallback() { | 535 void BufferedDataSource::NetworkEventCallback() { |
| 536 DCHECK(MessageLoop::current() == render_loop_); | 536 DCHECK(MessageLoop::current() == render_loop_); |
| 537 DCHECK(loader_.get()); | 537 DCHECK(loader_.get()); |
| 538 | 538 |
| 539 // In case of non-HTTP request we don't need to report network events, | 539 // In case of non-HTTP request we don't need to report network events, |
| 540 // so return immediately. | 540 // so return immediately. |
| 541 if (!url_.SchemeIs(kHttpScheme) && !url_.SchemeIs(kHttpsScheme)) | 541 if (!url_.SchemeIs(kHttpScheme) && !url_.SchemeIs(kHttpsScheme)) |
| 542 return; | 542 return; |
| 543 | 543 |
| 544 bool is_downloading_data = loader_->is_downloading_data(); | 544 bool is_downloading_data = loader_->is_downloading_data(); |
| 545 int64 buffered_position = loader_->GetBufferedPosition(); | 545 int64 current_buffered_position = loader_->GetBufferedPosition(); |
| 546 | 546 |
| 547 // If we get an unspecified value, return immediately. | 547 // If we get an unspecified value, return immediately. |
| 548 if (buffered_position == kPositionNotSpecified) | 548 if (current_buffered_position == kPositionNotSpecified) |
| 549 return; | 549 return; |
| 550 | 550 |
| 551 // We need to prevent calling to filter host and running the callback if | 551 // We need to prevent calling to filter host and running the callback if |
| 552 // we have received the stop signal. We need to lock down the whole callback | 552 // we have received the stop signal. We need to lock down the whole callback |
| 553 // method to prevent bad things from happening. The reason behind this is | 553 // method to prevent bad things from happening. The reason behind this is |
| 554 // that we cannot guarantee tasks on render thread have completely stopped | 554 // that we cannot guarantee tasks on render thread have completely stopped |
| 555 // when we receive the Stop() method call. So only way to solve this is to | 555 // when we receive the Stop() method call. So only way to solve this is to |
| 556 // let tasks on render thread to run but make sure they don't call outside | 556 // let tasks on render thread to run but make sure they don't call outside |
| 557 // this object when Stop() method is ever called. Locking this method is safe | 557 // this object when Stop() method is ever called. Locking this method is safe |
| 558 // because |lock_| is only acquired in tasks on render thread. | 558 // because |lock_| is only acquired in tasks on render thread. |
| 559 base::AutoLock auto_lock(lock_); | 559 base::AutoLock auto_lock(lock_); |
| 560 if (stop_signal_received_) | 560 if (stop_signal_received_) |
| 561 return; | 561 return; |
| 562 | 562 |
| 563 if (is_downloading_data != is_downloading_data_) { | 563 if (is_downloading_data != is_downloading_data_) { |
| 564 is_downloading_data_ = is_downloading_data; | 564 is_downloading_data_ = is_downloading_data; |
| 565 if (host()) | 565 if (host()) |
| 566 host()->SetNetworkActivity(is_downloading_data); | 566 host()->SetNetworkActivity(is_downloading_data); |
| 567 } | 567 } |
| 568 | 568 |
| 569 buffered_bytes_ = buffered_position + 1; | 569 if (host() && current_buffered_position > last_read_start_) |
| 570 if (host()) | 570 host()->AddBufferedByteRange(last_read_start_, current_buffered_position); |
| 571 host()->SetBufferedBytes(buffered_bytes_); | |
| 572 } | 571 } |
| 573 | 572 |
| 574 void BufferedDataSource::UpdateHostState_Locked() { | 573 void BufferedDataSource::UpdateHostState_Locked() { |
| 575 // Called from various threads, under lock. | 574 // Called from various threads, under lock. |
| 576 lock_.AssertAcquired(); | 575 lock_.AssertAcquired(); |
| 577 | 576 |
| 578 if (!host()) | 577 if (!host()) |
| 579 return; | 578 return; |
| 580 | 579 |
| 581 if (total_bytes_ != kPositionNotSpecified) | 580 if (total_bytes_ != kPositionNotSpecified) |
| 582 host()->SetTotalBytes(total_bytes_); | 581 host()->SetTotalBytes(total_bytes_); |
| 583 host()->SetBufferedBytes(buffered_bytes_); | 582 if (buffered_bytes_ > last_read_start_) |
| 583 host()->AddBufferedByteRange(last_read_start_, buffered_bytes_); |
| 584 } | 584 } |
| 585 | 585 |
| 586 } // namespace webkit_media | 586 } // namespace webkit_media |
| OLD | NEW |