ARM的视频采集以及jpeg压缩

 //转发~~

头文件:capture.h

#ifndef _CAPTURE_H_
#define _CAPTURE_H_


#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <linux/videodev.h>
#include <sys/ioctl.h>

#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>

#include <linux/types.h>
#include <jpeglib.h>
#include <setjmp.h>


#define bool int
#define true 1
#define false 0
//#include <sys/times.h>
int errno;


bool open_video() ;//open video
char *NextFrame() ;//capture one frame data
void close_video() ;//close video and free resource
bool capture_run() ;//create capture thread
void *thread_capture() ;//capture thread function
bool encode_jpeg(char *lpbuf,int width ,int height) ;//jpeg encode
#endif

 

程序文件capture.c

#include "capture.h"


//定义视频扑捉相应的结构体
struct video_mbuf v_bufferproperty ;//此结构体利用mmap进行映射帧信息
//实际上是输入到摄像头存储器缓冲区的帧信息
struct video_mmap *v_memorymap ;//用于内存映射
struct video_picture v_imageproperty ;//采集图像的各种属性
struct video_capability v_capability ;//摄像头的基本信息
char *memorymap ;
int bufferIndex=0 ;


//define the variable
char* deviceName = "/dev/v4l/video0";  
char *fname="temp.jpg" ;
int deviceHandle = 0;
int width = 320;  
int height = 240;  
int depth=16;  
int palette=VIDEO_PALETTE_RGB565;  
 
 
//conrresponding to thread
pthread_t hthread_capture ;//capture thread!

bool open_video()
{
 int ret =-1 ;
 //open device
 deviceHandle=open(deviceName,O_RDWR) ;//read and write mode
 if(deviceHandle==-1)
 {
  printf("Capture:Open failed!/n") ;
  printf("Mesg:%s/n",sys_errlist[errno]) ;
  return false ;
 }
 
 //get the property of capture
 ret=ioctl(deviceHandle,VIDIOCGCAP,&v_capability) ;
 if(ret == -1)
 {
  printf("Capture:obtain capability failed!/n") ;
  printf("Mesg:%s/n",sys_errlist[errno]) ;
  close(deviceHandle) ;//关闭设备文件
  return false ;
 }
 if((v_capability.type&VID_TYPE_CAPTURE)==0)
 {
  printf("Capture:this device can't capture video to memory!/n") ;
  close(deviceHandle) ;//关闭设备文件
  return false ;
 }
 //print the information of capture
  printf(v_capability.name);
  printf(", Type:%d/n",v_capability.type);
  printf("Maxwidth:%d,Maxheight:%d/n",v_capability.maxwidth ,v_capability.maxheight);
  printf("Minwidth:%d,Minheight:%d/n",v_capability.minwidth,v_capability.minheight);
  printf("Channels:%d,Audios:%d/n",v_capability.channels,v_capability.audios) ;
 
 
 //get property of the picture that captured
 ret=ioctl(deviceHandle,VIDIOCGPICT,&v_imageproperty) ;
 if(ret==-1)
 {
  printf("Capture:obtain picture property failed!/n") ;
  printf("Mesg:%s/n",sys_errlist[errno]) ;
  close(deviceHandle) ;//关闭设备文件
  return false ;
 }
 
 v_imageproperty.palette=palette ;
 v_imageproperty.depth=depth ;
 //set property of the picture that capured
 ret = ioctl(deviceHandle,VIDIOCSPICT,&v_imageproperty) ;
 if(ret==-1)
 {
  printf("Capture:Set the property of image failed!/n") ;  
  printf("Mesg:%s/n",sys_errlist[errno]) ;
  close(deviceHandle) ;//关闭设备文件
  return false ;
 }
 //printf("test!/n") ;
 //get the property of  map buffer
 ret=ioctl(deviceHandle,VIDIOCGMBUF,&v_bufferproperty) ;
 if(ret==-1)
 {
  printf("Capture:Get the property of map buffer failed!/n") ;
  printf("Mesg:%s/n",sys_errlist[errno]) ;
  close(deviceHandle) ;//关闭设备文件  
  return false ;
 }
 
 //map
 memorymap=(char *)mmap(0,v_bufferproperty.size,PROT_READ | PROT_WRITE, MAP_SHARED, deviceHandle, 0); 
 if((int)memorymap==-1)
 {
  printf("Capture:Mmap failed!/n") ;
  printf("Mesg:%s/n",sys_errlist[errno]) ;
  close(deviceHandle) ;//关闭设备文件  
  return false ;  
 }
printf("memorymap=%d/n",(int)memorymap) ;
 //allocate video_map structures
 v_memorymap=(struct video_mmap*)(malloc(v_bufferproperty.frames*sizeof(struct video_mmap))) ;
 if(v_memorymap==NULL)
 {
  printf("Capture:malloc failed!/n")  ;
  printf("Mesg:%s/n",sys_errlist[errno]) ;
  close(deviceHandle) ;//关闭设备文件  
  return false ;   
 }
 ret=0 ;
// printf("test!/n") ;
 while(ret<v_bufferproperty.frames)
 {
  v_memorymap[ret].frame=ret ;
  v_memorymap[ret].width=width ;
  v_memorymap[ret].height=height ;
  v_memorymap[ret].format=palette ;
  ++ret ;
 }

 ret=0 ;
printf("frame size:%d,frames :%d/n",v_bufferproperty.size,v_bufferproperty.frames) ;
 while(ret<(v_bufferproperty.frames-1))
 {

         if (ioctl (deviceHandle, VIDIOCMCAPTURE, &v_memorymap[bufferIndex]) == -1)  
         {       // capture request failed   
   printf("Capture:capture failed!/n") ;
   printf("Mesg:%s/n",sys_errlist[errno]) ;
   close(deviceHandle) ;//关闭设备文件
   exit(0) ;
         }    
  ++ret ; 
 }
 bufferIndex=v_bufferproperty.frames-1 ;

 return true ;
}
//注意bufferIndex标明当前是第几帧
char* NextFrame()  
{  
        // send a request to begin capturing to the currently indexed buffer   
        if (ioctl (deviceHandle, VIDIOCMCAPTURE, &v_memorymap[bufferIndex]) == -1)  
        {       // capture request failed   
  printf("Capture:capture failed!/n") ;
  printf("Mesg:%s/n",sys_errlist[errno]) ;
  close(deviceHandle) ;//关闭设备文件
  exit(0) ;
        }  
  
        // move bufferIndex to the next frame   
        ++ bufferIndex;  
        if (bufferIndex == v_bufferproperty.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, &v_memorymap[bufferIndex]) == -1)  
        {       // sync request failed 
  printf("Capture:video sync failed!/n") ;
  printf("Mesg:%s/n",sys_errlist[errno]) ;
  close(deviceHandle) ;//关闭设备文件
  exit(0) ; 

        }  
  
        // return the address of the frame data for the current buffer index   
        return (memorymap + v_bufferproperty.offsets[bufferIndex]);  

