summaryrefslogtreecommitdiffstats
path: root/kopete/protocols/jabber/jingle/libjingle/talk/third_party/ortp/ortp.c
blob: 80e07682bb2b48b4e9f40a5f19af29670130ea86 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
/*
  The oRTP library is an RTP (Realtime Transport Protocol - rfc1889) stack.
  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 <ortp.h>
#include "scheduler.h"
#include <stdlib.h>

rtp_stats_t ortp_global_stats;

#ifdef ENABLE_MEMCHECK
gint ortp_allocations=0;
#endif


RtpScheduler *__ortp_scheduler;


void dummy_log(const gchar *log_domain,
                                             GLogLevelFlags log_level,
                                             const gchar *message,
                                             gpointer user_data)
{
	return;
}

extern void av_profile_init(RtpProfile *profile);

static void init_random_number_generator(){
	struct timeval t;
	gettimeofday(&t,NULL);
	srandom(t.tv_usec+t.tv_sec);
}

/**
 *ortp_init:
 *
 *	Initialize the oRTP library. You should call this function first before using
 *	oRTP API.
**/
 
void ortp_init()
{
	static gboolean initialized=FALSE;
	if (initialized) return;
	initialized=TRUE;

#ifdef _WIN32
	WORD wVersionRequested;
	WSADATA wsaData;
 
	wVersionRequested = MAKEWORD( 1, 0 );

	if (WSAStartup(wVersionRequested,&wsaData)!=0) 
	{
		g_error("Fail to initialise socket api");
	}
#endif

#ifdef HAVE_GLIB
	if (!g_thread_supported()) g_thread_init (NULL);
#endif
	av_profile_init(&av_profile);
	ortp_global_stats_reset();
	init_random_number_generator();
	g_message("oRTP-" ORTP_VERSION "initialized.");
}


/**
 *ortp_scheduler_init:
 *
 *	Initialize the oRTP scheduler. You only have to do that if you intend to use the
 *	scheduled mode of the #RtpSession in your application.
 *	
**/
void ortp_scheduler_init()
{
	static gboolean initialized=FALSE;
	if (initialized) return;
	initialized=TRUE;
#ifdef __hpux
	/* on hpux, we must block sigalrm on the main process, because signal delivery
	is ?random?, well, sometimes the SIGALRM goes to both the main thread and the 
	scheduler thread */
	sigset_t set;
	sigemptyset(&set);
	sigaddset(&set,SIGALRM);
	sigprocmask(SIG_BLOCK,&set,NULL);
#endif /* __hpux */
	if (!g_thread_supported()) g_thread_init(NULL);
	__ortp_scheduler=rtp_scheduler_new();
	rtp_scheduler_start(__ortp_scheduler);
	//sleep(1);
}


/**
 *ortp_exit:
 *
 * Gracefully uninitialize the library, including shutdowning the scheduler if it was started.
 *	
**/
void ortp_exit()
{
	if (__ortp_scheduler!=NULL)
	{
		rtp_scheduler_destroy(__ortp_scheduler);
		__ortp_scheduler=NULL;
	}
}

/**
 *ortp_get_scheduler:
 *
 *	Returns a pointer to the scheduler, NULL if it was not running.
 *	The application developer should have to call this function.
 *
 *Returns: a pointer to the scheduler.
**/
RtpScheduler * ortp_get_scheduler()
{
	if (__ortp_scheduler==NULL) g_error("Cannot use the scheduled mode: the scheduler is not "
									"started. Call ortp_scheduler_init() at the begginning of the application.");
	return __ortp_scheduler;
}


void ortp_log(const gchar *log_domain,GLogLevelFlags log_level,
                                           const gchar *message,
                                           gpointer user_data)
{
	gchar *lev;
	switch(log_level){
		case G_LOG_LEVEL_MESSAGE:
			lev="message";
			break;
		case G_LOG_LEVEL_WARNING:
			lev="warning";
			break;
		case G_LOG_LEVEL_ERROR:
			lev="error";
		default:
			lev="(unknown log type)";
	}
	if (user_data==NULL){
		user_data=stdout;
	}
	fprintf((FILE*)user_data,"%s-%s:%s\n",log_domain,lev,message);
}


/**
 *ortp_set_debug_file:
 *@domain:	one of "oRTP" or "oRTP-stats" logging domain.
 *@file: a FILE pointer where to output the messages from the domain.
 *
 * Warning: domain is ignored when not compiling with glib support.
**/
void ortp_set_debug_file(gchar *domain,FILE *file)
{
	if (file!=NULL)
		g_log_set_handler (domain, G_LOG_LEVEL_MASK, ortp_log, (gpointer)file);
	else g_log_set_handler (domain, G_LOG_LEVEL_MASK, dummy_log, NULL);
}
/**
 *ortp_set_log_handler:
 *@domain: one of the "oRTP" or "oRTP-stats" logging domain.
 *@func: your logging function, compatible with the GLogFunc prototype.
 *
 * Warning: domain is ignored when not compiling with glib support.
**/
void ortp_set_log_handler(const gchar *domain, GLogFunc func, gpointer userdata){
	g_log_set_handler(domain,G_LOG_LEVEL_MASK,func,userdata);
}



void ortp_global_stats_display()
{
	rtp_stats_display(&ortp_global_stats,"Global statistics");
#ifdef ENABLE_MEMCHECK	
	printf("Unfreed allocations: %i\n",ortp_allocations);
#endif
}


void rtp_stats_display(rtp_stats_t *stats, char *header)
{

	g_log("oRTP-stats",G_LOG_LEVEL_MESSAGE,
			"\n   %s :\n"
	      " number of rtp packet sent=%lld\n"
	      " number of rtp bytes sent=%lld bytes\n"
	      " number of rtp packet received=%lld\n"
	      " number of rtp bytes received=%lld bytes\n"
	      " number of incoming rtp bytes successfully delivered to the application=%lld \n"
	      " number of times the application queried a packet that didn't exist=%lld \n"
	      " number of rtp packets received too late=%lld\n"
		  " number of rtp packets skipped=%lld\n"
	      " number of bad formatted rtp packets=%lld\n"
	      " number of packet discarded because of queue overflow=%lld\n",
	      header,
	      (long long)stats->packet_sent,
	      (long long)stats->sent,
	      (long long)stats->packet_recv,
	      (long long)stats->hw_recv,
	      (long long)stats->recv,
	      (long long)stats->unavaillable,
	      (long long)stats->outoftime,
		  (long long)stats->skipped,
	      (long long)stats->bad,
	      (long long)stats->discarded);
}

void ortp_global_stats_reset(){
	memset(&ortp_global_stats,0,sizeof(rtp_stats_t));
}

rtp_stats_t *ortp_get_global_stats(){
	return &ortp_global_stats;
}

void rtp_stats_reset(rtp_stats_t *stats){
	memset((void*)stats,0,sizeof(rtp_stats_t));
}


/**
 *ortp_min_version_required:
 *@major: 
 *@minor: 
 *@micro:
 *
 * This function give the opportunity to programs to check if the libortp they link to
 * has the minimum version number they need.
 *
 * Returns: true if ortp has a version number greater or equal than the required one.
**/
gboolean ortp_min_version_required(int major, int minor, int micro){
	return ((major*1000000) + (minor*1000) + micro) <= 
		   ((ORTP_MAJOR_VERSION*1000000) + (ORTP_MINOR_VERSION*1000) + ORTP_MICRO_VERSION);
}