summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/Makefile.am3
-rw-r--r--client/mainwindow.cc11
-rw-r--r--client/mainwindow.h2
-rw-r--r--client/player.cc199
-rw-r--r--client/player.h7
-rw-r--r--client/videowidget.cc59
-rw-r--r--client/videowidget.h18
-rw-r--r--client/yuv_draw.h3
8 files changed, 249 insertions, 53 deletions
diff --git a/client/Makefile.am b/client/Makefile.am
index 7d170fe..b0b3ad8 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -47,7 +47,8 @@ EXTRA_DIST = \
miav_client_LDADD := $(shell ../tools/MocList o ) \
../lib/libmiav.la \
$(SDL_LIBS) \
- $(QT_LDADD)
+ $(QT_LDADD) \
+ -lXv
miav_client_MOC = $(shell ../tools/MocList cc )
diff --git a/client/mainwindow.cc b/client/mainwindow.cc
index 57f1929..cab6189 100644
--- a/client/mainwindow.cc
+++ b/client/mainwindow.cc
@@ -35,6 +35,7 @@
#include "historywidget.h"
#include <QX11Info>
+#include <QMoveEvent>
QPushButton *MainWindow::createButton(char* icon)
{
@@ -48,8 +49,9 @@ QPushButton *MainWindow::createButton(char* icon)
pixmap = pixmap.scaled(w,h, aspect, Qt::SmoothTransformation);
+
QPushButton *btn = new QPushButton();
- btn->setIconSize(pixmap.size());
+ btn->setIconSize(QSize(50,50));
btn->setIcon(pixmap);
return btn;
@@ -166,3 +168,10 @@ void MainWindow::freeze_clicked()
void MainWindow::mute_clicked()
{
}
+
+// A hack to ensure we draw the video in the right place
+void MainWindow::moveEvent(QMoveEvent *event)
+{
+ QMoveEvent evt(video->pos(),video->pos());
+ video->moveEvent(&evt);
+}
diff --git a/client/mainwindow.h b/client/mainwindow.h
index 9332b0d..58edb3c 100644
--- a/client/mainwindow.h
+++ b/client/mainwindow.h
@@ -61,6 +61,8 @@ public:
VideoWidget *getVideo() { return video; }
+ void moveEvent(QMoveEvent *event);
+
public slots:
void cpr_clicked();
void clear_clicked();
diff --git a/client/player.cc b/client/player.cc
index c891941..f44842c 100644
--- a/client/player.cc
+++ b/client/player.cc
@@ -26,49 +26,79 @@
*/
#include "player.h"
+#define DBG(x) fprintf(stderr, x)
+
#include "info.h"
#include <QX11Info>
#define DV_FOURCC_YV12 0x32315659 /* 4:2:0 Planar mode: Y + V + U (3 planes) */
#define DV_FOURCC_YUY2 0x32595559 /* 4:2:2 Packed mode: Y0+U0+Y1+V0 (1 plane) */
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/extensions/Xv.h>
#include <X11/extensions/Xvlib.h>
#include <X11/extensions/XShm.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-Player::Player(VideoWidget *v)
+
+extern "C" {
+//extern int XShmQueryExtension(Display*);
+//extern int XShmGetEventBase(Display*);
+extern XvImage *XvShmCreateImage(Display*, XvPortID, int, char*, int, int, XShmSegmentInfo*);
+}
+
+Player::Player(VideoWidget *w)
{
- video = v;
+ widget = w;
// dpy = XOpenDisplay(NULL); // Get the deafult display
- display = video->x11Info().display();
- drawable = video->winId();
- gc = XCreateGC(display, drawable, 0, 0);
+ display = widget->x11Info().display();
+ drawable = widget->winId();
+ fprintf(stderr, "XCreateGC\n");
+ gc = XCreateGC(display, drawable, 0, &values);
+
+ /*
+ switch(gc) {
+ case BadAlloc:
+ MIaV::info->error("The server failed to allocate the requested resource or server memory.");
+ break;
+ case BadDrawable:
+ MIaV::info->error("A value for a Drawable argument does not name a defined Window or Pixmap.");
+ break;
+
+ case BadFont:
+ MIaV::info->error("A value for a Font or GContext argument does not name a defined Font.");
+ break;
+
+ case BadMatch:
+ MIaV::info->error("An InputOnly window is used as a Drawable.");
+ break;
+
+ case BadMatch:
+ MIaV::info->error("Some argument or pair of arguments has the correct type and range but fails to match in some other way required by the request.");
+ break;
+
+ case BadPixmap:
+ MIaV::info->error("A value for a Pixmap argument does not name a defined Pixmap.");
+ break;
+
+ case BadValue:
+ MIaV::info->error("Some numeric value falls outside the range of values accepted by the request. Unless a \
+specific range is specified for an argument, the full range defined by the argument's type is \
+accepted. Any argument defined as a set of alternatives can generate this error.");
+ break;
+ }
+ */
//
// Check version
//
unsigned int version, release;
unsigned int request_base, event_base, error_base;
+ fprintf(stderr, "XvQueryExtension\n");
switch(XvQueryExtension(display, &version, &release, &request_base, &event_base, &error_base)) {
- case Success:
- MIaV::info->info("Returned if XvQueryExtension(3X) completed successfully.");
- break;
-
- case XvBadExtension:
- MIaV::info->info("Returned if the Xv video extension is not available for the named display.");
- break;
-
- case XvBadAlloc:
- MIaV::info->info("Returned if XvQueryExtension(3X) failed to allocate memory to process the request.");
- break;
+ case Success:DBG("[-]Returned if XvQueryExtension(3X) completed successfully.");break;
+ case XvBadExtension:DBG("[E]Returned if the Xv video extension is not available for the named display.");break;
+ case XvBadAlloc:DBG("[E]Returned if XvQueryExtension(3X) failed to allocate memory to process the request.");break;
}
@@ -78,18 +108,11 @@ Player::Player(VideoWidget *v)
unsigned int adaptors;
XvAdaptorInfo *ai;
+ fprintf(stderr, "XvQueryAdaptors\n");
switch(XvQueryAdaptors(display, drawable, &adaptors, &ai)) {
- case Success:
- MIaV::info->info("Returned if XvQueryAdaptors(3X) completed successfully.");
- break;
-
- case XvBadExtension:
- MIaV::info->info("Returned if the Xv video extension is not available for the named display.");
- break;
-
- case XvBadAlloc:
- MIaV::info->info("Returned if XvQueryAdaptors(3X) failed to allocate memory to process the request.");
- break;
+ case Success:DBG("[-]Returned if XvQueryAdaptors(3X) completed successfully.");break;
+ case XvBadExtension:DBG("[E]Returned if the Xv video extension is not available for the named display.");break;
+ case XvBadAlloc:DBG("[E]Returned if XvQueryAdaptors(3X) failed to allocate memory to process the request.");break;
}
/*
@@ -113,27 +136,121 @@ Player::Player(VideoWidget *v)
for (unsigned int i = 0; i < adaptors; i++) {
if ((ai[i].type & XvInputMask) &&
(ai[i].type & XvImageMask) &&
+ (ai[i].type & XvOutputMask) &&
(port == 0)) {
port = ai[i].base_id;
}
}
+ fprintf(stderr, "XvGrabPort\n");
if(port == 0) {
MIaV::info->error("Unable to find suitable port.");
return;
} else {
MIaV::info->info("Using port %d.", port);
}
+
+ fprintf(stderr, "Using XVideo port: %d\n", port);
+
+ port=62;
+
+ switch(XvGrabPort(display, port, CurrentTime)) {
+ case Success:DBG("[-]Returned if XvGrabPort(3X) completed successfully.");break;
+ case XvInvalidTime:DBG("[E]Returned if requested time is older than the current port time.");break;
+ case XvAlreadyGrabbed:DBG("[E]Returned if the port is already grabbed by another client.");break;
+ case XvBadExtension:DBG("[E]Returned if the Xv extension is unavailable.");break;
+ case XvBadAlloc:DBG("[E]Returned if XvGrabPort(3X) failed to allocate memory to process the request.");break;
+ }
+
}
Player::~Player()
{
+ fprintf(stderr, "XFreeGC\n");
+ XvUngrabPort(display, port, CurrentTime);
+ XFreeGC(display, gc);
//XCloseDisplay(dpy); // Close the Display
}
-extern XvImage *XvShmCreateImage(Display*, XvPortID, int, char*, int, int, XShmSegmentInfo*);
+//extern XvImage *XvShmCreateImage(Display*, XvPortID, int, char*, int, int, XShmSegmentInfo*);
void Player::run()
{
+ while(1) {
+ XShmSegmentInfo yuv_shminfo;
+ static char pixels[720*576*4][4];
+ XvImage* xv_image = XvShmCreateImage(display, port,
+ DV_FOURCC_YV12, //DV_FOURCC_YUY2
+ pixels[0],
+ widget->getWidth(), widget->getHeight(),// dv_dpy->width, dv_dpy->height,
+ &yuv_shminfo);
+
+ XvShmPutImage(display, port,
+ drawable, gc,
+ xv_image,
+ 0, 0,
+ widget->getWidth(), widget->getHeight(),
+ widget->getX(), widget->getY(),
+ widget->getWidth(), widget->getHeight(),
+ True);
+ // XFlush(display);
+ sleep(1);
+ }
+ /*
+ int cnt = 100;
+ while(cnt--) {
+ sleep(1);
+ fprintf(stderr, "XvPutStill(%d,%d,%d,%d)\n",widget->getX(),widget->getY(),widget->getWidth(), widget->getHeight());
+ switch(XvPutStill(display, port, drawable, gc,
+ widget->getX(),widget->getY(),widget->getWidth(), widget->getHeight(),
+ widget->getX(),widget->getY(),widget->getWidth(), widget->getHeight())) {
+ // case Success:
+ // Yeah!
+ //break;
+ case XvBadExtension:
+ MIaV::info->error("Returned if the Xv extension is unavailable.");
+ break;
+ case XvBadAlloc:
+ MIaV::info->error("Returned if XvGetStill(3X) failed to allocate memory to process the request.");
+ break;
+ case XvBadPort:
+ MIaV::info->error("Generated if the requested port does not exist.");
+ break;
+ case BadDrawable:
+ MIaV::info->error("Generated if the requested drawable does not exist.");
+ break;
+ case BadGC:
+ MIaV::info->error("Generated if the requested graphics context does not exist.");
+ break;
+ case BadAlloc:
+ MIaV::info->error("Generated if there were insufficient resources to process the request.");
+ break;
+ }
+
+ // fprintf(stderr, "XFlush\n");
+ XFlush(display);
+ }
+ */
+
+
+}
+
+
+
+/*
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/extensions/Xv.h>
+#include <X11/extensions/Xvlib.h>
+#include <X11/extensions/XShm.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+*/
+ /*
+ XvImage* ximage=XCreateImage(display, visual, 32, ZPixmap, 0,
+ xw->virtualscreen, xw->width, xw->height, 32,
+ xw->width*xw->pixelsize);
+
XShmSegmentInfo yuv_shminfo;
yuv_shminfo.shmid = shmget(IPC_PRIVATE,
720*576*4, //yuv_image->data_size,
@@ -143,10 +260,10 @@ void Player::run()
char pixels[720*576*4][4];
XvImage* xv_image = XvShmCreateImage(display, port,
- DV_FOURCC_YUY2, // DV_FOURCC_YV12
- pixels[0],
- 720, 576,// dv_dpy->width, dv_dpy->height,
- &yuv_shminfo);
+ DV_FOURCC_YUY2, // DV_FOURCC_YV12
+ pixels[0],
+ 720, 576,// dv_dpy->width, dv_dpy->height,
+ &yuv_shminfo);
int swidth = 720;
int sheight = 576;
int lxoff = 0;
@@ -163,11 +280,7 @@ void Player::run()
lwidth, lheight,
True);
- XFlush(display);
-
- // XvPutStill(display, port, drawable, gc, 0, 0, 320, 200, 0, 0, 320, 200);
-}
-
+ */
// From:
// http://cvs.sourceforge.net/viewcvs.py/libmpeg2/MSSG/display_x11.c?rev=1.2
diff --git a/client/player.h b/client/player.h
index abceb9d..24920a5 100644
--- a/client/player.h
+++ b/client/player.h
@@ -37,18 +37,19 @@
class Player : public QThread
{
public:
- Player(VideoWidget *video);
+ Player(VideoWidget *widget);
~Player();
void run();
private:
+ VideoWidget *widget;
+
Display *display;
Drawable drawable;
GC gc;
XvPortID port;
-
- VideoWidget *video;
+ XGCValues values;
};
#endif/*__MIAV_PLAYER_H__*/
diff --git a/client/videowidget.cc b/client/videowidget.cc
index cc81ead..a007df8 100644
--- a/client/videowidget.cc
+++ b/client/videowidget.cc
@@ -27,7 +27,10 @@
#include "videowidget.h"
#include "miav_config.h"
-VideoWidget::VideoWidget()
+#include <QMoveEvent>
+#include <QResizeEvent>
+
+VideoWidget::VideoWidget() : QWidget()
{
// A welltested hack to force SDL to draw in the QWidget
@@ -39,8 +42,8 @@ VideoWidget::VideoWidget()
palette.setColor(backgroundRole(), Qt::blue);
setPalette(palette);
- setLineWidth(10);
- setFrameStyle(QFrame::Raised);
+ // setLineWidth(10);
+ // setFrameStyle(QFrame::Raised);
}
@@ -67,3 +70,53 @@ void VideoWidget::mouseReleaseEvent(QMouseEvent *event)
}
*/
}
+
+void VideoWidget::moveEvent(QMoveEvent *event)
+{
+ mutex.lock();
+ myposition = mapToGlobal(event->pos());
+ mutex.unlock();
+}
+
+void VideoWidget::resizeEvent(QResizeEvent *event)
+{
+ mutex.lock();
+ mysize = event->size();
+ mutex.unlock();
+}
+
+int VideoWidget::getX()
+{
+ int val;
+ mutex.lock();
+ val = myposition.x();
+ mutex.unlock();
+ return val;
+}
+
+int VideoWidget::getY()
+{
+ int val;
+ mutex.lock();
+ val = myposition.y();
+ mutex.unlock();
+ return val;
+}
+
+int VideoWidget::getWidth()
+{
+ int val;
+ mutex.lock();
+ val = mysize.width();
+ mutex.unlock();
+ return val;
+}
+
+int VideoWidget::getHeight()
+{
+ int val;
+ mutex.lock();
+ val = mysize.height();
+ mutex.unlock();
+ return val;
+}
diff --git a/client/videowidget.h b/client/videowidget.h
index 1647e28..d5e77bc 100644
--- a/client/videowidget.h
+++ b/client/videowidget.h
@@ -27,17 +27,31 @@
#ifndef __VIDEOWIDGET_H__
#define __VIDEOWIDGET_H__
-#include <QTextEdit>
+//#include <QTextEdit>
+#include <QWidget>
#include <QPixmap>
+#include <QMutex>
-class VideoWidget : public QTextEdit
+class VideoWidget : public QWidget
{
Q_OBJECT
public:
VideoWidget();
~VideoWidget();
+ int getX();
+ int getY();
+ int getWidth();
+ int getHeight();
+
void mouseReleaseEvent(QMouseEvent *event);
+ void moveEvent(QMoveEvent *event);
+ void resizeEvent(QResizeEvent *event);
+
+private:
+ QSize mysize;
+ QPoint myposition;
+ QMutex mutex;
};
#endif /* __VIDEOWIDGET_H__ */
diff --git a/client/yuv_draw.h b/client/yuv_draw.h
index 7bbc99b..9f704e3 100644
--- a/client/yuv_draw.h
+++ b/client/yuv_draw.h
@@ -36,6 +36,9 @@
#define ICON_HEIGHT 48
#define ICON_WIDTH 48
+// Take a look at this...
+// http://softpixel.com/~cwright/programming/colorspace/yuv/
+
class YUVDraw {
public:
YUVDraw();