Search code examples
c++streaminggstreamerrtsp

Why gstreamer gives rtsp Invalid URI error?


I have been trying to write a rtsp player with gstreamer. I am working with Windows 10 pc.

I want this player support reverse playback. When I started writing the code, the gstreamer version was 1.14.5. However in this version I found out that rtspsrc does not support reverse playback and this feature comes in version 1.15.2. When I wrote the code, all features(start, pause, stop, fast-forward) were working except reverse playback.

However, when I switched to version 1.15.2, I started getting an "Invalid URI" error and does not even try to send a request(I checked with wireshark). Everywhere I checked it says to close the proxy but I turned off the proxy from Windows settings and it still does not work.

Initialize gstreamer.

IGSPlayer::GSPlayer_ERROR Player::initialize_player(int argc, char* argv[]) {
gst_init(&argc,&argv);
GstElement *rtspsrc_element, *rtph264depay_element, *h264parse_element, *avdec_h264_element, *videoconvert_element, *glimagesink_element;
rtspsrc_element = gst_element_factory_make("rtspsrc", "rtspsrc");
if (!rtspsrc_element) {
    std::cout << "Unable to create rtspsrc!" << std::endl;
    return IGSPlayer::CREATE_ELEMENT_ERROR_RTSPSRC;
}
rtph264depay_element = gst_element_factory_make("rtph264depay", "rtph264depay");
if (!rtph264depay_element) {
    std::cout << "Unable to create rtph264depay_element!" << std::endl;
    return IGSPlayer::CREATE_ELEMENT_ERROR_DEPAY;
}
h264parse_element = gst_element_factory_make("h264parse", "h264parse");
if (!h264parse_element) {
    std::cout << "Unable to create h264parse_element!" << std::endl;
    return IGSPlayer::CREATE_ELEMENT_ERROR_PARSE;
}
avdec_h264_element = gst_element_factory_make("avdec_h264", "avdec_h264");
if (!avdec_h264_element) {
    std::cout << "Unable to create avdec_h264_element!" << std::endl;
    return IGSPlayer::CREATE_ELEMENT_ERROR_AVDEC;
}
videoconvert_element = gst_element_factory_make("videoconvert", "videoconvert");
if (!videoconvert_element) {
    std::cout << "Unable to create vidoeconvert_element!" << std::endl;
    return IGSPlayer::CREATE_ELEMENT_ERROR_CONVERT;
}
glimagesink_element = gst_element_factory_make("glimagesink", "glimagesink");
if (!glimagesink_element) {
    std::cout << "Unable to create glimagesink_element!" << std::endl;
    return IGSPlayer::CREATE_ELEMENT_ERROR_SINK;
}

setLoop(g_main_loop_new(NULL, FALSE));

g_object_set(rtspsrc_element, "location", get_rtsp_uri().c_str(), NULL);
g_object_set(rtspsrc_element, "latency", 0, NULL);

setVideoSink(glimagesink_element);

setPipeline(gst_pipeline_new("rtsp-pipeline"));
if (!getPipeline()) {
    std::cerr << "pipeline could not be created!" << std::endl;
    return IGSPlayer::CREATE_PIPELINE_ERROR;
}

setBus(gst_pipeline_get_bus(GST_PIPELINE(getPipeline())));
gst_bus_add_watch(getBus(), bus_call, this);
gst_object_unref(getBus());

gst_bin_add_many(GST_BIN(getPipeline()), rtspsrc_element, rtph264depay_element, NULL);
g_signal_connect(rtspsrc_element, "pad-added", G_CALLBACK(new_rtspsrc_pad), rtph264depay_element);
gst_bin_add_many(GST_BIN(getPipeline()), h264parse_element, NULL);
if (!gst_element_link(rtph264depay_element, h264parse_element)) {
    std::cout << "rtph264depay -> h264parse not be linked!" << std::endl;
    gst_object_unref(getPipeline());
    return IGSPlayer::LINKED_ERROR;
}
gst_bin_add_many(GST_BIN(getPipeline()), avdec_h264_element, videoconvert_element, glimagesink_element, NULL);

/* link the elements together */
if (!gst_element_link_many(h264parse_element, avdec_h264_element, videoconvert_element, glimagesink_element, NULL)) {
    std::cerr << "Elements could not be linked!" << std::endl;
    gst_object_unref(getPipeline());
    return IGSPlayer::LINKED_ERROR;
}

gst_video_overlay_set_window_handle(GST_VIDEO_OVERLAY(glimagesink_element), (guintptr) get_window_id());

setEndOfStream(false);
return IGSPlayer::SUCCESS;}

And play.

IGSPlayer::GSPlayer_ERROR Player::play_stream() {
    GstStateChangeReturn ret = gst_element_set_state(getPipeline(), GST_STATE_PLAYING);
    if (ret == GST_STATE_CHANGE_FAILURE) {
        gst_element_set_state(getPipeline(), GST_STATE_NULL);
        gst_object_unref(GST_OBJECT(getPipeline()));
        return IGSPlayer::GSPlayer_ERROR::STATE_CHANGE_ERROR;
    }
    setPlaying(TRUE);
    setRate(1.0);

    g_main_loop_run(getLoop());

    return IGSPlayer::SUCCESS;}

And also I tried on windows powershell with gst-launch-1.0 but it's does not working either. I would love to hear any ideas why this is not working.


Solution

  • Okey I found the solution. I was using the non-English language option on windows. The problem was solved when I made the language option in English.