Revision febef1ea

View differences:

plugins/janus_audiobridge.c
1191 1191

  
1192 1192
/* Thread to handle incoming messages */
1193 1193
static void *janus_audiobridge_handler(void *data) {
1194
	JANUS_LOG(LOG_VERB, "Joining thread\n");
1194
	JANUS_LOG(LOG_VERB, "Joining AudioBridge handler thread\n");
1195 1195
	janus_audiobridge_message *msg = NULL;
1196 1196
	int error_code = 0;
1197 1197
	char *error_cause = calloc(512, sizeof(char));	/* FIXME 512 should be enough, but anyway... */
......
1953 1953
		}
1954 1954
	}
1955 1955
	g_free(error_cause);
1956
	JANUS_LOG(LOG_VERB, "Leaving thread\n");
1956
	JANUS_LOG(LOG_VERB, "Leaving AudioBridge handler thread\n");
1957 1957
	return NULL;
1958 1958
}
1959 1959

  
plugins/janus_echotest.c
484 484

  
485 485
/* Thread to handle incoming messages */
486 486
static void *janus_echotest_handler(void *data) {
487
	JANUS_LOG(LOG_VERB, "Joining thread\n");
487
	JANUS_LOG(LOG_VERB, "Joining EchoTest handler thread\n");
488 488
	janus_echotest_message *msg = NULL;
489 489
	int error_code = 0;
490 490
	char *error_cause = calloc(512, sizeof(char));	/* FIXME 512 should be enough, but anyway... */
......
637 637
		}
638 638
	}
639 639
	g_free(error_cause);
640
	JANUS_LOG(LOG_VERB, "Leaving thread\n");
640
	JANUS_LOG(LOG_VERB, "Leaving EchoTest handler thread\n");
641 641
	return NULL;
642 642
}
plugins/janus_recordplay.c
708 708

  
709 709
/* Thread to handle incoming messages */
710 710
static void *janus_recordplay_handler(void *data) {
711
	JANUS_LOG(LOG_VERB, "Joining thread\n");
711
	JANUS_LOG(LOG_VERB, "Joining Record&Play handler thread\n");
712 712
	janus_recordplay_message *msg = NULL;
713 713
	int error_code = 0;
714 714
	char *error_cause = calloc(512, sizeof(char));	/* FIXME 512 should be enough, but anyway... */
......
1069 1069
		}
1070 1070
	}
1071 1071
	g_free(error_cause);
1072
	JANUS_LOG(LOG_VERB, "Leaving thread\n");
1072
	JANUS_LOG(LOG_VERB, "LeavingRecord&Play handler thread\n");
1073 1073
	return NULL;
1074 1074
}
1075 1075

  
plugins/janus_sip.c
765 765

  
766 766
/* Thread to handle incoming messages */
767 767
static void *janus_sip_handler(void *data) {
768
	JANUS_LOG(LOG_VERB, "Joining thread\n");
768
	JANUS_LOG(LOG_VERB, "Joining SIP handler thread\n");
769 769
	janus_sip_message *msg = NULL;
770 770
	int error_code = 0;
771 771
	char *error_cause = calloc(512, sizeof(char));	/* FIXME 512 should be enough, but anyway... */
......
1409 1409
		}
1410 1410
	}
1411 1411
	g_free(error_cause);
1412
	JANUS_LOG(LOG_VERB, "Leaving thread\n");
1412
	JANUS_LOG(LOG_VERB, "Leaving SIP handler thread\n");
1413 1413
	return NULL;
1414 1414
}
1415 1415

  
......
2216 2216
			continue;
2217 2217
		}
2218 2218
	}
2219
	JANUS_LOG(LOG_VERB, "Leaving relay thread\n");
2219
	JANUS_LOG(LOG_VERB, "Leaving SIP relay thread\n");
2220 2220
	g_thread_unref(g_thread_self());
2221 2221
	return NULL;
2222 2222
}
plugins/janus_streaming.c
249 249
}
250 250

  
251 251

  
252
typedef struct janus_streaming_context {
253
	/* Needed to fix seq and ts in case of stream switching */
254
	uint32_t a_last_ssrc, a_last_ts, a_base_ts, a_base_ts_prev,
255
			v_last_ssrc, v_last_ts, v_base_ts, v_base_ts_prev;
256
	uint16_t a_last_seq, a_base_seq, a_base_seq_prev,
257
			v_last_seq, v_base_seq, v_base_seq_prev;
258
} janus_streaming_context;
259

  
252 260
typedef struct janus_streaming_session {
253 261
	janus_plugin_session *handle;
254 262
	janus_streaming_mountpoint *mountpoint;
255 263
	gboolean started;
264
	gboolean paused;
265
	janus_streaming_context context;
256 266
	gboolean stopping;
257 267
	guint64 destroyed;	/* Time at which this session was marked as destroyed */
258 268
} janus_streaming_session;
......
265 275
	rtp_header *data;
