TypeError when decoding appsink output in numpy array

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

TypeError when decoding appsink output in numpy array

jrolso
I'm trying to get numpy frames from an appsink pipeline so I can process the frames in python using opencv and what not.
Using farious sources I pieced together some code:

import time
import gi
import numpy as np
gi.require_version("Gst", "1.0")
gi.require_version("GstApp", "1.0")
from gi.repository import Gst, GstApp, GLib
_ = GstApp

def on_new_sample(app_sink):
    sample = app_sink.pull_sample()
    caps = sample.get_caps()
    height = caps.get_structure(0).get_value("height")
    width = caps.get_structure(0).get_value("width")
    buffer = sample.get_buffer()
    data = buffer.extract_dup(0, buffer.get_size())
    numpy_frame = np.ndarray(
        shape=(height, width, 3),
        buffer=data,
        dtype=np.uint8)

Gst.init(None)
pipeline = Gst.parse_launch("videotestsrc ! video/x-raw, width=240, height=320 ! queue  ! videoconvert ! " +
"video/x-raw, width=240, height=320, format=BGR !  appsink sync=true  max-buffers=1 drop=true name=sink emit-signals=true")
t_start = time.time()
main_loop = GLib.MainLoop()
appsink = pipeline.get_by_name("sink")
appsink.set_property("emit-signals", True)
pipeline.set_state(Gst.State.PLAYING)
handler_id = appsink.connect("new-sample", on_new_sample)
time.sleep(30)
pipeline.set_state(Gst.State.NULL)
main_loop.quit()


The problem is that it seems that numpy is unable to piece together a frame from the data it reads from the buffer. The error I get is:

TypeError: can't convert return value to desired type


I know numpy can decode the data from the buffer into a frame fine because using the following piece of code I nabbed from another thread works just fine:

for i in range(100):
    pipeline.set_state(Gst.State.PLAYING)
    smp = appsink.emit('pull-preroll')
    caps = smp.get_caps()
    height = caps.get_structure(0).get_value("height")
    width = caps.get_structure(0).get_value("width")
    buf = smp.get_buffer()
    data=buf.extract_dup(0, buf.get_size())
    frame = np.ndarray(
            shape=(height, width, 3),
            buffer=data ,
            dtype=np.uint8)
    frame = cv2.resize(frame,(0,0),fx=0.2,fy=0.2)
    cv2.imshow('frame',frame)
    cv2.waitKey(50)
    pipeline.set_state(Gst.State.PAUSED)


Why does converting the data from the buffer into an numpy array give an error when using appsink.connect(), while it works fine using  appsink.emit('pull-preroll')?