Reputation: 2162
I'm getting different behavior when the sink of a gst-launch pipeline is a named pipe vs a normal file.
I have a gst-launch pipeline which displays video from a camera on an OMAP embedded (linux) board and delivers the video as avi via a tee.
gst-launch -v -e omx_camera device=0 do-timestamp=1 mode=0 name=cam cam.src ! "video/x-raw-yuv, format=(fourcc)NV12, width=240, height=320, framerate=30/1" ! tee name=t1 t1. ! queue ! ducatih264enc profile=100 level=50 rate-preset=low-delay bitrate=24000 ! h264parse ! queue ! avimux ! filesink location=/tmp/camerapipe t1. ! queue ! dri2videosink sync=false
If I make
filesink location=/some/real/file t1.
all is well
but I wish to read the output with a Java/opencv process, and when I do this I don't get anything to the java process. The gst-launch process does announc that it's changed to PLAY.
To simplify things instead of the java process I tail -f
the named pipe
and also don't see any output, though in both cases the dri2videosink is displaying the video
With either tail or the java process, killing it also stops the gst-launch process, so obviously it's 'connected' in some sense.
Killing the gst-launch process with the tail running gets what looks like a few K, maybe 1 frame of data, after gst-launch exits.
I've tried saving to normal file and reading with the java process, that works, so I know it's not the data format.
Upvotes: 3
Views: 5563
Reputation: 153
This would work, but problem with pipes and files is that closing reader makes gstreamer to stop working. Solution is to use racic's ftee program:
sudo gst-launch -e videotestsrc ! video/x-raw-yuv, framerate=20/1, width=640, height=480 ! ffenc_mpeg4 ! fdsink fd=1 | ./ftee /dev/video_stream > /dev/null 2>&1
This will output stdin of ftee
to named pipe with copy to stdout (sent to /dev/null) but ftee
ignored errors and closing of destination pipe. To playing from pipe and stopping does not influence gstreamer. Just try and then think about what I wrote. Not the opposite :)
Play from named pipe, anytime you want:
gst-launch filesrc location=/dev/video_stream ! autovideosink
Regarding your use with OpenCV:
VideoCapture capture("/dev/video_stream");
video stream from /dev/video_stream
should be mpeg4 but I'm not sure if OpenCV will sense properly the source. You might have to experiment with provider (even gstreamer provider is available when compiled into opencv).
See api prererence when creating Capture:
VideoCapture (const String &filename, int apiPreference)
set apiPreference
to proper value. I'd try ffmpeg or gstreamer.
If you want use gstreamer directly, try with appsink
as a sink, that is OpenCV. This might be something like
filesrc location=/dev/video_stream ! video/h264 ! appsink
caps with video/h264
is a blind guess as I don't have ffenc_mpeg4 encoder because it's from gst 0.10 but you get the idea.
Good luck.
Upvotes: 1
Reputation: 908
I am trying to do the same thing, I am using opencv in c and working in ubuntu though.
I did get the following to work:
I created a named pipe in /dev/ called video_stream using mkfifo make sur eyou have permissions to read/write to/from it or just use sudo.
Play with test video to a named pipe
sudo gst-launch -e videotestsrc ! video/x-raw-yuv, framerate=20/1, width=640, height=480 ! ffenc_mpeg4 ! filesink location=/dev/video_stream
Play from web cam to a named pipe:
sudo gst-launch -e v4l2src device=/dev/video0 ! ffenc_mpeg4 ! filesink location=/dev/video_stream
I then used the face detection tutorial at
to test everything, but changed my input from webcam 1 to the namedpipe.
capture = cvCaptureFromCAM( -1 );
Becomes
VideoCapture capture("/dev/video_stream");
Upvotes: 3