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

Unified Diff: media/filters/chunk_demuxer.cc

Issue 195973006: Allow StreamParsers to request automatic timestampOffset updates. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix timestamp offset. 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
« no previous file with comments | « media/base/stream_parser.h ('k') | media/filters/pipeline_integration_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/filters/chunk_demuxer.cc
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc
index 17f1d96c9046de426f653cddef6ff0565b403901..bf21d006f2ee9944f63a8a8f94a79833e814a908 100644
--- a/media/filters/chunk_demuxer.cc
+++ b/media/filters/chunk_demuxer.cc
@@ -24,6 +24,30 @@ using base::TimeDelta;
namespace media {
+// Compute the end timestamp for buffers within an append window range.
+// TODO(dalecurtis): This code should probably live in the frame processor, but
+// requires some spec updates before we can do so. For now it's a logical clone
+// of LegacyFrameProcessor::FilterWithAppendWindow().
+static TimeDelta EndTimestamp(const StreamParser::BufferQueue& buffers,
+ TimeDelta append_window_start,
+ TimeDelta append_window_end) {
+ TimeDelta end_timestamp = kNoTimestamp();
+
+ // Find the last buffer within the append window range.
+ for (StreamParser::BufferQueue::const_reverse_iterator itr = buffers.rbegin();
+ itr != buffers.rend();
+ ++itr) {
+ const scoped_refptr<StreamParserBuffer>& buffer = *itr;
+ if (buffer->timestamp() >= append_window_start &&
+ buffer->timestamp() <= append_window_end) {
+ end_timestamp = buffer->timestamp() + buffer->duration();
+ break;
+ }
+ }
+
+ return end_timestamp;
+}
+
// List of time ranges for each SourceBuffer.
typedef std::list<Ranges<TimeDelta> > RangesList;
static Ranges<TimeDelta> ComputeIntersection(const RangesList& activeRanges,
@@ -89,6 +113,13 @@ class SourceState {
typedef base::Callback<void(
ChunkDemuxerStream*, const TextTrackConfig&)> NewTextTrackCB;
+ // First parameter - Indicates initialization success. Set to true if
+ // initialization was successful. False if an error
+ // occurred.
+ // Second parameter - Indicates the stream duration. Only contains a valid
+ // value if the first parameter is true.
+ typedef base::Callback<void(bool, TimeDelta)> InitCB;
+
SourceState(
scoped_ptr<StreamParser> stream_parser,
scoped_ptr<FrameProcessorBase> frame_processor, const LogCB& log_cb,
@@ -96,7 +127,7 @@ class SourceState {
~SourceState();
- void Init(const StreamParser::InitCB& init_cb,
+ void Init(const InitCB& init_cb,
bool allow_audio,
bool allow_video,
const StreamParser::NeedKeyCB& need_key_cb,
@@ -177,6 +208,10 @@ class SourceState {
const StreamParser::BufferQueue& video_buffers,
const StreamParser::TextBufferQueueMap& text_map);
+ void OnSourceInitDone(bool success,
+ TimeDelta duration,
+ bool auto_update_timestamp_offset);
+
CreateDemuxerStreamCB create_demuxer_stream_cb_;
NewTextTrackCB new_text_track_cb_;
@@ -216,6 +251,11 @@ class SourceState {
scoped_ptr<FrameProcessorBase> frame_processor_;
LogCB log_cb_;
+ InitCB init_cb_;
+
+ // Indicates that timestampOffset should be updated automatically during
+ // OnNewBuffers() based on the earliest end timestamp of the buffers provided.
+ bool auto_update_timestamp_offset_;
DISALLOW_COPY_AND_ASSIGN(SourceState);
};
@@ -233,7 +273,8 @@ SourceState::SourceState(
audio_(NULL),
video_(NULL),
frame_processor_(frame_processor.release()),
- log_cb_(log_cb) {
+ log_cb_(log_cb),
+ auto_update_timestamp_offset_(false) {
DCHECK(!create_demuxer_stream_cb_.is_null());
DCHECK(frame_processor_);
}
@@ -244,14 +285,16 @@ SourceState::~SourceState() {
STLDeleteValues(&text_stream_map_);
}
-void SourceState::Init(const StreamParser::InitCB& init_cb,
+void SourceState::Init(const InitCB& init_cb,
bool allow_audio,
bool allow_video,
const StreamParser::NeedKeyCB& need_key_cb,
const NewTextTrackCB& new_text_track_cb) {
new_text_track_cb_ = new_text_track_cb;
+ init_cb_ = init_cb;
- stream_parser_->Init(init_cb,
+ stream_parser_->Init(base::Bind(&SourceState::OnSourceInitDone,
+ base::Unretained(this)),
base::Bind(&SourceState::OnNewConfigs,
base::Unretained(this),
allow_audio,
@@ -638,10 +681,45 @@ bool SourceState::OnNewBuffers(
DVLOG(2) << "OnNewBuffers()";
DCHECK(timestamp_offset_during_append_);
- 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_);
+ const TimeDelta current_timestamp_offset = *timestamp_offset_during_append_;
+ const bool success =
wolenetz 2014/03/18 02:09:30 nit: If |success| is false, this indicates a parse
DaleCurtis 2014/03/18 02:16:04 Done.
+ 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_);
+
+ // Update the timestamp offset for audio/video tracks if it hasn't already
+ // been updated by the frame processor.
+ if (auto_update_timestamp_offset_ &&
+ current_timestamp_offset == *timestamp_offset_during_append_) {
+ const TimeDelta audio_end = EndTimestamp(audio_buffers,
+ append_window_start_during_append_,
+ append_window_end_during_append_);
+ const TimeDelta video_end = EndTimestamp(audio_buffers,
wolenetz 2014/03/18 02:09:30 s/audio_buf/video_buf/
DaleCurtis 2014/03/18 02:16:04 Done.
+ append_window_start_during_append_,
+ append_window_end_during_append_);
+ const bool have_audio_buffers = audio_end != kNoTimestamp();
+ const bool have_video_buffers = video_end != kNoTimestamp();
+ if (have_audio_buffers && have_video_buffers) {
+ *timestamp_offset_during_append_ = std::min(audio_end, video_end);
+ } else if (have_audio_buffers) {
+ *timestamp_offset_during_append_ = audio_end;
+ } else if (have_video_buffers) {
+ *timestamp_offset_during_append_ = video_end;
+ }
+ }
+
+ return success;
+}
+
+void SourceState::OnSourceInitDone(bool success,
+ TimeDelta duration,
+ bool auto_update_timestamp_offset) {
+ auto_update_timestamp_offset_ = auto_update_timestamp_offset;
+ base::ResetAndReturn(&init_cb_).Run(success, duration);
}
ChunkDemuxerStream::ChunkDemuxerStream(Type type)
@@ -1417,8 +1495,8 @@ bool ChunkDemuxer::IsSeekWaitingForData_Locked() const {
}
void ChunkDemuxer::OnSourceInitDone(bool success, TimeDelta duration) {
- DVLOG(1) << "OnSourceInitDone(" << success << ", "
- << duration.InSecondsF() << ")";
+ DVLOG(1) << "OnSourceInitDone(" << success
+ << ", " << duration.InSecondsF() << ")";
lock_.AssertAcquired();
DCHECK_EQ(state_, INITIALIZING);
if (!success || (!audio_ && !video_)) {
« no previous file with comments | « media/base/stream_parser.h ('k') | media/filters/pipeline_integration_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698