⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 framebuffer.c

📁 linux 下的frambuffer,在屏幕的左上角显示一个图框!
💻 C
字号:
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;
int fbfd = 0;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
struct fb_cmap chen_fb_cmap;
long int screensize = 0;
char *fbp = 0;
int x = 0, y = 0;
long int location = 0;
typedef unsigned char BYTE;
BYTE m_pData[240][320];
int gwidth;
int gheight;
int gcount;
int GetSeg(int *x, int len);
void ErosionLin(int s[][20],int sm,int sn,int x[][320],int xm,int xn,int y[][320]);
void DilationLin(int s[][20],int sm,int sn,int x[][320],int xm,int xn,int y[][320]);
void CloseLin(int s[][20],int sm,int sn,int x[][320],int xm,int xn,int y[][320],int z[][320]);
int CountBySeg(int x[][320], long row, long col);
void OnResult();
void gray(char *data,int width,int height);
static int write_file(char *data, int width, int height);
int GetSeg(int *x, int len)
{
	int i,temp,sum;
	for(i=0;i<len-1;i++)
	{
		temp = x[i] * x[i+1];
		if(temp==1)
			x[i] = 0;
	}
	sum = 0;
	for(i=0;i<len;i++)
		sum = sum + x[i];
	return sum;
}
void ErosionLin(int s[][20],int sm,int sn,int x[][320],int xm,int xn,int y[][320]){
		int i0,j0,i,j;
		int sum0,sum;
		for(i0=0;i0<xm;i0++)
		for(j0=0;j0<xn;j0++){   
			y[i0][j0]=0;
		}
		sum0=0;
		for(i=0;i<sm;i++)
		for(j=0;j<sn;j++){
			sum0=sum0+s[i][j];
		}
		for(i0=0;i0<=xm-sm;i0++)
		for(j0=0;j0<=xn-sn;j0++){
			sum=0;
			for(i=0;i<sm;i++)
				for(j=0;j<sn;j++){
					sum=sum+s[i][j]*x[i0+i][j0+j];
				}
			if(sum==sum0)
				y[i0+sm/2][j0+sn/2]=1;
		}
	}

void DilationLin(int s[][20],int sm,int sn,int x[][320],int xm,int xn,int y[][320]){
		int i0,j0,i,j;
		int sum;
		for(i0=0;i0<xm;i0++)
			for(j0=0;j0<xn;j0++){
				y[i0][j0]=0;
		    	}
		for(i0=0;i0<=xm-sm;i0++)
			for(j0=0;j0<=xn-sn;j0++){
				sum=0;
				for(i=0;i<sm;i++)
					for(j=0;j<sn;j++){
						sum=sum+s[i][j]*x[i0+i][j0+j];
					}
				if(sum>0)
				y[i0+sm/2][j0+sn/2]=1;		
               }
}
void CloseLin(int s[][20],int sm,int sn,int x[][320],int xm,int xn,int y[][320],int z[][320]){		
		DilationLin(s,sm,sn,x,xm,xn,y);
		ErosionLin(s,sm,sn,y,xm,xn,z);
	}
int CountBySeg(int x[][320],long row, long col)
{
	int y[240][320];
	int * z;
	int i,j,j1,k;		
	int sum,count,seg;
	for(i=0;i<row;i++)
		for(j=0;j<col;j++)
			y[i][j] = x[i][j];
	for(i=0;i<row;i++)
		y[i][0]=y[i][col-1] = 0;
	for(j=0;j<col;j++)
		y[0][j]=y[row-1][j] = 0;
	z =(int*)malloc(sizeof(int)*col);
	count = 0;			
	for(i=1;i<row-1;i++)
	{
		j = 1;
		while(j<col-1)
		{//while 1				
			if(y[i][j]==1)
			{
				sum = 1;
				j1 = j + 1;
				while(y[i][j1])
				{
					sum++;
					j1++;
				}
				for(k=0;k<sum+2;k++)
					z[k] = y[i-1][j+k-1];
				seg = GetSeg(z,sum+2);
				count = count + 1 - seg;					
				j = j + sum;
			}
				j++;
		}		
	}
	free(z);
        gcount=count;
	return count;
}
void OnResult()
{
	int count,i,j;
	int  temp1[240][320],temp2[240][320];
        int xx[240][320];
        int s1[20][20];
        int s2[20][20];
	for(i=0; i<5; i++)
		for(j=0; j<5; j++)
			s1[i][j]=1;
	for(i=0; i<20; i++)
		for(j=0; j<20; j++)
			s2[i][j]=1;
	for(i=0; i<240; i++)
		for(j=0; j<320; j++)
		{
		 	xx[i][j] = m_pData[i][j];
		}
	CloseLin(s1,5,5,xx,240,320,temp1,temp2);
	ErosionLin(s2,10,10,temp2,240,320,temp1);
	count=CountBySeg(temp1,gheight,gwidth);
	return;
}
void gray(char *data,int width,int height)
  {
    int k=0;
    long i,j;
    gheight=height;
    gwidth=width;
    for ( i=0; i<height; i++)
    {
      for ( j=0; j<width; j++)
      {
        m_pData[i][j]= data[k] *0.114
                               +data[k+1] * 0.587
                               +data[k+2] * 0.299;
        if(m_pData[i][j]>50)
          m_pData[i][j]=1;
        else
          m_pData[i][j]=0;
        k+=3;
      }
    }
  }

