Revision d223cef1

View differences:

plugins/janus_echotest.c
185 185
	uint64_t bitrate;
186 186
	janus_recorder *arc;	/* The Janus recorder instance for this user's audio, if enabled */
187 187
	janus_recorder *vrc;	/* The Janus recorder instance for this user's video, if enabled */
188
	janus_mutex rec_mutex;	/* Mutex to protect the recorders from race conditions */
188 189
	guint16 slowlink_count;
189 190
	volatile gint hangingup;
190 191
	gint64 destroyed;	/* Time at which this session was marked as destroyed */
......
379 380
	session->has_video = FALSE;
380 381
	session->audio_active = TRUE;
381 382
	session->video_active = TRUE;
383
	janus_mutex_init(&session->rec_mutex);
382 384
	session->bitrate = 0;	/* No limit */
383 385
	session->destroyed = 0;
384 386
	g_atomic_int_set(&session->hangingup, 0);
......
491 493
			return;
492 494
		if((!video && session->audio_active) || (video && session->video_active)) {
493 495
			/* Save the frame if we're recording */
494
			if(video && session->vrc)
495
				janus_recorder_save_frame(session->vrc, buf, len);
496
			else if(!video && session->arc)
497
				janus_recorder_save_frame(session->arc, buf, len);
496
			janus_recorder_save_frame(video ? session->vrc : session->arc, buf, len);
498 497
			/* Send the frame back */
499 498
			gateway->relay_rtp(handle, video, buf, len);
500 499
		}
......
620 619
	JANUS_LOG(LOG_VERB, "  >> %d (%s)\n", ret, janus_get_api_error(ret));
621 620
	g_free(event_text);
622 621
	/* Get rid of the recorders, if available */
622
	janus_mutex_lock(&session->rec_mutex);
623 623
	if(session->arc) {
624 624
		janus_recorder_close(session->arc);
625 625
		JANUS_LOG(LOG_INFO, "Closed audio recording %s\n", session->arc->filename ? session->arc->filename : "??");
......
632 632
		janus_recorder_free(session->vrc);
633 633
	}
634 634
	session->vrc = NULL;
635
	janus_mutex_unlock(&session->rec_mutex);
635 636
	/* Reset controls */
636 637
	session->has_audio = FALSE;
637 638
	session->has_video = FALSE;
......
774 775
			gboolean recording = json_is_true(record);
775 776
			const char *recording_base = json_string_value(recfile);
776 777
			JANUS_LOG(LOG_VERB, "Recording %s (base filename: %s)\n", recording ? "enabled" : "disabled", recording_base ? recording_base : "not provided");
778
			janus_mutex_lock(&session->rec_mutex);
777 779
			if(!recording) {
778 780
				/* Not recording (anymore?) */
779 781
				if(session->arc) {
......
841 843
					gateway->relay_rtcp(session->handle, 1, buf, 12);
842 844
				}
843 845
			}
846
			janus_mutex_unlock(&session->rec_mutex);
844 847
		}
845 848
		/* Any SDP to handle? */
