1
0
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

188 lines
7.4 KiB

/*
* Copyright 2018 Fuzhou Rockchip Electronics Co. LTD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "RKATVAudioPolicyManager"
//#define LOG_NDEBUG 0
#include <media/AudioParameter.h>
#include <media/mediarecorder.h>
#include <utils/Log.h>
#include <utils/String16.h>
#include <utils/String8.h>
#include <utils/StrongPointer.h>
#include <cutils/properties.h>
#include "ATVAudioPolicyManager.h"
namespace android {
// --- class factory
extern "C" AudioPolicyInterface* createAudioPolicyManager(
AudioPolicyClientInterface *clientInterface)
{
ALOGD("%s: RKATVAudioPolicyManager ",__FUNCTION__);
ATVAudioPolicyManager *apm = new ATVAudioPolicyManager(clientInterface);
status_t status = apm->initialize();
if (status != NO_ERROR) {
delete apm;
apm = nullptr;
}
return apm;
}
extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
{
delete interface;
}
ATVAudioPolicyManager::ATVAudioPolicyManager(
AudioPolicyClientInterface *clientInterface)
: AudioPolicyManager(clientInterface)
{
ALOGD("%s",__FUNCTION__);
mBitstreamDevice = AUDIO_DEVICE_NONE;
}
status_t ATVAudioPolicyManager::initialize() {
return AudioPolicyManager::initialize();
}
bool ATVAudioPolicyManager::isAlreadConnect(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
const char *device_name,
audio_format_t encodedFormat)
{
// if device already in mAvailableOutputDevices, just return NO_ERROR
sp<DeviceDescriptor> devDesc =
mHwModules.getDeviceDescriptor(device, device_address, device_name, encodedFormat,
state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE);
if (audio_is_output_device(device)) {
ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
if(state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE){
if (index >= 0) {
return true;
}
}
}
return false;
}
/*
* set device for audio pass throught/bitstream (HDMI or spdif)
* there is no interface for android to set bitstream device
* we reusing setDeviceConnectionState to set the bitsteram device,
* if device_name = "RK_BITSTREAM_DEVICE_NAME", then set the bitstream device
*/
status_t ATVAudioPolicyManager::setBitStreamDevice(audio_devices_t device,audio_policy_dev_state_t state,
const char *device_address,const char *device_name, audio_format_t encodedFormat)
{
const char* setBitstreamDevice = "RK_BITSTREAM_DEVICE_NAME";
if((device_name != NULL) && (strcmp(device_name,setBitstreamDevice) == 0)){
audio_devices_t newDevice = mBitstreamDevice;
if((device == AUDIO_DEVICE_OUT_AUX_DIGITAL) && (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE)){
newDevice = AUDIO_DEVICE_OUT_AUX_DIGITAL;
}else if((device == AUDIO_DEVICE_OUT_SPDIF) && (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE)){
newDevice = AUDIO_DEVICE_OUT_SPDIF;
}
if((device == AUDIO_DEVICE_OUT_AUX_DIGITAL) || (device == AUDIO_DEVICE_OUT_SPDIF)){
// if device is changed, the surround format need clear
if(mBitstreamDevice != newDevice){
mBitstreamDevice = newDevice;
}
bool already = isAlreadConnect(device,state,device_address,device_name, encodedFormat);
if(already){
return NO_ERROR;
}
return AudioPolicyManager::setDeviceConnectionState(device, state, device_address, device_name, encodedFormat);
}
}
return -1;
}
status_t ATVAudioPolicyManager::setDeviceConnectionState(audio_devices_t device,
audio_policy_dev_state_t state,
const char *device_address,
const char *device_name,
audio_format_t encodedFormat)
{
ALOGD("ATVAudioPolicyManager::setDeviceConnectionState() device: 0x%X, state %d, address %s name %s format 0x%X",
device, state, device_address, device_name, encodedFormat);
if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
if(setBitStreamDevice(device,state,device_address,device_name, encodedFormat) == NO_ERROR) {
return NO_ERROR;
}
/*
* some device may be set connect already(For example: HDMI/SPDIF set connect for audio bitstream/pass throught by AudioSetting),
* so we just return NO_ERROR to tell AudioService or App this device is connect success
*/
bool already = isAlreadConnect(device,state,device_address,device_name, encodedFormat);
if(already){
ALOGD("setDeviceConnectionState() device already connected: %x", device);
return NO_ERROR;
}
return AudioPolicyManager::setDeviceConnectionState(device, state, device_address, device_name, encodedFormat);
}
/*
String deviceAddress = "RK_BITSTREAM_DEVICE_ADDRESS";
String deviceName = "RK_BITSTREAM_DEVICE_NAME";
*/
status_t ATVAudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
audio_io_handle_t *output,
audio_session_t session,
audio_stream_type_t *stream,
const AttributionSourceState& attributionSource,
const audio_config_t *config,
audio_output_flags_t *flags,
audio_port_handle_t *selectedDeviceId,
audio_port_handle_t *portId,
std::vector<audio_io_handle_t> *secondaryOutputs,
output_type_t *outputType) {
/*
* see flags which set in AudioTrack.cpp
* if (format == AUDIO_FORMAT_IEC61937) {
* flags = static_cast<audio_output_flags_t>(flags | AUDIO_OUTPUT_FLAG_IEC958_NONAUDIO);
*/
if ((config->format == AUDIO_FORMAT_IEC61937) && (*flags & AUDIO_OUTPUT_FLAG_DIRECT)) {
String8 address("RK_BITSTREAM_DEVICE_ADDRESS");
ALOGD("%s : getDevice for mBitstreamDevice = 0x%x", __FUNCTION__,mBitstreamDevice);
sp<DeviceDescriptor> device =
mAvailableOutputDevices.getDevice(mBitstreamDevice, address, AUDIO_FORMAT_IEC61937);
if (device != nullptr) {
*selectedDeviceId = device->getId();
} else{
ALOGD("%s,%d, connot get selectedDeviceId",__FUNCTION__,__LINE__);
}
}
return AudioPolicyManager::getOutputForAttr(attr, output, session, stream, attributionSource,
config, flags, selectedDeviceId, portId, secondaryOutputs, outputType);
}
} // namespace android