mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-26 02:00:33 +00:00
[MOVED FROM GST-P-FARSIGHT] Clean-up and refactorize dtmfsrc code
20070402124635-65035-3d13244461c1dd1fcc96b74124ad7a74d2ff0144.gz
This commit is contained in:
parent
f7d6d695aa
commit
50dbdcc4e1
1 changed files with 161 additions and 115 deletions
|
@ -315,6 +315,61 @@ gst_rtp_dtmf_src_finalize (GObject * object)
|
||||||
G_OBJECT_CLASS (parent_class)->finalize (object);
|
G_OBJECT_CLASS (parent_class)->finalize (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
|
static gboolean
|
||||||
gst_rtp_dtmf_src_handle_event (GstPad * pad, GstEvent * event)
|
gst_rtp_dtmf_src_handle_event (GstPad * pad, GstEvent * event)
|
||||||
{
|
{
|
||||||
|
@ -327,44 +382,7 @@ gst_rtp_dtmf_src_handle_event (GstPad * pad, GstEvent * event)
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_CUSTOM_UPSTREAM:
|
case GST_EVENT_CUSTOM_UPSTREAM:
|
||||||
{
|
{
|
||||||
const GstStructure *structure;
|
result = gst_rtp_dtmf_src_handle_custom_upstream (dtmfsrc, event);
|
||||||
|
|
||||||
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;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* Ideally this element should not be flushed but let's handle the event
|
/* 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
|
static void
|
||||||
gst_rtp_dtmf_src_start (GstRTPDTMFSrc *dtmfsrc,
|
gst_rtp_dtmf_prepare_timestamps (GstRTPDTMFSrc *dtmfsrc)
|
||||||
gint event_number, gint event_volume)
|
|
||||||
{
|
{
|
||||||
GstClock *clock;
|
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);
|
clock = GST_ELEMENT_CLOCK (dtmfsrc);
|
||||||
if (clock != NULL)
|
if (clock != NULL)
|
||||||
dtmfsrc->timestamp = gst_clock_get_time (GST_ELEMENT_CLOCK (dtmfsrc));
|
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 (
|
gst_util_uint64_scale_int (
|
||||||
dtmfsrc->timestamp - gst_element_get_base_time (GST_ELEMENT (dtmfsrc)),
|
dtmfsrc->timestamp - gst_element_get_base_time (GST_ELEMENT (dtmfsrc)),
|
||||||
dtmfsrc->clock_rate, GST_SECOND);
|
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);
|
gst_rtp_dtmf_src_set_caps (dtmfsrc);
|
||||||
|
|
||||||
/* Don't forget to get exclusive access to the stream */
|
/* Don't forget to get exclusive access to the stream */
|
||||||
|
@ -524,47 +546,10 @@ gst_rtp_dtmf_src_stop (GstRTPDTMFSrc *dtmfsrc)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
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;
|
GstClock *clock;
|
||||||
GstFlowReturn ret;
|
|
||||||
GstRTPDTMFPayload *payload;
|
|
||||||
GstClock * clock;
|
|
||||||
|
|
||||||
/* create buffer to hold the payload */
|
|
||||||
buf = gst_rtp_buffer_new_allocate (sizeof (GstRTPDTMFPayload), 0, 0);
|
|
||||||
|
|
||||||
gst_rtp_buffer_set_ssrc (buf, dtmfsrc->current_ssrc);
|
|
||||||
gst_rtp_buffer_set_payload_type (buf, dtmfsrc->pt);
|
|
||||||
if (dtmfsrc->first_packet) {
|
|
||||||
gst_rtp_buffer_set_marker (buf, TRUE);
|
|
||||||
dtmfsrc->first_packet = FALSE;
|
|
||||||
}
|
|
||||||
dtmfsrc->seqnum++;
|
|
||||||
gst_rtp_buffer_set_seq (buf, dtmfsrc->seqnum);
|
|
||||||
|
|
||||||
/* timestamp of RTP header */
|
|
||||||
gst_rtp_buffer_set_timestamp (buf, dtmfsrc->rtp_timestamp);
|
|
||||||
dtmfsrc->rtp_timestamp +=
|
|
||||||
DEFAULT_PACKET_INTERVAL * dtmfsrc->clock_rate / 1000;
|
|
||||||
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
dtmfsrc->timestamp += GST_BUFFER_DURATION (buf);
|
|
||||||
|
|
||||||
payload = (GstRTPDTMFPayload *) gst_rtp_buffer_get_payload (buf);
|
|
||||||
|
|
||||||
/* 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);
|
clock = GST_ELEMENT_CLOCK (dtmfsrc);
|
||||||
if (clock != NULL) {
|
if (clock != NULL) {
|
||||||
GstClockID clock_id;
|
GstClockID clock_id;
|
||||||
|
@ -582,9 +567,77 @@ gst_rtp_dtmf_src_push_next_rtp_packet (GstRTPDTMFSrc *dtmfsrc)
|
||||||
else {
|
else {
|
||||||
GST_ERROR_OBJECT (dtmfsrc, "No clock set for element %s", GST_ELEMENT_NAME (dtmfsrc));
|
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) {
|
||||||
|
gst_rtp_buffer_set_marker (buf, TRUE);
|
||||||
|
dtmfsrc->first_packet = FALSE;
|
||||||
|
}
|
||||||
|
dtmfsrc->seqnum++;
|
||||||
|
gst_rtp_buffer_set_seq (buf, dtmfsrc->seqnum);
|
||||||
|
|
||||||
|
/* timestamp of RTP header */
|
||||||
|
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;
|
||||||
|
dtmfsrc->timestamp += GST_BUFFER_DURATION (buf);
|
||||||
|
|
||||||
|
payload = (GstRTPDTMFPayload *) gst_rtp_buffer_get_payload (buf);
|
||||||
|
|
||||||
|
/* copy payload and convert to network-byte order */
|
||||||
|
g_memmove (payload, dtmfsrc->payload, sizeof (GstRTPDTMFPayload));
|
||||||
|
payload->duration = g_htons (payload->duration);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
gst_rtp_dtmf_prepare_buffer_data (dtmfsrc, buf);
|
||||||
|
|
||||||
|
/* 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 */
|
/* Set caps on the buffer before pushing it */
|
||||||
gst_buffer_set_caps (buf, GST_PAD_CAPS (dtmfsrc->srcpad));
|
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,
|
GST_DEBUG_OBJECT (dtmfsrc,
|
||||||
"pushing buffer on src pad of size %d", GST_BUFFER_SIZE (buf));
|
"pushing buffer on src pad of size %d", GST_BUFFER_SIZE (buf));
|
||||||
ret = gst_pad_push (dtmfsrc->srcpad, buf);
|
ret = gst_pad_push (dtmfsrc->srcpad, buf);
|
||||||
|
@ -620,20 +673,9 @@ gst_rtp_dtmf_src_set_caps (GstRTPDTMFSrc *dtmfsrc)
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstStateChangeReturn
|
static void
|
||||||
gst_rtp_dtmf_src_change_state (GstElement * element, GstStateChange transition)
|
gst_rtp_dtmf_src_ready_to_paused (GstRTPDTMFSrc *dtmfsrc)
|
||||||
{
|
{
|
||||||
GstRTPDTMFSrc *dtmfsrc;
|
|
||||||
GstStateChangeReturn result;
|
|
||||||
gboolean no_preroll = FALSE;
|
|
||||||
|
|
||||||
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)
|
if (dtmfsrc->ssrc == -1)
|
||||||
dtmfsrc->current_ssrc = g_random_int ();
|
dtmfsrc->current_ssrc = g_random_int ();
|
||||||
else
|
else
|
||||||
|
@ -649,14 +691,22 @@ gst_rtp_dtmf_src_change_state (GstElement * element, GstStateChange transition)
|
||||||
dtmfsrc->ts_base = g_random_int ();
|
dtmfsrc->ts_base = g_random_int ();
|
||||||
else
|
else
|
||||||
dtmfsrc->ts_base = dtmfsrc->ts_offset;
|
dtmfsrc->ts_base = dtmfsrc->ts_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstStateChangeReturn
|
||||||
|
gst_rtp_dtmf_src_change_state (GstElement * element, GstStateChange transition)
|
||||||
|
{
|
||||||
|
GstRTPDTMFSrc *dtmfsrc;
|
||||||
|
GstStateChangeReturn result;
|
||||||
|
gboolean no_preroll = FALSE;
|
||||||
|
|
||||||
|
dtmfsrc = GST_RTP_DTMF_SRC (element);
|
||||||
|
|
||||||
|
switch (transition) {
|
||||||
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||||
|
gst_rtp_dtmf_src_ready_to_paused (dtmfsrc);
|
||||||
/* Indicate that we don't do PRE_ROLL */
|
/* Indicate that we don't do PRE_ROLL */
|
||||||
no_preroll = TRUE;
|
no_preroll = TRUE;
|
||||||
|
|
||||||
break;
|
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -672,10 +722,6 @@ gst_rtp_dtmf_src_change_state (GstElement * element, GstStateChange transition)
|
||||||
/* Indicate that we don't do PRE_ROLL */
|
/* Indicate that we don't do PRE_ROLL */
|
||||||
no_preroll = TRUE;
|
no_preroll = TRUE;
|
||||||
break;
|
break;
|
||||||
case GST_STATE_CHANGE_PAUSED_TO_READY:
|
|
||||||
break;
|
|
||||||
case GST_STATE_CHANGE_READY_TO_NULL:
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue