mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-11 19:06:33 +00:00
rtpmux: port to 0.11
This commit is contained in:
parent
dc4194f86d
commit
e5ff5ee2db
6 changed files with 295 additions and 298 deletions
|
@ -316,7 +316,7 @@ GST_PLUGINS_NONPORTED=" adpcmdec adpcmenc aiff asfmux \
|
||||||
hdvparse hls id3tag inter interlace ivfparse jpegformat jp2kdecimator \
|
hdvparse hls id3tag inter interlace ivfparse jpegformat jp2kdecimator \
|
||||||
kate liveadder legacyresample librfb mpegdemux mpegtsmux \
|
kate liveadder legacyresample librfb mpegdemux mpegtsmux \
|
||||||
mpegpsmux mve mxf mythtv nsf nuvdemux \
|
mpegpsmux mve mxf mythtv nsf nuvdemux \
|
||||||
patchdetect pnm rawparse real removesilence rtpmux rtpvp8 scaletempo \
|
patchdetect pnm rawparse real removesilence rtpvp8 scaletempo \
|
||||||
sdi segmentclip siren speed subenc stereo tta videofilters \
|
sdi segmentclip siren speed subenc stereo tta videofilters \
|
||||||
videomaxrate videomeasure videosignal vmnc \
|
videomaxrate videomeasure videosignal vmnc \
|
||||||
decklink fbdev linsys shm vcd \
|
decklink fbdev linsys shm vcd \
|
||||||
|
|
|
@ -2,8 +2,7 @@ plugin_LTLIBRARIES = libgstrtpmux.la
|
||||||
|
|
||||||
libgstrtpmux_la_SOURCES = gstrtpmuxer.c gstrtpmux.c gstrtpdtmfmux.c
|
libgstrtpmux_la_SOURCES = gstrtpmuxer.c gstrtpmux.c gstrtpdtmfmux.c
|
||||||
|
|
||||||
libgstrtpmux_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS) \
|
libgstrtpmux_la_CFLAGS = $(GST_PLUGINS_BASE_CFLAGS) $(GST_CFLAGS)
|
||||||
-DEXTERN_BUF -DRTP_SUPPORT
|
|
||||||
libgstrtpmux_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstrtp-@GST_MAJORMINOR@ \
|
libgstrtpmux_la_LIBADD = $(GST_PLUGINS_BASE_LIBS) -lgstrtp-@GST_MAJORMINOR@ \
|
||||||
$(GST_BASE_LIBS) $(GST_LIBS)
|
$(GST_BASE_LIBS) $(GST_LIBS)
|
||||||
libgstrtpmux_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
libgstrtpmux_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
|
||||||
|
@ -22,5 +21,5 @@ Android.mk: Makefile.am $(BUILT_SOURCES)
|
||||||
$(libgstrtpmux_la_LIBADD) \
|
$(libgstrtpmux_la_LIBADD) \
|
||||||
-ldl \
|
-ldl \
|
||||||
-:PASSTHROUGH LOCAL_ARM_MODE:=arm \
|
-:PASSTHROUGH LOCAL_ARM_MODE:=arm \
|
||||||
LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.10' \
|
LOCAL_MODULE_PATH:='$$(TARGET_OUT)/lib/gstreamer-0.11' \
|
||||||
> $@
|
> $@
|
|
@ -58,35 +58,22 @@ GST_STATIC_PAD_TEMPLATE ("priority_sink_%u",
|
||||||
GST_STATIC_CAPS ("application/x-rtp"));
|
GST_STATIC_CAPS ("application/x-rtp"));
|
||||||
|
|
||||||
static GstPad *gst_rtp_dtmf_mux_request_new_pad (GstElement * element,
|
static GstPad *gst_rtp_dtmf_mux_request_new_pad (GstElement * element,
|
||||||
GstPadTemplate * templ, const gchar * name);
|
GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
|
||||||
static GstStateChangeReturn gst_rtp_dtmf_mux_change_state (GstElement * element,
|
static GstStateChangeReturn gst_rtp_dtmf_mux_change_state (GstElement * element,
|
||||||
GstStateChange transition);
|
GstStateChange transition);
|
||||||
|
|
||||||
static gboolean gst_rtp_dtmf_mux_accept_buffer_locked (GstRTPMux * rtp_mux,
|
static gboolean gst_rtp_dtmf_mux_accept_buffer_locked (GstRTPMux * rtp_mux,
|
||||||
GstRTPMuxPadPrivate * padpriv, GstBuffer * buffer);
|
GstRTPMuxPadPrivate * padpriv, GstRTPBuffer * rtpbuffer);
|
||||||
static gboolean gst_rtp_dtmf_mux_src_event (GstRTPMux * rtp_mux,
|
static gboolean gst_rtp_dtmf_mux_src_event (GstRTPMux * rtp_mux,
|
||||||
GstEvent * event);
|
GstEvent * event);
|
||||||
|
|
||||||
GST_BOILERPLATE (GstRTPDTMFMux, gst_rtp_dtmf_mux, GstRTPMux, GST_TYPE_RTP_MUX);
|
G_DEFINE_TYPE (GstRTPDTMFMux, gst_rtp_dtmf_mux, GST_TYPE_RTP_MUX);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_rtp_dtmf_mux_init (GstRTPDTMFMux * object, GstRTPDTMFMuxClass * g_class)
|
gst_rtp_dtmf_mux_init (GstRTPDTMFMux * mux)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gst_rtp_dtmf_mux_base_init (gpointer g_class)
|
|
||||||
{
|
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
|
||||||
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
|
||||||
gst_static_pad_template_get (&priority_sink_factory));
|
|
||||||
|
|
||||||
gst_element_class_set_details_simple (element_class, "RTP muxer",
|
|
||||||
"Codec/Muxer",
|
|
||||||
"mixes RTP DTMF streams into other RTP streams",
|
|
||||||
"Zeeshan Ali <first.last@nokia.com>");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_rtp_dtmf_mux_class_init (GstRTPDTMFMuxClass * klass)
|
gst_rtp_dtmf_mux_class_init (GstRTPDTMFMuxClass * klass)
|
||||||
|
@ -97,6 +84,14 @@ gst_rtp_dtmf_mux_class_init (GstRTPDTMFMuxClass * klass)
|
||||||
gstelement_class = (GstElementClass *) klass;
|
gstelement_class = (GstElementClass *) klass;
|
||||||
gstrtpmux_class = (GstRTPMuxClass *) klass;
|
gstrtpmux_class = (GstRTPMuxClass *) klass;
|
||||||
|
|
||||||
|
gst_element_class_add_pad_template (gstelement_class,
|
||||||
|
gst_static_pad_template_get (&priority_sink_factory));
|
||||||
|
|
||||||
|
gst_element_class_set_metadata (gstelement_class, "RTP muxer",
|
||||||
|
"Codec/Muxer",
|
||||||
|
"mixes RTP DTMF streams into other RTP streams",
|
||||||
|
"Zeeshan Ali <first.last@nokia.com>");
|
||||||
|
|
||||||
gstelement_class->request_new_pad =
|
gstelement_class->request_new_pad =
|
||||||
GST_DEBUG_FUNCPTR (gst_rtp_dtmf_mux_request_new_pad);
|
GST_DEBUG_FUNCPTR (gst_rtp_dtmf_mux_request_new_pad);
|
||||||
gstelement_class->change_state =
|
gstelement_class->change_state =
|
||||||
|
@ -107,45 +102,46 @@ gst_rtp_dtmf_mux_class_init (GstRTPDTMFMuxClass * klass)
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_rtp_dtmf_mux_accept_buffer_locked (GstRTPMux * rtp_mux,
|
gst_rtp_dtmf_mux_accept_buffer_locked (GstRTPMux * rtp_mux,
|
||||||
GstRTPMuxPadPrivate * padpriv, GstBuffer * buffer)
|
GstRTPMuxPadPrivate * padpriv, GstRTPBuffer * rtpbuffer)
|
||||||
{
|
{
|
||||||
GstRTPDTMFMux *mux = GST_RTP_DTMF_MUX (rtp_mux);
|
GstRTPDTMFMux *mux = GST_RTP_DTMF_MUX (rtp_mux);
|
||||||
GstClockTime running_ts;
|
GstClockTime running_ts;
|
||||||
|
|
||||||
running_ts = GST_BUFFER_TIMESTAMP (buffer);
|
running_ts = GST_BUFFER_PTS (rtpbuffer->buffer);
|
||||||
|
|
||||||
if (GST_CLOCK_TIME_IS_VALID (running_ts)) {
|
if (GST_CLOCK_TIME_IS_VALID (running_ts)) {
|
||||||
if (padpriv && padpriv->segment.format == GST_FORMAT_TIME)
|
if (padpriv && padpriv->segment.format == GST_FORMAT_TIME)
|
||||||
running_ts = gst_segment_to_running_time (&padpriv->segment,
|
running_ts = gst_segment_to_running_time (&padpriv->segment,
|
||||||
GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (buffer));
|
GST_FORMAT_TIME, GST_BUFFER_PTS (rtpbuffer->buffer));
|
||||||
|
|
||||||
if (padpriv && padpriv->priority) {
|
if (padpriv && padpriv->priority) {
|
||||||
if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
|
if (GST_BUFFER_PTS_IS_VALID (rtpbuffer->buffer)) {
|
||||||
if (GST_CLOCK_TIME_IS_VALID (mux->last_priority_end))
|
if (GST_CLOCK_TIME_IS_VALID (mux->last_priority_end))
|
||||||
mux->last_priority_end =
|
mux->last_priority_end =
|
||||||
MAX (running_ts + GST_BUFFER_DURATION (buffer),
|
MAX (running_ts + GST_BUFFER_DURATION (rtpbuffer->buffer),
|
||||||
mux->last_priority_end);
|
mux->last_priority_end);
|
||||||
else
|
else
|
||||||
mux->last_priority_end = running_ts + GST_BUFFER_DURATION (buffer);
|
mux->last_priority_end = running_ts +
|
||||||
|
GST_BUFFER_DURATION (rtpbuffer->buffer);
|
||||||
GST_LOG_OBJECT (mux, "Got buffer %p on priority pad, "
|
GST_LOG_OBJECT (mux, "Got buffer %p on priority pad, "
|
||||||
" blocking regular pads until %" GST_TIME_FORMAT, buffer,
|
" blocking regular pads until %" GST_TIME_FORMAT, rtpbuffer->buffer,
|
||||||
GST_TIME_ARGS (mux->last_priority_end));
|
GST_TIME_ARGS (mux->last_priority_end));
|
||||||
} else {
|
} else {
|
||||||
GST_WARNING_OBJECT (mux, "Buffer %p has an invalid duration,"
|
GST_WARNING_OBJECT (mux, "Buffer %p has an invalid duration,"
|
||||||
" not blocking other pad", buffer);
|
" not blocking other pad", rtpbuffer->buffer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (GST_CLOCK_TIME_IS_VALID (mux->last_priority_end) &&
|
if (GST_CLOCK_TIME_IS_VALID (mux->last_priority_end) &&
|
||||||
running_ts < mux->last_priority_end) {
|
running_ts < mux->last_priority_end) {
|
||||||
GST_LOG_OBJECT (mux, "Dropping buffer %p because running time"
|
GST_LOG_OBJECT (mux, "Dropping buffer %p because running time"
|
||||||
" %" GST_TIME_FORMAT " < %" GST_TIME_FORMAT, buffer,
|
" %" GST_TIME_FORMAT " < %" GST_TIME_FORMAT, rtpbuffer->buffer,
|
||||||
GST_TIME_ARGS (running_ts), GST_TIME_ARGS (mux->last_priority_end));
|
GST_TIME_ARGS (running_ts), GST_TIME_ARGS (mux->last_priority_end));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
GST_LOG_OBJECT (mux, "Buffer %p has an invalid timestamp,"
|
GST_LOG_OBJECT (mux, "Buffer %p has an invalid timestamp,"
|
||||||
" letting through", buffer);
|
" letting through", rtpbuffer->buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -154,12 +150,13 @@ gst_rtp_dtmf_mux_accept_buffer_locked (GstRTPMux * rtp_mux,
|
||||||
|
|
||||||
static GstPad *
|
static GstPad *
|
||||||
gst_rtp_dtmf_mux_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
gst_rtp_dtmf_mux_request_new_pad (GstElement * element, GstPadTemplate * templ,
|
||||||
const gchar * name)
|
const gchar * name, const GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstPad *pad;
|
GstPad *pad;
|
||||||
|
|
||||||
pad = GST_CALL_PARENT_WITH_DEFAULT (GST_ELEMENT_CLASS, request_new_pad,
|
pad =
|
||||||
(element, templ, name), NULL);
|
GST_ELEMENT_CLASS (gst_rtp_dtmf_mux_parent_class)->request_new_pad
|
||||||
|
(element, templ, name, caps);
|
||||||
|
|
||||||
if (pad) {
|
if (pad) {
|
||||||
GstRTPMuxPadPrivate *padpriv;
|
GstRTPMuxPadPrivate *padpriv;
|
||||||
|
@ -195,7 +192,8 @@ gst_rtp_dtmf_mux_src_event (GstRTPMux * rtp_mux, GstEvent * event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GST_RTP_MUX_CLASS (parent_class)->src_event (rtp_mux, event);
|
return GST_RTP_MUX_CLASS (gst_rtp_dtmf_mux_parent_class)->src_event (rtp_mux,
|
||||||
|
event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -217,7 +215,9 @@ gst_rtp_dtmf_mux_change_state (GstElement * element, GstStateChange transition)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
ret =
|
||||||
|
GST_ELEMENT_CLASS (gst_rtp_dtmf_mux_parent_class)->change_state (element,
|
||||||
|
transition);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,14 +89,18 @@ static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink_%u",
|
||||||
);
|
);
|
||||||
|
|
||||||
static GstPad *gst_rtp_mux_request_new_pad (GstElement * element,
|
static GstPad *gst_rtp_mux_request_new_pad (GstElement * element,
|
||||||
GstPadTemplate * templ, const gchar * name);
|
GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
|
||||||
static void gst_rtp_mux_release_pad (GstElement * element, GstPad * pad);
|
static void gst_rtp_mux_release_pad (GstElement * element, GstPad * pad);
|
||||||
static GstFlowReturn gst_rtp_mux_chain (GstPad * pad, GstBuffer * buffer);
|
static GstFlowReturn gst_rtp_mux_chain (GstPad * pad, GstObject * parent,
|
||||||
static GstFlowReturn gst_rtp_mux_chain_list (GstPad * pad,
|
GstBuffer * buffer);
|
||||||
|
static GstFlowReturn gst_rtp_mux_chain_list (GstPad * pad, GstObject * parent,
|
||||||
GstBufferList * bufferlist);
|
GstBufferList * bufferlist);
|
||||||
static gboolean gst_rtp_mux_setcaps (GstPad * pad, GstCaps * caps);
|
static gboolean gst_rtp_mux_setcaps (GstPad * pad, GstRTPMux * rtp_mux,
|
||||||
static GstCaps *gst_rtp_mux_getcaps (GstPad * pad);
|
GstCaps * caps);
|
||||||
static gboolean gst_rtp_mux_sink_event (GstPad * pad, GstEvent * event);
|
static gboolean gst_rtp_mux_sink_event (GstPad * pad, GstObject * parent,
|
||||||
|
GstEvent * event);
|
||||||
|
static gboolean gst_rtp_mux_sink_query (GstPad * pad, GstObject * parent,
|
||||||
|
GstQuery * query);
|
||||||
|
|
||||||
static GstStateChangeReturn gst_rtp_mux_change_state (GstElement *
|
static GstStateChangeReturn gst_rtp_mux_change_state (GstElement *
|
||||||
element, GstStateChange transition);
|
element, GstStateChange transition);
|
||||||
|
@ -110,22 +114,8 @@ static void gst_rtp_mux_dispose (GObject * object);
|
||||||
static gboolean gst_rtp_mux_src_event_real (GstRTPMux * rtp_mux,
|
static gboolean gst_rtp_mux_src_event_real (GstRTPMux * rtp_mux,
|
||||||
GstEvent * event);
|
GstEvent * event);
|
||||||
|
|
||||||
GST_BOILERPLATE (GstRTPMux, gst_rtp_mux, GstElement, GST_TYPE_ELEMENT);
|
G_DEFINE_TYPE (GstRTPMux, gst_rtp_mux, GST_TYPE_ELEMENT);
|
||||||
|
|
||||||
static void
|
|
||||||
gst_rtp_mux_base_init (gpointer g_class)
|
|
||||||
{
|
|
||||||
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
|
|
||||||
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
|
||||||
gst_static_pad_template_get (&src_factory));
|
|
||||||
gst_element_class_add_pad_template (element_class,
|
|
||||||
gst_static_pad_template_get (&sink_factory));
|
|
||||||
|
|
||||||
gst_element_class_set_details_simple (element_class, "RTP muxer",
|
|
||||||
"Codec/Muxer",
|
|
||||||
"multiplex N rtp streams into one", "Zeeshan Ali <first.last@nokia.com>");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_rtp_mux_class_init (GstRTPMuxClass * klass)
|
gst_rtp_mux_class_init (GstRTPMuxClass * klass)
|
||||||
|
@ -136,6 +126,16 @@ gst_rtp_mux_class_init (GstRTPMuxClass * klass)
|
||||||
gobject_class = (GObjectClass *) klass;
|
gobject_class = (GObjectClass *) klass;
|
||||||
gstelement_class = (GstElementClass *) klass;
|
gstelement_class = (GstElementClass *) klass;
|
||||||
|
|
||||||
|
|
||||||
|
gst_element_class_add_pad_template (gstelement_class,
|
||||||
|
gst_static_pad_template_get (&src_factory));
|
||||||
|
gst_element_class_add_pad_template (gstelement_class,
|
||||||
|
gst_static_pad_template_get (&sink_factory));
|
||||||
|
|
||||||
|
gst_element_class_set_metadata (gstelement_class, "RTP muxer",
|
||||||
|
"Codec/Muxer",
|
||||||
|
"multiplex N rtp streams into one", "Zeeshan Ali <first.last@nokia.com>");
|
||||||
|
|
||||||
gobject_class->get_property = gst_rtp_mux_get_property;
|
gobject_class->get_property = gst_rtp_mux_get_property;
|
||||||
gobject_class->set_property = gst_rtp_mux_set_property;
|
gobject_class->set_property = gst_rtp_mux_set_property;
|
||||||
gobject_class->dispose = gst_rtp_mux_dispose;
|
gobject_class->dispose = gst_rtp_mux_dispose;
|
||||||
|
@ -182,24 +182,20 @@ restart:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
G_OBJECT_CLASS (parent_class)->dispose (object);
|
G_OBJECT_CLASS (gst_rtp_mux_parent_class)->dispose (object);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_rtp_mux_src_event (GstPad * pad, GstEvent * event)
|
gst_rtp_mux_src_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
{
|
{
|
||||||
GstRTPMux *rtp_mux;
|
GstRTPMux *rtp_mux = GST_RTP_MUX (parent);
|
||||||
GstRTPMuxClass *klass;
|
GstRTPMuxClass *klass;
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
rtp_mux = (GstRTPMux *) gst_pad_get_parent_element (pad);
|
|
||||||
g_return_val_if_fail (rtp_mux != NULL, FALSE);
|
|
||||||
klass = GST_RTP_MUX_GET_CLASS (rtp_mux);
|
klass = GST_RTP_MUX_GET_CLASS (rtp_mux);
|
||||||
|
|
||||||
ret = klass->src_event (rtp_mux, event);
|
ret = klass->src_event (rtp_mux, event);
|
||||||
|
|
||||||
gst_object_unref (rtp_mux);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,18 +203,18 @@ static gboolean
|
||||||
gst_rtp_mux_src_event_real (GstRTPMux * rtp_mux, GstEvent * event)
|
gst_rtp_mux_src_event_real (GstRTPMux * rtp_mux, GstEvent * event)
|
||||||
{
|
{
|
||||||
GstIterator *iter;
|
GstIterator *iter;
|
||||||
GstPad *sinkpad;
|
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
gboolean done = FALSE;
|
gboolean done = FALSE;
|
||||||
|
|
||||||
iter = gst_element_iterate_sink_pads (GST_ELEMENT (rtp_mux));
|
iter = gst_element_iterate_sink_pads (GST_ELEMENT (rtp_mux));
|
||||||
|
|
||||||
while (!done) {
|
while (!done) {
|
||||||
switch (gst_iterator_next (iter, (gpointer) & sinkpad)) {
|
GValue item = { 0, };
|
||||||
|
|
||||||
|
switch (gst_iterator_next (iter, &item)) {
|
||||||
case GST_ITERATOR_OK:
|
case GST_ITERATOR_OK:
|
||||||
gst_event_ref (event);
|
gst_event_ref (event);
|
||||||
result |= gst_pad_push_event (sinkpad, event);
|
result |= gst_pad_push_event (g_value_get_object (&item), event);
|
||||||
gst_object_unref (sinkpad);
|
|
||||||
break;
|
break;
|
||||||
case GST_ITERATOR_RESYNC:
|
case GST_ITERATOR_RESYNC:
|
||||||
gst_iterator_resync (iter);
|
gst_iterator_resync (iter);
|
||||||
|
@ -238,23 +234,26 @@ gst_rtp_mux_src_event_real (GstRTPMux * rtp_mux, GstEvent * event)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_rtp_mux_init (GstRTPMux * object, GstRTPMuxClass * g_class)
|
gst_rtp_mux_init (GstRTPMux * rtp_mux)
|
||||||
{
|
{
|
||||||
GstElementClass *klass = GST_ELEMENT_GET_CLASS (object);
|
GstElementClass *klass = GST_ELEMENT_GET_CLASS (rtp_mux);
|
||||||
|
GstSegment segment;
|
||||||
|
|
||||||
object->srcpad =
|
rtp_mux->srcpad =
|
||||||
gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
|
gst_pad_new_from_template (gst_element_class_get_pad_template (klass,
|
||||||
"src"), "src");
|
"src"), "src");
|
||||||
gst_pad_set_event_function (object->srcpad,
|
gst_pad_set_event_function (rtp_mux->srcpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_rtp_mux_src_event));
|
GST_DEBUG_FUNCPTR (gst_rtp_mux_src_event));
|
||||||
gst_element_add_pad (GST_ELEMENT (object), object->srcpad);
|
gst_element_add_pad (GST_ELEMENT (rtp_mux), rtp_mux->srcpad);
|
||||||
|
|
||||||
object->ssrc = DEFAULT_SSRC;
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
object->ts_offset = DEFAULT_TIMESTAMP_OFFSET;
|
gst_pad_push_event (rtp_mux->srcpad, gst_event_new_segment (&segment));
|
||||||
object->seqnum_offset = DEFAULT_SEQNUM_OFFSET;
|
|
||||||
|
|
||||||
object->segment_pending = TRUE;
|
rtp_mux->ssrc = DEFAULT_SSRC;
|
||||||
object->last_stop = GST_CLOCK_TIME_NONE;
|
rtp_mux->ts_offset = DEFAULT_TIMESTAMP_OFFSET;
|
||||||
|
rtp_mux->seqnum_offset = DEFAULT_SEQNUM_OFFSET;
|
||||||
|
|
||||||
|
rtp_mux->last_stop = GST_CLOCK_TIME_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -263,16 +262,16 @@ gst_rtp_mux_setup_sinkpad (GstRTPMux * rtp_mux, GstPad * sinkpad)
|
||||||
GstRTPMuxPadPrivate *padpriv = g_slice_new0 (GstRTPMuxPadPrivate);
|
GstRTPMuxPadPrivate *padpriv = g_slice_new0 (GstRTPMuxPadPrivate);
|
||||||
|
|
||||||
/* setup some pad functions */
|
/* setup some pad functions */
|
||||||
gst_pad_set_setcaps_function (sinkpad, gst_rtp_mux_setcaps);
|
|
||||||
gst_pad_set_getcaps_function (sinkpad, gst_rtp_mux_getcaps);
|
|
||||||
gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (gst_rtp_mux_chain));
|
gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (gst_rtp_mux_chain));
|
||||||
gst_pad_set_chain_list_function (sinkpad,
|
gst_pad_set_chain_list_function (sinkpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_rtp_mux_chain_list));
|
GST_DEBUG_FUNCPTR (gst_rtp_mux_chain_list));
|
||||||
gst_pad_set_event_function (sinkpad,
|
gst_pad_set_event_function (sinkpad,
|
||||||
GST_DEBUG_FUNCPTR (gst_rtp_mux_sink_event));
|
GST_DEBUG_FUNCPTR (gst_rtp_mux_sink_event));
|
||||||
|
gst_pad_set_query_function (sinkpad,
|
||||||
|
GST_DEBUG_FUNCPTR (gst_rtp_mux_sink_query));
|
||||||
|
|
||||||
|
|
||||||
gst_segment_init (&padpriv->segment, GST_FORMAT_UNDEFINED);
|
gst_segment_init (&padpriv->segment, GST_FORMAT_TIME);
|
||||||
|
|
||||||
gst_pad_set_element_private (sinkpad, padpriv);
|
gst_pad_set_element_private (sinkpad, padpriv);
|
||||||
|
|
||||||
|
@ -282,7 +281,7 @@ gst_rtp_mux_setup_sinkpad (GstRTPMux * rtp_mux, GstPad * sinkpad)
|
||||||
|
|
||||||
static GstPad *
|
static GstPad *
|
||||||
gst_rtp_mux_request_new_pad (GstElement * element,
|
gst_rtp_mux_request_new_pad (GstElement * element,
|
||||||
GstPadTemplate * templ, const gchar * req_name)
|
GstPadTemplate * templ, const gchar * req_name, const GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstRTPMux *rtp_mux;
|
GstRTPMux *rtp_mux;
|
||||||
GstPad *newpad;
|
GstPad *newpad;
|
||||||
|
@ -327,7 +326,7 @@ gst_rtp_mux_release_pad (GstElement * element, GstPad * pad)
|
||||||
/* Put our own clock-base on the buffer */
|
/* Put our own clock-base on the buffer */
|
||||||
static void
|
static void
|
||||||
gst_rtp_mux_readjust_rtp_timestamp_locked (GstRTPMux * rtp_mux,
|
gst_rtp_mux_readjust_rtp_timestamp_locked (GstRTPMux * rtp_mux,
|
||||||
GstRTPMuxPadPrivate * padpriv, GstBuffer * buffer)
|
GstRTPMuxPadPrivate * padpriv, GstRTPBuffer * rtpbuffer)
|
||||||
{
|
{
|
||||||
guint32 ts;
|
guint32 ts;
|
||||||
guint32 sink_ts_base = 0;
|
guint32 sink_ts_base = 0;
|
||||||
|
@ -335,59 +334,87 @@ gst_rtp_mux_readjust_rtp_timestamp_locked (GstRTPMux * rtp_mux,
|
||||||
if (padpriv && padpriv->have_clock_base)
|
if (padpriv && padpriv->have_clock_base)
|
||||||
sink_ts_base = padpriv->clock_base;
|
sink_ts_base = padpriv->clock_base;
|
||||||
|
|
||||||
ts = gst_rtp_buffer_get_timestamp (buffer) - sink_ts_base + rtp_mux->ts_base;
|
ts = gst_rtp_buffer_get_timestamp (rtpbuffer) - sink_ts_base +
|
||||||
|
rtp_mux->ts_base;
|
||||||
GST_LOG_OBJECT (rtp_mux, "Re-adjusting RTP ts %u to %u",
|
GST_LOG_OBJECT (rtp_mux, "Re-adjusting RTP ts %u to %u",
|
||||||
gst_rtp_buffer_get_timestamp (buffer), ts);
|
gst_rtp_buffer_get_timestamp (rtpbuffer), ts);
|
||||||
gst_rtp_buffer_set_timestamp (buffer, ts);
|
gst_rtp_buffer_set_timestamp (rtpbuffer, ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
process_buffer_locked (GstRTPMux * rtp_mux, GstRTPMuxPadPrivate * padpriv,
|
process_buffer_locked (GstRTPMux * rtp_mux, GstRTPMuxPadPrivate * padpriv,
|
||||||
GstBuffer * buffer)
|
GstRTPBuffer * rtpbuffer)
|
||||||
{
|
{
|
||||||
GstRTPMuxClass *klass = GST_RTP_MUX_GET_CLASS (rtp_mux);
|
GstRTPMuxClass *klass = GST_RTP_MUX_GET_CLASS (rtp_mux);
|
||||||
|
|
||||||
if (klass->accept_buffer_locked)
|
if (klass->accept_buffer_locked)
|
||||||
if (!klass->accept_buffer_locked (rtp_mux, padpriv, buffer))
|
if (!klass->accept_buffer_locked (rtp_mux, padpriv, rtpbuffer))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
rtp_mux->seqnum++;
|
rtp_mux->seqnum++;
|
||||||
gst_rtp_buffer_set_seq (buffer, rtp_mux->seqnum);
|
gst_rtp_buffer_set_seq (rtpbuffer, rtp_mux->seqnum);
|
||||||
|
|
||||||
gst_rtp_buffer_set_ssrc (buffer, rtp_mux->current_ssrc);
|
gst_rtp_buffer_set_ssrc (rtpbuffer, rtp_mux->current_ssrc);
|
||||||
gst_rtp_mux_readjust_rtp_timestamp_locked (rtp_mux, padpriv, buffer);
|
gst_rtp_mux_readjust_rtp_timestamp_locked (rtp_mux, padpriv, rtpbuffer);
|
||||||
GST_LOG_OBJECT (rtp_mux, "Pushing packet size %d, seq=%d, ts=%u",
|
GST_LOG_OBJECT (rtp_mux, "Pushing packet size %d, seq=%d, ts=%u",
|
||||||
GST_BUFFER_SIZE (buffer), rtp_mux->seqnum,
|
rtpbuffer->size, rtp_mux->seqnum,
|
||||||
gst_rtp_buffer_get_timestamp (buffer));
|
gst_rtp_buffer_get_timestamp (rtpbuffer));
|
||||||
|
|
||||||
if (padpriv) {
|
if (padpriv) {
|
||||||
gst_buffer_set_caps (buffer, padpriv->out_caps);
|
|
||||||
if (padpriv->segment.format == GST_FORMAT_TIME)
|
if (padpriv->segment.format == GST_FORMAT_TIME)
|
||||||
GST_BUFFER_TIMESTAMP (buffer) =
|
GST_BUFFER_PTS (rtpbuffer->buffer) =
|
||||||
gst_segment_to_running_time (&padpriv->segment, GST_FORMAT_TIME,
|
gst_segment_to_running_time (&padpriv->segment, GST_FORMAT_TIME,
|
||||||
GST_BUFFER_TIMESTAMP (buffer));
|
GST_BUFFER_PTS (rtpbuffer->buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct BufferListData
|
||||||
|
{
|
||||||
|
GstRTPMux *rtp_mux;
|
||||||
|
GstRTPMuxPadPrivate *padpriv;
|
||||||
|
gboolean drop;
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
process_list_item (GstBuffer ** buffer, guint idx, gpointer user_data)
|
||||||
|
{
|
||||||
|
struct BufferListData *bd = user_data;
|
||||||
|
GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
|
||||||
|
|
||||||
|
*buffer = gst_buffer_make_writable (*buffer);
|
||||||
|
|
||||||
|
gst_rtp_buffer_map (*buffer, GST_MAP_READWRITE, &rtpbuffer);
|
||||||
|
|
||||||
|
bd->drop = !process_buffer_locked (bd->rtp_mux, bd->padpriv, &rtpbuffer);
|
||||||
|
|
||||||
|
gst_rtp_buffer_unmap (&rtpbuffer);
|
||||||
|
|
||||||
|
if (bd->drop)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (GST_BUFFER_DURATION_IS_VALID (*buffer) &&
|
||||||
|
GST_BUFFER_TIMESTAMP_IS_VALID (*buffer))
|
||||||
|
bd->rtp_mux->last_stop = GST_BUFFER_TIMESTAMP (*buffer) +
|
||||||
|
GST_BUFFER_DURATION (*buffer);
|
||||||
|
else
|
||||||
|
bd->rtp_mux->last_stop = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rtp_mux_chain_list (GstPad * pad, GstBufferList * bufferlist)
|
gst_rtp_mux_chain_list (GstPad * pad, GstObject * parent,
|
||||||
|
GstBufferList * bufferlist)
|
||||||
{
|
{
|
||||||
GstRTPMux *rtp_mux;
|
GstRTPMux *rtp_mux;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GstBufferListIterator *it;
|
|
||||||
GstRTPMuxPadPrivate *padpriv;
|
GstRTPMuxPadPrivate *padpriv;
|
||||||
GstEvent *newseg_event = NULL;
|
|
||||||
gboolean drop = TRUE;
|
gboolean drop = TRUE;
|
||||||
|
struct BufferListData bd;
|
||||||
|
|
||||||
rtp_mux = GST_RTP_MUX (gst_pad_get_parent (pad));
|
rtp_mux = GST_RTP_MUX (parent);
|
||||||
|
|
||||||
if (!gst_rtp_buffer_list_validate (bufferlist)) {
|
|
||||||
GST_ERROR_OBJECT (rtp_mux, "Invalid RTP buffer");
|
|
||||||
gst_object_unref (rtp_mux);
|
|
||||||
return GST_FLOW_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_OBJECT_LOCK (rtp_mux);
|
GST_OBJECT_LOCK (rtp_mux);
|
||||||
|
|
||||||
|
@ -399,52 +426,15 @@ gst_rtp_mux_chain_list (GstPad * pad, GstBufferList * bufferlist)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bd.rtp_mux = rtp_mux;
|
||||||
|
bd.padpriv = padpriv;
|
||||||
|
bd.drop = FALSE;
|
||||||
|
|
||||||
bufferlist = gst_buffer_list_make_writable (bufferlist);
|
bufferlist = gst_buffer_list_make_writable (bufferlist);
|
||||||
it = gst_buffer_list_iterate (bufferlist);
|
gst_buffer_list_foreach (bufferlist, process_list_item, &bd);
|
||||||
while (gst_buffer_list_iterator_next_group (it)) {
|
|
||||||
GstBuffer *rtpbuf;
|
|
||||||
|
|
||||||
rtpbuf = gst_buffer_list_iterator_next (it);
|
|
||||||
rtpbuf = gst_buffer_make_writable (rtpbuf);
|
|
||||||
|
|
||||||
drop = !process_buffer_locked (rtp_mux, padpriv, rtpbuf);
|
|
||||||
|
|
||||||
if (drop)
|
|
||||||
break;
|
|
||||||
|
|
||||||
gst_buffer_list_iterator_take (it, rtpbuf);
|
|
||||||
|
|
||||||
do {
|
|
||||||
if (GST_BUFFER_DURATION_IS_VALID (rtpbuf) &&
|
|
||||||
GST_BUFFER_TIMESTAMP_IS_VALID (rtpbuf))
|
|
||||||
rtp_mux->last_stop = GST_BUFFER_TIMESTAMP (rtpbuf) +
|
|
||||||
GST_BUFFER_DURATION (rtpbuf);
|
|
||||||
else
|
|
||||||
rtp_mux->last_stop = GST_CLOCK_TIME_NONE;
|
|
||||||
|
|
||||||
gst_buffer_list_iterator_take (it, rtpbuf);
|
|
||||||
|
|
||||||
} while ((rtpbuf = gst_buffer_list_iterator_next (it)) != NULL);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
gst_buffer_list_iterator_free (it);
|
|
||||||
|
|
||||||
if (!drop && rtp_mux->segment_pending) {
|
|
||||||
/*
|
|
||||||
* We set the start at 0, because we re-timestamps to the running time
|
|
||||||
*/
|
|
||||||
newseg_event = gst_event_new_new_segment_full (FALSE, 1.0, 1.0,
|
|
||||||
GST_FORMAT_TIME, 0, -1, 0);
|
|
||||||
|
|
||||||
rtp_mux->segment_pending = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_OBJECT_UNLOCK (rtp_mux);
|
GST_OBJECT_UNLOCK (rtp_mux);
|
||||||
|
|
||||||
if (newseg_event)
|
|
||||||
gst_pad_push_event (rtp_mux->srcpad, newseg_event);
|
|
||||||
|
|
||||||
if (drop) {
|
if (drop) {
|
||||||
gst_buffer_list_unref (bufferlist);
|
gst_buffer_list_unref (bufferlist);
|
||||||
ret = GST_FLOW_OK;
|
ret = GST_FLOW_OK;
|
||||||
|
@ -454,19 +444,18 @@ gst_rtp_mux_chain_list (GstPad * pad, GstBufferList * bufferlist)
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
||||||
gst_object_unref (rtp_mux);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_rtp_mux_chain (GstPad * pad, GstBuffer * buffer)
|
gst_rtp_mux_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GstRTPMux *rtp_mux;
|
GstRTPMux *rtp_mux;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GstRTPMuxPadPrivate *padpriv;
|
GstRTPMuxPadPrivate *padpriv;
|
||||||
GstEvent *newseg_event = NULL;
|
GstEvent *newseg_event = NULL;
|
||||||
gboolean drop;
|
gboolean drop;
|
||||||
|
GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
|
||||||
|
|
||||||
rtp_mux = GST_RTP_MUX (GST_OBJECT_PARENT (pad));
|
rtp_mux = GST_RTP_MUX (GST_OBJECT_PARENT (pad));
|
||||||
|
|
||||||
|
@ -487,19 +476,13 @@ gst_rtp_mux_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
|
|
||||||
buffer = gst_buffer_make_writable (buffer);
|
buffer = gst_buffer_make_writable (buffer);
|
||||||
|
|
||||||
drop = !process_buffer_locked (rtp_mux, padpriv, buffer);
|
gst_rtp_buffer_map (buffer, GST_MAP_READWRITE, &rtpbuffer);
|
||||||
|
|
||||||
|
drop = !process_buffer_locked (rtp_mux, padpriv, &rtpbuffer);
|
||||||
|
|
||||||
|
gst_rtp_buffer_unmap (&rtpbuffer);
|
||||||
|
|
||||||
if (!drop) {
|
if (!drop) {
|
||||||
if (rtp_mux->segment_pending) {
|
|
||||||
/*
|
|
||||||
* We set the start at 0, because we re-timestamps to the running time
|
|
||||||
*/
|
|
||||||
newseg_event = gst_event_new_new_segment_full (FALSE, 1.0, 1.0,
|
|
||||||
GST_FORMAT_TIME, 0, -1, 0);
|
|
||||||
|
|
||||||
rtp_mux->segment_pending = FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (GST_BUFFER_DURATION_IS_VALID (buffer) &&
|
if (GST_BUFFER_DURATION_IS_VALID (buffer) &&
|
||||||
GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
|
GST_BUFFER_TIMESTAMP_IS_VALID (buffer))
|
||||||
rtp_mux->last_stop = GST_BUFFER_TIMESTAMP (buffer) +
|
rtp_mux->last_stop = GST_BUFFER_TIMESTAMP (buffer) +
|
||||||
|
@ -524,19 +507,16 @@ gst_rtp_mux_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_rtp_mux_setcaps (GstPad * pad, GstCaps * caps)
|
gst_rtp_mux_setcaps (GstPad * pad, GstRTPMux * rtp_mux, GstCaps * caps)
|
||||||
{
|
{
|
||||||
GstRTPMux *rtp_mux;
|
|
||||||
GstStructure *structure;
|
GstStructure *structure;
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
GstRTPMuxPadPrivate *padpriv;
|
GstRTPMuxPadPrivate *padpriv;
|
||||||
|
|
||||||
rtp_mux = GST_RTP_MUX (gst_pad_get_parent (pad));
|
|
||||||
|
|
||||||
structure = gst_caps_get_structure (caps, 0);
|
structure = gst_caps_get_structure (caps, 0);
|
||||||
|
|
||||||
if (!structure)
|
if (!structure)
|
||||||
goto out;
|
return FALSE;
|
||||||
|
|
||||||
GST_OBJECT_LOCK (rtp_mux);
|
GST_OBJECT_LOCK (rtp_mux);
|
||||||
padpriv = gst_pad_get_element_private (pad);
|
padpriv = gst_pad_get_element_private (pad);
|
||||||
|
@ -572,9 +552,6 @@ gst_rtp_mux_setcaps (GstPad * pad, GstCaps * caps)
|
||||||
}
|
}
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
out:
|
|
||||||
gst_object_unref (rtp_mux);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,54 +577,47 @@ clear_caps (GstCaps * caps, gboolean only_clock_rate)
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
same_clock_rate_fold (gpointer item, GValue * ret, gpointer user_data)
|
same_clock_rate_fold (const GValue * item, GValue * ret, gpointer user_data)
|
||||||
{
|
{
|
||||||
GstPad *mypad = user_data;
|
GstPad *mypad = user_data;
|
||||||
GstPad *pad = item;
|
GstPad *pad = g_value_get_object (item);
|
||||||
GstCaps *peercaps;
|
GstCaps *peercaps;
|
||||||
GstCaps *othercaps;
|
|
||||||
const GstCaps *accumcaps;
|
const GstCaps *accumcaps;
|
||||||
GstCaps *intersect;
|
GstCaps *intersect;
|
||||||
|
|
||||||
if (pad == mypad) {
|
if (pad == mypad) {
|
||||||
gst_object_unref (pad);
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
peercaps = gst_pad_peer_get_caps (pad);
|
|
||||||
if (!peercaps) {
|
|
||||||
gst_object_unref (pad);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
othercaps = gst_caps_intersect (peercaps,
|
|
||||||
gst_pad_get_pad_template_caps (pad));
|
|
||||||
gst_caps_unref (peercaps);
|
|
||||||
|
|
||||||
accumcaps = gst_value_get_caps (ret);
|
accumcaps = gst_value_get_caps (ret);
|
||||||
|
peercaps = gst_pad_peer_query_caps (pad, (GstCaps *) accumcaps);
|
||||||
|
if (!peercaps) {
|
||||||
|
g_warning ("no peercaps");
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
peercaps = gst_caps_make_writable (peercaps);
|
||||||
|
clear_caps (peercaps, TRUE);
|
||||||
|
|
||||||
clear_caps (othercaps, TRUE);
|
intersect = gst_caps_intersect (accumcaps, peercaps);
|
||||||
|
|
||||||
intersect = gst_caps_intersect (accumcaps, othercaps);
|
|
||||||
|
|
||||||
g_value_take_boxed (ret, intersect);
|
g_value_take_boxed (ret, intersect);
|
||||||
|
gst_caps_unref (peercaps);
|
||||||
gst_caps_unref (othercaps);
|
|
||||||
gst_object_unref (pad);
|
|
||||||
|
|
||||||
return !gst_caps_is_empty (intersect);
|
return !gst_caps_is_empty (intersect);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GstCaps *
|
static GstCaps *
|
||||||
gst_rtp_mux_getcaps (GstPad * pad)
|
gst_rtp_mux_getcaps (GstPad * pad, GstRTPMux * mux, GstCaps * filter)
|
||||||
{
|
{
|
||||||
GstRTPMux *mux = GST_RTP_MUX (gst_pad_get_parent (pad));
|
|
||||||
GstCaps *caps = NULL;
|
GstCaps *caps = NULL;
|
||||||
GstIterator *iter = NULL;
|
GstIterator *iter = NULL;
|
||||||
GValue v = { 0 };
|
GValue v = { 0 };
|
||||||
GstIteratorResult res;
|
GstIteratorResult res;
|
||||||
GstCaps *peercaps = gst_pad_peer_get_caps (mux->srcpad);
|
GstCaps *peercaps;
|
||||||
GstCaps *othercaps = NULL;
|
GstCaps *othercaps = NULL;
|
||||||
|
GstCaps *filtered_caps;
|
||||||
|
|
||||||
|
peercaps = gst_pad_peer_query_caps (mux->srcpad, filter);
|
||||||
|
|
||||||
if (peercaps) {
|
if (peercaps) {
|
||||||
othercaps = gst_caps_intersect (peercaps,
|
othercaps = gst_caps_intersect (peercaps,
|
||||||
|
@ -657,13 +627,21 @@ gst_rtp_mux_getcaps (GstPad * pad)
|
||||||
othercaps = gst_caps_copy (gst_pad_get_pad_template_caps (mux->srcpad));
|
othercaps = gst_caps_copy (gst_pad_get_pad_template_caps (mux->srcpad));
|
||||||
}
|
}
|
||||||
|
|
||||||
clear_caps (othercaps, FALSE);
|
if (filter) {
|
||||||
|
filtered_caps = gst_caps_intersect (othercaps, filter);
|
||||||
|
gst_caps_unref (othercaps);
|
||||||
|
} else {
|
||||||
|
filtered_caps = othercaps;
|
||||||
|
}
|
||||||
|
|
||||||
|
filtered_caps = gst_caps_make_writable (filtered_caps);
|
||||||
|
clear_caps (filtered_caps, FALSE);
|
||||||
|
|
||||||
g_value_init (&v, GST_TYPE_CAPS);
|
g_value_init (&v, GST_TYPE_CAPS);
|
||||||
|
|
||||||
iter = gst_element_iterate_sink_pads (GST_ELEMENT (mux));
|
iter = gst_element_iterate_sink_pads (GST_ELEMENT (mux));
|
||||||
do {
|
do {
|
||||||
gst_value_set_caps (&v, othercaps);
|
gst_value_set_caps (&v, filtered_caps);
|
||||||
res = gst_iterator_fold (iter, same_clock_rate_fold, &v, pad);
|
res = gst_iterator_fold (iter, same_clock_rate_fold, &v, pad);
|
||||||
} while (res == GST_ITERATOR_RESYNC);
|
} while (res == GST_ITERATOR_RESYNC);
|
||||||
gst_iterator_free (iter);
|
gst_iterator_free (iter);
|
||||||
|
@ -675,13 +653,39 @@ gst_rtp_mux_getcaps (GstPad * pad)
|
||||||
caps = gst_caps_new_empty ();
|
caps = gst_caps_new_empty ();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (othercaps)
|
gst_caps_unref (filtered_caps);
|
||||||
gst_caps_unref (othercaps);
|
|
||||||
gst_object_unref (mux);
|
|
||||||
|
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_rtp_mux_sink_query (GstPad * pad, GstObject * parent, GstQuery * query)
|
||||||
|
{
|
||||||
|
GstRTPMux *mux = GST_RTP_MUX (parent);
|
||||||
|
gboolean res = FALSE;
|
||||||
|
|
||||||
|
switch (GST_QUERY_TYPE (query)) {
|
||||||
|
case GST_QUERY_CAPS:
|
||||||
|
{
|
||||||
|
GstCaps *filter, *caps;
|
||||||
|
|
||||||
|
gst_query_parse_caps (query, &filter);
|
||||||
|
caps = gst_rtp_mux_getcaps (pad, mux, filter);
|
||||||
|
gst_query_set_caps_result (query, caps);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
res = TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
res = gst_pad_query_default (pad, parent, query);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_rtp_mux_get_property (GObject * object,
|
gst_rtp_mux_get_property (GObject * object,
|
||||||
|
@ -737,49 +741,41 @@ gst_rtp_mux_set_property (GObject * object,
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
gst_rtp_mux_sink_event (GstPad * pad, GstEvent * event)
|
gst_rtp_mux_sink_event (GstPad * pad, GstObject * parent, GstEvent * event)
|
||||||
{
|
{
|
||||||
|
|
||||||
GstRTPMux *mux;
|
GstRTPMux *mux;
|
||||||
gboolean ret = FALSE;
|
gboolean ret = FALSE;
|
||||||
gboolean forward = TRUE;
|
gboolean forward = TRUE;
|
||||||
|
|
||||||
mux = GST_RTP_MUX (gst_pad_get_parent (pad));
|
mux = GST_RTP_MUX (parent);
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
|
case GST_EVENT_CAPS:
|
||||||
|
{
|
||||||
|
GstCaps *caps;
|
||||||
|
|
||||||
|
gst_event_parse_caps (event, &caps);
|
||||||
|
ret = gst_rtp_mux_setcaps (pad, mux, caps);
|
||||||
|
forward = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case GST_EVENT_FLUSH_STOP:
|
case GST_EVENT_FLUSH_STOP:
|
||||||
{
|
{
|
||||||
GstRTPMuxPadPrivate *padpriv;
|
|
||||||
|
|
||||||
GST_OBJECT_LOCK (mux);
|
GST_OBJECT_LOCK (mux);
|
||||||
mux->last_stop = GST_CLOCK_TIME_NONE;
|
mux->last_stop = GST_CLOCK_TIME_NONE;
|
||||||
mux->segment_pending = TRUE;
|
|
||||||
padpriv = gst_pad_get_element_private (pad);
|
|
||||||
if (padpriv)
|
|
||||||
gst_segment_init (&padpriv->segment, GST_FORMAT_UNDEFINED);
|
|
||||||
GST_OBJECT_UNLOCK (mux);
|
GST_OBJECT_UNLOCK (mux);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case GST_EVENT_NEWSEGMENT:
|
}
|
||||||
|
case GST_EVENT_SEGMENT:
|
||||||
{
|
{
|
||||||
gboolean update;
|
|
||||||
gdouble rate, applied_rate;
|
|
||||||
GstFormat format;
|
|
||||||
gint64 start, stop, position;
|
|
||||||
GstRTPMuxPadPrivate *padpriv;
|
GstRTPMuxPadPrivate *padpriv;
|
||||||
|
|
||||||
gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
|
|
||||||
&format, &start, &stop, &position);
|
|
||||||
|
|
||||||
GST_OBJECT_LOCK (mux);
|
GST_OBJECT_LOCK (mux);
|
||||||
padpriv = gst_pad_get_element_private (pad);
|
padpriv = gst_pad_get_element_private (pad);
|
||||||
|
|
||||||
if (padpriv) {
|
if (padpriv) {
|
||||||
if (format == GST_FORMAT_TIME)
|
gst_event_copy_segment (event, &padpriv->segment);
|
||||||
gst_segment_set_newsegment_full (&padpriv->segment, update,
|
|
||||||
rate, applied_rate, format, start, stop, position);
|
|
||||||
else
|
|
||||||
gst_segment_init (&padpriv->segment, GST_FORMAT_UNDEFINED);
|
|
||||||
}
|
}
|
||||||
GST_OBJECT_UNLOCK (mux);
|
GST_OBJECT_UNLOCK (mux);
|
||||||
gst_event_unref (event);
|
gst_event_unref (event);
|
||||||
|
@ -794,40 +790,14 @@ gst_rtp_mux_sink_event (GstPad * pad, GstEvent * event)
|
||||||
if (forward)
|
if (forward)
|
||||||
ret = gst_pad_push_event (mux->srcpad, event);
|
ret = gst_pad_push_event (mux->srcpad, event);
|
||||||
|
|
||||||
gst_object_unref (mux);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
clear_segment (gpointer data, gpointer user_data)
|
|
||||||
{
|
|
||||||
GstPad *pad = data;
|
|
||||||
GstRTPMux *mux = user_data;
|
|
||||||
GstRTPMuxPadPrivate *padpriv;
|
|
||||||
|
|
||||||
GST_OBJECT_LOCK (mux);
|
|
||||||
padpriv = gst_pad_get_element_private (pad);
|
|
||||||
if (padpriv)
|
|
||||||
gst_segment_init (&padpriv->segment, GST_FORMAT_UNDEFINED);
|
|
||||||
GST_OBJECT_UNLOCK (mux);
|
|
||||||
|
|
||||||
gst_object_unref (pad);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_rtp_mux_ready_to_paused (GstRTPMux * rtp_mux)
|
gst_rtp_mux_ready_to_paused (GstRTPMux * rtp_mux)
|
||||||
{
|
{
|
||||||
GstIterator *iter;
|
|
||||||
|
|
||||||
iter = gst_element_iterate_sink_pads (GST_ELEMENT (rtp_mux));
|
|
||||||
while (gst_iterator_foreach (iter, clear_segment, rtp_mux) ==
|
|
||||||
GST_ITERATOR_RESYNC);
|
|
||||||
gst_iterator_free (iter);
|
|
||||||
|
|
||||||
GST_OBJECT_LOCK (rtp_mux);
|
GST_OBJECT_LOCK (rtp_mux);
|
||||||
rtp_mux->segment_pending = TRUE;
|
|
||||||
|
|
||||||
if (rtp_mux->ssrc == -1)
|
if (rtp_mux->ssrc == -1)
|
||||||
rtp_mux->current_ssrc = g_random_int ();
|
rtp_mux->current_ssrc = g_random_int ();
|
||||||
|
@ -871,7 +841,8 @@ gst_rtp_mux_change_state (GstElement * element, GstStateChange transition)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
|
return GST_ELEMENT_CLASS (gst_rtp_mux_parent_class)->change_state (element,
|
||||||
|
transition);
|
||||||
}
|
}
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#define __GST_RTP_MUX_H__
|
#define __GST_RTP_MUX_H__
|
||||||
|
|
||||||
#include <gst/gst.h>
|
#include <gst/gst.h>
|
||||||
|
#include <gst/rtp/gstrtpbuffer.h>
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
#define GST_TYPE_RTP_MUX (gst_rtp_mux_get_type())
|
#define GST_TYPE_RTP_MUX (gst_rtp_mux_get_type())
|
||||||
|
@ -83,7 +84,7 @@ struct _GstRTPMuxClass
|
||||||
GstElementClass parent_class;
|
GstElementClass parent_class;
|
||||||
|
|
||||||
gboolean (*accept_buffer_locked) (GstRTPMux *rtp_mux,
|
gboolean (*accept_buffer_locked) (GstRTPMux *rtp_mux,
|
||||||
GstRTPMuxPadPrivate * padpriv, GstBuffer * buffer);
|
GstRTPMuxPadPrivate * padpriv, GstRTPBuffer * buffer);
|
||||||
|
|
||||||
gboolean (*src_event) (GstRTPMux *rtp_mux, GstEvent *event);
|
gboolean (*src_event) (GstRTPMux *rtp_mux, GstEvent *event);
|
||||||
};
|
};
|
||||||
|
|
|
@ -38,32 +38,43 @@ static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
|
||||||
|
|
||||||
typedef void (*check_cb) (GstPad * pad, int i);
|
typedef void (*check_cb) (GstPad * pad, int i);
|
||||||
|
|
||||||
static GstCaps *
|
|
||||||
getcaps_func (GstPad * pad)
|
|
||||||
{
|
|
||||||
GstCaps **caps = g_object_get_data (G_OBJECT (pad), "caps");
|
|
||||||
|
|
||||||
fail_unless (caps != NULL && *caps != NULL);
|
|
||||||
|
|
||||||
return gst_caps_ref (*caps);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
setcaps_func (GstPad * pad, GstCaps * caps)
|
query_func (GstPad * pad, GstObject * noparent, GstQuery * query)
|
||||||
{
|
{
|
||||||
GstCaps **caps2 = g_object_get_data (G_OBJECT (pad), "caps");
|
switch (GST_QUERY_TYPE (query)) {
|
||||||
|
case GST_QUERY_CAPS:
|
||||||
|
{
|
||||||
|
GstCaps **caps = g_object_get_data (G_OBJECT (pad), "caps");
|
||||||
|
|
||||||
fail_unless (caps2 != NULL && *caps2 != NULL);
|
fail_unless (caps != NULL && *caps != NULL);
|
||||||
|
gst_query_set_caps_result (query, *caps);
|
||||||
fail_unless (gst_caps_is_equal (caps, *caps2));
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
event_func (GstPad * pad, GstEvent * event)
|
event_func (GstPad * pad, GstObject * noparent, GstEvent * event)
|
||||||
{
|
{
|
||||||
gst_event_unref (event);
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
|
case GST_EVENT_CAPS:
|
||||||
|
{
|
||||||
|
GstCaps *caps;
|
||||||
|
GstCaps **caps2 = g_object_get_data (G_OBJECT (pad), "caps");
|
||||||
|
|
||||||
|
gst_event_parse_caps (event, &caps);
|
||||||
|
fail_unless (caps2 != NULL && *caps2 != NULL);
|
||||||
|
fail_unless (gst_caps_is_equal (caps, *caps2));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
gst_event_unref (event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -83,7 +94,7 @@ test_basic (const gchar * elem_name, const gchar * sink2, int count,
|
||||||
GstCaps *src2caps = NULL;
|
GstCaps *src2caps = NULL;
|
||||||
GstCaps *sinkcaps = NULL;
|
GstCaps *sinkcaps = NULL;
|
||||||
GstCaps *caps;
|
GstCaps *caps;
|
||||||
GstEvent *newsegment;
|
GstSegment segment;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
rtpmux = gst_check_setup_element (elem_name);
|
rtpmux = gst_check_setup_element (elem_name);
|
||||||
|
@ -98,10 +109,9 @@ test_basic (const gchar * elem_name, const gchar * sink2, int count,
|
||||||
src2 = gst_pad_new_from_static_template (&srctemplate, "src");
|
src2 = gst_pad_new_from_static_template (&srctemplate, "src");
|
||||||
fail_unless (gst_pad_link (src1, reqpad1) == GST_PAD_LINK_OK);
|
fail_unless (gst_pad_link (src1, reqpad1) == GST_PAD_LINK_OK);
|
||||||
fail_unless (gst_pad_link (src2, reqpad2) == GST_PAD_LINK_OK);
|
fail_unless (gst_pad_link (src2, reqpad2) == GST_PAD_LINK_OK);
|
||||||
gst_pad_set_getcaps_function (src1, getcaps_func);
|
gst_pad_set_query_function (src1, query_func);
|
||||||
gst_pad_set_getcaps_function (src2, getcaps_func);
|
gst_pad_set_query_function (src2, query_func);
|
||||||
gst_pad_set_getcaps_function (sink, getcaps_func);
|
gst_pad_set_query_function (sink, query_func);
|
||||||
gst_pad_set_setcaps_function (sink, setcaps_func);
|
|
||||||
gst_pad_set_event_function (sink, event_func);
|
gst_pad_set_event_function (sink, event_func);
|
||||||
g_object_set_data (G_OBJECT (src1), "caps", &src1caps);
|
g_object_set_data (G_OBJECT (src1), "caps", &src1caps);
|
||||||
g_object_set_data (G_OBJECT (src2), "caps", &src2caps);
|
g_object_set_data (G_OBJECT (src2), "caps", &src2caps);
|
||||||
|
@ -114,12 +124,12 @@ test_basic (const gchar * elem_name, const gchar * sink2, int count,
|
||||||
sinkcaps = gst_caps_new_simple ("application/x-rtp",
|
sinkcaps = gst_caps_new_simple ("application/x-rtp",
|
||||||
"clock-rate", G_TYPE_INT, 3, "ssrc", G_TYPE_UINT, 13, NULL);
|
"clock-rate", G_TYPE_INT, 3, "ssrc", G_TYPE_UINT, 13, NULL);
|
||||||
|
|
||||||
caps = gst_pad_peer_get_caps (src1);
|
caps = gst_pad_peer_query_caps (src1, NULL);
|
||||||
fail_unless (gst_caps_is_empty (caps));
|
fail_unless (gst_caps_is_empty (caps));
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
gst_caps_set_simple (src2caps, "clock-rate", G_TYPE_INT, 3, NULL);
|
gst_caps_set_simple (src2caps, "clock-rate", G_TYPE_INT, 3, NULL);
|
||||||
caps = gst_pad_peer_get_caps (src1);
|
caps = gst_pad_peer_query_caps (src1, NULL);
|
||||||
fail_unless (gst_caps_is_equal (caps, sinkcaps));
|
fail_unless (gst_caps_is_equal (caps, sinkcaps));
|
||||||
gst_caps_unref (caps);
|
gst_caps_unref (caps);
|
||||||
|
|
||||||
|
@ -141,27 +151,33 @@ test_basic (const gchar * elem_name, const gchar * sink2, int count,
|
||||||
"ssrc", G_TYPE_UINT, 66, NULL);
|
"ssrc", G_TYPE_UINT, 66, NULL);
|
||||||
fail_unless (gst_pad_set_caps (src1, caps));
|
fail_unless (gst_pad_set_caps (src1, caps));
|
||||||
|
|
||||||
newsegment = gst_event_new_new_segment (FALSE, 1, GST_FORMAT_TIME, 100000,
|
gst_segment_init (&segment, GST_FORMAT_TIME);
|
||||||
-1, 0);
|
segment.start = 100000;
|
||||||
fail_unless (gst_pad_push_event (src1, newsegment));
|
fail_unless (gst_pad_push_event (src1, gst_event_new_segment (&segment)));
|
||||||
newsegment = gst_event_new_new_segment (FALSE, 1, GST_FORMAT_TIME, 0, -1, 0);
|
segment.start = 0;
|
||||||
fail_unless (gst_pad_push_event (src2, newsegment));
|
fail_unless (gst_pad_push_event (src2, gst_event_new_segment (&segment)));
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
for (i = 0; i < count; i++) {
|
||||||
|
GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
|
||||||
|
|
||||||
inbuf = gst_rtp_buffer_new_allocate (10, 0, 0);
|
inbuf = gst_rtp_buffer_new_allocate (10, 0, 0);
|
||||||
GST_BUFFER_TIMESTAMP (inbuf) = i * 1000 + 100000;
|
GST_BUFFER_PTS (inbuf) = i * 1000 + 100000;
|
||||||
GST_BUFFER_DURATION (inbuf) = 1000;
|
GST_BUFFER_DURATION (inbuf) = 1000;
|
||||||
gst_buffer_set_caps (inbuf, caps);
|
|
||||||
gst_rtp_buffer_set_version (inbuf, 2);
|
gst_rtp_buffer_map (inbuf, GST_MAP_WRITE, &rtpbuffer);
|
||||||
gst_rtp_buffer_set_payload_type (inbuf, 98);
|
|
||||||
gst_rtp_buffer_set_ssrc (inbuf, 44);
|
gst_rtp_buffer_set_version (&rtpbuffer, 2);
|
||||||
gst_rtp_buffer_set_timestamp (inbuf, 200 + i);
|
gst_rtp_buffer_set_payload_type (&rtpbuffer, 98);
|
||||||
gst_rtp_buffer_set_seq (inbuf, 2000 + i);
|
gst_rtp_buffer_set_ssrc (&rtpbuffer, 44);
|
||||||
|
gst_rtp_buffer_set_timestamp (&rtpbuffer, 200 + i);
|
||||||
|
gst_rtp_buffer_set_seq (&rtpbuffer, 2000 + i);
|
||||||
|
gst_rtp_buffer_unmap (&rtpbuffer);
|
||||||
fail_unless (gst_pad_push (src1, inbuf) == GST_FLOW_OK);
|
fail_unless (gst_pad_push (src1, inbuf) == GST_FLOW_OK);
|
||||||
|
|
||||||
if (buffers)
|
if (buffers)
|
||||||
fail_unless (GST_BUFFER_TIMESTAMP (buffers->data) == i * 1000, "%lld",
|
fail_unless (GST_BUFFER_PTS (buffers->data) == i * 1000, "%lld",
|
||||||
GST_BUFFER_TIMESTAMP (buffers->data));
|
GST_BUFFER_PTS (buffers->data));
|
||||||
|
|
||||||
cb (src2, i);
|
cb (src2, i);
|
||||||
|
|
||||||
|
@ -195,11 +211,15 @@ test_basic (const gchar * elem_name, const gchar * sink2, int count,
|
||||||
static void
|
static void
|
||||||
basic_check_cb (GstPad * pad, int i)
|
basic_check_cb (GstPad * pad, int i)
|
||||||
{
|
{
|
||||||
|
GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
|
||||||
fail_unless (buffers && g_list_length (buffers) == 1);
|
fail_unless (buffers && g_list_length (buffers) == 1);
|
||||||
fail_unless (gst_rtp_buffer_get_ssrc (buffers->data) == 55);
|
|
||||||
fail_unless (gst_rtp_buffer_get_timestamp (buffers->data) ==
|
gst_rtp_buffer_map (buffers->data, GST_MAP_READ, &rtpbuffer);
|
||||||
|
fail_unless (gst_rtp_buffer_get_ssrc (&rtpbuffer) == 55);
|
||||||
|
fail_unless (gst_rtp_buffer_get_timestamp (&rtpbuffer) ==
|
||||||
200 - 57 + 1000 + i);
|
200 - 57 + 1000 + i);
|
||||||
fail_unless (gst_rtp_buffer_get_seq (buffers->data) == 100 + 1 + i);
|
fail_unless (gst_rtp_buffer_get_seq (&rtpbuffer) == 100 + 1 + i);
|
||||||
|
gst_rtp_buffer_unmap (&rtpbuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -225,20 +245,26 @@ lock_check_cb (GstPad * pad, int i)
|
||||||
if (i % 2) {
|
if (i % 2) {
|
||||||
fail_unless (buffers == NULL);
|
fail_unless (buffers == NULL);
|
||||||
} else {
|
} else {
|
||||||
|
GstRTPBuffer rtpbuffer = GST_RTP_BUFFER_INIT;
|
||||||
|
|
||||||
fail_unless (buffers && g_list_length (buffers) == 1);
|
fail_unless (buffers && g_list_length (buffers) == 1);
|
||||||
fail_unless (gst_rtp_buffer_get_ssrc (buffers->data) == 55);
|
gst_rtp_buffer_map (buffers->data, GST_MAP_READ, &rtpbuffer);
|
||||||
fail_unless (gst_rtp_buffer_get_timestamp (buffers->data) ==
|
fail_unless (gst_rtp_buffer_get_ssrc (&rtpbuffer) == 55);
|
||||||
|
fail_unless (gst_rtp_buffer_get_timestamp (&rtpbuffer) ==
|
||||||
200 - 57 + 1000 + i);
|
200 - 57 + 1000 + i);
|
||||||
fail_unless (gst_rtp_buffer_get_seq (buffers->data) == 100 + 1 + i);
|
fail_unless (gst_rtp_buffer_get_seq (&rtpbuffer) == 100 + 1 + i);
|
||||||
|
gst_rtp_buffer_unmap (&rtpbuffer);
|
||||||
|
|
||||||
inbuf = gst_rtp_buffer_new_allocate (10, 0, 0);
|
inbuf = gst_rtp_buffer_new_allocate (10, 0, 0);
|
||||||
GST_BUFFER_TIMESTAMP (inbuf) = i * 1000 + 500;
|
GST_BUFFER_PTS (inbuf) = i * 1000 + 500;
|
||||||
GST_BUFFER_DURATION (inbuf) = 1000;
|
GST_BUFFER_DURATION (inbuf) = 1000;
|
||||||
gst_rtp_buffer_set_version (inbuf, 2);
|
gst_rtp_buffer_map (inbuf, GST_MAP_WRITE, &rtpbuffer);
|
||||||
gst_rtp_buffer_set_payload_type (inbuf, 98);
|
gst_rtp_buffer_set_version (&rtpbuffer, 2);
|
||||||
gst_rtp_buffer_set_ssrc (inbuf, 44);
|
gst_rtp_buffer_set_payload_type (&rtpbuffer, 98);
|
||||||
gst_rtp_buffer_set_timestamp (inbuf, 200 + i);
|
gst_rtp_buffer_set_ssrc (&rtpbuffer, 44);
|
||||||
gst_rtp_buffer_set_seq (inbuf, 2000 + i);
|
gst_rtp_buffer_set_timestamp (&rtpbuffer, 200 + i);
|
||||||
|
gst_rtp_buffer_set_seq (&rtpbuffer, 2000 + i);
|
||||||
|
gst_rtp_buffer_unmap (&rtpbuffer);
|
||||||
fail_unless (gst_pad_push (pad, inbuf) == GST_FLOW_OK);
|
fail_unless (gst_pad_push (pad, inbuf) == GST_FLOW_OK);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue