Gstreamer-接受h264数据,并发送至本地端口

 下述代码使用场景:

用于将接收到的视频数据,转发至本地端口,供其他进程使用

// 初始化 pipeline
//  |--------------link---------------|--------------rtpbin----------------|-----------|
//  | appsrc->h264parse->rtph264pay---|-->send_rtp_sink_0  send_rtp_src_0--|-->udpsink |
//  |---------------------------------|------------------------------------|-----------|

bool init()
{
    m_pipeline = gst_pipeline_new("pipeline");
    if (!m_pipeline) {
        g_printerr("[init], pipeline could be created.\n");
        return false;
    }

    m_appsrc = gst_element_factory_make("appsrc", "appsrc");
    if (!m_appsrc) {
        g_printerr("[init], appsrc could be created.\n");
        return false;
    }

    m_h264parse = gst_element_factory_make("h264parse", "h264parse");
    if (!m_h264parse) {
        g_printerr("[init], h264parse could be created.\n");
        return false;
    }

    m_rtph264pay = gst_element_factory_make("rtph264pay", "rtph264pay");
    if (!m_rtph264pay) {
        g_printerr("[init], rtph264pay could be created.\n");
        return false;
    }
    gst_bin_add_many(GST_BIN(m_pipeline), m_appsrc, m_h264parse, m_rtph264pay, nullptr);
    if (gst_element_link_many(m_appsrc, m_h264parse, m_rtph264pay, nullptr) != TRUE) {
        g_printerr("[init], pipeline link failed.\n");
        gst_object_unref(m_pipeline);
        m_pipeline = nullptr;
        return false;
    }

    m_udpSink = gst_element_factory_make("udpsink", "udpsink");
    if (!m_udpSink) {
        g_printerr("[init], udpsink could be created.\n");
        return false;
    }
    g_object_set(G_OBJECT(m_udpSink), "host", "127.0.0.1", nullptr);
    g_object_set(G_OBJECT(m_udpSink), "port", 12345, nullptr);
    g_object_set(G_OBJECT(m_udpSink), "sync", 0, nullptr);
    gst_bin_add_many(GST_BIN(m_pipeline), m_udpSink, nullptr);

    m_rtpbin = gst_element_factory_make("rtpbin", "rtpbin");
    if (!m_rtpbin) {
        g_printerr("[init], rtpbin could be created.\n");
        return false;
    }
    gst_bin_add(GST_BIN(m_pipeline), m_rtpbin);
    GstPad *rtpbin_sinkpad = gst_element_request_pad_simple(m_rtpbin, "send_rtp_sink_0");
    GstPad *rtph264pay_srcpad = gst_element_get_static_pad(m_rtph264pay, "src");
    if (gst_pad_link(rtph264pay_srcpad, rtpbin_sinkpad) != GST_PAD_LINK_OK) {
        g_printerr("[init], link m_rtph264pay to m_rtpbin failed.\n");
        return false;
    }
    gst_object_unref(rtph264pay_srcpad);

    GstPad *rtpbin_srcpad = gst_element_get_static_pad(m_rtpbin, "send_rtp_src_0");
    GstPad *udpSink_sinkpad = gst_element_get_static_pad(m_udpSink, "sink");
    if (gst_pad_link(rtpbin_srcpad, udpSink_sinkpad) != GST_PAD_LINK_OK) {
        g_printerr("[init], link m_rtpbin to m_udpSink failed.\n");
        return false;
    }
    gst_object_unref(rtpbin_srcpad);
    gst_object_unref(udpSink_sinkpad);

    if (gst_element_set_state(m_pipeline, GST_STATE_PLAYING) == GST_STATE_CHANGE_FAILURE) {
        g_printerr("[init], failed to change the state to PLAYING.\n");
        return false;
    }
    g_print("[init], init video player successfully.\n");
    return true;
}

// push buffer to appsrc
bool pushData(void *data, int size)
{
    if (!data || size <= 0) {
        g_print("[pushData], parameter invalid.\n");
        return false;
    }
    static GstClockTime timestamp = 0;
    GstBuffer *buffer = gst_buffer_new_allocate(NULL, size, NULL);
    GstMapInfo map;

    gst_buffer_map(buffer, &map, GST_MAP_WRITE);
    memcpy((guchar *)map.data, data, gst_buffer_get_size(buffer));
    GST_BUFFER_PTS(buffer) = timestamp;
    // 需要注意一下时间戳
    GST_BUFFER_DURATION(buffer) = gst_util_uint64_scale_int(3, GST_SECOND, 1);
    timestamp += GST_BUFFER_DURATION(buffer);

    GstFlowReturn ret;
    if (m_appsrc) {
        g_signal_emit_by_name(m_appsrc, "push-buffer", buffer, &ret);
    }
    gst_buffer_unmap(buffer, &map);
    gst_buffer_unref(buffer);
    if (ret != GST_FLOW_OK) {
        g_printerr("[pushData], push buffer failed.\n");
        return false;
    }
    return true;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值