2016-07-23 57 views
0

實際的gst版本是1.8.1。使用gstreamer 1.0解碼流音頻並訪問波形數據?

目前我有接收gstreamer編碼流並通過我的聲卡播放它的代碼。我想修改它,讓我的應用程序訪問原始未壓縮的音頻數據。這應該會產生一個整數聲音樣本數組,如果我要繪製它們,我會看到音頻波形(例如完美的音調將是一個很好的正弦波),如果我要將最新的數組添加到最後一個回調收到我不會看到任何不連續。

這是當前播放代碼: https://github.com/lucasw/audio_common/blob/master/audio_play/src/audio_play.cpp

我想我需要的alsasink更改爲appsink,並設置一個回調已經通過解碼器通過後,將獲得音頻的最新塊。這是改編自https://github.com/jojva/gst-plugins-base/blob/master/tests/examples/app/appsink-src.c

_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); 

再有就是回調:

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

傳遞給回調gpointer數據正是我想要的(強制轉換爲gint16陣列?),否則我怎麼轉換和訪問它?

回答

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(只要有東西到達appsink,就會將其推送到appsrc),您可以忽略它們。您還顯式禁用appsrc元素上的這些事件。 (或者你仍然使用那個?)

緩衝區中的數據格式取決於解碼器和appsink達成一致的上限。這通常是解碼器的首選格式。根據解碼器的不同,您可能會對此格式有所控制或將其轉換爲您的首選格式。可能是值得的檢查格式,浮點32並不是少見..

我有點忘了您的實際問題是什麼,我怕..

+0

謝謝!我目前正在手動轉換爲Float32,但如果我可以設置它來爲我完成它,那麼這將變得更加脆弱。 –