那个公司做网站好网址大全下载到桌面
运行效果(音频)
简介
上一个教程演示了媒体格式和Pad功能。本教程介绍多线程和 Pad 可用性。GStreamer 会自动处理多线程,但是,在某些 情况下,您可能需要手动解耦线程。这 教程 演示如何执行此作,此外,还完成了 Exposition 关于 Pad 可用性。更准确地说,本文档解释了:
• 如何为 管道
• 什么是 Pad 可用性
• 如何复制流
GStreamer 是一个多线程框架。这意味着在内部它根据需要创建和销毁线程,例如,解耦 从应用程序线程流式传输。此外,插件也是免费的 创建用于自身处理的线程,例如,视频解码器 可以创建 4 个线程以充分利用具有 4 个内核的 CPU。最重要的是,在构建管道时,应用程序可以指定 明确地,分支(管道的一部分)在不同的 thread 中执行 同时)。这是使用 element 完成的,其工作方式如下。 sink pad 只是将数据排入队列并返回控制权。在不同的 thread,数据将出列并推送到下游。此元素也是 用于缓冲,如后面的流式处理教程所示。
源是合成音频信号(连续音调),即 使用 Element 进行 split(它通过其源 pad 发送所有内容 它通过其 Sink Pad 接收)。然后,一个分支将信号发送到 Audio Card 和 Present 的 Alpha S 的 S 的 S Alpha S 的 它到屏幕上。如图所示,队列会创建一个新线程,因此此管道 在 3 个线程中运行。具有多个 sink 的管道通常需要 multithreaded,因为要同步,sink 通常会阻塞 执行,直到所有其他 sink 都准备就绪,如果 只有一个线程被第一个 sink 阻塞。
GStreamer相关运行库
INCLUDEPATH += D:/Software/GStreamer/1.0/mingw_x86_64/include/gstreamer-1.0/gst
INCLUDEPATH += D:/Software/GStreamer/1.0/mingw_x86_64/include
INCLUDEPATH += D:/Software/GStreamer/1.0/mingw_x86_64/include/gstreamer-1.0
INCLUDEPATH += D:/Software/GStreamer/1.0/mingw_x86_64/include/glib-2.0
INCLUDEPATH += D:/Software/GStreamer/1.0/mingw_x86_64/lib/glib-2.0/includeLIBS += D:/Software/GStreamer/1.0/mingw_x86_64/lib/gstreamer-1.0.lib
LIBS += D:/Software/GStreamer/1.0/mingw_x86_64/lib/glib-2.0.lib
LIBS += D:/Software/GStreamer/1.0/mingw_x86_64/lib/gobject-2.0.lib
完整源码
#include <gst/gst.h>int main(int argc, char *argv[])
{/* 初始化GStreamer */gst_init (&argc, &argv);/* 创建元素 */GstElement *audio_source = gst_element_factory_make ("audiotestsrc", "audio_source");GstElement *tee = gst_element_factory_make ("tee", "tee");GstElement *audio_queue = gst_element_factory_make ("queue", "audio_queue");GstElement *audio_convert = gst_element_factory_make ("audioconvert", "audio_convert");GstElement *audio_resample = gst_element_factory_make ("audioresample", "audio_resample");GstElement *audio_sink = gst_element_factory_make ("autoaudiosink", "audio_sink");GstElement *video_queue = gst_element_factory_make ("queue", "video_queue");GstElement *visual = gst_element_factory_make ("wavescope", "visual");GstElement *video_convert = gst_element_factory_make ("videoconvert", "csp");GstElement *video_sink = gst_element_factory_make ("autovideosink", "video_sink");/* 创建空管道 */GstElement *pipeline = gst_pipeline_new ("test-pipeline");if (!pipeline || !audio_source || !tee || !audio_queue || !audio_convert || !audio_resample || !audio_sink || !video_queue || !visual || !video_convert || !video_sink){ g_printerr ("Not all elements could be created.\n"); return -1; }/* 配置元素 */g_object_set (audio_source, "freq", 215.0f, NULL);g_object_set (visual, "shader", 0, "style", 1, NULL);/* 链接所有可以自动链接的元素,因为它们有"Always"的pod */gst_bin_add_many (GST_BIN (pipeline), audio_source, tee, audio_queue, audio_convert, audio_resample, audio_sink, video_queue, visual, video_convert, video_sink, NULL);if (gst_element_link_many (audio_source, tee, NULL) != TRUE ||gst_element_link_many (audio_queue, audio_convert, audio_resample, audio_sink, NULL) != TRUE ||gst_element_link_many (video_queue, visual, video_convert, video_sink, NULL) != TRUE){g_printerr ("Elements could not be linked.\n");gst_object_unref (pipeline); return -1;}/* 手动连接带有"Request"的pads */GstPad *tee_audio_pad = gst_element_request_pad_simple (tee, "src_%u");g_print ("Obtained request pad %s for audio branch.\n", gst_pad_get_name (tee_audio_pad));GstPad *queue_audio_pad = gst_element_get_static_pad (audio_queue, "sink");GstPad *tee_video_pad = gst_element_request_pad_simple (tee, "src_%u");g_print ("Obtained request pad %s for video branch.\n", gst_pad_get_name (tee_video_pad));GstPad *queue_video_pad = gst_element_get_static_pad (video_queue, "sink");if (gst_pad_link (tee_audio_pad, queue_audio_pad) != GST_PAD_LINK_OK || gst_pad_link (tee_video_pad, queue_video_pad) != GST_PAD_LINK_OK){g_printerr ("Tee could not be linked.\n");gst_object_unref (pipeline); return -1;}gst_object_unref (queue_audio_pad);gst_object_unref (queue_video_pad);/* 开始播放管道 */gst_element_set_state (pipeline, GST_STATE_PLAYING);/* 等待错误或EOS */GstBus *bus = gst_element_get_bus (pipeline);GstMessage *msg = gst_bus_timed_pop_filtered (bus, GST_CLOCK_TIME_NONE, (GstMessageType)(GST_MESSAGE_ERROR | GST_MESSAGE_EOS));/* 释放请求的pad从tee中,然后释放 */gst_element_release_request_pad (tee, tee_audio_pad);gst_element_release_request_pad (tee, tee_video_pad);gst_object_unref (tee_audio_pad);gst_object_unref (tee_video_pad);/* 释放资源 */if (msg != NULL)gst_message_unref (msg);gst_object_unref (bus);gst_element_set_state (pipeline, GST_STATE_NULL);gst_object_unref (pipeline);return 0;
}
关注
笔者 - jxd