1 //Compile with:
2 // gcc -o ecore_pipe_gstreamer_example ecore_pipe_gstreamer_example.c `pkg-config --libs --cflags ecore gstreamer-1.0`
3 // or
4 // gcc -o ecore_pipe_gstreamer_example ecore_pipe_gstreamer_example.c `pkg-config --libs --cflags ecore gstreamer-0.10`
5
6 #include <gst/gst.h>
7 #include <Ecore.h>
8
9 static int nbr = 0;
10
11 static GstElement *_build_pipeline(gchar *filename, Ecore_Pipe *pipe);
12
13 static void new_decoded_pad_cb(GstElement *demuxer,
14 GstPad *new_pad,
15 gpointer user_data);
16
17 static void
handler(void * data,void * buf,unsigned int len EINA_UNUSED)18 handler(void *data, void *buf, unsigned int len EINA_UNUSED)
19 {
20 GstBuffer *buffer = *((GstBuffer **)buf);
21
22 printf("handler : %p\n", buffer);
23 printf("frame : %d %p %lld %p\n", nbr++, data, (long long)GST_BUFFER_DURATION(buffer), buffer);
24 gst_buffer_unref(buffer);
25 }
26
27 static void
handoff(GstElement * object EINA_UNUSED,GstBuffer * arg0,GstPad * arg1 EINA_UNUSED,gpointer user_data)28 handoff(GstElement *object EINA_UNUSED,
29 GstBuffer *arg0,
30 GstPad *arg1 EINA_UNUSED,
31 gpointer user_data)
32 {
33 Ecore_Pipe *pipe;
34
35 pipe = (Ecore_Pipe *)user_data;
36 printf("handoff : %p\n", arg0);
37 gst_buffer_ref(arg0);
38 ecore_pipe_write(pipe, &arg0, sizeof(arg0));
39 }
40
41 int
main(int argc,char * argv[])42 main(int argc, char *argv[])
43 {
44 GstElement *pipeline;
45 char *filename;
46 Ecore_Pipe *pipe;
47
48 gst_init(&argc, &argv);
49
50 if (!ecore_init())
51 {
52 gst_deinit();
53 return 0;
54 }
55
56 pipe = ecore_pipe_add(handler, NULL);
57 if (!pipe)
58 {
59 ecore_shutdown();
60 gst_deinit();
61 return 0;
62 }
63
64 if (argc < 2)
65 {
66 g_print("usage: %s file.avi\n", argv[0]);
67 ecore_pipe_del(pipe);
68 ecore_shutdown();
69 gst_deinit();
70 return 0;
71 }
72 filename = argv[1];
73
74 pipeline = _build_pipeline(filename, pipe);
75 if (!pipeline)
76 {
77 g_print("Error during the pipeline building\n");
78 ecore_pipe_del(pipe);
79 ecore_shutdown();
80 gst_deinit();
81 return -1;
82 }
83
84 gst_element_set_state(pipeline, GST_STATE_PLAYING);
85
86 ecore_main_loop_begin();
87
88 ecore_pipe_del(pipe);
89 ecore_shutdown();
90 gst_deinit();
91
92 return 0;
93 }
94
95 static void
new_decoded_pad_cb(GstElement * demuxer EINA_UNUSED,GstPad * new_pad,gpointer user_data)96 new_decoded_pad_cb(GstElement *demuxer EINA_UNUSED,
97 GstPad *new_pad,
98 gpointer user_data)
99 {
100 GstElement *decoder;
101 GstPad *pad;
102 GstCaps *caps;
103 GstStructure *s;
104 const gchar *str;
105
106 #if GST_CHECK_VERSION(1,0,0)
107 caps = gst_pad_get_current_caps(new_pad);
108 #else
109 caps = gst_pad_get_caps(new_pad);
110 #endif
111 s = gst_caps_get_structure(caps, 0);
112 str = gst_structure_get_name(s);
113
114 if (g_str_has_prefix(str, "video/"))
115 {
116 decoder = GST_ELEMENT(user_data);
117
118 #if GST_CHECK_VERSION(1,0,0)
119 pad = gst_element_get_static_pad(decoder, "sink");
120 #else
121 pad = gst_element_get_pad(decoder, "sink");
122 #endif
123 if (GST_PAD_LINK_FAILED(gst_pad_link(new_pad, pad)))
124 {
125 g_warning("Failed to link %s:%s to %s:%s", GST_DEBUG_PAD_NAME(new_pad),
126 GST_DEBUG_PAD_NAME(pad));
127 }
128 gst_object_unref(pad);
129 }
130 gst_caps_unref(caps);
131 }
132
133 static GstElement *
_build_pipeline(gchar * filename,Ecore_Pipe * pipe)134 _build_pipeline(gchar *filename, Ecore_Pipe *pipe)
135 {
136 GstElement *pipeline;
137 GstElement *filesrc;
138 GstElement *demuxer;
139 GstElement *decoder;
140 GstElement *sink;
141 GstStateChangeReturn res;
142
143 pipeline = gst_pipeline_new("pipeline");
144 if (!pipeline)
145 return NULL;
146
147 filesrc = gst_element_factory_make("filesrc", "filesrc");
148 if (!filesrc)
149 {
150 printf("no filesrc");
151 goto failure;
152 }
153 g_object_set(G_OBJECT(filesrc), "location", filename, NULL);
154
155 demuxer = gst_element_factory_make("oggdemux", "demuxer");
156 if (!demuxer)
157 {
158 printf("no demux");
159 goto failure;
160 }
161
162 decoder = gst_element_factory_make("theoradec", "decoder");
163 if (!decoder)
164 {
165 printf("no dec");
166 goto failure;
167 }
168
169 g_signal_connect(demuxer, "pad-added",
170 G_CALLBACK(new_decoded_pad_cb), decoder);
171
172 sink = gst_element_factory_make("fakesink", "sink");
173 if (!sink)
174 {
175 printf("no sink");
176 goto failure;
177 }
178 g_object_set(G_OBJECT(sink), "sync", EINA_TRUE, NULL);
179 g_object_set(G_OBJECT(sink), "signal-handoffs", EINA_TRUE, NULL);
180 g_signal_connect(sink, "handoff",
181 G_CALLBACK(handoff), pipe);
182
183 gst_bin_add_many(GST_BIN(pipeline),
184 filesrc, demuxer, decoder, sink, NULL);
185
186 if (!gst_element_link(filesrc, demuxer))
187 goto failure;
188 if (!gst_element_link(decoder, sink))
189 goto failure;
190
191 res = gst_element_set_state(pipeline, GST_STATE_PAUSED);
192 if (res == GST_STATE_CHANGE_FAILURE)
193 goto failure;
194
195 res = gst_element_get_state(pipeline, NULL, NULL, GST_CLOCK_TIME_NONE);
196 if (res != GST_STATE_CHANGE_SUCCESS)
197 goto failure;
198
199 return pipeline;
200
201 failure:
202 gst_object_unref(GST_OBJECT(pipeline));
203 return NULL;
204 }
205
206