mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 12:10:37 +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>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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_ENDCODE 0xB1
|
||||
#define USER_DATA_STARTCODE 0xB2
|
||||
|
@ -440,7 +414,7 @@ gst_mpeg4vparse_push (GstMpeg4VParse * parse, gsize size)
|
|||
|
||||
/* Restart now that we flushed data */
|
||||
parse->offset = 0;
|
||||
parse->state = PARSE_START_FOUND;
|
||||
parse->state = PARSE_NEED_START;
|
||||
parse->intra_frame = FALSE;
|
||||
}
|
||||
|
||||
|
@ -452,15 +426,39 @@ gst_mpeg4vparse_drain (GstMpeg4VParse * parse, GstBuffer * last_buffer)
|
|||
guint available = 0;
|
||||
|
||||
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);
|
||||
|
||||
/* Need at least 5 more bytes, 4 for the startcode, 1 to optionally determine
|
||||
* 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 &&
|
||||
data[parse->offset + 2] == 1) {
|
||||
|
||||
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:
|
||||
switch (data[parse->offset + 3]) {
|
||||
case VOP_STARTCODE:
|
||||
|
@ -498,15 +496,6 @@ gst_mpeg4vparse_drain (GstMpeg4VParse * parse, GstBuffer * last_buffer)
|
|||
break;
|
||||
case PARSE_VOP_FOUND:
|
||||
{ /* 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_mpeg4vparse_push (parse, parse->offset);
|
||||
|
@ -543,27 +532,9 @@ gst_mpeg4vparse_chain (GstPad * pad, GstBuffer * 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 */
|
||||
ret = gst_mpeg4vparse_drain (parse, buffer);
|
||||
|
||||
beach:
|
||||
gst_object_unref (parse);
|
||||
|
||||
return ret;
|
||||
|
@ -702,7 +673,6 @@ gst_mpeg4vparse_change_state (GstElement * element, GstStateChange transition)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue