使用本地 ipv6 的 gstreamer 传输视频时出现问题

问题描述 投票:0回答:0

我目前正在尝试使用 ipv6 通过本地网络使用 gstreamer 传输视频。这就是我的管道的样子:

void TransmiterVideo::addLinkVideo() {
    GstElement *ximagesrc, *videoscale, *videoconvert, *x264enc, *h264parse, *rtph264pay, *udpsink1, *capsfilter1, *capsfilter2;
    GstCaps *caps1, *caps2;
    if (data.pipeline == NULL) {
        data.pipeline = gst_pipeline_new("pipeline");
    }
    ximagesrc = gst_element_factory_make("ximagesrc", "ximagesrc");
    capsfilter1 = gst_element_factory_make("capsfilter", "capsfilter1");
    videoscale = gst_element_factory_make("videoscale", "videoscale");
    videoconvert = gst_element_factory_make("videoconvert", "videoconvert");
    x264enc = gst_element_factory_make("x264enc", "x264enc");
    capsfilter2 = gst_element_factory_make("capsfilter", "capsfilter2");
    h264parse = gst_element_factory_make("h264parse", "h264parse");
    rtph264pay = gst_element_factory_make("rtph264pay", "rtph264pay");
    udpsink1 = gst_element_factory_make("udpsink", "udpsink1");

    if (!data.pipeline || !h264parse || !ximagesrc || !capsfilter1 || !capsfilter2 || !videoscale || !videoconvert || !x264enc ||
        !rtph264pay || !udpsink1) {
        g_printerr("Not all elements could be created\n");
        return;
    }

    caps1 = gst_caps_new_simple("video/x-raw", "framerate", GST_TYPE_FRACTION, 30, 1,

                                NULL);

    caps2 =
        gst_caps_new_simple("video/x-h264", "profile", G_TYPE_STRING, "main", "width", G_TYPE_INT, 1024, "height", G_TYPE_INT, 600, NULL);

    g_object_set(G_OBJECT(capsfilter1), "caps", caps1, NULL);
    g_object_set(G_OBJECT(capsfilter2), "caps", caps2, NULL);

    gst_caps_unref(caps1);
    gst_caps_unref(caps2);

    gst_bin_add_many(GST_BIN(data.pipeline), ximagesrc, capsfilter1, videoscale, videoconvert, x264enc, capsfilter2, h264parse, rtph264pay,
                     udpsink1, NULL);

    if (gst_element_link_many(ximagesrc, capsfilter1, videoscale, videoconvert, x264enc, capsfilter2, h264parse, rtph264pay, udpsink1,
                              NULL) != TRUE) {
        g_printerr(
            "Failed to link elements: ximagesrc -> videoscale -> videoconvert -> x264enc -> "
            "rtph264pay -> udpsink1\n");
        gst_object_unref(data.pipeline);
        return;
    }

    g_object_set(udpsink1, "sync", FALSE, "host", processIPv6(local_ip6).toStdString().c_str(), "port", video_port, NULL);
    g_object_set(x264enc, "pass", 17, "tune", 4, "bitrate", 2200, NULL);
}


void TransmiterVideo::addLinkAudio() {
    GstElement *alsasrc, *audioconvert, *audioresample, *opusenc, *rtpopuspay, *udpsink2;
    if (data.pipeline == NULL) {
        data.pipeline = gst_pipeline_new("pipeline");
    }

    alsasrc = gst_element_factory_make("alsasrc", "alsasrc");
    audioconvert = gst_element_factory_make("audioconvert", "audioconvert");
    audioresample = gst_element_factory_make("audioresample", "audioresample");
    opusenc = gst_element_factory_make("opusenc", "opusenc");
    rtpopuspay = gst_element_factory_make("rtpopuspay", "rtpopuspay");
    udpsink2 = gst_element_factory_make("udpsink", "udpsink2");

    if (!data.pipeline || !alsasrc || !audioconvert || !audioresample || !opusenc || !rtpopuspay || !udpsink2) {
        g_printerr("Not all elements could be created\n");
        return;
    }

    gst_bin_add_many(GST_BIN(data.pipeline), alsasrc, audioconvert, audioresample, opusenc, rtpopuspay, udpsink2, NULL);

    if (gst_element_link_many(alsasrc, audioconvert, audioresample, opusenc, rtpopuspay, udpsink2, NULL) != TRUE) {
        g_printerr(
            "Failed to link elements: ximagesrc -> videoscale -> videoconvert -> x264enc -> "
            "rtph264pay -> udpsink1\n");
        gst_object_unref(data.pipeline);
        return;
    }

    g_object_set(udpsink2, "sync", FALSE, "host", processIPv6(local_ip6).toStdString().c_str(), "port", audio_port, NULL);
}