266 276
	gint length;
267 277
	gint is_video;
278
	uint32_t timestamp;
279
	uint16_t seq_number;
268 280
} janus_streaming_rtp_relay_packet;
269 281

  
270 282

  
......
277 289
#define JANUS_STREAMING_ERROR_NO_SUCH_MOUNTPOINT	455
278 290
#define JANUS_STREAMING_ERROR_CANT_CREATE			456
279 291
#define JANUS_STREAMING_ERROR_UNAUTHORIZED			457
292
#define JANUS_STREAMING_ERROR_CANT_SWITCH			458
280 293
#define JANUS_STREAMING_ERROR_UNKNOWN_ERROR			470
281 294

  
282 295

  
......
659 672
	session->handle = handle;
660 673
	session->mountpoint = NULL;	/* This will happen later */
661 674
	session->started = FALSE;	/* This will happen later */
675
	session->paused = FALSE;
662 676
	session->destroyed = 0;
663 677
	handle->plugin_handle = session;
664 678
	janus_mutex_lock(&sessions_mutex);
......
1569 1583
		g_free(response_text);
1570 1584
		return result;
1571 1585
	} else if(!strcasecmp(request_text, "watch") || !strcasecmp(request_text, "start")
1572
			|| !strcasecmp(request_text, "pause") || !strcasecmp(request_text, "stop")) {
1586
			|| !strcasecmp(request_text, "pause") || !strcasecmp(request_text, "stop")
1587
			|| !strcasecmp(request_text, "switch")) {
1573 1588
		/* These messages are handled asynchronously */
1574 1589
		goto async;
1575 1590
	} else {
......
1622 1637
	if(session->destroyed)
1623 1638
		return;
1624 1639
	/* TODO Only start streaming when we get this event */
1640
	session->context.a_last_ssrc = 0;
1641
	session->context.a_last_ssrc = 0;
1642
	session->context.a_last_ts = 0;
1643
	session->context.a_base_ts = 0;
1644
	session->context.a_base_ts_prev = 0;
1645
	session->context.v_last_ssrc = 0;
1646
	session->context.v_last_ts = 0;
1647
	session->context.v_base_ts = 0;
1648
	session->context.v_base_ts_prev = 0;
1649
	session->context.a_last_seq = 0;
1650
	session->context.a_base_seq = 0;
1651
	session->context.a_base_seq_prev = 0;
1652
	session->context.v_last_seq = 0;
1653
	session->context.v_base_seq = 0;
1654
	session->context.v_base_seq_prev = 0;
1625 1655
	session->started = TRUE;
1626 1656
	/* Prepare JSON event */
1627 1657
	json_t *event = json_object();
......
1683 1713

  
1684 1714
/* Thread to handle incoming messages */
1685 1715
static void *janus_streaming_handler(void *data) {
1686
	JANUS_LOG(LOG_VERB, "Joining thread\n");
1716
	JANUS_LOG(LOG_VERB, "Joining Streaming handler thread\n");
1687 1717
	janus_streaming_message *msg = NULL;
1688 1718
	int error_code = 0;
1689 1719
	char *error_cause = calloc(1024, sizeof(char));
......
1841 1871
			result = json_object();
1842 1872
			json_object_set_new(result, "status", json_string("preparing"));
1843 1873
		} else if(!strcasecmp(request_text, "start")) {
1874
			if(session->mountpoint == NULL) {
1875
				JANUS_LOG(LOG_VERB, "Can't start: no mountpoint set\n");
1876
				error_code = JANUS_STREAMING_ERROR_NO_SUCH_MOUNTPOINT;
1877
				g_snprintf(error_cause, 512, "Can't start: no mountpoint set");
1878
				goto error;
1879
			}
1844 1880
			JANUS_LOG(LOG_VERB, "Starting the streaming\n");
1881
			session->paused = FALSE;
1845 1882
			result = json_object();
1846 1883
			/* We wait for the setup_media event to start: on the other hand, it may have already arrived */
1847 1884
			json_object_set_new(result, "status", json_string(session->started ? "started" : "starting"));
1848 1885
		} else if(!strcasecmp(request_text, "pause")) {
1886
			if(session->mountpoint == NULL) {
1887
				JANUS_LOG(LOG_VERB, "Can't pause: no mountpoint set\n");
1888
				error_code = JANUS_STREAMING_ERROR_NO_SUCH_MOUNTPOINT;
1889
				g_snprintf(error_cause, 512, "Can't start: no mountpoint set");
1890
				goto error;
1891
			}
1849 1892
			JANUS_LOG(LOG_VERB, "Pausing the streaming\n");
1850
			session->started = FALSE;
1893
			session->paused = TRUE;
1851 1894
			result = json_object();
1852 1895
			json_object_set_new(result, "status", json_string("pausing"));
1896
		} else if(!strcasecmp(request_text, "switch")) {
1897
			/* This listener wants to switch to a different mountpoint
1898
			 * NOTE: this only works for live RTP streams as of now: you
1899
			 * cannot, for instance, switch from a live RTP mountpoint to
1900
			 * an on demand one or viceversa (TBD.) */
1901
			janus_streaming_mountpoint *oldmp = session->mountpoint;
1902
			if(oldmp == NULL) {
1903
				JANUS_LOG(LOG_VERB, "Can't switch: not on a mountpoint\n");
1904
				error_code = JANUS_STREAMING_ERROR_NO_SUCH_MOUNTPOINT;
1905
				g_snprintf(error_cause, 512, "Can't switch: not on a mountpoint");
1906
				goto error;
1907
			}
1908
			if(oldmp->streaming_type != janus_streaming_type_live || 
1909
					oldmp->streaming_source != janus_streaming_source_rtp) {
1910
				JANUS_LOG(LOG_VERB, "Can't switch: not on a live RTP mountpoint\n");
1911
				error_code = JANUS_STREAMING_ERROR_CANT_SWITCH;
1912
				g_snprintf(error_cause, 512, "Can't switch: not on a live RTP mountpoint");
1913
				goto error;
1914
			}
1915
			json_t *id = json_object_get(root, "id");
1916
			if(!id) {
1917
				JANUS_LOG(LOG_ERR, "Missing element (id)\n");
1918
				error_code = JANUS_STREAMING_ERROR_MISSING_ELEMENT;
1919
				g_snprintf(error_cause, 512, "Missing element (id)");
1920
				goto error;
1921
			}
1922
			if(!json_is_integer(id)) {
1923
				JANUS_LOG(LOG_ERR, "Invalid element (id should be an integer)\n");
1924
				error_code = JANUS_STREAMING_ERROR_INVALID_ELEMENT;
1925
				g_snprintf(error_cause, 512, "Invalid element (id should be an integer)");
1926
				goto error;
1927
			}
1928
			gint64 id_value = json_integer_value(id);
1929
			janus_mutex_lock(&mountpoints_mutex);
1930
			janus_streaming_mountpoint *mp = g_hash_table_lookup(mountpoints, GINT_TO_POINTER(id_value));
1931
			if(mp == NULL) {
1932
				janus_mutex_unlock(&mountpoints_mutex);
1933
				JANUS_LOG(LOG_VERB, "No such mountpoint/stream %"SCNu64"\n", id_value);
1934
				error_code = JANUS_STREAMING_ERROR_NO_SUCH_MOUNTPOINT;
1935
				g_snprintf(error_cause, 512, "No such mountpoint/stream %"SCNu64"", id_value);
1936
				goto error;
1937
			}
1938
			if(mp->streaming_type != janus_streaming_type_live || 
1939
					mp->streaming_source != janus_streaming_source_rtp) {
1940
				janus_mutex_unlock(&mountpoints_mutex);
1941
				JANUS_LOG(LOG_VERB, "Can't switch: target is not a live RTP mountpoint\n");
1942
				error_code = JANUS_STREAMING_ERROR_CANT_SWITCH;
1943
				g_snprintf(error_cause, 512, "Can't switch: target is not a live RTP mountpoint");
1944
				goto error;
1945
			}
1946
			janus_mutex_unlock(&mountpoints_mutex);
1947
			JANUS_LOG(LOG_VERB, "Request to switch to mountpoint/stream %"SCNu64" (old: %"SCNu64")\n", id_value, oldmp->id);
1948
			session->paused = TRUE;
1949
			/* Unsubscribe from the previous mountpoint and subscribe to the new one */
1950
			janus_mutex_lock(&oldmp->mutex);
1951
			oldmp->listeners = g_list_remove_all(oldmp->listeners, session);
1952
			janus_mutex_unlock(&oldmp->mutex);
1953
			/* Subscribe to the new one */
1954
			janus_mutex_lock(&mp->mutex);
1955
			mp->listeners = g_list_append(mp->listeners, session);
1956
			janus_mutex_unlock(&mp->mutex);
1957
			session->mountpoint = mp;
1958
			session->paused = FALSE;
1959
			/* Done */
1960
			result = json_object();
1961
			json_object_set_new(result, "streaming", json_string("event"));
1962
			json_object_set_new(result, "switched", json_string("ok"));
1963
			json_object_set_new(result, "id", json_integer(id_value));
1853 1964
		} else if(!strcasecmp(request_text, "stop")) {
1854 1965
			if(session->stopping || !session->started) {
1855 1966
				/* Been there, done that: ignore */
......
1859 1970
			JANUS_LOG(LOG_VERB, "Stopping the streaming\n");
1860 1971
			session->stopping = TRUE;
1861 1972
			session->started = FALSE;
1973
			session->paused = FALSE;
1862 1974
			result = json_object();
1863 1975
			json_object_set_new(result, "status", json_string("stopping"));
1864 1976
			if(session->mountpoint) {
......
1920 2032
		}
1921 2033
	}
1922 2034
	g_free(error_cause);
1923
	JANUS_LOG(LOG_VERB, "Leaving thread\n");
2035
	JANUS_LOG(LOG_VERB, "Leaving Streaming handler thread\n");
1924 2036
	return NULL;
1925 2037
}
1926 2038

  
......
2160 2272
		return NULL;
2161 2273
	}
