summaryrefslogtreecommitdiff
path: root/tvapi/libtv/tv/CTvScreenCapture.cpp (plain)
blob: 396c1d5c53ea69100f0f880e2767df7655880b2d
1
2#include <stdlib.h>
3#include <fcntl.h>
4#include <strings.h>
5#include <sys/ioctl.h>
6#include <asm/types.h>
7#include <fcntl.h>
8#include <unistd.h>
9#include <errno.h>
10#include <malloc.h>
11#include <sys/stat.h>
12#include <sys/types.h>
13#include <time.h>
14#include <sys/mman.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <assert.h>
19#include <linux/videodev2.h>
20#include <dirent.h>
21
22#include <binder/MemoryHeapBase.h>
23#include <binder/MemoryBase.h>
24
25//#include <media/stagefright/MediaSource.h>
26//#include <media/stagefright/MediaBuffer.h>
27//#include <OMX_IVCommon.h>
28//#include <media/stagefright/MetaData.h>
29//#include <media/stagefright/ScreenCatch.h>
30using namespace android;
31
32
33#include "CTvScreenCapture.h"
34
35#define CLEAR(x) memset (&(x), 0, sizeof (x))
36
37int CTvScreenCapture::xioctl(int fd, int request, void *arg)
38{
39 /* int r = 0;
40
41 do {
42 r = ioctl(fd, request, arg);
43 } while (-1 == r && EINTR == errno);
44
45 return r;*/
46 return 0;
47}
48
49int CTvScreenCapture::OpenCamera(struct camera *pCameraDev)
50{
51 /*
52 int iOutRet = 0, iRet;
53 struct stat st;
54
55 do {
56 if (-1 == stat(pCameraDev->device_name, &st)) {
57 LOGD( "Cannot identify '%s'\n", pCameraDev->device_name);
58 iOutRet = FAILED;
59 break;
60 }
61
62 if (!S_ISCHR(st.st_mode)) {
63 LOGD("%s is no device\n", pCameraDev->device_name);
64 iOutRet = FAILED;
65 break;
66 }
67
68 pCameraDev->fd = open(pCameraDev->device_name, O_RDWR | O_NONBLOCK, 0); // O_NONBLOCK
69 if (SUCCEED > pCameraDev->fd) {
70 LOGD("Cannot open '%s'\n", pCameraDev->device_name);
71 iOutRet = FAILED;
72 break;
73 }
74 } while (FALSE);
75
76 return iOutRet;*/
77 return 0;
78}
79
80
81int CTvScreenCapture::InitVCap(sp<IMemory> Mem)
82{
83 /* int iOutRet = FAILED;
84
85 do {
86 m_pMem = Mem;
87 m_pData = (char *)m_pMem->pointer();
88 LOGD("VVVVVVVVVVVVVVVVVVVVVVVVVVVVV %p\n", m_pData);
89 //default
90 } while (FALSE);
91
92 return iOutRet;*/
93 return 0;
94}
95
96int CTvScreenCapture::InitMmap(struct camera *cam)
97{
98 /* int iOutRet = SUCCEED, iRet;
99 struct v4l2_requestbuffers req;
100
101 do {
102 CLEAR(req);
103
104 req.count = 4;
105 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
106 req.memory = V4L2_MEMORY_MMAP;
107
108 iRet = xioctl(cam->fd, VIDIOC_REQBUFS, &req);
109 if (FAILED == iRet) {
110 if (EINVAL == errno) {
111 LOGD("VIDIOC_REQBUFS %s does not support memory mapping\n", cam->device_name);
112 }
113 iOutRet = iRet;
114 break;
115 }
116
117 if (req.count < 2) {
118 LOGD("Insufficient buffer memory on %s\n", cam->device_name);
119 iOutRet = FAILED;
120 break;
121 }
122
123 cam->buffers = (struct buffer *)calloc(req.count, sizeof(*(cam->buffers)));
124 if (!cam->buffers) {
125 LOGD("Out of memory\n");
126 iOutRet = FAILED;
127 break;
128 }
129
130 for (m_capNumBuffers = 0; m_capNumBuffers < req.count; ++m_capNumBuffers) {
131 struct v4l2_buffer buf;
132
133 CLEAR(buf);
134
135 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
136 buf.memory = V4L2_MEMORY_MMAP;
137 buf.index = m_capNumBuffers;
138
139 if (FAILED == xioctl(cam->fd, VIDIOC_QUERYBUF, &buf)) {
140 LOGD("VIDIOC_QUERYBUF ERROR\n");
141 iOutRet = FAILED;
142 goto IS_ERROR;
143 }
144
145 cam->buffers[m_capNumBuffers].length = buf.length;
146 cam->buffers[m_capNumBuffers].start = mmap(NULL \,
147 buf.length, PROT_READ | PROT_WRITE,
148 MAP_SHARED, cam->fd, buf.m.offset);
149
150 if (MAP_FAILED == cam->buffers[m_capNumBuffers].start) {
151 iOutRet = FAILED;
152 break;
153 }
154
155
156 }
157
158 LOGD("END m_capNumBuffers : %d\n", m_capNumBuffers);
159 } while (FALSE);
160 IS_ERROR:
161 return iOutRet;*/
162 return 0;
163}
164
165int CTvScreenCapture::InitCamera(struct camera *cam)
166{
167 /*
168 int iOutRet = SUCCEED, iRet;
169 struct v4l2_capability *cap = &(cam->v4l2_cap);
170 struct v4l2_cropcap *cropcap = &(cam->v4l2_cropcap);
171 struct v4l2_crop *crop = &(cam->crop);
172 struct v4l2_format *fmt = &(cam->v4l2_fmt);
173 unsigned int min;
174
175 do {
176 iRet = xioctl(cam->fd, VIDIOC_QUERYCAP, cap);
177 if (FAILED == iRet) {
178 if (EINVAL == errno) {
179 LOGD("%s is no V4L2 device\n", cam->device_name);
180 }
181 iOutRet = iRet;
182 break;
183 }
184
185 if (!(cap->capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
186 LOGD("%s is no video capture device\n", cam->device_name);
187 iOutRet = FAILED;
188 break;
189 }
190
191 if (!(cap->capabilities & V4L2_CAP_STREAMING)) {
192 LOGD("%s does not support streaming i/o\n", cam->device_name);
193 iOutRet = FAILED;
194 break;
195 }
196
197 LOGD("VIDOOC_QUERYCAP camera driver is [%s] card is [%s] businfo is [%s] version is [%d]\n", cap->driver,
198 cap->card, cap->bus_info, cap->version);
199
200 //* Select video input, video standard and tune here.
201
202 CLEAR(*cropcap);
203 cropcap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
204
205 crop->c.width = cam->width;
206 crop->c.height = cam->height;
207 crop->c.left = 0;
208 crop->c.top = 0;
209 crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
210
211 CLEAR(*fmt);
212 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
213 fmt->fmt.pix.width = cam->width;
214 fmt->fmt.pix.height = cam->height;
215 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_NV21;
216 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
217 iRet = xioctl(cam->fd, VIDIOC_S_FMT, fmt);
218 if (FAILED == iRet) {
219 iOutRet = iRet;
220 LOGD("VIDIOC_S_FMT is ERROR\n");
221 break;
222 }
223
224 //* Note VIDIOC_S_FMT may change width and height.
225 //* Buggy driver paranoia.
226 min = fmt->fmt.pix.width * 2;
227 LOGD("bytesperline : %d w:h [%d %d]\n", fmt->fmt.pix.bytesperline, fmt->fmt.pix.width, fmt->fmt.pix.height);
228 if (fmt->fmt.pix.bytesperline < min) {
229 fmt->fmt.pix.bytesperline = min;
230 }
231
232 min = fmt->fmt.pix.bytesperline * fmt->fmt.pix.height;
233 if (fmt->fmt.pix.sizeimage < min) {
234 fmt->fmt.pix.sizeimage = min;
235 }
236
237 iRet = InitMmap(cam);
238 if (FAILED == iRet) {
239 LOGD("INIT MMAP FAILED\n");
240 iOutRet = iRet;
241 break;
242 }
243
244 } while (FALSE);
245
246 return iOutRet;
247 */
248 return 0;
249}
250
251
252int CTvScreenCapture::SetVideoParameter(int width, int height, int frame)
253{
254 /*
255 int iOutRet = SUCCEED, iRet;
256
257 do {
258 m_capV4l2Cam.device_name = "/dev/video11";
259 m_capV4l2Cam.buffers = NULL;
260 m_capV4l2Cam.width = 1280;
261 m_capV4l2Cam.height = 720;
262 m_capV4l2Cam.display_depth = 24; //5; //* RGB24
263 m_capV4l2Cam.frame_number = 1; //fps
264 iOutRet = OpenCamera(&m_capV4l2Cam) ;
265 if (SUCCEED != iOutRet) {
266 LOGD("ERROR:::Open Camera device failed\n");
267 break;
268 }
269 m_capV4l2Cam.width = width;
270 m_capV4l2Cam.height = height;
271 m_capV4l2Cam.frame_number = frame;
272
273 iRet = InitCamera(&m_capV4l2Cam);
274 if (SUCCEED != iRet) {
275 iOutRet = iRet;
276 break;
277 }
278
279 } while (FALSE);
280
281 return iOutRet ;*/
282 return 0;
283}
284
285int CTvScreenCapture::StartCapturing(struct camera *cam)
286{
287 /*
288 unsigned int i;
289 int iOutRet = SUCCEED, iRet;
290 enum v4l2_buf_type type;
291
292 do {
293 for (i = 0; i < m_capNumBuffers; ++i) {
294 struct v4l2_buffer buf;
295
296 //CLEAR(buf);
297
298 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
299 buf.memory = V4L2_MEMORY_MMAP;
300 buf.index = i;
301
302 iRet = xioctl(cam->fd, VIDIOC_QBUF, &buf);
303 if (FAILED == iRet) {
304 iOutRet = iRet;
305 goto IS_ERROR;
306 }
307 }
308
309
310 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
311 iRet = xioctl(cam->fd, VIDIOC_STREAMON, &type);
312 if (FAILED == iRet) {
313 iOutRet = iRet;
314 break;
315 }
316 } while (FALSE);
317 IS_ERROR:
318
319 return iOutRet;*/
320 return 0;
321}
322
323int CTvScreenCapture::VideoStart()
324{
325 /*
326 int iOutRet = SUCCEED, iRet;
327
328 do {
329 iRet = StartCapturing(&m_capV4l2Cam);
330 if (FAILED == iRet) {
331 iOutRet = iRet;
332 break;
333 }
334
335 } while (FALSE);
336
337 return iOutRet;*/
338 return 0;
339}
340
341void CTvScreenCapture::yuv_to_rgb32(unsigned char y, unsigned char u, unsigned char v, unsigned char *rgb)
342{
343 /*
344 register int r, g, b;
345 int rgb24;
346
347 r = (1192 * (y - 16) + 1634 * (v - 128) ) >> 10;
348 g = (1192 * (y - 16) - 833 * (v - 128) - 400 * (u - 128) ) >> 10;
349 b = (1192 * (y - 16) + 2066 * (u - 128) ) >> 10;
350
351 r = r > 255 ? 255 : r < 0 ? 0 : r;
352 g = g > 255 ? 255 : g < 0 ? 0 : g;
353 b = b > 255 ? 255 : b < 0 ? 0 : b;
354
355 rgb24 = (int)((r << 16) | (g << 8) | b);
356
357 //*ARGB
358 *rgb = (unsigned char)r;
359 rgb ++;
360 *rgb = (unsigned char)g;
361 rgb++;
362 *rgb = (unsigned char)b;
363 rgb++;
364 *rgb = 0xff;*/
365 return;
366}
367
368
369void CTvScreenCapture::nv21_to_rgb32(unsigned char *buf, unsigned char *rgb, int width, int height, int *len)
370{
371 /*
372 int x, y, z = 0;
373 int h, w;
374 int blocks;
375 unsigned char Y1, Y2, U, V;
376
377 *len = 0;
378
379 blocks = (width * height) * 2;
380
381 for (h = 0, z = 0; h < height; h += 2) {
382 for (y = 0; y < width * 2; y += 2) {
383
384 Y1 = buf[ h * width + y + 0];
385 V = buf[ blocks / 2 + h * width / 2 + y % width + 0 ];
386 Y2 = buf[ h * width + y + 1];
387 U = buf[ blocks / 2 + h * width / 2 + y % width + 1 ];
388
389 yuv_to_rgb32(Y1, U, V, &rgb[z]);
390 yuv_to_rgb32(Y2, U, V, &rgb[z + 4]);
391 z += 8;
392 }
393 }
394 *len = z;
395 LOGD("z +++++++++++++++++++++++++++++++++ z %d\n", z);*/
396 return;
397}
398
399
400int CTvScreenCapture::GetVideoData(int *length)
401{
402 /*
403 int iOutRet = SUCCEED, iRet;
404
405 *length = 0;
406 while (true) {
407 fd_set fds;
408 struct timeval tv;
409 FD_ZERO(&fds);
410 FD_SET(m_capV4l2Cam.fd, &fds);
411 //* Timeout.
412 tv.tv_sec = 0;
413 tv.tv_usec = 30000;
414 iRet = select(m_capV4l2Cam.fd + 1, &fds, NULL, NULL, &tv);
415 if (FAILED == iRet) {
416 LOGD("select FAILED\n");
417 if (EINTR == errno) {
418 LOGD("select FAILED Continue\n");
419 continue;
420 }
421
422 }
423
424 if (0 == iRet) {
425 LOGD("select timeout\n");
426 continue ;
427 }
428
429 struct v4l2_buffer buf;
430 CLEAR(buf);
431
432 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
433 buf.memory = V4L2_MEMORY_MMAP;
434 iRet = xioctl(m_capV4l2Cam.fd, VIDIOC_DQBUF, &buf);
435 if (FAILED == iRet) {
436 if (errno == EAGAIN) {
437 LOGD("GetVideoData EAGAIN \n");
438 }
439
440 continue;
441 }
442
443 LOGD("DDDDDDDDDDAAAAAAAAAAAAAAAAAAAATTTTTTTTTTTTTTAAAAAAAAAAAAAAAAAAAAAAAAAAAAA %d %d [width:%d] [height:%d]\n", buf.length, iRet,
444 m_capV4l2Cam.width, m_capV4l2Cam.height);
445 int tmpLen = 0;
446 nv21_to_rgb32((unsigned char *)m_capV4l2Cam.buffers[buf.index].start, (unsigned char *)m_pData, m_capV4l2Cam.width, m_capV4l2Cam.height, &tmpLen);
447 //memcpy(m_pData,m_capV4l2Cam.buffers[buf.index].start, buf.length +1);
448 *length = buf.length;
449 break;
450
451 }
452
453 if (*length > 0) {
454 mCapEvt.mFrameWide = m_capV4l2Cam.width;
455 mCapEvt.mFrameHeight = m_capV4l2Cam.height;
456 mCapEvt.mFrameNum = 1;
457 mCapEvt.mFrameSize = *length;
458 } else {
459 mCapEvt.mFrameWide = 0;
460 mCapEvt.mFrameHeight = 0;
461 mCapEvt.mFrameNum = 0;
462 mCapEvt.mFrameSize = 0;
463 }
464
465 if (NULL != mpObserver) {
466 mpObserver->onTvEvent(mCapEvt);
467 }
468
469 return iOutRet;*/
470 return 0;
471}
472
473int CTvScreenCapture::StopCapturing(struct camera *cam)
474{
475 /*
476 int iOutRet = SUCCEED, iRet;
477 enum v4l2_buf_type type;
478
479 do {
480 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
481
482 iRet = xioctl(cam->fd, VIDIOC_STREAMOFF, &type);
483 if (FAILED == iRet) {
484 iOutRet = iRet;
485 break;
486 }
487 } while (FALSE);
488
489 return iOutRet;*/
490 return 0;
491}
492
493int CTvScreenCapture::VideoStop()
494{
495 /*
496 StopCapturing(&m_capV4l2Cam);
497 UninitCamera(&m_capV4l2Cam);
498 return SUCCEED;*/
499 return 0;
500}
501
502int CTvScreenCapture::UninitCamera(struct camera *cam)
503{
504 /*
505 unsigned int i;
506
507 for (i = 0; i < m_capNumBuffers; ++i) {
508 if (cam->buffers[i].start == NULL) {
509 break;
510 }
511
512 if (FAILED == munmap(cam->buffers[i].start, cam->buffers[i].length)) {
513 LOGD("ERROR::munmap cam buffer failed\n");
514 break;
515 }
516 }
517
518 if (NULL != cam->buffers)
519 free(cam->buffers);
520
521 cam->buffers = NULL;
522
523 return SUCCEED;*/
524 return 0;
525}
526
527int CTvScreenCapture::CloseCamera(struct camera *cam)
528{
529 /*
530 int iOutRet = SUCCEED, iRet;
531
532 do {
533 if (cam->fd > 0) {
534 iRet = close(cam->fd);
535 if (FAILED == iRet) {
536 iOutRet = iRet;
537 break;
538 }
539
540 cam->fd = -1;
541 }
542 } while (FALSE);
543
544 return iOutRet;*/
545 return 0;
546}
547
548int CTvScreenCapture::DeinitVideoCap()
549{
550 /*
551 CloseCamera(&m_capV4l2Cam);
552 return SUCCEED ;
553 */
554 return 0;
555}
556
557int CTvScreenCapture::AmvideocapCapFrame(char *buf, int size, int *w, int *h, int *ret_size)
558{
559 /*
560 int iOutRet = SUCCEED, iRet;
561 int iDevFd = -1;
562 int format = FORMAT_S32_ABGR;
563
564 do {
565 iDevFd = open(VIDEOCAPDEV, O_RDWR);
566 if (iDevFd < 0) {
567 LOGD("ERROR,open amvideocap0 failed\n");
568 iOutRet = FAILED;
569 break;
570 }
571
572 if ((w != NULL) && (*w > 0)) {
573 iRet = ioctl(iDevFd, AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH, *w);
574 if (iRet < 0) {
575 iOutRet = iRet;
576 break;
577 }
578 }
579
580 if ((h != NULL) && (*h > 0)) {
581
582 iRet = ioctl(iDevFd, AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT, *h);
583 if (iRet < 0) {
584 iOutRet = iRet;
585 break;
586 }
587 }
588
589 iRet = ioctl(iDevFd, AMVIDEOCAP_IOW_SET_WANTFRAME_FORMAT, format);
590 if (iRet < 0) {
591 iOutRet = iRet;
592 break;
593 }
594
595 *ret_size = read(iDevFd, buf, size);
596 if (0 == *ret_size) {
597 LOGD("ERROR:: Cann't Read video data\n");
598 iOutRet = FAILED;
599 *ret_size = 0;
600 break;
601 }
602
603 LOGD("========== Got Data Size : %d ==============\n", *ret_size);
604 #if 0
605 if (w != NULL) {
606 iRet = ioctl(iDevFd, AMVIDEOCAP_IOR_GET_FRAME_WIDTH, w);
607 }
608
609 if (h != NULL) {
610 iRet = ioctl(iDevFd, AMVIDEOCAP_IOR_GET_FRAME_HEIGHT, h);
611 }
612 #endif
613 } while (FALSE);
614
615 close(iDevFd);
616
617 return iOutRet;*/
618 return 0;
619}
620
621int CTvScreenCapture::CapOsdAndVideoLayer(int width, int height)
622{
623 /*
624 int iOutRet = SUCCEED, iRet;
625 status_t iStatus;
626 ScreenCatch *mScreenCatch = NULL;
627 MetaData *pMeta = NULL;
628 MediaBuffer *buffer = NULL;
629 int dataLen = 0;
630
631 do {
632 mScreenCatch = new ScreenCatch(width, height, 32);
633 if (NULL == mScreenCatch) {
634 LOGD("ERROR!!! mScreenCatch is NULL\n");
635 iOutRet = FAILED;
636 break;
637 }
638
639 pMeta = new MetaData();
640 if (NULL == pMeta) {
641 LOGD("ERROR!!! pMeta is NULL\n");
642 iOutRet = FAILED;
643 break;
644 }
645 pMeta->setInt32(kKeyColorFormat, OMX_COLOR_Format32bitARGB8888);
646
647 mScreenCatch->start(pMeta);
648
649 while (true) {
650 iStatus = mScreenCatch->read(&buffer);
651 if (iStatus != OK ) {
652 usleep(1000);
653 continue;
654 }
655
656 if (NULL == buffer) {
657 iOutRet = FAILED;
658 break;
659 }
660
661 LOGD("DDDDDDDDDDAAAAAAAAAAAAAAAAAAAATTTTTTTTTTTTTTAAAAAAAAAAAAAAAAAAAAAAAAAAAAA %d %d\n", buffer->size(), iStatus);
662 //nv21_to_rgb32((unsigned char*)buffer->data(),(unsigned char *)m_pData,width,height,&dataLen);
663 memcpy((unsigned char *)m_pData, (unsigned char *)buffer->data(), buffer->size());
664 break;
665 }
666
667 } while (FALSE);
668
669 if (dataLen > 0) {
670 mCapEvt.mFrameWide = width;
671 mCapEvt.mFrameHeight = height;
672 mCapEvt.mFrameNum = 1;
673 mCapEvt.mFrameSize = dataLen;
674 } else {
675 mCapEvt.mFrameWide = 0;
676 mCapEvt.mFrameHeight = 0;
677 mCapEvt.mFrameNum = 0;
678 mCapEvt.mFrameSize = 0;
679 }
680
681 if (NULL != mpObserver) {
682 mpObserver->onTvEvent(mCapEvt);
683 }
684
685 mScreenCatch->stop();
686
687 mScreenCatch->free(buffer);
688 buffer = NULL;
689 return iOutRet;*/
690 return 0;
691}
692
693int CTvScreenCapture::CapMediaPlayerVideoLayerOnly(int width, int height)
694{
695 /*
696 int iOutRet = SUCCEED, iRet;
697 int ibufSize, iDataSize = 0;
698 int w, h;
699
700 do {
701 ibufSize = width * height * 4;
702 w = width;
703 h = height;
704
705 iRet = AmvideocapCapFrame(m_pData, ibufSize, &w, &h, &iDataSize);
706 if (SUCCEED != iRet) {
707 LOGD("AmvideocapCapFrame Cannt CapFram\n");
708 iOutRet = iRet;
709 break;
710 }
711
712 LOGD("GOT DDDDDDDDDAAAAAAAATTTTTTTTTTTAAAAAA Size : %d w:%d h: %d\n", iDataSize, w, h);
713
714 if (iDataSize > 0) {
715 mCapEvt.mFrameWide = w;
716 mCapEvt.mFrameHeight = h;
717 mCapEvt.mFrameNum = 1;
718 mCapEvt.mFrameSize = iDataSize;
719 } else {
720 mCapEvt.mFrameWide = 0;
721 mCapEvt.mFrameHeight = 0;
722 mCapEvt.mFrameNum = 0;
723 mCapEvt.mFrameSize = 0;
724 }
725
726 if (NULL != mpObserver) {
727 mpObserver->onTvEvent(mCapEvt);
728 }
729 } while (FALSE);
730
731 return iOutRet;*/
732 return 0;
733}
734
735CTvScreenCapture::CTvScreenCapture()
736{
737 /*
738 m_capNumBuffers = 0;
739 memset(&m_capV4l2Cam, 0x00, sizeof(camera));
740 mpObserver = NULL;*/
741 return ;
742}
743CTvScreenCapture::~CTvScreenCapture()
744{
745 /*
746 memset(&m_capV4l2Cam, 0x00, sizeof(camera));
747 m_pData = NULL;*/
748}
749
750