tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
3
ZUGRIFFE
567
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    Der Wolf Der Wolf ist offline Mitglied Gold
    Registriert seit
    Aug 2007
    Beiträge
    158
    Hallo Leute,

    ich versuche gerade eine GStreamer Kette zu bauen und auf ihren Bus zu hören. Allerdings startet die Kette nicht, beziehungsweise ich schaffe es nicht, ihre einzelnen Kettenglieder zu verlinken.

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    
    #include <iostream>
    #include <gst/gst.h>
     
     
    int
    main(int argc, char* argv[]) {
     
        gst_init(&argc, &argv);
     
        GMainLoop *loop = g_main_loop_new(NULL, FALSE);
        GstElement *pipeline = gst_pipeline_new("analyse");
        GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
     
    //  g_object_set(G_OBJECT(pipeline), "gst-debug-level", "2", NULL);
     
        GstElement *source = gst_element_factory_make("filesrc", "src");
        g_object_set(G_OBJECT(source), "location", argv[1], NULL);
     
    //  GstElement *source = gst_element_factory_make("alsasrc", "src");
    //  g_object_set(G_OBJECT(source), "device", "plug:hw:1", NULL);
     
        GstElement *decoder = gst_element_factory_make("decodebin", "decoder");
     
        GstElement *spectrum = gst_element_factory_make("spectrum", "spectrum");
     
        GstElement *queue = gst_element_factory_make("queue", "queue1");
     
        GstElement *audioconvert = gst_element_factory_make("audioconvert", "convert");
            
        GstElement *sink = gst_element_factory_make("alsasink", "sink");    
     
     
        gst_bin_add_many(GST_BIN(pipeline), source, decoder, audioconvert, queue, spectrum, sink, NULL);
     
        if (!gst_element_link_many(source, decoder, sink, NULL)) {
            std::cout << "Could not link all elements together." << std::endl;
            GstMessage *msg = gst_bus_poll(bus, GST_MESSAGE_ERROR, 0);
            if (msg) {
          GError *err = NULL;
     
          gst_message_parse_error (msg, &err, NULL);
          g_print ("ERROR: %s\n", err->message);
          g_error_free (err);
          gst_message_unref (msg);
            } else {
                std::cout << "No error message available." << std::endl;
            }
            return -1;
        } else {
            std::cout << "All linked together." << std::endl;
        }
     
        GstStateChangeReturn ret = gst_element_set_state (pipeline, GST_STATE_PLAYING);
        if (ret == GST_STATE_CHANGE_FAILURE) {
            GstMessage *msg;
     
        g_print ("Failed to start up pipeline!\n");
     
        /* check if there is an error message with details on the bus */
        msg = gst_bus_poll (bus, GST_MESSAGE_ERROR, 0);
        if (msg) {
          GError *err = NULL;
     
          gst_message_parse_error (msg, &err, NULL);
          g_print ("ERROR: %s\n", err->message);
          g_error_free (err);
          gst_message_unref (msg);
            }
        }
      g_main_loop_run (loop);
     
      /* clean up */
      gst_element_set_state (pipeline, GST_STATE_NULL);
      gst_object_unref (pipeline);
     
    }

    Das müsste in etwa in der Kette:

    Code :
    1
    
    gst-launch-0.10 filesrc location=<filelocation> ! decodebin ! alsasink

    enden. Führe ich die Kette so auf der Kommandozeile aus, bekomme ich keine Probleme. Stelle ich sich im oben genannten Code zusammen bekomme, meckert er beim linken der einzelnen Glieder. Allerdings habe ich keine Ahnung wo da das Problem liegt, weil ich keine Fehlerausgaben oder Debugausgaben bekomme. Ich weiss, dass ich auf der Kommandozeile mit --gst-debug-level=2 mir Debugausgaben anzeigen lassen kann, allerdings weiss ich nicht, wie das oben im Code angegeben werden soll. Ich bin für jede Hilfe dankbar.

    Gruß
    Der Wolf
     

  2. #2
    deepthroat deepthroat ist offline Mitglied Diamant
    tutorials.de Premium-User
    Registriert seit
    Jun 2005
    Beiträge
    8.168
    Hi.
    Zitat Zitat von Der Wolf Beitrag anzeigen
    Stelle ich sich im oben genannten Code zusammen bekomme, meckert er beim linken der einzelnen Glieder.
    Wer meckert? Was meckert er?
    Zitat Zitat von Der Wolf Beitrag anzeigen
    Allerdings habe ich keine Ahnung wo da das Problem liegt, weil ich keine Fehlerausgaben oder Debugausgaben bekomme. Ich weiss, dass ich auf der Kommandozeile mit --gst-debug-level=2 mir Debugausgaben anzeigen lassen kann, allerdings weiss ich nicht, wie das oben im Code angegeben werden soll.
    Es sollte ausreichen die GST_DEBUG Umgebungsvariable zu setzen. Siehe http://www.gstreamer.net/data/doc/gs...t-running.html

    Gruß
     
    If at first you don't succeed, try again. Then quit. No use being a damn fool about it.

  3. #3
    Der Wolf Der Wolf ist offline Mitglied Gold
    Registriert seit
    Aug 2007
    Beiträge
    158
    Wer meckert? Was meckert er?
    Etwas missverständlich ausgedrückt. Mit meckern meinte ich

    Code :
    1
    
    gst_element_link_many(...)

    liefert false zurück.

    Es sollte ausreichen die GST_DEBUG Umgebungsvariable zu setzen.
    Danke, das hat schonnmal weitergeholfen. Ich hatte bisher nur versucht das im Code direkt per g_object_set zu setzen.

    \edit:

    Ah. Dank der debug Ausgaben habe ich schonmal folgende Meldung gefunden:

    0:00:00.300884621 4816 0x804f008 INFO GST_ELEMENT_PADS gstelement.c:884:gst_element_get_static_pad: no such pad 'src%d' in element "decoder"
    0:00:00.300911476 4816 0x804f008 INFO GST_ELEMENT_PADS gstutils.c:979:gst_element_get_compatible_pad:<decoder> Could not find a compatible pad to link to sink:sink
    Gruß
    Der Wolf
    Geändert von Der Wolf (13.09.10 um 13:32 Uhr) Grund: Debug Ausgaben nachgereicht
     

  4. #4
    Der Wolf Der Wolf ist offline Mitglied Gold
    Registriert seit
    Aug 2007
    Beiträge
    158
    Ok, ich habe es mittlerweile herausgefunden.
    Anscheinend kann man das decodebin nicht so einfach in die Kette einfügen. Hier mal der neue Code, mit dem es bei mir funktioniert.

    Code c:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    
    #include <iostream>
    #include <gst/gst.h>
     
    GstElement *audio;
     
    static gboolean 
    callback(GstBus *bus, GstMessage *msg, gpointer data) {
     
        if (msg->type == GST_MESSAGE_ELEMENT) {
     
            const GstStructure *s = gst_message_get_structure(msg);
            const gchar *name = gst_structure_get_name(s);      
            
            if (strcmp(name, "spectrum") == 0) {
                std::cout << "New spectrum received." << std::endl;
        }
     
        }
     
        return true;
     
    }
     
    static void
    cb_newpad (GstElement *decodebin,
           GstPad     *pad,
           gboolean    last,
           gpointer    data) {
      GstCaps *caps;
      GstStructure *str;
      GstPad *audiopad;
     
      /* only link once */
      audiopad = gst_element_get_static_pad (audio, "sink");
      if (GST_PAD_IS_LINKED (audiopad)) {
        g_object_unref (audiopad);
        return;
      }
     
      /* check media type */
      caps = gst_pad_get_caps (pad);
      str = gst_caps_get_structure (caps, 0);
      if (!g_strrstr (gst_structure_get_name (str), "audio")) {
        gst_caps_unref (caps);
        gst_object_unref (audiopad);
        return;
      }
      gst_caps_unref (caps);
     
      /* link'n'play */
      gst_pad_link (pad, audiopad);
     
      g_object_unref (audiopad);
    }
     
     
     
    int
    main(int argc, char* argv[]) {
     
        gst_init(&argc, &argv);
     
        GMainLoop *loop = g_main_loop_new(NULL, FALSE);
        GstElement *pipeline = gst_pipeline_new("analyse");
        GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
        gst_bus_add_watch(bus, callback, loop);
     
        // Creating audio src bin.  
        GstElement *source = gst_element_factory_make("filesrc", "src");
        GstElement *decoder = gst_element_factory_make("decodebin", "decoder");
        g_signal_connect (decoder, "new-decoded-pad", G_CALLBACK (cb_newpad), NULL);
     
        g_object_set(G_OBJECT(source), "location", argv[1], NULL);
     
        gst_bin_add_many(GST_BIN(pipeline), source, decoder, NULL);
        gst_element_link(source, decoder);
     
        // Creating audio output.
        audio = gst_bin_new ("audiobin");
        GstElement *spectrum = gst_element_factory_make("spectrum", "spectrum");
      GstElement *conv = gst_element_factory_make ("audioconvert", "aconv");
      GstPad *audiopad = gst_element_get_static_pad (conv, "sink");
      GstElement *sink = gst_element_factory_make ("alsasink", "sink");
      gst_bin_add_many (GST_BIN(audio), spectrum, conv, sink, NULL);
      gst_element_link_many (conv, spectrum, sink);
      gst_element_add_pad(audio, gst_ghost_pad_new ("sink", audiopad));
      gst_object_unref (audiopad);
      gst_bin_add (GST_BIN (pipeline), audio);
     
        /* run */
      gst_element_set_state (pipeline, GST_STATE_PLAYING);
      g_main_loop_run (loop);
     
      /* cleanup */
      gst_element_set_state (pipeline, GST_STATE_NULL);
      gst_object_unref (GST_OBJECT (pipeline));
     
      return 0;
     
    }

    Ich bin im Developer-Part der GStreamer Dokumentation auf die Lösung gestoßen (bitte keinen Kommentar -.- ). Die Kette enthält jetzt zusätzlich auch noch ein plugin das das Spektrum des Signals analysiert und das Ergebnis auf dem Bus published.

    Gruß
    Der Wolf
     

Ähnliche Themen

  1. GStreamer mit perl
    Von ToPeG im Forum CGI, Perl, Python, Ruby, Power Shell
    Antworten: 2
    Letzter Beitrag: 10.10.10, 16:40
  2. GStreamer und FFT
    Von Der Wolf im Forum C/C++
    Antworten: 8
    Letzter Beitrag: 30.08.10, 16:16
  3. Render-Pipeline von C4D
    Von Padrenuestro im Forum Cinema 4D
    Antworten: 1
    Letzter Beitrag: 19.01.09, 14:33
  4. GStreamer und GTK
    Von MS47475 im Forum C/C++
    Antworten: 0
    Letzter Beitrag: 13.01.08, 20:03
  5. Pipeline?
    Von DeMuX im Forum Netzwerke
    Antworten: 6
    Letzter Beitrag: 15.09.02, 14:54