mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 04:01:08 +00:00
gst/videorate/gstvideorate.c: Event handling (fixes #159986).
Original commit message from CVS: Reviewed by: Ronald S. Bultje <rbultje@ronald.bitfreak.net> * gst/videorate/gstvideorate.c: (gst_videorate_blank_data), (gst_videorate_init), (gst_videorate_chain), (gst_videorate_change_state): Event handling (fixes #159986).
This commit is contained in:
parent
50f80de3be
commit
3b7785eb8e
2 changed files with 63 additions and 16 deletions
|
@ -1,3 +1,12 @@
|
|||
2004-12-19 Edward Hervey <bilboed@bilboed.com>
|
||||
|
||||
Reviewed by: Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||
|
||||
* gst/videorate/gstvideorate.c: (gst_videorate_blank_data),
|
||||
(gst_videorate_init), (gst_videorate_chain),
|
||||
(gst_videorate_change_state):
|
||||
Event handling (fixes #159986).
|
||||
|
||||
2004-12-19 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
|
||||
|
||||
* gst-libs/gst/riff/riff-media.c:
|
||||
|
|
|
@ -51,6 +51,7 @@ struct _GstVideorate
|
|||
/* video state */
|
||||
gdouble from_fps, to_fps;
|
||||
guint64 next_ts;
|
||||
guint64 first_ts;
|
||||
GstBuffer *prevbuf;
|
||||
guint64 in, out, dup, drop;
|
||||
|
||||
|
@ -285,6 +286,21 @@ gst_videorate_link (GstPad * pad, const GstCaps * caps)
|
|||
return GST_PAD_LINK_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_videorate_blank_data (GstVideorate * videorate)
|
||||
{
|
||||
GST_DEBUG ("resetting data");
|
||||
if (videorate->prevbuf)
|
||||
gst_buffer_unref (videorate->prevbuf);
|
||||
videorate->prevbuf = NULL;
|
||||
videorate->in = 0;
|
||||
videorate->out = 0;
|
||||
videorate->drop = 0;
|
||||
videorate->dup = 0;
|
||||
videorate->next_ts = 0LL;
|
||||
videorate->first_ts = 0LL;
|
||||
}
|
||||
|
||||
static void
|
||||
gst_videorate_init (GstVideorate * videorate)
|
||||
{
|
||||
|
@ -306,11 +322,7 @@ gst_videorate_init (GstVideorate * videorate)
|
|||
gst_pad_set_getcaps_function (videorate->srcpad, gst_videorate_getcaps);
|
||||
gst_pad_set_link_function (videorate->srcpad, gst_videorate_link);
|
||||
|
||||
videorate->prevbuf = NULL;
|
||||
videorate->in = 0;
|
||||
videorate->out = 0;
|
||||
videorate->drop = 0;
|
||||
videorate->dup = 0;
|
||||
gst_videorate_blank_data (videorate);
|
||||
videorate->silent = DEFAULT_SILENT;
|
||||
videorate->new_pref = DEFAULT_NEW_PREF;
|
||||
}
|
||||
|
@ -324,29 +336,49 @@ gst_videorate_chain (GstPad * pad, GstData * data)
|
|||
if (GST_IS_EVENT (data)) {
|
||||
GstEvent *event = GST_EVENT (data);
|
||||
|
||||
gst_pad_event_default (pad, event);
|
||||
return;
|
||||
if (!videorate->prevbuf) {
|
||||
gst_pad_event_default (pad, event);
|
||||
return;
|
||||
}
|
||||
if (GST_EVENT_TYPE (event) == GST_EVENT_DISCONTINUOUS) {
|
||||
gint64 etime;
|
||||
|
||||
if (!(gst_event_discont_get_value (event, GST_FORMAT_TIME, &etime)))
|
||||
GST_WARNING ("Got discont but doesn't have GST_FORMAT_TIME value");
|
||||
else {
|
||||
gst_videorate_blank_data (videorate);
|
||||
videorate->first_ts = etime;
|
||||
}
|
||||
gst_pad_event_default (pad, event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
buf = GST_BUFFER (data);
|
||||
|
||||
/* pull in 2 buffers */
|
||||
if (videorate->prevbuf == NULL) {
|
||||
/* We're sure it's a GstBuffer here */
|
||||
videorate->prevbuf = buf;
|
||||
videorate->next_ts = videorate->first_ts = GST_BUFFER_TIMESTAMP (buf);
|
||||
} else {
|
||||
GstClockTime prevtime, intime;
|
||||
gint count = 0;
|
||||
gint64 diff1, diff2;
|
||||
|
||||
prevtime = GST_BUFFER_TIMESTAMP (videorate->prevbuf);
|
||||
intime = GST_BUFFER_TIMESTAMP (buf);
|
||||
/* If it's a GstEvent, we give him the time of the next outputed frame */
|
||||
intime = (GST_IS_EVENT (data))
|
||||
? videorate->next_ts +
|
||||
(1 / videorate->to_fps * GST_SECOND) : GST_BUFFER_TIMESTAMP (buf);
|
||||
|
||||
GST_LOG_OBJECT (videorate,
|
||||
"prev buf %" GST_TIME_FORMAT " new buf %" GST_TIME_FORMAT
|
||||
" outgoing ts %" GST_TIME_FORMAT, GST_TIME_ARGS (prevtime),
|
||||
GST_TIME_ARGS (intime), GST_TIME_ARGS (videorate->next_ts));
|
||||
|
||||
videorate->in++;
|
||||
if (GST_IS_BUFFER (data))
|
||||
videorate->in++;
|
||||
|
||||
/* got 2 buffers, see which one is the best */
|
||||
do {
|
||||
|
@ -375,7 +407,9 @@ gst_videorate_chain (GstPad * pad, GstData * data)
|
|||
GST_BUFFER_SIZE (videorate->prevbuf));
|
||||
GST_BUFFER_TIMESTAMP (outbuf) = videorate->next_ts;
|
||||
videorate->out++;
|
||||
videorate->next_ts = videorate->out / videorate->to_fps * GST_SECOND;
|
||||
videorate->next_ts =
|
||||
videorate->first_ts +
|
||||
(videorate->out / videorate->to_fps * GST_SECOND);
|
||||
GST_BUFFER_DURATION (outbuf) =
|
||||
videorate->next_ts - GST_BUFFER_TIMESTAMP (outbuf);
|
||||
gst_pad_push (videorate->srcpad, GST_DATA (outbuf));
|
||||
|
@ -405,14 +439,17 @@ gst_videorate_chain (GstPad * pad, GstData * data)
|
|||
}
|
||||
GST_LOG_OBJECT (videorate,
|
||||
"left loop, putting new in old, diff1 %" GST_TIME_FORMAT
|
||||
", diff2 %" GST_TIME_FORMAT
|
||||
", diff2 %" GST_TIME_FORMAT ", next_ts %" GST_TIME_FORMAT
|
||||
", in %lld, out %lld, drop %lld, dup %lld", GST_TIME_ARGS (diff1),
|
||||
GST_TIME_ARGS (diff2), videorate->in, videorate->out, videorate->drop,
|
||||
videorate->dup);
|
||||
GST_TIME_ARGS (diff2), GST_TIME_ARGS (videorate->next_ts),
|
||||
videorate->in, videorate->out, videorate->drop, videorate->dup);
|
||||
|
||||
/* swap in new one when it's the best */
|
||||
gst_buffer_unref (videorate->prevbuf);
|
||||
videorate->prevbuf = buf;
|
||||
if (GST_IS_BUFFER (data)) {
|
||||
/* swap in new one when it's the best */
|
||||
gst_buffer_unref (videorate->prevbuf);
|
||||
videorate->prevbuf = buf;
|
||||
} else
|
||||
gst_pad_event_default (pad, GST_EVENT (data));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -473,6 +510,7 @@ gst_videorate_change_state (GstElement * element)
|
|||
|
||||
switch (GST_STATE_TRANSITION (element)) {
|
||||
case GST_STATE_PAUSED_TO_READY:
|
||||
gst_videorate_blank_data (GST_VIDEORATE (element));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue