1) Overview
Bus is a simple system that uses its own threading mechanism to distribute messages from a pipe thread to an application. The advantage of the bus is that when GStreamer is used, the application does not require thread recognition, even if GStreamer has been loaded with multiple threads.
Each pipeline contains a bus by default, so the application does not need to create the bus again. The application only needs to set up a message processor on the bus that resembles an object-like signal processor. When the main loop is running, the bus will poll the message processor for new messages, and when the message is captured, the bus will call the appropriate callback function to complete the task.
2) How to use a bus
There are two ways to use the bus, as follows:
I. Run the glib/gtk+ main loop (you can also run the default glib primary loop yourself), and then use the listener to listen for the bus. Using this method, the main loop of the glib will poll for new messages on the bus, and when there is a new message, the bus will notify you immediately. In this case, you will use the Gst_bus_add_watch ()/Gst_bus_add_signal_watch () two functions. When using the bus, the Gst_bus_add_watch () can be used on the bus that sets the message processor to the pipe. To create a message handler to listen for pipelines. Whenever the pipeline sends a message to the bus, the message processor is triggered, and the message processor begins to detect the message signal type to determine which events will be processed. When the processor deletes a message from the bus, its return value should be true.
II. Listen for the bus messages themselves, using Gst_bus_peek () and/or Gst_bus_poll () can be implemented.
#include <gst/gst.h>
Static Gmainloop *loop;
Static Gboolean My_bus_callback (Gstbus *bus, Gstmessage *message, gpointer data)
{
G_print ("Got%s message\n", Gst_message_type_name (message));
Switch (Gst_message_type (MESSAGE)) {
Case Gst_message_error: {
Gerror *err;
Gchar *debug;
Gst_message_parse_error (Message, &err, &debug);
G_print ("Error:%s\n", err->message);
G_error_free (ERR);
G_free (Debug);
G_main_loop_quit (loop);
Break
}
Case Gst_message_eos:
/* End-of-stream */
G_main_loop_quit (loop);
Break
Default
/* Unhandled message */
Break
}
/* We want to being notified again the next time there is a message
* On the bus, so returning TRUE (FALSE means we want to stop watching
* For messages on the bus and we callback should not being called again)
*/
return TRUE;
}
Gint Main (Gint argc, Gchar *argv[])
{
Gstelement *pipeline;
Gstbus *bus;
/* init */
Gst_init (&ARGC, &ARGV);
/* Create pipeline, add handler */
Pipeline = gst_pipeline_new ("My_pipeline");
/* Adds a watch for new message on our pipeline ' s message bus to
* The default GLib main context, which is the main context
* GLib main loop is attached to below
*/
Bus = Gst_pipeline_get_bus (Gst_pipeline (pipeline));
Gst_bus_add_watch (bus, My_bus_callback, NULL);
Gst_object_unref (bus);
//[..]
/* Create a mainloop that runs/iterates the default GLib main context
* (Context NULL), in other words:makes the context check if anything
* It watches for have happened. When a message had been posted on the
* Bus, the default main context would automatically call our
* My_bus_callback () function to notify us of this message.
* The main loop would be run until someone calls G_main_loop_quit ()
*/
loop = G_main_loop_new (NULL, FALSE);
G_main_loop_run (loop);
/* Clean up */
Gst_element_set_state (pipeline, Gst_state_null);
Gst_object_unref (pipeline);
G_main_loop_unref (loop);
return 0;
}
3) Message type (msg types)
GStreamer has several predefined message types that are passed by the bus, and these messages are extensible. Plugins can define additional messages, and the application can have absolute code for these messages or ignore them. It is strongly recommended that the application handle at least the error message and give direct feedback to the user.
All messages have a message source, type, and timestamp. This source can be used to determine which element is sending a message. For example, in numerous messages, the application is only interested in messages from the upper-level pipeline (such as Hints for state transformations). The following lists all the message types, the meaning of the representation, and how to parse the content of the specific message.
1) errors, warnings, and message prompts: they are used by individual components to inform the user of the current state of the pipeline when necessary. The error message indicates a fatal error and terminates the data transfer. The error should be fixed so that the pipeline can continue to work. The warning is not fatal, but implies that there is a problem. A message prompt is used to tell a non-error message. These messages contain a gerror with the primary error type and message, and an optional debug string. Both can use Gst_message_parse_error (), _parse_warning (), and _parse_info () three functions to extract their information. When the use is complete, both the error and the fixup string are freed.
2) Data flow end (End-of-stream) Tip: When the data flow ends, the message is sent. The status of the pipeline will not change, but subsequent media operations will stop. The application can jump to the next song in the playlist by receiving this message. After the data flow end prompt appears, you can still navigate back to the previous location in front of the data stream by searching backwards. After that, the playback will automatically continue to execute. There are no special parameters for this message.
3) Tags: This message is sent when metadata is found in the data stream. A pipeline can emit multiple tags (such as metadata descriptions with artists, song names, and other examples of the stream's information sampling rate and bitrate). The application should store the metadata in the cache. The function Gst_message_parse_tag () is used to parse the list of tags, and the function Gst_tag_list_free () releases its corresponding tag when the list is no longer in use.
4) State Transition (state-changes): The message is sent when the status is successfully converted. The function gst_message_parse_state_changed () can be used to parse the old and new state in the transformation.
5) buffering (buffering): This message is sent when the network data stream is buffered. You can parse the "buffer-percent" property by using the return value of the function gst_message_get_structure () to manually get the buffering progress (the buffer progress is expressed as a percentage).
6) component Message (element messages): It is a special set of messages that identify a particular component. Such a special set of messages usually expresses some additional information. The information for the component should be described in detail, as some component information will be sent to other components as messages. For example, the ' Qtdemux ' QuickTime rectifier (demuxer) should store the ' redirect ' information in the component information in order to send the ' redirect ' component information in a particular case.
7) application-specific Message: We can parse the resulting message structure to get any information about the application-specific message. Typically, this information can be safely ignored.
Application messages are primarily used internally to prepare for the need to arrange information from some threads to the main thread application. These are very useful in applications that use component signals (these signals are emitted in the context of the data flow path).
OpenWrt GStreamer Example Learning Note (five. GStreamer BUS)