Crash when trying to stop pipeline containing encodebin
Michael Guinzbourg
mguinzbourg at gmail.com
Thu May 12 01:21:46 UTC 2016
I've made for you very simple application which you can use to reproduce
the problem. It takes the video stream as a source, decodes it, encodes it
into mpeg2, mux it into mpegts container, saves it to file. you can use any
video file as a source. As the file reaches the end pipeline receives EOS
event, at the event I try to set pipeline to GST_STATE_READY, it causes a
crash. Here's complete code below. I will try to give you backtrace with
gdb later.
typedef struct _CustomData {
//GstElement *pipeline;
GstElement *source;
GstElement *convert;
GstElement *q;
GstElement *q1;
GstElement *sink;
GstElement *filter;
GstCaps *filtercaps;
} CustomData;
static CustomData data;
GstElement *pipeline;
GstElement *ebin;
GstEncodingProfile *prof;
GstBus *bus;
GstMessage *msg;
GstStateChangeReturn ret;
GstPadLinkReturn res;
GMainLoop *loop;
gchar *format= "video/mpegts,systemstream=True,packetsize=188";
gchar *aformat= "audio/mpeg, mpegversion=(int)4, rate=(int)16000,
stream-format=(string)adts, base-profile=(string)lc, bitrate=(int)192";
//audio/x-ac3";
gchar *vformat= "video/mpeg,mpegversion=2,systemstream=False,
bitrate=(int)7500";//"video/x-h264";
static GstEncodingProfile *
create_profile (GstCaps * cf, GstCaps * vf, GstCaps * af)
{
GstEncodingContainerProfile *cprof = NULL;
GstEncodingProfile * vtmp = NULL;
cprof = gst_encoding_container_profile_new ((gchar *)
"test-application-profile", NULL, cf, NULL);
if (vf)
{
vtmp = (GstEncodingProfile *) gst_encoding_video_profile_new (vf, NULL,
NULL, 0);
gst_encoding_container_profile_add_profile (cprof, vtmp);
}
if (af)
gst_encoding_container_profile_add_profile (cprof, (GstEncodingProfile
*)
gst_encoding_audio_profile_new (af, NULL, NULL, 0));
/* print out some info */
{
gchar *desc = gst_pb_utils_get_codec_description (cf);
gchar *cd = gst_caps_to_string (cf);
g_print ("Encoding parameters\n");
g_print (" Container format : %s (%s)\n", desc, cd);
g_free (desc);
g_free (cd);
if (vf) {
desc = gst_pb_utils_get_codec_description (vf);
cd = gst_caps_to_string (vf);
g_print (" Video format : %s (%s)\n", desc, cd);
g_free (desc);
g_free (cd);
}
if (af) {
desc = gst_pb_utils_get_codec_description (af);
cd = gst_caps_to_string (af);
g_print (" Audio format : %s (%s)\n", desc, cd);
g_free (desc);
g_free (cd);
}
}
return (GstEncodingProfile *) cprof;
}
static GstEncodingProfile *
create_profile_from_string (gchar * format, gchar * vformat, gchar *
aformat)
{
GstEncodingProfile *prof = NULL;
GstCaps *cf = NULL, *vf = NULL, *af = NULL;
if (format)
cf = gst_caps_from_string (format);
if (vformat)
vf = gst_caps_from_string (vformat);
if (aformat)
af = gst_caps_from_string (aformat);
if (G_UNLIKELY ((vformat && (vf == NULL)) || (aformat && (af == NULL))))
goto beach;
prof = create_profile (cf, vf, af);
beach:
if (cf)
gst_caps_unref (cf);
if (vf)
gst_caps_unref (vf);
if (af)
gst_caps_unref (af);
return prof;
}
gboolean bus_call(GstBus *bus, GstMessage *msg, void *data)
{
gchar *debug;
GError *err;
GMainLoop *loop = (GMainLoop*)data;
switch (GST_MESSAGE_TYPE(msg))
{
case GST_MESSAGE_EOS:
g_print("EOS received on OBJ NAME
%s\n",GST_OBJECT_NAME(msg->src));
//g_main_loop_quit (loop);
gst_element_set_state (pipeline, GST_STATE_READY);
gst_element_set_state (pipeline, GST_STATE_PLAYING);
break;
case GST_MESSAGE_ERROR:
gst_message_parse_error(msg, &err, &debug);
g_free(debug);
g_print("BUS CALL %s\n", err->message);
g_error_free(err);
g_main_loop_quit (loop);
break;
default:
break;
}
return TRUE;
}
/* This function will be called by the pad-added signal */
static void pad_added_handler (GstElement *src, GstPad *new_pad, GstElement
*sink) {
GstPad *gsink_pad = gst_element_get_static_pad (sink, "sink");
GstPadLinkReturn ret;
GstCaps *new_pad_caps = NULL;
GstStructure *new_pad_struct = NULL;
const gchar *new_pad_type = NULL;
g_print ("Received new pad '%s' from '%s':\n", GST_PAD_NAME (new_pad),
GST_ELEMENT_NAME (src));
/* Check the new pad's type */
new_pad_caps = gst_pad_query_caps (new_pad, NULL);
new_pad_struct = gst_caps_get_structure (new_pad_caps, 0);
new_pad_type = gst_structure_get_name (new_pad_struct);
if (!g_str_has_prefix (new_pad_type, "video/x-raw") && !g_str_has_prefix
(new_pad_type, "audio/x-raw")) {
g_print (" It has type '%s' which is not raw video or audio.
Ignoring.\n", new_pad_type);
goto exit;
}
if (g_str_has_prefix (new_pad_type, "video/x-raw"))
{
ret = gst_pad_link (new_pad, gsink_pad);
}
else
{
return;
}
if (GST_PAD_LINK_FAILED (ret)) {
g_print (" Type is '%s' but link failed.\n", new_pad_type);
} else {
g_print (" Link succeeded (type '%s').\n", new_pad_type);
}
exit:
/* Unreference the new pad's caps, if we got them */
if (new_pad_caps != NULL)
gst_caps_unref (new_pad_caps);
/* Unreference the sink pad */
gst_object_unref (gsink_pad);
}
int
main (int argc,
char *argv[])
{
gst_init (&argc, &argv);
g_print ("gstreamer initialized.\n");
/* Create the elements */
data.source = gst_element_factory_make ("uridecodebin", "source");
data.convert = gst_element_factory_make ("videoscale", "convert");
data.q = gst_element_factory_make ("queue", "q");
data.q1 = gst_element_factory_make ("queue", "q1");
data.sink = gst_element_factory_make ("filesink", "sink");
g_object_set (G_OBJECT (data.sink), "location", "c:\\tmp\\channel.ts",
NULL);
data.filter = gst_element_factory_make("capsfilter","filter");
data.filtercaps = gst_caps_new_simple ("video/x-raw",
"format", G_TYPE_STRING, "I420",
"width", G_TYPE_INT, 854,
"height", G_TYPE_INT, 480,
NULL);
g_object_set (G_OBJECT (data.filter), "caps", data.filtercaps, NULL);
g_print ("starting profile initialization\n");
/* Create the profile */
prof = create_profile_from_string (format, vformat, aformat);
if (G_UNLIKELY (prof == NULL)) {
g_print ("Encoding arguments are not valid !\n");
return -1;
}
/* Create the encodebin */
ebin = gst_element_factory_make ("encodebin", NULL);
g_object_set (ebin, "profile", prof, NULL);
/* Create the empty pipeline */
pipeline = gst_pipeline_new ("test-pipeline");
loop = g_main_loop_new (NULL, FALSE);
if (!pipeline || !data.source || !data.q || !data.sink) {
g_printerr ("Not all elements could be created.\n");
return -1;
}
/* Build the pipeline. */
gst_bin_add_many (GST_BIN (pipeline), data.source, data.q,data.convert,
data.filter, ebin, data.q1, data.sink, NULL);
if (!gst_element_link_many (data.q, data.convert, data.filter, ebin,
data.q1, data.sink, NULL)) {
g_printerr ("Elements could not be linked.\n");
gst_object_unref (pipeline);
return -1;
}
/* Set the URI to play */
g_object_set (data.source, "uri", "
http://www.quebec511.info/diffusion/fr/camera/camera.ashx?format=mp4&id=3505",
NULL);
/* Connect to the pad-added signal */
g_signal_connect (data.source, "pad-added", G_CALLBACK
(pad_added_handler), data.q);
/* we add a message handler */
bus = gst_pipeline_get_bus (GST_PIPELINE (pipeline));
gst_bus_add_watch (bus, bus_call, loop);
gst_object_unref (bus);
/* Set the pipeline to "playing" state*/
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* Iterate */
g_print ("Running...\n");
//g_timeout_add_seconds (1, timeout_cb, loop);
g_main_loop_run (loop);
/* Out of the main loop, clean up nicely */
g_print ("Returned, stopping playback\n");
gst_element_set_state (pipeline, GST_STATE_NULL);
g_print ("Deleting pipeline\n");
gst_object_unref (GST_OBJECT (pipeline));
return 0;
}
On 11 May 2016 at 02:33, Sebastian Dröge <sebastian at centricular.com> wrote:
> On Mi, 2016-05-11 at 02:24 -0400, Michael Guinzbourg wrote:
> > I think the issue is very easy to reproduce: build any pipeline which
> > has encodebin element and ask encodebin to encode in mpeg2. then play
> > any file and try to restart pipeline when it reaches the end of file.
>
> Can you provide such code then? That makes it more likely someone tries
> to find the reason for your crash. Your code does not really provide a
> lot of details about what you're doing there.
>
> Also please provide a backtrace of all threads with gdb.
>
> --
> Sebastian Dröge, Centricular Ltd · http://www.centricular.com
>
>
> _______________________________________________
> gstreamer-devel mailing list
> gstreamer-devel at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/gstreamer-devel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/gstreamer-devel/attachments/20160511/fadfb952/attachment-0001.html>
More information about the gstreamer-devel
mailing list