Peering

Peering / Blog

Como o Peering transmite a tela do seu Mac para o seu iPhone

Uma área de trabalho remota é um fluxo de vídeo com uma exigência incomum: quem assiste é também quem controla. Cada escolha de projeto abaixo vem de manter esse ciclo curto.

Captura: peça a imagem ao sistema

O app do Mac usa o ScreenCaptureKit, da Apple, para obter os quadros. A origem pode ser uma tela inteira, todas as janelas de um app ou uma única janela, e você pode alternar entre elas sem derrubar a conexão. É também por isso que o macOS pede a permissão de Gravação de Tela na primeira vez: sem ela, o Mac só consegue entregar uma imagem preta.

Uma área de trabalho do Mac com um editor de código aberto, transmitida ao vivo para um iPhone com o Peering.
A imagem no iPhone é um fluxo de vídeo codificado, não uma série de capturas de tela.

Codificação: baixa latência, sem reordenação

Os quadros vão para o codificador VideoToolbox, da Apple, no Mac, como H.264 ou HEVC, o que o iPhone disser que consegue decodificar. Os ajustes são o oposto do que um serviço de streaming usa:

As informações de configuração do decodificador (os conjuntos de parâmetros) são enviadas uma vez, como uma mensagem própria, e não repetidas em cada quadro. Um iPhone que entra no meio da transmissão recebe essa mensagem e depois um keyframe.

Envio: quadros descartáveis, keyframes protegidos

Cada quadro viaja com um pequeno cabeçalho de 25 bytes: se é um keyframe, o seu tamanho em pixels e um horário de apresentação. Em uma conexão por relay ou direta, ele é cortado em datagramas de cerca de 1.080 bytes, cada um selado com ChaCha20-Poly1305 usando uma chave que só os dois dispositivos conhecem. Um contador em cada datagrama alimenta uma janela de repetição de 64 entradas, então um pacote capturado não pode ser reproduzido depois.

A regra para congestionamento é direta: o vídeo é descartável e os keyframes não. Se um quadro novo estiver pronto enquanto um antigo ainda espera para sair, o antigo é substituído, exceto que um keyframe não entregue nunca é substituído por um quadro comum. Mostrar a tela como ela está agora importa mais do que mostrar todos os quadros que já existiram.

Em uma rede doméstica, a imagem viaja por uma conexão TCP própria, onde a rede é confiável o bastante para que essa mesma regra raramente precise ser aplicada. Todo soquete define TCP_NODELAY. O comportamento padrão de agrupar pequenas gravações acrescenta dezenas de milissegundos a cada salto, o que é invisível em um download e muito visível quando você move um cursor.

Recuperação: a perda se paga em imagem, não em latência

O UDP não retransmite, então um datagrama perdido significa um quadro danificado. O iPhone não espera por ele. Continua decodificando, e o dano some no próximo keyframe, a no máximo dois segundos. Se você notar um borrão depois de um trecho ruim de Wi-Fi, é isso que está vendo. Pausar e retomar a imagem força um keyframe imediatamente.

Se o caminho rápido parar de entregar por completo, a transmissão recorre à conexão de controle, com uma taxa de bits menor, como o post sobre a conexão descreve, e volta quando o caminho rápido se recupera.

Exibição: ajustar ao iPhone, não ao Mac

O iPhone escolhe um nível de qualidade e pode pedir menos quadros por segundo, valor que o Mac limita a uma faixa razoável. O app pode ajustar a área de trabalho inteira à tela ou preenchê-la, e até pedir ao Mac uma tela virtual com o formato do iPhone, para que um monitor horizontal não seja espremido em uma tela vertical. Os toques na imagem seguem o caminho contrário, assunto de como um toque vira um clique.

Perguntas

Qual codec de vídeo o Peering usa?

H.264 ou HEVC, codificado no Mac com o VideoToolbox, sem B-frames e com ajustes de baixa latência. O iPhone diz ao Mac qual dos dois consegue decodificar.

Por que a imagem às vezes borra por um instante?

Um pacote de rede perdido danifica um quadro, e a imagem se recupera no próximo keyframe, que chega pelo menos a cada dois segundos. O Peering prefere um borrão breve a esperar por uma retransmissão.