I have the following 2 pipelines which have been decoupled using the interpipe elements from RidgeRun:
"filesrc location=ball.ts ! tsdemux : h264parse ! " "vaapih264dec name=dec low-latency=true ! video/x-raw,format=NV12 ! identity sync=true ! tee name=t ! queue ! fakesink " "t. ! queue ! interpipesink name=vtest sync=false async=false " "interpipesrc listen-to=vtest name=vselect is-live=false stream-sync=restart-ts max-bytes=2000000 ! video/x-raw,format=NV12 ! identity sync=true ! tee name=t1 ! queue ! fakesink " "t1. ! queue ! vaapih264enc name=enc rate-control=4 bitrate=15000 ! video/x-h264,profile=high ! fakesink " If they are both ran from the same gst_parse_launch() (and therefore share the same Bus) it all works. The problem is that I want to run them separately, so they will each be created by calling gst_parse_launch() and will therefore have separate Buses. Because of that the VAAPI elements (decoder and encoder) will each create their own VADisplay in their own GstContext. And then when the buffers are passed from one to the other they have incompatible VASurfaces and that causes the encoder pipeline to fail. I have been told to listen to the NEED_CONTEXT and HAVE_CONTEXT messages on the Buses so that I can set a common VADisplay for them through the GstContext. I have tried that but didn't manage to make it work. For me it seems like the new context gets set, but later gets overwritten back to the original one. I don't know if it could be some bug in the python bindings for GstContext or if I'm just doing things wrong. Basically I have tried: - start decoder pipeline, wait for HAVE_CONTEXT message from decoder, save duplicate of VADisplay object - start encoder pipelibe, wait for NEED_CONTEXT message from encoder, create new context with saved VADisplay and set it to whole pipeline (or just encoder element) self.vaapi_display = None elif mtype == Gst.MessageType.HAVE_CONTEXT: context = message.parse_have_context() context_type = context.get_context_type() if context_type != "gst.vaapi.Display": return Gst.BusSyncReply.PASS s = context.get_structure() value = s.get_value("gst.vaapi.Display") if not self.vaapi_display: self.vaapi_display = GObject.Value.dup_object(value) elif mtype == Gst.MessageType.NEED_CONTEXT: res, context_type = message.parse_context_type() if context_type != "gst.vaapi.Display": return Gst.BusSyncReply.PASS if not self.vaapi_display: print("No Context available") return Gst.BusSyncReply.PASS context = Gst.Context.new("gst.vaapi.Display", True) s = context.writable_structure() s.set_value("gst.vaapi.Display", self.vaapi_display) message.src.set_context(context) Based on https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/blob/master/tests/examples/test-vaapicontext.c#L157 |
For future reference see https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/issues/308#note_976732
There seems to be a problem with typecasting of the VADisplay when getting the value from one structure and setting to the new context structure. |
Free forum by Nabble | Edit this page |