summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2007-11-26 19:17:10 +0000
committerWim Taymans <wim.taymans@gmail.com>2007-11-26 19:17:10 +0000
commit28be655e11f2ac6ea62e7c1a861a2aaa4397ce50 (patch)
treede058c0353086e1e37a79abd52e3301562e0aade /gst
parentd37e93af90082a0b30640bc278bb11994fa63636 (diff)
gst/rtp/gstrtpmp4adepay.*: Fix depayloading when multiple frames are inside one RTP packet.
Original commit message from CVS: Based on Path by: Jayarama S. Santana <sundarsantana at gmail dot com> * gst/rtp/gstrtpmp4adepay.c: (gst_rtp_mp4a_depay_setcaps), (gst_rtp_mp4a_depay_process): * gst/rtp/gstrtpmp4adepay.h: Fix depayloading when multiple frames are inside one RTP packet. Fixes #499239.
Diffstat (limited to 'gst')
-rw-r--r--gst/rtp/gstrtpmp4adepay.c96
-rw-r--r--gst/rtp/gstrtpmp4adepay.h2
2 files changed, 74 insertions, 24 deletions
diff --git a/gst/rtp/gstrtpmp4adepay.c b/gst/rtp/gstrtpmp4adepay.c
index 959c3c11..f3be6062 100644
--- a/gst/rtp/gstrtpmp4adepay.c
+++ b/gst/rtp/gstrtpmp4adepay.c
@@ -191,6 +191,7 @@ gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
data = GST_BUFFER_DATA (buffer);
size = GST_BUFFER_SIZE (buffer);
+
if (size < 2) {
GST_WARNING_OBJECT (depayload, "config too short (%d < 2)", size);
goto bad_config;
@@ -200,7 +201,7 @@ gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
*
* audioMuxVersion == 0 (1 bit)
* allStreamsSameTimeFraming == 1 (1 bit)
- * numSubFrames == 0 (6 bits)
+ * numSubFrames == rtpmp4adepay->numSubFrames (6 bits)
* numProgram == 0 (4 bits)
* numLayer == 0 (3 bits)
*
@@ -214,6 +215,11 @@ gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
goto bad_config;
}
+ rtpmp4adepay->numSubFrames = (data[0] & 0x3F);
+
+ GST_LOG_OBJECT (rtpmp4adepay, "numSubFrames %d",
+ rtpmp4adepay->numSubFrames);
+
/* shift rest of string 15 bits down */
size -= 2;
for (i = 0; i < size; i++) {
@@ -261,47 +267,91 @@ gst_rtp_mp4a_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
* and push a buffer */
if (gst_rtp_buffer_get_marker (buf)) {
guint avail;
- guint latm_header_len;
- guint data_len;
+ guint i;
guint8 *data;
+ guint pos;
avail = gst_adapter_available (rtpmp4adepay->adapter);
- outbuf = gst_adapter_take_buffer (rtpmp4adepay->adapter, avail);
+ GST_LOG_OBJECT (rtpmp4adepay, "have marker and %u available", avail);
- /* determine payload length and set buffer data pointer accordingly */
- /* FIXME, check for overrun */
- latm_header_len = 0;
- data_len = 0;
+ outbuf = gst_adapter_take_buffer (rtpmp4adepay->adapter, avail);
data = GST_BUFFER_DATA (outbuf);
- do {
- data_len += data[latm_header_len];
- } while (data[latm_header_len++] == 0xff);
-
- /* just a check that lengths match, possibly there can be more than one
- * audioMuxElement in the payload? */
- if ((data_len + latm_header_len) != avail) {
- GST_WARNING_OBJECT (depayload, "not all payload consumed");
- }
+ /* position in data we are at */
+ pos = 0;
+
+ /* looping through the number of sub-frames in the audio payload */
+ for (i = 0; i <= rtpmp4adepay->numSubFrames; i++) {
+ /* determine payload length and set buffer data pointer accordingly */
+ guint skip;
+ guint data_len;
+ guint32 timestamp;
+
+ GstBuffer *tmp = NULL;
+
+ timestamp = gst_rtp_buffer_get_timestamp (buf);
+
+ /* each subframe starts with a variable length encoding */
+ data_len = 0;
+ for (skip = 0; skip < avail; skip++) {
+ data_len += data[skip];
+ if (data[skip] != 0xff)
+ break;
+ }
+ skip++;
+
+ /* this can not be possible, we have not enough data or the length
+ * decoding failed because we ran out of data. */
+ if (skip + data_len < avail)
+ goto wrong_size;
+
+ GST_LOG_OBJECT (rtpmp4adepay,
+ "subframe %u, header len %u, data len %u, left %u", i, skip, data_len,
+ avail);
- GST_BUFFER_SIZE (outbuf) = avail - latm_header_len;
- GST_BUFFER_DATA (outbuf) += latm_header_len;
+ /* take data out, skip the header */
+ pos += skip;
+ tmp = gst_buffer_create_sub (outbuf, pos, data_len);
- gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
+ /* skip data too */
+ skip += data_len;
+ pos += data_len;
- GST_DEBUG ("gst_rtp_mp4a_depay_process: pushing buffer of size %d",
- GST_BUFFER_SIZE (outbuf));
+ /* update our pointers whith what we consumed */
+ data += skip;
+ avail -= skip;
- return outbuf;
+ gst_buffer_set_caps (tmp, GST_PAD_CAPS (depayload->srcpad));
+
+ /* only apply the timestamp for the first buffer. Based on gstrtpmp4gdepay.c */
+ if (i == 0)
+ gst_base_rtp_depayload_push_ts (depayload, timestamp, tmp);
+ else
+ gst_base_rtp_depayload_push (depayload, tmp);
+ }
+
+ /* just a check that lengths match */
+ if (avail) {
+ GST_ELEMENT_WARNING (depayload, STREAM, DECODE,
+ ("Packet invalid"), ("Not all payload consumed: "
+ "possible wrongly encoded packet."));
+ }
}
return NULL;
+ /* ERRORS */
bad_packet:
{
GST_ELEMENT_WARNING (rtpmp4adepay, STREAM, DECODE,
("Packet did not validate"), (NULL));
return NULL;
}
+wrong_size:
+ {
+ GST_ELEMENT_WARNING (rtpmp4adepay, STREAM, DECODE,
+ ("Packet did not validate"), ("wrong packet size"));
+ return NULL;
+ }
}
static void
diff --git a/gst/rtp/gstrtpmp4adepay.h b/gst/rtp/gstrtpmp4adepay.h
index 03b6156e..36ed7145 100644
--- a/gst/rtp/gstrtpmp4adepay.h
+++ b/gst/rtp/gstrtpmp4adepay.h
@@ -42,8 +42,8 @@ typedef struct _GstRtpMP4ADepayClass GstRtpMP4ADepayClass;
struct _GstRtpMP4ADepay
{
GstBaseRTPDepayload depayload;
-
GstAdapter *adapter;
+ guint8 numSubFrames;
};
struct _GstRtpMP4ADepayClass