Ich versuche, mit GStreamer ein MP4-Video aus einer Datei abzuspielen. Ich habe es geschafft, die Datei mit playbin2 und von der Eingabeaufforderung mit abzuspielen:
gst-launch filesrc location=bbb.mp4 ! decodebin2 ! autovideosink
Ich rechne damit, dass ich in Zukunft kompliziertere Pipelines erstellen muss, und deshalb versuche ich, die Pipeline zu "programmieren". In meinem Programm versuche ich, die obige Pipeline nachzubilden, aber ich habe ein Problem, von dem ich vermute, dass es mit dem Anschluss des dynamischen oder "manchmal" Quellpads von decodebin2 an die Autovideosenke zusammenhängt. Ich verwende diese Elemente nur, um die Dinge so einfach wie möglich zu halten.
static void on_new_decoded_pad(GstElement* object,
GstPad* arg0,
gboolean arg1,
gpointer user_data)
{
// dynamically connect decoderbin2 src pad to autovideosink sink pad
}
static gboolean bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
// handle bus messages
}
int main(int argc, char *argv[])
{
GMainLoop *loop;
GstElement *pipeline, *source, *decodebin, *videosink;
GstBus *bus;
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
pipeline = gst_pipeline_new ("pipeline");
source = gst_element_factory_make("filesrc", "source");
decodebin = gst_element_factory_make("decodebin2", "decodebin");
videosink = gst_element_factory_make("autovideosink", "videosink");
/* check elements were created successfully */
if (!pipeline || !source || !decodebin || !videosink) {
// Failed to create element. Exit Program
return -1;
}
/* apply properties to elements before adding to pipeline */
gchar * filename = "bbb.mp4";
g_object_set(G_OBJECT(source), "location", filename, NULL);
/* add a message handler */
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);
/* add elements to pipeline (and bin if necessary) before linking them */
gst_bin_add_many(GST_BIN (pipeline),
source,
decodebin,
videosink,
NULL);
gst_element_link_pads(source, "src", decodebin, "sink");
/* decodebins src pad is a sometimes pad - it gets created dynamically */
g_signal_connect(decodebin, "new-decoded-pad", G_CALLBACK(on_new_decoded_pad), videosink);
/* run pipeline */
gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
g_main_loop_run(loop);
gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL);
gst_object_unref (pipeline);
return 0;
}
Was ich erwarte, wenn ich dieses Programm ausführe, ist, dass das on_new_decoded_pad über eine Callback-Funktion aufgerufen wird, die in der Zeile festgelegt ist:
g_signal_connect(decodebin, "new-decoded-pad", G_CALLBACK(on_new_decoded_pad), videosink);
und würde es mir ermöglichen, die Pads entsprechend zu verbinden. Aber es wird nie aufgerufen. Tatsächlich scheint das Programm vollständig durchzulaufen und dann einfach zu beenden (die Hauptschleife tut nichts).
Ich würde es wirklich zu schätzen wissen, wenn jemand darauf hinweisen könnte, was ich in Bezug auf den Rückruf falsch gemacht habe oder erklären, was sonst getan werden muss, damit dieses Beispiel mp4 mit den bereitgestellten Elementen abspielen kann.
Herzliche Grüße.