| 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" |
| 11 #include "media/base/data_buffer.h" | 11 #include "media/base/stream_parser_buffer.h" |
| 12 #include "media/base/video_decoder_config.h" | 12 #include "media/base/video_decoder_config.h" |
| 13 #include "media/filters/chunk_demuxer_client.h" | 13 #include "media/filters/chunk_demuxer_client.h" |
| 14 #include "media/webm/webm_stream_parser.h" | 14 #include "media/webm/webm_stream_parser.h" |
| 15 | 15 |
| 16 namespace media { | 16 namespace media { |
| 17 | 17 |
| 18 // TODO(acolwell): Remove this when fixing http://crbug.com/122909 . | 18 // TODO(acolwell): Remove this when fixing http://crbug.com/122909 . |
| 19 const char* kDefaultSourceType = "video/webm; codecs=\"vp8, vorbis\""; | 19 const char* kDefaultSourceType = "video/webm; codecs=\"vp8, vorbis\""; |
| 20 | 20 |
| 21 // Create an "end of stream" buffer. | |
| 22 static Buffer* CreateEOSBuffer() { | |
| 23 return new DataBuffer(0); | |
| 24 } | |
| 25 | |
| 26 class ChunkDemuxerStream : public DemuxerStream { | 21 class ChunkDemuxerStream : public DemuxerStream { |
| 27 public: | 22 public: |
| 28 typedef std::deque<scoped_refptr<Buffer> > BufferQueue; | 23 typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue; |
| 29 typedef std::deque<ReadCB> ReadCBQueue; | 24 typedef std::deque<ReadCB> ReadCBQueue; |
| 30 typedef std::deque<base::Closure> ClosureQueue; | 25 typedef std::deque<base::Closure> ClosureQueue; |
| 31 | 26 |
| 32 explicit ChunkDemuxerStream(const AudioDecoderConfig& audio_config); | 27 explicit ChunkDemuxerStream(const AudioDecoderConfig& audio_config); |
| 33 explicit ChunkDemuxerStream(const VideoDecoderConfig& video_config); | 28 explicit ChunkDemuxerStream(const VideoDecoderConfig& video_config); |
| 34 virtual ~ChunkDemuxerStream(); | 29 virtual ~ChunkDemuxerStream(); |
| 35 | 30 |
| 36 void Flush(); | 31 void Flush(); |
| 37 void Seek(base::TimeDelta time); | 32 void Seek(base::TimeDelta time); |
| 38 | 33 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 base::AutoLock auto_lock(lock_); | 193 base::AutoLock auto_lock(lock_); |
| 199 ChangeState_Locked(SHUTDOWN); | 194 ChangeState_Locked(SHUTDOWN); |
| 200 | 195 |
| 201 std::swap(read_cbs_, read_cbs); | 196 std::swap(read_cbs_, read_cbs); |
| 202 buffers_.clear(); | 197 buffers_.clear(); |
| 203 } | 198 } |
| 204 | 199 |
| 205 // Pass end of stream buffers to all callbacks to signal that no more data | 200 // Pass end of stream buffers to all callbacks to signal that no more data |
| 206 // will be sent. | 201 // will be sent. |
| 207 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) | 202 for (ReadCBQueue::iterator it = read_cbs.begin(); it != read_cbs.end(); ++it) |
| 208 it->Run(CreateEOSBuffer()); | 203 it->Run(StreamParserBuffer::CreateEOSBuffer()); |
| 209 } | 204 } |
| 210 | 205 |
| 211 bool ChunkDemuxerStream::GetLastBufferTimestamp( | 206 bool ChunkDemuxerStream::GetLastBufferTimestamp( |
| 212 base::TimeDelta* timestamp) const { | 207 base::TimeDelta* timestamp) const { |
| 213 base::AutoLock auto_lock(lock_); | 208 base::AutoLock auto_lock(lock_); |
| 214 | 209 |
| 215 if (buffers_.empty()) | 210 if (buffers_.empty()) |
| 216 return false; | 211 return false; |
| 217 | 212 |
| 218 *timestamp = buffers_.back()->GetTimestamp(); | 213 *timestamp = buffers_.back()->GetTimestamp(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 // Null buffers should be returned in this state since we are waiting | 252 // Null buffers should be returned in this state since we are waiting |
| 258 // for a seek. Any buffers in |buffers_| should NOT be returned because | 253 // for a seek. Any buffers in |buffers_| should NOT be returned because |
| 259 // they are associated with the seek. | 254 // they are associated with the seek. |
| 260 DCHECK(read_cbs_.empty()); | 255 DCHECK(read_cbs_.empty()); |
| 261 break; | 256 break; |
| 262 case RECEIVED_EOS: | 257 case RECEIVED_EOS: |
| 263 DCHECK(read_cbs_.empty()); | 258 DCHECK(read_cbs_.empty()); |
| 264 | 259 |
| 265 if (buffers_.empty()) { | 260 if (buffers_.empty()) { |
| 266 ChangeState_Locked(RETURNING_EOS_FOR_READS); | 261 ChangeState_Locked(RETURNING_EOS_FOR_READS); |
| 267 buffer = CreateEOSBuffer(); | 262 buffer = StreamParserBuffer::CreateEOSBuffer(); |
| 268 } else { | 263 } else { |
| 269 buffer = buffers_.front(); | 264 buffer = buffers_.front(); |
| 270 buffers_.pop_front(); | 265 buffers_.pop_front(); |
| 271 } | 266 } |
| 272 break; | 267 break; |
| 273 | 268 |
| 274 case RETURNING_EOS_FOR_READS: | 269 case RETURNING_EOS_FOR_READS: |
| 275 case SHUTDOWN: | 270 case SHUTDOWN: |
| 276 DCHECK(buffers_.empty()); | 271 DCHECK(buffers_.empty()); |
| 277 DCHECK(read_cbs_.empty()); | 272 DCHECK(read_cbs_.empty()); |
| 278 buffer = CreateEOSBuffer(); | 273 buffer = StreamParserBuffer::CreateEOSBuffer(); |
| 279 } | 274 } |
| 280 } | 275 } |
| 281 | 276 |
| 282 read_cb.Run(buffer); | 277 read_cb.Run(buffer); |
| 283 } | 278 } |
| 284 | 279 |
| 285 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; } | 280 DemuxerStream::Type ChunkDemuxerStream::type() { return type_; } |
| 286 | 281 |
| 287 void ChunkDemuxerStream::EnableBitstreamConverter() {} | 282 void ChunkDemuxerStream::EnableBitstreamConverter() {} |
| 288 | 283 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 318 while (!buffers_.empty() && !read_cbs_.empty()) { | 313 while (!buffers_.empty() && !read_cbs_.empty()) { |
| 319 closures->push_back(base::Bind(read_cbs_.front(), buffers_.front())); | 314 closures->push_back(base::Bind(read_cbs_.front(), buffers_.front())); |
| 320 buffers_.pop_front(); | 315 buffers_.pop_front(); |
| 321 read_cbs_.pop_front(); | 316 read_cbs_.pop_front(); |
| 322 } | 317 } |
| 323 | 318 |
| 324 if (state_ != RECEIVED_EOS || !buffers_.empty() || read_cbs_.empty()) | 319 if (state_ != RECEIVED_EOS || !buffers_.empty() || read_cbs_.empty()) |
| 325 return; | 320 return; |
| 326 | 321 |
| 327 // Push enough EOS buffers to satisfy outstanding Read() requests. | 322 // Push enough EOS buffers to satisfy outstanding Read() requests. |
| 328 scoped_refptr<Buffer> end_of_stream_buffer = CreateEOSBuffer(); | 323 scoped_refptr<Buffer> end_of_stream_buffer = |
| 324 StreamParserBuffer::CreateEOSBuffer(); |
| 329 while (!read_cbs_.empty()) { | 325 while (!read_cbs_.empty()) { |
| 330 closures->push_back(base::Bind(read_cbs_.front(), end_of_stream_buffer)); | 326 closures->push_back(base::Bind(read_cbs_.front(), end_of_stream_buffer)); |
| 331 read_cbs_.pop_front(); | 327 read_cbs_.pop_front(); |
| 332 } | 328 } |
| 333 | 329 |
| 334 ChangeState_Locked(RETURNING_EOS_FOR_READS); | 330 ChangeState_Locked(RETURNING_EOS_FOR_READS); |
| 335 } | 331 } |
| 336 | 332 |
| 337 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) | 333 ChunkDemuxer::ChunkDemuxer(ChunkDemuxerClient* client) |
| 338 : state_(WAITING_FOR_INIT), | 334 : state_(WAITING_FOR_INIT), |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 584 | 580 |
| 585 ChangeState_Locked(ENDED); | 581 ChangeState_Locked(ENDED); |
| 586 | 582 |
| 587 if (status != PIPELINE_OK) { | 583 if (status != PIPELINE_OK) { |
| 588 ReportError_Locked(status); | 584 ReportError_Locked(status); |
| 589 return; | 585 return; |
| 590 } | 586 } |
| 591 | 587 |
| 592 // Create an end of stream buffer. | 588 // Create an end of stream buffer. |
| 593 ChunkDemuxerStream::BufferQueue buffers; | 589 ChunkDemuxerStream::BufferQueue buffers; |
| 594 buffers.push_back(CreateEOSBuffer()); | 590 buffers.push_back(StreamParserBuffer::CreateEOSBuffer()); |
| 595 | 591 |
| 596 if (audio_.get()) | 592 if (audio_.get()) |
| 597 audio_->AddBuffers(buffers); | 593 audio_->AddBuffers(buffers); |
| 598 | 594 |
| 599 if (video_.get()) | 595 if (video_.get()) |
| 600 video_->AddBuffers(buffers); | 596 video_->AddBuffers(buffers); |
| 601 } | 597 } |
| 602 | 598 |
| 603 bool ChunkDemuxer::HasEnded() { | 599 bool ChunkDemuxer::HasEnded() { |
| 604 base::AutoLock auto_lock(lock_); | 600 base::AutoLock auto_lock(lock_); |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 738 return true; | 734 return true; |
| 739 } | 735 } |
| 740 | 736 |
| 741 bool ChunkDemuxer::OnKeyNeeded(scoped_array<uint8> init_data, | 737 bool ChunkDemuxer::OnKeyNeeded(scoped_array<uint8> init_data, |
| 742 int init_data_size) { | 738 int init_data_size) { |
| 743 client_->KeyNeeded(init_data.Pass(), init_data_size); | 739 client_->KeyNeeded(init_data.Pass(), init_data_size); |
| 744 return true; | 740 return true; |
| 745 } | 741 } |
| 746 | 742 |
| 747 } // namespace media | 743 } // namespace media |
| OLD | NEW |