WebRTC中如何设置视频的码流

WebRTC原生就是为了p2p通话而设计的,视频的码流会尽量匹配你的带宽。你会发现,当两个客户端在局域网内
通话时,视频的码流会非常大,有时会达到两三兆。在有些业务场景下,你可能不希望要这么大的视频码流,比如会占用
你的服务器很大的带宽。如果我们能够灵活的控制视频码流,这对节省服务器带宽会非常有用。
      在WebRTC生成的SDP中,与视频编码相关的部分如下:
a=rtpmap:100 VP8/90000
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=rtcp-fb:100 goog-remb
a=rtcp-fb:100 transport-cc
a=rtpmap:101 VP9/90000
a=rtcp-fb:101 ccm fir
a=rtcp-fb:101 nack
a=rtcp-fb:101 nack pli
a=rtcp-fb:101 goog-remb
a=rtcp-fb:101 transport-cc
a=rtpmap:107 H264/90000
a=rtcp-fb:107 ccm fir
a=rtcp-fb:107 nack
a=rtcp-fb:107 nack pli
a=rtcp-fb:107 goog-remb
a=rtcp-fb:107 transport-cc
a=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f

如果你希望控制VP8编码的码流,你可以把SDP修改成如下

a=rtcp-fb:100 transport-cc
a=fmtp:100 x-google-max-bitrate=2800;x-google-min-bitrate=1200;x-google-start-bitrate=200000 这一行是新加的
a=rtpmap:101 VP9/90000

如果你希望控制VP9编码的码流,你可以把SDP修改成如下
a=rtcp-fb:101 transport-cc
a=fmtp:101 x-google-max-bitrate=2800;x-google-min-bitrate=1200;x-google-start-bitrate=200000 这一行是新加的
a=rtpmap:107 H264/90000

如果你希望控制H264编码的码流,你可以把SDP修改成如下

a=fmtp:107 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f;x-google-max-bitrate=2800;x-google-min-bitrate=1200;x-google-start-bitrate=200000

下面我来解释码流控制相关的三个参数:
x-google-max-bitrate:视频码流最大值,当网络特别好时,码流最大能达到这个值,如果不设置这个值,网络好时码流会非常大
x-google-min-bitrate:视频码流最小值,当网络不太好时,WebRTC的码流每次5%递减,直到这个最小值为,如果没有设置这个值,网络不好时,视频质量会非常差
x-google-start-bitrate:视频编码初始值 ,当网络好时,码流会向最大值递增,当网络差时,码流会向最小值递减

在PeerConnection调用setRemoteDescription前修改SDP就会生效,本人已经在WebRTC56版本中实验成功。

作者:onlycoder_net
来源:CSDN
原文:https://blog.csdn.net/onlycoder_net/article/details/76702729
版权声明:本文为博主原创文章,转载请附上博文链接!

Webrt中H264编码相关问题

编译WebRTC后,默认是没有把H264编码编进来的。WebRTC中H264编码采用的是openh264,解码默认采用的是
ffmpeg,移动版本android,ios默认采用的是系统的h264硬件编码,如果你的手机支持H264硬件编码的话,WebRTC
就会默认支持H264.

1.如何在桌面版本中开启H264编码
  使用gn生成ninja文件时,加入以下两个选项就可以生成 ffmpeg_branding=”Chrome” rtc_use_h264=true,比如我
要编译Linux版本,使用以下命令 gn gen out/linux –args=’target_os=”linux” target_cpu=”x64″ is_component_build=false 
is_debug=false ffmpeg_branding=”Chrome” rtc_use_h264=true’,再输入ninja -C out/linux video_loopback,就会在out/linux
目录下生成video_loopback可执行文件,你进入到out/linux目录下,输入./video_loopback –codec=H264就可以看到效果了,
这个在WebRTC56版本,ubuntu14.04环境下测试。

