1.1 --- a/maemo-ui/src/mmyth_videoplayer.c Wed Nov 22 00:16:33 2006 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,369 +0,0 @@
1.4 -
1.5 -#include <gst/gst.h>
1.6 -#include <gtk/gtk.h>
1.7 -#include <gdk/gdkx.h>
1.8 -#include <gst/interfaces/xoverlay.h>
1.9 -#include <unistd.h>
1.10 -
1.11 -#include "mmyth_ui.h"
1.12 -#include "mmyth_videoplayer.h"
1.13 -#include "mmyth_sdpreader.h"
1.14 -
1.15 -#include "esg_database.h"
1.16 -
1.17 -#include "ipd_demux.h"
1.18 -#include "ipd_network.h"
1.19 -
1.20 -#ifdef INDT_IP_DECAPSULATOR
1.21 -#include <sys/types.h>
1.22 -#include <signal.h>
1.23 -#endif
1.24 -
1.25 -/* Global flag/semaphore to control IP decapsulator threads */
1.26 -gboolean state_keep_running = 0;
1.27 -
1.28 -
1.29 -typedef struct _GstPlayerWindowStateChange
1.30 -{
1.31 - GstElement *play;
1.32 - GstState old_state, new_state;
1.33 - MMythUi *mmyth_ui;
1.34 -} GstPlayerWindowStateChange;
1.35 -
1.36 -typedef struct _GstPlayerWindowTagFound
1.37 -{
1.38 - GstElement *play;
1.39 - GstTagList *taglist;
1.40 - MMythUi *mmyth_ui;
1.41 -} GstPlayerWindowTagFound;
1.42 -
1.43 -
1.44 -GstElement *gst_pipeline, *gst_decoder, *gst_videosink;
1.45 -
1.46 -static gboolean idle_state (gpointer data);
1.47 -
1.48 -static gboolean
1.49 -bus_call (GstBus * bus, GstMessage * msg, gpointer data)
1.50 -{
1.51 - MMythUi *mmyth_ui = (MMythUi *) data;
1.52 - GMainLoop *loop = mmyth_ui->loop;
1.53 -
1.54 - switch (GST_MESSAGE_TYPE (msg)) {
1.55 - case GST_MESSAGE_EOS:
1.56 -
1.57 - if (mmyth_ui->idle_id != 0) {
1.58 - g_source_remove (mmyth_ui->idle_id);
1.59 - mmyth_ui->idle_id = 0;
1.60 - }
1.61 -
1.62 - //g_idle_add ((GSourceFunc) idle_eos, data);
1.63 - gst_element_set_state (GST_ELEMENT (GST_MESSAGE_SRC (msg)),
1.64 - GST_STATE_READY);
1.65 - break;
1.66 - case GST_MESSAGE_ERROR:{
1.67 - gchar *debug;
1.68 - GError *err;
1.69 -
1.70 - gst_message_parse_error (msg, &err, &debug);
1.71 - g_free (debug);
1.72 -
1.73 - printf ("Error: %s\n", err->message);
1.74 - g_error_free (err);
1.75 -
1.76 - g_main_loop_quit (loop);
1.77 - }
1.78 - break;
1.79 - case GST_MESSAGE_STATE_CHANGED:{
1.80 - GstState oldstate;
1.81 - GstState newstate;
1.82 - GstState pending;
1.83 - GstPlayerWindowStateChange *st =
1.84 - g_new (GstPlayerWindowStateChange, 1);
1.85 -
1.86 - gst_message_parse_state_changed (msg,
1.87 - &oldstate,
1.88 - &newstate, &pending);
1.89 -
1.90 - st->play = mmyth_ui->play;
1.91 - gst_object_ref (GST_OBJECT (mmyth_ui->play));
1.92 - st->old_state = oldstate;
1.93 - st->new_state = newstate;
1.94 -
1.95 - st->mmyth_ui = mmyth_ui;
1.96 -
1.97 - /* State debug messages */
1.98 - printf ("oldstate = %s, newstate = %s, pendingstate = %s\n",
1.99 - gst_element_state_get_name (oldstate),
1.100 - gst_element_state_get_name (newstate),
1.101 - gst_element_state_get_name (pending));
1.102 -
1.103 - g_idle_add ((GSourceFunc) idle_state, st);
1.104 -
1.105 - }
1.106 - break;
1.107 - default:
1.108 - printf (gst_message_type_get_name (GST_MESSAGE_TYPE (msg)));
1.109 - printf ("\n");
1.110 - break;
1.111 - }
1.112 -
1.113 - return TRUE;
1.114 -}
1.115 -
1.116 -
1.117 -static gboolean
1.118 -cb_iterate (gpointer data)
1.119 -{
1.120 - MMythUi *mmyth_ui = (MMythUi *) data;
1.121 - //gboolean res;
1.122 -
1.123 - g_main_loop_run (mmyth_ui->loop);
1.124 -/*
1.125 - if (!GST_FLAG_IS_SET (mmyth_ui->play, GST_BIN_SELF_SCHEDULABLE)) {
1.126 - res = gst_bin_iterate (GST_BIN (mmyth_ui->play));
1.127 - } else {
1.128 - g_usleep (100);
1.129 - res = (gst_element_get_state (mmyth_ui->play) == GST_STATE_PLAYING);
1.130 - }
1.131 -
1.132 - if (!res)
1.133 - mmyth_ui->idle_id = 0;
1.134 -
1.135 - return res;
1.136 -*/
1.137 - return FALSE;
1.138 -
1.139 -}
1.140 -
1.141 -static gboolean
1.142 -idle_state (gpointer data)
1.143 -{
1.144 - GstPlayerWindowStateChange *st = data;
1.145 -
1.146 - if (st->old_state == GST_STATE_PLAYING) {
1.147 - if (st->mmyth_ui->idle_id != 0) {
1.148 - g_source_remove (st->mmyth_ui->idle_id);
1.149 - st->mmyth_ui->idle_id = 0;
1.150 - }
1.151 - }
1.152 - else if (st->new_state == GST_STATE_PLAYING) {
1.153 - if (st->mmyth_ui->idle_id != 0)
1.154 - g_source_remove (st->mmyth_ui->idle_id);
1.155 -
1.156 - st->mmyth_ui->idle_id = g_idle_add (cb_iterate, st->mmyth_ui);
1.157 - }
1.158 -
1.159 - /* new movie loaded? */
1.160 - if (st->old_state == GST_STATE_READY && st->new_state > GST_STATE_READY) {
1.161 -
1.162 - /* gboolean have_video = FALSE; */
1.163 -
1.164 - gtk_widget_show (st->mmyth_ui->videow);
1.165 -
1.166 - gtk_window_resize (GTK_WINDOW (st->mmyth_ui->main_window), 1, 1);
1.167 -
1.168 - }
1.169 -
1.170 - /* discarded movie? */
1.171 - if (st->old_state > GST_STATE_READY && st->new_state == GST_STATE_READY) {
1.172 -
1.173 - if (st->mmyth_ui->tagcache) {
1.174 - gst_tag_list_free (st->mmyth_ui->tagcache);
1.175 - st->mmyth_ui->tagcache = NULL;
1.176 - }
1.177 - }
1.178 -
1.179 - gst_object_unref (GST_OBJECT (st->play));
1.180 - //g_object_unref (G_OBJECT (st->win));
1.181 - g_free (st);
1.182 -
1.183 - /* once */
1.184 - return FALSE;
1.185 -}
1.186 -
1.187 -
1.188 -
1.189 -static gboolean
1.190 -expose (GtkWidget * widget, GdkEventExpose * event, gpointer user_data)
1.191 -{
1.192 - MMythUi *mmyth_ui = (MMythUi *) user_data;
1.193 -
1.194 - gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (mmyth_ui->videosink),
1.195 - GDK_WINDOW_XWINDOW (mmyth_ui->videow->
1.196 - window));
1.197 - return TRUE;
1.198 -}
1.199 -
1.200 -
1.201 -void
1.202 -mmyth_player_init (MMythUi * mmyth_ui)
1.203 -{
1.204 - GstElement *play;
1.205 - GstElement *source, *parser, *decoder, *videosink;
1.206 -
1.207 - play = gst_pipeline_new ("video-player");
1.208 - source = gst_element_factory_make ("udpsrc", "file-source");
1.209 - parser = gst_element_factory_make ("rtph263pdepay", "rtp-demux");
1.210 - decoder = gst_element_factory_make ("ffdec_h263", "mpeg-decoder");
1.211 - videosink = gst_element_factory_make ("xvimagesink", "image-output");
1.212 - gst_pipeline = play;
1.213 - gst_decoder = decoder;
1.214 - gst_videosink = videosink;
1.215 -
1.216 - if (!(gst_pipeline && source && parser && decoder && videosink)) {
1.217 - /* FIXME: hanlde the error correctly */
1.218 - /* video_alignment is not being created (below)
1.219 - and is causing problems to the ui */
1.220 - g_print ("GstElement creation error!\n");
1.221 - return;
1.222 - }
1.223 -
1.224 - g_object_set (G_OBJECT (videosink), "sync", FALSE, NULL);
1.225 -
1.226 - gst_bus_add_watch (gst_pipeline_get_bus (GST_PIPELINE (gst_pipeline)),
1.227 - bus_call, mmyth_ui);
1.228 -
1.229 - gst_bin_add_many (GST_BIN (gst_pipeline), source, parser, decoder,
1.230 - videosink, NULL);
1.231 -
1.232 - {
1.233 - GstCaps *rtpcaps = gst_caps_new_simple ("application/x-rtp", NULL);
1.234 - gst_element_link_filtered(source, parser, rtpcaps);
1.235 - }
1.236 -
1.237 - gst_element_link_many (/*source,*/ parser, decoder, videosink, NULL);
1.238 -
1.239 - /* actual window */
1.240 - mmyth_ui->play = play;
1.241 - mmyth_ui->videosink = videosink;
1.242 - mmyth_ui->udpsource = source;
1.243 -
1.244 - g_object_ref (mmyth_ui->play);
1.245 - g_object_ref (mmyth_ui->videosink);
1.246 -
1.247 - /* video widget */
1.248 - //mmyth_ui->videow = gst_player_video_new (videosink, play);
1.249 - mmyth_ui->videow = gtk_drawing_area_new ();
1.250 - gtk_widget_set_size_request (mmyth_ui->videow, 300, 240);
1.251 -
1.252 - mmyth_ui->logo = gdk_pixbuf_new_from_file ("logo.png", NULL);
1.253 -
1.254 -
1.255 - mmyth_ui->video_alignment = gtk_alignment_new (0.5, 0.5, 0, 0);
1.256 - gtk_widget_hide (mmyth_ui->video_alignment);
1.257 -
1.258 - gtk_container_add (GTK_CONTAINER (mmyth_ui->video_alignment),
1.259 - mmyth_ui->videow);
1.260 -
1.261 - g_signal_connect (mmyth_ui->videow, "expose-event", G_CALLBACK (expose),
1.262 - mmyth_ui);
1.263 - //g_signal_connect(mmyth_ui->videow, "size_request", G_CALLBACK(cb_preferred_video_size), mmyth_ui);
1.264 -
1.265 -
1.266 - g_object_ref (mmyth_ui->videow);
1.267 - g_object_ref (mmyth_ui->video_alignment);
1.268 -
1.269 - //gnome_app_set_contents (app, videow);
1.270 - //gtk_widget_show (mmyth_ui->videow);
1.271 -
1.272 -//fail:
1.273 -// gst_object_unref (GST_OBJECT (play));
1.274 -// return NULL;
1.275 -
1.276 -}
1.277 -
1.278 -void
1.279 -mmyth_player_stop (MMythUi * mmyth_ui)
1.280 -{
1.281 - gst_element_set_state (mmyth_ui->play, GST_STATE_NULL);
1.282 -
1.283 - if(mmyth_ui->videow != NULL)
1.284 - gtk_widget_hide (mmyth_ui->videow);
1.285 -
1.286 - /* Disable IP Decapsulator playing threads */
1.287 - state_keep_running = FALSE;
1.288 -
1.289 -}
1.290 -
1.291 -static gboolean
1.292 -idle_play (gpointer data)
1.293 -{
1.294 - MMythUi *mmyth_ui = (MMythUi *) data;
1.295 -
1.296 - sleep (2);
1.297 -
1.298 - gst_element_set_state (mmyth_ui->play, GST_STATE_PLAYING);
1.299 -
1.300 - return FALSE;
1.301 -}
1.302 -
1.303 -
1.304 -/* Run IP decapsulator play function in a new thread. The thread is finished setting the
1.305 - * semaphore "state_keep_running" to FALSE*/
1.306 -gpointer
1.307 -run_ipd(gpointer data)
1.308 -{
1.309 - GString *ip_addr = (GString*) data;
1.310 -
1.311 - state_keep_running = TRUE;
1.312 -
1.313 - printf("Inside thread\n");
1.314 -
1.315 - ipd_mpe_play_section (ip_addr->str, &state_keep_running);
1.316 -
1.317 - return 0;
1.318 -}
1.319 -
1.320 -void
1.321 -mmyth_play_channel (MMythUi * mmyth_ui, gint service_number)
1.322 -{
1.323 - ESGDatabase *esg_db;
1.324 - DVBHService *service;
1.325 - SDPData sdp_data;
1.326 - GString *service_ip_addr;
1.327 -
1.328 - /* First verifies if there is a tuned network */
1.329 - if ( !ipd_network_is_tuned() ) {
1.330 - /* FIXME: show alert and handle this error */
1.331 - g_warning ("Play not possible, network not tuned");
1.332 - return;
1.333 - }
1.334 -
1.335 - esg_db = esg_database_get_instance();
1.336 - /* Gets the service structure */
1.337 - service = (DVBHService *) esg_database_get_service_from_number
1.338 - (esg_db, service_number);
1.339 -
1.340 - /* Verifies if sdp fragment exists to this service */
1.341 - if ( service->sdp_file == NULL ) {
1.342 - /* FIXME: Implement error handling */
1.343 - g_warning ("SDP fragment not available to access service");
1.344 - return;
1.345 - }
1.346 -
1.347 - /* Parses the sdp to get ipv6 address and port */
1.348 - mmyth_sdp_parse_file (service->sdp_file->str, &sdp_data);
1.349 -
1.350 - /* Sets the gstreamer properties acording to the service access address */
1.351 - /* FIXME: Develop sdp_bin in gstreamer to give sdp file as pipeline config */
1.352 - g_object_set (G_OBJECT (mmyth_ui->udpsource), "multicast_group",
1.353 - sdp_data.ip_addr->str, NULL);
1.354 - g_object_set (G_OBJECT (mmyth_ui->udpsource), "port", sdp_data.video_port, NULL);
1.355 -
1.356 - /* Shows the video widget on screen */
1.357 - mmyth_ui_set_widget (mmyth_ui, mmyth_ui->video_uicommon);
1.358 -
1.359 - gtk_widget_show (mmyth_ui->videow);
1.360 - gtk_widget_queue_draw (mmyth_ui->videow);
1.361 -
1.362 -#ifdef INDT_IP_DECAPSULATOR
1.363 - /* Will be dealocated in run_ipd */
1.364 - service_ip_addr = g_string_new (sdp_data.ip_addr->str);
1.365 -
1.366 - /* Requests the IP decapsulator to play the channel stream*/
1.367 - g_thread_create (run_ipd, (gpointer) service_ip_addr, FALSE, NULL);
1.368 -#endif
1.369 -
1.370 - //gst_element_set_state (mmyth_ui->play, GST_STATE_PLAYING);
1.371 - g_idle_add (idle_play, mmyth_ui);
1.372 -}