No Final do Dia Tá a Mesma Coisa, 1,3 GB

Por Brenner Cruvinel • 6 minutos de leitura

eu tinha certeza. ordenar as cartas por similaridade antes de encodar ia multiplicar a compressão, porque frame vizinho parecido é exatamente o que codec de vídeo gosta. tinha escrito nas apostas, tinha repetido pro agente, e o benchmark tinha me devolvido uma linha estranha: a variante com inter ficou maior que a sem. a configuração estava errada, scene cut detection ligado, e carta diferente atrás de carta diferente é um scene cut por frame. o encoder gastava ciclo procurando uma cena que não existia. desliguei e montei um segundo corpus, quase três mil reprints reais da mesma arte, agrupadas.

aí sim. com predição em grupos de dezesseis frames o arquivo ficou 29% menor que sem predição. grupos de dezesseis ganharam de um keyframe só pro stream inteiro, o que me surpreendeu, e ainda deixam qualquer carta acessível decodificando no máximo dezesseis frames. e um detalhe que eu não esperava: embaralhar as reprints em vez de agrupar custou só dois pontos. parte do ganho vem da moldura que toda carta compartilha, não da arte repetida. o codec estava aproveitando o chrome, como eu tinha desconfiado no primeiro dia, e isso valia pra qualquer ordem.

buildando o corpus inteiro de madrugada

com 29% na mão, buildei o corpus completo com ordenação por similaridade e predição ligada, e do lado o mesmo corpus sem nada disso, pra comparar. e buildei com a mídia dentro do arquivo, porque a essa hora eu já não aceitava mp4 do lado do banco. antes de chegar nisso eu abri a pasta de um build intermediário e tinha .build, .cache, .forge-state, .tmp, lock, manifest, tudo do lado de um .nest de poucos megas. pra que isso? perguntei, e a resposta honesta era que cada peça tinha motivo e nenhuma tinha que estar ali quando o build termina. a mídia dentro do arquivo era a metade da resposta, a outra era limpar a saída.

o .nest é um container de seções, cada uma com seu hash. a seção nova é a mais simples de todas: uma tabela de posições e os bytes dos vídeos, crus, colados um atrás do outro. um mp4 continua mp4, nada é recodificado pra caber. abrir o arquivo não toca na mídia, o sistema só mapeia o trecho quando alguém pede uma carta, e dá pra exportar o mp4 original de volta com o hash checado antes de gravar.

essa seção não entra no hash de conteúdo do nest, e isso importa mais do que parece. o hash de conteúdo é calculado sobre o que está dentro do arquivo, não sobre a embalagem, e é ele que faz uma citação do nest apontar pra um pedaço de conhecimento em vez de pra um lugar no disco. o mesmo corpus buildado com a mídia dentro e com a mídia fora dá o mesmo hash. custou três por cento: os índices, o texto das cartas e os vetores somam uns quarenta megas em cima de 1,3 GB de vídeo.

os builds rodaram de madrugada, e a madrugada foi ruim. dois morreram com o disco cheio, porque o macos estava tirando snapshot de sistema em ondas, comendo e soltando giga sem aviso, e a certa altura sobraram cento e trinta megas livres. e no meio disso eu li um resumo do agente dizendo que o corpus tinha 200 cartas. eu tinha reunião com o cliente em poucas horas.

"sério que você usou 200 cartas de demo? tenho reunião com o cliente e não tenho o dataset ainda." mandei rodar a validação no arquivo de 1,3 GB. os 38 mil blobs bateram um a um. o corpus estava inteiro, o resumo é que mostrava o piloto, e eu tinha lido o resumo em vez do disco. depois do encoder que não tava usando o tune que o manifest dizia, era a segunda vez na semana que a coisa que eu li não era a coisa que estava lá.

no final do dia

o build com ordenação ficou do lado do build simples. 1,3 GB os dois, diferença de nada. mandei pro agente às quatro da manhã: no final do dia tá a mesma coisa né, 1,3 GB.

o motivo estava no manifest, dessa vez certo. o nest decide por segmento se usa predição ou não, encodando uma amostra dos dois jeitos. no corpus real, de carta única, o probe vetou a predição em todos os segmentos. não tem o que prever: a carta seguinte é outra carta, com outra arte, e o chrome compartilhado não paga o custo. o ganho de 29% só existe no corpus de reprints, e esse eu ainda não buildei inteiro.

teve uma parte pior, que eu só entendi depois. numa versão anterior do probe, ele decidia só por bytes, e num build da amostra escolheu predição em todos os segmentos porque empatava em tamanho. a qualidade mediana caiu dezesseis pontos. o encoder comprime frame previsto com quantização mais grossa, e em carta única o frame previsto é um keyframe pior disfarçado. bytes iguais não são qualidade igual, e o probe agora mede os dois lados, aceita perder até dois pontos, e grava o motivo quando veta. a matriz de 29% também compara só bytes, então o número é real mas não é qualidade equivalente. deixo isso dito aqui porque eu mesmo esqueci disso por um dia.

e se o arquivo não precisar ser bonito

o que eu levo da madrugada não é o 1,3 GB. é que a minha intuição sobre codec estava errada duas vezes, e que eu leio resumo quando devia ler arquivo. agora eu só ligo ordenação quando o corpus tem near-dup, e nenhum build entra sem a validação do arquivo real rodada junto.

e ficou uma pergunta que me pareceu mais promissora do que qualquer ordenação. o gate de qualidade do nest trava o codec num nível conservador porque as métricas visuais nunca passam em carta pequena com letra miúda. mas o app do felipe tem o jpeg de cada carta em cache pra exibir. o .nest só precisa responder qual carta. se o arquivo não precisa ser bonito, até onde dá pra subir o ajuste antes da busca reclamar?