gdouble play_scale;
gboolean discont;
- GstClockTime timestamp;
+ GstClockTime pts;
+ GstClockTime dts;
GstClockTime duration;
guint32 next_seqnum;
static GstStateChangeReturn gst_base_rtp_depayload_change_state (GstElement *
element, GstStateChange transition);
-static void gst_base_rtp_depayload_set_gst_timestamp
- (GstBaseRTPDepayload * filter, guint32 rtptime, GstBuffer * buf);
static gboolean gst_base_rtp_depayload_packet_lost (GstBaseRTPDepayload *
filter, GstEvent * event);
static gboolean gst_base_rtp_depayload_handle_event (GstBaseRTPDepayload *
gstelement_class->change_state = gst_base_rtp_depayload_change_state;
- klass->set_gst_timestamp = gst_base_rtp_depayload_set_gst_timestamp;
klass->packet_lost = gst_base_rtp_depayload_packet_lost;
klass->handle_event = gst_base_rtp_depayload_handle_event;
GstBaseRTPDepayloadClass *bclass;
GstFlowReturn ret = GST_FLOW_OK;
GstBuffer *out_buf;
- GstClockTime timestamp;
+ GstClockTime pts, dts;
guint16 seqnum;
guint32 rtptime;
gboolean discont;
if (!priv->discont)
priv->discont = GST_BUFFER_IS_DISCONT (in);
- timestamp = GST_BUFFER_TIMESTAMP (in);
+ pts = GST_BUFFER_PTS (in);
+ dts = GST_BUFFER_DTS (in);
/* convert to running_time and save the timestamp, this is the timestamp
* we put on outgoing buffers. */
- timestamp = gst_segment_to_running_time (&filter->segment, GST_FORMAT_TIME,
- timestamp);
- priv->timestamp = timestamp;
+ pts = gst_segment_to_running_time (&filter->segment, GST_FORMAT_TIME, pts);
+ dts = gst_segment_to_running_time (&filter->segment, GST_FORMAT_TIME, dts);
+ priv->pts = pts;
+ priv->dts = dts;
priv->duration = GST_BUFFER_DURATION (in);
gst_rtp_buffer_map (in, GST_MAP_READ, &rtp);
discont = FALSE;
- GST_LOG_OBJECT (filter, "discont %d, seqnum %u, rtptime %u, timestamp %"
- GST_TIME_FORMAT, priv->discont, seqnum, rtptime,
- GST_TIME_ARGS (timestamp));
+ GST_LOG_OBJECT (filter, "discont %d, seqnum %u, rtptime %u, pts %"
+ GST_TIME_FORMAT ", dts %" GST_TIME_FORMAT, priv->discont, seqnum, rtptime,
+ GST_TIME_ARGS (pts), GST_TIME_ARGS (dts));
/* Check seqnum. This is a very simple check that makes sure that the seqnums
* are striclty increasing, dropping anything that is out of the ordinary. We
/* let's send it out to processing */
out_buf = bclass->process (filter, in);
if (out_buf) {
- /* we pass rtptime as backward compatibility, in reality, the incomming
- * buffer timestamp is always applied to the outgoing packet. */
- ret = gst_base_rtp_depayload_push_ts (filter, rtptime, out_buf);
+ ret = gst_base_rtp_depayload_push (filter, out_buf);
}
gst_buffer_unref (in);
{
GstBaseRTPDepayload *depayload;
GstBaseRTPDepayloadClass *bclass;
- gboolean do_ts;
- gboolean rtptime;
} HeaderData;
static gboolean
set_headers (GstBuffer ** buffer, guint idx, HeaderData * data)
{
GstBaseRTPDepayload *depayload = data->depayload;
+ GstBaseRTPDepayloadPrivate *priv = depayload->priv;
+ GstClockTime pts, dts, duration;
*buffer = gst_buffer_make_writable (*buffer);
- /* set the timestamp if we must and can */
- if (data->bclass->set_gst_timestamp && data->do_ts)
- data->bclass->set_gst_timestamp (depayload, data->rtptime, *buffer);
+ pts = GST_BUFFER_PTS (*buffer);
+ dts = GST_BUFFER_DTS (*buffer);
+ duration = GST_BUFFER_DURATION (*buffer);
+
+ /* apply last incomming timestamp and duration to outgoing buffer if
+ * not otherwise set. */
+ if (!GST_CLOCK_TIME_IS_VALID (pts))
+ GST_BUFFER_PTS (*buffer) = priv->pts;
+ if (!GST_CLOCK_TIME_IS_VALID (dts))
+ GST_BUFFER_DTS (*buffer) = priv->dts;
+ if (!GST_CLOCK_TIME_IS_VALID (duration))
+ GST_BUFFER_DURATION (*buffer) = priv->duration;
if (G_UNLIKELY (depayload->priv->discont)) {
GST_LOG_OBJECT (depayload, "Marking DISCONT on output buffer");
depayload->priv->discont = FALSE;
}
+ /* make sure we only set the timestamp on the first packet */
+ priv->pts = GST_CLOCK_TIME_NONE;
+ priv->dts = GST_CLOCK_TIME_NONE;
+ priv->duration = GST_CLOCK_TIME_NONE;
+
return TRUE;
}
static GstFlowReturn
gst_base_rtp_depayload_prepare_push (GstBaseRTPDepayload * filter,
- gboolean do_ts, guint32 rtptime, gboolean is_list, gpointer obj)
+ gboolean is_list, gpointer obj)
{
HeaderData data;
data.depayload = filter;
- data.rtptime = rtptime;
- data.do_ts = do_ts;
data.bclass = GST_BASE_RTP_DEPAYLOAD_GET_CLASS (filter);
if (is_list) {
}
/**
- * gst_base_rtp_depayload_push_ts:
- * @filter: a #GstBaseRTPDepayload
- * @timestamp: an RTP timestamp to apply
- * @out_buf: a #GstBuffer
- *
- * Push @out_buf to the peer of @filter. This function takes ownership of
- * @out_buf.
- *
- * Unlike gst_base_rtp_depayload_push(), this function will by default apply
- * the last incomming timestamp on the outgoing buffer when it didn't have a
- * timestamp already. The set_get_timestamp vmethod can be overwritten to change
- * this behaviour (and take, for example, @timestamp into account).
- *
- * Returns: a #GstFlowReturn.
- */
-GstFlowReturn
-gst_base_rtp_depayload_push_ts (GstBaseRTPDepayload * filter, guint32 timestamp,
- GstBuffer * out_buf)
-{
- GstFlowReturn res;
-
- res =
- gst_base_rtp_depayload_prepare_push (filter, TRUE, timestamp, FALSE,
- &out_buf);
-
- if (G_LIKELY (res == GST_FLOW_OK))
- res = gst_pad_push (filter->srcpad, out_buf);
- else
- gst_buffer_unref (out_buf);
-
- return res;
-}
-
-/**
* gst_base_rtp_depayload_push:
* @filter: a #GstBaseRTPDepayload
* @out_buf: a #GstBuffer
* Push @out_buf to the peer of @filter. This function takes ownership of
* @out_buf.
*
- * Unlike gst_base_rtp_depayload_push_ts(), this function will not apply
- * any timestamp on the outgoing buffer. Subclasses should therefore timestamp
- * outgoing buffers themselves.
+ * This function will by default apply the last incomming timestamp on
+ * the outgoing buffer when it didn't have a timestamp already.
*
* Returns: a #GstFlowReturn.
*/
{
GstFlowReturn res;
- res = gst_base_rtp_depayload_prepare_push (filter, FALSE, 0, FALSE, &out_buf);
+ res = gst_base_rtp_depayload_prepare_push (filter, FALSE, &out_buf);
if (G_LIKELY (res == GST_FLOW_OK))
res = gst_pad_push (filter->srcpad, out_buf);
{
GstFlowReturn res;
- res = gst_base_rtp_depayload_prepare_push (filter, TRUE, 0, TRUE, &out_list);
+ res = gst_base_rtp_depayload_prepare_push (filter, TRUE, &out_list);
if (G_LIKELY (res == GST_FLOW_OK))
res = gst_pad_push_list (filter->srcpad, out_list);
return gst_pad_push_event (filter->srcpad, sevent);
}
-static void
-gst_base_rtp_depayload_set_gst_timestamp (GstBaseRTPDepayload * filter,
- guint32 rtptime, GstBuffer * buf)
-{
- GstBaseRTPDepayloadPrivate *priv;
- GstClockTime timestamp, duration;
-
- priv = filter->priv;
-
- timestamp = GST_BUFFER_TIMESTAMP (buf);
- duration = GST_BUFFER_DURATION (buf);
-
- /* apply last incomming timestamp and duration to outgoing buffer if
- * not otherwise set. */
- if (!GST_CLOCK_TIME_IS_VALID (timestamp))
- GST_BUFFER_TIMESTAMP (buf) = priv->timestamp;
- if (!GST_CLOCK_TIME_IS_VALID (duration))
- GST_BUFFER_DURATION (buf) = priv->duration;
-}
-
static GstStateChangeReturn
gst_base_rtp_depayload_change_state (GstElement * element,
GstStateChange transition)
PROP_LAST
};
-static void gst_basertppayload_class_init (GstBaseRTPPayloadClass * klass);
-static void gst_basertppayload_base_init (GstBaseRTPPayloadClass * klass);
-static void gst_basertppayload_init (GstBaseRTPPayload * basertppayload,
+static void gst_base_rtp_payload_class_init (GstBaseRTPPayloadClass * klass);
+static void gst_base_rtp_payload_init (GstBaseRTPPayload * basertppayload,
gpointer g_class);
-static void gst_basertppayload_finalize (GObject * object);
+static void gst_base_rtp_payload_finalize (GObject * object);
-static GstCaps *gst_basertppayload_sink_getcaps (GstPad * pad,
+static GstCaps *gst_base_rtp_payload_sink_getcaps (GstPad * pad,
GstCaps * filter);
-static gboolean gst_basertppayload_event_default (GstBaseRTPPayload *
+static gboolean gst_base_rtp_payload_event_default (GstBaseRTPPayload *
basertppayload, GstEvent * event);
-static gboolean gst_basertppayload_event (GstPad * pad, GstEvent * event);
-static GstFlowReturn gst_basertppayload_chain (GstPad * pad,
+static gboolean gst_base_rtp_payload_event (GstPad * pad, GstEvent * event);
+static GstFlowReturn gst_base_rtp_payload_chain (GstPad * pad,
GstBuffer * buffer);
+static GstCaps *gst_base_rtp_payload_getcaps_default (GstBaseRTPPayload *
+ basertppayload, GstPad * pad, GstCaps * filter);
-static void gst_basertppayload_set_property (GObject * object, guint prop_id,
+static void gst_base_rtp_payload_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec);
-static void gst_basertppayload_get_property (GObject * object, guint prop_id,
+static void gst_base_rtp_payload_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec);
-static GstStateChangeReturn gst_basertppayload_change_state (GstElement *
+static GstStateChangeReturn gst_base_rtp_payload_change_state (GstElement *
element, GstStateChange transition);
static GstElementClass *parent_class = NULL;
/* FIXME 0.11: API should be changed to gst_base_typ_payload_xyz */
GType
-gst_basertppayload_get_type (void)
+gst_base_rtp_payload_get_type (void)
{
static GType basertppayload_type = 0;
if (g_once_init_enter ((gsize *) & basertppayload_type)) {
static const GTypeInfo basertppayload_info = {
sizeof (GstBaseRTPPayloadClass),
- (GBaseInitFunc) gst_basertppayload_base_init,
NULL,
- (GClassInitFunc) gst_basertppayload_class_init,
+ NULL,
+ (GClassInitFunc) gst_base_rtp_payload_class_init,
NULL,
NULL,
sizeof (GstBaseRTPPayload),
0,
- (GInstanceInitFunc) gst_basertppayload_init,
+ (GInstanceInitFunc) gst_base_rtp_payload_init,
};
g_once_init_leave ((gsize *) & basertppayload_type,
}
static void
-gst_basertppayload_base_init (GstBaseRTPPayloadClass * klass)
-{
-}
-
-static void
-gst_basertppayload_class_init (GstBaseRTPPayloadClass * klass)
+gst_base_rtp_payload_class_init (GstBaseRTPPayloadClass * klass)
{
GObjectClass *gobject_class;
GstElementClass *gstelement_class;
parent_class = g_type_class_peek_parent (klass);
- gobject_class->finalize = gst_basertppayload_finalize;
+ gobject_class->finalize = gst_base_rtp_payload_finalize;
- gobject_class->set_property = gst_basertppayload_set_property;
- gobject_class->get_property = gst_basertppayload_get_property;
+ gobject_class->set_property = gst_base_rtp_payload_set_property;
+ gobject_class->get_property = gst_base_rtp_payload_get_property;
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_MTU,
g_param_spec_uint ("mtu", "MTU",
0, G_MAXINT64, DEFAULT_PTIME_MULTIPLE,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
- gstelement_class->change_state = gst_basertppayload_change_state;
+ gstelement_class->change_state = gst_base_rtp_payload_change_state;
- klass->handle_event = gst_basertppayload_event_default;
+ klass->get_caps = gst_base_rtp_payload_getcaps_default;
+ klass->handle_event = gst_base_rtp_payload_event_default;
GST_DEBUG_CATEGORY_INIT (basertppayload_debug, "basertppayload", 0,
"Base class for RTP Payloaders");
}
static void
-gst_basertppayload_init (GstBaseRTPPayload * basertppayload, gpointer g_class)
+gst_base_rtp_payload_init (GstBaseRTPPayload * basertppayload, gpointer g_class)
{
GstPadTemplate *templ;
GstBaseRTPPayloadPrivate *priv;
basertppayload->sinkpad = gst_pad_new_from_template (templ, "sink");
gst_pad_set_getcaps_function (basertppayload->sinkpad,
- gst_basertppayload_sink_getcaps);
+ gst_base_rtp_payload_sink_getcaps);
gst_pad_set_event_function (basertppayload->sinkpad,
- gst_basertppayload_event);
+ gst_base_rtp_payload_event);
gst_pad_set_chain_function (basertppayload->sinkpad,
- gst_basertppayload_chain);
+ gst_base_rtp_payload_chain);
gst_element_add_pad (GST_ELEMENT (basertppayload), basertppayload->sinkpad);
basertppayload->mtu = DEFAULT_MTU;
}
static void
-gst_basertppayload_finalize (GObject * object)
+gst_base_rtp_payload_finalize (GObject * object)
{
GstBaseRTPPayload *basertppayload;
}
static GstCaps *
-gst_basertppayload_sink_getcaps (GstPad * pad, GstCaps * filter)
+gst_base_rtp_payload_getcaps_default (GstBaseRTPPayload * basertppayload,
+ GstPad * pad, GstCaps * filter)
+{
+ GstCaps *caps;
+
+ caps = GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad));
+ GST_DEBUG_OBJECT (pad,
+ "using pad template %p with caps %p %" GST_PTR_FORMAT,
+ GST_PAD_PAD_TEMPLATE (pad), caps, caps);
+
+ if (filter)
+ caps = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+ else
+ caps = gst_caps_ref (caps);
+
+ return caps;
+}
+
+static GstCaps *
+gst_base_rtp_payload_sink_getcaps (GstPad * pad, GstCaps * filter)
{
GstBaseRTPPayload *basertppayload;
GstBaseRTPPayloadClass *basertppayload_class;
if (basertppayload_class->get_caps)
caps = basertppayload_class->get_caps (basertppayload, pad, filter);
- if (!caps) {
- caps = GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad));
- GST_DEBUG_OBJECT (pad,
- "using pad template %p with caps %p %" GST_PTR_FORMAT,
- GST_PAD_PAD_TEMPLATE (pad), caps, caps);
-
- if (filter)
- caps = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
- else
- caps = gst_caps_ref (caps);
- }
-
gst_object_unref (basertppayload);
return caps;
}
static gboolean
-gst_basertppayload_event_default (GstBaseRTPPayload * basertppayload,
+gst_base_rtp_payload_event_default (GstBaseRTPPayload * basertppayload,
GstEvent * event)
{
gboolean res = FALSE;
}
static gboolean
-gst_basertppayload_event (GstPad * pad, GstEvent * event)
+gst_base_rtp_payload_event (GstPad * pad, GstEvent * event)
{
GstBaseRTPPayload *basertppayload;
GstBaseRTPPayloadClass *basertppayload_class;
static GstFlowReturn
-gst_basertppayload_chain (GstPad * pad, GstBuffer * buffer)
+gst_base_rtp_payload_chain (GstPad * pad, GstBuffer * buffer)
{
GstBaseRTPPayload *basertppayload;
GstBaseRTPPayloadClass *basertppayload_class;
}
/**
- * gst_basertppayload_set_options:
+ * gst_base_rtp_payload_set_options:
* @payload: a #GstBaseRTPPayload
* @media: the media type (typically "audio" or "video")
* @dynamic: if the payload type is dynamic
*
* Set the rtp options of the payloader. These options will be set in the caps
* of the payloader. Subclasses must call this method before calling
- * gst_basertppayload_push() or gst_basertppayload_set_outcaps().
+ * gst_base_rtp_payload_push() or gst_base_rtp_payload_set_outcaps().
*/
void
-gst_basertppayload_set_options (GstBaseRTPPayload * payload,
+gst_base_rtp_payload_set_options (GstBaseRTPPayload * payload,
const gchar * media, gboolean dynamic, const gchar * encoding_name,
guint32 clock_rate)
{
}
/**
- * gst_basertppayload_set_outcaps:
+ * gst_base_rtp_payload_set_outcaps:
* @payload: a #GstBaseRTPPayload
* @fieldname: the first field name or %NULL
* @...: field values
* Returns: %TRUE if the caps could be set.
*/
gboolean
-gst_basertppayload_set_outcaps (GstBaseRTPPayload * payload,
+gst_base_rtp_payload_set_outcaps (GstBaseRTPPayload * payload,
const gchar * fieldname, ...)
{
GstCaps *srccaps, *peercaps;
}
/**
- * gst_basertppayload_is_filled:
+ * gst_base_rtp_payload_is_filled:
* @payload: a #GstBaseRTPPayload
* @size: the size of the packet
* @duration: the duration of the packet
* configured MTU or max_ptime.
*/
gboolean
-gst_basertppayload_is_filled (GstBaseRTPPayload * payload,
+gst_base_rtp_payload_is_filled (GstBaseRTPPayload * payload,
guint size, GstClockTime duration)
{
if (size > payload->mtu)
/* Updates the SSRC, payload type, seqnum and timestamp of the RTP buffer
* before the buffer is pushed. */
static GstFlowReturn
-gst_basertppayload_prepare_push (GstBaseRTPPayload * payload,
+gst_base_rtp_payload_prepare_push (GstBaseRTPPayload * payload,
gpointer obj, gboolean is_list)
{
GstBaseRTPPayloadPrivate *priv;
(is_list) ? -1 : gst_buffer_get_size (GST_BUFFER (obj)),
payload->seqnum, data.rtptime, GST_TIME_ARGS (data.timestamp));
- if (g_atomic_int_compare_and_exchange (&payload->
- priv->notified_first_timestamp, 1, 0)) {
+ if (g_atomic_int_compare_and_exchange (&payload->priv->
+ notified_first_timestamp, 1, 0)) {
g_object_notify (G_OBJECT (payload), "timestamp");
g_object_notify (G_OBJECT (payload), "seqnum");
}
}
/**
- * gst_basertppayload_push_list:
+ * gst_base_rtp_payload_push_list:
* @payload: a #GstBaseRTPPayload
* @list: a #GstBufferList
*
* Since: 0.10.24
*/
GstFlowReturn
-gst_basertppayload_push_list (GstBaseRTPPayload * payload, GstBufferList * list)
+gst_base_rtp_payload_push_list (GstBaseRTPPayload * payload,
+ GstBufferList * list)
{
GstFlowReturn res;
- res = gst_basertppayload_prepare_push (payload, list, TRUE);
+ res = gst_base_rtp_payload_prepare_push (payload, list, TRUE);
if (G_LIKELY (res == GST_FLOW_OK))
res = gst_pad_push_list (payload->srcpad, list);
}
/**
- * gst_basertppayload_push:
+ * gst_base_rtp_payload_push:
* @payload: a #GstBaseRTPPayload
* @buffer: a #GstBuffer
*
* Returns: a #GstFlowReturn.
*/
GstFlowReturn
-gst_basertppayload_push (GstBaseRTPPayload * payload, GstBuffer * buffer)
+gst_base_rtp_payload_push (GstBaseRTPPayload * payload, GstBuffer * buffer)
{
GstFlowReturn res;
- res = gst_basertppayload_prepare_push (payload, buffer, FALSE);
+ res = gst_base_rtp_payload_prepare_push (payload, buffer, FALSE);
if (G_LIKELY (res == GST_FLOW_OK))
res = gst_pad_push (payload->srcpad, buffer);
}
static void
-gst_basertppayload_set_property (GObject * object, guint prop_id,
+gst_base_rtp_payload_set_property (GObject * object, guint prop_id,
const GValue * value, GParamSpec * pspec)
{
GstBaseRTPPayload *basertppayload;
}
static void
-gst_basertppayload_get_property (GObject * object, guint prop_id,
+gst_base_rtp_payload_get_property (GObject * object, guint prop_id,
GValue * value, GParamSpec * pspec)
{
GstBaseRTPPayload *basertppayload;
}
static GstStateChangeReturn
-gst_basertppayload_change_state (GstElement * element,
+gst_base_rtp_payload_change_state (GstElement * element,
GstStateChange transition)
{
GstBaseRTPPayload *basertppayload;