mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-12 18:35:35 +00:00
videorate: fix assertion when pushing last and only buffer without duration
Fixing this pipeline: gst-launch-1.0 filesrc location=sample.png ! pngdec ! videorate ! fakesink - videorate receives a single buffer with pts = 0, duration = invalid; - then it receives eos triggering this buffer to be pushed downstream; - the pushing code was assuming that a duration was set, which is impossible as we received a single buffer and no output framerate was set either. So the best we can do is to push the buffer without duration. Fix #1177 Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/2320>
This commit is contained in:
parent
b8462b0624
commit
69b205613f
1 changed files with 18 additions and 12 deletions
|
@ -649,7 +649,7 @@ gst_video_rate_init (GstVideoRate * videorate)
|
||||||
/* @outbuf: (transfer full) needs to be writable */
|
/* @outbuf: (transfer full) needs to be writable */
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_video_rate_push_buffer (GstVideoRate * videorate, GstBuffer * outbuf,
|
gst_video_rate_push_buffer (GstVideoRate * videorate, GstBuffer * outbuf,
|
||||||
gboolean duplicate, GstClockTime next_intime)
|
gboolean duplicate, GstClockTime next_intime, gboolean invalid_duration)
|
||||||
{
|
{
|
||||||
GstFlowReturn res;
|
GstFlowReturn res;
|
||||||
GstClockTime push_ts;
|
GstClockTime push_ts;
|
||||||
|
@ -707,7 +707,7 @@ gst_video_rate_push_buffer (GstVideoRate * videorate, GstBuffer * outbuf,
|
||||||
videorate->to_rate_denominator * GST_SECOND,
|
videorate->to_rate_denominator * GST_SECOND,
|
||||||
videorate->to_rate_numerator);
|
videorate->to_rate_numerator);
|
||||||
GST_BUFFER_DURATION (outbuf) = videorate->next_ts - push_ts;
|
GST_BUFFER_DURATION (outbuf) = videorate->next_ts - push_ts;
|
||||||
} else {
|
} else if (!invalid_duration) {
|
||||||
/* There must always be a valid duration on prevbuf if rate > 0,
|
/* There must always be a valid duration on prevbuf if rate > 0,
|
||||||
* it is ensured in the transform_ip function */
|
* it is ensured in the transform_ip function */
|
||||||
g_assert (GST_BUFFER_PTS_IS_VALID (outbuf));
|
g_assert (GST_BUFFER_PTS_IS_VALID (outbuf));
|
||||||
|
@ -737,7 +737,7 @@ gst_video_rate_push_buffer (GstVideoRate * videorate, GstBuffer * outbuf,
|
||||||
/* flush the oldest buffer */
|
/* flush the oldest buffer */
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
gst_video_rate_flush_prev (GstVideoRate * videorate, gboolean duplicate,
|
gst_video_rate_flush_prev (GstVideoRate * videorate, gboolean duplicate,
|
||||||
GstClockTime next_intime)
|
GstClockTime next_intime, gboolean invalid_duration)
|
||||||
{
|
{
|
||||||
GstBuffer *outbuf;
|
GstBuffer *outbuf;
|
||||||
|
|
||||||
|
@ -748,7 +748,8 @@ gst_video_rate_flush_prev (GstVideoRate * videorate, gboolean duplicate,
|
||||||
/* make sure we can write to the metadata */
|
/* make sure we can write to the metadata */
|
||||||
outbuf = gst_buffer_make_writable (outbuf);
|
outbuf = gst_buffer_make_writable (outbuf);
|
||||||
|
|
||||||
return gst_video_rate_push_buffer (videorate, outbuf, duplicate, next_intime);
|
return gst_video_rate_push_buffer (videorate, outbuf, duplicate, next_intime,
|
||||||
|
invalid_duration);
|
||||||
|
|
||||||
/* WARNINGS */
|
/* WARNINGS */
|
||||||
eos_before_buffers:
|
eos_before_buffers:
|
||||||
|
@ -824,7 +825,7 @@ gst_video_rate_sink_event (GstBaseTransform * trans, GstEvent * event)
|
||||||
|| count < 1)) {
|
|| count < 1)) {
|
||||||
res =
|
res =
|
||||||
gst_video_rate_flush_prev (videorate, count > 0,
|
gst_video_rate_flush_prev (videorate, count > 0,
|
||||||
GST_CLOCK_TIME_NONE);
|
GST_CLOCK_TIME_NONE, FALSE);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
if (count > 1) {
|
if (count > 1) {
|
||||||
|
@ -886,7 +887,7 @@ gst_video_rate_sink_event (GstBaseTransform * trans, GstEvent * event)
|
||||||
videorate->segment.start)
|
videorate->segment.start)
|
||||||
)) {
|
)) {
|
||||||
res = gst_video_rate_flush_prev (videorate, count > 0,
|
res = gst_video_rate_flush_prev (videorate, count > 0,
|
||||||
GST_CLOCK_TIME_NONE);
|
GST_CLOCK_TIME_NONE, FALSE);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
} else if (!videorate->drop_only && videorate->prevbuf) {
|
} else if (!videorate->drop_only && videorate->prevbuf) {
|
||||||
|
@ -904,12 +905,15 @@ gst_video_rate_sink_event (GstBaseTransform * trans, GstEvent * event)
|
||||||
|| count < 1)) {
|
|| count < 1)) {
|
||||||
res =
|
res =
|
||||||
gst_video_rate_flush_prev (videorate, count > 0,
|
gst_video_rate_flush_prev (videorate, count > 0,
|
||||||
GST_CLOCK_TIME_NONE);
|
GST_CLOCK_TIME_NONE, FALSE);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
/* allow the duration to be invalid as there is no way to infer it if we
|
||||||
|
* received a single buffer and not output framerate was set. */
|
||||||
res =
|
res =
|
||||||
gst_video_rate_flush_prev (videorate, FALSE, GST_CLOCK_TIME_NONE);
|
gst_video_rate_flush_prev (videorate, FALSE, GST_CLOCK_TIME_NONE,
|
||||||
|
TRUE);
|
||||||
count = 1;
|
count = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1397,12 +1401,14 @@ gst_video_rate_do_max_duplicate (GstVideoRate * videorate, GstBuffer * buffer,
|
||||||
* previous buffer */
|
* previous buffer */
|
||||||
if (videorate->segment.rate < 0.0) {
|
if (videorate->segment.rate < 0.0) {
|
||||||
while (videorate->next_ts > prevtime) {
|
while (videorate->next_ts > prevtime) {
|
||||||
gst_video_rate_flush_prev (videorate, *count > 0, GST_CLOCK_TIME_NONE);
|
gst_video_rate_flush_prev (videorate, *count > 0, GST_CLOCK_TIME_NONE,
|
||||||
|
FALSE);
|
||||||
*count += 1;
|
*count += 1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (videorate->next_ts <= prevtime) {
|
while (videorate->next_ts <= prevtime) {
|
||||||
gst_video_rate_flush_prev (videorate, *count > 0, GST_CLOCK_TIME_NONE);
|
gst_video_rate_flush_prev (videorate, *count > 0, GST_CLOCK_TIME_NONE,
|
||||||
|
FALSE);
|
||||||
*count += 1;
|
*count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1582,7 +1588,7 @@ gst_video_rate_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
|
||||||
* GstBaseTransform can get its reference back. */
|
* GstBaseTransform can get its reference back. */
|
||||||
if ((r = gst_video_rate_push_buffer (videorate,
|
if ((r = gst_video_rate_push_buffer (videorate,
|
||||||
gst_buffer_ref (buffer), FALSE,
|
gst_buffer_ref (buffer), FALSE,
|
||||||
GST_CLOCK_TIME_NONE)) != GST_FLOW_OK) {
|
GST_CLOCK_TIME_NONE, FALSE)) != GST_FLOW_OK) {
|
||||||
res = r;
|
res = r;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -1710,7 +1716,7 @@ gst_video_rate_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
|
||||||
|
|
||||||
/* on error the _flush function posted a warning already */
|
/* on error the _flush function posted a warning already */
|
||||||
if ((r = gst_video_rate_flush_prev (videorate,
|
if ((r = gst_video_rate_flush_prev (videorate,
|
||||||
count > 1, intime)) != GST_FLOW_OK) {
|
count > 1, intime, FALSE)) != GST_FLOW_OK) {
|
||||||
res = r;
|
res = r;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue