| 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 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 blocking_thread_("FFmpegDemuxer"), | 367 blocking_thread_("FFmpegDemuxer"), |
| 368 pending_read_(false), | 368 pending_read_(false), |
| 369 pending_seek_(false), | 369 pending_seek_(false), |
| 370 data_source_(data_source), | 370 data_source_(data_source), |
| 371 media_log_(media_log), | 371 media_log_(media_log), |
| 372 bitrate_(0), | 372 bitrate_(0), |
| 373 start_time_(kNoTimestamp()), | 373 start_time_(kNoTimestamp()), |
| 374 audio_disabled_(false), | 374 audio_disabled_(false), |
| 375 text_enabled_(false), | 375 text_enabled_(false), |
| 376 duration_known_(false), | 376 duration_known_(false), |
| 377 url_protocol_(data_source, BindToLoop(task_runner_, base::Bind( | |
| 378 &FFmpegDemuxer::OnDataSourceError, base::Unretained(this)))), | |
| 379 need_key_cb_(need_key_cb) { | 377 need_key_cb_(need_key_cb) { |
| 380 DCHECK(task_runner_.get()); | 378 DCHECK(task_runner_.get()); |
| 381 DCHECK(data_source_); | 379 DCHECK(data_source_); |
| 382 } | 380 } |
| 383 | 381 |
| 384 FFmpegDemuxer::~FFmpegDemuxer() {} | 382 FFmpegDemuxer::~FFmpegDemuxer() {} |
| 385 | 383 |
| 386 void FFmpegDemuxer::Stop(const base::Closure& callback) { | 384 void FFmpegDemuxer::Stop(const base::Closure& callback) { |
| 387 DCHECK(task_runner_->BelongsToCurrentThread()); | 385 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 388 url_protocol_.Abort(); | 386 url_protocol_->Abort(); |
| 389 data_source_->Stop(BindToCurrentLoop(base::Bind( | 387 data_source_->Stop(BindToCurrentLoop(base::Bind( |
| 390 &FFmpegDemuxer::OnDataSourceStopped, weak_this_, | 388 &FFmpegDemuxer::OnDataSourceStopped, weak_this_, |
| 391 BindToCurrentLoop(callback)))); | 389 BindToCurrentLoop(callback)))); |
| 392 data_source_ = NULL; | 390 data_source_ = NULL; |
| 393 } | 391 } |
| 394 | 392 |
| 395 void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { | 393 void FFmpegDemuxer::Seek(base::TimeDelta time, const PipelineStatusCB& cb) { |
| 396 DCHECK(task_runner_->BelongsToCurrentThread()); | 394 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 397 CHECK(!pending_seek_); | 395 CHECK(!pending_seek_); |
| 398 | 396 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 bool enable_text_tracks) { | 432 bool enable_text_tracks) { |
| 435 DCHECK(task_runner_->BelongsToCurrentThread()); | 433 DCHECK(task_runner_->BelongsToCurrentThread()); |
| 436 host_ = host; | 434 host_ = host; |
| 437 weak_this_ = weak_factory_.GetWeakPtr(); | 435 weak_this_ = weak_factory_.GetWeakPtr(); |
| 438 text_enabled_ = enable_text_tracks; | 436 text_enabled_ = enable_text_tracks; |
| 439 | 437 |
| 440 // TODO(scherkus): DataSource should have a host by this point, | 438 // TODO(scherkus): DataSource should have a host by this point, |
| 441 // see http://crbug.com/122071 | 439 // see http://crbug.com/122071 |
| 442 data_source_->set_host(host); | 440 data_source_->set_host(host); |
| 443 | 441 |
| 444 glue_.reset(new FFmpegGlue(&url_protocol_)); | 442 url_protocol_.reset(new BlockingUrlProtocol(data_source_, BindToCurrentLoop( |
| 443 base::Bind(&FFmpegDemuxer::OnDataSourceError, base::Unretained(this))))); |
| 444 glue_.reset(new FFmpegGlue(url_protocol_.get())); |
| 445 AVFormatContext* format_context = glue_->format_context(); | 445 AVFormatContext* format_context = glue_->format_context(); |
| 446 | 446 |
| 447 // Disable ID3v1 tag reading to avoid costly seeks to end of file for data we | 447 // Disable ID3v1 tag reading to avoid costly seeks to end of file for data we |
| 448 // don't use. FFmpeg will only read ID3v1 tags if no other metadata is | 448 // don't use. FFmpeg will only read ID3v1 tags if no other metadata is |
| 449 // available, so add a metadata entry to ensure some is always present. | 449 // available, so add a metadata entry to ensure some is always present. |
| 450 av_dict_set(&format_context->metadata, "skip_id3v1_tags", "", 0); | 450 av_dict_set(&format_context->metadata, "skip_id3v1_tags", "", 0); |
| 451 | 451 |
| 452 // Open the AVFormatContext using our glue layer. | 452 // Open the AVFormatContext using our glue layer. |
| 453 CHECK(blocking_thread_.Start()); | 453 CHECK(blocking_thread_.Start()); |
| 454 base::PostTaskAndReplyWithResult( | 454 base::PostTaskAndReplyWithResult( |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 664 // generation so we always get timestamps, see http://crbug.com/169570 | 664 // generation so we always get timestamps, see http://crbug.com/169570 |
| 665 if (strcmp(format_context->iformat->name, "avi") == 0) | 665 if (strcmp(format_context->iformat->name, "avi") == 0) |
| 666 format_context->flags |= AVFMT_FLAG_GENPTS; | 666 format_context->flags |= AVFMT_FLAG_GENPTS; |
| 667 | 667 |
| 668 // Good to go: set the duration and bitrate and notify we're done | 668 // Good to go: set the duration and bitrate and notify we're done |
| 669 // initializing. | 669 // initializing. |
| 670 host_->SetDuration(max_duration); | 670 host_->SetDuration(max_duration); |
| 671 duration_known_ = (max_duration != kInfiniteDuration()); | 671 duration_known_ = (max_duration != kInfiniteDuration()); |
| 672 | 672 |
| 673 int64 filesize_in_bytes = 0; | 673 int64 filesize_in_bytes = 0; |
| 674 url_protocol_.GetSize(&filesize_in_bytes); | 674 url_protocol_->GetSize(&filesize_in_bytes); |
| 675 bitrate_ = CalculateBitrate(format_context, max_duration, filesize_in_bytes); | 675 bitrate_ = CalculateBitrate(format_context, max_duration, filesize_in_bytes); |
| 676 if (bitrate_ > 0) | 676 if (bitrate_ > 0) |
| 677 data_source_->SetBitrate(bitrate_); | 677 data_source_->SetBitrate(bitrate_); |
| 678 | 678 |
| 679 // Audio logging | 679 // Audio logging |
| 680 if (audio_stream) { | 680 if (audio_stream) { |
| 681 AVCodecContext* audio_codec = audio_stream->codec; | 681 AVCodecContext* audio_codec = audio_stream->codec; |
| 682 media_log_->SetBooleanProperty("found_audio_stream", true); | 682 media_log_->SetBooleanProperty("found_audio_stream", true); |
| 683 | 683 |
| 684 SampleFormat sample_format = audio_config.sample_format(); | 684 SampleFormat sample_format = audio_config.sample_format(); |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 944 } | 944 } |
| 945 for (size_t i = 0; i < buffered.size(); ++i) | 945 for (size_t i = 0; i < buffered.size(); ++i) |
| 946 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); | 946 host_->AddBufferedTimeRange(buffered.start(i), buffered.end(i)); |
| 947 } | 947 } |
| 948 | 948 |
| 949 void FFmpegDemuxer::OnDataSourceError() { | 949 void FFmpegDemuxer::OnDataSourceError() { |
| 950 host_->OnDemuxerError(PIPELINE_ERROR_READ); | 950 host_->OnDemuxerError(PIPELINE_ERROR_READ); |
| 951 } | 951 } |
| 952 | 952 |
| 953 } // namespace media | 953 } // namespace media |
| OLD | NEW |