Panda3D
 All Classes Functions Variables Enumerations
webcamVideoCursorOpenCV.cxx
1 // Filename: webcamVideoCursorOpenCV.cxx
2 // Created by: drose (20Oct10)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "webcamVideoOpenCV.h"
16 
17 #ifdef HAVE_OPENCV
18 
19 #include "pStatTimer.h"
20 
21 TypeHandle WebcamVideoCursorOpenCV::_type_handle;
22 
23 ////////////////////////////////////////////////////////////////////
24 // Function: WebcamVideoCursorOpenCV::Constructor
25 // Access: Published
26 // Description:
27 ////////////////////////////////////////////////////////////////////
28 WebcamVideoCursorOpenCV::
29 WebcamVideoCursorOpenCV(WebcamVideoOpenCV *src) : MovieVideoCursor(src) {
30  _size_x = src->_size_x;
31  _size_y = src->_size_y;
32  _num_components = 3;
33  _length = 1.0E10;
34  _can_seek = false;
35  _can_seek_fast = false;
36  _aborted = false;
37  _streaming = true;
38  _ready = false;
39 
40  _capture = cvCaptureFromCAM(src->_camera_index);
41  if (_capture != NULL) {
42  _size_x = (int)cvGetCaptureProperty(_capture, CV_CAP_PROP_FRAME_WIDTH);
43  _size_y = (int)cvGetCaptureProperty(_capture, CV_CAP_PROP_FRAME_HEIGHT);
44  _ready = true;
45  }
46 }
47 
48 ////////////////////////////////////////////////////////////////////
49 // Function: WebcamVideoCursorOpenCV::Destructor
50 // Access: Published, Virtual
51 // Description:
52 ////////////////////////////////////////////////////////////////////
53 WebcamVideoCursorOpenCV::
54 ~WebcamVideoCursorOpenCV() {
55  if (_capture != NULL) {
56  cvReleaseCapture(&_capture);
57  _capture = NULL;
58  }
59 }
60 
61 ////////////////////////////////////////////////////////////////////
62 // Function: WebcamVideoCursorOpenCV::fetch_buffer
63 // Access: Published, Virtual
64 // Description:
65 ////////////////////////////////////////////////////////////////////
66 PT(MovieVideoCursor::Buffer) WebcamVideoCursorOpenCV::
67 fetch_buffer() {
68  if (!_ready) {
69  return NULL;
70  }
71 
72  PT(Buffer) buffer = get_standard_buffer();
73  unsigned char *dest = buffer->_block;
74  int num_components = get_num_components();
75  nassertr(num_components == 3, NULL);
76  int dest_x_pitch = num_components; // Assume component_width == 1
77  int dest_y_pitch = _size_x * dest_x_pitch;
78 
79  const unsigned char *r, *g, *b;
80  int x_pitch, y_pitch;
81  if (get_frame_data(r, g, b, x_pitch, y_pitch)) {
82  if (num_components == 3 && x_pitch == 3) {
83  // The easy case--copy the whole thing in, row by row.
84  int copy_bytes = _size_x * dest_x_pitch;
85  nassertr(copy_bytes <= dest_y_pitch && copy_bytes <= abs(y_pitch), NULL);
86 
87  for (int y = 0; y < _size_y; ++y) {
88  memcpy(dest, r, copy_bytes);
89  dest += dest_y_pitch;
90  r += y_pitch;
91  }
92 
93  } else {
94  // The harder case--interleave in the color channels, pixel by
95  // pixel.
96 
97  for (int y = 0; y < _size_y; ++y) {
98  int dx = 0;
99  int sx = 0;
100  for (int x = 0; x < _size_x; ++x) {
101  dest[dx] = r[sx];
102  dest[dx + 1] = g[sx];
103  dest[dx + 2] = b[sx];
104  dx += dest_x_pitch;
105  sx += x_pitch;
106  }
107  dest += dest_y_pitch;
108  r += y_pitch;
109  g += y_pitch;
110  b += y_pitch;
111  }
112  }
113  }
114 
115  return buffer;
116 }
117 
118 ////////////////////////////////////////////////////////////////////
119 // Function: WebcamVideoCursorOpenCV::get_frame_data
120 // Access: Private
121 // Description: Gets the data needed to traverse through the
122 // decompressed buffer. Returns true on success, false
123 // on failure.
124 //
125 // In the case of a success indication (true return
126 // value), the three pointers r, g, b are loaded with
127 // the addresses of the three components of the
128 // bottom-left pixel of the image. (They will be
129 // adjacent in memory in the case of an interleaved
130 // image, and separated in the case of a
131 // separate-channel image.) The x_pitch value is filled
132 // with the amount to add to each pointer to advance to
133 // the pixel to the right; and the y_pitch value is
134 // filled with the amount to add to each pointer to
135 // advance to the pixel above. Note that these values
136 // may be negative (particularly in the case of a
137 // top-down image).
138 ////////////////////////////////////////////////////////////////////
139 bool WebcamVideoCursorOpenCV::
140 get_frame_data(const unsigned char *&r,
141  const unsigned char *&g,
142  const unsigned char *&b,
143  int &x_pitch, int &y_pitch) {
144  nassertr(ready(), false);
145 
146  IplImage *image = cvQueryFrame(_capture);
147  if (image == NULL) {
148  return false;
149  }
150 
151  r = (const unsigned char *)image->imageData;
152  g = r + 1;
153  b = g + 1;
154  x_pitch = 3;
155  y_pitch = image->widthStep;
156 
157  if (image->dataOrder == 1) {
158  // Separate channel images. That means a block of r, followed by
159  // a block of g, followed by a block of b.
160  x_pitch = 1;
161  g = r + image->height * y_pitch;
162  b = g + image->height * y_pitch;
163  }
164 
165  if (image->origin == 0) {
166  // The image data starts with the top row and ends with the bottom
167  // row--the opposite of Texture::_ram_data's storage convention.
168  // Therefore, we must increment the initial pointers to the last
169  // row, and count backwards.
170  r += (image->height - 1) * y_pitch;
171  g += (image->height - 1) * y_pitch;
172  b += (image->height - 1) * y_pitch;
173  y_pitch = -y_pitch;
174  }
175 
176  return true;
177 }
178 
179 #endif
Definition: buffer.h:26
A MovieVideo is actually any source that provides a sequence of video frames.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:85