91b7a5851a65059fb86ab893b30d8aff9908f102
[platform/upstream/gstreamer.git] / tests / examples / transition.c
1 /* GStreamer Editing Services
2  * Copyright (C) 2010 Brandon Lewis <brandon@alum.berkeley.edu>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 #include <stdlib.h>
21 #include <ges/ges.h>
22 #include <stdlib.h>
23
24 typedef struct
25 {
26   int type;
27   char *name;
28 } transition_type;
29
30 GESClip *make_source (gchar * path, guint64 start, guint64 inpoint,
31     guint64 duration, gint priority);
32
33 gboolean print_transition_data (GESClip * tr);
34
35 GESTimelinePipeline *make_timeline (gchar * nick, double tdur, gchar * patha,
36     gfloat adur, gdouble ainpoint, gchar * pathb, gfloat bdur,
37     gdouble binpoint);
38
39 GESClip *
40 make_source (gchar * path, guint64 start, guint64 duration, guint64 inpoint,
41     gint priority)
42 {
43   gchar *uri = gst_filename_to_uri (path, NULL);
44
45   GESClip *ret = GES_CLIP (ges_uri_clip_new (uri));
46
47   g_object_set (ret,
48       "start", (guint64) start,
49       "duration", (guint64) duration,
50       "priority", (guint32) priority, "in-point", (guint64) inpoint, NULL);
51
52   g_free (uri);
53
54   return ret;
55 }
56
57 gboolean
58 print_transition_data (GESClip * tr)
59 {
60   GESTrackElement *trackelement;
61   GstElement *gnlobj;
62   guint64 start, duration;
63   gint priority;
64   char *name;
65   GList *trackelements;
66
67   if (!tr)
68     return FALSE;
69
70   if (!(trackelements = GES_CONTAINER_CHILDREN (tr)))
71     return FALSE;
72   if (!(trackelement = GES_TRACK_ELEMENT (trackelements->data)))
73     return FALSE;
74   if (!(gnlobj = ges_track_element_get_gnlobject (trackelement)))
75     return FALSE;
76
77   g_object_get (gnlobj, "start", &start, "duration", &duration,
78       "priority", &priority, "name", &name, NULL);
79   g_print ("gnlobject for %s: %f %f %d\n", name,
80       ((gfloat) start) / GST_SECOND,
81       ((gfloat) duration) / GST_SECOND, priority);
82
83   return FALSE;
84 }
85
86 GESTimelinePipeline *
87 make_timeline (gchar * nick, gdouble tdur, gchar * patha, gfloat adur,
88     gdouble ainp, gchar * pathb, gfloat bdur, gdouble binp)
89 {
90   GESTimeline *timeline;
91   GESTrack *trackv, *tracka;
92   GESLayer *layer1;
93   GESClip *srca, *srcb;
94   GESTimelinePipeline *pipeline;
95   guint64 aduration, bduration, tduration, tstart, ainpoint, binpoint;
96   GESTransitionClip *tr = NULL;
97
98   pipeline = ges_timeline_pipeline_new ();
99
100   ges_timeline_pipeline_set_mode (pipeline, TIMELINE_MODE_PREVIEW_VIDEO);
101
102   timeline = ges_timeline_new ();
103   ges_timeline_pipeline_add_timeline (pipeline, timeline);
104
105   trackv = GES_TRACK (ges_video_track_new ());
106   ges_timeline_add_track (timeline, trackv);
107
108   tracka = GES_TRACK (ges_audio_track_new ());
109   ges_timeline_add_track (timeline, tracka);
110
111   layer1 = GES_LAYER (ges_layer_new ());
112   g_object_set (layer1, "priority", (gint32) 0, NULL);
113
114   if (!ges_timeline_add_layer (timeline, layer1))
115     exit (-1);
116
117   aduration = (guint64) (adur * GST_SECOND);
118   bduration = (guint64) (bdur * GST_SECOND);
119   tduration = (guint64) (tdur * GST_SECOND);
120   ainpoint = (guint64) (ainp * GST_SECOND);
121   binpoint = (guint64) (binp * GST_SECOND);
122   tstart = aduration - tduration;
123   srca = make_source (patha, 0, aduration, ainpoint, 1);
124   srcb = make_source (pathb, tstart, bduration, binpoint, 2);
125   ges_layer_add_clip (layer1, srca);
126   ges_layer_add_clip (layer1, srcb);
127   g_timeout_add_seconds (1, (GSourceFunc) print_transition_data, srca);
128   g_timeout_add_seconds (1, (GSourceFunc) print_transition_data, srcb);
129
130   if (tduration != 0) {
131     g_print ("creating transition at %" GST_TIME_FORMAT " of %f duration (%"
132         GST_TIME_FORMAT ")\n", GST_TIME_ARGS (tstart), tdur,
133         GST_TIME_ARGS (tduration));
134     if (!(tr = ges_transition_clip_new_for_nick (nick)))
135       g_error ("invalid transition type %s\n", nick);
136
137     g_object_set (tr,
138         "start", (guint64) tstart,
139         "duration", (guint64) tduration, "in-point", (guint64) 0, NULL);
140     ges_layer_add_clip (layer1, GES_CLIP (tr));
141     g_timeout_add_seconds (1, (GSourceFunc) print_transition_data, tr);
142   }
143
144   return pipeline;
145 }
146
147 int
148 main (int argc, char **argv)
149 {
150   GError *err = NULL;
151   GOptionContext *ctx;
152   GESTimelinePipeline *pipeline;
153   GMainLoop *mainloop;
154   gchar *type = (gchar *) "crossfade";
155   gchar *patha, *pathb;
156   gdouble adur, bdur, tdur, ainpoint, binpoint;
157
158   GOptionEntry options[] = {
159     {"type", 't', 0, G_OPTION_ARG_STRING, &type,
160         "type of transition to create", "<smpte-transition>"},
161     {"duration", 'd', 0, G_OPTION_ARG_DOUBLE, &tdur,
162         "duration of transition", "seconds"},
163     {NULL}
164   };
165
166   ctx = g_option_context_new ("- transition between two media files");
167   g_option_context_set_summary (ctx,
168       "Select two files, and optionally a transition duration and type.\n"
169       "A file is a triplet of filename, inpoint (in seconds) and duration (in seconds).\n"
170       "Example:\n" "transition file1.avi 0 5 file2.avi 25 5 -d 2 -t crossfade");
171   g_option_context_add_main_entries (ctx, options, NULL);
172   g_option_context_add_group (ctx, gst_init_get_option_group ());
173
174   if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
175     g_print ("Error initializing %s\n", err->message);
176     exit (1);
177   }
178
179   if (argc < 4) {
180     g_print ("%s", g_option_context_get_help (ctx, TRUE, NULL));
181     exit (0);
182   }
183
184   g_option_context_free (ctx);
185
186   ges_init ();
187
188   patha = argv[1];
189   ainpoint = (gdouble) atof (argv[2]);
190   adur = (gdouble) atof (argv[3]);
191   pathb = argv[4];
192   binpoint = (gdouble) atof (argv[5]);
193   bdur = (gdouble) atof (argv[6]);
194
195   pipeline =
196       make_timeline (type, tdur, patha, adur, ainpoint, pathb, bdur, binpoint);
197
198   mainloop = g_main_loop_new (NULL, FALSE);
199   g_timeout_add_seconds ((adur + bdur) + 1, (GSourceFunc) g_main_loop_quit,
200       mainloop);
201   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
202   g_main_loop_run (mainloop);
203
204   return 0;
205 }