2016-07-23 4 views
0

実際のgstバージョンは1.8.1です。gstreamer 1.0でストリーミングオーディオをデコードし、波形データにアクセスしますか?

現在、私はgstreamerでエンコードされたストリームを受信し、サウンドカードで再生するコードを持っています。私はそれを変更して、アプリケーションに生の圧縮されていないオーディオデータへのアクセスを与えたいと思っています。これは、整数のサウンドサンプルの配列になるはずです。もしそれらをプロットすると、オーディオ波形が見えます(例えば、完全なトーンは素晴らしい正弦波になります)。そして、最新の配列をコールバックで最後に受け取ったものは不連続性が見えません。

これは、現在の再生コードです:私はappsinkにalsasinkを変更する必要があると思うし、それはデコーダを通過した後にオーディオの最新のチャンクを取得するコールバックを設定する https://github.com/lucasw/audio_common/blob/master/audio_play/src/audio_play.cpp

_sink = gst_element_factory_make("appsink", "sink"); 
g_object_set (G_OBJECT (_sink), "emit-signals", TRUE, 
    "sync", FALSE, NULL); 
g_signal_connect (_sink, "new-sample", 
    G_CALLBACK (on_new_sample_from_sink), this); 

をそしてコールバックがあります:これはhttps://github.com/jojva/gst-plugins-base/blob/master/tests/examples/app/appsink-src.cから構成されている

static GstFlowReturn 
    on_new_sample_from_sink (GstElement * elt, gpointer data) 
    { 
    RosGstProcess *client = reinterpret_cast<RosGstProcess*>(data); 
    GstSample *sample; 
    GstBuffer *app_buffer, *buffer; 
    GstElement *source; 

    /* get the sample from appsink */ 
    sample = gst_app_sink_pull_sample (GST_APP_SINK (elt)); 
    buffer = gst_sample_get_buffer (sample); 

    /* make a copy */ 
    app_buffer = gst_buffer_copy (buffer); 
    /* we don't need the appsink sample anymore */ 
    gst_sample_unref (sample); 

    /* get source and push new buffer */ 
    source = gst_bin_get_by_name (GST_BIN (client->_sink), "app_source"); 
    return gst_app_src_push_buffer (GST_APP_SRC (source), app_buffer); 
    } 

は、私はそのコールバックでデータを取得することはできますか?私はGstFlowReturnで何をすべきですか?それが別のパイプライン要素にデータを渡しているのであれば、私はそれをやりたくはありません。

https://github.com/lucasw/audio_common/blob/appsink/audio_process/src/audio_process.cpp

(gint16配列にキャスト?)私が欲しい、まさにそのコールバックに渡さgpointerデータであり、あるいはどのように私は変換し、それをアクセスできますか?

答えて

0

以下に変更されたコールバックからデータを解釈することができます(画面にプロットするスクリプトがあります)、uint8配列の16ビットのサンプルが署名されているように見えます。

コールバックの戻り値が適切でないことがわかりました。このコードを使用して常にトリガされているコードの別の場所にcb_need_dataコールバック設定があります。

static void // GstFlowReturn 
    on_new_sample_from_sink (GstElement * elt, gpointer data) 
    { 
    RosGstProcess *client = reinterpret_cast<RosGstProcess*>(data); 
    GstSample *sample; 
    GstBuffer *buffer; 
    GstElement *source; 

    /* get the sample from appsink */ 
    sample = gst_app_sink_pull_sample (GST_APP_SINK (elt)); 
    buffer = gst_sample_get_buffer (sample); 

    GstMapInfo map; 

    if (gst_buffer_map (buffer, &map, GST_MAP_READ)) 
    { 
     audio_common_msgs::AudioData msg; 
     msg.data.resize(map.size); 
     // TODO(lucasw) copy this more efficiently 
     for (size_t i = 0; i < map.size; ++i) 
     { 
     msg.data[i] = map.data[i]; 
     } 
     gst_buffer_unmap (buffer, &map); 
     client->_pub.publish(msg); 
    } 
    } 

https://github.com/lucasw/audio_common/tree/appsink

1

GstFlowReturnは、単に基礎となる基本クラスの戻り値です。そこにエラーを返すと、おそらくパイプラインが停止するでしょう。致命的なエラーがあったからです。

cb_need_dataイベントは、appsrc要素によってトリガーされます。これは、必要に応じて絞り機構として使用できます。あなたはおそらく純粋なプッシュモードでappsrcを使用しているので(appslinkに何かが届くとすぐにappsrcにプッシュします)、これらを無視することができます。 appsrc要素でこれらのイベントを明示的に無効にすることもできます。 (またはそれでも使用しますか?)

バッファ内のデータフォーマットは、デコーダとappsinkが合意した上限によって異なります。これは、通常、デコーダが推奨するフォーマットです。デコーダに応じてこのフォーマットを何らかの形で制御したり、好みのフォーマットに変換することができます。

は、私は一種のあなたの実際の質問が何だったか忘れてしまった、私は怖い..フォーマットをチェックする価値がある、のfloat32はそれは珍しいことではないかもしれ...

+0

ありがとう!私は現在、手動でFloat32に変換していますが、これは私のために設定する必要がある場合は、はるかに少なくなります。 –

関連する問題