static void _teardown_test (void) { GstBus *bus; gst_element_set_state (demux, GST_STATE_NULL); bus = GST_ELEMENT_BUS (demux); gst_bus_set_flushing (bus, TRUE); gst_object_unref (bus); gst_pad_set_active (mjpg_pad, FALSE); gst_object_unref (mjpg_pad); if (h264_pad) { gst_pad_set_active (h264_pad, FALSE); gst_object_unref (h264_pad); } if (yuy2_pad) { gst_pad_set_active (yuy2_pad, FALSE); gst_object_unref (yuy2_pad); } if (nv12_pad) { gst_pad_set_active (nv12_pad, FALSE); gst_object_unref (nv12_pad); } if (jpg_pad) { gst_pad_set_active (jpg_pad, FALSE); gst_object_unref (jpg_pad); } if (gerror) { g_error_free (gerror); gerror = NULL; } if (error_debug) { g_free (error_debug); error_debug = NULL; } gst_object_unref (demux); mjpg_pad = h264_pad = yuy2_pad = nv12_pad = jpg_pad = NULL; demux = NULL; gst_caps_replace (&negotiated_caps_h264, NULL); gst_caps_replace (&negotiated_caps_yuy2, NULL); gst_caps_replace (&negotiated_caps_nv12, NULL); gst_caps_replace (&negotiated_caps_jpg, NULL); }
static void gst_device_monitor_init (GstDeviceMonitor * self) { self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GST_TYPE_DEVICE_MONITOR, GstDeviceMonitorPrivate); self->priv->show_all = DEFAULT_SHOW_ALL; self->priv->bus = gst_bus_new (); gst_bus_set_flushing (self->priv->bus, TRUE); self->priv->providers = g_ptr_array_new (); self->priv->filters = g_ptr_array_new_with_free_func ( (GDestroyNotify) device_filter_free); self->priv->last_id = 1; }
static void bus_message_cb (GstBus * bus, GstMessage * message, GMainLoop * mainloop) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR: g_print ("ERROR\n"); gst_bus_set_flushing (bus, TRUE); g_main_loop_quit (mainloop); break; case GST_MESSAGE_EOS: g_print ("Done\n"); g_main_loop_quit (mainloop); break; default: break; } }
static void cleanup_wavpackenc (GstElement * wavpackenc) { GST_DEBUG ("cleanup_wavpackenc"); gst_bus_set_flushing (bus, TRUE); gst_element_set_bus (wavpackenc, NULL); gst_object_unref (GST_OBJECT (bus)); gst_element_set_state (wavpackenc, GST_STATE_NULL); gst_pad_set_active (mysrcpad, FALSE); gst_pad_set_active (mysinkpad, FALSE); gst_check_teardown_src_pad (wavpackenc); gst_check_teardown_sink_pad (wavpackenc); gst_check_teardown_element (wavpackenc); }
/** * gst_discoverer_stop: * @discoverer: A #GstDiscoverer * * Stop the discovery of any pending URIs and clears the list of * pending URIS (if any). * * Since: 0.10.31 */ void gst_discoverer_stop (GstDiscoverer * discoverer) { GST_DEBUG_OBJECT (discoverer, "Stopping..."); if (!discoverer->priv->async) { GST_DEBUG_OBJECT (discoverer, "We were already stopped, or running synchronously"); return; } DISCO_LOCK (discoverer); if (discoverer->priv->processing) { /* We prevent any further processing by setting the bus to * flushing and setting the pipeline to READY. * _reset() will take care of the rest of the cleanup */ if (discoverer->priv->bus) gst_bus_set_flushing (discoverer->priv->bus, TRUE); if (discoverer->priv->pipeline) gst_element_set_state ((GstElement *) discoverer->priv->pipeline, GST_STATE_READY); } discoverer->priv->running = FALSE; DISCO_UNLOCK (discoverer); /* Remove timeout handler */ if (discoverer->priv->timeoutid) { g_source_remove (discoverer->priv->timeoutid); discoverer->priv->timeoutid = 0; } /* Remove signal watch */ if (discoverer->priv->sourceid) { g_source_remove (discoverer->priv->sourceid); discoverer->priv->sourceid = 0; } /* Unref main context */ if (discoverer->priv->ctx) { g_main_context_unref (discoverer->priv->ctx); discoverer->priv->ctx = NULL; } discoverer_reset (discoverer); discoverer->priv->async = FALSE; GST_DEBUG_OBJECT (discoverer, "Stopped"); }
static gboolean message_handler (GstBus * bus, GstMessage * message, gpointer user_data) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ELEMENT:{ const GstStructure *s = gst_message_get_structure (message); const gchar *name = gst_structure_get_name (s); if (strcmp (name, "not-mounted") == 0) { GMountOperation *mop = gtk_mount_operation_new (NULL); GFile *file = G_FILE (g_value_get_object (gst_structure_get_value (s, "file"))); g_print ("not-mounted\n"); gst_element_set_state (pipeline, GST_STATE_NULL); gst_bus_set_flushing (bus, TRUE); g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE, mop, NULL, mount_cb, bus); g_object_unref (mop); } break; } case GST_MESSAGE_EOS: g_print ("EOS\n"); gtk_main_quit (); break; case GST_MESSAGE_ERROR:{ GError *err = NULL; gst_message_parse_error (message, &err, NULL); g_print ("error: %s\n", err->message); g_clear_error (&err); gtk_main_quit (); break; } default: break; } return TRUE; }
static void cleanup_element (GstElement * element) { GstBus *bus; /* Free parsed buffers */ gst_check_drop_buffers (); bus = GST_ELEMENT_BUS (element); gst_bus_set_flushing (bus, TRUE); gst_object_unref (bus); gst_pad_set_active (srcpad, FALSE); gst_pad_set_active (sinkpad, FALSE); gst_check_teardown_src_pad (element); gst_check_teardown_sink_pad (element); gst_check_teardown_element (element); }
static void mount_cb (GObject * obj, GAsyncResult * res, gpointer user_data) { gboolean ret; GError *err = NULL; ret = g_file_mount_enclosing_volume_finish (G_FILE (obj), res, &err); if (ret) { g_print ("mounted successfully\n"); gst_bus_set_flushing ((GstBus *) user_data, FALSE); gst_element_set_state (pipeline, GST_STATE_PLAYING); } else { g_print ("mounting failed: %s\n", err->message); g_clear_error (&err); gtk_main_quit (); } }
static void teardown_cmmlenc (void) { /* free encoded buffers */ g_list_foreach (buffers, buffer_unref, NULL); g_list_free (buffers); buffers = NULL; current_buf = NULL; gst_bus_set_flushing (bus, TRUE); gst_object_unref (bus); GST_DEBUG ("teardown_cmmlenc"); gst_pad_set_active (srcpad, FALSE); gst_pad_set_active (sinkpad, FALSE); gst_check_teardown_src_pad (cmmlenc); gst_check_teardown_sink_pad (cmmlenc); gst_check_teardown_element (cmmlenc); }
/** * gst_device_monitor_stop: * @monitor: A #GstDeviceProvider * * Stops monitoring the devices. * * Since: 1.4 */ void gst_device_monitor_stop (GstDeviceMonitor * monitor) { guint i; g_return_if_fail (GST_IS_DEVICE_MONITOR (monitor)); gst_bus_set_flushing (monitor->priv->bus, TRUE); GST_OBJECT_LOCK (monitor); for (i = 0; i < monitor->priv->providers->len; i++) { GstDeviceProvider *provider = g_ptr_array_index (monitor->priv->providers, i); if (gst_device_provider_can_monitor (provider)) gst_device_provider_stop (provider); } monitor->priv->started = FALSE; GST_OBJECT_UNLOCK (monitor); }
static void cleanup_amrnbenc (GstElement * amrnbenc) { GstBus *bus; /* free encoded buffers */ g_list_foreach (buffers, buffer_unref, NULL); g_list_free (buffers); buffers = NULL; bus = GST_ELEMENT_BUS (amrnbenc); gst_bus_set_flushing (bus, TRUE); gst_object_unref (bus); GST_DEBUG ("cleanup_amrnbenc"); gst_pad_set_active (srcpad, FALSE); gst_pad_set_active (sinkpad, FALSE); gst_check_teardown_src_pad (amrnbenc); gst_check_teardown_sink_pad (amrnbenc); gst_check_teardown_element (amrnbenc); }
int gstreamer_stop(void) { if (!gst_provider.play) return 0; dprintf("%s: in\n", __func__); GstBus *bus = gst_element_get_bus (gst_provider.play); gst_bus_set_flushing (bus, TRUE); GstState cur_state; gst_element_get_state (gst_provider.play, &cur_state, NULL, 0); if (cur_state > GST_STATE_READY) { dprintf ("%s: stopping %s\n", __func__, gst_provider.uri); gst_element_set_state (gst_provider.play, GST_STATE_READY); } gst_object_unref (bus); dprintf("%s: out\n", __func__); return 0; }
/* Must be called with mutex locked. */ static void gst_uri_downloader_stop (GstUriDownloader * downloader) { GstPad *pad; GstElement *urisrc; if (!downloader->priv->urisrc) return; GST_DEBUG_OBJECT (downloader, "Stopping source element %s", GST_ELEMENT_NAME (downloader->priv->urisrc)); /* remove the bus' sync handler */ gst_bus_set_sync_handler (downloader->priv->bus, NULL, NULL, NULL); /* unlink the source element from the internal pad */ pad = gst_pad_get_peer (downloader->priv->pad); if (pad) { gst_pad_unlink (pad, downloader->priv->pad); gst_object_unref (pad); } urisrc = downloader->priv->urisrc; downloader->priv->urisrc = NULL; /* unlock so it doesn't block on chain function while changing state */ g_mutex_unlock (&downloader->priv->lock); GST_DEBUG_OBJECT (downloader, "Stopping source element %s", GST_ELEMENT_NAME (urisrc)); /* set the element state to NULL */ gst_element_set_state (urisrc, GST_STATE_NULL); gst_element_get_state (urisrc, NULL, NULL, GST_CLOCK_TIME_NONE); gst_element_set_bus (urisrc, NULL); gst_object_unref (urisrc); /* caller expects the mutex to be locked */ g_mutex_lock (&downloader->priv->lock); gst_bus_set_flushing (downloader->priv->bus, TRUE); }
static void gst_pipeline_init (GstPipeline * pipeline) { GstBus *bus; pipeline->priv = GST_PIPELINE_GET_PRIVATE (pipeline); /* set default property values */ pipeline->priv->auto_flush_bus = DEFAULT_AUTO_FLUSH_BUS; pipeline->delay = DEFAULT_DELAY; /* create and set a default bus */ bus = gst_bus_new (); #if 0 /* FIXME, disabled for 0.10.5 release as it caused to many regressions */ /* Start our bus in flushing if appropriate */ if (pipeline->priv->auto_flush_bus) gst_bus_set_flushing (bus, TRUE); #endif gst_element_set_bus (GST_ELEMENT_CAST (pipeline), bus); GST_DEBUG_OBJECT (pipeline, "set bus %" GST_PTR_FORMAT " on pipeline", bus); gst_object_unref (bus); }
static void helper (gboolean flush) { GstElement *filter; GstBus *bus; GstPad *mysrcpad; GstPad *mysinkpad; /* init */ filter = gst_check_setup_element ("omx_dummy"); mysrcpad = gst_check_setup_src_pad (filter, &srctemplate, NULL); mysinkpad = gst_check_setup_sink_pad (filter, &sinktemplate, NULL); gst_pad_set_active (mysrcpad, TRUE); gst_pad_set_active (mysinkpad, TRUE); /* need to know when we are eos */ gst_pad_set_event_function (mysinkpad, test_sink_event); /* and notify the test run */ eos_mutex = g_mutex_new (); eos_cond = g_cond_new (); eos_arrived = FALSE; g_object_set (G_OBJECT (filter), "library-name", "libomxil-foo.so", NULL); /* start */ fail_unless_equals_int (gst_element_set_state (filter, GST_STATE_PLAYING), GST_STATE_CHANGE_SUCCESS); bus = gst_bus_new (); gst_element_set_bus (filter, bus); /* send buffers in order*/ { guint i; for (i = 0; i < BUFFER_COUNT; i++) { GstBuffer *inbuffer; inbuffer = gst_buffer_new_and_alloc (BUFFER_SIZE); GST_BUFFER_DATA(inbuffer)[0] = i; ASSERT_BUFFER_REFCOUNT (inbuffer, "inbuffer", 1); fail_unless (gst_pad_push (mysrcpad, inbuffer) == GST_FLOW_OK); if (flush && i % FLUSH_AT == 0) { gst_pad_push_event (mysrcpad, gst_event_new_flush_start ()); gst_pad_push_event (mysrcpad, gst_event_new_flush_stop ()); i += FLUSH_AT; } } } { GstMessage *message; fail_if ((message = gst_bus_pop (bus)) != NULL); /* make sure there's no error on the bus */ message = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0); fail_if (message); } gst_pad_push_event (mysrcpad, gst_event_new_eos ()); /* need to wait a bit to make sure src pad task digested all and sent eos */ g_mutex_lock (eos_mutex); while (!eos_arrived) g_cond_wait (eos_cond, eos_mutex); g_mutex_unlock (eos_mutex); /* check the order of the buffers*/ if (!flush) { GList *cur; guint i; for (cur = buffers, i = 0; cur; cur = g_list_next (cur), i++) { GstBuffer *buffer; buffer = cur->data; fail_unless (GST_BUFFER_DATA(buffer)[0] == i); } fail_unless (i == BUFFER_COUNT); } /* cleanup */ gst_bus_set_flushing (bus, TRUE); gst_element_set_bus (filter, NULL); gst_object_unref (GST_OBJECT (bus)); gst_check_drop_buffers (); /* deinit */ gst_element_set_state (filter, GST_STATE_NULL); gst_pad_set_active (mysrcpad, FALSE); gst_pad_set_active (mysinkpad, FALSE); gst_check_teardown_src_pad (filter); gst_check_teardown_sink_pad (filter); gst_check_teardown_element (filter); g_mutex_free (eos_mutex); g_cond_free (eos_cond); }
/* MT safe */ static GstStateChangeReturn gst_pipeline_change_state (GstElement * element, GstStateChange transition) { GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS; GstPipeline *pipeline = GST_PIPELINE_CAST (element); GstClock *clock; switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: GST_OBJECT_LOCK (element); if (element->bus) gst_bus_set_flushing (element->bus, FALSE); GST_OBJECT_UNLOCK (element); break; case GST_STATE_CHANGE_READY_TO_PAUSED: GST_OBJECT_LOCK (element); pipeline->priv->update_clock = TRUE; GST_OBJECT_UNLOCK (element); /* READY to PAUSED starts running_time from 0 */ reset_start_time (pipeline, 0); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: { GstClockTime now, start_time, last_start_time, delay; gboolean update_clock; GstClock *cur_clock; GST_DEBUG_OBJECT (element, "selecting clock and base_time"); GST_OBJECT_LOCK (element); cur_clock = element->clock; if (cur_clock) gst_object_ref (cur_clock); /* get the desired running_time of the first buffer aka the start_time */ start_time = GST_ELEMENT_START_TIME (pipeline); last_start_time = pipeline->priv->last_start_time; pipeline->priv->last_start_time = start_time; /* see if we need to update the clock */ update_clock = pipeline->priv->update_clock; pipeline->priv->update_clock = FALSE; delay = pipeline->delay; GST_OBJECT_UNLOCK (element); /* running time changed, either with a PAUSED or a flush, we need to check * if there is a new clock & update the base time */ /* only do this for top-level, however */ if (GST_OBJECT_PARENT (element) == NULL && (update_clock || last_start_time != start_time)) { GST_DEBUG_OBJECT (pipeline, "Need to update start_time"); /* when going to PLAYING, select a clock when needed. If we just got * flushed, we don't reselect the clock. */ if (update_clock) { GST_DEBUG_OBJECT (pipeline, "Need to update clock."); clock = gst_element_provide_clock (element); } else { GST_DEBUG_OBJECT (pipeline, "Don't need to update clock, using old clock."); /* only try to ref if cur_clock is not NULL */ if (cur_clock) gst_object_ref (cur_clock); clock = cur_clock; } if (clock) { now = gst_clock_get_time (clock); } else { GST_DEBUG_OBJECT (pipeline, "no clock, using base time of NONE"); now = GST_CLOCK_TIME_NONE; } if (clock != cur_clock) { /* now distribute the clock (which could be NULL). If some * element refuses the clock, this will return FALSE and * we effectively fail the state change. */ if (!gst_element_set_clock (element, clock)) goto invalid_clock; /* if we selected and distributed a new clock, let the app * know about it */ gst_element_post_message (element, gst_message_new_new_clock (GST_OBJECT_CAST (element), clock)); } if (clock) gst_object_unref (clock); if (start_time != GST_CLOCK_TIME_NONE && now != GST_CLOCK_TIME_NONE) { GstClockTime new_base_time = now - start_time + delay; GST_DEBUG_OBJECT (element, "start_time=%" GST_TIME_FORMAT ", now=%" GST_TIME_FORMAT ", base_time %" GST_TIME_FORMAT, GST_TIME_ARGS (start_time), GST_TIME_ARGS (now), GST_TIME_ARGS (new_base_time)); gst_element_set_base_time (element, new_base_time); } else { GST_DEBUG_OBJECT (pipeline, "NOT adjusting base_time because start_time is NONE"); } } else { GST_DEBUG_OBJECT (pipeline, "NOT adjusting base_time because we selected one before"); } if (cur_clock) gst_object_unref (cur_clock); break; } case GST_STATE_CHANGE_PLAYING_TO_PAUSED: { /* we take a start_time snapshot before calling the children state changes * so that they know about when the pipeline PAUSED. */ pipeline_update_start_time (element); break; } case GST_STATE_CHANGE_PAUSED_TO_READY: reset_start_time (pipeline, 0); break; case GST_STATE_CHANGE_READY_TO_NULL: break; } result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: break; case GST_STATE_CHANGE_READY_TO_PAUSED: break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: break; case GST_STATE_CHANGE_PLAYING_TO_PAUSED: { /* Take a new snapshot of the start_time after calling the state change on * all children. This will be the running_time of the pipeline when we go * back to PLAYING */ pipeline_update_start_time (element); break; } case GST_STATE_CHANGE_PAUSED_TO_READY: break; case GST_STATE_CHANGE_READY_TO_NULL: { GstBus *bus; gboolean auto_flush; /* grab some stuff before we release the lock to flush out the bus */ GST_OBJECT_LOCK (element); if ((bus = element->bus)) gst_object_ref (bus); auto_flush = pipeline->priv->auto_flush_bus; GST_OBJECT_UNLOCK (element); if (bus) { if (auto_flush) { gst_bus_set_flushing (bus, TRUE); } else { GST_INFO_OBJECT (element, "not flushing bus, auto-flushing disabled"); } gst_object_unref (bus); } break; } } return result; /* ERRORS */ invalid_clock: { /* we generate this error when the selected clock was not * accepted by some element */ GST_ELEMENT_ERROR (pipeline, CORE, CLOCK, (_("Selected clock cannot be used in pipeline.")), ("Pipeline cannot operate with selected clock")); GST_DEBUG_OBJECT (pipeline, "Pipeline cannot operate with selected clock %p", clock); if (clock) gst_object_unref (clock); return GST_STATE_CHANGE_FAILURE; } }
/** * gst_uri_downloader_fetch_uri_with_range: * @downloader: the #GstUriDownloader * @uri: the uri * @range_start: the starting byte index * @range_end: the final byte index, use -1 for unspecified * * Returns the downloaded #GstFragment */ GstFragment * gst_uri_downloader_fetch_uri_with_range (GstUriDownloader * downloader, const gchar * uri, const gchar * referer, gboolean compress, gboolean refresh, gboolean allow_cache, gint64 range_start, gint64 range_end, GError ** err) { GstStateChangeReturn ret; GstFragment *download = NULL; GST_DEBUG_OBJECT (downloader, "Fetching URI %s", uri); g_mutex_lock (&downloader->priv->download_lock); downloader->priv->err = NULL; downloader->priv->got_buffer = FALSE; GST_OBJECT_LOCK (downloader); if (downloader->priv->cancelled) { GST_DEBUG_OBJECT (downloader, "Cancelled, aborting fetch"); goto quit; } if (!gst_uri_downloader_set_uri (downloader, uri, referer, compress, refresh, allow_cache)) { GST_WARNING_OBJECT (downloader, "Failed to set URI"); goto quit; } gst_bus_set_flushing (downloader->priv->bus, FALSE); if (downloader->priv->download) g_object_unref (downloader->priv->download); downloader->priv->download = gst_fragment_new (); downloader->priv->download->range_start = range_start; downloader->priv->download->range_end = range_end; GST_OBJECT_UNLOCK (downloader); ret = gst_element_set_state (downloader->priv->urisrc, GST_STATE_READY); GST_OBJECT_LOCK (downloader); if (ret == GST_STATE_CHANGE_FAILURE || downloader->priv->download == NULL) { GST_WARNING_OBJECT (downloader, "Failed to set src to READY"); goto quit; } /* might have been cancelled because of failures in state change */ if (downloader->priv->cancelled) { goto quit; } if (range_start < 0 && range_end < 0) { if (!gst_uri_downloader_set_method (downloader, "HEAD")) { GST_WARNING_OBJECT (downloader, "Failed to set HTTP method"); goto quit; } } else { if (!gst_uri_downloader_set_range (downloader, range_start, range_end)) { GST_WARNING_OBJECT (downloader, "Failed to set range"); goto quit; } } GST_OBJECT_UNLOCK (downloader); ret = gst_element_set_state (downloader->priv->urisrc, GST_STATE_PLAYING); GST_OBJECT_LOCK (downloader); if (ret == GST_STATE_CHANGE_FAILURE) { if (downloader->priv->download) { g_object_unref (downloader->priv->download); downloader->priv->download = NULL; } goto quit; } /* might have been cancelled because of failures in state change */ if (downloader->priv->cancelled) { goto quit; } /* wait until: * - the download succeed (EOS in the src pad) * - the download failed (Error message on the fetcher bus) * - the download was canceled */ GST_DEBUG_OBJECT (downloader, "Waiting to fetch the URI %s", uri); while (!downloader->priv->cancelled && !downloader->priv->download->completed) g_cond_wait (&downloader->priv->cond, GST_OBJECT_GET_LOCK (downloader)); if (downloader->priv->cancelled) { if (downloader->priv->download) { g_object_unref (downloader->priv->download); downloader->priv->download = NULL; } goto quit; } download = downloader->priv->download; downloader->priv->download = NULL; if (!downloader->priv->got_buffer) { if (download->range_start < 0 && download->range_end < 0) { /* HEAD request, so we don't expect a response */ } else { g_object_unref (download); download = NULL; GST_ERROR_OBJECT (downloader, "Didn't retrieve a buffer before EOS"); } } if (download != NULL) GST_INFO_OBJECT (downloader, "URI fetched successfully"); else GST_INFO_OBJECT (downloader, "Error fetching URI"); quit: { if (downloader->priv->urisrc) { GstPad *pad; GstElement *urisrc; urisrc = downloader->priv->urisrc; GST_DEBUG_OBJECT (downloader, "Stopping source element %s", GST_ELEMENT_NAME (urisrc)); /* remove the bus' sync handler */ gst_bus_set_sync_handler (downloader->priv->bus, NULL, NULL, NULL); gst_bus_set_flushing (downloader->priv->bus, TRUE); /* set the element state to NULL */ GST_OBJECT_UNLOCK (downloader); if (download == NULL) { gst_element_set_state (urisrc, GST_STATE_NULL); } else { GstQuery *query; /* Download successfull, let's query the URI */ query = gst_query_new_uri (); if (gst_element_query (urisrc, query)) { gst_query_parse_uri (query, &download->uri); gst_query_parse_uri_redirection (query, &download->redirect_uri); gst_query_parse_uri_redirection_permanent (query, &download->redirect_permanent); } gst_query_unref (query); gst_element_set_state (urisrc, GST_STATE_READY); } GST_OBJECT_LOCK (downloader); gst_element_set_bus (urisrc, NULL); /* unlink the source element from the internal pad */ pad = gst_pad_get_peer (downloader->priv->pad); if (pad) { gst_pad_unlink (pad, downloader->priv->pad); gst_object_unref (pad); } } GST_OBJECT_UNLOCK (downloader); if (download == NULL) { if (!downloader->priv->err) { g_set_error (err, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_OPEN_READ, "Failed to download '%s'", uri); } else { g_propagate_error (err, downloader->priv->err); downloader->priv->err = NULL; } } downloader->priv->cancelled = FALSE; g_mutex_unlock (&downloader->priv->download_lock); return download; } }
/** * gst_uri_downloader_fetch_uri_with_range: * @downloader: the #GstUriDownloader * @uri: the uri * @range_start: the starting byte index * @range_end: the final byte index, use -1 for unspecified * * Returns the downloaded #GstFragment */ GstFragment * gst_uri_downloader_fetch_uri_with_range (GstUriDownloader * downloader, const gchar * uri, gint64 range_start, gint64 range_end) { GstStateChangeReturn ret; GstFragment *download = NULL; GST_DEBUG_OBJECT (downloader, "Fetching URI %s", uri); g_mutex_lock (&downloader->priv->download_lock); GST_OBJECT_LOCK (downloader); if (downloader->priv->cancelled) { GST_DEBUG_OBJECT (downloader, "Cancelled, aborting fetch"); goto quit; } if (!gst_uri_downloader_set_uri (downloader, uri)) { GST_WARNING_OBJECT (downloader, "Failed to set URI"); goto quit; } gst_bus_set_flushing (downloader->priv->bus, FALSE); downloader->priv->download = gst_fragment_new (); GST_OBJECT_UNLOCK (downloader); ret = gst_element_set_state (downloader->priv->urisrc, GST_STATE_READY); GST_OBJECT_LOCK (downloader); if (ret == GST_STATE_CHANGE_FAILURE || downloader->priv->download == NULL) { GST_WARNING_OBJECT (downloader, "Failed to set src to READY"); goto quit; } /* might have been cancelled because of failures in state change */ if (downloader->priv->cancelled) { goto quit; } if (!gst_uri_downloader_set_range (downloader, range_start, range_end)) { GST_WARNING_OBJECT (downloader, "Failed to set range"); goto quit; } GST_OBJECT_UNLOCK (downloader); ret = gst_element_set_state (downloader->priv->urisrc, GST_STATE_PLAYING); GST_OBJECT_LOCK (downloader); if (ret == GST_STATE_CHANGE_FAILURE) { if (downloader->priv->download) { g_object_unref (downloader->priv->download); downloader->priv->download = NULL; } goto quit; } /* might have been cancelled because of failures in state change */ if (downloader->priv->cancelled) { goto quit; } /* wait until: * - the download succeed (EOS in the src pad) * - the download failed (Error message on the fetcher bus) * - the download was canceled */ GST_DEBUG_OBJECT (downloader, "Waiting to fetch the URI %s", uri); while (!downloader->priv->cancelled && !downloader->priv->download->completed) g_cond_wait (&downloader->priv->cond, GST_OBJECT_GET_LOCK (downloader)); if (downloader->priv->cancelled) { if (downloader->priv->download) { g_object_unref (downloader->priv->download); downloader->priv->download = NULL; } goto quit; } download = downloader->priv->download; downloader->priv->download = NULL; if (download != NULL) GST_INFO_OBJECT (downloader, "URI fetched successfully"); else GST_INFO_OBJECT (downloader, "Error fetching URI"); quit: { if (downloader->priv->urisrc) { GstPad *pad; GstElement *urisrc; GST_DEBUG_OBJECT (downloader, "Stopping source element %s", GST_ELEMENT_NAME (downloader->priv->urisrc)); /* remove the bus' sync handler */ gst_bus_set_sync_handler (downloader->priv->bus, NULL, NULL, NULL); /* unlink the source element from the internal pad */ pad = gst_pad_get_peer (downloader->priv->pad); if (pad) { gst_pad_unlink (pad, downloader->priv->pad); gst_object_unref (pad); } urisrc = downloader->priv->urisrc; downloader->priv->urisrc = NULL; GST_OBJECT_UNLOCK (downloader); GST_DEBUG_OBJECT (downloader, "Stopping source element %s", GST_ELEMENT_NAME (urisrc)); /* set the element state to NULL */ gst_bus_set_flushing (downloader->priv->bus, TRUE); gst_element_set_state (urisrc, GST_STATE_NULL); gst_element_get_state (urisrc, NULL, NULL, GST_CLOCK_TIME_NONE); gst_element_set_bus (urisrc, NULL); gst_object_unref (urisrc); } else { GST_OBJECT_UNLOCK (downloader); } g_mutex_unlock (&downloader->priv->download_lock); return download; } }
static void test_videoframe_audiolevel_generic (void) { GstElement *alevel; GstPad *asink, *vsink, *asrc, *vsrc, *aoutput_sink, *voutput_sink; GThread *athread, *vthread; GstBus *bus; guint i; got_eos = FALSE; audio_buffer_count = 0; video_buffer_count = 0; num_msgs = 0; g_queue_init (&v_timestamp_q); g_queue_init (&msg_timestamp_q); alevel = gst_element_factory_make ("videoframe-audiolevel", NULL); fail_unless (alevel != NULL); bus = gst_bus_new (); gst_element_set_bus (alevel, bus); gst_bus_set_sync_handler (bus, on_message, NULL, NULL); asink = gst_element_get_static_pad (alevel, "asink"); fail_unless (asink != NULL); vsink = gst_element_get_static_pad (alevel, "vsink"); fail_unless (vsink != NULL); asrc = gst_element_get_static_pad (alevel, "asrc"); aoutput_sink = gst_pad_new ("sink", GST_PAD_SINK); fail_unless (aoutput_sink != NULL); fail_unless (gst_pad_link (asrc, aoutput_sink) == GST_PAD_LINK_OK); vsrc = gst_element_get_static_pad (alevel, "vsrc"); voutput_sink = gst_pad_new ("sink", GST_PAD_SINK); fail_unless (voutput_sink != NULL); fail_unless (gst_pad_link (vsrc, voutput_sink) == GST_PAD_LINK_OK); gst_pad_set_chain_function (aoutput_sink, output_achain); gst_pad_set_event_function (aoutput_sink, output_aevent); gst_pad_set_chain_function (voutput_sink, output_vchain); gst_pad_set_event_function (voutput_sink, output_vevent); gst_pad_set_active (aoutput_sink, TRUE); gst_pad_set_active (voutput_sink, TRUE); fail_unless (gst_element_set_state (alevel, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS); athread = g_thread_new ("athread", (GThreadFunc) push_abuffers, asink); vthread = g_thread_new ("vthread", (GThreadFunc) push_vbuffers, vsink); g_thread_join (vthread); g_thread_join (athread); fail_unless (got_eos); fail_unless_equals_int (audio_buffer_count, n_abuffers); fail_unless_equals_int (video_buffer_count, n_vbuffers); if (!long_video) fail_unless_equals_int (num_msgs, n_vbuffers); fail_unless_equals_int (g_queue_get_length (&v_timestamp_q), n_vbuffers); /* num_msgs is equal to n_vbuffers except in the case of long_video */ fail_unless_equals_int (g_queue_get_length (&msg_timestamp_q), num_msgs); for (i = 0; i < g_queue_get_length (&msg_timestamp_q); i++) { GstClockTime *vt = g_queue_pop_head (&v_timestamp_q); GstClockTime *mt = g_queue_pop_head (&msg_timestamp_q); fail_unless (vt != NULL); fail_unless (mt != NULL); if (!video_gaps && !video_overlaps && !early_video) fail_unless_equals_uint64 (*vt, *mt); g_free (vt); g_free (mt); } /* teardown */ gst_element_set_state (alevel, GST_STATE_NULL); gst_bus_set_flushing (bus, TRUE); gst_object_unref (bus); g_queue_foreach (&v_timestamp_q, (GFunc) g_free, NULL); g_queue_foreach (&msg_timestamp_q, (GFunc) g_free, NULL); g_queue_clear (&v_timestamp_q); g_queue_clear (&msg_timestamp_q); gst_pad_unlink (asrc, aoutput_sink); gst_object_unref (asrc); gst_pad_unlink (vsrc, voutput_sink); gst_object_unref (vsrc); gst_object_unref (asink); gst_object_unref (vsink); gst_pad_set_active (aoutput_sink, FALSE); gst_object_unref (aoutput_sink); gst_pad_set_active (voutput_sink, FALSE); gst_object_unref (voutput_sink); gst_object_unref (alevel); }
gboolean gst_uri_downloader_stream_uri (GstUriDownloader * downloader, const gchar * uri, gint64 range_start, gint64 range_end, GstUriDownloaderChainFunction chain_func, gpointer user_data) { GstStateChangeReturn ret; GST_INFO_OBJECT (downloader, "fetching URI %s", uri); g_mutex_lock (&downloader->download_lock); downloader->chain = chain_func; downloader->priv = user_data; downloader->eos = FALSE; gst_pad_set_active (downloader->pad, TRUE); GST_OBJECT_LOCK (downloader); if (downloader->cancelled) goto quit; if (!gst_uri_downloader_set_uri (downloader, uri)) { GST_ERROR_OBJECT (downloader, "failed to set URI"); goto quit; } gst_bus_set_flushing (downloader->bus, FALSE); GST_OBJECT_UNLOCK (downloader); /* set to ready state first to allow setting range */ ret = gst_element_set_state (downloader->urisrc, GST_STATE_READY); GST_OBJECT_LOCK (downloader); if (ret == GST_STATE_CHANGE_FAILURE) { GST_ERROR_OBJECT (downloader, "failed to set src to READY"); goto quit; } if (downloader->cancelled) goto quit; if (!gst_uri_downloader_set_range (downloader, range_start, range_end)) { GST_ERROR_OBJECT (downloader, "failed to set range"); goto quit; } GST_OBJECT_UNLOCK (downloader); ret = gst_element_set_state (downloader->urisrc, GST_STATE_PLAYING); GST_OBJECT_LOCK (downloader); if (ret == GST_STATE_CHANGE_FAILURE) { GST_ERROR_OBJECT (downloader, "failed to set src to PLAYING"); goto quit; } if (downloader->cancelled) goto quit; if (!downloader->eos) { /* wait until: * - the download succeed (EOS in the src pad) * - the download failed (Error message on the fetcher bus) * - the download was canceled */ GST_DEBUG_OBJECT (downloader, "waiting to fetch the URI %s", uri); g_cond_wait (&downloader->cond, GST_OBJECT_GET_LOCK (downloader)); } quit: { gboolean ret = FALSE; if (downloader->cancelled) { GST_DEBUG_OBJECT (downloader, "download interrupted"); } else if (downloader->eos) { GST_DEBUG_OBJECT (downloader, "URI fetched successfully"); ret = TRUE; } downloader->cancelled = FALSE; gst_uri_downloader_stop (downloader); GST_OBJECT_UNLOCK (downloader); g_mutex_unlock (&downloader->download_lock); return ret; } }
static void run_decoding_test (GstElement * mpg123audiodec, gchar const *filename) { GstBus *bus; unsigned int num_input_buffers, num_decoded_buffers; gint expected_size; GstCaps *out_caps, *caps; GstAudioInfo audioinfo; GstElement *input_pipeline, *input_appsink; int i; GstBuffer *outbuffer; /* 440 Hz = frequency of sine wave in audio data * 44100 Hz = sample rate * (44100 / 2) Hz = Nyquist frequency */ static double const expected_frequency_spot = 440.0 / (44100.0 / 2.0); fail_unless (gst_element_set_state (mpg123audiodec, GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS, "could not set to playing"); bus = gst_bus_new (); gst_element_set_bus (mpg123audiodec, bus); setup_input_pipeline (filename, &input_pipeline, &input_appsink); num_input_buffers = 0; while (TRUE) { GstSample *sample; GstBuffer *input_buffer; sample = gst_app_sink_pull_sample (GST_APP_SINK (input_appsink)); if (sample == NULL) break; fail_unless (GST_IS_SAMPLE (sample)); input_buffer = gst_sample_get_buffer (sample); fail_if (input_buffer == NULL); /* This is done to be on the safe side - docs say lifetime of the input buffer * depends *solely* on the sample */ input_buffer = gst_buffer_copy (input_buffer); fail_unless_equals_int (gst_pad_push (mysrcpad, input_buffer), GST_FLOW_OK); ++num_input_buffers; gst_sample_unref (sample); } num_decoded_buffers = g_list_length (buffers); /* check number of decoded buffers */ fail_unless_equals_int (num_decoded_buffers, num_input_buffers - 2); caps = gst_pad_get_current_caps (mysinkpad); GST_LOG ("output caps %" GST_PTR_FORMAT, caps); fail_unless (gst_audio_info_from_caps (&audioinfo, caps), "Getting audio info from caps failed"); /* check caps */ out_caps = gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING, "S32LE", "layout", G_TYPE_STRING, "interleaved", "rate", G_TYPE_INT, 44100, "channels", G_TYPE_INT, 1, NULL); fail_unless (gst_caps_is_equal_fixed (caps, out_caps), "Incorrect out caps"); gst_caps_unref (out_caps); gst_caps_unref (caps); /* here, test if decoded data is a sine tone, and if the sine frequency is at the * right spot in the spectrum */ for (i = 0; i < num_decoded_buffers; ++i) { outbuffer = GST_BUFFER (buffers->data); fail_if (outbuffer == NULL, "Invalid buffer retrieved"); /* MPEG 1 layer 2 uses 1152 samples per frame */ expected_size = 1152 * GST_AUDIO_INFO_BPF (&audioinfo); fail_unless_equals_int (gst_buffer_get_size (outbuffer), expected_size); check_main_frequency_spot_S32 (outbuffer, expected_frequency_spot); buffers = g_list_remove (buffers, outbuffer); gst_buffer_unref (outbuffer); outbuffer = NULL; } g_list_free (buffers); buffers = NULL; cleanup_input_pipeline (input_pipeline); gst_bus_set_flushing (bus, TRUE); gst_element_set_bus (mpg123audiodec, NULL); gst_object_unref (GST_OBJECT (bus)); }
gboolean gst_device_monitor_start (GstDeviceMonitor * monitor) { guint cookie, i; GList *pending = NULL, *started = NULL, *removed = NULL; g_return_val_if_fail (GST_IS_DEVICE_MONITOR (monitor), FALSE); GST_OBJECT_LOCK (monitor); if (monitor->priv->filters->len == 0) { GST_OBJECT_UNLOCK (monitor); GST_WARNING_OBJECT (monitor, "No filters have been set, will expose all " "devices found"); gst_device_monitor_add_filter (monitor, NULL, NULL); GST_OBJECT_LOCK (monitor); } if (monitor->priv->providers->len == 0) { GST_OBJECT_UNLOCK (monitor); GST_WARNING_OBJECT (monitor, "No providers match the current filters"); return FALSE; } gst_bus_set_flushing (monitor->priv->bus, FALSE); again: cookie = monitor->priv->cookie; g_list_free_full (pending, gst_object_unref); pending = NULL; removed = started; started = NULL; for (i = 0; i < monitor->priv->providers->len; i++) { GstDeviceProvider *provider; GList *find; provider = g_ptr_array_index (monitor->priv->providers, i); find = g_list_find (removed, provider); if (find) { /* this was already started, move to started list */ removed = g_list_remove_link (removed, find); started = g_list_concat (started, find); } else { /* not started, add to pending list */ pending = g_list_append (pending, gst_object_ref (provider)); } } g_list_free_full (removed, gst_object_unref); removed = NULL; while (pending) { GstDeviceProvider *provider = pending->data; if (gst_device_provider_can_monitor (provider)) { GST_OBJECT_UNLOCK (monitor); if (!gst_device_provider_start (provider)) goto start_failed; GST_OBJECT_LOCK (monitor); } started = g_list_prepend (started, provider); pending = g_list_delete_link (pending, pending); if (monitor->priv->cookie != cookie) goto again; } monitor->priv->started = TRUE; GST_OBJECT_UNLOCK (monitor); g_list_free_full (started, gst_object_unref); return TRUE; start_failed: { GST_OBJECT_LOCK (monitor); gst_bus_set_flushing (monitor->priv->bus, TRUE); GST_OBJECT_UNLOCK (monitor); while (started) { GstDeviceProvider *provider = started->data; gst_device_provider_stop (provider); gst_object_unref (provider); started = g_list_delete_link (started, started); } return FALSE; } }
gboolean check_missing_plugins(GstEncodingProfile *profile, char ***details, char ***descriptions) { GstElement *encodebin; GstBus *bus; GstPad *pad; gboolean ret; ret = FALSE; encodebin = gst_element_factory_make("encodebin", NULL); if (encodebin == NULL) { g_warning("Unable to create encodebin"); return TRUE; } bus = gst_bus_new(); gst_element_set_bus(encodebin, bus); gst_bus_set_flushing(bus, FALSE); /* necessary? */ g_object_set(encodebin, "profile", profile, NULL); pad = gst_element_get_static_pad(encodebin, "audio_0"); if (pad == NULL) { GstMessage *message; GList *messages = NULL; GList *m; message = gst_bus_pop(bus); while (message != NULL) { if (gst_is_missing_plugin_message(message)) messages = g_list_append(messages, message); else gst_message_unref(message); message = gst_bus_pop(bus); } if (messages != NULL) { int i; if (details != NULL) *details = g_new0(char *, g_list_length(messages)+1); if (descriptions != NULL) *descriptions = g_new0(char *, g_list_length(messages)+1); i = 0; for (m = messages; m != NULL; m = m->next) { char *str; if (details != NULL) { str = gst_missing_plugin_message_get_installer_detail(m->data); (*details)[i] = str; } if (descriptions != NULL) { str = gst_missing_plugin_message_get_description(m->data); (*descriptions)[i] = str; } i++; } ret = TRUE; g_list_foreach(messages,(GFunc)gst_message_unref, NULL); g_list_free(messages); }