GNOME Bugzilla – Bug 794744
Data is none in buffer from GstVideo.VideoFrame
Last modified: 2018-11-03 15:37:21 UTC
Hey, When trying to get buffer data from GstVideo.VideoFrame when inheriting from GstVideo.VideoFilter using do_transform_frame. Steps to Reproduce: Run code below and it will show none for buffer Actual Results: No data in buffer Black screen from ximagesink(which may be because i have to push outframe back. Dont know if i need to since i dont change any of the frame.) Expected Results: Gives a Gst.Buffer which should hold a full image frame to be manipulated (in the docs here https://lazka.github.io/pgi-docs/GstVideo-1.0/classes/VideoFrame.html it says that a Gst.Buffer will be returned) Build Date & Hardware: March 26 2018 on ubuntu 16.04 LTS Additional Builds and Platforms: Havnt tested on any other builds Additional Information: I believe my Gstreamer version is gst-launch-1.0 version 1.8.3 GStreamer 1.8.3 https://launchpad.net/distros/ubuntu/+source/gstreamer1.0 This was found by using gst-launch-1.0 --version in the command prompt The buffer is None. Here is some sample code, let me know if i should post anything else or if i can help. Thanks for your time. import sys import gi gi.require_version('Gst', '1.0') gi.require_version('GstVideo', '1.0') from gi.repository import GObject, Gst, GstVideo Gst.init(sys.argv) GObject.threads_init() Gst.segtrap_set_enabled(False) class GstTimestamp(GstVideo.VideoFilter): __gstmetadata__ = ('<longname>', '<classification>', '<description>', '<author>') __gsttemplates__ = (Gst.PadTemplate.new("sink", Gst.PadDirection.SINK, Gst.PadPresence.ALWAYS, Gst.Caps.new_any()), Gst.PadTemplate.new("src", Gst.PadDirection.SRC, Gst.PadPresence.ALWAYS, Gst.Caps.new_any())) def __init__(self): GstVideo.VideoFilter.__init__(self) def do_transform_frame(self,inframe,outframe): #this should give me that data for the frame data = inframe.buffer #data is None print data #dont know if im properly sending data back since #i just get blank screen return Gst.FlowReturn.OK #used for registration def plugin_init(plugin): Gst.Element.register(plugin, 'timestamper', 0, GObject.type_register(GstTimestamp)) return True def init(): version = Gst.version() Gst.Plugin.register_static( version[0], version[1], 'timestamper', 'Timestamper', plugin_init, '1.0', 'GPL', 'timestamper', 'plugins-demo', 'demo') init() def connect(bus, name): def _connect(f): bus.connect(name, f) return f return _connect def main(): pipeline = Gst.parse_launch('videotestsrc ! timestamper ! ximagesink') bus = pipeline.get_bus() bus.add_signal_watch() #Gst.debug_set_active(True) #Gst.debug_set_default_threshold(4) @connect(bus, "message::error") def on_error(bus, message): pipeline.set_state(Gst.State.NULL) exit(message.parse_error()) @connect(bus, "message::eos") def on_eos(bus, message): pipeline.set_state(Gst.State.NULL) exit(0) pipeline.set_state(Gst.State.PLAYING) loop = GObject.MainLoop() try: loop.run() except(KeyboardInterrupt): pass pipeline.set_state(Gst.State.NULL) if __name__ == '__main__': main()
Investigated, this is unfortunately a gobject-introspection bug: pygobject obtains the value of the field with g_field_info_get_field(), which in turn uses the offset returned by g_field_info_get_offset(), which is wrong (differs from G_STRUCT_OFFSET (GstVideoFrame, buffer). Digging a bit deeper, the VideoFrame is defined as: struct _GstVideoFrame { GstVideoInfo info; GstVideoFrameFlags flags; GstBuffer *buffer; } and GstVideoInfo ends with a union: struct _GstVideoInfo { ... union { struct { GstVideoMultiviewMode multiview_mode; GstVideoMultiviewFlags multiview_flags; GstVideoFieldOrder field_order; } abi; /*< private >*/ gpointer _gst_reserved[GST_PADDING]; } ABI; } The union isn't taken into account by the return of get_offset, this is easy to determine as g_field_info_get_offset(buffer_field_info) == G_STRUCT_OFFSET (GstVideoInfo, ABI). The implementation of the get_offset function ends with: blob = (FieldBlob *)&rinfo->typelib->data[rinfo->offset]; return blob->struct_offset; I haven't investigated past this point, I would suggest reporting this issue to the gobject-introspection devs, ideally with a smaller test case, though the problem here is pretty clear cut.
correction: g_field_info_get_offset(flags_field_info) == G_STRUCT_OFFSET (GstVideoInfo, ABI) obviously
-- GitLab Migration Automatic Message -- This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/gstreamer/gst-python/issues/11.