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 | /** |
438 | * GstAggregatorStartTimeSelection: |
439 | * @GST_AGGREGATOR_START_TIME_SELECTION_ZERO: Start at running time 0. |
440 | * @GST_AGGREGATOR_START_TIME_SELECTION_FIRST: Start at the running time of |
441 | * the first buffer that is received. |
442 | * @GST_AGGREGATOR_START_TIME_SELECTION_SET: Start at the running time |
443 | * selected by the `start-time` property. |
444 | * |
445 | * Since: 1.18 |
446 | */ |
447 | typedef enum |
448 | { |
449 | GST_AGGREGATOR_START_TIME_SELECTION_ZERO, |
450 | GST_AGGREGATOR_START_TIME_SELECTION_FIRST, |
451 | GST_AGGREGATOR_START_TIME_SELECTION_SET |
452 | } GstAggregatorStartTimeSelection; |
453 | |
454 | GST_BASE_API |
455 | GType gst_aggregator_start_time_selection_get_type (void); |
456 | |
457 | G_END_DECLS |
458 | |
459 | G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstAggregator, gst_object_unref) |
460 | G_DEFINE_AUTOPTR_CLEANUP_FUNC(GstAggregatorPad, gst_object_unref) |
461 | |
462 | #endif /* __GST_AGGREGATOR_H__ */ |
463 | |