Gstreamer T恤块分支

时间:2015-08-31 13:00:24

标签: c++ gstreamer

我想创建一个管道,在输入和输出不同分辨率的jpeg图像中获取rtsp流。当管道正在播放时,我想阻止某个分支,但我无法阻止该元素。

命令行如下所示:

gst-launch-1.0 -v rtspsrc location="rtsp://ip:port/live.sdp" ! rtph264depay ! h264parse ! avdec_h264 ! videorate ! video/x-raw,framerate=5/1 ! tee name=t ! queue ! videoscale ! video/x-raw,width=320,height=240 ! jpegenc ! multifilesink location=snapshot320-%05d.jpg t. ! queue ! videoscale ! video/x-raw,width=1280,height=720 ! jpegenc ! multifilesink location=snapshot1280-%05d.jpg

我希望能够阻止数据通过分支,但我无法使用tee元素。

我已经看到函数gst_pad_add_probe允许阻止元素的填充。

这就是我所做的:

1)拿到垫子:

srcpad = gst_element_get_static_pad(tee, "src");
sinkpad = gst_element_get_static_pad(tee, "sink");

2)添加探针:

gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_IDLE, &GstProbeCallback, this, NULL)

3)刷新数据:

gst_pad_send_event (sinkpad, gst_event_new_eos ());

4)解开垫子

 gst_object_unref (sinkpad);
 gst_object_unref (srcpad);

5)将管道设置为播放状态:

gst_element_set_state(this->pipeline, GST_STATE_PLAYING)

这是给gst_pad_add_probe的回调:

static GstPadProbeReturn
GstProbeCallback(GstPad* pad, GstPadProbeInfo* info, gpointer user_data) {
    std::cout << "probe callback" << std::endl;
    return GST_PAD_PROBE_DROP;
}

[更新]

如果我将探针设置在tee元素后面的队列中,那么我的所有分支都会被阻塞。 更多代码如下:

    this->pipeline = gst_pipeline_new(NULL);

if (this->pipeline == NULL) {
    LOG_ERR("Failed to create the pipeline", "image_configuration");
    return NULL;
}

this->elements.tree.src = gst_element_factory_make("rtspsrc", NULL);
this->elements.tree.depay = gst_element_factory_make("rtph264depay", NULL);
this->elements.tree.parse = gst_element_factory_make("h264parse", NULL);
this->elements.tree.dec = gst_element_factory_make("avdec_h264", NULL);
this->elements.tree.rate = gst_element_factory_make("videorate", NULL);
this->elements.tree.ratefilter = gst_element_factory_make("capsfilter", NULL);
this->elements.tree.tee = gst_element_factory_make("tee", NULL);

for (auto& branch : this->elements.branches) {
    branch.queue = gst_element_factory_make("queue", NULL);
    branch.scale = gst_element_factory_make("videoscale", NULL);
    branch.scalecaps = gst_element_factory_make("capsfilter", NULL);
    branch.enc = gst_element_factory_make("jpegenc", NULL);
    branch.sink = gst_element_factory_make("redissink", NULL);
    branch.fakesink = gst_element_factory_make("fakesink", NULL);
    if (not(branch.queue && branch.scale && branch.scalecaps && branch.sink && branch.enc &&
            branch.fakesink)) {
        LOG_ERR("Failed to create elements", "image_configuration");
        return NULL;
    }
}

if (!this->pipeline || !this->elements.tree.src || !this->elements.tree.depay ||
    !this->elements.tree.parse || !this->elements.tree.dec || !this->elements.tree.rate ||
    !this->elements.tree.ratefilter || !this->elements.tree.tee) {
    LOG_ERR("Failed to create elements", "image_configuration");
    return NULL;
}

this->set_rate_caps(this->elements.tree.ratefilter);
g_object_set(
    this->elements.tree.src, "location", this->loc_in.c_str(), "latency", this->latency, NULL);

for (auto& branch : this->elements.branches) {
    this->set_scale_caps(branch.scalecaps, branch.resolution);
    g_object_set(branch.enc, "quality", 50, NULL);
    g_object_set(branch.sink, "func", &send_event, NULL);
    g_object_set(branch.sink, "camera_id", this->camera_id, NULL);
    g_object_set(branch.sink, "is_init", TRUE, NULL);
}
gst_bin_add_many(GST_BIN(this->pipeline),
                 this->elements.tree.src,
                 this->elements.tree.depay,
                 this->elements.tree.parse,
                 this->elements.tree.dec,
                 this->elements.tree.rate,
                 this->elements.tree.ratefilter,
                 this->elements.tree.tee,
                 NULL);
for (const auto& branch : this->elements.branches) {
    gst_bin_add_many(GST_BIN(this->pipeline),
                     branch.queue,
                     branch.scale,
                     branch.scalecaps,
                     branch.enc,
                     branch.sink,
                     branch.fakesink,
                     NULL);
}
if (!gst_element_link_many(this->elements.tree.depay,
                           this->elements.tree.parse,
                           this->elements.tree.dec,
                           this->elements.tree.rate,
                           this->elements.tree.ratefilter,
                           this->elements.tree.tee,
                           NULL)) {
    LOG_ERR("Failed to link elements", "image_configuration");
    return NULL;
}
g_signal_connect(
    this->elements.tree.src, "pad-added", G_CALLBACK(on_pad_added), &this->elements);
for (const auto& branch : this->elements.branches) {
    if (!gst_element_link_many(this->elements.tree.tee,
                               branch.queue,
                               branch.scale,
                               branch.scalecaps,
                               branch.enc,
                               branch.sink,
                               branch.fakesink,
                               NULL)) {
        LOG_ERR("Failed to link elements", "image_configuration");
        return NULL;
    }
}


if (not this->launch_pipeline()) return NULL;

getchar();
std::cout << "Add probe" << std::endl;

GstPad* srcpad;
GstPad* sinkpad;

srcpad = gst_element_get_static_pad(this->elements.branches[0].queue, "src");
sinkpad = gst_element_get_static_pad(this->elements.branches[0].queue, "sink");
 this->elements.branches[0].probe_id =
     gst_pad_add_probe(srcpad, GST_PAD_PROBE_TYPE_BLOCK, &GstProbeCallback, this, NULL);

 gst_pad_send_event (sinkpad, gst_event_new_eos ());
 gst_object_unref (sinkpad);
 gst_object_unref (srcpad);


return this->pipeline;

任何帮助将不胜感激

0 个答案:

没有答案