~ubuntu-branches/ubuntu/quantal/linphone/quantal

« back to all changes in this revision

Viewing changes to mediastreamer/msrtprecv.c

  • Committer: Bazaar Package Importer
  • Author(s): Samuel Mimram
  • Date: 2004-06-30 13:58:16 UTC
  • Revision ID: james.westby@ubuntu.com-20040630135816-wwx75gdlodkqbabb
Tags: upstream-0.12.2
ImportĀ upstreamĀ versionĀ 0.12.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  The mediastreamer library aims at providing modular media processing and I/O
 
3
        for linphone, but also for any telephony application.
 
4
  Copyright (C) 2001  Simon MORLAT simon.morlat@linphone.org
 
5
                                                                                
 
6
  This library is free software; you can redistribute it and/or
 
7
  modify it under the terms of the GNU Lesser General Public
 
8
  License as published by the Free Software Foundation; either
 
9
  version 2.1 of the License, or (at your option) any later version.
 
10
 
 
11
  This library is distributed in the hope that it will be useful,
 
12
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
  Lesser General Public License for more details.
 
15
 
 
16
  You should have received a copy of the GNU Lesser General Public
 
17
  License along with this library; if not, write to the Free Software
 
18
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
*/
 
20
 
 
21
 
 
22
#include "msrtprecv.h"
 
23
 
 
24
 
 
25
/* some utilities to convert mblk_t to MSMessage and vice-versa */
 
26
MSMessage *msgb_2_ms_message(mblk_t* mp){
 
27
        MSMessage *msg;
 
28
        MSBuffer *msbuf;
 
29
        if (mp->b_datap->ref_count!=1) return NULL; /* cannot handle properly non-unique buffers*/
 
30
        /* create a MSBuffer using the mblk_t buffer */
 
31
        msg=ms_message_alloc();
 
32
        msbuf=ms_buffer_alloc(0);
 
33
        msbuf->buffer=mp->b_datap->db_base;
 
34
        msbuf->size=(char*)mp->b_datap->db_lim-(char*)mp->b_datap->db_base;
 
35
        ms_message_set_buf(msg,msbuf);
 
36
        msg->size=mp->b_wptr-mp->b_rptr;
 
37
        msg->data=mp->b_rptr;
 
38
        /* free the mblk_t */
 
39
        g_free(mp->b_datap);
 
40
        g_free(mp);
 
41
        return msg;
 
42
}
 
43
 
 
44
 
 
45
static MSRtpRecvClass *ms_rtp_recv_class=NULL;
 
46
 
 
47
MSFilter * ms_rtp_recv_new(void)
 
48
{
 
49
        MSRtpRecv *r;
 
50
        
 
51
        r=g_new(MSRtpRecv,1);
 
52
        ms_rtp_recv_init(r);
 
53
        if (ms_rtp_recv_class==NULL)
 
54
        {
 
55
                ms_rtp_recv_class=g_new(MSRtpRecvClass,1);
 
56
                ms_rtp_recv_class_init(ms_rtp_recv_class);
 
57
        }
 
58
        MS_FILTER(r)->klass=MS_FILTER_CLASS(ms_rtp_recv_class);
 
59
        return(MS_FILTER(r));
 
60
}
 
61
        
 
62
 
 
63
/* FOR INTERNAL USE*/
 
64
void ms_rtp_recv_init(MSRtpRecv *r)
 
65
{
 
66
        ms_filter_init(MS_FILTER(r));
 
67
        MS_FILTER(r)->outfifos=r->f_outputs;
 
68
        MS_FILTER(r)->outqueues=r->q_outputs;
 
69
        memset(r->f_outputs,0,sizeof(MSFifo*)*MSRTPRECV_MAX_OUTPUTS);
 
70
        memset(r->q_outputs,0,sizeof(MSFifo*)*MSRTPRECV_MAX_OUTPUTS);
 
71
        r->rtpsession=NULL;
 
72
        r->stream_started=0;
 
73
}
 
74
 
 
75
void ms_rtp_recv_class_init(MSRtpRecvClass *klass)
 
