Gstreamer теряет данные при смене файловой ссылки

Я создал приложение на python, чтобы попытаться динамически изменить конвейер gstreamer, направив поток на другую файловую линию (см. Ниже). Код работает нормально и (обычно) создает серию файлов AVI. Есть пара проблем:

  1. Несмотря на то, что событие запуска нового файла запускается каждые 10 секунд, сами видео - только 3 секунды!
  2. Иногда файл будет сохранен без данных, а все последующие файлы будут пустыми.

У кого-нибудь есть понимание этих проблем?

#! /usr/bin/env python

import os
import sys
import logging

import gi
gi.require_version('Gst', "1.0")
gi.require_version('GstBase', "1.0")
gi.require_version('Gtk', "3.0")
#gi.require_version('GdkX11', '3.0')
gi.require_version('GstVideo', '1.0')

from gi.repository import GObject, Gst, GstBase, Gtk, GstVideo, GdkX11

import numpy as np
import datetime as dt

log = logging.getLogger(__name__)


class Segmenter:
    def __init__(self):
        Gst.init(None)

        self.terminate = False

        # Create gstreamer pipeline
        cmd = "v4l2src ! tee name=tee ! fakesink"
        self.pipeline = Gst.parse_launch(cmd)

        # Store references to gstreamer objects
        self.bus = self.pipeline.get_bus()
        self.recordpipe = None

    def run(self):    
        # Initiate main loop
        self.pipeline.set_state(Gst.State.PAUSED)
        self.pipeline.set_state(Gst.State.PLAYING)

        try:
            while not self.terminate:
                print(dt.datetime.now().time())
                # Listen for event messages on the bus
                msg = self.bus.timed_pop_filtered(10 * Gst.SECOND, (Gst.MessageType.EOS | Gst.MessageType.ERROR))

                if msg:
                    if msg.type == Gst.MessageType.ERROR:
                        err, dbg = msg.parse_error()
                        print("ERROR:", msg.src.get_name(), ":", err)
                        if dbg:
                            print("Debug info:", dbg)
                        self.terminate = True

                    elif msg.type == Gst.MessageType.EOS:
                        print("End-Of-Stream reached")
                        self.terminate = True

                else:
                    # No message - must have reached timeout
                    self.begin_new_file()


        finally:
            # Free up resources
            self.pipeline.set_state(Gst.State.NULL)

    def begin_new_file(self):

        # If recording a file currently, terminate it
        if self.recordpipe is not None:

            # Block new data
            filequeue = self.recordpipe.get_by_name("filequeue")
            filequeue.get_static_pad("src").add_probe(Gst.PadProbeType.BLOCK_DOWNSTREAM, self.probe_block)

            # Disconnect the recording pipe
            self.pipeline.get_by_name("tee").unlink(self.recordpipe)

            # Send a termination event to trigger the save
            filequeue.get_static_pad("sink").send_event(Gst.Event.new_eos())

            # Clear the reference to the pipe
            self.recordpipe = None

        # Create a new file target
        filename = dt.datetime.now().strftime("%Y-%m-%d_%H.%M.%S") + ".avi"
        print("Recording {}...".format(filename))

        # Create a new pipeline for the new file
        self.recordpipe = Gst.parse_bin_from_description("queue name=filequeue ! jpegenc ! avimux ! filesink location={} sync=False".format(filename), True)
        self.pipeline.add(self.recordpipe)

        # Connect to the main pipe
        self.pipeline.get_by_name("tee").link(self.recordpipe)

        # Start passing data
        self.recordpipe.set_state(Gst.State.PLAYING)

    def probe_block(self, pad, buf):
        """ Callback for downstream block """
        print('block.')
        return True


if __name__ == '__main__':
    seg = Segmenter()
    seg.run()

0 ответов

Другие вопросы по тегам