gst/rtp/: Flush adapter on disconts.

Original commit message from CVS:
* gst/rtp/gstasteriskh263.h:
* gst/rtp/gstrtph263pdepay.c: (gst_rtp_h263p_depay_process),
(gst_rtp_h263p_depay_change_state):
* gst/rtp/gstrtph263pdepay.h:
* gst/rtp/gstrtph264depay.c: (gst_rtp_h264_depay_class_init),
(gst_rtp_h264_depay_setcaps), (gst_rtp_h264_depay_process),
(gst_rtp_h264_depay_change_state):
* gst/rtp/gstrtph264depay.h:
* gst/rtp/gstrtpmp4adepay.c: (gst_rtp_mp4a_depay_class_init),
(gst_rtp_mp4a_depay_setcaps), (gst_rtp_mp4a_depay_process):
* gst/rtp/gstrtpmp4gdepay.c: (gst_rtp_mp4g_depay_process):
Flush adapter on disconts.
This commit is contained in:
Wim Taymans 2007-03-29 14:40:35 +00:00
parent da3e23d375
commit a87260cb3b
8 changed files with 76 additions and 13 deletions

View File

@ -1,3 +1,18 @@
2007-03-29 Wim Taymans <wim@fluendo.com>
* gst/rtp/gstasteriskh263.h:
* gst/rtp/gstrtph263pdepay.c: (gst_rtp_h263p_depay_process),
(gst_rtp_h263p_depay_change_state):
* gst/rtp/gstrtph263pdepay.h:
* gst/rtp/gstrtph264depay.c: (gst_rtp_h264_depay_class_init),
(gst_rtp_h264_depay_setcaps), (gst_rtp_h264_depay_process),
(gst_rtp_h264_depay_change_state):
* gst/rtp/gstrtph264depay.h:
* gst/rtp/gstrtpmp4adepay.c: (gst_rtp_mp4a_depay_class_init),
(gst_rtp_mp4a_depay_setcaps), (gst_rtp_mp4a_depay_process):
* gst/rtp/gstrtpmp4gdepay.c: (gst_rtp_mp4g_depay_process):
Flush adapter on disconts.
2007-03-29 Wim Taymans <wim@fluendo.com> 2007-03-29 Wim Taymans <wim@fluendo.com>
* gst/rtp/gstrtpL16depay.c: (gst_rtp_L16_depay_process): * gst/rtp/gstrtpL16depay.c: (gst_rtp_L16_depay_process):

View File

@ -48,7 +48,6 @@ struct _GstAsteriskh263
GstAdapter *adapter; GstAdapter *adapter;
guint frequency;
guint32 lastts; guint32 lastts;
}; };

View File