void TransmiterVideo::onStartSession() {
    qDebug() << "Starting video transmition";
    gst_init(nullptr, nullptr);
    addLinkVideo();
    addLinkAudio();
    startSend();
}
void ReciverVideo::addLinkVideo() {
    GstElement *udpsrc1, *queue1, *capsfilter1, *depay1, *parse1, *decode1, *convert1, *autovideosink1;
    GstCaps* caps1;
    if (data.pipeline == NULL) {
        data.pipeline = gst_pipeline_new("pipeline");
    }
    udpsrc1 = gst_element_factory_make("udpsrc", "udpsrc1");
    queue1 = gst_element_factory_make("queue", "buffer1");
    capsfilter1 = gst_element_factory_make("capsfilter", "capsfilter1");
    depay1 = gst_element_factory_make("rtph264depay", "depay1");
    parse1 = gst_element_factory_make("h264parse", "parse1");
    decode1 = gst_element_factory_make("avdec_h264", "decode1");
    convert1 = gst_element_factory_make("videoconvert", "convert1");
    autovideosink1 = gst_element_factory_make("autovideosink", "autovideosink1");

    if (!data.pipeline || !udpsrc1 || !depay1 || !parse1 || !decode1 || !convert1 || !autovideosink1 || !capsfilter1 || !queue1) {
        g_printerr("Not all elements could be created. Exiting.\n");
        return;
    }

    caps1 = gst_caps_new_simple("application/x-rtp", "media", G_TYPE_STRING, "video", "clock-rate", G_TYPE_INT, 90000, "encoding-name",
                                G_TYPE_STRING, "H264", "payload", G_TYPE_INT, 96, NULL);

    g_object_set(G_OBJECT(capsfilter1), "caps", caps1, NULL);

    gst_caps_unref(caps1);

    gst_bin_add_many(GST_BIN(data.pipeline), udpsrc1, queue1, capsfilter1, depay1, parse1, decode1, convert1, autovideosink1, NULL);

    if (!gst_element_link_many(udpsrc1, queue1, capsfilter1, depay1, parse1, decode1, convert1, autovideosink1, NULL)) {
        g_printerr("Could not link all elements. Exiting.\n");
        return;
    }

    g_object_set(udpsrc1, "port", video_port, NULL);
}


void ReciverVideo::addLinkAudio() {
    GstElement *udpsrc2, *depay2, *parse2, *decode2, *convert2, *autovideosink2, *audioresample, *capsfilter2, *queue2;
    GstCaps* caps2;
    if (data.pipeline == NULL) {
        data.pipeline = gst_pipeline_new("pipeline");
    }
    udpsrc2 = gst_element_factory_make("udpsrc", "udpsrc2");
    queue2 = gst_element_factory_make("queue", "buffer2");
    capsfilter2 = gst_element_factory_make("capsfilter", "capsfilter2");
    depay2 = gst_element_factory_make("rtpopusdepay", "depay2");
    parse2 = gst_element_factory_make("opusparse", "parse2");
    decode2 = gst_element_factory_make("avdec_opus", "decode2");
    convert2 = gst_element_factory_make("audioconvert", "convert2");
    audioresample = gst_element_factory_make("audioresample", "audioresample");
    autovideosink2 = gst_element_factory_make("autoaudiosink", "autovideosink2");

    if (!data.pipeline || !udpsrc2 || !depay2 || !parse2 || !decode2 || !convert2 || !autovideosink2 || !audioresample || !capsfilter2 ||
        !queue2) {
        g_printerr("Not all elements could be created. Exiting.\n");
        return;
    }

    caps2 = gst_caps_new_simple("application/x-rtp", "media", G_TYPE_STRING, "audio", "clock-rate", G_TYPE_INT, 48000, "encoding-name",
                                G_TYPE_STRING, "OPUS", "payload", G_TYPE_INT, 96, NULL);

    g_object_set(G_OBJECT(capsfilter2), "caps", caps2, NULL);

    gst_caps_unref(caps2);

    gst_bin_add_many(GST_BIN(data.pipeline), udpsrc2, queue2, capsfilter2, depay2, parse2, decode2, convert2, audioresample, autovideosink2,
                     NULL);

    if (!gst_element_link_many(udpsrc2, queue2, capsfilter2, depay2, parse2, decode2, convert2, audioresample, autovideosink2, NULL)) {
        g_printerr("Could not link all elements. Exiting.\n");
        return;
    }
    g_object_set(udpsrc2, "port", audio_port, NULL);
}


void ReciverVideo::onStartSession() {
    qDebug() << "Starting video receiver";
    gst_init(0, nullptr);
    addLinkVideo();
    addLinkAudio();
    startReceive();
}

IPv4 工作正常。如果我在接收器中指定它,还有“::1”。但 “fe80::aaaa:bbbb:cccc:dddd%enp0s3”地址就是懒得开始工作了。

到目前为止,我已经花了很多时间来解决这个问题。尝试查看 gstreamer 日志消息,重写我的代码几次并将我的地址翻译成许多表示形式,但目前所有这些都是徒劳的。 可能相关的主题: GStreamer udpsink 与 ipv6 主机不工作

c++ ip gstreamer ipv6
© www.soinside.com 2019 - 2024. All rights reserved.