OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/callback.h" | 6 #include "base/callback.h" |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
12 #include "base/time.h" | 12 #include "base/time.h" |
| 13 #include "media/base/data_buffer.h" |
13 #include "media/base/filter_host.h" | 14 #include "media/base/filter_host.h" |
14 #include "media/base/limits.h" | 15 #include "media/base/limits.h" |
15 #include "media/base/media_switches.h" | 16 #include "media/base/media_switches.h" |
16 #include "media/ffmpeg/ffmpeg_common.h" | 17 #include "media/ffmpeg/ffmpeg_common.h" |
17 #include "media/filters/bitstream_converter.h" | 18 #include "media/filters/bitstream_converter.h" |
18 #include "media/filters/ffmpeg_demuxer.h" | 19 #include "media/filters/ffmpeg_demuxer.h" |
19 #include "media/filters/ffmpeg_glue.h" | 20 #include "media/filters/ffmpeg_glue.h" |
20 #include "media/filters/ffmpeg_h264_bitstream_converter.h" | 21 #include "media/filters/ffmpeg_h264_bitstream_converter.h" |
21 | 22 |
22 namespace media { | 23 namespace media { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); | 133 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); |
133 base::AutoLock auto_lock(lock_); | 134 base::AutoLock auto_lock(lock_); |
134 DCHECK(read_queue_.empty()) << "Read requests should be empty"; | 135 DCHECK(read_queue_.empty()) << "Read requests should be empty"; |
135 buffer_queue_.clear(); | 136 buffer_queue_.clear(); |
136 } | 137 } |
137 | 138 |
138 void FFmpegDemuxerStream::Stop() { | 139 void FFmpegDemuxerStream::Stop() { |
139 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); | 140 DCHECK_EQ(MessageLoop::current(), demuxer_->message_loop()); |
140 base::AutoLock auto_lock(lock_); | 141 base::AutoLock auto_lock(lock_); |
141 buffer_queue_.clear(); | 142 buffer_queue_.clear(); |
| 143 for (ReadQueue::iterator it = read_queue_.begin(); |
| 144 it != read_queue_.end(); ++it) { |
| 145 it->Run(new DataBuffer(0)); |
| 146 } |
142 read_queue_.clear(); | 147 read_queue_.clear(); |
143 stopped_ = true; | 148 stopped_ = true; |
144 } | 149 } |
145 | 150 |
146 base::TimeDelta FFmpegDemuxerStream::duration() { | 151 base::TimeDelta FFmpegDemuxerStream::duration() { |
147 return duration_; | 152 return duration_; |
148 } | 153 } |
149 | 154 |
150 DemuxerStream::Type FFmpegDemuxerStream::type() { | 155 DemuxerStream::Type FFmpegDemuxerStream::type() { |
151 return type_; | 156 return type_; |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 // TODO(hclam): close the codecs in the corresponding decoders. | 287 // TODO(hclam): close the codecs in the corresponding decoders. |
283 if (!format_context_) | 288 if (!format_context_) |
284 return; | 289 return; |
285 | 290 |
286 DestroyAVFormatContext(format_context_); | 291 DestroyAVFormatContext(format_context_); |
287 format_context_ = NULL; | 292 format_context_ = NULL; |
288 } | 293 } |
289 | 294 |
290 void FFmpegDemuxer::PostDemuxTask() { | 295 void FFmpegDemuxer::PostDemuxTask() { |
291 message_loop_->PostTask(FROM_HERE, | 296 message_loop_->PostTask(FROM_HERE, |
292 base::Bind(&FFmpegDemuxer::DemuxTask, this)); | 297 base::Bind(&FFmpegDemuxer::DemuxTask, this)); |
293 } | 298 } |
294 | 299 |
295 void FFmpegDemuxer::Stop(const base::Closure& callback) { | 300 void FFmpegDemuxer::Stop(const base::Closure& callback) { |
296 // Post a task to notify the streams to stop as well. | 301 // Post a task to notify the streams to stop as well. |
297 message_loop_->PostTask(FROM_HERE, | 302 message_loop_->PostTask(FROM_HERE, |
298 base::Bind(&FFmpegDemuxer::StopTask, this, callback)); | 303 base::Bind(&FFmpegDemuxer::StopTask, this, callback)); |
299 | 304 |
300 // Then wakes up the thread from reading. | 305 // Then wakes up the thread from reading. |
301 SignalReadCompleted(DataSource::kReadError); | 306 SignalReadCompleted(DataSource::kReadError); |
302 } | 307 } |
303 | 308 |
304 void FFmpegDemuxer::Seek(base::TimeDelta time, const FilterStatusCB& cb) { | 309 void FFmpegDemuxer::Seek(base::TimeDelta time, const FilterStatusCB& cb) { |
305 message_loop_->PostTask(FROM_HERE, | 310 message_loop_->PostTask(FROM_HERE, |
306 base::Bind(&FFmpegDemuxer::SeekTask, this, time, cb)); | 311 base::Bind(&FFmpegDemuxer::SeekTask, this, time, cb)); |
307 } | 312 } |
308 | 313 |
309 void FFmpegDemuxer::SetPlaybackRate(float playback_rate) { | 314 void FFmpegDemuxer::SetPlaybackRate(float playback_rate) { |
310 DCHECK(data_source_.get()); | 315 DCHECK(data_source_.get()); |
311 data_source_->SetPlaybackRate(playback_rate); | 316 data_source_->SetPlaybackRate(playback_rate); |
312 } | 317 } |
313 | 318 |
314 void FFmpegDemuxer::SetPreload(Preload preload) { | 319 void FFmpegDemuxer::SetPreload(Preload preload) { |
315 DCHECK(data_source_.get()); | 320 DCHECK(data_source_.get()); |
316 data_source_->SetPreload(preload); | 321 data_source_->SetPreload(preload); |
317 } | 322 } |
318 | 323 |
319 void FFmpegDemuxer::OnAudioRendererDisabled() { | 324 void FFmpegDemuxer::OnAudioRendererDisabled() { |
320 message_loop_->PostTask(FROM_HERE, | 325 message_loop_->PostTask(FROM_HERE, base::Bind( |
321 base::Bind(&FFmpegDemuxer::DisableAudioStreamTask, this)); | 326 &FFmpegDemuxer::DisableAudioStreamTask, this)); |
322 } | 327 } |
323 | 328 |
324 void FFmpegDemuxer::set_host(FilterHost* filter_host) { | 329 void FFmpegDemuxer::set_host(FilterHost* filter_host) { |
325 Demuxer::set_host(filter_host); | 330 Demuxer::set_host(filter_host); |
326 if (data_source_) | 331 if (data_source_) |
327 data_source_->set_host(filter_host); | 332 data_source_->set_host(filter_host); |
328 if (max_duration_.InMicroseconds() >= 0) | 333 if (max_duration_.InMicroseconds() >= 0) |
329 host()->SetDuration(max_duration_); | 334 host()->SetDuration(max_duration_); |
330 if (read_position_ > 0) | 335 if (read_position_ > 0) |
331 host()->SetCurrentReadPosition(read_position_); | 336 host()->SetCurrentReadPosition(read_position_); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
466 base::TimeDelta max_duration; | 471 base::TimeDelta max_duration; |
467 const bool kDemuxerIsWebm = !strcmp("webm", format_context_->iformat->name); | 472 const bool kDemuxerIsWebm = !strcmp("webm", format_context_->iformat->name); |
468 bool no_supported_streams = true; | 473 bool no_supported_streams = true; |
469 for (size_t i = 0; i < format_context_->nb_streams; ++i) { | 474 for (size_t i = 0; i < format_context_->nb_streams; ++i) { |
470 AVCodecContext* codec_context = format_context_->streams[i]->codec; | 475 AVCodecContext* codec_context = format_context_->streams[i]->codec; |
471 AVMediaType codec_type = codec_context->codec_type; | 476 AVMediaType codec_type = codec_context->codec_type; |
472 if (codec_type == AVMEDIA_TYPE_AUDIO || codec_type == AVMEDIA_TYPE_VIDEO) { | 477 if (codec_type == AVMEDIA_TYPE_AUDIO || codec_type == AVMEDIA_TYPE_VIDEO) { |
473 AVStream* stream = format_context_->streams[i]; | 478 AVStream* stream = format_context_->streams[i]; |
474 // WebM is currently strictly VP8 and Vorbis. | 479 // WebM is currently strictly VP8 and Vorbis. |
475 if (kDemuxerIsWebm && (stream->codec->codec_id != CODEC_ID_VP8 && | 480 if (kDemuxerIsWebm && (stream->codec->codec_id != CODEC_ID_VP8 && |
476 stream->codec->codec_id != CODEC_ID_VORBIS)) { | 481 stream->codec->codec_id != CODEC_ID_VORBIS)) { |
477 packet_streams_.push_back(NULL); | 482 packet_streams_.push_back(NULL); |
478 continue; | 483 continue; |
479 } | 484 } |
480 | 485 |
481 scoped_refptr<FFmpegDemuxerStream> demuxer_stream( | 486 scoped_refptr<FFmpegDemuxerStream> demuxer_stream( |
482 new FFmpegDemuxerStream(this, stream)); | 487 new FFmpegDemuxerStream(this, stream)); |
483 if (!streams_[demuxer_stream->type()]) { | 488 if (!streams_[demuxer_stream->type()]) { |
484 no_supported_streams = false; | 489 no_supported_streams = false; |
485 streams_[demuxer_stream->type()] = demuxer_stream; | 490 streams_[demuxer_stream->type()] = demuxer_stream; |
486 max_duration = std::max(max_duration, demuxer_stream->duration()); | 491 max_duration = std::max(max_duration, demuxer_stream->duration()); |
487 | 492 |
488 if (stream->first_dts != static_cast<int64_t>(AV_NOPTS_VALUE)) { | 493 if (stream->first_dts != static_cast<int64_t>(AV_NOPTS_VALUE)) { |
489 const base::TimeDelta first_dts = ConvertFromTimeBase( | 494 const base::TimeDelta first_dts = ConvertFromTimeBase( |
490 stream->time_base, stream->first_dts); | 495 stream->time_base, stream->first_dts); |
491 if (start_time_ == kNoTimestamp || first_dts < start_time_) | 496 if (start_time_ == kNoTimestamp || first_dts < start_time_) |
492 start_time_ = first_dts; | 497 start_time_ = first_dts; |
493 } | 498 } |
494 } | 499 } |
495 packet_streams_.push_back(demuxer_stream); | 500 packet_streams_.push_back(demuxer_stream); |
496 } else { | 501 } else { |
497 packet_streams_.push_back(NULL); | 502 packet_streams_.push_back(NULL); |
498 } | 503 } |
499 } | 504 } |
500 if (no_supported_streams) { | 505 if (no_supported_streams) { |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 read_event_.Wait(); | 720 read_event_.Wait(); |
716 return last_read_bytes_; | 721 return last_read_bytes_; |
717 } | 722 } |
718 | 723 |
719 void FFmpegDemuxer::SignalReadCompleted(size_t size) { | 724 void FFmpegDemuxer::SignalReadCompleted(size_t size) { |
720 last_read_bytes_ = size; | 725 last_read_bytes_ = size; |
721 read_event_.Signal(); | 726 read_event_.Signal(); |
722 } | 727 } |
723 | 728 |
724 } // namespace media | 729 } // namespace media |
OLD | NEW |