Initial notification support (need system libnotify.deps update).
[dictix.git] / libdictix / dix-transcoder.c
blobe7a792bdb95fba4467742ac4dfc52f005dc25f51
1 /**
2 * Dictix / DixTranscoder - dix-transcoder.c
4 * Copyright (C) Martin Blanchard 2011 <tinram@gmx.fr>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <glib.h>
29 #include <glib/gi18n.h>
30 #include <gio/gio.h>
31 #include <gst/gst.h>
33 #include "dix-transcoder.h"
35 enum {
36 PROP_0
39 struct _DixTranscoderPrivate
41 gchar *input_uri;
42 gchar *output_uri;
44 GstBus *bus;
46 GstElement *source;
47 GstElement *decoder;
48 GstElement *encoder;
49 GstElement *sink;
52 #define DIX_TRANSCODER_GET_PRIVATE(obj) \
53 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), DIX_TYPE_TRANSCODER, DixTranscoderPrivate))
55 G_DEFINE_TYPE (DixTranscoder, dix_transcoder, GST_TYPE_PIPELINE)
57 static void dix_transcoder_error_cb (GstBus *bus, GstMessage *message, gpointer data);
58 static void dix_transcoder_element_cb (GstBus *bus, GstMessage *message, gpointer data);
59 static void dix_transcoder_state_changed_cb (GstBus *bus, GstMessage *message, gpointer data);
60 static void dix_transcoder_eos_cb (GstBus *bus, GstMessage *message, gpointer data);
62 static void
63 dix_transcoder_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
65 DixTranscoder *transcoder = (DixTranscoder *) object;
66 DixTranscoderPrivate *priv = transcoder->priv;
68 switch (prop_id) {
69 default:
70 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
74 static void
75 dix_transcoder_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
77 DixTranscoder *transcoder = (DixTranscoder *) object;
78 DixTranscoderPrivate *priv = transcoder->priv;
80 switch (prop_id) {
81 default:
82 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
86 static void
87 dix_transcoder_dispose (GObject *object)
89 DixTranscoder *transcoder = (DixTranscoder *) object;
90 DixTranscoderPrivate *priv = transcoder->priv;
92 if (priv->bus != NULL) {
93 gst_object_unref (GST_OBJECT (priv->bus));
95 priv->bus = NULL;
97 G_OBJECT_CLASS (dix_transcoder_parent_class)->dispose (object);
100 static void
101 dix_transcoder_finalize (GObject *object)
103 DixTranscoder *transcoder = (DixTranscoder *) object;
104 DixTranscoderPrivate *priv = transcoder->priv;
106 if (priv->input_uri != NULL) {
107 g_free (priv->input_uri);
109 priv->input_uri = NULL;
110 if (priv->output_uri != NULL) {
111 g_free (priv->output_uri);
113 priv->output_uri = NULL;
115 G_OBJECT_CLASS (dix_transcoder_parent_class)->finalize (object);
118 static void
119 dix_transcoder_class_init (DixTranscoderClass* klass)
121 GObjectClass *gobject_class = (GObjectClass *) klass;
123 gobject_class->set_property = dix_transcoder_set_property;
124 gobject_class->get_property = dix_transcoder_get_property;
125 gobject_class->dispose = dix_transcoder_dispose;
126 gobject_class->finalize = dix_transcoder_finalize;
128 g_type_class_add_private (gobject_class, sizeof (DixTranscoderPrivate));
131 static void
132 dix_transcoder_init (DixTranscoder* transcoder)
134 DixTranscoderPrivate *priv = DIX_TRANSCODER_GET_PRIVATE (transcoder);
135 transcoder->priv = priv;
137 gst_object_set_name (GST_OBJECT(transcoder), "DictixTranscoder");
139 priv->input_uri = NULL;
140 priv->output_uri = NULL;
142 priv->bus = NULL;
144 priv->source = NULL;
145 priv->decoder = NULL;
146 priv->encoder = NULL;
147 priv->sink = NULL;
150 DixTranscoder*
151 dix_transcoder_new ()
153 return g_object_new (DIX_TYPE_TRANSCODER, NULL);
156 void
157 dix_transcoder_pre_load (DixTranscoder *transcoder, gchar *uri)
159 g_return_if_fail (DIX_IS_TRANSCODER (transcoder));
160 g_return_if_fail (uri != NULL);
161 DixTranscoderPrivate *priv = transcoder->priv;
163 if (g_str_has_suffix (uri, ".flac") == FALSE) {
164 g_warning ("Transcoder only handles FLAC audio files as input.");
166 return;
169 if (G_UNLIKELY (priv->bus == NULL)) {
170 priv->source = gst_element_factory_make ("giosrc", "DictixTranscoderSource");
171 priv->decoder = gst_element_factory_make ("flacdec", "DictixTranscoderDecoder");
172 priv->encoder = gst_element_factory_make ("encodebin", "DictixTranscoderEncoder");
173 priv->sink = gst_element_factory_make ("giosink", "DictixTranscoderSink");
175 if (priv->source == NULL || priv->decoder == NULL
176 || priv->encoder == NULL || priv->sink == NULL) {
178 return;
181 gst_bin_add_many (GST_BIN (transcoder),
182 priv->source,
183 priv->decoder,
184 priv->encoder,
185 priv->sink,
186 NULL);
188 gst_element_link_many (priv->source,
189 priv->decoder,
190 priv->encoder,
191 priv->sink,
192 NULL);
194 priv->bus = gst_pipeline_get_bus (GST_PIPELINE (transcoder));
195 gst_bus_add_signal_watch (priv->bus);
196 g_signal_connect (priv->bus, "message::error",
197 G_CALLBACK (dix_transcoder_error_cb), transcoder);
198 g_signal_connect (priv->bus, "message::element",
199 G_CALLBACK (dix_transcoder_element_cb), transcoder);
200 g_signal_connect (priv->bus, "message::state-changed",
201 G_CALLBACK (dix_transcoder_state_changed_cb), transcoder);
202 g_signal_connect (priv->bus, "message::eos",
203 G_CALLBACK (dix_transcoder_eos_cb), transcoder);
206 g_object_set (G_OBJECT (priv->source), "location", uri, NULL);
209 void
210 dix_transcoder_transcode (DixTranscoder *transcoder, gchar *uri)
212 g_return_if_fail (DIX_IS_TRANSCODER (transcoder));
213 g_return_if_fail (uri != NULL);
214 DixTranscoderPrivate *priv = transcoder->priv;
219 static void
220 dix_transcoder_error_cb (GstBus *bus, GstMessage *message, gpointer data)
222 DixTranscoder *transcoder = (DixTranscoder *) data;
223 DixTranscoderPrivate *priv = transcoder->priv;
224 GError *error;
226 /* error = g_error_new (DIX_ERROR, DIX_ERROR_GST_INTERNAL,*/
227 /* _("Audio engine internal error"));*/
230 static void
231 dix_transcoder_element_cb (GstBus *bus, GstMessage *message, gpointer data)
233 DixTranscoder *transcoder = (DixTranscoder *) data;
234 DixTranscoderPrivate *priv = transcoder->priv;
235 const GstStructure *structure;
237 if (message->src != GST_OBJECT (priv->sink)) {
238 return;
241 structure = gst_message_get_structure (message);
242 if (gst_structure_has_name (structure, "file-exists")) {
243 /* File alredy exists, shoud not happened... */
244 gst_bus_set_flushing (priv->bus, TRUE);
248 gst_bus_set_flushing (priv->bus, FALSE);
249 gst_element_set_state (GST_ELEMENT (transcoder), GST_STATE_PLAYING);
253 static void
254 dix_transcoder_state_changed_cb (GstBus *bus, GstMessage *message, gpointer data)
256 DixTranscoder *transcoder = (DixTranscoder *) data;
257 DixTranscoderPrivate *priv = transcoder->priv;
258 GstState state, pending;
259 GFile *file = NULL;
261 gst_message_parse_state_changed (message, NULL, &state, NULL);
262 if (message->src != GST_OBJECT (transcoder)) {
263 return;
266 switch (state) {
267 case GST_STATE_NULL: {
268 break;
269 } case GST_STATE_READY: {
270 break;
271 } case GST_STATE_PLAYING: {
272 break;
273 } default: {
274 break;
279 static void
280 dix_transcoder_eos_cb (GstBus *bus, GstMessage *message, gpointer data)
282 DixTranscoder *transcoder = (DixTranscoder *) data;
283 DixTranscoderPrivate *priv = transcoder->priv;
285 gst_element_set_state (GST_ELEMENT (transcoder), GST_STATE_NULL);
286 gst_element_get_state (GST_ELEMENT (transcoder), NULL, NULL, GST_CLOCK_TIME_NONE);