summaryrefslogtreecommitdiffstats
path: root/camera
diff options
context:
space:
mode:
Diffstat (limited to 'camera')
-rw-r--r--camera/Android.mk4
-rw-r--r--camera/Camera.cpp56
-rw-r--r--camera/ICameraRecordingProxy.cpp109
-rw-r--r--camera/ICameraRecordingProxyListener.cpp75
4 files changed, 242 insertions, 2 deletions
diff --git a/camera/Android.mk b/camera/Android.mk
index b17b3d2..dc00957 100644
--- a/camera/Android.mk
+++ b/camera/Android.mk
@@ -6,7 +6,9 @@ LOCAL_SRC_FILES:= \
CameraParameters.cpp \
ICamera.cpp \
ICameraClient.cpp \
- ICameraService.cpp
+ ICameraService.cpp \
+ ICameraRecordingProxy.cpp \
+ ICameraRecordingProxyListener.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index 5eb48da..3c00db5 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -19,11 +19,12 @@
#define LOG_TAG "Camera"
#include <utils/Log.h>
#include <utils/threads.h>
-
+#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/IMemory.h>
#include <camera/Camera.h>
+#include <camera/ICameraRecordingProxyListener.h>
#include <camera/ICameraService.h>
#include <surfaceflinger/Surface.h>
@@ -236,6 +237,10 @@ void Camera::stopPreview()
void Camera::stopRecording()
{
LOGV("stopRecording");
+ {
+ Mutex::Autolock _l(mLock);
+ mRecordingProxyListener.clear();
+ }
sp <ICamera> c = mCamera;
if (c == 0) return;
c->stopRecording();
@@ -327,6 +332,12 @@ void Camera::setListener(const sp<CameraListener>& listener)
mListener = listener;
}
+void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>& listener)
+{
+ Mutex::Autolock _l(mLock);
+ mRecordingProxyListener = listener;
+}
+
void Camera::setPreviewCallbackFlags(int flag)
{
LOGV("setPreviewCallbackFlags");
@@ -364,6 +375,19 @@ void Camera::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr)
// callback from camera service when timestamped frame is ready
void Camera::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr)
{
+ // If recording proxy listener is registered, forward the frame and return.
+ // The other listener (mListener) is ignored because the receiver needs to
+ // call releaseRecordingFrame.
+ sp<ICameraRecordingProxyListener> proxylistener;
+ {
+ Mutex::Autolock _l(mLock);
+ proxylistener = mRecordingProxyListener;
+ }
+ if (proxylistener != NULL) {
+ proxylistener->dataCallbackTimestamp(timestamp, msgType, dataPtr);
+ return;
+ }
+
sp<CameraListener> listener;
{
Mutex::Autolock _l(mLock);
@@ -389,4 +413,34 @@ void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
LOGW("Camera server died!");
}
+sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
+ LOGV("getProxy");
+ return new RecordingProxy(this);
+}
+
+status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
+{
+ LOGV("RecordingProxy::startRecording");
+ mCamera->setRecordingProxyListener(listener);
+ mCamera->reconnect();
+ return mCamera->startRecording();
+}
+
+void Camera::RecordingProxy::stopRecording()
+{
+ LOGV("RecordingProxy::stopRecording");
+ mCamera->stopRecording();
+}
+
+void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
+{
+ LOGV("RecordingProxy::releaseRecordingFrame");
+ mCamera->releaseRecordingFrame(mem);
+}
+
+Camera::RecordingProxy::RecordingProxy(const sp<Camera>& camera)
+{
+ mCamera = camera;
+}
+
}; // namespace android
diff --git a/camera/ICameraRecordingProxy.cpp b/camera/ICameraRecordingProxy.cpp
new file mode 100644
index 0000000..64b6a5c
--- /dev/null
+++ b/camera/ICameraRecordingProxy.cpp
@@ -0,0 +1,109 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ICameraRecordingProxy"
+#include <camera/ICameraRecordingProxy.h>
+#include <camera/ICameraRecordingProxyListener.h>
+#include <binder/IMemory.h>
+#include <binder/Parcel.h>
+#include <stdint.h>
+#include <utils/Log.h>
+
+namespace android {
+
+enum {
+ START_RECORDING = IBinder::FIRST_CALL_TRANSACTION,
+ STOP_RECORDING,
+ RELEASE_RECORDING_FRAME,
+};
+
+
+class BpCameraRecordingProxy: public BpInterface<ICameraRecordingProxy>
+{
+public:
+ BpCameraRecordingProxy(const sp<IBinder>& impl)
+ : BpInterface<ICameraRecordingProxy>(impl)
+ {
+ }
+
+ status_t startRecording(const sp<ICameraRecordingProxyListener>& listener)
+ {
+ LOGV("startRecording");
+ Parcel data, reply;
+ data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
+ data.writeStrongBinder(listener->asBinder());
+ remote()->transact(START_RECORDING, data, &reply);
+ return reply.readInt32();
+ }
+
+ void stopRecording()
+ {
+ LOGV("stopRecording");
+ Parcel data, reply;
+ data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
+ remote()->transact(STOP_RECORDING, data, &reply);
+ }
+
+ void releaseRecordingFrame(const sp<IMemory>& mem)
+ {
+ LOGV("releaseRecordingFrame");
+ Parcel data, reply;
+ data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
+ data.writeStrongBinder(mem->asBinder());
+ remote()->transact(RELEASE_RECORDING_FRAME, data, &reply);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(CameraRecordingProxy, "android.hardware.ICameraRecordingProxy");
+
+// ----------------------------------------------------------------------
+
+status_t BnCameraRecordingProxy::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+ switch(code) {
+ case START_RECORDING: {
+ LOGV("START_RECORDING");
+ CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
+ sp<ICameraRecordingProxyListener> listener =
+ interface_cast<ICameraRecordingProxyListener>(data.readStrongBinder());
+ reply->writeInt32(startRecording(listener));
+ return NO_ERROR;
+ } break;
+ case STOP_RECORDING: {
+ LOGV("STOP_RECORDING");
+ CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
+ stopRecording();
+ return NO_ERROR;
+ } break;
+ case RELEASE_RECORDING_FRAME: {
+ LOGV("RELEASE_RECORDING_FRAME");
+ CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
+ sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder());
+ releaseRecordingFrame(mem);
+ return NO_ERROR;
+ } break;
+
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
diff --git a/camera/ICameraRecordingProxyListener.cpp b/camera/ICameraRecordingProxyListener.cpp
new file mode 100644
index 0000000..f8cece5
--- /dev/null
+++ b/camera/ICameraRecordingProxyListener.cpp
@@ -0,0 +1,75 @@
+/*
+ * 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.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ICameraRecordingProxyListener"
+#include <camera/ICameraRecordingProxyListener.h>
+#include <binder/IMemory.h>
+#include <binder/Parcel.h>
+#include <utils/Log.h>
+
+namespace android {
+
+enum {
+ DATA_CALLBACK_TIMESTAMP = IBinder::FIRST_CALL_TRANSACTION,
+};
+
+class BpCameraRecordingProxyListener: public BpInterface<ICameraRecordingProxyListener>
+{
+public:
+ BpCameraRecordingProxyListener(const sp<IBinder>& impl)
+ : BpInterface<ICameraRecordingProxyListener>(impl)
+ {
+ }
+
+ void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& imageData)
+ {
+ LOGV("dataCallback");
+ Parcel data, reply;
+ data.writeInterfaceToken(ICameraRecordingProxyListener::getInterfaceDescriptor());
+ data.writeInt64(timestamp);
+ data.writeInt32(msgType);
+ data.writeStrongBinder(imageData->asBinder());
+ remote()->transact(DATA_CALLBACK_TIMESTAMP, data, &reply, IBinder::FLAG_ONEWAY);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(CameraRecordingProxyListener, "android.hardware.ICameraRecordingProxyListener");
+
+// ----------------------------------------------------------------------
+
+status_t BnCameraRecordingProxyListener::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+ switch(code) {
+ case DATA_CALLBACK_TIMESTAMP: {
+ LOGV("DATA_CALLBACK_TIMESTAMP");
+ CHECK_INTERFACE(ICameraRecordingProxyListener, data, reply);
+ nsecs_t timestamp = data.readInt64();
+ int32_t msgType = data.readInt32();
+ sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
+ dataCallbackTimestamp(timestamp, msgType, imageData);
+ return NO_ERROR;
+ } break;
+ default:
+ return BBinder::onTransact(code, data, reply, flags);
+ }
+}
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+