在DVR中增加系统模式CGI接口

任务描述

1,协议定义并实现

需要增加的接口:

1)获取设备当前模式:

D1, 960H

AHD, TVI

HVR3IN1-AHD-720P, HVR3IN1-AHD-1080P-H, HVR-3IN1-AHD-1080P

HVR4IN1-720P, HVR4IN1-1080P-H, HVR-4IN1-1080P

2)获取当前通道模式,

960H,AHD, AHD1.0,AHD2.0,TV, TVI1.0, TVI2.0, AUTO, IPC

3)获取输入摄像头类型,包括类型和分辨率,帧率

类型vinType:960H,AHD, TVI

分辨率vinResolution:d1, 960H, 720P, 1080P(扩充:3M, 4M, 5M, 8M)

帧率vinFramerate:25,30,50,60

4) 获取通道编码能力集

所有支持的分辨率

当前分辨率的帧率取值范围

当前分辨率的码率取值范围

编码格式取值范围


一、获取设备当前模式

1、判断是否定义了_HVR这个宏(在配置文件clnf.h中可以查看),已经定义这个宏说明设备模式是HVR3IN1(三合一)或者是HVR4IN1(四合一),具体是几合一就得判断decode芯片是AHD(三合一)还是TVI(四合一)。接着判断支持的最高视频格式,调用JDK_vin_get_max_support()函数即可,最后判断是否定义了_EXT_HDDVR_LITE这个宏(在配置文件clnf.h中可以查看),定义了为half类型,没定义则不是half。如果_HVR这个宏没定义的话则是其他模式了,比如D1、960H、TVI、AHD等等。


2、在app2cgi_communication.c中添加命令类型CMD_GET_DEV_MODEL:

	case CMD_GET_DEV_MODEL:	
		cmd.dev_info.info.hvr = NULL;
		cmd.dev_info.info.half = NULL;
		cmd.dev_info.info.format = NULL;
#if defined(_HVR)
		if(strcmp(HDDVR_AD_AHD_TYPE, HDDVR_GetMODELType()) == 0){
			cmd.dev_info.info.hvr = "HVR3IN1-AHD"; 
		}
		else if(strcmp(HDDVR_AD_TVI_TYPE, HDDVR_GetMODELType()) == 0){
			cmd.dev_info.info.hvr = "HVR4IN1"; 
		}	
  #ifdef _EXT_HDDVR_LITE
	cmd.dev_info.info.half = "H";
  #endif
		
 		MaxSupport = JDK_vin_get_max_support();
		switch(MaxSupport){
			case 0:
				cmd.dev_info.info.format = "960H";
				break;
			case 1:
				cmd.dev_info.info.format = "720P";
				break;
			case 2:
				cmd.dev_info.info.format = "1080P";
				break;
			default:
				break;	
		}
#else
  #ifdef _EXT_HDDVR
  		cmd.dev_info.info.hvr = HDDVR_GetMODELType();
  #endif
#endif
		cmd.type = CMD_GET_DEV_MODEL_ACK;                //CMD_GET_DEV_MODEL_ACK说明这个命令已经被处理了
		SEND_DVRCMD_ACK(cmd, _socket_index);              //把处理结果发回cgi_gw.c
		break;

3、在cgi_gw.c中获取网页发过来的xml信息(通道号、命令、参数等等),然后用TCP协议发给APP并接受app2cgi_communication.c发回来的处理结果,最后反馈给网页:

