3 ** Copyright 2008, The Android 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.
18 #define LOG_TAG "CameraHardwareStub"
19 #include <utils/Log.h>
21 #include "CameraHardwareStub.h"
22 #include <utils/threads.h>
26 #include "CannedJpeg.h"
30 CameraHardwareStub::CameraHardwareStub()
35 mRawPictureCallback(0),
36 mJpegPictureCallback(0),
37 mPictureCallbackCookie(0),
39 mPreviewCallbackCookie(0),
40 mAutoFocusCallback(0),
41 mAutoFocusCallbackCookie(0),
42 mCurrentPreviewFrame(0)
44 initDefaultParameters();
47 void CameraHardwareStub::initDefaultParameters()
51 p.setPreviewSize(176, 144);
52 p.setPreviewFrameRate(15);
53 p.setPreviewFormat("yuv422sp");
55 p.setPictureSize(kCannedJpegWidth, kCannedJpegHeight);
56 p.setPictureFormat("jpeg");
58 if (setParameters(p) != NO_ERROR) {
59 LOGE("Failed to set default parameters?!");
63 void CameraHardwareStub::initHeapLocked()
66 mParameters.getPreviewSize(&width, &height);
68 LOGD("initHeapLocked: preview size=%dx%d", width, height);
70 // Note that we enforce yuv422 in setParameters().
71 int how_big = width * height * 2;
73 // If we are being reinitialized to the same size as before, no
74 // work needs to be done.
75 if (how_big == mPreviewFrameSize)
78 mPreviewFrameSize = how_big;
80 // Make a new mmap'ed heap that can be shared across processes.
81 // use code below to test with pmem
82 mHeap = new MemoryHeapBase(mPreviewFrameSize * kBufferCount);
83 // Make an IMemory for each frame so that we can reuse them in callbacks.
84 for (int i = 0; i < kBufferCount; i++) {
85 mBuffers[i] = new MemoryBase(mHeap, i * mPreviewFrameSize, mPreviewFrameSize);
88 // Recreate the fake camera to reflect the current size.
90 mFakeCamera = new FakeCamera(width, height);
93 CameraHardwareStub::~CameraHardwareStub()
96 mFakeCamera = 0; // paranoia
100 sp<IMemoryHeap> CameraHardwareStub::getPreviewHeap() const
105 // ---------------------------------------------------------------------------
107 int CameraHardwareStub::previewThread()
110 // the attributes below can change under our feet...
112 int previewFrameRate = mParameters.getPreviewFrameRate();
114 // Find the offset within the heap of the current buffer.
115 ssize_t offset = mCurrentPreviewFrame * mPreviewFrameSize;
117 sp<MemoryHeapBase> heap = mHeap;
119 // this assumes the internal state of fake camera doesn't change
120 // (or is thread safe)
121 FakeCamera* fakeCamera = mFakeCamera;
123 sp<MemoryBase> buffer = mBuffers[mCurrentPreviewFrame];
127 // TODO: here check all the conditions that could go wrong
129 // Calculate how long to wait between frames.
130 int delay = (int)(1000000.0f / float(previewFrameRate));
132 // This is always valid, even if the client died -- the memory
133 // is still mapped in our process.
134 void *base = heap->base();
136 // Fill the current frame with the fake camera.
137 uint8_t *frame = ((uint8_t *)base) + offset;
138 fakeCamera->getNextFrameAsYuv422(frame);
140 //LOGV("previewThread: generated frame to buffer %d", mCurrentPreviewFrame);
142 // Notify the client of a new frame.
143 mPreviewCallback(buffer, mPreviewCallbackCookie);
145 // Advance the buffer pointer.
146 mCurrentPreviewFrame = (mCurrentPreviewFrame + 1) % kBufferCount;
155 status_t CameraHardwareStub::startPreview(preview_callback cb, void* user)
157 Mutex::Autolock lock(mLock);
158 if (mPreviewThread != 0) {
160 return INVALID_OPERATION;
162 mPreviewCallback = cb;
163 mPreviewCallbackCookie = user;
164 mPreviewThread = new PreviewThread(this);
168 void CameraHardwareStub::stopPreview()
170 sp<PreviewThread> previewThread;
172 { // scope for the lock
173 Mutex::Autolock lock(mLock);
174 previewThread = mPreviewThread;
177 // don't hold the lock while waiting for the thread to quit
178 if (previewThread != 0) {
179 previewThread->requestExitAndWait();
182 Mutex::Autolock lock(mLock);
183 mPreviewThread.clear();
186 bool CameraHardwareStub::previewEnabled() {
187 return mPreviewThread != 0;
190 status_t CameraHardwareStub::startRecording(recording_callback cb, void* user)
192 return UNKNOWN_ERROR;
195 void CameraHardwareStub::stopRecording()
199 bool CameraHardwareStub::recordingEnabled()
204 void CameraHardwareStub::releaseRecordingFrame(const sp<IMemory>& mem)
208 // ---------------------------------------------------------------------------
210 int CameraHardwareStub::beginAutoFocusThread(void *cookie)
212 CameraHardwareStub *c = (CameraHardwareStub *)cookie;
213 return c->autoFocusThread();
216 int CameraHardwareStub::autoFocusThread()
218 if (mAutoFocusCallback != NULL) {
219 mAutoFocusCallback(true, mAutoFocusCallbackCookie);
220 mAutoFocusCallback = NULL;
223 return UNKNOWN_ERROR;
226 status_t CameraHardwareStub::autoFocus(autofocus_callback af_cb,
229 Mutex::Autolock lock(mLock);
231 if (mAutoFocusCallback != NULL) {
232 return mAutoFocusCallback == af_cb ? NO_ERROR : INVALID_OPERATION;
235 mAutoFocusCallback = af_cb;
236 mAutoFocusCallbackCookie = user;
237 if (createThread(beginAutoFocusThread, this) == false)
238 return UNKNOWN_ERROR;
242 /*static*/ int CameraHardwareStub::beginPictureThread(void *cookie)
244 CameraHardwareStub *c = (CameraHardwareStub *)cookie;
245 return c->pictureThread();
248 int CameraHardwareStub::pictureThread()
250 if (mShutterCallback)
251 mShutterCallback(mPictureCallbackCookie);
253 if (mRawPictureCallback) {
254 //FIXME: use a canned YUV image!
255 // In the meantime just make another fake camera picture.
257 mParameters.getPictureSize(&w, &h);
258 sp<MemoryHeapBase> heap = new MemoryHeapBase(w * 2 * h);
259 sp<MemoryBase> mem = new MemoryBase(heap, 0, w * 2 * h);
260 FakeCamera cam(w, h);
261 cam.getNextFrameAsYuv422((uint8_t *)heap->base());
262 if (mRawPictureCallback)
263 mRawPictureCallback(mem, mPictureCallbackCookie);
266 if (mJpegPictureCallback) {
267 sp<MemoryHeapBase> heap = new MemoryHeapBase(kCannedJpegSize);
268 sp<MemoryBase> mem = new MemoryBase(heap, 0, kCannedJpegSize);
269 memcpy(heap->base(), kCannedJpeg, kCannedJpegSize);
270 if (mJpegPictureCallback)
271 mJpegPictureCallback(mem, mPictureCallbackCookie);
276 status_t CameraHardwareStub::takePicture(shutter_callback shutter_cb,
278 jpeg_callback jpeg_cb,
282 mShutterCallback = shutter_cb;
283 mRawPictureCallback = raw_cb;
284 mJpegPictureCallback = jpeg_cb;
285 mPictureCallbackCookie = user;
286 if (createThread(beginPictureThread, this) == false)
291 status_t CameraHardwareStub::cancelPicture(bool cancel_shutter,
295 if (cancel_shutter) mShutterCallback = NULL;
296 if (cancel_raw) mRawPictureCallback = NULL;
297 if (cancel_jpeg) mJpegPictureCallback = NULL;
301 status_t CameraHardwareStub::dump(int fd, const Vector<String16>& args) const
303 const size_t SIZE = 256;
306 AutoMutex lock(&mLock);
307 if (mFakeCamera != 0) {
308 mFakeCamera->dump(fd, args);
309 mParameters.dump(fd, args);
310 snprintf(buffer, 255, " preview frame(%d), size (%d), running(%s)\n", mCurrentPreviewFrame, mPreviewFrameSize, mPreviewRunning?"true": "false");
311 result.append(buffer);
313 result.append("No camera client yet.\n");
315 write(fd, result.string(), result.size());
319 status_t CameraHardwareStub::setParameters(const CameraParameters& params)
321 Mutex::Autolock lock(mLock);
324 if (strcmp(params.getPreviewFormat(), "yuv422sp") != 0) {
325 LOGE("Only yuv422sp preview is supported");
329 if (strcmp(params.getPictureFormat(), "jpeg") != 0) {
330 LOGE("Only jpeg still pictures are supported");
335 params.getPictureSize(&w, &h);
336 if (w != kCannedJpegWidth && h != kCannedJpegHeight) {
337 LOGE("Still picture size must be size of canned JPEG (%dx%d)",
338 kCannedJpegWidth, kCannedJpegHeight);
342 mParameters = params;
349 CameraParameters CameraHardwareStub::getParameters() const
351 Mutex::Autolock lock(mLock);
355 void CameraHardwareStub::release()
359 wp<CameraHardwareInterface> CameraHardwareStub::singleton;
361 sp<CameraHardwareInterface> CameraHardwareStub::createInstance()
363 if (singleton != 0) {
364 sp<CameraHardwareInterface> hardware = singleton.promote();
369 sp<CameraHardwareInterface> hardware(new CameraHardwareStub());
370 singleton = hardware;
374 extern "C" sp<CameraHardwareInterface> openCameraHardware()
376 return CameraHardwareStub::createInstance();
379 }; // namespace android