Conversation
041723b to
a8c77d7
Compare
|
I would put the gstreamer cffi in |
The |
|
An important thing I'm seeing is that in l51 of pyproject.toml, it would be necessary to add
cc: @ylatuya |
|
Something to keep in mind... now that #319 uses exit code 69 for "not supported" (matching the Otherwise the |
ae60864 to
afab38d
Compare
|
@dabrain34 I have rebased this MR on top of your work. The runner is now returning a new |
3acb295 to
28e5e05
Compare
664f1bb to
7ace11d
Compare
7ace11d to
fea1db0
Compare
|
can you rebase the branch please ? |
fea1db0 to
7274020
Compare
7274020 to
f9e7266
Compare
dabrain34
left a comment
There was a problem hiding this comment.
would be nice to have a small unit test for the player as it brings potential new issues
|
|
||
| pipeline = self.gen_pipeline(input_filepath, output_filepath, output_format, optional_params) | ||
| run_command(shlex.split(pipeline), timeout=timeout, verbose=verbose, env=env) | ||
| result = run_pipeline(pipeline, timeout=timeout, verbose=verbose, env=env) |
There was a problem hiding this comment.
result is never used, you can remove it
| return result | ||
| else: | ||
| # No message received, check for timeout | ||
| if timeout_ns != GST_CLOCK_TIME_NONE: |
There was a problem hiding this comment.
This code should be run before polling the message as otherwise you'll never end if you still receive message after the timeout.
| cmd.append(pipeline) | ||
| process_env = os.environ.copy() if env is None else env.copy() | ||
| process_env.update(GStreamerInstallation().get_environment()) | ||
| result = subprocess.run(cmd, env=process_env, capture_output=True, text=True, check=False) |
There was a problem hiding this comment.
For more security in terms of potential deadlocks during the player teardown/cleanup, its highly recommandable to use the timeout here as well
| cmd.extend(["--timeout", str(timeout)]) | ||
| cmd.append(pipeline) | ||
| process_env = os.environ.copy() if env is None else env.copy() | ||
| process_env.update(GStreamerInstallation().get_environment()) |
There was a problem hiding this comment.
you need to tell where fluster.gstreamer.runner as it might fail to run it from outside of the fluster main folder.
laptop:~ $ path_to_fluster/fluster.py run -s -d GStreamer-H.264-Libav -ts JVT-FR-EXT
will fail silently
| process_env.update(GStreamerInstallation().get_environment()) | |
| process_env.update(GStreamerInstallation().get_environment()) | |
| pkg_root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) | |
| process_env["PYTHONPATH"]= os.pathsep.join(filter(None, [pkg_root, process_env.get("PYTHONPATH")])) |
| return self._plugin_path | ||
|
|
||
| @property | ||
| def bin_path(self) -> Optional[str]: |
| self._gst.gst_bus_timed_pop_filtered.restype = ctypes.c_void_p | ||
|
|
||
| # gst_bus_poll | ||
| self._gst.gst_bus_poll.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_uint64] |
There was a problem hiding this comment.
I dont think this is necessary, please clean up
| msg = self._gst.gst_bus_timed_pop_filtered(bus, timeout, message_types) | ||
| return msg if msg else None | ||
|
|
||
| def bus_poll(self, bus: ctypes.c_void_p, message_types: int, timeout: int) -> Optional[ctypes.c_void_p]: |
There was a problem hiding this comment.
this method is unnecessary
| raise GStreamerError("GStreamer not initialized") | ||
| return int(self._gst.gst_element_set_state(element, state)) | ||
|
|
||
| def element_get_state(self, element: ctypes.c_void_p, timeout: int = GST_CLOCK_TIME_NONE) -> Tuple[int, int, int]: |
There was a problem hiding this comment.
This method is useless, please remove
| raise GStreamerError("GStreamer initialization failed") | ||
| self._initialized = True | ||
|
|
||
| def deinit(self) -> None: |
There was a problem hiding this comment.
should it be called of the process ?
There was a problem hiding this comment.
Fixed: gst_deinit() now runs at exit — runner.py:408 → runner.py:151 → gst_ctypes.py:491.
|
I would not merge as the main feature is not working to track if the media is not supported by GStreamer. Investigating |
Add a new GStreamer runner to launch pipelines that gives use more control in errors and allow us to differentiate for example between a pipelines miss-configuration or a format that's not supported.
f9e7266 to
5e39fb5
Compare
rsanchez87
left a comment
There was a problem hiding this comment.
Review last changes, checking functionality
Hi @dabrain34, I think all the comments have been resolved at this point, and it's ready for review. Once you approve it, I'll clean up the commits and squash them properly for the Git history, thanks |
|
unfortunately I still experience the failure instead of not supported. The reason is that this is not negociated. you can give a try to:
I got this error with a nvidia hardware which should support VP9 but not this resolution, so the element should return an error (I dont recall from the top of my head) and the player should return a not supported . you can check what I did in https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/10088/diffs?file_path=subprojects%2Fgstreamer%2Ftools%2Fgst-launch.c#line_2370bc12d_A408 I think that was the one reported by the pipeline we should track by the way on a non-supporting vulkan setup, I get the following error when running this line: you can enable the leak tracer with |
Read the bus message type as unsigned and compare it exactly so extended message types are not mistaken for EOS/ERROR/WARNING, and report media GStreamer cannot handle as not supported (EX_UNAVAILABLE, 69), including the missing-plugin element message. Also set PYTHONPATH so the runner can be imported from any directory, add a subprocess timeout and verbose output, decode GError messages, let get_environment() take a base environment, and remove the unused bindings, gst-launch --no-fault leftovers and dead code.
Cover bus message classification, unsupported media detection, the message loop timeout and the exit code mapping of run_pipeline without requiring GStreamer to be installed.
Reading GstMessage.type with a hardcoded offset was wrong on 32-bit systems: GstMiniObject is nine 4-byte fields with no padding there, so it is 36 bytes and the type field lives at offset 36, not 32. Describe the GstMiniObject leading fields and the GstMessage head as ctypes Structures so ctypes computes the offset and padding for the current architecture, and keep reading the type as unsigned so extended message types are not sign-extended.
Assert the GstMiniObject size (64 bytes on 64-bit, 36 on 32-bit) and that the message type offset matches, and exercise the Windows library lookup with a faked platform so both the MSVC (glib-2.0-0.dll) and MinGW (libglib-2.0-0.dll) spellings are checked.
gst_parse_launch() can return a partially built pipeline together with an error, e.g. when an element does not exist. parse_launch() raised without unreffing it, so it leaked. Unref it before raising, and add tests for the error, error-without-pipeline and success cases.
Thanks for the detailed repro steps @dabrain34 , I tried it on a machine with GStreamer 1.24.2, where the Vulkan plugin only ships vulkanh264dec and vulkanh265dec. There is no vulkanvp9dec, so the run ends at the "no element" parse failure and the decoder is skipped. That means I could not reproduce the While doing this I did find and fix a leak on that error path, using For the not negotiated case: right now the runner only maps GST_STREAM_ERROR_CODEC_NOT_FOUND, GST_STREAM_ERROR_NOT_IMPLEMENTED and GST_CORE_ERROR_MISSING_PLUGIN to the not supported exit code, so a negotiation failure ends up as a plain error. To fix it properly I need to know which error the Vulkan decoder actually posts for that resolution. As far as I can tell, the current If it helps, I can also print the error domain and code in the runner's --verbose output, so the 08x10 case can be classified from your NVIDIA setup and we can add exactly that error to the mapping, with a test |
Add a new GStreamer runner to launch pipelines that gives use more control in errors and allow us to differentiate for example between a pipelines miss-configuration or a format that's not supported.
This a first iteration in order to support #319