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;
132 /* Query for the current time then attempt to set to time + offset */
133 peer_pad = gst_pad_get_peer (GST_BASE_TRANSFORM (navseek)->sinkpad);
134 ret = gst_pad_query_position (peer_pad, &peer_format, &peer_value);
136 if (ret && peer_format == GST_FORMAT_TIME) {
139 peer_value += offset;
143 event = gst_event_new_seek (1.0, GST_FORMAT_TIME,
144 GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH,
145 GST_SEEK_TYPE_SET, peer_value, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
147 gst_pad_send_event (peer_pad, event);
150 gst_object_unref (peer_pad);
154 gst_navseek_segseek (GstNavSeek * navseek)
159 if ((navseek->segment_start == GST_CLOCK_TIME_NONE) ||
160 (navseek->segment_end == GST_CLOCK_TIME_NONE) ||
161 (!GST_PAD_IS_LINKED (GST_BASE_TRANSFORM (navseek)->sinkpad))) {
167 gst_event_new_seek (1.0, GST_FORMAT_TIME,
168 GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_SEGMENT,
169 GST_SEEK_TYPE_SET, navseek->segment_start, GST_SEEK_TYPE_SET,
170 navseek->segment_end);
173 gst_event_new_seek (1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_ACCURATE,
174 GST_SEEK_TYPE_SET, navseek->segment_start, GST_SEEK_TYPE_SET,
175 navseek->segment_end);
178 peer_pad = gst_pad_get_peer (GST_BASE_TRANSFORM (navseek)->sinkpad);
179 gst_pad_send_event (peer_pad, event);
180 gst_object_unref (peer_pad);
184 gst_navseek_handle_src_event (GstPad * pad, GstEvent * event)
189 navseek = GST_NAVSEEK (GST_PAD_PARENT (pad));
191 switch (GST_EVENT_TYPE (event)) {
192 case GST_EVENT_NAVIGATION:
193 /* Check for a keyup and convert left/right to a seek event */
195 const GstStructure *structure;
196 const gchar *event_type;
198 structure = gst_event_get_structure (event);
199 g_return_val_if_fail (structure != NULL, FALSE);
201 event_type = gst_structure_get_string (structure, "event");
202 g_return_val_if_fail (event_type != NULL, FALSE);
204 if (strcmp (event_type, "key-press") == 0) {
207 key = gst_structure_get_string (structure, "key");
208 g_return_val_if_fail (key != NULL, FALSE);
210 if (strcmp (key, "Left") == 0) {
211 /* Seek backward by 5 secs */
212 gst_navseek_seek (navseek, -1.0 * navseek->seek_offset * GST_SECOND);
213 } else if (strcmp (key, "Right") == 0) {
215 gst_navseek_seek (navseek, navseek->seek_offset * GST_SECOND);
216 } else if (strcmp (key, "s") == 0) {
217 /* Grab the next frame as the start frame of a segment */
218 navseek->grab_seg_start = TRUE;
219 } else if (strcmp (key, "e") == 0) {
220 /* Grab the next frame as the end frame of a segment */
221 navseek->grab_seg_end = TRUE;
222 } else if (strcmp (key, "l") == 0) {
223 /* Toggle the loop flag. If we have both start and end segment times send a seek */
224 navseek->loop = !navseek->loop;
225 gst_navseek_segseek (navseek);
230 gst_event_unref (event);
238 if (event && GST_PAD_IS_LINKED (GST_BASE_TRANSFORM (navseek)->sinkpad)) {
239 GstPad *peer_pad = gst_pad_get_peer (GST_BASE_TRANSFORM (navseek)->sinkpad);
241 ret = gst_pad_send_event (peer_pad, event);
242 gst_object_unref (peer_pad);
249 gst_navseek_set_property (GObject * object, guint prop_id,
250 const GValue * value, GParamSpec * pspec)
252 GstNavSeek *navseek = GST_NAVSEEK (object);
256 GST_OBJECT_LOCK (navseek);
257 navseek->seek_offset = g_value_get_double (value);
258 GST_OBJECT_UNLOCK (navseek);
261 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
267 gst_navseek_get_property (GObject * object, guint prop_id,
268 GValue * value, GParamSpec * pspec)
270 GstNavSeek *navseek = GST_NAVSEEK (object);
274 GST_OBJECT_LOCK (navseek);
275 g_value_set_double (value, navseek->seek_offset);
276 GST_OBJECT_UNLOCK (navseek);
279 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
285 gst_navseek_event (GstBaseTransform * trans, GstEvent * event)
287 GstNavSeek *navseek = GST_NAVSEEK (trans);
289 switch (GST_EVENT_TYPE (event)) {
291 GST_OBJECT_LOCK (navseek);
293 gst_navseek_segseek (navseek);
294 GST_OBJECT_UNLOCK (navseek);
299 return GST_BASE_TRANSFORM_CLASS (parent_class)->event (trans, event);
303 gst_navseek_transform_ip (GstBaseTransform * basetrans, GstBuffer * buf)
305 GstNavSeek *navseek = GST_NAVSEEK (basetrans);
307 GST_OBJECT_LOCK (navseek);
309 if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
310 if (navseek->grab_seg_start) {
311 navseek->segment_start = GST_BUFFER_TIMESTAMP (buf);
312 navseek->segment_end = GST_CLOCK_TIME_NONE;
313 navseek->grab_seg_start = FALSE;
316 if (navseek->grab_seg_end) {
317 navseek->segment_end = GST_BUFFER_TIMESTAMP (buf);
318 navseek->grab_seg_end = FALSE;
319 gst_navseek_segseek (navseek);
323 GST_OBJECT_UNLOCK (navseek);
329 gst_navseek_start (GstBaseTransform * trans)
331 /* anything we should be doing here? */
336 gst_navseek_stop (GstBaseTransform * trans)
338 /* anything we should be doing here? */