Re: My first V4l app.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



Hi,
  What you are trying code is V4l2 application rather than V4l. Below u
can find the code which will help u to grab a image and store the same
in ".ppm" format using V4l. You replace the V4l APIs with V4l2
accordingly.

// Capturing frames from tv tuner card

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/videodev.h> 
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

char* deviceName = "/dev/video0";
int deviceHandle = 0;
int i; // temporary counter

struct video_capability capability;
struct video_channel queryChannel;
struct video_channel selectedChannel;
struct video_window captureWindow;
struct video_picture imageProperties;
struct video_mbuf memoryBuffer;
struct video_mmap* mmaps;

char* memoryMap;
int channelNumber = 0;
int width = 320;
int height = 240;
int depth;
int palette;
int bufferIndex;

char* NextFrame(); // function prototype

int main()
{
        // open the device
        deviceName = "/dev/video0";
        deviceHandle = open (deviceName, O_RDWR);
        if (deviceHandle == -1) // could not open device
        {
         // printf ("Could not open device %s - %s\n", deviceName,
sys_errlist[errno]);
	 printf ("Could not open device %s - %s\n", deviceName,
strerror(errno));
         return -1;
       }
       // get device capabilities
       if (ioctl (deviceHandle, VIDIOCGCAP, &capability) == -1)
        {       // query failed
         printf ("could not obtain device capabilities\n");
         return -1;
        }
	printf("Number of channels = %d \n",capability.channels);
        if ((capability.type & VID_TYPE_CAPTURE) == 0)
        {       // this device cannot capture video to memory, exit
         printf ("this device cannot capture video to memory\n");
         return -1;
        }
	if ((capability.type & VID_TYPE_OVERLAY))
        {       // this device cannot capture video to memory, exit
         printf ("Can overlay its image onto the frame buffer\n");
        }
        // enumerate and print out the channels
        printf ("Select a channel:\n");
        i = 0;
        while (i < capability.channels)
        {
         queryChannel.channel = i;
         if (ioctl (deviceHandle, VIDIOCGCHAN, &queryChannel) != -1)
          { // ioctl success, queryChannel contains information about
this channel
            printf ("%d. %s\n", queryChannel.channel,
queryChannel.name);
          }
          ++ i;
        }
        // have the user select a channel
        printf (": ");
        fflush (stdout);
        scanf ("%d", &channelNumber);
        selectedChannel.channel = channelNumber; // set the selected