2.如何在安卓版本中调试h264硬件编解码

       WebRTC是通过jni调用Android系统中的MediaCodec api来实现硬件编解码的,我通过分析代码发现,硬件解码的实现在org.webrtc.

MediaCodecVideoDecoder中实现的,目前WebRTC官方只调试过高通,三星等大厂商的芯片,像其它的比如海思,联发科,全志之类等
芯片,你要想把这些芯片的H264硬件解码调出来,就需要自己修改WebRTC的java代码了,在MediaCodecVideoDecoder.java中有以下代码

  private static final String[] supportedVp8HwCodecPrefixes = {“OMX.qcom.”, “OMX.Nvidia.”, “OMX.Exynos.”, “OMX.Intel.”};
  private static final String[] supportedVp9HwCodecPrefixes = {“OMX.qcom.”, “OMX.Exynos.”};
  private static final String[] supportedH264HwCodecPrefixes = {“OMX.qcom.”, “OMX.Intel.”, “OMX.Exynos.”};

以下代码的意思就是VP8硬件解码只支持高通,英伟达,三星,英特尔,VP9硬件解码只支持高通和三星,H264硬件解码只支持高通,英特尔,三星。
比如我知道海思的芯片支持H264硬件解码,我只需要修改一行就可以调试出来。
private static final String[] supportedH264HwCodecPrefixes = {“OMX.qcom.”, “OMX.Intel.”, “OMX.Exynos.”,”OMX.hisi.”};

说完解码我们再来看编码,硬件编码在的MediaCodec api来实现硬件编解码的,我通过分析代码发现,硬件解码的实现在org.webrtc.
MediaCodecVideoEncoder中,关键代码如下,
private static final MediaCodecProperties qcomH264HwProperties = new MediaCodecProperties(
      “OMX.qcom.”, Build.VERSION_CODES.KITKAT, BitrateAdjustmentType.NO_ADJUSTMENT);
private static final MediaCodecProperties exynosH264HwProperties = new MediaCodecProperties(
      “OMX.Exynos.”, Build.VERSION_CODES.LOLLIPOP, BitrateAdjustmentType.FRAMERATE_ADJUSTMENT);
private static final MediaCodecProperties[] h264HwList =
      new MediaCodecProperties[] {qcomH264HwProperties, exynosH264HwProperties};

以下代码的意思是WebRTC默认只支持高通和三星的芯片才有H264硬件编码,我现在想把海思的H264硬件编码也加进来,需要修成成以下这样:
private static final MediaCodecProperties qcomH264HwProperties = new MediaCodecProperties(
      “OMX.qcom.”, Build.VERSION_CODES.KITKAT, BitrateAdjustmentType.NO_ADJUSTMENT);
  private static final MediaCodecProperties exynosH264HwProperties = new MediaCodecProperties(
      “OMX.Exynos.”, Build.VERSION_CODES.LOLLIPOP, BitrateAdjustmentType.FRAMERATE_ADJUSTMENT);
  private static final MediaCodecProperties hihsH264HwProperties = new MediaCodecProperties(
    “OMX.hisi.”, Build.VERSION_CODES.KITKAT, BitrateAdjustmentType.NO_ADJUSTMENT);
  private static final MediaCodecProperties[] h264HwList =
      new MediaCodecProperties[] {qcomH264HwProperties, exynosH264HwProperties,hihsH264HwProperties};

我模仿高通的编码加了一行,并加入到h264HwList数组中,这样海思的H264硬件编码也在WebRTC中调试出来了。

作者:onlycoder_net
来源:CSDN
原文:https://blog.csdn.net/onlycoder_net/article/details/76703812
版权声明:本文为博主原创文章,转载请附上博文链接!

WebRTC通话过程中如何避免其它进程音量下降

在Windows下,WebRTC通话过程中,会把其它进程的音量自动下降,比如音乐播放器。
如何避免这种情况呢?其实很简单,只要修改一下注册表就可以了,用Qt的实现方法如下:

