24 #include <core/exception.h> 25 #include <core/exceptions/software.h> 27 #include <fvcams/v4l1.h> 28 #include <fvutils/color/colorspaces.h> 29 #include <fvutils/color/rgb.h> 30 #include <fvutils/system/camargp.h> 35 #include <sys/ioctl.h> 40 #include <linux/types.h> 45 #include <sys/types.h> 46 #include <linux/videodev.h> 62 V4L1CameraData(
const char *device_name)
64 this->device_name = strdup(device_name);
76 struct video_capability capabilities;
77 struct video_buffer vbuffer;
78 struct video_window window;
79 struct video_channel *channel;
80 struct video_picture picture;
81 struct video_tuner *tuner;
82 struct video_audio audio;
83 struct video_mbuf captured_frame_buffer;
84 struct video_mmap *buf_v4l;
96 V4L1Camera::V4L1Camera(
const char *device_name)
98 started = opened =
false;
99 __data =
new V4L1CameraData(device_name);
111 started = opened =
false;
112 if ( cap->
has(
"device") ) {
113 __data =
new V4L1CameraData(cap->
get(
"device").c_str());
125 V4L1Camera::V4L1Camera(
const char *device_name,
int dev)
127 started = opened =
false;
128 __data =
new V4L1CameraData(device_name);
132 if ( (ioctl(dev, VIDIOCGCAP, &(__data->capabilities))) == -1 ) {
133 throw Exception(
"V4L1Cam: Could not get capabilities");
141 V4L1Camera::~V4L1Camera()
152 dev = ::open(__data->device_name, O_RDWR);
154 throw Exception(
"V4L1Cam: Could not open device");
158 if ( (ioctl(dev, VIDIOCGCAP, &(__data->capabilities))) == -1 ) {
159 throw Exception(
"V4L1Cam: Could not get capabilities");
170 V4L1Camera::post_open()
173 if ( (ioctl(dev, VIDIOCGWIN, &__data->window)) == -1) {
174 throw Exception(
"V4L1Cam: Could not get window information");
178 if ( (ioctl(dev, VIDIOCGPICT, &__data->picture)) == -1) {
179 throw Exception(
"V4L1Cam: Could not get window information");
184 __data->channel = (
struct video_channel*)malloc(
sizeof(
struct video_channel)*(__data->capabilities.channels+1));
185 for(
int ch = 0; ch < __data->capabilities.channels; ch++) {
186 __data->channel[ch].norm = 0;
187 if ( (ioctl(dev, VIDIOCSCHAN, &__data->channel[ch])) == -1) {
188 printf(
"V4L1Cam: Could not get channel information for channel %i: %s", ch, strerror(errno));
193 if (ioctl (dev, VIDIOCGMBUF, __data->captured_frame_buffer) == -1) {
194 capture_method = READ;
195 frame_buffer = (
unsigned char *)malloc(__data->window.width * __data->window.height * RGB_PIXEL_SIZE);
197 capture_method = MMAP;
198 frame_buffer = (
unsigned char*)mmap (0, __data->captured_frame_buffer.size, PROT_READ | PROT_WRITE, MAP_SHARED, dev, 0);
199 if ((
unsigned char *) -1 == (
unsigned char *)frame_buffer) {
200 throw Exception(
"V4L1Cam: Cannot initialize mmap region");
204 __data->buf_v4l = NULL;
216 throw Exception(
"V4L1Cam: Trying to start closed cam!");
231 V4L1Camera::print_info()
234 if (! opened)
return;
236 cout << endl <<
"CAPABILITIES" << endl
237 <<
"===========================================================================" << endl;
239 if(__data->capabilities.type & VID_TYPE_CAPTURE)
240 cout <<
" + Can capture to memory" << endl;
241 if(__data->capabilities.type & VID_TYPE_TUNER)
242 cout <<
" + Has a tuner of some form" << endl;
243 if(__data->capabilities.type & VID_TYPE_TELETEXT)
244 cout <<
" + Has teletext capability" << endl;
245 if(__data->capabilities.type & VID_TYPE_OVERLAY)
246 cout <<
" + Can overlay its image onto the frame buffer" << endl;
247 if(__data->capabilities.type & VID_TYPE_CHROMAKEY)
248 cout <<
" + Overlay is Chromakeyed" << endl;
249 if(__data->capabilities.type & VID_TYPE_CLIPPING)
250 cout <<
" + Overlay clipping is supported" << endl;
251 if(__data->capabilities.type & VID_TYPE_FRAMERAM)
252 cout <<
" + Overlay overwrites frame buffer memory" << endl;
253 if(__data->capabilities.type & VID_TYPE_SCALES)
254 cout <<
" + The hardware supports image scaling" << endl;
255 if(__data->capabilities.type & VID_TYPE_MONOCHROME)
256 cout <<
" + Image capture is grey scale only" << endl;
257 if(__data->capabilities.type & VID_TYPE_SUBCAPTURE)
258 cout <<
" + Can subcapture" << endl;
261 cout <<
" Number of Channels ='" << __data->capabilities.channels <<
"'" << endl;
262 cout <<
" Number of Audio Devices ='" << __data->capabilities.audios <<
"'" << endl;
263 cout <<
" Maximum Capture Width ='" << __data->capabilities.maxwidth <<
"'" << endl;
264 cout <<
" Maximum Capture Height ='" << __data->capabilities.maxheight <<
"'" << endl;
265 cout <<
" Minimum Capture Width ='" << __data->capabilities.minwidth <<
"'" << endl;
266 cout <<
" Minimum Capture Height ='" << __data->capabilities.minheight <<
"'" << endl;
271 cout << endl <<
"CAPTURE WINDOW INFO" << endl
272 <<
"===========================================================================" << endl;
274 cout <<
" X Coord in X window Format: " << __data->window.x << endl;
275 cout <<
" Y Coord in X window Format: " << __data->window.y << endl;
276 cout <<
" Width of the Image Capture: " << __data->window.width << endl;
277 cout <<
" Height of the Image Capture: " << __data->window.height << endl;
278 cout <<
" ChromaKey: " << __data->window.chromakey << endl;
283 cout << endl <<
"DEVICE PICTURE INFO" << endl
284 <<
"===========================================================================" << endl;
286 cout <<
" Picture Brightness: " << __data->picture.brightness << endl;
287 cout <<
" Picture Hue: " << __data->picture.hue << endl;
288 cout <<
" Picture Colour: " << __data->picture.colour << endl;
289 cout <<
" Picture Contrast: " << __data->picture.contrast << endl;
290 cout <<
" Picture Whiteness: " << __data->picture.whiteness << endl;
291 cout <<
" Picture Depth: " << __data->picture.depth << endl;
292 cout <<
" Picture Palette: " << __data->picture.palette <<
" (";
294 if(__data->picture.palette == VIDEO_PALETTE_GREY)
295 cout <<
"VIDEO_PALETTE_GRAY";
296 if(__data->picture.palette == VIDEO_PALETTE_HI240)
297 cout <<
"VIDEO_PALETTE_HI240";
298 if(__data->picture.palette == VIDEO_PALETTE_RGB565)
299 cout <<
"VIDEO_PALETTE_RGB565";
300 if(__data->picture.palette == VIDEO_PALETTE_RGB555)
301 cout <<
"VIDEO_PALETTE_RGB555";
302 if(__data->picture.palette == VIDEO_PALETTE_RGB24)
303 cout <<
"VIDEO_PALETTE_RGB24";
304 if(__data->picture.palette == VIDEO_PALETTE_RGB32)
305 cout <<
"VIDEO_PALETTE_RGB32";
306 if(__data->picture.palette == VIDEO_PALETTE_YUV422)
307 cout <<
"VIDEO_PALETTE_YUV422";
308 if(__data->picture.palette == VIDEO_PALETTE_YUYV)
309 cout <<
"VIDEO_PALETTE_YUYV";
310 if(__data->picture.palette == VIDEO_PALETTE_UYVY)
311 cout <<
"VIDEO_PALETTE_UYVY";
312 if(__data->picture.palette == VIDEO_PALETTE_YUV420)
313 cout <<
"VIDEO_PALETTE_YUV420";
314 if(__data->picture.palette == VIDEO_PALETTE_YUV411)
315 cout <<
"VIDEO_PALETTE_YUV411";
316 if(__data->picture.palette == VIDEO_PALETTE_RAW)
317 cout <<
"VIDEO_PALETTE_RAW";
318 if(__data->picture.palette == VIDEO_PALETTE_YUV422P)
319 cout <<
"VIDEO_PALETTE_YUV422P";
320 if(__data->picture.palette == VIDEO_PALETTE_YUV411P)
321 cout <<
"VIDEO_PALETTE_YUV411P";
327 cout << endl <<
"VIDEO SOURCE INFO" << endl
328 <<
"===========================================================================" << endl;
330 cout <<
" Channel Number or Video Source Number: " << __data->channel->channel << endl;
331 cout <<
" Channel Name: " << __data->channel->name << endl;
332 cout <<
" Number of Tuners for this source: " << __data->channel->tuners << endl;
333 cout <<
" Channel Norm: " << __data->channel->norm << endl;
334 if(__data->channel->flags & VIDEO_VC_TUNER)
335 cout <<
" + This channel source has tuners" << endl;
336 if(__data->channel->flags & VIDEO_VC_AUDIO)
337 cout <<
" + This channel source has audio" << endl;
338 if(__data->channel->type & VIDEO_TYPE_TV)
339 cout <<
" + This channel source is a TV input" << endl;
340 if(__data->channel->type & VIDEO_TYPE_CAMERA)
341 cout <<
" + This channel source is a Camera input" << endl;
346 cout << endl <<
"FRAME BUFFER INFO" << endl
347 <<
"===========================================================================" << endl;
349 cout <<
" Base Physical Address: " << __data->vbuffer.base << endl;
350 cout <<
" Height of Frame Buffer: " << __data->vbuffer.height << endl;
351 cout <<
" Width of Frame Buffer: " << __data->vbuffer.width << endl;
352 cout <<
" Depth of Frame Buffer: " << __data->vbuffer.depth << endl;
353 cout <<
" Bytes Per Line: " << __data->vbuffer.bytesperline << endl;
378 V4L1Camera::capture()
381 if (capture_method == READ) {
382 int len = read(dev, frame_buffer, __data->window.width * __data->window.height * RGB_PIXEL_SIZE);
384 throw Exception(
"V4L1Cam: Could not capture frame");
388 __data->buf_v4l = (
struct video_mmap*)malloc(__data->captured_frame_buffer.frames *
sizeof(
struct video_mmap));
391 __data->buf_v4l[0].format = __data->picture.palette;
392 __data->buf_v4l[0].frame = 0;
393 __data->buf_v4l[0].width = __data->window.width;
394 __data->buf_v4l[0].height = __data->window.height;
396 if (ioctl (dev, VIDIOCMCAPTURE, &(__data->buf_v4l[0])) == -1) {
397 throw Exception(
"V4L1Cam: Could not capture frame (VIDIOCMCAPTURE)");
401 if (ioctl (dev, VIDIOCSYNC, &Frame) == -1) {
402 throw Exception(
"V4L1Cam: Could not capture frame (VIDIOCSYNC)");
409 V4L1Camera::dispose_buffer()
411 if (capture_method == MMAP) {
412 if (__data->buf_v4l != NULL) {
413 free(__data->buf_v4l);
414 __data->buf_v4l = NULL;
416 munmap(frame_buffer, __data->captured_frame_buffer.size);
428 V4L1Camera::buffer_size()
430 return colorspace_buffer_size(RGB, __data->window.width, __data->window.height);
442 V4L1Camera::pixel_width()
445 return __data->window.width;
447 throw Exception(
"V4L1Cam::pixel_width(): Camera not opened");
452 V4L1Camera::pixel_height()
455 return __data->window.height;
457 throw Exception(
"V4L1Cam::pixel_height(): Camera not opened");
463 V4L1Camera::colorspace()
483 V4L1Camera::set_image_number(
unsigned int n)
Fawkes library namespace.
bool has(std::string s) const
Check if an parameter was given.
Base class for exceptions in Fawkes.
std::string get(std::string s) const
Get the value of the given parameter.
Expected parameter is missing.