diff options
Diffstat (limited to 'media')
53 files changed, 1653 insertions, 232 deletions
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index 38a5b40..9b76f89 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -525,6 +525,7 @@ public class AudioService extends IAudioService.Stub { // Reference to BluetoothA2dp to query for AbsoluteVolume. private BluetoothA2dp mA2dp; + // lock always taken synchronized on mConnectedDevices private final Object mA2dpAvrcpLock = new Object(); // If absolute volume is supported in AVRCP device private boolean mAvrcpAbsVolSupported = false; @@ -2877,12 +2878,12 @@ public class AudioService extends IAudioService.Stub { List<BluetoothDevice> deviceList; switch(profile) { case BluetoothProfile.A2DP: - synchronized (mA2dpAvrcpLock) { - mA2dp = (BluetoothA2dp) proxy; - deviceList = mA2dp.getConnectedDevices(); - if (deviceList.size() > 0) { - btDevice = deviceList.get(0); - synchronized (mConnectedDevices) { + synchronized (mConnectedDevices) { + synchronized (mA2dpAvrcpLock) { + mA2dp = (BluetoothA2dp) proxy; + deviceList = mA2dp.getConnectedDevices(); + if (deviceList.size() > 0) { + btDevice = deviceList.get(0); int state = mA2dp.getConnectionState(btDevice); int delay = checkSendBecomingNoisyIntent( AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, @@ -2977,9 +2978,9 @@ public class AudioService extends IAudioService.Stub { public void onServiceDisconnected(int profile) { switch(profile) { case BluetoothProfile.A2DP: - synchronized (mA2dpAvrcpLock) { - mA2dp = null; - synchronized (mConnectedDevices) { + synchronized (mConnectedDevices) { + synchronized (mA2dpAvrcpLock) { + mA2dp = null; if (mConnectedDevices.containsKey(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP)) { makeA2dpDeviceUnavailableNow( mConnectedDevices.get(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP)); diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java index 4f74bdd..32d5b82 100644 --- a/media/java/android/media/SoundPool.java +++ b/media/java/android/media/SoundPool.java @@ -543,11 +543,6 @@ public class SoundPool { public int load(String path, int priority) { - // pass network streams to player - if (path.startsWith("http:")) - return _load(path, priority); - - // try local path int id = 0; try { File f = new File(path); @@ -562,6 +557,7 @@ public class SoundPool { return id; } + @Override public int load(Context context, int resId, int priority) { AssetFileDescriptor afd = context.getResources().openRawResourceFd(resId); int id = 0; @@ -576,6 +572,7 @@ public class SoundPool { return id; } + @Override public int load(AssetFileDescriptor afd, int priority) { if (afd != null) { long len = afd.getLength(); @@ -588,16 +585,17 @@ public class SoundPool { } } + @Override public int load(FileDescriptor fd, long offset, long length, int priority) { return _load(fd, offset, length, priority); } - private native final int _load(String uri, int priority); - private native final int _load(FileDescriptor fd, long offset, long length, int priority); + @Override public native final boolean unload(int soundID); + @Override public final int play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate) { if (isRestricted()) { @@ -620,16 +618,22 @@ public class SoundPool { } } + @Override public native final void pause(int streamID); + @Override public native final void resume(int streamID); + @Override public native final void autoPause(); + @Override public native final void autoResume(); + @Override public native final void stop(int streamID); + @Override public final void setVolume(int streamID, float leftVolume, float rightVolume) { if (isRestricted()) { return; @@ -639,16 +643,21 @@ public class SoundPool { private native final void _setVolume(int streamID, float leftVolume, float rightVolume); + @Override public void setVolume(int streamID, float volume) { setVolume(streamID, volume, volume); } + @Override public native final void setPriority(int streamID, int priority); + @Override public native final void setLoop(int streamID, int loop); + @Override public native final void setRate(int streamID, float rate); + @Override public void setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener listener) { synchronized(mLock) { @@ -729,52 +738,69 @@ public class SoundPool { return 0; } + @Override public int load(Context context, int resId, int priority) { return 0; } + @Override public int load(AssetFileDescriptor afd, int priority) { return 0; } + @Override public int load(FileDescriptor fd, long offset, long length, int priority) { return 0; } + @Override public final boolean unload(int soundID) { return true; } + @Override public final int play(int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate) { return 0; } + @Override public final void pause(int streamID) { } + @Override public final void resume(int streamID) { } + @Override public final void autoPause() { } + @Override public final void autoResume() { } + @Override public final void stop(int streamID) { } + @Override public final void setVolume(int streamID, float leftVolume, float rightVolume) { } + @Override public void setVolume(int streamID, float volume) { } + @Override public final void setPriority(int streamID, int priority) { } + @Override public final void setLoop(int streamID, int loop) { } + @Override public final void setRate(int streamID, float rate) { } + @Override public void setOnLoadCompleteListener(SoundPool.OnLoadCompleteListener listener) { } + @Override public final void release() { } } } diff --git a/media/jni/Android.mk b/media/jni/Android.mk index 90fe695..4ebbe26 100644 --- a/media/jni/Android.mk +++ b/media/jni/Android.mk @@ -64,7 +64,7 @@ LOCAL_C_INCLUDES += \ $(PV_INCLUDES) \ $(JNI_H_INCLUDE) -LOCAL_CFLAGS += +LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code LOCAL_MODULE:= libmedia_jni diff --git a/media/jni/android_media_AmrInputStream.cpp b/media/jni/android_media_AmrInputStream.cpp index 3df6530..afb5d5c 100644 --- a/media/jni/android_media_AmrInputStream.cpp +++ b/media/jni/android_media_AmrInputStream.cpp @@ -50,7 +50,7 @@ struct GsmAmrEncoderState { }; static jlong android_media_AmrInputStream_GsmAmrEncoderNew - (JNIEnv *env, jclass clazz) { + (JNIEnv *env, jclass /* clazz */) { GsmAmrEncoderState* gae = new GsmAmrEncoderState(); if (gae == NULL) { jniThrowRuntimeException(env, "Out of memory"); @@ -59,7 +59,7 @@ static jlong android_media_AmrInputStream_GsmAmrEncoderNew } static void android_media_AmrInputStream_GsmAmrEncoderInitialize - (JNIEnv *env, jclass clazz, jlong gae) { + (JNIEnv *env, jclass /* clazz */, jlong gae) { GsmAmrEncoderState *state = (GsmAmrEncoderState *) gae; int32_t nResult = AMREncodeInit(&state->mEncState, &state->mSidState, false); if (nResult != OK) { @@ -69,7 +69,7 @@ static void android_media_AmrInputStream_GsmAmrEncoderInitialize } static jint android_media_AmrInputStream_GsmAmrEncoderEncode - (JNIEnv *env, jclass clazz, + (JNIEnv *env, jclass /* clazz */, jlong gae, jbyteArray pcm, jint pcmOffset, jbyteArray amr, jint amrOffset) { jbyte inBuf[BYTES_PER_FRAME]; @@ -105,7 +105,7 @@ static jint android_media_AmrInputStream_GsmAmrEncoderEncode } static void android_media_AmrInputStream_GsmAmrEncoderCleanup - (JNIEnv *env, jclass clazz, jlong gae) { + (JNIEnv* /* env */, jclass /* clazz */, jlong gae) { GsmAmrEncoderState *state = (GsmAmrEncoderState *) gae; AMREncodeExit(&state->mEncState, &state->mSidState); state->mEncState = NULL; @@ -113,7 +113,7 @@ static void android_media_AmrInputStream_GsmAmrEncoderCleanup } static void android_media_AmrInputStream_GsmAmrEncoderDelete - (JNIEnv *env, jclass clazz, jlong gae) { + (JNIEnv* /* env */, jclass /* clazz */, jlong gae) { delete (GsmAmrEncoderState*)gae; } diff --git a/media/jni/android_media_ImageReader.cpp b/media/jni/android_media_ImageReader.cpp index 3f4736d..7e68c78 100644 --- a/media/jni/android_media_ImageReader.cpp +++ b/media/jni/android_media_ImageReader.cpp @@ -502,7 +502,6 @@ static jint Image_imageGetPixelStride(JNIEnv* env, CpuConsumer::LockedBuffer* bu case HAL_PIXEL_FORMAT_Y8: // Single plane 8bpp data. ALOG_ASSERT(idx == 0, "Wrong index: %d", idx); - pixelStride; break; case HAL_PIXEL_FORMAT_YV12: pixelStride = 1; diff --git a/media/jni/android_media_MediaCodecList.cpp b/media/jni/android_media_MediaCodecList.cpp index 12eb7d2..f8c349b 100644 --- a/media/jni/android_media_MediaCodecList.cpp +++ b/media/jni/android_media_MediaCodecList.cpp @@ -42,7 +42,7 @@ static sp<IMediaCodecList> getCodecList(JNIEnv *env) { } static jint android_media_MediaCodecList_getCodecCount( - JNIEnv *env, jobject thiz) { + JNIEnv *env, jobject /* thiz */) { sp<IMediaCodecList> mcl = getCodecList(env); if (mcl == NULL) { // Runtime exception already pending. @@ -52,7 +52,7 @@ static jint android_media_MediaCodecList_getCodecCount( } static jstring android_media_MediaCodecList_getCodecName( - JNIEnv *env, jobject thiz, jint index) { + JNIEnv *env, jobject /* thiz */, jint index) { sp<IMediaCodecList> mcl = getCodecList(env); if (mcl == NULL) { // Runtime exception already pending. @@ -70,7 +70,7 @@ static jstring android_media_MediaCodecList_getCodecName( } static jint android_media_MediaCodecList_findCodecByName( - JNIEnv *env, jobject thiz, jstring name) { + JNIEnv *env, jobject /* thiz */, jstring name) { if (name == NULL) { jniThrowException(env, "java/lang/IllegalArgumentException", NULL); return -ENOENT; @@ -95,7 +95,7 @@ static jint android_media_MediaCodecList_findCodecByName( } static jboolean android_media_MediaCodecList_isEncoder( - JNIEnv *env, jobject thiz, jint index) { + JNIEnv *env, jobject /* thiz */, jint index) { sp<IMediaCodecList> mcl = getCodecList(env); if (mcl == NULL) { // Runtime exception already pending. @@ -112,7 +112,7 @@ static jboolean android_media_MediaCodecList_isEncoder( } static jarray android_media_MediaCodecList_getSupportedTypes( - JNIEnv *env, jobject thiz, jint index) { + JNIEnv *env, jobject /* thiz */, jint index) { sp<IMediaCodecList> mcl = getCodecList(env); if (mcl == NULL) { // Runtime exception already pending. @@ -144,7 +144,7 @@ static jarray android_media_MediaCodecList_getSupportedTypes( } static jobject android_media_MediaCodecList_getCodecCapabilities( - JNIEnv *env, jobject thiz, jint index, jstring type) { + JNIEnv *env, jobject /* thiz */, jint index, jstring type) { if (type == NULL) { jniThrowException(env, "java/lang/IllegalArgumentException", NULL); return NULL; @@ -262,7 +262,7 @@ static jobject android_media_MediaCodecList_getCodecCapabilities( return caps; } -static void android_media_MediaCodecList_native_init(JNIEnv *env) { +static void android_media_MediaCodecList_native_init(JNIEnv* /* env */) { } static JNINativeMethod gMethods[] = { diff --git a/media/jni/android_media_MediaCrypto.cpp b/media/jni/android_media_MediaCrypto.cpp index a6f8dcd..d2216fb 100644 --- a/media/jni/android_media_MediaCrypto.cpp +++ b/media/jni/android_media_MediaCrypto.cpp @@ -224,7 +224,7 @@ static void android_media_MediaCrypto_native_finalize( } static jboolean android_media_MediaCrypto_isCryptoSchemeSupportedNative( - JNIEnv *env, jobject thiz, jbyteArray uuidObj) { + JNIEnv *env, jobject /* thiz */, jbyteArray uuidObj) { jsize uuidLength = env->GetArrayLength(uuidObj); if (uuidLength != 16) { diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp index 8e07ec0..d9de7a9 100644 --- a/media/jni/android_media_MediaDrm.cpp +++ b/media/jni/android_media_MediaDrm.cpp @@ -667,7 +667,7 @@ static void android_media_MediaDrm_native_finalize( } static jboolean android_media_MediaDrm_isCryptoSchemeSupportedNative( - JNIEnv *env, jobject thiz, jbyteArray uuidObj, jstring jmimeType) { + JNIEnv *env, jobject /* thiz */, jbyteArray uuidObj, jstring jmimeType) { if (uuidObj == NULL) { jniThrowException(env, "java/lang/IllegalArgumentException", NULL); @@ -1173,7 +1173,7 @@ static void android_media_MediaDrm_setPropertyByteArray( } static void android_media_MediaDrm_setCipherAlgorithmNative( - JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId, + JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId, jstring jalgorithm) { sp<IDrm> drm = GetDrm(env, jdrm); @@ -1197,7 +1197,7 @@ static void android_media_MediaDrm_setCipherAlgorithmNative( } static void android_media_MediaDrm_setMacAlgorithmNative( - JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId, + JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId, jstring jalgorithm) { sp<IDrm> drm = GetDrm(env, jdrm); @@ -1222,7 +1222,7 @@ static void android_media_MediaDrm_setMacAlgorithmNative( static jbyteArray android_media_MediaDrm_encryptNative( - JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId, + JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId, jbyteArray jkeyId, jbyteArray jinput, jbyteArray jiv) { sp<IDrm> drm = GetDrm(env, jdrm); @@ -1253,7 +1253,7 @@ static jbyteArray android_media_MediaDrm_encryptNative( } static jbyteArray android_media_MediaDrm_decryptNative( - JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId, + JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId, jbyteArray jkeyId, jbyteArray jinput, jbyteArray jiv) { sp<IDrm> drm = GetDrm(env, jdrm); @@ -1283,7 +1283,7 @@ static jbyteArray android_media_MediaDrm_decryptNative( } static jbyteArray android_media_MediaDrm_signNative( - JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId, + JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId, jbyteArray jkeyId, jbyteArray jmessage) { sp<IDrm> drm = GetDrm(env, jdrm); @@ -1313,7 +1313,7 @@ static jbyteArray android_media_MediaDrm_signNative( } static jboolean android_media_MediaDrm_verifyNative( - JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId, + JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId, jbyteArray jkeyId, jbyteArray jmessage, jbyteArray jsignature) { sp<IDrm> drm = GetDrm(env, jdrm); @@ -1342,7 +1342,7 @@ static jboolean android_media_MediaDrm_verifyNative( static jbyteArray android_media_MediaDrm_signRSANative( - JNIEnv *env, jobject thiz, jobject jdrm, jbyteArray jsessionId, + JNIEnv *env, jobject /* thiz */, jobject jdrm, jbyteArray jsessionId, jstring jalgorithm, jbyteArray jwrappedKey, jbyteArray jmessage) { sp<IDrm> drm = GetDrm(env, jdrm); diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp index 52e9910..c0795b6 100644 --- a/media/jni/android_media_MediaExtractor.cpp +++ b/media/jni/android_media_MediaExtractor.cpp @@ -93,7 +93,7 @@ class JavaDataSourceBridge : public DataSource { env->GetByteArrayRegion(byteArrayObj, 0, size, (jbyte*) buffer); env->DeleteLocalRef(byteArrayObj); if (env->ExceptionCheck()) { - ALOGW("Exception occurred while reading %zu at %lld", size, offset); + ALOGW("Exception occurred while reading %zu at %lld", size, (long long)offset); LOGW_EX(env); env->ExceptionClear(); return -1; diff --git a/media/jni/android_media_MediaExtractor.h b/media/jni/android_media_MediaExtractor.h index e5a0c16e..9f62506 100644 --- a/media/jni/android_media_MediaExtractor.h +++ b/media/jni/android_media_MediaExtractor.h @@ -30,7 +30,7 @@ namespace android { struct IMediaHTTPService; -struct MetaData; +class MetaData; struct NuMediaExtractor; struct JMediaExtractor : public RefBase { diff --git a/media/jni/android_media_MediaHTTPConnection.cpp b/media/jni/android_media_MediaHTTPConnection.cpp index 0e7d83e..7226ef5 100644 --- a/media/jni/android_media_MediaHTTPConnection.cpp +++ b/media/jni/android_media_MediaHTTPConnection.cpp @@ -128,7 +128,7 @@ static jobject android_media_MediaHTTPConnection_native_getIMemory( JNIEnv *env, jobject thiz) { sp<JMediaHTTPConnection> conn = getObject(env, thiz); - return javaObjectForIBinder(env, conn->getIMemory()->asBinder()); + return javaObjectForIBinder(env, IInterface::asBinder(conn->getIMemory())); } static jint android_media_MediaHTTPConnection_native_readAt( diff --git a/media/jni/android_media_MediaHTTPConnection.h b/media/jni/android_media_MediaHTTPConnection.h index 62ff678..f87f1eb 100644 --- a/media/jni/android_media_MediaHTTPConnection.h +++ b/media/jni/android_media_MediaHTTPConnection.h @@ -24,8 +24,8 @@ namespace android { -struct IMemory; -struct MemoryDealer; +class IMemory; +class MemoryDealer; struct JMediaHTTPConnection : public RefBase { enum { diff --git a/media/jni/android_media_MediaMetadataRetriever.cpp b/media/jni/android_media_MediaMetadataRetriever.cpp index fbe5340..fc7931e 100644 --- a/media/jni/android_media_MediaMetadataRetriever.cpp +++ b/media/jni/android_media_MediaMetadataRetriever.cpp @@ -77,7 +77,6 @@ static MediaMetadataRetriever* getRetriever(JNIEnv* env, jobject thiz) static void setRetriever(JNIEnv* env, jobject thiz, MediaMetadataRetriever* retriever) { // No lock is needed, since it is called internally by other methods that are protected - MediaMetadataRetriever *old = (MediaMetadataRetriever*) env->GetLongField(thiz, fields.context); env->SetLongField(thiz, fields.context, (jlong) retriever); } @@ -229,7 +228,7 @@ static void rotate(T *dst, const T *src, size_t width, size_t height, int angle) static jobject android_media_MediaMetadataRetriever_getFrameAtTime(JNIEnv *env, jobject thiz, jlong timeUs, jint option) { - ALOGV("getFrameAtTime: %lld us option: %d", timeUs, option); + ALOGV("getFrameAtTime: %lld us option: %d", (long long)timeUs, option); MediaMetadataRetriever* retriever = getRetriever(env, thiz); if (retriever == 0) { jniThrowException(env, "java/lang/IllegalStateException", "No retriever available"); diff --git a/media/jni/android_media_MediaMuxer.cpp b/media/jni/android_media_MediaMuxer.cpp index 3fef446f..ecb2ac8 100644 --- a/media/jni/android_media_MediaMuxer.cpp +++ b/media/jni/android_media_MediaMuxer.cpp @@ -41,7 +41,7 @@ static fields_t gFields; using namespace android; static jint android_media_MediaMuxer_addTrack( - JNIEnv *env, jclass clazz, jlong nativeObject, jobjectArray keys, + JNIEnv *env, jclass /* clazz */, jlong nativeObject, jobjectArray keys, jobjectArray values) { sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject)); if (muxer == NULL) { @@ -71,7 +71,7 @@ static jint android_media_MediaMuxer_addTrack( } static void android_media_MediaMuxer_writeSampleData( - JNIEnv *env, jclass clazz, jlong nativeObject, jint trackIndex, + JNIEnv *env, jclass /* clazz */, jlong nativeObject, jint trackIndex, jobject byteBuf, jint offset, jint size, jlong timeUs, jint flags) { sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject)); if (muxer == NULL) { @@ -107,7 +107,7 @@ static void android_media_MediaMuxer_writeSampleData( if (dstSize < (offset + size)) { ALOGE("writeSampleData saw wrong dstSize %lld, size %d, offset %d", - dstSize, size, offset); + (long long)dstSize, size, offset); if (byteArray != NULL) { env->ReleaseByteArrayElements(byteArray, (jbyte *)dst, 0); } @@ -146,7 +146,7 @@ static jlong android_media_MediaMuxer_native_setup( } static void android_media_MediaMuxer_setOrientationHint( - JNIEnv *env, jclass clazz, jlong nativeObject, jint degrees) { + JNIEnv *env, jclass /* clazz */, jlong nativeObject, jint degrees) { sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject)); if (muxer == NULL) { jniThrowException(env, "java/lang/IllegalStateException", @@ -164,7 +164,7 @@ static void android_media_MediaMuxer_setOrientationHint( } static void android_media_MediaMuxer_setLocation( - JNIEnv *env, jclass clazz, jlong nativeObject, jint latitude, jint longitude) { + JNIEnv *env, jclass /* clazz */, jlong nativeObject, jint latitude, jint longitude) { MediaMuxer* muxer = reinterpret_cast<MediaMuxer *>(nativeObject); status_t res = muxer->setLocation(latitude, longitude); @@ -175,7 +175,7 @@ static void android_media_MediaMuxer_setLocation( } } -static void android_media_MediaMuxer_start(JNIEnv *env, jclass clazz, +static void android_media_MediaMuxer_start(JNIEnv *env, jclass /* clazz */, jlong nativeObject) { sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject)); if (muxer == NULL) { @@ -193,7 +193,7 @@ static void android_media_MediaMuxer_start(JNIEnv *env, jclass clazz, } -static void android_media_MediaMuxer_stop(JNIEnv *env, jclass clazz, +static void android_media_MediaMuxer_stop(JNIEnv *env, jclass /* clazz */, jlong nativeObject) { sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject)); if (muxer == NULL) { @@ -212,7 +212,7 @@ static void android_media_MediaMuxer_stop(JNIEnv *env, jclass clazz, } static void android_media_MediaMuxer_native_release( - JNIEnv *env, jclass clazz, jlong nativeObject) { + JNIEnv* /* env */, jclass clazz, jlong nativeObject) { sp<MediaMuxer> muxer(reinterpret_cast<MediaMuxer *>(nativeObject)); if (muxer != NULL) { muxer->decStrong(clazz); diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index 73a924d..820de5b 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -895,8 +895,6 @@ static JNINativeMethod gMethods[] = { {"setNextMediaPlayer", "(Landroid/media/MediaPlayer;)V", (void *)android_media_MediaPlayer_setNextMediaPlayer}, }; -static const char* const kClassPathName = "android/media/MediaPlayer"; - // This function only registers the native methods static int register_android_media_MediaPlayer(JNIEnv *env) { diff --git a/media/jni/android_media_MediaProfiles.cpp b/media/jni/android_media_MediaProfiles.cpp index 007fc14..ca9db91 100644 --- a/media/jni/android_media_MediaProfiles.cpp +++ b/media/jni/android_media_MediaProfiles.cpp @@ -34,7 +34,7 @@ MediaProfiles *sProfiles = NULL; // This function is called from a static block in MediaProfiles.java class, // which won't run until the first time an instance of this class is used. static void -android_media_MediaProfiles_native_init(JNIEnv *env) +android_media_MediaProfiles_native_init(JNIEnv* /* env */) { ALOGV("native_init"); Mutex::Autolock lock(sLock); @@ -45,14 +45,14 @@ android_media_MediaProfiles_native_init(JNIEnv *env) } static jint -android_media_MediaProfiles_native_get_num_file_formats(JNIEnv *env, jobject thiz) +android_media_MediaProfiles_native_get_num_file_formats(JNIEnv* /* env */, jobject /* thiz */) { ALOGV("native_get_num_file_formats"); return (jint) sProfiles->getOutputFileFormats().size(); } static jint -android_media_MediaProfiles_native_get_file_format(JNIEnv *env, jobject thiz, jint index) +android_media_MediaProfiles_native_get_file_format(JNIEnv *env, jobject /* thiz */, jint index) { ALOGV("native_get_file_format: %d", index); Vector<output_format> formats = sProfiles->getOutputFileFormats(); @@ -65,14 +65,15 @@ android_media_MediaProfiles_native_get_file_format(JNIEnv *env, jobject thiz, ji } static jint -android_media_MediaProfiles_native_get_num_video_encoders(JNIEnv *env, jobject thiz) +android_media_MediaProfiles_native_get_num_video_encoders(JNIEnv* /* env */, jobject /* thiz */) { ALOGV("native_get_num_video_encoders"); return sProfiles->getVideoEncoders().size(); } static jobject -android_media_MediaProfiles_native_get_video_encoder_cap(JNIEnv *env, jobject thiz, jint index) +android_media_MediaProfiles_native_get_video_encoder_cap(JNIEnv *env, jobject /* thiz */, + jint index) { ALOGV("native_get_video_encoder_cap: %d", index); Vector<video_encoder> encoders = sProfiles->getVideoEncoders(); @@ -116,14 +117,15 @@ android_media_MediaProfiles_native_get_video_encoder_cap(JNIEnv *env, jobject th } static jint -android_media_MediaProfiles_native_get_num_audio_encoders(JNIEnv *env, jobject thiz) +android_media_MediaProfiles_native_get_num_audio_encoders(JNIEnv* /* env */, jobject /* thiz */) { ALOGV("native_get_num_audio_encoders"); return (jint) sProfiles->getAudioEncoders().size(); } static jobject -android_media_MediaProfiles_native_get_audio_encoder_cap(JNIEnv *env, jobject thiz, jint index) +android_media_MediaProfiles_native_get_audio_encoder_cap(JNIEnv *env, jobject /* thiz */, + jint index) { ALOGV("native_get_audio_encoder_cap: %d", index); Vector<audio_encoder> encoders = sProfiles->getAudioEncoders(); @@ -172,7 +174,8 @@ static bool isCamcorderQualityKnown(int quality) } static jobject -android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject thiz, jint id, jint quality) +android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject /* thiz */, jint id, + jint quality) { ALOGV("native_get_camcorder_profile: %d %d", id, quality); if (!isCamcorderQualityKnown(quality)) { @@ -221,7 +224,8 @@ android_media_MediaProfiles_native_get_camcorder_profile(JNIEnv *env, jobject th } static jboolean -android_media_MediaProfiles_native_has_camcorder_profile(JNIEnv *env, jobject thiz, jint id, jint quality) +android_media_MediaProfiles_native_has_camcorder_profile(JNIEnv* /* env */, jobject /* thiz */, + jint id, jint quality) { ALOGV("native_has_camcorder_profile: %d %d", id, quality); if (!isCamcorderQualityKnown(quality)) { @@ -233,14 +237,15 @@ android_media_MediaProfiles_native_has_camcorder_profile(JNIEnv *env, jobject th } static jint -android_media_MediaProfiles_native_get_num_video_decoders(JNIEnv *env, jobject thiz) +android_media_MediaProfiles_native_get_num_video_decoders(JNIEnv* /* env */, jobject /* thiz */) { ALOGV("native_get_num_video_decoders"); return (jint) sProfiles->getVideoDecoders().size(); } static jint -android_media_MediaProfiles_native_get_video_decoder_type(JNIEnv *env, jobject thiz, jint index) +android_media_MediaProfiles_native_get_video_decoder_type(JNIEnv *env, jobject /* thiz */, + jint index) { ALOGV("native_get_video_decoder_type: %d", index); Vector<video_decoder> decoders = sProfiles->getVideoDecoders(); @@ -254,14 +259,15 @@ android_media_MediaProfiles_native_get_video_decoder_type(JNIEnv *env, jobject t } static jint -android_media_MediaProfiles_native_get_num_audio_decoders(JNIEnv *env, jobject thiz) +android_media_MediaProfiles_native_get_num_audio_decoders(JNIEnv* /* env */, jobject /* thiz */) { ALOGV("native_get_num_audio_decoders"); return (jint) sProfiles->getAudioDecoders().size(); } static jint -android_media_MediaProfiles_native_get_audio_decoder_type(JNIEnv *env, jobject thiz, jint index) +android_media_MediaProfiles_native_get_audio_decoder_type(JNIEnv *env, jobject /* thiz */, + jint index) { ALOGV("native_get_audio_decoder_type: %d", index); Vector<audio_decoder> decoders = sProfiles->getAudioDecoders(); @@ -275,14 +281,17 @@ android_media_MediaProfiles_native_get_audio_decoder_type(JNIEnv *env, jobject t } static jint -android_media_MediaProfiles_native_get_num_image_encoding_quality_levels(JNIEnv *env, jobject thiz, jint cameraId) +android_media_MediaProfiles_native_get_num_image_encoding_quality_levels(JNIEnv* /* env */, + jobject /* thiz */, + jint cameraId) { ALOGV("native_get_num_image_encoding_quality_levels"); return (jint) sProfiles->getImageEncodingQualityLevels(cameraId).size(); } static jint -android_media_MediaProfiles_native_get_image_encoding_quality_level(JNIEnv *env, jobject thiz, jint cameraId, jint index) +android_media_MediaProfiles_native_get_image_encoding_quality_level(JNIEnv *env, jobject /* thiz */, + jint cameraId, jint index) { ALOGV("native_get_image_encoding_quality_level"); Vector<int> levels = sProfiles->getImageEncodingQualityLevels(cameraId); diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp index e9c80a0..8b7d40d 100644 --- a/media/jni/android_media_MediaRecorder.cpp +++ b/media/jni/android_media_MediaRecorder.cpp @@ -306,7 +306,7 @@ static void android_media_MediaRecorder_setMaxFileSize( JNIEnv *env, jobject thiz, jlong max_filesize_bytes) { - ALOGV("setMaxFileSize(%lld)", max_filesize_bytes); + ALOGV("setMaxFileSize(%lld)", (long long)max_filesize_bytes); sp<MediaRecorder> mr = getMediaRecorder(env, thiz); char params[64]; @@ -462,11 +462,13 @@ android_media_MediaRecorder_native_setup(JNIEnv *env, jobject thiz, jobject weak sp<JNIMediaRecorderListener> listener = new JNIMediaRecorderListener(env, thiz, weak_this); mr->setListener(listener); - // Convert client name jstring to String16 - const char16_t *rawClientName = env->GetStringChars(packageName, NULL); + // Convert client name jstring to String16 + const char16_t *rawClientName = reinterpret_cast<const char16_t*>( + env->GetStringChars(packageName, NULL)); jsize rawClientNameLen = env->GetStringLength(packageName); String16 clientName(rawClientName, rawClientNameLen); - env->ReleaseStringChars(packageName, rawClientName); + env->ReleaseStringChars(packageName, + reinterpret_cast<const jchar*>(rawClientName)); // pass client package name for permissions tracking mr->setClientName(clientName); @@ -508,8 +510,6 @@ static JNINativeMethod gMethods[] = { {"native_finalize", "()V", (void *)android_media_MediaRecorder_native_finalize}, }; -static const char* const kClassPathName = "android/media/MediaRecorder"; - // This function only registers the native methods, and is called from // JNI_OnLoad in android_media_MediaPlayer.cpp int register_android_media_MediaRecorder(JNIEnv *env) diff --git a/media/jni/android_media_MediaScanner.cpp b/media/jni/android_media_MediaScanner.cpp index 321c2e3..1a9384e 100644 --- a/media/jni/android_media_MediaScanner.cpp +++ b/media/jni/android_media_MediaScanner.cpp @@ -360,7 +360,6 @@ android_media_MediaScanner_extractAlbumArt( env->SetByteArrayRegion(array, 0, mediaAlbumArt->size(), data); } -done: free(mediaAlbumArt); // if NewByteArray() returned NULL, an out-of-memory // exception will have been raised. I just want to diff --git a/media/jni/android_media_ResampleInputStream.cpp b/media/jni/android_media_ResampleInputStream.cpp index d5a4a17..1549a30 100644 --- a/media/jni/android_media_ResampleInputStream.cpp +++ b/media/jni/android_media_ResampleInputStream.cpp @@ -73,7 +73,7 @@ static const int nFir21 = sizeof(fir21) / sizeof(fir21[0]); static const int BUF_SIZE = 2048; -static void android_media_ResampleInputStream_fir21(JNIEnv *env, jclass clazz, +static void android_media_ResampleInputStream_fir21(JNIEnv *env, jclass /* clazz */, jbyteArray jIn, jint jInOffset, jbyteArray jOut, jint jOutOffset, jint jNpoints) { diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp index 54c5e9b..ea33a2f 100644 --- a/media/jni/android_media_Utils.cpp +++ b/media/jni/android_media_Utils.cpp @@ -136,8 +136,7 @@ static void SetMapInt32( jstring keyObj = env->NewStringUTF(key); jobject valueObj = makeIntegerObject(env, value); - jobject res = env->CallObjectMethod( - hashMapObj, hashMapPutID, keyObj, valueObj); + env->CallObjectMethod(hashMapObj, hashMapPutID, keyObj, valueObj); env->DeleteLocalRef(valueObj); valueObj = NULL; env->DeleteLocalRef(keyObj); keyObj = NULL; @@ -266,8 +265,7 @@ status_t ConvertMessageToMap( if (valueObj != NULL) { jstring keyObj = env->NewStringUTF(key); - jobject res = env->CallObjectMethod( - hashMap, hashMapPutID, keyObj, valueObj); + env->CallObjectMethod(hashMap, hashMapPutID, keyObj, valueObj); env->DeleteLocalRef(keyObj); keyObj = NULL; env->DeleteLocalRef(valueObj); valueObj = NULL; diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp index 8b2e203..713f28c 100644 --- a/media/jni/android_mtp_MtpDatabase.cpp +++ b/media/jni/android_mtp_MtpDatabase.cpp @@ -765,7 +765,7 @@ MtpResponseCode MyMtpDatabase::getObjectPropertyList(MtpObjectHandle handle, return result; } -static void foreachentry(ExifEntry *entry, void * /*user*/) { +static void foreachentry(ExifEntry *entry, void* /* user */) { char buf[1024]; ALOGI("entry %x, format %d, size %d: %s", entry->tag, entry->format, entry->size, exif_entry_get_value(entry, buf, sizeof(buf))); @@ -783,7 +783,6 @@ static long getLongFromExifEntry(ExifEntry *e) { MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle, MtpObjectInfo& info) { - char date[20]; MtpString path; int64_t length; MtpObjectFormat format; @@ -811,13 +810,15 @@ MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle, info.mDateModified = longValues[1]; env->ReleaseLongArrayElements(mLongBuffer, longValues, 0); -// info.mAssociationType = (format == MTP_FORMAT_ASSOCIATION ? -// MTP_ASSOCIATION_TYPE_GENERIC_FOLDER : -// MTP_ASSOCIATION_TYPE_UNDEFINED); + if ((false)) { + info.mAssociationType = (format == MTP_FORMAT_ASSOCIATION ? + MTP_ASSOCIATION_TYPE_GENERIC_FOLDER : + MTP_ASSOCIATION_TYPE_UNDEFINED); + } info.mAssociationType = MTP_ASSOCIATION_TYPE_UNDEFINED; jchar* str = env->GetCharArrayElements(mStringBuffer, 0); - MtpString temp(str); + MtpString temp(reinterpret_cast<char16_t*>(str)); info.mName = strdup((const char *)temp); env->ReleaseCharArrayElements(mStringBuffer, str, 0); @@ -826,7 +827,9 @@ MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle, ExifData *exifdata = exif_data_new_from_file(path); if (exifdata) { - //exif_data_foreach_content(exifdata, foreachcontent, NULL); + if ((false)) { + exif_data_foreach_content(exifdata, foreachcontent, NULL); + } // XXX get this from exif, or parse jpeg header instead? ExifEntry *w = exif_content_get_entry( @@ -884,7 +887,8 @@ MtpResponseCode MyMtpDatabase::getObjectFilePath(MtpObjectHandle handle, } jchar* str = env->GetCharArrayElements(mStringBuffer, 0); - outFilePath.setTo(str, strlen16(str)); + outFilePath.setTo(reinterpret_cast<char16_t*>(str), + strlen16(reinterpret_cast<char16_t*>(str))); env->ReleaseCharArrayElements(mStringBuffer, str, 0); jlong* longValues = env->GetLongArrayElements(mLongBuffer, 0); @@ -1179,8 +1183,6 @@ static JNINativeMethod gMtpPropertyGroupMethods[] = { (void *)android_mtp_MtpPropertyGroup_format_date_time}, }; -static const char* const kClassPathName = "android/mtp/MtpDatabase"; - int register_android_mtp_MtpDatabase(JNIEnv *env) { jclass clazz; diff --git a/media/jni/android_mtp_MtpDevice.cpp b/media/jni/android_mtp_MtpDevice.cpp index 8e013a0..2dbd7dc 100644 --- a/media/jni/android_mtp_MtpDevice.cpp +++ b/media/jni/android_mtp_MtpDevice.cpp @@ -91,14 +91,6 @@ MtpDevice* get_device_from_object(JNIEnv* env, jobject javaDevice) return (MtpDevice*)env->GetLongField(javaDevice, field_context); } -static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) { - if (env->ExceptionCheck()) { - ALOGE("An exception was thrown by callback '%s'.", methodName); - LOGE_EX(env); - env->ExceptionClear(); - } -} - // ---------------------------------------------------------------------------- static jboolean @@ -425,8 +417,6 @@ static JNINativeMethod gMethods[] = { (void *)android_mtp_MtpDevice_import_file}, }; -static const char* const kClassPathName = "android/mtp/MtpDevice"; - int register_android_mtp_MtpDevice(JNIEnv *env) { jclass clazz; diff --git a/media/jni/android_mtp_MtpServer.cpp b/media/jni/android_mtp_MtpServer.cpp index 2f90dfe..2ce2a90 100644 --- a/media/jni/android_mtp_MtpServer.cpp +++ b/media/jni/android_mtp_MtpServer.cpp @@ -193,8 +193,6 @@ static JNINativeMethod gMethods[] = { {"native_remove_storage", "(I)V", (void *)android_mtp_MtpServer_remove_storage}, }; -static const char* const kClassPathName = "android/mtp/MtpServer"; - int register_android_mtp_MtpServer(JNIEnv *env) { jclass clazz; diff --git a/media/jni/audioeffect/Android.mk b/media/jni/audioeffect/Android.mk index 3b1fb19..5c22c9b 100644 --- a/media/jni/audioeffect/Android.mk +++ b/media/jni/audioeffect/Android.mk @@ -2,20 +2,22 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ - android_media_AudioEffect.cpp \ - android_media_Visualizer.cpp + android_media_AudioEffect.cpp \ + android_media_Visualizer.cpp LOCAL_SHARED_LIBRARIES := \ - liblog \ - libcutils \ - libutils \ - libandroid_runtime \ - libnativehelper \ - libmedia + liblog \ + libcutils \ + libutils \ + libandroid_runtime \ + libnativehelper \ + libmedia LOCAL_C_INCLUDES := \ - $(call include-path-for, audio-effects) + $(call include-path-for, audio-effects) LOCAL_MODULE:= libaudioeffect_jni +LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code + include $(BUILD_SHARED_LIBRARY) diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp index b59a541..460277f 100644 --- a/media/jni/audioeffect/android_media_Visualizer.cpp +++ b/media/jni/audioeffect/android_media_Visualizer.cpp @@ -162,10 +162,6 @@ static void captureCallback(void* user, uint8_t *fft, uint32_t samplingrate) { - int arg1 = 0; - int arg2 = 0; - size_t size; - visualizer_callback_cookie *callbackInfo = (visualizer_callback_cookie *)user; JNIEnv *env = AndroidRuntime::getJNIEnv(); @@ -486,7 +482,7 @@ android_media_visualizer_native_getEnabled(JNIEnv *env, jobject thiz) } static jintArray -android_media_visualizer_native_getCaptureSizeRange(JNIEnv *env, jobject thiz) +android_media_visualizer_native_getCaptureSizeRange(JNIEnv *env, jobject /* thiz */) { jintArray jRange = env->NewIntArray(2); jint *nRange = env->GetIntArrayElements(jRange, NULL); @@ -498,7 +494,7 @@ android_media_visualizer_native_getCaptureSizeRange(JNIEnv *env, jobject thiz) } static jint -android_media_visualizer_native_getMaxCaptureRate(JNIEnv *env, jobject thiz) +android_media_visualizer_native_getMaxCaptureRate(JNIEnv* /* env */, jobject /* thiz */) { return (jint) Visualizer::getMaxCaptureRate(); } diff --git a/media/jni/soundpool/Android.mk b/media/jni/soundpool/Android.mk index ed8d7c1..71ab013 100644 --- a/media/jni/soundpool/Android.mk +++ b/media/jni/soundpool/Android.mk @@ -2,16 +2,22 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ - android_media_SoundPool_SoundPoolImpl.cpp + android_media_SoundPool_SoundPoolImpl.cpp \ + SoundPool.cpp \ + SoundPoolThread.cpp LOCAL_SHARED_LIBRARIES := \ - liblog \ - libcutils \ - libutils \ - libandroid_runtime \ - libnativehelper \ - libmedia + liblog \ + libcutils \ + libutils \ + libandroid_runtime \ + libnativehelper \ + libmedia \ + libmediandk \ + libbinder LOCAL_MODULE:= libsoundpool +LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code + include $(BUILD_SHARED_LIBRARY) diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp new file mode 100644 index 0000000..a8b91d24c --- /dev/null +++ b/media/jni/soundpool/SoundPool.cpp @@ -0,0 +1,1018 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "SoundPool" + +#include <inttypes.h> + +#include <utils/Log.h> + +#define USE_SHARED_MEM_BUFFER + +#include <media/AudioTrack.h> +#include <media/IMediaHTTPService.h> +#include <media/mediaplayer.h> +#include <media/stagefright/MediaExtractor.h> +#include "SoundPool.h" +#include "SoundPoolThread.h" +#include <media/AudioPolicyHelper.h> +#include <ndk/NdkMediaCodec.h> +#include <ndk/NdkMediaExtractor.h> +#include <ndk/NdkMediaFormat.h> + +namespace android +{ + +int kDefaultBufferCount = 4; +uint32_t kMaxSampleRate = 48000; +uint32_t kDefaultSampleRate = 44100; +uint32_t kDefaultFrameCount = 1200; +size_t kDefaultHeapSize = 1024 * 1024; // 1MB + + +SoundPool::SoundPool(int maxChannels, const audio_attributes_t* pAttributes) +{ + ALOGV("SoundPool constructor: maxChannels=%d, attr.usage=%d, attr.flags=0x%x, attr.tags=%s", + maxChannels, pAttributes->usage, pAttributes->flags, pAttributes->tags); + + // check limits + mMaxChannels = maxChannels; + if (mMaxChannels < 1) { + mMaxChannels = 1; + } + else if (mMaxChannels > 32) { + mMaxChannels = 32; + } + ALOGW_IF(maxChannels != mMaxChannels, "App requested %d channels", maxChannels); + + mQuit = false; + mDecodeThread = 0; + memcpy(&mAttributes, pAttributes, sizeof(audio_attributes_t)); + mAllocated = 0; + mNextSampleID = 0; + mNextChannelID = 0; + + mCallback = 0; + mUserData = 0; + + mChannelPool = new SoundChannel[mMaxChannels]; + for (int i = 0; i < mMaxChannels; ++i) { + mChannelPool[i].init(this); + mChannels.push_back(&mChannelPool[i]); + } + + // start decode thread + startThreads(); +} + +SoundPool::~SoundPool() +{ + ALOGV("SoundPool destructor"); + mDecodeThread->quit(); + quit(); + + Mutex::Autolock lock(&mLock); + + mChannels.clear(); + if (mChannelPool) + delete [] mChannelPool; + // clean up samples + ALOGV("clear samples"); + mSamples.clear(); + + if (mDecodeThread) + delete mDecodeThread; +} + +void SoundPool::addToRestartList(SoundChannel* channel) +{ + Mutex::Autolock lock(&mRestartLock); + if (!mQuit) { + mRestart.push_back(channel); + mCondition.signal(); + } +} + +void SoundPool::addToStopList(SoundChannel* channel) +{ + Mutex::Autolock lock(&mRestartLock); + if (!mQuit) { + mStop.push_back(channel); + mCondition.signal(); + } +} + +int SoundPool::beginThread(void* arg) +{ + SoundPool* p = (SoundPool*)arg; + return p->run(); +} + +int SoundPool::run() +{ + mRestartLock.lock(); + while (!mQuit) { + mCondition.wait(mRestartLock); + ALOGV("awake"); + if (mQuit) break; + + while (!mStop.empty()) { + SoundChannel* channel; + ALOGV("Getting channel from stop list"); + List<SoundChannel* >::iterator iter = mStop.begin(); + channel = *iter; + mStop.erase(iter); + mRestartLock.unlock(); + if (channel != 0) { + Mutex::Autolock lock(&mLock); + channel->stop(); + } + mRestartLock.lock(); + if (mQuit) break; + } + + while (!mRestart.empty()) { + SoundChannel* channel; + ALOGV("Getting channel from list"); + List<SoundChannel*>::iterator iter = mRestart.begin(); + channel = *iter; + mRestart.erase(iter); + mRestartLock.unlock(); + if (channel != 0) { + Mutex::Autolock lock(&mLock); + channel->nextEvent(); + } + mRestartLock.lock(); + if (mQuit) break; + } + } + + mStop.clear(); + mRestart.clear(); + mCondition.signal(); + mRestartLock.unlock(); + ALOGV("goodbye"); + return 0; +} + +void SoundPool::quit() +{ + mRestartLock.lock(); + mQuit = true; + mCondition.signal(); + mCondition.wait(mRestartLock); + ALOGV("return from quit"); + mRestartLock.unlock(); +} + +bool SoundPool::startThreads() +{ + createThreadEtc(beginThread, this, "SoundPool"); + if (mDecodeThread == NULL) + mDecodeThread = new SoundPoolThread(this); + return mDecodeThread != NULL; +} + +SoundChannel* SoundPool::findChannel(int channelID) +{ + for (int i = 0; i < mMaxChannels; ++i) { + if (mChannelPool[i].channelID() == channelID) { + return &mChannelPool[i]; + } + } + return NULL; +} + +SoundChannel* SoundPool::findNextChannel(int channelID) +{ + for (int i = 0; i < mMaxChannels; ++i) { + if (mChannelPool[i].nextChannelID() == channelID) { + return &mChannelPool[i]; + } + } + return NULL; +} + +int SoundPool::load(int fd, int64_t offset, int64_t length, int priority __unused) +{ + ALOGV("load: fd=%d, offset=%" PRId64 ", length=%" PRId64 ", priority=%d", + fd, offset, length, priority); + Mutex::Autolock lock(&mLock); + sp<Sample> sample = new Sample(++mNextSampleID, fd, offset, length); + mSamples.add(sample->sampleID(), sample); + doLoad(sample); + return sample->sampleID(); +} + +void SoundPool::doLoad(sp<Sample>& sample) +{ + ALOGV("doLoad: loading sample sampleID=%d", sample->sampleID()); + sample->startLoad(); + mDecodeThread->loadSample(sample->sampleID()); +} + +bool SoundPool::unload(int sampleID) +{ + ALOGV("unload: sampleID=%d", sampleID); + Mutex::Autolock lock(&mLock); + return mSamples.removeItem(sampleID); +} + +int SoundPool::play(int sampleID, float leftVolume, float rightVolume, + int priority, int loop, float rate) +{ + ALOGV("play sampleID=%d, leftVolume=%f, rightVolume=%f, priority=%d, loop=%d, rate=%f", + sampleID, leftVolume, rightVolume, priority, loop, rate); + sp<Sample> sample; + SoundChannel* channel; + int channelID; + + Mutex::Autolock lock(&mLock); + + if (mQuit) { + return 0; + } + // is sample ready? + sample = findSample(sampleID); + if ((sample == 0) || (sample->state() != Sample::READY)) { + ALOGW(" sample %d not READY", sampleID); + return 0; + } + + dump(); + + // allocate a channel + channel = allocateChannel_l(priority); + + // no channel allocated - return 0 + if (!channel) { + ALOGV("No channel allocated"); + return 0; + } + + channelID = ++mNextChannelID; + + ALOGV("play channel %p state = %d", channel, channel->state()); + channel->play(sample, channelID, leftVolume, rightVolume, priority, loop, rate); + return channelID; +} + +SoundChannel* SoundPool::allocateChannel_l(int priority) +{ + List<SoundChannel*>::iterator iter; + SoundChannel* channel = NULL; + + // allocate a channel + if (!mChannels.empty()) { + iter = mChannels.begin(); + if (priority >= (*iter)->priority()) { + channel = *iter; + mChannels.erase(iter); + ALOGV("Allocated active channel"); + } + } + + // update priority and put it back in the list + if (channel) { + channel->setPriority(priority); + for (iter = mChannels.begin(); iter != mChannels.end(); ++iter) { + if (priority < (*iter)->priority()) { + break; + } + } + mChannels.insert(iter, channel); + } + return channel; +} + +// move a channel from its current position to the front of the list +void SoundPool::moveToFront_l(SoundChannel* channel) +{ + for (List<SoundChannel*>::iterator iter = mChannels.begin(); iter != mChannels.end(); ++iter) { + if (*iter == channel) { + mChannels.erase(iter); + mChannels.push_front(channel); + break; + } + } +} + +void SoundPool::pause(int channelID) +{ + ALOGV("pause(%d)", channelID); + Mutex::Autolock lock(&mLock); + SoundChannel* channel = findChannel(channelID); + if (channel) { + channel->pause(); + } +} + +void SoundPool::autoPause() +{ + ALOGV("autoPause()"); + Mutex::Autolock lock(&mLock); + for (int i = 0; i < mMaxChannels; ++i) { + SoundChannel* channel = &mChannelPool[i]; + channel->autoPause(); + } +} + +void SoundPool::resume(int channelID) +{ + ALOGV("resume(%d)", channelID); + Mutex::Autolock lock(&mLock); + SoundChannel* channel = findChannel(channelID); + if (channel) { + channel->resume(); + } +} + +void SoundPool::autoResume() +{ + ALOGV("autoResume()"); + Mutex::Autolock lock(&mLock); + for (int i = 0; i < mMaxChannels; ++i) { + SoundChannel* channel = &mChannelPool[i]; + channel->autoResume(); + } +} + +void SoundPool::stop(int channelID) +{ + ALOGV("stop(%d)", channelID); + Mutex::Autolock lock(&mLock); + SoundChannel* channel = findChannel(channelID); + if (channel) { + channel->stop(); + } else { + channel = findNextChannel(channelID); + if (channel) + channel->clearNextEvent(); + } +} + +void SoundPool::setVolume(int channelID, float leftVolume, float rightVolume) +{ + Mutex::Autolock lock(&mLock); + SoundChannel* channel = findChannel(channelID); + if (channel) { + channel->setVolume(leftVolume, rightVolume); + } +} + +void SoundPool::setPriority(int channelID, int priority) +{ + ALOGV("setPriority(%d, %d)", channelID, priority); + Mutex::Autolock lock(&mLock); + SoundChannel* channel = findChannel(channelID); + if (channel) { + channel->setPriority(priority); + } +} + +void SoundPool::setLoop(int channelID, int loop) +{ + ALOGV("setLoop(%d, %d)", channelID, loop); + Mutex::Autolock lock(&mLock); + SoundChannel* channel = findChannel(channelID); + if (channel) { + channel->setLoop(loop); + } +} + +void SoundPool::setRate(int channelID, float rate) +{ + ALOGV("setRate(%d, %f)", channelID, rate); + Mutex::Autolock lock(&mLock); + SoundChannel* channel = findChannel(channelID); + if (channel) { + channel->setRate(rate); + } +} + +// call with lock held +void SoundPool::done_l(SoundChannel* channel) +{ + ALOGV("done_l(%d)", channel->channelID()); + // if "stolen", play next event + if (channel->nextChannelID() != 0) { + ALOGV("add to restart list"); + addToRestartList(channel); + } + + // return to idle state + else { + ALOGV("move to front"); + moveToFront_l(channel); + } +} + +void SoundPool::setCallback(SoundPoolCallback* callback, void* user) +{ + Mutex::Autolock lock(&mCallbackLock); + mCallback = callback; + mUserData = user; +} + +void SoundPool::notify(SoundPoolEvent event) +{ + Mutex::Autolock lock(&mCallbackLock); + if (mCallback != NULL) { + mCallback(event, this, mUserData); + } +} + +void SoundPool::dump() +{ + for (int i = 0; i < mMaxChannels; ++i) { + mChannelPool[i].dump(); + } +} + + +Sample::Sample(int sampleID, int fd, int64_t offset, int64_t length) +{ + init(); + mSampleID = sampleID; + mFd = dup(fd); + mOffset = offset; + mLength = length; + ALOGV("create sampleID=%d, fd=%d, offset=%" PRId64 " length=%" PRId64, + mSampleID, mFd, mLength, mOffset); +} + +void Sample::init() +{ + mSize = 0; + mRefCount = 0; + mSampleID = 0; + mState = UNLOADED; + mFd = -1; + mOffset = 0; + mLength = 0; +} + +Sample::~Sample() +{ + ALOGV("Sample::destructor sampleID=%d, fd=%d", mSampleID, mFd); + if (mFd > 0) { + ALOGV("close(%d)", mFd); + ::close(mFd); + } +} + +static status_t decode(int fd, int64_t offset, int64_t length, + uint32_t *rate, int *numChannels, audio_format_t *audioFormat, + sp<MemoryHeapBase> heap, size_t *memsize) { + + ALOGV("fd %d, offset %" PRId64 ", size %" PRId64, fd, offset, length); + AMediaExtractor *ex = AMediaExtractor_new(); + status_t err = AMediaExtractor_setDataSourceFd(ex, fd, offset, length); + + if (err != AMEDIA_OK) { + return err; + } + + *audioFormat = AUDIO_FORMAT_PCM_16_BIT; + + size_t numTracks = AMediaExtractor_getTrackCount(ex); + for (size_t i = 0; i < numTracks; i++) { + AMediaFormat *format = AMediaExtractor_getTrackFormat(ex, i); + const char *mime; + if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &mime)) { + AMediaExtractor_delete(ex); + AMediaFormat_delete(format); + return UNKNOWN_ERROR; + } + if (strncmp(mime, "audio/", 6) == 0) { + + AMediaCodec *codec = AMediaCodec_createDecoderByType(mime); + if (AMediaCodec_configure(codec, format, + NULL /* window */, NULL /* drm */, 0 /* flags */) != AMEDIA_OK + || AMediaCodec_start(codec) != AMEDIA_OK + || AMediaExtractor_selectTrack(ex, i) != AMEDIA_OK) { + AMediaExtractor_delete(ex); + AMediaCodec_delete(codec); + AMediaFormat_delete(format); + return UNKNOWN_ERROR; + } + + bool sawInputEOS = false; + bool sawOutputEOS = false; + uint8_t* writePos = static_cast<uint8_t*>(heap->getBase()); + size_t available = heap->getSize(); + size_t written = 0; + + AMediaFormat_delete(format); + format = AMediaCodec_getOutputFormat(codec); + + while (!sawOutputEOS) { + if (!sawInputEOS) { + ssize_t bufidx = AMediaCodec_dequeueInputBuffer(codec, 5000); + ALOGV("input buffer %zd", bufidx); + if (bufidx >= 0) { + size_t bufsize; + uint8_t *buf = AMediaCodec_getInputBuffer(codec, bufidx, &bufsize); + int sampleSize = AMediaExtractor_readSampleData(ex, buf, bufsize); + ALOGV("read %d", sampleSize); + if (sampleSize < 0) { + sampleSize = 0; + sawInputEOS = true; + ALOGV("EOS"); + } + int64_t presentationTimeUs = AMediaExtractor_getSampleTime(ex); + + AMediaCodec_queueInputBuffer(codec, bufidx, + 0 /* offset */, sampleSize, presentationTimeUs, + sawInputEOS ? AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM : 0); + AMediaExtractor_advance(ex); + } + } + + AMediaCodecBufferInfo info; + int status = AMediaCodec_dequeueOutputBuffer(codec, &info, 1); + ALOGV("dequeueoutput returned: %d", status); + if (status >= 0) { + if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) { + ALOGV("output EOS"); + sawOutputEOS = true; + } + ALOGV("got decoded buffer size %d", info.size); + + uint8_t *buf = AMediaCodec_getOutputBuffer(codec, status, NULL /* out_size */); + size_t dataSize = info.size; + if (dataSize > available) { + dataSize = available; + } + memcpy(writePos, buf + info.offset, dataSize); + writePos += dataSize; + written += dataSize; + available -= dataSize; + AMediaCodec_releaseOutputBuffer(codec, status, false /* render */); + if (available == 0) { + // there might be more data, but there's no space for it + sawOutputEOS = true; + } + } else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) { + ALOGV("output buffers changed"); + } else if (status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) { + AMediaFormat_delete(format); + format = AMediaCodec_getOutputFormat(codec); + ALOGV("format changed to: %s", AMediaFormat_toString(format)); + } else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) { + ALOGV("no output buffer right now"); + } else { + ALOGV("unexpected info code: %d", status); + } + } + + AMediaCodec_stop(codec); + AMediaCodec_delete(codec); + AMediaExtractor_delete(ex); + if (!AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_SAMPLE_RATE, (int32_t*) rate) || + !AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_CHANNEL_COUNT, numChannels)) { + AMediaFormat_delete(format); + return UNKNOWN_ERROR; + } + AMediaFormat_delete(format); + *memsize = written; + return OK; + } + AMediaFormat_delete(format); + } + AMediaExtractor_delete(ex); + return UNKNOWN_ERROR; +} + +status_t Sample::doLoad() +{ + uint32_t sampleRate; + int numChannels; + audio_format_t format; + status_t status; + mHeap = new MemoryHeapBase(kDefaultHeapSize); + + ALOGV("Start decode"); + status = decode(mFd, mOffset, mLength, &sampleRate, &numChannels, &format, + mHeap, &mSize); + ALOGV("close(%d)", mFd); + ::close(mFd); + mFd = -1; + if (status != NO_ERROR) { + ALOGE("Unable to load sample"); + goto error; + } + ALOGV("pointer = %p, size = %zu, sampleRate = %u, numChannels = %d", + mHeap->getBase(), mSize, sampleRate, numChannels); + + if (sampleRate > kMaxSampleRate) { + ALOGE("Sample rate (%u) out of range", sampleRate); + status = BAD_VALUE; + goto error; + } + + if ((numChannels < 1) || (numChannels > 2)) { + ALOGE("Sample channel count (%d) out of range", numChannels); + status = BAD_VALUE; + goto error; + } + + mData = new MemoryBase(mHeap, 0, mSize); + mSampleRate = sampleRate; + mNumChannels = numChannels; + mFormat = format; + mState = READY; + return NO_ERROR; + +error: + mHeap.clear(); + return status; +} + + +void SoundChannel::init(SoundPool* soundPool) +{ + mSoundPool = soundPool; +} + +// call with sound pool lock held +void SoundChannel::play(const sp<Sample>& sample, int nextChannelID, float leftVolume, + float rightVolume, int priority, int loop, float rate) +{ + sp<AudioTrack> oldTrack; + sp<AudioTrack> newTrack; + status_t status; + + { // scope for the lock + Mutex::Autolock lock(&mLock); + + ALOGV("SoundChannel::play %p: sampleID=%d, channelID=%d, leftVolume=%f, rightVolume=%f," + " priority=%d, loop=%d, rate=%f", + this, sample->sampleID(), nextChannelID, leftVolume, rightVolume, + priority, loop, rate); + + // if not idle, this voice is being stolen + if (mState != IDLE) { + ALOGV("channel %d stolen - event queued for channel %d", channelID(), nextChannelID); + mNextEvent.set(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); + stop_l(); + return; + } + + // initialize track + size_t afFrameCount; + uint32_t afSampleRate; + audio_stream_type_t streamType = audio_attributes_to_stream_type(mSoundPool->attributes()); + if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { + afFrameCount = kDefaultFrameCount; + } + if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { + afSampleRate = kDefaultSampleRate; + } + int numChannels = sample->numChannels(); + uint32_t sampleRate = uint32_t(float(sample->sampleRate()) * rate + 0.5); + size_t frameCount = 0; + + if (loop) { + frameCount = sample->size()/numChannels/ + ((sample->format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(uint8_t)); + } + +#ifndef USE_SHARED_MEM_BUFFER + uint32_t totalFrames = (kDefaultBufferCount * afFrameCount * sampleRate) / afSampleRate; + // Ensure minimum audio buffer size in case of short looped sample + if(frameCount < totalFrames) { + frameCount = totalFrames; + } +#endif + + // mToggle toggles each time a track is started on a given channel. + // The toggle is concatenated with the SoundChannel address and passed to AudioTrack + // as callback user data. This enables the detection of callbacks received from the old + // audio track while the new one is being started and avoids processing them with + // wrong audio audio buffer size (mAudioBufferSize) + unsigned long toggle = mToggle ^ 1; + void *userData = (void *)((unsigned long)this | toggle); + audio_channel_mask_t channelMask = audio_channel_out_mask_from_count(numChannels); + + // do not create a new audio track if current track is compatible with sample parameters +#ifdef USE_SHARED_MEM_BUFFER + newTrack = new AudioTrack(streamType, sampleRate, sample->format(), + channelMask, sample->getIMemory(), AUDIO_OUTPUT_FLAG_FAST, callback, userData); +#else + uint32_t bufferFrames = (totalFrames + (kDefaultBufferCount - 1)) / kDefaultBufferCount; + newTrack = new AudioTrack(streamType, sampleRate, sample->format(), + channelMask, frameCount, AUDIO_OUTPUT_FLAG_FAST, callback, userData, + bufferFrames); +#endif + oldTrack = mAudioTrack; + status = newTrack->initCheck(); + if (status != NO_ERROR) { + ALOGE("Error creating AudioTrack"); + goto exit; + } + ALOGV("setVolume %p", newTrack.get()); + newTrack->setVolume(leftVolume, rightVolume); + newTrack->setLoop(0, frameCount, loop); + + // From now on, AudioTrack callbacks received with previous toggle value will be ignored. + mToggle = toggle; + mAudioTrack = newTrack; + mPos = 0; + mSample = sample; + mChannelID = nextChannelID; + mPriority = priority; + mLoop = loop; + mLeftVolume = leftVolume; + mRightVolume = rightVolume; + mNumChannels = numChannels; + mRate = rate; + clearNextEvent(); + mState = PLAYING; + mAudioTrack->start(); + mAudioBufferSize = newTrack->frameCount()*newTrack->frameSize(); + } + +exit: + ALOGV("delete oldTrack %p", oldTrack.get()); + if (status != NO_ERROR) { + mAudioTrack.clear(); + } +} + +void SoundChannel::nextEvent() +{ + sp<Sample> sample; + int nextChannelID; + float leftVolume; + float rightVolume; + int priority; + int loop; + float rate; + + // check for valid event + { + Mutex::Autolock lock(&mLock); + nextChannelID = mNextEvent.channelID(); + if (nextChannelID == 0) { + ALOGV("stolen channel has no event"); + return; + } + + sample = mNextEvent.sample(); + leftVolume = mNextEvent.leftVolume(); + rightVolume = mNextEvent.rightVolume(); + priority = mNextEvent.priority(); + loop = mNextEvent.loop(); + rate = mNextEvent.rate(); + } + + ALOGV("Starting stolen channel %d -> %d", channelID(), nextChannelID); + play(sample, nextChannelID, leftVolume, rightVolume, priority, loop, rate); +} + +void SoundChannel::callback(int event, void* user, void *info) +{ + SoundChannel* channel = static_cast<SoundChannel*>((void *)((unsigned long)user & ~1)); + + channel->process(event, info, (unsigned long)user & 1); +} + +void SoundChannel::process(int event, void *info, unsigned long toggle) +{ + //ALOGV("process(%d)", mChannelID); + + Mutex::Autolock lock(&mLock); + + AudioTrack::Buffer* b = NULL; + if (event == AudioTrack::EVENT_MORE_DATA) { + b = static_cast<AudioTrack::Buffer *>(info); + } + + if (mToggle != toggle) { + ALOGV("process wrong toggle %p channel %d", this, mChannelID); + if (b != NULL) { + b->size = 0; + } + return; + } + + sp<Sample> sample = mSample; + +// ALOGV("SoundChannel::process event %d", event); + + if (event == AudioTrack::EVENT_MORE_DATA) { + + // check for stop state + if (b->size == 0) return; + + if (mState == IDLE) { + b->size = 0; + return; + } + + if (sample != 0) { + // fill buffer + uint8_t* q = (uint8_t*) b->i8; + size_t count = 0; + + if (mPos < (int)sample->size()) { + uint8_t* p = sample->data() + mPos; + count = sample->size() - mPos; + if (count > b->size) { + count = b->size; + } + memcpy(q, p, count); +// ALOGV("fill: q=%p, p=%p, mPos=%u, b->size=%u, count=%d", q, p, mPos, b->size, +// count); + } else if (mPos < mAudioBufferSize) { + count = mAudioBufferSize - mPos; + if (count > b->size) { + count = b->size; + } + memset(q, 0, count); +// ALOGV("fill extra: q=%p, mPos=%u, b->size=%u, count=%d", q, mPos, b->size, count); + } + + mPos += count; + b->size = count; + //ALOGV("buffer=%p, [0]=%d", b->i16, b->i16[0]); + } + } else if (event == AudioTrack::EVENT_UNDERRUN || event == AudioTrack::EVENT_BUFFER_END) { + ALOGV("process %p channel %d event %s", + this, mChannelID, (event == AudioTrack::EVENT_UNDERRUN) ? "UNDERRUN" : + "BUFFER_END"); + mSoundPool->addToStopList(this); + } else if (event == AudioTrack::EVENT_LOOP_END) { + ALOGV("End loop %p channel %d", this, mChannelID); + } else if (event == AudioTrack::EVENT_NEW_IAUDIOTRACK) { + ALOGV("process %p channel %d NEW_IAUDIOTRACK", this, mChannelID); + } else { + ALOGW("SoundChannel::process unexpected event %d", event); + } +} + + +// call with lock held +bool SoundChannel::doStop_l() +{ + if (mState != IDLE) { + setVolume_l(0, 0); + ALOGV("stop"); + mAudioTrack->stop(); + mSample.clear(); + mState = IDLE; + mPriority = IDLE_PRIORITY; + return true; + } + return false; +} + +// call with lock held and sound pool lock held +void SoundChannel::stop_l() +{ + if (doStop_l()) { + mSoundPool->done_l(this); + } +} + +// call with sound pool lock held +void SoundChannel::stop() +{ + bool stopped; + { + Mutex::Autolock lock(&mLock); + stopped = doStop_l(); + } + + if (stopped) { + mSoundPool->done_l(this); + } +} + +//FIXME: Pause is a little broken right now +void SoundChannel::pause() +{ + Mutex::Autolock lock(&mLock); + if (mState == PLAYING) { + ALOGV("pause track"); + mState = PAUSED; + mAudioTrack->pause(); + } +} + +void SoundChannel::autoPause() +{ + Mutex::Autolock lock(&mLock); + if (mState == PLAYING) { + ALOGV("pause track"); + mState = PAUSED; + mAutoPaused = true; + mAudioTrack->pause(); + } +} + +void SoundChannel::resume() +{ + Mutex::Autolock lock(&mLock); + if (mState == PAUSED) { + ALOGV("resume track"); + mState = PLAYING; + mAutoPaused = false; + mAudioTrack->start(); + } +} + +void SoundChannel::autoResume() +{ + Mutex::Autolock lock(&mLock); + if (mAutoPaused && (mState == PAUSED)) { + ALOGV("resume track"); + mState = PLAYING; + mAutoPaused = false; + mAudioTrack->start(); + } +} + +void SoundChannel::setRate(float rate) +{ + Mutex::Autolock lock(&mLock); + if (mAudioTrack != NULL && mSample != 0) { + uint32_t sampleRate = uint32_t(float(mSample->sampleRate()) * rate + 0.5); + mAudioTrack->setSampleRate(sampleRate); + mRate = rate; + } +} + +// call with lock held +void SoundChannel::setVolume_l(float leftVolume, float rightVolume) +{ + mLeftVolume = leftVolume; + mRightVolume = rightVolume; + if (mAudioTrack != NULL) + mAudioTrack->setVolume(leftVolume, rightVolume); +} + +void SoundChannel::setVolume(float leftVolume, float rightVolume) +{ + Mutex::Autolock lock(&mLock); + setVolume_l(leftVolume, rightVolume); +} + +void SoundChannel::setLoop(int loop) +{ + Mutex::Autolock lock(&mLock); + if (mAudioTrack != NULL && mSample != 0) { + uint32_t loopEnd = mSample->size()/mNumChannels/ + ((mSample->format() == AUDIO_FORMAT_PCM_16_BIT) ? sizeof(int16_t) : sizeof(uint8_t)); + mAudioTrack->setLoop(0, loopEnd, loop); + mLoop = loop; + } +} + +SoundChannel::~SoundChannel() +{ + ALOGV("SoundChannel destructor %p", this); + { + Mutex::Autolock lock(&mLock); + clearNextEvent(); + doStop_l(); + } + // do not call AudioTrack destructor with mLock held as it will wait for the AudioTrack + // callback thread to exit which may need to execute process() and acquire the mLock. + mAudioTrack.clear(); +} + +void SoundChannel::dump() +{ + ALOGV("mState = %d mChannelID=%d, mNumChannels=%d, mPos = %d, mPriority=%d, mLoop=%d", + mState, mChannelID, mNumChannels, mPos, mPriority, mLoop); +} + +void SoundEvent::set(const sp<Sample>& sample, int channelID, float leftVolume, + float rightVolume, int priority, int loop, float rate) +{ + mSample = sample; + mChannelID = channelID; + mLeftVolume = leftVolume; + mRightVolume = rightVolume; + mPriority = priority; + mLoop = loop; + mRate =rate; +} + +} // end namespace android diff --git a/media/jni/soundpool/SoundPool.h b/media/jni/soundpool/SoundPool.h new file mode 100644 index 0000000..9d9cbdf --- /dev/null +++ b/media/jni/soundpool/SoundPool.h @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOUNDPOOL_H_ +#define SOUNDPOOL_H_ + +#include <utils/threads.h> +#include <utils/List.h> +#include <utils/Vector.h> +#include <utils/KeyedVector.h> +#include <media/AudioTrack.h> +#include <binder/MemoryHeapBase.h> +#include <binder/MemoryBase.h> + +namespace android { + +static const int IDLE_PRIORITY = -1; + +// forward declarations +class SoundEvent; +class SoundPoolThread; +class SoundPool; + +// for queued events +class SoundPoolEvent { +public: + SoundPoolEvent(int msg, int arg1=0, int arg2=0) : + mMsg(msg), mArg1(arg1), mArg2(arg2) {} + int mMsg; + int mArg1; + int mArg2; + enum MessageType { INVALID, SAMPLE_LOADED }; +}; + +// callback function prototype +typedef void SoundPoolCallback(SoundPoolEvent event, SoundPool* soundPool, void* user); + +// tracks samples used by application +class Sample : public RefBase { +public: + enum sample_state { UNLOADED, LOADING, READY, UNLOADING }; + Sample(int sampleID, int fd, int64_t offset, int64_t length); + ~Sample(); + int sampleID() { return mSampleID; } + int numChannels() { return mNumChannels; } + int sampleRate() { return mSampleRate; } + audio_format_t format() { return mFormat; } + size_t size() { return mSize; } + int state() { return mState; } + uint8_t* data() { return static_cast<uint8_t*>(mData->pointer()); } + status_t doLoad(); + void startLoad() { mState = LOADING; } + sp<IMemory> getIMemory() { return mData; } + +private: + void init(); + + size_t mSize; + volatile int32_t mRefCount; + uint16_t mSampleID; + uint16_t mSampleRate; + uint8_t mState : 3; + uint8_t mNumChannels : 2; + audio_format_t mFormat; + int mFd; + int64_t mOffset; + int64_t mLength; + sp<IMemory> mData; + sp<MemoryHeapBase> mHeap; +}; + +// stores pending events for stolen channels +class SoundEvent +{ +public: + SoundEvent() : mChannelID(0), mLeftVolume(0), mRightVolume(0), + mPriority(IDLE_PRIORITY), mLoop(0), mRate(0) {} + void set(const sp<Sample>& sample, int channelID, float leftVolume, + float rightVolume, int priority, int loop, float rate); + sp<Sample> sample() { return mSample; } + int channelID() { return mChannelID; } + float leftVolume() { return mLeftVolume; } + float rightVolume() { return mRightVolume; } + int priority() { return mPriority; } + int loop() { return mLoop; } + float rate() { return mRate; } + void clear() { mChannelID = 0; mSample.clear(); } + +protected: + sp<Sample> mSample; + int mChannelID; + float mLeftVolume; + float mRightVolume; + int mPriority; + int mLoop; + float mRate; +}; + +// for channels aka AudioTracks +class SoundChannel : public SoundEvent { +public: + enum state { IDLE, RESUMING, STOPPING, PAUSED, PLAYING }; + SoundChannel() : mState(IDLE), mNumChannels(1), + mPos(0), mToggle(0), mAutoPaused(false) {} + ~SoundChannel(); + void init(SoundPool* soundPool); + void play(const sp<Sample>& sample, int channelID, float leftVolume, float rightVolume, + int priority, int loop, float rate); + void setVolume_l(float leftVolume, float rightVolume); + void setVolume(float leftVolume, float rightVolume); + void stop_l(); + void stop(); + void pause(); + void autoPause(); + void resume(); + void autoResume(); + void setRate(float rate); + int state() { return mState; } + void setPriority(int priority) { mPriority = priority; } + void setLoop(int loop); + int numChannels() { return mNumChannels; } + void clearNextEvent() { mNextEvent.clear(); } + void nextEvent(); + int nextChannelID() { return mNextEvent.channelID(); } + void dump(); + +private: + static void callback(int event, void* user, void *info); + void process(int event, void *info, unsigned long toggle); + bool doStop_l(); + + SoundPool* mSoundPool; + sp<AudioTrack> mAudioTrack; + SoundEvent mNextEvent; + Mutex mLock; + int mState; + int mNumChannels; + int mPos; + int mAudioBufferSize; + unsigned long mToggle; + bool mAutoPaused; +}; + +// application object for managing a pool of sounds +class SoundPool { + friend class SoundPoolThread; + friend class SoundChannel; +public: + SoundPool(int maxChannels, const audio_attributes_t* pAttributes); + ~SoundPool(); + int load(int fd, int64_t offset, int64_t length, int priority); + bool unload(int sampleID); + int play(int sampleID, float leftVolume, float rightVolume, int priority, + int loop, float rate); + void pause(int channelID); + void autoPause(); + void resume(int channelID); + void autoResume(); + void stop(int channelID); + void setVolume(int channelID, float leftVolume, float rightVolume); + void setPriority(int channelID, int priority); + void setLoop(int channelID, int loop); + void setRate(int channelID, float rate); + const audio_attributes_t* attributes() { return &mAttributes; } + + // called from SoundPoolThread + void sampleLoaded(int sampleID); + + // called from AudioTrack thread + void done_l(SoundChannel* channel); + + // callback function + void setCallback(SoundPoolCallback* callback, void* user); + void* getUserData() { return mUserData; } + +private: + SoundPool() {} // no default constructor + bool startThreads(); + void doLoad(sp<Sample>& sample); + sp<Sample> findSample(int sampleID) { return mSamples.valueFor(sampleID); } + SoundChannel* findChannel (int channelID); + SoundChannel* findNextChannel (int channelID); + SoundChannel* allocateChannel_l(int priority); + void moveToFront_l(SoundChannel* channel); + void notify(SoundPoolEvent event); + void dump(); + + // restart thread + void addToRestartList(SoundChannel* channel); + void addToStopList(SoundChannel* channel); + static int beginThread(void* arg); + int run(); + void quit(); + + Mutex mLock; + Mutex mRestartLock; + Condition mCondition; + SoundPoolThread* mDecodeThread; + SoundChannel* mChannelPool; + List<SoundChannel*> mChannels; + List<SoundChannel*> mRestart; + List<SoundChannel*> mStop; + DefaultKeyedVector< int, sp<Sample> > mSamples; + int mMaxChannels; + audio_attributes_t mAttributes; + int mAllocated; + int mNextSampleID; + int mNextChannelID; + bool mQuit; + + // callback + Mutex mCallbackLock; + SoundPoolCallback* mCallback; + void* mUserData; +}; + +} // end namespace android + +#endif /*SOUNDPOOL_H_*/ diff --git a/media/jni/soundpool/SoundPoolThread.cpp b/media/jni/soundpool/SoundPoolThread.cpp new file mode 100644 index 0000000..ba3b482 --- /dev/null +++ b/media/jni/soundpool/SoundPoolThread.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "SoundPoolThread" +#include "utils/Log.h" + +#include "SoundPoolThread.h" + +namespace android { + +void SoundPoolThread::write(SoundPoolMsg msg) { + Mutex::Autolock lock(&mLock); + while (mMsgQueue.size() >= maxMessages) { + mCondition.wait(mLock); + } + + // if thread is quitting, don't add to queue + if (mRunning) { + mMsgQueue.push(msg); + mCondition.signal(); + } +} + +const SoundPoolMsg SoundPoolThread::read() { + Mutex::Autolock lock(&mLock); + while (mMsgQueue.size() == 0) { + mCondition.wait(mLock); + } + SoundPoolMsg msg = mMsgQueue[0]; + mMsgQueue.removeAt(0); + mCondition.signal(); + return msg; +} + +void SoundPoolThread::quit() { + Mutex::Autolock lock(&mLock); + if (mRunning) { + mRunning = false; + mMsgQueue.clear(); + mMsgQueue.push(SoundPoolMsg(SoundPoolMsg::KILL, 0)); + mCondition.signal(); + mCondition.wait(mLock); + } + ALOGV("return from quit"); +} + +SoundPoolThread::SoundPoolThread(SoundPool* soundPool) : + mSoundPool(soundPool) +{ + mMsgQueue.setCapacity(maxMessages); + if (createThreadEtc(beginThread, this, "SoundPoolThread")) { + mRunning = true; + } +} + +SoundPoolThread::~SoundPoolThread() +{ + quit(); +} + +int SoundPoolThread::beginThread(void* arg) { + ALOGV("beginThread"); + SoundPoolThread* soundPoolThread = (SoundPoolThread*)arg; + return soundPoolThread->run(); +} + +int SoundPoolThread::run() { + ALOGV("run"); + for (;;) { + SoundPoolMsg msg = read(); + ALOGV("Got message m=%d, mData=%d", msg.mMessageType, msg.mData); + switch (msg.mMessageType) { + case SoundPoolMsg::KILL: + ALOGV("goodbye"); + return NO_ERROR; + case SoundPoolMsg::LOAD_SAMPLE: + doLoadSample(msg.mData); + break; + default: + ALOGW("run: Unrecognized message %d\n", + msg.mMessageType); + break; + } + } +} + +void SoundPoolThread::loadSample(int sampleID) { + write(SoundPoolMsg(SoundPoolMsg::LOAD_SAMPLE, sampleID)); +} + +void SoundPoolThread::doLoadSample(int sampleID) { + sp <Sample> sample = mSoundPool->findSample(sampleID); + status_t status = -1; + if (sample != 0) { + status = sample->doLoad(); + } + mSoundPool->notify(SoundPoolEvent(SoundPoolEvent::SAMPLE_LOADED, sampleID, status)); +} + +} // end namespace android diff --git a/media/jni/soundpool/SoundPoolThread.h b/media/jni/soundpool/SoundPoolThread.h new file mode 100644 index 0000000..d388388 --- /dev/null +++ b/media/jni/soundpool/SoundPoolThread.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SOUNDPOOLTHREAD_H_ +#define SOUNDPOOLTHREAD_H_ + +#include <utils/threads.h> +#include <utils/Vector.h> +#include <media/AudioTrack.h> + +#include "SoundPool.h" + +namespace android { + +class SoundPoolMsg { +public: + enum MessageType { INVALID, KILL, LOAD_SAMPLE }; + SoundPoolMsg() : mMessageType(INVALID), mData(0) {} + SoundPoolMsg(MessageType MessageType, int data) : + mMessageType(MessageType), mData(data) {} + uint16_t mMessageType; + uint16_t mData; +}; + +/* + * This class handles background requests from the SoundPool + */ +class SoundPoolThread { +public: + SoundPoolThread(SoundPool* SoundPool); + ~SoundPoolThread(); + void loadSample(int sampleID); + void quit(); + void write(SoundPoolMsg msg); + +private: + static const size_t maxMessages = 5; + + static int beginThread(void* arg); + int run(); + void doLoadSample(int sampleID); + const SoundPoolMsg read(); + + Mutex mLock; + Condition mCondition; + Vector<SoundPoolMsg> mMsgQueue; + SoundPool* mSoundPool; + bool mRunning; +}; + +} // end namespace android + +#endif /*SOUNDPOOLTHREAD_H_*/ diff --git a/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp b/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp index 89b2893..b2333f8 100644 --- a/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp +++ b/media/jni/soundpool/android_media_SoundPool_SoundPoolImpl.cpp @@ -23,7 +23,7 @@ #include <nativehelper/jni.h> #include <nativehelper/JNIHelp.h> #include <android_runtime/AndroidRuntime.h> -#include <media/SoundPool.h> +#include "SoundPool.h" using namespace android; @@ -45,20 +45,6 @@ struct audio_attributes_fields_t { static audio_attributes_fields_t javaAudioAttrFields; // ---------------------------------------------------------------------------- -static jint -android_media_SoundPool_SoundPoolImpl_load_URL(JNIEnv *env, jobject thiz, jstring path, jint priority) -{ - ALOGV("android_media_SoundPool_SoundPoolImpl_load_URL"); - SoundPool *ap = MusterSoundPool(env, thiz); - if (path == NULL) { - jniThrowException(env, "java/lang/IllegalArgumentException", NULL); - return 0; - } - const char* s = env->GetStringUTFChars(path, NULL); - int id = ap->load(s, priority); - env->ReleaseStringUTFChars(path, s); - return (jint) id; -} static jint android_media_SoundPool_SoundPoolImpl_load_FD(JNIEnv *env, jobject thiz, jobject fileDescriptor, @@ -231,14 +217,14 @@ android_media_SoundPool_SoundPoolImpl_release(JNIEnv *env, jobject thiz) SoundPool *ap = MusterSoundPool(env, thiz); if (ap != NULL) { - // release weak reference + // release weak reference and clear callback jobject weakRef = (jobject) ap->getUserData(); + ap->setCallback(NULL, NULL); if (weakRef != NULL) { env->DeleteGlobalRef(weakRef); } - // clear callback and native context - ap->setCallback(NULL, NULL); + // clear native context env->SetLongField(thiz, fields.mNativeContext, 0); delete ap; } @@ -249,10 +235,6 @@ android_media_SoundPool_SoundPoolImpl_release(JNIEnv *env, jobject thiz) // Dalvik VM type signatures static JNINativeMethod gMethods[] = { { "_load", - "(Ljava/lang/String;I)I", - (void *)android_media_SoundPool_SoundPoolImpl_load_URL - }, - { "_load", "(Ljava/io/FileDescriptor;JJI)I", (void *)android_media_SoundPool_SoundPoolImpl_load_FD }, @@ -312,7 +294,7 @@ static JNINativeMethod gMethods[] = { static const char* const kClassPathName = "android/media/SoundPool$SoundPoolImpl"; -jint JNI_OnLoad(JavaVM* vm, void* reserved) +jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) { JNIEnv* env = NULL; jint result = -1; diff --git a/media/mca/filterfw/Android.mk b/media/mca/filterfw/Android.mk index 2a9448d..334f4e2 100644 --- a/media/mca/filterfw/Android.mk +++ b/media/mca/filterfw/Android.mk @@ -22,6 +22,7 @@ include $(all-subdir-makefiles) # Build main libfilterfw include $(CLEAR_VARS) +LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk LOCAL_MODULE := libfilterfw @@ -30,7 +31,7 @@ LOCAL_MODULE_TAGS := optional LOCAL_WHOLE_STATIC_LIBRARIES := libfilterfw_jni \ libfilterfw_native -LOCAL_SHARED_LIBRARIES := libstlport \ +LOCAL_SHARED_LIBRARIES := \ libGLESv2 \ libEGL \ libgui \ @@ -42,10 +43,4 @@ LOCAL_SHARED_LIBRARIES := libstlport \ libjnigraphics \ libmedia -# Don't prelink this library. For more efficient code, you may want -# to add this library to the prelink map and set this to true. However, -# it's difficult to do this for applications that are not supplied as -# part of a system image. -LOCAL_PRELINK_MODULE := false - include $(BUILD_SHARED_LIBRARY) diff --git a/media/mca/filterfw/java/android/filterfw/geometry/Point.java b/media/mca/filterfw/java/android/filterfw/geometry/Point.java index 8207c72c..4682a0d 100644 --- a/media/mca/filterfw/java/android/filterfw/geometry/Point.java +++ b/media/mca/filterfw/java/android/filterfw/geometry/Point.java @@ -70,7 +70,7 @@ public class Point { } public float length() { - return (float)Math.sqrt(x*x + y*y); + return (float)Math.hypot(x, y); } public float distanceTo(Point p) { diff --git a/media/mca/filterfw/jni/Android.mk b/media/mca/filterfw/jni/Android.mk index 5aa5af1..cba4e7e 100644 --- a/media/mca/filterfw/jni/Android.mk +++ b/media/mca/filterfw/jni/Android.mk @@ -38,14 +38,9 @@ include $(LOCAL_PATH)/../native/libfilterfw.mk # Also need the JNI headers. LOCAL_C_INCLUDES += \ - $(JNI_H_INCLUDE) \ - $(LOCAL_PATH)/.. + $(JNI_H_INCLUDE) \ + $(LOCAL_PATH)/.. -# Don't prelink this library. For more efficient code, you may want -# to add this library to the prelink map and set this to true. However, -# it's difficult to do this for applications that are not supplied as -# part of a system image. -LOCAL_PRELINK_MODULE := false +LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code -Wno-unused-parameter include $(BUILD_STATIC_LIBRARY) - diff --git a/media/mca/filterfw/jni/jni_gl_environment.cpp b/media/mca/filterfw/jni/jni_gl_environment.cpp index 6da7b7c..5f00739 100644 --- a/media/mca/filterfw/jni/jni_gl_environment.cpp +++ b/media/mca/filterfw/jni/jni_gl_environment.cpp @@ -20,8 +20,8 @@ #include "jni/jni_gl_environment.h" #include "jni/jni_util.h" -#include <media/mediarecorder.h> #include "native/core/gl_env.h" +#include <media/mediarecorder.h> #include <gui/IGraphicBufferProducer.h> #include <gui/Surface.h> @@ -92,8 +92,8 @@ jboolean Java_android_filterfw_core_GLEnvironment_nativeIsContextActive(JNIEnv* return gl_env ? ToJBool(gl_env->IsContextActive()) : JNI_FALSE; } -jboolean Java_android_filterfw_core_GLEnvironment_nativeIsAnyContextActive(JNIEnv* env, - jclass clazz) { +jboolean Java_android_filterfw_core_GLEnvironment_nativeIsAnyContextActive(JNIEnv* /* env */, + jclass /* clazz */) { return ToJBool(GLEnv::IsAnyContextActive()); } diff --git a/media/mca/filterfw/jni/jni_init.cpp b/media/mca/filterfw/jni/jni_init.cpp index 3b131f1..956a5a5 100644 --- a/media/mca/filterfw/jni/jni_init.cpp +++ b/media/mca/filterfw/jni/jni_init.cpp @@ -27,7 +27,7 @@ using namespace android::filterfw; JavaVM* g_current_java_vm_ = NULL; -jint JNI_OnLoad(JavaVM* vm, void* reserved) { +jint JNI_OnLoad(JavaVM* vm, void* /* reserved */) { // Set the current vm pointer g_current_java_vm_ = vm; diff --git a/media/mca/filterfw/jni/jni_util.h b/media/mca/filterfw/jni/jni_util.h index 68ff653..11c0871 100644 --- a/media/mca/filterfw/jni/jni_util.h +++ b/media/mca/filterfw/jni/jni_util.h @@ -16,7 +16,7 @@ #include <jni.h> -#include <hash_map> +#include <unordered_map> #include <string> #include "base/utilities.h" @@ -188,8 +188,8 @@ class ObjectPool { id_field_name_(id_fld_name), next_id_(0) { } - typedef std::hash_map<int, T*> CObjMap; - typedef std::hash_map<int, bool> FlagMap; + typedef std::unordered_map<int, T*> CObjMap; + typedef std::unordered_map<int, bool> FlagMap; static ObjectPool* instance_; std::string jclass_name_; std::string id_field_name_; diff --git a/media/mca/filterfw/native/Android.mk b/media/mca/filterfw/native/Android.mk index 46ee283..7c4703f 100644 --- a/media/mca/filterfw/native/Android.mk +++ b/media/mca/filterfw/native/Android.mk @@ -39,6 +39,8 @@ include $(LOCAL_PATH)/libfilterfw.mk # gcc should always be placed at the end. LOCAL_EXPORT_LDLIBS := -llog -lgcc +LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code + # TODO: Build a shared library as well? include $(BUILD_STATIC_LIBRARY) diff --git a/media/mca/filterfw/native/core/shader_program.cpp b/media/mca/filterfw/native/core/shader_program.cpp index d92eb31..1e573fb 100644 --- a/media/mca/filterfw/native/core/shader_program.cpp +++ b/media/mca/filterfw/native/core/shader_program.cpp @@ -30,9 +30,6 @@ namespace android { namespace filterfw { -// VBO attachment keys -static const int kDefaultVboKey = 1; - static const char* s_default_vertex_shader_source_ = "attribute vec4 a_position;\n" "attribute vec2 a_texcoord;\n" @@ -55,10 +52,6 @@ static void GetTileCoords(const float* b, float x, float y, float* xt, float* yt *yt = w0 * b[1] + w1 * b[3] + w2 * b[5] + w3 * b[7]; } -static inline float AdjustRatio(float current, float next) { - return (current + next) / 2.0; -} - // VertexAttrib implementation ///////////////////////////////////////////////// ShaderProgram::VertexAttrib::VertexAttrib() : is_const(true), @@ -318,15 +311,15 @@ GLuint ShaderProgram::CompileShader(GLenum shader_type, const char* source) { ALOGE("Problem compiling shader! Source:"); ALOGE("%s", source); std::string src(source); - unsigned int cur_pos = 0; - unsigned int next_pos = 0; - int line_number = 1; + size_t cur_pos = 0; + size_t next_pos = 0; + size_t line_number = 1; while ( (next_pos = src.find_first_of('\n', cur_pos)) != std::string::npos) { - ALOGE("%03d : %s", line_number, src.substr(cur_pos, next_pos-cur_pos).c_str()); + ALOGE("%03zd : %s", line_number, src.substr(cur_pos, next_pos-cur_pos).c_str()); cur_pos = next_pos + 1; line_number++; } - ALOGE("%03d : %s", line_number, src.substr(cur_pos, next_pos-cur_pos).c_str()); + ALOGE("%03zu : %s", line_number, src.substr(cur_pos, next_pos-cur_pos).c_str()); GLint log_length = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &log_length); @@ -442,7 +435,7 @@ bool ShaderProgram::BindInputTextures(const std::vector<GLuint>& textures, if (tex_var >= 0) { glUniform1i(tex_var, i); } else { - ALOGE("ShaderProgram: Shader does not seem to support %d number of " + ALOGE("ShaderProgram: Shader does not seem to support %zd number of " "inputs! Missing uniform 'tex_sampler_%d'!", textures.size(), i); return false; } diff --git a/media/mca/filterfw/native/core/value.cpp b/media/mca/filterfw/native/core/value.cpp index 04bf0ef..c0ea763 100644 --- a/media/mca/filterfw/native/core/value.cpp +++ b/media/mca/filterfw/native/core/value.cpp @@ -16,6 +16,7 @@ #include <stddef.h> #include <stdlib.h> +#include <string.h> #include "value.h" diff --git a/media/mca/filterfw/native/core/vertex_frame.cpp b/media/mca/filterfw/native/core/vertex_frame.cpp index 822573f..9fb9eaa 100644 --- a/media/mca/filterfw/native/core/vertex_frame.cpp +++ b/media/mca/filterfw/native/core/vertex_frame.cpp @@ -25,10 +25,6 @@ namespace android { namespace filterfw { -// GL Extensions that are dynamically looked up at runtime -static PFNGLMAPBUFFEROESPROC GLMapBufferOES = NULL; -static PFNGLUNMAPBUFFEROESPROC GLUnmapBufferOES = NULL; - VertexFrame::VertexFrame(int size) : vbo_(0), size_(size) { diff --git a/media/mca/filterfw/native/libfilterfw.mk b/media/mca/filterfw/native/libfilterfw.mk index 4e88e6f..69227ce 100644 --- a/media/mca/filterfw/native/libfilterfw.mk +++ b/media/mca/filterfw/native/libfilterfw.mk @@ -18,9 +18,6 @@ FFW_PATH := $(call my-dir) # Uncomment the requirements below, once we need them: -# STLport -include external/stlport/libstlport.mk - # Neven FaceDetect SDK #LOCAL_C_INCLUDES += external/neven/FaceRecEm/common/src/b_FDSDK \ # external/neven/FaceRecEm/common/src \ diff --git a/media/mca/filterpacks/Android.mk b/media/mca/filterpacks/Android.mk index 6e54f60..0ff7658 100644 --- a/media/mca/filterpacks/Android.mk +++ b/media/mca/filterpacks/Android.mk @@ -28,7 +28,7 @@ LOCAL_SRC_FILES := native/base/geometry.cpp \ LOCAL_CFLAGS := -DANDROID -include external/stlport/libstlport.mk +LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code include $(BUILD_STATIC_LIBRARY) @@ -48,6 +48,6 @@ LOCAL_SRC_FILES += native/imageproc/brightness.c \ LOCAL_SHARED_LIBRARIES := liblog libutils libfilterfw -LOCAL_PRELINK_MODULE := false +LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code include $(BUILD_SHARED_LIBRARY) diff --git a/media/mca/filterpacks/native/imageproc/brightness.c b/media/mca/filterpacks/native/imageproc/brightness.c index f4addf1..3c3652f 100644 --- a/media/mca/filterpacks/native/imageproc/brightness.c +++ b/media/mca/filterpacks/native/imageproc/brightness.c @@ -16,6 +16,7 @@ #include <android/log.h> #include <stdlib.h> +#include <string.h> #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "MCA", __VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, "MCA", __VA_ARGS__) diff --git a/media/mca/filterpacks/native/imageproc/contrast.c b/media/mca/filterpacks/native/imageproc/contrast.c index ea8c8d2..31c975c 100644 --- a/media/mca/filterpacks/native/imageproc/contrast.c +++ b/media/mca/filterpacks/native/imageproc/contrast.c @@ -16,6 +16,7 @@ #include <android/log.h> #include <stdlib.h> +#include <string.h> #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "MCA", __VA_ARGS__) #define LOGW(...) __android_log_print(ANDROID_LOG_WARN, "MCA", __VA_ARGS__) diff --git a/media/mca/filterpacks/native/imageproc/invert.c b/media/mca/filterpacks/native/imageproc/invert.c index 5938aac..f5f9e27 100644 --- a/media/mca/filterpacks/native/imageproc/invert.c +++ b/media/mca/filterpacks/native/imageproc/invert.c @@ -16,12 +16,14 @@ #include <android/log.h> +#define ATTRIBUTE_UNUSED __attribute__((unused)) + int invert_process(const char** inputs, const int* input_sizes, int input_count, char* output, int output_size, - void* user_data) { + void* user_data ATTRIBUTE_UNUSED) { // Make sure we have exactly one input if (input_count != 1) return 0; diff --git a/media/mca/filterpacks/native/imageproc/to_rgba.c b/media/mca/filterpacks/native/imageproc/to_rgba.c index bf4db2a..80094c0 100644 --- a/media/mca/filterpacks/native/imageproc/to_rgba.c +++ b/media/mca/filterpacks/native/imageproc/to_rgba.c @@ -16,12 +16,14 @@ #include <stdlib.h> +#define ATTRIBUTE_UNUSED __attribute__((unused)) + int gray_to_rgb_process(const char** inputs, const int* input_sizes, int input_count, char* output, int output_size, - void* user_data) { + void* user_data ATTRIBUTE_UNUSED) { // Make sure we have exactly one input if (input_count != 1) return 0; @@ -52,7 +54,7 @@ int rgba_to_rgb_process(const char** inputs, int input_count, char* output, int output_size, - void* user_data) { + void* user_data ATTRIBUTE_UNUSED) { // Make sure we have exactly one input if (input_count != 1) return 0; @@ -84,7 +86,7 @@ int gray_to_rgba_process(const char** inputs, int input_count, char* output, int output_size, - void* user_data) { + void* user_data ATTRIBUTE_UNUSED) { // Make sure we have exactly one input if (input_count != 1) return 0; @@ -116,7 +118,7 @@ int rgb_to_rgba_process(const char** inputs, int input_count, char* output, int output_size, - void* user_data) { + void* user_data ATTRIBUTE_UNUSED) { // Make sure we have exactly one input if (input_count != 1) return 0; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java index e6f0aaf..d12ef2e 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraFunctionalTest.java @@ -37,7 +37,6 @@ import android.os.Handler; import android.os.Looper; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.LargeTest; -import android.util.FloatMath; import android.util.Log; import android.view.SurfaceHolder; import com.android.mediaframeworktest.CameraStressTestRunner; diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java index 61b708a..8f67598 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/camera/CameraPairwiseTest.java @@ -24,7 +24,6 @@ import android.os.Handler; import android.os.Looper; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.LargeTest; -import android.util.FloatMath; import android.util.Log; import android.view.SurfaceHolder; diff --git a/media/tests/audiotests/Android.mk b/media/tests/audiotests/Android.mk index 69f0bb5..794e7f22 100644 --- a/media/tests/audiotests/Android.mk +++ b/media/tests/audiotests/Android.mk @@ -1,21 +1,23 @@ -ifeq ($(TARGET_ARCH),arm) LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE:= shared_mem_test + LOCAL_SRC_FILES := \ - shared_mem_test.cpp + shared_mem_test.cpp + LOCAL_SHARED_LIBRARIES := \ - libc \ - libcutils \ - libutils \ - libbinder \ - libhardware_legacy \ - libmedia + libc \ + libcutils \ + libutils \ + libbinder \ + libhardware_legacy \ + libmedia + LOCAL_MODULE_TAGS := tests -include $(BUILD_EXECUTABLE) +LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code -endif +include $(BUILD_EXECUTABLE) diff --git a/media/tests/audiotests/shared_mem_test.cpp b/media/tests/audiotests/shared_mem_test.cpp index 992c900..2f57499 100644 --- a/media/tests/audiotests/shared_mem_test.cpp +++ b/media/tests/audiotests/shared_mem_test.cpp @@ -133,12 +133,8 @@ int AudioTrackTest::Test01() { ************************************************************/ void AudioTrackTest::Generate(short *buffer, long bufferSz, long amplitude, unsigned long &phi, long dPhi) { - long pi13 = 25736; // 2^13*pi // fill buffer for(int i0=0; i0<bufferSz; i0++) { - long sample; - long l0, l1; - buffer[i0] = ComputeSine( amplitude, phi); phi += dPhi; } @@ -210,7 +206,7 @@ int main() { * global main * ************************************************************/ -int main(int argc, char *argv[]) { +int main() { return android::main(); } diff --git a/media/tests/players/Android.mk b/media/tests/players/Android.mk index adf0d30..7ab6458 100644 --- a/media/tests/players/Android.mk +++ b/media/tests/players/Android.mk @@ -26,5 +26,6 @@ LOCAL_SHARED_LIBRARIES:= \ LOCAL_MODULE:= invoke_mock_media_player LOCAL_MODULE_TAGS := tests eng +LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code include $(BUILD_SHARED_LIBRARY) diff --git a/media/tests/players/invoke_mock_media_player.cpp b/media/tests/players/invoke_mock_media_player.cpp index d1fed7bb..0d0c7ad 100644 --- a/media/tests/players/invoke_mock_media_player.cpp +++ b/media/tests/players/invoke_mock_media_player.cpp @@ -58,7 +58,7 @@ class Player: public MediaPlayerBase virtual bool hardwareOutput() {return true;} virtual status_t setDataSource( - const sp<IMediaHTTPService> &httpService, + const sp<IMediaHTTPService>& /* httpService */, const char *url, const KeyedVector<String8, String8> *) { ALOGV("setDataSource %s", url); @@ -69,24 +69,28 @@ class Player: public MediaPlayerBase return OK; } - virtual status_t setDataSource(int fd, int64_t offset, int64_t length) {return OK;} + virtual status_t setDataSource(int /* fd */, int64_t /* offset */, int64_t /* length */) { + return OK; + } virtual status_t setVideoSurfaceTexture( - const sp<IGraphicBufferProducer>& bufferProducer) {return OK;} - virtual status_t prepare() {return OK;} - virtual status_t prepareAsync() {return OK;} - virtual status_t start() {return OK;} - virtual status_t stop() {return OK;} - virtual status_t pause() {return OK;} - virtual bool isPlaying() {return true;} - virtual status_t seekTo(int msec) {return OK;} - virtual status_t getCurrentPosition(int *msec) {return OK;} - virtual status_t getDuration(int *msec) {return OK;} + const sp<IGraphicBufferProducer>& /* bufferProducer */) { + return OK; + } + virtual status_t prepare() { return OK; } + virtual status_t prepareAsync() { return OK; } + virtual status_t start() { return OK; } + virtual status_t stop() { return OK; } + virtual status_t pause() { return OK; } + virtual bool isPlaying() { return true; } + virtual status_t seekTo(int /* msec */) { return OK; } + virtual status_t getCurrentPosition(int* /* msec */) { return OK; } + virtual status_t getDuration(int* /* msec */) { return OK; } virtual status_t reset() {return OK;} - virtual status_t setLooping(int loop) {return OK;} + virtual status_t setLooping(int /* loop */) { return OK; } virtual player_type playerType() {return TEST_PLAYER;} virtual status_t invoke(const Parcel& request, Parcel *reply); - virtual status_t setParameter(int key, const Parcel &request) {return OK;} - virtual status_t getParameter(int key, Parcel *reply) {return OK;} + virtual status_t setParameter(int /* key */, const Parcel& /* request */) { return OK; } + virtual status_t getParameter(int /* key */, Parcel* /* reply */) { return OK; } private: |