Index: /trunk/MagicSoft/Cosy/Makefile
===================================================================
--- /trunk/MagicSoft/Cosy/Makefile	(revision 8844)
+++ /trunk/MagicSoft/Cosy/Makefile	(revision 8845)
@@ -25,5 +25,5 @@
 
 INCLUDES = -I. -Imain -Imars -Ibase -Icandrv -Iincl -Ivideodev \
- 	   -Igui -Imvideo -Itcpip -Itpoint
+ 	   -Igui -Itcpip -Itpoint
 
 #
@@ -48,5 +48,4 @@
           tcpip \
           videodev \
-          mvideo \
           tpoint
 
Index: /trunk/MagicSoft/Cosy/videodev/MVideo.cc
===================================================================
--- /trunk/MagicSoft/Cosy/videodev/MVideo.cc	(revision 8845)
+++ /trunk/MagicSoft/Cosy/videodev/MVideo.cc	(revision 8845)
@@ -0,0 +1,553 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz 1/2008 <mailto:tbretz@astro.uni-wuerzburg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2008
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// MVideo
+//
+// Interface to Video4Linux at a simple level
+//
+/////////////////////////////////////////////////////////////////////////////
+#include "MVideo.h"
+
+// iostream
+#include <iostream>
+
+// open
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <unistd.h>    // usleep
+#include <errno.h>     // errno
+#include <sys/mman.h>  // mmap
+#include <sys/ioctl.h> // ioctl
+
+#include <TString.h>
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+using namespace std;
+
+//ClassImp(MVideo);
+
+// -------------------------------------------------------------
+//
+// Constructor. Specify the device (e.g. "/dev/video") to be used
+//
+MVideo::MVideo(const char *path) : fPath(path), fFileDesc(-1), fMapBuffer(0)
+{
+    Reset();
+}
+
+// -------------------------------------------------------------
+//
+// Internal function to reset the descriptors of the device
+//
+void MVideo::Reset()
+{
+    memset(&fCaps,    0, sizeof(fCaps));
+    memset(&fChannel, 0, sizeof(fChannel));
+    memset(&fBuffer,  0, sizeof(fBuffer));
+
+    fFileDesc = -1;
+    fMapBuffer = 0;
+    fChannel.channel = -1;
+}
+
+// -------------------------------------------------------------
+//
+// Mapper around ioctl for easier access to the device
+//
+int MVideo::Ioctl(int req, void *opt, bool allowirq) const
+{
+    if (fFileDesc<0)
+    {
+        gLog << err << "ERROR - Ioctl: Device " << fPath << " not open." << endl;
+        return -1;
+    }
+
+    while (1)
+    {
+        // FIXME: This call is a possible source for a hangup
+        const int rc = ioctl(fFileDesc, req, opt);
+        if (rc>=0)
+            return rc;
+
+        // errno== 4: Interrupted system call (e.g. by alarm())
+        // errno==16: Device or resource busy
+        if (errno==4 || errno==16)
+        {
+            if (!allowirq && errno==4)
+                return -4;
+
+            gLog << err << "ERROR - MVideo::Ioctl -ioctl returned rc=" << rc << " '";
+            gLog << strerror(errno) << "' (errno = " << errno << ")" << endl;
+            usleep(10);
+            continue;
+        }
+
+        gLog << err << "ERROR - MVideo::Ioctl " << hex << req << ": errno=" << dec << errno << " - ";
+        gLog << strerror(errno) << " (rc=" << rc << ")" << endl;
+        return rc;
+    }
+    return -1;
+}
+
+// -------------------------------------------------------------
+//
+// Read the capabilities of the device
+//
+Bool_t MVideo::GetCapabilities()
+{
+    return Ioctl(VIDIOCGCAP, &fCaps)!=-1;
+}
+
+// -------------------------------------------------------------
+//
+// Read the properties of the device
+//
+Bool_t MVideo::GetProperties()
+{
+    return Ioctl(VIDIOCGPICT, &fProp)!=-1;
+}
+
+// -------------------------------------------------------------
+//
+// Open channel ch of the device
+//
+Bool_t MVideo::Open(Int_t ch)
+{
+    Bool_t rc = Init(ch);
+    if (!rc)
+        Close();
+    return rc;
+}
+
+// -------------------------------------------------------------
+//
+// Open a channel of the device and retriev all necessary
+// informations from the driver. Initialize the shared
+// memory. Other access methods are not supported yet.
+//
+Bool_t MVideo::Init(Int_t channel)
+{
+    if (IsOpen())
+    {
+        gLog << warn << "WARNING - Device " << fPath << " already open." << endl;
+        return kTRUE;
+    }
+
+    gLog << inf << "Opening " << fPath << "..." << flush;
+    do
+    {
+        fFileDesc = open(fPath, O_RDWR);
+        usleep(1);
+    }
+    while (errno==19 && fFileDesc==-1);
+
+    if (fFileDesc == -1)
+    {
+        gLog << err << "ERROR!" << endl;
+        return kFALSE;
+    }
+
+    gLog << "done (" << fFileDesc << ")." << endl;
+
+    // Close device on exit
+    if (fcntl(fFileDesc, F_SETFD, FD_CLOEXEC)<0)
+    {
+        gLog << err << "ERROR - Call to fnctl (F_SETFD, FD_CLOEXEC) failed." << endl;
+        return kFALSE;
+    }
+
+    if (!GetCapabilities())
+    {
+        gLog << err << "ERROR - Getting device capabilities failed." << endl;
+        return kFALSE;
+    }
+
+    if (!SetChannel(channel))
+        return kFALSE;
+
+    if (!GetProperties())
+    {
+        gLog << err << "ERROR - Couldn't get picture properties." << endl;
+        return kFALSE;
+    }
+
+    // get mmap grab buffer info
+    if (Ioctl(VIDIOCGMBUF, &fBuffer)==-1)
+    {
+        gLog << err << "ERROR - Couldn't get info about memory map buffer." << endl;
+        return kFALSE;
+    }
+
+    // map file (device) into memory
+    fMapBuffer = (char*)mmap(0, fBuffer.size, PROT_READ|PROT_WRITE, MAP_SHARED, fFileDesc, 0);
+    if (fMapBuffer == (void*)-1)
+    {
+        gLog << err << "ERROR - Couldn't map device buffer into memory." << endl;
+        fMapBuffer = 0;
+        return kFALSE;
+    }
+
+    Print();
+
+    return kTRUE;
+}
+
+// -------------------------------------------------------------
+//
+// Close device. Free the shared memory
+//
+Int_t MVideo::Close()
+{
+    //    if (!IsOpen())
+    //        return kTRUE;
+
+    Bool_t rc = kTRUE;
+
+    gLog << inf << "Closing " << fPath << " (" << fFileDesc << ")... " << flush;
+    if (fFileDesc != -1)
+    {
+        if (close(fFileDesc)<0)
+        {
+            gLog << err << "ERROR!" << endl;
+            rc = kFALSE;
+        }
+        fFileDesc = -1;
+    }
+    gLog << "done." << endl;
+
+    // unmap device memory
+    if (fMapBuffer)
+        munmap(fMapBuffer, fBuffer.size);
+
+    Reset();
+
+    return rc;
+}
+
+// -------------------------------------------------------------
+//
+// Instruct hardware to start capture into framebuffer frame
+//
+Bool_t MVideo::CaptureStart(unsigned int frame) const
+{
+    struct video_mmap gb =
+    {
+        frame%fBuffer.frames,            // frame
+        fCaps.maxheight, fCaps.maxwidth, // height, width
+        VIDEO_PALETTE_RGB24              // palette
+    };
+
+    //
+    // capture frame
+    //
+    if (Ioctl(VIDIOCMCAPTURE, &gb) != -1)
+        return kTRUE;
+
+    if (errno == EAGAIN)
+        gLog << err << "ERROR - Couldn't start capturing frame " << frame << " - unable to sync." << endl;
+
+    return kFALSE;
+}
+
+// -------------------------------------------------------------
+//
+// Wait until hardware has finished capture into framebuffer frame
+//
+Int_t MVideo::CaptureWait(unsigned int frame, char **ptr) const
+{
+    frame %= fBuffer.frames;
+
+    *ptr = NULL;
+
+    const int SYNC_TIMEOUT = 1;
+
+    alarm(SYNC_TIMEOUT);
+    const Int_t rc = Ioctl(VIDIOCSYNC, &frame, false);
+    if (rc==-4)
+    {
+        //cout << "ERROR - Waiting for frame " << frame << " timed out." << endl;
+        return kSKIP;
+    }
+    alarm(0);
+
+    if (rc==-1)
+    {
+        gLog << err << "ERROR - Waiting for captured frame failed." << endl;
+        return kFALSE;
+    }
+
+    *ptr = fMapBuffer+fBuffer.offsets[frame];
+
+    return kTRUE;
+}
+
+// -------------------------------------------------------------
+//
+// Change the channel of a priviously opened device
+//
+Bool_t MVideo::SetChannel(Int_t chan)
+{
+    if (fChannel.channel==chan)
+        return kTRUE;
+
+    if (chan<0 || chan>=fCaps.channels)
+    {
+        gLog << err << "ERROR - Set channel " << chan << " out of range." << endl;
+        return kFALSE;
+    }
+
+    // Switch to channel
+    struct video_channel ch = { chan, "", 0, 0, 0, 0 };
+    if (Ioctl(VIDIOCSCHAN, &ch)==-1)
+    {
+        gLog << err << "ERROR - Couldn't switch to channel " << chan << "." << endl;
+        gLog << "        You might need a bttv version > 0.5.13" << endl;
+        return kFALSE;
+    }
+
+    // Get information about channel
+    if (Ioctl(VIDIOCGCHAN, &ch)==-1)
+    {
+        gLog << err << "ERROR - Getting information for channel " << chan << " failed." << endl;
+        return kFALSE;
+    }
+
+    memcpy(&fChannel, &ch, sizeof(fChannel));
+
+    return kTRUE;
+}
+
+// -------------------------------------------------------------
+//
+// Has the device capture capabilities?
+//
+Bool_t MVideo::CanCapture() const
+{
+    return fCaps.type&VID_TYPE_CAPTURE;
+}
+
+// -------------------------------------------------------------
+//
+// Returns the number of frame buffers which can be used
+//
+Int_t MVideo::GetNumBuffers() const
+{
+    return fBuffer.frames;
+}
+
+// -------------------------------------------------------------
+//
+// Maximum width of the frame which can be captured
+//
+Int_t MVideo::GetWidth() const
+{
+    return fCaps.maxwidth;
+}
+
+// -------------------------------------------------------------
+//
+// Maximum height of the frame which can be captured
+//
+Int_t MVideo::GetHeight() const
+{
+    return fCaps.maxheight;
+}
+
+// -------------------------------------------------------------
+//
+// Return the device type as string
+//
+TString MVideo::GetDevType(int type) const
+{
+    TString rc;
+    if (CanCapture())
+        rc += " capture";
+    if (type&VID_TYPE_TUNER)
+        rc += " tuner";
+    if (type&VID_TYPE_TELETEXT)
+        rc += " teletext";
+    if (type&VID_TYPE_OVERLAY)
+        rc += " overlay";
+    if (type&VID_TYPE_CHROMAKEY)
+        rc += " chromakey";
+    if (type&VID_TYPE_CLIPPING)
+        rc += " clipping";
+    if (type&VID_TYPE_FRAMERAM)
+        rc += " frameram";
+    if (type&VID_TYPE_SCALES)
+        rc += " scales";
+    if (type&VID_TYPE_MONOCHROME)
+        rc += " monochrom";
+    if (type&VID_TYPE_SUBCAPTURE)
+        rc += " subcapature";
+    return rc;
+}
+
+// -------------------------------------------------------------
+//
+// Return the channel flags as string
+//
+TString MVideo::GetChannelFlags(Int_t flags) const
+{
+    TString rc = "video";
+    if (flags&VIDEO_VC_TUNER)
+        rc += " tuner";
+    if (flags&VIDEO_VC_AUDIO)
+        rc += " audio";
+    return rc;
+}
+
+// -------------------------------------------------------------
+//
+// Return the channel type as string
+//
+TString MVideo::GetChannelType(Int_t type) const
+{
+    if (type&VIDEO_TYPE_TV)
+        return "TV";
+    if (type&VIDEO_TYPE_CAMERA)
+        return "camera";
+    return "unknown";
+}
+
+// -------------------------------------------------------------
+//
+// Return the palette pal as string
+//
+TString MVideo::GetPalette(Int_t pal) const
+{
+    if (pal&VIDEO_PALETTE_GREY)
+        return "Linear intensity grey scale";
+    if (pal&VIDEO_PALETTE_HI240)
+        return "BT848 8-bit color cube";
+    if (pal&VIDEO_PALETTE_RGB565)
+        return "RGB565 packed into 16-bit words";
+    if (pal&VIDEO_PALETTE_RGB555)
+        return "RGB555 packed into 16-bit words, top bit undefined";
+    if (pal&VIDEO_PALETTE_RGB24)
+        return "RGB888 packed into 24-bit words";
+    if (pal&VIDEO_PALETTE_RGB32)
+        return "RGB888 packed into the low three bytes of 32-bit words. Top bits undefined.";
+    if (pal&VIDEO_PALETTE_YUV422)
+        return "Video style YUV422 - 8-bit packed, 4-bit Y, 2-bits U, 2-bits V";
+    if (pal&VIDEO_PALETTE_YUYV)
+        return "YUYV";
+    if (pal&VIDEO_PALETTE_UYVY)
+        return "UYVY";
+    if (pal&VIDEO_PALETTE_YUV420)
+        return "YUV420";
+    if (pal&VIDEO_PALETTE_YUV411)
+        return "YUV411";
+    if (pal&VIDEO_PALETTE_RAW)
+        return "Raw capture (Bt848)";
+    if (pal&VIDEO_PALETTE_YUV422P)
+        return "YUV 4:2:2 planar";
+    if (pal&VIDEO_PALETTE_YUV411P)
+        return "YUV 4:1:1 planar";
+
+    return "unknown";
+}
+
+// -------------------------------------------------------------
+//
+// Print informations about the device, the capabilities, the
+// channel and all available information
+//
+void MVideo::Print() const
+{
+    gLog << all;
+
+    gLog << "Device " << fPath << " " << (IsOpen()?"open":"closed") << "." << endl;
+
+    if (!IsOpen())
+        return;
+
+    gLog  << " - Name:       " << fCaps.name << endl;
+    gLog  << " - DevType:   "  << GetDevType(fCaps.type) << endl;
+    gLog  << " - Channels:   " << fCaps.channels << endl;
+    gLog  << " - Audios:     " << fCaps.audios << endl;
+    gLog  << " - Size:       ";
+    gLog  << fCaps.minwidth << "x" << fCaps.minheight << " to ";
+    gLog  << fCaps.maxwidth << "x" << fCaps.maxheight << endl;
+    gLog  << endl;
+    if (fChannel.channel>=0)
+    {
+        gLog  << " - Channel:    " << fChannel.channel << " (" << fChannel.name << ")" << endl;
+        gLog  << " - IsA:        " << GetChannelType(fChannel.type) << " with " << GetChannelFlags(fChannel.flags) << endl;
+        //if (fChannel.flags&VIDEO_VC_NORM)
+        gLog  << " - Norm:       " << fChannel.norm << endl;
+        gLog  << endl;
+    }
+    gLog  << " - Brightness: " << fProp.brightness << endl;
+    gLog  << " - Hue:        " << fProp.hue << endl;
+    gLog  << " - Color:      " << fProp.colour << endl;
+    gLog  << " - Contrast:   " << fProp.contrast << endl;
+    gLog  << " - Whiteness:  " << fProp.whiteness << endl;
+    gLog  << " - Depth:      " << fProp.depth << endl;
+    gLog  << " - Palette:    " << GetPalette(fProp.palette) << " (" << fProp.palette << ")" << endl;
+    gLog  << endl;
+
+    gLog  << " - BufferSize: 0x" << hex << fBuffer.size << " (" << dec << fBuffer.frames << " frames)" << endl;
+    gLog  << " - Offsets:   " << hex;
+    for (int i=0; i<fBuffer.frames; i++)
+        gLog  << " 0x" << fBuffer.offsets[i];
+    gLog  << dec << endl;
+}
+
+/*
+void MVideo::SetPicPar(int bright, int hue, int contrast)
+{
+    struct video_picture pict;
+
+    Ioctl(VIDIOCGPICT, &pict);  // get
+
+    if (contrast != -1)
+        pict.contrast = contrast;
+
+    if (bright != -1)
+        pict.brightness = bright;
+
+    if (hue != -1)
+	pict.hue = hue;
+
+    Ioctl(VIDIOCSPICT, &pict);  //set
+}
+
+void MVideo::GetPicPar(int *bright, int *hue, int *contrast)
+{
+    struct video_picture pict;
+
+    Ioctl(VIDIOCGPICT, &pict);   // get
+
+    *contrast = pict.contrast;
+    *bright   = pict.brightness;
+    *hue      = pict.hue;
+}
+*/
Index: /trunk/MagicSoft/Cosy/videodev/MVideo.h
===================================================================
--- /trunk/MagicSoft/Cosy/videodev/MVideo.h	(revision 8845)
+++ /trunk/MagicSoft/Cosy/videodev/MVideo.h	(revision 8845)
@@ -0,0 +1,77 @@
+#ifndef MARS_MVideo
+#define MARS_MVideo
+
+#ifndef MAGIC_MAGIC
+#include "MAGIC.h"
+#endif
+
+#ifndef __CINT__
+#ifndef __LINUX_VIDEODEV_H
+#include "videodev.h" // video4linux
+#endif
+#endif
+
+class MVideo
+{
+private:
+    TString fPath; // Device path
+
+    int fFileDesc; // File descriptor
+
+    char *fMapBuffer;
+
+protected:
+    struct video_capability fCaps;      // Device capabilities
+    struct video_channel    fChannel;   // Channel information
+    struct video_mbuf       fBuffer;    // Buffer information
+    struct video_picture    fProp;      // Picture properties
+
+private:
+    int Ioctl(int req, void *opt, bool allowirq=true) const;
+
+    void Reset();
+
+    Bool_t GetCapabilities();
+    Bool_t GetProperties();
+    Bool_t Init(Int_t channel);
+
+    // Conversion functions
+    TString GetDevType(int type) const;
+    TString GetChannelFlags(Int_t flags) const;
+    TString GetChannelType(Int_t type) const;
+    TString GetPalette(Int_t pal) const;
+
+public:
+    MVideo(const char *path="/dev/video");
+    virtual ~MVideo() { Close(); }
+
+    // Getter
+    Bool_t IsOpen() const { return fFileDesc>0 && fMapBuffer; }
+    Bool_t CanCapture() const;
+    Int_t  GetNumBuffers() const;
+
+    Int_t  GetWidth() const;
+    Int_t  GetHeight() const;
+
+    // Control
+    Bool_t Open(Int_t channel=0);
+    Int_t  Close();
+
+    Bool_t SetChannel(Int_t chan);
+
+    // Image capture
+    Bool_t CaptureStart(unsigned int frame) const;
+    Int_t  CaptureWait(unsigned int frame, char **ptr) const;
+
+    // Support
+    void Print() const;
+
+    // hardware features
+    //void SetPicPar(int  bright, int  hue, int  contrast);
+    //void GetPicPar(int *bright, int *hue, int *contrast);
+
+    //ClassDef(MVideo, 0) // Interface to Video4Linux at a simple level
+
+};
+
+#endif
Index: /trunk/MagicSoft/Cosy/videodev/Makefile
===================================================================
--- /trunk/MagicSoft/Cosy/videodev/Makefile	(revision 8844)
+++ /trunk/MagicSoft/Cosy/videodev/Makefile	(revision 8845)
@@ -10,5 +10,5 @@
 include ../Makefile.conf.general
 
-INCLUDES = -I. -I.. -I../incl -I../base -I../caos -I/usr/X11R6/include -I../mars -I../mvideo
+INCLUDES = -I. -I.. -I../incl -I../base -I../caos -I/usr/X11R6/include -I../mars
 
 CINT     = Videodev
@@ -21,5 +21,6 @@
            PixGetter.cc \
 	   FilterLed.cc \
-           Writer.cc 
+           Writer.cc \
+	   MVideo.cc
 
 ############################################################
