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
29 #include <glib/gi18n.h>
33 #include "dix-transcoder.h"
39 struct _DixTranscoderPrivate
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
);
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
;
70 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
75 dix_transcoder_get_property (GObject
*object
, guint prop_id
, GValue
*value
, GParamSpec
*pspec
)
77 DixTranscoder
*transcoder
= (DixTranscoder
*) object
;
78 DixTranscoderPrivate
*priv
= transcoder
->priv
;
82 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
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
));
97 G_OBJECT_CLASS (dix_transcoder_parent_class
)->dispose (object
);
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
);
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
));
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
;
145 priv
->decoder
= NULL
;
146 priv
->encoder
= NULL
;
151 dix_transcoder_new ()
153 return g_object_new (DIX_TYPE_TRANSCODER
, NULL
);
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.");
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
) {
181 gst_bin_add_many (GST_BIN (transcoder
),
188 gst_element_link_many (priv
->source
,
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
);
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
;
220 dix_transcoder_error_cb (GstBus
*bus
, GstMessage
*message
, gpointer data
)
222 DixTranscoder
*transcoder
= (DixTranscoder
*) data
;
223 DixTranscoderPrivate
*priv
= transcoder
->priv
;
226 /* error = g_error_new (DIX_ERROR, DIX_ERROR_GST_INTERNAL,*/
227 /* _("Audio engine internal error"));*/
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
)) {
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
);
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
;
261 gst_message_parse_state_changed (message
, NULL
, &state
, NULL
);
262 if (message
->src
!= GST_OBJECT (transcoder
)) {
267 case GST_STATE_NULL
: {
269 } case GST_STATE_READY
: {
271 } case GST_STATE_PLAYING
: {
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
);