This example runs a videotestsrt in one process, passes it with ipcpipelinesink/src via Unix file descriptors and plays it back on the main process.
Spike-example to test viability of a larger multimedia project, since I didn't find any online.
Learnings:
- Unix file descriptors allow zero-copy data passing between processes. Pipes are file descriptors. stdout/err are as well
ipcpipelinesrcallows inter-process gst pipeline data. You cannot useappsinkamongst processes- It requires two (!) FDs for bidirectional messaging: video data out, control/transport data in
- File descriptors can be passed to child processes by clearing the
FD_CLOEXECflag. By default,std::io::pipecreates FDs with theCLOEXECflag cleared for safety,so they aren't available with that API
We could use std::io::pipe with the traits std::os::fd::{AsRawFd} instead of nix::unistd::pipe, but for some reason, these file descriptors inherit CLOEXEC, while the nix::unistd::pipe ones don't.
In this case, we just get the error:
ERROR: from element /GstPipeline:pipeline0/GstIpcPipelineSink:ipcpipelinesink0: Could not write to resource.
This could be solved by importing nix = { version = "0.30.1", features = ["fs"] } or libc, and setting the flags with fcntl:
use nix::fcntl::{fcntl, FcntlArg, FdFlag};
// ...
// Clear the CLOEXEC flag on the FDs that the child will use
// This is necessary because std::io::pipe() sets CLOEXEC by default
fcntl(&data_write_fd, FcntlArg::F_SETFD(FdFlag::empty()))?;
fcntl(&ctrl_read_fd, FcntlArg::F_SETFD(FdFlag::empty()))?;Written in Rust, although the concepts will translate to other languages.