summaryrefslogtreecommitdiffstats
path: root/gst/rtpdtmf
diff options
context:
space:
mode:
Diffstat (limited to 'gst/rtpdtmf')
-rw-r--r--gst/rtpdtmf/gstrtpdtmfsrc.c246
1 files changed, 146 insertions, 100 deletions
diff --git a/gst/rtpdtmf/gstrtpdtmfsrc.c b/gst/rtpdtmf/gstrtpdtmfsrc.c
index 72b4e1af..cecacb9b 100644
--- a/gst/rtpdtmf/gstrtpdtmfsrc.c
+++ b/gst/rtpdtmf/gstrtpdtmfsrc.c
@@ -316,6 +316,61 @@ gst_rtp_dtmf_src_finalize (GObject * object)
}
static gboolean
+gst_rtp_dtmf_src_handle_dtmf_event (GstRTPDTMFSrc *dtmfsrc,
+ const GstStructure * event_structure)
+{
+ gint event_type;
+ gboolean start;
+
+ if (!gst_structure_get_int (event_structure, "type", &event_type) ||
+ !gst_structure_get_boolean (event_structure, "start", &start) ||
+ event_type != GST_RTP_DTMF_TYPE_EVENT)
+ goto failure;
+
+ if (start) {
+ gint event_number;
+ gint event_volume;
+
+ if (!gst_structure_get_int (event_structure, "number", &event_number) ||
+ !gst_structure_get_int (event_structure, "volume", &event_volume))
+ goto failure;
+
+ GST_DEBUG_OBJECT (dtmfsrc, "Received start event %d with volume %d",
+ event_number, event_volume);
+ gst_rtp_dtmf_src_start (dtmfsrc, event_number, event_volume);
+ }
+
+ else {
+ GST_DEBUG_OBJECT (dtmfsrc, "Received stop event");
+ gst_rtp_dtmf_src_stop (dtmfsrc);
+ }
+
+ return TRUE;
+failure:
+ return FALSE;
+}
+
+static gboolean
+gst_rtp_dtmf_src_handle_custom_upstream (GstRTPDTMFSrc *dtmfsrc, GstEvent * event)
+{
+ gboolean result = FALSE;
+ const GstStructure *structure;
+
+ if (GST_STATE (dtmfsrc) != GST_STATE_PLAYING) {
+ GST_DEBUG_OBJECT (dtmfsrc, "Received event while not in PLAYING state");
+ goto ret;
+ }
+
+ GST_DEBUG_OBJECT (dtmfsrc, "Received event is of our interest");
+ structure = gst_event_get_structure (event);
+ if (structure && gst_structure_has_name (structure, "dtmf-event"))
+ result = gst_rtp_dtmf_src_handle_dtmf_event (dtmfsrc, structure);
+
+ret:
+ return result;
+}
+
+static gboolean
gst_rtp_dtmf_src_handle_event (GstPad * pad, GstEvent * event)
{
GstRTPDTMFSrc *dtmfsrc;
@@ -327,44 +382,7 @@ gst_rtp_dtmf_src_handle_event (GstPad * pad, GstEvent * event)
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_CUSTOM_UPSTREAM:
{
- const GstStructure *structure;
-
- if (GST_STATE (dtmfsrc) != GST_STATE_PLAYING) {
- GST_DEBUG_OBJECT (dtmfsrc, "Received event while not in PLAYING state");
- break;
- }
-
- GST_DEBUG_OBJECT (dtmfsrc, "Received event is of our interest");
- structure = gst_event_get_structure (event);
- if (structure && gst_structure_has_name (structure, "dtmf-event")) {
- gint event_type;
- gboolean start;
-
- if (!gst_structure_get_int (structure, "type", &event_type) ||
- !gst_structure_get_boolean (structure, "start", &start) ||
- event_type != GST_RTP_DTMF_TYPE_EVENT)
- break;
-
- if (start) {
- gint event_number;
- gint event_volume;
-
- if (!gst_structure_get_int (structure, "number", &event_number) ||
- !gst_structure_get_int (structure, "volume", &event_volume))
- break;
-
- GST_DEBUG_OBJECT (dtmfsrc, "Received start event %d with volume %d",
- event_number, event_volume);
- gst_rtp_dtmf_src_start (dtmfsrc, event_number, event_volume);
- }
-
- else {
- GST_DEBUG_OBJECT (dtmfsrc, "Received stop event");
- gst_rtp_dtmf_src_stop (dtmfsrc);
- }
- }
-
- result = TRUE;
+ result = gst_rtp_dtmf_src_handle_custom_upstream (dtmfsrc, event);
break;
}
/* Ideally this element should not be flushed but let's handle the event
@@ -464,18 +482,10 @@ gst_rtp_dtmf_src_set_stream_lock (GstRTPDTMFSrc *dtmfsrc, gboolean lock)
}
static void
-gst_rtp_dtmf_src_start (GstRTPDTMFSrc *dtmfsrc,
- gint event_number, gint event_volume)
+gst_rtp_dtmf_prepare_timestamps (GstRTPDTMFSrc *dtmfsrc)
{
GstClock *clock;
- g_return_if_fail (dtmfsrc->payload == NULL);
-
- dtmfsrc->payload = g_new0 (GstRTPDTMFPayload, 1);
- dtmfsrc->payload->event = CLAMP (event_number, MIN_EVENT, MAX_EVENT);
- dtmfsrc->payload->volume = CLAMP (event_volume, MIN_VOLUME, MAX_VOLUME);
- dtmfsrc->first_packet = TRUE;
-
clock = GST_ELEMENT_CLOCK (dtmfsrc);
if (clock != NULL)
dtmfsrc->timestamp = gst_clock_get_time (GST_ELEMENT_CLOCK (dtmfsrc));
@@ -489,8 +499,20 @@ gst_rtp_dtmf_src_start (GstRTPDTMFSrc *dtmfsrc,
gst_util_uint64_scale_int (
dtmfsrc->timestamp - gst_element_get_base_time (GST_ELEMENT (dtmfsrc)),
dtmfsrc->clock_rate, GST_SECOND);
-
+}
+static void
+gst_rtp_dtmf_src_start (GstRTPDTMFSrc *dtmfsrc,
+ gint event_number, gint event_volume)
+{
+ g_return_if_fail (dtmfsrc->payload == NULL);
+
+ dtmfsrc->payload = g_new0 (GstRTPDTMFPayload, 1);
+ dtmfsrc->payload->event = CLAMP (event_number, MIN_EVENT, MAX_EVENT);
+ dtmfsrc->payload->volume = CLAMP (event_volume, MIN_VOLUME, MAX_VOLUME);
+ dtmfsrc->first_packet = TRUE;
+
+ gst_rtp_dtmf_prepare_timestamps (dtmfsrc);
gst_rtp_dtmf_src_set_caps (dtmfsrc);
/* Don't forget to get exclusive access to the stream */
@@ -524,16 +546,32 @@ gst_rtp_dtmf_src_stop (GstRTPDTMFSrc *dtmfsrc)
}
static void
-gst_rtp_dtmf_src_push_next_rtp_packet (GstRTPDTMFSrc *dtmfsrc)
+gst_rtp_dtmf_src_wait_for_buffer_ts (GstRTPDTMFSrc *dtmfsrc, GstBuffer * buf)
{
- GstBuffer *buf = NULL;
- GstFlowReturn ret;
- GstRTPDTMFPayload *payload;
- GstClock * clock;
+ GstClock *clock;
+
+ clock = GST_ELEMENT_CLOCK (dtmfsrc);
+ if (clock != NULL) {
+ GstClockID clock_id;
+ GstClockReturn clock_ret;
- /* create buffer to hold the payload */
- buf = gst_rtp_buffer_new_allocate (sizeof (GstRTPDTMFPayload), 0, 0);
+ clock_id = gst_clock_new_single_shot_id (clock, dtmfsrc->timestamp);
+ clock_ret = gst_clock_id_wait (clock_id, NULL);
+ if (clock_ret != GST_CLOCK_OK && clock_ret != GST_CLOCK_EARLY) {
+ GST_ERROR_OBJECT (dtmfsrc, "Failed to wait on clock %s",
+ GST_ELEMENT_NAME (clock));
+ }
+ gst_clock_id_unref (clock_id);
+ }
+ else {
+ GST_ERROR_OBJECT (dtmfsrc, "No clock set for element %s", GST_ELEMENT_NAME (dtmfsrc));
+ }
+}
+
+static void
+gst_rtp_dtmf_prepare_rtp_headers (GstRTPDTMFSrc *dtmfsrc, GstBuffer *buf)
+{
gst_rtp_buffer_set_ssrc (buf, dtmfsrc->current_ssrc);
gst_rtp_buffer_set_payload_type (buf, dtmfsrc->pt);
if (dtmfsrc->first_packet) {
@@ -547,12 +585,19 @@ gst_rtp_dtmf_src_push_next_rtp_packet (GstRTPDTMFSrc *dtmfsrc)
gst_rtp_buffer_set_timestamp (buf, dtmfsrc->rtp_timestamp);
dtmfsrc->rtp_timestamp +=
DEFAULT_PACKET_INTERVAL * dtmfsrc->clock_rate / 1000;
+}
+static void
+gst_rtp_dtmf_prepare_buffer_data (GstRTPDTMFSrc *dtmfsrc, GstBuffer *buf)
+{
+ GstRTPDTMFPayload *payload;
+
+ gst_rtp_dtmf_prepare_rtp_headers (dtmfsrc, buf);
/* duration of DTMF payload */
dtmfsrc->payload->duration +=
DEFAULT_PACKET_INTERVAL * dtmfsrc->clock_rate / 1000;
-
+
/* timestamp and duration of GstBuffer */
GST_BUFFER_DURATION (buf) = DEFAULT_PACKET_INTERVAL * GST_MSECOND;
GST_BUFFER_TIMESTAMP (buf) = dtmfsrc->timestamp;
@@ -563,28 +608,36 @@ gst_rtp_dtmf_src_push_next_rtp_packet (GstRTPDTMFSrc *dtmfsrc)
/* copy payload and convert to network-byte order */
g_memmove (payload, dtmfsrc->payload, sizeof (GstRTPDTMFPayload));
payload->duration = g_htons (payload->duration);
+}
- /* FIXME: Should we sync to clock ourselves or leave it to sink */
- clock = GST_ELEMENT_CLOCK (dtmfsrc);
- if (clock != NULL) {
- GstClockID clock_id;
- GstClockReturn clock_ret;
+static GstBuffer *
+gst_rtp_dtmf_src_create_next_rtp_packet (GstRTPDTMFSrc *dtmfsrc)
+{
+ GstBuffer *buf = NULL;
+
+ /* create buffer to hold the payload */
+ buf = gst_rtp_buffer_new_allocate (sizeof (GstRTPDTMFPayload), 0, 0);
- clock_id = gst_clock_new_single_shot_id (clock, dtmfsrc->timestamp);
- clock_ret = gst_clock_id_wait (clock_id, NULL);
- if (clock_ret != GST_CLOCK_OK && clock_ret != GST_CLOCK_EARLY) {
- GST_ERROR_OBJECT (dtmfsrc, "Failed to wait on clock %s",
- GST_ELEMENT_NAME (clock));
- }
- gst_clock_id_unref (clock_id);
- }
+ gst_rtp_dtmf_prepare_buffer_data (dtmfsrc, buf);
- else {
- GST_ERROR_OBJECT (dtmfsrc, "No clock set for element %s", GST_ELEMENT_NAME (dtmfsrc));
- }
+ /* FIXME: Should we sync to clock ourselves or leave it to sink */
+ gst_rtp_dtmf_src_wait_for_buffer_ts (dtmfsrc, buf);
/* Set caps on the buffer before pushing it */
gst_buffer_set_caps (buf, GST_PAD_CAPS (dtmfsrc->srcpad));
+
+ return buf;
+}
+
+static void
+gst_rtp_dtmf_src_push_next_rtp_packet (GstRTPDTMFSrc *dtmfsrc)
+{
+ GstBuffer *buf = NULL;
+ GstFlowReturn ret;
+
+ /* create buffer to hold the payload */
+ buf = gst_rtp_dtmf_src_create_next_rtp_packet (dtmfsrc);
+
GST_DEBUG_OBJECT (dtmfsrc,
"pushing buffer on src pad of size %d", GST_BUFFER_SIZE (buf));
ret = gst_pad_push (dtmfsrc->srcpad, buf);
@@ -620,6 +673,26 @@ gst_rtp_dtmf_src_set_caps (GstRTPDTMFSrc *dtmfsrc)
gst_caps_unref (caps);
}
+static void
+gst_rtp_dtmf_src_ready_to_paused (GstRTPDTMFSrc *dtmfsrc)
+{
+ if (dtmfsrc->ssrc == -1)
+ dtmfsrc->current_ssrc = g_random_int ();
+ else
+ dtmfsrc->current_ssrc = dtmfsrc->ssrc;
+
+ if (dtmfsrc->seqnum_offset == -1)
+ dtmfsrc->seqnum_base = g_random_int_range (0, G_MAXUINT16);
+ else
+ dtmfsrc->seqnum_base = dtmfsrc->seqnum_offset;
+ dtmfsrc->seqnum = dtmfsrc->seqnum_base;
+
+ if (dtmfsrc->ts_offset == -1)
+ dtmfsrc->ts_base = g_random_int ();
+ else
+ dtmfsrc->ts_base = dtmfsrc->ts_offset;
+}
+
static GstStateChangeReturn
gst_rtp_dtmf_src_change_state (GstElement * element, GstStateChange transition)
{
@@ -630,33 +703,10 @@ gst_rtp_dtmf_src_change_state (GstElement * element, GstStateChange transition)
dtmfsrc = GST_RTP_DTMF_SRC (element);
switch (transition) {
- case GST_STATE_CHANGE_NULL_TO_READY:
- break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
-
- if (dtmfsrc->ssrc == -1)
- dtmfsrc->current_ssrc = g_random_int ();
- else
- dtmfsrc->current_ssrc = dtmfsrc->ssrc;
-
- if (dtmfsrc->seqnum_offset == -1)
- dtmfsrc->seqnum_base = g_random_int_range (0, G_MAXUINT16);
- else
- dtmfsrc->seqnum_base = dtmfsrc->seqnum_offset;
- dtmfsrc->seqnum = dtmfsrc->seqnum_base;
-
- if (dtmfsrc->ts_offset == -1)
- dtmfsrc->ts_base = g_random_int ();
- else
- dtmfsrc->ts_base = dtmfsrc->ts_offset;
-
-
-
+ gst_rtp_dtmf_src_ready_to_paused (dtmfsrc);
/* Indicate that we don't do PRE_ROLL */
no_preroll = TRUE;
-
- break;
- case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
break;
default:
break;
@@ -672,10 +722,6 @@ gst_rtp_dtmf_src_change_state (GstElement * element, GstStateChange transition)
/* Indicate that we don't do PRE_ROLL */
no_preroll = TRUE;
break;
- case GST_STATE_CHANGE_PAUSED_TO_READY:
- break;
- case GST_STATE_CHANGE_READY_TO_NULL:
- break;
default:
break;
}