1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
|
/*=========================================================================
*
* Copyright NumFOCUS
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0.txt
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*=========================================================================*/
#ifndef itkVideoSource_h
#define itkVideoSource_h
#include "itkTemporalProcessObject.h"
#include "itkVideoStream.h"
namespace itk
{
/**
* \class VideoSource
* \brief A TemporalProcessObject that produces a VideoStream
*
* VideoSource acts as the base class for all TemporalProcess objects that
* produce a VideoStream as their output. This class defines GetOutput() which
* returns a pointer to the VideoStream object on output port 0.
*
* The other role that VideoSource plays is to implement the framework for
* spatial streaming to complement the temporal streaming implemented in
* TemporalProcessObject. This implementation mirrors the implementation in
* ImageSource except that each thread will be able to operate on a spatial
* region of each frame in the current temporal region that is being processed.
*
* \ingroup ITKVideoCore
*/
template <typename TOutputVideoStream>
class ITK_TEMPLATE_EXPORT VideoSource : public TemporalProcessObject
{
public:
ITK_DISALLOW_COPY_AND_MOVE(VideoSource);
/*-TYPEDEFS----------------------------------------------------------------*/
/** Standard class type aliases */
using Self = VideoSource;
using Superclass = TemporalProcessObject;
using Pointer = SmartPointer<Self>;
using ConstPointer = SmartPointer<const Self>;
using ConstWeakPointer = WeakPointer<const Self>;
using OutputVideoStreamType = TOutputVideoStream;
using OutputFrameType = typename OutputVideoStreamType::FrameType;
using OutputFrameSpatialRegionType = typename OutputVideoStreamType::SpatialRegionType;
using OutputFrameIndexType = typename OutputVideoStreamType::IndexType;
using OutputFramePixelType = typename OutputVideoStreamType::PixelType;
using OutputFramePointType = typename OutputVideoStreamType::PointType;
using OutputFrameSpacingType = typename OutputVideoStreamType::SpacingType;
using OutputFrameSizeType = typename OutputVideoStreamType::SizeType;
using OutputFrameDirectionType = typename OutputVideoStreamType::DirectionType;
itkNewMacro(Self);
/** \see LightObject::GetNameOfClass() */
itkOverrideGetNameOfClassMacro(VideoSource);
/*-PUBLIC METHODS----------------------------------------------------------*/
/** Access the spacial dimensionality of the frames */
static constexpr unsigned int OutputFrameDimension = OutputFrameType::ImageDimension;
static unsigned int
GetOutputFrameDimension()
{
return OutputFrameType::ImageDimension;
}
/** GetOutput() returns a pointer to the VideoStream on output port 0. This
* is analogous to the GetOutput on ImageSource and will be used to pass
* VideoStream data between TemporalProcessObjects (typically video filters)
*/
OutputVideoStreamType *
GetOutput();
OutputVideoStreamType *
GetOutput(unsigned int idx);
/** Graft the provided VideoStream onto the TemporalProcessObject's idx'th
* output using VideoStream's Graft implementation */
virtual void
GraftNthOutput(unsigned int idx, OutputVideoStreamType * graft);
/** Graft the provided VideoStream onto the 0th output. This is useful for
* ImageSources that use a mini-pipeline internally. See comment in
* ImageSource for more information. */
virtual void
GraftOutput(OutputVideoStreamType * graft);
/** Make a DataObject of the correct type for the specified output port. The
* default always creates an OutputVideoStreamType object, so subclasses with
* multiple types of output must override this to return the proper type. */
using DataObjectPointerArraySizeType = ProcessObject::DataObjectPointerArraySizeType;
using Superclass::MakeOutput;
DataObjectPointer
MakeOutput(DataObjectPointerArraySizeType idx) override;
protected:
/** Override GenerateOutputRequestedTemporalRegion to make sure that if the
* requested temporal region is not set, it gets set to the largest possible
* temporal region (using TemporalProcessObject's implementation) and the
* output has enough frame buffer slots to hold the entire request. We don't
* want the number of buffers to be changed for mid-pipeline filters since
* they will usually operate on fewer frames than requested at any given
* time. The solution is to only change the number of buffers if the
* requested temporal region was unset at the beginning of the call since
* mid-pipeline filters will always have their outputs' requested spatial
* regions set by the GenerateInputRequestedRegion call from the filter one
* further down the pipeline. */
void
GenerateOutputRequestedTemporalRegion(TemporalDataObject * output) override;
/** We override the default implementation of TemporalStreamingGenerateData
* from TemporalProcessObject to provide functionality for spatial streaming.
* This implementation works exactly the same way as the implementation of
* GenerateData in ImageSource. The filter-specific implementation of
* ThreadedGenerateData will be responsible of accessing the correct frames. */
void
TemporalStreamingGenerateData() override;
/** ThreadedGenerateData here serves the same semantic purpose as
* ThreadedGenerateData in ProcessObjects that handle Images. This is to say
* that ThreadedGenerateData is in charge of performing a single algorithmic
* operation on a portion of the requested region. The difference will come
* in the implementation of each filter. Subclass implementations must access
* the passed spatial region across the desired number of frames in the
* buffered TemporalRegion of the input.
*
* WARNING: subclasses may need to handle the case where different frames
* have different spatial dimensions and thus some frames may not be
* accessible at the requested spatial region. */
virtual void
ThreadedGenerateData(const OutputFrameSpatialRegionType & outputRegionForThread, int threadId);
/** The GenerateData method normally allocates the buffers for all of the
* outputs of a filter. Some filters may want to override this default
* behavior. For example, a filter may have multiple outputs with
* varying resolution. Or a filter may want to process data in place by
* grafting its input to its output. */
virtual void
AllocateOutputs();
/** Method that gets called before threads are dispatched from
* TemporalStreamingGenerateData */
virtual void
BeforeThreadedGenerateData()
{}
/** Method that gets called after all threads finish in
* TemporalStreamingGenerateData */
virtual void
AfterThreadedGenerateData()
{}
/** This method functions like SplitRequestedRegion in ImageSource and is
* used by the implementation of TemporalStreamingGenerateData to dispatch
* threads that call ThreadedGenerateData. */
virtual int
SplitRequestedSpatialRegion(int i, int num, OutputFrameSpatialRegionType & splitRegion);
/** Static thread callback function for the MultiThreaderBase. This gives control
* to ThreadedGenerateData(). */
static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION
ThreaderCallback(void * arg);
/** Internal structure used for passing image data into the threading library
*/
struct ThreadStruct
{
Pointer Filter;
};
VideoSource();
~VideoSource() override = default;
void
PrintSelf(std::ostream & os, Indent indent) const override;
private:
}; // end class VideoSource
} // end namespace itk
#ifndef ITK_MANUAL_INSTANTIATION
# include "itkVideoSource.hxx"
#endif
#endif
|