Merge "Add Quad channel output to AudioPolicyManager" into lmp-dev
diff --git a/camera/CameraUtils.cpp b/camera/CameraUtils.cpp
index 3ff181d..1ff63ab 100644
--- a/camera/CameraUtils.cpp
+++ b/camera/CameraUtils.cpp
@@ -73,18 +73,25 @@
return INVALID_OPERATION;
}
} else {
+ // Front camera needs to be horizontally flipped for
+ // mirror-like behavior.
+ // Note: Flips are applied before rotates.
switch (orientation) {
case 0:
- flags = HAL_TRANSFORM_FLIP_H;
+ flags = NATIVE_WINDOW_TRANSFORM_FLIP_H;
break;
case 90:
- flags = HAL_TRANSFORM_FLIP_H | HAL_TRANSFORM_ROT_90;
+ flags = NATIVE_WINDOW_TRANSFORM_FLIP_H |
+ NATIVE_WINDOW_TRANSFORM_ROT_270;
break;
case 180:
- flags = HAL_TRANSFORM_FLIP_V;
+ flags = NATIVE_WINDOW_TRANSFORM_FLIP_H |
+ NATIVE_WINDOW_TRANSFORM_ROT_180;
break;
case 270:
- flags = HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90;
+ flags = NATIVE_WINDOW_TRANSFORM_FLIP_H |
+ NATIVE_WINDOW_TRANSFORM_ROT_90;
+
break;
default:
ALOGE("%s: Invalid HAL android.sensor.orientation value: %d",
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 9ea18de..cf34991 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -139,12 +139,12 @@
// return the number of input frames lost by HAL implementation, or 0 if the handle is invalid
static uint32_t getInputFramesLost(audio_io_handle_t ioHandle);
- // Allocate a new audio session ID and return that new ID.
- // If unable to contact AudioFlinger, returns AUDIO_SESSION_ALLOCATE instead.
- // FIXME If AudioFlinger were to ever exhaust the session ID namespace,
- // this method could fail by returning either AUDIO_SESSION_ALLOCATE
- // or an unspecified existing session ID.
- static int newAudioSessionId();
+ // Allocate a new unique ID for use as an audio session ID or I/O handle.
+ // If unable to contact AudioFlinger, returns AUDIO_UNIQUE_ID_ALLOCATE instead.
+ // FIXME If AudioFlinger were to ever exhaust the unique ID namespace,
+ // this method could fail by returning either AUDIO_UNIQUE_ID_ALLOCATE
+ // or an unspecified existing unique ID.
+ static audio_unique_id_t newAudioUniqueId();
static void acquireAudioSessionId(int audioSession, pid_t pid);
static void releaseAudioSessionId(int audioSession, pid_t pid);
@@ -237,9 +237,12 @@
int sessionId,
audio_input_flags_t);
- static status_t startInput(audio_io_handle_t input);
- static status_t stopInput(audio_io_handle_t input);
- static void releaseInput(audio_io_handle_t input);
+ static status_t startInput(audio_io_handle_t input,
+ audio_session_t session);
+ static status_t stopInput(audio_io_handle_t input,
+ audio_session_t session);
+ static void releaseInput(audio_io_handle_t input,
+ audio_session_t session);
static status_t initStreamVolume(audio_stream_type_t stream,
int indexMin,
int indexMax);
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 31312d3..82ec09c 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -145,26 +145,26 @@
virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
audio_channel_mask_t channelMask) const = 0;
- virtual audio_io_handle_t openOutput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
- uint32_t *pLatencyMs,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo = NULL) = 0;
+ virtual status_t openOutput(audio_module_handle_t module,
+ audio_io_handle_t *output,
+ audio_config_t *config,
+ audio_devices_t *devices,
+ const String8& address,
+ uint32_t *latencyMs,
+ audio_output_flags_t flags) = 0;
virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
audio_io_handle_t output2) = 0;
virtual status_t closeOutput(audio_io_handle_t output) = 0;
virtual status_t suspendOutput(audio_io_handle_t output) = 0;
virtual status_t restoreOutput(audio_io_handle_t output) = 0;
- virtual audio_io_handle_t openInput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
- audio_input_flags_t flags) = 0;
+ virtual status_t openInput(audio_module_handle_t module,
+ audio_io_handle_t *input,
+ audio_config_t *config,
+ audio_devices_t *device,
+ const String8& address,
+ audio_source_t source,
+ audio_input_flags_t flags) = 0;
virtual status_t closeInput(audio_io_handle_t input) = 0;
virtual status_t invalidateStream(audio_stream_type_t stream) = 0;
@@ -176,7 +176,7 @@
virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const = 0;
- virtual int newAudioSessionId() = 0;
+ virtual audio_unique_id_t newAudioUniqueId() = 0;
virtual void acquireAudioSessionId(int audioSession, pid_t pid) = 0;
virtual void releaseAudioSessionId(int audioSession, pid_t pid) = 0;
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index e08b5ae..abbda32 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -75,9 +75,12 @@
audio_channel_mask_t channelMask,
int audioSession,
audio_input_flags_t flags) = 0;
- virtual status_t startInput(audio_io_handle_t input) = 0;
- virtual status_t stopInput(audio_io_handle_t input) = 0;
- virtual void releaseInput(audio_io_handle_t input) = 0;
+ virtual status_t startInput(audio_io_handle_t input,
+ audio_session_t session) = 0;
+ virtual status_t stopInput(audio_io_handle_t input,
+ audio_session_t session) = 0;
+ virtual void releaseInput(audio_io_handle_t input,
+ audio_session_t session) = 0;
virtual status_t initStreamVolume(audio_stream_type_t stream,
int indexMin,
int indexMax) = 0;
diff --git a/include/media/stagefright/foundation/ABase.h b/include/media/stagefright/foundation/ABase.h
index 9eceea3..949d49e 100644
--- a/include/media/stagefright/foundation/ABase.h
+++ b/include/media/stagefright/foundation/ABase.h
@@ -22,4 +22,31 @@
name(const name &); \
name &operator=(const name &)
+/* Returns true if the size parameter is safe for new array allocation (32-bit)
+ *
+ * Example usage:
+ *
+ * if (!isSafeArraySize<uint32_t>(arraySize)) {
+ * return BAD_VALUE;
+ * }
+ * ...
+ * uint32_t *myArray = new uint32_t[arraySize];
+ *
+ * There is a bug in gcc versions earlier than 4.8 where the new[] array allocation
+ * will overflow in the internal 32 bit heap allocation, resulting in an
+ * underallocated array. This is a security issue that allows potential overwriting
+ * of other heap data.
+ *
+ * An alternative to checking is to create a safe new array template function which
+ * either throws a std::bad_alloc exception or returns NULL/nullptr_t; NULL considered
+ * safe since normal access of NULL throws an exception.
+ *
+ * https://securityblog.redhat.com/2012/10/31/array-allocation-in-cxx/
+ */
+template <typename T, typename S>
+bool isSafeArraySize(S size) {
+ return size >= 0 // in case S is signed, ignored if not.
+ && size <= 0xffffffff / sizeof(T); // max-unsigned-32-bit-int / element-size.
+}
+
#endif // A_BASE_H_
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 80c8c5e..9e7ba88 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -214,7 +214,7 @@
// mNotificationFramesAct is initialized in openRecord_l
if (sessionId == AUDIO_SESSION_ALLOCATE) {
- mSessionId = AudioSystem::newAudioSessionId();
+ mSessionId = AudioSystem::newAudioUniqueId();
} else {
mSessionId = sessionId;
}
@@ -572,7 +572,7 @@
}
release:
- AudioSystem::releaseInput(input);
+ AudioSystem::releaseInput(input, (audio_session_t)mSessionId);
if (status == NO_ERROR) {
status = NO_INIT;
}
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index fd5824b..365a594 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -427,11 +427,11 @@
return result;
}
-int AudioSystem::newAudioSessionId()
+audio_unique_id_t AudioSystem::newAudioUniqueId()
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
- if (af == 0) return AUDIO_SESSION_ALLOCATE;
- return af->newAudioSessionId();
+ if (af == 0) return AUDIO_UNIQUE_ID_ALLOCATE;
+ return af->newAudioUniqueId();
}
void AudioSystem::acquireAudioSessionId(int audioSession, pid_t pid)
@@ -696,25 +696,28 @@
return aps->getInput(inputSource, samplingRate, format, channelMask, sessionId, flags);
}
-status_t AudioSystem::startInput(audio_io_handle_t input)
+status_t AudioSystem::startInput(audio_io_handle_t input,
+ audio_session_t session)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- return aps->startInput(input);
+ return aps->startInput(input, session);
}
-status_t AudioSystem::stopInput(audio_io_handle_t input)
+status_t AudioSystem::stopInput(audio_io_handle_t input,
+ audio_session_t session)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return PERMISSION_DENIED;
- return aps->stopInput(input);
+ return aps->stopInput(input, session);
}
-void AudioSystem::releaseInput(audio_io_handle_t input)
+void AudioSystem::releaseInput(audio_io_handle_t input,
+ audio_session_t session)
{
const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
if (aps == 0) return;
- aps->releaseInput(input);
+ aps->releaseInput(input, session);
}
status_t AudioSystem::initStreamVolume(audio_stream_type_t stream,
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index bd7ea46..5331fce 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -434,61 +434,40 @@
return reply.readInt64();
}
- virtual audio_io_handle_t openOutput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
- uint32_t *pLatencyMs,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo)
+ virtual status_t openOutput(audio_module_handle_t module,
+ audio_io_handle_t *output,
+ audio_config_t *config,
+ audio_devices_t *devices,
+ const String8& address,
+ uint32_t *latencyMs,
+ audio_output_flags_t flags)
{
+ if (output == NULL || config == NULL || devices == NULL || latencyMs == NULL) {
+ return BAD_VALUE;
+ }
Parcel data, reply;
- audio_devices_t devices = pDevices != NULL ? *pDevices : AUDIO_DEVICE_NONE;
- uint32_t samplingRate = pSamplingRate != NULL ? *pSamplingRate : 0;
- audio_format_t format = pFormat != NULL ? *pFormat : AUDIO_FORMAT_DEFAULT;
- audio_channel_mask_t channelMask = pChannelMask != NULL ?
- *pChannelMask : (audio_channel_mask_t)0;
- uint32_t latency = pLatencyMs != NULL ? *pLatencyMs : 0;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
data.writeInt32(module);
- data.writeInt32(devices);
- data.writeInt32(samplingRate);
- data.writeInt32(format);
- data.writeInt32(channelMask);
- data.writeInt32(latency);
+ data.write(config, sizeof(audio_config_t));
+ data.writeInt32(*devices);
+ data.writeString8(address);
data.writeInt32((int32_t) flags);
- // hasOffloadInfo
- if (offloadInfo == NULL) {
- data.writeInt32(0);
- } else {
- data.writeInt32(1);
- data.write(offloadInfo, sizeof(audio_offload_info_t));
+ status_t status = remote()->transact(OPEN_OUTPUT, data, &reply);
+ if (status != NO_ERROR) {
+ *output = AUDIO_IO_HANDLE_NONE;
+ return status;
}
- remote()->transact(OPEN_OUTPUT, data, &reply);
- audio_io_handle_t output = (audio_io_handle_t) reply.readInt32();
- ALOGV("openOutput() returned output, %d", output);
- devices = (audio_devices_t)reply.readInt32();
- if (pDevices != NULL) {
- *pDevices = devices;
+ status = (status_t)reply.readInt32();
+ if (status != NO_ERROR) {
+ *output = AUDIO_IO_HANDLE_NONE;
+ return status;
}
- samplingRate = reply.readInt32();
- if (pSamplingRate != NULL) {
- *pSamplingRate = samplingRate;
- }
- format = (audio_format_t) reply.readInt32();
- if (pFormat != NULL) {
- *pFormat = format;
- }
- channelMask = (audio_channel_mask_t)reply.readInt32();
- if (pChannelMask != NULL) {
- *pChannelMask = channelMask;
- }
- latency = reply.readInt32();
- if (pLatencyMs != NULL) {
- *pLatencyMs = latency;
- }
- return output;
+ *output = (audio_io_handle_t)reply.readInt32();
+ ALOGV("openOutput() returned output, %d", *output);
+ reply.read(config, sizeof(audio_config_t));
+ *devices = (audio_devices_t)reply.readInt32();
+ *latencyMs = reply.readInt32();
+ return NO_ERROR;
}
virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
@@ -529,46 +508,40 @@
return reply.readInt32();
}
- virtual audio_io_handle_t openInput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
- audio_input_flags_t flags)
+ virtual status_t openInput(audio_module_handle_t module,
+ audio_io_handle_t *input,
+ audio_config_t *config,
+ audio_devices_t *device,
+ const String8& address,
+ audio_source_t source,
+ audio_input_flags_t flags)
{
+ if (input == NULL || config == NULL || device == NULL) {
+ return BAD_VALUE;
+ }
Parcel data, reply;
- audio_devices_t devices = pDevices != NULL ? *pDevices : AUDIO_DEVICE_NONE;
- uint32_t samplingRate = pSamplingRate != NULL ? *pSamplingRate : 0;
- audio_format_t format = pFormat != NULL ? *pFormat : AUDIO_FORMAT_DEFAULT;
- audio_channel_mask_t channelMask = pChannelMask != NULL ?
- *pChannelMask : (audio_channel_mask_t)0;
-
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
data.writeInt32(module);
- data.writeInt32(devices);
- data.writeInt32(samplingRate);
- data.writeInt32(format);
- data.writeInt32(channelMask);
+ data.writeInt32(*input);
+ data.write(config, sizeof(audio_config_t));
+ data.writeInt32(*device);
+ data.writeString8(address);
+ data.writeInt32(source);
data.writeInt32(flags);
- remote()->transact(OPEN_INPUT, data, &reply);
- audio_io_handle_t input = (audio_io_handle_t) reply.readInt32();
- devices = (audio_devices_t)reply.readInt32();
- if (pDevices != NULL) {
- *pDevices = devices;
+ status_t status = remote()->transact(OPEN_INPUT, data, &reply);
+ if (status != NO_ERROR) {
+ *input = AUDIO_IO_HANDLE_NONE;
+ return status;
}
- samplingRate = reply.readInt32();
- if (pSamplingRate != NULL) {
- *pSamplingRate = samplingRate;
+ status = (status_t)reply.readInt32();
+ if (status != NO_ERROR) {
+ *input = AUDIO_IO_HANDLE_NONE;
+ return status;
}
- format = (audio_format_t) reply.readInt32();
- if (pFormat != NULL) {
- *pFormat = format;
- }
- channelMask = (audio_channel_mask_t)reply.readInt32();
- if (pChannelMask != NULL) {
- *pChannelMask = channelMask;
- }
- return input;
+ *input = (audio_io_handle_t)reply.readInt32();
+ reply.read(config, sizeof(audio_config_t));
+ *device = (audio_devices_t)reply.readInt32();
+ return NO_ERROR;
}
virtual status_t closeInput(int input)
@@ -631,12 +604,12 @@
return (uint32_t) reply.readInt32();
}
- virtual int newAudioSessionId()
+ virtual audio_unique_id_t newAudioUniqueId()
{
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
status_t status = remote()->transact(NEW_AUDIO_SESSION_ID, data, &reply);
- int id = AUDIO_SESSION_ALLOCATE;
+ audio_unique_id_t id = AUDIO_SESSION_ALLOCATE;
if (status == NO_ERROR) {
id = reply.readInt32();
}
@@ -1103,32 +1076,23 @@
case OPEN_OUTPUT: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
+ audio_config_t config;
+ data.read(&config, sizeof(audio_config_t));
audio_devices_t devices = (audio_devices_t)data.readInt32();
- uint32_t samplingRate = data.readInt32();
- audio_format_t format = (audio_format_t) data.readInt32();
- audio_channel_mask_t channelMask = (audio_channel_mask_t)data.readInt32();
- uint32_t latency = data.readInt32();
+ String8 address(data.readString8());
audio_output_flags_t flags = (audio_output_flags_t) data.readInt32();
- bool hasOffloadInfo = data.readInt32() != 0;
- audio_offload_info_t offloadInfo;
- if (hasOffloadInfo) {
- data.read(&offloadInfo, sizeof(audio_offload_info_t));
- }
- audio_io_handle_t output = openOutput(module,
- &devices,
- &samplingRate,
- &format,
- &channelMask,
- &latency,
- flags,
- hasOffloadInfo ? &offloadInfo : NULL);
+ uint32_t latencyMs;
+ audio_io_handle_t output;
+ status_t status = openOutput(module, &output, &config,
+ &devices, address, &latencyMs, flags);
ALOGV("OPEN_OUTPUT output, %d", output);
- reply->writeInt32((int32_t) output);
- reply->writeInt32(devices);
- reply->writeInt32(samplingRate);
- reply->writeInt32(format);
- reply->writeInt32(channelMask);
- reply->writeInt32(latency);
+ reply->writeInt32((int32_t)status);
+ if (status == NO_ERROR) {
+ reply->writeInt32((int32_t)output);
+ reply->write(&config, sizeof(audio_config_t));
+ reply->writeInt32(devices);
+ reply->writeInt32(latencyMs);
+ }
return NO_ERROR;
} break;
case OPEN_DUPLICATE_OUTPUT: {
@@ -1156,23 +1120,22 @@
case OPEN_INPUT: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
audio_module_handle_t module = (audio_module_handle_t)data.readInt32();
- audio_devices_t devices = (audio_devices_t)data.readInt32();
- uint32_t samplingRate = data.readInt32();
- audio_format_t format = (audio_format_t) data.readInt32();
- audio_channel_mask_t channelMask = (audio_channel_mask_t)data.readInt32();
+ audio_io_handle_t input = (audio_io_handle_t)data.readInt32();
+ audio_config_t config;
+ data.read(&config, sizeof(audio_config_t));
+ audio_devices_t device = (audio_devices_t)data.readInt32();
+ String8 address(data.readString8());
+ audio_source_t source = (audio_source_t)data.readInt32();
audio_input_flags_t flags = (audio_input_flags_t) data.readInt32();
- audio_io_handle_t input = openInput(module,
- &devices,
- &samplingRate,
- &format,
- &channelMask,
- flags);
- reply->writeInt32((int32_t) input);
- reply->writeInt32(devices);
- reply->writeInt32(samplingRate);
- reply->writeInt32(format);
- reply->writeInt32(channelMask);
+ status_t status = openInput(module, &input, &config,
+ &device, address, source, flags);
+ reply->writeInt32((int32_t) status);
+ if (status == NO_ERROR) {
+ reply->writeInt32((int32_t) input);
+ reply->write(&config, sizeof(audio_config_t));
+ reply->writeInt32(device);
+ }
return NO_ERROR;
} break;
case CLOSE_INPUT: {
@@ -1213,7 +1176,7 @@
} break;
case NEW_AUDIO_SESSION_ID: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
- reply->writeInt32(newAudioSessionId());
+ reply->writeInt32(newAudioUniqueId());
return NO_ERROR;
} break;
case ACQUIRE_AUDIO_SESSION_ID: {
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 40dfb58..1593b17 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -240,29 +240,35 @@
return static_cast <audio_io_handle_t> (reply.readInt32());
}
- virtual status_t startInput(audio_io_handle_t input)
+ virtual status_t startInput(audio_io_handle_t input,
+ audio_session_t session)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(input);
+ data.writeInt32(session);
remote()->transact(START_INPUT, data, &reply);
return static_cast <status_t> (reply.readInt32());
}
- virtual status_t stopInput(audio_io_handle_t input)
+ virtual status_t stopInput(audio_io_handle_t input,
+ audio_session_t session)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(input);
+ data.writeInt32(session);
remote()->transact(STOP_INPUT, data, &reply);
return static_cast <status_t> (reply.readInt32());
}
- virtual void releaseInput(audio_io_handle_t input)
+ virtual void releaseInput(audio_io_handle_t input,
+ audio_session_t session)
{
Parcel data, reply;
data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
data.writeInt32(input);
+ data.writeInt32(session);
remote()->transact(RELEASE_INPUT, data, &reply);
}
@@ -723,21 +729,24 @@
case START_INPUT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_io_handle_t input = static_cast <audio_io_handle_t>(data.readInt32());
- reply->writeInt32(static_cast <uint32_t>(startInput(input)));
+ audio_session_t session = static_cast <audio_session_t>(data.readInt32());
+ reply->writeInt32(static_cast <uint32_t>(startInput(input, session)));
return NO_ERROR;
} break;
case STOP_INPUT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_io_handle_t input = static_cast <audio_io_handle_t>(data.readInt32());
- reply->writeInt32(static_cast <uint32_t>(stopInput(input)));
+ audio_session_t session = static_cast <audio_session_t>(data.readInt32());
+ reply->writeInt32(static_cast <uint32_t>(stopInput(input, session)));
return NO_ERROR;
} break;
case RELEASE_INPUT: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
audio_io_handle_t input = static_cast <audio_io_handle_t>(data.readInt32());
- releaseInput(input);
+ audio_session_t session = static_cast <audio_session_t>(data.readInt32());
+ releaseInput(input, session);
return NO_ERROR;
} break;
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 2b7ea97..6cd377a 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -59,7 +59,7 @@
mLeftVolume = mRightVolume = 1.0;
mVideoWidth = mVideoHeight = 0;
mLockThreadId = 0;
- mAudioSessionId = AudioSystem::newAudioSessionId();
+ mAudioSessionId = AudioSystem::newAudioUniqueId();
AudioSystem::acquireAudioSessionId(mAudioSessionId, -1);
mSendLevel = 0;
mRetransmitEndpointValid = false;
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp
index e9c5e8e..dacb144 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.cpp
+++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp
@@ -62,18 +62,18 @@
player_type MediaPlayerFactory::getDefaultPlayerType() {
char value[PROPERTY_VALUE_MAX];
- if (property_get("media.stagefright.use-nuplayer", value, NULL)
+ if (property_get("media.stagefright.use-awesome", value, NULL)
&& (!strcmp("1", value) || !strcasecmp("true", value))) {
- return NU_PLAYER;
+ return STAGEFRIGHT_PLAYER;
}
// TODO: remove this EXPERIMENTAL developer settings property
- if (property_get("persist.sys.media.use-nuplayer", value, NULL)
+ if (property_get("persist.sys.media.use-awesome", value, NULL)
&& !strcasecmp("true", value)) {
- return NU_PLAYER;
+ return STAGEFRIGHT_PLAYER;
}
- return STAGEFRIGHT_PLAYER;
+ return NU_PLAYER;
}
status_t MediaPlayerFactory::registerFactory(IFactory* factory,
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 63a907c..0b09f58 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -42,6 +42,7 @@
uid_t uid)
: Source(notify),
mFetchSubtitleDataGeneration(0),
+ mFetchTimedTextDataGeneration(0),
mDurationUs(0ll),
mAudioIsVorbis(false),
mIsWidevine(isWidevine),
@@ -61,6 +62,7 @@
int fd, int64_t offset, int64_t length)
: Source(notify),
mFetchSubtitleDataGeneration(0),
+ mFetchTimedTextDataGeneration(0),
mDurationUs(0ll),
mAudioIsVorbis(false) {
DataSource::RegisterDefaultSniffers();
@@ -135,7 +137,6 @@
}
if (track != NULL) {
- CHECK_EQ(track->start(), (status_t)OK);
mSources.push(track);
int64_t durationUs;
if (meta->findInt64(kKeyDuration, &durationUs)) {
@@ -182,6 +183,7 @@
ALOGI("start");
if (mAudioTrack.mSource != NULL) {
+ CHECK_EQ(mAudioTrack.mSource->start(), (status_t)OK);
mAudioTrack.mPackets =
new AnotherPacketSource(mAudioTrack.mSource->getFormat());
@@ -189,6 +191,7 @@
}
if (mVideoTrack.mSource != NULL) {
+ CHECK_EQ(mVideoTrack.mSource->start(), (status_t)OK);
mVideoTrack.mPackets =
new AnotherPacketSource(mVideoTrack.mSource->getFormat());
@@ -204,66 +207,29 @@
switch (msg->what()) {
case kWhatFetchSubtitleData:
{
- int32_t generation;
- CHECK(msg->findInt32("generation", &generation));
- if (generation != mFetchSubtitleDataGeneration) {
- // stale
- break;
- }
+ fetchTextData(kWhatSendSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
+ mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
+ break;
+ }
- int32_t avail;
- if (mSubtitleTrack.mPackets->hasBufferAvailable(&avail)) {
- break;
- }
-
- int64_t timeUs;
- CHECK(msg->findInt64("timeUs", &timeUs));
-
- int64_t subTimeUs;
- readBuffer(MEDIA_TRACK_TYPE_SUBTITLE, timeUs, &subTimeUs);
-
- const int64_t oneSecUs = 1000000ll;
- const int64_t delayUs = subTimeUs - timeUs - oneSecUs;
- sp<AMessage> msg2 = new AMessage(kWhatSendSubtitleData, id());
- msg2->setInt32("generation", generation);
- msg2->post(delayUs < 0 ? 0 : delayUs);
- ALOGV("kWhatFetchSubtitleData generation %d, delayUs %lld",
- mFetchSubtitleDataGeneration, delayUs);
-
+ case kWhatFetchTimedTextData:
+ {
+ fetchTextData(kWhatSendTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
+ mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
break;
}
case kWhatSendSubtitleData:
{
- int32_t generation;
- CHECK(msg->findInt32("generation", &generation));
- if (generation != mFetchSubtitleDataGeneration) {
- // stale
- break;
- }
+ sendTextData(kWhatSubtitleData, MEDIA_TRACK_TYPE_SUBTITLE,
+ mFetchSubtitleDataGeneration, mSubtitleTrack.mPackets, msg);
+ break;
+ }
- int64_t subTimeUs;
- if (mSubtitleTrack.mPackets->nextBufferTime(&subTimeUs) != OK) {
- break;
- }
-
- int64_t nextSubTimeUs;
- readBuffer(MEDIA_TRACK_TYPE_SUBTITLE, -1, &nextSubTimeUs);
-
- sp<ABuffer> buffer;
- status_t dequeueStatus = mSubtitleTrack.mPackets->dequeueAccessUnit(&buffer);
- if (dequeueStatus != OK) {
- ALOGE("kWhatSendSubtitleData dequeueAccessUnit: %d", dequeueStatus);
- } else {
- sp<AMessage> notify = dupNotify();
- notify->setInt32("what", kWhatSubtitleData);
- notify->setBuffer("buffer", buffer);
- notify->post();
-
- const int64_t delayUs = nextSubTimeUs - subTimeUs;
- msg->post(delayUs < 0 ? 0 : delayUs);
- }
-
+ case kWhatSendTimedTextData:
+ {
+ sendTextData(kWhatTimedTextData, MEDIA_TRACK_TYPE_TIMEDTEXT,
+ mFetchTimedTextDataGeneration, mTimedTextTrack.mPackets, msg);
break;
}
@@ -290,7 +256,11 @@
}
+ if (track->mSource != NULL) {
+ track->mSource->stop();
+ }
track->mSource = source;
+ track->mSource->start();
track->mIndex = trackIndex;
status_t avail;
@@ -317,6 +287,74 @@
}
}
+void NuPlayer::GenericSource::fetchTextData(
+ uint32_t sendWhat,
+ media_track_type type,
+ int32_t curGen,
+ sp<AnotherPacketSource> packets,
+ sp<AMessage> msg) {
+ int32_t msgGeneration;
+ CHECK(msg->findInt32("generation", &msgGeneration));
+ if (msgGeneration != curGen) {
+ // stale
+ return;
+ }
+
+ int32_t avail;
+ if (packets->hasBufferAvailable(&avail)) {
+ return;
+ }
+
+ int64_t timeUs;
+ CHECK(msg->findInt64("timeUs", &timeUs));
+
+ int64_t subTimeUs;
+ readBuffer(type, timeUs, &subTimeUs);
+
+ int64_t delayUs = subTimeUs - timeUs;
+ if (msg->what() == kWhatFetchSubtitleData) {
+ const int64_t oneSecUs = 1000000ll;
+ delayUs -= oneSecUs;
+ }
+ sp<AMessage> msg2 = new AMessage(sendWhat, id());
+ msg2->setInt32("generation", msgGeneration);
+ msg2->post(delayUs < 0 ? 0 : delayUs);
+}
+
+void NuPlayer::GenericSource::sendTextData(
+ uint32_t what,
+ media_track_type type,
+ int32_t curGen,
+ sp<AnotherPacketSource> packets,
+ sp<AMessage> msg) {
+ int32_t msgGeneration;
+ CHECK(msg->findInt32("generation", &msgGeneration));
+ if (msgGeneration != curGen) {
+ // stale
+ return;
+ }
+
+ int64_t subTimeUs;
+ if (packets->nextBufferTime(&subTimeUs) != OK) {
+ return;
+ }
+
+ int64_t nextSubTimeUs;
+ readBuffer(type, -1, &nextSubTimeUs);
+
+ sp<ABuffer> buffer;
+ status_t dequeueStatus = packets->dequeueAccessUnit(&buffer);
+ if (dequeueStatus == OK) {
+ sp<AMessage> notify = dupNotify();
+ notify->setInt32("what", what);
+ notify->setBuffer("buffer", buffer);
+ notify->post();
+
+ const int64_t delayUs = nextSubTimeUs - subTimeUs;
+ msg->post(delayUs < 0 ? 0 : delayUs);
+ }
+}
+
sp<MetaData> NuPlayer::GenericSource::getFormatMeta(bool audio) {
sp<MediaSource> source = audio ? mAudioTrack.mSource : mVideoTrack.mSource;
@@ -351,27 +389,49 @@
readBuffer(audio? MEDIA_TRACK_TYPE_AUDIO : MEDIA_TRACK_TYPE_VIDEO, -1ll);
}
- if (mSubtitleTrack.mSource == NULL) {
+ if (mSubtitleTrack.mSource == NULL && mTimedTextTrack.mSource == NULL) {
return result;
}
- CHECK(mSubtitleTrack.mPackets != NULL);
+ if (mSubtitleTrack.mSource != NULL) {
+ CHECK(mSubtitleTrack.mPackets != NULL);
+ }
+ if (mTimedTextTrack.mSource != NULL) {
+ CHECK(mTimedTextTrack.mPackets != NULL);
+ }
+
if (result != OK) {
- mSubtitleTrack.mPackets->clear();
- mFetchSubtitleDataGeneration++;
+ if (mSubtitleTrack.mSource != NULL) {
+ mSubtitleTrack.mPackets->clear();
+ mFetchSubtitleDataGeneration++;
+ }
+ if (mTimedTextTrack.mSource != NULL) {
+ mTimedTextTrack.mPackets->clear();
+ mFetchTimedTextDataGeneration++;
+ }
return result;
}
int64_t timeUs;
status_t eosResult; // ignored
CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
- if (!mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
+
+ if (mSubtitleTrack.mSource != NULL
+ && !mSubtitleTrack.mPackets->hasBufferAvailable(&eosResult)) {
sp<AMessage> msg = new AMessage(kWhatFetchSubtitleData, id());
msg->setInt64("timeUs", timeUs);
msg->setInt32("generation", mFetchSubtitleDataGeneration);
msg->post();
}
+ if (mTimedTextTrack.mSource != NULL
+ && !mTimedTextTrack.mPackets->hasBufferAvailable(&eosResult)) {
+ sp<AMessage> msg = new AMessage(kWhatFetchTimedTextData, id());
+ msg->setInt64("timeUs", timeUs);
+ msg->setInt32("generation", mFetchTimedTextDataGeneration);
+ msg->post();
+ }
+
return result;
}
@@ -430,19 +490,53 @@
return format;
}
+ssize_t NuPlayer::GenericSource::getSelectedTrack(media_track_type type) const {
+ const Track *track = NULL;
+ switch (type) {
+ case MEDIA_TRACK_TYPE_VIDEO:
+ track = &mVideoTrack;
+ break;
+ case MEDIA_TRACK_TYPE_AUDIO:
+ track = &mAudioTrack;
+ break;
+ case MEDIA_TRACK_TYPE_TIMEDTEXT:
+ track = &mTimedTextTrack;
+ break;
+ case MEDIA_TRACK_TYPE_SUBTITLE:
+ track = &mSubtitleTrack;
+ break;
+ default:
+ break;
+ }
+
+ if (track != NULL && track->mSource != NULL) {
+ return track->mIndex;
+ }
+
+ return -1;
+}
+
status_t NuPlayer::GenericSource::selectTrack(size_t trackIndex, bool select) {
- ALOGV("selectTrack: %zu", trackIndex);
+ ALOGV("%s track: %zu", select ? "select" : "deselect", trackIndex);
if (trackIndex >= mSources.size()) {
return BAD_INDEX;
}
if (!select) {
- if (mSubtitleTrack.mSource == NULL || trackIndex != mSubtitleTrack.mIndex) {
+ Track* track = NULL;
+ if (mSubtitleTrack.mSource != NULL && trackIndex == mSubtitleTrack.mIndex) {
+ track = &mSubtitleTrack;
+ mFetchSubtitleDataGeneration++;
+ } else if (mTimedTextTrack.mSource != NULL && trackIndex == mTimedTextTrack.mIndex) {
+ track = &mTimedTextTrack;
+ mFetchTimedTextDataGeneration++;
+ }
+ if (track == NULL) {
return INVALID_OPERATION;
}
- mSubtitleTrack.mSource = NULL;
- mSubtitleTrack.mPackets->clear();
- mFetchSubtitleDataGeneration++;
+ track->mSource->stop();
+ track->mSource = NULL;
+ track->mPackets->clear();
return OK;
}
@@ -451,18 +545,31 @@
const char *mime;
CHECK(meta->findCString(kKeyMIMEType, &mime));
if (!strncasecmp(mime, "text/", 5)) {
- if (mSubtitleTrack.mSource != NULL && mSubtitleTrack.mIndex == trackIndex) {
+ bool isSubtitle = strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP);
+ Track *track = isSubtitle ? &mSubtitleTrack : &mTimedTextTrack;
+ if (track->mSource != NULL && track->mIndex == trackIndex) {
return OK;
}
- mSubtitleTrack.mIndex = trackIndex;
- mSubtitleTrack.mSource = mSources.itemAt(trackIndex);
- if (mSubtitleTrack.mPackets == NULL) {
- mSubtitleTrack.mPackets = new AnotherPacketSource(mSubtitleTrack.mSource->getFormat());
+ track->mIndex = trackIndex;
+ if (track->mSource != NULL) {
+ track->mSource->stop();
+ }
+ track->mSource = mSources.itemAt(trackIndex);
+ track->mSource->start();
+ if (track->mPackets == NULL) {
+ track->mPackets = new AnotherPacketSource(track->mSource->getFormat());
} else {
- mSubtitleTrack.mPackets->clear();
+ track->mPackets->clear();
+ track->mPackets->setFormat(track->mSource->getFormat());
}
- mFetchSubtitleDataGeneration++;
+
+ if (isSubtitle) {
+ mFetchSubtitleDataGeneration++;
+ } else {
+ mFetchTimedTextDataGeneration++;
+ }
+
return OK;
} else if (!strncasecmp(mime, "audio/", 6) || !strncasecmp(mime, "video/", 6)) {
bool audio = !strncasecmp(mime, "audio/", 6);
@@ -529,12 +636,19 @@
memcpy(abEnd, &numPageSamples, sizeof(numPageSamples));
}
+ sp<AMessage> meta = ab->meta();
+
int64_t timeUs;
CHECK(mb->meta_data()->findInt64(kKeyTime, &timeUs));
-
- sp<AMessage> meta = ab->meta();
meta->setInt64("timeUs", timeUs);
+ if (trackType == MEDIA_TRACK_TYPE_TIMEDTEXT) {
+ const char *mime;
+ CHECK(mTimedTextTrack.mSource != NULL
+ && mTimedTextTrack.mSource->getFormat()->findCString(kKeyMIMEType, &mime));
+ meta->setString("mime", mime);
+ }
+
int64_t durationUs;
if (mb->meta_data()->findInt64(kKeyDuration, &durationUs)) {
meta->setInt64("durationUs", durationUs);
@@ -567,6 +681,9 @@
case MEDIA_TRACK_TYPE_SUBTITLE:
track = &mSubtitleTrack;
break;
+ case MEDIA_TRACK_TYPE_TIMEDTEXT:
+ track = &mTimedTextTrack;
+ break;
default:
TRESPASS();
}
@@ -602,7 +719,9 @@
// formatChange && seeking: track whose source is changed during selection
// formatChange && !seeking: track whose source is not changed during selection
// !formatChange: normal seek
- if ((seeking || formatChange) && trackType != MEDIA_TRACK_TYPE_SUBTITLE) {
+ if ((seeking || formatChange)
+ && (trackType == MEDIA_TRACK_TYPE_AUDIO
+ || trackType == MEDIA_TRACK_TYPE_VIDEO)) {
ATSParser::DiscontinuityType type = formatChange
? (seeking
? ATSParser::DISCONTINUITY_FORMATCHANGE
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index 4e25d55..3c5f55c 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -58,6 +58,7 @@
virtual status_t getDuration(int64_t *durationUs);
virtual size_t getTrackCount() const;
virtual sp<AMessage> getTrackInfo(size_t trackIndex) const;
+ virtual ssize_t getSelectedTrack(media_track_type type) const;
virtual status_t selectTrack(size_t trackIndex, bool select);
virtual status_t seekTo(int64_t seekTimeUs);
@@ -73,7 +74,9 @@
private:
enum {
kWhatFetchSubtitleData,
+ kWhatFetchTimedTextData,
kWhatSendSubtitleData,
+ kWhatSendTimedTextData,
kWhatChangeAVSource,
};
@@ -88,8 +91,10 @@
Track mAudioTrack;
Track mVideoTrack;
Track mSubtitleTrack;
+ Track mTimedTextTrack;
int32_t mFetchSubtitleDataGeneration;
+ int32_t mFetchTimedTextDataGeneration;
int64_t mDurationUs;
bool mAudioIsVorbis;
bool mIsWidevine;
@@ -98,6 +103,14 @@
void initFromDataSource(const sp<DataSource> &dataSource);
+ void fetchTextData(
+ uint32_t what, media_track_type type,
+ int32_t curGen, sp<AnotherPacketSource> packets, sp<AMessage> msg);
+
+ void sendTextData(
+ uint32_t what, media_track_type type,
+ int32_t curGen, sp<AnotherPacketSource> packets, sp<AMessage> msg);
+
sp<ABuffer> mediaBufferToABuffer(
MediaBuffer *mbuf,
media_track_type trackType,
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index bad43f2..bdd6d56 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -330,6 +330,10 @@
}
mTimeToSampleCount = U32_AT(&header[4]);
+ uint64_t allocSize = mTimeToSampleCount * 2 * sizeof(uint32_t);
+ if (allocSize > SIZE_MAX) {
+ return ERROR_OUT_OF_RANGE;
+ }
mTimeToSample = new uint32_t[mTimeToSampleCount * 2];
size_t size = sizeof(uint32_t) * mTimeToSampleCount * 2;
@@ -372,6 +376,11 @@
}
mNumCompositionTimeDeltaEntries = numEntries;
+ uint64_t allocSize = numEntries * 2 * sizeof(uint32_t);
+ if (allocSize > SIZE_MAX) {
+ return ERROR_OUT_OF_RANGE;
+ }
+
mCompositionTimeDeltaEntries = new uint32_t[2 * numEntries];
if (mDataSource->readAt(
@@ -417,6 +426,11 @@
ALOGV("Table of sync samples is empty or has only a single entry!");
}
+ uint64_t allocSize = mNumSyncSamples * sizeof(uint32_t);
+ if (allocSize > SIZE_MAX) {
+ return ERROR_OUT_OF_RANGE;
+ }
+
mSyncSamples = new uint32_t[mNumSyncSamples];
size_t size = mNumSyncSamples * sizeof(uint32_t);
if (mDataSource->readAt(mSyncSampleOffset + 8, mSyncSamples, size)
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index f10a561..bd7121e 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1097,7 +1097,7 @@
AutoMutex lock(mHardwareLock);
mHardwareStatus = AUDIO_HW_GET_INPUT_BUFFER_SIZE;
- struct audio_config config;
+ audio_config_t config;
memset(&config, 0, sizeof(config));
config.sample_rate = sampleRate;
config.channel_mask = channelMask;
@@ -1577,17 +1577,21 @@
sp<AudioFlinger::PlaybackThread> AudioFlinger::openOutput_l(audio_module_handle_t module,
- audio_devices_t device,
- struct audio_config *config,
+ audio_io_handle_t *output,
+ audio_config_t *config,
+ audio_devices_t devices,
+ const String8& address,
audio_output_flags_t flags)
{
- AudioHwDevice *outHwDev = findSuitableHwDev_l(module, device);
+ AudioHwDevice *outHwDev = findSuitableHwDev_l(module, devices);
if (outHwDev == NULL) {
- return AUDIO_IO_HANDLE_NONE;
+ return 0;
}
audio_hw_device_t *hwDevHal = outHwDev->hwDevice();
- audio_io_handle_t id = nextUniqueId();
+ if (*output == AUDIO_IO_HANDLE_NONE) {
+ *output = nextUniqueId();
+ }
mHardwareStatus = AUDIO_HW_OUTPUT_OPEN;
@@ -1604,7 +1608,7 @@
//config->format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
//config->format = AUDIO_FORMAT_PCM_32_BIT;
//config->format = AUDIO_FORMAT_PCM_8_24_BIT;
- // ALOGV("openOutput() upgrading format to %#08x", config.format);
+ // ALOGV("openOutput_l() upgrading format to %#08x", config->format);
}
if (kEnableExtendedChannels) {
// Specify channel mask (uncomment one below to choose)
@@ -1615,14 +1619,15 @@
}
status_t status = hwDevHal->open_output_stream(hwDevHal,
- id,
- device,
- flags,
- config,
- &outStream);
+ *output,
+ devices,
+ flags,
+ config,
+ &outStream,
+ address.string());
mHardwareStatus = AUDIO_HW_IDLE;
- ALOGV("openOutput() openOutputStream returned output %p, sampleRate %d, Format %#x, "
+ ALOGV("openOutput_l() openOutputStream returned output %p, sampleRate %d, Format %#x, "
"channelMask %#x, status %d",
outStream,
config->sample_rate,
@@ -1631,76 +1636,53 @@
status);
if (status == NO_ERROR && outStream != NULL) {
- AudioStreamOut *output = new AudioStreamOut(outHwDev, outStream, flags);
+ AudioStreamOut *outputStream = new AudioStreamOut(outHwDev, outStream, flags);
PlaybackThread *thread;
if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
- thread = new OffloadThread(this, output, id, device);
- ALOGV("openOutput() created offload output: ID %d thread %p", id, thread);
+ thread = new OffloadThread(this, outputStream, *output, devices);
+ ALOGV("openOutput_l() created offload output: ID %d thread %p", *output, thread);
} else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
|| !isValidPcmSinkFormat(config->format)
|| !isValidPcmSinkChannelMask(config->channel_mask)) {
- thread = new DirectOutputThread(this, output, id, device);
- ALOGV("openOutput() created direct output: ID %d thread %p", id, thread);
+ thread = new DirectOutputThread(this, outputStream, *output, devices);
+ ALOGV("openOutput_l() created direct output: ID %d thread %p", *output, thread);
} else {
- thread = new MixerThread(this, output, id, device);
- ALOGV("openOutput() created mixer output: ID %d thread %p", id, thread);
+ thread = new MixerThread(this, outputStream, *output, devices);
+ ALOGV("openOutput_l() created mixer output: ID %d thread %p", *output, thread);
}
- mPlaybackThreads.add(id, thread);
+ mPlaybackThreads.add(*output, thread);
return thread;
}
return 0;
}
-audio_io_handle_t AudioFlinger::openOutput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
- uint32_t *pLatencyMs,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo)
+status_t AudioFlinger::openOutput(audio_module_handle_t module,
+ audio_io_handle_t *output,
+ audio_config_t *config,
+ audio_devices_t *devices,
+ const String8& address,
+ uint32_t *latencyMs,
+ audio_output_flags_t flags)
{
- struct audio_config config;
- memset(&config, 0, sizeof(config));
- config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;
- config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;
- config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;
- if (offloadInfo != NULL) {
- config.offload_info = *offloadInfo;
- }
-
ALOGV("openOutput(), module %d Device %x, SamplingRate %d, Format %#08x, Channels %x, flags %x",
module,
- (pDevices != NULL) ? *pDevices : 0,
- config.sample_rate,
- config.format,
- config.channel_mask,
+ (devices != NULL) ? *devices : 0,
+ config->sample_rate,
+ config->format,
+ config->channel_mask,
flags);
- ALOGV("openOutput(), offloadInfo %p version 0x%04x",
- offloadInfo, offloadInfo == NULL ? -1 : offloadInfo->version);
- if (pDevices == NULL || *pDevices == AUDIO_DEVICE_NONE) {
- return AUDIO_IO_HANDLE_NONE;
+ if (*devices == AUDIO_DEVICE_NONE) {
+ return BAD_VALUE;
}
Mutex::Autolock _l(mLock);
- sp<PlaybackThread> thread = openOutput_l(module, *pDevices, &config, flags);
+ sp<PlaybackThread> thread = openOutput_l(module, output, config, *devices, address, flags);
if (thread != 0) {
- if (pSamplingRate != NULL) {
- *pSamplingRate = config.sample_rate;
- }
- if (pFormat != NULL) {
- *pFormat = config.format;
- }
- if (pChannelMask != NULL) {
- *pChannelMask = config.channel_mask;
- }
- if (pLatencyMs != NULL) {
- *pLatencyMs = thread->latency();
- }
+ *latencyMs = thread->latency();
// notify client processes of the new output creation
thread->audioConfigChanged(AudioSystem::OUTPUT_OPENED);
@@ -1715,12 +1697,12 @@
mPrimaryHardwareDev->hwDevice()->set_mode(mPrimaryHardwareDev->hwDevice(), mMode);
mHardwareStatus = AUDIO_HW_IDLE;
- mPrimaryOutputSampleRate = config.sample_rate;
+ mPrimaryOutputSampleRate = config->sample_rate;
}
- return thread->id();
+ return NO_ERROR;
}
- return AUDIO_IO_HANDLE_NONE;
+ return NO_INIT;
}
audio_io_handle_t AudioFlinger::openDuplicateOutput(audio_io_handle_t output1,
@@ -1851,75 +1833,59 @@
return NO_ERROR;
}
-audio_io_handle_t AudioFlinger::openInput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
+status_t AudioFlinger::openInput(audio_module_handle_t module,
+ audio_io_handle_t *input,
+ audio_config_t *config,
+ audio_devices_t *device,
+ const String8& address,
+ audio_source_t source,
audio_input_flags_t flags)
{
Mutex::Autolock _l(mLock);
- if (pDevices == NULL || *pDevices == AUDIO_DEVICE_NONE) {
- return AUDIO_IO_HANDLE_NONE;
+ if (*device == AUDIO_DEVICE_NONE) {
+ return BAD_VALUE;
}
- struct audio_config config;
- memset(&config, 0, sizeof(config));
- config.sample_rate = (pSamplingRate != NULL) ? *pSamplingRate : 0;
- config.channel_mask = (pChannelMask != NULL) ? *pChannelMask : 0;
- config.format = (pFormat != NULL) ? *pFormat : AUDIO_FORMAT_DEFAULT;
-
- uint32_t reqSamplingRate = config.sample_rate;
- audio_format_t reqFormat = config.format;
- audio_channel_mask_t reqChannelMask = config.channel_mask;
-
- sp<RecordThread> thread = openInput_l(module, *pDevices, &config, flags);
+ sp<RecordThread> thread = openInput_l(module, input, config, *device, address, source, flags);
if (thread != 0) {
- if (pSamplingRate != NULL) {
- *pSamplingRate = reqSamplingRate;
- }
- if (pFormat != NULL) {
- *pFormat = config.format;
- }
- if (pChannelMask != NULL) {
- *pChannelMask = reqChannelMask;
- }
-
// notify client processes of the new input creation
thread->audioConfigChanged(AudioSystem::INPUT_OPENED);
- return thread->id();
+ return NO_ERROR;
}
- return AUDIO_IO_HANDLE_NONE;
+ return NO_INIT;
}
sp<AudioFlinger::RecordThread> AudioFlinger::openInput_l(audio_module_handle_t module,
+ audio_io_handle_t *input,
+ audio_config_t *config,
audio_devices_t device,
- struct audio_config *config,
+ const String8& address,
+ audio_source_t source,
audio_input_flags_t flags)
{
- uint32_t reqSamplingRate = config->sample_rate;
- audio_format_t reqFormat = config->format;
- audio_channel_mask_t reqChannelMask = config->channel_mask;
-
AudioHwDevice *inHwDev = findSuitableHwDev_l(module, device);
if (inHwDev == NULL) {
+ *input = AUDIO_IO_HANDLE_NONE;
return 0;
}
- audio_hw_device_t *inHwHal = inHwDev->hwDevice();
- audio_io_handle_t id = nextUniqueId();
+ if (*input == AUDIO_IO_HANDLE_NONE) {
+ *input = nextUniqueId();
+ }
+ audio_config_t halconfig = *config;
+ audio_hw_device_t *inHwHal = inHwDev->hwDevice();
audio_stream_in_t *inStream = NULL;
- status_t status = inHwHal->open_input_stream(inHwHal, id, device, config,
- &inStream, flags);
- ALOGV("openInput() openInputStream returned input %p, SamplingRate %d, Format %#x, Channels %x, "
- "flags %#x, status %d",
+ status_t status = inHwHal->open_input_stream(inHwHal, *input, device, &halconfig,
+ &inStream, flags, address.string(), source);
+ ALOGV("openInput_l() openInputStream returned input %p, SamplingRate %d"
+ ", Format %#x, Channels %x, flags %#x, status %d",
inStream,
- config->sample_rate,
- config->format,
- config->channel_mask,
+ halconfig.sample_rate,
+ halconfig.format,
+ halconfig.channel_mask,
flags,
status);
@@ -1927,14 +1893,15 @@
// conversion internally, try to open again with the proposed parameters. The AudioFlinger can
// resample the input and do mono to stereo or stereo to mono conversions on 16 bit PCM inputs.
if (status == BAD_VALUE &&
- reqFormat == config->format && config->format == AUDIO_FORMAT_PCM_16_BIT &&
- (config->sample_rate <= 2 * reqSamplingRate) &&
- (audio_channel_count_from_in_mask(config->channel_mask) <= FCC_2) &&
- (audio_channel_count_from_in_mask(reqChannelMask) <= FCC_2)) {
+ config->format == halconfig.format && halconfig.format == AUDIO_FORMAT_PCM_16_BIT &&
+ (halconfig.sample_rate <= 2 * config->sample_rate) &&
+ (audio_channel_count_from_in_mask(halconfig.channel_mask) <= FCC_2) &&
+ (audio_channel_count_from_in_mask(config->channel_mask) <= FCC_2)) {
// FIXME describe the change proposed by HAL (save old values so we can log them here)
- ALOGV("openInput() reopening with proposed sampling rate and channel mask");
+ ALOGV("openInput_l() reopening with proposed sampling rate and channel mask");
inStream = NULL;
- status = inHwHal->open_input_stream(inHwHal, id, device, config, &inStream, flags);
+ status = inHwHal->open_input_stream(inHwHal, *input, device, &halconfig,
+ &inStream, flags, address.string(), source);
// FIXME log this new status; HAL should not propose any further changes
}
@@ -1990,25 +1957,26 @@
}
#endif
- AudioStreamIn *input = new AudioStreamIn(inHwDev, inStream);
+ AudioStreamIn *inputStream = new AudioStreamIn(inHwDev, inStream);
// Start record thread
// RecordThread requires both input and output device indication to forward to audio
// pre processing modules
sp<RecordThread> thread = new RecordThread(this,
- input,
- id,
+ inputStream,
+ *input,
primaryOutputDevice_l(),
device
#ifdef TEE_SINK
, teeSink
#endif
);
- mRecordThreads.add(id, thread);
- ALOGV("openInput() created record thread: ID %d thread %p", id, thread.get());
+ mRecordThreads.add(*input, thread);
+ ALOGV("openInput_l() created record thread: ID %d thread %p", *input, thread.get());
return thread;
}
+ *input = AUDIO_IO_HANDLE_NONE;
return 0;
}
@@ -2069,7 +2037,7 @@
}
-int AudioFlinger::newAudioSessionId()
+audio_unique_id_t AudioFlinger::newAudioUniqueId()
{
return nextUniqueId();
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index ab4c567..31c5a1a 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -158,14 +158,13 @@
virtual size_t getInputBufferSize(uint32_t sampleRate, audio_format_t format,
audio_channel_mask_t channelMask) const;
- virtual audio_io_handle_t openOutput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
- uint32_t *pLatencyMs,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo);
+ virtual status_t openOutput(audio_module_handle_t module,
+ audio_io_handle_t *output,
+ audio_config_t *config,
+ audio_devices_t *devices,
+ const String8& address,
+ uint32_t *latencyMs,
+ audio_output_flags_t flags);
virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1,
audio_io_handle_t output2);
@@ -176,12 +175,13 @@
virtual status_t restoreOutput(audio_io_handle_t output);
- virtual audio_io_handle_t openInput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
- audio_input_flags_t flags);
+ virtual status_t openInput(audio_module_handle_t module,
+ audio_io_handle_t *input,
+ audio_config_t *config,
+ audio_devices_t *device,
+ const String8& address,
+ audio_source_t source,
+ audio_input_flags_t flags);
virtual status_t closeInput(audio_io_handle_t input);
@@ -194,7 +194,7 @@
virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const;
- virtual int newAudioSessionId();
+ virtual audio_unique_id_t newAudioUniqueId();
virtual void acquireAudioSessionId(int audioSession, pid_t pid);
@@ -331,7 +331,7 @@
// Set kEnableExtendedChannels to true to enable greater than stereo output
// for the MixerThread and device sink. Number of channels allowed is
// FCC_2 <= channels <= AudioMixer::MAX_NUM_CHANNELS.
- static const bool kEnableExtendedChannels = false;
+ static const bool kEnableExtendedChannels = true;
// Returns true if channel mask is permitted for the PCM sink in the MixerThread
static inline bool isValidPcmSinkChannelMask(audio_channel_mask_t channelMask) {
@@ -515,12 +515,17 @@
MixerThread *checkMixerThread_l(audio_io_handle_t output) const;
RecordThread *checkRecordThread_l(audio_io_handle_t input) const;
sp<RecordThread> openInput_l(audio_module_handle_t module,
+ audio_io_handle_t *input,
+ audio_config_t *config,
audio_devices_t device,
- struct audio_config *config,
+ const String8& address,
+ audio_source_t source,
audio_input_flags_t flags);
sp<PlaybackThread> openOutput_l(audio_module_handle_t module,
- audio_devices_t device,
- struct audio_config *config,
+ audio_io_handle_t *output,
+ audio_config_t *config,
+ audio_devices_t devices,
+ const String8& address,
audio_output_flags_t flags);
void closeOutputFinish(sp<PlaybackThread> thread);
diff --git a/services/audioflinger/AudioMixerOps.h b/services/audioflinger/AudioMixerOps.h
index 49131f6..f7376a8 100644
--- a/services/audioflinger/AudioMixerOps.h
+++ b/services/audioflinger/AudioMixerOps.h
@@ -184,7 +184,7 @@
template <typename TO, typename TI>
inline void MixAccum(TO *auxaccum, TI value) {
if (!is_same<TO, TI>::value) {
- LOG_ALWAYS_FATAL("MixAccum type not properly specialized: %d %d\n",
+ LOG_ALWAYS_FATAL("MixAccum type not properly specialized: %zu %zu\n",
sizeof(TO), sizeof(TI));
}
*auxaccum += value;
diff --git a/services/audioflinger/AudioResamplerDyn.cpp b/services/audioflinger/AudioResamplerDyn.cpp
index e201ff8..159ab70 100644
--- a/services/audioflinger/AudioResamplerDyn.cpp
+++ b/services/audioflinger/AudioResamplerDyn.cpp
@@ -82,17 +82,17 @@
void AudioResamplerDyn<TC, TI, TO>::InBuffer::resize(int CHANNELS, int halfNumCoefs)
{
// calculate desired state size
- int stateCount = halfNumCoefs * CHANNELS * 2 * kStateSizeMultipleOfFilterLength;
+ size_t stateCount = halfNumCoefs * CHANNELS * 2 * kStateSizeMultipleOfFilterLength;
// check if buffer needs resizing
if (mState
&& stateCount == mStateCount
- && mRingFull-mState == mStateCount-halfNumCoefs*CHANNELS) {
+ && mRingFull-mState == (ssize_t) (mStateCount-halfNumCoefs*CHANNELS)) {
return;
}
// create new buffer
- TI* state;
+ TI* state = NULL;
(void)posix_memalign(reinterpret_cast<void**>(&state), 32, stateCount*sizeof(*state));
memset(state, 0, stateCount*sizeof(*state));
@@ -213,7 +213,7 @@
void AudioResamplerDyn<TC, TI, TO>::createKaiserFir(Constants &c,
double stopBandAtten, int inSampleRate, int outSampleRate, double tbwCheat)
{
- TC* buf;
+ TC* buf = NULL;
static const double atten = 0.9998; // to avoid ripple overflow
double fcr;
double tbw = firKaiserTbw(c.mHalfNumCoefs, stopBandAtten);
diff --git a/services/audioflinger/AudioResamplerFirProcess.h b/services/audioflinger/AudioResamplerFirProcess.h
index d130013..efc8055 100644
--- a/services/audioflinger/AudioResamplerFirProcess.h
+++ b/services/audioflinger/AudioResamplerFirProcess.h
@@ -177,7 +177,7 @@
template <int CHANNELS, int STRIDE, typename TFUNC, typename TC, typename TI, typename TO, typename TINTERP>
static inline
void ProcessBase(TO* const out,
- int count,
+ size_t count,
const TC* coefsP,
const TC* coefsN,
const TI* sP,
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index bf509e7..49422a9 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -231,14 +231,16 @@
goto exit;
}
} else {
- struct audio_config config;
- config.sample_rate = 0;
- config.channel_mask = AUDIO_CHANNEL_NONE;
- config.format = AUDIO_FORMAT_DEFAULT;
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ audio_devices_t device = patch->sinks[0].ext.device.type;
+ String8 address = String8(patch->sinks[0].ext.device.address);
+ audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
newPatch->mPlaybackThread = audioflinger->openOutput_l(
patch->sinks[0].ext.device.hw_module,
- patch->sinks[0].ext.device.type,
+ &output,
&config,
+ device,
+ address,
AUDIO_OUTPUT_FLAG_NONE);
ALOGV("audioflinger->openOutput_l() returned %p",
newPatch->mPlaybackThread.get());
@@ -249,14 +251,19 @@
}
uint32_t channelCount = newPatch->mPlaybackThread->channelCount();
audio_devices_t device = patch->sources[0].ext.device.type;
- struct audio_config config;
+ String8 address = String8(patch->sources[0].ext.device.address);
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
audio_channel_mask_t inChannelMask = audio_channel_in_mask_from_count(channelCount);
config.sample_rate = newPatch->mPlaybackThread->sampleRate();
config.channel_mask = inChannelMask;
config.format = newPatch->mPlaybackThread->format();
+ audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
newPatch->mRecordThread = audioflinger->openInput_l(src_module,
- device,
+ &input,
&config,
+ device,
+ address,
+ AUDIO_SOURCE_MIC,
AUDIO_INPUT_FLAG_NONE);
ALOGV("audioflinger->openInput_l() returned %p inChannelMask %08x",
newPatch->mRecordThread.get(), inChannelMask);
@@ -298,14 +305,22 @@
status = BAD_VALUE;
goto exit;
}
- AudioParameter param;
- param.addInt(String8(AudioParameter::keyRouting),
+ char *address;
+ if (strcmp(patch->sources[0].ext.device.address, "") != 0) {
+ address = audio_device_address_to_parameter(
+ patch->sources[0].ext.device.type,
+ patch->sources[0].ext.device.address);
+ } else {
+ address = (char *)calloc(1, 1);
+ }
+ AudioParameter param = AudioParameter(String8(address));
+ free(address);
+ param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING),
(int)patch->sources[0].ext.device.type);
- param.addInt(String8(AudioParameter::keyInputSource),
- (int)patch->sinks[0].ext.mix.usecase.source);
-
+ param.addInt(String8(AUDIO_PARAMETER_STREAM_INPUT_SOURCE),
+ (int)patch->sinks[0].ext.mix.usecase.source);
ALOGV("createAudioPatch() AUDIO_PORT_TYPE_DEVICE setParameters %s",
- param.toString().string());
+ param.toString().string());
status = thread->setParameters(param.toString());
}
}
@@ -348,8 +363,17 @@
for (unsigned int i = 0; i < patch->num_sinks; i++) {
type |= patch->sinks[i].ext.device.type;
}
- AudioParameter param;
- param.addInt(String8(AudioParameter::keyRouting), (int)type);
+ char *address;
+ if (strcmp(patch->sinks[0].ext.device.address, "") != 0) {
+ address = audio_device_address_to_parameter(
+ patch->sinks[0].ext.device.type,
+ patch->sinks[0].ext.device.address);
+ } else {
+ address = (char *)calloc(1, 1);
+ }
+ AudioParameter param = AudioParameter(String8(address));
+ free(address);
+ param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), (int)type);
status = thread->setParameters(param.toString());
}
@@ -578,7 +602,7 @@
break;
}
AudioParameter param;
- param.addInt(String8(AudioParameter::keyRouting), 0);
+ param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), 0);
ALOGV("releaseAudioPatch() AUDIO_PORT_TYPE_DEVICE setParameters %s",
param.toString().string());
status = thread->setParameters(param.toString());
@@ -605,7 +629,7 @@
status = thread->sendReleaseAudioPatchConfigEvent(mPatches[index]->mHalHandle);
} else {
AudioParameter param;
- param.addInt(String8(AudioParameter::keyRouting), (int)0);
+ param.addInt(String8(AUDIO_PARAMETER_STREAM_ROUTING), 0);
status = thread->setParameters(param.toString());
}
} break;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index c959b9f..2e2f533 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -5297,11 +5297,13 @@
// to keep mRsmpInBuffer full so resampler always has sufficient input
size_t framesInNeeded;
// FIXME only re-calculate when it changes, and optimize for common ratios
- double inOverOut = (double) mSampleRate / activeTrack->mSampleRate;
- double outOverIn = (double) activeTrack->mSampleRate / mSampleRate;
- framesInNeeded = ceil(framesOut * inOverOut) + 1;
+ // Do not precompute in/out because floating point is not associative
+ // e.g. a*b/c != a*(b/c).
+ const double in(mSampleRate);
+ const double out(activeTrack->mSampleRate);
+ framesInNeeded = ceil(framesOut * in / out) + 1;
ALOGV("need %u frames in to produce %u out given in/out ratio of %.4g",
- framesInNeeded, framesOut, inOverOut);
+ framesInNeeded, framesOut, in / out);
// Although we theoretically have framesIn in circular buffer, some of those are
// unreleased frames, and thus must be discounted for purpose of budgeting.
size_t unreleased = activeTrack->mRsmpInUnrel;
@@ -5309,24 +5311,24 @@
if (framesIn < framesInNeeded) {
ALOGV("not enough to resample: have %u frames in but need %u in to "
"produce %u out given in/out ratio of %.4g",
- framesIn, framesInNeeded, framesOut, inOverOut);
- size_t newFramesOut = framesIn > 0 ? floor((framesIn - 1) * outOverIn) : 0;
+ framesIn, framesInNeeded, framesOut, in / out);
+ size_t newFramesOut = framesIn > 0 ? floor((framesIn - 1) * out / in) : 0;
LOG_ALWAYS_FATAL_IF(newFramesOut >= framesOut);
if (newFramesOut == 0) {
break;
}
- framesInNeeded = ceil(newFramesOut * inOverOut) + 1;
+ framesInNeeded = ceil(newFramesOut * in / out) + 1;
ALOGV("now need %u frames in to produce %u out given out/in ratio of %.4g",
- framesInNeeded, newFramesOut, outOverIn);
+ framesInNeeded, newFramesOut, out / in);
LOG_ALWAYS_FATAL_IF(framesIn < framesInNeeded);
ALOGV("success 2: have %u frames in and need %u in to produce %u out "
"given in/out ratio of %.4g",
- framesIn, framesInNeeded, newFramesOut, inOverOut);
+ framesIn, framesInNeeded, newFramesOut, in / out);
framesOut = newFramesOut;
} else {
ALOGV("success 1: have %u in and need %u in to produce %u out "
"given in/out ratio of %.4g",
- framesIn, framesInNeeded, framesOut, inOverOut);
+ framesIn, framesInNeeded, framesOut, in / out);
}
// reallocate mRsmpOutBuffer as needed; we will grow but never shrink
@@ -5647,7 +5649,7 @@
status_t status = NO_ERROR;
if (recordTrack->isExternalTrack()) {
mLock.unlock();
- status = AudioSystem::startInput(mId);
+ status = AudioSystem::startInput(mId, (audio_session_t)recordTrack->sessionId());
mLock.lock();
// FIXME should verify that recordTrack is still in mActiveTracks
if (status != NO_ERROR) {
@@ -5682,7 +5684,7 @@
startError:
if (recordTrack->isExternalTrack()) {
- AudioSystem::stopInput(mId);
+ AudioSystem::stopInput(mId, (audio_session_t)recordTrack->sessionId());
}
recordTrack->clearSyncStartEvent();
// FIXME I wonder why we do not reset the state here?
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index e81697f..48093da 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -2050,7 +2050,7 @@
if (thread != 0) {
RecordThread *recordThread = (RecordThread *)thread.get();
if (recordThread->stop(this) && isExternalTrack()) {
- AudioSystem::stopInput(recordThread->id());
+ AudioSystem::stopInput(recordThread->id(), (audio_session_t)mSessionId);
}
}
}
@@ -2064,9 +2064,9 @@
if (thread != 0) {
if (isExternalTrack()) {
if (mState == ACTIVE || mState == RESUMING) {
- AudioSystem::stopInput(thread->id());
+ AudioSystem::stopInput(thread->id(), (audio_session_t)mSessionId);
}
- AudioSystem::releaseInput(thread->id());
+ AudioSystem::releaseInput(thread->id(), (audio_session_t)mSessionId);
}
Mutex::Autolock _l(thread->mLock);
RecordThread *recordThread = (RecordThread *) thread.get();
diff --git a/services/audioflinger/tests/resampler_tests.cpp b/services/audioflinger/tests/resampler_tests.cpp
index 169ce02..d6217ba 100644
--- a/services/audioflinger/tests/resampler_tests.cpp
+++ b/services/audioflinger/tests/resampler_tests.cpp
@@ -60,7 +60,7 @@
int check = memcmp((const char*)reference + i * outputFrameSize,
(const char*)test + i * outputFrameSize, outputFrameSize);
if (check) {
- ALOGE("Failure at frame %d", i);
+ ALOGE("Failure at frame %zu", i);
ASSERT_EQ(check, 0); /* fails */
}
}
diff --git a/services/audioflinger/tests/test-mixer.cpp b/services/audioflinger/tests/test-mixer.cpp
index 5a00f40..9a4fad6 100644
--- a/services/audioflinger/tests/test-mixer.cpp
+++ b/services/audioflinger/tests/test-mixer.cpp
@@ -62,7 +62,7 @@
info.samplerate = sampleRate;
info.channels = channels;
info.format = SF_FORMAT_WAV | (isBufferFloat ? SF_FORMAT_FLOAT : SF_FORMAT_PCM_16);
- printf("saving file:%s channels:%d samplerate:%d frames:%d\n",
+ printf("saving file:%s channels:%u samplerate:%u frames:%zu\n",
filename, info.channels, info.samplerate, frames);
SNDFILE *sf = sf_open(filename, SFM_WRITE, &info);
if (sf == NULL) {
diff --git a/services/audioflinger/tests/test_utils.h b/services/audioflinger/tests/test_utils.h
index e446216..3d51cdc 100644
--- a/services/audioflinger/tests/test_utils.h
+++ b/services/audioflinger/tests/test_utils.h
@@ -120,7 +120,7 @@
}
if (!mInputIncr.empty()) {
size_t provided = mInputIncr[mNextIdx++];
- ALOGV("getNextBuffer() mValue[%d]=%u not %u",
+ ALOGV("getNextBuffer() mValue[%zu]=%zu not %zu",
mNextIdx-1, provided, buffer->frameCount);
if (provided < buffer->frameCount) {
buffer->frameCount = provided;
@@ -129,8 +129,8 @@
mNextIdx = 0;
}
}
- ALOGV("getNextBuffer() requested %u frames out of %u frames available"
- " and returned %u frames\n",
+ ALOGV("getNextBuffer() requested %zu frames out of %zu frames available"
+ " and returned %zu frames",
requestedFrames, mNumFrames - mNextFrame, buffer->frameCount);
mUnrel = buffer->frameCount;
if (buffer->frameCount > 0) {
@@ -145,14 +145,14 @@
virtual void releaseBuffer(Buffer* buffer)
{
if (buffer->frameCount > mUnrel) {
- ALOGE("releaseBuffer() released %u frames but only %u available "
- "to release\n", buffer->frameCount, mUnrel);
+ ALOGE("releaseBuffer() released %zu frames but only %zu available "
+ "to release", buffer->frameCount, mUnrel);
mNextFrame += mUnrel;
mUnrel = 0;
} else {
- ALOGV("releaseBuffer() released %u frames out of %u frames available "
- "to release\n", buffer->frameCount, mUnrel);
+ ALOGV("releaseBuffer() released %zu frames out of %zu frames available "
+ "to release", buffer->frameCount, mUnrel);
mNextFrame += buffer->frameCount;
mUnrel -= buffer->frameCount;
}
diff --git a/services/audiopolicy/AudioPolicyClientImpl.cpp b/services/audiopolicy/AudioPolicyClientImpl.cpp
index b5af089..c0019d1 100644
--- a/services/audiopolicy/AudioPolicyClientImpl.cpp
+++ b/services/audiopolicy/AudioPolicyClientImpl.cpp
@@ -35,22 +35,20 @@
return af->loadHwModule(name);
}
-audio_io_handle_t AudioPolicyService::AudioPolicyClient::openOutput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
- uint32_t *pLatencyMs,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo)
+status_t AudioPolicyService::AudioPolicyClient::openOutput(audio_module_handle_t module,
+ audio_io_handle_t *output,
+ audio_config_t *config,
+ audio_devices_t *devices,
+ const String8& address,
+ uint32_t *latencyMs,
+ audio_output_flags_t flags)
{
sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
if (af == 0) {
ALOGW("%s: could not get AudioFlinger", __func__);
- return 0;
+ return PERMISSION_DENIED;
}
- return af->openOutput(module, pDevices, pSamplingRate, pFormat, pChannelMask,
- pLatencyMs, flags, offloadInfo);
+ return af->openOutput(module, output, config, devices, address, latencyMs, flags);
}
audio_io_handle_t AudioPolicyService::AudioPolicyClient::openDuplicateOutput(
@@ -97,20 +95,21 @@
return af->restoreOutput(output);
}
-audio_io_handle_t AudioPolicyService::AudioPolicyClient::openInput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
- audio_input_flags_t flags)
+status_t AudioPolicyService::AudioPolicyClient::openInput(audio_module_handle_t module,
+ audio_io_handle_t *input,
+ audio_config_t *config,
+ audio_devices_t *device,
+ const String8& address,
+ audio_source_t source,
+ audio_input_flags_t flags)
{
sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
if (af == 0) {
ALOGW("%s: could not get AudioFlinger", __func__);
- return 0;
+ return PERMISSION_DENIED;
}
- return af->openInput(module, pDevices, pSamplingRate, pFormat, pChannelMask, flags);
+ return af->openInput(module, input, config, device, address, source, flags);
}
status_t AudioPolicyService::AudioPolicyClient::closeInput(audio_io_handle_t input)
@@ -213,4 +212,9 @@
mAudioPolicyService->onAudioPatchListUpdate();
}
+audio_unique_id_t AudioPolicyService::AudioPolicyClient::newAudioUniqueId()
+{
+ return AudioSystem::newAudioUniqueId();
+}
+
}; // namespace android
diff --git a/services/audiopolicy/AudioPolicyClientImplLegacy.cpp b/services/audiopolicy/AudioPolicyClientImplLegacy.cpp
index 97e12cc..9639096 100644
--- a/services/audiopolicy/AudioPolicyClientImplLegacy.cpp
+++ b/services/audiopolicy/AudioPolicyClientImplLegacy.cpp
@@ -62,6 +62,46 @@
return af->loadHwModule(name);
}
+static audio_io_handle_t open_output(audio_module_handle_t module,
+ audio_devices_t *pDevices,
+ uint32_t *pSamplingRate,
+ audio_format_t *pFormat,
+ audio_channel_mask_t *pChannelMask,
+ uint32_t *pLatencyMs,
+ audio_output_flags_t flags,
+ const audio_offload_info_t *offloadInfo)
+{
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == 0) {
+ ALOGW("%s: could not get AudioFlinger", __func__);
+ return AUDIO_IO_HANDLE_NONE;
+ }
+
+ if (pSamplingRate == NULL || pFormat == NULL || pChannelMask == NULL ||
+ pDevices == NULL || pLatencyMs == NULL) {
+ return AUDIO_IO_HANDLE_NONE;
+ }
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = *pSamplingRate;
+ config.format = *pFormat;
+ config.channel_mask = *pChannelMask;
+ if (offloadInfo != NULL) {
+ config.offload_info = *offloadInfo;
+ }
+ audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
+ status_t status = af->openOutput(module, &output, &config, pDevices,
+ String8(""), pLatencyMs, flags);
+ if (status == NO_ERROR) {
+ *pSamplingRate = config.sample_rate;
+ *pFormat = config.format;
+ *pChannelMask = config.channel_mask;
+ if (offloadInfo != NULL) {
+ *offloadInfo = config.offload_info;
+ }
+ }
+ return output;
+}
+
// deprecated: replaced by aps_open_output_on_module()
audio_io_handle_t aps_open_output(void *service __unused,
audio_devices_t *pDevices,
@@ -71,14 +111,8 @@
uint32_t *pLatencyMs,
audio_output_flags_t flags)
{
- sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
- if (af == 0) {
- ALOGW("%s: could not get AudioFlinger", __func__);
- return 0;
- }
-
- return af->openOutput((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask,
- pLatencyMs, flags);
+ return open_output((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask,
+ pLatencyMs, flags, NULL);
}
audio_io_handle_t aps_open_output_on_module(void *service __unused,
@@ -91,12 +125,7 @@
audio_output_flags_t flags,
const audio_offload_info_t *offloadInfo)
{
- sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
- if (af == 0) {
- ALOGW("%s: could not get AudioFlinger", __func__);
- return 0;
- }
- return af->openOutput(module, pDevices, pSamplingRate, pFormat, pChannelMask,
+ return open_output(module, pDevices, pSamplingRate, pFormat, pChannelMask,
pLatencyMs, flags, offloadInfo);
}
@@ -144,6 +173,37 @@
return af->restoreOutput(output);
}
+static audio_io_handle_t open_input(audio_module_handle_t module,
+ audio_devices_t *pDevices,
+ uint32_t *pSamplingRate,
+ audio_format_t *pFormat,
+ audio_channel_mask_t *pChannelMask)
+{
+ sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
+ if (af == 0) {
+ ALOGW("%s: could not get AudioFlinger", __func__);
+ return AUDIO_IO_HANDLE_NONE;
+ }
+
+ if (pSamplingRate == NULL || pFormat == NULL || pChannelMask == NULL || pDevices == NULL) {
+ return AUDIO_IO_HANDLE_NONE;
+ }
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;;
+ config.sample_rate = *pSamplingRate;
+ config.format = *pFormat;
+ config.channel_mask = *pChannelMask;
+ audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
+ status_t status = af->openInput(module, &input, &config, pDevices,
+ String8(""), AUDIO_SOURCE_MIC, AUDIO_INPUT_FLAG_FAST /*FIXME*/);
+ if (status == NO_ERROR) {
+ *pSamplingRate = config.sample_rate;
+ *pFormat = config.format;
+ *pChannelMask = config.channel_mask;
+ }
+ return input;
+}
+
+
// deprecated: replaced by aps_open_input_on_module(), and acoustics parameter is ignored
audio_io_handle_t aps_open_input(void *service __unused,
audio_devices_t *pDevices,
@@ -152,14 +212,7 @@
audio_channel_mask_t *pChannelMask,
audio_in_acoustics_t acoustics __unused)
{
- sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
- if (af == 0) {
- ALOGW("%s: could not get AudioFlinger", __func__);
- return 0;
- }
-
- return af->openInput((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask,
- AUDIO_INPUT_FLAG_FAST /*FIXME*/);
+ return open_input((audio_module_handle_t)0, pDevices, pSamplingRate, pFormat, pChannelMask);
}
audio_io_handle_t aps_open_input_on_module(void *service __unused,
@@ -169,14 +222,7 @@
audio_format_t *pFormat,
audio_channel_mask_t *pChannelMask)
{
- sp<IAudioFlinger> af = AudioSystem::get_audio_flinger();
- if (af == 0) {
- ALOGW("%s: could not get AudioFlinger", __func__);
- return 0;
- }
-
- return af->openInput(module, pDevices, pSamplingRate, pFormat, pChannelMask,
- AUDIO_INPUT_FLAG_FAST /*FIXME*/);
+ return open_input(module, pDevices, pSamplingRate, pFormat, pChannelMask);
}
int aps_close_input(void *service __unused, audio_io_handle_t input)
diff --git a/services/audiopolicy/AudioPolicyInterface.h b/services/audiopolicy/AudioPolicyInterface.h
index d45776b..50ee803 100644
--- a/services/audiopolicy/AudioPolicyInterface.h
+++ b/services/audiopolicy/AudioPolicyInterface.h
@@ -112,14 +112,17 @@
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_in_acoustics_t acoustics,
+ audio_session_t session,
audio_input_flags_t flags) = 0;
// indicates to the audio policy manager that the input starts being used.
- virtual status_t startInput(audio_io_handle_t input) = 0;
+ virtual status_t startInput(audio_io_handle_t input,
+ audio_session_t session) = 0;
// indicates to the audio policy manager that the input stops being used.
- virtual status_t stopInput(audio_io_handle_t input) = 0;
+ virtual status_t stopInput(audio_io_handle_t input,
+ audio_session_t session) = 0;
// releases the input.
- virtual void releaseInput(audio_io_handle_t input) = 0;
+ virtual void releaseInput(audio_io_handle_t input,
+ audio_session_t session) = 0;
//
// volume control functions
@@ -211,14 +214,13 @@
// in case the audio policy manager has no specific requirements for the output being opened.
// When the function returns, the parameter values reflect the actual values used by the audio hardware output stream.
// The audio policy manager can check if the proposed parameters are suitable or not and act accordingly.
- virtual audio_io_handle_t openOutput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
- uint32_t *pLatencyMs,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo = NULL) = 0;
+ virtual status_t openOutput(audio_module_handle_t module,
+ audio_io_handle_t *output,
+ audio_config_t *config,
+ audio_devices_t *devices,
+ const String8& address,
+ uint32_t *latencyMs,
+ audio_output_flags_t flags) = 0;
// creates a special output that is duplicated to the two outputs passed as arguments. The duplication is performed by
// a special mixer thread in the AudioFlinger.
virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2) = 0;
@@ -235,12 +237,13 @@
//
// opens an audio input
- virtual audio_io_handle_t openInput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
- audio_input_flags_t flags) = 0;
+ virtual status_t openInput(audio_module_handle_t module,
+ audio_io_handle_t *input,
+ audio_config_t *config,
+ audio_devices_t *device,
+ const String8& address,
+ audio_source_t source,
+ audio_input_flags_t flags) = 0;
// closes an audio input
virtual status_t closeInput(audio_io_handle_t input) = 0;
//
@@ -287,6 +290,8 @@
virtual void onAudioPortListUpdate() = 0;
virtual void onAudioPatchListUpdate() = 0;
+
+ virtual audio_unique_id_t newAudioUniqueId() = 0;
};
extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface);
diff --git a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
index 4a55bec..75745b3 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImpl.cpp
@@ -232,8 +232,8 @@
Mutex::Autolock _l(mLock);
// the audio_in_acoustics_t parameter is ignored by get_input()
audio_io_handle_t input = mAudioPolicyManager->getInput(inputSource, samplingRate,
- format, channelMask, (audio_in_acoustics_t) 0,
- flags);
+ format, channelMask,
+ (audio_session_t)audioSession, flags);
if (input == 0) {
return input;
@@ -248,33 +248,36 @@
return input;
}
-status_t AudioPolicyService::startInput(audio_io_handle_t input)
+status_t AudioPolicyService::startInput(audio_io_handle_t input,
+ audio_session_t session)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
Mutex::Autolock _l(mLock);
- return mAudioPolicyManager->startInput(input);
+ return mAudioPolicyManager->startInput(input, session);
}
-status_t AudioPolicyService::stopInput(audio_io_handle_t input)
+status_t AudioPolicyService::stopInput(audio_io_handle_t input,
+ audio_session_t session)
{
if (mAudioPolicyManager == NULL) {
return NO_INIT;
}
Mutex::Autolock _l(mLock);
- return mAudioPolicyManager->stopInput(input);
+ return mAudioPolicyManager->stopInput(input, session);
}
-void AudioPolicyService::releaseInput(audio_io_handle_t input)
+void AudioPolicyService::releaseInput(audio_io_handle_t input,
+ audio_session_t session)
{
if (mAudioPolicyManager == NULL) {
return;
}
Mutex::Autolock _l(mLock);
- mAudioPolicyManager->releaseInput(input);
+ mAudioPolicyManager->releaseInput(input, session);
// release audio processors from the input
status_t status = mAudioPolicyEffects->releaseInputEffects(input);
diff --git a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
index 5ef02e5..aa46ace 100644
--- a/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
+++ b/services/audiopolicy/AudioPolicyInterfaceImplLegacy.cpp
@@ -235,7 +235,8 @@
return input;
}
-status_t AudioPolicyService::startInput(audio_io_handle_t input)
+status_t AudioPolicyService::startInput(audio_io_handle_t input,
+ audio_session_t session __unused)
{
if (mpAudioPolicy == NULL) {
return NO_INIT;
@@ -245,7 +246,8 @@
return mpAudioPolicy->start_input(mpAudioPolicy, input);
}
-status_t AudioPolicyService::stopInput(audio_io_handle_t input)
+status_t AudioPolicyService::stopInput(audio_io_handle_t input,
+ audio_session_t session __unused)
{
if (mpAudioPolicy == NULL) {
return NO_INIT;
@@ -255,7 +257,8 @@
return mpAudioPolicy->stop_input(mpAudioPolicy, input);
}
-void AudioPolicyService::releaseInput(audio_io_handle_t input)
+void AudioPolicyService::releaseInput(audio_io_handle_t input,
+ audio_session_t session __unused)
{
if (mpAudioPolicy == NULL) {
return;
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index 603c44b..65d52d0 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -86,6 +86,7 @@
STRING_TO_ENUM(AUDIO_DEVICE_OUT_HDMI_ARC),
STRING_TO_ENUM(AUDIO_DEVICE_OUT_SPDIF),
STRING_TO_ENUM(AUDIO_DEVICE_OUT_FM),
+ STRING_TO_ENUM(AUDIO_DEVICE_OUT_AUX_LINE),
STRING_TO_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
STRING_TO_ENUM(AUDIO_DEVICE_IN_ALL_SCO),
@@ -687,8 +688,9 @@
audio_output_flags_t flags,
const audio_offload_info_t *offloadInfo)
{
- audio_io_handle_t output = 0;
+ audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
uint32_t latency = 0;
+ status_t status;
#ifdef AUDIO_POLICY_TEST
if (mCurOutput != 0) {
@@ -699,21 +701,26 @@
ALOGV("getOutput() opening test output");
sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL);
outputDesc->mDevice = mTestDevice;
- outputDesc->mSamplingRate = mTestSamplingRate;
- outputDesc->mFormat = mTestFormat;
- outputDesc->mChannelMask = mTestChannels;
outputDesc->mLatency = mTestLatencyMs;
outputDesc->mFlags =
(audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0);
outputDesc->mRefCount[stream] = 0;
- mTestOutputs[mCurOutput] = mpClientInterface->openOutput(0, &outputDesc->mDevice,
- &outputDesc->mSamplingRate,
- &outputDesc->mFormat,
- &outputDesc->mChannelMask,
- &outputDesc->mLatency,
- outputDesc->mFlags,
- offloadInfo);
- if (mTestOutputs[mCurOutput]) {
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = mTestSamplingRate;
+ config.channel_mask = mTestChannels;
+ config.format = mTestFormat;
+ config.offload_info = *offloadInfo;
+ status = mpClientInterface->openOutput(0,
+ &mTestOutputs[mCurOutput],
+ &config,
+ &outputDesc->mDevice,
+ String8(""),
+ &outputDesc->mLatency,
+ outputDesc->mFlags);
+ if (status == NO_ERROR) {
+ outputDesc->mSamplingRate = config.sample_rate;
+ outputDesc->mFormat = config.format;
+ outputDesc->mChannelMask = config.channel_mask;
AudioParameter outputCmd = AudioParameter();
outputCmd.addInt(String8("set_id"),mCurOutput);
mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
@@ -771,37 +778,42 @@
}
outputDesc = new AudioOutputDescriptor(profile);
outputDesc->mDevice = device;
- outputDesc->mSamplingRate = samplingRate;
- outputDesc->mFormat = format;
- outputDesc->mChannelMask = channelMask;
outputDesc->mLatency = 0;
outputDesc->mFlags =(audio_output_flags_t) (outputDesc->mFlags | flags);
- outputDesc->mRefCount[stream] = 0;
- outputDesc->mStopTime[stream] = 0;
- outputDesc->mDirectOpenCount = 1;
- output = mpClientInterface->openOutput(profile->mModule->mHandle,
- &outputDesc->mDevice,
- &outputDesc->mSamplingRate,
- &outputDesc->mFormat,
- &outputDesc->mChannelMask,
- &outputDesc->mLatency,
- outputDesc->mFlags,
- offloadInfo);
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = samplingRate;
+ config.channel_mask = channelMask;
+ config.format = format;
+ config.offload_info = *offloadInfo;
+ status = mpClientInterface->openOutput(profile->mModule->mHandle,
+ &output,
+ &config,
+ &outputDesc->mDevice,
+ String8(""),
+ &outputDesc->mLatency,
+ outputDesc->mFlags);
// only accept an output with the requested parameters
- if (output == 0 ||
- (samplingRate != 0 && samplingRate != outputDesc->mSamplingRate) ||
- (format != AUDIO_FORMAT_DEFAULT && format != outputDesc->mFormat) ||
- (channelMask != 0 && channelMask != outputDesc->mChannelMask)) {
+ if (status != NO_ERROR ||
+ (samplingRate != 0 && samplingRate != config.sample_rate) ||
+ (format != AUDIO_FORMAT_DEFAULT && format != config.format) ||
+ (channelMask != 0 && channelMask != config.channel_mask)) {
ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
"format %d %d, channelMask %04x %04x", output, samplingRate,
outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
outputDesc->mChannelMask);
- if (output != 0) {
+ if (output != AUDIO_IO_HANDLE_NONE) {
mpClientInterface->closeOutput(output);
}
- return 0;
+ return AUDIO_IO_HANDLE_NONE;
}
+ outputDesc->mSamplingRate = config.sample_rate;
+ outputDesc->mChannelMask = config.channel_mask;
+ outputDesc->mFormat = config.format;
+ outputDesc->mRefCount[stream] = 0;
+ outputDesc->mStopTime[stream] = 0;
+ outputDesc->mDirectOpenCount = 1;
+
audio_io_handle_t srcOutput = getOutputForEffect();
addOutput(output, outputDesc);
audio_io_handle_t dstOutput = getOutputForEffect();
@@ -1052,18 +1064,18 @@
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_in_acoustics_t acoustics,
+ audio_session_t session,
audio_input_flags_t flags)
{
- ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, acoustics %x, "
+ ALOGV("getInput() inputSource %d, samplingRate %d, format %d, channelMask %x, session %d, "
"flags %#x",
- inputSource, samplingRate, format, channelMask, acoustics, flags);
+ inputSource, samplingRate, format, channelMask, session, flags);
audio_devices_t device = getDeviceForInputSource(inputSource);
if (device == AUDIO_DEVICE_NONE) {
ALOGW("getInput() could not find device for inputSource %d", inputSource);
- return 0;
+ return AUDIO_IO_HANDLE_NONE;
}
// adapt channel selection to input source
@@ -1090,49 +1102,57 @@
ALOGW("getInput() could not find profile for device 0x%X, samplingRate %u, format %#x, "
"channelMask 0x%X, flags %#x",
device, samplingRate, format, channelMask, flags);
- return 0;
+ return AUDIO_IO_HANDLE_NONE;
}
if (profile->mModule->mHandle == 0) {
ALOGE("getInput(): HW module %s not opened", profile->mModule->mName);
- return 0;
+ return AUDIO_IO_HANDLE_NONE;
+ }
+
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = samplingRate;
+ config.channel_mask = channelMask;
+ config.format = format;
+ audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
+ status_t status = mpClientInterface->openInput(profile->mModule->mHandle,
+ &input,
+ &config,
+ &device,
+ String8(""),
+ inputSource,
+ flags);
+
+ // only accept input with the exact requested set of parameters
+ if (status != NO_ERROR ||
+ (samplingRate != config.sample_rate) ||
+ (format != config.format) ||
+ (channelMask != config.channel_mask)) {
+ ALOGW("getInput() failed opening input: samplingRate %d, format %d, channelMask %x",
+ samplingRate, format, channelMask);
+ if (input != AUDIO_IO_HANDLE_NONE) {
+ mpClientInterface->closeInput(input);
+ }
+ return AUDIO_IO_HANDLE_NONE;
}
sp<AudioInputDescriptor> inputDesc = new AudioInputDescriptor(profile);
-
inputDesc->mInputSource = inputSource;
- inputDesc->mDevice = device;
+ inputDesc->mRefCount = 0;
+ inputDesc->mOpenRefCount = 1;
inputDesc->mSamplingRate = samplingRate;
inputDesc->mFormat = format;
inputDesc->mChannelMask = channelMask;
- inputDesc->mRefCount = 0;
- inputDesc->mOpenRefCount = 1;
+ inputDesc->mDevice = device;
+ inputDesc->mSessions.add(session);
- audio_io_handle_t input = mpClientInterface->openInput(profile->mModule->mHandle,
- &inputDesc->mDevice,
- &inputDesc->mSamplingRate,
- &inputDesc->mFormat,
- &inputDesc->mChannelMask,
- flags);
-
- // only accept input with the exact requested set of parameters
- if (input == 0 ||
- (samplingRate != inputDesc->mSamplingRate) ||
- (format != inputDesc->mFormat) ||
- (channelMask != inputDesc->mChannelMask)) {
- ALOGW("getInput() failed opening input: samplingRate %d, format %d, channelMask %x",
- samplingRate, format, channelMask);
- if (input != 0) {
- mpClientInterface->closeInput(input);
- }
- return 0;
- }
addInput(input, inputDesc);
mpClientInterface->onAudioPortListUpdate();
return input;
}
-status_t AudioPolicyManager::startInput(audio_io_handle_t input)
+status_t AudioPolicyManager::startInput(audio_io_handle_t input,
+ audio_session_t session)
{
ALOGV("startInput() input %d", input);
ssize_t index = mInputs.indexOfKey(input);
@@ -1142,6 +1162,12 @@
}
sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
+ index = inputDesc->mSessions.indexOf(session);
+ if (index < 0) {
+ ALOGW("startInput() unknown session %d on input %d", session, input);
+ return BAD_VALUE;
+ }
+
// virtual input devices are compatible with other input devices
if (!isVirtualInputDevice(inputDesc->mDevice)) {
@@ -1154,8 +1180,8 @@
sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) {
ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput);
- stopInput(activeInput);
- releaseInput(activeInput);
+ stopInput(activeInput, activeDesc->mSessions.itemAt(0));
+ releaseInput(activeInput, activeDesc->mSessions.itemAt(0));
} else {
ALOGE("startInput(%d) failed: other input %d already started", input, activeInput);
return INVALID_OPERATION;
@@ -1180,7 +1206,8 @@
return NO_ERROR;
}
-status_t AudioPolicyManager::stopInput(audio_io_handle_t input)
+status_t AudioPolicyManager::stopInput(audio_io_handle_t input,
+ audio_session_t session)
{
ALOGV("stopInput() input %d", input);
ssize_t index = mInputs.indexOfKey(input);
@@ -1190,6 +1217,12 @@
}
sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
+ index = inputDesc->mSessions.indexOf(session);
+ if (index < 0) {
+ ALOGW("stopInput() unknown session %d on input %d", session, input);
+ return BAD_VALUE;
+ }
+
if (inputDesc->mRefCount == 0) {
ALOGW("stopInput() input %d already stopped", input);
return INVALID_OPERATION;
@@ -1209,7 +1242,8 @@
return NO_ERROR;
}
-void AudioPolicyManager::releaseInput(audio_io_handle_t input)
+void AudioPolicyManager::releaseInput(audio_io_handle_t input,
+ audio_session_t session)
{
ALOGV("releaseInput() %d", input);
ssize_t index = mInputs.indexOfKey(input);
@@ -1219,6 +1253,13 @@
}
sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
ALOG_ASSERT(inputDesc != 0);
+
+ index = inputDesc->mSessions.indexOf(session);
+ if (index < 0) {
+ ALOGW("releaseInput() unknown session %d on input %d", session, input);
+ return;
+ }
+ inputDesc->mSessions.remove(session);
if (inputDesc->mOpenRefCount == 0) {
ALOGW("releaseInput() invalid open ref count %d", inputDesc->mOpenRefCount);
return;
@@ -2318,19 +2359,28 @@
sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(outProfile);
outputDesc->mDevice = profileType;
- audio_io_handle_t output = mpClientInterface->openOutput(
- outProfile->mModule->mHandle,
- &outputDesc->mDevice,
- &outputDesc->mSamplingRate,
- &outputDesc->mFormat,
- &outputDesc->mChannelMask,
- &outputDesc->mLatency,
- outputDesc->mFlags);
- if (output == 0) {
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = outputDesc->mSamplingRate;
+ config.channel_mask = outputDesc->mChannelMask;
+ config.format = outputDesc->mFormat;
+ audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
+ status_t status = mpClientInterface->openOutput(outProfile->mModule->mHandle,
+ &output,
+ &config,
+ &outputDesc->mDevice,
+ String8(""),
+ &outputDesc->mLatency,
+ outputDesc->mFlags);
+
+ if (status != NO_ERROR) {
ALOGW("Cannot open output stream for device %08x on hw module %s",
outputDesc->mDevice,
mHwModules[i]->mName);
} else {
+ outputDesc->mSamplingRate = config.sample_rate;
+ outputDesc->mChannelMask = config.channel_mask;
+ outputDesc->mFormat = config.format;
+
for (size_t k = 0; k < outProfile->mSupportedDevices.size(); k++) {
audio_devices_t type = outProfile->mSupportedDevices[k]->mDeviceType;
ssize_t index =
@@ -2369,15 +2419,21 @@
inputDesc->mInputSource = AUDIO_SOURCE_MIC;
inputDesc->mDevice = profileType;
- audio_io_handle_t input = mpClientInterface->openInput(
- inProfile->mModule->mHandle,
- &inputDesc->mDevice,
- &inputDesc->mSamplingRate,
- &inputDesc->mFormat,
- &inputDesc->mChannelMask,
- AUDIO_INPUT_FLAG_NONE /*FIXME*/);
- if (input != 0) {
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = inputDesc->mSamplingRate;
+ config.channel_mask = inputDesc->mChannelMask;
+ config.format = inputDesc->mFormat;
+ audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
+ status_t status = mpClientInterface->openInput(inProfile->mModule->mHandle,
+ &input,
+ &config,
+ &inputDesc->mDevice,
+ String8(""),
+ AUDIO_SOURCE_MIC,
+ AUDIO_INPUT_FLAG_NONE);
+
+ if (status == NO_ERROR) {
for (size_t k = 0; k < inProfile->mSupportedDevices.size(); k++) {
audio_devices_t type = inProfile->mSupportedDevices[k]->mDeviceType;
ssize_t index =
@@ -2576,17 +2632,25 @@
sp<AudioOutputDescriptor> outputDesc = new AudioOutputDescriptor(NULL);
outputDesc->mDevice = AUDIO_DEVICE_OUT_SPEAKER;
- mPrimaryOutput = mpClientInterface->openOutput(moduleHandle,
- &outputDesc->mDevice,
- &outputDesc->mSamplingRate,
- &outputDesc->mFormat,
- &outputDesc->mChannelMask,
- &outputDesc->mLatency,
- outputDesc->mFlags);
- if (mPrimaryOutput == 0) {
- ALOGE("Failed to reopen hardware output stream, samplingRate: %d, format %d, channels %d",
- outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask);
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = outputDesc->mSamplingRate;
+ config.channel_mask = outputDesc->mChannelMask;
+ config.format = outputDesc->mFormat;
+ status_t status = mpClientInterface->openOutput(moduleHandle,
+ &mPrimaryOutput,
+ &config,
+ &outputDesc->mDevice,
+ String8(""),
+ &outputDesc->mLatency,
+ outputDesc->mFlags);
+ if (status != NO_ERROR) {
+ ALOGE("Failed to reopen hardware output stream, "
+ "samplingRate: %d, format %d, channels %d",
+ outputDesc->mSamplingRate, outputDesc->mFormat, outputDesc->mChannelMask);
} else {
+ outputDesc->mSamplingRate = config.sample_rate;
+ outputDesc->mChannelMask = config.channel_mask;
+ outputDesc->mFormat = config.format;
AudioParameter outputCmd = AudioParameter();
outputCmd.addInt(String8("set_id"), 0);
mpClientInterface->setParameters(mPrimaryOutput, outputCmd.toString());
@@ -2638,16 +2702,6 @@
nextAudioPortGeneration();
}
-String8 AudioPolicyManager::addressToParameter(audio_devices_t device, const String8 address)
-{
- if (device & AUDIO_DEVICE_OUT_ALL_A2DP) {
- return String8("a2dp_sink_address=")+address;
- } else if (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX) {
- return String8("mix=")+address;
- }
- return address;
-}
-
void AudioPolicyManager::findIoHandlesByAddress(sp<AudioOutputDescriptor> desc /*in*/,
const String8 address /*in*/,
SortedVector<audio_io_handle_t>& outputs /*out*/) {
@@ -2740,23 +2794,31 @@
device, address.string(), profile.get());
desc = new AudioOutputDescriptor(profile);
desc->mDevice = device;
- audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
- offloadInfo.sample_rate = desc->mSamplingRate;
- offloadInfo.format = desc->mFormat;
- offloadInfo.channel_mask = desc->mChannelMask;
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = desc->mSamplingRate;
+ config.channel_mask = desc->mChannelMask;
+ config.format = desc->mFormat;
+ config.offload_info.sample_rate = desc->mSamplingRate;
+ config.offload_info.channel_mask = desc->mChannelMask;
+ config.offload_info.format = desc->mFormat;
+ audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
+ status_t status = mpClientInterface->openOutput(profile->mModule->mHandle,
+ &output,
+ &config,
+ &desc->mDevice,
+ address,
+ &desc->mLatency,
+ desc->mFlags);
+ if (status == NO_ERROR) {
+ desc->mSamplingRate = config.sample_rate;
+ desc->mChannelMask = config.channel_mask;
+ desc->mFormat = config.format;
- audio_io_handle_t output = mpClientInterface->openOutput(profile->mModule->mHandle,
- &desc->mDevice,
- &desc->mSamplingRate,
- &desc->mFormat,
- &desc->mChannelMask,
- &desc->mLatency,
- desc->mFlags,
- &offloadInfo);
- if (output != 0) {
// Here is where the out_set_parameters() for card & device gets called
if (!address.isEmpty()) {
- mpClientInterface->setParameters(output, addressToParameter(device, address));
+ char *param = audio_device_address_to_parameter(device, address);
+ mpClientInterface->setParameters(output, String8(param));
+ free(param);
}
// Here is where we step through and resolve any "dynamic" fields
@@ -2800,31 +2862,36 @@
(profile->mChannelMasks.size() < 2))) {
ALOGW("checkOutputsForDevice() missing param");
mpClientInterface->closeOutput(output);
- output = 0;
+ output = AUDIO_IO_HANDLE_NONE;
} else if (profile->mSamplingRates[0] == 0 || profile->mFormats[0] == 0 ||
profile->mChannelMasks[0] == 0) {
mpClientInterface->closeOutput(output);
- desc->mSamplingRate = profile->pickSamplingRate();
- desc->mFormat = profile->pickFormat();
- desc->mChannelMask = profile->pickChannelMask();
- offloadInfo.sample_rate = desc->mSamplingRate;
- offloadInfo.format = desc->mFormat;
- offloadInfo.channel_mask = desc->mChannelMask;
- output = mpClientInterface->openOutput(
- profile->mModule->mHandle,
- &desc->mDevice,
- &desc->mSamplingRate,
- &desc->mFormat,
- &desc->mChannelMask,
- &desc->mLatency,
- desc->mFlags,
- &offloadInfo);
+ config.sample_rate = profile->pickSamplingRate();
+ config.channel_mask = profile->pickChannelMask();
+ config.format = profile->pickFormat();
+ config.offload_info.sample_rate = config.sample_rate;
+ config.offload_info.channel_mask = config.channel_mask;
+ config.offload_info.format = config.format;
+ status = mpClientInterface->openOutput(profile->mModule->mHandle,
+ &output,
+ &config,
+ &desc->mDevice,
+ address,
+ &desc->mLatency,
+ desc->mFlags);
+ if (status == NO_ERROR) {
+ desc->mSamplingRate = config.sample_rate;
+ desc->mChannelMask = config.channel_mask;
+ desc->mFormat = config.format;
+ } else {
+ output = AUDIO_IO_HANDLE_NONE;
+ }
}
- if (output != 0) {
+ if (output != AUDIO_IO_HANDLE_NONE) {
addOutput(output, desc);
if ((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) {
- audio_io_handle_t duplicatedOutput = 0;
+ audio_io_handle_t duplicatedOutput = AUDIO_IO_HANDLE_NONE;
// set initial stream volume for device
applyStreamVolumes(output, device, 0, true);
@@ -2834,9 +2901,10 @@
// open a duplicating output thread for the new output and the primary output
duplicatedOutput = mpClientInterface->openDuplicateOutput(output,
mPrimaryOutput);
- if (duplicatedOutput != 0) {
+ if (duplicatedOutput != AUDIO_IO_HANDLE_NONE) {
// add duplicated output descriptor
- sp<AudioOutputDescriptor> dupOutputDesc = new AudioOutputDescriptor(NULL);
+ sp<AudioOutputDescriptor> dupOutputDesc =
+ new AudioOutputDescriptor(NULL);
dupOutputDesc->mOutput1 = mOutputs.valueFor(mPrimaryOutput);
dupOutputDesc->mOutput2 = mOutputs.valueFor(output);
dupOutputDesc->mSamplingRate = desc->mSamplingRate;
@@ -2851,12 +2919,14 @@
mpClientInterface->closeOutput(output);
mOutputs.removeItem(output);
nextAudioPortGeneration();
- output = 0;
+ output = AUDIO_IO_HANDLE_NONE;
}
}
}
+ } else {
+ output = AUDIO_IO_HANDLE_NONE;
}
- if (output == 0) {
+ if (output == AUDIO_IO_HANDLE_NONE) {
ALOGW("checkOutputsForDevice() could not open output for device %x", device);
profiles.removeAt(profile_index);
profile_index--;
@@ -2985,17 +3055,28 @@
ALOGV("opening input for device 0x%X with params %s", device, address.string());
desc = new AudioInputDescriptor(profile);
desc->mDevice = device;
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = desc->mSamplingRate;
+ config.channel_mask = desc->mChannelMask;
+ config.format = desc->mFormat;
+ audio_io_handle_t input = AUDIO_IO_HANDLE_NONE;
+ status_t status = mpClientInterface->openInput(profile->mModule->mHandle,
+ &input,
+ &config,
+ &desc->mDevice,
+ address,
+ AUDIO_SOURCE_MIC,
+ AUDIO_INPUT_FLAG_NONE /*FIXME*/);
- audio_io_handle_t input = mpClientInterface->openInput(profile->mModule->mHandle,
- &desc->mDevice,
- &desc->mSamplingRate,
- &desc->mFormat,
- &desc->mChannelMask,
- AUDIO_INPUT_FLAG_NONE /*FIXME*/);
+ if (status == NO_ERROR) {
+ desc->mSamplingRate = config.sample_rate;
+ desc->mChannelMask = config.channel_mask;
+ desc->mFormat = config.format;
- if (input != 0) {
if (!address.isEmpty()) {
- mpClientInterface->setParameters(input, addressToParameter(device, address));
+ char *param = audio_device_address_to_parameter(device, address);
+ mpClientInterface->setParameters(input, String8(param));
+ free(param);
}
// Here is where we step through and resolve any "dynamic" fields
@@ -3035,7 +3116,7 @@
((profile->mChannelMasks[0] == 0) && (profile->mChannelMasks.size() < 2))) {
ALOGW("checkInputsForDevice() direct input missing param");
mpClientInterface->closeInput(input);
- input = 0;
+ input = AUDIO_IO_HANDLE_NONE;
}
if (input != 0) {
@@ -3043,7 +3124,7 @@
}
} // endif input != 0
- if (input == 0) {
+ if (input == AUDIO_IO_HANDLE_NONE) {
ALOGW("checkInputsForDevice() could not open input for device 0x%X", device);
profiles.removeAt(profile_index);
profile_index--;
@@ -5495,12 +5576,14 @@
return channelMask;
}
+/* format in order of increasing preference */
const audio_format_t AudioPolicyManager::AudioPort::sPcmFormatCompareTable[] = {
AUDIO_FORMAT_DEFAULT,
AUDIO_FORMAT_PCM_16_BIT,
AUDIO_FORMAT_PCM_8_24_BIT,
AUDIO_FORMAT_PCM_24_BIT_PACKED,
AUDIO_FORMAT_PCM_32_BIT,
+ AUDIO_FORMAT_PCM_FLOAT,
};
int AudioPolicyManager::AudioPort::compareFormats(audio_format_t format1,
@@ -5542,7 +5625,9 @@
}
audio_format_t format = AUDIO_FORMAT_DEFAULT;
- audio_format_t bestFormat = BEST_MIXER_FORMAT;
+ audio_format_t bestFormat =
+ AudioPolicyManager::AudioPort::sPcmFormatCompareTable[
+ ARRAY_SIZE(AudioPolicyManager::AudioPort::sPcmFormatCompareTable) - 1];
// For mixed output and inputs, use best mixer output format. Do not
// limit format otherwise
if ((mType != AUDIO_PORT_TYPE_MIX) ||
@@ -5622,7 +5707,7 @@
if (i == 0 && strcmp(formatStr, "") == 0) {
snprintf(buffer, SIZE, "Dynamic");
} else {
- snprintf(buffer, SIZE, "%-48s", formatStr);
+ snprintf(buffer, SIZE, "%s", formatStr);
}
result.append(buffer);
result.append(i == (mFormats.size() - 1) ? "" : ", ");
diff --git a/services/audiopolicy/AudioPolicyManager.h b/services/audiopolicy/AudioPolicyManager.h
index 62b3ce5..e28a362 100644
--- a/services/audiopolicy/AudioPolicyManager.h
+++ b/services/audiopolicy/AudioPolicyManager.h
@@ -53,10 +53,7 @@
#define OFFLOAD_DEFAULT_MIN_DURATION_SECS 60
#define MAX_MIXER_SAMPLING_RATE 48000
-#define MAX_MIXER_CHANNEL_COUNT 2
-// See AudioPort::compareFormats()
-#define WORST_MIXER_FORMAT AUDIO_FORMAT_PCM_16_BIT
-#define BEST_MIXER_FORMAT AUDIO_FORMAT_PCM_24_BIT_PACKED
+#define MAX_MIXER_CHANNEL_COUNT 8
// ----------------------------------------------------------------------------
// AudioPolicyManager implements audio policy manager behavior common to all platforms.
@@ -107,15 +104,18 @@
uint32_t samplingRate,
audio_format_t format,
audio_channel_mask_t channelMask,
- audio_in_acoustics_t acoustics,
+ audio_session_t session,
audio_input_flags_t flags);
// indicates to the audio policy manager that the input starts being used.
- virtual status_t startInput(audio_io_handle_t input);
+ virtual status_t startInput(audio_io_handle_t input,
+ audio_session_t session);
// indicates to the audio policy manager that the input stops being used.
- virtual status_t stopInput(audio_io_handle_t input);
- virtual void releaseInput(audio_io_handle_t input);
+ virtual status_t stopInput(audio_io_handle_t input,
+ audio_session_t session);
+ virtual void releaseInput(audio_io_handle_t input,
+ audio_session_t session);
virtual void closeAllInputs();
virtual void initStreamVolume(audio_stream_type_t stream,
int indexMin,
@@ -485,6 +485,7 @@
uint32_t mOpenRefCount;
audio_source_t mInputSource; // input source selected by application (mediarecorder.h)
const sp<IOProfile> mProfile; // I/O profile this output derives from
+ SortedVector<audio_session_t> mSessions; // audio sessions attached to this input
virtual void toAudioPortConfig(struct audio_port_config *dstConfig,
const struct audio_port_config *srcConfig = NULL) const;
@@ -802,8 +803,6 @@
uint32_t nextUniqueId();
uint32_t nextAudioPortGeneration();
uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; }
- // converts device address to string sent to audio HAL via setParameters
- static String8 addressToParameter(audio_devices_t device, const String8 address);
// internal method to return the output handle for the given device and format
audio_io_handle_t getOutputForDevice(
audio_devices_t device,
diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h
index 08942ee..97236e3 100644
--- a/services/audiopolicy/AudioPolicyService.h
+++ b/services/audiopolicy/AudioPolicyService.h
@@ -91,9 +91,12 @@
audio_channel_mask_t channelMask,
int audioSession,
audio_input_flags_t flags);
- virtual status_t startInput(audio_io_handle_t input);
- virtual status_t stopInput(audio_io_handle_t input);
- virtual void releaseInput(audio_io_handle_t input);
+ virtual status_t startInput(audio_io_handle_t input,
+ audio_session_t session);
+ virtual status_t stopInput(audio_io_handle_t input,
+ audio_session_t session);
+ virtual void releaseInput(audio_io_handle_t input,
+ audio_session_t session);
virtual status_t initStreamVolume(audio_stream_type_t stream,
int indexMin,
int indexMax);
@@ -361,14 +364,13 @@
// in case the audio policy manager has no specific requirements for the output being opened.
// When the function returns, the parameter values reflect the actual values used by the audio hardware output stream.
// The audio policy manager can check if the proposed parameters are suitable or not and act accordingly.
- virtual audio_io_handle_t openOutput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
- uint32_t *pLatencyMs,
- audio_output_flags_t flags,
- const audio_offload_info_t *offloadInfo = NULL);
+ virtual status_t openOutput(audio_module_handle_t module,
+ audio_io_handle_t *output,
+ audio_config_t *config,
+ audio_devices_t *devices,
+ const String8& address,
+ uint32_t *latencyMs,
+ audio_output_flags_t flags);
// creates a special output that is duplicated to the two outputs passed as arguments. The duplication is performed by
// a special mixer thread in the AudioFlinger.
virtual audio_io_handle_t openDuplicateOutput(audio_io_handle_t output1, audio_io_handle_t output2);
@@ -386,10 +388,11 @@
// opens an audio input
virtual audio_io_handle_t openInput(audio_module_handle_t module,
- audio_devices_t *pDevices,
- uint32_t *pSamplingRate,
- audio_format_t *pFormat,
- audio_channel_mask_t *pChannelMask,
+ audio_io_handle_t *input,
+ audio_config_t *config,
+ audio_devices_t *devices,
+ const String8& address,
+ audio_source_t source,
audio_input_flags_t flags);
// closes an audio input
virtual status_t closeInput(audio_io_handle_t input);
@@ -437,6 +440,8 @@
virtual void onAudioPortListUpdate();
virtual void onAudioPatchListUpdate();
+ virtual audio_unique_id_t newAudioUniqueId();
+
private:
AudioPolicyService *mAudioPolicyService;
};
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 648e82c..7766b90 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -235,7 +235,8 @@
}
struct camera_info info;
- status_t rc = mModule->get_camera_info(cameraId, &info);
+ status_t rc = filterGetInfoErrorCode(
+ mModule->get_camera_info(cameraId, &info));
cameraInfo->facing = info.facing;
cameraInfo->orientation = info.orientation;
return rc;
@@ -367,7 +368,7 @@
* Normal HAL 2.1+ codepath.
*/
struct camera_info info;
- ret = mModule->get_camera_info(cameraId, &info);
+ ret = filterGetInfoErrorCode(mModule->get_camera_info(cameraId, &info));
*cameraInfo = info.static_camera_characteristics;
}
@@ -404,23 +405,28 @@
return deviceVersion;
}
-bool CameraService::isValidCameraId(int cameraId) {
- int facing;
- int deviceVersion = getDeviceVersion(cameraId, &facing);
-
- switch(deviceVersion) {
- case CAMERA_DEVICE_API_VERSION_1_0:
- case CAMERA_DEVICE_API_VERSION_2_0:
- case CAMERA_DEVICE_API_VERSION_2_1:
- case CAMERA_DEVICE_API_VERSION_3_0:
- case CAMERA_DEVICE_API_VERSION_3_1:
- case CAMERA_DEVICE_API_VERSION_3_2:
- return true;
- default:
- return false;
+status_t CameraService::filterOpenErrorCode(status_t err) {
+ switch(err) {
+ case NO_ERROR:
+ case -EBUSY:
+ case -EINVAL:
+ case -EUSERS:
+ return err;
+ default:
+ break;
}
+ return -ENODEV;
+}
- return false;
+status_t CameraService::filterGetInfoErrorCode(status_t err) {
+ switch(err) {
+ case NO_ERROR:
+ case -EINVAL:
+ return err;
+ default:
+ break;
+ }
+ return -ENODEV;
}
bool CameraService::setUpVendorTags() {
@@ -665,14 +671,6 @@
int facing = -1;
int deviceVersion = getDeviceVersion(cameraId, &facing);
- // If there are other non-exclusive users of the camera,
- // this will tear them down before we can reuse the camera
- if (isValidCameraId(cameraId)) {
- // transition from PRESENT -> NOT_AVAILABLE
- updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
- cameraId);
- }
-
if (halVersion < 0 || halVersion == deviceVersion) {
// Default path: HAL version is unspecified by caller, create CameraClient
// based on device version reported by the HAL.
@@ -719,8 +717,6 @@
status_t status = connectFinishUnsafe(client, client->getRemote());
if (status != OK) {
// this is probably not recoverable.. maybe the client can try again
- // OK: we can only get here if we were originally in PRESENT state
- updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
return status;
}
@@ -970,14 +966,6 @@
int facing = -1;
int deviceVersion = getDeviceVersion(cameraId, &facing);
- // If there are other non-exclusive users of the camera,
- // this will tear them down before we can reuse the camera
- if (isValidCameraId(cameraId)) {
- // transition from PRESENT -> NOT_AVAILABLE
- updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
- cameraId);
- }
-
switch(deviceVersion) {
case CAMERA_DEVICE_API_VERSION_1_0:
ALOGW("Camera using old HAL version: %d", deviceVersion);
@@ -1002,8 +990,6 @@
status_t status = connectFinishUnsafe(client, client->getRemote());
if (status != OK) {
// this is probably not recoverable.. maybe the client can try again
- // OK: we can only get here if we were originally in PRESENT state
- updateStatus(ICameraServiceListener::STATUS_PRESENT, cameraId);
return status;
}
@@ -1427,13 +1413,15 @@
void CameraService::BasicClient::disconnect() {
ALOGV("BasicClient::disconnect");
mCameraService->removeClientByRemote(mRemoteBinder);
+
+ finishCameraOps();
// client shouldn't be able to call into us anymore
mClientPid = 0;
}
status_t CameraService::BasicClient::startCameraOps() {
int32_t res;
-
+ // Notify app ops that the camera is not available
mOpsCallback = new OpsCallback(this);
{
@@ -1451,16 +1439,39 @@
mCameraId, String8(mClientPackageName).string());
return PERMISSION_DENIED;
}
+
mOpsActive = true;
+
+ // Transition device availability listeners from PRESENT -> NOT_AVAILABLE
+ mCameraService->updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
+ mCameraId);
+
return OK;
}
status_t CameraService::BasicClient::finishCameraOps() {
+ // Check if startCameraOps succeeded, and if so, finish the camera op
if (mOpsActive) {
+ // Notify app ops that the camera is available again
mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
mClientPackageName);
mOpsActive = false;
+
+ // Notify device availability listeners that this camera is available
+ // again
+
+ StatusVector rejectSourceStates;
+ rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
+ rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
+
+ // Transition to PRESENT if the camera is not in either of above 2
+ // states
+ mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
+ mCameraId,
+ &rejectSourceStates);
+
}
+ // Always stop watching, even if no camera op is active
mAppOpsManager.stopWatchingMode(mOpsCallback);
mOpsCallback.clear();
@@ -1531,15 +1542,6 @@
ALOGV("Client::disconnect");
BasicClient::disconnect();
mCameraService->setCameraFree(mCameraId);
-
- StatusVector rejectSourceStates;
- rejectSourceStates.push_back(ICameraServiceListener::STATUS_NOT_PRESENT);
- rejectSourceStates.push_back(ICameraServiceListener::STATUS_ENUMERATING);
-
- // Transition to PRESENT if the camera is not in either of above 2 states
- mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
- mCameraId,
- &rejectSourceStates);
}
CameraService::Client::OpsCallback::OpsCallback(wp<BasicClient> client):
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 28590eb..cb98c96 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -138,6 +138,10 @@
// CameraDeviceFactory functionality
int getDeviceVersion(int cameraId, int* facing = NULL);
+ /////////////////////////////////////////////////////////////////////
+ // Shared utilities
+ static status_t filterOpenErrorCode(status_t err);
+ static status_t filterGetInfoErrorCode(status_t err);
/////////////////////////////////////////////////////////////////////
// CameraClient functionality
@@ -149,20 +153,19 @@
class BasicClient : public virtual RefBase {
public:
- virtual status_t initialize(camera_module_t *module) = 0;
-
- virtual void disconnect() = 0;
+ virtual status_t initialize(camera_module_t *module) = 0;
+ virtual void disconnect();
// because we can't virtually inherit IInterface, which breaks
// virtual inheritance
virtual sp<IBinder> asBinderWrapper() = 0;
// Return the remote callback binder object (e.g. IProCameraCallbacks)
- sp<IBinder> getRemote() {
+ sp<IBinder> getRemote() {
return mRemoteBinder;
}
- virtual status_t dump(int fd, const Vector<String16>& args) = 0;
+ virtual status_t dump(int fd, const Vector<String16>& args) = 0;
protected:
BasicClient(const sp<CameraService>& cameraService,
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 13c9f48..24d173c 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -112,8 +112,6 @@
TClientBase::mDestructionStarted = true;
- TClientBase::finishCameraOps();
-
disconnect();
ALOGI("Closed Camera %d", TClientBase::mCameraId);
diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
index 2746f6f..6386838 100644
--- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h
@@ -105,8 +105,8 @@
CAMERA_DEVICE_API_VERSION_1_0,
(hw_device_t **)&mDevice);
} else {
- rc = module->methods->open(module, mName.string(),
- (hw_device_t **)&mDevice);
+ rc = CameraService::filterOpenErrorCode(module->methods->open(
+ module, mName.string(), (hw_device_t **)&mDevice));
}
if (rc != OK) {
ALOGE("Could not open camera %s: %d", mName.string(), rc);
diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp
index 89c6b10..8c2520e 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.cpp
+++ b/services/camera/libcameraservice/device2/Camera2Device.cpp
@@ -30,6 +30,7 @@
#include <utils/Trace.h>
#include <utils/Timers.h>
#include "Camera2Device.h"
+#include "CameraService.h"
namespace android {
@@ -67,8 +68,8 @@
camera2_device_t *device;
- res = module->common.methods->open(&module->common, name,
- reinterpret_cast<hw_device_t**>(&device));
+ res = CameraService::filterOpenErrorCode(module->common.methods->open(
+ &module->common, name, reinterpret_cast<hw_device_t**>(&device)));
if (res != OK) {
ALOGE("%s: Could not open camera %d: %s (%d)", __FUNCTION__,
@@ -1087,25 +1088,33 @@
}
if (mFormat == HAL_PIXEL_FORMAT_BLOB) {
- res = native_window_set_buffers_geometry(mConsumerInterface.get(),
- mSize, 1, mFormat);
+ res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
+ mSize, 1);
if (res != OK) {
- ALOGE("%s: Unable to configure compressed stream buffer geometry"
+ ALOGE("%s: Unable to configure compressed stream buffer dimensions"
" %d x %d, size %zu for stream %d",
__FUNCTION__, mWidth, mHeight, mSize, mId);
return res;
}
} else {
- res = native_window_set_buffers_geometry(mConsumerInterface.get(),
- mWidth, mHeight, mFormat);
+ res = native_window_set_buffers_dimensions(mConsumerInterface.get(),
+ mWidth, mHeight);
if (res != OK) {
- ALOGE("%s: Unable to configure stream buffer geometry"
- " %d x %d, format 0x%x for stream %d",
- __FUNCTION__, mWidth, mHeight, mFormat, mId);
+ ALOGE("%s: Unable to configure stream buffer dimensions"
+ " %d x %d for stream %d",
+ __FUNCTION__, mWidth, mHeight, mId);
return res;
}
}
+ res = native_window_set_buffers_format(mConsumerInterface.get(), mFormat);
+ if (res != OK) {
+ ALOGE("%s: Unable to configure stream buffer format"
+ " %#x for stream %d",
+ __FUNCTION__, mFormat, mId);
+ return res;
+ }
+
int maxConsumerBuffers;
res = mConsumerInterface->query(mConsumerInterface.get(),
NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &maxConsumerBuffers);
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 44e8822..a6214cc 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -48,6 +48,7 @@
#include "device3/Camera3OutputStream.h"
#include "device3/Camera3InputStream.h"
#include "device3/Camera3ZslStream.h"
+#include "CameraService.h"
using namespace android::camera3;
@@ -104,8 +105,9 @@
camera3_device_t *device;
ATRACE_BEGIN("camera3->open");
- res = module->common.methods->open(&module->common, deviceName.string(),
- reinterpret_cast<hw_device_t**>(&device));
+ res = CameraService::filterOpenErrorCode(module->common.methods->open(
+ &module->common, deviceName.string(),
+ reinterpret_cast<hw_device_t**>(&device)));
ATRACE_END();
if (res != OK) {
@@ -124,7 +126,8 @@
}
camera_info info;
- res = module->get_camera_info(mId, &info);
+ res = CameraService::filterGetInfoErrorCode(module->get_camera_info(
+ mId, &info));
if (res != OK) return res;
if (info.device_version != device->common.version) {
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 7ec649b..169eb82 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -289,20 +289,25 @@
if (mMaxSize == 0) {
// For buffers of known size
- res = native_window_set_buffers_geometry(mConsumer.get(),
- camera3_stream::width, camera3_stream::height,
- camera3_stream::format);
+ res = native_window_set_buffers_dimensions(mConsumer.get(),
+ camera3_stream::width, camera3_stream::height);
} else {
// For buffers with bounded size
- res = native_window_set_buffers_geometry(mConsumer.get(),
- mMaxSize, 1,
- camera3_stream::format);
+ res = native_window_set_buffers_dimensions(mConsumer.get(),
+ mMaxSize, 1);
}
if (res != OK) {
- ALOGE("%s: Unable to configure stream buffer geometry"
- " %d x %d, format %x for stream %d",
+ ALOGE("%s: Unable to configure stream buffer dimensions"
+ " %d x %d (maxSize %zu) for stream %d",
__FUNCTION__, camera3_stream::width, camera3_stream::height,
- camera3_stream::format, mId);
+ mMaxSize, mId);
+ return res;
+ }
+ res = native_window_set_buffers_format(mConsumer.get(),
+ camera3_stream::format);
+ if (res != OK) {
+ ALOGE("%s: Unable to configure stream buffer format %#x for stream %d",
+ __FUNCTION__, camera3_stream::format, mId);
return res;
}