libcvd-members
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libcvd-members] libcvd Makefile.in cvd/videobuffer.h cvd/videos...


From: Edward Rosten
Subject: [libcvd-members] libcvd Makefile.in cvd/videobuffer.h cvd/videos...
Date: Thu, 28 Aug 2008 06:56:33 +0000

CVSROOT:        /cvsroot/libcvd
Module name:    libcvd
Changes by:     Edward Rosten <edrosten>        08/08/28 06:56:33

Modified files:
        .              : Makefile.in 
        cvd            : videobuffer.h videosource.h 
Added files:
        cvd            : serverpushjpegbuffer.h serverpushjpegframe.h 
        progs          : video_play_source.cc 

Log message:
        Added a new video source for http video streams from some ethernet 
cameras.
        This class does not do initiate the http transfer, it only opens a 
file.  Use
        wget and a named pipe to grab live video. It has been added to
        open_video_source
        
        Also added a very generic member to videobuffer, so that the lifetime
        of arbitrary classes can be managed by a video buffer. This allows 
        the new ServerPushJpegBuffer to manage the istream assosciated with the
        video. See open_video_source for an example of this. It will also allow
        decorator buffers to optionally manage the lifetime of the class they 
are
        decorating.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/libcvd/Makefile.in?cvsroot=libcvd&r1=1.78&r2=1.79
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd/videobuffer.h?cvsroot=libcvd&r1=1.10&r2=1.11
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd/videosource.h?cvsroot=libcvd&r1=1.11&r2=1.12
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd/serverpushjpegbuffer.h?cvsroot=libcvd&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/libcvd/cvd/serverpushjpegframe.h?cvsroot=libcvd&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/libcvd/progs/video_play_source.cc?cvsroot=libcvd&rev=1.1

Patches:
Index: Makefile.in
===================================================================
RCS file: /cvsroot/libcvd/libcvd/Makefile.in,v
retrieving revision 1.78
retrieving revision 1.79
diff -u -b -r1.78 -r1.79
--- Makefile.in 4 Jun 2008 10:26:01 -0000       1.78
+++ Makefile.in 28 Aug 2008 06:56:32 -0000      1.79
@@ -177,7 +177,7 @@
 LDFLAGS = -L. @LDFLAGS@
 LOADLIBES = @LIBS@
 
address@hidden@
address@hidden@ progs/video_play_source
 address@hidden@
 
 $(PROGS):$(soname)

Index: cvd/videobuffer.h
===================================================================
RCS file: /cvsroot/libcvd/libcvd/cvd/videobuffer.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -b -r1.10 -r1.11
--- cvd/videobuffer.h   9 May 2005 11:54:57 -0000       1.10
+++ cvd/videobuffer.h   28 Aug 2008 06:56:32 -0000      1.11
@@ -23,9 +23,34 @@
 
 #include <cvd/videoframe.h>
 #include <cvd/exceptions.h>
+#include <memory>
 
 namespace CVD {
 
+/// Base class for objects that a video buffer can 
+/// manage the lifetime of.
+class VideoBufferData
+{
+       public:
+               virtual ~VideoBufferData(){}
+};
+
+template<class T> class VideoBufferDataAuto: public VideoBufferData
+{
+       private:
+               T* data;
+
+       public:
+               VideoBufferDataAuto(T* d)
+               :data(d)
+               {}
+
+               virtual ~VideoBufferDataAuto()
+               {
+                       delete data;
+               }
+};
+
 /// Base class for objects which provide a video stream. A video 
 /// stream is a sequence of video frames (derived from VideoFrame).
 /// @param T The pixel type of the video frames
@@ -51,6 +76,12 @@
                /// \param t The frame time in seconds
                virtual void seek_to(double)
                {}
+               
+               /// Certain video buffers, especially the decorator classes, 
and buffers
+               /// such as ServerPushJpegBuffer have additional data 
+               /// with the same lifetime as the buffer. This is a tool to 
allow management of
+               /// this data.
+               std::auto_ptr<VideoBufferData> extra_data;
 };
 
 namespace Exceptions

Index: cvd/videosource.h
===================================================================
RCS file: /cvsroot/libcvd/libcvd/cvd/videosource.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -b -r1.11 -r1.12
--- cvd/videosource.h   28 Aug 2008 04:16:43 -0000      1.11
+++ cvd/videosource.h   28 Aug 2008 06:56:32 -0000      1.12
@@ -13,6 +13,7 @@
 #include <cvd/colourspaces.h>
 
 #include <cvd/diskbuffer2.h>
+#include <cvd/serverpushjpegbuffer.h>
 
 #if CVD_HAVE_FFMPEG
 #include <cvd/videofilebuffer.h>
@@ -57,6 +58,33 @@
 
     void parse(std::istream& in, VideoSource& vs);
        
+    template <class T> VideoBuffer<T>* makeJPEGStream(const std::string& 
filename)
+    {
+       using std::auto_ptr;
+       using std::ifstream;
+
+       auto_ptr<ifstream> stream(new ifstream(filename.c_str()));
+       
+       ServerPushJpegBuffer<T>* b = new ServerPushJpegBuffer<T>(*stream.get());
+       
+       auto_ptr<VideoBufferData> h(new 
VideoBufferDataAuto<ifstream>(stream.release()));
+
+       b->extra_data = h;
+       return b;
+    }
+
+    template <> inline VideoBuffer<vuy422> * makeJPEGStream(const std::string&)
+    {
+       throw VideoSourceException("DiskBuffer2 cannot handle type vuy422");
+    }
+
+    template <> inline VideoBuffer<yuv422> * makeJPEGStream(const std::string&)
+    {
+       throw VideoSourceException("DiskBuffer2 cannot handle type yuv422");
+    }
+
+
+       
 #ifdef CVD_HAVE_GLOB
     template <class T> VideoBuffer<T>* makeDiskBuffer2(const 
std::vector<std::string>& files, double fps, VideoBufferFlags::OnEndOfBuffer 
eob)
     {
@@ -145,8 +173,9 @@
 
     template <class T> VideoBuffer<T>* open_video_source(const VideoSource& vs)
     {
-       if(0)
+       if(vs.protocol == "jpegstream")
        {
+           return makeJPEGStream<T>(vs.identifier);
        }
 #if CVD_HAVE_GLOB
        else if (vs.protocol == "files") {
@@ -207,6 +236,7 @@
 #endif
        else
            throw VideoSourceException("undefined video source protocol: '" + 
vs.protocol + "'\n\t valid protocols: "
+                                      "jpegstream, "
 #if CVD_HAVE_FFMPEG
                                       "file, "
 #endif
@@ -249,7 +279,7 @@
 The url syntax is the following:
 @verbatim
 url      := protocol ':' [ '[' options ']' ] // identifier
-protocol := "files" | "file" | "v4l2" | "dc1394" | "qt"
+protocol := "files" | "file" | "v4l2" | "v4l1" | "jpegstream" | "dc1394" | "qt"
 options  := option [ ',' options ]
 option   := name [ '=' value ]
 @endverbatim
@@ -292,6 +322,19 @@
 qt:[showsettings=1]//0
 @endverbatim
 
+Open an HTTP camera. First create a named pipe from the shell, 
+and start grabbing video:
address@hidden
+mkfifo /tmp/video
+wget http//my.camera/file_representing_video -O /tmp/video
address@hidden
+then open a source with:
address@hidden
+jpegstream:///tmp/video
address@hidden
+
+
+
 Options supported by the various protocols are:
 @verbatim
 'files' protocol (DiskBuffer2):  identifier is glob pattern
@@ -303,6 +346,9 @@
        read_ahead  [= <number>] (default is 50 if specified without value)
        on_end = repeat_last | unset_pending | loop (default is repeat_last)
 
+'v4l1' protocol (V4L1Buffer): identifier is device name
+       size = vga | qvga | pal | ntsc | <width>x<height>  (default is 0x0)
+
 'v4l2' protocol (V4LBuffer): identifier is device name
        size = vga | qvga | pal | ntsc | <width>x<height>  (default vga)
        input = <number>
@@ -318,6 +364,8 @@
       size = vga | qvga | <width>x<height>  (default vga)
       showsettings = 0 | 1 (default 0)
 
+'jpegstream' protocol (ServerPushJpegBuffer): identifier is path to file
+
 @endverbatim
 
 @ingroup gVideo

Index: cvd/serverpushjpegbuffer.h
===================================================================
RCS file: cvd/serverpushjpegbuffer.h
diff -N cvd/serverpushjpegbuffer.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ cvd/serverpushjpegbuffer.h  28 Aug 2008 06:56:32 -0000      1.1
@@ -0,0 +1,140 @@
+#ifndef CVD_INC_SERVERPUSHJPEGBUFFER_H
+#define CVD_INC_SERVERPUSHJPEGBUFFER_H
+#include <cvd/localvideobuffer.h>
+#include <cvd/timer.h>
+#include <cvd/serverpushjpegframe.h>
+#include <iostream>
+
+namespace CVD
+{
+
+/// Play a server push stream as a video stream.  This is a standard used by a 
number of
+/// HTTP based security cameras. The format is as follows:
+/// @code
+/// --ImageSeparator\n
+/// Content-Type: image/jpeg\r\n
+/// Content-Length: 123456789\r\n
+/// \r\n
+/// <123456789 bytes of JPEG go here>\r\n
+/// @endcode
+/// This exact format is from the InVision IQEye series of cameras. Other 
cameras have
+/// a different image separator, and do not miss the carriage return.
+///
+/// The buffer reads a number of frames from the stream on initiation (by 
default 10),
+/// in order to flush the camera's inbuilt buffer. With some cameras, changing 
the video
+/// size does not flush the buffer, so the first few frames will be of the 
incorrect size.
+/// After flushing the buffer, the size of the first frame is taken to be the 
size of the
+/// video stream. If spurious frames arrive of a different size later, these 
will be ignored.
+///
+/// WARNING: error checking is currently very minimal. The result of failure 
will probably 
+/// result in an exception being thrown from the JPEG loader.
+///
+/// @param T The pixel type of the frames to provide (usually 
<code>CVD::Rgb<CVD::byte></code> 
+/// or <code>CVD::byte</code>. If the image files are of a different type, 
they will be automatically 
+/// converted (see @link gImageIO Image loading and saving, and format 
address@hidden).
+/// @ingroup gVideoBuffer
+template<class C> class ServerPushJpegBuffer: public LocalVideoBuffer<C>
+{
+       public:
+               ///Construct a ServerPushJpegBuffer from an istream. The 
istream 
+               ///
+               ///
+               ///@param i The stream to use for video.
+               ///@param warnings Whether to print warnings if mis-sized 
frames arrive. 
+               ///@param eat_frames Number of frames to discard on 
initialization.
+               ServerPushJpegBuffer<C>(std::istream& i, bool warnings_=0, int 
eat_frames=0)
+               :is(i),warnings(warnings_)
+               {
+                       std::string tmp;
+                       //Eat the first 10 frames because the camera sometimes 
takes a while to
+                       //crank out ones of the specified size
+                       
+                       for(int junk=0; junk< eat_frames; junk++)
+                               gimme_an_image(tmp);
+                       
+
+                       //Eat the first frame just to get the size
+                       Image<C> c = gimme_an_image(tmp);
+                       s = c.size();
+               }
+               
+               virtual ImageRef size()
+               {
+                       return s;
+               }       
+               
+               LocalVideoFrame<C>* get_frame()
+               {
+                       Image<C> c;
+                       std::string data;
+                       
+                       loop:
+                       c = gimme_an_image(data);
+
+                       if(c.size() != s)
+                       {
+                               if(warnings)
+                                       std::cerr << "ServerPushJpegBuffer: 
video frame is " << c.size() << " not " << s << std::endl;
+                               goto loop;
+                       }
+                       
+                       return new ServerPushJpegFrame<C>(get_time_of_day(), c, 
data);
+               }
+
+               void put_frame(VideoFrame<C>* f)
+               {
+                       LocalVideoFrame<C>* g = 
dynamic_cast<LocalVideoFrame<C>*>(f);
+
+                       if(g == NULL)
+                               throw 
CVD::Exceptions::VideoBuffer::BadPutFrame();
+                       else
+                               delete g;
+               }
+
+               bool frame_pending()
+               {
+                       return 1;
+               }
+
+               void seek_to(double){};
+               
+               ///This value is not currently correct.
+               double frame_rate()
+               {
+                       return 30;
+               }
+
+       private:
+               std::istream& is;
+               ImageRef s;
+               bool warnings;
+
+               Image<C> gimme_an_image(std::string& data)
+               {
+
+                       std::string line;
+                       
+                       int length;
+                       getline(is, line); //Get --ImageSeparator
+                       getline(is, line); //Get Content-Type:
+                       is >> line;        //Get Content-Length:
+                       is >> length;      //Get the actual content length
+                       getline(is, line); //Eat the rest of the line 
+                       getline(is, line); //Get the blank line
+                       
+                       data.resize(length);
+                       is.read(&data[0], length);
+
+                       std::istringstream ss(data);
+
+                       Image<C> c = img_load(ss);
+
+                       is.get();         //Eat the \r\n after the JPEG
+                       is.get();
+
+                       return c;
+               }
+};
+
+}
+#endif

Index: cvd/serverpushjpegframe.h
===================================================================
RCS file: cvd/serverpushjpegframe.h
diff -N cvd/serverpushjpegframe.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ cvd/serverpushjpegframe.h   28 Aug 2008 06:56:32 -0000      1.1
@@ -0,0 +1,36 @@
+#ifndef CVD_INC_SERVERPUSHJPEGFRAME_H
+#define CVD_INC_SERVERPUSHJPEGFRAME_H
+#include <cvd/localvideoframe.h>
+
+namespace CVD
+{
+
+template<class T> class ServerPushJpegBuffer;
+
+template<class T> class ServerPushJpegFrame: public LocalVideoFrame<T>
+{
+       friend class CVD::ServerPushJpegBuffer<T>;
+
+       public:         
+
+               /// The underlying JPEG data.
+               const std::string& jpeg() {return image_data;};
+
+       private:
+               ~ServerPushJpegFrame()
+               {
+               }
+
+               ServerPushJpegFrame(double time, CVD::Image<T>& im, const 
std::string& data)
+               :LocalVideoFrame<T>(time, im),image_data(data)
+               {
+               }       
+               
+       private:
+               std::string image_data;
+};
+
+
+};
+
+#endif

Index: progs/video_play_source.cc
===================================================================
RCS file: progs/video_play_source.cc
diff -N progs/video_play_source.cc
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ progs/video_play_source.cc  28 Aug 2008 06:56:32 -0000      1.1
@@ -0,0 +1,66 @@
+/*                       
+       This file is part of the CVD Library.
+
+       Copyright (C) 2005 The Authors
+
+       This library is free software; you can redistribute it and/or
+       modify it under the terms of the GNU Lesser General Public
+       License as published by the Free Software Foundation; either
+       version 2.1 of the License, or (at your option) any later version.
+
+       This library is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+       Lesser General Public License for more details.
+
+       You should have received a copy of the GNU Lesser General Public
+       License along with this library; if not, write to the Free Software
+       Foundation, Inc., 
+    51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+//  videoplay.C                                                            //
+//                                                                         //
+//  Test program for videofilebuffer                                       //
+//                                                                         //
+//  Paul Smith    30 April 2004                                            //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+#include <cvd/image.h>
+#include <cvd/rgb.h>
+#include <cvd/byte.h>
+#include <cvd/videodisplay.h>
+#include <cvd/gl_helpers.h>
+#include <cvd/videosource.h>
+
+using namespace std;
+using namespace CVD;
+
+int main(int argc, char* argv[])
+{
+       if(argc != 2)
+       {       
+               cerr << "Error: specify the video source\n";
+               return 1;
+       }
+       try
+       {
+               VideoBuffer<Rgb<byte> > *buffer = open_video_source<Rgb<byte> 
>(argv[1]);       
+               
+               VideoDisplay display(buffer->size());
+               
+               while(buffer->frame_pending())
+               {
+                       VideoFrame<Rgb<byte> >* frame = buffer->get_frame();
+                       glDrawPixels(*frame);
+                       buffer->put_frame(frame);
+                      glFlush();
+               }
+       }
+       catch(CVD::Exceptions::All& e)
+       {
+               cout << "Error: " << e.what << endl;
+       }
+}




reply via email to

[Prev in Thread] Current Thread [Next in Thread]