00001
00003 #include "OverlayWidget.h"
00004
00005 #include <stdlib.h>
00006 #include <stdio.h>
00007 #include <unistd.h>
00008
00009 #define X_UYVY 0x59565955
00010
00011 OverlayWidget::OverlayWidget(QWidget *parent) : QWidget(parent) {
00012 initXv();
00013
00014
00015 QWidget::setBackgroundRole(QPalette::Window);
00016 QWidget::setAutoFillBackground(true);
00017 QPalette overlayPalette = QWidget::palette();
00018 overlayPalette.setColor
00019 (QPalette::Window,
00020 colorKey());
00021 QWidget::setPalette(overlayPalette);
00022 }
00023
00024
00025 void OverlayWidget::initXv() {
00026 unsigned int nAdaptors;
00027 XvAdaptorInfo *ai;
00028
00029 dpy = x11Info().display();
00030
00031 XvQueryAdaptors(dpy,
00032 winId(),
00033 &nAdaptors, &ai);
00034
00035 if (nAdaptors > 0) {
00036
00037 xv_port = ai[0].base_id;
00038 printf("Using port %d\n", xv_port);
00039 XvFreeAdaptorInfo(ai);
00040 } else {
00041 printf("Error: no available xv ports\n");
00042 xv_port = -1;
00043 return;
00044 }
00045
00046 gc = XCreateGC(dpy, winId(), 0, 0);
00047
00048 yuv_image = NULL;
00049
00050
00051
00052
00053
00054
00055
00056 QColor key = colorKey();
00057 int val = ((key.red() >> 3) << 11) | ((key.green() >> 2) << 5) | ((key.blue() >> 3));
00058 XvSetPortAttribute(dpy, xv_port, XInternAtom(dpy, "XV_COLORKEY", True), val);
00059 }
00060
00061 void OverlayWidget::checkImageSize() {
00062 if (yuv_image == NULL ||
00063 width() != yuv_image->width ||
00064 height() != yuv_image->height) {
00065
00066 printf("Creating new image\n"); fflush(stdout);
00067
00068 if (yuv_image) XFree(yuv_image);
00069
00070 yuv_image = XvShmCreateImage(dpy, xv_port, X_UYVY, 0, width(), height(), &yuv_shminfo);
00071
00072 if (!yuv_image) {
00073 printf("XvShmCreateImage returned NULL\n");
00074 return;
00075 }
00076 yuv_shminfo.shmid = shmget(IPC_PRIVATE, yuv_image->data_size, IPC_CREAT | 0777);
00077 yuv_shminfo.shmaddr = yuv_image->data = (char *)shmat(yuv_shminfo.shmid, 0, 0);
00078 yuv_shminfo.readOnly = False;
00079
00080
00081
00082 framebuffer_ = FCam::Image(width(), height(),
00083 FCam::UYVY,
00084 (unsigned char*)yuv_image->data);
00085
00086 if (!XShmAttach(dpy, &yuv_shminfo)) {
00087 printf("XShmAttach failed !\n");
00088 return;
00089 }
00090
00091 }
00092 }
00093
00094 void OverlayWidget::paintEvent(QPaintEvent *) {
00095 if (!yuv_image) return;
00096
00097 XvShmPutImage(dpy, xv_port, winId(), gc, yuv_image,
00098 0, 0, yuv_image->width, yuv_image->height,
00099 0, 0, width(), height(), false);
00100 }
00101
00102 FCam::Image OverlayWidget::framebuffer() {
00103 checkImageSize();
00104 return framebuffer_;
00105 }