V4LCapture.cpp
Go to the documentation of this file.
00001 // ****************************************************************************
00002 // This file is part of the Integrating Vision Toolkit (IVT).
00003 //
00004 // The IVT is maintained by the Karlsruhe Institute of Technology (KIT)
00005 // (www.kit.edu) in cooperation with the company Keyetech (www.keyetech.de).
00006 //
00007 // Copyright (C) 2014 Karlsruhe Institute of Technology (KIT).
00008 // All rights reserved.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are met:
00012 //
00013 // 1. Redistributions of source code must retain the above copyright
00014 //    notice, this list of conditions and the following disclaimer.
00015 //
00016 // 2. Redistributions in binary form must reproduce the above copyright
00017 //    notice, this list of conditions and the following disclaimer in the
00018 //    documentation and/or other materials provided with the distribution.
00019 //
00020 // 3. Neither the name of the KIT nor the names of its contributors may be
00021 //    used to endorse or promote products derived from this software
00022 //    without specific prior written permission.
00023 //
00024 // THIS SOFTWARE IS PROVIDED BY THE KIT AND CONTRIBUTORS “AS IS” AND ANY
00025 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00026 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00027 // DISCLAIMED. IN NO EVENT SHALL THE KIT OR CONTRIBUTORS BE LIABLE FOR ANY
00028 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00029 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00031 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00032 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00033 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034 // ****************************************************************************
00035 // ****************************************************************************
00036 // Filename:  V4LCapture.cpp
00037 // Author:    Alexander Kaspar, Tilo Gockel, Pedram Azad
00038 // Date:      19.03.2009
00039 // ****************************************************************************
00040 
00041 
00042 // ****************************************************************************
00043 // Includes
00044 // ****************************************************************************
00045 
00046 #include "V4LCapture.h"
00047 
00048 #include <sys/types.h>
00049 #include <sys/stat.h>
00050 #include <sys/ioctl.h>
00051 #include <sys/mman.h>
00052 
00053 #include <fcntl.h>
00054 #include <unistd.h>
00055 #include <stdio.h>
00056 #include <errno.h>
00057 #include <stdlib.h>
00058 #include <string.h>
00059 
00060 
00061 
00062 // ****************************************************************************
00063 // Constructor / Destructor
00064 // ****************************************************************************
00065 
00066 CV4LCapture::CV4LCapture(const char *pDeviceName, int nChannel, CVideoCaptureInterface::VideoMode videoMode)
00067 {
00068         m_sDeviceName = "";
00069         m_sDeviceName += pDeviceName;
00070         
00071         m_nChannel = nChannel;
00072         m_videoMode = videoMode;
00073 
00074         width = -1;
00075         height = -1;
00076 }
00077 
00078 CV4LCapture::~CV4LCapture()
00079 {
00080 }
00081 
00082 
00083 // ****************************************************************************
00084 // Methods
00085 // ****************************************************************************
00086 
00087 bool CV4LCapture::OpenCamera()
00088 {
00089         video_capability capability;
00090         video_channel queryChannel;
00091         video_channel selectedChannel;
00092         video_window captureWindow;
00093         video_picture imageProperties;
00094         v4l2_capability cap;
00095         
00096 
00097         selectedChannel.channel = m_nChannel;
00098 
00099         if ((m_nDeviceHandle = open(m_sDeviceName.c_str(), O_RDWR)) == -1)
00100         {       // could not open device
00101                 printf ("Could not open device %s - %s\n", m_sDeviceName.c_str(), strerror(errno));
00102                 return false;
00103         }
00104 
00105         // get device capabilities
00106         if (ioctl(m_nDeviceHandle, VIDIOCGCAP, &capability) == -1)
00107         {       // query failed
00108                 printf ("could not obtain device capabilities\n");
00109                 return false;
00110         }
00111 
00112         if ((capability.type & VID_TYPE_CAPTURE) == 0)
00113         {       // this device cannot capture video to memory, exit
00114                 printf ("this device cannot capture video to memory\n");
00115                 return false;
00116         }
00117 
00118         // enumerate and print out the channels
00119         int i = 0;
00120         while (i < capability.channels)
00121         {
00122                 queryChannel.channel = i;
00123                 if (ioctl (m_nDeviceHandle, VIDIOCGCHAN, &queryChannel) != -1)
00124                 {       // ioctl success, queryChannel contains information about this channel
00125                         printf ("%d. %s\n", queryChannel.channel, queryChannel.name);
00126                 }
00127 
00128                 i++;
00129         }
00130 
00131         selectedChannel.norm = VIDEO_MODE_NTSC;
00132         if (ioctl (m_nDeviceHandle, VIDIOCSCHAN, &selectedChannel) == -1)
00133         {
00134                 // could not set the selected channel
00135                 printf ("Could not set channel #%d\nNot a fatal error.", selectedChannel.channel);
00136         }
00137 
00138         // set width and height attributes
00139         switch (m_videoMode)
00140         {
00141                 case e320x240: width = 320; height = 240; break;
00142                 case e640x480: width = 640; height = 480; break;
00143                 case e800x600: width = 800; height = 600; break;
00144                 case e768x576: width = 768; height = 576; break;
00145                 case e1024x768: width = 1024; height = 768; break;
00146                 case e1280x960: width = 1280; height = 960; break;
00147                 default: return false;
00148         }
00149 
00150         // set the desired width and height
00151         if ((capability.type & VID_TYPE_SCALES) != 0)
00152         {       // supports the ability to scale captured images
00153                 captureWindow.x = 0;
00154                 captureWindow.y = 0;
00155                 captureWindow.width = width;
00156                 captureWindow.height = height;
00157                 captureWindow.chromakey = 0;
00158                 captureWindow.flags = 0;
00159                 captureWindow.clips = 0;
00160                 captureWindow.clipcount = 0;
00161 
00162                 if (ioctl (m_nDeviceHandle, VIDIOCSWIN, &captureWindow) == -1)
00163                 {
00164                         // could not set window values for capture
00165                         printf ("Could not set desired dimensions\nNot a fatal error.\n");
00166                 }
00167         }
00168         
00169         // retrieve the actual width and height of the capturing images
00170         if (ioctl(m_nDeviceHandle, VIDIOCGWIN, &captureWindow) == -1)
00171         {       // could not obtain specifics of capture window
00172                 printf ("Could not obtain capture window dimensions.\n");
00173         }
00174         width = captureWindow.width;
00175         height = captureWindow.height;
00176         printf ("Capturing dimensions are : %d, %d\n", width, height);
00177 
00178         // request that we capture to 24bit RGB
00179 
00180         // get image properties
00181         if (ioctl (m_nDeviceHandle, VIDIOCGPICT, &imageProperties) != -1)
00182         {       // successfully retrieved the default image properties
00183 
00184                 // the following values are for requesting 24bit RGB
00185                 imageProperties.depth = 24;
00186                 imageProperties.palette = VIDEO_PALETTE_RGB24;
00187                 if (ioctl (m_nDeviceHandle, VIDIOCSPICT, &imageProperties) == -1)
00188                 {       // failed to set the image properties
00189                         printf ("Could not set the video depth and palette.\nPerhaps not a fatal error.\n");
00190                 }
00191         }
00192 
00193         // verify that the requested capture pixel depth and palette succeeded
00194         if (ioctl (m_nDeviceHandle, VIDIOCGPICT, &imageProperties) == -1)
00195         {       // failed to retrieve default image properties
00196                 printf ("Failed to retrieve the video depth and palette.\n");
00197                 return false;
00198         }
00199 
00200         if ((imageProperties.depth != 24) || (imageProperties.palette != VIDEO_PALETTE_RGB24))
00201         {       // not a format our program supports
00202                 printf ("Format is not 24bit RGB.\n");
00203                 return false;
00204         }
00205         
00206         printf ("Capture depth is 24bit RGB\n");
00207 
00208         // obtain memory about capture space
00209         if (ioctl (m_nDeviceHandle, VIDIOCGMBUF, &memoryBuffer) == -1)
00210         {       // failed to retrieve information about capture memory space
00211                 printf ("Failed to retrieve information about MMIO space.\n");
00212                 return false;
00213         }
00214 
00215 
00216         // obtain memory mapped area
00217         memoryMap = (char*)mmap (0, memoryBuffer.size, PROT_READ | PROT_WRITE, MAP_SHARED, m_nDeviceHandle, 0);
00218         if ((intptr_t) memoryMap == -1)
00219         {       // failed to retrieve pointer to memory mapped area
00220                 printf ("Failed to obtain MMIO space.\n");
00221                 return false;
00222         }
00223 
00224 
00225         printf("Allocating structures...\n");
00226         // allocate structures
00227         mmaps = (struct video_mmap*)(malloc (memoryBuffer.frames * sizeof (struct video_mmap)));
00228 
00229         // fill out the fields
00230         i = 0;
00231         while (i < memoryBuffer.frames)
00232         {
00233                 mmaps[i].frame = i;
00234                 mmaps[i].width = captureWindow.width;
00235                 mmaps[i].height = captureWindow.height;
00236                 mmaps[i].format = imageProperties.palette;
00237                 ++ i;
00238         }
00239 
00240         printf("Requesting capture buffers...\n");
00241         // request capture to each buffer except the last one
00242         i = 0;
00243         while (i < (memoryBuffer.frames-1))
00244         {
00245                 if (ioctl (m_nDeviceHandle, VIDIOCMCAPTURE, &mmaps[i]) == -1)
00246                 {       // capture request failed
00247                 }
00248                 ++ i;
00249         }
00250 
00251         printf("Set index buffer...\n");
00252         // set our index to the last buffer
00253         bufferIndex = memoryBuffer.frames-1;
00254 
00255         return true;
00256 }
00257 
00258 bool CV4LCapture::CaptureImage(CByteImage **ppImages)
00259 {
00260         // send a request to begin capturing to the currently indexed buffer
00261         if (ioctl (m_nDeviceHandle, VIDIOCMCAPTURE, &mmaps[bufferIndex]) == -1)
00262         {
00263                        // capture request failed
00264         }
00265 
00266         // move bufferIndex to the next frame
00267         if (++bufferIndex == memoryBuffer.frames)
00268         {
00269                 // bufferIndex is indexing beyond the last buffer
00270                 // set it to index the first buffer
00271                 bufferIndex = 0;
00272         }
00273 
00274         // wait for the currently indexed frame to complete capture
00275         if (ioctl(m_nDeviceHandle, VIDIOCSYNC, &mmaps[bufferIndex]) == -1)
00276         {       // sync request failed
00277         }
00278 
00279         // return the address of the frame data for the current buffer index
00280         const unsigned char *frame = (const unsigned char *) (memoryMap + memoryBuffer.offsets[bufferIndex]);
00281         unsigned char *output = ppImages[0]->pixels;
00282 
00283         const int nBytes = ppImages[0]->width * ppImages[0]->height * 3;
00284 
00285         for (int i = 0; i < nBytes; i += 3)
00286         {
00287                 output[i] = frame[i + 2];
00288                 output[i + 1] = frame[i + 1];
00289                 output[i + 2] = frame[i];
00290         }
00291 
00292         return true;
00293 }
00294 
00295 void CV4LCapture::CloseCamera()
00296 {
00297         // free the video_mmap structures
00298         free (mmaps);
00299 
00300         // unmap the capture memory
00301         munmap (memoryMap, memoryBuffer.size);
00302 
00303         // close the device
00304         close (m_nDeviceHandle);
00305 }


asr_ivt
Author(s): Allgeyer Tobias, Hutmacher Robin, Kleinert Daniel, Meißner Pascal, Scholz Jonas, Stöckle Patrick
autogenerated on Thu Jun 6 2019 21:46:58