gst-gmyth/playbinmaemo/gstplaybinmaemo.c
author leo_sobral
Thu Aug 16 15:24:01 2007 +0100 (2007-08-16)
branchtrunk
changeset 808 215c45290ce3
parent 805 a87c760e0dfa
child 811 69aba3b6b7b3
permissions -rw-r--r--
[svn r814] Added x error handling to playbin maemo
renatofilho@787
     1
/* GStreamer
renatofilho@797
     2
 * Copyright (C) <2007> Renato Araujo Oliveira Filho <renato.filho@indt.org.br>
renatofilho@787
     3
 *
renatofilho@787
     4
 * This library is free software; you can redistribute it and/or
renatofilho@787
     5
 * modify it under the terms of the GNU Library General Public
renatofilho@787
     6
 * License as published by the Free Software Foundation; either
renatofilho@787
     7
 * version 2 of the License, or (at your option) any later version.
renatofilho@787
     8
 *
renatofilho@787
     9
 * This library is distributed in the hope that it will be useful,
renatofilho@787
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
renatofilho@787
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
renatofilho@787
    12
 * Library General Public License for more details.
renatofilho@787
    13
 *
renatofilho@787
    14
 * You should have received a copy of the GNU Library General Public
renatofilho@787
    15
 * License along with this library; if not, write to the
renatofilho@787
    16
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
renatofilho@787
    17
 * Boston, MA 02111-1307, USA.
renatofilho@787
    18
 */
renatofilho@787
    19
renatofilho@787
    20
#ifdef HAVE_CONFIG_H
renatofilho@787
    21
#include "config.h"
renatofilho@787
    22
#endif
renatofilho@787
    23
renatofilho@787
    24
#include <glib/gi18n.h>
renatofilho@787
    25
#include <string.h>
renatofilho@787
    26
#include <gst/gst.h>
renatofilho@787
    27
#include <gst/gsterror.h>
renatofilho@787
    28
#include <gst/gstplugin.h>
renatofilho@787
    29
#include <gst/interfaces/xoverlay.h>
renatofilho@787
    30
#include <X11/Xlib.h>
renatofilho@787
    31
//#include <gst/pbutils/pbutils.h>
renatofilho@787
    32
#include "gstplaybinmaemo.h"
renatofilho@787
    33
renatofilho@787
    34
renatofilho@787
    35
GST_DEBUG_CATEGORY_STATIC (gst_play_bin_maemo_debug);
renatofilho@787
    36
#define GST_CAT_DEFAULT gst_play_bin_maemo_debug
renatofilho@787
    37
renatofilho@787
    38
#define DEFAULT_VOLUME               10
renatofilho@787
    39
#define DEFAULT_XID                 -1
renatofilho@787
    40
renatofilho@787
    41
/* props */
renatofilho@787
    42
enum
renatofilho@787
    43
{
renatofilho@787
    44
  ARG_0,
renatofilho@787
    45
  ARG_URI,
renatofilho@787
    46
  ARG_QUEUE_SIZE,
renatofilho@787
    47
  ARG_QUEUE_MIN_THRESHOLD,
renatofilho@787
    48
  ARG_SOURCE,
renatofilho@787
    49
  ARG_VOLUME,
renatofilho@788
    50
  ARG_PARSE_METADATA,
renatofilho@787
    51
  ARG_XID
renatofilho@787
    52
};
renatofilho@787
    53
renatofilho@787
    54
static const GstElementDetails gst_play_bin_maemo_details =
leo_sobral@796
    55
        GST_ELEMENT_DETAILS("playbinmaemo",
renatofilho@787
    56
                            "Generic/Bin/Player",
renatofilho@787
    57
                            "Autoplug and play media from an uri used on maemo plataform",
renatofilho@787
    58
                            "Renato Araujo Oliveira Filho <renato.filho@indt.org.br>");
renatofilho@787
    59
renatofilho@787
    60
static void     gst_play_bin_maemo_dispose          (GObject * object);
renatofilho@787
    61
static void     gst_play_bin_maemo_finalize         (GObject * object);
renatofilho@787
    62
static void     gst_play_bin_maemo_set_property     (GObject * object, guint prop_id,
renatofilho@787
    63
                                                    const GValue * value, GParamSpec * spec);
renatofilho@787
    64
static void     gst_play_bin_maemo_get_property     (GObject * object, guint prop_id,
renatofilho@787
    65
                                                    GValue * value, GParamSpec * spec);
renatofilho@787
    66
static GstStateChangeReturn
renatofilho@787
    67
                gst_play_bin_maemo_change_state     (GstElement *element,
renatofilho@787
    68
                                                    GstStateChange transition);
renatofilho@787
    69
static gboolean factory_filter_sinks                (GstPluginFeature *feature,
renatofilho@787
    70
                                                    GstPlayBinMaemo *pbm);
renatofilho@787
    71
static gint     compare_ranks                       (GstPluginFeature * f1,
renatofilho@787
    72
                                                    GstPluginFeature * f2);
renatofilho@787
    73
static GList    *find_compatibles                   (GstPlayBinMaemo *pbm,
renatofilho@787
    74
                                                     const GstCaps *caps);
renatofilho@787
    75
static GstPad   *find_sink_pad                      (GstElement * element);
renatofilho@787
    76
static void     update_volume                       (GstPlayBinMaemo *pbm);
renatofilho@787
    77
static void     update_xid                          (GstPlayBinMaemo *pbm);
renatofilho@787
    78
static void     new_decoded_pad_cb                  (GstElement *object,
renatofilho@787
    79
                                                     GstPad* pad,
renatofilho@787
    80
                                                     gboolean arg,
renatofilho@787
    81
                                                     gpointer user_data);
renatofilho@787
    82
static void     unknown_type_cb                     (GstElement *object,
renatofilho@787
    83
                                                     GstPad *pad,
renatofilho@787
    84
                                                     GstCaps *casp,
renatofilho@787
    85
                                                     gpointer user_data);
renatofilho@787
    86
static gboolean autoplug_continue_cb                (GstElement* object,
renatofilho@787
    87
                                                     GstCaps* caps,
renatofilho@787
    88
                                                     gpointer user_data);
renatofilho@792
    89
static gboolean add_element                         (GstPlayBinMaemo *pbm,
renatofilho@792
    90
                                                     GstElement *child);
renatofilho@792
    91
static void     clear_elements                      (GstPlayBinMaemo *pbm);
leo_sobral@808
    92
static int      x_error_handler                     (Display *display,
leo_sobral@808
    93
                                                     XErrorEvent *event);
renatofilho@787
    94
renatofilho@787
    95
GST_BOILERPLATE(GstPlayBinMaemo, gst_play_bin_maemo, GstPipeline, GST_TYPE_PIPELINE)
renatofilho@787
    96
renatofilho@787
    97
renatofilho@787
    98
static void
renatofilho@787
    99
gst_play_bin_maemo_base_init (gpointer klass)
renatofilho@787
   100
{
renatofilho@787
   101
    GstElementClass *element_class = GST_ELEMENT_CLASS(klass);
renatofilho@787
   102
renatofilho@787
   103
    gst_element_class_set_details (element_class, &gst_play_bin_maemo_details);
renatofilho@787
   104
}
renatofilho@787
   105
