| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "media/filters/ffmpeg_demuxer.h" | 5 #include "media/filters/ffmpeg_demuxer.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| (...skipping 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 weak_factory_(this) { | 523 weak_factory_(this) { |
| 524 DCHECK(task_runner_.get()); | 524 DCHECK(task_runner_.get()); |
| 525 DCHECK(data_source_); | 525 DCHECK(data_source_); |
| 526 } | 526 } |
| 527 | 527 |
| 528 FFmpegDemuxer::~FFmpegDemuxer() {} | 528 FFmpegDemuxer::~FFmpegDemuxer() {} |
| 529 | 529 |
| 530 void FFmpegDemuxer::Stop(const base::Closure& callback) { | 530 void FFmpegDemuxer::Stop(const base::Closure& callback) { |
| 531 DCHECK(task_runner_->BelongsToCurrentThread()); | 531 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 532 url_protocol_->Abort(); | 532 url_protocol_->Abort(); |
| 533 data_source_->Stop( | 533 data_source_->Stop(); |
| 534 BindToCurrentLoop(base::Bind(&FFmpegDemuxer::OnDataSourceStopped, | 534 |
| 535 weak_factory_.GetWeakPtr(), | 535 // This will block until all tasks complete. Note that after this returns it's |
| 536 BindToCurrentLoop(callback)))); | 536 // possible for reply tasks (e.g., OnReadFrameDone()) to be queued on this |
| 537 // thread. Each of the reply task methods must check whether we've stopped the |
| 538 // thread and drop their results on the floor. |
| 539 blocking_thread_.Stop(); |
| 540 |
| 541 StreamVector::iterator iter; |
| 542 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { |
| 543 if (*iter) |
| 544 (*iter)->Stop(); |
| 545 } |
| 546 |
| 537 data_source_ = NULL; | 547 data_source_ = NULL; |
| 548 task_runner_->PostTask(FROM_HERE, callback); |
| 538 } | 549 } |
| 539 | 550 |
| 540 void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { | 551 void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { |
| 541 DCHECK(task_runner_->BelongsToCurrentThread()); | 552 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 542 CHECK(!pending_seek_); | 553 CHECK(!pending_seek_); |
| 543 | 554 |
| 544 // TODO(scherkus): Inspect |pending_read_| and cancel IO via |blocking_url_|, | 555 // TODO(scherkus): Inspect |pending_read_| and cancel IO via |blocking_url_|, |
| 545 // otherwise we can end up waiting for a pre-seek read to complete even though | 556 // otherwise we can end up waiting for a pre-seek read to complete even though |
| 546 // we know we're going to drop it on the floor. | 557 // we know we're going to drop it on the floor. |
| 547 | 558 |
| (...skipping 565 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1113 } | 1124 } |
| 1114 | 1125 |
| 1115 FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index]; | 1126 FFmpegDemuxerStream* demuxer_stream = streams_[packet->stream_index]; |
| 1116 demuxer_stream->EnqueuePacket(packet.Pass()); | 1127 demuxer_stream->EnqueuePacket(packet.Pass()); |
| 1117 } | 1128 } |
| 1118 | 1129 |
| 1119 // Keep reading until we've reached capacity. | 1130 // Keep reading until we've reached capacity. |
| 1120 ReadFrameIfNeeded(); | 1131 ReadFrameIfNeeded(); |
| 1121 } | 1132 } |
| 1122 | 1133 |
| 1123 void FFmpegDemuxer::OnDataSourceStopped(const base::Closure& callback) { | |
| 1124 // This will block until all tasks complete. Note that after this returns it's | |
| 1125 // possible for reply tasks (e.g., OnReadFrameDone()) to be queued on this | |
| 1126 // thread. Each of the reply task methods must check whether we've stopped the | |
| 1127 // thread and drop their results on the floor. | |
| 1128 DCHECK(task_runner_->BelongsToCurrentThread()); | |
| 1129 blocking_thread_.Stop(); | |
| 1130 | |
| 1131 StreamVector::iterator iter; | |
| 1132 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { | |
| 1133 if (*iter) | |
| 1134 (*iter)->Stop(); | |
| 1135 } | |
| 1136 | |
| 1137 callback.Run(); | |
| 1138 } | |
| 1139 | |
| 1140 bool FFmpegDemuxer::StreamsHaveAvailableCapacity() { | 1134 bool FFmpegDemuxer::StreamsHaveAvailableCapacity() { |
| 1141 DCHECK(task_runner_->BelongsToCurrentThread()); | 1135 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 1142 StreamVector::iterator iter; | 1136 StreamVector::iterator iter; |
| 1143 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { | 1137 for (iter = streams_.begin(); iter != streams_.end(); ++iter) { |
| 1144 if (*iter && (*iter)->HasAvailableCapacity()) { | 1138 if (*iter && (*iter)->HasAvailableCapacity()) { |
| 1145 return true; | 1139 return true; |
| 1146 } | 1140 } |
| 1147 } | 1141 } |
| 1148 return false; | 1142 return false; |
| 1149 } | 1143 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1205 } | 1199 } |
| 1206 for (size_t i = 0; i < buffered.size(); ++i) | 1200 for (size_t i = 0; i < buffered.size(); ++i) |
| 1207 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); | 1201 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); |
| 1208 } | 1202 } |
| 1209 | 1203 |
| 1210 void FFmpegDemuxer::OnDataSourceError() { | 1204 void FFmpegDemuxer::OnDataSourceError() { |
| 1211 host_->OnDemuxerError(PIPELINE_ERROR_READ); | 1205 host_->OnDemuxerError(PIPELINE_ERROR_READ); |
| 1212 } | 1206 } |
| 1213 | 1207 |
| 1214 } // namespace media | 1208 } // namespace media |
| OLD | NEW |