//定义消息处理函数, static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) { GMainLoop *loop = (GMainLoop *) data;//这个是主循环的指针,在接受EOS消息时退出循环 switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_EOS: g_print("End of stream\n"); g_main_loop_quit(loop); break; case GST_MESSAGE_ERROR: { gchar *debug; GError *error; gst_message_parse_error(msg, &error, &debug); g_free(debug); g_printerr("ERROR:%s\n", error->message); g_error_free(error); g_main_loop_quit(loop); break; } case GST_MESSAGE_TAG: { GstTagList *tags; gchar *title = ""; gchar *artist = ""; gst_message_parse_tag(msg, &tags); if (gst_tag_list_get_string(tags, GST_TAG_TITLE, &title) && gst_tag_list_get_string(tags, GST_TAG_ARTIST, &artist)) { puts(title); puts(artist); } gst_tag_list_free(tags); break; } default: break; } return TRUE; }
static void pragha_backend_parse_message_tag (PraghaBackend *backend, GstMessage *message) { PraghaBackendPrivate *priv = backend->priv; GstTagList *tag_list; gchar *str = NULL; gint changed = 0; CDEBUG(DBG_BACKEND, "Parse message tag"); gst_message_parse_tag(message, &tag_list); save_embedded_art (backend, tag_list); if (pragha_musicobject_get_source (priv->mobj) != FILE_HTTP) goto out; if (gst_tag_list_get_string(tag_list, GST_TAG_TITLE, &str)) { changed |= TAG_TITLE_CHANGED; pragha_musicobject_set_title(priv->mobj, str); g_free(str); } if (gst_tag_list_get_string(tag_list, GST_TAG_ARTIST, &str)) { changed |= TAG_ARTIST_CHANGED; pragha_musicobject_set_artist(priv->mobj, str); g_free(str); } g_signal_emit (backend, signals[SIGNAL_TAGS_CHANGED], 0, changed); out: gst_tag_list_free(tag_list); }
static gboolean validity_bus_cb (GstBus * bus, GstMessage * message, gpointer data) { GMainLoop *loop = (GMainLoop *) data; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR: fail_if (TRUE, "validating captured data failed"); g_main_loop_quit (loop); break; case GST_MESSAGE_EOS: g_main_loop_quit (loop); GST_DEBUG ("eos"); break; case GST_MESSAGE_TAG:{ GstTagList *tags = NULL; gst_message_parse_tag (message, &tags); if (validation_taglist) { gst_tag_list_insert (validation_taglist, tags, GST_TAG_MERGE_REPLACE); gst_tag_list_free (tags); } else validation_taglist = tags; break; } default: break; } return TRUE; }
/* This function is called when a "tag" message is posted on the bus. */ static void tag_cb (GstBus *bus, GstMessage *msg, CustomData *data) { if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_TAG) { GstTagList *tags = NULL; gchar *title, *artist, *tagstring; gst_message_parse_tag (msg, &tags); get_tag (tags, GST_TAG_TITLE, &title); get_tag (tags, GST_TAG_ARTIST, &artist); g_print ("Title: %s Artist %s\n", title, artist); tagstring = g_strdup_printf("%s - %s", title, artist); /* only update when we got a meaningful tag */ if (!(0 == g_strcmp0 (title, "Unknown") && 0 == g_strcmp0 (artist, "Unknown"))) { update_taglabel(data, tagstring); } g_free(title); g_free(artist); g_free(tagstring); #if GST_VERSION_MAJOR == (0) gst_tag_list_free (tags); #else gst_tag_list_unref (tags); #endif } }
static gboolean bus_watch_handler(GstBus *bus, GstMessage *msg, gpointer data) { struct ausrc_st *st = data; GMainLoop *loop = st->loop; GstTagList *tag_list; gchar *title; GError *err; gchar *d; (void)bus; switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_EOS: /* XXX decrementing repeat count? */ /* Re-start stream */ if (st->run) { gst_element_set_state(st->pipeline, GST_STATE_NULL); gst_element_set_state(st->pipeline, GST_STATE_PLAYING); } else { g_main_loop_quit(loop); } break; case GST_MESSAGE_ERROR: gst_message_parse_error(msg, &err, &d); warning("gst: Error: %d(%m) message=\"%s\"\n", err->code, err->code, err->message); warning("gst: Debug: %s\n", d); g_free(d); /* Call error handler */ if (st->errh) st->errh(err->code, err->message, st->arg); g_error_free(err); st->run = false; g_main_loop_quit(loop); break; case GST_MESSAGE_TAG: gst_message_parse_tag(msg, &tag_list); if (gst_tag_list_get_string(tag_list, GST_TAG_TITLE, &title)) { info("gst: title: %s\n", title); g_free(title); } break; default: break; } return TRUE; }
static gboolean bus_handler (GstBus * bus, GstMessage * message, gpointer data) { GMainLoop *loop = (GMainLoop *) data; switch (message->type) { case GST_MESSAGE_EOS: g_main_loop_quit (loop); break; case GST_MESSAGE_WARNING: case GST_MESSAGE_ERROR:{ GError *gerror; gchar *debug; gst_message_parse_error (message, &gerror, &debug); gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug); g_error_free (gerror); g_free (debug); g_main_loop_quit (loop); break; } case GST_MESSAGE_TAG:{ if (received_tags == NULL) { gst_message_parse_tag (message, &received_tags); } else { GstTagList *tl = NULL, *ntl = NULL; gst_message_parse_tag (message, &tl); if (tl) { ntl = gst_tag_list_merge (received_tags, tl, GST_TAG_MERGE_PREPEND); if (ntl) { GST_LOG ("taglists merged: %" GST_PTR_FORMAT, ntl); gst_tag_list_free (received_tags); received_tags = ntl; } gst_tag_list_free (tl); } } break; } default: break; } return TRUE; }
TagList TagMessage::taglist() const { GstTagList * t; gst_message_parse_tag(object<GstMessage>(), &t); TagList tl(t); gst_tag_list_free(t); return tl; }
CAMLprim value ocaml_gstreamer_message_parse_tag(value _msg) { CAMLparam1(_msg); CAMLlocal4(v,s,t,ans); GstMessage *msg = Message_val(_msg); GstTagList *tags = NULL; const GValue *val; const gchar *tag; int taglen; int i, j, n; caml_release_runtime_system(); gst_message_parse_tag(msg, &tags); taglen = gst_tag_list_n_tags(tags); caml_acquire_runtime_system(); ans = caml_alloc_tuple(taglen); for(i = 0; i < taglen; i++) { t = caml_alloc_tuple(2); // Tag name tag = gst_tag_list_nth_tag_name(tags, i); Store_field(t, 0, caml_copy_string(tag)); // Tag fields n = gst_tag_list_get_tag_size(tags, tag); v = caml_alloc_tuple(n); for (j = 0; j < n; j++) { val = gst_tag_list_get_value_index(tags, tag, j); if (G_VALUE_HOLDS_STRING(val)) { s = caml_copy_string(g_value_get_string(val)); } else if (GST_VALUE_HOLDS_DATE_TIME(val)) { GstDateTime *dt = g_value_get_boxed(val); gchar *dt_str = gst_date_time_to_iso8601_string(dt); s = caml_copy_string(dt_str); g_free(dt_str); } else { //TODO: better typed handling of non-string values? char *vc = g_strdup_value_contents(val); s = caml_copy_string(vc); free(vc); } Store_field(v, j, s); } Store_field(t, 1, v); Store_field(ans, i, t); } gst_tag_list_unref(tags); CAMLreturn(ans); }
void tag_cb(GstBus *bus, GstMessage *msg, CustomData *data) { GstTagList *tags = NULL; gst_message_parse_tag(msg, &tags); GPlayerDEBUG("Got tags from element %s:\n", GST_OBJECT_NAME(msg->src)); gst_tag_list_foreach(tags, (GstTagForeachFunc) print_one_tag, data); gst_tag_list_unref(tags); gst_message_unref(msg); }
static gboolean brasero_transcode_bus_messages (GstBus *bus, GstMessage *msg, BraseroTranscode *transcode) { BraseroTranscodePrivate *priv; GstTagList *tags = NULL; GError *error = NULL; GstState state; gchar *debug; priv = BRASERO_TRANSCODE_PRIVATE (transcode); switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_TAG: /* we use the information to write an .inf file * for the time being just store the information */ gst_message_parse_tag (msg, &tags); gst_tag_list_foreach (tags, (GstTagForeachFunc) foreach_tag, transcode); gst_tag_list_free (tags); return TRUE; case GST_MESSAGE_ERROR: gst_message_parse_error (msg, &error, &debug); BRASERO_JOB_LOG (transcode, debug); g_free (debug); brasero_job_error (BRASERO_JOB (transcode), error); return FALSE; case GST_MESSAGE_EOS: brasero_transcode_song_end_reached (transcode); return FALSE; case GST_MESSAGE_STATE_CHANGED: { GstStateChangeReturn result; result = gst_element_get_state (priv->pipeline, &state, NULL, 1); if (result != GST_STATE_CHANGE_SUCCESS) return TRUE; if (state == GST_STATE_PLAYING) return brasero_transcode_active_state (transcode); break; } default: return TRUE; } return TRUE; }
static gboolean bus_callback (GstBus * bus, GstMessage * message, gpointer data) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_WARNING:{ GError *err; gchar *debug; gst_message_parse_warning (message, &err, &debug); g_print ("Warning: %s\n", err->message); g_error_free (err); g_free (debug); break; } case GST_MESSAGE_ERROR:{ GError *err; gchar *debug = NULL; gst_message_parse_error (message, &err, &debug); g_print ("Error: %s : %s\n", err->message, debug); g_error_free (err); g_free (debug); gtk_main_quit (); break; } case GST_MESSAGE_TAG:{ GstTagList *tags; GValue v = { 0, }; g_print ("Got tags\n"); gst_message_parse_tag (message, &tags); if (gst_tag_list_copy_value (&v, tags, "mxf-structure")) { const GstStructure *s; GtkTreeIter iter; s = gst_value_get_structure (&v); gtk_tree_store_append (treestore, &iter, NULL); insert_structure (s, &iter); gtk_widget_show_all (window); g_value_unset (&v); } gst_tag_list_unref (tags); break; } default: break; } return TRUE; }
static gboolean bus_handler (GstBus * bus, GstMessage * message, gpointer data) { GMainLoop *loop = (GMainLoop *) data; switch (message->type) { case GST_MESSAGE_EOS: g_main_loop_quit (loop); break; case GST_MESSAGE_WARNING: case GST_MESSAGE_ERROR:{ GError *gerror; gchar *debug; if (message->type == GST_MESSAGE_WARNING) gst_message_parse_warning (message, &gerror, &debug); else gst_message_parse_error (message, &gerror, &debug); gst_object_default_error (GST_MESSAGE_SRC (message), gerror, debug); gst_message_unref (message); g_error_free (gerror); g_free (debug); g_main_loop_quit (loop); break; } case GST_MESSAGE_TAG: { GstTagList *tag_list; gchar *fpr, *p; gst_message_parse_tag (message, &tag_list); fail_unless (gst_tag_list_get_string (tag_list, "ofa-fingerprint", &fpr)); p = fpr; while (*p) { fail_unless (g_ascii_isalnum (*p) || *p == '=' || *p == '+' || *p == '/'); p++; } g_free (fpr); gst_tag_list_unref (tag_list); found_fingerprint = TRUE; g_main_loop_quit (loop); break; } default: break; } return TRUE; }
static void internal_bus_watch_handler(struct gst_video_state *st) { GstTagList *tag_list; gchar *title; GError *err; gchar *d; GstMessage *msg = gst_bus_pop(st->bus); if (!msg) { // take a nap (300ms) usleep(300 * 1000); return; } switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_EOS: /* XXX decrementing repeat count? */ /* Re-start stream */ gst_element_set_state(st->pipeline, GST_STATE_NULL); gst_element_set_state(st->pipeline, GST_STATE_PLAYING); break; case GST_MESSAGE_ERROR: gst_message_parse_error(msg, &err, &d); DEBUG_WARNING("Error: %d(%m) message=%s\n", err->code, err->code, err->message); DEBUG_WARNING("Debug: %s\n", d); g_free(d); g_error_free(err); st->run = FALSE; break; case GST_MESSAGE_TAG: gst_message_parse_tag(msg, &tag_list); if (gst_tag_list_get_string(tag_list, GST_TAG_TITLE, &title)) { DEBUG_NOTICE("Title: %s\n", title); g_free(title); } break; default: break; } gst_message_unref(msg); }
static VALUE tag_parse(VALUE self) { VALUE value = rb_hash_new(); GstTagList *tag_list; gst_message_parse_tag(SELF(self), &tag_list); gst_structure_foreach(tag_list, foreach_pair, &value); gst_tag_list_free(tag_list); return value; }
/* Callback function invoked when a message arrives on the playback * pipeline's bus. */ static gboolean bus_callback (GstBus *bus, GstMessage *message, gpointer data) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR: { /* An error has occurred. * A real application would probably need to handle this more * intelligently than just quitting. */ 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); gtk_main_quit(); break; } case GST_MESSAGE_EOS: /* The pipeline has reached the end of the stream. */ g_print("End of stream\n"); stop_playback(); gui_status_update(STATE_STOP); break; case GST_MESSAGE_TAG: { /* The stream discovered new tags. */ GstTagList *tags; gchar *title = ""; gchar *artist = ""; /* Extract from the message the GstTagList. * This generates a copy, so we must remember to free it.*/ gst_message_parse_tag(message, &tags); /* Extract the title and artist tags - if they exist */ if (gst_tag_list_get_string(tags, GST_TAG_TITLE, &title) && gst_tag_list_get_string(tags, GST_TAG_ARTIST, &artist)) gui_update_metadata(title, artist); /* Free the tag list */ gst_tag_list_free(tags); break; } default: /* Another message occurred which we are not interested in handling. */ break; } /* We have handled this message, so indicate that it should be removed from * the queue.*/ return TRUE; }
/** * Scan a single file * @param file * @return */ int scan_file (gchar * file) { GstElement *pipe, *dec, *sink; /* Scanner pipeline */ GstMessage *msg; /* Scanner message buffer */ sqlite3 *database; /* SQL database */ gchar *zErrMsg = 0; /* SQL error message */ gint returnCode; /* SQL return code */ if (!gst_uri_is_valid (file)) g_error ("Must be used with a valid file uri."); pipe = gst_pipeline_new ("pipeline"); dec = gst_element_factory_make ("uridecodebin", NULL); g_object_set (dec, "uri", file, NULL); gst_bin_add (GST_BIN (pipe), dec); sink = gst_element_factory_make ("fakesink", NULL); gst_bin_add (GST_BIN (pipe), sink); g_signal_connect (dec, "pad-added", G_CALLBACK (on_new_pad), sink); gst_element_set_state (pipe, GST_STATE_PAUSED); while (TRUE) { GstTagList *tags = NULL; msg = gst_bus_timed_pop_filtered (GST_ELEMENT_BUS (pipe), GST_CLOCK_TIME_NONE, GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_TAG | GST_MESSAGE_ERROR); if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_TAG) /* error or async_done */ break; gst_message_parse_tag (msg, &tags); gst_tag_list_foreach (tags, insert_tags, NULL); gst_tag_list_free (tags); gst_message_unref (msg); }; if (GST_MESSAGE_TYPE (msg) == GST_MESSAGE_ERROR) g_error ("Got error"); gst_message_unref (msg); gst_element_set_state (pipe, GST_STATE_NULL); gst_object_unref (pipe); return 0; }
gboolean bus_callback(GstBus* sender, GstMessage* message, void* data) { gPlay* gplay = reinterpret_cast<gPlay*> (data); switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_STATE_CHANGED: { GstState newState; gst_message_parse_state_changed(message, NULL, &newState, NULL); std::string message_name(GST_MESSAGE_SRC_NAME(message));//TODO: Avoid this copy using glib if (message_name.compare("playbin") == 0){ gplay->on_state_changed(newState); } } break; case GST_MESSAGE_TAG: { GstTagList* tag_list = 0; gst_message_parse_tag(message, &tag_list); Track t; track_from_tag(tag_list, &t); gplay->on_tag_found(t); gst_tag_list_free(tag_list); } break; case GST_MESSAGE_EOS: gplay->on_eos(); break; case GST_MESSAGE_STREAM_STATUS: GstStreamStatusType message_type; gst_message_parse_stream_status(message, &message_type, NULL); g_print("Stream status: %d\n", message_type); break; default: g_print("Message from %s: %s\n", GST_MESSAGE_SRC_NAME(message), gst_message_type_get_name(GST_MESSAGE_TYPE(message))); break; } //TODO: Should I dispose message? return true; }
static gboolean bbd_pipeline_bus_callback (GstBus *bus, GstMessage *message, gpointer data) { BansheeBpmDetector *detector = (BansheeBpmDetector *)data; g_return_val_if_fail (detector != NULL, FALSE); switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_TAG: { GstTagList *tags; gst_message_parse_tag (message, &tags); if (GST_IS_TAG_LIST (tags)) { gst_tag_list_foreach (tags, (GstTagForeachFunc)bbd_pipeline_process_tag, detector); gst_tag_list_free (tags); } break; } case GST_MESSAGE_ERROR: { GError *error; gchar *debug; gst_message_parse_error (message, &error, &debug); bbd_raise_error (detector, error->message, debug); g_error_free (error); g_free (debug); detector->is_detecting = FALSE; break; } case GST_MESSAGE_EOS: { detector->is_detecting = FALSE; gst_element_set_state (GST_ELEMENT (detector->pipeline), GST_STATE_NULL); if (detector->finished_cb != NULL) { detector->finished_cb (); } break; } default: break; } return TRUE; }
static void loading_messages(GstBus * bus,GstMessage * message,TPMediaPlayer * mp) { USERDATA(mp); switch(message->type) { //..................................................................... // When a tag is found case GST_MESSAGE_TAG: { GstTagList * tags=NULL; gst_message_parse_tag(message,&tags); if (tags) { gst_tag_list_foreach(tags,collect_tags,mp); gst_tag_list_free(tags); } break; } //..................................................................... // When the load is done - the stream is paused and ready to go case GST_MESSAGE_ASYNC_DONE: { get_stream_information(mp); // Now, notify that the stream is loaded tp_media_player_loaded(mp); // Disconnect this signal handler g_signal_handler_disconnect(bus,ud->load_signal); ud->load_signal=0; break; } default: { // Default handler to make clang shut up break; } } }
void GstEnginePipeline::TagMessageReceived(GstMessage* msg) { GstTagList* taglist = nullptr; gst_message_parse_tag(msg, &taglist); Engine::SimpleMetaBundle bundle; bundle.title = ParseTag(taglist, GST_TAG_TITLE); bundle.artist = ParseTag(taglist, GST_TAG_ARTIST); bundle.comment = ParseTag(taglist, GST_TAG_COMMENT); bundle.album = ParseTag(taglist, GST_TAG_ALBUM); gst_tag_list_free(taglist); if (ignore_tags_) return; if (!bundle.title.isEmpty() || !bundle.artist.isEmpty() || !bundle.comment.isEmpty() || !bundle.album.isEmpty()) emit MetadataFound(id(), bundle); }
void GstPlayer::parseMessage(GstMessage *msg){ switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_STATE_CHANGED: { this->handleStateChangeMessage(msg); break; } case GST_MESSAGE_DURATION: this->queryDuration(); break; case GST_MESSAGE_TAG: { //QLOG_TRACE() << "[GST]" << GST_MESSAGE_TYPE_NAME(msg); GstTagList * tagList; // We should merge & store the list each time we get a new tag // We should also send a signal for every new tag that is defined gst_message_parse_tag(msg,&tagList); gst_tag_list_foreach(tagList,handleGstTag,this->track); gst_tag_list_free(tagList); break; } case GST_MESSAGE_EOS: { QLOG_TRACE() << "[GST] End-of-stream"; this->requestStop(); //g_main_loop_quit(loop); break; } case GST_MESSAGE_ERROR: { GError *err; gst_message_parse_error(msg, &err, NULL); QLOG_TRACE() << "[GST] [ERROR] " << err->message; error = true; g_error_free(err); // TODO: handle some errors // - Resource not found // // g_main_loop_quit(loop); break; } default: //QLOG_TRACE() << "[GST]" << GST_MESSAGE_TYPE_NAME(msg); break; } }
bool ParseTagMessage (GstMessage *msg, TagMap_t& map, const QString& region) { GstTagList *tagList = nullptr; gst_message_parse_tag (msg, &tagList); if (!tagList) return false; TagFunctionData data { map, region }; gst_tag_list_foreach (tagList, TagFunction, &data); #if GST_VERSION_MAJOR < 1 gst_tag_list_free (tagList); #else gst_tag_list_unref (tagList); #endif return true; }
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data) { GMainLoop *loop = (GMainLoop *) data; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_EOS: g_print ("end-of-stream\n"); break; case GST_MESSAGE_ERROR: { gchar *debug; GError *error; gst_message_parse_error (msg, &error, &debug); g_free (debug); g_printerr ("Error: %s\n", error->message); g_error_free (error); g_main_loop_quit (loop); break; } case GST_MESSAGE_TAG: { GstTagList *tags = NULL; gst_message_parse_tag (msg, &tags); gst_tag_list_foreach(tags,print_one_tag,NULL); gst_tag_list_free(tags); break; } default: break; }; return TRUE; }
static gboolean brasero_normalize_bus_messages (GstBus *bus, GstMessage *msg, BraseroNormalize *normalize) { GstTagList *tags = NULL; GError *error = NULL; gchar *debug; switch (GST_MESSAGE_TYPE (msg)) { case GST_MESSAGE_TAG: /* This is the information we've been waiting for. * NOTE: levels for whole album is delivered at the end */ gst_message_parse_tag (msg, &tags); gst_tag_list_foreach (tags, (GstTagForeachFunc) foreach_tag, normalize); gst_tag_list_free (tags); return TRUE; case GST_MESSAGE_ERROR: gst_message_parse_error (msg, &error, &debug); BRASERO_JOB_LOG (normalize, debug); g_free (debug); brasero_job_error (BRASERO_JOB (normalize), error); return FALSE; case GST_MESSAGE_EOS: brasero_normalize_song_end_reached (normalize); return FALSE; case GST_MESSAGE_STATE_CHANGED: break; default: return TRUE; } return TRUE; }
static void on_message (GstBus * bus, GstMessage * message, gpointer data) { switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_WARNING: case GST_MESSAGE_ERROR: g_error ("Got error"); gtk_main_quit (); break; case GST_MESSAGE_TAG:{ GstTagList *tags; GValue v = { 0, }; g_print ("Got tags\n"); gst_message_parse_tag (message, &tags); if (gst_tag_list_copy_value (&v, tags, "mxf-structure")) { const GstStructure *s; GtkTreeIter iter; s = gst_value_get_structure (&v); gtk_tree_store_append (treestore, &iter, NULL); insert_structure (s, &iter); gtk_widget_show_all (window); g_value_unset (&v); } gst_tag_list_free (tags); break; } default: break; } }
void GstEnginePipeline::TagMessageReceived(GstMessage* msg) { GstTagList* taglist = nullptr; gst_message_parse_tag(msg, &taglist); Engine::SimpleMetaBundle bundle; bundle.title = ParseTag(taglist, GST_TAG_TITLE); if (IsAkamaiTag(bundle.title)) { QPair<QString, QString> artistTitlePair = ParseAkamaiTag(bundle.title); bundle.artist = artistTitlePair.first; bundle.title = artistTitlePair.second; } else { bundle.artist = ParseTag(taglist, GST_TAG_ARTIST); bundle.comment = ParseTag(taglist, GST_TAG_COMMENT); bundle.album = ParseTag(taglist, GST_TAG_ALBUM); } gst_tag_list_free(taglist); if (ignore_tags_) return; if (!bundle.title.isEmpty() || !bundle.artist.isEmpty() || !bundle.comment.isEmpty() || !bundle.album.isEmpty()) emit MetadataFound(id(), bundle); }
static gboolean gst_switchui_handle_message (GstBus * bus, GstMessage * message, gpointer data) { GstSwitchUI *switchui = (GstSwitchUI *) data; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_EOS: gst_switchui_handle_eos (switchui); break; case GST_MESSAGE_ERROR: { GError *error = NULL; gchar *debug; gst_message_parse_error (message, &error, &debug); gst_switchui_handle_error (switchui, error, debug); } break; case GST_MESSAGE_WARNING: { GError *error = NULL; gchar *debug; gst_message_parse_warning (message, &error, &debug); gst_switchui_handle_warning (switchui, error, debug); } break; case GST_MESSAGE_INFO: { GError *error = NULL; gchar *debug; gst_message_parse_info (message, &error, &debug); gst_switchui_handle_info (switchui, error, debug); } break; case GST_MESSAGE_TAG: { GstTagList *tag_list; gst_message_parse_tag (message, &tag_list); if (verbose) g_print ("tag\n"); } break; case GST_MESSAGE_STATE_CHANGED: { GstState oldstate, newstate, pending; gst_message_parse_state_changed (message, &oldstate, &newstate, &pending); if (GST_ELEMENT (message->src) == switchui->pipeline) { if (verbose) g_print ("state change from %s to %s\n", gst_element_state_get_name (oldstate), gst_element_state_get_name (newstate)); switch (GST_STATE_TRANSITION (oldstate, newstate)) { case GST_STATE_CHANGE_NULL_TO_READY: gst_switchui_handle_null_to_ready (switchui); break; case GST_STATE_CHANGE_READY_TO_PAUSED: gst_switchui_handle_ready_to_paused (switchui); break; case GST_STATE_CHANGE_PAUSED_TO_PLAYING: gst_switchui_handle_paused_to_playing (switchui); break; case GST_STATE_CHANGE_PLAYING_TO_PAUSED: gst_switchui_handle_playing_to_paused (switchui); break; case GST_STATE_CHANGE_PAUSED_TO_READY: gst_switchui_handle_paused_to_ready (switchui); break; case GST_STATE_CHANGE_READY_TO_NULL: gst_switchui_handle_ready_to_null (switchui); break; default: if (verbose) g_print ("unknown state change from %s to %s\n", gst_element_state_get_name (oldstate), gst_element_state_get_name (newstate)); } } } break; case GST_MESSAGE_BUFFERING: { int percent; gst_message_parse_buffering (message, &percent); //g_print("buffering %d\n", percent); if (!switchui->paused_for_buffering && percent < 100) { g_print ("pausing for buffing\n"); switchui->paused_for_buffering = TRUE; gst_element_set_state (switchui->pipeline, GST_STATE_PAUSED); } else if (switchui->paused_for_buffering && percent == 100) { g_print ("unpausing for buffing\n"); switchui->paused_for_buffering = FALSE; gst_element_set_state (switchui->pipeline, GST_STATE_PLAYING); } } break; case GST_MESSAGE_STATE_DIRTY: case GST_MESSAGE_CLOCK_PROVIDE: case GST_MESSAGE_CLOCK_LOST: case GST_MESSAGE_NEW_CLOCK: case GST_MESSAGE_STRUCTURE_CHANGE: case GST_MESSAGE_STREAM_STATUS: break; case GST_MESSAGE_STEP_DONE: case GST_MESSAGE_APPLICATION: case GST_MESSAGE_ELEMENT: case GST_MESSAGE_SEGMENT_START: case GST_MESSAGE_SEGMENT_DONE: //case GST_MESSAGE_DURATION: case GST_MESSAGE_LATENCY: case GST_MESSAGE_ASYNC_START: case GST_MESSAGE_ASYNC_DONE: case GST_MESSAGE_REQUEST_STATE: case GST_MESSAGE_STEP_START: case GST_MESSAGE_QOS: default: if (verbose) { g_print ("message: %s\n", GST_MESSAGE_TYPE_NAME (message)); } break; } return TRUE; }
void QGstreamerPlayerSession::busMessage(const QGstreamerMessage &message) { GstMessage* gm = message.rawMessage(); if (gm == 0) { // Null message, query current position quint32 newPos = position(); if (newPos/1000 != m_lastPosition) { m_lastPosition = newPos/1000; emit positionChanged(newPos); } double volume = 1.0; g_object_get(G_OBJECT(m_playbin), "volume", &volume, NULL); if (m_volume != int(volume*100)) { m_volume = int(volume*100); emit volumeChanged(m_volume); } } else { //tag message comes from elements inside playbin, not from playbin itself if (GST_MESSAGE_TYPE(gm) == GST_MESSAGE_TAG) { //qDebug() << "tag message"; GstTagList *tag_list; gst_message_parse_tag(gm, &tag_list); gst_tag_list_foreach(tag_list, addTagToMap, &m_tags); //qDebug() << m_tags; emit tagsChanged(); } if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_playbin)) { switch (GST_MESSAGE_TYPE(gm)) { case GST_MESSAGE_STATE_CHANGED: { GstState oldState; GstState newState; GstState pending; gst_message_parse_state_changed(gm, &oldState, &newState, &pending); #ifdef DEBUG_PLAYBIN QStringList states; states << "GST_STATE_VOID_PENDING" << "GST_STATE_NULL" << "GST_STATE_READY" << "GST_STATE_PAUSED" << "GST_STATE_PLAYING"; qDebug() << QString("state changed: old: %1 new: %2 pending: %3") \ .arg(states[oldState]) \ .arg(states[newState]) \ .arg(states[pending]); #endif switch (newState) { case GST_STATE_VOID_PENDING: case GST_STATE_NULL: setSeekable(false); finishVideoOutputChange(); if (m_state != QMediaPlayer::StoppedState) emit stateChanged(m_state = QMediaPlayer::StoppedState); break; case GST_STATE_READY: setSeekable(false); if (m_state != QMediaPlayer::StoppedState) emit stateChanged(m_state = QMediaPlayer::StoppedState); break; case GST_STATE_PAUSED: { QMediaPlayer::State prevState = m_state; m_state = QMediaPlayer::PausedState; //check for seekable if (oldState == GST_STATE_READY) { getStreamsInfo(); updateVideoResolutionTag(); /* //gst_element_seek_simple doesn't work reliably here, have to find a better solution GstFormat format = GST_FORMAT_TIME; gint64 position = 0; bool seekable = false; if (gst_element_query_position(m_playbin, &format, &position)) { seekable = gst_element_seek_simple(m_playbin, format, GST_SEEK_FLAG_NONE, position); } setSeekable(seekable); */ setSeekable(true); if (!qFuzzyCompare(m_playbackRate, qreal(1.0))) { qreal rate = m_playbackRate; m_playbackRate = 1.0; setPlaybackRate(rate); } } if (m_state != prevState) emit stateChanged(m_state); break; } case GST_STATE_PLAYING: if (m_state != QMediaPlayer::PlayingState) emit stateChanged(m_state = QMediaPlayer::PlayingState); break; } } break; case GST_MESSAGE_EOS: emit playbackFinished(); break; case GST_MESSAGE_TAG: case GST_MESSAGE_STREAM_STATUS: case GST_MESSAGE_UNKNOWN: break; case GST_MESSAGE_ERROR: { GError *err; gchar *debug; gst_message_parse_error (gm, &err, &debug); emit error(int(QMediaPlayer::ResourceError), QString::fromUtf8(err->message)); qWarning() << "Error:" << QString::fromUtf8(err->message); g_error_free (err); g_free (debug); } break; case GST_MESSAGE_WARNING: { GError *err; gchar *debug; gst_message_parse_warning (gm, &err, &debug); qWarning() << "Warning:" << QString::fromUtf8(err->message); g_error_free (err); g_free (debug); } break; case GST_MESSAGE_INFO: #ifdef DEBUG_PLAYBIN { GError *err; gchar *debug; gst_message_parse_info (gm, &err, &debug); qDebug() << "Info:" << QString::fromUtf8(err->message); g_error_free (err); g_free (debug); } #endif break; case GST_MESSAGE_BUFFERING: { int progress = 0; gst_message_parse_buffering(gm, &progress); emit bufferingProgressChanged(progress); } break; case GST_MESSAGE_STATE_DIRTY: case GST_MESSAGE_STEP_DONE: case GST_MESSAGE_CLOCK_PROVIDE: case GST_MESSAGE_CLOCK_LOST: case GST_MESSAGE_NEW_CLOCK: case GST_MESSAGE_STRUCTURE_CHANGE: case GST_MESSAGE_APPLICATION: case GST_MESSAGE_ELEMENT: break; case GST_MESSAGE_SEGMENT_START: { const GstStructure *structure = gst_message_get_structure(gm); qint64 position = g_value_get_int64(gst_structure_get_value(structure, "position")); position /= 1000000; m_lastPosition = position; emit positionChanged(position); } break; case GST_MESSAGE_SEGMENT_DONE: break; case GST_MESSAGE_DURATION: { GstFormat format = GST_FORMAT_TIME; gint64 duration = 0; if (gst_element_query_duration(m_playbin, &format, &duration)) { int newDuration = duration / 1000000; if (m_duration != newDuration) { m_duration = newDuration; emit durationChanged(m_duration); } } } break; case GST_MESSAGE_LATENCY: #if (GST_VERSION_MAJOR >= 0) && (GST_VERSION_MINOR >= 10) && (GST_VERSION_MICRO >= 13) case GST_MESSAGE_ASYNC_START: case GST_MESSAGE_ASYNC_DONE: #if GST_VERSION_MICRO >= 23 case GST_MESSAGE_REQUEST_STATE: #endif #endif case GST_MESSAGE_ANY: break; default: break; } } else if (m_videoSink && m_renderer && GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoSink) && GST_MESSAGE_TYPE(gm) == GST_MESSAGE_STATE_CHANGED) { GstState oldState; GstState newState; gst_message_parse_state_changed(gm, &oldState, &newState, 0); if (oldState == GST_STATE_READY && newState == GST_STATE_PAUSED) m_renderer->precessNewStream(); } } }
static gboolean handle_message (InsanityGstPipelineTest * ptest, GstMessage * message) { gboolean ret = FALSE, done = FALSE; /* Allow the test code to handle the message instead */ g_signal_emit (ptest, bus_message_signal, 0, message, &ret); if (!ret) return FALSE; switch (GST_MESSAGE_TYPE (message)) { case GST_MESSAGE_ERROR:{ GError *error = NULL; char *debug = NULL; gst_message_parse_error (message, &error, &debug); send_error (ptest, error, debug); insanity_test_printf (INSANITY_TEST (ptest), "Error (%s, %s), quitting\n", error->message, debug); g_error_free (error); g_free (debug); done = TRUE; break; } case GST_MESSAGE_STATE_CHANGED: if (GST_MESSAGE_SRC (message) == GST_OBJECT (ptest->priv->pipeline)) { GstState oldstate, newstate, pending; gst_message_parse_state_changed (message, &oldstate, &newstate, &pending); if (newstate >= GST_STATE_PAUSED) { gint i; for (i = 0; i < G_N_ELEMENTS (duration_query_formats); i++) insanity_gst_pipeline_test_query_duration (ptest, duration_query_formats[i], NULL); } if (newstate == ptest->priv->initial_state && pending == GST_STATE_VOID_PENDING && !ptest->priv->reached_initial_state) { gboolean ret = TRUE; ptest->priv->reached_initial_state = TRUE; insanity_test_validate_checklist_item (INSANITY_TEST (ptest), "reached-initial-state", TRUE, NULL); /* Tell the test we reached our initial state */ g_signal_emit (ptest, reached_initial_state_signal, 0, &ret); if (!ret) { insanity_test_printf (INSANITY_TEST (ptest), "Reached initial state, and asked to quit, quitting\n"); done = TRUE; } } } break; case GST_MESSAGE_TAG:{ GstTagList *tags; gst_message_parse_tag (message, &tags); gst_tag_list_foreach (tags, &send_tag, (gpointer) ptest); gst_tag_list_unref (tags); break; } case GST_MESSAGE_DURATION_CHANGED:{ gint i; for (i = 0; i < G_N_ELEMENTS (duration_query_formats); i++) insanity_gst_pipeline_test_query_duration (ptest, duration_query_formats[i], NULL); break; } case GST_MESSAGE_EOS: if (GST_MESSAGE_SRC (message) == GST_OBJECT (ptest->priv->pipeline)) { /* Warning from the original Python source: # it's not 100% sure we want to stop here, because of the # race between the final state-change message and the eos message # arriving on the bus. */ if (ptest->priv->reached_initial_state) { insanity_test_printf (INSANITY_TEST (ptest), "Got EOS from pipeline, and we reached initial state, quitting\n"); done = TRUE; } else { /* If we've not seen the state change to initial state yet, we give an extra 3 seconds for it to complete */ insanity_test_printf (INSANITY_TEST (ptest), "Got EOS from pipeline, and we did not reach initial state, delaying quit\n"); ptest->priv->wait_timeout_id = g_timeout_add (3000, (GSourceFunc) & waiting_for_state_change, ptest); } } break; case GST_MESSAGE_BUFFERING:{ gint percent; gst_message_parse_buffering (message, &percent); /* no state management needed for live pipelines */ if (ptest->priv->is_live || !ptest->priv->enable_buffering) break; if (percent == 100) { /* a 100% message means buffering is done */ ptest->priv->buffering = FALSE; /* if the desired state is playing, go back */ if (ptest->priv->initial_state == GST_STATE_PLAYING) { gst_element_set_state (GST_ELEMENT (ptest->priv->pipeline), GST_STATE_PLAYING); } } else { /* buffering busy */ if (ptest->priv->buffering == FALSE && ptest->priv->initial_state == GST_STATE_PLAYING) { /* we were not buffering but PLAYING, PAUSE the pipeline. */ gst_element_set_state (GST_ELEMENT (ptest->priv->pipeline), GST_STATE_PAUSED); } ptest->priv->buffering = TRUE; } break; case GST_MESSAGE_CLOCK_LOST: gst_element_set_state (GST_ELEMENT (ptest->priv->pipeline), GST_STATE_PAUSED); gst_element_set_state (GST_ELEMENT (ptest->priv->pipeline), GST_STATE_PLAYING); break; } default: break; } return done; }
/* 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; } }