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.base.BaseParse; 26 27 private import gst.base.BaseParseFrame; 28 private import gst.base.c.functions; 29 public import gst.base.c.types; 30 private import gstreamer.Element; 31 private import gstreamer.TagList; 32 33 34 /** 35 * This base class is for parser elements that process data and splits it 36 * into separate audio/video/whatever frames. 37 * 38 * It provides for: 39 * 40 * * provides one sink pad and one source pad 41 * * handles state changes 42 * * can operate in pull mode or push mode 43 * * handles seeking in both modes 44 * * handles events (SEGMENT/EOS/FLUSH) 45 * * handles queries (POSITION/DURATION/SEEKING/FORMAT/CONVERT) 46 * * handles flushing 47 * 48 * The purpose of this base class is to provide the basic functionality of 49 * a parser and share a lot of rather complex code. 50 * 51 * # Description of the parsing mechanism: 52 * 53 * ## Set-up phase 54 * 55 * * #GstBaseParse calls @start to inform subclass that data processing is 56 * about to start now. 57 * 58 * * #GstBaseParse class calls @set_sink_caps to inform the subclass about 59 * incoming sinkpad caps. Subclass could already set the srcpad caps 60 * accordingly, but this might be delayed until calling 61 * gst_base_parse_finish_frame() with a non-queued frame. 62 * 63 * * At least at this point subclass needs to tell the #GstBaseParse class 64 * how big data chunks it wants to receive (min_frame_size). It can do 65 * this with gst_base_parse_set_min_frame_size(). 66 * 67 * * #GstBaseParse class sets up appropriate data passing mode (pull/push) 68 * and starts to process the data. 69 * 70 * ## Parsing phase 71 * 72 * * #GstBaseParse gathers at least min_frame_size bytes of data either 73 * by pulling it from upstream or collecting buffers in an internal 74 * #GstAdapter. 75 * 76 * * A buffer of (at least) min_frame_size bytes is passed to subclass with 77 * @handle_frame. Subclass checks the contents and can optionally 78 * return GST_FLOW_OK along with an amount of data to be skipped to find 79 * a valid frame (which will result in a subsequent DISCONT). 80 * If, otherwise, the buffer does not hold a complete frame, 81 * @handle_frame can merely return and will be called again when additional 82 * data is available. In push mode this amounts to an 83 * additional input buffer (thus minimal additional latency), in pull mode 84 * this amounts to some arbitrary reasonable buffer size increase. 85 * Of course, gst_base_parse_set_min_frame_size() could also be used if a 86 * very specific known amount of additional data is required. 87 * If, however, the buffer holds a complete valid frame, it can pass 88 * the size of this frame to gst_base_parse_finish_frame(). 89 * If acting as a converter, it can also merely indicate consumed input data 90 * while simultaneously providing custom output data. 91 * Note that baseclass performs some processing (such as tracking 92 * overall consumed data rate versus duration) for each finished frame, 93 * but other state is only updated upon each call to @handle_frame 94 * (such as tracking upstream input timestamp). 95 * 96 * Subclass is also responsible for setting the buffer metadata 97 * (e.g. buffer timestamp and duration, or keyframe if applicable). 98 * (although the latter can also be done by #GstBaseParse if it is 99 * appropriately configured, see below). Frame is provided with 100 * timestamp derived from upstream (as much as generally possible), 101 * duration obtained from configuration (see below), and offset 102 * if meaningful (in pull mode). 103 * 104 * Note that @check_valid_frame might receive any small 105 * amount of input data when leftover data is being drained (e.g. at EOS). 106 * 107 * * As part of finish frame processing, 108 * just prior to actually pushing the buffer in question, 109 * it is passed to @pre_push_frame which gives subclass yet one 110 * last chance to examine buffer metadata, or to send some custom (tag) 111 * events, or to perform custom (segment) filtering. 112 * 113 * * During the parsing process #GstBaseParseClass will handle both srcpad 114 * and sinkpad events. They will be passed to subclass if @event or 115 * @src_event callbacks have been provided. 116 * 117 * ## Shutdown phase 118 * 119 * * #GstBaseParse class calls @stop to inform the subclass that data 120 * parsing will be stopped. 121 * 122 * Subclass is responsible for providing pad template caps for 123 * source and sink pads. The pads need to be named "sink" and "src". It also 124 * needs to set the fixed caps on srcpad, when the format is ensured (e.g. 125 * when base class calls subclass' @set_sink_caps function). 126 * 127 * This base class uses %GST_FORMAT_DEFAULT as a meaning of frames. So, 128 * subclass conversion routine needs to know that conversion from 129 * %GST_FORMAT_TIME to %GST_FORMAT_DEFAULT must return the 130 * frame number that can be found from the given byte position. 131 * 132 * #GstBaseParse uses subclasses conversion methods also for seeking (or 133 * otherwise uses its own default one, see also below). 134 * 135 * Subclass @start and @stop functions will be called to inform the beginning 136 * and end of data processing. 137 * 138 * Things that subclass need to take care of: 139 * 140 * * Provide pad templates 141 * * Fixate the source pad caps when appropriate 142 * * Inform base class how big data chunks should be retrieved. This is 143 * done with gst_base_parse_set_min_frame_size() function. 144 * * Examine data chunks passed to subclass with @handle_frame and pass 145 * proper frame(s) to gst_base_parse_finish_frame(), and setting src pad 146 * caps and timestamps on frame. 147 * * Provide conversion functions 148 * * Update the duration information with gst_base_parse_set_duration() 149 * * Optionally passthrough using gst_base_parse_set_passthrough() 150 * * Configure various baseparse parameters using 151 * gst_base_parse_set_average_bitrate(), gst_base_parse_set_syncable() 152 * and gst_base_parse_set_frame_rate(). 153 * 154 * * In particular, if subclass is unable to determine a duration, but 155 * parsing (or specs) yields a frames per seconds rate, then this can be 156 * provided to #GstBaseParse to enable it to cater for 157 * buffer time metadata (which will be taken from upstream as much as 158 * possible). Internally keeping track of frame durations and respective 159 * sizes that have been pushed provides #GstBaseParse with an estimated 160 * bitrate. A default @convert (used if not overridden) will then use these 161 * rates to perform obvious conversions. These rates are also used to 162 * update (estimated) duration at regular frame intervals. 163 */ 164 public class BaseParse : Element 165 { 166 /** the main Gtk struct */ 167 protected GstBaseParse* gstBaseParse; 168 169 /** Get the main Gtk struct */ 170 public GstBaseParse* getBaseParseStruct(bool transferOwnership = false) 171 { 172 if (transferOwnership) 173 ownedRef = false; 174 return gstBaseParse; 175 } 176 177 /** the main Gtk struct as a void* */ 178 protected override void* getStruct() 179 { 180 return cast(void*)gstBaseParse; 181 } 182 183 /** 184 * Sets our main struct and passes it to the parent class. 185 */ 186 public this (GstBaseParse* gstBaseParse, bool ownedRef = false) 187 { 188 this.gstBaseParse = gstBaseParse; 189 super(cast(GstElement*)gstBaseParse, ownedRef); 190 } 191 192 193 /** */ 194 public static GType getType() 195 { 196 return gst_base_parse_get_type(); 197 } 198 199 /** 200 * Adds an entry to the index associating @offset to @ts. It is recommended 201 * to only add keyframe entries. @force allows to bypass checks, such as 202 * whether the stream is (upstream) seekable, another entry is already "close" 203 * to the new entry, etc. 204 * 205 * Params: 206 * offset = offset of entry 207 * ts = timestamp associated with offset 208 * key = whether entry refers to keyframe 209 * force = add entry disregarding sanity checks 210 * 211 * Returns: #gboolean indicating whether entry was added 212 */ 213 public bool addIndexEntry(ulong offset, GstClockTime ts, bool key, bool force) 214 { 215 return gst_base_parse_add_index_entry(gstBaseParse, offset, ts, key, force) != 0; 216 } 217 218 /** 219 * Default implementation of "convert" vmethod in #GstBaseParse class. 220 * 221 * Params: 222 * srcFormat = #GstFormat describing the source format. 223 * srcValue = Source value to be converted. 224 * destFormat = #GstFormat defining the converted format. 225 * destValue = Pointer where the conversion result will be put. 226 * 227 * Returns: %TRUE if conversion was successful. 228 */ 229 public bool convertDefault(GstFormat srcFormat, long srcValue, GstFormat destFormat, out long destValue) 230 { 231 return gst_base_parse_convert_default(gstBaseParse, srcFormat, srcValue, destFormat, &destValue) != 0; 232 } 233 234 /** 235 * Drains the adapter until it is empty. It decreases the min_frame_size to 236 * match the current adapter size and calls chain method until the adapter 237 * is emptied or chain returns with error. 238 * 239 * Since: 1.12 240 */ 241 public void drain() 242 { 243 gst_base_parse_drain(gstBaseParse); 244 } 245 246 /** 247 * Collects parsed data and pushes this downstream. 248 * Source pad caps must be set when this is called. 249 * 250 * If @frame's out_buffer is set, that will be used as subsequent frame data. 251 * Otherwise, @size samples will be taken from the input and used for output, 252 * and the output's metadata (timestamps etc) will be taken as (optionally) 253 * set by the subclass on @frame's (input) buffer (which is otherwise 254 * ignored for any but the above purpose/information). 255 * 256 * Note that the latter buffer is invalidated by this call, whereas the 257 * caller retains ownership of @frame. 258 * 259 * Params: 260 * frame = a #GstBaseParseFrame 261 * size = consumed input data represented by frame 262 * 263 * Returns: a #GstFlowReturn that should be escalated to caller (of caller) 264 */ 265 public GstFlowReturn finishFrame(BaseParseFrame frame, int size) 266 { 267 return gst_base_parse_finish_frame(gstBaseParse, (frame is null) ? null : frame.getBaseParseFrameStruct(), size); 268 } 269 270 /** 271 * Sets the parser subclass's tags and how they should be merged with any 272 * upstream stream tags. This will override any tags previously-set 273 * with gst_base_parse_merge_tags(). 274 * 275 * Note that this is provided for convenience, and the subclass is 276 * not required to use this and can still do tag handling on its own. 277 * 278 * Params: 279 * tags = a #GstTagList to merge, or NULL to unset 280 * previously-set tags 281 * mode = the #GstTagMergeMode to use, usually #GST_TAG_MERGE_REPLACE 282 * 283 * Since: 1.6 284 */ 285 public void mergeTags(TagList tags, GstTagMergeMode mode) 286 { 287 gst_base_parse_merge_tags(gstBaseParse, (tags is null) ? null : tags.getTagListStruct(), mode); 288 } 289 290 /** 291 * Pushes the frame's buffer downstream, sends any pending events and 292 * does some timestamp and segment handling. Takes ownership of 293 * frame's buffer, though caller retains ownership of @frame. 294 * 295 * This must be called with sinkpad STREAM_LOCK held. 296 * 297 * Params: 298 * frame = a #GstBaseParseFrame 299 * 300 * Returns: #GstFlowReturn 301 */ 302 public GstFlowReturn pushFrame(BaseParseFrame frame) 303 { 304 return gst_base_parse_push_frame(gstBaseParse, (frame is null) ? null : frame.getBaseParseFrameStruct()); 305 } 306 307 /** 308 * Optionally sets the average bitrate detected in media (if non-zero), 309 * e.g. based on metadata, as it will be posted to the application. 310 * 311 * By default, announced average bitrate is estimated. The average bitrate 312 * is used to estimate the total duration of the stream and to estimate 313 * a seek position, if there's no index and the format is syncable 314 * (see gst_base_parse_set_syncable()). 315 * 316 * Params: 317 * bitrate = average bitrate in bits/second 318 */ 319 public void setAverageBitrate(uint bitrate) 320 { 321 gst_base_parse_set_average_bitrate(gstBaseParse, bitrate); 322 } 323 324 /** 325 * Sets the duration of the currently playing media. Subclass can use this 326 * when it is able to determine duration and/or notices a change in the media 327 * duration. Alternatively, if @interval is non-zero (default), then stream 328 * duration is determined based on estimated bitrate, and updated every @interval 329 * frames. 330 * 331 * Params: 332 * fmt = #GstFormat. 333 * duration = duration value. 334 * interval = how often to update the duration estimate based on bitrate, or 0. 335 */ 336 public void setDuration(GstFormat fmt, long duration, int interval) 337 { 338 gst_base_parse_set_duration(gstBaseParse, fmt, duration, interval); 339 } 340 341 /** 342 * If frames per second is configured, parser can take care of buffer duration 343 * and timestamping. When performing segment clipping, or seeking to a specific 344 * location, a corresponding decoder might need an initial @lead_in and a 345 * following @lead_out number of frames to ensure the desired segment is 346 * entirely filled upon decoding. 347 * 348 * Params: 349 * fpsNum = frames per second (numerator). 350 * fpsDen = frames per second (denominator). 351 * leadIn = frames needed before a segment for subsequent decode 352 * leadOut = frames needed after a segment 353 */ 354 public void setFrameRate(uint fpsNum, uint fpsDen, uint leadIn, uint leadOut) 355 { 356 gst_base_parse_set_frame_rate(gstBaseParse, fpsNum, fpsDen, leadIn, leadOut); 357 } 358 359 /** 360 * Set if frames carry timing information which the subclass can (generally) 361 * parse and provide. In particular, intrinsic (rather than estimated) time 362 * can be obtained following a seek. 363 * 364 * Params: 365 * hasTiming = whether frames carry timing information 366 */ 367 public void setHasTimingInfo(bool hasTiming) 368 { 369 gst_base_parse_set_has_timing_info(gstBaseParse, hasTiming); 370 } 371 372 /** 373 * By default, the base class might try to infer PTS from DTS and vice 374 * versa. While this is generally correct for audio data, it may not 375 * be otherwise. Sub-classes implementing such formats should disable 376 * timestamp inferring. 377 * 378 * Params: 379 * inferTs = %TRUE if parser should infer DTS/PTS from each other 380 */ 381 public void setInferTs(bool inferTs) 382 { 383 gst_base_parse_set_infer_ts(gstBaseParse, inferTs); 384 } 385 386 /** 387 * Sets the minimum and maximum (which may likely be equal) latency introduced 388 * by the parsing process. If there is such a latency, which depends on the 389 * particular parsing of the format, it typically corresponds to 1 frame duration. 390 * 391 * Params: 392 * minLatency = minimum parse latency 393 * maxLatency = maximum parse latency 394 */ 395 public void setLatency(GstClockTime minLatency, GstClockTime maxLatency) 396 { 397 gst_base_parse_set_latency(gstBaseParse, minLatency, maxLatency); 398 } 399 400 /** 401 * Subclass can use this function to tell the base class that it needs to 402 * give at least #min_size buffers. 403 * 404 * Params: 405 * minSize = Minimum size of the data that this base class should give to 406 * subclass. 407 */ 408 public void setMinFrameSize(uint minSize) 409 { 410 gst_base_parse_set_min_frame_size(gstBaseParse, minSize); 411 } 412 413 /** 414 * Set if the nature of the format or configuration does not allow (much) 415 * parsing, and the parser should operate in passthrough mode (which only 416 * applies when operating in push mode). That is, incoming buffers are 417 * pushed through unmodified, i.e. no @check_valid_frame or @parse_frame 418 * callbacks will be invoked, but @pre_push_frame will still be invoked, 419 * so subclass can perform as much or as little is appropriate for 420 * passthrough semantics in @pre_push_frame. 421 * 422 * Params: 423 * passthrough = %TRUE if parser should run in passthrough mode 424 */ 425 public void setPassthrough(bool passthrough) 426 { 427 gst_base_parse_set_passthrough(gstBaseParse, passthrough); 428 } 429 430 /** 431 * By default, the base class will guess PTS timestamps using a simple 432 * interpolation (previous timestamp + duration), which is incorrect for 433 * data streams with reordering, where PTS can go backward. Sub-classes 434 * implementing such formats should disable PTS interpolation. 435 * 436 * Params: 437 * ptsInterpolate = %TRUE if parser should interpolate PTS timestamps 438 */ 439 public void setPtsInterpolation(bool ptsInterpolate) 440 { 441 gst_base_parse_set_pts_interpolation(gstBaseParse, ptsInterpolate); 442 } 443 444 /** 445 * Set if frame starts can be identified. This is set by default and 446 * determines whether seeking based on bitrate averages 447 * is possible for a format/stream. 448 * 449 * Params: 450 * syncable = set if frame starts can be identified 451 */ 452 public void setSyncable(bool syncable) 453 { 454 gst_base_parse_set_syncable(gstBaseParse, syncable); 455 } 456 457 /** 458 * This function should only be called from a @handle_frame implementation. 459 * 460 * #GstBaseParse creates initial timestamps for frames by using the last 461 * timestamp seen in the stream before the frame starts. In certain 462 * cases, the correct timestamps will occur in the stream after the 463 * start of the frame, but before the start of the actual picture data. 464 * This function can be used to set the timestamps based on the offset 465 * into the frame data that the picture starts. 466 * 467 * Params: 468 * offset = offset into current buffer 469 * 470 * Since: 1.2 471 */ 472 public void setTsAtOffset(size_t offset) 473 { 474 gst_base_parse_set_ts_at_offset(gstBaseParse, offset); 475 } 476 }