Merge "BufferQueue: Increase max slots from 32 to 64"
diff --git a/camera/Android.mk b/camera/Android.mk
index 369d0c5..5774b6f 100644
--- a/camera/Android.mk
+++ b/camera/Android.mk
@@ -22,6 +22,7 @@
Camera.cpp \
CameraMetadata.cpp \
CameraParameters.cpp \
+ CaptureResult.cpp \
ICamera.cpp \
ICameraClient.cpp \
ICameraService.cpp \
diff --git a/camera/CaptureResult.cpp b/camera/CaptureResult.cpp
new file mode 100644
index 0000000..c016e52
--- /dev/null
+++ b/camera/CaptureResult.cpp
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2014 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 "Camera-CaptureResult"
+#include <utils/Log.h>
+
+#include <camera/CaptureResult.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+bool CaptureResultExtras::isValid() {
+ return requestId >= 0;
+}
+
+status_t CaptureResultExtras::readFromParcel(Parcel *parcel) {
+ if (parcel == NULL) {
+ ALOGE("%s: Null parcel", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ parcel->readInt32(&requestId);
+ parcel->readInt32(&burstId);
+ parcel->readInt32(&afTriggerId);
+ parcel->readInt32(&precaptureTriggerId);
+ parcel->readInt64(&frameNumber);
+
+ return OK;
+}
+
+status_t CaptureResultExtras::writeToParcel(Parcel *parcel) const {
+ if (parcel == NULL) {
+ ALOGE("%s: Null parcel", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ parcel->writeInt32(requestId);
+ parcel->writeInt32(burstId);
+ parcel->writeInt32(afTriggerId);
+ parcel->writeInt32(precaptureTriggerId);
+ parcel->writeInt64(frameNumber);
+
+ return OK;
+}
+
+CaptureResult::CaptureResult() :
+ mMetadata(), mResultExtras() {
+}
+
+CaptureResult::CaptureResult(const CaptureResult &otherResult) {
+ mResultExtras = otherResult.mResultExtras;
+ mMetadata = otherResult.mMetadata;
+}
+
+status_t CaptureResult::readFromParcel(Parcel *parcel) {
+
+ ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
+
+ if (parcel == NULL) {
+ ALOGE("%s: parcel is null", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ mMetadata.clear();
+
+ status_t res = OK;
+ res = mMetadata.readFromParcel(parcel);
+ if (res != OK) {
+ ALOGE("%s: Failed to read metadata from parcel.",
+ __FUNCTION__);
+ return res;
+ }
+ ALOGV("%s: Read metadata from parcel", __FUNCTION__);
+
+ res = mResultExtras.readFromParcel(parcel);
+ if (res != OK) {
+ ALOGE("%s: Failed to read result extras from parcel.",
+ __FUNCTION__);
+ return res;
+ }
+ ALOGV("%s: Read result extras from parcel", __FUNCTION__);
+
+ return OK;
+}
+
+status_t CaptureResult::writeToParcel(Parcel *parcel) const {
+
+ ALOGV("%s: parcel = %p", __FUNCTION__, parcel);
+
+ if (parcel == NULL) {
+ ALOGE("%s: parcel is null", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ status_t res;
+
+ res = mMetadata.writeToParcel(parcel);
+ if (res != OK) {
+ ALOGE("%s: Failed to write metadata to parcel", __FUNCTION__);
+ return res;
+ }
+ ALOGV("%s: Wrote metadata to parcel", __FUNCTION__);
+
+ res = mResultExtras.writeToParcel(parcel);
+ if (res != OK) {
+ ALOGE("%s: Failed to write result extras to parcel", __FUNCTION__);
+ return res;
+ }
+ ALOGV("%s: Wrote result extras to parcel", __FUNCTION__);
+
+ return OK;
+}
+
+}
diff --git a/camera/camera2/ICameraDeviceCallbacks.cpp b/camera/camera2/ICameraDeviceCallbacks.cpp
index 613358a..4cc7b5d 100644
--- a/camera/camera2/ICameraDeviceCallbacks.cpp
+++ b/camera/camera2/ICameraDeviceCallbacks.cpp
@@ -28,6 +28,7 @@
#include <camera/camera2/ICameraDeviceCallbacks.h>
#include "camera/CameraMetadata.h"
+#include "camera/CaptureResult.h"
namespace android {
@@ -46,12 +47,14 @@
{
}
- void onDeviceError(CameraErrorCode errorCode)
+ void onDeviceError(CameraErrorCode errorCode, const CaptureResultExtras& resultExtras)
{
ALOGV("onDeviceError");
Parcel data, reply;
data.writeInterfaceToken(ICameraDeviceCallbacks::getInterfaceDescriptor());
data.writeInt32(static_cast<int32_t>(errorCode));
+ data.writeInt32(1); // to mark presence of CaptureResultExtras object
+ resultExtras.writeToParcel(&data);
remote()->transact(CAMERA_ERROR, data, &reply, IBinder::FLAG_ONEWAY);
data.writeNoException();
}
@@ -65,25 +68,28 @@
data.writeNoException();
}
- void onCaptureStarted(int32_t requestId, int64_t timestamp)
+ void onCaptureStarted(const CaptureResultExtras& result, int64_t timestamp)
{
ALOGV("onCaptureStarted");
Parcel data, reply;
data.writeInterfaceToken(ICameraDeviceCallbacks::getInterfaceDescriptor());
- data.writeInt32(requestId);
+ data.writeInt32(1); // to mark presence of CaptureResultExtras object
+ result.writeToParcel(&data);
data.writeInt64(timestamp);
remote()->transact(CAPTURE_STARTED, data, &reply, IBinder::FLAG_ONEWAY);
data.writeNoException();
}
- void onResultReceived(int32_t requestId, const CameraMetadata& result) {
+ void onResultReceived(const CameraMetadata& metadata,
+ const CaptureResultExtras& resultExtras) {
ALOGV("onResultReceived");
Parcel data, reply;
data.writeInterfaceToken(ICameraDeviceCallbacks::getInterfaceDescriptor());
- data.writeInt32(requestId);
data.writeInt32(1); // to mark presence of metadata object
- result.writeToParcel(&data);
+ metadata.writeToParcel(&data);
+ data.writeInt32(1); // to mark presence of CaptureResult object
+ resultExtras.writeToParcel(&data);
remote()->transact(RESULT_RECEIVED, data, &reply, IBinder::FLAG_ONEWAY);
data.writeNoException();
}
@@ -104,7 +110,13 @@
CHECK_INTERFACE(ICameraDeviceCallbacks, data, reply);
CameraErrorCode errorCode =
static_cast<CameraErrorCode>(data.readInt32());
- onDeviceError(errorCode);
+ CaptureResultExtras resultExtras;
+ if (data.readInt32() != 0) {
+ resultExtras.readFromParcel(const_cast<Parcel*>(&data));
+ } else {
+ ALOGE("No CaptureResultExtras object is present!");
+ }
+ onDeviceError(errorCode, resultExtras);
data.readExceptionCode();
return NO_ERROR;
} break;
@@ -118,23 +130,33 @@
case CAPTURE_STARTED: {
ALOGV("onCaptureStarted");
CHECK_INTERFACE(ICameraDeviceCallbacks, data, reply);
- int32_t requestId = data.readInt32();
+ CaptureResultExtras result;
+ if (data.readInt32() != 0) {
+ result.readFromParcel(const_cast<Parcel*>(&data));
+ } else {
+ ALOGE("No CaptureResultExtras object is present in result!");
+ }
int64_t timestamp = data.readInt64();
- onCaptureStarted(requestId, timestamp);
+ onCaptureStarted(result, timestamp);
data.readExceptionCode();
return NO_ERROR;
} break;
case RESULT_RECEIVED: {
ALOGV("onResultReceived");
CHECK_INTERFACE(ICameraDeviceCallbacks, data, reply);
- int32_t requestId = data.readInt32();
- CameraMetadata result;
+ CameraMetadata metadata;
if (data.readInt32() != 0) {
- result.readFromParcel(const_cast<Parcel*>(&data));
+ metadata.readFromParcel(const_cast<Parcel*>(&data));
} else {
ALOGW("No metadata object is present in result");
}
- onResultReceived(requestId, result);
+ CaptureResultExtras resultExtras;
+ if (data.readInt32() != 0) {
+ resultExtras.readFromParcel(const_cast<Parcel*>(&data));
+ } else {
+ ALOGW("No capture result extras object is present in result");
+ }
+ onResultReceived(metadata, resultExtras);
data.readExceptionCode();
return NO_ERROR;
} break;
diff --git a/camera/camera2/ICameraDeviceUser.cpp b/camera/camera2/ICameraDeviceUser.cpp
index 1e5822f..ad65955 100644
--- a/camera/camera2/ICameraDeviceUser.cpp
+++ b/camera/camera2/ICameraDeviceUser.cpp
@@ -35,6 +35,7 @@
enum {
DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
SUBMIT_REQUEST,
+ SUBMIT_REQUEST_LIST,
CANCEL_REQUEST,
DELETE_STREAM,
CREATE_STREAM,
@@ -75,7 +76,8 @@
reply.readExceptionCode();
}
- virtual int submitRequest(sp<CaptureRequest> request, bool streaming)
+ virtual status_t submitRequest(sp<CaptureRequest> request, bool repeating,
+ int64_t *lastFrameNumber)
{
Parcel data, reply;
data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
@@ -89,15 +91,67 @@
}
// arg1 = streaming (bool)
- data.writeInt32(streaming);
+ data.writeInt32(repeating);
remote()->transact(SUBMIT_REQUEST, data, &reply);
reply.readExceptionCode();
- return reply.readInt32();
+ status_t res = reply.readInt32();
+
+ status_t resFrameNumber = BAD_VALUE;
+ if (reply.readInt32() != 0) {
+ if (lastFrameNumber != NULL) {
+ resFrameNumber = reply.readInt64(lastFrameNumber);
+ }
+ }
+
+ if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
+ res = FAILED_TRANSACTION;
+ }
+ return res;
}
- virtual status_t cancelRequest(int requestId)
+ virtual status_t submitRequestList(List<sp<CaptureRequest> > requestList, bool repeating,
+ int64_t *lastFrameNumber)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
+
+ data.writeInt32(requestList.size());
+
+ for (List<sp<CaptureRequest> >::iterator it = requestList.begin();
+ it != requestList.end(); ++it) {
+ sp<CaptureRequest> request = *it;
+ if (request != 0) {
+ data.writeInt32(1);
+ if (request->writeToParcel(&data) != OK) {
+ return BAD_VALUE;
+ }
+ } else {
+ data.writeInt32(0);
+ }
+ }
+
+ data.writeInt32(repeating);
+
+ remote()->transact(SUBMIT_REQUEST_LIST, data, &reply);
+
+ reply.readExceptionCode();
+ status_t res = reply.readInt32();
+
+ status_t resFrameNumber = BAD_VALUE;
+ if (reply.readInt32() != 0) {
+ if (lastFrameNumber != NULL) {
+ resFrameNumber = reply.readInt64(lastFrameNumber);
+ }
+ }
+ if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
+ res = FAILED_TRANSACTION;
+ }
+ return res;
+ }
+
+ virtual status_t cancelRequest(int requestId, int64_t *lastFrameNumber)
{
Parcel data, reply;
data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
@@ -106,7 +160,18 @@
remote()->transact(CANCEL_REQUEST, data, &reply);
reply.readExceptionCode();
- return reply.readInt32();
+ status_t res = reply.readInt32();
+
+ status_t resFrameNumber = BAD_VALUE;
+ if (reply.readInt32() != 0) {
+ if (lastFrameNumber != NULL) {
+ res = reply.readInt64(lastFrameNumber);
+ }
+ }
+ if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
+ res = FAILED_TRANSACTION;
+ }
+ return res;
}
virtual status_t deleteStream(int streamId)
@@ -197,14 +262,25 @@
return reply.readInt32();
}
- virtual status_t flush()
+ virtual status_t flush(int64_t *lastFrameNumber)
{
ALOGV("flush");
Parcel data, reply;
data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
remote()->transact(FLUSH, data, &reply);
reply.readExceptionCode();
- return reply.readInt32();
+ status_t res = reply.readInt32();
+
+ status_t resFrameNumber = BAD_VALUE;
+ if (reply.readInt32() != 0) {
+ if (lastFrameNumber != NULL) {
+ res = reply.readInt64(lastFrameNumber);
+ }
+ }
+ if ((res != NO_ERROR) || (resFrameNumber != NO_ERROR)) {
+ res = FAILED_TRANSACTION;
+ }
+ return res;
}
private:
@@ -239,11 +315,43 @@
}
// arg1 = streaming (bool)
- bool streaming = data.readInt32();
+ bool repeating = data.readInt32();
// return code: requestId (int32)
reply->writeNoException();
- reply->writeInt32(submitRequest(request, streaming));
+ int64_t lastFrameNumber = -1;
+ reply->writeInt32(submitRequest(request, repeating, &lastFrameNumber));
+ reply->writeInt32(1);
+ reply->writeInt64(lastFrameNumber);
+
+ return NO_ERROR;
+ } break;
+ case SUBMIT_REQUEST_LIST: {
+ CHECK_INTERFACE(ICameraDeviceUser, data, reply);
+
+ List<sp<CaptureRequest> > requestList;
+ int requestListSize = data.readInt32();
+ for (int i = 0; i < requestListSize; i++) {
+ if (data.readInt32() != 0) {
+ sp<CaptureRequest> request = new CaptureRequest();
+ if (request->readFromParcel(const_cast<Parcel*>(&data)) != OK) {
+ return BAD_VALUE;
+ }
+ requestList.push_back(request);
+ } else {
+ sp<CaptureRequest> request = 0;
+ requestList.push_back(request);
+ ALOGE("A request is missing. Sending in null request.");
+ }
+ }
+
+ bool repeating = data.readInt32();
+
+ reply->writeNoException();
+ int64_t lastFrameNumber = -1;
+ reply->writeInt32(submitRequestList(requestList, repeating, &lastFrameNumber));
+ reply->writeInt32(1);
+ reply->writeInt64(lastFrameNumber);
return NO_ERROR;
} break;
@@ -251,7 +359,10 @@
CHECK_INTERFACE(ICameraDeviceUser, data, reply);
int requestId = data.readInt32();
reply->writeNoException();
- reply->writeInt32(cancelRequest(requestId));
+ int64_t lastFrameNumber = -1;
+ reply->writeInt32(cancelRequest(requestId, &lastFrameNumber));
+ reply->writeInt32(1);
+ reply->writeInt64(lastFrameNumber);
return NO_ERROR;
} break;
case DELETE_STREAM: {
@@ -339,7 +450,10 @@
case FLUSH: {
CHECK_INTERFACE(ICameraDeviceUser, data, reply);
reply->writeNoException();
- reply->writeInt32(flush());
+ int64_t lastFrameNumber = -1;
+ reply->writeInt32(flush(&lastFrameNumber));
+ reply->writeInt32(1);
+ reply->writeInt64(lastFrameNumber);
return NO_ERROR;
}
default:
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 6b41fd4..b70afe6 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -14,16 +14,16 @@
* limitations under the License.
*/
+#include <inttypes.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
//#define LOG_NDEBUG 0
#define LOG_TAG "stagefright"
#include <media/stagefright/foundation/ADebug.h>
-#include <sys/time.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-
#include "jpeg.h"
#include "SineSource.h"
@@ -51,8 +51,6 @@
#include <private/media/VideoFrame.h>
-#include <fcntl.h>
-
#include <gui/GLConsumer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
@@ -648,7 +646,7 @@
const CodecProfileLevel &profileLevel =
results[i].mProfileLevels[j];
- printf("%s%ld/%ld", j > 0 ? ", " : "",
+ printf("%s%" PRIu32 "/%" PRIu32, j > 0 ? ", " : "",
profileLevel.mProfile, profileLevel.mLevel);
}
diff --git a/drm/common/DrmSupportInfo.cpp b/drm/common/DrmSupportInfo.cpp
index 5400bdd..584c6a6 100644
--- a/drm/common/DrmSupportInfo.cpp
+++ b/drm/common/DrmSupportInfo.cpp
@@ -47,7 +47,7 @@
return false;
}
- for (unsigned int i = 0; i < mMimeTypeVector.size(); i++) {
+ for (size_t i = 0; i < mMimeTypeVector.size(); i++) {
const String8 item = mMimeTypeVector.itemAt(i);
if (!strcasecmp(item.string(), mimeType.string())) {
@@ -58,7 +58,7 @@
}
bool DrmSupportInfo::isSupportedFileSuffix(const String8& fileType) const {
- for (unsigned int i = 0; i < mFileSuffixVector.size(); i++) {
+ for (size_t i = 0; i < mFileSuffixVector.size(); i++) {
const String8 item = mFileSuffixVector.itemAt(i);
if (!strcasecmp(item.string(), fileType.string())) {
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index dccd23d..d8aeb0c 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -101,7 +101,7 @@
status_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
mPlugInManager.loadPlugIns(plugInDirPath);
Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
- for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
+ for (size_t i = 0; i < plugInPathList.size(); ++i) {
String8 plugInPath = plugInPathList[i];
DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
if (NULL != info) {
@@ -138,7 +138,7 @@
Mutex::Autolock _l(mLock);
if (!mSupportInfoToPlugInIdMap.isEmpty()) {
Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
- for (unsigned int index = 0; index < plugInIdList.size(); index++) {
+ for (size_t index = 0; index < plugInIdList.size(); index++) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
rDrmEngine.initialize(uniqueId);
rDrmEngine.setOnInfoListener(uniqueId, this);
@@ -149,7 +149,7 @@
void DrmManager::removeClient(int uniqueId) {
Mutex::Autolock _l(mLock);
Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
- for (unsigned int index = 0; index < plugInIdList.size(); index++) {
+ for (size_t index = 0; index < plugInIdList.size(); index++) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
rDrmEngine.terminate(uniqueId);
}
@@ -208,7 +208,7 @@
bool result = false;
Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
- for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
+ for (size_t i = 0; i < plugInPathList.size(); ++i) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]);
result = rDrmEngine.canHandle(uniqueId, path);
@@ -318,7 +318,7 @@
status_t DrmManager::removeAllRights(int uniqueId) {
Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
status_t result = DRM_ERROR_UNKNOWN;
- for (unsigned int index = 0; index < plugInIdList.size(); index++) {
+ for (size_t index = 0; index < plugInIdList.size(); index++) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
result = rDrmEngine.removeAllRights(uniqueId);
if (DRM_NO_ERROR != result) {
@@ -412,7 +412,7 @@
if (NULL != handle) {
handle->decryptId = mDecryptSessionId + 1;
- for (unsigned int index = 0; index < plugInIdList.size(); index++) {
+ for (size_t index = 0; index < plugInIdList.size(); index++) {
String8 plugInId = plugInIdList.itemAt(index);
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length, mime);
@@ -440,7 +440,7 @@
if (NULL != handle) {
handle->decryptId = mDecryptSessionId + 1;
- for (unsigned int index = 0; index < plugInIdList.size(); index++) {
+ for (size_t index = 0; index < plugInIdList.size(); index++) {
String8 plugInId = plugInIdList.itemAt(index);
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
result = rDrmEngine.openDecryptSession(uniqueId, handle, uri, mime);
@@ -565,7 +565,7 @@
String8 plugInId("");
if (EMPTY_STRING != mimeType) {
- for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
+ for (size_t index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
if (drmSupportInfo.isSupportedMimeType(mimeType)) {
@@ -581,7 +581,7 @@
String8 plugInId("");
const String8 fileSuffix = path.getPathExtension();
- for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
+ for (size_t index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) {
@@ -599,7 +599,7 @@
void DrmManager::onInfo(const DrmInfoEvent& event) {
Mutex::Autolock _l(mListenerLock);
- for (unsigned int index = 0; index < mServiceListeners.size(); index++) {
+ for (size_t index = 0; index < mServiceListeners.size(); index++) {
int uniqueId = mServiceListeners.keyAt(index);
if (uniqueId == event.getUniqueId()) {
diff --git a/drm/libdrmframework/include/PlugInManager.h b/drm/libdrmframework/include/PlugInManager.h
index 7bb143f..c1d019a 100644
--- a/drm/libdrmframework/include/PlugInManager.h
+++ b/drm/libdrmframework/include/PlugInManager.h
@@ -80,7 +80,7 @@
Vector<String8> plugInFileList = getPlugInPathList(rsPlugInDirPath);
if (!plugInFileList.isEmpty()) {
- for (unsigned int i = 0; i < plugInFileList.size(); ++i) {
+ for (size_t i = 0; i < plugInFileList.size(); ++i) {
loadPlugIn(plugInFileList[i]);
}
}
@@ -91,7 +91,7 @@
*
*/
void unloadPlugIns() {
- for (unsigned int i = 0; i < m_plugInIdList.size(); ++i) {
+ for (size_t i = 0; i < m_plugInIdList.size(); ++i) {
unloadPlugIn(m_plugInIdList[i]);
}
m_plugInIdList.clear();
diff --git a/include/camera/CaptureResult.h b/include/camera/CaptureResult.h
new file mode 100644
index 0000000..6e47a16
--- /dev/null
+++ b/include/camera/CaptureResult.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 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_HARDWARE_CAPTURERESULT_H
+#define ANDROID_HARDWARE_CAPTURERESULT_H
+
+#include <utils/RefBase.h>
+#include <camera/CameraMetadata.h>
+
+namespace android {
+
+/**
+ * CaptureResultExtras is a structure to encapsulate various indices for a capture result.
+ * These indices are framework-internal and not sent to the HAL.
+ */
+struct CaptureResultExtras {
+ /**
+ * An integer to index the request sequence that this result belongs to.
+ */
+ int32_t requestId;
+
+ /**
+ * An integer to index this result inside a request sequence, starting from 0.
+ */
+ int32_t burstId;
+
+ /**
+ * TODO: Add documentation for this field.
+ */
+ int32_t afTriggerId;
+
+ /**
+ * TODO: Add documentation for this field.
+ */
+ int32_t precaptureTriggerId;
+
+ /**
+ * A 64bit integer to index the frame number associated with this result.
+ */
+ int64_t frameNumber;
+
+ /**
+ * Constructor initializes object as invalid by setting requestId to be -1.
+ */
+ CaptureResultExtras()
+ : requestId(-1),
+ burstId(0),
+ afTriggerId(0),
+ precaptureTriggerId(0),
+ frameNumber(0) {
+ }
+
+ /**
+ * This function returns true if it's a valid CaptureResultExtras object.
+ * Otherwise, returns false. It is valid only when requestId is non-negative.
+ */
+ bool isValid();
+
+ status_t readFromParcel(Parcel* parcel);
+ status_t writeToParcel(Parcel* parcel) const;
+};
+
+struct CaptureResult : public virtual LightRefBase<CaptureResult> {
+ CameraMetadata mMetadata;
+ CaptureResultExtras mResultExtras;
+
+ CaptureResult();
+
+ CaptureResult(const CaptureResult& otherResult);
+
+ status_t readFromParcel(Parcel* parcel);
+ status_t writeToParcel(Parcel* parcel) const;
+};
+
+}
+
+#endif /* ANDROID_HARDWARE_CAPTURERESULT_H */
diff --git a/include/camera/camera2/ICameraDeviceCallbacks.h b/include/camera/camera2/ICameraDeviceCallbacks.h
index 8dac4f2..f059b3d 100644
--- a/include/camera/camera2/ICameraDeviceCallbacks.h
+++ b/include/camera/camera2/ICameraDeviceCallbacks.h
@@ -24,9 +24,12 @@
#include <utils/Timers.h>
#include <system/camera.h>
+#include <camera/CaptureResult.h>
+
namespace android {
class CameraMetadata;
+
class ICameraDeviceCallbacks : public IInterface
{
/**
@@ -45,18 +48,19 @@
};
// One way
- virtual void onDeviceError(CameraErrorCode errorCode) = 0;
+ virtual void onDeviceError(CameraErrorCode errorCode,
+ const CaptureResultExtras& resultExtras) = 0;
// One way
virtual void onDeviceIdle() = 0;
// One way
- virtual void onCaptureStarted(int32_t requestId,
+ virtual void onCaptureStarted(const CaptureResultExtras& resultExtras,
int64_t timestamp) = 0;
// One way
- virtual void onResultReceived(int32_t requestId,
- const CameraMetadata& result) = 0;
+ virtual void onResultReceived(const CameraMetadata& metadata,
+ const CaptureResultExtras& resultExtras) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/camera/camera2/ICameraDeviceUser.h b/include/camera/camera2/ICameraDeviceUser.h
index f71f302..913696f 100644
--- a/include/camera/camera2/ICameraDeviceUser.h
+++ b/include/camera/camera2/ICameraDeviceUser.h
@@ -19,6 +19,7 @@
#include <binder/IInterface.h>
#include <binder/Parcel.h>
+#include <utils/List.h>
struct camera_metadata;
@@ -30,6 +31,10 @@
class CaptureRequest;
class CameraMetadata;
+enum {
+ NO_IN_FLIGHT_REPEATING_FRAMES = -1,
+};
+
class ICameraDeviceUser : public IInterface
{
/**
@@ -44,9 +49,34 @@
* Request Handling
**/
+ /**
+ * For streaming requests, output lastFrameNumber is the last frame number
+ * of the previous repeating request.
+ * For non-streaming requests, output lastFrameNumber is the expected last
+ * frame number of the current request.
+ */
virtual int submitRequest(sp<CaptureRequest> request,
- bool streaming = false) = 0;
- virtual status_t cancelRequest(int requestId) = 0;
+ bool streaming = false,
+ /*out*/
+ int64_t* lastFrameNumber = NULL) = 0;
+
+ /**
+ * For streaming requests, output lastFrameNumber is the last frame number
+ * of the previous repeating request.
+ * For non-streaming requests, output lastFrameNumber is the expected last
+ * frame number of the current request.
+ */
+ virtual int submitRequestList(List<sp<CaptureRequest> > requestList,
+ bool streaming = false,
+ /*out*/
+ int64_t* lastFrameNumber = NULL) = 0;
+
+ /**
+ * Output lastFrameNumber is the last frame number of the previous repeating request.
+ */
+ virtual status_t cancelRequest(int requestId,
+ /*out*/
+ int64_t* lastFrameNumber = NULL) = 0;
virtual status_t deleteStream(int streamId) = 0;
virtual status_t createStream(
@@ -64,8 +94,12 @@
// Wait until all the submitted requests have finished processing
virtual status_t waitUntilIdle() = 0;
- // Flush all pending and in-progress work as quickly as possible.
- virtual status_t flush() = 0;
+ /**
+ * Flush all pending and in-progress work as quickly as possible.
+ * Output lastFrameNumber is the last frame number of the previous repeating request.
+ */
+ virtual status_t flush(/*out*/
+ int64_t* lastFrameNumber = NULL) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/media/stagefright/FileSource.h b/include/media/stagefright/FileSource.h
index 9838ed2..a981d1c 100644
--- a/include/media/stagefright/FileSource.h
+++ b/include/media/stagefright/FileSource.h
@@ -56,7 +56,7 @@
sp<DecryptHandle> mDecryptHandle;
DrmManagerClient *mDrmManagerClient;
int64_t mDrmBufOffset;
- int64_t mDrmBufSize;
+ size_t mDrmBufSize;
unsigned char *mDrmBuf;
ssize_t readAtDRM(off64_t offset, void *data, size_t size);
diff --git a/libvideoeditor/lvpp/DummyVideoSource.cpp b/libvideoeditor/lvpp/DummyVideoSource.cpp
index b06f937..6dbcf2a 100755
--- a/libvideoeditor/lvpp/DummyVideoSource.cpp
+++ b/libvideoeditor/lvpp/DummyVideoSource.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "DummyVideoSource"
+#include <inttypes.h>
#include <stdlib.h>
#include <utils/Log.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -146,7 +147,7 @@
if (mIsFirstImageFrame) {
M4OSA_clockGetTime(&mImagePlayStartTime, kTimeScale);
mFrameTimeUs = (mImageSeekTime + 1);
- ALOGV("read: jpg 1st frame timeUs = %lld, begin cut time = %ld",
+ ALOGV("read: jpg 1st frame timeUs = %lld, begin cut time = %" PRIu32,
mFrameTimeUs, mImageSeekTime);
mIsFirstImageFrame = false;
diff --git a/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp b/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp
index e60030e..e1a81d8 100755
--- a/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp
+++ b/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <inttypes.h>
+
#define LOG_NDEBUG 1
#define LOG_TAG "VideoEditorAudioPlayer"
#include <utils/Log.h>
@@ -372,7 +374,7 @@
// Get the duration in time of the audio BT
if ( result == M4NO_ERROR ) {
- ALOGV("VEAP: channels = %d freq = %d",
+ ALOGV("VEAP: channels = %" PRIu32 " freq = %" PRIu32,
mAudioMixSettings->uiNbChannels, mAudioMixSettings->uiSamplingFrequency);
// No trim
@@ -440,7 +442,7 @@
// do nothing
}
- ALOGV("VideoEditorAudioPlayer::startTime %d", startTime);
+ ALOGV("VideoEditorAudioPlayer::startTime %" PRIu32, startTime);
seekTimeStamp = 0;
if (startTime) {
if (startTime >= mBGAudioPCMFileDuration) {
diff --git a/libvideoeditor/lvpp/VideoEditorBGAudioProcessing.cpp b/libvideoeditor/lvpp/VideoEditorBGAudioProcessing.cpp
index e24fcf4..0c12aac 100755
--- a/libvideoeditor/lvpp/VideoEditorBGAudioProcessing.cpp
+++ b/libvideoeditor/lvpp/VideoEditorBGAudioProcessing.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <inttypes.h>
+
//#define LOG_NDEBUG 0
#define LOG_TAG "VideoEditorBGAudioProcessing"
#include <utils/Log.h>
@@ -50,8 +52,8 @@
void *backgroundTrackBuffer,
void *outBuffer) {
- ALOGV("mixAndDuck: track buffers (primary: 0x%x and background: 0x%x) "
- "and out buffer 0x%x",
+ ALOGV("mixAndDuck: track buffers (primary: %p and background: %p) "
+ "and out buffer %p",
primaryTrackBuffer, backgroundTrackBuffer, outBuffer);
M4AM_Buffer16* pPrimaryTrack = (M4AM_Buffer16*)primaryTrackBuffer;
@@ -217,7 +219,7 @@
mDoDucking = 0;
mDuckingFactor = 1.0;
- ALOGV("ducking enable 0x%x lowVolume %f threshold %d "
+ ALOGV("ducking enable 0x%x lowVolume %f threshold %" PRIu32 " "
"fPTVolLevel %f BTVolLevel %f",
mDucking_enable, mDucking_lowVolume, mDucking_threshold,
mPTVolLevel, mPTVolLevel);
diff --git a/libvideoeditor/osal/inc/M4OSA_Types.h b/libvideoeditor/osal/inc/M4OSA_Types.h
index 92a68d8..ee258a0 100755
--- a/libvideoeditor/osal/inc/M4OSA_Types.h
+++ b/libvideoeditor/osal/inc/M4OSA_Types.h
@@ -36,13 +36,13 @@
#endif
-typedef signed char M4OSA_Bool;
-typedef unsigned char M4OSA_UInt8;
-typedef signed char M4OSA_Int8;
-typedef unsigned short M4OSA_UInt16;
-typedef signed short M4OSA_Int16;
-typedef unsigned long M4OSA_UInt32;
-typedef signed long M4OSA_Int32;
+typedef int8_t M4OSA_Bool;
+typedef uint8_t M4OSA_UInt8;
+typedef int8_t M4OSA_Int8;
+typedef uint16_t M4OSA_UInt16;
+typedef int16_t M4OSA_Int16;
+typedef uint32_t M4OSA_UInt32;
+typedef int32_t M4OSA_Int32;
typedef signed char M4OSA_Char;
typedef unsigned char M4OSA_UChar;
diff --git a/libvideoeditor/osal/src/M4OSA_Thread.c b/libvideoeditor/osal/src/M4OSA_Thread.c
index db54245..3e82fb3 100755
--- a/libvideoeditor/osal/src/M4OSA_Thread.c
+++ b/libvideoeditor/osal/src/M4OSA_Thread.c
@@ -524,7 +524,7 @@
M4OSA_TRACE2_2("M4OSA_SetThreadSyncPriority\t\tM4OSA_Context 0x%x\t"
"M4OSA_DataOption 0x%x", context, optionValue);
- if((M4OSA_UInt32)optionValue>M4OSA_kThreadLowestPriority)
+ if((M4OSA_UInt32)(uintptr_t)optionValue>M4OSA_kThreadLowestPriority)
{
return M4ERR_PARAMETER;
}
@@ -590,7 +590,7 @@
M4OSA_TRACE2_2("M4OSA_SetThreadSyncStackSize\t\tM4OSA_Context 0x%x\t"
"M4OSA_DataOption 0x%x", context, optionValue);
- threadContext->stackSize = (M4OSA_UInt32)optionValue;
+ threadContext->stackSize = (M4OSA_UInt32)(uintptr_t)optionValue;
return M4NO_ERROR;
}
diff --git a/libvideoeditor/osal/src/M4PSW_DebugTrace.c b/libvideoeditor/osal/src/M4PSW_DebugTrace.c
index 0fcba94..850ed91 100755
--- a/libvideoeditor/osal/src/M4PSW_DebugTrace.c
+++ b/libvideoeditor/osal/src/M4PSW_DebugTrace.c
@@ -25,6 +25,7 @@
*/
+#include <inttypes.h>
#include <stdio.h> /*for printf */
#include "M4OSA_Types.h"
@@ -65,9 +66,9 @@
}
#ifdef NO_FILE
- printf("Error: %li, on %s: %s\n",err,cond,msg);
+ printf("Error: %" PRIu32 ", on %s: %s\n",err,cond,msg);
#else /* NO_FILE */
- printf("Error: %li, on %s: %s Line %lu in: %s\n",err,cond,msg,line,file);
+ printf("Error: %" PRIu32 ", on %s: %s Line %" PRIu32 " in: %s\n",err,cond,msg,line,file);
#endif /* NO_FILE */
}
diff --git a/libvideoeditor/vss/common/inc/marker.h b/libvideoeditor/vss/common/inc/marker.h
deleted file mode 100755
index 83cade0..0000000
--- a/libvideoeditor/vss/common/inc/marker.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2011 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 MARKER_H
-#define MARKER_H
-
-#define ADD_CODE_MARKER_FUN(m_condition) \
- if ( !(m_condition) ) \
- { \
- __asm__ volatile ( \
- ".word 0x21614062\n\t" /* '!a@b' */ \
- ".word 0x47712543\n\t" /* 'Gq%C' */ \
- ".word 0x5F5F5F43\n\t" /* '___C' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x245F5F5F" /* '$___' */ \
- ); \
- }
-
-#define ADD_TEXT_MARKER_FUN(m_condition) \
- if ( !(m_condition) ) \
- { \
- __asm__ volatile ( \
- ".word 0x21614062\n\t" /* '!a@b' */ \
- ".word 0x47712543\n\t" /* 'Gq%C' */ \
- ".word 0x5F5F5F54\n\t" /* '___T' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x245F5F5F" /* '$___' */ \
- ); \
- }
-
-#endif
diff --git a/libvideoeditor/vss/src/M4PCMR_CoreReader.c b/libvideoeditor/vss/src/M4PCMR_CoreReader.c
index 3343254..19f07dd 100755
--- a/libvideoeditor/vss/src/M4PCMR_CoreReader.c
+++ b/libvideoeditor/vss/src/M4PCMR_CoreReader.c
@@ -690,7 +690,7 @@
switch(optionID)
{
case M4PCMR_kPCMblockSize:
- c->m_blockSize = (M4OSA_UInt32)Value;
+ c->m_blockSize = (M4OSA_UInt32)(uintptr_t)Value;
break;
default:
diff --git a/libvideoeditor/vss/src/M4READER_Amr.c b/libvideoeditor/vss/src/M4READER_Amr.c
index 0859157..71f0e28 100755
--- a/libvideoeditor/vss/src/M4READER_Amr.c
+++ b/libvideoeditor/vss/src/M4READER_Amr.c
@@ -303,7 +303,7 @@
pStreamHandler->m_decoderSpecificInfoSize = streamDesc.decoderSpecificInfoSize;
pStreamHandler->m_streamId = streamDesc.streamID;
pStreamHandler->m_duration = streamDesc.duration;
- pStreamHandler->m_pUserData = (void*)streamDesc.timeScale; /*trick to change*/
+ pStreamHandler->m_pUserData = (void*)(intptr_t)streamDesc.timeScale; /*trick to change*/
if (streamDesc.duration > pC->m_maxDuration)
{
@@ -704,7 +704,7 @@
if (err == M4NO_ERROR)
{
- timeScale = (M4OSA_Float)(M4OSA_Int32)(pStreamHandler->m_pUserData)/1000;
+ timeScale = (M4OSA_Float)(M4OSA_Int32)(intptr_t)(pStreamHandler->m_pUserData)/1000;
pAccessUnit->m_dataAddress = (M4OSA_MemAddr8)pAu->dataAddress;
pAccessUnit->m_size = pAu->size;
pAccessUnit->m_CTS = (M4_MediaTime)pAu->CTS/*/timeScale*/;
diff --git a/libvideoeditor/vss/src/M4READER_Pcm.c b/libvideoeditor/vss/src/M4READER_Pcm.c
index 833930b..392367f 100755
--- a/libvideoeditor/vss/src/M4READER_Pcm.c
+++ b/libvideoeditor/vss/src/M4READER_Pcm.c
@@ -386,7 +386,7 @@
pC->m_pAudioStream->m_decoderSpecificInfoSize = streamDesc.decoderSpecificInfoSize;
pC->m_pAudioStream->m_streamId = streamDesc.streamID;
pC->m_pAudioStream->m_pUserData =
- (void*)streamDesc.timeScale; /*trick to change*/
+ (void*)(intptr_t)streamDesc.timeScale; /*trick to change*/
pC->m_pAudioStream->m_averageBitRate = streamDesc.averageBitrate;
pC->m_pAudioStream->m_maxAUSize =
pAudioStreamHandler->m_byteFrameLength*pAudioStreamHandler->m_byteSampleSize\
diff --git a/libvideoeditor/vss/src/M4VD_EXTERNAL_BitstreamParser.c b/libvideoeditor/vss/src/M4VD_EXTERNAL_BitstreamParser.c
index cc67e72..fb83952 100755
--- a/libvideoeditor/vss/src/M4VD_EXTERNAL_BitstreamParser.c
+++ b/libvideoeditor/vss/src/M4VD_EXTERNAL_BitstreamParser.c
@@ -13,6 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <inttypes.h>
+
#include "utils/Log.h"
#include "M4OSA_Types.h"
#include "M4OSA_Debug.h"
@@ -505,7 +507,7 @@
}
constraintSet3 = (pDSI[index+2] & 0x10);
- ALOGV("getAVCProfileAndLevel profile_byte %d, level_byte: %d constrain3flag",
+ ALOGV("getAVCProfileAndLevel profile_byte %d, level_byte: %d constrain3flag: %d",
pDSI[index+1], pDSI[index+3], constraintSet3);
switch (pDSI[index+1]) {
@@ -586,7 +588,8 @@
default:
*pLevel = M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL;
}
- ALOGV("getAVCProfileAndLevel profile %ld level %ld", *pProfile, *pLevel);
+ ALOGV("getAVCProfileAndLevel profile %" PRId32 " level %" PRId32,
+ *pProfile, *pLevel);
return M4NO_ERROR;
}
@@ -606,7 +609,7 @@
*pLevel = M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL;
return M4ERR_PARAMETER;
}
- ALOGV("getH263ProfileAndLevel profile_byte %d, level_byte",
+ ALOGV("getH263ProfileAndLevel profile_byte %d, level_byte %d",
pDSI[6], pDSI[5]);
/* get the H263 level */
switch (pDSI[5]) {
@@ -670,7 +673,8 @@
default:
*pProfile = M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE;
}
- ALOGV("getH263ProfileAndLevel profile %ld level %ld", *pProfile, *pLevel);
+ ALOGV("getH263ProfileAndLevel profile %" PRId32 " level %" PRId32,
+ *pProfile, *pLevel);
return M4NO_ERROR;
}
@@ -693,6 +697,7 @@
break;
}
}
- ALOGV("getMPEG4ProfileAndLevel profile %ld level %ld", *pProfile, *pLevel);
+ ALOGV("getMPEG4ProfileAndLevel profile %" PRId32 " level %" PRId32,
+ *pProfile, *pLevel);
return M4NO_ERROR;
}
diff --git a/libvideoeditor/vss/src/M4xVSS_internal.c b/libvideoeditor/vss/src/M4xVSS_internal.c
index 64a6f40..84959ec 100755
--- a/libvideoeditor/vss/src/M4xVSS_internal.c
+++ b/libvideoeditor/vss/src/M4xVSS_internal.c
@@ -4156,12 +4156,12 @@
M4VIFI_ImagePlane boxPlane[3];
- if(M4xVSS_kVideoEffectType_ZoomOut == (M4OSA_UInt32)pFunctionContext)
+ if((M4OSA_Void *)M4xVSS_kVideoEffectType_ZoomOut == pFunctionContext)
{
//ratio = 16 - (15 * pProgress->uiProgress)/1000;
ratio = 16 - pProgress->uiProgress / 66 ;
}
- else if(M4xVSS_kVideoEffectType_ZoomIn == (M4OSA_UInt32)pFunctionContext)
+ else if((M4OSA_Void *)M4xVSS_kVideoEffectType_ZoomIn == pFunctionContext)
{
//ratio = 1 + (15 * pProgress->uiProgress)/1000;
ratio = 1 + pProgress->uiProgress / 66 ;
diff --git a/libvideoeditor/vss/stagefrightshells/src/VideoEditorBuffer.c b/libvideoeditor/vss/stagefrightshells/src/VideoEditorBuffer.c
index f4cfa7c..5a7b28e 100755
--- a/libvideoeditor/vss/stagefrightshells/src/VideoEditorBuffer.c
+++ b/libvideoeditor/vss/stagefrightshells/src/VideoEditorBuffer.c
@@ -22,6 +22,8 @@
#undef M4OSA_TRACE_LEVEL
#define M4OSA_TRACE_LEVEL 1
+#include <inttypes.h>
+
#include "VideoEditorBuffer.h"
#include "utils/Log.h"
@@ -55,7 +57,7 @@
VIDEOEDITOR_BUFFER_Pool* pool;
M4OSA_UInt32 index;
- ALOGV("VIDEOEDITOR_BUFFER_allocatePool : ppool = 0x%x nbBuffers = %d ",
+ ALOGV("VIDEOEDITOR_BUFFER_allocatePool : ppool = %p nbBuffers = %" PRIu32,
ppool, nbBuffers);
pool = M4OSA_NULL;
@@ -131,7 +133,7 @@
M4OSA_ERR err;
M4OSA_UInt32 j = 0;
- ALOGV("VIDEOEDITOR_BUFFER_freePool : ppool = 0x%x", ppool);
+ ALOGV("VIDEOEDITOR_BUFFER_freePool : ppool = %p", ppool);
err = M4NO_ERROR;
@@ -200,7 +202,7 @@
/* case where a buffer has been found */
*pNXPBuffer = &(ppool->pNXPBuffer[ibuf]);
- ALOGV("VIDEOEDITOR_BUFFER_getBuffer: idx = %d", ibuf);
+ ALOGV("VIDEOEDITOR_BUFFER_getBuffer: idx = %" PRIu32, ibuf);
return(err);
}
diff --git a/libvideoeditor/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp b/libvideoeditor/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp
index 4787680..ca7db68 100755
--- a/libvideoeditor/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp
+++ b/libvideoeditor/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp
@@ -857,7 +857,7 @@
ALOGV("VideoEditorVideoEncoder_processOutputBuffer : buffer is empty");
goto cleanUp;
}
- VIDEOEDITOR_CHECK(0 == ((M4OSA_UInt32)buffer->data())%4, M4ERR_PARAMETER);
+ VIDEOEDITOR_CHECK(0 == (((intptr_t)buffer->data())%4), M4ERR_PARAMETER);
VIDEOEDITOR_CHECK(buffer->meta_data().get(), M4ERR_PARAMETER);
if ( buffer->meta_data()->findInt32(kKeyIsCodecConfig, &i32Tmp) && i32Tmp ){
{ // Display the DSI
diff --git a/media/common_time/utils.cpp b/media/common_time/utils.cpp
index 6539171..91cf2fd 100644
--- a/media/common_time/utils.cpp
+++ b/media/common_time/utils.cpp
@@ -59,7 +59,7 @@
}
void deserializeSockaddr(const Parcel* p, struct sockaddr_storage* addr) {
- memset(addr, 0, sizeof(addr));
+ memset(addr, 0, sizeof(*addr));
addr->ss_family = p->readInt32();
switch(addr->ss_family) {
diff --git a/media/libeffects/downmix/EffectDownmix.c b/media/libeffects/downmix/EffectDownmix.c
index a39d837..1663d47 100644
--- a/media/libeffects/downmix/EffectDownmix.c
+++ b/media/libeffects/downmix/EffectDownmix.c
@@ -16,7 +16,8 @@
#define LOG_TAG "EffectDownmix"
//#define LOG_NDEBUG 0
-#include <cutils/log.h>
+#include <log/log.h>
+#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
@@ -99,7 +100,7 @@
// strictly for testing, logs the indices of the channels for a given mask,
// uses the same code as Downmix_foldGeneric()
void Downmix_testIndexComputation(uint32_t mask) {
- ALOGI("Testing index computation for 0x%x:", mask);
+ ALOGI("Testing index computation for 0x%" PRIx32 ":", mask);
// check against unsupported channels
if (mask & kUnsupported) {
ALOGE("Unsupported channels (top or front left/right of center)");
@@ -220,7 +221,7 @@
*pHandle = (effect_handle_t) module;
- ALOGV("DownmixLib_Create() %p , size %d", module, sizeof(downmix_module_t));
+ ALOGV("DownmixLib_Create() %p , size %zu", module, sizeof(downmix_module_t));
return 0;
}
@@ -254,7 +255,7 @@
ALOGV("DownmixLib_GetDescriptor() i=%d", i);
if (memcmp(uuid, &gDescriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) {
memcpy(pDescriptor, gDescriptors[i], sizeof(effect_descriptor_t));
- ALOGV("EffectGetDescriptor - UUID matched downmix type %d, UUID = %x",
+ ALOGV("EffectGetDescriptor - UUID matched downmix type %d, UUID = %" PRIx32,
i, gDescriptors[i]->uuid.timeLow);
return 0;
}
@@ -328,7 +329,7 @@
// bypass the optimized downmix routines for the common formats
if (!Downmix_foldGeneric(
downmixInputChannelMask, pSrc, pDst, numFrames, accumulate)) {
- ALOGE("Multichannel configuration 0x%x is not supported", downmixInputChannelMask);
+ ALOGE("Multichannel configuration 0x%" PRIx32 " is not supported", downmixInputChannelMask);
return -EINVAL;
}
break;
@@ -352,7 +353,7 @@
default:
if (!Downmix_foldGeneric(
downmixInputChannelMask, pSrc, pDst, numFrames, accumulate)) {
- ALOGE("Multichannel configuration 0x%x is not supported", downmixInputChannelMask);
+ ALOGE("Multichannel configuration 0x%" PRIx32 " is not supported", downmixInputChannelMask);
return -EINVAL;
}
break;
@@ -380,7 +381,7 @@
pDownmixer = (downmix_object_t*) &pDwmModule->context;
- ALOGV("Downmix_Command command %d cmdSize %d",cmdCode, cmdSize);
+ ALOGV("Downmix_Command command %" PRIu32 " cmdSize %" PRIu32, cmdCode, cmdSize);
switch (cmdCode) {
case EFFECT_CMD_INIT:
@@ -404,7 +405,7 @@
break;
case EFFECT_CMD_GET_PARAM:
- ALOGV("Downmix_Command EFFECT_CMD_GET_PARAM pCmdData %p, *replySize %d, pReplyData: %p",
+ ALOGV("Downmix_Command EFFECT_CMD_GET_PARAM pCmdData %p, *replySize %" PRIu32 ", pReplyData: %p",
pCmdData, *replySize, pReplyData);
if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
pReplyData == NULL ||
@@ -413,7 +414,7 @@
}
effect_param_t *rep = (effect_param_t *) pReplyData;
memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + sizeof(int32_t));
- ALOGV("Downmix_Command EFFECT_CMD_GET_PARAM param %d, replySize %d",
+ ALOGV("Downmix_Command EFFECT_CMD_GET_PARAM param %" PRId32 ", replySize %" PRIu32,
*(int32_t *)rep->data, rep->vsize);
rep->status = Downmix_getParameter(pDownmixer, *(int32_t *)rep->data, &rep->vsize,
rep->data + sizeof(int32_t));
@@ -421,8 +422,8 @@
break;
case EFFECT_CMD_SET_PARAM:
- ALOGV("Downmix_Command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, " \
- "pReplyData %p", cmdSize, pCmdData, *replySize, pReplyData);
+ ALOGV("Downmix_Command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %" PRIu32
+ ", pReplyData %p", cmdSize, pCmdData, *replySize, pReplyData);
if (pCmdData == NULL || (cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)))
|| pReplyData == NULL || *replySize != (int)sizeof(int32_t)) {
return -EINVAL;
@@ -471,7 +472,7 @@
return -EINVAL;
}
// FIXME change type if playing on headset vs speaker
- ALOGV("Downmix_Command EFFECT_CMD_SET_DEVICE: 0x%08x", *(uint32_t *)pCmdData);
+ ALOGV("Downmix_Command EFFECT_CMD_SET_DEVICE: 0x%08" PRIx32, *(uint32_t *)pCmdData);
break;
case EFFECT_CMD_SET_VOLUME: {
@@ -491,7 +492,7 @@
if (pCmdData == NULL || cmdSize != (int)sizeof(uint32_t)) {
return -EINVAL;
}
- ALOGV("Downmix_Command EFFECT_CMD_SET_AUDIO_MODE: %d", *(uint32_t *)pCmdData);
+ ALOGV("Downmix_Command EFFECT_CMD_SET_AUDIO_MODE: %" PRIu32, *(uint32_t *)pCmdData);
break;
case EFFECT_CMD_SET_CONFIG_REVERSE:
@@ -500,7 +501,7 @@
break;
default:
- ALOGW("Downmix_Command invalid command %d",cmdCode);
+ ALOGW("Downmix_Command invalid command %" PRIu32, cmdCode);
return -EINVAL;
}
@@ -702,28 +703,28 @@
int Downmix_setParameter(downmix_object_t *pDownmixer, int32_t param, uint32_t size, void *pValue) {
int16_t value16;
- ALOGV("Downmix_setParameter, context %p, param %d, value16 %d, value32 %d",
+ ALOGV("Downmix_setParameter, context %p, param %" PRId32 ", value16 %" PRId16 ", value32 %" PRId32,
pDownmixer, param, *(int16_t *)pValue, *(int32_t *)pValue);
switch (param) {
case DOWNMIX_PARAM_TYPE:
if (size != sizeof(downmix_type_t)) {
- ALOGE("Downmix_setParameter(DOWNMIX_PARAM_TYPE) invalid size %u, should be %zu",
+ ALOGE("Downmix_setParameter(DOWNMIX_PARAM_TYPE) invalid size %" PRIu32 ", should be %zu",
size, sizeof(downmix_type_t));
return -EINVAL;
}
value16 = *(int16_t *)pValue;
- ALOGV("set DOWNMIX_PARAM_TYPE, type %d", value16);
+ ALOGV("set DOWNMIX_PARAM_TYPE, type %" PRId16, value16);
if (!((value16 > DOWNMIX_TYPE_INVALID) && (value16 <= DOWNMIX_TYPE_LAST))) {
- ALOGE("Downmix_setParameter invalid DOWNMIX_PARAM_TYPE value %d", value16);
+ ALOGE("Downmix_setParameter invalid DOWNMIX_PARAM_TYPE value %" PRId16, value16);
return -EINVAL;
} else {
pDownmixer->type = (downmix_type_t) value16;
break;
default:
- ALOGE("Downmix_setParameter unknown parameter %d", param);
+ ALOGE("Downmix_setParameter unknown parameter %" PRId32, param);
return -EINVAL;
}
}
@@ -762,17 +763,17 @@
case DOWNMIX_PARAM_TYPE:
if (*pSize < sizeof(int16_t)) {
- ALOGE("Downmix_getParameter invalid parameter size %zu for DOWNMIX_PARAM_TYPE", *pSize);
+ ALOGE("Downmix_getParameter invalid parameter size %" PRIu32 " for DOWNMIX_PARAM_TYPE", *pSize);
return -EINVAL;
}
pValue16 = (int16_t *)pValue;
*pValue16 = (int16_t) pDownmixer->type;
*pSize = sizeof(int16_t);
- ALOGV("Downmix_getParameter DOWNMIX_PARAM_TYPE is %d", *pValue16);
+ ALOGV("Downmix_getParameter DOWNMIX_PARAM_TYPE is %" PRId16, *pValue16);
break;
default:
- ALOGE("Downmix_getParameter unknown parameter %d", param);
+ ALOGE("Downmix_getParameter unknown parameter %" PRId16, param);
return -EINVAL;
}
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index 5bdaa03..47cab62 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -16,8 +16,9 @@
#define LOG_TAG "EffectVisualizer"
//#define LOG_NDEBUG 0
-#include <cutils/log.h>
+#include <log/log.h>
#include <assert.h>
+#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <new>
@@ -226,8 +227,8 @@
//
int VisualizerLib_Create(const effect_uuid_t *uuid,
- int32_t sessionId,
- int32_t ioId,
+ int32_t /*sessionId*/,
+ int32_t /*ioId*/,
effect_handle_t *pHandle) {
int ret;
int i;
@@ -418,7 +419,7 @@
return -EINVAL;
}
-// ALOGV("Visualizer_command command %d cmdSize %d",cmdCode, cmdSize);
+// ALOGV("Visualizer_command command %" PRIu32 " cmdSize %" PRIu32, cmdCode, cmdSize);
switch (cmdCode) {
case EFFECT_CMD_INIT:
@@ -484,19 +485,19 @@
}
switch (*(uint32_t *)p->data) {
case VISUALIZER_PARAM_CAPTURE_SIZE:
- ALOGV("get mCaptureSize = %d", pContext->mCaptureSize);
+ ALOGV("get mCaptureSize = %" PRIu32, pContext->mCaptureSize);
*((uint32_t *)p->data + 1) = pContext->mCaptureSize;
p->vsize = sizeof(uint32_t);
*replySize += sizeof(uint32_t);
break;
case VISUALIZER_PARAM_SCALING_MODE:
- ALOGV("get mScalingMode = %d", pContext->mScalingMode);
+ ALOGV("get mScalingMode = %" PRIu32, pContext->mScalingMode);
*((uint32_t *)p->data + 1) = pContext->mScalingMode;
p->vsize = sizeof(uint32_t);
*replySize += sizeof(uint32_t);
break;
case VISUALIZER_PARAM_MEASUREMENT_MODE:
- ALOGV("get mMeasurementMode = %d", pContext->mMeasurementMode);
+ ALOGV("get mMeasurementMode = %" PRIu32, pContext->mMeasurementMode);
*((uint32_t *)p->data + 1) = pContext->mMeasurementMode;
p->vsize = sizeof(uint32_t);
*replySize += sizeof(uint32_t);
@@ -520,19 +521,19 @@
switch (*(uint32_t *)p->data) {
case VISUALIZER_PARAM_CAPTURE_SIZE:
pContext->mCaptureSize = *((uint32_t *)p->data + 1);
- ALOGV("set mCaptureSize = %d", pContext->mCaptureSize);
+ ALOGV("set mCaptureSize = %" PRIu32, pContext->mCaptureSize);
break;
case VISUALIZER_PARAM_SCALING_MODE:
pContext->mScalingMode = *((uint32_t *)p->data + 1);
- ALOGV("set mScalingMode = %d", pContext->mScalingMode);
+ ALOGV("set mScalingMode = %" PRIu32, pContext->mScalingMode);
break;
case VISUALIZER_PARAM_LATENCY:
pContext->mLatency = *((uint32_t *)p->data + 1);
- ALOGV("set mLatency = %d", pContext->mLatency);
+ ALOGV("set mLatency = %" PRIu32, pContext->mLatency);
break;
case VISUALIZER_PARAM_MEASUREMENT_MODE:
pContext->mMeasurementMode = *((uint32_t *)p->data + 1);
- ALOGV("set mMeasurementMode = %d", pContext->mMeasurementMode);
+ ALOGV("set mMeasurementMode = %" PRIu32, pContext->mMeasurementMode);
break;
default:
*(int32_t *)pReplyData = -EINVAL;
@@ -545,9 +546,9 @@
case VISUALIZER_CMD_CAPTURE: {
- int32_t captureSize = pContext->mCaptureSize;
+ uint32_t captureSize = pContext->mCaptureSize;
if (pReplyData == NULL || *replySize != captureSize) {
- ALOGV("VISUALIZER_CMD_CAPTURE() error *replySize %d captureSize %d",
+ ALOGV("VISUALIZER_CMD_CAPTURE() error *replySize %" PRIu32 " captureSize %" PRIu32,
*replySize, captureSize);
return -EINVAL;
}
@@ -573,7 +574,7 @@
int32_t capturePoint = pContext->mCaptureIdx - captureSize - deltaSmpl;
if (capturePoint < 0) {
- int32_t size = -capturePoint;
+ uint32_t size = -capturePoint;
if (size > captureSize) {
size = captureSize;
}
@@ -604,7 +605,7 @@
// measurements aren't relevant anymore and shouldn't bias the new one)
const int32_t delayMs = Visualizer_getDeltaTimeMsFromUpdatedTime(pContext);
if (delayMs > DISCARD_MEASUREMENTS_TIME_MS) {
- ALOGV("Discarding measurements, last measurement is %dms old", delayMs);
+ ALOGV("Discarding measurements, last measurement is %" PRId32 "ms old", delayMs);
for (uint32_t i=0 ; i<pContext->mMeasurementWindowSizeInBuffers ; i++) {
pContext->mPastMeasurements[i].mIsValid = false;
pContext->mPastMeasurements[i].mPeakU16 = 0;
@@ -638,14 +639,14 @@
} else {
pIntReplyData[MEASUREMENT_IDX_PEAK] = (int32_t) (2000 * log10(peakU16 / 32767.0f));
}
- ALOGV("VISUALIZER_CMD_MEASURE peak=%d (%dmB), rms=%.1f (%dmB)",
+ ALOGV("VISUALIZER_CMD_MEASURE peak=%" PRIu16 " (%" PRId32 "mB), rms=%.1f (%" PRId32 "mB)",
peakU16, pIntReplyData[MEASUREMENT_IDX_PEAK],
rms, pIntReplyData[MEASUREMENT_IDX_RMS]);
}
break;
default:
- ALOGW("Visualizer_command invalid command %d",cmdCode);
+ ALOGW("Visualizer_command invalid command %" PRIu32, cmdCode);
return -EINVAL;
}
diff --git a/media/libstagefright/AMRExtractor.cpp b/media/libstagefright/AMRExtractor.cpp
index 3f592ed..a6fb3d8 100644
--- a/media/libstagefright/AMRExtractor.cpp
+++ b/media/libstagefright/AMRExtractor.cpp
@@ -265,7 +265,7 @@
mOffset = mOffsetTable[index] + (mIsWide ? 9 : 6);
- for (int i = 0; i< seekFrame - index * 50; i++) {
+ for (size_t i = 0; i< seekFrame - index * 50; i++) {
status_t err;
if ((err = getFrameSizeByOffset(mDataSource, mOffset,
mIsWide, &size)) != OK) {
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index 60cdf66..15ba967 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -135,7 +135,7 @@
}
bool videoSizeSupported = false;
- for (uint32_t i = 0; i < supportedSizes.size(); ++i) {
+ for (size_t i = 0; i < supportedSizes.size(); ++i) {
int32_t pictureWidth = supportedSizes[i].width;
int32_t pictureHeight = supportedSizes[i].height;
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 72ea32d..61cf0ad 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -648,7 +648,7 @@
ssize_t lowwaterMarkKb, highwaterMarkKb;
int keepAliveSecs;
- if (sscanf(s, "%d/%d/%d",
+ if (sscanf(s, "%zd/%zd/%d",
&lowwaterMarkKb, &highwaterMarkKb, &keepAliveSecs) != 3) {
ALOGE("Failed to parse cache parameters from '%s'.", s);
return;
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 1cfe6c0..a879656 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <inttypes.h>
+
//#define LOG_NDEBUG 0
#define LOG_TAG "OMXCodec"
#include <utils/Log.h>
@@ -4251,9 +4253,9 @@
CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput)
|| (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput));
- printf(" nBufferCountActual = %ld\n", def.nBufferCountActual);
- printf(" nBufferCountMin = %ld\n", def.nBufferCountMin);
- printf(" nBufferSize = %ld\n", def.nBufferSize);
+ printf(" nBufferCountActual = %" PRIu32 "\n", def.nBufferCountActual);
+ printf(" nBufferCountMin = %" PRIu32 "\n", def.nBufferCountMin);
+ printf(" nBufferSize = %" PRIu32 "\n", def.nBufferSize);
switch (def.eDomain) {
case OMX_PortDomainImage:
@@ -4262,9 +4264,9 @@
printf("\n");
printf(" // Image\n");
- printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth);
- printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight);
- printf(" nStride = %ld\n", imageDef->nStride);
+ printf(" nFrameWidth = %" PRIu32 "\n", imageDef->nFrameWidth);
+ printf(" nFrameHeight = %" PRIu32 "\n", imageDef->nFrameHeight);
+ printf(" nStride = %" PRIu32 "\n", imageDef->nStride);
printf(" eCompressionFormat = %s\n",
imageCompressionFormatString(imageDef->eCompressionFormat));
@@ -4281,9 +4283,9 @@
printf("\n");
printf(" // Video\n");
- printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth);
- printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight);
- printf(" nStride = %ld\n", videoDef->nStride);
+ printf(" nFrameWidth = %" PRIu32 "\n", videoDef->nFrameWidth);
+ printf(" nFrameHeight = %" PRIu32 "\n", videoDef->nFrameHeight);
+ printf(" nStride = %" PRIu32 "\n", videoDef->nStride);
printf(" eCompressionFormat = %s\n",
videoCompressionFormatString(videoDef->eCompressionFormat));
@@ -4312,10 +4314,10 @@
mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params));
CHECK_EQ(err, (status_t)OK);
- printf(" nSamplingRate = %ld\n", params.nSamplingRate);
- printf(" nChannels = %ld\n", params.nChannels);
+ printf(" nSamplingRate = %" PRIu32 "\n", params.nSamplingRate);
+ printf(" nChannels = %" PRIu32 "\n", params.nChannels);
printf(" bInterleaved = %d\n", params.bInterleaved);
- printf(" nBitPerSample = %ld\n", params.nBitPerSample);
+ printf(" nBitPerSample = %" PRIu32 "\n", params.nBitPerSample);
printf(" eNumData = %s\n",
params.eNumData == OMX_NumericalDataSigned
@@ -4331,7 +4333,7 @@
mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
CHECK_EQ(err, (status_t)OK);
- printf(" nChannels = %ld\n", amr.nChannels);
+ printf(" nChannels = %" PRIu32 "\n", amr.nChannels);
printf(" eAMRBandMode = %s\n",
amrBandModeString(amr.eAMRBandMode));
printf(" eAMRFrameFormat = %s\n",
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes.h
index 8b295a6..912cb0d 100644
--- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes.h
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes.h
@@ -32,6 +32,7 @@
#define _OMXTYPES_H_
#include <limits.h>
+#include <stdint.h>
#define OMX_IN
#define OMX_OUT
@@ -75,64 +76,22 @@
/* OMX_U8 */
-#if UCHAR_MAX == 0xff
-typedef unsigned char OMX_U8;
-#elif USHRT_MAX == 0xff
-typedef unsigned short int OMX_U8;
-#else
-#error OMX_U8 undefined
-#endif
-
+typedef uint8_t OMX_U8;
/* OMX_S8 */
-#if SCHAR_MAX == 0x7f
-typedef signed char OMX_S8;
-#elif SHRT_MAX == 0x7f
-typedef signed short int OMX_S8;
-#else
-#error OMX_S8 undefined
-#endif
-
+typedef int8_t OMX_S8;
/* OMX_U16 */
-#if USHRT_MAX == 0xffff
-typedef unsigned short int OMX_U16;
-#elif UINT_MAX == 0xffff
-typedef unsigned int OMX_U16;
-#else
-#error OMX_U16 undefined
-#endif
-
+typedef uint16_t OMX_U16;
/* OMX_S16 */
-#if SHRT_MAX == 0x7fff
-typedef signed short int OMX_S16;
-#elif INT_MAX == 0x7fff
-typedef signed int OMX_S16;
-#else
-#error OMX_S16 undefined
-#endif
-
+typedef int16_t OMX_S16;
/* OMX_U32 */
-#if UINT_MAX == 0xffffffff
-typedef unsigned int OMX_U32;
-#elif LONG_MAX == 0xffffffff
-typedef unsigned long int OMX_U32;
-#else
-#error OMX_U32 undefined
-#endif
-
+typedef uint32_t OMX_U32;
/* OMX_S32 */
-#if INT_MAX == 0x7fffffff
-typedef signed int OMX_S32;
-#elif LONG_MAX == 0x7fffffff
-typedef long signed int OMX_S32;
-#else
-#error OMX_S32 undefined
-#endif
-
+typedef int32_t OMX_S32;
/* OMX_U64 & OMX_S64 */
#if defined( _WIN32 ) || defined ( _WIN64 )
@@ -143,15 +102,14 @@
#define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFi64)
#define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFi64)
#else
- typedef long long OMX_S64; /** Signed 64-bit integer */
- typedef unsigned long long OMX_U64; /** Unsigned 64-bit integer */
+ typedef int64_t OMX_S64; /** Signed 64-bit integer */
+ typedef uint64_t OMX_U64; /** Unsigned 64-bit integer */
#define OMX_MIN_S64 (0x8000000000000000LL)
#define OMX_MIN_U64 (0x0000000000000000LL)
#define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFLL)
#define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFLL)
#endif
-
/* OMX_SC8 */
typedef struct
{
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h
index 8b295a6..912cb0d 100755
--- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h
@@ -32,6 +32,7 @@
#define _OMXTYPES_H_
#include <limits.h>
+#include <stdint.h>
#define OMX_IN
#define OMX_OUT
@@ -75,64 +76,22 @@
/* OMX_U8 */
-#if UCHAR_MAX == 0xff
-typedef unsigned char OMX_U8;
-#elif USHRT_MAX == 0xff
-typedef unsigned short int OMX_U8;
-#else
-#error OMX_U8 undefined
-#endif
-
+typedef uint8_t OMX_U8;
/* OMX_S8 */
-#if SCHAR_MAX == 0x7f
-typedef signed char OMX_S8;
-#elif SHRT_MAX == 0x7f
-typedef signed short int OMX_S8;
-#else
-#error OMX_S8 undefined
-#endif
-
+typedef int8_t OMX_S8;
/* OMX_U16 */
-#if USHRT_MAX == 0xffff
-typedef unsigned short int OMX_U16;
-#elif UINT_MAX == 0xffff
-typedef unsigned int OMX_U16;
-#else
-#error OMX_U16 undefined
-#endif
-
+typedef uint16_t OMX_U16;
/* OMX_S16 */
-#if SHRT_MAX == 0x7fff
-typedef signed short int OMX_S16;
-#elif INT_MAX == 0x7fff
-typedef signed int OMX_S16;
-#else
-#error OMX_S16 undefined
-#endif
-
+typedef int16_t OMX_S16;
/* OMX_U32 */
-#if UINT_MAX == 0xffffffff
-typedef unsigned int OMX_U32;
-#elif LONG_MAX == 0xffffffff
-typedef unsigned long int OMX_U32;
-#else
-#error OMX_U32 undefined
-#endif
-
+typedef uint32_t OMX_U32;
/* OMX_S32 */
-#if INT_MAX == 0x7fffffff
-typedef signed int OMX_S32;
-#elif LONG_MAX == 0x7fffffff
-typedef long signed int OMX_S32;
-#else
-#error OMX_S32 undefined
-#endif
-
+typedef int32_t OMX_S32;
/* OMX_U64 & OMX_S64 */
#if defined( _WIN32 ) || defined ( _WIN64 )
@@ -143,15 +102,14 @@
#define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFi64)
#define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFi64)
#else
- typedef long long OMX_S64; /** Signed 64-bit integer */
- typedef unsigned long long OMX_U64; /** Unsigned 64-bit integer */
+ typedef int64_t OMX_S64; /** Signed 64-bit integer */
+ typedef uint64_t OMX_U64; /** Unsigned 64-bit integer */
#define OMX_MIN_S64 (0x8000000000000000LL)
#define OMX_MIN_U64 (0x0000000000000000LL)
#define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFLL)
#define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFLL)
#endif
-
/* OMX_SC8 */
typedef struct
{
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/omxtypes.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/omxtypes.h
index 8b295a6..912cb0d 100644
--- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/omxtypes.h
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/omxtypes.h
@@ -32,6 +32,7 @@
#define _OMXTYPES_H_
#include <limits.h>
+#include <stdint.h>
#define OMX_IN
#define OMX_OUT
@@ -75,64 +76,22 @@
/* OMX_U8 */
-#if UCHAR_MAX == 0xff
-typedef unsigned char OMX_U8;
-#elif USHRT_MAX == 0xff
-typedef unsigned short int OMX_U8;
-#else
-#error OMX_U8 undefined
-#endif
-
+typedef uint8_t OMX_U8;
/* OMX_S8 */
-#if SCHAR_MAX == 0x7f
-typedef signed char OMX_S8;
-#elif SHRT_MAX == 0x7f
-typedef signed short int OMX_S8;
-#else
-#error OMX_S8 undefined
-#endif
-
+typedef int8_t OMX_S8;
/* OMX_U16 */
-#if USHRT_MAX == 0xffff
-typedef unsigned short int OMX_U16;
-#elif UINT_MAX == 0xffff
-typedef unsigned int OMX_U16;
-#else
-#error OMX_U16 undefined
-#endif
-
+typedef uint16_t OMX_U16;
/* OMX_S16 */
-#if SHRT_MAX == 0x7fff
-typedef signed short int OMX_S16;
-#elif INT_MAX == 0x7fff
-typedef signed int OMX_S16;
-#else
-#error OMX_S16 undefined
-#endif
-
+typedef int16_t OMX_S16;
/* OMX_U32 */
-#if UINT_MAX == 0xffffffff
-typedef unsigned int OMX_U32;
-#elif LONG_MAX == 0xffffffff
-typedef unsigned long int OMX_U32;
-#else
-#error OMX_U32 undefined
-#endif
-
+typedef uint32_t OMX_U32;
/* OMX_S32 */
-#if INT_MAX == 0x7fffffff
-typedef signed int OMX_S32;
-#elif LONG_MAX == 0x7fffffff
-typedef long signed int OMX_S32;
-#else
-#error OMX_S32 undefined
-#endif
-
+typedef int32_t OMX_S32;
/* OMX_U64 & OMX_S64 */
#if defined( _WIN32 ) || defined ( _WIN64 )
@@ -143,15 +102,14 @@
#define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFi64)
#define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFi64)
#else
- typedef long long OMX_S64; /** Signed 64-bit integer */
- typedef unsigned long long OMX_U64; /** Unsigned 64-bit integer */
+ typedef int64_t OMX_S64; /** Signed 64-bit integer */
+ typedef uint64_t OMX_U64; /** Unsigned 64-bit integer */
#define OMX_MIN_S64 (0x8000000000000000LL)
#define OMX_MIN_U64 (0x0000000000000000LL)
#define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFLL)
#define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFLL)
#endif
-
/* OMX_SC8 */
typedef struct
{
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index 0b4a616..16f6c58 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <inttypes.h>
+
#define LOG_TAG "GraphicBufferSource"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
@@ -207,7 +209,7 @@
return;
}
- ALOGV("addCodecBuffer h=%p size=%lu p=%p",
+ ALOGV("addCodecBuffer h=%p size=%" PRIu32 " p=%p",
header, header->nAllocLen, header->pBuffer);
CodecBuffer codecBuffer;
codecBuffer.mHeader = header;
@@ -228,7 +230,7 @@
return;
}
- ALOGV("codecBufferEmptied h=%p size=%lu filled=%lu p=%p",
+ ALOGV("codecBufferEmptied h=%p size=%" PRIu32 " filled=%" PRIu32 " p=%p",
header, header->nAllocLen, header->nFilledLen,
header->pBuffer);
CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index a608479..74076c6 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <inttypes.h>
+
//#define LOG_NDEBUG 0
#define LOG_TAG "OMX"
#include <utils/Log.h>
@@ -425,7 +427,7 @@
OMX_IN OMX_U32 nData1,
OMX_IN OMX_U32 nData2,
OMX_IN OMX_PTR /* pEventData */) {
- ALOGV("OnEvent(%d, %ld, %ld)", eEvent, nData1, nData2);
+ ALOGV("OnEvent(%d, %" PRIu32", %" PRIu32 ")", eEvent, nData1, nData2);
// Forward to OMXNodeInstance.
findInstance(node)->onEvent(eEvent, nData1, nData2);
diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
index 08a3d42..eb9fcf7 100644
--- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <inttypes.h>
+
//#define LOG_NDEBUG 0
#define LOG_TAG "SoftVideoDecoderOMXComponent"
#include <utils/Log.h>
@@ -177,7 +179,7 @@
(OMX_VIDEO_PARAM_PROFILELEVELTYPE *) params;
if (profileLevel->nPortIndex != kInputPortIndex) {
- ALOGE("Invalid port index: %ld", profileLevel->nPortIndex);
+ ALOGE("Invalid port index: %" PRIu32, profileLevel->nPortIndex);
return OMX_ErrorUnsupportedIndex;
}
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index d672dff..d6d5dd5 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -195,7 +195,7 @@
MtpDevice::~MtpDevice() {
close();
- for (int i = 0; i < mDeviceProperties.size(); i++)
+ for (size_t i = 0; i < mDeviceProperties.size(); i++)
delete mDeviceProperties[i];
usb_request_free(mRequestIn1);
usb_request_free(mRequestIn2);
@@ -253,7 +253,7 @@
ALOGI("*** FORMAT: %s\n", MtpDebug::getFormatCodeName(format));
MtpObjectPropertyList* props = getObjectPropsSupported(format);
if (props) {
- for (int j = 0; j < props->size(); j++) {
+ for (size_t j = 0; j < props->size(); j++) {
MtpObjectProperty prop = (*props)[j];
MtpProperty* property = getObjectPropDesc(prop, format);
if (property) {
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index dadfb54..157f2ce 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -20,6 +20,7 @@
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <dirent.h>
@@ -125,7 +126,7 @@
void MtpServer::removeStorage(MtpStorage* storage) {
Mutex::Autolock autoLock(mMutex);
- for (int i = 0; i < mStorages.size(); i++) {
+ for (size_t i = 0; i < mStorages.size(); i++) {
if (mStorages[i] == storage) {
mStorages.removeAt(i);
sendStoreRemoved(storage->getStorageID());
@@ -137,7 +138,7 @@
MtpStorage* MtpServer::getStorage(MtpStorageID id) {
if (id == 0)
return mStorages[0];
- for (int i = 0; i < mStorages.size(); i++) {
+ for (size_t i = 0; i < mStorages.size(); i++) {
MtpStorage* storage = mStorages[i];
if (storage->getStorageID() == id)
return storage;
@@ -1116,7 +1117,7 @@
}
const char* filePath = (const char *)edit->mPath;
- ALOGV("receiving partial %s %lld %lld\n", filePath, offset, length);
+ ALOGV("receiving partial %s %lld %" PRIu32 "\n", filePath, offset, length);
// read the header, and possibly some data
int ret = mData.read(mFD);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index bb8c15e..755d480 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -607,7 +607,7 @@
}
// Look for sync events awaiting for a session to be used.
- for (int i = 0; i < (int)mPendingSyncEvents.size(); i++) {
+ for (size_t i = 0; i < mPendingSyncEvents.size(); i++) {
if (mPendingSyncEvents[i]->triggerSession() == lSessionId) {
if (thread->isValidSyncEvent(mPendingSyncEvents[i])) {
if (lStatus == NO_ERROR) {
@@ -912,7 +912,7 @@
AutoMutex lock(mLock);
mStreamTypes[stream].mute = muted;
- for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
+ for (size_t i = 0; i < mPlaybackThreads.size(); i++)
mPlaybackThreads.valueAt(i)->setStreamMute(stream, muted);
return NO_ERROR;
diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp
index ca98f16..562c4ea 100644
--- a/services/audioflinger/AudioResampler.cpp
+++ b/services/audioflinger/AudioResampler.cpp
@@ -234,7 +234,16 @@
case DYN_MED_QUALITY:
case DYN_HIGH_QUALITY:
ALOGV("Create dynamic Resampler = %d", quality);
- resampler = new AudioResamplerDyn(bitDepth, inChannelCount, sampleRate, quality);
+ if (bitDepth == 32) { /* bitDepth == 32 signals float precision */
+ resampler = new AudioResamplerDyn<float, float, float>(bitDepth, inChannelCount,
+ sampleRate, quality);
+ } else if (quality == DYN_HIGH_QUALITY) {
+ resampler = new AudioResamplerDyn<int32_t, int16_t, int32_t>(bitDepth, inChannelCount,
+ sampleRate, quality);
+ } else {
+ resampler = new AudioResamplerDyn<int16_t, int16_t, int32_t>(bitDepth, inChannelCount,
+ sampleRate, quality);
+ }
break;
}
diff --git a/services/audioflinger/AudioResamplerDyn.cpp b/services/audioflinger/AudioResamplerDyn.cpp
index 7e4ca0c..3abe8fd 100644
--- a/services/audioflinger/AudioResamplerDyn.cpp
+++ b/services/audioflinger/AudioResamplerDyn.cpp
@@ -25,6 +25,7 @@
#include <cutils/compiler.h>
#include <cutils/properties.h>
+#include <utils/Debug.h>
#include <utils/Log.h>
#include "AudioResamplerFirOps.h" // USE_NEON and USE_INLINE_ASSEMBLY defined here
@@ -38,9 +39,9 @@
namespace android {
// generate a unique resample type compile-time constant (constexpr)
-#define RESAMPLETYPE(CHANNELS, LOCKED, STRIDE, COEFTYPE) \
- ((((CHANNELS)-1)&1) | !!(LOCKED)<<1 | (COEFTYPE)<<2 \
- | ((STRIDE)==8 ? 1 : (STRIDE)==16 ? 2 : 0)<<3)
+#define RESAMPLETYPE(CHANNELS, LOCKED, STRIDE) \
+ ((((CHANNELS)-1)&1) | !!(LOCKED)<<1 \
+ | ((STRIDE)==8 ? 1 : (STRIDE)==16 ? 2 : 0)<<2)
/*
* InBuffer is a type agnostic input buffer.
@@ -58,42 +59,46 @@
* r = extra space for implementing the ring buffer
*/
-template<typename TI>
-AudioResamplerDyn::InBuffer<TI>::InBuffer()
- : mState(NULL), mImpulse(NULL), mRingFull(NULL), mStateSize(0) {
+template<typename TC, typename TI, typename TO>
+AudioResamplerDyn<TC, TI, TO>::InBuffer::InBuffer()
+ : mState(NULL), mImpulse(NULL), mRingFull(NULL), mStateCount(0)
+{
}
-template<typename TI>
-AudioResamplerDyn::InBuffer<TI>::~InBuffer() {
+template<typename TC, typename TI, typename TO>
+AudioResamplerDyn<TC, TI, TO>::InBuffer::~InBuffer()
+{
init();
}
-template<typename TI>
-void AudioResamplerDyn::InBuffer<TI>::init() {
+template<typename TC, typename TI, typename TO>
+void AudioResamplerDyn<TC, TI, TO>::InBuffer::init()
+{
free(mState);
mState = NULL;
mImpulse = NULL;
mRingFull = NULL;
- mStateSize = 0;
+ mStateCount = 0;
}
// resizes the state buffer to accommodate the appropriate filter length
-template<typename TI>
-void AudioResamplerDyn::InBuffer<TI>::resize(int CHANNELS, int halfNumCoefs) {
+template<typename TC, typename TI, typename TO>
+void AudioResamplerDyn<TC, TI, TO>::InBuffer::resize(int CHANNELS, int halfNumCoefs)
+{
// calculate desired state size
- int stateSize = halfNumCoefs * CHANNELS * 2
- * kStateSizeMultipleOfFilterLength;
+ int stateCount = halfNumCoefs * CHANNELS * 2 * kStateSizeMultipleOfFilterLength;
// check if buffer needs resizing
if (mState
- && stateSize == mStateSize
- && mRingFull-mState == mStateSize-halfNumCoefs*CHANNELS) {
+ && stateCount == mStateCount
+ && mRingFull-mState == mStateCount-halfNumCoefs*CHANNELS) {
return;
}
// create new buffer
- TI* state = (int16_t*)memalign(32, stateSize*sizeof(*state));
- memset(state, 0, stateSize*sizeof(*state));
+ TI* state;
+ (void)posix_memalign(reinterpret_cast<void**>(&state), 32, stateCount*sizeof(*state));
+ memset(state, 0, stateCount*sizeof(*state));
// attempt to preserve state
if (mState) {
@@ -105,8 +110,8 @@
dst += mState-srcLo;
srcLo = mState;
}
- if (srcHi > mState + mStateSize) {
- srcHi = mState + mStateSize;
+ if (srcHi > mState + mStateCount) {
+ srcHi = mState + mStateCount;
}
memcpy(dst, srcLo, (srcHi - srcLo) * sizeof(*srcLo));
free(mState);
@@ -114,27 +119,29 @@
// set class member vars
mState = state;
- mStateSize = stateSize;
- mImpulse = mState + halfNumCoefs*CHANNELS; // actually one sample greater than needed
- mRingFull = mState + mStateSize - halfNumCoefs*CHANNELS;
+ mStateCount = stateCount;
+ mImpulse = state + halfNumCoefs*CHANNELS; // actually one sample greater than needed
+ mRingFull = state + mStateCount - halfNumCoefs*CHANNELS;
}
// copy in the input data into the head (impulse+halfNumCoefs) of the buffer.
-template<typename TI>
+template<typename TC, typename TI, typename TO>
template<int CHANNELS>
-void AudioResamplerDyn::InBuffer<TI>::readAgain(TI*& impulse, const int halfNumCoefs,
- const TI* const in, const size_t inputIndex) {
- int16_t* head = impulse + halfNumCoefs*CHANNELS;
+void AudioResamplerDyn<TC, TI, TO>::InBuffer::readAgain(TI*& impulse, const int halfNumCoefs,
+ const TI* const in, const size_t inputIndex)
+{
+ TI* head = impulse + halfNumCoefs*CHANNELS;
for (size_t i=0 ; i<CHANNELS ; i++) {
head[i] = in[inputIndex*CHANNELS + i];
}
}
// advance the impulse pointer, and load in data into the head (impulse+halfNumCoefs)
-template<typename TI>
+template<typename TC, typename TI, typename TO>
template<int CHANNELS>
-void AudioResamplerDyn::InBuffer<TI>::readAdvance(TI*& impulse, const int halfNumCoefs,
- const TI* const in, const size_t inputIndex) {
+void AudioResamplerDyn<TC, TI, TO>::InBuffer::readAdvance(TI*& impulse, const int halfNumCoefs,
+ const TI* const in, const size_t inputIndex)
+{
impulse += CHANNELS;
if (CC_UNLIKELY(impulse >= mRingFull)) {
@@ -145,7 +152,8 @@
readAgain<CHANNELS>(impulse, halfNumCoefs, in, inputIndex);
}
-void AudioResamplerDyn::Constants::set(
+template<typename TC, typename TI, typename TO>
+void AudioResamplerDyn<TC, TI, TO>::Constants::set(
int L, int halfNumCoefs, int inSampleRate, int outSampleRate)
{
int bits = 0;
@@ -158,10 +166,11 @@
mHalfNumCoefs = halfNumCoefs;
}
-AudioResamplerDyn::AudioResamplerDyn(int bitDepth,
+template<typename TC, typename TI, typename TO>
+AudioResamplerDyn<TC, TI, TO>::AudioResamplerDyn(int bitDepth,
int inChannelCount, int32_t sampleRate, src_quality quality)
: AudioResampler(bitDepth, inChannelCount, sampleRate, quality),
- mResampleType(0), mFilterSampleRate(0), mFilterQuality(DEFAULT_QUALITY),
+ mResampleFunc(0), mFilterSampleRate(0), mFilterQuality(DEFAULT_QUALITY),
mCoefBuffer(NULL)
{
mVolumeSimd[0] = mVolumeSimd[1] = 0;
@@ -172,33 +181,48 @@
mConstants.set(128, 8, mSampleRate, mSampleRate); // TODO: set better
}
-AudioResamplerDyn::~AudioResamplerDyn() {
+template<typename TC, typename TI, typename TO>
+AudioResamplerDyn<TC, TI, TO>::~AudioResamplerDyn()
+{
free(mCoefBuffer);
}
-void AudioResamplerDyn::init() {
+template<typename TC, typename TI, typename TO>
+void AudioResamplerDyn<TC, TI, TO>::init()
+{
mFilterSampleRate = 0; // always trigger new filter generation
mInBuffer.init();
}
-void AudioResamplerDyn::setVolume(int16_t left, int16_t right) {
+template<typename TC, typename TI, typename TO>
+void AudioResamplerDyn<TC, TI, TO>::setVolume(int16_t left, int16_t right)
+{
AudioResampler::setVolume(left, right);
- mVolumeSimd[0] = static_cast<int32_t>(left)<<16;
- mVolumeSimd[1] = static_cast<int32_t>(right)<<16;
+ // volume is applied on the output type.
+ if (is_same<TO, float>::value || is_same<TO, double>::value) {
+ const TO scale = 1. / (1UL << 12);
+ mVolumeSimd[0] = static_cast<TO>(left) * scale;
+ mVolumeSimd[1] = static_cast<TO>(right) * scale;
+ } else {
+ mVolumeSimd[0] = static_cast<int32_t>(left) << 16;
+ mVolumeSimd[1] = static_cast<int32_t>(right) << 16;
+ }
}
-template <typename T> T max(T a, T b) {return a > b ? a : b;}
+template<typename T> T max(T a, T b) {return a > b ? a : b;}
-template <typename T> T absdiff(T a, T b) {return a > b ? a - b : b - a;}
+template<typename T> T absdiff(T a, T b) {return a > b ? a - b : b - a;}
-template<typename T>
-void AudioResamplerDyn::createKaiserFir(Constants &c, double stopBandAtten,
- int inSampleRate, int outSampleRate, double tbwCheat) {
- T* buf = reinterpret_cast<T*>(memalign(32, (c.mL+1)*c.mHalfNumCoefs*sizeof(T)));
+template<typename TC, typename TI, typename TO>
+void AudioResamplerDyn<TC, TI, TO>::createKaiserFir(Constants &c,
+ double stopBandAtten, int inSampleRate, int outSampleRate, double tbwCheat)
+{
+ TC* buf;
static const double atten = 0.9998; // to avoid ripple overflow
double fcr;
double tbw = firKaiserTbw(c.mHalfNumCoefs, stopBandAtten);
+ (void)posix_memalign(reinterpret_cast<void**>(&buf), 32, (c.mL+1)*c.mHalfNumCoefs*sizeof(TC));
if (inSampleRate < outSampleRate) { // upsample
fcr = max(0.5*tbwCheat - tbw/2, tbw/2);
} else { // downsample
@@ -206,7 +230,7 @@
}
// create and set filter
firKaiserGen(buf, c.mL, c.mHalfNumCoefs, stopBandAtten, fcr, atten);
- c.setBuf(buf);
+ c.mFirCoefs = buf;
if (mCoefBuffer) {
free(mCoefBuffer);
}
@@ -228,7 +252,8 @@
}
// recursive gcd. Using objdump, it appears the tail recursion is converted to a while loop.
-static int gcd(int n, int m) {
+static int gcd(int n, int m)
+{
if (m == 0) {
return n;
}
@@ -236,7 +261,8 @@
}
static bool isClose(int32_t newSampleRate, int32_t prevSampleRate,
- int32_t filterSampleRate, int32_t outSampleRate) {
+ int32_t filterSampleRate, int32_t outSampleRate)
+{
// different upsampling ratios do not need a filter change.
if (filterSampleRate != 0
@@ -253,7 +279,9 @@
return pdiff < prevSampleRate>>4 && adiff < filterSampleRate>>3;
}
-void AudioResamplerDyn::setSampleRate(int32_t inSampleRate) {
+template<typename TC, typename TI, typename TO>
+void AudioResamplerDyn<TC, TI, TO>::setSampleRate(int32_t inSampleRate)
+{
if (mInSampleRate == inSampleRate) {
return;
}
@@ -357,13 +385,8 @@
// create the filter
mConstants.set(phases, halfLength, inSampleRate, mSampleRate);
- if (useS32) {
- createKaiserFir<int32_t>(mConstants, stopBandAtten,
- inSampleRate, mSampleRate, tbwCheat);
- } else {
- createKaiserFir<int16_t>(mConstants, stopBandAtten,
- inSampleRate, mSampleRate, tbwCheat);
- }
+ createKaiserFir(mConstants, stopBandAtten,
+ inSampleRate, mSampleRate, tbwCheat);
} // End Kaiser filter
// update phase and state based on the new filter.
@@ -385,7 +408,7 @@
mPhaseFraction = mPhaseFraction >> c.mShift << c.mShift; // remove fractional phase
}
- mResampleType = RESAMPLETYPE(mChannelCount, locked, stride, !!useS32);
+ setResampler(RESAMPLETYPE(mChannelCount, locked, stride));
#ifdef DEBUG_RESAMPLER
printf("channels:%d %s stride:%d %s coef:%d shift:%d\n",
mChannelCount, locked ? "locked" : "interpolated",
@@ -393,78 +416,45 @@
#endif
}
-void AudioResamplerDyn::resample(int32_t* out, size_t outFrameCount,
+template<typename TC, typename TI, typename TO>
+void AudioResamplerDyn<TC, TI, TO>::resample(int32_t* out, size_t outFrameCount,
AudioBufferProvider* provider)
{
- // TODO:
- // 24 cases - this perhaps can be reduced later, as testing might take too long
- switch (mResampleType) {
+ (this->*mResampleFunc)(reinterpret_cast<TO*>(out), outFrameCount, provider);
+}
+template<typename TC, typename TI, typename TO>
+void AudioResamplerDyn<TC, TI, TO>::setResampler(unsigned resampleType)
+{
// stride 16 (falls back to stride 2 for machines that do not support NEON)
- case RESAMPLETYPE(1, true, 16, 0):
- return resample<1, true, 16>(out, outFrameCount, mConstants.mFirCoefsS16, provider);
- case RESAMPLETYPE(2, true, 16, 0):
- return resample<2, true, 16>(out, outFrameCount, mConstants.mFirCoefsS16, provider);
- case RESAMPLETYPE(1, false, 16, 0):
- return resample<1, false, 16>(out, outFrameCount, mConstants.mFirCoefsS16, provider);
- case RESAMPLETYPE(2, false, 16, 0):
- return resample<2, false, 16>(out, outFrameCount, mConstants.mFirCoefsS16, provider);
- case RESAMPLETYPE(1, true, 16, 1):
- return resample<1, true, 16>(out, outFrameCount, mConstants.mFirCoefsS32, provider);
- case RESAMPLETYPE(2, true, 16, 1):
- return resample<2, true, 16>(out, outFrameCount, mConstants.mFirCoefsS32, provider);
- case RESAMPLETYPE(1, false, 16, 1):
- return resample<1, false, 16>(out, outFrameCount, mConstants.mFirCoefsS32, provider);
- case RESAMPLETYPE(2, false, 16, 1):
- return resample<2, false, 16>(out, outFrameCount, mConstants.mFirCoefsS32, provider);
-#if 0
- // TODO: Remove these?
- // stride 8
- case RESAMPLETYPE(1, true, 8, 0):
- return resample<1, true, 8>(out, outFrameCount, mConstants.mFirCoefsS16, provider);
- case RESAMPLETYPE(2, true, 8, 0):
- return resample<2, true, 8>(out, outFrameCount, mConstants.mFirCoefsS16, provider);
- case RESAMPLETYPE(1, false, 8, 0):
- return resample<1, false, 8>(out, outFrameCount, mConstants.mFirCoefsS16, provider);
- case RESAMPLETYPE(2, false, 8, 0):
- return resample<2, false, 8>(out, outFrameCount, mConstants.mFirCoefsS16, provider);
- case RESAMPLETYPE(1, true, 8, 1):
- return resample<1, true, 8>(out, outFrameCount, mConstants.mFirCoefsS32, provider);
- case RESAMPLETYPE(2, true, 8, 1):
- return resample<2, true, 8>(out, outFrameCount, mConstants.mFirCoefsS32, provider);
- case RESAMPLETYPE(1, false, 8, 1):
- return resample<1, false, 8>(out, outFrameCount, mConstants.mFirCoefsS32, provider);
- case RESAMPLETYPE(2, false, 8, 1):
- return resample<2, false, 8>(out, outFrameCount, mConstants.mFirCoefsS32, provider);
- // stride 2 (can handle any filter length)
- case RESAMPLETYPE(1, true, 2, 0):
- return resample<1, true, 2>(out, outFrameCount, mConstants.mFirCoefsS16, provider);
- case RESAMPLETYPE(2, true, 2, 0):
- return resample<2, true, 2>(out, outFrameCount, mConstants.mFirCoefsS16, provider);
- case RESAMPLETYPE(1, false, 2, 0):
- return resample<1, false, 2>(out, outFrameCount, mConstants.mFirCoefsS16, provider);
- case RESAMPLETYPE(2, false, 2, 0):
- return resample<2, false, 2>(out, outFrameCount, mConstants.mFirCoefsS16, provider);
- case RESAMPLETYPE(1, true, 2, 1):
- return resample<1, true, 2>(out, outFrameCount, mConstants.mFirCoefsS32, provider);
- case RESAMPLETYPE(2, true, 2, 1):
- return resample<2, true, 2>(out, outFrameCount, mConstants.mFirCoefsS32, provider);
- case RESAMPLETYPE(1, false, 2, 1):
- return resample<1, false, 2>(out, outFrameCount, mConstants.mFirCoefsS32, provider);
- case RESAMPLETYPE(2, false, 2, 1):
- return resample<2, false, 2>(out, outFrameCount, mConstants.mFirCoefsS32, provider);
-#endif
+ switch (resampleType) {
+ case RESAMPLETYPE(1, true, 16):
+ mResampleFunc = &AudioResamplerDyn<TC, TI, TO>::resample<1, true, 16>;
+ return;
+ case RESAMPLETYPE(2, true, 16):
+ mResampleFunc = &AudioResamplerDyn<TC, TI, TO>::resample<2, true, 16>;
+ return;
+ case RESAMPLETYPE(1, false, 16):
+ mResampleFunc = &AudioResamplerDyn<TC, TI, TO>::resample<1, false, 16>;
+ return;
+ case RESAMPLETYPE(2, false, 16):
+ mResampleFunc = &AudioResamplerDyn<TC, TI, TO>::resample<2, false, 16>;
+ return;
default:
- ; // error
+ LOG_ALWAYS_FATAL("Invalid resampler type: %u", resampleType);
+ mResampleFunc = NULL;
+ return;
}
}
-template<int CHANNELS, bool LOCKED, int STRIDE, typename TC>
-void AudioResamplerDyn::resample(int32_t* out, size_t outFrameCount,
- const TC* const coefs, AudioBufferProvider* provider)
+template<typename TC, typename TI, typename TO>
+template<int CHANNELS, bool LOCKED, int STRIDE>
+void AudioResamplerDyn<TC, TI, TO>::resample(TO* out, size_t outFrameCount,
+ AudioBufferProvider* provider)
{
const Constants& c(mConstants);
- int16_t* impulse = mInBuffer.getImpulse();
+ const TC* const coefs = mConstants.mFirCoefs;
+ TI* impulse = mInBuffer.getImpulse();
size_t inputIndex = mInputIndex;
uint32_t phaseFraction = mPhaseFraction;
const uint32_t phaseIncrement = mPhaseIncrement;
@@ -490,8 +480,9 @@
goto resample_exit;
}
if (phaseFraction >= phaseWrapLimit) { // read in data
- mInBuffer.readAdvance<CHANNELS>(
- impulse, c.mHalfNumCoefs, mBuffer.i16, inputIndex);
+ mInBuffer.template readAdvance<CHANNELS>(
+ impulse, c.mHalfNumCoefs,
+ reinterpret_cast<TI*>(mBuffer.raw), inputIndex);
phaseFraction -= phaseWrapLimit;
while (phaseFraction >= phaseWrapLimit) {
inputIndex++;
@@ -500,20 +491,21 @@
provider->releaseBuffer(&mBuffer);
break;
}
- mInBuffer.readAdvance<CHANNELS>(
- impulse, c.mHalfNumCoefs, mBuffer.i16, inputIndex);
+ mInBuffer.template readAdvance<CHANNELS>(
+ impulse, c.mHalfNumCoefs,
+ reinterpret_cast<TI*>(mBuffer.raw), inputIndex);
phaseFraction -= phaseWrapLimit;
}
}
}
- const int16_t* const in = mBuffer.i16;
+ const TI* const in = reinterpret_cast<const TI*>(mBuffer.raw);
const size_t frameCount = mBuffer.frameCount;
const int coefShift = c.mShift;
const int halfNumCoefs = c.mHalfNumCoefs;
- const int32_t* const volumeSimd = mVolumeSimd;
+ const TO* const volumeSimd = mVolumeSimd;
// reread the last input in.
- mInBuffer.readAgain<CHANNELS>(impulse, halfNumCoefs, in, inputIndex);
+ mInBuffer.template readAgain<CHANNELS>(impulse, halfNumCoefs, in, inputIndex);
// main processing loop
while (CC_LIKELY(outputIndex < outputSampleCount)) {
@@ -536,7 +528,7 @@
if (inputIndex >= frameCount) {
goto done; // need a new buffer
}
- mInBuffer.readAdvance<CHANNELS>(impulse, halfNumCoefs, in, inputIndex);
+ mInBuffer.template readAdvance<CHANNELS>(impulse, halfNumCoefs, in, inputIndex);
phaseFraction -= phaseWrapLimit;
}
}
@@ -555,5 +547,10 @@
mPhaseFraction = phaseFraction;
}
+/* instantiate templates used by AudioResampler::create */
+template class AudioResamplerDyn<float, float, float>;
+template class AudioResamplerDyn<int16_t, int16_t, int32_t>;
+template class AudioResamplerDyn<int32_t, int16_t, int32_t>;
+
// ----------------------------------------------------------------------------
}; // namespace android
diff --git a/services/audioflinger/AudioResamplerDyn.h b/services/audioflinger/AudioResamplerDyn.h
index df1fdbe..8c56319 100644
--- a/services/audioflinger/AudioResamplerDyn.h
+++ b/services/audioflinger/AudioResamplerDyn.h
@@ -25,10 +25,24 @@
namespace android {
+/* AudioResamplerDyn
+ *
+ * This class template is used for floating point and integer resamplers.
+ *
+ * Type variables:
+ * TC = filter coefficient type (one of int16_t, int32_t, or float)
+ * TI = input data type (one of int16_t or float)
+ * TO = output data type (one of int32_t or float)
+ *
+ * For integer input data types TI, the coefficient type TC is either int16_t or int32_t.
+ * For float input data types TI, the coefficient type TC is float.
+ */
+
+template<typename TC, typename TI, typename TO>
class AudioResamplerDyn: public AudioResampler {
public:
- AudioResamplerDyn(int bitDepth, int inChannelCount, int32_t sampleRate,
- src_quality quality);
+ AudioResamplerDyn(int bitDepth, int inChannelCount,
+ int32_t sampleRate, src_quality quality);
virtual ~AudioResamplerDyn();
@@ -46,46 +60,38 @@
class Constants { // stores the filter constants.
public:
Constants() :
- mL(0), mShift(0), mHalfNumCoefs(0), mFirCoefsS16(NULL)
+ mL(0), mShift(0), mHalfNumCoefs(0), mFirCoefs(NULL)
{}
void set(int L, int halfNumCoefs,
int inSampleRate, int outSampleRate);
- inline void setBuf(int16_t* buf) {
- mFirCoefsS16 = buf;
- }
- inline void setBuf(int32_t* buf) {
- mFirCoefsS32 = buf;
- }
- int mL; // interpolation phases in the filter.
- int mShift; // right shift to get polyphase index
+ int mL; // interpolation phases in the filter.
+ int mShift; // right shift to get polyphase index
unsigned int mHalfNumCoefs; // filter half #coefs
- union { // polyphase filter bank
- const int16_t* mFirCoefsS16;
- const int32_t* mFirCoefsS32;
- };
+ const TC* mFirCoefs; // polyphase filter bank
};
- // Input buffer management for a given input type TI, now (int16_t)
- // Is agnostic of the actual type, can work with int32_t and float.
- template<typename TI>
- class InBuffer {
+ class InBuffer { // buffer management for input type TI
public:
InBuffer();
~InBuffer();
void init();
+
void resize(int CHANNELS, int halfNumCoefs);
// used for direct management of the mImpulse pointer
inline TI* getImpulse() {
return mImpulse;
}
+
inline void setImpulse(TI *impulse) {
mImpulse = impulse;
}
+
template<int CHANNELS>
inline void readAgain(TI*& impulse, const int halfNumCoefs,
const TI* const in, const size_t inputIndex);
+
template<int CHANNELS>
inline void readAdvance(TI*& impulse, const int halfNumCoefs,
const TI* const in, const size_t inputIndex);
@@ -94,31 +100,35 @@
// tuning parameter guidelines: 2 <= multiple <= 8
static const int kStateSizeMultipleOfFilterLength = 4;
- TI* mState; // base pointer for the input buffer storage
- TI* mImpulse; // current location of the impulse response (centered)
- TI* mRingFull; // mState <= mImpulse < mRingFull
// in general, mRingFull = mState + mStateSize - halfNumCoefs*CHANNELS.
- size_t mStateSize; // in units of TI.
+ TI* mState; // base pointer for the input buffer storage
+ TI* mImpulse; // current location of the impulse response (centered)
+ TI* mRingFull; // mState <= mImpulse < mRingFull
+ size_t mStateCount; // size of state in units of TI.
};
- template<int CHANNELS, bool LOCKED, int STRIDE, typename TC>
- void resample(int32_t* out, size_t outFrameCount,
- const TC* const coefs, AudioBufferProvider* provider);
-
- template<typename T>
void createKaiserFir(Constants &c, double stopBandAtten,
int inSampleRate, int outSampleRate, double tbwCheat);
- InBuffer<int16_t> mInBuffer;
- Constants mConstants; // current set of coefficient parameters
- int32_t __attribute__ ((aligned (8))) mVolumeSimd[2];
- int32_t mResampleType; // contains the resample type.
- int32_t mFilterSampleRate; // designed filter sample rate.
- src_quality mFilterQuality; // designed filter quality.
- void* mCoefBuffer; // if a filter is created, this is not null
+ void setResampler(unsigned resampleType);
+
+ template<int CHANNELS, bool LOCKED, int STRIDE>
+ void resample(TO* out, size_t outFrameCount, AudioBufferProvider* provider);
+
+ // declare a pointer to member function for resample
+ typedef void (AudioResamplerDyn<TC, TI, TO>::*resample_ABP_t)(TO* out,
+ size_t outFrameCount, AudioBufferProvider* provider);
+
+ // data - the contiguous storage and layout of these is important.
+ InBuffer mInBuffer;
+ Constants mConstants; // current set of coefficient parameters
+ TO __attribute__ ((aligned (8))) mVolumeSimd[2]; // must be aligned or NEON may crash
+ resample_ABP_t mResampleFunc; // called function for resampling
+ int32_t mFilterSampleRate; // designed filter sample rate.
+ src_quality mFilterQuality; // designed filter quality.
+ void* mCoefBuffer; // if a filter is created, this is not null
};
-// ----------------------------------------------------------------------------
}; // namespace android
#endif /*ANDROID_AUDIO_RESAMPLER_DYN_H*/
diff --git a/services/audioflinger/AudioResamplerFirGen.h b/services/audioflinger/AudioResamplerFirGen.h
index 8833758..d024b2f 100644
--- a/services/audioflinger/AudioResamplerFirGen.h
+++ b/services/audioflinger/AudioResamplerFirGen.h
@@ -365,6 +365,28 @@
}
}
+/* A speed optimized version of the Modified Bessel I0() which incorporates
+ * the sqrt and numerator multiply and denominator divide into the computation.
+ * This speeds up filter computation by about 10-15%.
+ */
+static inline double I0SqrRat(double x2, double num, double den) {
+ if (x2 < (3.75 * 3.75)) {
+ return Poly7(I0Term<0>::value, I0Term<1>::value,
+ I0Term<2>::value, I0Term<3>::value,
+ I0Term<4>::value, I0Term<5>::value,
+ I0Term<6>::value, x2) * num / den; // e < 1.6e-7
+ }
+ num *= Poly9(-0.13544938430e9, -0.33153754512e8,
+ -0.19406631946e7, -0.48058318783e5,
+ -0.63269783360e3, -0.49520779070e1,
+ -0.24970910370e-1, -0.74741159550e-4,
+ -0.18257612460e-6, x2); // e < 10^(-7.13).
+ double y = x2 - 225.; // reflection around 15 (squared)
+ den *= Poly4(-0.34598737196e8, 0.23852643181e6,
+ -0.70699387620e3, 0.10000000000e1, y);
+ return num / den;
+}
+
/*
* calculates the transition bandwidth for a Kaiser filter
*
@@ -645,6 +667,7 @@
const double xstep = (2. * M_PI) * fcr / L;
const double xfrac = 1. / N;
const double yscale = atten * L / (I0(beta) * M_PI);
+ const double sqrbeta = sqr(beta);
// We use sine generators, which computes sines on regular step intervals.
// This speeds up overall computation about 40% from computing the sine directly.
@@ -663,7 +686,8 @@
double x = static_cast<double>(ix);
// sine generator: sg.valueAdvance() returns sin(ix*xstep);
- y = I0(beta * sqrt(1.0 - sqr(x * xfrac))) * yscale * sg.valueAdvance() / x;
+ // y = I0(beta * sqrt(1.0 - sqr(x * xfrac))) * yscale * sg.valueAdvance() / x;
+ y = I0SqrRat(sqrbeta * (1.0 - sqr(x * xfrac)), yscale * sg.valueAdvance(), x);
} else {
y = 2. * atten * fcr; // center of filter, sinc(0) = 1.
sg.advance();
diff --git a/services/audioflinger/AudioResamplerFirProcess.h b/services/audioflinger/AudioResamplerFirProcess.h
index 38e387c..76d2d66 100644
--- a/services/audioflinger/AudioResamplerFirProcess.h
+++ b/services/audioflinger/AudioResamplerFirProcess.h
@@ -21,47 +21,55 @@
// depends on AudioResamplerFirOps.h
-template<int CHANNELS, typename TC>
+/* variant for input type TI = int16_t input samples */
+template<typename TC>
static inline
-void mac(
- int32_t& l, int32_t& r,
- const TC coef,
- const int16_t* samples)
+void mac(int32_t& l, int32_t& r, TC coef, const int16_t* samples)
{
- if (CHANNELS == 2) {
- uint32_t rl = *reinterpret_cast<const uint32_t*>(samples);
- l = mulAddRL(1, rl, coef, l);
- r = mulAddRL(0, rl, coef, r);
- } else {
- r = l = mulAdd(samples[0], coef, l);
- }
+ uint32_t rl = *reinterpret_cast<const uint32_t*>(samples);
+ l = mulAddRL(1, rl, coef, l);
+ r = mulAddRL(0, rl, coef, r);
}
-template<int CHANNELS, typename TC>
+template<typename TC>
static inline
-void interpolate(
- int32_t& l, int32_t& r,
- const TC coef_0, const TC coef_1,
- const int16_t lerp, const int16_t* samples)
+void mac(int32_t& l, TC coef, const int16_t* samples)
{
- TC sinc;
+ l = mulAdd(samples[0], coef, l);
+}
- if (is_same<TC, int16_t>::value) {
- sinc = (lerp * ((coef_1-coef_0)<<1)>>16) + coef_0;
- } else {
- sinc = mulAdd(lerp, (coef_1-coef_0)<<1, coef_0);
- }
- if (CHANNELS == 2) {
- uint32_t rl = *reinterpret_cast<const uint32_t*>(samples);
- l = mulAddRL(1, rl, sinc, l);
- r = mulAddRL(0, rl, sinc, r);
- } else {
- r = l = mulAdd(samples[0], sinc, l);
- }
+/* variant for input type TI = float input samples */
+template<typename TC>
+static inline
+void mac(float& l, float& r, TC coef, const float* samples)
+{
+ l += *samples++ * coef;
+ r += *samples++ * coef;
+}
+
+template<typename TC>
+static inline
+void mac(float& l, TC coef, const float* samples)
+{
+ l += *samples++ * coef;
+}
+
+/* variant for output type TO = int32_t output samples */
+static inline
+int32_t volumeAdjust(int32_t value, int32_t volume)
+{
+ return 2 * mulRL(0, value, volume); // Note: only use top 16b
+}
+
+/* variant for output type TO = float output samples */
+static inline
+float volumeAdjust(float value, float volume)
+{
+ return value * volume;
}
/*
- * Calculates a single output sample (two stereo frames).
+ * Calculates a single output frame (two samples).
*
* This function computes both the positive half FIR dot product and
* the negative half FIR dot product, accumulates, and then applies the volume.
@@ -72,30 +80,43 @@
* filter bank.
*/
-template <int CHANNELS, int STRIDE, typename TC>
+template <int CHANNELS, int STRIDE, typename TC, typename TI, typename TO>
static inline
-void ProcessL(int32_t* const out,
+void ProcessL(TO* const out,
int count,
const TC* coefsP,
const TC* coefsN,
- const int16_t* sP,
- const int16_t* sN,
- const int32_t* const volumeLR)
+ const TI* sP,
+ const TI* sN,
+ const TO* const volumeLR)
{
- int32_t l = 0;
- int32_t r = 0;
- do {
- mac<CHANNELS>(l, r, *coefsP++, sP);
- sP -= CHANNELS;
- mac<CHANNELS>(l, r, *coefsN++, sN);
- sN += CHANNELS;
- } while (--count > 0);
- out[0] += 2 * mulRL(0, l, volumeLR[0]); // Note: only use top 16b
- out[1] += 2 * mulRL(0, r, volumeLR[1]); // Note: only use top 16b
+ COMPILE_TIME_ASSERT_FUNCTION_SCOPE(CHANNELS >= 1 && CHANNELS <= 2)
+ if (CHANNELS == 2) {
+ TO l = 0;
+ TO r = 0;
+ do {
+ mac(l, r, *coefsP++, sP);
+ sP -= CHANNELS;
+ mac(l, r, *coefsN++, sN);
+ sN += CHANNELS;
+ } while (--count > 0);
+ out[0] += volumeAdjust(l, volumeLR[0]);
+ out[1] += volumeAdjust(r, volumeLR[1]);
+ } else { /* CHANNELS == 1 */
+ TO l = 0;
+ do {
+ mac(l, *coefsP++, sP);
+ sP -= CHANNELS;
+ mac(l, *coefsN++, sN);
+ sN += CHANNELS;
+ } while (--count > 0);
+ out[0] += volumeAdjust(l, volumeLR[0]);
+ out[1] += volumeAdjust(l, volumeLR[1]);
+ }
}
/*
- * Calculates a single output sample (two stereo frames) interpolating phase.
+ * Calculates a single output frame (two samples) interpolating phase.
*
* This function computes both the positive half FIR dot product and
* the negative half FIR dot product, accumulates, and then applies the volume.
@@ -106,47 +127,91 @@
* filter bank.
*/
-template <int CHANNELS, int STRIDE, typename TC>
+template<typename TC, typename T>
+void adjustLerp(T& lerpP __unused)
+{
+}
+
+template<int32_t, typename T>
+void adjustLerp(T& lerpP)
+{
+ lerpP >>= 16; // lerpP is 32bit for NEON int32_t, but always 16 bit for non-NEON path
+}
+
+template<typename TC, typename TINTERP>
static inline
-void Process(int32_t* const out,
+TC interpolate(TC coef_0, TC coef_1, TINTERP lerp)
+{
+ return lerp * (coef_1 - coef_0) + coef_0;
+}
+
+template<int16_t, uint32_t>
+static inline
+int16_t interpolate(int16_t coef_0, int16_t coef_1, uint32_t lerp)
+{
+ return (static_cast<int16_t>(lerp) * ((coef_1-coef_0)<<1)>>16) + coef_0;
+}
+
+template<int32_t, uint32_t>
+static inline
+int32_t interpolate(int32_t coef_0, int32_t coef_1, uint32_t lerp)
+{
+ return mulAdd(static_cast<int16_t>(lerp), (coef_1-coef_0)<<1, coef_0);
+}
+
+template <int CHANNELS, int STRIDE, typename TC, typename TI, typename TO, typename TINTERP>
+static inline
+void Process(TO* const out,
int count,
const TC* coefsP,
const TC* coefsN,
- const TC* coefsP1,
- const TC* coefsN1,
- const int16_t* sP,
- const int16_t* sN,
- uint32_t lerpP,
- const int32_t* const volumeLR)
+ const TC* coefsP1 __unused,
+ const TC* coefsN1 __unused,
+ const TI* sP,
+ const TI* sN,
+ TINTERP lerpP,
+ const TO* const volumeLR)
{
- (void) coefsP1; // suppress unused parameter warning
- (void) coefsN1;
- if (sizeof(*coefsP)==4) {
- lerpP >>= 16; // ensure lerpP is 16b
+ COMPILE_TIME_ASSERT_FUNCTION_SCOPE(CHANNELS >= 1 && CHANNELS <= 2)
+ adjustLerp<TC, TINTERP>(lerpP); // coefficient type adjustment for interpolation
+
+ if (CHANNELS == 2) {
+ TO l = 0;
+ TO r = 0;
+ for (size_t i = 0; i < count; ++i) {
+ mac(l, r, interpolate(coefsP[0], coefsP[count], lerpP), sP);
+ coefsP++;
+ sP -= CHANNELS;
+ mac(l, r, interpolate(coefsN[count], coefsN[0], lerpP), sN);
+ coefsN++;
+ sN += CHANNELS;
+ }
+ out[0] += volumeAdjust(l, volumeLR[0]);
+ out[1] += volumeAdjust(r, volumeLR[1]);
+ } else { /* CHANNELS == 1 */
+ TO l = 0;
+ for (size_t i = 0; i < count; ++i) {
+ mac(l, interpolate(coefsP[0], coefsP[count], lerpP), sP);
+ coefsP++;
+ sP -= CHANNELS;
+ mac(l, interpolate(coefsN[count], coefsN[0], lerpP), sN);
+ coefsN++;
+ sN += CHANNELS;
+ }
+ out[0] += volumeAdjust(l, volumeLR[0]);
+ out[1] += volumeAdjust(l, volumeLR[1]);
}
- int32_t l = 0;
- int32_t r = 0;
- for (size_t i = 0; i < count; ++i) {
- interpolate<CHANNELS>(l, r, coefsP[0], coefsP[count], lerpP, sP);
- coefsP++;
- sP -= CHANNELS;
- interpolate<CHANNELS>(l, r, coefsN[count], coefsN[0], lerpP, sN);
- coefsN++;
- sN += CHANNELS;
- }
- out[0] += 2 * mulRL(0, l, volumeLR[0]); // Note: only use top 16b
- out[1] += 2 * mulRL(0, r, volumeLR[1]); // Note: only use top 16b
}
/*
- * Calculates a single output sample (two stereo frames) from input sample pointer.
+ * Calculates a single output frame (two samples) from input sample pointer.
*
* This sets up the params for the accelerated Process() and ProcessL()
* functions to do the appropriate dot products.
*
- * @param out should point to the output buffer with at least enough space for 2 output frames.
+ * @param out should point to the output buffer with space for at least one output frame.
*
- * @param phase is the fractional distance between input samples for interpolation:
+ * @param phase is the fractional distance between input frames for interpolation:
* phase >= 0 && phase < phaseWrapLimit. It can be thought of as a rational fraction
* of phase/phaseWrapLimit.
*
@@ -195,14 +260,17 @@
* lerpP = phase << sizeof(phase)*8 - coefShift
* >> (sizeof(phase)-sizeof(*coefs))*8 + 1;
*
+ * For floating point, lerpP is the fractional phase scaled to [0.0, 1.0):
+ *
+ * lerpP = (phase << 32 - coefShift) / (1 << 32); // floating point equivalent
*/
-template<int CHANNELS, bool LOCKED, int STRIDE, typename TC>
+template<int CHANNELS, bool LOCKED, int STRIDE, typename TC, typename TI, typename TO>
static inline
-void fir(int32_t* const out,
+void fir(TO* const out,
const uint32_t phase, const uint32_t phaseWrapLimit,
const int coefShift, const int halfNumCoefs, const TC* const coefs,
- const int16_t* const samples, const int32_t* const volumeLR)
+ const TI* const samples, const TO* const volumeLR)
{
// NOTE: be very careful when modifying the code here. register
// pressure is very high and a small change might cause the compiler
@@ -216,8 +284,8 @@
uint32_t indexN = (phaseWrapLimit - phase) >> coefShift;
const TC* coefsP = coefs + indexP*halfNumCoefs;
const TC* coefsN = coefs + indexN*halfNumCoefs;
- const int16_t* sP = samples;
- const int16_t* sN = samples + CHANNELS;
+ const TI* sP = samples;
+ const TI* sN = samples + CHANNELS;
// dot product filter.
ProcessL<CHANNELS, STRIDE>(out,
@@ -231,8 +299,8 @@
const TC* coefsN = coefs + indexN*halfNumCoefs;
const TC* coefsP1 = coefsP + halfNumCoefs;
const TC* coefsN1 = coefsN + halfNumCoefs;
- const int16_t* sP = samples;
- const int16_t* sN = samples + CHANNELS;
+ const TI* sP = samples;
+ const TI* sN = samples + CHANNELS;
// Interpolation fraction lerpP derived by shifting all the way up and down
// to clear the appropriate bits and align to the appropriate level
@@ -242,12 +310,21 @@
//
// interpolated[P] = index[P]*lerpP + index[P+1]*(1-lerpP)
// interpolated[N] = index[N+1]*lerpP + index[N]*(1-lerpP)
- uint32_t lerpP = phase << (sizeof(phase)*8 - coefShift)
- >> ((sizeof(phase)-sizeof(*coefs))*8 + 1);
// on-the-fly interpolated dot product filter
- Process<CHANNELS, STRIDE>(out,
- halfNumCoefs, coefsP, coefsN, coefsP1, coefsN1, sP, sN, lerpP, volumeLR);
+ if (is_same<TC, float>::value || is_same<TC, double>::value) {
+ static const TC scale = 1. / (65536. * 65536.); // scale phase bits to [0.0, 1.0)
+ TC lerpP = TC(phase << (sizeof(phase)*8 - coefShift)) * scale;
+
+ Process<CHANNELS, STRIDE>(out,
+ halfNumCoefs, coefsP, coefsN, coefsP1, coefsN1, sP, sN, lerpP, volumeLR);
+ } else {
+ uint32_t lerpP = phase << (sizeof(phase)*8 - coefShift)
+ >> ((sizeof(phase)-sizeof(*coefs))*8 + 1);
+
+ Process<CHANNELS, STRIDE>(out,
+ halfNumCoefs, coefsP, coefsN, coefsP1, coefsN1, sP, sN, lerpP, volumeLR);
+ }
}
}
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index feedd89..ae3dd8b 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -3951,6 +3951,16 @@
AudioParameter param = AudioParameter(keyValuePair);
int value;
+ if (param.getInt(String8(AudioParameter::keyRouting), value) == NO_ERROR) {
+ // forward device change to effects that have requested to be
+ // aware of attached audio device.
+ if (value != AUDIO_DEVICE_NONE) {
+ mOutDevice = value;
+ for (size_t i = 0; i < mEffectChains.size(); i++) {
+ mEffectChains[i]->setDevice_l(mOutDevice);
+ }
+ }
+ }
if (param.getInt(String8(AudioParameter::keyFrameCount), value) == NO_ERROR) {
// do not accept frame count changes if tracks are open as the track buffer
// size depends on frame count and correct behavior would not be garantied
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 2cf10e2..1064fd1 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -930,7 +930,7 @@
void AudioFlinger::PlaybackThread::Track::triggerEvents(AudioSystem::sync_event_t type)
{
- for (int i = 0; i < (int)mSyncEvents.size(); i++) {
+ for (size_t i = 0; i < mSyncEvents.size(); i++) {
if (mSyncEvents[i]->type() == type) {
mSyncEvents[i]->trigger();
mSyncEvents.removeAt(i);
diff --git a/services/audioflinger/test-resample.cpp b/services/audioflinger/test-resample.cpp
index d1de95d..e14b4ae 100644
--- a/services/audioflinger/test-resample.cpp
+++ b/services/audioflinger/test-resample.cpp
@@ -36,16 +36,16 @@
static bool gVerbose = false;
static int usage(const char* name) {
- fprintf(stderr,"Usage: %s [-p] [-f] [-F] [-h] [-v] [-s] [-q {dq|lq|mq|hq|vhq|dlq|dmq|dhq}]"
+ fprintf(stderr,"Usage: %s [-p] [-f] [-F] [-v] [-c channels]"
+ " [-q {dq|lq|mq|hq|vhq|dlq|dmq|dhq}]"
" [-i input-sample-rate] [-o output-sample-rate]"
" [-O csv] [-P csv] [<input-file>]"
" <output-file>\n", name);
fprintf(stderr," -p enable profiling\n");
fprintf(stderr," -f enable filter profiling\n");
fprintf(stderr," -F enable floating point -q {dlq|dmq|dhq} only");
- fprintf(stderr," -h create wav file\n");
fprintf(stderr," -v verbose : log buffer provider calls\n");
- fprintf(stderr," -s stereo (ignored if input file is specified)\n");
+ fprintf(stderr," -c # channels (1-2 for lq|mq|hq; 1-8 for dlq|dmq|dhq)\n");
fprintf(stderr," -q resampler quality\n");
fprintf(stderr," dq : default quality\n");
fprintf(stderr," lq : low quality\n");
@@ -102,11 +102,9 @@
}
int main(int argc, char* argv[]) {
-
const char* const progname = argv[0];
bool profileResample = false;
bool profileFilter = false;
- bool writeHeader = false;
bool useFloat = false;
int channels = 1;
int input_freq = 0;
@@ -116,7 +114,7 @@
Vector<int> Pvalues;
int ch;
- while ((ch = getopt(argc, argv, "pfFhvsq:i:o:O:P:")) != -1) {
+ while ((ch = getopt(argc, argv, "pfFvc:q:i:o:O:P:")) != -1) {
switch (ch) {
case 'p':
profileResample = true;
@@ -127,14 +125,11 @@
case 'F':
useFloat = true;
break;
- case 'h':
- writeHeader = true;
- break;
case 'v':
gVerbose = true;
break;
- case 's':
- channels = 2;
+ case 'c':
+ channels = atoi(optarg);
break;
case 'q':
if (!strcmp(optarg, "dq"))
@@ -183,6 +178,11 @@
}
}
+ if (channels < 1
+ || channels > (quality < AudioResampler::DYN_LOW_QUALITY ? 2 : 8)) {
+ fprintf(stderr, "invalid number of audio channels %d\n", channels);
+ return -1;
+ }
if (useFloat && quality < AudioResampler::DYN_LOW_QUALITY) {
fprintf(stderr, "float processing is only possible for dynamic resamplers\n");
return -1;
@@ -234,20 +234,20 @@
double t = double(i) / input_freq;
double y = sin(M_PI * k * t * t);
int16_t yi = floor(y * 32767.0 + 0.5);
- for (size_t j=0 ; j<(size_t)channels ; j++) {
- in[i*channels + j] = yi / (1+j); // right ch. 1/2 left ch.
+ for (int j = 0; j < channels; j++) {
+ in[i*channels + j] = yi / (1 + j);
}
}
}
- size_t frame_size = channels * sizeof(int16_t);
- size_t input_frames = input_size / frame_size;
+ size_t input_framesize = channels * sizeof(int16_t);
+ size_t input_frames = input_size / input_framesize;
// For float processing, convert input int16_t to float array
if (useFloat) {
void *new_vaddr;
- frame_size = channels * sizeof(float);
- input_size = input_frames * frame_size;
+ input_framesize = channels * sizeof(float);
+ input_size = input_frames * input_framesize;
new_vaddr = malloc(input_size);
memcpy_to_float_from_i16(reinterpret_cast<float*>(new_vaddr),
reinterpret_cast<int16_t*>(input_vaddr), input_frames * channels);
@@ -323,15 +323,17 @@
void reset() {
mNextFrame = 0;
}
- } provider(input_vaddr, input_frames, frame_size, Pvalues);
+ } provider(input_vaddr, input_frames, input_framesize, Pvalues);
if (gVerbose) {
printf("%zu input frames\n", input_frames);
}
int bit_depth = useFloat ? 32 : 16;
- size_t output_size = 2 * 4 * ((int64_t) input_frames * output_freq) / input_freq;
- output_size &= ~7; // always stereo, 32-bits
+ int output_channels = channels > 2 ? channels : 2; // output is at least stereo samples
+ size_t output_framesize = output_channels * (useFloat ? sizeof(float) : sizeof(int32_t));
+ size_t output_frames = ((int64_t) input_frames * output_freq) / input_freq;
+ size_t output_size = output_frames * output_framesize;
if (profileFilter) {
// Check how fast sample rate changes are that require filter changes.
@@ -380,7 +382,7 @@
void* output_vaddr = malloc(output_size);
AudioResampler* resampler = AudioResampler::create(bit_depth, channels,
output_freq, quality);
- size_t out_frames = output_size/8;
+
/* set volume precision to 12 bits, so the volume scale is 1<<12.
* The output int32_t is represented as Q4.27, with 4 bits of guard
@@ -422,7 +424,7 @@
for (int n = 0; n < trials; ++n) {
clock_gettime(CLOCK_MONOTONIC, &start);
for (int i = 0; i < looplimit; ++i) {
- resampler->resample((int*) output_vaddr, out_frames, &provider);
+ resampler->resample((int*) output_vaddr, output_frames, &provider);
provider.reset(); // during benchmarking reset only the provider
}
clock_gettime(CLOCK_MONOTONIC, &end);
@@ -435,26 +437,26 @@
}
// Mfrms/s is "Millions of output frames per second".
printf("quality: %d channels: %d msec: %" PRId64 " Mfrms/s: %.2lf\n",
- quality, channels, time/1000000, out_frames * looplimit / (time / 1e9) / 1e6);
+ quality, channels, time/1000000, output_frames * looplimit / (time / 1e9) / 1e6);
resampler->reset();
}
memset(output_vaddr, 0, output_size);
if (gVerbose) {
- printf("resample() %zu output frames\n", out_frames);
+ printf("resample() %zu output frames\n", output_frames);
}
if (Ovalues.isEmpty()) {
- Ovalues.push(out_frames);
+ Ovalues.push(output_frames);
}
- for (size_t i = 0, j = 0; i < out_frames; ) {
+ for (size_t i = 0, j = 0; i < output_frames; ) {
size_t thisFrames = Ovalues[j++];
if (j >= Ovalues.size()) {
j = 0;
}
- if (thisFrames == 0 || thisFrames > out_frames - i) {
- thisFrames = out_frames - i;
+ if (thisFrames == 0 || thisFrames > output_frames - i) {
+ thisFrames = output_frames - i;
}
- resampler->resample((int*) output_vaddr + 2*i, thisFrames, &provider);
+ resampler->resample((int*) output_vaddr + output_channels*i, thisFrames, &provider);
i += thisFrames;
}
if (gVerbose) {
@@ -471,20 +473,20 @@
// which is then converted to int16_t for final storage.
if (useFloat) {
memcpy_to_q4_27_from_float(reinterpret_cast<int32_t*>(output_vaddr),
- reinterpret_cast<float*>(output_vaddr), out_frames * 2); // stereo samples
+ reinterpret_cast<float*>(output_vaddr), output_frames * output_channels);
}
- // mono takes left channel only
- // stereo right channel is half amplitude of stereo left channel (due to input creation)
+ // mono takes left channel only (out of stereo output pair)
+ // stereo and multichannel preserve all channels.
int32_t* out = (int32_t*) output_vaddr;
- int16_t* convert = (int16_t*) malloc(out_frames * channels * sizeof(int16_t));
+ int16_t* convert = (int16_t*) malloc(output_frames * channels * sizeof(int16_t));
// round to half towards zero and saturate at int16 (non-dithered)
const int roundVal = (1<<(volumePrecision-1)) - 1; // volumePrecision > 0
- for (size_t i = 0; i < out_frames; i++) {
+ for (size_t i = 0; i < output_frames; i++) {
for (int j = 0; j < channels; j++) {
- int32_t s = out[i * 2 + j] + roundVal; // add offset here
+ int32_t s = out[i * output_channels + j] + roundVal; // add offset here
if (s < 0) {
s = (s + 1) >> volumePrecision; // round to 0
if (s < -32768) {
@@ -501,29 +503,18 @@
}
// write output to disk
- if (writeHeader) {
- SF_INFO info;
- info.frames = 0;
- info.samplerate = output_freq;
- info.channels = channels;
- info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
- SNDFILE *sf = sf_open(file_out, SFM_WRITE, &info);
- if (sf == NULL) {
- perror(file_out);
- return EXIT_FAILURE;
- }
- (void) sf_writef_short(sf, convert, out_frames);
- sf_close(sf);
- } else {
- int output_fd = open(file_out, O_WRONLY | O_CREAT | O_TRUNC,
- S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
- if (output_fd < 0) {
- perror(file_out);
- return EXIT_FAILURE;
- }
- write(output_fd, convert, out_frames * channels * sizeof(int16_t));
- close(output_fd);
+ SF_INFO info;
+ info.frames = 0;
+ info.samplerate = output_freq;
+ info.channels = channels;
+ info.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
+ SNDFILE *sf = sf_open(file_out, SFM_WRITE, &info);
+ if (sf == NULL) {
+ perror(file_out);
+ return EXIT_FAILURE;
}
+ (void) sf_writef_short(sf, convert, output_frames);
+ sf_close(sf);
return EXIT_SUCCESS;
}
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 5c6f653..02bca1f 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1116,7 +1116,8 @@
// Reset the client PID to allow server-initiated disconnect,
// and to prevent further calls by client.
mClientPid = getCallingPid();
- notifyError();
+ CaptureResultExtras resultExtras; // a dummy result (invalid)
+ notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE, resultExtras);
disconnect();
}
}
@@ -1145,7 +1146,8 @@
return client;
}
-void CameraService::Client::notifyError() {
+void CameraService::Client::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
+ const CaptureResultExtras& resultExtras) {
mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
}
@@ -1199,7 +1201,8 @@
CameraService::ProClient::~ProClient() {
}
-void CameraService::ProClient::notifyError() {
+void CameraService::ProClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
+ const CaptureResultExtras& resultExtras) {
mRemoteCallback->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0);
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 8853e48..76ea7be 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -31,6 +31,7 @@
#include <camera/camera2/ICameraDeviceUser.h>
#include <camera/camera2/ICameraDeviceCallbacks.h>
#include <camera/VendorTagDescriptor.h>
+#include <camera/CaptureResult.h>
#include <camera/ICameraServiceListener.h>
@@ -182,7 +183,9 @@
status_t finishCameraOps();
// Notify client about a fatal error
- virtual void notifyError() = 0;
+ virtual void notifyError(
+ ICameraDeviceCallbacks::CameraErrorCode errorCode,
+ const CaptureResultExtras& resultExtras) = 0;
private:
AppOpsManager mAppOpsManager;
@@ -259,7 +262,8 @@
// convert client from cookie. Client lock should be acquired before getting Client.
static Client* getClientFromCookie(void* user);
- virtual void notifyError();
+ virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
+ const CaptureResultExtras& resultExtras);
// Initialized in constructor
@@ -307,7 +311,8 @@
virtual void onExclusiveLockStolen() = 0;
protected:
- virtual void notifyError();
+ virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
+ const CaptureResultExtras& resultExtras);
sp<IProCameraCallbacks> mRemoteCallback;
}; // class ProClient
diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
index f5c28ed..8268f65 100644
--- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
@@ -106,13 +106,12 @@
}
}
-void CaptureSequencer::onFrameAvailable(int32_t requestId,
- const CameraMetadata &frame) {
- ALOGV("%s: Listener found new frame", __FUNCTION__);
+void CaptureSequencer::onResultAvailable(const CaptureResult &result) {
ATRACE_CALL();
+ ALOGV("%s: New result available.", __FUNCTION__);
Mutex::Autolock l(mInputMutex);
- mNewFrameId = requestId;
- mNewFrame = frame;
+ mNewFrameId = result.mResultExtras.requestId;
+ mNewFrame = result.mMetadata;
if (!mNewFrameReceived) {
mNewFrameReceived = true;
mNewFrameSignal.signal();
@@ -585,12 +584,15 @@
entry = mNewFrame.find(ANDROID_SENSOR_TIMESTAMP);
if (entry.count == 0) {
ALOGE("No timestamp field in capture frame!");
- }
- if (entry.data.i64[0] != mCaptureTimestamp) {
- ALOGW("Mismatched capture timestamps: Metadata frame %" PRId64 ","
- " captured buffer %" PRId64,
- entry.data.i64[0],
- mCaptureTimestamp);
+ } else if (entry.count == 1) {
+ if (entry.data.i64[0] != mCaptureTimestamp) {
+ ALOGW("Mismatched capture timestamps: Metadata frame %" PRId64 ","
+ " captured buffer %" PRId64,
+ entry.data.i64[0],
+ mCaptureTimestamp);
+ }
+ } else {
+ ALOGE("Timestamp metadata is malformed!");
}
client->removeFrameListener(mCaptureId, mCaptureId + 1, this);
diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.h b/services/camera/libcameraservice/api1/client2/CaptureSequencer.h
index 9fb4ee7..d42ab13 100644
--- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.h
+++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.h
@@ -24,6 +24,7 @@
#include <utils/Mutex.h>
#include <utils/Condition.h>
#include "camera/CameraMetadata.h"
+#include "camera/CaptureResult.h"
#include "Parameters.h"
#include "FrameProcessor.h"
@@ -61,8 +62,8 @@
// Notifications about AE state changes
void notifyAutoExposure(uint8_t newState, int triggerId);
- // Notifications from the frame processor
- virtual void onFrameAvailable(int32_t requestId, const CameraMetadata &frame);
+ // Notification from the frame processor
+ virtual void onResultAvailable(const CaptureResult &result);
// Notifications from the JPEG processor
void onCaptureAvailable(nsecs_t timestamp, sp<MemoryBase> captureBuffer);
diff --git a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp
index dd5b27c..69bea24 100644
--- a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp
@@ -55,7 +55,7 @@
FrameProcessor::~FrameProcessor() {
}
-bool FrameProcessor::processSingleFrame(CameraMetadata &frame,
+bool FrameProcessor::processSingleFrame(CaptureResult &frame,
const sp<CameraDeviceBase> &device) {
sp<Camera2Client> client = mClient.promote();
@@ -66,19 +66,19 @@
bool partialResult = false;
if (mUsePartialQuirk) {
camera_metadata_entry_t entry;
- entry = frame.find(ANDROID_QUIRKS_PARTIAL_RESULT);
+ entry = frame.mMetadata.find(ANDROID_QUIRKS_PARTIAL_RESULT);
if (entry.count > 0 &&
entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) {
partialResult = true;
}
}
- if (!partialResult && processFaceDetect(frame, client) != OK) {
+ if (!partialResult && processFaceDetect(frame.mMetadata, client) != OK) {
return false;
}
if (mSynthesize3ANotify) {
- process3aState(frame, client);
+ process3aState(frame.mMetadata, client);
}
return FrameProcessorBase::processSingleFrame(frame, device);
diff --git a/services/camera/libcameraservice/api1/client2/FrameProcessor.h b/services/camera/libcameraservice/api1/client2/FrameProcessor.h
index 856ad32..514bd1a 100644
--- a/services/camera/libcameraservice/api1/client2/FrameProcessor.h
+++ b/services/camera/libcameraservice/api1/client2/FrameProcessor.h
@@ -51,7 +51,7 @@
void processNewFrames(const sp<Camera2Client> &client);
- virtual bool processSingleFrame(CameraMetadata &frame,
+ virtual bool processSingleFrame(CaptureResult &frame,
const sp<CameraDeviceBase> &device);
status_t processFaceDetect(const CameraMetadata &frame,
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
index 6ab9e1a..2a2a5af 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
@@ -73,18 +73,19 @@
}
}
-void ZslProcessor::onFrameAvailable(int32_t /*requestId*/,
- const CameraMetadata &frame) {
+void ZslProcessor::onResultAvailable(const CaptureResult &result) {
+ ATRACE_CALL();
+ ALOGV("%s:", __FUNCTION__);
Mutex::Autolock l(mInputMutex);
camera_metadata_ro_entry_t entry;
- entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
+ entry = result.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
nsecs_t timestamp = entry.data.i64[0];
(void)timestamp;
ALOGVV("Got preview frame for timestamp %" PRId64, timestamp);
if (mState != RUNNING) return;
- mFrameList.editItemAt(mFrameListHead) = frame;
+ mFrameList.editItemAt(mFrameListHead) = result.mMetadata;
mFrameListHead = (mFrameListHead + 1) % kFrameListDepth;
findMatchesLocked();
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.h b/services/camera/libcameraservice/api1/client2/ZslProcessor.h
index 6d3cb85..f4cf0c8 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor.h
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.h
@@ -24,6 +24,7 @@
#include <utils/Condition.h>
#include <gui/BufferItemConsumer.h>
#include <camera/CameraMetadata.h>
+#include <camera/CaptureResult.h>
#include "common/CameraDeviceBase.h"
#include "api1/client2/ZslProcessorInterface.h"
@@ -54,7 +55,7 @@
// From mZslConsumer
virtual void onFrameAvailable();
// From FrameProcessor
- virtual void onFrameAvailable(int32_t requestId, const CameraMetadata &frame);
+ virtual void onResultAvailable(const CaptureResult &result);
virtual void onBufferReleased(buffer_handle_t *handle);
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
index 3949b90..1dcb718 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
@@ -63,18 +63,19 @@
deleteStream();
}
-void ZslProcessor3::onFrameAvailable(int32_t /*requestId*/,
- const CameraMetadata &frame) {
+void ZslProcessor3::onResultAvailable(const CaptureResult &result) {
+ ATRACE_CALL();
+ ALOGV("%s:", __FUNCTION__);
Mutex::Autolock l(mInputMutex);
camera_metadata_ro_entry_t entry;
- entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
+ entry = result.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
nsecs_t timestamp = entry.data.i64[0];
(void)timestamp;
ALOGVV("Got preview metadata for timestamp %" PRId64, timestamp);
if (mState != RUNNING) return;
- mFrameList.editItemAt(mFrameListHead) = frame;
+ mFrameList.editItemAt(mFrameListHead) = result.mMetadata;
mFrameListHead = (mFrameListHead + 1) % kFrameListDepth;
}
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor3.h b/services/camera/libcameraservice/api1/client2/ZslProcessor3.h
index d2f8322..4c52a64 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor3.h
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor3.h
@@ -50,8 +50,8 @@
ZslProcessor3(sp<Camera2Client> client, wp<CaptureSequencer> sequencer);
~ZslProcessor3();
- // From FrameProcessor
- virtual void onFrameAvailable(int32_t requestId, const CameraMetadata &frame);
+ // From FrameProcessor::FilteredListener
+ virtual void onResultAvailable(const CaptureResult &result);
/**
****************************************
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 1c9a342..3d85e90 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -16,7 +16,7 @@
#define LOG_TAG "CameraDeviceClient"
#define ATRACE_TAG ATRACE_TAG_CAMERA
-// #define LOG_NDEBUG 0
+//#define LOG_NDEBUG 0
#include <cutils/properties.h>
#include <utils/Log.h>
@@ -91,105 +91,18 @@
}
status_t CameraDeviceClient::submitRequest(sp<CaptureRequest> request,
- bool streaming) {
- ATRACE_CALL();
- ALOGV("%s", __FUNCTION__);
-
- status_t res;
-
- if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
-
- Mutex::Autolock icl(mBinderSerializationLock);
-
- if (!mDevice.get()) return DEAD_OBJECT;
-
- if (request == 0) {
- ALOGE("%s: Camera %d: Sent null request. Rejecting request.",
- __FUNCTION__, mCameraId);
- return BAD_VALUE;
- }
-
- CameraMetadata metadata(request->mMetadata);
-
- if (metadata.isEmpty()) {
- ALOGE("%s: Camera %d: Sent empty metadata packet. Rejecting request.",
- __FUNCTION__, mCameraId);
- return BAD_VALUE;
- } else if (request->mSurfaceList.size() == 0) {
- ALOGE("%s: Camera %d: Requests must have at least one surface target. "
- "Rejecting request.", __FUNCTION__, mCameraId);
- return BAD_VALUE;
- }
-
- if (!enforceRequestPermissions(metadata)) {
- // Callee logs
- return PERMISSION_DENIED;
- }
-
- /**
- * Write in the output stream IDs which we calculate from
- * the capture request's list of surface targets
- */
- Vector<int32_t> outputStreamIds;
- outputStreamIds.setCapacity(request->mSurfaceList.size());
- for (size_t i = 0; i < request->mSurfaceList.size(); ++i) {
- sp<Surface> surface = request->mSurfaceList[i];
-
- if (surface == 0) continue;
-
- sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
- int idx = mStreamMap.indexOfKey(gbp->asBinder());
-
- // Trying to submit request with surface that wasn't created
- if (idx == NAME_NOT_FOUND) {
- ALOGE("%s: Camera %d: Tried to submit a request with a surface that"
- " we have not called createStream on",
- __FUNCTION__, mCameraId);
- return BAD_VALUE;
- }
-
- int streamId = mStreamMap.valueAt(idx);
- outputStreamIds.push_back(streamId);
- ALOGV("%s: Camera %d: Appending output stream %d to request",
- __FUNCTION__, mCameraId, streamId);
- }
-
- metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS, &outputStreamIds[0],
- outputStreamIds.size());
-
- int32_t requestId = mRequestIdCounter++;
- metadata.update(ANDROID_REQUEST_ID, &requestId, /*size*/1);
- ALOGV("%s: Camera %d: Creating request with ID %d",
- __FUNCTION__, mCameraId, requestId);
-
- if (streaming) {
- res = mDevice->setStreamingRequest(metadata);
- if (res != OK) {
- ALOGE("%s: Camera %d: Got error %d after trying to set streaming "
- "request", __FUNCTION__, mCameraId, res);
- } else {
- mStreamingRequestList.push_back(requestId);
- }
- } else {
- res = mDevice->capture(metadata);
- if (res != OK) {
- ALOGE("%s: Camera %d: Got error %d after trying to set capture",
- __FUNCTION__, mCameraId, res);
- }
- }
-
- ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
- if (res == OK) {
- return requestId;
- }
-
- return res;
+ bool streaming,
+ /*out*/
+ int64_t* lastFrameNumber) {
+ List<sp<CaptureRequest> > requestList;
+ requestList.push_back(request);
+ return submitRequestList(requestList, streaming, lastFrameNumber);
}
status_t CameraDeviceClient::submitRequestList(List<sp<CaptureRequest> > requests,
- bool streaming) {
+ bool streaming, int64_t* lastFrameNumber) {
ATRACE_CALL();
- ALOGV("%s-start of function", __FUNCTION__);
+ ALOGV("%s-start of function. Request list size %d", __FUNCTION__, requests.size());
status_t res;
if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
@@ -238,9 +151,8 @@
*/
Vector<int32_t> outputStreamIds;
outputStreamIds.setCapacity(request->mSurfaceList.size());
- for (Vector<sp<Surface> >::iterator surfaceIt = 0;
- surfaceIt != request->mSurfaceList.end(); ++surfaceIt) {
- sp<Surface> surface = *surfaceIt;
+ for (size_t i = 0; i < request->mSurfaceList.size(); ++i) {
+ sp<Surface> surface = request->mSurfaceList[i];
if (surface == 0) continue;
sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
@@ -273,7 +185,7 @@
mRequestIdCounter++;
if (streaming) {
- res = mDevice->setStreamingRequestList(metadataRequestList);
+ res = mDevice->setStreamingRequestList(metadataRequestList, lastFrameNumber);
if (res != OK) {
ALOGE("%s: Camera %d: Got error %d after trying to set streaming "
"request", __FUNCTION__, mCameraId, res);
@@ -281,11 +193,12 @@
mStreamingRequestList.push_back(requestId);
}
} else {
- res = mDevice->captureList(metadataRequestList);
+ res = mDevice->captureList(metadataRequestList, lastFrameNumber);
if (res != OK) {
ALOGE("%s: Camera %d: Got error %d after trying to set capture",
__FUNCTION__, mCameraId, res);
}
+ ALOGV("%s: requestId = %d ", __FUNCTION__, requestId);
}
ALOGV("%s: Camera %d: End of function", __FUNCTION__, mCameraId);
@@ -296,7 +209,7 @@
return res;
}
-status_t CameraDeviceClient::cancelRequest(int requestId) {
+status_t CameraDeviceClient::cancelRequest(int requestId, int64_t* lastFrameNumber) {
ATRACE_CALL();
ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
@@ -322,7 +235,7 @@
return BAD_VALUE;
}
- res = mDevice->clearStreamingRequest();
+ res = mDevice->clearStreamingRequest(lastFrameNumber);
if (res == OK) {
ALOGV("%s: Camera %d: Successfully cleared streaming request",
@@ -369,8 +282,6 @@
} else if (res == OK) {
mStreamMap.removeItemsAt(index);
- ALOGV("%s: Camera %d: Successfully deleted stream ID (%d)",
- __FUNCTION__, mCameraId, streamId);
}
return res;
@@ -575,7 +486,7 @@
return res;
}
-status_t CameraDeviceClient::flush() {
+status_t CameraDeviceClient::flush(int64_t* lastFrameNumber) {
ATRACE_CALL();
ALOGV("%s", __FUNCTION__);
@@ -586,7 +497,7 @@
if (!mDevice.get()) return DEAD_OBJECT;
- return mDevice->flush();
+ return mDevice->flush(lastFrameNumber);
}
status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
@@ -603,13 +514,13 @@
return dumpDevice(fd, args);
}
-
-void CameraDeviceClient::notifyError() {
+void CameraDeviceClient::notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
+ const CaptureResultExtras& resultExtras) {
// Thread safe. Don't bother locking.
sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
if (remoteCb != 0) {
- remoteCb->onDeviceError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE);
+ remoteCb->onDeviceError(errorCode, resultExtras);
}
}
@@ -622,12 +533,12 @@
}
}
-void CameraDeviceClient::notifyShutter(int requestId,
+void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
nsecs_t timestamp) {
// Thread safe. Don't bother locking.
sp<ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
if (remoteCb != 0) {
- remoteCb->onCaptureStarted(requestId, timestamp);
+ remoteCb->onCaptureStarted(resultExtras, timestamp);
}
}
@@ -662,16 +573,14 @@
}
/** Device-related methods */
-void CameraDeviceClient::onFrameAvailable(int32_t requestId,
- const CameraMetadata& frame) {
+void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
ATRACE_CALL();
ALOGV("%s", __FUNCTION__);
// Thread-safe. No lock necessary.
sp<ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
if (remoteCb != NULL) {
- ALOGV("%s: frame = %p ", __FUNCTION__, &frame);
- remoteCb->onResultReceived(requestId, frame);
+ remoteCb->onResultReceived(result.mMetadata, result.mResultExtras);
}
}
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index e96e1ae..0b37784 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -64,11 +64,17 @@
// Note that the callee gets a copy of the metadata.
virtual status_t submitRequest(sp<CaptureRequest> request,
- bool streaming = false);
+ bool streaming = false,
+ /*out*/
+ int64_t* lastFrameNumber = NULL);
// List of requests are copied.
virtual status_t submitRequestList(List<sp<CaptureRequest> > requests,
- bool streaming = false);
- virtual status_t cancelRequest(int requestId);
+ bool streaming = false,
+ /*out*/
+ int64_t* lastFrameNumber = NULL);
+ virtual status_t cancelRequest(int requestId,
+ /*out*/
+ int64_t* lastFrameNumber = NULL);
// Returns -EBUSY if device is not idle
virtual status_t deleteStream(int streamId);
@@ -92,7 +98,8 @@
virtual status_t waitUntilIdle();
// Flush all active and pending requests as fast as possible
- virtual status_t flush();
+ virtual status_t flush(/*out*/
+ int64_t* lastFrameNumber = NULL);
/**
* Interface used by CameraService
@@ -117,16 +124,16 @@
*/
virtual void notifyIdle();
- virtual void notifyError();
- virtual void notifyShutter(int requestId, nsecs_t timestamp);
+ virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
+ const CaptureResultExtras& resultExtras);
+ virtual void notifyShutter(const CaptureResultExtras& resultExtras, nsecs_t timestamp);
/**
* Interface used by independent components of CameraDeviceClient.
*/
protected:
/** FilteredListener implementation **/
- virtual void onFrameAvailable(int32_t requestId,
- const CameraMetadata& frame);
+ virtual void onResultAvailable(const CaptureResult& result);
virtual void detachDevice();
// Calculate the ANativeWindow transform from android.sensor.orientation
diff --git a/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp b/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp
index 1a7a7a7..0f6d278 100644
--- a/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp
+++ b/services/camera/libcameraservice/api_pro/ProCamera2Client.cpp
@@ -373,9 +373,7 @@
Camera2ClientBase::detachDevice();
}
-/** Device-related methods */
-void ProCamera2Client::onFrameAvailable(int32_t requestId,
- const CameraMetadata& frame) {
+void ProCamera2Client::onResultAvailable(const CaptureResult& result) {
ATRACE_CALL();
ALOGV("%s", __FUNCTION__);
@@ -383,13 +381,12 @@
SharedCameraCallbacks::Lock l(mSharedCameraCallbacks);
if (mRemoteCallback != NULL) {
- CameraMetadata tmp(frame);
+ CameraMetadata tmp(result.mMetadata);
camera_metadata_t* meta = tmp.release();
ALOGV("%s: meta = %p ", __FUNCTION__, meta);
- mRemoteCallback->onResultReceived(requestId, meta);
+ mRemoteCallback->onResultReceived(result.mResultExtras.requestId, meta);
tmp.acquire(meta);
}
-
}
bool ProCamera2Client::enforceRequestPermissions(CameraMetadata& metadata) {
diff --git a/services/camera/libcameraservice/api_pro/ProCamera2Client.h b/services/camera/libcameraservice/api_pro/ProCamera2Client.h
index 8a0f547..9d83122 100644
--- a/services/camera/libcameraservice/api_pro/ProCamera2Client.h
+++ b/services/camera/libcameraservice/api_pro/ProCamera2Client.h
@@ -21,6 +21,7 @@
#include "common/FrameProcessorBase.h"
#include "common/Camera2ClientBase.h"
#include "device2/Camera2Device.h"
+#include "camera/CaptureResult.h"
namespace android {
@@ -97,8 +98,8 @@
protected:
/** FilteredListener implementation **/
- virtual void onFrameAvailable(int32_t requestId,
- const CameraMetadata& frame);
+ virtual void onResultAvailable(const CaptureResult& result);
+
virtual void detachDevice();
private:
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 6a88c87..19efd30 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -221,10 +221,11 @@
/** Device-related methods */
template <typename TClientBase>
-void Camera2ClientBase<TClientBase>::notifyError(int errorCode, int arg1,
- int arg2) {
- ALOGE("Error condition %d reported by HAL, arguments %d, %d", errorCode,
- arg1, arg2);
+void Camera2ClientBase<TClientBase>::notifyError(
+ ICameraDeviceCallbacks::CameraErrorCode errorCode,
+ const CaptureResultExtras& resultExtras) {
+ ALOGE("Error condition %d reported by HAL, requestId %" PRId32, errorCode,
+ resultExtras.requestId);
}
template <typename TClientBase>
@@ -233,13 +234,13 @@
}
template <typename TClientBase>
-void Camera2ClientBase<TClientBase>::notifyShutter(int requestId,
+void Camera2ClientBase<TClientBase>::notifyShutter(const CaptureResultExtras& resultExtras,
nsecs_t timestamp) {
- (void)requestId;
+ (void)resultExtras;
(void)timestamp;
- ALOGV("%s: Shutter notification for request id %d at time %" PRId64,
- __FUNCTION__, requestId, timestamp);
+ ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64,
+ __FUNCTION__, resultExtras.requestId, timestamp);
}
template <typename TClientBase>
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index 61e44f0..9feca93 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -18,6 +18,7 @@
#define ANDROID_SERVERS_CAMERA_CAMERA2CLIENT_BASE_H
#include "common/CameraDeviceBase.h"
+#include "camera/CaptureResult.h"
namespace android {
@@ -61,9 +62,11 @@
* CameraDeviceBase::NotificationListener implementation
*/
- virtual void notifyError(int errorCode, int arg1, int arg2);
+ virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
+ const CaptureResultExtras& resultExtras);
virtual void notifyIdle();
- virtual void notifyShutter(int requestId, nsecs_t timestamp);
+ virtual void notifyShutter(const CaptureResultExtras& resultExtras,
+ nsecs_t timestamp);
virtual void notifyAutoFocus(uint8_t newState, int triggerId);
virtual void notifyAutoExposure(uint8_t newState, int triggerId);
virtual void notifyAutoWhitebalance(uint8_t newState,
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index a4ae179..7597b10 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -24,8 +24,10 @@
#include <utils/Timers.h>
#include <utils/List.h>
+#include <camera/camera2/ICameraDeviceCallbacks.h>
#include "hardware/camera2.h"
#include "camera/CameraMetadata.h"
+#include "camera/CaptureResult.h"
namespace android {
@@ -45,7 +47,7 @@
virtual status_t initialize(camera_module_t *module) = 0;
virtual status_t disconnect() = 0;
- virtual status_t dump(int fd, const Vector<String16>& args) = 0;
+ virtual status_t dump(int fd, const Vector<String16> &args) = 0;
/**
* The device's static characteristics metadata buffer
@@ -55,29 +57,37 @@
/**
* Submit request for capture. The CameraDevice takes ownership of the
* passed-in buffer.
+ * Output lastFrameNumber is the expected frame number of this request.
*/
- virtual status_t capture(CameraMetadata &request) = 0;
+ virtual status_t capture(CameraMetadata &request, int64_t *lastFrameNumber = NULL) = 0;
/**
* Submit a list of requests.
+ * Output lastFrameNumber is the expected last frame number of the list of requests.
*/
- virtual status_t captureList(const List<const CameraMetadata> &requests) = 0;
+ virtual status_t captureList(const List<const CameraMetadata> &requests,
+ int64_t *lastFrameNumber = NULL) = 0;
/**
* Submit request for streaming. The CameraDevice makes a copy of the
* passed-in buffer and the caller retains ownership.
+ * Output lastFrameNumber is the last frame number of the previous streaming request.
*/
- virtual status_t setStreamingRequest(const CameraMetadata &request) = 0;
+ virtual status_t setStreamingRequest(const CameraMetadata &request,
+ int64_t *lastFrameNumber = NULL) = 0;
/**
* Submit a list of requests for streaming.
+ * Output lastFrameNumber is the last frame number of the previous streaming request.
*/
- virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests) = 0;
+ virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests,
+ int64_t *lastFrameNumber = NULL) = 0;
/**
* Clear the streaming request slot.
+ * Output lastFrameNumber is the last frame number of the previous streaming request.
*/
- virtual status_t clearStreamingRequest() = 0;
+ virtual status_t clearStreamingRequest(int64_t *lastFrameNumber = NULL) = 0;
/**
* Wait until a request with the given ID has been dequeued by the
@@ -153,11 +163,12 @@
// API1 and API2.
// Required for API 1 and 2
- virtual void notifyError(int errorCode, int arg1, int arg2) = 0;
+ virtual void notifyError(ICameraDeviceCallbacks::CameraErrorCode errorCode,
+ const CaptureResultExtras &resultExtras) = 0;
// Required only for API2
virtual void notifyIdle() = 0;
- virtual void notifyShutter(int requestId,
+ virtual void notifyShutter(const CaptureResultExtras &resultExtras,
nsecs_t timestamp) = 0;
// Required only for API1
@@ -190,11 +201,12 @@
virtual status_t waitForNextFrame(nsecs_t timeout) = 0;
/**
- * Get next metadata frame from the frame queue. Returns NULL if the queue
- * is empty; caller takes ownership of the metadata buffer.
- * May be called concurrently to most methods, except for waitForNextFrame
+ * Get next capture result frame from the result queue. Returns NOT_ENOUGH_DATA
+ * if the queue is empty; caller takes ownership of the metadata buffer inside
+ * the capture result object's metadata field.
+ * May be called concurrently to most methods, except for waitForNextFrame.
*/
- virtual status_t getNextFrame(CameraMetadata *frame) = 0;
+ virtual status_t getNextResult(CaptureResult *frame) = 0;
/**
* Trigger auto-focus. The latest ID used in a trigger autofocus or cancel
@@ -235,8 +247,9 @@
/**
* Flush all pending and in-flight requests. Blocks until flush is
* complete.
+ * Output lastFrameNumber is the last frame number of the previous streaming request.
*/
- virtual status_t flush() = 0;
+ virtual status_t flush(int64_t *lastFrameNumber = NULL) = 0;
};
diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.cpp b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
index 4d31667..f6a971a 100644
--- a/services/camera/libcameraservice/common/FrameProcessorBase.cpp
+++ b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
@@ -99,15 +99,17 @@
void FrameProcessorBase::processNewFrames(const sp<CameraDeviceBase> &device) {
status_t res;
ATRACE_CALL();
- CameraMetadata frame;
+ CaptureResult result;
ALOGV("%s: Camera %d: Process new frames", __FUNCTION__, device->getId());
- while ( (res = device->getNextFrame(&frame)) == OK) {
+ while ( (res = device->getNextResult(&result)) == OK) {
+ // TODO: instead of getting frame number from metadata, we should read
+ // this from result.mResultExtras when CameraDeviceBase interface is fixed.
camera_metadata_entry_t entry;
- entry = frame.find(ANDROID_REQUEST_FRAME_COUNT);
+ entry = result.mMetadata.find(ANDROID_REQUEST_FRAME_COUNT);
if (entry.count == 0) {
ALOGE("%s: Camera %d: Error reading frame number",
__FUNCTION__, device->getId());
@@ -115,13 +117,13 @@
}
ATRACE_INT("cam2_frame", entry.data.i32[0]);
- if (!processSingleFrame(frame, device)) {
+ if (!processSingleFrame(result, device)) {
break;
}
- if (!frame.isEmpty()) {
+ if (!result.mMetadata.isEmpty()) {
Mutex::Autolock al(mLastFrameMutex);
- mLastFrame.acquire(frame);
+ mLastFrame.acquire(result.mMetadata);
}
}
if (res != NOT_ENOUGH_DATA) {
@@ -133,21 +135,22 @@
return;
}
-bool FrameProcessorBase::processSingleFrame(CameraMetadata &frame,
- const sp<CameraDeviceBase> &device) {
+bool FrameProcessorBase::processSingleFrame(CaptureResult &result,
+ const sp<CameraDeviceBase> &device) {
ALOGV("%s: Camera %d: Process single frame (is empty? %d)",
- __FUNCTION__, device->getId(), frame.isEmpty());
- return processListeners(frame, device) == OK;
+ __FUNCTION__, device->getId(), result.mMetadata.isEmpty());
+ return processListeners(result, device) == OK;
}
-status_t FrameProcessorBase::processListeners(const CameraMetadata &frame,
+status_t FrameProcessorBase::processListeners(const CaptureResult &result,
const sp<CameraDeviceBase> &device) {
ATRACE_CALL();
+
camera_metadata_ro_entry_t entry;
// Quirks: Don't deliver partial results to listeners that don't want them
bool quirkIsPartial = false;
- entry = frame.find(ANDROID_QUIRKS_PARTIAL_RESULT);
+ entry = result.mMetadata.find(ANDROID_QUIRKS_PARTIAL_RESULT);
if (entry.count != 0 &&
entry.data.u8[0] == ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL) {
ALOGV("%s: Camera %d: Not forwarding partial result to listeners",
@@ -155,10 +158,13 @@
quirkIsPartial = true;
}
- entry = frame.find(ANDROID_REQUEST_ID);
+ // TODO: instead of getting requestID from CameraMetadata, we should get it
+ // from CaptureResultExtras. This will require changing Camera2Device.
+ // Currently Camera2Device uses MetadataQueue to store results, which does not
+ // include CaptureResultExtras.
+ entry = result.mMetadata.find(ANDROID_REQUEST_ID);
if (entry.count == 0) {
- ALOGE("%s: Camera %d: Error reading frame id",
- __FUNCTION__, device->getId());
+ ALOGE("%s: Camera %d: Error reading frame id", __FUNCTION__, device->getId());
return BAD_VALUE;
}
int32_t requestId = entry.data.i32[0];
@@ -169,9 +175,8 @@
List<RangeListener>::iterator item = mRangeListeners.begin();
while (item != mRangeListeners.end()) {
- if (requestId >= item->minId &&
- requestId < item->maxId &&
- (!quirkIsPartial || item->quirkSendPartials) ) {
+ if (requestId >= item->minId && requestId < item->maxId &&
+ (!quirkIsPartial || item->quirkSendPartials)) {
sp<FilteredListener> listener = item->listener.promote();
if (listener == 0) {
item = mRangeListeners.erase(item);
@@ -183,10 +188,12 @@
item++;
}
}
- ALOGV("Got %zu range listeners out of %zu", listeners.size(), mRangeListeners.size());
+ ALOGV("%s: Camera %d: Got %zu range listeners out of %zu", __FUNCTION__,
+ device->getId(), listeners.size(), mRangeListeners.size());
+
List<sp<FilteredListener> >::iterator item = listeners.begin();
for (; item != listeners.end(); item++) {
- (*item)->onFrameAvailable(requestId, frame);
+ (*item)->onResultAvailable(result);
}
return OK;
}
diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.h b/services/camera/libcameraservice/common/FrameProcessorBase.h
index 89b608a..15a014e 100644
--- a/services/camera/libcameraservice/common/FrameProcessorBase.h
+++ b/services/camera/libcameraservice/common/FrameProcessorBase.h
@@ -23,6 +23,7 @@
#include <utils/KeyedVector.h>
#include <utils/List.h>
#include <camera/CameraMetadata.h>
+#include <camera/CaptureResult.h>
namespace android {
@@ -39,8 +40,7 @@
virtual ~FrameProcessorBase();
struct FilteredListener: virtual public RefBase {
- virtual void onFrameAvailable(int32_t requestId,
- const CameraMetadata &frame) = 0;
+ virtual void onResultAvailable(const CaptureResult &result) = 0;
};
// Register a listener for a range of IDs [minId, maxId). Multiple listeners
@@ -72,10 +72,10 @@
void processNewFrames(const sp<CameraDeviceBase> &device);
- virtual bool processSingleFrame(CameraMetadata &frame,
+ virtual bool processSingleFrame(CaptureResult &result,
const sp<CameraDeviceBase> &device);
- status_t processListeners(const CameraMetadata &frame,
+ status_t processListeners(const CaptureResult &result,
const sp<CameraDeviceBase> &device);
CameraMetadata mLastFrame;
diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp
index 0cc3a04..c33c166 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.cpp
+++ b/services/camera/libcameraservice/device2/Camera2Device.cpp
@@ -199,7 +199,7 @@
return mDeviceInfo;
}
-status_t Camera2Device::capture(CameraMetadata &request) {
+status_t Camera2Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) {
ATRACE_CALL();
ALOGV("%s: E", __FUNCTION__);
@@ -207,27 +207,29 @@
return OK;
}
-status_t Camera2Device::captureList(const List<const CameraMetadata> &requests) {
+status_t Camera2Device::captureList(const List<const CameraMetadata> &requests,
+ int64_t* /*lastFrameNumber*/) {
ATRACE_CALL();
ALOGE("%s: Camera2Device burst capture not implemented", __FUNCTION__);
return INVALID_OPERATION;
}
-
-status_t Camera2Device::setStreamingRequest(const CameraMetadata &request) {
+status_t Camera2Device::setStreamingRequest(const CameraMetadata &request,
+ int64_t* /*lastFrameNumber*/) {
ATRACE_CALL();
ALOGV("%s: E", __FUNCTION__);
CameraMetadata streamRequest(request);
return mRequestQueue.setStreamSlot(streamRequest.release());
}
-status_t Camera2Device::setStreamingRequestList(const List<const CameraMetadata> &requests) {
+status_t Camera2Device::setStreamingRequestList(const List<const CameraMetadata> &requests,
+ int64_t* /*lastFrameNumber*/) {
ATRACE_CALL();
ALOGE("%s, Camera2Device streaming burst not implemented", __FUNCTION__);
return INVALID_OPERATION;
}
-status_t Camera2Device::clearStreamingRequest() {
+status_t Camera2Device::clearStreamingRequest(int64_t* /*lastFrameNumber*/) {
ATRACE_CALL();
return mRequestQueue.setStreamSlot(NULL);
}
@@ -460,7 +462,13 @@
if (listener != NULL) {
switch (msg_type) {
case CAMERA2_MSG_ERROR:
- listener->notifyError(ext1, ext2, ext3);
+ // TODO: This needs to be fixed. ext2 and ext3 need to be considered.
+ listener->notifyError(
+ ((ext1 == CAMERA2_MSG_ERROR_DEVICE)
+ || (ext1 == CAMERA2_MSG_ERROR_HARDWARE)) ?
+ ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE :
+ ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE,
+ CaptureResultExtras());
break;
case CAMERA2_MSG_SHUTTER: {
// TODO: Only needed for camera2 API, which is unsupported
@@ -489,16 +497,22 @@
return mFrameQueue.waitForBuffer(timeout);
}
-status_t Camera2Device::getNextFrame(CameraMetadata *frame) {
+status_t Camera2Device::getNextResult(CaptureResult *result) {
ATRACE_CALL();
+ ALOGV("%s: get CaptureResult", __FUNCTION__);
+ if (result == NULL) {
+ ALOGE("%s: result pointer is NULL", __FUNCTION__);
+ return BAD_VALUE;
+ }
status_t res;
camera_metadata_t *rawFrame;
res = mFrameQueue.dequeue(&rawFrame);
- if (rawFrame == NULL) {
+ if (rawFrame == NULL) {
return NOT_ENOUGH_DATA;
} else if (res == OK) {
- frame->acquire(rawFrame);
+ result->mMetadata.acquire(rawFrame);
}
+
return res;
}
@@ -568,7 +582,7 @@
return res;
}
-status_t Camera2Device::flush() {
+status_t Camera2Device::flush(int64_t* /*lastFrameNumber*/) {
ATRACE_CALL();
mRequestQueue.clear();
diff --git a/services/camera/libcameraservice/device2/Camera2Device.h b/services/camera/libcameraservice/device2/Camera2Device.h
index 61bfd1a..22a13ac 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.h
+++ b/services/camera/libcameraservice/device2/Camera2Device.h
@@ -47,11 +47,14 @@
virtual status_t disconnect();
virtual status_t dump(int fd, const Vector<String16>& args);
virtual const CameraMetadata& info() const;
- virtual status_t capture(CameraMetadata &request);
- virtual status_t captureList(const List<const CameraMetadata> &requests);
- virtual status_t setStreamingRequest(const CameraMetadata &request);
- virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests);
- virtual status_t clearStreamingRequest();
+ virtual status_t capture(CameraMetadata &request, int64_t *lastFrameNumber = NULL);
+ virtual status_t captureList(const List<const CameraMetadata> &requests,
+ int64_t *lastFrameNumber = NULL);
+ virtual status_t setStreamingRequest(const CameraMetadata &request,
+ int64_t *lastFrameNumber = NULL);
+ virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests,
+ int64_t *lastFrameNumber = NULL);
+ virtual status_t clearStreamingRequest(int64_t *lastFrameNumber = NULL);
virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout);
virtual status_t createStream(sp<ANativeWindow> consumer,
uint32_t width, uint32_t height, int format, size_t size,
@@ -67,14 +70,14 @@
virtual status_t setNotifyCallback(NotificationListener *listener);
virtual bool willNotify3A();
virtual status_t waitForNextFrame(nsecs_t timeout);
- virtual status_t getNextFrame(CameraMetadata *frame);
+ virtual status_t getNextResult(CaptureResult *frame);
virtual status_t triggerAutofocus(uint32_t id);
virtual status_t triggerCancelAutofocus(uint32_t id);
virtual status_t triggerPrecaptureMetering(uint32_t id);
virtual status_t pushReprocessBuffer(int reprocessStreamId,
buffer_handle_t *buffer, wp<BufferReleasedListener> listener);
// Flush implemented as just a wait
- virtual status_t flush();
+ virtual status_t flush(int64_t *lastFrameNumber = NULL);
private:
const int mId;
camera2_device_t *mHal2Device;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index f586e75..f965136 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -399,6 +399,7 @@
return BAD_VALUE;
}
+ int32_t burstId = 0;
for (List<const CameraMetadata>::const_iterator it = metadataList.begin();
it != metadataList.end(); ++it) {
sp<CaptureRequest> newRequest = setUpRequestLocked(*it);
@@ -406,60 +407,39 @@
CLOGE("Can't create capture request");
return BAD_VALUE;
}
+
+ // Setup burst Id and request Id
+ newRequest->mResultExtras.burstId = burstId++;
+ if (it->exists(ANDROID_REQUEST_ID)) {
+ if (it->find(ANDROID_REQUEST_ID).count == 0) {
+ CLOGE("RequestID entry exists; but must not be empty in metadata");
+ return BAD_VALUE;
+ }
+ newRequest->mResultExtras.requestId = it->find(ANDROID_REQUEST_ID).data.i32[0];
+ } else {
+ CLOGE("RequestID does not exist in metadata");
+ return BAD_VALUE;
+ }
+
requestList->push_back(newRequest);
+
+ ALOGV("%s: requestId = %" PRId32, __FUNCTION__, newRequest->mResultExtras.requestId);
}
return OK;
}
-status_t Camera3Device::capture(CameraMetadata &request) {
+status_t Camera3Device::capture(CameraMetadata &request, int64_t* /*lastFrameNumber*/) {
ATRACE_CALL();
- status_t res;
- Mutex::Autolock il(mInterfaceLock);
- Mutex::Autolock l(mLock);
- // TODO: take ownership of the request
-
- switch (mStatus) {
- case STATUS_ERROR:
- CLOGE("Device has encountered a serious error");
- return INVALID_OPERATION;
- case STATUS_UNINITIALIZED:
- CLOGE("Device not initialized");
- return INVALID_OPERATION;
- case STATUS_UNCONFIGURED:
- // May be lazily configuring streams, will check during setup
- case STATUS_CONFIGURED:
- case STATUS_ACTIVE:
- // OK
- break;
- default:
- SET_ERR_L("Unexpected status: %d", mStatus);
- return INVALID_OPERATION;
- }
-
- sp<CaptureRequest> newRequest = setUpRequestLocked(request);
- if (newRequest == NULL) {
- CLOGE("Can't create capture request");
- return BAD_VALUE;
- }
-
- res = mRequestThread->queueRequest(newRequest);
- if (res == OK) {
- waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
- if (res != OK) {
- SET_ERR_L("Can't transition to active in %f seconds!",
- kActiveTimeout/1e9);
- }
- ALOGV("Camera %d: Capture request enqueued", mId);
- } else {
- CLOGE("Cannot queue request. Impossible."); // queueRequest always returns OK.
- return BAD_VALUE;
- }
- return res;
+ List<const CameraMetadata> requests;
+ requests.push_back(request);
+ return captureList(requests, /*lastFrameNumber*/NULL);
}
status_t Camera3Device::submitRequestsHelper(
- const List<const CameraMetadata> &requests, bool repeating) {
+ const List<const CameraMetadata> &requests, bool repeating,
+ /*out*/
+ int64_t *lastFrameNumber) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
@@ -479,9 +459,9 @@
}
if (repeating) {
- res = mRequestThread->setRepeatingRequests(requestList);
+ res = mRequestThread->setRepeatingRequests(requestList, lastFrameNumber);
} else {
- res = mRequestThread->queueRequestList(requestList);
+ res = mRequestThread->queueRequestList(requestList, lastFrameNumber);
}
if (res == OK) {
@@ -490,7 +470,8 @@
SET_ERR_L("Can't transition to active in %f seconds!",
kActiveTimeout/1e9);
}
- ALOGV("Camera %d: Capture request enqueued", mId);
+ ALOGV("Camera %d: Capture request %" PRId32 " enqueued", mId,
+ (*(requestList.begin()))->mResultExtras.requestId);
} else {
CLOGE("Cannot queue request. Impossible.");
return BAD_VALUE;
@@ -499,61 +480,27 @@
return res;
}
-status_t Camera3Device::captureList(const List<const CameraMetadata> &requests) {
+status_t Camera3Device::captureList(const List<const CameraMetadata> &requests,
+ int64_t *lastFrameNumber) {
ATRACE_CALL();
- return submitRequestsHelper(requests, /*repeating*/false);
+ return submitRequestsHelper(requests, /*repeating*/false, lastFrameNumber);
}
-status_t Camera3Device::setStreamingRequest(const CameraMetadata &request) {
+status_t Camera3Device::setStreamingRequest(const CameraMetadata &request,
+ int64_t* /*lastFrameNumber*/) {
ATRACE_CALL();
- status_t res;
- Mutex::Autolock il(mInterfaceLock);
- Mutex::Autolock l(mLock);
- switch (mStatus) {
- case STATUS_ERROR:
- CLOGE("Device has encountered a serious error");
- return INVALID_OPERATION;
- case STATUS_UNINITIALIZED:
- CLOGE("Device not initialized");
- return INVALID_OPERATION;
- case STATUS_UNCONFIGURED:
- // May be lazily configuring streams, will check during setup
- case STATUS_CONFIGURED:
- case STATUS_ACTIVE:
- // OK
- break;
- default:
- SET_ERR_L("Unexpected status: %d", mStatus);
- return INVALID_OPERATION;
- }
-
- sp<CaptureRequest> newRepeatingRequest = setUpRequestLocked(request);
- if (newRepeatingRequest == NULL) {
- CLOGE("Can't create repeating request");
- return BAD_VALUE;
- }
-
- RequestList newRepeatingRequests;
- newRepeatingRequests.push_back(newRepeatingRequest);
-
- res = mRequestThread->setRepeatingRequests(newRepeatingRequests);
- if (res == OK) {
- waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
- if (res != OK) {
- SET_ERR_L("Can't transition to active in %f seconds!",
- kActiveTimeout/1e9);
- }
- ALOGV("Camera %d: Repeating request set", mId);
- }
- return res;
+ List<const CameraMetadata> requests;
+ requests.push_back(request);
+ return setStreamingRequestList(requests, /*lastFrameNumber*/NULL);
}
-status_t Camera3Device::setStreamingRequestList(const List<const CameraMetadata> &requests) {
+status_t Camera3Device::setStreamingRequestList(const List<const CameraMetadata> &requests,
+ int64_t *lastFrameNumber) {
ATRACE_CALL();
- return submitRequestsHelper(requests, /*repeating*/true);
+ return submitRequestsHelper(requests, /*repeating*/true, lastFrameNumber);
}
sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
@@ -576,7 +523,7 @@
return newRequest;
}
-status_t Camera3Device::clearStreamingRequest() {
+status_t Camera3Device::clearStreamingRequest(int64_t *lastFrameNumber) {
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
@@ -598,7 +545,8 @@
return INVALID_OPERATION;
}
ALOGV("Camera %d: Clearing repeating request", mId);
- return mRequestThread->clearRepeatingRequests();
+
+ return mRequestThread->clearRepeatingRequests(lastFrameNumber);
}
status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
@@ -1115,7 +1063,7 @@
return OK;
}
-status_t Camera3Device::getNextFrame(CameraMetadata *frame) {
+status_t Camera3Device::getNextResult(CaptureResult *frame) {
ATRACE_CALL();
Mutex::Autolock l(mOutputLock);
@@ -1123,8 +1071,14 @@
return NOT_ENOUGH_DATA;
}
- CameraMetadata &result = *(mResultQueue.begin());
- frame->acquire(result);
+ if (frame == NULL) {
+ ALOGE("%s: argument cannot be NULL", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ CaptureResult &result = *(mResultQueue.begin());
+ frame->mResultExtras = result.mResultExtras;
+ frame->mMetadata.acquire(result.mMetadata);
mResultQueue.erase(mResultQueue.begin());
return OK;
@@ -1202,13 +1156,13 @@
return INVALID_OPERATION;
}
-status_t Camera3Device::flush() {
+status_t Camera3Device::flush(int64_t *frameNumber) {
ATRACE_CALL();
ALOGV("%s: Camera %d: Flushing all requests", __FUNCTION__, mId);
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
- mRequestThread->clear();
+ mRequestThread->clear(/*out*/frameNumber);
status_t res;
if (mHal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_1) {
res = mHal3Device->ops->flush(mHal3Device);
@@ -1484,13 +1438,13 @@
* In-flight request management
*/
-status_t Camera3Device::registerInFlight(int32_t frameNumber,
- int32_t requestId, int32_t numBuffers) {
+status_t Camera3Device::registerInFlight(uint32_t frameNumber,
+ int32_t numBuffers, CaptureResultExtras resultExtras) {
ATRACE_CALL();
Mutex::Autolock l(mInFlightLock);
ssize_t res;
- res = mInFlightMap.add(frameNumber, InFlightRequest(requestId, numBuffers));
+ res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras));
if (res < 0) return res;
return OK;
@@ -1502,8 +1456,8 @@
* to the output frame queue
*/
bool Camera3Device::processPartial3AQuirk(
- int32_t frameNumber, int32_t requestId,
- const CameraMetadata& partial) {
+ uint32_t frameNumber,
+ const CameraMetadata& partial, const CaptureResultExtras& resultExtras) {
// Check if all 3A states are present
// The full list of fields is
@@ -1552,7 +1506,7 @@
ALOGVV("%s: Camera %d: Frame %d, Request ID %d: AF mode %d, AWB mode %d, "
"AF state %d, AE state %d, AWB state %d, "
"AF trigger %d, AE precapture trigger %d",
- __FUNCTION__, mId, frameNumber, requestId,
+ __FUNCTION__, mId, frameNumber, resultExtras.requestId,
afMode, awbMode,
afState, aeState, awbState,
afTriggerId, aeTriggerId);
@@ -1567,58 +1521,63 @@
Mutex::Autolock l(mOutputLock);
- CameraMetadata& min3AResult =
- *mResultQueue.insert(
- mResultQueue.end(),
- CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0));
+ CaptureResult captureResult;
+ captureResult.mResultExtras = resultExtras;
+ captureResult.mMetadata = CameraMetadata(kMinimal3AResultEntries, /*dataCapacity*/ 0);
+ // TODO: change this to sp<CaptureResult>. This will need other changes, including,
+ // but not limited to CameraDeviceBase::getNextResult
+ CaptureResult& min3AResult =
+ *mResultQueue.insert(mResultQueue.end(), captureResult);
- if (!insert3AResult(min3AResult, ANDROID_REQUEST_FRAME_COUNT,
- &frameNumber, frameNumber)) {
+ if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_FRAME_COUNT,
+ // TODO: This is problematic casting. Need to fix CameraMetadata.
+ reinterpret_cast<int32_t*>(&frameNumber), frameNumber)) {
return false;
}
- if (!insert3AResult(min3AResult, ANDROID_REQUEST_ID,
+ int32_t requestId = resultExtras.requestId;
+ if (!insert3AResult(min3AResult.mMetadata, ANDROID_REQUEST_ID,
&requestId, frameNumber)) {
return false;
}
static const uint8_t partialResult = ANDROID_QUIRKS_PARTIAL_RESULT_PARTIAL;
- if (!insert3AResult(min3AResult, ANDROID_QUIRKS_PARTIAL_RESULT,
+ if (!insert3AResult(min3AResult.mMetadata, ANDROID_QUIRKS_PARTIAL_RESULT,
&partialResult, frameNumber)) {
return false;
}
- if (!insert3AResult(min3AResult, ANDROID_CONTROL_AF_MODE,
+ if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_MODE,
&afMode, frameNumber)) {
return false;
}
- if (!insert3AResult(min3AResult, ANDROID_CONTROL_AWB_MODE,
+ if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_MODE,
&awbMode, frameNumber)) {
return false;
}
- if (!insert3AResult(min3AResult, ANDROID_CONTROL_AE_STATE,
+ if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_STATE,
&aeState, frameNumber)) {
return false;
}
- if (!insert3AResult(min3AResult, ANDROID_CONTROL_AF_STATE,
+ if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_STATE,
&afState, frameNumber)) {
return false;
}
- if (!insert3AResult(min3AResult, ANDROID_CONTROL_AWB_STATE,
+ if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AWB_STATE,
&awbState, frameNumber)) {
return false;
}
- if (!insert3AResult(min3AResult, ANDROID_CONTROL_AF_TRIGGER_ID,
+ if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AF_TRIGGER_ID,
&afTriggerId, frameNumber)) {
return false;
}
- if (!insert3AResult(min3AResult, ANDROID_CONTROL_AE_PRECAPTURE_ID,
+ if (!insert3AResult(min3AResult.mMetadata, ANDROID_CONTROL_AE_PRECAPTURE_ID,
&aeTriggerId, frameNumber)) {
return false;
}
@@ -1630,7 +1589,7 @@
template<typename T>
bool Camera3Device::get3AResult(const CameraMetadata& result, int32_t tag,
- T* value, int32_t frameNumber) {
+ T* value, uint32_t frameNumber) {
(void) frameNumber;
camera_metadata_ro_entry_t entry;
@@ -1655,7 +1614,7 @@
template<typename T>
bool Camera3Device::insert3AResult(CameraMetadata& result, int32_t tag,
- const T* value, int32_t frameNumber) {
+ const T* value, uint32_t frameNumber) {
if (result.update(tag, value, 1) != NO_ERROR) {
mResultQueue.erase(--mResultQueue.end(), mResultQueue.end());
SET_ERR("Frame %d: Failed to set %s in partial metadata",
@@ -1682,11 +1641,12 @@
}
bool partialResultQuirk = false;
CameraMetadata collectedQuirkResult;
+ CaptureResultExtras resultExtras;
- // Get capture timestamp from list of in-flight requests, where it was added
- // by the shutter notification for this frame. Then update the in-flight
- // status and remove the in-flight entry if all result data has been
- // received.
+ // Get capture timestamp and resultExtras from list of in-flight requests,
+ // where it was added by the shutter notification for this frame.
+ // Then update the in-flight status and remove the in-flight entry if
+ // all result data has been received.
nsecs_t timestamp = 0;
{
Mutex::Autolock l(mInFlightLock);
@@ -1697,6 +1657,10 @@
return;
}
InFlightRequest &request = mInFlightMap.editValueAt(idx);
+ ALOGVV("%s: got InFlightRequest requestId = %" PRId32 ", frameNumber = %" PRId64
+ ", burstId = %" PRId32,
+ __FUNCTION__, request.resultExtras.requestId, request.resultExtras.frameNumber,
+ request.resultExtras.burstId);
// Check if this result carries only partial metadata
if (mUsePartialResultQuirk && result->result != NULL) {
@@ -1718,13 +1682,15 @@
if (!request.partialResultQuirk.haveSent3A) {
request.partialResultQuirk.haveSent3A =
processPartial3AQuirk(frameNumber,
- request.requestId,
- request.partialResultQuirk.collectedResult);
+ request.partialResultQuirk.collectedResult,
+ request.resultExtras);
}
}
}
timestamp = request.captureTimestamp;
+ resultExtras = request.resultExtras;
+
/**
* One of the following must happen before it's legal to call process_capture_result,
* unless partial metadata is being provided:
@@ -1791,11 +1757,12 @@
}
mNextResultFrameNumber++;
- CameraMetadata captureResult;
- captureResult = result->result;
+ CaptureResult captureResult;
+ captureResult.mResultExtras = resultExtras;
+ captureResult.mMetadata = result->result;
- if (captureResult.update(ANDROID_REQUEST_FRAME_COUNT,
- (int32_t*)&frameNumber, 1) != OK) {
+ if (captureResult.mMetadata.update(ANDROID_REQUEST_FRAME_COUNT,
+ (int32_t*)&frameNumber, 1) != OK) {
SET_ERR("Failed to set frame# in metadata (%d)",
frameNumber);
gotResult = false;
@@ -1806,15 +1773,15 @@
// Append any previous partials to form a complete result
if (mUsePartialResultQuirk && !collectedQuirkResult.isEmpty()) {
- captureResult.append(collectedQuirkResult);
+ captureResult.mMetadata.append(collectedQuirkResult);
}
- captureResult.sort();
+ captureResult.mMetadata.sort();
// Check that there's a timestamp in the result metadata
camera_metadata_entry entry =
- captureResult.find(ANDROID_SENSOR_TIMESTAMP);
+ captureResult.mMetadata.find(ANDROID_SENSOR_TIMESTAMP);
if (entry.count == 0) {
SET_ERR("No timestamp provided by HAL for frame %d!",
frameNumber);
@@ -1828,9 +1795,13 @@
if (gotResult) {
// Valid result, insert into queue
- CameraMetadata& queuedResult =
- *mResultQueue.insert(mResultQueue.end(), CameraMetadata());
- queuedResult.swap(captureResult);
+ List<CaptureResult>::iterator queuedResult =
+ mResultQueue.insert(mResultQueue.end(), CaptureResult(captureResult));
+ ALOGVV("%s: result requestId = %" PRId32 ", frameNumber = %" PRId64
+ ", burstId = %" PRId32, __FUNCTION__,
+ queuedResult->mResultExtras.requestId,
+ queuedResult->mResultExtras.frameNumber,
+ queuedResult->mResultExtras.burstId);
}
} // scope for mOutputLock
@@ -1856,8 +1827,6 @@
}
-
-
void Camera3Device::notify(const camera3_notify_msg *msg) {
ATRACE_CALL();
NotificationListener *listener;
@@ -1884,18 +1853,32 @@
mId, __FUNCTION__, msg->message.error.frame_number,
streamId, msg->message.error.error_code);
+ CaptureResultExtras resultExtras;
// Set request error status for the request in the in-flight tracking
{
Mutex::Autolock l(mInFlightLock);
ssize_t idx = mInFlightMap.indexOfKey(msg->message.error.frame_number);
if (idx >= 0) {
- mInFlightMap.editValueAt(idx).requestStatus = msg->message.error.error_code;
+ InFlightRequest &r = mInFlightMap.editValueAt(idx);
+ r.requestStatus = msg->message.error.error_code;
+ resultExtras = r.resultExtras;
+ } else {
+ resultExtras.frameNumber = msg->message.error.frame_number;
+ ALOGE("Camera %d: %s: cannot find in-flight request on frame %" PRId64
+ " error", mId, __FUNCTION__, resultExtras.frameNumber);
}
}
if (listener != NULL) {
- listener->notifyError(msg->message.error.error_code,
- msg->message.error.frame_number, streamId);
+ if (msg->message.error.error_code == CAMERA3_MSG_ERROR_DEVICE) {
+ listener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
+ resultExtras);
+ } else {
+ listener->notifyError(ICameraDeviceCallbacks::ERROR_CAMERA_SERVICE,
+ resultExtras);
+ }
+ } else {
+ ALOGE("Camera %d: %s: no listener available", mId, __FUNCTION__);
}
break;
}
@@ -1915,7 +1898,7 @@
mNextShutterFrameNumber++;
}
- int32_t requestId = -1;
+ CaptureResultExtras resultExtras;
// Set timestamp for the request in the in-flight tracking
// and get the request ID to send upstream
@@ -1925,7 +1908,7 @@
if (idx >= 0) {
InFlightRequest &r = mInFlightMap.editValueAt(idx);
r.captureTimestamp = timestamp;
- requestId = r.requestId;
+ resultExtras = r.resultExtras;
}
}
if (idx < 0) {
@@ -1934,10 +1917,10 @@
break;
}
ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64,
- mId, __FUNCTION__, frameNumber, requestId, timestamp);
+ mId, __FUNCTION__, frameNumber, resultExtras.requestId, timestamp);
// Call listener, if any
if (listener != NULL) {
- listener->notifyShutter(requestId, timestamp);
+ listener->notifyShutter(resultExtras, timestamp);
}
break;
}
@@ -1959,6 +1942,7 @@
return retVal;
}
+
/**
* RequestThread inner class methods
*/
@@ -1975,7 +1959,8 @@
mDoPause(false),
mPaused(true),
mFrameNumber(0),
- mLatestRequestId(NAME_NOT_FOUND) {
+ mLatestRequestId(NAME_NOT_FOUND),
+ mRepeatingLastFrameNumber(NO_IN_FLIGHT_REPEATING_FRAMES) {
mStatusId = statusTracker->addComponent();
}
@@ -1984,24 +1969,23 @@
mReconfigured = true;
}
-status_t Camera3Device::RequestThread::queueRequest(
- sp<CaptureRequest> request) {
- Mutex::Autolock l(mRequestLock);
- mRequestQueue.push_back(request);
-
- unpauseForNewRequests();
-
- return OK;
-}
-
status_t Camera3Device::RequestThread::queueRequestList(
- List<sp<CaptureRequest> > &requests) {
+ List<sp<CaptureRequest> > &requests,
+ /*out*/
+ int64_t *lastFrameNumber) {
Mutex::Autolock l(mRequestLock);
for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end();
++it) {
mRequestQueue.push_back(*it);
}
+ if (lastFrameNumber != NULL) {
+ *lastFrameNumber = mFrameNumber + mRequestQueue.size() - 1;
+ ALOGV("%s: requestId %d, mFrameNumber %" PRId32 ", lastFrameNumber %" PRId64 ".",
+ __FUNCTION__, (*(requests.begin()))->mResultExtras.requestId, mFrameNumber,
+ *lastFrameNumber);
+ }
+
unpauseForNewRequests();
return OK;
@@ -2064,28 +2048,43 @@
}
status_t Camera3Device::RequestThread::setRepeatingRequests(
- const RequestList &requests) {
+ const RequestList &requests,
+ /*out*/
+ int64_t *lastFrameNumber) {
Mutex::Autolock l(mRequestLock);
+ if (lastFrameNumber != NULL) {
+ *lastFrameNumber = mRepeatingLastFrameNumber;
+ }
mRepeatingRequests.clear();
mRepeatingRequests.insert(mRepeatingRequests.begin(),
requests.begin(), requests.end());
unpauseForNewRequests();
+ mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
return OK;
}
-status_t Camera3Device::RequestThread::clearRepeatingRequests() {
+status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
Mutex::Autolock l(mRequestLock);
mRepeatingRequests.clear();
+ if (lastFrameNumber != NULL) {
+ *lastFrameNumber = mRepeatingLastFrameNumber;
+ }
+ mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
return OK;
}
-status_t Camera3Device::RequestThread::clear() {
+status_t Camera3Device::RequestThread::clear(/*out*/int64_t *lastFrameNumber) {
Mutex::Autolock l(mRequestLock);
+ ALOGV("RequestThread::%s:", __FUNCTION__);
mRepeatingRequests.clear();
mRequestQueue.clear();
mTriggerMap.clear();
+ if (lastFrameNumber != NULL) {
+ *lastFrameNumber = mRepeatingLastFrameNumber;
+ }
+ mRepeatingLastFrameNumber = NO_IN_FLIGHT_REPEATING_FRAMES;
return OK;
}
@@ -2137,6 +2136,7 @@
// Create request to HAL
camera3_capture_request_t request = camera3_capture_request_t();
+ request.frame_number = nextRequest->mResultExtras.frameNumber;
Vector<camera3_stream_buffer_t> outputBuffers;
// Get the request ID, if any
@@ -2157,7 +2157,7 @@
if (res < 0) {
SET_ERR("RequestThread: Unable to insert triggers "
"(capture request %d, HAL device: %s (%d)",
- (mFrameNumber+1), strerror(-res), res);
+ request.frame_number, strerror(-res), res);
cleanUpFailedRequest(request, nextRequest, outputBuffers);
return false;
}
@@ -2175,7 +2175,7 @@
if (res != OK) {
SET_ERR("RequestThread: Unable to insert dummy trigger IDs "
"(capture request %d, HAL device: %s (%d)",
- (mFrameNumber+1), strerror(-res), res);
+ request.frame_number, strerror(-res), res);
cleanUpFailedRequest(request, nextRequest, outputBuffers);
return false;
}
@@ -2199,7 +2199,7 @@
if (e.count > 0) {
ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
__FUNCTION__,
- mFrameNumber+1,
+ request.frame_number,
e.data.u8[0]);
}
}
@@ -2241,8 +2241,6 @@
request.num_output_buffers++;
}
- request.frame_number = mFrameNumber++;
-
// Log request in the in-flight queue
sp<Camera3Device> parent = mParent.promote();
if (parent == NULL) {
@@ -2251,8 +2249,13 @@
return false;
}
- res = parent->registerInFlight(request.frame_number, requestId,
- request.num_output_buffers);
+ res = parent->registerInFlight(request.frame_number,
+ request.num_output_buffers, nextRequest->mResultExtras);
+ ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
+ ", burstId = %" PRId32 ".",
+ __FUNCTION__,
+ nextRequest->mResultExtras.requestId, nextRequest->mResultExtras.frameNumber,
+ nextRequest->mResultExtras.burstId);
if (res != OK) {
SET_ERR("RequestThread: Unable to register new in-flight request:"
" %s (%d)", strerror(-res), res);
@@ -2329,6 +2332,7 @@
return mLatestRequest;
}
+
void Camera3Device::RequestThread::cleanUpFailedRequest(
camera3_capture_request_t &request,
sp<CaptureRequest> &nextRequest,
@@ -2370,6 +2374,9 @@
++firstRequest,
requests.end());
// No need to wait any longer
+
+ mRepeatingLastFrameNumber = mFrameNumber + requests.size() - 1;
+
break;
}
@@ -2421,6 +2428,9 @@
mReconfigured = false;
}
+ if (nextRequest != NULL) {
+ nextRequest->mResultExtras.frameNumber = mFrameNumber++;
+ }
return nextRequest;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index ed58246..3ef39f3 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -24,6 +24,8 @@
#include <utils/Thread.h>
#include <utils/KeyedVector.h>
#include <hardware/camera3.h>
+#include <camera/CaptureResult.h>
+#include <camera/camera2/ICameraDeviceUser.h>
#include "common/CameraDeviceBase.h"
#include "device3/StatusTracker.h"
@@ -78,11 +80,14 @@
// Capture and setStreamingRequest will configure streams if currently in
// idle state
- virtual status_t capture(CameraMetadata &request);
- virtual status_t captureList(const List<const CameraMetadata> &requests);
- virtual status_t setStreamingRequest(const CameraMetadata &request);
- virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests);
- virtual status_t clearStreamingRequest();
+ virtual status_t capture(CameraMetadata &request, int64_t *lastFrameNumber = NULL);
+ virtual status_t captureList(const List<const CameraMetadata> &requests,
+ int64_t *lastFrameNumber = NULL);
+ virtual status_t setStreamingRequest(const CameraMetadata &request,
+ int64_t *lastFrameNumber = NULL);
+ virtual status_t setStreamingRequestList(const List<const CameraMetadata> &requests,
+ int64_t *lastFrameNumber = NULL);
+ virtual status_t clearStreamingRequest(int64_t *lastFrameNumber = NULL);
virtual status_t waitUntilRequestReceived(int32_t requestId, nsecs_t timeout);
@@ -118,7 +123,7 @@
virtual status_t setNotifyCallback(NotificationListener *listener);
virtual bool willNotify3A();
virtual status_t waitForNextFrame(nsecs_t timeout);
- virtual status_t getNextFrame(CameraMetadata *frame);
+ virtual status_t getNextResult(CaptureResult *frame);
virtual status_t triggerAutofocus(uint32_t id);
virtual status_t triggerCancelAutofocus(uint32_t id);
@@ -127,7 +132,7 @@
virtual status_t pushReprocessBuffer(int reprocessStreamId,
buffer_handle_t *buffer, wp<BufferReleasedListener> listener);
- virtual status_t flush();
+ virtual status_t flush(int64_t *lastFrameNumber = NULL);
// Methods called by subclasses
void notifyStatus(bool idle); // updates from StatusTracker
@@ -200,6 +205,7 @@
sp<camera3::Camera3Stream> mInputStream;
Vector<sp<camera3::Camera3OutputStreamInterface> >
mOutputStreams;
+ CaptureResultExtras mResultExtras;
};
typedef List<sp<CaptureRequest> > RequestList;
@@ -207,9 +213,11 @@
status_t convertMetadataListToRequestListLocked(
const List<const CameraMetadata> &metadataList,
- /*out*/RequestList *requestList);
+ /*out*/
+ RequestList *requestList);
- status_t submitRequestsHelper(const List<const CameraMetadata> &requests, bool repeating);
+ status_t submitRequestsHelper(const List<const CameraMetadata> &requests, bool repeating,
+ int64_t *lastFrameNumber = NULL);
/**
* Get the last request submitted to the hal by the request thread.
@@ -324,17 +332,21 @@
* on either. Use waitUntilPaused to wait until request queue
* has emptied out.
*/
- status_t setRepeatingRequests(const RequestList& requests);
- status_t clearRepeatingRequests();
+ status_t setRepeatingRequests(const RequestList& requests,
+ /*out*/
+ int64_t *lastFrameNumber = NULL);
+ status_t clearRepeatingRequests(/*out*/
+ int64_t *lastFrameNumber = NULL);
- status_t queueRequest(sp<CaptureRequest> request);
-
- status_t queueRequestList(List<sp<CaptureRequest> > &requests);
+ status_t queueRequestList(List<sp<CaptureRequest> > &requests,
+ /*out*/
+ int64_t *lastFrameNumber = NULL);
/**
* Remove all queued and repeating requests, and pending triggers
*/
- status_t clear();
+ status_t clear(/*out*/
+ int64_t *lastFrameNumber = NULL);
/**
* Queue a trigger to be dispatched with the next outgoing
@@ -447,6 +459,8 @@
TriggerMap mTriggerMap;
TriggerMap mTriggerRemovedMap;
TriggerMap mTriggerReplacedMap;
+
+ int64_t mRepeatingLastFrameNumber;
};
sp<RequestThread> mRequestThread;
@@ -455,8 +469,6 @@
*/
struct InFlightRequest {
- // android.request.id for the request
- int requestId;
// Set by notify() SHUTTER call.
nsecs_t captureTimestamp;
int requestStatus;
@@ -465,6 +477,7 @@
// Decremented by calls to process_capture_result with valid output
// buffers
int numBuffersLeft;
+ CaptureResultExtras resultExtras;
// Fields used by the partial result quirk only
struct PartialResultQuirkInFlight {
@@ -480,20 +493,26 @@
// Default constructor needed by KeyedVector
InFlightRequest() :
- requestId(0),
captureTimestamp(0),
requestStatus(OK),
haveResultMetadata(false),
numBuffersLeft(0) {
}
- InFlightRequest(int id, int numBuffers) :
- requestId(id),
+ InFlightRequest(int numBuffers) :
captureTimestamp(0),
requestStatus(OK),
haveResultMetadata(false),
numBuffersLeft(numBuffers) {
}
+
+ InFlightRequest(int numBuffers, CaptureResultExtras extras) :
+ captureTimestamp(0),
+ requestStatus(OK),
+ haveResultMetadata(false),
+ numBuffersLeft(numBuffers),
+ resultExtras(extras) {
+ }
};
// Map from frame number to the in-flight request state
typedef KeyedVector<uint32_t, InFlightRequest> InFlightMap;
@@ -501,25 +520,25 @@
Mutex mInFlightLock; // Protects mInFlightMap
InFlightMap mInFlightMap;
- status_t registerInFlight(int32_t frameNumber, int32_t requestId,
- int32_t numBuffers);
+ status_t registerInFlight(uint32_t frameNumber,
+ int32_t numBuffers, CaptureResultExtras resultExtras);
/**
* For the partial result quirk, check if all 3A state fields are available
* and if so, queue up 3A-only result to the client. Returns true if 3A
* is sent.
*/
- bool processPartial3AQuirk(int32_t frameNumber, int32_t requestId,
- const CameraMetadata& partial);
+ bool processPartial3AQuirk(uint32_t frameNumber,
+ const CameraMetadata& partial, const CaptureResultExtras& resultExtras);
// Helpers for reading and writing 3A metadata into to/from partial results
template<typename T>
bool get3AResult(const CameraMetadata& result, int32_t tag,
- T* value, int32_t frameNumber);
+ T* value, uint32_t frameNumber);
template<typename T>
bool insert3AResult(CameraMetadata &result, int32_t tag, const T* value,
- int32_t frameNumber);
+ uint32_t frameNumber);
/**
* Tracking for idle detection
*/
@@ -536,7 +555,7 @@
uint32_t mNextResultFrameNumber;
uint32_t mNextShutterFrameNumber;
- List<CameraMetadata> mResultQueue;
+ List<CaptureResult> mResultQueue;
Condition mResultSignal;
NotificationListener *mListener;
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index d662cc2..50a2c10 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -34,7 +34,8 @@
Camera3Stream(id, type,
width, height, maxSize, format),
mTotalBufferCount(0),
- mDequeuedBufferCount(0),
+ mHandoutTotalBufferCount(0),
+ mHandoutOutputBufferCount(0),
mFrameCount(0),
mLastTimestamp(0) {
@@ -55,8 +56,8 @@
nsecs_t signalTime = mCombinedFence->getSignalTime();
ALOGV("%s: Stream %d: Has %zu outstanding buffers,"
" buffer signal time is %" PRId64,
- __FUNCTION__, mId, mDequeuedBufferCount, signalTime);
- if (mDequeuedBufferCount > 0 || signalTime == INT64_MAX) {
+ __FUNCTION__, mId, mHandoutTotalBufferCount, signalTime);
+ if (mHandoutTotalBufferCount > 0 || signalTime == INT64_MAX) {
return true;
}
return false;
@@ -75,7 +76,7 @@
lines.appendFormat(" Frames produced: %d, last timestamp: %" PRId64 " ns\n",
mFrameCount, mLastTimestamp);
lines.appendFormat(" Total buffers: %zu, currently dequeued: %zu\n",
- mTotalBufferCount, mDequeuedBufferCount);
+ mTotalBufferCount, mHandoutTotalBufferCount);
write(fd, lines.string(), lines.size());
}
@@ -104,6 +105,14 @@
return mTotalBufferCount;
}
+size_t Camera3IOStreamBase::getHandoutOutputBufferCountLocked() {
+ return mHandoutOutputBufferCount;
+}
+
+size_t Camera3IOStreamBase::getHandoutInputBufferCountLocked() {
+ return (mHandoutTotalBufferCount - mHandoutOutputBufferCount);
+}
+
status_t Camera3IOStreamBase::disconnectLocked() {
switch (mState) {
case STATE_IN_RECONFIG:
@@ -117,9 +126,9 @@
return -ENOTCONN;
}
- if (mDequeuedBufferCount > 0) {
+ if (mHandoutTotalBufferCount > 0) {
ALOGE("%s: Can't disconnect with %zu buffers still dequeued!",
- __FUNCTION__, mDequeuedBufferCount);
+ __FUNCTION__, mHandoutTotalBufferCount);
return INVALID_OPERATION;
}
@@ -130,7 +139,8 @@
buffer_handle_t *handle,
int acquireFence,
int releaseFence,
- camera3_buffer_status_t status) {
+ camera3_buffer_status_t status,
+ bool output) {
/**
* Note that all fences are now owned by HAL.
*/
@@ -144,14 +154,25 @@
buffer.status = status;
// Inform tracker about becoming busy
- if (mDequeuedBufferCount == 0 && mState != STATE_IN_CONFIG &&
+ if (mHandoutTotalBufferCount == 0 && mState != STATE_IN_CONFIG &&
mState != STATE_IN_RECONFIG) {
+ /**
+ * Avoid a spurious IDLE->ACTIVE->IDLE transition when using buffers
+ * before/after register_stream_buffers during initial configuration
+ * or re-configuration.
+ *
+ * TODO: IN_CONFIG and IN_RECONFIG checks only make sense for <HAL3.2
+ */
sp<StatusTracker> statusTracker = mStatusTracker.promote();
if (statusTracker != 0) {
statusTracker->markComponentActive(mStatusId);
}
}
- mDequeuedBufferCount++;
+ mHandoutTotalBufferCount++;
+
+ if (output) {
+ mHandoutOutputBufferCount++;
+ }
}
status_t Camera3IOStreamBase::getBufferPreconditionCheckLocked() const {
@@ -165,7 +186,7 @@
// Only limit dequeue amount when fully configured
if (mState == STATE_CONFIGURED &&
- mDequeuedBufferCount == camera3_stream::max_buffers) {
+ mHandoutTotalBufferCount == camera3_stream::max_buffers) {
ALOGE("%s: Stream %d: Already dequeued maximum number of simultaneous"
" buffers (%d)", __FUNCTION__, mId,
camera3_stream::max_buffers);
@@ -183,7 +204,7 @@
__FUNCTION__, mId, mState);
return INVALID_OPERATION;
}
- if (mDequeuedBufferCount == 0) {
+ if (mHandoutTotalBufferCount == 0) {
ALOGE("%s: Stream %d: No buffers outstanding to return", __FUNCTION__,
mId);
return INVALID_OPERATION;
@@ -221,9 +242,20 @@
mCombinedFence = Fence::merge(mName, mCombinedFence, releaseFence);
}
- mDequeuedBufferCount--;
- if (mDequeuedBufferCount == 0 && mState != STATE_IN_CONFIG &&
+ if (output) {
+ mHandoutOutputBufferCount--;
+ }
+
+ mHandoutTotalBufferCount--;
+ if (mHandoutTotalBufferCount == 0 && mState != STATE_IN_CONFIG &&
mState != STATE_IN_RECONFIG) {
+ /**
+ * Avoid a spurious IDLE->ACTIVE->IDLE transition when using buffers
+ * before/after register_stream_buffers during initial configuration
+ * or re-configuration.
+ *
+ * TODO: IN_CONFIG and IN_RECONFIG checks only make sense for <HAL3.2
+ */
ALOGV("%s: Stream %d: All buffers returned; now idle", __FUNCTION__,
mId);
sp<StatusTracker> statusTracker = mStatusTracker.promote();
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
index fcb9d04..a35c290 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.h
@@ -48,7 +48,10 @@
protected:
size_t mTotalBufferCount;
// sum of input and output buffers that are currently acquired by HAL
- size_t mDequeuedBufferCount;
+ size_t mHandoutTotalBufferCount;
+ // number of output buffers that are currently acquired by HAL. This will be
+ // Redundant when camera3 streams are no longer bidirectional streams.
+ size_t mHandoutOutputBufferCount;
Condition mBufferReturnedSignal;
uint32_t mFrameCount;
// Last received output buffer's timestamp
@@ -76,6 +79,10 @@
virtual size_t getBufferCountLocked();
+ virtual size_t getHandoutOutputBufferCountLocked();
+
+ virtual size_t getHandoutInputBufferCountLocked();
+
virtual status_t getEndpointUsage(uint32_t *usage) = 0;
status_t getBufferPreconditionCheckLocked() const;
@@ -92,7 +99,8 @@
buffer_handle_t *handle,
int acquire_fence,
int release_fence,
- camera3_buffer_status_t status);
+ camera3_buffer_status_t status,
+ bool output);
}; // class Camera3IOStreamBase
diff --git a/services/camera/libcameraservice/device3/Camera3InputStream.cpp b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
index dd7fb6c..319be1d 100644
--- a/services/camera/libcameraservice/device3/Camera3InputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3InputStream.cpp
@@ -81,7 +81,7 @@
* in which case we reassign it to acquire_fence
*/
handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
- /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK);
+ /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/false);
mBuffersInFlight.push_back(bufferItem);
return OK;
@@ -199,7 +199,7 @@
assert(mMaxSize == 0);
assert(camera3_stream::format != HAL_PIXEL_FORMAT_BLOB);
- mDequeuedBufferCount = 0;
+ mHandoutTotalBufferCount = 0;
mFrameCount = 0;
if (mConsumer.get() == 0) {
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 682755d..7ec649b 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -119,7 +119,7 @@
* in which case we reassign it to acquire_fence
*/
handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
- /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK);
+ /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/true);
return OK;
}
@@ -324,7 +324,7 @@
}
mTotalBufferCount = maxConsumerBuffers + camera3_stream::max_buffers;
- mDequeuedBufferCount = 0;
+ mHandoutTotalBufferCount = 0;
mFrameCount = 0;
mLastTimestamp = 0;
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 70406f1..abfb602 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -23,6 +23,8 @@
#include "device3/Camera3Stream.h"
#include "device3/StatusTracker.h"
+#include <cutils/properties.h>
+
namespace android {
namespace camera3 {
@@ -137,6 +139,7 @@
if (mState == STATE_CONSTRUCTED) {
mState = STATE_IN_CONFIG;
} else { // mState == STATE_CONFIGURED
+ LOG_ALWAYS_FATAL_IF(mState != STATE_CONFIGURED, "Invalid state: 0x%x", mState);
mState = STATE_IN_RECONFIG;
}
@@ -209,8 +212,30 @@
status_t Camera3Stream::getBuffer(camera3_stream_buffer *buffer) {
ATRACE_CALL();
Mutex::Autolock l(mLock);
+ status_t res = OK;
- status_t res = getBufferLocked(buffer);
+ // This function should be only called when the stream is configured already.
+ if (mState != STATE_CONFIGURED) {
+ ALOGE("%s: Stream %d: Can't get buffers if stream is not in CONFIGURED state %d",
+ __FUNCTION__, mId, mState);
+ return INVALID_OPERATION;
+ }
+
+ // Wait for new buffer returned back if we are running into the limit.
+ if (getHandoutOutputBufferCountLocked() == camera3_stream::max_buffers) {
+ ALOGV("%s: Already dequeued max output buffers (%d), wait for next returned one.",
+ __FUNCTION__, camera3_stream::max_buffers);
+ res = mOutputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration);
+ if (res != OK) {
+ if (res == TIMED_OUT) {
+ ALOGE("%s: wait for output buffer return timed out after %lldms", __FUNCTION__,
+ kWaitForBufferDuration / 1000000LL);
+ }
+ return res;
+ }
+ }
+
+ res = getBufferLocked(buffer);
if (res == OK) {
fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/true);
}
@@ -223,9 +248,18 @@
ATRACE_CALL();
Mutex::Autolock l(mLock);
+ /**
+ * TODO: Check that the state is valid first.
+ *
+ * <HAL3.2 IN_CONFIG and IN_RECONFIG in addition to CONFIGURED.
+ * >= HAL3.2 CONFIGURED only
+ *
+ * Do this for getBuffer as well.
+ */
status_t res = returnBufferLocked(buffer, timestamp);
if (res == OK) {
fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/true);
+ mOutputBufferReturnedSignal.signal();
}
return res;
@@ -234,8 +268,30 @@
status_t Camera3Stream::getInputBuffer(camera3_stream_buffer *buffer) {
ATRACE_CALL();
Mutex::Autolock l(mLock);
+ status_t res = OK;
- status_t res = getInputBufferLocked(buffer);
+ // This function should be only called when the stream is configured already.
+ if (mState != STATE_CONFIGURED) {
+ ALOGE("%s: Stream %d: Can't get input buffers if stream is not in CONFIGURED state %d",
+ __FUNCTION__, mId, mState);
+ return INVALID_OPERATION;
+ }
+
+ // Wait for new buffer returned back if we are running into the limit.
+ if (getHandoutInputBufferCountLocked() == camera3_stream::max_buffers) {
+ ALOGV("%s: Already dequeued max input buffers (%d), wait for next returned one.",
+ __FUNCTION__, camera3_stream::max_buffers);
+ res = mInputBufferReturnedSignal.waitRelative(mLock, kWaitForBufferDuration);
+ if (res != OK) {
+ if (res == TIMED_OUT) {
+ ALOGE("%s: wait for input buffer return timed out after %lldms", __FUNCTION__,
+ kWaitForBufferDuration / 1000000LL);
+ }
+ return res;
+ }
+ }
+
+ res = getInputBufferLocked(buffer);
if (res == OK) {
fireBufferListenersLocked(*buffer, /*acquired*/true, /*output*/false);
}
@@ -250,6 +306,7 @@
status_t res = returnInputBufferLocked(buffer);
if (res == OK) {
fireBufferListenersLocked(buffer, /*acquired*/false, /*output*/false);
+ mInputBufferReturnedSignal.signal();
}
return res;
}
@@ -314,12 +371,46 @@
status_t Camera3Stream::registerBuffersLocked(camera3_device *hal3Device) {
ATRACE_CALL();
+
+ /**
+ * >= CAMERA_DEVICE_API_VERSION_3_2:
+ *
+ * camera3_device_t->ops->register_stream_buffers() is not called and must
+ * be NULL.
+ */
+ if (hal3Device->common.version >= CAMERA_DEVICE_API_VERSION_3_2) {
+ ALOGV("%s: register_stream_buffers unused as of HAL3.2", __FUNCTION__);
+
+ /**
+ * Skip the NULL check if camera.dev.register_stream is 1.
+ *
+ * For development-validation purposes only.
+ *
+ * TODO: Remove the property check before shipping L (b/13914251).
+ */
+ char value[PROPERTY_VALUE_MAX] = { '\0', };
+ property_get("camera.dev.register_stream", value, "0");
+ int propInt = atoi(value);
+
+ if (propInt == 0 && hal3Device->ops->register_stream_buffers != NULL) {
+ ALOGE("%s: register_stream_buffers is deprecated in HAL3.2; "
+ "must be set to NULL in camera3_device::ops", __FUNCTION__);
+ return INVALID_OPERATION;
+ } else {
+ ALOGD("%s: Skipping NULL check for deprecated register_stream_buffers");
+ }
+
+ return OK;
+ } else {
+ ALOGV("%s: register_stream_buffers using deprecated code path", __FUNCTION__);
+ }
+
status_t res;
size_t bufferCount = getBufferCountLocked();
Vector<buffer_handle_t*> buffers;
- buffers.insertAt(NULL, 0, bufferCount);
+ buffers.insertAt(/*prototype_item*/NULL, /*index*/0, bufferCount);
camera3_stream_buffer_set bufferSet = camera3_stream_buffer_set();
bufferSet.stream = this;
@@ -327,7 +418,7 @@
bufferSet.buffers = buffers.editArray();
Vector<camera3_stream_buffer_t> streamBuffers;
- streamBuffers.insertAt(camera3_stream_buffer_t(), 0, bufferCount);
+ streamBuffers.insertAt(camera3_stream_buffer_t(), /*index*/0, bufferCount);
// Register all buffers with the HAL. This means getting all the buffers
// from the stream, providing them to the HAL with the
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index 6eeb721..14f5387 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -82,6 +82,23 @@
* STATE_CONFIGURED => STATE_CONSTRUCTED:
* When disconnect() is called after making sure stream is idle with
* waitUntilIdle().
+ *
+ * Status Tracking:
+ * Each stream is tracked by StatusTracker as a separate component,
+ * depending on the handed out buffer count. The state must be STATE_CONFIGURED
+ * in order for the component to be marked.
+ *
+ * It's marked in one of two ways:
+ *
+ * - ACTIVE: One or more buffers have been handed out (with #getBuffer).
+ * - IDLE: All buffers have been returned (with #returnBuffer), and their
+ * respective release_fence(s) have been signaled.
+ *
+ * A typical use case is output streams. When the HAL has any buffers
+ * dequeued, the stream is marked ACTIVE. When the HAL returns all buffers
+ * (e.g. if no capture requests are active), the stream is marked IDLE.
+ * In this use case, the app consumer does not affect the component status.
+ *
*/
class Camera3Stream :
protected camera3_stream,
@@ -262,6 +279,12 @@
// Get the total number of buffers in the queue
virtual size_t getBufferCountLocked() = 0;
+ // Get handout output buffer count.
+ virtual size_t getHandoutOutputBufferCountLocked() = 0;
+
+ // Get handout input buffer count.
+ virtual size_t getHandoutInputBufferCountLocked() = 0;
+
// Get the usage flags for the other endpoint, or return
// INVALID_OPERATION if they cannot be obtained.
virtual status_t getEndpointUsage(uint32_t *usage) = 0;
@@ -274,6 +297,9 @@
private:
uint32_t oldUsage;
uint32_t oldMaxBuffers;
+ Condition mOutputBufferReturnedSignal;
+ Condition mInputBufferReturnedSignal;
+ static const nsecs_t kWaitForBufferDuration = 3000000000LL; // 3000 ms
// Gets all buffers from endpoint and registers them with the HAL.
status_t registerBuffersLocked(camera3_device *hal3Device);
diff --git a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp
index 09e14c5..05b3d1f 100644
--- a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp
@@ -176,7 +176,7 @@
* in which case we reassign it to acquire_fence
*/
handoutBufferLocked(*buffer, &(anb->handle), /*acquireFence*/fenceFd,
- /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK);
+ /*releaseFence*/-1, CAMERA3_BUFFER_STATUS_OK, /*output*/false);
mBuffersInFlight.push_back(bufferItem);