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.Clock; 26 27 private import gobject.ObjectG; 28 private import gobject.Signals; 29 private import gstreamer.ObjectGst; 30 private import gstreamerc.gstreamer; 31 public import gstreamerc.gstreamertypes; 32 private import std.algorithm; 33 34 35 /** 36 * GStreamer uses a global clock to synchronize the plugins in a pipeline. 37 * Different clock implementations are possible by implementing this abstract 38 * base class or, more conveniently, by subclassing #GstSystemClock. 39 * 40 * The #GstClock returns a monotonically increasing time with the method 41 * gst_clock_get_time(). Its accuracy and base time depend on the specific 42 * clock implementation but time is always expressed in nanoseconds. Since the 43 * baseline of the clock is undefined, the clock time returned is not 44 * meaningful in itself, what matters are the deltas between two clock times. 45 * The time returned by a clock is called the absolute time. 46 * 47 * The pipeline uses the clock to calculate the running time. Usually all 48 * renderers synchronize to the global clock using the buffer timestamps, the 49 * newsegment events and the element's base time, see #GstPipeline. 50 * 51 * A clock implementation can support periodic and single shot clock 52 * notifications both synchronous and asynchronous. 53 * 54 * One first needs to create a #GstClockID for the periodic or single shot 55 * notification using gst_clock_new_single_shot_id() or 56 * gst_clock_new_periodic_id(). 57 * 58 * To perform a blocking wait for the specific time of the #GstClockID use the 59 * gst_clock_id_wait(). To receive a callback when the specific time is reached 60 * in the clock use gst_clock_id_wait_async(). Both these calls can be 61 * interrupted with the gst_clock_id_unschedule() call. If the blocking wait is 62 * unscheduled a return value of #GST_CLOCK_UNSCHEDULED is returned. 63 * 64 * Periodic callbacks scheduled async will be repeatedly called automatically 65 * until it is unscheduled. To schedule a sync periodic callback, 66 * gst_clock_id_wait() should be called repeatedly. 67 * 68 * The async callbacks can happen from any thread, either provided by the core 69 * or from a streaming thread. The application should be prepared for this. 70 * 71 * A #GstClockID that has been unscheduled cannot be used again for any wait 72 * operation, a new #GstClockID should be created and the old unscheduled one 73 * should be destroyed with gst_clock_id_unref(). 74 * 75 * It is possible to perform a blocking wait on the same #GstClockID from 76 * multiple threads. However, registering the same #GstClockID for multiple 77 * async notifications is not possible, the callback will only be called for 78 * the thread registering the entry last. 79 * 80 * None of the wait operations unref the #GstClockID, the owner is responsible 81 * for unreffing the ids itself. This holds for both periodic and single shot 82 * notifications. The reason being that the owner of the #GstClockID has to 83 * keep a handle to the #GstClockID to unblock the wait on FLUSHING events or 84 * state changes and if the entry would be unreffed automatically, the handle 85 * might become invalid without any notification. 86 * 87 * These clock operations do not operate on the running time, so the callbacks 88 * will also occur when not in PLAYING state as if the clock just keeps on 89 * running. Some clocks however do not progress when the element that provided 90 * the clock is not PLAYING. 91 * 92 * When a clock has the #GST_CLOCK_FLAG_CAN_SET_MASTER flag set, it can be 93 * slaved to another #GstClock with the gst_clock_set_master(). The clock will 94 * then automatically be synchronized to this master clock by repeatedly 95 * sampling the master clock and the slave clock and recalibrating the slave 96 * clock with gst_clock_set_calibration(). This feature is mostly useful for 97 * plugins that have an internal clock but must operate with another clock 98 * selected by the #GstPipeline. They can track the offset and rate difference 99 * of their internal clock relative to the master clock by using the 100 * gst_clock_get_calibration() function. 101 * 102 * The master/slave synchronisation can be tuned with the #GstClock:timeout, 103 * #GstClock:window-size and #GstClock:window-threshold properties. 104 * The #GstClock:timeout property defines the interval to sample the master 105 * clock and run the calibration functions. #GstClock:window-size defines the 106 * number of samples to use when calibrating and #GstClock:window-threshold 107 * defines the minimum number of samples before the calibration is performed. 108 */ 109 public class Clock : ObjectGst 110 { 111 /** the main Gtk struct */ 112 protected GstClock* gstClock; 113 114 /** Get the main Gtk struct */ 115 public GstClock* getClockStruct(bool transferOwnership = false) 116 { 117 if (transferOwnership) 118 ownedRef = false; 119 return gstClock; 120 } 121 122 /** the main Gtk struct as a void* */ 123 protected override void* getStruct() 124 { 125 return cast(void*)gstClock; 126 } 127 128 protected override void setStruct(GObject* obj) 129 { 130 gstClock = cast(GstClock*)obj; 131 super.setStruct(obj); 132 } 133 134 /** 135 * Sets our main struct and passes it to the parent class. 136 */ 137 public this (GstClock* gstClock, bool ownedRef = false) 138 { 139 this.gstClock = gstClock; 140 super(cast(GstObject*)gstClock, ownedRef); 141 } 142 143 144 /** */ 145 public static GType getType() 146 { 147 return gst_clock_get_type(); 148 } 149 150 /** 151 * Compares the two #GstClockID instances. This function can be used 152 * as a GCompareFunc when sorting ids. 153 * 154 * Params: 155 * id1 = A #GstClockID 156 * id2 = A #GstClockID to compare with 157 * 158 * Returns: negative value if a < b; zero if a = b; positive value if a > b 159 * 160 * MT safe. 161 */ 162 public static int idCompareFunc(void* id1, void* id2) 163 { 164 return gst_clock_id_compare_func(id1, id2); 165 } 166 167 /** 168 * Get the time of the clock ID 169 * 170 * Params: 171 * id = The #GstClockID to query 172 * 173 * Returns: the time of the given clock id. 174 * 175 * MT safe. 176 */ 177 public static GstClockTime idGetTime(GstClockID id) 178 { 179 return gst_clock_id_get_time(id); 180 } 181 182 /** 183 * Increase the refcount of given @id. 184 * 185 * Params: 186 * id = The #GstClockID to ref 187 * 188 * Returns: The same #GstClockID with increased refcount. 189 * 190 * MT safe. 191 */ 192 public static GstClockID idRef(GstClockID id) 193 { 194 return gst_clock_id_ref(id); 195 } 196 197 /** 198 * Unref given @id. When the refcount reaches 0 the 199 * #GstClockID will be freed. 200 * 201 * MT safe. 202 * 203 * Params: 204 * id = The #GstClockID to unref 205 */ 206 public static void idUnref(GstClockID id) 207 { 208 gst_clock_id_unref(id); 209 } 210 211 /** 212 * Cancel an outstanding request with @id. This can either 213 * be an outstanding async notification or a pending sync notification. 214 * After this call, @id cannot be used anymore to receive sync or 215 * async notifications, you need to create a new #GstClockID. 216 * 217 * MT safe. 218 * 219 * Params: 220 * id = The id to unschedule 221 */ 222 public static void idUnschedule(GstClockID id) 223 { 224 gst_clock_id_unschedule(id); 225 } 226 227 /** 228 * Perform a blocking wait on @id. 229 * @id should have been created with gst_clock_new_single_shot_id() 230 * or gst_clock_new_periodic_id() and should not have been unscheduled 231 * with a call to gst_clock_id_unschedule(). 232 * 233 * If the @jitter argument is not %NULL and this function returns #GST_CLOCK_OK 234 * or #GST_CLOCK_EARLY, it will contain the difference 235 * against the clock and the time of @id when this method was 236 * called. 237 * Positive values indicate how late @id was relative to the clock 238 * (in which case this function will return #GST_CLOCK_EARLY). 239 * Negative values indicate how much time was spent waiting on the clock 240 * before this function returned. 241 * 242 * Params: 243 * id = The #GstClockID to wait on 244 * jitter = a pointer that will contain the jitter, 245 * can be %NULL. 246 * 247 * Returns: the result of the blocking wait. #GST_CLOCK_EARLY will be returned 248 * if the current clock time is past the time of @id, #GST_CLOCK_OK if 249 * @id was scheduled in time. #GST_CLOCK_UNSCHEDULED if @id was 250 * unscheduled with gst_clock_id_unschedule(). 251 * 252 * MT safe. 253 */ 254 public static GstClockReturn idWait(GstClockID id, out GstClockTimeDiff jitter) 255 { 256 return gst_clock_id_wait(id, &jitter); 257 } 258 259 /** 260 * Register a callback on the given #GstClockID @id with the given 261 * function and user_data. When passing a #GstClockID with an invalid 262 * time to this function, the callback will be called immediately 263 * with a time set to GST_CLOCK_TIME_NONE. The callback will 264 * be called when the time of @id has been reached. 265 * 266 * The callback @func can be invoked from any thread, either provided by the 267 * core or from a streaming thread. The application should be prepared for this. 268 * 269 * Params: 270 * id = a #GstClockID to wait on 271 * func = The callback function 272 * userData = User data passed in the callback 273 * destroyData = #GDestroyNotify for user_data 274 * 275 * Returns: the result of the non blocking wait. 276 * 277 * MT safe. 278 */ 279 public static GstClockReturn idWaitAsync(GstClockID id, GstClockCallback func, void* userData, GDestroyNotify destroyData) 280 { 281 return gst_clock_id_wait_async(id, func, userData, destroyData); 282 } 283 284 /** 285 * The time @master of the master clock and the time @slave of the slave 286 * clock are added to the list of observations. If enough observations 287 * are available, a linear regression algorithm is run on the 288 * observations and @clock is recalibrated. 289 * 290 * If this functions returns %TRUE, @r_squared will contain the 291 * correlation coefficient of the interpolation. A value of 1.0 292 * means a perfect regression was performed. This value can 293 * be used to control the sampling frequency of the master and slave 294 * clocks. 295 * 296 * Params: 297 * slave = a time on the slave 298 * master = a time on the master 299 * rSquared = a pointer to hold the result 300 * 301 * Returns: %TRUE if enough observations were added to run the 302 * regression algorithm. 303 * 304 * MT safe. 305 */ 306 public bool addObservation(GstClockTime slave, GstClockTime master, out double rSquared) 307 { 308 return gst_clock_add_observation(gstClock, slave, master, &rSquared) != 0; 309 } 310 311 /** 312 * Add a clock observation to the internal slaving algorithm the same as 313 * gst_clock_add_observation(), and return the result of the master clock 314 * estimation, without updating the internal calibration. 315 * 316 * The caller can then take the results and call gst_clock_set_calibration() 317 * with the values, or some modified version of them. 318 * 319 * Params: 320 * slave = a time on the slave 321 * master = a time on the master 322 * rSquared = a pointer to hold the result 323 * internal = a location to store the internal time 324 * external = a location to store the external time 325 * rateNum = a location to store the rate numerator 326 * rateDenom = a location to store the rate denominator 327 * 328 * Since: 1.6 329 */ 330 public bool addObservationUnapplied(GstClockTime slave, GstClockTime master, out double rSquared, out GstClockTime internal, out GstClockTime external, out GstClockTime rateNum, out GstClockTime rateDenom) 331 { 332 return gst_clock_add_observation_unapplied(gstClock, slave, master, &rSquared, &internal, &external, &rateNum, &rateDenom) != 0; 333 } 334 335 /** 336 * Converts the given @internal clock time to the external time, adjusting for the 337 * rate and reference time set with gst_clock_set_calibration() and making sure 338 * that the returned time is increasing. This function should be called with the 339 * clock's OBJECT_LOCK held and is mainly used by clock subclasses. 340 * 341 * This function is the reverse of gst_clock_unadjust_unlocked(). 342 * 343 * Params: 344 * internal = a clock time 345 * 346 * Returns: the converted time of the clock. 347 */ 348 public GstClockTime adjustUnlocked(GstClockTime internal) 349 { 350 return gst_clock_adjust_unlocked(gstClock, internal); 351 } 352 353 /** 354 * Converts the given @internal_target clock time to the external time, 355 * using the passed calibration parameters. This function performs the 356 * same calculation as gst_clock_adjust_unlocked() when called using the 357 * current calibration parameters, but doesn't ensure a monotonically 358 * increasing result as gst_clock_adjust_unlocked() does. 359 * 360 * Note: The @clock parameter is unused and can be NULL 361 * 362 * Params: 363 * internalTarget = a clock time 364 * cinternal = a reference internal time 365 * cexternal = a reference external time 366 * cnum = the numerator of the rate of the clock relative to its 367 * internal time 368 * cdenom = the denominator of the rate of the clock 369 * 370 * Returns: the converted time of the clock. 371 * 372 * Since: 1.6 373 */ 374 public GstClockTime adjustWithCalibration(GstClockTime internalTarget, GstClockTime cinternal, GstClockTime cexternal, GstClockTime cnum, GstClockTime cdenom) 375 { 376 return gst_clock_adjust_with_calibration(gstClock, internalTarget, cinternal, cexternal, cnum, cdenom); 377 } 378 379 /** 380 * Gets the internal rate and reference time of @clock. See 381 * gst_clock_set_calibration() for more information. 382 * 383 * @internal, @external, @rate_num, and @rate_denom can be left %NULL if the 384 * caller is not interested in the values. 385 * 386 * MT safe. 387 * 388 * Params: 389 * internal = a location to store the internal time 390 * external = a location to store the external time 391 * rateNum = a location to store the rate numerator 392 * rateDenom = a location to store the rate denominator 393 */ 394 public void getCalibration(out GstClockTime internal, out GstClockTime external, out GstClockTime rateNum, out GstClockTime rateDenom) 395 { 396 gst_clock_get_calibration(gstClock, &internal, &external, &rateNum, &rateDenom); 397 } 398 399 /** 400 * Gets the current internal time of the given clock. The time is returned 401 * unadjusted for the offset and the rate. 402 * 403 * Returns: the internal time of the clock. Or GST_CLOCK_TIME_NONE when 404 * given invalid input. 405 * 406 * MT safe. 407 */ 408 public GstClockTime getInternalTime() 409 { 410 return gst_clock_get_internal_time(gstClock); 411 } 412 413 /** 414 * Get the master clock that @clock is slaved to or %NULL when the clock is 415 * not slaved to any master clock. 416 * 417 * Returns: a master #GstClock or %NULL 418 * when this clock is not slaved to a master clock. Unref after 419 * usage. 420 * 421 * MT safe. 422 */ 423 public Clock getMaster() 424 { 425 auto p = gst_clock_get_master(gstClock); 426 427 if(p is null) 428 { 429 return null; 430 } 431 432 return ObjectG.getDObject!(Clock)(cast(GstClock*) p, true); 433 } 434 435 /** 436 * Get the accuracy of the clock. The accuracy of the clock is the granularity 437 * of the values returned by gst_clock_get_time(). 438 * 439 * Returns: the resolution of the clock in units of #GstClockTime. 440 * 441 * MT safe. 442 */ 443 public GstClockTime getResolution() 444 { 445 return gst_clock_get_resolution(gstClock); 446 } 447 448 /** 449 * Gets the current time of the given clock. The time is always 450 * monotonically increasing and adjusted according to the current 451 * offset and rate. 452 * 453 * Returns: the time of the clock. Or GST_CLOCK_TIME_NONE when 454 * given invalid input. 455 * 456 * MT safe. 457 */ 458 public GstClockTime getTime() 459 { 460 return gst_clock_get_time(gstClock); 461 } 462 463 /** 464 * Get the amount of time that master and slave clocks are sampled. 465 * 466 * Returns: the interval between samples. 467 */ 468 public GstClockTime getTimeout() 469 { 470 return gst_clock_get_timeout(gstClock); 471 } 472 473 /** 474 * Checks if the clock is currently synced. 475 * 476 * This returns if GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC is not set on the clock. 477 * 478 * Returns: %TRUE if the clock is currently synced 479 * 480 * Since: 1.6 481 */ 482 public bool isSynced() 483 { 484 return gst_clock_is_synced(gstClock) != 0; 485 } 486 487 /** 488 * Get an ID from @clock to trigger a periodic notification. 489 * The periodic notifications will start at time @start_time and 490 * will then be fired with the given @interval. @id should be unreffed 491 * after usage. 492 * 493 * Free-function: gst_clock_id_unref 494 * 495 * Params: 496 * startTime = the requested start time 497 * interval = the requested interval 498 * 499 * Returns: a #GstClockID that can be used to request the 500 * time notification. 501 * 502 * MT safe. 503 */ 504 public GstClockID newPeriodicId(GstClockTime startTime, GstClockTime interval) 505 { 506 return gst_clock_new_periodic_id(gstClock, startTime, interval); 507 } 508 509 /** 510 * Get a #GstClockID from @clock to trigger a single shot 511 * notification at the requested time. The single shot id should be 512 * unreffed after usage. 513 * 514 * Free-function: gst_clock_id_unref 515 * 516 * Params: 517 * time = the requested time 518 * 519 * Returns: a #GstClockID that can be used to request the 520 * time notification. 521 * 522 * MT safe. 523 */ 524 public GstClockID newSingleShotId(GstClockTime time) 525 { 526 return gst_clock_new_single_shot_id(gstClock, time); 527 } 528 529 /** 530 * Reinitializes the provided periodic @id to the provided start time and 531 * interval. Does not modify the reference count. 532 * 533 * Params: 534 * id = a #GstClockID 535 * startTime = the requested start time 536 * interval = the requested interval 537 * 538 * Returns: %TRUE if the GstClockID could be reinitialized to the provided 539 * @time, else %FALSE. 540 */ 541 public bool periodicIdReinit(GstClockID id, GstClockTime startTime, GstClockTime interval) 542 { 543 return gst_clock_periodic_id_reinit(gstClock, id, startTime, interval) != 0; 544 } 545 546 /** 547 * Adjusts the rate and time of @clock. A rate of 1/1 is the normal speed of 548 * the clock. Values bigger than 1/1 make the clock go faster. 549 * 550 * @internal and @external are calibration parameters that arrange that 551 * gst_clock_get_time() should have been @external at internal time @internal. 552 * This internal time should not be in the future; that is, it should be less 553 * than the value of gst_clock_get_internal_time() when this function is called. 554 * 555 * Subsequent calls to gst_clock_get_time() will return clock times computed as 556 * follows: 557 * 558 * |[ 559 * time = (internal_time - internal) * rate_num / rate_denom + external 560 * ]| 561 * 562 * This formula is implemented in gst_clock_adjust_unlocked(). Of course, it 563 * tries to do the integer arithmetic as precisely as possible. 564 * 565 * Note that gst_clock_get_time() always returns increasing values so when you 566 * move the clock backwards, gst_clock_get_time() will report the previous value 567 * until the clock catches up. 568 * 569 * MT safe. 570 * 571 * Params: 572 * internal = a reference internal time 573 * external = a reference external time 574 * rateNum = the numerator of the rate of the clock relative to its 575 * internal time 576 * rateDenom = the denominator of the rate of the clock 577 */ 578 public void setCalibration(GstClockTime internal, GstClockTime external, GstClockTime rateNum, GstClockTime rateDenom) 579 { 580 gst_clock_set_calibration(gstClock, internal, external, rateNum, rateDenom); 581 } 582 583 /** 584 * Set @master as the master clock for @clock. @clock will be automatically 585 * calibrated so that gst_clock_get_time() reports the same time as the 586 * master clock. 587 * 588 * A clock provider that slaves its clock to a master can get the current 589 * calibration values with gst_clock_get_calibration(). 590 * 591 * @master can be %NULL in which case @clock will not be slaved anymore. It will 592 * however keep reporting its time adjusted with the last configured rate 593 * and time offsets. 594 * 595 * Params: 596 * master = a master #GstClock 597 * 598 * Returns: %TRUE if the clock is capable of being slaved to a master clock. 599 * Trying to set a master on a clock without the 600 * #GST_CLOCK_FLAG_CAN_SET_MASTER flag will make this function return %FALSE. 601 * 602 * MT safe. 603 */ 604 public bool setMaster(Clock master) 605 { 606 return gst_clock_set_master(gstClock, (master is null) ? null : master.getClockStruct()) != 0; 607 } 608 609 /** 610 * Set the accuracy of the clock. Some clocks have the possibility to operate 611 * with different accuracy at the expense of more resource usage. There is 612 * normally no need to change the default resolution of a clock. The resolution 613 * of a clock can only be changed if the clock has the 614 * #GST_CLOCK_FLAG_CAN_SET_RESOLUTION flag set. 615 * 616 * Params: 617 * resolution = The resolution to set 618 * 619 * Returns: the new resolution of the clock. 620 */ 621 public GstClockTime setResolution(GstClockTime resolution) 622 { 623 return gst_clock_set_resolution(gstClock, resolution); 624 } 625 626 /** 627 * Sets @clock to synced and emits the GstClock::synced signal, and wakes up any 628 * thread waiting in gst_clock_wait_for_sync(). 629 * 630 * This function must only be called if GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC 631 * is set on the clock, and is intended to be called by subclasses only. 632 * 633 * Params: 634 * synced = if the clock is synced 635 * 636 * Since: 1.6 637 */ 638 public void setSynced(bool synced) 639 { 640 gst_clock_set_synced(gstClock, synced); 641 } 642 643 /** 644 * Set the amount of time, in nanoseconds, to sample master and slave 645 * clocks 646 * 647 * Params: 648 * timeout = a timeout 649 */ 650 public void setTimeout(GstClockTime timeout) 651 { 652 gst_clock_set_timeout(gstClock, timeout); 653 } 654 655 /** 656 * Reinitializes the provided single shot @id to the provided time. Does not 657 * modify the reference count. 658 * 659 * Params: 660 * id = a #GstClockID 661 * time = The requested time. 662 * 663 * Returns: %TRUE if the GstClockID could be reinitialized to the provided 664 * @time, else %FALSE. 665 */ 666 public bool singleShotIdReinit(GstClockID id, GstClockTime time) 667 { 668 return gst_clock_single_shot_id_reinit(gstClock, id, time) != 0; 669 } 670 671 /** 672 * Converts the given @external clock time to the internal time of @clock, 673 * using the rate and reference time set with gst_clock_set_calibration(). 674 * This function should be called with the clock's OBJECT_LOCK held and 675 * is mainly used by clock subclasses. 676 * 677 * This function is the reverse of gst_clock_adjust_unlocked(). 678 * 679 * Params: 680 * external = an external clock time 681 * 682 * Returns: the internal time of the clock corresponding to @external. 683 */ 684 public GstClockTime unadjustUnlocked(GstClockTime external) 685 { 686 return gst_clock_unadjust_unlocked(gstClock, external); 687 } 688 689 /** 690 * Converts the given @external_target clock time to the internal time, 691 * using the passed calibration parameters. This function performs the 692 * same calculation as gst_clock_unadjust_unlocked() when called using the 693 * current calibration parameters. 694 * 695 * Note: The @clock parameter is unused and can be NULL 696 * 697 * Params: 698 * externalTarget = a clock time 699 * cinternal = a reference internal time 700 * cexternal = a reference external time 701 * cnum = the numerator of the rate of the clock relative to its 702 * internal time 703 * cdenom = the denominator of the rate of the clock 704 * 705 * Returns: the converted time of the clock. 706 * 707 * Since: 1.8 708 */ 709 public GstClockTime unadjustWithCalibration(GstClockTime externalTarget, GstClockTime cinternal, GstClockTime cexternal, GstClockTime cnum, GstClockTime cdenom) 710 { 711 return gst_clock_unadjust_with_calibration(gstClock, externalTarget, cinternal, cexternal, cnum, cdenom); 712 } 713 714 /** 715 * Waits until @clock is synced for reporting the current time. If @timeout 716 * is %GST_CLOCK_TIME_NONE it will wait forever, otherwise it will time out 717 * after @timeout nanoseconds. 718 * 719 * For asynchronous waiting, the GstClock::synced signal can be used. 720 * 721 * This returns immediately with TRUE if GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC 722 * is not set on the clock, or if the clock is already synced. 723 * 724 * Params: 725 * timeout = timeout for waiting or %GST_CLOCK_TIME_NONE 726 * 727 * Returns: %TRUE if waiting was successful, or %FALSE on timeout 728 * 729 * Since: 1.6 730 */ 731 public bool waitForSync(GstClockTime timeout) 732 { 733 return gst_clock_wait_for_sync(gstClock, timeout) != 0; 734 } 735 736 protected class OnSyncedDelegateWrapper 737 { 738 static OnSyncedDelegateWrapper[] listeners; 739 void delegate(bool, Clock) dlg; 740 gulong handlerId; 741 742 this(void delegate(bool, Clock) dlg) 743 { 744 this.dlg = dlg; 745 this.listeners ~= this; 746 } 747 748 void remove(OnSyncedDelegateWrapper source) 749 { 750 foreach(index, wrapper; listeners) 751 { 752 if (wrapper.handlerId == source.handlerId) 753 { 754 listeners[index] = null; 755 listeners = std.algorithm.remove(listeners, index); 756 break; 757 } 758 } 759 } 760 } 761 762 /** 763 * Signaled on clocks with GST_CLOCK_FLAG_NEEDS_STARTUP_SYNC set once 764 * the clock is synchronized, or when it completely lost synchronization. 765 * This signal will not be emitted on clocks without the flag. 766 * 767 * This signal will be emitted from an arbitrary thread, most likely not 768 * the application's main thread. 769 * 770 * Params: 771 * synced = if the clock is synced now 772 * 773 * Since: 1.6 774 */ 775 gulong addOnSynced(void delegate(bool, Clock) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 776 { 777 auto wrapper = new OnSyncedDelegateWrapper(dlg); 778 wrapper.handlerId = Signals.connectData( 779 this, 780 "synced", 781 cast(GCallback)&callBackSynced, 782 cast(void*)wrapper, 783 cast(GClosureNotify)&callBackSyncedDestroy, 784 connectFlags); 785 return wrapper.handlerId; 786 } 787 788 extern(C) static void callBackSynced(GstClock* clockStruct, bool synced, OnSyncedDelegateWrapper wrapper) 789 { 790 wrapper.dlg(synced, wrapper.outer); 791 } 792 793 extern(C) static void callBackSyncedDestroy(OnSyncedDelegateWrapper wrapper, GClosure* closure) 794 { 795 wrapper.remove(wrapper); 796 } 797 }