After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 794744 - Data is none in buffer from GstVideo.VideoFrame
Data is none in buffer from GstVideo.VideoFrame
Status: RESOLVED OBSOLETE
Product: GStreamer
Classification: Platform
Component: gst-python
unspecified
Other Linux
: Normal normal
: git master
Assigned To: GStreamer Maintainers
GStreamer Maintainers
Depends on:
Blocks:
 
 
Reported: 2018-03-27 21:58 UTC by Dineth W
Modified: 2018-11-03 15:37 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Dineth W 2018-03-27 21:58:09 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()
Comment 1 Mathieu Duponchelle 2018-03-27 23:55:29 UTC
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.
Comment 2 Mathieu Duponchelle 2018-03-27 23:57:03 UTC
correction: g_field_info_get_offset(flags_field_info) == G_STRUCT_OFFSET (GstVideoInfo, ABI) obviously
Comment 3 GStreamer system administrator 2018-11-03 15:37:21 UTC
-- 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.