diff options
| author | deva <deva> | 2006-04-10 13:04:31 +0000 | 
|---|---|---|
| committer | deva <deva> | 2006-04-10 13:04:31 +0000 | 
| commit | 582bcd19d6a58c266f5453961c87acf72fae5353 (patch) | |
| tree | 5ee3bdc1726d833da65efab320e5eabfcb802e51 | |
| parent | 46b3c21f079a10e1ed072976d355a8026bcb7580 (diff) | |
*** empty log message ***
| -rw-r--r-- | client/decoder.cc | 39 | ||||
| -rw-r--r-- | client/decoder.h | 13 | ||||
| -rw-r--r-- | client/mainwindow.h | 2 | ||||
| -rw-r--r-- | client/miav_client.cc | 2 | ||||
| -rw-r--r-- | client/player.cc | 373 | ||||
| -rw-r--r-- | client/player.h | 15 | ||||
| -rw-r--r-- | client/xvaccelrenderer.cc | 23 | ||||
| -rw-r--r-- | client/xvaccelrenderer.h | 12 | ||||
| -rw-r--r-- | lib/Makefile.am | 2 | ||||
| -rw-r--r-- | lib/frame.cc | 3 | ||||
| -rw-r--r-- | lib/frame.h | 7 | 
11 files changed, 98 insertions, 393 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__*/ diff --git a/lib/Makefile.am b/lib/Makefile.am index f2293d1..6f01ef1 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -10,6 +10,7 @@ libmiav_la_SOURCES = \  	info.cc \  	info_simple.cc \  	jpeg_mem_dest.cc \ +	libdv_wrapper.cc \  	miav_config.cc \  	mutex.cc \  	network.cc \ @@ -32,6 +33,7 @@ EXTRA_DIST = \  	info.h \  	info_simple.h \  	jpeg_mem_dest.h \ +	libdv_wrapper.h \  	miav_config.h \  	mutex.h \  	network.h \ diff --git a/lib/frame.cc b/lib/frame.cc index 568c46b..caab521 100644 --- a/lib/frame.cc +++ b/lib/frame.cc @@ -34,11 +34,14 @@ Frame::Frame(unsigned char *d, int sz)  {    if(sz) data = new unsigned char[sz];    if(sz && d) memcpy(data, d, sz); +  if(sz == 0 && d) data = d;    size = sz;    number = 0;    memset(timecode, 0, sizeof(timecode));    endOfFrameStream = false; + +  usage = 0;  }  Frame::~Frame() diff --git a/lib/frame.h b/lib/frame.h index 988f460..66c2ce7 100644 --- a/lib/frame.h +++ b/lib/frame.h @@ -28,12 +28,15 @@  #ifndef __FRAME_H__  #define __FRAME_H__ +#define START_USE_FRAME(x) x->usage++ +#define STOP_USE_FRAME(x) if(--x->usage == 0) delete x; x = NULL +  // Definition of vector  #include <vector>  class Frame {  public: -  Frame(unsigned char *d, int sz); +  Frame(unsigned char *d, int sz = 0);    ~Frame();    unsigned char *data; @@ -51,6 +54,8 @@ public:    char timecode[12];    bool endOfFrameStream; + +  int usage;  };  typedef std::vector< Frame* > FrameVector; | 
