GstVideo.VideoFrame data property does not expose correct value
When I populate a GstVideo.VideoFrame object using the .map() member function, the data property of the VideoFrame does not contain the expected value.
I'm using python to run the following gstreamer pipeline:
self.pipeline = Gst.parse_launch(
'videotestsrc pattern=18 ! '
'video/x-raw, width=1280, height=720, framerate=30/1 ! '
'queue max-size-buffers=3 ! '
'glupload ! '
'appsink caps="video/x-raw(memory:GLMemory), format=RGB" emit-signals=true name=appsink'
)
I'm using the glupload element to load video frames straight into an existing GL context. To then display the video frames I need to grab the GL texture id from the samples that come out of appsink. I can use ctypes and get this with C code:
unsigned int
get_texture_id_from_buffer (GstBuffer * buf, GstVideoInfo *v_info)
{
GstVideoFrame v_frame;
guint texture = 0;
gst_video_frame_map(
&v_frame,
v_info,
buf,
(GstMapFlags)(GST_MAP_READ | GST_MAP_GL)
)
texture = *(guint *)v_frame.data[0];
gst_video_frame_unmap(&v_frame);
return (unsigned int)texture;
}
However, if I try to do the same in python through the gi GstVideo API I get some unexpected values:
glstuff = ctypes.CDLL('./glstuff.so')
...
self.appsink = self.pipeline.get_by_name('appsink')
self.appsink.connect('new-sample', self.new_sample)
...
def new_sample(self, appsink):
sample = self.appsink.emit('pull-sample')
buf = sample.get_buffer()
caps = sample.get_caps()
v_info = GstVideo.VideoInfo.new()
v_info.from_caps(caps)
# This returns the correct tex_id
# tex_id = glstuff.get_texture_id_from_buffer(ctypes.c_void_p(hash(buf)),
# ctypes.c_void_p(hash(v_info)))
v_frame = GstVideo.VideoFrame()
if not v_frame.map(v_info, buf, Gst.MapFlags(Gst.MapFlags.READ | GstGL.MAP_GL)):
return -1
print("v_frame.data: {}, v_frame.data[0]: {}".format(v_frame.data, v_frame.data[0]))
# output: v_frame.data: [0, 94238349179072, 94238349119112, 0], v_frame.data[0]: 0
The data property always contains a similar list of numbers, where the first and last numbers are 0 and the second and third are always high 64-bit numbers. I tried treating the middle two as pointers but they point to random, unchanging values that do not match the tex_id I get from the C function.
The value I expect from v_frame.data[0] is an unsigned int, and it's usually in the range 2-7. If I access any other index of data within the C function I get a segfault, so I'm assuming only the first index is used for this mapping.
Here's my env details:
- Fedora 28
- python3-gobject-3.28.3-1.fc28.x86_64
- python3-3.6.6-1.fc28.x86_64
- gstreamer1-1.14.1-2.fc28.x86_64
Could anyone confirm whether or not this is a bug? I'm happy to provide more info if needed.