2162 2274
	if(mountpoint->streaming_source != janus_streaming_source_file) {
2163
		JANUS_LOG(LOG_ERR, "Not an file source mountpoint!\n");
2275
		JANUS_LOG(LOG_ERR, "[%s] Not an file source mountpoint!\n", mountpoint->name);
2164 2276
		g_thread_unref(g_thread_self());
2165 2277
		return NULL;
2166 2278
	}
2167 2279
	if(mountpoint->streaming_type != janus_streaming_type_on_demand) {
2168
		JANUS_LOG(LOG_ERR, "Not an on-demand file source mountpoint!\n");
2280
		JANUS_LOG(LOG_ERR, "[%s] Not an on-demand file source mountpoint!\n", mountpoint->name);
2169 2281
		g_thread_unref(g_thread_self());
2170 2282
		return NULL;
2171 2283
	}
2172 2284
	janus_streaming_file_source *source = mountpoint->source;
2173 2285
	if(source == NULL || source->filename == NULL) {
2174 2286
		g_thread_unref(g_thread_self());
2175
		JANUS_LOG(LOG_ERR, "Invalid file source mountpoint!\n");
2287
		JANUS_LOG(LOG_ERR, "[%s] Invalid file source mountpoint!\n", mountpoint->name);
2176 2288
		return NULL;
2177 2289
	}
