[MOVED FROM GST-P-FARSIGHT] Add caps negotiation function
20070917002412-3e2dc-ca266816e9629746e9083c5bb8b7f73b94a9b2b0.gz
This commit is contained in:
parent
fce9b071f5
commit
f135a43de2
@ -219,13 +219,12 @@ static GstStateChangeReturn gst_rtp_dtmf_src_change_state (GstElement * element,
|
|||||||
static void gst_rtp_dtmf_src_add_start_event (GstRTPDTMFSrc *dtmfsrc,
|
static void gst_rtp_dtmf_src_add_start_event (GstRTPDTMFSrc *dtmfsrc,
|
||||||
gint event_number, gint event_volume);
|
gint event_number, gint event_volume);
|
||||||
static void gst_rtp_dtmf_src_add_stop_event (GstRTPDTMFSrc *dtmfsrc);
|
static void gst_rtp_dtmf_src_add_stop_event (GstRTPDTMFSrc *dtmfsrc);
|
||||||
static void gst_rtp_dtmf_src_set_caps (GstRTPDTMFSrc *dtmfsrc);
|
|
||||||
|
|
||||||
static gboolean gst_rtp_dtmf_src_unlock (GstBaseSrc *src);
|
static gboolean gst_rtp_dtmf_src_unlock (GstBaseSrc *src);
|
||||||
static gboolean gst_rtp_dtmf_src_unlock_stop (GstBaseSrc *src);
|
static gboolean gst_rtp_dtmf_src_unlock_stop (GstBaseSrc *src);
|
||||||
static GstFlowReturn gst_rtp_dtmf_src_create (GstBaseSrc * basesrc,
|
static GstFlowReturn gst_rtp_dtmf_src_create (GstBaseSrc * basesrc,
|
||||||
guint64 offset, guint length, GstBuffer ** buffer);
|
guint64 offset, guint length, GstBuffer ** buffer);
|
||||||
|
static gboolean gst_rtp_dtmf_src_negotiate (GstBaseSrc * basesrc);
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -312,7 +311,8 @@ gst_rtp_dtmf_src_class_init (GstRTPDTMFSrcClass * klass)
|
|||||||
GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_handle_event);
|
GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_handle_event);
|
||||||
gstbasesrc_class->create =
|
gstbasesrc_class->create =
|
||||||
GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_create);
|
GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_create);
|
||||||
|
gstbasesrc_class->negotiate =
|
||||||
|
GST_DEBUG_FUNCPTR (gst_rtp_dtmf_src_negotiate);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -455,14 +455,14 @@ gst_rtp_dtmf_src_set_property (GObject * object, guint prop_id,
|
|||||||
break;
|
break;
|
||||||
case PROP_CLOCK_RATE:
|
case PROP_CLOCK_RATE:
|
||||||
dtmfsrc->clock_rate = g_value_get_uint (value);
|
dtmfsrc->clock_rate = g_value_get_uint (value);
|
||||||
gst_rtp_dtmf_src_set_caps (dtmfsrc);
|
dtmfsrc->dirty = TRUE;
|
||||||
break;
|
break;
|
||||||
case PROP_SSRC:
|
case PROP_SSRC:
|
||||||
dtmfsrc->ssrc = g_value_get_uint (value);
|
dtmfsrc->ssrc = g_value_get_uint (value);
|
||||||
break;
|
break;
|
||||||
case PROP_PT:
|
case PROP_PT:
|
||||||
dtmfsrc->pt = g_value_get_uint (value);
|
dtmfsrc->pt = g_value_get_uint (value);
|
||||||
gst_rtp_dtmf_src_set_caps (dtmfsrc);
|
dtmfsrc->dirty = TRUE;
|
||||||
break;
|
break;
|
||||||
case PROP_INTERVAL:
|
case PROP_INTERVAL:
|
||||||
dtmfsrc->interval = g_value_get_uint (value);
|
dtmfsrc->interval = g_value_get_uint (value);
|
||||||
@ -562,21 +562,6 @@ gst_rtp_dtmf_prepare_timestamps (GstRTPDTMFSrc *dtmfsrc)
|
|||||||
dtmfsrc->clock_rate, GST_SECOND);
|
dtmfsrc->clock_rate, GST_SECOND);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
static void
|
|
||||||
gst_rtp_dtmf_src_start (GstRTPDTMFSrc *dtmfsrc)
|
|
||||||
{
|
|
||||||
gst_rtp_dtmf_src_set_caps (dtmfsrc);
|
|
||||||
|
|
||||||
dtmfsrc->task_paused = FALSE;
|
|
||||||
if (!gst_pad_start_task (dtmfsrc->srcpad,
|
|
||||||
(GstTaskFunction) gst_rtp_dtmf_src_push_next_rtp_packet, dtmfsrc)) {
|
|
||||||
GST_ERROR_OBJECT (dtmfsrc, "Failed to start task on src pad");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_rtp_dtmf_src_add_start_event (GstRTPDTMFSrc *dtmfsrc, gint event_number,
|
gst_rtp_dtmf_src_add_start_event (GstRTPDTMFSrc *dtmfsrc, gint event_number,
|
||||||
@ -843,31 +828,125 @@ gst_rtp_dtmf_src_create (GstBaseSrc * basesrc, guint64 offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean
|
||||||
static void
|
gst_rtp_dtmf_src_negotiate (GstBaseSrc * basesrc)
|
||||||
gst_rtp_dtmf_src_set_caps (GstRTPDTMFSrc *dtmfsrc)
|
|
||||||
{
|
{
|
||||||
GstCaps *caps;
|
GstCaps *srccaps, *peercaps;
|
||||||
|
GstRTPDTMFSrc *dtmfsrc = GST_RTP_DTMF_SRC (basesrc);
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
caps = gst_caps_new_simple ("application/x-rtp",
|
/* fill in the defaults, there properties cannot be negotiated. */
|
||||||
|
srccaps = gst_caps_new_simple ("application/x-rtp",
|
||||||
"media", G_TYPE_STRING, "audio",
|
"media", G_TYPE_STRING, "audio",
|
||||||
"payload", G_TYPE_INT, dtmfsrc->pt,
|
|
||||||
"clock-rate", G_TYPE_INT, dtmfsrc->clock_rate,
|
"clock-rate", G_TYPE_INT, dtmfsrc->clock_rate,
|
||||||
"encoding-name", G_TYPE_STRING, "telephone-event",
|
"encoding-name", G_TYPE_STRING, "telephone-event", NULL);
|
||||||
"ssrc", G_TYPE_UINT, dtmfsrc->current_ssrc,
|
|
||||||
"clock-base", G_TYPE_UINT, dtmfsrc->ts_base,
|
|
||||||
"seqnum-base", G_TYPE_UINT, dtmfsrc->seqnum_base, NULL);
|
|
||||||
|
|
||||||
if (!gst_pad_set_caps (dtmfsrc->srcpad, caps))
|
/* the peer caps can override some of the defaults */
|
||||||
GST_ERROR_OBJECT (dtmfsrc,
|
peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc));
|
||||||
"Failed to set caps %" GST_PTR_FORMAT " on src pad", caps);
|
if (peercaps == NULL) {
|
||||||
else
|
/* no peer caps, just add the other properties */
|
||||||
GST_DEBUG_OBJECT (dtmfsrc,
|
gst_caps_set_simple (srccaps,
|
||||||
"caps %" GST_PTR_FORMAT " set on src pad", caps);
|
"payload", G_TYPE_INT, dtmfsrc->pt,
|
||||||
|
"ssrc", G_TYPE_UINT, dtmfsrc->current_ssrc,
|
||||||
|
"clock-base", G_TYPE_UINT, dtmfsrc->ts_base,
|
||||||
|
"seqnum-base", G_TYPE_UINT, dtmfsrc->seqnum_base, NULL);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (dtmfsrc, "no peer caps: %" GST_PTR_FORMAT, srccaps);
|
||||||
|
} else {
|
||||||
|
GstCaps *temp;
|
||||||
|
GstStructure *s;
|
||||||
|
const GValue *value;
|
||||||
|
gint pt;
|
||||||
|
|
||||||
|
/* peer provides caps we can use to fixate, intersect. This always returns a
|
||||||
|
* writable caps. */
|
||||||
|
temp = gst_caps_intersect (srccaps, peercaps);
|
||||||
|
gst_caps_unref (srccaps);
|
||||||
|
gst_caps_unref (peercaps);
|
||||||
|
|
||||||
|
if (!temp) {
|
||||||
|
GST_DEBUG_OBJECT (dtmfsrc, "Could not get intersection with peer caps");
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gst_caps_is_empty (temp)) {
|
||||||
|
GST_DEBUG_OBJECT (dtmfsrc, "Intersection with peer caps is empty");
|
||||||
|
gst_caps_unref (temp);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* now fixate, start by taking the first caps */
|
||||||
|
gst_caps_truncate (temp);
|
||||||
|
srccaps = temp;
|
||||||
|
|
||||||
|
/* get first structure */
|
||||||
|
s = gst_caps_get_structure (srccaps, 0);
|
||||||
|
|
||||||
|
if (gst_structure_get_int (s, "dtmfsrc", &pt)) {
|
||||||
|
/* use peer pt */
|
||||||
|
dtmfsrc->pt = pt;
|
||||||
|
GST_LOG_OBJECT (dtmfsrc, "using peer pt %d", pt);
|
||||||
|
} else {
|
||||||
|
if (gst_structure_has_field (s, "payload")) {
|
||||||
|
/* can only fixate if there is a field */
|
||||||
|
gst_structure_fixate_field_nearest_int (s, "payload",
|
||||||
|
dtmfsrc->pt);
|
||||||
|
gst_structure_get_int (s, "payload", &pt);
|
||||||
|
GST_LOG_OBJECT (dtmfsrc, "using peer pt %d", pt);
|
||||||
|
} else {
|
||||||
|
/* no pt field, use the internal pt */
|
||||||
|
pt = dtmfsrc->pt;
|
||||||
|
gst_structure_set (s, "payload", G_TYPE_INT, pt, NULL);
|
||||||
|
GST_LOG_OBJECT (dtmfsrc, "using internal pt", pt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gst_structure_has_field_typed (s, "ssrc", G_TYPE_UINT)) {
|
||||||
|
value = gst_structure_get_value (s, "ssrc");
|
||||||
|
dtmfsrc->current_ssrc = g_value_get_uint (value);
|
||||||
|
GST_LOG_OBJECT (dtmfsrc, "using peer ssrc %08x", dtmfsrc->current_ssrc);
|
||||||
|
} else {
|
||||||
|
/* FIXME, fixate_nearest_uint would be even better */
|
||||||
|
gst_structure_set (s, "ssrc", G_TYPE_UINT, dtmfsrc->current_ssrc, NULL);
|
||||||
|
GST_LOG_OBJECT (dtmfsrc, "using internal ssrc %08x",
|
||||||
|
dtmfsrc->current_ssrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gst_structure_has_field_typed (s, "clock-base", G_TYPE_UINT)) {
|
||||||
|
value = gst_structure_get_value (s, "clock-base");
|
||||||
|
dtmfsrc->ts_base = g_value_get_uint (value);
|
||||||
|
GST_LOG_OBJECT (dtmfsrc, "using peer clock-base %u", dtmfsrc->ts_base);
|
||||||
|
} else {
|
||||||
|
/* FIXME, fixate_nearest_uint would be even better */
|
||||||
|
gst_structure_set (s, "clock-base", G_TYPE_UINT, dtmfsrc->ts_base, NULL);
|
||||||
|
GST_LOG_OBJECT (dtmfsrc, "using internal clock-base %u",
|
||||||
|
dtmfsrc->ts_base);
|
||||||
|
}
|
||||||
|
if (gst_structure_has_field_typed (s, "seqnum-base", G_TYPE_UINT)) {
|
||||||
|
value = gst_structure_get_value (s, "seqnum-base");
|
||||||
|
dtmfsrc->seqnum_base = g_value_get_uint (value);
|
||||||
|
GST_LOG_OBJECT (dtmfsrc, "using peer seqnum-base %u",
|
||||||
|
dtmfsrc->seqnum_base);
|
||||||
|
} else {
|
||||||
|
/* FIXME, fixate_nearest_uint would be even better */
|
||||||
|
gst_structure_set (s, "seqnum-base", G_TYPE_UINT, dtmfsrc->seqnum_base,
|
||||||
|
NULL);
|
||||||
|
GST_LOG_OBJECT (dtmfsrc, "using internal seqnum-base %u",
|
||||||
|
dtmfsrc->seqnum_base);
|
||||||
|
}
|
||||||
|
GST_DEBUG_OBJECT (dtmfsrc, "with peer caps: %" GST_PTR_FORMAT, srccaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), srccaps);
|
||||||
|
gst_caps_unref (srccaps);
|
||||||
|
|
||||||
|
dtmfsrc->dirty = FALSE;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
gst_caps_unref (caps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_rtp_dtmf_src_ready_to_paused (GstRTPDTMFSrc *dtmfsrc)
|
gst_rtp_dtmf_src_ready_to_paused (GstRTPDTMFSrc *dtmfsrc)
|
||||||
{
|
{
|
||||||
|
@ -108,6 +108,7 @@ struct _GstRTPDTMFSrc {
|
|||||||
guint16 packet_redundancy;
|
guint16 packet_redundancy;
|
||||||
guint32 clock_rate;
|
guint32 clock_rate;
|
||||||
|
|
||||||
|
gboolean dirty;
|
||||||
guint16 redundancy_count;
|
guint16 redundancy_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user