mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 19:51:11 +00:00
videorate: Add a max-closing-segment-duplication-duration
property
This allows users to let videorate fully fill the segments when received EOS or on new segment, removing an arbitrary limit of 25 duplicates which might not be what the user wants (for example on low FPS stream in GES, that sometimes leaded to broken behavior) Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3000>
This commit is contained in:
parent
515e1b55ee
commit
bb840bd116
13 changed files with 442 additions and 49 deletions
|
@ -14153,6 +14153,20 @@
|
|||
"type": "guint64",
|
||||
"writable": false
|
||||
},
|
||||
"max-closing-segment-duplication-duration": {
|
||||
"blurb": "Maximum duration of duplicated buffers to close current segment",
|
||||
"conditionally-available": false,
|
||||
"construct": false,
|
||||
"construct-only": false,
|
||||
"controllable": false,
|
||||
"default": "1000000000",
|
||||
"max": "18446744073709551615",
|
||||
"min": "0",
|
||||
"mutable": "null",
|
||||
"readable": true,
|
||||
"type": "guint64",
|
||||
"writable": true
|
||||
},
|
||||
"max-duplication-time": {
|
||||
"blurb": "Do not duplicate frames if the gap exceeds this period (in ns) (0 = disabled)",
|
||||
"conditionally-available": false,
|
||||
|
|
|
@ -100,6 +100,7 @@ enum
|
|||
#define DEFAULT_MAX_RATE G_MAXINT
|
||||
#define DEFAULT_RATE 1.0
|
||||
#define DEFAULT_MAX_DUPLICATION_TIME 0
|
||||
#define DEFAULT_MAX_CLOSING_SEGMENT_DUPLICATION_DURATION GST_SECOND
|
||||
|
||||
enum
|
||||
{
|
||||
|
@ -115,7 +116,8 @@ enum
|
|||
PROP_AVERAGE_PERIOD,
|
||||
PROP_MAX_RATE,
|
||||
PROP_RATE,
|
||||
PROP_MAX_DUPLICATION_TIME
|
||||
PROP_MAX_DUPLICATION_TIME,
|
||||
PROP_MAX_CLOSING_SEGMENT_DUPLICATION_DURATION
|
||||
};
|
||||
|
||||
static GstStaticPadTemplate gst_video_rate_src_template =
|
||||
|
@ -295,6 +297,27 @@ gst_video_rate_class_init (GstVideoRateClass * klass)
|
|||
0, G_MAXUINT64, DEFAULT_MAX_DUPLICATION_TIME,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* GstVideoRate:max-closing-segment-duplication-duration:
|
||||
*
|
||||
* Limits the maximum duration for which the last buffer is duplicated when
|
||||
* finalizing a segment or on EOS. When receiving an EOS event or a new
|
||||
* segment, videorate duplicates the last frame to close the configured
|
||||
* segment (copying the last buffer until its #GstSegment.stop time (or
|
||||
* #GstSegment.start time for reverse playback) is reached), this property
|
||||
* ensures that it won't push buffers covering a duration longer than
|
||||
* specified.
|
||||
*
|
||||
* Since: 1.22
|
||||
*/
|
||||
g_object_class_install_property (object_class,
|
||||
PROP_MAX_CLOSING_SEGMENT_DUPLICATION_DURATION,
|
||||
g_param_spec_uint64 ("max-closing-segment-duplication-duration",
|
||||
"Maximum closing segment duplication duration",
|
||||
"Maximum duration of duplicated buffers to close current segment", 0,
|
||||
G_MAXUINT64, DEFAULT_MAX_CLOSING_SEGMENT_DUPLICATION_DURATION,
|
||||
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
||||
|
||||
gst_element_class_set_static_metadata (element_class,
|
||||
"Video rate adjuster", "Filter/Effect/Video",
|
||||
"Drops/duplicates/adjusts timestamps on video frames to make a perfect stream",
|
||||
|
@ -637,6 +660,8 @@ gst_video_rate_init (GstVideoRate * videorate)
|
|||
videorate->rate = DEFAULT_RATE;
|
||||
videorate->pending_rate = DEFAULT_RATE;
|
||||
videorate->max_duplication_time = DEFAULT_MAX_DUPLICATION_TIME;
|
||||
videorate->max_closing_segment_duplication_duration =
|
||||
DEFAULT_MAX_CLOSING_SEGMENT_DUPLICATION_DURATION;
|
||||
|
||||
videorate->from_rate_numerator = 0;
|
||||
videorate->from_rate_denominator = 0;
|
||||
|
@ -782,7 +807,90 @@ gst_video_rate_notify_duplicate (GstVideoRate * videorate)
|
|||
g_object_notify_by_pspec ((GObject *) videorate, pspec_duplicate);
|
||||
}
|
||||
|
||||
#define MAGIC_LIMIT 25
|
||||
static gboolean
|
||||
gst_video_rate_check_duplicate_to_close_segment (GstVideoRate * videorate,
|
||||
GstClockTime last_input_ts, gboolean is_first)
|
||||
{
|
||||
GstClockTime next_stream_time = videorate->next_ts - videorate->segment.base;
|
||||
GstClockTime max_closing_segment_duplication_duration =
|
||||
videorate->max_closing_segment_duplication_duration;
|
||||
|
||||
if (!GST_CLOCK_TIME_IS_VALID (videorate->next_ts))
|
||||
return FALSE;
|
||||
|
||||
if (videorate->segment.rate > 0.0) {
|
||||
|
||||
if (!GST_CLOCK_TIME_IS_VALID (videorate->segment.stop)) {
|
||||
/* Ensure that if no 'stop' is set, we push the last frame anyway */
|
||||
return is_first;
|
||||
}
|
||||
|
||||
if (next_stream_time >= videorate->segment.stop)
|
||||
return FALSE;
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (max_closing_segment_duplication_duration)) {
|
||||
if (last_input_ts > videorate->next_ts)
|
||||
return TRUE;
|
||||
|
||||
return (videorate->next_ts - last_input_ts <
|
||||
max_closing_segment_duplication_duration);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Reverse playback */
|
||||
|
||||
if (!GST_CLOCK_TIME_IS_VALID (videorate->segment.start)) {
|
||||
/* Ensure that if no 'start' is set, we push the last frame anyway */
|
||||
return is_first;
|
||||
}
|
||||
|
||||
if (next_stream_time < videorate->segment.start)
|
||||
return FALSE;
|
||||
|
||||
if (GST_CLOCK_TIME_IS_VALID (max_closing_segment_duplication_duration)) {
|
||||
if (last_input_ts < videorate->next_ts)
|
||||
return TRUE;
|
||||
|
||||
return (last_input_ts - videorate->next_ts <
|
||||
max_closing_segment_duplication_duration);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gint
|
||||
gst_video_rate_duplicate_to_close_segment (GstVideoRate * videorate)
|
||||
{
|
||||
gint count = 0;
|
||||
GstFlowReturn res;
|
||||
GstClockTime last_input_ts = videorate->prev_ts;
|
||||
|
||||
if (videorate->drop_only)
|
||||
return count;
|
||||
|
||||
if (!videorate->prevbuf) {
|
||||
GST_INFO_OBJECT (videorate, "got EOS before any buffer was received");
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
res = GST_FLOW_OK;
|
||||
/* fill up to the end of current segment */
|
||||
while (res == GST_FLOW_OK
|
||||
&& gst_video_rate_check_duplicate_to_close_segment (videorate,
|
||||
last_input_ts, count < 1)) {
|
||||
res =
|
||||
gst_video_rate_flush_prev (videorate, count > 0, GST_CLOCK_TIME_NONE,
|
||||
FALSE);
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_video_rate_sink_event (GstBaseTransform * trans, GstEvent * event)
|
||||
{
|
||||
|
@ -804,30 +912,8 @@ gst_video_rate_sink_event (GstBaseTransform * trans, GstEvent * event)
|
|||
|
||||
/* close up the previous segment, if appropriate */
|
||||
if (videorate->prevbuf) {
|
||||
gint count = 0;
|
||||
GstFlowReturn res;
|
||||
|
||||
res = GST_FLOW_OK;
|
||||
/* 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->drop_only
|
||||
&& ((videorate->segment.rate > 0.0
|
||||
&& GST_CLOCK_TIME_IS_VALID (videorate->segment.stop)
|
||||
&& GST_CLOCK_TIME_IS_VALID (videorate->next_ts)
|
||||
&& videorate->next_ts - videorate->segment.base <
|
||||
videorate->segment.stop) || (videorate->segment.rate < 0.0
|
||||
&& GST_CLOCK_TIME_IS_VALID (videorate->segment.start)
|
||||
&& GST_CLOCK_TIME_IS_VALID (videorate->next_ts)
|
||||
&& videorate->next_ts - videorate->segment.base >=
|
||||
videorate->segment.start)
|
||||
|| count < 1)) {
|
||||
res =
|
||||
gst_video_rate_flush_prev (videorate, count > 0,
|
||||
GST_CLOCK_TIME_NONE, FALSE);
|
||||
count++;
|
||||
}
|
||||
/* fill up to the end of current segment */
|
||||
gint count = gst_video_rate_duplicate_to_close_segment (videorate);
|
||||
if (count > 1) {
|
||||
videorate->dup += count - 1;
|
||||
if (!videorate->silent)
|
||||
|
@ -871,34 +957,23 @@ gst_video_rate_sink_event (GstBaseTransform * trans, GstEvent * event)
|
|||
|
||||
/* 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->drop_only
|
||||
&& ((videorate->segment.rate > 0.0
|
||||
&& GST_CLOCK_TIME_IS_VALID (videorate->segment.stop)
|
||||
&& GST_CLOCK_TIME_IS_VALID (videorate->next_ts)
|
||||
&& videorate->next_ts - videorate->segment.base <
|
||||
videorate->segment.stop) || (videorate->segment.rate < 0.0
|
||||
&& GST_CLOCK_TIME_IS_VALID (videorate->segment.start)
|
||||
&& GST_CLOCK_TIME_IS_VALID (videorate->next_ts)
|
||||
&& videorate->next_ts - videorate->segment.base >=
|
||||
videorate->segment.start)
|
||||
)) {
|
||||
res = gst_video_rate_flush_prev (videorate, count > 0,
|
||||
GST_CLOCK_TIME_NONE, FALSE);
|
||||
count++;
|
||||
}
|
||||
/* fill up to the end of current segment */
|
||||
count = gst_video_rate_duplicate_to_close_segment (videorate);
|
||||
} else if (!videorate->drop_only && 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);
|
||||
GstClockTime end_ts, duration =
|
||||
GST_BUFFER_DURATION (videorate->prevbuf);
|
||||
|
||||
while (res == GST_FLOW_OK && count <= MAGIC_LIMIT &&
|
||||
((videorate->segment.rate > 0.0
|
||||
if (GST_CLOCK_TIME_IS_VALID
|
||||
(videorate->max_closing_segment_duplication_duration))
|
||||
duration =
|
||||
MIN (videorate->max_closing_segment_duplication_duration,
|
||||
duration);
|
||||
|
||||
end_ts = videorate->next_ts + duration;
|
||||
while (res == GST_FLOW_OK && ((videorate->segment.rate > 0.0
|
||||
&& GST_CLOCK_TIME_IS_VALID (videorate->segment.stop)
|
||||
&& GST_CLOCK_TIME_IS_VALID (videorate->next_ts)
|
||||
&& videorate->next_ts - videorate->segment.base < end_ts)
|
||||
|
@ -1839,6 +1914,10 @@ gst_video_rate_set_property (GObject * object,
|
|||
case PROP_MAX_DUPLICATION_TIME:
|
||||
videorate->max_duplication_time = g_value_get_uint64 (value);
|
||||
break;
|
||||
case PROP_MAX_CLOSING_SEGMENT_DUPLICATION_DURATION:
|
||||
videorate->max_closing_segment_duplication_duration =
|
||||
g_value_get_uint64 (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -1901,6 +1980,10 @@ gst_video_rate_get_property (GObject * object,
|
|||
case PROP_MAX_DUPLICATION_TIME:
|
||||
g_value_set_uint64 (value, videorate->max_duplication_time);
|
||||
break;
|
||||
case PROP_MAX_CLOSING_SEGMENT_DUPLICATION_DURATION:
|
||||
g_value_set_uint64 (value,
|
||||
videorate->max_closing_segment_duplication_duration);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
|
@ -58,6 +58,7 @@ struct _GstVideoRate
|
|||
gboolean force_variable_rate;
|
||||
gboolean updating_caps;
|
||||
guint64 max_duplication_time;
|
||||
guint64 max_closing_segment_duplication_duration;
|
||||
|
||||
/* segment handling */
|
||||
GstSegment segment;
|
||||
|
|
|
@ -17,6 +17,9 @@ tests = [
|
|||
'videorate/rate_0_5_with_decoder',
|
||||
'videorate/rate_2_0',
|
||||
'videorate/rate_2_0_with_decoder',
|
||||
'videorate/duplicate_on_eos',
|
||||
'videorate/duplicate_on_eos_disbaled',
|
||||
'videorate/duplicate_on_eos_half_sec',
|
||||
'compositor/renogotiate_failing_unsupported_src_format',
|
||||
'giosrc/read-growing-file',
|
||||
'encodebin/set-encoder-properties',
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
meta,
|
||||
args = {
|
||||
"videotestsrc pattern=ball animation-mode=frames ! video/x-raw,format=I420,framerate=1/1,width=320,height=240 ! videorate name=videorate ! video/x-raw,framerate=30/1 ! fakesink sync=true qos=true",
|
||||
},
|
||||
configs = {
|
||||
"$(validateflow), pad=videorate:sink, buffers-checksum=as-id, ignored-event-types={ tag }",
|
||||
"$(validateflow), pad=videorate:src, buffers-checksum=as-id, ignored-event-types={ tag }",
|
||||
},
|
||||
handles-states=true,
|
||||
ignore-eos=true
|
||||
|
||||
pause
|
||||
|
||||
seek, flags=flush+accurate, start=0, stop=3.0
|
||||
play
|
||||
crank-clock, repeat=91
|
||||
wait, message-type=eos
|
||||
|
||||
# Last buffer is duplicated until the full segment is filled
|
||||
check-position, expected-position=3.0
|
||||
stop
|
|
@ -0,0 +1,12 @@
|
|||
event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
|
||||
event caps: video/x-raw, format=(string)I420, framerate=(fraction)1/1, height=(int)240, interlace-mode=(string)progressive, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, width=(int)320;
|
||||
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
|
||||
buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:01.000000000, flags=discont
|
||||
buffer: content-id=1, pts=0:00:01.000000000, dur=0:00:01.000000000
|
||||
event flush-start: (no structure)
|
||||
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
|
||||
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=0:00:03.000000000, flags=0x01, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
|
||||
buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:01.000000000, flags=discont
|
||||
buffer: content-id=1, pts=0:00:01.000000000, dur=0:00:01.000000000
|
||||
buffer: content-id=2, pts=0:00:02.000000000, dur=0:00:01.000000000
|
||||
event eos: (no structure)
|
|
@ -0,0 +1,98 @@
|
|||
event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
|
||||
event caps: video/x-raw, format=(string)I420, framerate=(fraction)30/1, height=(int)240, interlace-mode=(string)progressive, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, width=(int)320;
|
||||
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
|
||||
buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:00.033333333, flags=discont
|
||||
event flush-start: (no structure)
|
||||
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
|
||||
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=0:00:03.000000000, flags=0x01, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
|
||||
buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:00.033333333, flags=discont
|
||||
buffer: content-id=0, pts=0:00:00.033333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.066666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.100000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.133333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.166666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.200000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.233333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.266666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.300000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.333333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.366666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.400000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.433333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.466666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.500000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.533333333, dur=0:00:00.033333333
|
||||
buffer: content-id=1, pts=0:00:00.566666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.600000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.633333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.666666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.700000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.733333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.766666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.800000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.833333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.866666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.900000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.933333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.966666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.000000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.033333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.066666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.100000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.133333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.166666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.200000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.233333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.266666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.300000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.333333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.366666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.400000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.433333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.466666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.500000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:01.533333333, dur=0:00:00.033333333
|
||||
buffer: content-id=2, pts=0:00:01.566666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=2, pts=0:00:01.600000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:01.633333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:01.666666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=2, pts=0:00:01.700000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:01.733333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:01.766666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=2, pts=0:00:01.800000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:01.833333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:01.866666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=2, pts=0:00:01.900000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:01.933333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:01.966666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.000000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.033333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.066666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.100000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.133333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.166666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.200000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.233333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.266666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.300000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.333333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.366666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.400000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.433333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.466666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.500000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.533333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.566666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.600000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.633333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.666666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.700000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.733333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.766666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.800000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.833333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.866666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.900000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.933333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=2, pts=0:00:02.966666666, dur=0:00:00.033333334, flags=gap
|
||||
event eos: (no structure)
|
|
@ -0,0 +1,23 @@
|
|||
meta,
|
||||
args = {
|
||||
"videotestsrc pattern=ball animation-mode=frames ! video/x-raw,format=I420,framerate=1/1,width=320,height=240 ! videorate max-closing-segment-duplication-duration=0 name=videorate ! video/x-raw,framerate=30/1 ! fakesink sync=true qos=true",
|
||||
},
|
||||
configs = {
|
||||
"$(validateflow), pad=videorate:sink, buffers-checksum=as-id, ignored-event-types={ tag }",
|
||||
"$(validateflow), pad=videorate:src, buffers-checksum=as-id, ignored-event-types={ tag }",
|
||||
},
|
||||
handles-states=true,
|
||||
ignore-eos=true
|
||||
|
||||
pause
|
||||
|
||||
seek, flags=flush+accurate, start=0, stop=2.0
|
||||
play
|
||||
crank-clock, repeat=31
|
||||
wait, message-type=eos
|
||||
|
||||
# Second buffer won't be duplicated as we disabled on on EOS
|
||||
check-position, expected-position=1.0
|
||||
stop
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
|
||||
event caps: video/x-raw, format=(string)I420, framerate=(fraction)1/1, height=(int)240, interlace-mode=(string)progressive, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, width=(int)320;
|
||||
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
|
||||
buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:01.000000000, flags=discont
|
||||
buffer: content-id=1, pts=0:00:01.000000000, dur=0:00:01.000000000
|
||||
event flush-start: (no structure)
|
||||
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
|
||||
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=0:00:02.000000000, flags=0x01, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
|
||||
buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:01.000000000, flags=discont
|
||||
buffer: content-id=1, pts=0:00:01.000000000, dur=0:00:01.000000000
|
||||
event eos: (no structure)
|
|
@ -0,0 +1,38 @@
|
|||
event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
|
||||
event caps: video/x-raw, format=(string)I420, framerate=(fraction)30/1, height=(int)240, interlace-mode=(string)progressive, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, width=(int)320;
|
||||
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
|
||||
buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:00.033333333, flags=discont
|
||||
event flush-start: (no structure)
|
||||
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
|
||||
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=0:00:02.000000000, flags=0x01, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
|
||||
buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:00.033333333, flags=discont
|
||||
buffer: content-id=0, pts=0:00:00.033333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.066666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.100000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.133333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.166666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.200000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.233333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.266666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.300000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.333333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.366666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.400000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.433333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.466666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.500000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.533333333, dur=0:00:00.033333333
|
||||
buffer: content-id=1, pts=0:00:00.566666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.600000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.633333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.666666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.700000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.733333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.766666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.800000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.833333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.866666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.900000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.933333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.966666666, dur=0:00:00.033333334, flags=gap
|
||||
event eos: (no structure)
|
|
@ -0,0 +1,25 @@
|
|||
meta,
|
||||
args = {
|
||||
"videotestsrc pattern=ball animation-mode=frames ! video/x-raw,format=I420,framerate=1/1,width=320,height=240 ! videorate max-closing-segment-duplication-duration=500000000 name=videorate ! video/x-raw,framerate=30/1 ! fakesink sync=true qos=true",
|
||||
},
|
||||
configs = {
|
||||
"$(validateflow), pad=videorate:sink, buffers-checksum=as-id, ignored-event-types={ tag }",
|
||||
"$(validateflow), pad=videorate:src, buffers-checksum=as-id, ignored-event-types={ tag }",
|
||||
},
|
||||
handles-states=true,
|
||||
ignore-eos=true
|
||||
|
||||
pause
|
||||
|
||||
seek, flags=flush+accurate, start=0, stop=2.0
|
||||
play
|
||||
crank-clock, repeat=46
|
||||
wait, message-type=eos
|
||||
|
||||
# At most 0.5 second can be output after EOS, meaning that after the second
|
||||
# buffer (which starts at 1) videorate will duplicate the frame for 0.5 secs
|
||||
check-position, expected-position=1.5
|
||||
stop
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
|
||||
event caps: video/x-raw, format=(string)I420, framerate=(fraction)1/1, height=(int)240, interlace-mode=(string)progressive, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, width=(int)320;
|
||||
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
|
||||
buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:01.000000000, flags=discont
|
||||
buffer: content-id=1, pts=0:00:01.000000000, dur=0:00:01.000000000
|
||||
event flush-start: (no structure)
|
||||
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
|
||||
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=0:00:02.000000000, flags=0x01, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
|
||||
buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:01.000000000, flags=discont
|
||||
buffer: content-id=1, pts=0:00:01.000000000, dur=0:00:01.000000000
|
||||
event eos: (no structure)
|
|
@ -0,0 +1,53 @@
|
|||
event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1;
|
||||
event caps: video/x-raw, format=(string)I420, framerate=(fraction)30/1, height=(int)240, interlace-mode=(string)progressive, multiview-mode=(string)mono, pixel-aspect-ratio=(fraction)1/1, width=(int)320;
|
||||
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
|
||||
buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:00.033333333, flags=discont
|
||||
event flush-start: (no structure)
|
||||
event flush-stop: GstEventFlushStop, reset-time=(boolean)true;
|
||||
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=0:00:02.000000000, flags=0x01, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
|
||||
buffer: content-id=0, pts=0:00:00.000000000, dur=0:00:00.033333333, flags=discont
|
||||
buffer: content-id=0, pts=0:00:00.033333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.066666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.100000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.133333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.166666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.200000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.233333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.266666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.300000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.333333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.366666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.400000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.433333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.466666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=0, pts=0:00:00.500000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.533333333, dur=0:00:00.033333333
|
||||
buffer: content-id=1, pts=0:00:00.566666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.600000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.633333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.666666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.700000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.733333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.766666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.800000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.833333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.866666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.900000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.933333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:00.966666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.000000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.033333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.066666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.100000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.133333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.166666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.200000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.233333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.266666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.300000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.333333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.366666666, dur=0:00:00.033333334, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.400000000, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.433333333, dur=0:00:00.033333333, flags=gap
|
||||
buffer: content-id=1, pts=0:00:01.466666666, dur=0:00:00.033333334, flags=gap
|
||||
event eos: (no structure)
|
Loading…
Reference in a new issue