846 849
		if(msg->sdp) {
plugins/janus_recordplay.c
392 392
	janus_recordplay_recording *recording;
393 393
	janus_recorder *arc;	/* Audio recorder */
394 394
	janus_recorder *vrc;	/* Video recorder */
395
	janus_mutex rec_mutex;	/* Mutex to protect the recorders from race conditions */
395 396
	janus_recordplay_frame_packet *aframes;	/* Audio frames (for playout) */
396 397
	janus_recordplay_frame_packet *vframes;	/* Video frames (for playout) */
397 398
	guint video_remb_startup;
......
657 658
	session->firefox = FALSE;
658 659
	session->arc = NULL;
659 660
	session->vrc = NULL;
661
	janus_mutex_init(&session->rec_mutex);
660 662
	session->destroyed = 0;
661 663
	g_atomic_int_set(&session->hangingup, 0);
662 664
	session->video_remb_startup = 4;
......
983 985
			return;
984 986
		/* Are we recording? */
985 987
		if(session->recorder) {
986
			if(video && session->vrc)
987
				janus_recorder_save_frame(session->vrc, buf, len);
988
			else if(!video && session->arc)
989
				janus_recorder_save_frame(session->arc, buf, len);
988
			janus_recorder_save_frame(video ? session->vrc : session->arc, buf, len);
990 989
		}
991 990

  
992 991
		janus_recordplay_send_rtcp_feedback(handle, video, buf, len);
......
1324 1323
		} else if(!strcasecmp(request_text, "stop")) {
1325 1324
			/* Stop the recording/playout */
1326 1325
			session->active = FALSE;
1326
			janus_mutex_lock(&session->rec_mutex);
1327 1327
			if(session->arc) {
1328 1328
				janus_recorder_close(session->arc);
1329 1329
				JANUS_LOG(LOG_INFO, "Closed audio recording %s\n", session->arc->filename ? session->arc->filename : "??");
......
1336 1336
				janus_recorder_free(session->vrc);
1337 1337
			}
1338 1338
			session->vrc = NULL;
1339
			janus_mutex_unlock(&session->rec_mutex);
1339 1340
			if(session->recorder) {
1340 1341
				/* Create a .nfo file for this recording */
1341 1342
				char nfofile[1024], nfo[1024];
plugins/janus_sip.c
330 330
	janus_recorder *arc_peer;	/* The Janus recorder instance for the peer's audio, if enabled */
331 331
	janus_recorder *vrc;		/* The Janus recorder instance for this user's video, if enabled */
332 332
	janus_recorder *vrc_peer;	/* The Janus recorder instance for the peer's video, if enabled */
333
	janus_mutex rec_mutex;		/* Mutex to protect the recorders from race conditions */
333 334
	volatile gint hangingup;
334 335
	gint64 destroyed;	/* Time at which this session was marked as destroyed */
335 336
	janus_mutex mutex;
......
882 883
	session->media.video_pt_name = NULL;
883 884
	session->media.video_srtp_suite_in = 0;
884 885
	session->media.video_srtp_suite_out = 0;
886
	janus_mutex_init(&session->rec_mutex);
885 887
	session->destroyed = 0;
886 888
	g_atomic_int_set(&session->hangingup, 0);
887 889
	janus_mutex_init(&session->mutex);
......
1161 1163
		 session->status == janus_sip_call_status_incall))
1162 1164
		return;
1163 1165
	/* Get rid of the recorders, if available */
1164
	janus_mutex_lock(&session->mutex);
1166
	janus_mutex_lock(&session->rec_mutex);
1165 1167
	if(session->arc) {
1166 1168
		janus_recorder_close(session->arc);
1167 1169
		JANUS_LOG(LOG_INFO, "Closed user's audio recording %s\n", session->arc->filename ? session->arc->filename : "??");
......
1186 1188
		janus_recorder_free(session->vrc_peer);
1187 1189
	}
1188 1190
	session->vrc_peer = NULL;
1189
	janus_mutex_unlock(&session->mutex);
1191
	janus_mutex_unlock(&session->rec_mutex);
1190 1192
	/* FIXME Simulate a "hangup" coming from the browser */
1191 1193
	janus_sip_message *msg = g_malloc0(sizeof(janus_sip_message));
1192 1194
	msg->handle = handle;
......
1892 1894
			}
1893 1895
			json_t *recfile = json_object_get(root, "filename");
1894 1896
			const char *recording_base = json_string_value(recfile);
1895
			janus_mutex_lock(&session->mutex);
1897
			janus_mutex_lock(&session->rec_mutex);
1896 1898
			if(!strcasecmp(action_text, "start")) {
1897 1899
				/* Start recording something */
1898 1900
				char filename[255];
......
2051 2053
					session->vrc_peer = NULL;
2052 2054
				}
2053 2055
			}
2054
			janus_mutex_unlock(&session->mutex);
2056
			janus_mutex_unlock(&session->rec_mutex);
2055 2057
			/* Notify the result */
2056 2058
			result = json_object();