76
{
 
77
        ms_filter_class_init(MS_FILTER_CLASS(klass));
 
78
        ms_filter_class_set_name(MS_FILTER_CLASS(klass),"RTPRecv");
 
79
        MS_FILTER_CLASS(klass)->max_qoutputs=MSRTPRECV_MAX_OUTPUTS;
 
80
        MS_FILTER_CLASS(klass)->max_foutputs=MSRTPRECV_MAX_OUTPUTS;
 
81
        MS_FILTER_CLASS(klass)->w_maxgran=MSRTPRECV_DEF_GRAN;
 
82
        ms_filter_class_set_attr(MS_FILTER_CLASS(klass),FILTER_IS_SOURCE);
 
83
        MS_FILTER_CLASS(klass)->destroy=(MSFilterDestroyFunc)ms_rtp_recv_destroy;
 
84
        MS_FILTER_CLASS(klass)->process=(MSFilterProcessFunc)ms_rtp_recv_process;
 
85
        MS_FILTER_CLASS(klass)->setup=(MSFilterSetupFunc)ms_rtp_recv_setup;
 
86
}
 
87
        
 
88
void ms_rtp_recv_process(MSRtpRecv *r)
 
89
{
 
90
        MSFifo *fo;
 
91
        MSQueue *qo;
 
92
        MSSync *sync= r->sync;
 
93
        void *d;
 
94
        mblk_t *mp;
 
95
        gint len;
 
96
        gint gran=ms_sync_get_samples_per_tick(MS_SYNC(sync));
 
97
        
 
98
        if (r->rtpsession==NULL) return;
 
99
        /* process output fifo and output queue*/
 
100
        fo=r->f_outputs[0];
 
101
        if (fo!=NULL)
 
102
        {
 
103
                while( (mp=rtp_session_recvm_with_ts(r->rtpsession,r->prev_ts))!=NULL) {
 
104
                        /* try to get rtp packets and paste them to the output fifo */
 
105
                        r->stream_started=1;
 
106
                        len=mp->b_cont->b_wptr-mp->b_cont->b_rptr;
 
107
                        ms_fifo_get_write_ptr(fo,len,&d);
 
108
                        if (d!=NULL){
 
109
                                memcpy(d,mp->b_cont->b_rptr,len);
 
110
                        }else ms_warning("ms_rtp_recv_process: no space on output fifo !");
 
111
                        freemsg(mp);
 
112
                }
 
113
                r->prev_ts+=gran; 
 
114
                                
 
115
        }
 
116
        qo=r->q_outputs[0];
 
117
        if (qo!=NULL)
 
118
        {
 
119
                guint32 clock;
 
120
                gint got=0;
 
121
                /* we are connected with queues (surely for video)*/
 
122
                /* use the sync system time to compute a timestamp */
 
123
                PayloadType *pt=rtp_profile_get_payload(r->rtpsession->profile,r->rtpsession->payload_type);
 
124
                if (pt==NULL) {
 
125
                        ms_warning("ms_rtp_recv_process(): NULL RtpPayload- skipping.");
 
126
                        return;
 
127
                }
 
128
                clock=(sync->time*pt->clock_rate)/1000;
 
129
                //g_message("sync->time=%i clock=%i",sync->time,clock); 
 
130
                /* get rtp packet, and send them through the output queue */
 
131
                while ( (mp=rtp_session_recvm_with_ts(r->rtpsession,clock))!=NULL ){
 
132
                        MSMessage *msg;
 
133
                        mblk_t *mdata;
 
134
                        got++;
 
135
                        r->stream_started=1;
 
136
                        mdata=mp->b_cont;
 
137
                        freeb(mp);
 
138
                        msg=msgb_2_ms_message(mdata);
 
139
                        ms_queue_put(qo,msg);
 
140
                }
 
141
                if ((r->stream_started) && (got==0) && (gran!=0)){
 
142
                        /* we could not find a packet for current time but the stream has started */
 
143
                        /* notify this missing packet to next filter by sending an empty message */
 
144
                        MSMessage *msg;
 
145
                        //printf("sending missing packet information\n");
 
146
                        msg=ms_message_alloc();
 
147
                        ms_queue_put(qo,msg);
 
148
                }
 
149
        }
 
150
}
 
151
 
 
152
void ms_rtp_recv_destroy( MSRtpRecv *obj)
 
153
{
 
154
        g_free(obj);
 
155
}
 
156
 
 
157
RtpSession * ms_rtp_recv_set_session(MSRtpRecv *obj,RtpSession *session)
 
158
{
 
159
        RtpSession *old=obj->rtpsession;
 
160
        obj->rtpsession=session;
 
161
        obj->prev_ts=0;
 
162
        return old;
 
163
}
 
164
 
 
165
 
 
166
void ms_rtp_recv_setup(MSRtpRecv *r,MSSync *sync)
 
167
{
 
168
        r->sync=sync;
 
169
        r->stream_started=0;
 
170
}