Gstreamer rtsp stream to appsink to openCV - c++

I need a bit of your help because I'm trying to receive rtsp stream by gstreamer and then put it into openCV to process video. What is worse, I will need it back from openCV but first things first. I'm quite new to this so I don't know Gstreamer well so I'm counting on you guys. Some simple examples would be best but I'll use what I have;)
Thanks in advance

You can use something like this:
uridecodebin uri=rtsp:// name=uridec ! queue ! tee name=t ! queue ! <some encoder and muxer> ! filesink t. ! queue ! videoconvert ! "video/x-raw, format=BGR" ! appsink t. ! queue ! <restream>
In this possible solution you are receiving and decoding at uridecodebin which means that for re-streaming you need to encode, as well as encoding for storing to a file. If that's not what you want you can replace uridecodebin with rtspsrc that will give you RTP streams instead of decoded raw streams. Something like:
rtspsrc ! rtpXdepay ! tee name=t ! ...
Replace X with the format you are receiving (can be done dynamically from your application). Now the output is an encoded stream that you can use in a similar way as the sample pipeline above.
Note that these suggestions are assuming your rtsp input is a single stream (video likely), if you want video and audio you need to add 2 branches out of uridecodebin or rtspsrc. I also assumed that by 'rtspStream' is some sort of external library/application that you are going to use to retransmit instead of using gstreamer itself. In any way, this should give you an idea.

Related

Gstreamer capture and store mjpeg from webcam

I am trying to capture and store a webcam stream. The requirements are 1920x1080#30fps. And it must be done by a single-board-computer (Raspberry).
The duration to capture is 10 minutes. (For the moment I only capture 10 seconds for testing)
In general the camera (usbfhd01m from ELP) is able to provide an MJPEG stream in 1920x1080#30fps. I am just not able to store it. And I don't know why. I tried it with the following pipeline:
gst-launch-1.0 v4l2src device=/dev/video0 num-buffers=300 do-timestamp=true ! image/jpeg,width=1920,height=1080,framerate=30/1 ! queue ! avimux ! filesink location=test.avi
The result is a video file which is far away from being fluent. What is missing in my pipeline?
When I use the same pipeline, but decode the stream and save it in a raw file like this:
gst-launch-1.0 v4l2src device=/dev/video0 num-buffers=300 do-timestamp=true ! image/jpeg,width=1920,height=1080,framerate=30/1 ! queue ! jpegdec ! filesink location=test.yuv
then the raw video is absolutely fluent. Therefore, I think the pipeline and the device is able to record in 1920x1080#30fps, but there seems to be something wrong for saving the stream.
Storing the stream into matroska fileformat does not change my problem. And for transcoding on the fly to H264 the Raspberry Pi 3 doesn't seem to be powerful enough. (Even by using omxh264enc)
What happens when you remove the do-timestamp=true? This options applies current pipeline timestamps to the sample buffers - overwriting those coming out from the device. You probably want to store the original timestamps instead of overwriting them as they can carry some pipeline jitter.
In your second pipeline you save the stream as raw. Basically removing all timestamp information that you have (also the jitter timestamps). So when you play back the raw stream it assumes a constant framerate instead.

Implement multi-stream in Gstreamer

I've written a Gstreamer source plugin, it can produce buffers and transform to downstream elements and do preview. Recently I received a request to implement multi-stream, that one stream to do preview, and the other stream to do recording(using filesink, I suppose). I investigated 'tee' plugin before, but it turns out that it only supports multiple streams with the same formats/resolutions. What plugin should I use if two streams have different formats/resolutions, say, two capsfilters in one pipeline? If there are plugin could do that, could you provide some examples for how to use them?
the pipeline I expect goes like this:
gst-launch-1.0 mysrc ! (some plugins) name=t ! video/x-raw,format=NV12,width=320,height=240 ! xvimagesink t. ! video/x-raw,format=YUY2,width=640,height=480 ! filesink location=img_file
I think either you implement this in your plugin which will produce two src pads and you will just connect the filesink and videosink correctly..
Or you will use tee and videoscale videoconvert videorate elements to achieve different resolutions. This approach is of course more resource demanding and the first approach may be better optimisable (just guessing, I dont know anything about your plugin).
This is example with two videosink each different size.. You have to realise that you have one input from your mysrc.. that is you have to duplicate it and then one of the branches have to be resized (or maybe two if you need).. there is no other way. What you want is element of combination of tee and videoscale/videorate/videoconvert.. I am not sure if there is such element, and I am not sure it would be very usable(but maybe it has sense, I just do not see it)..
gst-launch-1.0 videotestsrc ! video/x-raw,width=640,height=480 ! tee name=t t. ! queue ! videoscale ! video/x-raw,width=320,height=240 ! videoconvert ! autovideosink t. ! queue ! videoscale ! video/x-raw,width=200,height=200 ! videoconvert ! autovideosink
Maybe I just didnt understand your question.

