Ejemplo n.º 1
0
/**
 * 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;
  }
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
/**
 * 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;
}
Ejemplo n.º 7
0
/**
 * 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;
}
Ejemplo n.º 8
0
/* 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);
}
Ejemplo n.º 9
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);
}
Ejemplo n.º 10
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;
  }
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
/* 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);
}
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
0
/* 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);
}
Ejemplo n.º 19
0
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;
}
Ejemplo n.º 20
0
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;
}
Ejemplo n.º 21
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;
  }
}
Ejemplo n.º 22
0
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;
}
Ejemplo n.º 23
0
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;
}
Ejemplo n.º 24
0
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;
}
Ejemplo n.º 25
0
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;

}
Ejemplo n.º 26
0
/* 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 (&params[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);
  }
}
Ejemplo n.º 27
0
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;
}
Ejemplo n.º 28
0
/* 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;
  }
}
Ejemplo n.º 29
0
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;
}
Ejemplo n.º 30
0
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;
}