
2020幎4æã«ãCitizenlabã¯ãZoomã®æå·åãããªã匱ãããšãå ±åããZoomãSILKãªãŒãã£ãªã³ãŒããã¯ã䜿çšããŠãããšè¿°ã¹ãŸãããæ®å¿µãªããããã®èšäºã«ã¯ããã確èªããå°æ¥åç §ããæ©äŒãäžããããã®åæããŒã¿ãå«ãŸããŠããŸããã§ãããããããããããã¿ãªãŒSilvanovichããGoogleã®Project Zeroã®ãããŠFridaãã¬ãŒã¹ããŒã«ã«ãããã€ãã®çã®SILKãã¬ãŒã ã®ãã³ããååŸããããšãã§ããŸããã圌ãã®åæãããWebRTCããªãŒãã£ãªãåŠçããæ¹æ³ã調ã¹ãããã«ãªããŸãããäžè¬çã«ç¥èŠãããé話å質ã«é¢ããŠã¯ãå°ããªã°ãªããã§ããæ°ä»ãåŸåããããããæã圱é¿ãäžããã®ã¯ãªãŒãã£ãªå質ã§ããWebRTCãæäŸããé³è³ªãæ¹åããããã®ãªãã·ã§ã³ãæ¢ããšãããå®éã®åéºã«çæããã«ã¯ãããã10ç§ã®åæã§ååã§ããã
2017幎ã«ïŒDataChannelã®æçš¿ã®åã«ïŒãã€ãã£ãã®Zoomã¯ã©ã€ã¢ã³ããæ±ã£ããšããããã®ãªãŒãã£ãªããã±ãŒãžãWebRTCããŒã¹ã®ãœãªã¥ãŒã·ã§ã³ããã±ãŒãžãšæ¯èŒããŠéåžžã«å€§ããå Žåãããããšã«æ°ä»ããŸããã

äžã®ã°ã©ãã¯ãç¹å®ã®UDPãã€ããŒãé·ãæã€ãã±ããã®æ°ã瀺ããŠããŸãã150ã300ãã€ãã®ãã±ããã¯ãéåžžã®WebRTCåŒã³åºããšæ¯èŒãããšç°åžžã§ãããããã¯ãéåžžOpusããååŸãããã±ãããããã¯ããã«é·ããªããŸãããã©ã¯ãŒããšã©ãŒã³ã³ãããŒã«ïŒFECïŒãŸãã¯åé·æ§ããããšæãããŸããããæå·åãããŠããªããã¬ãŒã ã«ã¢ã¯ã»ã¹ã§ããªããã°ãããã«çµè«ãå°ãåºããããäœãããããããããšã¯å°é£ã§ããã
æ°ãããã³ãã®æå·åãããŠããªãSILKãã¬ãŒã ã¯ãéåžžã«ãã䌌ãååžã瀺ããŸããããã¬ãŒã ããã¡ã€ã«ã«å€æããŠããçãã¡ãã»ãŒãžãåçããåŸïŒéåžžã«åœ¹ç«ã€ããã°æçš¿ãããŠãããGiacomo Vaccaã«æè¬ããŸãïŒå¿ èŠãªæé ã説æããŸãïŒWiresharkã«æ»ããããã±ãŒãžã確èªããŸãããããã¯ç§ãç¹ã«è峿·±ããšæã£ã3ã€ã®ããã±ãŒãžã®äŸã§ãïŒ
packet 7:
e9e4ab17ad8b9b5176b1659995972ac9b63737f8aa4d83ffc3073d3037b452fe6e1ee
5e6e68e6bcd73adbd59d3d31ea5fdda955cbb7f
packet 8:
e790ba4908639115e02b457676ea75bfe50727bb1c44144d37f74756f90e1ab926ef
930a3ffc36c6a8e773a780202af790acfbd6a4dff79698ea2d96365271c3dff86ce6396
203453951f00065ec7d26a03420496f
packet 9:
e93997d503c0601e918d1445e5e985d2f57736614e7f1201711760e4772b020212dc
854000ac6a80fb9a5538741ddd2b5159070ebbf79d5d83363be59f10ef
e790ba4908639115e02b457676ea75bfe50727bb1c44144d37f74756f90e1ab926ef
930a3ffc36c6a8e773a780202af790acfbd6a4dff79698ea2d96365271c3dff86ce6396
203453951f00065ec7d26a03420496f
e9e4ab17ad8b9b5176b1659995972ac9b63737f8aa4d83ffc3073d3037b452fe6e1ee
5e6e68e6bcd73adbd59d3d31ea5fdda955cbaef
ããã±ãŒãž9ã«ã¯ã2ã€ã®ä»¥åã®ããã±ãŒãžãããã±ãŒãž8-1ã€ã®ä»¥åã®ããã±ãŒãžãå«ãŸããŠããŸãããã®åé·æ§ã¯ãSILKãã³ãŒããŒã®è©³çްãªèª¿æ»ã«ãã£ãŠç€ºãããLBRR-äœãããã¬ãŒãåé·æ§ãã©ãŒãããã®äœ¿çšã«ãã£ãŠåŒãèµ·ããããŸãïŒSkypeããŒã ãæäŸããã€ã³ã¿ãŒããããããžã§ã¯ãããŸãã¯GitHubã®ãªããžããªã«ãããŸãïŒã

