static GstBuffer * gst_dtmf_src_create_next_tone_packet (GstDTMFSrc * dtmfsrc, GstDTMFSrcEvent * event) { GstBuffer *buf = NULL; gboolean send_silence = FALSE; GstPad *srcpad = GST_BASE_SRC_PAD (dtmfsrc); GST_LOG_OBJECT (dtmfsrc, "Creating buffer for tone %s", DTMF_KEYS[event->event_number].event_name); /* create buffer to hold the tone */ buf = gst_buffer_new (); if (event->packet_count * dtmfsrc->interval < MIN_INTER_DIGIT_INTERVAL) { send_silence = TRUE; } if (send_silence) { GST_LOG_OBJECT (dtmfsrc, "Generating silence"); gst_dtmf_src_generate_silence (buf, dtmfsrc->interval, dtmfsrc->sample_rate); } else { GST_LOG_OBJECT (dtmfsrc, "Generating tone"); gst_dtmf_src_generate_tone (event, DTMF_KEYS[event->event_number], dtmfsrc->interval, buf, dtmfsrc->sample_rate); } event->packet_count++; /* timestamp and duration of GstBuffer */ GST_BUFFER_DURATION (buf) = dtmfsrc->interval * GST_MSECOND; GST_BUFFER_TIMESTAMP (buf) = dtmfsrc->timestamp; dtmfsrc->timestamp += GST_BUFFER_DURATION (buf); /* Set caps on the buffer before pushing it */ gst_buffer_set_caps (buf, GST_PAD_CAPS (srcpad)); return buf; }
static GstBuffer * gst_dtmf_src_create_next_tone_packet (GstDTMFSrc * dtmfsrc, GstDTMFSrcEvent * event) { GstBuffer *buf = NULL; gboolean send_silence = FALSE; GST_LOG_OBJECT (dtmfsrc, "Creating buffer for tone %s", DTMF_KEYS[event->event_number].event_name); if (event->packet_count * dtmfsrc->interval < MIN_INTER_DIGIT_INTERVAL) { send_silence = TRUE; } if (send_silence) { GST_LOG_OBJECT (dtmfsrc, "Generating silence"); buf = gst_dtmf_src_generate_silence (dtmfsrc->interval, dtmfsrc->sample_rate); } else { GST_LOG_OBJECT (dtmfsrc, "Generating tone"); buf = gst_dtmf_src_generate_tone (event, DTMF_KEYS[event->event_number], dtmfsrc->interval, dtmfsrc->sample_rate); } event->packet_count++; /* timestamp and duration of GstBuffer */ GST_BUFFER_DURATION (buf) = dtmfsrc->interval * GST_MSECOND; GST_BUFFER_TIMESTAMP (buf) = dtmfsrc->timestamp; GST_LOG_OBJECT (dtmfsrc, "Creating new buffer with event %u duration " " gst: %" GST_TIME_FORMAT " at %" GST_TIME_FORMAT, event->event_number, GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); dtmfsrc->timestamp += GST_BUFFER_DURATION (buf); return buf; }
static GstBuffer * gst_rtp_dtmf_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf) { GstRtpDTMFDepay *rtpdtmfdepay = NULL; GstBuffer *outbuf = NULL; gint payload_len; guint8 *payload = NULL; guint32 timestamp; GstRTPDTMFPayload dtmf_payload; gboolean marker; GstStructure *structure = NULL; GstMessage *dtmf_message = NULL; rtpdtmfdepay = GST_RTP_DTMF_DEPAY (depayload); if (!gst_rtp_buffer_validate (buf)) goto bad_packet; payload_len = gst_rtp_buffer_get_payload_len (buf); payload = gst_rtp_buffer_get_payload (buf); if (payload_len != sizeof (GstRTPDTMFPayload)) goto bad_packet; memcpy (&dtmf_payload, payload, sizeof (GstRTPDTMFPayload)); if (dtmf_payload.event > MAX_EVENT) goto bad_packet; marker = gst_rtp_buffer_get_marker (buf); timestamp = gst_rtp_buffer_get_timestamp (buf); dtmf_payload.duration = g_ntohs (dtmf_payload.duration); /* clip to whole units of unit_time */ if (rtpdtmfdepay->unit_time) { guint unit_time_clock = (rtpdtmfdepay->unit_time * depayload->clock_rate) / 1000; if (dtmf_payload.duration % unit_time_clock) { /* Make sure we don't overflow the duration */ if (dtmf_payload.duration < G_MAXUINT16 - unit_time_clock) dtmf_payload.duration += unit_time_clock - (dtmf_payload.duration % unit_time_clock); else dtmf_payload.duration -= dtmf_payload.duration % unit_time_clock; } } /* clip to max duration */ if (rtpdtmfdepay->max_duration) { guint max_duration_clock = (rtpdtmfdepay->max_duration * depayload->clock_rate) / 1000; if (max_duration_clock < G_MAXUINT16 && dtmf_payload.duration > max_duration_clock) dtmf_payload.duration = max_duration_clock; } GST_DEBUG_OBJECT (depayload, "Received new RTP DTMF packet : " "marker=%d - timestamp=%u - event=%d - duration=%d", marker, timestamp, dtmf_payload.event, dtmf_payload.duration); GST_DEBUG_OBJECT (depayload, "Previous information : timestamp=%u - duration=%d", rtpdtmfdepay->previous_ts, rtpdtmfdepay->previous_duration); /* First packet */ if (marker || rtpdtmfdepay->previous_ts != timestamp) { rtpdtmfdepay->sample = 0; rtpdtmfdepay->previous_ts = timestamp; rtpdtmfdepay->previous_duration = dtmf_payload.duration; rtpdtmfdepay->first_gst_ts = GST_BUFFER_TIMESTAMP (buf); structure = gst_structure_new ("dtmf-event", "number", G_TYPE_INT, dtmf_payload.event, "volume", G_TYPE_INT, dtmf_payload.volume, "type", G_TYPE_INT, 1, "method", G_TYPE_INT, 1, NULL); if (structure) { dtmf_message = gst_message_new_element (GST_OBJECT (depayload), structure); if (dtmf_message) { if (!gst_element_post_message (GST_ELEMENT (depayload), dtmf_message)) { GST_ERROR_OBJECT (depayload, "Unable to send dtmf-event message to bus"); } } else { GST_ERROR_OBJECT (depayload, "Unable to create dtmf-event message"); } } else { GST_ERROR_OBJECT (depayload, "Unable to create dtmf-event structure"); } } else { guint16 duration = dtmf_payload.duration; dtmf_payload.duration -= rtpdtmfdepay->previous_duration; /* If late buffer, ignore */ if (duration > rtpdtmfdepay->previous_duration) rtpdtmfdepay->previous_duration = duration; } GST_DEBUG_OBJECT (depayload, "new previous duration : %d - new duration : %d" " - diff : %d - clock rate : %d - timestamp : %llu", rtpdtmfdepay->previous_duration, dtmf_payload.duration, (rtpdtmfdepay->previous_duration - dtmf_payload.duration), depayload->clock_rate, GST_BUFFER_TIMESTAMP (buf)); /* If late or duplicate packet (like the redundant end packet). Ignore */ if (dtmf_payload.duration > 0) { outbuf = gst_buffer_new (); gst_dtmf_src_generate_tone (rtpdtmfdepay, dtmf_payload, outbuf); GST_BUFFER_TIMESTAMP (outbuf) = rtpdtmfdepay->first_gst_ts + (rtpdtmfdepay->previous_duration - dtmf_payload.duration) * GST_SECOND / depayload->clock_rate; GST_BUFFER_OFFSET (outbuf) = (rtpdtmfdepay->previous_duration - dtmf_payload.duration) * GST_SECOND / depayload->clock_rate; GST_BUFFER_OFFSET_END (outbuf) = rtpdtmfdepay->previous_duration * GST_SECOND / depayload->clock_rate; GST_DEBUG_OBJECT (depayload, "timestamp : %llu - time %" GST_TIME_FORMAT, GST_BUFFER_TIMESTAMP (buf), GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf))); } return outbuf; bad_packet: GST_ELEMENT_WARNING (rtpdtmfdepay, STREAM, DECODE, ("Packet did not validate"), (NULL)); return NULL; }