OSDN Git Service

make camcorder ok
[android-x86/frameworks-base.git] / camera / libcameraservice / CameraHardware.cpp
1 /*
2 **
3 ** Copyright 2009, The Android-x86 Open Source Project
4 **
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
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
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.
16 **
17 ** Author: Niels Keeman <nielskeeman@gmail.com>
18 **
19 */
20
21 #define LOG_TAG "CameraHardware"
22 #include <utils/Log.h>
23
24 #include "CameraHardware.h"
25 #include <fcntl.h>
26 #include <sys/mman.h>
27
28 #define VIDEO_DEVICE        "/dev/video0"
29 #define MIN_WIDTH           640
30
31 #define MIN_HEIGHT          480
32 #define PIXEL_FORMAT        V4L2_PIX_FMT_YUYV
33
34 namespace android {
35
36 wp<CameraHardwareInterface> CameraHardware::singleton;
37
38 CameraHardware::CameraHardware()
39                   : mParameters(),
40                     mHeap(0),
41                     mPreviewHeap(0),
42                     mRecordHeap(0),
43                     mRawHeap(0),
44                     mPreviewFrameSize(0),
45                     mCurrentPreviewFrame(0),
46                     mRecordRunning(false),
47                     previewStopped(true),
48                     nQueued(0),
49                     nDequeued(0),
50                     mNotifyFn(NULL),
51                     mDataFn(NULL),
52                     mTimestampFn(NULL),
53                     mUser(NULL)
54 {
55     initDefaultParameters();
56 }
57
58 void CameraHardware::initDefaultParameters()
59 {
60     CameraParameters p;
61
62     p.setPreviewSize(MIN_WIDTH, MIN_HEIGHT);
63     p.setPreviewFrameRate(15);
64     p.setPreviewFormat("yuv422sp");
65
66     p.setPictureSize(MIN_WIDTH, MIN_HEIGHT);
67     p.setPictureFormat("jpeg");
68
69     if (setParameters(p) != NO_ERROR) {
70         LOGE("Failed to set default parameters?!");
71     }
72 }
73
74 CameraHardware::~CameraHardware()
75 {
76     singleton.clear();
77 }
78
79 sp<IMemoryHeap> CameraHardware::getPreviewHeap() const
80 {
81     return mHeap;
82 }
83
84 sp<IMemoryHeap> CameraHardware::getRawHeap() const
85 {
86     return mRawHeap;
87 }
88
89 // ---------------------------------------------------------------------------
90
91 void CameraHardware::setCallbacks(notify_callback notify_cb,
92                                   data_callback data_cb,
93                                   data_callback_timestamp data_cb_timestamp,
94                                   void *arg) {
95     Mutex::Autolock lock(mLock);
96     mNotifyFn = notify_cb;
97     mDataFn = data_cb;
98     mTimestampFn = data_cb_timestamp;
99     mUser = arg;
100 }
101
102 void CameraHardware::enableMsgType(int32_t msgType)
103 {
104     Mutex::Autolock lock(mLock);
105     mMsgEnabled |= msgType;
106 }
107
108 void CameraHardware::disableMsgType(int32_t msgType)
109 {
110     Mutex::Autolock lock(mLock);
111     mMsgEnabled &= ~msgType;
112 }
113
114 bool CameraHardware::msgTypeEnabled(int32_t msgType)
115 {
116     Mutex::Autolock lock(mLock);
117     return (mMsgEnabled & msgType);
118 }
119
120
121 //-------------------------------------------------------------
122 int CameraHardware::previewThread()
123 {
124     if (!previewStopped) {
125         // Get preview frame
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);
133             }
134             mDataFn(CAMERA_MSG_PREVIEW_FRAME,mBuffer, mUser);
135         }
136     }
137
138     return NO_ERROR;
139 }
140
141 status_t CameraHardware::startPreview()
142 {
143     int width, height;
144
145     Mutex::Autolock lock(mLock);
146     if (mPreviewThread != 0) {
147         //already running
148         return INVALID_OPERATION;
149     }
150
151     camera.Open(VIDEO_DEVICE, MIN_WIDTH, MIN_HEIGHT, PIXEL_FORMAT);
152
153     mPreviewFrameSize = MIN_WIDTH * MIN_HEIGHT * 2;
154
155     mHeap = new MemoryHeapBase(mPreviewFrameSize);
156     mBuffer = new MemoryBase(mHeap, 0, mPreviewFrameSize);
157
158     camera.Init();
159     camera.StartStreaming();
160
161     previewStopped = false;
162     mPreviewThread = new PreviewThread(this);
163
164     return NO_ERROR;
165 }
166
167 void CameraHardware::stopPreview()
168 {
169     sp<PreviewThread> previewThread;
170
171     { // scope for the lock
172         Mutex::Autolock lock(mLock);
173         previewStopped = true;
174     }
175
176     if (mPreviewThread != 0) {
177         camera.Uninit();
178         camera.StopStreaming();
179         camera.Close();
180     }
181
182     {
183         Mutex::Autolock lock(mLock);
184         previewThread = mPreviewThread;
185     }
186
187     if (previewThread != 0) {
188         previewThread->requestExitAndWait();
189     }
190
191     Mutex::Autolock lock(mLock);
192     mPreviewThread.clear();
193 }
194
195 bool CameraHardware::previewEnabled()
196 {
197     return mPreviewThread != 0;
198 }
199
200 status_t CameraHardware::startRecording()
201 {
202     Mutex::Autolock lock(mLock);
203
204     mRecordHeap = new MemoryHeapBase(mPreviewFrameSize);
205     mRecordBuffer = new MemoryBase(mRecordHeap, 0, mPreviewFrameSize);
206     mRecordRunning = true;
207
208     return NO_ERROR;
209 }
210
211 void CameraHardware::stopRecording()
212 {
213     mRecordRunning = false;
214 }
215
216 bool CameraHardware::recordingEnabled()
217 {
218     return mRecordRunning;
219 }
220
221 void CameraHardware::releaseRecordingFrame(const sp<IMemory>& mem)
222 {
223 }
224
225 // ---------------------------------------------------------------------------
226
227 int CameraHardware::beginAutoFocusThread(void *cookie)
228 {
229     CameraHardware *c = (CameraHardware *)cookie;
230     return c->autoFocusThread();
231 }
232
233 int CameraHardware::autoFocusThread()
234 {
235     if (mMsgEnabled & CAMERA_MSG_FOCUS)
236         mNotifyFn(CAMERA_MSG_FOCUS, true, 0, mUser);
237     return NO_ERROR;
238 }
239
240 status_t CameraHardware::autoFocus()
241 {
242     Mutex::Autolock lock(mLock);
243     if (createThread(beginAutoFocusThread, this) == false)
244         return UNKNOWN_ERROR;
245     return NO_ERROR;
246 }
247
248 status_t CameraHardware::cancelAutoFocus()
249 {
250     return NO_ERROR;
251 }
252
253 /*static*/ int CameraHardware::beginPictureThread(void *cookie)
254 {
255     CameraHardware *c = (CameraHardware *)cookie;
256     return c->pictureThread();
257 }
258
259 int CameraHardware::pictureThread()
260 {
261     unsigned char *frame;
262     int bufferSize;
263     int w,h;
264     int ret;
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;
270
271
272    if (mMsgEnabled & CAMERA_MSG_SHUTTER)
273         mNotifyFn(CAMERA_MSG_SHUTTER, 0, 0, mUser);
274
275     mParameters.getPictureSize(&w, &h);
276     LOGD("Picture Size: Width = %d \t Height = %d", w, h);
277
278     int width, height;
279     mParameters.getPictureSize(&width, &height);
280     camera.Open(VIDEO_DEVICE, MIN_WIDTH, MIN_HEIGHT, PIXEL_FORMAT);
281     camera.Init();
282     camera.StartStreaming();
283
284     if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) {
285         LOGD ("mJpegPictureCallback");
286         mDataFn(CAMERA_MSG_COMPRESSED_IMAGE, camera.GrabJpegFrame(),mUser);
287     }
288
289     camera.Uninit();
290     camera.StopStreaming();
291     camera.Close();
292
293     return NO_ERROR;
294 }
295
296 status_t CameraHardware::takePicture()
297 {
298     stopPreview();
299     //if (createThread(beginPictureThread, this) == false)
300     //    return -1;
301
302     pictureThread();
303
304     return NO_ERROR;
305 }
306
307 status_t CameraHardware::cancelPicture()
308 {
309
310     return NO_ERROR;
311 }
312
313 status_t CameraHardware::dump(int fd, const Vector<String16>& args) const
314 {
315     return NO_ERROR;
316 }
317
318 status_t CameraHardware::setParameters(const CameraParameters& params)
319 {
320     Mutex::Autolock lock(mLock);
321
322     if (strcmp(params.getPreviewFormat(), "yuv422sp") != 0) {
323         LOGE("Only yuv422sp preview is supported");
324         return -1;
325     }
326
327     if (strcmp(params.getPictureFormat(), "jpeg") != 0) {
328         LOGE("Only jpeg still pictures are supported");
329         return -1;
330     }
331
332     int w, h;
333     int framerate;
334
335     params.getPreviewSize(&w, &h);
336     framerate = params.getPreviewFrameRate();
337     LOGD("PREVIEW SIZE: w=%d h=%d framerate=%d", w, h, framerate);
338
339     params.getPictureSize(&w, &h);
340
341     mParameters = params;
342
343     // Set to fixed sizes
344     mParameters.setPreviewSize(MIN_WIDTH,MIN_HEIGHT);
345
346     return NO_ERROR;
347 }
348
349 status_t CameraHardware::sendCommand(int32_t command, int32_t arg1,
350                                          int32_t arg2)
351 {
352     return BAD_VALUE;
353 }
354
355 CameraParameters CameraHardware::getParameters() const
356 {
357     CameraParameters params;
358
359     {
360     Mutex::Autolock lock(mLock);
361         params = mParameters;
362     }
363
364     return params;
365 }
366
367 void CameraHardware::release()
368 {
369     close(camera_device);
370 }
371
372 sp<CameraHardwareInterface> CameraHardware::createInstance()
373 {
374     if (singleton != 0) {
375         sp<CameraHardwareInterface> hardware = singleton.promote();
376         if (hardware != 0) {
377             return hardware;
378         }
379     }
380     sp<CameraHardwareInterface> hardware(new CameraHardware());
381     singleton = hardware;
382     return hardware;
383 }
384
385 extern "C" sp<CameraHardwareInterface> openCameraHardware()
386 {
387     return CameraHardware::createInstance();
388 }
389 }; // namespace android