3 ** Copyright 2009, The Android-x86 Open Source Project
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
9 ** http://www.apache.org/licenses/LICENSE-2.0
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
17 ** Author: Niels Keeman <nielskeeman@gmail.com>
21 #define LOG_TAG "CameraHardware"
22 #include <utils/Log.h>
24 #include "CameraHardware.h"
28 #define VIDEO_DEVICE "/dev/video0"
31 #define MIN_HEIGHT 480
32 #define PIXEL_FORMAT V4L2_PIX_FMT_YUYV
36 wp<CameraHardwareInterface> CameraHardware::singleton;
38 CameraHardware::CameraHardware()
45 mCurrentPreviewFrame(0),
46 mRecordRunning(false),
55 initDefaultParameters();
58 void CameraHardware::initDefaultParameters()
62 p.setPreviewSize(MIN_WIDTH, MIN_HEIGHT);
63 p.setPreviewFrameRate(15);
64 p.setPreviewFormat("yuv422sp");
66 p.setPictureSize(MIN_WIDTH, MIN_HEIGHT);
67 p.setPictureFormat("jpeg");
69 if (setParameters(p) != NO_ERROR) {
70 LOGE("Failed to set default parameters?!");
74 CameraHardware::~CameraHardware()
79 sp<IMemoryHeap> CameraHardware::getPreviewHeap() const
84 sp<IMemoryHeap> CameraHardware::getRawHeap() const
89 // ---------------------------------------------------------------------------
91 void CameraHardware::setCallbacks(notify_callback notify_cb,
92 data_callback data_cb,
93 data_callback_timestamp data_cb_timestamp,
95 Mutex::Autolock lock(mLock);
96 mNotifyFn = notify_cb;
98 mTimestampFn = data_cb_timestamp;
102 void CameraHardware::enableMsgType(int32_t msgType)
104 Mutex::Autolock lock(mLock);
105 mMsgEnabled |= msgType;
108 void CameraHardware::disableMsgType(int32_t msgType)
110 Mutex::Autolock lock(mLock);
111 mMsgEnabled &= ~msgType;
114 bool CameraHardware::msgTypeEnabled(int32_t msgType)
116 Mutex::Autolock lock(mLock);
117 return (mMsgEnabled & msgType);
121 //-------------------------------------------------------------
122 int CameraHardware::previewThread()
124 if (!previewStopped) {
126 camera.GrabPreviewFrame(mHeap->getBase());
127 if ((mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) ||
128 (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME)) {
129 if (mMsgEnabled & CAMERA_MSG_VIDEO_FRAME) {
130 camera.GrabRecordFrame(mRecordHeap->getBase());
131 nsecs_t timeStamp = systemTime(SYSTEM_TIME_MONOTONIC);
132 mTimestampFn(timeStamp, CAMERA_MSG_VIDEO_FRAME,mRecordBuffer, mUser);
134 mDataFn(CAMERA_MSG_PREVIEW_FRAME,mBuffer, mUser);
141 status_t CameraHardware::startPreview()
145 Mutex::Autolock lock(mLock);
146 if (mPreviewThread != 0) {
148 return INVALID_OPERATION;
151 camera.Open(VIDEO_DEVICE, MIN_WIDTH, MIN_HEIGHT, PIXEL_FORMAT);
153 mPreviewFrameSize = MIN_WIDTH * MIN_HEIGHT * 2;
155 mHeap = new MemoryHeapBase(mPreviewFrameSize);
156 mBuffer = new MemoryBase(mHeap, 0, mPreviewFrameSize);
159 camera.StartStreaming();
161 previewStopped = false;
162 mPreviewThread = new PreviewThread(this);
167 void CameraHardware::stopPreview()
169 sp<PreviewThread> previewThread;
171 { // scope for the lock
172 Mutex::Autolock lock(mLock);
173 previewStopped = true;
176 if (mPreviewThread != 0) {
178 camera.StopStreaming();
183 Mutex::Autolock lock(mLock);
184 previewThread = mPreviewThread;
187 if (previewThread != 0) {
188 previewThread->requestExitAndWait();
191 Mutex::Autolock lock(mLock);
192 mPreviewThread.clear();
195 bool CameraHardware::previewEnabled()
197 return mPreviewThread != 0;
200 status_t CameraHardware::startRecording()
202 Mutex::Autolock lock(mLock);
204 mRecordHeap = new MemoryHeapBase(mPreviewFrameSize);
205 mRecordBuffer = new MemoryBase(mRecordHeap, 0, mPreviewFrameSize);
206 mRecordRunning = true;
211 void CameraHardware::stopRecording()
213 mRecordRunning = false;
216 bool CameraHardware::recordingEnabled()
218 return mRecordRunning;
221 void CameraHardware::releaseRecordingFrame(const sp<IMemory>& mem)
225 // ---------------------------------------------------------------------------
227 int CameraHardware::beginAutoFocusThread(void *cookie)
229 CameraHardware *c = (CameraHardware *)cookie;
230 return c->autoFocusThread();
233 int CameraHardware::autoFocusThread()
235 if (mMsgEnabled & CAMERA_MSG_FOCUS)
236 mNotifyFn(CAMERA_MSG_FOCUS, true, 0, mUser);
240 status_t CameraHardware::autoFocus()
242 Mutex::Autolock lock(mLock);
243 if (createThread(beginAutoFocusThread, this) == false)
244 return UNKNOWN_ERROR;
248 status_t CameraHardware::cancelAutoFocus()
253 /*static*/ int CameraHardware::beginPictureThread(void *cookie)
255 CameraHardware *c = (CameraHardware *)cookie;
256 return c->pictureThread();
259 int CameraHardware::pictureThread()
261 unsigned char *frame;
265 struct v4l2_buffer buffer;
266 struct v4l2_format format;
267 struct v4l2_buffer cfilledbuffer;
268 struct v4l2_requestbuffers creqbuf;
269 struct v4l2_capability cap;
272 if (mMsgEnabled & CAMERA_MSG_SHUTTER)
273 mNotifyFn(CAMERA_MSG_SHUTTER, 0, 0, mUser);
275 mParameters.getPictureSize(&w, &h);
276 LOGD("Picture Size: Width = %d \t Height = %d", w, h);
279 mParameters.getPictureSize(&width, &height);
280 camera.Open(VIDEO_DEVICE, MIN_WIDTH, MIN_HEIGHT, PIXEL_FORMAT);
282 camera.StartStreaming();
284 if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) {
285 LOGD ("mJpegPictureCallback");
286 mDataFn(CAMERA_MSG_COMPRESSED_IMAGE, camera.GrabJpegFrame(),mUser);
290 camera.StopStreaming();
296 status_t CameraHardware::takePicture()
299 //if (createThread(beginPictureThread, this) == false)
307 status_t CameraHardware::cancelPicture()
313 status_t CameraHardware::dump(int fd, const Vector<String16>& args) const
318 status_t CameraHardware::setParameters(const CameraParameters& params)
320 Mutex::Autolock lock(mLock);
322 if (strcmp(params.getPreviewFormat(), "yuv422sp") != 0) {
323 LOGE("Only yuv422sp preview is supported");
327 if (strcmp(params.getPictureFormat(), "jpeg") != 0) {
328 LOGE("Only jpeg still pictures are supported");
335 params.getPreviewSize(&w, &h);
336 framerate = params.getPreviewFrameRate();
337 LOGD("PREVIEW SIZE: w=%d h=%d framerate=%d", w, h, framerate);
339 params.getPictureSize(&w, &h);
341 mParameters = params;
343 // Set to fixed sizes
344 mParameters.setPreviewSize(MIN_WIDTH,MIN_HEIGHT);
349 status_t CameraHardware::sendCommand(int32_t command, int32_t arg1,
355 CameraParameters CameraHardware::getParameters() const
357 CameraParameters params;
360 Mutex::Autolock lock(mLock);
361 params = mParameters;
367 void CameraHardware::release()
369 close(camera_device);
372 sp<CameraHardwareInterface> CameraHardware::createInstance()
374 if (singleton != 0) {
375 sp<CameraHardwareInterface> hardware = singleton.promote();
380 sp<CameraHardwareInterface> hardware(new CameraHardware());
381 singleton = hardware;
385 extern "C" sp<CameraHardwareInterface> openCameraHardware()
387 return CameraHardware::createInstance();
389 }; // namespace android