@ -165,13 +165,19 @@ gst_rtp_h263p_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
if (!gst_rtp_buffer_validate (buf)) if (!gst_rtp_buffer_validate (buf))
goto bad_packet; goto bad_packet;
/* flush remaining data on discont */
if (GST_BUFFER_IS_DISCONT (buf)) {
gst_adapter_clear (rtph263pdepay->adapter);
rtph263pdepay->wait_start = TRUE;
}
{ {
gint payload_len; gint payload_len;
guint8 *payload; guint8 *payload;
gboolean P, V, M; gboolean P, V, M;
guint32 timestamp; guint32 timestamp;
guint header_len; guint header_len;
guint8 PLEN; guint8 PLEN, PEBIT;
payload_len = gst_rtp_buffer_get_payload_len (buf); payload_len = gst_rtp_buffer_get_payload_len (buf);
payload = gst_rtp_buffer_get_payload (buf); payload = gst_rtp_buffer_get_payload (buf);
@ -179,9 +185,17 @@ gst_rtp_h263p_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
header_len = 2; header_len = 2;
M = gst_rtp_buffer_get_marker (buf); M = gst_rtp_buffer_get_marker (buf);
/* 0 1
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | RR |P|V| PLEN |PEBIT|
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
P = (payload[0] & 0x04) == 0x04; P = (payload[0] & 0x04) == 0x04;
V = (payload[0] & 0x02) == 0x02; V = (payload[0] & 0x02) == 0x02;
PLEN = ((payload[0] & 0x1) << 5) | (payload[1] >> 3); PLEN = ((payload[0] & 0x1) << 5) | (payload[1] >> 3);
PEBIT = payload[1] & 0x7;
if (V) { if (V) {
header_len++; header_len++;
@ -191,11 +205,15 @@ gst_rtp_h263p_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
} }
if (P) { if (P) {
rtph263pdepay->wait_start = FALSE;
header_len -= 2; header_len -= 2;
payload[header_len] = 0; payload[header_len] = 0;
payload[header_len + 1] = 0; payload[header_len + 1] = 0;
} }
if (rtph263pdepay->wait_start)
goto waiting_start;
/* FIXME do not ignore the VRC header (See RFC 2429 section 4.2) */ /* FIXME do not ignore the VRC header (See RFC 2429 section 4.2) */
/* strip off header */ /* strip off header */
payload += header_len; payload += header_len;
@ -205,21 +223,21 @@ gst_rtp_h263p_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
if (M) { if (M) {
/* frame is completed: append to previous, push it out */ /* frame is completed: append to previous, push it out */
guint len; guint len, padlen;
guint avail; guint avail;
guint8 *data;
avail = gst_adapter_available (rtph263pdepay->adapter); avail = gst_adapter_available (rtph263pdepay->adapter);
len = avail + payload_len; len = avail + payload_len;
outbuf = gst_buffer_new_and_alloc (len + (len % 4) + 4); padlen = (len % 4) + 4;
memset (GST_BUFFER_DATA (outbuf) + len, 0, (len % 4) + 4); outbuf = gst_buffer_new_and_alloc (len + padlen);
memset (GST_BUFFER_DATA (outbuf) + len, 0, padlen);
GST_BUFFER_SIZE (outbuf) = len; GST_BUFFER_SIZE (outbuf) = len;
/* prepend previous data */ /* prepend previous data */
if (avail > 0) { if (avail > 0) {
data = (guint8 *) gst_adapter_peek (rtph263pdepay->adapter, avail); gst_adapter_copy (rtph263pdepay->adapter, GST_BUFFER_DATA (outbuf), 0,
memcpy (GST_BUFFER_DATA (outbuf), data, avail); avail);
gst_adapter_flush (rtph263pdepay->adapter, avail); gst_adapter_flush (rtph263pdepay->adapter, avail);
} }
memcpy (GST_BUFFER_DATA (outbuf) + avail, payload, payload_len); memcpy (GST_BUFFER_DATA (outbuf) + avail, payload, payload_len);
@ -249,6 +267,11 @@ bad_packet:
("Packet did not validate"), (NULL)); ("Packet did not validate"), (NULL));
return NULL; return NULL;
} }
waiting_start:
{
GST_DEBUG_OBJECT (rtph263pdepay, "waiting for picture start");
return NULL;
}
} }
static void static void
@ -295,6 +318,7 @@ gst_rtp_h263p_depay_change_state (GstElement * element,
break; break;
case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_READY_TO_PAUSED:
gst_adapter_clear (rtph263pdepay->adapter); gst_adapter_clear (rtph263pdepay->adapter);
rtph263pdepay->wait_start = TRUE;
break; break;
default: default:
break; break;

View File

@ -45,8 +45,7 @@ struct _GstRtpH263PDepay
GstBaseRTPDepayload depayload; GstBaseRTPDepayload depayload;
GstAdapter *adapter; GstAdapter *adapter;
gboolean wait_start;
guint frequency;
}; };
struct _GstRtpH263PDepayClass struct _GstRtpH263PDepayClass

View File

@ -278,6 +278,12 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
if (!gst_rtp_buffer_validate (buf)) if (!gst_rtp_buffer_validate (buf))
goto bad_packet; goto bad_packet;
/* flush remaining data on discont */
if (GST_BUFFER_IS_DISCONT (buf)) {
gst_adapter_clear (rtph264depay->adapter);
rtph264depay->wait_start = TRUE;
}
{ {
gint payload_len; gint payload_len;
guint8 *payload; guint8 *payload;
@ -325,6 +331,8 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
payload += header_len; payload += header_len;
payload_len -= header_len; payload_len -= header_len;
rtph264depay->wait_start = FALSE;
/* STAP-A Single-time aggregation packet 5.7.1 */ /* STAP-A Single-time aggregation packet 5.7.1 */
while (payload_len > 2) { while (payload_len > 2) {
/* 1 /* 1
@ -390,10 +398,15 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
GST_DEBUG_OBJECT (rtph264depay, "S %d, E %d", S, E); GST_DEBUG_OBJECT (rtph264depay, "S %d, E %d", S, E);
if (rtph264depay->wait_start && !S)
goto waiting_start;
if (S) { if (S) {
/* NAL unit starts here */ /* NAL unit starts here */
guint8 nal_header; guint8 nal_header;
rtph264depay->wait_start = FALSE;
/* reconstruct NAL header */ /* reconstruct NAL header */
nal_header = (payload[0] & 0xe0) | (payload[1] & 0x1f); nal_header = (payload[0] & 0xe0) | (payload[1] & 0x1f);
@ -446,6 +459,8 @@ gst_rtp_h264_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
} }
default: default:
{ {
rtph264depay->wait_start = FALSE;
/* 1-23 NAL unit Single NAL unit packet per H.264 5.6 */ /* 1-23 NAL unit Single NAL unit packet per H.264 5.6 */
/* the entire payload is the output buffer */ /* the entire payload is the output buffer */
nalu_size = payload_len; nalu_size = payload_len;
@ -478,6 +493,11 @@ undefined_type:
(NULL), ("Undefined packet type")); (NULL), ("Undefined packet type"));
return NULL; return NULL;
} }
waiting_start:
{
GST_DEBUG_OBJECT (rtph264depay, "waiting for start");
return NULL;
}
not_implemented: not_implemented:
{ {
GST_ELEMENT_ERROR (rtph264depay, STREAM, FORMAT, GST_ELEMENT_ERROR (rtph264depay, STREAM, FORMAT,
@ -530,6 +550,7 @@ gst_rtp_h264_depay_change_state (GstElement * element,
break; break;
case GST_STATE_CHANGE_READY_TO_PAUSED: case GST_STATE_CHANGE_READY_TO_PAUSED:
gst_adapter_clear (rtph264depay->adapter); gst_adapter_clear (rtph264depay->adapter);
rtph264depay->wait_start = TRUE;
break; break;
default: default:
break; break;

View File

@ -45,8 +45,7 @@ struct _GstRtpH264Depay
GstBaseRTPDepayload depayload; GstBaseRTPDepayload depayload;
GstAdapter *adapter; GstAdapter *adapter;
gboolean wait_start;
guint frequency;
}; };
struct _GstRtpH264DepayClass struct _GstRtpH264DepayClass

View File

@ -249,8 +249,9 @@ gst_rtp_mp4a_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
goto bad_packet; goto bad_packet;
/* flush remaining data on discont */ /* flush remaining data on discont */
if (GST_BUFFER_IS_DISCONT (buf)) if (GST_BUFFER_IS_DISCONT (buf)) {
gst_adapter_clear (rtpmp4adepay->adapter); gst_adapter_clear (rtpmp4adepay->adapter);
}
outbuf = gst_rtp_buffer_get_payload_buffer (buf); outbuf = gst_rtp_buffer_get_payload_buffer (buf);

View File

@ -275,6 +275,11 @@ gst_rtp_mp4g_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
if (!gst_rtp_buffer_validate (buf)) if (!gst_rtp_buffer_validate (buf))
goto bad_packet; goto bad_packet;
/* flush remaining data on discont */
if (GST_BUFFER_IS_DISCONT (buf)) {
gst_adapter_clear (rtpmp4gdepay->adapter);
}
{ {
gint payload_len, payload_header; gint payload_len, payload_header;
guint8 *payload; guint8 *payload;