mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 01:30:38 +00:00
audiopayload: add support for buffer-lists
This commit is contained in:
parent
951b8516f1
commit
73d5ae1107
1 changed files with 143 additions and 12 deletions
|
@ -70,6 +70,15 @@
|
||||||
GST_DEBUG_CATEGORY_STATIC (basertpaudiopayload_debug);
|
GST_DEBUG_CATEGORY_STATIC (basertpaudiopayload_debug);
|
||||||
#define GST_CAT_DEFAULT (basertpaudiopayload_debug)
|
#define GST_CAT_DEFAULT (basertpaudiopayload_debug)
|
||||||
|
|
||||||
|
#define DEFAULT_BUFFER_LIST FALSE
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PROP_0,
|
||||||
|
PROP_BUFFER_LIST,
|
||||||
|
PROP_LAST
|
||||||
|
};
|
||||||
|
|
||||||
/* function to convert bytes to a time */
|
/* function to convert bytes to a time */
|
||||||
typedef GstClockTime (*GetBytesToTimeFunc) (GstBaseRTPAudioPayload * payload,
|
typedef GstClockTime (*GetBytesToTimeFunc) (GstBaseRTPAudioPayload * payload,
|
||||||
guint64 bytes);
|
guint64 bytes);
|
||||||
|
@ -101,6 +110,8 @@ struct _GstBaseRTPAudioPayloadPrivate
|
||||||
guint cached_ptime;
|
guint cached_ptime;
|
||||||
guint cached_min_length;
|
guint cached_min_length;
|
||||||
guint cached_max_length;
|
guint cached_max_length;
|
||||||
|
|
||||||
|
gboolean buffer_list;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,6 +121,11 @@ struct _GstBaseRTPAudioPayloadPrivate
|
||||||
|
|
||||||
static void gst_base_rtp_audio_payload_finalize (GObject * object);
|
static void gst_base_rtp_audio_payload_finalize (GObject * object);
|
||||||
|
|
||||||
|
static void gst_base_rtp_audio_payload_set_property (GObject * object,
|
||||||
|
guint prop_id, const GValue * value, GParamSpec * pspec);
|
||||||
|
static void gst_base_rtp_audio_payload_get_property (GObject * object,
|
||||||
|
guint prop_id, GValue * value, GParamSpec * pspec);
|
||||||
|
|
||||||
/* bytes to time functions */
|
/* bytes to time functions */
|
||||||
static GstClockTime
|
static GstClockTime
|
||||||
gst_base_rtp_audio_payload_frame_bytes_to_time (GstBaseRTPAudioPayload *
|
gst_base_rtp_audio_payload_frame_bytes_to_time (GstBaseRTPAudioPayload *
|
||||||
|
@ -165,6 +181,13 @@ gst_base_rtp_audio_payload_class_init (GstBaseRTPAudioPayloadClass * klass)
|
||||||
gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
|
gstbasertppayload_class = (GstBaseRTPPayloadClass *) klass;
|
||||||
|
|
||||||
gobject_class->finalize = gst_base_rtp_audio_payload_finalize;
|
gobject_class->finalize = gst_base_rtp_audio_payload_finalize;
|
||||||
|
gobject_class->set_property = gst_base_rtp_audio_payload_set_property;
|
||||||
|
gobject_class->get_property = gst_base_rtp_audio_payload_get_property;
|
||||||
|
|
||||||
|
g_object_class_install_property (G_OBJECT_CLASS (klass), PROP_BUFFER_LIST,
|
||||||
|
g_param_spec_boolean ("buffer-list", "Buffer List",
|
||||||
|
"Use Buffer Lists",
|
||||||
|
DEFAULT_BUFFER_LIST, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||||
|
|
||||||
gstelement_class->change_state =
|
gstelement_class->change_state =
|
||||||
GST_DEBUG_FUNCPTR (gst_base_rtp_payload_audio_change_state);
|
GST_DEBUG_FUNCPTR (gst_base_rtp_payload_audio_change_state);
|
||||||
|
@ -192,6 +215,8 @@ gst_base_rtp_audio_payload_init (GstBaseRTPAudioPayload * payload,
|
||||||
payload->sample_size = 0;
|
payload->sample_size = 0;
|
||||||
|
|
||||||
payload->priv->adapter = gst_adapter_new ();
|
payload->priv->adapter = gst_adapter_new ();
|
||||||
|
|
||||||
|
payload->priv->buffer_list = DEFAULT_BUFFER_LIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -206,6 +231,42 @@ gst_base_rtp_audio_payload_finalize (GObject * object)
|
||||||
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
|
GST_CALL_PARENT (G_OBJECT_CLASS, finalize, (object));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_base_rtp_audio_payload_set_property (GObject * object,
|
||||||
|
guint prop_id, const GValue * value, GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
GstBaseRTPAudioPayload *payload;
|
||||||
|
|
||||||
|
payload = GST_BASE_RTP_AUDIO_PAYLOAD (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_BUFFER_LIST:
|
||||||
|
payload->priv->buffer_list = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gst_base_rtp_audio_payload_get_property (GObject * object,
|
||||||
|
guint prop_id, GValue * value, GParamSpec * pspec)
|
||||||
|
{
|
||||||
|
GstBaseRTPAudioPayload *payload;
|
||||||
|
|
||||||
|
payload = GST_BASE_RTP_AUDIO_PAYLOAD (object);
|
||||||
|
|
||||||
|
switch (prop_id) {
|
||||||
|
case PROP_BUFFER_LIST:
|
||||||
|
g_value_set_boolean (value, payload->priv->buffer_list);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_base_rtp_audio_payload_set_frame_based:
|
* gst_base_rtp_audio_payload_set_frame_based:
|
||||||
* @basertpaudiopayload: a pointer to the element.
|
* @basertpaudiopayload: a pointer to the element.
|
||||||
|
@ -414,6 +475,68 @@ gst_base_rtp_audio_payload_push (GstBaseRTPAudioPayload * baseaudiopayload,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
gst_base_rtp_audio_payload_push_buffer (GstBaseRTPAudioPayload *
|
||||||
|
baseaudiopayload, GstBuffer * buffer)
|
||||||
|
{
|
||||||
|
GstBaseRTPPayload *basepayload;
|
||||||
|
GstBaseRTPAudioPayloadPrivate *priv;
|
||||||
|
GstBuffer *outbuf;
|
||||||
|
GstClockTime timestamp;
|
||||||
|
guint8 *payload;
|
||||||
|
guint payload_len;
|
||||||
|
GstFlowReturn ret;
|
||||||
|
|
||||||
|
priv = baseaudiopayload->priv;
|
||||||
|
basepayload = GST_BASE_RTP_PAYLOAD (baseaudiopayload);
|
||||||
|
|
||||||
|
payload_len = GST_BUFFER_SIZE (buffer);
|
||||||
|
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (baseaudiopayload, "Pushing %d bytes ts %" GST_TIME_FORMAT,
|
||||||
|
payload_len, GST_TIME_ARGS (timestamp));
|
||||||
|
|
||||||
|
if (priv->buffer_list) {
|
||||||
|
/* create just the RTP header buffer */
|
||||||
|
outbuf = gst_rtp_buffer_new_allocate (0, 0, 0);
|
||||||
|
} else {
|
||||||
|
/* create buffer to hold the payload */
|
||||||
|
outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set metadata */
|
||||||
|
gst_base_rtp_audio_payload_set_meta (baseaudiopayload, outbuf, payload_len,
|
||||||
|
timestamp);
|
||||||
|
|
||||||
|
if (priv->buffer_list) {
|
||||||
|
GstBufferList *list;
|
||||||
|
GstBufferListIterator *it;
|
||||||
|
|
||||||
|
list = gst_buffer_list_new ();
|
||||||
|
it = gst_buffer_list_iterate (list);
|
||||||
|
|
||||||
|
/* add both buffers to the buffer list */
|
||||||
|
gst_buffer_list_iterator_add_group (it);
|
||||||
|
gst_buffer_list_iterator_add (it, outbuf);
|
||||||
|
gst_buffer_list_iterator_add (it, buffer);
|
||||||
|
|
||||||
|
gst_buffer_list_iterator_free (it);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (baseaudiopayload, "Pushing list %p", list);
|
||||||
|
ret = gst_basertppayload_push_list (basepayload, list);
|
||||||
|
} else {
|
||||||
|
/* copy payload */
|
||||||
|
payload = gst_rtp_buffer_get_payload (outbuf);
|
||||||
|
memcpy (payload, GST_BUFFER_DATA (buffer), payload_len);
|
||||||
|
gst_buffer_unref (buffer);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (baseaudiopayload, "Pushing buffer %p", outbuf);
|
||||||
|
ret = gst_basertppayload_push (basepayload, outbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_base_rtp_audio_payload_flush:
|
* gst_base_rtp_audio_payload_flush:
|
||||||
* @baseaudiopayload: a #GstBaseRTPPayload
|
* @baseaudiopayload: a #GstBaseRTPPayload
|
||||||
|
@ -473,9 +596,18 @@ gst_base_rtp_audio_payload_flush (GstBaseRTPAudioPayload * baseaudiopayload,
|
||||||
GST_DEBUG_OBJECT (baseaudiopayload, "Pushing %d bytes ts %" GST_TIME_FORMAT,
|
GST_DEBUG_OBJECT (baseaudiopayload, "Pushing %d bytes ts %" GST_TIME_FORMAT,
|
||||||
payload_len, GST_TIME_ARGS (timestamp));
|
payload_len, GST_TIME_ARGS (timestamp));
|
||||||
|
|
||||||
|
if (priv->buffer_list && gst_adapter_available_fast (adapter) >= payload_len) {
|
||||||
|
GstBuffer *buffer;
|
||||||
|
/* we can quickly take a buffer out of the adapter without having to copy
|
||||||
|
* anything. */
|
||||||
|
buffer = gst_adapter_take_buffer (adapter, payload_len);
|
||||||
|
|
||||||
|
ret = gst_base_rtp_audio_payload_push_buffer (baseaudiopayload, buffer);
|
||||||
|
} else {
|
||||||
/* create buffer to hold the payload */
|
/* create buffer to hold the payload */
|
||||||
outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
|
outbuf = gst_rtp_buffer_new_allocate (payload_len, 0, 0);
|
||||||
|
|
||||||
|
/* copy payload */
|
||||||
payload = gst_rtp_buffer_get_payload (outbuf);
|
payload = gst_rtp_buffer_get_payload (outbuf);
|
||||||
gst_adapter_copy (adapter, payload, 0, payload_len);
|
gst_adapter_copy (adapter, payload, 0, payload_len);
|
||||||
gst_adapter_flush (adapter, payload_len);
|
gst_adapter_flush (adapter, payload_len);
|
||||||
|
@ -485,6 +617,7 @@ gst_base_rtp_audio_payload_flush (GstBaseRTPAudioPayload * baseaudiopayload,
|
||||||
timestamp);
|
timestamp);
|
||||||
|
|
||||||
ret = gst_basertppayload_push (basepayload, outbuf);
|
ret = gst_basertppayload_push (basepayload, outbuf);
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -720,9 +853,7 @@ gst_base_rtp_audio_payload_handle_buffer (GstBaseRTPPayload *
|
||||||
/* If buffer fits on an RTP packet, let's just push it through
|
/* If buffer fits on an RTP packet, let's just push it through
|
||||||
* this will check against max_ptime and max_mtu */
|
* this will check against max_ptime and max_mtu */
|
||||||
GST_DEBUG_OBJECT (payload, "Fast packet push");
|
GST_DEBUG_OBJECT (payload, "Fast packet push");
|
||||||
ret = gst_base_rtp_audio_payload_push (payload,
|
ret = gst_base_rtp_audio_payload_push_buffer (payload, buffer);
|
||||||
GST_BUFFER_DATA (buffer), size, GST_BUFFER_TIMESTAMP (buffer));
|
|
||||||
gst_buffer_unref (buffer);
|
|
||||||
} else {
|
} else {
|
||||||
/* push the buffer in the adapter */
|
/* push the buffer in the adapter */
|
||||||
gst_adapter_push (priv->adapter, buffer);
|
gst_adapter_push (priv->adapter, buffer);
|
||||||
|
|
Loading…
Reference in a new issue