2057 2059
			json_object_set_new(result, "event", json_string("recordingupdated"));
plugins/janus_streaming.c
315 315
	in_addr_t video_mcast;
316 316
	janus_recorder *arc;	/* The Janus recorder instance for this streams's audio, if enabled */
317 317
	janus_recorder *vrc;	/* The Janus recorder instance for this streams's video, if enabled */
318
	janus_mutex rec_mutex;	/* Mutex to protect the recorders from race conditions */
318 319
	int audio_fd;
319 320
	int video_fd;
320 321
	gint64 last_received_video;
......
1699 1700
				g_snprintf(error_cause, 512, "Missing audio and/or video");
1700 1701
				goto error;
1701 1702
			}
1703
			janus_mutex_lock(&source->rec_mutex);
1702 1704
			if(audio && json_is_true(audio) && source->arc) {
1703 1705
				/* Close the audio recording */
1704 1706
				janus_recorder_close(source->arc);
......
1715 1717
				source->vrc = NULL;
1716 1718
				janus_recorder_free(tmp);
1717 1719
			}
1720
			janus_mutex_unlock(&source->rec_mutex);
1718 1721
			janus_mutex_unlock(&mountpoints_mutex);
1719 1722
			/* Send a success response back */
1720 1723
			response = json_object();
......
1757 1760
			mp->enabled = FALSE;
1758 1761
			/* Any recording to close? */
1759 1762
			janus_streaming_rtp_source *source = mp->source;
1763
			janus_mutex_lock(&source->rec_mutex);
1760 1764
			if(source->arc) {
1761 1765
				janus_recorder_close(source->arc);
1762 1766
				JANUS_LOG(LOG_INFO, "[%s] Closed audio recording %s\n", mp->name, source->arc->filename ? source->arc->filename : "??");
......
1771 1775
				source->vrc = NULL;
1772 1776
				janus_recorder_free(tmp);
1773 1777
			}
1778
			janus_mutex_unlock(&source->rec_mutex);
1774 1779
			/* FIXME: Should we notify the listeners, or is this up to the controller application? */
1775 1780
		}
1776 1781
		janus_mutex_unlock(&mountpoints_mutex);
......
2483 2488
	live_rtp_source->video_port = dovideo ? vport : -1;
2484 2489
	live_rtp_source->arc = NULL;
2485 2490
	live_rtp_source->vrc = NULL;
2491
	janus_mutex_init(&live_rtp_source->rec_mutex);
2486 2492
	live_rtp_source->audio_fd = audio_fd;
2487 2493
	live_rtp_source->video_fd = video_fd;
2488 2494
	live_rtp_source->last_received_audio = janus_get_monotonic_time();
......
3280 3286
						//~ ntohl(rtp->ssrc), rtp->type, ntohs(rtp->seq_number), ntohl(rtp->timestamp));
3281 3287
					packet.data->type = mountpoint->codecs.audio_pt;
3282 3288
					/* Is there a recorder? */
3283
					if(source->arc) {
3284
						JANUS_LOG(LOG_HUGE, "[%s] Saving audio frame (%d bytes)\n", name, bytes);
3285
						janus_recorder_save_frame(source->arc, buffer, bytes);
3286
					}
3289
					janus_recorder_save_frame(source->arc, buffer, bytes);
3287 3290
					/* Backup the actual timestamp and sequence number set by the restreamer, in case switching is involved */
3288 3291
					packet.timestamp = ntohl(packet.data->timestamp);
3289 3292
					packet.seq_number = ntohs(packet.data->seq_number);
......
3383 3386
						//~ ntohl(rtp->ssrc), rtp->type, ntohs(rtp->seq_number), ntohl(rtp->timestamp));
3384 3387
					packet.data->type = mountpoint->codecs.video_pt;
3385 3388
					/* Is there a recorder? */
3386
					if(source->vrc) {
3387
						JANUS_LOG(LOG_HUGE, "[%s] Saving video frame (%d bytes)\n", name, bytes);
3388
						janus_recorder_save_frame(source->vrc, buffer, bytes);
3389
					}
