"encoding-name = (string) SBC")
);
+enum
+{
+ PROP_0,
+ PROP_IGNORE_TIMESTAMPS,
+ PROP_LAST
+};
+
+#define DEFAULT_IGNORE_TIMESTAMPS FALSE
+
#define gst_rtp_sbc_depay_parent_class parent_class
G_DEFINE_TYPE (GstRtpSbcDepay, gst_rtp_sbc_depay, GST_TYPE_RTP_BASE_DEPAYLOAD);
+static void gst_rtp_sbc_depay_set_property (GObject * object,
+ guint prop_id, const GValue * value, GParamSpec * pspec);
+static void gst_rtp_sbc_depay_get_property (GObject * object,
+ guint prop_id, GValue * value, GParamSpec * pspec);
static void gst_rtp_sbc_depay_finalize (GObject * object);
static gboolean gst_rtp_sbc_depay_setcaps (GstRTPBaseDepayload * base,
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = gst_rtp_sbc_depay_finalize;
+ gobject_class->set_property = gst_rtp_sbc_depay_set_property;
+ gobject_class->get_property = gst_rtp_sbc_depay_get_property;
+
+ g_object_class_install_property (gobject_class, PROP_IGNORE_TIMESTAMPS,
+ g_param_spec_boolean ("ignore-timestamps", "Ignore Timestamps",
+ "Various statistics", DEFAULT_IGNORE_TIMESTAMPS,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
gstbasertpdepayload_class->set_caps = gst_rtp_sbc_depay_setcaps;
gstbasertpdepayload_class->process_rtp_packet = gst_rtp_sbc_depay_process;
gst_rtp_sbc_depay_init (GstRtpSbcDepay * rtpsbcdepay)
{
rtpsbcdepay->adapter = gst_adapter_new ();
+ rtpsbcdepay->stream_align =
+ gst_audio_stream_align_new (48000, 40 * GST_MSECOND, 1 * GST_SECOND);
+ rtpsbcdepay->ignore_timestamps = DEFAULT_IGNORE_TIMESTAMPS;
}
static void
{
GstRtpSbcDepay *depay = GST_RTP_SBC_DEPAY (object);
+ gst_audio_stream_align_free (depay->stream_align);
gst_object_unref (depay->adapter);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
+static void
+gst_rtp_sbc_depay_set_property (GObject * object,
+ guint prop_id, const GValue * value, GParamSpec * pspec)
+{
+ GstRtpSbcDepay *depay = GST_RTP_SBC_DEPAY (object);
+
+ switch (prop_id) {
+ case PROP_IGNORE_TIMESTAMPS:
+ depay->ignore_timestamps = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_rtp_sbc_depay_get_property (GObject * object,
+ guint prop_id, GValue * value, GParamSpec * pspec)
+{
+ GstRtpSbcDepay *depay = GST_RTP_SBC_DEPAY (object);
+
+ switch (prop_id) {
+ case PROP_IGNORE_TIMESTAMPS:
+ g_value_set_boolean (value, depay->ignore_timestamps);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
/* FIXME: This duplicates similar functionality rtpsbcpay, but there isn't a
* simple way to consolidate the two. This is best done by moving the function
* to the codec-utils library in gst-plugins-base when these elements move to
if (oldcaps)
gst_caps_unref (oldcaps);
+ /* Reset when the caps are changing */
+ gst_audio_stream_align_set_rate (depay->stream_align, depay->rate);
+
return TRUE;
bad_caps:
guint8 nframes;
guint8 *payload;
guint payload_len;
+ gint samples = 0;
+
+ GstClockTime timestamp;
GST_LOG_OBJECT (depay, "Got %" G_GSIZE_FORMAT " bytes",
gst_buffer_get_size (rtp->buffer));
goto bad_packet;
}
+ timestamp = GST_BUFFER_DTS_OR_PTS (rtp->buffer);
+ if (depay->ignore_timestamps && timestamp == GST_CLOCK_TIME_NONE) {
+ GstClockTime initial_timestamp;
+ guint64 n_samples;
+
+ initial_timestamp =
+ gst_audio_stream_align_get_timestamp_at_discont (depay->stream_align);
+ n_samples =
+ gst_audio_stream_align_get_samples_since_discont (depay->stream_align);
+
+ if (initial_timestamp == GST_CLOCK_TIME_NONE) {
+ GST_ERROR_OBJECT (depay,
+ "Can only ignore timestamps on streams without valid initial timestamp");
+ return NULL;
+ }
+
+ timestamp =
+ initial_timestamp + gst_util_uint64_scale (n_samples, GST_SECOND,
+ depay->rate);
+ }
+
payload = gst_rtp_buffer_get_payload (rtp);
payload_len = gst_rtp_buffer_get_payload_len (rtp);
gst_adapter_push (depay->adapter, data);
if (last) {
+ gint framelen, samples;
+ guint8 header[4];
+
data = gst_adapter_take_buffer (depay->adapter,
gst_adapter_available (depay->adapter));
gst_rtp_drop_non_audio_meta (depay, data);
- } else
- data = NULL;
+ if (gst_buffer_extract (data, 0, &header, 4) != 4 ||
+ gst_rtp_sbc_depay_get_params (depay, header,
+ payload_len, &framelen, &samples) < 0) {
+ gst_buffer_unref (data);
+ goto bad_packet;
+ }
+ } else {
+ data = NULL;
+ }
} else {
/* !fragment */
- gint framelen, samples;
+ gint framelen;
GST_LOG_OBJECT (depay, "Got %d frames", nframes);
goto bad_packet;
}
+ samples *= nframes;
+
GST_LOG_OBJECT (depay, "Got payload of %d", payload_len);
if (nframes * framelen > (gint) payload_len) {
}
}
+ if (depay->ignore_timestamps) {
+ GstClockTime duration;
+
+ gst_audio_stream_align_process (depay->stream_align,
+ GST_BUFFER_IS_DISCONT (rtp->buffer), timestamp, samples, ×tamp,
+ &duration, NULL);
+
+ GST_BUFFER_PTS (data) = timestamp;
+ GST_BUFFER_DTS (data) = GST_CLOCK_TIME_NONE;
+ GST_BUFFER_DURATION (data) = duration;
+ }
+
out:
return data;