static void proc_juan_getdevmodel(UniStructNode* root_in, UniStructNode* root_out)
{
	UniStructNodesList* tmp_nodes_in;
	UniStructNode* tmp_node_in;
	UniStructNode* tmp_node_out;
	UniStructAttr* tmp_attr_in;
//	UniStructAttr* tmp_attr_out;

	tmp_nodes_in = UniStruct_find_children(root_in, "devmodel");
	if(tmp_nodes_in != NULL)
	{
		int i;
		for(i = 0; i < tmp_nodes_in->count; i++)
		{
			tmp_node_in = tmp_nodes_in->nodes[i];
			tmp_node_out = UniStruct_append_child(root_out, "devmodel", "");
			UniStruct_append_attr(tmp_node_out, "errno", _convert_from_enum(JUAN_ERRNO_NO_ERROR));

			char* usr = NULL;
			char* pwd = NULL;
			CHK_USR_PWD(JUAN_ERRNO_USR_OR_PWD_ERROR);

#define PTZCTRL_PROC_START(key) \
{ \
tmp_attr_in = UniStruct_find_attr(tmp_node_in, key); \
if(tmp_attr_in != NULL) \
{ \

#define PTZCTRL_PROC_END(key) \
	UniStruct_append_attr(tmp_node_out, key, tmp_attr_in->value); \
} \
}
			int chn = -1;
			int param = -1;

			PTZCTRL_PROC_START("chn");
			chn = _convert_from_string(tmp_attr_in->value);
			PTZCTRL_PROC_END("chn");

			PTZCTRL_PROC_START("param");
			param = _convert_from_string(tmp_attr_in->value);
			PTZCTRL_PROC_END("param");

			if(chn == -1 || param == -1)
			{
				UniStruct_modify_attr(tmp_node_out, "errno", _convert_from_enum(JUAN_ERRNO_PARAM_ERROR));
				continue;
			}
			///
			DVRCommand_t dvr_cmd;
			memset(&dvr_cmd, 0, sizeof(DVRCommand_t));
			dvr_cmd.flag = DVR_CMD_FLAG;
			dvr_cmd.type = CMD_GET_DEV_MODEL;
			dvr_cmd.dev_info.nChn = chn;
			dvr_cmd.dev_info.u8Val = param;

			SEND_CMD_TO_APP(dvr_cmd, SEND_CMD_TO_APP_TIMEOUT);     //把收到的xml信息填充好dvr_cmd结构体,然后发给APP
			if(dvr_cmd.type != CMD_GET_DEV_MODEL_ACK)              //判断APP那边是否已经处理了这条命令
			{
				UniStruct_modify_attr(tmp_node_out, "errno", _convert_from_enum(JUAN_ERRNO_APP_RESPONSE_ERROR));
				continue;
			}
			else{
				char devmodel_content[128];
				if(dvr_cmd.dev_info.info.hvr && dvr_cmd.dev_info.info.format){
					if(dvr_cmd.dev_info.info.half){
						sprintf(devmodel_content, "%s-%s-%s",	dvr_cmd.dev_info.info.hvr,
											dvr_cmd.dev_info.info.format,
											dvr_cmd.dev_info.info.half);
					}
					else{
						sprintf(devmodel_content, "%s-%s",	dvr_cmd.dev_info.info.hvr,
											dvr_cmd.dev_info.info.format);
					}
				}
				else{
					sprintf(devmodel_content, "%s", dvr_cmd.dev_info.info.hvr);
				}
				UniStruct_append_child(tmp_node_out, "devmodel", devmodel_content);   //把要反馈给网页的信息放到等待发送的队列中
			}
		}
		UniStruct_free_nodes_list(tmp_nodes_in);
		tmp_nodes_in = NULL;
	}
}


二、获取当前通道模式

1、首先判断通道模式是否为JDK_INPUT_FORMAT_AUTO(四合一都会是这个):

如果是的话再判断是否为IPC(数字通道),VIDEO_TYPE_960H_TVI(对应显示器界面上的自动选项),VIDEO_TYPE_AHD(对应界面上的AHD选项)。

如果不是的话(一般是三合一)再判断是否为IPC(数字通道),VIDEO_MODE_960H(界面上的960H选项)、VIDEO_MODE_720P(界面上的AHD1.0选项)、VIDEO_MODE_HALF1080P或者VIDEO_MODE_1080P(界面上的AHD2.0选项)。

判断是否为IPC(数字通道)的方法:从环境变量中获取BNC的通道数(即模拟通道数),如果比通道数(MAX_CAM_CH)小的话则有通道为IPC(数字通道),因为设置IPC通道只能从最大通道开始,所以如果当前通道号等于或大于BNC的通道数的话则该通道为IPC(数字通道)。


