summaryrefslogtreecommitdiff
authorguosong.zhou <guosong.zhou@amlogic.com>2014-12-12 07:55:04 (GMT)
committer guosong.zhou <guosong.zhou@amlogic.com>2014-12-12 07:55:04 (GMT)
commitbbdf8a01c1eca90896f002626c558228c48321ef (patch)
tree4d9bd04ce5f916f0bad691b718890bd1258c6673
parentf441e17f40f5c787acede174216d1a98f3dc5dc5 (diff)
downloadcamera-bbdf8a01c1eca90896f002626c558228c48321ef.zip
camera-bbdf8a01c1eca90896f002626c558228c48321ef.tar.gz
camera-bbdf8a01c1eca90896f002626c558228c48321ef.tar.bz2
add usb camera jpeg function
Change-Id: Idf94243eb23aaf1ffdc391187f46e1c547eab0ea
Diffstat
-rwxr-xr-xv3/Android.mk3
-rwxr-xr-xv3/EmulatedFakeCamera3.cpp73
-rwxr-xr-xv3/EmulatedFakeCamera3.h2
-rwxr-xr-xv3/fake-pipeline2/Sensor.cpp110
-rwxr-xr-xv3/fake-pipeline2/Sensor.h7
-rwxr-xr-xv3/fake-pipeline2/camera_hw.cpp98
-rwxr-xr-xv3/fake-pipeline2/camera_hw.h2
-rwxr-xr-xv3/fake-pipeline2/util.c73
-rwxr-xr-xv3/fake-pipeline2/util.h15
9 files changed, 338 insertions, 45 deletions
diff --git a/v3/Android.mk b/v3/Android.mk
index e10495f..2a5d552 100755
--- a/v3/Android.mk
+++ b/v3/Android.mk
@@ -96,7 +96,8 @@ LOCAL_SRC_FILES := \
fake-pipeline2/Sensor.cpp \
fake-pipeline2/ge2d_stream.cpp \
fake-pipeline2/JpegCompressor.cpp \
- fake-pipeline2/NV12_resize.c\
+ fake-pipeline2/NV12_resize.c \
+ fake-pipeline2/util.c \
EmulatedCamera3.cpp \
EmulatedFakeCamera3.cpp \
EmulatedFakeCamera3Info.cpp \
diff --git a/v3/EmulatedFakeCamera3.cpp b/v3/EmulatedFakeCamera3.cpp
index cbd95fd..b8a153f 100755
--- a/v3/EmulatedFakeCamera3.cpp
+++ b/v3/EmulatedFakeCamera3.cpp
@@ -179,6 +179,8 @@ EmulatedFakeCamera3::EmulatedFakeCamera3(int cameraId, bool facingBack,
*/
//TODO limited or full mode, read this from camera driver
//mFullMode = facingBack;
+ mSupportCap = 0;
+ mSupportRotate = 0;
mFullMode = 0;
}
@@ -250,6 +252,11 @@ status_t EmulatedFakeCamera3::connectCamera(hw_device_t** device) {
DBG_LOGB("mSensor startUp, mCameraID=%d\n", mCameraID);
if (res != NO_ERROR) return res;
+ mSupportCap = mSensor->IoctlStateProbe();
+ if (mSupportCap & IOCTL_MASK_ROTATE) {
+ mSupportRotate = true;
+ }
+
mReadoutThread = new ReadoutThread(this);
mJpegCompressor = new JpegCompressor();
@@ -484,7 +491,7 @@ status_t EmulatedFakeCamera3::configureStreams(
if (isRestart) {
mSensor->streamOff();
pixelfmt = mSensor->halFormatToSensorFormat(pixelfmt);
- mSensor->setOutputFormat(width, height, pixelfmt);
+ mSensor->setOutputFormat(width, height, pixelfmt, 0);
mSensor->streamOn();
DBG_LOGB("width=%d, height=%d, pixelfmt=%.4s\n",
width, height, (char*)&pixelfmt);
@@ -1148,6 +1155,7 @@ status_t EmulatedFakeCamera3::processCaptureRequest(
bool needJpeg = false;
struct ExifInfo info;
ssize_t jpegbuffersize;
+ uint32_t jpegpixelfmt;
exposureTime = settings.find(ANDROID_SENSOR_EXPOSURE_TIME).data.i64[0];
frameDuration = settings.find(ANDROID_SENSOR_FRAME_DURATION).data.i64[0];
@@ -1180,14 +1188,24 @@ status_t EmulatedFakeCamera3::processCaptureRequest(
needJpeg = true;
memset(&info,0,sizeof(struct ExifInfo));
info.orientation = settings.find(ANDROID_JPEG_ORIENTATION).data.i32[0];
- if ((info.orientation==90)||(info.orientation==270)) {
- info.mainwidth = srcBuf.stream->height;
- info.mainheight = srcBuf.stream->width;
- } else {
- info.mainwidth = srcBuf.stream->width;
- info.mainheight = srcBuf.stream->height;
- }
- mSensor->setOutputFormat(info.mainwidth,info.mainheight,V4L2_PIX_FMT_RGB24);
+ jpegpixelfmt = mSensor->getOutputFormat();
+ if (!mSupportRotate) {
+ info.mainwidth = srcBuf.stream->width;
+ info.mainheight = srcBuf.stream->height;
+ } else {
+ if ((info.orientation==90)||(info.orientation==270)) {
+ info.mainwidth = srcBuf.stream->height;
+ info.mainheight = srcBuf.stream->width;
+ } else {
+ info.mainwidth = srcBuf.stream->width;
+ info.mainheight = srcBuf.stream->height;
+ }
+ }
+ if ((jpegpixelfmt == V4L2_PIX_FMT_MJPEG)||(jpegpixelfmt == V4L2_PIX_FMT_YUYV)) {
+ mSensor->setOutputFormat(info.mainwidth,info.mainheight,jpegpixelfmt,1);
+ } else {
+ mSensor->setOutputFormat(info.mainwidth,info.mainheight,V4L2_PIX_FMT_RGB24,1);
+ }
}
// Wait on fence
@@ -1245,13 +1263,18 @@ status_t EmulatedFakeCamera3::processCaptureRequest(
}
if (needJpeg){
- if ((info.orientation==90)||(info.orientation==270)) {
- info.thumbwidth = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[1];
- info.thumbheight = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[0];
- } else {
- info.thumbwidth = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[0];
- info.thumbheight = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[1];
- }
+ if (!mSupportRotate) {
+ info.thumbwidth = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[0];
+ info.thumbheight = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[1];
+ } else {
+ if ((info.orientation==90)||(info.orientation==270)) {
+ info.thumbwidth = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[1];
+ info.thumbheight = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[0];
+ } else {
+ info.thumbwidth = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[0];
+ info.thumbheight = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[1];
+ }
+ }
if (settings.exists(ANDROID_JPEG_GPS_COORDINATES)) {
info.latitude = settings.find(ANDROID_JPEG_GPS_COORDINATES).data.d[0];
info.longitude = settings.find(ANDROID_JPEG_GPS_COORDINATES).data.d[1];
@@ -1491,7 +1514,7 @@ status_t EmulatedFakeCamera3::constructStaticInfo() {
CameraMetadata info;
uint32_t picSizes[64 * 8];
- int64_t duration[36];
+ int64_t* duration = NULL;
int count, duration_count, availablejpegsize;
uint8_t maxCount = 10;
char property[PROPERTY_VALUE_MAX];
@@ -1666,11 +1689,14 @@ status_t EmulatedFakeCamera3::constructStaticInfo() {
info.update(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
(int32_t*)full_size,
sizeof(full_size)/sizeof(full_size[0]));
- duration_count = sizeof(duration)/sizeof(duration[0]);
- if (count < duration_count) {
- duration_count = count;
+ duration = new int64_t[count];
+ if (duration == NULL) {
+ DBG_LOGA("allocate memory for duration failed");
+ return NO_MEMORY;
+ } else {
+ memset(duration,0,sizeof(int64_t)*count);
}
- duration_count = s->getStreamConfigurationDurations(picSizes, duration , duration_count);
+ duration_count = s->getStreamConfigurationDurations(picSizes, duration , count);
info.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS,
duration, duration_count);
@@ -1924,7 +1950,10 @@ status_t EmulatedFakeCamera3::constructStaticInfo() {
mCameraInfo = info.release();
DBG_LOGB("mCameraID=%d,mCameraInfo=%p\n", mCameraID, mCameraInfo);
-
+ if (duration != NULL) {
+ delete [] duration;
+ }
+
s->shutDown();
s.clear();
diff --git a/v3/EmulatedFakeCamera3.h b/v3/EmulatedFakeCamera3.h
index dec3edc..8bf94d2 100755
--- a/v3/EmulatedFakeCamera3.h
+++ b/v3/EmulatedFakeCamera3.h
@@ -241,6 +241,8 @@ private:
sp<Sensor> mSensor;
sp<JpegCompressor> mJpegCompressor;
friend class JpegCompressor;
+ unsigned int mSupportCap;
+ unsigned int mSupportRotate;
/** Processing thread for sending out results */
diff --git a/v3/fake-pipeline2/Sensor.cpp b/v3/fake-pipeline2/Sensor.cpp
index c9fbc7b..5285550 100755
--- a/v3/fake-pipeline2/Sensor.cpp
+++ b/v3/fake-pipeline2/Sensor.cpp
@@ -37,6 +37,7 @@
#include "NV12_resize.h"
#include "libyuv/scale.h"
#include "ge2d_stream.h"
+#include "util.h"
#include <sys/time.h>
@@ -134,6 +135,8 @@ Sensor::Sensor():
mFrameNumber(0),
mCapturedBuffers(NULL),
mListener(NULL),
+ mIoctlSupport(0),
+ msupportrotate(0),
mScene(kResolution[0], kResolution[1], kElectronsPerLuxSecond)
{
@@ -175,6 +178,27 @@ status_t Sensor::startUp(int idx) {
return res;
}
+
+status_t Sensor::IoctlStateProbe(void) {
+ struct v4l2_queryctrl qc;
+ int ret = 0;
+ mIoctlSupport = 0;
+ memset(&qc, 0, sizeof(struct v4l2_queryctrl));
+ qc.id = V4L2_ROTATE_ID;
+ ret = ioctl (vinfo->fd, VIDIOC_QUERYCTRL, &qc);
+ if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)|| (qc.type != V4L2_CTRL_TYPE_INTEGER)){
+ mIoctlSupport &= ~IOCTL_MASK_ROTATE;
+ }else{
+ mIoctlSupport |= IOCTL_MASK_ROTATE;
+ }
+
+ if(mIoctlSupport & IOCTL_MASK_ROTATE){
+ msupportrotate = true;
+ DBG_LOGA("camera support capture rotate");
+ }
+ return mIoctlSupport;
+}
+
uint32_t Sensor::getStreamUsage(int stream_type)
{
uint32_t usage = GRALLOC_USAGE_HW_CAMERA_WRITE;
@@ -203,14 +227,14 @@ uint32_t Sensor::getStreamUsage(int stream_type)
return usage;
}
-status_t Sensor::setOutputFormat(int width, int height, int pixelformat)
+status_t Sensor::setOutputFormat(int width, int height, int pixelformat, bool isjpeg)
{
int res;
framecount = 0;
fps = 0;
- if (pixelformat == V4L2_PIX_FMT_RGB24) {
+ if (isjpeg) {
vinfo->picture.format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
vinfo->picture.format.fmt.pix.width = width;
vinfo->picture.format.fmt.pix.height = height;
@@ -256,8 +280,11 @@ bool Sensor::isNeedRestart(uint32_t width, uint32_t height, uint32_t pixelformat
return false;
}
status_t Sensor::streamOff() {
-
- return stop_capturing(vinfo);
+ if (mSensorType == SENSOR_USB) {
+ return releasebuf_and_stop_capturing(vinfo);
+ } else {
+ return stop_capturing(vinfo);
+ }
}
int Sensor::getOutputFormat()
@@ -349,7 +376,11 @@ status_t Sensor::shutDown() {
}
if (vinfo != NULL) {
- stop_capturing(vinfo);
+ if (mSensorType == SENSOR_USB) {
+ releasebuf_and_stop_capturing(vinfo);
+ } else {
+ stop_capturing(vinfo);
+ }
}
camera_close(vinfo);
@@ -1045,21 +1076,30 @@ int Sensor::captureNewImage() {
int orientation;
orientation = getPictureRotate();
ALOGD("bAux orientation=%d",orientation);
- if ((orientation==90)||(orientation==270)) {
- bAux.streamId = 0;
- bAux.width = b.height;
- bAux.height = b.width;
- bAux.format = HAL_PIXEL_FORMAT_RGB_888;
- bAux.stride = b.height;
- bAux.buffer = NULL;
- } else {
- bAux.streamId = 0;
+ if (!msupportrotate) {
+ bAux.streamId = 0;
bAux.width = b.width;
bAux.height = b.height;
bAux.format = HAL_PIXEL_FORMAT_RGB_888;
bAux.stride = b.width;
bAux.buffer = NULL;
- }
+ } else {
+ if ((orientation==90)||(orientation==270)) {
+ bAux.streamId = 0;
+ bAux.width = b.height;
+ bAux.height = b.width;
+ bAux.format = HAL_PIXEL_FORMAT_RGB_888;
+ bAux.stride = b.height;
+ bAux.buffer = NULL;
+ } else {
+ bAux.streamId = 0;
+ bAux.width = b.width;
+ bAux.height = b.height;
+ bAux.format = HAL_PIXEL_FORMAT_RGB_888;
+ bAux.stride = b.width;
+ bAux.buffer = NULL;
+ }
+ }
// TODO: Reuse these
bAux.img = new uint8_t[b.width * b.height * 3];
mNextCapturedBuffers->push_back(bAux);
@@ -1257,8 +1297,8 @@ int Sensor::getStreamConfigurations(uint32_t picSizes[], const int32_t kAvailabl
uint32_t jpgSrcfmt[] = {
V4L2_PIX_FMT_RGB24,
- V4L2_PIX_FMT_YUYV,
V4L2_PIX_FMT_MJPEG,
+ V4L2_PIX_FMT_YUYV,
};
START = count;
@@ -1331,10 +1371,10 @@ int Sensor::getStreamConfigurationDurations(uint32_t picSizes[], int64_t duratio
int tmp_size = size;
memset(duration, 0 ,sizeof(int64_t)*ARRAY_SIZE(duration));
int pixelfmt_tbl[] = {
+ V4L2_PIX_FMT_MJPEG,
V4L2_PIX_FMT_YVU420,
V4L2_PIX_FMT_NV21,
V4L2_PIX_FMT_RGB24,
- V4L2_PIX_FMT_MJPEG,
V4L2_PIX_FMT_YUYV,
// V4L2_PIX_FMT_YVU420
};
@@ -1381,6 +1421,8 @@ int Sensor::getStreamConfigurationDurations(uint32_t picSizes[], int64_t duratio
}
} else {
if (j > 0) {
+ if (count > tmp_size)
+ break;
duration[count+0] = (int64_t)(picSizes[size-4]);
duration[count+1] = (int64_t)(picSizes[size-3]);
duration[count+2] = (int64_t)(picSizes[size-2]);
@@ -1598,6 +1640,11 @@ void Sensor::captureRGB(uint8_t *img, uint32_t gain, uint32_t stride) {
rotate = getPictureRotate();
width = vinfo->picture.format.fmt.pix.width;
height = vinfo->picture.format.fmt.pix.height;
+ if (mSensorType == SENSOR_USB) {
+ releasebuf_and_stop_capturing(vinfo);
+ } else {
+ stop_capturing(vinfo);
+ }
ret = start_picture(vinfo,rotate);
if (ret < 0)
{
@@ -1614,6 +1661,27 @@ void Sensor::captureRGB(uint8_t *img, uint32_t gain, uint32_t stride) {
}
}
ALOGD("get picture success !");
+
+ if (vinfo->picture.format.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG){
+ uint8_t *tmp_buffer = new uint8_t[width * height * 3 / 2];
+ if ( tmp_buffer == NULL) {
+ ALOGE("new buffer failed!\n");
+ return;
+ }
+ if (ConvertMjpegToNV21(src, vinfo->picture.buf.bytesused, tmp_buffer,
+ width, tmp_buffer + width * height, (width + 1) / 2, width,
+ height, width, height, libyuv::FOURCC_MJPG) != 0) {
+ DBG_LOGA("Decode MJPEG frame failed\n");
+ } else {
+ DBG_LOGA("Decode MJPEG frame failed\n");
+ }
+ nv21_to_rgb24(tmp_buffer,img,width,height);
+ if (tmp_buffer != NULL)
+ delete [] tmp_buffer;
+ } else if (vinfo->picture.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) {
+ yuyv422_to_rgb24(src,img,width,height);
+ }
+
if (vinfo->picture.format.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24){
if (vinfo->picture.buf.length == width*height*3) {
memcpy(img, src, vinfo->picture.buf.length);
@@ -1621,7 +1689,13 @@ void Sensor::captureRGB(uint8_t *img, uint32_t gain, uint32_t stride) {
rgb24_memcpy( img, src, width, height);
}
}
- stop_picture(vinfo);
+
+ if (mSensorType == SENSOR_USB) {
+ releasebuf_and_stop_picture(vinfo);
+ } else {
+ stop_picture(vinfo);
+ }
+
#endif
}
diff --git a/v3/fake-pipeline2/Sensor.h b/v3/fake-pipeline2/Sensor.h
index 5ba1b57..8de02be 100755
--- a/v3/fake-pipeline2/Sensor.h
+++ b/v3/fake-pipeline2/Sensor.h
@@ -149,6 +149,8 @@ typedef enum camera_focus_mode_e {
CAM_FOCUS_MODE_CONTI_PIC,
}camera_focus_mode_t;
+#define IOCTL_MASK_ROTATE (1<<0)
+
class Sensor: private Thread, public virtual RefBase {
public:
@@ -164,7 +166,7 @@ class Sensor: private Thread, public virtual RefBase {
int getOutputFormat();
int halFormatToSensorFormat(uint32_t pixelfmt);
- status_t setOutputFormat(int width, int height, int pixelformat);
+ status_t setOutputFormat(int width, int height, int pixelformat, bool isjpeg);
void setPictureRotate(int rotate);
int getPictureRotate();
uint32_t getStreamUsage(int stream_type);
@@ -177,6 +179,7 @@ class Sensor: private Thread, public virtual RefBase {
int getStreamConfigurationDurations(uint32_t picSizes[], int64_t duration[], int size);
bool isStreaming();
bool isNeedRestart(uint32_t width, uint32_t height, uint32_t pixelformat);
+ status_t IoctlStateProbe(void);
void dump(int fd);
/*
* Access to scene
@@ -330,6 +333,8 @@ class Sensor: private Thread, public virtual RefBase {
}sensor_type_t;
enum sensor_type_e mSensorType;
+ unsigned int mIoctlSupport;
+ unsigned int msupportrotate;
/**
* Inherited Thread virtual overrides, and members only used by the
diff --git a/v3/fake-pipeline2/camera_hw.cpp b/v3/fake-pipeline2/camera_hw.cpp
index 68f4ee9..c98f154 100755
--- a/v3/fake-pipeline2/camera_hw.cpp
+++ b/v3/fake-pipeline2/camera_hw.cpp
@@ -182,6 +182,46 @@ int stop_capturing(struct VideoInfo *vinfo)
return res;
}
+int releasebuf_and_stop_capturing(struct VideoInfo *vinfo)
+{
+ enum v4l2_buf_type type;
+ int res = 0 ,ret;
+ int i;
+
+ if (!vinfo->isStreaming)
+ return -1;
+
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ if (-1 == ioctl(vinfo->fd, VIDIOC_STREAMOFF, &type)){
+ DBG_LOGB("VIDIOC_STREAMOFF, errno=%d", errno);
+ res = -1;
+ }
+
+ for (i = 0; i < (int)vinfo->preview.rb.count; ++i) {
+ if (-1 == munmap(vinfo->mem[i], vinfo->preview.buf.length)) {
+ DBG_LOGB("munmap failed errno=%d", errno);
+ res = -1;
+ }
+ }
+
+ vinfo->isStreaming = false;
+
+ vinfo->preview.format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ vinfo->preview.rb.memory = V4L2_MEMORY_MMAP;
+ vinfo->preview.rb.count = 0;
+
+ ret = ioctl(vinfo->fd, VIDIOC_REQBUFS, &vinfo->preview.rb);
+ if (ret < 0) {
+ DBG_LOGB("VIDIOC_REQBUFS failed: %s", strerror(errno));
+ //return ret;
+ }else{
+ DBG_LOGA("VIDIOC_REQBUFS delete buffer success\n");
+ }
+
+ return res;
+}
+
+
uintptr_t get_frame_phys(struct VideoInfo *vinfo)
{
CLEAR(vinfo->preview.buf);
@@ -252,10 +292,9 @@ int start_picture(struct VideoInfo *vinfo, int rotate)
int i;
enum v4l2_buf_type type;
struct v4l2_buffer buf;
+ bool usbcamera = false;
CLEAR(vinfo->picture.rb);
-
- stop_capturing(vinfo);
//step 1 : ioctl VIDIOC_S_FMT
ret = ioctl(vinfo->fd, VIDIOC_S_FMT, &vinfo->picture.format);
@@ -322,7 +361,13 @@ int start_picture(struct VideoInfo *vinfo, int rotate)
DBG_LOGA("already stream on\n");
}
- set_rotate_value(vinfo->fd,rotate);
+ if (strstr((const char *)vinfo->cap.driver, "uvcvideo")) {
+ usbcamera = true;
+ }
+ if (!usbcamera) {
+ set_rotate_value(vinfo->fd,rotate);
+ }
+
//step 5: Stream ON
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (-1 == ioctl(vinfo->fd, VIDIOC_STREAMON, &type))
@@ -393,6 +438,53 @@ void stop_picture(struct VideoInfo *vinfo)
}
+void releasebuf_and_stop_picture(struct VideoInfo *vinfo)
+{
+ enum v4l2_buf_type type;
+ struct v4l2_buffer buf;
+ int i,ret;
+
+ if (!vinfo->isPicture)
+ return ;
+
+ //QBUF
+ for (i = 0; i < (int)vinfo->picture.rb.count; ++i) {
+ CLEAR(buf);
+ buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ buf.memory = V4L2_MEMORY_MMAP;
+ buf.index = i;
+ if (-1 == ioctl(vinfo->fd, VIDIOC_QBUF, &buf))
+ DBG_LOGB("VIDIOC_QBUF failed, errno=%d\n", errno);
+ }
+
+ //stream off and unmap buffer
+ type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ if (-1 == ioctl(vinfo->fd, VIDIOC_STREAMOFF, &type))
+ DBG_LOGB("VIDIOC_STREAMOFF, errno=%d", errno);
+
+ for (i = 0; i < (int)vinfo->picture.rb.count; i++)
+ {
+ if (-1 == munmap(vinfo->mem_pic[i], vinfo->picture.buf.length))
+ DBG_LOGB("munmap failed errno=%d", errno);
+ }
+
+ vinfo->isPicture = false;
+
+ vinfo->picture.format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ vinfo->picture.rb.memory = V4L2_MEMORY_MMAP;
+ vinfo->picture.rb.count = 0;
+ ret = ioctl(vinfo->fd, VIDIOC_REQBUFS, &vinfo->picture.rb);
+ if (ret < 0) {
+ DBG_LOGB("VIDIOC_REQBUFS failed: %s", strerror(errno));
+ //return ret;
+ }else{
+ DBG_LOGA("VIDIOC_REQBUFS delete buffer success\n");
+ }
+
+ setBuffersFormat(vinfo);
+ start_capturing(vinfo);
+}
+
void camera_close(struct VideoInfo *vinfo)
{
if (NULL == vinfo) {
diff --git a/v3/fake-pipeline2/camera_hw.h b/v3/fake-pipeline2/camera_hw.h
index f4cb349..6ed581d 100755
--- a/v3/fake-pipeline2/camera_hw.h
+++ b/v3/fake-pipeline2/camera_hw.h
@@ -60,7 +60,9 @@ extern int setBuffersFormat(struct VideoInfo *cam_dev);
extern int start_capturing(struct VideoInfo *vinfo);
extern int start_picture(struct VideoInfo *vinfo,int rotate);
extern void stop_picture(struct VideoInfo *vinfo);
+extern void releasebuf_and_stop_picture(struct VideoInfo *vinfo);
extern int stop_capturing(struct VideoInfo *vinfo);
+extern int releasebuf_and_stop_capturing(struct VideoInfo *vinfo);
extern uintptr_t get_frame_phys(struct VideoInfo *vinfo);
diff --git a/v3/fake-pipeline2/util.c b/v3/fake-pipeline2/util.c
new file mode 100755
index 0000000..1314d7c
--- a/dev/null
+++ b/v3/fake-pipeline2/util.c
@@ -0,0 +1,73 @@
+#include <utils/Log.h>
+
+#include "util.h"
+#ifndef ALIGN
+#define ALIGN(b,w) (((b)+((w)-1))/(w)*(w))
+#endif
+
+static inline void yuv_to_rgb24(unsigned char y,unsigned char u,unsigned char v,unsigned char *rgb)
+{
+ register int r,g,b;
+ int rgb24;
+
+ r = (1192 * (y - 16) + 1634 * (v - 128) ) >> 10;
+ g = (1192 * (y - 16) - 833 * (v - 128) - 400 * (u -128) ) >> 10;
+ b = (1192 * (y - 16) + 2066 * (u - 128) ) >> 10;
+
+ r = r > 255 ? 255 : r < 0 ? 0 : r;
+ g = g > 255 ? 255 : g < 0 ? 0 : g;
+ b = b > 255 ? 255 : b < 0 ? 0 : b;
+
+ rgb24 = (int)((r <<16) | (g << 8)| b);
+
+ *rgb = (unsigned char)r;
+ rgb++;
+ *rgb = (unsigned char)g;
+ rgb++;
+ *rgb = (unsigned char)b;
+}
+
+void yuyv422_to_rgb24(unsigned char *buf, unsigned char *rgb, int width, int height)
+{
+ int x,y,z=0;
+ int blocks;
+
+ blocks = (width * height) * 2;
+
+ for (y = 0,z=0; y < blocks; y+=4,z+=6) {
+ unsigned char Y1, Y2, U, V;
+
+ Y1 = buf[y + 0];
+ U = buf[y + 1];
+ Y2 = buf[y + 2];
+ V = buf[y + 3];
+
+ yuv_to_rgb24(Y1, U, V, &rgb[z]);
+ yuv_to_rgb24(Y2, U, V, &rgb[z + 3]);
+ }
+}
+
+void nv21_to_rgb24(unsigned char *buf, unsigned char *rgb, int width, int height)
+{
+ int x,y,z=0;
+ int h,w;
+ int blocks;
+ unsigned char Y1, Y2, U, V;
+
+ blocks = (width * height) * 2;
+
+ for(h=0, z=0; h< height; h+=2){
+ for (y = 0; y < width*2; y+=2) {
+
+ Y1 = buf[ h*width + y + 0];
+ V = buf[ blocks/2 + h*width/2 + y%width + 0 ];
+ Y2 = buf[ h*width + y + 1];
+ U = buf[ blocks/2 + h*width/2 + y%width + 1 ];
+
+ yuv_to_rgb24(Y1, U, V, &rgb[z]);
+ yuv_to_rgb24(Y2, U, V, &rgb[z + 3]);
+ z+=6;
+ }
+ }
+}
+
diff --git a/v3/fake-pipeline2/util.h b/v3/fake-pipeline2/util.h
new file mode 100755
index 0000000..18969a8
--- a/dev/null
+++ b/v3/fake-pipeline2/util.h
@@ -0,0 +1,15 @@
+#ifndef __UTIL_H
+#define __UTIL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void yuyv422_to_rgb24(unsigned char *buf, unsigned char *rgb, int width, int height);
+void nv21_to_rgb24(unsigned char *buf, unsigned char *rgb, int width, int height);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif