Chromium Code Reviews| 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 |