mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
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.
This commit is contained in:
parent
d37e93af90
commit
28be655e11
3 changed files with 85 additions and 25 deletions
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
||||||
|
2007-11-26 Wim Taymans <wim.taymans@gmail.com>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
2007-11-26 Stefan Kost <ensonic@users.sf.net>
|
2007-11-26 Stefan Kost <ensonic@users.sf.net>
|
||||||
|
|
||||||
* gst/level/gstlevel.c:
|
* gst/level/gstlevel.c:
|
||||||
|
|
|
@ -191,6 +191,7 @@ gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
||||||
|
|
||||||
data = GST_BUFFER_DATA (buffer);
|
data = GST_BUFFER_DATA (buffer);
|
||||||
size = GST_BUFFER_SIZE (buffer);
|
size = GST_BUFFER_SIZE (buffer);
|
||||||
|
|
||||||
if (size < 2) {
|
if (size < 2) {
|
||||||
GST_WARNING_OBJECT (depayload, "config too short (%d < 2)", size);
|
GST_WARNING_OBJECT (depayload, "config too short (%d < 2)", size);
|
||||||
goto bad_config;
|
goto bad_config;
|
||||||
|
@ -200,7 +201,7 @@ gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
||||||
*
|
*
|
||||||
* audioMuxVersion == 0 (1 bit)
|
* audioMuxVersion == 0 (1 bit)
|
||||||
* allStreamsSameTimeFraming == 1 (1 bit)
|
* allStreamsSameTimeFraming == 1 (1 bit)
|
||||||
* numSubFrames == 0 (6 bits)
|
* numSubFrames == rtpmp4adepay->numSubFrames (6 bits)
|
||||||
* numProgram == 0 (4 bits)
|
* numProgram == 0 (4 bits)
|
||||||
* numLayer == 0 (3 bits)
|
* numLayer == 0 (3 bits)
|
||||||
*
|
*
|
||||||
|
@ -214,6 +215,11 @@ gst_rtp_mp4a_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps)
|
||||||
goto bad_config;
|
goto bad_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rtpmp4adepay->numSubFrames = (data[0] & 0x3F);
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (rtpmp4adepay, "numSubFrames %d",
|
||||||
|
rtpmp4adepay->numSubFrames);
|
||||||
|
|
||||||
/* shift rest of string 15 bits down */
|
/* shift rest of string 15 bits down */
|
||||||
size -= 2;
|
size -= 2;
|
||||||
for (i = 0; i < size; i++) {
|
for (i = 0; i < size; i++) {
|
||||||
|
@ -261,47 +267,91 @@ gst_rtp_mp4a_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
|
||||||
* and push a buffer */
|
* and push a buffer */
|
||||||
if (gst_rtp_buffer_get_marker (buf)) {
|
if (gst_rtp_buffer_get_marker (buf)) {
|
||||||
guint avail;
|
guint avail;
|
||||||
guint latm_header_len;
|
guint i;
|
||||||
guint data_len;
|
|
||||||
guint8 *data;
|
guint8 *data;
|
||||||
|
guint pos;
|
||||||
|
|
||||||
avail = gst_adapter_available (rtpmp4adepay->adapter);
|
avail = gst_adapter_available (rtpmp4adepay->adapter);
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (rtpmp4adepay, "have marker and %u available", avail);
|
||||||
|
|
||||||
outbuf = gst_adapter_take_buffer (rtpmp4adepay->adapter, avail);
|
outbuf = gst_adapter_take_buffer (rtpmp4adepay->adapter, avail);
|
||||||
|
|
||||||
/* determine payload length and set buffer data pointer accordingly */
|
|
||||||
/* FIXME, check for overrun */
|
|
||||||
latm_header_len = 0;
|
|
||||||
data_len = 0;
|
|
||||||
data = GST_BUFFER_DATA (outbuf);
|
data = GST_BUFFER_DATA (outbuf);
|
||||||
do {
|
/* position in data we are at */
|
||||||
data_len += data[latm_header_len];
|
pos = 0;
|
||||||
} while (data[latm_header_len++] == 0xff);
|
|
||||||
|
|
||||||
/* just a check that lengths match, possibly there can be more than one
|
/* looping through the number of sub-frames in the audio payload */
|
||||||
* audioMuxElement in the payload? */
|
for (i = 0; i <= rtpmp4adepay->numSubFrames; i++) {
|
||||||
if ((data_len + latm_header_len) != avail) {
|
/* determine payload length and set buffer data pointer accordingly */
|
||||||
GST_WARNING_OBJECT (depayload, "not all payload consumed");
|
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);
|
||||||
|
|
||||||
|
/* take data out, skip the header */
|
||||||
|
pos += skip;
|
||||||
|
tmp = gst_buffer_create_sub (outbuf, pos, data_len);
|
||||||
|
|
||||||
|
/* skip data too */
|
||||||
|
skip += data_len;
|
||||||
|
pos += data_len;
|
||||||
|
|
||||||
|
/* update our pointers whith what we consumed */
|
||||||
|
data += skip;
|
||||||
|
avail -= skip;
|
||||||
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_BUFFER_SIZE (outbuf) = avail - latm_header_len;
|
/* just a check that lengths match */
|
||||||
GST_BUFFER_DATA (outbuf) += latm_header_len;
|
if (avail) {
|
||||||
|
GST_ELEMENT_WARNING (depayload, STREAM, DECODE,
|
||||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (depayload->srcpad));
|
("Packet invalid"), ("Not all payload consumed: "
|
||||||
|
"possible wrongly encoded packet."));
|
||||||
GST_DEBUG ("gst_rtp_mp4a_depay_process: pushing buffer of size %d",
|
}
|
||||||
GST_BUFFER_SIZE (outbuf));
|
|
||||||
|
|
||||||
return outbuf;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
/* ERRORS */
|
||||||
bad_packet:
|
bad_packet:
|
||||||
{
|
{
|
||||||
GST_ELEMENT_WARNING (rtpmp4adepay, STREAM, DECODE,
|
GST_ELEMENT_WARNING (rtpmp4adepay, STREAM, DECODE,
|
||||||
("Packet did not validate"), (NULL));
|
("Packet did not validate"), (NULL));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
wrong_size:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_WARNING (rtpmp4adepay, STREAM, DECODE,
|
||||||
|
("Packet did not validate"), ("wrong packet size"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -42,8 +42,8 @@ typedef struct _GstRtpMP4ADepayClass GstRtpMP4ADepayClass;
|
||||||
struct _GstRtpMP4ADepay
|
struct _GstRtpMP4ADepay
|
||||||
{
|
{
|
||||||
GstBaseRTPDepayload depayload;
|
GstBaseRTPDepayload depayload;
|
||||||
|
|
||||||
GstAdapter *adapter;
|
GstAdapter *adapter;
|
||||||
|
guint8 numSubFrames;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GstRtpMP4ADepayClass
|
struct _GstRtpMP4ADepayClass
|
||||||
|
|
Loading…
Reference in a new issue