コード例 #1
0
/*****************************************************************************
 * RetxQueue: store a packet in the retx queue
 *****************************************************************************/
static void RetxQueue( block_t *p_block, uint64_t i_current_date )
{
    p_block->i_date = i_current_date;
    p_block->p_next = NULL;
    rtp_set_marker( p_block->p_data );

    /* Queue block */
    if ( p_retx_last != NULL )
    {
        p_retx_last->p_next = p_block;
        p_retx_last = p_block;
    }
    else
        p_retx_last = p_retx_first = p_block;

    /* Purge old blocks */
    while ( p_retx_first != NULL &&
            p_retx_first->i_date < i_current_date - i_retx_buffer )
    {
        block_t *p_next = p_retx_first->p_next;
        free(p_retx_first);
        p_retx_first = p_next;
    }
    if ( p_retx_first == NULL )
        p_retx_last = NULL;
}
コード例 #2
0
ファイル: rtpenc.c プロジェクト: emon/emon
int
main(int argc, char *argv[])
{
#ifndef RTPESND
	char            p_header[PIPE_HEADER_LEN];
#endif RTPSEND
	char            r_header[RTP_HEADER_LEN];
	char           *buffer;
	struct iovec    iov[3];
	ssize_t         length;
	u_int16_t       seq;
	PIPE_CONTEXT    p;
	int             dummy_cnt; /* dummy(very old packet)cnt */
#ifdef RTPSEND
	int             count=0; /* for Debug */
	struct timeval  blk_start_tv;
	int             blk_wait4start=1;
	int             blk_pktcnt = 0;
	u_int32_t       waitperframe;
#endif
	sigset_t        sigset;
	ssize_t         io_ret;
/* 	sigfillset(&sigset); */
/* 	sigdelset(&sigset,SIGINT); */
/* 	sigdelset(&sigset,SIGTSTP); */
	if (sigprocmask(SIG_BLOCK,&sigset,NULL)!=0){
	  e_printf("sigprocmask fail.\n");
	  exit(0);
	}
	signal(SIGINT,cb_sig);
	signal(SIGTSTP,cb_sig);
	signal(SIGPIPE,cb_sig);

	if (opt_etc(argc, argv) == -1) {
		return -1;
	}
	if (isatty(STDIN)) {
		e_printf("Standard input must be binded with pipe.\n");
		return -1;
	}
#ifndef RTPSEND
	if (isatty(STDOUT)) {
		e_printf("Standard output must be binded with pipe.\n");
		return -1;
	}
#endif /* ! RTPSEND */
	if ((buffer = malloc(OPT.plen)) == NULL) {
		e_printf("cannot malloc for buffer\n");
		return -1;
	}
	if (OPT.compatible_mode) {
		seq = 0;
	} else {
		srand(time(NULL));
		seq = rand() & 0xffff;
	}
	d1_printf("first seq/rtp=%u\n",seq);

	rtp_reset(r_header, RTP_HEADER_LEN);
	rtp_set_version(r_header, 1);
	rtp_set_ptype(r_header, OPT.payload_type);

	memset(buffer, 0, OPT.plen);
#ifdef RTPSEND
	switch(OPT.shaping_lev)
	{
	case 0:
	default:
		OPT.shaping_lev=0;
		waitperframe=1;
		d1_printf("shaping_mode : frame\n");
		break;
	case 1:
		waitperframe=OPT.rs_N;
		d1_printf("shaping_mode : packet with dups\n");
		break;
	case 2:
		waitperframe=OPT.rs_N*OPT.send_double;
		d1_printf("shaping_mode : all packet(include dups)\n");
		break;
	}
	iov[0].iov_base = r_header;
	iov[0].iov_len = RTP_HEADER_LEN;
	iov[1].iov_base = buffer;
/*	iov[1].iov_len = OPT.plen;*/
#else /* RTPSEND */
	iov[0].iov_base = p_header;
	iov[0].iov_len = PIPE_HEADER_LEN;
	iov[1].iov_base = r_header;
	iov[1].iov_len = RTP_HEADER_LEN;
	iov[2].iov_base = buffer;
/*	iov[2].iov_len = OPT.plen;*/
#endif /* RTPSEND */
	p=pipe_context_init(STDIN,1 /*OPT.rs_N*/, OPT.plen);
	wclk_ps_tvstart.tv_sec=0;
	while ((length = pipe_blocked_read_packet_ex(p, p_header, buffer))>=0){
#ifdef RTPSEND
		if(wclk_ps_tvstart.tv_sec==0){
				/* recode start time */
				gettimeofday(&wclk_ps_tvstart, NULL);
		}
		count++;
		if(blk_wait4start){
			gettimeofday(&blk_start_tv,NULL);
			blk_wait4start=0;
			blk_pktcnt = 0;
		}else{
			blk_pktcnt++;
		}
		blk_wait4start=pipe_get_marker(p_header);
#endif
#ifdef RTPSEND
		iov[1].iov_len =length;
		pipe_set_length(p_header,length);
#else 
		iov[2].iov_len =length;
		pipe_set_length(p_header,length + RTP_HEADER_LEN);
#endif /* RTPSEND*/
		rtp_set_timestamp(r_header, pipe_get_timestamp(p_header));
		rtp_set_marker(r_header, pipe_get_marker(p_header));
		rtp_set_seqnum(r_header, seq++);
		if(seq>=0x10000) seq-=0x10000;
		d3_printf("rtpenc: marker %d : seq %d\n",pipe_get_marker(p_header),seq-1);
#ifdef RTPSEND
		if (display_time_all_packet) {
			d_printf("\n%d:", seq);
		}
		rtsend_tslimit+=(u_int32_t)(pipe_get_timestamp(p_header) - pkt_tslast);
		pkt_tslast=pipe_get_timestamp(p_header);
#if 0
		wait4rtsend(&wclk_tvstart,blk_pktcnt);
#else

		if(!(OPT.shaping_lev==0 && blk_pktcnt>=1)){
			wait4rtsend(&wclk_tvstart,&rtsend_tslimit,blk_pktcnt,waitperframe);
		}
#endif 
		if (OPT.send_err_rate > 0) {
			if ((rand() % OPT.send_err_rate) == 0) {
				total_drop++;
				continue;
			}
		}
		d2_printf(" write %d bytes", pipe_get_length(p_header));
		if (writev(OPT.sfd, iov, 2) == -1) {
		    total_drop++;
		    d2_printf(" writev-NG(ts/sq=%d/%d)\n", pipe_get_timestamp(p_header), count);
		} else {
		    d2_printf(" writev-OK(ts/sq=%d/%d)\n", pipe_get_timestamp(p_header), count);
		    total_send++;
		}

		if(OPT.dup2dummy){
			rtp_set_seqnum(r_header, (seq+0x10000-0x100)&0xffff);
		}
		for(dummy_cnt=1;dummy_cnt<OPT.send_double;dummy_cnt++){
			if(OPT.shaping_lev==2){
				blk_pktcnt++;
				wait4rtsend(&wclk_tvstart,&rtsend_tslimit,blk_pktcnt,waitperframe);
			}
			d2_printf(" write dup(%d/%d) \n",dummy_cnt,OPT.send_double);
			io_ret=writev(OPT.sfd, iov, 2);
			if ( io_ret == -1) {
			    total_drop++;
			    d2_printf(" writev-NG(ts/sq=%d/%d)\n", pipe_get_timestamp(p_header), count);
			} else {
			    d2_printf(" writev-OK(ts/sq=%d/%d)\n", pipe_get_timestamp(p_header), count);
			    total_send++;
			}
		}
#else /* RTPSEND */
		d2_printf(" write pkt\n");
		writev(STDOUT, iov, 3);
		if(OPT.dup2dummy){
			rtp_set_seqnum(r_header, (seq+0x10000-0x100)&0xffff);
		}
		for(dummy_cnt=1;dummy_cnt<OPT.send_double;dummy_cnt++){
		  d2_printf(" write dup(%d/%d) \n",dummy_cnt,OPT.send_double);
		  io_ret=writev(STDOUT, iov, 3);
		  if(io_ret==-1){
			  exit_req=1;
			  break;
		  }
		}
#endif /* RTPSEND */
		if(exit_req==1){
		  break;
		}
	}
#ifdef RTPSEND
	last_seq=seq-1;
	statistics_display();
	sleep(1);
#endif
	return 0;
}