VTK  9.3.1
vtkFFMPEGVideoSource.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
18 #ifndef vtkFFMPEGVideoSource_h
19 #define vtkFFMPEGVideoSource_h
20 
21 #include "vtkIOFFMPEGModule.h" // For export macro
22 #include "vtkMultiThreader.h" // for ivar
23 #include "vtkNew.h" // for ivar
24 #include "vtkVideoSource.h"
25 #include <condition_variable> // for std::condition_variable_any
26 #include <functional> // for audio callback
27 #include <mutex> // for std::mutex
28 
29 VTK_ABI_NAMESPACE_BEGIN
30 class vtkFFMPEGVideoSourceInternal;
32 
33 // audio callback struct, outside the class so that we
34 // can forward ref it
36 {
41  int DataType;
42  bool Packed;
43  unsigned char** Data;
45  void* ClientData;
46 };
47 
48 // video callback struct, outside the class so that we
49 // can forward ref it
51 {
52  int Height;
53  int LineSize[8];
54  unsigned char* Data[8]; // nullptr for empty planes
56  void* ClientData;
57 };
58 
59 class VTKIOFFMPEG_EXPORT vtkFFMPEGVideoSource : public vtkVideoSource
60 {
61 public:
62  static vtkFFMPEGVideoSource* New();
64  void PrintSelf(ostream& os, vtkIndent indent) override;
65 
69  void Record() override;
70 
74  void Play() override;
75 
79  void Stop() override;
80 
84  void Grab() override;
85 
87 
90  void SetFrameSize(int x, int y, int z) override;
91  void SetFrameSize(int dim[3]) override { this->SetFrameSize(dim[0], dim[1], dim[2]); }
93 
97  void SetFrameRate(float rate) override;
98 
102  void SetOutputFormat(int format) override;
103 
108  void Initialize() override;
109 
114  void ReleaseSystemResources() override;
115 
117 
120  vtkSetFilePathMacro(FileName);
121  vtkGetFilePathMacro(FileName);
123 
129  void InternalGrab() override;
130 
131  // is the video at the end of file?
132  // Useful for while loops
133  vtkGetMacro(EndOfFile, bool);
134 
135  // Is the video stream stereo 3d
136  vtkGetMacro(Stereo3D, bool);
137 
138  // we do not use Invoke Observers here because this callback
139  // will happen in a different thread that could conflict
140  // with events from other threads. In this function you should
141  // not block the thread (for example waiting for audio to play)
142  // instead you should have enough buffering that you can consume
143  // the provided data and return. Typically even 1 second of
144  // buffer storage is enough to prevent blocking.
145  typedef std::function<void(vtkFFMPEGVideoSourceAudioCallbackData const& data)> AudioCallbackType;
146  void SetAudioCallback(AudioCallbackType cb, void* clientData)
147  {
148  this->AudioCallback = cb;
149  this->AudioCallbackClientData = clientData;
150  }
151 
152  // we do not use Invoke Observers here because this callback
153  // will happen in a different thread that could conflict
154  // with events from other threads. In this function you should
155  // not block the thread (for example waiting for video to play)
156  // instead you should have enough buffering that you can consume
157  // the provided data and return.
158  typedef std::function<void(vtkFFMPEGVideoSourceVideoCallbackData const& data)> VideoCallbackType;
159  void SetVideoCallback(VideoCallbackType cb, void* clientData)
160  {
161  this->VideoCallback = cb;
162  this->VideoCallbackClientData = clientData;
163  }
164 
166 
171  vtkSetMacro(DecodingThreads, int);
172  vtkGetMacro(DecodingThreads, int);
174 
175 protected:
177  ~vtkFFMPEGVideoSource() override;
178 
179  AudioCallbackType AudioCallback;
181 
183 
184  static void* DrainAudioThread(vtkMultiThreader::ThreadInfo* data);
185  void* DrainAudio(vtkMultiThreader::ThreadInfo* data);
187 
188  static void* DrainThread(vtkMultiThreader::ThreadInfo* data);
189  void* Drain(vtkMultiThreader::ThreadInfo* data);
191 
192  bool EndOfFile;
193 
194  std::condition_variable_any FeedCondition;
195  std::mutex FeedMutex;
196  std::condition_variable_any FeedAudioCondition;
197  std::mutex FeedAudioMutex;
198  static void* FeedThread(vtkMultiThreader::ThreadInfo* data);
199  void* Feed(vtkMultiThreader::ThreadInfo* data);
201 
202  char* FileName;
203 
204  vtkFFMPEGVideoSourceInternal* Internal;
205 
206  void ReadFrame();
207 
208  bool Stereo3D;
209 
210  VideoCallbackType VideoCallback;
212 
213 private:
215  void operator=(const vtkFFMPEGVideoSource&) = delete;
216 };
217 
218 VTK_ABI_NAMESPACE_END
219 #endif
VideoCallbackType VideoCallback
virtual void Stop()
Stop recording or playing.
void PrintSelf(ostream &os, vtkIndent indent) override
Methods invoked by print to print information about the object including superclasses.
void SetAudioCallback(AudioCallbackType cb, void *clientData)
std::function< void(vtkFFMPEGVideoSourceVideoCallbackData const &data)> VideoCallbackType
std::condition_variable_any FeedCondition
virtual void Initialize()
Initialize the hardware.
std::function< void(vtkFFMPEGVideoSourceAudioCallbackData const &data)> AudioCallbackType
AudioCallbackType AudioCallback
vtkFFMPEGVideoSourceInternal * Internal
This is the structure that is passed to the thread that is created from the SingleMethodExecute, MultipleMethodExecute or the SpawnThread method.
void SetFrameSize(int dim[3]) override
Request a particular frame size (set the third value to 1).
Superclass of video input devices for VTK.
virtual void ReleaseSystemResources()
Release the video driver.
std::condition_variable_any FeedAudioCondition
a simple class to control print indentation
Definition: vtkIndent.h:28
virtual void Record()
Record incoming video at the specified FrameRate.
Reader for ffmpeg supported formats.
virtual void SetOutputFormat(int format)
Set the output format.
static vtkVideoSource * New()
virtual void SetFrameSize(int x, int y, int z)
Set the full-frame size.
virtual void Play()
Play through the 'tape' sequentially at the specified frame rate.
virtual void Grab()
Grab a single video frame.
virtual void SetFrameRate(float rate)
Request a particular frame rate (default 30 frames per second).
virtual void InternalGrab()
The internal function which actually does the grab.
void SetVideoCallback(VideoCallbackType cb, void *clientData)