renatofilho@787
   106
static void
renatofilho@787
   107
gst_play_bin_maemo_class_init (GstPlayBinMaemoClass * klass)
renatofilho@787
   108
{
renatofilho@787
   109
  GObjectClass *gobject_klass;
renatofilho@787
   110
  GstElementClass *gstelement_klass;
renatofilho@787
   111
  GstBinClass *gstbin_klass;
renatofilho@787
   112
renatofilho@787
   113
  gobject_klass = (GObjectClass *) klass;
renatofilho@787
   114
  gstelement_klass = (GstElementClass *) klass;
renatofilho@787
   115
  gstbin_klass = (GstBinClass *) klass;
renatofilho@787
   116
renatofilho@787
   117
  parent_class = g_type_class_peek_parent (klass);
renatofilho@787
   118
renatofilho@787
   119
  gobject_klass->set_property = gst_play_bin_maemo_set_property;
renatofilho@787
   120
  gobject_klass->get_property = gst_play_bin_maemo_get_property;
renatofilho@787
   121
renatofilho@787
   122
  g_object_class_install_property (gobject_klass, ARG_URI,
renatofilho@787
   123
      g_param_spec_string ("uri", "URI", "URI of the media to play",
renatofilho@787
   124
          NULL, G_PARAM_READWRITE));
renatofilho@787
   125
renatofilho@787
   126
  g_object_class_install_property (gobject_klass, ARG_VOLUME,
renatofilho@793
   127
      g_param_spec_double ("volume", "Audio volume", "volume",
renatofilho@793
   128
                            0.0, 10.0, (gdouble) DEFAULT_VOLUME, G_PARAM_READWRITE));
renatofilho@787
   129
renatofilho@787
   130
  g_object_class_install_property (gobject_klass, ARG_XID,
renatofilho@787
   131
      g_param_spec_long ("xid", "xid", "X windown ID",
renatofilho@787
   132
                         -1, G_MAXLONG, DEFAULT_XID, G_PARAM_READWRITE));
renatofilho@787
   133
renatofilho@787
   134
  g_object_class_install_property (gobject_klass, ARG_SOURCE,
renatofilho@787
   135
      g_param_spec_object ("source", "Source", "Source element",
renatofilho@787
   136
          GST_TYPE_ELEMENT, G_PARAM_READABLE));
renatofilho@787
   137
renatofilho@788
   138
  g_object_class_install_property (gobject_klass, ARG_PARSE_METADATA,
renatofilho@788
   139
      g_param_spec_boolean ("parse-metadata", "Parse Metadata", "Parse metadata info",
renatofilho@788
   140
          TRUE, G_PARAM_READWRITE));
renatofilho@788
   141
renatofilho@788
   142
renatofilho@787
   143
  GST_DEBUG_CATEGORY_INIT (gst_play_bin_maemo_debug, "playbinmaemo", 0,
renatofilho@787
   144
      "playbinmaemo");
renatofilho@787
   145
renatofilho@787
   146
  gobject_klass->dispose = GST_DEBUG_FUNCPTR (gst_play_bin_maemo_dispose);
renatofilho@787
   147
  gobject_klass->finalize = GST_DEBUG_FUNCPTR (gst_play_bin_maemo_finalize);
renatofilho@787
   148
renatofilho@787
   149
  gstelement_klass->change_state =
renatofilho@787
   150
      GST_DEBUG_FUNCPTR (gst_play_bin_maemo_change_state);
renatofilho@787
   151
}
renatofilho@787
   152
renatofilho@787
   153
static void
renatofilho@787
   154
gst_play_bin_maemo_init (GstPlayBinMaemo * play_bin_maemo, GstPlayBinMaemoClass *class)
renatofilho@787
   155
{
renatofilho@787
   156
  GList *factories;
renatofilho@787
   157
renatofilho@787
   158
  play_bin_maemo->uri = NULL;
renatofilho@787
   159
  play_bin_maemo->source = NULL;
renatofilho@787
   160
renatofilho@787
   161
  play_bin_maemo->volume = DEFAULT_VOLUME * 65535 / 10;
renatofilho@787
   162
  play_bin_maemo->xid = DEFAULT_XID;
renatofilho@788
   163
  play_bin_maemo->parse_metadata = TRUE;
renatofilho@787
   164
renatofilho@787
   165
  factories = gst_default_registry_feature_filter ((GstPluginFeatureFilter) factory_filter_sinks,
renatofilho@787
   166
                                                   FALSE, play_bin_maemo);
renatofilho@787
   167
renatofilho@787
   168
  play_bin_maemo->factories = g_list_sort (factories, (GCompareFunc) compare_ranks);
renatofilho@787
   169
}
renatofilho@787
   170
renatofilho@787
   171
static void
renatofilho@787
   172
gst_play_bin_maemo_dispose (GObject * object)
renatofilho@787
   173
{
renatofilho@787
   174
  GstPlayBinMaemo *play_bin_maemo;
renatofilho@787
   175
renatofilho@787
   176
  play_bin_maemo = GST_PLAY_BIN_MAEMO (object);
renatofilho@787
   177
  g_free (play_bin_maemo->uri);
renatofilho@787
   178
  play_bin_maemo->uri = NULL;
renatofilho@787
   179
renatofilho@787
   180
  G_OBJECT_CLASS (parent_class)->dispose (object);
renatofilho@787
   181
}
renatofilho@787
   182
renatofilho@787
   183
static void
renatofilho@787
   184
gst_play_bin_maemo_finalize (GObject * object)
renatofilho@787
   185
{
renatofilho@792
   186
  clear_elements (GST_PLAY_BIN_MAEMO (object));
renatofilho@787
   187
  G_OBJECT_CLASS (parent_class)->finalize (object);
renatofilho@787
   188
}
renatofilho@787
   189
renatofilho@787
   190
static gboolean
renatofilho@787
   191
array_has_value (const gchar * values[], const gchar * value)
renatofilho@787
   192
{
renatofilho@787
   193
  gint i;
renatofilho@787
   194
renatofilho@787
   195
  for (i = 0; values[i]; i++) {
renatofilho@787
   196
    if (g_str_has_prefix (value, values[i]))
renatofilho@787
   197
      return TRUE;
renatofilho@787
   198
  }
renatofilho@787
   199
  return FALSE;
renatofilho@787
   200
}
renatofilho@787
   201
renatofilho@787
   202
/* list of URIs that we consider to be streams and that need buffering.
renatofilho@787
   203
 * We have no mechanism yet to figure this out with a query. */
renatofilho@787
   204
static const gchar *stream_uris[] = { "http://", "mms://", "mmsh://",
renatofilho@787
   205
  "mmsu://", "mmst://", NULL
renatofilho@787
   206
};
renatofilho@787
   207
renatofilho@787
   208
/* blacklisted URIs, we know they will always fail. */
renatofilho@787
   209
static const gchar *blacklisted_uris[] = { NULL };
renatofilho@787
   210
renatofilho@787
   211
/* mime types that we don't consider to be media types */
renatofilho@793
   212
/*
renatofilho@787
   213
static const gchar *no_media_mimes[] = {
renatofilho@787
   214
  "application/x-executable", "application/x-bzip", "application/x-gzip",
renatofilho@787
   215
  "application/zip", "application/x-compress", NULL
renatofilho@787
   216
};
renatofilho@793
   217
*/
renatofilho@787
   218
