Merge "Add AudioRouting interface in AudioRecorder."
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 26a320c..2432cac 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -89,7 +89,8 @@
audio_input_flags_t flags,
uid_t uid,
pid_t pid,
- const audio_attributes_t* pAttributes)
+ const audio_attributes_t* pAttributes,
+ audio_port_handle_t selectedDeviceId)
: mActive(false),
mStatus(NO_INIT),
mOpPackageName(opPackageName),
@@ -97,12 +98,11 @@
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
mPreviousSchedulingGroup(SP_DEFAULT),
mProxy(NULL),
- mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
mPortId(AUDIO_PORT_HANDLE_NONE)
{
mStatus = set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user,
notificationFrames, false /*threadCanCallJava*/, sessionId, transferType, flags,
- uid, pid, pAttributes);
+ uid, pid, pAttributes, selectedDeviceId);
}
AudioRecord::~AudioRecord()
@@ -148,7 +148,8 @@
audio_input_flags_t flags,
uid_t uid,
pid_t pid,
- const audio_attributes_t* pAttributes)
+ const audio_attributes_t* pAttributes,
+ audio_port_handle_t selectedDeviceId)
{
ALOGV("set(): inputSource %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
"notificationFrames %u, sessionId %d, transferType %d, flags %#x, opPackageName %s "
@@ -156,6 +157,8 @@
inputSource, sampleRate, format, channelMask, frameCount, notificationFrames,
sessionId, transferType, flags, String8(mOpPackageName).string(), uid, pid);
+ mSelectedDeviceId = selectedDeviceId;
+
switch (transferType) {
case TRANSFER_DEFAULT:
if (cbf == NULL || threadCanCallJava) {
@@ -489,6 +492,7 @@
mAudioRecord->stop();
}
android_atomic_or(CBLK_INVALID, &mCblk->mFlags);
+ mProxy->interrupt();
}
}
return NO_ERROR;
diff --git a/media/libaudioclient/include/media/AudioRecord.h b/media/libaudioclient/include/media/AudioRecord.h
index c6ad1b5..51596a2 100644
--- a/media/libaudioclient/include/media/AudioRecord.h
+++ b/media/libaudioclient/include/media/AudioRecord.h
@@ -185,7 +185,8 @@
audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE,
uid_t uid = AUDIO_UID_INVALID,
pid_t pid = -1,
- const audio_attributes_t* pAttributes = NULL);
+ const audio_attributes_t* pAttributes = NULL,
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
/* Terminates the AudioRecord and unregisters it from AudioFlinger.
* Also destroys all resources associated with the AudioRecord.
@@ -223,7 +224,8 @@
audio_input_flags_t flags = AUDIO_INPUT_FLAG_NONE,
uid_t uid = AUDIO_UID_INVALID,
pid_t pid = -1,
- const audio_attributes_t* pAttributes = NULL);
+ const audio_attributes_t* pAttributes = NULL,
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
/* Result of constructing the AudioRecord. This must be checked for successful initialization
* before using any AudioRecord API (except for set()), because using
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index 5282352..72f5f58 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -61,6 +61,9 @@
PAUSE,
RESUME,
GET_METRICS,
+ SET_INPUT_DEVICE,
+ GET_ROUTED_DEVICE_ID,
+ ENABLE_AUDIO_DEVICE_CALLBACK,
};
@@ -337,6 +340,57 @@
remote()->transact(RELEASE, data, &reply);
return reply.readInt32();
}
+
+ status_t setInputDevice(audio_port_handle_t deviceId)
+ {
+ ALOGV("setInputDevice");
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
+ data.writeInt32(deviceId);
+
+ status_t status = remote()->transact(SET_INPUT_DEVICE, data, &reply);
+ if (status != OK) {
+ ALOGE("setInputDevice binder call failed: %d", status);
+ return status;
+ }
+ return reply.readInt32();;
+ }
+
+ audio_port_handle_t getRoutedDeviceId(audio_port_handle_t *deviceId)
+ {
+ ALOGV("getRoutedDeviceId");
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
+
+ status_t status = remote()->transact(GET_ROUTED_DEVICE_ID, data, &reply);
+ if (status != OK) {
+ ALOGE("getRoutedDeviceid binder call failed: %d", status);
+ *deviceId = AUDIO_PORT_HANDLE_NONE;
+ return status;
+ }
+
+ status = reply.readInt32();
+ if (status != NO_ERROR) {
+ *deviceId = AUDIO_PORT_HANDLE_NONE;
+ } else {
+ *deviceId = reply.readInt32();
+ }
+ return status;
+ }
+
+ status_t enableAudioDeviceCallback(bool enabled)
+ {
+ ALOGV("enableAudioDeviceCallback");
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
+ data.writeBool(enabled);
+ status_t status = remote()->transact(ENABLE_AUDIO_DEVICE_CALLBACK, data, &reply);
+ if (status != OK) {
+ ALOGE("enableAudioDeviceCallback binder call failed: %d, %d", enabled, status);
+ return status;
+ }
+ return reply.readInt32();
+ }
};
IMPLEMENT_META_INTERFACE(MediaRecorder, "android.media.IMediaRecorder");
@@ -543,6 +597,41 @@
}
return NO_ERROR;
} break;
+ case SET_INPUT_DEVICE: {
+ ALOGV("SET_INPUT_DEVICE");
+ CHECK_INTERFACE(IMediaRecorder, data, reply);
+ audio_port_handle_t deviceId;
+ status_t status = data.readInt32(&deviceId);
+ if (status == NO_ERROR) {
+ reply->writeInt32(setInputDevice(deviceId));
+ } else {
+ reply->writeInt32(BAD_VALUE);
+ }
+ return NO_ERROR;
+ } break;
+ case GET_ROUTED_DEVICE_ID: {
+ ALOGV("GET_ROUTED_DEVICE_ID");
+ CHECK_INTERFACE(IMediaRecorder, data, reply);
+ audio_port_handle_t deviceId;
+ status_t status = getRoutedDeviceId(&deviceId);
+ reply->writeInt32(status);
+ if (status == NO_ERROR) {
+ reply->writeInt32(deviceId);
+ }
+ return NO_ERROR;
+ } break;
+ case ENABLE_AUDIO_DEVICE_CALLBACK: {
+ ALOGV("ENABLE_AUDIO_DEVICE_CALLBACK");
+ CHECK_INTERFACE(IMediaRecorder, data, reply);
+ bool enabled;
+ status_t status = data.readBool(&enabled);
+ if (status == NO_ERROR) {
+ reply->writeInt32(enableAudioDeviceCallback(enabled));
+ } else {
+ reply->writeInt32(BAD_VALUE);
+ }
+ return NO_ERROR;
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/media/libmedia/include/media/IMediaRecorder.h b/media/libmedia/include/media/IMediaRecorder.h
index 9d0341a..3cef329 100644
--- a/media/libmedia/include/media/IMediaRecorder.h
+++ b/media/libmedia/include/media/IMediaRecorder.h
@@ -19,6 +19,7 @@
#define ANDROID_IMEDIARECORDER_H
#include <binder/IInterface.h>
+#include <system/audio.h>
namespace android {
@@ -64,6 +65,10 @@
virtual status_t release() = 0;
virtual status_t setInputSurface(const sp<PersistentSurface>& surface) = 0;
virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() = 0;
+
+ virtual status_t setInputDevice(audio_port_handle_t deviceId) = 0;
+ virtual status_t getRoutedDeviceId(audio_port_handle_t *deviceId) = 0;
+ virtual status_t enableAudioDeviceCallback(bool enabled) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/media/libmedia/include/media/MediaRecorderBase.h b/media/libmedia/include/media/MediaRecorderBase.h
index 40dd9f9..748153c 100644
--- a/media/libmedia/include/media/MediaRecorderBase.h
+++ b/media/libmedia/include/media/MediaRecorderBase.h
@@ -18,6 +18,7 @@
#define MEDIA_RECORDER_BASE_H_
+#include <media/AudioSystem.h>
#include <media/mediarecorder.h>
#include <system/audio.h>
@@ -62,6 +63,10 @@
virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
virtual status_t setInputSurface(const sp<PersistentSurface>& surface) = 0;
virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() const = 0;
+ virtual status_t setInputDevice(audio_port_handle_t deviceId) = 0;
+ virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId) = 0;
+ virtual void setAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback) = 0;
+ virtual status_t enableAudioDeviceCallback(bool enabled) = 0;
protected:
diff --git a/media/libmedia/include/media/mediarecorder.h b/media/libmedia/include/media/mediarecorder.h
index b9717ea..5f2a6fe 100644
--- a/media/libmedia/include/media/mediarecorder.h
+++ b/media/libmedia/include/media/mediarecorder.h
@@ -141,6 +141,8 @@
MEDIA_RECORDER_TRACK_EVENT_ERROR = 100,
MEDIA_RECORDER_TRACK_EVENT_INFO = 101,
MEDIA_RECORDER_TRACK_EVENT_LIST_END = 1000,
+
+ MEDIA_RECORDER_AUDIO_ROUTING_CHANGED = 10000,
};
/*
@@ -253,6 +255,9 @@
status_t setInputSurface(const sp<PersistentSurface>& surface);
sp<IGraphicBufferProducer> querySurfaceMediaSourceFromMediaServer();
status_t getMetrics(Parcel *reply);
+ status_t setInputDevice(audio_port_handle_t deviceId);
+ status_t getRoutedDeviceId(audio_port_handle_t *deviceId);
+ status_t enableAudioDeviceCallback(bool enabled);
private:
void doCleanUp();
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 4405930..aab845b 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -792,4 +792,41 @@
notify(MEDIA_RECORDER_EVENT_ERROR, MEDIA_ERROR_SERVER_DIED, 0);
}
+status_t MediaRecorder::setInputDevice(audio_port_handle_t deviceId)
+{
+ ALOGV("setInputDevice");
+
+ if (mMediaRecorder == NULL) {
+ ALOGE("media recorder is not initialized yet");
+ return INVALID_OPERATION;
+ }
+ return mMediaRecorder->setInputDevice(deviceId);
+}
+
+status_t MediaRecorder::getRoutedDeviceId(audio_port_handle_t* deviceId)
+{
+ ALOGV("getRoutedDeviceId");
+
+ if (mMediaRecorder == NULL) {
+ ALOGE("media recorder is not initialized yet");
+ return INVALID_OPERATION;
+ }
+ status_t status = mMediaRecorder->getRoutedDeviceId(deviceId);
+ if (status != NO_ERROR) {
+ *deviceId = AUDIO_PORT_HANDLE_NONE;
+ }
+ return status;
+}
+
+status_t MediaRecorder::enableAudioDeviceCallback(bool enabled)
+{
+ ALOGV("enableAudioDeviceCallback");
+
+ if (mMediaRecorder == NULL) {
+ ALOGE("media recorder is not initialized yet");
+ return INVALID_OPERATION;
+ }
+ return mMediaRecorder->enableAudioDeviceCallback(enabled);
+}
+
} // namespace android
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index a423fee..dcd393b 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -411,6 +411,25 @@
}
}
+MediaRecorderClient::AudioDeviceUpdatedNotifier::AudioDeviceUpdatedNotifier(
+ const sp<IMediaRecorderClient>& listener) {
+ mListener = listener;
+}
+
+MediaRecorderClient::AudioDeviceUpdatedNotifier::~AudioDeviceUpdatedNotifier() {
+}
+
+void MediaRecorderClient::AudioDeviceUpdatedNotifier::onAudioDeviceUpdate(
+ audio_io_handle_t audioIo,
+ audio_port_handle_t deviceId) {
+ sp<IMediaRecorderClient> listener = mListener.promote();
+ if (listener != NULL) {
+ listener->notify(MEDIA_RECORDER_AUDIO_ROUTING_CHANGED, audioIo, deviceId);
+ } else {
+ ALOGW("listener for process %d death is gone", MEDIA_RECORDER_AUDIO_ROUTING_CHANGED);
+ }
+}
+
void MediaRecorderClient::clearDeathNotifiers_l() {
if (mCameraDeathListener != nullptr) {
mCameraDeathListener->unlinkToDeath();
@@ -459,6 +478,9 @@
MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
omx->linkToDeath(mCodecDeathListener, 0);
+ mAudioDeviceUpdatedNotifier = new AudioDeviceUpdatedNotifier(listener);
+ mRecorder->setAudioDeviceCallback(mAudioDeviceUpdatedNotifier);
+
return OK;
}
@@ -479,4 +501,30 @@
return OK;
}
+status_t MediaRecorderClient::setInputDevice(audio_port_handle_t deviceId) {
+ ALOGV("setInputDevice(%d)", deviceId);
+ Mutex::Autolock lock(mLock);
+ if (mRecorder != NULL) {
+ return mRecorder->setInputDevice(deviceId);
+ }
+ return NO_INIT;
+}
+
+status_t MediaRecorderClient::getRoutedDeviceId(audio_port_handle_t* deviceId) {
+ ALOGV("getRoutedDeviceId");
+ Mutex::Autolock lock(mLock);
+ if (mRecorder != NULL) {
+ return mRecorder->getRoutedDeviceId(deviceId);
+ }
+ return NO_INIT;
+}
+
+status_t MediaRecorderClient::enableAudioDeviceCallback(bool enabled) {
+ ALOGV("enableDeviceCallback: %d", enabled);
+ Mutex::Autolock lock(mLock);
+ if (mRecorder != NULL) {
+ return mRecorder->enableAudioDeviceCallback(enabled);
+ }
+ return NO_INIT;
+}
}; // namespace android
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index 711db2c..538b461 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -18,6 +18,7 @@
#ifndef ANDROID_MEDIARECORDERCLIENT_H
#define ANDROID_MEDIARECORDERCLIENT_H
+#include <media/AudioSystem.h>
#include <media/IMediaRecorder.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
@@ -58,6 +59,18 @@
wp<IMediaRecorderClient> mListener;
};
+ class AudioDeviceUpdatedNotifier: public AudioSystem::AudioDeviceCallback
+ {
+ public:
+ AudioDeviceUpdatedNotifier(const sp<IMediaRecorderClient>& listener);
+ virtual ~AudioDeviceUpdatedNotifier();
+ virtual void onAudioDeviceUpdate(
+ audio_io_handle_t audioIo,
+ audio_port_handle_t deviceId);
+ private:
+ wp<IMediaRecorderClient> mListener;
+ };
+
void clearDeathNotifiers_l();
public:
@@ -91,6 +104,9 @@
virtual status_t dump(int fd, const Vector<String16>& args);
virtual status_t setInputSurface(const sp<PersistentSurface>& surface);
virtual sp<IGraphicBufferProducer> querySurfaceMediaSource();
+ virtual status_t setInputDevice(audio_port_handle_t deviceId);
+ virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
+ virtual status_t enableAudioDeviceCallback(bool enabled);
private:
friend class MediaPlayerService; // for accessing private constructor
@@ -103,6 +119,7 @@
sp<ServiceDeathNotifier> mCameraDeathListener;
sp<ServiceDeathNotifier> mCodecDeathListener;
+ sp<AudioDeviceUpdatedNotifier> mAudioDeviceUpdatedNotifier;
pid_t mPid;
Mutex mLock;
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 89354d6..77eaefe 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -103,7 +103,9 @@
mOutputFd(-1),
mAudioSource(AUDIO_SOURCE_CNT),
mVideoSource(VIDEO_SOURCE_LIST_END),
- mStarted(false) {
+ mStarted(false),
+ mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE),
+ mDeviceCallbackEnabled(false) {
ALOGV("Constructor");
@@ -204,7 +206,7 @@
return OK;
}
-// The client side of mediaserver asks it to creat a SurfaceMediaSource
+// The client side of mediaserver asks it to create a SurfaceMediaSource
// and return a interface reference. The client side will use that
// while encoding GL Frames
sp<IGraphicBufferProducer> StagefrightRecorder::querySurfaceMediaSource() const {
@@ -1069,7 +1071,8 @@
mAudioChannels,
mSampleRate,
mClientUid,
- mClientPid);
+ mClientPid,
+ mSelectedDeviceId);
status_t err = audioSource->initCheck();
@@ -1120,6 +1123,10 @@
sp<MediaCodecSource> audioEncoder =
MediaCodecSource::Create(mLooper, format, audioSource);
+ sp<AudioSystem::AudioDeviceCallback> callback = mAudioDeviceCallback.promote();
+ if (mDeviceCallbackEnabled && callback != 0) {
+ audioSource->addAudioDeviceCallback(callback);
+ }
mAudioSourceNode = audioSource;
if (audioEncoder == NULL) {
@@ -2116,6 +2123,46 @@
return OK;
}
+status_t StagefrightRecorder::setInputDevice(audio_port_handle_t deviceId) {
+ ALOGV("setInputDevice");
+
+ if (mSelectedDeviceId != deviceId) {
+ mSelectedDeviceId = deviceId;
+ if (mAudioSourceNode != 0) {
+ return mAudioSourceNode->setInputDevice(deviceId);
+ }
+ }
+ return NO_ERROR;
+}
+
+status_t StagefrightRecorder::getRoutedDeviceId(audio_port_handle_t* deviceId) {
+ ALOGV("getRoutedDeviceId");
+
+ if (mAudioSourceNode != 0) {
+ status_t status = mAudioSourceNode->getRoutedDeviceId(deviceId);
+ return status;
+ }
+ return NO_INIT;
+}
+
+void StagefrightRecorder::setAudioDeviceCallback(
+ const sp<AudioSystem::AudioDeviceCallback>& callback) {
+ mAudioDeviceCallback = callback;
+}
+
+status_t StagefrightRecorder::enableAudioDeviceCallback(bool enabled) {
+ mDeviceCallbackEnabled = enabled;
+ sp<AudioSystem::AudioDeviceCallback> callback = mAudioDeviceCallback.promote();
+ if (mAudioSourceNode != 0 && callback != 0) {
+ if (enabled) {
+ return mAudioSourceNode->addAudioDeviceCallback(callback);
+ } else {
+ return mAudioSourceNode->removeAudioDeviceCallback(callback);
+ }
+ }
+ return NO_ERROR;
+}
+
status_t StagefrightRecorder::dump(
int fd, const Vector<String16>& args) const {
ALOGV("dump");
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 5111c8e..ec7e8ed 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -72,6 +72,10 @@
virtual status_t dump(int fd, const Vector<String16> &args) const;
// Querying a SurfaceMediaSourcer
virtual sp<IGraphicBufferProducer> querySurfaceMediaSource() const;
+ virtual status_t setInputDevice(audio_port_handle_t deviceId);
+ virtual status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
+ virtual void setAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback);
+ virtual status_t enableAudioDeviceCallback(bool enabled);
private:
mutable Mutex mLock;
@@ -144,6 +148,10 @@
sp<IGraphicBufferProducer> mGraphicBufferProducer;
sp<ALooper> mLooper;
+ audio_port_handle_t mSelectedDeviceId;
+ bool mDeviceCallbackEnabled;
+ wp<AudioSystem::AudioDeviceCallback> mAudioDeviceCallback;
+
static const int kMaxHighSpeedFps = 1000;
status_t prepareInternal();
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index f2b1f10..b8da980 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -52,7 +52,7 @@
AudioSource::AudioSource(
audio_source_t inputSource, const String16 &opPackageName,
uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate,
- uid_t uid, pid_t pid)
+ uid_t uid, pid_t pid, audio_port_handle_t selectedDeviceId)
: mStarted(false),
mSampleRate(sampleRate),
mOutSampleRate(outSampleRate > 0 ? outSampleRate : sampleRate),
@@ -101,7 +101,9 @@
AudioRecord::TRANSFER_DEFAULT,
AUDIO_INPUT_FLAG_NONE,
uid,
- pid);
+ pid,
+ NULL /*pAttributes*/,
+ selectedDeviceId);
mInitCheck = mRecord->initCheck();
if (mInitCheck != OK) {
mRecord.clear();
@@ -465,4 +467,35 @@
return value;
}
+status_t AudioSource::setInputDevice(audio_port_handle_t deviceId) {
+ if (mRecord != 0) {
+ return mRecord->setInputDevice(deviceId);
+ }
+ return NO_INIT;
+}
+
+status_t AudioSource::getRoutedDeviceId(audio_port_handle_t* deviceId) {
+ if (mRecord != 0) {
+ *deviceId = mRecord->getRoutedDeviceId();
+ return NO_ERROR;
+ }
+ return NO_INIT;
+}
+
+status_t AudioSource::addAudioDeviceCallback(
+ const sp<AudioSystem::AudioDeviceCallback>& callback) {
+ if (mRecord != 0) {
+ return mRecord->addAudioDeviceCallback(callback);
+ }
+ return NO_INIT;
+}
+
+status_t AudioSource::removeAudioDeviceCallback(
+ const sp<AudioSystem::AudioDeviceCallback>& callback) {
+ if (mRecord != 0) {
+ return mRecord->removeAudioDeviceCallback(callback);
+ }
+ return NO_INIT;
+}
+
} // namespace android
diff --git a/media/libstagefright/include/media/stagefright/AudioSource.h b/media/libstagefright/include/media/stagefright/AudioSource.h
index 4984f69..9414aab 100644
--- a/media/libstagefright/include/media/stagefright/AudioSource.h
+++ b/media/libstagefright/include/media/stagefright/AudioSource.h
@@ -40,7 +40,8 @@
uint32_t channels,
uint32_t outSampleRate = 0,
uid_t uid = -1,
- pid_t pid = -1);
+ pid_t pid = -1,
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE);
status_t initCheck() const;
@@ -58,6 +59,11 @@
status_t dataCallback(const AudioRecord::Buffer& buffer);
virtual void signalBufferReturned(MediaBuffer *buffer);
+ status_t setInputDevice(audio_port_handle_t deviceId);
+ status_t getRoutedDeviceId(audio_port_handle_t* deviceId);
+ status_t addAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback);
+ status_t removeAudioDeviceCallback(const sp<AudioSystem::AudioDeviceCallback>& callback);
+
protected:
virtual ~AudioSource();