mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-06 23:48:53 +00:00
gst/mpeg4videoparse/mpeg4videoparse.c: Move some code around to integrate the startcode searching with the other bits...
Original commit message from CVS: Patch by: Sjoerd Simons <sjoerd at luon dot net> * gst/mpeg4videoparse/mpeg4videoparse.c: (gst_mpeg4vparse_push), (gst_mpeg4vparse_drain), (gst_mpeg4vparse_chain), (gst_mpeg4vparse_change_state): Move some code around to integrate the startcode searching with the other bits of parsing, avoid a whole bunch of peeks. Get rid of invalid data that should not happen according to the specs. Fixes #533559.
This commit is contained in:
parent
fb7879098c
commit
b3bc29bc64
3 changed files with 39 additions and 57 deletions
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2008-05-22 Wim Taymans <wim.taymans@collabora.co.uk>
|
||||||
|
|
||||||
|
Patch by: Sjoerd Simons <sjoerd at luon dot net>
|
||||||
|
|
||||||
|
* gst/mpeg4videoparse/mpeg4videoparse.c: (gst_mpeg4vparse_push),
|
||||||
|
(gst_mpeg4vparse_drain), (gst_mpeg4vparse_chain),
|
||||||
|
(gst_mpeg4vparse_change_state):
|
||||||
|
Move some code around to integrate the startcode searching with the
|
||||||
|
other bits of parsing, avoid a whole bunch of peeks.
|
||||||
|
Get rid of invalid data that should not happen according to the specs.
|
||||||
|
Fixes #533559.
|
||||||
|
|
||||||
2008-05-20 Sebastian Dröge <slomo@circular-chaos.org>
|
2008-05-20 Sebastian Dröge <slomo@circular-chaos.org>
|
||||||
|
|
||||||
Patch by: Bastien Nocera <hadess at hadess dot net>
|
Patch by: Bastien Nocera <hadess at hadess dot net>
|
||||||
|
|
2
common
2
common
|
@ -1 +1 @@
|
||||||
Subproject commit e365978c480a8fffa4bdb61568fb2cd989d1b197
|
Subproject commit 5e771924d59d9ac912237ea466d0c60ad95df5ab
|
|
@ -121,32 +121,6 @@ gst_mpeg4vparse_set_new_caps (GstMpeg4VParse * parse,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
gst_mpeg4vparse_align (GstMpeg4VParse * parse)
|
|
||||||
{
|
|
||||||
guint flushed = 0;
|
|
||||||
|
|
||||||
/* Searching for a start code */
|
|
||||||
while (gst_adapter_available (parse->adapter) >= 4) {
|
|
||||||
/* If we have enough data, ensure we're aligned to a start code */
|
|
||||||
const guint8 *data = gst_adapter_peek (parse->adapter, 4);
|
|
||||||
|
|
||||||
if (G_LIKELY (data[0] == 0 && data[1] == 0 && data[2] == 1)) {
|
|
||||||
GST_LOG_OBJECT (parse, "found start code with type %02X", data[3]);
|
|
||||||
parse->state = PARSE_START_FOUND;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
gst_adapter_flush (parse->adapter, 1);
|
|
||||||
flushed++;
|
|
||||||
parse->state = PARSE_NEED_START;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (G_UNLIKELY (flushed)) {
|
|
||||||
GST_LOG_OBJECT (parse, "flushed %u bytes while aligning", flushed);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define VOS_STARTCODE 0xB0
|
#define VOS_STARTCODE 0xB0
|
||||||
#define VOS_ENDCODE 0xB1
|
#define VOS_ENDCODE 0xB1
|
||||||
#define USER_DATA_STARTCODE 0xB2
|
#define USER_DATA_STARTCODE 0xB2
|
||||||
|
@ -440,7 +414,7 @@ gst_mpeg4vparse_push (GstMpeg4VParse * parse, gsize size)
|
||||||
|
|
||||||
/* Restart now that we flushed data */
|
/* Restart now that we flushed data */
|
||||||
parse->offset = 0;
|
parse->offset = 0;
|
||||||
parse->state = PARSE_START_FOUND;
|
parse->state = PARSE_NEED_START;
|
||||||
parse->intra_frame = FALSE;
|
parse->intra_frame = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,15 +426,39 @@ gst_mpeg4vparse_drain (GstMpeg4VParse * parse, GstBuffer * last_buffer)
|
||||||
guint available = 0;
|
guint available = 0;
|
||||||
|
|
||||||
available = gst_adapter_available (parse->adapter);
|
available = gst_adapter_available (parse->adapter);
|
||||||
|
/* We do a quick check here to avoid the _peek() below. */
|
||||||
|
if (G_UNLIKELY (available < 5)) {
|
||||||
|
GST_DEBUG_OBJECT (parse, "we need more data, %d < 5", available);
|
||||||
|
goto beach;
|
||||||
|
}
|
||||||
data = gst_adapter_peek (parse->adapter, available);
|
data = gst_adapter_peek (parse->adapter, available);
|
||||||
|
|
||||||
/* Need at least 5 more bytes, 4 for the startcode, 1 to optionally determine
|
/* Need at least 5 more bytes, 4 for the startcode, 1 to optionally determine
|
||||||
* the VOP frame type */
|
* the VOP frame type */
|
||||||
while (parse->offset < available - 5) {
|
while (available >= 5 && parse->offset < available - 5) {
|
||||||
if (data[parse->offset] == 0 && data[parse->offset + 1] == 0 &&
|
if (data[parse->offset] == 0 && data[parse->offset + 1] == 0 &&
|
||||||
data[parse->offset + 2] == 1) {
|
data[parse->offset + 2] == 1) {
|
||||||
|
|
||||||
switch (parse->state) {
|
switch (parse->state) {
|
||||||
|
case PARSE_NEED_START:
|
||||||
|
switch (data[parse->offset + 3]) {
|
||||||
|
case VOP_STARTCODE:
|
||||||
|
case VOS_STARTCODE:
|
||||||
|
case GOP_STARTCODE:
|
||||||
|
/* valid starts of a frame */
|
||||||
|
parse->state = PARSE_START_FOUND;
|
||||||
|
if (parse->offset > 0) {
|
||||||
|
GST_LOG_OBJECT (parse, "Flushing %u bytes", parse->offset);
|
||||||
|
gst_adapter_flush (parse->adapter, parse->offset);
|
||||||
|
parse->offset = 0;
|
||||||
|
available = gst_adapter_available (parse->adapter);
|
||||||
|
data = gst_adapter_peek (parse->adapter, available);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
parse->offset += 4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case PARSE_START_FOUND:
|
case PARSE_START_FOUND:
|
||||||
switch (data[parse->offset + 3]) {
|
switch (data[parse->offset + 3]) {
|
||||||
case VOP_STARTCODE:
|
case VOP_STARTCODE:
|
||||||
|
@ -498,15 +496,6 @@ gst_mpeg4vparse_drain (GstMpeg4VParse * parse, GstBuffer * last_buffer)
|
||||||
break;
|
break;
|
||||||
case PARSE_VOP_FOUND:
|
case PARSE_VOP_FOUND:
|
||||||
{ /* We were in a VOP already, any start code marks the end of it */
|
{ /* We were in a VOP already, any start code marks the end of it */
|
||||||
if (data[parse->offset + 3] == USER_DATA_STARTCODE) {
|
|
||||||
/* Userdata shouldn't come directly after a VOP, but some
|
|
||||||
* implementation do it anyways :( This prevents pushing
|
|
||||||
* USER_DATA as the initial bit of a buffer, which causes confusing
|
|
||||||
* with other elements */
|
|
||||||
parse->offset += 4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (parse, "found VOP end marker at %u", parse->offset);
|
GST_LOG_OBJECT (parse, "found VOP end marker at %u", parse->offset);
|
||||||
|
|
||||||
gst_mpeg4vparse_push (parse, parse->offset);
|
gst_mpeg4vparse_push (parse, parse->offset);
|
||||||
|
@ -543,27 +532,9 @@ gst_mpeg4vparse_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
|
|
||||||
gst_adapter_push (parse->adapter, buffer);
|
gst_adapter_push (parse->adapter, buffer);
|
||||||
|
|
||||||
/* We need to get aligned on a start code */
|
|
||||||
if (G_UNLIKELY (parse->state == PARSE_NEED_START)) {
|
|
||||||
gst_mpeg4vparse_align (parse);
|
|
||||||
/* No start code found in that buffer */
|
|
||||||
if (G_UNLIKELY (parse->state == PARSE_NEED_START)) {
|
|
||||||
GST_DEBUG_OBJECT (parse, "start code not found, need more data");
|
|
||||||
goto beach;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We need at least 8 bytes to find the next start code which marks the end
|
|
||||||
of the one we just found */
|
|
||||||
if (G_UNLIKELY (gst_adapter_available (parse->adapter) < 8)) {
|
|
||||||
GST_DEBUG_OBJECT (parse, "start code found, need more data to find next");
|
|
||||||
goto beach;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Drain the accumulated blocks frame per frame */
|
/* Drain the accumulated blocks frame per frame */
|
||||||
ret = gst_mpeg4vparse_drain (parse, buffer);
|
ret = gst_mpeg4vparse_drain (parse, buffer);
|
||||||
|
|
||||||
beach:
|
|
||||||
gst_object_unref (parse);
|
gst_object_unref (parse);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -702,7 +673,6 @@ gst_mpeg4vparse_change_state (GstElement * element, GstStateChange transition)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue