summaryrefslogtreecommitdiff
path: root/v4l2_vdin.cpp (plain)
blob: 38ae48a4989d4ff889a29f401b2a9cb768becc7f
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18//reinclude because of a bug with the log macros
19//#define LOG_NDEBUG 0
20#define LOG_TAG "V4L2VINSOURCE"
21#include <utils/Log.h>
22#include <utils/String8.h>
23
24#include <signal.h>
25#include <stdio.h>
26#include <stdlib.h>
27#include <string.h>
28#include <fcntl.h>
29#include <unistd.h>
30#include <errno.h>
31#include <sys/ioctl.h>
32#include <sys/mman.h>
33#include <sys/select.h>
34#include <linux/videodev2.h>
35#include <sys/time.h>
36
37#include <cutils/properties.h>
38#include <sys/types.h>
39#include <sys/stat.h>
40
41#include "v4l2_vdin.h"
42#include <ui/GraphicBufferMapper.h>
43#include <ui/GraphicBuffer.h>
44#include <linux/videodev2.h>
45
46namespace android {
47
48#define V4L2_ROTATE_ID 0x980922
49
50#ifndef container_of
51#define container_of(ptr, type, member) ({ \
52 const typeof(((type *) 0)->member) *__mptr = (ptr); \
53 (type *) ((char *) __mptr - (char *)(&((type *)0)->member)); })
54#endif
55
56#define ALIGN(b,w) (((b)+((w)-1))/(w)*(w))
57
58static size_t getBufSize(int format, int width, int height)
59{
60 size_t buf_size = 0;
61 switch (format) {
62 case V4L2_PIX_FMT_YVU420:
63 case V4L2_PIX_FMT_NV21:
64 buf_size = width * height * 3 / 2;
65 break;
66 case V4L2_PIX_FMT_YUYV:
67 case V4L2_PIX_FMT_RGB565:
68 case V4L2_PIX_FMT_RGB565X:
69 buf_size = width * height * 2;
70 break;
71 case V4L2_PIX_FMT_RGB24:
72 buf_size = width * height * 3;
73 break;
74 case V4L2_PIX_FMT_RGB32:
75 buf_size = width * height * 4;
76 break;
77 default:
78 ALOGE("Invalid format");
79 buf_size = width * height * 3 / 2;
80 }
81 return buf_size;
82}
83
84static void two_bytes_per_pixel_memcpy_align32(unsigned char *dst, unsigned char *src, int width, int height)
85{
86 int stride = (width + 31) & ( ~31);
87 int w, h;
88 for (h=0; h<height; h++)
89 {
90 memcpy( dst, src, width*2);
91 dst += width*2;
92 src += stride*2;
93 }
94}
95
96static void nv21_memcpy_align32(unsigned char *dst, unsigned char *src, int width, int height)
97{
98 int stride = (width + 31) & ( ~31);
99 int w, h;
100 for (h=0; h<height*3/2; h++)
101 {
102 memcpy( dst, src, width);
103 dst += width;
104 src += stride;
105 }
106}
107
108static void yv12_memcpy_align32(unsigned char *dst, unsigned char *src, int width, int height)
109{
110 int new_width = (width + 63) & ( ~63);
111 int stride;
112 int w, h;
113 for (h=0; h<height; h++)
114 {
115 memcpy( dst, src, width);
116 dst += width;
117 src += new_width;
118 }
119
120 stride = ALIGN(width/2, 16);
121 for (h=0; h<height; h++)
122 {
123 memcpy( dst, src, width/2);
124 dst += stride;
125 src += new_width/2;
126 }
127}
128
129static void rgb24_memcpy_align32(unsigned char *dst, unsigned char *src, int width, int height)
130{
131 int stride = (width + 31) & ( ~31);
132 int w, h;
133 for (h=0; h<height; h++)
134 {
135 memcpy( dst, src, width*3);
136 dst += width*3;
137 src += stride*3;
138 }
139}
140
141static void rgb32_memcpy_align32(unsigned char *dst, unsigned char *src, int width, int height)
142{
143 int stride = (width + 31) & ( ~31);
144 int w, h;
145 for (h=0; h<height; h++)
146 {
147 memcpy( dst, src, width*4);
148 dst += width*4;
149 src += stride*4;
150 }
151}
152
153static int getNativeWindowFormat(int format)
154{
155 int nativeFormat = HAL_PIXEL_FORMAT_YCbCr_422_I;
156
157 switch(format){
158 case V4L2_PIX_FMT_YVU420:
159 nativeFormat = HAL_PIXEL_FORMAT_YV12;
160 break;
161 case V4L2_PIX_FMT_NV21:
162 nativeFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
163 break;
164 case V4L2_PIX_FMT_YUYV:
165 nativeFormat = HAL_PIXEL_FORMAT_YCbCr_422_I;
166 break;
167 case V4L2_PIX_FMT_RGB565:
168 nativeFormat = HAL_PIXEL_FORMAT_RGB_565;
169 break;
170 case V4L2_PIX_FMT_RGB24:
171 nativeFormat = HAL_PIXEL_FORMAT_RGB_888;
172 break;
173 case V4L2_PIX_FMT_RGB32:
174 nativeFormat = HAL_PIXEL_FORMAT_RGBA_8888;
175 break;
176 default:
177 ALOGE("Invalid format,Use default format");
178 }
179 return nativeFormat;
180}
181
182
183static ANativeWindowBuffer* handle_to_buffer(buffer_handle_t *handle)
184{
185 return container_of(handle, ANativeWindowBuffer, handle);
186}
187
188vdin_screen_source::vdin_screen_source()
189 : mCameraHandle(-1),
190 mVideoInfo(NULL)
191{
192 ALOGV("%s %d", __FUNCTION__, __LINE__);
193}
194
195int vdin_screen_source::init(int id){
196 ALOGV("%s %d", __FUNCTION__, __LINE__);
197 if (id == 0) {
198 mCameraHandle = open("/dev/video11", O_RDWR| O_NONBLOCK);
199 if (mCameraHandle < 0)
200 {
201 ALOGE("[%s %d] mCameraHandle:%x [%s]", __FUNCTION__, __LINE__, mCameraHandle,strerror(errno));
202 return -1;
203 }
204 } else {
205 mCameraHandle = open("/dev/video12", O_RDWR| O_NONBLOCK);
206 if (mCameraHandle < 0)
207 {
208 ALOGE("[%s %d] mCameraHandle:%x [%s]", __FUNCTION__, __LINE__, mCameraHandle,strerror(errno));
209 return -1;
210 }
211 }
212 mVideoInfo = (struct VideoInfo *) calloc (1, sizeof (struct VideoInfo));
213 if (mVideoInfo == NULL)
214 {
215 ALOGE("[%s %d] no memory for mVideoInfo", __FUNCTION__, __LINE__);
216 close(mCameraHandle);
217 return NO_MEMORY;
218 }
219 mBufferCount = 4;
220 for (int i = 0; i < mBufferCount; i++) {
221 src_temp[i] = NULL;
222 }
223 mPixelFormat = V4L2_PIX_FMT_NV21;
224 mNativeWindowPixelFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
225 mFrameWidth = 1280;
226 mFrameHeight = 720;
227 mBufferSize = mFrameWidth * mFrameHeight * 3/2;
228 mSetStateCB = NULL;
229 mState = STOP;
230 mANativeWindow = NULL;
231 mFrameType = 0;
232 mWorkThread = NULL;
233 mDataCB = NULL;
234 mOpen = false;
235 return NO_ERROR;
236}
237
238vdin_screen_source::~vdin_screen_source()
239{
240 if (mVideoInfo)
241 free (mVideoInfo);
242 if (mCameraHandle >= 0)
243 close(mCameraHandle);
244}
245
246int vdin_screen_source::start_v4l2_device()
247{
248 int ret = -1;
249
250 ALOGV("[%s %d] mCameraHandle:%x", __FUNCTION__, __LINE__, mCameraHandle);
251
252 ioctl(mCameraHandle, VIDIOC_QUERYCAP, &mVideoInfo->cap);
253
254 mVideoInfo->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
255 mVideoInfo->rb.memory = V4L2_MEMORY_MMAP;
256 mVideoInfo->rb.count = mBufferCount;
257
258 ret = ioctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
259
260 if (ret < 0) {
261 ALOGE("[%s %d] VIDIOC_REQBUFS:%d mCameraHandle:%x", __FUNCTION__, __LINE__, ret, mCameraHandle);
262 return ret;
263 }
264
265 for (int i = 0; i < mBufferCount; i++) {
266 memset (&mVideoInfo->buf, 0, sizeof (struct v4l2_buffer));
267
268 mVideoInfo->buf.index = i;
269 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
270 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
271
272 ret = ioctl (mCameraHandle, VIDIOC_QUERYBUF, &mVideoInfo->buf);
273 if (ret < 0) {
274 ALOGE("[%s %d]VIDIOC_QUERYBUF %d failed", __FUNCTION__, __LINE__, i);
275 return ret;
276 }
277 mVideoInfo->canvas[i] = mVideoInfo->buf.reserved;
278 mVideoInfo->mem[i] = (long *)mmap (0, mVideoInfo->buf.length, PROT_READ | PROT_WRITE,
279 MAP_SHARED, mCameraHandle, mVideoInfo->buf.m.offset);
280
281 if (mVideoInfo->mem[i] == MAP_FAILED) {
282 ALOGE("[%s %d] MAP_FAILED", __FUNCTION__, __LINE__);
283 return -1;
284 }
285 mVideoInfo->refcount[i] = 0;
286 mBufs.add(mVideoInfo->mem[i],i);
287 if (mFrameWidth %32 != 0) {
288 mTemp_Bufs.add(src_temp[i],i);
289 }
290 }
291 ALOGV("[%s %d] VIDIOC_QUERYBUF successful", __FUNCTION__, __LINE__);
292
293 for (int i = 0; i < mBufferCount; i++) {
294 mVideoInfo->buf.index = i;
295 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
296 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
297 ret = ioctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf);
298 if (ret < 0) {
299 ALOGE("VIDIOC_QBUF Failed");
300 return -1;
301 }
302 }
303 enum v4l2_buf_type bufType;
304 bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
305
306 ret = ioctl (mCameraHandle, VIDIOC_STREAMON, &bufType);
307
308 ALOGV("[%s %d] VIDIOC_STREAMON:%x", __FUNCTION__, __LINE__, ret);
309 return ret;
310}
311
312int vdin_screen_source::stop_v4l2_device()
313{
314 ALOGE("%s %d", __FUNCTION__, __LINE__);
315 int ret;
316 enum v4l2_buf_type bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
317
318 ret = ioctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType);
319 if (ret < 0) {
320 ALOGE("StopStreaming: Unable to stop capture: %s", strerror(errno));
321 }
322 for (int i = 0; i < mBufferCount; i++) {
323 if (munmap(mVideoInfo->mem[i], mVideoInfo->buf.length) < 0) {
324 ALOGE("Unmap failed");
325 }
326 }
327 mBufs.clear();
328 if (mFrameWidth %32 != 0) {
329 mTemp_Bufs.clear();
330 for (int j = 0; j <mBufferCount; j++ ) {
331 free(src_temp[j]);
332 src_temp[j] = NULL;
333 }
334 }
335 return ret;
336}
337int vdin_screen_source::start()
338{
339 ALOGV("%s %d", __FUNCTION__, __LINE__);
340 int ret;
341 if(mOpen == true){
342 ALOGI("already open");
343 return NO_ERROR;
344 }
345
346 ret = start_v4l2_device();
347 if(ret != NO_ERROR){
348 ALOGE("Start v4l2 device failed:%d",ret);
349 return ret;
350 }
351 if(mFrameType & NATIVE_WINDOW_DATA){
352 ret = init_native_window();
353 if(ret != NO_ERROR){
354 ALOGE("Init Native Window Failed:%d",ret);
355 return ret;
356 }
357 }
358 if(mFrameType & NATIVE_WINDOW_DATA || mFrameType & CALL_BACK_DATA){
359 ALOGD("Create Work Thread");
360 mWorkThread = new WorkThread(this);
361 }
362 if(mSetStateCB != NULL)
363 mSetStateCB(START);
364 mState = START;
365 mOpen = true;
366 ALOGV("%s %d ret:%d", __FUNCTION__, __LINE__, ret);
367 return NO_ERROR;
368}
369
370int vdin_screen_source::pause()
371{
372 ALOGV("%s %d", __FUNCTION__, __LINE__);
373 mState = PAUSE;
374 if(mSetStateCB != NULL)
375 mSetStateCB(PAUSE);
376 return NO_ERROR;
377}
378int vdin_screen_source::stop()
379{
380 ALOGE("!!!!!!!!!%s %d", __FUNCTION__, __LINE__);
381 int ret;
382 mState = STOPING;
383
384 if(mWorkThread != NULL){
385 mWorkThread->requestExitAndWait();
386 mWorkThread.clear();
387 }
388
389 enum v4l2_buf_type bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
390
391 ret = ioctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType);
392 if (ret < 0) {
393 ALOGE("StopStreaming: Unable to stop capture: %s", strerror(errno));
394 }
395 for (int i = 0; i < mBufferCount; i++){
396 if (munmap(mVideoInfo->mem[i], mVideoInfo->buf.length) < 0)
397 ALOGE("Unmap failed");
398 }
399
400 mBufferCount = 0;
401 mState = STOP;
402 if(mSetStateCB != NULL)
403 mSetStateCB(STOP);
404 mOpen = false;
405 return ret;
406}
407
408int vdin_screen_source::set_state_callback(olStateCB callback)
409{
410 if (!callback){
411 ALOGE("NULL state callback pointer");
412 return BAD_VALUE;
413 }
414 mSetStateCB = callback;
415 return NO_ERROR;
416}
417
418int vdin_screen_source::set_preview_window(ANativeWindow* window)
419{
420 ALOGV("%s %d", __FUNCTION__, __LINE__);
421 if(mOpen == true)
422 return NO_ERROR;
423 //can work without a valid window object ?
424 if (window == NULL){
425 ALOGD("NULL window object passed to ScreenSource");
426 if(mWorkThread != NULL){
427 mWorkThread->requestExitAndWait();
428 mWorkThread.clear();
429 }
430 mFrameType &= ~NATIVE_WINDOW_DATA;
431 return NO_ERROR;
432 }
433 mFrameType |= NATIVE_WINDOW_DATA;
434 mANativeWindow = window;
435 return NO_ERROR;
436}
437
438int vdin_screen_source::set_data_callback(app_data_callback callback, void* user)
439{
440 ALOGV("%s %d", __FUNCTION__, __LINE__);
441 if (callback == NULL){
442 ALOGE("NULL data callback pointer");
443 return BAD_VALUE;
444 }
445 mDataCB = callback;
446 mUser = user;
447 mFrameType |= CALL_BACK_DATA;
448 return NO_ERROR;
449}
450
451int vdin_screen_source::get_format()
452{
453 return mPixelFormat;
454}
455
456int vdin_screen_source::set_format(int width, int height, int color_format)
457{
458 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
459 if(mOpen == true)
460 return NO_ERROR;
461 int ret;
462 mVideoInfo->width = width;
463 mVideoInfo->height = height;
464 mVideoInfo->framesizeIn = (mVideoInfo->width * mVideoInfo->height << 3); //note color format
465 mVideoInfo->formatIn = color_format;
466
467 mVideoInfo->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
468 mVideoInfo->format.fmt.pix.width = width;
469 mVideoInfo->format.fmt.pix.height = height;
470 mVideoInfo->format.fmt.pix.pixelformat = color_format;
471 mPixelFormat = color_format;
472 mNativeWindowPixelFormat = getNativeWindowFormat(color_format);
473 mFrameWidth = width;
474 mFrameHeight = height;
475 mBufferSize = getBufSize(color_format, mFrameWidth, mFrameHeight);
476 if (mFrameWidth %32 != 0) {
477 for (int i = 0; i < mBufferCount; i++) {
478 src_temp[i] = (long*) malloc(mBufferSize);
479 if (!src_temp[i]) {
480 ALOGE("malloc src_temp buffer failed .\n");
481 return NO_MEMORY;
482 }
483 }
484 }
485 ALOGD("mFrameWidth:%d,mFrameHeight:%d",mFrameWidth,mFrameHeight);
486 ALOGD("mPixelFormat:%x,mNativeWindowPixelFormat:%x,mBufferSize:%d",mPixelFormat,mNativeWindowPixelFormat,mBufferSize);
487 ret = ioctl(mCameraHandle, VIDIOC_S_FMT, &mVideoInfo->format);
488 if (ret < 0) {
489 ALOGE("[%s %d]VIDIOC_S_FMT %d", __FUNCTION__, __LINE__, ret);
490 return ret;
491 }
492 return ret;
493}
494
495int vdin_screen_source::set_rotation(int degree)
496{
497 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
498
499 int ret = 0;
500 struct v4l2_control ctl;
501
502 if(mCameraHandle<0)
503 return -1;
504
505 if((degree!=0)&&(degree!=90)&&(degree!=180)&&(degree!=270)){
506 ALOGE("Set rotate value invalid: %d.", degree);
507 return -1;
508 }
509
510 memset( &ctl, 0, sizeof(ctl));
511 ctl.value=degree;
512 ctl.id = V4L2_ROTATE_ID;
513 ret = ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl);
514
515 if(ret<0){
516 ALOGE("Set rotate value fail: %s. ret=%d", strerror(errno),ret);
517 }
518 return ret ;
519}
520
521int vdin_screen_source::set_crop(int x, int y, int width, int height)
522{
523 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
524 if (NULL == mANativeWindow.get())
525 return BAD_VALUE;
526
527 int err = NO_ERROR;
528 android_native_rect_t crop = { x, y, x + width - 1, y + height - 1 };
529 err = native_window_set_crop(mANativeWindow.get(), &crop);
530 if (err != 0) {
531 ALOGW("Failed to set crop!");
532 return err;
533 }
534 return NO_ERROR;
535}
536
537int vdin_screen_source::set_frame_rate(int frameRate)
538{
539 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
540 int ret = 0;
541 struct v4l2_control ctl;
542
543 if(mCameraHandle<0)
544 return -1;
545
546 struct v4l2_streamparm sparm;
547 memset(&sparm, 0, sizeof( sparm ));
548 sparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;//stream_flag;
549 sparm.parm.output.timeperframe.denominator = frameRate;
550 sparm.parm.output.timeperframe.numerator = 1;
551
552 ret = ioctl(mCameraHandle, VIDIOC_S_PARM, &sparm);
553 if(ret < 0){
554 ALOGE("Set frame rate fail: %s. ret=%d", strerror(errno),ret);
555 }
556 return ret ;
557}
558
559int vdin_screen_source::get_amlvideo2_crop(int *x, int *y, int *width, int *height)
560{
561 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
562 int ret = 0;
563
564 struct v4l2_crop crop;
565 memset(&crop, 0, sizeof(struct v4l2_crop));
566 crop.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
567 ret = ioctl(mCameraHandle, VIDIOC_S_CROP, &crop);
568 if (ret) {
569 ALOGE("get amlvideo2 crop fail: %s. ret=%d", strerror(errno),ret);
570 }
571 *x = crop.c.left;
572 *y = crop.c.top;
573 *width = crop.c.width;
574 *height = crop.c.height;
575 return ret ;
576}
577
578int vdin_screen_source::set_amlvideo2_crop(int x, int y, int width, int height)
579{
580 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
581 int ret = 0;
582
583 struct v4l2_crop crop;
584 memset(&crop, 0, sizeof(struct v4l2_crop));
585
586 crop.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
587 crop.c.left = x;
588 crop.c.top = y;
589 crop.c.width = width;
590 crop.c.height = height;
591 ret = ioctl(mCameraHandle, VIDIOC_S_CROP, &crop);
592 if (ret) {
593 ALOGE("Set amlvideo2 crop fail: %s. ret=%d", strerror(errno),ret);
594 }
595
596 return ret ;
597}
598
599int vdin_screen_source::set_source_type(int sourceType)
600{
601 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
602 int ret = 0;
603
604 ret = ioctl(mCameraHandle, VIDIOC_S_INPUT, &sourceType);
605 if(ret < 0){
606 ALOGE("Set source type fail: %s. ret:%d", strerror(errno),ret);
607 }
608 return ret;
609}
610
611int vdin_screen_source::set_port_type(int sourceType)
612 {
613 ALOGD("[%s %d]", __FUNCTION__, __LINE__);
614 int ret = 0;
615 unsigned int portType = (unsigned int)sourceType;
616 ALOGE("portType:%d",portType);
617 ret = ioctl(mCameraHandle, VIDIOC_S_INPUT, &portType);
618 if (ret < 0) {
619 ALOGE("Set port type fail: %s. ret:%d", strerror(errno),ret);
620 }
621 return ret;
622 }
623int vdin_screen_source::get_source_type()
624{
625 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
626 int ret = -1;
627 int sourceType;
628
629 ret = ioctl(mCameraHandle, VIDIOC_G_INPUT, &sourceType);
630 if(ret < 0){
631 ALOGE("Set source type fail: %s. ret:%d", strerror(errno),ret);
632 return ret;
633 }
634 return sourceType;
635}
636
637int vdin_screen_source::get_current_sourcesize(int *width, int *height)
638{
639 int ret = NO_ERROR;
640 struct v4l2_format format;
641 memset(&format, 0,sizeof(struct v4l2_format));
642
643 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
644 ret = ioctl(mCameraHandle, VIDIOC_G_FMT, &format);
645 if (ret < 0) {
646 ALOGE("Open: VIDIOC_G_FMT Failed: %s", strerror(errno));
647 return ret;
648 }
649 *width = format.fmt.pix.width;
650 *height = format.fmt.pix.height;
651 ALOGD("VIDIOC_G_FMT, w * h: %5d x %5d", *width, *height);
652 return ret;
653}
654
655int vdin_screen_source::set_screen_mode(int mode)
656{
657 int ret = NO_ERROR;
658
659 ret = ioctl(mCameraHandle, VIDIOC_S_OUTPUT, &mode);
660 if (ret < 0) {
661 ALOGE("VIDIOC_S_OUTPUT Failed: %s", strerror(errno));
662 return ret;
663 }
664 return ret;
665}
666
667int vdin_screen_source::aquire_buffer(aml_screen_buffer_info_t *buff_info)
668{
669 ALOGE("%s %d", __FUNCTION__, __LINE__);
670 int ret = -1;
671 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
672 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
673
674 ret = ioctl(mCameraHandle, VIDIOC_DQBUF, &mVideoInfo->buf);
675 if (ret < 0) {
676 if(EAGAIN == errno){
677 ret = -EAGAIN;
678 }else{
679 ALOGE("[%s %d]aquire_buffer %d", __FUNCTION__, __LINE__, ret);
680 }
681 buff_info->buffer_mem = 0;
682 buff_info->buffer_canvas = 0;
683 ALOGE("aquire_buffer %d %d", ret ,__LINE__);
684 return ret;
685 }
686
687 if (!(mFrameType & NATIVE_WINDOW_DATA || mFrameType & CALL_BACK_DATA))
688 mVideoInfo->refcount[mVideoInfo->buf.index] += 1;
689
690 if (mFrameWidth %32 != 0) {
691 switch (mVideoInfo->format.fmt.pix.pixelformat) {
692 case V4L2_PIX_FMT_YVU420:
693 yv12_memcpy_align32((unsigned char*)src_temp[mVideoInfo->buf.index], (unsigned char*)mVideoInfo->mem[mVideoInfo->buf.index], mFrameWidth, mFrameHeight);
694 break;
695 case V4L2_PIX_FMT_NV21:
696 nv21_memcpy_align32((unsigned char*)src_temp[mVideoInfo->buf.index], (unsigned char*)mVideoInfo->mem[mVideoInfo->buf.index], mFrameWidth, mFrameHeight);
697 break;
698 case V4L2_PIX_FMT_YUYV:
699 case V4L2_PIX_FMT_RGB565:
700 case V4L2_PIX_FMT_RGB565X:
701 two_bytes_per_pixel_memcpy_align32 ((unsigned char*)src_temp[mVideoInfo->buf.index], (unsigned char*)mVideoInfo->mem[mVideoInfo->buf.index], mFrameWidth, mFrameHeight);
702 break;
703 case V4L2_PIX_FMT_RGB24:
704 rgb24_memcpy_align32((unsigned char*)src_temp[mVideoInfo->buf.index], (unsigned char*)mVideoInfo->mem[mVideoInfo->buf.index], mFrameWidth, mFrameHeight);
705 break;
706 case V4L2_PIX_FMT_RGB32:
707 rgb32_memcpy_align32((unsigned char*)src_temp[mVideoInfo->buf.index], (unsigned char*)mVideoInfo->mem[mVideoInfo->buf.index], mFrameWidth, mFrameHeight);
708 break;
709 default:
710 ALOGE("Invalid format , %s %d " , __FUNCTION__, __LINE__);
711 }
712 buff_info->buffer_mem = src_temp[mVideoInfo->buf.index];
713 buff_info->buffer_canvas = mVideoInfo->canvas[mVideoInfo->buf.index];
714 buff_info->tv_sec = mVideoInfo->buf.timestamp.tv_sec;
715 buff_info->tv_usec = mVideoInfo->buf.timestamp.tv_usec;
716 } else {
717 buff_info->buffer_mem = mVideoInfo->mem[mVideoInfo->buf.index];
718 buff_info->buffer_canvas = mVideoInfo->canvas[mVideoInfo->buf.index];
719 buff_info->tv_sec = mVideoInfo->buf.timestamp.tv_sec;
720 buff_info->tv_usec = mVideoInfo->buf.timestamp.tv_usec;
721 }
722
723 ALOGE("%s finish %d ", __FUNCTION__, __LINE__);
724 return ret;
725}
726
727/* int vdin_screen_source::inc_buffer_refcount(int *ptr){
728 ALOGV("%s %d", __FUNCTION__, __LINE__);
729 int ret = -1;
730 int index;
731 index = mBufs.valueFor((unsigned int)ptr);
732 mVideoInfo->refcount[index] += 1;
733 return true;
734} */
735
736int vdin_screen_source::release_buffer(long* ptr)
737{
738 ALOGV("%s %d", __FUNCTION__, __LINE__);
739 int ret = -1;
740 int currentIndex;
741 v4l2_buffer hbuf_query;
742
743 Mutex::Autolock autoLock(mLock);
744 if (mFrameWidth % 32 != 0) {
745 currentIndex = mTemp_Bufs.valueFor(ptr);
746 } else {
747 currentIndex = mBufs.valueFor(ptr);
748 }
749 if (mVideoInfo->refcount[currentIndex] > 0) {
750 mVideoInfo->refcount[currentIndex] -= 1;
751 } else {
752 ALOGE("return buffer when refcount already zero");
753 return 0;
754 }
755 if (mVideoInfo->refcount[currentIndex] == 0) {
756 memset(&hbuf_query,0,sizeof(v4l2_buffer));
757 hbuf_query.index = currentIndex;
758 hbuf_query.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
759 hbuf_query.memory = V4L2_MEMORY_MMAP;
760 ALOGV("return buffer :%d",currentIndex);
761 ret = ioctl(mCameraHandle, VIDIOC_QBUF, &hbuf_query);
762 if (ret != 0) {
763 ALOGE("Return Buffer :%d failed", currentIndex);
764 }
765 }
766 return 0;
767}
768
769int vdin_screen_source::init_native_window()
770{
771 ALOGV("%s %d", __FUNCTION__, __LINE__);
772 int err = NO_ERROR;
773
774 if(NULL == mANativeWindow.get())
775 return BAD_VALUE;
776
777 // Set gralloc usage bits for window.
778 err = native_window_set_usage(mANativeWindow.get(), SCREENSOURCE_GRALLOC_USAGE);
779 if (err != 0) {
780 ALOGE("native_window_set_usage failed: %s\n", strerror(-err));
781 if(ENODEV == err ){
782 ALOGE("Preview surface abandoned!");
783 mANativeWindow = NULL;
784 }
785 return err;
786 }
787
788 ALOGD("Number of buffers set to ANativeWindow %d", mBufferCount);
789 ///Set the number of buffers needed for camera preview
790 err = native_window_set_buffer_count(mANativeWindow.get(), mBufferCount);
791 if (err != 0) {
792 ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), -err);
793 if(ENODEV == err){
794 ALOGE("Preview surface abandoned!");
795 mANativeWindow = NULL;
796 }
797 return err;
798 }
799
800 ALOGD("native_window_set_buffers_geometry format:0x%x",mNativeWindowPixelFormat);
801 // Set window geometry
802 err = native_window_set_buffers_geometry(
803 mANativeWindow.get(),
804 mFrameWidth,
805 mFrameHeight,
806 mNativeWindowPixelFormat);
807
808 if (err != 0) {
809 ALOGE("native_window_set_buffers_geometry failed: %s", strerror(-err));
810 if ( ENODEV == err ) {
811 ALOGE("Surface abandoned!");
812 mANativeWindow = NULL;
813 }
814 return err;
815 }
816 err = native_window_set_scaling_mode(mANativeWindow.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
817 if (err != 0) {
818 ALOGW("Failed to set scaling mode: %d", err);
819 return err;
820 }
821 return NO_ERROR;
822}
823
824int vdin_screen_source::workThread()
825{
826 bool buff_keep = false;
827 int index;
828 aml_screen_buffer_info_t buff_info;
829 int ret;
830 long *src = NULL;
831 unsigned char *dest = NULL;
832 uint8_t *handle = NULL;
833 ANativeWindowBuffer* buf;
834 if(mState == START){
835 usleep(5000);
836 ret = aquire_buffer(&buff_info);
837 if (ret != 0 || (buff_info.buffer_mem == 0)) {
838 ALOGV("Get V4l2 buffer failed");
839 return ret;
840 }
841 src = buff_info.buffer_mem;
842 index = mBufs.valueFor(src);
843 if(mFrameType & NATIVE_WINDOW_DATA){
844 mVideoInfo->refcount[index] += 1;
845 if(mANativeWindow.get() == NULL){
846 ALOGE("Null window");
847 return BAD_VALUE;
848 }
849 ret = mANativeWindow->dequeueBuffer_DEPRECATED(mANativeWindow.get(), &buf);
850 if(ret != 0){
851 ALOGE("dequeue buffer failed :%s (%d)",strerror(-ret), -ret);
852 return BAD_VALUE;
853 }
854 mANativeWindow->lockBuffer_DEPRECATED(mANativeWindow.get(), buf);
855 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
856 graphicBuffer->lock(SCREENSOURCE_GRALLOC_USAGE, (void **)&dest);
857 if(dest == NULL){
858 ALOGE("Invalid Gralloc Handle");
859 return BAD_VALUE;
860 }
861 memcpy(dest, src, mBufferSize);
862 graphicBuffer->unlock();
863 mANativeWindow->queueBuffer_DEPRECATED(mANativeWindow.get(), buf);
864 graphicBuffer.clear();
865 ALOGV("queue one buffer to native window");
866 release_buffer(src);
867 }
868 if(mFrameType & CALL_BACK_DATA && mDataCB != NULL&& mState == START){
869 mVideoInfo->refcount[index] += 1;
870 mDataCB(mUser, &buff_info);
871 }
872 }
873 return NO_ERROR;
874}
875
876}
877