输出视频时长与C ++中的GStreamer不匹配

时间:2019-04-10 13:07:18

标签: c++11 gstreamer

我正在尝试从USB摄像机录制视频,使用GStreamer进行编码并保存。我想每20秒停止播放一次视频,更改输出名称,然后重新开始捕获/编码。

我将发布代码的简化版本,因为它很长且不相关。

其他详细信息: timer跟踪经过的时间(以秒为单位)。 create_pip(j)建立以下gst管道并将j附加到文件名(例如test_rgb_0.mp4,test_rgb_1.mp4等)

    "v4l2src ! video/x-raw, width=1280, height=720, framerate=30/1, format=RGB ! videoconvert ! omxh265enc bitrate=2000000 qp-range=35,51:35,51:-1,-1 vbv-size=1 iframeinterval=60 ! matroskamux ! filesink location=test_rgb.mp4 -e" 
    // declarations and stuff
    // this for is just to have 3 different video files
    for(int j=0; j<3; j++){
        // create pipeline
        pipeline = gst_parse_launch(create_pip(j).c_str(),NULL);
        gst_element_set_state(pipeline,GST_STATE_PLAYING);
        timer.reset();        // reset timer to 0
        while(timer.elapsed()<=20){
            // do some other stuff, can be ignored
        }
        // stop stream and release pipeline
        gst_element_set_state(pipeline,GST_STATE_NULL);
        gst_object_unref(pipeline);
    }

一切正常,输出视频长20秒,但vlc(或mediainfo)显示视频长0或1秒。如果我打开视频,它实际上是20秒长,因此剩余时间为负数(-19或-20秒)。由于我创建的管道在命令行上运行良好,因此我认为我的程序在关闭流时无法保存一些元数据。对不起,但我对Gstreamer还是陌生的,我还缺少什么?

1 个答案:

答案 0 :(得分:0)

哦,我没有意识到您需要重新启动整个管道。我认为您需要通过管道发送EOS,而不仅仅是将其状态设置为NULL。

-e特定于gst-launch-1.0应用程序。我认为它不是常规启动语法的一部分。您将必须自己执行此操作。

例如

// send EOS to pipeline
gst_element_send_event(pipeline, gst_event_new_eos());

// wait for the EOS to traverse the pipeline and is reported to the bus
GstBus *bus = gst_element_get_bus(pipeline);
gst_bus_timed_pop_filtered(bus, GST_CLOCK_TIME_NONE, GST_MESSAGE_EOS);

gst_element_set_state(pipeline, GST_STATE_NULL);

[..]

我不确定直播来源。也许您需要告诉v4l2src自己发送EOS,而不是整个发送管道。还是只是mp4mux?至少我很确定mp4 mux在某个时候需要EOS才能正确完成文件。