From: Jun Tian Date: Thu, 24 Jan 2013 09:51:36 +0000 (+0800) Subject: Fix the issue: when taking pictures in a high frequence, the camera will be froze X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.1~1108^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c9ef429695734b81ff0d1bd844927e2cc1aa4c26;p=sdk%2Femulator%2Fqemu.git Fix the issue: when taking pictures in a high frequence, the camera will be froze Sometimes, when clicking the take picture in a high frequence, the camera would be froze. It caused by a short delay in the driver. Meanwhile, this patch clean up the source code to align to the windows and linux implementation. --- diff --git a/tizen/src/hw/maru_camera_darwin_converter.c b/tizen/src/hw/maru_camera_darwin_converter.c index 1037fc7900..67862e5c58 100644 --- a/tizen/src/hw/maru_camera_darwin_converter.c +++ b/tizen/src/hw/maru_camera_darwin_converter.c @@ -25,23 +25,19 @@ static void YUYVToYUV420(unsigned char *bufsrc, unsigned char *bufdest, int widt /* Convert pixel format to YUV420 */ void convert_frame(uint32_t pixel_format, int frame_width, int frame_height, - size_t frame_size, void* frame_pixels, void* video_buf) + size_t frame_size, void* frame_pixels, void* video_buf) { switch (pixel_format) { case V4L2_PIX_FMT_YUV420: - printf("format: V4L2_PIX_FMT_YUV420\n"); memcpy(video_buf, (void*)frame_pixels, (size_t)frame_size); break; case V4L2_PIX_FMT_YVU420: - printf("format: V4L2_PIX_FMT_YVU420\n"); YVU420ToYUV420(frame_pixels, video_buf, frame_width, frame_height); break; case V4L2_PIX_FMT_YUYV: - printf("format: V4L2_PIX_FMT_YUYV\n"); YUYVToYUV420(frame_pixels, video_buf, frame_width, frame_height); break; case V4L2_PIX_FMT_UYVY: // Mac default format - printf("format: V4L2_PIX_FMT_UYVY\n"); UYVYToYUV420(frame_pixels, video_buf, frame_width, frame_height); break; default: @@ -56,113 +52,113 @@ static void UYVYToYUV420(unsigned char *bufsrc, unsigned char *bufdest, int widt /* Source */ unsigned char *ptrsrcy1, *ptrsrcy2; - unsigned char *ptrsrcy3, *ptrsrcy4; - unsigned char *ptrsrccb1, *ptrsrccb2; - unsigned char *ptrsrccb3, *ptrsrccb4; - unsigned char *ptrsrccr1, *ptrsrccr2; - unsigned char *ptrsrccr3, *ptrsrccr4; - int srcystride, srcccstride; - - ptrsrcy1 = bufsrc + 1; - ptrsrcy2 = bufsrc + (width<<1) + 1; - ptrsrcy3 = bufsrc + (width<<1)*2 + 1; - ptrsrcy4 = bufsrc + (width<<1)*3 + 1; - - ptrsrccb1 = bufsrc; - ptrsrccb2 = bufsrc + (width<<1); - ptrsrccb3 = bufsrc + (width<<1)*2; - ptrsrccb4 = bufsrc + (width<<1)*3; - - ptrsrccr1 = bufsrc + 2; - ptrsrccr2 = bufsrc + (width<<1) + 2; - ptrsrccr3 = bufsrc + (width<<1)*2 + 2; - ptrsrccr4 = bufsrc + (width<<1)*3 + 2; - - srcystride = (width<<1)*3; - srcccstride = (width<<1)*3; + unsigned char *ptrsrcy3, *ptrsrcy4; + unsigned char *ptrsrccb1, *ptrsrccb2; + unsigned char *ptrsrccb3, *ptrsrccb4; + unsigned char *ptrsrccr1, *ptrsrccr2; + unsigned char *ptrsrccr3, *ptrsrccr4; + int srcystride, srcccstride; + + ptrsrcy1 = bufsrc + 1; + ptrsrcy2 = bufsrc + (width<<1) + 1; + ptrsrcy3 = bufsrc + (width<<1)*2 + 1; + ptrsrcy4 = bufsrc + (width<<1)*3 + 1; + + ptrsrccb1 = bufsrc; + ptrsrccb2 = bufsrc + (width<<1); + ptrsrccb3 = bufsrc + (width<<1)*2; + ptrsrccb4 = bufsrc + (width<<1)*3; + + ptrsrccr1 = bufsrc + 2; + ptrsrccr2 = bufsrc + (width<<1) + 2; + ptrsrccr3 = bufsrc + (width<<1)*2 + 2; + ptrsrccr4 = bufsrc + (width<<1)*3 + 2; + + srcystride = (width<<1)*3; + srcccstride = (width<<1)*3; /* Destination */ - unsigned char *ptrdesty1, *ptrdesty2; - unsigned char *ptrdesty3, *ptrdesty4; - unsigned char *ptrdestcb1, *ptrdestcb2; - unsigned char *ptrdestcr1, *ptrdestcr2; - int destystride, destccstride; - - ptrdesty1 = bufdest; - ptrdesty2 = bufdest + width; - ptrdesty3 = bufdest + width*2; - ptrdesty4 = bufdest + width*3; - - ptrdestcb1 = bufdest + width*height; - ptrdestcb2 = bufdest + width*height + (width>>1); - - ptrdestcr1 = bufdest + width*height + ((width*height) >> 2); - ptrdestcr2 = bufdest + width*height + ((width*height) >> 2) + (width>>1); - - destystride = (width)*3; - destccstride = (width>>1); - - for(j=0; j<(height/4); j++) - { - for(i=0;i<(width/2);i++) - { - (*ptrdesty1++) = (*ptrsrcy1); - (*ptrdesty2++) = (*ptrsrcy2); - (*ptrdesty3++) = (*ptrsrcy3); - (*ptrdesty4++) = (*ptrsrcy4); - - ptrsrcy1 += 2; - ptrsrcy2 += 2; - ptrsrcy3 += 2; - ptrsrcy4 += 2; - - (*ptrdesty1++) = (*ptrsrcy1); - (*ptrdesty2++) = (*ptrsrcy2); - (*ptrdesty3++) = (*ptrsrcy3); - (*ptrdesty4++) = (*ptrsrcy4); - - ptrsrcy1 += 2; - ptrsrcy2 += 2; - ptrsrcy3 += 2; - ptrsrcy4 += 2; - - (*ptrdestcb1++) = (*ptrsrccb1); - (*ptrdestcb2++) = (*ptrsrccb3); - - ptrsrccb1 += 4; - ptrsrccb3 += 4; - - (*ptrdestcr1++) = (*ptrsrccr1); - (*ptrdestcr2++) = (*ptrsrccr3); - - ptrsrccr1 += 4; - ptrsrccr3 += 4; - - } - - /* Update src pointers */ - ptrsrcy1 += srcystride; - ptrsrcy2 += srcystride; - ptrsrcy3 += srcystride; - ptrsrcy4 += srcystride; - - ptrsrccb1 += srcccstride; - ptrsrccb3 += srcccstride; - - ptrsrccr1 += srcccstride; - ptrsrccr3 += srcccstride; - - /* Update dest pointers */ - ptrdesty1 += destystride; - ptrdesty2 += destystride; - ptrdesty3 += destystride; - ptrdesty4 += destystride; - - ptrdestcb1 += destccstride; - ptrdestcb2 += destccstride; - - ptrdestcr1 += destccstride; - ptrdestcr2 += destccstride; + unsigned char *ptrdesty1, *ptrdesty2; + unsigned char *ptrdesty3, *ptrdesty4; + unsigned char *ptrdestcb1, *ptrdestcb2; + unsigned char *ptrdestcr1, *ptrdestcr2; + int destystride, destccstride; + + ptrdesty1 = bufdest; + ptrdesty2 = bufdest + width; + ptrdesty3 = bufdest + width*2; + ptrdesty4 = bufdest + width*3; + + ptrdestcb1 = bufdest + width*height; + ptrdestcb2 = bufdest + width*height + (width>>1); + + ptrdestcr1 = bufdest + width*height + ((width*height) >> 2); + ptrdestcr2 = bufdest + width*height + ((width*height) >> 2) + (width>>1); + + destystride = (width)*3; + destccstride = (width>>1); + + for(j=0; j<(height/4); j++) + { + for(i=0;i<(width/2);i++) + { + (*ptrdesty1++) = (*ptrsrcy1); + (*ptrdesty2++) = (*ptrsrcy2); + (*ptrdesty3++) = (*ptrsrcy3); + (*ptrdesty4++) = (*ptrsrcy4); + + ptrsrcy1 += 2; + ptrsrcy2 += 2; + ptrsrcy3 += 2; + ptrsrcy4 += 2; + + (*ptrdesty1++) = (*ptrsrcy1); + (*ptrdesty2++) = (*ptrsrcy2); + (*ptrdesty3++) = (*ptrsrcy3); + (*ptrdesty4++) = (*ptrsrcy4); + + ptrsrcy1 += 2; + ptrsrcy2 += 2; + ptrsrcy3 += 2; + ptrsrcy4 += 2; + + (*ptrdestcb1++) = (*ptrsrccb1); + (*ptrdestcb2++) = (*ptrsrccb3); + + ptrsrccb1 += 4; + ptrsrccb3 += 4; + + (*ptrdestcr1++) = (*ptrsrccr1); + (*ptrdestcr2++) = (*ptrsrccr3); + + ptrsrccr1 += 4; + ptrsrccr3 += 4; + + } + + /* Update src pointers */ + ptrsrcy1 += srcystride; + ptrsrcy2 += srcystride; + ptrsrcy3 += srcystride; + ptrsrcy4 += srcystride; + + ptrsrccb1 += srcccstride; + ptrsrccb3 += srcccstride; + + ptrsrccr1 += srcccstride; + ptrsrccr3 += srcccstride; + + /* Update dest pointers */ + ptrdesty1 += destystride; + ptrdesty2 += destystride; + ptrdesty3 += destystride; + ptrdesty4 += destystride; + + ptrdestcb1 += destccstride; + ptrdestcb2 += destccstride; + + ptrdestcr1 += destccstride; + ptrdestcr2 += destccstride; } } @@ -172,207 +168,207 @@ static void YVU420ToYUV420(unsigned char *bufsrc, unsigned char *bufdest, int wi /* Source*/ unsigned char *ptrsrcy1, *ptrsrcy2; - unsigned char *ptrsrcy3, *ptrsrcy4; - unsigned char *ptrsrccb1, *ptrsrccb2; - unsigned char *ptrsrccr1, *ptrsrccr2; - int srcystride, srcccstride; + unsigned char *ptrsrcy3, *ptrsrcy4; + unsigned char *ptrsrccb1, *ptrsrccb2; + unsigned char *ptrsrccr1, *ptrsrccr2; + int srcystride, srcccstride; - ptrsrcy1 = bufsrc; - ptrsrcy2 = bufsrc + width; - ptrsrcy3 = bufsrc + width*2; - ptrsrcy4 = bufsrc + width*3; + ptrsrcy1 = bufsrc; + ptrsrcy2 = bufsrc + width; + ptrsrcy3 = bufsrc + width*2; + ptrsrcy4 = bufsrc + width*3; - ptrsrccr1 = bufsrc + width*height; - ptrsrccr2 = bufsrc + width*height + (width>>1); + ptrsrccr1 = bufsrc + width*height; + ptrsrccr2 = bufsrc + width*height + (width>>1); - ptrsrccb1 = bufsrc + width*height + ((width*height) >> 2); - ptrsrccb2 = bufsrc + width*height + ((width*height) >> 2) + (width>>1); + ptrsrccb1 = bufsrc + width*height + ((width*height) >> 2); + ptrsrccb2 = bufsrc + width*height + ((width*height) >> 2) + (width>>1); - srcystride = (width)*3; - srcccstride = (width>>1); + srcystride = (width)*3; + srcccstride = (width>>1); /* Destination */ unsigned char *ptrdesty1, *ptrdesty2; - unsigned char *ptrdesty3, *ptrdesty4; - unsigned char *ptrdestcb1, *ptrdestcb2; - unsigned char *ptrdestcr1, *ptrdestcr2; - int destystride, destccstride; - - ptrdesty1 = bufdest; - ptrdesty2 = bufdest + width; - ptrdesty3 = bufdest + width*2; - ptrdesty4 = bufdest + width*3; - - ptrdestcb1 = bufdest + width*height; - ptrdestcb2 = bufdest + width*height + (width>>1); - - ptrdestcr1 = bufdest + width*height + ((width*height) >> 2); - ptrdestcr2 = bufdest + width*height + ((width*height) >> 2) + (width>>1); - - destystride = (width)*3; - destccstride = (width>>1); - - for(j=0; j<(height/4); j++) - { - for(i=0;i<(width/2);i++) - { - - (*ptrdesty1++) = (*ptrsrcy1++); - (*ptrdesty2++) = (*ptrsrcy2++); - (*ptrdesty3++) = (*ptrsrcy3++); - (*ptrdesty4++) = (*ptrsrcy4++); - (*ptrdesty1++) = (*ptrsrcy1++); - (*ptrdesty2++) = (*ptrsrcy2++); - (*ptrdesty3++) = (*ptrsrcy3++); - (*ptrdesty4++) = (*ptrsrcy4++); - - (*ptrdestcb1++) = (*ptrsrccb1++); - (*ptrdestcr1++) = (*ptrsrccr1++); - (*ptrdestcb2++) = (*ptrsrccb2++); - (*ptrdestcr2++) = (*ptrsrccr2++); - - } + unsigned char *ptrdesty3, *ptrdesty4; + unsigned char *ptrdestcb1, *ptrdestcb2; + unsigned char *ptrdestcr1, *ptrdestcr2; + int destystride, destccstride; + + ptrdesty1 = bufdest; + ptrdesty2 = bufdest + width; + ptrdesty3 = bufdest + width*2; + ptrdesty4 = bufdest + width*3; + + ptrdestcb1 = bufdest + width*height; + ptrdestcb2 = bufdest + width*height + (width>>1); + + ptrdestcr1 = bufdest + width*height + ((width*height) >> 2); + ptrdestcr2 = bufdest + width*height + ((width*height) >> 2) + (width>>1); + + destystride = (width)*3; + destccstride = (width>>1); + + for(j=0; j<(height/4); j++) + { + for(i=0;i<(width/2);i++) + { + + (*ptrdesty1++) = (*ptrsrcy1++); + (*ptrdesty2++) = (*ptrsrcy2++); + (*ptrdesty3++) = (*ptrsrcy3++); + (*ptrdesty4++) = (*ptrsrcy4++); + (*ptrdesty1++) = (*ptrsrcy1++); + (*ptrdesty2++) = (*ptrsrcy2++); + (*ptrdesty3++) = (*ptrsrcy3++); + (*ptrdesty4++) = (*ptrsrcy4++); + + (*ptrdestcb1++) = (*ptrsrccb1++); + (*ptrdestcr1++) = (*ptrsrccr1++); + (*ptrdestcb2++) = (*ptrsrccb2++); + (*ptrdestcr2++) = (*ptrsrccr2++); + + } + + /* Update src pointers */ + ptrsrcy1 += srcystride; + ptrsrcy2 += srcystride; + ptrsrcy3 += srcystride; + ptrsrcy4 += srcystride; + + ptrsrccb1 += srcccstride; + ptrsrccb2 += srcccstride; + + ptrsrccr1 += srcccstride; + ptrsrccr2 += srcccstride; + + /* Update dest pointers */ + ptrdesty1 += destystride; + ptrdesty2 += destystride; + ptrdesty3 += destystride; + ptrdesty4 += destystride; + + ptrdestcb1 += destccstride; + ptrdestcb2 += destccstride; + + ptrdestcr1 += destccstride; + ptrdestcr2 += destccstride; - /* Update src pointers */ - ptrsrcy1 += srcystride; - ptrsrcy2 += srcystride; - ptrsrcy3 += srcystride; - ptrsrcy4 += srcystride; - - ptrsrccb1 += srcccstride; - ptrsrccb2 += srcccstride; - - ptrsrccr1 += srcccstride; - ptrsrccr2 += srcccstride; - - /* Update dest pointers */ - ptrdesty1 += destystride; - ptrdesty2 += destystride; - ptrdesty3 += destystride; - ptrdesty4 += destystride; - - ptrdestcb1 += destccstride; - ptrdestcb2 += destccstride; - - ptrdestcr1 += destccstride; - ptrdestcr2 += destccstride; - - } + } } static void YUYVToYUV420(unsigned char *bufsrc, unsigned char *bufdest, int width, int height) { - int i, j; + int i, j; /* Source*/ unsigned char *ptrsrcy1, *ptrsrcy2; - unsigned char *ptrsrcy3, *ptrsrcy4; - unsigned char *ptrsrccb1, *ptrsrccb2; - unsigned char *ptrsrccb3, *ptrsrccb4; - unsigned char *ptrsrccr1, *ptrsrccr2; - unsigned char *ptrsrccr3, *ptrsrccr4; - int srcystride, srcccstride; - - ptrsrcy1 = bufsrc ; - ptrsrcy2 = bufsrc + (width<<1) ; - ptrsrcy3 = bufsrc + (width<<1)*2 ; - ptrsrcy4 = bufsrc + (width<<1)*3 ; - - ptrsrccb1 = bufsrc + 1; - ptrsrccb2 = bufsrc + (width<<1) + 1; - ptrsrccb3 = bufsrc + (width<<1)*2 + 1; - ptrsrccb4 = bufsrc + (width<<1)*3 + 1; - - ptrsrccr1 = bufsrc + 3; - ptrsrccr2 = bufsrc + (width<<1) + 3; - ptrsrccr3 = bufsrc + (width<<1)*2 + 3; - ptrsrccr4 = bufsrc + (width<<1)*3 + 3; - - srcystride = (width<<1)*3; - srcccstride = (width<<1)*3; + unsigned char *ptrsrcy3, *ptrsrcy4; + unsigned char *ptrsrccb1, *ptrsrccb2; + unsigned char *ptrsrccb3, *ptrsrccb4; + unsigned char *ptrsrccr1, *ptrsrccr2; + unsigned char *ptrsrccr3, *ptrsrccr4; + int srcystride, srcccstride; + + ptrsrcy1 = bufsrc ; + ptrsrcy2 = bufsrc + (width<<1) ; + ptrsrcy3 = bufsrc + (width<<1)*2 ; + ptrsrcy4 = bufsrc + (width<<1)*3 ; + + ptrsrccb1 = bufsrc + 1; + ptrsrccb2 = bufsrc + (width<<1) + 1; + ptrsrccb3 = bufsrc + (width<<1)*2 + 1; + ptrsrccb4 = bufsrc + (width<<1)*3 + 1; + + ptrsrccr1 = bufsrc + 3; + ptrsrccr2 = bufsrc + (width<<1) + 3; + ptrsrccr3 = bufsrc + (width<<1)*2 + 3; + ptrsrccr4 = bufsrc + (width<<1)*3 + 3; + + srcystride = (width<<1)*3; + srcccstride = (width<<1)*3; /* Destination */ unsigned char *ptrdesty1, *ptrdesty2; - unsigned char *ptrdesty3, *ptrdesty4; - unsigned char *ptrdestcb1, *ptrdestcb2; - unsigned char *ptrdestcr1, *ptrdestcr2; - int destystride, destccstride; - - ptrdesty1 = bufdest; - ptrdesty2 = bufdest + width; - ptrdesty3 = bufdest + width*2; - ptrdesty4 = bufdest + width*3; - - ptrdestcb1 = bufdest + width*height; - ptrdestcb2 = bufdest + width*height + (width>>1); - - ptrdestcr1 = bufdest + width*height + ((width*height) >> 2); - ptrdestcr2 = bufdest + width*height + ((width*height) >> 2) + (width>>1); - - destystride = (width)*3; - destccstride = (width>>1); - - for(j=0; j<(height/4); j++) - { - for(i=0;i<(width/2);i++) - { - (*ptrdesty1++) = (*ptrsrcy1); - (*ptrdesty2++) = (*ptrsrcy2); - (*ptrdesty3++) = (*ptrsrcy3); - (*ptrdesty4++) = (*ptrsrcy4); - - ptrsrcy1 += 2; - ptrsrcy2 += 2; - ptrsrcy3 += 2; - ptrsrcy4 += 2; - - (*ptrdesty1++) = (*ptrsrcy1); - (*ptrdesty2++) = (*ptrsrcy2); - (*ptrdesty3++) = (*ptrsrcy3); - (*ptrdesty4++) = (*ptrsrcy4); - - ptrsrcy1 += 2; - ptrsrcy2 += 2; - ptrsrcy3 += 2; - ptrsrcy4 += 2; - - (*ptrdestcb1++) = (*ptrsrccb1); - (*ptrdestcb2++) = (*ptrsrccb3); - - ptrsrccb1 += 4; - ptrsrccb3 += 4; - - (*ptrdestcr1++) = (*ptrsrccr1); - (*ptrdestcr2++) = (*ptrsrccr3); - - ptrsrccr1 += 4; - ptrsrccr3 += 4; - - } - - /* Update src pointers */ - ptrsrcy1 += srcystride; - ptrsrcy2 += srcystride; - ptrsrcy3 += srcystride; - ptrsrcy4 += srcystride; - - ptrsrccb1 += srcccstride; - ptrsrccb3 += srcccstride; - - ptrsrccr1 += srcccstride; - ptrsrccr3 += srcccstride; - - /* Update dest pointers */ - ptrdesty1 += destystride; - ptrdesty2 += destystride; - ptrdesty3 += destystride; - ptrdesty4 += destystride; - - ptrdestcb1 += destccstride; - ptrdestcb2 += destccstride; - - ptrdestcr1 += destccstride; - ptrdestcr2 += destccstride; - } + unsigned char *ptrdesty3, *ptrdesty4; + unsigned char *ptrdestcb1, *ptrdestcb2; + unsigned char *ptrdestcr1, *ptrdestcr2; + int destystride, destccstride; + + ptrdesty1 = bufdest; + ptrdesty2 = bufdest + width; + ptrdesty3 = bufdest + width*2; + ptrdesty4 = bufdest + width*3; + + ptrdestcb1 = bufdest + width*height; + ptrdestcb2 = bufdest + width*height + (width>>1); + + ptrdestcr1 = bufdest + width*height + ((width*height) >> 2); + ptrdestcr2 = bufdest + width*height + ((width*height) >> 2) + (width>>1); + + destystride = (width)*3; + destccstride = (width>>1); + + for(j=0; j<(height/4); j++) + { + for(i=0;i<(width/2);i++) + { + (*ptrdesty1++) = (*ptrsrcy1); + (*ptrdesty2++) = (*ptrsrcy2); + (*ptrdesty3++) = (*ptrsrcy3); + (*ptrdesty4++) = (*ptrsrcy4); + + ptrsrcy1 += 2; + ptrsrcy2 += 2; + ptrsrcy3 += 2; + ptrsrcy4 += 2; + + (*ptrdesty1++) = (*ptrsrcy1); + (*ptrdesty2++) = (*ptrsrcy2); + (*ptrdesty3++) = (*ptrsrcy3); + (*ptrdesty4++) = (*ptrsrcy4); + + ptrsrcy1 += 2; + ptrsrcy2 += 2; + ptrsrcy3 += 2; + ptrsrcy4 += 2; + + (*ptrdestcb1++) = (*ptrsrccb1); + (*ptrdestcb2++) = (*ptrsrccb3); + + ptrsrccb1 += 4; + ptrsrccb3 += 4; + + (*ptrdestcr1++) = (*ptrsrccr1); + (*ptrdestcr2++) = (*ptrsrccr3); + + ptrsrccr1 += 4; + ptrsrccr3 += 4; + + } + + /* Update src pointers */ + ptrsrcy1 += srcystride; + ptrsrcy2 += srcystride; + ptrsrcy3 += srcystride; + ptrsrcy4 += srcystride; + + ptrsrccb1 += srcccstride; + ptrsrccb3 += srcccstride; + + ptrsrccr1 += srcccstride; + ptrsrccr3 += srcccstride; + + /* Update dest pointers */ + ptrdesty1 += destystride; + ptrdesty2 += destystride; + ptrdesty3 += destystride; + ptrdesty4 += destystride; + + ptrdestcb1 += destccstride; + ptrdestcb2 += destccstride; + + ptrdestcr1 += destccstride; + ptrdestcr2 += destccstride; + } } diff --git a/tizen/src/hw/maru_camera_darwin_pci.m b/tizen/src/hw/maru_camera_darwin_pci.m index 7f590c22f7..442290f1fe 100644 --- a/tizen/src/hw/maru_camera_darwin_pci.m +++ b/tizen/src/hw/maru_camera_darwin_pci.m @@ -105,6 +105,7 @@ static MaruCamState *g_state = NULL; static uint32_t ready_count = 0; static uint32_t cur_fmt_idx = 0; static uint32_t cur_frame_idx = 0; +static void *grab_buf; /*********************************** * Mac camera helper functions @@ -191,10 +192,8 @@ static uint32_t get_sizeimage(uint32_t pixfmt, uint32_t width, uint32_t height) @interface MaruCameraDriver : NSObject { QTCaptureSession *mCaptureSession; - //QTCaptureMovieFileOutput *mCaptureMovieFileOutput; - QTCaptureVideoPreviewOutput *mCaptureVideoPreviewOutput; QTCaptureDeviceInput *mCaptureVideoDeviceInput; - QTCaptureDeviceInput *mCaptureAudioDeviceInput; + QTCaptureVideoPreviewOutput *mCaptureVideoPreviewOutput; CVImageBufferRef mCurrentImageBuffer; CVImageBufferRef imageBuffer; @@ -204,6 +203,7 @@ static uint32_t get_sizeimage(uint32_t pixfmt, uint32_t width, uint32_t height) - (MaruCameraDriver*)init; - (int)startCapture:(int)width:(int)height; +- (int)stopCapture; - (int)readFrame:(void*)video_buf; - (int)setCaptureFormat:(int)width:(int)height:(int)pix_format; - (int)getCaptureFormat:(int)width:(int)height:(int)pix_format; @@ -290,48 +290,50 @@ static uint32_t get_sizeimage(uint32_t pixfmt, uint32_t width, uint32_t height) if ([mCaptureSession isRunning]) { while(!mCaptureIsStarted) { // Wait Until Capture is started - [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 1]]; + [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: 0.5]]; } - INFO("Capture session started!\n"); ret = 0; } return ret; } +- (int)stopCapture +{ + if ([mCaptureSession isRunning]) { + [mCaptureSession stopRunning]; + } +} + - (int)readFrame:(void*)video_buf { - int ret = -1; NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; @synchronized (self) { if (mCurrentImageBuffer != nil) { + CVPixelBufferLockBaseAddress(mCurrentImageBuffer, 0); const uint32_t pixel_format = corevideo_to_fourcc(CVPixelBufferGetPixelFormatType(mCurrentImageBuffer)); const int frame_width = CVPixelBufferGetWidth(mCurrentImageBuffer); const int frame_height = CVPixelBufferGetHeight(mCurrentImageBuffer); const size_t frame_size =CVPixelBufferGetBytesPerRow(mCurrentImageBuffer) * frame_height; - INFO("buffer(%p), pixel_format(%d,%.4s), frame_width(%d), frame_height(%d0, frame_size(%d)\n", - mCurrentImageBuffer, (int)pixel_format, (const char*)&pixel_format, frame_width, frame_height, (int)frame_size); - - //convert frame to v4l2 format - CVPixelBufferLockBaseAddress(mCurrentImageBuffer, 0); const void* frame_pixels = CVPixelBufferGetBaseAddress(mCurrentImageBuffer); - if (frame_pixels != nil && video_buf != nil) { - convert_frame(pixel_format, frame_width, frame_height, - frame_size, (void*)frame_pixels, video_buf); - } else { - INFO("Unable to obtain framebuffer"); - return -1; - } + + /* + INFO("buffer(%p), pixel_format(%d,%.4s), frame_width(%d), frame_height(%d), frame_size(%d)\n", + mCurrentImageBuffer, (int)pixel_format, (const char*)&pixel_format, + frame_width, frame_height, (int)frame_size); + */ + + // convert frame to v4l2 format + convert_frame(pixel_format, frame_width, frame_height, + frame_size, (void*)frame_pixels, video_buf); CVPixelBufferUnlockBaseAddress(mCurrentImageBuffer, 0); + [pool release]; return 0; - } else { - //INFO("%s, First frame not captured ?\n", __FUNCTION__); - return 1; } } [pool release]; - return ret; + return -1; } - (int)setCaptureFormat:(int)width:(int)height:(int)pix_format @@ -385,7 +387,6 @@ static uint32_t get_sizeimage(uint32_t pixfmt, uint32_t width, uint32_t height) { [mCaptureSession release]; [mCaptureVideoDeviceInput release]; - [mCaptureAudioDeviceInput release]; [mCaptureVideoPreviewOutput release]; [super dealloc]; } @@ -421,60 +422,62 @@ struct MaruCameraDevice { /* Golbal representation of the Maru camera */ MaruCameraDevice *mcd = NULL; -static int marucam_device_read_frame() +static void __raise_err_intr() { - int ret; - void* tmp_buf; - - if (g_state->streamon == 0) { - INFO("%s, %d, Streaming is off, exiting ...\n", __FUNCTION__, __LINE__); - return -1; - } - qemu_mutex_lock(&g_state->thread_mutex); - if (g_state->req_frame == 0) { - qemu_mutex_unlock(&g_state->thread_mutex); - camera_sleep(30); - //INFO("%s, %d, req_frame = 0, next loop\n", __FUNCTION__, __LINE__); - return 0; + if (g_state->streamon) { + g_state->req_frame = 0; /* clear request */ + g_state->isr = 0x08; /* set a error flag of rasing a interrupt */ + qemu_bh_schedule(g_state->tx_bh); } - tmp_buf = g_state->vaddr + g_state->buf_size * (g_state->req_frame - 1); qemu_mutex_unlock(&g_state->thread_mutex); +} - ret = [mcd->driver readFrame: tmp_buf]; - //INFO("%s, %d, ret:%d\n", __FUNCTION__, __LINE__, ret); - if (ret == -1) { - //INFO("%s, Capture error\n", __FUNCTION__); - return -1; - } - if(ret == 0) { - //INFO("%s, Capture a frame\n", __FUNCTION__); - } - if(ret == 1) { - //INFO("%s, Capture first frame missed\n", __FUNCTION__); - } +static int marucam_device_read_frame() +{ + int ret; + void* tmp_buf; qemu_mutex_lock(&g_state->thread_mutex); if (g_state->streamon) { + if (ready_count < MARUCAM_SKIPFRAMES) { + /* skip a frame cause first some frame are distorted */ + ++ready_count; + INFO("Skip %d frame\n", ready_count); + qemu_mutex_unlock(&g_state->thread_mutex); + return 0; + } + + if (g_state->req_frame == 0) { + //INFO("There is no request\n"); + qemu_mutex_unlock(&g_state->thread_mutex); + return 0; + } + + // Grab the camera frame into temp buffer + ret = [mcd->driver readFrame: grab_buf]; + if (ret < 0) { + INFO("%s, Capture error\n", __FUNCTION__); + qemu_mutex_unlock(&g_state->thread_mutex); + __raise_err_intr(); + return -1; + } + + tmp_buf = g_state->vaddr + g_state->buf_size * (g_state->req_frame - 1); + memcpy(tmp_buf, grab_buf, g_state->buf_size); g_state->req_frame = 0; // clear request g_state->isr |= 0x01; // set a flag of rasing a interrupt qemu_bh_schedule(g_state->tx_bh); - ret = 1; - } else { - ret = -1; } qemu_mutex_unlock(&g_state->thread_mutex); - return ret; + return 0; } /* Worker thread to grab frames to the preview window */ static void *marucam_worker_thread(void *thread_param) { - //MaruCamState *state = (MaruCamState*)thread_param; - while (1) { qemu_mutex_lock(&g_state->thread_mutex); - // Wait on the condition qemu_cond_wait(&g_state->thread_cond, &g_state->thread_mutex); qemu_mutex_unlock(&g_state->thread_mutex); @@ -482,18 +485,20 @@ static void *marucam_worker_thread(void *thread_param) break; } + //convert_trial = 10; + ready_count = 0; + /* Loop: capture frame -> convert format -> render to screen */ while (1) { if (g_state->streamon) { if (marucam_device_read_frame() < 0) { - INFO("Streaming is off ...\n"); - break; + INFO("Streaming is off ...\n"); + break; } } else { INFO("Streaming is off ...\n"); break; } - //camera_sleep(50); } } @@ -534,14 +539,12 @@ void marucam_device_open(MaruCamState* state) param->top = 0; mcd = (MaruCameraDevice*)malloc(sizeof(MaruCameraDevice)); - if (mcd != NULL) { - memset(mcd, 0, sizeof(MaruCameraDevice)); - } else { + if (mcd == NULL) { ERR("%s: MaruCameraDevice allocate failed\n", __FUNCTION__); + return; } - //qemu_mutex_lock(&state->thread_mutex); + memset(mcd, 0, sizeof(MaruCameraDevice)); mcd->driver = [[MaruCameraDriver alloc] init]; - //qemu_mutex_unlock(&state->thread_mutex); if (mcd->driver == nil) { INFO("Camera device open failed\n"); return; @@ -571,24 +574,34 @@ void marucam_device_start_preview(MaruCamState* state) MaruCamParam *param = state->param; param->top = 0; - ready_count = 0; + //ready_count = 0; width = supported_dst_frames[cur_frame_idx].width; height = supported_dst_frames[cur_frame_idx].height; pixfmt = supported_dst_pixfmts[cur_fmt_idx].fmt; state->buf_size = get_sizeimage(pixfmt, width, height); - INFO("Pixfmt(%c%c%c%c), W:H(%d:%d), buf size(%u), frame idx(%d), fmt idx(%d)\n", - (char)(pixfmt), (char)(pixfmt >> 8), - (char)(pixfmt >> 16), (char)(pixfmt >> 24), - width, height, state->buf_size, - cur_frame_idx, cur_fmt_idx); + /*INFO("Pixfmt(%c%c%c%c), W:H(%d:%d), buf size(%u), frame idx(%d), fmt idx(%d)\n", + (char)(pixfmt), (char)(pixfmt >> 8), + (char)(pixfmt >> 16), (char)(pixfmt >> 24), + width, height, state->buf_size, + cur_frame_idx, cur_fmt_idx); + */ - if (mcd->driver != nil) { - [mcd->driver startCapture: width: height]; - } else { + if (mcd->driver == nil) { ERR("%s: Start capture failed: vaild device", __FUNCTION__); return; } + [mcd->driver startCapture: width: height]; + + if (grab_buf) { + g_free(grab_buf); + grab_buf = NULL; + } + grab_buf = (void *)malloc(state->buf_size); + if (grab_buf == NULL) { + param->errCode = ENOMEM; + return; + } // Enable the condition to capture frames now qemu_mutex_lock(&state->thread_mutex); @@ -606,9 +619,19 @@ void marucam_device_stop_preview(MaruCamState* state) param->top = 0; INFO("Stopping preview ...\n"); + if (mcd->driver != nil) { + [mcd->driver stopCapture]; + } + qemu_mutex_lock(&state->thread_mutex); state->streamon = 0; qemu_mutex_unlock(&state->thread_mutex); + + if (grab_buf) { + g_free(grab_buf); + grab_buf = NULL; + } + state->buf_size = 0; } /* MARUCAM_CMD_S_PARAM */ @@ -724,7 +747,7 @@ void marucam_device_g_fmt(MaruCamState* state) void marucam_device_try_fmt(MaruCamState* state) { - INFO("Try device frame format, use default setting ...\n"); + //INFO("Try device frame format, use default setting ...\n"); } /* Get specific pixelformat description */ @@ -775,29 +798,29 @@ void marucam_device_qctrl(MaruCamState* state) id = param->stack[0]; switch (id) { - case V4L2_CID_BRIGHTNESS: - INFO("V4L2_CID_BRIGHTNESS\n"); - memcpy((void*)name, (void*)"brightness", 32); - i = 0; - break; - case V4L2_CID_CONTRAST: - INFO("V4L2_CID_CONTRAST\n"); - memcpy((void*)name, (void*)"contrast", 32); - i = 1; - break; - case V4L2_CID_SATURATION: - INFO("V4L2_CID_SATURATION\n"); - memcpy((void*)name, (void*)"saturation", 32); - i = 2; - break; - case V4L2_CID_SHARPNESS: - INFO("V4L2_CID_SHARPNESS\n"); - memcpy((void*)name, (void*)"sharpness", 32); - i = 3; - break; - default: - param->errCode = EINVAL; - return; + case V4L2_CID_BRIGHTNESS: + INFO("V4L2_CID_BRIGHTNESS\n"); + memcpy((void*)name, (void*)"brightness", 32); + i = 0; + break; + case V4L2_CID_CONTRAST: + INFO("V4L2_CID_CONTRAST\n"); + memcpy((void*)name, (void*)"contrast", 32); + i = 1; + break; + case V4L2_CID_SATURATION: + INFO("V4L2_CID_SATURATION\n"); + memcpy((void*)name, (void*)"saturation", 32); + i = 2; + break; + case V4L2_CID_SHARPNESS: + INFO("V4L2_CID_SHARPNESS\n"); + memcpy((void*)name, (void*)"sharpness", 32); + i = 3; + break; + default: + param->errCode = EINVAL; + return; } param->stack[0] = id;