Tizen 2.1 base
[profile/mobile/emotion.git] / src / modules / gstreamer / emotion_gstreamer_pipeline_dvd.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4 #include "emotion_gstreamer.h"
5 #include "emotion_gstreamer_pipeline.h"
6
7
8 static void dvd_pad_added_cb    (GstElement *dvddemuxer,
9                                  GObject    *new_pad,
10                                  gpointer    user_data);
11
12 static void dvd_no_more_pads_cb (GstElement *dvddemuxer,
13                                  gpointer    user_data);
14
15 static int no_more_pads = 0;
16
17
18 int
19 emotion_pipeline_dvd_build(void *video, const char *device)
20 {
21    GstElement              *dvdreadsrc;
22    GstElement              *dvddemux;
23    Emotion_Gstreamer_Video *ev;
24
25    ev = (Emotion_Gstreamer_Video *)video;
26    if (!ev) return 0;
27
28    dvdreadsrc = gst_element_factory_make("dvdreadsrc", "src");
29    if (!dvdreadsrc)
30      goto failure_dvdreadsrc;
31    if (device)
32      g_object_set(G_OBJECT(dvdreadsrc), "device", device, NULL);
33
34    dvddemux = gst_element_factory_make("dvddemux", "dvddemux");
35    if (!dvddemux)
36      goto failure_dvddemux;
37    g_signal_connect(dvddemux, "pad-added",
38                     G_CALLBACK(dvd_pad_added_cb), ev);
39    g_signal_connect(dvddemux, "no-more-pads",
40                     G_CALLBACK(dvd_no_more_pads_cb), ev);
41
42    gst_bin_add_many(GST_BIN(ev->pipeline), dvdreadsrc, dvddemux, NULL);
43    if (!gst_element_link(dvdreadsrc, dvddemux))
44      goto failure_link;
45
46    if (!emotion_pipeline_pause(ev->pipeline))
47      goto failure_gstreamer_pause;
48
49    while (no_more_pads == 0)
50      {
51         g_print("toto\n");
52      }
53    no_more_pads = 0;
54
55    /* We get the informations of streams */
56    ecore_list_first_goto(ev->video_sinks);
57    ecore_list_first_goto(ev->audio_sinks);
58
59      {
60         GstIterator *it;
61         gpointer     data;
62
63         it = gst_element_iterate_src_pads(dvddemux);
64         while (gst_iterator_next(it, &data) == GST_ITERATOR_OK)
65           {
66              GstPad  *pad;
67              GstCaps *caps;
68              gchar   *str;
69
70              pad = GST_PAD(data);
71
72              caps = gst_pad_get_caps(pad);
73              str = gst_caps_to_string(caps);
74              g_print("caps !! %s\n", str);
75              /* video stream */
76              if (g_str_has_prefix(str, "video/mpeg"))
77                {
78                   Emotion_Video_Sink *vsink;
79                   GstPad             *sink_pad;
80                   GstCaps            *sink_caps;
81
82                   vsink = (Emotion_Video_Sink *)ecore_list_next(ev->video_sinks);
83                   sink_pad = gst_element_get_pad(gst_bin_get_by_name(GST_BIN(ev->pipeline), "mpeg2dec"), "src");
84                   sink_caps = gst_pad_get_caps(sink_pad);
85                   str = gst_caps_to_string(sink_caps);
86                   g_print(" ** caps v !! %s\n", str);
87
88                   emotion_video_sink_fill(vsink, sink_pad, sink_caps);
89
90                   gst_caps_unref(sink_caps);
91                   gst_object_unref(sink_pad);
92                }
93              /* audio stream */
94              else if (g_str_has_prefix(str, "audio/"))
95                {
96                   Emotion_Audio_Sink *asink;
97                   GstPad             *sink_pad;
98                   GstCaps            *sink_caps;
99
100                   asink = (Emotion_Audio_Sink *)ecore_list_next(ev->audio_sinks);
101                   sink_pad = gst_element_get_pad(gst_bin_get_by_name(GST_BIN(ev->pipeline), "a52dec"), "src");
102                   sink_caps = gst_pad_get_caps(sink_pad);
103
104                   emotion_audio_sink_fill(asink, sink_pad, sink_caps);
105                }
106              gst_caps_unref(caps);
107              g_free(str);
108              gst_object_unref(pad);
109           }
110         gst_iterator_free(it);
111      }
112
113    /* The first vsink is a valid Emotion_Video_Sink * */
114    /* If no video stream is found, it's a visualisation sink */
115      {
116         Emotion_Video_Sink *vsink;
117
118         vsink = (Emotion_Video_Sink *)ecore_list_first_goto(ev->video_sinks);
119         if (vsink && vsink->sink)
120           {
121              g_object_set(G_OBJECT(vsink->sink), "sync", TRUE, NULL);
122              g_object_set(G_OBJECT(vsink->sink), "signal-handoffs", TRUE, NULL);
123              g_signal_connect(G_OBJECT(vsink->sink),
124                               "handoff",
125                               G_CALLBACK(cb_handoff), ev);
126           }
127      }
128
129    return 1;
130
131 failure_gstreamer_pause:
132 failure_link:
133    gst_element_set_state(ev->pipeline, GST_STATE_NULL);
134    gst_bin_remove(GST_BIN(ev->pipeline), dvddemux);
135 failure_dvddemux:
136    gst_bin_remove(GST_BIN(ev->pipeline), dvdreadsrc);
137 failure_dvdreadsrc:
138
139    return 0;
140 }
141
142 static void
143 dvd_pad_added_cb(GstElement *dvddemuxer,
144                  GObject    *new_pad,
145                  gpointer    user_data)
146 {
147    Emotion_Gstreamer_Video *ev;
148    GstCaps                 *caps;
149    gchar                   *str;
150
151    ev = (Emotion_Gstreamer_Video *)user_data;
152    caps = gst_pad_get_caps(GST_PAD(new_pad));
153    str = gst_caps_to_string(caps);
154    /* video stream */
155    if (g_str_has_prefix(str, "video/mpeg"))
156      {
157         Emotion_Video_Sink *vsink;
158         GstElement         *queue;
159         GstElement         *decoder;
160         GstPad             *videopad;
161
162         vsink = (Emotion_Video_Sink *)malloc(sizeof(Emotion_Video_Sink));
163         if (!vsink) return;
164         if (!ecore_list_append(ev->video_sinks, vsink))
165           {
166              free(vsink);
167              return;
168           }
169
170         queue = gst_element_factory_make("queue", NULL);
171         decoder = gst_element_factory_make("mpeg2dec", "mpeg2dec");
172         vsink->sink = gst_element_factory_make("fakesink", "videosink");
173         gst_bin_add_many(GST_BIN(ev->pipeline), queue, decoder, vsink->sink, NULL);
174         gst_element_link(queue, decoder);
175         gst_element_link(decoder, vsink->sink);
176         videopad = gst_element_get_pad(queue, "sink");
177         gst_pad_link(GST_PAD(new_pad), videopad);
178         gst_object_unref(videopad);
179         if (ecore_list_count(ev->video_sinks) == 1)
180           {
181              ev->ratio = (double)vsink->width / (double)vsink->height;
182           }
183         gst_element_set_state(queue, GST_STATE_PAUSED);
184         gst_element_set_state(decoder, GST_STATE_PAUSED);
185         gst_element_set_state(vsink->sink, GST_STATE_PAUSED);
186      }
187    /* audio stream */
188    else if (g_str_has_prefix(str, "audio/"))
189      {
190         Emotion_Audio_Sink *asink;
191         GstElement         *queue;
192         GstElement         *decoder;
193         GstElement         *conv;
194         GstElement         *resample;
195         GstElement         *volume;
196         GstPad             *audiopad;
197         double              vol;
198
199         asink = (Emotion_Audio_Sink *)malloc(sizeof(Emotion_Audio_Sink));
200         if (!asink) return;
201         if (!ecore_list_append(ev->audio_sinks, asink))
202           {
203              free(asink);
204              return;
205           }
206
207         queue = gst_element_factory_make("queue", NULL);
208         decoder = gst_element_factory_make("a52dec", "a52dec");
209         conv = gst_element_factory_make("audioconvert", NULL);
210         resample = gst_element_factory_make("audioresample", NULL);
211         volume = gst_element_factory_make("volume", "volume");
212         g_object_get(G_OBJECT(volume), "volume", &vol, NULL);
213         ev->volume = vol / 10.0;
214
215         /* FIXME: must manage several audio streams */
216         asink->sink = gst_element_factory_make("fakesink", NULL);
217
218         gst_bin_add_many(GST_BIN(ev->pipeline),
219                          queue, decoder, conv, resample, volume, asink->sink, NULL);
220         gst_element_link_many(queue, decoder, conv, resample, volume, asink->sink, NULL);
221
222         audiopad = gst_element_get_pad(queue, "sink");
223         gst_pad_link(GST_PAD(new_pad), audiopad);
224         gst_object_unref(audiopad);
225
226         gst_element_set_state(queue, GST_STATE_PAUSED);
227         gst_element_set_state(decoder, GST_STATE_PAUSED);
228         gst_element_set_state(conv, GST_STATE_PAUSED);
229         gst_element_set_state(resample, GST_STATE_PAUSED);
230         gst_element_set_state(volume, GST_STATE_PAUSED);
231         gst_element_set_state(asink->sink, GST_STATE_PAUSED);
232      }
233 }
234
235 static void
236 dvd_no_more_pads_cb(GstElement *dvddemuxer,
237                     gpointer    user_data)
238 {
239   no_more_pads = 1;
240 }