summaryrefslogtreecommitdiff
path: root/v4l2_vdin.cpp (plain)
blob: 772154cc4d807bb03a811dae2cab86179cbde4df
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 BOUNDRY 32
57
58#define ALIGN(x) (x + (BOUNDRY) - 1)& ~((BOUNDRY) - 1)
59
60static size_t getBufSize(int format, int width, int height)
61{
62 size_t buf_size = 0;
63
64 switch(format){
65 case V4L2_PIX_FMT_YVU420:
66 case V4L2_PIX_FMT_NV21:
67 buf_size = width * height * 3 / 2;
68 break;
69 case V4L2_PIX_FMT_YUYV:
70 case V4L2_PIX_FMT_RGB565:
71 buf_size = width * height * 2;
72 break;
73 case V4L2_PIX_FMT_RGB24:
74 buf_size = width * height * 3;
75 break;
76 case V4L2_PIX_FMT_RGB32:
77 buf_size = width * height * 4;
78 break;
79 default:
80 ALOGE("Invalid format");
81 buf_size = 0;
82 }
83 return buf_size;
84}
85
86static int getNativeWindowFormat(int format)
87{
88 int nativeFormat = HAL_PIXEL_FORMAT_YCbCr_422_I;
89
90 switch(format){
91 case V4L2_PIX_FMT_YVU420:
92 nativeFormat = HAL_PIXEL_FORMAT_YV12;
93 break;
94 case V4L2_PIX_FMT_NV21:
95 nativeFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
96 break;
97 case V4L2_PIX_FMT_YUYV:
98 nativeFormat = HAL_PIXEL_FORMAT_YCbCr_422_I;
99 break;
100 case V4L2_PIX_FMT_RGB565:
101 nativeFormat = HAL_PIXEL_FORMAT_RGB_565;
102 break;
103 case V4L2_PIX_FMT_RGB24:
104 nativeFormat = HAL_PIXEL_FORMAT_RGB_888;
105 break;
106 case V4L2_PIX_FMT_RGB32:
107 nativeFormat = HAL_PIXEL_FORMAT_RGBA_8888;
108 break;
109 default:
110 ALOGE("Invalid format,Use default format");
111 }
112 return nativeFormat;
113}
114
115
116static ANativeWindowBuffer* handle_to_buffer(buffer_handle_t *handle)
117{
118 return container_of(handle, ANativeWindowBuffer, handle);
119}
120
121vdin_screen_source::vdin_screen_source()
122 : mCameraHandle(-1),
123 mVideoInfo(NULL)
124{
125 ALOGV("%s %d", __FUNCTION__, __LINE__);
126}
127
128int vdin_screen_source::init(){
129 ALOGV("%s %d", __FUNCTION__, __LINE__);
130 mCameraHandle = open("/dev/video11", O_RDWR| O_NONBLOCK);
131 if (mCameraHandle < 0)
132 {
133 ALOGE("[%s %d] mCameraHandle:%x [%s]", __FUNCTION__, __LINE__, mCameraHandle,strerror(errno));
134 return -1;
135 }
136 mVideoInfo = (struct VideoInfo *) calloc (1, sizeof (struct VideoInfo));
137 if (mVideoInfo == NULL)
138 {
139 ALOGE("[%s %d] no memory for mVideoInfo", __FUNCTION__, __LINE__);
140 close(mCameraHandle);
141 return NO_MEMORY;
142 }
143 mBufferCount = 4;
144 mPixelFormat = V4L2_PIX_FMT_NV21;
145 mNativeWindowPixelFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
146 mFrameWidth = 1280;
147 mFrameHeight = 720;
148 mBufferSize = mFrameWidth * mFrameHeight * 3/2;
149 mSetStateCB = NULL;
150 mState = STOP;
151 mANativeWindow = NULL;
152 mFrameType = 0;
153 mWorkThread = NULL;
154 mDataCB = NULL;
155 mOpen = false;
156 return NO_ERROR;
157}
158
159vdin_screen_source::~vdin_screen_source()
160{
161 if (mVideoInfo)
162 free (mVideoInfo);
163 if (mCameraHandle >= 0)
164 close(mCameraHandle);
165}
166
167int vdin_screen_source::start_v4l2_device()
168{
169 int ret = -1;
170
171 ALOGV("[%s %d] mCameraHandle:%x", __FUNCTION__, __LINE__, mCameraHandle);
172
173 ioctl(mCameraHandle, VIDIOC_QUERYCAP, &mVideoInfo->cap);
174
175 mVideoInfo->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
176 mVideoInfo->rb.memory = V4L2_MEMORY_MMAP;
177 mVideoInfo->rb.count = mBufferCount;
178
179 ret = ioctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
180
181 if (ret < 0) {
182 ALOGE("[%s %d] VIDIOC_REQBUFS:%d mCameraHandle:%x", __FUNCTION__, __LINE__, ret, mCameraHandle);
183 return ret;
184 }
185
186 for (int i = 0; i < mBufferCount; i++) {
187 memset (&mVideoInfo->buf, 0, sizeof (struct v4l2_buffer));
188
189 mVideoInfo->buf.index = i;
190 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
191 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
192
193 ret = ioctl (mCameraHandle, VIDIOC_QUERYBUF, &mVideoInfo->buf);
194 if (ret < 0) {
195 ALOGE("[%s %d]VIDIOC_QUERYBUF %d failed", __FUNCTION__, __LINE__, i);
196 return ret;
197 }
198 mVideoInfo->canvas[i] = mVideoInfo->buf.reserved;
199 mVideoInfo->mem[i] = (long *)mmap (0, mVideoInfo->buf.length, PROT_READ | PROT_WRITE,
200 MAP_SHARED, mCameraHandle, mVideoInfo->buf.m.offset);
201
202 if (mVideoInfo->mem[i] == MAP_FAILED) {
203 ALOGE("[%s %d] MAP_FAILED", __FUNCTION__, __LINE__);
204 return -1;
205 }
206 mVideoInfo->refcount[i] = 0;
207 mBufs.add(mVideoInfo->mem[i],i);
208 }
209 ALOGV("[%s %d] VIDIOC_QUERYBUF successful", __FUNCTION__, __LINE__);
210
211 for (int i = 0; i < mBufferCount; i++) {
212 mVideoInfo->buf.index = i;
213 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
214 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
215 ret = ioctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf);
216 if (ret < 0) {
217 ALOGE("VIDIOC_QBUF Failed");
218 return -1;
219 }
220 }
221 enum v4l2_buf_type bufType;
222 bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
223
224 ret = ioctl (mCameraHandle, VIDIOC_STREAMON, &bufType);
225
226 ALOGV("[%s %d] VIDIOC_STREAMON:%x", __FUNCTION__, __LINE__, ret);
227 return ret;
228}
229
230int vdin_screen_source::stop_v4l2_device()
231{
232 ALOGE("%s %d", __FUNCTION__, __LINE__);
233 int ret;
234 enum v4l2_buf_type bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
235
236 ret = ioctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType);
237 if (ret < 0) {
238 ALOGE("StopStreaming: Unable to stop capture: %s", strerror(errno));
239 }
240 for (int i = 0; i < mBufferCount; i++) {
241 if (munmap(mVideoInfo->mem[i], mVideoInfo->buf.length) < 0) {
242 ALOGE("Unmap failed");
243 }
244 }
245 return ret;
246}
247int vdin_screen_source::start()
248{
249 ALOGV("%s %d", __FUNCTION__, __LINE__);
250 int ret;
251 if(mOpen == true){
252 ALOGI("already open");
253 return NO_ERROR;
254 }
255
256 ret = start_v4l2_device();
257 if(ret != NO_ERROR){
258 ALOGE("Start v4l2 device failed:%d",ret);
259 return ret;
260 }
261 if(mFrameType & NATIVE_WINDOW_DATA){
262 ret = init_native_window();
263 if(ret != NO_ERROR){
264 ALOGE("Init Native Window Failed:%d",ret);
265 return ret;
266 }
267 }
268 if(mFrameType & NATIVE_WINDOW_DATA || mFrameType & CALL_BACK_DATA){
269 ALOGD("Create Work Thread");
270 mWorkThread = new WorkThread(this);
271 }
272 if(mSetStateCB != NULL)
273 mSetStateCB(START);
274 mState = START;
275 mOpen = true;
276 ALOGV("%s %d ret:%d", __FUNCTION__, __LINE__, ret);
277 return NO_ERROR;
278}
279
280int vdin_screen_source::pause()
281{
282 ALOGV("%s %d", __FUNCTION__, __LINE__);
283 mState = PAUSE;
284 if(mSetStateCB != NULL)
285 mSetStateCB(PAUSE);
286 return NO_ERROR;
287}
288int vdin_screen_source::stop()
289{
290 ALOGE("!!!!!!!!!%s %d", __FUNCTION__, __LINE__);
291 int ret;
292 mState = STOPING;
293
294 if(mWorkThread != NULL){
295 mWorkThread->requestExitAndWait();
296 mWorkThread.clear();
297 }
298
299 enum v4l2_buf_type bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
300
301 ret = ioctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType);
302 if (ret < 0) {
303 ALOGE("StopStreaming: Unable to stop capture: %s", strerror(errno));
304 }
305 for (int i = 0; i < mBufferCount; i++){
306 if (munmap(mVideoInfo->mem[i], mVideoInfo->buf.length) < 0)
307 ALOGE("Unmap failed");
308 }
309
310 mBufferCount = 0;
311 mState = STOP;
312 if(mSetStateCB != NULL)
313 mSetStateCB(STOP);
314 mOpen = false;
315 return ret;
316}
317
318int vdin_screen_source::set_state_callback(olStateCB callback)
319{
320 if (!callback){
321 ALOGE("NULL state callback pointer");
322 return BAD_VALUE;
323 }
324 mSetStateCB = callback;
325 return NO_ERROR;
326}
327
328int vdin_screen_source::set_preview_window(ANativeWindow* window)
329{
330 ALOGV("%s %d", __FUNCTION__, __LINE__);
331 if(mOpen == true)
332 return NO_ERROR;
333 //can work without a valid window object ?
334 if (window == NULL){
335 ALOGD("NULL window object passed to ScreenSource");
336 if(mWorkThread != NULL){
337 mWorkThread->requestExitAndWait();
338 mWorkThread.clear();
339 }
340 mFrameType &= ~NATIVE_WINDOW_DATA;
341 return NO_ERROR;
342 }
343 mFrameType |= NATIVE_WINDOW_DATA;
344 mANativeWindow = window;
345 return NO_ERROR;
346}
347
348int vdin_screen_source::set_data_callback(app_data_callback callback, void* user)
349{
350 ALOGV("%s %d", __FUNCTION__, __LINE__);
351 if (callback == NULL){
352 ALOGE("NULL data callback pointer");
353 return BAD_VALUE;
354 }
355 mDataCB = callback;
356 mUser = user;
357 mFrameType |= CALL_BACK_DATA;
358 return NO_ERROR;
359}
360
361int vdin_screen_source::get_format()
362{
363 return mPixelFormat;
364}
365
366int vdin_screen_source::set_format(int width, int height, int color_format)
367{
368 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
369 if(mOpen == true)
370 return NO_ERROR;
371 int ret;
372 mVideoInfo->width = ALIGN(width);
373 mVideoInfo->height = height;
374 mVideoInfo->framesizeIn = (mVideoInfo->width * mVideoInfo->height << 3); //note color format
375 mVideoInfo->formatIn = color_format;
376
377 mVideoInfo->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
378 mVideoInfo->format.fmt.pix.width = ALIGN(width);
379 mVideoInfo->format.fmt.pix.height = height;
380 mVideoInfo->format.fmt.pix.pixelformat = color_format;
381 mPixelFormat = color_format;
382 mNativeWindowPixelFormat = getNativeWindowFormat(color_format);
383 mFrameWidth = ALIGN(width);
384 mFrameHeight = height;
385 mBufferSize = getBufSize(color_format, mFrameWidth, mFrameHeight);
386 ALOGD("mFrameWidth:%d,mFrameHeight:%d",mFrameWidth,mFrameHeight);
387 ALOGD("mPixelFormat:%x,mNativeWindowPixelFormat:%x,mBufferSize:%d",mPixelFormat,mNativeWindowPixelFormat,mBufferSize);
388 ret = ioctl(mCameraHandle, VIDIOC_S_FMT, &mVideoInfo->format);
389 if (ret < 0) {
390 ALOGE("[%s %d]VIDIOC_S_FMT %d", __FUNCTION__, __LINE__, ret);
391 return ret;
392 }
393 return ret;
394}
395
396int vdin_screen_source::set_rotation(int degree)
397{
398 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
399
400 int ret = 0;
401 struct v4l2_control ctl;
402
403 if(mCameraHandle<0)
404 return -1;
405
406 if((degree!=0)&&(degree!=90)&&(degree!=180)&&(degree!=270)){
407 ALOGE("Set rotate value invalid: %d.", degree);
408 return -1;
409 }
410
411 memset( &ctl, 0, sizeof(ctl));
412 ctl.value=degree;
413 ctl.id = V4L2_ROTATE_ID;
414 ret = ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl);
415
416 if(ret<0){
417 ALOGE("Set rotate value fail: %s. ret=%d", strerror(errno),ret);
418 }
419 return ret ;
420}
421
422int vdin_screen_source::set_crop(int x, int y, int width, int height)
423{
424 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
425 if (NULL == mANativeWindow.get())
426 return BAD_VALUE;
427
428 int err = NO_ERROR;
429 android_native_rect_t crop = { x, y, x + width - 1, y + height - 1 };
430 err = native_window_set_crop(mANativeWindow.get(), &crop);
431 if (err != 0) {
432 ALOGW("Failed to set crop!");
433 return err;
434 }
435 return NO_ERROR;
436}
437
438int vdin_screen_source::set_frame_rate(int frameRate)
439{
440 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
441 int ret = 0;
442 struct v4l2_control ctl;
443
444 if(mCameraHandle<0)
445 return -1;
446
447 struct v4l2_streamparm sparm;
448 memset(&sparm, 0, sizeof( sparm ));
449 sparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;//stream_flag;
450 sparm.parm.output.timeperframe.denominator = frameRate;
451 sparm.parm.output.timeperframe.numerator = 1;
452
453 ret = ioctl(mCameraHandle, VIDIOC_S_PARM, &sparm);
454 if(ret < 0){
455 ALOGE("Set frame rate fail: %s. ret=%d", strerror(errno),ret);
456 }
457 return ret ;
458}
459
460int vdin_screen_source::set_amlvideo2_crop(int x, int y, int width, int height)
461{
462 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
463 int ret = 0;
464
465 struct v4l2_crop crop;
466 memset(&crop, 0, sizeof(struct v4l2_crop));
467
468 crop.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
469 crop.c.left = x;
470 crop.c.top = y;
471 crop.c.width = width;
472 crop.c.height = height;
473 ret = ioctl(mCameraHandle, VIDIOC_S_CROP, &crop);
474 if (ret) {
475 ALOGE("Set frame rate fail: %s. ret=%d", strerror(errno),ret);
476 }
477
478 return ret ;
479}
480
481int vdin_screen_source::set_source_type(int sourceType)
482{
483 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
484 int ret = 0;
485
486 ret = ioctl(mCameraHandle, VIDIOC_S_INPUT, &sourceType);
487 if(ret < 0){
488 ALOGE("Set source type fail: %s. ret:%d", strerror(errno),ret);
489 }
490 return ret;
491}
492
493int vdin_screen_source::set_port_type(int sourceType)
494 {
495 ALOGD("[%s %d]", __FUNCTION__, __LINE__);
496 int ret = 0;
497 unsigned int portType = (unsigned int)sourceType;
498 ALOGE("portType:%d",portType);
499 ret = ioctl(mCameraHandle, VIDIOC_S_INPUT, &portType);
500 if (ret < 0) {
501 ALOGE("Set port type fail: %s. ret:%d", strerror(errno),ret);
502 }
503 return ret;
504 }
505int vdin_screen_source::get_source_type()
506{
507 ALOGV("[%s %d]", __FUNCTION__, __LINE__);
508 int ret = -1;
509 int sourceType;
510
511 ret = ioctl(mCameraHandle, VIDIOC_G_INPUT, &sourceType);
512 if(ret < 0){
513 ALOGE("Set source type fail: %s. ret:%d", strerror(errno),ret);
514 return ret;
515 }
516 return sourceType;
517}
518
519int vdin_screen_source::aquire_buffer(aml_screen_buffer_info_t *buff_info)
520{
521 ALOGE("%s %d", __FUNCTION__, __LINE__);
522 int ret = -1;
523 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
524 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
525
526 ret = ioctl(mCameraHandle, VIDIOC_DQBUF, &mVideoInfo->buf);
527 if (ret < 0) {
528 if(EAGAIN == errno){
529 ret = -EAGAIN;
530 }else{
531 ALOGE("[%s %d]aquire_buffer %d", __FUNCTION__, __LINE__, ret);
532 }
533 buff_info->buffer_mem = 0;
534 buff_info->buffer_canvas = 0;
535 ALOGE("aquire_buffer %d %d", ret ,__LINE__);
536 return ret;
537 }
538
539 if (!(mFrameType & NATIVE_WINDOW_DATA || mFrameType & CALL_BACK_DATA))
540 mVideoInfo->refcount[mVideoInfo->buf.index] += 1;
541
542 ALOGE("%s finish %d ", __FUNCTION__, __LINE__);
543 buff_info->buffer_mem = mVideoInfo->mem[mVideoInfo->buf.index];
544 buff_info->buffer_canvas = mVideoInfo->canvas[mVideoInfo->buf.index];
545 buff_info->tv_sec = mVideoInfo->buf.timestamp.tv_sec;
546 buff_info->tv_usec = mVideoInfo->buf.timestamp.tv_usec;
547 return ret;
548}
549
550/* int vdin_screen_source::inc_buffer_refcount(int *ptr){
551 ALOGV("%s %d", __FUNCTION__, __LINE__);
552 int ret = -1;
553 int index;
554 index = mBufs.valueFor((unsigned int)ptr);
555 mVideoInfo->refcount[index] += 1;
556 return true;
557} */
558
559int vdin_screen_source::release_buffer(long* ptr)
560{
561 ALOGV("%s %d", __FUNCTION__, __LINE__);
562 int ret = -1;
563 int currentIndex;
564 v4l2_buffer hbuf_query;
565
566 Mutex::Autolock autoLock(mLock);
567
568 currentIndex = mBufs.valueFor(ptr);
569 if(mVideoInfo->refcount[currentIndex] > 0){
570 mVideoInfo->refcount[currentIndex] -= 1;
571 }else{
572 ALOGE("return buffer when refcount already zero");
573 return 0;
574 }
575 if(mVideoInfo->refcount[currentIndex] == 0){
576 memset(&hbuf_query,0,sizeof(v4l2_buffer));
577 hbuf_query.index = currentIndex;
578 hbuf_query.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
579 hbuf_query.memory = V4L2_MEMORY_MMAP;
580 ALOGV("return buffer :%d",currentIndex);
581 ret = ioctl(mCameraHandle, VIDIOC_QBUF, &hbuf_query);
582 if(ret != 0){
583 ALOGE("Return Buffer :%d failed", currentIndex);
584 }
585 }
586 return 0;
587}
588
589int vdin_screen_source::init_native_window()
590{
591 ALOGV("%s %d", __FUNCTION__, __LINE__);
592 int err = NO_ERROR;
593
594 if(NULL == mANativeWindow.get())
595 return BAD_VALUE;
596
597 // Set gralloc usage bits for window.
598 err = native_window_set_usage(mANativeWindow.get(), SCREENSOURCE_GRALLOC_USAGE);
599 if (err != 0) {
600 ALOGE("native_window_set_usage failed: %s\n", strerror(-err));
601 if(ENODEV == err ){
602 ALOGE("Preview surface abandoned!");
603 mANativeWindow = NULL;
604 }
605 return err;
606 }
607
608 ALOGD("Number of buffers set to ANativeWindow %d", mBufferCount);
609 ///Set the number of buffers needed for camera preview
610 err = native_window_set_buffer_count(mANativeWindow.get(), mBufferCount);
611 if (err != 0) {
612 ALOGE("native_window_set_buffer_count failed: %s (%d)", strerror(-err), -err);
613 if(ENODEV == err){
614 ALOGE("Preview surface abandoned!");
615 mANativeWindow = NULL;
616 }
617 return err;
618 }
619
620 ALOGD("native_window_set_buffers_geometry format:0x%x",mNativeWindowPixelFormat);
621 // Set window geometry
622 err = native_window_set_buffers_geometry(
623 mANativeWindow.get(),
624 mFrameWidth,
625 mFrameHeight,
626 mNativeWindowPixelFormat);
627
628 if (err != 0) {
629 ALOGE("native_window_set_buffers_geometry failed: %s", strerror(-err));
630 if ( ENODEV == err ) {
631 ALOGE("Surface abandoned!");
632 mANativeWindow = NULL;
633 }
634 return err;
635 }
636 err = native_window_set_scaling_mode(mANativeWindow.get(), NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
637 if (err != 0) {
638 ALOGW("Failed to set scaling mode: %d", err);
639 return err;
640 }
641 return NO_ERROR;
642}
643
644int vdin_screen_source::workThread()
645{
646 bool buff_keep = false;
647 int index;
648 aml_screen_buffer_info_t buff_info;
649 int ret;
650 long *src = NULL;
651 unsigned char *dest = NULL;
652 uint8_t *handle = NULL;
653 ANativeWindowBuffer* buf;
654 if(mState == START){
655 usleep(5000);
656 ret = aquire_buffer(&buff_info);
657 if (ret != 0 || (buff_info.buffer_mem == 0)) {
658 ALOGV("Get V4l2 buffer failed");
659 return ret;
660 }
661 src = buff_info.buffer_mem;
662 index = mBufs.valueFor(src);
663 if(mFrameType & NATIVE_WINDOW_DATA){
664 mVideoInfo->refcount[index] += 1;
665 if(mANativeWindow.get() == NULL){
666 ALOGE("Null window");
667 return BAD_VALUE;
668 }
669 ret = mANativeWindow->dequeueBuffer_DEPRECATED(mANativeWindow.get(), &buf);
670 if(ret != 0){
671 ALOGE("dequeue buffer failed :%s (%d)",strerror(-ret), -ret);
672 return BAD_VALUE;
673 }
674 mANativeWindow->lockBuffer_DEPRECATED(mANativeWindow.get(), buf);
675 sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
676 graphicBuffer->lock(SCREENSOURCE_GRALLOC_USAGE, (void **)&dest);
677 if(dest == NULL){
678 ALOGE("Invalid Gralloc Handle");
679 return BAD_VALUE;
680 }
681 memcpy(dest, src, mBufferSize);
682 graphicBuffer->unlock();
683 mANativeWindow->queueBuffer_DEPRECATED(mANativeWindow.get(), buf);
684 graphicBuffer.clear();
685 ALOGV("queue one buffer to native window");
686 release_buffer(src);
687 }
688 if(mFrameType & CALL_BACK_DATA && mDataCB != NULL&& mState == START){
689 mVideoInfo->refcount[index] += 1;
690 mDataCB(mUser, &buff_info);
691 }
692 }
693 return NO_ERROR;
694}
695
696}
697