am 909318b3: am dbf995ce: am 6b203f06: am 66b24004: am 0ea9e276: am 184ad88d: am fba72ab0: am f394f121: Merge "libmedia: clear reply data for IEffect command" into klp-dev
* commit '909318b3c7e5d80c8a79f8a37200e797a287c061':
libmedia: clear reply data for IEffect command
diff --git a/camera/ICameraServiceProxy.cpp b/camera/ICameraServiceProxy.cpp
index 06a5afb..694e9c3 100644
--- a/camera/ICameraServiceProxy.cpp
+++ b/camera/ICameraServiceProxy.cpp
@@ -29,11 +29,21 @@
BpCameraServiceProxy(const sp<IBinder>& impl) : BpInterface<ICameraServiceProxy>(impl) {}
virtual void pingForUserUpdate() {
- Parcel data, reply;
+ Parcel data;
data.writeInterfaceToken(ICameraServiceProxy::getInterfaceDescriptor());
- remote()->transact(BnCameraServiceProxy::PING_FOR_USER_UPDATE, data, &reply,
+ remote()->transact(BnCameraServiceProxy::PING_FOR_USER_UPDATE, data, nullptr,
IBinder::FLAG_ONEWAY);
}
+
+ virtual void notifyCameraState(String16 cameraId, CameraState newCameraState) {
+ Parcel data;
+ data.writeInterfaceToken(ICameraServiceProxy::getInterfaceDescriptor());
+ data.writeString16(cameraId);
+ data.writeInt32(newCameraState);
+ remote()->transact(BnCameraServiceProxy::NOTIFY_CAMERA_STATE, data, nullptr,
+ IBinder::FLAG_ONEWAY);
+ }
+
};
@@ -47,9 +57,16 @@
pingForUserUpdate();
return NO_ERROR;
} break;
+ case NOTIFY_CAMERA_STATE: {
+ CHECK_INTERFACE(ICameraServiceProxy, data, reply);
+ String16 cameraId = data.readString16();
+ CameraState newCameraState =
+ static_cast<CameraState>(data.readInt32());
+ notifyCameraState(cameraId, newCameraState);
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
}; // namespace android
-
diff --git a/camera/camera2/ICameraDeviceUser.cpp b/camera/camera2/ICameraDeviceUser.cpp
index d2dc200..2a9fd2b 100644
--- a/camera/camera2/ICameraDeviceUser.cpp
+++ b/camera/camera2/ICameraDeviceUser.cpp
@@ -49,7 +49,8 @@
WAIT_UNTIL_IDLE,
FLUSH,
PREPARE,
- TEAR_DOWN
+ TEAR_DOWN,
+ PREPARE2
};
namespace {
@@ -366,6 +367,21 @@
return reply.readInt32();
}
+ virtual status_t prepare2(int maxCount, int streamId)
+ {
+ ALOGV("prepare2");
+ Parcel data, reply;
+
+ data.writeInterfaceToken(ICameraDeviceUser::getInterfaceDescriptor());
+ data.writeInt32(maxCount);
+ data.writeInt32(streamId);
+
+ remote()->transact(PREPARE2, data, &reply);
+
+ reply.readExceptionCode();
+ return reply.readInt32();
+ }
+
virtual status_t tearDown(int streamId)
{
ALOGV("tearDown");
@@ -592,7 +608,14 @@
reply->writeInt32(tearDown(streamId));
return NO_ERROR;
} break;
-
+ case PREPARE2: {
+ CHECK_INTERFACE(ICameraDeviceUser, data, reply);
+ int maxCount = data.readInt32();
+ int streamId = data.readInt32();
+ reply->writeNoException();
+ reply->writeInt32(prepare2(maxCount, streamId));
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/include/camera/ICameraServiceProxy.h b/include/camera/ICameraServiceProxy.h
index 12a555f..2613c01 100644
--- a/include/camera/ICameraServiceProxy.h
+++ b/include/camera/ICameraServiceProxy.h
@@ -23,15 +23,30 @@
namespace android {
+/**
+ * Interface from native camera service to managed-side camera service proxy.
+ *
+ * Keep in sync with frameworks/base/core/java/android/hardware/ICameraServiceProxy.aidl
+ *
+ */
class ICameraServiceProxy : public IInterface {
public:
enum {
PING_FOR_USER_UPDATE = IBinder::FIRST_CALL_TRANSACTION,
+ NOTIFY_CAMERA_STATE
+ };
+
+ enum CameraState {
+ CAMERA_STATE_OPEN,
+ CAMERA_STATE_ACTIVE,
+ CAMERA_STATE_IDLE,
+ CAMERA_STATE_CLOSED
};
DECLARE_META_INTERFACE(CameraServiceProxy);
virtual void pingForUserUpdate() = 0;
+ virtual void notifyCameraState(String16 cameraId, CameraState newCameraState) = 0;
};
class BnCameraServiceProxy: public BnInterface<ICameraServiceProxy>
@@ -48,5 +63,3 @@
}; // namespace android
#endif // ANDROID_HARDWARE_ICAMERASERVICEPROXY_H
-
-
diff --git a/include/camera/camera2/ICameraDeviceUser.h b/include/camera/camera2/ICameraDeviceUser.h
index a7bf8ab..4d8eb53 100644
--- a/include/camera/camera2/ICameraDeviceUser.h
+++ b/include/camera/camera2/ICameraDeviceUser.h
@@ -140,6 +140,11 @@
virtual status_t prepare(int streamId) = 0;
/**
+ * Preallocate up to maxCount buffers for a given output stream asynchronously.
+ */
+ virtual status_t prepare2(int maxCount, int streamId) = 0;
+
+ /**
* Free all unused buffers for a given output stream.
*/
virtual status_t tearDown(int streamId) = 0;
diff --git a/media/img_utils/include/img_utils/DngUtils.h b/media/img_utils/include/img_utils/DngUtils.h
index 3dcedc5..1d8df9c 100644
--- a/media/img_utils/include/img_utils/DngUtils.h
+++ b/media/img_utils/include/img_utils/DngUtils.h
@@ -138,6 +138,34 @@
double opticalCenterY,
const double* kCoeffs);
+
+ /**
+ * Add FixBadPixelsList opcode for the given metadata parameters.
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ virtual status_t addBadPixelListForMetadata(const uint32_t* hotPixels,
+ uint32_t xyPairCount,
+ uint32_t colorFilterArrangement);
+
+ /**
+ * Add FixBadPixelsList opcode.
+ *
+ * bayerPhase - 0=top-left of image is red, 1=top-left of image is green pixel in red row,
+ * 2=top-left of image is green pixel in blue row, 3=top-left of image is
+ * blue.
+ * badPointCount - number of (x,y) pairs of bad pixels are given in badPointRowColPairs.
+ * badRectCount - number of (top, left, bottom, right) tuples are given in
+ * badRectTopLeftBottomRightTuples
+ *
+ * Returns OK on success, or a negative error code.
+ */
+ virtual status_t addBadPixelList(uint32_t bayerPhase,
+ uint32_t badPointCount,
+ uint32_t badRectCount,
+ const uint32_t* badPointRowColPairs,
+ const uint32_t* badRectTopLeftBottomRightTuples);
+
// TODO: Add other Opcode methods
protected:
static const uint32_t FLAG_OPTIONAL = 0x1u;
@@ -146,6 +174,7 @@
// Opcode IDs
enum {
WARP_RECTILINEAR_ID = 1,
+ FIX_BAD_PIXELS_LIST = 5,
GAIN_MAP_ID = 9,
};
@@ -161,6 +190,8 @@
ByteArrayOutput mOpList;
EndianOutput mEndianOut;
+ status_t addOpcodePreamble(uint32_t opcodeId);
+
};
} /*namespace img_utils*/
diff --git a/media/img_utils/src/DngUtils.cpp b/media/img_utils/src/DngUtils.cpp
index b213403..9473dce 100644
--- a/media/img_utils/src/DngUtils.cpp
+++ b/media/img_utils/src/DngUtils.cpp
@@ -224,13 +224,7 @@
uint32_t mapPlanes,
const float* mapGains) {
- uint32_t opcodeId = GAIN_MAP_ID;
-
- status_t err = mEndianOut.write(&opcodeId, 0, 1);
- if (err != OK) return err;
-
- uint8_t version[] = {1, 3, 0, 0};
- err = mEndianOut.write(version, 0, NELEMS(version));
+ status_t err = addOpcodePreamble(GAIN_MAP_ID);
if (err != OK) return err;
// Allow this opcode to be skipped if not supported
@@ -334,13 +328,7 @@
double opticalCenterY,
const double* kCoeffs) {
- uint32_t opcodeId = WARP_RECTILINEAR_ID;
-
- status_t err = mEndianOut.write(&opcodeId, 0, 1);
- if (err != OK) return err;
-
- uint8_t version[] = {1, 3, 0, 0};
- err = mEndianOut.write(version, 0, NELEMS(version));
+ status_t err = addOpcodePreamble(WARP_RECTILINEAR_ID);
if (err != OK) return err;
// Allow this opcode to be skipped if not supported
@@ -373,5 +361,74 @@
return OK;
}
+status_t OpcodeListBuilder::addBadPixelListForMetadata(const uint32_t* hotPixels,
+ uint32_t xyPairCount,
+ uint32_t colorFilterArrangement) {
+ if (colorFilterArrangement > 3) {
+ ALOGE("%s: Unknown color filter arrangement %" PRIu32, __FUNCTION__,
+ colorFilterArrangement);
+ return BAD_VALUE;
+ }
+
+ return addBadPixelList(colorFilterArrangement, xyPairCount, 0, hotPixels, nullptr);
+}
+
+status_t OpcodeListBuilder::addBadPixelList(uint32_t bayerPhase,
+ uint32_t badPointCount,
+ uint32_t badRectCount,
+ const uint32_t* badPointRowColPairs,
+ const uint32_t* badRectTopLeftBottomRightTuples) {
+
+ status_t err = addOpcodePreamble(FIX_BAD_PIXELS_LIST);
+ if (err != OK) return err;
+
+ // Allow this opcode to be skipped if not supported
+ uint32_t flags = FLAG_OPTIONAL;
+
+ err = mEndianOut.write(&flags, 0, 1);
+ if (err != OK) return err;
+
+ const uint32_t NUM_NON_VARLEN_FIELDS = 3;
+ const uint32_t SIZE_OF_POINT = 2;
+ const uint32_t SIZE_OF_RECT = 4;
+
+ uint32_t totalSize = (NUM_NON_VARLEN_FIELDS + badPointCount * SIZE_OF_POINT +
+ badRectCount * SIZE_OF_RECT) * sizeof(uint32_t);
+ err = mEndianOut.write(&totalSize, 0, 1);
+ if (err != OK) return err;
+
+ err = mEndianOut.write(&bayerPhase, 0, 1);
+ if (err != OK) return err;
+
+ err = mEndianOut.write(&badPointCount, 0, 1);
+ if (err != OK) return err;
+
+ err = mEndianOut.write(&badRectCount, 0, 1);
+ if (err != OK) return err;
+
+ if (badPointCount > 0) {
+ err = mEndianOut.write(badPointRowColPairs, 0, SIZE_OF_POINT * badPointCount);
+ if (err != OK) return err;
+ }
+
+ if (badRectCount > 0) {
+ err = mEndianOut.write(badRectTopLeftBottomRightTuples, 0, SIZE_OF_RECT * badRectCount);
+ if (err != OK) return err;
+ }
+
+ mCount++;
+ return OK;
+}
+
+status_t OpcodeListBuilder::addOpcodePreamble(uint32_t opcodeId) {
+ status_t err = mEndianOut.write(&opcodeId, 0, 1);
+ if (err != OK) return err;
+
+ uint8_t version[] = {1, 3, 0, 0};
+ err = mEndianOut.write(version, 0, NELEMS(version));
+ if (err != OK) return err;
+ return OK;
+}
+
} /*namespace img_utils*/
} /*namespace android*/
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 56521a2..bcfd83a 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -1734,7 +1734,7 @@
t->setVolume(mLeftVolume, mRightVolume);
mSampleRateHz = sampleRate;
- mFlags = t->getFlags(); // we suggest the flags above, but new AudioTrack() may not grant it.
+ mFlags = flags;
mMsecsPerFrame = 1E3f / (mPlaybackRate.mSpeed * sampleRate);
mFrameSize = t->frameSize();
uint32_t pos;
@@ -1746,7 +1746,7 @@
status_t res = NO_ERROR;
// Note some output devices may give us a direct track even though we don't specify it.
// Example: Line application b/17459982.
- if ((mFlags & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT)) == 0) {
+ if ((t->getFlags() & (AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD | AUDIO_OUTPUT_FLAG_DIRECT)) == 0) {
res = t->setPlaybackRate(mPlaybackRate);
if (res == NO_ERROR) {
t->setAuxEffectSendLevel(mSendLevel);
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index 58ff113..af0351e 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -134,7 +134,9 @@
return;
}
}
- mHandler->pause();
+ if (mHandler != NULL) {
+ mHandler->pause();
+ }
}
void NuPlayer::RTSPSource::resume() {
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index 3505844..6e4a1dd 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -290,6 +290,10 @@
status_t AudioSource::dataCallback(const AudioRecord::Buffer& audioBuffer) {
int64_t timeUs = systemTime() / 1000ll;
+ // Estimate the real sampling time of the 1st sample in this buffer
+ // from AudioRecord's latency. (Apply this adjustment first so that
+ // the start time logic is not affected.)
+ timeUs -= mRecord->latency() * 1000LL;
ALOGV("dataCallbackTimestamp: %" PRId64 " us", timeUs);
Mutex::Autolock autoLock(mLock);
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index e7f6864..b1d7b13 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -1066,7 +1066,7 @@
*delayMs = 0;
if (stream == AUDIO_STREAM_TTS) {
ALOGV("\t found BEACON stream");
- if (mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) {
+ if (!mTtsOutputAvailable && mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) {
return INVALID_OPERATION;
} else {
beaconMuteLatency = handleEventForBeacon(STARTING_BEACON);
@@ -2000,6 +2000,9 @@
snprintf(buffer, SIZE, " Force use for hdmi system audio %d\n",
mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO));
result.append(buffer);
+ snprintf(buffer, SIZE, " TTS output %s\n", mTtsOutputAvailable ? "available" : "not available");
+ result.append(buffer);
+
write(fd, result.string(), result.size());
mAvailableOutputDevices.dump(fd, String8("output"));
@@ -2680,7 +2683,8 @@
mAudioPortGeneration(1),
mBeaconMuteRefCount(0),
mBeaconPlayingRefCount(0),
- mBeaconMuted(false)
+ mBeaconMuted(false),
+ mTtsOutputAvailable(false)
{
audio_policy::EngineInstance *engineInstance = audio_policy::EngineInstance::getInstance();
if (!engineInstance) {
@@ -2737,6 +2741,9 @@
ALOGW("Output profile contains no device on module %s", mHwModules[i]->mName);
continue;
}
+ if ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_TTS) != 0) {
+ mTtsOutputAvailable = true;
+ }
if ((outProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) {
continue;
@@ -4036,6 +4043,12 @@
}
uint32_t AudioPolicyManager::handleEventForBeacon(int event) {
+
+ // skip beacon mute management if a dedicated TTS output is available
+ if (mTtsOutputAvailable) {
+ return 0;
+ }
+
switch(event) {
case STARTING_OUTPUT:
mBeaconMuteRefCount++;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index bf3ae4a..bbdf396 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -548,6 +548,7 @@
uint32_t mBeaconMuteRefCount; // ref count for stream that would mute beacon
uint32_t mBeaconPlayingRefCount;// ref count for the playing beacon streams
bool mBeaconMuted; // has STREAM_TTS been muted
+ bool mTtsOutputAvailable; // true if a dedicated output for TTS stream is available
AudioPolicyMixCollection mPolicyMixes; // list of registered mixes
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 43a8ec4..7128df7 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -33,7 +33,6 @@
#include <binder/MemoryBase.h>
#include <binder/MemoryHeapBase.h>
#include <binder/ProcessInfoService.h>
-#include <camera/ICameraServiceProxy.h>
#include <cutils/atomic.h>
#include <cutils/properties.h>
#include <gui/Surface.h>
@@ -250,13 +249,19 @@
CameraService::pingCameraServiceProxy();
}
-void CameraService::pingCameraServiceProxy() {
+sp<ICameraServiceProxy> CameraService::getCameraServiceProxy() {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.camera.proxy"));
if (binder == nullptr) {
- return;
+ return nullptr;
}
sp<ICameraServiceProxy> proxyBinder = interface_cast<ICameraServiceProxy>(binder);
+ return proxyBinder;
+}
+
+void CameraService::pingCameraServiceProxy() {
+ sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
+ if (proxyBinder == nullptr) return;
proxyBinder->pingForUserUpdate();
}
@@ -1948,6 +1953,10 @@
mCameraService->updateStatus(ICameraServiceListener::STATUS_NOT_AVAILABLE,
String8::format("%d", mCameraId));
+ // Transition device state to OPEN
+ mCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_OPEN,
+ String8::format("%d", mCameraId));
+
return OK;
}
@@ -1966,6 +1975,10 @@
mCameraService->updateStatus(ICameraServiceListener::STATUS_PRESENT,
String8::format("%d", mCameraId), rejected);
+ // Transition device state to CLOSED
+ mCameraService->updateProxyDeviceState(ICameraServiceProxy::CAMERA_STATE_CLOSED,
+ String8::format("%d", mCameraId));
+
// Notify flashlight that a camera device is closed.
mCameraService->mFlashlight->deviceClosed(
String8::format("%d", mCameraId));
@@ -2466,6 +2479,14 @@
});
}
+void CameraService::updateProxyDeviceState(ICameraServiceProxy::CameraState newState,
+ const String8& cameraId) {
+ sp<ICameraServiceProxy> proxyBinder = getCameraServiceProxy();
+ if (proxyBinder == nullptr) return;
+ String16 id(cameraId);
+ proxyBinder->notifyCameraState(id, newState);
+}
+
status_t CameraService::getTorchStatusLocked(
const String8& cameraId,
ICameraServiceListener::TorchStatus *status) const {
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 7f4d43f..894767a 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -24,6 +24,7 @@
#include <binder/BinderService.h>
#include <binder/IAppOpsCallback.h>
#include <camera/ICameraService.h>
+#include <camera/ICameraServiceProxy.h>
#include <hardware/camera.h>
#include <camera/ICamera.h>
@@ -164,6 +165,14 @@
void playSound(sound_kind kind);
void releaseSound();
+ /**
+ * Update the state of a given camera device (open/close/active/idle) with
+ * the camera proxy service in the system service
+ */
+ static void updateProxyDeviceState(
+ ICameraServiceProxy::CameraState newState,
+ const String8& cameraId);
+
/////////////////////////////////////////////////////////////////////
// CameraDeviceFactory functionality
int getDeviceVersion(int cameraId, int* facing = NULL);
@@ -728,6 +737,7 @@
static String8 toString(std::set<userid_t> intSet);
+ static sp<ICameraServiceProxy> getCameraServiceProxy();
static void pingCameraServiceProxy();
};
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 36e99dd..48b5a26 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -1912,6 +1912,8 @@
ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64,
__FUNCTION__, resultExtras.requestId, timestamp);
mCaptureSequencer->notifyShutter(resultExtras, timestamp);
+
+ Camera2ClientBase::notifyShutter(resultExtras, timestamp);
}
camera2::SharedParameters& Camera2Client::getParameters() {
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index e552633..38e35cd 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -251,6 +251,9 @@
// Turn off all messages.
disableMsgType(CAMERA_MSG_ALL_MSGS);
mHardware->stopPreview();
+ mCameraService->updateProxyDeviceState(
+ ICameraServiceProxy::CAMERA_STATE_IDLE,
+ String8::format("%d", mCameraId));
mHardware->cancelPicture();
// Release the hardware resources.
mHardware->release();
@@ -409,7 +412,11 @@
}
mHardware->setPreviewWindow(mPreviewWindow);
result = mHardware->startPreview();
-
+ if (result == NO_ERROR) {
+ mCameraService->updateProxyDeviceState(
+ ICameraServiceProxy::CAMERA_STATE_ACTIVE,
+ String8::format("%d", mCameraId));
+ }
return result;
}
@@ -449,7 +456,9 @@
disableMsgType(CAMERA_MSG_PREVIEW_FRAME);
mHardware->stopPreview();
-
+ mCameraService->updateProxyDeviceState(
+ ICameraServiceProxy::CAMERA_STATE_IDLE,
+ String8::format("%d", mCameraId));
mPreviewBuffer.clear();
}
@@ -790,6 +799,12 @@
}
disableMsgType(CAMERA_MSG_SHUTTER);
+ // Shutters only happen in response to takePicture, so mark device as
+ // idle now, until preview is restarted
+ mCameraService->updateProxyDeviceState(
+ ICameraServiceProxy::CAMERA_STATE_IDLE,
+ String8::format("%d", mCameraId));
+
mLock.unlock();
}
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index c717a56..0c531c3 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -719,6 +719,43 @@
return res;
}
+status_t CameraDeviceClient::prepare2(int maxCount, int streamId) {
+ ATRACE_CALL();
+ ALOGV("%s", __FUNCTION__);
+
+ status_t res = OK;
+ if ( (res = checkPid(__FUNCTION__) ) != OK) return res;
+
+ Mutex::Autolock icl(mBinderSerializationLock);
+
+ // Guard against trying to prepare non-created streams
+ ssize_t index = NAME_NOT_FOUND;
+ for (size_t i = 0; i < mStreamMap.size(); ++i) {
+ if (streamId == mStreamMap.valueAt(i)) {
+ index = i;
+ break;
+ }
+ }
+
+ if (index == NAME_NOT_FOUND) {
+ ALOGW("%s: Camera %d: Invalid stream ID (%d) specified, no stream created yet",
+ __FUNCTION__, mCameraId, streamId);
+ return BAD_VALUE;
+ }
+
+ if (maxCount <= 0) {
+ ALOGE("%s: Camera %d: Invalid maxCount (%d) specified, must be greater than 0.",
+ __FUNCTION__, mCameraId, maxCount);
+ return BAD_VALUE;
+ }
+
+ // Also returns BAD_VALUE if stream ID was not valid, or stream already
+ // has been used
+ res = mDevice->prepare(maxCount, streamId);
+
+ return res;
+}
+
status_t CameraDeviceClient::tearDown(int streamId) {
ATRACE_CALL();
ALOGV("%s", __FUNCTION__);
@@ -799,6 +836,7 @@
if (remoteCb != 0) {
remoteCb->onDeviceIdle();
}
+ Camera2ClientBase::notifyIdle();
}
void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
@@ -808,6 +846,7 @@
if (remoteCb != 0) {
remoteCb->onCaptureStarted(resultExtras, timestamp);
}
+ Camera2ClientBase::notifyShutter(resultExtras, timestamp);
}
void CameraDeviceClient::notifyPrepared(int streamId) {
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 1f8b39d..d1e692c 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -114,6 +114,9 @@
// Tear down stream resources by freeing its unused buffers
virtual status_t tearDown(int streamId);
+ // Prepare stream by preallocating up to maxCount of its buffers
+ virtual status_t prepare2(int maxCount, int streamId);
+
/**
* Interface used by CameraService
*/
@@ -189,6 +192,7 @@
Vector<int> mStreamingRequestList;
int32_t mRequestIdCounter;
+
};
}; // namespace android
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index ba0b264..5732f80 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -55,7 +55,8 @@
TClientBase(cameraService, remoteCallback, clientPackageName,
cameraId, cameraFacing, clientPid, clientUid, servicePid),
mSharedCameraCallbacks(remoteCallback),
- mDeviceVersion(cameraService->getDeviceVersion(cameraId))
+ mDeviceVersion(cameraService->getDeviceVersion(cameraId)),
+ mDeviceActive(false)
{
ALOGI("Camera %d: Opened. Client: %s (PID %d, UID %d)", cameraId,
String8(clientPackageName).string(), clientPid, clientUid);
@@ -235,6 +236,13 @@
template <typename TClientBase>
void Camera2ClientBase<TClientBase>::notifyIdle() {
+ if (mDeviceActive) {
+ getCameraService()->updateProxyDeviceState(
+ ICameraServiceProxy::CAMERA_STATE_IDLE,
+ String8::format("%d", TClientBase::mCameraId));
+ }
+ mDeviceActive = false;
+
ALOGV("Camera device is now idle");
}
@@ -244,6 +252,13 @@
(void)resultExtras;
(void)timestamp;
+ if (!mDeviceActive) {
+ getCameraService()->updateProxyDeviceState(
+ ICameraServiceProxy::CAMERA_STATE_ACTIVE,
+ String8::format("%d", TClientBase::mCameraId));
+ }
+ mDeviceActive = true;
+
ALOGV("%s: Shutter notification for request id %" PRId32 " at time %" PRId64,
__FUNCTION__, resultExtras.requestId, timestamp);
}
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index f1cacdf..220c5ad 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -136,6 +136,8 @@
status_t checkPid(const char *checkLocation) const;
virtual void detachDevice();
+
+ bool mDeviceActive;
};
}; // namespace android
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index cd25949..7b083a3 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -294,6 +294,12 @@
virtual status_t tearDown(int streamId) = 0;
/**
+ * Prepare stream by preallocating up to maxCount buffers for it asynchronously.
+ * Calls notifyPrepared() once allocation is complete.
+ */
+ virtual status_t prepare(int maxCount, int streamId) = 0;
+
+ /**
* Get the HAL device version.
*/
virtual uint32_t getDeviceVersion() = 0;
diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp
index c9c990c..d74f976 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.cpp
+++ b/services/camera/libcameraservice/device2/Camera2Device.cpp
@@ -632,6 +632,12 @@
return NO_INIT;
}
+status_t Camera2Device::prepare(int maxCount, int streamId) {
+ ATRACE_CALL();
+ ALOGE("%s: Camera %d: unimplemented", __FUNCTION__, mId);
+ return NO_INIT;
+}
+
uint32_t Camera2Device::getDeviceVersion() {
ATRACE_CALL();
return mDeviceVersion;
diff --git a/services/camera/libcameraservice/device2/Camera2Device.h b/services/camera/libcameraservice/device2/Camera2Device.h
index 34c1ded..b4d343c 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.h
+++ b/services/camera/libcameraservice/device2/Camera2Device.h
@@ -88,6 +88,7 @@
// Prepare and tearDown are no-ops
virtual status_t prepare(int streamId);
virtual status_t tearDown(int streamId);
+ virtual status_t prepare(int maxCount, int streamId);
virtual uint32_t getDeviceVersion();
virtual ssize_t getJpegBufferSize(uint32_t width, uint32_t height) const;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 0c941fb..e4d75cb 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -1408,6 +1408,10 @@
}
status_t Camera3Device::prepare(int streamId) {
+ return prepare(camera3::Camera3StreamInterface::ALLOCATE_PIPELINE_MAX, streamId);
+}
+
+status_t Camera3Device::prepare(int maxCount, int streamId) {
ATRACE_CALL();
ALOGV("%s: Camera %d: Preparing stream %d", __FUNCTION__, mId, streamId);
Mutex::Autolock il(mInterfaceLock);
@@ -1432,7 +1436,7 @@
return BAD_VALUE;
}
- return mPreparerThread->prepare(stream);
+ return mPreparerThread->prepare(maxCount, stream);
}
status_t Camera3Device::tearDown(int streamId) {
@@ -3478,12 +3482,12 @@
clear();
}
-status_t Camera3Device::PreparerThread::prepare(sp<Camera3StreamInterface>& stream) {
+status_t Camera3Device::PreparerThread::prepare(int maxCount, sp<Camera3StreamInterface>& stream) {
status_t res;
Mutex::Autolock l(mLock);
- res = stream->startPrepare();
+ res = stream->startPrepare(maxCount);
if (res == OK) {
// No preparation needed, fire listener right off
ALOGV("%s: Stream %d already prepared", __FUNCTION__, stream->getId());
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index 5287058..1f39940 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -62,6 +62,7 @@
public CameraDeviceBase,
private camera3_callback_ops {
public:
+
Camera3Device(int id);
virtual ~Camera3Device();
@@ -143,6 +144,8 @@
virtual status_t tearDown(int streamId);
+ virtual status_t prepare(int maxCount, int streamId);
+
virtual uint32_t getDeviceVersion();
virtual ssize_t getJpegBufferSize(uint32_t width, uint32_t height) const;
@@ -698,10 +701,11 @@
void setNotificationListener(NotificationListener *listener);
/**
- * Queue up a stream to be prepared. Streams are processed by
- * a background thread in FIFO order
+ * Queue up a stream to be prepared. Streams are processed by a background thread in FIFO
+ * order. Pre-allocate up to maxCount buffers for the stream, or the maximum number needed
+ * for the pipeline if maxCount is ALLOCATE_PIPELINE_MAX.
*/
- status_t prepare(sp<camera3::Camera3StreamInterface>& stream);
+ status_t prepare(int maxCount, sp<camera3::Camera3StreamInterface>& stream);
/**
* Cancel all current and pending stream preparation
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 2527fd6..7163d62 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -53,7 +53,8 @@
mName(String8::format("Camera3Stream[%d]", id)),
mMaxSize(maxSize),
mState(STATE_CONSTRUCTED),
- mStatusId(StatusTracker::NO_STATUS_ID) {
+ mStatusId(StatusTracker::NO_STATUS_ID),
+ mLastMaxCount(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX) {
camera3_stream::stream_type = type;
camera3_stream::width = width;
@@ -252,12 +253,18 @@
return mStreamUnpreparable;
}
-status_t Camera3Stream::startPrepare() {
+status_t Camera3Stream::startPrepare(int maxCount) {
ATRACE_CALL();
Mutex::Autolock l(mLock);
status_t res = OK;
+ if (maxCount < 0) {
+ ALOGE("%s: Stream %d: Can't prepare stream if max buffer count (%d) is < 0",
+ __FUNCTION__, mId, maxCount);
+ return BAD_VALUE;
+ }
+
// This function should be only called when the stream is configured already.
if (mState != STATE_CONFIGURED) {
ALOGE("%s: Stream %d: Can't prepare stream if stream is not in CONFIGURED "
@@ -279,9 +286,19 @@
return INVALID_OPERATION;
}
+
+
+ size_t pipelineMax = getBufferCountLocked();
+ size_t clampedCount = (pipelineMax < static_cast<size_t>(maxCount)) ?
+ pipelineMax : static_cast<size_t>(maxCount);
+ size_t bufferCount = (maxCount == Camera3StreamInterface::ALLOCATE_PIPELINE_MAX) ?
+ pipelineMax : clampedCount;
+
+ mPrepared = bufferCount <= mLastMaxCount;
+
if (mPrepared) return OK;
- size_t bufferCount = getBufferCountLocked();
+ mLastMaxCount = bufferCount;
mPreparedBuffers.insertAt(camera3_stream_buffer_t(), /*index*/0, bufferCount);
mPreparedBufferIdx = 0;
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index bab2177..753280b 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -188,7 +188,9 @@
/**
* Start stream preparation. May only be called in the CONFIGURED state,
- * when no valid buffers have yet been returned to this stream.
+ * when no valid buffers have yet been returned to this stream. Prepares
+ * up to maxCount buffers, or the maximum number of buffers needed by the
+ * pipeline if maxCount is ALLOCATE_PIPELINE_MAX.
*
* If no prepartion is necessary, returns OK and does not transition to
* PREPARING state. Otherwise, returns NOT_ENOUGH_DATA and transitions
@@ -204,7 +206,7 @@
* INVALID_OPERATION if called when not in CONFIGURED state, or a
* valid buffer has already been returned to this stream.
*/
- status_t startPrepare();
+ status_t startPrepare(int maxCount);
/**
* Check if the stream is mid-preparing.
@@ -444,6 +446,9 @@
Vector<camera3_stream_buffer_t> mPreparedBuffers;
size_t mPreparedBufferIdx;
+ // Number of buffers allocated on last prepare call.
+ int mLastMaxCount;
+
}; // class Camera3Stream
}; // namespace camera3
diff --git a/services/camera/libcameraservice/device3/Camera3StreamInterface.h b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
index c086eaf..54009ae 100644
--- a/services/camera/libcameraservice/device3/Camera3StreamInterface.h
+++ b/services/camera/libcameraservice/device3/Camera3StreamInterface.h
@@ -34,6 +34,11 @@
*/
class Camera3StreamInterface : public virtual RefBase {
public:
+
+ enum {
+ ALLOCATE_PIPELINE_MAX = 0, // Allocate max buffers used by a given surface
+ };
+
/**
* Get the stream's ID
*/
@@ -98,7 +103,9 @@
/**
* Start stream preparation. May only be called in the CONFIGURED state,
- * when no valid buffers have yet been returned to this stream.
+ * when no valid buffers have yet been returned to this stream. Prepares
+ * up to maxCount buffers, or the maximum number of buffers needed by the
+ * pipeline if maxCount is ALLOCATE_PIPELINE_MAX.
*
* If no prepartion is necessary, returns OK and does not transition to
* PREPARING state. Otherwise, returns NOT_ENOUGH_DATA and transitions
@@ -112,7 +119,7 @@
* INVALID_OPERATION if called when not in CONFIGURED state, or a
* valid buffer has already been returned to this stream.
*/
- virtual status_t startPrepare() = 0;
+ virtual status_t startPrepare(int maxCount) = 0;
/**
* Check if the stream is mid-preparing.