📄 rtpsession.c
字号:
}/** * Set the RTP profile to be used for the receiveing by this session. By default, all session are created by * rtp_session_new() are initialized with the AV profile, as defined in RFC 3551. The application * can set any other profile instead using that function. * * @param session a rtp session * @param profile a rtp profile**/voidrtp_session_set_recv_profile (RtpSession * session, RtpProfile * profile){ session->rcv.profile = profile; rtp_session_recv_telephone_events_supported(session);}/** *@param session a rtp session * * DEPRECATED! Returns current send profile. * Use rtp_session_get_send_profile() or rtp_session_get_recv_profile() ***/RtpProfile *rtp_session_get_profile(RtpSession *session){ return session->snd.profile;}/** *@param session a rtp session * * Returns current send profile. ***/RtpProfile *rtp_session_get_send_profile(RtpSession *session){ return session->snd.profile;}/** *@param session a rtp session * * Returns current receive profile. ***/RtpProfile *rtp_session_get_recv_profile(RtpSession *session){ return session->rcv.profile;}/** * The default value is UDP_MAX_SIZE bytes, a value which is working for mostly everyone. * However if your application can make assumption on the sizes of received packet, * it can be interesting to set it to a lower value in order to save memory. * * @param session a rtp session * @param bufsize max size in bytes for receiving packets**/void rtp_session_set_recv_buf_size(RtpSession *session, int bufsize){ session->recv_buf_size=bufsize;}/** * Set kernel send maximum buffer size for the rtp socket. * A value of zero defaults to the operating system default.**/void rtp_session_set_rtp_socket_send_buffer_size(RtpSession * session, unsigned int size){ session->rtp.snd_socket_size=size;}/** * Set kernel recv maximum buffer size for the rtp socket. * A value of zero defaults to the operating system default.**/void rtp_session_set_rtp_socket_recv_buffer_size(RtpSession * session, unsigned int size){ session->rtp.rcv_socket_size=size;}/** * This function provides the way for an application to be informed of various events that * may occur during a rtp session. @signal is a string identifying the event, and @cb is * a user supplied function in charge of processing it. The application can register * several callbacks for the same signal, in the limit of #RTP_CALLBACK_TABLE_MAX_ENTRIES. * Here are name and meaning of supported signals types: * * "ssrc_changed" : the SSRC of the incoming stream has changed. * * "payload_type_changed" : the payload type of the incoming stream has changed. * * "telephone-event_packet" : a telephone-event rtp packet (RFC2833) is received. * * "telephone-event" : a telephone event has occured. This is a high-level shortcut for "telephone-event_packet". * * "network_error" : a network error happened on a socket. Arguments of the callback functions are * a const char * explaining the error, an int errno error code and the user_data as usual. * * "timestamp_jump" : we have received a packet with timestamp in far future compared to last timestamp received. * The farness of far future is set by rtp_sesssion_set_time_jump_limit() * "rtcp_bye": we have received a RTCP bye packet. Arguments of the callback * functions are a const char * containing the leaving reason and * the user_data. * * Returns: 0 on success, -EOPNOTSUPP if the signal does not exists, -1 if no more callbacks * can be assigned to the signal type. * * @param session a rtp session * @param signal_name the name of a signal * @param cb a RtpCallback * @param user_data a pointer to any data to be passed when invoking the callback. ***/intrtp_session_signal_connect (RtpSession * session, const char *signal_name, RtpCallback cb, unsigned long user_data){ OList *elem; for (elem=session->signal_tables;elem!=NULL;elem=o_list_next(elem)){ RtpSignalTable *s=(RtpSignalTable*) elem->data; if (strcmp(signal_name,s->signal_name)==0){ return rtp_signal_table_add(s,cb,user_data); } } ortp_warning ("rtp_session_signal_connect: inexistant signal %s",signal_name); return -1;}/** * Removes callback function @cb to the list of callbacks for signal @signal. * * @param session a rtp session * @param signal_name a signal name * @param cb a callback function. * @return: 0 on success, a negative value if the callback was not found.**/intrtp_session_signal_disconnect_by_callback (RtpSession * session, const char *signal_name, RtpCallback cb){ OList *elem; for (elem=session->signal_tables;elem!=NULL;elem=o_list_next(elem)){ RtpSignalTable *s=(RtpSignalTable*) elem->data; if (strcmp(signal_name,s->signal_name)==0){ return rtp_signal_table_remove_by_callback(s,cb); } } ortp_warning ("rtp_session_signal_connect: inexistant signal %s",signal_name); return -1;}/** * sets the initial sequence number of a sending session. * @param session a rtp session freshly created. * @param addr a 16 bit unsigned number. ***/void rtp_session_set_seq_number(RtpSession *session, uint16_t seq){ session->rtp.snd_seq=seq;}uint16_t rtp_session_get_seq_number(RtpSession *session){ return session->rtp.snd_seq;}/** * Sets the SSRC for the outgoing stream. * If not done, a random ssrc is used. * * @param session a rtp session. * @param ssrc an unsigned 32bit integer representing the synchronisation source identifier (SSRC).**/voidrtp_session_set_ssrc (RtpSession * session, uint32_t ssrc){ session->snd.ssrc = ssrc;}void rtp_session_update_payload_type(RtpSession *session, int paytype){ /* check if we support this payload type */ PayloadType *pt=rtp_profile_get_payload(session->rcv.profile,paytype); session->hw_recv_pt=paytype; if (pt!=0){ ortp_message ("payload type changed to %i(%s) !", paytype,pt->mime_type); payload_type_changed(session,pt); }else{ ortp_warning("Receiving packet with unknown payload type %i.",paytype); }}/** * Sets the payload type of the rtp session. It decides of the payload types written in the * of the rtp header for the outgoing stream, if the session is SENDRECV or SENDONLY. * For payload type in incoming packets, the application can be informed by registering * for the "payload_type_changed" signal, so that it can make the necessary changes * on the downstream decoder that deals with the payload of the packets. * * @param session a rtp session * @param paytype the payload type number * @return 0 on success, -1 if the payload is not defined.**/intrtp_session_set_send_payload_type (RtpSession * session, int paytype){ session->snd.pt=paytype; return 0;}/** *@param session a rtp session * *@return the payload type currently used in outgoing rtp packets**/int rtp_session_get_send_payload_type(const RtpSession *session){ return session->snd.pt;}/** * * Sets the expected payload type for incoming packets. * If the actual payload type in incoming packets is different that this expected payload type, thus * the "payload_type_changed" signal is emitted. * *@param session a rtp session *@param paytype the payload type number *@return 0 on success, -1 if the payload is not defined.**/intrtp_session_set_recv_payload_type (RtpSession * session, int paytype){ PayloadType *pt; session->rcv.pt=paytype; session->hw_recv_pt=paytype; pt=rtp_profile_get_payload(session->rcv.profile,paytype); if (pt!=NULL){ payload_type_changed(session,pt); } return 0;}/** *@param session a rtp session * * @return the payload type currently used in incoming rtp packets**/int rtp_session_get_recv_payload_type(const RtpSession *session){ return session->rcv.pt;}/** * Sets the expected payload type for incoming packets and payload type to be used for outgoing packets. * If the actual payload type in incoming packets is different that this expected payload type, thus * the "payload_type_changed" signal is emitted. * * @param session a rtp session * @param paytype the payload type number * @return 0 on success, -1 if the payload is not defined.**/int rtp_session_set_payload_type(RtpSession *session, int pt){ if (rtp_session_set_send_payload_type(session,pt)<0) return -1; if (rtp_session_set_recv_payload_type(session,pt)<0) return -1; return 0;}static void rtp_header_init_from_session(rtp_header_t *rtp, RtpSession *session){ rtp->version = 2; rtp->padbit = 0; rtp->extbit = 0; rtp->markbit= 0; rtp->cc = 0; rtp->paytype = session->snd.pt; rtp->ssrc = session->snd.ssrc; rtp->timestamp = 0; /* set later, when packet is sended */ /* set a seq number */ rtp->seq_number=session->rtp.snd_seq;}/** * Allocates a new rtp packet. In the header, ssrc and payload_type according to the session's * context. Timestamp and seq number are not set, there will be set when the packet is going to be * sent with rtp_session_sendm_with_ts(). * If payload_size is zero, thus an empty packet (just a RTP header) is returned. * *@param session a rtp session. *@param header_size the rtp header size. For standart size (without extensions), it is RTP_FIXED_HEADER_SIZE *@param payload data to be copied into the rtp packet. *@param payload_size size of data carried by the rtp packet. *@return a rtp packet in a mblk_t (message block) structure.**/mblk_t * rtp_session_create_packet(RtpSession *session,int header_size, const uint8_t *payload, int payload_size){ mblk_t *mp; int msglen=header_size+payload_size; rtp_header_t *rtp; mp=allocb(msglen,BPRI_MED); rtp=(rtp_header_t*)mp->b_rptr; rtp_header_init_from_session(rtp,session); /*copy the payload, if any */ mp->b_wptr+=header_size; if (payload_size){ memcpy(mp->b_wptr,payload,payload_size); mp->b_wptr+=payload_size; } return mp;}/** * Creates a new rtp packet using the given payload buffer (no copy). The header will be allocated separetely. * In the header, ssrc and payload_type according to the session's * context. Timestamp and seq number are not set, there will be set when the packet is going to be * sent with rtp_session_sendm_with_ts(). * oRTP will send this packet using libc's sendmsg() (if this function is availlable!) so that there will be no * packet concatenation involving copies to be done in user-space. * @freefn can be NULL, in that case payload will be kept untouched. * * @param session a rtp session. * @param payload the data to be sent with this packet * @param payload_size size of data * @param freefn a function that will be called when the payload buffer is no more needed. * @return: a rtp packet in a mblk_t (message block) structure.**/mblk_t * rtp_session_create_packet_with_data(RtpSession *session, uint8_t *payload, int payload_size, void (*freefn)(void*)){ mblk_t *mp,*mpayload; int header_size=RTP_FIXED_HEADER_SIZE; /* revisit when support for csrc is done */ rtp_header_t *rtp; mp=allocb(header_size,BPRI_MED); rtp=(rtp_header_t*)mp->b_rptr; rtp_header_init_from_session(rtp,session); mp->b_wptr+=header_size; /* create a mblk_t around the user supplied payload buffer */ mpayload=esballoc(payload,payload_size,BPRI_MED,freefn); mpayload->b_wptr+=payload_size; /* link it with the header */ mp->b_cont=mpayload; return mp;}/** * Creates a new rtp packet using the buffer given in arguments (no copy). * In the header, ssrc and payload_type according to the session's *context. Timestamp and seq number are not set, there will be set when the packet is going to be * sent with rtp_session_sendm_with_ts(). * @freefn can be NULL, in that case payload will be kept untouched. * * @param session a rtp session. * @param buffer a buffer that contains first just enough place to write a RTP header, then the data to send. * @param size the size of the buffer * @param freefn a function that will be called once the buffer is no more needed (the data has been sent). * @return a rtp packet in a mblk_t (message block) structure.**/mblk_t * rtp_session_create_packet_in_place(RtpSession *session,uint8_t *buffer, int size, void (*freefn)(void*) ){ mblk_t *mp; rtp_header_t *rtp; mp=esballoc(buffer,size,BPRI_MED,freefn); rtp=(rtp_header_t*)mp->b_rptr; rtp_header_init_from_session(rtp,session); return mp;}int__rtp_session_sendm_with_ts (RtpSession * session, mblk_t *mp, uint32_t packet_ts, uint32_t send_ts){ rtp_header_t *rtp; uint32_t packet_time; int error = 0; int packsize; RtpScheduler *sched=session->sched; RtpStream *stream=&session->rtp; if (session->flags & RTP_SESSION_SEND_NOT_STARTED) { session->rtp.snd_ts_offset = send_ts; /* Set initial last_rcv_time to first send time. */ if ((session->flags & RTP_SESSION_RECV_NOT_STARTED) || session->mode == RTP_SESSION_SENDONLY) { gettimeofday(&session->last_recv_time, NULL); } if (session->flags & RTP_SESSION_SCHEDULED) { session->rtp.snd_time_offset = sched->time_; } rtp_session_unset_flag (session,RTP_SESSION_SEND_NOT_STARTED);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -