theorapay: handle 0 sized packets

Handle 0 sized packets (repeat frame) in the payloader and depayloader.

Fixes #641827
This commit is contained in:
Wim Taymans 2011-02-14 16:46:46 +01:00
parent d203b1ef50
commit 4279aa6a68
2 changed files with 13 additions and 9 deletions

View file

@ -501,7 +501,7 @@ gst_rtp_theora_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
to_free = payload; to_free = payload;
} }
GST_DEBUG_OBJECT (depayload, "assemble done"); GST_DEBUG_OBJECT (depayload, "assemble done, payload_len %d", payload_len);
/* we not assembling anymore now */ /* we not assembling anymore now */
rtptheoradepay->assembling = FALSE; rtptheoradepay->assembling = FALSE;
@ -524,7 +524,7 @@ gst_rtp_theora_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
*/ */
timestamp = gst_rtp_buffer_get_timestamp (buf); timestamp = gst_rtp_buffer_get_timestamp (buf);
while (payload_len > 2) { while (payload_len >= 2) {
guint16 length; guint16 length;
length = GST_READ_UINT16_BE (payload); length = GST_READ_UINT16_BE (payload);
@ -559,7 +559,7 @@ gst_rtp_theora_depay_process (GstBaseRTPDepayload * depayload, GstBuffer * buf)
memcpy (GST_BUFFER_DATA (outbuf), payload, length); memcpy (GST_BUFFER_DATA (outbuf), payload, length);
} }
if ((payload[0] & 0xC0) == 0x0) if (payload_len > 0 && (payload[0] & 0xC0) == 0x0)
rtptheoradepay->needs_keyframe = FALSE; rtptheoradepay->needs_keyframe = FALSE;
payload += length; payload += length;

View file

@ -563,7 +563,7 @@ gst_rtp_theora_pay_payload_buffer (GstRtpTheoraPay * rtptheorapay, guint8 TDT,
/* put buffer in packet, it either fits completely or needs to be fragmented /* put buffer in packet, it either fits completely or needs to be fragmented
* over multiple RTP packets. */ * over multiple RTP packets. */
while (size) { do {
plen = MIN (rtptheorapay->payload_left - 2, size); plen = MIN (rtptheorapay->payload_left - 2, size);
GST_DEBUG_OBJECT (rtptheorapay, "append %u bytes", plen); GST_DEBUG_OBJECT (rtptheorapay, "append %u bytes", plen);
@ -571,6 +571,7 @@ gst_rtp_theora_pay_payload_buffer (GstRtpTheoraPay * rtptheorapay, guint8 TDT,
/* data is copied in the payload with a 2 byte length header */ /* data is copied in the payload with a 2 byte length header */
ppos[0] = ((plen - not_in_length) >> 8) & 0xff; ppos[0] = ((plen - not_in_length) >> 8) & 0xff;
ppos[1] = ((plen - not_in_length) & 0xff); ppos[1] = ((plen - not_in_length) & 0xff);
if (plen)
memcpy (&ppos[2], data, plen); memcpy (&ppos[2], data, plen);
/* only first (only) configuration cuts length field */ /* only first (only) configuration cuts length field */
@ -617,7 +618,7 @@ gst_rtp_theora_pay_payload_buffer (GstRtpTheoraPay * rtptheorapay, guint8 TDT,
if (duration != GST_CLOCK_TIME_NONE) if (duration != GST_CLOCK_TIME_NONE)
rtptheorapay->payload_duration += duration; rtptheorapay->payload_duration += duration;
} }
} } while (size);
return ret; return ret;
} }
@ -644,11 +645,14 @@ gst_rtp_theora_pay_handle_buffer (GstBaseRTPPayload * basepayload,
GST_DEBUG_OBJECT (rtptheorapay, "size %u, duration %" GST_TIME_FORMAT, GST_DEBUG_OBJECT (rtptheorapay, "size %u, duration %" GST_TIME_FORMAT,
size, GST_TIME_ARGS (duration)); size, GST_TIME_ARGS (duration));
if (G_UNLIKELY (size < 1 || size > 0xffff)) if (G_UNLIKELY (size > 0xffff))
goto wrong_size; goto wrong_size;
/* find packet type */ /* find packet type */
if (data[0] & 0x80) { if (size == 0) {
TDT = 0;
keyframe = FALSE;
} else if (data[0] & 0x80) {
/* header */ /* header */
if (data[0] == 0x80) { if (data[0] == 0x80) {
/* identification, we need to parse this in order to get the clock rate. /* identification, we need to parse this in order to get the clock rate.
@ -743,7 +747,7 @@ done:
wrong_size: wrong_size:
{ {
GST_ELEMENT_WARNING (rtptheorapay, STREAM, DECODE, GST_ELEMENT_WARNING (rtptheorapay, STREAM, DECODE,
("Invalid packet size (1 < %d <= 0xffff)", size), (NULL)); ("Invalid packet size (%d <= 0xffff)", size), (NULL));
gst_buffer_unref (buffer); gst_buffer_unref (buffer);
return GST_FLOW_OK; return GST_FLOW_OK;
} }