Gstreamer message to signal a new frame from the video source (webcam)

I am trying to save a stream from a webcam as a series of images using gstreamer. I have written this code so far ...

#!/usr/bin/python import sys, os import pygtk, gtk, gobject import pygst pygst.require("0.10") import gst def __init__(self): #.... # Code to create a gtk Window #.... self.player = gst.Pipeline("player") source = gst.element_factory_make("v4l2src", "video-source") sink = gst.element_factory_make("xvimagesink", "video-output") caps = gst.Caps("video/x-raw-yuv, width=640, height=480") filter = gst.element_factory_make("capsfilter", "filter") filter.set_property("caps", caps) self.player.add(source, filter, sink) gst.element_link_many(source, filter, sink) 

After that, I try to create a signal on the bus to listen to any message from the source or receiver, to indicate that a new frame has been sent or received so that it can be saved.

  bus = self.player.get_bus() bus.add_signal_watch() bus.connect("message::any", self.save_file,"Save file") 

where save_file is my callback where I want to save the file.

 def save_file(self, bus, msg): print "SAVED A NEW FILE" 

I have two questions:

  • How do I call this callback. The message :: any does not work.
  • When this message is called, how do I access the image buffer.

UPDATE (4-12-2012):

A couple of links for reference

+4
source share
2 answers

Gstreamer Bus is not intended for this purpose. Messages posted there signal some special event, such as the end of a stream, a change in the state of an element, and so on. Buffers (images) passing through elements usually do not generate any messages on the bus.

You can consider several options:

  • make the element "tee" in front of the video content and connect the "multifilesink" in parallel to the videos (you may want to see some image encoders such as pngenc or jpegenc and put one of them before multifiling ")
  • as before, but use "appsink", which allows you to process buffers and do anything with them -
  • if you want to enable and disable the reset, consider using the valve element

You might want to set the sync property to false on your secondary receiver (which causes buffers to be flushed as soon as possible without synchronizing with the clock). Consider also adding some queues after the tee (without this deadlock, it can happen during the transition to readiness to pause).

+1
source

I am not sure that my answer over the years will be useful to you. but hopefully it will be useful to others.

to get a message that you received a buffer, you can use gstreamer probes .

It could be something similar:

 def make_pipeline(self): CLI2 = [ 'v4l2src ! video/x-raw,format=RGB,width=640,height=480,framerate=30/1 ! ', 'videoconvert ! x264enc bitrate=128 ! mpegtsmux name="mux" ! hlssink name="sink"', ] gcmd = ''.join(CLI2) self.pipeline = Gst.parse_launch(gcmd) self.hlssink = self.pipeline.get_by_name("sink") self.hlssink.set_property("target-duration",2) self.hlssink_pad = self.hlssink.get_static_pad("sink") probe_id = self.hlssink_pad.add_probe(Gst.PadProbeType.EVENT_UPSTREAM,probe_callback) 

and then the probe callback function can be:

 def probe_callback(hlssink_pad,info): info_event = info.get_event() info_structure = info_event.get_structure() do_something_with_this_info return Gst.PadProbeReturn.PASS 

So, every time there is an event on the source site or on the stand, the probe callback function is called in the main thread.

Hope this helps!

0
source

Source: https://habr.com/ru/post/1447973/


All Articles