mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-23 06:26:23 +00:00
gst/videorate/gstvideorate.c: Handle segment seeks
Original commit message from CVS: * gst/videorate/gstvideorate.c: (gst_videorate_blank_data), (gst_videorate_event), (gst_videorate_chain): Handle segment seeks
This commit is contained in:
parent
99fb91493e
commit
a780198451
3 changed files with 65 additions and 25 deletions
|
@ -1,3 +1,9 @@
|
||||||
|
2005-11-16 Edward Hervey <edward@fluendo.com>
|
||||||
|
|
||||||
|
* gst/videorate/gstvideorate.c: (gst_videorate_blank_data),
|
||||||
|
(gst_videorate_event), (gst_videorate_chain):
|
||||||
|
Handle segment seeks
|
||||||
|
|
||||||
2005-11-16 Wim Taymans <wim@fluendo.com>
|
2005-11-16 Wim Taymans <wim@fluendo.com>
|
||||||
|
|
||||||
* gst-libs/gst/audio/gstbaseaudiosink.c:
|
* gst-libs/gst/audio/gstbaseaudiosink.c:
|
||||||
|
|
2
common
2
common
|
@ -1 +1 @@
|
||||||
Subproject commit 657b549dfb640a76f3d7ab7676e453c801a83dca
|
Subproject commit 3aa0adc0cc4539ec9bb62ccf6d535240dad19e58
|
|
@ -48,11 +48,17 @@ struct _GstVideorate
|
||||||
|
|
||||||
/* video state */
|
/* video state */
|
||||||
gdouble from_fps, to_fps;
|
gdouble from_fps, to_fps;
|
||||||
guint64 next_ts;
|
guint64 next_ts; /* Timestamp of next buffer to output */
|
||||||
guint64 first_ts;
|
guint64 first_ts; /* Timestamp of first buffer */
|
||||||
GstBuffer *prevbuf;
|
GstBuffer *prevbuf;
|
||||||
|
guint64 prev_ts; /* Previous buffer timestamp */
|
||||||
guint64 in, out, dup, drop;
|
guint64 in, out, dup, drop;
|
||||||
|
|
||||||
|
/* segment handling */
|
||||||
|
gint64 segment_start;
|
||||||
|
gint64 segment_stop;
|
||||||
|
gint64 segment_accum;
|
||||||
|
|
||||||
gboolean silent;
|
gboolean silent;
|
||||||
gdouble new_pref;
|
gdouble new_pref;
|
||||||
};
|
};
|
||||||
|
@ -343,6 +349,11 @@ gst_videorate_blank_data (GstVideorate * videorate)
|
||||||
videorate->dup = 0;
|
videorate->dup = 0;
|
||||||
videorate->next_ts = 0LL;
|
videorate->next_ts = 0LL;
|
||||||
videorate->first_ts = 0LL;
|
videorate->first_ts = 0LL;
|
||||||
|
videorate->prev_ts = 0LL;
|
||||||
|
|
||||||
|
videorate->segment_start = 0;
|
||||||
|
videorate->segment_stop = 0;
|
||||||
|
videorate->segment_accum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -377,34 +388,47 @@ gst_videorate_event (GstPad * pad, GstEvent * event)
|
||||||
|
|
||||||
videorate = GST_VIDEORATE (GST_PAD_PARENT (pad));
|
videorate = GST_VIDEORATE (GST_PAD_PARENT (pad));
|
||||||
|
|
||||||
if (!videorate->prevbuf)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_NEWSEGMENT:
|
case GST_EVENT_NEWSEGMENT:
|
||||||
{
|
{
|
||||||
gint64 start, stop;
|
gint64 start, stop, base;
|
||||||
|
gdouble rate;
|
||||||
|
gboolean update;
|
||||||
GstFormat format;
|
GstFormat format;
|
||||||
|
|
||||||
GST_STREAM_LOCK (pad);
|
GST_STREAM_LOCK (pad);
|
||||||
|
|
||||||
gst_event_parse_newsegment (event, NULL, NULL, &format, &start, &stop,
|
gst_event_parse_newsegment (event, &update, &rate, &format, &start, &stop,
|
||||||
NULL);
|
&base);
|
||||||
|
|
||||||
if (format != GST_FORMAT_TIME) {
|
if (format != GST_FORMAT_TIME) {
|
||||||
GST_WARNING ("Got discont but doesn't have GST_FORMAT_TIME value");
|
GST_WARNING ("Got discont but doesn't have GST_FORMAT_TIME value");
|
||||||
} else {
|
} else {
|
||||||
gst_videorate_blank_data (videorate);
|
/*
|
||||||
videorate->first_ts = start;
|
We just want to update the accumulated stream_time.
|
||||||
|
*/
|
||||||
|
videorate->segment_accum +=
|
||||||
|
videorate->segment_stop - videorate->segment_start;
|
||||||
|
videorate->segment_start = start;
|
||||||
|
videorate->segment_stop = stop;
|
||||||
|
GST_DEBUG_OBJECT (videorate, "Updated segment_accum:%" GST_TIME_FORMAT
|
||||||
|
" segment_start:%" GST_TIME_FORMAT " segment_stop:%"
|
||||||
|
GST_TIME_FORMAT, GST_TIME_ARGS (videorate->segment_accum),
|
||||||
|
GST_TIME_ARGS (videorate->segment_start),
|
||||||
|
GST_TIME_ARGS (videorate->segment_stop));
|
||||||
}
|
}
|
||||||
GST_STREAM_UNLOCK (pad);
|
GST_STREAM_UNLOCK (pad);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case GST_EVENT_FLUSH_STOP:
|
||||||
|
{
|
||||||
|
gst_videorate_blank_data (videorate);
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
done:
|
|
||||||
return gst_pad_event_default (pad, event);
|
return gst_pad_event_default (pad, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -426,23 +450,21 @@ gst_videorate_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
if (videorate->prevbuf == NULL) {
|
if (videorate->prevbuf == NULL) {
|
||||||
/* We're sure it's a GstBuffer here */
|
/* We're sure it's a GstBuffer here */
|
||||||
videorate->prevbuf = buffer;
|
videorate->prevbuf = buffer;
|
||||||
videorate->next_ts = videorate->first_ts = GST_BUFFER_TIMESTAMP (buffer);
|
videorate->next_ts = videorate->first_ts = videorate->prev_ts =
|
||||||
|
GST_BUFFER_TIMESTAMP (buffer) - videorate->segment_start +
|
||||||
|
videorate->segment_accum;
|
||||||
} else {
|
} else {
|
||||||
GstClockTime prevtime, intime;
|
GstClockTime prevtime, intime;
|
||||||
gint count = 0;
|
gint count = 0;
|
||||||
gint64 diff1, diff2;
|
gint64 diff1, diff2;
|
||||||
|
|
||||||
prevtime = GST_BUFFER_TIMESTAMP (videorate->prevbuf);
|
prevtime = videorate->prev_ts;
|
||||||
/* If it's a GstEvent, we give him the time of the next outputed frame */
|
intime =
|
||||||
#if 0
|
GST_BUFFER_TIMESTAMP (buffer) - videorate->segment_start +
|
||||||
intime = (GST_IS_EVENT (data))
|
videorate->segment_accum;
|
||||||
? videorate->next_ts +
|
|
||||||
(1 / videorate->to_fps * GST_SECOND) : GST_BUFFER_TIMESTAMP (buffer);
|
|
||||||
#endif
|
|
||||||
intime = GST_BUFFER_TIMESTAMP (buffer);
|
|
||||||
|
|
||||||
GST_LOG_OBJECT (videorate,
|
GST_LOG_OBJECT (videorate,
|
||||||
"prev buf %" GST_TIME_FORMAT " new buf %" GST_TIME_FORMAT
|
"BEGINNING prev buf %" GST_TIME_FORMAT " new buf %" GST_TIME_FORMAT
|
||||||
" outgoing ts %" GST_TIME_FORMAT, GST_TIME_ARGS (prevtime),
|
" outgoing ts %" GST_TIME_FORMAT, GST_TIME_ARGS (prevtime),
|
||||||
GST_TIME_ARGS (intime), GST_TIME_ARGS (videorate->next_ts));
|
GST_TIME_ARGS (intime), GST_TIME_ARGS (videorate->next_ts));
|
||||||
|
|
||||||
|
@ -480,13 +502,22 @@ gst_videorate_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
(videorate->out / videorate->to_fps * GST_SECOND);
|
(videorate->out / videorate->to_fps * GST_SECOND);
|
||||||
GST_BUFFER_DURATION (outbuf) =
|
GST_BUFFER_DURATION (outbuf) =
|
||||||
videorate->next_ts - GST_BUFFER_TIMESTAMP (outbuf);
|
videorate->next_ts - GST_BUFFER_TIMESTAMP (outbuf);
|
||||||
|
/* adapt for looping */
|
||||||
|
GST_BUFFER_TIMESTAMP (outbuf) -= videorate->segment_accum;
|
||||||
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (videorate->srcpad));
|
gst_buffer_set_caps (outbuf, GST_PAD_CAPS (videorate->srcpad));
|
||||||
|
|
||||||
if ((res = gst_pad_push (videorate->srcpad, outbuf)) != GST_FLOW_OK)
|
GST_LOG_OBJECT (videorate,
|
||||||
|
"old is best, dup, pushing buffer outgoing ts %" GST_TIME_FORMAT,
|
||||||
|
GST_TIME_ARGS (videorate->next_ts));
|
||||||
|
|
||||||
|
if ((res = gst_pad_push (videorate->srcpad, outbuf)) != GST_FLOW_OK) {
|
||||||
|
GST_WARNING_OBJECT (videorate, "couldn't push buffer on srcpad:%d",
|
||||||
|
res);
|
||||||
goto done;
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
GST_LOG_OBJECT (videorate,
|
GST_LOG_OBJECT (videorate,
|
||||||
"old is best, dup, outgoing ts %" GST_TIME_FORMAT,
|
"old is best, dup, pushed buffer outgoing ts %" GST_TIME_FORMAT,
|
||||||
GST_TIME_ARGS (videorate->next_ts));
|
GST_TIME_ARGS (videorate->next_ts));
|
||||||
}
|
}
|
||||||
/* continue while the first one was the best */
|
/* continue while the first one was the best */
|
||||||
|
@ -509,7 +540,7 @@ gst_videorate_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
GST_TIME_FORMAT, GST_TIME_ARGS (videorate->next_ts));
|
GST_TIME_FORMAT, GST_TIME_ARGS (videorate->next_ts));
|
||||||
}
|
}
|
||||||
GST_LOG_OBJECT (videorate,
|
GST_LOG_OBJECT (videorate,
|
||||||
"left loop, putting new in old, diff1 %" GST_TIME_FORMAT
|
"END, putting new in old, diff1 %" GST_TIME_FORMAT
|
||||||
", diff2 %" GST_TIME_FORMAT ", next_ts %" GST_TIME_FORMAT
|
", diff2 %" GST_TIME_FORMAT ", next_ts %" GST_TIME_FORMAT
|
||||||
", in %lld, out %lld, drop %lld, dup %lld", GST_TIME_ARGS (diff1),
|
", in %lld, out %lld, drop %lld, dup %lld", GST_TIME_ARGS (diff1),
|
||||||
GST_TIME_ARGS (diff2), GST_TIME_ARGS (videorate->next_ts),
|
GST_TIME_ARGS (diff2), GST_TIME_ARGS (videorate->next_ts),
|
||||||
|
@ -518,6 +549,9 @@ gst_videorate_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
/* swap in new one when it's the best */
|
/* swap in new one when it's the best */
|
||||||
gst_buffer_unref (videorate->prevbuf);
|
gst_buffer_unref (videorate->prevbuf);
|
||||||
videorate->prevbuf = buffer;
|
videorate->prevbuf = buffer;
|
||||||
|
videorate->prev_ts =
|
||||||
|
GST_BUFFER_TIMESTAMP (buffer) - videorate->segment_start +
|
||||||
|
videorate->segment_accum;
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue