static GstJackAudioConnection * gst_jack_audio_get_connection (const gchar * id, const gchar * server, jack_client_t * jclient, jack_status_t * status) { GstJackAudioConnection *conn; GList *found; FindData data; GST_DEBUG ("getting connection for id %s, server %s", id, GST_STR_NULL (server)); data.id = id; data.server = server; G_LOCK (connections_lock); found = g_list_find_custom (connections, &data, (GCompareFunc) connection_find); if (found != NULL && jclient != NULL) { /* we found it, increase refcount and return it */ conn = (GstJackAudioConnection *) found->data; conn->refcount++; GST_DEBUG ("found connection %p", conn); } else { /* make new connection */ conn = gst_jack_audio_make_connection (id, server, jclient, status); if (conn != NULL) { GST_DEBUG ("created connection %p", conn); /* add to list on success */ connections = g_list_prepend (connections, conn); } else { GST_WARNING ("could not create connection"); } } G_UNLOCK (connections_lock); return conn; }
static void print_plugin (const gchar * marker, GstRegistry * registry, GstPlugin * plugin) { const gchar *name; GList *features, *f; name = gst_plugin_get_name (plugin); GST_DEBUG ("%s: plugin %p %d %s file: %s", marker, plugin, GST_OBJECT_REFCOUNT (plugin), name, GST_STR_NULL (gst_plugin_get_filename (plugin))); features = gst_registry_get_feature_list_by_plugin (registry, name); for (f = features; f != NULL; f = f->next) { GstPluginFeature *feature; feature = GST_PLUGIN_FEATURE (f->data); GST_LOG ("%s: feature: %p %s", marker, feature, GST_OBJECT_NAME (feature)); } gst_plugin_feature_list_free (features); }
/** * gst_element_factory_make: * @factoryname: a named 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 element factory. * If name is NULL, then the element will receive a guaranteed unique name, * consisting of the element factory name and a number. * If name is given, it will be given the name supplied. * * Returns: (transfer full): new #GstElement or NULL if unable to create element */ GstElement * gst_element_factory_make (const gchar * factoryname, const gchar * name) { GstElementFactory *factory; GstElement *element; g_return_val_if_fail (factoryname != NULL, NULL); g_return_val_if_fail (gst_is_initialized (), NULL); GST_LOG ("gstelementfactory: make \"%s\" \"%s\"", factoryname, GST_STR_NULL (name)); factory = gst_element_factory_find (factoryname); if (factory == NULL) goto no_factory; GST_LOG_OBJECT (factory, "found factory %p", factory); element = gst_element_factory_create (factory, name); if (element == NULL) goto create_failed; gst_object_unref (factory); return element; /* ERRORS */ no_factory: { GST_INFO ("no such element factory \"%s\"!", factoryname); return NULL; } create_failed: { GST_INFO_OBJECT (factory, "couldn't create instance!"); gst_object_unref (factory); return NULL; } }
static void jack_shutdown_cb (void *arg) { GstJackAudioConnection *conn = (GstJackAudioConnection *) arg; GList *walk; GST_DEBUG ("disconnect client %s from server %s", conn->id, GST_STR_NULL (conn->server)); g_mutex_lock (conn->lock); for (walk = conn->src_clients; walk; walk = g_list_next (walk)) { GstJackAudioClient *client = (GstJackAudioClient *) walk->data; if (client->shutdown) client->shutdown (client->user_data); } for (walk = conn->sink_clients; walk; walk = g_list_next (walk)) { GstJackAudioClient *client = (GstJackAudioClient *) walk->data; if (client->shutdown) client->shutdown (client->user_data); } g_mutex_unlock (conn->lock); }
static gboolean gst_mms_do_seek (GstBaseSrc * src, GstSegment * segment) { mms_off_t start; GstMMS *mmssrc = GST_MMS (src); if (segment->format == GST_FORMAT_TIME) { if (!mmsx_time_seek (NULL, mmssrc->connection, (double) segment->start / GST_SECOND)) { GST_LOG_OBJECT (mmssrc, "mmsx_time_seek() failed"); return FALSE; } start = mmsx_get_current_pos (mmssrc->connection); GST_INFO_OBJECT (mmssrc, "sought to %" GST_TIME_FORMAT ", offset after " "seek: %" G_GINT64_FORMAT, GST_TIME_ARGS (segment->start), start); } else if (segment->format == GST_FORMAT_BYTES) { start = mmsx_seek (NULL, mmssrc->connection, segment->start, SEEK_SET); /* mmsx_seek will close and reopen the connection when seeking with the mmsh protocol, if the reopening fails this is indicated with -1 */ if (start == -1) { GST_DEBUG_OBJECT (mmssrc, "connection broken during seek"); return FALSE; } GST_INFO_OBJECT (mmssrc, "sought to: %" G_GINT64_FORMAT " bytes, " "result: %" G_GINT64_FORMAT, segment->start, start); } else { GST_DEBUG_OBJECT (mmssrc, "unsupported seek segment format: %s", GST_STR_NULL (gst_format_get_name (segment->format))); return FALSE; } gst_segment_init (segment, GST_FORMAT_BYTES); gst_segment_set_seek (segment, segment->rate, GST_FORMAT_BYTES, segment->flags, GST_SEEK_TYPE_SET, start, GST_SEEK_TYPE_NONE, segment->stop, NULL); return TRUE; }
void totem_gst_message_print (GstMessage *msg, GstElement *play, const char *filename) { GError *err = NULL; char *dbg = NULL; g_return_if_fail (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR); if (play != NULL) { g_return_if_fail (filename != NULL); GST_DEBUG_BIN_TO_DOT_FILE (GST_BIN_CAST (play), GST_DEBUG_GRAPH_SHOW_ALL ^ GST_DEBUG_GRAPH_SHOW_NON_DEFAULT_PARAMS, filename); } gst_message_parse_error (msg, &err, &dbg); if (err) { char *uri; g_object_get (play, "uri", &uri, NULL); GST_ERROR ("message = %s", GST_STR_NULL (err->message)); GST_ERROR ("domain = %d (%s)", err->domain, GST_STR_NULL (g_quark_to_string (err->domain))); GST_ERROR ("code = %d", err->code); GST_ERROR ("debug = %s", GST_STR_NULL (dbg)); GST_ERROR ("source = %" GST_PTR_FORMAT, msg->src); GST_ERROR ("uri = %s", GST_STR_NULL (uri)); g_free (uri); g_message ("Error: %s\n%s\n", GST_STR_NULL (err->message), GST_STR_NULL (dbg)); g_error_free (err); } g_free (dbg); }
static gboolean gst_rtp_g722_depay_setcaps (GstBaseRTPDepayload * depayload, GstCaps * caps) { GstStructure *structure; GstRtpG722Depay *rtpg722depay; gint clock_rate, payload, samplerate; gint channels; GstCaps *srccaps; gboolean res; const gchar *channel_order; const GstRTPChannelOrder *order; rtpg722depay = GST_RTP_G722_DEPAY (depayload); structure = gst_caps_get_structure (caps, 0); payload = 96; gst_structure_get_int (structure, "payload", &payload); switch (payload) { case GST_RTP_PAYLOAD_G722: channels = 1; clock_rate = 8000; samplerate = 16000; break; default: /* no fixed mapping, we need clock-rate */ channels = 0; clock_rate = 0; samplerate = 0; break; } /* caps can overwrite defaults */ clock_rate = gst_rtp_g722_depay_parse_int (structure, "clock-rate", clock_rate); if (clock_rate == 0) goto no_clockrate; if (clock_rate == 8000) samplerate = 16000; if (samplerate == 0) samplerate = clock_rate; channels = gst_rtp_g722_depay_parse_int (structure, "encoding-params", channels); if (channels == 0) { channels = gst_rtp_g722_depay_parse_int (structure, "channels", channels); if (channels == 0) { /* channels defaults to 1 otherwise */ channels = 1; } } depayload->clock_rate = clock_rate; rtpg722depay->rate = samplerate; rtpg722depay->channels = channels; srccaps = gst_caps_new_simple ("audio/G722", "rate", G_TYPE_INT, samplerate, "channels", G_TYPE_INT, channels, NULL); /* add channel positions */ channel_order = gst_structure_get_string (structure, "channel-order"); order = gst_rtp_channels_get_by_order (channels, channel_order); if (order) { gst_audio_set_channel_positions (gst_caps_get_structure (srccaps, 0), order->pos); } else { GstAudioChannelPosition *pos; GST_ELEMENT_WARNING (rtpg722depay, STREAM, DECODE, (NULL), ("Unknown channel order '%s' for %d channels", GST_STR_NULL (channel_order), channels)); /* create default NONE layout */ pos = gst_rtp_channels_create_default (channels); gst_audio_set_channel_positions (gst_caps_get_structure (srccaps, 0), pos); g_free (pos); } res = gst_pad_set_caps (depayload->srcpad, srccaps); gst_caps_unref (srccaps); return res; /* ERRORS */ no_clockrate: { GST_ERROR_OBJECT (depayload, "no clock-rate specified"); return FALSE; } }
static gboolean gst_gsettings_audio_sink_change_child (GstGSettingsAudioSink * sink) { const gchar *key = NULL; gchar *new_string; GError *err = NULL; GstElement *new_kid; GST_OBJECT_LOCK (sink); switch (sink->profile) { case GST_GSETTINGS_AUDIOSINK_PROFILE_SOUNDS: key = GST_GSETTINGS_KEY_SOUNDS_AUDIOSINK; break; case GST_GSETTINGS_AUDIOSINK_PROFILE_MUSIC: key = GST_GSETTINGS_KEY_MUSIC_AUDIOSINK; break; case GST_GSETTINGS_AUDIOSINK_PROFILE_CHAT: key = GST_GSETTINGS_KEY_CHAT_AUDIOSINK; break; default: break; } new_string = g_settings_get_string (sink->settings, key); if (new_string != NULL && sink->gsettings_str != NULL && (strlen (new_string) == 0 || strcmp (sink->gsettings_str, new_string) == 0)) { g_free (new_string); GST_DEBUG_OBJECT (sink, "GSettings key was updated, but it didn't change. Ignoring"); GST_OBJECT_UNLOCK (sink); return TRUE; } GST_OBJECT_UNLOCK (sink); GST_DEBUG_OBJECT (sink, "GSettings key changed from '%s' to '%s'", GST_STR_NULL (sink->gsettings_str), GST_STR_NULL (new_string)); if (new_string) { new_kid = gst_parse_bin_from_description (new_string, TRUE, &err); if (err) { GST_ERROR_OBJECT (sink, "error creating bin '%s': %s", new_string, err->message); g_error_free (err); } } else { new_kid = NULL; } if (new_kid == NULL) { GST_ELEMENT_ERROR (sink, LIBRARY, SETTINGS, (NULL), ("Failed to render audio sink from GSettings")); goto fail; } if (!gst_switch_sink_set_child (GST_SWITCH_SINK (sink), new_kid)) { GST_WARNING_OBJECT (sink, "Failed to update child element"); goto fail; } g_free (sink->gsettings_str); sink->gsettings_str = new_string; return TRUE; fail: g_free (new_string); return FALSE; }
static gboolean gst_pulsesrc_open (GstAudioSrc * asrc) { GstPulseSrc *pulsesrc = GST_PULSESRC_CAST (asrc); gchar *name = gst_pulse_client_name (); pa_threaded_mainloop_lock (pulsesrc->mainloop); g_assert (!pulsesrc->context); g_assert (!pulsesrc->stream); GST_DEBUG_OBJECT (pulsesrc, "opening device"); if (!(pulsesrc->context = pa_context_new (pa_threaded_mainloop_get_api (pulsesrc->mainloop), name))) { GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, ("Failed to create context"), (NULL)); goto unlock_and_fail; } pa_context_set_state_callback (pulsesrc->context, gst_pulsesrc_context_state_cb, pulsesrc); GST_DEBUG_OBJECT (pulsesrc, "connect to server %s", GST_STR_NULL (pulsesrc->server)); if (pa_context_connect (pulsesrc->context, pulsesrc->server, 0, NULL) < 0) { GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, ("Failed to connect: %s", pa_strerror (pa_context_errno (pulsesrc->context))), (NULL)); goto unlock_and_fail; } for (;;) { pa_context_state_t state; state = pa_context_get_state (pulsesrc->context); if (!PA_CONTEXT_IS_GOOD (state)) { GST_ELEMENT_ERROR (pulsesrc, RESOURCE, FAILED, ("Failed to connect: %s", pa_strerror (pa_context_errno (pulsesrc->context))), (NULL)); goto unlock_and_fail; } if (state == PA_CONTEXT_READY) break; /* Wait until the context is ready */ pa_threaded_mainloop_wait (pulsesrc->mainloop); } GST_DEBUG_OBJECT (pulsesrc, "connected"); pa_threaded_mainloop_unlock (pulsesrc->mainloop); g_free (name); return TRUE; /* ERRORS */ unlock_and_fail: { gst_pulsesrc_destroy_context (pulsesrc); pa_threaded_mainloop_unlock (pulsesrc->mainloop); g_free (name); return FALSE; } }
/* 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; g_mutex_init (&conn->lock); g_cond_init (&conn->flush_cond); 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_clear (&conn->lock); g_free (conn->id); g_free (conn->server); g_free (conn); return NULL; } }
int main (int argc, char **argv) { GstBus *bus; GOptionContext *ctx; GIOChannel *io_stdin; GError *err = NULL; gboolean res; GOptionEntry options[] = { {NULL} }; GThread *rthread; /* Clear application state */ memset (state, 0, sizeof (*state)); state->animate = TRUE; /* must initialise the threading system before using any other GLib funtion */ if (!g_thread_supported ()) g_thread_init (NULL); ctx = g_option_context_new ("[ADDITIONAL ARGUMENTS]"); 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); if (argc != 2) { g_print ("Usage: %s <URI> or <PIPELINE-DESCRIPTION>\n", argv[0]); exit (1); } /* Initialize GStreamer */ gst_init (&argc, &argv); /* initialize inter thread comunnication */ init_intercom (state); TRACE_VC_MEMORY ("state 0"); if (!(rthread = g_thread_new ("render", (GThreadFunc) render_func, NULL))) { g_print ("Render thread create failed\n"); exit (1); } /* Initialize player */ if (gst_uri_is_valid (argv[1])) { res = init_playbin_player (state, argv[1]); } else { res = init_parse_launch_player (state, argv[1]); } if (!res) goto done; /* Create a GLib Main Loop and set it to run */ state->main_loop = g_main_loop_new (NULL, FALSE); /* Add a keyboard watch so we get notified of keystrokes */ io_stdin = g_io_channel_unix_new (fileno (stdin)); g_io_add_watch (io_stdin, G_IO_IN, (GIOFunc) handle_keyboard, state); g_io_channel_unref (io_stdin); /* *INDENT-OFF* */ g_print ("Available commands: \n" " a - Toggle animation \n" " p - Pause playback \n" " r - Resume playback \n" " l - Query position/duration\n" " f - Seek 30 seconds forward \n" " b - Seek 30 seconds backward \n" " q - Quit \n"); /* *INDENT-ON* */ /* Connect the bus handlers */ bus = gst_element_get_bus (state->pipeline); gst_bus_set_sync_handler (bus, (GstBusSyncHandler) bus_sync_handler, state, NULL); gst_bus_add_signal_watch_full (bus, G_PRIORITY_HIGH); gst_bus_enable_sync_message_emission (bus); g_signal_connect (G_OBJECT (bus), "message::error", (GCallback) error_cb, state); g_signal_connect (G_OBJECT (bus), "message::buffering", (GCallback) buffering_cb, state); g_signal_connect (G_OBJECT (bus), "message::eos", (GCallback) eos_cb, state); g_signal_connect (G_OBJECT (bus), "message::qos", (GCallback) qos_cb, state); g_signal_connect (G_OBJECT (bus), "message::state-changed", (GCallback) state_changed_cb, state); gst_object_unref (bus); /* Make player start playing */ gst_element_set_state (state->pipeline, GST_STATE_PLAYING); /* Start the mainloop */ state->main_loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (state->main_loop); done: /* Release pipeline */ if (state->pipeline) { gst_element_set_state (state->pipeline, GST_STATE_NULL); if (state->vsink) { gst_object_unref (state->vsink); state->vsink = NULL; } gst_object_unref (state->pipeline); } /* Unref the mainloop */ if (state->main_loop) { g_main_loop_unref (state->main_loop); } /* Stop rendering thread */ state->running = FALSE; g_thread_join (rthread); terminate_intercom (state); TRACE_VC_MEMORY ("at exit"); return 0; }
static gboolean gst_rtp_L16_depay_setcaps (GstRTPBaseDepayload * depayload, GstCaps * caps) { GstStructure *structure; GstRtpL16Depay *rtpL16depay; gint clock_rate, payload; gint channels; GstCaps *srccaps; gboolean res; const gchar *channel_order; const GstRTPChannelOrder *order; GstAudioInfo *info; rtpL16depay = GST_RTP_L16_DEPAY (depayload); structure = gst_caps_get_structure (caps, 0); payload = 96; gst_structure_get_int (structure, "payload", &payload); switch (payload) { case GST_RTP_PAYLOAD_L16_STEREO: channels = 2; clock_rate = 44100; break; case GST_RTP_PAYLOAD_L16_MONO: channels = 1; clock_rate = 44100; break; default: /* no fixed mapping, we need clock-rate */ channels = 0; clock_rate = 0; break; } /* caps can overwrite defaults */ clock_rate = gst_rtp_L16_depay_parse_int (structure, "clock-rate", clock_rate); if (clock_rate == 0) goto no_clockrate; channels = gst_rtp_L16_depay_parse_int (structure, "encoding-params", channels); if (channels == 0) { channels = gst_rtp_L16_depay_parse_int (structure, "channels", channels); if (channels == 0) { /* channels defaults to 1 otherwise */ channels = 1; } } depayload->clock_rate = clock_rate; info = &rtpL16depay->info; gst_audio_info_init (info); info->finfo = gst_audio_format_get_info (GST_AUDIO_FORMAT_S16BE); info->rate = clock_rate; info->channels = channels; info->bpf = (info->finfo->width / 8) * channels; /* add channel positions */ channel_order = gst_structure_get_string (structure, "channel-order"); order = gst_rtp_channels_get_by_order (channels, channel_order); rtpL16depay->order = order; if (order) { memcpy (info->position, order->pos, sizeof (GstAudioChannelPosition) * channels); gst_audio_channel_positions_to_valid_order (info->position, info->channels); } else { GST_ELEMENT_WARNING (rtpL16depay, STREAM, DECODE, (NULL), ("Unknown channel order '%s' for %d channels", GST_STR_NULL (channel_order), channels)); /* create default NONE layout */ gst_rtp_channels_create_default (channels, info->position); } srccaps = gst_audio_info_to_caps (info); res = gst_pad_set_caps (depayload->srcpad, srccaps); gst_caps_unref (srccaps); return res; /* ERRORS */ no_clockrate: { GST_ERROR_OBJECT (depayload, "no clock-rate specified"); return FALSE; } }
static gboolean gst_amc_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps) { GstAmcAudioDec *self; GstStructure *s; GstAmcFormat *format; const gchar *mime; gboolean is_format_change = FALSE; gboolean needs_disable = FALSE; gchar *format_string; gint rate, channels; GError *err = NULL; self = GST_AMC_AUDIO_DEC (decoder); GST_DEBUG_OBJECT (self, "Setting new caps %" GST_PTR_FORMAT, caps); /* Check if the caps change is a real format change or if only irrelevant * parts of the caps have changed or nothing at all. */ is_format_change |= (!self->input_caps || !gst_caps_is_equal (self->input_caps, caps)); needs_disable = self->started; /* If the component is not started and a real format change happens * we have to restart the component. If no real format change * happened we can just exit here. */ if (needs_disable && !is_format_change) { /* Framerate or something minor changed */ self->input_caps_changed = TRUE; GST_DEBUG_OBJECT (self, "Already running and caps did not change the format"); return TRUE; } if (needs_disable && is_format_change) { gst_amc_audio_dec_drain (self); GST_AUDIO_DECODER_STREAM_UNLOCK (self); gst_amc_audio_dec_stop (GST_AUDIO_DECODER (self)); GST_AUDIO_DECODER_STREAM_LOCK (self); gst_amc_audio_dec_close (GST_AUDIO_DECODER (self)); if (!gst_amc_audio_dec_open (GST_AUDIO_DECODER (self))) { GST_ERROR_OBJECT (self, "Failed to open codec again"); return FALSE; } if (!gst_amc_audio_dec_start (GST_AUDIO_DECODER (self))) { GST_ERROR_OBJECT (self, "Failed to start codec again"); } } /* srcpad task is not running at this point */ mime = caps_to_mime (caps); if (!mime) { GST_ERROR_OBJECT (self, "Failed to convert caps to mime"); return FALSE; } s = gst_caps_get_structure (caps, 0); if (!gst_structure_get_int (s, "rate", &rate) || !gst_structure_get_int (s, "channels", &channels)) { GST_ERROR_OBJECT (self, "Failed to get rate/channels"); return FALSE; } format = gst_amc_format_new_audio (mime, rate, channels, &err); if (!format) { GST_ELEMENT_ERROR_FROM_ERROR (self, err); return FALSE; } /* FIXME: These buffers needs to be valid until the codec is stopped again */ g_list_foreach (self->codec_datas, (GFunc) gst_buffer_unref, NULL); g_list_free (self->codec_datas); self->codec_datas = NULL; if (gst_structure_has_field (s, "codec_data")) { const GValue *h = gst_structure_get_value (s, "codec_data"); GstBuffer *codec_data = gst_value_get_buffer (h); GstMapInfo minfo; guint8 *data; gst_buffer_map (codec_data, &minfo, GST_MAP_READ); data = g_memdup (minfo.data, minfo.size); self->codec_datas = g_list_prepend (self->codec_datas, data); gst_amc_format_set_buffer (format, "csd-0", data, minfo.size, &err); if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); gst_buffer_unmap (codec_data, &minfo); } else if (gst_structure_has_field (s, "streamheader")) { const GValue *sh = gst_structure_get_value (s, "streamheader"); gint nsheaders = gst_value_array_get_size (sh); GstBuffer *buf; const GValue *h; gint i, j; gchar *fname; GstMapInfo minfo; guint8 *data; for (i = 0, j = 0; i < nsheaders; i++) { h = gst_value_array_get_value (sh, i); buf = gst_value_get_buffer (h); if (strcmp (mime, "audio/vorbis") == 0) { guint8 header_type; gst_buffer_extract (buf, 0, &header_type, 1); /* Only use the identification and setup packets */ if (header_type != 0x01 && header_type != 0x05) continue; } fname = g_strdup_printf ("csd-%d", j); gst_buffer_map (buf, &minfo, GST_MAP_READ); data = g_memdup (minfo.data, minfo.size); self->codec_datas = g_list_prepend (self->codec_datas, data); gst_amc_format_set_buffer (format, fname, data, minfo.size, &err); if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); gst_buffer_unmap (buf, &minfo); g_free (fname); j++; } } format_string = gst_amc_format_to_string (format, &err); if (err) GST_ELEMENT_WARNING_FROM_ERROR (self, err); GST_DEBUG_OBJECT (self, "Configuring codec with format: %s", GST_STR_NULL (format_string)); g_free (format_string); if (!gst_amc_codec_configure (self->codec, format, 0, &err)) { GST_ERROR_OBJECT (self, "Failed to configure codec"); GST_ELEMENT_ERROR_FROM_ERROR (self, err); return FALSE; } gst_amc_format_free (format); if (!gst_amc_codec_start (self->codec, &err)) { GST_ERROR_OBJECT (self, "Failed to start codec"); GST_ELEMENT_ERROR_FROM_ERROR (self, err); return FALSE; } self->spf = -1; /* TODO: Implement for other codecs too */ if (gst_structure_has_name (s, "audio/mpeg")) { gint mpegversion = -1; gst_structure_get_int (s, "mpegversion", &mpegversion); if (mpegversion == 1) { gint layer = -1, mpegaudioversion = -1; gst_structure_get_int (s, "layer", &layer); gst_structure_get_int (s, "mpegaudioversion", &mpegaudioversion); if (layer == 1) self->spf = 384; else if (layer == 2) self->spf = 1152; else if (layer == 3 && mpegaudioversion != -1) self->spf = (mpegaudioversion == 1 ? 1152 : 576); } } self->started = TRUE; self->input_caps_changed = TRUE; /* Start the srcpad loop again */ self->flushing = FALSE; self->downstream_flow_ret = GST_FLOW_OK; gst_pad_start_task (GST_AUDIO_DECODER_SRC_PAD (self), (GstTaskFunction) gst_amc_audio_dec_loop, decoder, NULL); return TRUE; }
static gboolean do_toggle_element (GstGConfVideoSink * sink) { GstPad *targetpad; gchar *new_gconf_str; GstState cur, next; new_gconf_str = gst_gconf_get_string (GST_GCONF_VIDEOSINK_KEY); if (new_gconf_str != NULL && sink->gconf_str != NULL && (strlen (new_gconf_str) == 0 || strcmp (sink->gconf_str, new_gconf_str) == 0)) { g_free (new_gconf_str); GST_DEBUG_OBJECT (sink, "GConf key was updated, but it didn't change"); return TRUE; } /* Sometime, it would be lovely to allow sink changes even when * already running, but this involves sending an appropriate new-segment * and possibly prerolling etc */ GST_OBJECT_LOCK (sink); cur = GST_STATE (sink); next = GST_STATE_PENDING (sink); GST_OBJECT_UNLOCK (sink); if (cur > GST_STATE_READY || next == GST_STATE_PAUSED) { GST_DEBUG_OBJECT (sink, "Auto-sink is already running. Ignoring GConf change"); g_free (new_gconf_str); return TRUE; } GST_DEBUG_OBJECT (sink, "GConf key changed: '%s' to '%s'", GST_STR_NULL (sink->gconf_str), GST_STR_NULL (new_gconf_str)); g_free (sink->gconf_str); sink->gconf_str = new_gconf_str; /* kill old element */ if (sink->kid) { GST_DEBUG_OBJECT (sink, "Removing old kid"); gst_element_set_state (sink->kid, GST_STATE_NULL); gst_bin_remove (GST_BIN (sink), sink->kid); sink->kid = NULL; } GST_DEBUG_OBJECT (sink, "Creating new kid"); if (!(sink->kid = gst_gconf_get_default_video_sink ())) { GST_ELEMENT_ERROR (sink, LIBRARY, SETTINGS, (NULL), ("Failed to render video sink from GConf")); return FALSE; } gst_element_set_state (sink->kid, GST_STATE (sink)); gst_bin_add (GST_BIN (sink), sink->kid); /* re-attach ghostpad */ GST_DEBUG_OBJECT (sink, "Creating new ghostpad"); targetpad = gst_element_get_static_pad (sink->kid, "sink"); gst_ghost_pad_set_target (GST_GHOST_PAD (sink->pad), targetpad); gst_object_unref (targetpad); GST_DEBUG_OBJECT (sink, "done changing gconf video sink"); return TRUE; }
GstMixerOptions * gst_sunaudiomixer_options_new (GstSunAudioMixerCtrl * mixer, gint track_num) { GstMixerOptions *opts; GstSunAudioMixerOptions *sun_opts; GstMixerTrack *track; const gchar *label; gint i; struct audio_info audioinfo; if ((mixer == NULL) || (mixer->mixer_fd == -1)) { g_warning ("mixer not initialized"); return NULL; } if (track_num != GST_SUNAUDIO_TRACK_RECSRC) { g_warning ("invalid options track"); return (NULL); } label = N_("Record Source"); opts = g_object_new (GST_TYPE_SUNAUDIO_MIXER_OPTIONS, "untranslated-label", label, NULL); sun_opts = GST_SUNAUDIO_MIXER_OPTIONS (opts); track = GST_MIXER_TRACK (opts); GST_DEBUG_OBJECT (opts, "New mixer options, track %d: %s", track_num, GST_STR_NULL (label)); /* save off names for the record sources */ sun_opts->names[0] = g_quark_from_string (_("Microphone")); sun_opts->names[1] = g_quark_from_string (_("Line In")); sun_opts->names[2] = g_quark_from_string (_("Internal CD")); sun_opts->names[3] = g_quark_from_string (_("SPDIF In")); sun_opts->names[4] = g_quark_from_string (_("AUX 1 In")); sun_opts->names[5] = g_quark_from_string (_("AUX 2 In")); sun_opts->names[6] = g_quark_from_string (_("Codec Loopback")); sun_opts->names[7] = g_quark_from_string (_("SunVTS Loopback")); /* set basic information */ track->label = g_strdup (_(label)); track->num_channels = 0; track->min_volume = 0; track->max_volume = 0; track->flags = GST_MIXER_TRACK_INPUT | GST_MIXER_TRACK_WHITELIST | GST_MIXER_TRACK_NO_RECORD; if (ioctl (mixer->mixer_fd, AUDIO_GETINFO, &audioinfo) < 0) { g_warning ("Error getting audio device settings"); g_object_unref (G_OBJECT (sun_opts)); return NULL; } sun_opts->avail = audioinfo.record.avail_ports; sun_opts->track_num = track_num; for (i = 0; i < 8; i++) { if ((1 << i) & audioinfo.record.avail_ports) { const char *s = g_quark_to_string (sun_opts->names[i]); opts->values = g_list_append (opts->values, g_strdup (s)); GST_DEBUG_OBJECT (opts, "option for track %d: %s", track_num, GST_STR_NULL (s)); } } return opts; }
/* returns TRUE if there was an error or we caught a keyboard interrupt. */ static gboolean event_loop (GstElement * pipeline, gboolean blocking, GstState target_state) { GstBus *bus; GstMessage *message = NULL; gboolean res = FALSE; gboolean buffering = FALSE; bus = gst_element_get_bus (GST_ELEMENT (pipeline)); #ifndef DISABLE_FAULT_HANDLER g_timeout_add (50, (GSourceFunc) check_intr, pipeline); #endif while (TRUE) { message = gst_bus_poll (bus, GST_MESSAGE_ANY, blocking ? -1 : 0); /* if the poll timed out, only when !blocking */ if (message == NULL) goto exit; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_NEW_CLOCK: { GstClock *clock; gst_message_parse_new_clock (message, &clock); g_print ("New clock: %s\n", (clock ? GST_OBJECT_NAME (clock) : "NULL")); break; } case GST_MESSAGE_EOS: g_print ("Got EOS from element \"%s\".\n", GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)))); goto exit; case GST_MESSAGE_TAG: if (tags) { GstTagList *tags; gst_message_parse_tag (message, &tags); g_print ("FOUND TAG : found by element \"%s\".\n", GST_STR_NULL (GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)))); gst_tag_list_foreach (tags, print_tag, NULL); gst_tag_list_free (tags); } break; case GST_MESSAGE_INFO:{ GError *gerror; gchar *debug; gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (message)); gst_message_parse_info (message, &gerror, &debug); if (debug) { g_print ("INFO:\n%s\n", debug); } g_error_free (gerror); g_free (debug); g_free (name); break; } case GST_MESSAGE_WARNING:{ GError *gerror; gchar *debug; gchar *name = gst_object_get_path_string (GST_MESSAGE_SRC (message)); /* dump graph on warning */ GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "gst-launch.warning"); gst_message_parse_warning (message, &gerror, &debug); g_print ("WARNING: from element %s: %s\n", name, gerror->message); if (debug) { g_print ("Additional debug info:\n%s\n", debug); } g_error_free (gerror); g_free (debug); g_free (name); break; } case GST_MESSAGE_ERROR:{ GError *gerror; gchar *debug; /* dump graph on error */ GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, "gst-launch.error"); gst_message_parse_error (message, &gerror, &debug); gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug); g_error_free (gerror); g_free (debug); /* we have an error */ res = TRUE; goto exit; } case GST_MESSAGE_STATE_CHANGED:{ GstState old, newX, pending; gst_message_parse_state_changed (message, &old, &newX, &pending); /* we only care about pipeline state change messages */ if (GST_MESSAGE_SRC (message) != GST_OBJECT_CAST (pipeline)) break; /* dump graph for pipeline state changes */ { gchar *dump_name = g_strdup_printf ("gst-launch.%s_%s", gst_element_state_get_name (old), gst_element_state_get_name (newX)); GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (pipeline), GST_DEBUG_GRAPH_SHOW_ALL, dump_name); g_free (dump_name); } /* ignore when we are buffering since then we mess with the states * ourselves. */ if (buffering) { fprintf (stderr, "Prerolled, waiting for buffering to finish...\n"); break; } /* if we reached the final target state, exit */ if (target_state == GST_STATE_PAUSED && newX == target_state) goto exit; /* else not an interesting message */ break; } case GST_MESSAGE_BUFFERING:{ gint percent; gst_message_parse_buffering (message, &percent); fprintf (stderr, "%s %d%% \r", "buffering...", percent); /* no state management needed for live pipelines */ if (is_live) break; if (percent == 100) { /* a 100% message means buffering is done */ buffering = FALSE; /* if the desired state is playing, go back */ if (target_state == GST_STATE_PLAYING) { fprintf (stderr, "Done buffering, setting pipeline to PLAYING ...\n"); gst_element_set_state (pipeline, GST_STATE_PLAYING); } else goto exit; } else { /* buffering busy */ if (buffering == FALSE && target_state == GST_STATE_PLAYING) { /* we were not buffering but PLAYING, PAUSE the pipeline. */ fprintf (stderr, "Buffering, setting pipeline to PAUSED ...\n"); gst_element_set_state (pipeline, GST_STATE_PAUSED); } buffering = TRUE; } break; } case GST_MESSAGE_LATENCY: { fprintf (stderr, "Redistribute latency...\n"); gst_bin_recalculate_latency (GST_BIN (pipeline)); break; } case GST_MESSAGE_APPLICATION:{ const GstStructure *s; s = gst_message_get_structure (message); if (gst_structure_has_name (s, "GstLaunchInterrupt")) { /* this application message is posted when we caught an interrupt and * we need to stop the pipeline. */ fprintf (stderr, "Interrupt: Stopping pipeline ...\n"); /* return TRUE when we caught an interrupt */ res = TRUE; goto exit; } } default: /* just be quiet by default */ break; } if (message) gst_message_unref (message); } g_assert_not_reached (); exit: { if (message) gst_message_unref (message); gst_object_unref (bus); return res; } }
static gboolean gst_cd_paranoia_src_open (GstAudioCdSrc * audiocdsrc, const gchar * device) { GstCdParanoiaSrc *src = GST_CD_PARANOIA_SRC (audiocdsrc); gint i, cache_size; GST_DEBUG_OBJECT (src, "trying to open device %s (generic-device=%s) ...", device, GST_STR_NULL (src->generic_device)); /* find the device */ if (src->generic_device != NULL) { src->d = cdda_identify_scsi (src->generic_device, device, FALSE, NULL); } else { if (device != NULL) { src->d = cdda_identify (device, FALSE, NULL); } else { src->d = cdda_identify ("/dev/cdrom", FALSE, NULL); } } /* fail if the device couldn't be found */ if (src->d == NULL) goto no_device; /* set verbosity mode */ cdda_verbose_set (src->d, CDDA_MESSAGE_FORGETIT, CDDA_MESSAGE_FORGETIT); /* open the disc */ if (cdda_open (src->d)) goto open_failed; GST_INFO_OBJECT (src, "set read speed to %d", src->read_speed); cdda_speed_set (src->d, src->read_speed); for (i = 1; i < src->d->tracks + 1; i++) { GstAudioCdSrcTrack track = { 0, }; track.num = i; track.is_audio = IS_AUDIO (src->d, i - 1); track.start = cdda_track_firstsector (src->d, i); track.end = cdda_track_lastsector (src->d, i); track.tags = NULL; gst_audio_cd_src_add_track (GST_AUDIO_CD_SRC (src), &track); } /* create the paranoia struct and set it up */ src->p = paranoia_init (src->d); if (src->p == NULL) goto init_failed; paranoia_modeset (src->p, src->paranoia_mode); GST_INFO_OBJECT (src, "set paranoia mode to 0x%02x", src->paranoia_mode); if (src->search_overlap != -1) { paranoia_overlapset (src->p, src->search_overlap); GST_INFO_OBJECT (src, "search overlap set to %u", src->search_overlap); } cache_size = src->cache_size; if (cache_size == -1) { /* if paranoia mode is low (the default), assume we're doing playback */ if (src->paranoia_mode <= PARANOIA_MODE_FRAGMENT) cache_size = 150; else cache_size = paranoia_cachemodel_size (src->p, -1); } paranoia_cachemodel_size (src->p, cache_size); GST_INFO_OBJECT (src, "set cachemodel size to %u", cache_size); src->next_sector = -1; return TRUE; /* ERRORS */ no_device: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (_("Could not open CD device for reading.")), ("cdda_identify failed")); return FALSE; } open_failed: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (_("Could not open CD device for reading.")), ("cdda_open failed")); cdda_close (src->d); src->d = NULL; return FALSE; } init_failed: { GST_ELEMENT_ERROR (src, LIBRARY, INIT, ("failed to initialize paranoia"), ("failed to initialize paranoia")); return FALSE; } }
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; }
int main (int argc, char **argv) { GPtrArray *files; gchar **args = NULL; guint num, i; GError *err = NULL; GOptionContext *ctx; GOptionEntry options[] = { {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &args, NULL}, {NULL} }; GTimer *timer; if (!g_thread_supported ()) g_thread_init (NULL); ctx = g_option_context_new ("FILES OR DIRECTORIES WITH AUDIO FILES"); 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); if (args == NULL || *args == NULL) { g_print ("Please provide one or more directories with audio files\n\n"); return 1; } files = g_ptr_array_new (); num = g_strv_length (args); for (i = 0; i < num; ++i) { if (g_path_is_absolute (args[i])) { check_arg (files, args[i]); } else { g_warning ("Argument '%s' is not an absolute file path", args[i]); } } if (files->len == 0) { g_print ("Did not find any files\n\n"); return 1; } timer = g_timer_new (); while (g_timer_elapsed (timer, NULL) < TEST_RUNTIME) { gint32 idx; idx = g_random_int_range (0, files->len); play_file ((const gchar *) g_ptr_array_index (files, idx)); } g_strfreev (args); g_timer_destroy (timer); return 0; }
static GstFlowReturn gst_test_http_src_create (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer ** retbuf) { GstTestHTTPSrc *src = GST_TEST_HTTP_SRC (basesrc); guint bytes_read; GstFlowReturn ret = GST_FLOW_OK; guint blocksize; fail_unless (gst_test_http_src_callbacks != NULL); fail_unless (gst_test_http_src_callbacks->src_create != NULL); GST_OBJECT_LOCK (src); blocksize = basesrc->blocksize; GST_OBJECT_UNLOCK (src); g_mutex_lock (&src->mutex); GST_DEBUG ("gst_test_http_src_create feeding from %" G_GUINT64_FORMAT, src->position); if (src->uri == NULL) { GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM); g_mutex_unlock (&src->mutex); return GST_FLOW_ERROR; } if (src->input.status_code < 200 || src->input.status_code >= 300) { GST_ELEMENT_ERROR (src, RESOURCE, NOT_FOUND, ("%s", "Generated requested error"), ("%s (%d), URL: %s, Redirect to: %s", "Generated requested error", src->input.status_code, src->uri, GST_STR_NULL (NULL))); g_mutex_unlock (&src->mutex); return GST_FLOW_ERROR; } if (src->http_method == METHOD_INVALID) { GST_ELEMENT_ERROR (src, RESOURCE, READ, ("%s", "Invalid HTTP method"), ("%s (%s), URL: %s", "Invalid HTTP method", src->http_method_name, src->uri)); g_mutex_unlock (&src->mutex); return GST_FLOW_ERROR; } else if (src->http_method == METHOD_HEAD) { ret = GST_FLOW_EOS; goto http_events; } fail_unless_equals_uint64 (offset, src->position); bytes_read = MIN ((src->segment_end - src->position), blocksize); if (bytes_read == 0) { ret = GST_FLOW_EOS; goto http_events; } ret = gst_test_http_src_callbacks->src_create (src, offset, bytes_read, retbuf, src->input.context, gst_test_http_src_callback_user_data); if (ret != GST_FLOW_OK) { goto http_events; } GST_BUFFER_OFFSET (*retbuf) = src->position; GST_BUFFER_OFFSET_END (*retbuf) = src->position + bytes_read; src->position += bytes_read; http_events: if (src->http_headers_event) { gst_pad_push_event (GST_BASE_SRC_PAD (src), src->http_headers_event); src->http_headers_event = NULL; } if (src->duration_changed) { src->duration_changed = FALSE; gst_element_post_message (GST_ELEMENT (src), gst_message_new_duration_changed (GST_OBJECT (src))); } g_mutex_unlock (&src->mutex); return ret; }
gint main (gint argc, gchar * argv[]) { GstStateChangeReturn ret; GstElement *pipeline; GstElement *filter, *sink; GstElement *sourcebin; GError *error = NULL; GtkWidget *window; GtkWidget *screen; GtkWidget *vbox, *combo; GtkWidget *hbox; GtkWidget *play, *pause, *null, *ready; gchar **source_desc_array = NULL; gchar *source_desc = NULL; GOptionContext *context; GOptionEntry options[] = { {"source-bin", 's', 0, G_OPTION_ARG_STRING_ARRAY, &source_desc_array, "Use a custom source bin description (gst-launch style)", NULL} , {NULL} }; context = g_option_context_new (NULL); g_option_context_add_main_entries (context, options, NULL); g_option_context_add_group (context, gst_init_get_option_group ()); g_option_context_add_group (context, gtk_get_option_group (TRUE)); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_print ("Inizialization error: %s\n", GST_STR_NULL (error->message)); return -1; } g_option_context_free (context); if (source_desc_array != NULL) { source_desc = g_strjoinv (" ", source_desc_array); g_strfreev (source_desc_array); } if (source_desc == NULL) { source_desc = g_strdup ("videotestsrc ! video/x-raw, width=352, height=288 ! identity"); } sourcebin = gst_parse_bin_from_description (g_strdup (source_desc), TRUE, &error); g_free (source_desc); if (error) { g_print ("Error while parsing source bin description: %s\n", GST_STR_NULL (error->message)); return -1; } g_set_application_name ("gst-gl-effects test app"); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_container_set_border_width (GTK_CONTAINER (window), 3); pipeline = gst_pipeline_new ("pipeline"); filter = gst_element_factory_make ("gleffects", "flt"); sink = gst_element_factory_make ("glimagesink", "glsink"); gst_bin_add_many (GST_BIN (pipeline), sourcebin, filter, sink, NULL); if (!gst_element_link_many (sourcebin, filter, sink, NULL)) { g_print ("Failed to link one or more elements!\n"); return -1; } g_signal_connect (G_OBJECT (window), "delete-event", G_CALLBACK (destroy_cb), pipeline); g_signal_connect (G_OBJECT (window), "destroy-event", G_CALLBACK (destroy_cb), pipeline); screen = gtk_drawing_area_new (); gtk_widget_set_size_request (screen, 640, 480); // 500 x 376 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2); gtk_box_pack_start (GTK_BOX (vbox), screen, TRUE, TRUE, 0); combo = gtk_combo_box_text_new (); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "identity"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "mirror"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "squeeze"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "stretch"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "fisheye"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "twirl"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "bulge"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "tunnel"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "square"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "heat"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "xpro"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "lumaxpro"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "sepia"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "xray"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "sin"); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (combo), "glow"); g_signal_connect (G_OBJECT (combo), "changed", G_CALLBACK (apply_fx), filter); gtk_box_pack_start (GTK_BOX (vbox), combo, FALSE, FALSE, 0); hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); play = gtk_button_new_with_label ("PLAY"); g_signal_connect (G_OBJECT (play), "clicked", G_CALLBACK (play_cb), pipeline); pause = gtk_button_new_with_label ("PAUSE"); g_signal_connect (G_OBJECT (pause), "clicked", G_CALLBACK (pause_cb), pipeline); null = gtk_button_new_with_label ("NULL"); g_signal_connect (G_OBJECT (null), "clicked", G_CALLBACK (null_cb), pipeline); ready = gtk_button_new_with_label ("READY"); g_signal_connect (G_OBJECT (ready), "clicked", G_CALLBACK (ready_cb), pipeline); gtk_box_pack_start (GTK_BOX (hbox), null, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (hbox), ready, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (hbox), play, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (hbox), pause, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); gtk_container_add (GTK_CONTAINER (window), vbox); g_signal_connect (screen, "realize", G_CALLBACK (expose_cb), pipeline); ret = gst_element_set_state (pipeline, GST_STATE_PLAYING); if (ret == GST_STATE_CHANGE_FAILURE) { g_print ("Failed to start up pipeline!\n"); return -1; } gtk_widget_show_all (GTK_WIDGET (window)); gtk_main (); return 0; }
/* open the file, necessary to go to RUNNING state */ static gboolean gst_vcdsrc_start (GstBaseSrc * bsrc) { int i; GstVCDSrc *src = GST_VCDSRC (bsrc); struct stat buf; /* open the device */ src->fd = open (src->device, O_RDONLY); if (src->fd < 0) goto open_failed; if (fstat (src->fd, &buf) < 0) goto toc_failed; /* If it's not a block device, then we need to try and * parse the cue file if there is one * FIXME implement */ if (!S_ISBLK (buf.st_mode)) { GST_DEBUG ("Reading CUE files not handled yet, cannot process %s", GST_STR_NULL (src->device)); goto toc_failed; } /* read the table of contents */ if (ioctl (src->fd, CDROMREADTOCHDR, &src->tochdr)) goto toc_failed; /* allocate enough track structs for disk */ src->numtracks = (src->tochdr.cdth_trk1 - src->tochdr.cdth_trk0) + 1; src->tracks = g_new (struct cdrom_tocentry, src->numtracks + 1); /* read each track entry */ for (i = 0; i <= src->numtracks; i++) { src->tracks[i].cdte_track = i == src->numtracks ? CDROM_LEADOUT : i + 1; src->tracks[i].cdte_format = CDROM_MSF; if (ioctl (src->fd, CDROMREADTOCENTRY, &src->tracks[i])) goto toc_entry_failed; GST_DEBUG ("track %d begins at %d:%02d.%02d", i, src->tracks[i].cdte_addr.msf.minute, src->tracks[i].cdte_addr.msf.second, src->tracks[i].cdte_addr.msf.frame); } src->curoffset = 0; gst_vcdsrc_recalculate (src); return TRUE; /* ERRORS */ open_failed: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM); return FALSE; } toc_failed: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM); close (src->fd); return FALSE; } toc_entry_failed: { GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, (NULL), GST_ERROR_SYSTEM); g_free (src->tracks); close (src->fd); return FALSE; } }
GstElement *mmsGstLaunch(const char *pipeline_description) { GError *error = NULL; gint res = 0; #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); #endif if (!g_thread_supported ()) g_thread_init (NULL); gst_alloc_trace_set_flags_all (GST_ALLOC_TRACE_LIVE); #ifndef DISABLE_FAULT_HANDLER fault_setup (); sigint_setup (); play_signal_setup (); #endif // parse the pipeline description pipeline = gst_parse_launch(pipeline_description, &error); if (!pipeline) { if (error) { fprintf (stderr, "ERROR: pipeline could not be constructed: %s.\n", GST_STR_NULL (error->message)); g_error_free (error); } else { fprintf (stderr, "ERROR: pipeline could not be constructed.\n"); } return NULL; } else if (error) { fprintf (stderr, "WARNING: erroneous pipeline: %s\n", GST_STR_NULL (error->message)); g_error_free (error); return NULL; } GstState state; GstStateChangeReturn ret; /* If the top-level object is not a pipeline, place it in a pipeline. */ if (!GST_IS_PIPELINE (pipeline)) { GstElement *real_pipeline = gst_element_factory_make ("pipeline", NULL); if (real_pipeline == NULL) { fprintf (stderr, "ERROR: the 'pipeline' element wasn't found.\n"); return NULL; } gst_bin_add (GST_BIN (real_pipeline), pipeline); pipeline = real_pipeline; } fprintf (stderr, "Setting pipeline to PAUSED ...\n"); ret = gst_element_set_state (pipeline, GST_STATE_PAUSED); switch (ret) { case GST_STATE_CHANGE_FAILURE: fprintf (stderr, "ERROR: Pipeline doesn't want to pause.\n"); res = -1; event_loop (pipeline, FALSE, GST_STATE_VOID_PENDING); goto end; case GST_STATE_CHANGE_NO_PREROLL: fprintf (stderr, "Pipeline is live and does not need PREROLL ...\n"); is_live = TRUE; break; case GST_STATE_CHANGE_ASYNC: fprintf (stderr, "Pipeline is PREROLLING ...\n"); caught_error = event_loop (pipeline, TRUE, GST_STATE_PAUSED); if (caught_error) { fprintf (stderr, "ERROR: pipeline doesn't want to preroll.\n"); goto end; } state = GST_STATE_PAUSED; // fallthrough case GST_STATE_CHANGE_SUCCESS: fprintf (stderr, "Pipeline is PREROLLED ...\n"); break; } // pipe successfully created return pipeline; end: mmsGstFree(); return NULL; }
static gboolean wildmidi_open_config (void) { gchar *path = g_strdup (g_getenv ("WILDMIDI_CFG")); gint ret; GST_DEBUG ("trying %s", GST_STR_NULL (path)); if (path && (g_access (path, R_OK) == -1)) { g_free (path); path = NULL; } if (path == NULL) { path = g_build_path (G_DIR_SEPARATOR_S, g_get_home_dir (), ".wildmidirc", NULL); GST_DEBUG ("trying %s", path); if (path && (g_access (path, R_OK) == -1)) { g_free (path); path = NULL; } } if (path == NULL) { path = g_build_path (G_DIR_SEPARATOR_S, G_DIR_SEPARATOR_S "etc", "wildmidi.cfg", NULL); GST_DEBUG ("trying %s", path); if (path && (g_access (path, R_OK) == -1)) { g_free (path); path = NULL; } } if (path == NULL) { path = g_build_path (G_DIR_SEPARATOR_S, G_DIR_SEPARATOR_S "etc", "wildmidi", "wildmidi.cfg", NULL); GST_DEBUG ("trying %s", path); if (path && (g_access (path, R_OK) == -1)) { g_free (path); path = NULL; } } if (path == NULL) { path = g_strdup (WILDMIDI_CFG); GST_DEBUG ("trying %s", path); if (path && (g_access (path, R_OK) == -1)) { g_free (path); path = NULL; } } if (path == NULL) { path = g_build_path (G_DIR_SEPARATOR_S, G_DIR_SEPARATOR_S "etc", "timidity.cfg", NULL); GST_DEBUG ("trying %s", path); if (path && (g_access (path, R_OK) == -1)) { g_free (path); path = NULL; } } if (path == NULL) { path = g_build_path (G_DIR_SEPARATOR_S, G_DIR_SEPARATOR_S "etc", "timidity", "timidity.cfg", NULL); GST_DEBUG ("trying %s", path); if (path && (g_access (path, R_OK) == -1)) { g_free (path); path = NULL; } } if (path == NULL) { /* I've created a symlink to get it playing * ln -s /usr/share/timidity/timidity.cfg /etc/wildmidi.cfg * we could make it use : WILDMIDI_CFG * but unfortunately it fails to create a proper filename if the config * has a redirect * http://sourceforge.net/tracker/index.php?func=detail&aid=1657358&group_id=42635&atid=433744 */ GST_WARNING ("no config file, can't initialise"); return FALSE; } /* this also initializes a some filter and stuff and thus is slow */ ret = WildMidi_Init (path, WILDMIDI_RATE, 0); g_free (path); return (ret == 0); }
static GstFlowReturn gst_rdt_manager_chain_rtcp (GstPad * pad, GstObject * parent, GstBuffer * buffer) { GstRDTManager *src; #ifdef HAVE_RTCP gboolean valid; GstRTCPPacket packet; gboolean more; #endif src = GST_RDT_MANAGER (parent); GST_DEBUG_OBJECT (src, "got rtcp packet"); #ifdef HAVE_RTCP valid = gst_rtcp_buffer_validate (buffer); if (!valid) goto bad_packet; /* position on first packet */ more = gst_rtcp_buffer_get_first_packet (buffer, &packet); while (more) { switch (gst_rtcp_packet_get_type (&packet)) { case GST_RTCP_TYPE_SR: { guint32 ssrc, rtptime, packet_count, octet_count; guint64 ntptime; guint count, i; gst_rtcp_packet_sr_get_sender_info (&packet, &ssrc, &ntptime, &rtptime, &packet_count, &octet_count); GST_DEBUG_OBJECT (src, "got SR packet: SSRC %08x, NTP %" G_GUINT64_FORMAT ", RTP %u, PC %u, OC %u", ssrc, ntptime, rtptime, packet_count, octet_count); count = gst_rtcp_packet_get_rb_count (&packet); for (i = 0; i < count; i++) { guint32 ssrc, exthighestseq, jitter, lsr, dlsr; guint8 fractionlost; gint32 packetslost; gst_rtcp_packet_get_rb (&packet, i, &ssrc, &fractionlost, &packetslost, &exthighestseq, &jitter, &lsr, &dlsr); GST_DEBUG_OBJECT (src, "got RB packet %d: SSRC %08x, FL %u" ", PL %u, HS %u, JITTER %u, LSR %u, DLSR %u", ssrc, fractionlost, packetslost, exthighestseq, jitter, lsr, dlsr); } break; } case GST_RTCP_TYPE_RR: { guint32 ssrc; guint count, i; ssrc = gst_rtcp_packet_rr_get_ssrc (&packet); GST_DEBUG_OBJECT (src, "got RR packet: SSRC %08x", ssrc); count = gst_rtcp_packet_get_rb_count (&packet); for (i = 0; i < count; i++) { guint32 ssrc, exthighestseq, jitter, lsr, dlsr; guint8 fractionlost; gint32 packetslost; gst_rtcp_packet_get_rb (&packet, i, &ssrc, &fractionlost, &packetslost, &exthighestseq, &jitter, &lsr, &dlsr); GST_DEBUG_OBJECT (src, "got RB packet %d: SSRC %08x, FL %u" ", PL %u, HS %u, JITTER %u, LSR %u, DLSR %u", ssrc, fractionlost, packetslost, exthighestseq, jitter, lsr, dlsr); } break; } case GST_RTCP_TYPE_SDES: { guint chunks, i, j; gboolean more_chunks, more_items; chunks = gst_rtcp_packet_sdes_get_chunk_count (&packet); GST_DEBUG_OBJECT (src, "got SDES packet with %d chunks", chunks); more_chunks = gst_rtcp_packet_sdes_first_chunk (&packet); i = 0; while (more_chunks) { guint32 ssrc; ssrc = gst_rtcp_packet_sdes_get_ssrc (&packet); GST_DEBUG_OBJECT (src, "chunk %d, SSRC %08x", i, ssrc); more_items = gst_rtcp_packet_sdes_first_item (&packet); j = 0; while (more_items) { GstRTCPSDESType type; guint8 len; gchar *data; gst_rtcp_packet_sdes_get_item (&packet, &type, &len, &data); GST_DEBUG_OBJECT (src, "item %d, type %d, len %d, data %s", j, type, len, data); more_items = gst_rtcp_packet_sdes_next_item (&packet); j++; } more_chunks = gst_rtcp_packet_sdes_next_chunk (&packet); i++; } break; } case GST_RTCP_TYPE_BYE: { guint count, i; gchar *reason; reason = gst_rtcp_packet_bye_get_reason (&packet); GST_DEBUG_OBJECT (src, "got BYE packet (reason: %s)", GST_STR_NULL (reason)); g_free (reason); count = gst_rtcp_packet_bye_get_ssrc_count (&packet); for (i = 0; i < count; i++) { guint32 ssrc; ssrc = gst_rtcp_packet_bye_get_nth_ssrc (&packet, i); GST_DEBUG_OBJECT (src, "SSRC: %08x", ssrc); } break; } case GST_RTCP_TYPE_APP: GST_DEBUG_OBJECT (src, "got APP packet"); break; default: GST_WARNING_OBJECT (src, "got unknown RTCP packet"); break; } more = gst_rtcp_packet_move_to_next (&packet); } gst_buffer_unref (buffer); return GST_FLOW_OK; bad_packet: { GST_WARNING_OBJECT (src, "got invalid RTCP packet"); return GST_FLOW_OK; } #else return GST_FLOW_OK; #endif }
static void test_taglib_id3mux_with_tags (GstTagList * tags, guint32 mask) { GstMessage *msg; GstTagList *tags_read = NULL; GstElement *pipeline, *id3mux, *id3demux, *fakesrc, *identity, *fakesink; GstBus *bus; guint64 offset; GstBuffer *outbuf = NULL; GstBuffer *tagbuf = NULL; GstStateChangeReturn state_result; pipeline = gst_pipeline_new ("pipeline"); g_assert (pipeline != NULL); fakesrc = gst_element_factory_make ("fakesrc", "fakesrc"); g_assert (fakesrc != NULL); id3mux = gst_element_factory_make ("id3v2mux", "id3v2mux"); g_assert (id3mux != NULL); identity = gst_element_factory_make ("identity", "identity"); g_assert (identity != NULL); id3demux = gst_element_factory_make ("id3demux", "id3demux"); g_assert (id3demux != NULL); fakesink = gst_element_factory_make ("fakesink", "fakesink"); g_assert (fakesink != NULL); /* set up sink */ outbuf = NULL; g_object_set (fakesink, "signal-handoffs", TRUE, NULL); g_signal_connect (fakesink, "handoff", G_CALLBACK (got_buffer), &outbuf); gst_bin_add (GST_BIN (pipeline), fakesrc); gst_bin_add (GST_BIN (pipeline), id3mux); gst_bin_add (GST_BIN (pipeline), identity); gst_bin_add (GST_BIN (pipeline), id3demux); gst_bin_add (GST_BIN (pipeline), fakesink); gst_tag_setter_merge_tags (GST_TAG_SETTER (id3mux), tags, GST_TAG_MERGE_APPEND); gst_element_link_many (fakesrc, id3mux, identity, id3demux, fakesink, NULL); /* set up source */ g_object_set (fakesrc, "signal-handoffs", TRUE, "can-activate-pull", FALSE, "filltype", 2, "sizetype", 2, "sizemax", MP3_FRAME_SIZE, "num-buffers", 16, NULL); offset = 0; g_signal_connect (fakesrc, "handoff", G_CALLBACK (fill_mp3_buffer), &offset); /* set up identity to catch tag buffer */ g_signal_connect (identity, "handoff", G_CALLBACK (identity_cb), &tagbuf); GST_LOG ("setting and getting state ..."); gst_element_set_state (pipeline, GST_STATE_PLAYING); state_result = gst_element_get_state (pipeline, NULL, NULL, -1); fail_unless (state_result == GST_STATE_CHANGE_SUCCESS, "Unexpected result from get_state(). Expected success, got %d", state_result); bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline)); GST_LOG ("Waiting for tag ..."); msg = gst_bus_poll (bus, GST_MESSAGE_TAG | GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1); if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) { GError *err; gchar *dbg; gst_message_parse_error (msg, &err, &dbg); g_printerr ("ERROR from element %s: %s\n%s\n", GST_OBJECT_NAME (msg->src), err->message, GST_STR_NULL (dbg)); g_error_free (err); g_free (dbg); } else if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_EOS) { g_printerr ("EOS message, but were waiting for TAGS!\n"); } fail_unless (msg->type == GST_MESSAGE_TAG); gst_message_parse_tag (msg, &tags_read); gst_message_unref (msg); GST_LOG ("Got tags: %" GST_PTR_FORMAT, tags_read); test_taglib_id3mux_check_tags (tags_read, mask); gst_tag_list_unref (tags_read); fail_unless (tagbuf != NULL); test_taglib_id3mux_check_tag_buffer (tagbuf, mask); gst_buffer_unref (tagbuf); GST_LOG ("Waiting for EOS ..."); msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1); if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) { GError *err; gchar *dbg; gst_message_parse_error (msg, &err, &dbg); g_printerr ("ERROR from element %s: %s\n%s\n", GST_OBJECT_NAME (msg->src), err->message, GST_STR_NULL (dbg)); g_error_free (err); g_free (dbg); } fail_unless (msg->type == GST_MESSAGE_EOS); gst_message_unref (msg); gst_object_unref (bus); GST_LOG ("Got EOS, shutting down ..."); gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (pipeline); test_taglib_id3mux_check_output_buffer (outbuf); gst_buffer_unref (outbuf); GST_LOG ("Done"); }
static gboolean gst_split_file_src_start (GstBaseSrc * basesrc) { GstSplitFileSrc *src = GST_SPLIT_FILE_SRC (basesrc); GCancellable *cancel; gboolean ret = FALSE; guint64 offset; GError *err = NULL; gchar *basename = NULL; gchar *dirname = NULL; gchar **files; guint i; GST_OBJECT_LOCK (src); if (src->location != NULL && src->location[0] != '\0') { basename = g_path_get_basename (src->location); dirname = g_path_get_dirname (src->location); } GST_OBJECT_UNLOCK (src); files = gst_split_file_src_find_files (src, dirname, basename, &err); if (files == NULL || *files == NULL) goto no_files; src->num_parts = g_strv_length (files); src->parts = g_new0 (GstFilePart, src->num_parts); cancel = src->cancellable; offset = 0; for (i = 0; i < src->num_parts; ++i) { GFileInputStream *stream; GFileInfo *info; goffset size; GFile *file; file = g_file_new_for_path (files[i]); stream = g_file_read (file, cancel, &err); g_object_unref (file); if (err != NULL) goto open_read_error; info = g_file_input_stream_query_info (stream, "standard::*", NULL, &err); if (err != NULL) { g_object_unref (stream); goto query_info_error; } size = g_file_info_get_size (info); g_object_unref (info); src->parts[i].stream = stream; src->parts[i].path = g_strdup (files[i]); src->parts[i].start = offset; src->parts[i].stop = offset + size - 1; GST_DEBUG ("[%010" G_GUINT64_FORMAT "-%010" G_GUINT64_FORMAT "] %s", src->parts[i].start, src->parts[i].stop, src->parts[i].path); offset += size; } GST_INFO ("Successfully opened %u file parts for reading", src->num_parts); src->cur_part = 0; src->cancellable = g_cancellable_new (); ret = TRUE; done: if (err != NULL) g_error_free (err); g_strfreev (files); g_free (basename); g_free (dirname); return ret; /* ERRORS */ no_files: { if (err->code == G_IO_ERROR_CANCELLED) goto cancelled; GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("%s", err->message), ("Failed to find files in '%s' for pattern '%s'", GST_STR_NULL (dirname), GST_STR_NULL (basename))); goto done; } open_read_error: { if (err->code == G_IO_ERROR_CANCELLED) goto cancelled; GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("%s", err->message), ("Failed to open file '%s' for reading", files[i])); goto done; } query_info_error: { if (err->code == G_IO_ERROR_CANCELLED) goto cancelled; GST_ELEMENT_ERROR (src, RESOURCE, OPEN_READ, ("%s", err->message), ("Failed to query info for file '%s'", files[i])); goto done; } cancelled: { GST_DEBUG_OBJECT (src, "I/O operation cancelled from another thread"); goto done; } }
/* First some utils, then the mixer implementation */ static gboolean gst_alsa_mixer_open (GstAlsaMixer * mixer) { gint err; snd_ctl_t *ctl; snd_ctl_card_info_t *card_info; g_return_val_if_fail (mixer->handle == NULL, FALSE); /* open and initialize the mixer device */ err = snd_mixer_open (&mixer->handle, 0); if (err < 0 || mixer->handle == NULL) goto open_failed; if ((err = snd_mixer_attach (mixer->handle, mixer->device)) < 0) { GST_WARNING ("Cannot open mixer for sound device '%s': %s", mixer->device, snd_strerror (err)); goto error; } if ((err = snd_mixer_selem_register (mixer->handle, NULL, NULL)) < 0) { GST_WARNING ("Cannot register mixer elements: %s", snd_strerror (err)); goto error; } if ((err = snd_mixer_load (mixer->handle)) < 0) { GST_WARNING ("Cannot load mixer settings: %s", snd_strerror (err)); goto error; } snd_mixer_set_callback_private (mixer->handle, mixer); snd_mixer_set_callback (mixer->handle, gst_alsa_mixer_handle_callback); /* now get the device name, any of this is not fatal */ g_free (mixer->cardname); if ((err = snd_ctl_open (&ctl, mixer->device, 0)) < 0) { GST_WARNING ("Cannot open CTL: %s", snd_strerror (err)); goto no_card_name; } snd_ctl_card_info_malloc (&card_info); if ((err = snd_ctl_card_info (ctl, card_info)) < 0) { GST_WARNING ("Cannot get card info: %s", snd_strerror (err)); snd_ctl_close (ctl); goto no_card_name; } mixer->cardname = g_strdup (snd_ctl_card_info_get_name (card_info)); GST_DEBUG ("Card name = %s", GST_STR_NULL (mixer->cardname)); snd_ctl_card_info_free (card_info); snd_ctl_close (ctl); no_card_name: if (mixer->cardname == NULL) { mixer->cardname = g_strdup ("Unknown"); GST_DEBUG ("Cannot find card name"); } GST_INFO ("Successfully opened mixer for device '%s'.", mixer->device); return TRUE; /* ERROR */ open_failed: { GST_WARNING ("Cannot open mixer: %s", snd_strerror (err)); mixer->handle = NULL; return FALSE; } error: { snd_mixer_close (mixer->handle); mixer->handle = NULL; return FALSE; } }
int main (int argc, char **argv) { GstPlay *play; GPtrArray *playlist; gboolean verbose = FALSE; gboolean print_version = FALSE; gboolean interactive = TRUE; gboolean gapless = FALSE; gboolean shuffle = FALSE; gdouble volume = -1; gchar **filenames = NULL; gchar *audio_sink = NULL; gchar *video_sink = NULL; gchar **uris; gchar *flags = NULL; guint num, i; GError *err = NULL; GOptionContext *ctx; gchar *playlist_file = NULL; GOptionEntry options[] = { {"verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, N_("Output status information and property notifications"), NULL}, {"flags", 0, 0, G_OPTION_ARG_STRING, &flags, N_("Control playback behaviour setting playbin 'flags' property"), NULL}, {"version", 0, 0, G_OPTION_ARG_NONE, &print_version, N_("Print version information and exit"), NULL}, {"videosink", 0, 0, G_OPTION_ARG_STRING, &video_sink, N_("Video sink to use (default is autovideosink)"), NULL}, {"audiosink", 0, 0, G_OPTION_ARG_STRING, &audio_sink, N_("Audio sink to use (default is autoaudiosink)"), NULL}, {"gapless", 0, 0, G_OPTION_ARG_NONE, &gapless, N_("Enable gapless playback"), NULL}, {"shuffle", 0, 0, G_OPTION_ARG_NONE, &shuffle, N_("Shuffle playlist"), NULL}, {"no-interactive", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &interactive, N_("Disable interactive control via the keyboard"), NULL}, {"volume", 0, 0, G_OPTION_ARG_DOUBLE, &volume, N_("Volume"), NULL}, {"playlist", 0, 0, G_OPTION_ARG_FILENAME, &playlist_file, N_("Playlist file containing input media files"), NULL}, {"quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet, N_("Do not print any output (apart from errors)"), NULL}, {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL}, {NULL} }; setlocale (LC_ALL, ""); #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); #endif g_set_prgname ("gst-play-" GST_API_VERSION); ctx = g_option_context_new ("FILE1|URI1 [FILE2|URI2] [FILE3|URI3] ..."); g_option_context_add_main_entries (ctx, options, GETTEXT_PACKAGE); 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)); g_option_context_free (ctx); g_clear_error (&err); return 1; } g_option_context_free (ctx); GST_DEBUG_CATEGORY_INIT (play_debug, "play", 0, "gst-play"); if (print_version) { gchar *version_str; version_str = gst_version_string (); g_print ("%s version %s\n", g_get_prgname (), PACKAGE_VERSION); g_print ("%s\n", version_str); g_print ("%s\n", GST_PACKAGE_ORIGIN); g_free (version_str); g_free (audio_sink); g_free (video_sink); g_free (playlist_file); return 0; } playlist = g_ptr_array_new (); if (playlist_file != NULL) { gchar *playlist_contents = NULL; gchar **lines = NULL; if (g_file_get_contents (playlist_file, &playlist_contents, NULL, &err)) { lines = g_strsplit (playlist_contents, "\n", 0); num = g_strv_length (lines); for (i = 0; i < num; i++) { if (lines[i][0] != '\0') { GST_LOG ("Playlist[%d]: %s", i + 1, lines[i]); add_to_playlist (playlist, lines[i]); } } g_strfreev (lines); g_free (playlist_contents); } else { g_printerr ("Could not read playlist: %s\n", err->message); g_clear_error (&err); } g_free (playlist_file); playlist_file = NULL; } if (playlist->len == 0 && (filenames == NULL || *filenames == NULL)) { g_printerr (_("Usage: %s FILE1|URI1 [FILE2|URI2] [FILE3|URI3] ..."), "gst-play-" GST_API_VERSION); g_printerr ("\n\n"), g_printerr ("%s\n\n", _("You must provide at least one filename or URI to play.")); /* No input provided. Free array */ g_ptr_array_free (playlist, TRUE); g_free (audio_sink); g_free (video_sink); return 1; } /* fill playlist */ if (filenames != NULL && *filenames != NULL) { num = g_strv_length (filenames); for (i = 0; i < num; ++i) { GST_LOG ("command line argument: %s", filenames[i]); add_to_playlist (playlist, filenames[i]); } g_strfreev (filenames); } num = playlist->len; g_ptr_array_add (playlist, NULL); uris = (gchar **) g_ptr_array_free (playlist, FALSE); if (shuffle) shuffle_uris (uris, num); /* prepare */ play = play_new (uris, audio_sink, video_sink, gapless, volume, verbose, flags); if (play == NULL) { g_printerr ("Failed to create 'playbin' element. Check your GStreamer installation.\n"); return EXIT_FAILURE; } if (interactive) { if (gst_play_kb_set_key_handler (keyboard_cb, play)) { g_print (_("Press 'k' to see a list of keyboard shortcuts.\n")); atexit (restore_terminal); } else { g_print ("Interactive keyboard handling in terminal not available.\n"); } } /* play */ do_play (play); /* clean up */ play_free (play); g_free (audio_sink); g_free (video_sink); g_print ("\n"); gst_deinit (); return 0; }
int main (int argc, char **argv) { GstPlay *play; GPtrArray *playlist; gboolean print_version = FALSE; gboolean interactive = FALSE; /* FIXME: maybe enable by default? */ gboolean shuffle = FALSE; gdouble volume = 1.0; gchar **filenames = NULL; gchar **uris; guint num, i; GError *err = NULL; GOptionContext *ctx; gchar *playlist_file = NULL; GOptionEntry options[] = { {"version", 0, 0, G_OPTION_ARG_NONE, &print_version, "Print version information and exit", NULL}, {"shuffle", 0, 0, G_OPTION_ARG_NONE, &shuffle, "Shuffle playlist", NULL}, {"interactive", 0, 0, G_OPTION_ARG_NONE, &interactive, "Interactive control via keyboard", NULL}, {"volume", 0, 0, G_OPTION_ARG_DOUBLE, &volume, "Volume", NULL}, {"playlist", 0, 0, G_OPTION_ARG_FILENAME, &playlist_file, "Playlist file containing input media files", NULL}, {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL}, {NULL} }; g_set_prgname ("gst-play"); ctx = g_option_context_new ("FILE1|URI1 [FILE2|URI2] [FILE3|URI3] ..."); 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)); return 1; } g_option_context_free (ctx); GST_DEBUG_CATEGORY_INIT (play_debug, "play", 0, "gst-play"); if (print_version) { gchar *version_str; version_str = gst_version_string (); g_print ("%s version %s\n", g_get_prgname (), "1.0"); g_print ("%s\n", version_str); g_free (version_str); g_free (playlist_file); return 0; } playlist = g_ptr_array_new (); if (playlist_file != NULL) { gchar *playlist_contents = NULL; gchar **lines = NULL; if (g_file_get_contents (playlist_file, &playlist_contents, NULL, &err)) { lines = g_strsplit (playlist_contents, "\n", 0); num = g_strv_length (lines); for (i = 0; i < num; i++) { if (lines[i][0] != '\0') { GST_LOG ("Playlist[%d]: %s", i + 1, lines[i]); add_to_playlist (playlist, lines[i]); } } g_strfreev (lines); g_free (playlist_contents); } else { g_printerr ("Could not read playlist: %s\n", err->message); g_clear_error (&err); } g_free (playlist_file); playlist_file = NULL; } if (playlist->len == 0 && (filenames == NULL || *filenames == NULL)) { g_printerr ("Usage: %s FILE1|URI1 [FILE2|URI2] [FILE3|URI3] ...", "gst-play"); g_printerr ("\n\n"), g_printerr ("%s\n\n", "You must provide at least one filename or URI to play."); /* No input provided. Free array */ g_ptr_array_free (playlist, TRUE); return 1; } /* fill playlist */ if (filenames != NULL && *filenames != NULL) { num = g_strv_length (filenames); for (i = 0; i < num; ++i) { GST_LOG ("command line argument: %s", filenames[i]); add_to_playlist (playlist, filenames[i]); } g_strfreev (filenames); } num = playlist->len; g_ptr_array_add (playlist, NULL); uris = (gchar **) g_ptr_array_free (playlist, FALSE); if (shuffle) shuffle_uris (uris, num); /* prepare */ play = play_new (uris, volume); if (interactive) { if (gst_play_kb_set_key_handler (keyboard_cb, play)) { atexit (restore_terminal); } else { g_print ("Interactive keyboard handling in terminal not available.\n"); } } /* play */ do_play (play); /* clean up */ play_free (play); g_print ("\n"); return 0; }