changeset 8 | 4a7fac7dd34a |
parent 0 | 0e761a78d257 |
child 30 | 7e817e7e631c |
7:71e347f905f2 | 8:4a7fac7dd34a |
---|---|
22 * Boston, MA 02111-1307, USA. |
22 * Boston, MA 02111-1307, USA. |
23 */ |
23 */ |
24 |
24 |
25 /** |
25 /** |
26 * SECTION:element-queue |
26 * SECTION:element-queue |
27 * @short_description: Simple asynchronous data queue. |
|
28 * |
27 * |
29 * Data is queued until one of the limits specified by the |
28 * Data is queued until one of the limits specified by the |
30 * #GstQueue:max-size-buffers, #GstQueue:max-size-bytes and/or |
29 * #GstQueue:max-size-buffers, #GstQueue:max-size-bytes and/or |
31 * #GstQueue:max-size-time properties has been reached. Any attempt to push |
30 * #GstQueue:max-size-time properties has been reached. Any attempt to push |
32 * more buffers into the queue will block the pushing thread until more space |
31 * more buffers into the queue will block the pushing thread until more space |
53 * The #GstQueue::underrun signal is emitted when the queue has less data than |
52 * The #GstQueue::underrun signal is emitted when the queue has less data than |
54 * the specified minimum thresholds require (by default: when the queue is |
53 * the specified minimum thresholds require (by default: when the queue is |
55 * empty). The #GstQueue::overrun signal is emitted when the queue is filled |
54 * empty). The #GstQueue::overrun signal is emitted when the queue is filled |
56 * up. Both signals are emitted from the context of the streaming thread. |
55 * up. Both signals are emitted from the context of the streaming thread. |
57 */ |
56 */ |
58 #ifdef __SYMBIAN32__ |
|
59 #include <gst_global.h> |
|
60 #endif |
|
61 |
57 |
62 #include "gst/gst_private.h" |
58 #include "gst/gst_private.h" |
63 |
59 |
64 #include <gst/gst.h> |
60 #include <gst/gst.h> |
65 #include "gstqueue.h" |
61 #include "gstqueue.h" |
66 |
62 |
67 #include "../../gst/gst-i18n-lib.h" |
63 #include "../../gst/gst-i18n-lib.h" |
68 #ifdef __SYMBIAN32__ |
|
69 #include <glib_global.h> |
|
70 #include <gobject_global.h> |
|
71 |
|
72 #endif |
|
73 |
64 |
74 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", |
65 static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", |
75 GST_PAD_SINK, |
66 GST_PAD_SINK, |
76 GST_PAD_ALWAYS, |
67 GST_PAD_ALWAYS, |
77 GST_STATIC_CAPS_ANY); |
68 GST_STATIC_CAPS_ANY); |
203 static gboolean gst_queue_handle_sink_event (GstPad * pad, GstEvent * event); |
194 static gboolean gst_queue_handle_sink_event (GstPad * pad, GstEvent * event); |
204 |
195 |
205 static gboolean gst_queue_handle_src_event (GstPad * pad, GstEvent * event); |
196 static gboolean gst_queue_handle_src_event (GstPad * pad, GstEvent * event); |
206 static gboolean gst_queue_handle_src_query (GstPad * pad, GstQuery * query); |
197 static gboolean gst_queue_handle_src_query (GstPad * pad, GstQuery * query); |
207 |
198 |
199 static gboolean gst_queue_acceptcaps (GstPad * pad, GstCaps * caps); |
|
208 static GstCaps *gst_queue_getcaps (GstPad * pad); |
200 static GstCaps *gst_queue_getcaps (GstPad * pad); |
209 static GstPadLinkReturn gst_queue_link_sink (GstPad * pad, GstPad * peer); |
201 static GstPadLinkReturn gst_queue_link_sink (GstPad * pad, GstPad * peer); |
210 static GstPadLinkReturn gst_queue_link_src (GstPad * pad, GstPad * peer); |
202 static GstPadLinkReturn gst_queue_link_src (GstPad * pad, GstPad * peer); |
211 static void gst_queue_locked_flush (GstQueue * queue); |
203 static void gst_queue_locked_flush (GstQueue * queue); |
212 |
204 |
213 static gboolean gst_queue_src_activate_push (GstPad * pad, gboolean active); |
205 static gboolean gst_queue_src_activate_push (GstPad * pad, gboolean active); |
214 static gboolean gst_queue_sink_activate_push (GstPad * pad, gboolean active); |
206 static gboolean gst_queue_sink_activate_push (GstPad * pad, gboolean active); |
215 static GstStateChangeReturn gst_queue_change_state (GstElement * element, |
|
216 GstStateChange transition); |
|
217 |
207 |
218 static gboolean gst_queue_is_empty (GstQueue * queue); |
208 static gboolean gst_queue_is_empty (GstQueue * queue); |
219 static gboolean gst_queue_is_filled (GstQueue * queue); |
209 static gboolean gst_queue_is_filled (GstQueue * queue); |
220 |
210 |
221 #define GST_TYPE_QUEUE_LEAKY (queue_leaky_get_type ()) |
211 #define GST_TYPE_QUEUE_LEAKY (queue_leaky_get_type ()) |
256 |
246 |
257 static void |
247 static void |
258 gst_queue_class_init (GstQueueClass * klass) |
248 gst_queue_class_init (GstQueueClass * klass) |
259 { |
249 { |
260 GObjectClass *gobject_class = G_OBJECT_CLASS (klass); |
250 GObjectClass *gobject_class = G_OBJECT_CLASS (klass); |
261 GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); |
|
262 |
251 |
263 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_queue_set_property); |
252 gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_queue_set_property); |
264 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_queue_get_property); |
253 gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_queue_get_property); |
265 |
254 |
266 /* signals */ |
255 /* signals */ |
316 |
305 |
317 /* properties */ |
306 /* properties */ |
318 g_object_class_install_property (gobject_class, ARG_CUR_LEVEL_BYTES, |
307 g_object_class_install_property (gobject_class, ARG_CUR_LEVEL_BYTES, |
319 g_param_spec_uint ("current-level-bytes", "Current level (kB)", |
308 g_param_spec_uint ("current-level-bytes", "Current level (kB)", |
320 "Current amount of data in the queue (bytes)", |
309 "Current amount of data in the queue (bytes)", |
321 0, G_MAXUINT, 0, G_PARAM_READABLE)); |
310 0, G_MAXUINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); |
322 g_object_class_install_property (gobject_class, ARG_CUR_LEVEL_BUFFERS, |
311 g_object_class_install_property (gobject_class, ARG_CUR_LEVEL_BUFFERS, |
323 g_param_spec_uint ("current-level-buffers", "Current level (buffers)", |
312 g_param_spec_uint ("current-level-buffers", "Current level (buffers)", |
324 "Current number of buffers in the queue", |
313 "Current number of buffers in the queue", |
325 0, G_MAXUINT, 0, G_PARAM_READABLE)); |
314 0, G_MAXUINT, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); |
326 g_object_class_install_property (gobject_class, ARG_CUR_LEVEL_TIME, |
315 g_object_class_install_property (gobject_class, ARG_CUR_LEVEL_TIME, |
327 g_param_spec_uint64 ("current-level-time", "Current level (ns)", |
316 g_param_spec_uint64 ("current-level-time", "Current level (ns)", |
328 "Current amount of data in the queue (in ns)", |
317 "Current amount of data in the queue (in ns)", |
329 0, G_MAXUINT64, 0, G_PARAM_READABLE)); |
318 0, G_MAXUINT64, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); |
330 |
319 |
331 g_object_class_install_property (gobject_class, ARG_MAX_SIZE_BYTES, |
320 g_object_class_install_property (gobject_class, ARG_MAX_SIZE_BYTES, |
332 g_param_spec_uint ("max-size-bytes", "Max. size (kB)", |
321 g_param_spec_uint ("max-size-bytes", "Max. size (kB)", |
333 "Max. amount of data in the queue (bytes, 0=disable)", |
322 "Max. amount of data in the queue (bytes, 0=disable)", |
334 0, G_MAXUINT, DEFAULT_MAX_SIZE_BYTES, G_PARAM_READWRITE)); |
323 0, G_MAXUINT, DEFAULT_MAX_SIZE_BYTES, |
324 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
|
335 g_object_class_install_property (gobject_class, ARG_MAX_SIZE_BUFFERS, |
325 g_object_class_install_property (gobject_class, ARG_MAX_SIZE_BUFFERS, |
336 g_param_spec_uint ("max-size-buffers", "Max. size (buffers)", |
326 g_param_spec_uint ("max-size-buffers", "Max. size (buffers)", |
337 "Max. number of buffers in the queue (0=disable)", |
327 "Max. number of buffers in the queue (0=disable)", 0, G_MAXUINT, |
338 0, G_MAXUINT, DEFAULT_MAX_SIZE_BUFFERS, G_PARAM_READWRITE)); |
328 DEFAULT_MAX_SIZE_BUFFERS, |
329 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
|
339 g_object_class_install_property (gobject_class, ARG_MAX_SIZE_TIME, |
330 g_object_class_install_property (gobject_class, ARG_MAX_SIZE_TIME, |
340 g_param_spec_uint64 ("max-size-time", "Max. size (ns)", |
331 g_param_spec_uint64 ("max-size-time", "Max. size (ns)", |
341 "Max. amount of data in the queue (in ns, 0=disable)", |
332 "Max. amount of data in the queue (in ns, 0=disable)", 0, G_MAXUINT64, |
342 0, G_MAXUINT64, DEFAULT_MAX_SIZE_TIME, G_PARAM_READWRITE)); |
333 DEFAULT_MAX_SIZE_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
343 |
334 |
344 g_object_class_install_property (gobject_class, ARG_MIN_THRESHOLD_BYTES, |
335 g_object_class_install_property (gobject_class, ARG_MIN_THRESHOLD_BYTES, |
345 g_param_spec_uint ("min-threshold-bytes", "Min. threshold (kB)", |
336 g_param_spec_uint ("min-threshold-bytes", "Min. threshold (kB)", |
346 "Min. amount of data in the queue to allow reading (bytes, 0=disable)", |
337 "Min. amount of data in the queue to allow reading (bytes, 0=disable)", |
347 0, G_MAXUINT, 0, G_PARAM_READWRITE)); |
338 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
348 g_object_class_install_property (gobject_class, ARG_MIN_THRESHOLD_BUFFERS, |
339 g_object_class_install_property (gobject_class, ARG_MIN_THRESHOLD_BUFFERS, |
349 g_param_spec_uint ("min-threshold-buffers", "Min. threshold (buffers)", |
340 g_param_spec_uint ("min-threshold-buffers", "Min. threshold (buffers)", |
350 "Min. number of buffers in the queue to allow reading (0=disable)", |
341 "Min. number of buffers in the queue to allow reading (0=disable)", |
351 0, G_MAXUINT, 0, G_PARAM_READWRITE)); |
342 0, G_MAXUINT, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
352 g_object_class_install_property (gobject_class, ARG_MIN_THRESHOLD_TIME, |
343 g_object_class_install_property (gobject_class, ARG_MIN_THRESHOLD_TIME, |
353 g_param_spec_uint64 ("min-threshold-time", "Min. threshold (ns)", |
344 g_param_spec_uint64 ("min-threshold-time", "Min. threshold (ns)", |
354 "Min. amount of data in the queue to allow reading (in ns, 0=disable)", |
345 "Min. amount of data in the queue to allow reading (in ns, 0=disable)", |
355 0, G_MAXUINT64, 0, G_PARAM_READWRITE)); |
346 0, G_MAXUINT64, 0, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
356 |
347 |
357 g_object_class_install_property (gobject_class, ARG_LEAKY, |
348 g_object_class_install_property (gobject_class, ARG_LEAKY, |
358 g_param_spec_enum ("leaky", "Leaky", |
349 g_param_spec_enum ("leaky", "Leaky", |
359 "Where the queue leaks, if at all", |
350 "Where the queue leaks, if at all", |
360 GST_TYPE_QUEUE_LEAKY, GST_QUEUE_NO_LEAK, G_PARAM_READWRITE)); |
351 GST_TYPE_QUEUE_LEAKY, GST_QUEUE_NO_LEAK, |
352 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); |
|
361 |
353 |
362 /* set several parent class virtual functions */ |
354 /* set several parent class virtual functions */ |
363 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_queue_finalize); |
355 gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_queue_finalize); |
364 |
|
365 gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_queue_change_state); |
|
366 } |
356 } |
367 |
357 |
368 static void |
358 static void |
369 gst_queue_init (GstQueue * queue, GstQueueClass * g_class) |
359 gst_queue_init (GstQueue * queue, GstQueueClass * g_class) |
370 { |
360 { |
378 GST_DEBUG_FUNCPTR (gst_queue_handle_sink_event)); |
368 GST_DEBUG_FUNCPTR (gst_queue_handle_sink_event)); |
379 gst_pad_set_link_function (queue->sinkpad, |
369 gst_pad_set_link_function (queue->sinkpad, |
380 GST_DEBUG_FUNCPTR (gst_queue_link_sink)); |
370 GST_DEBUG_FUNCPTR (gst_queue_link_sink)); |
381 gst_pad_set_getcaps_function (queue->sinkpad, |
371 gst_pad_set_getcaps_function (queue->sinkpad, |
382 GST_DEBUG_FUNCPTR (gst_queue_getcaps)); |
372 GST_DEBUG_FUNCPTR (gst_queue_getcaps)); |
373 gst_pad_set_acceptcaps_function (queue->sinkpad, |
|
374 GST_DEBUG_FUNCPTR (gst_queue_acceptcaps)); |
|
383 gst_pad_set_bufferalloc_function (queue->sinkpad, |
375 gst_pad_set_bufferalloc_function (queue->sinkpad, |
384 GST_DEBUG_FUNCPTR (gst_queue_bufferalloc)); |
376 GST_DEBUG_FUNCPTR (gst_queue_bufferalloc)); |
385 gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad); |
377 gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad); |
386 |
378 |
387 queue->srcpad = gst_pad_new_from_static_template (&srctemplate, "src"); |
379 queue->srcpad = gst_pad_new_from_static_template (&srctemplate, "src"); |
388 |
380 |
389 gst_pad_set_activatepush_function (queue->srcpad, |
381 gst_pad_set_activatepush_function (queue->srcpad, |
390 GST_DEBUG_FUNCPTR (gst_queue_src_activate_push)); |
382 GST_DEBUG_FUNCPTR (gst_queue_src_activate_push)); |
391 gst_pad_set_link_function (queue->srcpad, |
383 gst_pad_set_link_function (queue->srcpad, |
392 GST_DEBUG_FUNCPTR (gst_queue_link_src)); |
384 GST_DEBUG_FUNCPTR (gst_queue_link_src)); |
385 gst_pad_set_acceptcaps_function (queue->srcpad, |
|
386 GST_DEBUG_FUNCPTR (gst_queue_acceptcaps)); |
|
393 gst_pad_set_getcaps_function (queue->srcpad, |
387 gst_pad_set_getcaps_function (queue->srcpad, |
394 GST_DEBUG_FUNCPTR (gst_queue_getcaps)); |
388 GST_DEBUG_FUNCPTR (gst_queue_getcaps)); |
395 gst_pad_set_event_function (queue->srcpad, |
389 gst_pad_set_event_function (queue->srcpad, |
396 GST_DEBUG_FUNCPTR (gst_queue_handle_src_event)); |
390 GST_DEBUG_FUNCPTR (gst_queue_handle_src_event)); |
397 gst_pad_set_query_function (queue->srcpad, |
391 gst_pad_set_query_function (queue->srcpad, |
437 g_mutex_free (queue->qlock); |
431 g_mutex_free (queue->qlock); |
438 g_cond_free (queue->item_add); |
432 g_cond_free (queue->item_add); |
439 g_cond_free (queue->item_del); |
433 g_cond_free (queue->item_del); |
440 |
434 |
441 G_OBJECT_CLASS (parent_class)->finalize (object); |
435 G_OBJECT_CLASS (parent_class)->finalize (object); |
436 } |
|
437 |
|
438 static gboolean |
|
439 gst_queue_acceptcaps (GstPad * pad, GstCaps * caps) |
|
440 { |
|
441 gboolean result; |
|
442 GstQueue *queue; |
|
443 GstPad *otherpad; |
|
444 |
|
445 queue = GST_QUEUE (GST_PAD_PARENT (pad)); |
|
446 |
|
447 otherpad = (pad == queue->srcpad ? queue->sinkpad : queue->srcpad); |
|
448 result = gst_pad_peer_accept_caps (otherpad, caps); |
|
449 |
|
450 return result; |
|
442 } |
451 } |
443 |
452 |
444 static GstCaps * |
453 static GstCaps * |
445 gst_queue_getcaps (GstPad * pad) |
454 gst_queue_getcaps (GstPad * pad) |
446 { |
455 { |
799 out_flushing: |
808 out_flushing: |
800 { |
809 { |
801 GST_CAT_LOG_OBJECT (queue_dataflow, queue, |
810 GST_CAT_LOG_OBJECT (queue_dataflow, queue, |
802 "refusing event, we are flushing"); |
811 "refusing event, we are flushing"); |
803 GST_QUEUE_MUTEX_UNLOCK (queue); |
812 GST_QUEUE_MUTEX_UNLOCK (queue); |
804 gst_buffer_unref (event); |
813 gst_event_unref (event); |
805 return FALSE; |
814 return FALSE; |
806 } |
815 } |
807 out_eos: |
816 out_eos: |
808 { |
817 { |
809 GST_CAT_LOG_OBJECT (queue_dataflow, queue, "refusing event, we are EOS"); |
818 GST_CAT_LOG_OBJECT (queue_dataflow, queue, "refusing event, we are EOS"); |
810 GST_QUEUE_MUTEX_UNLOCK (queue); |
819 GST_QUEUE_MUTEX_UNLOCK (queue); |
811 gst_buffer_unref (event); |
820 gst_event_unref (event); |
812 return FALSE; |
821 return FALSE; |
813 } |
822 } |
814 } |
823 } |
815 |
824 |
816 static gboolean |
825 static gboolean |
817 gst_queue_is_empty (GstQueue * queue) |
826 gst_queue_is_empty (GstQueue * queue) |
818 { |
827 { |
819 return (queue->queue->length == 0 || |
828 if (queue->queue->length == 0) |
820 (queue->min_threshold.buffers > 0 && |
829 return TRUE; |
830 |
|
831 /* It is possible that a max size is reached before all min thresholds are. |
|
832 * Therefore, only consider it empty if it is not filled. */ |
|
833 return ((queue->min_threshold.buffers > 0 && |
|
821 queue->cur_level.buffers < queue->min_threshold.buffers) || |
834 queue->cur_level.buffers < queue->min_threshold.buffers) || |
822 (queue->min_threshold.bytes > 0 && |
835 (queue->min_threshold.bytes > 0 && |
823 queue->cur_level.bytes < queue->min_threshold.bytes) || |
836 queue->cur_level.bytes < queue->min_threshold.bytes) || |
824 (queue->min_threshold.time > 0 && |
837 (queue->min_threshold.time > 0 && |
825 queue->cur_level.time < queue->min_threshold.time)); |
838 queue->cur_level.time < queue->min_threshold.time)) && |
839 !gst_queue_is_filled (queue); |
|
826 } |
840 } |
827 |
841 |
828 static gboolean |
842 static gboolean |
829 gst_queue_is_filled (GstQueue * queue) |
843 gst_queue_is_filled (GstQueue * queue) |
830 { |
844 { |
832 queue->cur_level.buffers >= queue->max_size.buffers) || |
846 queue->cur_level.buffers >= queue->max_size.buffers) || |
833 (queue->max_size.bytes > 0 && |
847 (queue->max_size.bytes > 0 && |
834 queue->cur_level.bytes >= queue->max_size.bytes) || |
848 queue->cur_level.bytes >= queue->max_size.bytes) || |
835 (queue->max_size.time > 0 && |
849 (queue->max_size.time > 0 && |
836 queue->cur_level.time >= queue->max_size.time))); |
850 queue->cur_level.time >= queue->max_size.time))); |
851 } |
|
852 |
|
853 static void |
|
854 gst_queue_leak_downstream (GstQueue * queue) |
|
855 { |
|
856 /* for as long as the queue is filled, dequeue an item and discard it */ |
|
857 while (gst_queue_is_filled (queue)) { |
|
858 GstMiniObject *leak; |
|
859 |
|
860 leak = gst_queue_locked_dequeue (queue); |
|
861 /* there is nothing to dequeue and the queue is still filled.. This should |
|
862 * not happen */ |
|
863 g_assert (leak != NULL); |
|
864 |
|
865 GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, |
|
866 "queue is full, leaking item %p on downstream end", leak); |
|
867 gst_mini_object_unref (leak); |
|
868 |
|
869 /* last buffer needs to get a DISCONT flag */ |
|
870 queue->head_needs_discont = TRUE; |
|
871 } |
|
837 } |
872 } |
838 |
873 |
839 static GstFlowReturn |
874 static GstFlowReturn |
840 gst_queue_chain (GstPad * pad, GstBuffer * buffer) |
875 gst_queue_chain (GstPad * pad, GstBuffer * buffer) |
841 { |
876 { |
881 GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, |
916 GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, |
882 "queue is full, leaking buffer on upstream end"); |
917 "queue is full, leaking buffer on upstream end"); |
883 /* now we can clean up and exit right away */ |
918 /* now we can clean up and exit right away */ |
884 goto out_unref; |
919 goto out_unref; |
885 case GST_QUEUE_LEAK_DOWNSTREAM: |
920 case GST_QUEUE_LEAK_DOWNSTREAM: |
886 { |
921 gst_queue_leak_downstream (queue); |
887 /* for as long as the queue is filled, dequeue an item and discard |
|
888 * it. */ |
|
889 do { |
|
890 GstMiniObject *leak; |
|
891 |
|
892 leak = gst_queue_locked_dequeue (queue); |
|
893 /* there is nothing to dequeue and the queue is still filled.. This |
|
894 * should not happen. */ |
|
895 g_assert (leak != NULL); |
|
896 |
|
897 GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, |
|
898 "queue is full, leaking item %p on downstream end", leak); |
|
899 gst_buffer_unref (leak); |
|
900 } while (gst_queue_is_filled (queue)); |
|
901 /* last buffer needs to get a DISCONT flag */ |
|
902 queue->head_needs_discont = TRUE; |
|
903 break; |
922 break; |
904 } |
|
905 default: |
923 default: |
906 g_warning ("Unknown leaky type, using default"); |
924 g_warning ("Unknown leaky type, using default"); |
907 /* fall-through */ |
925 /* fall-through */ |
908 case GST_QUEUE_NO_LEAK: |
926 case GST_QUEUE_NO_LEAK: |
909 { |
927 { |
1196 break; |
1214 break; |
1197 case GST_FORMAT_TIME: |
1215 case GST_FORMAT_TIME: |
1198 peer_pos -= queue->cur_level.time; |
1216 peer_pos -= queue->cur_level.time; |
1199 break; |
1217 break; |
1200 default: |
1218 default: |
1201 GST_WARNING_OBJECT (queue, "dropping query in %s format, don't " |
1219 GST_DEBUG_OBJECT (queue, "Can't adjust query in %s format, don't " |
1202 "know how to adjust value", gst_format_get_name (format)); |
1220 "know how to adjust value", gst_format_get_name (format)); |
1203 return FALSE; |
1221 return TRUE; |
1204 } |
1222 } |
1205 /* set updated position */ |
1223 /* set updated position */ |
1206 gst_query_set_position (query, format, peer_pos); |
1224 gst_query_set_position (query, format, peer_pos); |
1207 break; |
1225 break; |
1208 } |
1226 } |
1219 * possible right now. */ |
1237 * possible right now. */ |
1220 if (queue->max_size.time > 0 && max != -1) |
1238 if (queue->max_size.time > 0 && max != -1) |
1221 max += queue->max_size.time; |
1239 max += queue->max_size.time; |
1222 else |
1240 else |
1223 max = -1; |
1241 max = -1; |
1242 |
|
1243 /* adjust for min-threshold */ |
|
1244 if (queue->min_threshold.time > 0 && min != -1) |
|
1245 min += queue->min_threshold.time; |
|
1224 |
1246 |
1225 gst_query_set_latency (query, live, min, max); |
1247 gst_query_set_latency (query, live, min, max); |
1226 break; |
1248 break; |
1227 } |
1249 } |
1228 default: |
1250 default: |
1296 gst_object_unref (queue); |
1318 gst_object_unref (queue); |
1297 |
1319 |
1298 return result; |
1320 return result; |
1299 } |
1321 } |
1300 |
1322 |
1301 static GstStateChangeReturn |
1323 static void |
1302 gst_queue_change_state (GstElement * element, GstStateChange transition) |
1324 queue_capacity_change (GstQueue * queue) |
1303 { |
1325 { |
1304 GstQueue *queue; |
1326 if (queue->leaky == GST_QUEUE_LEAK_DOWNSTREAM) { |
1305 GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS; |
1327 gst_queue_leak_downstream (queue); |
1306 |
1328 } |
1307 queue = GST_QUEUE (element); |
1329 |
1308 |
1330 /* changing the capacity of the queue must wake up |
1309 switch (transition) { |
1331 * the _chain function, it might have more room now |
1310 case GST_STATE_CHANGE_NULL_TO_READY: |
1332 * to store the buffer/event in the queue */ |
1311 break; |
1333 GST_QUEUE_SIGNAL_DEL (queue); |
1312 case GST_STATE_CHANGE_READY_TO_PAUSED: |
1334 } |
1313 break; |
|
1314 case GST_STATE_CHANGE_PAUSED_TO_PLAYING: |
|
1315 break; |
|
1316 default: |
|
1317 break; |
|
1318 } |
|
1319 |
|
1320 ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); |
|
1321 |
|
1322 switch (transition) { |
|
1323 case GST_STATE_CHANGE_PLAYING_TO_PAUSED: |
|
1324 break; |
|
1325 case GST_STATE_CHANGE_PAUSED_TO_READY: |
|
1326 break; |
|
1327 case GST_STATE_CHANGE_READY_TO_NULL: |
|
1328 break; |
|
1329 default: |
|
1330 break; |
|
1331 } |
|
1332 |
|
1333 return ret; |
|
1334 } |
|
1335 |
|
1336 /* changing the capacity of the queue must wake up |
|
1337 * the _chain function, it might have more room now |
|
1338 * to store the buffer/event in the queue */ |
|
1339 #define QUEUE_CAPACITY_CHANGE(q)\ |
|
1340 GST_QUEUE_SIGNAL_DEL (q); |
|
1341 |
1335 |
1342 /* Changing the minimum required fill level must |
1336 /* Changing the minimum required fill level must |
1343 * wake up the _loop function as it might now |
1337 * wake up the _loop function as it might now |
1344 * be able to preceed. |
1338 * be able to preceed. |
1345 */ |
1339 */ |
1357 GST_QUEUE_MUTEX_LOCK (queue); |
1351 GST_QUEUE_MUTEX_LOCK (queue); |
1358 |
1352 |
1359 switch (prop_id) { |
1353 switch (prop_id) { |
1360 case ARG_MAX_SIZE_BYTES: |
1354 case ARG_MAX_SIZE_BYTES: |
1361 queue->max_size.bytes = g_value_get_uint (value); |
1355 queue->max_size.bytes = g_value_get_uint (value); |
1362 QUEUE_CAPACITY_CHANGE (queue); |
1356 queue_capacity_change (queue); |
1363 break; |
1357 break; |
1364 case ARG_MAX_SIZE_BUFFERS: |
1358 case ARG_MAX_SIZE_BUFFERS: |
1365 queue->max_size.buffers = g_value_get_uint (value); |
1359 queue->max_size.buffers = g_value_get_uint (value); |
1366 QUEUE_CAPACITY_CHANGE (queue); |
1360 queue_capacity_change (queue); |
1367 break; |
1361 break; |
1368 case ARG_MAX_SIZE_TIME: |
1362 case ARG_MAX_SIZE_TIME: |
1369 queue->max_size.time = g_value_get_uint64 (value); |
1363 queue->max_size.time = g_value_get_uint64 (value); |
1370 QUEUE_CAPACITY_CHANGE (queue); |
1364 queue_capacity_change (queue); |
1371 break; |
1365 break; |
1372 case ARG_MIN_THRESHOLD_BYTES: |
1366 case ARG_MIN_THRESHOLD_BYTES: |
1373 queue->min_threshold.bytes = g_value_get_uint (value); |
1367 queue->min_threshold.bytes = g_value_get_uint (value); |
1374 queue->orig_min_threshold.bytes = queue->min_threshold.bytes; |
1368 queue->orig_min_threshold.bytes = queue->min_threshold.bytes; |
1375 QUEUE_THRESHOLD_CHANGE (queue); |
1369 QUEUE_THRESHOLD_CHANGE (queue); |