2178
	JANUS_LOG(LOG_VERB, "Opening file source %s...\n", source->filename);
2290
	JANUS_LOG(LOG_VERB, "[%s] Opening file source %s...\n", mountpoint->name, source->filename);
2179 2291
	FILE *audio = fopen(source->filename, "rb");
2180 2292
	if(!audio) {
2181
		JANUS_LOG(LOG_ERR, "Ooops, audio file missing!\n");
2293
		JANUS_LOG(LOG_ERR, "[%s] Ooops, audio file missing!\n", mountpoint->name);
2182 2294
		g_thread_unref(g_thread_self());
2183 2295
		return NULL;
2184 2296
	}
2185
	JANUS_LOG(LOG_VERB, "Streaming audio file: %s\n", source->filename);
2297
	JANUS_LOG(LOG_VERB, "[%s] Streaming audio file: %s\n", mountpoint->name, source->filename);
2186 2298
	/* Buffer */
2187 2299
	char *buf = calloc(1024, sizeof(char));
2188 2300
	if(buf == NULL) {
2189
		JANUS_LOG(LOG_FATAL, "Memory error!\n");
2301
		JANUS_LOG(LOG_FATAL, "[%s] Memory error!\n", mountpoint->name);
2190 2302
		g_thread_unref(g_thread_self());
2191 2303
		return NULL;
2192 2304
	}
