timeline-object: Add TrackObject to the Track after the TimelineObject
[platform/upstream/gstreamer.git] / ges / ges-track-image-source.c
1 /* GStreamer Editing Services
2  * Copyright (C) 2009 Edward Hervey <edward.hervey@collabora.co.uk>
3  *               2009 Nokia Corporation
4  *
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.
9  *
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.
14  *
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.
19  */
20
21 /**
22  * SECTION:ges-track-image-source
23  * @short_description: outputs the video stream from a media file as a still
24  * image.
25  * 
26  * Outputs the video stream from a given file as a still frame. The frame
27  * chosen will be determined by the in-point property on the track object. For
28  * image files, do not set the in-point property.
29  */
30
31 #include "ges-internal.h"
32 #include "ges-track-object.h"
33 #include "ges-track-image-source.h"
34
35 G_DEFINE_TYPE (GESTrackImageSource, ges_track_image_source,
36     GES_TYPE_TRACK_SOURCE);
37
38 struct _GESTrackImageSourcePrivate
39 {
40   /*  Dummy variable */
41   void *nothing;
42 };
43
44 enum
45 {
46   PROP_0,
47   PROP_URI
48 };
49
50 static void
51 ges_track_image_source_get_property (GObject * object, guint property_id,
52     GValue * value, GParamSpec * pspec)
53 {
54   GESTrackImageSource *tfs = GES_TRACK_IMAGE_SOURCE (object);
55
56   switch (property_id) {
57     case PROP_URI:
58       g_value_set_string (value, tfs->uri);
59       break;
60     default:
61       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
62   }
63 }
64
65 static void
66 ges_track_image_source_set_property (GObject * object, guint property_id,
67     const GValue * value, GParamSpec * pspec)
68 {
69   GESTrackImageSource *tfs = GES_TRACK_IMAGE_SOURCE (object);
70
71   switch (property_id) {
72     case PROP_URI:
73       tfs->uri = g_value_dup_string (value);
74       break;
75     default:
76       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
77   }
78 }
79
80 static void
81 ges_track_image_source_dispose (GObject * object)
82 {
83   GESTrackImageSource *tfs = GES_TRACK_IMAGE_SOURCE (object);
84
85   if (tfs->uri)
86     g_free (tfs->uri);
87
88   G_OBJECT_CLASS (ges_track_image_source_parent_class)->dispose (object);
89 }
90
91 static void
92 pad_added_cb (GstElement * timeline, GstPad * pad, GstElement * scale)
93 {
94   GstPad *sinkpad;
95   GstPadLinkReturn ret;
96
97   sinkpad = gst_element_get_static_pad (scale, "sink");
98   if (sinkpad) {
99     GST_DEBUG ("got sink pad, trying to link");
100
101     ret = gst_pad_link (pad, sinkpad);
102     if GST_PAD_LINK_SUCCESSFUL
103       (ret) {
104       GST_DEBUG ("linked ok, returning");
105       gst_object_unref (sinkpad);
106       return;
107       }
108   }
109
110   GST_DEBUG ("pad failed to link properly");
111 }
112
113 static GstElement *
114 ges_track_image_source_create_element (GESTrackObject * object)
115 {
116   GstElement *bin, *source, *scale, *freeze, *iconv;
117   GstPad *src, *target;
118
119   bin = GST_ELEMENT (gst_bin_new ("still-image-bin"));
120   source = gst_element_factory_make ("uridecodebin", NULL);
121   scale = gst_element_factory_make ("videoscale", NULL);
122   freeze = gst_element_factory_make ("imagefreeze", NULL);
123   iconv = gst_element_factory_make ("ffmpegcolorspace", NULL);
124
125   g_object_set (scale, "add-borders", TRUE, NULL);
126
127   gst_bin_add_many (GST_BIN (bin), source, scale, freeze, iconv, NULL);
128
129   gst_element_link_pads_full (scale, "src", iconv, "sink",
130       GST_PAD_LINK_CHECK_NOTHING);
131   gst_element_link_pads_full (iconv, "src", freeze, "sink",
132       GST_PAD_LINK_CHECK_NOTHING);
133
134   /* FIXME: add capsfilter here with sink caps (see 626518) */
135
136   target = gst_element_get_static_pad (freeze, "src");
137
138   src = gst_ghost_pad_new ("src", target);
139   gst_element_add_pad (bin, src);
140   gst_object_unref (target);
141
142   g_object_set (source, "uri", ((GESTrackImageSource *) object)->uri, NULL);
143
144   g_signal_connect (G_OBJECT (source), "pad-added",
145       G_CALLBACK (pad_added_cb), scale);
146
147   return bin;
148 }
149
150 static void
151 ges_track_image_source_class_init (GESTrackImageSourceClass * klass)
152 {
153   GObjectClass *object_class = G_OBJECT_CLASS (klass);
154   GESTrackObjectClass *gesobj_class = GES_TRACK_OBJECT_CLASS (klass);
155
156   g_type_class_add_private (klass, sizeof (GESTrackImageSourcePrivate));
157
158   object_class->get_property = ges_track_image_source_get_property;
159   object_class->set_property = ges_track_image_source_set_property;
160   object_class->dispose = ges_track_image_source_dispose;
161
162   /**
163    * GESTrackImageSource:uri
164    *
165    * The location of the file/resource to use.
166    */
167   g_object_class_install_property (object_class, PROP_URI,
168       g_param_spec_string ("uri", "URI", "uri of the resource",
169           NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
170   gesobj_class->create_element = ges_track_image_source_create_element;
171 }
172
173 static void
174 ges_track_image_source_init (GESTrackImageSource * self)
175 {
176   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
177       GES_TYPE_TRACK_IMAGE_SOURCE, GESTrackImageSourcePrivate);
178 }
179
180 /**
181  * ges_track_image_source_new:
182  * @uri: the URI the source should control
183  *
184  * Creates a new #GESTrackImageSource for the provided @uri.
185  *
186  * Returns: A new #GESTrackImageSource.
187  */
188 GESTrackImageSource *
189 ges_track_image_source_new (gchar * uri)
190 {
191   return g_object_new (GES_TYPE_TRACK_IMAGE_SOURCE, "uri", uri, NULL);
192 }