videoCapture.h

Engine/source/gfx/video/videoCapture.h

More...

Classes:

class

Video capture interface class.

class

Abstract video encoder class.

class

Abstract frame grabber class implementation and initalization depends on video device.

Public Defines

define
REGISTER_VIDEO_ENCODER(ClassName, EncoderName)    * EncoderFactory##EncoderName() { return  ClassName(); } \
   struct __VidEncReg##EncoderName { __VidEncReg##EncoderName() { ( #EncoderName, &EncoderFactory##EncoderName ); } }; \
   static __VidEncReg##EncoderName _gEncoderRegistration;

VIDEO ENCODER REGISTRATION MACRO.

define
VIDCAP() <>::instance()

Returns the VideoCapture singleton.

Public Typedefs

VideoEncoderFactoryFn )()

Detailed Description

Public Defines

REGISTER_VIDEO_ENCODER(ClassName, EncoderName)    * EncoderFactory##EncoderName() { return  ClassName(); } \
   struct __VidEncReg##EncoderName { __VidEncReg##EncoderName() { ( #EncoderName, &EncoderFactory##EncoderName ); } }; \
   static __VidEncReg##EncoderName _gEncoderRegistration;

VIDEO ENCODER REGISTRATION MACRO.

VIDCAP() <>::instance()

Returns the VideoCapture singleton.

Public Typedefs