3389
					janus_recorder_save_frame(source->vrc, buffer, bytes);
3390 3390
					/* Backup the actual timestamp and sequence number set by the restreamer, in case switching is involved */
3391 3391
					packet.timestamp = ntohl(packet.data->timestamp);
3392 3392
					packet.seq_number = ntohs(packet.data->seq_number);
plugins/janus_videocall.c
364 364
	struct janus_videocall_session *peer;
365 365
	janus_recorder *arc;	/* The Janus recorder instance for this user's audio, if enabled */
366 366
	janus_recorder *vrc;	/* The Janus recorder instance for this user's video, if enabled */
367
	janus_mutex rec_mutex;	/* Mutex to protect the recorders from race conditions */
367 368
	volatile gint hangingup;
368 369
	gint64 destroyed;	/* Time at which this session was marked as destroyed */
369 370
} janus_videocall_session;
......
552 553
	session->bitrate = 0;	/* No limit */
553 554
	session->peer = NULL;
554 555
	session->username = NULL;
556
	janus_mutex_init(&session->rec_mutex);
555 557
	session->destroyed = 0;
556 558
	g_atomic_int_set(&session->hangingup, 0);
557 559
	handle->plugin_handle = session;
......
672 674
			return;
673 675
		if((!video && session->audio_active) || (video && session->video_active)) {
674 676
			/* Save the frame if we're recording */
675
			if(video && session->vrc)
676
				janus_recorder_save_frame(session->vrc, buf, len);
677
			else if(!video && session->arc)
678
				janus_recorder_save_frame(session->arc, buf, len);
677
			janus_recorder_save_frame(video ? session->vrc : session->arc, buf, len);
679 678
			/* Forward the packet to the peer */
680 679
			gateway->relay_rtp(session->peer->handle, video, buf, len);
681 680
		}
......
803 802
	if(g_atomic_int_add(&session->hangingup, 1))
804 803
		return;
805 804
	/* Get rid of the recorders, if available */
805
	janus_mutex_lock(&session->rec_mutex);
806 806
	if(session->arc) {
807 807
		janus_recorder_close(session->arc);
808 808
		JANUS_LOG(LOG_INFO, "Closed audio recording %s\n", session->arc->filename ? session->arc->filename : "??");
......
815 815
		janus_recorder_free(session->vrc);
816 816
	}
817 817
	session->vrc = NULL;
818
	janus_mutex_unlock(&session->rec_mutex);
818 819
	if(session->peer) {
819 820
		/* Send event to our peer too */
820 821
		json_t *call = json_object();
......
1135 1136
				gboolean recording = json_is_true(record);
1136 1137
				const char *recording_base = json_string_value(recfile);
1137 1138
				JANUS_LOG(LOG_VERB, "Recording %s (base filename: %s)\n", recording ? "enabled" : "disabled", recording_base ? recording_base : "not provided");
1139
				janus_mutex_lock(&session->rec_mutex);
1138 1140
				if(!recording) {
1139 1141
					/* Not recording (anymore?) */
1140 1142
					if(session->arc) {
......
1208 1210
						gateway->relay_rtcp(session->handle, 1, buf, 12);
1209 1211
					}
1210 1212
				}
1213
				janus_mutex_unlock(&session->rec_mutex);
1211 1214
			}
1212 1215
			/* Send an ack back */
1213 1216
			result = json_object();
plugins/janus_videoroom.c
426 426
	gchar *recording_base;	/* Base name for the recording (e.g., /path/to/filename, will generate /path/to/filename-audio.mjr and/or /path/to/filename-video.mjr */
427 427
	janus_recorder *arc;	/* The Janus recorder instance for this publisher's audio, if enabled */
428 428
	janus_recorder *vrc;	/* The Janus recorder instance for this publisher's video, if enabled */
429
	janus_mutex rec_mutex;	/* Mutex to protect the recorders from race conditions */
429 430
	GSList *listeners;
430 431
	janus_mutex listeners_mutex;
431 432
	GHashTable *rtp_forwarders;
......
1995 1996
		}
