Merge "Camera3: fix aborting reprocess requests" into mnc-dev
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index e9f0131..54e86b9 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -59,9 +59,11 @@
// voluntary invalidation by mediaserver, or mediaserver crash.
EVENT_STREAM_END = 7, // Sent after all the buffers queued in AF and HW are played
// back (after stop is called)
+#if 0 // FIXME not yet implemented
EVENT_NEW_TIMESTAMP = 8, // Delivered periodically and when there's a significant change
// in the mapping from frame position to presentation time.
// See AudioTimestamp for the information included with event.
+#endif
};
/* Client should declare a Buffer and pass the address to obtainBuffer()
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index f061d22..e02918f 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -58,24 +58,6 @@
CAMCORDER_QUALITY_HIGH_SPEED_LIST_END = 2005,
};
-/**
- * Set CIF as default maximum import and export resolution of video editor.
- * The maximum import and export resolutions are platform specific,
- * which should be defined in media_profiles.xml.
- * Set default maximum prefetch YUV frames to 6, which means video editor can
- * queue up to 6 YUV frames in the video encoder source.
- * This value is used to limit the amount of memory used by video editor
- * engine when the encoder consumes YUV frames at a lower speed
- * than video editor engine produces.
- */
-enum videoeditor_capability {
- VIDEOEDITOR_DEFAULT_MAX_INPUT_FRAME_WIDTH = 352,
- VIDEOEDITOR_DEFUALT_MAX_INPUT_FRAME_HEIGHT = 288,
- VIDEOEDITOR_DEFAULT_MAX_OUTPUT_FRAME_WIDTH = 352,
- VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT = 288,
- VIDEOEDITOR_DEFAULT_MAX_PREFETCH_YUV_FRAMES = 6
-};
-
enum video_decoder {
VIDEO_DECODER_WMV,
};
@@ -148,32 +130,6 @@
int getVideoEncoderParamByName(const char *name, video_encoder codec) const;
/**
- * Returns the value for the given param name for the video editor cap
- * param or -1 if error.
- * Supported param name are:
- * videoeditor.input.width.max - max input video frame width
- * videoeditor.input.height.max - max input video frame height
- * videoeditor.output.width.max - max output video frame width
- * videoeditor.output.height.max - max output video frame height
- * maxPrefetchYUVFrames - max prefetch YUV frames in video editor engine. This value is used
- * to limit the memory consumption.
- */
- int getVideoEditorCapParamByName(const char *name) const;
-
- /**
- * Returns the value for the given param name for the video editor export codec format
- * param or -1 if error.
- * Supported param name are:
- * videoeditor.export.profile - export video profile
- * videoeditor.export.level - export video level
- * Supported param codec are:
- * 1 for h263
- * 2 for h264
- * 3 for mpeg4
- */
- int getVideoEditorExportParamByName(const char *name, int codec) const;
-
- /**
* Returns the audio encoders supported.
*/
Vector<audio_encoder> getAudioEncoders() const;
@@ -221,7 +177,7 @@
MediaProfiles& operator=(const MediaProfiles&); // Don't call me
MediaProfiles(const MediaProfiles&); // Don't call me
- MediaProfiles() { mVideoEditorCap = NULL; } // Dummy default constructor
+ MediaProfiles() {} // Dummy default constructor
~MediaProfiles(); // Don't delete me
struct VideoCodec {
@@ -366,31 +322,6 @@
int mCameraId;
Vector<int> mLevels;
};
- struct ExportVideoProfile {
- ExportVideoProfile(int codec, int profile, int level)
- :mCodec(codec),mProfile(profile),mLevel(level) {}
- ~ExportVideoProfile() {}
- int mCodec;
- int mProfile;
- int mLevel;
- };
- struct VideoEditorCap {
- VideoEditorCap(int inFrameWidth, int inFrameHeight,
- int outFrameWidth, int outFrameHeight, int frames)
- : mMaxInputFrameWidth(inFrameWidth),
- mMaxInputFrameHeight(inFrameHeight),
- mMaxOutputFrameWidth(outFrameWidth),
- mMaxOutputFrameHeight(outFrameHeight),
- mMaxPrefetchYUVFrames(frames) {}
-
- ~VideoEditorCap() {}
-
- int mMaxInputFrameWidth;
- int mMaxInputFrameHeight;
- int mMaxOutputFrameWidth;
- int mMaxOutputFrameHeight;
- int mMaxPrefetchYUVFrames;
- };
int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const;
void initRequiredProfileRefs(const Vector<int>& cameraIds);
@@ -403,7 +334,6 @@
static void logAudioEncoderCap(const AudioEncoderCap& cap);
static void logVideoDecoderCap(const VideoDecoderCap& cap);
static void logAudioDecoderCap(const AudioDecoderCap& cap);
- static void logVideoEditorCap(const VideoEditorCap& cap);
// If the xml configuration file does exist, use the settings
// from the xml
@@ -415,9 +345,6 @@
static VideoDecoderCap* createVideoDecoderCap(const char **atts);
static VideoEncoderCap* createVideoEncoderCap(const char **atts);
static AudioEncoderCap* createAudioEncoderCap(const char **atts);
- static VideoEditorCap* createVideoEditorCap(
- const char **atts, MediaProfiles *profiles);
- static ExportVideoProfile* createExportVideoProfile(const char **atts);
static CamcorderProfile* createCamcorderProfile(
int cameraId, const char **atts, Vector<int>& cameraIds);
@@ -461,8 +388,6 @@
static void createDefaultEncoderOutputFileFormats(MediaProfiles *profiles);
static void createDefaultImageEncodingQualityLevels(MediaProfiles *profiles);
static void createDefaultImageDecodingMaxMemory(MediaProfiles *profiles);
- static void createDefaultVideoEditorCap(MediaProfiles *profiles);
- static void createDefaultExportVideoProfiles(MediaProfiles *profiles);
static VideoEncoderCap* createDefaultH263VideoEncoderCap();
static VideoEncoderCap* createDefaultM4vVideoEncoderCap();
@@ -520,8 +445,6 @@
RequiredProfiles *mRequiredProfileRefs;
Vector<int> mCameraIds;
- VideoEditorCap* mVideoEditorCap;
- Vector<ExportVideoProfile*> mVideoEditorExportProfiles;
};
}; // namespace android
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index ae0061f..c5790fb 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -152,16 +152,6 @@
ALOGV("codec = %d", cap.mCodec);
}
-/*static*/ void
-MediaProfiles::logVideoEditorCap(const MediaProfiles::VideoEditorCap& cap UNUSED)
-{
- ALOGV("videoeditor cap:");
- ALOGV("mMaxInputFrameWidth = %d", cap.mMaxInputFrameWidth);
- ALOGV("mMaxInputFrameHeight = %d", cap.mMaxInputFrameHeight);
- ALOGV("mMaxOutputFrameWidth = %d", cap.mMaxOutputFrameWidth);
- ALOGV("mMaxOutputFrameHeight = %d", cap.mMaxOutputFrameHeight);
-}
-
/*static*/ int
MediaProfiles::findTagForName(const MediaProfiles::NameToTagMap *map, size_t nMappings,
const char *name)
@@ -398,42 +388,6 @@
ALOGV("%s: cameraId=%d, offset=%d ms", __func__, cameraId, offsetTimeMs);
mStartTimeOffsets.replaceValueFor(cameraId, offsetTimeMs);
}
-/*static*/ MediaProfiles::ExportVideoProfile*
-MediaProfiles::createExportVideoProfile(const char **atts)
-{
- CHECK(!strcmp("name", atts[0]) &&
- !strcmp("profile", atts[2]) &&
- !strcmp("level", atts[4]));
-
- const size_t nMappings =
- sizeof(sVideoEncoderNameMap)/sizeof(sVideoEncoderNameMap[0]);
- const int codec = findTagForName(sVideoEncoderNameMap, nMappings, atts[1]);
- CHECK(codec != -1);
-
- MediaProfiles::ExportVideoProfile *profile =
- new MediaProfiles::ExportVideoProfile(
- codec, atoi(atts[3]), atoi(atts[5]));
-
- return profile;
-}
-/*static*/ MediaProfiles::VideoEditorCap*
-MediaProfiles::createVideoEditorCap(const char **atts, MediaProfiles *profiles)
-{
- CHECK(!strcmp("maxInputFrameWidth", atts[0]) &&
- !strcmp("maxInputFrameHeight", atts[2]) &&
- !strcmp("maxOutputFrameWidth", atts[4]) &&
- !strcmp("maxOutputFrameHeight", atts[6]) &&
- !strcmp("maxPrefetchYUVFrames", atts[8]));
-
- MediaProfiles::VideoEditorCap *pVideoEditorCap =
- new MediaProfiles::VideoEditorCap(atoi(atts[1]), atoi(atts[3]),
- atoi(atts[5]), atoi(atts[7]), atoi(atts[9]));
-
- logVideoEditorCap(*pVideoEditorCap);
- profiles->mVideoEditorCap = pVideoEditorCap;
-
- return pVideoEditorCap;
-}
/*static*/ void
MediaProfiles::startElementHandler(void *userData, const char *name, const char **atts)
@@ -465,10 +419,6 @@
createCamcorderProfile(profiles->mCurrentCameraId, atts, profiles->mCameraIds));
} else if (strcmp("ImageEncoding", name) == 0) {
profiles->addImageEncodingQualityLevel(profiles->mCurrentCameraId, atts);
- } else if (strcmp("VideoEditorCap", name) == 0) {
- createVideoEditorCap(atts, profiles);
- } else if (strcmp("ExportVideoProfile", name) == 0) {
- profiles->mVideoEditorExportProfiles.add(createExportVideoProfile(atts));
}
}
@@ -873,32 +823,6 @@
profiles->mImageEncodingQualityLevels.add(levels);
}
-/*static*/ void
-MediaProfiles::createDefaultVideoEditorCap(MediaProfiles *profiles)
-{
- profiles->mVideoEditorCap =
- new MediaProfiles::VideoEditorCap(
- VIDEOEDITOR_DEFAULT_MAX_INPUT_FRAME_WIDTH,
- VIDEOEDITOR_DEFUALT_MAX_INPUT_FRAME_HEIGHT,
- VIDEOEDITOR_DEFAULT_MAX_OUTPUT_FRAME_WIDTH,
- VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT,
- VIDEOEDITOR_DEFAULT_MAX_PREFETCH_YUV_FRAMES);
-}
-/*static*/ void
-MediaProfiles::createDefaultExportVideoProfiles(MediaProfiles *profiles)
-{
- // Create default video export profiles
- profiles->mVideoEditorExportProfiles.add(
- new ExportVideoProfile(VIDEO_ENCODER_H263,
- OMX_VIDEO_H263ProfileBaseline, OMX_VIDEO_H263Level10));
- profiles->mVideoEditorExportProfiles.add(
- new ExportVideoProfile(VIDEO_ENCODER_MPEG_4_SP,
- OMX_VIDEO_MPEG4ProfileSimple, OMX_VIDEO_MPEG4Level1));
- profiles->mVideoEditorExportProfiles.add(
- new ExportVideoProfile(VIDEO_ENCODER_H264,
- OMX_VIDEO_AVCProfileBaseline, OMX_VIDEO_AVCLevel13));
-}
-
/*static*/ MediaProfiles*
MediaProfiles::createDefaultInstance()
{
@@ -910,8 +834,6 @@
createDefaultAudioDecoders(profiles);
createDefaultEncoderOutputFileFormats(profiles);
createDefaultImageEncodingQualityLevels(profiles);
- createDefaultVideoEditorCap(profiles);
- createDefaultExportVideoProfiles(profiles);
return profiles;
}
@@ -1009,54 +931,6 @@
ALOGE("The given video encoder param name %s is not found", name);
return -1;
}
-int MediaProfiles::getVideoEditorExportParamByName(
- const char *name, int codec) const
-{
- ALOGV("getVideoEditorExportParamByName: name %s codec %d", name, codec);
- ExportVideoProfile *exportProfile = NULL;
- int index = -1;
- for (size_t i =0; i < mVideoEditorExportProfiles.size(); i++) {
- exportProfile = mVideoEditorExportProfiles[i];
- if (exportProfile->mCodec == codec) {
- index = i;
- break;
- }
- }
- if (index == -1) {
- ALOGE("The given video decoder %d is not found", codec);
- return -1;
- }
- if (!strcmp("videoeditor.export.profile", name))
- return exportProfile->mProfile;
- if (!strcmp("videoeditor.export.level", name))
- return exportProfile->mLevel;
-
- ALOGE("The given video editor export param name %s is not found", name);
- return -1;
-}
-int MediaProfiles::getVideoEditorCapParamByName(const char *name) const
-{
- ALOGV("getVideoEditorCapParamByName: %s", name);
-
- if (mVideoEditorCap == NULL) {
- ALOGE("The mVideoEditorCap is not created, then create default cap.");
- createDefaultVideoEditorCap(sInstance);
- }
-
- if (!strcmp("videoeditor.input.width.max", name))
- return mVideoEditorCap->mMaxInputFrameWidth;
- if (!strcmp("videoeditor.input.height.max", name))
- return mVideoEditorCap->mMaxInputFrameHeight;
- if (!strcmp("videoeditor.output.width.max", name))
- return mVideoEditorCap->mMaxOutputFrameWidth;
- if (!strcmp("videoeditor.output.height.max", name))
- return mVideoEditorCap->mMaxOutputFrameHeight;
- if (!strcmp("maxPrefetchYUVFrames", name))
- return mVideoEditorCap->mMaxPrefetchYUVFrames;
-
- ALOGE("The given video editor param name %s is not found", name);
- return -1;
-}
Vector<audio_encoder> MediaProfiles::getAudioEncoders() const
{
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 9c0af4a..258dc13 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1884,6 +1884,15 @@
me->mCallbackCookie, CB_EVENT_TEAR_DOWN);
break;
+ case AudioTrack::EVENT_UNDERRUN:
+ // This occurs when there is no data available, typically occurring
+ // when there is a failure to supply data to the AudioTrack. It can also
+ // occur in non-offloaded mode when the audio device comes out of standby.
+ //
+ // If you see this at the start of playback, there probably was a glitch.
+ ALOGI("callbackwrapper: EVENT_UNDERRUN (discarded)");
+ break;
+
default:
ALOGE("received unknown event type: %d inside CallbackWrapper !", event);
}
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index 6708828..f366b1f 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -73,10 +73,24 @@
if (gCodecList->initCheck() == OK) {
sCodecList = gCodecList;
- struct stat s;
- if (stat(kProfilingResults, &s) == -1) {
+ FILE *resultsFile = fopen(kProfilingResults, "r");
+ if (resultsFile) {
+ AString currentVersion = getProfilingVersionString();
+ size_t currentVersionSize = currentVersion.size();
+ char *versionString = new char[currentVersionSize];
+ fgets(versionString, currentVersionSize, resultsFile);
+ if (strncmp(versionString, currentVersion.c_str(), currentVersionSize) != 0) {
+ // profiling result out of date
+ profilingNeeded = true;
+ }
+ fclose(resultsFile);
+ delete[] versionString;
+ } else {
// profiling results doesn't existed
profilingNeeded = true;
+ }
+
+ if (profilingNeeded) {
for (size_t i = 0; i < gCodecList->countCodecs(); ++i) {
infos.push_back(gCodecList->getCodecInfo(i));
}
diff --git a/media/libstagefright/MediaCodecListOverrides.cpp b/media/libstagefright/MediaCodecListOverrides.cpp
index 006454d..a928163 100644
--- a/media/libstagefright/MediaCodecListOverrides.cpp
+++ b/media/libstagefright/MediaCodecListOverrides.cpp
@@ -20,6 +20,7 @@
#include "MediaCodecListOverrides.h"
+#include <cutils/properties.h>
#include <gui/Surface.h>
#include <media/ICrypto.h>
#include <media/IMediaCodecList.h>
@@ -34,6 +35,15 @@
const char *kProfilingResults = "/data/misc/media/media_codecs_profiling_results.xml";
+AString getProfilingVersionString() {
+ char val[PROPERTY_VALUE_MAX];
+ if (property_get("ro.build.display.id", val, NULL) && (strlen(val) > 0)) {
+ return AStringPrintf("<!-- Profiled-with: %s -->", val);
+ }
+
+ return "<!-- Profiled-with: UNKNOWN_BUILD_ID -->";
+}
+
// a limit to avoid allocating unreasonable number of codec instances in the measurement.
// this should be in sync with the MAX_SUPPORTED_INSTANCES defined in MediaCodecInfo.java.
static const int kMaxInstances = 32;
@@ -375,6 +385,8 @@
}
AString overrides;
+ overrides.append(getProfilingVersionString());
+ overrides.append("\n");
overrides.append("<MediaCodecs>\n");
if (global_results.size() > 0) {
overrides.append(" <Settings>\n");
diff --git a/media/libstagefright/MediaCodecListOverrides.h b/media/libstagefright/MediaCodecListOverrides.h
index e350d2a..d4bb225 100644
--- a/media/libstagefright/MediaCodecListOverrides.h
+++ b/media/libstagefright/MediaCodecListOverrides.h
@@ -26,10 +26,13 @@
namespace android {
+extern const char *kProfilingVersionString;
extern const char *kProfilingResults;
struct MediaCodecInfo;
+AString getProfilingVersionString();
+
bool splitString(const AString &s, const AString &delimiter, AString *s1, AString *s2);
// profile codecs and save the result to xml file named kProfilingResults.
diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
index d1b0f76..a9723ea 100644
--- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
@@ -428,7 +428,15 @@
}
}
-void SoftAMR::onPortFlushCompleted(OMX_U32 /* portIndex */) {
+void SoftAMR::onPortFlushCompleted(OMX_U32 portIndex) {
+ ALOGV("onPortFlushCompleted portindex %d, resetting frame ", portIndex);
+ if (portIndex == 0) {
+ if (mMode == MODE_NARROW) {
+ Speech_Decode_Frame_reset(mState);
+ } else {
+ pvDecoder_AmrWb_Reset(mState, 0 /* reset_all */);
+ }
+ }
}
void SoftAMR::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index e0ee87b..aae3e9f 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -194,18 +194,19 @@
ATSParser::VIDEO).get()
: (AnotherPacketSource *)mParser->getSource(
ATSParser::AUDIO).get();
- int64_t prevBufferedDurationUs = 0;
+ size_t prevSyncSize = 1;
int64_t durationUs = -1;
List<int64_t> durations;
// Estimate duration --- stabilize until you get <500ms deviation.
- while (feedMore() == OK && ALooper::GetNowUs() - startTime <= 2000000ll) {
- status_t err;
- int64_t bufferedDurationUs = impl->getBufferedDurationUs(&err);
- if (err != OK) {
- break;
- }
- if (bufferedDurationUs != prevBufferedDurationUs) {
- durationUs = size * bufferedDurationUs / mOffset;
+ while (feedMore() == OK
+ && ALooper::GetNowUs() - startTime <= 2000000ll) {
+ if (mSeekSyncPoints->size() > prevSyncSize) {
+ prevSyncSize = mSeekSyncPoints->size();
+ int64_t diffUs = mSeekSyncPoints->keyAt(prevSyncSize - 1)
+ - mSeekSyncPoints->keyAt(0);
+ off64_t diffOffset = mSeekSyncPoints->valueAt(prevSyncSize - 1)
+ - mSeekSyncPoints->valueAt(0);
+ durationUs = size * diffUs / diffOffset;
durations.push_back(durationUs);
if (durations.size() > 5) {
durations.erase(durations.begin());
@@ -225,9 +226,14 @@
break;
}
}
- prevBufferedDurationUs = bufferedDurationUs;
}
}
+ status_t err;
+ int64_t bufferedDurationUs;
+ bufferedDurationUs = impl->getBufferedDurationUs(&err);
+ if (err == ERROR_END_OF_STREAM) {
+ durationUs = bufferedDurationUs;
+ }
if (durationUs > 0) {
const sp<MetaData> meta = impl->getFormat();
meta->setInt64(kKeyDuration, durationUs);
diff --git a/media/libstagefright/tests/MediaCodecListOverrides_test.cpp b/media/libstagefright/tests/MediaCodecListOverrides_test.cpp
index cee62a3..ab547be 100644
--- a/media/libstagefright/tests/MediaCodecListOverrides_test.cpp
+++ b/media/libstagefright/tests/MediaCodecListOverrides_test.cpp
@@ -150,7 +150,11 @@
fclose(f);
free(buf);
- EXPECT_TRUE(overrides == kTestOverridesStr);
+ AString expected;
+ expected.append(getProfilingVersionString());
+ expected.append("\n");
+ expected.append(kTestOverridesStr);
+ EXPECT_TRUE(overrides == expected);
remove(fileName);
}
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 8bccb47..949c91d 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -335,13 +335,21 @@
// TODO: handle configuration of effects replacing track process
channelMask = thread->channelMask();
+ mConfig.outputCfg.channels = channelMask;
if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_MONO;
} else {
mConfig.inputCfg.channels = channelMask;
+ // TODO: Update this logic when multichannel effects are implemented.
+ // For offloaded tracks consider mono output as stereo for proper effect initialization
+ if (channelMask == AUDIO_CHANNEL_OUT_MONO) {
+ mConfig.inputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+ mConfig.outputCfg.channels = AUDIO_CHANNEL_OUT_STEREO;
+ ALOGV("Overriding effect input and output as STEREO");
+ }
}
- mConfig.outputCfg.channels = channelMask;
+
mConfig.inputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
mConfig.outputCfg.format = AUDIO_FORMAT_PCM_16_BIT;
mConfig.inputCfg.samplingRate = thread->sampleRate();
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 0593e1b..7809eff 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -356,13 +356,47 @@
AUDIO_DEVICE_OUT_SPEAKER, "SPEAKER",
AUDIO_DEVICE_OUT_WIRED_HEADSET, "WIRED_HEADSET",
AUDIO_DEVICE_OUT_WIRED_HEADPHONE, "WIRED_HEADPHONE",
+ AUDIO_DEVICE_OUT_BLUETOOTH_SCO, "BLUETOOTH_SCO",
+ AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET, "BLUETOOTH_SCO_HEADSET",
+ AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT, "BLUETOOTH_SCO_CARKIT",
+ AUDIO_DEVICE_OUT_BLUETOOTH_A2DP, "BLUETOOTH_A2DP",
+ AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, "BLUETOOTH_A2DP_HEADPHONES",
+ AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, "BLUETOOTH_A2DP_SPEAKER",
+ AUDIO_DEVICE_OUT_AUX_DIGITAL, "AUX_DIGITAL",
+ AUDIO_DEVICE_OUT_HDMI, "HDMI",
+ AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET, "ANLG_DOCK_HEADSET",
+ AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET, "DGTL_DOCK_HEADSET",
+ AUDIO_DEVICE_OUT_USB_ACCESSORY, "USB_ACCESSORY",
+ AUDIO_DEVICE_OUT_USB_DEVICE, "USB_DEVICE",
AUDIO_DEVICE_OUT_TELEPHONY_TX, "TELEPHONY_TX",
+ AUDIO_DEVICE_OUT_LINE, "LINE",
+ AUDIO_DEVICE_OUT_HDMI_ARC, "HDMI_ARC",
+ AUDIO_DEVICE_OUT_SPDIF, "SPDIF",
+ AUDIO_DEVICE_OUT_FM, "FM",
+ AUDIO_DEVICE_OUT_AUX_LINE, "AUX_LINE",
+ AUDIO_DEVICE_OUT_SPEAKER_SAFE, "SPEAKER_SAFE",
AUDIO_DEVICE_NONE, "NONE", // must be last
}, mappingsIn[] = {
+ AUDIO_DEVICE_IN_COMMUNICATION, "COMMUNICATION",
+ AUDIO_DEVICE_IN_AMBIENT, "AMBIENT",
AUDIO_DEVICE_IN_BUILTIN_MIC, "BUILTIN_MIC",
+ AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET, "BLUETOOTH_SCO_HEADSET",
AUDIO_DEVICE_IN_WIRED_HEADSET, "WIRED_HEADSET",
+ AUDIO_DEVICE_IN_AUX_DIGITAL, "AUX_DIGITAL",
AUDIO_DEVICE_IN_VOICE_CALL, "VOICE_CALL",
+ AUDIO_DEVICE_IN_TELEPHONY_RX, "TELEPHONY_RX",
+ AUDIO_DEVICE_IN_BACK_MIC, "BACK_MIC",
AUDIO_DEVICE_IN_REMOTE_SUBMIX, "REMOTE_SUBMIX",
+ AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET, "ANLG_DOCK_HEADSET",
+ AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET, "DGTL_DOCK_HEADSET",
+ AUDIO_DEVICE_IN_USB_ACCESSORY, "USB_ACCESSORY",
+ AUDIO_DEVICE_IN_USB_DEVICE, "USB_DEVICE",
+ AUDIO_DEVICE_IN_FM_TUNER, "FM_TUNER",
+ AUDIO_DEVICE_IN_TV_TUNER, "TV_TUNER",
+ AUDIO_DEVICE_IN_LINE, "LINE",
+ AUDIO_DEVICE_IN_SPDIF, "SPDIF",
+ AUDIO_DEVICE_IN_BLUETOOTH_A2DP, "BLUETOOTH_A2DP",
+ AUDIO_DEVICE_IN_LOOPBACK, "LOOPBACK",
AUDIO_DEVICE_NONE, "NONE", // must be last
};
String8 result;