source: verona/phapi/phms.c @ 150:5e24ab07af1f

Last change on this file since 150:5e24ab07af1f was 150:5e24ab07af1f, checked in by Nikita Kozlov <nikita@…>, 2 years ago

fix some memleaks in phapi

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