From 2aecae09eb08f5caeee0e22034e8008665fb2524 Mon Sep 17 00:00:00 2001 From: schodet Date: Sat, 1 May 2004 14:29:59 +0000 Subject: Add: Video4Linux. --- 2004/i/nono/src/video4linux/Makefile.defs | 9 ++ 2004/i/nono/src/video4linux/test_video4linux.cc | 85 ++++++++++++ 2004/i/nono/src/video4linux/video4linux.cc | 164 ++++++++++++++++++++++++ 2004/i/nono/src/video4linux/video4linux.h | 66 ++++++++++ 4 files changed, 324 insertions(+) create mode 100644 2004/i/nono/src/video4linux/Makefile.defs create mode 100644 2004/i/nono/src/video4linux/test_video4linux.cc create mode 100644 2004/i/nono/src/video4linux/video4linux.cc create mode 100644 2004/i/nono/src/video4linux/video4linux.h (limited to '2004') diff --git a/2004/i/nono/src/video4linux/Makefile.defs b/2004/i/nono/src/video4linux/Makefile.defs new file mode 100644 index 0000000..6a98a80 --- /dev/null +++ b/2004/i/nono/src/video4linux/Makefile.defs @@ -0,0 +1,9 @@ +TARGETS += test_video4linux +LIBS += video4linux.a +test_video4linux_SOURCES = test_video4linux.cc video4linux.a date.a image.a +video4linux_a_SOURCES = video4linux.cc + +test_video4linux: $(test_video4linux_SOURCES:%.cc=%.o) + +video4linux.a: ${video4linux_a_SOURCES:%.cc=video4linux.a(%.o)} + diff --git a/2004/i/nono/src/video4linux/test_video4linux.cc b/2004/i/nono/src/video4linux/test_video4linux.cc new file mode 100644 index 0000000..23809dd --- /dev/null +++ b/2004/i/nono/src/video4linux/test_video4linux.cc @@ -0,0 +1,85 @@ +// test_video4linux.cc +// nono - programme du robot 2004. {{{ +// +// Copyright (C) 2004 Nicolas Schodet +// +// Robot APB Team/Efrei 2004. +// Web: http://assos.efrei.fr/robot/ +// Email: robot AT efrei DOT fr +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// }}} +#include "video4linux.h" +#include "utils/errno_exception.h" +#include "date/date.h" + +#include +#include +#include +#include +#include +#include +#include + +int +main (int argc, char **argv) +{ + try + { + if (argc != 3) + throw std::runtime_error ("Syntaxe : fichier " + "{rgb|bgr|yuv|yuv422}"); + std::string format (argv[2]); + Video4Linux::ColorSpace cs; + if (format == "rgb") + cs = Video4Linux::rgb; + else if (format == "bgr") + cs = Video4Linux::bgr; + else if (format == "yuv") + cs = Video4Linux::yuv; + else if (format == "yuv422") + cs = Video4Linux::yuv422; + else + throw std::invalid_argument ("Syntaxe : fichier {rgb|yuv422}"); + Video4Linux vid ("/dev/video", cs); + vid.calibrate (); + int w, h; + vid.getSize (w, h); + std::cout << w << ' ' << h << std::endl; + int s; + s = vid.getBufSize (); + unsigned char *buf = new unsigned char[s]; + for (int i = 0; i < 10; ++i) + { + s = vid.read (buf, s); + std::ostringstream os; + os << argv[1] << std::setw (3) << std::setfill ('0') << i << '.' + << argv[2]; + int fd = open (os.str ().c_str (), O_WRONLY | O_CREAT, 0666); + if (fd == -1) + throw errno_exception (argv[1], errno); + write (fd, buf, s); + close (fd); + } + delete[] buf; + return 0; + } + catch (const std::exception &e) + { + std::cerr << e.what () << std::endl; + return 1; + } +} diff --git a/2004/i/nono/src/video4linux/video4linux.cc b/2004/i/nono/src/video4linux/video4linux.cc new file mode 100644 index 0000000..7781b79 --- /dev/null +++ b/2004/i/nono/src/video4linux/video4linux.cc @@ -0,0 +1,164 @@ +// video4linux.cc +// nono - programme du robot 2004. {{{ +// +// Copyright (C) 2004 Nicolas Schodet +// +// Robot APB Team/Efrei 2004. +// Web: http://assos.efrei.fr/robot/ +// Email: robot AT efrei DOT fr +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// }}} +#include "video4linux.h" +#include "utils/errno_exception.h" + +#include +#include +#include +#include +#include +#include //XXX + +/// Constructeur. +Video4Linux::Video4Linux (const char *dev, ColorSpace colorSpace, int + brightness = 58000) + : fd_ (-1), width_ (-1), height_ (-1), colorSpace_ (colorSpace), + rgb_ (colorSpace == ImageLoader::rgb || colorSpace == ImageLoader::bgr), + brightness_ (brightness), contrast_ (32768) +{ + open (dev); +} + +/// Destructeur. +Video4Linux::~Video4Linux (void) +{ + close (); +} + +/// Lit une image, retourne le nombre d'octets lus. +int +Video4Linux::read (void *buf, int size) const +{ + if (buf && size != getBufSize ()) + return 0; + // Mmap. + void *map; + map = mmap (0, bufsize_, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0); + // Capture. + video_mmap mmap; + mmap.format = rgb_ ? VIDEO_PALETTE_RGB24 : VIDEO_PALETTE_YUV422; + mmap.frame = 0; + mmap.width = width_; + mmap.height = height_; + ioctl (fd_, VIDIOCMCAPTURE, &mmap); + // Sync. + ioctl (fd_, VIDIOCSYNC, &mmap); + // Copy. + if (buf) + { + unsigned char *src = reinterpret_cast (map); + unsigned char *dst = reinterpret_cast (buf); + switch (colorSpace_) + { + case ImageLoader::rgb: + for (int i = 0; i < width_ * height_; ++i) + { + *dst++ = src[2]; + *dst++ = src[1]; + *dst++ = src[0]; + src += 3; + } + break; + case ImageLoader::bgr: + memcpy (buf, map, size); + break; + case ImageLoader::yuv: + for (int i = 0; i < width_ * height_ / 2; ++i) + { + *dst++ = src[0]; // Y1 + *dst++ = src[1]; // U + *dst++ = src[3]; // V + *dst++ = src[2]; // Y2 + *dst++ = src[1]; // U + *dst++ = src[3]; // V + src += 4; + } + break; + case ImageLoader::yuv422: + memcpy (buf, map, size); + break; + } + } + // Munmap. + munmap (map, bufsize_); + return size; +} + +/// Calibre la caméra. +void +Video4Linux::calibrate (void) +{ + std::cout << "Calibration... " << std::flush; + for (int i = 0; i < 100; ++i) + read (0, 0); + std::cout << "ok" << std::endl; +} + +/// Ouvre le périphérique. +void +Video4Linux::open (const char *dev) +{ + if (fd_ != -1) + close (); + fd_ = ::open (dev, O_RDWR); + if (fd_ == -1) + throw errno_exception (dev, errno); + // On récupère les cap dont on se tappe ! + video_capability cap; + if (ioctl (fd_, VIDIOCGCAP, &cap) == -1) + throw errno_exception (dev, errno); + // On veut du RGB24. + video_picture pic; + ioctl (fd_, VIDIOCGPICT, &pic); + pic.palette = rgb_ ? VIDEO_PALETTE_RGB24 : VIDEO_PALETTE_YUV422; + bpp_ = colorSpace_ == ImageLoader::yuv422 ? 2 : 3; + pic.brightness = brightness_; + pic.contrast = contrast_; + ioctl (fd_, VIDIOCSPICT, &pic); + // Channel de merde. + video_channel chn; + ioctl (fd_, VIDIOCGCHAN, &chn); + chn.channel = 0; + chn.norm = VIDEO_MODE_PAL; + ioctl (fd_, VIDIOCSCHAN, &chn); + // Récupères les infos sur la camera. + video_window win; + ioctl (fd_, VIDIOCGWIN, &win); + width_ = win.width; + height_ = win.height; + // Initialisation mmap. + video_mbuf mbuf; + ioctl (fd_, VIDIOCGMBUF, &mbuf); + bufsize_ = mbuf.size; +} + +/// Ferme le périphérique. +void +Video4Linux::close (void) +{ + ::close (fd_); +} + diff --git a/2004/i/nono/src/video4linux/video4linux.h b/2004/i/nono/src/video4linux/video4linux.h new file mode 100644 index 0000000..43539ca --- /dev/null +++ b/2004/i/nono/src/video4linux/video4linux.h @@ -0,0 +1,66 @@ +#ifndef video4linux_h +#define video4linux_h +// video4linux.h +// nono - programme du robot 2004. {{{ +// +// Copyright (C) 2004 Nicolas Schodet +// +// Robot APB Team/Efrei 2004. +// Web: http://assos.efrei.fr/robot/ +// Email: robot AT efrei DOT fr +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +// }}} +#include "image/image_loader.h" + +/// Class d'accés à Video4Linux. +class Video4Linux : public ImageLoader +{ + private: + int fd_; + int width_, height_; + int bufsize_; + ImageLoader::ColorSpace colorSpace_; + bool rgb_; + int brightness_, contrast_; + int bpp_; + public: + /// Constructeur. + Video4Linux (const char *dev, ImageLoader::ColorSpace colorSpace, int + brightness = 58000); + /// Destructeur. + ~Video4Linux (void); + /// Récupère la taille de l'image. + void getSize (int &width, int &height) const + { width = width_; height = height_; } + /// Récupère la taille du tampon. + int getBufSize (void) const + { return width_ * height_ * bpp_; } + /// Récupère le format de l'image. + ImageLoader::ColorSpace getColorSpace (void) const + { return colorSpace_; } + /// Lit une image, retourne le nombre d'octets lus. + int read (void *buf, int size) const; + /// Calibre la caméra. + void calibrate (void); + protected: + /// Ouvre le périphérique. + void open (const char *dev); + /// Ferme le périphérique. + void close (void); +}; + +#endif // video4linux_h -- cgit v1.2.3