libcvd
deinterlacebuffer.h
1 // PAS 17/6/04 (revised 16/2/05)
2 #ifndef CVD_INCLUDE_DEINTERLACEBUFFER_H
3 #define CVD_INCLUDE_DEINTERLACEBUFFER_H
4 
5 #include <cvd/deinterlaceframe.h>
6 #include <cvd/internal/pixel_operations.h>
7 #include <cvd/internal/rgb_components.h>
8 #include <cvd/videobuffer.h>
9 
10 namespace CVD
11 {
13 // DEINTERLACE BUFFER EXCEPTIONS
14 //
15 namespace Exceptions
16 {
20  {
24  {
25  using CVD::Exceptions::VideoBuffer::All::All;
26  };
27 
30  struct OddNumberOfLines : public All
31  {
33  };
34  }
35 }
36 
38 // DEINTERLACE BUFFER
39 //
40 
62 
65 {
66  enum Fields
67  {
71  EvenOdd
72  };
73 };
74 
75 template <typename T>
76 class DeinterlaceBuffer : public VideoBuffer<T>
77 {
78  public:
83  DeinterlaceBuffer(CVD::VideoBuffer<T>& buf, Fields::Fields fields = Fields::OddEven, bool line_double = false);
84 
87  ImageRef size();
88 
89  CVD::VideoFrame<T>* get_frame();
90 
92  {
93  return &m_vidbuf;
94  }
95 
96  void put_frame(CVD::VideoFrame<T>* f);
97 
98  virtual bool frame_pending()
99  {
100  return m_vidbuf.frame_pending();
101  }
102 
103  virtual void seek_to(double t)
104  {
105  return m_vidbuf.seek_to(t);
106  }
107 
111  virtual double frame_rate()
112  {
113  if(m_fields == Fields::OddOnly || m_fields == Fields::EvenOnly)
114  return m_vidbuf.frame_rate();
115  else
116  return m_vidbuf.frame_rate() * 2.0;
117  }
118 
119  private:
120  CVD::VideoFrame<T>* my_realframe;
121  CVD::VideoBuffer<T>& m_vidbuf;
122  Fields::Fields m_fields;
123  bool m_loadnewframe;
124  ImageRef m_size;
125  long m_linebytes;
126  bool line_double;
127 };
128 
129 //
130 // CONSTRUCTOR
131 //
132 template <typename T>
134  : VideoBuffer<T>(vidbuf.type())
135  , m_vidbuf(vidbuf)
136  , m_fields(fields)
137  , m_loadnewframe(true)
138  , line_double(l)
139 {
140  // Check it has an even number of lines
141  if(m_vidbuf.size().y % 2 != 0)
143 
144  if(line_double == false)
145  m_size = ImageRef(m_vidbuf.size().x, m_vidbuf.size().y / 2);
146  else
147  m_size = m_vidbuf.size();
148 
149  m_linebytes = sizeof(T) * m_size.x;
150 }
151 
152 //
153 // GET FRAME
154 //
155 template <typename T>
157 {
158  if(m_loadnewframe)
159  {
160  // Get a new frame from the real videobuffer
161  my_realframe = m_vidbuf.get_frame();
162  }
163 
164  // Now return the deinterlaced image
165  // First sort out the time
166  double time = my_realframe->timestamp();
167 
168  // If we're giving the second frame of a pair, make its time half-way to the next frame
169  if(!m_loadnewframe)
170  time += 0.5 / frame_rate();
171 
172  DeinterlaceFrame<T>* frame = new DeinterlaceFrame<T>(time, Image<T>(size()));
173 
174  if(m_fields == Fields::OddOnly || (m_fields == Fields::OddEven && m_loadnewframe) || (m_fields == Fields::EvenOdd && !m_loadnewframe))
175  {
176 
177  // We want the odd field
178  if(line_double)
179  {
180  frame->zero();
181  for(int y = 1; y < m_size.y; y += 2)
182  for(int x = 0; x < m_size.x; x++)
183  (*frame)[y][x] = (*my_realframe)[y][x];
184 
185  for(int y = 2; y < m_size.y - 1; y += 2)
186  for(int x = 0; x < m_size.x; x++)
187  for(unsigned int i = 0; i < Pixel::Component<T>::count; i++)
188  Pixel::Component<T>::get((*frame)[y][x], i) = static_cast<typename Pixel::Component<T>::type>((Pixel::Component<T>::get((*my_realframe)[y - 1][x], i) + Pixel::Component<T>::get((*my_realframe)[y + 1][x], i)) / 2);
189 
190  /*
191  //Copy line 0 from line 1, and copy over line 1 to line 1
192  for(int y=0; y < 2; y++)
193  for(int x=0; x < m_size.x; x++)
194  (*frame)[y][x] = (*my_realframe)[0][x];
195 
196  //Done 0, 1. next 2, 3
197 
198  for(int y=3; y < m_size.y; y+=2)
199  for(int x=0; x < m_size.x; x++)
200  {
201  (*frame)[y][x] = (*my_realframe)[y][x];
202  (*frame)[y-1][x] = ((*my_realframe)[y][x] + (*my_realframe)[y-2][x])/2;
203  }
204  */
205  }
206  else
207  {
208  for(int y = 0; y < m_size.y; y++)
209  for(int x = 0; x < m_size.x; x++)
210  (*frame)[y][x] = (*my_realframe)[2 * y + 1][x];
211  }
212  }
213  else
214  {
215  // We want the even field
216  // We want the odd field
217  if(line_double)
218  {
219  frame->zero();
220  for(int y = 0; y < m_size.y; y += 2)
221  for(int x = 0; x < m_size.x; x++)
222  (*frame)[y][x] = (*my_realframe)[y][x];
223 
224  for(int y = 1; y < m_size.y - 1; y += 2)
225  for(int x = 0; x < m_size.x; x++)
226  for(unsigned int i = 0; i < Pixel::Component<T>::count; i++)
227  Pixel::Component<T>::get((*frame)[y][x], i) = static_cast<typename Pixel::Component<T>::type>((Pixel::Component<T>::get((*my_realframe)[y - 1][x], i) + Pixel::Component<T>::get((*my_realframe)[y + 1][x], i)) / 2);
228  /*
229  //Copy over and double the first set of lines
230  for(int y=0; y < m_size.y-2; y+=2)
231  for(int x=0; x < m_size.x; x++)
232  {
233  (*frame)[y][x] = (*my_realframe)[y][x];
234  (*frame)[y+1][x] = ((*my_realframe)[y][x] + (*my_realframe)[y+2][x])/2;
235  }
236 
237  //Copy the last line.
238  for(int y=m_size.y-2; y < m_size.y; y++)
239  for(int x=0; x < m_size.x; x++)
240  (*frame)[y][x] = (*my_realframe)[m_size.y-2][x];
241  */
242  }
243  else
244  {
245  for(int y = 0; y < m_size.y; y++)
246  for(int x = 0; x < m_size.x; x++)
247  (*frame)[y][x] = (*my_realframe)[2 * y][x];
248  }
249  }
250  frame->real_frame = my_realframe;
251 
252  if(m_fields == Fields::OddEven || m_fields == Fields::EvenOdd)
253  {
254  // If we're taking both fields, we only load a frame every other field
255  m_loadnewframe = !m_loadnewframe;
256  }
257 
258  return frame;
259 }
260 
261 //
262 // SIZE
263 //
264 template <typename T>
266 {
267  return m_size;
268 }
269 
270 //
271 // PUT FRAME
272 //
273 template <typename T>
275 {
276  if(m_loadnewframe)
277  {
278  // Next time we'll be getting a new real frame, so put back the current real frame
279  m_vidbuf.put_frame(my_realframe);
280  }
281 
282  // And delete the data for my current deinterlaced frame
283  delete dynamic_cast<DeinterlaceFrame<T>*>(frame);
284 }
285 
286 } // CVD
287 #endif
virtual double frame_rate()
What is the (expected) frame rate of this video buffer, in frames per second? If OddEven or EvenOdd a...
Definition: deinterlacebuffer.h:111
Base class which provides untyped access to video grabber objects.
Definition: videobuffer.h:39
virtual bool frame_pending()
Is there a frame waiting in the buffer? This function does not block.
Definition: deinterlacebuffer.h:98
All classes and functions are within the CVD namespace.
Definition: argb.h:6
A decorator class which wraps a VideoBuffer to return fields instead of the original frames (see also...
Definition: deinterlacebuffer.h:64
Even fields only.
Definition: deinterlacebuffer.h:69
Base class for objects which provide a typed video stream.
Definition: videobuffer.h:88
A frame from a DeinterlaceBuffer, representing one field from an interlaced frame.
Definition: deinterlaceframe.h:21
void zero()
Set image data to all zero bytes.
Definition: image.h:564
void put_frame(CVD::VideoFrame< T > *f)
Tell the buffer that you are finished with this frame.
Definition: deinterlacebuffer.h:274
CVD::VideoFrame< T > * get_frame()
Returns the next frame from the buffer. This function blocks until a frame is ready.
Definition: deinterlacebuffer.h:156
virtual RawVideoBuffer * source_buffer()
Which video grabber provides the source images for this video grabber.
Definition: deinterlacebuffer.h:91
int x
The x co-ordinate.
Definition: image_ref.h:172
The VideoBuffer that is being wrapped does not have an even number of lines (so the odd and even- fie...
Definition: deinterlacebuffer.h:30
Base class for all DeinterlaceBuffer exceptions.
Definition: deinterlacebuffer.h:23
Definition: image_ref.h:29
Odd fields only.
Definition: deinterlacebuffer.h:68
Both fields, presenting the odd lines from each frame first.
Definition: deinterlacebuffer.h:70
Base class for all VideoBuffer exceptions.
Definition: videobuffer.h:153
Definition: deinterlacebuffer.h:76
A frame from a VideoBuffer.
Definition: videoframe.h:35
virtual void seek_to(double t)
Go to a particular point in the video buffer (only implemented in buffers of recorded video) ...
Definition: deinterlacebuffer.h:103
A full image which manages its own data.
Definition: image.h:623
ImageRef size()
The size of the VideoFrames returns by this buffer.
Definition: deinterlacebuffer.h:265
DeinterlaceBuffer(CVD::VideoBuffer< T > &buf, Fields::Fields fields=Fields::OddEven, bool line_double=false)
Construct a DeinterlaceBuffer by wrapping it around another VideoBuffer.
Definition: deinterlacebuffer.h:133
Definition: builtin_components.h:38
Fields
Definition: deinterlacebuffer.h:66