24 #include <core/exception.h>
25 #include <core/exceptions/software.h>
26 #include <fvcams/v4l1.h>
27 #include <fvutils/color/colorspaces.h>
28 #include <fvutils/color/rgb.h>
29 #include <fvutils/system/camargp.h>
30 #include <linux/types.h>
31 #include <linux/videodev.h>
32 #include <sys/ioctl.h>
36 #include <sys/types.h>
50 namespace firevision {
57 V4L1CameraData(
const char *device_name)
59 this->device_name = strdup(device_name);
71 struct video_capability capabilities;
72 struct video_buffer vbuffer;
73 struct video_window window;
76 struct video_picture picture;
77 struct video_tuner * tuner;
78 struct video_audio audio;
80 captured_frame_buffer;
81 struct video_mmap *buf_v4l;
93 V4L1Camera::V4L1Camera(
const char *device_name)
95 started = opened =
false;
96 data_ =
new V4L1CameraData(device_name);
107 started = opened =
false;
108 if (cap->
has(
"device")) {
109 data_ =
new V4L1CameraData(cap->
get(
"device").c_str());
121 V4L1Camera::V4L1Camera(
const char *device_name,
int dev)
123 started = opened =
false;
124 data_ =
new V4L1CameraData(device_name);
128 if ((ioctl(dev, VIDIOCGCAP, &(data_->capabilities))) == -1) {
129 throw Exception(
"V4L1Cam: Could not get capabilities");
136 V4L1Camera::~V4L1Camera()
146 dev = ::open(data_->device_name, O_RDWR);
148 throw Exception(
"V4L1Cam: Could not open device");
152 if ((ioctl(dev, VIDIOCGCAP, &(data_->capabilities))) == -1) {
153 throw Exception(
"V4L1Cam: Could not get capabilities");
164 V4L1Camera::post_open()
167 if ((ioctl(dev, VIDIOCGWIN, &data_->window)) == -1) {
168 throw Exception(
"V4L1Cam: Could not get window information");
172 if ((ioctl(dev, VIDIOCGPICT, &data_->picture)) == -1) {
173 throw Exception(
"V4L1Cam: Could not get window information");
178 data_->channel = (
struct video_channel *)malloc(
sizeof(
struct video_channel)
179 * (data_->capabilities.channels + 1));
180 for (
int ch = 0; ch < data_->capabilities.channels; ch++) {
181 data_->channel[ch].norm = 0;
182 if ((ioctl(dev, VIDIOCSCHAN, &data_->channel[ch])) == -1) {
183 printf(
"V4L1Cam: Could not get channel information for channel %i: %s", ch, strerror(errno));
188 if (ioctl(dev, VIDIOCGMBUF, data_->captured_frame_buffer) == -1) {
189 capture_method = READ;
191 (
unsigned char *)malloc(data_->window.width * data_->window.height * RGB_PIXEL_SIZE);
193 capture_method = MMAP;
194 frame_buffer = (
unsigned char *)
195 mmap(0, data_->captured_frame_buffer.size, PROT_READ | PROT_WRITE, MAP_SHARED, dev, 0);
196 if ((
unsigned char *)-1 == (
unsigned char *)frame_buffer) {
197 throw Exception(
"V4L1Cam: Cannot initialize mmap region");
201 data_->buf_v4l = NULL;
211 throw Exception(
"V4L1Cam: Trying to start closed cam!");
224 V4L1Camera::print_info()
230 <<
"CAPABILITIES" << endl
231 <<
"===========================================================================" << endl;
233 if (data_->capabilities.type & VID_TYPE_CAPTURE)
234 cout <<
" + Can capture to memory" << endl;
235 if (data_->capabilities.type & VID_TYPE_TUNER)
236 cout <<
" + Has a tuner of some form" << endl;
237 if (data_->capabilities.type & VID_TYPE_TELETEXT)
238 cout <<
" + Has teletext capability" << endl;
239 if (data_->capabilities.type & VID_TYPE_OVERLAY)
240 cout <<
" + Can overlay its image onto the frame buffer" << endl;
241 if (data_->capabilities.type & VID_TYPE_CHROMAKEY)
242 cout <<
" + Overlay is Chromakeyed" << endl;
243 if (data_->capabilities.type & VID_TYPE_CLIPPING)
244 cout <<
" + Overlay clipping is supported" << endl;
245 if (data_->capabilities.type & VID_TYPE_FRAMERAM)
246 cout <<
" + Overlay overwrites frame buffer memory" << endl;
247 if (data_->capabilities.type & VID_TYPE_SCALES)
248 cout <<
" + The hardware supports image scaling" << endl;
249 if (data_->capabilities.type & VID_TYPE_MONOCHROME)
250 cout <<
" + Image capture is grey scale only" << endl;
251 if (data_->capabilities.type & VID_TYPE_SUBCAPTURE)
252 cout <<
" + Can subcapture" << endl;
255 cout <<
" Number of Channels ='" << data_->capabilities.channels <<
"'" << endl;
256 cout <<
" Number of Audio Devices ='" << data_->capabilities.audios <<
"'" << endl;
257 cout <<
" Maximum Capture Width ='" << data_->capabilities.maxwidth <<
"'" << endl;
258 cout <<
" Maximum Capture Height ='" << data_->capabilities.maxheight <<
"'" << endl;
259 cout <<
" Minimum Capture Width ='" << data_->capabilities.minwidth <<
"'" << endl;
260 cout <<
" Minimum Capture Height ='" << data_->capabilities.minheight <<
"'" << endl;
263 <<
"CAPTURE WINDOW INFO" << endl
264 <<
"===========================================================================" << endl;
266 cout <<
" X Coord in X window Format: " << data_->window.x << endl;
267 cout <<
" Y Coord in X window Format: " << data_->window.y << endl;
268 cout <<
" Width of the Image Capture: " << data_->window.width << endl;
269 cout <<
" Height of the Image Capture: " << data_->window.height << endl;
270 cout <<
" ChromaKey: " << data_->window.chromakey << endl;
273 <<
"DEVICE PICTURE INFO" << endl
274 <<
"===========================================================================" << endl;
276 cout <<
" Picture Brightness: " << data_->picture.brightness << endl;
277 cout <<
" Picture Hue: " << data_->picture.hue << endl;
278 cout <<
" Picture Colour: " << data_->picture.colour << endl;
279 cout <<
" Picture Contrast: " << data_->picture.contrast << endl;
280 cout <<
" Picture Whiteness: " << data_->picture.whiteness << endl;
281 cout <<
" Picture Depth: " << data_->picture.depth << endl;
282 cout <<
" Picture Palette: " << data_->picture.palette <<
" (";
284 if (data_->picture.palette == VIDEO_PALETTE_GREY)
285 cout <<
"VIDEO_PALETTE_GRAY";
286 if (data_->picture.palette == VIDEO_PALETTE_HI240)
287 cout <<
"VIDEO_PALETTE_HI240";
288 if (data_->picture.palette == VIDEO_PALETTE_RGB565)
289 cout <<
"VIDEO_PALETTE_RGB565";
290 if (data_->picture.palette == VIDEO_PALETTE_RGB555)
291 cout <<
"VIDEO_PALETTE_RGB555";
292 if (data_->picture.palette == VIDEO_PALETTE_RGB24)
293 cout <<
"VIDEO_PALETTE_RGB24";
294 if (data_->picture.palette == VIDEO_PALETTE_RGB32)
295 cout <<
"VIDEO_PALETTE_RGB32";
296 if (data_->picture.palette == VIDEO_PALETTE_YUV422)
297 cout <<
"VIDEO_PALETTE_YUV422";
298 if (data_->picture.palette == VIDEO_PALETTE_YUYV)
299 cout <<
"VIDEO_PALETTE_YUYV";
300 if (data_->picture.palette == VIDEO_PALETTE_UYVY)
301 cout <<
"VIDEO_PALETTE_UYVY";
302 if (data_->picture.palette == VIDEO_PALETTE_YUV420)
303 cout <<
"VIDEO_PALETTE_YUV420";
304 if (data_->picture.palette == VIDEO_PALETTE_YUV411)
305 cout <<
"VIDEO_PALETTE_YUV411";
306 if (data_->picture.palette == VIDEO_PALETTE_RAW)
307 cout <<
"VIDEO_PALETTE_RAW";
308 if (data_->picture.palette == VIDEO_PALETTE_YUV422P)
309 cout <<
"VIDEO_PALETTE_YUV422P";
310 if (data_->picture.palette == VIDEO_PALETTE_YUV411P)
311 cout <<
"VIDEO_PALETTE_YUV411P";
316 <<
"VIDEO SOURCE INFO" << endl
317 <<
"===========================================================================" << endl;
319 cout <<
" Channel Number or Video Source Number: " << data_->channel->channel << endl;
320 cout <<
" Channel Name: " << data_->channel->name << endl;
321 cout <<
" Number of Tuners for this source: " << data_->channel->tuners << endl;
322 cout <<
" Channel Norm: " << data_->channel->norm << endl;
323 if (data_->channel->flags & VIDEO_VC_TUNER)
324 cout <<
" + This channel source has tuners" << endl;
325 if (data_->channel->flags & VIDEO_VC_AUDIO)
326 cout <<
" + This channel source has audio" << endl;
327 if (data_->channel->type & VIDEO_TYPE_TV)
328 cout <<
" + This channel source is a TV input" << endl;
329 if (data_->channel->type & VIDEO_TYPE_CAMERA)
330 cout <<
" + This channel source is a Camera input" << endl;
333 <<
"FRAME BUFFER INFO" << endl
334 <<
"===========================================================================" << endl;
336 cout <<
" Base Physical Address: " << data_->vbuffer.base << endl;
337 cout <<
" Height of Frame Buffer: " << data_->vbuffer.height << endl;
338 cout <<
" Width of Frame Buffer: " << data_->vbuffer.width << endl;
339 cout <<
" Depth of Frame Buffer: " << data_->vbuffer.depth << endl;
340 cout <<
" Bytes Per Line: " << data_->vbuffer.bytesperline << endl;
361 V4L1Camera::capture()
363 if (capture_method == READ) {
364 int len = read(dev, frame_buffer, data_->window.width * data_->window.height * RGB_PIXEL_SIZE);
366 throw Exception(
"V4L1Cam: Could not capture frame");
370 (
struct video_mmap *)malloc(data_->captured_frame_buffer.frames *
sizeof(
struct video_mmap));
373 data_->buf_v4l[0].format = data_->picture.palette;
374 data_->buf_v4l[0].frame = 0;
375 data_->buf_v4l[0].width = data_->window.width;
376 data_->buf_v4l[0].height = data_->window.height;
378 if (ioctl(dev, VIDIOCMCAPTURE, &(data_->buf_v4l[0])) == -1) {
379 throw Exception(
"V4L1Cam: Could not capture frame (VIDIOCMCAPTURE)");
383 if (ioctl(dev, VIDIOCSYNC, &Frame) == -1) {
384 throw Exception(
"V4L1Cam: Could not capture frame (VIDIOCSYNC)");
390 V4L1Camera::dispose_buffer()
392 if (capture_method == MMAP) {
393 if (data_->buf_v4l != NULL) {
394 free(data_->buf_v4l);
395 data_->buf_v4l = NULL;
397 munmap(frame_buffer, data_->captured_frame_buffer.size);
408 V4L1Camera::buffer_size()
410 return colorspace_buffer_size(RGB, data_->window.width, data_->window.height);
422 V4L1Camera::pixel_width()
425 return data_->window.width;
427 throw Exception(
"V4L1Cam::pixel_width(): Camera not opened");
432 V4L1Camera::pixel_height()
435 return data_->window.height;
437 throw Exception(
"V4L1Cam::pixel_height(): Camera not opened");
442 V4L1Camera::colorspace()
459 V4L1Camera::set_image_number(
unsigned int n)
Base class for exceptions in Fawkes.
Expected parameter is missing.
bool has(std::string s) const
Check if an parameter was given.
std::string get(std::string s) const
Get the value of the given parameter.
Fawkes library namespace.