1. 程式人生 > 實用技巧 >基於視訊壓縮的實時監控系統-sprint3採集端傳輸子系統設計

基於視訊壓縮的實時監控系統-sprint3採集端傳輸子系統設計

  由於jpg本來就是編碼壓縮後的格式,所有無需重複編碼

傳輸子系統步驟:(1)初始化:a.socket(初始化tcp連線);b.將事件新增到epoll中

         (2)事件處理:接收到網路包、傳送完網路包

struct tcp_srv* net_sys_init()
{
    struct tcp_srv* s;
    struct sockaddr_in addr;
    struct sockaddr_in sin;
    struct tcp_cli* c;
    int len;

    s = calloc(1, sizeof(struct tcp_srv));
    c 
= calloc(1, sizeof(struct tcp_cli)); //1. 初始化傳輸子系統(socket初始化) //1.1 建立socket s->sock = socket(AF_INET, SOCK_STREAM, 0); //1.2 初始化地址 addr.sin_addr.s_addr = INADDR_ANY; addr.sin_family = AF_INET; addr.sin_port = htons(DEF_TCP_SRV_PORT); //1.3 bind地址 bind(s->sock, (struct
sockaddr*)&addr, sizeof(struct sockaddr)); //1.4 listen listen(s->sock, 5); //1.5 accept c->sock = accept(s->sock, (struct sockaddr*)&sin, &len); memcpy(&(c->addr), &sin, len); //2. 將傳輸子系統中的事件加入epoll池 c->ev_rx = epoll_event_create(c->sock, EPOLLIN, rx_app_handler, c); c
->ev_tx = epoll_event_create(c->sock, EPOLLOUT, tx_app_handler, c); epoll_add_event(srv_main->epfd, c->ev_rx); return s; } void tx_app_handler(int sock, void* arg) { //傳送事件 struct tcp_cli* c = arg; send(sock, c->buf, c->len, 0); epoll_del_event(srv_main->epfd, c->ev_tx); epoll_add_event(srv_main->epfd, c->ev_rx); } void rx_app_handler(int sock, void* arg) { //接收事件 unsigned char* pbuf;//儲存讀取的資料 struct tcp_cli* c = arg; pbuf = &(c->req[0]); read(c->sock, pbuf, FRAME_HDR_SZ); process_incoming(c);//資料處理子函式 } int process_incoming(struct tcp_cli* c) { //針對不同的命令做處理 __u8 id; __u8 data[FRAME_DAT_MAX];//資料最大長度 struct cam* v = srv_main->cam; __u8* req = c->req; __u8* rsp = c->rsp; __u8 status = ERR_SUCCESS; __u32 pos, len, size; id = req[CMD1_POS];//請求的ID switch (id) { case REQUEST_ID(VID_GET_FMT)://VID_GET_FMT //1. 獲取影象格式 cam_get_fmt(v, data); //2. 構造返回資料 build_ack(rsp, (TYPE_SREQ << TYPE_BIT_POS) | SUBS_VID, id, 4, data); //3. 傳送返回資料 net_send(c, rsp, FRAME_HDR_SZ + 4); break; case REQUEST_ID(VID_REQ_FRAME)://VID_REQ_FRAME //1. 獲取一幀影象 pos = FRAME_HDR_SZ + 4; size = cam_get_trans_frame(v, &rsp[pos]);//獲取到影象的長度; //2. 構造返回資料,按照要求的格式數傳送 build_ack(rsp, (TYPE_SREQ << TYPE_BIT_POS) | SUBS_VID, id, 4, (__u8*)&size); //3. 傳送返回資料 net_send(c, rsp, FRAME_HDR_SZ + 4 + size); break; default: break; } return status; } int build_ack(unsigned char* rsp, unsigned char type, unsigned char id, unsigned char len, unsigned char* data) { //cam.c構造返回資料 rsp[LEN_POS] = len; rsp[CMD0_POS] = type; rsp[CMD1_POS] = id; memcpy(&rsp[DAT_POS], data, len); return len + FRAME_HDR_SZ; } void net_send(struct tcp_cli* tc, void* buf, int len) { // 傳送返回資料 struct tcp_cli* c = (struct tcp_cli*)tc; struct tcp_srv* s = c->srv; epoll_del_event(s->epfd, c->ev_rx); c->buf = buf; c->len = len; epoll_add_event(srv_main->epfd, c->ev_tx); }