void gst_vlc_dec_ensure_empty_queue( decoder_t *p_dec ) { decoder_sys_t *p_sys = p_dec->p_sys; int i_count = 0; msg_Dbg( p_dec, "Ensuring the decoder queue is empty"); /* Busy wait with sleep; As this is rare case and the * wait might at max go for 3-4 iterations, preferred to not * to throw in a cond/lock here. */ while( p_sys->b_running && i_count < 60 && gst_atomic_queue_length( p_sys->p_que )) { msleep ( 15000 ); i_count++; } if( p_sys->b_running ) { if( !gst_atomic_queue_length( p_sys->p_que )) msg_Dbg( p_dec, "Ensured the decoder queue is empty" ); else msg_Warn( p_dec, "Timed out when ensuring an empty queue" ); } else msg_Dbg( p_dec, "Ensuring empty decoder queue not required; decoder \ not running" ); }
/** * gst_bus_have_pending: * @bus: a #GstBus to check * * Check if there are pending messages on the bus that * should be handled. * * Returns: %TRUE if there are messages on the bus to be handled, %FALSE * otherwise. * * MT safe. */ gboolean gst_bus_have_pending (GstBus * bus) { gboolean result; g_return_val_if_fail (GST_IS_BUS (bus), FALSE); /* see if there is a message on the bus */ result = gst_atomic_queue_length (bus->priv->queue) != 0; return result; }
GstV4l2Return gst_v4l2_allocator_stop (GstV4l2Allocator * allocator) { GstV4l2Object *obj = allocator->obj; struct v4l2_requestbuffers breq = { 0, obj->type, allocator->memory }; gint i = 0; GstV4l2Return ret = GST_V4L2_OK; GST_DEBUG_OBJECT (allocator, "stop allocator"); GST_OBJECT_LOCK (allocator); if (!g_atomic_int_get (&allocator->active)) goto done; if (gst_atomic_queue_length (allocator->free_queue) != allocator->count) { GST_DEBUG_OBJECT (allocator, "allocator is still in use"); ret = GST_V4L2_BUSY; goto done; } while (gst_atomic_queue_pop (allocator->free_queue)) { /* nothing */ }; for (i = 0; i < allocator->count; i++) { GstV4l2MemoryGroup *group = allocator->groups[i]; allocator->groups[i] = NULL; if (group) gst_v4l2_memory_group_free (group); } /* Not all drivers support rebufs(0), so warn only */ if (obj->ioctl (obj->video_fd, VIDIOC_REQBUFS, &breq) < 0) GST_WARNING_OBJECT (allocator, "error releasing buffers buffers: %s", g_strerror (errno)); allocator->count = 0; g_atomic_int_set (&allocator->active, FALSE); done: GST_OBJECT_UNLOCK (allocator); return ret; }
/** * gst_bus_timed_pop_filtered: * @bus: a #GstBus to pop from * @timeout: a timeout in nanoseconds, or GST_CLOCK_TIME_NONE to wait forever * @types: message types to take into account, GST_MESSAGE_ANY for any type * * Get a message from the bus whose type matches the message type mask @types, * waiting up to the specified timeout (and discarding any messages that do not * match the mask provided). * * If @timeout is 0, this function behaves like gst_bus_pop_filtered(). If * @timeout is #GST_CLOCK_TIME_NONE, this function will block forever until a * matching message was posted on the bus. * * Returns: (transfer full) (nullable): a #GstMessage matching the * filter in @types, or %NULL if no matching message was found on * the bus until the timeout expired. The message is taken from * the bus and needs to be unreffed with gst_message_unref() after * usage. * * MT safe. */ GstMessage * gst_bus_timed_pop_filtered (GstBus * bus, GstClockTime timeout, GstMessageType types) { GstMessage *message; GTimeVal now, then; gboolean first_round = TRUE; GstClockTime elapsed = 0; g_return_val_if_fail (GST_IS_BUS (bus), NULL); g_return_val_if_fail (types != 0, NULL); g_return_val_if_fail (timeout == 0 || bus->priv->poll != NULL, NULL); g_mutex_lock (&bus->priv->queue_lock); while (TRUE) { gint ret; GST_LOG_OBJECT (bus, "have %d messages", gst_atomic_queue_length (bus->priv->queue)); while ((message = gst_atomic_queue_pop (bus->priv->queue))) { if (bus->priv->poll) { while (!gst_poll_read_control (bus->priv->poll)) { if (errno == EWOULDBLOCK) { /* Retry, this can happen if pushing to the queue has finished, * popping here succeeded but writing control did not finish * before we got to this line. */ /* Give other threads the chance to do something */ g_thread_yield (); continue; } else { /* This is a real error and means that either the bus is in an * inconsistent state, or the GstPoll is invalid. GstPoll already * prints a critical warning about this, no need to do that again * ourselves */ break; } } } GST_DEBUG_OBJECT (bus, "got message %p, %s from %s, type mask is %u", message, GST_MESSAGE_TYPE_NAME (message), GST_MESSAGE_SRC_NAME (message), (guint) types); if ((GST_MESSAGE_TYPE (message) & types) != 0) { /* Extra check to ensure extended types don't get matched unless * asked for */ if ((!GST_MESSAGE_TYPE_IS_EXTENDED (message)) || (types & GST_MESSAGE_EXTENDED)) { /* exit the loop, we have a message */ goto beach; } } GST_DEBUG_OBJECT (bus, "discarding message, does not match mask"); gst_message_unref (message); message = NULL; } /* no need to wait, exit loop */ if (timeout == 0) break; else if (timeout != GST_CLOCK_TIME_NONE) { if (first_round) { g_get_current_time (&then); first_round = FALSE; } else { g_get_current_time (&now); elapsed = GST_TIMEVAL_TO_TIME (now) - GST_TIMEVAL_TO_TIME (then); if (elapsed > timeout) break; } } /* only here in timeout case */ g_assert (bus->priv->poll); g_mutex_unlock (&bus->priv->queue_lock); ret = gst_poll_wait (bus->priv->poll, timeout - elapsed); g_mutex_lock (&bus->priv->queue_lock); if (ret == 0) { GST_INFO_OBJECT (bus, "timed out, breaking loop"); break; } else { GST_INFO_OBJECT (bus, "we got woken up, recheck for message"); } } beach: g_mutex_unlock (&bus->priv->queue_lock); return message; }
/** * gst_bus_timed_pop_filtered: * @bus: a #GstBus to pop from * @timeout: a timeout in nanoseconds, or GST_CLOCK_TIME_NONE to wait forever * @types: message types to take into account, GST_MESSAGE_ANY for any type * * Get a message from the bus whose type matches the message type mask @types, * waiting up to the specified timeout (and discarding any messages that do not * match the mask provided). * * If @timeout is 0, this function behaves like gst_bus_pop_filtered(). If * @timeout is #GST_CLOCK_TIME_NONE, this function will block forever until a * matching message was posted on the bus. * * Returns: (transfer full) (nullable): a #GstMessage matching the * filter in @types, or %NULL if no matching message was found on * the bus until the timeout expired. The message is taken from * the bus and needs to be unreffed with gst_message_unref() after * usage. * * MT safe. */ GstMessage * gst_bus_timed_pop_filtered (GstBus * bus, GstClockTime timeout, GstMessageType types) { GstMessage *message; GTimeVal now, then; gboolean first_round = TRUE; GstClockTime elapsed = 0; g_return_val_if_fail (GST_IS_BUS (bus), NULL); g_return_val_if_fail (types != 0, NULL); g_return_val_if_fail (timeout == 0 || bus->priv->poll != NULL, NULL); g_mutex_lock (&bus->priv->queue_lock); while (TRUE) { gint ret; GST_LOG_OBJECT (bus, "have %d messages", gst_atomic_queue_length (bus->priv->queue)); while ((message = gst_atomic_queue_pop (bus->priv->queue))) { if (bus->priv->poll) gst_poll_read_control (bus->priv->poll); GST_DEBUG_OBJECT (bus, "got message %p, %s from %s, type mask is %u", message, GST_MESSAGE_TYPE_NAME (message), GST_MESSAGE_SRC_NAME (message), (guint) types); if ((GST_MESSAGE_TYPE (message) & types) != 0) { /* Extra check to ensure extended types don't get matched unless * asked for */ if ((!GST_MESSAGE_TYPE_IS_EXTENDED (message)) || (types & GST_MESSAGE_EXTENDED)) { /* exit the loop, we have a message */ goto beach; } } GST_DEBUG_OBJECT (bus, "discarding message, does not match mask"); gst_message_unref (message); message = NULL; } /* no need to wait, exit loop */ if (timeout == 0) break; else if (timeout != GST_CLOCK_TIME_NONE) { if (first_round) { g_get_current_time (&then); first_round = FALSE; } else { g_get_current_time (&now); elapsed = GST_TIMEVAL_TO_TIME (now) - GST_TIMEVAL_TO_TIME (then); if (elapsed > timeout) break; } } /* only here in timeout case */ g_assert (bus->priv->poll); g_mutex_unlock (&bus->priv->queue_lock); ret = gst_poll_wait (bus->priv->poll, timeout - elapsed); g_mutex_lock (&bus->priv->queue_lock); if (ret == 0) { GST_INFO_OBJECT (bus, "timed out, breaking loop"); break; } else { GST_INFO_OBJECT (bus, "we got woken up, recheck for message"); } } beach: g_mutex_unlock (&bus->priv->queue_lock); return message; }