summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/decoder.cc39
-rw-r--r--client/decoder.h13
-rw-r--r--client/mainwindow.h2
-rw-r--r--client/miav_client.cc2
-rw-r--r--client/player.cc373
-rw-r--r--client/player.h15
-rw-r--r--client/xvaccelrenderer.cc23
-rw-r--r--client/xvaccelrenderer.h12
8 files changed, 87 insertions, 392 deletions
diff --git a/client/decoder.cc b/client/decoder.cc
index e181516..fd2464b 100644
--- a/client/decoder.cc
+++ b/client/decoder.cc
@@ -28,13 +28,23 @@
#include "info.h"
+#define READ_DV_FROM_FILE
+
#include "dv.h"
-//#include "dvfile.h"
+#ifdef READ_DV_FROM_FILE
+#include "dvfile.h"
+#else/* READ_DV_FROM_FILE*/
#include "dv1394.h"
+#endif/* READ_DV_FROM_FILE*/
+
+#include <QEvent>
+#include <QApplication>
-Decoder::Decoder()
+Decoder::Decoder(): semaphore(1)
{
frame = NULL;
+ running = true;
+ qApp->installEventFilter(this);
}
Decoder::~Decoder()
@@ -42,16 +52,33 @@ Decoder::~Decoder()
void Decoder::run()
{
- dv1394 reader;
+ semaphore.acquire(); // Lock the shutdown process
+#ifdef READ_DV_FROM_FILE
+ dvfile reader;
+#else/* READ_DV_FROM_FILE*/
+ dv1394 reader;
reader.connect();
+#endif/* READ_DV_FROM_FILE*/
- while(1) {
- frame = reader.readFrame();
+ while(running) {
+ frame = new Frame(reader.readFrame());
}
+ semaphore.release(); // Unlock the shutdown process
}
-unsigned char *Decoder::getFrame()
+Frame *Decoder::getFrame()
{
return frame;
}
+
+bool Decoder::eventFilter(QObject *o, QEvent *e)
+{
+ if (e->type() == QEvent::Close) {
+ running = false; // Tell the thread to stop.
+ semaphore.acquire(); // Wait for the thread to stop.
+ }
+
+ // standard event processing
+ return false;
+}
diff --git a/client/decoder.h b/client/decoder.h
index ca684ed..3a1b30f 100644
--- a/client/decoder.h
+++ b/client/decoder.h
@@ -28,19 +28,28 @@
#define __MIAV_DECODER_H__
#include <QThread>
+#include <QSemaphore>
+#include "frame.h"
class Decoder : public QThread
{
+Q_OBJECT
public:
Decoder();
~Decoder();
- unsigned char *getFrame();
+ Frame *getFrame();
void run();
+protected:
+ bool eventFilter(QObject *o, QEvent *e);
+
private:
- unsigned char *frame;
+ volatile bool running;
+ volatile bool stopped;
+ Frame *frame;
+ QSemaphore semaphore;
};
#endif/*__MIAV_DECODER_H__*/
diff --git a/client/mainwindow.h b/client/mainwindow.h
index 58edb3c..4698a2c 100644
--- a/client/mainwindow.h
+++ b/client/mainwindow.h
@@ -59,7 +59,7 @@ public:
MainWindow();
~MainWindow();
- VideoWidget *getVideo() { return video; }
+ QWidget *getVideoWidget() { return video; }
void moveEvent(QMoveEvent *event);
diff --git a/client/miav_client.cc b/client/miav_client.cc
index 376a27e..6122093 100644
--- a/client/miav_client.cc
+++ b/client/miav_client.cc
@@ -48,7 +48,7 @@ int main(int argc, char *argv[])
MainWindow mainwindow;
Decoder decoder;
- Player player(mainwindow.getVideo(), &decoder);
+ Player player(mainwindow.getVideoWidget(), &decoder);
NetworkSender sender;
decoder.start();
diff --git a/client/player.cc b/client/player.cc
index 1edf2cb..1f789b9 100644
--- a/client/player.cc
+++ b/client/player.cc
@@ -29,32 +29,23 @@
#define WIDTH 720
#define HEIGHT 576
-static unsigned char yuv_buf[WIDTH*HEIGHT*3];
+//#define COLORSPACE_YV12
+
static int num = 0;
static bool first = true;
-Player::Player(VideoWidget *w, Decoder *d)
+Player::Player(QWidget *w, Decoder *d)
{
widget = w;
decoder = d;
- render.init(widget, WIDTH, HEIGHT);//widget->getWidth(), widget->getHeight()
+ render.init(widget, WIDTH, HEIGHT);
connect(this, SIGNAL(timeout()), this, SLOT(show_frame()));
- /*
- for(int x = 1; x < 720; x++)
- for(int y = 1; y < 576; y++) {
- yuv[x + y * 576 * 1] = x % 720 * 255;
- yuv[x + y * 576 * 2] = y % 576 * 255;
- yuv[x + y * 576 * 3] = (unsigned char)x % y;
- }
- */
-
dvdecoder = dv_decoder_new(FALSE/*this value is unused*/, FALSE, FALSE);
- dvdecoder->quality = DV_QUALITY_BEST;
-
- // reader.connect();
+ dv_set_quality(dvdecoder, DV_QUALITY_COLOR | DV_QUALITY_AC_1);
+ //dv_set_quality(dvdecoder, DV_QUALITY_BEST);
}
Player::~Player()
@@ -64,26 +55,26 @@ Player::~Player()
void Player::show_frame()
{
- uint8_t *frame;
+ Frame *frame;
fprintf(stderr, "Frame!%d\n", num++);
frame = decoder->getFrame();
-
if(!frame) return;
+
if(first) {
#ifdef COLORSPACE_YV12
- yuv[0] = yuv_buf;
+ yuv[0] = (unsigned char*)render.xvimage->data;
yuv[1] = (unsigned char*)yuv[0] + (WIDTH * HEIGHT);
yuv[2] = (unsigned char*)yuv[1] + (WIDTH * HEIGHT / 4);
pitches[0] = WIDTH;
pitches[1] = WIDTH / 2;
pitches[2] = WIDTH / 2;
#else
- yuv[0] = yuv_buf;
+ yuv[0] = (unsigned char*)render.getDisplayData(); // Decode directly to the XVideo buffer
pitches[0] = WIDTH * 2;
#endif
- dv_parse_header(dvdecoder, frame);
+ dv_parse_header(dvdecoder, frame->data);
//dv_parse_packs(decoder, frame->data); // Not needed anyway!
dvdecoder->system = e_dv_system_625_50; // PAL lines, PAL framerate
@@ -94,347 +85,13 @@ void Player::show_frame()
}
dv_decode_full_frame(dvdecoder,
- frame,
+ frame->data,
e_dv_color_yuv,
yuv,
pitches);
- render.width = widget->getWidth();
- render.height = widget->getHeight();
- render.display(yuv_buf, WIDTH, HEIGHT);//widget->width(), widget->height());
-
-}
-
-
-
-
-
-
-#if 0
-
-#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/extensions/Xvlib.h>
-#include <X11/extensions/XShm.h>
-
-
-extern "C" {
-//extern int XShmQueryExtension(Display*);
-//extern int XShmGetEventBase(Display*);
-extern XvImage *XvShmCreateImage(Display*, XvPortID, int, char*, int, int, XShmSegmentInfo*);
-}
-
-Player::Player(VideoWidget *w)
-{
- widget = w;
-
- // dpy = XOpenDisplay(NULL); // Get the deafult display
-
- 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: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;
- }
-
-
- //
- // Find port
- //
- unsigned int adaptors;
- XvAdaptorInfo *ai;
-
- fprintf(stderr, "XvQueryAdaptors\n");
- switch(XvQueryAdaptors(display, drawable, &adaptors, &ai)) {
- 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;
- }
-
- /*
- typedef struct {
- XvPortID base_id;
- unsigned long num_ports;
- char type;
- char *name;
- unsigned long num_formats;
- XvFormat *formats;
- unsigned long num_adaptors;
- } XvAdaptorInfo;
- */
- if(adaptors == 0) {
- MIaV::info->error("Unable to find any adapters.");
- return;
- }
+ render.width = widget->width();
+ render.height = widget->height();
+ render.display(WIDTH, HEIGHT);
- /* check adaptors */
- port = 0;
- 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*);
-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,
- IPC_CREAT | 0777);
- // yuv_shminfo.shmaddr = shmat(yuv_shminfo.shmid, 0, 0);
- yuv_shminfo.readOnly = False;
-
- 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);
- int swidth = 720;
- int sheight = 576;
- int lxoff = 0;
- int lyoff = 0;
- int lwidth = swidth;
- int lheight = sheight;
-
- XvShmPutImage(display, port,
- drawable, gc,
- xv_image,
- 0, 0,
- swidth, sheight,
- lxoff, lyoff,
- lwidth, lheight,
- True);
-
- */
-
-// From:
-// http://cvs.sourceforge.net/viewcvs.py/libmpeg2/MSSG/display_x11.c?rev=1.2
-//#if 0
-#ifdef HAVE_XV
-xv_port = 0;
-if (Success == XvQueryExtension(mydisplay,&ver,&rel,&req,&ev,&err)) {
- /* check for Xvideo support */
- if (Success != XvQueryAdaptors(mydisplay,DefaultRootWindow(mydisplay),
- &adaptors,&ai)) {
- fprintf(stderr,"Xv: XvQueryAdaptors failed");
- exit(1);
- }
- /* check adaptors */
- for (i = 0; i < adaptors; i++) {
- if ((ai[i].type & XvInputMask) &&
- (ai[i].type & XvImageMask) &&
- (xv_port == 0)) {
- xv_port = ai[i].base_id;
- }
- }
- /* check image formats */
- if (xv_port != 0) {
- fo = XvListImageFormats(mydisplay, xv_port, (int*)&formats);
- for(i = 0; i < formats; i++) {
- fprintf(stderr, "Xvideo image format: 0x%x (%4.4s) %s\n",
- fo[i].id,
- (char*)&fo[i].id,
- (fo[i].format == XvPacked) ? "packed" : "planar");
- if (0x32315659 == fo[i].id) {
- xv_format = fo[i].id;
- break;
- }
- }
- if (i == formats)
- /* no matching image format not */
- xv_port = 0;
- }
- if (xv_port != 0) {
- fprintf(stderr,"using Xvideo port %d for hw scaling\n",
- xv_port);
-
- /* allocate XvImages. FIXME: no error checking, without
- * mit-shm this will bomb... */
- xvimage1 = XvShmCreateImage(mydisplay, xv_port, xv_format, 0,
- image_width, image_height,
- &Shminfo1);
- Shminfo1.shmid = shmget(IPC_PRIVATE, xvimage1->data_size,
- IPC_CREAT | 0777);
- Shminfo1.shmaddr = (char *) shmat(Shminfo1.shmid, 0, 0);
- Shminfo1.readOnly = False;
- xvimage1->data = Shminfo1.shmaddr;
- XShmAttach(mydisplay, &Shminfo1);
- XSync(mydisplay, False);
- shmctl(Shminfo1.shmid, IPC_RMID, 0);
-
- /* so we can do grayscale while testing... */
- memset(xvimage1->data,128,xvimage1->data_size);
-
- /* catch window resizes */
- XSelectInput(mydisplay, mywindow, StructureNotifyMask);
- win_width = image_width;
- win_height = image_height;
-
- /* all done (I hope...) */
- X_already_started++;
- return;
- }
}
-#endif/* HAVE_XV */
-#endif/* 0 */
diff --git a/client/player.h b/client/player.h
index d3db533..824e2c0 100644
--- a/client/player.h
+++ b/client/player.h
@@ -37,6 +37,7 @@
#include <X11/Xlib.h>
#include <X11/extensions/Xvlib.h>
+//#include "libdv_wrapper.h"
// Use libdv
#include <libdv/dv.h>
#include <libdv/dv_types.h>
@@ -47,29 +48,23 @@ class Player : public QTimer
{
Q_OBJECT
public:
- Player(VideoWidget *widget, Decoder *decoder);
+ Player(QWidget *widget, Decoder *decoder);
~Player();
public slots:
void show_frame();
private:
- // dv1394 reader;
-
int pitches[3];
unsigned char* yuv[3];
+ // LibDVWrapper dvdecoder;
dv_decoder_t *dvdecoder;
+
Decoder *decoder;
- VideoWidget *widget;
+ QWidget *widget;
XvAccelRender render;
-
- Display *display;
- Drawable drawable;
- GC gc;
- XvPortID port;
- XGCValues values;
};
#endif/*__MIAV_PLAYER_H__*/
diff --git a/client/xvaccelrenderer.cc b/client/xvaccelrenderer.cc
index f030642..7de4510 100644
--- a/client/xvaccelrenderer.cc
+++ b/client/xvaccelrenderer.cc
@@ -1,3 +1,4 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/***************************************************************************
gui_xv.cpp - description
-------------------
@@ -28,10 +29,6 @@
// Use this define for verbose output
#define VERBOSE_XV
-
-//static uint8_t GUI_XvSync(void);
-
-
//________________Wrapper around Xv_______________
XvAccelRender::XvAccelRender( void )
{
@@ -57,14 +54,19 @@ uint8_t XvAccelRender::end(void)
return 1;
}
-uint8_t XvAccelRender::display(uint8_t *ptr, uint32_t w, uint32_t h)
+char *XvAccelRender::getDisplayData()
+{
+ if(xvimage) return xvimage->data;
+ else return NULL;
+}
+
+uint8_t XvAccelRender::display(uint32_t w, uint32_t h)
{
- return GUI_XvDisplay(ptr, w, h);
+ return GUI_XvDisplay(w, h);
}
//________________Wrapper around Xv_______________
-//static uint8_t GUI_XvExpose( void );
//
// Free all ressources allocated by xv
//
@@ -92,7 +94,7 @@ void XvAccelRender::GUI_XvEnd( void )
}
//------------------------------------
-uint8_t XvAccelRender::GUI_XvDisplay(uint8_t * src, uint32_t w, uint32_t h)
+uint8_t XvAccelRender::GUI_XvDisplay(uint32_t w, uint32_t h)
{
if (xvimage)
@@ -102,7 +104,10 @@ uint8_t XvAccelRender::GUI_XvDisplay(uint8_t * src, uint32_t w, uint32_t h)
// for YV12, 4 bits for Y 4 bits for u, 4 bits for v
// total 1.5*
- memcpy(xvimage->data, src, (w*h*3)>>1);
+
+ // memcpy(xvimage->data, src, (w*h*3)>>1);
+ //memcpy(xvimage->data, src, (w*h*4)>>1); // We decodee directly to the buffer, so we don't need to copy it.
+
XLockDisplay (xv_display);
// And display it !
#if 1
diff --git a/client/xvaccelrenderer.h b/client/xvaccelrenderer.h
index 69745d6..3d70e91 100644
--- a/client/xvaccelrenderer.h
+++ b/client/xvaccelrenderer.h
@@ -1,4 +1,4 @@
-/* -*- mode: c++ -*- */
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
#ifndef __XVACCELRENDERER_H__
#define __XVACCELRENDERER_H__
@@ -31,16 +31,18 @@ public:
XvAccelRender();
uint8_t init(QWidget *window, uint32_t w, uint32_t h);
uint8_t end(void);
- uint8_t display(uint8_t *ptr, uint32_t w, uint32_t h);
+ uint8_t display(uint32_t w, uint32_t h);
unsigned int width, height;
+ char *getDisplayData();
+
private:
unsigned int xv_port;
uint32_t xv_format;
Display *xv_display;
- XvImage *xvimage;
- GC xv_gc;
+ XvImage *xvimage;
+ GC xv_gc;
XGCValues xv_xgc;
Window xv_win;
XShmSegmentInfo Shminfo;
@@ -48,7 +50,7 @@ private:
uint8_t GUI_XvList(Display *dis, uint32_t port, uint32_t * fmt);
uint8_t GUI_XvInit(QWidget *window, uint32_t w, uint32_t h);
void GUI_XvEnd();
- uint8_t GUI_XvDisplay(uint8_t * src, uint32_t w, uint32_t h);
+ uint8_t GUI_XvDisplay(uint32_t w, uint32_t h);
};
#endif/*__XVACCELRENDERER_H__*/