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