renatofilho@787
   219
/* mime types we consider raw media */
renatofilho@787
   220
static const gchar *raw_mimes[] = {
renatofilho@787
   221
  "audio/x-raw", "video/x-raw", NULL
renatofilho@787
   222
};
renatofilho@787
   223
renatofilho@787
   224
#define IS_STREAM_URI(uri)          (array_has_value (stream_uris, uri))
renatofilho@787
   225
#define IS_BLACKLISTED_URI(uri)     (array_has_value (blacklisted_uris, uri))
renatofilho@787
   226
#define IS_NO_MEDIA_MIME(mime)      (array_has_value (no_media_mimes, mime))
renatofilho@787
   227
#define IS_RAW_MIME(mime)           (array_has_value (raw_mimes, mime))
renatofilho@787
   228
renatofilho@787
   229
/*
renatofilho@787
   230
 * Generate and configure a source element.
renatofilho@787
   231
 */
renatofilho@787
   232
static GstElement *
renatofilho@787
   233
gen_source_element (GstPlayBinMaemo * play_bin_maemo)
renatofilho@787
   234
{
renatofilho@787
   235
  GstElement *source;
renatofilho@787
   236
renatofilho@787
   237
  if (!play_bin_maemo->uri)
renatofilho@787
   238
    goto no_uri;
renatofilho@787
   239
renatofilho@787
   240
  if (!gst_uri_is_valid (play_bin_maemo->uri))
renatofilho@787
   241
    goto invalid_uri;
renatofilho@787
   242
renatofilho@787
   243
  if (IS_BLACKLISTED_URI (play_bin_maemo->uri))
renatofilho@787
   244
    goto uri_blacklisted;
renatofilho@787
   245
renatofilho@792
   246
  source = gst_element_make_from_uri (GST_URI_SRC, play_bin_maemo->uri, "source");
renatofilho@787
   247
  if (!source)
renatofilho@787
   248
    goto no_source;
renatofilho@787
   249
renatofilho@787
   250
  play_bin_maemo->is_stream = IS_STREAM_URI (play_bin_maemo->uri);
renatofilho@787
   251
renatofilho@787
   252
  /* make HTTP sources send extra headers so we get icecast
renatofilho@787
   253
   * metadata in case the stream is an icecast stream */
renatofilho@787
   254
  if (!strncmp (play_bin_maemo->uri, "http://", 7) &&
renatofilho@787
   255
      g_object_class_find_property (G_OBJECT_GET_CLASS (source),
renatofilho@787
   256
          "iradio-mode")) {
renatofilho@787
   257
    g_object_set (source, "iradio-mode", TRUE, NULL);
renatofilho@787
   258
  }
renatofilho@787
   259
  return source;
renatofilho@787
   260
renatofilho@787
   261
  /* ERRORS */
renatofilho@787
   262
no_uri:
renatofilho@787
   263
  {
renatofilho@787
   264
    GST_ELEMENT_ERROR (play_bin_maemo, RESOURCE, NOT_FOUND,
renatofilho@787
   265
        (_("No URI specified to play from.")), (NULL));
renatofilho@787
   266
    return NULL;
renatofilho@787
   267
  }
renatofilho@787
   268
invalid_uri:
renatofilho@787
   269
  {
renatofilho@787
   270
    GST_ELEMENT_ERROR (play_bin_maemo, RESOURCE, NOT_FOUND,
renatofilho@787
   271
        (_("Invalid URI \"%s\"."), play_bin_maemo->uri), (NULL));
renatofilho@787
   272
    return NULL;
renatofilho@787
   273
  }
renatofilho@787
   274
uri_blacklisted:
renatofilho@787
   275
  {
renatofilho@787
   276
    GST_ELEMENT_ERROR (play_bin_maemo, RESOURCE, FAILED,
renatofilho@787
   277
        (_("RTSP streams cannot be played yet.")), (NULL));
renatofilho@787
   278
    return NULL;
renatofilho@787
   279
  }
renatofilho@787
   280
no_source:
renatofilho@787
   281
  {
renatofilho@787
   282
    gchar *prot = gst_uri_get_protocol (play_bin_maemo->uri);
renatofilho@787
   283
renatofilho@787
   284
    /* whoops, could not create the source element, dig a little deeper to
renatofilho@787
   285
     * figure out what might be wrong. */
renatofilho@787
   286
    if (prot) {
renatofilho@793
   287
       /*
renatofilho@787
   288
      gchar *desc;
renatofilho@787
   289
renatofilho@787
   290
      gst_element_post_message (GST_ELEMENT (play_bin_maemo),
renatofilho@787
   291
          gst_missing_uri_source_message_new (GST_ELEMENT (play_bin_maemo),
renatofilho@787
   292
              prot));
renatofilho@787
   293
renatofilho@787
   294
      desc = gst_pb_utils_get_source_description (prot);
renatofilho@787
   295
      GST_ELEMENT_ERROR (play_bin_maemo, CORE, MISSING_PLUGIN,
renatofilho@787
   296
          (_("A %s plugin is required to play this stream, but not installed."),
renatofilho@787
   297
              desc), ("No URI handler for %s", prot));
renatofilho@787
   298
      g_free (desc);
renatofilho@793
   299
      */
renatofilho@787
   300
      g_free (prot);
renatofilho@787
   301
    } else
renatofilho@787
   302
      goto invalid_uri;
renatofilho@787
   303
renatofilho@787
   304
    return NULL;
renatofilho@787
   305
  }
renatofilho@787
   306
}
renatofilho@787
   307
renatofilho@787
   308
static void
renatofilho@787
   309
prepare_elements (GstPlayBinMaemo *pbm)
renatofilho@787
   310
{
leo_sobral@805
   311
  GstElement *decoder;
leo_sobral@805
   312
  GstElement *queue;
renatofilho@787
   313
leo_sobral@805
   314
  decoder = gst_element_factory_make ("decodebin2", "decode");
leo_sobral@805
   315
  add_element (pbm, decoder);
leo_sobral@805
   316
  g_signal_connect (G_OBJECT (decoder),
leo_sobral@805
   317
                    "autoplug-continue",
leo_sobral@805
   318
                    G_CALLBACK (autoplug_continue_cb),
leo_sobral@805
   319
                    pbm);
renatofilho@787
   320
leo_sobral@805
   321
  g_signal_connect (G_OBJECT (decoder),
leo_sobral@805
   322
                    "unknown-type",
leo_sobral@805
   323
                    G_CALLBACK (unknown_type_cb),
leo_sobral@805
   324
                    pbm);
renatofilho@792
   325
leo_sobral@805
   326
  g_signal_connect (G_OBJECT (decoder),
leo_sobral@805
   327
                    "new-decoded-pad",
leo_sobral@805
   328
                    G_CALLBACK (new_decoded_pad_cb),
leo_sobral@805
   329
                    pbm);
renatofilho@792
   330
leo_sobral@805
   331
  queue = gst_element_factory_make ("queue", NULL);
leo_sobral@805
   332
  add_element (pbm, queue);
renatofilho@792
   333
leo_sobral@805
   334
  if (gst_element_link_many (pbm->source, queue, decoder, NULL) == FALSE) {
leo_sobral@805
   335
    g_warning ("FAIL TO LINK SRC WITH DECODEBIN2");
leo_sobral@805
   336
  }
renatofilho@787
   337
}
renatofilho@787
   338
