首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >无法为华为设备上的H264编码视频设置远程SDP报价

无法为华为设备上的H264编码视频设置远程SDP报价
EN

Stack Overflow用户
提问于 2021-06-11 00:27:33
回答 1查看 644关注 0票数 0

我正在为Android开发一个WebRTC视频呼叫应用程序(单向视频和双向音频),它带有预先构建的包org.webrtc:google-webrtc:1.0.32006。我被这个库中的一个错误所困扰,它声明:

代码语言:javascript
运行
复制
LS_ERROR
tag: webrtc_video_engine.cc 
message: (line 745): No video codecs supported.

尝试设置远程SDP报价后:

代码语言:javascript
运行
复制
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}时,这让我感到困惑。

我使用的是Honor 7X和华为P10,我知道他们的芯片组缺乏硬件H264编码,这很好,因为i不从安卓设备上传输任何视频

作为一种视频流设备,我采用RaspberryPi构建与GStreamer作为媒体处理流水线。v4l2-ctl --list-formats输出

代码语言:javascript
运行
复制
    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)

这是我的流水线定义:

代码语言:javascript
运行
复制
#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实现这一点。那么,我应该把sendonly放在RPi上吗?

最后,为什么我要设置VideoEncoderFactory事件,尽管我没有编码任何视频?如果不显式地将DefaultVideoEncoderFactory传递给PeerConnection,我就根本无法建立任何连接。

你能给我指明正确的方向吗?任何线索、经验和文档都是非常感谢的!

EN

Stack Overflow用户

发布于 2021-12-04 15:07:14

经过一番斗争,我们终于解决了这个问题。解决方案是在视频媒体SDP部件上强制使用sendonly标志。这可以通过两种方式来完成(在我的例子中,这两种方法都是成功绕过华为缺少的H264编码器所必需的):

‘要约接收’属性

在创建SDP提供程序时,可以向MediaConstraints添加一个属性,该属性将强制执行正确的SDP生成。

代码语言:javascript
运行
复制
val mediaConstraints = MediaConstraints()     
mediaConstraints.mandatory.add(MediaConstraints.KeyValuePair("OfferToReceiveVideo", "true"))
peerConnection.createOffer(observer, mediaConstraints)

通过这种方式,设备将生成一个可以解码的所有视频格式的列表,并将其放入带有recvonly的SDP视频请求中。

Gstreamer流水线定义

为了在gstreamer端执行sendonly,我们想出了一种有点麻烦的解决方案。

代码语言:javascript
运行
复制
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提供/应答上设置正确的属性,并且不会强迫设备查找视频编码器。

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67929919

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档