2305
	char *name = g_strdup(mountpoint->name ? mountpoint->name : "??");
2193 2306
	/* Set up RTP */
2194 2307
	gint16 seq = 1;
2195 2308
	gint32 ts = 0;
......
2230 2343
			before.tv_usec -= 1000000;
2231 2344
		}
2232 2345
		/* If not started or paused, wait some more */
2233
		if(!session->started || !mountpoint->enabled)
2346
		if(!session->started || session->paused || !mountpoint->enabled)
2234 2347
			continue;
2235 2348
		/* Read frame from file... */
2236 2349
		read = fread(buf + RTP_HEADER_SIZE, sizeof(char), 160, audio);
2237 2350
		if(feof(audio)) {
2238 2351
			/* FIXME We're doing this forever... should this be configurable? */
2239
			JANUS_LOG(LOG_VERB, "Rewind! (%s)\n", source->filename);
2352
			JANUS_LOG(LOG_VERB, "[%s] Rewind! (%s)\n", name, source->filename);
2240 2353
			fseek(audio, 0, SEEK_SET);
2241 2354
			continue;
2242 2355
		}
......
2259 2372
		header->timestamp = htonl(ts);
2260 2373
		header->markerbit = 0;
2261 2374
	}
2262
	JANUS_LOG(LOG_VERB, "Leaving filesource thread\n");
2375
	JANUS_LOG(LOG_VERB, "[%s] Leaving filesource (ondemand) thread\n", name);
2376
	g_free(name);
2263 2377
	g_free(buf);
2264 2378
	fclose(audio);
2265 2379
	g_thread_unref(g_thread_self());
......
2268 2382

  
2269 2383
/* FIXME Thread to send RTP packets from a file (live) */
2270 2384
static void *janus_streaming_filesource_thread(void *data) {
2271
	JANUS_LOG(LOG_VERB, "Filesource RTP thread starting...\n");
2385
	JANUS_LOG(LOG_VERB, "Filesource (live) thread starting...\n");
2272 2386
	janus_streaming_mountpoint *mountpoint = (janus_streaming_mountpoint *)data;
2273 2387
	if(!mountpoint) {
2274 2388
		JANUS_LOG(LOG_ERR, "Invalid mountpoint!\n");
......
2276 2390
		return NULL;
2277 2391
	}
2278 2392
	if(mountpoint->streaming_source != janus_streaming_source_file) {
2279
		JANUS_LOG(LOG_ERR, "Not an file source mountpoint!\n");
2393
		JANUS_LOG(LOG_ERR, "[%s] Not an file source mountpoint!\n", mountpoint->name);
2280 2394
		g_thread_unref(g_thread_self());
2281 2395
		return NULL;
2282 2396
	}
2283 2397
	if(mountpoint->streaming_type != janus_streaming_type_live) {
2284
		JANUS_LOG(LOG_ERR, "Not a live file source mountpoint!\n");
2398
		JANUS_LOG(LOG_ERR, "[%s] Not a live file source mountpoint!\n", mountpoint->name);
2285 2399
		g_thread_unref(g_thread_self());
2286 2400
		return NULL;
2287 2401
	}
2288 2402
	janus_streaming_file_source *source = mountpoint->source;
2289 2403
	if(source == NULL || source->filename == NULL) {
2290
		JANUS_LOG(LOG_ERR, "Invalid file source mountpoint!\n");
2404
		JANUS_LOG(LOG_ERR, "[%s] Invalid file source mountpoint!\n", mountpoint->name);
2291 2405
		g_thread_unref(g_thread_self());
2292 2406
		return NULL;
2293 2407
	}
2294
	JANUS_LOG(LOG_VERB, "Opening file source %s...\n", source->filename);
2408
	JANUS_LOG(LOG_VERB, "[%s] Opening file source %s...\n", mountpoint->name, source->filename);
2295 2409
	FILE *audio = fopen(source->filename, "rb");
2296 2410
	if(!audio) {
2297
		JANUS_LOG(LOG_ERR, "Ooops, audio file missing!\n");
2411
		JANUS_LOG(LOG_ERR, "[%s] Ooops, audio file missing!\n", mountpoint->name);
2298 2412
		g_thread_unref(g_thread_self());
2299 2413
		return NULL;
2300 2414
	}
2301
	JANUS_LOG(LOG_VERB, "Streaming audio file: %s\n", source->filename);
2415
	JANUS_LOG(LOG_VERB, "[%s] Streaming audio file: %s\n", mountpoint->name, source->filename);
2302 2416
	/* Buffer */
2303 2417
	char *buf = calloc(1024, sizeof(char));
2304 2418
	if(buf == NULL) {
2305
		JANUS_LOG(LOG_FATAL, "Memory error!\n");
2419
		JANUS_LOG(LOG_FATAL, "[%s] Memory error!\n", mountpoint->name);
2306 2420
		g_thread_unref(g_thread_self());
2307 2421
		return NULL;
2308 2422
	}
2423
	char *name = g_strdup(mountpoint->name ? mountpoint->name : "??");
2309 2424
	/* Set up RTP */
2310 2425
	gint16 seq = 1;
2311 2426
	gint32 ts = 0;
......
2352 2467
		read = fread(buf + RTP_HEADER_SIZE, sizeof(char), 160, audio);
2353 2468
		if(feof(audio)) {
2354 2469
			/* FIXME We're doing this forever... should this be configurable? */
2355
			JANUS_LOG(LOG_VERB, "Rewind! (%s)\n", source->filename);
2470
			JANUS_LOG(LOG_VERB, "[%s] Rewind! (%s)\n", name, source->filename);
2356 2471
			fseek(audio, 0, SEEK_SET);
2357 2472
			continue;
2358 2473
		}
......
2377 2492
		header->timestamp = htonl(ts);
2378 2493
		header->markerbit = 0;
2379 2494
	}
