Exemple #1
0
int cs_set_video_encoder_resolution(CSSession *cs, uint16_t width, uint16_t height)
{
    vpx_codec_enc_cfg_t cfg = *cs->v_encoder.config.enc;

    if (cfg.g_w == width && cfg.g_h == height)
        return 0;

    if (width * height > cs->max_width * cs->max_height) {
        vpx_codec_ctx_t v_encoder = cs->v_encoder;

        if (init_video_encoder(cs, width, height, cs->video_bitrate) == -1) {
            cs->v_encoder = v_encoder;
            return cs_ErrorSettingVideoResolution;
        }

        vpx_codec_destroy(&v_encoder);
        return 0;
    }

    LOGGER_DEBUG("New video resolution: %u %u", width, height);
    cfg.g_w = width;
    cfg.g_h = height;
    int rc = vpx_codec_enc_config_set(&cs->v_encoder, &cfg);

    if ( rc != VPX_CODEC_OK) {
        LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc));
        return cs_ErrorSettingVideoResolution;
    }

    return 0;
}
Exemple #2
0
CodecState *codec_init_session ( uint32_t audio_bitrate,
                                 uint16_t audio_frame_duration,
                                 uint32_t audio_sample_rate,
                                 uint32_t audio_channels,
                                 uint16_t video_width,
                                 uint16_t video_height,
                                 uint32_t video_bitrate )
{
    CodecState *retu = calloc(sizeof(CodecState), 1);
    assert(retu);

    retu->audio_bitrate = audio_bitrate;
    retu->audio_sample_rate = audio_sample_rate;

    /* Encoders */
    if (!video_width || !video_height) { /* Disable video */
        /*video_width = 320;
        video_height = 240; */
    }
    else {
        retu->supported_actions |= ( 0 == init_video_encoder(retu, video_width, video_height, video_bitrate) ) ? v_encoding : 0;
        retu->supported_actions |= ( 0 == init_video_decoder(retu) ) ? v_decoding : 0;
    }

    retu->supported_actions |= ( 0 == init_audio_encoder(retu, audio_channels) ) ? a_encoding : 0;
    retu->supported_actions |= ( 0 == init_audio_decoder(retu, audio_channels) ) ? a_decoding : 0;

    return retu;
}
Exemple #3
0
CodecState *codec_init_session ( uint32_t audio_bitrate,
                                 uint16_t audio_frame_duration,
                                 uint32_t audio_sample_rate,
                                 uint32_t audio_channels,
                                 uint16_t video_width,
                                 uint16_t video_height,
                                 uint32_t video_bitrate )
{
    CodecState *retu = calloc(sizeof(CodecState), 1);

    if (!retu) return NULL;

    retu->audio_bitrate = audio_bitrate;
    retu->audio_sample_rate = audio_sample_rate;

    /* Encoders */
    if (!video_width || !video_height) { /* Disable video */
        /*video_width = 320;
        video_height = 240; */
    } else {
        retu->capabilities |= ( 0 == init_video_encoder(retu, video_width, video_height, video_bitrate) ) ? v_encoding : 0;
        retu->capabilities |= ( 0 == init_video_decoder(retu) ) ? v_decoding : 0;
    }

    retu->capabilities |= ( 0 == init_audio_encoder(retu, audio_channels) ) ? a_encoding : 0;
    retu->capabilities |= ( 0 == init_audio_decoder(retu, audio_channels) ) ? a_decoding : 0;

    if ( retu->capabilities == 0  ) { /* everything failed */
        free (retu);
        return NULL;
    }

    return retu;
}
Exemple #4
0
CSSession *cs_new(const ToxAvCSettings *cs_self, const ToxAvCSettings *cs_peer, uint32_t jbuf_size, int has_video)
{
    CSSession *cs = calloc(sizeof(CSSession), 1);

    if (!cs) {
        LOGGER_WARNING("Allocation failed! Application might misbehave!");
        return NULL;
    }

    if (create_recursive_mutex(cs->queue_mutex) != 0) {
        LOGGER_WARNING("Failed to create recursive mutex!");
        free(cs);
        return NULL;
    }

    if ( !(cs->j_buf = jbuf_new(jbuf_size)) ) {
        LOGGER_WARNING("Jitter buffer creaton failed!");
        goto error;
    }

    cs->audio_encoder_bitrate        = cs_self->audio_bitrate;
    cs->audio_encoder_sample_rate    = cs_self->audio_sample_rate;
    cs->audio_encoder_channels       = cs_self->audio_channels;
    cs->audio_encoder_frame_duration = cs_self->audio_frame_duration;

    cs->audio_decoder_bitrate        = cs_peer->audio_bitrate;
    cs->audio_decoder_sample_rate    = cs_peer->audio_sample_rate;
    cs->audio_decoder_channels       = cs_peer->audio_channels;
    cs->audio_decoder_frame_duration = cs_peer->audio_frame_duration;


    cs->capabilities |= ( 0 == init_audio_encoder(cs) ) ? cs_AudioEncoding : 0;
    cs->capabilities |= ( 0 == init_audio_decoder(cs) ) ? cs_AudioDecoding : 0;

    if ( !(cs->capabilities & cs_AudioEncoding) || !(cs->capabilities & cs_AudioDecoding) ) goto error;

    if ((cs->support_video = has_video)) {
        cs->max_video_frame_size = MAX_VIDEOFRAME_SIZE;
        cs->video_frame_piece_size = VIDEOFRAME_PIECE_SIZE;

        cs->capabilities |= ( 0 == init_video_encoder(cs, cs_self->max_video_width,
                              cs_self->max_video_height, cs_self->video_bitrate) ) ? cs_VideoEncoding : 0;
        cs->capabilities |= ( 0 == init_video_decoder(cs) ) ? cs_VideoDecoding : 0;

        if ( !(cs->capabilities & cs_VideoEncoding) || !(cs->capabilities & cs_VideoDecoding) ) goto error;

        if ( !(cs->frame_buf = calloc(cs->max_video_frame_size, 1)) ) goto error;

        if ( !(cs->split_video_frame = calloc(cs->video_frame_piece_size + VIDEOFRAME_HEADER_SIZE, 1)) )
            goto error;

        if ( !(cs->vbuf_raw = buffer_new(VIDEO_DECODE_BUFFER_SIZE)) ) goto error;
    }

    return cs;

error:
    LOGGER_WARNING("Error initializing codec session! Application might misbehave!");

    pthread_mutex_destroy(cs->queue_mutex);

    if ( cs->audio_encoder ) opus_encoder_destroy(cs->audio_encoder);

    if ( cs->audio_decoder ) opus_decoder_destroy(cs->audio_decoder);


    if (has_video) {
        if ( cs->capabilities & cs_VideoDecoding ) vpx_codec_destroy(&cs->v_decoder);

        if ( cs->capabilities & cs_VideoEncoding ) vpx_codec_destroy(&cs->v_encoder);

        buffer_free(cs->vbuf_raw);

        free(cs->frame_buf);
        free(cs->split_video_frame);
    }

    jbuf_free(cs->j_buf);
    free(cs);

    return NULL;
}
Exemple #5
0
void* process_videoencoder(void *param)
{
	int sock = *(int *)param;
	free(param);
	printf("videoencoder new session sock=%d\n",sock);

	video_encoder_t* p_video_encoder = NULL;
	InputParams_videoencoder video_encoder_params;
	video_encoder_params.width = width;
	video_encoder_params.height = height;
	video_encoder_params.gopsize_min = gopsize_min;
	video_encoder_params.gopsize_max = gopsize_max;
	video_encoder_params.bitrate = encode_bitrate;
	video_encoder_params.fps = fps;
	p_video_encoder = init_video_encoder(&video_encoder_params);
	if(p_video_encoder == NULL)
	{		 
		printf("videoencoder: init_video_encoder fail..\n");		 
		return NULL;	  
	}


	

	
	int buffer_size = width*height*3/2+24;
	char *buffer = (char *)malloc(buffer_size);
	if(buffer == NULL)
	{		 
		printf("videoencoder malloc buffer fail..\n");		 
		return NULL;	  
	}
	
	char *input_video_sample;
	int input_video_sample_size;
	
	int output_video_sample_size = width*height*3/2;
	char *output_video_sample = (char *)malloc(buffer_size);
	if(output_video_sample == NULL)
	{		 
		fprintf(stderr ,"malloc buffer fail..\n");		 
		return NULL;	  
	}

	int len = -1;
	int ret = -1;

	int type;
	int length;
	int x;
	int y;
	int w;
	int h;
	msg_head head;

	struct timeval tv;
	long time_us1,time_us2,time_us3,time_us4;


	while (1)
	{
		gettimeofday(&tv,NULL);
		time_us1 = tv.tv_sec*1000 + tv.tv_usec/1000;
		printf("time_us1 =%ld start recv\n",time_us1);
		
		len = recv(sock,&head,sizeof(head),0);
		if(len == 0)
		{
			fprintf(stderr ,"connect broken error len=%d..\n",len);
			break;
		}
		
		if(len < 0)
		{
			fprintf(stderr ,"recv data error len=%d..\n",len);
			continue;
		}

		type = head.type;
		length = head.length;
		x=head.x;
		y=head.y;
		w=head.w;
		h=head.h;

		if(length != 16+w*h*3/2)
		{
			fprintf(stderr ,"length error len=%d..\n",len);
			continue;
		}

		len = recv_len(sock,buffer,buffer_size,w*h*3/2);
		if(len != w*h*3/2)
		{
			fprintf(stderr ,"recv data error len=%d..\n",len);
			continue;
		}

		input_video_sample = buffer;
		input_video_sample_size = w * h *3/2;

		gettimeofday(&tv,NULL);
		time_us2 = tv.tv_sec*1000 + tv.tv_usec/1000;
		printf("time_us2 =%ld type=%d length=%d x=%d y=%d w=%d h=%d\n",time_us2,head.type,head.length,head.x,head.y,head.w,head.h);


		output_video_sample_size = width*height*3/2;
		ret = encode_video_sample_inc(p_video_encoder,input_video_sample,input_video_sample_size,
	output_video_sample,&output_video_sample_size,x,y,w,h);
		if(ret < 0)
		{
			fprintf(stderr ,"encode_video_sample_inc error ret=%d..\n",ret);
			continue;
		}

		gettimeofday(&tv,NULL);
		time_us3 = tv.tv_sec*1000 + tv.tv_usec/1000;
		printf("time_us3 =%ld encode_video_sample length=%d\n",time_us3,output_video_sample_size);

		head.type = 2;
		head.length = 4*4 + output_video_sample_size;
		head.x = 0;
		head.y = 0;
		head.w = 0;
		head.h = 0;

		len = send(sock,&head,sizeof(head),0);
		if(len < 0)
		{
			fprintf(stderr ,"send head error ret=%d..\n",len);
			continue;
		}

		len = send(sock,output_video_sample,output_video_sample_size,0);
		if(len < 0)
		{
			fprintf(stderr ,"send output_video_sample error ret=%d..\n",len);
			continue;
		}

		gettimeofday(&tv,NULL);
		time_us4 = tv.tv_sec*1000 + tv.tv_usec/1000;
		printf("time_us4 =%ld send over\n",time_us4);
		
	}

	uninit_video_encoder(p_video_encoder);
	
}
int main(int argc,char** argv)
{
	if(argc < 4)
		{
			printf("erro param \n");
			return -1;
		}
	int width = atoi(argv[2]);
	int height = atoi(argv[3]);
		printf("file path %s ,w =%d,h=%d \n",argv[1],width,height);

	int gopsize_min = 15;
	int gopsize_max = 15;
	int encode_bitrate=4500000;
	int fps = 25;

	InputParams_videoencoder video_encoder_params;
	
	video_encoder_params.width = width;
	video_encoder_params.height = height;
	video_encoder_params.gopsize_min = gopsize_min;
	video_encoder_params.gopsize_max = gopsize_max;
	video_encoder_params.bitrate = encode_bitrate;
	video_encoder_params.fps = fps;

	p_video_encoder = init_video_encoder(&video_encoder_params);
	if(p_video_encoder == NULL)
	{		 
		fprintf(stderr ,"avencoder: init_video_encoder fail..\n");		 
		return -1;	  
	}
	printf("file path %s ,w =%d,h=%d \n",argv[1],width,height);
	p_video_source_sample = (char *)malloc(n_video_source_sample_size);
	if( p_video_source_sample == NULL)
	{		 
		fprintf(stderr ,"avencoder: malloc fail..\n");		 
		return -2;	  
	}

	p_video_encode_sample = (char *)malloc(n_video_encode_sample_size);
	if( p_video_encode_sample == NULL)
	{		 
		fprintf(stderr ,"avencoder: malloc fail..\n");		 
		return -2;	  
	}
	
	FILE *fp = fopen(argv[1],"rb");
	FILE* fpout = fopen("out.es","wb+");
	if(fp==NULL)
	{
		printf("---file open failed \n");
		return -7;
	}
	printf("---beging read data \n");
	//循环读取数据
	while(1)
	{
		n_video_source_sample =fread(p_video_source_sample,1,width*height*3/2,fp);
		
			//编码视频
		printf("====read dat len =%d \n",n_video_source_sample);
		if(n_video_source_sample <= 0)
			break;
		n_video_encode_sample = n_video_encode_sample_size;
		//ret = encode_video_sample_inc(p_video_encoder,p_video_source_sample,n_video_source_sample,p_video_encode_sample,&n_video_encode_sample,x,y,w,h);
		int ret = encode_video_sample(p_video_encoder,(unsigned char*)p_video_source_sample,n_video_source_sample,p_video_encode_sample,&n_video_encode_sample);
		
		if(ret < 0)
		{		 
			fprintf(stderr ,"avencoder: encode_video_sample fail..\n");		 
			continue;	  
		}
		fwrite(p_video_encode_sample,1,n_video_encode_sample,fpout);
	}
	printf("---over\n");
	return 0;
}
int main(int argc,char **argv)
{
	
	
	const char *short_options = "i:w:h:b:d:p:s:g:f:l:?";
	struct option long_options[] = {
		{"help",	no_argument,	   NULL, '?'},
		{"index",	required_argument, NULL, 'i'},
		{"width",	required_argument, NULL, 'w'},
		{"height",	required_argument, NULL, 'h'},
		{"bitrate",	required_argument, NULL, 'b'},
		{"sbitrate",required_argument, NULL, 's'},
		{"destaddr",required_argument, NULL, 'd'},
		{"pids",	required_argument, NULL, 'p'},
		{"gopsize",	required_argument, NULL, 'g'},
		{"fps",		required_argument, NULL, 'f'},
		{"logfile",	required_argument, NULL, 'l'},
		{NULL,		0,				   NULL, 0},
	};
	int c = -1;
	bool has_index = false;
	bool has_destaddr = false;
	bool has_ebitrate = false;
	bool has_sbitrate = false;

	while(1)
	{
		c = getopt_long(argc, argv, short_options, long_options, NULL);
		if(c == -1)
			break;
		switch(c)
		{
			case '?':
				printf("Usage:%s [options] index destaddr ....\n",argv[0]);
				printf("avencoder version %s\n",version_str);
				printf("-? --help 		Display this usage information.\n");
				printf("-i --index 		Set the index.\n");
				printf("-w --width 		Set the width.\n");
				printf("-h --height		Set the height.\n");
				printf("-b --bitrate 		Set the encoder bitrate .\n");
				printf("-s --sbitrate 		Set the smooth bitrate.\n");
				printf("-d --destaddr 		Set the dest addr (ip:port).\n");
				printf("-p --pids 		Set the service_id pmt_pid video_pid audio_pid (pmt_pid:service_id:video_pid:audio_pid).\n");
				printf("-g --gopsize 		Set the video encode gopsize (gopsize_min:gopsize_max).\n");
				printf("-l --logfile 		Set the log file path.\n");
				printf("Example: %s --index 0 --width 1280 --height 720 --bitrate 4000000 --pids 1024:1:64:65 --gopsize 5:100 --destaddr 192.168.60.248:14000.\n",argv[0]);
				printf("Example: %s -i 0 -w 1280 -h 720 -b 4000000 -p 1024:1:64:65 -g 5:100 -d 192.168.60.248:14000.\n",argv[0]);
				return -1;
			case 'i':
				m_index = atoi(optarg);
				has_index = true;
				break;
			case 'w':
				width = atoi(optarg);
				break;
			case 'h':
				height = atoi(optarg);
				break;
			case 'b':
				encode_bitrate = atoi(optarg);
				has_ebitrate = true;
				break;
			case 's':
				smooth_bitrate = atoi(optarg);
				has_sbitrate = true;
				break;
			case 'd':
				if(sscanf(optarg,"%[^:]:%d",destip,&destport) != 2)
				{
					fprintf(stderr ,"avencoder: error destip:destport.%s.\n",optarg);        
					return -2; 
				}
				strncpy(destip_record,destip,sizeof(destip_record));
				destport_record = destport;
				has_destaddr = true;
				break;
			case 'p':
				if(sscanf(optarg,"%d:%d:%d:%d",&pmt_pid,&service_id,&video_pid,&audio_pid) != 4)
				{
					fprintf(stderr ,"avencoder: error pmt_pid:service_id:video_pid:audio_pid.%s.\n",optarg);        
					return -3; 
				}
				break;
			case 'g':
				if(sscanf(optarg,"%d:%d",&gopsize_min,&gopsize_max) != 2)
				{
					gopsize_min = gopsize_max = atoi(optarg);
				}
				break;
			case 'f':
				fps = atoi(optarg);
				break;
			case 'l':
				memset(logfile,0,sizeof(logfile));
				strncpy(logfile,optarg,sizeof(logfile));
				break;

			}	
	}

	if(has_index == false || has_destaddr == false)
	{
		fprintf(stderr ,"avencoder: index and destaddr is must,not empty.\n");
		return -3;
	}
	if(has_ebitrate == true && has_sbitrate == false)
		smooth_bitrate = encode_bitrate*3;
	else if(has_ebitrate == false && has_sbitrate == true)
		encode_bitrate = smooth_bitrate/3;

	if(encode_bitrate < 0)
		encode_bitrate = 4*1024*1024;
	
	//TODO 检查各个参数的有效性
	printf("avencoder version %s\n",version_str);
	printf("++++++index=%d|width=%d|height=%d|smooth_bitrate=%d|encode_bitrate=%d|destip=%s|destport=%d++++++\n",m_index,width,height,smooth_bitrate,encode_bitrate,destip,destport);
	printf("++++++pmt_pid=%d|service_id=%d|video_pid=%d|audio_pid=%d|gopsize_min=%d|gopsize_max=%d|logfile=%s++++++\n",pmt_pid,service_id,video_pid,audio_pid,gopsize_min,gopsize_max,logfile);

	InputParams_audiosource audio_source_params;
	InputParams_videosource video_source_params;
	InputParams_videoencoder video_encoder_params;
	InputParams_avmuxer avmuxer_params;
	InputParams_tssmooth tssmooth_params;

	audio_source_params.index = m_index;
	p_audio_source = init_audio_source(&audio_source_params);
	if(p_audio_source == NULL)
	{        
		fprintf(stderr ,"avencoder: init_audio_source fail..\n");        
		return -1;    
	}
	video_source_params.index = m_index;
	video_source_params.width = width;
	video_source_params.height = height;
	
	p_video_source = init_video_source(&video_source_params);
	if(p_video_source == NULL)
	{        
		fprintf(stderr ,"avencoder: init_video_source fail..\n");        
		return -1;    
	}

	p_audio_encoder = init_audio_encoder();
	if(p_audio_encoder == NULL)
	{		 
		fprintf(stderr ,"avencoder: init_audio_encoder fail..\n");		 
		return -1;	  
	}

	
	video_encoder_params.width = width;
	video_encoder_params.height = height;
	video_encoder_params.gopsize_min = gopsize_min;
	video_encoder_params.gopsize_max = gopsize_max;
	video_encoder_params.bitrate = encode_bitrate;
	video_encoder_params.fps = fps;
	p_video_encoder = init_video_encoder(&video_encoder_params);
	if(p_video_encoder == NULL)
	{		 
		fprintf(stderr ,"avencoder: init_video_encoder fail..\n");		 
		return -1;	  
	}
#if 0
	if(smooth_bitrate > 0)
	{
		memset(&tssmooth_params,0,sizeof(tssmooth_params));
		tssmooth_params.index = m_index;
		tssmooth_params.listen_udp_port = 0;
		strcpy(tssmooth_params.dst_udp_ip,destip);
		tssmooth_params.dst_udp_port = destport;
		tssmooth_params.bit_rate = smooth_bitrate;
		tssmooth_params.buffer_max_size = 10*1024*1024;

		p_tssmooth = init_tssmooth(&tssmooth_params);
		if(p_tssmooth == NULL)
		{		 
			fprintf(stderr ,"avencoder: init_smooth fail..\n");		 
			return -1;	  
		}

		strcpy(destip,tssmooth_params.listen_udp_ip);
		destport = tssmooth_params.listen_udp_port;
		
		printf("++++++now dest addr is modify destip=%s|destport=%d++++++\n",destip,destport);
	}
#endif

	avmuxer_params.codecID = KY_CODEC_ID_H264;
	avmuxer_params.nWidth = width;
	avmuxer_params.nHeight = height;
	avmuxer_params.nBitRate = encode_bitrate;
	avmuxer_params.nPeakBitRate = smooth_bitrate;
	avmuxer_params.nSamplerate = 48000;
	avmuxer_params.nFramerate = fps;
	snprintf(avmuxer_params.monitorName,sizeof(avmuxer_params.monitorName),"%d.monitor",m_index);
	snprintf(avmuxer_params.appName,sizeof(avmuxer_params.appName),"%s",argv[0]);

	strcpy(avmuxer_params.destip,destip);
	avmuxer_params.destport = destport;
	avmuxer_params.index = m_index;
	avmuxer_params.pmt_pid = pmt_pid;
	avmuxer_params.service_id = service_id;
	avmuxer_params.video_pid = video_pid;
	avmuxer_params.audio_pid = audio_pid;
	p_avmuxer = init_ts_muxer(&avmuxer_params);
	if(p_avmuxer == NULL)
	{		 
		fprintf(stderr ,"avencoder: init_ts_muxer fail..\n");		 
		return -1;	  
	}



	p_audio_source_sample = (char *)malloc(n_audio_source_sample_size);
	p_video_source_sample = (char *)malloc(n_video_source_sample_size);
	if(p_audio_source_sample == NULL || p_video_source_sample == NULL)
	{		 
		fprintf(stderr ,"avencoder: malloc fail..\n");		 
		return -2;	  
	}

	p_audio_encode_sample = (char *)malloc(n_audio_encode_sample_size);
	p_video_encode_sample = (char *)malloc(n_video_encode_sample_size);
	if(p_audio_encode_sample == NULL || p_video_encode_sample == NULL)
	{		 
		fprintf(stderr ,"avencoder: malloc fail..\n");		 
		return -2;	  
	}

	pthread_t pthread;
	int ret = pthread_create(&pthread, NULL, statistics_process, NULL);
	if(ret != 0)
	{
		printf("avencoder: pthread_create fail!...\n");
		return -3;
	}


	

	double videopts = 0.0;
	double audiopts = 0.0;

	struct timeval tv;
	long start_time_us,end_time_us;
	gettimeofday(&tv,NULL);
	start_time_us = end_time_us = tv.tv_sec*1000 + tv.tv_usec/1000;
	
	while(1)
	{
		gettimeofday(&tv,NULL);
		start_time_us = tv.tv_sec*1000 + tv.tv_usec/1000;

		write_video_frames();

		video_pts(p_avmuxer,&videopts);
		audio_pts(p_avmuxer,&audiopts);

		//printf("++++++++++videopts = [%lf]   audiopts = [%lf]+++++++++\n",videopts,audiopts);

		while(audiopts < videopts)
		{
			write_audio_frames();

			video_pts(p_avmuxer,&videopts);
			audio_pts(p_avmuxer,&audiopts);
			//printf("----------videopts = [%lf]   audiopts = [%lf]---------\n",videopts,audiopts);
		}

		gettimeofday(&tv,NULL);
		end_time_us = tv.tv_sec*1000 + tv.tv_usec/1000;

		//if(end_time_us - start_time_us >= 40)
		//	printf("1++++++++++start_time_us = [%ld]	 end_time_us = [%ld]+++++diff=%ld++++\n",start_time_us,end_time_us,end_time_us - start_time_us);

		if(end_time_us - start_time_us < delaytimeus)
			usleep((delaytimeus-(end_time_us - start_time_us))*1000);
		
	}


	uninit_audio_source(p_audio_source);
	uninit_video_source(p_video_source);
	uninit_audio_encoder(p_audio_encoder);
	uninit_video_encoder(p_video_encoder);
	uninit_ts_muxer(p_avmuxer);
	if(smooth_bitrate > 0 && p_tssmooth)
		uninit_tssmooth(p_tssmooth);


	return 0;
}