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