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 gst.app.AppSrc; 26 27 private import gobject.ObjectG; 28 private import gobject.Signals; 29 private import gst.app.c.functions; 30 public import gst.app.c.types; 31 private import gst.base.BaseSrc; 32 private import gstreamer.Buffer; 33 private import gstreamer.Caps; 34 private import gstreamer.Sample; 35 private import gstreamer.URIHandlerIF; 36 private import gstreamer.URIHandlerT; 37 private import std.algorithm; 38 39 40 /** 41 * The appsrc element can be used by applications to insert data into a 42 * GStreamer pipeline. Unlike most GStreamer elements, appsrc provides 43 * external API functions. 44 * 45 * appsrc can be used by linking with the libgstapp library to access the 46 * methods directly or by using the appsrc action signals. 47 * 48 * Before operating appsrc, the caps property must be set to fixed caps 49 * describing the format of the data that will be pushed with appsrc. An 50 * exception to this is when pushing buffers with unknown caps, in which case no 51 * caps should be set. This is typically true of file-like sources that push raw 52 * byte buffers. If you don't want to explicitly set the caps, you can use 53 * gst_app_src_push_sample. This method gets the caps associated with the 54 * sample and sets them on the appsrc replacing any previously set caps (if 55 * different from sample's caps). 56 * 57 * The main way of handing data to the appsrc element is by calling the 58 * gst_app_src_push_buffer() method or by emitting the push-buffer action signal. 59 * This will put the buffer onto a queue from which appsrc will read from in its 60 * streaming thread. It is important to note that data transport will not happen 61 * from the thread that performed the push-buffer call. 62 * 63 * The "max-bytes" property controls how much data can be queued in appsrc 64 * before appsrc considers the queue full. A filled internal queue will always 65 * signal the "enough-data" signal, which signals the application that it should 66 * stop pushing data into appsrc. The "block" property will cause appsrc to 67 * block the push-buffer method until free data becomes available again. 68 * 69 * When the internal queue is running out of data, the "need-data" signal is 70 * emitted, which signals the application that it should start pushing more data 71 * into appsrc. 72 * 73 * In addition to the "need-data" and "enough-data" signals, appsrc can emit the 74 * "seek-data" signal when the "stream-mode" property is set to "seekable" or 75 * "random-access". The signal argument will contain the new desired position in 76 * the stream expressed in the unit set with the "format" property. After 77 * receiving the seek-data signal, the application should push-buffers from the 78 * new position. 79 * 80 * These signals allow the application to operate the appsrc in two different 81 * ways: 82 * 83 * The push mode, in which the application repeatedly calls the push-buffer/push-sample 84 * method with a new buffer/sample. Optionally, the queue size in the appsrc 85 * can be controlled with the enough-data and need-data signals by respectively 86 * stopping/starting the push-buffer/push-sample calls. This is a typical 87 * mode of operation for the stream-type "stream" and "seekable". Use this 88 * mode when implementing various network protocols or hardware devices. 89 * 90 * The pull mode, in which the need-data signal triggers the next push-buffer call. 91 * This mode is typically used in the "random-access" stream-type. Use this 92 * mode for file access or other randomly accessable sources. In this mode, a 93 * buffer of exactly the amount of bytes given by the need-data signal should be 94 * pushed into appsrc. 95 * 96 * In all modes, the size property on appsrc should contain the total stream 97 * size in bytes. Setting this property is mandatory in the random-access mode. 98 * For the stream and seekable modes, setting this property is optional but 99 * recommended. 100 * 101 * When the application has finished pushing data into appsrc, it should call 102 * gst_app_src_end_of_stream() or emit the end-of-stream action signal. After 103 * this call, no more buffers can be pushed into appsrc until a flushing seek 104 * occurs or the state of the appsrc has gone through READY. 105 */ 106 public class AppSrc : BaseSrc, URIHandlerIF 107 { 108 /** the main Gtk struct */ 109 protected GstAppSrc* gstAppSrc; 110 111 /** Get the main Gtk struct */ 112 public GstAppSrc* getAppSrcStruct(bool transferOwnership = false) 113 { 114 if (transferOwnership) 115 ownedRef = false; 116 return gstAppSrc; 117 } 118 119 /** the main Gtk struct as a void* */ 120 protected override void* getStruct() 121 { 122 return cast(void*)gstAppSrc; 123 } 124 125 /** 126 * Sets our main struct and passes it to the parent class. 127 */ 128 public this (GstAppSrc* gstAppSrc, bool ownedRef = false) 129 { 130 this.gstAppSrc = gstAppSrc; 131 super(cast(GstBaseSrc*)gstAppSrc, ownedRef); 132 } 133 134 // add the URIHandler capabilities 135 mixin URIHandlerT!(GstAppSrc); 136 137 138 /** */ 139 public static GType getType() 140 { 141 return gst_app_src_get_type(); 142 } 143 144 /** 145 * Indicates to the appsrc element that the last buffer queued in the 146 * element is the last buffer of the stream. 147 * 148 * Returns: #GST_FLOW_OK when the EOS was successfuly queued. 149 * #GST_FLOW_FLUSHING when @appsrc is not PAUSED or PLAYING. 150 */ 151 public GstFlowReturn endOfStream() 152 { 153 return gst_app_src_end_of_stream(gstAppSrc); 154 } 155 156 /** 157 * Get the configured caps on @appsrc. 158 * 159 * Returns: the #GstCaps produced by the source. gst_caps_unref() after usage. 160 */ 161 public Caps getCaps() 162 { 163 auto p = gst_app_src_get_caps(gstAppSrc); 164 165 if(p is null) 166 { 167 return null; 168 } 169 170 return ObjectG.getDObject!(Caps)(cast(GstCaps*) p, true); 171 } 172 173 /** 174 * Get the number of currently queued bytes inside @appsrc. 175 * 176 * Returns: The number of currently queued bytes. 177 * 178 * Since: 1.2 179 */ 180 public ulong getCurrentLevelBytes() 181 { 182 return gst_app_src_get_current_level_bytes(gstAppSrc); 183 } 184 185 /** 186 * Get the duration of the stream in nanoseconds. A value of GST_CLOCK_TIME_NONE means that the duration is 187 * not known. 188 * 189 * Returns: the duration of the stream previously set with gst_app_src_set_duration(); 190 * 191 * Since: 1.10 192 */ 193 public GstClockTime getDuration() 194 { 195 return gst_app_src_get_duration(gstAppSrc); 196 } 197 198 /** 199 * Check if appsrc will emit the "new-preroll" and "new-buffer" signals. 200 * 201 * Returns: %TRUE if @appsrc is emitting the "new-preroll" and "new-buffer" 202 * signals. 203 */ 204 public bool getEmitSignals() 205 { 206 return gst_app_src_get_emit_signals(gstAppSrc) != 0; 207 } 208 209 /** 210 * Retrieve the min and max latencies in @min and @max respectively. 211 * 212 * Params: 213 * min = the min latency 214 * max = the min latency 215 */ 216 public void getLatency(ulong* min, ulong* max) 217 { 218 gst_app_src_get_latency(gstAppSrc, min, max); 219 } 220 221 /** 222 * Get the maximum amount of bytes that can be queued in @appsrc. 223 * 224 * Returns: The maximum amount of bytes that can be queued. 225 */ 226 public ulong getMaxBytes() 227 { 228 return gst_app_src_get_max_bytes(gstAppSrc); 229 } 230 231 /** 232 * Get the size of the stream in bytes. A value of -1 means that the size is 233 * not known. 234 * 235 * Returns: the size of the stream previously set with gst_app_src_set_size(); 236 */ 237 public long getSize() 238 { 239 return gst_app_src_get_size(gstAppSrc); 240 } 241 242 /** 243 * Get the stream type. Control the stream type of @appsrc 244 * with gst_app_src_set_stream_type(). 245 * 246 * Returns: the stream type. 247 */ 248 public GstAppStreamType getStreamType() 249 { 250 return gst_app_src_get_stream_type(gstAppSrc); 251 } 252 253 /** 254 * Adds a buffer to the queue of buffers that the appsrc element will 255 * push to its source pad. This function takes ownership of the buffer. 256 * 257 * When the block property is TRUE, this function can block until free 258 * space becomes available in the queue. 259 * 260 * Params: 261 * buffer = a #GstBuffer to push 262 * 263 * Returns: #GST_FLOW_OK when the buffer was successfuly queued. 264 * #GST_FLOW_FLUSHING when @appsrc is not PAUSED or PLAYING. 265 * #GST_FLOW_EOS when EOS occured. 266 */ 267 public GstFlowReturn pushBuffer(Buffer buffer) 268 { 269 return gst_app_src_push_buffer(gstAppSrc, (buffer is null) ? null : buffer.getBufferStruct()); 270 } 271 272 /** 273 * Extract a buffer from the provided sample and adds it to the queue of 274 * buffers that the appsrc element will push to its source pad. Any 275 * previous caps that were set on appsrc will be replaced by the caps 276 * associated with the sample if not equal. 277 * 278 * When the block property is TRUE, this function can block until free 279 * space becomes available in the queue. 280 * 281 * Params: 282 * sample = a #GstSample from which buffer and caps may be 283 * extracted 284 * 285 * Returns: #GST_FLOW_OK when the buffer was successfuly queued. 286 * #GST_FLOW_FLUSHING when @appsrc is not PAUSED or PLAYING. 287 * #GST_FLOW_EOS when EOS occured. 288 * 289 * Since: 1.6 290 */ 291 public GstFlowReturn pushSample(Sample sample) 292 { 293 return gst_app_src_push_sample(gstAppSrc, (sample is null) ? null : sample.getSampleStruct()); 294 } 295 296 /** 297 * Set callbacks which will be executed when data is needed, enough data has 298 * been collected or when a seek should be performed. 299 * This is an alternative to using the signals, it has lower overhead and is thus 300 * less expensive, but also less flexible. 301 * 302 * If callbacks are installed, no signals will be emitted for performance 303 * reasons. 304 * 305 * Params: 306 * callbacks = the callbacks 307 * userData = a user_data argument for the callbacks 308 * notify = a destroy notify function 309 */ 310 public void setCallbacks(GstAppSrcCallbacks* callbacks, void* userData, GDestroyNotify notify) 311 { 312 gst_app_src_set_callbacks(gstAppSrc, callbacks, userData, notify); 313 } 314 315 /** 316 * Set the duration of the stream in nanoseconds. A value of GST_CLOCK_TIME_NONE means that the duration is 317 * not known. 318 * 319 * Params: 320 * duration = the duration to set 321 * 322 * Since: 1.10 323 */ 324 public void setDuration(GstClockTime duration) 325 { 326 gst_app_src_set_duration(gstAppSrc, duration); 327 } 328 329 /** 330 * Make appsrc emit the "new-preroll" and "new-buffer" signals. This option is 331 * by default disabled because signal emission is expensive and unneeded when 332 * the application prefers to operate in pull mode. 333 * 334 * Params: 335 * emit = the new state 336 */ 337 public void setEmitSignals(bool emit) 338 { 339 gst_app_src_set_emit_signals(gstAppSrc, emit); 340 } 341 342 /** 343 * Configure the @min and @max latency in @src. If @min is set to -1, the 344 * default latency calculations for pseudo-live sources will be used. 345 * 346 * Params: 347 * min = the min latency 348 * max = the min latency 349 */ 350 public void setLatency(ulong min, ulong max) 351 { 352 gst_app_src_set_latency(gstAppSrc, min, max); 353 } 354 355 /** 356 * Set the maximum amount of bytes that can be queued in @appsrc. 357 * After the maximum amount of bytes are queued, @appsrc will emit the 358 * "enough-data" signal. 359 * 360 * Params: 361 * max = the maximum number of bytes to queue 362 */ 363 public void setMaxBytes(ulong max) 364 { 365 gst_app_src_set_max_bytes(gstAppSrc, max); 366 } 367 368 /** 369 * Set the size of the stream in bytes. A value of -1 means that the size is 370 * not known. 371 * 372 * Params: 373 * size = the size to set 374 */ 375 public void setSize(long size) 376 { 377 gst_app_src_set_size(gstAppSrc, size); 378 } 379 380 /** 381 * Set the stream type on @appsrc. For seekable streams, the "seek" signal must 382 * be connected to. 383 * 384 * A stream_type stream 385 * 386 * Params: 387 * type = the new state 388 */ 389 public void setStreamType(GstAppStreamType type) 390 { 391 gst_app_src_set_stream_type(gstAppSrc, type); 392 } 393 394 protected class OnEndOfStreamDelegateWrapper 395 { 396 GstFlowReturn delegate(AppSrc) dlg; 397 gulong handlerId; 398 399 this(GstFlowReturn delegate(AppSrc) dlg) 400 { 401 this.dlg = dlg; 402 onEndOfStreamListeners ~= this; 403 } 404 405 void remove(OnEndOfStreamDelegateWrapper source) 406 { 407 foreach(index, wrapper; onEndOfStreamListeners) 408 { 409 if (wrapper.handlerId == source.handlerId) 410 { 411 onEndOfStreamListeners[index] = null; 412 onEndOfStreamListeners = std.algorithm.remove(onEndOfStreamListeners, index); 413 break; 414 } 415 } 416 } 417 } 418 OnEndOfStreamDelegateWrapper[] onEndOfStreamListeners; 419 420 /** 421 * Notify @appsrc that no more buffer are available. 422 */ 423 gulong addOnEndOfStream(GstFlowReturn delegate(AppSrc) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 424 { 425 auto wrapper = new OnEndOfStreamDelegateWrapper(dlg); 426 wrapper.handlerId = Signals.connectData( 427 this, 428 "end-of-stream", 429 cast(GCallback)&callBackEndOfStream, 430 cast(void*)wrapper, 431 cast(GClosureNotify)&callBackEndOfStreamDestroy, 432 connectFlags); 433 return wrapper.handlerId; 434 } 435 436 extern(C) static GstFlowReturn callBackEndOfStream(GstAppSrc* appsrcStruct, OnEndOfStreamDelegateWrapper wrapper) 437 { 438 return wrapper.dlg(wrapper.outer); 439 } 440 441 extern(C) static void callBackEndOfStreamDestroy(OnEndOfStreamDelegateWrapper wrapper, GClosure* closure) 442 { 443 wrapper.remove(wrapper); 444 } 445 446 protected class OnEnoughDataDelegateWrapper 447 { 448 void delegate(AppSrc) dlg; 449 gulong handlerId; 450 451 this(void delegate(AppSrc) dlg) 452 { 453 this.dlg = dlg; 454 onEnoughDataListeners ~= this; 455 } 456 457 void remove(OnEnoughDataDelegateWrapper source) 458 { 459 foreach(index, wrapper; onEnoughDataListeners) 460 { 461 if (wrapper.handlerId == source.handlerId) 462 { 463 onEnoughDataListeners[index] = null; 464 onEnoughDataListeners = std.algorithm.remove(onEnoughDataListeners, index); 465 break; 466 } 467 } 468 } 469 } 470 OnEnoughDataDelegateWrapper[] onEnoughDataListeners; 471 472 /** 473 * Signal that the source has enough data. It is recommended that the 474 * application stops calling push-buffer until the need-data signal is 475 * emitted again to avoid excessive buffer queueing. 476 */ 477 gulong addOnEnoughData(void delegate(AppSrc) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 478 { 479 auto wrapper = new OnEnoughDataDelegateWrapper(dlg); 480 wrapper.handlerId = Signals.connectData( 481 this, 482 "enough-data", 483 cast(GCallback)&callBackEnoughData, 484 cast(void*)wrapper, 485 cast(GClosureNotify)&callBackEnoughDataDestroy, 486 connectFlags); 487 return wrapper.handlerId; 488 } 489 490 extern(C) static void callBackEnoughData(GstAppSrc* appsrcStruct, OnEnoughDataDelegateWrapper wrapper) 491 { 492 wrapper.dlg(wrapper.outer); 493 } 494 495 extern(C) static void callBackEnoughDataDestroy(OnEnoughDataDelegateWrapper wrapper, GClosure* closure) 496 { 497 wrapper.remove(wrapper); 498 } 499 500 protected class OnNeedDataDelegateWrapper 501 { 502 void delegate(uint, AppSrc) dlg; 503 gulong handlerId; 504 505 this(void delegate(uint, AppSrc) dlg) 506 { 507 this.dlg = dlg; 508 onNeedDataListeners ~= this; 509 } 510 511 void remove(OnNeedDataDelegateWrapper source) 512 { 513 foreach(index, wrapper; onNeedDataListeners) 514 { 515 if (wrapper.handlerId == source.handlerId) 516 { 517 onNeedDataListeners[index] = null; 518 onNeedDataListeners = std.algorithm.remove(onNeedDataListeners, index); 519 break; 520 } 521 } 522 } 523 } 524 OnNeedDataDelegateWrapper[] onNeedDataListeners; 525 526 /** 527 * Signal that the source needs more data. In the callback or from another 528 * thread you should call push-buffer or end-of-stream. 529 * 530 * @length is just a hint and when it is set to -1, any number of bytes can be 531 * pushed into @appsrc. 532 * 533 * You can call push-buffer multiple times until the enough-data signal is 534 * fired. 535 * 536 * Params: 537 * length = the amount of bytes needed. 538 */ 539 gulong addOnNeedData(void delegate(uint, AppSrc) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 540 { 541 auto wrapper = new OnNeedDataDelegateWrapper(dlg); 542 wrapper.handlerId = Signals.connectData( 543 this, 544 "need-data", 545 cast(GCallback)&callBackNeedData, 546 cast(void*)wrapper, 547 cast(GClosureNotify)&callBackNeedDataDestroy, 548 connectFlags); 549 return wrapper.handlerId; 550 } 551 552 extern(C) static void callBackNeedData(GstAppSrc* appsrcStruct, uint length, OnNeedDataDelegateWrapper wrapper) 553 { 554 wrapper.dlg(length, wrapper.outer); 555 } 556 557 extern(C) static void callBackNeedDataDestroy(OnNeedDataDelegateWrapper wrapper, GClosure* closure) 558 { 559 wrapper.remove(wrapper); 560 } 561 562 protected class OnPushBufferDelegateWrapper 563 { 564 GstFlowReturn delegate(Buffer, AppSrc) dlg; 565 gulong handlerId; 566 567 this(GstFlowReturn delegate(Buffer, AppSrc) dlg) 568 { 569 this.dlg = dlg; 570 onPushBufferListeners ~= this; 571 } 572 573 void remove(OnPushBufferDelegateWrapper source) 574 { 575 foreach(index, wrapper; onPushBufferListeners) 576 { 577 if (wrapper.handlerId == source.handlerId) 578 { 579 onPushBufferListeners[index] = null; 580 onPushBufferListeners = std.algorithm.remove(onPushBufferListeners, index); 581 break; 582 } 583 } 584 } 585 } 586 OnPushBufferDelegateWrapper[] onPushBufferListeners; 587 588 /** 589 * Adds a buffer to the queue of buffers that the appsrc element will 590 * push to its source pad. This function does not take ownership of the 591 * buffer so the buffer needs to be unreffed after calling this function. 592 * 593 * When the block property is TRUE, this function can block until free space 594 * becomes available in the queue. 595 * 596 * Params: 597 * buffer = a buffer to push 598 */ 599 gulong addOnPushBuffer(GstFlowReturn delegate(Buffer, AppSrc) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 600 { 601 auto wrapper = new OnPushBufferDelegateWrapper(dlg); 602 wrapper.handlerId = Signals.connectData( 603 this, 604 "push-buffer", 605 cast(GCallback)&callBackPushBuffer, 606 cast(void*)wrapper, 607 cast(GClosureNotify)&callBackPushBufferDestroy, 608 connectFlags); 609 return wrapper.handlerId; 610 } 611 612 extern(C) static GstFlowReturn callBackPushBuffer(GstAppSrc* appsrcStruct, GstBuffer* buffer, OnPushBufferDelegateWrapper wrapper) 613 { 614 return wrapper.dlg(ObjectG.getDObject!(Buffer)(buffer), wrapper.outer); 615 } 616 617 extern(C) static void callBackPushBufferDestroy(OnPushBufferDelegateWrapper wrapper, GClosure* closure) 618 { 619 wrapper.remove(wrapper); 620 } 621 622 protected class OnPushSampleDelegateWrapper 623 { 624 GstFlowReturn delegate(Sample, AppSrc) dlg; 625 gulong handlerId; 626 627 this(GstFlowReturn delegate(Sample, AppSrc) dlg) 628 { 629 this.dlg = dlg; 630 onPushSampleListeners ~= this; 631 } 632 633 void remove(OnPushSampleDelegateWrapper source) 634 { 635 foreach(index, wrapper; onPushSampleListeners) 636 { 637 if (wrapper.handlerId == source.handlerId) 638 { 639 onPushSampleListeners[index] = null; 640 onPushSampleListeners = std.algorithm.remove(onPushSampleListeners, index); 641 break; 642 } 643 } 644 } 645 } 646 OnPushSampleDelegateWrapper[] onPushSampleListeners; 647 648 /** 649 * Extract a buffer from the provided sample and adds the extracted buffer 650 * to the queue of buffers that the appsrc element will 651 * push to its source pad. This function set the appsrc caps based on the caps 652 * in the sample and reset the caps if they change. 653 * Only the caps and the buffer of the provided sample are used and not 654 * for example the segment in the sample. 655 * This function does not take ownership of the 656 * sample so the sample needs to be unreffed after calling this function. 657 * 658 * When the block property is TRUE, this function can block until free space 659 * becomes available in the queue. 660 * 661 * Params: 662 * sample = a sample from which extract buffer to push 663 * 664 * Since: 1.6 665 */ 666 gulong addOnPushSample(GstFlowReturn delegate(Sample, AppSrc) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 667 { 668 auto wrapper = new OnPushSampleDelegateWrapper(dlg); 669 wrapper.handlerId = Signals.connectData( 670 this, 671 "push-sample", 672 cast(GCallback)&callBackPushSample, 673 cast(void*)wrapper, 674 cast(GClosureNotify)&callBackPushSampleDestroy, 675 connectFlags); 676 return wrapper.handlerId; 677 } 678 679 extern(C) static GstFlowReturn callBackPushSample(GstAppSrc* appsrcStruct, GstSample* sample, OnPushSampleDelegateWrapper wrapper) 680 { 681 return wrapper.dlg(ObjectG.getDObject!(Sample)(sample), wrapper.outer); 682 } 683 684 extern(C) static void callBackPushSampleDestroy(OnPushSampleDelegateWrapper wrapper, GClosure* closure) 685 { 686 wrapper.remove(wrapper); 687 } 688 689 protected class OnSeekDataDelegateWrapper 690 { 691 bool delegate(ulong, AppSrc) dlg; 692 gulong handlerId; 693 694 this(bool delegate(ulong, AppSrc) dlg) 695 { 696 this.dlg = dlg; 697 onSeekDataListeners ~= this; 698 } 699 700 void remove(OnSeekDataDelegateWrapper source) 701 { 702 foreach(index, wrapper; onSeekDataListeners) 703 { 704 if (wrapper.handlerId == source.handlerId) 705 { 706 onSeekDataListeners[index] = null; 707 onSeekDataListeners = std.algorithm.remove(onSeekDataListeners, index); 708 break; 709 } 710 } 711 } 712 } 713 OnSeekDataDelegateWrapper[] onSeekDataListeners; 714 715 /** 716 * Seek to the given offset. The next push-buffer should produce buffers from 717 * the new @offset. 718 * This callback is only called for seekable stream types. 719 * 720 * Params: 721 * offset = the offset to seek to 722 * 723 * Returns: %TRUE if the seek succeeded. 724 */ 725 gulong addOnSeekData(bool delegate(ulong, AppSrc) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) 726 { 727 auto wrapper = new OnSeekDataDelegateWrapper(dlg); 728 wrapper.handlerId = Signals.connectData( 729 this, 730 "seek-data", 731 cast(GCallback)&callBackSeekData, 732 cast(void*)wrapper, 733 cast(GClosureNotify)&callBackSeekDataDestroy, 734 connectFlags); 735 return wrapper.handlerId; 736 } 737 738 extern(C) static int callBackSeekData(GstAppSrc* appsrcStruct, ulong offset, OnSeekDataDelegateWrapper wrapper) 739 { 740 return wrapper.dlg(offset, wrapper.outer); 741 } 742 743 extern(C) static void callBackSeekDataDestroy(OnSeekDataDelegateWrapper wrapper, GClosure* closure) 744 { 745 wrapper.remove(wrapper); 746 } 747 748 /** 749 * Set the capabilities on the appsrc element. This function takes 750 * a copy of the caps structure. After calling this method, the source will 751 * only produce caps that match @caps. @caps must be fixed and the caps on the 752 * buffers must match the caps or left NULL. 753 * 754 * Params: 755 * caps = caps to set 756 */ 757 public void appSrcSetCaps(Caps caps) 758 { 759 gst_app_src_set_caps(gstAppSrc, (caps is null) ? null : caps.getCapsStruct()); 760 } 761 }