summaryrefslogtreecommitdiffstats
path: root/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.c
diff options
context:
space:
mode:
Diffstat (limited to 'kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.c')
-rw-r--r--kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.c211
1 files changed, 211 insertions, 0 deletions
diff --git a/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.c b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.c
new file mode 100644
index 00000000..cfcb6b34
--- /dev/null
+++ b/kopete/protocols/jabber/jingle/libjingle/talk/third_party/mediastreamer/msrtpsend.c
@@ -0,0 +1,211 @@
+/*
+ The mediastreamer library aims at providing modular media processing and I/O
+ for linphone, but also for any telephony application.
+ Copyright (C) 2001 Simon MORLAT simon.morlat@linphone.org
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include "msrtpsend.h"
+#include <ortp/telephonyevents.h>
+#include "mssync.h"
+#include "mscodec.h"
+
+
+
+static MSRtpSendClass *ms_rtp_send_class=NULL;
+
+MSFilter * ms_rtp_send_new(void)
+{
+ MSRtpSend *r;
+
+ r=g_new(MSRtpSend,1);
+
+ if (ms_rtp_send_class==NULL)
+ {
+ ms_rtp_send_class=g_new(MSRtpSendClass,1);
+ ms_rtp_send_class_init(ms_rtp_send_class);
+ }
+ MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_rtp_send_class);
+ ms_rtp_send_init(r);
+ return(MS_FILTER(r));
+}
+
+
+void ms_rtp_send_init(MSRtpSend *r)
+{
+ ms_filter_init(MS_FILTER(r));
+ MS_FILTER(r)->infifos=r->f_inputs;
+ MS_FILTER(r)->inqueues=r->q_inputs;
+ MS_FILTER(r)->r_mingran=MSRTPSEND_DEF_GRAN;
+ memset(r->f_inputs,0,sizeof(MSFifo*)*MSRTPSEND_MAX_INPUTS);
+ memset(r->q_inputs,0,sizeof(MSFifo*)*MSRTPSEND_MAX_INPUTS);
+ r->rtpsession=NULL;
+ r->ts=0;
+ r->ts_inc=0;
+ r->flags=0;
+ r->delay=0;
+}
+
+void ms_rtp_send_class_init(MSRtpSendClass *klass)
+{
+ ms_filter_class_init(MS_FILTER_CLASS(klass));
+ ms_filter_class_set_name(MS_FILTER_CLASS(klass),"RTPSend");
+ MS_FILTER_CLASS(klass)->max_qinputs=MSRTPSEND_MAX_INPUTS;
+ MS_FILTER_CLASS(klass)->max_finputs=MSRTPSEND_MAX_INPUTS;
+ MS_FILTER_CLASS(klass)->r_maxgran=MSRTPSEND_DEF_GRAN;
+ MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_rtp_send_destroy;
+ MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_rtp_send_process;
+ MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_rtp_send_setup;
+}
+
+void ms_rtp_send_set_timing(MSRtpSend *r, guint32 ts_inc, gint payload_size)
+{
+ r->ts_inc=ts_inc;
+ r->packet_size=payload_size;
+ if (r->ts_inc!=0) r->flags|=RTPSEND_CONFIGURED;
+ else r->flags&=~RTPSEND_CONFIGURED;
+ MS_FILTER(r)->r_mingran=payload_size;
+ /*g_message("ms_rtp_send_set_timing: ts_inc=%i",ts_inc);*/
+}
+
+guint32 get_new_timestamp(MSRtpSend *r,guint32 synctime)
+{
+ guint32 clockts;
+ /* use the sync system time to compute a timestamp */
+ PayloadType *pt=rtp_profile_get_payload(r->rtpsession->profile,r->rtpsession->payload_type);
+ g_return_val_if_fail(pt!=NULL,0);
+ clockts=(guint32)(((double)synctime * (double)pt->clock_rate)/1000.0);
+ ms_trace("ms_rtp_send_process: sync->time=%i clock=%i",synctime,clockts);
+ if (r->flags & RTPSEND_CONFIGURED){
+ if (RTP_TIMESTAMP_IS_STRICTLY_NEWER_THAN(clockts,r->ts+(2*r->ts_inc) )){
+ r->ts=clockts;
+ }
+ else r->ts+=r->ts_inc;
+ }else{
+ r->ts=clockts;
+ }
+ return r->ts;
+}
+
+
+void ms_rtp_send_process(MSRtpSend *r)
+{
+ MSFifo *fi;
+ MSQueue *qi;
+ MSSync *sync= r->sync;
+ int gran=ms_sync_get_samples_per_tick(sync);
+ guint32 ts;
+ void *s;
+ guint skip;
+ guint32 synctime=sync->time;
+
+ g_return_if_fail(gran>0);
+ if (r->rtpsession==NULL) return;
+
+ ms_filter_lock(MS_FILTER(r));
+ skip=r->delay!=0;
+ if (skip) r->delay--;
+ /* process output fifo and output queue*/
+ fi=r->f_inputs[0];
+ if (fi!=NULL)
+ {
+ ts=get_new_timestamp(r,synctime);
+ /* try to read r->packet_size bytes and send them in a rtp packet*/
+ ms_fifo_get_read_ptr(fi,r->packet_size,&s);
+ if (!skip){
+ rtp_session_send_with_ts(r->rtpsession,s,r->packet_size,ts);
+ ms_trace("len=%i, ts=%i ",r->packet_size,ts);
+ }
+ }
+ qi=r->q_inputs[0];
+ if (qi!=NULL)
+ {
+ MSMessage *msg;
+ /* read a MSMessage and send it through the network*/
+ while ( (msg=ms_queue_get(qi))!=NULL){
+ ts=get_new_timestamp(r,synctime);
+ if (!skip) {
+ /*g_message("Sending packet with ts=%u",ts);*/
+ rtp_session_send_with_ts(r->rtpsession,msg->data,msg->size,ts);
+
+ }
+ ms_message_destroy(msg);
+ }
+ }
+ ms_filter_unlock(MS_FILTER(r));
+}
+
+void ms_rtp_send_destroy( MSRtpSend *obj)
+{
+ g_free(obj);
+}
+
+RtpSession * ms_rtp_send_set_session(MSRtpSend *obj,RtpSession *session)
+{
+ RtpSession *old=obj->rtpsession;
+ obj->rtpsession=session;
+ obj->ts=0;
+ obj->ts_inc=0;
+ return old;
+}
+
+void ms_rtp_send_setup(MSRtpSend *r, MSSync *sync)
+{
+ MSFilter *codec;
+ MSCodecInfo *info;
+ r->sync=sync;
+ codec=ms_filter_search_upstream_by_type(MS_FILTER(r),MS_FILTER_AUDIO_CODEC);
+ if (codec==NULL) codec=ms_filter_search_upstream_by_type(MS_FILTER(r),MS_FILTER_VIDEO_CODEC);
+ if (codec==NULL){
+ g_warning("ms_rtp_send_setup: could not find upstream codec.");
+ return;
+ }
+ info=MS_CODEC_INFO(codec->klass->info);
+ if (info->info.type==MS_FILTER_AUDIO_CODEC){
+ int ts_inc=info->fr_size/2;
+ int psize=info->dt_size;
+ if (ts_inc==0){
+ /* dont'use the normal frame size: this is a variable frame size codec */
+ /* use the MS_FILTER(codec)->r_mingran */
+ ts_inc=MS_FILTER(codec)->r_mingran/2;
+ psize=0;
+ }
+ ms_rtp_send_set_timing(r,ts_inc,psize);
+ }
+}
+
+gint ms_rtp_send_dtmf(MSRtpSend *r, gchar dtmf)
+{
+ gint res;
+
+ if (r->rtpsession==NULL) return -1;
+ if (rtp_session_telephone_events_supported(r->rtpsession)==-1){
+ g_warning("ERROR : telephone events not supported.\n");
+ return -1;
+ }
+
+ ms_filter_lock(MS_FILTER(r));
+ g_message("Sending DTMF.");
+ res=rtp_session_send_dtmf(r->rtpsession, dtmf, r->ts);
+ if (res==0){
+ /* //r->ts+=r->ts_inc; */
+ r->delay+=2;
+ }else g_warning("Could not send dtmf.");
+
+ ms_filter_unlock(MS_FILTER(r));
+
+ return res;
+}