jpegparse: improve buffer scanning

Specifically, when scanning for entropy data segment length and needing
more data, do not rescan from start next time around, but resume at
last position.

See also #583047.
This commit is contained in:
Mark Nauwelaerts 2010-04-29 16:33:44 +02:00
parent 01c5a78f0b
commit d68a4c1dcc

View file

@ -78,6 +78,7 @@ struct _GstJpegParsePrivate
GstAdapter *adapter; GstAdapter *adapter;
guint last_offset; guint last_offset;
guint last_entropy_len;
/* negotiated state */ /* negotiated state */
gint caps_width, caps_height; gint caps_width, caps_height;
@ -291,7 +292,8 @@ gst_jpeg_parse_parse_tag_has_entropy_segment (guint8 tag)
* enough data. * enough data.
*/ */
static guint static guint
gst_jpeg_parse_match_next_marker (const guint8 * data, guint size) gst_jpeg_parse_match_next_marker (GstJpegParse * parse, const guint8 * data,
guint size)
{ {
guint marker_len; guint marker_len;
guint8 tag; guint8 tag;
@ -316,11 +318,19 @@ gst_jpeg_parse_match_next_marker (const guint8 * data, guint size)
goto need_more_data; goto need_more_data;
if (G_UNLIKELY (gst_jpeg_parse_parse_tag_has_entropy_segment (tag))) { if (G_UNLIKELY (gst_jpeg_parse_parse_tag_has_entropy_segment (tag))) {
if (parse->priv->last_entropy_len) {
marker_len = parse->priv->last_entropy_len;
GST_LOG_OBJECT (parse, "resuming entropy segment scan at len %u",
marker_len);
}
while (!(data[marker_len] == 0xff && data[marker_len + 1] != 0x00)) { while (!(data[marker_len] == 0xff && data[marker_len + 1] != 0x00)) {
++marker_len; ++marker_len;
if (G_UNLIKELY (marker_len + 2 > size)) if (G_UNLIKELY (marker_len + 2 > size)) {
parse->priv->last_entropy_len = marker_len;
goto need_more_data; goto need_more_data;
}
} }
parse->priv->last_entropy_len = 0;
} }
return marker_len; return marker_len;
@ -369,7 +379,7 @@ gst_jpeg_parse_find_end_marker (GstJpegParse * parse, const guint8 * data,
return offset; return offset;
} }
/* Skip over this marker. */ /* Skip over this marker. */
marker_len = gst_jpeg_parse_match_next_marker (data + offset, marker_len = gst_jpeg_parse_match_next_marker (parse, data + offset,
size - offset); size - offset);
if (G_UNLIKELY (marker_len == -1)) { if (G_UNLIKELY (marker_len == -1)) {
return -1; return -1;
@ -736,6 +746,7 @@ gst_jpeg_parse_push_buffer (GstJpegParse * parse, guint len)
/* reset the offset (only when we flushed) */ /* reset the offset (only when we flushed) */
parse->priv->last_offset = 2; parse->priv->last_offset = 2;
parse->priv->last_entropy_len = 0;
outbuf = gst_adapter_take_buffer (parse->priv->adapter, len); outbuf = gst_adapter_take_buffer (parse->priv->adapter, len);
if (outbuf == NULL) { if (outbuf == NULL) {
@ -885,6 +896,7 @@ gst_jpeg_parse_change_state (GstElement * element, GstStateChange transition)
parse->priv->next_ts = GST_CLOCK_TIME_NONE; parse->priv->next_ts = GST_CLOCK_TIME_NONE;
parse->priv->last_offset = 2; parse->priv->last_offset = 2;
parse->priv->last_entropy_len = 0;
default: default:
break; break;
} }