Capturing video streams continuously

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



Hi all, 
  From the code given below, I can able to capture more than one image 
from "/dev/video0" and save it in ".ppm" format. How to capture the 
video stream and display it in a window instead of saving it in ".ppm" 
format? Like "XAWTV". In the source code of "XAWTV" I can't able to 
find where in the code they actually drawing the window on the desktop 
and mapping the captured video stream, in such a way the video stream 
is displayed within the window. 
 
#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; 
struct video_tuner tuner; 
struct video_audio audio; 
 
char* memoryMap; 
int channelNumber = 0; 
int width = 320; 
int height = 240; 
int depth; 
int palette; 
int bufferIndex; 
 
char* NextFrame() 
{ 
 // send a request to begin capturing to the currently indexed buffer 
  if (ioctl (deviceHandle, VIDIOCMCAPTURE, &mmaps[bufferIndex]) == -1) 
        {       // capture request failed 
        } 
        // move bufferIndex to the next frame 
        ++ bufferIndex; 
        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]); 
} 
 
int main() 
{ 
        // open the device 
	memset(&tuner,0,sizeof(tuner)); 
	memset(&audio,0,sizeof(audio)); 
        deviceName = "/dev/video0"; 
        deviceHandle = open (deviceName, O_RDWR); 
        if (deviceHandle == -1) // could not open device 
        { 
       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; 
        } 
 
        // 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); 
 
        // set the selected channel 
        selectedChannel.channel = channelNumber; 
        //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, memoryBuffer.size, PROT_READ | 
PROT_WRITE, MAP_SHARED, deviceHandle, 0); 
        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 
        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 ten frames 
        printf ("Capture is ready; capturing 2 images.\n"); 
        int i = 0; 
        while (i < 10) 
        { 
                char* frame = NextFrame(); 
 
                // write out PPM file 
                char fname[80]; 
                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) 
                { 
                        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 the video_mmap structures 
        free (mmaps); 
 
        // unmap the capture memory 
        munmap (memoryMap, memoryBuffer.size); 
 
        // close the device 
        close (deviceHandle); 
 
        return 0; 
} 
 
With Regards, 
S.Suriya Mohan. 

There is no substitution for hard work. 
Information is wealth. 

[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