1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkVideoSource.h
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 /**
16  * @class   vtkVideoSource
17  * @brief   Superclass of video input devices for VTK
18  *
19  * vtkVideoSource is a superclass for video input interfaces for VTK.
20  * The goal is to provide an interface which is very similar to the
21  * interface of a VCR, where the 'tape' is an internal frame buffer
22  * capable of holding a preset number of video frames.  Specialized
23  * versions of this class record input from various video input sources.
24  * This base class records input from a noise source.
25  * @warning
26  * You must call the ReleaseSystemResources() method before the application
27  * exits.  Otherwise the application might hang while trying to exit.
28  * @sa
29  * vtkWin32VideoSource vtkMILVideoSource
30 */
31 
32 #ifndef vtkVideoSource_h
33 #define vtkVideoSource_h
34 
35 #include "vtkIOVideoModule.h" // For export macro
36 #include "vtkImageAlgorithm.h"
37 
38 class vtkTimerLog;
39 class vtkCriticalSection;
40 class vtkMultiThreader;
41 class vtkScalarsToColors;
42 
43 class VTKIOVIDEO_EXPORT vtkVideoSource : public vtkImageAlgorithm
44 {
45 public:
46   static vtkVideoSource *New();
47   vtkTypeMacro(vtkVideoSource,vtkImageAlgorithm);
48   void PrintSelf(ostream& os, vtkIndent indent) override;
49 
50   /**
51    * Record incoming video at the specified FrameRate.  The recording
52    * continues indefinitely until Stop() is called.
53    */
54   virtual void Record();
55 
56   /**
57    * Play through the 'tape' sequentially at the specified frame rate.
58    * If you have just finished Recoding, you should call Rewind() first.
59    */
60   virtual void Play();
61 
62   /**
63    * Stop recording or playing.
64    */
65   virtual void Stop();
66 
67   /**
68    * Rewind to the frame with the earliest timestamp.  Record operations
69    * will start on the following frame, therefore if you want to re-record
70    * over this frame you must call Seek(-1) before calling Grab() or Record().
71    */
72   virtual void Rewind();
73 
74   /**
75    * FastForward to the last frame that was recorded (i.e. to the frame
76    * that has the most recent timestamp).
77    */
78   virtual void FastForward();
79 
80   /**
81    * Seek forwards or backwards by the specified number of frames
82    * (positive is forward, negative is backward).
83    */
84   virtual void Seek(int n);
85 
86   /**
87    * Grab a single video frame.
88    */
89   virtual void Grab();
90 
91   //@{
92   /**
93    * Are we in record mode? (record mode and play mode are mutually
94    * exclusive).
95    */
96   vtkGetMacro(Recording,int);
97   //@}
98 
99   //@{
100   /**
101    * Are we in play mode? (record mode and play mode are mutually
102    * exclusive).
103    */
104   vtkGetMacro(Playing,int);
105   //@}
106 
107   //@{
108   /**
109    * Set the full-frame size.  This must be an allowed size for the device,
110    * the device may either refuse a request for an illegal frame size or
111    * automatically choose a new frame size.
112    * The default is usually 320x240x1, but can be device specific.
113    * The 'depth' should always be 1 (unless you have a device that
114    * can handle 3D acquisition).
115    */
116   virtual void SetFrameSize(int x, int y, int z);
SetFrameSize(int dim[3])117   virtual void SetFrameSize(int dim[3]) {
118     this->SetFrameSize(dim[0], dim[1], dim[2]); };
119   vtkGetVector3Macro(FrameSize,int);
120   //@}
121 
122   //@{
123   /**
124    * Request a particular frame rate (default 30 frames per second).
125    */
126   virtual void SetFrameRate(float rate);
127   vtkGetMacro(FrameRate,float);
128   //@}
129 
130   //@{
131   /**
132    * Set the output format.  This must be appropriate for device,
133    * usually only VTK_LUMINANCE, VTK_RGB, and VTK_RGBA are supported.
134    */
135   virtual void SetOutputFormat(int format);
SetOutputFormatToLuminance()136   void SetOutputFormatToLuminance() { this->SetOutputFormat(VTK_LUMINANCE); };
SetOutputFormatToRGB()137   void SetOutputFormatToRGB() { this->SetOutputFormat(VTK_RGB); };
SetOutputFormatToRGBA()138   void SetOutputFormatToRGBA() { this->SetOutputFormat(VTK_RGBA); };
139   vtkGetMacro(OutputFormat,int);
140   //@}
141 
142   //@{
143   /**
144    * Set size of the frame buffer, i.e. the number of frames that
145    * the 'tape' can store.
146    */
147   virtual void SetFrameBufferSize(int FrameBufferSize);
148   vtkGetMacro(FrameBufferSize,int);
149   //@}
150 
151   //@{
152   /**
153    * Set the number of frames to copy to the output on each execute.
154    * The frames will be concatenated along the Z dimension, with the
155    * most recent frame first.
156    * Default: 1
157    */
158   vtkSetMacro(NumberOfOutputFrames,int);
159   vtkGetMacro(NumberOfOutputFrames,int);
160   //@}
161 
162   //@{
163   /**
164    * Set whether to automatically advance the buffer before each grab.
165    * Default: on
166    */
167   vtkBooleanMacro(AutoAdvance,vtkTypeBool);
168   vtkSetMacro(AutoAdvance,vtkTypeBool)
169   vtkGetMacro(AutoAdvance,vtkTypeBool);
170   //@}
171 
172   //@{
173   /**
174    * Set the clip rectangle for the frames.  The video will be clipped
175    * before it is copied into the framebuffer.  Changing the ClipRegion
176    * will destroy the current contents of the framebuffer.
177    * The default ClipRegion is (0,VTK_INT_MAX,0,VTK_INT_MAX,0,VTK_INT_MAX).
178    */
SetClipRegion(int r[6])179   virtual void SetClipRegion(int r[6]) {
180     this->SetClipRegion(r[0],r[1],r[2],r[3],r[4],r[5]); };
181   virtual void SetClipRegion(int x0, int x1, int y0, int y1, int z0, int z1);
182   vtkGetVector6Macro(ClipRegion,int);
183   //@}
184 
185   //@{
186   /**
187    * Get/Set the WholeExtent of the output.  This can be used to either
188    * clip or pad the video frame.  This clipping/padding is done when
189    * the frame is copied to the output, and does not change the contents
190    * of the framebuffer.  This is useful e.g. for expanding
191    * the output size to a power of two for texture mapping.  The
192    * default is (0,-1,0,-1,0,-1) which causes the entire frame to be
193    * copied to the output.
194    */
195   vtkSetVector6Macro(OutputWholeExtent,int);
196   vtkGetVector6Macro(OutputWholeExtent,int);
197   //@}
198 
199   //@{
200   /**
201    * Set/Get the pixel spacing.
202    * Default: (1.0,1.0,1.0)
203    */
204   vtkSetVector3Macro(DataSpacing,double);
205   vtkGetVector3Macro(DataSpacing,double);
206   //@}
207 
208   //@{
209   /**
210    * Set/Get the coordinates of the lower, left corner of the frame.
211    * Default: (0.0,0.0,0.0)
212    */
213   vtkSetVector3Macro(DataOrigin,double);
214   vtkGetVector3Macro(DataOrigin,double);
215   //@}
216 
217   //@{
218   /**
219    * For RGBA output only (4 scalar components), set the opacity.  This
220    * will not modify the existing contents of the framebuffer, only
221    * subsequently grabbed frames.
222    */
223   vtkSetMacro(Opacity,float);
224   vtkGetMacro(Opacity,float);
225   //@}
226 
227   //@{
228   /**
229    * This value is incremented each time a frame is grabbed.
230    * reset it to zero (or any other value) at any time.
231    */
232   vtkGetMacro(FrameCount, int);
233   vtkSetMacro(FrameCount, int);
234   //@}
235 
236   //@{
237   /**
238    * Get the frame index relative to the 'beginning of the tape'.  This
239    * value wraps back to zero if it increases past the FrameBufferSize.
240    */
241   vtkGetMacro(FrameIndex, int);
242   //@}
243 
244   /**
245    * Get a time stamp in seconds (resolution of milliseconds) for
246    * a video frame.   Time began on Jan 1, 1970.  You can specify
247    * a number (negative or positive) to specify the position of the
248    * video frame relative to the current frame.
249    */
250   virtual double GetFrameTimeStamp(int frame);
251 
252   /**
253    * Get a time stamp in seconds (resolution of milliseconds) for
254    * the Output.  Time began on Jan 1, 1970.  This timestamp is only
255    * valid after the Output has been Updated.
256    */
GetFrameTimeStamp()257   double GetFrameTimeStamp() { return this->FrameTimeStamp; };
258 
259   //@{
260   /**
261    * Initialize the hardware.  This is called automatically
262    * on the first Update or Grab.
263    */
264   virtual void Initialize();
GetInitialized()265   virtual int GetInitialized() { return this->Initialized; };
266   //@}
267 
268   /**
269    * Release the video driver.  This method must be called before
270    * application exit, or else the application might hang during
271    * exit.
272    */
273   virtual void ReleaseSystemResources();
274 
275   /**
276    * The internal function which actually does the grab.  You will
277    * definitely want to override this if you develop a vtkVideoSource
278    * subclass.
279    */
280   virtual void InternalGrab();
281 
282   //@{
283   /**
284    * And internal variable which marks the beginning of a Record session.
285    * These methods are for internal use only.
286    */
SetStartTimeStamp(double t)287   void SetStartTimeStamp(double t) { this->StartTimeStamp = t; };
GetStartTimeStamp()288   double GetStartTimeStamp() { return this->StartTimeStamp; };
289   //@}
290 
291 protected:
292   vtkVideoSource();
293   ~vtkVideoSource() override;
294   int RequestInformation(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
295 
296   int Initialized;
297 
298   int FrameSize[3];
299   int ClipRegion[6];
300   int OutputWholeExtent[6];
301   double DataSpacing[3];
302   double DataOrigin[3];
303   int OutputFormat;
304   // set according to the OutputFormat
305   int NumberOfScalarComponents;
306   // The FrameOutputExtent is the WholeExtent for a single output frame.
307   // It is initialized in ExecuteInformation.
308   int FrameOutputExtent[6];
309 
310   // save this information from the output so that we can see if the
311   // output scalars have changed
312   int LastNumberOfScalarComponents;
313   int LastOutputExtent[6];
314 
315   int Recording;
316   int Playing;
317   float FrameRate;
318   int FrameCount;
319 
320   double StartTimeStamp;
321   double FrameTimeStamp;
322 
323   vtkTypeBool AutoAdvance;
324   int NumberOfOutputFrames;
325 
326   float Opacity;
327 
328   // true if Execute() must apply a vertical flip to each frame
329   int FlipFrames;
330 
331   // set if output needs to be cleared to be cleared before being written
332   int OutputNeedsInitialization;
333 
334   // An example of asynchrony
335   vtkMultiThreader *PlayerThreader;
336   int PlayerThreadId;
337 
338   // A mutex for the frame buffer: must be applied when any of the
339   // below data is modified.
340   vtkCriticalSection *FrameBufferMutex;
341 
342   // set according to the needs of the hardware:
343   // number of bits per framebuffer pixel
344   int FrameBufferBitsPerPixel;
345   // byte alignment of each row in the framebuffer
346   int FrameBufferRowAlignment;
347   // FrameBufferExtent is the extent of frame after it has been clipped
348   // with ClipRegion.  It is initialized in CheckBuffer().
349   int FrameBufferExtent[6];
350 
351   int FrameBufferSize;
352 
353   // where the current frame is, note this decreases in time
354   // increasing values are older frames
355   int FrameBufferIndex;
356 
357   // number of frames from the beginning sort of,
358   // it does wrap, sometimes
359   int FrameIndex;
360 
361 
362   void **FrameBuffer;
363   double *FrameBufferTimeStamps;
364 
365   //@{
366   /**
367    * These methods can be overridden in subclasses
368    */
369   virtual void UpdateFrameBuffer();
370   virtual void AdvanceFrameBuffer(int n);
371   int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *) override;
372   // if some component conversion is required, it is done here:
373   virtual void UnpackRasterLine(char *outPtr, char *rowPtr,
374                                 int start, int count);
375   //@}
376 
377 private:
378   vtkVideoSource(const vtkVideoSource&) = delete;
379   void operator=(const vtkVideoSource&) = delete;
380 };
381 
382 #endif
383 
384 
385 
386 
387 
388