/* 服务端程序 server.c */
//WB
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <linux/types.h>
#include <linux/videodev2.h>
#include <setjmp.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "convert.h"
#include "../avc-src-0.14/avc/common/T264.h"
#define SERVER_PORT 8888
#define WIDTH 160
#define HEIGHT 120
#define FRAME_COUNT 1 //?建?????
#define FRAME_IDLE 60
T264_t* m_t264;
T264_param_t m_param;
char* m_pSrc;
char* m_pDst;
int* m_lDstSize;
char* m_pPoolData;
#define USB_VIDEO "/dev/video0"
typedef struct VideoBuffer //定义一个结构体来映射每个缓冲帧
{
void *start;
size_t length;
}VideoBuffer;
static int cam_fd;
static VideoBuffer *buffers = NULL;
static unsigned int numBufs = 0;
static int read_video(int index)
{
struct v4l2_buffer buf;
memset(&buf,0,sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = index;
//VIDIOC_DQBUF 从队列中取出帧
if (ioctl(cam_fd, VIDIOC_DQBUF, &buf) == -1)
return -1;
/*图像处理
process_image(buffers[buf.index].start); */
//将取出的缓冲帧放回缓冲区
if (ioctl(cam_fd, VIDIOC_QBUF, &buf) == -1)
return -1;
return 0;
}
static int init_video(int w,int h) /* bpp == bytes per pixel*/
{
/*设备的打开*/
cam_fd = open( USB_VIDEO, O_RDWR );
if(cam_fd<0 )
printf("Can't open video device\n");
/* 使用IOCTL命令VIDIOCGCAP,获取摄像头的基本信息,如最大,最小分辨率*/
struct v4l2_capability cap;
if (ioctl (cam_fd, VIDIOC_QUERYCAP, &cap) == -1)
{
printf("Get camara capability is fail.\n");
return -1;
}
printf("camara driver: %s\n", cap.driver);
printf("camara card: %s\n", cap.card);
printf("camara bus info: %s\n", cap.bus_info);
printf("camara version: %d\n", cap.version);
printf("4\n");
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) //是否支持图像获取
{
printf("Camara does not support VIDEO CAPTURE.\n");
return -1;
}
printf("5\n");
if (!(cap.capabilities & V4L2_CAP_STREAMING)) //I/O的读写控制流
{
printf("Camara does not support STREAMING.\n");
return -1;
}
printf("6\n");
struct v4l2_format fmt;
memset(&fmt, 0, sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = WIDTH;//帧宽 帧高 单位像素
fmt.fmt.pix.height = HEIGHT;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
if (ioctl(cam_fd, VIDIOC_S_FMT, &fmt) == -1)//检查是否支持V4L2_PIX_FMT_MJPEG 格式
{
printf("Camara set fmt is errror.\n");
return -1;
}
printf("7\n");
struct v4l2_requestbuffers req;
enum v4l2_buf_type type; //enum v4l2_buf_type type; //数据流类型,必须永远是V4L2_BUF_TYPE_VIDEO_CAPTURE
struct v4l2_buffer buf;
memset(&req, 0, sizeof (req));
req.count = FRAME_COUNT;缓存数量,也就是说在缓存队列里保持多少张照片 申请一个拥有FRAME_COUNT个缓冲帧的缓冲区
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if (ioctl(cam_fd, VIDIOC_REQBUFS, &req) < 0)
{
printf("VIDIOC_REQBUFS failed\n");
return -1;
}
printf("8\n");
buffers = (VideoBuffer *)calloc(req.count, sizeof(*buffers));
// 映射
printf("9\n");
for (numBufs = 0; numBufs < req.count; numBufs++)
{
printf("10\n");
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = numBufs;
// 查询序号为numBufs的缓冲区,得到其起始物理地址和大小
if (ioctl(cam_fd, VIDIOC_QUERYBUF, &buf) == -1) // 读取缓存
return -1;
buffers[numBufs].length = buf.length;
// 转换成相对地址
//映射内存
printf("11\n");
buffers[numBufs].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, cam_fd, buf.m.offset);//返回所分配的内存空间的首地址。
/*
void *mmap(void*addr, size_t length, int prot, int flags, int fd, off_t offset);
//addr 映射起始地址,一般为NULL ,让内核自动选择
//length 被映射内存块的长度
//prot 标志映射后能否被读写,其值为PROT_EXEC,PROT_READ,PROT_WRITE,PROT_NONE
//flags 确定此内存映射能否被其他进程共享,MAP_SHARED,MAP_PRIVATE
//fd,offset, 确定被映射的内存地址
返回成功映射后的地址,不成功返回MAP_FAILED ((void*)-1);*/
if (buffers[numBufs].start == MAP_FAILED)
return -1;
printf("12\n");
//VIDIOC_QBUF// 把帧放入队列
//VIDIOC_DQBUF// 从队列中取出帧
if (ioctl(cam_fd, VIDIOC_QBUF, &buf) == -1)// 放入缓存队列
return -1;
printf("13\n");
}
// 在开始之前,还应当把缓冲帧放入缓冲队列:
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
printf("14\n");
if (ioctl(cam_fd, VIDIOC_STREAMON, &type) < 0) //开始视屏流数据的采集
{
printf("VIDIOC_STREAMON error\n");
return -1;
}
printf("15\n");
//InitLookupTable();//实现的函数调用有InitLookupTable()用于初始化色彩空间转换;
return 0;
}
void init_param(T264_param_t* param, const char* file)
{
int total_no;
FILE* fd;
char line[255];
int32_t b;
if (!(fd = fopen(file,"r")))
{
printf("Couldn't open parameter file %s.\n", file);
exit(-1);
}
memset(param, 0, sizeof(*param));
fgets(line, 254, fd); sscanf(line,"%d", &b);
if (b != 4)
{
printf("wrong param file version, expect v4.0\n");
exit(-1);
}
fgets(line, 254, fd); sscanf(line,"%d", ¶m->width);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->height);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->search_x);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->search_y);
fgets(line, 254, fd); sscanf(line,"%d", &total_no);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->iframe);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->idrframe);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->b_num);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->ref_num);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->enable_rc);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->bitrate);
fgets(line, 254, fd); sscanf(line,"%f", ¶m->framerate);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->qp);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->min_qp);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->max_qp);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->enable_stat);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->disable_filter);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->aspect_ratio);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->video_format);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->luma_coeff_cost);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_INTRA16x16) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_INTRA4x4) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_INTRAININTER) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_HALFPEL) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_QUARTPEL) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_SUBBLOCK) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_FULLSEARCH) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_DIAMONDSEACH) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_FORCEBLOCKSIZE) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_FASTINTERPOLATE) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_SAD) * b;
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_EXTRASUBPELSEARCH) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_SCENEDETECT) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_16x16P) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_16x8P) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_8x16P) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_8x8P) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_8x4P) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_4x8P) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_4x4P) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_16x16B) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_16x8B) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_8x16B) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_8x8B) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->cpu);
fgets(line, 254, fd); sscanf(line, "%d", ¶m->cabac);
// fgets(line, 254, fd); sscanf(line,"%s", src_path);
// fgets(line, 254, fd); sscanf(line,"%s", out_path);
// fgets(line, 254, fd); sscanf(line,"%s", rec_path);
// param->rec_name = rec_path;
fclose(fd);
}
void init_encoder()
{
//编码准备
const char* paramfile = "fastspeed.txt";
/*获取fastspeed.txt文件信息*/
init_param(&m_param, paramfile);
printf("1\n");
m_param.direct_flag = 1;
/*t264编码的打开*/
//T264_t *T264_open(¶m) 根据param 参数配置,打开并初始化一个编码器实例,返回编码器实例指针,可以当成句柄理解。
m_t264 = T264_open(&m_param);
m_lDstSize = m_param.height * m_param.width + (m_param.height * m_param.width >> 1);
/*分配t264解码后数据存放的内存*/
m_pDst = (uint8_t*)T264_malloc(m_lDstSize, CACHE_SIZE); // uint8_t *T264_malloc(size, CACHE_SIZE),分配内存,大小为 size,返回内存区指针。
printf("2\n");
/*分配内存用于存放一帧数据长度的数据*/
m_pPoolData = malloc(m_param.width*m_param.height*3/2);
printf("3\n");
}
void udps_respon(int sockfd,int w,int h)
{
struct sockaddr_in addrsrc;
struct sockaddr_in addrdst;
int addrlen,n;
int32_t iActualLen;
int row_stride = w*3*h/2;
bzero(&addrdst,sizeof(struct sockaddr_in));
addrdst.sin_family=AF_INET;
/*客户端PC机IP地址*/
addrdst.sin_addr.s_addr=inet_addr("192.168.1.1");
addrdst.sin_port=htons(SERVER_PORT);
while(1)
{
/*数据的采集*/
if(read_video(0))
exit(1);
/*对采集到的数据通过H264编码*/
iActualLen = T264_encode(m_t264,buffers[0].start, m_pDst, row_stride);
printf("encoded:%d, %d bytes.\n",row_stride,iActualLen);
/*frame_num:存放帧号*/
memcpy(m_pPoolData,&m_t264->frame_num,1);
/*m_pDst解码后的数据*/
memcpy(m_pPoolData+1, m_pDst, iActualLen);
iActualLen++;
/*使用UDP协议发送编码后的数据到客服端*/
sendto(sockfd,m_pPoolData,iActualLen,0,(struct sockaddr*)&addrdst,sizeof(struct sockaddr_in));
}
}
void free_dev()
{
printf("free device\n");
close(cam_fd);
}
/*主函数入口*/
int main(void)
{
int sockfd;
struct sockaddr_in addr;
printf("start 2.0...\n");
/*创建套接字*/
sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(sockfd<0)
{
printf("0-");
printf("Socket Error\n");
exit(1);
}
bzero(&addr,sizeof(struct sockaddr_in));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=htonl(INADDR_ANY);
addr.sin_port=htons(SERVER_PORT);
/*套接字绑定*/
if(bind(sockfd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in))<0 )
{
printf("Socket Error\n");
exit(1);
}
/*该函数完成编码前的准备*/
init_encoder();
atexit(&free_dev ); //(即main执行结束后调用的函数)
/*采集数据前的初始化函数*/
if (init_video(m_param.width,m_param.height))
{
printf("init_vodeo Error\n");
exit(1);
}
/*使用UDP协议发送采集到的数据*/
udps_respon(sockfd,m_param.width,m_param.height);
close(sockfd);
}
//WB
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <linux/types.h>
#include <linux/videodev2.h>
#include <setjmp.h>
#include <string.h>
#include <signal.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "convert.h"
#include "../avc-src-0.14/avc/common/T264.h"
#define SERVER_PORT 8888
#define WIDTH 160
#define HEIGHT 120
#define FRAME_COUNT 1 //?建?????
#define FRAME_IDLE 60
T264_t* m_t264;
T264_param_t m_param;
char* m_pSrc;
char* m_pDst;
int* m_lDstSize;
char* m_pPoolData;
#define USB_VIDEO "/dev/video0"
typedef struct VideoBuffer //定义一个结构体来映射每个缓冲帧
{
void *start;
size_t length;
}VideoBuffer;
static int cam_fd;
static VideoBuffer *buffers = NULL;
static unsigned int numBufs = 0;
static int read_video(int index)
{
struct v4l2_buffer buf;
memset(&buf,0,sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = index;
//VIDIOC_DQBUF 从队列中取出帧
if (ioctl(cam_fd, VIDIOC_DQBUF, &buf) == -1)
return -1;
/*图像处理
process_image(buffers[buf.index].start); */
//将取出的缓冲帧放回缓冲区
if (ioctl(cam_fd, VIDIOC_QBUF, &buf) == -1)
return -1;
return 0;
}
static int init_video(int w,int h) /* bpp == bytes per pixel*/
{
/*设备的打开*/
cam_fd = open( USB_VIDEO, O_RDWR );
if(cam_fd<0 )
printf("Can't open video device\n");
/* 使用IOCTL命令VIDIOCGCAP,获取摄像头的基本信息,如最大,最小分辨率*/
struct v4l2_capability cap;
if (ioctl (cam_fd, VIDIOC_QUERYCAP, &cap) == -1)
{
printf("Get camara capability is fail.\n");
return -1;
}
printf("camara driver: %s\n", cap.driver);
printf("camara card: %s\n", cap.card);
printf("camara bus info: %s\n", cap.bus_info);
printf("camara version: %d\n", cap.version);
printf("4\n");
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) //是否支持图像获取
{
printf("Camara does not support VIDEO CAPTURE.\n");
return -1;
}
printf("5\n");
if (!(cap.capabilities & V4L2_CAP_STREAMING)) //I/O的读写控制流
{
printf("Camara does not support STREAMING.\n");
return -1;
}
printf("6\n");
struct v4l2_format fmt;
memset(&fmt, 0, sizeof(fmt));
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = WIDTH;//帧宽 帧高 单位像素
fmt.fmt.pix.height = HEIGHT;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_MJPEG;
fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
if (ioctl(cam_fd, VIDIOC_S_FMT, &fmt) == -1)//检查是否支持V4L2_PIX_FMT_MJPEG 格式
{
printf("Camara set fmt is errror.\n");
return -1;
}
printf("7\n");
struct v4l2_requestbuffers req;
enum v4l2_buf_type type; //enum v4l2_buf_type type; //数据流类型,必须永远是V4L2_BUF_TYPE_VIDEO_CAPTURE
struct v4l2_buffer buf;
memset(&req, 0, sizeof (req));
req.count = FRAME_COUNT;缓存数量,也就是说在缓存队列里保持多少张照片 申请一个拥有FRAME_COUNT个缓冲帧的缓冲区
req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
req.memory = V4L2_MEMORY_MMAP;
if (ioctl(cam_fd, VIDIOC_REQBUFS, &req) < 0)
{
printf("VIDIOC_REQBUFS failed\n");
return -1;
}
printf("8\n");
buffers = (VideoBuffer *)calloc(req.count, sizeof(*buffers));
// 映射
printf("9\n");
for (numBufs = 0; numBufs < req.count; numBufs++)
{
printf("10\n");
memset(&buf, 0, sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = numBufs;
// 查询序号为numBufs的缓冲区,得到其起始物理地址和大小
if (ioctl(cam_fd, VIDIOC_QUERYBUF, &buf) == -1) // 读取缓存
return -1;
buffers[numBufs].length = buf.length;
// 转换成相对地址
//映射内存
printf("11\n");
buffers[numBufs].start = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, cam_fd, buf.m.offset);//返回所分配的内存空间的首地址。
/*
void *mmap(void*addr, size_t length, int prot, int flags, int fd, off_t offset);
//addr 映射起始地址,一般为NULL ,让内核自动选择
//length 被映射内存块的长度
//prot 标志映射后能否被读写,其值为PROT_EXEC,PROT_READ,PROT_WRITE,PROT_NONE
//flags 确定此内存映射能否被其他进程共享,MAP_SHARED,MAP_PRIVATE
//fd,offset, 确定被映射的内存地址
返回成功映射后的地址,不成功返回MAP_FAILED ((void*)-1);*/
if (buffers[numBufs].start == MAP_FAILED)
return -1;
printf("12\n");
//VIDIOC_QBUF// 把帧放入队列
//VIDIOC_DQBUF// 从队列中取出帧
if (ioctl(cam_fd, VIDIOC_QBUF, &buf) == -1)// 放入缓存队列
return -1;
printf("13\n");
}
// 在开始之前,还应当把缓冲帧放入缓冲队列:
type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
printf("14\n");
if (ioctl(cam_fd, VIDIOC_STREAMON, &type) < 0) //开始视屏流数据的采集
{
printf("VIDIOC_STREAMON error\n");
return -1;
}
printf("15\n");
//InitLookupTable();//实现的函数调用有InitLookupTable()用于初始化色彩空间转换;
return 0;
}
void init_param(T264_param_t* param, const char* file)
{
int total_no;
FILE* fd;
char line[255];
int32_t b;
if (!(fd = fopen(file,"r")))
{
printf("Couldn't open parameter file %s.\n", file);
exit(-1);
}
memset(param, 0, sizeof(*param));
fgets(line, 254, fd); sscanf(line,"%d", &b);
if (b != 4)
{
printf("wrong param file version, expect v4.0\n");
exit(-1);
}
fgets(line, 254, fd); sscanf(line,"%d", ¶m->width);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->height);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->search_x);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->search_y);
fgets(line, 254, fd); sscanf(line,"%d", &total_no);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->iframe);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->idrframe);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->b_num);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->ref_num);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->enable_rc);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->bitrate);
fgets(line, 254, fd); sscanf(line,"%f", ¶m->framerate);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->qp);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->min_qp);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->max_qp);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->enable_stat);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->disable_filter);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->aspect_ratio);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->video_format);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->luma_coeff_cost);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_INTRA16x16) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_INTRA4x4) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_INTRAININTER) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_HALFPEL) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_QUARTPEL) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_SUBBLOCK) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_FULLSEARCH) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_DIAMONDSEACH) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_FORCEBLOCKSIZE) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_FASTINTERPOLATE) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_SAD) * b;
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_EXTRASUBPELSEARCH) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->flags |= (USE_SCENEDETECT) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_16x16P) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_16x8P) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_8x16P) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_8x8P) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_8x4P) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_4x8P) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_4x4P) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_16x16B) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_16x8B) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_8x16B) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", &b);
param->block_size |= (SEARCH_8x8B) * (!!b);
fgets(line, 254, fd); sscanf(line,"%d", ¶m->cpu);
fgets(line, 254, fd); sscanf(line, "%d", ¶m->cabac);
// fgets(line, 254, fd); sscanf(line,"%s", src_path);
// fgets(line, 254, fd); sscanf(line,"%s", out_path);
// fgets(line, 254, fd); sscanf(line,"%s", rec_path);
// param->rec_name = rec_path;
fclose(fd);
}
void init_encoder()
{
//编码准备
const char* paramfile = "fastspeed.txt";
/*获取fastspeed.txt文件信息*/
init_param(&m_param, paramfile);
printf("1\n");
m_param.direct_flag = 1;
/*t264编码的打开*/
//T264_t *T264_open(¶m) 根据param 参数配置,打开并初始化一个编码器实例,返回编码器实例指针,可以当成句柄理解。
m_t264 = T264_open(&m_param);
m_lDstSize = m_param.height * m_param.width + (m_param.height * m_param.width >> 1);
/*分配t264解码后数据存放的内存*/
m_pDst = (uint8_t*)T264_malloc(m_lDstSize, CACHE_SIZE); // uint8_t *T264_malloc(size, CACHE_SIZE),分配内存,大小为 size,返回内存区指针。
printf("2\n");
/*分配内存用于存放一帧数据长度的数据*/
m_pPoolData = malloc(m_param.width*m_param.height*3/2);
printf("3\n");
}
void udps_respon(int sockfd,int w,int h)
{
struct sockaddr_in addrsrc;
struct sockaddr_in addrdst;
int addrlen,n;
int32_t iActualLen;
int row_stride = w*3*h/2;
bzero(&addrdst,sizeof(struct sockaddr_in));
addrdst.sin_family=AF_INET;
/*客户端PC机IP地址*/
addrdst.sin_addr.s_addr=inet_addr("192.168.1.1");
addrdst.sin_port=htons(SERVER_PORT);
while(1)
{
/*数据的采集*/
if(read_video(0))
exit(1);
/*对采集到的数据通过H264编码*/
iActualLen = T264_encode(m_t264,buffers[0].start, m_pDst, row_stride);
printf("encoded:%d, %d bytes.\n",row_stride,iActualLen);
/*frame_num:存放帧号*/
memcpy(m_pPoolData,&m_t264->frame_num,1);
/*m_pDst解码后的数据*/
memcpy(m_pPoolData+1, m_pDst, iActualLen);
iActualLen++;
/*使用UDP协议发送编码后的数据到客服端*/
sendto(sockfd,m_pPoolData,iActualLen,0,(struct sockaddr*)&addrdst,sizeof(struct sockaddr_in));
}
}
void free_dev()
{
printf("free device\n");
close(cam_fd);
}
/*主函数入口*/
int main(void)
{
int sockfd;
struct sockaddr_in addr;
printf("start 2.0...\n");
/*创建套接字*/
sockfd=socket(AF_INET,SOCK_DGRAM,0);
if(sockfd<0)
{
printf("0-");
printf("Socket Error\n");
exit(1);
}
bzero(&addr,sizeof(struct sockaddr_in));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=htonl(INADDR_ANY);
addr.sin_port=htons(SERVER_PORT);
/*套接字绑定*/
if(bind(sockfd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in))<0 )
{
printf("Socket Error\n");
exit(1);
}
/*该函数完成编码前的准备*/
init_encoder();
atexit(&free_dev ); //(即main执行结束后调用的函数)
/*采集数据前的初始化函数*/
if (init_video(m_param.width,m_param.height))
{
printf("init_vodeo Error\n");
exit(1);
}
/*使用UDP协议发送采集到的数据*/
udps_respon(sockfd,m_param.width,m_param.height);
close(sockfd);
}