mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-08 16:35:40 +00:00
gst/rtp/gstrtpmp4gdepay.c: Change some of the ranges in the caps, mostly for the amount of bits we can use.
Original commit message from CVS: * gst/rtp/gstrtpmp4gdepay.c: (gst_bs_parse_init), (gst_bs_parse_read), (gst_rtp_mp4g_depay_process): Change some of the ranges in the caps, mostly for the amount of bits we can use. Added a little bitstream parse and use it to parse the AU header fields. Check for malformed and wrongly sized packets better. Implement more header field parsing. Handle the size of fragmented packets correctly.
This commit is contained in:
parent
50eed1907b
commit
fe9b449678
2 changed files with 142 additions and 21 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2008-09-15 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||
|
||||
* gst/rtp/gstrtpmp4gdepay.c: (gst_bs_parse_init),
|
||||
(gst_bs_parse_read), (gst_rtp_mp4g_depay_process):
|
||||
Change some of the ranges in the caps, mostly for the amount of bits we
|
||||
can use.
|
||||
Added a little bitstream parse and use it to parse the AU header fields.
|
||||
Check for malformed and wrongly sized packets better.
|
||||
Implement more header field parsing.
|
||||
Handle the size of fragmented packets correctly.
|
||||
|
||||
2008-09-14 Edward Hervey <edward.hervey@collabora.co.uk>
|
||||
|
||||
Patch by: Jonathan Matthew <notverysmart@gmail.com>
|
||||
|
|
|
@ -67,16 +67,71 @@ GST_STATIC_PAD_TEMPLATE ("sink",
|
|||
/* "maxdisplacement = (string) [1,MAX], " */
|
||||
/* "de-interleavebuffersize = (string) [1,MAX], " */
|
||||
/* Optional configuration parameters */
|
||||
/* "sizelength = (string) [1, 16], " *//* max 16 bits, should be enough... */
|
||||
/* "indexlength = (string) [1, 8], " */
|
||||
/* "indexdeltalength = (string) [1, 8], " */
|
||||
/* "ctsdeltalength = (string) [1, 64], " */
|
||||
/* "dtsdeltalength = (string) [1, 64], " */
|
||||
/* "sizelength = (string) [1, 32], " */
|
||||
/* "indexlength = (string) [1, 32], " */
|
||||
/* "indexdeltalength = (string) [1, 32], " */
|
||||
/* "ctsdeltalength = (string) [1, 32], " */
|
||||
/* "dtsdeltalength = (string) [1, 32], " */
|
||||
/* "randomaccessindication = (string) {0, 1}, " */
|
||||
/* "streamstateindication = (string) [0, 64], " */
|
||||
/* "auxiliarydatasizelength = (string) [0, 64]" */ )
|
||||
/* "streamstateindication = (string) [0, 32], " */
|
||||
/* "auxiliarydatasizelength = (string) [0, 32]" */ )
|
||||
);
|
||||
|
||||
/* simple bitstream parser */
|
||||
typedef struct
|
||||
{
|
||||
const guint8 *data;
|
||||
const guint8 *end;
|
||||
gint head; /* bitpos in the cache of next bit */
|
||||
guint64 cache; /* cached bytes */
|
||||
} GstBsParse;
|
||||
|
||||
static void
|
||||
gst_bs_parse_init (GstBsParse * bs, const guint8 * data, guint size)
|
||||
{
|
||||
bs->data = data;
|
||||
bs->end = data + size;
|
||||
bs->head = 0;
|
||||
bs->cache = 0xffffffff;
|
||||
}
|
||||
|
||||
static guint32
|
||||
gst_bs_parse_read (GstBsParse * bs, guint n)
|
||||
{
|
||||
guint32 res = 0;
|
||||
gint shift;
|
||||
|
||||
if (n == 0)
|
||||
return res;
|
||||
|
||||
/* fill up the cache if we need to */
|
||||
while (bs->head < n) {
|
||||
if (bs->data >= bs->end) {
|
||||
/* we're at the end, can't produce more than head number of bits */
|
||||
n = bs->head;
|
||||
break;
|
||||
}
|
||||
/* shift bytes in cache, moving the head bits of the cache left */
|
||||
bs->cache = (bs->cache << 8) | *bs->data++;
|
||||
bs->head += 8;
|
||||
}
|
||||
|
||||
/* bring the required bits down and truncate */
|
||||
if ((shift = bs->head - n) > 0)
|
||||
res = bs->cache >> shift;
|
||||
else
|
||||
res = bs->cache;
|
||||
|
||||
/* mask out required bits */
|
||||
if (n < 32)
|
||||
res &= (1 << n) - 1;
|
||||
|
||||
bs->head = shift;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
GST_BOILERPLATE (GstRtpMP4GDepay, gst_rtp_mp4g_depay, GstBaseRTPDepayload,
|
||||
GST_TYPE_BASE_RTP_DEPAYLOAD);
|
||||
|
||||
|
@ -261,22 +316,25 @@ gst_rtp_mp4g_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
|||
}
|
||||
|
||||
{
|
||||
gint payload_len, payload_header;
|
||||
gint payload_len, payload_AU;
|
||||
guint8 *payload;
|
||||
guint32 timestamp;
|
||||
guint AU_headers_len;
|
||||
guint AU_size, AU_index;
|
||||
guint AU_size, AU_index, payload_AU_size;
|
||||
gboolean M;
|
||||
|
||||
payload_len = gst_rtp_buffer_get_payload_len (buf);
|
||||
payload = gst_rtp_buffer_get_payload (buf);
|
||||
payload_header = 0;
|
||||
|
||||
timestamp = gst_rtp_buffer_get_timestamp (buf);
|
||||
M = gst_rtp_buffer_get_marker (buf);
|
||||
|
||||
if (rtpmp4gdepay->sizelength > 0) {
|
||||
gint num_AU_headers, AU_headers_bytes, i;
|
||||
GstBsParse bs;
|
||||
|
||||
if (payload_len < 2)
|
||||
goto short_payload;
|
||||
|
||||
/* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- .. -+-+-+-+-+-+-+-+-+-+
|
||||
* |AU-headers-length|AU-header|AU-header| |AU-header|padding|
|
||||
|
@ -295,22 +353,67 @@ gst_rtp_mp4g_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
|||
|
||||
/* skip header */
|
||||
payload += 2;
|
||||
/* skip special headers */
|
||||
payload_header = 2 + AU_headers_bytes;
|
||||
payload_len -= 2;
|
||||
|
||||
for (i = 0; i < num_AU_headers; i++) {
|
||||
/* FIXME, use bits */
|
||||
AU_size = ((payload[0] << 8) | payload[1]) >> 3;
|
||||
AU_index = payload[1] & 0x7;
|
||||
payload += 2;
|
||||
if (payload_len < AU_headers_bytes)
|
||||
goto short_payload;
|
||||
|
||||
GST_DEBUG_OBJECT (rtpmp4gdepay, "len, %d, size %d, index %d",
|
||||
AU_headers_len, AU_size, AU_index);
|
||||
/* skip special headers, point to first payload AU */
|
||||
payload_AU = 2 + AU_headers_bytes;
|
||||
payload_AU_size = payload_len - AU_headers_bytes;
|
||||
|
||||
/* point the bitstream parser to the first AU header bit */
|
||||
gst_bs_parse_init (&bs, payload, payload_len);
|
||||
|
||||
for (i = 0; i < num_AU_headers && payload_AU_size > 0; i++) {
|
||||
/* parse AU header
|
||||
* +---------------------------------------+
|
||||
* | AU-size |
|
||||
* +---------------------------------------+
|
||||
* | AU-Index / AU-Index-delta |
|
||||
* +---------------------------------------+
|
||||
* | CTS-flag |
|
||||
* +---------------------------------------+
|
||||
* | CTS-delta |
|
||||
* +---------------------------------------+
|
||||
* | DTS-flag |
|
||||
* +---------------------------------------+
|
||||
* | DTS-delta |
|
||||
* +---------------------------------------+
|
||||
* | RAP-flag |
|
||||
* +---------------------------------------+
|
||||
* | Stream-state |
|
||||
* +---------------------------------------+
|
||||
*/
|
||||
AU_size = gst_bs_parse_read (&bs, rtpmp4gdepay->sizelength);
|
||||
if (i == 0)
|
||||
AU_index = gst_bs_parse_read (&bs, rtpmp4gdepay->indexlength);
|
||||
else
|
||||
AU_index = gst_bs_parse_read (&bs, rtpmp4gdepay->indexdeltalength);
|
||||
if (rtpmp4gdepay->ctsdeltalength > 0) {
|
||||
if (gst_bs_parse_read (&bs, 1))
|
||||
gst_bs_parse_read (&bs, rtpmp4gdepay->ctsdeltalength);
|
||||
}
|
||||
if (rtpmp4gdepay->dtsdeltalength > 0) {
|
||||
if (gst_bs_parse_read (&bs, 1))
|
||||
gst_bs_parse_read (&bs, rtpmp4gdepay->dtsdeltalength);
|
||||
}
|
||||
if (rtpmp4gdepay->randomaccessindication)
|
||||
gst_bs_parse_read (&bs, 1);
|
||||
if (rtpmp4gdepay->streamstateindication > 0)
|
||||
gst_bs_parse_read (&bs, rtpmp4gdepay->streamstateindication);
|
||||
|
||||
GST_DEBUG_OBJECT (rtpmp4gdepay, "size %d, index %d", AU_size, AU_index);
|
||||
|
||||
/* fragmented pakets have the AU_size set to the size of the
|
||||
* unfragmented AU. */
|
||||
if (AU_size > payload_AU_size)
|
||||
AU_size = payload_AU_size;
|
||||
|
||||
/* collect stuff in the adapter, strip header from payload and push in
|
||||
* the adapter */
|
||||
outbuf =
|
||||
gst_rtp_buffer_get_payload_subbuffer (buf, payload_header, AU_size);
|
||||
gst_rtp_buffer_get_payload_subbuffer (buf, payload_AU, AU_size);
|
||||
gst_adapter_push (rtpmp4gdepay->adapter, outbuf);
|
||||
|
||||
if (M) {
|
||||
|
@ -331,7 +434,8 @@ gst_rtp_mp4g_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
|||
else
|
||||
gst_base_rtp_depayload_push (depayload, outbuf);
|
||||
}
|
||||
payload_header += AU_size;
|
||||
payload_AU += AU_size;
|
||||
payload_AU_size -= AU_size;
|
||||
}
|
||||
} else {
|
||||
/* push complete buffer in adapter */
|
||||
|
@ -363,6 +467,12 @@ bad_packet:
|
|||
("Packet did not validate."), (NULL));
|
||||
return NULL;
|
||||
}
|
||||
short_payload:
|
||||
{
|
||||
GST_ELEMENT_WARNING (rtpmp4gdepay, STREAM, DECODE,
|
||||
("Packet payload was too short."), (NULL));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static GstStateChangeReturn
|
||||
|
|
Loading…
Reference in a new issue