blob: 817a562ba6a1b116c200c429c254b5d67cbbd436 [file] [log] [blame]
// Copyright 2018 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/backend/direct_mixer_source.h"
#include "base/logging.h"
#include "chromecast/media/cma/backend/stream_mixer.h"
#include "chromecast/public/media/direct_audio_source.h"
#include "chromecast/public/media/media_pipeline_device_params.h"
#include "media/base/audio_bus.h"
namespace chromecast {
namespace media {
namespace {
std::string AudioContentTypeToString(media::AudioContentType type) {
switch (type) {
case media::AudioContentType::kMedia:
return "media";
case media::AudioContentType::kAlarm:
return "alarm";
case media::AudioContentType::kCommunication:
return "communication";
case media::AudioContentType::kOther:
return "other";
case media::AudioContentType::kNumTypes:
NOTREACHED();
}
return std::string();
}
} // namespace
// static
DirectAudioSourceToken* CastMediaShlib::AddDirectAudioSource(
DirectAudioSource* source,
const MediaPipelineDeviceParams& params,
int playout_channel) {
DCHECK(source);
return new DirectMixerSource(source, params, playout_channel);
}
// static
void CastMediaShlib::RemoveDirectAudioSource(DirectAudioSourceToken* token) {
DirectMixerSource* source = static_cast<DirectMixerSource*>(token);
source->Remove();
}
// static
void CastMediaShlib::SetDirectAudioSourceVolume(DirectAudioSourceToken* token,
float multiplier) {
DirectMixerSource* source = static_cast<DirectMixerSource*>(token);
source->SetVolumeMultiplier(multiplier);
}
DirectMixerSource::DirectMixerSource(DirectAudioSource* direct_source,
const MediaPipelineDeviceParams& params,
int playout_channel)
: source_(direct_source),
num_channels_(source_->GetNumChannels()),
input_samples_per_second_(source_->GetSampleRate()),
primary_(params.audio_type !=
MediaPipelineDeviceParams::kAudioStreamSoundEffects),
device_id_(params.device_id),
content_type_(params.content_type),
playout_channel_(playout_channel),
mixer_(StreamMixer::Get()),
channel_vector_(num_channels_) {
LOG(INFO) << "Create " << device_id_ << " (" << this
<< "), content type = " << AudioContentTypeToString(content_type_)
<< ", num_channels = " << num_channels_;
DCHECK(source_);
DCHECK(mixer_);
mixer_->AddInput(this);
}
DirectMixerSource::~DirectMixerSource() {
LOG(INFO) << "Destroy " << device_id_ << " (" << this << ")";
}
int DirectMixerSource::num_channels() {
return num_channels_;
}
int DirectMixerSource::input_samples_per_second() {
return input_samples_per_second_;
}
bool DirectMixerSource::primary() {
return primary_;
}
const std::string& DirectMixerSource::device_id() {
return device_id_;
}
AudioContentType DirectMixerSource::content_type() {
return content_type_;
}
int DirectMixerSource::desired_read_size() {
return source_->GetDesiredFillSize();
}
int DirectMixerSource::playout_channel() {
return playout_channel_;
}
void DirectMixerSource::SetVolumeMultiplier(float multiplier) {
mixer_->SetVolumeMultiplier(this, multiplier);
}
void DirectMixerSource::InitializeAudioPlayback(
int read_size,
RenderingDelay initial_rendering_delay) {
source_->InitializeAudioPlayback(read_size, initial_rendering_delay);
}
int DirectMixerSource::FillAudioPlaybackFrames(int num_frames,
RenderingDelay rendering_delay,
::media::AudioBus* buffer) {
DCHECK(buffer);
DCHECK_EQ(num_channels_, buffer->channels());
DCHECK_GE(buffer->frames(), num_frames);
for (int c = 0; c < num_channels_; ++c) {
channel_vector_[c] = buffer->channel(c);
}
return source_->FillAudioPlaybackFrames(num_frames, rendering_delay,
channel_vector_);
}
void DirectMixerSource::OnAudioPlaybackError(MixerError error) {
if (error == MixerError::kInputIgnored) {
LOG(INFO) << "Mixer input " << device_id_ << " (" << this << ")"
<< " now being ignored due to output sample rate change";
}
source_->OnAudioPlaybackError();
}
void DirectMixerSource::Remove() {
LOG(INFO) << "Remove " << device_id_ << " (" << this << ")";
mixer_->RemoveInput(this);
}
void DirectMixerSource::FinalizeAudioPlayback() {
source_->OnAudioPlaybackComplete();
delete this;
}
} // namespace media
} // namespace chromecast