summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2009-05-06 12:54:22 +0200
committerWim Taymans <wim.taymans@collabora.co.uk>2009-05-06 12:56:58 +0200
commitb7c5847dbdab1907852c8cf0744461df3f879af3 (patch)
treee430bdb8fcb866c4255ee9e08ef61e30cd217fec
parent8e7273076d14444d2fa5ba764bbc09ad4fefa6d4 (diff)
rtpjpegpay: handle input with 1 quant table
Also handle input with just one quant table, simply duplicate the quant table. Handle invalid SOF correctly and some small cleanups. Fixes #578257
-rw-r--r--gst/rtp/gstrtpjpegpay.c41
1 files changed, 28 insertions, 13 deletions
diff --git a/gst/rtp/gstrtpjpegpay.c b/gst/rtp/gstrtpjpegpay.c
index 63bcb10c5..81f044b06 100644
--- a/gst/rtp/gstrtpjpegpay.c
+++ b/gst/rtp/gstrtpjpegpay.c
@@ -378,7 +378,8 @@ gst_rtp_jpeg_pay_read_sof (GstRtpJPEGPay * pay, const guint8 * data,
infolen++;
}
- /* see that the components are supported */
+ /* see that the components are supported, the first component must use quant
+ * table 0 */
cptr = &info[0];
if (cptr->samp == 0x21 && cptr->qt == 0)
pay->type = 0;
@@ -389,12 +390,13 @@ gst_rtp_jpeg_pay_read_sof (GstRtpJPEGPay * pay, const guint8 * data,
header->type = pay->type;
+ /* the other components are free to use quant table 0 or 1 */
cptr = &info[1];
- if (!(cptr->samp == 0x11 && cptr->qt == 1))
+ if (!(cptr->samp == 0x11 && cptr->qt < 2))
goto invalid_comp;
cptr = &info[2];
- if (!(cptr->samp == 0x11 && cptr->qt == 1))
+ if (!(cptr->samp == 0x11 && cptr->qt < 2))
goto invalid_comp;
return TRUE;
@@ -484,24 +486,22 @@ gst_rtp_jpeg_pay_handle_buffer (GstBaseRTPPayload * basepayload,
data = GST_BUFFER_DATA (buffer);
timestamp = GST_BUFFER_TIMESTAMP (buffer);
+ GST_LOG_OBJECT (pay, "got buffer size %u, timestamp %" GST_TIME_FORMAT, size,
+ GST_TIME_ARGS (timestamp));
+
/* parse the jpeg header for 'start of scan' and read quant tables if needed */
while (!sos_found && (offset < size)) {
+ GST_LOG_OBJECT (pay, "checking from offset %u", offset);
switch (gst_rtp_jpeg_pay_scan_marker (data, size, &offset)) {
case JPEG_MARKER_JFIF:
case JPEG_MARKER_CMT:
+ case JPEG_MARKER_DHT:
offset += gst_rtp_jpeg_pay_header_size (data, offset);
break;
case JPEG_MARKER_SOF:
- offset += gst_rtp_jpeg_pay_read_sof (pay, data, &offset, &jpeg_header);
+ if (!gst_rtp_jpeg_pay_read_sof (pay, data, &offset, &jpeg_header))
+ goto invalid_format;
break;
- case JPEG_MARKER_DHT:
- {
- guint len;
-
- len = gst_rtp_jpeg_pay_header_size (data, offset);
- offset += len;
- break;
- }
case JPEG_MARKER_DQT:
{
GST_LOG ("DQT found");
@@ -520,10 +520,21 @@ gst_rtp_jpeg_pay_handle_buffer (GstBaseRTPPayload * basepayload,
break;
}
case JPEG_MARKER_SOS:
+ {
sos_found = TRUE;
+ if (quant_table_index == 1) {
+ /* we only had one quant table, duplicate it. We always need 2 quant
+ * tables for the Types we support */
+ jpeg_quantizer_table[1] = jpeg_quantizer_table[0];
+ quant_table_index++;
+ quant_data_size += quant_header.length;
+ quant_header.length += quant_header.length;
+ quant_header.precision |= (quant_header.precision & 1) << 1;
+ }
GST_LOG_OBJECT (pay, "SOS found");
jpeg_header_size = offset + gst_rtp_jpeg_pay_header_size (data, offset);
break;
+ }
case JPEG_MARKER_EOI:
GST_WARNING_OBJECT (pay, "EOI reached before SOS!");
break;
@@ -615,7 +626,11 @@ no_dimension:
GST_ELEMENT_ERROR (pay, STREAM, FORMAT, ("No size given"), (NULL));
return GST_FLOW_NOT_NEGOTIATED;
}
-
+invalid_format:
+ {
+ /* error was posted */
+ return GST_FLOW_ERROR;
+ }
}
static void