1996 1997
		janus_mutex_unlock(&participant->rtp_forwarders_mutex);
1997 1998
		/* Save the frame if we're recording */
1998
		if(video && participant->vrc)
1999
			janus_recorder_save_frame(participant->vrc, buf, len);
2000
		else if(!video && participant->arc)
2001
			janus_recorder_save_frame(participant->arc, buf, len);
1999
		janus_recorder_save_frame(video ? participant->vrc : participant->arc, buf, len);
2002 2000
		/* Done, relay it */
2003 2001
		janus_videoroom_rtp_relay_packet packet;
2004 2002
		packet.data = rtp;
......
2194 2192
	if(session->participant_type == janus_videoroom_p_type_publisher) {
2195 2193
		/* This publisher just 'unpublished' */
2196 2194
		janus_videoroom_participant *participant = (janus_videoroom_participant *)session->participant;
2197
		/* Lock listeners_mutex to protect recorders from race conditions. */
2198
		/* This mutex doesn't have an appropriate name but it is less coarse than participant->room->participants_mutex. */
2199 2195
		janus_mutex_lock(&participant->listeners_mutex);
2200 2196
		if(participant->sdp)
2201 2197
			g_free(participant->sdp);
......
2208 2204
		participant->fir_latest = 0;
2209 2205
		participant->fir_seq = 0;
2210 2206
		/* Get rid of the recorders, if available */
2207
		janus_mutex_lock(&participant->rec_mutex);
2211 2208
		if(participant->arc) {
2212 2209
			janus_recorder_close(participant->arc);
2213 2210
			JANUS_LOG(LOG_INFO, "Closed audio recording %s\n", participant->arc->filename ? participant->arc->filename : "??");
......
2220 2217
			janus_recorder_free(participant->vrc);
2221 2218
		}
2222 2219
		participant->vrc = NULL;
2220
		janus_mutex_unlock(&participant->rec_mutex);
2223 2221
		while(participant->listeners) {
2224 2222
			janus_videoroom_listener *l = (janus_videoroom_listener *)participant->listeners->data;
2225 2223
			if(l) {
......
2452 2450
				publisher->recording_base = NULL;
2453 2451
				publisher->arc = NULL;
2454 2452
				publisher->vrc = NULL;
2453
				janus_mutex_init(&publisher->rec_mutex);
2455 2454
				publisher->firefox = FALSE;
2456 2455
				publisher->bitrate = videoroom->bitrate;
2457 2456
				publisher->listeners = NULL;
......
2765 2764
				json_t *bitrate = json_object_get(root, "bitrate");
2766 2765
				json_t *record = json_object_get(root, "record");
2767 2766
				json_t *recfile = json_object_get(root, "filename");
2768
				/* Lock listeners_mutex to protect recorders from race conditions. */
2769
				janus_mutex_lock(&participant->listeners_mutex);
2770 2767
				if(audio) {
2771 2768
					participant->audio_active = json_is_true(audio);
2772 2769
					JANUS_LOG(LOG_VERB, "Setting audio property: %s (room %"SCNu64", user %"SCNu64")\n", participant->audio_active ? "true" : "false", participant->room->room_id, participant->user_id);
......
2784 2781
					janus_rtcp_remb((char *)(&rtcpbuf), 24, participant->bitrate ? participant->bitrate : 256*1024);
2785 2782
					gateway->relay_rtcp(msg->handle, 1, rtcpbuf, 24);
2786 2783
				}
2784
				janus_mutex_lock(&participant->rec_mutex);
2787 2785
				gboolean prev_recording_active = participant->recording_active;
2788 2786
				if(record) {
2789 2787
					participant->recording_active = json_is_true(record);
......
2871 2869
						}
2872 2870
					}
2873 2871
				}
2874
				janus_mutex_unlock(&participant->listeners_mutex);
2872
				janus_mutex_unlock(&participant->rec_mutex);
2875 2873
				/* Done */
2876 2874
				event = json_object();
2877 2875
				json_object_set_new(event, "videoroom", json_string("event"));

Also available in: Unified diff