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 "media/filters/chunk_demuxer.h" | 5 #include "media/filters/chunk_demuxer.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "media/base/audio_decoder_config.h" | 10 #include "media/base/audio_decoder_config.h" |
(...skipping 12 matching lines...) Expand all Loading... | |
23 class ChunkDemuxerStream : public DemuxerStream { | 23 class ChunkDemuxerStream : public DemuxerStream { |
24 public: | 24 public: |
25 typedef std::deque<scoped_refptr<Buffer> > BufferQueue; | 25 typedef std::deque<scoped_refptr<Buffer> > BufferQueue; |
26 typedef std::deque<ReadCallback> ReadCBQueue; | 26 typedef std::deque<ReadCallback> ReadCBQueue; |
27 | 27 |
28 explicit ChunkDemuxerStream(const AudioDecoderConfig& audio_config); | 28 explicit ChunkDemuxerStream(const AudioDecoderConfig& audio_config); |
29 explicit ChunkDemuxerStream(const VideoDecoderConfig& video_config); | 29 explicit ChunkDemuxerStream(const VideoDecoderConfig& video_config); |
30 virtual ~ChunkDemuxerStream(); | 30 virtual ~ChunkDemuxerStream(); |
31 | 31 |
32 void Flush(); | 32 void Flush(); |
33 void Seek(base::TimeDelta time); | |
33 | 34 |
34 // Checks if it is ok to add the |buffers| to the stream. | 35 // Checks if it is ok to add the |buffers| to the stream. |
35 bool CanAddBuffers(const BufferQueue& buffers) const; | 36 bool CanAddBuffers(const BufferQueue& buffers) const; |
36 | 37 |
37 void AddBuffers(const BufferQueue& buffers); | 38 void AddBuffers(const BufferQueue& buffers); |
38 void Shutdown(); | 39 void Shutdown(); |
39 | 40 |
40 bool GetLastBufferTimestamp(base::TimeDelta* timestamp) const; | 41 bool GetLastBufferTimestamp(base::TimeDelta* timestamp) const; |
41 | 42 |
42 // DemuxerStream methods. | 43 // DemuxerStream methods. |
43 virtual void Read(const ReadCallback& read_callback); | 44 virtual void Read(const ReadCallback& read_callback); |
Ami GONE FROM CHROMIUM
2012/01/27 23:44:58
How is this not breaking the clang bots, missing O
acolwell GONE FROM CHROMIUM
2012/01/29 03:00:41
Not sure. Fixed though.
| |
44 virtual Type type(); | 45 virtual Type type(); |
45 virtual void EnableBitstreamConverter(); | 46 virtual void EnableBitstreamConverter(); |
46 virtual const AudioDecoderConfig& audio_decoder_config(); | 47 virtual const AudioDecoderConfig& audio_decoder_config(); |
47 virtual const VideoDecoderConfig& video_decoder_config(); | 48 virtual const VideoDecoderConfig& video_decoder_config(); |
48 | 49 |
49 private: | 50 private: |
51 enum State { | |
52 PLAYING, | |
Ami GONE FROM CHROMIUM
2012/01/28 00:19:59
Oh, also, PLAYING is a terrible name ;)
NORMAL/STE
acolwell GONE FROM CHROMIUM
2012/01/29 03:00:41
Agreed. I've renamed all the states. I think they
| |
53 FLUSHED, | |
54 FLUSHED_END_OF_STREAM, | |
Ami GONE FROM CHROMIUM
2012/01/27 23:44:58
These names are not self-explanatory as to what th
acolwell GONE FROM CHROMIUM
2012/01/29 03:00:41
Done.
| |
55 RECEIVED_END_OF_STREAM, | |
56 END_OF_STREAM, | |
57 SHUTDOWN, | |
58 }; | |
59 | |
60 void ChangeState_Locked(State state); | |
Ami GONE FROM CHROMIUM
2012/01/27 23:44:58
Commentary here and below please.
acolwell GONE FROM CHROMIUM
2012/01/29 03:00:41
Done.
| |
61 void DeferRead_Locked(const ReadCallback& read_cb); | |
62 void CreateReadDoneClosures_Locked(std::deque<base::Closure>* closures); | |
63 | |
50 Type type_; | 64 Type type_; |
51 AudioDecoderConfig audio_config_; | 65 AudioDecoderConfig audio_config_; |
52 VideoDecoderConfig video_config_; | 66 VideoDecoderConfig video_config_; |
53 | 67 |
54 mutable base::Lock lock_; | 68 mutable base::Lock lock_; |
69 State state_; | |
55 ReadCBQueue read_cbs_; | 70 ReadCBQueue read_cbs_; |
56 BufferQueue buffers_; | 71 BufferQueue buffers_; |
57 bool shutdown_called_; | |
58 bool received_end_of_stream_; | |
59 | 72 |
60 // Keeps track of the timestamp of the last buffer we have | 73 // Keeps track of the timestamp of the last buffer we have |
61 // added to |buffers_|. This is used to enforce buffers with strictly | 74 // added to |buffers_|. This is used to enforce buffers with strictly |
62 // monotonically increasing timestamps. | 75 // monotonically increasing timestamps. |
63 base::TimeDelta last_buffer_timestamp_; | 76 base::TimeDelta last_buffer_timestamp_; |
64 | 77 |
65 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); | 78 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); |
66 }; | 79 }; |
67 | 80 |
68 ChunkDemuxerStream::ChunkDemuxerStream(const AudioDecoderConfig& audio_config) | 81 ChunkDemuxerStream::ChunkDemuxerStream(const AudioDecoderConfig& audio_config) |
69 : type_(AUDIO), | 82 : type_(AUDIO), |
70 shutdown_called_(false), | 83 state_(PLAYING), |
71 received_end_of_stream_(false), | |
72 last_buffer_timestamp_(kNoTimestamp()) { | 84 last_buffer_timestamp_(kNoTimestamp()) { |
73 audio_config_.CopyFrom(audio_config); | 85 audio_config_.CopyFrom(audio_config); |
74 } | 86 } |
75 | 87 |
76 | 88 |
77 ChunkDemuxerStream::ChunkDemuxerStream(const VideoDecoderConfig& video_config) | 89 ChunkDemuxerStream::ChunkDemuxerStream(const VideoDecoderConfig& video_config) |
78 : type_(VIDEO), | 90 : type_(VIDEO), |
79 shutdown_called_(false), | 91 state_(PLAYING), |
80 received_end_of_stream_(false), | |
81 last_buffer_timestamp_(kNoTimestamp()) { | 92 last_buffer_timestamp_(kNoTimestamp()) { |
82 video_config_.CopyFrom(video_config); | 93 video_config_.CopyFrom(video_config); |
83 } | 94 } |
84 | 95 |
85 ChunkDemuxerStream::~ChunkDemuxerStream() {} | 96 ChunkDemuxerStream::~ChunkDemuxerStream() {} |
86 | 97 |
87 void ChunkDemuxerStream::Flush() { | 98 void ChunkDemuxerStream::Flush() { |
88 DVLOG(1) << "Flush()"; | 99 DVLOG(1) << "Flush()"; |
100 std::deque<base::Closure> callbacks; | |
Ami GONE FROM CHROMIUM
2012/01/27 23:44:58
If you changed this to:
ReadCBQueue read_cbs;
and
acolwell GONE FROM CHROMIUM
2012/01/29 03:00:41
Done.
| |
101 { | |
102 base::AutoLock auto_lock(lock_); | |
103 buffers_.clear(); | |
104 ChangeState_Locked(FLUSHED); | |
105 last_buffer_timestamp_ = kNoTimestamp(); | |
106 | |
107 // Return null to all pending Read() callbacks to indicate that | |
108 // we are flushing. | |
109 while(!read_cbs_.empty()) { | |
110 callbacks.push_back(base::Bind(read_cbs_.front(), | |
111 scoped_refptr<Buffer>())); | |
112 read_cbs_.pop_front(); | |
113 } | |
114 } | |
115 | |
116 while (!callbacks.empty()) { | |
117 callbacks.front().Run(); | |
118 callbacks.pop_front(); | |
119 } | |
120 } | |
121 | |
122 void ChunkDemuxerStream::Seek(base::TimeDelta time) { | |
89 base::AutoLock auto_lock(lock_); | 123 base::AutoLock auto_lock(lock_); |
90 buffers_.clear(); | 124 |
91 received_end_of_stream_ = false; | 125 DCHECK(read_cbs_.empty()); |
92 last_buffer_timestamp_ = kNoTimestamp(); | 126 |
127 if (state_ == FLUSHED) { | |
128 ChangeState_Locked(PLAYING); | |
129 return; | |
130 } | |
131 | |
132 if (state_ == FLUSHED_END_OF_STREAM) { | |
133 ChangeState_Locked(RECEIVED_END_OF_STREAM); | |
134 return; | |
135 } | |
93 } | 136 } |
94 | 137 |
95 bool ChunkDemuxerStream::CanAddBuffers(const BufferQueue& buffers) const { | 138 bool ChunkDemuxerStream::CanAddBuffers(const BufferQueue& buffers) const { |
96 base::AutoLock auto_lock(lock_); | 139 base::AutoLock auto_lock(lock_); |
97 | 140 |
98 // If we haven't seen any buffers yet, then anything can be added. | 141 // If we haven't seen any buffers yet, then anything can be added. |
99 if (last_buffer_timestamp_ == kNoTimestamp()) | 142 if (last_buffer_timestamp_ == kNoTimestamp()) |
100 return true; | 143 return true; |
101 | 144 |
102 if (buffers.empty()) | 145 if (buffers.empty()) |
103 return true; | 146 return true; |
104 | 147 |
105 return (buffers.front()->GetTimestamp() > last_buffer_timestamp_); | 148 return (buffers.front()->GetTimestamp() > last_buffer_timestamp_); |
106 } | 149 } |
107 | 150 |
108 void ChunkDemuxerStream::AddBuffers(const BufferQueue& buffers) { | 151 void ChunkDemuxerStream::AddBuffers(const BufferQueue& buffers) { |
109 if (buffers.empty()) | 152 if (buffers.empty()) |
110 return; | 153 return; |
111 | 154 |
112 std::deque<base::Closure> callbacks; | 155 std::deque<base::Closure> callbacks; |
Ami GONE FROM CHROMIUM
2012/01/27 23:44:58
s/callbacks/closures/ ?
acolwell GONE FROM CHROMIUM
2012/01/29 03:00:41
Done.
| |
113 { | 156 { |
114 base::AutoLock auto_lock(lock_); | 157 base::AutoLock auto_lock(lock_); |
115 | 158 |
116 for (BufferQueue::const_iterator itr = buffers.begin(); | 159 for (BufferQueue::const_iterator itr = buffers.begin(); |
117 itr != buffers.end(); itr++) { | 160 itr != buffers.end(); itr++) { |
118 // Make sure we aren't trying to add a buffer after we have received and | 161 // Make sure we aren't trying to add a buffer after we have received and |
119 // "end of stream" buffer. | 162 // "end of stream" buffer. |
120 DCHECK(!received_end_of_stream_); | 163 DCHECK_NE(state_, FLUSHED_END_OF_STREAM); |
164 DCHECK_NE(state_, RECEIVED_END_OF_STREAM); | |
165 DCHECK_NE(state_, END_OF_STREAM); | |
121 | 166 |
122 if ((*itr)->IsEndOfStream()) { | 167 if ((*itr)->IsEndOfStream()) { |
123 received_end_of_stream_ = true; | 168 if (state_ == FLUSHED) { |
124 | 169 ChangeState_Locked(FLUSHED_END_OF_STREAM); |
125 // Push enough EOS buffers to satisfy outstanding Read() requests. | 170 } else { |
126 if (read_cbs_.size() > buffers_.size()) { | 171 ChangeState_Locked(RECEIVED_END_OF_STREAM); |
127 size_t pending_read_without_data = read_cbs_.size() - buffers_.size(); | |
128 for (size_t i = 0; i <= pending_read_without_data; ++i) { | |
129 buffers_.push_back(*itr); | |
130 } | |
131 } | 172 } |
132 } else { | 173 } else { |
133 base::TimeDelta current_ts = (*itr)->GetTimestamp(); | 174 base::TimeDelta current_ts = (*itr)->GetTimestamp(); |
134 if (last_buffer_timestamp_ != kNoTimestamp()) { | 175 if (last_buffer_timestamp_ != kNoTimestamp()) { |
135 DCHECK_GT(current_ts.ToInternalValue(), | 176 DCHECK_GT(current_ts.ToInternalValue(), |
136 last_buffer_timestamp_.ToInternalValue()); | 177 last_buffer_timestamp_.ToInternalValue()); |
137 } | 178 } |
138 | 179 |
139 last_buffer_timestamp_ = current_ts; | 180 last_buffer_timestamp_ = current_ts; |
140 buffers_.push_back(*itr); | 181 buffers_.push_back(*itr); |
141 } | 182 } |
142 } | 183 } |
143 | 184 |
144 while (!buffers_.empty() && !read_cbs_.empty()) { | 185 CreateReadDoneClosures_Locked(&callbacks); |
145 callbacks.push_back(base::Bind(read_cbs_.front(), buffers_.front())); | |
146 buffers_.pop_front(); | |
147 read_cbs_.pop_front(); | |
148 } | |
149 } | 186 } |
150 | 187 |
151 while (!callbacks.empty()) { | 188 while (!callbacks.empty()) { |
152 callbacks.front().Run(); | 189 callbacks.front().Run(); |
153 callbacks.pop_front(); | 190 callbacks.pop_front(); |
Ami GONE FROM CHROMIUM
2012/01/27 23:44:58
If you replace the piecewise pop_front() with a fi
acolwell GONE FROM CHROMIUM
2012/01/29 03:00:41
I don't follow. Replaced this with a for loop like
| |
154 } | 191 } |
155 } | 192 } |
156 | 193 |
157 void ChunkDemuxerStream::Shutdown() { | 194 void ChunkDemuxerStream::Shutdown() { |
158 std::deque<ReadCallback> callbacks; | 195 std::deque<ReadCallback> callbacks; |
159 { | 196 { |
160 base::AutoLock auto_lock(lock_); | 197 base::AutoLock auto_lock(lock_); |
161 shutdown_called_ = true; | 198 ChangeState_Locked(SHUTDOWN); |
162 | 199 |
163 // Collect all the pending Read() callbacks. | 200 // Collect all the pending Read() callbacks. |
164 while (!read_cbs_.empty()) { | 201 while (!read_cbs_.empty()) { |
Ami GONE FROM CHROMIUM
2012/01/27 23:44:58
std::swap()
acolwell GONE FROM CHROMIUM
2012/01/29 03:00:41
Done.
| |
165 callbacks.push_back(read_cbs_.front()); | 202 callbacks.push_back(read_cbs_.front()); |
166 read_cbs_.pop_front(); | 203 read_cbs_.pop_front(); |
167 } | 204 } |
205 | |
206 buffers_.clear(); | |
168 } | 207 } |
169 | 208 |
170 // Pass end of stream buffers to all callbacks to signal that no more data | 209 // Pass end of stream buffers to all callbacks to signal that no more data |
171 // will be sent. | 210 // will be sent. |
172 while (!callbacks.empty()) { | 211 while (!callbacks.empty()) { |
173 callbacks.front().Run(CreateEOSBuffer()); | 212 callbacks.front().Run(CreateEOSBuffer()); |
174 callbacks.pop_front(); | 213 callbacks.pop_front(); |
Ami GONE FROM CHROMIUM
2012/01/27 23:44:58
pop_front unnecessary
acolwell GONE FROM CHROMIUM
2012/01/29 03:00:41
Replaced with for loop.
| |
175 } | 214 } |
176 } | 215 } |
177 | 216 |
178 bool ChunkDemuxerStream::GetLastBufferTimestamp( | 217 bool ChunkDemuxerStream::GetLastBufferTimestamp( |
179 base::TimeDelta* timestamp) const { | 218 base::TimeDelta* timestamp) const { |
180 base::AutoLock auto_lock(lock_); | 219 base::AutoLock auto_lock(lock_); |
181 | 220 |
182 if (buffers_.empty()) | 221 if (buffers_.empty()) |
183 return false; | 222 return false; |
184 | 223 |
(...skipping 14 matching lines...) Expand all Loading... | |
199 read_callback.Run(buffer); | 238 read_callback.Run(buffer); |
200 } | 239 } |
201 | 240 |
202 // DemuxerStream methods. | 241 // DemuxerStream methods. |
203 void ChunkDemuxerStream::Read(const ReadCallback& read_callback) { | 242 void ChunkDemuxerStream::Read(const ReadCallback& read_callback) { |
204 scoped_refptr<Buffer> buffer; | 243 scoped_refptr<Buffer> buffer; |
205 | 244 |
206 { | 245 { |
207 base::AutoLock auto_lock(lock_); | 246 base::AutoLock auto_lock(lock_); |
208 | 247 |
209 if (shutdown_called_ || (received_end_of_stream_ && buffers_.empty())) { | 248 switch(state_) { |
210 buffer = CreateEOSBuffer(); | 249 case PLAYING: |
211 } else { | 250 // Satisfy the request immediately if we have a buffer and |
212 if (buffers_.empty()) { | 251 // no pending reads. |
213 // Wrap & store |read_callback| so that it will | 252 if (buffers_.empty() || !read_cbs_.empty()) { |
Ami GONE FROM CHROMIUM
2012/01/27 23:44:58
This test is the opposite of the comment, which I
acolwell GONE FROM CHROMIUM
2012/01/29 03:00:41
Done.
| |
214 // get called on the current MessageLoop. | 253 DeferRead_Locked(read_callback); |
215 read_cbs_.push_back(base::Bind(&RunOnMessageLoop, | 254 return; |
216 read_callback, | 255 } |
217 MessageLoop::current())); | 256 |
257 buffer = buffers_.front(); | |
258 buffers_.pop_front(); | |
259 break; | |
260 | |
261 case FLUSHED: | |
262 case FLUSHED_END_OF_STREAM: | |
Ami GONE FROM CHROMIUM
2012/01/27 23:44:58
Can these not be fall-throughs to the PLAYING case
acolwell GONE FROM CHROMIUM
2012/01/29 03:00:41
This was a bug. NULLs need to be immediately retur
| |
263 DeferRead_Locked(read_callback); | |
218 return; | 264 return; |
219 } | |
220 | 265 |
221 if (!read_cbs_.empty()) { | 266 case RECEIVED_END_OF_STREAM: |
222 // Wrap & store |read_callback| so that it will | 267 DCHECK(read_cbs_.empty()); |
223 // get called on the current MessageLoop. | |
224 read_cbs_.push_back(base::Bind(&RunOnMessageLoop, | |
225 read_callback, | |
226 MessageLoop::current())); | |
227 return; | |
228 } | |
229 | 268 |
230 buffer = buffers_.front(); | 269 if (buffers_.empty()) { |
231 buffers_.pop_front(); | 270 ChangeState_Locked(END_OF_STREAM); |
271 buffer = CreateEOSBuffer(); | |
272 } else { | |
273 buffer = buffers_.front(); | |
274 buffers_.pop_front(); | |
275 } | |
276 break; | |
277 | |
278 case END_OF_STREAM: | |
279 case SHUTDOWN: | |
280 DCHECK(buffers_.empty()); | |
281 DCHECK(read_cbs_.empty()); | |
282 buffer = CreateEOSBuffer(); | |
232 } | 283 } |
233 } | 284 } |
234 | 285 |
235 DCHECK(buffer.get()); | 286 DCHECK(buffer.get()); |
236 read_callback.Run(buffer); | 287 read_callback.Run(buffer); |
237 } | 288 } |
238 | 289 |
239 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; } | 290 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; } |
240 | 291 |
241 void ChunkDemuxerStream::EnableBitstreamConverter() {} | 292 void ChunkDemuxerStream::EnableBitstreamConverter() {} |
242 | 293 |
243 const AudioDecoderConfig& ChunkDemuxerStream::audio_decoder_config() { | 294 const AudioDecoderConfig& ChunkDemuxerStream::audio_decoder_config() { |
244 CHECK_EQ(type_, AUDIO); | 295 CHECK_EQ(type_, AUDIO); |
245 return audio_config_; | 296 return audio_config_; |
246 } | 297 } |
247 | 298 |
248 const VideoDecoderConfig& ChunkDemuxerStream::video_decoder_config() { | 299 const VideoDecoderConfig& ChunkDemuxerStream::video_decoder_config() { |
249 CHECK_EQ(type_, VIDEO); | 300 CHECK_EQ(type_, VIDEO); |
250 return video_config_; | 301 return video_config_; |
251 } | 302 } |
252 | 303 |
304 void ChunkDemuxerStream::ChangeState_Locked(State state) { | |
305 lock_.AssertAcquired(); | |
306 state_ = state; | |
307 } | |
308 | |
309 void ChunkDemuxerStream::DeferRead_Locked(const ReadCallback& read_cb) { | |
310 lock_.AssertAcquired(); | |
311 // Wrap & store |read_callback| so that it will | |
312 // get called on the current MessageLoop. | |
313 read_cbs_.push_back(base::Bind(&RunOnMessageLoop, read_cb, | |
314 MessageLoop::current())); | |
315 } | |
316 | |
317 void ChunkDemuxerStream::CreateReadDoneClosures_Locked( | |
318 std::deque<base::Closure>* closures) { | |
319 lock_.AssertAcquired(); | |
320 | |
321 while ((state_ == PLAYING || state_ == RECEIVED_END_OF_STREAM) && | |
Ami GONE FROM CHROMIUM
2012/01/27 23:44:58
Having state_ in this while condition is strange (
acolwell GONE FROM CHROMIUM
2012/01/29 03:00:41
Done.
| |
322 !buffers_.empty() && | |
323 !read_cbs_.empty()) { | |
324 closures->push_back(base::Bind(read_cbs_.front(), buffers_.front())); | |
325 buffers_.pop_front(); | |
326 read_cbs_.pop_front(); | |
327 } | |
328 | |
329 if (state_ == RECEIVED_END_OF_STREAM && | |
330 buffers_.empty() && !read_cbs_.empty()) { | |
331 | |
332 // Push enough EOS buffers to satisfy outstanding Read() requests. | |
333 scoped_refptr<Buffer> end_of_stream_buffer = CreateEOSBuffer(); | |
334 while(!read_cbs_.empty()) { | |
335 closures->push_back(base::Bind(read_cbs_.front(), end_of_stream_buffer)); | |
336 read_cbs_.pop_front(); | |
337 } | |
338 | |
339 ChangeState_Locked(END_OF_STREAM); | |
340 } | |
341 } | |
342 | |
253 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) | 343 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) |
254 : state_(WAITING_FOR_INIT), | 344 : state_(WAITING_FOR_INIT), |
255 client_(client), | 345 client_(client), |
256 buffered_bytes_(0), | 346 buffered_bytes_(0), |
257 seek_waits_for_data_(true), | 347 seek_waits_for_data_(true), |
258 deferred_error_(PIPELINE_OK) { | 348 deferred_error_(PIPELINE_OK) { |
259 DCHECK(client); | 349 DCHECK(client); |
260 } | 350 } |
261 | 351 |
262 ChunkDemuxer::~ChunkDemuxer() { | 352 ChunkDemuxer::~ChunkDemuxer() { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
299 } | 389 } |
300 | 390 |
301 void ChunkDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { | 391 void ChunkDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { |
302 DVLOG(1) << "Seek(" << time.InSecondsF() << ")"; | 392 DVLOG(1) << "Seek(" << time.InSecondsF() << ")"; |
303 | 393 |
304 PipelineStatus status = PIPELINE_ERROR_INVALID_STATE; | 394 PipelineStatus status = PIPELINE_ERROR_INVALID_STATE; |
305 { | 395 { |
306 base::AutoLock auto_lock(lock_); | 396 base::AutoLock auto_lock(lock_); |
307 | 397 |
308 if (state_ == INITIALIZED || state_ == ENDED) { | 398 if (state_ == INITIALIZED || state_ == ENDED) { |
399 if (audio_.get()) | |
Ami GONE FROM CHROMIUM
2012/01/27 23:44:58
.get() here and below are unnecessary (scoped_refp
acolwell GONE FROM CHROMIUM
2012/01/29 03:00:41
Done.
| |
400 audio_->Seek(time); | |
401 | |
402 if (video_.get()) | |
403 video_->Seek(time); | |
404 | |
309 if (seek_waits_for_data_) { | 405 if (seek_waits_for_data_) { |
310 DVLOG(1) << "Seek() : waiting for more data to arrive."; | 406 DVLOG(1) << "Seek() : waiting for more data to arrive."; |
311 seek_cb_ = cb; | 407 seek_cb_ = cb; |
312 return; | 408 return; |
313 } | 409 } |
314 | 410 |
315 status = PIPELINE_OK; | 411 status = PIPELINE_OK; |
316 } | 412 } |
317 } | 413 } |
318 | 414 |
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
646 if (!video_->CanAddBuffers(buffers)) | 742 if (!video_->CanAddBuffers(buffers)) |
647 return false; | 743 return false; |
648 | 744 |
649 video_->AddBuffers(buffers); | 745 video_->AddBuffers(buffers); |
650 seek_waits_for_data_ = false; | 746 seek_waits_for_data_ = false; |
651 | 747 |
652 return true; | 748 return true; |
653 } | 749 } |
654 | 750 |
655 } // namespace media | 751 } // namespace media |
OLD | NEW |