2、在app2cgi_communication.c中添加命令类型CMD_GET_CHN_MODEL:

case CMD_GET_CHN_MODEL:		
		bAuto = g_pstSysEnv->GetChannelModeAuto(g_pstSysEnv);
		model = g_pstSysEnv->GetChannelModelType(g_pstSysEnv, cmd.chn_info.nChn);
		channel_mode = g_pstSysEnv->GetChannelModes(g_pstSysEnv, cmd.chn_info.nChn);
		inmode = bAuto ? JDK_INPUT_FORMAT_AUTO : JDK_INPUT_BNC_720P_25;
		//nBNC = g_pstSysEnv->stAttr.stContent.stHvr.nBnc;
		
#if defined(_HVR)
		if( JCONF_IS_NET_CAM(cmd.chn_info.nChn) ){//(nBNC < MAX_CAM_CH) && (cmd.chn_info.nChn >= nBNC) ){
			cmd.chn_info.chnnel_model = "IPC";
		}
		else if(strcmp(HDDVR_AD_TVI_TYPE, HDDVR_GetMODELType()) == 0){
			if( VIDEO_TYPE_960H_TVI == model){
				cmd.chn_info.chnnel_model = "AUTO";
			}else if(VIDEO_TYPE_AHD == model){
				cmd.chn_info.chnnel_model = "AHD";
			} 
		}
		else if (strcmp(HDDVR_AD_AHD_TYPE, HDDVR_GetMODELType()) == 0) {
		    if(inmode == JDK_INPUT_FORMAT_AUTO){	
				cmd.chn_info.chnnel_model = "AUTO";
			}else{		
				switch(channel_mode){
					case VIDEO_MODE_960H:
						cmd.chn_info.chnnel_model = "960H";
						break;
					case VIDEO_MODE_720P:
						cmd.chn_info.chnnel_model = "AHD1.0";
						break;
					case VIDEO_MODE_HALF1080P:
					case VIDEO_MODE_1080P:
						cmd.chn_info.chnnel_model = "AHD2.0";
						break;
					case VIDEO_MODE_IPCAM:
						cmd.chn_info.chnnel_model = "IPC";
					default:
						break;
				}
			}
		}
#endif
		cmd.type = CMD_GET_CHN_MODEL_ACK;
		SEND_DVRCMD_ACK(cmd, _socket_index);
		break;




3、在cgi_gw.c中获取网页发过来的xml信息(通道号、命令、参数等等),然后用TCP协议发给APP并接受app2cgi_communication.c发回来的处理结果,最后反馈给网页:

static void proc_juan_getchnmodel(UniStructNode* root_in, UniStructNode* root_out)
{
	UniStructNodesList* tmp_nodes_in;
	UniStructNode* tmp_node_in;
	UniStructNode* tmp_node_out;
	UniStructAttr* tmp_attr_in;
//	UniStructAttr* tmp_attr_out;

	tmp_nodes_in = UniStruct_find_children(root_in, "chnmodel");
	if(tmp_nodes_in != NULL)
	{
		int i;
		for(i = 0; i < tmp_nodes_in->count; i++)
		{
			tmp_node_in = tmp_nodes_in->nodes[i];
			tmp_node_out = UniStruct_append_child(root_out, "chnmodel", "");
			UniStruct_append_attr(tmp_node_out, "errno", _convert_from_enum(JUAN_ERRNO_NO_ERROR));

			char* usr = NULL;
			char* pwd = NULL;
			CHK_USR_PWD(JUAN_ERRNO_USR_OR_PWD_ERROR);

#define PTZCTRL_PROC_START(key) \
{ \
tmp_attr_in = UniStruct_find_attr(tmp_node_in, key); \
if(tmp_attr_in != NULL) \
{ \

#define PTZCTRL_PROC_END(key) \
	UniStruct_append_attr(tmp_node_out, key, tmp_attr_in->value); \
} \
}
			int chn = -1;
			int param = -1;

			PTZCTRL_PROC_START("chn");
			chn = _convert_from_string(tmp_attr_in->value);
			PTZCTRL_PROC_END("chn");
			
			PTZCTRL_PROC_START("param");
			param = _convert_from_string(tmp_attr_in->value);
			PTZCTRL_PROC_END("param");

			if(chn == -1 || param == -1)
			{
				UniStruct_modify_attr(tmp_node_out, "errno", _convert_from_enum(JUAN_ERRNO_PARAM_ERROR));
				continue;
			}
			///
			DVRCommand_t dvr_cmd;
			memset(&dvr_cmd, 0, sizeof(DVRCommand_t));
			dvr_cmd.flag = DVR_CMD_FLAG;
			dvr_cmd.type = CMD_GET_CHN_MODEL;
			dvr_cmd.chn_info.nChn = chn;
			dvr_cmd.chn_info.u8Val = param;

			SEND_CMD_TO_APP(dvr_cmd, SEND_CMD_TO_APP_TIMEOUT);
			if(dvr_cmd.type != CMD_GET_CHN_MODEL_ACK)
			{
				UniStruct_modify_attr(tmp_node_out, "errno", _convert_from_enum(JUAN_ERRNO_APP_RESPONSE_ERROR));
				continue;
			}
			else{
				char chnmodel_content[128];
				sprintf(chnmodel_content, "%s",	dvr_cmd.chn_info.chnnel_model);
				UniStruct_append_child(tmp_node_out, "chnmodel", chnmodel_content);
			}
		}
		UniStruct_free_nodes_list(tmp_nodes_in);
		tmp_nodes_in = NULL;
	}
}


