Multi channel Pipeline

diegoavila diego_javila at hotmail.com
Mon Oct 21 16:04:32 UTC 2019


Hello Nicolas this is my actual code :
#include <gst/gst.h>
#include <gst/app/gstappsrc.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


#include <gdk-pixbuf/gdk-pixbuf.h>
#define CHUNK_SIZE  4096
typedef struct {
    GstPipeline *pipeline;
    GstAppSrc *src;
    GstElement *sink;
    GstElement *decoder;
    GstElement *audio_convert;
    GstElement *audiosink;
    GstElement *deinterleave;
    GstElement *resample;
    GMainLoop *loop;
    guint sourceid;
    GMappedFile *file;
    guint8 *data;
    gsize length;
    guint64 offset;
}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 void print_pad_capabilities (GstElement *element, gchar *pad_name) {

  GstPad *pad = NULL;

  GstCaps *caps = NULL;

  /* Retrieve pad */

  pad = gst_element_get_static_pad (element, pad_name);

  if (!pad) {

    g_printerr ("Could not retrieve pad '%s'\n", pad_name);

    return;

  }

  /* Retrieve negotiated caps (or acceptable caps if negotiation is not
finished yet) */

  caps = gst_pad_get_current_caps (pad);

  if (!caps)

    caps = gst_pad_query_caps (pad, NULL);

  /* Print and free */

  g_print ("Caps for the %s pad:\n", pad_name);

  print_caps (caps, "      ");

  gst_caps_unref (caps);

  gst_object_unref (pad);

}
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, *aconv, *ares, *appsink;

                queue = gst_element_factory_make("queue",  NULL);

                aconv = gst_element_factory_make("audioconvert", NULL);

                appsink = gst_element_factory_make("alsasink", NULL);

               

                gst_bin_add_many (GST_BIN (data->pipeline), queue, aconv,
appsink, NULL);

                 gst_element_link(queue, aconv);

                 gst_element_link(aconv,appsink);

       

                g_object_set(G_OBJECT (appsink), "sync", FALSE, NULL);

               

                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;
    GstPad *tee_audio_pad, *tee_video_pad, *tee_app_pad;
    GstPad *queue_audio_pad, *queue_video_pad, *queue_app_pad;

  /* try to open the file as an mmapped file */
    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);
    }
    /* get some vitals, this will be used to read data from the mmapped file
and
    * feed it to appsrc. */
    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", "src");
    app->audio_convert = gst_element_factory_make("audioconvert",
"myaudio_convert");
    app->audiosink = gst_element_factory_make("alsasink", "d");
    app->deinterleave = gst_element_factory_make("deinterleave", NULL);

    g_assert(app->src);
    g_assert(app->decoder);
    g_assert(app->audio_convert);
    g_assert(app->audiosink);
    g_assert(app->deinterleave);

    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->audio_convert);
    g_signal_connect (app->deinterleave, "pad-added", G_CALLBACK
(il_new_pad), app);
   // GstCaps *bufcaps=gst_caps_from_string (" audio/x-raw,
format=(string)S16LE, layout=(string)interleaved, rate=(int)44100,
channels=(int)6, channel-mask=(bitmask)0x000000000000003f");
   // g_object_set(G_OBJECT(app->src), "caps", bufcaps, NULL); 

    gst_bin_add_many(GST_BIN(app->pipeline), (GstElement*)app->src,
app->decoder, app->audio_convert, app->audiosink,app->deinterleave,  NULL);
    

    if(!gst_element_link((GstElement*)app->src, app->decoder)){
        g_warning("failed to link src anbd decoder");
    }
    if(!gst_element_link(app->audio_convert, app->deinterleave)){
        g_warning("failed to link audio_convert and deinterleave");
    }
    if(!gst_element_link(app->audio_convert, app->audiosink)){
        g_warning("failed to link audio_convert and audiosink");
    }

    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;
}
My main problem is that i cant convert the mp3 to 6 channel , could you help
me please



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


More information about the gstreamer-devel mailing list