OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // TODO(scherkus): clean up PipelineImpl... too many crazy function names, | 5 // TODO(scherkus): clean up PipelineImpl... too many crazy function names, |
6 // potential deadlocks, etc... | 6 // potential deadlocks, etc... |
7 | 7 |
8 #include "base/callback.h" | 8 #include "base/callback.h" |
9 #include "base/compiler_specific.h" | 9 #include "base/compiler_specific.h" |
10 #include "base/stl_util-inl.h" | 10 #include "base/stl_util-inl.h" |
(...skipping 17 matching lines...) Expand all Loading... |
28 PipelineImpl::PipelineImpl(MessageLoop* message_loop) | 28 PipelineImpl::PipelineImpl(MessageLoop* message_loop) |
29 : message_loop_(message_loop), | 29 : message_loop_(message_loop), |
30 clock_(new ClockImpl(&base::Time::Now)), | 30 clock_(new ClockImpl(&base::Time::Now)), |
31 waiting_for_clock_update_(false), | 31 waiting_for_clock_update_(false), |
32 state_(kCreated), | 32 state_(kCreated), |
33 current_bytes_(0) { | 33 current_bytes_(0) { |
34 ResetState(); | 34 ResetState(); |
35 } | 35 } |
36 | 36 |
37 PipelineImpl::~PipelineImpl() { | 37 PipelineImpl::~PipelineImpl() { |
38 AutoLock auto_lock(lock_); | 38 base::AutoLock auto_lock(lock_); |
39 DCHECK(!running_) << "Stop() must complete before destroying object"; | 39 DCHECK(!running_) << "Stop() must complete before destroying object"; |
40 DCHECK(!stop_pending_); | 40 DCHECK(!stop_pending_); |
41 DCHECK(!seek_pending_); | 41 DCHECK(!seek_pending_); |
42 } | 42 } |
43 | 43 |
44 void PipelineImpl::Init(PipelineCallback* ended_callback, | 44 void PipelineImpl::Init(PipelineCallback* ended_callback, |
45 PipelineCallback* error_callback, | 45 PipelineCallback* error_callback, |
46 PipelineCallback* network_callback) { | 46 PipelineCallback* network_callback) { |
47 DCHECK(!IsRunning()) | 47 DCHECK(!IsRunning()) |
48 << "Init() should be called before the pipeline has started"; | 48 << "Init() should be called before the pipeline has started"; |
49 ended_callback_.reset(ended_callback); | 49 ended_callback_.reset(ended_callback); |
50 error_callback_.reset(error_callback); | 50 error_callback_.reset(error_callback); |
51 network_callback_.reset(network_callback); | 51 network_callback_.reset(network_callback); |
52 } | 52 } |
53 | 53 |
54 // Creates the PipelineInternal and calls it's start method. | 54 // Creates the PipelineInternal and calls it's start method. |
55 bool PipelineImpl::Start(FilterCollection* collection, | 55 bool PipelineImpl::Start(FilterCollection* collection, |
56 const std::string& url, | 56 const std::string& url, |
57 PipelineCallback* start_callback) { | 57 PipelineCallback* start_callback) { |
58 AutoLock auto_lock(lock_); | 58 base::AutoLock auto_lock(lock_); |
59 scoped_ptr<PipelineCallback> callback(start_callback); | 59 scoped_ptr<PipelineCallback> callback(start_callback); |
60 scoped_ptr<FilterCollection> filter_collection(collection); | 60 scoped_ptr<FilterCollection> filter_collection(collection); |
61 | 61 |
62 if (running_) { | 62 if (running_) { |
63 VLOG(1) << "Media pipeline is already running"; | 63 VLOG(1) << "Media pipeline is already running"; |
64 return false; | 64 return false; |
65 } | 65 } |
66 | 66 |
67 if (collection->IsEmpty()) { | 67 if (collection->IsEmpty()) { |
68 return false; | 68 return false; |
69 } | 69 } |
70 | 70 |
71 // Kick off initialization! | 71 // Kick off initialization! |
72 running_ = true; | 72 running_ = true; |
73 message_loop_->PostTask( | 73 message_loop_->PostTask( |
74 FROM_HERE, | 74 FROM_HERE, |
75 NewRunnableMethod(this, | 75 NewRunnableMethod(this, |
76 &PipelineImpl::StartTask, | 76 &PipelineImpl::StartTask, |
77 filter_collection.release(), | 77 filter_collection.release(), |
78 url, | 78 url, |
79 callback.release())); | 79 callback.release())); |
80 return true; | 80 return true; |
81 } | 81 } |
82 | 82 |
83 void PipelineImpl::Stop(PipelineCallback* stop_callback) { | 83 void PipelineImpl::Stop(PipelineCallback* stop_callback) { |
84 AutoLock auto_lock(lock_); | 84 base::AutoLock auto_lock(lock_); |
85 scoped_ptr<PipelineCallback> callback(stop_callback); | 85 scoped_ptr<PipelineCallback> callback(stop_callback); |
86 if (!running_) { | 86 if (!running_) { |
87 VLOG(1) << "Media pipeline has already stopped"; | 87 VLOG(1) << "Media pipeline has already stopped"; |
88 return; | 88 return; |
89 } | 89 } |
90 | 90 |
91 // Stop the pipeline, which will set |running_| to false on behalf. | 91 // Stop the pipeline, which will set |running_| to false on behalf. |
92 message_loop_->PostTask(FROM_HERE, | 92 message_loop_->PostTask(FROM_HERE, |
93 NewRunnableMethod(this, &PipelineImpl::StopTask, callback.release())); | 93 NewRunnableMethod(this, &PipelineImpl::StopTask, callback.release())); |
94 } | 94 } |
95 | 95 |
96 void PipelineImpl::Seek(base::TimeDelta time, | 96 void PipelineImpl::Seek(base::TimeDelta time, |
97 PipelineCallback* seek_callback) { | 97 PipelineCallback* seek_callback) { |
98 AutoLock auto_lock(lock_); | 98 base::AutoLock auto_lock(lock_); |
99 scoped_ptr<PipelineCallback> callback(seek_callback); | 99 scoped_ptr<PipelineCallback> callback(seek_callback); |
100 if (!running_) { | 100 if (!running_) { |
101 VLOG(1) << "Media pipeline must be running"; | 101 VLOG(1) << "Media pipeline must be running"; |
102 return; | 102 return; |
103 } | 103 } |
104 | 104 |
105 message_loop_->PostTask(FROM_HERE, | 105 message_loop_->PostTask(FROM_HERE, |
106 NewRunnableMethod(this, &PipelineImpl::SeekTask, time, | 106 NewRunnableMethod(this, &PipelineImpl::SeekTask, time, |
107 callback.release())); | 107 callback.release())); |
108 } | 108 } |
109 | 109 |
110 bool PipelineImpl::IsRunning() const { | 110 bool PipelineImpl::IsRunning() const { |
111 AutoLock auto_lock(lock_); | 111 base::AutoLock auto_lock(lock_); |
112 return running_; | 112 return running_; |
113 } | 113 } |
114 | 114 |
115 bool PipelineImpl::IsInitialized() const { | 115 bool PipelineImpl::IsInitialized() const { |
116 // TODO(scherkus): perhaps replace this with a bool that is set/get under the | 116 // TODO(scherkus): perhaps replace this with a bool that is set/get under the |
117 // lock, because this is breaching the contract that |state_| is only accessed | 117 // lock, because this is breaching the contract that |state_| is only accessed |
118 // on |message_loop_|. | 118 // on |message_loop_|. |
119 AutoLock auto_lock(lock_); | 119 base::AutoLock auto_lock(lock_); |
120 switch (state_) { | 120 switch (state_) { |
121 case kPausing: | 121 case kPausing: |
122 case kFlushing: | 122 case kFlushing: |
123 case kSeeking: | 123 case kSeeking: |
124 case kStarting: | 124 case kStarting: |
125 case kStarted: | 125 case kStarted: |
126 case kEnded: | 126 case kEnded: |
127 return true; | 127 return true; |
128 default: | 128 default: |
129 return false; | 129 return false; |
130 } | 130 } |
131 } | 131 } |
132 | 132 |
133 bool PipelineImpl::IsNetworkActive() const { | 133 bool PipelineImpl::IsNetworkActive() const { |
134 AutoLock auto_lock(lock_); | 134 base::AutoLock auto_lock(lock_); |
135 return network_activity_; | 135 return network_activity_; |
136 } | 136 } |
137 | 137 |
138 bool PipelineImpl::IsRendered(const std::string& major_mime_type) const { | 138 bool PipelineImpl::IsRendered(const std::string& major_mime_type) const { |
139 AutoLock auto_lock(lock_); | 139 base::AutoLock auto_lock(lock_); |
140 bool is_rendered = (rendered_mime_types_.find(major_mime_type) != | 140 bool is_rendered = (rendered_mime_types_.find(major_mime_type) != |
141 rendered_mime_types_.end()); | 141 rendered_mime_types_.end()); |
142 return is_rendered; | 142 return is_rendered; |
143 } | 143 } |
144 | 144 |
145 float PipelineImpl::GetPlaybackRate() const { | 145 float PipelineImpl::GetPlaybackRate() const { |
146 AutoLock auto_lock(lock_); | 146 base::AutoLock auto_lock(lock_); |
147 return playback_rate_; | 147 return playback_rate_; |
148 } | 148 } |
149 | 149 |
150 void PipelineImpl::SetPlaybackRate(float playback_rate) { | 150 void PipelineImpl::SetPlaybackRate(float playback_rate) { |
151 if (playback_rate < 0.0f) { | 151 if (playback_rate < 0.0f) { |
152 return; | 152 return; |
153 } | 153 } |
154 | 154 |
155 AutoLock auto_lock(lock_); | 155 base::AutoLock auto_lock(lock_); |
156 playback_rate_ = playback_rate; | 156 playback_rate_ = playback_rate; |
157 if (running_) { | 157 if (running_) { |
158 message_loop_->PostTask(FROM_HERE, | 158 message_loop_->PostTask(FROM_HERE, |
159 NewRunnableMethod(this, &PipelineImpl::PlaybackRateChangedTask, | 159 NewRunnableMethod(this, &PipelineImpl::PlaybackRateChangedTask, |
160 playback_rate)); | 160 playback_rate)); |
161 } | 161 } |
162 } | 162 } |
163 | 163 |
164 float PipelineImpl::GetVolume() const { | 164 float PipelineImpl::GetVolume() const { |
165 AutoLock auto_lock(lock_); | 165 base::AutoLock auto_lock(lock_); |
166 return volume_; | 166 return volume_; |
167 } | 167 } |
168 | 168 |
169 void PipelineImpl::SetVolume(float volume) { | 169 void PipelineImpl::SetVolume(float volume) { |
170 if (volume < 0.0f || volume > 1.0f) { | 170 if (volume < 0.0f || volume > 1.0f) { |
171 return; | 171 return; |
172 } | 172 } |
173 | 173 |
174 AutoLock auto_lock(lock_); | 174 base::AutoLock auto_lock(lock_); |
175 volume_ = volume; | 175 volume_ = volume; |
176 if (running_) { | 176 if (running_) { |
177 message_loop_->PostTask(FROM_HERE, | 177 message_loop_->PostTask(FROM_HERE, |
178 NewRunnableMethod(this, &PipelineImpl::VolumeChangedTask, | 178 NewRunnableMethod(this, &PipelineImpl::VolumeChangedTask, |
179 volume)); | 179 volume)); |
180 } | 180 } |
181 } | 181 } |
182 | 182 |
183 base::TimeDelta PipelineImpl::GetCurrentTime() const { | 183 base::TimeDelta PipelineImpl::GetCurrentTime() const { |
184 // TODO(scherkus): perhaps replace checking state_ == kEnded with a bool that | 184 // TODO(scherkus): perhaps replace checking state_ == kEnded with a bool that |
185 // is set/get under the lock, because this is breaching the contract that | 185 // is set/get under the lock, because this is breaching the contract that |
186 // |state_| is only accessed on |message_loop_|. | 186 // |state_| is only accessed on |message_loop_|. |
187 AutoLock auto_lock(lock_); | 187 base::AutoLock auto_lock(lock_); |
188 return GetCurrentTime_Locked(); | 188 return GetCurrentTime_Locked(); |
189 } | 189 } |
190 | 190 |
191 base::TimeDelta PipelineImpl::GetCurrentTime_Locked() const { | 191 base::TimeDelta PipelineImpl::GetCurrentTime_Locked() const { |
192 base::TimeDelta elapsed = clock_->Elapsed(); | 192 base::TimeDelta elapsed = clock_->Elapsed(); |
193 if (state_ == kEnded || elapsed > duration_) { | 193 if (state_ == kEnded || elapsed > duration_) { |
194 return duration_; | 194 return duration_; |
195 } | 195 } |
196 return elapsed; | 196 return elapsed; |
197 } | 197 } |
198 | 198 |
199 base::TimeDelta PipelineImpl::GetBufferedTime() { | 199 base::TimeDelta PipelineImpl::GetBufferedTime() { |
200 AutoLock auto_lock(lock_); | 200 base::AutoLock auto_lock(lock_); |
201 | 201 |
202 // If media is fully loaded, then return duration. | 202 // If media is fully loaded, then return duration. |
203 if (loaded_ || total_bytes_ == buffered_bytes_) { | 203 if (loaded_ || total_bytes_ == buffered_bytes_) { |
204 max_buffered_time_ = duration_; | 204 max_buffered_time_ = duration_; |
205 return duration_; | 205 return duration_; |
206 } | 206 } |
207 | 207 |
208 base::TimeDelta current_time = GetCurrentTime_Locked(); | 208 base::TimeDelta current_time = GetCurrentTime_Locked(); |
209 | 209 |
210 // If buffered time was set, we report that value directly. | 210 // If buffered time was set, we report that value directly. |
(...skipping 19 matching lines...) Expand all Loading... |
230 // Make sure buffered_time is at least the current time | 230 // Make sure buffered_time is at least the current time |
231 buffered_time = std::max(buffered_time, current_time); | 231 buffered_time = std::max(buffered_time, current_time); |
232 | 232 |
233 // Only print the max buffered time for smooth buffering. | 233 // Only print the max buffered time for smooth buffering. |
234 max_buffered_time_ = std::max(buffered_time, max_buffered_time_); | 234 max_buffered_time_ = std::max(buffered_time, max_buffered_time_); |
235 | 235 |
236 return max_buffered_time_; | 236 return max_buffered_time_; |
237 } | 237 } |
238 | 238 |
239 base::TimeDelta PipelineImpl::GetMediaDuration() const { | 239 base::TimeDelta PipelineImpl::GetMediaDuration() const { |
240 AutoLock auto_lock(lock_); | 240 base::AutoLock auto_lock(lock_); |
241 return duration_; | 241 return duration_; |
242 } | 242 } |
243 | 243 |
244 int64 PipelineImpl::GetBufferedBytes() const { | 244 int64 PipelineImpl::GetBufferedBytes() const { |
245 AutoLock auto_lock(lock_); | 245 base::AutoLock auto_lock(lock_); |
246 return buffered_bytes_; | 246 return buffered_bytes_; |
247 } | 247 } |
248 | 248 |
249 int64 PipelineImpl::GetTotalBytes() const { | 249 int64 PipelineImpl::GetTotalBytes() const { |
250 AutoLock auto_lock(lock_); | 250 base::AutoLock auto_lock(lock_); |
251 return total_bytes_; | 251 return total_bytes_; |
252 } | 252 } |
253 | 253 |
254 void PipelineImpl::GetVideoSize(size_t* width_out, size_t* height_out) const { | 254 void PipelineImpl::GetVideoSize(size_t* width_out, size_t* height_out) const { |
255 CHECK(width_out); | 255 CHECK(width_out); |
256 CHECK(height_out); | 256 CHECK(height_out); |
257 AutoLock auto_lock(lock_); | 257 base::AutoLock auto_lock(lock_); |
258 *width_out = video_width_; | 258 *width_out = video_width_; |
259 *height_out = video_height_; | 259 *height_out = video_height_; |
260 } | 260 } |
261 | 261 |
262 bool PipelineImpl::IsStreaming() const { | 262 bool PipelineImpl::IsStreaming() const { |
263 AutoLock auto_lock(lock_); | 263 base::AutoLock auto_lock(lock_); |
264 return streaming_; | 264 return streaming_; |
265 } | 265 } |
266 | 266 |
267 bool PipelineImpl::IsLoaded() const { | 267 bool PipelineImpl::IsLoaded() const { |
268 AutoLock auto_lock(lock_); | 268 base::AutoLock auto_lock(lock_); |
269 return loaded_; | 269 return loaded_; |
270 } | 270 } |
271 | 271 |
272 PipelineError PipelineImpl::GetError() const { | 272 PipelineError PipelineImpl::GetError() const { |
273 AutoLock auto_lock(lock_); | 273 base::AutoLock auto_lock(lock_); |
274 return error_; | 274 return error_; |
275 } | 275 } |
276 | 276 |
277 void PipelineImpl::SetCurrentReadPosition(int64 offset) { | 277 void PipelineImpl::SetCurrentReadPosition(int64 offset) { |
278 AutoLock auto_lock(lock_); | 278 base::AutoLock auto_lock(lock_); |
279 | 279 |
280 // The current read position should never be ahead of the buffered byte | 280 // The current read position should never be ahead of the buffered byte |
281 // position but threading issues between BufferedDataSource::DoneRead_Locked() | 281 // position but threading issues between BufferedDataSource::DoneRead_Locked() |
282 // and BufferedDataSource::NetworkEventCallback() can cause them to be | 282 // and BufferedDataSource::NetworkEventCallback() can cause them to be |
283 // temporarily out of sync. The easiest fix for this is to cap both | 283 // temporarily out of sync. The easiest fix for this is to cap both |
284 // buffered_bytes_ and current_bytes_ to always be legal values in | 284 // buffered_bytes_ and current_bytes_ to always be legal values in |
285 // SetCurrentReadPosition() and in SetBufferedBytes(). | 285 // SetCurrentReadPosition() and in SetBufferedBytes(). |
286 if (offset > buffered_bytes_) | 286 if (offset > buffered_bytes_) |
287 buffered_bytes_ = offset; | 287 buffered_bytes_ = offset; |
288 current_bytes_ = offset; | 288 current_bytes_ = offset; |
289 } | 289 } |
290 | 290 |
291 int64 PipelineImpl::GetCurrentReadPosition() { | 291 int64 PipelineImpl::GetCurrentReadPosition() { |
292 AutoLock auto_lock(lock_); | 292 base::AutoLock auto_lock(lock_); |
293 return current_bytes_; | 293 return current_bytes_; |
294 } | 294 } |
295 | 295 |
296 void PipelineImpl::ResetState() { | 296 void PipelineImpl::ResetState() { |
297 AutoLock auto_lock(lock_); | 297 base::AutoLock auto_lock(lock_); |
298 const base::TimeDelta kZero; | 298 const base::TimeDelta kZero; |
299 running_ = false; | 299 running_ = false; |
300 stop_pending_ = false; | 300 stop_pending_ = false; |
301 seek_pending_ = false; | 301 seek_pending_ = false; |
302 tearing_down_ = false; | 302 tearing_down_ = false; |
303 duration_ = kZero; | 303 duration_ = kZero; |
304 buffered_time_ = kZero; | 304 buffered_time_ = kZero; |
305 buffered_bytes_ = 0; | 305 buffered_bytes_ = 0; |
306 streaming_ = false; | 306 streaming_ = false; |
307 loaded_ = false; | 307 loaded_ = false; |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
413 return GetCurrentTime(); | 413 return GetCurrentTime(); |
414 } | 414 } |
415 | 415 |
416 base::TimeDelta PipelineImpl::GetDuration() const { | 416 base::TimeDelta PipelineImpl::GetDuration() const { |
417 DCHECK(IsRunning()); | 417 DCHECK(IsRunning()); |
418 return GetMediaDuration(); | 418 return GetMediaDuration(); |
419 } | 419 } |
420 | 420 |
421 void PipelineImpl::SetTime(base::TimeDelta time) { | 421 void PipelineImpl::SetTime(base::TimeDelta time) { |
422 DCHECK(IsRunning()); | 422 DCHECK(IsRunning()); |
423 AutoLock auto_lock(lock_); | 423 base::AutoLock auto_lock(lock_); |
424 | 424 |
425 // If we were waiting for a valid timestamp and such timestamp arrives, we | 425 // If we were waiting for a valid timestamp and such timestamp arrives, we |
426 // need to clear the flag for waiting and start the clock. | 426 // need to clear the flag for waiting and start the clock. |
427 if (waiting_for_clock_update_) { | 427 if (waiting_for_clock_update_) { |
428 if (time < clock_->Elapsed()) | 428 if (time < clock_->Elapsed()) |
429 return; | 429 return; |
430 waiting_for_clock_update_ = false; | 430 waiting_for_clock_update_ = false; |
431 clock_->SetTime(time); | 431 clock_->SetTime(time); |
432 clock_->Play(); | 432 clock_->Play(); |
433 return; | 433 return; |
434 } | 434 } |
435 clock_->SetTime(time); | 435 clock_->SetTime(time); |
436 } | 436 } |
437 | 437 |
438 void PipelineImpl::SetDuration(base::TimeDelta duration) { | 438 void PipelineImpl::SetDuration(base::TimeDelta duration) { |
439 DCHECK(IsRunning()); | 439 DCHECK(IsRunning()); |
440 AutoLock auto_lock(lock_); | 440 base::AutoLock auto_lock(lock_); |
441 duration_ = duration; | 441 duration_ = duration; |
442 } | 442 } |
443 | 443 |
444 void PipelineImpl::SetBufferedTime(base::TimeDelta buffered_time) { | 444 void PipelineImpl::SetBufferedTime(base::TimeDelta buffered_time) { |
445 DCHECK(IsRunning()); | 445 DCHECK(IsRunning()); |
446 AutoLock auto_lock(lock_); | 446 base::AutoLock auto_lock(lock_); |
447 buffered_time_ = buffered_time; | 447 buffered_time_ = buffered_time; |
448 } | 448 } |
449 | 449 |
450 void PipelineImpl::SetTotalBytes(int64 total_bytes) { | 450 void PipelineImpl::SetTotalBytes(int64 total_bytes) { |
451 DCHECK(IsRunning()); | 451 DCHECK(IsRunning()); |
452 AutoLock auto_lock(lock_); | 452 base::AutoLock auto_lock(lock_); |
453 total_bytes_ = total_bytes; | 453 total_bytes_ = total_bytes; |
454 } | 454 } |
455 | 455 |
456 void PipelineImpl::SetBufferedBytes(int64 buffered_bytes) { | 456 void PipelineImpl::SetBufferedBytes(int64 buffered_bytes) { |
457 DCHECK(IsRunning()); | 457 DCHECK(IsRunning()); |
458 AutoLock auto_lock(lock_); | 458 base::AutoLock auto_lock(lock_); |
459 | 459 |
460 // See comments in SetCurrentReadPosition() about capping. | 460 // See comments in SetCurrentReadPosition() about capping. |
461 if (buffered_bytes < current_bytes_) | 461 if (buffered_bytes < current_bytes_) |
462 current_bytes_ = buffered_bytes; | 462 current_bytes_ = buffered_bytes; |
463 buffered_bytes_ = buffered_bytes; | 463 buffered_bytes_ = buffered_bytes; |
464 } | 464 } |
465 | 465 |
466 void PipelineImpl::SetVideoSize(size_t width, size_t height) { | 466 void PipelineImpl::SetVideoSize(size_t width, size_t height) { |
467 DCHECK(IsRunning()); | 467 DCHECK(IsRunning()); |
468 AutoLock auto_lock(lock_); | 468 base::AutoLock auto_lock(lock_); |
469 video_width_ = width; | 469 video_width_ = width; |
470 video_height_ = height; | 470 video_height_ = height; |
471 } | 471 } |
472 | 472 |
473 void PipelineImpl::SetStreaming(bool streaming) { | 473 void PipelineImpl::SetStreaming(bool streaming) { |
474 DCHECK(IsRunning()); | 474 DCHECK(IsRunning()); |
475 AutoLock auto_lock(lock_); | 475 base::AutoLock auto_lock(lock_); |
476 streaming_ = streaming; | 476 streaming_ = streaming; |
477 } | 477 } |
478 | 478 |
479 void PipelineImpl::NotifyEnded() { | 479 void PipelineImpl::NotifyEnded() { |
480 DCHECK(IsRunning()); | 480 DCHECK(IsRunning()); |
481 message_loop_->PostTask(FROM_HERE, | 481 message_loop_->PostTask(FROM_HERE, |
482 NewRunnableMethod(this, &PipelineImpl::NotifyEndedTask)); | 482 NewRunnableMethod(this, &PipelineImpl::NotifyEndedTask)); |
483 } | 483 } |
484 | 484 |
485 void PipelineImpl::SetLoaded(bool loaded) { | 485 void PipelineImpl::SetLoaded(bool loaded) { |
486 DCHECK(IsRunning()); | 486 DCHECK(IsRunning()); |
487 AutoLock auto_lock(lock_); | 487 base::AutoLock auto_lock(lock_); |
488 loaded_ = loaded; | 488 loaded_ = loaded; |
489 } | 489 } |
490 | 490 |
491 void PipelineImpl::SetNetworkActivity(bool network_activity) { | 491 void PipelineImpl::SetNetworkActivity(bool network_activity) { |
492 DCHECK(IsRunning()); | 492 DCHECK(IsRunning()); |
493 { | 493 { |
494 AutoLock auto_lock(lock_); | 494 base::AutoLock auto_lock(lock_); |
495 network_activity_ = network_activity; | 495 network_activity_ = network_activity; |
496 } | 496 } |
497 message_loop_->PostTask(FROM_HERE, | 497 message_loop_->PostTask(FROM_HERE, |
498 NewRunnableMethod(this, &PipelineImpl::NotifyNetworkEventTask)); | 498 NewRunnableMethod(this, &PipelineImpl::NotifyNetworkEventTask)); |
499 } | 499 } |
500 | 500 |
501 void PipelineImpl::DisableAudioRenderer() { | 501 void PipelineImpl::DisableAudioRenderer() { |
502 DCHECK(IsRunning()); | 502 DCHECK(IsRunning()); |
503 | 503 |
504 // Disable renderer on the message loop. | 504 // Disable renderer on the message loop. |
505 message_loop_->PostTask(FROM_HERE, | 505 message_loop_->PostTask(FROM_HERE, |
506 NewRunnableMethod(this, &PipelineImpl::DisableAudioRendererTask)); | 506 NewRunnableMethod(this, &PipelineImpl::DisableAudioRendererTask)); |
507 } | 507 } |
508 | 508 |
509 void PipelineImpl::InsertRenderedMimeType(const std::string& major_mime_type) { | 509 void PipelineImpl::InsertRenderedMimeType(const std::string& major_mime_type) { |
510 DCHECK(IsRunning()); | 510 DCHECK(IsRunning()); |
511 AutoLock auto_lock(lock_); | 511 base::AutoLock auto_lock(lock_); |
512 rendered_mime_types_.insert(major_mime_type); | 512 rendered_mime_types_.insert(major_mime_type); |
513 } | 513 } |
514 | 514 |
515 bool PipelineImpl::HasRenderedMimeTypes() const { | 515 bool PipelineImpl::HasRenderedMimeTypes() const { |
516 DCHECK(IsRunning()); | 516 DCHECK(IsRunning()); |
517 AutoLock auto_lock(lock_); | 517 base::AutoLock auto_lock(lock_); |
518 return !rendered_mime_types_.empty(); | 518 return !rendered_mime_types_.empty(); |
519 } | 519 } |
520 | 520 |
521 // Called from any thread. | 521 // Called from any thread. |
522 void PipelineImpl::OnFilterInitialize() { | 522 void PipelineImpl::OnFilterInitialize() { |
523 // Continue the initialize task by proceeding to the next stage. | 523 // Continue the initialize task by proceeding to the next stage. |
524 message_loop_->PostTask(FROM_HERE, | 524 message_loop_->PostTask(FROM_HERE, |
525 NewRunnableMethod(this, &PipelineImpl::InitializeTask)); | 525 NewRunnableMethod(this, &PipelineImpl::InitializeTask)); |
526 } | 526 } |
527 | 527 |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 PipelineError error = GetError(); | 673 PipelineError error = GetError(); |
674 | 674 |
675 if (state_ == kStopped || (IsPipelineStopPending() && error == PIPELINE_OK)) { | 675 if (state_ == kStopped || (IsPipelineStopPending() && error == PIPELINE_OK)) { |
676 // If we are already stopped or stopping normally, return immediately. | 676 // If we are already stopped or stopping normally, return immediately. |
677 delete stop_callback; | 677 delete stop_callback; |
678 return; | 678 return; |
679 } else if (state_ == kError || | 679 } else if (state_ == kError || |
680 (IsPipelineStopPending() && error != PIPELINE_OK)) { | 680 (IsPipelineStopPending() && error != PIPELINE_OK)) { |
681 // If we are stopping due to SetError(), stop normally instead of | 681 // If we are stopping due to SetError(), stop normally instead of |
682 // going to error state. | 682 // going to error state. |
683 AutoLock auto_lock(lock_); | 683 base::AutoLock auto_lock(lock_); |
684 error_ = PIPELINE_OK; | 684 error_ = PIPELINE_OK; |
685 } | 685 } |
686 | 686 |
687 stop_callback_.reset(stop_callback); | 687 stop_callback_.reset(stop_callback); |
688 | 688 |
689 stop_pending_ = true; | 689 stop_pending_ = true; |
690 if (!IsPipelineSeeking()) { | 690 if (!IsPipelineSeeking()) { |
691 // We will tear down pipeline immediately when there is no seek operation | 691 // We will tear down pipeline immediately when there is no seek operation |
692 // pending. This should include the case where we are partially initialized. | 692 // pending. This should include the case where we are partially initialized. |
693 // Ideally this case should use SetError() rather than Stop() to tear down. | 693 // Ideally this case should use SetError() rather than Stop() to tear down. |
694 DCHECK(!IsPipelineTearingDown()); | 694 DCHECK(!IsPipelineTearingDown()); |
695 TearDownPipeline(); | 695 TearDownPipeline(); |
696 } | 696 } |
697 } | 697 } |
698 | 698 |
699 void PipelineImpl::ErrorChangedTask(PipelineError error) { | 699 void PipelineImpl::ErrorChangedTask(PipelineError error) { |
700 DCHECK_EQ(MessageLoop::current(), message_loop_); | 700 DCHECK_EQ(MessageLoop::current(), message_loop_); |
701 DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!"; | 701 DCHECK_NE(PIPELINE_OK, error) << "PIPELINE_OK isn't an error!"; |
702 | 702 |
703 // Suppress executing additional error logic. Note that if we are currently | 703 // Suppress executing additional error logic. Note that if we are currently |
704 // performing a normal stop, then we return immediately and continue the | 704 // performing a normal stop, then we return immediately and continue the |
705 // normal stop. | 705 // normal stop. |
706 if (IsPipelineStopped() || IsPipelineTearingDown()) { | 706 if (IsPipelineStopped() || IsPipelineTearingDown()) { |
707 return; | 707 return; |
708 } | 708 } |
709 | 709 |
710 AutoLock auto_lock(lock_); | 710 base::AutoLock auto_lock(lock_); |
711 error_ = error; | 711 error_ = error; |
712 | 712 |
713 TearDownPipeline(); | 713 TearDownPipeline(); |
714 } | 714 } |
715 | 715 |
716 void PipelineImpl::PlaybackRateChangedTask(float playback_rate) { | 716 void PipelineImpl::PlaybackRateChangedTask(float playback_rate) { |
717 DCHECK_EQ(MessageLoop::current(), message_loop_); | 717 DCHECK_EQ(MessageLoop::current(), message_loop_); |
718 { | 718 { |
719 AutoLock auto_lock(lock_); | 719 base::AutoLock auto_lock(lock_); |
720 clock_->SetPlaybackRate(playback_rate); | 720 clock_->SetPlaybackRate(playback_rate); |
721 } | 721 } |
722 | 722 |
723 // Notify |pipeline_filter_| if it has been initialized. If initialization | 723 // Notify |pipeline_filter_| if it has been initialized. If initialization |
724 // hasn't completed yet, the playback rate will be set when initialization | 724 // hasn't completed yet, the playback rate will be set when initialization |
725 // completes. | 725 // completes. |
726 if (pipeline_filter_) { | 726 if (pipeline_filter_) { |
727 pipeline_filter_->SetPlaybackRate(playback_rate); | 727 pipeline_filter_->SetPlaybackRate(playback_rate); |
728 } | 728 } |
729 } | 729 } |
(...skipping 30 matching lines...) Expand all Loading... |
760 // kPausing (for each filter) | 760 // kPausing (for each filter) |
761 // kSeeking (for each filter) | 761 // kSeeking (for each filter) |
762 // kStarting (for each filter) | 762 // kStarting (for each filter) |
763 // kStarted | 763 // kStarted |
764 set_state(kPausing); | 764 set_state(kPausing); |
765 seek_timestamp_ = time; | 765 seek_timestamp_ = time; |
766 seek_callback_.reset(seek_callback); | 766 seek_callback_.reset(seek_callback); |
767 | 767 |
768 // Kick off seeking! | 768 // Kick off seeking! |
769 { | 769 { |
770 AutoLock auto_lock(lock_); | 770 base::AutoLock auto_lock(lock_); |
771 // If we are waiting for a clock update, the clock hasn't been played yet. | 771 // If we are waiting for a clock update, the clock hasn't been played yet. |
772 if (!waiting_for_clock_update_) | 772 if (!waiting_for_clock_update_) |
773 clock_->Pause(); | 773 clock_->Pause(); |
774 } | 774 } |
775 pipeline_filter_->Pause( | 775 pipeline_filter_->Pause( |
776 NewCallback(this, &PipelineImpl::OnFilterStateTransition)); | 776 NewCallback(this, &PipelineImpl::OnFilterStateTransition)); |
777 } | 777 } |
778 | 778 |
779 void PipelineImpl::NotifyEndedTask() { | 779 void PipelineImpl::NotifyEndedTask() { |
780 DCHECK_EQ(MessageLoop::current(), message_loop_); | 780 DCHECK_EQ(MessageLoop::current(), message_loop_); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
816 if (network_callback_.get()) { | 816 if (network_callback_.get()) { |
817 network_callback_->Run(); | 817 network_callback_->Run(); |
818 } | 818 } |
819 } | 819 } |
820 | 820 |
821 void PipelineImpl::DisableAudioRendererTask() { | 821 void PipelineImpl::DisableAudioRendererTask() { |
822 DCHECK_EQ(MessageLoop::current(), message_loop_); | 822 DCHECK_EQ(MessageLoop::current(), message_loop_); |
823 | 823 |
824 // |rendered_mime_types_| is read through public methods so we need to lock | 824 // |rendered_mime_types_| is read through public methods so we need to lock |
825 // this variable. | 825 // this variable. |
826 AutoLock auto_lock(lock_); | 826 base::AutoLock auto_lock(lock_); |
827 rendered_mime_types_.erase(mime_type::kMajorTypeAudio); | 827 rendered_mime_types_.erase(mime_type::kMajorTypeAudio); |
828 | 828 |
829 audio_disabled_ = true; | 829 audio_disabled_ = true; |
830 | 830 |
831 // Notify all filters of disabled audio renderer. If the filter isn't | 831 // Notify all filters of disabled audio renderer. If the filter isn't |
832 // initialized yet, OnAudioRendererDisabled() will be called when | 832 // initialized yet, OnAudioRendererDisabled() will be called when |
833 // initialization is complete. | 833 // initialization is complete. |
834 if (pipeline_filter_) { | 834 if (pipeline_filter_) { |
835 pipeline_filter_->OnAudioRendererDisabled(); | 835 pipeline_filter_->OnAudioRendererDisabled(); |
836 } | 836 } |
(...skipping 10 matching lines...) Expand all Loading... |
847 if (!TransientState(state_)) { | 847 if (!TransientState(state_)) { |
848 NOTREACHED() << "Invalid current state: " << state_; | 848 NOTREACHED() << "Invalid current state: " << state_; |
849 SetError(PIPELINE_ERROR_ABORT); | 849 SetError(PIPELINE_ERROR_ABORT); |
850 return; | 850 return; |
851 } | 851 } |
852 | 852 |
853 // Decrement the number of remaining transitions, making sure to transition | 853 // Decrement the number of remaining transitions, making sure to transition |
854 // to the next state if needed. | 854 // to the next state if needed. |
855 set_state(FindNextState(state_)); | 855 set_state(FindNextState(state_)); |
856 if (state_ == kSeeking) { | 856 if (state_ == kSeeking) { |
857 AutoLock auto_lock(lock_); | 857 base::AutoLock auto_lock(lock_); |
858 clock_->SetTime(seek_timestamp_); | 858 clock_->SetTime(seek_timestamp_); |
859 } | 859 } |
860 | 860 |
861 // Carry out the action for the current state. | 861 // Carry out the action for the current state. |
862 if (TransientState(state_)) { | 862 if (TransientState(state_)) { |
863 if (state_ == kPausing) { | 863 if (state_ == kPausing) { |
864 pipeline_filter_->Pause( | 864 pipeline_filter_->Pause( |
865 NewCallback(this, &PipelineImpl::OnFilterStateTransition)); | 865 NewCallback(this, &PipelineImpl::OnFilterStateTransition)); |
866 } else if (state_ == kFlushing) { | 866 } else if (state_ == kFlushing) { |
867 pipeline_filter_->Flush( | 867 pipeline_filter_->Flush( |
(...skipping 10 matching lines...) Expand all Loading... |
878 } else { | 878 } else { |
879 NOTREACHED() << "Unexpected state: " << state_; | 879 NOTREACHED() << "Unexpected state: " << state_; |
880 } | 880 } |
881 } else if (state_ == kStarted) { | 881 } else if (state_ == kStarted) { |
882 FinishInitialization(); | 882 FinishInitialization(); |
883 | 883 |
884 // Finally, reset our seeking timestamp back to zero. | 884 // Finally, reset our seeking timestamp back to zero. |
885 seek_timestamp_ = base::TimeDelta(); | 885 seek_timestamp_ = base::TimeDelta(); |
886 seek_pending_ = false; | 886 seek_pending_ = false; |
887 | 887 |
888 AutoLock auto_lock(lock_); | 888 base::AutoLock auto_lock(lock_); |
889 // We use audio stream to update the clock. So if there is such a stream, | 889 // We use audio stream to update the clock. So if there is such a stream, |
890 // we pause the clock until we receive a valid timestamp. | 890 // we pause the clock until we receive a valid timestamp. |
891 waiting_for_clock_update_ = | 891 waiting_for_clock_update_ = |
892 rendered_mime_types_.find(mime_type::kMajorTypeAudio) != | 892 rendered_mime_types_.find(mime_type::kMajorTypeAudio) != |
893 rendered_mime_types_.end(); | 893 rendered_mime_types_.end(); |
894 if (!waiting_for_clock_update_) | 894 if (!waiting_for_clock_update_) |
895 clock_->Play(); | 895 clock_->Play(); |
896 | 896 |
897 if (IsPipelineStopPending()) { | 897 if (IsPipelineStopPending()) { |
898 // We had a pending stop request need to be honored right now. | 898 // We had a pending stop request need to be honored right now. |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1134 pipeline_filter_->Pause(NewCallback( | 1134 pipeline_filter_->Pause(NewCallback( |
1135 this, &PipelineImpl::OnFilterStateTransition)); | 1135 this, &PipelineImpl::OnFilterStateTransition)); |
1136 } else { | 1136 } else { |
1137 set_state(kStopped); | 1137 set_state(kStopped); |
1138 message_loop_->PostTask(FROM_HERE, | 1138 message_loop_->PostTask(FROM_HERE, |
1139 NewRunnableMethod(this, &PipelineImpl::FinishDestroyingFiltersTask)); | 1139 NewRunnableMethod(this, &PipelineImpl::FinishDestroyingFiltersTask)); |
1140 } | 1140 } |
1141 } | 1141 } |
1142 | 1142 |
1143 } // namespace media | 1143 } // namespace media |
OLD | NEW |