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 #include <list> | 10 #include <list> |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 | 116 |
| 117 // Calls Remove(|start|, |end|, |duration|) on all | 117 // Calls Remove(|start|, |end|, |duration|) on all |
| 118 // ChunkDemuxerStreams managed by this object. | 118 // ChunkDemuxerStreams managed by this object. |
| 119 void Remove(TimeDelta start, TimeDelta end, TimeDelta duration); | 119 void Remove(TimeDelta start, TimeDelta end, TimeDelta duration); |
| 120 | 120 |
| 121 // Sets |timestamp_offset_| if possible. | 121 // Sets |timestamp_offset_| if possible. |
| 122 // Returns if the offset was set. Returns false if the offset could not be | 122 // Returns if the offset was set. Returns false if the offset could not be |
| 123 // updated at this time. | 123 // updated at this time. |
| 124 bool SetTimestampOffset(TimeDelta timestamp_offset); | 124 bool SetTimestampOffset(TimeDelta timestamp_offset); |
| 125 | 125 |
| 126 // Sets |sequence_mode_| to |is_sequence_mode| if possible. | |
| 127 // Returns true if the mode update was allowed. Returns false if the mode | |
| 128 // could not be updated at this time. | |
| 129 bool SetSequenceMode(bool is_sequence_mode); | |
|
acolwell GONE FROM CHROMIUM
2014/01/11 01:24:36
nit: drop the is_ since you are using sequence_mod
wolenetz
2014/01/11 02:15:05
Done.
| |
| 130 | |
| 126 TimeDelta timestamp_offset() const { return timestamp_offset_; } | 131 TimeDelta timestamp_offset() const { return timestamp_offset_; } |
| 127 | 132 |
| 128 void set_append_window_start(TimeDelta start) { | 133 void set_append_window_start(TimeDelta start) { |
| 129 append_window_start_ = start; | 134 append_window_start_ = start; |
| 130 } | 135 } |
| 131 void set_append_window_end(TimeDelta end) { append_window_end_ = end; } | 136 void set_append_window_end(TimeDelta end) { append_window_end_ = end; } |
| 132 | 137 |
| 133 // Returns the range of buffered data in this source, capped at |duration|. | 138 // Returns the range of buffered data in this source, capped at |duration|. |
| 134 // |ended| - Set to true if end of stream has been signalled and the special | 139 // |ended| - Set to true if end of stream has been signalled and the special |
| 135 // end of stream range logic needs to be executed. | 140 // end of stream range logic needs to be executed. |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 bool* needs_keyframe, | 215 bool* needs_keyframe, |
| 211 StreamParser::BufferQueue* filtered_buffers); | 216 StreamParser::BufferQueue* filtered_buffers); |
| 212 | 217 |
| 213 CreateDemuxerStreamCB create_demuxer_stream_cb_; | 218 CreateDemuxerStreamCB create_demuxer_stream_cb_; |
| 214 IncreaseDurationCB increase_duration_cb_; | 219 IncreaseDurationCB increase_duration_cb_; |
| 215 NewTextTrackCB new_text_track_cb_; | 220 NewTextTrackCB new_text_track_cb_; |
| 216 | 221 |
| 217 // The offset to apply to media segment timestamps. | 222 // The offset to apply to media segment timestamps. |
| 218 TimeDelta timestamp_offset_; | 223 TimeDelta timestamp_offset_; |
| 219 | 224 |
| 225 // Tracks the mode by which appended media is processed. If true, then | |
| 226 // appended media is processed using "sequence" mode. Otherwise, appended | |
| 227 // media is processed using "segments" mode. | |
| 228 // TODO(wolenetz): Enable "sequence" mode logic. See http://crbug.com/249422 | |
| 229 // and http://crbug.com/333437. | |
| 230 bool sequence_mode_; | |
| 231 | |
| 220 TimeDelta append_window_start_; | 232 TimeDelta append_window_start_; |
| 221 TimeDelta append_window_end_; | 233 TimeDelta append_window_end_; |
| 222 | 234 |
| 223 // Set to true if the next buffers appended within the append window | 235 // Set to true if the next buffers appended within the append window |
| 224 // represent the start of a new media segment. This flag being set | 236 // represent the start of a new media segment. This flag being set |
| 225 // triggers a call to |new_segment_cb_| when the new buffers are | 237 // triggers a call to |new_segment_cb_| when the new buffers are |
| 226 // appended. The flag is set on actual media segment boundaries and | 238 // appended. The flag is set on actual media segment boundaries and |
| 227 // when the "append window" filtering causes discontinuities in the | 239 // when the "append window" filtering causes discontinuities in the |
| 228 // appended data. | 240 // appended data. |
| 229 bool new_media_segment_; | 241 bool new_media_segment_; |
| 230 | 242 |
| 231 // Keeps track of whether |timestamp_offset_| can be modified. | 243 // Keeps track of whether |timestamp_offset_| or |sequence_mode_| can be |
| 232 bool can_update_offset_; | 244 // updated. These cannot be updated if a media segment is being parsed. |
| 245 bool parsing_media_segment_; | |
| 233 | 246 |
| 234 // The object used to parse appended data. | 247 // The object used to parse appended data. |
| 235 scoped_ptr<StreamParser> stream_parser_; | 248 scoped_ptr<StreamParser> stream_parser_; |
| 236 | 249 |
| 237 ChunkDemuxerStream* audio_; | 250 ChunkDemuxerStream* audio_; |
| 238 bool audio_needs_keyframe_; | 251 bool audio_needs_keyframe_; |
| 239 | 252 |
| 240 ChunkDemuxerStream* video_; | 253 ChunkDemuxerStream* video_; |
| 241 bool video_needs_keyframe_; | 254 bool video_needs_keyframe_; |
| 242 | 255 |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 349 | 362 |
| 350 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); | 363 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); |
| 351 }; | 364 }; |
| 352 | 365 |
| 353 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser, | 366 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser, |
| 354 const LogCB& log_cb, | 367 const LogCB& log_cb, |
| 355 const CreateDemuxerStreamCB& create_demuxer_stream_cb, | 368 const CreateDemuxerStreamCB& create_demuxer_stream_cb, |
| 356 const IncreaseDurationCB& increase_duration_cb) | 369 const IncreaseDurationCB& increase_duration_cb) |
| 357 : create_demuxer_stream_cb_(create_demuxer_stream_cb), | 370 : create_demuxer_stream_cb_(create_demuxer_stream_cb), |
| 358 increase_duration_cb_(increase_duration_cb), | 371 increase_duration_cb_(increase_duration_cb), |
| 372 sequence_mode_(false), | |
| 359 append_window_end_(kInfiniteDuration()), | 373 append_window_end_(kInfiniteDuration()), |
| 360 new_media_segment_(false), | 374 new_media_segment_(false), |
| 361 can_update_offset_(true), | 375 parsing_media_segment_(false), |
| 362 stream_parser_(stream_parser.release()), | 376 stream_parser_(stream_parser.release()), |
| 363 audio_(NULL), | 377 audio_(NULL), |
| 364 audio_needs_keyframe_(true), | 378 audio_needs_keyframe_(true), |
| 365 video_(NULL), | 379 video_(NULL), |
| 366 video_needs_keyframe_(true), | 380 video_needs_keyframe_(true), |
| 367 log_cb_(log_cb) { | 381 log_cb_(log_cb) { |
| 368 DCHECK(!create_demuxer_stream_cb_.is_null()); | 382 DCHECK(!create_demuxer_stream_cb_.is_null()); |
| 369 DCHECK(!increase_duration_cb_.is_null()); | 383 DCHECK(!increase_duration_cb_.is_null()); |
| 370 } | 384 } |
| 371 | 385 |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 399 new_text_buffers_cb, | 413 new_text_buffers_cb, |
| 400 need_key_cb, | 414 need_key_cb, |
| 401 base::Bind(&SourceState::OnNewMediaSegment, | 415 base::Bind(&SourceState::OnNewMediaSegment, |
| 402 base::Unretained(this)), | 416 base::Unretained(this)), |
| 403 base::Bind(&SourceState::OnEndOfMediaSegment, | 417 base::Bind(&SourceState::OnEndOfMediaSegment, |
| 404 base::Unretained(this)), | 418 base::Unretained(this)), |
| 405 log_cb_); | 419 log_cb_); |
| 406 } | 420 } |
| 407 | 421 |
| 408 bool SourceState::SetTimestampOffset(TimeDelta timestamp_offset) { | 422 bool SourceState::SetTimestampOffset(TimeDelta timestamp_offset) { |
| 409 if (!can_update_offset_) | 423 if (parsing_media_segment_) |
| 410 return false; | 424 return false; |
| 411 | 425 |
| 412 timestamp_offset_ = timestamp_offset; | 426 timestamp_offset_ = timestamp_offset; |
| 413 return true; | 427 return true; |
| 414 } | 428 } |
| 415 | 429 |
| 430 bool SourceState::SetSequenceMode(bool is_sequence_mode) { | |
|
acolwell GONE FROM CHROMIUM
2014/01/11 01:24:36
ditto
wolenetz
2014/01/11 02:15:05
Done.
| |
| 431 if (parsing_media_segment_) | |
| 432 return false; | |
| 433 | |
| 434 sequence_mode_ = is_sequence_mode; | |
| 435 return true; | |
| 436 } | |
| 437 | |
| 438 | |
| 416 bool SourceState::Append(const uint8* data, size_t length) { | 439 bool SourceState::Append(const uint8* data, size_t length) { |
| 417 return stream_parser_->Parse(data, length); | 440 return stream_parser_->Parse(data, length); |
| 418 } | 441 } |
| 419 | 442 |
| 420 void SourceState::Abort() { | 443 void SourceState::Abort() { |
| 421 stream_parser_->Flush(); | 444 stream_parser_->Flush(); |
| 422 audio_needs_keyframe_ = true; | 445 audio_needs_keyframe_ = true; |
| 423 video_needs_keyframe_ = true; | 446 video_needs_keyframe_ = true; |
| 424 can_update_offset_ = true; | 447 parsing_media_segment_ = false; |
| 425 } | 448 } |
| 426 | 449 |
| 427 void SourceState::Remove(TimeDelta start, TimeDelta end, TimeDelta duration) { | 450 void SourceState::Remove(TimeDelta start, TimeDelta end, TimeDelta duration) { |
| 428 if (audio_) | 451 if (audio_) |
| 429 audio_->Remove(start, end, duration); | 452 audio_->Remove(start, end, duration); |
| 430 | 453 |
| 431 if (video_) | 454 if (video_) |
| 432 video_->Remove(start, end, duration); | 455 video_->Remove(start, end, duration); |
| 433 | 456 |
| 434 for (TextStreamMap::iterator itr = text_stream_map_.begin(); | 457 for (TextStreamMap::iterator itr = text_stream_map_.begin(); |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 737 } | 760 } |
| 738 } | 761 } |
| 739 } | 762 } |
| 740 | 763 |
| 741 DVLOG(1) << "OnNewConfigs() : " << (success ? "success" : "failed"); | 764 DVLOG(1) << "OnNewConfigs() : " << (success ? "success" : "failed"); |
| 742 return success; | 765 return success; |
| 743 } | 766 } |
| 744 | 767 |
| 745 void SourceState::OnNewMediaSegment() { | 768 void SourceState::OnNewMediaSegment() { |
| 746 DVLOG(2) << "OnNewMediaSegment()"; | 769 DVLOG(2) << "OnNewMediaSegment()"; |
| 747 can_update_offset_ = false; | 770 parsing_media_segment_ = true; |
| 748 new_media_segment_ = true; | 771 new_media_segment_ = true; |
| 749 } | 772 } |
| 750 | 773 |
| 751 void SourceState::OnEndOfMediaSegment() { | 774 void SourceState::OnEndOfMediaSegment() { |
| 752 DVLOG(2) << "OnEndOfMediaSegment()"; | 775 DVLOG(2) << "OnEndOfMediaSegment()"; |
| 753 can_update_offset_ = true; | 776 parsing_media_segment_ = false; |
| 754 new_media_segment_ = false; | 777 new_media_segment_ = false; |
| 755 } | 778 } |
| 756 | 779 |
| 757 bool SourceState::OnNewBuffers(const StreamParser::BufferQueue& audio_buffers, | 780 bool SourceState::OnNewBuffers(const StreamParser::BufferQueue& audio_buffers, |
| 758 const StreamParser::BufferQueue& video_buffers) { | 781 const StreamParser::BufferQueue& video_buffers) { |
| 759 DCHECK(!audio_buffers.empty() || !video_buffers.empty()); | 782 DCHECK(!audio_buffers.empty() || !video_buffers.empty()); |
| 760 AdjustBufferTimestamps(audio_buffers); | 783 AdjustBufferTimestamps(audio_buffers); |
| 761 AdjustBufferTimestamps(video_buffers); | 784 AdjustBufferTimestamps(video_buffers); |
| 762 | 785 |
| 763 StreamParser::BufferQueue filtered_audio; | 786 StreamParser::BufferQueue filtered_audio; |
| (...skipping 753 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1517 } | 1540 } |
| 1518 | 1541 |
| 1519 bool ChunkDemuxer::SetTimestampOffset(const std::string& id, TimeDelta offset) { | 1542 bool ChunkDemuxer::SetTimestampOffset(const std::string& id, TimeDelta offset) { |
| 1520 base::AutoLock auto_lock(lock_); | 1543 base::AutoLock auto_lock(lock_); |
| 1521 DVLOG(1) << "SetTimestampOffset(" << id << ", " << offset.InSecondsF() << ")"; | 1544 DVLOG(1) << "SetTimestampOffset(" << id << ", " << offset.InSecondsF() << ")"; |
| 1522 CHECK(IsValidId(id)); | 1545 CHECK(IsValidId(id)); |
| 1523 | 1546 |
| 1524 return source_state_map_[id]->SetTimestampOffset(offset); | 1547 return source_state_map_[id]->SetTimestampOffset(offset); |
| 1525 } | 1548 } |
| 1526 | 1549 |
| 1550 bool ChunkDemuxer::SetSequenceMode(const std::string& id, | |
| 1551 bool is_sequence_mode) { | |
|
acolwell GONE FROM CHROMIUM
2014/01/11 01:24:36
ditto
wolenetz
2014/01/11 02:15:05
Done.
| |
| 1552 base::AutoLock auto_lock(lock_); | |
| 1553 DVLOG(1) << "SetSequenceMode(" << id << ", " << is_sequence_mode << ")"; | |
| 1554 CHECK(IsValidId(id)); | |
| 1555 DCHECK_NE(state_, ENDED); | |
| 1556 | |
| 1557 return source_state_map_[id]->SetSequenceMode(is_sequence_mode); | |
| 1558 } | |
| 1559 | |
| 1527 void ChunkDemuxer::MarkEndOfStream(PipelineStatus status) { | 1560 void ChunkDemuxer::MarkEndOfStream(PipelineStatus status) { |
| 1528 DVLOG(1) << "MarkEndOfStream(" << status << ")"; | 1561 DVLOG(1) << "MarkEndOfStream(" << status << ")"; |
| 1529 base::AutoLock auto_lock(lock_); | 1562 base::AutoLock auto_lock(lock_); |
| 1530 DCHECK_NE(state_, WAITING_FOR_INIT); | 1563 DCHECK_NE(state_, WAITING_FOR_INIT); |
| 1531 DCHECK_NE(state_, ENDED); | 1564 DCHECK_NE(state_, ENDED); |
| 1532 | 1565 |
| 1533 if (state_ == SHUTDOWN || state_ == PARSE_ERROR) | 1566 if (state_ == SHUTDOWN || state_ == PARSE_ERROR) |
| 1534 return; | 1567 return; |
| 1535 | 1568 |
| 1536 if (state_ == INITIALIZING) { | 1569 if (state_ == INITIALIZING) { |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1820 } | 1853 } |
| 1821 | 1854 |
| 1822 void ChunkDemuxer::ShutdownAllStreams() { | 1855 void ChunkDemuxer::ShutdownAllStreams() { |
| 1823 for (SourceStateMap::iterator itr = source_state_map_.begin(); | 1856 for (SourceStateMap::iterator itr = source_state_map_.begin(); |
| 1824 itr != source_state_map_.end(); ++itr) { | 1857 itr != source_state_map_.end(); ++itr) { |
| 1825 itr->second->Shutdown(); | 1858 itr->second->Shutdown(); |
| 1826 } | 1859 } |
| 1827 } | 1860 } |
| 1828 | 1861 |
| 1829 } // namespace media | 1862 } // namespace media |
| OLD | NEW |