Revision 78955474 plugins/janus_recordplay.c

View differences:

plugins/janus_recordplay.c
383 383
	guint video_keyframe_interval; /* keyframe request interval (ms) */
384 384
	guint64 video_keyframe_request_last; /* timestamp of last keyframe request sent */
385 385
	gint video_fir_seq;
386
	guint64 destroyed;	/* Time at which this session was marked as destroyed */
386
	gboolean hangingup;
387
	gint64 destroyed;	/* Time at which this session was marked as destroyed */
387 388
} janus_recordplay_session;
388 389
static GHashTable *sessions;
389 390
static GList *old_sessions;
......
1040 1041
		JANUS_LOG(LOG_ERR, "No session associated with this handle...\n");
1041 1042
		return;
1042 1043
	}
1043
	if(session->destroyed)
1044
		return;
1045 1044
	session->active = FALSE;
1046
	if(!session->recorder)
1045
	if(session->destroyed || !session->recorder || session->hangingup)
1047 1046
		return;
1047
	session->hangingup = TRUE;
1048 1048

  
1049 1049
	/* Send an event to the browser and tell it's over */
1050 1050
	json_t *event = json_object();
......
1065 1065
	msg->sdp_type = NULL;
1066 1066
	msg->sdp = NULL;
1067 1067
	g_async_queue_push(messages, msg);
1068
	/* Done */
1069
	session->hangingup = FALSE;
1068 1070
}
1069 1071

  
1070 1072
/* Thread to handle incoming messages */
......
1622 1624

  
1623 1625
	/* Pre-parse */
1624 1626
	JANUS_LOG(LOG_VERB, "Pre-parsing file %s to generate ordered index...\n", source);
1627
	gboolean parsed_header = FALSE;
1625 1628
	int bytes = 0;
1626 1629
	long offset = 0;
1627 1630
	uint16_t len = 0, count = 0;
......
1638 1641
			fclose(file);
1639 1642
			return NULL;
1640 1643
		}
1641
		offset += 8;
1642
		bytes = fread(&len, sizeof(uint16_t), 1, file);
1643
		len = ntohs(len);
1644
		offset += 2;
