pushing backup
[glsdk/dual-decode.git] / src / gst-controller.c
1 /*                                                                              
2  *  Copyright (c) 2010-2011, Texas Instruments Incorporated                     
3  *                                                                              
4  *  Redistribution and use in source and binary forms, with or without          
5  *  modification, are permitted provided that the following conditions          
6  *  are met:                                                                    
7  *                                                                              
8  *  *  Redistributions of source code must retain the above copyright           
9  *   notice, this list of conditions and the following disclaimer.              
10  *                                                                              
11  *  *  Redistributions in binary form must reproduce the above copyright        
12  *   notice, this list of conditions and the following disclaimer in the        
13  *   documentation and/or other materials provided with the distribution.       
14  *                                                                              
15  *  *  Neither the name of Texas Instruments Incorporated nor the names of      
16  *   its contributors may be used to endorse or promote products derived        
17  *   from this software without specific prior written permission.              
18  *                                                                              
19  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
20  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,       
21  *  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR      
22  *  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR            
23  *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,       
24  *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,         
25  *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
26  *  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,    
27  *  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR     
28  *  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,              
29  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                          
30  *                                                                              
31  *  Contact information for paper mail:                                         
32  *  Texas Instruments                                                           
33  *  Post Office Box 655303                                                      
34  *  Dallas, Texas 75265                                                         
35  *  Contact information:                                                        
36  *  http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
37  *  DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact                             
38  *  ============================================================================
39  *                                                                              
40  */                                                                             
41                                                                                 
42 /**                                                                             
43  * @file  gst-controller.c                                                                 
44  *                                                                              
45  * @brief                                                                       
46  */ 
47 #include <stdint.h>
48 #include <string.h>
49 #include <gst/gst.h>
50 #include <gtk/gtk.h>
51 #include <gdk/gdkx.h>
52 #include <gst/interfaces/xoverlay.h>
54 #include "gst-controller.h"
56 GstElement * createImageSinkFromWindow(GtkWidget *window,gchar *name)
57 {
58         GstElement *sink                = NULL;
59         XID xid                                 = 0;
60         GdkDrawable *drawable   = NULL;
62         /*make an xvimagesink element from factory*/
63         /*TODO : hard coded strings. will change*/
64         sink = gst_element_factory_make("xvimagesink",name);
65         if(NULL == sink){
66                 goto return_pos;
67         }
69         /*get the XID of the display window's drawable*/
70         drawable = gtk_widget_get_window (GTK_WIDGET (window));
71         if(FALSE == GDK_IS_DRAWABLE(drawable)){
72                 /*TODO: A BUG HERE?*/
73                 g_object_unref(G_OBJECT(sink));
74                 sink=NULL;
75                 goto return_pos;
76         }
77         xid = gdk_x11_drawable_get_xid(drawable);
78         
79         /*link the gst sink element to the XID*/
80         gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (sink),xid);
82 return_pos:
83         return sink;
84 }
86 gboolean attachPipeElements (Pipeline *pipePtr, GtkWidget *drawArea1, 
87                              GtkWidget *drawArea2)
88 {
89     gboolean ret = TRUE;
90  
91     GstElement *bin = NULL;   
92     GstElement *tee = NULL;                                                     
93     GstElement *queue0 = NULL;                                                  
94     GstElement *queue1 = NULL;                                                  
95     GstElement *sink0 = NULL;                                                   
96     GstElement *sink1 = NULL;                                                   
97     GstPad *pad = NULL;   
98     
99     
100     if (NULL != drawArea2) { 
101         bin = gst_bin_new ("vsinkbin");
102         tee = gst_element_factory_make ("tee","splitter"); 
103         sink0 = createImageSinkFromWindow (drawArea1, "sink0");
104         queue0 = gst_element_factory_make ("queue","q0");                           
105         sink1 = createImageSinkFromWindow (drawArea2, "sink1"); 
106                 queue1 = gst_element_factory_make ("queue","q1");  
108         if ( !bin || !tee || !sink0 || !sink1 || !queue0 || !queue1) {
109             ret = FALSE;
110             goto exit;
111         }
112                    
113         gst_bin_add_many (GST_BIN (bin), tee, sink0, sink1, queue0, queue1,NULL); 
114     
115         /*Connecting the tee through queues is necessary to sync the two displays*/ 
116         gst_element_link(tee,queue0);                                               
117         gst_element_link(tee,queue1);                                               
118         gst_element_link(queue0,sink0);                                             
119         gst_element_link(queue1,sink1);                                             
120                                                                                 
121         pad = gst_element_get_static_pad (tee, "sink");                             
122         gst_element_add_pad (bin, gst_ghost_pad_new ("sink", pad));                 
123         gst_object_unref (GST_OBJECT (pad)); 
124         g_object_set (G_OBJECT (pipePtr->pipe), "video-sink", bin, NULL);              
125     }
126     else {
127     
128      sink0 = createImageSinkFromWindow (drawArea1, "sink0"); 
129      if (!sink0){
130          ret = FALSE;
131          goto exit;
132     }
133     g_object_set (G_OBJECT (pipePtr->pipe), "video-sink", sink0, NULL);
134     }
136 exit:    return ret;
138 gboolean busCallback(GstBus *bus, GstMessage *msg, gpointer data)
139 {    
140         gchar *name             = (gchar *)data;
141     gchar *debugMsg     = NULL;                                                 
142     GError *err         = NULL;                                                 
143     static int count = 0;
145     switch(GST_MESSAGE_TYPE(msg)){                                              
146                                                                                 
147         case GST_MESSAGE_EOS:                                                   
148             g_printerr("%s -> Message (EOS) : End of stream.\n",name);                          
149                         count++;
150             break;                                                              
151                                                                                
152          case GST_MESSAGE_ERROR: {                                             
153             gst_message_parse_error(msg,&err,&debugMsg);                      
154             g_printerr("%s -> Message (ERROR) : %s : debug ( %s )\n", name,err->message,debugMsg);                                                      
155             g_free(debugMsg);                                                   
156             g_error_free(err);                                                  
157                         count++;
158             break;                                                              
159         }                                                                       
160         case GST_MESSAGE_WARNING: {                                             
161             gst_message_parse_warning(msg,&err,&debugMsg);                      
162             g_printerr("%s -> Message (WARNING) : %s : debug ( %s )\n",
163                                            name,err->message,debugMsg);                                                      
164             g_free(debugMsg);                                                   
165             g_error_free(err);                                                  
166             break;                                                              
167         }                                                                       
168                                                                                 
169         default:                                                                
170             break;                                                              
171     }                                                                           
172                                                                                 
173     return TRUE;                                                                
174
175        
176 Pipeline * DualDecode_createPipeline()
178     Pipeline *pipelinePtr = (Pipeline *) malloc (sizeof(Pipeline));
179     pipelinePtr->pipe = NULL;
180                                                   
181     GstBus *bus = NULL;
182                                                                                 
183            
184     pipelinePtr->pipe = gst_element_factory_make("playbin2",NULL);                 
185     bus = gst_pipeline_get_bus (GST_PIPELINE(pipelinePtr->pipe));                    
186     pipelinePtr->busSignal = gst_bus_add_watch (bus,busCallback, NULL);                                   
187     gst_object_unref (bus);     
188     pipelinePtr->logFunc = NULL;
189                                                                           
190                                                                                 
191     return pipelinePtr;                
194 gboolean DualDecode_seekMedia(Pipeline *pipePtr, gint64 position)
196         if(position < 0){
197                 return FALSE;
198         }
199         return gst_element_seek_simple(pipePtr->pipe,
200                         GST_FORMAT_TIME,
201                         GST_SEEK_FLAG_FLUSH,
202                         position);
205 gboolean DualDecode_playMedia (Pipeline *pipePtr, gchar *filename, gint64 position,  
206                                GtkWidget *drawArea1, GtkWidget *drawArea2)
208     gboolean ret = TRUE;
209     
210     g_object_set(G_OBJECT(pipePtr->pipe),"uri", filename,NULL);
211         if (!(attachPipeElements (pipePtr, drawArea1, drawArea2))) {
212         ret = FALSE;
213         goto exit;
214     }
215         gst_element_set_state (pipePtr->pipe, GST_STATE_NULL);                                 
216     gst_element_set_state (pipePtr->pipe, GST_STATE_PLAYING);                                 
218         DualDecode_getMediaState(pipePtr);
219         DualDecode_seekMedia(pipePtr, position);
220     
221      
222 exit:    return ret;
225 gboolean DualDecode_pauseMedia (Pipeline *pipePtr)
227     gboolean ret = TRUE;
228     if(!gst_element_set_state (pipePtr->pipe, GST_STATE_PAUSED))
229         ret = FALSE;  
230     
231     return ret;
234 gboolean DualDecode_resumeMedia (Pipeline *pipePtr)                              
235 {                                                                               
236     gboolean ret = TRUE;                                                        
237     if(!gst_element_set_state (pipePtr->pipe, GST_STATE_PLAYING))                
238         ret = FALSE;                                                            
239                                                                                 
240     return ret;                                                                 
241
243 gboolean DualDecode_stopMedia (Pipeline *pipePtr)                             
244 {                                                                               
245     gboolean ret = TRUE;                                                        
246     if(!gst_element_set_state (pipePtr->pipe, GST_STATE_NULL))               
247         ret = FALSE;                                                            
248                                                                                 
249     return ret;                                                                 
250 }  
252 gboolean DualDecode_setLogFunction (Pipeline *pipePtr, LogFunc func, gpointer data)
254     gboolean ret = TRUE;
255     
257     return ret;   
260 GstState DualDecode_getMediaState(Pipeline *pipePtr)
262         GstState state, pending;
263         if(GST_STATE_CHANGE_SUCCESS != gst_element_get_state(
264                                 pipePtr->pipe,
265                                 &state,
266                                 &pending,
267                                 GST_CLOCK_TIME_NONE)){
268                 /*TODO : a bug here*/
269                 g_printerr("No state in GstElement\n");
270         }
271         return state;