Pausing a gstreamer thread made with tee

I have a gstreamer pipeline that takes video from the webcam and splits it into two threads:
1) use appsink so I can programmatically edit the captured frames
2) saves the video to a file
The pipeline looks like this:
gst-launch-1.0 v4l2src device=/dev/video0 \
! tee name=t ! queue ! videoconvert ! videoscale ! appsink name=sink caps="video/x-raw,format=RGB,width=800,framerate=15/1" t. \
! queue ! video/x-raw,width=800,framerate=15/1 ! jpegenc ! avimux ! filesink location=/tmp/output.avi
I'm using this inside a C++ app.
My problem is that in most of the time I don't need the two threads running simultaneously, but only one of them. And in rare cases - need both.
So I need some way to temporarily pause/stop either the appsink or the video saving - in order to save CPU.
The way I do it now is to destroy the pipeline and recreate it again with only one thread when needed, but that seems quite ugly.
I've been looking for a better solution, but no luck so far - is there any way to do that?
Thanks in advance!
An easier way to approach this may be to use a valve element. It has a drop property that you can set to true or false. Put it right after the queue on the tee.
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer-plugins/html/gstreamer-plugins-valve.html
EDIT: This doesn't work. Some more details are present in this post on the GStreamer mailing list:
http://gstreamer-devel.966125.n4.nabble.com/How-to-Stop-start-recording-using-Valve-element-td4661728.html

Not able to save gstream videosink

I'm just trying to save the dummy video to my directory.
In that case I end up in this error so I knew something is wrong in the pipeline.
Do I missing any parameters here ?
gst-launch -v videotestsrc ! ximagesink ! filesink location=~/cupcake.mp4
WARNING: erroneous pipeline: could not link ximagesink0 to filesink0
I just want to record only the video.
ximagesink is a sink element and as such doesn't have an output (source pad).
This command will tell you about the details of an element:
gst-inspect-1.0 ximagesink
Notice that ximagesink has only sink pad and no source pads, so it doesn't generate any output.
You can dump the video directly to file by using:
gst-launch-1.0 videotestsrc ! filesink location=~/cupcake.raw
Unfortunately, this is still not what you want as videotestsrc will generate raw video and not encoded or muxed to mp4. If you want mp4 you need to put it into the mp4mux that will organize the data it receives into the mp4 container. It is also recommended to encode the video to reduce its size. Let's assume you want to use H.264 as your codec. You can use the element x264enc to encode to H.264
gst-launch-1.0 -e videotestsrc ! x264enc ! mp4mux ! filesink location=~/cupcake.mp4
Notice that I also added the "-e" parameter that will make gst-launch-1.0 send an EOS event and wait for the EOS message to indicate elements have finished working. Without the flag the pipeline is simply interrupted and aborted.
In any case I'd recommend going back to the manuals for application development: http://gstreamer.freedesktop.org/documentation/
The manpage for gst-launch-1.0 is also useful.
Disclaimer: You are using gstreamer 0.10 which is 3 years unmantained and obsolete, please upgrade to 1.0 (This answer is aimed at 1.0 but it can easily be applied to 0.10 by changing the commands to 0.10 version)

Gst-launch: Saving every image of a video stream while watching it

I'm currently trying to save a video stream into files using gst-launch while simultaneously watching the video itself (using v4l2src). As of now I got this by doing a work around with saving the images to files using ! multifilesink while having a tcl-script that automatically shows the newest file in one folder in an X windows.
This works but has of course a bit of a delay I would like to reduce.
Is there a possibility to do this with only using gst-launch? I'm not very experienced with gstreamer unfortunately. Could it be done saving the files with multifilesink while showing them using multifilesrc? Or is it impossible with only gst-launch?
It is possible, there is the 'tee' element that will replicate the stream in its source pads.
So, for example:
gst-launch-1.0 v4l2src ! tee name=t ! queue ! videoconvert ! autovideosink t. ! queue ! videoconvert ! jpegenc ! multifilesink location=image_%06d.jpg
This should have it displaying and saving to jpg with multifilesink.
Also, it seems that you are using gstreamer 0.10, it is (2 years?) obsolete and unmantained. Please move to 1.x