diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/Makefile.am | 3 | ||||
-rw-r--r-- | client/mainwindow.cc | 11 | ||||
-rw-r--r-- | client/mainwindow.h | 2 | ||||
-rw-r--r-- | client/player.cc | 199 | ||||
-rw-r--r-- | client/player.h | 7 | ||||
-rw-r--r-- | client/videowidget.cc | 59 | ||||
-rw-r--r-- | client/videowidget.h | 18 | ||||
-rw-r--r-- | client/yuv_draw.h | 3 |
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(); |