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