blob: 7a779900c6e272e2ae908a119b7cf542f0e2d04b [file] [log] [blame]
// Copyright 2014 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 "chromecast/media/cma/pipeline/audio_pipeline_impl.h"
#include <stddef.h>
#include <utility>
#include "base/bind.h"
#include "base/logging.h"
#include "chromecast/media/cma/base/buffering_defs.h"
#include "chromecast/media/cma/base/coded_frame_provider.h"
#include "chromecast/media/cma/base/decoder_config_adapter.h"
#include "chromecast/media/cma/pipeline/backend_decryptor.h"
#include "chromecast/media/cma/pipeline/cdm_decryptor.h"
#include "chromecast/public/media/decoder_config.h"
#include "chromecast/public/media/media_capabilities_shlib.h"
#include "chromecast/public/media/media_pipeline_backend.h"
#include "media/base/audio_decoder_config.h"
namespace chromecast {
namespace media {
namespace {
const size_t kMaxAudioFrameSize = 32 * 1024;
}
AudioPipelineImpl::AudioPipelineImpl(CmaBackend::AudioDecoder* decoder,
const AvPipelineClient& client)
: AvPipelineImpl(decoder, client), audio_decoder_(decoder) {
DCHECK(audio_decoder_);
}
AudioPipelineImpl::~AudioPipelineImpl() = default;
::media::PipelineStatus AudioPipelineImpl::Initialize(
const ::media::AudioDecoderConfig& audio_config,
std::unique_ptr<CodedFrameProvider> frame_provider) {
LOG(INFO) << __FUNCTION__ << " " << audio_config.AsHumanReadableString();
if (frame_provider) {
SetCodedFrameProvider(std::move(frame_provider), kAppAudioBufferSize,
kMaxAudioFrameSize);
}
DCHECK(audio_config.IsValidConfig());
audio_config_ =
DecoderConfigAdapter::ToCastAudioConfig(kPrimary, audio_config);
if (!audio_decoder_->SetConfig(audio_config_)) {
return ::media::PIPELINE_ERROR_INITIALIZATION_FAILED;
}
set_state(kFlushed);
return ::media::PIPELINE_OK;
}
void AudioPipelineImpl::SetVolume(float volume) {
audio_decoder_->SetVolume(volume);
}
void AudioPipelineImpl::OnUpdateConfig(
StreamId id,
const ::media::AudioDecoderConfig& audio_config,
const ::media::VideoDecoderConfig& video_config) {
if (audio_config.IsValidConfig()) {
LOG(INFO) << __FUNCTION__ << " id:" << id << " "
<< audio_config.AsHumanReadableString();
audio_config_ = DecoderConfigAdapter::ToCastAudioConfig(id, audio_config);
bool success = audio_decoder_->SetConfig(audio_config_);
if (!success && !client().playback_error_cb.is_null())
client().playback_error_cb.Run(::media::PIPELINE_ERROR_DECODE);
}
}
EncryptionScheme AudioPipelineImpl::GetEncryptionScheme(StreamId id) const {
return audio_config_.encryption_scheme;
}
std::unique_ptr<StreamDecryptor> AudioPipelineImpl::CreateDecryptor() {
bool clear_buffer_needed = audio_decoder_->RequiresDecryption();
if (audio_config_.is_encrypted() &&
MediaPipelineBackend::CreateAudioDecryptor && clear_buffer_needed) {
LOG(INFO) << __func__ << " Create backend decryptor for audio.";
return std::make_unique<BackendDecryptor>(audio_config_.encryption_scheme);
}
return std::make_unique<CdmDecryptor>(clear_buffer_needed);
}
void AudioPipelineImpl::UpdateStatistics() {
if (client().statistics_cb.is_null())
return;
// TODO(mbjorge): Give Statistics a default constructor when the
// next system update happens. b/32802298
CmaBackend::AudioDecoder::Statistics audio_stats = {};
audio_decoder_->GetStatistics(&audio_stats);
::media::PipelineStatistics current_stats;
current_stats.audio_bytes_decoded = audio_stats.decoded_bytes;
::media::PipelineStatistics delta_stats;
delta_stats.audio_bytes_decoded =
current_stats.audio_bytes_decoded - previous_stats_.audio_bytes_decoded;
bytes_decoded_since_last_update_ = delta_stats.audio_bytes_decoded;
previous_stats_ = current_stats;
client().statistics_cb.Run(delta_stats);
}
} // namespace media
} // namespace chromecast