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

Unified Diff: media/filters/chunk_demuxer.cc

Issue 10803019: Chrome-side implementation of media source timestamp offset (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase ToT Created 8 years, 5 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/filters/chunk_demuxer.h ('k') | media/filters/chunk_demuxer_unittest.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 be4fa60ce46ed00b59e8d39b3c8d30784ada33c5..29e31af00d7aae8f5fc64596f357c770e4af7136 100644
--- a/media/filters/chunk_demuxer.cc
+++ b/media/filters/chunk_demuxer.cc
@@ -111,7 +111,7 @@ static bool IsSupported(const std::string& type,
*has_audio = false;
*has_video = false;
- // Search for the SupportedTypeInfo for |type|
+ // Search for the SupportedTypeInfo for |type|.
for (size_t i = 0; i < arraysize(kSupportedTypeInfo); ++i) {
const SupportedTypeInfo& type_info = kSupportedTypeInfo[i];
if (type == type_info.type) {
@@ -637,19 +637,24 @@ ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id,
audio_cb,
video_cb,
base::Bind(&ChunkDemuxer::OnNeedKey, base::Unretained(this)),
- base::Bind(&ChunkDemuxer::OnNewMediaSegment, base::Unretained(this), id));
+ base::Bind(&ChunkDemuxer::OnNewMediaSegment, base::Unretained(this), id),
+ base::Bind(&ChunkDemuxer::OnEndOfMediaSegment,
+ base::Unretained(this), id));
stream_parser_map_[id] = stream_parser.release();
+ SourceInfo info = { base::TimeDelta(), true };
+ source_info_map_[id] = info;
return kOk;
}
void ChunkDemuxer::RemoveId(const std::string& id) {
- CHECK_GT(stream_parser_map_.count(id), 0u);
+ CHECK(IsValidId(id));
base::AutoLock auto_lock(lock_);
delete stream_parser_map_[id];
stream_parser_map_.erase(id);
+ source_info_map_.erase(id);
if (source_id_audio_ == id && audio_)
audio_->Shutdown();
@@ -660,7 +665,7 @@ void ChunkDemuxer::RemoveId(const std::string& id) {
Ranges<TimeDelta> ChunkDemuxer::GetBufferedRanges(const std::string& id) const {
DCHECK(!id.empty());
- DCHECK_GT(stream_parser_map_.count(id), 0u);
+ DCHECK(IsValidId(id));
DCHECK(id == source_id_audio_ || id == source_id_video_);
base::AutoLock auto_lock(lock_);
@@ -730,7 +735,7 @@ bool ChunkDemuxer::AppendData(const std::string& id,
switch (state_) {
case INITIALIZING:
case WAITING_FOR_START_TIME:
- DCHECK_GT(stream_parser_map_.count(id), 0u);
+ DCHECK(IsValidId(id));
if (!stream_parser_map_[id]->Parse(data, length)) {
ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN);
return true;
@@ -738,7 +743,7 @@ bool ChunkDemuxer::AppendData(const std::string& id,
break;
case INITIALIZED: {
- DCHECK_GT(stream_parser_map_.count(id), 0u);
+ DCHECK(IsValidId(id));
if (!stream_parser_map_[id]->Parse(data, length)) {
ReportError_Locked(PIPELINE_ERROR_DECODE);
return true;
@@ -780,11 +785,24 @@ bool ChunkDemuxer::AppendData(const std::string& id,
void ChunkDemuxer::Abort(const std::string& id) {
DVLOG(1) << "Abort(" << id << ")";
DCHECK(!id.empty());
- DCHECK_GT(stream_parser_map_.count(id), 0u);
+ CHECK(IsValidId(id));
stream_parser_map_[id]->Flush();
}
+bool ChunkDemuxer::SetTimestampOffset(const std::string& id, double offset) {
+ DVLOG(1) << "SetTimestampOffset(" << id << ", " << offset << ")";
+ CHECK(IsValidId(id));
+
+ if (!source_info_map_[id].can_update_offset)
+ return false;
+
+ TimeDelta time_offset = TimeDelta::FromMicroseconds(
+ offset * base::Time::kMicrosecondsPerSecond);
+ source_info_map_[id].timestamp_offset = time_offset;
+ return true;
+}
+
bool ChunkDemuxer::EndOfStream(PipelineStatus status) {
DVLOG(1) << "EndOfStream(" << status << ")";
base::AutoLock auto_lock(lock_);
@@ -983,6 +1001,10 @@ bool ChunkDemuxer::OnAudioBuffers(const StreamParser::BufferQueue& buffers) {
if (!audio_)
return false;
+ CHECK(IsValidId(source_id_audio_));
+ AdjustBufferTimestamps(
+ buffers, source_info_map_[source_id_audio_].timestamp_offset);
+
return audio_->Append(buffers);
}
@@ -993,6 +1015,10 @@ bool ChunkDemuxer::OnVideoBuffers(const StreamParser::BufferQueue& buffers) {
if (!video_)
return false;
+ CHECK(IsValidId(source_id_video_));
+ AdjustBufferTimestamps(
+ buffers, source_info_map_[source_id_video_].timestamp_offset);
+
return video_->Append(buffers);
}
@@ -1003,11 +1029,16 @@ bool ChunkDemuxer::OnNeedKey(scoped_array<uint8> init_data,
}
void ChunkDemuxer::OnNewMediaSegment(const std::string& source_id,
- TimeDelta start_timestamp) {
+ TimeDelta timestamp) {
DVLOG(2) << "OnNewMediaSegment(" << source_id << ", "
- << start_timestamp.InSecondsF() << ")";
+ << timestamp.InSecondsF() << ")";
lock_.AssertAcquired();
+ CHECK(IsValidId(source_id));
+ source_info_map_[source_id].can_update_offset = false;
+ base::TimeDelta start_timestamp =
+ timestamp + source_info_map_[source_id].timestamp_offset;
+
if (start_time_ == kNoTimestamp()) {
DCHECK(state_ == INITIALIZING || state_ == WAITING_FOR_START_TIME);
// Use the first reported media segment start time as the |start_time_|
@@ -1037,4 +1068,29 @@ void ChunkDemuxer::OnNewMediaSegment(const std::string& source_id,
base::ResetAndReturn(&init_cb_).Run(PIPELINE_OK);
}
+void ChunkDemuxer::OnEndOfMediaSegment(const std::string& source_id) {
+ DVLOG(2) << "OnEndOfMediaSegment(" << source_id << ")";
+ CHECK(IsValidId(source_id));
+ source_info_map_[source_id].can_update_offset = true;
+}
+
+void ChunkDemuxer::AdjustBufferTimestamps(
+ const StreamParser::BufferQueue& buffers,
+ base::TimeDelta timestamp_offset) {
+ if (timestamp_offset == base::TimeDelta())
+ return;
+
+ for (StreamParser::BufferQueue::const_iterator itr = buffers.begin();
+ itr != buffers.end(); ++itr) {
+ (*itr)->SetDecodeTimestamp(
+ (*itr)->GetDecodeTimestamp() + timestamp_offset);
+ (*itr)->SetTimestamp((*itr)->GetTimestamp() + timestamp_offset);
+ }
+}
+
+bool ChunkDemuxer::IsValidId(const std::string& source_id) const {
+ return source_info_map_.count(source_id) > 0u &&
+ stream_parser_map_.count(source_id) > 0u;
+}
+
} // namespace media
« no previous file with comments | « media/filters/chunk_demuxer.h ('k') | media/filters/chunk_demuxer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698