Hey I am working on a player using gstreamer, this is my setupgstreamer:
void mainWindow::setupGStreamer(QString authUri) {
gst_init(nullptr, nullptr);
pipeline = gst_pipeline_new("http-player");
source = gst_element_factory_make("souphttpsrc", "http-source");
GstElement *decodebin = gst_element_factory_make("decodebin", "decodebin");
convert = gst_element_factory_make("videoconvert", "converter");
crop = gst_element_factory_make("videocrop", "videocrop");
scale = gst_element_factory_make("videoscale", "videoscale");
sink = gst_element_factory_make("glimagesink", "video-output");
GstElement *capsfilter = gst_element_factory_make("capsfilter", "capsfilter");
videorate = gst_element_factory_make("videorate", "videorate");
if (!pipeline || !source || !decodebin || !convert || !crop || !scale || !sink || !capsfilter || !videorate) {
g_error("Failed to create elements");
}
// Set capsfilter to enforce raw video format
GstCaps *caps = gst_caps_from_string("video/x-raw");
if (!caps) {
g_error("Failed to create caps");
}
g_object_set(capsfilter, "caps", caps, nullptr);
gst_caps_unref(caps);
g_object_set(videorate, "max-rate", 30, nullptr);
gst_bin_add_many(GST_BIN(pipeline), source, decodebin, videorate, convert, capsfilter, crop, scale, sink, nullptr);
g_signal_connect(decodebin, "pad-added", G_CALLBACK(on_pad_added), convert);
// Link the elements with capsfilter and videorate included
if (!gst_element_link_many(convert, capsfilter, videorate, crop, scale, sink, nullptr)) {
g_error("Failed to link elements");
g_error("Failed to link elements");
}
qDebug() << "URI: " << authUri;
g_object_set(source, "location", authUri.toStdString().c_str(), nullptr);
// Link the source to the decodebin
if (!gst_element_link(source, decodebin)) {
g_error("Failed to link source to decodebin");
}
WId xwinid = videoWidget->winId();
gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(sink), xwinid);
// Query the frame rate from the decoder
GstPad *pad = gst_element_get_static_pad(convert, "sink");
if (pad) {
caps = gst_pad_get_current_caps(pad);
if (caps) {
const GstStructure *str = gst_caps_get_structure(caps, 0);
if (gst_structure_get_fraction(str, "framerate", &fps_numerator, &fps_denominator)) {
fps = static_cast<double>(fps_numerator) / fps_denominator;
}
gst_caps_unref(caps);
}
gst_object_unref(pad);
}
}
That being said I change my videorate using this:
void mainWindow::handleSpeed(){
gst_element_set_state(pipeline, GST_STATE_PAUSED);
if(speed == 1.0){
speed = 0.5;
g_object_set(videorate, "rate", 0.5, nullptr);
speedButton->setText("Speed: 0.5");
} else if(speed == 0.5){
g_object_set(videorate, "rate", 0.25, nullptr);
speed = 0.25;
speedButton->setText("Speed: 0.25");
} else {
g_object_set(videorate, "rate", 1, nullptr);
speed = 1.0;
speedButton->setText("Speed: 1.0");
}
gst_element_set_state(pipeline, GST_STATE_PLAYING);
}
Changing for the first time from 1.0 to 0.5 works fine anything after that just simply either skips frames or stops playing and i have to restart pipeline