linphone-developers
[Top][All Lists]
Advanced

[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






reply via email to

[Prev in Thread] Current Thread [Next in Thread]