Несоответствие длительности выходного видео с GStreamer в C ++ - PullRequest
0 голосов
/ 10 апреля 2019

Я пытаюсь записать видео с 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 голосов
/ 10 апреля 2019

О, я не знал, что ты перезапустил весь трубопровод. Я думаю, что вам нужно отправлять EOS через конвейер, а не просто устанавливать его состояние в NULL.

-e относится к приложению gst-launch-1.0. Я считаю, что это не является частью синтаксиса обычного запуска. Вам придется сделать это самостоятельно.

1007 * Е.Г. *

// 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, чтобы правильно завершить файл.

...