Playbin with custom audiosink bin audio/x-raw conversion

Nick_law nicholas at umantec.net
Wed May 19 07:01:23 UTC 2021


Update,
I now get valid audio out, but the data written to file is never longer than
the input file.
But if I switch the sink from file sink to autoaudiosink then the audio out
my speaker does loop.
I'm not sure if the EOS signal is resetting the filesink file?


gboolean bus_callback(GstBus* bus, GstMessage* msg, gpointer data)
{
	GstElement* play = GST_ELEMENT(data);
	switch (GST_MESSAGE_TYPE(msg)) {
		case GST_MESSAGE_EOS:
			/* restart playback if at end */
			//std::cout << "Replay" << std::endl;
			if (!gst_element_seek(play,
								  1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
								  GST_SEEK_TYPE_SET, 0,
								  GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) {
				g_print("Seek failed!\n");
			}
			break;
		default:
			break;
	}
	return TRUE;
}

void Playfile()
{
	GMainLoop* loop;
	GstElement* pipeline;
	GstBus* bus;
	GstMessage* msg;

	/* init GStreamer */
	gst_init(NULL, NULL);
	loop = g_main_loop_new(NULL, FALSE);

	/* set up */
	pipeline = gst_element_factory_make("playbin", "play");
	g_object_set(G_OBJECT(pipeline), "uri",
"file:///home/nick/devel/tnm/analysis/modules/gcc_release_build/ssf_tests/bin/8ch_24bit_1s.wav",
NULL);

	//-------------
	GstElement *bin, *convert, *sink, *filter;
	GstCaps* caps;
	GstPad *pad, *ghost_pad;

	convert = gst_element_factory_make("audioconvert", "convert");
	//sink = gst_element_factory_make("filesink", "audio_sink");
	sink = gst_element_factory_make("autoaudiosink", "audio_sink");

	filter = gst_element_factory_make("capsfilter", "capsfilter");
	if (!convert || !sink) {
		g_printerr("Not all elements could be created.\n");
	}

	caps = gst_caps_new_simple("audio/x-raw",
							   "format", G_TYPE_STRING, "F32LE",
							   "rate", G_TYPE_INT, 48000,
							   "channel-mask", GST_TYPE_BITMASK, 0xff,
							   NULL);

	g_object_set(G_OBJECT(filter), "caps", caps, NULL);
	gst_caps_unref(caps);

	//g_object_set(sink, "location", "stinker", NULL);

	/* Create the sink bin, add the elements and link them */
	bin = gst_bin_new("audio_sink_bin");
	gst_bin_add_many(GST_BIN(bin), filter, convert, sink, NULL);
	gst_element_link_many(filter, convert, sink, NULL);
	pad = gst_element_get_static_pad(filter, "sink");
	ghost_pad = gst_ghost_pad_new("sink", pad);
	gst_pad_set_active(ghost_pad, TRUE);
	gst_element_add_pad(bin, ghost_pad);
	gst_object_unref(pad);

	/* Set playbin's audio sink to be our sink bin */
	g_object_set(GST_OBJECT(pipeline), "audio-sink", bin, NULL);

	//-------------

	gst_element_set_state(pipeline, GST_STATE_PLAYING);
	// gst_element_set_state(pipeline, GST_STATE_PLAYING);

	bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
	gst_bus_add_watch(bus, bus_callback, pipeline);
	gst_object_unref(bus);

	//msg = gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE,
static_cast<GstMessageType>(GST_MESSAGE_ERROR));

	Thread_wrapper mainloop_thread;

	mainloop_thread.Start(
		"mainloop_thread", [&]() {
			g_main_loop_run(loop);
			return false;
		});
	/* now run */

	for (int i = 0; i < 30; ++i) {
		gst_element_set_state(sink, GST_STATE_PLAYING);

		sleep(1);
		std::string name = "test";
		GST_DEBUG_BIN_TO_DOT_FILE(GST_BIN(pipeline), GST_DEBUG_GRAPH_SHOW_ALL,
name.c_str());
		std::cout << i << " seconds" << std::endl;
	}

	g_main_loop_quit(loop);
	mainloop_thread.Stop();

	/* also clean up */
	/* Free resources */
	// if (msg != NULL)
	// 	gst_message_unref(msg);
	gst_object_unref(bus);
	gst_element_set_state(pipeline, GST_STATE_NULL);
	gst_object_unref(GST_OBJECT(pipeline));
}



--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/


More information about the gstreamer-devel mailing list