GStreamer 1.0 — не удается воспроизвести аудио: Ошибка: поток в неправильном формате

#c #gstreamer #gstreamer-1.0

#c #gstreamer #gstreamer-1.0

Вопрос:

Я создал аудиофайл .pcm с помощью следующей команды:

 gst-launch-1.0 filesrc location=/home/pi/rawaudio/can-you-keep-a-secret.wav ! wavparse ! audioresample ! audioconvert ! audio/x-raw,format=S16BE,channels=1,rate=44100,layout=interleaved ! filesink location=/home/pi/rawaudio/test.pcm
  

Я могу воспроизвести его с:

 gst-launch-1.0 filesrc location=/home/pi/rawaudio/test.pcm ! audio/x-raw,format=S16BE,channels=1,rate=44100,layout=interleaved ! audioconvert ! audioresample ! alsasink
  

Это работает отлично. Но теперь мне нужно реализовать это в моем приложении на c . Это то, что у меня уже есть:

 #include <string>
#include <stdio.h>
#include <gst/gst.h>
#include <gio/gio.h>
#include <boost/thread.hpp>

#define AUDIO_LOCATION "/home/pi/rawaudio/test.pcm"

static gboolean bus_call(GstBus *bus,
                         GstMessage *msg,
                         gpointer data) {
    GMainLoop *loop = (GMainLoop*)data;

    switch (GST_MESSAGE_TYPE(msg)) {
        case GST_MESSAGE_EOS:
            g_print ("End of streamn");
            g_main_loop_quit(loop);
            break;
        case GST_MESSAGE_ERROR: {
            gchar  *debug;
            GError *error;

            gst_message_parse_error(msg, amp;error, amp;debug);
            g_free (debug);

            g_printerr("Error: %sn", error->message);
            g_error_free(error);

            g_main_loop_quit(loop);
            break;
        }
        default:
            break;
    }
    return true;
}

int main (int argc, char **argv) {
    gst_init(amp;argc, amp;argv);

    GstElement *pipeline, *source, *parser, *sink, *convert;

    GMainLoop *loop;
    GstBus *bus;
    guint bus_watch_id;

    // loop
    loop = g_main_loop_new(NULL, false);
    // pipeline
    pipeline = gst_pipeline_new("test_pipeline");

    sink = gst_element_factory_make ("alsasink", "sink");
    source = gst_element_factory_make("filesrc", "source");
    g_object_set(G_OBJECT(source), "location", AUDIO_LOCATION, NULL);

    //convert = gst_element_factory_make("audioconvert", "convert");
    //parser = gst_element_factory_make("audioresample","parse");

    GstPad *sourcepad, *sinkpad;

    sourcepad = gst_element_get_static_pad(source, "src");
    gst_pad_set_caps(sourcepad,
        gst_caps_new_simple("audio/x-raw",
                            "rate", G_TYPE_INT, 44100,
                            "channels", G_TYPE_INT, 1,
                            "format", G_TYPE_STRING, "S16BE",
                            "layout", G_TYPE_STRING, "interleaved",
                            NULL));
    gst_object_unref(sourcepad);



    // bus
    bus = gst_pipeline_get_bus(GST_PIPELINE (pipeline));
    bus_watch_id = gst_bus_add_watch(bus, bus_call, loop);
    gst_object_unref(bus);

    // add elements into pipeline
    gst_bin_add_many(GST_BIN(pipeline), source, sink, NULL);
    // link source to decode
    gst_element_link_many(source, sink, NULL);

    // start playing
    gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);

    // iterate
    g_print("Running...n");
    g_main_loop_run(loop);

    // out of the main loop, clean up nicely
    g_print("Returned, stopping playbackn");
    gst_element_set_state(pipeline, GST_STATE_NULL);

    g_print("Deleting pipelinen");
    gst_object_unref(GST_OBJECT(pipeline));
    g_source_remove (bus_watch_id);
    g_main_loop_unref(loop);

    return 0;
}
  

Но это не работает. Я получаю

 Error: The stream is in the wrong format
  

при запуске.

Чего я не понимаю? некоторые элементы, такие как audioparse, audioconvert, audioresample … Я также попытался вставить audioconvert и audioresample после источника в конвейер, но затем я получаю исключение ошибки внутреннего потока данных.

Комментарии:

1. Ваша закодированная версия немного отличается от gst-launch. Заглавные буквы в строке запуска фактически создают элемент capsfilter, в то время как ваш код устанавливает заглавные буквы на клавиатуре (запускает событие sticky caps). Я предполагаю, что у него может быть другое поведение.