三、获取输入摄像头类型,包括类型和分辨率,帧率

1、调用JDK_vin_get_video_type函数可以获取当前通道接的摄像机类型和分辨率,帧率,然后再单个解析。

2、在app2cgi_communication.c中添加命令类型CMD_GET_CAMERA_TYPE:
case CMD_GET_CAMERA_TYPE:
#if  defined(_EXT_HDDVR)
		cam_model = JDK_vin_get_video_type(cmd.camera_info.nChn);
		
		while(*cam_model && !(*cam_model == '-') && !(*cam_model == '\0') && i<10){
			cmd.camera_info.info.vinType[i++] = *cam_model;
			cam_model++;
		}
		cmd.camera_info.info.vinType[i] = '\0';
		cam_model++;
		i = 0;
		if(strcmp("SD", cmd.camera_info.info.vinType) == 0){
			while(*cam_model && (*cam_model != '\0') && i<10){
					cmd.camera_info.info.vinFramerate[i++] = *cam_model;
					cam_model++;
				}
				cmd.camera_info.info.vinFramerate[i] = '\0';
				if(strcmp("PAL", cmd.camera_info.info.vinFramerate) == 0){
					strcpy(cmd.camera_info.info.vinResolution, "704x576");
					strcpy(cmd.camera_info.info.vinFramerate, "25FPS");
				}
				else if(strcmp("NTSC", cmd.camera_info.info.vinFramerate) == 0){
					strcpy(cmd.camera_info.info.vinResolution, "704x480");
					strcpy(cmd.camera_info.info.vinFramerate, "30FPS");
			}
		}
		else if((strcmp("TVI", cmd.camera_info.info.vinType) == 0) || 
				(strcmp("AHD", cmd.camera_info.info.vinType) == 0)){
			while(*cam_model && (*cam_model != '@') && (*cam_model != '\0') && i<10){
					cmd.camera_info.info.vinResolution[i++] = *cam_model;
					cam_model++;
				}
				cmd.camera_info.info.vinResolution[i] = '\0';
				cam_model++;
				i = 0;
				while(*cam_model && (*cam_model != '\0') && i<10){
					cmd.camera_info.info.vinFramerate[i++] = *cam_model;
					cam_model++;
				}
				cmd.camera_info.info.vinFramerate[i] = '\0';
		}else if((strcmp("UNKNOWN", cmd.camera_info.info.vinType) == 0)) {
<span style="white-space:pre">			</span>strcpy( cmd.camera_info.info.vinResolution, "UNKNOWN");
<span style="white-space:pre">			</span>strcpy( cmd.camera_info.info.vinFramerate, "UNKNOWN");
<span style="white-space:pre">		</span>}
		
