static gboolean gst_uri_downloader_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) { gboolean ret = FALSE; GstUriDownloader *downloader; downloader = GST_URI_DOWNLOADER (gst_pad_get_element_private (pad)); switch (event->type) { case GST_EVENT_EOS:{ GST_OBJECT_LOCK (downloader); GST_DEBUG_OBJECT (downloader, "Got EOS on the fetcher pad"); if (downloader->priv->download != NULL) { /* signal we have fetched the URI */ downloader->priv->download->completed = TRUE; downloader->priv->download->download_stop_time = gst_util_get_timestamp (); GST_OBJECT_UNLOCK (downloader); GST_DEBUG_OBJECT (downloader, "Signaling chain funtion"); g_cond_signal (&downloader->priv->cond); } else { GST_OBJECT_UNLOCK (downloader); } gst_event_unref (event); break; } default: ret = gst_pad_event_default (pad, parent, event); break; } return ret; }
/* * gst_debug_bin_to_dot_file_with_ts: * @bin: the top-level pipeline that should be analyzed * @file_name: output base filename (e.g. "myplayer") * * This works like gst_debug_bin_to_dot_file(), but adds the current timestamp * to the filename, so that it can be used to take multiple snapshots. */ void gst_debug_bin_to_dot_file_with_ts (GstBin * bin, GstDebugGraphDetails details, const gchar * file_name) { gchar *ts_file_name = NULL; GstClockTime elapsed; g_return_if_fail (GST_IS_BIN (bin)); if (!file_name) { file_name = g_get_application_name (); if (!file_name) file_name = "unnamed"; } /* add timestamp */ elapsed = GST_CLOCK_DIFF (_priv_gst_info_start_time, gst_util_get_timestamp ()); /* we don't use GST_TIME_FORMAT as such filenames would fail on some * filesystems like fat */ ts_file_name = g_strdup_printf ("%u.%02u.%02u.%09u-%s", GST_TIME_ARGS (elapsed), file_name); gst_debug_bin_to_dot_file (bin, details, ts_file_name); g_free (ts_file_name); }
static GstPadProbeReturn on_video_sink_data_flow (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) { GstMiniObject *mini_obj = GST_PAD_PROBE_INFO_DATA (info); GstFPSDisplaySink *self = GST_FPS_DISPLAY_SINK (user_data); if (GST_IS_BUFFER (mini_obj)) { GstClockTime ts; /* assume the frame is going to be rendered. If it isnt', we'll get a qos * message and reset ->frames_rendered from there. */ g_atomic_int_inc (&self->frames_rendered); ts = gst_util_get_timestamp (); if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (self->start_ts))) { self->interval_ts = self->last_ts = self->start_ts = ts; } if (GST_CLOCK_DIFF (self->interval_ts, ts) > self->fps_update_interval) { display_current_fps (self); self->interval_ts = ts; } } return GST_PAD_PROBE_OK; }
EXPORT_C #endif void _gst_debug_bin_to_dot_file_with_ts (GstBin * bin, GstDebugGraphDetails details, const gchar * file_name) { gchar *ts_file_name = NULL; GstClockTime elapsed; g_return_if_fail (GST_IS_BIN (bin)); if (!file_name) { file_name = g_get_application_name (); if (!file_name) file_name = "unnamed"; } /* add timestamp */ elapsed = GST_CLOCK_DIFF (_priv_gst_info_start_time, gst_util_get_timestamp ()); ts_file_name = g_strdup_printf ("%" GST_TIME_FORMAT "-%s", GST_TIME_ARGS (elapsed), file_name); _gst_debug_bin_to_dot_file (bin, details, ts_file_name); g_free (ts_file_name); }
/* Perform seek, if we are not too close to the previous seek. Otherwise, schedule the seek for * some time in the future. */ void execute_seek(gint64 desired_position, CustomData *data) { gint64 diff; if (desired_position == GST_CLOCK_TIME_NONE || !data->allow_seek) return; diff = gst_util_get_timestamp() - data->last_seek_time; if (!data->is_live) { GPlayerDEBUG("Seeking to %" GST_TIME_FORMAT, GST_TIME_ARGS(desired_position)); data->last_seek_time = gst_util_get_timestamp(); gst_element_seek_simple(data->pipeline, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT, desired_position); data->desired_position = GST_CLOCK_TIME_NONE; } }
static void check_log_handler (const gchar * const log_domain, const GLogLevelFlags log_level, const gchar * const message, gpointer const user_data) { gchar *msg, *level; GstClockTime elapsed; //-- check message contents if (__check_method && (strstr (message, __check_method) != NULL) && __check_test && (strstr (message, __check_test) != NULL)) __check_error_trapped = TRUE; else if (__check_method && (strstr (message, __check_method) != NULL) && !__check_test) __check_error_trapped = TRUE; else if (__check_test && (strstr (message, __check_test) != NULL) && !__check_method) __check_error_trapped = TRUE; //-- format switch (log_level & G_LOG_LEVEL_MASK) { case G_LOG_LEVEL_ERROR: level = "ERROR"; break; case G_LOG_LEVEL_CRITICAL: level = "CRITICAL"; break; case G_LOG_LEVEL_WARNING: level = "WARNING"; break; case G_LOG_LEVEL_MESSAGE: level = "MESSAGE"; break; case G_LOG_LEVEL_INFO: level = "INFO"; break; case G_LOG_LEVEL_DEBUG: level = "DEBUG"; break; default: level = "???"; break; } elapsed = GST_CLOCK_DIFF (_priv_bt_info_start_time, gst_util_get_timestamp ()); msg = g_alloca (85 + strlen (level) + (log_domain ? strlen (log_domain) : 0) + (message ? strlen (message) : 0)); g_sprintf (msg, "%" GST_TIME_FORMAT " %" PID_FMT " %" PTR_FMT " %-7s %20s ::: %s", GST_TIME_ARGS (elapsed), getpid (), g_thread_self (), level, (log_domain ? log_domain : ""), (message ? message : "")); check_print_handler (msg); }
static gboolean viewfinder_get_timestamp_probe (GstPad * pad, GstMiniObject * obj, gpointer udata) { CaptureTiming *timing; timing = (CaptureTiming *) g_list_first (capture_times)->data; timing->precapture = gst_util_get_timestamp (); gst_pad_remove_data_probe (pad, viewfinder_probe_id); return TRUE; }
static gboolean on_video_sink_data_flow (GstPad * pad, GstMiniObject * mini_obj, gpointer user_data) { GstFPSDisplaySink *self = GST_FPS_DISPLAY_SINK (user_data); #if 0 if (GST_IS_BUFFER (mini_obj)) { GstBuffer *buf = GST_BUFFER_CAST (mini_obj); if (GST_CLOCK_TIME_IS_VALID (self->next_ts)) { if (GST_BUFFER_TIMESTAMP (buf) <= self->next_ts) { self->frames_rendered++; } else { GST_WARNING_OBJECT (self, "dropping frame : ts %" GST_TIME_FORMAT " < expected_ts %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (self->next_ts)); self->frames_dropped++; } } else { self->frames_rendered++; } } else #endif if (GST_IS_EVENT (mini_obj)) { GstEvent *ev = GST_EVENT_CAST (mini_obj); if (GST_EVENT_TYPE (ev) == GST_EVENT_QOS) { GstClockTimeDiff diff; GstClockTime ts; gst_event_parse_qos (ev, NULL, &diff, &ts); if (diff <= 0.0) { g_atomic_int_inc (&self->frames_rendered); } else { g_atomic_int_inc (&self->frames_dropped); } ts = gst_util_get_timestamp (); if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (self->start_ts))) { self->interval_ts = self->last_ts = self->start_ts = ts; } if (GST_CLOCK_DIFF (self->interval_ts, ts) > self->fps_update_interval) { display_current_fps (self); self->interval_ts = ts; } } } return TRUE; }
static void check_gst_log_handler (GstDebugCategory * category, GstDebugLevel level, const gchar * file, const gchar * function, gint line, GObject * object, GstDebugMessage * _message, gpointer data) { const gchar *message = gst_debug_message_get (_message); gchar *msg, *obj_str; const gchar *level_str, *cat_str; GstClockTime elapsed; //-- check message contents if (__check_method && (strstr (function, __check_method) != NULL) && __check_test && (strstr (message, __check_test) != NULL)) __check_error_trapped = TRUE; else if (__check_method && (strstr (function, __check_method) != NULL) && !__check_test) __check_error_trapped = TRUE; else if (__check_test && (strstr (message, __check_test) != NULL) && !__check_method) __check_error_trapped = TRUE; if (level > gst_debug_category_get_threshold (category)) return; elapsed = GST_CLOCK_DIFF (_priv_bt_info_start_time, gst_util_get_timestamp ()); level_str = gst_debug_level_get_name (level); cat_str = gst_debug_category_get_name (category); if (object) { if (GST_IS_OBJECT (object)) { obj_str = g_strdup_printf ("<%s,%" G_OBJECT_REF_COUNT_FMT ">", GST_OBJECT_NAME (object), G_OBJECT_LOG_REF_COUNT (object)); } else if (GST_IS_OBJECT (object)) { obj_str = g_strdup_printf ("<%s,%" G_OBJECT_REF_COUNT_FMT ">", G_OBJECT_TYPE_NAME (object), G_OBJECT_LOG_REF_COUNT (object)); } else { obj_str = g_strdup_printf ("%p", object); } } else { obj_str = g_strdup (""); } msg = g_alloca (95 + strlen (cat_str) + strlen (level_str) + strlen (message) + strlen (file) + strlen (function) + strlen (obj_str)); g_sprintf (msg, "%" GST_TIME_FORMAT " %" PID_FMT " %" PTR_FMT " %-7s %20s %s:%d:%s:%s %s", GST_TIME_ARGS (elapsed), getpid (), g_thread_self (), level_str, cat_str, file, line, function, obj_str, message); g_free (obj_str); check_print_handler (msg); }
// must be called after gst_init(), see comment in setup_log_capture() void bt_check_init (void) { _priv_bt_info_start_time = gst_util_get_timestamp (); // disable logging from gstreamer itself gst_debug_remove_log_function (gst_debug_log_default); // set e.g. GST_DEBUG="bt-core:DEBUG" if more details are needed if (gst_debug_get_default_threshold () < GST_LEVEL_INFO) { gst_debug_set_default_threshold (GST_LEVEL_INFO); } // register our plugins extern gboolean bt_test_plugin_init (GstPlugin * plugin); gst_plugin_register_static (GST_VERSION_MAJOR, GST_VERSION_MINOR, "bt-test", "buzztrax test plugin - several unit test support elements", bt_test_plugin_init, VERSION, "LGPL", PACKAGE, PACKAGE_NAME, "http://www.buzztrax.org"); GST_DEBUG_CATEGORY_INIT (GST_CAT_DEFAULT, "bt-check", 0, "music production environment / unit tests"); const gchar *checks = g_getenv ("BT_CHECKS"); if (BT_IS_STRING (checks)) { // we're leaking this funcs = g_strsplit (checks, ",", -1); } #ifdef HAVE_SETRLIMIT // only fork mode limit cpu/mem usage const gchar *mode = g_getenv ("CK_FORK"); if (!mode || strcmp (mode, "no")) { struct rlimit rl; rl.rlim_max = RLIM_INFINITY; // limit cpu in seconds rl.rlim_cur = 20; if (setrlimit (RLIMIT_CPU, &rl) < 0) perror ("setrlimit(RLIMIT_CPU) failed"); // limit process’s data size in bytes // if we get failing tests and "mmap() failed: Cannot allocate memory" // this limit needs to be increased rl.rlim_cur = 515 * 1024 * 1024; // 0.5GB if (setrlimit (RLIMIT_DATA, &rl) < 0) perror ("setrlimit(RLIMIT_DATA) failed"); } #endif }
static gboolean gst_net_client_clock_timeout_source_prepare (GSource * s, gint * p_timeout) { GstNetClientClockTimeoutSource *source = (GstNetClientClockTimeoutSource *) s; GstClockTime expiration_time = source->clock->priv->timeout_expiration; GstClockTime now = gst_util_get_timestamp (); if (now >= expiration_time || (expiration_time - now) <= GST_MSECOND) { *p_timeout = 0; return TRUE; } *p_timeout = (expiration_time - now) / GST_MSECOND; GST_TRACE_OBJECT (source->clock, "time out in %d ms please", *p_timeout); return FALSE; }
static gboolean gst_uri_downloader_sink_event (GstPad * pad, GstObject * parent, GstEvent * event) { gboolean ret = FALSE; GstUriDownloader *downloader; downloader = GST_URI_DOWNLOADER (gst_pad_get_element_private (pad)); switch (event->type) { case GST_EVENT_EOS:{ GST_OBJECT_LOCK (downloader); GST_DEBUG_OBJECT (downloader, "Got EOS on the fetcher pad"); if (downloader->priv->download != NULL) { /* signal we have fetched the URI */ downloader->priv->download->completed = TRUE; downloader->priv->download->download_stop_time = gst_util_get_timestamp (); GST_DEBUG_OBJECT (downloader, "Signaling chain funtion"); g_cond_signal (&downloader->priv->cond); } GST_OBJECT_UNLOCK (downloader); gst_event_unref (event); break; } case GST_EVENT_CUSTOM_DOWNSTREAM_STICKY:{ const GstStructure *str; str = gst_event_get_structure (event); if (gst_structure_has_name (str, "http-headers")) { GST_OBJECT_LOCK (downloader); if (downloader->priv->download != NULL) { if (downloader->priv->download->headers) gst_structure_free (downloader->priv->download->headers); downloader->priv->download->headers = gst_structure_copy (str); } GST_OBJECT_UNLOCK (downloader); } } /* falls through */ default: ret = gst_pad_event_default (pad, parent, event); break; } return ret; }
static void gst_fragment_init (GstFragment * fragment) { GstFragmentPrivate *priv; fragment->priv = priv = gst_fragment_get_instance_private (fragment); g_mutex_init (&fragment->priv->lock); priv->buffer = NULL; fragment->download_start_time = gst_util_get_timestamp (); fragment->start_time = 0; fragment->stop_time = 0; fragment->index = 0; fragment->name = g_strdup (""); fragment->completed = FALSE; fragment->discontinuous = FALSE; fragment->headers = NULL; }
EXPORT_API void gub_ref(const char *gst_debug_string) { gub_log("GST ref (%d -> %d)", gub_ref_count, gub_ref_count + 1); if (gub_ref_count == 0) { GError *err = 0; gchar *version = NULL; if (!gst_init_check(0, 0, &err)) { gub_log("Failed to initialize GStreamer: %s", err ? err->message : "<No error message>"); return; } /* get time we started for debugging messages */ _priv_gst_info_start_time = gst_util_get_timestamp(); gst_debug_remove_log_function(gst_debug_log_default); gst_debug_add_log_function((GstLogFunction)gst_debug_gub, NULL, NULL); if (gst_debug_string) { gub_log("Setting debug level to %s", gst_debug_string); gst_debug_set_active(TRUE); gst_debug_set_threshold_from_string(gst_debug_string, TRUE); } else { gst_debug_set_active(FALSE); } #if defined (__ANDROID__) gst_android_register_static_plugins(); gst_android_load_gio_modules(); #endif gub_main_loop_thread = g_thread_new("GstUnityBridge Main Thread", gub_main_loop_func, NULL); if (!gub_main_loop_thread) { gub_log("Failed to create GLib main thread: %s", err ? err->message : "<No error message>"); return; } version = gst_version_string(); gub_log("%s initialized", version); g_free(version); } gub_ref_count++; }
static void gst_net_client_clock_observe_times (GstNetClientClock * self, GstClockTime local_1, GstClockTime remote, GstClockTime local_2) { GstClockTime current_timeout; GstClockTime local_avg; gdouble r_squared; GstClock *clock; if (local_2 < local_1) goto bogus_observation; local_avg = (local_2 + local_1) / 2; clock = GST_CLOCK_CAST (self); if (gst_clock_add_observation (GST_CLOCK (self), local_avg, remote, &r_squared)) { /* geto formula */ current_timeout = (1e-3 / (1 - MIN (r_squared, 0.99999))) * GST_SECOND; current_timeout = MIN (current_timeout, gst_clock_get_timeout (clock)); } else { current_timeout = 0; } GST_INFO ("next timeout: %" GST_TIME_FORMAT, GST_TIME_ARGS (current_timeout)); self->priv->timeout_expiration = gst_util_get_timestamp () + current_timeout; return; bogus_observation: { GST_WARNING_OBJECT (self, "time packet receive time < send time (%" GST_TIME_FORMAT " < %" GST_TIME_FORMAT ")", GST_TIME_ARGS (local_1), GST_TIME_ARGS (local_2)); return; } }
static gpointer gst_net_client_clock_thread (gpointer data) { GstNetClientClock *self = data; GstNetTimePacket *packet; GMainContext *ctx; GSourceFuncs funcs = { NULL, }; GSource *source; GIOCondition cond; gboolean timeout; GSocket *socket = self->priv->socket; GError *err = NULL; GstClock *clock = data; GST_INFO_OBJECT (self, "net client clock thread running, socket=%p", socket); g_socket_set_blocking (socket, TRUE); g_socket_set_timeout (socket, 0); ctx = g_main_context_new (); source = g_socket_create_source (socket, G_IO_IN, self->priv->cancel); g_source_set_name (source, "GStreamer net client clock thread socket"); g_source_set_callback (source, (GSourceFunc) gst_net_client_clock_socket_cb, &cond, NULL); g_source_attach (source, ctx); g_source_unref (source); /* GSocket only support second granularity for timeouts, so roll our own * timeout source (so we don't have to create a new source whenever the * timeout changes, as we would have to do with the default timeout source) */ funcs.prepare = gst_net_client_clock_timeout_source_prepare; funcs.check = gst_net_client_clock_timeout_source_check; funcs.dispatch = gst_net_client_clock_timeout_source_dispatch; funcs.finalize = NULL; source = g_source_new (&funcs, sizeof (GstNetClientClockTimeoutSource)); ((GstNetClientClockTimeoutSource *) source)->clock = self; ((GstNetClientClockTimeoutSource *) source)->p_timeout = &timeout; g_source_set_name (source, "GStreamer net client clock timeout"); g_source_attach (source, ctx); g_source_unref (source); while (!g_cancellable_is_cancelled (self->priv->cancel)) { cond = 0; timeout = FALSE; g_main_context_iteration (ctx, TRUE); if (g_cancellable_is_cancelled (self->priv->cancel)) break; if (timeout) { /* timed out, let's send another packet */ GST_DEBUG_OBJECT (self, "timed out"); packet = gst_net_time_packet_new (NULL); packet->local_time = gst_clock_get_internal_time (GST_CLOCK (self)); GST_DEBUG_OBJECT (self, "sending packet, local time = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->local_time)); gst_net_time_packet_send (packet, self->priv->socket, self->priv->servaddr, NULL); g_free (packet); /* reset timeout (but are expecting a response sooner anyway) */ self->priv->timeout_expiration = gst_util_get_timestamp () + gst_clock_get_timeout (clock); continue; } /* got data to read? */ if ((cond & G_IO_IN)) { GstClockTime new_local; new_local = gst_clock_get_internal_time (GST_CLOCK (self)); packet = gst_net_time_packet_receive (socket, NULL, &err); if (err != NULL) { GST_WARNING_OBJECT (self, "receive error: %s", err->message); g_error_free (err); err = NULL; continue; } GST_LOG_OBJECT (self, "got packet back"); GST_LOG_OBJECT (self, "local_1 = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->local_time)); GST_LOG_OBJECT (self, "remote = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->remote_time)); GST_LOG_OBJECT (self, "local_2 = %" GST_TIME_FORMAT, GST_TIME_ARGS (new_local)); /* observe_times will reset the timeout */ gst_net_client_clock_observe_times (self, packet->local_time, packet->remote_time, new_local); g_free (packet); continue; } if ((cond & (G_IO_ERR | G_IO_HUP))) { GST_DEBUG_OBJECT (self, "socket error?! %s", g_strerror (errno)); g_usleep (G_USEC_PER_SEC / 10); continue; } } GST_INFO_OBJECT (self, "shutting down net client clock thread"); g_main_context_unref (ctx); return NULL; }
/* we have no fail cases yet, but maybe in the future */ static gboolean init_pre (GOptionContext * context, GOptionGroup * group, gpointer data, GError ** error) { gchar *libdir; if (gst_initialized) { GST_DEBUG ("already initialized"); return TRUE; } _priv_gst_start_time = gst_util_get_timestamp (); #ifndef GST_DISABLE_GST_DEBUG _priv_gst_debug_init (); priv_gst_dump_dot_dir = g_getenv ("GST_DEBUG_DUMP_DOT_DIR"); #endif #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); #endif /* ENABLE_NLS */ /* This is the earliest we can make stuff show up in the logs. * So give some useful info about GStreamer here */ #ifdef G_OS_WIN32 { gchar *basedir = g_win32_get_package_installation_directory_of_module (_priv_gst_dll_handle); libdir = g_build_filename (basedir, #ifdef _DEBUG "debug" #endif "lib", NULL); g_free (basedir); } #else libdir = g_strdup (LIBDIR); #endif GST_INFO ("Initializing GStreamer Core Library version %s", VERSION); GST_INFO ("Using library installed in %s", libdir); g_free (libdir); /* Print some basic system details if possible (OS/architecture) */ #ifdef HAVE_SYS_UTSNAME_H { struct utsname sys_details; if (uname (&sys_details) == 0) { GST_INFO ("%s %s %s %s %s", sys_details.sysname, sys_details.nodename, sys_details.release, sys_details.version, sys_details.machine); } } #endif #ifndef G_ATOMIC_LOCK_FREE GST_CAT_WARNING (GST_CAT_PERFORMANCE, "GLib atomic operations are NOT " "implemented using real hardware atomic operations!"); #endif return TRUE; }
static gboolean run_pipeline (gpointer user_data) { GstCaps *preview_caps = NULL; gchar *filename_str = NULL; GstElement *video_source = NULL; const gchar *filename_suffix; CaptureTiming *timing; g_object_set (camerabin, "mode", mode, NULL); if (preview_caps_name != NULL) { preview_caps = gst_caps_from_string (preview_caps_name); if (preview_caps) { g_object_set (camerabin, "preview-caps", preview_caps, NULL); GST_DEBUG ("Preview caps set"); } else GST_DEBUG ("Preview caps set but could not create caps from string"); } set_metadata (camerabin); /* Construct filename */ if (mode == MODE_VIDEO) filename_suffix = ".mp4"; else filename_suffix = ".jpg"; filename_str = g_strdup_printf ("%s/test_%04u%s", filename->str, capture_count, filename_suffix); GST_DEBUG ("Setting filename: %s", filename_str); g_object_set (camerabin, "location", filename_str, NULL); g_free (filename_str); g_object_get (camerabin, "camera-source", &video_source, NULL); if (video_source) { if (GST_IS_ELEMENT (video_source) && gst_element_implements_interface (video_source, GST_TYPE_PHOTOGRAPHY)) { /* Set GstPhotography interface options. If option not given as command-line parameter use default of the source element. */ if (scene_mode != SCENE_MODE_NONE) g_object_set (video_source, "scene-mode", scene_mode, NULL); if (ev_compensation != EV_COMPENSATION_NONE) g_object_set (video_source, "ev-compensation", ev_compensation, NULL); if (aperture != APERTURE_NONE) g_object_set (video_source, "aperture", aperture, NULL); if (flash_mode != FLASH_MODE_NONE) g_object_set (video_source, "flash-mode", flash_mode, NULL); if (exposure != EXPOSURE_NONE) g_object_set (video_source, "exposure", exposure, NULL); if (iso_speed != ISO_SPEED_NONE) g_object_set (video_source, "iso-speed", iso_speed, NULL); if (wb_mode != WHITE_BALANCE_MODE_NONE) g_object_set (video_source, "white-balance-mode", wb_mode, NULL); if (color_mode != COLOR_TONE_MODE_NONE) g_object_set (video_source, "colour-tone-mode", color_mode, NULL); } g_object_unref (video_source); } else { video_source = gst_bin_get_by_name (GST_BIN (camerabin), "camerasrc"); gst_object_unref (video_source); } g_object_set (camerabin, "zoom", zoom / 100.0f, NULL); capture_count++; timing = g_slice_new0 (CaptureTiming); capture_times = g_list_prepend (capture_times, timing); /* set pad probe to check when buffer leaves the camera source */ if (mode == MODE_IMAGE) { GstPad *pad; pad = gst_element_get_static_pad (video_source, "imgsrc"); camera_probe_id = gst_pad_add_buffer_probe (pad, (GCallback) camera_src_get_timestamp_probe, NULL); gst_object_unref (pad); } timing->start_capture = gst_util_get_timestamp (); g_signal_emit_by_name (camerabin, "start-capture", 0); if (mode == MODE_VIDEO) { g_timeout_add ((capture_time * 1000), (GSourceFunc) stop_capture, NULL); } return FALSE; }
gint main (gint argc, gchar * argv[]) { GThread *threads[MAX_THREADS]; gint num_threads; gint t; GstBuffer *tmp; GstClockTime start, end; gst_init (&argc, &argv); mutex = g_mutex_new (); if (argc != 3) { g_print ("usage: %s <num_threads> <nbbuffers>\n", argv[0]); exit (-1); } num_threads = atoi (argv[1]); nbbuffers = atoi (argv[2]); if (num_threads <= 0 || num_threads > MAX_THREADS) { g_print ("number of threads must be between 0 and %d\n", MAX_THREADS); exit (-2); } if (nbbuffers <= 0) { g_print ("number of buffers must be greater than 0\n"); exit (-3); } g_mutex_lock (mutex); /* Let's just make sure the GstBufferClass is loaded ... */ tmp = gst_buffer_new (); printf ("main(): Creating %d threads.\n", num_threads); for (t = 0; t < num_threads; t++) { GError *error = NULL; threads[t] = g_thread_create (run_test, GINT_TO_POINTER (t), TRUE, &error); if (error) { printf ("ERROR: g_thread_create() %s\n", error->message); exit (-1); } } /* Signal all threads to start */ start = gst_util_get_timestamp (); g_mutex_unlock (mutex); for (t = 0; t < num_threads; t++) { if (threads[t]) g_thread_join (threads[t]); } end = gst_util_get_timestamp (); g_print ("*** total %" GST_TIME_FORMAT " - average %" GST_TIME_FORMAT " - Done creating %" G_GUINT64_FORMAT " buffers\n", GST_TIME_ARGS (end - start), GST_TIME_ARGS ((end - start) / (num_threads * nbbuffers)), num_threads * nbbuffers); gst_buffer_unref (tmp); return 0; }
static void event_loop (GstElement * bin, GstClockTime start) { GstBus *bus; GstMessage *msg = NULL; gboolean running = TRUE; bus = gst_element_get_bus (bin); while (running) { msg = gst_bus_poll (bus, GST_MESSAGE_STATE_CHANGED | GST_MESSAGE_ERROR | GST_MESSAGE_WARNING, -1); switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_STATE_CHANGED: if (GST_MESSAGE_SRC (msg) == (GstObject *) bin) { GstState old_state, new_state; GstClockTime end; gst_message_parse_state_changed (msg, &old_state, &new_state, NULL); end = gst_util_get_timestamp (); g_print ("%" GST_TIME_FORMAT " state change on the bin: %s -> %s\n", GST_TIME_ARGS (end - start), gst_element_state_get_name (old_state), gst_element_state_get_name (new_state)); if (old_state == GST_STATE_READY && new_state == GST_STATE_PAUSED) { running = FALSE; } } break; case GST_MESSAGE_WARNING:{ GError *err = NULL; gchar *dbg = NULL; gst_message_parse_warning (msg, &err, &dbg); GST_WARNING_OBJECT (GST_MESSAGE_SRC (msg), "%s (%s)", err->message, (dbg ? dbg : "no details")); g_error_free (err); g_free (dbg); break; } case GST_MESSAGE_ERROR:{ GError *err = NULL; gchar *dbg = NULL; gst_message_parse_error (msg, &err, &dbg); GST_ERROR_OBJECT (GST_MESSAGE_SRC (msg), "%s (%s)", err->message, (dbg ? dbg : "no details")); g_error_free (err); g_free (dbg); running = FALSE; break; } default: break; } gst_message_unref (msg); } gst_object_unref (bus); }
static gint codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush) { gint err; GstClockTime t; GstBuffer *outbuf = NULL; gint i; self->outArgs->outputID[0] = 0; self->outArgs->freeBufID[0] = 0; t = gst_util_get_timestamp (); err = VIDDEC3_process (self->codec, self->inBufs, self->outBufs, self->inArgs, self->outArgs); GST_INFO_OBJECT (self, "%10dns", (gint) (gst_util_get_timestamp () - t)); if (err) { GST_WARNING_OBJECT (self, "err=%d, extendedError=%08x", err, self->outArgs->extendedError); err = VIDDEC3_control (self->codec, XDM_GETSTATUS, self->dynParams, self->status); GST_WARNING_OBJECT (self, "XDM_GETSTATUS: err=%d, extendedError=%08x", err, self->status->extendedError); if (XDM_ISFATALERROR (self->outArgs->extendedError) || flush) { /* we are processing for display and it is a non-fatal error, so lets * try to recover.. otherwise return the error */ err = XDM_EFAIL; } } for (i = 0; self->outArgs->outputID[i]; i++) { if (G_UNLIKELY (self->first_out_buffer) && send) { /* send region of interest to sink on first buffer: */ XDM_Rect *r = &(self->outArgs->displayBufs.bufDesc[0].activeFrameRegion); GST_DEBUG_OBJECT (self, "setting crop to %d, %d, %d, %d", r->topLeft.x, r->topLeft.y, r->bottomRight.x, r->bottomRight.y); gst_pad_push_event (self->srcpad, gst_event_new_crop (r->topLeft.y, r->topLeft.x, r->bottomRight.x - r->topLeft.x, r->bottomRight.y - r->topLeft.y)); self->first_out_buffer = FALSE; } outbuf = codec_get_outbuf (self, self->outArgs->outputID[i]); if (send) { if (GST_IS_DUCATIBUFFER (outbuf)) { outbuf = gst_ducati_buffer_get (GST_DUCATIBUFFER (outbuf)); } GST_DEBUG_OBJECT (self, "got buffer: %d %p (%" GST_TIME_FORMAT ")", i, outbuf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf))); gst_pad_push (self->srcpad, outbuf); } else { GST_DEBUG_OBJECT (self, "free buffer: %d %p", i, outbuf); gst_buffer_unref (outbuf); } } for (i = 0; self->outArgs->freeBufID[i]; i++) { codec_unlock_outbuf (self, self->outArgs->freeBufID[i]); } return err; }
static gboolean display_current_fps (gpointer data) { GstFPSDisplaySink *self = GST_FPS_DISPLAY_SINK (data); guint64 frames_rendered, frames_dropped; gdouble rr, dr, average_fps; gchar fps_message[256]; gdouble time_diff, time_elapsed; GstClockTime current_ts = gst_util_get_timestamp (); frames_rendered = g_atomic_int_get (&self->frames_rendered); frames_dropped = g_atomic_int_get (&self->frames_dropped); if ((frames_rendered + frames_dropped) == 0) { /* in case timer fired and we didn't yet get any QOS events */ return TRUE; } time_diff = (gdouble) (current_ts - self->last_ts) / GST_SECOND; time_elapsed = (gdouble) (current_ts - self->start_ts) / GST_SECOND; rr = (gdouble) (frames_rendered - self->last_frames_rendered) / time_diff; dr = (gdouble) (frames_dropped - self->last_frames_dropped) / time_diff; average_fps = (gdouble) frames_rendered / time_elapsed; if (self->max_fps == -1 || rr > self->max_fps) { self->max_fps = rr; GST_DEBUG_OBJECT (self, "Updated max-fps to %f", rr); } if (self->min_fps == -1 || rr < self->min_fps) { self->min_fps = rr; GST_DEBUG_OBJECT (self, "Updated min-fps to %f", rr); } if (self->signal_measurements) { GST_LOG_OBJECT (self, "Signaling measurements: fps:%f droprate:%f " "avg-fps:%f", rr, dr, average_fps); g_signal_emit (G_OBJECT (self), fpsdisplaysink_signals[SIGNAL_FPS_MEASUREMENTS], 0, rr, dr, average_fps); } /* Display on a single line to make it easier to read and import * into, for example, excel.. note: it would be nice to show * timestamp too.. need to check if there is a sane way to log * timestamp of last rendered buffer, so we could correlate dips * in framerate to certain positions in the stream. */ if (dr == 0.0) { g_snprintf (fps_message, 255, "rendered: %" G_GUINT64_FORMAT "\t dropped: %" G_GUINT64_FORMAT "\t current: %.2f\t average: %.2f", frames_rendered, frames_dropped, rr, average_fps); } else { g_snprintf (fps_message, 255, "rendered: %" G_GUINT64_FORMAT "\t dropped: %" G_GUINT64_FORMAT "\t fps: %.2f\t drop rate: %.2f", frames_rendered, frames_dropped, rr, dr); } if (self->use_text_overlay) { g_object_set (self->text_overlay, "text", fps_message, NULL); } else { g_print ("%s\n", fps_message); } self->last_frames_rendered = frames_rendered; self->last_frames_dropped = frames_dropped; self->last_ts = current_ts; return TRUE; }
static gpointer gst_net_client_clock_thread (gpointer data) { GstNetClientClock *self = data; GstNetTimePacket *packet; GSocket *socket = self->priv->socket; GError *err = NULL; GstClock *clock = data; GST_INFO_OBJECT (self, "net client clock thread running, socket=%p", socket); g_socket_set_blocking (socket, TRUE); g_socket_set_timeout (socket, 0); while (!g_cancellable_is_cancelled (self->priv->cancel)) { GstClockTime expiration_time = self->priv->timeout_expiration; GstClockTime now = gst_util_get_timestamp (); gint64 socket_timeout; if (now >= expiration_time || (expiration_time - now) <= GST_MSECOND) { socket_timeout = 0; } else { socket_timeout = (expiration_time - now) / GST_USECOND; } GST_TRACE_OBJECT (self, "timeout: %" G_GINT64_FORMAT "us", socket_timeout); if (!g_socket_condition_timed_wait (socket, G_IO_IN, socket_timeout, self->priv->cancel, &err)) { /* cancelled, timeout or error */ if (err->code == G_IO_ERROR_CANCELLED) { GST_INFO_OBJECT (self, "cancelled"); g_clear_error (&err); break; } else if (err->code == G_IO_ERROR_TIMED_OUT) { /* timed out, let's send another packet */ GST_DEBUG_OBJECT (self, "timed out"); packet = gst_net_time_packet_new (NULL); packet->local_time = gst_clock_get_internal_time (GST_CLOCK (self)); GST_DEBUG_OBJECT (self, "sending packet, local time = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->local_time)); gst_net_time_packet_send (packet, self->priv->socket, self->priv->servaddr, NULL); g_free (packet); /* reset timeout (but are expecting a response sooner anyway) */ self->priv->timeout_expiration = gst_util_get_timestamp () + gst_clock_get_timeout (clock); } else { GST_DEBUG_OBJECT (self, "socket error: %s", err->message); g_usleep (G_USEC_PER_SEC / 10); /* throttle */ } g_clear_error (&err); } else { GstClockTime new_local; /* got packet */ new_local = gst_clock_get_internal_time (GST_CLOCK (self)); packet = gst_net_time_packet_receive (socket, NULL, &err); if (packet != NULL) { GST_LOG_OBJECT (self, "got packet back"); GST_LOG_OBJECT (self, "local_1 = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->local_time)); GST_LOG_OBJECT (self, "remote = %" GST_TIME_FORMAT, GST_TIME_ARGS (packet->remote_time)); GST_LOG_OBJECT (self, "local_2 = %" GST_TIME_FORMAT, GST_TIME_ARGS (new_local)); /* observe_times will reset the timeout */ gst_net_client_clock_observe_times (self, packet->local_time, packet->remote_time, new_local); g_free (packet); } else if (err != NULL) { GST_WARNING_OBJECT (self, "receive error: %s", err->message); g_clear_error (&err); } } } GST_INFO_OBJECT (self, "shutting down net client clock thread"); return NULL; }
static gboolean bus_callback (GstBus * bus, GstMessage * message, gpointer data) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR:{ GError *err; gchar *debug; gst_message_parse_error (message, &err, &debug); g_print ("Error: %s\n", err->message); g_error_free (err); g_free (debug); /* Write debug graph to file */ GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (camerabin), GST_DEBUG_GRAPH_SHOW_ALL, "camerabin.error"); g_main_loop_quit (loop); break; } case GST_MESSAGE_STATE_CHANGED: if (GST_IS_BIN (GST_MESSAGE_SRC (message))) { GstState oldstate, newstate; gst_message_parse_state_changed (message, &oldstate, &newstate, NULL); GST_DEBUG_OBJECT (GST_MESSAGE_SRC (message), "state-changed: %s -> %s", gst_element_state_get_name (oldstate), gst_element_state_get_name (newstate)); } break; case GST_MESSAGE_EOS: /* end-of-stream */ GST_INFO ("got eos() - should not happen"); g_main_loop_quit (loop); break; case GST_MESSAGE_ELEMENT: if (GST_MESSAGE_SRC (message) == (GstObject *) camerabin) { const GstStructure *structure = gst_message_get_structure (message); if (gst_structure_has_name (structure, "image-done")) { CaptureTiming *timing; #ifndef GST_DISABLE_GST_DEBUG const gchar *fname = gst_structure_get_string (structure, "filename"); GST_DEBUG ("image done: %s", fname); #endif timing = (CaptureTiming *) g_list_first (capture_times)->data; timing->capture_done = gst_util_get_timestamp (); if (capture_count < capture_total) { g_idle_add ((GSourceFunc) run_pipeline, NULL); } else { g_main_loop_quit (loop); } } } break; default: /* unhandled message */ break; } return TRUE; }
gint main (gint argc, gchar * argv[]) { GstMessage *msg; GstElement *pipeline, *src, *e; GSList *saved_src_list, *src_list, *new_src_list; guint complexity_order, n_elements, i, j, max_this_level; GstClockTime start, end; gst_init (&argc, &argv); if (argc != 3) { g_print ("Usage: %s COMPLEXITY_ORDER N_ELEMENTS\n", argv[0]); return 1; } complexity_order = atoi (argv[1]); n_elements = atoi (argv[2]); start = gst_util_get_timestamp (); pipeline = gst_element_factory_make ("pipeline", NULL); g_assert (pipeline); e = gst_element_factory_make ("fakesrc", NULL); g_object_set (e, "num-buffers", BUFFER_COUNT, NULL); g_object_set (e, "silent", TRUE, NULL); gst_bin_add (GST_BIN (pipeline), e); src_list = saved_src_list = g_slist_append (NULL, e); new_src_list = NULL; max_this_level = 1; for (i = 0, j = 0; i < n_elements; i++, j++) { if (j >= max_this_level) { g_slist_free (saved_src_list); saved_src_list = g_slist_reverse (new_src_list); new_src_list = NULL; j = 0; max_this_level *= complexity_order; } if (!src_list) { src_list = saved_src_list; } src = (GstElement *) src_list->data; src_list = src_list->next; if (i + max_this_level < n_elements) { e = gst_element_factory_make ("tee", NULL); } else { e = gst_element_factory_make ("fakesink", NULL); g_object_set (e, "async", FALSE, NULL); } g_object_set (e, "silent", TRUE, NULL); new_src_list = g_slist_prepend (new_src_list, e); gst_bin_add (GST_BIN (pipeline), e); if (!gst_element_link (src, e)) g_assert_not_reached (); } g_slist_free (saved_src_list); g_slist_free (new_src_list); end = gst_util_get_timestamp (); g_print ("%" GST_TIME_FORMAT " - creating and linking %u elements\n", GST_TIME_ARGS (end - start), i); start = gst_util_get_timestamp (); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) g_assert_not_reached (); if (gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE) == GST_STATE_CHANGE_FAILURE) g_assert_not_reached (); end = gst_util_get_timestamp (); g_print ("%" GST_TIME_FORMAT " - setting pipeline to playing\n", GST_TIME_ARGS (end - start)); start = gst_util_get_timestamp (); msg = gst_bus_poll (gst_element_get_bus (pipeline), GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1); end = gst_util_get_timestamp (); gst_message_unref (msg); g_print ("%" GST_TIME_FORMAT " - putting %d buffers through\n", GST_TIME_ARGS (end - start), BUFFER_COUNT); start = gst_util_get_timestamp (); if (gst_element_set_state (pipeline, GST_STATE_NULL) != GST_STATE_CHANGE_SUCCESS) g_assert_not_reached (); end = gst_util_get_timestamp (); g_print ("%" GST_TIME_FORMAT " - setting pipeline to NULL\n", GST_TIME_ARGS (end - start)); start = gst_util_get_timestamp (); g_object_unref (pipeline); end = gst_util_get_timestamp (); g_print ("%" GST_TIME_FORMAT " - unreffing pipeline\n", GST_TIME_ARGS (end - start)); return 0; }
static gboolean setup_pipeline (void) { gboolean res = TRUE; GstBus *bus; GstElement *sink = NULL, *ipp = NULL; GstEncodingProfile *prof = NULL; initial_time = gst_util_get_timestamp (); camerabin = gst_element_factory_make ("camerabin2", NULL); if (NULL == camerabin) { g_warning ("can't create camerabin element\n"); goto error; } bus = gst_pipeline_get_bus (GST_PIPELINE (camerabin)); /* Add sync handler for time critical messages that need to be handled fast */ gst_bus_set_sync_handler (bus, sync_bus_callback, NULL); /* Handle normal messages asynchronously */ gst_bus_add_watch (bus, bus_callback, NULL); gst_object_unref (bus); GST_INFO_OBJECT (camerabin, "camerabin2 created"); if (videosrc_name) { GstElement *wrapper; GstElement *videosrc; if (wrappersrc_name) wrapper = gst_element_factory_make (wrappersrc_name, NULL); else wrapper = gst_element_factory_make ("wrappercamerabinsrc", NULL); if (setup_pipeline_element (wrapper, "video-source", videosrc_name, NULL)) { g_object_set (camerabin, "camera-source", wrapper, NULL); } else { GST_WARNING ("Failed to set videosrc to %s", videosrc_name); } g_object_get (wrapper, "video-source", &videosrc, NULL); if (videosrc && videodevice_name && g_object_class_find_property (G_OBJECT_GET_CLASS (videosrc), "device")) { g_object_set (videosrc, "device", videodevice_name, NULL); } } /* configure used elements */ res &= setup_pipeline_element (camerabin, "audio-source", audiosrc_name, NULL); res &= setup_pipeline_element (camerabin, "viewfinder-sink", vfsink_name, &sink); res &= setup_pipeline_element (camerabin, "viewfinder-filter", viewfinder_filter, NULL); if (imagepp_name) { ipp = create_ipp_bin (); if (ipp) g_object_set (camerabin, "image-filter", ipp, NULL); else GST_WARNING ("Could not create ipp elements"); } prof = load_encoding_profile (); if (prof) g_object_set (G_OBJECT (camerabin), "video-profile", prof, NULL); GST_INFO_OBJECT (camerabin, "elements created"); if (sink) { g_object_set (sink, "sync", TRUE, NULL); } else { /* Get the inner viewfinder sink, this uses fixed names given * by default in camerabin2 */ sink = gst_bin_get_by_name (GST_BIN (camerabin), "vf-bin"); g_assert (sink); gst_object_unref (sink); sink = gst_bin_get_by_name (GST_BIN (sink), "vfbin-sink"); g_assert (sink); gst_object_unref (sink); } viewfinder_sink = sink; GST_INFO_OBJECT (camerabin, "elements configured"); /* configure a resolution and framerate */ if (image_width > 0 && image_height > 0) { if (mode == MODE_VIDEO) { GstCaps *caps = NULL; if (view_framerate_num > 0) caps = gst_caps_new_full (gst_structure_new ("video/x-raw-yuv", "width", G_TYPE_INT, image_width, "height", G_TYPE_INT, image_height, "framerate", GST_TYPE_FRACTION, view_framerate_num, view_framerate_den, NULL), gst_structure_new ("video/x-raw-rgb", "width", G_TYPE_INT, image_width, "height", G_TYPE_INT, image_height, "framerate", GST_TYPE_FRACTION, view_framerate_num, view_framerate_den, NULL), NULL); else caps = gst_caps_new_full (gst_structure_new ("video/x-raw-yuv", "width", G_TYPE_INT, image_width, "height", G_TYPE_INT, image_height, NULL), gst_structure_new ("video/x-raw-rgb", "width", G_TYPE_INT, image_width, "height", G_TYPE_INT, image_height, NULL), NULL); g_object_set (camerabin, "video-capture-caps", caps, NULL); gst_caps_unref (caps); } else { GstCaps *caps = gst_caps_new_full (gst_structure_new ("video/x-raw-yuv", "width", G_TYPE_INT, image_width, "height", G_TYPE_INT, image_height, NULL), gst_structure_new ("video/x-raw-rgb", "width", G_TYPE_INT, image_width, "height", G_TYPE_INT, image_height, NULL), NULL); g_object_set (camerabin, "image-capture-caps", caps, NULL); gst_caps_unref (caps); } } set_camerabin2_caps_from_string (); /* change to the wrong mode if timestamping if performance mode is on so * we can change it back and measure the time after in playing */ if (performance_measure) { g_object_set (camerabin, "mode", mode == MODE_VIDEO ? MODE_IMAGE : MODE_VIDEO, NULL); } if (GST_STATE_CHANGE_FAILURE == gst_element_set_state (camerabin, GST_STATE_READY)) { g_warning ("can't set camerabin to ready\n"); goto error; } GST_INFO_OBJECT (camerabin, "camera ready"); if (GST_STATE_CHANGE_FAILURE == gst_element_set_state (camerabin, GST_STATE_PLAYING)) { g_warning ("can't set camerabin to playing\n"); goto error; } GST_INFO_OBJECT (camerabin, "camera started"); /* do the mode change timestamping if performance mode is on */ if (performance_measure) { change_mode_before = gst_util_get_timestamp (); g_object_set (camerabin, "mode", mode, NULL); change_mode_after = gst_util_get_timestamp (); } return TRUE; error: cleanup_pipeline (); return FALSE; }
bool mmsGstPlay(GstElement *pipelineX) { pipeline = pipelineX; GstState state, pending; caught_error = event_loop (pipeline, FALSE, GST_STATE_PLAYING); if (caught_error) { fprintf (stderr, "ERROR: pipeline doesn't want to preroll.\n"); } else { GstClockTime tfthen, tfnow; GstClockTimeDiff diff; fprintf (stderr, "Setting pipeline to PLAYING ...\n"); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) { GstMessage *err_msg; GstBus *bus; fprintf (stderr, "ERROR: pipeline doesn't want to play.\n"); bus = gst_element_get_bus (pipeline); if ((err_msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0))) { GError *gerror; gchar *debug; gst_message_parse_error (err_msg, &gerror, &debug); gst_object_default_error (GST_MESSAGE_SRC (err_msg), gerror, debug); gst_message_unref (err_msg); g_error_free (gerror); g_free (debug); } gst_object_unref (bus); mmsGstFree(); return false; } tfthen = gst_util_get_timestamp (); caught_error = event_loop (pipeline, TRUE, GST_STATE_PLAYING); tfnow = gst_util_get_timestamp (); diff = GST_CLOCK_DIFF (tfthen, tfnow); g_print ("Execution ended after %" G_GUINT64_FORMAT " ns.\n", diff); } /* iterate mainloop to process pending stuff */ while (g_main_context_iteration (NULL, FALSE)); fprintf (stderr, "Setting pipeline to PAUSED ...\n"); gst_element_set_state (pipeline, GST_STATE_PAUSED); if (!caught_error) gst_element_get_state (pipeline, &state, &pending, GST_CLOCK_TIME_NONE); fprintf (stderr, "Setting pipeline to READY ...\n"); gst_element_set_state (pipeline, GST_STATE_READY); gst_element_get_state (pipeline, &state, &pending, GST_CLOCK_TIME_NONE); // playback is finished return true; }
static void gst_debug_gub(GstDebugCategory * category, GstDebugLevel level, const gchar * file, const gchar * function, gint line, GObject * object, GstDebugMessage * message, gpointer unused) { GstClockTime elapsed; gchar *tag; const gchar *level_str; if (level > gst_debug_category_get_threshold(category)) return; elapsed = GST_CLOCK_DIFF(_priv_gst_info_start_time, gst_util_get_timestamp()); switch (level) { case GST_LEVEL_ERROR: level_str = "ERR"; break; case GST_LEVEL_WARNING: level_str = "WRN"; break; case GST_LEVEL_INFO: level_str = "NFO"; break; case GST_LEVEL_DEBUG: level_str = "DBG"; break; default: level_str = "LOG"; break; } tag = g_strdup_printf("%s", gst_debug_category_get_name(category)); if (object) { gchar *obj; if (GST_IS_PAD(object) && GST_OBJECT_NAME(object)) { obj = g_strdup_printf("<%s:%s>", GST_DEBUG_PAD_NAME(object)); } else if (GST_IS_OBJECT(object) && GST_OBJECT_NAME(object)) { obj = g_strdup_printf("<%s>", GST_OBJECT_NAME(object)); } else if (G_IS_OBJECT(object)) { obj = g_strdup_printf("<%s@%p>", G_OBJECT_TYPE_NAME(object), object); } else { obj = g_strdup_printf("<%p>", object); } gub_log( "%" GST_TIME_FORMAT " %p %s %s %s:%d:%s:%s %s", GST_TIME_ARGS(elapsed), g_thread_self(), level_str, tag, file, line, function, obj, gst_debug_message_get(message)); g_free(obj); } else { gub_log( "%" GST_TIME_FORMAT " %p %s %s %s:%d:%s %s", GST_TIME_ARGS(elapsed), g_thread_self(), level_str, tag, file, line, function, gst_debug_message_get(message)); } g_free(tag); }
gint main (gint argc, gchar * argv[]) { GstBin *bin; GstClockTime start, end; GstElement *sink, *new_sink; /* default parameters */ gint depth = 4; gint children = 3; gint flavour = FLAVOUR_AUDIO; const gchar *flavour_str = "audio"; gst_init (&argc, &argv); /* check command line options */ if (argc) { gint arg; for (arg = 0; arg < argc; arg++) { if (!strcmp (argv[arg], "-d")) { arg++; if (arg < argc) depth = atoi (argv[arg]); } else if (!strcmp (argv[arg], "-c")) { arg++; if (arg < argc) children = atoi (argv[arg]); } else if (!strcmp (argv[arg], "-f")) { arg++; if (arg < argc) { flavour_str = argv[arg]; switch (*flavour_str) { case 'a': flavour = FLAVOUR_AUDIO; break; case 'v': flavour = FLAVOUR_VIDEO; break; default: break; } } } } } /* build pipeline */ g_print ("building %s pipeline with depth = %d and children = %d\n", flavour_str, depth, children); start = gst_util_get_timestamp (); bin = GST_BIN (gst_pipeline_new ("pipeline")); sink = gst_element_factory_make ("fakesink", NULL); gst_bin_add (bin, sink); if (!create_node (bin, sink, "sink", &new_sink, children, flavour)) { goto Error; } if (!create_nodes (bin, new_sink, depth, children, flavour)) { goto Error; } end = gst_util_get_timestamp (); /* num-threads = num-sources = pow (children, depth) */ g_print ("%" GST_TIME_FORMAT " built pipeline with %d elements\n", GST_TIME_ARGS (end - start), GST_BIN_NUMCHILDREN (bin)); /* meassure */ g_print ("starting pipeline\n"); gst_element_set_state (GST_ELEMENT (bin), GST_STATE_READY); GST_DEBUG_BIN_TO_DOT_FILE (bin, GST_DEBUG_GRAPH_SHOW_MEDIA_TYPE, "capsnego"); start = gst_util_get_timestamp (); gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED); event_loop (GST_ELEMENT (bin), start); end = gst_util_get_timestamp (); g_print ("%" GST_TIME_FORMAT " reached paused\n", GST_TIME_ARGS (end - start)); /* clean up */ Error: gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL); gst_object_unref (bin); return 0; }
static GstBusSyncReply sync_bus_callback (GstBus * bus, GstMessage * message, gpointer data) { const GstStructure *st; const GValue *image; GstBuffer *buf = NULL; guint8 *data_buf = NULL; gchar *caps_string; guint size = 0; gchar *preview_filename = NULL; FILE *f = NULL; size_t written; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ELEMENT:{ st = gst_message_get_structure (message); if (st) { if (gst_structure_has_name (message->structure, "prepare-xwindow-id")) { if (!no_xwindow && window) { gst_x_overlay_set_window_handle (GST_X_OVERLAY (GST_MESSAGE_SRC (message)), window); gst_message_unref (message); message = NULL; return GST_BUS_DROP; } } else if (gst_structure_has_name (st, "preview-image")) { CaptureTiming *timing; GST_DEBUG ("preview-image"); timing = (CaptureTiming *) g_list_first (capture_times)->data; timing->got_preview = gst_util_get_timestamp (); { /* set up probe to check when the viewfinder gets data */ GstPad *pad = gst_element_get_static_pad (viewfinder_sink, "sink"); viewfinder_probe_id = gst_pad_add_buffer_probe (pad, (GCallback) viewfinder_get_timestamp_probe, NULL); gst_object_unref (pad); } /* extract preview-image from msg */ image = gst_structure_get_value (st, "buffer"); if (image) { buf = gst_value_get_buffer (image); data_buf = GST_BUFFER_DATA (buf); size = GST_BUFFER_SIZE (buf); preview_filename = g_strdup_printf ("test_vga.rgb"); caps_string = gst_caps_to_string (GST_BUFFER_CAPS (buf)); g_free (caps_string); f = g_fopen (preview_filename, "w"); if (f) { written = fwrite (data_buf, size, 1, f); if (!written) { g_print ("error writing file\n"); } fclose (f); } else { g_print ("error opening file for raw image writing\n"); } g_free (preview_filename); } } } break; } case GST_MESSAGE_STATE_CHANGED: if (GST_MESSAGE_SRC (message) == (GstObject *) camerabin) { GstState newstate; gst_message_parse_state_changed (message, NULL, &newstate, NULL); if (newstate == GST_STATE_PLAYING) { startup_time = gst_util_get_timestamp (); } } break; default: /* unhandled message */ break; } return GST_BUS_PASS; }