1.1 --- a/maemo-ui-old/src/mmyth_tvplayer.c Fri Feb 01 14:30:21 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,712 +0,0 @@
1.4 -/**
1.5 - * GMyth Library
1.6 - *
1.7 - * @file gmyth/mmyth_tvplayer.c
1.8 - *
1.9 - * @brief <p> This component provides playback of the remote A/V using
1.10 - * GStreamer.
1.11 - *
1.12 - * Copyright (C) 2006 INdT - Instituto Nokia de Tecnologia.
1.13 - * @author Hallyson Luiz de Morais Melo <hallyson.melo@indt.org.br>
1.14 - *
1.15 - *//*
1.16 - *
1.17 - * This program is free software; you can redistribute it and/or modify
1.18 - * it under the terms of the GNU Lesser General Public License as published by
1.19 - * the Free Software Foundation; either version 2 of the License, or
1.20 - * (at your option) any later version.
1.21 - *
1.22 - * This program is distributed in the hope that it will be useful,
1.23 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.24 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1.25 - * GNU General Public License for more details.
1.26 - *
1.27 - * You should have received a copy of the GNU Lesser General Public License
1.28 - * along with this program; if not, write to the Free Software
1.29 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1.30 - */
1.31 -
1.32 -#include "mmyth_tvplayer.h"
1.33 -
1.34 -#include <gdk/gdkx.h>
1.35 -
1.36 -#include <gmyth/gmyth_remote_util.h>
1.37 -
1.38 -#define MYTHTV_VERSION_DEFAULT 30
1.39 -
1.40 -typedef struct _GstPlayerWindowStateChange {
1.41 - GstElement *play;
1.42 - GstState old_state,
1.43 - new_state;
1.44 - MMythTVPlayer *tvplayer;
1.45 -} GstPlayerWindowStateChange;
1.46 -
1.47 -typedef struct _GstPlayerWindowTagFound {
1.48 - GstElement *play;
1.49 - GstTagList *taglist;
1.50 - MMythTVPlayer *tvplayer;
1.51 -} GstPlayerWindowTagFound;
1.52 -
1.53 -/*
1.54 - * static gboolean idle_state (gpointer data);
1.55 - */
1.56 -static gboolean bus_call(GstBus * bus, GstMessage * msg, gpointer data);
1.57 -
1.58 -static void mmyth_tvplayer_class_init(MMythTVPlayerClass * klass);
1.59 -static void mmyth_tvplayer_init(MMythTVPlayer * object);
1.60 -
1.61 -static void mmyth_tvplayer_dispose(GObject * object);
1.62 -static void mmyth_tvplayer_finalize(GObject * object);
1.63 -
1.64 -G_DEFINE_TYPE(MMythTVPlayer, mmyth_tvplayer, G_TYPE_OBJECT)
1.65 -
1.66 - static gboolean mmyth_tvplayer_create_pipeline(MMythTVPlayer *
1.67 - tvplayer);
1.68 - static void new_pad_cb(GstElement * element, GstPad * pad,
1.69 - gpointer data);
1.70 -
1.71 - static gboolean expose_cb(GtkWidget * widget,
1.72 - GdkEventExpose * event, gpointer user_data);
1.73 -
1.74 - static void
1.75 - mmyth_tvplayer_class_init(MMythTVPlayerClass * klass)
1.76 -{
1.77 - GObjectClass *gobject_class;
1.78 -
1.79 - gobject_class = (GObjectClass *) klass;
1.80 -
1.81 - gobject_class->dispose = mmyth_tvplayer_dispose;
1.82 - gobject_class->finalize = mmyth_tvplayer_finalize;
1.83 -}
1.84 -
1.85 -static void
1.86 -new_pad_cb(GstElement * element, GstPad * pad, gpointer data)
1.87 -{
1.88 - MMythTVPlayer *tvplayer = MMYTH_TVPLAYER(data);
1.89 - GstPadLinkReturn ret;
1.90 - char *s;
1.91 -
1.92 - s = gst_caps_to_string(pad->caps);
1.93 -
1.94 - if (s[0] == 'a') {
1.95 - ret =
1.96 - gst_pad_link(pad,
1.97 - gst_element_get_pad(tvplayer->audioqueue1,
1.98 - "sink"));
1.99 - } else {
1.100 - ret =
1.101 - gst_pad_link(pad,
1.102 - gst_element_get_pad(tvplayer->videoqueue1,
1.103 - "sink"));
1.104 - }
1.105 -
1.106 - g_free(s);
1.107 -}
1.108 -
1.109 -static gboolean
1.110 -expose_cb(GtkWidget * widget, GdkEventExpose * event, gpointer user_data)
1.111 -{
1.112 - MMythTVPlayer *tvplayer = MMYTH_TVPLAYER(user_data);
1.113 -
1.114 - if (tvplayer && tvplayer->videow) {
1.115 - gst_x_overlay_set_xwindow_id(GST_X_OVERLAY
1.116 - (tvplayer->gst_videosink),
1.117 - GDK_WINDOW_XWINDOW(widget->window));
1.118 - return TRUE;
1.119 - }
1.120 -
1.121 - g_warning("MMythTVPlayer expose called before setting video window\n");
1.122 -
1.123 - return FALSE;
1.124 -}
1.125 -
1.126 -static void
1.127 -mmyth_tvplayer_init(MMythTVPlayer * tvplayer)
1.128 -{
1.129 - tvplayer->gst_pipeline = NULL;
1.130 - tvplayer->gst_source = NULL;
1.131 - tvplayer->gst_videodec = NULL;
1.132 - tvplayer->gst_videosink = NULL;
1.133 - tvplayer->gst_videocolortrs = NULL;
1.134 - tvplayer->videoqueue1 = NULL;
1.135 - tvplayer->videoqueue2 = NULL;
1.136 - tvplayer->audioqueue1 = NULL;
1.137 - tvplayer->audioqueue2 = NULL;
1.138 -
1.139 - /*
1.140 - * GTKWidget for rendering the video
1.141 - */
1.142 - tvplayer->videow = NULL;
1.143 - tvplayer->expose_handler = 0;
1.144 -
1.145 - tvplayer->backend_hostname = NULL;
1.146 - tvplayer->backend_port = 0;
1.147 - tvplayer->local_hostname = NULL;
1.148 -
1.149 - tvplayer->recorder = NULL;
1.150 - tvplayer->tvchain = NULL;
1.151 - tvplayer->proginfo = NULL;
1.152 -}
1.153 -
1.154 -static void
1.155 -mmyth_tvplayer_dispose(GObject * object)
1.156 -{
1.157 -
1.158 - G_OBJECT_CLASS(mmyth_tvplayer_parent_class)->dispose(object);
1.159 -}
1.160 -
1.161 -static void
1.162 -mmyth_tvplayer_finalize(GObject * object)
1.163 -{
1.164 - g_signal_handlers_destroy(object);
1.165 -
1.166 - MMythTVPlayer *tvplayer = MMYTH_TVPLAYER(object);
1.167 -
1.168 - g_debug("[%s] Finalizing tvplayer", __FUNCTION__);
1.169 -
1.170 - if (tvplayer->videow != NULL) {
1.171 - if (g_signal_handler_is_connected(tvplayer->videow,
1.172 - tvplayer->expose_handler)) {
1.173 - g_signal_handler_disconnect(tvplayer->videow,
1.174 - tvplayer->expose_handler);
1.175 - }
1.176 - g_object_unref(tvplayer->videow);
1.177 - }
1.178 -
1.179 - if (tvplayer->recorder != NULL)
1.180 - g_object_unref(tvplayer->recorder);
1.181 - if (tvplayer->tvchain != NULL)
1.182 - g_object_unref(tvplayer->tvchain);
1.183 - if (tvplayer->proginfo != NULL)
1.184 - g_object_unref(tvplayer->proginfo);
1.185 -
1.186 - // Release Gstreamer elements
1.187 - if (tvplayer->gst_pipeline != NULL)
1.188 - g_object_unref(tvplayer->gst_pipeline);
1.189 - if (tvplayer->gst_source != NULL)
1.190 - g_object_unref(tvplayer->gst_source);
1.191 - if (tvplayer->gst_videodec != NULL)
1.192 - g_object_unref(tvplayer->gst_videodec);
1.193 - if (tvplayer->gst_videocolortrs != NULL)
1.194 - g_object_unref(tvplayer->gst_videocolortrs);
1.195 - if (tvplayer->gst_videosink != NULL)
1.196 - g_object_unref(tvplayer->gst_videosink);
1.197 - if (tvplayer->videoqueue1 != NULL)
1.198 - g_object_unref(tvplayer->videoqueue1);
1.199 - if (tvplayer->videoqueue2 != NULL)
1.200 - g_object_unref(tvplayer->videoqueue2);
1.201 - if (tvplayer->audioqueue1 != NULL)
1.202 - g_object_unref(tvplayer->audioqueue1);
1.203 - if (tvplayer->audioqueue2 != NULL)
1.204 - g_object_unref(tvplayer->audioqueue2);
1.205 -
1.206 - G_OBJECT_CLASS(mmyth_tvplayer_parent_class)->finalize(object);
1.207 -}
1.208 -
1.209 -/** Creates a new instance of MMythTVPlayer.
1.210 - *
1.211 - * @return a new instance of MMythTVPlayer.
1.212 - */
1.213 -MMythTVPlayer *
1.214 -mmyth_tvplayer_new()
1.215 -{
1.216 - MMythTVPlayer *tvplayer =
1.217 - MMYTH_TVPLAYER(g_object_new(MMYTH_TVPLAYER_TYPE, NULL));
1.218 -
1.219 - return tvplayer;
1.220 -}
1.221 -
1.222 -/** Initializes the tv player.
1.223 - *
1.224 - * @param tvplayer the object instance.
1.225 - * @return gboolean TRUE if the pipeline was created
1.226 - * successfully, FALSE otherwise.
1.227 - */
1.228 -gboolean
1.229 -mmyth_tvplayer_initialize(MMythTVPlayer * tvplayer,
1.230 - GMythBackendInfo * backend_info)
1.231 -{
1.232 - tvplayer->backend_info = backend_info;
1.233 -
1.234 - if (!mmyth_tvplayer_create_pipeline(tvplayer)) {
1.235 - g_warning
1.236 - ("[%s] Error while creating pipeline. TV Player not initialized",
1.237 - __FUNCTION__);
1.238 - return FALSE;
1.239 - } else {
1.240 - g_debug("[%s] GStreamer pipeline created", __FUNCTION__);
1.241 - }
1.242 -
1.243 - return TRUE;
1.244 -}
1.245 -
1.246 -/** Creates the GStreamer pipeline used by the player.
1.247 - *
1.248 - * @param tvplayer the object instance.
1.249 - * @return gboolean TRUE if the pipeline was created
1.250 - * successfully, FALSE otherwise.
1.251 - */
1.252 -static gboolean
1.253 -mmyth_tvplayer_create_pipeline(MMythTVPlayer * tvplayer)
1.254 -{
1.255 - GstElement *pipeline;
1.256 - GstElement *source,
1.257 - *parser;
1.258 - GstElement *videodec,
1.259 - *videosink;
1.260 - GstElement *videocolortrs;
1.261 -#ifndef MAEMO_PLATFORM
1.262 - GstElement *audiodec,
1.263 - *audioconv,
1.264 - *audioqueue2;
1.265 -#endif
1.266 - GstElement *audiosink;
1.267 - GstElement *videoqueue1,
1.268 - *videoqueue2,
1.269 - *audioqueue1;
1.270 -
1.271 - g_debug("MMythTVPlayer: Setting the Gstreamer pipeline\n");
1.272 -
1.273 - pipeline = gst_pipeline_new("video-player");
1.274 - source = gst_element_factory_make("mythtvsrc", "myth-source");
1.275 - parser = gst_element_factory_make("nuvdemux", "nuv-demux");
1.276 -
1.277 - /*
1.278 - * Gstreamer Video elements
1.279 - */
1.280 - videoqueue1 = gst_element_factory_make("queue", "video-queue1");
1.281 - videodec = gst_element_factory_make("ffdec_mpeg4", "video-decoder");
1.282 - videoqueue2 = gst_element_factory_make("queue", "video-queue2");
1.283 - videocolortrs =
1.284 - gst_element_factory_make("ffmpegcolorspace",
1.285 - "image-color-transforms");
1.286 -
1.287 -#ifdef MAEMO_PLATFORM
1.288 - videosink = gst_element_factory_make("sdlvideosink", "image-output");
1.289 -#else
1.290 - videosink = gst_element_factory_make("xvimagesink", "image-output");
1.291 -#endif
1.292 -
1.293 - /*
1.294 - * Gstreamer Audio elements
1.295 - */
1.296 - audioqueue1 = gst_element_factory_make("queue", "audio-queue1");
1.297 -#ifdef MAEMO_PLATFORM
1.298 - audiosink = gst_element_factory_make("dspmp3sink", "audio-output");
1.299 -#else
1.300 - audioqueue2 = gst_element_factory_make("queue", "audio-queue2");
1.301 - audiodec = gst_element_factory_make("mad", "audio-decoder");
1.302 - audioconv =
1.303 - gst_element_factory_make("audioconvert", "audio-converter");
1.304 - audiosink = gst_element_factory_make("alsasink", "audio-output");
1.305 -#endif
1.306 -
1.307 - if (!(pipeline && source && parser && videodec && videosink) ||
1.308 - !(videoqueue1 && videoqueue2 && audioqueue1 && audiosink)) {
1.309 - /*
1.310 - * FIXME: hanlde the error correctly
1.311 - */
1.312 - /*
1.313 - * video_alignment is not being created (below) and is causing
1.314 - * problems to the ui
1.315 - */
1.316 -
1.317 - tvplayer->gst_pipeline = NULL;
1.318 - tvplayer->gst_videodec = NULL;
1.319 - tvplayer->gst_videosink = NULL;
1.320 - tvplayer->gst_videocolortrs = NULL;
1.321 -
1.322 - g_warning("GstElement creation error!\n");
1.323 - return FALSE;
1.324 - }
1.325 -#ifndef MAEMO_PLATFORM
1.326 - if (!(audiodec && audioconv)) {
1.327 - g_warning("GstElement for audio stream creation error!");
1.328 - return FALSE;
1.329 - }
1.330 -#endif
1.331 -
1.332 - tvplayer->gst_pipeline = pipeline;
1.333 - tvplayer->gst_source = source;
1.334 - tvplayer->gst_videodec = videodec;
1.335 - tvplayer->gst_videosink = videosink;
1.336 - tvplayer->gst_videocolortrs = videocolortrs;
1.337 - g_object_ref(tvplayer->gst_pipeline);
1.338 - g_object_ref(tvplayer->gst_source);
1.339 - g_object_ref(tvplayer->gst_videodec);
1.340 - g_object_ref(tvplayer->gst_videosink);
1.341 - g_object_ref(tvplayer->gst_videocolortrs);
1.342 -
1.343 - tvplayer->videoqueue1 = videoqueue1;
1.344 - tvplayer->videoqueue2 = videoqueue2;
1.345 - tvplayer->audioqueue1 = audioqueue1;
1.346 - g_object_ref(tvplayer->videoqueue1);
1.347 - g_object_ref(tvplayer->videoqueue2);
1.348 - g_object_ref(tvplayer->audioqueue1);
1.349 -
1.350 -#ifndef MAEMO_PLATFORM
1.351 - tvplayer->audioqueue2 = audioqueue2;
1.352 - g_object_ref(tvplayer->audioqueue2);
1.353 -#endif
1.354 -
1.355 - // g_object_set (G_OBJECT (videosink), "sync", TRUE, NULL);
1.356 - g_object_set(G_OBJECT(audiosink), "sync", FALSE, NULL);
1.357 -
1.358 - gst_bus_add_watch(gst_pipeline_get_bus
1.359 - (GST_PIPELINE(tvplayer->gst_pipeline)), bus_call,
1.360 - tvplayer);
1.361 -
1.362 - gst_bin_add_many(GST_BIN(pipeline), source, parser, videoqueue1,
1.363 - videodec, videoqueue2, videocolortrs, videosink,
1.364 - NULL);
1.365 -
1.366 -#ifndef MAEMO_PLATFORM
1.367 - gst_bin_add_many(GST_BIN(pipeline), audioqueue1, audiodec, audioconv,
1.368 - audioqueue2, audiosink, NULL);
1.369 -#else
1.370 - gst_bin_add_many(GST_BIN(pipeline), audioqueue1, audiosink, NULL);
1.371 -#endif
1.372 -
1.373 - {
1.374 - // GstCaps *rtpcaps = gst_caps_new_simple ("application/x-rtp",
1.375 - // NULL);
1.376 - // gst_element_link_filtered(source, parser, rtpcaps);
1.377 - }
1.378 -
1.379 - gst_element_link(source, parser);
1.380 - gst_element_link_many(videoqueue1, videodec, videoqueue2,
1.381 - videocolortrs, videosink, NULL);
1.382 -
1.383 -#ifndef MAEMO_PLATFORM
1.384 - gst_element_link_many(videosink, audioqueue1, audiodec, audioconv,
1.385 - audioqueue2, audiosink, NULL);
1.386 -#else
1.387 - gst_element_link_many(videosink, audioqueue1, audiosink, NULL);
1.388 -#endif
1.389 -
1.390 - g_signal_connect(parser, "pad-added", G_CALLBACK(new_pad_cb),
1.391 - tvplayer);
1.392 -
1.393 - return TRUE;
1.394 -}
1.395 -
1.396 -/** Configures the backend and the tv player
1.397 - * for playing the recorded content A/V.
1.398 - *
1.399 - * FIXME: Change filename to program info or other structure about the recorded
1.400 - *
1.401 - * @param tvplayer the object instance.
1.402 - * @param filename the file uri of the recorded content to be played.
1.403 - * @return TRUE if successfull, FALSE if any error happens.
1.404 - */
1.405 -gboolean
1.406 -mmyth_tvplayer_record_setup(MMythTVPlayer * tvplayer,
1.407 - const gchar * filename)
1.408 -{
1.409 - // FIXME: we should receive the uri instead of filename
1.410 - const gchar *hostname =
1.411 - gmyth_backend_info_get_hostname(tvplayer->backend_info);
1.412 - const gint port =
1.413 - gmyth_backend_info_get_port(tvplayer->backend_info);
1.414 -
1.415 - GString *fullpath = g_string_new("myth://");
1.416 - g_string_append_printf(fullpath, "%s:%d/%s", hostname, port, filename);
1.417 -
1.418 - tvplayer->is_livetv = FALSE;
1.419 -
1.420 - g_debug("[%s] Setting record uri to gstreamer pipeline to %s",
1.421 - __FUNCTION__, fullpath->str);
1.422 -
1.423 - g_object_set(G_OBJECT(tvplayer->gst_source), "location",
1.424 - fullpath->str, NULL);
1.425 -
1.426 - return TRUE;
1.427 -}
1.428 -
1.429 -/** Configures the backend and the tv player
1.430 - * for playing the live tv.
1.431 - *
1.432 - * @param tvplayer the object instance.
1.433 - * @return TRUE if successfull, FALSE if any error happens.
1.434 - */
1.435 -gboolean
1.436 -mmyth_tvplayer_livetv_setup(MMythTVPlayer * tvplayer)
1.437 -{
1.438 - gboolean res = TRUE;
1.439 -
1.440 - tvplayer->livetv = gmyth_livetv_new();
1.441 -
1.442 - if (!gmyth_livetv_setup(tvplayer->livetv, tvplayer->backend_info))
1.443 - goto error;
1.444 -
1.445 - return res;
1.446 -
1.447 - error:
1.448 - res = FALSE;
1.449 - if (tvplayer->livetv != NULL) {
1.450 - g_object_unref(tvplayer->livetv);
1.451 - }
1.452 -
1.453 - if (tvplayer->local_hostname != NULL) {
1.454 - g_string_free(tvplayer->local_hostname, TRUE);
1.455 - }
1.456 -
1.457 - if (tvplayer->recorder != NULL) {
1.458 - g_object_unref(tvplayer->recorder);
1.459 - tvplayer->recorder = NULL;
1.460 - }
1.461 -
1.462 - if (tvplayer->tvchain != NULL) {
1.463 - g_object_unref(tvplayer->tvchain);
1.464 - tvplayer->tvchain = NULL;
1.465 - }
1.466 -
1.467 - if (tvplayer->proginfo != NULL) {
1.468 - g_object_unref(tvplayer->proginfo);
1.469 - tvplayer->proginfo = NULL;
1.470 - }
1.471 -
1.472 - return res;
1.473 -
1.474 -}
1.475 -
1.476 -/** Sets the GTK video widget for the tv player.
1.477 - *
1.478 - * @param tvplayer the object instance.
1.479 - * @param videow the GTK video window.
1.480 - * @return TRUE if successfull, FALSE if any error happens.
1.481 - */
1.482 -gboolean
1.483 -mmyth_tvplayer_set_widget(MMythTVPlayer * tvplayer, GtkWidget * videow)
1.484 -{
1.485 - tvplayer->videow = videow;
1.486 - g_object_ref(videow);
1.487 -
1.488 - g_debug("[%s] Setting widget for tv player render", __FUNCTION__);
1.489 -
1.490 - tvplayer->expose_handler =
1.491 - g_signal_connect(tvplayer->videow, "expose-event",
1.492 - G_CALLBACK(expose_cb), tvplayer);
1.493 -
1.494 - // g_signal_connect(miptv_ui->videow, "size_request",
1.495 - // G_CALLBACK(cb_preferred_video_size), miptv_ui);
1.496 -
1.497 - return TRUE;
1.498 -}
1.499 -
1.500 -static gboolean
1.501 -bus_call(GstBus * bus, GstMessage * msg, gpointer data)
1.502 -{
1.503 - // MMythTVPlayer *tvplayer = MMYTH_TVPLAYER ( data );
1.504 - // GMainLoop *loop = tvplayer->loop;
1.505 -
1.506 - switch (GST_MESSAGE_TYPE(msg)) {
1.507 - case GST_MESSAGE_EOS:
1.508 - printf("End of stream\n");
1.509 - // g_idle_add ((GSourceFunc) idle_eos, data);
1.510 - gst_element_set_state(GST_ELEMENT(GST_MESSAGE_SRC(msg)),
1.511 - GST_STATE_NULL);
1.512 - gst_element_set_locked_state(GST_ELEMENT(GST_MESSAGE_SRC(msg)),
1.513 - TRUE);
1.514 - break;
1.515 - case GST_MESSAGE_ERROR:
1.516 - {
1.517 - gchar *debug;
1.518 - GError *err;
1.519 -
1.520 - gst_message_parse_error(msg, &err, &debug);
1.521 - g_free(debug);
1.522 -
1.523 - printf("Error: %s\n", err->message);
1.524 - g_error_free(err);
1.525 -
1.526 - // g_main_loop_quit (loop);
1.527 - }
1.528 - break;
1.529 - default:
1.530 - printf(gst_message_type_get_name(GST_MESSAGE_TYPE(msg)));
1.531 - printf("\n");
1.532 - break;
1.533 - }
1.534 -
1.535 - return TRUE;
1.536 -}
1.537 -
1.538 -
1.539 -#if 0
1.540 -static gboolean
1.541 -idle_state(gpointer data)
1.542 -{
1.543 - GstPlayerWindowStateChange *st = data;
1.544 -
1.545 - if (st->old_state == GST_STATE_PLAYING) {
1.546 - if (st->miptv_ui->idle_id != 0) {
1.547 - g_source_remove(st->miptv_ui->idle_id);
1.548 - st->miptv_ui->idle_id = 0;
1.549 - }
1.550 - } else if (st->new_state == GST_STATE_PLAYING) {
1.551 - if (st->miptv_ui->idle_id != 0)
1.552 - g_source_remove(st->miptv_ui->idle_id);
1.553 -
1.554 - st->miptv_ui->idle_id = g_idle_add(cb_iterate, st->miptv_ui);
1.555 - }
1.556 -
1.557 - /*
1.558 - * new movie loaded?
1.559 - */
1.560 - if (st->old_state == GST_STATE_READY
1.561 - && st->new_state > GST_STATE_READY) {
1.562 -
1.563 - /*
1.564 - * gboolean have_video = FALSE;
1.565 - */
1.566 -
1.567 - gtk_widget_show(st->miptv_ui->videow);
1.568 -
1.569 - gtk_window_resize(GTK_WINDOW(st->miptv_ui->main_window), 1, 1);
1.570 -
1.571 - }
1.572 -
1.573 - /*
1.574 - * discarded movie?
1.575 - */
1.576 - if (st->old_state > GST_STATE_READY
1.577 - && st->new_state == GST_STATE_READY) {
1.578 -
1.579 - if (st->miptv_ui->tagcache) {
1.580 - gst_tag_list_free(st->miptv_ui->tagcache);
1.581 - st->miptv_ui->tagcache = NULL;
1.582 - }
1.583 - }
1.584 -
1.585 - gst_object_unref(GST_OBJECT(st->play));
1.586 - // g_object_unref (G_OBJECT (st->win));
1.587 - g_free(st);
1.588 -
1.589 - /*
1.590 - * once
1.591 - */
1.592 - return FALSE;
1.593 -}
1.594 -
1.595 -#endif
1.596 -
1.597 -/** Stops playing the current A/V.
1.598 - *
1.599 - * FIXME: How to proceed differently between livetv
1.600 - * and recorded content?
1.601 - *
1.602 - * @param tvplayer the object instance.
1.603 - * @return void
1.604 - */
1.605 -void
1.606 -mmyth_tvplayer_stop_playing(MMythTVPlayer * tvplayer)
1.607 -{
1.608 - g_debug("[%s] Setting gstreamer pipeline state to NULL", __FUNCTION__);
1.609 -
1.610 - gst_element_set_state(tvplayer->gst_pipeline, GST_STATE_NULL);
1.611 -
1.612 - if (tvplayer->is_livetv) {
1.613 - if (!gmyth_recorder_stop_livetv(tvplayer->recorder)) {
1.614 - g_warning("[%s] Error while stoping remote encoder",
1.615 - __FUNCTION__);
1.616 - }
1.617 - }
1.618 -}
1.619 -
1.620 -/** Queries if the tvplayer is active playing A/V content.
1.621 - *
1.622 - * @param tvplayer the object instance.
1.623 - * @return TRUE if the tvplayer is active, FALSE otherwise.
1.624 - */
1.625 -gboolean
1.626 -mmyth_tvplayer_is_playing(MMythTVPlayer * tvplayer)
1.627 -{
1.628 - return (GST_STATE(tvplayer->gst_pipeline) == GST_STATE_PLAYING);
1.629 -}
1.630 -
1.631 -/** Static function that sets the tvplayer state to PLAYING.
1.632 - *
1.633 - * @param tvplayer the object instance.
1.634 - * @return TRUE if the tvplayer is active, FALSE otherwise.
1.635 - */
1.636 -static gboolean
1.637 -idle_play(gpointer data)
1.638 -{
1.639 - MMythTVPlayer *tvplayer = MMYTH_TVPLAYER(data);
1.640 -
1.641 - g_debug("MMythTVPlayer: Setting pipeline state to PLAYING\n");
1.642 -
1.643 - gst_element_set_state(tvplayer->gst_pipeline, GST_STATE_PLAYING);
1.644 -
1.645 - return FALSE;
1.646 -}
1.647 -
1.648 -/** Start playing A/V with the tvplayer attributes.
1.649 - *
1.650 - * @param tvplayer the object instance.
1.651 - */
1.652 -void
1.653 -mmyth_tvplayer_start_playing(MMythTVPlayer * tvplayer)
1.654 -{
1.655 -
1.656 - // FIXME: Move this to livetv_setup??
1.657 - if (tvplayer->is_livetv) {
1.658 -
1.659 -#if 0
1.660 - if (!tvplayer || !(tvplayer->proginfo)
1.661 - || !(tvplayer->local_hostname)
1.662 - || !(tvplayer->gst_source)) {
1.663 - g_warning("GMythtvPlayer not ready to start playing\n");
1.664 - }
1.665 -
1.666 - if (!(tvplayer->proginfo->pathname)) {
1.667 - g_warning
1.668 - ("[%s] Playback url is null, could not play the myth content",
1.669 - __FUNCTION__);
1.670 - return;
1.671 - }
1.672 -
1.673 - g_debug("MMythTVPlayer: Start playing %s",
1.674 - tvplayer->proginfo->pathname->str);
1.675 -#endif
1.676 - g_object_set(G_OBJECT(tvplayer->gst_source), "mythtv-live",
1.677 - TRUE, NULL);
1.678 -#if 0
1.679 - if (tvplayer->tvchain != NULL) {
1.680 - GString *str_chainid =
1.681 - gmyth_tvchain_get_id(tvplayer->tvchain);
1.682 - g_print("[%s]\tCHAIN ID: %s\n", __FUNCTION__,
1.683 - str_chainid->str);
1.684 -
1.685 - g_object_set(G_OBJECT(tvplayer->gst_source),
1.686 - "mythtv-live-chainid", g_strdup(str_chainid->str),
1.687 - NULL);
1.688 - if (str_chainid != NULL)
1.689 - g_string_free(str_chainid, FALSE);
1.690 - }
1.691 -
1.692 - if (tvplayer->recorder != NULL)
1.693 - g_object_set(G_OBJECT(tvplayer->gst_source), "mythtv-live-id",
1.694 - tvplayer->recorder->recorder_num, NULL);
1.695 - g_debug("[%s] Setting location to %s", __FUNCTION__,
1.696 - tvplayer->proginfo->pathname->str);
1.697 -
1.698 - /*
1.699 - * Sets the gstreamer properties acording to the service access
1.700 - * address
1.701 - */
1.702 - g_object_set(G_OBJECT(tvplayer->gst_source), "location",
1.703 - tvplayer->proginfo->pathname->str, NULL);
1.704 -#endif
1.705 - }
1.706 -
1.707 - g_object_set(G_OBJECT(tvplayer->gst_source), "mythtv-version",
1.708 - MYTHTV_VERSION_DEFAULT, NULL);
1.709 -
1.710 - g_object_set(G_OBJECT(tvplayer->gst_source), "mythtv-debug",
1.711 - TRUE, NULL);
1.712 -
1.713 - g_idle_add(idle_play, tvplayer);
1.714 -
1.715 -}