#else
		
#endif
		cmd.type = CMD_GET_CAMERA_TYPE_ACK;
		SEND_DVRCMD_ACK(cmd, _socket_index);
		break;

3、在cgi_gw.c中获取网页发过来的xml信息(通道号、命令、参数等等),然后用TCP协议发给APP并接受app2cgi_communication.c发回来的处理结果,最后反馈给网页:
static void proc_juan_getcameratype(UniStructNode* root_in, UniStructNode* root_out)
{
	UniStructNodesList* tmp_nodes_in;
	UniStructNode* tmp_node_in;
	UniStructNode* tmp_node_out;
	UniStructAttr* tmp_attr_in;
//	UniStructAttr* tmp_attr_out;

	tmp_nodes_in = UniStruct_find_children(root_in, "cameratype");
	if(tmp_nodes_in != NULL)
	{
		int i;
		for(i = 0; i < tmp_nodes_in->count; i++)
		{
			tmp_node_in = tmp_nodes_in->nodes[i];
			tmp_node_out = UniStruct_append_child(root_out, "cameratype", "");
			UniStruct_append_attr(tmp_node_out, "errno", _convert_from_enum(JUAN_ERRNO_NO_ERROR));

			char* usr = NULL;
			char* pwd = NULL;
			CHK_USR_PWD(JUAN_ERRNO_USR_OR_PWD_ERROR);

#define PTZCTRL_PROC_START(key) \
{ \
tmp_attr_in = UniStruct_find_attr(tmp_node_in, key); \
if(tmp_attr_in != NULL) \
{ \

#define PTZCTRL_PROC_END(key) \
	UniStruct_append_attr(tmp_node_out, key, tmp_attr_in->value); \
} \
}
			int chn = -1;
			int param = -1;

			PTZCTRL_PROC_START("chn");
			chn = _convert_from_string(tmp_attr_in->value);
			PTZCTRL_PROC_END("chn");

			PTZCTRL_PROC_START("param");
			param = _convert_from_string(tmp_attr_in->value);
			PTZCTRL_PROC_END("param");

			if(chn == -1 || param == -1)
			{
				UniStruct_modify_attr(tmp_node_out, "errno", _convert_from_enum(JUAN_ERRNO_PARAM_ERROR));
				continue;
			}
			///
			DVRCommand_t dvr_cmd;
			memset(&dvr_cmd, 0, sizeof(DVRCommand_t));
			dvr_cmd.flag = DVR_CMD_FLAG;
			dvr_cmd.type = CMD_GET_CAMERA_TYPE;
			dvr_cmd.camera_info.nChn = chn;
			dvr_cmd.camera_info.u8Val = param;

			SEND_CMD_TO_APP(dvr_cmd, SEND_CMD_TO_APP_TIMEOUT);
			if(dvr_cmd.type != CMD_GET_CAMERA_TYPE_ACK)
			{
				UniStruct_modify_attr(tmp_node_out, "errno", _convert_from_enum(JUAN_ERRNO_APP_RESPONSE_ERROR));
				continue;
			}
			else{
				char camera_content[128];
				sprintf(camera_content, "%s",  dvr_cmd.camera_info.info.vinType);															
				UniStruct_append_child(tmp_node_out, "vinType", camera_content);
				sprintf(camera_content, "%s",  dvr_cmd.camera_info.info.vinResolution);															
				UniStruct_append_child(tmp_node_out, "vinResolution", camera_content);
				sprintf(camera_content, "%s",  dvr_cmd.camera_info.info.vinFramerate);															
				UniStruct_append_child(tmp_node_out, "vinFramerate", camera_content);
			}
		}
		UniStruct_free_nodes_list(tmp_nodes_in);
		tmp_nodes_in = NULL;
	}
}


四、获取通道编码能力集

