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
This commit is contained in:
Wim Taymans 2009-05-06 12:54:22 +02:00
parent 8e7273076d
commit b7c5847dbd

View file

@ -378,7 +378,8 @@ gst_rtp_jpeg_pay_read_sof (GstRtpJPEGPay * pay, const guint8 * data,
infolen++; infolen++;
} }
/* see that the components are supported */ /* see that the components are supported, the first component must use quant
* table 0 */
cptr = &info[0]; cptr = &info[0];
if (cptr->samp == 0x21 && cptr->qt == 0) if (cptr->samp == 0x21 && cptr->qt == 0)
pay->type = 0; pay->type = 0;
@ -389,12 +390,13 @@ gst_rtp_jpeg_pay_read_sof (GstRtpJPEGPay * pay, const guint8 * data,
header->type = pay->type; header->type = pay->type;
/* the other components are free to use quant table 0 or 1 */
cptr = &info[1]; cptr = &info[1];
if (!(cptr->samp == 0x11 && cptr->qt == 1)) if (!(cptr->samp == 0x11 && cptr->qt < 2))
goto invalid_comp; goto invalid_comp;
cptr = &info[2]; cptr = &info[2];
if (!(cptr->samp == 0x11 && cptr->qt == 1)) if (!(cptr->samp == 0x11 && cptr->qt < 2))
goto invalid_comp; goto invalid_comp;
return TRUE; return TRUE;
@ -484,24 +486,22 @@ gst_rtp_jpeg_pay_handle_buffer (GstBaseRTPPayload * basepayload,
data = GST_BUFFER_DATA (buffer); data = GST_BUFFER_DATA (buffer);
timestamp = GST_BUFFER_TIMESTAMP (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 */ /* parse the jpeg header for 'start of scan' and read quant tables if needed */
while (!sos_found && (offset < size)) { while (!sos_found && (offset < size)) {
GST_LOG_OBJECT (pay, "checking from offset %u", offset);
switch (gst_rtp_jpeg_pay_scan_marker (data, size, &offset)) { switch (gst_rtp_jpeg_pay_scan_marker (data, size, &offset)) {
case JPEG_MARKER_JFIF: case JPEG_MARKER_JFIF:
case JPEG_MARKER_CMT: case JPEG_MARKER_CMT:
case JPEG_MARKER_DHT:
offset += gst_rtp_jpeg_pay_header_size (data, offset); offset += gst_rtp_jpeg_pay_header_size (data, offset);
break; break;
case JPEG_MARKER_SOF: 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; break;
case JPEG_MARKER_DHT:
{
guint len;
len = gst_rtp_jpeg_pay_header_size (data, offset);
offset += len;
break;
}
case JPEG_MARKER_DQT: case JPEG_MARKER_DQT:
{ {
GST_LOG ("DQT found"); GST_LOG ("DQT found");
@ -520,10 +520,21 @@ gst_rtp_jpeg_pay_handle_buffer (GstBaseRTPPayload * basepayload,
break; break;
} }
case JPEG_MARKER_SOS: case JPEG_MARKER_SOS:
{
sos_found = TRUE; 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"); GST_LOG_OBJECT (pay, "SOS found");
jpeg_header_size = offset + gst_rtp_jpeg_pay_header_size (data, offset); jpeg_header_size = offset + gst_rtp_jpeg_pay_header_size (data, offset);
break; break;
}
case JPEG_MARKER_EOI: case JPEG_MARKER_EOI:
GST_WARNING_OBJECT (pay, "EOI reached before SOS!"); GST_WARNING_OBJECT (pay, "EOI reached before SOS!");
break; break;
@ -615,7 +626,11 @@ no_dimension:
GST_ELEMENT_ERROR (pay, STREAM, FORMAT, ("No size given"), (NULL)); GST_ELEMENT_ERROR (pay, STREAM, FORMAT, ("No size given"), (NULL));
return GST_FLOW_NOT_NEGOTIATED; return GST_FLOW_NOT_NEGOTIATED;
} }
invalid_format:
{
/* error was posted */
return GST_FLOW_ERROR;
}
} }
static void static void