在WebRTCbin中启用RED音频功能的技术问题求助
GStreamer应答方启用RED冗余编码问题
我用C++构建了GStreamer管道,负责接收SDP Offer并回复应答。仅使用OPUS时功能正常,但音频质量偶尔不佳,因此尝试启用RED(冗余编码),但遇到了问题。找到过发起Offer时启用RED的实现方式,但我作为应答方,该方法不适用。
代码片段:通用OPUS配置
以下是核心管道构建逻辑:
GstElement * _audio_depay = gst_element_factory_make("rtpopusdepay", "webrtcaudiodepay"); GstElement * _audio_dec = gst_element_factory_make("opusdec", "audiodecode"); GstElement * _audio_converter_caps = gst_caps_new_simple("audio/x-raw", "format", G_TYPE_STRING, "S16LE", "layout", G_TYPE_STRING, "interleaved", NULL); std::stringstream ss; ss << "webrtcbin name=webrtcbin " << "appsrc name=webrtcaudioappsrc ! audioconvert ! audioresample ! audiorate ! " << "opusenc inband-fec=true audio-type=restricted-lowdelay bitrate-type=cbr packet-loss-percentage=100 bandwidth=1102 dtx=true ! rtpopuspay dtx=true pt=111 ! " << "application/x-rtp,media=audio,encoding-name=OPUS,payload=111 ! webrtcbin. "; GError * error = nullptr; _pipeline = gst_parse_launch(ss.str().c_str(), &error); GstElement * _webrtc = gst_bin_get_by_name(GST_BIN(_pipeline), "webrtcbin");
监听_webrtcbin的pad-added信号后,手动链接形成如下管道:
webrtcbin -> rtpopusdepay -> opusdec -> audioconvert -> appsink
尝试启用RED
浏览器发来的SDP Offer包含RED条目(精简后内容):
m=audio 9 UDP/TLS/RTP/SAVPF 111 63 9 102 0 8 13 110 126 ... a=rtpmap:111 opus/48000/2 a=rtcp-fb:111 transport-cc a=fmtp:111 minptime=10;useinbandfec=1 a=rtpmap:63 red/48000/2 a=fmtp:63 111/111 ...
我尝试修改该Offer,将63移至m行的111之前,再提交给webrtcbin生成应答:
GstSDPMessage * sdp = nullptr; gst_sdp_message_new_from_text(sdp_data.c_str(), &sdp); // sdp_data是修改后的浏览器发送字符串 GstWebRTCSessionDescription * offer = nullptr; offer = gst_webrtc_session_description_new(GST_WEBRTC_SDP_TYPE_OFFER, sdp); auto promise = gst_promise_new(); g_signal_emit_by_name(_webrtc, "set-remote-description", offer, promise); gst_promise_wait(promise); gst_webrtc_session_description_free(offer); gst_promise_unref(promise); promise = gst_promise_new_with_change_func(on_answer, this, NULL); g_signal_emit_by_name(_webrtc, "create-answer", NULL, promise);
但生成的应答仍默认使用OPUS(111)。推测可能是webrtcbin依赖rtpmap排序,更可能是因为webrtcbin已链接OPUS相关元素,导致必须使用OPUS。
我尝试手动添加元素,构建如下管道:
appsrc -> opusenc -> rtpopuspay -> rtpulpfecenc -> rtpredenc -> webrtcbin webrtcbin -> rtpreddec -> rtpstorage -> rtpssrcdemux -> rtpjitterbuffer -> rtpulpfecdec -> rtpopusdepay -> opusdec -> audioconvert -> appsink
运行时出现警告,提示生成的元素仅支持接收:
0:00:13.919634921 41106 0x7756b8004940 WARN webrtcbin gstwebrtcbin.c:4636:_create_answer_task:<webrtcbin> did not find compatible transceiver for offer caps application/x-rtp, media=(string)audio, payload=(int)63, clock-rate=(int)48000, encoding-name=(string)RED, encoding-params=(string)2, 111/111=(string)1; application/x-rtp, media=(string)audio, payload=(int)111, clock-rate=(int)48000, encoding-name=(string)OPUS, encoding-params=(string)2, minptime=(string)10, useinbandfec=(string)1, rtcp-fb-transport-cc=(boolean)true; application/x-rtp, media=(string)audio, payload=(int)9, clock-rate=(int)8000, encoding-name=(string)G722; application/x-rtp, media=(string)audio, payload=(int)0, clock-rate=(int)8000, encoding-name=(string)PCMU; application/x-rtp, media=(string)audio, payload=(int)8, clock-rate=(int)8000, encoding-name=(string)PCMA; application/x-rtp, media=(string)audio, payload=(int)13, clock-rate=(int)8000, encoding-name=(string)CN; application/x-rtp, media=(string)audio, payload=(int)110, clock-rate=(int)48000, encoding-name=(string)TELEPHONE-EVENT; application/x-rtp, media=(string)audio, payload=(int)126, clock-rate=(int)8000, encoding-name=(string)TELEPHONE-EVENT, will only receive
令人困扰的是,生成的管道dot文件显示webrtcbin已包含RED编解码器,我希望直接使用这些内置组件,但不知如何启用。
更新内容
唯一能让应答将RED置于OPUS之前的方法是完全移除m行中的OPUS。
之后尝试调用get-transceivers时,发现kind属性设置过晚:
- 若将所有收发器设置为
fec-type=GST_WEBRTC_FEC_TYPE_ULP_RED且do-nack=true,随后尽快恢复视频收发器设置(在设置ICE候选阶段),会添加视频pad但出现协商失败错误; - 若不对收发器做任何操作,或在获取到kind后立即设置音频收发器,视频可正常传输,但仍无音频pad添加,且出现“未设置远端描述就创建应答”的警告。
内容的提问来源于stack exchange,提问作者Gemms
相关产品推荐
相关产品推荐

