2 * Copyright (C) <1999> Erik Walthinsen <omega@cse.ogi.edu>
3 * Copyright (C) <2003> David Schleef <ds@schleef.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
22 * This file was (probably) generated from gstnavseek.c,
23 * gstnavseek.c,v 1.7 2003/11/08 02:48:59 dschleef Exp
30 #include "gstnavseek.h"
40 GstStaticPadTemplate navseek_src_template = GST_STATIC_PAD_TEMPLATE ("src",
45 GstStaticPadTemplate navseek_sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
50 static const GstElementDetails navseek_details =
51 GST_ELEMENT_DETAILS ("Seek based on left-right arrows",
53 "Seek based on navigation keys left-right",
54 "Jan Schmidt <thaytan@mad.scientist.com>");
56 static gboolean gst_navseek_event (GstBaseTransform * trans, GstEvent * event);
57 static GstFlowReturn gst_navseek_transform_ip (GstBaseTransform * basetrans,
59 static gboolean gst_navseek_handle_src_event (GstPad * pad, GstEvent * event);
60 static gboolean gst_navseek_stop (GstBaseTransform * trans);
61 static gboolean gst_navseek_start (GstBaseTransform * trans);
63 static void gst_navseek_set_property (GObject * object, guint prop_id,
64 const GValue * value, GParamSpec * pspec);
65 static void gst_navseek_get_property (GObject * object, guint prop_id,
66 GValue * value, GParamSpec * pspec);
68 GST_BOILERPLATE (GstNavSeek, gst_navseek, GstBaseTransform,
69 GST_TYPE_BASE_TRANSFORM);
72 gst_navseek_base_init (gpointer g_class)
74 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
76 gst_element_class_add_pad_template (element_class,
77 gst_static_pad_template_get (&navseek_sink_template));
78 gst_element_class_add_pad_template (element_class,
79 gst_static_pad_template_get (&navseek_src_template));
81 gst_element_class_set_details (element_class, &navseek_details);
85 gst_navseek_class_init (GstNavSeekClass * klass)
87 GstBaseTransformClass *gstbasetrans_class;
88 GObjectClass *gobject_class;
90 gobject_class = G_OBJECT_CLASS (klass);
91 gstbasetrans_class = GST_BASE_TRANSFORM_CLASS (klass);
93 gobject_class->set_property = gst_navseek_set_property;
94 gobject_class->get_property = gst_navseek_get_property;
96 g_object_class_install_property (gobject_class,
97 ARG_SEEKOFFSET, g_param_spec_double ("seek-offset", "Seek Offset",
98 "Time in seconds to seek by", 0.0, G_MAXDOUBLE, 5.0,
101 gstbasetrans_class->event = GST_DEBUG_FUNCPTR (gst_navseek_event);
102 gstbasetrans_class->transform_ip =
103 GST_DEBUG_FUNCPTR (gst_navseek_transform_ip);
104 gstbasetrans_class->start = GST_DEBUG_FUNCPTR (gst_navseek_start);
105 gstbasetrans_class->stop = GST_DEBUG_FUNCPTR (gst_navseek_stop);
109 gst_navseek_init (GstNavSeek * navseek, GstNavSeekClass * g_class)
111 gst_pad_set_event_function (GST_BASE_TRANSFORM (navseek)->srcpad,
112 GST_DEBUG_FUNCPTR (gst_navseek_handle_src_event));
114 gst_base_transform_set_passthrough (GST_BASE_TRANSFORM (navseek), TRUE);
116 navseek->seek_offset = 5.0;
117 navseek->loop = FALSE;
118 navseek->grab_seg_start = FALSE;
119 navseek->grab_seg_end = FALSE;
120 navseek->segment_start = GST_CLOCK_TIME_NONE;
121 navseek->segment_end = GST_CLOCK_TIME_NONE;
125 gst_navseek_seek (GstNavSeek * navseek, gint64 offset)
127 GstFormat peer_format = GST_FORMAT_TIME;
133 /* Query for the current time then attempt to set to time + offset */
134 peer_pad = gst_pad_get_peer (GST_BASE_TRANSFORM (navseek)->sinkpad);
135 ret = gst_pad_query_position (peer_pad, &peer_format, &peer_value);
137 if (ret && peer_format == GST_FORMAT_TIME) {
140 peer_value += offset;
144 event = gst_event_new_seek (1.0, GST_FORMAT_TIME,
145 GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH,
146 GST_SEEK_TYPE_SET, peer_value, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
148 gst_pad_send_event (peer_pad, event);
151 gst_object_unref (peer_pad);
155 gst_navseek_segseek (GstNavSeek * navseek)
160 if ((navseek->segment_start == GST_CLOCK_TIME_NONE) ||
161 (navseek->segment_end == GST_CLOCK_TIME_NONE) ||
162 (!GST_PAD_IS_LINKED (GST_BASE_TRANSFORM (navseek)->sinkpad))) {
168 gst_event_new_seek (1.0, GST_FORMAT_TIME,
169 GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_SEGMENT,
170 GST_SEEK_TYPE_SET, navseek->segment_start, GST_SEEK_TYPE_SET,
171 navseek->segment_end);
174 gst_event_new_seek (1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_ACCURATE,
175 GST_SEEK_TYPE_SET, navseek->segment_start, GST_SEEK_TYPE_SET,
176 navseek->segment_end);
179 peer_pad = gst_pad_get_peer (GST_BASE_TRANSFORM (navseek)->sinkpad);
180 gst_pad_send_event (peer_pad, event);
181 gst_object_unref (peer_pad);
185 gst_navseek_handle_src_event (GstPad * pad, GstEvent * event)
190 navseek = GST_NAVSEEK (GST_PAD_PARENT (pad));
192 switch (GST_EVENT_TYPE (event)) {
193 case GST_EVENT_NAVIGATION:
194 /* Check for a keyup and convert left/right to a seek event */
196 const GstStructure *structure;
197 const gchar *event_type;
199 structure = gst_event_get_structure (event);
200 g_return_val_if_fail (structure != NULL, FALSE);
202 event_type = gst_structure_get_string (structure, "event");
203 g_return_val_if_fail (event_type != NULL, FALSE);
205 if (strcmp (event_type, "key-press") == 0) {
208 key = gst_structure_get_string (structure, "key");
209 g_return_val_if_fail (key != NULL, FALSE);
211 if (strcmp (key, "Left") == 0) {
212 /* Seek backward by 5 secs */
213 gst_navseek_seek (navseek, -1.0 * navseek->seek_offset * GST_SECOND);
214 } else if (strcmp (key, "Right") == 0) {
216 gst_navseek_seek (navseek, navseek->seek_offset * GST_SECOND);
217 } else if (strcmp (key, "s") == 0) {
218 /* Grab the next frame as the start frame of a segment */
219 navseek->grab_seg_start = TRUE;
220 } else if (strcmp (key, "e") == 0) {
221 /* Grab the next frame as the end frame of a segment */
222 navseek->grab_seg_end = TRUE;
223 } else if (strcmp (key, "l") == 0) {
224 /* Toggle the loop flag. If we have both start and end segment times send a seek */
225 navseek->loop = !navseek->loop;
226 gst_navseek_segseek (navseek);
231 gst_event_unref (event);
239 if (event && GST_PAD_IS_LINKED (GST_BASE_TRANSFORM (navseek)->sinkpad)) {
240 GstPad *peer_pad = gst_pad_get_peer (GST_BASE_TRANSFORM (navseek)->sinkpad);
242 ret = gst_pad_send_event (peer_pad, event);
243 gst_object_unref (peer_pad);
250 gst_navseek_set_property (GObject * object, guint prop_id,
251 const GValue * value, GParamSpec * pspec)
253 GstNavSeek *navseek = GST_NAVSEEK (object);
257 GST_OBJECT_LOCK (navseek);
258 navseek->seek_offset = g_value_get_double (value);
259 GST_OBJECT_UNLOCK (navseek);
262 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
268 gst_navseek_get_property (GObject * object, guint prop_id,
269 GValue * value, GParamSpec * pspec)
271 GstNavSeek *navseek = GST_NAVSEEK (object);
275 GST_OBJECT_LOCK (navseek);
276 g_value_set_double (value, navseek->seek_offset);
277 GST_OBJECT_UNLOCK (navseek);
280 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
286 gst_navseek_event (GstBaseTransform * trans, GstEvent * event)
288 GstNavSeek *navseek = GST_NAVSEEK (trans);
290 switch (GST_EVENT_TYPE (event)) {
292 GST_OBJECT_LOCK (navseek);
294 gst_navseek_segseek (navseek);
295 GST_OBJECT_UNLOCK (navseek);
300 return GST_BASE_TRANSFORM_CLASS (parent_class)->event (trans, event);
304 gst_navseek_transform_ip (GstBaseTransform * basetrans, GstBuffer * buf)
306 GstNavSeek *navseek = GST_NAVSEEK (basetrans);
308 GST_OBJECT_LOCK (navseek);
310 if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
311 if (navseek->grab_seg_start) {
312 navseek->segment_start = GST_BUFFER_TIMESTAMP (buf);
313 navseek->segment_end = GST_CLOCK_TIME_NONE;
314 navseek->grab_seg_start = FALSE;
317 if (navseek->grab_seg_end) {
318 navseek->segment_end = GST_BUFFER_TIMESTAMP (buf);
319 navseek->grab_seg_end = FALSE;
320 gst_navseek_segseek (navseek);
324 GST_OBJECT_UNLOCK (navseek);
330 gst_navseek_start (GstBaseTransform * trans)
332 /* anything we should be doing here? */
337 gst_navseek_stop (GstBaseTransform * trans)
339 /* anything we should be doing here? */
344 gst_navseek_plugin_init (GstPlugin * plugin)
346 return gst_element_register (plugin, "navseek", GST_RANK_NONE,