Gstreamer Multiple Source с единой реализацией Sink в PythonGST - PullRequest
0 голосов
/ 11 октября 2018

Я новичок в Gstreamer, а также в Python-GST.Мне нужно собрать несколько исходных необработанных данных видеопотока в один приемник, я не знаю, возможно ли это или нет.

Позвольте мне подробнее объяснить мой сценарий:

У меня есть 2 видеопока исходный сервер, один - моя веб-камера, а другой - просто файл mp4, я открыл этот источник, используя следующую команду

Source1 :

gst-Устройство launch-1.0 v4l2src = / dev / video0!'video / x-raw, ширина = 640, высота = 480'!x264enc pass = qual quantizer = 20 tune = zerolatency!rtph264pay!хост udpsink = 127.0.0.1 порт = 5000

Source2 :

gst-launch-1.0 filesrc location = имя_файла.mp4!'video / x-raw, ширина = 640, высота = 480'!x264enc pass = qual quantizer = 20 tune = zerolatency!rtph264pay!хост udpsink = 127.0.0.1 порт = 5000

Я пытаюсь отправить оба потока данных на порт localhost 5000 после кодирования с H264 .

Для получения у меня есть сервер Python Sink:

import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstApp', '1.0')
from gi.repository import GObject, Gst, GstApp

GObject.threads_init()
Gst.init(None)
GST_DEBUG="6"

class Example:
    def __init__(self):
        self.mainloop   = GObject.MainLoop()
        self.pipeline   = Gst.Pipeline.new("Pipeline") 
        self.bus        = self.pipeline.get_bus()
        self.bus.add_signal_watch()
        self.bus.connect("message", self.on_message)
        # self.bus.connect('message::eos', self.on_eos)
        # self.bus.connect('message::error', self.on_error)
        # self.bus.connect("sync-message::element", self.on_sync_message)

        #Create QUEUE elements
        self.queue1     = Gst.ElementFactory.make("queue",          None)
        self.queue2     = Gst.ElementFactory.make("queue",          None)

        # Create the elements
        self.source     = Gst.ElementFactory.make("udpsrc",         None)
        self.depay      = Gst.ElementFactory.make("rtph264depay",   None)
        self.parser     = Gst.ElementFactory.make("h264parse",      None)
        self.decoder    = Gst.ElementFactory.make("avdec_h264",     None)
        self.sink       = Gst.ElementFactory.make("appsink",        None)

        # Add elements to pipeline
        self.pipeline.add(self.source)
        self.pipeline.add(self.queue1)
        self.pipeline.add(self.depay)
        self.pipeline.add(self.parser)
        self.pipeline.add(self.decoder)
        self.pipeline.add(self.queue2)
        self.pipeline.add(self.sink)

        # Set properties
        self.source.set_property('port', 5000)
        self.source.set_property('caps', Gst.caps_from_string("application/x-rtp, encoding-name=H264,payload=96"))
        self.sink.set_property('emit-signals', True)
        # turns off sync to make decoding as fast as possible
        self.sink.set_property('sync', False)
        self.sink.connect('new-sample', self.on_new_buffer, self.sink)




    def on_new_buffer(self, appsink, data):
        print "exec two..."
        appsink_sample = GstApp.AppSink.pull_sample(self.sink)
        # with open('example.h264', 'a+') as streamer:
        buff = appsink_sample.get_buffer()
        size, offset, maxsize = buff.get_sizes()
        frame_data = buff.extract_dup(offset, size)
        print(size)
        # flag, info = buff.map(Gst.MapFlags.READ)
        # streamer.write(info.data)
        # print(info.size)
        return False

    def run(self):
        ret = self.pipeline.set_state(Gst.State.PLAYING)        
        if ret == Gst.StateChangeReturn.FAILURE:
            print("Unable to set the pipeline to the playing state.")
            exit(-1)

        self.mainloop.run()

    def kill(self):
        self.pipeline.set_state(Gst.State.NULL)
        self.mainloop.quit()

    def on_eos(self, bus, msg):
        print('on_eos()')
        self.kill()

    def on_error(self, bus, msg):
        print('on_error():', msg.parse_error())
        self.kill()

    def on_message(self, bus, message):
        t = message.type
        if t == Gst.MessageType.EOS:
            print "End of Stream :("
            self.kill()
        elif t == Gst.MessageType.ERROR:
            err, debug = message.parse_error()
            print "Error: %s" % err, debug
            self.kill()


    def on_sync_message(self, bus, message):
        print message.src


example = Example()
example.run()

Во-первых Обратный вызов AppSink не работает, я не знаю почему?Я думаю, что я должен сделать эту конфигурацию правильной в коде Python.Может кто-нибудь, пожалуйста, помогите разобраться с этим?

Во-вторых, когда я попробовал с FFMpeg и FFPlay , я получил так много проблем кодирования H264 , какэто:

enter image description here

Основная путаница заключается в том, может ли GStreamer обрабатывать данные нескольких источников в одном приемнике (мне нужно различать каждый видеокадр).

Большое спасибо.

...