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