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 |