1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkVideoFileReader_h
19 #define itkVideoFileReader_h
20 
21 #include "itkVideoSource.h"
22 #include "itkVideoIOFactory.h"
23 #include "itkDefaultConvertPixelTraits.h"
24 
25 namespace itk
26 {
27 
28 /** \class VideoFileReader
29  * \brief Reader that creates a VideoStream
30  *
31  * This class is responsible for reading video information from files. It is a
32  * subclass of VideoSource, giving it functionality to connect to other
33  * TemporalProcessObject classes (specifically, VideoToVideoFilter classes). It
34  * uses the temporal streaming implementation provided by TemporalProcessObject
35  * to load a single frame at a time into the frame buffer of the output
36  * VideoSource.
37  *
38  * \ingroup ITKVideoIO
39  */
40 template< typename TOutputVideoStream >
41 class ITK_TEMPLATE_EXPORT VideoFileReader : public VideoSource< TOutputVideoStream >
42 {
43 public:
44   ITK_DISALLOW_COPY_AND_ASSIGN(VideoFileReader);
45 
46   /** Standard class type aliases. */
47   using Self = VideoFileReader;
48   using Superclass = VideoSource< TOutputVideoStream >;
49   using Pointer = SmartPointer<Self>;
50   using VideoStreamType = TOutputVideoStream;
51   using VideoStreamPointer = typename VideoStreamType::Pointer;
52 
53   using FrameType = typename VideoStreamType::FrameType;
54   using PixelType = typename FrameType::PixelType;
55   using RegionType = typename FrameType::RegionType;
56   using SizeType = typename FrameType::SizeType;
57   using IndexType = typename FrameType::IndexType;
58   using PointType = typename FrameType::PointType;
59   using SpacingType = typename FrameType::SpacingType;
60   using DirectionType = typename FrameType::DirectionType;
61 
62   using TemporalOffsetType = typename VideoIOBase::TemporalOffsetType;
63   using FrameOffsetType = typename VideoIOBase::FrameOffsetType;
64   using TemporalRatioType = typename VideoIOBase::TemporalRatioType;
65 
66   static constexpr unsigned int FrameDimension = FrameType::ImageDimension;
67 
68   /** Pixel conversion type alias */
69   using ConvertPixelTraits = DefaultConvertPixelTraits<PixelType>;
70 
71   /** Method for creation through the object factory. */
72   itkNewMacro(Self);
73 
74   /** Run-time type information (and related methods). */
75   itkTypeMacro(VideoFileReader, VideoSource);
76 
77 
78   /** Specify the file to read. This is forwarded to the IO instance. */
79   itkSetStringMacro(FileName);
80   itkGetStringMacro(FileName);
81 
82   /** Get/Set IFrameSafe. If true, the last IFrame will be reported as the last
83    * frame for the largest possible temporal region */
84   itkSetMacro(IFrameSafe, bool);
85   itkGetMacro(IFrameSafe, bool);
86 
87   /** Set up the output information */
88   void UpdateOutputInformation() override;
89 
90   /** Set the internal VideoIOBase pointer. This will generally be called by
91    * the object that creates the RingBuffer (e.g. itk::VideoFileReader) */
92   void SetVideoIO(VideoIOBase* videoIO);
93 
94   /** Get the current position as frame, ratio, or MSec */
95   FrameOffsetType GetCurrentPositionFrame();
96 
97   TemporalRatioType GetCurrentPositionRatio();
98 
99   TemporalOffsetType GetCurrentPositionMSec();
100 
101   /** Get number of frames */
102   FrameOffsetType GetNumberOfFrames();
103 
104   /** Get framerate */
105   TemporalRatioType GetFramesPerSecond();
106 
107 protected:
108 
109   VideoFileReader();
110   ~VideoFileReader() override = default;
111   void PrintSelf(std::ostream & os, Indent indent) const override;
112 
113   /** Override TemporalStreamingGenerateData to generate output a single frame.
114    * We don't override ThreadedGenerateData because we read whole frames one at
115    * a time. As such, we have to handle the allocation of the frames here. */
116   void TemporalStreamingGenerateData() override;
117 
118   /** Convert buffer for output */
119   void DoConvertBuffer(void* inputData, FrameOffsetType frameNumber);
120 
121   /** Set up the VideoIO using VideoIOFactory
122    * Warning: this will overwrite any currently set VideoIO */
123   void InitializeVideoIO();
124 
125 private:
126   /** The file to read */
127   std::string m_FileName;
128 
129   /** VideoIOBase used to retrieve images. This may be changed if more
130    * hierarchy is added to support general ImageSet sources. */
131   VideoIOBase::Pointer m_VideoIO;
132 
133   /** Flag to store whether or not the pixel type needs to be converted. */
134   bool m_PixelConversionNeeded;
135 
136   /** Flag to indicate whether to report the last frame as the last IFrame. On
137    * by default. */
138   bool m_IFrameSafe;
139 };
140 
141 } // end namespace itk
142 
143 #ifndef ITK_MANUAL_INSTANTIATION
144 #include "itkVideoFileReader.hxx"
145 #endif
146 
147 #endif
148