2
* Copyright (C) 2008 Barracuda Networks, Inc.
4
* This library is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU Lesser General Public
6
* License as published by the Free Software Foundation; either
7
* version 2.1 of the License, or (at your option) any later version.
9
* This library is distributed in the hope that it will be useful,
10
* but WITHANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
* Lesser General Public License for more details.
14
* You should have received a copy of the GNU Lesser General Public
15
* License along with this library; if not, write to the Free Software
16
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21
#include "videomaxrate.h"
23
static const GstElementDetails videomaxrate_details =
24
GST_ELEMENT_DETAILS ("Video maximum rate adjuster",
25
"Filter/Effect/Video",
27
"Justin Karneges <justin@affinix.com>");
29
static GstStaticPadTemplate gst_videomaxrate_src_template =
30
GST_STATIC_PAD_TEMPLATE ("src",
33
GST_STATIC_CAPS ("video/x-raw-yuv; video/x-raw-rgb")
36
static GstStaticPadTemplate gst_videomaxrate_sink_template =
37
GST_STATIC_PAD_TEMPLATE ("sink",
40
GST_STATIC_CAPS ("video/x-raw-yuv; video/x-raw-rgb")
43
static gboolean gst_videomaxrate_sink_event (GstPad *pad, GstEvent *event);
44
static GstCaps *gst_videomaxrate_transform_caps (GstBaseTransform *trans,
45
GstPadDirection direction, GstCaps *caps);
46
static gboolean gst_videomaxrate_set_caps (GstBaseTransform *trans,
47
GstCaps *incaps, GstCaps *outcaps);
48
static GstFlowReturn gst_videomaxrate_transform_ip (GstBaseTransform *trans,
51
GST_BOILERPLATE (GstVideoMaxRate, gst_videomaxrate, GstBaseTransform,
52
GST_TYPE_BASE_TRANSFORM);
55
gst_videomaxrate_base_init (gpointer gclass)
57
GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
59
gst_element_class_set_details (element_class, &videomaxrate_details);
61
gst_element_class_add_pad_template (element_class,
62
gst_static_pad_template_get (&gst_videomaxrate_sink_template));
63
gst_element_class_add_pad_template (element_class,
64
gst_static_pad_template_get (&gst_videomaxrate_src_template));
68
gst_videomaxrate_class_init (GstVideoMaxRateClass *klass)
70
GstBaseTransformClass *base_class;
71
base_class = (GstBaseTransformClass *)klass;
73
base_class->transform_caps = gst_videomaxrate_transform_caps;
74
base_class->set_caps = gst_videomaxrate_set_caps;
75
base_class->transform_ip = gst_videomaxrate_transform_ip;
79
gst_videomaxrate_init (GstVideoMaxRate *videomaxrate,
80
GstVideoMaxRateClass *gclass)
84
videomaxrate->to_rate_numerator = -1;
85
videomaxrate->to_rate_denominator = -1;
86
videomaxrate->have_last_ts = FALSE;
88
gst_pad_set_event_function (GST_BASE_TRANSFORM_SINK_PAD (videomaxrate),
89
gst_videomaxrate_sink_event);
93
gst_videomaxrate_sink_event (GstPad *pad, GstEvent *event)
95
GstVideoMaxRate *videomaxrate;
98
videomaxrate = (GstVideoMaxRate *)gst_pad_get_parent (pad);
99
switch (GST_EVENT_TYPE(event)) {
100
case GST_EVENT_NEWSEGMENT:
101
case GST_EVENT_FLUSH_STOP:
102
videomaxrate->have_last_ts = FALSE;
108
ret = gst_pad_push_event (GST_BASE_TRANSFORM_SRC_PAD (videomaxrate), event);
110
gst_object_unref (videomaxrate);
115
gst_videomaxrate_transform_caps (GstBaseTransform *trans,
116
GstPadDirection direction, GstCaps *caps)
119
GstStructure *structure;
124
/* this function is always called with a simple caps */
125
g_return_val_if_fail (GST_CAPS_IS_SIMPLE (caps), NULL);
127
ret = gst_caps_copy (caps);
129
/* set the framerate as a range */
130
structure = gst_structure_copy (gst_caps_get_structure (ret, 0));
131
gst_structure_set (structure, "framerate", GST_TYPE_FRACTION_RANGE, 0, 1,
133
gst_caps_merge_structure (ret, gst_structure_copy (structure));
134
gst_structure_free (structure);
140
gst_videomaxrate_set_caps (GstBaseTransform *trans, GstCaps *incaps,
143
GstVideoMaxRate *videomaxrate;
145
gint numerator, denominator;
147
videomaxrate = (GstVideoMaxRate *)trans;
150
// keep track of the outbound framerate
151
cs = gst_caps_get_structure (outcaps, 0);
152
if (!gst_structure_get_fraction (cs, "framerate", &numerator, &denominator))
155
videomaxrate->to_rate_numerator = numerator;
156
videomaxrate->to_rate_denominator = denominator;
162
gst_videomaxrate_transform_ip (GstBaseTransform *trans, GstBuffer *buf)
164
GstVideoMaxRate *videomaxrate;
167
videomaxrate = (GstVideoMaxRate *)trans;
168
ts = GST_BUFFER_TIMESTAMP (buf);
170
/* drop frames if they exceed our output rate */
171
if (videomaxrate->have_last_ts) {
172
if (ts < videomaxrate->last_ts + gst_util_uint64_scale (1,
173
videomaxrate->to_rate_denominator * GST_SECOND,
174
videomaxrate->to_rate_numerator)) {
175
return GST_BASE_TRANSFORM_FLOW_DROPPED;
179
videomaxrate->last_ts = ts;
180
videomaxrate->have_last_ts = TRUE;