gst/mpeg1videoparse/gstmp1videoparse.*: Fix for some slight mis-cuts in buffer parsing, and for some potential overfl...

Original commit message from CVS:
* gst/mpeg1videoparse/gstmp1videoparse.c: (gst_mp1videoparse_init),
(gst_mp1videoparse_real_chain), (gst_mp1videoparse_change_state):
* gst/mpeg1videoparse/gstmp1videoparse.h:
Fix for some slight mis-cuts in buffer parsing, and for some
potential overflows or faults-causers. Adds disconts. Also fixes
#139105 while we're at it.
This commit is contained in:
Ronald S. Bultje 2004-04-10 22:40:51 +00:00
parent 4c4871f133
commit ad0f319236
3 changed files with 38 additions and 11 deletions

View file

@ -1,3 +1,12 @@
2004-04-10 Ronald Bultje <rbultje@ronald.bitfreak.net>
* gst/mpeg1videoparse/gstmp1videoparse.c: (gst_mp1videoparse_init),
(gst_mp1videoparse_real_chain), (gst_mp1videoparse_change_state):
* gst/mpeg1videoparse/gstmp1videoparse.h:
Fix for some slight mis-cuts in buffer parsing, and for some
potential overflows or faults-causers. Adds disconts. Also fixes
#139105 while we're at it.
2004-04-10 Ronald Bultje <rbultje@ronald.bitfreak.net> 2004-04-10 Ronald Bultje <rbultje@ronald.bitfreak.net>
* configure.ac: * configure.ac:

View file

