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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
111 // error occurred. | 111 // error occurred. |
112 bool Append(const uint8* data, size_t length); | 112 bool Append(const uint8* data, size_t length); |
113 | 113 |
114 // Aborts the current append sequence and resets the parser. | 114 // Aborts the current append sequence and resets the parser. |
115 void Abort(); | 115 void Abort(); |
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 user-specified |timestamp_offset_| if possible. |
122 // Returns if the offset was set. Returns false if the offset could not be | 122 // Returns true if the offset was set. Returns false if the offset could not |
123 // updated at this time. | 123 // be updated at this time. |
124 bool SetTimestampOffset(TimeDelta timestamp_offset); | 124 bool SetTimestampOffset(double timestamp_offset); |
125 | |
126 // Gets the current timestamp offset. | |
127 // If |using_user_specified_timestamp_offset_| is true, meaning | |
128 // |timestamp_offset_| was most recently updated by SetTimestampOffset(), | |
129 // returns the exact double representation |user_specified_timestamp_offset_|. | |
130 // Otherwise, |timestamp_offset_| has diverged since construction or the | |
131 // last SetTimestampOffset(), such as may occur in "sequence" mode Append() | |
132 // coded frame processing. In this case, returns a double representation of | |
133 // the current |timestamp_offset_| TimeDelta. | |
134 double GetTimestampOffset() const; | |
125 | 135 |
126 // Sets |sequence_mode_| to |sequence_mode| if possible. | 136 // Sets |sequence_mode_| to |sequence_mode| if possible. |
127 // Returns true if the mode update was allowed. Returns false if the mode | 137 // Returns true if the mode update was allowed. Returns false if the mode |
128 // could not be updated at this time. | 138 // could not be updated at this time. |
129 bool SetSequenceMode(bool sequence_mode); | 139 bool SetSequenceMode(bool sequence_mode); |
130 | 140 |
131 TimeDelta timestamp_offset() const { return timestamp_offset_; } | |
132 | |
133 void set_append_window_start(TimeDelta start) { | 141 void set_append_window_start(TimeDelta start) { |
134 append_window_start_ = start; | 142 append_window_start_ = start; |
135 } | 143 } |
136 void set_append_window_end(TimeDelta end) { append_window_end_ = end; } | 144 void set_append_window_end(TimeDelta end) { append_window_end_ = end; } |
137 | 145 |
138 // Returns the range of buffered data in this source, capped at |duration|. | 146 // Returns the range of buffered data in this source, capped at |duration|. |
139 // |ended| - Set to true if end of stream has been signalled and the special | 147 // |ended| - Set to true if end of stream has been signalled and the special |
140 // end of stream range logic needs to be executed. | 148 // end of stream range logic needs to be executed. |
141 Ranges<TimeDelta> GetBufferedRanges(TimeDelta duration, bool ended) const; | 149 Ranges<TimeDelta> GetBufferedRanges(TimeDelta duration, bool ended) const; |
142 | 150 |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
217 bool* needs_keyframe, | 225 bool* needs_keyframe, |
218 StreamParser::BufferQueue* filtered_buffers); | 226 StreamParser::BufferQueue* filtered_buffers); |
219 | 227 |
220 CreateDemuxerStreamCB create_demuxer_stream_cb_; | 228 CreateDemuxerStreamCB create_demuxer_stream_cb_; |
221 IncreaseDurationCB increase_duration_cb_; | 229 IncreaseDurationCB increase_duration_cb_; |
222 NewTextTrackCB new_text_track_cb_; | 230 NewTextTrackCB new_text_track_cb_; |
223 | 231 |
224 // The offset to apply to media segment timestamps. | 232 // The offset to apply to media segment timestamps. |
225 TimeDelta timestamp_offset_; | 233 TimeDelta timestamp_offset_; |
226 | 234 |
235 // Enable exact round-tripping SetTimestampOffset()+GetTimestampOffset(), | |
236 // unless the offset is updated in the interim by coded frame processing | |
237 // in "sequence" mode Append() operations. | |
238 double user_specified_timestamp_offset_; | |
239 bool using_user_specified_timestamp_offset_; | |
240 | |
227 // Tracks the mode by which appended media is processed. If true, then | 241 // Tracks the mode by which appended media is processed. If true, then |
228 // appended media is processed using "sequence" mode. Otherwise, appended | 242 // appended media is processed using "sequence" mode. Otherwise, appended |
229 // media is processed using "segments" mode. | 243 // media is processed using "segments" mode. |
230 // TODO(wolenetz): Enable "sequence" mode logic. See http://crbug.com/249422 | 244 // TODO(wolenetz): Enable "sequence" mode logic. See http://crbug.com/249422 |
231 // and http://crbug.com/333437. | 245 // and http://crbug.com/333437. |
232 bool sequence_mode_; | 246 bool sequence_mode_; |
233 | 247 |
234 TimeDelta append_window_start_; | 248 TimeDelta append_window_start_; |
235 TimeDelta append_window_end_; | 249 TimeDelta append_window_end_; |
236 | 250 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
358 | 372 |
359 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); | 373 DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream); |
360 }; | 374 }; |
361 | 375 |
362 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser, | 376 SourceState::SourceState(scoped_ptr<StreamParser> stream_parser, |
363 const LogCB& log_cb, | 377 const LogCB& log_cb, |
364 const CreateDemuxerStreamCB& create_demuxer_stream_cb, | 378 const CreateDemuxerStreamCB& create_demuxer_stream_cb, |
365 const IncreaseDurationCB& increase_duration_cb) | 379 const IncreaseDurationCB& increase_duration_cb) |
366 : create_demuxer_stream_cb_(create_demuxer_stream_cb), | 380 : create_demuxer_stream_cb_(create_demuxer_stream_cb), |
367 increase_duration_cb_(increase_duration_cb), | 381 increase_duration_cb_(increase_duration_cb), |
382 user_specified_timestamp_offset_(0.0), | |
383 using_user_specified_timestamp_offset_(true), | |
368 sequence_mode_(false), | 384 sequence_mode_(false), |
369 append_window_end_(kInfiniteDuration()), | 385 append_window_end_(kInfiniteDuration()), |
370 new_media_segment_(false), | 386 new_media_segment_(false), |
371 parsing_media_segment_(false), | 387 parsing_media_segment_(false), |
372 stream_parser_(stream_parser.release()), | 388 stream_parser_(stream_parser.release()), |
373 audio_(NULL), | 389 audio_(NULL), |
374 audio_needs_keyframe_(true), | 390 audio_needs_keyframe_(true), |
375 video_(NULL), | 391 video_(NULL), |
376 video_needs_keyframe_(true), | 392 video_needs_keyframe_(true), |
377 log_cb_(log_cb) { | 393 log_cb_(log_cb) { |
(...skipping 23 matching lines...) Expand all Loading... | |
401 base::Unretained(this)), | 417 base::Unretained(this)), |
402 new_text_track_cb_.is_null(), | 418 new_text_track_cb_.is_null(), |
403 need_key_cb, | 419 need_key_cb, |
404 base::Bind(&SourceState::OnNewMediaSegment, | 420 base::Bind(&SourceState::OnNewMediaSegment, |
405 base::Unretained(this)), | 421 base::Unretained(this)), |
406 base::Bind(&SourceState::OnEndOfMediaSegment, | 422 base::Bind(&SourceState::OnEndOfMediaSegment, |
407 base::Unretained(this)), | 423 base::Unretained(this)), |
408 log_cb_); | 424 log_cb_); |
409 } | 425 } |
410 | 426 |
411 bool SourceState::SetTimestampOffset(TimeDelta timestamp_offset) { | 427 bool SourceState::SetTimestampOffset(double timestamp_offset) { |
412 if (parsing_media_segment_) | 428 if (parsing_media_segment_) |
413 return false; | 429 return false; |
414 | 430 |
415 timestamp_offset_ = timestamp_offset; | 431 using_user_specified_timestamp_offset_ = true; |
432 user_specified_timestamp_offset_ = timestamp_offset; | |
433 timestamp_offset_ = base::TimeDelta::FromMicroseconds( | |
434 timestamp_offset * base::Time::kMicrosecondsPerSecond); | |
435 | |
416 return true; | 436 return true; |
417 } | 437 } |
418 | 438 |
439 double SourceState::GetTimestampOffset() const { | |
440 if (using_user_specified_timestamp_offset_) | |
441 return user_specified_timestamp_offset_; | |
acolwell GONE FROM CHROMIUM
2014/02/25 17:24:28
I think we should just return NaN here. Blink alre
wolenetz
2014/02/25 20:32:20
Done, using TimeDelta, name change, and kNoTimesta
| |
442 else | |
acolwell GONE FROM CHROMIUM
2014/02/25 17:24:28
nit: drop else.
wolenetz
2014/02/25 20:32:20
Done.
| |
443 return timestamp_offset_.InSecondsF(); | |
444 } | |
445 | |
419 bool SourceState::SetSequenceMode(bool sequence_mode) { | 446 bool SourceState::SetSequenceMode(bool sequence_mode) { |
420 if (parsing_media_segment_) | 447 if (parsing_media_segment_) |
421 return false; | 448 return false; |
422 | 449 |
423 sequence_mode_ = sequence_mode; | 450 sequence_mode_ = sequence_mode; |
424 return true; | 451 return true; |
425 } | 452 } |
426 | 453 |
427 | 454 |
428 bool SourceState::Append(const uint8* data, size_t length) { | 455 bool SourceState::Append(const uint8* data, size_t length) { |
(...skipping 1115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1544 user_specified_duration_ = duration; | 1571 user_specified_duration_ = duration; |
1545 duration_ = duration_td; | 1572 duration_ = duration_td; |
1546 host_->SetDuration(duration_); | 1573 host_->SetDuration(duration_); |
1547 | 1574 |
1548 for (SourceStateMap::iterator itr = source_state_map_.begin(); | 1575 for (SourceStateMap::iterator itr = source_state_map_.begin(); |
1549 itr != source_state_map_.end(); ++itr) { | 1576 itr != source_state_map_.end(); ++itr) { |
1550 itr->second->OnSetDuration(duration_); | 1577 itr->second->OnSetDuration(duration_); |
1551 } | 1578 } |
1552 } | 1579 } |
1553 | 1580 |
1554 bool ChunkDemuxer::SetTimestampOffset(const std::string& id, TimeDelta offset) { | 1581 bool ChunkDemuxer::SetTimestampOffset(const std::string& id, double offset) { |
1555 base::AutoLock auto_lock(lock_); | 1582 base::AutoLock auto_lock(lock_); |
1556 DVLOG(1) << "SetTimestampOffset(" << id << ", " << offset.InSecondsF() << ")"; | 1583 DVLOG(1) << "SetTimestampOffset(" << id << ", " << offset << ")"; |
1557 CHECK(IsValidId(id)); | 1584 CHECK(IsValidId(id)); |
1558 | 1585 |
1559 return source_state_map_[id]->SetTimestampOffset(offset); | 1586 return source_state_map_[id]->SetTimestampOffset(offset); |
1560 } | 1587 } |
1561 | 1588 |
1589 double ChunkDemuxer::GetTimestampOffset(const std::string& id) { | |
1590 base::AutoLock auto_lock(lock_); | |
1591 DVLOG(1) << "GetTimestampOffset(" << id << ")"; | |
1592 CHECK(IsValidId(id)); | |
1593 | |
1594 return source_state_map_[id]->GetTimestampOffset(); | |
1595 } | |
1596 | |
1562 bool ChunkDemuxer::SetSequenceMode(const std::string& id, | 1597 bool ChunkDemuxer::SetSequenceMode(const std::string& id, |
1563 bool sequence_mode) { | 1598 bool sequence_mode) { |
1564 base::AutoLock auto_lock(lock_); | 1599 base::AutoLock auto_lock(lock_); |
1565 DVLOG(1) << "SetSequenceMode(" << id << ", " << sequence_mode << ")"; | 1600 DVLOG(1) << "SetSequenceMode(" << id << ", " << sequence_mode << ")"; |
1566 CHECK(IsValidId(id)); | 1601 CHECK(IsValidId(id)); |
1567 DCHECK_NE(state_, ENDED); | 1602 DCHECK_NE(state_, ENDED); |
1568 | 1603 |
1569 return source_state_map_[id]->SetSequenceMode(sequence_mode); | 1604 return source_state_map_[id]->SetSequenceMode(sequence_mode); |
1570 } | 1605 } |
1571 | 1606 |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1865 } | 1900 } |
1866 | 1901 |
1867 void ChunkDemuxer::ShutdownAllStreams() { | 1902 void ChunkDemuxer::ShutdownAllStreams() { |
1868 for (SourceStateMap::iterator itr = source_state_map_.begin(); | 1903 for (SourceStateMap::iterator itr = source_state_map_.begin(); |
1869 itr != source_state_map_.end(); ++itr) { | 1904 itr != source_state_map_.end(); ++itr) { |
1870 itr->second->Shutdown(); | 1905 itr->second->Shutdown(); |
1871 } | 1906 } |
1872 } | 1907 } |
1873 | 1908 |
1874 } // namespace media | 1909 } // namespace media |
OLD | NEW |