Getting file size in Gstreamer - gstreamer

I am using gstreamer to implement an audio player. I have created pipeline as below:
filesrc location=a.mp3 ! mymp3parser ! mymp3dec ! alsasink.
I want to use the size of the file in bytes (i.e a.mp3 file size) in mymp3parser plugin. But I haven't got any clue to get the file size. How do I get the file size in mymp3parser from filesrc?

You can send a duration query to the filesrc. The query can specify the format (e.g. time or bytes).

Related

Is there any way to write h264 encoded video stream in a matroska file with gstreamer?

I have to get a processed video from gstreamer pipe, compress it based on h264 or h265 alg. and then write it to storage. There are some problems in this project that must be handled:
Saved video must be playable by any standard video players such as vlcplaye, windows media player, kmplayer and ...
If for any reason the destination file does not close properly (such as a power outage), the entire file should not be lost and the saved video should be playable until the problem occurs.
My solution to this project with these constraints, is an opencv writer with a gstreamer pipe as follow:
...
std::string gstPipe("appsrc ! videoconvert ! omxh264enc ! "
"splitmuxsink muxer=matroskamux "
"max-size-time=50000000000 location="
"/file/path/save%d.mkv");
cv::Size frameSize(frameWidth, frameHeight);
bool result = videoWriter.open(gstPipe, cv::CAP_GSTREAMER, 0,
fps, frameSize);
This solution splits a video stream into multiple files, but it is needed to save whole video in one file.
Does anyone have a better solution to offer?
Thank you very much in advance for your helps.

GStreamer 'rawvideoparse' element reads wrong amount of bytes

I'm reading a byte-stream YUV420 at 972x720 pixels from a file with Gstreamer using the following command:
gst-launch-1.0 filesrc location=testfile blocksize=1049760 ! rawvideoparse width=972 height=720 framerate=1/1 ! xvimagesink
This works in so far that I get an image but it isn't displayed correctly. When exporting the frames seperately using command:
gst-launch-1.0 filesrc location=testfile blocksize=1049760 ! rawvideoparse width=972 height=720 framerate=1/1 ! multifilesink location="rvp_%d.raw"
I see that when using the element 'rawvideoparse' it will create a file of 1051200 bytes per frame instead of the expected 1049760. When I remove 'rawvideoparse' the frames are exported correctly but my objective is to read them directly from the file into an 'xvimagesink'
Where am I messing up?
Thanks to the GStreamer Development mailing list I got an answer. The problems was that the rawvideoparse element can't handle this resolution. When I switched to 976 width it works.

GStreamer: VBI data stream decoding

I have a question related to processing VBI data stream through 'teletextdec' plug-in.
Basically, I've already checked functionality of the next configuration:
gst-launch-1.0 -v -m filesrc location=sample.mpeg ! tsdemux ! teletextdec ! videoconvert ! ximagesink
where sample.mpeg is a video file containing not only video data, but also VBI data. Result is presented as video frames with overlayed VBI decoded VBI data.
At the moment, I'm interested to repeat similar configuration, but when video and VBI data are separated from each other (need to work with two data sources: one for video data providing, another for VBI data providing).
In other words, we have two next data sources:
/dev/vbi0 - is a character device, with binary data as an output
/dev/video0 - v4l2 device, with RAW data video as an output
I understand, that generally I need to have something like that:
avfvideosrc name=src ! videomixer src.vbi_01 ! teletextdec
Does anyone have similar experience?
Could anyone explain how correctly to execute mixing and decoding of RAW video data with VBI data?
Thanks in advance!

Gstreamer multifilesink wav files splitting

