Hi,
I’m trying to create the following pipeline:
filesrc → qtdemux → h264parse → omxh264dec → nvvidconv → appsink
But when I run the pipeline I get a “Error: Gstreamer encountered a general stream error.”. What confuses me is when I use gst-launch-1.0 to start a similar pipeline (xvimagesink instead of appsink) it works fine.
Here’s my code
#include <gst/gst.h>
#include <gst/app/gstappsink.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
static GstElement *pipeline;
static gboolean
bus_call (GstBus *bus, GstMessage *msg, gpointer data)
{
/* Watches for messages on the pipeline bus. */
GMainLoop *loop = (GMainLoop *) data;
switch (GST_MESSAGE_TYPE (msg)) {
case GST_MESSAGE_EOS: {
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;
}
default:
break;
}
return TRUE;
}
static int
on_new_sample_from_sink (GstAppSink * elt)
{
GstSample *sample;
GstBuffer *buffer;
GstMapInfo map;
/* get the sample from appsink */
sample = gst_app_sink_pull_sample(elt);
buffer = gst_sample_get_buffer(sample);
/* make a copy */
if (gst_buffer_map (buffer, &map, GST_MAP_READ)) {
printf("%ld\n", map.size);
gst_buffer_unmap (buffer, &map);
}
/* we don't need the appsink sample anymore */
gst_sample_unref (sample);
return 0;
}
int
main (int argc, char *argv[])
{
printf("========================================================\n");
printf("Usage:\n\n ./producer [VIDEOFILE_PATH]\n");
printf("\n========================================================\n");
if (argc != 2) exit(0);
/* Initialize GStreamer */
gst_init(NULL, NULL);
GMainLoop *loop = g_main_loop_new(NULL, FALSE);
pipeline = gst_pipeline_new(NULL);
/* Set up GStreamer Bus Message Handler */
GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
guint bus_watch_id = gst_bus_add_watch(bus, bus_call, loop);
gst_object_unref(bus);
/* Create GStreamer Elements */
GstElement *src = gst_element_factory_make("filesrc", NULL);
GstElement *demux = gst_element_factory_make("qtdemux", NULL);
GstElement *h264parse = gst_element_factory_make("h264parse", NULL);
GstElement *h264dec = gst_element_factory_make("omxh264dec", NULL);
GstElement *nvconv = gst_element_factory_make("nvvidconv", NULL);
GstElement *appsink = gst_element_factory_make("appsink", NULL);
if ( !src || !demux || !h264parse || !h264dec || !nvconv || !appsink )
{
printf("error\n");
exit(0);
}
/* Add all elements to the pipeline */
gst_bin_add_many(GST_BIN(pipeline), src, demux, h264parse, h264dec, nvconv, appsink, NULL);
g_object_set(src, "location", argv[1], NULL);
g_object_set(appsink, "emit-signals", TRUE, "sync", FALSE, NULL);
g_signal_connect (appsink, "new-sample", G_CALLBACK (on_new_sample_from_sink), NULL);
/* Link elements */
gst_element_link_many(src, demux, h264parse, h264dec, nvconv, appsink, NULL);
/* Start Pipeline */
g_print("Starting Pipeline\n");
gst_element_set_state (pipeline, GST_STATE_PLAYING);
g_main_loop_run(loop);
/* After EOS shuts down loop, run cleanup */
g_print("\nCleaning up Pipeline\n");
gst_element_set_state(pipeline, GST_STATE_NULL);
gst_object_unref(pipeline);
g_source_remove(bus_watch_id);
g_main_loop_unref(loop);
return 0;
}