1、调用JDK_vin_get_max_support函数获取支持最高编码格式,然后再计算出支持的每个编码格式所对应的码率和帧率,帧率大于25帧取25帧。
计算接口如下:
static unsigned int _enc_format_to_pixel(unsigned int format)
{
	unsigned int ret = 0;
	switch (format) {
		case ENC_FMT_QCIF:
			ret = 176*144;
			break;
		case ENC_FMT_CIF:
			ret = 352*288;
			break;
		case ENC_FMT_HD1:
			ret = 352 * 576;
			break;
		case ENC_FMT_D1:
			ret = 704*576;
			break;
		case ENC_FMT_WCIF:
			ret = 480*288;
			break;
		case ENC_FMT_960H:
			ret = 960*576;
			break;
		case ENC_FMT_HD720P:
			ret = 1280*720;
			break;	
		case ENC_FMT_HD1080P_HALF:
			ret = 960*1080;
			break;
		case ENC_FMT_HD1080P:
			ret = 1920*1080;
			break;
		default:
			ret = 0;
			break;
	}

	//printf("format %u -> pixels:%u\n", format, ret);
	return ret;
}

static unsigned int _enc_fps_from_enc_format(unsigned int fmt, int streamIndex)
{
	int ret = 0;
	unsigned int pixels = _enc_format_to_pixel(fmt);
	if (pixels == 0) {
		return 0;
	}
	if (streamIndex == 0) {
		ret = (MAX_BNC_1ST_RESOL*MAX_BNC_1ST_FPS) /pixels;
	}
	else{
		ret = MAX_BNC_2ST_FPS;
	}
	return ret;
}

static unsigned int _enc_bps_from_enc_format(unsigned int fmt)
{
	unsigned int ret = 0;
	switch (fmt) {
		case ENC_FMT_QCIF:
			ret = ENC_BR_64KPS;
			break;
		case ENC_FMT_CIF:
			ret = ENC_BR_256KPS;
			break;
		case ENC_FMT_HD1:
			ret = ENC_BR_512KPS;
			break;
		case ENC_FMT_D1:
			ret = ENC_BR_512KPS;
			break;
		case ENC_FMT_WCIF:
			ret = ENC_BR_384KPS;
			break;
		case ENC_FMT_960H:
			ret = ENC_BR_768KPS;
			break;
		case ENC_FMT_HD720P:
			ret = ENC_BR_2MPS;
			break;	
		case ENC_FMT_HD1080P_HALF:
			ret = ENC_BR_2MPS;
			break;
		case ENC_FMT_HD1080P:
			ret = ENC_BR_3MPS;
			break;
		default:
			ret = 0;
			break;
	}

	//printf("format %u -> bps:%u\n", format, ret);
	return ret;
}

2、在app2cgi_communication.c中添加命令类型CMD_GET_CHN_ENCODE:

