void test_flags() { GstElement *element; GError *err = NULL; xmlfile = "test_flags"; std_log(LOG_FILENAME_LINE, "Test Started test_flags"); /* avoid misleading 'no such element' error debug messages when using cvs */ if (!g_getenv ("GST_DEBUG")) gst_debug_set_default_threshold (GST_LEVEL_NONE); /* default behaviour is to return any already constructed bins/elements */ element = gst_parse_launch_full ("fakesrc ! coffeesink", NULL, 0, &err); fail_unless (err != NULL, "expected error"); fail_unless_equals_int (err->code, GST_PARSE_ERROR_NO_SUCH_ELEMENT); fail_unless (element != NULL, "expected partial pipeline/element"); g_error_free (err); err = NULL; gst_object_unref (element); /* test GST_PARSE_FLAG_FATAL_ERRORS */ element = gst_parse_launch_full ("fakesrc ! coffeesink", NULL, GST_PARSE_FLAG_FATAL_ERRORS, &err); fail_unless (err != NULL, "expected error"); fail_unless_equals_int (err->code, GST_PARSE_ERROR_NO_SUCH_ELEMENT); fail_unless (element == NULL, "expected NULL return with FATAL_ERRORS"); g_error_free (err); err = NULL; std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
static gboolean create_pipeline(SpiceGstDecoder *decoder) { gchar *desc; gboolean auto_enabled; guint opt; GstAppSinkCallbacks appsink_cbs = { NULL }; GError *err = NULL; GstBus *bus; auto_enabled = (g_getenv("SPICE_GSTVIDEO_AUTO") != NULL); if (auto_enabled || !VALID_VIDEO_CODEC_TYPE(decoder->base.codec_type)) { SPICE_DEBUG("Trying %s for codec type %d %s", gst_opts[0].dec_name, decoder->base.codec_type, (auto_enabled) ? "(SPICE_GSTVIDEO_AUTO is set)" : ""); opt = 0; } else { opt = decoder->base.codec_type; } /* - We schedule the frame display ourselves so set sync=false on appsink * so the pipeline decodes them as fast as possible. This will also * minimize the risk of frames getting lost when we rebuild the * pipeline. * - Set max-bytes=0 on appsrc so it does not drop frames that may be * needed by those that follow. */ desc = g_strdup_printf("appsrc name=src is-live=true format=time max-bytes=0 block=true " "%s ! %s ! videoconvert ! appsink name=sink " "caps=video/x-raw,format=BGRx sync=false drop=false", gst_opts[opt].dec_caps, gst_opts[opt].dec_name); SPICE_DEBUG("GStreamer pipeline: %s", desc); decoder->pipeline = gst_parse_launch_full(desc, NULL, GST_PARSE_FLAG_FATAL_ERRORS, &err); g_free(desc); if (!decoder->pipeline) { spice_warning("GStreamer error: %s", err->message); g_clear_error(&err); return FALSE; } decoder->appsrc = GST_APP_SRC(gst_bin_get_by_name(GST_BIN(decoder->pipeline), "src")); decoder->appsink = GST_APP_SINK(gst_bin_get_by_name(GST_BIN(decoder->pipeline), "sink")); appsink_cbs.new_sample = new_sample; gst_app_sink_set_callbacks(decoder->appsink, &appsink_cbs, decoder, NULL); bus = gst_pipeline_get_bus(GST_PIPELINE(decoder->pipeline)); gst_bus_add_watch(bus, handle_pipeline_message, decoder); gst_object_unref(bus); decoder->clock = gst_pipeline_get_clock(GST_PIPELINE(decoder->pipeline)); if (gst_element_set_state(decoder->pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { SPICE_DEBUG("GStreamer error: Unable to set the pipeline to the playing state."); free_pipeline(decoder); return FALSE; } return TRUE; }
static gboolean recorder_open_pipeline (ShellRecorder *recorder) { RecorderPipeline *pipeline; const char *pipeline_description; char *parsed_pipeline; GError *error = NULL; GstBus *bus; pipeline = g_new0 (RecorderPipeline, 1); pipeline->recorder = g_object_ref (recorder); pipeline->outfile = - 1; pipeline_description = recorder->pipeline_description; if (!pipeline_description) pipeline_description = DEFAULT_PIPELINE; parsed_pipeline = substitute_thread_count (pipeline_description); pipeline->pipeline = gst_parse_launch_full (parsed_pipeline, NULL, GST_PARSE_FLAG_FATAL_ERRORS, &error); g_free (parsed_pipeline); if (pipeline->pipeline == NULL) { g_warning ("ShellRecorder: failed to parse pipeline: %s", error->message); g_error_free (error); goto error; } if (!recorder_pipeline_add_source (pipeline)) goto error; if (!recorder_pipeline_add_sink (pipeline)) goto error; gst_element_set_state (pipeline->pipeline, GST_STATE_PLAYING); bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline->pipeline)); gst_bus_add_watch (bus, recorder_pipeline_bus_watch, pipeline); gst_object_unref (bus); g_signal_connect (pipeline->src, "notify::memory-used", G_CALLBACK (recorder_pipeline_on_memory_used_changed), pipeline); recorder->current_pipeline = pipeline; recorder->pipelines = g_slist_prepend (recorder->pipelines, pipeline); return TRUE; error: recorder_pipeline_free (pipeline); return FALSE; }
GstElement *create_audio_sink() { GstElement *bin, *decoder = NULL; GstIterator *iter; GstIteratorResult res; GError *error = NULL; GstPad *pad; gpointer element = NULL; bin = gst_parse_launch_full("decodebin ! queue ! audioconvert \ ! audioresample \ ! autoaudiosink", NULL, 0, &error); if (!bin) { g_error("GStreamer: failed to parse audio sink pipeline\n"); return NULL; } gst_object_set_name(GST_OBJECT(bin), "audio-sink"); iter = gst_bin_iterate_elements(GST_BIN(bin)); res = gst_iterator_next (iter, &element); while (res == GST_ITERATOR_OK) { gchar *name; name = gst_object_get_name(GST_OBJECT (element)); if (name) { if (!strncmp(name, "decodebin", strlen("decodebin"))) { decoder = GST_ELEMENT(element); } g_printf("GS: audio sink element: %s \n", name); g_free (name); } gst_object_unref (element); element = NULL; res = gst_iterator_next (iter, &element); } gst_iterator_free (iter); if (!decoder) { /* mem leak */ g_printf("decoder element not found\n"); return NULL; } /* add ghostpad */ pad = gst_element_get_static_pad(decoder, "sink"); gst_element_add_pad(bin, gst_ghost_pad_new("sink", pad)); gst_object_unref(GST_OBJECT(pad)); return bin; }
/** * gst_parse_launchv_full: * @argv: (in) (array zero-terminated=1): null-terminated array of arguments * @context: (allow-none): a parse context allocated with * [gst_parse_context_new](), or [NULL]() * @flags: parsing options, or [GST_PARSE_FLAG_NONE]() * @error: pointer to a [GError]() (which must be initialised to [NULL]()) * * Create a new element based on command line syntax. * _error_ will contain an error message if an erroneous pipeline is specified. * An error does not mean that the pipeline could not be constructed. * * Returns: (transfer floating): a new element on success; on failure, either [NULL]() * or a partially-constructed bin or element will be returned and _error_ will * be set (unless you passed [GST_PARSE_FLAG_FATAL_ERRORS]() in _flags_, then * [NULL]() will always be returned on failure) */ GstElement * gst_parse_launchv_full (const gchar ** argv, GstParseContext * context, GstParseFlags flags, GError ** error) { #ifndef GST_DISABLE_PARSE GstElement *element; GString *str; const gchar **argvp, *arg; gchar *tmp; g_return_val_if_fail (argv != NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); /* let's give it a nice size. */ str = g_string_sized_new (1024); argvp = argv; while (*argvp) { arg = *argvp; GST_DEBUG ("escaping argument %s", arg); tmp = _gst_parse_escape (arg); g_string_append (str, tmp); g_free (tmp); g_string_append_c (str, ' '); argvp++; } element = gst_parse_launch_full (str->str, context, flags, error); g_string_free (str, TRUE); return element; #else /* gst_parse_launch_full() will set a GST_CORE_ERROR_DISABLED error for us */ return gst_parse_launch_full ("", NULL, 0, error); #endif }
static GstElement * make_pipeline (gint type) { GstElement *result; gchar *pstr; switch (type) { case 0: pstr = g_strdup_printf ("videotestsrc ! videocrop name=crop ! " "xvimagesink"); break; default: return NULL; } result = gst_parse_launch_full (pstr, NULL, GST_PARSE_FLAG_NONE, NULL); g_print ("created test %d: \"%s\"\n", type, pstr); g_free (pstr); return result; }
/** * gst_parse_launch: * @pipeline_description: the command line describing the pipeline * @error: the error message in case of an erroneous pipeline. * * Create a new pipeline based on command line syntax. * Please note that you might get a return value that is not [NULL]() even though * the _error_ is set. In this case there was a recoverable parsing error and you * can try to play the pipeline. * * Returns: (transfer floating): a new element on success, [NULL]() on failure. If * more than one toplevel element is specified by the _pipeline_description_, * all elements are put into a [GstPipeline](), which than is returned. */ GstElement * gst_parse_launch (const gchar * pipeline_description, GError ** error) { return gst_parse_launch_full (pipeline_description, NULL, GST_PARSE_FLAG_NONE, error); }
void test_missing_elements() { GstParseContext *ctx; GstElement *element; GError *err = NULL; gchar **arr; xmlfile = "test_missing_elements"; std_log(LOG_FILENAME_LINE, "Test Started test_missing_elements"); /* avoid misleading 'no such element' error debug messages when using cvs */ if (!g_getenv ("GST_DEBUG")) gst_debug_set_default_threshold (GST_LEVEL_NONE); /* one missing element */ ctx = gst_parse_context_new (); element = gst_parse_launch_full ("fakesrc ! coffeesink", ctx, GST_PARSE_FLAG_FATAL_ERRORS, &err); fail_unless (err != NULL, "expected error"); fail_unless_equals_int (err->code, GST_PARSE_ERROR_NO_SUCH_ELEMENT); fail_unless (element == NULL, "expected NULL return with FATAL_ERRORS"); arr = gst_parse_context_get_missing_elements (ctx); fail_unless (arr != NULL, "expected missing elements"); fail_unless_equals_string (arr[0], "coffeesink"); fail_unless (arr[1] == NULL); g_strfreev (arr); gst_parse_context_free (ctx); g_error_free (err); err = NULL; /* multiple missing elements */ ctx = gst_parse_context_new (); element = gst_parse_launch_full ("fakesrc ! bogusenc ! identity ! goomux ! " "fakesink", ctx, GST_PARSE_FLAG_FATAL_ERRORS, &err); fail_unless (err != NULL, "expected error"); fail_unless_equals_int (err->code, GST_PARSE_ERROR_NO_SUCH_ELEMENT); fail_unless (element == NULL, "expected NULL return with FATAL_ERRORS"); arr = gst_parse_context_get_missing_elements (ctx); fail_unless (arr != NULL, "expected missing elements"); fail_unless_equals_string (arr[0], "bogusenc"); fail_unless_equals_string (arr[1], "goomux"); fail_unless (arr[2] == NULL); g_strfreev (arr); gst_parse_context_free (ctx); g_error_free (err); err = NULL; /* multiple missing elements, different link pattern */ ctx = gst_parse_context_new (); element = gst_parse_launch_full ("fakesrc ! bogusenc ! mux.sink " "blahsrc ! goomux name=mux ! fakesink fakesrc ! goosink", ctx, GST_PARSE_FLAG_FATAL_ERRORS, &err); fail_unless (err != NULL, "expected error"); fail_unless_equals_int (err->code, GST_PARSE_ERROR_NO_SUCH_ELEMENT); fail_unless (element == NULL, "expected NULL return with FATAL_ERRORS"); arr = gst_parse_context_get_missing_elements (ctx); fail_unless (arr != NULL, "expected missing elements"); fail_unless_equals_string (arr[0], "bogusenc"); fail_unless_equals_string (arr[1], "blahsrc"); fail_unless_equals_string (arr[2], "goomux"); fail_unless_equals_string (arr[3], "goosink"); fail_unless (arr[4] == NULL); g_strfreev (arr); gst_parse_context_free (ctx); g_error_free (err); err = NULL; std_log(LOG_FILENAME_LINE, "Test Successful"); create_xml(0); }
/** * gst_parse_launch: * @pipeline_description: the command line describing the pipeline * @error: the error message in case of an erroneous pipeline. * * Create a new pipeline based on command line syntax. * Please note that you might get a return value that is not %NULL even though * the @error is set. In this case there was a recoverable parsing error and you * can try to play the pipeline. * * Returns: (transfer full): a new element on success, %NULL on failure. If * more than one toplevel element is specified by the @pipeline_description, * all elements are put into a #GstPipeline, which than is returned. */ GstElement * gst_parse_launch (const gchar * pipeline_description, GError ** error) { return gst_parse_launch_full (pipeline_description, NULL, 0, error); }
GstElement *create_video_sink() { GstElement *bin, *decoder = NULL; GstIterator *iter; GstIteratorResult res; GError *error = NULL; GstPad *pad; gpointer element = NULL; const char* decoder_name; #ifndef DESKTOP /* create pipeline */ decoder_name = "tividdec20"; bin = gst_parse_launch_full("TIViddec2 genTimeStamps=FALSE \ engineName=decode \ codecName=h264dec numFrames=-1 \ ! videoscale method=0 \ ! video/x-raw-yuv, format=(fourcc)I420, width=320, height=240 \ ! ffmpegcolorspace \ ! video/x-raw-rgb, bpp=16 \ ! TIDmaiVideoSink displayStd=fbdev displayDevice=/dev/fb0 videoStd=QVGA \ videoOutput=LCD resizer=FALSE accelFrameCopy=TRUE", NULL, 0, &error); #else decoder_name = "decodebin"; bin = gst_parse_launch_full("decodebin \ ! videoscale method=0 \ ! video/x-raw-yuv, format=(fourcc)I420, width=320, height=240 \ ! xvimagesink", NULL, 0, &error); #endif if (!bin) { g_error("GStreamer: failed to parse video sink pipeline\n"); return NULL; } gst_object_set_name(GST_OBJECT(bin), "video-sink"); iter = gst_bin_iterate_elements(GST_BIN(bin)); res = gst_iterator_next (iter, &element); while (res == GST_ITERATOR_OK) { gchar *name; name = gst_object_get_name(GST_OBJECT (element)); if (name) { if (!strncmp(name, decoder_name, strlen(decoder_name))) { decoder = GST_ELEMENT(element); } g_printf("GS: video sink element: %s \n", name); g_free (name); } gst_object_unref (element); element = NULL; res = gst_iterator_next (iter, &element); } gst_iterator_free (iter); if (!decoder) { /* mem leak */ g_printf("decoder element not found\n"); return NULL; } /* add ghostpad */ pad = gst_element_get_static_pad (decoder, "sink"); gst_element_add_pad(bin, gst_ghost_pad_new("sink", pad)); gst_object_unref(GST_OBJECT(pad)); return bin; }