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