1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation; either version 3 7 * of the License, or (at your option) any later version, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 // generated automatically - do not change 21 // find conversion definition on APILookup.txt 22 // implement new conversion functionalities on the wrap.utils pakage 23 24 25 module gstreamer.Registry; 26 27 private import glib.ListG; 28 private import glib.Str; 29 private import gobject.ObjectG; 30 private import gobject.Signals; 31 private import gstreamer.ObjectGst; 32 private import gstreamer.Plugin; 33 private import gstreamer.PluginFeature; 34 private import gstreamer.c.functions; 35 public import gstreamer.c.types; 36 public import gstreamerc.gstreamertypes; 37 private import std.algorithm; 38 39 40 /** 41 * One registry holds the metadata of a set of plugins. 42 * 43 * <emphasis role="bold">Design:</emphasis> 44 * 45 * The #GstRegistry object is a list of plugins and some functions for dealing 46 * with them. Each #GstPlugin is matched 1-1 with a file on disk, and may or may 47 * not be loaded at a given time. 48 * 49 * The primary source, at all times, of plugin information is each plugin file 50 * itself. Thus, if an application wants information about a particular plugin, 51 * or wants to search for a feature that satisfies given criteria, the primary 52 * means of doing so is to load every plugin and look at the resulting 53 * information that is gathered in the default registry. Clearly, this is a time 54 * consuming process, so we cache information in the registry file. The format 55 * and location of the cache file is internal to gstreamer. 56 * 57 * On startup, plugins are searched for in the plugin search path. The following 58 * locations are checked in this order: 59 * 60 * * location from --gst-plugin-path commandline option. 61 * * the GST_PLUGIN_PATH environment variable. 62 * * the GST_PLUGIN_SYSTEM_PATH environment variable. 63 * * default locations (if GST_PLUGIN_SYSTEM_PATH is not set). 64 * Those default locations are: 65 * `$XDG_DATA_HOME/gstreamer-$GST_API_VERSION/plugins/` 66 * and `$prefix/libs/gstreamer-$GST_API_VERSION/`. 67 * [$XDG_DATA_HOME](http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html) defaults to 68 * `$HOME/.local/share`. 69 * 70 * The registry cache file is loaded from 71 * `$XDG_CACHE_HOME/gstreamer-$GST_API_VERSION/registry-$ARCH.bin` 72 * (where $XDG_CACHE_HOME defaults to `$HOME/.cache`) or the file listed in the `GST_REGISTRY` 73 * env var. One reason to change the registry location is for testing. 74 * 75 * For each plugin that is found in the plugin search path, there could be 3 76 * possibilities for cached information: 77 * 78 * * the cache may not contain information about a given file. 79 * * the cache may have stale information. 80 * * the cache may have current information. 81 * 82 * In the first two cases, the plugin is loaded and the cache updated. In 83 * addition to these cases, the cache may have entries for plugins that are not 84 * relevant to the current process. These are marked as not available to the 85 * current process. If the cache is updated for whatever reason, it is marked 86 * dirty. 87 * 88 * A dirty cache is written out at the end of initialization. Each entry is 89 * checked to make sure the information is minimally valid. If not, the entry is 90 * simply dropped. 91 * 92 * ## Implementation notes: 93 * 94 * The "cache" and "registry" are different concepts and can represent 95 * different sets of plugins. For various reasons, at init time, the cache is 96 * stored in the default registry, and plugins not relevant to the current 97 * process are marked with the %GST_PLUGIN_FLAG_CACHED bit. These plugins are 98 * removed at the end of initialization. 99 */ 100 public class Registry : ObjectGst 101 { 102 /** the main Gtk struct */ 103 protected GstRegistry* gstRegistry; 104 105 /** Get the main Gtk struct */ 106 public GstRegistry* getRegistryStruct(bool transferOwnership = false) 107 { 108 if (transferOwnership) 109 ownedRef = false; 110 return gstRegistry; 111 } 112 113 /** the main Gtk struct as a void* */ 114 protected override void* getStruct() 115 { 116 return cast(void*)gstRegistry; 117 } 118 119 /** 120 * Sets our main struct and passes it to the parent class. 121 */ 122 public this (GstRegistry* gstRegistry, bool ownedRef = false) 123 { 124 this.gstRegistry = gstRegistry; 125 super(cast(GstObject*)gstRegistry, ownedRef); 126 } 127 128 129 /** */ 130 public static GType getType() 131 { 132 return gst_registry_get_type(); 133 } 134 135 /** 136 * By default GStreamer will perform scanning and rebuilding of the 137 * registry file using a helper child process. 138 * 139 * Applications might want to disable this behaviour with the 140 * gst_registry_fork_set_enabled() function, in which case new plugins 141 * are scanned (and loaded) into the application process. 142 * 143 * Returns: %TRUE if GStreamer will use the child helper process when 144 * rebuilding the registry. 145 */ 146 public static bool forkIsEnabled() 147 { 148 return gst_registry_fork_is_enabled() != 0; 149 } 150 151 /** 152 * Applications might want to disable/enable spawning of a child helper process 153 * when rebuilding the registry. See gst_registry_fork_is_enabled() for more 154 * information. 155 * 156 * Params: 157 * enabled = whether rebuilding the registry can use a temporary child helper process. 158 */ 159 public static void forkSetEnabled(bool enabled) 160 { 161 gst_registry_fork_set_enabled(enabled); 162 } 163 164 /** 165 * Retrieves the singleton plugin registry. The caller does not own a 166 * reference on the registry, as it is alive as long as GStreamer is 167 * initialized. 168 * 169 * Returns: the #GstRegistry. 170 */ 171 public static Registry get() 172 { 173 auto p = gst_registry_get(); 174 175 if(p is null) 176 { 177 return null; 178 } 179 180 return ObjectG.getDObject!(Registry)(cast(GstRegistry*) p); 181 } 182 183 /** 184 * Add the feature to the registry. The feature-added signal will be emitted. 185 * This function sinks @feature. 186 * 187 * Params: 188 * feature = the feature to add 189 * 190 * Returns: %TRUE on success. 191 * 192 * MT safe. 193 */ 194 public bool addFeature(PluginFeature feature) 195 { 196 return gst_registry_add_feature(gstRegistry, (feature is null) ? null : feature.getPluginFeatureStruct()) != 0; 197 } 198 199 /** 200 * Add the plugin to the registry. The plugin-added signal will be emitted. 201 * This function will sink @plugin. 202 * 203 * Params: 204 * plugin = the plugin to add 205 * 206 * Returns: %TRUE on success. 207 * 208 * MT safe. 209 */ 210 public bool addPlugin(Plugin plugin) 211 { 212 return gst_registry_add_plugin(gstRegistry, (plugin is null) ? null : plugin.getPluginStruct()) != 0; 213 } 214 215 /** 216 * Checks whether a plugin feature by the given name exists in 217 * @registry and whether its version is at least the 218 * version required. 219 * 220 * Params: 221 * featureName = the name of the feature (e.g. "oggdemux") 222 * minMajor = the minimum major version number 223 * minMinor = the minimum minor version number 224 * minMicro = the minimum micro version number 225 * 226 * Returns: %TRUE if the feature could be found and the version is 227 * the same as the required version or newer, and %FALSE otherwise. 228 */ 229 public bool checkFeatureVersion(string featureName, uint minMajor, uint minMinor, uint minMicro) 230 { 231 return gst_registry_check_feature_version(gstRegistry, Str.toStringz(featureName), minMajor, minMinor, minMicro) != 0; 232 } 233 234 /** 235 * Runs a filter against all features of the plugins in the registry 236 * and returns a GList with the results. 237 * If the first flag is set, only the first match is 238 * returned (as a list with a single object). 239 * 240 * Params: 241 * filter = the filter to use 242 * first = only return first match 243 * userData = user data passed to the filter function 244 * 245 * Returns: a #GList of 246 * #GstPluginFeature. Use gst_plugin_feature_list_free() after usage. 247 * 248 * MT safe. 249 */ 250 public ListG featureFilter(GstPluginFeatureFilter filter, bool first, void* userData) 251 { 252 auto p = gst_registry_feature_filter(gstRegistry, filter, first, userData); 253 254 if(p is null) 255 { 256 return null; 257 } 258 259 return new ListG(cast(GList*) p, true); 260 } 261 262 /** 263 * Find the pluginfeature with the given name and type in the registry. 264 * 265 * Params: 266 * name = the pluginfeature name to find 267 * type = the pluginfeature type to find 268 * 269 * Returns: the pluginfeature with the 270 * given name and type or %NULL if the plugin was not 271 * found. gst_object_unref() after usage. 272 * 273 * MT safe. 274 */ 275 public PluginFeature findFeature(string name, GType type) 276 { 277 auto p = gst_registry_find_feature(gstRegistry, Str.toStringz(name), type); 278 279 if(p is null) 280 { 281 return null; 282 } 283 284 return ObjectG.getDObject!(PluginFeature)(cast(GstPluginFeature*) p, true); 285 } 286 287 /** 288 * Find the plugin with the given name in the registry. 289 * The plugin will be reffed; caller is responsible for unreffing. 290 * 291 * Params: 292 * name = the plugin name to find 293 * 294 * Returns: the plugin with the given name 295 * or %NULL if the plugin was not found. gst_object_unref() after 296 * usage. 297 * 298 * MT safe. 299 */ 300 public Plugin findPlugin(string name) 301 { 302 auto p = gst_registry_find_plugin(gstRegistry, Str.toStringz(name)); 303 304 if(p is null) 305 { 306 return null; 307 } 308 309 return ObjectG.getDObject!(Plugin)(cast(GstPlugin*) p, true); 310 } 311 312 /** 313 * Retrieves a #GList of #GstPluginFeature of @type. 314 * 315 * Params: 316 * type = a #GType. 317 * 318 * Returns: a #GList of 319 * #GstPluginFeature of @type. Use gst_plugin_feature_list_free() after use 320 * 321 * MT safe. 322 */ 323 public ListG getFeatureList(GType type) 324 { 325 auto p = gst_registry_get_feature_list(gstRegistry, type); 326 327 if(p is null) 328 { 329 return null; 330 } 331 332 return new ListG(cast(GList*) p, true); 333 } 334 335 /** 336 * Retrieves a #GList of features of the plugin with name @name. 337 * 338 * Params: 339 * name = a plugin name. 340 * 341 * Returns: a #GList of 342 * #GstPluginFeature. Use gst_plugin_feature_list_free() after usage. 343 */ 344 public ListG getFeatureListByPlugin(string name) 345 { 346 auto p = gst_registry_get_feature_list_by_plugin(gstRegistry, Str.toStringz(name)); 347 348 if(p is null) 349 { 350 return null; 351 } 352 353 return new ListG(cast(GList*) p, true); 354 } 355 356 /** 357 * Returns the registry's feature list cookie. This changes 358 * every time a feature is added or removed from the registry. 359 * 360 * Returns: the feature list cookie. 361 */ 362 public uint getFeatureListCookie() 363 { 364 return gst_registry_get_feature_list_cookie(gstRegistry); 365 } 366 367 /** 368 * Get a copy of all plugins registered in the given registry. The refcount 369 * of each element in the list in incremented. 370 * 371 * Returns: a #GList of #GstPlugin. 372 * Use gst_plugin_list_free() after usage. 373 * 374 * MT safe. 375 */ 376 public ListG getPluginList() 377 { 378 auto p = gst_registry_get_plugin_list(gstRegistry); 379 380 if(p is null) 381 { 382 return null; 383 } 384 385 return new ListG(cast(GList*) p, true); 386 } 387 388 /** 389 * Look up a plugin in the given registry with the given filename. 390 * If found, plugin is reffed. 391 * 392 * Params: 393 * filename = the name of the file to look up 394 * 395 * Returns: the #GstPlugin if found, or 396 * %NULL if not. gst_object_unref() after usage. 397 */ 398 public Plugin lookup(string filename) 399 { 400 auto p = gst_registry_lookup(gstRegistry, Str.toStringz(filename)); 401 402 if(p is null) 403 { 404 return null; 405 } 406 407 return ObjectG.getDObject!(Plugin)(cast(GstPlugin*) p, true); 408 } 409 410 /** 411 * Find a #GstPluginFeature with @name in @registry. 412 * 413 * Params: 414 * name = a #GstPluginFeature name 415 * 416 * Returns: a #GstPluginFeature with its refcount incremented, 417 * use gst_object_unref() after usage. 418 * 419 * MT safe. 420 */ 421 public PluginFeature lookupFeature(string name) 422 { 423 auto p = gst_registry_lookup_feature(gstRegistry, Str.toStringz(name)); 424 425 if(p is null) 426 { 427 return null; 428 } 429 430 return ObjectG.getDObject!(PluginFeature)(cast(GstPluginFeature*) p, true); 431 } 432 433 /** 434 * Runs a filter against all plugins in the registry and returns a #GList with 435 * the results. If the first flag is set, only the first match is 436 * returned (as a list with a single object). 437 * Every plugin is reffed; use gst_plugin_list_free() after use, which 438 * will unref again. 439 * 440 * Params: 441 * filter = the filter to use 442 * first = only return first match 443 * userData = user data passed to the filter function 444 * 445 * Returns: a #GList of #GstPlugin. 446 * Use gst_plugin_list_free() after usage. 447 * 448 * MT safe. 449 */ 450 public ListG pluginFilter(GstPluginFilter filter, bool first, void* userData) 451 { 452 auto p = gst_registry_plugin_filter(gstRegistry, filter, first, userData); 453 454 if(p is null) 455 { 456 return null; 457 } 458 459 return new ListG(cast(GList*) p, true); 460 } 461 462 /** 463 * Remove the feature from the registry. 464 * 465 * MT safe. 466 * 467 * Params: 468 * feature = the feature to remove 469 */ 470 public void removeFeature(PluginFeature feature) 471 { 472 gst_registry_remove_feature(gstRegistry, (feature is null) ? null : feature.getPluginFeatureStruct()); 473 } 474 475 /** 476 * Remove the plugin from the registry. 477 * 478 * MT safe. 479 * 480 * Params: 481 * plugin = the plugin to remove 482 */ 483 public void removePlugin(Plugin plugin) 484 { 485 gst_registry_remove_plugin(gstRegistry, (plugin is null) ? null : plugin.getPluginStruct()); 486 } 487 488 /** 489 * Scan the given path for plugins to add to the registry. The syntax of the 490 * path is specific to the registry. 491 * 492 * Params: 493 * path = the path to scan 494 * 495 * Returns: %TRUE if registry changed 496 */ 497 public bool scanPath(string path) 498 { 499 return gst_registry_scan_path(gstRegistry, Str.toStringz(path)) != 0; 500 } 501 502 protected class OnFeatureAddedDelegateWrapper 503 { 504 void delegate(PluginFeature, Registry) dlg; 505 gulong handlerId; 506 507 this(void delegate(PluginFeature, Registry) dlg) 508 { 509 this.dlg = dlg; 510 onFeatureAddedListeners ~= this; 511 } 512 513 void remove(OnFeatureAddedDelegateWrapper source) 514 { 515 foreach(index, wrapper; onFeatureAddedListeners) 516 { 517 if (wrapper.handlerId == source.handlerId) 518 { 519 onFeatureAddedListeners[index] = null; 520 onFeatureAddedListeners = std.algorithm.remove(onFeatureAddedListeners, index); 521 break; 522 } 523 } 524 } 525 } 526 OnFeatureAddedDelegateWrapper[] onFeatureAddedListeners; 527 528 /** 529 * Signals that a feature has been added to the registry (possibly 530 * replacing a previously-added one by the same name) 531 * 532 * Params: 533 * feature = the feature that has been added 534 */ 535 gulong addOnFeatureAdded(void delegate(PluginFeature, Registry) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 536 { 537 auto wrapper = new OnFeatureAddedDelegateWrapper(dlg); 538 wrapper.handlerId = Signals.connectData( 539 this, 540 "feature-added", 541 cast(GCallback)&callBackFeatureAdded, 542 cast(void*)wrapper, 543 cast(GClosureNotify)&callBackFeatureAddedDestroy, 544 connectFlags); 545 return wrapper.handlerId; 546 } 547 548 extern(C) static void callBackFeatureAdded(GstRegistry* registryStruct, GstPluginFeature* feature, OnFeatureAddedDelegateWrapper wrapper) 549 { 550 wrapper.dlg(ObjectG.getDObject!(PluginFeature)(feature), wrapper.outer); 551 } 552 553 extern(C) static void callBackFeatureAddedDestroy(OnFeatureAddedDelegateWrapper wrapper, GClosure* closure) 554 { 555 wrapper.remove(wrapper); 556 } 557 558 protected class OnPluginAddedDelegateWrapper 559 { 560 void delegate(Plugin, Registry) dlg; 561 gulong handlerId; 562 563 this(void delegate(Plugin, Registry) dlg) 564 { 565 this.dlg = dlg; 566 onPluginAddedListeners ~= this; 567 } 568 569 void remove(OnPluginAddedDelegateWrapper source) 570 { 571 foreach(index, wrapper; onPluginAddedListeners) 572 { 573 if (wrapper.handlerId == source.handlerId) 574 { 575 onPluginAddedListeners[index] = null; 576 onPluginAddedListeners = std.algorithm.remove(onPluginAddedListeners, index); 577 break; 578 } 579 } 580 } 581 } 582 OnPluginAddedDelegateWrapper[] onPluginAddedListeners; 583 584 /** 585 * Signals that a plugin has been added to the registry (possibly 586 * replacing a previously-added one by the same name) 587 * 588 * Params: 589 * plugin = the plugin that has been added 590 */ 591 gulong addOnPluginAdded(void delegate(Plugin, Registry) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 592 { 593 auto wrapper = new OnPluginAddedDelegateWrapper(dlg); 594 wrapper.handlerId = Signals.connectData( 595 this, 596 "plugin-added", 597 cast(GCallback)&callBackPluginAdded, 598 cast(void*)wrapper, 599 cast(GClosureNotify)&callBackPluginAddedDestroy, 600 connectFlags); 601 return wrapper.handlerId; 602 } 603 604 extern(C) static void callBackPluginAdded(GstRegistry* registryStruct, GstPlugin* plugin, OnPluginAddedDelegateWrapper wrapper) 605 { 606 wrapper.dlg(ObjectG.getDObject!(Plugin)(plugin), wrapper.outer); 607 } 608 609 extern(C) static void callBackPluginAddedDestroy(OnPluginAddedDelegateWrapper wrapper, GClosure* closure) 610 { 611 wrapper.remove(wrapper); 612 } 613 }