renatofilho@787
   339
static gboolean
renatofilho@787
   340
setup_source (GstPlayBinMaemo *pbm)
renatofilho@787
   341
{
leo_sobral@805
   342
  if (!pbm->need_rebuild)
leo_sobral@805
   343
    return TRUE;
renatofilho@787
   344
leo_sobral@805
   345
  clear_elements (pbm);
renatofilho@792
   346
leo_sobral@805
   347
  GST_DEBUG_OBJECT (pbm, "setup source");
renatofilho@787
   348
leo_sobral@805
   349
  pbm->has_metadata = FALSE;
renatofilho@788
   350
leo_sobral@805
   351
  /* create and configure an element that can handle the uri */
leo_sobral@805
   352
  if (!(pbm->source = gen_source_element (pbm)))
leo_sobral@805
   353
    goto no_source;
renatofilho@787
   354
leo_sobral@805
   355
  add_element (pbm, pbm->source);
renatofilho@787
   356
renatofilho@787
   357
renatofilho@787
   358
#if 0
renatofilho@787
   359
    if (verify_src_have_sink (pbm)) {
renatofilho@787
   360
        /* source can be linked with sinks directly */
renatofilho@787
   361
        return TRUE;
renatofilho@787
   362
    }
renatofilho@787
   363
#endif
renatofilho@787
   364
leo_sobral@805
   365
  prepare_elements (pbm);
renatofilho@787
   366
leo_sobral@805
   367
  return TRUE;
renatofilho@787
   368
renatofilho@787
   369
no_source:
leo_sobral@805
   370
  return FALSE;
renatofilho@787
   371
}
renatofilho@787
   372
renatofilho@787
   373
static void
renatofilho@787
   374
gst_play_bin_maemo_set_property (GObject *object,
renatofilho@787
   375
                                 guint prop_id,
renatofilho@787
   376
                                 const GValue *value,
renatofilho@787
   377
                                 GParamSpec *pspec)
renatofilho@787
   378
{
renatofilho@787
   379
  GstPlayBinMaemo *play_bin_maemo;
renatofilho@787
   380
renatofilho@787
   381
  g_return_if_fail (GST_IS_PLAY_BIN_MAEMO (object));
renatofilho@787
   382
renatofilho@787
   383
  play_bin_maemo = GST_PLAY_BIN_MAEMO (object);
renatofilho@787
   384
renatofilho@787
   385
  switch (prop_id) {
renatofilho@787
   386
    case ARG_URI:
renatofilho@787
   387
    {
renatofilho@787
   388
      const gchar *uri = g_value_get_string (value);
renatofilho@787
   389
renatofilho@787
   390
      if (uri == NULL) {
renatofilho@787
   391
        g_warning ("cannot set NULL uri");
renatofilho@787
   392
        return;
renatofilho@787
   393
      }
renatofilho@787
   394
      /* if we have no previous uri, or the new uri is different from the
renatofilho@787
   395
       * old one, replug */
renatofilho@787
   396
      if (play_bin_maemo->uri == NULL || strcmp (play_bin_maemo->uri, uri) != 0) {
renatofilho@787
   397
        g_free (play_bin_maemo->uri);
renatofilho@787
   398
        play_bin_maemo->uri = g_strdup (uri);
renatofilho@787
   399
renatofilho@787
   400
        GST_DEBUG ("setting new uri to %s", uri);
renatofilho@787
   401
renatofilho@787
   402
        play_bin_maemo->need_rebuild = TRUE;
renatofilho@787
   403
      }
renatofilho@787
   404
      break;
renatofilho@787
   405
    }
renatofilho@787
   406
    case ARG_VOLUME:
renatofilho@787
   407
    {
renatofilho@793
   408
      gdouble d_volume = 0;
renatofilho@793
   409
      guint u_volume = 0;
renatofilho@793
   410
      d_volume = g_value_get_double (value);
renatofilho@793
   411
renatofilho@793
   412
      g_debug ("Getting : %5.2f", d_volume);
renatofilho@793
   413
      if (d_volume != 0) {
renatofilho@793
   414
        u_volume = (guint) (65535 * d_volume);
renatofilho@787
   415
      }
renatofilho@787
   416
renatofilho@793
   417
      g_debug ("Converting : %d", u_volume);
renatofilho@793
   418
      if (play_bin_maemo->volume != u_volume) {
renatofilho@793
   419
          play_bin_maemo->volume = u_volume;
renatofilho@787
   420
          update_volume (play_bin_maemo);
renatofilho@787
   421
      }
renatofilho@787
   422
      break;
renatofilho@787
   423
    }
renatofilho@787
   424
    case ARG_XID:
renatofilho@787
   425
    {
renatofilho@787
   426
      long xid;
renatofilho@787
   427
      xid = g_value_get_long (value);
renatofilho@792
   428
      if (play_bin_maemo->xid != xid)
renatofilho@792
   429
      {
renatofilho@787
   430
          play_bin_maemo->xid = xid;
renatofilho@787
   431
          update_xid (play_bin_maemo);
renatofilho@787
   432
      }
renatofilho@787
   433
      break;
renatofilho@787
   434
    }
renatofilho@788
   435
    case ARG_PARSE_METADATA:
renatofilho@788
   436
        play_bin_maemo->parse_metadata = g_value_get_boolean (value);
renatofilho@788
   437
        break;
renatofilho@787
   438
    default:
renatofilho@787
   439
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
renatofilho@787
   440
      break;
renatofilho@787
   441
  }
renatofilho@787
   442
}
renatofilho@787
   443
renatofilho@787
   444
static void
renatofilho@787
   445
gst_play_bin_maemo_get_property (GObject * object, guint prop_id, GValue * value,
renatofilho@787
   446
    GParamSpec * pspec)
renatofilho@787
   447
{
renatofilho@787
   448
  GstPlayBinMaemo *play_bin_maemo;
renatofilho@787
   449
renatofilho@787
   450
  g_return_if_fail (GST_IS_PLAY_BIN_MAEMO (object));
renatofilho@787
   451
renatofilho@787
   452
  play_bin_maemo = GST_PLAY_BIN_MAEMO (object);
renatofilho@787
   453
renatofilho@787
   454
  switch (prop_id) {
renatofilho@787
   455
    case ARG_URI:
renatofilho@787
   456
      g_value_set_string (value, play_bin_maemo->uri);
renatofilho@787
   457
      break;
renatofilho@787
   458
    case ARG_SOURCE:
renatofilho@787
   459
      g_value_set_object (value, play_bin_maemo->source);
renatofilho@787
   460
      break;
renatofilho@787
   461
    case ARG_VOLUME:
leo_sobral@805
   462
    {
renatofilho@793
   463
      gdouble volume  = 0;
renatofilho@792
   464
      if (play_bin_maemo->volume > 0) {
renatofilho@793
   465
          volume = play_bin_maemo->volume / 65535;
renatofilho@792
   466
      }
renatofilho@793
   467
      g_value_set_double (value, volume);
renatofilho@787
   468
      break;
leo_sobral@805
   469
    }
renatofilho@787
   470
    case ARG_XID:
renatofilho@787
   471
      g_value_set_long (value, play_bin_maemo->xid);
renatofilho@787
   472
      break;
renatofilho@788
   473
    case ARG_PARSE_METADATA:
renatofilho@788
   474
      g_value_set_boolean (value, play_bin_maemo->parse_metadata);
renatofilho@788
   475
      break;
renatofilho@787
   476
    default:
renatofilho@787
   477
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
renatofilho@787
   478
      break;
renatofilho@787
   479
  }
renatofilho@787
   480
}
renatofilho@787
   481
