Index: media/filters/chunk_demuxer.cc |
diff --git a/media/filters/chunk_demuxer.cc b/media/filters/chunk_demuxer.cc |
index 9a55e15520ec99609953998f1b63e1cea9e7cc96..9da955a7a8497bdbb350a5ef63e331a658862a7d 100644 |
--- a/media/filters/chunk_demuxer.cc |
+++ b/media/filters/chunk_demuxer.cc |
@@ -323,17 +323,22 @@ void ChunkDemuxer::Stop(FilterCallback* callback) { |
void ChunkDemuxer::Seek(base::TimeDelta time, const FilterStatusCB& cb) { |
VLOG(1) << "Seek(" << time.InSecondsF() << ")"; |
+ PipelineStatus status = PIPELINE_ERROR_INVALID_STATE; |
{ |
base::AutoLock auto_lock(lock_); |
- if (seek_waits_for_data_) { |
- VLOG(1) << "Seek() : waiting for more data to arrive."; |
- seek_cb_ = cb; |
- return; |
+ if (state_ == INITIALIZED || state_ == ENDED) { |
+ if (seek_waits_for_data_) { |
+ VLOG(1) << "Seek() : waiting for more data to arrive."; |
+ seek_cb_ = cb; |
+ return; |
+ } |
+ |
+ status = PIPELINE_OK; |
} |
} |
- cb.Run(PIPELINE_OK); |
+ cb.Run(status); |
} |
void ChunkDemuxer::OnAudioRendererDisabled() { |
@@ -394,7 +399,7 @@ bool ChunkDemuxer::AppendData(const uint8* data, unsigned length) { |
case INITIALIZING: |
if (!ParseInfoAndTracks_Locked(data, length)) { |
VLOG(1) << "AppendData(): parsing info & tracks failed"; |
- return false; |
+ ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); |
} |
return true; |
break; |
@@ -402,17 +407,17 @@ bool ChunkDemuxer::AppendData(const uint8* data, unsigned length) { |
case INITIALIZED: |
if (!ParseAndAppendData_Locked(data, length)) { |
VLOG(1) << "AppendData(): parsing data failed"; |
- return false; |
+ ReportError_Locked(PIPELINE_ERROR_DECODE); |
+ return true; |
} |
break; |
case WAITING_FOR_INIT: |
case ENDED: |
- case INIT_ERROR: |
+ case PARSE_ERROR: |
case SHUTDOWN: |
VLOG(1) << "AppendData(): called in unexpected state " << state_; |
return false; |
- break; |
} |
seek_waits_for_data_ = false; |
@@ -454,21 +459,21 @@ bool ChunkDemuxer::AppendData(const uint8* data, unsigned length) { |
void ChunkDemuxer::EndOfStream(PipelineStatus status) { |
VLOG(1) << "EndOfStream(" << status << ")"; |
base::AutoLock auto_lock(lock_); |
- DCHECK((state_ == INITIALIZING) || (state_ == INITIALIZED) || |
- (state_ == SHUTDOWN)); |
+ DCHECK_NE(state_, WAITING_FOR_INIT); |
+ DCHECK_NE(state_, ENDED); |
- if (state_ == SHUTDOWN) |
+ if (state_ == SHUTDOWN || state_ == PARSE_ERROR) |
return; |
if (state_ == INITIALIZING) { |
- InitFailed_Locked(); |
+ ReportError_Locked(DEMUXER_ERROR_COULD_NOT_OPEN); |
return; |
} |
ChangeState(ENDED); |
if (status != PIPELINE_OK) { |
- host()->SetError(status); |
+ ReportError_Locked(status); |
return; |
} |
@@ -488,7 +493,6 @@ bool ChunkDemuxer::HasEnded() { |
return (state_ == ENDED); |
} |
- |
void ChunkDemuxer::Shutdown() { |
VLOG(1) << "Shutdown()"; |
FilterStatusCB cb; |
@@ -531,10 +535,8 @@ bool ChunkDemuxer::ParseInfoAndTracks_Locked(const uint8* data, int size) { |
WebMInfoParser info_parser; |
int res = info_parser.Parse(cur, cur_size); |
- if (res <= 0) { |
- InitFailed_Locked(); |
+ if (res <= 0) |
return false; |
- } |
cur += res; |
cur_size -= res; |
@@ -542,10 +544,8 @@ bool ChunkDemuxer::ParseInfoAndTracks_Locked(const uint8* data, int size) { |
WebMTracksParser tracks_parser(info_parser.timecode_scale()); |
res = tracks_parser.Parse(cur, cur_size); |
- if (res <= 0) { |
- InitFailed_Locked(); |
+ if (res <= 0) |
return false; |
- } |
double mult = info_parser.timecode_scale() / 1000.0; |
duration_ = base::TimeDelta::FromMicroseconds(info_parser.duration() * mult); |
@@ -560,7 +560,6 @@ bool ChunkDemuxer::ParseInfoAndTracks_Locked(const uint8* data, int size) { |
format_context_ = CreateFormatContext(data, size); |
if (!format_context_ || !SetupStreams()) { |
- InitFailed_Locked(); |
return false; |
} |
@@ -677,11 +676,34 @@ bool ChunkDemuxer::ParseAndAppendData_Locked(const uint8* data, int length) { |
return true; |
} |
-void ChunkDemuxer::InitFailed_Locked() { |
- ChangeState(INIT_ERROR); |
+void ChunkDemuxer::ReportError_Locked(PipelineStatus error) { |
+ DCHECK_NE(error, PIPELINE_OK); |
+ |
+ ChangeState(PARSE_ERROR); |
+ |
PipelineStatusCB cb; |
- std::swap(cb, init_cb_); |
- cb.Run(DEMUXER_ERROR_COULD_NOT_OPEN); |
+ |
+ if (!init_cb_.is_null()) { |
+ std::swap(cb, init_cb_); |
+ } else { |
+ if (!seek_cb_.is_null()) |
+ std::swap(cb, seek_cb_); |
+ |
+ if (audio_.get()) |
+ audio_->Shutdown(); |
+ |
+ if (video_.get()) |
+ video_->Shutdown(); |
+ } |
+ |
+ { |
+ base::AutoUnlock auto_unlock(lock_); |
+ if (cb.is_null()) { |
+ host()->SetError(error); |
+ return; |
+ } |
+ cb.Run(error); |
+ } |
} |
} // namespace media |