I have problem with recording streams using gstreamer.
I have to write audio and video separately and cut in when signal arrived. I have correctly working video, but still have problems with wav files.
Even simple pipeline in gst-launch don't work correctly. I have wave file and I am trying to split it using multifilesink:
gst-launch filesrc location=test.wav ! multifilesink location=test2%d.wav next-file=4 max-file-size=512000
But final wav files are corrupted while the same pipeline with ts files is working ok:
gst-launch-1.0 filesrc location=test.ts ! multifilesink location=test2%d.ts next-file=4 max-file-size=2000000
multifilesink doesn't know anything about the data it splits up, so it won't take care of adding headers to each of the files it writes.
The reason why your .ts files work is because it was designed to be a streaming format where each separate packet will be treated independently. Therefore, one can just 'tune in' to the stream whenever one likes. The decoder will simply look for the next packet header it finds and start decoding there (for Details have a look at MPEG TS' wiki page.
The WAV file format however was designed as pure file (and not as a streaming) format. Therefore, there's only one header at the start of the file. When you split that file up into multiple files, these headers are missing (the file contains only raw PCM data then).
To work around that issue, you can...
manually copy the .wav header from the first file to all the other ones
use programs that support PCM files and either work directly with them or convert the files (you'll have to set the channel count, sample rate and bitrate manually when opening those files though).
use another, stream oriented file format like .mp3 which comes from the same family of codecs as .ts and also uses a separate 4-byte header for each frame (Keep in mind though that MP3 is a lossy file format).
An example pipeline would be:
gst-launch filesrc location=test.wav ! wavparse ! lame ! multifilesink location=test%d.mp3 next-file=4 max-file-size=100000
If you're willing to use some scripting as well and split the task up into different gst-launch calls, I can offer you another possible way to solve your little problem:
The following script is a Linux bash script. You should be able to translate that to Windows batch script (or a C or python app if you want):
#!/bin/bash -e
# First write the buffer stream to .buff files (annotated using GStreamer's GDP format)
gst-launch -e filesrc location=test.wav ! wavparse ! gdppay ! multifilesink next-file=4 max-file-size=1000000 location=foo%05d.buff
# use the following instead for any other source (e.g. internet radio streams)
#gst-launch -e uridecodebin uri=http://url.to/stream ! gdppay ! multifilesink next-file=4 max-file-size=1000000 location=foo%05d.buff
# After we're done, convert each of the resulting files to proper .wav files with headers
for file in *.buff; do
tgtFile="$(echo "$file"|sed 's/.buff$/.wav/')"
gst-launch-0.10 filesrc "location=$file" ! gdpdepay ! wavenc ! filesink "location=$tgtFile"
done
# Uncomment the following line to remove the .buff files here, but to avoid accidentally
# deleting stuff we haven't properly converted if something went wrong, I'm not gonna do that now.
#rm *.buff
Now to what the script does:
First we're gonna use multifilesink to create a set of .buff files, each under 1MB of size (gdppay will annotate each buffer with its caps; the -e flag of gst-launch will cause it to trigger an EOS if the process gets killed prematurely which is useful if you're reading and decoding an internet stream)
The second gst-launch invocation within the for loop takes one of the .buff files, parses the GDP headers using gdpdepay (and strips them), adds a WAV header and writes the result to a .wav file.
Hope this is a solution you can live with, because I doubt there's a way to do it with one single gst-launch run.

How do I use gstreamer to encode an ffv1 file?

I'd like to encode a video with gstreamer to an FFV1 (ffmpeg's lossless video format) file. However, I cannot work out what type of mux'ing to use. If I run this:
gst-launch videotestsrc ! ffenc_ffv1 ! filesink location="test.ffv1"
Then the thing runs OK, but the resulting file doesn't appear to be a valid video file. When creating theora videos, I've previously written "theora ! oggmux ! filesink" in the pipeline, and this works. However, oggmux doesn't work here. What type of transport stream should I be using here, and what is the correct gst-launch fudge to use?
Cheers.
This does not seem to be supported in the version I have installed. You can check it for your version by saving the output of gst-xmlinspect to a file and searching for video/x-ffv in this file. The elements where this mime type is mentioned are:
avidemux
ogmvideoparse
ffdec_ffv1
ffenc_ffv1
So it seems this is supported by the avi demuxer but not by any muxer.
PS: The mime type can be found with gst-inspect ffenc_ffv1.