簡體   English   中英

無法在華為設備上為 H264 編碼視頻設置遠程 SDP 報價

[英]Unable to set remote SDP offer for H264 encoded video on Huawei devices

I'm developing a WebRTC video call app (one-way video and two-way audio) for Android with prebuilt package org.webrtc:google-webrtc:1.0.32006 . 我遇到了這個庫中的一個錯誤,該錯誤指出:

LS_ERROR
tag: webrtc_video_engine.cc 
message: (line 745): No video codecs supported.

嘗試設置遠程 SDP 報價后:

v=0
o=- 955391267744368972 0 IN IP4 0.0.0.0
s=-
t=0 0
a=ice-options:trickle
a=group:BUNDLE video0 audio1 application2
m=video 9 UDP/TLS/RTP/SAVPF 96
c=IN IP4 0.0.0.0
a=setup:actpass
a=ice-ufrag:NwMv07hmtKD9s8EFikQCvqv7JvMpVhv4
a=ice-pwd:[xxx]
a=rtcp-mux
a=rtcp-rsize
a=sendrecv
a=rtpmap:96 H264/90000
a=rtcp-fb:96 nack pli
a=framerate:30
a=fmtp:96 packetization-mode=1;profile-level-id=42c01f;sprop-parameter-sets=J0LAH5WgKA9oQAAAAwBAAAAPOSAACYlgABqz+97gHiRNQA==,KM4fIA==
a=ssrc:2596331602 msid:user823769301@host-4c0ea8a4 webrtctransceiver0
a=ssrc:2596331602 cname:user823769301@host-4c0ea8a4
a=mid:video0
a=fingerprint:sha-256 [xxx]
m=audio 0 UDP/TLS/RTP/SAVPF 97
c=IN IP4 0.0.0.0
a=setup:actpass
a=ice-ufrag:NwMv07hmtKD9s8EFikQCvqv7JvMpVhv4
a=ice-pwd:[xxx]
a=bundle-only
a=rtcp-mux
a=rtcp-rsize
a=sendrecv
a=rtpmap:97 OPUS/48000/2
a=rtcp-fb:97 nack pli
a=fmtp:97 sprop-maxcapturerate=48000;sprop-stereo=0
a=ssrc:235675792 msid:user823769301@host-4c0ea8a4 webrtctransceiver1
a=ssrc:235675792 cname:user823769301@host-4c0ea8a4
a=mid:audio1
a=fingerprint:sha-256 [xxx]
m=application 0 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=setup:actpass
a=ice-ufrag:NwMv07hmtKD9s8EFikQCvqv7JvMpVhv4
a=ice-pwd:[xxx]
a=bundle-only
a=mid:application2
a=sctp-port:5000
a=fingerprint:sha-256 [xxx]

它讓我感到困惑,因為android.media.MediaCodecList包含OMX.google.h264HardwareVideoDecoderFactory::supportedCodecs包含name: H264; params: {level-asymmetry-allowed=1, profile-level-id=42e01f, packetization-mode=1} name: H264; params: {level-asymmetry-allowed=1, profile-level-id=42e01f, packetization-mode=1}

我使用的是榮耀 7X 和華為 P10,我知道他們的芯片組缺少硬件 H264 編碼,這很好,因為我沒有 stream 來自 Android 設備的任何視頻

作為視頻流設備,我使用帶有 GStreamer 的 RaspberryPi 構建作為媒體處理管道。 v4l2-ctl --list-formats的 output :

    Type: Video Capture

    [0]: 'YU12' (Planar YUV 4:2:0)
    [1]: 'YUYV' (YUYV 4:2:2)
    [2]: 'RGB3' (24-bit RGB 8-8-8)
    [3]: 'JPEG' (JFIF JPEG, compressed)
    [4]: 'H264' (H.264, compressed)
    [5]: 'MJPG' (Motion-JPEG, compressed)
    [6]: 'YVYU' (YVYU 4:2:2)
    [7]: 'VYUY' (VYUY 4:2:2)
    [8]: 'UYVY' (UYVY 4:2:2)
    [9]: 'NV12' (Y/CbCr 4:2:0)
    [10]: 'BGR3' (24-bit BGR 8-8-8)
    [11]: 'YV12' (Planar YVU 4:2:0)
    [12]: 'NV21' (Y/CrCb 4:2:0)
    [13]: 'RX24' (32-bit XBGR 8-8-8-8)

這是我的管道定義:

#define RTP_CAPS_OPUS "application/x-rtp,media=audio,encoding-name=OPUS,payload="
#define RTP_CAPS_H264 "application/x-rtp,media=video,encoding-name=H264,payload="

"v4l2src ! video/x-raw,width=640,height=480,framerate=30/1 ! v4l2h264enc ! video/x-h264,level=(string)3.1,stream-format=(string)byte-stream ! h264parse ! rtph264pay ! "  
        "" RTP_CAPS_H264 "96 ! sendrecv. "
        "alsasrc ! queue ! webrtcdsp noise-suppression-level=3 ! webrtcechoprobe ! audioamplify amplification=1 ! audioconvert ! audioresample ! queue ! opusenc ! rtpopuspay ! "
        "queue ! " RTP_CAPS_OPUS "97 ! sendrecv. "

我的猜測是 H264 配置文件不同(RPi: 42c01f ;華為: 42e01f )。 格式有效負載的差異也可能在某種程度上(分別為96100 ),但是我對這些差異的重要性沒有任何線索。

我的第二個猜測是我不應該在兩個客戶端的視頻媒體描述中設置a=sendrecv ,但我不知道如何通過 WebRTC Android API 來實現。 那我應該為sendonly設置 sendonly 嗎?

最后,雖然我沒有對任何視頻進行編碼,但為什么要設置VideoEncoderFactory事件? 如果沒有明確地將DefaultVideoEncoderFactory傳遞給PeerConnection ,我根本無法建立任何連接。

你能指出我正確的方向嗎? 任何線索、經驗和文檔都非常感謝!

經過一番努力,我們設法解決了這個問題。 解決方案是在視頻媒體 SDP 部分強制使用sendonly標志。 這可以通過兩種方式完成(在我的情況下,這兩種方式都需要成功繞過華為缺少的 H264 編碼器):

'要約接收' 屬性

創建 SDP 報價時,您可以為MediaConstraints設置一個屬性,該屬性將強制生成正確的 SDP

val mediaConstraints = MediaConstraints()     
mediaConstraints.mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"))
peerConnection.createOffer(observer, mediaConstraints)

這樣,設備將生成它可以解碼的所有視頻格式的列表,並將其放入帶有recvonly的 SDP 視頻請求中。


Gstreamer 管道定義

為了在 gstreamer 端強制執行sendonly ,我們想出了一個 hacky 解決方案

GstSDPMedia *video_media = (GstSDPMedia *)offer->sdp->medias[0].data;
const GstSDPAttribute *direction_attribute = gst_sdp_media_get_attribute(video_media, 5);
gst_sdp_attribute_set(direction_attribute, "sendonly", NULL);

這會導致在來自 gstreamer 的 SDP 提議/答案上設置正確的屬性,並且不會強制設備查找視頻編碼器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM