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

Unified Diff: media/filters/chunk_demuxer.cc

Issue 191513002: Extract coded frame processing from SourceState into LegacyFrameProcessor (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase and address PS2 comments and nits 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..e0fbfb2e1812083971caea9f905a0bd2c8dcc120 100644
--- a/media/filters/chunk_demuxer.cc
+++ b/media/filters/chunk_demuxer.cc
@@ -5,7 +5,6 @@
#include "media/filters/chunk_demuxer.h"
#include <algorithm>
-#include <deque>
#include <limits>
#include <list>
@@ -18,6 +17,7 @@
#include "media/base/bind_to_current_loop.h"
#include "media/base/stream_parser_buffer.h"
#include "media/base/video_decoder_config.h"
+#include "media/filters/legacy_frame_processor.h"
#include "media/filters/stream_parser_factory.h"
using base::TimeDelta;
@@ -86,17 +86,13 @@ class SourceState {
typedef base::Callback<ChunkDemuxerStream*(
DemuxerStream::Type)> CreateDemuxerStreamCB;
- // Callback signature used to notify ChunkDemuxer of timestamps
- // that may cause the duration to be updated.
- typedef base::Callback<void(
- TimeDelta, ChunkDemuxerStream*)> IncreaseDurationCB;
-
typedef base::Callback<void(
ChunkDemuxerStream*, const TextTrackConfig&)> NewTextTrackCB;
- SourceState(scoped_ptr<StreamParser> stream_parser, const LogCB& log_cb,
- const CreateDemuxerStreamCB& create_demuxer_stream_cb,
- const IncreaseDurationCB& increase_duration_cb);
+ SourceState(
+ scoped_ptr<StreamParser> stream_parser,
+ scoped_ptr<FrameProcessorBase> frame_processor, const LogCB& log_cb,
+ const CreateDemuxerStreamCB& create_demuxer_stream_cb);
~SourceState();
@@ -108,11 +104,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,
+ const base::TimeDelta& append_window_start,
acolwell GONE FROM CHROMIUM 2014/03/11 20:00:37 ditto
wolenetz 2014/03/12 00:46:14 Done in the prereq CL I split out of this.
+ const base::TimeDelta& append_window_end,
+ base::TimeDelta* timestamp_offset);
// Aborts the current append sequence and resets the parser.
void Abort();
@@ -121,20 +120,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 IsParsingMediaSegment() const { return parsing_media_segment_; }
acolwell GONE FROM CHROMIUM 2014/03/11 20:00:37 nit: unix_hacker_style since this is a simple acce
wolenetz 2014/03/12 00:46:14 Done in the prereq CL I split out of this.
- // 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 |frame_processor_|'s 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
@@ -177,67 +167,30 @@ class SourceState {
// Called by the |stream_parser_| at the end of a media segment.
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|.
+ // Called by the |stream_parser_| when new buffers have been parsed.
+ // It processes the new buffers using |frame_processor_|, which includes
+ // appending the processed frames to associated demuxer streams for each
+ // frame's track.
// Returns true on a successful call. Returns false if an error occurred while
// processing the buffers.
bool OnNewBuffers(const StreamParser::BufferQueue& audio_buffers,
const StreamParser::BufferQueue& video_buffers,
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
- // the track having |text_track_id|.
- // Returns true on a successful call. Returns false if an error occurred while
- // processing the buffers.
- bool OnTextBuffers(StreamParser::TrackId text_track_id,
- const StreamParser::BufferQueue& buffers);
-
- // Helper function that appends |buffers| to |stream| and calls
- // |increase_duration_cb_| to potentially update the duration.
- // Returns true if the append was successful. Returns false if
- // |stream| is NULL or something in |buffers| caused the append to fail.
- bool AppendAndUpdateDuration(ChunkDemuxerStream* stream,
- const StreamParser::BufferQueue& buffers);
-
- // Helper function that adds |timestamp_offset_| 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_|).
- // |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|.
- // Buffers that are inside the append window are appended to the end
- // of |filtered_buffers|.
- void FilterWithAppendWindow(const StreamParser::BufferQueue& buffers,
- bool* needs_keyframe,
- StreamParser::BufferQueue* filtered_buffers);
-
CreateDemuxerStreamCB create_demuxer_stream_cb_;
- IncreaseDurationCB increase_duration_cb_;
NewTextTrackCB new_text_track_cb_;
- // The offset to apply to media segment timestamps.
- TimeDelta timestamp_offset_;
-
- // Flag that tracks whether or not the current Append() operation changed
- // |timestamp_offset_|.
- bool timestamp_offset_updated_by_append_;
-
- // Tracks the mode by which appended media is processed. If true, then
- // appended media is processed using "sequence" mode. Otherwise, appended
- // media is processed using "segments" mode.
- // TODO(wolenetz): Enable "sequence" mode logic. See http://crbug.com/249422
- // and http://crbug.com/333437.
- bool sequence_mode_;
+ // 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.
+ base::TimeDelta* timestamp_offset_during_append_;
- TimeDelta append_window_start_;
- TimeDelta append_window_end_;
+ // During Append(), coded frame processing triggered by OnNewBuffers()
+ // requires these two attributes. These are only valid during the lifetime of
+ // an Append() call.
+ base::TimeDelta append_window_start_during_append_;
+ base::TimeDelta append_window_end_during_append_;
// Set to true if the next buffers appended within the append window
// represent the start of a new media segment. This flag being set
@@ -247,142 +200,40 @@ class SourceState {
// appended data.
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_;
- bool audio_needs_keyframe_;
-
- ChunkDemuxerStream* video_;
- bool video_needs_keyframe_;
+ ChunkDemuxerStream* audio_; // Not owned by |this|.
+ ChunkDemuxerStream* video_; // Not owned by |this|.
typedef std::map<StreamParser::TrackId, ChunkDemuxerStream*> TextStreamMap;
- TextStreamMap text_stream_map_;
+ TextStreamMap text_stream_map_; // |this| owns the map's stream pointers.
+ scoped_ptr<FrameProcessorBase> frame_processor_;
LogCB log_cb_;
DISALLOW_COPY_AND_ASSIGN(SourceState);
};
-class ChunkDemuxerStream : public DemuxerStream {
- public:
- typedef std::deque<scoped_refptr<StreamParserBuffer> > BufferQueue;
-
- explicit ChunkDemuxerStream(Type type);
- virtual ~ChunkDemuxerStream();
-
- // ChunkDemuxerStream control methods.
- void StartReturningData();
- void AbortReads();
- void CompletePendingReadIfPossible();
- void Shutdown();
-
- // SourceBufferStream manipulation methods.
- void Seek(TimeDelta time);
- bool IsSeekWaitingForData() const;
-
- // Add buffers to this stream. Buffers are stored in SourceBufferStreams,
- // which handle ordering and overlap resolution.
- // Returns true if buffers were successfully added.
- bool Append(const StreamParser::BufferQueue& buffers);
-
- // Removes buffers between |start| and |end| according to the steps
- // in the "Coded Frame Removal Algorithm" in the Media Source
- // Extensions Spec.
- // https://dvcs.w3.org/hg/html-media/raw-file/default/media-source/media-source.html#sourcebuffer-coded-frame-removal
- //
- // |duration| is the current duration of the presentation. It is
- // required by the computation outlined in the spec.
- void Remove(TimeDelta start, TimeDelta end, TimeDelta duration);
-
- // Signal to the stream that duration has changed to |duration|.
- void OnSetDuration(TimeDelta duration);
-
- // Returns the range of buffered data in this stream, capped at |duration|.
- Ranges<TimeDelta> GetBufferedRanges(TimeDelta duration) const;
-
- // Returns the duration of the buffered data.
- // Returns TimeDelta() if the stream has no buffered data.
- TimeDelta GetBufferedDuration() const;
-
- // Signal to the stream that buffers handed in through subsequent calls to
- // Append() belong to a media segment that starts at |start_timestamp|.
- void OnNewMediaSegment(TimeDelta start_timestamp);
-
- // Called when midstream config updates occur.
- // Returns true if the new config is accepted.
- // Returns false if the new config should trigger an error.
- bool UpdateAudioConfig(const AudioDecoderConfig& config, const LogCB& log_cb);
- bool UpdateVideoConfig(const VideoDecoderConfig& config, const LogCB& log_cb);
- void UpdateTextConfig(const TextTrackConfig& config, const LogCB& log_cb);
-
- void MarkEndOfStream();
- void UnmarkEndOfStream();
-
- // DemuxerStream methods.
- virtual void Read(const ReadCB& read_cb) OVERRIDE;
- virtual Type type() OVERRIDE;
- virtual void EnableBitstreamConverter() OVERRIDE;
- virtual AudioDecoderConfig audio_decoder_config() OVERRIDE;
- virtual VideoDecoderConfig video_decoder_config() OVERRIDE;
-
- // Returns the text track configuration. It is an error to call this method
- // if type() != TEXT.
- TextTrackConfig text_track_config();
-
- // Sets the memory limit, in bytes, on the SourceBufferStream.
- void set_memory_limit_for_testing(int memory_limit) {
- stream_->set_memory_limit_for_testing(memory_limit);
- }
-
- private:
- enum State {
- UNINITIALIZED,
- RETURNING_DATA_FOR_READS,
- RETURNING_ABORT_FOR_READS,
- SHUTDOWN,
- };
-
- // Assigns |state_| to |state|
- void ChangeState_Locked(State state);
-
- void CompletePendingReadIfPossible_Locked();
-
- // Specifies the type of the stream.
- Type type_;
-
- scoped_ptr<SourceBufferStream> stream_;
-
- mutable base::Lock lock_;
- State state_;
- ReadCB read_cb_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(ChunkDemuxerStream);
-};
-
-SourceState::SourceState(scoped_ptr<StreamParser> stream_parser,
- const LogCB& log_cb,
- const CreateDemuxerStreamCB& create_demuxer_stream_cb,
- const IncreaseDurationCB& increase_duration_cb)
+SourceState::SourceState(
+ scoped_ptr<StreamParser> stream_parser,
+ scoped_ptr<FrameProcessorBase> frame_processor,
+ const LogCB& log_cb,
+ const CreateDemuxerStreamCB& create_demuxer_stream_cb)
: create_demuxer_stream_cb_(create_demuxer_stream_cb),
- increase_duration_cb_(increase_duration_cb),
- timestamp_offset_updated_by_append_(false),
- sequence_mode_(false),
- append_window_end_(kInfiniteDuration()),
+ timestamp_offset_during_append_(NULL),
new_media_segment_(false),
parsing_media_segment_(false),
stream_parser_(stream_parser.release()),
audio_(NULL),
- audio_needs_keyframe_(true),
video_(NULL),
- video_needs_keyframe_(true),
+ frame_processor_(frame_processor.release()),
log_cb_(log_cb) {
DCHECK(!create_demuxer_stream_cb_.is_null());
- DCHECK(!increase_duration_cb_.is_null());
+ DCHECK(frame_processor_);
}
SourceState::~SourceState() {
@@ -414,37 +265,29 @@ 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;
+ frame_processor_->SetSequenceMode(sequence_mode);
}
bool SourceState::Append(const uint8* data, size_t length,
- double* timestamp_offset) {
- timestamp_offset_updated_by_append_ = false;
+ const base::TimeDelta& append_window_start,
+ const 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;
bool err = stream_parser_->Parse(data, length);
acolwell GONE FROM CHROMIUM 2014/03/11 20:00:37 nit: Add a TODO here to change the StreamParser::P
wolenetz 2014/03/12 00:46:14 Done in prereq CL I split out of this. I assigned
-
- if (timestamp_offset_updated_by_append_ && timestamp_offset)
- *timestamp_offset = timestamp_offset_.InSecondsF();
-
+ timestamp_offset_during_append_ = NULL;
return err;
}
void SourceState::Abort() {
stream_parser_->Flush();
- audio_needs_keyframe_ = true;
- video_needs_keyframe_ = true;
+ frame_processor_->Reset();
parsing_media_segment_ = false;
}
@@ -631,19 +474,6 @@ bool SourceState::IsSeekWaitingForData() const {
return false;
}
-void SourceState::AdjustBufferTimestamps(
- const StreamParser::BufferQueue& buffers) {
- 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_);
- }
-}
-
bool SourceState::OnNewConfigs(
bool allow_audio, bool allow_video,
const AudioDecoderConfig& audio_config,
@@ -689,6 +519,12 @@ bool SourceState::OnNewConfigs(
DVLOG(1) << "Failed to create an audio stream.";
return false;
}
+
+ if (!frame_processor_->AddTrack(FrameProcessorBase::kAudioTrackId,
+ audio_)) {
+ DVLOG(1) << "Failed to add audio track to frame processor.";
+ return false;
+ }
}
success &= audio_->UpdateAudioConfig(audio_config, log_cb_);
@@ -702,6 +538,12 @@ bool SourceState::OnNewConfigs(
DVLOG(1) << "Failed to create a video stream.";
return false;
}
+
+ if (!frame_processor_->AddTrack(FrameProcessorBase::kVideoTrackId,
+ video_)) {
+ DVLOG(1) << "Failed to add video track to frame processor.";
+ return false;
+ }
}
success &= video_->UpdateVideoConfig(video_config, log_cb_);
@@ -713,6 +555,12 @@ bool SourceState::OnNewConfigs(
itr != text_configs.end(); ++itr) {
ChunkDemuxerStream* const text_stream =
create_demuxer_stream_cb_.Run(DemuxerStream::TEXT);
+ if (!frame_processor_->AddTrack(itr->first, text_stream)) {
+ success &= false;
+ MEDIA_LOG(log_cb_) << "Failed to add text track ID " << itr->first
+ << " to frame processor.";
+ break;
+ }
text_stream->UpdateTextConfig(itr->second, log_cb_);
text_stream_map_[itr->first] = text_stream;
new_text_track_cb_.Run(text_stream, itr->second);
@@ -782,167 +630,13 @@ bool SourceState::OnNewBuffers(
const StreamParser::BufferQueue& audio_buffers,
const StreamParser::BufferQueue& video_buffers,
const StreamParser::TextBufferQueueMap& text_map) {
- DCHECK(!audio_buffers.empty() || !video_buffers.empty() ||
- !text_map.empty());
-
- // TODO(wolenetz): DCHECK + return false if any of these buffers have UNKNOWN
- // type() in upcoming coded frame processing compliant implementation. See
- // http://crbug.com/249422.
-
- AdjustBufferTimestamps(audio_buffers);
- AdjustBufferTimestamps(video_buffers);
-
- StreamParser::BufferQueue filtered_audio;
- StreamParser::BufferQueue filtered_video;
-
- FilterWithAppendWindow(audio_buffers, &audio_needs_keyframe_,
- &filtered_audio);
-
- FilterWithAppendWindow(video_buffers, &video_needs_keyframe_,
- &filtered_video);
-
- if ((!filtered_audio.empty() || !filtered_video.empty()) &&
- new_media_segment_) {
- // Find the earliest timestamp in the filtered buffers and use that for the
- // segment start timestamp.
- TimeDelta segment_timestamp = kNoTimestamp();
-
- if (!filtered_audio.empty())
- segment_timestamp = filtered_audio.front()->GetDecodeTimestamp();
-
- if (!filtered_video.empty() &&
- (segment_timestamp == kNoTimestamp() ||
- filtered_video.front()->GetDecodeTimestamp() < segment_timestamp)) {
- segment_timestamp = filtered_video.front()->GetDecodeTimestamp();
- }
-
- new_media_segment_ = false;
-
- if (audio_)
- audio_->OnNewMediaSegment(segment_timestamp);
-
- if (video_)
- video_->OnNewMediaSegment(segment_timestamp);
-
- for (TextStreamMap::iterator itr = text_stream_map_.begin();
- itr != text_stream_map_.end(); ++itr) {
- itr->second->OnNewMediaSegment(segment_timestamp);
- }
- }
-
- if (!filtered_audio.empty() &&
- !AppendAndUpdateDuration(audio_, filtered_audio)) {
- return false;
- }
-
- if (!filtered_video.empty() &&
- !AppendAndUpdateDuration(video_, filtered_video)) {
- return false;
- }
-
- if (text_map.empty())
- return true;
-
- // Process any buffers for each of the text tracks in the map.
- bool all_text_buffers_empty = true;
- for (StreamParser::TextBufferQueueMap::const_iterator itr = text_map.begin();
- itr != text_map.end();
- ++itr) {
- const StreamParser::BufferQueue text_buffers = itr->second;
- if (!text_buffers.empty()) {
- all_text_buffers_empty = false;
- if (!OnTextBuffers(itr->first, text_buffers))
- return false;
- }
- }
-
- DCHECK(!all_text_buffers_empty);
- return true;
-}
+ DVLOG(2) << "OnNewBuffers()";
+ DCHECK(timestamp_offset_during_append_);
-bool SourceState::OnTextBuffers(
- StreamParser::TrackId text_track_id,
- const StreamParser::BufferQueue& buffers) {
- DCHECK(!buffers.empty());
-
- TextStreamMap::iterator itr = text_stream_map_.find(text_track_id);
- if (itr == text_stream_map_.end())
- return false;
-
- AdjustBufferTimestamps(buffers);
-
- StreamParser::BufferQueue filtered_buffers;
- bool needs_keyframe = false;
- FilterWithAppendWindow(buffers, &needs_keyframe, &filtered_buffers);
-
- if (filtered_buffers.empty())
- return true;
-
- return AppendAndUpdateDuration(itr->second, filtered_buffers);
-}
-
-bool SourceState::AppendAndUpdateDuration(
- ChunkDemuxerStream* stream,
- const StreamParser::BufferQueue& buffers) {
- DCHECK(!buffers.empty());
-
- if (!stream || !stream->Append(buffers))
- return false;
-
- increase_duration_cb_.Run(buffers.back()->timestamp(), stream);
- return true;
-}
-
-void SourceState::FilterWithAppendWindow(
- const StreamParser::BufferQueue& buffers, bool* needs_keyframe,
- StreamParser::BufferQueue* filtered_buffers) {
- DCHECK(needs_keyframe);
- DCHECK(filtered_buffers);
-
- // This loop implements steps 1.9, 1.10, & 1.11 of the "Coded frame
- // processing loop" in the Media Source Extensions spec.
- // These steps filter out buffers that are not within the "append
- // window" and handles resyncing on the next random access point
- // (i.e., next keyframe) if a buffer gets dropped.
- for (StreamParser::BufferQueue::const_iterator itr = buffers.begin();
- itr != buffers.end(); ++itr) {
- // Filter out buffers that are outside the append window. Anytime
- // a buffer gets dropped we need to set |*needs_keyframe| to true
- // because we can only resume decoding at keyframes.
- TimeDelta presentation_timestamp = (*itr)->timestamp();
-
- // TODO(acolwell): Change |frame_end_timestamp| value to
- // |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_) {
- DVLOG(1) << "Dropping buffer outside append window."
- << " presentation_timestamp "
- << presentation_timestamp.InSecondsF();
- *needs_keyframe = true;
-
- // This triggers a discontinuity so we need to treat the next frames
- // appended within the append window as if they were the beginning of a
- // new segment.
- new_media_segment_ = true;
- continue;
- }
-
- // If |*needs_keyframe| is true then filter out buffers until we
- // encounter the next keyframe.
- if (*needs_keyframe) {
- if (!(*itr)->IsKeyframe()) {
- DVLOG(1) << "Dropping non-keyframe. presentation_timestamp "
- << presentation_timestamp.InSecondsF();
- continue;
- }
-
- *needs_keyframe = false;
- }
-
- filtered_buffers->push_back(*itr);
- }
+ return frame_processor_->ProcessFrames(
+ audio_buffers, video_buffers, text_map,
+ append_window_start_during_append_, append_window_end_during_append_,
+ &new_media_segment_, timestamp_offset_during_append_);
}
ChunkDemuxerStream::ChunkDemuxerStream(Type type)
@@ -1370,11 +1064,14 @@ ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id,
if (has_video)
source_id_video_ = id;
+ scoped_ptr<FrameProcessorBase> frame_processor(new LegacyFrameProcessor(
+ base::Bind(&ChunkDemuxer::IncreaseDurationIfNecessary,
+ base::Unretained(this))));
+
scoped_ptr<SourceState> source_state(
- new SourceState(stream_parser.Pass(), log_cb_,
+ new SourceState(stream_parser.Pass(),
+ frame_processor.Pass(), log_cb_,
base::Bind(&ChunkDemuxer::CreateDemuxerStream,
- base::Unretained(this)),
- base::Bind(&ChunkDemuxer::IncreaseDurationIfNecessary,
base::Unretained(this))));
SourceState::NewTextTrackCB new_text_track_cb;
@@ -1421,10 +1118,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) {
+ const base::TimeDelta& append_window_start,
+ const 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 +1145,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 +1156,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 +1270,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]->IsParsingMediaSegment();
}
-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 +1338,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