Merge "mediacodec-x86.policy: Allow media.omx to call statfs64 on x86 platform"
diff --git a/camera/ndk/include/camera/NdkCameraCaptureSession.h b/camera/ndk/include/camera/NdkCameraCaptureSession.h
index 9bf8247..5e0db60 100644
--- a/camera/ndk/include/camera/NdkCameraCaptureSession.h
+++ b/camera/ndk/include/camera/NdkCameraCaptureSession.h
@@ -45,6 +45,8 @@
__BEGIN_DECLS
+#if __ANDROID_API__ >= 24
+
/**
* ACameraCaptureSession is an opaque type that manages frame captures of a camera device.
*
@@ -591,6 +593,10 @@
camera_status_t ACameraCaptureSession_abortCaptures(ACameraCaptureSession* session)
__INTRODUCED_IN(24);
+#endif /* __ANDROID_API__ >= 24 */
+
+#if __ANDROID_API__ >= 28
+
typedef struct ACaptureSessionOutput ACaptureSessionOutput;
/**
@@ -635,6 +641,7 @@
*/
camera_status_t ACameraCaptureSession_updateSharedOutput(ACameraCaptureSession* session,
ACaptureSessionOutput* output) __INTRODUCED_IN(28);
+#endif /* __ANDROID_API__ >= 28 */
__END_DECLS
diff --git a/camera/ndk/include/camera/NdkCameraDevice.h b/camera/ndk/include/camera/NdkCameraDevice.h
index bdd27f9..7c13b34 100644
--- a/camera/ndk/include/camera/NdkCameraDevice.h
+++ b/camera/ndk/include/camera/NdkCameraDevice.h
@@ -44,6 +44,8 @@
__BEGIN_DECLS
+#if __ANDROID_API__ >= 24
+
/**
* ACameraDevice is opaque type that provides access to a camera device.
*
@@ -666,6 +668,10 @@
const ACameraCaptureSession_stateCallbacks* callbacks,
/*out*/ACameraCaptureSession** session) __INTRODUCED_IN(24);
+#endif /* __ANDROID_API__ >= 24 */
+
+#if __ANDROID_API__ >= 28
+
/**
* Create a shared ACaptureSessionOutput object.
*
@@ -757,6 +763,8 @@
const ACameraCaptureSession_stateCallbacks* callbacks,
/*out*/ACameraCaptureSession** session) __INTRODUCED_IN(28);
+#endif /* __ANDROID_API__ >= 28 */
+
__END_DECLS
#endif /* _NDK_CAMERA_DEVICE_H */
diff --git a/camera/ndk/include/camera/NdkCameraError.h b/camera/ndk/include/camera/NdkCameraError.h
index e19ce36..6b58155 100644
--- a/camera/ndk/include/camera/NdkCameraError.h
+++ b/camera/ndk/include/camera/NdkCameraError.h
@@ -40,6 +40,8 @@
__BEGIN_DECLS
+#if __ANDROID_API__ >= 24
+
typedef enum {
ACAMERA_OK = 0,
@@ -130,6 +132,8 @@
ACAMERA_ERROR_PERMISSION_DENIED = ACAMERA_ERROR_BASE - 13,
} camera_status_t;
+#endif /* __ANDROID_API__ >= 24 */
+
__END_DECLS
#endif /* _NDK_CAMERA_ERROR_H */
diff --git a/camera/ndk/include/camera/NdkCameraManager.h b/camera/ndk/include/camera/NdkCameraManager.h
index a1cca4d..ea76738 100644
--- a/camera/ndk/include/camera/NdkCameraManager.h
+++ b/camera/ndk/include/camera/NdkCameraManager.h
@@ -44,6 +44,8 @@
__BEGIN_DECLS
+#if __ANDROID_API__ >= 24
+
/**
* ACameraManager is opaque type that provides access to camera service.
*
@@ -119,7 +121,7 @@
* this callback returns.
*/
typedef void (*ACameraManager_AvailabilityCallback)(void* context,
- const char* cameraId) __INTRODUCED_IN(24);
+ const char* cameraId);
/**
* A listener for camera devices becoming available or unavailable to open.
@@ -274,6 +276,8 @@
ACameraDevice_StateCallbacks* callback,
/*out*/ACameraDevice** device) __INTRODUCED_IN(24);
+#endif /* __ANDROID_API__ >= 24 */
+
__END_DECLS
#endif /* _NDK_CAMERA_MANAGER_H */
diff --git a/camera/ndk/include/camera/NdkCameraMetadata.h b/camera/ndk/include/camera/NdkCameraMetadata.h
index 2078da7..611e270 100644
--- a/camera/ndk/include/camera/NdkCameraMetadata.h
+++ b/camera/ndk/include/camera/NdkCameraMetadata.h
@@ -44,6 +44,8 @@
__BEGIN_DECLS
+#if __ANDROID_API__ >= 24
+
/**
* ACameraMetadata is opaque type that provides access to read-only camera metadata like camera
* characteristics (via {@link ACameraManager_getCameraCharacteristics}) or capture results (via
@@ -229,6 +231,8 @@
*/
void ACameraMetadata_free(ACameraMetadata* metadata) __INTRODUCED_IN(24);
+#endif /* __ANDROID_API__ >= 24 */
+
__END_DECLS
#endif /* _NDK_CAMERA_METADATA_H */
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index 7398f78..0501006 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -40,6 +40,8 @@
__BEGIN_DECLS
+#if __ANDROID_API__ >= 24
+
typedef enum acamera_metadata_section {
ACAMERA_COLOR_CORRECTION,
ACAMERA_CONTROL,
@@ -5092,12 +5094,26 @@
* the following code snippet can be used:</p>
* <pre><code>// Returns true if the device supports the required hardware level, or better.
* boolean isHardwareLevelSupported(CameraCharacteristics c, int requiredLevel) {
+ * final int[] sortedHwLevels = {
+ * CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY,
+ * CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL,
+ * CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED,
+ * CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_FULL,
+ * CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_3
+ * };
* int deviceLevel = c.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
- * if (deviceLevel == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
- * return requiredLevel == deviceLevel;
+ * if (requiredLevel == deviceLevel) {
+ * return true;
* }
- * // deviceLevel is not LEGACY, can use numerical sort
- * return requiredLevel <= deviceLevel;
+ *
+ * for (int sortedlevel : sortedHwLevels) {
+ * if (sortedlevel == requiredLevel) {
+ * return true;
+ * } else if (sortedlevel == deviceLevel) {
+ * return false;
+ * }
+ * }
+ * return false; // Should never reach here
* }
* </code></pre>
* <p>At a high level, the levels are:</p>
@@ -5111,6 +5127,8 @@
* post-processing settings, and image capture at a high rate.</li>
* <li><code>LEVEL_3</code> devices additionally support YUV reprocessing and RAW image capture, along
* with additional output stream configurations.</li>
+ * <li><code>EXTERNAL</code> devices are similar to <code>LIMITED</code> devices with exceptions like some sensor or
+ * lens information not reorted or less stable framerates.</li>
* </ul>
* <p>See the individual level enums for full descriptions of the supported capabilities. The
* ACAMERA_REQUEST_AVAILABLE_CAPABILITIES entry describes the device's capabilities at a
@@ -7878,6 +7896,9 @@
} acamera_metadata_enum_android_distortion_correction_mode_t;
+
+#endif /* __ANDROID_API__ >= 24 */
+
__END_DECLS
#endif /* _NDK_CAMERA_METADATA_TAGS_H */
diff --git a/camera/ndk/include/camera/NdkCaptureRequest.h b/camera/ndk/include/camera/NdkCaptureRequest.h
index 2fb5d12..5340e76 100644
--- a/camera/ndk/include/camera/NdkCaptureRequest.h
+++ b/camera/ndk/include/camera/NdkCaptureRequest.h
@@ -44,6 +44,8 @@
__BEGIN_DECLS
+#if __ANDROID_API__ >= 24
+
// Container for output targets
typedef struct ACameraOutputTargets ACameraOutputTargets;
@@ -302,6 +304,10 @@
*/
void ACaptureRequest_free(ACaptureRequest* request) __INTRODUCED_IN(24);
+#endif /* __ANDROID_API__ >= 24 */
+
+#if __ANDROID_API__ >= 28
+
/**
* Associate an arbitrary user context pointer to the {@link ACaptureRequest}
*
@@ -350,6 +356,8 @@
*/
ACaptureRequest* ACaptureRequest_copy(const ACaptureRequest* src) __INTRODUCED_IN(28);
+#endif /* __ANDROID_API__ >= 28 */
+
__END_DECLS
#endif /* _NDK_CAPTURE_REQUEST_H */
diff --git a/include/media/EventLog.h b/include/media/EventLog.h
new file mode 120000
index 0000000..9b2c4bf
--- /dev/null
+++ b/include/media/EventLog.h
@@ -0,0 +1 @@
+../../media/utils/include/mediautils/EventLog.h
\ No newline at end of file
diff --git a/include/media/TimeCheck.h b/include/media/TimeCheck.h
index e3ef134..85e17f9 120000
--- a/include/media/TimeCheck.h
+++ b/include/media/TimeCheck.h
@@ -1 +1 @@
-../../media/libmedia/include/media/TimeCheck.h
\ No newline at end of file
+../../media/utils/include/mediautils/TimeCheck.h
\ No newline at end of file
diff --git a/media/libaaudio/examples/input_monitor/jni/Android.mk b/media/libaaudio/examples/input_monitor/jni/Android.mk
deleted file mode 100644
index a0b981c..0000000
--- a/media/libaaudio/examples/input_monitor/jni/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/av/media/libaaudio/include \
- frameworks/av/media/libaaudio/src \
- frameworks/av/media/libaaudio/examples/utils
-
-# NDK recommends using this kind of relative path instead of an absolute path.
-LOCAL_SRC_FILES:= ../src/input_monitor.cpp
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_SHARED_LIBRARIES := libaaudio
-LOCAL_MODULE := input_monitor
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/av/media/libaaudio/include \
- frameworks/av/media/libaaudio/examples/utils
-
-LOCAL_SRC_FILES:= ../src/input_monitor_callback.cpp
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_SHARED_LIBRARIES := libaaudio
-LOCAL_MODULE := input_monitor_callback
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libaaudio_prebuilt
-LOCAL_SRC_FILES := libaaudio.so
-LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
-include $(PREBUILT_SHARED_LIBRARY)
diff --git a/media/libaaudio/examples/input_monitor/jni/Application.mk b/media/libaaudio/examples/input_monitor/jni/Application.mk
deleted file mode 100644
index e74475c..0000000
--- a/media/libaaudio/examples/input_monitor/jni/Application.mk
+++ /dev/null
@@ -1,3 +0,0 @@
-# TODO remove then when we support other architectures
-APP_ABI := arm64-v8a
-APP_CPPFLAGS += -std=c++11
diff --git a/media/libaaudio/examples/loopback/jni/Android.mk b/media/libaaudio/examples/loopback/jni/Android.mk
deleted file mode 100644
index aebe877..0000000
--- a/media/libaaudio/examples/loopback/jni/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/av/media/libaaudio/include \
- frameworks/av/media/libaaudio/examples/utils
-
-# NDK recommends using this kind of relative path instead of an absolute path.
-LOCAL_SRC_FILES:= ../src/loopback.cpp
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_STATIC_LIBRARIES := libsndfile
-LOCAL_SHARED_LIBRARIES := libaaudio libaudioutils
-LOCAL_MODULE := aaudio_loopback
-include $(BUILD_EXECUTABLE)
diff --git a/media/libaaudio/examples/loopback/jni/Application.mk b/media/libaaudio/examples/loopback/jni/Application.mk
deleted file mode 100644
index ba44f37..0000000
--- a/media/libaaudio/examples/loopback/jni/Application.mk
+++ /dev/null
@@ -1 +0,0 @@
-APP_CPPFLAGS += -std=c++11
diff --git a/media/libaaudio/examples/write_sine/jni/Android.mk b/media/libaaudio/examples/write_sine/jni/Android.mk
deleted file mode 100644
index 1a1bd43..0000000
--- a/media/libaaudio/examples/write_sine/jni/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/av/media/libaaudio/include \
- frameworks/av/media/libaaudio/src \
- frameworks/av/media/libaaudio/examples/utils
-
-# NDK recommends using this kind of relative path instead of an absolute path.
-LOCAL_SRC_FILES:= ../src/write_sine.cpp
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_SHARED_LIBRARIES := libaaudio
-LOCAL_MODULE := write_sine
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE_TAGS := tests
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
- frameworks/av/media/libaaudio/include \
- frameworks/av/media/libaaudio/examples/utils
-
-LOCAL_SRC_FILES:= ../src/write_sine_callback.cpp
-LOCAL_CFLAGS := -Wall -Werror
-LOCAL_SHARED_LIBRARIES := libaaudio
-LOCAL_MODULE := write_sine_callback
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libaaudio_prebuilt
-LOCAL_SRC_FILES := libaaudio.so
-LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
-include $(PREBUILT_SHARED_LIBRARY)
diff --git a/media/libaaudio/examples/write_sine/jni/Application.mk b/media/libaaudio/examples/write_sine/jni/Application.mk
deleted file mode 100644
index ba44f37..0000000
--- a/media/libaaudio/examples/write_sine/jni/Application.mk
+++ /dev/null
@@ -1 +0,0 @@
-APP_CPPFLAGS += -std=c++11
diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp
index 37c62a8..84e8bee 100644
--- a/media/libaudioclient/IAudioFlinger.cpp
+++ b/media/libaudioclient/IAudioFlinger.cpp
@@ -949,7 +949,8 @@
break;
}
- TimeCheck check("IAudioFlinger");
+ std::string tag("IAudioFlinger command " + std::to_string(code));
+ TimeCheck check(tag.c_str());
switch (code) {
case CREATE_TRACK: {
diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp
index 9d77376..e229f4c 100644
--- a/media/libaudioclient/IAudioPolicyService.cpp
+++ b/media/libaudioclient/IAudioPolicyService.cpp
@@ -935,7 +935,8 @@
break;
}
- TimeCheck check("IAudioPolicyService");
+ std::string tag("IAudioPolicyService command " + std::to_string(code));
+ TimeCheck check(tag.c_str());
switch (code) {
case SET_DEVICE_CONNECTION_STATE: {
diff --git a/media/libeffects/config/include/media/EffectsConfig.h b/media/libeffects/config/include/media/EffectsConfig.h
index 55b946f..fa0415b 100644
--- a/media/libeffects/config/include/media/EffectsConfig.h
+++ b/media/libeffects/config/include/media/EffectsConfig.h
@@ -96,7 +96,7 @@
/** Parsed config, nullptr if the xml lib could not load the file */
std::unique_ptr<Config> parsedConfig;
size_t nbSkippedElement; //< Number of skipped invalid library, effect or processing chain
- const char* configPath; //< Path to the loaded configuration
+ const std::string configPath; //< Path to the loaded configuration
};
/** Parses the provided effect configuration.
diff --git a/media/libeffects/config/src/EffectsConfig.cpp b/media/libeffects/config/src/EffectsConfig.cpp
index d79501f..351b1ee 100644
--- a/media/libeffects/config/src/EffectsConfig.cpp
+++ b/media/libeffects/config/src/EffectsConfig.cpp
@@ -250,14 +250,14 @@
return true;
}
-/** Internal version of the public parse(const char* path) with precondition `path != nullptr`. */
-ParsingResult parseWithPath(const char* path) {
+/** Internal version of the public parse(const char* path) where path always exist. */
+ParsingResult parseWithPath(std::string&& path) {
XMLDocument doc;
- doc.LoadFile(path);
+ doc.LoadFile(path.c_str());
if (doc.Error()) {
- ALOGE("Failed to parse %s: Tinyxml2 error (%d): %s", path,
+ ALOGE("Failed to parse %s: Tinyxml2 error (%d): %s", path.c_str(),
doc.ErrorID(), doc.ErrorStr());
- return {nullptr, 0, path};
+ return {nullptr, 0, std::move(path)};
}
auto config = std::make_unique<Config>();
@@ -295,7 +295,7 @@
}
}
}
- return {std::move(config), nbSkippedElements, path};
+ return {std::move(config), nbSkippedElements, std::move(path)};
}
}; // namespace
@@ -310,14 +310,14 @@
if (access(defaultPath.c_str(), R_OK) != 0) {
continue;
}
- auto result = parseWithPath(defaultPath.c_str());
+ auto result = parseWithPath(std::move(defaultPath));
if (result.parsedConfig != nullptr) {
return result;
}
}
ALOGE("Could not parse effect configuration in any of the default locations.");
- return {nullptr, 0, nullptr};
+ return {nullptr, 0, ""};
}
} // namespace effectsConfig
diff --git a/media/libeffects/factory/EffectsXmlConfigLoader.cpp b/media/libeffects/factory/EffectsXmlConfigLoader.cpp
index 7a7d431..052a88b 100644
--- a/media/libeffects/factory/EffectsXmlConfigLoader.cpp
+++ b/media/libeffects/factory/EffectsXmlConfigLoader.cpp
@@ -327,7 +327,8 @@
&gSkippedEffects, &gSubEffectList);
ALOGE_IF(result.nbSkippedElement != 0, "%zu errors during loading of configuration: %s",
- result.nbSkippedElement, result.configPath ?: "No config file found");
+ result.nbSkippedElement,
+ result.configPath.empty() ? "No config file found" : result.configPath.c_str());
return result.nbSkippedElement;
}
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index a22819a..e6d6b3e 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -20,7 +20,7 @@
vndk: {
enabled: true,
},
- srcs: ["AudioParameter.cpp", "TypeConverter.cpp", "TimeCheck.cpp"],
+ srcs: ["AudioParameter.cpp", "TypeConverter.cpp"],
cflags: [
"-Werror",
"-Wno-error=deprecated-declarations",
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 72eff94..353e407 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -860,7 +860,15 @@
}
//static
-sp<CodecBase> MediaCodec::GetCodecBase(const AString &name) {
+sp<CodecBase> MediaCodec::GetCodecBase(const AString &name, const char *owner) {
+ if (owner) {
+ if (strncmp(owner, "default", 8) == 0) {
+ return new ACodec;
+ } else if (strncmp(owner, "codec2", 7) == 0) {
+ return CreateCCodec();
+ }
+ }
+
if (name.startsWithIgnoreCase("c2.")) {
return CreateCCodec();
} else if (name.startsWithIgnoreCase("omx.")) {
@@ -884,11 +892,6 @@
// we need to invest in an extra looper to free the main event
// queue.
- mCodec = GetCodecBase(name);
- if (mCodec == NULL) {
- return NAME_NOT_FOUND;
- }
-
mCodecInfo.clear();
bool secureCodec = false;
@@ -922,6 +925,11 @@
return NAME_NOT_FOUND;
}
+ mCodec = GetCodecBase(name, mCodecInfo->getOwnerName());
+ if (mCodec == NULL) {
+ return NAME_NOT_FOUND;
+ }
+
if (mIsVideo) {
// video codec needs dedicated looper
if (mCodecLooper == NULL) {
@@ -1935,7 +1943,9 @@
mAnalyticsItem->setCString(kCodecCodec, mComponentName.c_str());
}
- if (mComponentName.startsWith("OMX.google.")) {
+ const char *owner = mCodecInfo->getOwnerName();
+ if (mComponentName.startsWith("OMX.google.")
+ && (owner == nullptr || strncmp(owner, "default", 8) == 0)) {
mFlags |= kFlagUsesSoftwareRenderer;
} else {
mFlags &= ~kFlagUsesSoftwareRenderer;
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index ad02004..7f6aae6 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -377,7 +377,7 @@
MediaCodec(const sp<ALooper> &looper, pid_t pid, uid_t uid);
- static sp<CodecBase> GetCodecBase(const AString &name);
+ static sp<CodecBase> GetCodecBase(const AString &name, const char *owner = nullptr);
static status_t PostAndAwaitResponse(
const sp<AMessage> &msg, sp<AMessage> *response);
diff --git a/media/ndk/include/media/NdkImage.h b/media/ndk/include/media/NdkImage.h
index 38e12e3..f936118 100644
--- a/media/ndk/include/media/NdkImage.h
+++ b/media/ndk/include/media/NdkImage.h
@@ -36,13 +36,12 @@
#ifndef _NDK_IMAGE_H
#define _NDK_IMAGE_H
+#include <stdint.h>
#include <sys/cdefs.h>
#include "NdkMediaError.h"
-#if __ANDROID_API__ >= 26
#include <android/hardware_buffer.h>
-#endif /* __ANDROID_API__ >= 26 */
__BEGIN_DECLS
@@ -516,6 +515,8 @@
int32_t bottom;
} AImageCropRect;
+#if __ANDROID_API__ >= 24
+
/**
* Return the image back the the system and delete the AImage object from memory.
*
@@ -712,6 +713,10 @@
const AImage* image, int planeIdx,
/*out*/uint8_t** data, /*out*/int* dataLength) __INTRODUCED_IN(24);
+#endif /* __ANDROID_API__ >= 24 */
+
+#if __ANDROID_API__ >= 26
+
/**
* Return the image back the the system and delete the AImage object from memory asynchronously.
*
@@ -756,6 +761,8 @@
*/
media_status_t AImage_getHardwareBuffer(const AImage* image, /*out*/AHardwareBuffer** buffer) __INTRODUCED_IN(26);
+#endif /* __ANDROID_API__ >= 26 */
+
__END_DECLS
#endif //_NDK_IMAGE_H
diff --git a/media/ndk/include/media/NdkImageReader.h b/media/ndk/include/media/NdkImageReader.h
index eb1a44a..68de176 100644
--- a/media/ndk/include/media/NdkImageReader.h
+++ b/media/ndk/include/media/NdkImageReader.h
@@ -50,6 +50,8 @@
*/
typedef struct AImageReader AImageReader;
+#if __ANDROID_API__ >= 24
+
/**
* Create a new reader for images of the desired size and format.
*
@@ -296,6 +298,10 @@
media_status_t AImageReader_setImageListener(
AImageReader* reader, AImageReader_ImageListener* listener) __INTRODUCED_IN(24);
+#endif /* __ANDROID_API__ >= 24 */
+
+#if __ANDROID_API__ >= 26
+
/**
* AImageReader constructor similar to {@link AImageReader_new} that takes an additional parameter
* for the consumer usage. All other parameters and the return values are identical to those passed
@@ -455,6 +461,8 @@
media_status_t AImageReader_setBufferRemovedListener(
AImageReader* reader, AImageReader_BufferRemovedListener* listener) __INTRODUCED_IN(26);
+#endif /* __ANDROID_API__ >= 26 */
+
__END_DECLS
#endif //_NDK_IMAGE_READER_H
diff --git a/media/ndk/include/media/NdkMediaCodec.h b/media/ndk/include/media/NdkMediaCodec.h
index b329b39..9dc120d 100644
--- a/media/ndk/include/media/NdkMediaCodec.h
+++ b/media/ndk/include/media/NdkMediaCodec.h
@@ -121,6 +121,8 @@
AMediaCodecOnAsyncError onAsyncError;
};
+#if __ANDROID_API__ >= 21
+
/**
* Create codec by name. Use this if you know the exact codec you want to use.
* When configuring, you will need to specify whether to use the codec as an
@@ -274,6 +276,8 @@
media_status_t AMediaCodec_releaseOutputBufferAtTime(
AMediaCodec *mData, size_t idx, int64_t timestampNs) __INTRODUCED_IN(21);
+#if __ANDROID_API__ >= 26
+
/**
* Creates a Surface that can be used as the input to encoder, in place of input buffers
*
@@ -344,6 +348,10 @@
*/
media_status_t AMediaCodec_signalEndOfInputStream(AMediaCodec *mData) __INTRODUCED_IN(26);
+#endif /* __ANDROID_API__ >= 26 */
+
+#if __ANDROID_API__ >= 28
+
/**
* Get the component name. If the codec was created by createDecoderByType
* or createEncoderByType, what component is chosen is not known beforehand.
@@ -405,6 +413,8 @@
*/
bool AMediaCodecActionCode_isTransient(int32_t actionCode) __INTRODUCED_IN(28);
+#endif /* __ANDROID_API__ >= 28 */
+
typedef enum {
AMEDIACODECRYPTOINFO_MODE_CLEAR = 0,
AMEDIACODECRYPTOINFO_MODE_AES_CTR = 1,
@@ -483,6 +493,8 @@
*/
media_status_t AMediaCodecCryptoInfo_getEncryptedBytes(AMediaCodecCryptoInfo*, size_t *dst) __INTRODUCED_IN(21);
+#endif /* __ANDROID_API__ >= 21 */
+
__END_DECLS
#endif //_NDK_MEDIA_CODEC_H
diff --git a/media/ndk/include/media/NdkMediaCrypto.h b/media/ndk/include/media/NdkMediaCrypto.h
index b673adc..bcdf9a0 100644
--- a/media/ndk/include/media/NdkMediaCrypto.h
+++ b/media/ndk/include/media/NdkMediaCrypto.h
@@ -47,6 +47,8 @@
typedef uint8_t AMediaUUID[16];
+#if __ANDROID_API__ >= 21
+
bool AMediaCrypto_isCryptoSchemeSupported(const AMediaUUID uuid) __INTRODUCED_IN(21);
bool AMediaCrypto_requiresSecureDecoderComponent(const char *mime) __INTRODUCED_IN(21);
@@ -55,6 +57,8 @@
void AMediaCrypto_delete(AMediaCrypto* crypto) __INTRODUCED_IN(21);
+#endif /* __ANDROID_API__ >= 21 */
+
__END_DECLS
#endif // _NDK_MEDIA_CRYPTO_H
diff --git a/media/ndk/include/media/NdkMediaDataSource.h b/media/ndk/include/media/NdkMediaDataSource.h
index 3a4373c..ea5ba0c 100644
--- a/media/ndk/include/media/NdkMediaDataSource.h
+++ b/media/ndk/include/media/NdkMediaDataSource.h
@@ -38,6 +38,8 @@
struct AMediaDataSource;
typedef struct AMediaDataSource AMediaDataSource;
+#if __ANDROID_API__ >= 28
+
/*
* AMediaDataSource's callbacks will be invoked on an implementation-defined thread
* or thread pool. No guarantees are provided about which thread(s) will be used for
@@ -133,6 +135,8 @@
AMediaDataSource*,
AMediaDataSourceClose) __INTRODUCED_IN(28);
+#endif /*__ANDROID_API__ >= 28 */
+
__END_DECLS
#endif // _NDK_MEDIA_DATASOURCE_H
diff --git a/media/ndk/include/media/NdkMediaDrm.h b/media/ndk/include/media/NdkMediaDrm.h
index 24c0d6d..0209681 100644
--- a/media/ndk/include/media/NdkMediaDrm.h
+++ b/media/ndk/include/media/NdkMediaDrm.h
@@ -87,6 +87,8 @@
typedef void (*AMediaDrmEventListener)(AMediaDrm *, const AMediaDrmSessionId *sessionId,
AMediaDrmEventType eventType, int extra, const uint8_t *data, size_t dataSize);
+#if __ANDROID_API__ >= 21
+
/**
* Query if the given scheme identified by its UUID is supported on this device, and
* whether the drm plugin is able to handle the media container format specified by mimeType.
@@ -459,6 +461,8 @@
const char *macAlgorithm, uint8_t *keyId, const uint8_t *message, size_t messageSize,
const uint8_t *signature, size_t signatureSize) __INTRODUCED_IN(21);
+#endif /* __ANDROID_API__ >= 21 */
+
__END_DECLS
#endif //_NDK_MEDIA_DRM_H
diff --git a/media/ndk/include/media/NdkMediaExtractor.h b/media/ndk/include/media/NdkMediaExtractor.h
index 9f60891..6a1796f 100644
--- a/media/ndk/include/media/NdkMediaExtractor.h
+++ b/media/ndk/include/media/NdkMediaExtractor.h
@@ -49,6 +49,8 @@
struct AMediaExtractor;
typedef struct AMediaExtractor AMediaExtractor;
+#if __ANDROID_API__ >= 21
+
/**
* Create new media extractor
*/
@@ -72,12 +74,16 @@
const char *location) __INTRODUCED_IN(21);
// TODO support headers
+#if __ANDROID_API__ >= 28
+
/**
* Set the custom data source implementation from which the extractor will read.
*/
media_status_t AMediaExtractor_setDataSourceCustom(AMediaExtractor*,
AMediaDataSource *src) __INTRODUCED_IN(28);
+#endif /* __ANDROID_API__ >= 28 */
+
/**
* Return the number of tracks in the previously specified media file
*/
@@ -173,6 +179,8 @@
AMEDIAEXTRACTOR_SAMPLE_FLAG_ENCRYPTED = 2,
};
+#if __ANDROID_API__ >= 28
+
/**
* Returns the format of the extractor. The caller must free the returned format
* using AMediaFormat_delete(format).
@@ -219,6 +227,10 @@
media_status_t AMediaExtractor_getSampleFormat(AMediaExtractor *ex,
AMediaFormat *fmt) __INTRODUCED_IN(28);
+#endif /* __ANDROID_API__ >= 28 */
+
+#endif /* __ANDROID_API__ >= 21 */
+
__END_DECLS
#endif // _NDK_MEDIA_EXTRACTOR_H
diff --git a/media/ndk/include/media/NdkMediaFormat.h b/media/ndk/include/media/NdkMediaFormat.h
index 8f37f7b..5f7804d 100644
--- a/media/ndk/include/media/NdkMediaFormat.h
+++ b/media/ndk/include/media/NdkMediaFormat.h
@@ -46,6 +46,8 @@
struct AMediaFormat;
typedef struct AMediaFormat AMediaFormat;
+#if __ANDROID_API__ >= 21
+
AMediaFormat *AMediaFormat_new() __INTRODUCED_IN(21);
media_status_t AMediaFormat_delete(AMediaFormat*) __INTRODUCED_IN(21);
@@ -155,6 +157,9 @@
extern const char* AMEDIAFORMAT_KEY_TRACK_INDEX __INTRODUCED_IN(28);
extern const char* AMEDIAFORMAT_KEY_WIDTH __INTRODUCED_IN(21);
+#endif /* __ANDROID_API__ >= 21 */
+
+#if __ANDROID_API__ >= 28
bool AMediaFormat_getDouble(AMediaFormat*, const char *name, double *out) __INTRODUCED_IN(28);
bool AMediaFormat_getRect(AMediaFormat*, const char *name,
int32_t *left, int32_t *top, int32_t *right, int32_t *bottom) __INTRODUCED_IN(28);
@@ -163,6 +168,7 @@
void AMediaFormat_setSize(AMediaFormat*, const char* name, size_t value) __INTRODUCED_IN(28);
void AMediaFormat_setRect(AMediaFormat*, const char* name,
int32_t left, int32_t top, int32_t right, int32_t bottom) __INTRODUCED_IN(28);
+#endif /* __ANDROID_API__ >= 28 */
__END_DECLS
diff --git a/media/ndk/include/media/NdkMediaMuxer.h b/media/ndk/include/media/NdkMediaMuxer.h
index 75c70ed..7393867 100644
--- a/media/ndk/include/media/NdkMediaMuxer.h
+++ b/media/ndk/include/media/NdkMediaMuxer.h
@@ -53,6 +53,8 @@
AMEDIAMUXER_OUTPUT_FORMAT_WEBM = 1,
} OutputFormat;
+#if __ANDROID_API__ >= 21
+
/**
* Create new media muxer
*/
@@ -121,6 +123,8 @@
size_t trackIdx, const uint8_t *data,
const AMediaCodecBufferInfo *info) __INTRODUCED_IN(21);
+#endif /* __ANDROID_API__ >= 21 */
+
__END_DECLS
#endif // _NDK_MEDIA_MUXER_H
diff --git a/media/utils/Android.bp b/media/utils/Android.bp
index de8e46a..13b66ed 100644
--- a/media/utils/Android.bp
+++ b/media/utils/Android.bp
@@ -22,6 +22,7 @@
"ProcessInfo.cpp",
"SchedulingPolicyService.cpp",
"ServiceUtilities.cpp",
+ "TimeCheck.cpp",
],
shared_libs: [
"libbinder",
@@ -31,6 +32,8 @@
"libmemunreachable",
],
+ logtags: ["EventLogTags.logtags"],
+
cflags: [
"-Wall",
"-Wextra",
diff --git a/media/utils/EventLogTags.logtags b/media/utils/EventLogTags.logtags
new file mode 100644
index 0000000..67f0ea8
--- /dev/null
+++ b/media/utils/EventLogTags.logtags
@@ -0,0 +1,41 @@
+# The entries in this file map a sparse set of log tag numbers to tag names.
+# This is installed on the device, in /system/etc, and parsed by logcat.
+#
+# Tag numbers are decimal integers, from 0 to 2^31. (Let's leave the
+# negative values alone for now.)
+#
+# Tag names are one or more ASCII letters and numbers or underscores, i.e.
+# "[A-Z][a-z][0-9]_". Do not include spaces or punctuation (the former
+# impacts log readability, the latter makes regex searches more annoying).
+#
+# Tag numbers and names are separated by whitespace. Blank lines and lines
+# starting with '#' are ignored.
+#
+# Optionally, after the tag names can be put a description for the value(s)
+# of the tag. Description are in the format
+# (<name>|data type[|data unit])
+# Multiple values are separated by commas.
+#
+# The data type is a number from the following values:
+# 1: int
+# 2: long
+# 3: string
+# 4: list
+#
+# The data unit is a number taken from the following list:
+# 1: Number of objects
+# 2: Number of bytes
+# 3: Number of milliseconds
+# 4: Number of allocations
+# 5: Id
+# 6: Percent
+# Default value for data of type int/long is 2 (bytes).
+#
+# See system/core/logcat/event.logtags for the master copy of the tags.
+
+# 61000 - 61199 reserved for audioserver
+
+61000 audioserver_binder_timeout (command|3)
+
+# NOTE - the range 1000000-2000000 is reserved for partners and others who
+# want to define their own log tags without conflicting with the core platform.
diff --git a/media/libmedia/TimeCheck.cpp b/media/utils/TimeCheck.cpp
similarity index 91%
rename from media/libmedia/TimeCheck.cpp
rename to media/utils/TimeCheck.cpp
index dab5d4f..59cf4ef 100644
--- a/media/libmedia/TimeCheck.cpp
+++ b/media/utils/TimeCheck.cpp
@@ -15,7 +15,9 @@
*/
+#include <utils/Log.h>
#include <media/TimeCheck.h>
+#include <media/EventLog.h>
namespace android {
@@ -81,7 +83,10 @@
status = mCond.waitRelative(mMutex, waitTimeNs);
}
}
- LOG_ALWAYS_FATAL_IF(status != NO_ERROR, "TimeCheck timeout for %s", tag);
+ if (status != NO_ERROR) {
+ LOG_EVENT_STRING(LOGTAG_AUDIO_BINDER_TIMEOUT, tag);
+ LOG_ALWAYS_FATAL("TimeCheck timeout for %s", tag);
+ }
return true;
}
diff --git a/media/utils/include/mediautils/EventLog.h b/media/utils/include/mediautils/EventLog.h
new file mode 100644
index 0000000..553d3bd
--- /dev/null
+++ b/media/utils/include/mediautils/EventLog.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2018 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 ANDROID_AUDIO_EVENT_LOG_H_
+#define ANDROID_AUDIO_EVENT_LOG_H_
+
+namespace android {
+
+// keep values in sync with frameworks/av/media/utils/EventLogTags.logtags
+enum {
+ LOGTAG_AUDIO_BINDER_TIMEOUT = 61000,
+};
+
+} // namespace android
+
+#endif // ANDROID_AUDIO_EVENT_LOG_H_
diff --git a/media/libmedia/include/media/TimeCheck.h b/media/utils/include/mediautils/TimeCheck.h
similarity index 100%
rename from media/libmedia/include/media/TimeCheck.h
rename to media/utils/include/mediautils/TimeCheck.h
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 79501cd..9234364 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -20,9 +20,11 @@
//#define LOG_NDEBUG 0
#include "Configuration.h"
+#include <algorithm> // std::any_of
#include <dirent.h>
#include <math.h>
#include <signal.h>
+#include <string>
#include <sys/time.h>
#include <sys/resource.h>
@@ -434,6 +436,15 @@
if (!dumpAllowed()) {
dumpPermissionDenial(fd, args);
} else {
+ // XXX This is sort of hacky for now.
+ const bool formatJson = std::any_of(args.begin(), args.end(),
+ [](const String16 &arg) { return arg == String16("--json"); });
+ if (formatJson) {
+ // XXX consider buffering if the string happens to be too long.
+ dprintf(fd, "%s", getJsonString().c_str());
+ return NO_ERROR;
+ }
+
// get state of hardware lock
bool hardwareLocked = dumpTryLock(mHardwareLock);
if (!hardwareLocked) {
@@ -443,7 +454,7 @@
mHardwareLock.unlock();
}
- bool locked = dumpTryLock(mLock);
+ const bool locked = dumpTryLock(mLock);
// failed to lock - AudioFlinger is probably deadlocked
if (!locked) {
@@ -545,6 +556,36 @@
return NO_ERROR;
}
+std::string AudioFlinger::getJsonString()
+{
+ std::string jsonStr = "{\n";
+ const bool locked = dumpTryLock(mLock);
+
+ // failed to lock - AudioFlinger is probably deadlocked
+ if (!locked) {
+ jsonStr += " \"deadlock_message\": ";
+ jsonStr += kDeadlockedString;
+ jsonStr += ",\n";
+ }
+ // FIXME risky to access data structures without a lock held?
+
+ jsonStr += " \"Playback_Threads\": [\n";
+ // dump playback threads
+ for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
+ if (i != 0) {
+ jsonStr += ",\n";
+ }
+ jsonStr += mPlaybackThreads.valueAt(i)->getJsonString();
+ }
+ jsonStr += "\n ]\n}\n";
+
+ if (locked) {
+ mLock.unlock();
+ }
+
+ return jsonStr;
+}
+
sp<AudioFlinger::Client> AudioFlinger::registerPid(pid_t pid)
{
Mutex::Autolock _cl(mClientLock);
@@ -1836,7 +1877,7 @@
mHardwareStatus = AUDIO_HW_IDLE;
}
- if (strcmp(name, AUDIO_HAL_SERVICE_NAME_MSD) == 0) {
+ if (strcmp(name, AUDIO_HARDWARE_MODULE_ID_MSD) == 0) {
// An MSD module is inserted before hardware modules in order to mix encoded streams.
flags = static_cast<AudioHwDevice::Flags>(flags | AudioHwDevice::AHWD_IS_INSERT);
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 4a780ce..95b947c 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -23,6 +23,8 @@
#include <mutex>
#include <deque>
#include <map>
+#include <memory>
+#include <string>
#include <vector>
#include <stdint.h>
#include <sys/types.h>
@@ -112,6 +114,7 @@
static const char* getServiceName() ANDROID_API { return "media.audio_flinger"; }
virtual status_t dump(int fd, const Vector<String16>& args);
+ std::string getJsonString();
// IAudioFlinger interface, in binder opcode order
virtual sp<IAudioTrack> createTrack(const CreateTrackInput& input,
diff --git a/services/audioflinger/Configuration.h b/services/audioflinger/Configuration.h
index ede8e3f..64bb426 100644
--- a/services/audioflinger/Configuration.h
+++ b/services/audioflinger/Configuration.h
@@ -27,7 +27,7 @@
//#define AUDIO_WATCHDOG
// uncomment to display CPU load adjusted for CPU frequency
-//#define CPU_FREQUENCY_STATISTICS
+#define CPU_FREQUENCY_STATISTICS
// uncomment to enable fast threads to take performance samples for later statistical analysis
#define FAST_THREAD_STATISTICS
diff --git a/services/audioflinger/FastMixerDumpState.cpp b/services/audioflinger/FastMixerDumpState.cpp
index d60643c..c0f9f0f 100644
--- a/services/audioflinger/FastMixerDumpState.cpp
+++ b/services/audioflinger/FastMixerDumpState.cpp
@@ -24,6 +24,7 @@
#include <cpustats/ThreadCpuUsage.h>
#endif
#endif
+#include <string>
#include <utils/Debug.h>
#include <utils/Log.h>
#include "FastMixerDumpState.h"
@@ -76,14 +77,14 @@
dprintf(fd, " FastMixer Timestamp stats: %s\n", mTimestampVerifier.toString().c_str());
#ifdef FAST_THREAD_STATISTICS
// find the interval of valid samples
- uint32_t bounds = mBounds;
- uint32_t newestOpen = bounds & 0xFFFF;
+ const uint32_t bounds = mBounds;
+ const uint32_t newestOpen = bounds & 0xFFFF;
uint32_t oldestClosed = bounds >> 16;
//uint32_t n = (newestOpen - oldestClosed) & 0xFFFF;
uint32_t n;
__builtin_sub_overflow(newestOpen, oldestClosed, &n);
- n = n & 0xFFFF;
+ n &= 0xFFFF;
if (n > mSamplingN) {
ALOGE("too many samples %u", n);
@@ -204,4 +205,56 @@
}
}
+// TODO get rid of extraneous lines and use better key names.
+// TODO may go back to using a library to do the json formatting.
+std::string FastMixerDumpState::getJsonString() const
+{
+ if (mCommand == FastMixerState::INITIAL) {
+ return " {\n \"status\": \"uninitialized\"\n }";
+ }
+ std::string jsonStr = " {\n";
+#ifdef FAST_THREAD_STATISTICS
+ // find the interval of valid samples
+ const uint32_t bounds = mBounds;
+ const uint32_t newestOpen = bounds & 0xFFFF;
+ uint32_t oldestClosed = bounds >> 16;
+
+ //uint32_t n = (newestOpen - oldestClosed) & 0xFFFF;
+ uint32_t n;
+ __builtin_sub_overflow(newestOpen, oldestClosed, &n);
+ n &= 0xFFFF;
+
+ if (n > mSamplingN) {
+ ALOGE("too many samples %u", n);
+ n = mSamplingN;
+ }
+ // statistics for monotonic (wall clock) time, thread raw CPU load in time, CPU clock frequency,
+ // and adjusted CPU load in MHz normalized for CPU clock frequency
+ std::string jsonWallStr = " \"wall_clock_time\":[";
+ std::string jsonLoadNsStr = " \"raw_cpu_load\":[";
+ // loop over all the samples
+ for (uint32_t j = 0; j < n; ++j) {
+ size_t i = oldestClosed++ & (mSamplingN - 1);
+ uint32_t wallNs = mMonotonicNs[i];
+ if (j != 0) {
+ jsonWallStr += ',';
+ jsonLoadNsStr += ',';
+ }
+ /* jsonObject["wall"].append(wallNs); */
+ jsonWallStr += std::to_string(wallNs);
+ uint32_t sampleLoadNs = mLoadNs[i];
+ jsonLoadNsStr += std::to_string(sampleLoadNs);
+ }
+ jsonWallStr += ']';
+ jsonLoadNsStr += ']';
+ if (n) {
+ jsonStr += jsonWallStr + ",\n" + jsonLoadNsStr + "\n";
+ } else {
+ //dprintf(fd, " No FastMixer statistics available currently\n");
+ }
+#endif
+ jsonStr += " }";
+ return jsonStr;
+}
+
} // android
diff --git a/services/audioflinger/FastMixerDumpState.h b/services/audioflinger/FastMixerDumpState.h
index 9b91cbc..81c4175 100644
--- a/services/audioflinger/FastMixerDumpState.h
+++ b/services/audioflinger/FastMixerDumpState.h
@@ -18,6 +18,7 @@
#define ANDROID_AUDIO_FAST_MIXER_DUMP_STATE_H
#include <stdint.h>
+#include <string>
#include <audio_utils/TimestampVerifier.h>
#include "Configuration.h"
#include "FastThreadDumpState.h"
@@ -65,7 +66,8 @@
FastMixerDumpState();
/*virtual*/ ~FastMixerDumpState();
- void dump(int fd) const; // should only be called on a stable copy, not the original
+ void dump(int fd) const; // should only be called on a stable copy, not the original
+ std::string getJsonString() const; // should only be called on a stable copy, not the original
double mLatencyMs = 0.; // measured latency, default of 0 if no valid timestamp read.
uint32_t mWriteSequence; // incremented before and after each write()
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 15a60c2..f044fb7 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -471,12 +471,16 @@
audio_output_flags_t outputFlags = mAudioPatch.sinks[0].config_mask & AUDIO_PORT_CONFIG_FLAGS ?
mAudioPatch.sinks[0].flags.output : AUDIO_OUTPUT_FLAG_NONE;
-
+ audio_stream_type_t streamType = AUDIO_STREAM_PATCH;
+ if (mAudioPatch.num_sources == 2 && mAudioPatch.sources[1].type == AUDIO_PORT_TYPE_MIX) {
+ // "reuse one existing output mix" case
+ streamType = mAudioPatch.sources[1].ext.mix.usecase.stream;
+ }
// create a special playback track to render to playback thread.
// this track is given the same buffer as the PatchRecord buffer
sp<PlaybackThread::PatchTrack> tempPatchTrack = new (std::nothrow) PlaybackThread::PatchTrack(
mPlayback.thread().get(),
- mAudioPatch.sources[1].ext.mix.usecase.stream,
+ streamType,
sampleRate,
outChannelMask,
format,
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index e3b83f9..1e411c7 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -23,6 +23,8 @@
#include "Configuration.h"
#include <math.h>
#include <fcntl.h>
+#include <memory>
+#include <string>
#include <linux/futex.h>
#include <sys/stat.h>
#include <sys/syscall.h>
@@ -1761,6 +1763,11 @@
mLocalLog.dump(fd, " " /* prefix */, 40 /* lines */);
}
+std::string AudioFlinger::PlaybackThread::getJsonString() const
+{
+ return "{}";
+}
+
void AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& args __unused)
{
String8 result;
@@ -5110,9 +5117,8 @@
// while we are dumping it. It may be inconsistent, but it won't mutate!
// This is a large object so we place it on the heap.
// FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages.
- const FastMixerDumpState *copy = new FastMixerDumpState(mFastMixerDumpState);
+ const std::unique_ptr<FastMixerDumpState> copy(new FastMixerDumpState(mFastMixerDumpState));
copy->dump(fd);
- delete copy;
#ifdef STATE_QUEUE_DUMP
// Similar for state queue
@@ -5135,6 +5141,16 @@
}
}
+std::string AudioFlinger::MixerThread::getJsonString() const
+{
+ // Make a non-atomic copy of fast mixer dump state so it won't change underneath us
+ // while we are dumping it. It may be inconsistent, but it won't mutate!
+ // This is a large object so we place it on the heap.
+ // FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages.
+ return std::unique_ptr<FastMixerDumpState>(new FastMixerDumpState(mFastMixerDumpState))
+ ->getJsonString();
+}
+
uint32_t AudioFlinger::MixerThread::idleSleepTimeUs() const
{
return (uint32_t)(((mNormalFrameCount * 1000) / mSampleRate) * 1000) / 2;
@@ -7450,9 +7466,8 @@
// while we are dumping it. It may be inconsistent, but it won't mutate!
// This is a large object so we place it on the heap.
// FIXME 25972958: Need an intelligent copy constructor that does not touch unused pages.
- const FastCaptureDumpState *copy = new FastCaptureDumpState(mFastCaptureDumpState);
+ std::unique_ptr<FastCaptureDumpState> copy(new FastCaptureDumpState(mFastCaptureDumpState));
copy->dump(fd);
- delete copy;
}
void AudioFlinger::RecordThread::dumpTracks(int fd, const Vector<String16>& args __unused)
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 0c833f1..847a9c6 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -658,6 +658,8 @@
virtual ~PlaybackThread();
void dump(int fd, const Vector<String16>& args);
+ // returns a string of audio performance related data in JSON format.
+ virtual std::string getJsonString() const;
// Thread virtuals
virtual bool threadLoop();
@@ -1103,6 +1105,7 @@
virtual bool checkForNewParameter_l(const String8& keyValuePair,
status_t& status);
virtual void dumpInternals(int fd, const Vector<String16>& args);
+ std::string getJsonString() const override;
virtual bool isTrackAllowed_l(
audio_channel_mask_t channelMask, audio_format_t format,
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 941119b..ca64d86 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -725,6 +725,9 @@
device = AUDIO_DEVICE_IN_BACK_MIC;
} else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
device = AUDIO_DEVICE_IN_BUILTIN_MIC;
+ } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
+ // This is specifically for a device without built-in mic
+ device = AUDIO_DEVICE_IN_USB_DEVICE;
}
break;
case AUDIO_SOURCE_VOICE_DOWNLINK:
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 5cdd63a..bc9514f 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -851,6 +851,21 @@
*flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
}
+ // Set incall music only if device was explicitly set, and fallback to the device which is
+ // chosen by the engine if not.
+ // FIXME: provide a more generic approach which is not device specific and move this back
+ // to getOutputForDevice.
+ if (device == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
+ *stream == AUDIO_STREAM_MUSIC &&
+ audio_is_linear_pcm(config->format) &&
+ isInCall()) {
+ if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
+ *flags = (audio_output_flags_t)AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
+ } else {
+ device = mEngine->getDeviceForStrategy(strategy);
+ }
+ }
+
ALOGV("getOutputForAttr() device 0x%x, sampling rate %d, format %#x, channel mask %#x, "
"flags %#x",
device, config->sample_rate, config->format, config->channel_mask, *flags);
@@ -906,11 +921,6 @@
*flags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_VOIP_RX |
AUDIO_OUTPUT_FLAG_DIRECT);
ALOGV("Set VoIP and Direct output flags for PCM format");
- } else if (device == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
- stream == AUDIO_STREAM_MUSIC &&
- audio_is_linear_pcm(config->format) &&
- isInCall()) {
- *flags = (audio_output_flags_t)AUDIO_OUTPUT_FLAG_INCALL_MUSIC;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index eb66493..d4f78e0 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -277,6 +277,7 @@
status_t Camera3Device::disconnect() {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
+ Mutex::Autolock stLock(mTrackerLock);
ALOGI("%s: E", __FUNCTION__);
@@ -2728,8 +2729,9 @@
if (res < 0) return res;
if (mInFlightMap.size() == 1) {
- // hold mLock to prevent race with disconnect
- Mutex::Autolock l(mLock);
+ // Hold a separate dedicated tracker lock to prevent race with disconnect and also
+ // avoid a deadlock during reprocess requests.
+ Mutex::Autolock l(mTrackerLock);
if (mStatusTracker != nullptr) {
mStatusTracker->markComponentActive(mInFlightStatusId);
}
@@ -2762,8 +2764,9 @@
// Indicate idle inFlightMap to the status tracker
if (mInFlightMap.size() == 0) {
- // hold mLock to prevent race with disconnect
- Mutex::Autolock l(mLock);
+ // Hold a separate dedicated tracker lock to prevent race with disconnect and also
+ // avoid a deadlock during reprocess requests.
+ Mutex::Autolock l(mTrackerLock);
if (mStatusTracker != nullptr) {
mStatusTracker->markComponentIdle(mInFlightStatusId, Fence::NO_FENCE);
}
@@ -3918,18 +3921,17 @@
}
hardware::details::return_status err;
+ auto resultCallback =
+ [&status, &numRequestProcessed] (auto s, uint32_t n) {
+ status = s;
+ *numRequestProcessed = n;
+ };
if (hidlSession_3_4 != nullptr) {
err = hidlSession_3_4->processCaptureRequest_3_4(captureRequests_3_4, cachesToRemove,
- [&status, &numRequestProcessed] (auto s, uint32_t n) {
- status = s;
- *numRequestProcessed = n;
- });
+ resultCallback);
} else {
err = mHidlSession->processCaptureRequest(captureRequests, cachesToRemove,
- [&status, &numRequestProcessed] (auto s, uint32_t n) {
- status = s;
- *numRequestProcessed = n;
- });
+ resultCallback);
}
if (!err.isOk()) {
ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
@@ -4766,7 +4768,7 @@
bool newRequest = (mPrevRequest != captureRequest || triggersMixedIn) &&
// Request settings are all the same within one batch, so only treat the first
// request in a batch as new
- !(batchedRequest && i >= 0);
+ !(batchedRequest && i > 0);
if (newRequest) {
/**
* HAL workaround:
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index ef3cbc4..96212ab 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -1210,6 +1210,9 @@
static callbacks_notify_t sNotify;
+ // Synchronizes access to status tracker between inflight updates and disconnect.
+ // b/79972865
+ Mutex mTrackerLock;
}; // class Camera3Device
}; // namespace android