typedef VideoEncoder *(* VideoEncoderFactoryFn )()
  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _VIDEOCAPTURE_H_
 25#define _VIDEOCAPTURE_H_
 26
 27#ifndef _TSINGLETON_H_
 28#include "core/util/tSingleton.h"
 29#endif
 30
 31#ifndef _TVECTOR_H_
 32#include "core/util/tVector.h"
 33#endif
 34
 35#ifndef _TORQUE_STRING_H_
 36#include "core/util/str.h"
 37#endif
 38
 39#ifndef _GFXTEXTUREHANDLE_H_
 40#include "gfx/gfxTextureHandle.h"
 41#endif
 42
 43#ifndef _MPOINT2_H_
 44#include "math/mPoint2.h"
 45#endif
 46
 47#ifndef _THREADSAFEDEQUE_H_
 48#include "platform/threads/threadSafeDeque.h"
 49#endif
 50
 51
 52class GuiCanvas;
 53class VideoFrameGrabber;
 54class VideoEncoder;
 55class GBitmap;
 56
 57typedef VideoEncoder* (*VideoEncoderFactoryFn)();
 58
 59
 60/// Abstract frame grabber class
 61/// implementation and initalization depends on video device
 62class VideoFrameGrabber
 63{
 64   friend class VideoCapture;
 65protected:
 66   Point2I mResolution; // The resolution used to capture the back buffer (scaling will be used)
 67   Vector<GBitmap*> mBitmapList; //List of bitmaps created from backbuffer captures
 68
 69   /// Sets the output frame resolution
 70   void setOutResolution( const Point2I& res ) { mResolution = res; }   
 71
 72   /// Pushes a fresh bitmap into our list
 73   void pushNewBitmap( GBitmap* bitmap ) { mBitmapList.push_back(bitmap); }
 74
 75   /// Returns one captured bitmap. Returns NULL if there are no more bitmaps.
 76   GBitmap* fetchBitmap();
 77
 78   /// Texture event callback
 79   void _onTextureEvent(GFXTexCallbackCode code);
 80   
 81   /// Captures the current backbuffer. If the last capture wasn't made into a bitmap, it will be overriden.   
 82   virtual void captureBackBuffer() = 0;
 83
 84   /// Starts converting the last backbuffer capture to a bitmap
 85   /// Depending on the VideoFrameGrabber implementation, this may not produce a bitmap right away.
 86   virtual void makeBitmap() = 0;
 87
 88   /// Releases internal textures
 89   virtual void releaseTextures() {};
 90
 91public:
 92   VideoFrameGrabber();
 93   virtual ~VideoFrameGrabber();
 94};
 95
 96
 97/// Video capture interface class
 98class VideoCapture
 99{   
100private:
101   struct EncoderFactory {
102      const char* name;
103      VideoEncoderFactoryFn factory;      
104   };
105
106   /// List of encoder factory functions
107   static Vector<EncoderFactory> mEncoderFactoryFnList;
108
109   // The frame position of the latest backbuffer capture
110   F32 mCapturedFramePos;
111
112   /// Our current video encoder
113   VideoEncoder* mEncoder;
114
115   /// Our video frame grabber
116   VideoFrameGrabber* mFrameGrabber;
117
118   /// The canvas we're recording from
119   GuiCanvas* mCanvas;
120
121   /// True if we're recording
122   bool mIsRecording;
123
124   /// Time when we captured the previous frame
125   U32 mVideoCaptureStartTime;
126
127   /// Frame to be captured next
128   F32 mNextFramePosition;
129
130   /// The framerate we'll use to record
131   F32 mFrameRate;
132
133   /// The per-frame time (in milliseconds)
134   F32 mMsPerFrame;   
135
136   /// Accumulated error when converting the per-frame-time to integer
137   /// this is used to dither the value and keep overall time advancing
138   /// correct
139   F32 mMsPerFrameError;
140
141   /// Name of the encoder we'll be using
142   String mEncoderName;
143
144   /// The video output resolution
145   Point2I mResolution;
146
147   /// Output filename
148   String mFileName;
149
150   /// Tur if we're waiting for a canvas to bre created before capturing
151   bool mWaitingForCanvas;
152
153   /// Vector with bitmaps to delete
154   Vector< GBitmap*> mBitmapDeleteList;
155
156   /// Initializes our encoder
157   bool initEncoder( const char* name );   
158
159   /// Deletes processed bitmaps
160   void deleteProcessedBitmaps();
161      
162public:
163   VideoCapture();
164      
165   /// Start a video capture session
166   void begin( GuiCanvas* canvas );
167
168   /// Captures a new frame
169   void capture();
170   
171   /// Ends a video capture
172   void end();
173
174   /// Sets the output filename
175   void setFilename( const char* filename ) { mFileName = filename; }
176
177   /// Sets the encoder we'll use
178   void setEncoderName( const char* encoder ) { mEncoderName = encoder; }
179
180   /// Sets the framerate
181   void setFramerate( F32 fps ) { mFrameRate = fps; }
182
183   /// Sets the video output resolution
184   void setResolution(const Point2I& res) { mResolution = res; }
185
186   /// Returns true if we're capturing
187   bool isRecording() { return mIsRecording; }
188
189   /// Returns the number of milliseconds per frame
190   S32 getMsPerFrame();
191
192   /// Sets the video farme grabber (cannot record without one).
193   void setFrameGrabber( VideoFrameGrabber* grabber ) { mFrameGrabber = grabber; }
194
195   /// This will make the video capture begin capturing 
196   /// as soon as a GuiCanvas is created
197   void waitForCanvas() { mWaitingForCanvas = true; }
198   bool isWaitingForCanvas() { return mWaitingForCanvas; }
199
200   /// Registers an encoder
201   static void registerEncoder( const char* name, VideoEncoderFactoryFn factoryFn );    
202
203   // For ManagedSingleton.
204   static const char* getSingletonName() { return "VideoCapture"; }   
205};
206
207
208
209/// Abstract video encoder class
210class VideoEncoder
211{
212protected:
213   // Video output file path
214   String mPath;
215
216   // Video framerate
217   F32 mFramerate;
218
219   // Video resolution
220   Point2I mResolution;
221
222   // List with bitmaps which are done encoding
223   ThreadSafeDeque< GBitmap*> mProcessedBitmaps;
224public:
225   virtual ~VideoEncoder() { }
226
227   // Stores an encoded bitmap to be dealt with later
228   void pushProcessedBitmap( GBitmap* bitmap );
229      
230public:
231   /// Sets the file the encoder will write to
232   void setFile( const char* path );
233
234   /// Sets the framerate (and fixes it if its invalid)
235   virtual void setFramerate( F32* framerate ) { mFramerate = *framerate; }
236
237   /// Sets the output resolution (and fixes it if its invalid)
238   virtual void setResolution( Point2I* resolution ) { mResolution = *resolution; }
239
240   /// Begins accepting frames for encoding
241   virtual bool begin() = 0;
242
243   /// Pushes a new frame into the video stream
244   virtual bool pushFrame( GBitmap * bitmap ) = 0;
245
246   /// Finishes the encoding and closes the video
247   virtual bool end() = 0;
248
249   /// Returns an already encoded bitmap. Video capture will get these and manage their deletion
250   GBitmap* getProcessedBitmap();
251};
252
253/// Returns the VideoCapture singleton.
254#define VIDCAP ManagedSingleton<VideoCapture>::instance()
255
256//-----------------------------------------
257/// VIDEO ENCODER REGISTRATION MACRO
258#define REGISTER_VIDEO_ENCODER(ClassName, EncoderName)   \
259   VideoEncoder* EncoderFactory##EncoderName() { return new ClassName(); } \
260   struct __VidEncReg##EncoderName { __VidEncReg##EncoderName() { VideoCapture::registerEncoder( #EncoderName, &EncoderFactory##EncoderName ); } }; \
261   static __VidEncReg##EncoderName _gEncoderRegistration;
262
263#endif // !_VIDEOCAPTURE_H_
264