//free resource
void close_video()
{
 //free the video_mmap structure
 free(v_memorymap) ;
 //unmap the capture memory
 munmap(memorymap,v_bufferproperty.size) ;
 //Close device file
 close(deviceHandle) ;
}
//create thread

bool capture_Run()
{
 int ret=-1 ;
 //注意在linux下使用线程,在编译链接时要加lpthread
 ret=pthread_create(&hthread_capture,NULL,thread_capture,NULL)  ;
 if(ret==-1)
 {
  printf("Capture:create capture thread failed!/n") ;
  return false ;
 }
// printf("test!/n") ;
 return true ;
}
//thread function
void *thread_capture()
{
 char *temp=NULL ;
 int a=0 ;
 if(!open_video())
 {
  goto exit ;
 }
// bufferIndex=0 ;
// printf("test11!/n") ;
 while(1)
 {
  temp=NextFrame() ;
 printf("Frames:%d/n",a) ;
  if(!encode_jpeg(temp,width,height))
  {
   goto exit ;
  }
 ++a ;
  
 }
 close_video() ;
exit:
 printf("Capture:capture thread exited !/n") ;
}


bool encode_jpeg(char *lpbuf,int width ,int height)
{
 struct jpeg_compress_struct cinfo ;//
 struct jpeg_error_mgr jerr ;//
 JSAMPROW  row_pointer[1] ;
 int row_stride ;
 char *buffer=NULL ;
 int x ;
 
 FILE *fptr_jpg = fopen (fname,"wb");//注意这里为什么用fopen而不用open
 if(fptr_jpg==NULL)
 {
  printf("Encoder:open file failed!/n") ;
  printf("Mesg:%s/n",sys_errlist[errno]) ;  
  return false ;
 }

    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_stdio_dest(&cinfo, fptr_jpg);

    cinfo.image_width = width;
    cinfo.image_height = height;
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_RGB;

    jpeg_set_defaults(&cinfo);
   

    jpeg_set_quality(&cinfo, 80,true);
   
   
    jpeg_start_compress(&cinfo, TRUE);

    row_stride = width * 3;
 //       row_pointer[0] = &buffer[cinfo.next_scanline * row_stride];
buffer=malloc(row_stride) ;
        row_pointer[0] = buffer;
    while (cinfo.next_scanline < height)
    {


 //       (void)jpeg_write_scanlines(&cinfo, row_pointer, 1);
 //printf("row_stride=%d/n",row_stride) ;


   for (x = 0; x < row_stride; x+=3)
   {

    buffer[x]   = lpbuf[x];
    buffer[x+1] = lpbuf[x+1];
    buffer[x+2] = lpbuf[x+2];

   }
   jpeg_write_scanlines (&cinfo, row_pointer, 1);//critical
   lpbuf += row_stride;
    }

    jpeg_finish_compress(&cinfo);
    fclose(fptr_jpg);
    jpeg_destroy_compress(&cinfo);
    free(buffer) ;
    return true ;
 
}

int main()
{
 capture_Run() ;
 while(1) ;
 return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值