void disableCommunicationReduce()
{
        static const QString key = “HKEY_CURRENT_USER\SOFTWARE\Microsoft\Multimedia\Audio”;
        QSettings settings(key, QSettings::NativeFormat);
        settings.setValue(“UserDuckingPreference”, 3);

}

作者:onlycoder_net
来源:CSDN
原文:https://blog.csdn.net/onlycoder_net/article/details/76781141
版权声明:本文为博主原创文章,转载请附上博文链接!

WebRTC中OPUS编码相关设置和分析

新版本的WebRTC默认是采用OPUS编码,OPUS编码是silk编码和celt编码的合成,silk编码是skype公司开源的一个编码,
特别适合语音通信,它根据人的声音做了很多优化,但不是适合传输高质量的音乐。celt编码相反更适合传输高质量的音乐。
OPUS编码在采样率很高的情况下,音质还是非常不错的,以下这个连接地址有很多opus的音频样例,大家可以在线听听。
http://www.opus-codec.org/examples/

       根据阅读官方文档知道OPUS编码支持8000,16000,32000,48000等几种编码,支持单声道,双声道,支持6kb-510kb编码率。如果我们想改变WebRTC的声音
编码参数,我们应该如何做呢?
       1.首先我会先去看看WebRTC有没有引出相关的接口,结果查看了PeerConnection,MediaStream,AudioTrack等等相关的类后,根本没有发现相关接口。
       2.根据以往经验,如果WebRTC没有提供直接的接口来调,往往还可以通过修改SDP参数和达到我们的目的。我把生成的Offer SDP打印出来后,发现了比较可疑的地
         方,”fmtp:111 minptime=10;useinbandfec=1″,这一行是设置opus编码参数的地方。我再以“useinbandfec”为关键字在WebRTC中代码中搜索,
       在mediaconstants.cc代码,找到以下相关代码
         // draft-spittka-payload-rtp-opus-03.txt
             const char kCodecParamPTime[] = “ptime”;
             const char kCodecParamMaxPTime[] = “maxptime”;
             const char kCodecParamMinPTime[] = “minptime”;
             const char kCodecParamSPropStereo[] = “sprop-stereo”;
             const char kCodecParamStereo[] = “stereo”;
             const char kCodecParamUseInbandFec[] = “useinbandfec”;
             const char kCodecParamUseDtx[] = “usedtx”;
             const char kCodecParamMaxAverageBitrate[] = “maxaveragebitrate”;
             const char kCodecParamMaxPlaybackRate[] = “maxplaybackrate”;
       3.我依葫芦画瓢,在我自己写的demo代码中把sdp中的”fmtp:111 minptime=10;useinbandfec=1″ 这一行替换成”fmtp:111 minptime=10;useinbandfec=1;maxaveragebitrate =8000″,编译成功运行后,发现参数生效了,发送一路语音占用的带宽由于5K变成了3K左右,这就证明参数生效了。

      4.在网络挺别差的情况下,我们可能希望声音的码流再变小一点,对音质的要求反而不是哪么高了,音频采样率为8000HZ就够了。要实现这个功能的话把”fmtp:111 minptime=10;useinbandfec=1″ 这一行替换成”fmtp:111 minptime=10;useinbandfec=1;maxaveragebitrate =6000;maxplaybackrate=8000″就行了

     5.如果要传音乐,哪我们必需强制OPUS切换到CELT编码。要实现这个功能的话把”fmtp:111 minptime=10;useinbandfec=1″ 这一行替换成”fmtp:111 minptime=10;useinbandfec=1;maxaveragebitrate =64000;maxplaybackrate=48000;stereo=1″就行了

以下功能在WebRTC56版本中试验成功,修改SDP的时机在 SetRemoteDescription 之前,把对方传过来的SDP字符串给替换了,再调用SetRemoteDescription方法