147
171
"Drops/duplicates/adjusts timestamps on video frames to make a perfect stream",
148
172
"Wim Taymans <wim@fluendo.com>");
150
gst_element_class_add_pad_template (element_class,
151
gst_static_pad_template_get (&gst_video_rate_sink_template));
152
gst_element_class_add_pad_template (element_class,
153
gst_static_pad_template_get (&gst_video_rate_src_template));
174
gst_element_class_add_static_pad_template (element_class,
175
&gst_video_rate_sink_template);
176
gst_element_class_add_static_pad_template (element_class,
177
&gst_video_rate_src_template);
157
181
gst_video_rate_class_init (GstVideoRateClass * klass)
159
183
GObjectClass *object_class = G_OBJECT_CLASS (klass);
160
GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
184
GstBaseTransformClass *base_class = GST_BASE_TRANSFORM_CLASS (klass);
162
186
parent_class = g_type_class_peek_parent (klass);
164
188
object_class->set_property = gst_video_rate_set_property;
165
189
object_class->get_property = gst_video_rate_get_property;
167
g_object_class_install_property (object_class, ARG_IN,
191
base_class->set_caps = GST_DEBUG_FUNCPTR (gst_video_rate_setcaps);
192
base_class->transform_caps =
193
GST_DEBUG_FUNCPTR (gst_video_rate_transform_caps);
194
base_class->transform_ip = GST_DEBUG_FUNCPTR (gst_video_rate_transform_ip);
195
base_class->prepare_output_buffer =
196
GST_DEBUG_FUNCPTR (gst_video_rate_prepare_output_buffer);
197
base_class->event = GST_DEBUG_FUNCPTR (gst_video_rate_event);
198
base_class->start = GST_DEBUG_FUNCPTR (gst_video_rate_start);
199
base_class->stop = GST_DEBUG_FUNCPTR (gst_video_rate_stop);
200
base_class->fixate_caps = GST_DEBUG_FUNCPTR (gst_video_rate_fixate_caps);
201
base_class->query = GST_DEBUG_FUNCPTR (gst_video_rate_query);
203
g_object_class_install_property (object_class, PROP_IN,
168
204
g_param_spec_uint64 ("in", "In",
169
205
"Number of input frames", 0, G_MAXUINT64, 0,
170
206
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
171
g_object_class_install_property (object_class, ARG_OUT,
207
g_object_class_install_property (object_class, PROP_OUT,
172
208
g_param_spec_uint64 ("out", "Out", "Number of output frames", 0,
173
209
G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
174
210
pspec_duplicate = g_param_spec_uint64 ("duplicate", "Duplicate",
175
211
"Number of duplicated frames", 0, G_MAXUINT64, 0,
176
212
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
177
g_object_class_install_property (object_class, ARG_DUP, pspec_duplicate);
213
g_object_class_install_property (object_class, PROP_DUP, pspec_duplicate);
178
214
pspec_drop = g_param_spec_uint64 ("drop", "Drop", "Number of dropped frames",
179
215
0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
180
g_object_class_install_property (object_class, ARG_DROP, pspec_drop);
181
g_object_class_install_property (object_class, ARG_SILENT,
216
g_object_class_install_property (object_class, PROP_DROP, pspec_drop);
217
g_object_class_install_property (object_class, PROP_SILENT,
182
218
g_param_spec_boolean ("silent", "silent",
183
219
"Don't emit notify for dropped and duplicated frames", DEFAULT_SILENT,
184
220
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
185
g_object_class_install_property (object_class, ARG_NEW_PREF,
221
g_object_class_install_property (object_class, PROP_NEW_PREF,
186
222
g_param_spec_double ("new-pref", "New Pref",
187
223
"Value indicating how much to prefer new frames (unused)", 0.0, 1.0,
188
224
DEFAULT_NEW_PREF, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
197
g_object_class_install_property (object_class, ARG_SKIP_TO_FIRST,
233
g_object_class_install_property (object_class, PROP_SKIP_TO_FIRST,
198
234
g_param_spec_boolean ("skip-to-first", "Skip to first buffer",
199
235
"Don't produce buffers before the first one we receive",
200
236
DEFAULT_SKIP_TO_FIRST, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
202
element_class->change_state = GST_DEBUG_FUNCPTR (gst_video_rate_change_state);
205
/* return the caps that can be used on out_pad given in_caps on in_pad */
239
* GstVideoRate:drop-only:
241
* Only drop frames, no duplicates are produced.
245
g_object_class_install_property (object_class, PROP_DROP_ONLY,
246
g_param_spec_boolean ("drop-only", "Only Drop",
247
"Only drop frames, no duplicates are produced",
248
DEFAULT_DROP_ONLY, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
251
* GstVideoRate:average-period:
253
* Arrange for maximum framerate by dropping frames beyond a certain framerate,
254
* where the framerate is calculated using a moving average over the
259
g_object_class_install_property (object_class, PROP_AVERAGE_PERIOD,
260
g_param_spec_uint64 ("average-period", "Period over which to average",
261
"Period over which to average the framerate (in ns) (0 = disabled)",
262
0, G_MAXINT64, DEFAULT_AVERAGE_PERIOD,
263
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
266
* GstVideoRate:max-rate:
268
* maximum framerate to pass through
272
g_object_class_install_property (object_class, PROP_MAX_RATE,
273
g_param_spec_int ("max-rate", "maximum framerate",
274
"Maximum framerate allowed to pass through "
275
"(in frames per second, implies drop-only)",
276
1, G_MAXINT, DEFAULT_MAX_RATE,
277
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
280
* GstVideoRate:force-fps:
282
* Forced output framerate
286
g_object_class_install_property (object_class, PROP_FORCE_FPS,
287
gst_param_spec_fraction ("force-fps", "Force output framerate",
288
"Force output framerate (negative means negotiate via caps)",
289
-1, 1, G_MAXINT, 1, DEFAULT_FORCE_FPS_N, DEFAULT_FORCE_FPS_D,
290
G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
294
gst_value_fraction_get_extremes (const GValue * v,
295
gint * min_num, gint * min_denom, gint * max_num, gint * max_denom)
297
if (GST_VALUE_HOLDS_FRACTION (v)) {
298
*min_num = *max_num = gst_value_get_fraction_numerator (v);
299
*min_denom = *max_denom = gst_value_get_fraction_denominator (v);
300
} else if (GST_VALUE_HOLDS_FRACTION_RANGE (v)) {
301
const GValue *min, *max;
303
min = gst_value_get_fraction_range_min (v);
304
*min_num = gst_value_get_fraction_numerator (min);
305
*min_denom = gst_value_get_fraction_denominator (min);
307
max = gst_value_get_fraction_range_max (v);
308
*max_num = gst_value_get_fraction_numerator (max);
309
*max_denom = gst_value_get_fraction_denominator (max);
310
} else if (GST_VALUE_HOLDS_LIST (v)) {
311
gint min_n = G_MAXINT, min_d = 1, max_n = 0, max_d = 1;
319
n = gst_value_list_get_size (v);
323
for (i = 0; i < n; i++) {
324
const GValue *t = gst_value_list_get_value (v, i);
326
gst_value_fraction_get_extremes (t, &min_n, &min_d, &max_n, &max_d);
327
if (gst_util_fraction_compare (min_n, min_d, *min_num, *min_denom) < 0) {
332
if (gst_util_fraction_compare (max_n, max_d, *max_num, *max_denom) > 0) {
338
g_warning ("Unknown type for framerate");
346
/* Clamp the framerate in a caps structure to be a smaller range then
347
* [1...max_rate], otherwise return false */
207
gst_video_rate_transformcaps (GstPad * in_pad, GstCaps * in_caps,
208
GstPad * out_pad, GstCaps ** out_caps)
349
gst_video_max_rate_clamp_structure (GstStructure * s, gint maxrate,
350
gint * min_num, gint * min_denom, gint * max_num, gint * max_denom)
211
const GstCaps *in_templ;
213
GSList *extra_structures = NULL;
216
in_templ = gst_pad_get_pad_template_caps (in_pad);
217
intersect = gst_caps_intersect (in_caps, in_templ);
219
/* all possible framerates are allowed */
220
for (i = 0; i < gst_caps_get_size (intersect); i++) {
221
GstStructure *structure;
223
structure = gst_caps_get_structure (intersect, i);
225
if (gst_structure_has_field (structure, "framerate")) {
226
GstStructure *copy_structure;
228
copy_structure = gst_structure_copy (structure);
229
gst_structure_set (copy_structure,
230
"framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
231
extra_structures = g_slist_append (extra_structures, copy_structure);
352
gboolean ret = FALSE;
354
if (!gst_structure_has_field (s, "framerate")) {
355
/* No framerate field implies any framerate, clamping would result in
356
* [1..max_rate] so not a real subset */
360
GValue intersection = { 0, };
361
GValue clamp = { 0, };
362
gint tmp_num, tmp_denom;
364
g_value_init (&clamp, GST_TYPE_FRACTION_RANGE);
365
gst_value_set_fraction_range_full (&clamp, 0, 1, maxrate, 1);
367
v = gst_structure_get_value (s, "framerate");
368
ret = gst_value_intersect (&intersection, v, &clamp);
369
g_value_unset (&clamp);
374
gst_value_fraction_get_extremes (&intersection,
375
min_num, min_denom, max_num, max_denom);
377
gst_value_fraction_get_extremes (v,
378
&tmp_num, &tmp_denom, max_num, max_denom);
380
if (gst_util_fraction_compare (*max_num, *max_denom, maxrate, 1) > 0) {
235
/* append the extra structures */
236
for (iter = extra_structures; iter != NULL; iter = g_slist_next (iter)) {
237
gst_caps_append_structure (intersect, (GstStructure *) iter->data);
239
g_slist_free (extra_structures);
241
*out_caps = intersect;
385
gst_structure_take_value (s, "framerate", &intersection);
247
gst_video_rate_getcaps (GstPad * pad)
393
gst_video_rate_transform_caps (GstBaseTransform * trans,
394
GstPadDirection direction, GstCaps * caps)
249
GstVideoRate *videorate;
253
videorate = GST_VIDEO_RATE (GST_PAD_PARENT (pad));
255
otherpad = (pad == videorate->srcpad) ? videorate->sinkpad :
258
/* we can do what the peer can */
259
caps = gst_pad_peer_get_caps (otherpad);
263
gst_video_rate_transformcaps (otherpad, caps, pad, &transform);
264
gst_caps_unref (caps);
396
GstVideoRate *videorate = GST_VIDEO_RATE (trans);
398
GstStructure *s, *s2;
399
GstStructure *s3 = NULL;
400
int maxrate = g_atomic_int_get (&videorate->max_rate);
402
/* Should always be called with simple caps */
403
g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), NULL);
405
ret = gst_caps_copy (caps);
407
s = gst_caps_get_structure (ret, 0);
408
s2 = gst_structure_copy (s);
410
if (videorate->force_fps_n >= 0 && videorate->force_fps_d >= 0) {
411
if (direction == GST_PAD_SINK) {
412
gst_caps_remove_structure (ret, 0);
413
gst_structure_set (s2, "framerate", GST_TYPE_FRACTION,
414
videorate->force_fps_n, videorate->force_fps_d, NULL);
416
gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
419
} else if (videorate->drop_only) {
420
gint min_num = 0, min_denom = 1;
421
gint max_num = G_MAXINT, max_denom = 1;
423
/* Clamp the caps to our maximum rate as the first caps if possible */
424
if (!gst_video_max_rate_clamp_structure (s, maxrate,
425
&min_num, &min_denom, &max_num, &max_denom)) {
431
/* clamp wouldn't be a real subset of 1..maxrate, in this case the sink
432
* caps should become [1..maxrate], [1..maxint] and the src caps just
433
* [1..maxrate]. In case there was a caps incompatibility things will
434
* explode later as appropriate :)
436
* In case [X..maxrate] == [X..maxint], skip as we'll set it later
438
if (direction == GST_PAD_SRC && maxrate != G_MAXINT)
439
gst_structure_set (s, "framerate", GST_TYPE_FRACTION_RANGE,
440
min_num, min_denom, maxrate, 1, NULL);
442
gst_caps_remove_structure (ret, 0);
445
if (direction == GST_PAD_SRC) {
446
/* We can accept anything as long as it's at least the minimal framerate
447
* the the sink needs */
448
gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE,
449
min_num, min_denom, G_MAXINT, 1, NULL);
451
/* Also allow unknown framerate, if it isn't already */
452
if (min_num != 0 || min_denom != 1) {
453
s3 = gst_structure_copy (s);
454
gst_structure_set (s3, "framerate", GST_TYPE_FRACTION, 0, 1, NULL);
456
} else if (max_num != 0 || max_denom != 1) {
457
/* We can provide everything upto the maximum framerate at the src */
458
gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE,
459
0, 1, max_num, max_denom, NULL);
461
} else if (direction == GST_PAD_SINK) {
462
gint min_num = 0, min_denom = 1;
463
gint max_num = G_MAXINT, max_denom = 1;
465
if (!gst_video_max_rate_clamp_structure (s, maxrate,
466
&min_num, &min_denom, &max_num, &max_denom))
467
gst_caps_remove_structure (ret, 0);
469
gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
267
/* no peer, our padtemplate is enough then */
268
caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
472
/* set the framerate as a range */
473
gst_structure_set (s2, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
477
gst_caps_merge_structure (ret, s2);
479
gst_caps_merge_structure (ret, s3);
485
gst_video_rate_fixate_caps (GstBaseTransform * trans,
486
GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
491
s = gst_caps_get_structure (caps, 0);
492
if (G_UNLIKELY (!gst_structure_get_fraction (s, "framerate", &num, &denom)))
495
s = gst_caps_get_structure (othercaps, 0);
496
gst_structure_fixate_field_nearest_fraction (s, "framerate", num, denom);
275
gst_video_rate_setcaps (GstPad * pad, GstCaps * caps)
500
gst_video_rate_setcaps (GstBaseTransform * trans, GstCaps * in_caps,
277
503
GstVideoRate *videorate;
278
504
GstStructure *structure;
279
505
gboolean ret = TRUE;
280
GstPad *otherpad, *opeer;
281
506
gint rate_numerator, rate_denominator;
283
videorate = GST_VIDEO_RATE (gst_pad_get_parent (pad));
285
GST_DEBUG_OBJECT (pad, "setcaps called %" GST_PTR_FORMAT, caps);
287
structure = gst_caps_get_structure (caps, 0);
288
if (!gst_structure_get_fraction (structure, "framerate",
289
&rate_numerator, &rate_denominator))
292
if (pad == videorate->srcpad) {
293
/* out_frame_count is scaled by the frame rate caps when calculating next_ts.
294
* when the frame rate caps change, we must update base_ts and reset
296
if (videorate->to_rate_numerator) {
297
videorate->base_ts +=
298
gst_util_uint64_scale (videorate->out_frame_count,
299
videorate->to_rate_denominator * GST_SECOND,
300
videorate->to_rate_numerator);
302
videorate->out_frame_count = 0;
303
videorate->to_rate_numerator = rate_numerator;
304
videorate->to_rate_denominator = rate_denominator;
305
otherpad = videorate->sinkpad;
307
videorate->from_rate_numerator = rate_numerator;
308
videorate->from_rate_denominator = rate_denominator;
309
otherpad = videorate->srcpad;
312
/* now try to find something for the peer */
313
opeer = gst_pad_get_peer (otherpad);
315
if (gst_pad_accept_caps (opeer, caps)) {
316
/* the peer accepts the caps as they are */
317
gst_pad_set_caps (otherpad, caps);
322
GstCaps *transform = NULL;
326
/* see how we can transform the input caps */
327
if (!gst_video_rate_transformcaps (pad, caps, otherpad, &transform))
330
/* see what the peer can do */
331
peercaps = gst_pad_get_caps (opeer);
333
GST_DEBUG_OBJECT (opeer, "icaps %" GST_PTR_FORMAT, peercaps);
334
GST_DEBUG_OBJECT (videorate, "transform %" GST_PTR_FORMAT, transform);
336
/* filter against our possibilities */
337
caps = gst_caps_intersect (peercaps, transform);
338
gst_caps_unref (peercaps);
339
gst_caps_unref (transform);
341
GST_DEBUG_OBJECT (videorate, "intersect %" GST_PTR_FORMAT, caps);
343
/* could turn up empty, due to e.g. colorspace etc */
344
if (gst_caps_get_size (caps) == 0) {
345
gst_caps_unref (caps);
349
/* take first possibility */
350
gst_caps_truncate (caps);
351
structure = gst_caps_get_structure (caps, 0);
354
gst_structure_fixate_field_nearest_fraction (structure, "framerate",
355
rate_numerator, rate_denominator);
357
gst_structure_get_fraction (structure, "framerate",
358
&rate_numerator, &rate_denominator);
360
if (otherpad == videorate->srcpad) {
361
videorate->to_rate_numerator = rate_numerator;
362
videorate->to_rate_denominator = rate_denominator;
364
videorate->from_rate_numerator = rate_numerator;
365
videorate->from_rate_denominator = rate_denominator;
368
if (gst_structure_has_field (structure, "interlaced"))
369
gst_structure_fixate_field_boolean (structure, "interlaced", FALSE);
370
if (gst_structure_has_field (structure, "color-matrix"))
371
gst_structure_fixate_field_string (structure, "color-matrix", "sdtv");
372
if (gst_structure_has_field (structure, "chroma-site"))
373
gst_structure_fixate_field_string (structure, "chroma-site", "mpeg2");
374
if (gst_structure_has_field (structure, "pixel-aspect-ratio"))
375
gst_structure_fixate_field_nearest_fraction (structure,
376
"pixel-aspect-ratio", 1, 1);
378
gst_pad_set_caps (otherpad, caps);
379
gst_caps_unref (caps);
382
gst_object_unref (opeer);
508
videorate = GST_VIDEO_RATE (trans);
510
GST_DEBUG_OBJECT (trans, "setcaps called in: %" GST_PTR_FORMAT
511
" out: %" GST_PTR_FORMAT, in_caps, out_caps);
513
structure = gst_caps_get_structure (in_caps, 0);
514
if (!gst_structure_get_fraction (structure, "framerate",
515
&rate_numerator, &rate_denominator))
518
videorate->from_rate_numerator = rate_numerator;
519
videorate->from_rate_denominator = rate_denominator;
521
structure = gst_caps_get_structure (out_caps, 0);
522
if (!gst_structure_get_fraction (structure, "framerate",
523
&rate_numerator, &rate_denominator))
526
/* out_frame_count is scaled by the frame rate caps when calculating next_ts.
527
* when the frame rate caps change, we must update base_ts and reset
529
if (videorate->to_rate_numerator) {
530
videorate->base_ts +=
531
gst_util_uint64_scale (videorate->out_frame_count,
532
videorate->to_rate_denominator * GST_SECOND,
533
videorate->to_rate_numerator);
535
videorate->out_frame_count = 0;
536
videorate->to_rate_numerator = rate_numerator;
537
videorate->to_rate_denominator = rate_denominator;
540
videorate->wanted_diff = gst_util_uint64_scale_int (GST_SECOND,
541
rate_denominator, rate_numerator);
543
videorate->wanted_diff = 0;
385
546
/* After a setcaps, our caps may have changed. In that case, we can't use
386
547
* the old buffer, if there was one (it might have different dimensions) */
387
548
GST_DEBUG_OBJECT (videorate, "swapping old buffers");
388
549
gst_video_rate_swap_prev (videorate, NULL, GST_CLOCK_TIME_NONE);
550
videorate->last_ts = GST_CLOCK_TIME_NONE;
551
videorate->average = 0;
390
gst_object_unref (videorate);
395
557
GST_DEBUG_OBJECT (videorate, "no framerate specified");
400
GST_DEBUG_OBJECT (videorate, "no framerate transform possible");
745
890
gst_query_set_latency (query, live, min, max);
747
892
gst_object_unref (peer);
895
/* Simple fallthrough if we don't have a latency or not a peer that we
896
* can't ask about its latency yet.. */
752
res = gst_pad_query_default (pad, query);
899
res = parent_class->query (trans, direction, query);
755
gst_object_unref (videorate);
760
906
static GstFlowReturn
761
gst_video_rate_chain (GstPad * pad, GstBuffer * buffer)
907
gst_video_rate_trans_ip_max_avg (GstVideoRate * videorate, GstBuffer * buf)
909
GstClockTime ts = GST_BUFFER_TIMESTAMP (buf);
913
if (!GST_CLOCK_TIME_IS_VALID (ts) || videorate->wanted_diff == 0)
916
/* drop frames if they exceed our output rate */
917
if (GST_CLOCK_TIME_IS_VALID (videorate->last_ts)) {
918
GstClockTimeDiff diff = ts - videorate->last_ts;
920
/* Drop buffer if its early compared to the desired frame rate and
921
* the current average is higher than the desired average
923
if (diff < videorate->wanted_diff &&
924
videorate->average < videorate->wanted_diff)
928
if (videorate->average) {
929
GstClockTimeDiff wanted_diff;
931
if (G_LIKELY (videorate->average_period > videorate->wanted_diff))
932
wanted_diff = videorate->wanted_diff;
934
wanted_diff = videorate->average_period * 10;
937
gst_util_uint64_scale_round (videorate->average,
938
videorate->average_period - wanted_diff,
939
videorate->average_period) +
940
gst_util_uint64_scale_round (diff, wanted_diff,
941
videorate->average_period);
943
videorate->average = diff;
947
videorate->last_ts = ts;
954
if (!videorate->silent)
955
gst_video_rate_notify_drop (videorate);
956
return GST_BASE_TRANSFORM_FLOW_DROPPED;
960
gst_video_rate_prepare_output_buffer (GstBaseTransform * trans,
961
GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf)
963
if (gst_buffer_is_metadata_writable (input)) {
964
gst_buffer_set_caps (input, caps);
965
*buf = gst_buffer_ref (input);
967
*buf = gst_buffer_create_sub (input, 0, GST_BUFFER_SIZE (input));
968
gst_buffer_set_caps (*buf, caps);
975
gst_video_rate_transform_ip (GstBaseTransform * trans, GstBuffer * buffer)
763
977
GstVideoRate *videorate;
764
GstFlowReturn res = GST_FLOW_OK;
978
GstFlowReturn res = GST_BASE_TRANSFORM_FLOW_DROPPED;
765
979
GstClockTime intime, in_ts, in_dur;
980
GstClockTime avg_period;
981
gboolean skip = FALSE;
767
videorate = GST_VIDEO_RATE (GST_PAD_PARENT (pad));
983
videorate = GST_VIDEO_RATE (trans);
769
985
/* make sure the denominators are not 0 */
770
986
if (videorate->from_rate_denominator == 0 ||
771
987
videorate->to_rate_denominator == 0)
772
988
goto not_negotiated;
990
GST_OBJECT_LOCK (videorate);
991
avg_period = videorate->average_period_set;
992
GST_OBJECT_UNLOCK (videorate);
994
/* MT-safe switching between modes */
995
if (G_UNLIKELY (avg_period != videorate->average_period)) {
996
gboolean switch_mode = (avg_period == 0 || videorate->average_period == 0);
997
videorate->average_period = avg_period;
998
videorate->last_ts = GST_CLOCK_TIME_NONE;
1002
/* enabling average mode */
1003
videorate->average = 0;
1004
/* make sure no cached buffers from regular mode are left */
1005
gst_video_rate_swap_prev (videorate, NULL, 0);
1007
/* enable regular mode */
1008
videorate->next_ts = GST_CLOCK_TIME_NONE;
1012
/* max averaging mode has a no latency, normal mode does */
1013
gst_element_post_message (GST_ELEMENT (videorate),
1014
gst_message_new_latency (GST_OBJECT (videorate)));
1018
if (videorate->average_period > 0)
1019
return gst_video_rate_trans_ip_max_avg (videorate, buffer);
774
1021
in_ts = GST_BUFFER_TIMESTAMP (buffer);
775
1022
in_dur = GST_BUFFER_DURATION (buffer);