mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-25 17:50:36 +00:00
gstdepay: add support for events
Conflicts: gst/rtp/gstrtpgstdepay.c
This commit is contained in:
parent
54b783b5a3
commit
08e5a197b4
1 changed files with 180 additions and 64 deletions
|
@ -183,6 +183,121 @@ gst_rtp_gst_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
read_length (GstRtpGSTDepay * rtpgstdepay, guint8 * data, guint size,
|
||||||
|
guint * length, guint * skip)
|
||||||
|
{
|
||||||
|
guint b, len, offset;
|
||||||
|
|
||||||
|
/* start reading the length, we need this to skip to the data later */
|
||||||
|
len = offset = 0;
|
||||||
|
do {
|
||||||
|
if (offset >= size)
|
||||||
|
return FALSE;
|
||||||
|
b = data[offset++];
|
||||||
|
len = (len << 7) | (b & 0x7f);
|
||||||
|
} while (b & 0x80);
|
||||||
|
|
||||||
|
/* check remaining buffer size */
|
||||||
|
if (size - offset < len)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
*length = len;
|
||||||
|
*skip = offset;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstCaps *
|
||||||
|
read_caps (GstRtpGSTDepay * rtpgstdepay, GstBuffer * buf, guint * skip)
|
||||||
|
{
|
||||||
|
guint offset, length;
|
||||||
|
GstCaps *caps;
|
||||||
|
GstMapInfo map;
|
||||||
|
|
||||||
|
gst_buffer_map (buf, &map, GST_MAP_READ);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (rtpgstdepay, "buffer size %u", map.size);
|
||||||
|
|
||||||
|
if (!read_length (rtpgstdepay, map.data, map.size, &length, &offset))
|
||||||
|
goto too_small;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (rtpgstdepay, "parsing caps %s", &map.data[offset]);
|
||||||
|
|
||||||
|
/* parse and store in cache */
|
||||||
|
caps = gst_caps_from_string ((gchar *) & map.data[offset]);
|
||||||
|
gst_buffer_unmap (buf, &map);
|
||||||
|
|
||||||
|
*skip = length + offset;
|
||||||
|
|
||||||
|
return caps;
|
||||||
|
|
||||||
|
too_small:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
|
||||||
|
("Buffer too small."), (NULL));
|
||||||
|
gst_buffer_unmap (buf, &map);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static GstEvent *
|
||||||
|
read_event (GstRtpGSTDepay * rtpgstdepay, guint type,
|
||||||
|
GstBuffer * buf, guint * skip)
|
||||||
|
{
|
||||||
|
guint offset, length;
|
||||||
|
GstStructure *s;
|
||||||
|
GstEvent *event;
|
||||||
|
GstEventType etype;
|
||||||
|
gchar *end;
|
||||||
|
GstMapInfo map;
|
||||||
|
|
||||||
|
gst_buffer_map (buf, &map, GST_MAP_READ);
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (rtpgstdepay, "buffer size %u", map.size);
|
||||||
|
|
||||||
|
if (!read_length (rtpgstdepay, map.data, map.size, &length, &offset))
|
||||||
|
goto too_small;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (rtpgstdepay, "parsing event %s", &map.data[offset]);
|
||||||
|
|
||||||
|
/* parse */
|
||||||
|
s = gst_structure_from_string ((gchar *) & map.data[offset], &end);
|
||||||
|
gst_buffer_unmap (buf, &map);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 1:
|
||||||
|
etype = GST_EVENT_TAG;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
etype = GST_EVENT_CUSTOM_DOWNSTREAM;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
etype = GST_EVENT_CUSTOM_BOTH;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto unknown_event;
|
||||||
|
}
|
||||||
|
event = gst_event_new_custom (etype, s);
|
||||||
|
|
||||||
|
*skip = length + offset;
|
||||||
|
|
||||||
|
return event;
|
||||||
|
|
||||||
|
too_small:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
|
||||||
|
("Buffer too small."), (NULL));
|
||||||
|
gst_buffer_unmap (buf, &map);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
unknown_event:
|
||||||
|
{
|
||||||
|
GST_DEBUG_OBJECT (rtpgstdepay, "unknown event type");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GstBuffer *
|
static GstBuffer *
|
||||||
gst_rtp_gst_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
|
gst_rtp_gst_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
|
||||||
{
|
{
|
||||||
|
@ -190,7 +305,7 @@ gst_rtp_gst_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
|
||||||
GstBuffer *subbuf, *outbuf = NULL;
|
GstBuffer *subbuf, *outbuf = NULL;
|
||||||
gint payload_len;
|
gint payload_len;
|
||||||
guint8 *payload;
|
guint8 *payload;
|
||||||
guint CV, frag_offset, avail;
|
guint CV, frag_offset, avail, offset;
|
||||||
GstRTPBuffer rtp = { NULL };
|
GstRTPBuffer rtp = { NULL };
|
||||||
|
|
||||||
rtpgstdepay = GST_RTP_GST_DEPAY (depayload);
|
rtpgstdepay = GST_RTP_GST_DEPAY (depayload);
|
||||||
|
@ -214,7 +329,7 @@ gst_rtp_gst_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
|
||||||
* 0 1 2 3
|
* 0 1 2 3
|
||||||
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
* |C| CV |D|0|0|0| MBZ |
|
* |C| CV |D|0|0|0| ETYPE | MBZ |
|
||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
* | Frag_offset |
|
* | Frag_offset |
|
||||||
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||||
|
@ -230,6 +345,7 @@ gst_rtp_gst_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
|
||||||
subbuf = gst_rtp_buffer_get_payload_subbuffer (&rtp, 8, -1);
|
subbuf = gst_rtp_buffer_get_payload_subbuffer (&rtp, 8, -1);
|
||||||
gst_adapter_push (rtpgstdepay->adapter, subbuf);
|
gst_adapter_push (rtpgstdepay->adapter, subbuf);
|
||||||
|
|
||||||
|
offset = 0;
|
||||||
if (gst_rtp_buffer_get_marker (&rtp)) {
|
if (gst_rtp_buffer_get_marker (&rtp)) {
|
||||||
guint avail;
|
guint avail;
|
||||||
GstCaps *outcaps;
|
GstCaps *outcaps;
|
||||||
|
@ -241,59 +357,52 @@ gst_rtp_gst_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
|
||||||
CV = (payload[0] >> 4) & 0x7;
|
CV = (payload[0] >> 4) & 0x7;
|
||||||
|
|
||||||
if (payload[0] & 0x80) {
|
if (payload[0] & 0x80) {
|
||||||
guint b, csize, left, offset;
|
guint size;
|
||||||
GstMapInfo map;
|
|
||||||
GstBuffer *subbuf;
|
|
||||||
|
|
||||||
/* C bit, we have inline caps */
|
/* C bit, we have inline caps */
|
||||||
gst_buffer_map (outbuf, &map, GST_MAP_READ);
|
outcaps = read_caps (rtpgstdepay, outbuf, &size);
|
||||||
|
if (outcaps == NULL)
|
||||||
|
goto no_caps;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (rtpgstdepay, "buffer size %u", map.size);
|
GST_DEBUG_OBJECT (rtpgstdepay,
|
||||||
|
"inline caps %u, length %u, %" GST_PTR_FORMAT, CV, size, outcaps);
|
||||||
|
|
||||||
/* start reading the length, we need this to skip to the data later */
|
|
||||||
csize = offset = 0;
|
|
||||||
left = map.size;
|
|
||||||
do {
|
|
||||||
if (offset >= left) {
|
|
||||||
gst_buffer_unmap (outbuf, &map);
|
|
||||||
goto too_small;
|
|
||||||
}
|
|
||||||
b = map.data[offset++];
|
|
||||||
csize = (csize << 7) | (b & 0x7f);
|
|
||||||
} while (b & 0x80);
|
|
||||||
|
|
||||||
/* we have read csize, reduce remaining buffer size */
|
|
||||||
left -= offset;
|
|
||||||
if (left < csize) {
|
|
||||||
gst_buffer_unmap (outbuf, &map);
|
|
||||||
goto too_small;
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (rtpgstdepay, "parsing caps %s", &map.data[offset]);
|
|
||||||
|
|
||||||
/* parse and store in cache */
|
|
||||||
outcaps = gst_caps_from_string ((gchar *) & map.data[offset]);
|
|
||||||
store_cache (rtpgstdepay, CV, outcaps);
|
store_cache (rtpgstdepay, CV, outcaps);
|
||||||
|
|
||||||
/* skip caps */
|
/* skip caps */
|
||||||
offset += csize;
|
offset += size;
|
||||||
left -= csize;
|
avail -= size;
|
||||||
|
}
|
||||||
|
if (payload[1]) {
|
||||||
|
guint size;
|
||||||
|
GstEvent *event;
|
||||||
|
|
||||||
|
/* we have an event */
|
||||||
|
event = read_event (rtpgstdepay, payload[1], outbuf, &size);
|
||||||
|
if (event == NULL)
|
||||||
|
goto no_event;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (rtpgstdepay,
|
GST_DEBUG_OBJECT (rtpgstdepay,
|
||||||
"inline caps %u, length %u, %" GST_PTR_FORMAT, CV, csize, outcaps);
|
"inline event, length %u, %" GST_PTR_FORMAT, size, event);
|
||||||
|
|
||||||
|
gst_pad_push_event (depayload->srcpad, event);
|
||||||
|
|
||||||
|
/* no buffer after event */
|
||||||
|
avail = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (avail) {
|
||||||
|
if (offset != 0) {
|
||||||
|
GstBuffer *temp;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (rtpgstdepay, "sub buffer: offset %u, size %u", offset,
|
GST_DEBUG_OBJECT (rtpgstdepay, "sub buffer: offset %u, size %u", offset,
|
||||||
left);
|
avail);
|
||||||
/* create real data buffer when needed */
|
|
||||||
if (left)
|
temp =
|
||||||
subbuf =
|
gst_buffer_copy_region (outbuf, GST_BUFFER_COPY_ALL, offset, avail);
|
||||||
gst_buffer_copy_region (outbuf, GST_BUFFER_COPY_ALL, offset, left);
|
|
||||||
else
|
|
||||||
subbuf = NULL;
|
|
||||||
|
|
||||||
gst_buffer_unmap (outbuf, &map);
|
|
||||||
gst_buffer_unref (outbuf);
|
gst_buffer_unref (outbuf);
|
||||||
outbuf = subbuf;
|
outbuf = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* see what caps we need */
|
/* see what caps we need */
|
||||||
|
@ -311,12 +420,15 @@ gst_rtp_gst_depay_process (GstRTPBaseDepayload * depayload, GstBuffer * buf)
|
||||||
rtpgstdepay->current_CV = CV;
|
rtpgstdepay->current_CV = CV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outbuf) {
|
|
||||||
if (payload[0] & 0x8)
|
if (payload[0] & 0x8)
|
||||||
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
|
GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||||
|
} else {
|
||||||
|
gst_buffer_unref (outbuf);
|
||||||
|
outbuf = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gst_rtp_buffer_unmap (&rtp);
|
gst_rtp_buffer_unmap (&rtp);
|
||||||
|
|
||||||
return outbuf;
|
return outbuf;
|
||||||
|
|
||||||
/* ERRORS */
|
/* ERRORS */
|
||||||
|
@ -334,11 +446,16 @@ wrong_frag:
|
||||||
GST_LOG_OBJECT (rtpgstdepay, "wrong fragment, skipping");
|
GST_LOG_OBJECT (rtpgstdepay, "wrong fragment, skipping");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
too_small:
|
no_caps:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
|
GST_WARNING_OBJECT (rtpgstdepay, "failed to parse caps");
|
||||||
("Buffer too small."), (NULL));
|
gst_buffer_unref (outbuf);
|
||||||
if (outbuf)
|
gst_rtp_buffer_unmap (&rtp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
no_event:
|
||||||
|
{
|
||||||
|
GST_WARNING_OBJECT (rtpgstdepay, "failed to parse event");
|
||||||
gst_buffer_unref (outbuf);
|
gst_buffer_unref (outbuf);
|
||||||
gst_rtp_buffer_unmap (&rtp);
|
gst_rtp_buffer_unmap (&rtp);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -347,7 +464,6 @@ missing_caps:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
|
GST_ELEMENT_WARNING (rtpgstdepay, STREAM, DECODE,
|
||||||
("Missing caps %u.", CV), (NULL));
|
("Missing caps %u.", CV), (NULL));
|
||||||
if (outbuf)
|
|
||||||
gst_buffer_unref (outbuf);
|
gst_buffer_unref (outbuf);
|
||||||
gst_rtp_buffer_unmap (&rtp);
|
gst_rtp_buffer_unmap (&rtp);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in a new issue