www.pudn.com > jpeg_thread.rar > jpeg_thread.c
#include#include #include #include #include #include #include #include #include //#include "jpeglib.h" #include "gpsserver.h" #include "sudp_linux.h" #include #include #include "main.h" #include #define GPECON 0x56000040 #define GPE11 0xb #define BUF_SIZE 1024*1024 #define IMAGE_SIZE 256*720 //YUV像素大小 #define byte unsigned char static unsigned char image_buffer[256*720*2]; int alarmmark=0;//报警信号位,0为无报警,1为有报警(发送数据接口用) /********************************************** 包头定义:0x42 0x4d:B M(2字节) 文件大小:256*720*3+54=553014=0x87036(4个字节) 4个字节保留,值为0// 4个字节表示第一个像素的偏移量(54=0x36) 4 个字节存放文件信息头的长度 ,其值为 40=0x28 4 个字节存放位图的宽度720=0x2D0 4 个字节存放位图的高度256=0x100 2 个字节存放平面的数目 ,其值为 1 2 个字节存放每个像素所占的位数 ,24=0x18 4 个字节指定位图是否压缩,0// 4 个字节表示位图的实际大小,文件大小-包头(54),0x87000 4 个字节指定目标设备的水平分辨率 ,通常不用将其设为 0。 4 个字节指定目标设备的垂直分辨率 ,通常不用将其设为 0。 4 个字节指定图像实际用到的颜色数 ,若使用所有颜色则值为 0 4 个字节指定图像中重要的颜色数 ,若全部重要则值为 0 ********************************************/ unsigned char head[54]={0x42,0x4d,0x36,0x70,0x08,0,0,0,0,0, //10 0x36,0,0,0,0x28,0,0,0,0xd0,0x2,0,0,0x00,0x1,0,0,0x1,0,0x18,0,0,0,0,0,//24 0,0x70,0x8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //20 int WriteJPEG(void); void InitGPIO(); void GetFromSram(); void GetPictrue(void); inline byte ADJUST(double ); void YUV_BMP24(); int * firstthread(void *); int * secondthread(void *); pthread_t firstid,secondid; int main() { InitGPIO(); /******************创建线程***************/ if(pthread_create(&firstid, NULL, (void *)firstthread, NULL) != 0) //创建线程1,用于侦听服务器下行命令 { printf("thread creation failed\n"); exit(1); } if(pthread_create(&secondid, NULL, (void *)secondthread, NULL) != 0) //创建线程2,用于每30秒发送心跳 { printf("thread creation failed\n"); exit(1); } pthread_exit(0); printf("this is end"); } int * firstthread(void * arg) { GetPictrue(); } int * secondthread(void * arg) { while(1) { printf("this is secondthread\n "); sleep(3); } } /************************************************************** 函数说明:JPEG压缩,压缩当前文件夹的bmp图像,有待改进 ******************************************************************/ int WriteJPEG(void) { pid_t pid; int i; char *argv[]={"cjpeg","-quality","25","-outfile","/version_w/pic.jpg","/version_w/pic.bmp",(char *)0}; if((pid=fork())==-1) { printf("Error in fork\n"); exit(1); } if(pid==0) //子进程 { if(i=execv("/version_w/cjpeg",argv)<0) { printf("\n cjpeg error. \n"); perror("cjpeg error"); } } } /****************************************************************************************** 函数说明:拍照函数 ARM通过上拉GPE11通知FPGA采集图片;FPGA通过上拉GPG2(EINT9)通知ARM采集完一帧, ARM从SRAM中读数据,并调用压缩处理模块,GPE11复位 *******************************************************************************************/ void GetPictrue(void) { unsigned long *sp; unsigned long gpioaddress; int memfd; /* gpioaddress=0x56000000; alarmmark=1;//置报警信息位 memfd=open ("/dev/mem",O_RDWR); sp=(unsigned long *)mmap(0,10000,PROT_READ|PROT_WRITE,MAP_SHARED,memfd,gpioaddress); *(unsigned long*)(sp+rGPEDAT) |=0x0800; //拉高GPE11 munmap(sp,10000); close(memfd); while(1) { sleep(1); memfd=open ("/dev/mem",O_RDWR); sp=(unsigned long *)mmap(0,10000,PROT_READ|PROT_WRITE,MAP_SHARED,memfd,gpioaddress); if((*(unsigned long*)(sp+rGPGDAT))&&0x2)//等待GPG1电平拉高 { *(unsigned long*)(sp+rGPEDAT) &=0xf7ff; //拉低 munmap(sp,10000); close(memfd); */ int t; unsigned long p[2]; /* t=open("/dev/gpio",O_RDWR | O_NOCTTY); if (t < 0) { printf("can not open led!\n"); perror("open /dev/gpio "); } p[0]=GPECON; //GPJCON p[1]=GPE11; write(t,p,0); write(t,p,1);sleep(1); write(t,p,0); close(t); printf("3333333\n"); */ GetFromSram(); printf("111111111\n"); YUV_BMP24(); printf("2222222\n"); WriteJPEG(); printf("4444444\n"); // send_cf(man_number); // alarmmark=0;//发送完就复位报警信息位 // send_pp(); // pthread_mutex_lock(&ftp_mutex); // FtpPic(); //图片上传 // pthread_mutex_unlock(&ftp_mutex); // munmap(sp,10000); // close(memfd); // break; // } // } } /****************************************************************************************** 函数说明:从指定地址的SRAM中读取图像数据,存在imagebuff,低位存低字节,高位存高字节 *******************************************************************************************/ void GetFromSram() { // int i,j,fd,bufsize; int i,j,bufsize; int k=0; int memfd; unsigned short *sp1; unsigned long sramaddress; size_t size; memset(image_buffer,0,sizeof(image_buffer)); size = getpagesize(); bufsize=BUF_SIZE; sramaddress=0x8000000; memfd=open ("/dev/mem",O_RDWR); sp1=(unsigned short *)mmap(0,((bufsize/size)+1)*size,PROT_READ|PROT_WRITE,MAP_SHARED,memfd,sramaddress); for(i=0;i<256;i++)// 从内存读到imagebuff for(j=0;j<720;j++) { *(unsigned short*)&image_buffer[k]=*(unsigned short *)(sp1+1024*i+j); k=k+2; } munmap(sp1,bufsize); close(memfd); } /****************************************************************************************** YUV422-->BMP24的数据转换,并生成BMP文件(还没添加BMP文件头56字节) *******************************************************************************************/ inline byte ADJUST(double tmp) { return (byte)((tmp >= 0 && tmp <= 255)?tmp:(tmp < 0 ? 0 : 255)); } void YUV_BMP24() { int i,j,size; unsigned char temp; unsigned char write_buffer[256*720*3]; unsigned char file_buffer[256*720*3+54]; FILE *output_file; byte Y1,Y2,U,V; char out_file[]="/version_w/pic.bmp"; //此处应申明为宏定义或全局变量,作为输出文件的目录,与JPEG压缩对应 size=256*720*2; memset(write_buffer,0,sizeof(write_buffer)); memset(file_buffer,0,sizeof(file_buffer)); for(i=0;i<(size/4)+1;i=i+1) { /***一个宏像素里4个字节,有4个Y分量,2个U分量,2个V分量,Y:U:V=4:2:2,** *****Y0 U0 Y1 V0 Y2 U2 Y3 V2,4个字节-->6个字节********************/ /**************RGB24在内存中的存放顺序BGR,BGR,...*********/ Y1=image_buffer[4*i+1]; Y2=image_buffer[4*i+3]; U=image_buffer[4*i]; V=image_buffer[4*i+2]; write_buffer[6*i] = ADJUST((Y1+ (1.772 * (U - 128)))); //B1 write_buffer[6*i+1] = ADJUST((Y1 - (0.34414 * (U - 128) - 0.71414 * (V - 128)))); //G1 write_buffer[6*i+2] = ADJUST((Y1 + (1.402 * (V - 128)))); //R1 write_buffer[6*i+3] = ADJUST((Y2+ (1.772 * (U - 128)))); //B2 write_buffer[6*i+4] = ADJUST((Y2 - (0.34414 * (U - 128) - 0.71414 * (V - 128)))); //G2 write_buffer[6*i+5] = ADJUST((Y2 + (1.402 * (V - 128)))); //R2 } /***********BMP图像数据按逆序存储**************/ for(i=0;i<128;i++) for(j=0;j<720*3;j++) { temp=write_buffer[j+720*3*i]; write_buffer[j+720*3*i]=write_buffer[j+720*3*(256-i-1)]; write_buffer[j+720*3*(256-i-1)]=temp; } /*********** 连接BMP头部,并生成BMP文件**************/ /*********** 效率太低,怎么把两文件直接连接?**************/ for(i=0;i<54;i++) { file_buffer[i]=head[i]; } for(i=0;i<256*720*3;i++) { file_buffer[54+i]=write_buffer[i]; } if((output_file = fopen(out_file,"wb"))==NULL) { fprintf(stderr, "cannot open the %s\n", out_file); exit(0); } // printf("before write\n"); fwrite(file_buffer,sizeof(unsigned char),(256*720*3+54),output_file); fclose(output_file); } /****************************************************************************************** 函数说明:配置各端口控制寄存器,初始化各数据寄存器 *******************************************************************************************/ void InitGPIO() { int memfd; unsigned long *sp,sp1; // unsigned long address; // address=0x56000000; /****************配置BWSCON,Determine data bus width for bank 1,16bit**************/ memfd=open ("/dev/mem",O_RDWR); sp1=(unsigned long *)mmap(0,0x1000,PROT_READ|PROT_WRITE,MAP_SHARED,memfd,0x48000000); // printf("memory control register old %x\n",*(unsigned long *)(sp1)); *(unsigned long *)(sp1)=0x2211d110; // printf("memory control register new %x\n",*(unsigned long *)(sp1)); munmap(sp1,0x1000); close(memfd); /**************配置GPE端口,其中GPE11为output,FPGA要求****************/ memfd=open ("/dev/mem",O_RDWR); sp=(unsigned long *)mmap(0,0x1000,PROT_READ|PROT_WRITE,MAP_SHARED,memfd,0x56000000); *(unsigned long*)(sp+rGPECON) &=0xff7fffff; *(unsigned long*)(sp+rGPECON) |=0x400000; *(unsigned long*)(sp+rGPEDAT) &=0xf7ff; //拉低 /***************配置GPG1(EINT9)为input******************/ *(unsigned long*)(sp+rGPGCON) &=0xfffffff3; /**********************************GPH9做为系统自检成功后的亮灯标识************/ *(unsigned long*)(sp+rGPHCON) &=0x37ffff; *(unsigned long*)(sp+rGPHCON) |=0x40000; *(unsigned long*)(sp+rGPHDAT) &=0x5ff; //拉低点亮GPH9 munmap(sp,0x1000); close(memfd); }