videorate: Fill the segment on EOS or at least produce enough frames to use the complete buffer duration

Fixes bug #628400.
This commit is contained in:
Sebastian Dröge 2010-09-01 11:33:12 +02:00
parent 20d5c6d05c
commit 4da242a6b2

View file

@ -577,11 +577,55 @@ gst_video_rate_event (GstPad * pad, GstEvent * event)
&videorate->segment);
break;
}
case GST_EVENT_EOS:
/* flush last queued frame */
case GST_EVENT_EOS:{
gint count = 0;
GstFlowReturn res = GST_FLOW_OK;
GST_DEBUG_OBJECT (videorate, "Got EOS");
gst_video_rate_flush_prev (videorate, FALSE);
/* If the segment has a stop position, fill the segment */
if (GST_CLOCK_TIME_IS_VALID (videorate->segment.stop)) {
/* fill up to the end of current segment,
* or only send out the stored buffer if there is no specific stop.
* regardless, prevent going loopy in strange cases */
while (res == GST_FLOW_OK && count <= MAGIC_LIMIT &&
((videorate->next_ts - videorate->segment.accum <
videorate->segment.stop)
|| count < 1)) {
res = gst_video_rate_flush_prev (videorate, count > 0);
count++;
}
} else if (videorate->prevbuf) {
/* Output at least one frame but if the buffer duration is valid, output
* enough frames to use the complete buffer duration */
if (GST_BUFFER_DURATION_IS_VALID (videorate->prevbuf)) {
GstClockTime end_ts =
videorate->next_ts + GST_BUFFER_DURATION (videorate->prevbuf);
while (res == GST_FLOW_OK && count <= MAGIC_LIMIT &&
((videorate->next_ts - videorate->segment.accum < end_ts)
|| count < 1)) {
res = gst_video_rate_flush_prev (videorate, count > 0);
count++;
}
} else {
res = gst_video_rate_flush_prev (videorate, FALSE);
count = 1;
}
}
if (count > 1) {
videorate->dup += count - 1;
if (!videorate->silent)
g_object_notify (G_OBJECT (videorate), "duplicate");
} else if (count == 0) {
videorate->drop++;
if (!videorate->silent)
g_object_notify (G_OBJECT (videorate), "drop");
}
break;
}
case GST_EVENT_FLUSH_STOP:
/* also resets the segment */
GST_DEBUG_OBJECT (videorate, "Got FLUSH_STOP");