Zoomã¯SKP_SILK_LBRR_VER1ã䜿çšããŸããã2ã€ã®ãã©ãŒã«ããã¯ããã±ãŒãžããããŸããåUDPãã±ããã«çŸåšã®ãªãŒãã£ãªãã¬ãŒã ã ãã§ãªããåã®2ã€ã®ãªãŒãã£ãªãã¬ãŒã ãå«ãŸããŠããå Žåã3ã€ã®ãã±ããã®ãã¡2ã€ã倱ã£ãŠããå ç¢ã«ãªããŸããã§ã¯ããºãŒã ã®é³è³ªã®éµã¯ãã°ãã¡ããã®Skypeã·ãŒã¯ã¬ããã¬ã·ããããããŸããã
Opus FEC
WebRTCã§åãããšãã©ã®ããã«éæã§ããŸããïŒæ¬¡ã®æãããªã¹ãããã¯ãOpusFECãæ€èšããããšã§ããã
SILKã®LBRRïŒäœã¬ãŒãäºçŽïŒã¯Opusã«ããããŸãïŒOpusã¯ãããã¬ãŒãç¯å²ã®äžéã«SILKã䜿çšãããã€ããªããã³ãŒããã¯ã§ããããšãå¿ããªãã§ãã ããïŒããã ããOpus SILKã¯ããšã©ãŒå¶åŸ¡ã¢ãŒãã§äœ¿çšãããLBRRã®äžéšã§ããããã«ããœãŒã¹ã³ãŒãããã€ãŠSkypeã«ãã£ãŠæ€åºãããå ã®SILKãšã¯å€§ããç°ãªããŸãã
Opusã¯ãå ã®ãªãŒãã£ãªãã¬ãŒã ã®åŸã«ãšã©ãŒå¶åŸ¡ã远å ããã ãã§ãªãããã®åã«ããããããã¹ããªãŒã ã«ãšã³ã³ãŒããããŸããInsertable Streams APIã䜿çšããŠç¬èªã®ãšã©ãŒå¶åŸ¡ã远å ããŠã¿ãŸããããå®éã®ãã±ããã®åã«æ å ±ããããã¹ããªãŒã ã«æ¿å ¥ããã«ã¯ãå®å šãªãã©ã³ã¹ã³ãŒãã£ã³ã°ãå¿ èŠã§ããã

åãçµã¿ã¯æåããŸããã§ããããLBRRã®åœ±é¿ã«é¢ããããã€ãã®çµ±èšãçæãããŸããããããäžã®å³ã«ç€ºããŸãã LBRRã¯ããã±ããæå€±ã倧ããããããã«æå€§10 kbpsïŒãŸãã¯ããŒã¿ã¬ãŒãã®3åã®2ïŒã®ãããã¬ãŒãã䜿çšããŸãããªããžããªã¯ããããå ¥æã§ããŸãããããã®çµ±èšã¯ã®WebRTCãåŒã³åºãããšãã«è¡šç€ºãããŠããªã
getStats() APIãããã®çµæã¯éåžžã«è峿·±ããã®ã§ããã
OpusFECã®åé¡ã¯ãã©ã³ã¹ã³ãŒãã£ã³ã°ã ãã§ã¯ãããŸãããçµå±ã®ãšãããWebRTCã§ã®èšå®ã¯ãã圹ã«ç«ããªãã
- , , - . Slack 2016 . , .
- 25%. .
- FEC (. ).
ã¿ãŒã²ããã®æå€§ãããã¬ãŒãããFECãããã¬ãŒããå·®ãåŒãããšã¯ãŸã£ããæå³ããããŸãã-FECã¯ã¡ã€ã³ã¹ããªãŒã ã®ãããã¬ãŒããç©æ¥µçã«åæžããŠããŸããéåžžããããã¬ãŒãã¹ããªãŒã ãäœããšãå質ãäœäžããŸãã FECã§ä¿®æ£ã§ãããã±ããæå€±ããªãå ŽåãFECã¯å質ãäœäžãããã ãã§ãå質ãåäžãããããšã¯ãããŸããããªããããèµ·ããã®ã§ããïŒäž»ãªçè«ã¯ã茻茳ããã±ããæå€±ã®çç±ã®1ã€ã§ãããšããããšã§ãã茻茳ãçºçããŠããå Žåã¯ãåé¡ãæªåãããã ããªã®ã§ããã以äžããŒã¿ãéä¿¡ããããªãã§ããããããããEmilIvovã2017幎ã®çŽ æŽãããKrankyGeekã®è¬æŒã§èª¬æããŠããããã«èŒ»èŒ³ãå¿ ããããã±ããæå€±ã®åå ã§ãããšã¯éããŸãããããã«ããã®ã¢ãããŒãã§ã¯ãä»éãããããªã¹ããªãŒã ãç¡èŠãããŸããæ¯èŒçå°ããª50kbpsã®Opusã¹ããªãŒã ãšãšãã«æ°çŸãããããã®ãããªãéä¿¡ããå ŽåãOpusãªãŒãã£ãªã®èŒ»èŒ³ããŒã¹ã®FECæŠç¥ã¯ããŸãæå³ããããŸãããããããå°æ¥çã«ã¯libopusã«ããã€ãã®å€æŽãå ããããã§ãããããçŸåšWebRTCã§ããã©ã«ãã§æå¹ã«ãªã£ãŠãããããä»ã®ãšããç¡å¹ã«ããããšæããŸãã
ããã¯ç§ãã¡ã«ã¯é©ããªããšçµè«ä»ããŸã...
èµ€
çã®åé·æ§ãå¿ èŠãªå ŽåãRTPã«ã¯åé·ãªãŒãã£ãªããŒã¿ã®RTPãã€ããŒãïŒREDïŒãšåŒã°ãããœãªã¥ãŒã·ã§ã³ããããŸããããã¯ããªãå€ãã§ããRFC2198ã¯1997å¹Žã«æžãããŸããããã®ãœãªã¥ãŒã·ã§ã³ã§ã¯ãã¿ã€ã ã¹ã¿ã³ããç°ãªãè€æ°ã®RTPãã€ããŒãããæ¯èŒçäœã³ã¹ãã§åãRTPãã±ããã«å ¥ããããšãã§ããŸãã
REDã䜿çšããŠåãã±ããã«1ã€ãŸãã¯2ã€ã®åé·ãªãŒãã£ãªãã¬ãŒã ãé 眮ãããšãOpusFECããããã±ããæå€±ã«å¯ŸããŠã¯ããã«å ç¢ã«ãªããŸãããã ããããã¯ããªãŒãã£ãªãããã¬ãŒãã30kbpsãã60ãŸãã¯90kbpsã«2åãŸãã¯3åã«ããããšã«ãã£ãŠã®ã¿å¯èœã§ãïŒããããŒçšã«10 kbpsã远å ïŒããã ãã1ç§ããã1ã¡ã¬ããããè¶ ãããããªããŒã¿ãšæ¯èŒãããšãããã»ã©æªãã¯ãããŸããã
WebRTCã©ã€ãã©ãªã«ã¯ãREDçšã®2çªç®ã®ãšã³ã³ãŒããšãã³ãŒããå«ãŸããŠããŸãããæªäœ¿çšã®ãªãŒãã£ãªREDã³ãŒããåé€ããããšããã«ããããããããã®ãšã³ã³ãŒããŒãæ¯èŒçå°ãªãåŽåã§é©çšããããšãã§ããŸããããœãªã¥ãŒã·ã§ã³ã®å®å šãªå±¥æŽã¯ã WebRTCãã°è¿œè·¡ã·ã¹ãã ã§å ¥æã§ããŸãã
ãŸããChromeãæ¬¡ã®ãã©ã°ã§å§ãŸããšãã«å«ãŸãã詊çšçãšããŠå©çšã§ããŸãã
--force-fieldtrials=WebRTC-Audio-Red-For-Opus/Enabled/
次ã«ãSDPããŽã·ãšãŒã·ã§ã³ãä»ããŠREDãæå¹ã«ã§ããŸããæ¬¡ã®ããã«è¡šç€ºãããŸãã
a=rtpmap:someid red/48000/2
远å ã®åž¯åå¹ ã䜿çšããããšã¯ãå§ãã§ããªãç°å¢ããããããããã©ã«ãã§ã¯æå¹ã«ãªã£ãŠããŸããã REDã䜿çšããã«ã¯ãOpusã³ãŒããã¯ã®åã«æ¥ãããã«ã³ãŒããã¯ã®é åºã倿ŽããŸããããã¯ãããã«
RTCRtpTransceiver.setCodecPreferences瀺ãããã«APIã䜿çšããŠå®è¡ã§ããŸããæããã«å¥ã®æ¹æ³ã¯ãSDPãæåã§å€æŽããããšã§ãã SDP圢åŒã§ãæå€§äºçŽã¬ãã«ãèšå®ããæ¹æ³ãæäŸã§ããŸãããRFC 2198ã®ãªãã¡ãŒãšå¿çã®ã»ãã³ãã£ã¯ã¹ãå®å
šã«æç¢ºã§ã¯ãªãã£ããããããããã°ããå»¶æããããšã«ããŸããããªãŒãã£ãªã®äŸ
ã§å®è¡ããããšã§ãããããã¹ãŠã©ã®ããã«æ©èœãããã瀺ãããšãã§ããŸããããã¯ã1ã€ã®ããã¯ã¢ããããã±ãŒãžã䜿çšããåæããŒãžã§ã³ã®å€èгã§ãã

ããã©ã«ãã§ã¯ããã€ããŒãã®ãããã¬ãŒãïŒèµ€ãç·ïŒã¯ãåé·æ§ããªãå Žåã®ã»ãŒ2åã§ãã»ãŒ60kbpsã§ããDTXïŒDiscontinuous TransferïŒã¯ãé³å£°ãæ€åºããããšãã«ã®ã¿ãã±ãããéä¿¡ãã垯åå¹ ç¯çŽã¡ã«ããºã ã§ããäºæ³ã©ãããDTXã䜿çšãããšãéè©±ã®æåŸã«è¡šç€ºãããããã«ããããã¬ãŒãã®åœ±é¿ãå€å°ç·©åãããŸãã


ãã±ããé·ããã§ãã¯ãããšãæåŸ ãããçµæã瀺ãããŸãããã±ããã¯ã以äžã«ç€ºããã€ããŒãé·ã®éåžžã®ååžãšæ¯èŒããŠãå¹³åããŠ2åã®é·ãïŒèãé«ãïŒã§ãã
ããã¯ãéšåçãªäºçŽãèŠãããZoomã®æ©èœãšã¯ãŸã å°ãç°ãªããŸããæ¯èŒã確èªããããã«ãåã«ç€ºãããºãŒã ãã±ããé·ã°ã©ããããäžåºŠèŠãŠã¿ãŸãããã

