appsink 与 appsrc:打通 GStreamer 和业务代码专栏:GStreamer C++ 从零到工程实战· 第 13 篇 / 共 17 篇用 appsink 获取 Sample、Buffer 与 Caps,用 appsrc 注入业务数据,正确处理队列、时间戳、回调取消和 Buffer 所有权。第 15 课:appsink——把媒体数据交给业务代码前面的数据一直在 Pipeline 内部流动。真实项目还会需要:图:appsink 把 Sample、Buffer 与 Caps 交给业务代码appsink是 GStreamer 与算法、图像处理、AI 推理等业务代码之间最常用的出口。一、appsink 交出来的为什么是 Sample?应用拿到的通常是GstSample:GstSample ├─ GstBuffer:数据和时间戳 ├─ GstCaps:格式、尺寸、帧率 └─ Segment:时间映射上下文只拿 Buffer 而不看 Caps,应用就可能不知道这些字节究竟是 BGRA、NV12 还是别的格式。二、一个完整可运行的 appsink 程序下面的程序主动拉取 60 帧 BGRA 图像,同时处理超时、EOS 和 ERROR。主动 pull 的线程模型通常比new-sampleSignal 更直观。#includegst/app/gstappsink.h#includegst/gst.hstaticvoidprint_error(GstMessage*message){GError*error=nullptr;gchar*debug=nullptr;gst_message_parse_error(message,error,debug);g_printerr("ERROR from %s: %s\n",GST_OBJECT_NAME(message-src),error?error-message:"unknown error");if(debug)g_printerr("Debug: %s\n",debug);g_clear_error(error);g_free(debug);}intmain(intargc,char*argv[]){gst_init(argc,argv);GError*parse_error=nullptr;GstElement*pipeline=gst_parse_launch("videotestsrc num-buffers=60 ""! videoconvert ""! video/x-raw,format=BGRA,width=320,height=240 ""! appsink name=framesink max-buffers=2 ""leaky-type=downstream sync=false",parse_error);if(!pipeline){g_printerr("Parse failed: %s\n",parse_error?parse_error-message:"unknown error");g_clear_error(parse_error);return1;}g_clear_error(parse_error);GstElement*sink_element=gst_bin_get_by_name(GST_BIN(pipeline),"framesink");GstBus*bus=gst_element_get_bus(pipeline);if(!sink_element||!bus){g_printerr("Could not obtain appsink or bus\n");if(sink_element)gst_object_unref(sink_element);if(