[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Linphone-developers] oRTP multi-duplex-streams-application
From: |
Simon Morlat |
Subject: |
Re: [Linphone-developers] oRTP multi-duplex-streams-application |
Date: |
Tue, 13 Nov 2007 15:24:44 +0100 |
User-agent: |
KMail/1.9.7 |
Hi,
Unfortunately I have no time to help you debugging your application...
The mrtprecv.c and mrtpsend.c are good examples for usage of
session_set_select(), despite I know I have no example with duplex streams.
However there's nothing specific for duplex streams.
Sorry not to have the time to help you more...
Simon
Le Thursday 25 October 2007 17:51:04 Машкин С В, vous avez écrit :
> Hi!
>
>
>
> (Sorry for my sometimes "invalid" English.)
>
> I am "green" in oRTP, so I have problems (I think, in my mind, not in oRTP
> lib.)
>
> About 1 year ago I've read RTP RFCs, made own RTP functions (in ADSP-21xx
> asm).
>
>
>
> But now my task needs oRTP usage. (I use oRTP 0.13.1)
>
>
>
> As it was recommended in oRTP documentation, I've started with oRTP
>
> examples mrtprecv.c, mrtpsend.c and so on. Then read oRTP docs, generated
> with
>
> Doxygen (sometimes generated docs are very full, THANKS! But sometimes
> there are
>
> "black-holes"... Even in comments, which are not used for documentation
> generating).
>
>
>
>
>
> My task is to open number of duplex rtp-streams
>
> (at Blackfin platform, and at PC platform for debug).
>
> So, I decide to use "sessionset.h" function session_set_select().
>
> I use scheduled,nonblocking modes,
>
> open rtpsessions in connected mode,
>
> use adaptive jitter compensation.
>
>
>
> When there is one stream, sound receiving and transmitting are good,
>
> but when there are two, three or more streams - sound is corrupted
>
> (in most cases - only in last opened streams...)
>
>
>
> As "Ethereal"-sniffer showes numbers of input and output packets are
> different.
>
> (In some my experiments with my aplication code number of output packets is
>
> more than of input ones, in others experiments - number of input packets is
>
> larger.)
>
>
>
> First of all I read linphone pipermail... And found descriptions of
>
> like-my situations (Something connected with #ifdef ORTP_IPVER6 and
> REENTRANT).
>
> I though, that was my case, but I was wrong...
>
>
>
> Now I have no ONE RIGHT questions...
>
> so
>
> I can only ask for good simple multi-duplex-session example
>
> (with usage of "session_set_select" function in one thread
>
> and scheduler working in other thread)
>
> or
>
> ask Do I correctly use oRTP lib in my application?
>
>
>
> My application (and some other questions - see in comments) are
>
> (some unimportant code and check details are absent):
>
>
>
> --------------------------------------------------------------
>
>
>
> //============================================================
>
> //Global variables
>
> //============================================================
>
>
>
> #define RTP_CHANNELS 16 //Number of RTP-sessions in application
>
>
>
> RtpSession * session[RTP_CHANNELS];
>
> uint32_t session_rts[RTP_CHANNELS]; //timestamps
>
> uint32_t session_tts[RTP_CHANNELS];
>
> uint32_t session_drts[RTP_CHANNELS]; //increments
>
> uint32_t session_dtts[RTP_CHANNELS];
>
> char * session_ptlist[RTP_CHANNELS]; //payload types of session
>
>
>
> SessionSet * rset; //set for receiving events
>
> SessionSet * tset; //set for transiving events
>
> int active_sessions; //number of active sessions
>
>
>
> char * sup_ptlist = " 3 0 8 "; //Supported payload types
>
> //in preferenced order:
>
> //GSM=3,PCMU=0,PCMA=8
>
>
>
> //============================================================
>
> // timestampjump-event handler
>
> //============================================================
>
> void timestampjump_handler(RtpSession* session)
>
> {
>
> //QUESTION : Is this good realization of the handler?
>
> rtp_session_reset(session);
>
>
>
> #if 0
>
> //QUESTION : It is good idea to flush sockets buffers
>
> // in the handler?
>
> rtp_session_flush_sockets(session);
>
> #endif
>
> }
>
>
>
> //============================================================
>
> // ssrcchanged-event handler
>
> //============================================================
>
> void ssrcchanged_handler(RtpSession* session)
>
> {
>
> //QUESTION : Is this good realization of the handler?
>
> rtp_session_reset(session);
>
> }
>
>
>
>
>
> //============================================================
>
> //Initialisation of RTP-level
>
> //============================================================
>
> int rtp_layer_init(void)
>
> {
>
> int i;
>
>
>
> //init rtp-lib
>
> ortp_init();
>
>
>
> //init rtp-scheduler
>
> ortp_scheduler_init();
>
>
>
> //log level
>
> ortp_set_log_level_mask(ORTP_DEBUG|ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR);
>
> ortp_set_log_file(stdout);
>
>
>
> //no rtp-session yet - clear array of sessions
>
> for(i=0;i<RTP_CHANNELS;i++)
>
> {
>
> session[i] = NULL;
>
> }
>
> active_sessions = 0;
>
>
>
> //create session-set
>
> rset = session_set_new(); //receive session set
>
> tset = session_set_new(); //transive session set
>
>
>
> //init sound devices
>
> init_sound_devices(); //overall sound-devices initialization
>
>
>
> return(0);
>
> }
>
>
>
> //============================================================
>
> //Uninitialization of rtp-layer
>
> //============================================================
>
> void rtp_layer_exit(void)
>
> {
>
> int i;
>
>
>
> //delete sessions
>
> for(i=0;i<RTP_CHANNELS;i++)
>
> {
>
> if(session[i]!=NULL)
>
> {
>
> rtp_session_destroy(session[i]);
>
> }
>
> rtp_close_sound_device(i);
>
> }
>
>
>
> active_sessions = 0;
>
>
>
> //delete rset & tset
>
> session_set_destroy(rset);
>
> session_set_destroy(tset);
>
>
>
> //exit oRTP-lib
>
> ortp_exit();
>
>
>
> //show rtp-statistics
>
> ortp_global_stats_display();
>
>
>
> printf(" RET rtp_layer_exit\n");
>
> return;
>
> }
>
>
>
> //============================================================
>
> //Open rtp-connection (Add session)
>
> //============================================================
>
> //returns: 0 = ok
>
> // -1 = error
>
> int rtp_connection_open(int chan, //number of rtp-channel
>
> char *payload_types, //"0 1 13 101"
>
> char *remoteaddr, //"192.168.1.122"
>
> char *remoteport, //"2222"
>
> char *localaddr, //"192.168.1.133"
>
> char *localport) //"3333"
>
> {
>
> int ptype;
>
> int err;
>
> char * ptlist;
>
>
>
> //check if every payload_types is supported and make ptlist string
>
> //from payload_types string
>
> ptlist_from_str(&ptlist, sup_ptlist, payload_types); //my function
>
>
>
> //close current rtp-session on the channel (if it is present)
>
> rtp_connection_close(chan);
>
>
>
> //remember payload_types for the session
>
> session_ptlist[chan] = ptlist;
>
>
>
> //get the best payload type
>
> ptype = ptlist_best_ptn(session_ptlist[chan], sup_ptlist); //my function
>
>
>
> //open sound device (one sound-device is connected with one rtp-session)
>
> rtp_open_sound_device(chan); //my function
>
>
>
> //create new session on rtpchan channel:
>
> session[chan] = rtp_session_new( RTP_SESSION_SENDRECV ); //duplex session
>
>
>
> //settings:
>
> rtp_session_set_scheduling_mode( session[chan], 1 );
>
> rtp_session_set_blocking_mode( session[chan], 0 );
>
> rtp_session_set_remote_addr( session[chan], remoteaddr, atoi(remoteport)
> );
>
> rtp_session_set_local_addr( session[chan], localaddr, atoi(localport) );
>
> rtp_session_enable_adaptive_jitter_compensation( session[chan], TRUE );
>
> rtp_session_set_jitter_compensation( session[chan], RTP_RV_JITTER_COMP );
>
> rtp_session_set_recv_buf_size( session[chan], 2000 ); //(default
> recv_buf_size is 65535)
>
> rtp_session_set_connected_mode( session[chan], TRUE );
>
> rtp_session_set_payload_type( session[chan], ptype );
>
> //rtp_session_set_SSRC( session[chan], SSRC );
>
>
>
> //QUESTION : can you recommend some "intro"-documentation on
>
> // jitter compensation algorithm, which is used
>
> // in oRTP?
>
>
>
> //init session timestamps
>
> session_rts[chan] = 0;
>
> session_tts[chan] = 0;
>
> //init session timestamps increments
>
> session_drts[chan] = payload_type_dts(ptype); //my function
>
> session_dtts[chan] = payload_type_dts(ptype); //my function
>
>
>
> //oRTP events-handlers
>
> rtp_session_signal_connect(session[chan], "timestamp_jump",
> (RtpCallback)timestampjump_handler, 0);
>
> rtp_session_signal_connect(session[chan], "ssrc_changed",
> (RtpCallback)ssrcchanged_handler, 0);
>
>
>
> //increment number of active sessions
>
> active_sessions++;
>
>
>
> return(0); //ok: rtp-connection was opened
>
> }
>
>
>
> //============================================================
>
> //Close rtp-connection (Remove session)
>
> //============================================================
>
> void rtp_connection_close(int chan)
>
> {
>
> int chan;
>
>
>
> if( session[chan] != NULL )
>
> {
>
> rtp_close_sound_device( chan );
>
>
>
> free( session_ptlist[chan] );
>
> session_ptlist[chan] = NULL;
>
>
>
> rtp_session_destroy( session[chan] );
>
> session[chan] = NULL;
>
>
>
> //decrement number of active sessions
>
> active_sessions--;
>
> }
>
> return;
>
> }
>
>
>
>
>
> //============================================================
>
> //Wait for rtp-events and process them
>
> //============================================================
>
> int rtp_layer_wait(void)
>
> {
>
> int i;
>
> int rtpevents; //number of rtp-events
>
>
>
> //session's sets init
>
> //QUESTION : Really I have to do this here or this is made
>
> // automatically?
>
> session_set_init(rset);
>
> session_set_init(tset);
>
>
>
> //add all existing sessions to rset and tset
>
> for(i=0;i<RTP_CHANNELS;i++)
>
> {
>
> if(session[i]!=NULL)
>
> {
>
> session_set_set(rset,session[i]);
>
> session_set_set(tset,session[i]);
>
> }
>
> }
>
>
>
> //wait and process rtp-events
>
> if( active_sessions > 0 )
>
> {
>
> //sessions select
>
> rtpevents = session_set_select(rset,tset,NULL);
>
> //QUESTION : What is eset events examples?
>
>
>
> if(rtpevents > 0)
>
> {
>
> //search for rset's events
>
> for(i=0;i<RTP_CHANNELS;i++)
>
> {
>
> if(session[i]!=NULL) //check only for existing sessions
>
> {
>
> if(session_set_is_set(rset,session[i]))
>
> {//new data received
>
>
>
> //QUESTION : If we are here - does this mean, that it is
> time
>
> // to receive next rtp-packet (so, we can receive
>
> // NULL packets in silence periods)?
>
> // Or we are here only when
> right-timestamp-packet
>
> // is available in rtp-layer received packets
> queue.
>
>
>
> mblk_t *mp;
>
> int len;
>
> int err;
>
> int rvptype;
>
>
>
> //QUESTION : If I don't have mistake, in
> "mediastreamer/msrtprecv.c"
>
> // in function ms_rtp_recv_process() at the point
>
> // WHILE instead IF is used. Why? - Can oRTP
> generate
>
> // receive-event for one session in
> session_set_select()
>
> // for which rtp_session_recvm_with_ts() can
> return
>
> // more than one packets? (not only NULL or one
> packet)
>
>
>
> if( (mp =
> rtp_session_recvm_with_ts(session[i],session_rts[i]))!=NULL ) //! or
> while(...) ?
>
> {
>
>
>
> //data received
>
> len = mp->b_cont->b_wptr - mp->b_cont->b_rptr; //length
> of payload data
>
> if(len>0)
>
> {
>
> //get current payload type
>
> rvptype =
> rtp_session_get_recv_payload_type(session[i]);
>
>
>
> //play_payload() decodes and plays received data
>
> //(then frees payload data - body of the packet)
>
> err = play_payload(i, rvptype, mp->b_cont->b_rptr,
> len); //my function
>
> }
>
> freemsg(mp); //free the packet (its header)
>
> }
>
> else
>
> {//silence period? - play nothing
>
> //...
>
> //play_nothing();
>
> }
>
>
>
> //increment rts
>
> //QUESTION : It seems, that this is too simple way to
>
> // calculate new value of session_rts[i]?
>
> // May be use rtp_session_get_current_recv_ts()
>
> // function? If yes, how?
>
> session_rts[i] = session_rts[i] + session_drts[i];
>
> }
>
> }
>
> }
>
>
>
> //search for tset's events
>
> for(i=0;i<RTP_CHANNELS;i++)
>
> {
>
> if(session[i]!=NULL) //check only for existing sessions
>
> {
>
> if(session_set_is_set(tset,session[i]))
>
> {//need new data to transmit
>
>
>
> //QUESTION : Does this tset-event arise when last execute
> of
>
> // rtp_session_sendm_with_ts() was finished,
>
> // i.e. last rtp-packet was sended (i.e.
>
> // was written to socket)?
>
> // Or this event has place, only when it is
>
> // time to send next rtp-packet?
>
> //
>
> // In some of my experiments I saw, that
> tset-events
>
> // arised more frequently than with 20ms interval
>
> // (If we use GSM-payload-packets, for example).
>
>
>
> mblk_t *mp;
>
> unsigned char *payload_buf;
>
> int payload_len;
>
> int sended_bytes;
>
> int err;
>
>
>
> int trptype;
>
> int trptype_fact;
>
> uint32_t tts_now;
>
>
>
> //get current payload type
>
> trptype = rtp_session_get_send_payload_type(session[i]);
>
>
>
> //form_payload() forms payload (allocates payload_buf
>
> //and fills it with encoded audio data)
>
> //trptype_fact - is needed, if we use silence suppression
>
> //and comfort noise generation
>
> form_payload(i, trptype, &payload_buf, &payload_len,
> &trptype_fact);
>
>
>
> //create rtp-packet
>
> mp =
> rtp_session_create_packet_with_data(session[i],payload_buf,payload_len,NULL
>);
>
>
>
> //send rtp-packet (and free its header)
>
> sended_bytes =
> rtp_session_sendm_with_ts(session[i],mp,session_tts[i]);
>
> if(payload_buf!=NULL)
>
> {
>
> free(payload_buf); //free payload-body of sended packet
>
> }
>
>
>
> //increment tts
>
> //QUESTION : Is this correct way to increment the
> timestamp?
>
> // Or it is better to use
> rtp_session_get_current_send_ts()?
>
> // If yes, how?
>
> session_tts[i] = session_tts[i] + session_dtts[i];
>
>
>
> //QUESTION : When I wrote rtp-layer for ADSP-21xx
>
> // rtp-packet-need-to-be-send event generates
>
> // when enough audio data (sampled with 8000 Hz)
>
> // was collected. But with oRTP I can't use
>
> // such principle... So, what principle may
>
> // you recommend? (Use audio-data-flow or timer?
>
> // Use own timers, or timers of oRTP? What
> timers?)
>
> // So
>
> // What is the good way to calculate ts value for
>
> // rtp_session_sendm_with_ts() ?
>
>
>
> }
>
> }
>
> }
>
> }
>
> else
>
> {
>
> //error: no events
>
> //..
>
> }
>
> }
>
> return(0);
>
> }
>
>
>
> --------------------------------------------------------------
>
>
>
> P.S.: QUESTION: Are there some oRTP-based multi-duplex-rtp-streams
>
> application examples (open source) in which
>
> session_set_select() is used?
>
>
>
> Serg Ma.
>
>
> _______________________________________________
> Linphone-developers mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/linphone-developers
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [Linphone-developers] oRTP multi-duplex-streams-application,
Simon Morlat <=