renatofilho@787
   482
static GstStateChangeReturn
renatofilho@787
   483
gst_play_bin_maemo_change_state (GstElement * element, GstStateChange transition)
renatofilho@787
   484
{
renatofilho@787
   485
  GstStateChangeReturn ret;
renatofilho@787
   486
  GstPlayBinMaemo *play_bin_maemo;
renatofilho@787
   487
renatofilho@787
   488
  play_bin_maemo = GST_PLAY_BIN_MAEMO (element);
renatofilho@787
   489
renatofilho@787
   490
  switch (transition) {
renatofilho@787
   491
    case GST_STATE_CHANGE_READY_TO_PAUSED:
renatofilho@787
   492
      if (!setup_source (play_bin_maemo))
renatofilho@787
   493
        goto source_failed;
renatofilho@787
   494
      break;
renatofilho@787
   495
    default:
renatofilho@787
   496
      break;
renatofilho@787
   497
  }
renatofilho@787
   498
renatofilho@787
   499
  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
renatofilho@787
   500
renatofilho@787
   501
  switch (transition) {
renatofilho@787
   502
    case GST_STATE_CHANGE_READY_TO_PAUSED:
renatofilho@787
   503
      if (ret == GST_STATE_CHANGE_FAILURE) {
renatofilho@787
   504
        play_bin_maemo->need_rebuild = TRUE;
renatofilho@787
   505
        return GST_STATE_CHANGE_FAILURE;
renatofilho@787
   506
      }
renatofilho@787
   507
      break;
renatofilho@787
   508
      /* clean-up in both cases, READY=>NULL clean-up is if there was an error */
renatofilho@787
   509
    case GST_STATE_CHANGE_PAUSED_TO_READY:
renatofilho@787
   510
    case GST_STATE_CHANGE_READY_TO_NULL:
renatofilho@787
   511
      play_bin_maemo->need_rebuild = TRUE;
renatofilho@792
   512
      clear_elements (play_bin_maemo);
renatofilho@787
   513
      break;
renatofilho@787
   514
    default:
renatofilho@787
   515
      break;
renatofilho@787
   516
  }
renatofilho@787
   517
  return ret;
renatofilho@787
   518
renatofilho@787
   519
  /* ERRORS */
renatofilho@787
   520
source_failed:
renatofilho@787
   521
  {
renatofilho@787
   522
    play_bin_maemo->need_rebuild = TRUE;
renatofilho@787
   523
renatofilho@787
   524
    return GST_STATE_CHANGE_FAILURE;
renatofilho@787
   525
  }
renatofilho@787
   526
}
renatofilho@787
   527
renatofilho@787
   528
static gboolean
renatofilho@787
   529
factory_filter_sinks (GstPluginFeature *feature,
renatofilho@787
   530
                      GstPlayBinMaemo *pbm)
renatofilho@787
   531
{
leo_sobral@805
   532
  guint rank;
leo_sobral@805
   533
  const gchar *klass;
renatofilho@787
   534
leo_sobral@805
   535
  if (!GST_IS_ELEMENT_FACTORY (feature))
leo_sobral@805
   536
    return FALSE;
renatofilho@787
   537
leo_sobral@805
   538
  klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
renatofilho@787
   539
leo_sobral@805
   540
  if ((strstr (klass, "Sink/Video") == NULL) && (strstr (klass, "Sink/Audio") == NULL))
leo_sobral@805
   541
    return FALSE;
renatofilho@787
   542
leo_sobral@805
   543
  g_debug ("Filtered: %s", gst_element_factory_get_longname ((GST_ELEMENT_FACTORY (feature))));
leo_sobral@805
   544
  rank = gst_plugin_feature_get_rank (feature);
leo_sobral@805
   545
  if (rank < GST_RANK_MARGINAL)
leo_sobral@805
   546
    return FALSE;
renatofilho@787
   547
leo_sobral@805
   548
  return TRUE;
renatofilho@787
   549
}
renatofilho@787
   550
renatofilho@787
   551
static gint
renatofilho@787
   552
compare_ranks (GstPluginFeature * f1, GstPluginFeature * f2)
renatofilho@787
   553
{
renatofilho@787
   554
  gint diff;
renatofilho@787
   555
  const gchar *rname1, *rname2;
renatofilho@787
   556
renatofilho@787
   557
  diff = gst_plugin_feature_get_rank (f2) - gst_plugin_feature_get_rank (f1);
renatofilho@787
   558
  if (diff != 0)
renatofilho@787
   559
    return diff;
renatofilho@787
   560
renatofilho@787
   561
  rname1 = gst_plugin_feature_get_name (f1);
renatofilho@787
   562
  rname2 = gst_plugin_feature_get_name (f2);
renatofilho@787
   563
renatofilho@787
   564
  diff = strcmp (rname2, rname1);
renatofilho@787
   565
renatofilho@787
   566
  return diff;
renatofilho@787
   567
}
renatofilho@787
   568
renatofilho@787
   569
renatofilho@787
   570
static GList *
renatofilho@787
   571
find_compatibles (GstPlayBinMaemo *pbm, const GstCaps *caps)
renatofilho@787
   572
{
renatofilho@787
   573
  GList *factories;
renatofilho@787
   574
  GList *to_try = NULL;
renatofilho@787
   575
renatofilho@787
   576
  /* loop over all the factories */
renatofilho@787
   577
  for (factories = pbm->factories; factories; factories = g_list_next (factories)) {
renatofilho@787
   578
    GstElementFactory *factory = GST_ELEMENT_FACTORY (factories->data);
renatofilho@787
   579
    const GList *templates;
renatofilho@787
   580
    GList *walk;
renatofilho@787
   581
renatofilho@787
   582
    /* get the templates from the element factory */
renatofilho@787
   583
    templates = gst_element_factory_get_static_pad_templates (factory);
renatofilho@787
   584
    for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
renatofilho@787
   585
      GstStaticPadTemplate *templ = walk->data;
renatofilho@787
   586
renatofilho@787
   587
      /* we only care about the sink templates */
renatofilho@787
   588
      if (templ->direction == GST_PAD_SINK) {
renatofilho@787
   589
        GstCaps *intersect;
renatofilho@787
   590
        GstCaps *tmpl_caps;
renatofilho@787
   591
renatofilho@787
   592
        /* try to intersect the caps with the caps of the template */
renatofilho@787
   593
        tmpl_caps = gst_static_caps_get (&templ->static_caps);
renatofilho@787
   594
renatofilho@787
   595
        intersect = gst_caps_intersect (caps, tmpl_caps);
renatofilho@787
   596
        gst_caps_unref (tmpl_caps);
renatofilho@787
   597
renatofilho@787
   598
        /* check if the intersection is empty */
renatofilho@787
   599
        if (!gst_caps_is_empty (intersect)) {
renatofilho@787
   600
          /* non empty intersection, we can use this element */
renatofilho@787
   601
          to_try = g_list_prepend (to_try, factory);
renatofilho@787
   602
          gst_caps_unref (intersect);
renatofilho@787
   603
          break;
renatofilho@787
   604
        }
renatofilho@787
   605
        gst_caps_unref (intersect);
renatofilho@787
   606
      }
renatofilho@787
   607
    }
renatofilho@787
   608
  }