static int write_file(char *data, int width, int height)
{
    gray(data,width,height);
    OnResult();
    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
        }
        // 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
        char * videodeviceName = "/dev/v4l/video0";
        deviceHandle = open (videodeviceName, O_RDWR);
        if (deviceHandle == -1)
        {       // could not open device
                printf("Could not open device %s\n",videodeviceName);
		// printf ("Could not open device %s - %s\n", videodeviceName, strerror[errno]);
                return -1;
        }
        // get device capabilities
        if (ioctl (deviceHandle, VIDIOCGCAP, &capability) == -1)
        {       // query failed
                printf ("could not obtain device capabilities\n");
                return -1;
        }
        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;
        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 %dbit RGB\n",depth);
        // 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)));
	   
		//****************
		//add by chenfu 2005.01.26
		//****************
		//open framebuffer
       /*int fbfd = 0;
        struct fb_var_screeninfo vinfo;
        struct fb_fix_screeninfo finfo;
	struct fb_cmap chen_fb_cmap;
        long int screensize = 0;
        char *fbp = 0;
        int x = 0, y = 0;
        long int location = 0;*/
            // Open the file for reading and writing
        fbfd = open("/dev/fb/0", O_RDWR);
        if (!fbfd) {
                printf("Error: cannot open framebuffer device.\n");
                exit(1);
        }
        printf("The framebuffer device was opened successfully.\n");
         // Get fixed screen information
        if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
                printf("Error reading fixed information.\n");
                exit(2);
        }
        // Get variable screen information
        if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
                printf("Error reading variable information.\n");
                exit(3);
        }
        vinfo.bits_per_pixel=12;
	if(ioctl(fbfd, FBIOPUT_VSCREENINFO, &vinfo)){
	        printf("The dfdfdfdfdfdfdfdfdfdfu\n");
        }	
                // printf("The framebuffer set not  .chenfu\n");
	    // Get variable screen information
        if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
                printf("Error reading variable information.\n");
                exit(3);
        }
        printf("    the chenfu framebuffe is %dx%d, %dbpp    \n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel );
       /*if (ioctl(fbfd, FBIOGETCMAP, &chen_fb_cmap)) {
                printf("Error  CHENFU variable information.\n");
                exit(4);
         }*/
    //    printf("the CHENFU CMAP %d\n",*chen_fb_cmap.red);
            // Figure out the size of the screen in bytes
        //screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;
	screensize = vinfo.xres * vinfo.yres*1.5;
            // Map the device to memory
        fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,fbfd, 0);
		if ((int)fbp == -1) {
                printf("Error: failed to map framebuffer device to memory.\n");
                exit(4);
        }
            printf("The framebuffer device was mapped to memory successfully.\n");

		//the next is to capture 
		//start capture
        // 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;now start to captur images.\n");
        while (1)
        {                char* frame = NextFrame();    
		write_file(frame, 320, 240);
		int index=0;
		for ( y = 0; y < 240; y++ )
			for ( x = 0; x <160; x++ ) {
	               		index = index +2; 
				location =(x+ vinfo.xoffset) * 3 + (y+vinfo.yoffset) * finfo.line_length;
				*(fbp + location) = (frame[index*3+2]&0xF0)|((frame[index*3+1]&0xF0)>>4);
		 		*(fbp + location+1) = (frame[index*3]&0xF0)|((frame[(index+1)*3+2]&0xF0)>>4);
                                *(fbp + location+2) = (frame[(index+1)*3+1]&0xF0)|((frame[(index+1)*3]&0xF0)>>4);
		}
		if((gcount>=0)&&(gcount<=9))
			drawNum(gcount);
		else
			drawNum(0);
	}
        // free the video_mmap structures
        free (mmaps);
        // unmap the capture memory
        munmap (memoryMap, memoryBuffer.size);
       // close the device
        close (deviceHandle);
        return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -