[Top][All Lists]
[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;
+ }
+}
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libcvd-members] libcvd Makefile.in cvd/videobuffer.h cvd/videos...,
Edward Rosten <=