如何在活动的GStreamer管道中删除tee分支?

时间:2014-09-17 11:00:35

标签: gstreamer

大家

我使用的GStreamer版本是1.x.我花了很多时间寻找删除T恤分支的方法。

在活动管道中,如下创建记录箱,并通过分支tee元件将其插入此管道。

"排队! video / x-h264,width = 800,height = 600,framerate = 10/1,stream-format =(string)byte-stream! h264parse! mp4mux! filesink location = / xxxx"

除了我想动态删除录音箱并获得可播放的mp4文件外,它完美无缺。根据一些讨论和教程,为了获得正确的mp4文件,我们需要处理一些关于EOS的事情。在尝试了一些方法后,我总是得到破坏的mp4文件。

有没有人用C语言编写示例代码给我看?我很感激你的帮助。

4 个答案:

答案 0 :(得分:1)

对于此类案例,您最好的选择可能是创建两个流程。第一个过程将运行视频,它的一半发球台将通过任何方式将h264数据传送到第二个进程。

以下是两个使用UDP套接字演示概念的管道。

gst-launch-1.0 videotestsrc! x264enc! tee name = t! h264parse! avdec_h264!视频转换! ximagesink t。 !排队! h264parse! rtph264pay! udpsink host = localhost port = 8888

gst-launch-1.0 udpsrc port = 8888 num-buffers = 300! application / x-rtp,media = video,encoding-name = H264! rtph264depay! h264parse! mp4mux! filesink location = / tmp / 264.mp4

获得干净的mp4的诀窍是确保可靠地提供EOS事件。

答案 1 :(得分:0)

默认情况下,您只需将它添加到管道中,而不是动态添加它,并在探测器回调中在队列的源填充处添加探测回调,您必须执行此操作以传递缓冲区(GST_PAD_PROBE_DROP drop)缓冲区和GST_PAD_PROBE_OK将缓冲区传递给下一个元素)所以当你得到一个事件来开始/停止重新编码时,你只需要返回适当的值。而且你可以使用multifilesink代替filesfile,以便在每次启动/停止时写入不同的文件。 请注意在mux元素之前丢弃缓冲区的队列,否则文件将损坏。 希望有所帮助!

答案 2 :(得分:0)

最后,我想出了一个解决方案。

假设有一个包含录音箱的活动管道。

  

“udpsrc port = 4444 caps = \”application / x-rtp,media =(string)video,   clock-rate =(int)90000,encoding-name =(string)H264! rtph264depay!   tee name = tp tp。 !排队! video / x-h264,width = 800,height = 600,   帧率= 10/1! decodebin!视频转换! video / x-raw,format = RGBA!   autovideosink“

录音箱:

  

“queue!video / x-h264,width = 800,height = 600,framerate = 10/1,   stream-format =(string)byte-stream! h264parse! mp4mux!文件接收   位置= / XXXX“

经过一段时间后,我们想停止录制并保存为mp4文件,视频媒体仍然是流媒体。

首先,我使用阻挡探针来阻挡tee的src垫。在这个阻塞探测器回调中,我使用事件探测器来捕获filesink的接收器中的EOS并进行繁忙的等待。

*如果在事件探测器回调中捕获了EOS

self->isGotEOS = YES;

*忙于等待阻塞探测回调

 while (self->isGotEOS == NO) {
    usleep(100000);
}

在进入忙碌等待循环之前,会创建一个EOS事件并将其发送到记录箱的接收器。

忙碌等待完成后:

usleep(200000);

[self destory_record_elements];

我认为usleep(200000)是一个绝招。没有它,通常会产生不可播放的mp4文件。处理EOS似乎足够长200ms。

答案 3 :(得分:0)

我以前有类似的问题,我的管道

videotestsrc do-timestamp="TRUE" ! videoflip method=0 ! tee name=t
    t. ! queue ! videoconvert ! glupload ! glshader ! autovideosink async="FALSE"
    t. ! queue ! identity drop-probability=1 ! videoconvert name=conv2 ! openh264enc ! h264parse ! avimux ! multifilesink async="FALSE" post-messages=true next-file=4

然后我只需更改drop-probability property

上的identity element
  • drop-probability = 1 + gst_pad_send_event(conv2_sinkpad, gst_event_new_eos()); - 停止录制

  • drop-probability = 0 - 恢复录制