gstreamer中如何使用probe(探针)获取帧数据

功能

gstreamer应用程序中提供一种能够监视和控制焊盘上的方式。分为以下几种类型:

  1. be notified when the pad is/becomes idle and make sure the pad stays idle. This is essential to be able to implement dynamic relinking of elements without breaking the dataflow.
  2. be notified when data, events or queries are pushed or sent on a pad. It should also be possible to inspect and modify the data.
  3. be able to drop, pass and block on data based on the result of the callback.
  4. be able to drop, pass data on blocking pads based on methods performed by the application thread.

概述

gst_pad_add_probe()用于将探针添加到pad。

 gulong  gst_pad_add_probe    (GstPad *pad,
                                  GstPadProbeType mask,
                                  GstPadProbeCallback callback,
                                  gpointer user_data,
                                  GDestroyNotify destroy_data);                                

mask表示探针类型


typedef enum
{
  GST_PAD_PROBE_TYPE_INVALID          = 0,

  /* flags to control blocking */
  GST_PAD_PROBE_TYPE_IDLE             = (1 << 0),
  GST_PAD_PROBE_TYPE_BLOCK            = (1 << 1),

  /* flags to select datatypes */
  GST_PAD_PROBE_TYPE_BUFFER           = (1 << 4),
  GST_PAD_PROBE_TYPE_BUFFER_LIST      = (1 << 5),
  GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM = (1 << 6),
  GST_PAD_PROBE_TYPE_EVENT_UPSTREAM   = (1 << 7),
  GST_PAD_PROBE_TYPE_EVENT_FLUSH      = (1 << 8),
  GST_PAD_PROBE_TYPE_QUERY_DOWNSTREAM = (1 << 9),
  GST_PAD_PROBE_TYPE_QUERY_UPSTREAM   = (1 << 10),

  /* flags to select scheduling mode */
  GST_PAD_PROBE_TYPE_PUSH             = (1 << 12),
  GST_PAD_PROBE_TYPE_PULL             = (1 << 13),
} GstPadProbeType;

当添加带有IDLE或BLOCK标志的探针时,该探针将成为阻塞探针。否则,探针将是DATA探针。

数据类型和调度选择器标志用于选择回调中应允许的数据类型和调度模式。

阻止标志必须与触发的探针完全匹配。

回调函数定义为:

GstPadProbeReturn (*GstPadProbeCallback) (GstPad *pad, 
	GstPadProbeInfo *info,
    gpointer user_data);

数据探针

本文主要介绍如何使用探针获取帧数据,下面开始介绍数据探针。
在整个playing状态的管道中,pad上有数据通过时,数据探针会通知你。通过 GST_PAD_PROBE_TYPE_BUFFER和/或GST_PAD_PROBE_TYPE_BUFFER_LIST以 gst_pad_add_probe ()创建这种探头。下面给出在qt应用中的例子。因为qt里的Qimage可以直接操作rgb数据,如果使用gstreamer管道过程中源数据不是rgb格式,可以使用gstreamer中的videoconvert实现转码功能。命令行形式如下
`

gst-launch-1.0 videotestsrc ! videoconvert ! video/x-raw,format=RGB ! xvimagesink

将probe位置设置在xvimagesink的sink pad 上。
代码如下`

   GstElement *videosink = gst_element_factory_make ("xvimagesinkk", "videosink");
   //date probe
    GstPad *pad = gst_element_get_static_pad (videosink, "sink");
    gst_pad_add_probe (pad, GST_PAD_PROBE_TYPE_BUFFER,
        (GstPadProbeCallback) cb_have_data, &date, NULL);
    gst_object_unref (pad);

回调函数

static GstPadProbeReturn
cb_have_data (GstPad          *pad,
              GstPadProbeInfo *info,
              CustomData      *date){

        // 使用mapinfo获取图像数据
        GstBuffer *buffer = GST_PAD_PROBE_INFO_BUFFER (info);
               
        if (!gst_buffer_map(buffer, &date->map_info, GST_MAP_READ)) {
            g_print("gst_buffer_map() error!");
            return GST_PAD_PROBE_DROP;
        }
                g_print("apply buffer\n");
        unsigned char jpg[date->map_info.size] = {0};
        memcpy(jpg, date->map_info.data, date->map_info.size);
        g_print("jpg size = %ld \n", date->map_info.size);

        QImage img(date->map_info.data, date->Width, date->Height, date->Width * 4, QImage::Format_RGB32);
        QString strFile = QString("Capture-%0.jpg").arg(QDateTime::currentDateTime().toString("yyyyMMddhhmmssz"));
        img.save(strFile, "jpeg");
        g_print("save  %s succese\n",strFile.toStdString().c_str()); 

    return GST_PAD_PROBE_OK;
}

此方式适用于将少量帧数据保存为图片。如果需要保存大量图片可以使用multifilsink这种element实现。如需要取出帧数据做修改则可以使用appsink从管道中获取。

上一篇:微服务从代码到k8s部署应有尽有系列(二、网关)


下一篇:JsonResult与OkObjectResul