gst-gmyth/playbinmaemo/gstplaybinmaemo.c
branchtrunk
changeset 792 a6ac25bf88a7
parent 788 357b301e2d23
child 793 45c799bef1f6
     1.1 --- a/gst-gmyth/playbinmaemo/gstplaybinmaemo.c	Tue Jul 17 23:17:09 2007 +0100
     1.2 +++ b/gst-gmyth/playbinmaemo/gstplaybinmaemo.c	Thu Aug 02 14:58:15 2007 +0100
     1.3 @@ -95,10 +95,9 @@
     1.4                                                       gpointer user_data);
     1.5  static void     queue_sink_overrun_cb               (GstElement* queue,
     1.6                                                       gpointer user_data);
     1.7 -
     1.8 -
     1.9 -
    1.10 -
    1.11 +static gboolean add_element                         (GstPlayBinMaemo *pbm,
    1.12 +                                                     GstElement *child);
    1.13 +static void     clear_elements                      (GstPlayBinMaemo *pbm);
    1.14  
    1.15  GST_BOILERPLATE(GstPlayBinMaemo, gst_play_bin_maemo, GstPipeline, GST_TYPE_PIPELINE)
    1.16  
    1.17 @@ -191,6 +190,7 @@
    1.18  static void
    1.19  gst_play_bin_maemo_finalize (GObject * object)
    1.20  {
    1.21 +  clear_elements (GST_PLAY_BIN_MAEMO (object));
    1.22    G_OBJECT_CLASS (parent_class)->finalize (object);
    1.23  }
    1.24  
    1.25 @@ -248,8 +248,7 @@
    1.26    if (IS_BLACKLISTED_URI (play_bin_maemo->uri))
    1.27      goto uri_blacklisted;
    1.28  
    1.29 -  source = gst_element_make_from_uri (GST_URI_SRC, play_bin_maemo->uri,
    1.30 -      "source");
    1.31 +  source = gst_element_make_from_uri (GST_URI_SRC, play_bin_maemo->uri, "source");
    1.32    if (!source)
    1.33      goto no_source;
    1.34  
    1.35 @@ -312,76 +311,32 @@
    1.36  }
    1.37  
    1.38  static void
    1.39 -remove_source (GstPlayBinMaemo *pbm)
    1.40 -{
    1.41 -  GstElement *source = pbm->source;
    1.42 -
    1.43 -  if (source) {
    1.44 -    GST_DEBUG_OBJECT (pbm, "removing old src element");
    1.45 -    gst_element_set_state (source, GST_STATE_NULL);
    1.46 -    gst_bin_remove (GST_BIN_CAST (pbm), source);
    1.47 -    pbm->source = NULL;
    1.48 -  }
    1.49 -}
    1.50 -
    1.51 -static void
    1.52 -remove_decoders (GstPlayBinMaemo *pbm)
    1.53 -{
    1.54 -    if (pbm->queue != NULL) {
    1.55 -        gst_element_set_state (pbm->queue, GST_STATE_NULL);
    1.56 -        gst_bin_remove (GST_BIN_CAST (pbm), pbm->queue);
    1.57 -        pbm->queue = NULL;
    1.58 -    }
    1.59 -
    1.60 -    if (pbm->decoder != NULL) {
    1.61 -        gst_element_set_state (pbm->decoder, GST_STATE_NULL);
    1.62 -        gst_bin_remove (GST_BIN_CAST (pbm), pbm->decoder);
    1.63 -        pbm->decoder = NULL;
    1.64 -    }
    1.65 -}
    1.66 -
    1.67 -static void
    1.68 -remove_sinks (GstPlayBinMaemo *pbm)
    1.69 -{
    1.70 -    GSList *walk;
    1.71 -
    1.72 -    for(walk=pbm->sinks; walk != NULL; walk = walk->next) {
    1.73 -        GstElement *element = (GstElement *) walk->data;
    1.74 -
    1.75 -        gst_element_set_state (element, GST_STATE_NULL);
    1.76 -        gst_bin_remove (GST_BIN_CAST (pbm), element);
    1.77 -    }
    1.78 -
    1.79 -    g_slist_free (pbm->sinks);
    1.80 -    pbm->sinks = NULL;
    1.81 -}
    1.82 -
    1.83 -static void
    1.84  prepare_elements (GstPlayBinMaemo *pbm)
    1.85  {
    1.86 -    if (pbm->decoder == NULL) {
    1.87 -        pbm->decoder = gst_element_factory_make ("decodebin2", "decode");
    1.88 -        gst_bin_add (GST_BIN (pbm), pbm->decoder);
    1.89 -        g_signal_connect (G_OBJECT (pbm->decoder),
    1.90 -                          "autoplug-continue",
    1.91 -                          G_CALLBACK (autoplug_continue_cb),
    1.92 -                          pbm);
    1.93 -        g_signal_connect (G_OBJECT (pbm->decoder),
    1.94 -                          "unknown-type",
    1.95 -                          G_CALLBACK (unknown_type_cb),
    1.96 -                          pbm);
    1.97 -        g_signal_connect (G_OBJECT (pbm->decoder),
    1.98 -                          "new-decoded-pad",
    1.99 -                          G_CALLBACK (new_decoded_pad_cb),
   1.100 -                          pbm);
   1.101 -    }
   1.102 +    GstElement *decoder;
   1.103 +    GstElement *queue;
   1.104  
   1.105 -    if (pbm->queue == NULL) {
   1.106 -        pbm->queue = gst_element_factory_make ("queue", NULL);
   1.107 -        gst_bin_add (GST_BIN (pbm), pbm->queue);
   1.108 -    }
   1.109 +    decoder = gst_element_factory_make ("decodebin2", "decode");
   1.110 +    add_element (pbm, decoder);
   1.111 +    g_signal_connect (G_OBJECT (decoder),
   1.112 +                      "autoplug-continue",
   1.113 +                      G_CALLBACK (autoplug_continue_cb),
   1.114 +                      pbm);
   1.115  
   1.116 -    if (gst_element_link_many (pbm->source, pbm->queue, pbm->decoder, NULL) == FALSE) {
   1.117 +    g_signal_connect (G_OBJECT (decoder),
   1.118 +                      "unknown-type",
   1.119 +                      G_CALLBACK (unknown_type_cb),
   1.120 +                      pbm);
   1.121 +
   1.122 +    g_signal_connect (G_OBJECT (decoder),
   1.123 +                      "new-decoded-pad",
   1.124 +                      G_CALLBACK (new_decoded_pad_cb),
   1.125 +                      pbm);
   1.126 +
   1.127 +    queue = gst_element_factory_make ("queue", NULL);
   1.128 +    add_element (pbm, queue);
   1.129 +
   1.130 +    if (gst_element_link_many (pbm->source, queue, decoder, NULL) == FALSE) {
   1.131          g_warning ("FAIL TO LINK SRC WITH DECODEBIN2");
   1.132      }
   1.133  }
   1.134 @@ -389,26 +344,25 @@
   1.135  static gboolean
   1.136  setup_source (GstPlayBinMaemo *pbm)
   1.137  {
   1.138 +    GstIterator *childs;
   1.139 +    GstState state;
   1.140 +
   1.141      if (!pbm->need_rebuild)
   1.142          return TRUE;
   1.143  
   1.144 +    clear_elements (pbm);
   1.145 +
   1.146      GST_DEBUG_OBJECT (pbm, "setup source");
   1.147  
   1.148      pbm->has_metadata = FALSE;
   1.149  
   1.150 -    /* delete old src */
   1.151 -    remove_source (pbm);
   1.152 -
   1.153      /* create and configure an element that can handle the uri */
   1.154      if (!(pbm->source = gen_source_element (pbm)))
   1.155          goto no_source;
   1.156  
   1.157  
   1.158 -    gst_bin_add (GST_BIN_CAST (pbm), pbm->source);
   1.159 +    add_element (pbm, pbm->source);
   1.160  
   1.161 -    remove_decoders (pbm);
   1.162 -
   1.163 -    remove_sinks (pbm);
   1.164  
   1.165  #if 0
   1.166      if (verify_src_have_sink (pbm)) {
   1.167 @@ -460,7 +414,7 @@
   1.168      }
   1.169      case ARG_VOLUME:
   1.170      {
   1.171 -      guint volume;
   1.172 +      guint volume = 0;
   1.173        volume = g_value_get_uint (value);
   1.174        if (volume != 0) {
   1.175          volume = (guint) (65535 * volume / 10);
   1.176 @@ -476,7 +430,8 @@
   1.177      {
   1.178        long xid;
   1.179        xid = g_value_get_long (value);
   1.180 -      if (play_bin_maemo->xid != xid) {
   1.181 +      if (play_bin_maemo->xid != xid)
   1.182 +      {
   1.183            play_bin_maemo->xid = xid;
   1.184            update_xid (play_bin_maemo);
   1.185        }
   1.186 @@ -509,8 +464,14 @@
   1.187        g_value_set_object (value, play_bin_maemo->source);
   1.188        break;
   1.189      case ARG_VOLUME:
   1.190 -      g_value_set_uint (value, play_bin_maemo->volume);
   1.191 +      {
   1.192 +      guint volume  = 0;
   1.193 +      if (play_bin_maemo->volume > 0) {
   1.194 +          volume = 10 * play_bin_maemo->volume / 65535;
   1.195 +      }
   1.196 +      g_value_set_uint (value, volume);
   1.197        break;
   1.198 +      }
   1.199      case ARG_XID:
   1.200        g_value_set_long (value, play_bin_maemo->xid);
   1.201        break;
   1.202 @@ -553,8 +514,7 @@
   1.203      case GST_STATE_CHANGE_PAUSED_TO_READY:
   1.204      case GST_STATE_CHANGE_READY_TO_NULL:
   1.205        play_bin_maemo->need_rebuild = TRUE;
   1.206 -      remove_decoders (play_bin_maemo);
   1.207 -      remove_source (play_bin_maemo);
   1.208 +      clear_elements (play_bin_maemo);
   1.209        break;
   1.210      default:
   1.211        break;
   1.212 @@ -719,47 +679,93 @@
   1.213  static GstElement*
   1.214  create_element (GstPlayBinMaemo *pbm, GstElementFactory *factory)
   1.215  {
   1.216 -    GstElement *ret = NULL;
   1.217 +    GstElement *queue;
   1.218 +    GstElement *bin = NULL;
   1.219      GstElement *element;
   1.220 +    GstPad *pad;
   1.221  
   1.222      element = gst_element_factory_create (factory, NULL);
   1.223      if (element == NULL)
   1.224          return NULL;
   1.225  
   1.226 +
   1.227 +    bin = gst_bin_new (NULL);
   1.228 +
   1.229 +    queue = gst_element_factory_make ("queue", NULL);
   1.230 +    gst_bin_add (GST_BIN (bin), queue);
   1.231 +
   1.232      if (strstr (gst_element_factory_get_klass (factory), "Sink/Video") != NULL) {
   1.233 +        GstElement *colorspace;
   1.234 +
   1.235 +        colorspace = gst_element_factory_make ("ffmpegcolorspace", NULL);
   1.236 +
   1.237 +        gst_bin_add (GST_BIN (bin), colorspace);
   1.238 +        if (gst_element_link (queue, colorspace) == FALSE) {
   1.239 +            GST_WARNING_OBJECT (pbm, "Fail to link queue and colorspace");
   1.240 +            gst_element_set_state (colorspace, GST_STATE_NULL);
   1.241 +            gst_object_unref (colorspace);
   1.242 +            goto error;
   1.243 +        }
   1.244 +
   1.245 +        gst_bin_add (GST_BIN (bin), element);
   1.246 +        if (gst_element_link (colorspace, element) == FALSE) {
   1.247 +            GST_WARNING_OBJECT (pbm, "Fail to link colorspace and sink video: %s", GST_ELEMENT_NAME (element));
   1.248 +            gst_element_set_state (colorspace, GST_STATE_NULL);
   1.249 +            gst_object_unref (colorspace);
   1.250 +            goto error;
   1.251 +        }
   1.252 +
   1.253 +        pbm->sink_video = element;
   1.254          update_xid (pbm);
   1.255 -        pbm->sink_video = element;
   1.256 -        ret = element;
   1.257 +
   1.258      } else if (strstr (gst_element_factory_get_klass (factory), "Sink/Audio") != NULL) {
   1.259          GParamSpec *vol_spec;
   1.260 +        GstElement *prev;
   1.261  
   1.262 +        prev = queue;
   1.263          vol_spec = g_object_class_find_property (G_OBJECT_GET_CLASS (element), "volume");
   1.264          if (vol_spec == NULL) {
   1.265 -            GstElement *bin;
   1.266              GstElement *volume;
   1.267  
   1.268              bin = gst_bin_new (NULL);
   1.269              volume = gst_element_factory_make ("volume", "volume");
   1.270              gst_bin_add (GST_BIN (bin), volume);
   1.271 -            gst_bin_add (GST_BIN (bin), element);
   1.272 -            if (gst_element_link (volume, element) == FALSE) {
   1.273 -                GST_WARNING_OBJECT (pbm, "Fail to link volume and sink audio: %s", GST_ELEMENT_NAME (element));
   1.274 -                gst_element_set_state (bin, GST_STATE_NULL);
   1.275 -                gst_object_unref (bin);
   1.276 -                return NULL;
   1.277 +            if (gst_element_link (queue, volume) == FALSE) {
   1.278 +                GST_WARNING_OBJECT (pbm, "Fail to link queue and volume");
   1.279 +                gst_element_set_state (volume, GST_STATE_NULL);
   1.280 +                gst_object_unref (volume);
   1.281 +                goto error;
   1.282              }
   1.283 -            pbm->volume_element = volume;
   1.284 -            ret = bin;
   1.285 -        } else {
   1.286 -            ret = element;
   1.287 -            pbm->volume_element = element;
   1.288 +
   1.289 +            prev = volume;
   1.290              g_param_spec_unref (vol_spec);
   1.291          }
   1.292  
   1.293 +        gst_bin_add (GST_BIN (bin), element);
   1.294 +        if (gst_element_link (prev, element) == FALSE) {
   1.295 +           GST_WARNING_OBJECT (pbm, "Fail to link volume and sink audio: %s", GST_ELEMENT_NAME (element));
   1.296 +           if (prev != queue) {
   1.297 +               gst_element_set_state (prev, GST_STATE_NULL);
   1.298 +               gst_object_unref (prev);
   1.299 +           }
   1.300 +           goto error;
   1.301 +        }
   1.302 +
   1.303 +        pbm->volume_element = (prev != queue) ? prev : element;
   1.304          update_volume (pbm);
   1.305      }
   1.306  
   1.307 -    return ret;
   1.308 +    pad = gst_element_get_pad (queue, "sink");
   1.309 +    gst_element_add_pad (bin, gst_ghost_pad_new ("sink", pad));
   1.310 +    gst_object_unref (pad);
   1.311 +
   1.312 +    return bin;
   1.313 +error:
   1.314 +
   1.315 +    gst_element_set_state (bin, GST_STATE_NULL);
   1.316 +    gst_object_unref (bin);
   1.317 +
   1.318 +    return NULL;
   1.319  }
   1.320  
   1.321  static void
   1.322 @@ -798,10 +804,13 @@
   1.323          if ((element = create_element (pbm, factory)) == NULL) {
   1.324              GST_WARNING_OBJECT (pbm, "Could not create an element from %s",
   1.325                  gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
   1.326 +            g_debug ("Could not create an element from %s",
   1.327 +                gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
   1.328 +
   1.329              continue;
   1.330          }
   1.331  
   1.332 -        if (!(gst_bin_add (GST_BIN (user_data), element))) {
   1.333 +        if (!(add_element (GST_PLAY_BIN_MAEMO (user_data), element))) {
   1.334              GST_WARNING_OBJECT (pbm, "Couldn't set %s to READY", GST_ELEMENT_NAME (element));
   1.335              gst_object_unref (element);
   1.336              continue;
   1.337 @@ -817,6 +826,7 @@
   1.338  
   1.339          if (!(sinkpad = find_sink_pad (element))) {
   1.340              GST_WARNING_OBJECT (pbm, "Element %s doesn't have a sink pad", GST_ELEMENT_NAME (element));
   1.341 +            g_debug ("Element %s doesn't have a sink pad", GST_ELEMENT_NAME (element));
   1.342              gst_object_unref (element);
   1.343              continue;
   1.344          }
   1.345 @@ -838,8 +848,6 @@
   1.346              continue;
   1.347          }
   1.348  
   1.349 -
   1.350 -        pbm->sinks = g_slist_append (pbm->sinks, element);
   1.351          linked = TRUE;
   1.352          break;
   1.353      }
   1.354 @@ -874,14 +882,51 @@
   1.355          (pbm->xid != -1) &&
   1.356          (GST_IS_X_OVERLAY (pbm->sink_video))) {
   1.357  
   1.358 +        Display *display;
   1.359          g_object_set (G_OBJECT (pbm->sink_video),
   1.360                        "force-aspect-ratio", TRUE, NULL);
   1.361 +        display = XOpenDisplay(NULL);
   1.362 +        XMapRaised(display, pbm->xid);
   1.363 +        XSync (display, FALSE);
   1.364 +
   1.365          gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (pbm->sink_video),
   1.366                                        pbm->xid);
   1.367      }
   1.368  }
   1.369  
   1.370  static gboolean
   1.371 +add_element (GstPlayBinMaemo *pbm,
   1.372 +             GstElement *child)
   1.373 +{
   1.374 +    if (gst_bin_add (GST_BIN (pbm), child)) {
   1.375 +        pbm->elements = g_list_append (pbm->elements, child);
   1.376 +        return TRUE;
   1.377 +    }
   1.378 +    return FALSE;
   1.379 +}
   1.380 +
   1.381 +static void
   1.382 +clear_elements (GstPlayBinMaemo *pbm)
   1.383 +{
   1.384 +    GList *walk;
   1.385 +
   1.386 +    walk = pbm->elements;
   1.387 +
   1.388 +    for (; walk != NULL; walk = walk->next) {
   1.389 +        GstElement *e = GST_ELEMENT (walk->data);
   1.390 +
   1.391 +        gst_element_set_state (e, GST_STATE_NULL);
   1.392 +        gst_bin_remove (GST_BIN (pbm), e);
   1.393 +    }
   1.394 +
   1.395 +    g_list_free (pbm->elements);
   1.396 +    pbm->elements = NULL;
   1.397 +    pbm->source = NULL;
   1.398 +    pbm->volume_element = NULL;
   1.399 +    pbm->sink_video = NULL;
   1.400 +}
   1.401 +
   1.402 +static gboolean
   1.403  plugin_init(GstPlugin * plugin)
   1.404  {
   1.405  #ifdef ENABLE_NLS