/** * gst_element_factory_create: * @factory: factory to instantiate * @name: (allow-none): name of new element, or NULL to automatically create * a unique name * * Create a new element of the type defined by the given elementfactory. * It will be given the name supplied, since all elements require a name as * their first argument. * * Returns: (transfer full): new #GstElement or NULL if the element couldn't * be created */ GstElement * gst_element_factory_create (GstElementFactory * factory, const gchar * name) { GstElement *element; GstElementClass *oclass; GstElementFactory *newfactory; g_return_val_if_fail (factory != NULL, NULL); newfactory = GST_ELEMENT_FACTORY (gst_plugin_feature_load (GST_PLUGIN_FEATURE (factory))); if (newfactory == NULL) goto load_failed; factory = newfactory; if (name) GST_INFO ("creating element \"%s\" named \"%s\"", GST_PLUGIN_FEATURE_NAME (factory), GST_STR_NULL (name)); else GST_INFO ("creating element \"%s\"", GST_PLUGIN_FEATURE_NAME (factory)); if (factory->type == 0) goto no_type; /* create an instance of the element, cast so we don't assert on NULL * also set name as early as we can */ if (name) element = GST_ELEMENT_CAST (g_object_new (factory->type, "name", name, NULL)); else element = GST_ELEMENT_CAST (g_object_newv (factory->type, 0, NULL)); if (G_UNLIKELY (element == NULL)) goto no_element; /* fill in the pointer to the factory in the element class. The * class will not be unreffed currently. * Be thread safe as there might be 2 threads creating the first instance of * an element at the same moment */ oclass = GST_ELEMENT_GET_CLASS (element); if (!G_ATOMIC_POINTER_COMPARE_AND_EXCHANGE (&oclass->elementfactory, NULL, factory)) gst_object_unref (factory); GST_DEBUG ("created element \"%s\"", GST_PLUGIN_FEATURE_NAME (factory)); return element; /* ERRORS */ load_failed: { GST_WARNING_OBJECT (factory, "loading plugin containing feature %s returned NULL!", name); return NULL; } no_type: { GST_WARNING_OBJECT (factory, "factory has no type"); gst_object_unref (factory); return NULL; } no_element: { GST_WARNING_OBJECT (factory, "could not create element"); gst_object_unref (factory); return NULL; } }
static gboolean _check_directory (GstValidateSsim * self, const gchar * ref_dir, const gchar * compared_dir, gfloat * mean, gfloat * lowest, gfloat * highest, const gchar * outfolder) { gint nfiles = 0, nnotfound = 0, nfailures = 0; gboolean res = TRUE; GFileInfo *info; GFileEnumerator *fenum; gfloat min_avg = 1.0, min_min = 1.0, total_avg = 0; GFile *file = g_file_new_for_path (ref_dir); if (!(fenum = g_file_enumerate_children (file, "standard::*", G_FILE_QUERY_INFO_NONE, NULL, NULL))) { GST_INFO ("%s is not a folder", ref_dir); res = FALSE; goto done; } for (info = g_file_enumerator_next_file (fenum, NULL, NULL); info; info = g_file_enumerator_next_file (fenum, NULL, NULL)) { if (g_file_info_get_file_type (info) == G_FILE_TYPE_REGULAR || g_file_info_get_file_type (info) == G_FILE_TYPE_SYMBOLIC_LINK) { gchar *compared_file = g_build_path (G_DIR_SEPARATOR_S, compared_dir, g_file_info_get_name (info), NULL); gchar *ref_file = NULL; if (!g_file_test (compared_file, G_FILE_TEST_IS_REGULAR)) { GST_INFO_OBJECT (self, "Could not find file %s", compared_file); nnotfound++; res = FALSE; } else { ref_file = g_build_path (G_DIR_SEPARATOR_S, ref_dir, g_file_info_get_name (info), NULL); if (!gst_validate_ssim_compare_image_files (self, ref_file, compared_file, mean, lowest, highest, outfolder)) { nfailures++; res = FALSE; } else { nfiles++; } } min_avg = MIN (min_avg, *mean); min_min = MIN (min_min, *lowest); total_avg += *mean; gst_validate_printf (NULL, "<position: %s duration: %" GST_TIME_FORMAT " avg: %f min: %f (Passed: %d failed: %d, %d not found)/>\r", g_file_info_get_display_name (info), GST_TIME_ARGS (GST_CLOCK_TIME_NONE), *mean, *lowest, nfiles, nfailures, nnotfound); g_free (compared_file); g_free (ref_file); } g_object_unref (info); } if (nfiles == 0) { gst_validate_printf (NULL, "\nNo files to verify.\n"); } else { gst_validate_printf (NULL, "\nAverage similarity: %f, min_avg: %f, min_min: %f\n", total_avg / nfiles, min_avg, min_min); } done: gst_object_unref (file); if (fenum) gst_object_unref (fenum); return res; }
static void gst_lv2_filter_base_init (gpointer g_class) { GstLV2FilterClass *klass = (GstLV2FilterClass *) g_class; GstElementClass *element_class = GST_ELEMENT_CLASS (g_class); LilvPlugin *lv2plugin; LilvNode *val; /* FIXME Handle channels positionning * GstAudioChannelPosition position = GST_AUDIO_CHANNEL_POSITION_INVALID; */ guint j, in_pad_index = 0, out_pad_index = 0; gchar *longname, *author; lv2plugin = (LilvPlugin *) g_type_get_qdata (G_OBJECT_CLASS_TYPE (klass), descriptor_quark); g_assert (lv2plugin); GST_INFO ("base_init %p, plugin %s", g_class, lilv_node_get_turtle_token (lilv_plugin_get_uri (lv2plugin))); klass->in_group.ports = g_array_new (FALSE, TRUE, sizeof (GstLV2FilterPort)); klass->out_group.ports = g_array_new (FALSE, TRUE, sizeof (GstLV2FilterPort)); klass->control_in_ports = g_array_new (FALSE, TRUE, sizeof (GstLV2FilterPort)); klass->control_out_ports = g_array_new (FALSE, TRUE, sizeof (GstLV2FilterPort)); /* find ports and groups */ for (j = 0; j < lilv_plugin_get_num_ports (lv2plugin); j++) { const LilvPort *port = lilv_plugin_get_port_by_index (lv2plugin, j); const gboolean is_input = lilv_port_is_a (lv2plugin, port, input_class); struct _GstLV2FilterPort desc = { j, 0, }; LilvNodes *lv2group = lilv_port_get (lv2plugin, port, group_pred); if (lv2group) { /* port is part of a group */ const gchar *group_uri = lilv_node_as_uri (lv2group); GstLV2FilterGroup *group = is_input ? &klass->in_group : &klass->out_group; if (group->uri == NULL) { group->uri = g_strdup (group_uri); group->pad = is_input ? in_pad_index++ : out_pad_index++; group->ports = g_array_new (FALSE, TRUE, sizeof (GstLV2FilterPort)); } /* FIXME Handle channels positionning position = GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT; sub_values = lilv_port_get_value (lv2plugin, port, has_role_pred); if (lilv_nodes_size (sub_values) > 0) { LilvNode *role = lilv_nodes_get_at (sub_values, 0); position = gst_lv2_filter_role_to_position (role); } lilv_nodes_free (sub_values); if (position != GST_AUDIO_CHANNEL_POSITION_INVALID) { desc.position = position; } */ g_array_append_val (group->ports, desc); } else { /* port is not part of a group, or it is part of a group but that group * is illegal so we just ignore it */ if (lilv_port_is_a (lv2plugin, port, audio_class)) { desc.pad = is_input ? in_pad_index++ : out_pad_index++; if (is_input) g_array_append_val (klass->in_group.ports, desc); else g_array_append_val (klass->out_group.ports, desc); } else if (lilv_port_is_a (lv2plugin, port, control_class)) { if (is_input) g_array_append_val (klass->control_in_ports, desc); else g_array_append_val (klass->control_out_ports, desc); } else { /* unknown port type */ GST_INFO ("unhandled port %d", j); continue; } } } gst_lv2_filter_type_class_add_pad_templates (klass); val = lilv_plugin_get_name (lv2plugin); if (val) { longname = g_strdup (lilv_node_as_string (val)); lilv_node_free (val); } else { longname = g_strdup ("no description available"); } val = lilv_plugin_get_author_name (lv2plugin); if (val) { author = g_strdup (lilv_node_as_string (val)); lilv_node_free (val); } else { author = g_strdup ("no author available"); } gst_element_class_set_metadata (element_class, longname, "Filter/Effect/Audio/LV2", longname, author); g_free (longname); g_free (author); klass->plugin = lv2plugin; }
int main (int argc, char *argv[]) { HTTPMgmt *httpmgmt; HTTPStreaming *httpstreaming; GMainLoop *loop; GOptionContext *ctx; GError *err = NULL; gboolean foreground; struct rlimit rlim; GDateTime *datetime; gchar exe_path[512], *date; ctx = g_option_context_new (NULL); g_option_context_add_main_entries (ctx, options, NULL); g_option_context_add_group (ctx, gst_init_get_option_group ()); if (!g_option_context_parse (ctx, &argc, &argv, &err)) { g_print ("Error initializing: %s\n", GST_STR_NULL (err->message)); exit (1); } g_option_context_free (ctx); GST_DEBUG_CATEGORY_INIT (GSTREAMILL, "gstreamill", 0, "gstreamill log"); if (version) { print_version_info (); exit (0); } /* stop gstreamill. */ if (stop) { gchar *pid_str; gint pid; g_file_get_contents (PID_FILE, &pid_str, NULL, NULL); if (pid_str == NULL) { g_print ("File %s not found, check if gstreamill is running.\n", PID_FILE); exit (1); } pid = atoi (pid_str); g_free (pid_str); g_print ("stoping gstreamill with pid %d ...\n", pid); kill (pid, SIGTERM); exit (0); } /* readlink exe path before setuid, on CentOS, readlink exe path after setgid/setuid failure on permission denied */ memset (exe_path, '\0', sizeof (exe_path)); if (readlink ("/proc/self/exe", exe_path, sizeof (exe_path)) == -1) { g_print ("Read /proc/self/exe error: %s", g_strerror (errno)); exit (2); } if (prepare_gstreamill_run_dir () != 0) { g_print ("Can't create gstreamill run directory\n"); exit (3); } /* if (set_user_and_group () != 0) { g_print ("set user and group failure\n"); exit (4); } */ if (job_file != NULL) { /* gstreamill command with job, run in foreground */ foreground = TRUE; } else { /* gstreamill command without job, run in background */ foreground = FALSE; } if (gst_debug_get_default_threshold () < GST_LEVEL_WARNING) { gst_debug_set_default_threshold (GST_LEVEL_WARNING); } /* initialize ts segment static plugin */ if (!gst_plugin_register_static (GST_VERSION_MAJOR, GST_VERSION_MINOR, "tssegment", "ts segment plugin", ts_segment_plugin_init, "0.1.0", "GPL", "GStreamer", "GStreamer", "http://gstreamer.net/")) { GST_ERROR ("registe tssegment error"); exit (17); } /* subprocess, create_job_process */ if (shm_name != NULL) { gint fd; gchar *job_desc, *p; Job *job; gchar *log_path, *name; gint ret; /* set subprocess maximum of core file */ rlim.rlim_cur = 0; rlim.rlim_max = 0; if (setrlimit (RLIMIT_CORE, &rlim) == -1) { GST_ERROR ("setrlimit error: %s", g_strerror (errno)); } /* read job description from share memory */ job_desc = NULL; fd = shm_open (shm_name, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if (ftruncate (fd, job_length) == -1) { exit (5); } p = mmap (NULL, job_length, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); job_desc = g_strdup (p); if ((job_desc != NULL) && (!jobdesc_is_valid (job_desc))) { exit (6); } /* initialize log */ name = (gchar *)jobdesc_get_name (job_desc); if (!jobdesc_is_live (job_desc)) { gchar *p; p = jobdesc_get_log_path (job_desc); log_path = g_build_filename (p, "gstreamill.log", NULL); g_free (p); } else { log_path = g_build_filename (log_dir, name, "gstreamill.log", NULL); } ret = init_log (log_path); g_free (log_path); if (ret != 0) { exit (7); } /* launch a job. */ datetime = g_date_time_new_now_local (); date = g_date_time_format (datetime, "%b %d %H:%M:%S"); fprintf (_log->log_hd, "\n*** %s : job %s starting ***\n\n", date, name); g_date_time_unref (datetime); g_free (date); job = job_new ("name", name, "job", job_desc, NULL); job->is_live = jobdesc_is_live (job_desc); job->eos = FALSE; loop = g_main_loop_new (NULL, FALSE); GST_INFO ("Initializing job ..."); if (job_initialize (job, TRUE) != 0) { GST_ERROR ("initialize job failure, exit"); exit (8); } GST_INFO ("Initializing job done"); GST_INFO ("Initializing job's encoders output ..."); if (job_encoders_output_initialize (job) != 0) { GST_ERROR ("initialize job encoders' output failure, exit"); exit (8); } GST_INFO ("Initializing job's encoders output done"); GST_INFO ("Starting job ..."); if (job_start (job) != 0) { GST_ERROR ("start livejob failure, exit"); exit (9); } datetime = g_date_time_new_now_local (); date = g_date_time_format (datetime, "%b %d %H:%M:%S"); fprintf (_log->log_hd, "\n*** %s : job %s started ***\n\n", date, name); g_date_time_unref (datetime); g_free (date); g_free (name); g_free (job_desc); signal (SIGPIPE, SIG_IGN); signal (SIGUSR1, sighandler); signal (SIGTERM, stop_job); g_main_loop_run (loop); } else { /* set parent process maximum of core file */ rlim.rlim_cur = RLIM_INFINITY; rlim.rlim_max = RLIM_INFINITY; if (setrlimit (RLIMIT_CORE, &rlim) == -1) { GST_ERROR ("setrlimit error: %s", g_strerror (errno)); } } /* run in background? */ if (!foreground) { gchar *path; gint ret; /* pid file exist? */ if (g_file_test (PID_FILE, G_FILE_TEST_EXISTS)) { g_print ("file %s found, gstreamill already running !!!\n", PID_FILE); exit (10); } /* media directory */ path = g_strdup_printf ("%s/dvr", MEDIA_LOCATION); if (!g_file_test (path, G_FILE_TEST_EXISTS)) { g_printf ("Create DVR directory: %s", path); if (g_mkdir_with_parents (path, 0755) != 0) { g_printf ("Create DVR directory failure: %s", path); } } g_free (path); path = g_strdup_printf ("%s/transcode/in", MEDIA_LOCATION); if (!g_file_test (path, G_FILE_TEST_EXISTS)) { g_printf ("Create transcode directory: %s", path); if (g_mkdir_with_parents (path, 0755) != 0) { g_printf ("Create transcode directory failure: %s", path); } } g_free (path); path = g_strdup_printf ("%s/transcode/out", MEDIA_LOCATION); if (!g_file_test (path, G_FILE_TEST_EXISTS)) { g_printf ("Create transcode directory: %s", path); if (g_mkdir_with_parents (path, 0755) != 0) { g_printf ("Create transcode directory failure: %s", path); } } g_free (path); /* log to file */ path = g_build_filename (log_dir, "gstreamill.log", NULL); ret = init_log (path); g_free (path); if (ret != 0) { g_print ("Init log error, ret %d.\n", ret); exit (11); } /* daemonize */ if (daemon (0, 0) != 0) { fprintf (_log->log_hd, "Failed to daemonize"); remove_pid_file (); exit (1); } /* create pid file */ if (create_pid_file () != 0) { exit (1); } /* customize signal */ signal (SIGUSR1, sighandler); signal (SIGTERM, stop_gstreamill); datetime = g_date_time_new_now_local (); date = g_date_time_format (datetime, "%b %d %H:%M:%S"); fprintf (_log->log_hd, "\n*** %s : gstreamill started ***\n\n", date); g_free (date); g_date_time_unref (datetime); } /* ignore SIGPIPE */ signal (SIGPIPE, SIG_IGN); loop = g_main_loop_new (NULL, FALSE); /* gstreamill */ gstreamill = gstreamill_new ("daemon", !foreground, "log_dir", log_dir, "exe_path", exe_path, NULL); if (gstreamill_start (gstreamill) != 0) { GST_ERROR ("start gstreamill error, exit."); remove_pid_file (); exit (12); } /* httpstreaming, pull */ httpstreaming = httpstreaming_new ("gstreamill", gstreamill, "address", http_streaming, NULL); if (httpstreaming_start (httpstreaming, 10) != 0) { GST_ERROR ("start httpstreaming error, exit."); remove_pid_file (); exit (13); } if (!foreground) { /* run in background, management via http */ httpmgmt = httpmgmt_new ("gstreamill", gstreamill, "address", http_mgmt, NULL); if (httpmgmt_start (httpmgmt) != 0) { GST_ERROR ("start http mangment error, exit."); remove_pid_file (); exit (14); } } else { /* run in foreground, start job */ gchar *job, *p, *result; JSON_Value *val; JSON_Object *obj; /* ctrl-c, stop gstreamill */ signal (SIGINT, stop_gstreamill); /* ctrl-\, stop gstreamill */ signal (SIGQUIT, stop_gstreamill); if (!g_file_get_contents (job_file, &job, NULL, NULL)) { GST_ERROR ("Read job file %s error.", job_file); exit (15); } p = gstreamill_job_start (gstreamill, job); val = json_parse_string (p); obj = json_value_get_object (val); result = (gchar *)json_object_get_string (obj, "result"); GST_INFO ("start job result: %s.", result); if (g_strcmp0 (result, "success") != 0) { exit (16); } json_value_free (val); g_free (p); } g_main_loop_run (loop); return 0; }
static void gst_dasf_enable (GstDasfSrc* self) { GST_INFO (""); GstPad *peer; GstElement *next_element; GooComponent *component; GstBaseSrc *base_src; if (self->component != NULL) { return; } peer = gst_pad_get_peer (GST_BASE_SRC_PAD (self)); if (G_UNLIKELY (peer == NULL)) { GST_INFO ("No next pad"); return; } next_element = GST_ELEMENT (gst_pad_get_parent (peer)); if (G_UNLIKELY (next_element == NULL)) { GST_INFO ("Cannot find a next element"); goto done; } /** expecting a capsfilter between dasfsrc and goo audio component **/ while (GST_IS_BASE_TRANSFORM (next_element)) { GST_DEBUG_OBJECT(self, "next element name: %s", gst_element_get_name (next_element)); gst_object_unref (peer); peer = gst_pad_get_peer (GST_BASE_TRANSFORM_SRC_PAD (next_element)); gst_object_unref (next_element); next_element = GST_ELEMENT(gst_pad_get_parent (peer)) ; GST_DEBUG_OBJECT (self, "one after element name: %s", gst_element_get_name(next_element)); } /** capsfilter might be found * element next to the caps filter should be goo **/ component = GOO_COMPONENT (g_object_get_data (G_OBJECT (next_element), "goo")); if (G_UNLIKELY (component == NULL)) { GST_INFO ("Previous element does not have a Goo component"); goto done; } if (!GOO_IS_TI_AUDIO_COMPONENT (component)) { GST_WARNING ("The component in previous element is not TI Audio"); goto done; } self->component = GOO_TI_AUDIO_COMPONENT (component); goo_ti_audio_component_set_dasf_mode (self->component, TRUE); GST_DEBUG_OBJECT (self, "set data path"); goo_ti_audio_component_set_data_path (self->component, 0); /** getting num-buffers from base src **/ base_src = GST_BASE_SRC (self); goo_ti_audio_encoder_set_number_buffers (GOO_TI_AUDIO_ENCODER (component), base_src->num_buffers); done: gst_object_unref (peer); gst_object_unref (next_element); GST_DEBUG_OBJECT (self, "peer refcount = %d", G_OBJECT (peer)->ref_count); GST_DEBUG_OBJECT (self, "next element refcount = %d", G_OBJECT (next_element)->ref_count); return; }
/** * gst_rtsp_mount_points_match: * @mounts: a #GstRTSPMountPoints * @path: a mount point * @matched: (out): the amount of @path matched * * Find the factory in @mounts that has the longest match with @path. * * If @matched is %NULL, @path will match the factory exactly otherwise * the amount of characters that matched is returned in @matched. * * Returns: (transfer full): the #GstRTSPMediaFactory for @path. * g_object_unref() after usage. */ GstRTSPMediaFactory * gst_rtsp_mount_points_match (GstRTSPMountPoints * mounts, const gchar * path, gint * matched) { GstRTSPMountPointsPrivate *priv; GstRTSPMediaFactory *result = NULL; GSequenceIter *iter, *best; DataItem item, *ritem; g_return_val_if_fail (GST_IS_RTSP_MOUNT_POINTS (mounts), NULL); g_return_val_if_fail (path != NULL, NULL); priv = mounts->priv; item.path = (gchar *) path; item.len = strlen (path); g_mutex_lock (&priv->lock); if (priv->dirty) { g_sequence_sort (priv->mounts, data_item_compare, mounts); g_sequence_foreach (priv->mounts, (GFunc) data_item_dump, (gpointer) "sort :"); priv->dirty = FALSE; } /* find the location of the media in the hashtable we only use the absolute * path of the uri to find a media factory. If the factory depends on other * properties found in the url, this method should be overridden. */ iter = g_sequence_get_begin_iter (priv->mounts); best = NULL; while (!g_sequence_iter_is_end (iter)) { ritem = g_sequence_get (iter); data_item_dump (ritem, "inspect: "); if (best == NULL) { if (has_prefix (&item, ritem)) { data_item_dump (ritem, "prefix: "); best = iter; } } else { if (!has_prefix (&item, ritem)) break; best = iter; data_item_dump (ritem, "new best: "); } iter = g_sequence_iter_next (iter); } if (best) { ritem = g_sequence_get (best); data_item_dump (ritem, "result: "); if (matched || ritem->len == item.len) { result = g_object_ref (ritem->factory); if (matched) *matched = ritem->len; } } g_mutex_unlock (&priv->lock); GST_INFO ("found media factory %p for path %s", result, path); return result; }
/** * recursively iterate all our pads and search adjacent elements */ static GooComponent * find_goo_component_in_elem (GstElement *elem, SearchContext *ctx) { GstIterator *itr; gpointer item; GooComponent *component = NULL; /* check if we've already examined this element, to prevent loops: */ if (already_visited (ctx->visited_nodes, elem)) { GST_INFO ("already visited elem=%s (%s)", gst_element_get_name (elem), G_OBJECT_TYPE_NAME (elem)); return NULL; } GST_INFO ("elem=%s (%s)", gst_element_get_name (elem), G_OBJECT_TYPE_NAME (elem)); /* note: we don't handle the case of the underlying data structure changing * while iterating.. we just bail out and the user needs to restart. */ for( itr = gst_element_iterate_pads (elem); gst_iterator_next (itr, &item) == GST_ITERATOR_OK && !component; gst_object_unref (item) ) { GstElement *adjacent_elem = NULL; GstPad *pad = GST_PAD (item); GstPad *peer = gst_pad_get_peer (pad); GST_INFO ("found pad: %s (%s)", gst_pad_get_name (pad), G_OBJECT_TYPE_NAME (pad)); if (G_UNLIKELY (peer == NULL)) { GST_INFO ("NULL peer.. not connected yet?"); continue; } /* in the case of GstGhostPad (and probably other proxy pads) * the parent is actually the pad we are a proxy for, so * keep looping until we find the GstElement */ while(TRUE) { GstObject *obj = gst_pad_get_parent (peer); if( GST_IS_PAD(obj) ) { gst_object_unref (peer); peer = GST_PAD (obj); } else { adjacent_elem = GST_ELEMENT (obj); break; } } if (G_UNLIKELY (adjacent_elem == NULL)) { gst_object_unref (peer); GST_INFO ("Cannot find a adjacent element"); continue; } GST_INFO ("found adjacent_elem: %s", gst_element_get_name (adjacent_elem)); component = find_goo_component (adjacent_elem, ctx); /* cleanup: */ gst_object_unref (adjacent_elem); gst_object_unref (peer); } gst_iterator_free (itr); return component; }
/* check if adding pads work as expected */ void test_add_pad() { GstElement *bin, *src1, *src2, *adder, *sink; GstBus *bus; gboolean res; //xmlfile = "test_add_pad"; std_log(LOG_FILENAME_LINE, "Test Started test_add_pad"); GST_INFO ("preparing test"); /* build pipeline */ bin = gst_pipeline_new ("pipeline"); bus = gst_element_get_bus (bin); gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH); src1 = gst_element_factory_make ("audiotestsrc", "src1"); g_object_set (src1, "num-buffers", 4, NULL); g_object_set (src1, "wave", 4, NULL); /* silence */ src2 = gst_element_factory_make ("audiotestsrc", "src2"); /* one buffer less, we connect with 1 buffer of delay */ g_object_set (src2, "num-buffers", 3, NULL); g_object_set (src2, "wave", 4, NULL); /* silence */ adder = gst_element_factory_make ("adder", "adder"); sink = gst_element_factory_make ("fakesink", "sink"); gst_bin_add_many (GST_BIN (bin), src1, adder, sink, NULL); res = gst_element_link (src1, adder); fail_unless (res == TRUE, NULL); res = gst_element_link (adder, sink); fail_unless (res == TRUE, NULL); main_loop = g_main_loop_new (NULL, FALSE); g_signal_connect (bus, "message::segment-done", (GCallback) message_received, bin); g_signal_connect (bus, "message::error", (GCallback) message_received, bin); g_signal_connect (bus, "message::warning", (GCallback) message_received, bin); g_signal_connect (bus, "message::eos", (GCallback) message_received, bin); GST_INFO ("starting test"); /* prepare playing */ res = gst_element_set_state (bin, GST_STATE_PAUSED); fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL); /* wait for completion */ res = gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_CLOCK_TIME_NONE); fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL); /* add other element */ gst_bin_add_many (GST_BIN (bin), src2, NULL); /* now link the second element */ res = gst_element_link (src2, adder); fail_unless (res == TRUE, NULL); /* set to PAUSED as well */ res = gst_element_set_state (src2, GST_STATE_PAUSED); /* now play all */ res = gst_element_set_state (bin, GST_STATE_PLAYING); fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL); g_main_loop_run (main_loop); res = gst_element_set_state (bin, GST_STATE_NULL); fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL); /* cleanup */ g_main_loop_unref (main_loop); gst_object_unref (G_OBJECT (bus)); gst_object_unref (G_OBJECT (bin)); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
/* check if removing pads work as expected */ void test_remove_pad() { GstElement *bin, *src, *adder, *sink; GstBus *bus; GstPad *pad; gboolean res; //xmlfile = "test_remove_pad"; std_log(LOG_FILENAME_LINE, "Test Started test_remove_pad"); GST_INFO ("preparing test"); /* build pipeline */ bin = gst_pipeline_new ("pipeline"); bus = gst_element_get_bus (bin); gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH); src = gst_element_factory_make ("audiotestsrc", "src"); g_object_set (src, "num-buffers", 4, NULL); g_object_set (src, "wave", 4, NULL); adder = gst_element_factory_make ("adder", "adder"); sink = gst_element_factory_make ("fakesink", "sink"); gst_bin_add_many (GST_BIN (bin), src, adder, sink, NULL); res = gst_element_link (src, adder); fail_unless (res == TRUE, NULL); res = gst_element_link (adder, sink); fail_unless (res == TRUE, NULL); /* create an unconnected sinkpad in adder */ pad = gst_element_get_request_pad (adder, "sink%d"); fail_if (pad == NULL, NULL); main_loop = g_main_loop_new (NULL, FALSE); g_signal_connect (bus, "message::segment-done", (GCallback) message_received, bin); g_signal_connect (bus, "message::error", (GCallback) message_received, bin); g_signal_connect (bus, "message::warning", (GCallback) message_received, bin); g_signal_connect (bus, "message::eos", (GCallback) message_received, bin); GST_INFO ("starting test"); /* prepare playing, this will not preroll as adder is waiting * on the unconnected sinkpad. */ res = gst_element_set_state (bin, GST_STATE_PAUSED); fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL); /* wait for completion for one second, will return ASYNC */ res = gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_SECOND); fail_unless (res == GST_STATE_CHANGE_ASYNC, NULL); /* get rid of the pad now, adder should stop waiting on it and * continue the preroll */ gst_element_release_request_pad (adder, pad); gst_object_unref (pad); /* wait for completion, should work now */ res = gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_CLOCK_TIME_NONE); fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL); /* now play all */ res = gst_element_set_state (bin, GST_STATE_PLAYING); fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL); g_main_loop_run (main_loop); res = gst_element_set_state (bin, GST_STATE_NULL); fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL); /* cleanup */ g_main_loop_unref (main_loop); gst_object_unref (G_OBJECT (bus)); gst_object_unref (G_OBJECT (bin)); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
GstFlowReturn gst_ks_video_device_read_frame (GstKsVideoDevice * self, GstBuffer ** buf, GstClockTime * presentation_time, gulong * error_code, gchar ** error_str) { GstKsVideoDevicePrivate *priv = GST_KS_VIDEO_DEVICE_GET_PRIVATE (self); guint req_idx; DWORD wait_ret; BOOL success; DWORD bytes_returned; g_assert (priv->cur_media_type != NULL); /* First time we're called, submit the requests. */ if (G_UNLIKELY (!priv->requests_submitted)) { priv->requests_submitted = TRUE; for (req_idx = 0; req_idx < priv->num_requests; req_idx++) { ReadRequest *req = &g_array_index (priv->requests, ReadRequest, req_idx); if (!gst_ks_video_device_request_frame (self, req, error_code, error_str)) goto error_request_failed; } } *buf = NULL; do { /* Wait for either a request to complete, a cancel or a timeout */ wait_ret = WaitForMultipleObjects (priv->request_events->len, (HANDLE *) priv->request_events->data, FALSE, READ_TIMEOUT); if (wait_ret == WAIT_TIMEOUT) goto error_timeout; else if (wait_ret == WAIT_FAILED) goto error_wait; /* Stopped? */ if (WaitForSingleObject (priv->cancel_event, 0) == WAIT_OBJECT_0) goto error_cancel; /* Find the last ReadRequest that finished and get the result, immediately * re-issuing each request that has completed. */ for (req_idx = wait_ret - WAIT_OBJECT_0; req_idx < priv->num_requests; req_idx++) { ReadRequest *req = &g_array_index (priv->requests, ReadRequest, req_idx); /* * Completed? WaitForMultipleObjects() returns the lowest index if * multiple objects are in the signaled state, and we know that requests * are processed one by one so there's no point in looking further once * we've found the first that's non-signaled. */ if (WaitForSingleObject (req->overlapped.hEvent, 0) != WAIT_OBJECT_0) break; success = GetOverlappedResult (priv->pin_handle, &req->overlapped, &bytes_returned, TRUE); ResetEvent (req->overlapped.hEvent); if (success) { KSSTREAM_HEADER *hdr = &req->params.header; KS_FRAME_INFO *frame_info = &req->params.frame_info; GstClockTime timestamp = GST_CLOCK_TIME_NONE; GstClockTime duration = GST_CLOCK_TIME_NONE; if (hdr->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TIMEVALID) timestamp = hdr->PresentationTime.Time * 100; if (hdr->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_DURATIONVALID) duration = hdr->Duration * 100; UNREF_BUFFER (buf); if (G_LIKELY (hdr->DataUsed != 0)) { /* Assume it's a good frame */ GST_BUFFER_SIZE (req->buf) = hdr->DataUsed; *buf = gst_buffer_ref (req->buf); } if (G_LIKELY (presentation_time != NULL)) *presentation_time = timestamp; if (G_UNLIKELY (GST_DEBUG_IS_ENABLED ())) { gchar *options_flags_str = ks_options_flags_to_string (hdr->OptionsFlags); GST_DEBUG ("PictureNumber=%" G_GUINT64_FORMAT ", DropCount=%" G_GUINT64_FORMAT ", PresentationTime=%" GST_TIME_FORMAT ", Duration=%" GST_TIME_FORMAT ", OptionsFlags=%s: %lu bytes", frame_info->PictureNumber, frame_info->DropCount, GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration), options_flags_str, hdr->DataUsed); g_free (options_flags_str); } /* Protect against old frames. This should never happen, see previous * comment on last_timestamp. */ if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (timestamp))) { if (G_UNLIKELY (GST_CLOCK_TIME_IS_VALID (priv->last_timestamp) && timestamp < priv->last_timestamp)) { GST_INFO ("got an old frame (last_timestamp=%" GST_TIME_FORMAT ", timestamp=%" GST_TIME_FORMAT ")", GST_TIME_ARGS (priv->last_timestamp), GST_TIME_ARGS (timestamp)); UNREF_BUFFER (buf); } else { priv->last_timestamp = timestamp; } } } else if (GetLastError () != ERROR_OPERATION_ABORTED) { goto error_get_result; } /* Submit a new request immediately */ if (!gst_ks_video_device_request_frame (self, req, error_code, error_str)) goto error_request_failed; } } while (*buf == NULL); return GST_FLOW_OK; /* ERRORS */ error_request_failed: { UNREF_BUFFER (buf); return GST_FLOW_ERROR; } error_timeout: { GST_DEBUG ("IOCTL_KS_READ_STREAM timed out"); if (error_code != NULL) *error_code = 0; if (error_str != NULL) *error_str = NULL; return GST_FLOW_UNEXPECTED; } error_wait: { gst_ks_video_device_parse_win32_error ("WaitForMultipleObjects", GetLastError (), error_code, error_str); return GST_FLOW_ERROR; } error_cancel: { if (error_code != NULL) *error_code = 0; if (error_str != NULL) *error_str = NULL; return GST_FLOW_FLUSHING; } error_get_result: { gst_ks_video_device_parse_win32_error ("GetOverlappedResult", GetLastError (), error_code, error_str); return GST_FLOW_ERROR; } }
void test_play_twice() { GstElement *bin, *src1, *src2, *adder, *sink; GstBus *bus; gboolean res; //xmlfile = "test_play_twice"; std_log(LOG_FILENAME_LINE, "Test Started test_play_twice"); GST_INFO ("preparing test"); /* build pipeline */ bin = gst_pipeline_new ("pipeline"); bus = gst_element_get_bus (bin); gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH); src1 = gst_element_factory_make ("audiotestsrc", "src1"); g_object_set (src1, "wave", 4, NULL); /* silence */ src2 = gst_element_factory_make ("audiotestsrc", "src2"); g_object_set (src2, "wave", 4, NULL); /* silence */ adder = gst_element_factory_make ("adder", "adder"); sink = gst_element_factory_make ("fakesink", "sink"); gst_bin_add_many (GST_BIN (bin), src1, src2, adder, sink, NULL); res = gst_element_link (src1, adder); fail_unless (res == TRUE, NULL); res = gst_element_link (src2, adder); fail_unless (res == TRUE, NULL); res = gst_element_link (adder, sink); fail_unless (res == TRUE, NULL); play_seek_event = gst_event_new_seek (1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_SEGMENT | GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, (GstClockTime) 0, GST_SEEK_TYPE_SET, (GstClockTime) 2 * GST_SECOND); play_count = 0; main_loop = g_main_loop_new (NULL, FALSE); g_signal_connect (bus, "message::segment-done", (GCallback) test_play_twice_message_received, bin); g_signal_connect (bus, "message::error", (GCallback) message_received, bin); g_signal_connect (bus, "message::warning", (GCallback) message_received, bin); g_signal_connect (bus, "message::eos", (GCallback) message_received, bin); GST_INFO ("starting test"); /* prepare playing */ res = gst_element_set_state (bin, GST_STATE_PAUSED); fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL); /* wait for completion */ res = gst_element_get_state (GST_ELEMENT (bin), NULL, NULL, GST_CLOCK_TIME_NONE); fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL); res = gst_element_send_event (bin, gst_event_ref (play_seek_event)); fail_unless (res == TRUE, NULL); /* run pipeline */ res = gst_element_set_state (bin, GST_STATE_PLAYING); fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL); g_main_loop_run (main_loop); res = gst_element_set_state (bin, GST_STATE_NULL); fail_unless (res != GST_STATE_CHANGE_FAILURE, NULL); fail_unless (play_count == 2, NULL); /* cleanup */ g_main_loop_unref (main_loop); gst_object_unref (G_OBJECT (bus)); gst_object_unref (G_OBJECT (bin)); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
static gboolean _2d_texture_renderer_init_fbo (GstAmc2DTextureRenderer * renderer) { GstGLFuncs *gl; GLuint fake_texture = 0; guint out_width, out_height; out_width = GST_VIDEO_INFO_WIDTH (&renderer->info); out_height = GST_VIDEO_INFO_HEIGHT (&renderer->info); gl = renderer->context->gl_vtable; if (!gl->GenFramebuffers) { /* turn off the pipeline because Frame buffer object is a not present */ gst_gl_context_set_error (renderer->context, "Context, EXT_framebuffer_object supported: no"); return FALSE; } GST_INFO ("Context, EXT_framebuffer_object supported: yes"); /* setup FBO */ gl->GenFramebuffers (1, &renderer->fbo); gl->BindFramebuffer (GL_FRAMEBUFFER, renderer->fbo); /* setup the render buffer for depth */ gl->GenRenderbuffers (1, &renderer->depth_buffer); gl->BindRenderbuffer (GL_RENDERBUFFER, renderer->depth_buffer); gl->RenderbufferStorage (GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, out_width, out_height); /* a fake texture is attached to the render FBO (cannot init without it) */ gl->GenTextures (1, &fake_texture); gl->BindTexture (GL_TEXTURE_2D, fake_texture); gl->TexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, out_width, out_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); gl->TexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); /* attach the texture to the FBO to renderer to */ gl->FramebufferTexture2D (GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fake_texture, 0); /* attach the depth render buffer to the FBO */ gl->FramebufferRenderbuffer (GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderer->depth_buffer); if (!gst_gl_context_check_framebuffer_status (renderer->context)) { gst_gl_context_set_error (renderer->context, "GL framebuffer status incomplete"); return FALSE; } /* unbind the FBO */ gl->BindFramebuffer (GL_FRAMEBUFFER, 0); gl->DeleteTextures (1, &fake_texture); return TRUE; }
static gboolean gst_gl_context_glx_choose_format (GstGLContext * context, GError ** error) { GstGLContextGLX *context_glx; GstGLWindow *window; GstGLWindowX11 *window_x11; gint error_base; gint event_base; Display *device; context_glx = GST_GL_CONTEXT_GLX (context); window = gst_gl_context_get_window (context); if (!GST_IS_GL_WINDOW_X11 (window)) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Cannot create an GLX context from a non-X11 window"); goto failure; } window_x11 = GST_GL_WINDOW_X11 (window); device = (Display *) gst_gl_display_get_handle (window->display); if (!device) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_RESOURCE_UNAVAILABLE, "Invalid Display handle"); goto failure; } if (!glXQueryExtension (device, &error_base, &event_base)) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_RESOURCE_UNAVAILABLE, "No GLX extension"); goto failure; } if (!glXQueryVersion (device, &context_glx->priv->glx_major, &context_glx->priv->glx_minor)) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_CREATE_CONTEXT, "Failed to query GLX version (glXQueryVersion failed)"); goto failure; } GST_INFO ("GLX Version: %d.%d", context_glx->priv->glx_major, context_glx->priv->glx_minor); /* legacy case */ if (context_glx->priv->glx_major < 1 || (context_glx->priv->glx_major == 1 && context_glx->priv->glx_minor < 3)) { gint attribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, None }; window_x11->visual_info = glXChooseVisual (device, window_x11->screen_num, attribs); if (!window_x11->visual_info) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Bad attributes in glXChooseVisual"); goto failure; } } else { gint attribs[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1, GLX_BLUE_SIZE, 1, GLX_DEPTH_SIZE, 16, GLX_DOUBLEBUFFER, True, None }; int fbcount; context_glx->priv->fbconfigs = glXChooseFBConfig (device, DefaultScreen (device), attribs, &fbcount); if (!context_glx->priv->fbconfigs) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Could not find any FBConfig's to use (check attributes?)"); goto failure; } _describe_fbconfig (device, context_glx->priv->fbconfigs[0]); window_x11->visual_info = glXGetVisualFromFBConfig (device, context_glx->priv->fbconfigs[0]); if (!window_x11->visual_info) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Bad attributes in FBConfig"); goto failure; } } gst_gl_window_x11_create_window ((GstGLWindowX11 *) window); gst_object_unref (window); return TRUE; failure: if (window) gst_object_unref (window); return FALSE; }
/* Note: lots of this code here is also in the videotestsrc.c unit test */ void test_rgb_to_rgb() { const struct { const gchar *pattern_name; gint pattern_enum; guint8 r_expected; guint8 g_expected; guint8 b_expected; } test_patterns[] = { { "white", 3, 0xff, 0xff, 0xff}, { "red", 4, 0xff, 0x00, 0x00}, { "green", 5, 0x00, 0xff, 0x00}, { "blue", 6, 0x00, 0x00, 0xff}, { "black", 2, 0x00, 0x00, 0x00} }; GstElement *pipeline, *src, *filter1, *csp, *filter2, *sink; const GstCaps *template_caps; GstBuffer *buf = NULL; GstPad *srcpad; GList *conversions, *l; gint p; /* test check function */ fail_unless (right_shift_colour (0x00ff0000, 0x11223344) == 0x22); pipeline = gst_pipeline_new ("pipeline"); src = gst_check_setup_element ("videotestsrc"); filter1 = gst_check_setup_element ("capsfilter"); csp = gst_check_setup_element ("ffmpegcolorspace"); filter2 = gst_element_factory_make ("capsfilter", "to_filter"); sink = gst_check_setup_element ("fakesink"); gst_bin_add_many (GST_BIN (pipeline), src, filter1, csp, filter2, sink, NULL); fail_unless (gst_element_link (src, filter1)); fail_unless (gst_element_link (filter1, csp)); fail_unless (gst_element_link (csp, filter2)); fail_unless (gst_element_link (filter2, sink)); srcpad = gst_element_get_pad (src, "src"); template_caps = gst_pad_get_pad_template_caps (srcpad); gst_object_unref (srcpad); g_object_set (sink, "signal-handoffs", TRUE, NULL); g_signal_connect (sink, "preroll-handoff", G_CALLBACK (got_buf_cb), &buf); GST_LOG ("videotestsrc src template caps: %" GST_PTR_FORMAT, template_caps); conversions = create_rgb_conversions (); for (l = conversions; l != NULL; l = l->next) { RGBConversion *conv = (RGBConversion *) l->data; /* does videotestsrc support the from_caps? */ if (!gst_caps_is_subset (conv->from_caps, template_caps)) { GST_DEBUG ("videotestsrc doesn't support from_caps %" GST_PTR_FORMAT, conv->from_caps); continue; } /* caps are supported, let's run some tests then ... */ for (p = 0; p < G_N_ELEMENTS (test_patterns); ++p) { GstStateChangeReturn state_ret; RGBFormat *from = &conv->from_fmt; RGBFormat *to = &conv->to_fmt; /* trick compiler into thinking from is used, might throw warning * otherwise if the debugging system is disabled */ fail_unless (from != NULL); gst_element_set_state (pipeline, GST_STATE_NULL); g_object_set (src, "pattern", test_patterns[p].pattern_enum, NULL); GST_INFO ("%5s %u/%u %08x %08x %08x %08x %u => " "%5s %u/%u %08x %08x %08x %08x %u, pattern=%s", from->nick, from->bpp, from->depth, from->red_mask, from->green_mask, from->blue_mask, from->alpha_mask, from->endianness, to->nick, to->bpp, to->depth, to->red_mask, to->green_mask, to->blue_mask, to->alpha_mask, to->endianness, test_patterns[p].pattern_name); /* now get videotestsrc to produce a buffer with the given caps */ g_object_set (filter1, "caps", conv->from_caps, NULL); /* ... and force ffmpegcolorspace to convert to our target caps */ g_object_set (filter2, "caps", conv->to_caps, NULL); state_ret = gst_element_set_state (pipeline, GST_STATE_PAUSED); if (state_ret == GST_STATE_CHANGE_FAILURE) { GstMessage *msg; GError *err = NULL; msg = gst_bus_poll (GST_ELEMENT_BUS (pipeline), GST_MESSAGE_ERROR, 0); fail_if (msg == NULL, "expected ERROR message on the bus"); fail_unless (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR); gst_message_parse_error (msg, &err, NULL); fail_unless (err != NULL); if (msg->src == GST_OBJECT_CAST (src) && err->code == GST_STREAM_ERROR_FORMAT) { GST_DEBUG ("ffmpegcolorspace does not support this conversion"); gst_message_unref (msg); g_error_free (err); continue; } fail_unless (state_ret != GST_STATE_CHANGE_FAILURE, "pipeline _set_state() to PAUSED failed: %s", err->message); } state_ret = gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS, "pipeline failed going to PAUSED state"); state_ret = gst_element_set_state (pipeline, GST_STATE_NULL); fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS); fail_unless (buf != NULL); /* check buffer caps */ { GstStructure *s; gint v; fail_unless (GST_BUFFER_CAPS (buf) != NULL); s = gst_caps_get_structure (GST_BUFFER_CAPS (buf), 0); fail_unless (gst_structure_get_int (s, "bpp", &v)); fail_unless_equals_int (v, to->bpp); fail_unless (gst_structure_get_int (s, "depth", &v)); fail_unless_equals_int (v, to->depth); fail_unless (gst_structure_get_int (s, "red_mask", &v)); fail_unless_equals_int (v, to->red_mask); fail_unless (gst_structure_get_int (s, "green_mask", &v)); fail_unless_equals_int (v, to->green_mask); fail_unless (gst_structure_get_int (s, "blue_mask", &v)); fail_unless_equals_int (v, to->blue_mask); /* there mustn't be an alpha_mask if there's no alpha component */ if (to->depth == 32) { fail_unless (gst_structure_get_int (s, "alpha_mask", &v)); fail_unless_equals_int (v, to->alpha_mask); } else { fail_unless (gst_structure_get_value (s, "alpha_mask") == NULL); } } /* now check the top-left pixel */ check_rgb_buf (GST_BUFFER_DATA (buf), to->red_mask, to->green_mask, to->blue_mask, to->alpha_mask, test_patterns[p].r_expected, test_patterns[p].g_expected, test_patterns[p].b_expected, to->endianness, to->bpp, to->depth); gst_buffer_unref (buf); buf = NULL; } } g_list_foreach (conversions, (GFunc) rgb_conversion_free, NULL); g_list_free (conversions); gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (pipeline); std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
static gboolean gst_gl_context_egl_create_context (GstGLContext * context, GstGLAPI gl_api, GstGLContext * other_context, GError ** error) { GstGLContextEGL *egl; GstGLWindow *window = NULL; EGLNativeWindowType window_handle = (EGLNativeWindowType) 0; gint i = 0; EGLint context_attrib[3]; EGLint majorVersion; EGLint minorVersion; const gchar *egl_exts; gboolean need_surface = TRUE; guintptr external_gl_context = 0; GstGLDisplay *display; egl = GST_GL_CONTEXT_EGL (context); window = gst_gl_context_get_window (context); if (other_context) { if (gst_gl_context_get_gl_platform (other_context) != GST_GL_PLATFORM_EGL) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Cannot share context with non-EGL context"); goto failure; } external_gl_context = gst_gl_context_get_gl_context (other_context); } if ((gl_api & (GST_GL_API_OPENGL | GST_GL_API_GLES2)) == GST_GL_API_NONE) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_API, "EGL supports opengl or gles2"); goto failure; } display = gst_gl_context_get_display (context); if (display->type == GST_GL_DISPLAY_TYPE_EGL) { egl->egl_display = (EGLDisplay) gst_gl_display_get_handle (display); } else { guintptr native_display = gst_gl_display_get_handle (display); if (!native_display) { GstGLWindow *window = NULL; GST_WARNING ("Failed to get a global display handle, falling back to " "per-window display handles. Context sharing may not work"); if (other_context) window = gst_gl_context_get_window (other_context); if (!window) window = gst_gl_context_get_window (context); if (window) { native_display = gst_gl_window_get_display (window); gst_object_unref (window); } } egl->egl_display = eglGetDisplay ((EGLNativeDisplayType) native_display); } gst_object_unref (display); if (eglInitialize (egl->egl_display, &majorVersion, &minorVersion)) { GST_INFO ("egl initialized, version: %d.%d", majorVersion, minorVersion); } else { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_RESOURCE_UNAVAILABLE, "Failed to initialize egl: %s", gst_gl_context_egl_get_error_string ()); goto failure; } if (gl_api & GST_GL_API_OPENGL) { /* egl + opengl only available with EGL 1.4+ */ if (majorVersion == 1 && minorVersion <= 3) { if ((gl_api & ~GST_GL_API_OPENGL) == GST_GL_API_NONE) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_OLD_LIBS, "EGL version (%i.%i) too old for OpenGL support, (needed at least 1.4)", majorVersion, minorVersion); goto failure; } else { GST_WARNING ("EGL version (%i.%i) too old for OpenGL support, (needed at least 1.4)", majorVersion, minorVersion); if (gl_api & GST_GL_API_GLES2) { goto try_gles2; } else { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Failed to choose a suitable OpenGL API"); goto failure; } } } if (!eglBindAPI (EGL_OPENGL_API)) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED, "Failed to bind OpenGL API: %s", gst_gl_context_egl_get_error_string ()); goto failure; } GST_INFO ("Using OpenGL"); egl->gl_api = GST_GL_API_OPENGL; } else if (gl_api & GST_GL_API_GLES2) { try_gles2: if (!eglBindAPI (EGL_OPENGL_ES_API)) { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED, "Failed to bind OpenGL|ES API: %s", gst_gl_context_egl_get_error_string ()); goto failure; } GST_INFO ("Using OpenGL|ES 2.0"); egl->gl_api = GST_GL_API_GLES2; } if (!gst_gl_context_egl_choose_config (egl, other_context, error)) { g_assert (error == NULL || *error != NULL); goto failure; } GST_DEBUG ("about to create gl context\n"); if (egl->gl_api & GST_GL_API_GLES2) { context_attrib[i++] = EGL_CONTEXT_CLIENT_VERSION; context_attrib[i++] = 2; } context_attrib[i++] = EGL_NONE; egl->egl_context = eglCreateContext (egl->egl_display, egl->egl_config, (EGLContext) external_gl_context, context_attrib); if (egl->egl_context != EGL_NO_CONTEXT) { GST_INFO ("gl context created: %" G_GUINTPTR_FORMAT, (guintptr) egl->egl_context); } else { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_CREATE_CONTEXT, "Failed to create a OpenGL context: %s", gst_gl_context_egl_get_error_string ()); goto failure; } egl_exts = eglQueryString (egl->egl_display, EGL_EXTENSIONS); if (other_context == NULL) { /* FIXME do we want a window vfunc ? */ #if GST_GL_HAVE_WINDOW_X11 if (GST_GL_IS_WINDOW_X11 (context->window)) { gst_gl_window_x11_create_window ((GstGLWindowX11 *) context->window); } #endif #if GST_GL_HAVE_WINDOW_WIN32 if (GST_GL_IS_WINDOW_WIN32 (context->window)) { gst_gl_window_win32_create_window ((GstGLWindowWin32 *) context->window); } #endif } if (window) window_handle = (EGLNativeWindowType) gst_gl_window_get_window_handle (window); if (window_handle) { egl->egl_surface = eglCreateWindowSurface (egl->egl_display, egl->egl_config, window_handle, NULL); } else if (!gst_gl_check_extension ("EGL_KHR_surfaceless_context", egl_exts)) { EGLint surface_attrib[7]; gint j = 0; /* FIXME: Width/height doesn't seem to matter but we can't leave them * at 0, otherwise X11 complains about BadValue */ surface_attrib[j++] = EGL_WIDTH; surface_attrib[j++] = 1; surface_attrib[j++] = EGL_HEIGHT; surface_attrib[j++] = 1; surface_attrib[j++] = EGL_LARGEST_PBUFFER; surface_attrib[j++] = EGL_TRUE; surface_attrib[j++] = EGL_NONE; egl->egl_surface = eglCreatePbufferSurface (egl->egl_display, egl->egl_config, surface_attrib); } else { egl->egl_surface = EGL_NO_SURFACE; need_surface = FALSE; } if (need_surface) { if (egl->egl_surface != EGL_NO_SURFACE) { GST_INFO ("surface created"); } else { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_FAILED, "Failed to create window surface: %s", gst_gl_context_egl_get_error_string ()); goto failure; } } /* EGLImage functions */ if (GST_GL_CHECK_GL_VERSION (majorVersion, minorVersion, 1, 5)) { egl->eglCreateImage = gst_gl_context_get_proc_address (context, "eglCreateImage"); egl->eglDestroyImage = gst_gl_context_get_proc_address (context, "eglDestroyImage"); } else if (gst_gl_check_extension ("EGL_KHR_image_base", egl_exts)) { egl->eglCreateImage = gst_gl_context_get_proc_address (context, "eglCreateImageKHR"); egl->eglDestroyImage = gst_gl_context_get_proc_address (context, "eglDestroyImageKHR"); } if (egl->eglCreateImage == NULL || egl->eglDestroyImage == NULL) { egl->eglCreateImage = NULL; egl->eglDestroyImage = NULL; } if (window) gst_object_unref (window); return TRUE; failure: if (window) gst_object_unref (window); return FALSE; }
/* set up the encoder state */ static gboolean gst_two_lame_setup (GstTwoLame * twolame) { #define CHECK_ERROR(command) G_STMT_START {\ if ((command) < 0) { \ GST_ERROR_OBJECT (twolame, "setup failed: " G_STRINGIFY (command)); \ return FALSE; \ } \ }G_STMT_END int retval; GstCaps *allowed_caps; GST_DEBUG_OBJECT (twolame, "starting setup"); /* check if we're already setup; if we are, we might want to check * if this initialization is compatible with the previous one */ /* FIXME: do this */ if (twolame->setup) { GST_WARNING_OBJECT (twolame, "already setup"); twolame->setup = FALSE; } twolame->glopts = twolame_init (); if (twolame->glopts == NULL) return FALSE; /* copy the parameters over */ twolame_set_in_samplerate (twolame->glopts, twolame->samplerate); /* let twolame choose default samplerate unless outgoing sample rate is fixed */ allowed_caps = gst_pad_get_allowed_caps (GST_AUDIO_ENCODER_SRC_PAD (twolame)); if (allowed_caps != NULL) { GstStructure *structure; gint samplerate; structure = gst_caps_get_structure (allowed_caps, 0); if (gst_structure_get_int (structure, "rate", &samplerate)) { GST_DEBUG_OBJECT (twolame, "Setting sample rate to %d as fixed in src caps", samplerate); twolame_set_out_samplerate (twolame->glopts, samplerate); } else { GST_DEBUG_OBJECT (twolame, "Letting twolame choose sample rate"); twolame_set_out_samplerate (twolame->glopts, 0); } gst_caps_unref (allowed_caps); allowed_caps = NULL; } else { GST_DEBUG_OBJECT (twolame, "No peer yet, letting twolame choose sample rate"); twolame_set_out_samplerate (twolame->glopts, 0); } /* force mono encoding if we only have one channel */ if (twolame->num_channels == 1) twolame->mode = 3; /* Fix bitrates and MPEG version */ CHECK_ERROR (twolame_set_num_channels (twolame->glopts, twolame->num_channels)); CHECK_ERROR (twolame_set_mode (twolame->glopts, twolame->mode)); CHECK_ERROR (twolame_set_psymodel (twolame->glopts, twolame->psymodel)); CHECK_AND_FIXUP_BITRATE (twolame, "bitrate", twolame->bitrate); CHECK_ERROR (twolame_set_bitrate (twolame->glopts, twolame->bitrate)); CHECK_ERROR (twolame_set_padding (twolame->glopts, twolame->padding)); CHECK_ERROR (twolame_set_energy_levels (twolame->glopts, twolame->energy_level_extension)); CHECK_ERROR (twolame_set_emphasis (twolame->glopts, twolame->emphasis)); CHECK_ERROR (twolame_set_error_protection (twolame->glopts, twolame->error_protection)); CHECK_ERROR (twolame_set_copyright (twolame->glopts, twolame->copyright)); CHECK_ERROR (twolame_set_original (twolame->glopts, twolame->original)); CHECK_ERROR (twolame_set_VBR (twolame->glopts, twolame->vbr)); CHECK_ERROR (twolame_set_VBR_level (twolame->glopts, twolame->vbr_level)); CHECK_ERROR (twolame_set_ATH_level (twolame->glopts, twolame->ath_level)); CHECK_AND_FIXUP_BITRATE (twolame, "vbr-max-bitrate", twolame->vbr_max_bitrate); CHECK_ERROR (twolame_set_VBR_max_bitrate_kbps (twolame->glopts, twolame->vbr_max_bitrate)); CHECK_ERROR (twolame_set_quick_mode (twolame->glopts, twolame->quick_mode)); CHECK_ERROR (twolame_set_quick_count (twolame->glopts, twolame->quick_mode_count)); /* initialize the twolame encoder */ if ((retval = twolame_init_params (twolame->glopts)) >= 0) { twolame->setup = TRUE; /* FIXME: it would be nice to print out the mode here */ GST_INFO ("twolame encoder setup (%d kbit/s, %d Hz, %d channels)", twolame->bitrate, twolame->samplerate, twolame->num_channels); } else { GST_ERROR_OBJECT (twolame, "twolame_init_params returned %d", retval); } GST_DEBUG_OBJECT (twolame, "done with setup"); return twolame->setup; #undef CHECK_ERROR }
/** * gst_rtsp_media_factory_construct: * @factory: a #GstRTSPMediaFactory * @url: the url used * * Prepare the media object and create its streams. Implementations * should create the needed gstreamer elements and add them to the result * object. No state changes should be performed on them yet. * * One or more GstRTSPMediaStream objects should be added to the result with * the srcpad member set to a source pad that produces buffer of type * application/x-rtp. * * Returns: a new #GstRTSPMedia if the media could be prepared. */ GstRTSPMedia * gst_rtsp_media_factory_construct (GstRTSPMediaFactory * factory, const GstRTSPUrl * url) { gchar *key; GstRTSPMedia *media; GstRTSPMediaFactoryClass *klass; klass = GST_RTSP_MEDIA_FACTORY_GET_CLASS (factory); /* convert the url to a key for the hashtable. NULL return or a NULL function * will not cache anything for this factory. */ if (klass->gen_key) key = klass->gen_key (factory, url); else key = NULL; g_mutex_lock (&factory->medias_lock); if (key) { /* we have a key, see if we find a cached media */ media = g_hash_table_lookup (factory->medias, key); if (media) g_object_ref (media); } else media = NULL; if (media == NULL) { /* nothing cached found, try to create one */ if (klass->construct) { media = klass->construct (factory, url); if (media) g_signal_emit (factory, gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONSTRUCTED], 0, media, NULL); } else media = NULL; if (media) { /* configure the media */ if (klass->configure) klass->configure (factory, media); g_signal_emit (factory, gst_rtsp_media_factory_signals[SIGNAL_MEDIA_CONFIGURE], 0, media, NULL); /* check if we can cache this media */ if (gst_rtsp_media_is_shared (media)) { /* insert in the hashtable, takes ownership of the key */ g_object_ref (media); g_hash_table_insert (factory->medias, key, media); key = NULL; } if (!gst_rtsp_media_is_reusable (media)) { /* when not reusable, connect to the unprepare signal to remove the item * from our cache when it gets unprepared */ g_signal_connect (media, "unprepared", (GCallback) media_unprepared, factory); } } } g_mutex_unlock (&factory->medias_lock); if (key) g_free (key); GST_INFO ("constructed media %p for url %s", media, url->abspath); return media; }
GST_END_TEST GST_START_TEST (check_emit_encoded_media) { guint bus_watch_id1, bus_watch_id2; GstBus *srcbus, *testbus; GstCaps *caps; GST_INFO ("Running test check_push_buffer"); loop = g_main_loop_new (NULL, FALSE); /* Create source pipeline */ src_pipeline = gst_pipeline_new ("src-pipeline"); uridecodebin = gst_element_factory_make ("uridecodebin", NULL); appsink = gst_element_factory_make ("appsink", NULL); srcbus = gst_pipeline_get_bus (GST_PIPELINE (src_pipeline)); bus_watch_id1 = gst_bus_add_watch (srcbus, gst_bus_async_signal_func, NULL); g_signal_connect (srcbus, "message", G_CALLBACK (bus_msg_cb), src_pipeline); g_object_unref (srcbus); gst_bin_add_many (GST_BIN (src_pipeline), uridecodebin, appsink, NULL); caps = gst_caps_new_any (); g_object_set (G_OBJECT (uridecodebin), "uri", VIDEO_PATH, "caps", caps, NULL); gst_caps_unref (caps); g_signal_connect (G_OBJECT (uridecodebin), "pad-added", G_CALLBACK (link_pad), appsink); g_object_set (appsink, "emit-signals", TRUE, NULL); g_signal_connect (appsink, "new-sample", G_CALLBACK (post_recv_sample), NULL); g_signal_connect (appsink, "eos", G_CALLBACK (appsink_eos_cb), NULL); /* Create test pipeline */ test_pipeline = gst_pipeline_new ("test-pipeline"); httpep = gst_element_factory_make ("httpendpoint", NULL); g_object_set (httpep, "use-encoded-media", TRUE, NULL); testbus = gst_pipeline_get_bus (GST_PIPELINE (test_pipeline)); bus_watch_id2 = gst_bus_add_watch (testbus, gst_bus_async_signal_func, NULL); g_signal_connect (testbus, "message", G_CALLBACK (bus_msg_cb), test_pipeline); g_object_unref (testbus); gst_bin_add (GST_BIN (test_pipeline), httpep); g_signal_connect (G_OBJECT (httpep), "eos", G_CALLBACK (http_eos_cb), NULL); /* Set pipeline to start state */ gst_element_set_state (test_pipeline, GST_STATE_PLAYING); g_object_get (G_OBJECT (httpep), "http-method", &method, NULL); GST_INFO ("Http end point configured as %d", method); /* Http end point is not configured yet */ ck_assert_int_eq (method, KMS_HTTP_ENDPOINT_METHOD_UNDEFINED); GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (test_pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "test_entering_main_loop"); mark_point (); g_timeout_add_seconds (WAIT_TIMEOUT, timer_cb, NULL); GST_INFO ("Waitig %d second for Agnosticbin to be ready to go to " "PLAYING state", WAIT_TIMEOUT); g_main_loop_run (loop); mark_point (); GST_DEBUG ("Main loop stopped"); GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (src_pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "src_after_main_loop"); GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (test_pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "test_after_main_loop"); gst_element_set_state (src_pipeline, GST_STATE_NULL); gst_object_unref (GST_OBJECT (src_pipeline)); gst_element_set_state (test_pipeline, GST_STATE_NULL); gst_object_unref (GST_OBJECT (test_pipeline)); g_source_remove (bus_watch_id1); g_source_remove (bus_watch_id2); g_main_loop_unref (loop); }
static gboolean register_plugin (GstPlugin * plugin, const gchar * vendor, const gchar * filename) { GModule *module; GstFrei0rPluginRegisterReturn ret = GST_FREI0R_PLUGIN_REGISTER_RETURN_FAILED; GstFrei0rFuncTable ftable = { NULL, }; gint i; f0r_plugin_info_t info = { NULL, }; f0r_instance_t *instance = NULL; GST_DEBUG ("Registering plugin '%s'", filename); module = g_module_open (filename, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); if (!module) { GST_WARNING ("Failed to load plugin"); return FALSE; } if (!g_module_symbol (module, "f0r_init", (gpointer *) & ftable.init)) { GST_INFO ("No frei0r plugin"); g_module_close (module); return FALSE; } if (!g_module_symbol (module, "f0r_deinit", (gpointer *) & ftable.deinit) || !g_module_symbol (module, "f0r_construct", (gpointer *) & ftable.construct) || !g_module_symbol (module, "f0r_destruct", (gpointer *) & ftable.destruct) || !g_module_symbol (module, "f0r_get_plugin_info", (gpointer *) & ftable.get_plugin_info) || !g_module_symbol (module, "f0r_get_param_info", (gpointer *) & ftable.get_param_info) || !g_module_symbol (module, "f0r_set_param_value", (gpointer *) & ftable.set_param_value) || !g_module_symbol (module, "f0r_get_param_value", (gpointer *) & ftable.get_param_value)) goto invalid_frei0r_plugin; /* One of these must exist */ g_module_symbol (module, "f0r_update", (gpointer *) & ftable.update); g_module_symbol (module, "f0r_update2", (gpointer *) & ftable.update2); if (!ftable.init ()) { GST_WARNING ("Failed to initialize plugin"); g_module_close (module); return FALSE; } if (!ftable.update && !ftable.update2) goto invalid_frei0r_plugin; ftable.get_plugin_info (&info); if (info.frei0r_version > 1) { GST_WARNING ("Unsupported frei0r version %d", info.frei0r_version); ftable.deinit (); g_module_close (module); return FALSE; } if (info.color_model > F0R_COLOR_MODEL_PACKED32) { GST_WARNING ("Unsupported color model %d", info.color_model); ftable.deinit (); g_module_close (module); return FALSE; } for (i = 0; i < info.num_params; i++) { f0r_param_info_t pinfo = { NULL, }; ftable.get_param_info (&pinfo, i); if (pinfo.type > F0R_PARAM_STRING) { GST_WARNING ("Unsupported parameter type %d", pinfo.type); ftable.deinit (); g_module_close (module); return FALSE; } } instance = ftable.construct (640, 480); if (!instance) { GST_WARNING ("Failed to instanciate plugin '%s'", info.name); ftable.deinit (); g_module_close (module); return FALSE; } ftable.destruct (instance); switch (info.plugin_type) { case F0R_PLUGIN_TYPE_FILTER: ret = gst_frei0r_filter_register (plugin, vendor, &info, &ftable); break; case F0R_PLUGIN_TYPE_SOURCE: ret = gst_frei0r_src_register (plugin, vendor, &info, &ftable); break; case F0R_PLUGIN_TYPE_MIXER2: case F0R_PLUGIN_TYPE_MIXER3: ret = gst_frei0r_mixer_register (plugin, vendor, &info, &ftable); break; default: break; } switch (ret) { case GST_FREI0R_PLUGIN_REGISTER_RETURN_OK: return TRUE; case GST_FREI0R_PLUGIN_REGISTER_RETURN_FAILED: GST_ERROR ("Failed to register frei0r plugin"); ftable.deinit (); g_module_close (module); return FALSE; case GST_FREI0R_PLUGIN_REGISTER_RETURN_ALREADY_REGISTERED: GST_DEBUG ("frei0r plugin already registered"); ftable.deinit (); g_module_close (module); return TRUE; default: g_return_val_if_reached (FALSE); } g_return_val_if_reached (FALSE); invalid_frei0r_plugin: GST_ERROR ("Invalid frei0r plugin"); ftable.deinit (); g_module_close (module); return FALSE; }
int main (int argc, char **argv) { static const GOptionEntry test_goptions[] = { { "videosink", '\0', 0, G_OPTION_ARG_STRING, &opt_videosink_str, "videosink to use (default: " DEFAULT_VIDEOSINK ")", NULL }, { "caps", '\0', 0, G_OPTION_ARG_STRING, &opt_filtercaps_str, "filter caps to narrow down formats to test", NULL }, { "with-ffmpegcolorspace", '\0', 0, G_OPTION_ARG_NONE, &opt_with_ffmpegcolorspace, "whether to add an ffmpegcolorspace element in front of the sink", NULL }, {NULL, '\0', 0, 0, NULL, NULL, NULL} }; GOptionContext *ctx; GError *opt_err = NULL; GstElement *pipeline, *src, *filter1, *crop, *scale, *filter2, *csp, *sink; GMainLoop *loop; GstCaps *filter_caps = NULL; GList *caps_list, *l; if (!g_thread_supported ()) g_thread_init (NULL); /* command line option parsing */ ctx = g_option_context_new (""); g_option_context_add_group (ctx, gst_init_get_option_group ()); g_option_context_add_main_entries (ctx, test_goptions, NULL); if (!g_option_context_parse (ctx, &argc, &argv, &opt_err)) { g_error ("Error parsing command line options: %s", opt_err->message); return -1; } GST_DEBUG_CATEGORY_INIT (videocrop_test_debug, "videocroptest", 0, "vctest"); loop = g_main_loop_new (NULL, FALSE); pipeline = gst_pipeline_new ("pipeline"); src = gst_element_factory_make ("videotestsrc", "videotestsrc"); g_assert (src != NULL); filter1 = gst_element_factory_make ("capsfilter", "capsfilter1"); g_assert (filter1 != NULL); crop = gst_element_factory_make ("videocrop", "videocrop"); g_assert (crop != NULL); scale = gst_element_factory_make ("videoscale", "videoscale"); g_assert (scale != NULL); filter2 = gst_element_factory_make ("capsfilter", "capsfilter2"); g_assert (filter2 != NULL); if (opt_with_ffmpegcolorspace) { g_print ("Adding ffmpegcolorspace\n"); csp = gst_element_factory_make ("ffmpegcolorspace", "colorspace"); } else { csp = gst_element_factory_make ("identity", "colorspace"); } g_assert (csp != NULL); if (opt_filtercaps_str) { filter_caps = gst_caps_from_string (opt_filtercaps_str); if (filter_caps == NULL) { g_error ("Invalid filter caps string '%s'", opt_filtercaps_str); } else { g_print ("Using filter caps '%s'\n", opt_filtercaps_str); } } if (opt_videosink_str) { g_print ("Trying videosink '%s' ...", opt_videosink_str); sink = gst_element_factory_make (opt_videosink_str, "sink"); g_print ("%s\n", (sink) ? "ok" : "element couldn't be created"); } else { sink = NULL; } if (sink == NULL) { g_print ("Trying videosink '%s' ...", DEFAULT_VIDEOSINK); sink = gst_element_factory_make (DEFAULT_VIDEOSINK, "sink"); g_print ("%s\n", (sink) ? "ok" : "element couldn't be created"); } if (sink == NULL) { g_print ("Trying videosink '%s' ...", "xvimagesink"); sink = gst_element_factory_make ("xvimagesink", "sink"); g_print ("%s\n", (sink) ? "ok" : "element couldn't be created"); } if (sink == NULL) { g_print ("Trying videosink '%s' ...", "ximagesink"); sink = gst_element_factory_make ("ximagesink", "sink"); g_print ("%s\n", (sink) ? "ok" : "element couldn't be created"); } g_assert (sink != NULL); gst_bin_add_many (GST_BIN (pipeline), src, filter1, crop, scale, filter2, csp, sink, NULL); if (!gst_element_link (src, filter1)) g_error ("Failed to link videotestsrc to capsfilter1"); if (!gst_element_link (filter1, crop)) g_error ("Failed to link capsfilter1 to videocrop"); if (!gst_element_link (crop, scale)) g_error ("Failed to link videocrop to videoscale"); if (!gst_element_link (scale, filter2)) g_error ("Failed to link videoscale to capsfilter2"); if (!gst_element_link (filter2, csp)) g_error ("Failed to link capsfilter2 to ffmpegcolorspace"); if (!gst_element_link (csp, sink)) g_error ("Failed to link ffmpegcolorspace to video sink"); caps_list = video_crop_get_test_caps (crop); for (l = caps_list; l != NULL; l = l->next) { GstStateChangeReturn ret; GstCaps *caps, *out_caps; gboolean skip = FALSE; gchar *s; if (filter_caps) { GstCaps *icaps; icaps = gst_caps_intersect (filter_caps, GST_CAPS (l->data)); skip = gst_caps_is_empty (icaps); gst_caps_unref (icaps); } /* this is the size of our window (stays fixed) */ out_caps = gst_caps_copy (GST_CAPS (l->data)); gst_structure_set (gst_caps_get_structure (out_caps, 0), "width", G_TYPE_INT, OUT_WIDTH, "height", G_TYPE_INT, OUT_HEIGHT, NULL); g_object_set (filter2, "caps", out_caps, NULL); /* filter1 gets these too to prevent videotestsrc from renegotiating */ g_object_set (filter1, "caps", out_caps, NULL); gst_caps_unref (out_caps); caps = gst_caps_copy (GST_CAPS (l->data)); GST_INFO ("testing format: %" GST_PTR_FORMAT, caps); s = gst_caps_to_string (caps); if (skip) { g_print ("Skipping format: %s\n", s); g_free (s); continue; } g_print ("Format: %s\n", s); caps = gst_caps_make_writable (caps); /* FIXME: check return values */ ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); if (ret != GST_STATE_CHANGE_FAILURE) { ret = gst_element_get_state (pipeline, NULL, NULL, -1); if (ret != GST_STATE_CHANGE_FAILURE) { test_with_caps (src, crop, caps); } else { g_print ("Format: %s not supported (failed to go to PLAYING)\n", s); } } else { g_print ("Format: %s not supported\n", s); } gst_element_set_state (pipeline, GST_STATE_NULL); gst_caps_unref (caps); g_free (s); } g_list_foreach (caps_list, (GFunc) gst_caps_unref, NULL); g_list_free (caps_list); gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (pipeline); return 0; }
gboolean audio_convert_prepare_context (AudioConvertCtx * ctx, GstAudioInfo * in, GstAudioInfo * out, GstAudioConvertDithering dither, GstAudioConvertNoiseShaping ns) { gint idx_in, idx_out; gint in_depth, out_depth; g_return_val_if_fail (ctx != NULL, FALSE); g_return_val_if_fail (in != NULL, FALSE); g_return_val_if_fail (out != NULL, FALSE); /* first clean the existing context */ audio_convert_clean_context (ctx); if ((GST_AUDIO_INFO_CHANNELS (in) != GST_AUDIO_INFO_CHANNELS (out)) && (GST_AUDIO_INFO_IS_UNPOSITIONED (in) || GST_AUDIO_INFO_IS_UNPOSITIONED (out))) goto unpositioned; ctx->in = *in; ctx->out = *out; in_depth = GST_AUDIO_FORMAT_INFO_DEPTH (in->finfo); out_depth = GST_AUDIO_FORMAT_INFO_DEPTH (out->finfo); GST_INFO ("depth in %d, out %d", in_depth, out_depth); /* Don't dither or apply noise shaping if target depth is bigger than 20 bits * as DA converters only can do a SNR up to 20 bits in reality. * Also don't dither or apply noise shaping if target depth is larger than * source depth. */ if (out_depth <= 20 && (!GST_AUDIO_FORMAT_INFO_IS_INTEGER (in->finfo) || in_depth >= out_depth)) { ctx->dither = dither; ctx->ns = ns; GST_INFO ("using dither %d and noise shaping %d", dither, ns); } else { ctx->dither = DITHER_NONE; ctx->ns = NOISE_SHAPING_NONE; GST_INFO ("using no dither and noise shaping"); } /* Use simple error feedback when output sample rate is smaller than * 32000 as the other methods might move the noise to audible ranges */ if (ctx->ns > NOISE_SHAPING_ERROR_FEEDBACK && out->rate < 32000) ctx->ns = NOISE_SHAPING_ERROR_FEEDBACK; gst_channel_mix_setup_matrix (ctx); idx_in = audio_convert_get_func_index (ctx, in->finfo); ctx->unpack = unpack_funcs[idx_in]; idx_out = audio_convert_get_func_index (ctx, out->finfo); ctx->pack = pack_funcs[idx_out]; GST_INFO ("func index in %d, out %d", idx_in, idx_out); /* if both formats are float/double or we use noise shaping use double as * intermediate format and switch mixing */ if (!DOUBLE_INTERMEDIATE_FORMAT (ctx)) { GST_INFO ("use int mixing"); ctx->channel_mix = (AudioConvertMix) gst_channel_mix_mix_int; } else { GST_INFO ("use float mixing"); ctx->channel_mix = (AudioConvertMix) gst_channel_mix_mix_float; } GST_INFO ("unitsizes: %d -> %d", in->bpf, out->bpf); /* check if input is in default format */ ctx->in_default = check_default (ctx, in->finfo); /* check if channel mixer is passthrough */ ctx->mix_passthrough = gst_channel_mix_passthrough (ctx); /* check if output is in default format */ ctx->out_default = check_default (ctx, out->finfo); GST_INFO ("in default %d, mix passthrough %d, out default %d", ctx->in_default, ctx->mix_passthrough, ctx->out_default); ctx->in_scale = GST_AUDIO_FORMAT_INFO_IS_INTEGER (in->finfo) ? (32 - in_depth) : 0; ctx->out_scale = GST_AUDIO_FORMAT_INFO_IS_INTEGER (out->finfo) ? (32 - out_depth) : 0; GST_INFO ("scale in %d, out %d", ctx->in_scale, ctx->out_scale); gst_audio_quantize_setup (ctx); return TRUE; /* ERRORS */ unpositioned: { GST_WARNING ("unpositioned channels"); return FALSE; } }
static gboolean gst_dshowvideosrc_set_caps (GstBaseSrc * bsrc, GstCaps * caps) { HRESULT hres; IPin *input_pin = NULL; IPin *output_pin = NULL; GstDshowVideoSrc *src = GST_DSHOWVIDEOSRC (bsrc); GstStructure *s = gst_caps_get_structure (caps, 0); OAFilterState ds_graph_state; GstCaps *current_caps; /* search the negociated caps in our caps list to get its index and the corresponding mediatype */ if (gst_caps_is_subset (caps, src->caps)) { guint i = 0; gint res = -1; hres = src->media_control->GetState(0, &ds_graph_state); if(ds_graph_state == State_Running) { GST_INFO("Setting caps while DirectShow graph is already running"); current_caps = gst_pad_get_current_caps(GST_BASE_SRC_PAD(src)); if(gst_caps_is_equal(current_caps, caps)) { /* no need to set caps, just return */ GST_INFO("Not resetting caps"); gst_caps_unref(current_caps); return TRUE; } else { /* stop graph and disconnect filters so new caps can be set */ GST_INFO("Different caps, stopping DirectShow graph"); hres = src->media_control->Stop(); hres = src->media_control->GetState(2000, &ds_graph_state); if(hres != S_OK) { GST_ERROR("Could not stop DirectShow graph. Cannot renegoiate pins."); goto error; } gst_dshow_get_pin_from_filter (src->dshow_fakesink, PINDIR_INPUT, &input_pin); if (!input_pin) { input_pin->Release(); GST_ERROR ("Can't get input pin from our dshow fakesink"); goto error; } input_pin->ConnectedTo(&output_pin); hres = input_pin->Disconnect(); hres = output_pin->Disconnect(); input_pin->Release(); output_pin->Release(); } gst_caps_unref(current_caps); } for (; i < gst_caps_get_size (src->caps) && res == -1; i++) { GstCaps *capstmp = gst_caps_copy_nth (src->caps, i); if (gst_caps_is_subset (caps, capstmp)) { res = i; } gst_caps_unref (capstmp); } if (res != -1 && src->pins_mediatypes) { /* get the corresponding media type and build the dshow graph */ GList *type_pin_mediatype = g_list_nth (src->pins_mediatypes, res); if (type_pin_mediatype) { GstCapturePinMediaType *pin_mediatype = (GstCapturePinMediaType *) type_pin_mediatype->data; gchar *src_caps_string = NULL; const gchar *format_string = NULL; /* retrieve the desired video size */ VIDEOINFOHEADER *video_info = NULL; gint width = 0; gint height = 0; gint numerator = 0; gint denominator = 0; gst_structure_get_int (s, "width", &width); gst_structure_get_int (s, "height", &height); gst_structure_get_fraction (s, "framerate", &numerator, &denominator); /* check if the desired video size is valid about granularity */ /* This check will be removed when GST_TYPE_INT_RANGE_STEP exits */ /* See remarks in gst_dshow_new_video_caps function */ if (pin_mediatype->granularityWidth != 0 && width % pin_mediatype->granularityWidth != 0) g_warning ("your desired video size is not valid : %d mod %d !=0\n", width, pin_mediatype->granularityWidth); if (pin_mediatype->granularityHeight != 0 && height % pin_mediatype->granularityHeight != 0) g_warning ("your desired video size is not valid : %d mod %d !=0\n", height, pin_mediatype->granularityHeight); /* update mediatype */ video_info = (VIDEOINFOHEADER *) pin_mediatype->mediatype->pbFormat; video_info->bmiHeader.biWidth = width; video_info->bmiHeader.biHeight = height; video_info->AvgTimePerFrame = (LONGLONG) (10000000 * denominator / (double) numerator); video_info->bmiHeader.biSizeImage = DIBSIZE (video_info->bmiHeader); pin_mediatype->mediatype->lSampleSize = DIBSIZE (video_info->bmiHeader); src->dshow_fakesink->gst_set_media_type (pin_mediatype->mediatype); src->dshow_fakesink->gst_set_buffer_callback ( (push_buffer_func) gst_dshowvideosrc_push_buffer, src); gst_dshow_get_pin_from_filter (src->dshow_fakesink, PINDIR_INPUT, &input_pin); if (!input_pin) { GST_ERROR ("Can't get input pin from our dshow fakesink"); goto error; } hres = src->filter_graph->ConnectDirect (pin_mediatype->capture_pin, input_pin, pin_mediatype->mediatype); input_pin->Release (); if (hres != S_OK) { GST_ERROR ("Can't connect capture filter with fakesink filter (error=0x%x)", hres); goto error; } /* save width and height negociated */ gst_structure_get_int (s, "width", &src->width); gst_structure_get_int (s, "height", &src->height); src->is_rgb = FALSE; format_string = gst_structure_get_string (s, "format"); if(format_string) { if(!strcmp(format_string, "BGR")) { src->is_rgb = TRUE; } else { src->is_rgb = FALSE; } } hres = src->media_control->Run(); hres = src->media_control->GetState(5000, &ds_graph_state); if(hres != S_OK || ds_graph_state != State_Running) { GST_ERROR("Could not run graph"); goto error; } } } } return TRUE; error: return FALSE; }
gboolean gst_gl_mixer_process_textures (GstGLMixer * mix, GstBuffer * outbuf) { guint i; GList *walk; guint out_tex; gboolean res = TRUE; guint array_index = 0; GstVideoFrame out_frame; gboolean out_gl_wrapped = FALSE; GstElement *element = GST_ELEMENT (mix); GstVideoAggregator *vagg = GST_VIDEO_AGGREGATOR (mix); GstGLMixerClass *mix_class = GST_GL_MIXER_GET_CLASS (mix); GstGLMixerPrivate *priv = mix->priv; GST_TRACE ("Processing buffers"); if (!gst_video_frame_map (&out_frame, &vagg->info, outbuf, GST_MAP_WRITE | GST_MAP_GL)) { return FALSE; } if (gst_is_gl_memory (out_frame.map[0].memory)) { out_tex = *(guint *) out_frame.data[0]; } else { GST_INFO ("Output Buffer does not contain correct memory, " "attempting to wrap for download"); out_tex = mix->out_tex_id;; if (!mix->download) mix->download = gst_gl_download_new (mix->context); gst_gl_download_set_format (mix->download, &out_frame.info); out_gl_wrapped = TRUE; } GST_OBJECT_LOCK (mix); walk = element->sinkpads; i = mix->frames->len; g_ptr_array_set_size (mix->frames, element->numsinkpads); for (; i < element->numsinkpads; i++) mix->frames->pdata[i] = g_slice_new0 (GstGLMixerFrameData); while (walk) { GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data); GstVideoAggregatorPad *vaggpad = walk->data; GstGLMixerFrameData *frame; frame = g_ptr_array_index (mix->frames, array_index); frame->pad = pad; frame->texture = 0; walk = g_list_next (walk); if (vaggpad->buffer != NULL) { guint in_tex; if (!pad->upload) { pad->upload = gst_gl_upload_new (mix->context); gst_gl_upload_set_format (pad->upload, &vaggpad->info); } if (!gst_gl_upload_perform_with_buffer (pad->upload, vaggpad->buffer, &in_tex)) { ++array_index; pad->mapped = FALSE; continue; } pad->mapped = TRUE; frame->texture = in_tex; } ++array_index; } g_mutex_lock (&priv->gl_resource_lock); if (!priv->gl_resource_ready) g_cond_wait (&priv->gl_resource_cond, &priv->gl_resource_lock); if (!priv->gl_resource_ready) { g_mutex_unlock (&priv->gl_resource_lock); GST_ERROR_OBJECT (mix, "fbo used to render can't be created, do not run process_textures"); res = FALSE; goto out; } mix_class->process_textures (mix, mix->frames, out_tex); g_mutex_unlock (&priv->gl_resource_lock); if (out_gl_wrapped) { if (!gst_gl_download_perform_with_data (mix->download, out_tex, out_frame.data)) { GST_ELEMENT_ERROR (mix, RESOURCE, NOT_FOUND, ("%s", "Failed to download video frame"), (NULL)); res = FALSE; goto out; } } out: i = 0; walk = GST_ELEMENT (mix)->sinkpads; while (walk) { GstGLMixerPad *pad = GST_GL_MIXER_PAD (walk->data); if (pad->mapped) gst_gl_upload_release_buffer (pad->upload); pad->mapped = FALSE; walk = g_list_next (walk); i++; } GST_OBJECT_UNLOCK (mix); gst_video_frame_unmap (&out_frame); return res; }
static int run_test (const char *format, ...) { GstStateChangeReturn ret; GstElement *pipe, *src, *sink; GstBuffer *buf = NULL; GstMessage *msg; gchar *url; va_list args; int rc = -1; pipe = gst_pipeline_new (NULL); src = gst_element_factory_make ("souphttpsrc", NULL); fail_unless (src != NULL); sink = gst_element_factory_make ("fakesink", NULL); fail_unless (sink != NULL); gst_bin_add (GST_BIN (pipe), src); gst_bin_add (GST_BIN (pipe), sink); fail_unless (gst_element_link (src, sink)); if (http_port == 0) { GST_DEBUG ("failed to start soup http server"); } fail_unless (http_port != 0); va_start (args, format); g_vasprintf (&url, format, args); va_end (args); fail_unless (url != NULL); g_object_set (src, "location", url, NULL); g_free (url); g_object_set (src, "automatic-redirect", redirect, NULL); if (cookies != NULL) g_object_set (src, "cookies", cookies, NULL); g_object_set (sink, "signal-handoffs", TRUE, NULL); g_signal_connect (sink, "preroll-handoff", G_CALLBACK (handoff_cb), &buf); if (user_id != NULL) g_object_set (src, "user-id", user_id, NULL); if (user_pw != NULL) g_object_set (src, "user-pw", user_pw, NULL); ret = gst_element_set_state (pipe, GST_STATE_PAUSED); if (ret != GST_STATE_CHANGE_ASYNC) { GST_DEBUG ("failed to start up soup http src, ret = %d", ret); goto done; } gst_element_set_state (pipe, GST_STATE_PLAYING); msg = gst_bus_poll (GST_ELEMENT_BUS (pipe), GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1); if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) { gchar *debug = NULL; GError *err = NULL; gst_message_parse_error (msg, &err, &debug); GST_INFO ("error: %s", err->message); if (g_str_has_suffix (err->message, "Not Found")) rc = 404; else if (g_str_has_suffix (err->message, "Forbidden")) rc = 403; else if (g_str_has_suffix (err->message, "Unauthorized")) rc = 401; else if (g_str_has_suffix (err->message, "Found")) rc = 302; GST_INFO ("debug: %s", debug); g_error_free (err); g_free (debug); gst_message_unref (msg); goto done; } gst_message_unref (msg); /* don't wait for more than 10 seconds */ ret = gst_element_get_state (pipe, NULL, NULL, 10 * GST_SECOND); GST_LOG ("ret = %u", ret); if (buf == NULL) { /* we want to test the buffer offset, nothing else; if there's a failure * it might be for lots of reasons (no network connection, whatever), we're * not interested in those */ GST_DEBUG ("didn't manage to get data within 10 seconds, skipping test"); goto done; } GST_DEBUG ("buffer offset = %" G_GUINT64_FORMAT, GST_BUFFER_OFFSET (buf)); /* first buffer should have a 0 offset */ fail_unless (GST_BUFFER_OFFSET (buf) == 0); gst_buffer_unref (buf); rc = 0; done: gst_element_set_state (pipe, GST_STATE_NULL); gst_object_unref (pipe); return rc; }
static void gst_dasf_change_peer_omx_state (GstDasfSrc* self) { GST_INFO (""); GstPad *peer; GstElement *next_element; GooComponent *component; GstBaseSrc *base_src; peer = gst_pad_get_peer (GST_BASE_SRC_PAD (self)); if (G_UNLIKELY (peer == NULL)) { GST_INFO ("No next pad"); return; } next_element = GST_ELEMENT (gst_pad_get_parent (peer)); if (G_UNLIKELY (next_element == NULL)) { GST_INFO ("Cannot find a next element"); gst_object_unref (next_element); return; } /** expecting a capsfilter between dasfsrc and goo audio component **/ while (GST_IS_BASE_TRANSFORM (next_element)) { GST_DEBUG_OBJECT(self, "next element name: %s", gst_element_get_name (next_element)); gst_object_unref (peer); peer = gst_pad_get_peer (GST_BASE_TRANSFORM_SRC_PAD (next_element)); gst_object_unref (next_element); next_element = GST_ELEMENT(gst_pad_get_parent (peer)) ; GST_DEBUG_OBJECT (self, "one after element name: %s", gst_element_get_name(next_element)); } /** capsfilter might be found * element next to the caps filter should be goo **/ component = GOO_COMPONENT (g_object_get_data (G_OBJECT (next_element), "goo")); if (G_UNLIKELY (component == NULL)) { GST_INFO ("Previous element does not have a Goo component"); gst_object_unref (peer); gst_object_unref (next_element); return; } if (!GOO_IS_TI_AUDIO_COMPONENT (component)) { GST_WARNING ("The component in previous element is not TI Audio"); gst_object_unref (peer); gst_object_unref (next_element); return; } self->peer_element = g_object_ref (GST_GOO_AUDIO_FILTER (next_element)); /* Work with a queue on the output buffers */ g_object_set (GST_GOO_AUDIO_FILTER (next_element)->component, "outport-queue", TRUE, NULL); /** This fixates the caps on the next goo element to configure the output omx port **/ gst_goo_audio_filter_check_fixed_src_caps (GST_GOO_AUDIO_FILTER (next_element)); g_object_set (GST_GOO_AUDIO_FILTER (next_element)->inport, "buffercount", 1, NULL); g_object_set (GST_GOO_AUDIO_FILTER (next_element)->outport, "buffercount", 1, NULL); GST_INFO ("Setting peer omx component to idle"); goo_component_set_state_idle (GST_GOO_AUDIO_FILTER (next_element)->component); GST_INFO ("Setting peer omx component to executing"); goo_component_set_state_executing (GST_GOO_AUDIO_FILTER (next_element)->component); gst_object_unref (peer); gst_object_unref (next_element); GST_DEBUG_OBJECT (self, "peer refcount = %d", G_OBJECT (peer)->ref_count); GST_DEBUG_OBJECT (self, "next element refcount = %d", G_OBJECT (next_element)->ref_count); return; }
/* Initialize the tracing system */ void _priv_gst_tracing_init (void) { const gchar *env = g_getenv ("GST_TRACER_PLUGINS"); if (env != NULL && *env != '\0') { GstRegistry *registry = gst_registry_get (); GstPluginFeature *feature; GstTracerFactory *factory; gchar **t = g_strsplit_set (env, ";", 0); gint i = 0; gchar *params; GST_INFO ("enabling tracers: '%s'", env); if (G_N_ELEMENTS (_quark_strings) != GST_TRACER_QUARK_MAX) g_warning ("the quark table is not consistent! %d != %d", (gint) G_N_ELEMENTS (_quark_strings), GST_TRACER_QUARK_MAX); for (i = 0; i < GST_TRACER_QUARK_MAX; i++) { _priv_gst_tracer_quark_table[i] = g_quark_from_static_string (_quark_strings[i]); } _priv_tracers = g_hash_table_new (NULL, NULL); i = 0; while (t[i]) { // check t[i] for params if ((params = strchr (t[i], '('))) { gchar *end = strchr (¶ms[1], ')'); *params = '\0'; params++; if (end) *end = '\0'; } else { params = NULL; } GST_INFO ("checking tracer: '%s'", t[i]); if ((feature = gst_registry_lookup_feature (registry, t[i]))) { factory = GST_TRACER_FACTORY (gst_plugin_feature_load (feature)); if (factory) { GST_INFO_OBJECT (factory, "creating tracer: type-id=%u", (guint) factory->type); /* tracers register them self to the hooks */ gst_object_unref (g_object_new (factory->type, "params", params, NULL)); } else { GST_WARNING_OBJECT (feature, "loading plugin containing feature %s failed!", t[i]); } } else { GST_WARNING ("no tracer named '%s'", t[i]); } i++; } g_strfreev (t); } }
static GstFlowReturn gst_glimage_sink_render (GstBaseSink * bsink, GstBuffer * buf) { GstGLImageSink *glimage_sink = NULL; GstGLBuffer *gl_buffer = NULL; glimage_sink = GST_GLIMAGE_SINK (bsink); GST_INFO ("buffer size: %d", GST_BUFFER_SIZE (buf)); //is gl if (glimage_sink->is_gl) { //increment gl buffer ref before storage gl_buffer = GST_GL_BUFFER (gst_buffer_ref (buf)); //if glimagesink has not the display yet if (glimage_sink->display == NULL) { glimage_sink->display = g_object_ref (gl_buffer->display); gst_gl_display_set_client_reshape_callback (glimage_sink->display, glimage_sink->clientReshapeCallback); gst_gl_display_set_client_draw_callback (glimage_sink->display, glimage_sink->clientDrawCallback); } } //is not gl else { //if glimagesink has not the display yet if (glimage_sink->display == NULL) { //create a display glimage_sink->display = gst_gl_display_new (); //init opengl context gst_gl_display_create_context (glimage_sink->display, glimage_sink->width, glimage_sink->height, 0); //init colorspace conversion if needed gst_gl_display_init_upload (glimage_sink->display, glimage_sink->format, glimage_sink->width, glimage_sink->height, glimage_sink->width, glimage_sink->height); gst_gl_display_set_client_reshape_callback (glimage_sink->display, glimage_sink->clientReshapeCallback); gst_gl_display_set_client_draw_callback (glimage_sink->display, glimage_sink->clientDrawCallback); } //blocking call gl_buffer = gst_gl_buffer_new (glimage_sink->display, glimage_sink->width, glimage_sink->height); //blocking call gst_gl_display_do_upload (glimage_sink->display, gl_buffer->texture, glimage_sink->width, glimage_sink->height, GST_BUFFER_DATA (buf)); //gl_buffer is created in this block, so the gl buffer is already referenced } if (glimage_sink->window_id != glimage_sink->new_window_id) { glimage_sink->window_id = glimage_sink->new_window_id; gst_gl_display_set_window_id (glimage_sink->display, glimage_sink->window_id); } //the buffer is cleared when an other comes in if (glimage_sink->stored_buffer) { gst_buffer_unref (GST_BUFFER_CAST (glimage_sink->stored_buffer)); glimage_sink->stored_buffer = NULL; } //store current buffer glimage_sink->stored_buffer = gl_buffer; //redisplay opengl scene if (gl_buffer->texture && gst_gl_display_redisplay (glimage_sink->display, gl_buffer->texture, gl_buffer->width, gl_buffer->height, glimage_sink->keep_aspect_ratio)) return GST_FLOW_OK; else return GST_FLOW_UNEXPECTED; }
/* make a connection with @id and @server. Returns NULL on failure with the * status set. */ static GstJackAudioConnection * gst_jack_audio_make_connection (const gchar * id, const gchar * server, jack_client_t * jclient, jack_status_t * status) { GstJackAudioConnection *conn; jack_options_t options; gint res; *status = 0; GST_DEBUG ("new client %s, connecting to server %s", id, GST_STR_NULL (server)); /* never start a server */ options = JackNoStartServer; /* if we have a servername, use it */ if (server != NULL) options |= JackServerName; /* open the client */ if (jclient == NULL) jclient = jack_client_open (id, options, status, server); if (jclient == NULL) goto could_not_open; /* now create object */ conn = g_new (GstJackAudioConnection, 1); conn->refcount = 1; conn->lock = g_mutex_new (); conn->flush_cond = g_cond_new (); conn->id = g_strdup (id); conn->server = g_strdup (server); conn->client = jclient; conn->n_clients = 0; conn->src_clients = NULL; conn->sink_clients = NULL; conn->cur_ts = -1; conn->transport_state = GST_STATE_VOID_PENDING; /* set our callbacks */ jack_set_process_callback (jclient, jack_process_cb, conn); /* these callbacks cause us to error */ jack_set_buffer_size_callback (jclient, jack_buffer_size_cb, conn); jack_set_sample_rate_callback (jclient, jack_sample_rate_cb, conn); jack_on_shutdown (jclient, jack_shutdown_cb, conn); /* all callbacks are set, activate the client */ GST_INFO ("activate jack_client %p", jclient); if ((res = jack_activate (jclient))) goto could_not_activate; GST_DEBUG ("opened connection %p", conn); return conn; /* ERRORS */ could_not_open: { GST_DEBUG ("failed to open jack client, %d", *status); return NULL; } could_not_activate: { GST_ERROR ("Could not activate client (%d)", res); *status = JackFailure; g_mutex_free (conn->lock); g_free (conn->id); g_free (conn->server); g_free (conn); return NULL; } }
static gboolean gst_gl_context_egl_choose_config (GstGLContextEGL * egl, GstGLAPI gl_api, gint major, GError ** error) { gboolean create_context; EGLint numConfigs; gint i = 0; EGLint config_attrib[20]; create_context = gst_gl_check_extension ("EGL_KHR_create_context", egl->egl_exts); /* silence unused warnings */ (void) create_context; config_attrib[i++] = EGL_SURFACE_TYPE; config_attrib[i++] = EGL_WINDOW_BIT; config_attrib[i++] = EGL_RENDERABLE_TYPE; if (gl_api & GST_GL_API_GLES2) { if (major == 3) { #if defined(EGL_KHR_create_context) if (create_context) { config_attrib[i++] = EGL_OPENGL_ES3_BIT_KHR; } else #endif { return FALSE; } } else { config_attrib[i++] = EGL_OPENGL_ES2_BIT; } } else config_attrib[i++] = EGL_OPENGL_BIT; #if defined(USE_EGL_RPI) && GST_GL_HAVE_WINDOW_WAYLAND /* The configurations with a=0 seems to be buggy whereas * it works when using dispmanx directly */ config_attrib[i++] = EGL_ALPHA_SIZE; config_attrib[i++] = 1; #endif config_attrib[i++] = EGL_DEPTH_SIZE; config_attrib[i++] = 16; config_attrib[i++] = EGL_RED_SIZE; config_attrib[i++] = 1; config_attrib[i++] = EGL_GREEN_SIZE; config_attrib[i++] = 1; config_attrib[i++] = EGL_BLUE_SIZE; config_attrib[i++] = 1; config_attrib[i++] = EGL_NONE; if (eglChooseConfig (egl->egl_display, config_attrib, &egl->egl_config, 1, &numConfigs)) { GST_INFO ("config set: %" G_GUINTPTR_FORMAT ", %u", (guintptr) egl->egl_config, (unsigned int) numConfigs); } else { g_set_error (error, GST_GL_CONTEXT_ERROR, GST_GL_CONTEXT_ERROR_WRONG_CONFIG, "Failed to set window configuration: %s", gst_gl_context_egl_get_error_string (eglGetError ())); goto failure; } return TRUE; failure: return FALSE; }
static GstBuffer * read_device (int fd, int adapter_number, int frontend_number, int size, GstDvbSrc * object) { int count = 0; struct pollfd pfd[1]; int ret_val = 0; guint attempts = 0; const int TIMEOUT = 100; GstBuffer *buf = gst_buffer_new_and_alloc (size); g_return_val_if_fail (GST_IS_BUFFER (buf), NULL); if (fd < 0) { return NULL; } pfd[0].fd = fd; pfd[0].events = POLLIN; while (count < size && !object->need_unlock) { ret_val = poll (pfd, 1, TIMEOUT); if (ret_val > 0) { if (pfd[0].revents & POLLIN) { int tmp = 0; tmp = read (fd, GST_BUFFER_DATA (buf) + count, size - count); if (tmp < 0) { GST_WARNING ("Unable to read from device: /dev/dvb/adapter%d/dvr%d (%d)", adapter_number, frontend_number, errno); attempts += 1; if (attempts % 10 == 0) { GST_WARNING ("Unable to read from device after %u attempts: /dev/dvb/adapter%d/dvr%d", attempts, adapter_number, frontend_number); } } else count = count + tmp; } else { GST_LOG ("revents = %d\n", pfd[0].revents); } } else if (ret_val == 0) { // poll timeout attempts += 1; GST_INFO ("Reading from device /dev/dvb/adapter%d/dvr%d timedout (%d)", adapter_number, frontend_number, attempts); if (attempts % 10 == 0) { GST_WARNING ("Unable to read after %u attempts from device: /dev/dvb/adapter%d/dvr%d (%d)", attempts, adapter_number, frontend_number, errno); gst_element_post_message (GST_ELEMENT_CAST (object), gst_message_new_element (GST_OBJECT (object), gst_structure_empty_new ("dvb-read-failure"))); } } else if (errno == -EINTR) { // poll interrupted if (attempts % 50 == 0) { gst_buffer_unref (buf); return NULL; }; } } if (!count) { gst_buffer_unref (buf); return NULL; } GST_BUFFER_SIZE (buf) = count; GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE; return buf; }