📄 con-flow.c
字号:
/*
** $Id: Con-flow.c,v 1.0 2008/03/19 PanChx $
**
** --右上键;+-右下键;NumLock-左上键;/-左下键
**
**
** Copyright (C) 2004 Feynman Software.
**
** License: GPL
*/
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <termios.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <pwd.h>
#include <errno.h>
#include <sys/wait.h>
#include <linux/types.h>
#include <linux/videodev.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <fcntl.h>
#include <pthread.h>
#include <minigui/common.h>
#include <minigui/minigui.h>
#include <minigui/gdi.h>
#include <minigui/window.h>
#include <minigui/control.h>
#include <minigui/minigui.h>
#include "con-flow.h"
//打开串口
int open_serial_modem(char *SerialPort)
{
// "/dev/ttyS0", "/dev/stS0", "/dev/stS1", "/dev/stS2",
//打开串口
int serial_port = -1;
serial_port = open((const char *)SerialPort, O_RDWR);
if (-1 == serial_port)
{
printf("\t!!!serial open error!!!\n");
}
return serial_port;
}
//关闭串口
int close_serial_modem(int serial_port)
{
close(serial_port);
serial_port = 0;
return 0;
}
//进行拨号
void dial_number(int serial_port)
{
write(serial_port, "ATD15953169608;\x0d", 16);
}
//挂断电话
void hangup(int serial_port)
{
write(serial_port, "ATH\x0d", 4);
}
//设置串口波特率
int config_serial_port(int serial_port, speed_t speed)
{
//得到串口结构
tcgetattr(serial_port, &Opt);
//设置输入波特率
cfsetispeed(&Opt, speed);
//设置输出波特率
cfsetospeed(&Opt, speed);
//以立即生效的方式设置串口结构
tcsetattr(serial_port,TCSANOW, &Opt);
//设置控制标志前的屏蔽
Opt.c_cflag &= ~CSIZE;
/*8 bit data*/
Opt.c_cflag |= CS8;
//允许输出产生奇偶信息以及输入的奇偶校验
Opt.c_cflag &= ~PARENB;
/*1 stop bit*/
Opt.c_cflag &= ~CSTOPB;
/*RAW mode*/
/*ICANON起用标准模式,允许使用特殊字符EOF,EOL,EOL2,ERASE,KILL,LNEXT
ECHO:回显输入字符
ECHOE:如果同时设置了ICANON,字符ERASE擦除前一个输入字符,WERASE擦除前一个词
ISIG:当接受到字符INTR,QUIT,SUSP或DSUSP时,产生相应的信号*/
Opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/
/*Output*/
/*启用具体实现自行定义的输出处理,其余c_oflag标志常量定义在POSIX1003.1-2001中,除非另外说明*/
Opt.c_oflag &= ~OPOST;
//控制字符VTIME:非canonical模式读时的延时,以十分之一秒为单位
Opt.c_cc[VTIME] = 8;
//VMIN非canonical模式读的最小字符数
Opt.c_cc[VMIN] = 2;
//丢弃要写入引用的对象,但是尚未传输的数据,或者收到但是尚未读取的数据,取决于queue_selector的值。
/*TCIFLUSH:刷新收到的数据但是不读*/
tcflush(serial_port, TCIFLUSH);
//设置与终端相关的参数(除非需要底层支持却无法满足),使用termios_p引用的termios结构
tcsetattr(serial_port, TCSANOW, &Opt);
return 0;
}
//检测信号质量
void check_signalquality(int serial_port)
{
write(serial_port, "AT+csq\x0d", 7);
}
/*把共享缓冲区中的数据放到一个变量中,通知系统已获得一帧
dst:目的地址
src:源地址*/
int convertframe(unsigned char *dst,unsigned char *src, int formatIn, int size)
{
int jpegsize =0;
switch (formatIn)
{
case VIDEO_PALETTE_JPEG:
jpegsize = get_jpegsize(src, size);
if (jpegsize < 0)
break;
memcpy(dst,src,jpegsize);
break;
default:
break;
}
return jpegsize;
}
void exit_fatal(char *messages)
{
printf("%s \n",messages);
exit(1);
}
//获取颜色深度
static int GetDepth (int format)
{
int depth;
switch (format)
{
case VIDEO_PALETTE_JPEG:
depth = 8;
break;
default:
depth = -1;
break;
}
return depth;
}
//测试芯片类型
static int isSpcaChip (const char *BridgeName)
{
int i = -1;
int find = -1;
int size = 0;
for (i = 0; i < MAX_BRIDGE -1; i++)
{
size = strlen (Blist[i].name) ;
if (strncmp (BridgeName, Blist[i].name, size) == 0)
{
find = i;
break;
}
}
return find;
}
//测试输出数据格式
static int GetStreamId (const char *BridgeName)
{
int i = -1;
int match = -1;
if ((match = isSpcaChip (BridgeName)) < 0)
{
return match;
}
switch (match)
{
case BRIDGE_ZC3XX:
i = JPEG;
break;
}
return i;
}
static int SetVideoPict (struct vdIn *vd)
{
//VIDIOCSPICT:设置图片属性
if (ioctl (vd->fd, VIDIOCSPICT, &vd->videopict) < 0)
exit_fatal ("Couldnt set videopict params with VIDIOCSPICT");
return 0;
}
//获取jpeg图片大小
int get_jpegsize (unsigned char *buf, int insize)
{
int i;
/*jpeg图片的8个标记:SOI 0xD8 图象开始;
APPO 0xE0 JEIF 应用数据块
APPn 0xE1-0xEF 其它得应用数据块(n,1~15)
DQT 0xDB 量化表
SOF0 0xC0 帧开始
DHT 0xC4 霍夫曼(Huffman)表
SOS 0xDA 扫描线开始
EOI 0xD9 图像结束
每一帧缓冲区的最开头四个字节为ff d8 ff d9,然后是图象大小*/
for (i = 1024 ; i < insize; i++)
{
if ((buf[i] == 0xFF) && (buf[i+1] == 0xD9))
return i+2;
}
return -1;
}
static int GetVideoPict (struct vdIn *vd)
{
/* VIDIOCGPICT:Get picture properties */
if (ioctl (vd->fd, VIDIOCGPICT, &vd->videopict) < 0)
exit_fatal ("Couldnt get videopict params with VIDIOCGPICT");
return 0;
}
//从摄像头采集图片
int v4lGrab(struct vdIn *vd, BITMAP * bitmap_stru)
{
int len;
int size;
int erreur = 0;
int jpegsize = 0;
FILE *f;
/* read method */
size = vd->framesizeIn;
//从vd->fd中读取size个字节到vd->pFramebuffer中
len = read (vd->fd, vd->pFramebuffer, size);
if (len < 0 )
{
perror("read error");
return 0;
}
jpegsize= convertframe(vd->ptframe, vd->pFramebuffer ,vd->formatIn,vd->framesizeIn);
printf("jpegsize = %x\n",jpegsize);
len = LoadBitmapFromMem(HDC_SCREEN, bitmap_stru, vd->ptframe, jpegsize, "jpg");
if(0!=len)
{
printf("LoadBitmapFromMem return failure%d,h=%x,w=%x\n",len,bitmap_stru->bmHeight,bitmap_stru->bmWidth);
}
return 1;
}
//初始化视频设备
static int init_v4l (struct vdIn *vd)
{
int erreur = 0;
//打开端口
if ((vd->fd = open (vd->videodevice, O_RDWR)) == -1)
exit_fatal ("ERROR opening V4L interface");
//打开设备能力
if (ioctl (vd->fd, VIDIOCGCAP, &(vd->videocap)) == -1)
exit_fatal ("Couldn't get videodevice capability");
snprintf (vd->cameraname, 32, "%s", vd->videocap.name);
//得到图片属性
erreur = GetVideoPict (vd);
/* Get channel info (sources) */
if (ioctl (vd->fd, VIDIOCGCHAN, &vd->videochan) == -1)
{
vd->cameratype = UNOW;
}
else
{
if (vd->videochan.name)
{
snprintf (vd->bridge, 9, "%s", vd->videochan.name);
vd->cameratype = GetStreamId (vd->bridge);
}
else
{
vd->cameratype = UNOW;
}
}
/* Only jpeg webcam allowed */
if(vd->cameratype != JPEG)
{
exit_fatal ("Not a JPEG webcam sorry Abort !");
}
//palette:palette in use
vd->videopict.palette = vd->formatIn;
//Capture depth
vd->videopict.depth = GetDepth (vd->formatIn);
vd->bppIn = GetDepth (vd->formatIn);
//宽*高*4
vd->framesizeIn = (vd->hdrwidth * vd->hdrheight >> 2 ); // here alloc the output ringbuffer jpeg only
erreur = SetVideoPict (vd);
erreur = GetVideoPict (vd);
//为什么需要获得两次呢?
if (vd->formatIn != vd->videopict.palette ||
vd->bppIn != vd->videopict.depth)
exit_fatal ("could't set video palette Abort !");
if (erreur < 0)
exit_fatal ("could't set video palette Abort !");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -