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 <algorithm> | 7 #include <algorithm> |
| 8 #include <deque> | 8 #include <deque> |
| 9 #include <limits> | 9 #include <limits> |
| 10 | 10 |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 | 23 |
| 24 // Contains state belonging to a source id. | 24 // Contains state belonging to a source id. |
| 25 class SourceState { | 25 class SourceState { |
| 26 public: | 26 public: |
| 27 explicit SourceState(scoped_ptr<StreamParser> stream_parser); | 27 explicit SourceState(scoped_ptr<StreamParser> stream_parser); |
| 28 | 28 |
| 29 void Init(const StreamParser::InitCB& init_cb, | 29 void Init(const StreamParser::InitCB& init_cb, |
| 30 const StreamParser::NewConfigCB& config_cb, | 30 const StreamParser::NewConfigCB& config_cb, |
| 31 const StreamParser::NewBuffersCB& audio_cb, | 31 const StreamParser::NewBuffersCB& audio_cb, |
| 32 const StreamParser::NewBuffersCB& video_cb, | 32 const StreamParser::NewBuffersCB& video_cb, |
| 33 const StreamParser::NewBuffersCB& text_cb, | |
| 33 const StreamParser::NeedKeyCB& need_key_cb, | 34 const StreamParser::NeedKeyCB& need_key_cb, |
| 35 const AddTextTrackCB& add_text_track_cb, | |
| 34 const StreamParser::NewMediaSegmentCB& new_segment_cb, | 36 const StreamParser::NewMediaSegmentCB& new_segment_cb, |
| 35 const LogCB& log_cb); | 37 const LogCB& log_cb); |
| 36 | 38 |
| 37 // Appends new data to the StreamParser. | 39 // Appends new data to the StreamParser. |
| 38 // Returns true if the data was successfully appended. Returns false if an | 40 // Returns true if the data was successfully appended. Returns false if an |
| 39 // error occurred. | 41 // error occurred. |
| 40 bool Append(const uint8* data, size_t length); | 42 bool Append(const uint8* data, size_t length); |
| 41 | 43 |
| 42 // Aborts the current append sequence and resets the parser. | 44 // Aborts the current append sequence and resets the parser. |
| 43 void Abort(); | 45 void Abort(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 85 | 87 |
| 86 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser) | 88 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser) |
| 87 : can_update_offset_(true), | 89 : can_update_offset_(true), |
| 88 stream_parser_(stream_parser.release()) { | 90 stream_parser_(stream_parser.release()) { |
| 89 } | 91 } |
| 90 | 92 |
| 91 void SourceState::Init(const StreamParser::InitCB& init_cb, | 93 void SourceState::Init(const StreamParser::InitCB& init_cb, |
| 92 const StreamParser::NewConfigCB& config_cb, | 94 const StreamParser::NewConfigCB& config_cb, |
| 93 const StreamParser::NewBuffersCB& audio_cb, | 95 const StreamParser::NewBuffersCB& audio_cb, |
| 94 const StreamParser::NewBuffersCB& video_cb, | 96 const StreamParser::NewBuffersCB& video_cb, |
| 97 const StreamParser::NewBuffersCB& text_cb, | |
| 95 const StreamParser::NeedKeyCB& need_key_cb, | 98 const StreamParser::NeedKeyCB& need_key_cb, |
| 99 const AddTextTrackCB& add_text_track_cb, | |
| 96 const StreamParser::NewMediaSegmentCB& new_segment_cb, | 100 const StreamParser::NewMediaSegmentCB& new_segment_cb, |
| 97 const LogCB& log_cb) { | 101 const LogCB& log_cb) { |
| 98 stream_parser_->Init(init_cb, config_cb, | 102 stream_parser_->Init(init_cb, config_cb, |
| 99 base::Bind(&SourceState::OnBuffers, | 103 base::Bind(&SourceState::OnBuffers, |
| 100 base::Unretained(this), audio_cb), | 104 base::Unretained(this), audio_cb), |
| 101 base::Bind(&SourceState::OnBuffers, | 105 base::Bind(&SourceState::OnBuffers, |
| 102 base::Unretained(this), video_cb), | 106 base::Unretained(this), video_cb), |
| 107 base::Bind(&SourceState::OnBuffers, | |
| 108 base::Unretained(this), text_cb), | |
| 103 need_key_cb, | 109 need_key_cb, |
| 110 add_text_track_cb, | |
| 104 base::Bind(&SourceState::OnNewMediaSegment, | 111 base::Bind(&SourceState::OnNewMediaSegment, |
| 105 base::Unretained(this), new_segment_cb), | 112 base::Unretained(this), new_segment_cb), |
| 106 base::Bind(&SourceState::OnEndOfMediaSegment, | 113 base::Bind(&SourceState::OnEndOfMediaSegment, |
| 107 base::Unretained(this)), | 114 base::Unretained(this)), |
| 108 log_cb); | 115 log_cb); |
| 109 } | 116 } |
| 110 | 117 |
| 111 bool SourceState::SetTimestampOffset(TimeDelta timestamp_offset) { | 118 bool SourceState::SetTimestampOffset(TimeDelta timestamp_offset) { |
| 112 if (!can_update_offset_) | 119 if (!can_update_offset_) |
| 113 return false; | 120 return false; |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 538 *buffer = StreamParserBuffer::CreateEOSBuffer(); | 545 *buffer = StreamParserBuffer::CreateEOSBuffer(); |
| 539 return true; | 546 return true; |
| 540 } | 547 } |
| 541 | 548 |
| 542 NOTREACHED(); | 549 NOTREACHED(); |
| 543 return false; | 550 return false; |
| 544 } | 551 } |
| 545 | 552 |
| 546 ChunkDemuxer::ChunkDemuxer(const base::Closure& open_cb, | 553 ChunkDemuxer::ChunkDemuxer(const base::Closure& open_cb, |
| 547 const NeedKeyCB& need_key_cb, | 554 const NeedKeyCB& need_key_cb, |
| 555 const AddTextTrackCB& add_text_track_cb, | |
| 548 const LogCB& log_cb) | 556 const LogCB& log_cb) |
| 549 : state_(WAITING_FOR_INIT), | 557 : state_(WAITING_FOR_INIT), |
| 550 host_(NULL), | 558 host_(NULL), |
| 551 open_cb_(open_cb), | 559 open_cb_(open_cb), |
| 552 need_key_cb_(need_key_cb), | 560 need_key_cb_(need_key_cb), |
| 561 add_text_track_cb_(add_text_track_cb), | |
| 553 log_cb_(log_cb), | 562 log_cb_(log_cb), |
| 554 duration_(kNoTimestamp()), | 563 duration_(kNoTimestamp()), |
| 555 user_specified_duration_(-1) { | 564 user_specified_duration_(-1) { |
| 556 DCHECK(!open_cb_.is_null()); | 565 DCHECK(!open_cb_.is_null()); |
| 557 DCHECK(!need_key_cb_.is_null()); | 566 DCHECK(!need_key_cb_.is_null()); |
| 558 } | 567 } |
| 559 | 568 |
| 560 void ChunkDemuxer::Initialize(DemuxerHost* host, const PipelineStatusCB& cb) { | 569 void ChunkDemuxer::Initialize(DemuxerHost* host, const PipelineStatusCB& cb) { |
| 561 DVLOG(1) << "Init()"; | 570 DVLOG(1) << "Init()"; |
| 562 | 571 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 696 audio_cb = base::Bind(&ChunkDemuxer::OnAudioBuffers, | 705 audio_cb = base::Bind(&ChunkDemuxer::OnAudioBuffers, |
| 697 base::Unretained(this)); | 706 base::Unretained(this)); |
| 698 } | 707 } |
| 699 | 708 |
| 700 if (has_video) { | 709 if (has_video) { |
| 701 source_id_video_ = id; | 710 source_id_video_ = id; |
| 702 video_cb = base::Bind(&ChunkDemuxer::OnVideoBuffers, | 711 video_cb = base::Bind(&ChunkDemuxer::OnVideoBuffers, |
| 703 base::Unretained(this)); | 712 base::Unretained(this)); |
| 704 } | 713 } |
| 705 | 714 |
| 715 StreamParser::NewBuffersCB text_cb; | |
| 716 text_cb = base::Bind(&ChunkDemuxer::OnTextBuffers, | |
|
acolwell GONE FROM CHROMIUM
2013/05/10 18:41:39
nit: Please inline like the other Bind calls below
Matthew Heaney (Chromium)
2013/05/11 07:29:13
Done.
| |
| 717 base::Unretained(this)); | |
| 718 | |
| 706 scoped_ptr<SourceState> source_state(new SourceState(stream_parser.Pass())); | 719 scoped_ptr<SourceState> source_state(new SourceState(stream_parser.Pass())); |
| 707 source_state->Init( | 720 source_state->Init( |
| 708 base::Bind(&ChunkDemuxer::OnSourceInitDone, base::Unretained(this)), | 721 base::Bind(&ChunkDemuxer::OnSourceInitDone, base::Unretained(this)), |
| 709 base::Bind(&ChunkDemuxer::OnNewConfigs, base::Unretained(this), | 722 base::Bind(&ChunkDemuxer::OnNewConfigs, base::Unretained(this), |
| 710 has_audio, has_video), | 723 has_audio, has_video), |
| 711 audio_cb, | 724 audio_cb, |
| 712 video_cb, | 725 video_cb, |
| 726 text_cb, | |
| 713 base::Bind(&ChunkDemuxer::OnNeedKey, base::Unretained(this)), | 727 base::Bind(&ChunkDemuxer::OnNeedKey, base::Unretained(this)), |
| 728 add_text_track_cb_, | |
| 714 base::Bind(&ChunkDemuxer::OnNewMediaSegment, base::Unretained(this), id), | 729 base::Bind(&ChunkDemuxer::OnNewMediaSegment, base::Unretained(this), id), |
| 715 log_cb_); | 730 log_cb_); |
| 716 | 731 |
| 717 source_state_map_[id] = source_state.release(); | 732 source_state_map_[id] = source_state.release(); |
| 718 return kOk; | 733 return kOk; |
| 719 } | 734 } |
| 720 | 735 |
| 721 void ChunkDemuxer::RemoveId(const std::string& id) { | 736 void ChunkDemuxer::RemoveId(const std::string& id) { |
| 722 base::AutoLock auto_lock(lock_); | 737 base::AutoLock auto_lock(lock_); |
| 723 CHECK(IsValidId(id)); | 738 CHECK(IsValidId(id)); |
| (...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1179 return false; | 1194 return false; |
| 1180 | 1195 |
| 1181 CHECK(IsValidId(source_id_video_)); | 1196 CHECK(IsValidId(source_id_video_)); |
| 1182 if (!video_->Append(buffers)) | 1197 if (!video_->Append(buffers)) |
| 1183 return false; | 1198 return false; |
| 1184 | 1199 |
| 1185 IncreaseDurationIfNecessary(buffers, video_.get()); | 1200 IncreaseDurationIfNecessary(buffers, video_.get()); |
| 1186 return true; | 1201 return true; |
| 1187 } | 1202 } |
| 1188 | 1203 |
| 1204 bool ChunkDemuxer::OnTextBuffers(const StreamParser::BufferQueue& buffers) { | |
| 1205 lock_.AssertAcquired(); | |
| 1206 DCHECK_NE(state_, SHUTDOWN); | |
| 1207 | |
| 1208 // TODO(matthewjheaney): | |
| 1209 // The text buffers are pushed up the stack directly by the stream parser, | |
| 1210 // so it doesn't appear that there's anything we need to do here. | |
|
acolwell GONE FROM CHROMIUM
2013/05/10 18:41:39
Text tracks need to be able to update the duration
Matthew Heaney (Chromium)
2013/05/11 07:29:13
Done.
| |
| 1211 | |
| 1212 return true; | |
| 1213 } | |
| 1214 | |
| 1189 // TODO(acolwell): Remove bool from StreamParser::NeedKeyCB so that | 1215 // TODO(acolwell): Remove bool from StreamParser::NeedKeyCB so that |
| 1190 // this method can be removed and need_key_cb_ can be passed directly | 1216 // this method can be removed and need_key_cb_ can be passed directly |
| 1191 // to the parser. | 1217 // to the parser. |
| 1192 bool ChunkDemuxer::OnNeedKey(const std::string& type, | 1218 bool ChunkDemuxer::OnNeedKey(const std::string& type, |
| 1193 scoped_ptr<uint8[]> init_data, | 1219 scoped_ptr<uint8[]> init_data, |
| 1194 int init_data_size) { | 1220 int init_data_size) { |
| 1195 lock_.AssertAcquired(); | 1221 lock_.AssertAcquired(); |
| 1196 need_key_cb_.Run(type, init_data.Pass(), init_data_size); | 1222 need_key_cb_.Run(type, init_data.Pass(), init_data_size); |
| 1197 return true; | 1223 return true; |
| 1198 } | 1224 } |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1250 | 1276 |
| 1251 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const { | 1277 Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges() const { |
| 1252 if (audio_ && !video_) | 1278 if (audio_ && !video_) |
| 1253 return audio_->GetBufferedRanges(duration_); | 1279 return audio_->GetBufferedRanges(duration_); |
| 1254 else if (!audio_ && video_) | 1280 else if (!audio_ && video_) |
| 1255 return video_->GetBufferedRanges(duration_); | 1281 return video_->GetBufferedRanges(duration_); |
| 1256 return ComputeIntersection(); | 1282 return ComputeIntersection(); |
| 1257 } | 1283 } |
| 1258 | 1284 |
| 1259 } // namespace media | 1285 } // namespace media |
| OLD | NEW |