#include "stdinc.h"
#include "utils.h"
#include "v4l2.h"
#include "webcam.h"
#include "tcputils.h"
#include "frame.h"
extern struct rect zc301_res[];
extern struct rect ov511_res[];
extern bool g_bcamoff; //服务退出标识
extern v4l2_device_t g_vd;
pthread_t g_cam_tid; //采集线程
pthread_t g_ser_tid; //服务器线程
pthread_mutex_t g_cam_mutex;
pthread_cond_t g_cam_cond;
char *g_video_dev_name;
struct rect *g_cur_res_list; //当前分辨率列表
__u32 g_cur_res_no; //当前选择的分辨率标号
__u8 *g_cur_frame = NULL;
__u32 g_cur_frame_len;
__u32 g_frame_nr = 0;
__s32 g_pixfmt;
__u16 g_ser_port;
int g_ser_sock; //服务器 sock
void sig_handler(int signo);
int cmdline_parse(int argc, char *argv[]);
void cam_server(void *args);
void adjust_devinfo(void);
int main(int argc, char *argv[])
{
int i;
int new_sock; //新的客户端 sock
int sin_size;
struct sockaddr_in cli_addr;
if (-1 == cmdline_parse(argc, argv))
_exit(EXIT_FAILURE);
if (-1 == camera_init(g_video_dev_name,
g_cur_res_list[g_cur_res_no].w,
g_cur_res_list[g_cur_res_no].h,
g_pixfmt) )
_exit(EXIT_FAILURE);
adjust_devinfo();
signal(SIGINT, sig_handler);
//启动采集线程
pthread_mutex_init(&g_cam_mutex, NULL);
pthread_cond_init(&g_cam_cond, NULL);
pthread_create(&g_cam_tid, NULL, (void *)camera_run, NULL);
//启动服务器
if (-1 == (g_ser_sock=open_ser_sock(g_ser_port)))
_exit(EXIT_FAILURE);
sin_size = sizeof(struct sockaddr_in);
while (!g_bcamoff) {
if (-1 == (new_sock=accept(g_ser_sock, (struct sockaddr*)&cli_addr,
&sin_size))) {
continue;
}
DBG("Got connection from %s\n", inet_ntoa(cli_addr.sin_addr));
pthread_create(&g_ser_tid, NULL, (void *)cam_server, &new_sock);
}
camera_stop();
pthread_join(g_cam_tid, NULL);
DBG("Cam Thread return!\n");
pthread_mutex_destroy(&g_cam_mutex);
pthread_cond_destroy(&g_cam_cond);
close(g_ser_sock);
return 0;
}
/*
* S/C 线程
*/
void cam_server(void *args)
{
int sock = *((int*)args);
int i, ret;
__u32 fnr = 0; //帧编号
__u8 fid[FRAME_ID_SIZ]; //帧ID
__u32 cmd;
struct frame_header fhdr;
struct ctrl_frame_hdr cfhdr;
while (!g_bcamoff) {
bzero(&fhdr, sizeof(struct frame_header));
DBG("Wait for REQ\n");
ret = read_sock(sock, (__u8*)&fhdr, sizeof(struct frame_header));
if (ret < 0) {
DBG("Client vaporished\n");
break;
} else {
bzero(fid, FRAME_ID_SIZ);
strncpy(fid, fhdr.fid, FRAME_ID_SIZ);
cmd = fhdr.cmd;
}
DBG("Get REQ\n");
bzero(&fhdr, sizeof(struct frame_header));
if (strncmp(fid, FRAME_ID, FRAME_ID_SIZ)) {
//鉴别fid, 确定是否该处理该帧
DBG("Receive Bad package with wrong FID\n");
strncpy(fhdr.fid, FRAME_ID, FRAME_ID_SIZ);
fhdr.cmd = MKCMD(CMD_TYP(cmd), RQT_ACK, DIR_TOC, ACK_ERR);
ret = write_sock(sock, (__u8*)&fhdr, sizeof(struct frame_header));
if (ret < 0)
break;
continue;
}
if (CMD_RQT(cmd) != RQT_REQ || CMD_DIR(cmd) != DIR_TOS) {
DBG("Receive Bad package with wrong RQT or DIR\n");
strncpy(fhdr.fid, FRAME_ID, FRAME_ID_SIZ);
fhdr.cmd = MKCMD(CMD_TYP(cmd), RQT_ACK, DIR_TOC, ACK_ERR);
ret = write_sock(sock, (__u8*)&fhdr, sizeof(struct frame_header));
if (ret < 0)
break;
continue;
}
switch (CMD_TYP(cmd)) {
case TYP_INF:
strncpy(fhdr.fid, FRAME_ID, FRAME_ID_SIZ);
fhdr.cmd = MKCMD(CMD_TYP(cmd), RQT_ACK, DIR_TOC, ACK_OK);
DBG("BUF LEN = %d\n", g_vd.buf[0].len);
fhdr.fsiz = g_vd.buf[0].len; //这里的fsiz表示的是
//device为一帧分配的空间
bzero(&cfhdr, sizeof(struct ctrl_frame_hdr));
strncpy(cfhdr.name, g_vd.name, 32);
cfhdr.pixfmt = g_pixfmt; //g_vd.pfmt.pixelformat;
cfhdr.nr_uctrl = g_vd.nr_uctrl;
cfhdr.cres_no = g_cur_res_no;
cfhdr.nr_res = get_res_nr(g_cur_res_list);
ret = write_sock(sock, (__u8*)&fhdr, sizeof(struct frame_header));
if (ret < 0)
goto quit;
ret = write_sock(sock, (__u8*)&cfhdr, sizeof(struct ctrl_frame_hdr));
if (ret < 0)
goto quit;
ret = write_sock(sock, (__u8*)g_vd.uctrl,
cfhdr.nr_uctrl * sizeof(struct v4l2_usrctrl));
if (ret < 0)
goto quit;
ret = write_sock(sock, (__u8*)g_cur_res_list,
cfhdr.nr_res * sizeof(struct rect));
if (ret < 0)
goto quit;
break;
case TYP_SET:
bzero(&cfhdr, sizeof(struct ctrl_frame_hdr));
ret = read_sock(sock, (__u8*)&cfhdr, sizeof(struct ctrl_frame_hdr));
if (ret < 0)
goto quit;
//如果改变捕获图像的分辨率,则需要重启
if (cfhdr.cres_no != g_cur_res_no) {
if (cfhdr.cres_no >= get_res_nr(g_cur_res_list)) {
//请求的分辨率不被支持, 不用重启
DBG("cfhdr.cres_no is out of range, set default!\n");
} else {
g_cur_res_no = cfhdr.cres_no;
if (-1 == camera_restart(g_video_dev_name,
g_cur_res_list[g_cur_res_no].w,
g_cur_res_list[g_cur_res_no].h,
g_pixfmt))
_exit(EXIT_FAILURE);
struct rect res;
res.w = g_vd.pfmt.width;
res.h = g_vd.pfmt.height;
g_cur_res_no = get_res_no(res, g_cur_res_list);
g_pixfmt = g_vd.pfmt.pixelformat;
DBG("Camera restart ok, w = %d, h = %d!\n",
res.w, res.h);
g_frame_nr = 0;
}
}
//用接收到的参数设置设备
for (i = 0; i < g_vd.nr_uctrl; i++) {
struct v4l2_usrctrl uctrl;
ret = read_sock(sock, (__u8*)&uctrl,
sizeof(struct v4l2_usrctrl));
if (ret < 0)
goto quit;
if (uctrl.val == g_vd.uctrl[i].val)
continue;
v4l2_set_uctrl(&g_vd, i, uctrl.val);
g_vd.uctrl[i].val = uctrl.val;
}
//应答, 并返回新的设备信息
strncpy(fhdr.fid, FRAME_ID, FRAME_ID_SIZ);
fhdr.cmd = MKCMD(CMD_TYP(cmd), RQT_ACK, DIR_TOC, ACK_OK);
DBG("BUF LEN = %d\n", g_vd.buf[0].len);
fhdr.fsiz = g_vd.buf[0].len;
bzero(&cfhdr, sizeof(struct ctrl_frame_hdr));
strncpy(cfhdr.name, g_vd.name, 32);
cfhdr.pixfmt = g_pixfmt; //g_vd.pfmt.pixelformat;
cfhdr.nr_uctrl = g_vd.nr_uctrl;
cfhdr.cres_no = g_cur_res_no;
DBG("setting Cam write_sock fhdr\n");
ret = write_sock(sock, (__u8*)&fhdr, sizeof(struct frame_header));
if (ret < 0)
goto quit;
DBG("setting Cam write_sock cfhdr, cres_no = %d\n",
g_cur_res_no);
ret = write_sock(sock, (__u8*)&cfhdr, sizeof(struct ctrl_frame_hdr));
if (ret < 0)
goto quit;
DBG("setting Cam write_sock uctrl, nr_uctrl = %d\n",
cfhdr.nr_uctrl);
ret = write_sock(sock, (__u8*)g_vd.uctrl,
cfhdr.nr_uctrl * sizeof(struct v4l2_usrctrl));
if (ret < 0)
goto quit;
//sleep(1);
while (!g_frame_nr)
usleep(1000);
break;
case TYP_DAT:
if (NULL == g_cur_frame) {
DBG("Device is not ready\n");
strncpy(fhdr.fid, FRAME_ID, FRAME_ID_SIZ);
fhdr.cmd = MKCMD(CMD_TYP(cmd), RQT_ACK, DIR_TOC, ACK_BSY);
ret = write_sock(sock, (__u8*)&fhdr,
sizeof(struct frame_header));
if (ret < 0)
goto quit;
break;
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
server.rar (19个子文件)
server
server.c 12KB
tags 8KB
v4l2.h 3KB
webcam.h 530B
cam_server 29KB
v4l2.c 7KB
v4l2.o 9KB
tcputils.h 441B
stdinc.h 629B
frame.h 3KB
tcputils.o 4KB
tcputils.c 2KB
utils.c 1KB
utils.o 2KB
utils.h 749B
Makefile 179B
webcam.c 3KB
server.o 10KB
webcam.o 4KB
共 19 条
- 1
guozhiyuan20095318
- 粉丝: 65
- 资源: 9
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
前往页