renatofilho@787
   609
  to_try = g_list_reverse (to_try);
renatofilho@787
   610
renatofilho@787
   611
  return to_try;
renatofilho@787
   612
}
renatofilho@787
   613
renatofilho@787
   614
renatofilho@787
   615
static gboolean
renatofilho@787
   616
autoplug_continue_cb (GstElement* object,
renatofilho@787
   617
                      GstCaps* caps,
renatofilho@787
   618
                      gpointer user_data)
renatofilho@787
   619
{
renatofilho@787
   620
    GList *comp = NULL;
renatofilho@787
   621
    gboolean ret = TRUE;
renatofilho@788
   622
    GstPlayBinMaemo *pbm;
renatofilho@788
   623
renatofilho@788
   624
    pbm = GST_PLAY_BIN_MAEMO (user_data);
renatofilho@788
   625
renatofilho@788
   626
    //TODO: fix this for work with all metada elements
renatofilho@788
   627
    if (pbm->parse_metadata) {
renatofilho@788
   628
        gchar *caps_str = gst_caps_to_string (caps);
renatofilho@788
   629
        if ((strstr (caps_str, "id3") != NULL) &&
renatofilho@788
   630
            (pbm->has_metadata == FALSE)) {
renatofilho@788
   631
renatofilho@788
   632
            g_free (caps_str);
renatofilho@788
   633
            pbm->has_metadata = TRUE;
renatofilho@788
   634
            return ret;
renatofilho@788
   635
        }
renatofilho@788
   636
        g_free (caps_str);
renatofilho@788
   637
    }
renatofilho@787
   638
renatofilho@787
   639
    comp = find_compatibles (GST_PLAY_BIN_MAEMO (user_data), caps);
renatofilho@787
   640
    if (comp != NULL) {
renatofilho@787
   641
        g_list_free (comp);
renatofilho@787
   642
        ret = FALSE;
renatofilho@787
   643
    }
renatofilho@787
   644
renatofilho@787
   645
    return ret;
renatofilho@787
   646
}
renatofilho@787
   647
renatofilho@787
   648
static void
renatofilho@787
   649
unknown_type_cb (GstElement *object,
renatofilho@787
   650
                 GstPad *pad,
renatofilho@787
   651
                 GstCaps *caps,
renatofilho@787
   652
                 gpointer user_data)
renatofilho@787
   653
{
leo_sobral@805
   654
  g_debug ("unknown_type_cb: %s", gst_caps_to_string (caps));
renatofilho@787
   655
}
renatofilho@787
   656
renatofilho@787
   657
static GstPad *
renatofilho@787
   658
find_sink_pad (GstElement * element)
renatofilho@787
   659
{
renatofilho@787
   660
  GstIterator *it;
renatofilho@787
   661
  GstPad *pad = NULL;
renatofilho@787
   662
  gpointer point;
renatofilho@787
   663
renatofilho@787
   664
  it = gst_element_iterate_sink_pads (element);
renatofilho@787
   665
renatofilho@787
   666
  if ((gst_iterator_next (it, &point)) == GST_ITERATOR_OK)
renatofilho@787
   667
    pad = (GstPad *) point;
renatofilho@787
   668
renatofilho@787
   669
  gst_iterator_free (it);
renatofilho@787
   670
renatofilho@787
   671
  return pad;
renatofilho@787
   672
}
renatofilho@787
   673
renatofilho@788
   674
static GstElement*
renatofilho@788
   675
create_element (GstPlayBinMaemo *pbm, GstElementFactory *factory)
renatofilho@788
   676
{
leo_sobral@805
   677
  GstElement *queue;
leo_sobral@805
   678
  GstElement *bin = NULL;
leo_sobral@805
   679
  GstElement *element;
leo_sobral@805
   680
  GstPad *pad;
renatofilho@788
   681
leo_sobral@805
   682
  element = gst_element_factory_create (factory, NULL);
leo_sobral@805
   683
  if (element == NULL)
leo_sobral@805
   684
    return NULL;
renatofilho@788
   685
renatofilho@792
   686
leo_sobral@805
   687
  bin = gst_bin_new (NULL);
renatofilho@792
   688
leo_sobral@805
   689
  queue = gst_element_factory_make ("queue", NULL);
leo_sobral@805
   690
  gst_bin_add (GST_BIN (bin), queue);
renatofilho@792
   691
leo_sobral@805
   692
  if (strstr (gst_element_factory_get_klass (factory), "Sink/Video") != NULL) {
leo_sobral@805
   693
    GstElement *colorspace;
renatofilho@792
   694
leo_sobral@805
   695
    colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
renatofilho@792
   696
leo_sobral@805
   697
    gst_bin_add (GST_BIN (bin), colorspace);
leo_sobral@805
   698
    if (gst_element_link (queue, colorspace) == FALSE) {
leo_sobral@805
   699
      GST_WARNING_OBJECT (pbm, "Fail to link queue and colorspace");
leo_sobral@805
   700
      gst_element_set_state (colorspace, GST_STATE_NULL);
leo_sobral@805
   701
      gst_object_unref (colorspace);
leo_sobral@805
   702
      goto error;
renatofilho@788
   703
    }
renatofilho@788
   704
leo_sobral@805
   705
    gst_bin_add (GST_BIN (bin), element);
leo_sobral@805
   706
    if (gst_element_link (colorspace, element) == FALSE) {
leo_sobral@805
   707
      GST_WARNING_OBJECT (pbm, "Fail to link colorspace and sink video: %s", GST_ELEMENT_NAME (element));
leo_sobral@805
   708
      gst_element_set_state (colorspace, GST_STATE_NULL);
leo_sobral@805
   709
      gst_object_unref (colorspace);
leo_sobral@805
   710
      goto error;
leo_sobral@805
   711
    }
renatofilho@792
   712
leo_sobral@805
   713
    pbm->video_sink = element;
leo_sobral@805
   714
    update_xid (pbm);
leo_sobral@805
   715
leo_sobral@805
   716
  } else if (strstr (gst_element_factory_get_klass (factory), "Sink/Audio") != NULL) {
leo_sobral@805
   717
    GParamSpec *vol_spec;
leo_sobral@805
   718
    GstElement *prev;
leo_sobral@805
   719
leo_sobral@805
   720
    prev = queue;
leo_sobral@805
   721
    vol_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (element), "volume");
leo_sobral@805
   722
    if (vol_spec == NULL) {
leo_sobral@805
   723
      GstElement *volume;
leo_sobral@805
   724
leo_sobral@805
   725
      bin = gst_bin_new (NULL);
leo_sobral@805
   726
      volume = gst_element_factory_make ("volume", "volume");
leo_sobral@805
   727
      gst_bin_add (GST_BIN (bin), volume);
leo_sobral@805
   728
      if (gst_element_link (queue, volume) == FALSE) {
leo_sobral@805
   729
        GST_WARNING_OBJECT (pbm, "Fail to link queue and volume");
leo_sobral@805
   730
        gst_element_set_state (volume, GST_STATE_NULL);
leo_sobral@805
   731
        gst_object_unref (volume);
leo_sobral@805
   732
        goto error;
leo_sobral@805
   733
      }
leo_sobral@805
   734
leo_sobral@805
   735
      prev = volume;
leo_sobral@805
   736
      g_param_spec_unref (vol_spec);
leo_sobral@805
   737
    }
leo_sobral@805
   738
leo_sobral@805
   739
    gst_bin_add (GST_BIN (bin), element);
leo_sobral@805
   740
    if (gst_element_link (prev, element) == FALSE) {
leo_sobral@805
   741
      GST_WARNING_OBJECT (pbm, "Fail to link volume and sink audio: %s", GST_ELEMENT_NAME (element));
leo_sobral@805
   742
      if (prev != queue) {
leo_sobral@805
   743
        gst_element_set_state (prev, GST_STATE_NULL);
leo_sobral@805
   744
        gst_object_unref (prev);
leo_sobral@805
   745
      }
leo_sobral@805
   746
      goto error;
leo_sobral@805
   747
    }
leo_sobral@805
   748
leo_sobral@805
   749
    pbm->volume_element = (prev != queue) ? prev : element;
leo_sobral@805
   750
    update_volume (pbm);
leo_sobral@805
   751
  }
leo_sobral@805
   752
leo_sobral@805
   753
  pad = gst_element_get_pad (queue, "sink");
leo_sobral@805
   754
  gst_element_add_pad (bin, gst_ghost_pad_new ("sink", pad));
leo_sobral@805
   755
  gst_object_unref (pad);
leo_sobral@805
   756
leo_sobral@805
   757
  return bin;
renatofilho@792
   758
error:
renatofilho@792
   759
leo_sobral@805
   760
  gst_element_set_state (bin, GST_STATE_NULL);
leo_sobral@805
   761
  gst_object_unref (bin);
renatofilho@792
   762
leo_sobral@805
   763
  return NULL;
renatofilho@788
   764
}
renatofilho@788
   765
renatofilho@787
   766
static void
renatofilho@787
   767
new_decoded_pad_cb (GstElement *object,
renatofilho@787
   768
                    GstPad* pad,
renatofilho@787
   769
                    gboolean arg,
renatofilho@787
   770
                    gpointer user_data)
renatofilho@787
   771
{
leo_sobral@805
   772
  GList *comp = NULL;
leo_sobral@805
   773
  GList *walk;
leo_sobral@805
   774
  GstCaps *caps;
leo_sobral@805
   775
  gboolean linked;
leo_sobral@805
   776
  GstPlayBinMaemo *pbm;
renatofilho@787
   777
leo_sobral@805
   778
  pbm = GST_PLAY_BIN_MAEMO (user_data);
leo_sobral@805
   779
  caps = gst_pad_get_caps (pad);
renatofilho@787
   780
leo_sobral@805
   781
  g_debug ("new_decoded_pad_cb: %s", gst_caps_to_string (caps));
renatofilho@787
   782
leo_sobral@805
   783
  comp = find_compatibles (GST_PLAY_BIN_MAEMO (user_data), caps);
renatofilho@787
   784
renatofilho@787
   785
leo_sobral@805
   786
  if (comp == NULL) {
leo_sobral@805
   787
    g_warning ("flow error: dont find comaptible");
leo_sobral@805
   788
    return;
leo_sobral@805
   789
  }
leo_sobral@805
   790
leo_sobral@805
   791
  GST_PAD_STREAM_LOCK (pad);
leo_sobral@805
   792
leo_sobral@805
   793
  linked = FALSE;
leo_sobral@805
   794
  for (walk=comp; walk != NULL; walk = walk->next) {
leo_sobral@805
   795
    GstElementFactory *factory = (GstElementFactory *) walk->data;
leo_sobral@805
   796
    GstElement *element;
leo_sobral@805
   797
    GstPad *sinkpad = NULL;
leo_sobral@805
   798
leo_sobral@805
   799
    if ((element = create_element (pbm, factory)) == NULL) {
leo_sobral@805
   800
      GST_WARNING_OBJECT (pbm, "Could not create an element from %s",
leo_sobral@805
   801
          gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
leo_sobral@805
   802
      g_debug ("Could not create an element from %s",
leo_sobral@805
   803
          gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
leo_sobral@805
   804
leo_sobral@805
   805
      continue;
renatofilho@787
   806
    }
renatofilho@787
   807
leo_sobral@805
   808
    if (!(add_element (GST_PLAY_BIN_MAEMO (user_data), element))) {
leo_sobral@805
   809
      GST_WARNING_OBJECT (pbm, "Couldn't set %s to READY", GST_ELEMENT_NAME (element));
leo_sobral@805
   810
      gst_object_unref (element);
leo_sobral@805
   811
      continue;
renatofilho@787
   812
    }
renatofilho@787
   813
leo_sobral@805
   814
    if ((gst_element_set_state (element, GST_STATE_READY))
leo_sobral@805
   815
                   == GST_STATE_CHANGE_FAILURE) {
leo_sobral@805
   816
      gst_element_set_state (element, GST_STATE_NULL);
leo_sobral@805
   817
      gst_object_unref (sinkpad);
leo_sobral@805
   818
      gst_bin_remove (GST_BIN (user_data), element);
leo_sobral@805
   819
      continue;
renatofilho@787
   820
    }
leo_sobral@805
   821
leo_sobral@805
   822
    if (!(sinkpad = find_sink_pad (element))) {
leo_sobral@805
   823
      GST_WARNING_OBJECT (pbm, "Element %s doesn't have a sink pad", GST_ELEMENT_NAME (element));
leo_sobral@805
   824
      g_debug ("Element %s doesn't have a sink pad", GST_ELEMENT_NAME (element));
leo_sobral@805
   825
      gst_object_unref (element);
leo_sobral@805
   826
      continue;
leo_sobral@805
   827
    }
leo_sobral@805
   828
leo_sobral@805
   829
leo_sobral@805
   830
    if ((gst_pad_link (pad, sinkpad)) != GST_PAD_LINK_OK) {
leo_sobral@805
   831
        GST_WARNING_OBJECT (pbm, "Link failed on pad %s:%s", GST_DEBUG_PAD_NAME (sinkpad));
leo_sobral@805
   832
        gst_element_set_state (element, GST_STATE_NULL);
leo_sobral@805
   833
        gst_object_unref (sinkpad);
leo_sobral@805
   834
        gst_bin_remove (GST_BIN (user_data), element);
leo_sobral@805
   835
      continue;
leo_sobral@805
   836
    }
leo_sobral@805
   837
leo_sobral@805
   838
    gst_object_unref (sinkpad);
leo_sobral@805
   839
leo_sobral@805
   840
    if ((gst_element_set_state (element, GST_STATE_PAUSED)) == GST_STATE_CHANGE_FAILURE) {
leo_sobral@805
   841
        gst_element_set_state (element, GST_STATE_NULL);
leo_sobral@805
   842
        gst_bin_remove (GST_BIN (user_data), element);
leo_sobral@805
   843
      continue;
leo_sobral@805
   844
    }
leo_sobral@805
   845
leo_sobral@805
   846
    linked = TRUE;
leo_sobral@805
   847
    break;
leo_sobral@805
   848
  }
leo_sobral@805
   849
leo_sobral@805
   850
  g_list_free (comp);
leo_sobral@805
   851
  if (linked == FALSE) {
leo_sobral@805
   852
    g_warning ("GstFlow ERROR");
leo_sobral@805
   853
  }
leo_sobral@805
   854
  GST_PAD_STREAM_UNLOCK (pad);
renatofilho@787
   855
}
renatofilho@787
   856
renatofilho@787
   857
static void
renatofilho@787
   858
update_volume (GstPlayBinMaemo *pbm)
renatofilho@787
   859
{
leo_sobral@805
   860
  if (pbm->volume_element != NULL) {
leo_sobral@805
   861
    if (pbm->volume > 0) {
leo_sobral@805
   862
      g_object_set (G_OBJECT (pbm->volume_element),
leo_sobral@805
   863
                    "volume", pbm->volume,
leo_sobral@805
   864
                    NULL);
leo_sobral@805
   865
    } else {
leo_sobral@805
   866
      g_object_set (G_OBJECT (pbm->volume_element),
leo_sobral@805
   867
                    "mute", TRUE,
leo_sobral@805
   868
                    NULL);
renatofilho@787
   869
    }
leo_sobral@805
   870
  }
renatofilho@787
   871
}
renatofilho@787
   872
renatofilho@787
   873
static void
renatofilho@787
   874
update_xid (GstPlayBinMaemo *pbm)
renatofilho@787
   875
{
leo_sobral@805
   876
  if ((pbm->video_sink != NULL) &&
leo_sobral@805
   877
    (pbm->xid != -1) &&
leo_sobral@805
   878
    (GST_IS_X_OVERLAY (pbm->video_sink))) {
leo_sobral@805
   879
    Display *display;
leo_sobral@805
   880
    g_object_set (G_OBJECT (pbm->video_sink),
leo_sobral@805
   881
                  "force-aspect-ratio", TRUE, NULL);
leo_sobral@805
   882
    display = XOpenDisplay(NULL);
leo_sobral@805
   883
    XMapRaised(display, pbm->xid);
leo_sobral@808
   884
    XSetErrorHandler(x_error_handler);
leo_sobral@805
   885
    XSync (display, FALSE);
renatofilho@792
   886
leo_sobral@805
   887
    gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (pbm->video_sink),
leo_sobral@805
   888
                                  pbm->xid);
leo_sobral@805
   889
  }
renatofilho@787
   890
}
renatofilho@787
   891
leo_sobral@808
   892
static int
leo_sobral@808
   893
x_error_handler(Display *display, XErrorEvent *event)
leo_sobral@808
   894
{
leo_sobral@808
   895
    g_debug ("In x error handler:");
leo_sobral@808
   896
leo_sobral@808
   897
    switch (event->error_code) {
leo_sobral@808
   898
        case BadWindow:
leo_sobral@808
   899
            g_debug ("got bad window");
leo_sobral@808
   900
            break;
leo_sobral@808
   901
        case BadDrawable:
leo_sobral@808
   902
            g_debug ("got bad drawable");
leo_sobral@808
   903
            break;
leo_sobral@808
   904
        case BadGC:
leo_sobral@808
   905
            g_debug ("got bad gc");
leo_sobral@808
   906
            break;
leo_sobral@808
   907
        default:
leo_sobral@808
   908
            g_debug ("unhandled x error = %d", event->error_code);
leo_sobral@808
   909
    }
leo_sobral@808
   910
leo_sobral@808
   911
    return 0;
leo_sobral@808
   912
}
leo_sobral@808
   913
renatofilho@787
   914
static gboolean
renatofilho@792
   915
add_element (GstPlayBinMaemo *pbm,
renatofilho@792
   916
             GstElement *child)
renatofilho@792
   917
{
leo_sobral@805
   918
  if (gst_bin_add (GST_BIN (pbm), child)) {
leo_sobral@805
   919
    pbm->elements = g_list_append (pbm->elements, child);
leo_sobral@805
   920
    return TRUE;
leo_sobral@805
   921
  }
leo_sobral@805
   922
  return FALSE;
renatofilho@792
   923
}
renatofilho@792
   924
renatofilho@792
   925
static void
renatofilho@792
   926
clear_elements (GstPlayBinMaemo *pbm)
renatofilho@792
   927
{
leo_sobral@805
   928
  GList *walk;
renatofilho@792
   929
leo_sobral@805
   930
  walk = pbm->elements;
renatofilho@792
   931
leo_sobral@805
   932
  for (; walk != NULL; walk = walk->next) {
leo_sobral@805
   933
    GstElement *e = GST_ELEMENT (walk->data);
renatofilho@792
   934
leo_sobral@805
   935
    gst_element_set_state (e, GST_STATE_NULL);
leo_sobral@805
   936
    gst_bin_remove (GST_BIN (pbm), e);
leo_sobral@805
   937
  }
renatofilho@792
   938
leo_sobral@805
   939
  g_list_free (pbm->elements);
leo_sobral@805
   940
  pbm->elements = NULL;
leo_sobral@805
   941
  pbm->source = NULL;
leo_sobral@805
   942
  pbm->volume_element = NULL;
leo_sobral@805
   943
  pbm->video_sink = NULL;
renatofilho@792
   944
}
renatofilho@792
   945
renatofilho@792
   946
static gboolean
renatofilho@787
   947
plugin_init(GstPlugin * plugin)
renatofilho@787
   948
{
renatofilho@787
   949
#ifdef ENABLE_NLS
leo_sobral@805
   950
  setlocale(LC_ALL, "");
leo_sobral@805
   951
  bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
renatofilho@787
   952
#endif                          /* ENABLE_NLS */
renatofilho@787
   953
leo_sobral@805
   954
  if (!gst_element_register(plugin, "playbinmaemo", GST_RANK_SECONDARY,
leo_sobral@805
   955
                          GST_TYPE_PLAY_BIN_MAEMO)) {
leo_sobral@805
   956
    return FALSE;
leo_sobral@805
   957
  }
renatofilho@787
   958
leo_sobral@805
   959
  return TRUE;
renatofilho@787
   960
}
renatofilho@787
   961
renatofilho@787
   962
GST_PLUGIN_DEFINE(GST_VERSION_MAJOR,
renatofilho@787
   963
                  GST_VERSION_MINOR,
renatofilho@787
   964
                  "playbinmaemo",
leo_sobral@796
   965
                  "A playbin element that uses decodebin2 for automatic playback of audio and video",
renatofilho@787
   966
                  plugin_init, VERSION, GST_LICENSE, GST_PACKAGE_NAME,
renatofilho@787
   967
                  GST_PACKAGE_ORIGIN)