• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Aucun tag

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

frameworks/base


Commit MetaInfo

Révisiond5a403fef350592255cc99ee9b1db63973d6dc99 (tree)
l'heure2010-02-27 17:47:44
AuteurJeremy Chang <jeremy@0xla...>
CommiterChih-Wei Huang

Message de Log

bring up video recording function from 0xlab.org

Change Summary

Modification

--- a/camera/libcameraservice/Android.mk
+++ b/camera/libcameraservice/Android.mk
@@ -8,7 +8,8 @@ include $(CLEAR_VARS)
88
99 LOCAL_SRC_FILES:= \
1010 CameraHardware.cpp \
11- V4L2Camera.cpp
11+ V4L2Camera.cpp \
12+ converter.cpp
1213
1314 LOCAL_CFLAGS += -Iexternal/jpeg
1415
--- a/camera/libcameraservice/CameraHardware.cpp
+++ b/camera/libcameraservice/CameraHardware.cpp
@@ -1,5 +1,6 @@
11 /*
22 **
3+** Copyright (C) 2009 0xlab.org - http://0xlab.org/
34 ** Copyright 2008, The Android Open Source Project
45 **
56 ** Licensed under the Apache License, Version 2.0 (the "License");
@@ -19,15 +20,23 @@
1920 #include <utils/Log.h>
2021
2122 #include "CameraHardware.h"
23+#include "converter.h"
2224 #include <fcntl.h>
2325 #include <sys/mman.h>
2426
2527 #define VIDEO_DEVICE "/dev/video0"
26-#define MIN_WIDTH 640
27-
28-#define MIN_HEIGHT 480
28+#define PREVIEW_WIDTH 352
29+#define PREVIEW_HEIGHT 288
30+#define PICTURE_WIDTH 1600 /* 2MP */
31+#define PICTURE_HEIGHT 1200 /* 2MP */
2932 #define PIXEL_FORMAT V4L2_PIX_FMT_YUYV
3033
34+#include <cutils/properties.h>
35+#ifndef UNLIKELY
36+#define UNLIKELY(exp) (__builtin_expect( (exp) != 0, false ))
37+#endif
38+static int mDebugFps = 0;
39+
3140 namespace android {
3241
3342 wp<CameraHardwareInterface> CameraHardware::singleton;
@@ -37,7 +46,10 @@ CameraHardware::CameraHardware()
3746 mHeap(0),
3847 mPreviewHeap(0),
3948 mRawHeap(0),
40- mPreviewFrameSize(0),
49+ mPreviewFrameSize(0),
50+ mRecordingFrameSize(0),
51+ mRecordingCallback(0),
52+ mRecordingCallbackCookie(0),
4153 mRawPictureCallback(0),
4254 mJpegPictureCallback(0),
4355 mPictureCallbackCookie(0),
@@ -45,24 +57,28 @@ CameraHardware::CameraHardware()
4557 mPreviewCallbackCookie(0),
4658 mAutoFocusCallback(0),
4759 mAutoFocusCallbackCookie(0),
48- mCurrentPreviewFrame(0),
49- previewStopped(true),
50- nQueued(0),
51- nDequeued(0)
60+ previewStopped(true)
5261 {
5362 initDefaultParameters();
63+ /* whether prop "debug.camera.showfps" is enabled or not */
64+ char value[PROPERTY_VALUE_MAX];
65+ property_get("debug.camera.showfps", value, "0");
66+ mDebugFps = atoi(value);
67+ LOGD_IF(mDebugFps, "showfps enabled");
5468 }
5569
5670 void CameraHardware::initDefaultParameters()
5771 {
5872 CameraParameters p;
5973
60- p.setPreviewSize(MIN_WIDTH, MIN_HEIGHT);
61- p.setPreviewFrameRate(15);
74+ p.setPreviewSize(PREVIEW_WIDTH, PREVIEW_HEIGHT);
75+ p.setPreviewFrameRate(DEFAULT_FRAME_RATE);
6276 p.setPreviewFormat("yuv422sp");
63-
64- p.setPictureSize(MIN_WIDTH, MIN_HEIGHT);
6577 p.setPictureFormat("jpeg");
78+ p.setPictureSize(PREVIEW_WIDTH, PREVIEW_HEIGHT);
79+
80+ p.set("jpeg-quality", "100"); // maximum quality
81+ p.set("picture-size-values", "1600x1200,1024x768,640x480,352x288");
6682
6783 if (setParameters(p) != NO_ERROR) {
6884 LOGE("Failed to set default parameters?!");
@@ -76,7 +92,7 @@ CameraHardware::~CameraHardware()
7692
7793 sp<IMemoryHeap> CameraHardware::getPreviewHeap() const
7894 {
79- return mHeap;
95+ return mPreviewHeap;
8096 }
8197
8298 sp<IMemoryHeap> CameraHardware::getRawHeap() const
@@ -85,13 +101,59 @@ sp<IMemoryHeap> CameraHardware::getRawHeap() const
85101 }
86102
87103 // ---------------------------------------------------------------------------
104+static void showFPS(const char *tag)
105+{
106+ static int mFrameCount = 0;
107+ static int mLastFrameCount = 0;
108+ static nsecs_t mLastFpsTime = 0;
109+ static float mFps = 0;
110+ mFrameCount++;
111+ if (!(mFrameCount & 0x1F)) {
112+ nsecs_t now = systemTime();
113+ nsecs_t diff = now - mLastFpsTime;
114+ mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
115+ mLastFpsTime = now;
116+ mLastFrameCount = mFrameCount;
117+ LOGD("[%s] %d Frames, %f FPS", tag, mFrameCount, mFps);
118+ }
119+}
88120
89121 int CameraHardware::previewThread()
90122 {
123+ Mutex::Autolock lock(mPreviewLock);
91124 if (!previewStopped) {
92- // Get preview frame
93- camera.GrabPreviewFrame(mHeap->getBase());
94- mPreviewCallback(mBuffer, mPreviewCallbackCookie);
125+
126+ camera.GrabRawFrame(mRawHeap->getBase());
127+
128+ if (mRecordingCallback) {
129+ yuyv422_to_yuv420sp((unsigned char *)mRawHeap->getBase(),
130+ (unsigned char *)mRecordingHeap->getBase(),
131+ PREVIEW_WIDTH, PREVIEW_HEIGHT);
132+ nsecs_t timeStamp = systemTime(SYSTEM_TIME_MONOTONIC);
133+ mRecordingCallback(timeStamp, mRecordingBuffer, mRecordingCallbackCookie);
134+
135+ camera.convert((unsigned char *) mRawHeap->getBase(),
136+ (unsigned char *) mPreviewHeap->getBase(),
137+ PREVIEW_WIDTH, PREVIEW_HEIGHT);
138+
139+ if (UNLIKELY(mDebugFps)) {
140+ showFPS("Recording");
141+ }
142+ }
143+ else {
144+ camera.convert((unsigned char *) mRawHeap->getBase(),
145+ (unsigned char *) mPreviewHeap->getBase(),
146+ PREVIEW_WIDTH, PREVIEW_HEIGHT);
147+
148+ yuyv422_to_yuv420((unsigned char *)mRawHeap->getBase(),
149+ (unsigned char *)mHeap->getBase(),
150+ PREVIEW_WIDTH, PREVIEW_HEIGHT);
151+ mPreviewCallback(mBuffer, mPreviewCallbackCookie);
152+
153+ if (UNLIKELY(mDebugFps)) {
154+ showFPS("Preview");
155+ }
156+ }
95157 }
96158
97159 return NO_ERROR;
@@ -104,16 +166,29 @@ status_t CameraHardware::startPreview(preview_callback cb, void* user)
104166 Mutex::Autolock lock(mLock);
105167 if (mPreviewThread != 0) {
106168 //already running
169+ LOGD("startPreview: but already running");
107170 return INVALID_OPERATION;
108171 }
109172
110- camera.Open(VIDEO_DEVICE, MIN_WIDTH, MIN_HEIGHT, PIXEL_FORMAT);
173+ if (camera.Open(VIDEO_DEVICE, PREVIEW_WIDTH, PREVIEW_HEIGHT, PIXEL_FORMAT) < 0) {
174+ LOGE("startPreview failed: cannot open device.");
175+ return UNKNOWN_ERROR;
176+ }
111177
112- mPreviewFrameSize = MIN_WIDTH * MIN_HEIGHT * 2;
178+ mPreviewFrameSize = PREVIEW_WIDTH * PREVIEW_HEIGHT * 2;
113179
114180 mHeap = new MemoryHeapBase(mPreviewFrameSize);
115181 mBuffer = new MemoryBase(mHeap, 0, mPreviewFrameSize);
116182
183+ mPreviewHeap = new MemoryHeapBase(mPreviewFrameSize);
184+ mPreviewBuffer = new MemoryBase(mPreviewHeap, 0, mPreviewFrameSize);
185+
186+ mRecordingHeap = new MemoryHeapBase(mPreviewFrameSize);
187+ mRecordingBuffer = new MemoryBase(mRecordingHeap, 0, mPreviewFrameSize);
188+
189+ mRawHeap = new MemoryHeapBase(mPreviewFrameSize);
190+ mRawBuffer = new MemoryBase(mRawHeap, 0, mPreviewFrameSize);
191+
117192 camera.Init();
118193 camera.StartStreaming();
119194
@@ -161,20 +236,34 @@ bool CameraHardware::previewEnabled()
161236
162237 status_t CameraHardware::startRecording(recording_callback cb, void* user)
163238 {
164- return UNKNOWN_ERROR;
239+ LOGD("startRecording");
240+ mRecordingLock.lock();
241+ mRecordingCallback = cb;
242+ mRecordingCallbackCookie = user;
243+ mRecordingLock.unlock();
244+ return NO_ERROR;
245+
165246 }
166247
167248 void CameraHardware::stopRecording()
168249 {
250+ mRecordingLock.lock();
251+ mRecordingCallback = NULL;
252+ mRecordingCallbackCookie = NULL;
253+ mRecordingLock.unlock();
169254 }
170255
171256 bool CameraHardware::recordingEnabled()
172257 {
173- return false;
258+ return mRecordingCallback !=0;
174259 }
175260
176261 void CameraHardware::releaseRecordingFrame(const sp<IMemory>& mem)
177262 {
263+ if (UNLIKELY(mDebugFps)) {
264+ showFPS("Recording");
265+ }
266+ return;
178267 }
179268
180269 // ---------------------------------------------------------------------------
@@ -219,44 +308,25 @@ status_t CameraHardware::autoFocus(autofocus_callback af_cb,
219308
220309 int CameraHardware::pictureThread()
221310 {
222- unsigned char *frame;
223- int bufferSize;
224- int w,h;
225311 int ret;
226- struct v4l2_buffer buffer;
227- struct v4l2_format format;
228- struct v4l2_buffer cfilledbuffer;
229- struct v4l2_requestbuffers creqbuf;
230- struct v4l2_capability cap;
231312
232313 if (mShutterCallback)
233314 mShutterCallback(mPictureCallbackCookie);
234315
235- mParameters.getPictureSize(&w, &h);
236- LOGD("Picture Size: Width = %d \t Height = %d", w, h);
237-
238- int width, height;
239- mParameters.getPictureSize(&width, &height);
240- camera.Open(VIDEO_DEVICE, MIN_WIDTH, MIN_HEIGHT, PIXEL_FORMAT);
241- camera.Init();
242- camera.StartStreaming();
243-
244- if (mRawPictureCallback) {
245- LOGD("mRawPictureCallback");
246-
247-// mRawPictureCallback(camera.GrabRawFrame(), mPictureCallbackCookie);
316+ sp<PreviewThread> previewThread;
317+ Mutex::Autolock lock(mLock);
318+ previewStopped = true;
319+ previewThread = mPreviewThread;
320+ if (previewThread != 0) {
321+ previewThread->requestExitAndWait();
248322 }
249-
323+ mPreviewThread.clear();
324+ // Grab the photo
250325 if (mJpegPictureCallback) {
251- LOGD ("mJpegPictureCallback");
252-
253326 mJpegPictureCallback(camera.GrabJpegFrame(), mPictureCallbackCookie);
254327 }
255-
256- camera.Uninit();
257- camera.StopStreaming();
258- camera.Close();
259-
328+ previewStopped = false;
329+ mPreviewThread = new PreviewThread(this);
260330 return NO_ERROR;
261331 }
262332
@@ -265,14 +335,10 @@ status_t CameraHardware::takePicture(shutter_callback shutter_cb,
265335 jpeg_callback jpeg_cb,
266336 void* user)
267337 {
268- stopPreview();
269338 mShutterCallback = shutter_cb;
270339 mRawPictureCallback = raw_cb;
271340 mJpegPictureCallback = jpeg_cb;
272341 mPictureCallbackCookie = user;
273- //if (createThread(beginPictureThread, this) == false)
274- // return -1;
275-
276342 pictureThread();
277343
278344 return NO_ERROR;
@@ -316,11 +382,13 @@ status_t CameraHardware::setParameters(const CameraParameters& params)
316382 LOGD("PREVIEW SIZE: w=%d h=%d framerate=%d", w, h, framerate);
317383
318384 params.getPictureSize(&w, &h);
385+ LOGD("requested size %d x %d", w, h);
319386
320387 mParameters = params;
321388
322389 // Set to fixed sizes
323- mParameters.setPreviewSize(MIN_WIDTH,MIN_HEIGHT);
390+ mParameters.setPreviewSize(PREVIEW_WIDTH, PREVIEW_HEIGHT);
391+ mParameters.setPictureSize(PREVIEW_WIDTH, PREVIEW_HEIGHT);
324392
325393 return NO_ERROR;
326394 }
@@ -330,7 +398,7 @@ CameraParameters CameraHardware::getParameters() const
330398 CameraParameters params;
331399
332400 {
333- Mutex::Autolock lock(mLock);
401+ Mutex::Autolock lock(mLock);
334402 params = mParameters;
335403 }
336404
@@ -339,7 +407,6 @@ CameraParameters CameraHardware::getParameters() const
339407
340408 void CameraHardware::release()
341409 {
342- close(camera_device);
343410 }
344411
345412 sp<CameraHardwareInterface> CameraHardware::createInstance()
--- a/camera/libcameraservice/CameraHardware.h
+++ b/camera/libcameraservice/CameraHardware.h
@@ -1,5 +1,6 @@
11 /*
22 **
3+** Copyright (C) 2009 0xlab.org - http://0xlab.org/
34 ** Copyright 2008, The Android Open Source Project
45 **
56 ** Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,7 +25,7 @@
2425 #include <utils/MemoryHeapBase.h>
2526 #include <utils/threads.h>
2627
27-#include <sys/ioctl.h>
28+#include <jpeglib.h>
2829 #include "V4L2Camera.h"
2930
3031 namespace android {
@@ -93,14 +94,17 @@ private:
9394 int pictureThread();
9495
9596 mutable Mutex mLock;
97+ mutable Mutex mPreviewLock;
9698
9799 CameraParameters mParameters;
98100
99- sp<MemoryHeapBase> mHeap;
100- sp<MemoryBase> mBuffer;
101+ sp<MemoryHeapBase> mHeap; // format: 420
102+ sp<MemoryBase> mBuffer;
101103
102- sp<MemoryHeapBase> mPreviewHeap;
103- sp<MemoryHeapBase> mRawHeap;
104+ sp<MemoryHeapBase> mPreviewHeap; // format: 565
105+ sp<MemoryBase> mPreviewBuffer;
106+ sp<MemoryHeapBase> mRawHeap; // format: 422
107+ sp<MemoryBase> mRawBuffer;
104108
105109 bool mPreviewRunning;
106110 int mPreviewFrameSize;
@@ -110,7 +114,6 @@ private:
110114 jpeg_callback mJpegPictureCallback;
111115 void *mPictureCallbackCookie;
112116
113- // protected by mLock
114117 sp<PreviewThread> mPreviewThread;
115118 preview_callback mPreviewCallback;
116119 void *mPreviewCallbackCookie;
@@ -118,16 +121,16 @@ private:
118121 autofocus_callback mAutoFocusCallback;
119122 void *mAutoFocusCallbackCookie;
120123
121- // only used from PreviewThread
122- int mCurrentPreviewFrame;
124+ sp<MemoryHeapBase> mRecordingHeap;
125+ sp<MemoryBase> mRecordingBuffer;
123126
124- void * framebuffer;
125- bool previewStopped;
126- int camera_device;
127- void* mem[4];
128- int nQueued;
129- int nDequeued;
130- V4L2Camera camera;
127+ Mutex mRecordingLock;
128+ int mRecordingFrameSize;
129+ recording_callback mRecordingCallback;
130+ void *mRecordingCallbackCookie;
131+
132+ bool previewStopped;
133+ V4L2Camera camera;
131134 };
132135
133136 }; // namespace android
--- a/camera/libcameraservice/V4L2Camera.cpp
+++ b/camera/libcameraservice/V4L2Camera.cpp
@@ -1,11 +1,20 @@
11 /*
2- * This program is free software; you can redistribute it and/or modify
3- * it under the terms of the GNU General Public License as published by
4- * the Free Software Foundation; either version 2 of the License, or
5- * (at your option) any later version.
6- * Author: Niels Keeman nielskeeman@gmail.com
7- *
8- */
2+**
3+** Copyright (C) 2009 0xlab.org - http://0xlab.org/
4+** Copyright 2008, The Android Open Source Project
5+**
6+** Licensed under the Apache License, Version 2.0 (the "License");
7+** you may not use this file except in compliance with the License.
8+** You may obtain a copy of the License at
9+**
10+** http://www.apache.org/licenses/LICENSE-2.0
11+**
12+** Unless required by applicable law or agreed to in writing, software
13+** distributed under the License is distributed on an "AS IS" BASIS,
14+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+** See the License for the specific language governing permissions and
16+** limitations under the License.
17+*/
918
1019 #define LOG_TAG "V4L2Camera"
1120 #include <utils/Log.h>
@@ -22,12 +31,12 @@
2231
2332 #include <linux/videodev.h>
2433
25-#include "V4L2Camera.h"
26-
27-extern "C" { /* Android jpeglib.h missed extern "C" */
28-#include <jpeglib.h>
34+extern "C" {
35+ #include <jpeglib.h>
2936 }
3037
38+#include "V4L2Camera.h"
39+
3140 namespace android {
3241
3342 V4L2Camera::V4L2Camera ()
@@ -41,7 +50,7 @@ V4L2Camera::~V4L2Camera()
4150 free(videoIn);
4251 }
4352
44-int V4L2Camera::Open (const char *device, int width, int height, int pixelformat)
53+int V4L2Camera::Open(const char *device, int width, int height, int pixelformat)
4554 {
4655 int ret;
4756
@@ -82,6 +91,15 @@ int V4L2Camera::Open (const char *device, int width, int height, int pixelformat
8291 return ret;
8392 }
8493
94+ ret = init_parm();
95+ if (ret < 0) {
96+ LOGE("Init_parm Failed: %s", strerror(errno));
97+ return ret;
98+ }
99+
100+ videoIn->width = videoIn->format.fmt.pix.width;
101+ videoIn->height = videoIn->format.fmt.pix.height;
102+
85103 return 0;
86104 }
87105
@@ -90,6 +108,8 @@ void V4L2Camera::Close ()
90108 close(fd);
91109 }
92110
111+
112+// Init mmap
93113 int V4L2Camera::Init()
94114 {
95115 int ret;
@@ -143,7 +163,34 @@ int V4L2Camera::Init()
143163 return 0;
144164 }
145165
146-void V4L2Camera::Uninit ()
166+int V4L2Camera::init_parm()
167+{
168+ int ret;
169+ int framerate;
170+ struct v4l2_streamparm parm;
171+
172+ framerate = DEFAULT_FRAME_RATE;
173+
174+ parm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
175+
176+ ret = ioctl(fd, VIDIOC_G_PARM, &parm);
177+ if(ret != 0) {
178+ LOGE("VIDIOC_G_PARM fail....");
179+ return ret;
180+ }
181+
182+ parm.parm.capture.timeperframe.numerator = 1;
183+ parm.parm.capture.timeperframe.denominator = framerate;
184+ ret = ioctl(fd, VIDIOC_S_PARM, &parm);
185+ if(ret != 0) {
186+ LOGE("VIDIOC_S_PARM Fail....");
187+ return -1;
188+ }
189+
190+ return 0;
191+}
192+
193+void V4L2Camera::Uninit()
147194 {
148195 int ret;
149196
@@ -220,16 +267,15 @@ void V4L2Camera::GrabPreviewFrame (void *previewBuffer)
220267 /* DQ */
221268 ret = ioctl(fd, VIDIOC_DQBUF, &videoIn->buf);
222269 if (ret < 0) {
223- //LOGE("GrabPreviewFrame: VIDIOC_DQBUF Failed");
224-
270+ LOGE("GrabPreviewFrame: VIDIOC_DQBUF Failed");
225271 return;
226272 }
227273 nDequeued++;
228274
229- memcpy (tmpBuffer, videoIn->mem[videoIn->buf.index], (size_t) videoIn->buf.bytesused);
275+ memcpy(tmpBuffer, videoIn->mem[videoIn->buf.index], (size_t) videoIn->buf.bytesused);
230276
231- //convertYUYVtoYUV422SP((uint8_t *)tmpBuffer, (uint8_t *)previewBuffer, videoIn->width, videoIn->height);
232- convert((unsigned char *)tmpBuffer, (unsigned char *)previewBuffer, videoIn->width, videoIn->height);
277+ convert((unsigned char *) tmpBuffer, (unsigned char *) previewBuffer,
278+ videoIn->width, videoIn->height);
233279
234280 ret = ioctl(fd, VIDIOC_QBUF, &videoIn->buf);
235281 if (ret < 0) {
@@ -242,14 +288,49 @@ void V4L2Camera::GrabPreviewFrame (void *previewBuffer)
242288 free(tmpBuffer);
243289 }
244290
245-sp<IMemory> V4L2Camera::GrabRawFrame ()
291+void V4L2Camera::GrabRawFrame(void *previewBuffer)
292+{
293+ int ret;
294+
295+ videoIn->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
296+ videoIn->buf.memory = V4L2_MEMORY_MMAP;
297+
298+ /* DQ */
299+ ret = ioctl(fd, VIDIOC_DQBUF, &videoIn->buf);
300+ if (ret < 0) {
301+ LOGE("GrabRawFrame: VIDIOC_DQBUF Failed");
302+ return;
303+ }
304+ nDequeued++;
305+
306+ memcpy(previewBuffer, videoIn->mem[videoIn->buf.index], (size_t) videoIn->buf.bytesused);
307+
308+ ret = ioctl(fd, VIDIOC_QBUF, &videoIn->buf);
309+ if (ret < 0) {
310+ LOGE("postGrabRawFrame: VIDIOC_QBUF Failed");
311+ return;
312+ }
313+
314+ nQueued++;
315+}
316+
317+int
318+V4L2Camera::savePicture(unsigned char *inputBuffer, const char * filename)
246319 {
247- sp<MemoryHeapBase> memHeap = new MemoryHeapBase(videoIn->width * videoIn->height * 2);
248- sp<MemoryBase> memBase = new MemoryBase(memHeap, 0, videoIn->width * videoIn->height * 2);
320+ FILE *output;
321+ int fileSize;
322+ int ret;
323+ output = fopen(filename, "wb");
324+
325+ if (output == NULL) {
326+ LOGE("GrabJpegFrame: Ouput file == NULL");
327+ return 0;
328+ }
249329
250- // Not yet implemented, do I have to?
330+ fileSize = saveYUYVtoJPEG(inputBuffer, videoIn->width, videoIn->height, output, 100);
251331
252- return memBase;
332+ fclose(output);
333+ return fileSize;
253334 }
254335
255336 sp<IMemory> V4L2Camera::GrabJpegFrame ()
@@ -270,7 +351,7 @@ sp<IMemory> V4L2Camera::GrabJpegFrame ()
270351 }
271352 nDequeued++;
272353
273- LOGI("GrabJpegFrame: Generated a frame from capture device");
354+ fileSize = savePicture((unsigned char *)videoIn->mem[videoIn->buf.index], "/sdcard/tmp.jpg");
274355
275356 /* Enqueue buffer */
276357 ret = ioctl(fd, VIDIOC_QBUF, &videoIn->buf);
@@ -280,17 +361,6 @@ sp<IMemory> V4L2Camera::GrabJpegFrame ()
280361 }
281362 nQueued++;
282363
283- output = fopen("/sdcard/tmp.jpg", "wb");
284-
285- if (output == NULL) {
286- LOGE("GrabJpegFrame: Ouput file == NULL");
287- return NULL;
288- }
289-
290- fileSize = saveYUYVtoJPEG((unsigned char *)videoIn->mem[videoIn->buf.index], videoIn->width, videoIn->height, output, 85);
291-
292- fclose(output);
293-
294364 input = fopen("/sdcard/tmp.jpg", "rb");
295365
296366 if (input == NULL)
@@ -324,8 +394,6 @@ int V4L2Camera::saveYUYVtoJPEG (unsigned char *inputBuffer, int width, int heigh
324394 jpeg_create_compress (&cinfo);
325395 jpeg_stdio_dest (&cinfo, file);
326396
327- LOGI("JPEG PICTURE WIDTH AND HEIGHT: %dx%d", width, height);
328-
329397 cinfo.image_width = width;
330398 cinfo.image_height = height;
331399 cinfo.input_components = 3;
@@ -380,6 +448,30 @@ int V4L2Camera::saveYUYVtoJPEG (unsigned char *inputBuffer, int width, int heigh
380448 return fileSize;
381449 }
382450
451+static inline void yuv_to_rgb16(unsigned char y,
452+ unsigned char u,
453+ unsigned char v,
454+ unsigned char *rgb)
455+{
456+ register int r,g,b;
457+ int rgb16;
458+
459+ r = (1192 * (y - 16) + 1634 * (v - 128) ) >> 10;
460+ g = (1192 * (y - 16) - 833 * (v - 128) - 400 * (u -128) ) >> 10;
461+ b = (1192 * (y - 16) + 2066 * (u - 128) ) >> 10;
462+
463+ r = r > 255 ? 255 : r < 0 ? 0 : r;
464+ g = g > 255 ? 255 : g < 0 ? 0 : g;
465+ b = b > 255 ? 255 : b < 0 ? 0 : b;
466+
467+ rgb16 = (int)(((r >> 3)<<11) | ((g >> 2) << 5)| ((b >> 3) << 0));
468+
469+ *rgb = (unsigned char)(rgb16 & 0xFF);
470+ rgb++;
471+ *rgb = (unsigned char)((rgb16 & 0xFF00) >> 8);
472+
473+}
474+
383475 void V4L2Camera::convert(unsigned char *buf, unsigned char *rgb, int width, int height)
384476 {
385477 int x,y,z=0;
@@ -398,36 +490,8 @@ void V4L2Camera::convert(unsigned char *buf, unsigned char *rgb, int width, int
398490 yuv_to_rgb16(Y1, U, V, &rgb[y]);
399491 yuv_to_rgb16(Y2, U, V, &rgb[y + 2]);
400492 }
401-
402493 }
403494
404-void V4L2Camera::yuv_to_rgb16(unsigned char y, unsigned char u, unsigned char v, unsigned char *rgb)
405-{
406- int r,g,b;
407- int z;
408- int rgb16;
409-
410- z = 0;
411-
412- r = 1.164 * (y - 16) + 1.596 * (v - 128);
413- g = 1.164 * (y - 16) - 0.813 * (v - 128) - 0.391 * (u -128);
414- b = 1.164 * (y - 16) + 2.018 * (u - 128);
415-
416- if (r > 255) r = 255;
417- if (g > 255) g = 255;
418- if (b > 255) b = 255;
419-
420- if (r < 0) r = 0;
421- if (g < 0) g = 0;
422- if (b < 0) b = 0;
423-
424- rgb16 = (int)(((r >> 3)<<11) | ((g >> 2) << 5)| ((b >> 3) << 0));
425-
426- *rgb = (unsigned char)(rgb16 & 0xFF);
427- rgb++;
428- *rgb = (unsigned char)((rgb16 & 0xFF00) >> 8);
429-
430-}
431495
432496
433497 }; // namespace android
--- a/camera/libcameraservice/V4L2Camera.h
+++ b/camera/libcameraservice/V4L2Camera.h
@@ -1,16 +1,26 @@
11 /*
2- * This program is free software; you can redistribute it and/or modify
3- * it under the terms of the GNU General Public License as published by
4- * the Free Software Foundation; either version 2 of the License, or
5- * (at your option) any later version.
6- * Author: Niels Keeman nielskeeman@gmail.com
7- *
8- */
2+**
3+** Copyright (C) 2009 0xlab.org - http://0xlab.org/
4+** Copyright 2008, The Android Open Source Project
5+**
6+** Licensed under the Apache License, Version 2.0 (the "License");
7+** you may not use this file except in compliance with the License.
8+** You may obtain a copy of the License at
9+**
10+** http://www.apache.org/licenses/LICENSE-2.0
11+**
12+** Unless required by applicable law or agreed to in writing, software
13+** distributed under the License is distributed on an "AS IS" BASIS,
14+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+** See the License for the specific language governing permissions and
16+** limitations under the License.
17+*/
918
1019 #ifndef _V4L2CAMERA_H
1120 #define _V4L2CAMERA_H
1221
1322 #define NB_BUFFER 4
23+#define DEFAULT_FRAME_RATE 30
1424
1525 #include <utils/MemoryBase.h>
1626 #include <utils/MemoryHeapBase.h>
@@ -41,14 +51,17 @@ public:
4151 void Close ();
4252
4353 int Init ();
54+ int init_parm();
4455 void Uninit ();
4556
4657 int StartStreaming ();
4758 int StopStreaming ();
4859
4960 void GrabPreviewFrame (void *previewBuffer);
50- sp<IMemory> GrabRawFrame ();
61+ void GrabRawFrame(void *previewBuffer);
5162 sp<IMemory> GrabJpegFrame ();
63+ int savePicture(unsigned char *inputBuffer, const char * filename);
64+ void convert(unsigned char *buf, unsigned char *rgb, int width, int height);
5265
5366 private:
5467 struct vdIn *videoIn;
@@ -58,9 +71,6 @@ private:
5871 int nDequeued;
5972
6073 int saveYUYVtoJPEG (unsigned char *inputBuffer, int width, int height, FILE *file, int quality);
61-
62- void convert(unsigned char *buf, unsigned char *rgb, int width, int height);
63- void yuv_to_rgb16(unsigned char y, unsigned char u, unsigned char v, unsigned char *rgb);
6474 };
6575
6676 }; // namespace android
--- /dev/null
+++ b/camera/libcameraservice/converter.cpp
@@ -0,0 +1,261 @@
1+/*
2+**
3+** Copyright (C) 2009 0xlab.org - http://0xlab.org/
4+** Copyright 2008, The Android Open Source Project
5+**
6+** This work is based on yuvconverter project.
7+**
8+** Licensed under the Apache License, Version 2.0 (the "License");
9+** you may not use this file except in compliance with the License.
10+** You may obtain a copy of the License at
11+**
12+** http://www.apache.org/licenses/LICENSE-2.0
13+**
14+** Unless required by applicable law or agreed to in writing, software
15+** distributed under the License is distributed on an "AS IS" BASIS,
16+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+** See the License for the specific language governing permissions and
18+** limitations under the License.
19+*/
20+
21+#include "converter.h"
22+
23+void
24+yuyv422_to_yuv420(unsigned char *bufsrc, unsigned char *bufdest, int width, int height)
25+{
26+ unsigned char *ptrsrcy1, *ptrsrcy2;
27+ unsigned char *ptrsrcy3, *ptrsrcy4;
28+ unsigned char *ptrsrccb1, *ptrsrccb2;
29+ unsigned char *ptrsrccb3, *ptrsrccb4;
30+ unsigned char *ptrsrccr1, *ptrsrccr2;
31+ unsigned char *ptrsrccr3, *ptrsrccr4;
32+ int srcystride, srcccstride;
33+
34+ ptrsrcy1 = bufsrc ;
35+ ptrsrcy2 = bufsrc + (width<<1) ;
36+ ptrsrcy3 = bufsrc + (width<<1)*2 ;
37+ ptrsrcy4 = bufsrc + (width<<1)*3 ;
38+
39+ ptrsrccb1 = bufsrc + 1;
40+ ptrsrccb2 = bufsrc + (width<<1) + 1;
41+ ptrsrccb3 = bufsrc + (width<<1)*2 + 1;
42+ ptrsrccb4 = bufsrc + (width<<1)*3 + 1;
43+
44+ ptrsrccr1 = bufsrc + 3;
45+ ptrsrccr2 = bufsrc + (width<<1) + 3;
46+ ptrsrccr3 = bufsrc + (width<<1)*2 + 3;
47+ ptrsrccr4 = bufsrc + (width<<1)*3 + 3;
48+
49+ srcystride = (width<<1)*3;
50+ srcccstride = (width<<1)*3;
51+
52+ unsigned char *ptrdesty1, *ptrdesty2;
53+ unsigned char *ptrdesty3, *ptrdesty4;
54+ unsigned char *ptrdestcb1, *ptrdestcb2;
55+ unsigned char *ptrdestcr1, *ptrdestcr2;
56+ int destystride, destccstride;
57+
58+ ptrdesty1 = bufdest;
59+ ptrdesty2 = bufdest + width;
60+ ptrdesty3 = bufdest + width*2;
61+ ptrdesty4 = bufdest + width*3;
62+
63+ ptrdestcb1 = bufdest + width*height;
64+ ptrdestcb2 = bufdest + width*height + (width>>1);
65+
66+ ptrdestcr1 = bufdest + width*height + ((width*height) >> 2);
67+ ptrdestcr2 = bufdest + width*height + ((width*height) >> 2) + (width>>1);
68+
69+ destystride = (width)*3;
70+ destccstride = (width>>1);
71+
72+ int i, j;
73+
74+ for(j=0; j<(height/4); j++)
75+ {
76+ for(i=0;i<(width/2);i++)
77+ {
78+ (*ptrdesty1++) = (*ptrsrcy1);
79+ (*ptrdesty2++) = (*ptrsrcy2);
80+ (*ptrdesty3++) = (*ptrsrcy3);
81+ (*ptrdesty4++) = (*ptrsrcy4);
82+
83+ ptrsrcy1 += 2;
84+ ptrsrcy2 += 2;
85+ ptrsrcy3 += 2;
86+ ptrsrcy4 += 2;
87+
88+ (*ptrdesty1++) = (*ptrsrcy1);
89+ (*ptrdesty2++) = (*ptrsrcy2);
90+ (*ptrdesty3++) = (*ptrsrcy3);
91+ (*ptrdesty4++) = (*ptrsrcy4);
92+
93+ ptrsrcy1 += 2;
94+ ptrsrcy2 += 2;
95+ ptrsrcy3 += 2;
96+ ptrsrcy4 += 2;
97+
98+ (*ptrdestcb1++) = (*ptrsrccb1);
99+ (*ptrdestcb2++) = (*ptrsrccb3);
100+
101+ ptrsrccb1 += 4;
102+ ptrsrccb3 += 4;
103+
104+ (*ptrdestcr1++) = (*ptrsrccr1);
105+ (*ptrdestcr2++) = (*ptrsrccr3);
106+
107+ ptrsrccr1 += 4;
108+ ptrsrccr3 += 4;
109+
110+ }
111+
112+
113+ /* Update src pointers */
114+ ptrsrcy1 += srcystride;
115+ ptrsrcy2 += srcystride;
116+ ptrsrcy3 += srcystride;
117+ ptrsrcy4 += srcystride;
118+
119+ ptrsrccb1 += srcccstride;
120+ ptrsrccb3 += srcccstride;
121+
122+ ptrsrccr1 += srcccstride;
123+ ptrsrccr3 += srcccstride;
124+
125+
126+ /* Update dest pointers */
127+ ptrdesty1 += destystride;
128+ ptrdesty2 += destystride;
129+ ptrdesty3 += destystride;
130+ ptrdesty4 += destystride;
131+
132+ ptrdestcb1 += destccstride;
133+ ptrdestcb2 += destccstride;
134+
135+ ptrdestcr1 += destccstride;
136+ ptrdestcr2 += destccstride;
137+
138+ }
139+}
140+
141+void
142+yuyv422_to_yuv420sp(unsigned char *bufsrc, unsigned char *bufdest, int width, int height)
143+{
144+ unsigned char *ptrsrcy1, *ptrsrcy2;
145+ unsigned char *ptrsrcy3, *ptrsrcy4;
146+ unsigned char *ptrsrccb1, *ptrsrccb2;
147+ unsigned char *ptrsrccb3, *ptrsrccb4;
148+ unsigned char *ptrsrccr1, *ptrsrccr2;
149+ unsigned char *ptrsrccr3, *ptrsrccr4;
150+ int srcystride, srcccstride;
151+
152+ ptrsrcy1 = bufsrc ;
153+ ptrsrcy2 = bufsrc + (width<<1) ;
154+ ptrsrcy3 = bufsrc + (width<<1)*2 ;
155+ ptrsrcy4 = bufsrc + (width<<1)*3 ;
156+
157+ ptrsrccb1 = bufsrc + 1;
158+ ptrsrccb2 = bufsrc + (width<<1) + 1;
159+ ptrsrccb3 = bufsrc + (width<<1)*2 + 1;
160+ ptrsrccb4 = bufsrc + (width<<1)*3 + 1;
161+
162+ ptrsrccr1 = bufsrc + 3;
163+ ptrsrccr2 = bufsrc + (width<<1) + 3;
164+ ptrsrccr3 = bufsrc + (width<<1)*2 + 3;
165+ ptrsrccr4 = bufsrc + (width<<1)*3 + 3;
166+
167+ srcystride = (width<<1)*3;
168+ srcccstride = (width<<1)*3;
169+
170+ unsigned char *ptrdesty1, *ptrdesty2;
171+ unsigned char *ptrdesty3, *ptrdesty4;
172+ unsigned char *ptrdestcb1, *ptrdestcb2;
173+ unsigned char *ptrdestcr1, *ptrdestcr2;
174+ int destystride, destccstride;
175+
176+ ptrdesty1 = bufdest;
177+ ptrdesty2 = bufdest + width;
178+ ptrdesty3 = bufdest + width*2;
179+ ptrdesty4 = bufdest + width*3;
180+
181+ ptrdestcb1 = bufdest + width*height;
182+ ptrdestcb2 = bufdest + width*height + width;
183+
184+ ptrdestcr1 = bufdest + width*height + 1;
185+ ptrdestcr2 = bufdest + width*height + width + 1;
186+
187+ destystride = (width)*3;
188+ destccstride = width;
189+
190+ int i, j;
191+
192+ for(j=0; j<(height/4); j++)
193+ {
194+ for(i=0;i<(width/2);i++)
195+ {
196+ (*ptrdesty1++) = (*ptrsrcy1);
197+ (*ptrdesty2++) = (*ptrsrcy2);
198+ (*ptrdesty3++) = (*ptrsrcy3);
199+ (*ptrdesty4++) = (*ptrsrcy4);
200+
201+ ptrsrcy1 += 2;
202+ ptrsrcy2 += 2;
203+ ptrsrcy3 += 2;
204+ ptrsrcy4 += 2;
205+
206+ (*ptrdesty1++) = (*ptrsrcy1);
207+ (*ptrdesty2++) = (*ptrsrcy2);
208+ (*ptrdesty3++) = (*ptrsrcy3);
209+ (*ptrdesty4++) = (*ptrsrcy4);
210+
211+ ptrsrcy1 += 2;
212+ ptrsrcy2 += 2;
213+ ptrsrcy3 += 2;
214+ ptrsrcy4 += 2;
215+
216+ (*ptrdestcb1) = (*ptrsrccb1);
217+ (*ptrdestcb2) = (*ptrsrccb3);
218+ ptrdestcb1 += 2;
219+ ptrdestcb2 += 2;
220+
221+ ptrsrccb1 += 4;
222+ ptrsrccb3 += 4;
223+
224+ (*ptrdestcr1) = (*ptrsrccr1);
225+ (*ptrdestcr2) = (*ptrsrccr3);
226+ ptrdestcr1 += 2;
227+ ptrdestcr2 += 2;
228+
229+ ptrsrccr1 += 4;
230+ ptrsrccr3 += 4;
231+
232+ }
233+
234+
235+ /* Update src pointers */
236+ ptrsrcy1 += srcystride;
237+ ptrsrcy2 += srcystride;
238+ ptrsrcy3 += srcystride;
239+ ptrsrcy4 += srcystride;
240+
241+ ptrsrccb1 += srcccstride;
242+ ptrsrccb3 += srcccstride;
243+
244+ ptrsrccr1 += srcccstride;
245+ ptrsrccr3 += srcccstride;
246+
247+
248+ /* Update dest pointers */
249+ ptrdesty1 += destystride;
250+ ptrdesty2 += destystride;
251+ ptrdesty3 += destystride;
252+ ptrdesty4 += destystride;
253+
254+ ptrdestcb1 += destccstride;
255+ ptrdestcb2 += destccstride;
256+
257+ ptrdestcr1 += destccstride;
258+ ptrdestcr2 += destccstride;
259+
260+ }
261+}
--- /dev/null
+++ b/camera/libcameraservice/converter.h
@@ -0,0 +1,25 @@
1+/*
2+**
3+** Copyright (C) 2009 0xlab.org - http://0xlab.org/
4+** Copyright 2008, The Android Open Source Project
5+**
6+** Licensed under the Apache License, Version 2.0 (the "License");
7+** you may not use this file except in compliance with the License.
8+** You may obtain a copy of the License at
9+**
10+** http://www.apache.org/licenses/LICENSE-2.0
11+**
12+** Unless required by applicable law or agreed to in writing, software
13+** distributed under the License is distributed on an "AS IS" BASIS,
14+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+** See the License for the specific language governing permissions and
16+** limitations under the License.
17+*/
18+
19+#ifndef CONVERTER_H
20+#define CONVERTER_H
21+
22+void yuyv422_to_yuv420(unsigned char *bufsrc, unsigned char *bufdest, int width, int height);
23+void yuyv422_to_yuv420sp(unsigned char *bufsrc, unsigned char *bufdest, int width, int height);
24+
25+#endif