Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1022)

Side by Side Diff: webkit/media/buffered_data_source.cc

Issue 10692106: Split BufferedResourceLoader's network callback into separate loading state and progress callbacks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add bug #s Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
11 11
12 using WebKit::WebFrame; 12 using WebKit::WebFrame;
13 13
14 namespace webkit_media { 14 namespace webkit_media {
15 15
16 // BufferedDataSource has an intermediate buffer, this value governs the initial 16 // BufferedDataSource has an intermediate buffer, this value governs the initial
17 // size of that buffer. It is set to 32KB because this is a typical read size 17 // size of that buffer. It is set to 32KB because this is a typical read size
18 // of FFmpeg. 18 // of FFmpeg.
19 static const int kInitialReadBufferSize = 32768; 19 static const int kInitialReadBufferSize = 32768;
20 20
21 // Number of cache misses we allow for a single Read() before signalling an 21 // Number of cache misses we allow for a single Read() before signalling an
22 // error. 22 // error.
23 static const int kNumCacheMissRetries = 3; 23 static const int kNumCacheMissRetries = 3;
24 24
25 // Non-HTTP resources are assumed to be fully loaded so we ignore any
26 // loading/progress related callbacks.
scherkus (not reviewing) 2012/07/06 16:28:35 see http://codereview.chromium.org/10692106/ -- I
Ami GONE FROM CHROMIUM 2012/07/09 03:25:10 FTR, you mean https://chromiumcodereview.appspot.c
27 static void NonHttpLoadingCallback(BufferedResourceLoader::LoadingState) {}
28 static void NonHttpProgressCallback(int64) {}
29
25 BufferedDataSource::BufferedDataSource( 30 BufferedDataSource::BufferedDataSource(
26 MessageLoop* render_loop, 31 MessageLoop* render_loop,
27 WebFrame* frame, 32 WebFrame* frame,
28 media::MediaLog* media_log) 33 media::MediaLog* media_log)
29 : total_bytes_(kPositionNotSpecified), 34 : total_bytes_(kPositionNotSpecified),
30 buffered_bytes_(0), 35 buffered_bytes_(0),
31 streaming_(false), 36 streaming_(false),
32 frame_(frame), 37 frame_(frame),
33 loader_(NULL), 38 loader_(NULL),
34 is_downloading_data_(false), 39 is_downloading_data_(false),
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 url_ = url; 93 url_ = url;
89 94
90 initialize_cb_ = initialize_cb; 95 initialize_cb_ = initialize_cb;
91 96
92 if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) { 97 if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) {
93 // Do an unbounded range request starting at the beginning. If the server 98 // Do an unbounded range request starting at the beginning. If the server
94 // responds with 200 instead of 206 we'll fall back into a streaming mode. 99 // responds with 200 instead of 206 we'll fall back into a streaming mode.
95 loader_.reset(CreateResourceLoader(0, kPositionNotSpecified)); 100 loader_.reset(CreateResourceLoader(0, kPositionNotSpecified));
96 loader_->Start( 101 loader_->Start(
97 base::Bind(&BufferedDataSource::HttpInitialStartCallback, this), 102 base::Bind(&BufferedDataSource::HttpInitialStartCallback, this),
98 base::Bind(&BufferedDataSource::NetworkEventCallback, this), 103 base::Bind(&BufferedDataSource::HttpLoadingCallback, this),
104 base::Bind(&BufferedDataSource::HttpProgressCallback, this),
99 frame_); 105 frame_);
100 return; 106 return;
101 } 107 }
102 108
103 // For all other protocols, assume they support range request. We fetch 109 // For all other protocols, assume they support range request. We fetch
104 // the full range of the resource to obtain the instance size because 110 // the full range of the resource to obtain the instance size because
105 // we won't be served HTTP headers. 111 // we won't be served HTTP headers.
106 loader_.reset(CreateResourceLoader(kPositionNotSpecified, 112 loader_.reset(CreateResourceLoader(kPositionNotSpecified,
107 kPositionNotSpecified)); 113 kPositionNotSpecified));
108 loader_->Start( 114 loader_->Start(
109 base::Bind(&BufferedDataSource::NonHttpInitialStartCallback, this), 115 base::Bind(&BufferedDataSource::NonHttpInitialStartCallback, this),
110 base::Bind(&BufferedDataSource::NetworkEventCallback, this), 116 base::Bind(&NonHttpLoadingCallback),
117 base::Bind(&NonHttpProgressCallback),
111 frame_); 118 frame_);
112 } 119 }
113 120
114 void BufferedDataSource::SetPreload(Preload preload) { 121 void BufferedDataSource::SetPreload(Preload preload) {
115 DCHECK(MessageLoop::current() == render_loop_); 122 DCHECK(MessageLoop::current() == render_loop_);
116 preload_ = preload; 123 preload_ = preload;
117 } 124 }
118 125
119 bool BufferedDataSource::HasSingleOrigin() { 126 bool BufferedDataSource::HasSingleOrigin() {
120 DCHECK(MessageLoop::current() == render_loop_); 127 DCHECK(MessageLoop::current() == render_loop_);
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 if (stopped_on_render_loop_) 255 if (stopped_on_render_loop_)
249 return; 256 return;
250 257
251 { 258 {
252 // If there's no outstanding read then return early. 259 // If there's no outstanding read then return early.
253 base::AutoLock auto_lock(lock_); 260 base::AutoLock auto_lock(lock_);
254 if (read_cb_.is_null()) 261 if (read_cb_.is_null())
255 return; 262 return;
256 } 263 }
257 264
265 // Start reading from where we last left off until the end of the resource.
258 loader_.reset( 266 loader_.reset(
259 CreateResourceLoader(last_read_start_, kPositionNotSpecified)); 267 CreateResourceLoader(last_read_start_, kPositionNotSpecified));
260 loader_->Start( 268 if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) {
261 base::Bind(&BufferedDataSource::PartialReadStartCallback, this), 269 loader_->Start(
262 base::Bind(&BufferedDataSource::NetworkEventCallback, this), 270 base::Bind(&BufferedDataSource::PartialReadStartCallback, this),
263 frame_); 271 base::Bind(&BufferedDataSource::HttpLoadingCallback, this),
272 base::Bind(&BufferedDataSource::HttpProgressCallback, this),
273 frame_);
274 } else {
275 loader_->Start(
276 base::Bind(&BufferedDataSource::NonHttpInitialStartCallback, this),
277 base::Bind(&NonHttpLoadingCallback),
278 base::Bind(&NonHttpProgressCallback),
279 frame_);
280 }
264 } 281 }
265 282
266 void BufferedDataSource::SetPlaybackRateTask(float playback_rate) { 283 void BufferedDataSource::SetPlaybackRateTask(float playback_rate) {
267 DCHECK(MessageLoop::current() == render_loop_); 284 DCHECK(MessageLoop::current() == render_loop_);
268 DCHECK(loader_.get()); 285 DCHECK(loader_.get());
269 286
270 if (playback_rate != 0) 287 if (playback_rate != 0)
271 media_has_played_ = true; 288 media_has_played_ = true;
272 289
273 playback_rate_ = playback_rate; 290 playback_rate_ = playback_rate;
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 cache_miss_retries_left_--; 514 cache_miss_retries_left_--;
498 render_loop_->PostTask(FROM_HERE, 515 render_loop_->PostTask(FROM_HERE,
499 base::Bind(&BufferedDataSource::RestartLoadingTask, this)); 516 base::Bind(&BufferedDataSource::RestartLoadingTask, this));
500 return; 517 return;
501 } 518 }
502 519
503 // Fall through to signal a read error. 520 // Fall through to signal a read error.
504 bytes_read = kReadError; 521 bytes_read = kReadError;
505 } 522 }
506 523
507 // We need to prevent calling to filter host and running the callback if 524 // TODO(scherkus): we shouldn't have to lock to signal host(), see
508 // we have received the stop signal. We need to lock down the whole callback 525 // http://crbug.com/113712 for details.
509 // method to prevent bad things from happening. The reason behind this is
510 // that we cannot guarantee tasks on render thread have completely stopped
511 // when we receive the Stop() method call. So only way to solve this is to
512 // let tasks on render thread to run but make sure they don't call outside
513 // this object when Stop() method is ever called. Locking this method is safe
514 // because |lock_| is only acquired in tasks on render thread.
515 base::AutoLock auto_lock(lock_); 526 base::AutoLock auto_lock(lock_);
516 if (stop_signal_received_) 527 if (stop_signal_received_)
517 return; 528 return;
518 529
519 if (bytes_read > 0) { 530 if (bytes_read > 0) {
520 memcpy(read_buffer_, intermediate_read_buffer_.get(), bytes_read); 531 memcpy(read_buffer_, intermediate_read_buffer_.get(), bytes_read);
521 } else if (bytes_read == 0 && total_bytes_ == kPositionNotSpecified) { 532 } 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 533 // 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 534 // 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. 535 // fail like they would if we had known the file size at the beginning.
525 total_bytes_ = loader_->instance_size(); 536 total_bytes_ = loader_->instance_size();
526 537
527 if (host() && total_bytes_ != kPositionNotSpecified) { 538 if (host() && total_bytes_ != kPositionNotSpecified) {
528 host()->SetTotalBytes(total_bytes_); 539 host()->SetTotalBytes(total_bytes_);
529 host()->AddBufferedByteRange(last_read_start_, total_bytes_); 540 host()->AddBufferedByteRange(last_read_start_, total_bytes_);
530 } 541 }
531 } 542 }
532 DoneRead_Locked(bytes_read); 543 DoneRead_Locked(bytes_read);
533 } 544 }
534 545
535 void BufferedDataSource::NetworkEventCallback() { 546 void BufferedDataSource::HttpLoadingCallback(
547 BufferedResourceLoader::LoadingState state) {
536 DCHECK(MessageLoop::current() == render_loop_); 548 DCHECK(MessageLoop::current() == render_loop_);
537 DCHECK(loader_.get()); 549 DCHECK(url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme));
538 550
539 // In case of non-HTTP request we don't need to report network events, 551 // TODO(scherkus): we shouldn't have to lock to signal host(), see
540 // so return immediately. 552 // http://crbug.com/113712 for details.
541 if (!url_.SchemeIs(kHttpScheme) && !url_.SchemeIs(kHttpsScheme))
542 return;
543
544 bool is_downloading_data = loader_->is_downloading_data();
545 int64 current_buffered_position = loader_->GetBufferedPosition();
546
547 // If we get an unspecified value, return immediately.
548 if (current_buffered_position == kPositionNotSpecified)
549 return;
550
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
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
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
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.
559 base::AutoLock auto_lock(lock_); 553 base::AutoLock auto_lock(lock_);
560 if (stop_signal_received_) 554 if (stop_signal_received_)
561 return; 555 return;
562 556
557 bool is_downloading_data;
558 switch (state) {
559 case BufferedResourceLoader::kLoading:
560 is_downloading_data = true;
561 break;
562 case BufferedResourceLoader::kLoadingDeferred:
563 is_downloading_data = false;
564 break;
565
566 // TODO(scherkus): we don't signal network activity changes when loads
567 // complete or fail to preserve existing behaviour when deferring is
568 // toggled, however SetNetworkActivity() should use a similar enum as there
569 // isn't any signal today to notify the client that loading has
570 // failed/finished (we only get errors on subsequent reads).
571 case BufferedResourceLoader::kLoadingFailed:
572 case BufferedResourceLoader::kLoadingFinished:
573 return;
574 }
575
563 if (is_downloading_data != is_downloading_data_) { 576 if (is_downloading_data != is_downloading_data_) {
564 is_downloading_data_ = is_downloading_data; 577 is_downloading_data_ = is_downloading_data;
565 if (host()) 578 if (host())
566 host()->SetNetworkActivity(is_downloading_data); 579 host()->SetNetworkActivity(is_downloading_data);
567 } 580 }
581 }
568 582
569 if (host() && current_buffered_position > last_read_start_) 583 void BufferedDataSource::HttpProgressCallback(int64 position) {
570 host()->AddBufferedByteRange(last_read_start_, current_buffered_position); 584 DCHECK(MessageLoop::current() == render_loop_);
585 DCHECK(url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme));
586
587 // TODO(scherkus): we shouldn't have to lock to signal host(), see
588 // http://crbug.com/113712 for details.
589 base::AutoLock auto_lock(lock_);
590 if (stop_signal_received_)
591 return;
592
593 if (host() && position > last_read_start_)
594 host()->AddBufferedByteRange(last_read_start_, position);
571 } 595 }
572 596
573 void BufferedDataSource::UpdateHostState_Locked() { 597 void BufferedDataSource::UpdateHostState_Locked() {
574 // Called from various threads, under lock.
575 lock_.AssertAcquired(); 598 lock_.AssertAcquired();
576 599
577 if (!host()) 600 if (!host())
578 return; 601 return;
579 602
580 if (total_bytes_ != kPositionNotSpecified) 603 if (total_bytes_ != kPositionNotSpecified)
581 host()->SetTotalBytes(total_bytes_); 604 host()->SetTotalBytes(total_bytes_);
582 if (buffered_bytes_ > last_read_start_) 605 if (buffered_bytes_ > last_read_start_)
583 host()->AddBufferedByteRange(last_read_start_, buffered_bytes_); 606 host()->AddBufferedByteRange(last_read_start_, buffered_bytes_);
584 } 607 }
585 608
586 } // namespace webkit_media 609 } // namespace webkit_media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698