gstreamer find out decoding bit rate - gstreamer

The function query_position(gst.FORMAT_BYTES, None)[0] returns me the no. of bytes in the pipeline after gstreamer has decoded the video/audio. I want to know the no. of bytes of the source file that were consumed to decode till this point of time. Is there a function in gstreamer API to do this?

Please read the seeking chapter from pygst docs. You can replace pos_int = self.player.query_position(gst.FORMAT_TIME, None)[0] with your version to get the bytes in real time. They are using thread object.
You can also add the timeout method. In Python its gobject.timeout_add(interval, callback, ...)

I have received the download data size in souphttpsrc source using onGotChunk event. This onGotChunk is MPEGDASH specific patch for souphttpsrc element.
In general
gboolean gst_element_query_duration (GstElement *element, GstFormat format, gint64 *duration); this API can be used. Pass source element as a 1st argument to this function and check.

Related

Drop buffers in gstreamer

I am developing a gstreamer application (plugin) that sinks from a video stream, analyzes each buffer for a certain condition and then if that condition is present passes the buffer to the plugin source. If the condition is not present for a given buffer, the buffer should be dropped and the plugin source should not receive this buffer.
Upon looking through the gstreamer documentation and tutorials as a newcomer to gstreamer, I cannot find a way for my plugin to "drop" a buffer.
Try using GstProbe for data buffers and return GST_PAD_PROBE_DROP or GST_PAD_PROBE_HANDLED when yours conditions are met.
If your plugin is based on GstBaseTransform, you should implement your own transform_frame_ip or transform_frame. If so, you can return GST_BASE_TRANSFORM_FLOW_DROPPED:
/**
* GST_BASE_TRANSFORM_FLOW_DROPPED:
*
* A #GstFlowReturn that can be returned from transform and transform_ip to
* indicate that no output buffer was generated.
*/
#define GST_BASE_TRANSFORM_FLOW_DROPPED GST_FLOW_CUSTOM_SUCCESS

How to write ROS AudioData message into wav file?

I'm using ReSpeaker Mic Array v2.0 on my robot, I used the following git repo: https://github.com/furushchev/respeaker_ros.git to capture the audio received by the speaker. I subscribed to it's raw audio ros topic /audio which is just byte array data(http://docs.ros.org/noetic/api/audio_common_msgs/html/msg/AudioData.html)
How can I write the AudioData message's uint8[] data into a wav file in C++? I would like to play the wav file by other means afterwards.
I saw that in ros audio_common library example it uses gstreamer to do the writing, but I'm quite confused after reading the code(https://github.com/ros-drivers/audio_common/blob/master/audio_capture/src/audio_capture.cpp)
Example that you saw is using Gstremaer's alsasrc to capture audio from mic in this line
_source = gst_element_factory_make("alsasrc", "source");
So Gstreamer's pipeline is internally handling/capturing audio byte array and, in case of input parameters dst_type=="filesink" and format=="wave", encoding it with
_filter = gst_element_factory_make("wavenc", "filter");
and creating .wav file with
_sink = gst_element_factory_make("filesink", "sink");
On the other hand, running that code with input parameters dst_type=="appsink" and format=="wave" actually captures audio bytes again but, instead of writing to file, publishes them on ros topic /audio.
If you cannot (from any reason) use this code with input parameters dst_type=="filesink" and format=="wave", I suppose you will need to use Gstreamer's appsrc element and feed it with bytes from your AudioData message. In that case, the rest of Gstreamer pipeline for encoding and writing to file should remain the same as in the example.

How can I hand over CD audio data read by cdparanoia to the ALSA player?

I'm trying to playback an audio CD by using cd_paranoia (from the cdio package) and to hand over the data read to the ALSA sound output. Buffered, of course. My issue is now the following: As stated in this example program, a call to paranoia_read () returns an int16_t* containing one sector (2,352 bytes) of audio data, which can be then cast into a char*.
The ALSA snd_pcm_writei () method, on the other hand needs a chunk of audio data in a char*, whose length is to be determined by using the snd_pcm_hw_params_get_period_size () method, which basically returns the count of bytes sent to the sound device, until it triggers an interrupt. Sell also this example sourcecode.
The two methods will almost for sure return different values 'cause an ALSA frame has a different size than a CD sector. This would mean I'd have to divide the data cd-paranoia delivers me somehow, so that they will fit into ALSA's frame structure. Or would it be sufficient just to stream the CD audio data into a big byte array (std::queue<char>) and then, step by step, read as many bytes from this array, so that I will get a complete ALSA "frame"?
Any hints? Thank you.
snd_pcm_writei() handles any number of frames.

How to use properties on gstreamer

I am new using g streamer, and i try to use the emit-stats properties in tsdemux
How can I do to use this in my pipeline?
I'm trying to get the program clock reference value of a signal transport stream but no way to get it.
Properties in GStreamer are normally accessed by using the normal GLib APIs : g_object_set and g_object_get. Doing g_object_set (v1_demux, "emit-stats", TRUE, NULL);, supposing that v1_demux is a GstTSDemux*, will start emitting messages containing the PTS and DTS of the packets that flow into the demuxer.
Element messages in GStreamer are emitted by gst_element_post_message. In order to receive them in your application, it needs to set up a bus watch on the main pipeline's GstBus.
Just for the record, you can test how the property works and see the content of the messages by running this example pipeline in gst-launch :
gst-launch-1.0 -m filesrc location="$YOUR_TRANSPORT_STREAM" ! tsdemux emit-stats=1 ! fakesink
Running this with one of the transport streams on my HDD, I can see messages with the PTS and DTS being emitted from the demuxer element :
Got message #77 from element "tsdemux0" (element): tsdemux, pid=(uint)1803, offset=(guint64)266020, pts=(guint64)8429319339;
Got message #78 from element "tsdemux0" (element): tsdemux, pid=(uint)1805, offset=(guint64)273540, pts=(guint64)8429311261;
Got message #79 from element "tsdemux0" (element): tsdemux, pid=(uint)1802, offset=(guint64)282564, dts=(guint64)8429444461;
However, it doesn't look like PCR and OPCR values are emitted. You'll have to add this functionality yourself.
Thanks for the info.
was test commands and see the script and check the values, but is costing me add messages emit-stats in my line.
If I created a bus watch on the main pipeline's GstBus,to see the video duration and as playtime in my line, but can not see messages stats and video simultaneously. I still investigating comohacerlo as storing information pts and dts in some way.
My idea is get stamps of two videos and subtract this to calculate an automatic offset in one video.

FFMPEG reading keyframes

I am trying to write a c++ program that would read key frames from the video file using ffmpeg.
So far I managed to get all the frames using av_read_frame where you sequentially read
frame by frame.
But I having some problems using av_seek_frame which (if I am correct) supposed to do the trick for keyframes.
int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags);
I have FormatContext but what are other correct arguments to sequentially get only all keyframes ?
Is there other function that I can use instead?
Thanks
EDIT: In av_read_frame i am getting AVPacket, which I can use to get frame data, but how I can get packet by using av_seek_frame ?
SOLUTION: OK there is a simple boolean value in AVFrame->key_frame. True if its a keyframe
av_seek_frame has the ability to seek to a certain timestamp in a video file. It takes 4 parameters: a pointer to the AVFormatContext, a stream index, the timestamp to seek to and flags to select the direction and seeking mode.
The function will then seek to the first key frame before the given timestamp.
Check the documentation of that function for more information.