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