case CMD_GET_CHN_ENCODE:
		cmd.chn_encode.Bit_rate[encode_index] = ENC_BR_VALUE_STRING1[_enc_bps_from_enc_format(ENC_FMT_QCIF)];
		cmd.chn_encode.Frame_rate[encode_index] = _enc_fps_from_enc_format(ENC_FMT_QCIF, 0) < 25? _enc_fps_from_enc_format(ENC_FMT_QCIF, 0):25;		
		cmd.chn_encode.Bit_rate[++encode_index] = ENC_BR_VALUE_STRING1[_enc_bps_from_enc_format(ENC_FMT_CIF)];
		cmd.chn_encode.Frame_rate[encode_index] = _enc_fps_from_enc_format(ENC_FMT_CIF, 0) < 25? _enc_fps_from_enc_format(ENC_FMT_CIF, 0):25;
		cmd.chn_encode.Bit_rate[++encode_index] = ENC_BR_VALUE_STRING1[_enc_bps_from_enc_format(ENC_FMT_HD1)];
		cmd.chn_encode.Frame_rate[encode_index] =_enc_fps_from_enc_format(ENC_FMT_HD1, 0) < 25? _enc_fps_from_enc_format(ENC_FMT_HD1, 0):25;
		cmd.chn_encode.Bit_rate[++encode_index] = ENC_BR_VALUE_STRING1[_enc_bps_from_enc_format(ENC_FMT_D1)];
		cmd.chn_encode.Frame_rate[encode_index] = _enc_fps_from_enc_format(ENC_FMT_D1, 0) < 25? _enc_fps_from_enc_format(ENC_FMT_D1, 0):25;
		cmd.chn_encode.Bit_rate[++encode_index] = ENC_BR_VALUE_STRING1[_enc_bps_from_enc_format(ENC_FMT_WCIF)];
		cmd.chn_encode.Frame_rate[encode_index] = _enc_fps_from_enc_format(ENC_FMT_WCIF, 0) < 25? _enc_fps_from_enc_format(ENC_FMT_WCIF, 0):25;
				
		MaxSupport = JDK_vin_get_max_support();
		switch(MaxSupport){
			case 0:
				cmd.chn_encode.Bit_rate[++encode_index] = ENC_BR_VALUE_STRING1[_enc_bps_from_enc_format(ENC_FMT_960H)];
				cmd.chn_encode.Frame_rate[encode_index] = _enc_fps_from_enc_format(ENC_FMT_960H, 0) < 25? _enc_fps_from_enc_format(ENC_FMT_960H, 0):25;
				break;
			case 1:
				cmd.chn_encode.Bit_rate[++encode_index] = ENC_BR_VALUE_STRING1[_enc_bps_from_enc_format(ENC_FMT_960H)];
				cmd.chn_encode.Frame_rate[encode_index] = _enc_fps_from_enc_format(ENC_FMT_960H, 0) < 25? _enc_fps_from_enc_format(ENC_FMT_960H, 0):25;
				cmd.chn_encode.Bit_rate[++encode_index] = ENC_BR_VALUE_STRING1[_enc_bps_from_enc_format(ENC_FMT_HD720P)];
				cmd.chn_encode.Frame_rate[encode_index] = _enc_fps_from_enc_format(ENC_FMT_HD720P, 0) < 25? _enc_fps_from_enc_format(ENC_FMT_HD720P, 0):25;
				break;
			case 2:
#ifdef _EXT_HDDVR_LITE
				cmd.chn_encode.Bit_rate[++encode_index] = ENC_BR_VALUE_STRING1[_enc_bps_from_enc_format(ENC_FMT_960H)];
				cmd.chn_encode.Frame_rate[encode_index] = _enc_fps_from_enc_format(ENC_FMT_960H, 0) < 25? _enc_fps_from_enc_format(ENC_FMT_960H, 0):25;
				cmd.chn_encode.Bit_rate[++encode_index] = ENC_BR_VALUE_STRING1[_enc_bps_from_enc_format(ENC_FMT_HD720P)];
				cmd.chn_encode.Frame_rate[encode_index] = _enc_fps_from_enc_format(ENC_FMT_HD720P, 0) < 25? _enc_fps_from_enc_format(ENC_FMT_HD720P, 0):25;
				cmd.chn_encode.Bit_rate[++encode_index] = ENC_BR_VALUE_STRING1[_enc_bps_from_enc_format(ENC_FMT_HD1080P_HALF)];
				cmd.chn_encode.Frame_rate[encode_index] = _enc_fps_from_enc_format(ENC_FMT_HD1080P_HALF, 0) < 25? _enc_fps_from_enc_format(ENC_FMT_HD1080P_HALF, 0):25;
#else
				cmd.chn_encode.Bit_rate[++encode_index] = ENC_BR_VALUE_STRING1[_enc_bps_from_enc_format(ENC_FMT_960H)];
				cmd.chn_encode.Frame_rate[encode_index] = _enc_fps_from_enc_format(ENC_FMT_960H, 0) < 25? _enc_fps_from_enc_format(ENC_FMT_960H, 0):25;
				cmd.chn_encode.Bit_rate[++encode_index] = ENC_BR_VALUE_STRING1[_enc_bps_from_enc_format(ENC_FMT_HD720P)];
				cmd.chn_encode.Frame_rate[encode_index] = _enc_fps_from_enc_format(ENC_FMT_HD720P, 0) < 25? _enc_fps_from_enc_format(ENC_FMT_HD720P, 0):25;
				cmd.chn_encode.Bit_rate[++encode_index] = ENC_BR_VALUE_STRING1[_enc_bps_from_enc_format(ENC_FMT_HD1080P)];
				cmd.chn_encode.Frame_rate[encode_index] = _enc_fps_from_enc_format(ENC_FMT_HD1080P, 0) < 25? _enc_fps_from_enc_format(ENC_FMT_HD1080P, 0):25;
				
#endif				
				break;
			default:
				break;	
		}	
		cmd.type = CMD_GET_CHN_ENCODE_ACK;
		SEND_DVRCMD_ACK(cmd, _socket_index);
		break;


