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 protected override void setStruct(GObject* obj) 120 { 121 gstRegistry = cast(GstRegistry*)obj; 122 super.setStruct(obj); 123 } 124 125 /** 126 * Sets our main struct and passes it to the parent class. 127 */ 128 public this (GstRegistry* gstRegistry, bool ownedRef = false) 129 { 130 this.gstRegistry = gstRegistry; 131 super(cast(GstObject*)gstRegistry, ownedRef); 132 } 133 134 135 /** */ 136 public static GType getType() 137 { 138 return gst_registry_get_type(); 139 } 140 141 /** 142 * By default GStreamer will perform scanning and rebuilding of the 143 * registry file using a helper child process. 144 * 145 * Applications might want to disable this behaviour with the 146 * gst_registry_fork_set_enabled() function, in which case new plugins 147 * are scanned (and loaded) into the application process. 148 * 149 * Returns: %TRUE if GStreamer will use the child helper process when 150 * rebuilding the registry. 151 */ 152 public static bool forkIsEnabled() 153 { 154 return gst_registry_fork_is_enabled() != 0; 155 } 156 157 /** 158 * Applications might want to disable/enable spawning of a child helper process 159 * when rebuilding the registry. See gst_registry_fork_is_enabled() for more 160 * information. 161 * 162 * Params: 163 * enabled = whether rebuilding the registry can use a temporary child helper process. 164 */ 165 public static void forkSetEnabled(bool enabled) 166 { 167 gst_registry_fork_set_enabled(enabled); 168 } 169 170 /** 171 * Retrieves the singleton plugin registry. The caller does not own a 172 * reference on the registry, as it is alive as long as GStreamer is 173 * initialized. 174 * 175 * Returns: the #GstRegistry. 176 */ 177 public static Registry get() 178 { 179 auto p = gst_registry_get(); 180 181 if(p is null) 182 { 183 return null; 184 } 185 186 return ObjectG.getDObject!(Registry)(cast(GstRegistry*) p); 187 } 188 189 /** 190 * Add the feature to the registry. The feature-added signal will be emitted. 191 * This function sinks @feature. 192 * 193 * Params: 194 * feature = the feature to add 195 * 196 * Returns: %TRUE on success. 197 * 198 * MT safe. 199 */ 200 public bool addFeature(PluginFeature feature) 201 { 202 return gst_registry_add_feature(gstRegistry, (feature is null) ? null : feature.getPluginFeatureStruct()) != 0; 203 } 204 205 /** 206 * Add the plugin to the registry. The plugin-added signal will be emitted. 207 * This function will sink @plugin. 208 * 209 * Params: 210 * plugin = the plugin to add 211 * 212 * Returns: %TRUE on success. 213 * 214 * MT safe. 215 */ 216 public bool addPlugin(Plugin plugin) 217 { 218 return gst_registry_add_plugin(gstRegistry, (plugin is null) ? null : plugin.getPluginStruct()) != 0; 219 } 220 221 /** 222 * Checks whether a plugin feature by the given name exists in 223 * @registry and whether its version is at least the 224 * version required. 225 * 226 * Params: 227 * featureName = the name of the feature (e.g. "oggdemux") 228 * minMajor = the minimum major version number 229 * minMinor = the minimum minor version number 230 * minMicro = the minimum micro version number 231 * 232 * Returns: %TRUE if the feature could be found and the version is 233 * the same as the required version or newer, and %FALSE otherwise. 234 */ 235 public bool checkFeatureVersion(string featureName, uint minMajor, uint minMinor, uint minMicro) 236 { 237 return gst_registry_check_feature_version(gstRegistry, Str.toStringz(featureName), minMajor, minMinor, minMicro) != 0; 238 } 239 240 /** 241 * Runs a filter against all features of the plugins in the registry 242 * and returns a GList with the results. 243 * If the first flag is set, only the first match is 244 * returned (as a list with a single object). 245 * 246 * Params: 247 * filter = the filter to use 248 * first = only return first match 249 * userData = user data passed to the filter function 250 * 251 * Returns: a #GList of 252 * #GstPluginFeature. Use gst_plugin_feature_list_free() after usage. 253 * 254 * MT safe. 255 */ 256 public ListG featureFilter(GstPluginFeatureFilter filter, bool first, void* userData) 257 { 258 auto p = gst_registry_feature_filter(gstRegistry, filter, first, userData); 259 260 if(p is null) 261 { 262 return null; 263 } 264 265 return new ListG(cast(GList*) p, true); 266 } 267 268 /** 269 * Find the pluginfeature with the given name and type in the registry. 270 * 271 * Params: 272 * name = the pluginfeature name to find 273 * type = the pluginfeature type to find 274 * 275 * Returns: the pluginfeature with the 276 * given name and type or %NULL if the plugin was not 277 * found. gst_object_unref() after usage. 278 * 279 * MT safe. 280 */ 281 public PluginFeature findFeature(string name, GType type) 282 { 283 auto p = gst_registry_find_feature(gstRegistry, Str.toStringz(name), type); 284 285 if(p is null) 286 { 287 return null; 288 } 289 290 return ObjectG.getDObject!(PluginFeature)(cast(GstPluginFeature*) p, true); 291 } 292 293 /** 294 * Find the plugin with the given name in the registry. 295 * The plugin will be reffed; caller is responsible for unreffing. 296 * 297 * Params: 298 * name = the plugin name to find 299 * 300 * Returns: the plugin with the given name 301 * or %NULL if the plugin was not found. gst_object_unref() after 302 * usage. 303 * 304 * MT safe. 305 */ 306 public Plugin findPlugin(string name) 307 { 308 auto p = gst_registry_find_plugin(gstRegistry, Str.toStringz(name)); 309 310 if(p is null) 311 { 312 return null; 313 } 314 315 return ObjectG.getDObject!(Plugin)(cast(GstPlugin*) p, true); 316 } 317 318 /** 319 * Retrieves a #GList of #GstPluginFeature of @type. 320 * 321 * Params: 322 * type = a #GType. 323 * 324 * Returns: a #GList of 325 * #GstPluginFeature of @type. Use gst_plugin_feature_list_free() after use 326 * 327 * MT safe. 328 */ 329 public ListG getFeatureList(GType type) 330 { 331 auto p = gst_registry_get_feature_list(gstRegistry, type); 332 333 if(p is null) 334 { 335 return null; 336 } 337 338 return new ListG(cast(GList*) p, true); 339 } 340 341 /** 342 * Retrieves a #GList of features of the plugin with name @name. 343 * 344 * Params: 345 * name = a plugin name. 346 * 347 * Returns: a #GList of 348 * #GstPluginFeature. Use gst_plugin_feature_list_free() after usage. 349 */ 350 public ListG getFeatureListByPlugin(string name) 351 { 352 auto p = gst_registry_get_feature_list_by_plugin(gstRegistry, Str.toStringz(name)); 353 354 if(p is null) 355 { 356 return null; 357 } 358 359 return new ListG(cast(GList*) p, true); 360 } 361 362 /** 363 * Returns the registry's feature list cookie. This changes 364 * every time a feature is added or removed from the registry. 365 * 366 * Returns: the feature list cookie. 367 */ 368 public uint getFeatureListCookie() 369 { 370 return gst_registry_get_feature_list_cookie(gstRegistry); 371 } 372 373 /** 374 * Get a copy of all plugins registered in the given registry. The refcount 375 * of each element in the list in incremented. 376 * 377 * Returns: a #GList of #GstPlugin. 378 * Use gst_plugin_list_free() after usage. 379 * 380 * MT safe. 381 */ 382 public ListG getPluginList() 383 { 384 auto p = gst_registry_get_plugin_list(gstRegistry); 385 386 if(p is null) 387 { 388 return null; 389 } 390 391 return new ListG(cast(GList*) p, true); 392 } 393 394 /** 395 * Look up a plugin in the given registry with the given filename. 396 * If found, plugin is reffed. 397 * 398 * Params: 399 * filename = the name of the file to look up 400 * 401 * Returns: the #GstPlugin if found, or 402 * %NULL if not. gst_object_unref() after usage. 403 */ 404 public Plugin lookup(string filename) 405 { 406 auto p = gst_registry_lookup(gstRegistry, Str.toStringz(filename)); 407 408 if(p is null) 409 { 410 return null; 411 } 412 413 return ObjectG.getDObject!(Plugin)(cast(GstPlugin*) p, true); 414 } 415 416 /** 417 * Find a #GstPluginFeature with @name in @registry. 418 * 419 * Params: 420 * name = a #GstPluginFeature name 421 * 422 * Returns: a #GstPluginFeature with its refcount incremented, 423 * use gst_object_unref() after usage. 424 * 425 * MT safe. 426 */ 427 public PluginFeature lookupFeature(string name) 428 { 429 auto p = gst_registry_lookup_feature(gstRegistry, Str.toStringz(name)); 430 431 if(p is null) 432 { 433 return null; 434 } 435 436 return ObjectG.getDObject!(PluginFeature)(cast(GstPluginFeature*) p, true); 437 } 438 439 /** 440 * Runs a filter against all plugins in the registry and returns a #GList with 441 * the results. If the first flag is set, only the first match is 442 * returned (as a list with a single object). 443 * Every plugin is reffed; use gst_plugin_list_free() after use, which 444 * will unref again. 445 * 446 * Params: 447 * filter = the filter to use 448 * first = only return first match 449 * userData = user data passed to the filter function 450 * 451 * Returns: a #GList of #GstPlugin. 452 * Use gst_plugin_list_free() after usage. 453 * 454 * MT safe. 455 */ 456 public ListG pluginFilter(GstPluginFilter filter, bool first, void* userData) 457 { 458 auto p = gst_registry_plugin_filter(gstRegistry, filter, first, userData); 459 460 if(p is null) 461 { 462 return null; 463 } 464 465 return new ListG(cast(GList*) p, true); 466 } 467 468 /** 469 * Remove the feature from the registry. 470 * 471 * MT safe. 472 * 473 * Params: 474 * feature = the feature to remove 475 */ 476 public void removeFeature(PluginFeature feature) 477 { 478 gst_registry_remove_feature(gstRegistry, (feature is null) ? null : feature.getPluginFeatureStruct()); 479 } 480 481 /** 482 * Remove the plugin from the registry. 483 * 484 * MT safe. 485 * 486 * Params: 487 * plugin = the plugin to remove 488 */ 489 public void removePlugin(Plugin plugin) 490 { 491 gst_registry_remove_plugin(gstRegistry, (plugin is null) ? null : plugin.getPluginStruct()); 492 } 493 494 /** 495 * Scan the given path for plugins to add to the registry. The syntax of the 496 * path is specific to the registry. 497 * 498 * Params: 499 * path = the path to scan 500 * 501 * Returns: %TRUE if registry changed 502 */ 503 public bool scanPath(string path) 504 { 505 return gst_registry_scan_path(gstRegistry, Str.toStringz(path)) != 0; 506 } 507 508 protected class OnFeatureAddedDelegateWrapper 509 { 510 void delegate(PluginFeature, Registry) dlg; 511 gulong handlerId; 512 513 this(void delegate(PluginFeature, Registry) dlg) 514 { 515 this.dlg = dlg; 516 onFeatureAddedListeners ~= this; 517 } 518 519 void remove(OnFeatureAddedDelegateWrapper source) 520 { 521 foreach(index, wrapper; onFeatureAddedListeners) 522 { 523 if (wrapper.handlerId == source.handlerId) 524 { 525 onFeatureAddedListeners[index] = null; 526 onFeatureAddedListeners = std.algorithm.remove(onFeatureAddedListeners, index); 527 break; 528 } 529 } 530 } 531 } 532 OnFeatureAddedDelegateWrapper[] onFeatureAddedListeners; 533 534 /** 535 * Signals that a feature has been added to the registry (possibly 536 * replacing a previously-added one by the same name) 537 * 538 * Params: 539 * feature = the feature that has been added 540 */ 541 gulong addOnFeatureAdded(void delegate(PluginFeature, Registry) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 542 { 543 auto wrapper = new OnFeatureAddedDelegateWrapper(dlg); 544 wrapper.handlerId = Signals.connectData( 545 this, 546 "feature-added", 547 cast(GCallback)&callBackFeatureAdded, 548 cast(void*)wrapper, 549 cast(GClosureNotify)&callBackFeatureAddedDestroy, 550 connectFlags); 551 return wrapper.handlerId; 552 } 553 554 extern(C) static void callBackFeatureAdded(GstRegistry* registryStruct, GstPluginFeature* feature, OnFeatureAddedDelegateWrapper wrapper) 555 { 556 wrapper.dlg(ObjectG.getDObject!(PluginFeature)(feature), wrapper.outer); 557 } 558 559 extern(C) static void callBackFeatureAddedDestroy(OnFeatureAddedDelegateWrapper wrapper, GClosure* closure) 560 { 561 wrapper.remove(wrapper); 562 } 563 564 protected class OnPluginAddedDelegateWrapper 565 { 566 void delegate(Plugin, Registry) dlg; 567 gulong handlerId; 568 569 this(void delegate(Plugin, Registry) dlg) 570 { 571 this.dlg = dlg; 572 onPluginAddedListeners ~= this; 573 } 574 575 void remove(OnPluginAddedDelegateWrapper source) 576 { 577 foreach(index, wrapper; onPluginAddedListeners) 578 { 579 if (wrapper.handlerId == source.handlerId) 580 { 581 onPluginAddedListeners[index] = null; 582 onPluginAddedListeners = std.algorithm.remove(onPluginAddedListeners, index); 583 break; 584 } 585 } 586 } 587 } 588 OnPluginAddedDelegateWrapper[] onPluginAddedListeners; 589 590 /** 591 * Signals that a plugin has been added to the registry (possibly 592 * replacing a previously-added one by the same name) 593 * 594 * Params: 595 * plugin = the plugin that has been added 596 */ 597 gulong addOnPluginAdded(void delegate(Plugin, Registry) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 598 { 599 auto wrapper = new OnPluginAddedDelegateWrapper(dlg); 600 wrapper.handlerId = Signals.connectData( 601 this, 602 "plugin-added", 603 cast(GCallback)&callBackPluginAdded, 604 cast(void*)wrapper, 605 cast(GClosureNotify)&callBackPluginAddedDestroy, 606 connectFlags); 607 return wrapper.handlerId; 608 } 609 610 extern(C) static void callBackPluginAdded(GstRegistry* registryStruct, GstPlugin* plugin, OnPluginAddedDelegateWrapper wrapper) 611 { 612 wrapper.dlg(ObjectG.getDObject!(Plugin)(plugin), wrapper.outer); 613 } 614 615 extern(C) static void callBackPluginAddedDestroy(OnPluginAddedDelegateWrapper wrapper, GClosure* closure) 616 { 617 wrapper.remove(wrapper); 618 } 619 }