2380
	JANUS_LOG(LOG_VERB, "Leaving filesource thread\n");
2495
	JANUS_LOG(LOG_VERB, "[%s] Leaving filesource (live) thread\n", name);
2496
	g_free(name);
2381 2497
	g_free(buf);
2382 2498
	fclose(audio);
2383 2499
	g_thread_unref(g_thread_self());
......
2386 2502

  
2387 2503
/* FIXME Test thread to relay RTP frames coming from gstreamer/ffmpeg/others */
2388 2504
static void *janus_streaming_relay_thread(void *data) {
2389
	JANUS_LOG(LOG_VERB, "Starting relay thread\n");
2505
	JANUS_LOG(LOG_VERB, "Starting streaming relay thread\n");
2390 2506
	janus_streaming_mountpoint *mountpoint = (janus_streaming_mountpoint *)data;
2391 2507
	if(!mountpoint) {
2392 2508
		JANUS_LOG(LOG_ERR, "Invalid mountpoint!\n");
......
2438 2554
		}
2439 2555
		JANUS_LOG(LOG_VERB, "[%s] Video listener bound to port %d\n", mountpoint->name, video_port);
2440 2556
	}
2557
	char *name = g_strdup(mountpoint->name ? mountpoint->name : "??");
2441 2558
	int maxfd = (audio_fd > video_fd) ? audio_fd : video_fd;
2442 2559
	/* Needed to fix seq and ts */
2443 2560
	uint32_t a_last_ssrc = 0, a_last_ts = 0, a_base_ts = 0, a_base_ts_prev = 0,
......
2485 2602
			/* Do we have a new stream? */
