| 1 | /* GStreamer aggregator base class |
| 2 | * Copyright (C) 2014 Mathieu Duponchelle <mathieu.duponchelle@oencreed.com> |
| 3 | * Copyright (C) 2014 Thibault Saunier <tsaunier@gnome.org> |
| 4 | * |
| 5 | * This library is free software; you can redistribute it and/or |
| 6 | * modify it under the terms of the GNU Library General Public |
| 7 | * License as published by the Free Software Foundation; either |
| 8 | * version 2 of the License, or (at your option) any later version. |
| 9 | * |
| 10 | * This library 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 GNU |
| 13 | * Library General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU Library General Public |
| 16 | * License along with this library; if not, write to the |
| 17 | * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
| 18 | * Boston, MA 02110-1301, USA. |
| 19 | */ |
| 20 | |
| 21 | #ifndef __GST_AGGREGATOR_H__ |
| 22 | #define __GST_AGGREGATOR_H__ |
| 23 | |
| 24 | #include <gst/gst.h> |
| 25 | #include <gst/base/base-prelude.h> |
| 26 | |
| 27 | G_BEGIN_DECLS |
| 28 | |
| 29 | /************************** |
| 30 | * GstAggregator Structs * |
| 31 | *************************/ |
| 32 | |
| 33 | typedef struct _GstAggregator GstAggregator; |
| 34 | typedef struct _GstAggregatorPrivate GstAggregatorPrivate; |
| 35 | typedef struct _GstAggregatorClass GstAggregatorClass; |
| 36 | |
| 37 | /************************ |
| 38 | * GstAggregatorPad API * |
| 39 | ***********************/ |
| 40 | |
| 41 | #define GST_TYPE_AGGREGATOR_PAD (gst_aggregator_pad_get_type()) |
| 42 | #define GST_AGGREGATOR_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AGGREGATOR_PAD, GstAggregatorPad)) |
| 43 | #define GST_AGGREGATOR_PAD_CAST(obj) ((GstAggregatorPad *)(obj)) |
| 44 | #define GST_AGGREGATOR_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AGGREGATOR_PAD, GstAggregatorPadClass)) |
| 45 | #define GST_AGGREGATOR_PAD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),GST_TYPE_AGGREGATOR_PAD, GstAggregatorPadClass)) |
| 46 | #define GST_IS_AGGREGATOR_PAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AGGREGATOR_PAD)) |
| 47 | #define GST_IS_AGGREGATOR_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AGGREGATOR_PAD)) |
| 48 | |
| 49 | /**************************** |
| 50 | * GstAggregatorPad Structs * |
| 51 | ***************************/ |
| 52 | |
| 53 | typedef struct _GstAggregatorPad GstAggregatorPad; |
| 54 | typedef struct _GstAggregatorPadClass GstAggregatorPadClass; |
| 55 | typedef struct _GstAggregatorPadPrivate GstAggregatorPadPrivate; |
| 56 | |
| 57 | /** |
| 58 | * GstAggregatorPad: |
| 59 | * @segment: last segment received. |
| 60 | * |
| 61 | * The implementation the GstPad to use with #GstAggregator |
| 62 | * |
| 63 | * Since: 1.14 |
| 64 | */ |
| 65 | struct _GstAggregatorPad |
| 66 | { |
| 67 | GstPad parent; |
| 68 | |
| 69 | /*< public >*/ |
| 70 | /* Protected by the OBJECT_LOCK */ |
| 71 | GstSegment segment; |
| 72 | |
| 73 | /* < private > */ |
| 74 | GstAggregatorPadPrivate * priv; |
| 75 | |
| 76 | gpointer _gst_reserved[GST_PADDING]; |
| 77 | }; |
| 78 | |
| 79 | /** |
| 80 | * GstAggregatorPadClass: |
| 81 | * @flush: Optional |
| 82 | * Called when the pad has received a flush stop, this is the place |
| 83 | * to flush any information specific to the pad, it allows for individual |
| 84 | * pads to be flushed while others might not be. |
| 85 | * @skip_buffer: Optional |
| 86 | * Called before input buffers are queued in the pad, return %TRUE |
| 87 | * if the buffer should be skipped. |
| 88 | * |
| 89 | * Since: 1.14 |
| 90 | */ |
| 91 | struct _GstAggregatorPadClass |
| 92 | { |
| 93 | GstPadClass parent_class; |
| 94 | |
| 95 | GstFlowReturn (*flush) (GstAggregatorPad * aggpad, GstAggregator * aggregator); |
| 96 | gboolean (*skip_buffer) (GstAggregatorPad * aggpad, GstAggregator * aggregator, GstBuffer * buffer); |
| 97 | |
| 98 | /*< private >*/ |
| 99 | gpointer _gst_reserved[GST_PADDING_LARGE]; |
| 100 | }; |
| 101 | |
| 102 | GST_BASE_API |
| 103 | GType gst_aggregator_pad_get_type (void); |
| 104 | |
| 105 | /**************************** |
| 106 | * GstAggregatorPad methods * |
| 107 | ***************************/ |
| 108 | |
| 109 | GST_BASE_API |
| 110 | GstBuffer * gst_aggregator_pad_pop_buffer (GstAggregatorPad * pad); |
| 111 | |
| 112 | GST_BASE_API |
| 113 | GstBuffer * gst_aggregator_pad_peek_buffer (GstAggregatorPad * pad); |
| 114 | |
| 115 | GST_BASE_API |
| 116 | gboolean gst_aggregator_pad_drop_buffer (GstAggregatorPad * pad); |
| 117 | |
| 118 | GST_BASE_API |
| 119 | gboolean gst_aggregator_pad_has_buffer (GstAggregatorPad * pad); |
| 120 | |
| 121 | GST_BASE_API |
| 122 | gboolean gst_aggregator_pad_is_eos (GstAggregatorPad * pad); |
| 123 | |
| 124 | GST_BASE_API |
| 125 | gboolean gst_aggregator_pad_is_inactive (GstAggregatorPad * pad); |
| 126 | |
| 127 | /********************* |
| 128 | * GstAggregator API * |
| 129 | ********************/ |
| 130 | |
| 131 | #define GST_TYPE_AGGREGATOR (gst_aggregator_get_type()) |
| 132 | #define GST_AGGREGATOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_AGGREGATOR,GstAggregator)) |
| 133 | #define GST_AGGREGATOR_CAST(obj) ((GstAggregator *)(obj)) |
| 134 | #define GST_AGGREGATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_AGGREGATOR,GstAggregatorClass)) |
| 135 | #define GST_AGGREGATOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),GST_TYPE_AGGREGATOR,GstAggregatorClass)) |
| 136 | #define GST_IS_AGGREGATOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_AGGREGATOR)) |
| 137 | #define GST_IS_AGGREGATOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_AGGREGATOR)) |
| 138 | |
| 139 | #define GST_AGGREGATOR_FLOW_NEED_DATA GST_FLOW_CUSTOM_ERROR |
| 140 | |
| 141 | /** |
| 142 | * GstAggregator: |
| 143 | * @srcpad: the aggregator's source pad |
| 144 | * |
| 145 | * Aggregator base class object structure. |
| 146 | * |
| 147 | * Since: 1.14 |
| 148 | */ |
| 149 | struct _GstAggregator |
| 150 | { |
| 151 | GstElement parent; |
| 152 | |
| 153 | /*< public >*/ |
| 154 | GstPad * srcpad; |
| 155 | |
| 156 | /*< private >*/ |
| 157 | GstAggregatorPrivate * priv; |
| 158 | |
| 159 | gpointer _gst_reserved[GST_PADDING_LARGE]; |
| 160 | }; |
| 161 | |
| 162 | /** |
| 163 | * GstAggregatorClass: |
| 164 | * @flush: Optional. |
| 165 | * Called after a successful flushing seek, once all the flush |
| 166 | * stops have been received. Flush pad-specific data in |
| 167 | * #GstAggregatorPad->flush. |
| 168 | * @clip: Optional. |
| 169 | * Called when a buffer is received on a sink pad, the task of |
| 170 | * clipping it and translating it to the current segment falls |
| 171 | * on the subclass. The function should use the segment of data |
| 172 | * and the negotiated media type on the pad to perform |
| 173 | * clipping of input buffer. This function takes ownership of |
| 174 | * buf and should output a buffer or return NULL in |
| 175 | * if the buffer should be dropped. |
| 176 | * @finish_buffer: Optional. |
| 177 | * Called when a subclass calls gst_aggregator_finish_buffer() |
| 178 | * from their aggregate function to push out a buffer. |
| 179 | * Subclasses can override this to modify or decorate buffers |
| 180 | * before they get pushed out. This function takes ownership |
| 181 | * of the buffer passed. Subclasses that override this method |
| 182 | * should always chain up to the parent class virtual method. |
| 183 | * @sink_event: Optional. |
| 184 | * Called when an event is received on a sink pad, the subclass |
| 185 | * should always chain up. |
| 186 | * @sink_query: Optional. |
| 187 | * Called when a query is received on a sink pad, the subclass |
| 188 | * should always chain up. |
| 189 | * @src_event: Optional. |
| 190 | * Called when an event is received on the src pad, the subclass |
| 191 | * should always chain up. |
| 192 | * @src_query: Optional. |
| 193 | * Called when a query is received on the src pad, the subclass |
| 194 | * should always chain up. |
| 195 | * @src_activate: Optional. |
| 196 | * Called when the src pad is activated, it will start/stop its |
| 197 | * pad task right after that call. |
| 198 | * @aggregate: Mandatory. |
| 199 | * Called when buffers are queued on all sinkpads. Classes |
| 200 | * should iterate the GstElement->sinkpads and peek or steal |
| 201 | * buffers from the #GstAggregatorPads. If the subclass returns |
| 202 | * GST_FLOW_EOS, sending of the eos event will be taken care |
| 203 | * of. Once / if a buffer has been constructed from the |
| 204 | * aggregated buffers, the subclass should call _finish_buffer. |
| 205 | * @stop: Optional. |
| 206 | * Called when the element goes from PAUSED to READY. |
| 207 | * The subclass should free all resources and reset its state. |
| 208 | * @start: Optional. |
| 209 | * Called when the element goes from READY to PAUSED. |
| 210 | * The subclass should get ready to process |
| 211 | * aggregated buffers. |
| 212 | * @get_next_time: Optional. |
| 213 | * Called when the element needs to know the running time of the next |
| 214 | * rendered buffer for live pipelines. This causes deadline |
| 215 | * based aggregation to occur. Defaults to returning |
| 216 | * GST_CLOCK_TIME_NONE causing the element to wait for buffers |
| 217 | * on all sink pads before aggregating. |
| 218 | * @create_new_pad: Optional. |
| 219 | * Called when a new pad needs to be created. Allows subclass that |
| 220 | * don't have a single sink pad template to provide a pad based |
| 221 | * on the provided information. |
| 222 | * @update_src_caps: Lets subclasses update the #GstCaps representing |
| 223 | * the src pad caps before usage. The result should end up |
| 224 | * in @ret. Return %GST_AGGREGATOR_FLOW_NEED_DATA to indicate that the |
| 225 | * element needs more information (caps, a buffer, etc) to |
| 226 | * choose the correct caps. Should return ANY caps if the |
| 227 | * stream has not caps at all. |
| 228 | * @fixate_src_caps: Optional. |
| 229 | * Fixate and return the src pad caps provided. The function takes |
| 230 | * ownership of @caps and returns a fixated version of |
| 231 | * @caps. @caps is not guaranteed to be writable. |
| 232 | * @negotiated_src_caps: Optional. |
| 233 | * Notifies subclasses what caps format has been negotiated |
| 234 | * @decide_allocation: Optional. |
| 235 | * Allows the subclass to influence the allocation choices. |
| 236 | * Setup the allocation parameters for allocating output |
| 237 | * buffers. The passed in query contains the result of the |
| 238 | * downstream allocation query. |
| 239 | * @propose_allocation: Optional. |
| 240 | * Allows the subclass to handle the allocation query from upstream. |
| 241 | * @negotiate: Optional. |
| 242 | * Negotiate the caps with the peer (Since: 1.18). |
| 243 | * @sink_event_pre_queue: Optional. |
| 244 | * Called when an event is received on a sink pad before queueing up |
| 245 | * serialized events. The subclass should always chain up (Since: 1.18). |
| 246 | * @sink_query_pre_queue: Optional. |
| 247 | * Called when a query is received on a sink pad before queueing up |
| 248 | * serialized queries. The subclass should always chain up (Since: 1.18). |
| 249 | * |
| 250 | * The aggregator base class will handle in a thread-safe way all manners of |
| 251 | * concurrent flushes, seeks, pad additions and removals, leaving to the |
| 252 | * subclass the responsibility of clipping buffers, and aggregating buffers in |
| 253 | * the way the implementor sees fit. |
| 254 | * |
| 255 | * It will also take care of event ordering (stream-start, segment, eos). |
| 256 | * |
| 257 | * Basically, a simple implementation will override @aggregate, and call |
| 258 | * _finish_buffer from inside that function. |
| 259 | * |
| 260 | * Since: 1.14 |
| 261 | */ |
| 262 | struct _GstAggregatorClass { |
| 263 | GstElementClass parent_class; |
| 264 | |
| 265 | GstFlowReturn (*flush) (GstAggregator * aggregator); |
| 266 | |
| 267 | GstBuffer * (*clip) (GstAggregator * aggregator, |
| 268 | GstAggregatorPad * aggregator_pad, |
| 269 | GstBuffer * buf); |
| 270 | |
| 271 | GstFlowReturn (*finish_buffer) (GstAggregator * aggregator, |
| 272 | GstBuffer * buffer); |
| 273 | |
| 274 | /* sinkpads virtual methods */ |
| 275 | gboolean (*sink_event) (GstAggregator * aggregator, |
| 276 | GstAggregatorPad * aggregator_pad, |
| 277 | GstEvent * event); |
| 278 | |
| 279 | gboolean (*sink_query) (GstAggregator * aggregator, |
| 280 | GstAggregatorPad * aggregator_pad, |
| 281 | GstQuery * query); |
| 282 | |
| 283 | /* srcpad virtual methods */ |
| 284 | gboolean (*src_event) (GstAggregator * aggregator, |
| 285 | GstEvent * event); |
| 286 | |
| 287 | gboolean (*src_query) (GstAggregator * aggregator, |
| 288 | GstQuery * query); |
| 289 | |
| 290 | gboolean (*src_activate) (GstAggregator * aggregator, |
| 291 | GstPadMode mode, |
| 292 | gboolean active); |
| 293 | |
| 294 | GstFlowReturn (*aggregate) (GstAggregator * aggregator, |
| 295 | gboolean timeout); |
| 296 | |
| 297 | gboolean (*stop) (GstAggregator * aggregator); |
| 298 | |
| 299 | gboolean (*start) (GstAggregator * aggregator); |
| 300 | |
| 301 | GstClockTime (*get_next_time) (GstAggregator * aggregator); |
| 302 | |
| 303 | GstAggregatorPad * (*create_new_pad) (GstAggregator * self, |
| 304 | GstPadTemplate * templ, |
| 305 | const gchar * req_name, |
| 306 | const GstCaps * caps); |
| 307 | |
| 308 | /** |
| 309 | * GstAggregatorClass::update_src_caps: |
| 310 | * @ret: (out) (allow-none): |
| 311 | */ |
| 312 | GstFlowReturn (*update_src_caps) (GstAggregator * self, |
| 313 | GstCaps * caps, |
| 314 | GstCaps ** ret); |
| 315 | GstCaps * (*fixate_src_caps) (GstAggregator * self, |
| 316 | GstCaps * caps); |
| 317 | gboolean (*negotiated_src_caps) (GstAggregator * self, |
| 318 | GstCaps * caps); |
| 319 | gboolean (*decide_allocation) (GstAggregator * self, |
| 320 | GstQuery * query); |
| 321 | gboolean (*propose_allocation) (GstAggregator * self, |
| 322 | GstAggregatorPad * pad, |
| 323 | GstQuery * decide_query, |
| 324 | GstQuery * query); |
| 325 | |
| 326 | gboolean (*negotiate) (GstAggregator * self); |
| 327 | |
| 328 | GstFlowReturn (*sink_event_pre_queue) (GstAggregator * aggregator, |
| 329 | GstAggregatorPad * aggregator_pad, |
| 330 | GstEvent * event); |
| 331 | |
| 332 | gboolean (*sink_query_pre_queue) (GstAggregator * aggregator, |
| 333 | GstAggregatorPad * aggregator_pad, |
| 334 | GstQuery * query); |
| 335 | |
| 336 | /** |
| 337 | * GstAggregatorClass::finish_buffer_list: |
| 338 | * |
| 339 | * Optional. Equivalent of #GstAggregatorClass::finish_buffer for |
| 340 | * buffer lists. |
| 341 | * |
| 342 | * Since: 1.18 |
| 343 | */ |
| 344 | GstFlowReturn (*finish_buffer_list) (GstAggregator * aggregator, |
| 345 | GstBufferList * bufferlist); |
| 346 | /** |
| 347 | * GstAggregatorClass::peek_next_sample: |
| 348 | * |
| 349 | * See gst_aggregator_peek_next_sample(). |
| 350 | * |
| 351 | * Since: 1.18 |
| 352 | */ |
| 353 | GstSample * (*peek_next_sample) (GstAggregator *aggregator, |
| 354 | GstAggregatorPad * aggregator_pad); |
| 355 | |
| 356 | /*< private >*/ |
| 357 | gpointer _gst_reserved[GST_PADDING_LARGE-5]; |
| 358 | }; |
| 359 | |
| 360 | /************************************ |
| 361 | * GstAggregator convenience macros * |
| 362 | ***********************************/ |
| 363 | |
| 364 | /** |
| 365 | * GST_AGGREGATOR_SRC_PAD: |
| 366 | * @agg: a #GstAggregator |
| 367 | * |
| 368 | * Convenience macro to access the source pad of #GstAggregator |
| 369 | * |
| 370 | * Since: 1.6 |
| 371 | */ |
| 372 | #define GST_AGGREGATOR_SRC_PAD(agg) (((GstAggregator *)(agg))->srcpad) |
| 373 | |
| 374 | /************************* |
| 375 | * GstAggregator methods * |
| 376 | ************************/ |
| 377 | |
| 378 | GST_BASE_API |
| 379 | GstFlowReturn gst_aggregator_finish_buffer (GstAggregator * aggregator, |
| 380 | GstBuffer * buffer); |
| 381 | |
| 382 | GST_BASE_API |
| 383 | GstFlowReturn gst_aggregator_finish_buffer_list (GstAggregator * aggregator, |
| 384 | GstBufferList * bufferlist); |
| 385 | |
| 386 | GST_BASE_API |
| 387 | void gst_aggregator_set_src_caps (GstAggregator * self, |
| 388 | GstCaps * caps); |
| 389 | |
| 390 | GST_BASE_API |
| 391 | gboolean gst_aggregator_negotiate (GstAggregator * self); |
| 392 | |
| 393 | GST_BASE_API |
| 394 | void gst_aggregator_set_latency (GstAggregator * self, |
| 395 | GstClockTime min_latency, |
| 396 | GstClockTime max_latency); |
| 397 | |
| 398 | GST_BASE_API |
| 399 | GType gst_aggregator_get_type(void); |
| 400 | |
| 401 | GST_BASE_API |
| 402 | GstClockTime gst_aggregator_get_latency (GstAggregator * self); |
| 403 | |
| 404 | GST_BASE_API |
| 405 | GstBufferPool * gst_aggregator_get_buffer_pool (GstAggregator * self); |
| 406 | |
| 407 | GST_BASE_API |
| 408 | void gst_aggregator_get_allocator (GstAggregator * self, |
| 409 | GstAllocator ** allocator, |
| 410 | GstAllocationParams * params); |
| 411 | |
| 412 | GST_BASE_API |
| 413 | GstClockTime gst_aggregator_simple_get_next_time (GstAggregator * self); |
| 414 | |
| 415 | GST_BASE_API |
| 416 | void gst_aggregator_update_segment (GstAggregator * self, |
| 417 | const GstSegment * segment); |
| 418 | |
| 419 | GST_BASE_API |
| 420 | GstSample * gst_aggregator_peek_next_sample (GstAggregator *self, |
| 421 | GstAggregatorPad * pad); |
| 422 | |
| 423 | GST_BASE_API |
| 424 | void gst_aggregator_selected_samples (GstAggregator * self, |
| 425 | GstClockTime pts, |
| 426 | GstClockTime dts, |
| 427 | GstClockTime duration, |
| 428 | GstStructure * info); |
| 429 | |
| 430 | GST_BASE_API |
| 431 | void gst_aggregator_set_ignore_inactive_pads (GstAggregator * self, |
| 432 | gboolean ignore); |
| 433 | |
| 434 | GST_BASE_API |
| 435 | gboolean gst_aggregator_get_ignore_inactive_pads (GstAggregator * self); |
| 436 | |
| 437 | GST_BASE_API |
| 438 | gboolean gst_aggregator_get_force_live (GstAggregator *self); |
| 439 | |
| 440 | GST_BASE_API |
| 441 | void gst_aggregator_set_force_live (GstAggregator *self, |
| 442 | gboolean force_live); |
| 443 | |
| 444 | /** |
| 445 | * GstAggregatorStartTimeSelection: |
| 446 | * @GST_AGGREGATOR_START_TIME_SELECTION_ZERO: Start at running time 0. |
| 447 | * @GST_AGGREGATOR_START_TIME_SELECTION_FIRST: Start at the running time of |
| 448 | * the first buffer that is received. |
| 449 | * @GST_AGGREGATOR_START_TIME_SELECTION_SET: Start at the running time |
| 450 | * selected by the `start-time` property. |
| 451 | * |
| 452 | * Since: 1.18 |
| 453 | */ |
| 454 | typedef enum |
| 455 | { |
| 456 | GST_AGGREGATOR_START_TIME_SELECTION_ZERO, |
| 457 | GST_AGGREGATOR_START_TIME_SELECTION_FIRST, |
| 458 | GST_AGGREGATOR_START_TIME_SELECTION_SET |
| 459 | } GstAggregatorStartTimeSelection; |
| 460 | |
| 461 | GST_BASE_API |
| 462 | GType gst_aggregator_start_time_selection_get_type (void); |
| 463 | |
| 464 | G_END_DECLS |
| 465 | |
| 466 | G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstAggregator, gst_object_unref) |
| 467 | G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstAggregatorPad, gst_object_unref) |
| 468 | |
| 469 | #endif /* __GST_AGGREGATOR_H__ */ |
| 470 | |