1 /**************************************************************************
3 xserver-xorg-video-emulfb
5 Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
7 Contact: Boram Park <boram1288.park@samsung.com>
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
35 #include <sys/types.h>
39 #include <X11/extensions/Xv.h>
40 #include <X11/extensions/Xvproto.h>
42 #include "fbdev_util.h"
43 #include "fbdev_video_v4l2.h"
47 #include "fbdev_util.h"
48 #include "fbdev_video.h"
49 #include "fbdev_video_fourcc.h"
51 typedef struct _DeviceInfo
53 char *video; /* video */
54 char *fb; /* output frame buffer */
59 typedef struct _FormatInfo
64 FBDevV4l2Memory memory;
80 struct fb_fix_screeninfo fix;
107 FBDevV4l2FimcBuffer fimcbuf;
108 FBDevV4l2SrcBuffer *src_buf;
109 FBDevV4l2Memory memory;
111 int initial_dequeued_buf;
123 static FormatInfo format_infos [] =
125 { FOURCC_RGB565, TYPE_RGB, V4L2_PIX_FMT_RGB565, V4L2_MEMORY_MMAP },
126 { FOURCC_RGB32, TYPE_RGB, V4L2_PIX_FMT_RGB32, V4L2_MEMORY_MMAP },
127 { FOURCC_I420, TYPE_YUV420, V4L2_PIX_FMT_YUV420, V4L2_MEMORY_MMAP },
128 { FOURCC_S420, TYPE_YUV420, V4L2_PIX_FMT_YUV420, V4L2_MEMORY_USERPTR },
129 { FOURCC_ST12, TYPE_YUV420, V4L2_PIX_FMT_NV12T, V4L2_MEMORY_USERPTR },
130 { FOURCC_NV12, TYPE_YUV420, V4L2_PIX_FMT_NV12, V4L2_MEMORY_MMAP },
131 { FOURCC_SN12, TYPE_YUV420, V4L2_PIX_FMT_NV12, V4L2_MEMORY_USERPTR },
132 { FOURCC_YUY2, TYPE_YUV422, V4L2_PIX_FMT_YUYV, V4L2_MEMORY_MMAP },
133 { FOURCC_SUYV, TYPE_YUV422, V4L2_PIX_FMT_YUYV, V4L2_MEMORY_USERPTR },
136 static XF86ImageRec Images[] =
149 static DeviceInfo device_infos[] =
151 { "/dev/video2", "/dev/fb1", OUTPUT_PATH_DMA, FALSE },
152 { "/dev/video3", "/dev/fb2", OUTPUT_PATH_DMA, FALSE },
155 #define NUM_IMAGES (sizeof(Images) / sizeof(XF86ImageRec))
156 #define DEVICE_NUMS (sizeof (device_infos) / sizeof (DeviceInfo))
159 _fbdevVideoV4l2SetSrc (int fd,
160 xRectangle *src_rect,
161 xRectangle *crop_rect,
164 struct v4l2_format format = {0,};
165 struct v4l2_crop crop = {0,};
168 return_val_if_fail (fd >= 0, FALSE);
170 DRVLOG ("[SetSrc] src_r(%d,%d %dx%d) crop_r(%d,%d %dx%d) pixfmt(0x%08x) \n",
171 src_rect->x, src_rect->y, src_rect->width, src_rect->height,
172 crop_rect->x, crop_rect->y, crop_rect->width, crop_rect->height,
175 /* check if capabilities is valid */
176 capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_OVERLAY;
177 if (!fbdev_v4l2_querycap (fd, capabilities))
182 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
183 if (!fbdev_v4l2_g_fmt (fd, &format))
186 format.fmt.pix.width = src_rect->width;
187 format.fmt.pix.height = src_rect->height;
188 format.fmt.pix.pixelformat = pixelformat;
189 format.fmt.pix.field = V4L2_FIELD_NONE;
190 if (!fbdev_v4l2_s_fmt (fd, &format))
195 crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
196 crop.c.left = crop_rect->x;
197 crop.c.top = crop_rect->y;
198 crop.c.width = crop_rect->width;
199 crop.c.height = crop_rect->height;
200 if (!fbdev_v4l2_cropcap (fd, crop.type, &crop.c))
203 if (!fbdev_v4l2_s_crop (fd, &crop))
210 _fbdevVideoV4l2SetDst (int fd,
211 xRectangle *dst_rect,
212 xRectangle *win_rect,
219 struct v4l2_format format = {0,};
220 struct v4l2_control ctrl = {0,};
221 struct v4l2_framebuffer fbuf = {0,};
223 return_val_if_fail (fd >= 0, FALSE);
225 DRVLOG ("[SetDst] dst_r(%d,%d %dx%d) win_r(%d,%d %dx%d) rot(%d) flip(%d,%d) path(%d) addr(%p) \n",
226 dst_rect->x, dst_rect->y, dst_rect->width, dst_rect->height,
227 win_rect->x, win_rect->y, win_rect->width, win_rect->height,
228 rotation, hflip, vflip, path, (void*)addr);
232 ctrl.id = V4L2_CID_ROTATION;
233 ctrl.value = rotation;
234 if (!fbdev_v4l2_s_ctrl (fd, &ctrl))
238 ctrl.id = V4L2_CID_HFLIP;
240 if (!fbdev_v4l2_s_ctrl (fd, &ctrl))
244 ctrl.id = V4L2_CID_VFLIP;
246 if (!fbdev_v4l2_s_ctrl (fd, &ctrl))
249 ctrl.id = V4L2_CID_OVLY_MODE;
250 ctrl.value = 0x4; //single buffer
251 if (!fbdev_v4l2_s_ctrl (fd, &ctrl))
254 /* set framebuffer */
256 if (!fbdev_v4l2_g_fbuf (fd, &fbuf))
259 if (path == OUTPUT_PATH_DMA)
260 fbuf.base = (void*)addr;
262 fbuf.fmt.width = dst_rect->width;
263 fbuf.fmt.height = dst_rect->height;
264 fbuf.fmt.pixelformat = V4L2_PIX_FMT_RGB32;
265 if (!fbdev_v4l2_s_fbuf (fd, &fbuf))
270 format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
271 if (!fbdev_v4l2_g_fmt (fd, &format))
274 format.fmt.win.w.left = win_rect->x;
275 format.fmt.win.w.top = win_rect->y;
276 format.fmt.win.w.width = win_rect->width;
277 format.fmt.win.w.height = win_rect->height;
278 if (!fbdev_v4l2_s_fmt (fd, &format))
285 _fbdevVideoV4l2SetBuffer (int fd,
286 FBDevV4l2BufType type,
287 FBDevV4l2Memory memory,
289 FBDevV4l2SrcBuffer **mem_buf)
291 struct v4l2_requestbuffers req = {0,};
293 return_val_if_fail (fd >= 0, FALSE);
295 DRVLOG ("[SetBuffer] num_buf(%d) mem_buf(%p) memory(%d)\n",
296 num_buf, mem_buf, memory);
302 if (!fbdev_v4l2_reqbuf (fd, &req))
305 if (memory == V4L2_MEMORY_MMAP)
307 FBDevV4l2SrcBuffer *out_buf;
310 return_val_if_fail (mem_buf != NULL, FALSE);
312 out_buf = calloc (req.count, sizeof (FBDevV4l2SrcBuffer));
313 return_val_if_fail (out_buf != NULL, FALSE);
315 for (i = 0; i < num_buf; i++)
317 struct v4l2_buffer buffer = {0,};
322 buffer.memory = V4L2_MEMORY_MMAP;
323 if (!fbdev_v4l2_querybuf (fd, &buffer))
329 out_buf[i].index = buffer.index;
330 out_buf[i].size = buffer.length;
331 out_buf[i].buf = mmap (NULL, buffer.length,
332 PROT_READ | PROT_WRITE , \
333 MAP_SHARED , fd, buffer.m.offset);
334 if (out_buf[i].buf == MAP_FAILED)
336 xf86DrvMsg (0, X_ERROR, "[SetBuffer] mmap failed. index(%d)\n", i);
349 _fbdevVideoV4l2ClearBuffer (int fd,
350 FBDevV4l2BufType type,
351 FBDevV4l2Memory memory,
353 FBDevV4l2SrcBuffer *mem_buf)
355 struct v4l2_requestbuffers req = {0,};
357 return_val_if_fail (fd >= 0, FALSE);
359 DRVLOG ("[ClearBuffer] memory(%d) num_buf(%d) mem_buf(%p)\n",
360 num_buf, mem_buf, memory);
362 if (memory == V4L2_MEMORY_MMAP && mem_buf)
366 for (i = 0; i < num_buf; i++)
368 if (munmap (mem_buf[i].buf, mem_buf[i].size) == -1)
369 xf86DrvMsg (0, X_WARNING, "[ClearBuffer] Failed to unmap v4l2 buffer at index %d\n", i);
378 if (!fbdev_v4l2_reqbuf (fd, &req))
385 _fbdevVideoV4l2StreamOn (int fd, FBDevV4l2BufType type)
387 return_val_if_fail (fd >= 0, FALSE);
389 DRVLOG ("[StreamOn] type(%d) \n", type);
391 if (!fbdev_v4l2_streamon (fd, type))
399 _fbdevVideoV4l2StreamOff (int fd, FBDevV4l2BufType type)
401 return_val_if_fail (fd >= 0, FALSE);
403 DRVLOG ("[StreamOff] type(%d) \n", type);
405 if (!fbdev_v4l2_streamoff (fd, type))
412 _fbdevVideoV4l2Dequeue (int fd, FBDevV4l2BufType type, FBDevV4l2Memory memory)
414 struct v4l2_buffer buf = {0,};
416 return_val_if_fail (fd >= 0, -1);
422 if (!fbdev_v4l2_dequeue (fd, &buf))
425 DRVLOG ("[Dequeue] index(%d) type(%d) memory(%d)\n",
426 buf.index, type, memory);
432 _fbdevVideoV4l2Queue (int fd, FBDevV4l2BufType type, FBDevV4l2Memory memory, int index, FBDevV4l2FimcBuffer *fimc_buf)
434 struct v4l2_buffer buf = {0,};
436 return_val_if_fail (fd >= 0, -1);
443 if (memory == V4L2_MEMORY_USERPTR)
444 buf.m.userptr = (unsigned long) fimc_buf;
446 if (!fbdev_v4l2_queue (fd, &buf))
449 DRVLOG ("[Queue] index(%d) type(%d) memory(%d)\n",
450 index, type, memory);
456 _open_device (char *device)
460 return_val_if_fail (device != NULL, -1);
462 fd = open (device, O_RDWR);
465 xf86DrvMsg (0, X_ERROR, "Cannot open '%s'. fd(%d)\n", device, fd);
469 DRVLOG ("'%s' opened. fd(%d) \n", device, fd);
475 _close_device (int fd)
479 return_if_fail (fd >= 0);
484 xf86DrvMsg (0, X_ERROR, "Cannot close fd(%d)\n", fd);
488 DRVLOG ("fd(%d) closed. \n", fd);
492 _move_resize_fb (FBDevDispHandle *hdisp, int x, int y, int width, int height)
494 struct fb_var_screeninfo var;
496 return_val_if_fail (hdisp->fb_fd >= 0, FALSE);
498 DRVLOG ("[MoveResize] '%s' to (%d,%d %dx%d) \n",
499 device_infos[hdisp->index].fb, x, y, width, height);
501 if (!fbdevFbGetVarScreenInfo (hdisp->fb_fd, &var))
504 var.xres = var.xres_virtual = width;
505 var.yres = var.yres_virtual = height;
506 var.transp.length = 0;
507 var.activate = FB_ACTIVATE_FORCE;
508 if (!fbdevFbSetVarScreenInfo (hdisp->fb_fd, &var))
511 if (!fbdevFbGetFixScreenInfo (hdisp->fb_fd, &hdisp->fix))
514 if (hdisp->fix.smem_len == 0)
517 hdisp->fb_base_phy = (void*)hdisp->fix.smem_start; /* Physical address */
518 if (!hdisp->fb_base_phy)
521 hdisp->fb_base_vir = mmap (NULL, hdisp->fix.smem_len,
522 PROT_READ | PROT_WRITE, MAP_SHARED, hdisp->fb_fd, 0);
523 if (!hdisp->fb_base_vir)
526 if (!fbdevFbSetWinPosition (hdisp->fb_fd, x, y)) /* 1 : auto */
528 munmap ((void*)hdisp->fb_base_vir, hdisp->fix.smem_len);
536 _fbdevVideoV4l2EnsureStreamOff (FBDevDispHandle *hdisp)
538 if (!hdisp->status.streamon)
541 if (!_fbdevVideoV4l2StreamOff (hdisp->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT))
544 hdisp->status.streamon = FALSE;
550 _fbdevVideoV4l2OpenDevice (FBDevDispHandle *hdisp, int index, int requestbuffer)
552 if (device_infos[index].bOpened)
554 DRVLOG ("[OpenDevice, %p] Already opened : %s\n", hdisp, device_infos[index].video);
558 hdisp->video_fd = _open_device (device_infos[index].video);
559 if (hdisp->video_fd < 0)
562 if (device_infos[index].type == OUTPUT_PATH_DMA)
564 hdisp->fb_fd = _open_device (device_infos[index].fb);
565 if (hdisp->fb_fd < 0)
567 _close_device (hdisp->video_fd);
568 hdisp->video_fd = -1;
573 device_infos[index].bOpened = TRUE;
578 /* This function never failed.
579 * If failed, it means kernel has some problems.
580 * Then a device should be rebooted.
583 _fbdevVideoV4l2CloseDevice (FBDevDispHandle *hdisp)
585 if (!_fbdevVideoV4l2EnsureStreamOff (hdisp)) // We will consider this as a LCD Off case.
586 xf86DrvMsg (0, X_WARNING, "[CloseDevice, %p] Warning : Cannot stream off!! \n", hdisp);
588 if (hdisp->status.requestbuffer > 0)
590 if (hdisp->video_fd >= 0)
591 if (!_fbdevVideoV4l2ClearBuffer (hdisp->video_fd,
592 V4L2_BUF_TYPE_VIDEO_OUTPUT,
594 hdisp->status.requestbuffer,
596 xf86DrvMsg (0, X_WARNING, "[CloseDevice, %p] Warning : Cannot clear buffer!! \n", hdisp);
598 hdisp->status.requestbuffer = 0;
599 hdisp->src_buf = NULL;
602 if (hdisp->video_fd >= 0)
604 _close_device (hdisp->video_fd);
605 hdisp->video_fd = -1;
608 if (hdisp->fb_fd >= 0)
610 fbdevFbDeActivate (hdisp->fb_fd);
611 if (hdisp->fb_base_vir)
613 munmap ((void*)hdisp->fb_base_vir, hdisp->fix.smem_len);
614 hdisp->fb_base_vir = NULL;
617 _close_device (hdisp->fb_fd);
619 hdisp->fb_base_phy = NULL;
620 hdisp->fb_shown = FALSE;
623 device_infos[hdisp->index].bOpened = FALSE;
627 fbdevVideoV4l2GetHandleNums (void)
633 fbdevVideoV4l2HandleOpened (int index)
635 return_val_if_fail (index < DEVICE_NUMS, FALSE);
637 return device_infos[index].bOpened;
641 fbdevVideoV4l2OpenHandle (ScreenPtr pScreen, int index, int requestbuffer)
643 FBDevDispHandle *handle;
645 return_val_if_fail (pScreen != NULL, NULL);
646 return_val_if_fail (index < DEVICE_NUMS, NULL);
648 handle = (FBDevDispHandle*)calloc (sizeof (FBDevDispHandle), 1);
650 return_val_if_fail (handle != NULL, NULL);
652 handle->pScreen = pScreen;
653 handle->index = index;
654 handle->status.hw_rotate = -1;
655 handle->status.id = 0;
656 handle->status.cur_idx = -1;
657 handle->status.init = 0;
658 handle->memory = V4L2_MEMORY_MMAP;
659 handle->initial_dequeued_buf = requestbuffer;
660 handle->video_fd = -1;
663 if (!_fbdevVideoV4l2OpenDevice (handle, index, requestbuffer))
669 DRVLOG ("[OpenHandle, %p] Handle(%d) opened. \n", handle, index);
675 fbdevVideoV4l2CloseHandle (void *handle)
677 FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
679 return_if_fail (handle != NULL);
681 _fbdevVideoV4l2CloseDevice ((FBDevDispHandle*)handle);
683 if (hdisp->status.backup)
685 free (hdisp->status.backup);
686 hdisp->status.backup = NULL;
689 DRVLOG ("[CloseHandle, %p] Handle(%d) closed. \n", hdisp, hdisp->index);
695 fbdevVideoV4l2StreamOn (void *handle)
697 FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
700 return_val_if_fail (hdisp != NULL, FALSE);
702 hdisp->re_setting = TRUE;
704 if (!_fbdevVideoV4l2OpenDevice (hdisp, hdisp->index, hdisp->status.requestbuffer))
707 fbdevVideoV4l2SetFormat (handle,
712 hdisp->status.scn_rotate,
713 hdisp->status.hw_rotate,
716 hdisp->status.requestbuffer,
719 phy_addrs[0] = hdisp->fimcbuf.base[0];
720 phy_addrs[1] = hdisp->fimcbuf.base[1];
721 phy_addrs[2] = hdisp->fimcbuf.base[2];
723 fbdevVideoV4l2Draw (handle, hdisp->status.backup, phy_addrs);
725 if (hdisp->status.backup)
727 free (hdisp->status.backup);
728 hdisp->status.backup = NULL;
731 hdisp->re_setting = FALSE;
733 DRVLOG ("%s \n", __FUNCTION__);
739 fbdevVideoV4l2StreamOff (void *handle)
741 FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
744 return_if_fail (hdisp != NULL);
746 if (hdisp->memory == V4L2_MEMORY_MMAP)
750 if (hdisp->status.backup)
752 free (hdisp->status.backup);
753 hdisp->status.backup = NULL;
756 size = fbdevVideoQueryImageAttributes (NULL, hdisp->status.id,
757 (unsigned short*)&hdisp->status.img.width,
758 (unsigned short*)&hdisp->status.img.height,
762 hdisp->status.backup = malloc (size);
764 if (hdisp->status.backup &&
766 hdisp->src_buf[hdisp->status.queued_index].buf)
767 memcpy (hdisp->status.backup,
768 hdisp->src_buf[hdisp->status.queued_index].buf,
772 requestbuffer = hdisp->status.requestbuffer;
774 _fbdevVideoV4l2CloseDevice (hdisp);
776 hdisp->status.requestbuffer = requestbuffer;
778 DRVLOG ("%s \n", __FUNCTION__);
781 /* img->x, img->y : not used. */
783 fbdevVideoV4l2SetFormat (void *handle,
784 xRectangle *img, xRectangle *crop, xRectangle *dst,
793 FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
794 Bool src_changed = FALSE;
795 Bool dst_changed = FALSE;
796 Bool buf_changed = FALSE;
798 return_val_if_fail (handle != NULL, FALSE);
799 return_val_if_fail (img != NULL, FALSE);
800 return_val_if_fail (crop != NULL, FALSE);
801 return_val_if_fail (dst != NULL, FALSE);
803 DRVLOG ("[SetFormat, %p] try to set : img(%d,%d %dx%d) crop(%d,%d %dx%d) dst(%d,%d %dx%d) id(%x), rot(%d), flip(%d,%d) req(%d)\n", hdisp,
804 img->x, img->y, img->width, img->height,
805 crop->x, crop->y, crop->width, crop->height,
806 dst->x, dst->y, dst->width, dst->height,
807 id, hw_rotate, hflip, vflip, requestbuffer);
809 if (memcmp (&hdisp->status.img, img, sizeof (xRectangle)) ||
810 memcmp (&hdisp->status.crop, crop, sizeof (xRectangle)) ||
811 hdisp->status.id != id)
814 if (memcmp (&hdisp->status.dst, dst, sizeof (xRectangle)) ||
815 hdisp->status.hw_rotate != hw_rotate ||
816 hdisp->status.hflip != hflip ||
817 hdisp->status.vflip != vflip)
820 if (hdisp->status.requestbuffer != requestbuffer)
823 if (hdisp->status.init && (src_changed || dst_changed || buf_changed))
825 _fbdevVideoV4l2CloseDevice (hdisp);
826 _fbdevVideoV4l2OpenDevice (hdisp, hdisp->index, requestbuffer);
828 DRVLOG ("[SetFormat, %p] changed : img(%d) dst(%d) buf(%d) \n", hdisp,
829 src_changed, dst_changed, buf_changed);
831 /* After close device, below all steps should be done. */
832 src_changed = dst_changed = buf_changed = TRUE;
833 hdisp->status.init = 0;
836 if (hdisp->re_setting)
837 src_changed = dst_changed = buf_changed = TRUE;
841 fbdevVideoV4l2GetFormatInfo (id, NULL, &hdisp->pixfmt, &hdisp->memory);
843 DRVLOG ("[SetFormat, %p] id(%c%c%c%c) => pixfmt(%d) memory(%d) \n", hdisp,
844 id & 0xFF, (id & 0xFF00) >> 8, (id & 0xFF0000) >> 16, (id & 0xFF000000) >> 24,
845 hdisp->pixfmt, hdisp->memory);
848 xf86DrvMsg (0, X_WARNING, "img->width(%d) is not multiple of 16!!!\n", img->width);
850 if (!_fbdevVideoV4l2SetSrc (hdisp->video_fd, img, crop, hdisp->pixfmt))
852 xf86DrvMsg (0, X_ERROR, "[SetFormat, %p] _fbdevVideoV4l2SetSrc is failed. \n", hdisp);
856 hdisp->status.img = *img;
857 hdisp->status.crop = *crop;
858 hdisp->status.id = id;
859 hdisp->status.sync = sync;
861 hdisp->status.requestbuffer = 0;
862 hdisp->status.init = 1;
867 hdisp->status.cur_idx = 0;
868 hdisp->status.hw_rotate = hw_rotate;
869 hdisp->status.scn_rotate = scn_rotate;
870 hdisp->status.hflip = hflip;
871 hdisp->status.vflip = vflip;
872 hdisp->status.dst = *dst;
874 if (hdisp->fb_fd >= 0)
876 xRectangle fb_rect = *dst;
877 if (!_move_resize_fb (hdisp, fb_rect.x, fb_rect.y, fb_rect.width, fb_rect.height))
879 xf86DrvMsg (0, X_ERROR, "[SetFormat, %p] _move_resize_fb is failed. \n", hdisp);
884 fbdev_util_rotate_rect ((int)hdisp->pScreen->width,
885 (int)hdisp->pScreen->height,
886 0, (hw_rotate + (360 - scn_rotate)) % 360, dst);
887 if (hdisp->fb_base_phy)
889 xRectangle win_rect = {0, 0, dst->width, dst->height};
891 if (!_fbdevVideoV4l2SetDst (hdisp->video_fd, dst, &win_rect, hw_rotate, hflip, vflip, OUTPUT_PATH_DMA, (uint)hdisp->fb_base_phy))
893 xf86DrvMsg (0, X_ERROR, "[SetFormat, %p] _fbdevVideoV4l2SetDst is failed. \n", hdisp);
899 if (!_fbdevVideoV4l2SetDst (hdisp->video_fd, dst, dst, hw_rotate, hflip, vflip, OUTPUT_PATH_FIMD, 0))
901 xf86DrvMsg (0, X_ERROR, "[SetFormat, %p] _fbdevVideoV4l2SetDst is failed. \n", hdisp);
909 if (!_fbdevVideoV4l2SetBuffer (hdisp->video_fd,
910 V4L2_BUF_TYPE_VIDEO_OUTPUT,
915 xf86DrvMsg (0, X_ERROR, "[SetFormat, %p] _fbdevVideoV4l2SetBuffer is failed. \n", hdisp);
919 hdisp->status.cur_idx = 0;
920 hdisp->status.requestbuffer = requestbuffer;
921 hdisp->initial_dequeued_buf = requestbuffer;
924 if (!hdisp->status.streamon)
926 _fbdevVideoV4l2StreamOn (hdisp->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT);
927 hdisp->status.streamon = TRUE;
934 fbdevVideoV4l2SupportImages (int *count)
943 fbdevVideoV4l2Draw (void *handle, uchar *buf, uint *phy_addrs)
945 FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
948 return_val_if_fail (handle != NULL, FALSE);
949 // return_val_if_fail (phy_addrs != NULL, FALSE);
951 if (!hdisp->status.sync)
953 if (hdisp->initial_dequeued_buf > 0)
955 idx = hdisp->status.requestbuffer - hdisp->initial_dequeued_buf;
956 hdisp->initial_dequeued_buf--;
960 if ((idx = _fbdevVideoV4l2Dequeue (hdisp->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT, hdisp->memory)) < 0)
962 xf86DrvMsg (0, X_ERROR, "[Draw, %p] _fbdevVideoV4l2Dequeue is failed. \n", hdisp);
968 idx = hdisp->status.queued_index;
970 if (hdisp->memory == V4L2_MEMORY_MMAP)
972 uchar *destbuf = hdisp->src_buf[idx].buf;
975 return_val_if_fail (buf != NULL, FALSE);
977 hdisp->status.last_buffer = destbuf;
979 size = fbdevVideoQueryImageAttributes (NULL, hdisp->status.id,
980 (unsigned short*)&hdisp->status.img.width,
981 (unsigned short*)&hdisp->status.img.height,
983 memcpy (destbuf, buf, size);
986 hdisp->fimcbuf.base[0] = phy_addrs[0];
987 hdisp->fimcbuf.base[1] = phy_addrs[1];
988 hdisp->fimcbuf.base[2] = phy_addrs[2];
989 hdisp->fimcbuf.length[0] = hdisp->status.img.width * hdisp->status.img.height;
990 hdisp->fimcbuf.length[1] = hdisp->fimcbuf.length[0] >> 1;
991 hdisp->fimcbuf.length[2] = hdisp->fimcbuf.base[1] + hdisp->fimcbuf.length[1];
993 if ((idx = _fbdevVideoV4l2Queue (hdisp->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT,
994 hdisp->memory, idx, &hdisp->fimcbuf)) < 0)
996 xf86DrvMsg (0, X_ERROR, "[Draw, %p] _fbdevVideoV4l2Queue is failed. \n", hdisp);
1000 if (hdisp->status.sync)
1002 if ((idx = _fbdevVideoV4l2Dequeue (hdisp->video_fd, V4L2_BUF_TYPE_VIDEO_OUTPUT, hdisp->memory)) < 0)
1004 xf86DrvMsg (0, X_ERROR, "[Draw, %p] _fbdevVideoV4l2Dequeue is failed. \n", hdisp);
1009 if (hdisp->fb_fd >= 0 && !hdisp->fb_shown)
1011 if (!fbdevFbActivate (hdisp->fb_fd))
1013 xf86DrvMsg (0, X_ERROR, "[%s, %p] %d failed. \n", __FUNCTION__, hdisp, __LINE__);
1017 hdisp->fb_shown = TRUE;
1020 hdisp->status.queued_index = idx + 1;
1021 if (hdisp->status.queued_index > hdisp->status.requestbuffer - 1)
1022 hdisp->status.queued_index = 0;
1028 fbdevVideoV4l2GetFormatInfo (int id, int *type, uint *pixelformat, FBDevV4l2Memory *memory)
1032 for (i = 0; i < sizeof (format_infos) / sizeof (FormatInfo); i++)
1033 if (format_infos[i].id == id)
1036 *type = format_infos[i].type;
1038 *pixelformat = format_infos[i].pixelformat;
1040 *memory = format_infos[i].memory;
1047 /* img : original src size
1048 * src : real src size (cropped area inside img)
1049 * dst : real dst size
1050 * original dst size (in case that image is drawn on opened framebuffer)
1053 fbdevVideoV4l2CheckSize (void *handle, uint pixelformat,
1054 xRectangle *img, xRectangle *src, xRectangle *dst,
1055 int type, int memory)
1060 if (img->width % 16)
1061 xf86DrvMsg (0, X_WARNING, "img's width(%d) is not multiple of 16!!!\n", img->width);
1063 if (type == TYPE_YUV420 && img->height % 2)
1064 xf86DrvMsg (0, X_WARNING, "img's height(%d) is not multiple of 2!!!\n", img->height);
1066 return_val_if_fail (img->width >= 16, FALSE);
1067 return_val_if_fail (img->height >= 16, FALSE);
1073 if (type == TYPE_YUV420 || type == TYPE_YUV422)
1075 src->x = src->x & (~0x1);
1076 src->width = src->width & (~0x1);
1079 if (type == TYPE_YUV420)
1080 src->height = src->height & (~0x1);
1082 return_val_if_fail (src->width >= 16, FALSE);
1083 return_val_if_fail (src->height >= 16, FALSE);
1089 dst->width = dst->width & (~0x1);
1090 dst->height = dst->height & (~0x1);
1092 return_val_if_fail (dst->width >= 8, FALSE);
1093 return_val_if_fail (dst->height >= 8, FALSE);
1100 fbdevVideoGetFBInfo (void *handle, void **base, xRectangle *pos)
1102 FBDevDispHandle *hdisp = (FBDevDispHandle*)handle;
1108 *pos = hdisp->status.dst;
1110 *base = hdisp->fb_base_vir;