Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(314)

Unified Diff: media/filters/chunk_demuxer.cc

Issue 196173002: MSE: Lift timestampOffset and appendWindow[Start,End] storage to WebSourceBufferImpl (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: media/filters/chunk_demuxer.cc
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc
index 2e22cd834f5b69ad66f0a2a95b00207e94d5fcbd..71024a9adf55abc1489b0440fcb25b4b9c1c3e45 100644
--- a/media/filters/chunk_demuxer.cc
+++ b/media/filters/chunk_demuxer.cc
@@ -108,11 +108,14 @@ class SourceState {
// Appends new data to the StreamParser.
// Returns true if the data was successfully appended. Returns false if an
- // error occurred. Appending uses cached |timestamp_offset_| and may update
- // |*timestamp_offset| if |timestamp_offset| is not NULL.
- // TODO(wolenetz): Rework so |timestamp_offset_| is only valid during
- // Append(). See http://crbug.com/347623.
- bool Append(const uint8* data, size_t length, double* timestamp_offset);
+ // error occurred. |*timestamp_offset| is used and possibly updated by the
+ // append. |append_window_start| and |append_window_end| correspond to the MSE
+ // spec's similarly named source buffer attributes that are used in coded
+ // frame processing.
+ bool Append(const uint8* data, size_t length,
+ base::TimeDelta append_window_start_,
+ base::TimeDelta append_window_end_,
+ base::TimeDelta* timestamp_offset);
// Aborts the current append sequence and resets the parser.
void Abort();
@@ -121,20 +124,11 @@ class SourceState {
// ChunkDemuxerStreams managed by this object.
void Remove(TimeDelta start, TimeDelta end, TimeDelta duration);
- // Sets user-specified |timestamp_offset_| if possible.
- // Returns true if the offset was set. Returns false if the offset could not
- // be set at this time.
- bool SetTimestampOffset(TimeDelta timestamp_offset);
+ // Returns true if currently parsing a media segment, or false otherwise.
+ bool parsing_media_segment() const { return parsing_media_segment_; }
- // Sets |sequence_mode_| to |sequence_mode| if possible.
- // Returns true if the mode update was allowed. Returns false if the mode
- // could not be updated at this time.
- bool SetSequenceMode(bool sequence_mode);
-
- void set_append_window_start(TimeDelta start) {
- append_window_start_ = start;
- }
- void set_append_window_end(TimeDelta end) { append_window_end_ = end; }
+ // Sets |sequence_mode_| to |sequence_mode|.
+ void SetSequenceMode(bool sequence_mode);
// Returns the range of buffered data in this source, capped at |duration|.
// |ended| - Set to true if end of stream has been signalled and the special
@@ -178,10 +172,11 @@ class SourceState {
void OnEndOfMediaSegment();
// Called by the |stream_parser_| when new buffers have been parsed. It
- // applies |timestamp_offset_| to all buffers in |audio_buffers|,
- // |video_buffers| and |text_map| and then calls Append() with the modified
- // buffers on |audio_|, |video_| and/or the text demuxer streams associated
- // with the track numbers in |text_map|.
+ // applies |*timestamp_offset_during_append_| to all buffers in
+ // |audio_buffers|, |video_buffers| and |text_map|, filters buffers against
+ // |append_window_[start,end]_during_append_| and then calls Append()
+ // with the surviving modified buffers on |audio_|, |video_| and/or the text
+ // demuxer streams associated with the track numbers in |text_map|.
// Returns true on a successful call. Returns false if an error occurred while
// processing the buffers.
bool OnNewBuffers(const StreamParser::BufferQueue& audio_buffers,
@@ -189,8 +184,9 @@ class SourceState {
const StreamParser::TextBufferQueueMap& text_map);
// Helper function for OnNewBuffers() when new text buffers have been parsed.
- // It applies |timestamp_offset_| to all buffers in |buffers| and then appends
- // the (modified) buffers to the demuxer stream associated with
+ // It applies |*timestamp_offset_during_append_| to all buffers in |buffers|,
+ // filters the buffers against |append_window_[start,end]_during_append_| and
+ // then appends the (modified) buffers to the demuxer stream associated with
// the track having |text_track_id|.
// Returns true on a successful call. Returns false if an error occurred while
// processing the buffers.
@@ -204,11 +200,12 @@ class SourceState {
bool AppendAndUpdateDuration(ChunkDemuxerStream* stream,
const StreamParser::BufferQueue& buffers);
- // Helper function that adds |timestamp_offset_| to each buffer in |buffers|.
+ // Helper function that adds |*timestamp_offset_during_append_| to each buffer
+ // in |buffers|.
void AdjustBufferTimestamps(const StreamParser::BufferQueue& buffers);
// Filters out buffers that are outside of the append window
- // [|append_window_start_|, |append_window_end_|).
+ // [|append_window_start_during_append_|, |append_window_end_during_append_|).
// |needs_keyframe| is a pointer to the |xxx_need_keyframe_| flag
// associated with the |buffers|. Its state is read an updated as
// this method filters |buffers|.
@@ -222,12 +219,17 @@ class SourceState {
IncreaseDurationCB increase_duration_cb_;
NewTextTrackCB new_text_track_cb_;
- // The offset to apply to media segment timestamps.
- TimeDelta timestamp_offset_;
+ // During Append(), if OnNewBuffers() coded frame processing updates the
+ // timestamp offset then |*timestamp_offset_during_append_| is also updated
+ // so Append()'s caller can know the new offset. This pointer is only non-NULL
+ // during the lifetime of an Append() call.
+ TimeDelta* timestamp_offset_during_append_;
- // Flag that tracks whether or not the current Append() operation changed
- // |timestamp_offset_|.
- bool timestamp_offset_updated_by_append_;
+ // During Append(), coded frame processing triggered by OnNewBuffers()
+ // requires these two attributes. These are only valid during the lifetime of
+ // an Append() call.
+ TimeDelta append_window_start_during_append_;
+ TimeDelta append_window_end_during_append_;
// Tracks the mode by which appended media is processed. If true, then
// appended media is processed using "sequence" mode. Otherwise, appended
@@ -236,32 +238,30 @@ class SourceState {
// and http://crbug.com/333437.
bool sequence_mode_;
- TimeDelta append_window_start_;
- TimeDelta append_window_end_;
-
// Set to true if the next buffers appended within the append window
// represent the start of a new media segment. This flag being set
// triggers a call to |new_segment_cb_| when the new buffers are
// appended. The flag is set on actual media segment boundaries and
// when the "append window" filtering causes discontinuities in the
// appended data.
+ // TODO(wolenetz/acolwell): Investigate if we need this, or if coded frame
+ // processing's discontinuity logic is enough. See http://crbug.com/351489.
bool new_media_segment_;
- // Keeps track of whether |timestamp_offset_| or |sequence_mode_| can be
- // updated. These cannot be updated if a media segment is being parsed.
+ // Keeps track of whether a media segment is being parsed.
bool parsing_media_segment_;
// The object used to parse appended data.
scoped_ptr<StreamParser> stream_parser_;
- ChunkDemuxerStream* audio_;
+ ChunkDemuxerStream* audio_; // Not owned by |this|.
bool audio_needs_keyframe_;
- ChunkDemuxerStream* video_;
+ ChunkDemuxerStream* video_; // Not owned by |this|.
bool video_needs_keyframe_;
typedef std::map<StreamParser::TrackId, ChunkDemuxerStream*> TextStreamMap;
- TextStreamMap text_stream_map_;
+ TextStreamMap text_stream_map_; // |this| owns the map's stream pointers.
LogCB log_cb_;
@@ -370,9 +370,8 @@ SourceState::SourceState(scoped_ptr<StreamParser> stream_parser,
const IncreaseDurationCB& increase_duration_cb)
: create_demuxer_stream_cb_(create_demuxer_stream_cb),
increase_duration_cb_(increase_duration_cb),
- timestamp_offset_updated_by_append_(false),
+ timestamp_offset_during_append_(NULL),
sequence_mode_(false),
- append_window_end_(kInfiniteDuration()),
new_media_segment_(false),
parsing_media_segment_(false),
stream_parser_(stream_parser.release()),
@@ -414,30 +413,26 @@ void SourceState::Init(const StreamParser::InitCB& init_cb,
log_cb_);
}
-bool SourceState::SetTimestampOffset(TimeDelta timestamp_offset) {
- if (parsing_media_segment_)
- return false;
-
- timestamp_offset_ = timestamp_offset;
- return true;
-}
-
-bool SourceState::SetSequenceMode(bool sequence_mode) {
- if (parsing_media_segment_)
- return false;
+void SourceState::SetSequenceMode(bool sequence_mode) {
+ DCHECK(!parsing_media_segment_);
sequence_mode_ = sequence_mode;
- return true;
}
bool SourceState::Append(const uint8* data, size_t length,
- double* timestamp_offset) {
- timestamp_offset_updated_by_append_ = false;
+ base::TimeDelta append_window_start,
+ base::TimeDelta append_window_end,
+ base::TimeDelta* timestamp_offset) {
+ DCHECK(timestamp_offset);
+ DCHECK(!timestamp_offset_during_append_);
+ timestamp_offset_during_append_ = timestamp_offset;
+ append_window_start_during_append_ = append_window_start;
+ append_window_end_during_append_ = append_window_end;
+
+ // TODO(wolenetz/acolwell): Curry and pass a NewBuffersCB here bound with
+ // append window and timestamp offset pointer. See http://crbug.com/351454.
bool err = stream_parser_->Parse(data, length);
-
- if (timestamp_offset_updated_by_append_ && timestamp_offset)
- *timestamp_offset = timestamp_offset_.InSecondsF();
-
+ timestamp_offset_during_append_ = NULL;
return err;
}
@@ -633,14 +628,15 @@ bool SourceState::IsSeekWaitingForData() const {
void SourceState::AdjustBufferTimestamps(
const StreamParser::BufferQueue& buffers) {
- if (timestamp_offset_ == TimeDelta())
+ base::TimeDelta timestamp_offset = *timestamp_offset_during_append_;
acolwell GONE FROM CHROMIUM 2014/03/11 23:51:29 nit: drop base::
wolenetz 2014/03/12 00:02:32 Done (fixed here and in a few other places in this
+ if (timestamp_offset == TimeDelta())
return;
for (StreamParser::BufferQueue::const_iterator itr = buffers.begin();
itr != buffers.end(); ++itr) {
(*itr)->SetDecodeTimestamp(
- (*itr)->GetDecodeTimestamp() + timestamp_offset_);
- (*itr)->set_timestamp((*itr)->timestamp() + timestamp_offset_);
+ (*itr)->GetDecodeTimestamp() + timestamp_offset);
+ (*itr)->set_timestamp((*itr)->timestamp() + timestamp_offset);
}
}
@@ -782,6 +778,8 @@ bool SourceState::OnNewBuffers(
const StreamParser::BufferQueue& audio_buffers,
const StreamParser::BufferQueue& video_buffers,
const StreamParser::TextBufferQueueMap& text_map) {
+ DVLOG(2) << "OnNewBuffers()";
+ DCHECK(timestamp_offset_during_append_);
DCHECK(!audio_buffers.empty() || !video_buffers.empty() ||
!text_map.empty());
@@ -915,8 +913,8 @@ void SourceState::FilterWithAppendWindow(
// |presentation_timestamp + (*itr)->duration()|, like the spec
// requires, once frame durations are actually present in all buffers.
TimeDelta frame_end_timestamp = presentation_timestamp;
- if (presentation_timestamp < append_window_start_ ||
- frame_end_timestamp > append_window_end_) {
+ if (presentation_timestamp < append_window_start_during_append_ ||
+ frame_end_timestamp > append_window_end_during_append_) {
DVLOG(1) << "Dropping buffer outside append window."
<< " presentation_timestamp "
<< presentation_timestamp.InSecondsF();
@@ -1421,10 +1419,13 @@ Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const {
void ChunkDemuxer::AppendData(const std::string& id,
const uint8* data, size_t length,
- double* timestamp_offset) {
+ base::TimeDelta append_window_start,
+ base::TimeDelta append_window_end,
+ base::TimeDelta* timestamp_offset) {
DVLOG(1) << "AppendData(" << id << ", " << length << ")";
DCHECK(!id.empty());
+ DCHECK(timestamp_offset);
Ranges<TimeDelta> ranges;
@@ -1445,6 +1446,8 @@ void ChunkDemuxer::AppendData(const std::string& id,
case INITIALIZING:
DCHECK(IsValidId(id));
if (!source_state_map_[id]->Append(data, length,
+ append_window_start,
+ append_window_end,
timestamp_offset)) {
ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN);
return;
@@ -1454,6 +1457,8 @@ void ChunkDemuxer::AppendData(const std::string& id,
case INITIALIZED: {
DCHECK(IsValidId(id));
if (!source_state_map_[id]->Append(data, length,
+ append_window_start,
+ append_window_end,
timestamp_offset)) {
ReportError_Locked(PIPELINE_ERROR_DECODE);
return;
@@ -1566,22 +1571,22 @@ void ChunkDemuxer::SetDuration(double duration) {
}
}
-bool ChunkDemuxer::SetTimestampOffset(const std::string& id, TimeDelta offset) {
+bool ChunkDemuxer::IsParsingMediaSegment(const std::string& id) {
base::AutoLock auto_lock(lock_);
- DVLOG(1) << "SetTimestampOffset(" << id << ", " << offset.InSecondsF() << ")";
+ DVLOG(1) << "IsParsingMediaSegment(" << id << ")";
CHECK(IsValidId(id));
- return source_state_map_[id]->SetTimestampOffset(offset);
+ return source_state_map_[id]->parsing_media_segment();
}
-bool ChunkDemuxer::SetSequenceMode(const std::string& id,
+void ChunkDemuxer::SetSequenceMode(const std::string& id,
bool sequence_mode) {
base::AutoLock auto_lock(lock_);
DVLOG(1) << "SetSequenceMode(" << id << ", " << sequence_mode << ")";
CHECK(IsValidId(id));
DCHECK_NE(state_, ENDED);
- return source_state_map_[id]->SetSequenceMode(sequence_mode);
+ source_state_map_[id]->SetSequenceMode(sequence_mode);
}
void ChunkDemuxer::MarkEndOfStream(PipelineStatus status) {
@@ -1634,22 +1639,6 @@ void ChunkDemuxer::UnmarkEndOfStream() {
}
}
-void ChunkDemuxer::SetAppendWindowStart(const std::string& id,
- TimeDelta start) {
- base::AutoLock auto_lock(lock_);
- DVLOG(1) << "SetAppendWindowStart(" << id << ", "
- << start.InSecondsF() << ")";
- CHECK(IsValidId(id));
- source_state_map_[id]->set_append_window_start(start);
-}
-
-void ChunkDemuxer::SetAppendWindowEnd(const std::string& id, TimeDelta end) {
- base::AutoLock auto_lock(lock_);
- DVLOG(1) << "SetAppendWindowEnd(" << id << ", " << end.InSecondsF() << ")";
- CHECK(IsValidId(id));
- source_state_map_[id]->set_append_window_end(end);
-}
-
void ChunkDemuxer::Shutdown() {
DVLOG(1) << "Shutdown()";
base::AutoLock auto_lock(lock_);

Powered by Google App Engine
This is Rietveld 408576698