libgupnp-dlna: Remove debug print
[gupnp:gupnp-dlna.git] / tests / dlna-encoding.c
1 /* Example application for using GstProfile and encodebin
2  * Copyright (C) 2009 Edward Hervey <edward.hervey@collabora.co.uk>
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., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <stdlib.h>
25 #include <glib.h>
26 #include <gst/gst.h>
27 #include <gst/profile/gstprofile.h>
28 #include <gst/pbutils/pbutils.h>
29 #include <libgupnp-dlna/gupnp-dlna-profile.h>
30
31 static gboolean silent = FALSE;
32
33 static void
34 pad_added_cb (GstElement * uridecodebin, GstPad * pad, GstElement * encodebin)
35 {
36   GstPad *sinkpad;
37
38   sinkpad = gst_element_get_compatible_pad (encodebin, pad, NULL);
39
40   if (sinkpad == NULL) {
41     GstCaps *caps;
42
43     /* Ask encodebin for a compatible pad */
44     caps = gst_pad_get_caps (pad);
45     g_signal_emit_by_name (encodebin, "request-pad", caps, &sinkpad);
46     if (caps)
47       gst_caps_unref (caps);
48   }
49   if (sinkpad == NULL) {
50     g_print ("Couldn't get an encoding channel for pad %s:%s\n",
51         GST_DEBUG_PAD_NAME (pad));
52     return;
53   }
54
55   if (G_UNLIKELY (gst_pad_link (pad, sinkpad) != GST_PAD_LINK_OK)) {
56     g_print ("Couldn't link pads\n");
57   }
58
59   return;
60 }
61
62 static gboolean
63 autoplug_continue_cb (GstElement * uridecodebin, GstPad * somepad,
64     GstCaps * caps, GstElement * encodebin)
65 {
66   GstPad *sinkpad;
67
68   g_signal_emit_by_name (encodebin, "request-pad", caps, &sinkpad);
69
70   if (sinkpad == NULL)
71     return TRUE;
72
73   return FALSE;
74 }
75
76 static void
77 bus_message_cb (GstBus * bus, GstMessage * message, GMainLoop * mainloop)
78 {
79   switch (GST_MESSAGE_TYPE (message)) {
80     case GST_MESSAGE_ERROR:
81       g_print ("ERROR\n");
82       g_main_loop_quit (mainloop);
83       break;
84     case GST_MESSAGE_EOS:
85       g_print ("Done\n");
86       g_main_loop_quit (mainloop);
87       break;
88     default:
89       break;
90   }
91 }
92
93 static void
94 transcode_file (gchar * uri, gchar * outputuri, GstEncodingProfile * prof)
95 {
96   GstElement *pipeline;
97   GstElement *src;
98   GstElement *ebin;
99   GstElement *sink;
100   GstBus *bus;
101   GstCaps *profilecaps, *rescaps;
102   GMainLoop *mainloop;
103
104   g_print (" Input URI  : %s\n", uri);
105   g_print (" Output URI : %s\n", outputuri);
106
107   sink = gst_element_make_from_uri (GST_URI_SINK, outputuri, "sink");
108   if (G_UNLIKELY (sink == NULL)) {
109     g_print ("Can't create output sink, most likely invalid output URI !\n");
110     return;
111   }
112
113   src = gst_element_factory_make ("uridecodebin", NULL);
114   if (G_UNLIKELY (src == NULL)) {
115     g_print ("Can't create uridecodebin for input URI, aborting!\n");
116     return;
117   }
118
119   /* Figure out the streams that can be passed as-is to encodebin */
120   g_object_get (src, "caps", &rescaps, NULL);
121   rescaps = gst_caps_copy (rescaps);
122   profilecaps = gst_encoding_profile_get_codec_caps (prof);
123   gst_caps_append (rescaps, profilecaps);
124
125   /* Set properties */
126   g_object_set (src, "uri", uri, "caps", rescaps, NULL);
127
128   ebin = gst_element_factory_make ("encodebin", NULL);
129   g_object_set (ebin, "profile", prof, NULL);
130
131   g_signal_connect (src, "autoplug-continue", G_CALLBACK (autoplug_continue_cb),
132       ebin);
133   g_signal_connect (src, "pad-added", G_CALLBACK (pad_added_cb), ebin);
134
135   pipeline = gst_pipeline_new ("encoding-pipeline");
136
137   gst_bin_add_many (GST_BIN (pipeline), src, ebin, sink, NULL);
138
139   gst_element_link (ebin, sink);
140
141   mainloop = g_main_loop_new (NULL, FALSE);
142
143   bus = gst_pipeline_get_bus ((GstPipeline *) pipeline);
144   gst_bus_add_signal_watch (bus);
145   g_signal_connect (bus, "message", G_CALLBACK (bus_message_cb), mainloop);
146
147   if (gst_element_set_state (pipeline,
148           GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
149     g_print ("Failed to start the encoding\n");
150     return;
151   }
152
153   g_main_loop_run (mainloop);
154
155   gst_element_set_state (pipeline, GST_STATE_NULL);
156 }
157
158 static gchar *
159 ensure_uri (gchar * location)
160 {
161   gchar *res;
162   gchar *path;
163
164   if (gst_uri_is_valid (location))
165     return g_strdup (location);
166
167   if (!g_path_is_absolute (location)) {
168     gchar *cur_dir;
169     cur_dir = g_get_current_dir ();
170     path = g_build_filename (cur_dir, location, NULL);
171     g_free (cur_dir);
172   } else
173     path = g_strdup (location);
174
175   res = g_filename_to_uri (path, NULL, NULL);
176   g_free (path);
177
178   return res;
179 }
180
181 int
182 main (int argc, char **argv)
183 {
184   GError *err = NULL;
185   gchar *outputuri = NULL;
186   gchar *format = NULL;
187   GOptionEntry options[] = {
188     {"silent", 's', 0, G_OPTION_ARG_NONE, &silent,
189         "Don't output the information structure", NULL},
190     {"outputuri", 'o', 0, G_OPTION_ARG_STRING, &outputuri,
191         "URI to encode to", "URI (<protocol>://<location>)"},
192     {"format", 'f', 0, G_OPTION_ARG_STRING, &format,
193         "DLNA profile to use", NULL},
194     {NULL}
195   };
196   GOptionContext *ctx;
197   GUPnPDLNAProfile *profile;
198   gchar *inputuri;
199
200   if (!g_thread_supported ())
201     g_thread_init (NULL);
202
203   ctx = g_option_context_new ("- encode URIs with GstProfile and encodebin");
204   g_option_context_add_main_entries (ctx, options, NULL);
205   g_option_context_add_group (ctx, gst_init_get_option_group ());
206
207   if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
208     g_print ("Error initializing: %s\n", err->message);
209     exit (1);
210   }
211
212   g_option_context_free (ctx);
213
214   if (outputuri == NULL || argc != 2) {
215     g_print ("usage: %s <inputuri> -o <outputuri> --format <profile>\n",
216         argv[0]);
217     exit (-1);
218   }
219
220   /* Create the profile */
221   profile = gupnp_dlna_profile_from_name (format);
222   if (G_UNLIKELY (profile == NULL)) {
223     g_print ("Encoding arguments are not valid !\n");
224     return 1;
225   }
226
227   /* Fixup outputuri to be a URI */
228   inputuri = ensure_uri (argv[1]);
229   outputuri = ensure_uri (outputuri);
230
231   /* Trancode file */
232   transcode_file (inputuri, outputuri, profile->enc_profile);
233
234   /* cleanup */
235   g_object_unref (profile);
236
237   return 0;
238 }