Merge "Camera: Advertise only unique API1 compatible devices" into oc-dev
diff --git a/media/libaaudio/include/aaudio/AAudio.h b/media/libaaudio/include/aaudio/AAudio.h
index c21caa4..4e36e84 100644
--- a/media/libaaudio/include/aaudio/AAudio.h
+++ b/media/libaaudio/include/aaudio/AAudio.h
@@ -209,14 +209,13 @@
/**
* Request a sample rate in Hertz.
*
- * The stream may be opened with a different sample rate.
- * So the application should query for the actual rate after the stream is opened.
- *
- * Technically, this should be called the "frame rate" or "frames per second",
- * because it refers to the number of complete frames transferred per second.
- * But it is traditionally called "sample rate". So we use that term.
- *
* The default, if you do not call this function, is AAUDIO_UNSPECIFIED.
+ * An optimal value will then be chosen when the stream is opened.
+ * After opening a stream with an unspecified value, the application must
+ * query for the actual value, which may vary by device.
+ *
+ * If an exact value is specified then an opened stream will use that value.
+ * If a stream cannot be opened with the specified value then the open will fail.
*
* @param builder reference provided by AAudio_createStreamBuilder()
* @param sampleRate frames per second. Common rates include 44100 and 48000 Hz.
@@ -227,12 +226,13 @@
/**
* Request a number of channels for the stream.
*
- * The stream may be opened with a different value.
- * So the application should query for the actual value after the stream is opened.
- *
* The default, if you do not call this function, is AAUDIO_UNSPECIFIED.
+ * An optimal value will then be chosen when the stream is opened.
+ * After opening a stream with an unspecified value, the application must
+ * query for the actual value, which may vary by device.
*
- * Note, this quantity is sometimes referred to as "samples per frame".
+ * If an exact value is specified then an opened stream will use that value.
+ * If a stream cannot be opened with the specified value then the open will fail.
*
* @param builder reference provided by AAudio_createStreamBuilder()
* @param channelCount Number of channels desired.
@@ -252,12 +252,15 @@
* Request a sample data format, for example AAUDIO_FORMAT_PCM_I16.
*
* The default, if you do not call this function, is AAUDIO_UNSPECIFIED.
+ * An optimal value will then be chosen when the stream is opened.
+ * After opening a stream with an unspecified value, the application must
+ * query for the actual value, which may vary by device.
*
- * The stream may be opened with a different value.
- * So the application should query for the actual value after the stream is opened.
+ * If an exact value is specified then an opened stream will use that value.
+ * If a stream cannot be opened with the specified value then the open will fail.
*
* @param builder reference provided by AAudio_createStreamBuilder()
- * @param format Most common formats are AAUDIO_FORMAT_PCM_FLOAT and AAUDIO_FORMAT_PCM_I16.
+ * @param format common formats are AAUDIO_FORMAT_PCM_FLOAT and AAUDIO_FORMAT_PCM_I16.
*/
AAUDIO_API void AAudioStreamBuilder_setFormat(AAudioStreamBuilder* builder,
aaudio_audio_format_t format);
diff --git a/media/libaaudio/src/core/AudioStreamBuilder.cpp b/media/libaaudio/src/core/AudioStreamBuilder.cpp
index 9bc2ef2..f313b58 100644
--- a/media/libaaudio/src/core/AudioStreamBuilder.cpp
+++ b/media/libaaudio/src/core/AudioStreamBuilder.cpp
@@ -91,7 +91,8 @@
AudioStream *audioStream = nullptr;
*streamPtr = nullptr;
- bool tryMMap = (sharingMode == AAUDIO_SHARING_MODE_SHARED) && MMAP_SHARED_ENABLED;
+ bool tryMMap = ((sharingMode == AAUDIO_SHARING_MODE_SHARED) && MMAP_SHARED_ENABLED) ||
+ ((sharingMode == AAUDIO_SHARING_MODE_EXCLUSIVE) && MMAP_EXCLUSIVE_ENABLED);
aaudio_result_t result = builder_createStream(getDirection(), sharingMode,
tryMMap, &audioStream);
if (result == AAUDIO_OK) {
diff --git a/media/libaaudio/tests/Android.mk b/media/libaaudio/tests/Android.mk
index 01360b1..fba81f2 100644
--- a/media/libaaudio/tests/Android.mk
+++ b/media/libaaudio/tests/Android.mk
@@ -47,3 +47,15 @@
LOCAL_STATIC_LIBRARIES := libaaudio
LOCAL_MODULE := test_linear_ramp
include $(BUILD_NATIVE_TEST)
+
+include $(CLEAR_VARS)
+LOCAL_C_INCLUDES := \
+ $(call include-path-for, audio-utils) \
+ frameworks/av/media/libaaudio/include \
+ frameworks/av/media/libaaudio/src
+LOCAL_SRC_FILES:= test_open_params.cpp
+LOCAL_SHARED_LIBRARIES := libaudioclient libaudioutils libbinder \
+ libcutils liblog libmedia libutils
+LOCAL_STATIC_LIBRARIES := libaaudio
+LOCAL_MODULE := test_open_params
+include $(BUILD_NATIVE_TEST)
diff --git a/media/libaaudio/tests/test_open_params.cpp b/media/libaaudio/tests/test_open_params.cpp
new file mode 100644
index 0000000..5125653
--- /dev/null
+++ b/media/libaaudio/tests/test_open_params.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+// Play sine waves using AAudio.
+
+#include <stdio.h>
+//#include <stdlib.h>
+//#include <math.h>
+
+#include <android-base/macros.h>
+#include <aaudio/AAudio.h>
+
+#include <gtest/gtest.h>
+
+static const char *getSharingModeText(aaudio_sharing_mode_t mode) {
+ const char *modeText = "unknown";
+ switch (mode) {
+ case AAUDIO_SHARING_MODE_EXCLUSIVE:
+ modeText = "EXCLUSIVE";
+ break;
+ case AAUDIO_SHARING_MODE_SHARED:
+ modeText = "SHARED";
+ break;
+ default:
+ break;
+ }
+ return modeText;
+}
+
+// Callback function that fills the audio output buffer.
+aaudio_data_callback_result_t MyDataCallbackProc(
+ AAudioStream *stream,
+ void *userData,
+ void *audioData,
+ int32_t numFrames
+) {
+ (void) stream;
+ (void) userData;
+ (void) audioData;
+ (void) numFrames;
+ return AAUDIO_CALLBACK_RESULT_CONTINUE;
+}
+
+static void testOpenOptions(aaudio_direction_t direction,
+ int32_t channelCount,
+ int32_t sampleRate,
+ aaudio_audio_format_t format) {
+
+ aaudio_result_t result = AAUDIO_OK;
+
+ int32_t bufferCapacity;
+ int32_t framesPerBurst = 0;
+
+ int32_t actualChannelCount = 0;
+ int32_t actualSampleRate = 0;
+ aaudio_audio_format_t actualDataFormat = AAUDIO_FORMAT_UNSPECIFIED;
+ aaudio_sharing_mode_t actualSharingMode = AAUDIO_SHARING_MODE_SHARED;
+ aaudio_direction_t actualDirection;
+
+ AAudioStreamBuilder *aaudioBuilder = nullptr;
+ AAudioStream *aaudioStream = nullptr;
+
+ printf("TestOpen: dir = %d, chans = %3d, rate = %6d format = %d\n",
+ direction, channelCount, sampleRate, format);
+
+ // Use an AAudioStreamBuilder to contain requested parameters.
+ ASSERT_EQ(AAUDIO_OK, AAudio_createStreamBuilder(&aaudioBuilder));
+
+ // Request stream properties.
+ AAudioStreamBuilder_setDirection(aaudioBuilder, direction);
+ AAudioStreamBuilder_setSampleRate(aaudioBuilder, sampleRate);
+ AAudioStreamBuilder_setChannelCount(aaudioBuilder, channelCount);
+ AAudioStreamBuilder_setFormat(aaudioBuilder, format);
+ AAudioStreamBuilder_setDataCallback(aaudioBuilder, MyDataCallbackProc, nullptr);
+
+ //AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_NONE);
+ AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_LOW_LATENCY);
+ //AAudioStreamBuilder_setPerformanceMode(aaudioBuilder, AAUDIO_PERFORMANCE_MODE_POWER_SAVING);
+
+ // Create an AAudioStream using the Builder.
+ result = AAudioStreamBuilder_openStream(aaudioBuilder, &aaudioStream);
+ if (result != AAUDIO_OK) {
+ printf("Stream not opened! That may be OK.\n");
+ goto finish;
+ }
+
+ // Check to see what kind of stream we actually got.
+ actualSampleRate = AAudioStream_getSampleRate(aaudioStream);
+ actualChannelCount = AAudioStream_getChannelCount(aaudioStream);
+ actualDataFormat = AAudioStream_getFormat(aaudioStream);
+ actualDirection = AAudioStream_getDirection(aaudioStream);
+
+ printf(" dir = %d, chans = %3d, rate = %6d format = %d\n",
+ direction, actualChannelCount, actualSampleRate, actualDataFormat);
+
+ // If we ask for something specific then we should get that.
+ if (channelCount != AAUDIO_UNSPECIFIED) {
+ EXPECT_EQ(channelCount, actualChannelCount);
+ }
+ if (sampleRate != AAUDIO_UNSPECIFIED) {
+ EXPECT_EQ(sampleRate, actualSampleRate);
+ }
+ if (format != AAUDIO_FORMAT_UNSPECIFIED) {
+ EXPECT_EQ(format, actualDataFormat);
+ }
+ EXPECT_EQ(direction, actualDirection);
+
+ // This is the number of frames that are read in one chunk by a DMA controller
+ // or a DSP or a mixer.
+ framesPerBurst = AAudioStream_getFramesPerBurst(aaudioStream);
+ bufferCapacity = AAudioStream_getBufferCapacityInFrames(aaudioStream);
+ printf(" bufferCapacity = %d, remainder = %d\n",
+ bufferCapacity, bufferCapacity % framesPerBurst);
+
+finish:
+ AAudioStream_close(aaudioStream);
+ AAudioStreamBuilder_delete(aaudioBuilder);
+ printf(" result = %d = %s\n", result, AAudio_convertResultToText(result));
+}
+
+//void foo() { // for tricking the Android Studio formatter
+TEST(test_open_params, aaudio_open_all) {
+ aaudio_direction_t directions[] = {AAUDIO_DIRECTION_OUTPUT, AAUDIO_DIRECTION_INPUT};
+ aaudio_audio_format_t formats[] = {AAUDIO_FORMAT_UNSPECIFIED, AAUDIO_FORMAT_PCM_I16, AAUDIO_FORMAT_PCM_FLOAT};
+ int32_t rates[] = {AAUDIO_UNSPECIFIED, 22050, 32000, 44100, 48000, 88200, 96000, 37913, 59132};
+
+ // Make printf print immediately so that debug info is not stuck
+ // in a buffer if we hang or crash.
+ setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
+
+ for (uint dirIndex = 0;dirIndex < arraysize(directions); dirIndex++) {
+ aaudio_direction_t direction = directions[dirIndex];
+ for (int32_t channelCount = 0; channelCount <= 8; channelCount++) {
+ testOpenOptions(direction, channelCount,
+ AAUDIO_UNSPECIFIED, AAUDIO_FORMAT_UNSPECIFIED);
+ }
+ for (uint i = 0; i < arraysize(rates); i++) {
+ testOpenOptions(direction, AAUDIO_UNSPECIFIED, rates[i], AAUDIO_FORMAT_UNSPECIFIED);
+ }
+ for (uint i = 0; i < arraysize(formats); i++) {
+ testOpenOptions(direction, AAUDIO_UNSPECIFIED, AAUDIO_UNSPECIFIED, formats[i]);
+ }
+ }
+}
diff --git a/media/libaudiohal/StreamHalHidl.cpp b/media/libaudiohal/StreamHalHidl.cpp
index 5b06b73..42785d5 100644
--- a/media/libaudiohal/StreamHalHidl.cpp
+++ b/media/libaudiohal/StreamHalHidl.cpp
@@ -158,7 +158,7 @@
if (retval == Result::OK) {
const native_handle *handle = hidlInfo.sharedMemory.handle();
if (handle->numFds > 0) {
- info->shared_memory_fd = dup(handle->data[0]);
+ info->shared_memory_fd = handle->data[0];
info->buffer_size_frames = hidlInfo.bufferSizeFrames;
info->burst_size_frames = hidlInfo.burstSizeFrames;
// info->shared_memory_address is not needed in HIDL context
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 0c06976..ad788f7 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -588,10 +588,10 @@
// log only non-empty records
// we always updateMetrics() before we get here
- // and that always injects 2 fields (duration and playing time) into
- // the record.
- // So the canonical "empty" record has 2 elements in it.
- if (mAnalyticsItem->count() > 2) {
+ // and that always injects 3 fields (duration, playing time, and
+ // datasource) into the record.
+ // So the canonical "empty" record has 3 elements in it.
+ if (mAnalyticsItem->count() > 3) {
mAnalyticsItem->setFinalized(true);
mAnalyticsItem->selfrecord();
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
index b057ffe..b1af17b 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
@@ -613,6 +613,7 @@
IV_STATUS_T status;
WORD32 level;
uint32_t displaySizeY;
+
CHECK(!mStarted);
OMX_ERRORTYPE errType = OMX_ErrorNone;
@@ -916,6 +917,9 @@
}
}
+ // clear other pointers into the space being free()d
+ mCodecCtx = NULL;
+
mStarted = false;
return OMX_ErrorNone;
@@ -1508,6 +1512,14 @@
return;
}
+void SoftAVC::onReset() {
+ SoftVideoEncoderOMXComponent::onReset();
+
+ if (releaseEncoder() != OMX_ErrorNone) {
+ ALOGW("releaseEncoder failed");
+ }
+}
+
} // namespace android
android::SoftOMXComponent *createSoftOMXComponent(
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
index 4d30ba0..818e4a1 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
@@ -136,6 +136,8 @@
protected:
virtual ~SoftAVC();
+ virtual void onReset();
+
private:
enum {
kNumBuffers = 2,
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index 836972a..e06a81f 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -93,10 +93,6 @@
}
if (mFlashControl == NULL) {
- if (enabled == false) {
- return OK;
- }
-
res = createFlashlightControl(cameraId);
if (res) {
return res;
@@ -139,10 +135,14 @@
cameraIds[i] = String8(ids[i].c_str());
}
- mHasFlashlightMap.clear();
- mFlashlightMapInitialized = false;
+ mFlashControl.clear();
for (auto &id : cameraIds) {
+ ssize_t index = mHasFlashlightMap.indexOfKey(id);
+ if (0 <= index) {
+ continue;
+ }
+
bool hasFlash = false;
res = createFlashlightControl(id);
if (res) {
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 0031441..415fdf5 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -198,13 +198,17 @@
}
status_t CameraService::enumerateProviders() {
- mCameraProviderManager = new CameraProviderManager();
status_t res;
- res = mCameraProviderManager->initialize(this);
- if (res != OK) {
- ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
- __FUNCTION__, strerror(-res), res);
- return res;
+ Mutex::Autolock l(mServiceLock);
+
+ if (nullptr == mCameraProviderManager.get()) {
+ mCameraProviderManager = new CameraProviderManager();
+ res = mCameraProviderManager->initialize(this);
+ if (res != OK) {
+ ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
+ return res;
+ }
}
mNumberOfCameras = mCameraProviderManager->getCameraCount();
@@ -216,15 +220,25 @@
// TODO: maybe put this into CameraProviderManager::initialize()?
mCameraProviderManager->setUpVendorTags();
- mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
+ if (nullptr == mFlashlight.get()) {
+ mFlashlight = new CameraFlashlight(mCameraProviderManager, this);
+ }
+
res = mFlashlight->findFlashUnits();
if (res != OK) {
ALOGE("Failed to enumerate flash units: %s (%d)", strerror(-res), res);
}
- // TODO: Verify device versions are in support
-
for (auto& cameraId : mCameraProviderManager->getCameraDeviceIds()) {
+ String8 id8 = String8(cameraId.c_str());
+ {
+ Mutex::Autolock lock(mCameraStatesLock);
+ auto iter = mCameraStates.find(id8);
+ if (iter != mCameraStates.end()) {
+ continue;
+ }
+ }
+
hardware::camera::common::V1_0::CameraResourceCost cost;
res = mCameraProviderManager->getResourceCost(cameraId, &cost);
if (res != OK) {
@@ -235,22 +249,19 @@
for (size_t i = 0; i < cost.conflictingDevices.size(); i++) {
conflicting.emplace(String8(cost.conflictingDevices[i].c_str()));
}
- String8 id8 = String8(cameraId.c_str());
Mutex::Autolock lock(mCameraStatesLock);
mCameraStates.emplace(id8,
std::make_shared<CameraState>(id8, cost.resourceCost, conflicting));
if (mFlashlight->hasFlashUnit(id8)) {
- mTorchStatusMap.add(id8,
- TorchModeStatus::AVAILABLE_OFF);
+ mTorchStatusMap.add(id8, TorchModeStatus::AVAILABLE_OFF);
}
}
return OK;
}
-
sp<ICameraServiceProxy> CameraService::getCameraServiceProxy() {
sp<ICameraServiceProxy> proxyBinder = nullptr;
#ifndef __BRILLO__
@@ -276,6 +287,10 @@
VendorTagDescriptor::clearGlobalVendorTagDescriptor();
}
+void CameraService::onNewProviderRegistered() {
+ enumerateProviders();
+}
+
void CameraService::onDeviceStatusChanged(const String8& id,
CameraDeviceStatus newHalStatus) {
ALOGI("%s: Status changed for cameraId=%s, newStatus=%d", __FUNCTION__,
@@ -407,6 +422,7 @@
Status CameraService::getNumberOfCameras(int32_t type, int32_t* numCameras) {
ATRACE_CALL();
+ Mutex::Autolock l(mServiceLock);
switch (type) {
case CAMERA_TYPE_BACKWARD_COMPATIBLE:
*numCameras = mNumberOfNormalCameras;
@@ -426,6 +442,8 @@
Status CameraService::getCameraInfo(int cameraId,
CameraInfo* cameraInfo) {
ATRACE_CALL();
+ Mutex::Autolock l(mServiceLock);
+
if (!mInitialized) {
return STATUS_ERROR(ERROR_DISCONNECTED,
"Camera subsystem is not available");
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 7d81993..87603a3 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -99,6 +99,7 @@
hardware::camera::common::V1_0::CameraDeviceStatus newHalStatus) override;
virtual void onTorchStatusChanged(const String8& cameraId,
hardware::camera::common::V1_0::TorchModeStatus newStatus) override;
+ virtual void onNewProviderRegistered() override;
/////////////////////////////////////////////////////////////////////
// ICameraService
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index f839095..b9d6843 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -225,7 +225,6 @@
status_t CameraProviderManager::setUpVendorTags() {
sp<VendorTagDescriptorCache> tagCache = new VendorTagDescriptorCache();
- VendorTagDescriptorCache::clearGlobalVendorTagCache();
for (auto& provider : mProviders) {
hardware::hidl_vec<VendorTagSection> vts;
Status status;
@@ -325,9 +324,17 @@
const hardware::hidl_string& /*fqName*/,
const hardware::hidl_string& name,
bool /*preexisting*/) {
- std::lock_guard<std::mutex> lock(mInterfaceMutex);
+ {
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
- addProviderLocked(name);
+ addProviderLocked(name);
+ }
+
+ sp<StatusListener> listener = getStatusListener();
+ if (nullptr != listener.get()) {
+ listener->onNewProviderRegistered();
+ }
+
return hardware::Return<void>();
}
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 9cce245..e82282f 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -106,6 +106,7 @@
hardware::camera::common::V1_0::CameraDeviceStatus newStatus) = 0;
virtual void onTorchStatusChanged(const String8 &cameraId,
hardware::camera::common::V1_0::TorchModeStatus newStatus) = 0;
+ virtual void onNewProviderRegistered() = 0;
};
/**
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 4706319..4571db8 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -4080,6 +4080,13 @@
}
for (size_t i = 0; i < halRequest->num_output_buffers; i++) {
+ //Buffers that failed processing could still have
+ //valid acquire fence.
+ int acquireFence = (*outputBuffers)[i].acquire_fence;
+ if (0 <= acquireFence) {
+ close(acquireFence);
+ outputBuffers->editItemAt(i).acquire_fence = -1;
+ }
outputBuffers->editItemAt(i).status = CAMERA3_BUFFER_STATUS_ERROR;
captureRequest->mOutputStreams.editItemAt(i)->returnBuffer((*outputBuffers)[i], 0);
}