| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. Use of this |
| 2 // source code is governed by a BSD-style license that can be found in the | 2 // source code is governed by a BSD-style license that can be found in the |
| 3 // LICENSE file. | 3 // LICENSE file. |
| 4 | 4 |
| 5 #include "base/compiler_specific.h" | 5 #include "base/compiler_specific.h" |
| 6 #include "base/message_loop.h" | 6 #include "base/message_loop.h" |
| 7 #include "base/process_util.h" | 7 #include "base/process_util.h" |
| 8 #include "base/stl_util-inl.h" | 8 #include "base/stl_util-inl.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "chrome/common/extensions/url_pattern.h" | 10 #include "chrome/common/extensions/url_pattern.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 // number of bytes, we should determine this value from typical connection speed | 42 // number of bytes, we should determine this value from typical connection speed |
| 43 // and amount of time for a suitable wait. Now I just make a guess for this | 43 // and amount of time for a suitable wait. Now I just make a guess for this |
| 44 // number to be 2MB. | 44 // number to be 2MB. |
| 45 // TODO(hclam): determine a better value for this. | 45 // TODO(hclam): determine a better value for this. |
| 46 const int kForwardWaitThreshold = 2 * kMegabyte; | 46 const int kForwardWaitThreshold = 2 * kMegabyte; |
| 47 | 47 |
| 48 // Defines how long we should wait for more data before we declare a connection | 48 // Defines how long we should wait for more data before we declare a connection |
| 49 // timeout and start a new request. | 49 // timeout and start a new request. |
| 50 // TODO(hclam): Use this value when retry is implemented. | 50 // TODO(hclam): Use this value when retry is implemented. |
| 51 // TODO(hclam): Set it to 5s, calibrate this value later. | 51 // TODO(hclam): Set it to 5s, calibrate this value later. |
| 52 const int kDataTransferTimeoutSeconds = 5; | 52 const int kTimeoutMilliseconds = 5000; |
| 53 | 53 |
| 54 // Defines how many times we should try to read from a buffered resource loader | 54 // Defines how many times we should try to read from a buffered resource loader |
| 55 // before we declare a read error. After each failure of read from a buffered | 55 // before we declare a read error. After each failure of read from a buffered |
| 56 // resource loader, a new one is created to be read. | 56 // resource loader, a new one is created to be read. |
| 57 // TODO(hclam): Use this value when retry is implemented. | 57 // TODO(hclam): Use this value when retry is implemented. |
| 58 const int kReadTrials = 3; | 58 const int kReadTrials = 3; |
| 59 | 59 |
| 60 // BufferedDataSource has an intermediate buffer, this value governs the initial | 60 // BufferedDataSource has an intermediate buffer, this value governs the initial |
| 61 // size of that buffer. It is set to 32KB because this is a typical read size | 61 // size of that buffer. It is set to 32KB because this is a typical read size |
| 62 // of FFmpeg. | 62 // of FFmpeg. |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 // for testing purpose. | 440 // for testing purpose. |
| 441 BufferedResourceLoader* BufferedDataSource::CreateLoader( | 441 BufferedResourceLoader* BufferedDataSource::CreateLoader( |
| 442 int64 first_byte_position, int64 last_byte_position) { | 442 int64 first_byte_position, int64 last_byte_position) { |
| 443 DCHECK(MessageLoop::current() == render_loop_); | 443 DCHECK(MessageLoop::current() == render_loop_); |
| 444 | 444 |
| 445 return new BufferedResourceLoader(bridge_factory_.get(), url_, | 445 return new BufferedResourceLoader(bridge_factory_.get(), url_, |
| 446 first_byte_position, | 446 first_byte_position, |
| 447 last_byte_position); | 447 last_byte_position); |
| 448 } | 448 } |
| 449 | 449 |
| 450 // This method simply returns kTimeoutMilliseconds. The purpose of this |
| 451 // method is to be overidded so as to provide a different timeout value |
| 452 // for testing purpose. |
| 453 base::TimeDelta BufferedDataSource::GetTimeoutMilliseconds() { |
| 454 return base::TimeDelta::FromMilliseconds(kTimeoutMilliseconds); |
| 455 } |
| 456 |
| 450 ///////////////////////////////////////////////////////////////////////////// | 457 ///////////////////////////////////////////////////////////////////////////// |
| 451 // BufferedDataSource, media::MediaFilter implementation | 458 // BufferedDataSource, media::MediaFilter implementation |
| 452 void BufferedDataSource::Initialize(const std::string& url, | 459 void BufferedDataSource::Initialize(const std::string& url, |
| 453 media::FilterCallback* callback) { | 460 media::FilterCallback* callback) { |
| 454 DCHECK(callback); | 461 DCHECK(callback); |
| 455 initialize_callback_.reset(callback); | 462 initialize_callback_.reset(callback); |
| 456 | 463 |
| 457 // Saves the url. | 464 // Saves the url. |
| 458 url_ = GURL(url); | 465 url_ = GURL(url); |
| 459 | 466 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 bool BufferedDataSource::IsSeekable() { | 510 bool BufferedDataSource::IsSeekable() { |
| 504 return total_bytes_ != kPositionNotSpecified; | 511 return total_bytes_ != kPositionNotSpecified; |
| 505 } | 512 } |
| 506 | 513 |
| 507 ///////////////////////////////////////////////////////////////////////////// | 514 ///////////////////////////////////////////////////////////////////////////// |
| 508 // BufferedDataSource, render thread tasks | 515 // BufferedDataSource, render thread tasks |
| 509 void BufferedDataSource::InitializeTask() { | 516 void BufferedDataSource::InitializeTask() { |
| 510 DCHECK(MessageLoop::current() == render_loop_); | 517 DCHECK(MessageLoop::current() == render_loop_); |
| 511 DCHECK(!loader_.get()); | 518 DCHECK(!loader_.get()); |
| 512 | 519 |
| 520 // Kick starts the watch dog task that will handle connection timeout. |
| 521 // We run the watch dog 2 times faster the actual timeout so as to catch |
| 522 // the timeout more accurately. |
| 523 watch_dog_timer_.Start( |
| 524 GetTimeoutMilliseconds() / 2, |
| 525 this, |
| 526 &BufferedDataSource::WatchDogTask); |
| 527 |
| 513 // Creates a new resource loader with the full range. | 528 // Creates a new resource loader with the full range. |
| 514 loader_.reset(CreateLoader(-1, -1)); | 529 loader_.reset(CreateLoader(-1, -1)); |
| 515 | 530 |
| 516 // And then start the resource request. | 531 // And then start the resource request. |
| 517 loader_->Start(NewCallback(this, | 532 loader_->Start(NewCallback(this, |
| 518 &BufferedDataSource::InitializeStartCallback)); | 533 &BufferedDataSource::InitializeStartCallback)); |
| 519 } | 534 } |
| 520 | 535 |
| 521 void BufferedDataSource::ReadTask( | 536 void BufferedDataSource::ReadTask( |
| 522 int64 position, int read_size, uint8* buffer, | 537 int64 position, int read_size, uint8* buffer, |
| 523 media::DataSource::ReadCallback* read_callback) { | 538 media::DataSource::ReadCallback* read_callback) { |
| 524 DCHECK(MessageLoop::current() == render_loop_); | 539 DCHECK(MessageLoop::current() == render_loop_); |
| 525 DCHECK(!read_callback_.get()); | 540 DCHECK(!read_callback_.get()); |
| 526 DCHECK(read_callback); | 541 DCHECK(read_callback); |
| 527 | 542 |
| 528 // Saves the read parameters. | 543 // Saves the read parameters. |
| 529 read_position_ = position; | 544 read_position_ = position; |
| 530 read_size_ = read_size; | 545 read_size_ = read_size; |
| 531 read_callback_.reset(read_callback); | 546 read_callback_.reset(read_callback); |
| 532 read_buffer_ = buffer; | 547 read_buffer_ = buffer; |
| 548 read_submitted_time_ = base::Time::Now(); |
| 549 read_attempts_ = 0; |
| 533 | 550 |
| 534 // Call to read internal to perform the actual read. | 551 // Call to read internal to perform the actual read. |
| 535 ReadInternal(); | 552 ReadInternal(); |
| 536 } | 553 } |
| 537 | 554 |
| 538 void BufferedDataSource::StopTask() { | 555 void BufferedDataSource::StopTask() { |
| 539 DCHECK(MessageLoop::current() == render_loop_); | 556 DCHECK(MessageLoop::current() == render_loop_); |
| 540 | 557 |
| 558 // Stop the watch dog. |
| 559 watch_dog_timer_.Stop(); |
| 560 |
| 541 // We just need to stop the loader, so it stops activity. | 561 // We just need to stop the loader, so it stops activity. |
| 542 if (loader_.get()) { | 562 if (loader_.get()) { |
| 543 loader_->Stop(); | 563 loader_->Stop(); |
| 544 loader_.reset(); | 564 loader_.reset(); |
| 545 } | 565 } |
| 566 |
| 567 // Reset the parameters of the current read request. |
| 568 read_callback_.reset(); |
| 569 read_position_ = 0; |
| 570 read_size_ = 0; |
| 571 read_buffer_ = 0; |
| 572 read_submitted_time_ = base::Time(); |
| 573 read_attempts_ = 0; |
| 546 } | 574 } |
| 547 | 575 |
| 548 void BufferedDataSource::SwapLoaderTask(BufferedResourceLoader* loader) { | 576 void BufferedDataSource::SwapLoaderTask(BufferedResourceLoader* loader) { |
| 549 DCHECK(MessageLoop::current() == render_loop_); | 577 DCHECK(MessageLoop::current() == render_loop_); |
| 550 DCHECK(loader); | 578 DCHECK(loader); |
| 551 | 579 |
| 552 loader_.reset(loader); | 580 loader_.reset(loader); |
| 553 loader_->Start(NewCallback(this, | 581 loader_->Start(NewCallback(this, |
| 554 &BufferedDataSource::PartialReadStartCallback)); | 582 &BufferedDataSource::PartialReadStartCallback)); |
| 555 } | 583 } |
| 556 | 584 |
| 585 void BufferedDataSource::WatchDogTask() { |
| 586 DCHECK(MessageLoop::current() == render_loop_); |
| 587 |
| 588 // We only care if there is an active read request. |
| 589 if (!read_callback_.get()) |
| 590 return; |
| 591 |
| 592 DCHECK(loader_.get()); |
| 593 base::TimeDelta delta = base::Time::Now() - read_submitted_time_; |
| 594 if (delta < GetTimeoutMilliseconds()) |
| 595 return; |
| 596 |
| 597 // TODO(hclam): Maybe raise an error here. But if an error is reported |
| 598 // the whole pipeline may get destroyed... |
| 599 if (read_attempts_ >= kReadTrials) |
| 600 return; |
| 601 |
| 602 ++read_attempts_; |
| 603 read_submitted_time_ = base::Time::Now(); |
| 604 |
| 605 // Stops the current loader and swap in a new resource loader and |
| 606 // retry the request. |
| 607 loader_->Stop(); |
| 608 SwapLoaderTask(CreateLoader(read_position_, -1)); |
| 609 } |
| 610 |
| 557 // This method is the place where actual read happens, |loader_| must be valid | 611 // This method is the place where actual read happens, |loader_| must be valid |
| 558 // prior to make this method call. | 612 // prior to make this method call. |
| 559 void BufferedDataSource::ReadInternal() { | 613 void BufferedDataSource::ReadInternal() { |
| 560 DCHECK(MessageLoop::current() == render_loop_); | 614 DCHECK(MessageLoop::current() == render_loop_); |
| 561 DCHECK(loader_.get()); | 615 DCHECK(loader_.get()); |
| 562 | 616 |
| 563 // First we prepare the intermediate read buffer for BufferedResourceLoader | 617 // First we prepare the intermediate read buffer for BufferedResourceLoader |
| 564 // to write to. | 618 // to write to. |
| 565 if (read_size_ > intermediate_read_buffer_size_) { | 619 if (read_size_ > intermediate_read_buffer_size_) { |
| 566 intermediate_read_buffer_.reset(new uint8[read_size_]); | 620 intermediate_read_buffer_.reset(new uint8[read_size_]); |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 | 779 |
| 726 // TODO(hclam): It may be bad to access host() here. | 780 // TODO(hclam): It may be bad to access host() here. |
| 727 host()->SetError(media::PIPELINE_ERROR_NETWORK); | 781 host()->SetError(media::PIPELINE_ERROR_NETWORK); |
| 728 | 782 |
| 729 // Stops the laoder. | 783 // Stops the laoder. |
| 730 loader_->Stop(); | 784 loader_->Stop(); |
| 731 } | 785 } |
| 732 } | 786 } |
| 733 | 787 |
| 734 } // namespace webkit_glue | 788 } // namespace webkit_glue |
| OLD | NEW |