é³å£°ã¢ã¯ãã£ããã£æ€åºïŒVADïŒãµããŒãã®è¿œå
Opus FECã¯ããã±ããã«é³å£°ã¢ã¯ãã£ããã£ãããå Žåã«ã®ã¿ããã¯ã¢ããããŒã¿ãéä¿¡ããŸããåãããšãREDã®å®è£ ã«ãåœãŠã¯ãŸããŸãããã®ãããSILKã¬ãã«ã§å®çŸ©ãããŠããæ£ããVADæ å ±ã衚瀺ããããã«Opusãšã³ã³ãŒããŒã倿Žããå¿ èŠããããŸãããã®èšå®ã§ã¯ããããã¬ãŒãã¯é³å£°ãååšããå Žåã«ã®ã¿60 kbpsã«éããŸãïŒäžå®ã®60+ kbpsãšæ¯èŒããŠïŒã

ãããŠããã¹ãã¯ãã«ãã¯ããºãŒã ã§èŠããã®ã®ããã«ãªããŸãã

ãããéæããããã®å€æŽã¯ãŸã çŸããŠããŸããã
é©åãªè·é¢ãèŠã€ãã
è·é¢ã¯ãããã¯ã¢ãããã±ããã®æ°ãã€ãŸããçŸåšã®ãã±ããã®åã®ãã±ããã®æ°ã§ããé©åãªè·é¢ãèŠã€ããäœæ¥ãããŠãããšãè·é¢1ã®REDãæ¶Œããå Žåãè·é¢2ã®REDã¯ããã«æ¶ŒããããšãããããŸãããç§ãã¡ã®ç ç©¶æã®èŠç©ããã§ã¯ã60ïŒ ã®ã©ã³ãã ãªãã±ããæå€±ãã·ãã¥ã¬ãŒãããŸããããã®ç°å¢ã§ã¯ãOpus + REDã®ããã©ãŒãã³ã¹ã¯åªããŠããŸããããREDã®ãªãOpusã®ããã©ãŒãã³ã¹ã¯ã¯ããã«å£ã£ãŠããŸããã WebRTC getstatsãïŒïŒAPIã¯ãåå²ããŠåŸãããé ããã詊æã®å²åãšæ¯èŒããããšã«ãã£ãŠããããæž¬å®ããããã®éåžžã«æçšãªæ©èœãæäŸconcealedSamplesãããããšã«ãã£ãŠtotalSamplesReceivedãã
ãªãŒãã£ãªãµã³ãã«ããŒãžã§ã¯ãã³ã³ãœãŒã«ã«è²Œãä»ããæ¬¡ã®JavaScriptã¹ããããã䜿çšããŠããã®ããŒã¿ãç°¡åã«ååŸã§ããŸãã
(await pc2.getReceivers()[0].getStats()).forEach(report => {
if(report.type === "track") console.log(report.concealmentEvents, report.concealedSamples, report.totalSamplesReceived, report.concealedSamples / report.totalSamplesReceived)})
ããŸãç¥ãããŠããªããéåžžã«äŸ¿å©ãªãã©ã°ã䜿çšããŠãããã€ãã®ãã±ããæå€±ãã¹ããå®è¡ããŸãã
WebRTCFakeNetworkReceiveLossPercentã
--force-fieldtrials=WebRTC-Audio-Red-For-Opus/Enabled/WebRTCFakeNetworkReceiveLossPercent/20/
20ïŒ ã®ãã±ããæå€±ãšããã©ã«ãã§æå¹ã«ãªã£ãŠããFECã§ã¯ããªãŒãã£ãªå質ã«å€§ããªéãã¯ãããŸããã§ããããã¡ããªãã¯ã«ã¯ããããªéãããããŸããã
| ã·ããªãª | æå€±ç |
|---|---|
| èµ€ãªã | 18ïŒ |
| èµ€ãªããFECç¡å¹ | 20ïŒ |
| è·é¢1ã®èµ€ | 4ïŒ |
| è·é¢2ã®èµ€ | 0.7ïŒ |
REDãŸãã¯FECããªãå Žåãã¡ããªãã¯ã¯èŠæ±ããããã±ããæå€±ãšã»ãŒäžèŽããŸããFECã®å¹æã¯ãããŸãããå°ããã§ãã
REDããªããšã60ïŒ ã®æå€±ã§é³è³ªãããªãæªããªããå°ãã¡ã¿ãªãã¯ã«ãªããèšèãçè§£ãã«ãããªããŸããã
| ã·ããªãª | æå€±ç |
|---|---|
| èµ€ãªã | 60ïŒ |
| è·é¢1ã®èµ€ | 32ïŒ |
| è·é¢2ã®èµ€ | 18ïŒ |
REDã§ã¯è·é¢= 1ã®å¯èŽã¢ãŒãã£ãã¡ã¯ããããã€ããããŸããããè·é¢2ïŒçŸåšäœ¿çšãããŠããåé·æ§ã®éïŒã§ã¯ã»ãŒå®å šãªãµãŠã³ãã§ããã
人éã®è³ã¯äžèŠåã«èµ·ããããçšåºŠã®æ²é»ã«èããããšãã§ãããšããæèŠããããŸããïŒãããŠãGoogle Duoã¯æ²é»ãåããããã«æ©æ¢°åŠç¿ã¢ã«ãŽãªãºã ã䜿çšããŠããããã§ããïŒ
å®äžçã§ã®ããã©ãŒãã³ã¹ã®æž¬å®
Opusã«REDãå«ããããšã§é³è³ªãåäžããããšãé¡ã£ãŠããŸãããå Žåã«ãã£ãŠã¯æªåããããšããããŸãã Emil Ivovã¯ãPOLQA-MOSã¡ãœããã䜿çšããŠããã€ãã®ãªã¹ãã³ã°ãã¹ãã宿œããããšãå¿é¡ããŸãããããã¯ãã§ã«Opusã«å¯ŸããŠè¡ãããŠãããããæ¯èŒã®ããã®ããŒã¹ã©ã€ã³ããããŸãã
æåã®ãã¹ãã§ææãªçµæã瀺ãããå Žåã¯ãäžèšã§äœ¿çšããæå€±çã®ææšãé©çšããŠãJitsiMeetã®ã¡ã€ã³ã¹ãã£ã³ã§å€§èŠæš¡ãªå®éšãè¡ããŸãã
ã¡ãã£ã¢ãµãŒããŒãšSFUã®å Žåããã¹ãŠã®ã¯ã©ã€ã¢ã³ããREDäŒè°ããµããŒãããŠããããã§ã¯ãªããã®ããã«ããµãŒããŒãéžæããã¯ã©ã€ã¢ã³ããžã®REDãªã¬ãŒã管çããå¿ èŠãããå ŽåããããããREDã®æå¹åã¯å°ãé£ããããšã«æ³šæããŠãã ããããŸããäžéšã®ã¯ã©ã€ã¢ã³ãã¯ãREDãäžèŠãªéããã垯åå¹ ã®ãã£ãã«äžã«ããå ŽåããããŸãããšã³ããã€ã³ããREDããµããŒãããŠããªãå ŽåãSFUã¯äžèŠãªãšã³ã³ãŒãã£ã³ã°ãåé€ããã©ãããŒãªãã§Opusãéä¿¡ã§ããŸããåæ§ã«ãREDèªäœãå®è£ ããOpusãéä¿¡ãããšã³ããã€ã³ãããREDããµããŒããããšã³ããã€ã³ãã«ãã±ãããåéä¿¡ãããšãã«äœ¿çšã§ããŸãã
ãã®ãšããµã€ãã£ã³ã°ãªåéºãåŸæŽããŠãããJitsi / 8Ã8Incãšãå¿ èŠãªå€æŽã«ã€ããŠåæããŠãã£ãŒãããã¯ãæäŸããŠãããGoogleã®äººã ã«æè¬ããŸãã
ãããŠããã¿ãªãŒã»ã·ã«ãããããããââãªãã£ãããç§ã¯æå·åããããã€ããèŠãŠåº§ã£ãŠããã ããïŒ