static switch_status_t switch_vpx_control(switch_codec_t *codec, 
										  switch_codec_control_command_t cmd, 
										  switch_codec_control_type_t ctype,
										  void *cmd_data,
										  switch_codec_control_type_t atype,
										  void *cmd_arg,
										  switch_codec_control_type_t *rtype,
										  void **ret_data) 
{

	vpx_context_t *context = (vpx_context_t *)codec->private_info;

	switch(cmd) {
	case SCC_VIDEO_RESET:
		{
			int mask = *((int *) cmd_data);
			if (mask & 1) {
				context->need_encoder_reset = 1;
			}
			if (mask & 2) {
				context->need_decoder_reset = 1;
			}
		}
		break;
	case SCC_VIDEO_REFRESH:
		context->need_key_frame = 1;		
		break;
	case SCC_VIDEO_BANDWIDTH:
		{
			switch(ctype) {
			case SCCT_INT:
				context->change_bandwidth = *((int *) cmd_data);
				break;
			case SCCT_STRING:
				{
					char *bwv = (char *) cmd_data;
					context->change_bandwidth = switch_parse_bandwidth_string(bwv);
				}
				break;
			default:
				break;
			}
		}
		break;
	default:
		break;
	}


	return SWITCH_STATUS_SUCCESS;
}
bool WSClientParser::InitChannel(WSChannel* wsChannel) {
	switch_core_session_t *session = wsChannel->session;
	switch_channel_t* channel = switch_core_session_get_channel(wsChannel->session);

	// 初始化语音
	wsChannel->read_frame.data = wsChannel->databuf;
	wsChannel->read_frame.buflen = sizeof(wsChannel->databuf);

	/* Initialize read & write codecs */
	if (switch_core_codec_init(
			&wsChannel->read_codec,
			/* name */ "SPEEX",
			/* modname */ NULL,
			/* fmtp */ NULL,
			/* rate */ 16000,
			/* ms */ 20,
			/* channels */ 1,
			/* flags */ SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
			/* codec settings */ NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(
				SWITCH_CHANNEL_SESSION_LOG(session),
				SWITCH_LOG_ERROR,
				"WSClientParser::InitChannel( "
				"[Fail, Can't initialize read codec], "
				"this : %p, "
				"wsChannel : %p "
				")\n",
				this,
				wsChannel
				);

		return false;
	}

	if (switch_core_codec_init(
			&wsChannel->write_codec,
			/* name */ "SPEEX",
			/* modname */ NULL,
			/* fmtp */ NULL,
			/* rate */ 16000,
			/* ms */ 20,
			/* channels */ 1,
			/* flags */ SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
			/* codec settings */ NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
		switch_log_printf(
				SWITCH_CHANNEL_SESSION_LOG(session),
				SWITCH_LOG_ERROR, ""
				"WSClientParser::InitChannel( "
				"[Fail, Can't initialize write codec], "
				"this : %p, "
				"wsChannel : %p "
				")\n",
				this,
				wsChannel
				);

		return false;
	}

	switch_core_session_set_read_codec(session, &wsChannel->read_codec);
	switch_core_session_set_write_codec(session, &wsChannel->write_codec);

	//static inline uint8_t rtmp_audio_codec(int channels, int bits, int rate, rtmp_audio_format_t format) {
	wsChannel->audio_codec = 0xB2; //rtmp_audio_codec(1, 16, 0 /* speex is always 8000  */, RTMP_AUDIO_SPEEX);

	// 初始化视频
	switch_codec_settings_t codec_settings = {{ 0 }};
	wsChannel->video_read_frame.data = wsChannel->video_databuf;
	wsChannel->video_read_frame.buflen = sizeof(wsChannel->video_databuf);

	/* Initialize video read & write codecs */
	if (switch_core_codec_init(
			&wsChannel->video_read_codec,
			/* name */ "H264",
			/* modname */ NULL,
			/* fmtp */ NULL,
			/* rate */ 90000,
			/* ms */ 0,
			/* channels */ 1,
			/* flags */ SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
			/* codec settings */ NULL,
			switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS
			) {
		switch_log_printf(
				SWITCH_CHANNEL_SESSION_LOG(session),
				SWITCH_LOG_ERROR,
				"WSClientParser::InitChannel( "
				"[Fail, Can't initialize video read codec], "
				"this : %p, "
				"wsChannel : %p "
				") \n",
				this,
				wsChannel
				);

		return false;
	}

	codec_settings.video.bandwidth = switch_parse_bandwidth_string("1mb");

	if (switch_core_codec_init(
			&wsChannel->video_write_codec,
			/* name */ "H264",
			/* modname */ NULL,
			/* fmtp */ NULL,
			/* rate */ 90000,
			/* ms */ 0,
			/* channels */ 1,
			/* flags */ SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
			/* codec settings */ &codec_settings,
			switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS
			) {
		switch_log_printf(
				SWITCH_CHANNEL_SESSION_LOG(session),
				SWITCH_LOG_ERROR,
				"WSClientParser::InitChannel( "
				"[Fail, Can't initialize write codec], "
				"this : %p, "
				"wsChannel : %p "
				") \n",
				this,
				wsChannel
				);
		return false;
	}

	switch_core_session_set_video_read_codec(session, &wsChannel->video_read_codec);
	switch_core_session_set_video_write_codec(session, &wsChannel->video_write_codec);
	switch_channel_set_flag(channel, CF_VIDEO);

	wsChannel->mparams.external_video_source = SWITCH_TRUE;
	switch_media_handle_create(&wsChannel->media_handle, session, &wsChannel->mparams);

	wsChannel->video_read_frame.packet = wsChannel->video_databuf;
	wsChannel->video_read_frame.data = wsChannel->video_databuf + 12;
	wsChannel->video_read_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE - 12;

	switch_mutex_init(&wsChannel->video_readbuf_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));

	switch_buffer_create_dynamic(&wsChannel->video_readbuf, 1024, 1024, 2048000);

	wsChannel->video_codec = 0xB2;

	return true;
}