mavlink / qgroundcontrol

Cross-platform ground control station for drones (Android, iOS, Mac OS, Linux, Windows)
http://qgroundcontrol.io
3.31k stars 3.63k forks source link

RTSP TCP / RTSPT Not Support, from Incorrect URL validation. ( Instructions how to fix ) #10402

Open AndreySkyFoxSidorov opened 2 years ago

AndreySkyFoxSidorov commented 2 years ago

RTSP TCP Not Support from Incorrect URL validation. I managed to fix it: need replace https://github.com/mavlink/qgroundcontrol/blob/bafd59242ede75d82d53b7fd947398db9982ed27/src/VideoReceiver/GstVideoReceiver.cc#L696 bool isRtsp = uri.contains("rtsp://", Qt::CaseInsensitive); To bool isRtsp = uri.contains("rtsp://", Qt::CaseInsensitive) || uri.contains("rtspt://", Qt::CaseInsensitive);

The problem of video squares glith on TCP camera( SIYI ZR 10, SIYI mini and others ) can be solved by adding filters in GstVideoReceiver.cc:

` gboolean GstVideoReceiver::_filterParserCaps(GstElement bin, GstPad pad, GstElement element, GstQuery query, gpointer data) { Q_UNUSED(bin) Q_UNUSED(pad) Q_UNUSED(element) Q_UNUSED(data)

if (GST_QUERY_TYPE(query) != GST_QUERY_CAPS) {
    return FALSE;
}

GstCaps* srcCaps;

gst_query_parse_caps(query, &srcCaps);

if (srcCaps == nullptr || gst_caps_is_any(srcCaps)) {
    return FALSE;
}

GstCaps* sinkCaps = nullptr;

GstCaps* filter;

if (sinkCaps == nullptr && (filter = gst_caps_from_string("video/x-h264")) != nullptr) {
    if (gst_caps_can_intersect(srcCaps, filter)) {
        sinkCaps = gst_caps_from_string("video/x-h264,stream-format=avc");
    }

    gst_caps_unref(filter);
    filter = nullptr;
} else if (sinkCaps == nullptr && (filter = gst_caps_from_string("video/x-h265")) != nullptr) {
    if (gst_caps_can_intersect(srcCaps, filter)) {
        sinkCaps = gst_caps_from_string("video/x-h265,stream-format=hvc1");
    }

    gst_caps_unref(filter);
    filter = nullptr;
}

if (sinkCaps == nullptr) {
    return FALSE;
}

gst_query_set_caps_result(query, sinkCaps);

gst_caps_unref(sinkCaps);
sinkCaps = nullptr;

return TRUE;

}

gboolean GstVideoReceiver::_autoplugQueryCaps(GstElement bin, GstPad pad, GstElement element, GstQuery query, gpointer data) { Q_UNUSED(bin) Q_UNUSED(pad) Q_UNUSED(element)

GstElement* glupload = (GstElement* )data;

GstPad* sinkpad;

if ((sinkpad = gst_element_get_static_pad(glupload, "sink")) == nullptr) {
    qCCritical(VideoReceiverLog) << "No sink pad found";
    return FALSE;
}

GstCaps* filter;

gst_query_parse_caps(query, &filter);

GstCaps* sinkcaps = gst_pad_query_caps(sinkpad, filter);

gst_query_set_caps_result(query, sinkcaps);

const gboolean ret = !gst_caps_is_empty(sinkcaps);

gst_caps_unref(sinkcaps);
sinkcaps = nullptr;

gst_object_unref(sinkpad);
sinkpad = nullptr;

return ret;

}

gboolean GstVideoReceiver::_autoplugQueryContext(GstElement bin, GstPad pad, GstElement element, GstQuery query, gpointer data) { Q_UNUSED(bin) Q_UNUSED(pad) Q_UNUSED(element)

GstElement* glsink = (GstElement* )data;

GstPad* sinkpad;

if ((sinkpad = gst_element_get_static_pad(glsink, "sink")) == nullptr){
    qCCritical(VideoReceiverLog) << "No sink pad found";
    return FALSE;
}

const gboolean ret = gst_pad_query(sinkpad, query);

gst_object_unref(sinkpad);
sinkpad = nullptr;

return ret;

}

gboolean GstVideoReceiver::_autoplugQuery(GstElement bin, GstPad pad, GstElement element, GstQuery query, gpointer data) { gboolean ret;

switch (GST_QUERY_TYPE(query)) {
case GST_QUERY_CAPS:
    ret = _autoplugQueryCaps(bin, pad, element, query, data);
    break;
case GST_QUERY_CONTEXT:
    ret = _autoplugQueryContext(bin, pad, element, query, data);
    break;
default:
    ret = FALSE;
    break;
}

return ret;

}

`

The filter initialization moment needs add in the method GstVideoReceiver::_makeDecoder(GstCaps caps, GstElement videoSink) g_signal_connect(decoder, "autoplug-query", G_CALLBACK(_autoplugQuery), videoSink); image

and method GstVideoReceiver::_makeSource(const QString& uri) g_signal_connect(parser, "autoplug-query", G_CALLBACK(_filterParserCaps), nullptr); image

fredowski commented 2 years ago

Hi @AndreySkyFoxSidorov : Is the change that you propose maybe the one from @andrewvoznytsa that I have in PR #10396? I would be much easier if your change proposals are made via a Pull Request, because then it is much easier to check and compare.

AndreySkyFoxSidorov commented 2 years ago

Hi @AndreySkyFoxSidorov : Is the change that you propose maybe the one from @andrewvoznytsa that I have in PR #10396? I would be much easier if your change proposals are made via a Pull Request, because then it is much easier to check and compare.

No, I solved a slightly different problem. But I'm sure that I had a problem in checking the URL. I will attach my version of the modified files, if you want you can merge them. https://gist.github.com/AndreySkyFoxSidorov/637c8cd837594046ceadfbfe729ea206