channel
        //selectedChannel.norm = VIDEO_MODE_NTSC;
	selectedChannel.norm = VIDEO_MODE_PAL;
        if (ioctl (deviceHandle, VIDIOCSCHAN, &selectedChannel) == -1)
        { // could not set the selected channel
          printf ("Could not set channel #%d\nNot a fatal error.",
channelNumber);
        }
        // set the desired width and height
        if ((capability.type & VID_TYPE_SCALES) != 0)
         { // supports the ability to scale captured images have the
user enter a desired width
          printf ("Enter the desired width (e.g. 320): ");
          fflush (stdout);
          scanf ("%d", &width);
          printf ("Enter the desired height (e.g. 240): ");
          fflush (stdout);
          scanf ("%d", &height);
          captureWindow.x = 0;
          captureWindow.y = 0;
          captureWindow.width = width;
          captureWindow.height = height;
          captureWindow.chromakey = 0;
          captureWindow.flags = 0;
          captureWindow.clips = 0;
          captureWindow.clipcount = 0;
          if (ioctl (deviceHandle, VIDIOCSWIN, &captureWindow) == -1)
           { // could not set window values for capture
              printf ("Could not set desired dimensions\nNot a fatal
error.\n");
           }
         }
        // retrieve the actual width and height of the capturing images
        if (ioctl (deviceHandle, VIDIOCGWIN, &captureWindow) == -1)
        { // could not obtain specifics of capture window
          printf ("Could not obtain capture window dimensions.\n");
        }
        width = captureWindow.width;
        height = captureWindow.height;
        printf ("Capturing dimensions are : %d, %d\n", width, height);
        // request that we capture to 24bit RGB
        // get image properties
        if (ioctl (deviceHandle, VIDIOCGPICT, &imageProperties) != -1)
         { // successfully retrieved the default image properties
          // the following values are for requesting 24bit RGB
          imageProperties.depth = 24;
          imageProperties.palette = VIDEO_PALETTE_RGB24;
          if (ioctl (deviceHandle, VIDIOCSPICT, &imageProperties) == -1)
           {       // failed to set the image properties
            printf ("Could not set the video depth and palette.\nPerhaps
not a fatal error.\n");
           }
         }
        // verify that the requested capture pixel depth and palette
succeeded
        if (ioctl (deviceHandle, VIDIOCGPICT, &imageProperties) == -1)
        {       // failed to retrieve default image properties
                printf ("Failed to retrieve the video depth and
palette.\n");
                return -1;
        }
        depth = imageProperties.depth;
        palette = imageProperties.palette;
        if ((depth != 24) || (palette != VIDEO_PALETTE_RGB24))
        { // not a format our program supports
          printf ("Format is not 24bit RGB.\n");
          return -1;
        }
        printf ("Capture depth is 24bit RGB\n");
        // obtain memory about capture space
        if (ioctl (deviceHandle, VIDIOCGMBUF, &memoryBuffer) == -1)
        { // failed to retrieve information about capture memory space
          printf ("Failed to retrieve information about MMIO space.\n");
          return -1;
        }
        // obtain memory mapped area
        memoryMap = (char*)mmap (0, // start address
	                         memoryBuffer.size, // length in bytes
				 PROT_READ | PROT_WRITE, // memory protection
	                         MAP_SHARED, // type of the  mapped  object
				 deviceHandle, // file descriptor
				 0 // offset of the buffer in device memory
				 );
	printf("memoryMap = %u \n", memoryMap);
        if ((int)memoryMap == -1)
         { // failed to retrieve pointer to memory mapped area
           printf ("Failed to obtain MMIO space.\n");
           return -1;
         }
        // allocate structures
        mmaps = (struct video_mmap*)(malloc (memoryBuffer.frames *
sizeof (struct video_mmap)));
        // fill out the fields
	printf("No of frames = %d \n", memoryBuffer.frames);
        i = 0;
        while (i < memoryBuffer.frames)
         {
           mmaps[i].frame = i;
           mmaps[i].width = width;
           mmaps[i].height = height;
           mmaps[i].format = palette;
           ++ i;
         }
        // request capture to each buffer except the last one
        i = 0;
        while (i < (memoryBuffer.frames-1))
        {
         if (ioctl (deviceHandle, VIDIOCMCAPTURE, &mmaps[i]) == -1)
          {       // capture request failed
          }
         ++ i;
        }
        // set our index to the last buffer
        bufferIndex = memoryBuffer.frames-1;
        // capture and write out frames
        printf ("Capture is ready; capturing 10 images.\n");
        int i = 0;
        while (i < 10)
         {
           char* frame = NextFrame();
           char fname[80]; // write out PPM file
           sprintf (fname, "output%02d.ppm", i);
           printf ("Writing out PPM file %s\n", fname);
           FILE* fp;
           if ((fp = fopen (fname, "w")) == NULL)
            {
             printf ("Could not open file %s for writing.\n", fname);
             return -1;
            }
           fprintf (fp, "P6\n%d %d\n255\n", width, height);
           int n = width * height;
	   int index=0;
           for (index;index < n;++ index)
             {
	       frame[index*3+2]=0;
	       frame[index*3+1]=255;
	       frame[index*3+2]=0;
               putc (frame[index*3+2], fp);
               putc (frame[index*3+1], fp);
               putc (frame[index*3+0], fp);
             }
           fflush (fp);
           fclose (fp);
           ++ i;
	 }
        printf ("Use 'xv output*' to view output.\n");
        free (mmaps); // free the video_mmap structures
        munmap (memoryMap, memoryBuffer.size); // unmap the capture
memory
        close (deviceHandle); // close the device
        return 0;
}

char* NextFrame()
{
  // send a request to begin capturing to the currently indexed buffer
  if (ioctl (deviceHandle, VIDIOCMCAPTURE, &mmaps[bufferIndex]) == -1)
   {       // capture request failed
   }
  ++ bufferIndex; // move bufferIndex to the next frame
  if (bufferIndex == memoryBuffer.frames)
   { // bufferIndex is indexing beyond the last buffer
    // set it to index the first buffer
    bufferIndex = 0;
   }
   // wait for the currently indexed frame to complete capture
  if (ioctl (deviceHandle, VIDIOCSYNC, &mmaps[bufferIndex]) == -1)
   { // sync request failed
   }
   // return the address of the frame data for the current buffer index
  return (memoryMap + memoryBuffer.offsets[bufferIndex]);
}

Try this one out. All the best.

On Tue, 2003-12-30 at 07:04, Garrett Kajmowicz wrote:
> I'm trying to write my first v4l application.  The goal right now is to simply 
> do individual image capturing.  As you might suspect, it isn't working 
> properly.
> 
> This is being done on a Hauppauge tuner card with the bt878 chipset.
> 
> So far, I am able to open the device, set the video input and set the video 
> standard to V4L2_STD_NTSC_M;
> 
> My next step is to try and set the capture format
> 
> My code is roughly:
> 
> v4l2_format retval
> retval.fmt.pix.sizeimage=0;
> retval.fmt.pix.bytesperline = 0;
> retval.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
> retval.fmt.pix.width = 640;
> retval.fmt.pix.height = 480;
> retval.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
> retval.fmt.pix.field = V4L2_FIELD_ANY;
> retval.fmt.pix.priv = 0;
> 
> Unfortunately, the ioctl fails with EINVAL
> 
> Where am I going wrong?
> 
> Thanks for the help.
> 
> -	Garrett Kajmowicz
> 
> 
> --
> video4linux-list mailing list
> Unsubscribe mailto:video4linux-list-request@xxxxxxxxxx?subject=unsubscribe
> https://www.redhat.com/mailman/listinfo/video4linux-list
-- 
S.Suriya Mohan, MCA.
Software Engineer,
Insys Technologies,
Coimbatore-641001.
India.

There is no substitution for hard work.





[Index of Archives]     [Linux DVB]     [Video Disk Recorder]     [Asterisk]     [Photo]     [DCCP]     [Netdev]     [Xorg]     [Util Linux NG]     [Xfree86]     [Free Photo Albums]     [Fedora Users]     [Fedora Women]     [ALSA Users]     [ALSA Devel]     [Linux USB]

Powered by Linux