基类:
//.h
typedef int (*TELE_SEND_CB)(char *pdata, int len); //函数表结构 typedef struct tele_pro_base_vtbl { int (*trans_data)(int chun,enum rtsp_frame_type type, char *pdata, unsigned int len,unsigned int ts); int (*send_cmd)(int cmd,char *para,unsigned int len); int (*parse_cmd)(char *data_in, int size_in, void *data_out); }tele_pro_base_vtbl_t; //基类 typedef struct tele_pro_base { /*virtual table*/ tele_pro_base_vtbl_t *vptr; TELE_SEND_CB send_cb; }tele_pro_base_t; int akp_tele_pro_low_send(tele_pro_base_t *this,char *pdata,unsigned int len); tele_pro_base_t * akp_tele_pro_base_ctor(TELE_SEND_CB send_cb); int akp_tele_pro_send_cmd(tele_pro_base_t *this,int cmd,char *pdata,unsigned int len); int akp_tele_pro_trans_data(tele_pro_base_t *this,int chun,enum rtsp_frame_type type, char *pdata, unsigned int len,unsigned int ts); int akp_tele_pro_parse_cmd(tele_pro_base_t *this, char *data_in, int size_in, void *data_out);
// .c
/****************************************************** * Constant ******************************************************/ /****************************************************** * Macro ******************************************************/ /****************************************************** * Type Definitions ******************************************************/ /****************************************************** * Global Variables ******************************************************/ static tele_pro_base_t *ptele_pro_base = NULL; /****************************************************** * Function interface ******************************************************/ static int __send(char *pdata,unsigned int len) { int ret = 0;; if(NULL != ptele_pro_base->send_cb) { ret = ptele_pro_base->send_cb(pdata,len); } return ret; } static int anyka_trans_data(int chun,enum rtsp_frame_type type, \ char *pdata, unsigned int len,unsigned int ts) { int ret = -1; ret = ak_rtsp_send_stream(chun,type,pdata,len,ts); return ret; } static int anyka_send_cmd(int cmd,char *pdata,unsigned int len) { int ret = 0; unsigned int len_out = 0; char *pout = malloc(len+TEL_CTRLPRO_FRAME_SIZE_MIN); akp_tel_ctrlpro_pack(cmd, pdata, len, pout, &len_out); if(len_out > len+TEL_CTRLPRO_FRAME_SIZE_MIN) { ak_print_error("akp_tel_ctrlpro_pack error\n"); ret = -1; } ret = __send(pout, len_out); free(pout); return ret; } /** * akp_tel_ctrlpro_parse-report net state to observer * @data_in[IN]: recv data. * @size_in[IN]: recv data lenght. * @data_out[IN]: out frame data. * eg: akp_tel_ctrlpro_parse(recv_buf, len,parse_buf); * tel_video_set_t video_para = (tel_video_set_t)parse_buf; * return: > 0 command, -1 error, -2 continue recv * notes: if have data,pl ensure length > TEL_CTRLPRO_FRAME_SIZE_MAX */ static int anyka_parse_cmd(char *data_in, int size_in, void *data_out) { return akp_tel_ctrlpro_parse(data_in, size_in,data_out); } /* 可多态的函数表 */ static tele_pro_base_vtbl_t base_table = { anyka_trans_data, anyka_send_cmd, anyka_parse_cmd }; //基类的构造函数 tele_pro_base_t * akp_tele_pro_base_ctor(TELE_SEND_CB send_cb) { tele_pro_base_t *temp = (tele_pro_base_t *)malloc(sizeof(tele_pro_base_t)); temp->vptr = &base_table; temp->send_cb = send_cb; ptele_pro_base = temp; return temp; } //基类方法 int akp_tele_pro_low_send(tele_pro_base_t *this,char *pdata,unsigned int len) { int ret = 0;; if(NULL != this->send_cb) { ret = this->send_cb(pdata,len); } return ret; } int akp_tele_pro_send_cmd(tele_pro_base_t *this,int cmd,char *pdata,unsigned int len) { int ret = 0; if(NULL != this->vptr->send_cmd) { ret = this->vptr->send_cmd(cmd,pdata,len); } else { ak_print_warning_ex("tele pro send cmd fun is null\n"); ret = -1; } return ret; } int akp_tele_pro_trans_data(tele_pro_base_t *this,int chun,enum rtsp_frame_type type, char *pdata, unsigned int len,unsigned int ts) { int ret = 0; if(NULL != this->vptr->trans_data) { ret = this->vptr->trans_data(chun,type,pdata,len ,ts); } else { ak_print_warning_ex("tele pro trans data fun is null\n"); ret = -1; } return ret; } int akp_tele_pro_parse_cmd(tele_pro_base_t *this, char *data_in, int size_in, void *data_out) { int ret = 0; if(NULL != this->vptr->parse_cmd) { ret = this->vptr->parse_cmd(data_in,size_in,data_out); } else { ak_print_warning_ex("tele pro parse cmd fun is null\n"); ret = -1; } return ret; }
派生类:
// .h
#define JUAN_TXBUF_SIZE 1024 #define JUAN_PARSE_BUF_SIZE 2048 typedef struct tele_pro_juan { tele_pro_base_t base; unsigned int ssrc; unsigned short seqNumber; int fw_type; unsigned int fw_size; unsigned int fw_seq; int buf_len; char parse_buf[JUAN_PARSE_BUF_SIZE]; int tx_buf_length; char tx_buf[JUAN_TXBUF_SIZE]; ak_mutex_t mutex_tx; }tele_pro_juan_t; int akp_telepro_juan_post_describe(int chun); tele_pro_juan_t* akp_tele_pro_juan_data_chun_ctor(TELE_SEND_CB send_cb);
// .c
//------------------基类函数的多态实现--------------------- static int juan_trans_data(int chun,enum rtsp_frame_type type, char *pdata, unsigned int len,unsigned int ts_ms) { int ret = -1; static unsigned long bit_len = 0; static unsigned long t1 = 0; unsigned long t2; ak_thread_mutex_lock(&ptele_pro->mutex_tx); // calculate bsp if(0 == bit_len) { t1 = ak_get_tick_count_ms(); } bit_len += len; t2 = ak_get_tick_count_ms(); if(t2-t1 >= 1000) { ak_print_notice("[juan rtsp]: bps=%d\n",bit_len*8); bit_len = 0; } unsigned int ts = ts_ms*1000; if(RTSP_AFRAME == type) { ret = __juan_data_chun_send_data(HICHIP_FRAME_TYPE_UNUSE,HICHIP_MD_TYPE_G711,pdata,len,ts); } else if(RTSP_IFRAME == type){ ret = __juan_data_chun_send_data(HICHIP_FRAME_TYPE_BASE_IDRSLICE,HICHIP_MD_TYPE_H264,pdata,len,ts); } else if(RTSP_PFRAME == type) { ret = __juan_data_chun_send_data(HICHIP_FRAME_TYPE_UNUSE,HICHIP_MD_TYPE_H264,pdata,len,ts); } else { ak_print_error("[tele]: donot support this frame type=%d\n",type); } ak_thread_mutex_unlock(&ptele_pro->mutex_tx); return ret; } static int juan_data_chun_send_cmd(int cmd,char *para,unsigned int len) { int ret = 0; ak_thread_mutex_lock(&ptele_pro->mutex_tx); switch(cmd) { case TELE_MSG_SEND_LOGIN: ak_print_normal("[anyka]: UL_WAKEUP_IND_MSG\n"); __juan_data_chun_post_describe(0); __juan_data_chun_login(); break; case TELE_MSG_SEND_DEVINFO: { ring_dev_info_t *dev_info = (ring_dev_info_t *)para; unsigned int event = 0; unsigned int io = 0; if(WAKEUP_EVENT_PIR == dev_info->wake_event) { event |= NK_HICHIP_EVENT_IO; io |= NK_HICHIP_IO_PIR; } if(dev_info->md) { event |= NK_HICHIP_EVENT_MD; } ak_print_normal_ex("stream chun: event=%d io=%d\n",event,io); __juan_data_chun_send_cmd(event,io); }break; default: //ak_print_warning_ex("[tele]: donot support this cmd=%d\n",cmd); break; } ak_thread_mutex_unlock(&ptele_pro->mutex_tx); return ret; } /** * akp_tel_ctrlpro_parse-report net state to observer * @data_in[IN]: recv data. * @size_in[IN]: recv data lenght. * @data_out[IN]: out frame data. * eg: akp_tel_ctrlpro_parse(recv_buf, len,parse_buf); * tel_video_set_t video_para = (tel_video_set_t)parse_buf; * return: > 0 command, -1 error, -2 continue recv * notes: if have data,pl ensure length > TEL_CTRLPRO_FRAME_SIZE_MAX */ static int juan_data_chun_parse_cmd(char* data_in, int size_in, void *data_out) { char *recv_buf = ptele_pro->parse_buf; int cmd_len; int ret = -2; int i; for(i = 0; i< size_in; i++) { juan_debug_log("%c",data_in[i]); } juan_debug_log("\n"); #if 1 /* join data */ memcpy(recv_buf+ptele_pro->buf_len,data_in, size_in); ptele_pro->buf_len += size_in; cmd_len = find_string(recv_buf,ptele_pro->buf_len,"\r\n"); juan_debug_log("cmd_len=%d\n",cmd_len); if(cmd_len > 0) { ret = __juan_data_chun_do_cmd(recv_buf,cmd_len+2,data_out); //ak_print_normal("cmd ret = %d DL_START_VIDEO_MSG=%d\n",ret,DL_START_VIDEO_MSG); memcpy(recv_buf, recv_buf+cmd_len, ptele_pro->buf_len-cmd_len); ptele_pro->buf_len -= cmd_len; memset(recv_buf + ptele_pro->buf_len, 0, cmd_len); } if(ptele_pro->buf_len > JUAN_PARSE_BUF_SIZE-64) { ak_print_warning_ex(" ptele_pro->parse_buf have too many data\n"); } return ret; #else if(strstr(data_in,"HTTP/1.1 100") != NULL) { ret = DL_START_VIDEO_MSG; } return ret; #endif } /*函数表 */ static tele_pro_base_vtbl_t vir_table = { juan_trans_data, juan_data_chun_send_cmd, juan_data_chun_parse_cmd }; //派生类的构造函数 tele_pro_juan_t* akp_tele_pro_juan_data_chun_ctor(TELE_SEND_CB send_cb) { tele_pro_juan_t *temp= (tele_pro_juan_t*)malloc(sizeof(tele_pro_juan_t)); temp->base.vptr = &vir_table; temp->base.send_cb = send_cb; ptele_pro = temp; memset(ptele_pro->parse_buf,0,sizeof(ptele_pro->parse_buf)); ptele_pro->buf_len = 0; ak_thread_mutex_init(&ptele_pro->mutex_tx,NULL); return temp; }