source: verona/phapi/phms.c @ 406:31a03b808483

Last change on this file since 406:31a03b808483 was 406:31a03b808483, checked in by laurent <laurent@…>, 17 months ago

[mq]: reinvite

File size: 23.0 KB
Line 
1/*
2 * phms -  Phone Api media streamer
3 *
4 * Copyright (C) 2008 Halina Nowak <halina@mbdsys.com>
5 * Copyright (C) 2005-2006 WENGO SAS
6 * Copyright (C) 2004 Vadim Lebedev <vadim@mbdsys.com>
7 * Copyright (C) 2002,2003   Aymeric Moizard <jack@atosc.org>
8 *
9 * This is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation; either version 2,
12 * or (at your option) any later version.
13 *
14 * This is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public
20 * License along with dpkg; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "phapi-config.h"
25
26#include "phglobal.h"
27#ifdef OS_WIN32
28#include <winsock2.h>
29#include <windows.h>
30#endif
31#include <osipparser2/osip_port.h>
32#include <osip2/osip_mt.h>
33#include <osip2/osip.h>
34#ifdef OS_POSIX
35#include <sys/ioctl.h>
36#include <sys/time.h>
37#endif
38
39#include <limits.h>
40
41#include <fcntl.h>
42#include <stdlib.h>
43#include <ortp/ortp.h>
44#include <ortp/telephonyevents.h>
45#include <mediastreamer2/mediastream.h>
46#include "phapi.h"
47#include "phcall.h"
48#include "phms.h"
49
50
51#include "phms_audiostream.h"
52#include "phms_videostream.h"
53
54#include "phdebug.h"
55
56#if defined(OS_WIN32) || defined(_WIN32_WCE)
57#define snprintf _snprintf
58#if !defined(_WIN32_WCE) && !defined(strncasecmp)
59#define strncasecmp strnicmp
60#endif /* !_WIN32_WCE */
61#define strcasecmp stricmp
62#endif
63
64static int stop_on_hold=0;
65static int video_stop_on_hold=0;
66
67//#define TEST_PREVIEW
68
69#ifdef TEST_PREVIEW
70VideoStream *preview=NULL;
71void phms_start_video_test()
72{
73        MSWebCam *cam;
74        MSVideoSize disp_size;
75        cam=ms_web_cam_manager_get_default_cam(ms_web_cam_manager_get());
76        disp_size.width=MS_VIDEO_SIZE_CIF_W;
77        disp_size.height=MS_VIDEO_SIZE_CIF_H;
78        preview=video_preview_start(cam, disp_size);
79        return;
80}
81void phms_stop_video_test()
82{
83        if(preview)
84                video_preview_stop(preview);
85}
86#endif
87
88
89int ph_media_cleanup()
90{
91        ms_exit();
92        return 0;
93}
94
95RtpProfile* make_profile(RtpProfile *profile, ph_mstream_params_t * params)
96{
97        int i;
98        RtpProfile *prof=rtp_profile_new("Call profile");
99        PayloadType *pt, *const_pt;
100        ph_media_payload_t *payload;
101
102        for (i = 0; i < PH_MAX_STREAM_PAYLOAD; i++)
103        {
104                int nb_frame = 1;
105                payload = &params->opayloads[i];
106                /*if (payload->number == 101) //skip telephony event
107                        continue;*/
108                if (payload->rate == 0)
109                        break;
110                const_pt=rtp_profile_get_payload_from_rtpmap(profile, payload->string);
111                if(const_pt)
112                {
113                        pt = payload_type_clone(const_pt);
114                        if (payload->ptime > 0)
115                        {
116                                char tmp[40];
117                                snprintf(tmp,sizeof(tmp),"ptime=%i",payload->ptime);
118                                payload_type_append_send_fmtp(pt,tmp);         
119                        }
120                        else
121                                payload->ptime = 20;
122
123                        nb_frame = payload->ptime / 20;
124                        //HACK: mediastreamer assume that pt->normal_bitrate is the network bitrate instead of the rtp payload
125                        // (UDP_HDR_SZ+RTP_HDR_SZ+IP4_HDR_SZ) * 8 == 320
126                        if (pt->normal_bitrate>0)
127                        {
128                                pt->normal_bitrate = (pt->normal_bitrate / 50 * nb_frame +  320) * 1000 / payload->ptime;
129                        }
130
131                        rtp_profile_set_payload(prof, payload->number, pt);
132                }
133        }
134        return prof;
135}
136
137int ph_msession_start(struct ph_msession_s *s, const char *adevice_in, const char *adevice_out, int use_tr_sock)
138{       
139        int ret = 0;
140        phms_audio_stream_t *audio = NULL;
141        ph_config_t* conf = ph_get_config();
142        struct ph_mstream_params_s *audio1 = &s->streams[PH_MSTREAM_AUDIO1];
143
144        audio1->profile = make_profile(&av_profile, audio1);
145
146
147#ifdef TEST_PREVIEW
148        phms_stop_video_test();
149#endif
150
151        DBG_MEDIA_ENGINE("MEDIA_ENGINE: entering ph_msession_start\n");
152
153        osip_mutex_lock(s->critsec_mstream_init);
154
155#ifndef SKIP_AUDIO
156        if(s->newstreams & 1<<PH_MSTREAM_AUDIO1)
157        {
158                audio = phms_audio_stream_start(audio1->profile, audio1->localport,audio1->remoteaddr,audio1->remoteport,audio1->remotertcpport,
159                                audio1->ipayloads[0].number, audio1->jitter, (audio1->flags)&PH_MSTREAM_FLAG_AEC, s, adevice_in, adevice_out, use_tr_sock);
160                if(!audio)
161                {
162                        osip_mutex_unlock(s->critsec_mstream_init);
163                        return -1;
164                }
165                else
166                {
167                        audio1->streamerData = audio;
168                        audio1->flags |= PH_MSTREAM_FLAG_RUNNING;
169                        s->activestreams |= (1 << PH_MSTREAM_AUDIO1);
170                }
171        }
172#endif
173
174#ifdef PHAPI_VIDEO_SUPPORT
175        if(s->newstreams & 1<<PH_MSTREAM_VIDEO1)
176        {
177                struct ph_mstream_params_s *video1 = &s->streams[PH_MSTREAM_VIDEO1];
178                phms_video_stream_t *video = phms_video_stream_new(video1->localport, ms_is_ipv6(video1->remoteaddr), video1->traffictype, conf->video_config.video_webcam_capture_width,conf->video_config.video_webcam_capture_height);
179
180                if(video == NULL)
181                {
182                        osip_mutex_unlock(s->critsec_mstream_init);
183                        return -1;
184                }
185                else
186                {
187                        video1->streamerData = video;
188                        video1->flags |= PH_MSTREAM_FLAG_RUNNING;
189                        s->activestreams |= (1 << PH_MSTREAM_VIDEO1);
190
191                        // Preserve quality from call or take from phcfg if none
192                        if(!video1->video_quality)
193                                video1->video_quality = conf->video_config.video_line_configuration;
194
195                        video1->profile = make_profile(&av_profile, video1);
196                }
197               
198                ret = phms_video_stream_start(video, video1->profile, video1->remoteaddr,video1->remoteport,video1->remoteport+1,video1->ipayloads[0].number,video1->jitter, s);
199        }
200#endif
201
202        osip_mutex_unlock(s->critsec_mstream_init);
203
204        return(ret);
205}
206int phms_audio_suspended(struct ph_msession_s *s)
207{
208        struct ph_mstream_params_s *audio = &s->streams[PH_MSTREAM_AUDIO1];
209        return (audio->flags & (PH_MSTREAM_FLAG_SUSPENDED));
210}
211int phms_video_suspended(struct ph_msession_s *s)
212{
213        struct ph_mstream_params_s *video = &s->streams[PH_MSTREAM_VIDEO1];
214        return (video->flags & (PH_MSTREAM_FLAG_SUSPENDED));
215}
216int phms_video_running(struct ph_msession_s *s)
217{
218        struct ph_mstream_params_s *video = &s->streams[PH_MSTREAM_VIDEO1];
219        return (video->streamerData && (video->flags & (PH_MSTREAM_FLAG_RUNNING)));
220}
221int ph_msession_conf_start(struct ph_msession_s *s1, struct ph_msession_s *s2, const char *device_in, const char *device_out)
222{
223        int ret;
224
225        struct ph_mstream_params_s *audio1 = &s1->streams[PH_MSTREAM_AUDIO1];
226#ifdef PHAPI_VIDEO_SUPPORT
227        struct ph_mstream_params_s *video1 = &s1->streams[PH_MSTREAM_VIDEO1];
228#endif
229
230        struct ph_mstream_params_s *audio2 = &s2->streams[PH_MSTREAM_AUDIO1];
231#ifdef PHAPI_VIDEO_SUPPORT
232        struct ph_mstream_params_s *video2 = &s2->streams[PH_MSTREAM_VIDEO1];
233#endif
234
235        // error if one of the 2 sessions is already involved in a conf
236        if (s1->confflags || s2->confflags)
237        {
238                return -PH_NORESOURCES;
239        }
240        osip_mutex_lock(s1->critsec_mstream_init);
241        osip_mutex_lock(s2->critsec_mstream_init);
242
243        // Both session must be suspended before conference
244#ifdef PHAPI_VIDEO_SUPPORT
245        if(video1 && video1->streamerData && !phms_video_suspended(s1))
246        {
247                phms_video_stream_suspend(video1->streamerData, video1->traffictype);
248                video1->flags |= PH_MSTREAM_FLAG_SUSPENDED;
249        }
250        if(video2 && video2->streamerData && !phms_video_suspended(s2))
251        {
252                phms_video_stream_suspend(video2->streamerData, video2->traffictype);
253                video2->flags |= PH_MSTREAM_FLAG_SUSPENDED;
254        }
255#endif 
256        if(!phms_audio_suspended(s1))
257        {
258                phms_audio_stream_suspend(((phms_audio_stream_t *)audio1->streamerData)->stream, audio1->traffictype);
259                audio1->flags |= PH_MSTREAM_FLAG_SUSPENDED;
260        }
261        if(!phms_audio_suspended(s2))
262        {
263                phms_audio_stream_suspend(((phms_audio_stream_t *)audio2->streamerData)->stream, audio2->traffictype);
264                audio2->flags |= PH_MSTREAM_FLAG_SUSPENDED;
265        }
266
267        s1->confflags = PH_MSESSION_CONF_MASTER;
268        s2->confflags = PH_MSESSION_CONF_MEMBER;
269
270        ret = phms_audio_conf_start(s1,s2);
271
272        if(ret >= 0)
273        {
274#ifdef PHAPI_VIDEO_SUPPORT
275                if(phms_video_running(s1) && phms_video_running(s2))
276                        phms_video_conf_start(s1,s2);
277                else if(phms_video_running(s1))
278                        phms_video_stream_resume(s1, video1->traffictype);
279                else if(phms_video_running(s2))
280                        phms_video_stream_resume(s2, video2->traffictype);
281#endif 
282
283                s1->confsession = s2;
284                s2->confsession = s1;
285
286                audio1->flags &= ~PH_MSTREAM_FLAG_SUSPENDED;
287                audio2->flags &= ~PH_MSTREAM_FLAG_SUSPENDED;
288#ifdef PHAPI_VIDEO_SUPPORT
289                video1->flags &= ~PH_MSTREAM_FLAG_SUSPENDED;
290                video2->flags &= ~PH_MSTREAM_FLAG_SUSPENDED;
291#endif   
292        }
293        else
294        {
295                s1->confflags = 0;
296                s2->confflags = 0;
297        }
298        osip_mutex_unlock(s2->critsec_mstream_init);
299        osip_mutex_unlock(s1->critsec_mstream_init);
300
301        return ret;
302}
303
304int phms_conf_stop(struct ph_msession_s *s1, struct ph_msession_s *s2)
305{
306        struct ph_msession_s *master, *member;
307        if(s1->confflags == PH_MSESSION_CONF_MASTER)
308        {
309                master = s1;
310                member = s2;
311        }
312        else
313        {
314                master = s2;
315                member = s1;
316        }
317        phms_audio_conf_stop(master,member);
318
319#ifdef PHAPI_VIDEO_SUPPORT
320        if(phms_video_running(s1) && phms_video_running(s2))
321                phms_video_conf_stop(master,member);
322#endif 
323
324        s1->confflags = 0;
325        s1->confsession = 0;
326        s2->confflags = 0;
327        s2->confsession = 0;
328
329        return 0;
330}
331int ph_msession_conf_stop(struct ph_msession_s *s1, struct ph_msession_s *s2)
332{
333        int ret;
334        DBG_MEDIA_ENGINE("MEDIA_ENGINE: entering ph_msession_conf_stop\n");
335
336        osip_mutex_lock(s1->critsec_mstream_init);
337        osip_mutex_lock(s2->critsec_mstream_init);
338
339        ret = phms_conf_stop(s1,s2);
340
341        osip_mutex_unlock(s2->critsec_mstream_init);
342        osip_mutex_unlock(s1->critsec_mstream_init);
343
344        return ret;
345}
346
347int ph_msession_in_conf_suspend(struct ph_msession_s *s,  int traffictype)
348{
349        int ret = 0;
350        struct ph_mstream_params_s *audio1 = &s->streams[PH_MSTREAM_AUDIO1];
351#ifdef PHAPI_VIDEO_SUPPORT
352        struct ph_mstream_params_s *video1 = &s->streams[PH_MSTREAM_VIDEO1];
353
354        if(!phms_video_suspended(s) && video1->streamerData)
355        {
356                ret = phms_video_conf_suspend_stream(video1->streamerData, traffictype);
357                video1->flags |= PH_MSTREAM_FLAG_SUSPENDED;
358        }
359#endif
360
361        if(!phms_audio_suspended(s))
362        {
363                ret = phms_audio_conf_suspend_stream(s);
364                audio1->flags |= PH_MSTREAM_FLAG_SUSPENDED;
365        }
366        return ret;
367}
368
369int ph_msession_suspend(struct ph_msession_s *s,  int traffictype, const char *device_in, const char *device_out)
370{
371        struct ph_mstream_params_s *audio1 = &s->streams[PH_MSTREAM_AUDIO1];
372#ifdef PHAPI_VIDEO_SUPPORT
373        struct ph_mstream_params_s *video1 = &s->streams[PH_MSTREAM_VIDEO1];
374#endif 
375
376        DBG_MEDIA_ENGINE("MEDIA_ENGINE: entering ph_msession_suspend\n");
377        osip_mutex_lock(s->critsec_mstream_init);
378        if(s->confflags)
379        {
380                ph_msession_in_conf_suspend(s, traffictype);
381                osip_mutex_unlock(s->critsec_mstream_init);
382                return 0;
383
384        }       
385#ifdef PHAPI_VIDEO_SUPPORT
386        {
387                struct ph_mstream_params_s *video1 = &s->streams[PH_MSTREAM_VIDEO1];
388                if(video1->streamerData)
389                {
390                        if(video_stop_on_hold)
391                        {
392                                phms_video_stream_stop(video1->streamerData);
393                                s->activestreams &= ~(1 << PH_MSTREAM_VIDEO1);
394                        }
395                        else
396                        {
397                                if(!(video1->flags & PH_MSTREAM_FLAG_SUSPENDED))
398                                {
399                                        phms_video_stream_suspend(video1->streamerData, traffictype);
400                                        video1->flags |= PH_MSTREAM_FLAG_SUSPENDED;
401                                }
402                        }
403                }
404        }
405#endif
406
407        if(stop_on_hold)
408        {
409#ifdef USE_PHMS_AUDIOSTREAM
410                phms_audio_stream_stop(((phms_audio_stream_t *)audio1->streamerData)->stream);
411#else
412                audio_stream_stop(((phms_audio_stream_t *)audio1->streamerData)->stream);
413#endif
414                s->activestreams &= ~(1 << PH_MSTREAM_AUDIO1);
415        }
416        else
417        {
418                if(!(audio1->flags & PH_MSTREAM_FLAG_SUSPENDED))
419                {
420                        phms_audio_stream_suspend(((phms_audio_stream_t *)audio1->streamerData)->stream, traffictype);
421                        audio1->flags |= PH_MSTREAM_FLAG_SUSPENDED;
422                }
423        }
424        osip_mutex_unlock(s->critsec_mstream_init);
425        return (0);
426}
427
428int phms_session_in_conf_resume(struct ph_msession_s *s, int traffictype)
429{
430        int ret = 0;
431        struct ph_mstream_params_s *audio1 = &s->streams[PH_MSTREAM_AUDIO1];
432
433#ifdef PHAPI_VIDEO_SUPPORT
434        phms_video_stream_t *video = NULL;
435        struct ph_mstream_params_s *video1 = &s->streams[PH_MSTREAM_VIDEO1];
436
437        if(phms_video_suspended(s))
438        {
439                video = video1->streamerData;
440                ret = phms_video_conf_resume_stream(video, PH_MSTREAM_TRAFFIC_IO);
441                video1->flags |= PH_MSTREAM_FLAG_RUNNING;
442                video1->flags &= ~PH_MSTREAM_FLAG_SUSPENDED;
443                s->activestreams |= (1 << PH_MSTREAM_VIDEO1);
444        }
445#endif 
446
447        if(phms_audio_suspended(s))
448        {
449                ret = phms_audio_conf_resume_stream(s);
450                audio1->flags |= PH_MSTREAM_FLAG_RUNNING;
451                audio1->flags &= ~PH_MSTREAM_FLAG_SUSPENDED;
452                s->activestreams |= (1 << PH_MSTREAM_AUDIO1);
453        }
454        return ret;
455}
456int ph_msession_resume(struct ph_msession_s *s, int traffictype, const char *device_in,  const char *device_out, int use_tr_sock)
457{
458        int ret = 0;
459        phms_audio_stream_t *audio = NULL;
460#ifdef PHAPI_VIDEO_SUPPORT
461        phms_video_stream_t *video = NULL;
462#endif 
463
464        struct ph_mstream_params_s *audio1 = &s->streams[PH_MSTREAM_AUDIO1];
465#ifdef PHAPI_VIDEO_SUPPORT
466        struct ph_mstream_params_s *video1 = &s->streams[PH_MSTREAM_VIDEO1];
467#endif
468
469        DBG_MEDIA_ENGINE("MEDIA_ENGINE: entering ph_msession_resume\n");
470        osip_mutex_lock(s->critsec_mstream_init);
471
472        if(s->confflags)
473        {
474                phms_session_in_conf_resume(s,traffictype);
475                osip_mutex_unlock(s->critsec_mstream_init);
476                return ret;
477        }       
478        else
479        {
480                RtpProfile * profile = rtp_profile_clone(&av_profile); //should replace it by video1->profile
481                if (audio1->profile)
482                        rtp_profile_destroy(audio1->profile);
483               
484                audio1->profile = make_profile(&av_profile, audio1);
485
486#ifdef PHAPI_VIDEO_SUPPORT
487                if(video_stop_on_hold)
488                {
489                        video = phms_video_stream_new(video1->localport, ms_is_ipv6(video1->remoteaddr), video1->traffictype, -1,-1);
490                        if(video == NULL)
491                        {
492                                pthread_mutex_unlock(&s->critsec_mstream_init);
493                                return -1;
494                        }
495                        else
496                                video1->streamerData = video;
497
498                        ret = phms_video_stream_start(video, profile, video1->remoteaddr,video1->remoteport,video1->remoteport+1,video1->ipayloads[0].number,video1->jitter, s);
499                }else{
500                        video = video1->streamerData;
501                        if(video)
502                        {
503                                ret = phms_video_stream_resume(video, PH_MSTREAM_TRAFFIC_IO);
504                                video1->flags |= PH_MSTREAM_FLAG_RUNNING;
505                                video1->flags &= ~PH_MSTREAM_FLAG_SUSPENDED;
506                                s->activestreams |= (1 << PH_MSTREAM_VIDEO1);
507                        }
508                }
509#endif
510                if(stop_on_hold)
511                {
512                        audio = phms_audio_stream_start(audio1->profile, audio1->localport,audio1->remoteaddr,audio1->remoteport,audio1->remotertcpport,
513                                        audio1->ipayloads[0].number, audio1->jitter, (audio1->flags)&PH_MSTREAM_FLAG_AEC,s,device_in,device_out,use_tr_sock);
514                }
515                else
516                {
517                        audio = audio1->streamerData;
518                        if(audio)
519                                phms_audio_stream_resume(audio->stream, traffictype);
520                }
521
522                if(!audio)
523                {
524                        osip_mutex_unlock(s->critsec_mstream_init);
525                        return -1;
526                }
527                else
528                        audio1->streamerData = audio;
529        }
530
531        audio1->flags |= PH_MSTREAM_FLAG_RUNNING;
532        audio1->flags &= ~PH_MSTREAM_FLAG_SUSPENDED;
533        s->activestreams |= (1 << PH_MSTREAM_AUDIO1);
534
535        osip_mutex_unlock(s->critsec_mstream_init);
536        return ret;
537}
538
539int ph_msession_stopped(struct ph_msession_s *s)
540{
541        return (s->activestreams == 0);
542}
543
544int ph_msession_audio_stopped(struct ph_msession_s *s)
545{
546        return !(s->activestreams & (1 << PH_MSTREAM_AUDIO1));
547}
548int ph_msession_video_stopped(struct ph_msession_s *s)
549{
550        return !(s->activestreams & (1 << PH_MSTREAM_VIDEO1));
551}
552void phms_stop(struct ph_msession_s *s)
553{
554#ifdef PHAPI_VIDEO_SUPPORT
555        if (!ph_msession_video_stopped(s))
556        {
557                struct ph_mstream_params_s *video1 = &s->streams[PH_MSTREAM_VIDEO1];
558                phms_video_stream_stop((phms_video_stream_t *)video1->streamerData);
559                video1->flags = 0;
560                s->activestreams &= ~(1 << PH_MSTREAM_VIDEO1);
561        }
562#endif
563        if (!ph_msession_audio_stopped(s))
564        {
565                struct ph_mstream_params_s *audio1 = &s->streams[PH_MSTREAM_AUDIO1];
566#ifdef USE_PHMS_AUDIOSTREAM
567                phms_audio_stream_stop(((phms_audio_stream_t *)audio1->streamerData)->stream);
568#else
569                audio_stream_stop(((phms_audio_stream_t *)audio1->streamerData)->stream);
570#endif
571                rtp_profile_destroy(audio1->profile);
572                audio1->flags = 0;
573                osip_free(audio1->streamerData);
574                s->activestreams &= ~(1 << PH_MSTREAM_AUDIO1);
575        }
576}
577void ph_msession_stop(struct ph_msession_s *s, const char *adevice_in, const char *adevice_out, int use_tr_sock)
578{
579        DBG_MEDIA_ENGINE("MEDIA_ENGINE: entering ph_msession_stop\n");
580        osip_mutex_lock(s->critsec_mstream_init);
581
582        if(s->confflags == 0 && s->confsession == NULL)
583        {
584                phms_stop(s);
585        }
586        else
587        {
588                // involved in conference, stop conference and resume last
589                // participating call
590                struct ph_msession_s *other = s->confsession; 
591                osip_mutex_lock(other->critsec_mstream_init);
592                phms_conf_stop(s, other);
593                phms_stop(s);
594                osip_mutex_unlock(other->critsec_mstream_init);
595                if(!phms_audio_suspended(other) && !phms_video_suspended(other))
596                        ph_msession_resume(other, PH_MSTREAM_TRAFFIC_IO, adevice_in, adevice_out,use_tr_sock);
597        }
598        osip_mutex_unlock(s->critsec_mstream_init);
599}
600
601
602int ph_msession_send_sound_file(struct ph_msession_s *s, const char *filename)
603{
604        return(phms_audio_send_sound_file(s, filename));
605}
606int ph_msession_send_dtmf(struct ph_msession_s *s, int dtmf, int mode)
607{
608        return(phms_audio_send_dtmf(s, dtmf, mode));
609}
610
611int ph_msession_is_stream_alive(struct ph_msession_s *s, int timeout)
612{
613        phms_audio_stream_t *phstream;
614
615        if (timeout <= 0)
616                return 1;
617        phstream = (phms_audio_stream_t *)(s->streams[PH_MSTREAM_AUDIO1].streamerData);
618        if (!phstream)
619                return 0;
620        return phstream->stream != NULL && audio_stream_alive(phstream->stream, timeout);
621}
622
623static PayloadType cng_8={
624                TYPE( PAYLOAD_AUDIO_PACKETIZED),
625                CLOCK_RATE(8000),
626                BITS_PER_SAMPLE(0),
627                ZERO_PATTERN(NULL),
628                PATTERN_LENGTH(0),
629                NORMAL_BITRATE(8000),
630                MIME_TYPE ("CN")
631};
632
633int
634ph_media_init(const char *pluginpath)
635{
636        //static int first_time = 1;
637
638        RtpProfile *profile;
639
640        /*if (!first_time)
641        {
642                return 0;
643        }*/
644        stop_on_hold = 0;
645        video_stop_on_hold = 0;
646        ortp_init();
647        ms_init();
648        ms_load_plugins(pluginpath);
649
650        /* initialize audio payloads (ortp needs this) */
651        profile = &av_profile;
652        rtp_profile_set_payload(profile,PH_MEDIA_DTMF_PAYLOAD, &payload_type_telephone_event);
653        rtp_profile_set_payload(profile,PH_MEDIA_PCMA_PAYLOAD, &payload_type_pcma8000);
654        rtp_profile_set_payload(profile,PH_MEDIA_PCMU_PAYLOAD, &payload_type_pcmu8000);
655        rtp_profile_set_payload(profile,PH_MEDIA_CN_PAYLOAD, &cng_8);
656
657#ifdef ENABLE_ILBC
658        rtp_profile_set_payload(profile,PH_MEDIA_ILBC_PAYLOAD, &payload_type_ilbc);
659#endif
660#ifdef ENABLE_G722
661        rtp_profile_set_payload(profile,PH_MEDIA_G722_PAYLOAD, &payload_type_g722);
662#endif
663#ifdef ENABLE_G726
664        //rtp_profile_set_payload(profile,PH_MEDIA_G726_PAYLOAD, &payload_type_g726_16);
665        rtp_profile_set_payload(profile,PH_MEDIA_G72632_PAYLOAD, &payload_type_g726_32);
666#endif
667#ifdef ENABLE_GSM
668        rtp_profile_set_payload(profile,PH_MEDIA_GSM_PAYLOAD, &payload_type_gsm);
669#endif
670#ifdef ENABLE_SPEEX
671        rtp_profile_set_payload(profile,PH_MEDIA_SPEEXNB_PAYLOAD, &payload_type_speex_nb);
672        rtp_profile_set_payload(profile,PH_MEDIA_SPEEXWB_PAYLOAD, &payload_type_speex_wb);
673#endif
674#ifdef  ENABLE_AMR     
675        rtp_profile_set_payload(profile,PH_MEDIA_AMR_PAYLOAD, &payload_type_amr);
676        rtp_profile_set_payload(profile,PH_MEDIA_AMR_WB_PAYLOAD, &payload_type_amrwb);
677#endif
678
679
680#ifdef PHAPI_VIDEO_SUPPORT
681#ifdef ENABLE_H263
682        rtp_profile_set_payload(profile,PH_MEDIA_H263P_PAYLOAD, &payload_type_h263_1998);
683        rtp_profile_set_payload(profile,PH_MEDIA_H263_PAYLOAD, &payload_type_h263);
684        //  rtp_profile_set_payload(profile,PH_MEDIA_H263FLV1_PAYLOAD, &h263flv1);
685#endif 
686#ifdef ENABLE_MPEG4
687        rtp_profile_set_payload(profile,PH_MEDIA_MPEG4_PAYLOAD, &payload_type_mp4v);
688#endif
689#ifdef ENABLE_THEORA
690        rtp_profile_set_payload(profile,PH_MEDIA_THEORA_PAYLOAD, &payload_type_theora);
691#endif
692#ifdef ENABLE_H264
693        rtp_profile_set_payload(profile,PH_MEDIA_H264_PAYLOAD, &payload_type_h264);
694#endif
695#ifdef ENABLE_X_SNOW
696        rtp_profile_set_payload(profile,PH_MEDIA_X_SNOW_PAYLOAD, &payload_type_x_snow);
697#endif
698        //rtp_profile_set_payload(profile,PH_MEDIA_JPEG_PAYLOAD, &payload_type_jpeg);
699#endif
700
701        //ortp_scheduler_init();
702        //ortp_set_log_file(NULL);
703
704        //first_time = 0;
705#ifdef TEST_PREVIEW
706        phms_start_video_test();
707#endif
708        return 0;
709}
710
711int ph_media_supported_payload(PayloadType **rtppt, const char *ptstring)
712{
713        *rtppt = rtp_profile_get_payload_from_rtpmap(&av_profile, ptstring);
714        if (*rtppt == NULL)
715                return 0;
716        if (strcmp((*rtppt)->mime_type,"telephone-event"))
717                return ms_filter_codec_supported((*rtppt)->mime_type);
718        return 1;
719}
720
721/* find a codec object corresponding to given payload */
722char *ph_media_lookup_codec_mime(int payload)
723{
724        RtpProfile *profile = &av_profile;
725        PayloadType *pt = rtp_profile_get_payload(profile, payload);
726        if(pt)
727                return pt->mime_type;
728        return 0;
729}
730
731void ph_tvsub(register struct timeval *out, register struct timeval *in)
732{
733        out->tv_usec -= in->tv_usec;
734
735        while(out->tv_usec < 0)
736        {
737                --out->tv_sec;
738                out->tv_usec += 1000000;
739        }
740
741        out->tv_sec -= in->tv_sec;
742}
743
744void
745ph_tvdiff(register struct timeval *diff, register struct timeval *out, register struct timeval *in)
746{
747        diff->tv_sec = out->tv_sec;
748        diff->tv_usec = out->tv_usec;
749
750        diff->tv_usec -= in->tv_usec;
751
752        while(diff->tv_usec < 0)
753        {
754                --diff->tv_sec;
755                diff->tv_usec += 1000000;
756        }
757
758        diff->tv_sec -= in->tv_sec;
759}
760
761int
762ph_timeval_substract (struct timeval *result, struct timeval *x, struct timeval *y)
763{
764        /* Perform the carry for the later subtraction by updating y. */
765        if (x->tv_usec < y->tv_usec)
766        {
767                int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
768                y->tv_usec -= 1000000 * nsec;
769                y->tv_sec += nsec;
770        }
771        if (x->tv_usec - y->tv_usec > 1000000)
772        {
773                int nsec = (x->tv_usec - y->tv_usec) / 1000000;
774                y->tv_usec += 1000000 * nsec;
775                y->tv_sec -= nsec;
776        }
777
778        /* Compute the time remaining to wait.
779           tv_usec is certainly positive. */
780        result->tv_sec = x->tv_sec - y->tv_sec;
781        result->tv_usec = x->tv_usec - y->tv_usec;
782
783        /* Return 1 if result is negative. */
784        return x->tv_sec < y->tv_sec;
785}
786
787int ph_media_get_clock_rate(int payload)
788{
789        RtpProfile *profile = &av_profile;
790        PayloadType *pt;
791#ifdef SPEEX_OVER_G729_HACK
792        if (payload == PH_MEDIA_G729_PAYLOAD)
793        {
794                payload = PH_MEDIA_SPEEXWB_PAYLOAD;
795        }
796#endif
797        pt  = rtp_profile_get_payload(profile, payload);
798        return pt->clock_rate;
799}
800int ph_getenv_int(const char* variable, int default_value )
801{
802        char* string;
803        long  value;
804
805        string = getenv(variable);
806        if(! string){
807                return default_value;
808        }
809        value = strtol( string, NULL, 10);
810        switch (value) {
811        case LONG_MAX:
812        case LONG_MIN:
813                return default_value;
814
815        default:
816                return (int) value;
817        }
818}
819
820int ph_msession_get_local_stats(struct ph_msession_s *s, rtp_stats_t *lstats)
821{
822        struct ph_mstream_params_s *audio;
823        phms_audio_stream_t* audioparam;
824
825        if (!s || s->activestreams == 0)
826                return -1;
827        audio = &s->streams[PH_MSTREAM_AUDIO1];
828        audioparam = audio->streamerData;
829        if (audioparam->stream && audioparam->stream->session)
830        {
831                const rtp_stats_t *stats=rtp_session_get_stats(audioparam->stream->session);
832                memcpy(lstats,stats,sizeof(*stats));
833        }
834        else
835        {
836                memset(lstats,0,sizeof(rtp_stats_t));
837                return -1;
838        }
839
840        return 0;
841}
842
843int phms_error()
844{
845        return -1;
846}
Note: See TracBrowser for help on using the repository browser.