videorate: Add a property to force dropping out of segment buffers

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5725>
This commit is contained in:
Thibault Saunier 2023-11-28 11:39:58 -03:00 committed by GStreamer Marge Bot
parent 6dc86b1f91
commit f59219228f
7 changed files with 88 additions and 2 deletions

View file

@ -15138,6 +15138,18 @@
"type": "gboolean",
"writable": true
},
"drop-out-of-segment": {
"blurb": "Drop out of segment buffers",
"conditionally-available": false,
"construct": false,
"construct-only": false,
"controllable": false,
"default": "false",
"mutable": "null",
"readable": true,
"type": "gboolean",
"writable": true
},
"duplicate": {
"blurb": "Number of duplicated frames",
"conditionally-available": false,

View file

@ -101,6 +101,7 @@ enum
#define DEFAULT_RATE 1.0
#define DEFAULT_MAX_DUPLICATION_TIME 0
#define DEFAULT_MAX_CLOSING_SEGMENT_DUPLICATION_DURATION GST_SECOND
#define DEFAULT_DROP_OUT_OF_SEGMENT FALSE
enum
{
@ -117,7 +118,8 @@ enum
PROP_MAX_RATE,
PROP_RATE,
PROP_MAX_DUPLICATION_TIME,
PROP_MAX_CLOSING_SEGMENT_DUPLICATION_DURATION
PROP_MAX_CLOSING_SEGMENT_DUPLICATION_DURATION,
PROP_DROP_OUT_OF_SEGMENT
};
static GstStaticPadTemplate gst_video_rate_src_template =
@ -318,6 +320,19 @@ gst_video_rate_class_init (GstVideoRateClass * klass)
G_MAXUINT64, DEFAULT_MAX_CLOSING_SEGMENT_DUPLICATION_DURATION,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
/**
* GstVideoRate:drop-out-of-segment:
*
* Drop all frames that are out of segment
*
* Since: 1.24
*/
g_object_class_install_property (object_class, PROP_DROP_OUT_OF_SEGMENT,
g_param_spec_boolean ("drop-out-of-segment",
"Drop out of segment buffers", "Drop out of segment buffers",
DEFAULT_DROP_OUT_OF_SEGMENT,
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",
@ -660,6 +675,7 @@ gst_video_rate_init (GstVideoRate * videorate)
videorate->silent = DEFAULT_SILENT;
videorate->new_pref = DEFAULT_NEW_PREF;
videorate->drop_only = DEFAULT_DROP_ONLY;
videorate->drop_out_of_segment = DEFAULT_DROP_OUT_OF_SEGMENT;
videorate->average_period = DEFAULT_AVERAGE_PERIOD;
videorate->average_period_set = DEFAULT_AVERAGE_PERIOD;
videorate->max_rate = DEFAULT_MAX_RATE;
@ -682,7 +698,7 @@ static GstFlowReturn
gst_video_rate_push_buffer (GstVideoRate * videorate, GstBuffer * outbuf,
gboolean duplicate, GstClockTime next_intime, gboolean invalid_duration)
{
GstFlowReturn res;
GstFlowReturn res = GST_FLOW_OK;
GstClockTime push_ts;
GST_BUFFER_OFFSET (outbuf) = videorate->out;
@ -760,6 +776,17 @@ gst_video_rate_push_buffer (GstVideoRate * videorate, GstBuffer * outbuf,
"old is best, dup, pushing buffer outgoing ts %" GST_TIME_FORMAT,
GST_TIME_ARGS (push_ts));
if (videorate->drop_out_of_segment
&& !gst_segment_clip (&videorate->segment, GST_FORMAT_TIME,
GST_BUFFER_PTS (outbuf),
GST_BUFFER_PTS (outbuf) + GST_BUFFER_DURATION (outbuf), NULL, NULL)) {
GST_INFO_OBJECT (videorate, "Buffer is out of segment, dropping");
gst_buffer_unref (outbuf);
return res;
}
res = gst_pad_push (GST_BASE_TRANSFORM_SRC_PAD (videorate), outbuf);
return res;
@ -2036,6 +2063,10 @@ gst_video_rate_set_property (GObject * object,
videorate->max_closing_segment_duplication_duration =
g_value_get_uint64 (value);
break;
case PROP_DROP_OUT_OF_SEGMENT:{
videorate->drop_out_of_segment = g_value_get_boolean (value);
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@ -2102,6 +2133,9 @@ gst_video_rate_get_property (GObject * object,
g_value_set_uint64 (value,
videorate->max_closing_segment_duplication_duration);
break;
case PROP_DROP_OUT_OF_SEGMENT:
g_value_set_boolean (value, videorate->drop_out_of_segment);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;

View file

@ -69,6 +69,7 @@ struct _GstVideoRate
gdouble new_pref;
gboolean skip_to_first;
gboolean drop_only;
gboolean drop_out_of_segment;
guint64 average_period_set;
int max_rate;

View file

@ -21,6 +21,7 @@ tests = [
'videorate/duplicate_on_eos_disbaled',
'videorate/duplicate_on_eos_half_sec',
'videorate/fill_segment_after_caps_changed_before_eos',
'videorate/drop_out_of_segment',
'compositor/renogotiate_failing_unsupported_src_format',
'giosrc/read-growing-file',
'encodebin/set-encoder-properties',

View file

@ -0,0 +1,24 @@
meta,
args = {
"appsrc name=src format=time handle-segment-change=true automatic-eos=false ! \
videorate drop-out-of-segment=true name=videorate ! video/x-raw,framerate=1/1 ! $(videosink) name=sink",
},
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
foreach,
i=<1.0, 2.0, 3.0, 4.0, 5.0>,
actions = {
[
appsrc-push, target-element-name=src, fill-mode=counter, size=115200, pts="$(i)", duration=1.0,
caps=(GstCaps)[video/x-raw,format=I420,framerate=1/1,width=320,height=240],
segment=[segment, stop=1.0, format=(GstFormat)time],
],
}
play
appsrc-eos, target-element-name=src

View file

@ -0,0 +1,9 @@
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, width=(int)320;
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=0:00:01.000000000, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000
buffer: content-id=0, pts=0:00:01.000000000, dur=0:00:01.000000000, flags=discont
buffer: content-id=1, pts=0:00:02.000000000, dur=0:00:01.000000000
buffer: content-id=2, pts=0:00:03.000000000, dur=0:00:01.000000000
buffer: content-id=3, pts=0:00:04.000000000, dur=0:00:01.000000000
buffer: content-id=4, pts=0:00:05.000000000, dur=0:00:01.000000000
event eos: (no structure)

View file

@ -0,0 +1,5 @@
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, width=(int)320;
event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=0:00:01.000000000, 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
event eos: (no structure)