1645
		if(len == 5) {
1646
			/* This is the main header */
1647
			bytes = fread(prebuffer, sizeof(char), 5, file);
1648
			if(prebuffer[0] == 'v') {
1649
				JANUS_LOG(LOG_VERB, "This is a video recording, assuming VP8\n");
1650
			} else if(prebuffer[0] == 'a') {
1651
				JANUS_LOG(LOG_VERB, "This is an audio recording, assuming Opus\n");
1652
			} else {
1653
				JANUS_LOG(LOG_ERR, "Unsupported recording media type...\n");
1654
				fclose(file);
1655
				return NULL;
1644
		if(prebuffer[1] == 'E') {
1645
			/* Either the old .mjr format header ('MEETECHO' header followed by 'audio' or 'video'), or a frame */
1646
			offset += 8;
1647
			bytes = fread(&len, sizeof(uint16_t), 1, file);
1648
			len = ntohs(len);
1649
			offset += 2;
1650
			if(len == 5 && !parsed_header) {
1651
				/* This is the main header */
1652
				parsed_header = TRUE;
1653
				JANUS_LOG(LOG_VERB, "Old .mjr header format\n");
1654
				bytes = fread(prebuffer, sizeof(char), 5, file);
1655
				if(prebuffer[0] == 'v') {
1656
					JANUS_LOG(LOG_INFO, "This is a video recording, assuming VP8\n");
1657
				} else if(prebuffer[0] == 'a') {
1658
					JANUS_LOG(LOG_INFO, "This is an audio recording, assuming Opus\n");
1659
				} else {
1660
					JANUS_LOG(LOG_WARN, "Unsupported recording media type...\n");
1661
					fclose(file);
1662
					return NULL;
1663
				}
1664
				offset += len;
1665
				continue;
1666
			} else if(len < 12) {
1667
				/* Not RTP, skip */
1668
				JANUS_LOG(LOG_VERB, "Skipping packet (not RTP?)\n");
1669
				offset += len;
1670
				continue;
1656 1671
			}
1657
			offset += len;
1658
			continue;
1659
		} else if(len < 12) {
1660
			/* Not RTP, skip */
1661
			JANUS_LOG(LOG_VERB, "Skipping packet (not RTP?)\n");
1662
			offset += len;
1663
			continue;
1672
		} else if(prebuffer[1] == 'J') {
1673
			/* New .mjr format, the header may contain useful info */
1674
			offset += 8;
1675
			bytes = fread(&len, sizeof(uint16_t), 1, file);
1676
			len = ntohs(len);
1677
			offset += 2;
1678
			if(len > 0 && !parsed_header) {
1679
				/* This is the info header */
1680
				JANUS_LOG(LOG_VERB, "New .mjr header format\n");
1681
				bytes = fread(prebuffer, sizeof(char), len, file);
1682
				parsed_header = TRUE;
1683
				prebuffer[len] = '\0';
1684
				json_error_t error;
1685
				json_t *info = json_loads(prebuffer, 0, &error);
1686
				if(!info) {
1687
					JANUS_LOG(LOG_ERR, "JSON error: on line %d: %s\n", error.line, error.text);
1688
					JANUS_LOG(LOG_WARN, "Error parsing info header...\n");
1689
					fclose(file);
1690
					return NULL;
1691
				}
1692
				/* Is it audio or video? */
1693
				json_t *type = json_object_get(info, "t");
1694
				if(!type || !json_is_string(type)) {
1695
					JANUS_LOG(LOG_WARN, "Missing/invalid recording type in info header...\n");
1696
					fclose(file);
1697
					return NULL;
1698
				}
1699
				const char *t = json_string_value(type);
1700
				int video = 0;
1701
				gint64 c_time = 0, w_time = 0;
1702
				if(!strcasecmp(t, "v")) {
1703
					video = 1;
1704
				} else if(!strcasecmp(t, "a")) {
1705
					video = 0;
1706
				} else {
1707
					JANUS_LOG(LOG_WARN, "Unsupported recording type '%s' in info header...\n", t);
1708
					fclose(file);
1709
					return NULL;
1710
				}
1711
				/* What codec was used? */
1712
				json_t *codec = json_object_get(info, "c");
1713
				if(!codec || !json_is_string(codec)) {
1714
					JANUS_LOG(LOG_WARN, "Missing recording codec in info header...\n");
1715
					fclose(file);
1716
					return NULL;
1717
				}
1718
				const char *c = json_string_value(codec);
1719
				if(video && strcasecmp(c, "vp8")) {
1720
					JANUS_LOG(LOG_WARN, "The post-processor only suupports VP8 video for now (was '%s')...\n", c);
1721
					fclose(file);
1722
					return NULL;
1723
				} else if(!video && strcasecmp(c, "opus")) {
1724
					JANUS_LOG(LOG_WARN, "The post-processor only suupports Opus audio for now (was '%s')...\n", c);
1725
					fclose(file);
1726
					return NULL;
1727
				}
1728
				/* When was the file created? */
1729
				json_t *created = json_object_get(info, "s");
1730
				if(!created || !json_is_integer(created)) {
1731
					JANUS_LOG(LOG_WARN, "Missing recording created time in info header...\n");
1732
					fclose(file);
1733
					return NULL;
1734
				}
1735
				c_time = json_integer_value(created);
1736
				/* When was the first frame written? */
1737
				json_t *written = json_object_get(info, "u");
1738
				if(!written || !json_is_integer(written)) {
1739
					JANUS_LOG(LOG_WARN, "Missing recording written time in info header...\n");
1740
					fclose(file);
1741
					return NULL;
1742
				}
1743
				w_time = json_integer_value(created);
1744
				/* Summary */
1745
				JANUS_LOG(LOG_VERB, "This is %s recording:\n", video ? "a video" : "an audio");
1746
				JANUS_LOG(LOG_VERB, "  -- Codec:   %s\n", c);
1747
				JANUS_LOG(LOG_VERB, "  -- Created: %"SCNi64"\n", c_time);
1748
				JANUS_LOG(LOG_VERB, "  -- Written: %"SCNi64"\n", w_time);
1749
			}
1750
		} else {
1751
			JANUS_LOG(LOG_ERR, "Invalid header...\n");
1752
			fclose(file);
1753
			return NULL;
1664 1754
		}
1665 1755
		/* Only read RTP header */
1666 1756
		bytes = fread(prebuffer, sizeof(char), 16, file);
......
1699 1789
		len = ntohs(len);
1700 1790
		JANUS_LOG(LOG_HUGE, "  -- Length: %"SCNu16"\n", len);
1701 1791
		offset += 2;
1702
		if(len < 12) {
1792
		if(prebuffer[1] == 'J' || len < 12) {
1703 1793
			/* Not RTP, skip */
1704 1794
			JANUS_LOG(LOG_HUGE, "  -- Not RTP, skipping\n");
1705 1795
			offset += len;

Also available in: Unified diff