| Index: media/filters/audio_decoder_factory.cc
|
| diff --git a/media/filters/audio_decoder_factory.cc b/media/filters/audio_decoder_factory.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..f2b98e3c09373cde87cdfa94c059624e9c3abbae
|
| --- /dev/null
|
| +++ b/media/filters/audio_decoder_factory.cc
|
| @@ -0,0 +1,151 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "media/filters/audio_decoder_factory.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/callback_helpers.h"
|
| +#include "base/logging.h"
|
| +#include "base/message_loop_proxy.h"
|
| +#include "media/base/audio_decoder_config.h"
|
| +#include "media/base/bind_to_loop.h"
|
| +#include "media/base/demuxer_stream.h"
|
| +#include "media/base/pipeline.h"
|
| +#include "media/filters/decrypting_audio_decoder.h"
|
| +#include "media/filters/decrypting_demuxer_stream.h"
|
| +
|
| +namespace media {
|
| +
|
| +AudioDecoderFactory::AudioDecoderFactory(
|
| + const scoped_refptr<base::MessageLoopProxy>& message_loop,
|
| + const AudioDecoderList& decoders,
|
| + const RequestDecryptorNotificationCB& request_decryptor_notification_cb)
|
| + : message_loop_(message_loop),
|
| + precreated_decoders_(decoders),
|
| + request_decryptor_notification_cb_(request_decryptor_notification_cb),
|
| + ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)),
|
| + weak_this_(weak_ptr_factory_.GetWeakPtr()) {
|
| +}
|
| +
|
| +void AudioDecoderFactory::InitAudioDecoder(
|
| + const scoped_refptr<DemuxerStream>& stream,
|
| + const StatisticsCB& statistics_cb,
|
| + const InitDoneCB& init_done_cb) {
|
| + DCHECK(message_loop_->BelongsToCurrentThread());
|
| + DVLOG(2) << "InitAudioDecoder()";
|
| + DCHECK(stream);
|
| +
|
| + init_done_cb_ = BindToCurrentLoop(init_done_cb);
|
| +
|
| + const AudioDecoderConfig& config = stream->audio_decoder_config();
|
| + if (!config.IsValidConfig()) {
|
| + DLOG(ERROR) << "Invalid audio stream config.";
|
| + base::ResetAndReturn(&init_done_cb_).Run(NULL, NULL);
|
| + return;
|
| + }
|
| +
|
| + input_stream_ = stream;
|
| + statistics_cb_ = statistics_cb;
|
| +
|
| + if (!config.is_encrypted()) {
|
| + if (precreated_decoders_.empty()) {
|
| + DLOG(ERROR) << "No audio decoder can be used to decode the input stream.";
|
| + base::ResetAndReturn(&init_done_cb_).Run(NULL, NULL);
|
| + return;
|
| + }
|
| +
|
| + InitializeNextPrecreatedDecoder();
|
| + return;
|
| + }
|
| +
|
| + // This could happen if Encrypted Media Extension (EME) is not enabled.
|
| + if (request_decryptor_notification_cb_.is_null()) {
|
| + base::ResetAndReturn(&init_done_cb_).Run(NULL, NULL);
|
| + return;
|
| + }
|
| +
|
| + audio_decoder_ = new DecryptingAudioDecoder(
|
| + message_loop_, request_decryptor_notification_cb_);
|
| +
|
| + audio_decoder_->Initialize(
|
| + input_stream_,
|
| + BindToCurrentLoop(base::Bind(
|
| + &AudioDecoderFactory::DecryptingAudioDecoderInitDone, weak_this_)),
|
| + statistics_cb_);
|
| +}
|
| +
|
| +void AudioDecoderFactory::DecryptingAudioDecoderInitDone(
|
| + PipelineStatus status) {
|
| + DCHECK(message_loop_->BelongsToCurrentThread());
|
| +
|
| + if (status == PIPELINE_OK) {
|
| + precreated_decoders_.clear();
|
| + base::ResetAndReturn(&init_done_cb_).Run(audio_decoder_, NULL);
|
| + return;
|
| + }
|
| +
|
| + audio_decoder_ = NULL;
|
| +
|
| + if (precreated_decoders_.empty()) {
|
| + DLOG(ERROR) << "No audio decoder can be used to decode the input stream.";
|
| + base::ResetAndReturn(&init_done_cb_).Run(NULL, NULL);
|
| + return;
|
| + }
|
| +
|
| + decrypted_stream_ = new DecryptingDemuxerStream(
|
| + message_loop_, request_decryptor_notification_cb_);
|
| +
|
| + decrypted_stream_->Initialize(
|
| + input_stream_,
|
| + BindToCurrentLoop(base::Bind(
|
| + &AudioDecoderFactory::DecryptingDemuxerStreamInitDone, weak_this_)));
|
| +}
|
| +
|
| +void AudioDecoderFactory::DecryptingDemuxerStreamInitDone(
|
| + PipelineStatus status) {
|
| + DCHECK(message_loop_->BelongsToCurrentThread());
|
| +
|
| + if (status != PIPELINE_OK) {
|
| + decrypted_stream_ = NULL;
|
| + base::ResetAndReturn(&init_done_cb_).Run(NULL, NULL);
|
| + return;
|
| + }
|
| +
|
| + DCHECK(!decrypted_stream_->audio_decoder_config().is_encrypted());
|
| + input_stream_ = decrypted_stream_;
|
| + InitializeNextPrecreatedDecoder();
|
| +}
|
| +
|
| +void AudioDecoderFactory::InitializeNextPrecreatedDecoder() {
|
| + DCHECK(message_loop_->BelongsToCurrentThread());
|
| + DCHECK(!precreated_decoders_.empty());
|
| +
|
| + audio_decoder_ = precreated_decoders_.front();
|
| + precreated_decoders_.pop_front();
|
| + DCHECK(audio_decoder_);
|
| + audio_decoder_->Initialize(
|
| + input_stream_,
|
| + BindToCurrentLoop(base::Bind(
|
| + &AudioDecoderFactory::PrecreatedDecoderInitDone, weak_this_)),
|
| + statistics_cb_);
|
| +}
|
| +
|
| +void AudioDecoderFactory::PrecreatedDecoderInitDone(PipelineStatus status) {
|
| + DCHECK(message_loop_->BelongsToCurrentThread());
|
| +
|
| + if (status != PIPELINE_OK) {
|
| + if (!precreated_decoders_.empty())
|
| + InitializeNextPrecreatedDecoder();
|
| + else
|
| + base::ResetAndReturn(&init_done_cb_).Run(NULL, NULL);
|
| + return;
|
| + }
|
| +
|
| + precreated_decoders_.clear();
|
| + base::ResetAndReturn(&init_done_cb_).Run(audio_decoder_, decrypted_stream_);
|
| +}
|
| +
|
| +AudioDecoderFactory::~AudioDecoderFactory() {}
|
| +
|
| +} // namespace media
|
|
|