Merge "Camera: skip unnecessary reconfig"
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 bd85469..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,
@@ -7894,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/media/extractors/mp4/SampleIterator.cpp b/media/extractors/mp4/SampleIterator.cpp
index 93ee7c6..1a6d306 100644
--- a/media/extractors/mp4/SampleIterator.cpp
+++ b/media/extractors/mp4/SampleIterator.cpp
@@ -328,7 +328,15 @@
++mTimeToSampleIndex;
}
- *time = mTTSSampleTime + mTTSDuration * (sampleIndex - mTTSSampleIndex);
+ // below is equivalent to:
+ // *time = mTTSSampleTime + mTTSDuration * (sampleIndex - mTTSSampleIndex);
+ uint32_t tmp;
+ if (__builtin_sub_overflow(sampleIndex, mTTSSampleIndex, &tmp) ||
+ __builtin_mul_overflow(mTTSDuration, tmp, &tmp) ||
+ __builtin_add_overflow(mTTSSampleTime, tmp, &tmp)) {
+ return ERROR_OUT_OF_RANGE;
+ }
+ *time = tmp;
int32_t offset = mTable->getCompositionTimeOffset(sampleIndex);
if ((offset < 0 && *time < (offset == INT32_MIN ?
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index aade69a..e0f5a40 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -546,8 +546,8 @@
if (info->mHasRefProfile) {
- CamcorderProfile *profile =
- new CamcorderProfile(
+ std::unique_ptr<CamcorderProfile> profile =
+ std::make_unique<CamcorderProfile>(
*mCamcorderProfiles[info->mRefProfileIndex]);
// Overwrite the quality
@@ -581,7 +581,7 @@
mCamcorderProfiles[info->mRefProfileIndex]->mQuality,
profile->mQuality, cameraId);
- mCamcorderProfiles.add(profile);
+ mCamcorderProfiles.add(profile.release());
}
}
}
diff --git a/media/libnblog/PerformanceAnalysis.cpp b/media/libnblog/PerformanceAnalysis.cpp
index 22a30b9..3418dc0 100644
--- a/media/libnblog/PerformanceAnalysis.cpp
+++ b/media/libnblog/PerformanceAnalysis.cpp
@@ -32,6 +32,7 @@
#include <sys/prctl.h>
#include <time.h>
#include <new>
+#include <audio_utils/LogPlot.h>
#include <audio_utils/roundup.h>
#include <media/nblog/NBLog.h>
#include <media/nblog/PerformanceAnalysis.h>
@@ -208,27 +209,6 @@
return isOutlier;
}
-static int widthOf(int x) {
- int width = 0;
- if (x < 0) {
- width++;
- x = x == INT_MIN ? INT_MAX : -x;
- }
- // assert (x >= 0)
- do {
- ++width;
- x /= 10;
- } while (x > 0);
- return width;
-}
-
-// computes the column width required for a specific histogram value
-inline int numberWidth(double number, int leftPadding) {
- // Added values account for whitespaces needed around numbers, and for the
- // dot and decimal digit not accounted for by widthOf
- return std::max(std::max(widthOf(static_cast<int>(number)) + 3, 2), leftPadding + 1);
-}
-
// rounds value to precision based on log-distance from mean
__attribute__((no_sanitize("signed-integer-overflow")))
inline double logRound(double x, double mean) {
@@ -281,65 +261,8 @@
static_cast<long long>(hash), static_cast<long long>(startingTs));
static const char * const kLabel = "ms";
- auto it = buckets.begin();
- double maxDelta = it->first;
- int maxCount = it->second;
- // Compute maximum values
- while (++it != buckets.end()) {
- if (it->first > maxDelta) {
- maxDelta = it->first;
- }
- if (it->second > maxCount) {
- maxCount = it->second;
- }
- }
- int height = log2(maxCount) + 1; // maxCount > 0, safe to call log2
- const int leftPadding = widthOf(1 << height);
- const int bucketWidth = numberWidth(maxDelta, leftPadding);
- int scalingFactor = 1;
- // scale data if it exceeds maximum height
- if (height > maxHeight) {
- scalingFactor = (height + maxHeight) / maxHeight;
- height /= scalingFactor;
- }
- body->appendFormat("%s", title);
- // write histogram label line with bucket values
- body->appendFormat("\n%s", " ");
- body->appendFormat("%*s", leftPadding, " ");
- for (auto const &x : buckets) {
- const int colWidth = numberWidth(x.first, leftPadding);
- body->appendFormat("%*d", colWidth, x.second);
- }
- // write histogram ascii art
- // underscores and spaces length corresponds to maximum width of histogram
- static const int kLen = 200;
- static const std::string underscores(kLen, '_');
- static const std::string spaces(kLen, ' ');
-
- body->appendFormat("\n%s", " ");
- for (int row = height * scalingFactor; row >= 0; row -= scalingFactor) {
- const int value = 1 << row;
- body->appendFormat("%.*s", leftPadding, spaces.c_str());
- for (auto const &x : buckets) {
- const int colWidth = numberWidth(x.first, leftPadding);
- body->appendFormat("%.*s%s", colWidth - 1,
- spaces.c_str(), x.second < value ? " " : "|");
- }
- body->appendFormat("\n%s", " ");
- }
- // print x-axis
- const int columns = static_cast<int>(buckets.size());
- body->appendFormat("%*c", leftPadding, ' ');
- body->appendFormat("%.*s", (columns + 1) * bucketWidth, underscores.c_str());
- body->appendFormat("\n%s", " ");
-
- // write footer with bucket labels
- body->appendFormat("%*s", leftPadding, " ");
- for (auto const &x : buckets) {
- const int colWidth = numberWidth(x.first, leftPadding);
- body->appendFormat("%*.*f", colWidth, 1, x.first);
- }
- body->appendFormat("%.*s%s\n", bucketWidth, spaces.c_str(), kLabel);
+ body->appendFormat("%s",
+ audio_utils_plot_histogram(buckets, title, kLabel, maxHeight).c_str());
// Now report glitches
body->appendFormat("\ntime elapsed between glitches and glitch timestamps:\n");
diff --git a/media/libnblog/include/media/nblog/PerformanceAnalysis.h b/media/libnblog/include/media/nblog/PerformanceAnalysis.h
index ddfe9d6..56e0ea6 100644
--- a/media/libnblog/include/media/nblog/PerformanceAnalysis.h
+++ b/media/libnblog/include/media/nblog/PerformanceAnalysis.h
@@ -25,6 +25,8 @@
namespace android {
+class String8;
+
namespace ReportPerformance {
class PerformanceAnalysis;
diff --git a/media/libnblog/include/media/nblog/ReportPerformance.h b/media/libnblog/include/media/nblog/ReportPerformance.h
index ec0842f..1b11197 100644
--- a/media/libnblog/include/media/nblog/ReportPerformance.h
+++ b/media/libnblog/include/media/nblog/ReportPerformance.h
@@ -23,9 +23,6 @@
namespace android {
-// The String8 class is used by reportPerformance function
-class String8;
-
namespace ReportPerformance {
constexpr int kMsPerSec = 1000;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 5361159..353e407 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -1943,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/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/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index c389683..9234364 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1877,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/Threads.cpp b/services/audioflinger/Threads.cpp
index 1e411c7..d55da1b 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3354,7 +3354,7 @@
continue;
}
- if ((!mActiveTracks.size() && systemTime() > mStandbyTimeNs) ||
+ if ((mActiveTracks.isEmpty() && systemTime() > mStandbyTimeNs) ||
isSuspended()) {
// put audio hardware into standby after short delay
if (shouldStandby_l()) {
@@ -3368,7 +3368,7 @@
mStandby = true;
}
- if (!mActiveTracks.size() && mConfigEvents.isEmpty()) {
+ if (mActiveTracks.isEmpty() && mConfigEvents.isEmpty()) {
// we're about to wait, flush the binder command buffer
IPCThreadState::self()->flushCommands();
@@ -6649,7 +6649,7 @@
}
// sleep if there are no active tracks to process
- if (activeTracks.size() == 0) {
+ if (activeTracks.isEmpty()) {
if (sleepUs == 0) {
sleepUs = kRecordThreadSleepUs;
}
@@ -7443,7 +7443,7 @@
audio_input_flags_t flags = input != NULL ? input->flags : AUDIO_INPUT_FLAG_NONE;
dprintf(fd, " AudioStreamIn: %p flags %#x (%s)\n",
input, flags, inputFlagsToString(flags).c_str());
- if (mActiveTracks.size() == 0) {
+ if (mActiveTracks.isEmpty()) {
dprintf(fd, " No active record clients\n");
}
@@ -7909,7 +7909,7 @@
status_t AudioFlinger::RecordThread::addEffectChain_l(const sp<EffectChain>& chain)
{
// only one chain per input thread
- if (mEffectChains.size() != 0) {
+ if (!mEffectChains.isEmpty()) {
ALOGW("addEffectChain_l() already one chain %p on thread %p", chain.get(), this);
return INVALID_OPERATION;
}
@@ -8245,7 +8245,7 @@
// abort if start is rejected by audio policy manager
if (ret != NO_ERROR) {
ALOGE("%s: error start rejected by AudioPolicyManager = %d", __FUNCTION__, ret);
- if (mActiveTracks.size() != 0) {
+ if (!mActiveTracks.isEmpty()) {
mLock.unlock();
if (isOutput()) {
AudioSystem::releaseOutput(portId);
@@ -8346,7 +8346,7 @@
if (mHalStream == 0) {
return NO_INIT;
}
- if (mActiveTracks.size() != 0) {
+ if (!mActiveTracks.isEmpty()) {
return INVALID_OPERATION;
}
mHalStream->standby();
@@ -8784,7 +8784,7 @@
dprintf(fd, " Attributes: content type %d usage %d source %d\n",
mAttr.content_type, mAttr.usage, mAttr.source);
dprintf(fd, " Session: %d port Id: %d\n", mSessionId, mPortId);
- if (mActiveTracks.size() == 0) {
+ if (mActiveTracks.isEmpty()) {
dprintf(fd, " No active clients\n");
}
}
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 847a9c6..dc23717 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -555,6 +555,9 @@
size_t size() const {
return mActiveTracks.size();
}
+ bool isEmpty() const {
+ return mActiveTracks.isEmpty();
+ }
ssize_t indexOf(const sp<T>& item) {
return mActiveTracks.indexOf(item);
}
diff --git a/services/audiopolicy/common/managerdefinitions/Android.mk b/services/audiopolicy/common/managerdefinitions/Android.mk
index b3611c4..09dbb32 100644
--- a/services/audiopolicy/common/managerdefinitions/Android.mk
+++ b/services/audiopolicy/common/managerdefinitions/Android.mk
@@ -21,7 +21,8 @@
src/AudioSourceDescriptor.cpp \
src/VolumeCurve.cpp \
src/TypeConverter.cpp \
- src/AudioSession.cpp
+ src/AudioSession.cpp \
+ src/ClientDescriptor.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
index 9f3fc0c..555412e 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioIODescriptorInterface.h
@@ -34,12 +34,4 @@
virtual void setPatchHandle(audio_patch_handle_t handle) = 0;
};
-class AudioIODescriptorUpdateListener
-{
-public:
- virtual ~AudioIODescriptorUpdateListener() {};
-
- virtual void onIODescriptorUpdate() const = 0;
-};
-
} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
index 85f3b86..ca837c4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioInputDescriptor.h
@@ -66,6 +66,8 @@
AudioSessionCollection getAudioSessions(bool activeOnly) const;
size_t getAudioSessionCount(bool activeOnly) const;
audio_source_t getHighestPrioritySource(bool activeOnly) const;
+ void changeRefCount(audio_session_t session, int delta);
+
// implementation of AudioIODescriptorInterface
audio_config_base_t getConfig() const override;
@@ -79,14 +81,17 @@
audio_input_flags_t flags,
audio_io_handle_t *input);
// Called when a stream is about to be started.
- // Note: called after AudioSession::changeActiveCount(1)
+ // Note: called after changeRefCount(session, 1)
status_t start();
// Called after a stream is stopped
- // Note: called after AudioSession::changeActiveCount(-1)
+ // Note: called after changeRefCount(session, -1)
void stop();
void close();
private:
+
+ void updateSessionRecordingConfiguration(int event, const sp<AudioSession>& audioSession);
+
audio_patch_handle_t mPatchHandle;
audio_port_handle_t mId;
// audio sessions attached to this input
@@ -99,6 +104,7 @@
// We also inherit sessions from the preempted input to avoid a 3 way preemption loop etc...
SortedVector<audio_session_t> mPreemptedSessions;
AudioPolicyClientInterface *mClientInterface;
+ uint32_t mGlobalRefCount; // non-session-specific ref count
};
class AudioInputCollection :
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
index 57d1cfa..292e59f 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioOutputDescriptor.h
@@ -17,7 +17,6 @@
#pragma once
#include <sys/types.h>
-
#include "AudioPort.h"
#include <RoutingStrategy.h>
#include <utils/Errors.h>
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h b/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h
index 4226ff2..d2fc6a3 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioProfile.h
@@ -27,11 +27,42 @@
namespace android {
typedef SortedVector<uint32_t> SampleRateVector;
-typedef SortedVector<audio_channel_mask_t> ChannelsVector;
typedef Vector<audio_format_t> FormatVector;
template <typename T>
-bool operator == (const SortedVector<T> &left, const SortedVector<T> &right);
+bool operator== (const SortedVector<T> &left, const SortedVector<T> &right)
+{
+ if (left.size() != right.size()) {
+ return false;
+ }
+ for (size_t index = 0; index < right.size(); index++) {
+ if (left[index] != right[index]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+template <typename T>
+bool operator!= (const SortedVector<T> &left, const SortedVector<T> &right)
+{
+ return !(left == right);
+}
+
+class ChannelsVector : public SortedVector<audio_channel_mask_t>
+{
+public:
+ ChannelsVector() = default;
+ ChannelsVector(const ChannelsVector&) = default;
+ ChannelsVector(const SortedVector<audio_channel_mask_t>& sv) :
+ SortedVector<audio_channel_mask_t>(sv) {}
+ ChannelsVector& operator=(const ChannelsVector&) = default;
+
+ // Applies audio_channel_mask_out_to_in to all elements and returns the result.
+ ChannelsVector asInMask() const;
+ // Applies audio_channel_mask_in_to_out to all elements and returns the result.
+ ChannelsVector asOutMask() const;
+};
class AudioProfile : public virtual RefBase
{
@@ -194,6 +225,16 @@
return 0;
}
+ sp<AudioProfile> getFirstValidProfileFor(audio_format_t format) const
+ {
+ for (size_t i = 0; i < size(); i++) {
+ if (itemAt(i)->isValid() && itemAt(i)->getFormat() == format) {
+ return itemAt(i);
+ }
+ }
+ return 0;
+ }
+
bool hasValidProfile() const { return getFirstValidProfile() != 0; }
status_t checkExactProfile(uint32_t samplingRate, audio_channel_mask_t channelMask,
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
index 53e6ec9..1636d3a 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioSession.h
@@ -29,7 +29,7 @@
class AudioPolicyClientInterface;
-class AudioSession : public RefBase, public AudioIODescriptorUpdateListener
+class AudioSession : public RefBase
{
public:
AudioSession(audio_session_t session,
@@ -39,9 +39,7 @@
audio_channel_mask_t channelMask,
audio_input_flags_t flags,
uid_t uid,
- bool isSoundTrigger,
- AudioMix* policyMix,
- AudioPolicyClientInterface *clientInterface);
+ bool isSoundTrigger);
status_t dump(int fd, int spaces, int index) const;
@@ -50,6 +48,8 @@
audio_format_t format() const { return mConfig.format; }
uint32_t sampleRate() const { return mConfig.sample_rate; }
audio_channel_mask_t channelMask() const { return mConfig.channel_mask; }
+ audio_config_base config() const { return mConfig; }
+ record_client_info_t recordClientInfo() const { return mRecordClientInfo; }
audio_input_flags_t flags() const { return mFlags; }
uid_t uid() const { return mRecordClientInfo.uid; }
void setUid(uid_t uid) { mRecordClientInfo.uid = uid; }
@@ -63,10 +63,6 @@
uint32_t changeOpenCount(int delta);
uint32_t changeActiveCount(int delta);
- void setInfoProvider(AudioIODescriptorInterface *provider);
- // implementation of AudioIODescriptorUpdateListener
- virtual void onIODescriptorUpdate() const;
-
private:
record_client_info_t mRecordClientInfo;
const struct audio_config_base mConfig;
@@ -75,19 +71,14 @@
bool mSilenced;
uint32_t mOpenCount;
uint32_t mActiveCount;
- AudioMix* mPolicyMix; // non NULL when used by a dynamic policy
- AudioPolicyClientInterface* mClientInterface;
- const AudioIODescriptorInterface* mInfoProvider;
};
class AudioSessionCollection :
- public DefaultKeyedVector<audio_session_t, sp<AudioSession> >,
- public AudioIODescriptorUpdateListener
+ public DefaultKeyedVector<audio_session_t, sp<AudioSession> >
{
public:
status_t addSession(audio_session_t session,
- const sp<AudioSession>& audioSession,
- AudioIODescriptorInterface *provider);
+ const sp<AudioSession>& audioSession);
status_t removeSession(audio_session_t session);
@@ -99,9 +90,6 @@
bool isSourceActive(audio_source_t source) const;
audio_source_t getHighestPrioritySource(bool activeOnly) const;
- // implementation of AudioIODescriptorUpdateListener
- virtual void onIODescriptorUpdate() const;
-
status_t dump(int fd, int spaces) const;
};
diff --git a/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
new file mode 100644
index 0000000..fb09932
--- /dev/null
+++ b/services/audiopolicy/common/managerdefinitions/include/ClientDescriptor.h
@@ -0,0 +1,101 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <system/audio.h>
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+namespace android {
+
+class ClientDescriptor: public RefBase
+{
+public:
+ ClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_session_t sessionId,
+ audio_attributes_t attributes, audio_config_base_t config,
+ audio_port_handle_t preferredDeviceId) :
+ mPortId(portId), mUid(uid), mSessionId(sessionId), mAttributes(attributes),
+ mConfig(config), mPreferredDeviceId(preferredDeviceId), mActive(false) {}
+ ~ClientDescriptor() override = default;
+
+ virtual status_t dump(int fd);
+
+ audio_port_handle_t portId() const { return mPortId; }
+ uid_t uid() const { return mUid; }
+ audio_session_t session() const { return mSessionId; };
+ audio_attributes_t attributes() const { return mAttributes; }
+ audio_config_base_t config() const { return mConfig; }
+ audio_port_handle_t preferredDeviceId() const { return mPreferredDeviceId; };
+ void setActive(bool active) { mActive = active; }
+ bool active() const { return mActive; }
+
+private:
+ const audio_port_handle_t mPortId; // unique Id for this client
+ const uid_t mUid; // client UID
+ const audio_session_t mSessionId; // audio session ID
+ const audio_attributes_t mAttributes; // usage...
+ const audio_config_base_t mConfig;
+ const audio_port_handle_t mPreferredDeviceId; // selected input device port ID
+ bool mActive;
+};
+
+class TrackClientDescriptor: public ClientDescriptor
+{
+public:
+ TrackClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_session_t sessionId,
+ audio_attributes_t attributes, audio_config_base_t config,
+ audio_port_handle_t preferredDeviceId,
+ audio_stream_type_t stream, audio_output_flags_t flags) :
+ ClientDescriptor(portId, uid, sessionId, attributes, config, preferredDeviceId),
+ mStream(stream), mFlags(flags) {}
+ ~TrackClientDescriptor() override = default;
+
+ status_t dump(int fd) override;
+
+ audio_output_flags_t flags() const { return mFlags; }
+ audio_stream_type_t stream() const { return mStream; }
+
+private:
+ const audio_stream_type_t mStream;
+ const audio_output_flags_t mFlags;
+};
+
+class RecordClientDescriptor: public ClientDescriptor
+{
+public:
+ RecordClientDescriptor(audio_port_handle_t portId, uid_t uid, audio_session_t sessionId,
+ audio_attributes_t attributes, audio_config_base_t config,
+ audio_port_handle_t preferredDeviceId,
+ audio_source_t source, audio_input_flags_t flags) :
+ ClientDescriptor(portId, uid, sessionId, attributes, config, preferredDeviceId),
+ mSource(source), mFlags(flags) {}
+ ~RecordClientDescriptor() override = default;
+
+ status_t dump(int fd) override;
+
+ audio_source_t source() const { return mSource; }
+ audio_input_flags_t flags() const { return mFlags; }
+
+private:
+ const audio_source_t mSource;
+ const audio_input_flags_t mFlags;
+};
+
+} // namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
index f0144db..b9895a9 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioInputDescriptor.cpp
@@ -32,7 +32,7 @@
: mIoHandle(0),
mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL),
mProfile(profile), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0),
- mClientInterface(clientInterface)
+ mClientInterface(clientInterface), mGlobalRefCount(0)
{
if (profile != NULL) {
profile->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
@@ -164,7 +164,7 @@
status_t AudioInputDescriptor::addAudioSession(audio_session_t session,
const sp<AudioSession>& audioSession) {
- return mSessions.addSession(session, audioSession, /*AudioIODescriptorInterface*/this);
+ return mSessions.addSession(session, audioSession);
}
status_t AudioInputDescriptor::removeAudioSession(audio_session_t session) {
@@ -179,7 +179,11 @@
void AudioInputDescriptor::setPatchHandle(audio_patch_handle_t handle)
{
mPatchHandle = handle;
- mSessions.onIODescriptorUpdate();
+ for (size_t i = 0; i < mSessions.size(); i++) {
+ if (mSessions[i]->activeCount() > 0) {
+ updateSessionRecordingConfiguration(RECORD_CONFIG_EVENT_START, mSessions[i]);
+ }
+ }
}
audio_config_base_t AudioInputDescriptor::getConfig() const
@@ -266,7 +270,7 @@
LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
__FUNCTION__, mProfile->curOpenCount);
// do not call stop() here as stop() is supposed to be called after
- // AudioSession::changeActiveCount(-1) and we don't know how many sessions
+ // changeRefCount(session, -1) and we don't know how many sessions
// are still active at this time
if (isActive()) {
mProfile->curActiveCount--;
@@ -276,6 +280,66 @@
}
}
+void AudioInputDescriptor::changeRefCount(audio_session_t session, int delta)
+{
+ sp<AudioSession> audioSession = mSessions.valueFor(session);
+ if (audioSession == 0) {
+ return;
+ }
+ // handle session-independent ref count
+ uint32_t oldGlobalRefCount = mGlobalRefCount;
+ if ((delta + (int)mGlobalRefCount) < 0) {
+ ALOGW("changeRefCount() invalid delta %d globalRefCount %d", delta, mGlobalRefCount);
+ delta = -((int)mGlobalRefCount);
+ }
+ mGlobalRefCount += delta;
+ if ((oldGlobalRefCount == 0) && (mGlobalRefCount > 0)) {
+ if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
+ {
+ mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
+ MIX_STATE_MIXING);
+ }
+
+ } else if ((oldGlobalRefCount > 0) && (mGlobalRefCount == 0)) {
+ if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
+ {
+ mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
+ MIX_STATE_IDLE);
+ }
+ }
+
+ uint32_t oldActiveCount = audioSession->activeCount();
+ if ((delta + (int)oldActiveCount) < 0) {
+ ALOGW("changeRefCount() invalid delta %d for sesion %d active count %d",
+ delta, session, oldActiveCount);
+ delta = -((int)oldActiveCount);
+ }
+
+ audioSession->changeActiveCount(delta);
+
+ int event = RECORD_CONFIG_EVENT_NONE;
+ if ((oldActiveCount == 0) && (audioSession->activeCount() > 0)) {
+ event = RECORD_CONFIG_EVENT_START;
+ } else if ((oldActiveCount > 0) && (audioSession->activeCount() == 0)) {
+ event = RECORD_CONFIG_EVENT_STOP;
+ }
+ if (event != RECORD_CONFIG_EVENT_NONE) {
+ updateSessionRecordingConfiguration(event, audioSession);
+ }
+
+}
+
+void AudioInputDescriptor::updateSessionRecordingConfiguration(
+ int event, const sp<AudioSession>& audioSession) {
+
+ const audio_config_base_t sessionConfig = audioSession->config();
+ const record_client_info_t recordClientInfo = audioSession->recordClientInfo();
+ const audio_config_base_t config = getConfig();
+ mClientInterface->onRecordingConfigurationUpdate(event,
+ &recordClientInfo, &sessionConfig,
+ &config, mPatchHandle);
+}
+
status_t AudioInputDescriptor::dump(int fd)
{
const size_t SIZE = 256;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
index 26af9b4..e8fe5ff 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioProfile.cpp
@@ -28,6 +28,28 @@
namespace android {
+ChannelsVector ChannelsVector::asInMask() const
+{
+ ChannelsVector inMaskVector;
+ for (const auto& channel : *this) {
+ if (audio_channel_mask_out_to_in(channel) != AUDIO_CHANNEL_INVALID) {
+ inMaskVector.add(audio_channel_mask_out_to_in(channel));
+ }
+ }
+ return inMaskVector;
+}
+
+ChannelsVector ChannelsVector::asOutMask() const
+{
+ ChannelsVector outMaskVector;
+ for (const auto& channel : *this) {
+ if (audio_channel_mask_in_to_out(channel) != AUDIO_CHANNEL_INVALID) {
+ outMaskVector.add(audio_channel_mask_in_to_out(channel));
+ }
+ }
+ return outMaskVector;
+}
+
static AudioProfile* createFullDynamicImpl()
{
AudioProfile* dynamicProfile = new AudioProfile(gDynamicFormat,
@@ -56,20 +78,6 @@
return BAD_VALUE;
}
-template <typename T>
-bool operator == (const SortedVector<T> &left, const SortedVector<T> &right)
-{
- if (left.size() != right.size()) {
- return false;
- }
- for(size_t index = 0; index < right.size(); index++) {
- if (left[index] != right[index]) {
- return false;
- }
- }
- return true;
-}
-
bool operator == (const AudioProfile &left, const AudioProfile &compareTo)
{
return (left.getFormat() == compareTo.getFormat()) &&
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
index 91dee35..5ea4c92 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioSession.cpp
@@ -35,14 +35,11 @@
audio_channel_mask_t channelMask,
audio_input_flags_t flags,
uid_t uid,
- bool isSoundTrigger,
- AudioMix* policyMix,
- AudioPolicyClientInterface *clientInterface) :
+ bool isSoundTrigger) :
mRecordClientInfo({ .uid = uid, .session = session, .source = inputSource}),
mConfig({ .format = format, .sample_rate = sampleRate, .channel_mask = channelMask}),
mFlags(flags), mIsSoundTrigger(isSoundTrigger),
- mOpenCount(1), mActiveCount(0), mPolicyMix(policyMix), mClientInterface(clientInterface),
- mInfoProvider(NULL)
+ mOpenCount(1), mActiveCount(0)
{
}
@@ -60,7 +57,6 @@
uint32_t AudioSession::changeActiveCount(int delta)
{
- const uint32_t oldActiveCount = mActiveCount;
if ((delta + (int)mActiveCount) < 0) {
ALOGW("%s invalid delta %d, active count %d",
__FUNCTION__, delta, mActiveCount);
@@ -68,34 +64,6 @@
}
mActiveCount += delta;
ALOGV("%s active count %d", __FUNCTION__, mActiveCount);
- int event = RECORD_CONFIG_EVENT_NONE;
-
- if ((oldActiveCount == 0) && (mActiveCount > 0)) {
- event = RECORD_CONFIG_EVENT_START;
- } else if ((oldActiveCount > 0) && (mActiveCount == 0)) {
- event = RECORD_CONFIG_EVENT_STOP;
- }
-
- if (event != RECORD_CONFIG_EVENT_NONE) {
- // Dynamic policy callback:
- // if input maps to a dynamic policy with an activity listener, notify of state change
- if ((mPolicyMix != NULL) && ((mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0))
- {
- mClientInterface->onDynamicPolicyMixStateUpdate(mPolicyMix->mDeviceAddress,
- (event == RECORD_CONFIG_EVENT_START) ? MIX_STATE_MIXING : MIX_STATE_IDLE);
- }
-
- // Recording configuration callback:
- const AudioIODescriptorInterface* provider = mInfoProvider;
- const audio_config_base_t deviceConfig = (provider != NULL) ? provider->getConfig() :
- AUDIO_CONFIG_BASE_INITIALIZER;
- const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() :
- AUDIO_PATCH_HANDLE_NONE;
- if (patchHandle != AUDIO_PATCH_HANDLE_NONE) {
- mClientInterface->onRecordingConfigurationUpdate(event, &mRecordClientInfo,
- &mConfig, &deviceConfig, patchHandle);
- }
- }
return mActiveCount;
}
@@ -114,27 +82,6 @@
return false;
}
-void AudioSession::setInfoProvider(AudioIODescriptorInterface *provider)
-{
- mInfoProvider = provider;
-}
-
-void AudioSession::onIODescriptorUpdate() const
-{
- if (mActiveCount > 0) {
- // resend the callback after requerying the informations from the info provider
- const AudioIODescriptorInterface* provider = mInfoProvider;
- const audio_config_base_t deviceConfig = (provider != NULL) ? provider->getConfig() :
- AUDIO_CONFIG_BASE_INITIALIZER;
- const audio_patch_handle_t patchHandle = (provider != NULL) ? provider->getPatchHandle() :
- AUDIO_PATCH_HANDLE_NONE;
- if (patchHandle != AUDIO_PATCH_HANDLE_NONE) {
- mClientInterface->onRecordingConfigurationUpdate(RECORD_CONFIG_EVENT_START,
- &mRecordClientInfo, &mConfig, &deviceConfig, patchHandle);
- }
- }
-}
-
status_t AudioSession::dump(int fd, int spaces, int index) const
{
const size_t SIZE = 256;
@@ -169,8 +116,7 @@
}
status_t AudioSessionCollection::addSession(audio_session_t session,
- const sp<AudioSession>& audioSession,
- AudioIODescriptorInterface *provider)
+ const sp<AudioSession>& audioSession)
{
ssize_t index = indexOfKey(session);
@@ -178,7 +124,6 @@
ALOGW("addSession() session %d already in", session);
return ALREADY_EXISTS;
}
- audioSession->setInfoProvider(provider);
add(session, audioSession);
ALOGV("addSession() session %d client %d source %d",
session, audioSession->uid(), audioSession->inputSource());
@@ -194,7 +139,6 @@
return ALREADY_EXISTS;
}
ALOGV("removeSession() session %d", session);
- valueAt(index)->setInfoProvider(NULL);
removeItemsAt(index);
return NO_ERROR;
}
@@ -271,13 +215,6 @@
return source;
}
-void AudioSessionCollection::onIODescriptorUpdate() const
-{
- for (size_t i = 0; i < size(); i++) {
- valueAt(i)->onIODescriptorUpdate();
- }
-}
-
status_t AudioSessionCollection::dump(int fd, int spaces) const
{
const size_t SIZE = 256;
diff --git a/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
new file mode 100644
index 0000000..1e64d2e
--- /dev/null
+++ b/services/audiopolicy/common/managerdefinitions/src/ClientDescriptor.cpp
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "APM_ClientDescriptor"
+//#define LOG_NDEBUG 0
+
+#include <utils/String8.h>
+#include "ClientDescriptor.h"
+
+namespace android {
+
+status_t ClientDescriptor::dump(int fd)
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+
+ snprintf(buffer, SIZE, " Port ID: %d Session Id: %d UID: %d\n", mPortId, mSessionId, mUid);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Format: %08x Sampling rate: %d Channels: %08x\n",
+ mConfig.format, mConfig.sample_rate, mConfig.channel_mask);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " Preferred Device Id: %08x\n", mPreferredDeviceId);
+ result.append(buffer);
+ snprintf(buffer, SIZE, " State: %s\n", mActive ? "Active" : "Inactive");
+ result.append(buffer);
+
+ write(fd, result.string(), result.size());
+
+ return NO_ERROR;
+}
+
+status_t TrackClientDescriptor::dump(int fd)
+{
+ ClientDescriptor::dump(fd);
+
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+
+ snprintf(buffer, SIZE, " Stream: %d flags: %08x\n", mStream, mFlags);
+ result.append(buffer);
+
+ write(fd, result.string(), result.size());
+
+ return NO_ERROR;
+}
+
+status_t RecordClientDescriptor::dump(int fd)
+{
+ ClientDescriptor::dump(fd);
+
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+
+ snprintf(buffer, SIZE, " Source: %d flags: %08x\n", mSource, mFlags);
+ result.append(buffer);
+
+ write(fd, result.string(), result.size());
+
+ return NO_ERROR;
+}
+
+}; //namespace android
diff --git a/services/audiopolicy/common/managerdefinitions/src/SessionRoute.cpp b/services/audiopolicy/common/managerdefinitions/src/SessionRoute.cpp
index 38ab560..440a4e7 100644
--- a/services/audiopolicy/common/managerdefinitions/src/SessionRoute.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/SessionRoute.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "APM::SessionRoute"
+#define LOG_TAG "APM_SessionRoute"
//#define LOG_NDEBUG 0
#include "SessionRoute.h"
@@ -122,19 +122,17 @@
audio_devices_t SessionRouteMap::getActiveDeviceForStream(audio_stream_type_t streamType,
const DeviceVector& availableDevices)
{
- audio_devices_t device = AUDIO_DEVICE_NONE;
-
for (size_t index = 0; index < size(); index++) {
sp<SessionRoute> route = valueAt(index);
if (streamType == route->mStreamType && route->isActiveOrChanged()
&& route->mDeviceDescriptor != 0) {
- device = route->mDeviceDescriptor->type();
+ audio_devices_t device = route->mDeviceDescriptor->type();
if (!availableDevices.getDevicesFromTypeMask(device).isEmpty()) {
- break;
+ return device;
}
}
}
- return device;
+ return AUDIO_DEVICE_NONE;
}
} // namespace android
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 bc9514f..856bcb3 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1689,74 +1689,7 @@
config->channel_mask,
flags,
uid,
- isSoundTrigger,
- policyMix, mpClientInterface);
-
-// FIXME: disable concurrent capture until UI is ready
-#if 0
- // reuse an open input if possible
- sp<AudioInputDescriptor> reusedInputDesc;
- for (size_t i = 0; i < mInputs.size(); i++) {
- sp<AudioInputDescriptor> desc = mInputs.valueAt(i);
- // reuse input if:
- // - it shares the same profile
- // AND
- // - it is not a reroute submix input
- // AND
- // - it is: not used for sound trigger
- // OR
- // used for sound trigger and all clients use the same session ID
- //
- if ((profile == desc->mProfile) &&
- (isSoundTrigger == desc->isSoundTrigger()) &&
- !is_virtual_input_device(device)) {
-
- sp<AudioSession> as = desc->getAudioSession(session);
- if (as != 0) {
- // do not allow unmatching properties on same session
- if (as->matches(audioSession)) {
- as->changeOpenCount(1);
- } else {
- ALOGW("getInputForDevice() record with different attributes"
- " exists for session %d", session);
- continue;
- }
- } else if (isSoundTrigger) {
- continue;
- }
-
- // Reuse the already opened input stream on this profile if:
- // - the new capture source is background OR
- // - the path requested configurations match OR
- // - the new source priority is less than the highest source priority on this input
- // If the input stream cannot be reused, close it before opening a new stream
- // on the same profile for the new client so that the requested path configuration
- // can be selected.
- if (!isConcurrentSource(inputSource) &&
- ((desc->mSamplingRate != samplingRate ||
- desc->mChannelMask != config->channel_mask ||
- !audio_formats_match(desc->mFormat, config->format)) &&
- (source_priority(desc->getHighestPrioritySource(false /*activeOnly*/)) <
- source_priority(inputSource)))) {
- reusedInputDesc = desc;
- continue;
- } else {
- desc->addAudioSession(session, audioSession);
- ALOGV("%s: reusing input %d", __FUNCTION__, mInputs.keyAt(i));
- return mInputs.keyAt(i);
- }
- }
- }
-
- if (reusedInputDesc != 0) {
- AudioSessionCollection sessions = reusedInputDesc->getAudioSessions(false /*activeOnly*/);
- for (size_t j = 0; j < sessions.size(); j++) {
- audio_session_t currentSession = sessions.keyAt(j);
- stopInput(reusedInputDesc->mIoHandle, currentSession);
- releaseInput(reusedInputDesc->mIoHandle, currentSession);
- }
- }
-#endif
+ isSoundTrigger);
if (!profile->canOpenNewIo()) {
return AUDIO_IO_HANDLE_NONE;
@@ -1901,20 +1834,6 @@
return BAD_VALUE;
}
-// FIXME: disable concurrent capture until UI is ready
-#if 0
- if (!isConcurentCaptureAllowed(inputDesc, audioSession)) {
- ALOGW("startInput(%d) failed: other input already started", input);
- return INVALID_OPERATION;
- }
-
- if (isInCall()) {
- *concurrency |= API_INPUT_CONCURRENCY_CALL;
- }
- if (mInputs.activeInputsCountOnDevices() != 0) {
- *concurrency |= API_INPUT_CONCURRENCY_CAPTURE;
- }
-#else
if (!is_virtual_input_device(inputDesc->mDevice)) {
if (mCallTxPatch != 0 &&
inputDesc->getModuleHandle() == mCallTxPatch->mPatch.sources[0].ext.device.hw_module) {
@@ -2010,14 +1929,13 @@
}
}
}
-#endif
// Make sure we start with the correct silence state
audioSession->setSilenced(silenced);
// increment activity count before calling getNewInputDevice() below as only active sessions
// are considered for device selection
- audioSession->changeActiveCount(1);
+ inputDesc->changeRefCount(session, 1);
// Routing?
mInputRoutes.incRouteActivity(session);
@@ -2031,7 +1949,7 @@
status_t status = inputDesc->start();
if (status != NO_ERROR) {
mInputRoutes.decRouteActivity(session);
- audioSession->changeActiveCount(-1);
+ inputDesc->changeRefCount(session, -1);
return status;
}
@@ -2095,7 +2013,7 @@
return INVALID_OPERATION;
}
- audioSession->changeActiveCount(-1);
+ inputDesc->changeRefCount(session, -1);
// Routing?
mInputRoutes.decRouteActivity(session);
@@ -3426,7 +3344,7 @@
return NO_ERROR;
}
-status_t AudioPolicyManager::stopAudioSource(audio_patch_handle_t handle __unused)
+status_t AudioPolicyManager::stopAudioSource(audio_patch_handle_t handle)
{
sp<AudioSourceDescriptor> sourceDesc = mAudioSources.valueFor(handle);
ALOGV("%s handle %d", __FUNCTION__, handle);
@@ -4637,20 +4555,6 @@
return outputs;
}
-bool AudioPolicyManager::vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
- SortedVector<audio_io_handle_t>& outputs2)
-{
- if (outputs1.size() != outputs2.size()) {
- return false;
- }
- for (size_t i = 0; i < outputs1.size(); i++) {
- if (outputs1[i] != outputs2[i]) {
- return false;
- }
- }
- return true;
-}
-
void AudioPolicyManager::checkForDeviceAndOutputChanges()
{
checkForDeviceAndOutputChanges([](){ return false; });
@@ -4691,7 +4595,7 @@
}
}
- if (!vectorsEqual(srcOutputs,dstOutputs)) {
+ if (srcOutputs != dstOutputs) {
// get maximum latency of all source outputs to determine the minimum mute time guaranteeing
// audio from invalidated tracks will be rendered when unmuting
uint32_t maxLatency = 0;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 70ca39f..e412645 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -39,6 +39,7 @@
#include <AudioPolicyConfig.h>
#include <AudioPort.h>
#include <AudioPatch.h>
+#include <AudioProfile.h>
#include <DeviceDescriptor.h>
#include <IOProfile.h>
#include <HwModule.h>
@@ -459,8 +460,6 @@
SortedVector<audio_io_handle_t> getOutputsForDevice(audio_devices_t device,
const SwAudioOutputCollection& openOutputs);
- bool vectorsEqual(SortedVector<audio_io_handle_t>& outputs1,
- SortedVector<audio_io_handle_t>& outputs2);
// mute/unmute strategies using an incompatible device combination
// if muting, wait for the audio in pcm buffer to be drained before proceeding
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index baf051a..84428c2 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -1682,9 +1682,12 @@
// WORKAROUND: HAL refuses to disconnect while there's streams in flight
{
- mDevice->clearStreamingRequest();
-
+ int64_t lastFrameNumber;
status_t code;
+ if ((code = mDevice->flush(&lastFrameNumber)) != OK) {
+ ALOGE("%s: flush failed with code 0x%x", __FUNCTION__, code);
+ }
+
if ((code = mDevice->waitUntilDrained()) != OK) {
ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
code);
diff --git a/services/mediacodec/seccomp_policy/mediacodec-x86.policy b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
index 6e6b276..4031b11 100644
--- a/services/mediacodec/seccomp_policy/mediacodec-x86.policy
+++ b/services/mediacodec/seccomp_policy/mediacodec-x86.policy
@@ -24,6 +24,7 @@
mmap2: 1
fstat64: 1
stat64: 1
+statfs64: 1
madvise: 1
fstatat64: 1
futex: 1