2486 2603
			if(ntohl(packet.data->ssrc) != a_last_ssrc) {
2487 2604
				a_last_ssrc = ntohl(packet.data->ssrc);
2488
				JANUS_LOG(LOG_INFO, "[%s] New audio stream! (ssrc=%u)\n", mountpoint->name, a_last_ssrc);
2605
				JANUS_LOG(LOG_INFO, "[%s] New audio stream! (ssrc=%u)\n", name, a_last_ssrc);
2489 2606
				a_base_ts_prev = a_last_ts;
2490 2607
				a_base_ts = ntohl(packet.data->timestamp);
2491 2608
				a_base_seq_prev = a_last_seq;
......
2500 2617
			packet.data->type = mountpoint->codecs.audio_pt;
2501 2618
			/* Is there a recorder? */
2502 2619
			if(source->arc) {
2503
				JANUS_LOG(LOG_HUGE, "Saving audio frame (%d bytes)\n", bytes);
2620
				JANUS_LOG(LOG_HUGE, "[%s] Saving audio frame (%d bytes)\n", name, bytes);
2504 2621
				janus_recorder_save_frame(source->arc, buffer, bytes);
2505 2622
			}
2623
			/* Backup the actual timestamp and sequence number set by the restreamer, in case switching is involved */
2624
			packet.timestamp = ntohl(packet.data->timestamp);
2625
			packet.seq_number = ntohs(packet.data->seq_number);
2506 2626
			/* Go! */
2507 2627
			janus_mutex_lock(&mountpoint->mutex);
2508 2628
			g_list_foreach(mountpoint->listeners, janus_streaming_relay_rtp_packet, &packet);
......
2529 2649
			/* Do we have a new stream? */
2530 2650
			if(ntohl(packet.data->ssrc) != v_last_ssrc) {
2531 2651
				v_last_ssrc = ntohl(packet.data->ssrc);
2532
				JANUS_LOG(LOG_INFO, "[%s] New video stream! (ssrc=%u)\n", mountpoint->name, v_last_ssrc);
2652
				JANUS_LOG(LOG_INFO, "[%s] New video stream! (ssrc=%u)\n", name, v_last_ssrc);
2533 2653
				v_base_ts_prev = v_last_ts;
2534 2654
				v_base_ts = ntohl(packet.data->timestamp);
2535 2655
				v_base_seq_prev = v_last_seq;
......
2544 2664
			packet.data->type = mountpoint->codecs.video_pt;
2545 2665
			/* Is there a recorder? */
2546 2666
			if(source->vrc) {
2547
				JANUS_LOG(LOG_HUGE, "Saving video frame (%d bytes)\n", bytes);
2667
				JANUS_LOG(LOG_HUGE, "[%s] Saving video frame (%d bytes)\n", name, bytes);
2548 2668
				janus_recorder_save_frame(source->vrc, buffer, bytes);
2549 2669
			}
2670
			/* Backup the actual timestamp and sequence number set by the restreamer, in case switching is involved */
2671
			packet.timestamp = ntohl(packet.data->timestamp);
2672
			packet.seq_number = ntohs(packet.data->seq_number);
2550 2673
			/* Go! */
2551 2674
			janus_mutex_lock(&mountpoint->mutex);
2552 2675
			g_list_foreach(mountpoint->listeners, janus_streaming_relay_rtp_packet, &packet);
......
2554 2677
			continue;
2555 2678
		}
2556 2679
	}
2557
	JANUS_LOG(LOG_VERB, "Leaving relay thread\n");
2680
	JANUS_LOG(LOG_VERB, "[%s] Leaving streaming relay thread\n", name);
2681
	g_free(name);
2558 2682
	g_thread_unref(g_thread_self());
2559 2683
	return NULL;
2560 2684
}
......
2570 2694
		// JANUS_LOG(LOG_ERR, "Invalid session...\n");
2571 2695
		return;
2572 2696
	}