@ -155,6 +155,7 @@ gst_mp1videoparse_init (Mp1VideoParse * mp1videoparse)
mp1videoparse->partialbuf = NULL; mp1videoparse->partialbuf = NULL;
mp1videoparse->need_resync = FALSE; mp1videoparse->need_resync = FALSE;
mp1videoparse->need_discont = TRUE;
mp1videoparse->last_pts = GST_CLOCK_TIME_NONE; mp1videoparse->last_pts = GST_CLOCK_TIME_NONE;
mp1videoparse->picture_in_buffer = 0; mp1videoparse->picture_in_buffer = 0;
mp1videoparse->width = mp1videoparse->height = -1; mp1videoparse->width = mp1videoparse->height = -1;
@ -333,8 +334,10 @@ gst_mp1videoparse_real_chain (Mp1VideoParse * mp1videoparse, GstBuffer * buf,
GstEvent *event = GST_EVENT (buf); GstEvent *event = GST_EVENT (buf);
switch (GST_EVENT_TYPE (event)) { switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_FLUSH:
case GST_EVENT_DISCONTINUOUS: case GST_EVENT_DISCONTINUOUS:
mp1videoparse->need_discont = TRUE;
/* fall-through */
case GST_EVENT_FLUSH:
gst_mp1videoparse_flush (mp1videoparse); gst_mp1videoparse_flush (mp1videoparse);
break; break;
case GST_EVENT_EOS: case GST_EVENT_EOS:
@ -481,16 +484,16 @@ gst_mp1videoparse_real_chain (Mp1VideoParse * mp1videoparse, GstBuffer * buf,
/* something else... */ /* something else... */
else else
sync_state = 0; sync_state = 0;
/* go down the buffer */ /* go down the buffer */
offset++; offset++;
} }
if (have_sync) { if (have_sync) {
offset -= 2; offset -= 2;
GST_DEBUG ("mp1videoparse: synced at %ld code 0x000001%02x", offset, GST_DEBUG ("mp1videoparse: synced");
data[offset + 3]);
outbuf = gst_buffer_create_sub (mp1videoparse->partialbuf, 0, offset + 4); outbuf = gst_buffer_create_sub (mp1videoparse->partialbuf, 0, offset);
g_assert (outbuf != NULL); g_assert (outbuf != NULL);
GST_BUFFER_TIMESTAMP (outbuf) = mp1videoparse->last_pts; GST_BUFFER_TIMESTAMP (outbuf) = mp1videoparse->last_pts;
GST_BUFFER_DURATION (outbuf) = GST_SECOND / mp1videoparse->fps; GST_BUFFER_DURATION (outbuf) = GST_SECOND / mp1videoparse->fps;
@ -502,6 +505,16 @@ gst_mp1videoparse_real_chain (Mp1VideoParse * mp1videoparse, GstBuffer * buf,
} }
if (GST_PAD_CAPS (outpad) != NULL) { if (GST_PAD_CAPS (outpad) != NULL) {
if (mp1videoparse->need_discont &&
GST_BUFFER_TIMESTAMP_IS_VALID (outbuf)) {
GstEvent *event = gst_event_new_discontinuous (FALSE,
GST_FORMAT_TIME, GST_BUFFER_TIMESTAMP (outbuf),
GST_FORMAT_UNDEFINED);
GST_DEBUG ("prepending discont event");
gst_pad_push (outpad, GST_DATA (event));
mp1videoparse->need_discont = FALSE;
}
GST_DEBUG ("mp1videoparse: pushing %d bytes %" G_GUINT64_FORMAT, GST_DEBUG ("mp1videoparse: pushing %d bytes %" G_GUINT64_FORMAT,
GST_BUFFER_SIZE (outbuf), GST_BUFFER_TIMESTAMP (outbuf)); GST_BUFFER_SIZE (outbuf), GST_BUFFER_TIMESTAMP (outbuf));
gst_pad_push (outpad, GST_DATA (outbuf)); gst_pad_push (outpad, GST_DATA (outbuf));
@ -512,19 +525,22 @@ gst_mp1videoparse_real_chain (Mp1VideoParse * mp1videoparse, GstBuffer * buf,
} }
mp1videoparse->picture_in_buffer = 0; mp1videoparse->picture_in_buffer = 0;
temp = if (size != offset) {
gst_buffer_create_sub (mp1videoparse->partialbuf, offset, temp =
size - offset); gst_buffer_create_sub (mp1videoparse->partialbuf, offset,
size - offset);
} else {
temp = NULL;
}
gst_buffer_unref (mp1videoparse->partialbuf); gst_buffer_unref (mp1videoparse->partialbuf);
mp1videoparse->partialbuf = temp; mp1videoparse->partialbuf = temp;
offset = 0; offset = 0;
} else { } else {
if (time_stamp != GST_CLOCK_TIME_NONE) { if (time_stamp != GST_CLOCK_TIME_NONE)
mp1videoparse->last_pts = time_stamp; mp1videoparse->last_pts = time_stamp;
break; return;
}
} }
} while (1); } while (mp1videoparse->partialbuf != NULL);
} }
static GstElementStateReturn static GstElementStateReturn
@ -539,6 +555,7 @@ gst_mp1videoparse_change_state (GstElement * element)
switch (GST_STATE_TRANSITION (element)) { switch (GST_STATE_TRANSITION (element)) {
case GST_STATE_PAUSED_TO_READY: case GST_STATE_PAUSED_TO_READY:
gst_mp1videoparse_flush (mp1videoparse); gst_mp1videoparse_flush (mp1videoparse);
mp1videoparse->need_discont = TRUE;
mp1videoparse->width = mp1videoparse->height = -1; mp1videoparse->width = mp1videoparse->height = -1;
mp1videoparse->fps = mp1videoparse->asr = 0.; mp1videoparse->fps = mp1videoparse->asr = 0.;
break; break;

View file

@ -53,6 +53,7 @@ struct _Mp1VideoParse {
gulong next_buffer_offset; gulong next_buffer_offset;
gboolean need_resync; gboolean need_resync;
gboolean in_flush; gboolean in_flush;
gboolean need_discont;
guint64 last_pts; guint64 last_pts;
gint picture_in_buffer; gint picture_in_buffer;