Backout a74bd5095902, Bug 959405 - Please update the Buri Moz-central, 1.3, 1.2 with...
[gecko.git] / dom / camera / GonkCameraHwMgr.cpp
blobef54b6f1e293dc4083001a5844e89966f5e9887a
1 /*
2 * Copyright (C) 2012 Mozilla Foundation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 #include <binder/IPCThreadState.h>
18 #include <sys/system_properties.h>
20 #include "base/basictypes.h"
21 #include "nsDebug.h"
22 #include "GonkCameraControl.h"
23 #include "GonkCameraHwMgr.h"
24 #include "GonkNativeWindow.h"
25 #include "CameraCommon.h"
27 using namespace mozilla;
28 using namespace mozilla::layers;
29 using namespace android;
31 #if GIHM_TIMING_RECEIVEFRAME
32 #define INCLUDE_TIME_H 1
33 #endif
34 #if GIHM_TIMING_OVERALL
35 #define INCLUDE_TIME_H 1
36 #endif
38 #if INCLUDE_TIME_H
39 #include <time.h>
41 static __inline void timespecSubtract(struct timespec* a, struct timespec* b)
43 // a = b - a
44 if (b->tv_nsec < a->tv_nsec) {
45 b->tv_nsec += 1000000000;
46 b->tv_sec -= 1;
48 a->tv_nsec = b->tv_nsec - a->tv_nsec;
49 a->tv_sec = b->tv_sec - a->tv_sec;
51 #endif
53 GonkCameraHardware::GonkCameraHardware(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId, const sp<Camera>& aCamera)
54 : mCameraId(aCameraId)
55 , mClosing(false)
56 , mMonitor("GonkCameraHardware.Monitor")
57 , mNumFrames(0)
58 , mCamera(aCamera)
59 , mTarget(aTarget)
60 , mInitialized(false)
61 , mSensorOrientation(0)
63 DOM_CAMERA_LOGT( "%s:%d : this=%p (aTarget=%p)\n", __func__, __LINE__, (void*)this, (void*)aTarget );
64 Init();
67 void
68 GonkCameraHardware::OnNewFrame()
70 if (mClosing) {
71 return;
73 nsRefPtr<GraphicBufferLocked> buffer = mNativeWindow->getCurrentBuffer();
74 if (!buffer) {
75 DOM_CAMERA_LOGW("received null frame");
76 return;
78 ReceiveFrame(mTarget, buffer);
81 // Android data callback
82 void
83 GonkCameraHardware::postData(int32_t aMsgType, const sp<IMemory>& aDataPtr, camera_frame_metadata_t* metadata)
85 if (mClosing) {
86 return;
89 switch (aMsgType) {
90 case CAMERA_MSG_PREVIEW_FRAME:
91 // Do nothing
92 break;
94 case CAMERA_MSG_COMPRESSED_IMAGE:
95 if (aDataPtr != nullptr) {
96 ReceiveImage(mTarget, (uint8_t*)aDataPtr->pointer(), aDataPtr->size());
97 } else {
98 ReceiveImageError(mTarget);
100 break;
102 default:
103 DOM_CAMERA_LOGE("Unhandled data callback event %d\n", aMsgType);
104 break;
108 // Android notify callback
109 void
110 GonkCameraHardware::notify(int32_t aMsgType, int32_t ext1, int32_t ext2)
112 bool bSuccess;
113 if (mClosing) {
114 return;
117 switch (aMsgType) {
118 case CAMERA_MSG_FOCUS:
119 if (ext1) {
120 DOM_CAMERA_LOGI("Autofocus complete");
121 bSuccess = true;
122 } else {
123 DOM_CAMERA_LOGW("Autofocus failed");
124 bSuccess = false;
126 AutoFocusComplete(mTarget, bSuccess);
127 break;
129 case CAMERA_MSG_SHUTTER:
130 OnShutter(mTarget);
131 break;
133 default:
134 DOM_CAMERA_LOGE("Unhandled notify callback event %d\n", aMsgType);
135 break;
139 void
140 GonkCameraHardware::postDataTimestamp(nsecs_t aTimestamp, int32_t aMsgType, const sp<IMemory>& aDataPtr)
142 DOM_CAMERA_LOGI("%s",__func__);
143 if (mClosing) {
144 return;
147 if (mListener.get()) {
148 DOM_CAMERA_LOGI("Listener registered, posting recording frame!");
149 mListener->postDataTimestamp(aTimestamp, aMsgType, aDataPtr);
150 } else {
151 DOM_CAMERA_LOGW("No listener was set. Drop a recording frame.");
152 mCamera->releaseRecordingFrame(aDataPtr);
156 void
157 GonkCameraHardware::Init()
159 DOM_CAMERA_LOGT("%s: this=%p\n", __func__, (void* )this);
161 CameraInfo info;
162 int rv = Camera::getCameraInfo(mCameraId, &info);
163 if (rv != 0) {
164 DOM_CAMERA_LOGE("%s: failed to get CameraInfo mCameraId %d\n", __func__, mCameraId);
165 return;
168 mRawSensorOrientation = info.orientation;
169 mSensorOrientation = mRawSensorOrientation;
172 * Non-V4L2-based camera driver adds extra offset onto picture orientation
173 * set by gecko, so we have to adjust it back.
175 char propname[PROP_NAME_MAX];
176 char prop[PROP_VALUE_MAX];
177 int offset = 0;
178 snprintf(propname, sizeof(propname), "ro.moz.cam.%d.sensor_offset", mCameraId);
179 if (__system_property_get(propname, prop) > 0) {
180 offset = clamped(atoi(prop), 0, 270);
181 mSensorOrientation += offset;
182 mSensorOrientation %= 360;
184 DOM_CAMERA_LOGI("Sensor orientation: base=%d, offset=%d, final=%d\n", info.orientation, offset, mSensorOrientation);
186 // Disable shutter sound in android CameraService because gaia camera app will play it
187 mCamera->sendCommand(CAMERA_CMD_ENABLE_SHUTTER_SOUND, 0, 0);
189 mNativeWindow = new GonkNativeWindow();
190 mNativeWindow->setNewFrameCallback(this);
191 mCamera->setListener(this);
192 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
193 mCamera->setPreviewTexture(mNativeWindow->getBufferQueue());
194 #else
195 mCamera->setPreviewTexture(mNativeWindow);
196 #endif
197 mInitialized = true;
200 sp<GonkCameraHardware>
201 GonkCameraHardware::Connect(mozilla::nsGonkCameraControl* aTarget, uint32_t aCameraId)
203 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
204 sp<Camera> camera = Camera::connect(aCameraId, /* clientPackageName */String16("gonk.camera"), Camera::USE_CALLING_UID);
205 #else
206 sp<Camera> camera = Camera::connect(aCameraId);
207 #endif
210 if (camera.get() == nullptr) {
211 return nullptr;
213 sp<GonkCameraHardware> cameraHardware = new GonkCameraHardware(aTarget, aCameraId, camera);
214 return cameraHardware;
217 void
218 GonkCameraHardware::Close()
220 DOM_CAMERA_LOGT( "%s:%d : this=%p\n", __func__, __LINE__, (void*)this );
222 mClosing = true;
223 mCamera->stopPreview();
224 mCamera->disconnect();
225 if (mNativeWindow.get()) {
226 mNativeWindow->abandon();
228 mCamera.clear();
229 mNativeWindow.clear();
231 // Ensure that ICamera's destructor is actually executed
232 IPCThreadState::self()->flushCommands();
235 GonkCameraHardware::~GonkCameraHardware()
237 DOM_CAMERA_LOGT( "%s:%d : this=%p\n", __func__, __LINE__, (void*)this );
238 mCamera.clear();
239 mNativeWindow.clear();
241 if (mClosing) {
242 return;
246 * Trigger the OnClosed event; the upper layers can't do anything
247 * with the hardware layer once they receive this event.
249 if (mTarget) {
250 OnClosed(mTarget);
255 GonkCameraHardware::GetSensorOrientation(uint32_t aType)
257 DOM_CAMERA_LOGI("%s\n", __func__);
259 switch (aType) {
260 case OFFSET_SENSOR_ORIENTATION:
261 return mSensorOrientation;
263 case RAW_SENSOR_ORIENTATION:
264 return mRawSensorOrientation;
266 default:
267 DOM_CAMERA_LOGE("%s:%d : unknown aType=%d\n", __func__, __LINE__, aType);
268 return 0;
273 GonkCameraHardware::AutoFocus()
275 DOM_CAMERA_LOGI("%s\n", __func__);
276 return mCamera->autoFocus();
279 void
280 GonkCameraHardware::CancelAutoFocus()
282 DOM_CAMERA_LOGI("%s\n", __func__);
283 mCamera->cancelAutoFocus();
287 GonkCameraHardware::TakePicture()
289 return mCamera->takePicture(CAMERA_MSG_SHUTTER | CAMERA_MSG_COMPRESSED_IMAGE);
292 void
293 GonkCameraHardware::CancelTakePicture()
295 DOM_CAMERA_LOGW("%s: android::Camera do not provide this capability\n", __func__);
299 GonkCameraHardware::PushParameters(const CameraParameters& aParams)
301 String8 s = aParams.flatten();
302 return mCamera->setParameters(s);
305 void
306 GonkCameraHardware::PullParameters(CameraParameters& aParams)
308 const String8 s = mCamera->getParameters();
309 aParams.unflatten(s);
313 GonkCameraHardware::StartPreview()
315 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
316 return mCamera->startPreview();
319 void
320 GonkCameraHardware::StopPreview()
322 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
323 return mCamera->stopPreview();
327 GonkCameraHardware::StartRecording()
329 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
330 int rv = OK;
332 rv = mCamera->startRecording();
333 if (rv != OK) {
334 DOM_CAMERA_LOGE("mHardware->startRecording() failed with status %d", rv);
336 return rv;
340 GonkCameraHardware::StopRecording()
342 DOM_CAMERA_LOGT("%s:%d : this=%p\n", __func__, __LINE__, this);
343 mCamera->stopRecording();
344 return OK;
348 GonkCameraHardware::SetListener(const sp<GonkCameraListener>& aListener)
350 mListener = aListener;
351 return OK;
354 void
355 GonkCameraHardware::ReleaseRecordingFrame(const sp<IMemory>& aFrame)
357 mCamera->releaseRecordingFrame(aFrame);
361 GonkCameraHardware::StoreMetaDataInBuffers(bool aEnabled)
363 return mCamera->storeMetaDataInBuffers(aEnabled);