Come Peering trasmette lo schermo del tuo Mac al tuo iPhone
Un desktop remoto è uno stream video con un requisito insolito: chi guarda è anche chi controlla. Ogni scelta di progetto qui sotto nasce dalla necessità di tenere breve quel ciclo.
Cattura: chiedere l'immagine al sistema
L'app per Mac usa ScreenCaptureKit di Apple per ottenere i fotogrammi. La sorgente può essere un intero display, tutte le finestre di un'app o una sola finestra, e puoi passare dall'una all'altra senza interrompere la connessione. È anche per questo che macOS chiede l'autorizzazione Registrazione schermo la prima volta: senza di essa il Mac può consegnare solo un'immagine nera.
Codifica: bassa latenza, nessun riordino
I fotogrammi vanno all'encoder VideoToolbox di Apple sul Mac, come H.264 o HEVC, a seconda di quello che il telefono dichiara di saper decodificare. Le impostazioni sono l'opposto di quelle di un servizio di streaming:
- Nessun B-frame. Un B-frame richiede un fotogramma dal futuro, quindi usarli significa trattenere le immagini. Senza, l'ordine di decodifica è l'ordine di visualizzazione e nulla aspetta.
- Controllo del bitrate a bassa latenza. L'encoder spende i suoi bit man mano, invece di guardare avanti.
- Un keyframe almeno ogni due secondi, e subito quando un nuovo spettatore si unisce, riprende o cambia sorgente, così un'immagine persa si ripristina rapidamente.
- Un bitrate che scala con lo schermo. Per impostazione predefinita è il numero di pixel per il frame rate per 0,12, mantenuto tra 4 e 30 Mbps, a 60 fotogrammi al secondo di default.
Le informazioni di configurazione del decoder (i parameter set) vengono inviate una volta, come messaggio a sé, e non ripetute in ogni fotogramma. Un telefono che si unisce a stream già avviato riceve quel messaggio e poi un keyframe.
Invio: fotogrammi scartabili, keyframe protetti
Ogni fotogramma viaggia con una piccola intestazione da 25 byte: se è un keyframe, le sue dimensioni in pixel e un orario di presentazione. Su una connessione via relay o diretta viene suddiviso in datagrammi di circa 1.080 byte, ciascuno cifrato con ChaCha20-Poly1305 usando una chiave che conoscono solo i due dispositivi. Un contatore in ogni datagramma alimenta una finestra anti-replay da 64 voci, quindi un pacchetto catturato non può essere riprodotto in seguito.
La regola per la congestione è netta: il video si può scartare, i keyframe no. Se un nuovo fotogramma è pronto mentre uno vecchio aspetta ancora di partire, quello vecchio viene sostituito, tranne che un keyframe non consegnato non viene mai sostituito da un fotogramma ordinario. Mostrare lo schermo com'è adesso conta più che mostrare ogni fotogramma mai esistito.
Su una rete domestica l'immagine viaggia invece su una propria connessione TCP, dove la rete
è abbastanza affidabile da far scattare di rado la stessa regola. Ogni socket imposta TCP_NODELAY.
Il comportamento predefinito di raggruppare le piccole scritture aggiunge decine di millisecondi a ogni salto, cosa
invisibile in un download e molto visibile quando muovi un cursore.
Recupero: la perdita si paga in immagini, non in latenza
UDP non ritrasmette, quindi un datagramma perso significa un fotogramma danneggiato. Il telefono non lo aspetta. Continua a decodificare e il danno scompare al keyframe successivo, al massimo due secondi dopo. Se noti una sbavatura dopo un brutto momento del Wi-Fi, è quello che stai vedendo. Mettere in pausa e riprendere l'immagine forza subito un keyframe.
Se il percorso veloce smette del tutto di consegnare, lo stream ripiega sulla connessione di controllo a un bitrate più basso, come descrive l'articolo sulla connessione, e torna indietro quando il percorso veloce si riprende.
Visualizzazione: adattarsi al telefono, non al Mac
Il telefono sceglie un livello di qualità e può chiedere meno fotogrammi al secondo, che il Mac limita a un intervallo ragionevole. L'app può adattare l'intero desktop allo schermo o riempirlo, e può perfino chiedere al Mac un display virtuale con la forma del telefono, così un monitor orizzontale non viene schiacciato su uno schermo verticale. I tocchi sull'immagine viaggiano nella direzione opposta, ed è l'argomento di come un tocco diventa un clic.
Domande
Quale codec video usa Peering?
H.264 o HEVC, codificato sul Mac con VideoToolbox, senza B-frame e con impostazioni a bassa latenza. L'iPhone dice al Mac quale può decodificare.
Perché l'immagine a volte sbava per un attimo?
Un pacchetto di rete perso danneggia un fotogramma, e l'immagine si ripristina al keyframe successivo, che arriva almeno ogni due secondi. Peering preferisce una breve sbavatura ad aspettare una ritrasmissione.