Appsrc + decodebin + deinterleave + interleave HELP
diegoavila
diego_javila at hotmail.com
Thu Oct 24 17:03:43 UTC 2019
Hey, I have a problem on my code, its almost done but i cant make that my
queue pads get linked to my sink if i link my sink pads it plays but im not
sure if its a multichannel pipeline because i tried to set volume 0 to each
channel and didtn work
This is my code :
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <stdlib.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#define CHUNK_SIZE 4096
typedef struct {
GstPipeline *pipeline;
GstAppSrc *src;
GstElement *sink;
GstElement *decoder;
GstElement *audioconvert;
GstElement *audiosink;
GstElement *audioresample;
GstElement *deinterleave;
GstElement *interleave;
GMainLoop *loop;
guint sourceid;
GMappedFile *file;
guint8 *data;
gsize length;
guint64 offset;
GstCaps *caps;
}gst_app_t;
static gst_app_t gst_app;
#define BUFF_SIZE (1024)
static gboolean print_field (GQuark field, const GValue * value, gpointer
pfx) {
gchar *str = gst_value_serialize (value);
g_print ("%s %15s: %s\n", (gchar *) pfx, g_quark_to_string (field), str);
g_free (str);
return TRUE;
}
static void print_caps (const GstCaps * caps, const gchar * pfx) {
guint i;
g_return_if_fail (caps != NULL);
if (gst_caps_is_any (caps)) {
g_print ("%sANY\n", pfx);
return;
}
if (gst_caps_is_empty (caps)) {
g_print ("%sEMPTY\n", pfx);
return;
}
for (i = 0; i < gst_caps_get_size (caps); i++) {
GstStructure *structure = gst_caps_get_structure (caps, i);
g_print ("%s%s\n", pfx, gst_structure_get_name (structure));
gst_structure_foreach (structure, print_field, (gpointer) pfx);
}
}
static gboolean read_data(gst_app_t *app)
{
GstBuffer *buffer;
guint len;
GstFlowReturn ret;
if (app->offset >= app->length) {
/* we are EOS, send end-of-stream and remove the source */
g_signal_emit_by_name (app->src, "end-of-stream", &ret);
return FALSE;
}
/* read the next chunk */
buffer = gst_buffer_new ();
len = CHUNK_SIZE;
if (app->offset + len > app->length)
len = app->length - app->offset;
gst_buffer_append_memory (buffer,
gst_memory_new_wrapped
(GST_MEMORY_FLAG_READONLY,
app->data,
app->length, app->offset, len, NULL, NULL));
g_print ("feed buffer %p, offset %" G_GUINT64_FORMAT "-%u \n", buffer,
app->offset, len);
g_signal_emit_by_name (app->src, "push-buffer", buffer, &ret);
gst_buffer_unref (buffer);
if (ret != GST_FLOW_OK) {
/* some error, stop sending data */
return FALSE;
}
app->offset += len;
return TRUE;
}
static void start_feed (GstElement * playbin, guint size, gst_app_t * app)
{
if (app->sourceid == 0) {
g_print("Start feeding \n");
app->sourceid = g_idle_add ((GSourceFunc) read_data, app);
}
}
static void stop_feed (GstElement * playbin, gst_app_t * app)
{
if (app->sourceid != 0) {
g_print ("Stop feeding \n");
g_source_remove (app->sourceid);
app->sourceid = 0;
}
}
static void cb_new_pad (GstElement *element, GstPad *pad, gpointer data)
{
gchar *name;
GstElement *other = data;
name = gst_pad_get_name (pad);
g_print ("A new pad %s was created for %s\n", name,
gst_element_get_name(element));
g_free (name);
g_print ("element %s will be linked to %s\n",
gst_element_get_name(element),
gst_element_get_name(other));
gst_element_link(element, other);
}
static gboolean bus_callback(GstBus *bus, GstMessage *message, gpointer
*ptr)
{
gst_app_t *app = (gst_app_t*)ptr;
switch(GST_MESSAGE_TYPE(message)){
case GST_MESSAGE_ERROR:{
gchar *debug;
GError *err;
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(app->loop);
}
break;
case GST_MESSAGE_EOS:
g_print("End of stream\n");
g_main_loop_quit(app->loop);
break;
default:
g_print("got message %s\n", \
gst_message_type_get_name (GST_MESSAGE_TYPE (message)));
break;
}
return TRUE;
}
int _channels=0;
void il_new_pad (GstElement *decodebin, GstPad *pad, gst_app_t * data)
{
GstElement* element=0;
std::cout<<_channels;
if (data->pipeline)
{
GstElement *queue, *audioconvert, *ares, *audiosink
,*interleave, *volume;
queue = gst_element_factory_make("queue", NULL);
audiosink = gst_element_factory_make("alsasink", NULL);
//interleave = gst_element_factory_make("interleave", NULL);
volume = gst_element_factory_make("volume", NULL);
gst_bin_add_many (GST_BIN (data->pipeline), queue, volume,NULL);
if(!gst_element_link((GstElement*)queue, volume)){
g_warning("failed to link queue anbd volume");
}
if(!gst_element_link((GstElement*)volume,data->interleave)){
g_warning("failed to link volume anbd interleave");
}
/*
if(!gst_element_link((GstElement*)data->interleave,data->audiosink)){
g_warning("failed to link volume anbd interleave");
}
*/
g_object_set(G_OBJECT (audiosink), "sync", true, NULL);
//element=data->audiosink;
element= queue;
gst_element_sync_state_with_parent(element);
++_channels;
}
GstCaps *caps;
GstStructure *str;
GstPad *audiopad;
/* only link once */
audiopad = gst_element_get_static_pad (element, "sink");
if (GST_PAD_IS_LINKED (audiopad))
{
g_object_unref (audiopad);
}
/* check media type */
caps = gst_pad_query_caps (pad,NULL);
print_caps(caps, " ");
str = gst_caps_get_structure (caps, 0);
if (!g_strrstr (gst_structure_get_name (str), "audio"))
{
std::cerr<<"won't connect!"<<std::endl;
gst_caps_unref (caps);
gst_object_unref (audiopad);
}
gst_caps_unref (caps);
/* link'n'play */
gst_pad_link (pad, audiopad);
}
int main(int argc, char *argv[])
{
gst_app_t *app = &gst_app;
GstBus *bus;
GError *error = NULL;
GstStateChangeReturn state_ret;
app->file = g_mapped_file_new ("/home/arion/Downloads/test2.mp3", FALSE,
&error);
if (error) {
g_print ("failed to open file: %s \n", error->message);
g_error_free (error);
}
app->length = g_mapped_file_get_length (app->file);
app->data = (guint8 *) g_mapped_file_get_contents (app->file);
app->offset = 0;
gst_init(NULL, NULL);
app->pipeline = (GstPipeline*)gst_pipeline_new("mypipeline");
bus = gst_pipeline_get_bus(app->pipeline);
gst_bus_add_watch(bus, (GstBusFunc)bus_callback, app);
gst_object_unref(bus);
app->src = (GstAppSrc*)gst_element_factory_make("appsrc", "mysrc");
app->decoder = gst_element_factory_make("decodebin", "mydecoder");
app->audioconvert = gst_element_factory_make("audioconvert",
"myaudioconvert");
app->audiosink = gst_element_factory_make("alsasink", "myvsink");
app->audioresample =
gst_element_factory_make("audioresample","audio-resample");
app->deinterleave = gst_element_factory_make("deinterleave", "deint");
app->interleave = gst_element_factory_make("interleave", "int");
g_assert(app->src);
g_assert(app->decoder);
g_assert(app->audioconvert);
g_assert(app->audiosink);
g_assert(app->audioresample);
g_assert(app->deinterleave);
g_assert(app->interleave);
g_object_set (app->interleave, "name", "i", NULL);
g_object_set (app->src, "size", (gint64) app->length, NULL);
g_signal_connect(app->src, "need-data", G_CALLBACK(start_feed), app);
g_signal_connect(app->src, "enough-data", G_CALLBACK(stop_feed), app);
g_signal_connect(app->decoder, "pad-added", G_CALLBACK(cb_new_pad),
app->audioresample);
g_signal_connect(app->deinterleave, "pad-added",
G_CALLBACK(il_new_pad),app);
app->caps = gst_caps_new_simple ("audio/x-raw", "format", G_TYPE_STRING,
"S16LE", "layout",
G_TYPE_STRING, "interleaved", "rate", G_TYPE_INT, (int)44100,
"channels", G_TYPE_INT, (int)6, NULL);
gst_bin_add_many(GST_BIN(app->pipeline), (GstElement*)app->src,
app->decoder,
app->audioconvert,app->audioresample,app->deinterleave,app->interleave,
app->audiosink, NULL);
gboolean link_ok = gst_element_link_filtered (app->audioconvert,
app->deinterleave, app->caps);
gst_caps_unref (app->caps);
if (!link_ok) {
g_warning ("Failed to link element1 and element2!");
}
if(!gst_element_link((GstElement*)app->src, app->decoder)){
g_warning("failed to link src anbd decoder");
}
if(!gst_element_link((GstElement*)app->audioresample,
app->audioconvert)){
g_warning("failed to link audioresample anbd audioconvert");
}
/* if(!gst_element_link((GstElement*)app->deinterleave,
app->interleave)){
g_warning("failed to link deinterleave anbd interleave");
}
*/
state_ret = gst_element_set_state((GstElement*)app->pipeline,
GST_STATE_PLAYING);
g_warning("set state returned %d\n", state_ret);
app->loop = g_main_loop_new(NULL, FALSE);
printf("Running main loop\n");
g_main_loop_run(app->loop);
state_ret = gst_element_set_state((GstElement*)app->pipeline,
GST_STATE_NULL);
g_warning("set state null returned %d\n", state_ret);
return 0;
}
<http://gstreamer-devel.966125.n4.nabble.com/file/t378976/pipeline.png>
--
Sent from: http://gstreamer-devel.966125.n4.nabble.com/
More information about the gstreamer-devel
mailing list