我目前正在尝试使用 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 主机不工作