Gstreamer-音频数据播放之PCM
下述代码使用场景:
用于需要在当前设备端播放PCM音频数据
// push buffer to appsrc
bool push_data(const char *data, int data_size)
{
GstBuffer *buffer = gst_buffer_new_allocate(NULL, data_size, NULL);
GstMapInfo map;
gst_buffer_map(buffer, &map, GST_MAP_WRITE);
memcpy((guchar *)map.data, data, gst_buffer_get_size(buffer));
GstFlowReturn ret;
g_signal_emit_by_name(m_app_src, "push-buffer", buffer, &ret);
gst_buffer_unmap(buffer, &map);
gst_buffer_unref(buffer);
if (ret != GST_FLOW_OK) {
g_printerr("[push_data], push_data fail ret: %d.\n", ret);
return false;
}
return true;
}
// 初始化 pipeline
// |---------------------------pipeline-----------------------------|
// | appsrc->audioconvert->audioresample->capsfilter->autoaudiosink |
// |----------------------------------------------------------------|
bool init(int sample_rate, int channel, const char *formate)
{
m_app_src = gst_element_factory_make("appsrc", "app_src");
if (!m_app_src) {
g_printerr("[init], failed to create a appsrc.\n");
return false;
}
m_audio_convert = gst_element_factory_make("audioconvert", "audio_convert");
if (!m_audio_convert) {
g_printerr("[init], failed to create a audioconvert.\n");
return false;
}
m_audio_resample = gst_element_factory_make("audioresample", "audio_resample");
if (!m_audio_resample) {
g_printerr("[init], failed to create a audioconvert.\n");
return false;
}
m_auto_audio_sink = gst_element_factory_make("autoaudiosink", "auto_audio_sink");
if (!m_auto_audio_sink) {
g_printerr("[init], failed to create a autoaudiosink.\n");
return false;
}
m_pipeline = gst_pipeline_new("pipeline");
if (!m_pipeline) {
g_printerr("[init], failed to create a pipeline.\n");
return false;
}
GstCaps *audioCaps = gst_caps_new_simple("audio/x-raw", "format", G_TYPE_STRING, formate, "rate", G_TYPE_INT,
sample_rate, "channels", G_TYPE_INT, channel, "layout", G_TYPE_STRING, "interleaved", "is-live", G_TYPE_BOOLEAN,
TRUE, nullptr);
if (!audioCaps) {
g_printerr("[init], audioCaps is null.\n");
return false;
}
g_object_set(G_OBJECT(m_app_src), "caps", audioCaps, nullptr);
gst_caps_unref(audioCaps);
m_caps_filter = gst_element_factory_make("capsfilter", "caps_filter");
if (!m_caps_filter) {
g_printerr("[init], caps_filter elements could be created.\n");
return false;
}
GstCaps *caps = gst_caps_new_simple(
"audio/x-raw", "format", G_TYPE_STRING, "S16LE", "rate", G_TYPE_INT, 48000, "channels", G_TYPE_INT, 2, nullptr);
if (!caps) {
g_printerr("[init], caps new fail.\n");
return false;
}
g_object_set(G_OBJECT(m_caps_filter), "caps", caps, nullptr);
gst_caps_unref(caps);
gst_bin_add_many(
GST_BIN(m_pipeline), m_app_src, m_audio_convert, m_audio_resample, m_caps_filter, m_auto_audio_sink, nullptr);
if (gst_element_link_many(
m_app_src, m_audio_convert, m_audio_resample, m_caps_filter, m_auto_audio_sink, nullptr) != TRUE) {
g_printerr("[init], gst_element_link_filtered fail.\n");
return false;
}
if (gst_element_set_state(m_pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
g_printerr("[init], play audioplayer fail.\n");
return false;
}
g_printerr("[init], init audioplayer successfully.\n");
m_isPlaying = true;
return true;
}