3、在cgi_gw.c中获取网页发过来的xml信息(通道号、命令、参数等等),然后用TCP协议发给APP并接受app2cgi_communication.c发回来的处理结果,最后反馈给网页:
static void proc_juan_getchnencode(UniStructNode* root_in, UniStructNode* root_out)
{
	UniStructNodesList* tmp_nodes_in;
	UniStructNode* tmp_node_in;
	UniStructNode* tmp_node_out;
	UniStructAttr* tmp_attr_in;
//	UniStructAttr* tmp_attr_out;
	int i;

	tmp_nodes_in = UniStruct_find_children(root_in, "chnencode");
	if(tmp_nodes_in != NULL)
	{	
		for(i = 0; i < tmp_nodes_in->count; i++)
		{
			tmp_node_in = tmp_nodes_in->nodes[i];
			tmp_node_out = UniStruct_append_child(root_out, "chnencode", "");
			UniStruct_append_attr(tmp_node_out, "errno", _convert_from_enum(JUAN_ERRNO_NO_ERROR));

			char* usr = NULL;
			char* pwd = NULL;
			CHK_USR_PWD(JUAN_ERRNO_USR_OR_PWD_ERROR);

#define PTZCTRL_PROC_START(key) \
{ \
tmp_attr_in = UniStruct_find_attr(tmp_node_in, key); \
if(tmp_attr_in != NULL) \
{ \

#define PTZCTRL_PROC_END(key) \
	UniStruct_append_attr(tmp_node_out, key, tmp_attr_in->value); \
} \
}
			int chn = -1;
			int param = -1;

			PTZCTRL_PROC_START("chn");
			chn = _convert_from_string(tmp_attr_in->value);
			PTZCTRL_PROC_END("chn");

			PTZCTRL_PROC_START("param");
			param = _convert_from_string(tmp_attr_in->value);
			PTZCTRL_PROC_END("param");

			if(chn == -1 || param == -1)
			{
				UniStruct_modify_attr(tmp_node_out, "errno", _convert_from_enum(JUAN_ERRNO_PARAM_ERROR));
				continue;
			}
			///
			DVRCommand_t dvr_cmd;
			memset(&dvr_cmd, 0, sizeof(DVRCommand_t));
			dvr_cmd.flag = DVR_CMD_FLAG;
			dvr_cmd.type = CMD_GET_CHN_ENCODE;
			dvr_cmd.chn_encode.nChn = chn;
			dvr_cmd.chn_encode.u8Val = param;

			SEND_CMD_TO_APP(dvr_cmd, SEND_CMD_TO_APP_TIMEOUT);
			char *encode_format[10] = {"QCIF", "CIF", "HD1", "D1", "WCIF", "960H" ,"720P", "1080P-H", "1080P"};
			if(dvr_cmd.type != CMD_GET_CHN_ENCODE_ACK)
			{
				UniStruct_modify_attr(tmp_node_out, "errno", _convert_from_enum(JUAN_ERRNO_APP_RESPONSE_ERROR));
				continue;
			}
			else{
				char encode_content[128];
				i = 0;
				while(dvr_cmd.chn_encode.Bit_rate[i] != NULL){
					sprintf(encode_content, "<BitRate>%s<BitRate><FrameRate>%d<FrameRate>\n",  dvr_cmd.chn_encode.Bit_rate[i],
																			   dvr_cmd.chn_encode.Frame_rate[i]);				
					UniStruct_append_child(tmp_node_out, encode_format[i], encode_content);
					i++;
				}											  		    												  		    												   			
			}
		}
		UniStruct_free_nodes_list(tmp_nodes_in);
		tmp_nodes_in = NULL;
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值