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

Unified Diff: media/filters/chunk_demuxer.cc

Issue 17261029: Fix ChunkDemuxer seek and init callback dispatch. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address CR comment Created 7 years, 6 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 73dbae6c0cf4e3144b4b2a459642e6b63a74ee39..768473c0f3ee9c8b0b79afe00887805943f48ac2 100644
--- a/media/filters/chunk_demuxer.cc
+++ b/media/filters/chunk_demuxer.cc
@@ -13,6 +13,7 @@
#include "base/location.h"
#include "base/message_loop/message_loop_proxy.h"
#include "media/base/audio_decoder_config.h"
+#include "media/base/bind_to_loop.h"
#include "media/base/stream_parser_buffer.h"
#include "media/base/video_decoder_config.h"
#include "media/filters/stream_parser_factory.h"
@@ -207,7 +208,7 @@ class ChunkDemuxerStream : public DemuxerStream {
void StartWaitingForSeek();
void Seek(TimeDelta time);
void CancelPendingSeek();
- bool IsSeekPending() const;
+ bool IsSeekWaitingForData() const;
// Add buffers to this stream. Buffers are stored in SourceBufferStreams,
// which handle ordering and overlap resolution.
@@ -215,10 +216,10 @@ class ChunkDemuxerStream : public DemuxerStream {
bool Append(const StreamParser::BufferQueue& buffers);
// Signal to the stream that duration has changed to |duration|.
- void OnSetDuration(base::TimeDelta duration);
+ void OnSetDuration(TimeDelta duration);
// Returns the range of buffered data in this stream, capped at |duration|.
- Ranges<TimeDelta> GetBufferedRanges(base::TimeDelta duration) const;
+ Ranges<TimeDelta> GetBufferedRanges(TimeDelta duration) const;
// Signal to the stream that buffers handed in through subsequent calls to
// Append() belong to a media segment that starts at |start_timestamp|.
@@ -334,7 +335,7 @@ void ChunkDemuxerStream::CancelPendingSeek() {
it->Run(kAborted, NULL);
}
-bool ChunkDemuxerStream::IsSeekPending() const {
+bool ChunkDemuxerStream::IsSeekWaitingForData() const {
base::AutoLock auto_lock(lock_);
return stream_->IsSeekPending();
}
@@ -365,13 +366,13 @@ bool ChunkDemuxerStream::Append(const StreamParser::BufferQueue& buffers) {
return true;
}
-void ChunkDemuxerStream::OnSetDuration(base::TimeDelta duration) {
+void ChunkDemuxerStream::OnSetDuration(TimeDelta duration) {
base::AutoLock auto_lock(lock_);
stream_->OnSetDuration(duration);
}
Ranges<TimeDelta> ChunkDemuxerStream::GetBufferedRanges(
- base::TimeDelta duration) const {
+ TimeDelta duration) const {
base::AutoLock auto_lock(lock_);
Ranges<TimeDelta> range = stream_->GetBufferedTime();
@@ -578,16 +579,15 @@ void ChunkDemuxer::Initialize(DemuxerHost* host, const PipelineStatusCB& cb) {
base::AutoLock auto_lock(lock_);
+ init_cb_ = BindToCurrentLoop(cb);
if (state_ == SHUTDOWN) {
- base::MessageLoopProxy::current()->PostTask(FROM_HERE, base::Bind(
- cb, DEMUXER_ERROR_COULD_NOT_OPEN));
+ base::ResetAndReturn(&init_cb_).Run(DEMUXER_ERROR_COULD_NOT_OPEN);
return;
}
DCHECK_EQ(state_, WAITING_FOR_INIT);
host_ = host;
ChangeState_Locked(INITIALIZING);
- init_cb_ = cb;
base::ResetAndReturn(&open_cb_).Run();
}
@@ -604,27 +604,25 @@ void ChunkDemuxer::Seek(TimeDelta time, const PipelineStatusCB& cb) {
DCHECK(seek_cb_.is_null());
PipelineStatus status = PIPELINE_ERROR_INVALID_STATE;
- {
- base::AutoLock auto_lock(lock_);
-
- if (state_ == INITIALIZED || state_ == ENDED) {
- if (audio_)
- audio_->Seek(time);
+ base::AutoLock auto_lock(lock_);
- if (video_)
- video_->Seek(time);
+ seek_cb_ = BindToCurrentLoop(cb);
+ if (state_ == INITIALIZED || state_ == ENDED) {
+ if (audio_)
+ audio_->Seek(time);
- if (IsSeekPending_Locked()) {
- DVLOG(1) << "Seek() : waiting for more data to arrive.";
- seek_cb_ = cb;
- return;
- }
+ if (video_)
+ video_->Seek(time);
- status = PIPELINE_OK;
+ if (IsSeekWaitingForData_Locked()) {
+ DVLOG(1) << "Seek() : waiting for more data to arrive.";
+ return;
}
+
+ status = PIPELINE_OK;
}
- cb.Run(status);
+ base::ResetAndReturn(&seek_cb_).Run(status);
}
void ChunkDemuxer::OnAudioRendererDisabled() {
@@ -665,21 +663,17 @@ void ChunkDemuxer::StartWaitingForSeek() {
}
void ChunkDemuxer::CancelPendingSeek() {
- PipelineStatusCB cb;
- {
- base::AutoLock auto_lock(lock_);
- if (IsSeekPending_Locked() && !seek_cb_.is_null()) {
- std::swap(cb, seek_cb_);
- }
- if (audio_)
- audio_->CancelPendingSeek();
+ base::AutoLock auto_lock(lock_);
+ DCHECK(seek_cb_.is_null() != IsSeekWaitingForData_Locked());
- if (video_)
- video_->CancelPendingSeek();
- }
+ if (audio_)
+ audio_->CancelPendingSeek();
+
+ if (video_)
+ video_->CancelPendingSeek();
- if (!cb.is_null())
- cb.Run(PIPELINE_OK);
+ if (!seek_cb_.is_null())
+ base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
}
ChunkDemuxer::Status ChunkDemuxer::AddId(const std::string& id,
@@ -815,12 +809,12 @@ void ChunkDemuxer::AppendData(const std::string& id,
Ranges<TimeDelta> ranges;
- PipelineStatusCB cb;
{
base::AutoLock auto_lock(lock_);
- // Capture if the SourceBuffer has a pending seek before we start parsing.
- bool old_seek_pending = IsSeekPending_Locked();
+ // Capture if any of the SourceBuffers are waiting for data before we start
+ // parsing.
+ bool old_waiting_for_data = IsSeekWaitingForData_Locked();
if (state_ == ENDED) {
ChangeState_Locked(INITIALIZED);
@@ -867,8 +861,9 @@ void ChunkDemuxer::AppendData(const std::string& id,
// Check to see if data was appended at the pending seek point. This
// indicates we have parsed enough data to complete the seek.
- if (old_seek_pending && !IsSeekPending_Locked() && !seek_cb_.is_null()) {
- std::swap(cb, seek_cb_);
+ if (old_waiting_for_data && !IsSeekWaitingForData_Locked() &&
+ !seek_cb_.is_null()) {
+ base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
}
ranges = GetBufferedRanges();
@@ -876,9 +871,6 @@ void ChunkDemuxer::AppendData(const std::string& id,
for (size_t i = 0; i < ranges.size(); ++i)
host_->AddBufferedTimeRange(ranges.start(i), ranges.end(i));
-
- if (!cb.is_null())
- cb.Run(PIPELINE_OK);
}
void ChunkDemuxer::Abort(const std::string& id) {
@@ -920,14 +912,13 @@ void ChunkDemuxer::SetDuration(double duration) {
// Compute & bounds check the TimeDelta representation of duration.
// This can be different if the value of |duration| doesn't fit the range or
- // precision of base::TimeDelta.
- base::TimeDelta min_duration = base::TimeDelta::FromInternalValue(1);
- base::TimeDelta max_duration =
- base::TimeDelta::FromInternalValue(kint64max - 1);
+ // precision of TimeDelta.
+ TimeDelta min_duration = TimeDelta::FromInternalValue(1);
+ TimeDelta max_duration = TimeDelta::FromInternalValue(kint64max - 1);
double min_duration_in_seconds = min_duration.InSecondsF();
double max_duration_in_seconds = max_duration.InSecondsF();
- base::TimeDelta duration_td;
+ TimeDelta duration_td;
if (duration == std::numeric_limits<double>::infinity()) {
duration_td = media::kInfiniteDuration();
} else if (duration < min_duration_in_seconds) {
@@ -935,11 +926,11 @@ void ChunkDemuxer::SetDuration(double duration) {
} else if (duration > max_duration_in_seconds) {
duration_td = max_duration;
} else {
- duration_td = base::TimeDelta::FromMicroseconds(
+ duration_td = TimeDelta::FromMicroseconds(
duration * base::Time::kMicrosecondsPerSecond);
}
- DCHECK(duration_td > base::TimeDelta());
+ DCHECK(duration_td > TimeDelta());
user_specified_duration_ = duration;
duration_ = duration_td;
@@ -962,66 +953,57 @@ bool ChunkDemuxer::SetTimestampOffset(const std::string& id, TimeDelta offset) {
void ChunkDemuxer::EndOfStream(PipelineStatus status) {
DVLOG(1) << "EndOfStream(" << status << ")";
- PipelineStatusCB cb;
- {
- base::AutoLock auto_lock(lock_);
- DCHECK_NE(state_, WAITING_FOR_INIT);
- DCHECK_NE(state_, ENDED);
+ base::AutoLock auto_lock(lock_);
+ DCHECK_NE(state_, WAITING_FOR_INIT);
+ DCHECK_NE(state_, ENDED);
- if (state_ == SHUTDOWN || state_ == PARSE_ERROR)
- return;
+ if (state_ == SHUTDOWN || state_ == PARSE_ERROR)
+ return;
- if (state_ == INITIALIZING) {
- ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN);
- return;
- }
+ if (state_ == INITIALIZING) {
+ ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN);
+ return;
+ }
- bool old_seek_pending = IsSeekPending_Locked();
- if (audio_)
- audio_->EndOfStream();
+ bool old_waiting_for_data = IsSeekWaitingForData_Locked();
+ if (audio_)
+ audio_->EndOfStream();
- if (video_)
- video_->EndOfStream();
+ if (video_)
+ video_->EndOfStream();
- // Give a chance to resume the pending seek process.
- if (status != PIPELINE_OK) {
- ReportError_Locked(status);
- return;
- }
+ // Give a chance to resume the pending seek process.
+ if (status != PIPELINE_OK) {
+ ReportError_Locked(status);
+ return;
+ }
- ChangeState_Locked(ENDED);
- DecreaseDurationIfNecessary();
+ ChangeState_Locked(ENDED);
+ DecreaseDurationIfNecessary();
- if (old_seek_pending && !IsSeekPending_Locked() && !seek_cb_.is_null())
- std::swap(cb, seek_cb_);
+ if (old_waiting_for_data && !IsSeekWaitingForData_Locked() &&
+ !seek_cb_.is_null()) {
+ base::ResetAndReturn(&seek_cb_).Run(PIPELINE_OK);
}
-
- if (!cb.is_null())
- cb.Run(PIPELINE_OK);
}
void ChunkDemuxer::Shutdown() {
DVLOG(1) << "Shutdown()";
- PipelineStatusCB cb;
- {
- base::AutoLock auto_lock(lock_);
-
- if (state_ == SHUTDOWN)
- return;
+ base::AutoLock auto_lock(lock_);
- std::swap(cb, seek_cb_);
+ if (state_ == SHUTDOWN)
+ return;
- if (audio_)
- audio_->Shutdown();
+ if (audio_)
+ audio_->Shutdown();
- if (video_)
- video_->Shutdown();
+ if (video_)
+ video_->Shutdown();
- ChangeState_Locked(SHUTDOWN);
- }
+ ChangeState_Locked(SHUTDOWN);
- if (!cb.is_null())
- cb.Run(PIPELINE_ERROR_ABORT);
+ if(!seek_cb_.is_null())
+ base::ResetAndReturn(&seek_cb_).Run(PIPELINE_ERROR_ABORT);
}
void ChunkDemuxer::ChangeState_Locked(State new_state) {
@@ -1063,7 +1045,6 @@ void ChunkDemuxer::ReportError_Locked(PipelineStatus error) {
}
if (!cb.is_null()) {
- base::AutoUnlock auto_unlock(lock_);
cb.Run(error);
return;
}
@@ -1072,17 +1053,17 @@ void ChunkDemuxer::ReportError_Locked(PipelineStatus error) {
host_->OnDemuxerError(error);
}
-bool ChunkDemuxer::IsSeekPending_Locked() const {
+bool ChunkDemuxer::IsSeekWaitingForData_Locked() const {
lock_.AssertAcquired();
- bool seek_pending = false;
+ bool waiting_for_data = false;
if (audio_)
- seek_pending = audio_->IsSeekPending();
+ waiting_for_data = audio_->IsSeekWaitingForData();
- if (!seek_pending && video_)
- seek_pending = video_->IsSeekPending();
+ if (!waiting_for_data && video_)
+ waiting_for_data = video_->IsSeekWaitingForData();
- return seek_pending;
+ return waiting_for_data;
}
void ChunkDemuxer::OnSourceInitDone(bool success, TimeDelta duration) {
@@ -1095,7 +1076,7 @@ void ChunkDemuxer::OnSourceInitDone(bool success, TimeDelta duration) {
return;
}
- if (duration != base::TimeDelta() && duration_ == kNoTimestamp())
+ if (duration != TimeDelta() && duration_ == kNoTimestamp())
UpdateDuration(duration);
// Wait until all streams have initialized.
@@ -1216,8 +1197,8 @@ bool ChunkDemuxer::OnTextBuffers(
for (StreamParser::BufferQueue::const_iterator itr = buffers.begin();
itr != buffers.end(); ++itr) {
const StreamParserBuffer* const buffer = itr->get();
- const base::TimeDelta start = buffer->GetTimestamp();
- const base::TimeDelta end = start + buffer->GetDuration();
+ const TimeDelta start = buffer->GetTimestamp();
+ const TimeDelta end = start + buffer->GetDuration();
std::string id, settings, content;
@@ -1261,7 +1242,7 @@ bool ChunkDemuxer::IsValidId(const std::string& source_id) const {
return source_state_map_.count(source_id) > 0u;
}
-void ChunkDemuxer::UpdateDuration(base::TimeDelta new_duration) {
+void ChunkDemuxer::UpdateDuration(TimeDelta new_duration) {
DCHECK(duration_ != new_duration);
user_specified_duration_ = -1;
duration_ = new_duration;
@@ -1278,7 +1259,7 @@ void ChunkDemuxer::IncreaseDurationIfNecessary(
Ranges<TimeDelta> ranges = stream->GetBufferedRanges(kInfiniteDuration());
DCHECK_GT(ranges.size(), 0u);
- base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1);
+ TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1);
if (last_timestamp_buffered > duration_)
UpdateDuration(last_timestamp_buffered);
}
@@ -1288,7 +1269,7 @@ void ChunkDemuxer::DecreaseDurationIfNecessary() {
if (ranges.size() == 0u)
return;
- base::TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1);
+ TimeDelta last_timestamp_buffered = ranges.end(ranges.size() - 1);
if (last_timestamp_buffered < duration_)
UpdateDuration(last_timestamp_buffered);
}
« 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