2573
	if(!session->started) {
2697
	if(!session->started || session->paused) {
2574 2698
		// JANUS_LOG(LOG_ERR, "Streaming not started yet for this session...\n");
2575 2699
		return;
2576 2700
	}
2577
	if(gateway != NULL)	/* FIXME What about RTCP? */
2578
		gateway->relay_rtp(session->handle, packet->is_video, (char *)packet->data, packet->length);
2701

  
2702
	/* Make sure there hasn't been a publisher switch by checking the SSRC */
2703
	if(packet->is_video) {
2704
		if(ntohl(packet->data->ssrc) != session->context.v_last_ssrc) {
2705
			session->context.v_last_ssrc = ntohl(packet->data->ssrc);
2706
			session->context.v_base_ts_prev = session->context.v_last_ts;
2707
			session->context.v_base_ts = packet->timestamp;
2708
			session->context.v_base_seq_prev = session->context.v_last_seq;
2709
			session->context.v_base_seq = packet->seq_number;
2710
		}
2711
		/* Compute a coherent timestamp and sequence number */
2712
		session->context.v_last_ts = (packet->timestamp-session->context.v_base_ts)
2713
			+ session->context.v_base_ts_prev+4500;	/* FIXME When switching, we assume 15fps */
2714
		session->context.v_last_seq = (packet->seq_number-session->context.v_base_seq)+session->context.v_base_seq_prev+1;
2715
		/* Update the timestamp and sequence number in the RTP packet, and send it */
2716
		packet->data->timestamp = htonl(session->context.v_last_ts);
2717
		packet->data->seq_number = htons(session->context.v_last_seq);
2718
		if(gateway != NULL)
2719
			gateway->relay_rtp(session->handle, packet->is_video, (char *)packet->data, packet->length);
2720
		/* Restore the timestamp and sequence number to what the publisher set them to */
2721
		packet->data->timestamp = htonl(packet->timestamp);
2722
		packet->data->seq_number = htons(packet->seq_number);
2723
	} else {
2724
		if(ntohl(packet->data->ssrc) != session->context.a_last_ssrc) {
2725
			session->context.a_last_ssrc = ntohl(packet->data->ssrc);
2726
			session->context.a_base_ts_prev = session->context.a_last_ts;
2727
			session->context.a_base_ts = packet->timestamp;
2728
			session->context.a_base_seq_prev = session->context.a_last_seq;
2729
			session->context.a_base_seq = packet->seq_number;
2730
		}
2731
		/* Compute a coherent timestamp and sequence number */
2732
		session->context.a_last_ts = (packet->timestamp-session->context.a_base_ts)
2733
			+ session->context.a_base_ts_prev+960;	/* FIXME When switching, we assume Opus and so a 960 ts step */
2734
		session->context.a_last_seq = (packet->seq_number-session->context.a_base_seq)+session->context.a_base_seq_prev+1;
2735
		/* Update the timestamp and sequence number in the RTP packet, and send it */
2736
		packet->data->timestamp = htonl(session->context.a_last_ts);
2737
		packet->data->seq_number = htons(session->context.a_last_seq);
2738
		if(gateway != NULL)
2739
			gateway->relay_rtp(session->handle, packet->is_video, (char *)packet->data, packet->length);
2740
		/* Restore the timestamp and sequence number to what the publisher set them to */
2741
		packet->data->timestamp = htonl(packet->timestamp);
2742
		packet->data->seq_number = htons(packet->seq_number);
2743
	}
2744

  
2579 2745
	return;
2580 2746
}
plugins/janus_videocall.c
524 524

  
525 525
/* Thread to handle incoming messages */
526 526
static void *janus_videocall_handler(void *data) {
527
	JANUS_LOG(LOG_VERB, "Joining thread\n");
527
	JANUS_LOG(LOG_VERB, "Joining VideoCall handler thread\n");
528 528
	janus_videocall_message *msg = NULL;
529 529
	int error_code = 0;
530 530
	char *error_cause = calloc(512, sizeof(char));	/* FIXME 512 should be enough, but anyway... */
......
888 888
		}
889 889
	}
890 890
	g_free(error_cause);
891
	JANUS_LOG(LOG_VERB, "Leaving thread\n");
891
	JANUS_LOG(LOG_VERB, "Leaving VideoCall handler thread\n");
892 892
	return NULL;
893 893
}
plugins/janus_videoroom.c
1533 1533

  
1534 1534
/* Thread to handle incoming messages */
1535 1535
static void *janus_videoroom_handler(void *data) {
1536
	JANUS_LOG(LOG_VERB, "Joining thread\n");
1536
	JANUS_LOG(LOG_VERB, "Joining VideoRoom handler thread\n");
1537 1537
	janus_videoroom_message *msg = NULL;
1538 1538
	int error_code = 0;
1539 1539
	char *error_cause = calloc(512, sizeof(char));	/* FIXME 512 should be enough, but anyway... */
......
2811 2811
		}
2812 2812
	}
2813 2813
	g_free(error_cause);
2814
	JANUS_LOG(LOG_VERB, "Leaving thread\n");
2814
	JANUS_LOG(LOG_VERB, "Leaving VideoRoom handler thread\n");
2815 2815
	return NULL;
2816 2816
}
2817 2817

  
plugins/janus_voicemail.c
554 554

  
555 555
/* Thread to handle incoming messages */
556 556
static void *janus_voicemail_handler(void *data) {
557
	JANUS_LOG(LOG_VERB, "Joining thread\n");
557
	JANUS_LOG(LOG_VERB, "Joining VoiceMail handler thread\n");
558 558
	janus_voicemail_message *msg = NULL;
559 559
	int error_code = 0;
560 560
	char *error_cause = calloc(512, sizeof(char));	/* FIXME 512 should be enough, but anyway... */
......
759 759
		}
760 760
	}
761 761
	g_free(error_cause);
762
	JANUS_LOG(LOG_VERB, "Leaving thread\n");
762
	JANUS_LOG(LOG_VERB, "Leaving VoiceMail handler thread\n");
763 763
	return NULL;
764 764
}
765 765

  

Also available in: Unified diff