summaryrefslogtreecommitdiff
path: root/v4l2_vdin.cpp (plain)
blob: fd4fc10613a78eb676cac743a77e0ff68055264b
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(){
196 ALOGV("%s %d", __FUNCTION__, __LINE__);
197 mCameraHandle = open("/dev/video11", O_RDWR| O_NONBLOCK);
198 if (mCameraHandle < 0)
199 {
200 ALOGE("[%s %d] mCameraHandle:%x [%s]", __FUNCTION__, __LINE__, mCameraHandle,strerror(errno));
201 return -1;
202 }
203 mVideoInfo = (struct VideoInfo *) calloc (1, sizeof (struct VideoInfo));
204 if (mVideoInfo == NULL)
205 {
206 ALOGE("[%s %d] no memory for mVideoInfo", __FUNCTION__, __LINE__);
207 close(mCameraHandle);
208 return NO_MEMORY;
209 }
210 mBufferCount = 4;
211 for (int i = 0; i < mBufferCount; i++) {
212 src_temp[i] = NULL;
213 }
214 mPixelFormat = V4L2_PIX_FMT_NV21;
215 mNativeWindowPixelFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
216 mFrameWidth = 1280;
217 mFrameHeight = 720;
218 mBufferSize = mFrameWidth * mFrameHeight * 3/2;
219 mSetStateCB = NULL;
220 mState = STOP;
221 mANativeWindow = NULL;
222 mFrameType = 0;
223 mWorkThread = NULL;
224 mDataCB = NULL;
225 mOpen = false;
226 return NO_ERROR;
227}
228
229vdin_screen_source::~vdin_screen_source()
230{
231 if (mVideoInfo)
232 free (mVideoInfo);
233 if (mCameraHandle >= 0)
234 close(mCameraHandle);
235}
236
237int vdin_screen_source::start_v4l2_device()
238{
239 int ret = -1;
240
241 ALOGV("[%s %d] mCameraHandle:%x", __FUNCTION__, __LINE__, mCameraHandle);
242
243 ioctl(mCameraHandle, VIDIOC_QUERYCAP, &mVideoInfo->cap);
244
245 mVideoInfo->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
246 mVideoInfo->rb.memory = V4L2_MEMORY_MMAP;
247 mVideoInfo->rb.count = mBufferCount;
248
249 ret = ioctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
250
251 if (ret < 0) {
252 ALOGE("[%s %d] VIDIOC_REQBUFS:%d mCameraHandle:%x", __FUNCTION__, __LINE__, ret, mCameraHandle);
253 return ret;
254 }
255
256 for (int i = 0; i < mBufferCount; i++) {
257 memset (&mVideoInfo->buf, 0, sizeof (struct v4l2_buffer));
258
259 mVideoInfo->buf.index = i;
260 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
261 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
262
263 ret = ioctl (mCameraHandle, VIDIOC_QUERYBUF, &mVideoInfo->buf);
264 if (ret < 0) {
265 ALOGE("[%s %d]VIDIOC_QUERYBUF %d failed", __FUNCTION__, __LINE__, i);
266 return ret;
267 }
268 mVideoInfo->canvas[i] = mVideoInfo->buf.reserved;
269 mVideoInfo->mem[i] = (long *)mmap (0, mVideoInfo->buf.length, PROT_READ | PROT_WRITE,
270 MAP_SHARED, mCameraHandle, mVideoInfo->buf.m.offset);
271
272 if (mVideoInfo->mem[i] == MAP_FAILED) {
273 ALOGE("[%s %d] MAP_FAILED", __FUNCTION__, __LINE__);
274 return -1;
275 }
276 mVideoInfo->refcount[i] = 0;
277 mBufs.add(mVideoInfo->mem[i],i);
278 if (mFrameWidth %32 != 0) {
279 mTemp_Bufs.add(src_temp[i],i);
280 }
281 }
282 ALOGV("[%s %d] VIDIOC_QUERYBUF successful", __FUNCTION__, __LINE__);
283
284 for (int i = 0; i < mBufferCount; i++) {
285 mVideoInfo->buf.index = i;
286 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
287 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
288 ret = ioctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf);
289 if (ret < 0) {
290 ALOGE("VIDIOC_QBUF Failed");
291 return -1;
292 }
293 }
294 enum v4l2_buf_type bufType;
295 bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
296
297 ret = ioctl (mCameraHandle, VIDIOC_STREAMON, &bufType);
298
299 ALOGV("[%s %d] VIDIOC_STREAMON:%x", __FUNCTION__, __LINE__, ret);
300 return ret;
301}
302
303int vdin_screen_source::stop_v4l2_device()
304{
305 ALOGE("%s %d", __FUNCTION__, __LINE__);
306 int ret;
307 enum v4l2_buf_type bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
308
309 ret = ioctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType);
310 if (ret < 0) {
311 ALOGE("StopStreaming: Unable to stop capture: %s", strerror(errno));
312 }
313 for (int i = 0; i < mBufferCount; i++) {
314 if (munmap(mVideoInfo->mem[i], mVideoInfo->buf.length) < 0) {
315 ALOGE("Unmap failed");
316 }
317 }
318 mBufs.clear();
319 if (mFrameWidth %32 != 0) {
320 mTemp_Bufs.clear();
321 for (int j = 0; j <mBufferCount; j++ ) {
322 free(src_temp[j]);
323 src_temp[j] = NULL;
324 }
325 }
326 return ret;
327}
328int vdin_screen_source::start()
329{
330 ALOGV("%s %d", __FUNCTION__, __LINE__);
331 int ret;
332 if(mOpen == true){
333 ALOGI("already open");
334 return NO_ERROR;
335 }
336
337 ret = start_v4l2_device();
338 if(ret != NO_ERROR){
339 ALOGE("Start v4l2 device failed:%d",ret);
340 return ret;
341 }
342 if(mFrameType & NATIVE_WINDOW_DATA){
343 ret = init_native_window();
344 if(ret != NO_ERROR){
345 ALOGE("Init Native Window Failed:%d",ret);
346 return ret;
347 }
348 }
349 if(mFrameType & NATIVE_WINDOW_DATA || mFrameType & CALL_BACK_DATA){
350 ALOGD("Create Work Thread");
351 mWorkThread = new WorkThread(this);
352 }
353 if(mSetStateCB != NULL)
354 mSetStateCB(START);
355 mState = START;
356 mOpen = true;
357 ALOGV("%s %d ret:%d", __FUNCTION__, __LINE__, ret);
358 return NO_ERROR;
359}
360
361int vdin_screen_source::pause()
362{
363 ALOGV("%s %d", __FUNCTION__, __LINE__);
364 mState = PAUSE;
365 if(mSetStateCB != NULL)
366 mSetStateCB(PAUSE);
367 return NO_ERROR;
368}
369int vdin_screen_source::stop()
370{
371 ALOGE("!!!!!!!!!%s %d", __FUNCTION__, __LINE__);
372 int ret;
373 mState = STOPING;
374
375 if(mWorkThread != NULL){
376 mWorkThread->requestExitAndWait();
377 mWorkThread.clear();
378 }
379
380 enum v4l2_buf_type bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
381
382 ret = ioctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType);
383 if (ret < 0) {
384 ALOGE("StopStreaming: Unable to stop capture: %s", strerror(errno));
385 }
386 for (int i = 0; i < mBufferCount; i++){
387 if (munmap(mVideoInfo->mem[i], mVideoInfo->buf.length) < 0)
388 ALOGE("Unmap failed");
389 }
390
391 mBufferCount = 0;
392 mState = STOP;
393 if(mSetStateCB != NULL)
394 mSetStateCB(STOP);
395 mOpen = false;
396 return ret;
397}
398
399int vdin_screen_source::set_state_callback(olStateCB callback)
400{
401 if (!callback){
402 ALOGE("NULL state callback pointer");
403 return BAD_VALUE;
404 }
405 mSetStateCB = callback;
406 return NO_ERROR;
407}
408
409int vdin_screen_source::set_preview_window(ANativeWindow* window)
410{
411 ALOGV("%s %d", __FUNCTION__, __LINE__);
412 if(mOpen == true)
413 return NO_ERROR;
414 //can work without a valid window object ?
415 if (window == NULL){
416 ALOGD("NULL window object passed to ScreenSource");
417 if(mWorkThread != NULL){
418 mWorkThread->requestExitAndWait();
419 mWorkThread.clear();
420 }
421 mFrameType &= ~NATIVE_WINDOW_DATA;
422 return NO_ERROR;
423 }
424 mFrameType |= NATIVE_WINDOW_DATA;
425 mANativeWindow = window;
426 return NO_ERROR;
427}
428
429int vdin_screen_source::set_data_callback(app_data_callback callback, void* user)
430{
431 ALOGV("%s %d", __FUNCTION__, __LINE__);
432 if (callback == NULL){
433 ALOGE("NULL data callback pointer");
434 return BAD_VALUE;
435 }
436 mDataCB = callback;
437 mUser = user;
438 mFrameType |= CALL_BACK_DATA;
439 return NO_ERROR;
440}
441
442int vdin_screen_source::get_format()
443{
444 return mPixelFormat;
445}
446
447int vdin_screen_source::set_format(int width, int height, int color_format)
448{
449 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
450 if(mOpen == true)
451 return NO_ERROR;
452 int ret;
453 mVideoInfo->width = width;
454 mVideoInfo->height = height;
455 mVideoInfo->framesizeIn = (mVideoInfo->width * mVideoInfo->height << 3); //note color format
456 mVideoInfo->formatIn = color_format;
457
458 mVideoInfo->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
459 mVideoInfo->format.fmt.pix.width = width;
460 mVideoInfo->format.fmt.pix.height = height;
461 mVideoInfo->format.fmt.pix.pixelformat = color_format;
462 mPixelFormat = color_format;
463 mNativeWindowPixelFormat = getNativeWindowFormat(color_format);
464 mFrameWidth = width;
465 mFrameHeight = height;
466 mBufferSize = getBufSize(color_format, mFrameWidth, mFrameHeight);
467 if (mFrameWidth %32 != 0) {
468 for (int i = 0; i < mBufferCount; i++) {
469 src_temp[i] = (long*) malloc(mBufferSize);
470 if (!src_temp[i]) {
471 ALOGE("malloc src_temp buffer failed .\n");
472 return NO_MEMORY;
473 }
474 }
475 }
476 ALOGD("mFrameWidth:%d,mFrameHeight:%d",mFrameWidth,mFrameHeight);
477 ALOGD("mPixelFormat:%x,mNativeWindowPixelFormat:%x,mBufferSize:%d",mPixelFormat,mNativeWindowPixelFormat,mBufferSize);
478 ret = ioctl(mCameraHandle, VIDIOC_S_FMT, &mVideoInfo->format);
479 if (ret < 0) {
480 ALOGE("[%s %d]VIDIOC_S_FMT %d", __FUNCTION__, __LINE__, ret);
481 return ret;
482 }
483 return ret;
484}
485
486int vdin_screen_source::set_rotation(int degree)
487{
488 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
489
490 int ret = 0;
491 struct v4l2_control ctl;
492
493 if(mCameraHandle<0)
494 return -1;
495
496 if((degree!=0)&&(degree!=90)&&(degree!=180)&&(degree!=270)){
497 ALOGE("Set rotate value invalid: %d.", degree);
498 return -1;
499 }
500
501 memset( &ctl, 0, sizeof(ctl));
502 ctl.value=degree;
503 ctl.id = V4L2_ROTATE_ID;
504 ret = ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl);
505
506 if(ret<0){
507 ALOGE("Set rotate value fail: %s. ret=%d", strerror(errno),ret);
508 }
509 return ret ;
510}
511
512int vdin_screen_source::set_crop(int x, int y, int width, int height)
513{
514 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
515 if (NULL == mANativeWindow.get())
516 return BAD_VALUE;
517
518 int err = NO_ERROR;
519 android_native_rect_t crop = { x, y, x + width - 1, y + height - 1 };
520 err = native_window_set_crop(mANativeWindow.get(), &crop);
521 if (err != 0) {
522 ALOGW("Failed to set crop!");
523 return err;
524 }
525 return NO_ERROR;
526}
527
528int vdin_screen_source::set_frame_rate(int frameRate)
529{
530 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
531 int ret = 0;
532 struct v4l2_control ctl;
533
534 if(mCameraHandle<0)
535 return -1;
536
537 struct v4l2_streamparm sparm;
538 memset(&sparm, 0, sizeof( sparm ));
539 sparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;//stream_flag;
540 sparm.parm.output.timeperframe.denominator = frameRate;
541 sparm.parm.output.timeperframe.numerator = 1;
542
543 ret = ioctl(mCameraHandle, VIDIOC_S_PARM, &sparm);
544 if(ret < 0){
545 ALOGE("Set frame rate fail: %s. ret=%d", strerror(errno),ret);
546 }
547 return ret ;
548}
549
550int vdin_screen_source::get_amlvideo2_crop(int *x, int *y, int *width, int *height)
551{
552 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
553 int ret = 0;
554
555 struct v4l2_crop crop;
556 memset(&crop, 0, sizeof(struct v4l2_crop));
557 crop.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
558 ret = ioctl(mCameraHandle, VIDIOC_S_CROP, &crop);
559 if (ret) {
560 ALOGE("get amlvideo2 crop fail: %s. ret=%d", strerror(errno),ret);
561 }
562 *x = crop.c.left;
563 *y = crop.c.top;
564 *width = crop.c.width;
565 *height = crop.c.height;
566 return ret ;
567}
568
569int vdin_screen_source::set_amlvideo2_crop(int x, int y, int width, int height)
570{
571 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
572 int ret = 0;
573
574 struct v4l2_crop crop;
575 memset(&crop, 0, sizeof(struct v4l2_crop));
576
577 crop.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
578 crop.c.left = x;
579 crop.c.top = y;
580 crop.c.width = width;
581 crop.c.height = height;
582 ret = ioctl(mCameraHandle, VIDIOC_S_CROP, &crop);
583 if (ret) {
584 ALOGE("Set amlvideo2 crop fail: %s. ret=%d", strerror(errno),ret);
585 }
586
587 return ret ;
588}
589
590int vdin_screen_source::set_source_type(int sourceType)
591{
592 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
593 int ret = 0;
594
595 ret = ioctl(mCameraHandle, VIDIOC_S_INPUT, &sourceType);
596 if(ret < 0){
597 ALOGE("Set source type fail: %s. ret:%d", strerror(errno),ret);
598 }
599 return ret;
600}
601
602int vdin_screen_source::set_port_type(int sourceType)
603 {
604 ALOGD("[%s %d]", __FUNCTION__, __LINE__);
605 int ret = 0;
606 unsigned int portType = (unsigned int)sourceType;
607 ALOGE("portType:%d",portType);
608 ret = ioctl(mCameraHandle, VIDIOC_S_INPUT, &portType);
609 if (ret < 0) {
610 ALOGE("Set port type fail: %s. ret:%d", strerror(errno),ret);
611 }
612 return ret;
613 }
614int vdin_screen_source::get_source_type()
615{
616 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
617 int ret = -1;
618 int sourceType;
619
620 ret = ioctl(mCameraHandle, VIDIOC_G_INPUT, &sourceType);
621 if(ret < 0){
622 ALOGE("Set source type fail: %s. ret:%d", strerror(errno),ret);
623 return ret;
624 }
625 return sourceType;
626}
627
628int vdin_screen_source::get_current_sourcesize(int *width, int *height)
629{
630 int ret = NO_ERROR;
631 struct v4l2_format format;
632 memset(&format, 0,sizeof(struct v4l2_format));
633
634 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
635 ret = ioctl(mCameraHandle, VIDIOC_G_FMT, &format);
636 if (ret < 0) {
637 ALOGE("Open: VIDIOC_G_FMT Failed: %s", strerror(errno));
638 return ret;
639 }
640 *width = format.fmt.pix.width;
641 *height = format.fmt.pix.height;
642 ALOGD("VIDIOC_G_FMT, w * h: %5d x %5d", *width, *height);
643 return ret;
644}
645
646int vdin_screen_source::set_screen_mode(int mode)
647{
648 int ret = NO_ERROR;
649
650 ret = ioctl(mCameraHandle, VIDIOC_S_OUTPUT, &mode);
651 if (ret < 0) {
652 ALOGE("VIDIOC_S_OUTPUT Failed: %s", strerror(errno));
653 return ret;
654 }
655 return ret;
656}
657
658int vdin_screen_source::aquire_buffer(aml_screen_buffer_info_t *buff_info)
659{
660 ALOGE("%s %d", __FUNCTION__, __LINE__);
661 int ret = -1;
662 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
663 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
664
665 ret = ioctl(mCameraHandle, VIDIOC_DQBUF, &mVideoInfo->buf);
666 if (ret < 0) {
667 if(EAGAIN == errno){
668 ret = -EAGAIN;
669 }else{
670 ALOGE("[%s %d]aquire_buffer %d", __FUNCTION__, __LINE__, ret);
671 }
672 buff_info->buffer_mem = 0;
673 buff_info->buffer_canvas = 0;
674 ALOGE("aquire_buffer %d %d", ret ,__LINE__);
675 return ret;
676 }
677
678 if (!(mFrameType & NATIVE_WINDOW_DATA || mFrameType & CALL_BACK_DATA))
679 mVideoInfo->refcount[mVideoInfo->buf.index] += 1;
680
681 if (mFrameWidth %32 != 0) {
682 switch (mVideoInfo->format.fmt.pix.pixelformat) {
683 case V4L2_PIX_FMT_YVU420:
684 yv12_memcpy_align32((unsigned char*)src_temp[mVideoInfo->buf.index], (unsigned char*)mVideoInfo->mem[mVideoInfo->buf.index], mFrameWidth, mFrameHeight);
685 break;
686 case V4L2_PIX_FMT_NV21:
687 nv21_memcpy_align32((unsigned char*)src_temp[mVideoInfo->buf.index], (unsigned char*)mVideoInfo->mem[mVideoInfo->buf.index], mFrameWidth, mFrameHeight);
688 break;
689 case V4L2_PIX_FMT_YUYV:
690 case V4L2_PIX_FMT_RGB565:
691 case V4L2_PIX_FMT_RGB565X:
692 two_bytes_per_pixel_memcpy_align32 ((unsigned char*)src_temp[mVideoInfo->buf.index], (unsigned char*)mVideoInfo->mem[mVideoInfo->buf.index], mFrameWidth, mFrameHeight);
693 break;
694 case V4L2_PIX_FMT_RGB24:
695 rgb24_memcpy_align32((unsigned char*)src_temp[mVideoInfo->buf.index], (unsigned char*)mVideoInfo->mem[mVideoInfo->buf.index], mFrameWidth, mFrameHeight);
696 break;
697 case V4L2_PIX_FMT_RGB32:
698 rgb32_memcpy_align32((unsigned char*)src_temp[mVideoInfo->buf.index], (unsigned char*)mVideoInfo->mem[mVideoInfo->buf.index], mFrameWidth, mFrameHeight);
699 break;
700 default:
701 ALOGE("Invalid format , %s %d " , __FUNCTION__, __LINE__);
702 }
703 buff_info->buffer_mem = src_temp[mVideoInfo->buf.index];
704 buff_info->buffer_canvas = mVideoInfo->canvas[mVideoInfo->buf.index];
705 buff_info->tv_sec = mVideoInfo->buf.timestamp.tv_sec;
706 buff_info->tv_usec = mVideoInfo->buf.timestamp.tv_usec;
707 } else {
708 buff_info->buffer_mem = mVideoInfo->mem[mVideoInfo->buf.index];
709 buff_info->buffer_canvas = mVideoInfo->canvas[mVideoInfo->buf.index];
710 buff_info->tv_sec = mVideoInfo->buf.timestamp.tv_sec;
711 buff_info->tv_usec = mVideoInfo->buf.timestamp.tv_usec;
712 }
713
714 ALOGE("%s finish %d ", __FUNCTION__, __LINE__);
715 return ret;
716}
717
718/* int vdin_screen_source::inc_buffer_refcount(int *ptr){
719 ALOGV("%s %d", __FUNCTION__, __LINE__);
720 int ret = -1;
721 int index;
722 index = mBufs.valueFor((unsigned int)ptr);
723 mVideoInfo->refcount[index] += 1;
724 return true;
725} */
726
727int vdin_screen_source::release_buffer(long* ptr)
728{
729 ALOGV("%s %d", __FUNCTION__, __LINE__);
730 int ret = -1;
731 int currentIndex;
732 v4l2_buffer hbuf_query;
733
734 Mutex::Autolock autoLock(mLock);
735 if (mFrameWidth % 32 != 0) {
736 currentIndex = mTemp_Bufs.valueFor(ptr);
737 } else {
738 currentIndex = mBufs.valueFor(ptr);
739 }
740 if (mVideoInfo->refcount[currentIndex] > 0) {
741 mVideoInfo->refcount[currentIndex] -= 1;
742 } else {
743 ALOGE("return buffer when refcount already zero");
744 return 0;
745 }
746 if (mVideoInfo->refcount[currentIndex] == 0) {
747 memset(&hbuf_query,0,sizeof(v4l2_buffer));
748 hbuf_query.index = currentIndex;
749 hbuf_query.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
750 hbuf_query.memory = V4L2_MEMORY_MMAP;
751 ALOGV("return buffer :%d",currentIndex);
752 ret = ioctl(mCameraHandle, VIDIOC_QBUF, &hbuf_query);
753 if (ret != 0) {
754 ALOGE("Return Buffer :%d failed", currentIndex);
755 }
756 }
757 return 0;
758}
759
760int vdin_screen_source::init_native_window()
761{
762 ALOGV("%s %d", __FUNCTION__, __LINE__);
763 int err = NO_ERROR;
764
765 if(NULL == mANativeWindow.get())
766 return BAD_VALUE;
767
768 // Set gralloc usage bits for window.
769 err = native_window_set_usage(mANativeWindow.get(), SCREENSOURCE_GRALLOC_USAGE);
770 if (err != 0) {
771 ALOGE("native_window_set_usage failed: %s\n", strerror(-err));
772 if(ENODEV == err ){
773 ALOGE("Preview surface abandoned!");
774 mANativeWindow = NULL;
775 }
776 return err;
777 }
778
779 ALOGD("Number of buffers set to ANativeWindow %d", mBufferCount);
780 ///Set the number of buffers needed for camera preview
781 err = native_window_set_buffer_count(mANativeWindow.get(), mBufferCount);
782 if (err != 0) {
783 ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), -err);
784 if(ENODEV == err){
785 ALOGE("Preview surface abandoned!");
786 mANativeWindow = NULL;
787 }
788 return err;
789 }
790
791 ALOGD("native_window_set_buffers_geometry format:0x%x",mNativeWindowPixelFormat);
792 // Set window geometry
793 err = native_window_set_buffers_geometry(
794 mANativeWindow.get(),
795 mFrameWidth,
796 mFrameHeight,
797 mNativeWindowPixelFormat);
798
799 if (err != 0) {
800 ALOGE("native_window_set_buffers_geometry failed: %s", strerror(-err));
801 if ( ENODEV == err ) {
802 ALOGE("Surface abandoned!");
803 mANativeWindow = NULL;
804 }
805 return err;
806 }
807 err = native_window_set_scaling_mode(mANativeWindow.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
808 if (err != 0) {
809 ALOGW("Failed to set scaling mode: %d", err);
810 return err;
811 }
812 return NO_ERROR;
813}
814
815int vdin_screen_source::workThread()
816{
817 bool buff_keep = false;
818 int index;
819 aml_screen_buffer_info_t buff_info;
820 int ret;
821 long *src = NULL;
822 unsigned char *dest = NULL;
823 uint8_t *handle = NULL;
824 ANativeWindowBuffer* buf;
825 if(mState == START){
826 usleep(5000);
827 ret = aquire_buffer(&buff_info);
828 if (ret != 0 || (buff_info.buffer_mem == 0)) {
829 ALOGV("Get V4l2 buffer failed");
830 return ret;
831 }
832 src = buff_info.buffer_mem;
833 index = mBufs.valueFor(src);
834 if(mFrameType & NATIVE_WINDOW_DATA){
835 mVideoInfo->refcount[index] += 1;
836 if(mANativeWindow.get() == NULL){
837 ALOGE("Null window");
838 return BAD_VALUE;
839 }
840 ret = mANativeWindow->dequeueBuffer_DEPRECATED(mANativeWindow.get(), &buf);
841 if(ret != 0){
842 ALOGE("dequeue buffer failed :%s (%d)",strerror(-ret), -ret);
843 return BAD_VALUE;
844 }
845 mANativeWindow->lockBuffer_DEPRECATED(mANativeWindow.get(), buf);
846 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
847 graphicBuffer->lock(SCREENSOURCE_GRALLOC_USAGE, (void **)&dest);
848 if(dest == NULL){
849 ALOGE("Invalid Gralloc Handle");
850 return BAD_VALUE;
851 }
852 memcpy(dest, src, mBufferSize);
853 graphicBuffer->unlock();
854 mANativeWindow->queueBuffer_DEPRECATED(mANativeWindow.get(), buf);
855 graphicBuffer.clear();
856 ALOGV("queue one buffer to native window");
857 release_buffer(src);
858 }
859 if(mFrameType & CALL_BACK_DATA && mDataCB != NULL&& mState == START){
860 mVideoInfo->refcount[index] += 1;
861 mDataCB(mUser, &buff_info);
862 }
863 }
864 return NO_ERROR;
865}
866
867}
868