 Olá, boa tarde, meu nome é Daniel Almeida, e hoje a gente vai estar falando um pouquinho sobre virtualização, sobre decodificadores de vídeo, sobre VA API, e a gente vai estar falando sobre a relação dessas coisas com o Chrome OS e qual o papel da colabora, como a colabora tem trabalhado para melhorar a experiência de usuário, de uma pessoa que comprou um Chromebook, certo? A gente vai estar falando hoje por uns 35 a 40 minutos. E eu quero começar trazendo alguns dados, em primeiro lugar, uma pesquisa da Cisco que foi feita uns dois, três anos atrás, onde ela traz que em 2022, portanto, no ano que a gente está hoje, 82% do tráfego de internet de consumidores finais seria de aplicativos relacionados a vídeo, portanto, aí a gente pode incluir os vários streamings, a gente pode incluir o aplicativo do YouTube, etc. E o outro dado é um dado da própria Google que traz que em 2021, portanto, ano passado, a utilização de aplicativos Android em Chromebooks aumentou 50%. A gente está falando aí de uma pessoa que comprou um Chromebook, portanto, um computador que vai estar rodando o Chrome OS, lógico, e dentro desse Chromebook, a pessoa vai estar utilizando um aplicativo Android da Play Store através de uma camada de virtualização que é relativamente transparente para o usuário, e a gente vai falar bastante sobre o que é isso. E na medida em que a pessoa rode um programa Android da Play Store que vai estar fazendo decodificação de vídeo, esse programa já está utilizando o virtual video hoje, portanto, isso já faz o virtual video algo que a gente tem que ter no nosso radar, porque isso é apenas uma das aplicações. A gente pode ter inúmeras aplicações no setor automotivo, questão de infotainimento, enfim, aí fica da criatividade de cada desenvolvedor. Portanto, realmente, o virtual video vai ser um protocolo que vai ter um futuro muito extensivo pela frente. Mas antes da gente falar um pouquinho sobre o virtual video, sobre o que é o virtual video, como o virtual video já está sendo utilizado hoje em produção, a gente precisa falar do que um codec e da diferença entre um codec stateful e um codec stateless. Primeiro lugar, embora o nome codec diga a respeito a codificadores via decodificadores, para essa apresentação eu quero focar só em decodificadores. E esses termos stateful e stateless, eles dizem respeito a duas interfaces diferentes que a gente vai estar utilizando para comandar esse decodificador. Na imagem aqui, a gente pode ver um decodificador M2M, aqui a gente já está falando do caso específico de um decodificador no kernel, nov4l2, e esse nome M2M, ele faz a ferência ao fato desse decodificador trabalhar entre duas filas. Portanto, aqui do lado esquerdo, a gente pode ver que a gente tem a output queue, que seria o local onde o user space vai colocar algo chamado de bitstream, a gente vai falar em alguns segundos o que é isso, e a gente tem do lado direito uma outra fila chamada de capture queue, onde o user space vai colocar inicialmente buffers vazios e posteriormente ele vai desenfilerar buffers com os dados decodificados. Ora, o que é bitstream? Bitstream nada mais é do que a mídia, depois que ela passa por uma lógica de compressão, e essa lógica de compressão é um algoritmo que é especificado pelo codec que foi utilizado, pelo codificador que foi utilizado, cada codec no mercado, como por exemplo vp8, vp9, h.264, h.265, h.215, cada codec vai ter sua lógica de compressão e ele vai utilizar essa lógica de compressão para comprimir a mídia e no momento em que essa mídia está comprimida ela é denominada de bitstream, claro que esse bitstream ele não pode ser exibido por exemplo, por uma simples razão de que ele está comprimido, antes dele ser exibido ele precisa passar para um processo de decodificação. E para você realizar a decodificação desse bitstream, você no caso do v4all 2 stateful, que é a interface que a gente está falando no momento, você vai ter que obedecer a uma máquina de status finitos, e a gente vai estar tratando aqui para frente dessa máquina de status finitos, através da sigla em inglês mesmo, FSM de finite state machine, e essa máquina de status finitos ela existe por uma simples razão, um decodificador não pode assim que você começa a utilizá-lo, ele não pode já de imediato começar a decodificar quadros, existem diferentes etapas que você precisa passar para que você possa estar fazendo o setup desses decodificadores, então aqui a gente vê que a gente tem nós por exemplo, onde está escrito inicialização, tem um nó onde está escrito capture setup, tem um nó que está escrito decoding, que eu diria o estado talvez mais importante, que é o estado onde você realmente está decodificando quadros no loop, e ainda depois que você termina com esse decodificador você não pode simplesmente abandonar o decodificador, porque existem outros estados que você precisa trafegar até que você realmente tenha parado de decodificar 100%. Então todos esses estados, eles são codificados nessa máquina de status finitos, e a maneira que você trafega de um estado, que você muda de um estado para o outro, é através das iocotons que você vai estar executando contra um nó, que você, um nó de vídeo, ou seja, barra dev, barra vídeo zero, um, que você abriu anteriormente. Ora, dito isso, qual é a diferença entre um codec na API, na interface stateful, e um codec que utiliza API status? A diferença basicamente é quem vai estar abrigando o estado da decodificação. Ora, Daniel, o que é o estado da decodificação? Ora, muito simples. Hoje os codecs modernos, eles só codificam alguns quadros de maneira independente. Todos os outros quadros fazem referência a um quadro anterior, e esses quadros anteriores que a gente está fazendo referência vão ser chamados de quadros de referência. Portanto, esses quadros de referência que a gente vai estar utilizando para decodificar o quadro atual, eles fazem parte desse estado da decodificação. E não só isso, a gente também vai ter um componente chamado de parser, que vai estar ali lindo, a bitstream, e à medida que ele vai lendo, ele também pode guardar um estado, e assim sucessivamente todo esse estado, no caso de um codec stateful, ele é armazenado pelo driver e ou firmware. Na medida em que um codec stateless, ele vai fazer o armazenamento desses dados no próprio user space, e não no driver. Então, essa seria a diferença de um interface stateful para um interface stateless. A interface stateless, ela não armazena o estado, quem armazena o estado, vai ser o próprio aplicativo rodando user space, que vai ter que fazer a administração desse estado, e apenas retransmitir o estado, na medida em que ele queira decodificar um quadro. Ao passo que a interface stateful, o user space não precisa fazer nada disso, a implementação do user space vai ser bem mais simples, ele vai apenas mandar os buffers para o driver, o driver vai armazenar, seja no driver, seja no firmware, ele vai armazenar todo esse estado e ele vai operar como se fosse uma caixa preta, decodificando e voltando os buffers com os dados já decodificados. Agora a gente pode falar sobre o ArcVM, porque o ArcVM vai ser essa camada que vai estar fazendo essa virtualização, que vai estar fazendo um usuário, por exemplo, no Chrome OS, para esse usuário rodar um aplicativo Android dentro do Chrome OS de uma maneira quase imperceptível, sem precisar lançar a mão de algo que a gente chama de developer mode no Chromebook, que facilita as coisas. E essa camada, o ArcVM ela já é utilizada em produção e alguns Chromebooks de ponta, e a tendência que ela seja cada vez mais utilizada na medida em que novos modelos de Chromebook são lançados. Isso quer dizer que o usuário vai poder decodificar, ele vai poder utilizar aplicações nativas da Play Store, como por exemplo o aplicativo do Netflix, do YouTube, um jogo onde esse jogo queira fazer uma decodificação de vídeo, por exemplo, no Chromebook dele, com velocidade de decodificação quase nativa, utilizando ali o hardware do próprio Chromebook, ainda que o aplicativo esteja rodando em cima do Android e não em cima do Chrome OS, especificamente, através de uma camada de virtualização. E toda vez que o que o usuário faça isso, ele vai estar utilizando o Voraio vídeo. E aí, como que isso se dá? Para a gente entender como que isso se dá, a gente precisa primeiro falar sobre o que é Voraio. Voraio é uma família de dispositivos virtuais que vão se comportar como se fossem dispositivos físicos. Ora, Daniel, o que você quer dizer? O que eu quero dizer é que um programa rodando no user space do Guest, ele não precisa saber que ele está lidando com um dispositivo virtual. Na percepção desse programa, ele vai estar lidando com um dispositivo físico. E o próprio protocolo Voraio, ele vai possibilitar toda essa virtualização de modo transparente. E esse protocolo, os dispositivos Voraio, geralmente, são implementados com duas interfaces diferentes, vai ter um interface que a gente vai chamar de Viber, que ele vai implementar a interface do Guest, ele vai ser geralmente implementado como módulo do kernel, por exemplo, o Voraio GPU, o Voraio vídeo, enfim, como módulo. E o device, ele vai ser uma implementação que vai fazer a parte do host, vai fazer a interface do host e ele vai ser implementado na virtual machine manager, por exemplo, no cross VM ou no QMU. E o Voraio, ele é uma maneira da gente ter o que a gente chama de para-virtualização. Ora, o que é para-virtualização? Na virtualização que não utiliza para-virtualização, o Guest não sabe que ele está sendo virtualizado. Por não saber que ele está sendo virtualizado, ele pode, por exemplo, tentar acessar diretamente dispositivos, porque ele não sabe, ele pensa que ele está em cima do hardware, mas na verdade ele não está, ele está em cima de outro sistema operacional, porque ele está sendo virtualizado. E ao tentar acessar diretamente um dispositivo, ele não vai conseguir. Quando ele não consegue, ele volta para virtual machine manager, por exemplo, para o QMU, para o cross VM, enfim, ele pede que essa solicitação seja concluída de alguma maneira. Essa transição é muito custosa, certo? Então essa solução de emulação, ela geralmente tem um grande, um hit grande na performance. Ao passo que quando a gente usa para-virtualização, como por exemplo, quando a gente usa o Verdeo, a gente ao invés de estar se comunicando, pedindo para que a máquina virtual, o virtual machine manager, emule o dispositivo, a gente vai ter uma estratégia mais inteligente, a gente vai se comunicar através de memória, a gente vai compartilhar a memória, compartilhar buffers e depois de uma maneira acíncrona, o device vai poder processar esses buffers, sem que a gente, a cada acesso, precise estar passando por essa instrução, esse contact switch, por exemplo, entre o guest e entre a máquina virtual. A gente pode fazer vários requests de uma vez só e no momento oportuno, de maneira acíncrona, o device vai ver que existem vários requests infilerados, infilerados onde, onde esses buffers estarão infilerados. E é algo que a gente vai chamar de vertq, a gente vai tratar bem a respeito disso daqui a pouco. Então o device vai ver que tem esses buffers infilerados na vertq, ele vai tirar, desinfilerar esses buffers e vai fazer um processamento, na medida que seja conveniente para ele, caso esse processamento ele dê origem a algum tipo de resposta, ele vai colocar essa resposta de volta num buffer utilizado, vai infilerar esse buffer novamente na vertq e aí sim o driver vai poder desinfilerar esse buffer e fazer uso dessa resposta, caso seja necessário. Isso melhora muito as taxas de transferência, mas por outro lado isso vai demandar muito mais, não muito mais, mas vai demandar mais código. Ora Daniel, como assim vai demandar mais código? Alguns dos lados atrás a gente viu que a implementação de um dispositivo Voreo ela é feita em duas metades, por assim dizer, uma parte da implementação é feita no kernel do guest e outra parte da implementação é feita no Roche, na virtual machine manager. E essas implementações você vai ter que desenvolver. Mas na medida em que você escreve esse código, que você paga esse custo inicial, dali para frente você vai ter uma performance muito melhor, uma taxa de transferência muito melhor no seu dispositivo. E aí a gente pode falar um pouco sobre o fluxo de trabalho do Virtio em geral, a gente vai ter uma etapa de inicialização, nessa etapa de inicialização a gente vai ter um handshake, vamos assim dizer, onde o device e o driver vão combinar os tipos de features que eles aceitam de maneira mútua. Depois dessa etapa de virtualização a gente vai ter uma transferência de buffers através das vertq, porque a gente pode ter mais de uma vertq, onde o driver por exemplo supõe um fluxo de trabalho do driver para o device, mas não precisa ser necessariamente dessa maneira, a gente pode ter um fluxo também do device para o driver, no sentido oposto, a gente pode ter mais de uma vertq, onde uma vertq seja implementar um fluxo do driver para o device, é outro implementar um fluxo contrário do device para o driver, mas por exemplo, em um fluxo do driver para o device, o driver vai colocar as solicitações na fila, portanto, só lembrando, mais uma vez o driver implementa a parte do gash, então o gash coloca essas solicitações na fila, ele enfilera esses buffers numa vertq, e o device vai processar esses buffers de maneira acíncrona, como for conveniente, ele vai colocar esse buffer utilizado na fila novamente, desculpa, caso haja alguma resposta, e esses passos, esses dois últimos passos, eles vão ocorrer em loop, até que não haja mais nenhum tipo de comunicação que precisa se dar entre gash e roche, e a partir daí existe uma etapa de limpeza. Cada dispositivo, o Voraio, por exemplo, o Voraio GPU, é um dispositivo, o Voraio Video, um outro dispositivo, cada dispositivo, cada protocolo separado do Voraio, vai poder decidir no número, na quantidade das vertqs, e o que essas vertqs querem dizer. Mas isso aí, o Voraio em geral, e o Voraio Video é especificamente, né? Ora, o Voraio Video vai ser um dispositivo Voraio, que vai adicionar suporte para decodificadores e codificadores, utilizando o mesmo protocolo, certo? O protocolo, o Voraio Video, ele já foi proposto na... na... na main list, a última versão que foi proposta, é a RFC V5, e ele ainda está sendo trabalhado, ele é Work in Progress, o driver, por sua vez, também é Work in Progress, e ele é baseado numa implementação do Voraio GPU, que já é bem madura no kernel, certo? E o driver está um pouco atrasado, a última submissão, ela implementa a versão V3 do protocolo, é na medida em que o protocolo já está na versão V5, e em breve o Google vai estar lançando a versão V6. Ele foi desenvolvido de maneira inicialmente independente por duas empresas, a Google e a Open Synergy, e a partir do momento que as pessoas, os sonários da Google, mandaram a primeira versão em upstream, notou-se que tinham duas empresas trabalhando basicamente da mesma coisa, de maneira independente, e essas duas implementações foram fundidas na V3, de maneira que já na V3 só existe um protocolo Voraio Video sendo... desenvolvido, certo? E o Voraio Video, desculpa, ele conta com duas vertikills, uma vertikill vai ser acamente kill, que é onde a gente vai colocar as solicitações do driver, do gash, para o device, e a outra vai ser a EventKill, que vai fazer o sentido contrário do device para o driver. Na medida em que o device esteja processando, ele encontra por exemplo um erro, ou uma mudança de resolução, ele pode estar comunicando ao driver esse tipo de situação através da EventKill. E o ponto chave é que o Voraio Video ele pode ser utilizado para implementar aquela máquina de status finito do V4O2 Stateful. Olha, e por que isso é importante? Porque se eu implemento uma máquina de status finitos, essa máquina de status finitos da V4O2 Stateful, eu estou automaticamente dando suporte a uma interface madura, se não me engano, o desenvolvimento começou... lembra-se, foi em 2013, mas enfim, uma interface que já tem muito suporte no user space, uma interface que já é muito consolidada, e também uma interface que nos é conveniente. Porque caso você se lembre, a gente falou lá atrás, que essa interface ela trabalha de uma maneira como se fosse uma caixa preta. O user space, ele submete os buffers com os dados, ele não sabe o que está acontecendo lá dentro, que tem uma grande derrugação lá dentro, e ele recebe, o sol que ele sabe, é que em um determinado momento ele vai receber esses dados decodificados de volta. Para a gente isso é muito bom, porque nesse modelo de caixa preta a gente pode simplesmente ter toda uma etapa de virtualização por trás, de uma maneira que esse user space nem fique sabendo, e a gente devolve simplesmente o buffer decodificado. Ora, como funciona essa tradução? Porque em algum momento o nosso user space ele vai estar falando com essa interface do v4l, que não entende nada de v4l. E o lado que vai estar fazendo a decodificação no rosto, ele vai estar falando com uma interface de v4l, que não entende nada de v4l. Então, fica claro que aí precisa ter uma etapa de tradução. Como vai ser essa tradução? Ora, na medida em que o user space no gaste, ele executa as ioctos, que a gente falou, contra o node video, contra, por exemplo, dev barra-dev barra-video zero, barra-dev barra-video 1, etc. Conforme ele vai executando essas ioctos para enfleirar buffers, para pedir, também que esses buffers sejam decodificados, para desenfleirar o buffer, para mapear o conteúdo daquele buffer no seu address space, conforme ele vai executando essas ioctos, o canal driver, que está rodando novamente no gaste, ele vai traduzir essas ioctos para os seus comandos equivalentes do rail video, e na medida em que ele faça a tradução, ele adiciona esses comandos da comenda que o pré-processamento pelo ruche. Então, vamos ver mais uma vez essa máquina de estados finitos, está aqui com, se não me engano, e aí a gente vai ver um exemplo de tradução. Ora, um exemplo que eu escolhi, um exemplo do videoc create buff, do videoc rack buff, que são duas chamadas, duas ioctos para a gente alocar buffers, para que a gente possa posteriormente enfleirar esses buffers, caso a gente se lembre lá atrás dos slides anteriores, a gente precisa antes pedir para que a alocação desses buffers seja feita, para depois a gente mapear esses buffers no nosso address space, a gente copiar alguns dados, e a bitstream dentro do buffer, da output queue, e depois a gente enfilerar esse buffer. Ora, como é que isso vai ser feito? O gash não sabe que está tendo uma camada de virtualização, ele vai pedir, ele vai, através da ioctos, pedir que esse buffer seja criado. O driver do virtual video rodando no gash, vai traduzir isso para um comando específico do vrio, que no caso é o vrio command resource create. Esse comando vai ser colocado na camada de queue, ele vai ser processado pelo device, o device que agora está rodando no roxo dentro da virtual machine manager, por exemplo, dentro do queue em mil, dentro do cross em, no nosso caso, dentro do cross em, que a gente vai ver mais para frente, que não tem implementação ainda do queue em mil, ele vai se comunicar com uma caixa preta, que a gente vai falar mais adiante do que é isso, e ele vai, essa caixa preta ela vai fazer, ela vai trabalhar, solicitação, ela vai devolver essa solicitação, essa solicitação pode ter algum tipo de resposta, utilizado na camada de queue, o driver do virtual video rodando no gash, vai ver, que ele tem um buffer utilizado ali, ele vai desenfilerar esse buffer, ele vai extrair essa resposta, e a partir daí ele pode processar essa resposta para atualizar as suas próprias estruturas de vídeo, e para converter essa resposta, numa resposta do v4l2, porque novamente o user space rodando no gash, ele só entende de v4l2 stateful, não entende de v4l2 stateful, não sabe inclusive o que está tendo uma camada de virtualização por trás, e aí a gente ao fazer essa tradução, a gente vai ter aí uma virtualização acontecendo, e a única coisa que a gente vai precisar trabalhar melhor é o que seria aquela caixa com interrogação, só para uma questão de ser mais completo, eu trouxe todos os comandos que podem, na versão 5, podem estar na camada de kill, então a gente tem crew caps, stream create, stream destroy, resource attach, que são vários comandos que o driver pode traduzir as iocals que estão vindo do user space no gash, ele pode traduzir em alguns desses comandos, em uma combinação desses comandos e colocar na camada de kill, e os comandos que podem ir na event kill, por enquanto são o event error, que diz que houve um erro na decodificação, e o decoder resolution changed, que diz que o device estava processando aquela mídia e encontrou uma mudança de resolução, por exemplo, de hd para full hd, pode acontecer para determinados codecs, e quando isso acontece, geralmente a gente vai precisar refazer a locação, portanto é uma das que o driver vai... é a forma que o device vai poder falar para o driver que isso aconteceu é enfileirando esse evento na event kill, e isso é o que a gente tem até a v5, a medida em que a gente vai ter novas interações do protocolo esses comandos podem sofrer alterações, e a gente tem a criatura até então, a gente vai ter o gash fazendo as iocals contra o driver, o driver traduzindo essas iocals para o ver.io, a gente vai ter o virtual machine manager falando com uma caixa preta, essa caixa preta, eventualmente vai decodificar, vai voltar os quadros para o virtual machine manager, o virtual machine manager vai voltar os quadros para o driver do virtual video, o dano do gash, e o gash vai voltar esses quadros para o aplicativo em user space. Ora, vamos só fazer aqui uma breve explicação sobre o cross-vm, o cross-vm é um virtual machine manager, que ele é disponibilizado de maneira conjunta, com Chrome OS, ele é escrito em Rust, e o foco dele é em dispositivos para virtualizados em especial dispositivos do ver.io, porque ele objetiva ter essa virtualização de uma maneira veloja, uma maneira rápida, para que você não tenha uma queda da performance, por exemplo, quando o usuário for estar utilizando um aplicativo Android dentro do Chromebook. E o que seria essa caixa sombreada que a gente tanto vem falando? Essa caixa sombreada ela é um dos backends. Ora, inicialmente aqui no cross-vm a gente só suportava um backend, que era o libvdl e usava um processo de GPU do Chrome, para codificar e decodificar o vídeo com a aceleração em hardware. Ora, a aceleração em hardware geralmente tem uma performance muito boa, então, maravilha. Só que ela adiciona o Chrome como dependência. Então, qual que é o problema? A pessoa que está utilizando um cross-vm que é um virtual machine manager vai depender de um navegador, que é um outro tipo, uma outra classe de programa, certo? E essa pessoa também ela não vai conseguir utilizar esse backend se ela não tiver um Chromebook. Por que, por exemplo, o cross-vm pode ser utilizado no Linux, embora ele seja distribuído com Chromebook, faça parte do ChromeOS, aí pode muito bem ser utilizado no Linux hoje, como você utiliza o kiomio no Linux hoje. Mas caso você faça isso, você não vai ter o suporte para estar decodificando simplesmente pela razão de que a libvdl não existe fora dos Chromebooks, ou seja, não era possível nem desenvolver, nem utilizar o virtual video, se a pessoa não tivesse um Chromebook. O próximo backend que foi gerado foi o ffmpeg ele vai utilizar os decodificadores de vídeo do ffmpeg para decodificar os quadros, só que ele ainda não vai ser utilizado em produção por uma simplização, ele novamente tem o problema da dependência, porque ele vai usar todo o ffmpeg como dependência, enfim, um componente muito grande do ffmpeg melhor dizer, e esse componente como todo o resto do ffmpeg, ele é escrito em C, que não é uma linguagem que vai ter todas as garantias de memória do Rust. Então por conta disso a gente agora vai tratar do backend que é o foco do trabalho da colabra, que é o backend VAPI. Ora, o backend VAPI, ele vai utilizar o driver do VAPI do sistema para decodificar a mídia, ou codificar no futuro, utilizando a salaração em hardware através da própria GPU do Chromebook. E ele é o working progress, ele hoje consegue decodificar a vp8, h264 e novos codecs surgirão no futuro, na medida em que a gente adiciona o código suporte para esses ovos codecs. Só que tem um detalhe A VAPI ele é um API stateless, e caso a gente se recorde o driver do virtual video no gash ele vai implementar, ele vai disponibilizar um interface stateless, então a gente novamente vai precisar fazer uma conversão, uma segunda conversão que vai ser a conversão de um interface stateless por interface stateless Daniel, como que isso vai se dar? Vamos se lembrar da diferença das interfaces stateless. Ora aqui na interface stateless é o mesmo diagrama que a gente tinha antes, só que eu fiz questão de aqui mostrar que dentro dessa forma a gente tinha um parser e no diagrama da interface stateless eu fiz questão de mostrar que mesmo user space a gente ainda tem um parser que vai ser um código escrito em user space, que vai estar por exemplo dentro do streamer, vamos dizer, mas ele ainda existe. Ora, a tradução que a gente vai fazer é a seguinte, o decodificador ele precisa ser implementado no hypervisor de alguma maneira, porque a gente viu nos últimos dois quadros que esse decodificador ele é um componente que ele existe, então ele precisa ser implementado em algum local, se ele não é implementado no firmware, se ele não está implementado na user space do gash ele vai ser implementado no virtual machine manager, no nosso caos no cross-vm. O parser ele também era uma caixinha que estava nos dois tanto no state quanto no state, porém em locais diferentes e pela mesma lógica se ele não está em user space, se ele não está no firmware ele precisa ser implementado no hypervisor. Então o hypervisor vai ser a parte que vai manter o estado da decodificação e ele vai retransmitir esse estado da decodificação para o VA API a cada quadro. Ora, vamos tratar um pouco agora do back-end do VA API em específico, e aqui nesse slide vocês podem ver a arquitetura vocês vão ver que inicialmente a gente vai ter alguns componentes como parser, como decodificador esses componentes eles vão falar com um outro componente, que é escrito em rustigura a gente vai falar mais ou menos o que é isso em breve esse componente ele vai falar com a biblioteca da Libve no sistema essa biblioteca ela vai falar com kernel através do DRM e até agora ninguém sabe decodificar a mídia, ninguém sabe decodificar a mídia mas quem sabe decodificar a mídia? A GPU, por que a GPU sabe decodificar a mídia? Porque a GPU vai ter uma parte do silício, ela vai ter um circuito específico que foi criado com esse propósito, com propósito de decodificação e implementa o codec silício no próprio chip então a GPU vai fazer a decodificação dos quadros e aí ela vai devolver esses quadros para o DRM, que vai devolver para o driver que vai devolver para a biblioteca que vai devolver para o cross-vm e isso a gente precisa ter em mente que todos esses blocos eles apresentam apenas o bloco com a interrogação então quando os quadros chegam nesse bloco com a interrogação eles ainda vão ter que voltar para o cross-vm vão ter que voltar para o driver já no gash, porque tem então a gente estava no roxo e aí sim o driver do virtual video vai disponibilizar esses drivers para o user space e user space não vai ficar sabendo que toda essa camada de virtualização existiu, então vamos trabalhar aqui rapidamente cada bloco do decodificador o parser, como a gente já falou eles traem os metadados do bittreem e aqui cabe mais uma vez uma explicação por que a gente precisa desses metadados por que VAPI é um backend state então ele não guarda nenhum tipo de estado nós que precisamos prover esse estado a cada quadro como a gente prover esse estado a gente extrai os metadados a gente usa esses metadados para atualizar o nosso estado interno e a gente também usa esses metadados para preencher estruturas do VAPI que a gente vai mandar para o VAPI quando a gente precisar decodificar um quadro esse parser ele vai disponibilizar esses metadados para o decodificador por sua vez, vai utilizar esses metadados para preencher as estruturas do VAPI ele vai utilizar esse módulo, que em Rust a gente vai chamar de Crate, esse módulo que envolve essa biblioteca do libv do sistema vai utilizar esse módulo para solicitar uma operação de decodificação e na medida em que os quadros foram decodificados ele vai administrar esses quadros de referência quais são o conjunto de quadros de referência e o resto do estado da decodificação e a Session ela vai conter o estado do dispositivo para uma única sessão de reprodução de mídia porque você pode, por exemplo, ter dois aplicativos em Space, cada um decodificando mídia, mas cada um desses vai dar início a uma Session diferente com o seu próprio estado essa Session vai implementar uma parte da lógica da máquina de estado infinito porque a gente precisa disso uma hora essas coisas aparecem na nossa implementação porque a gente precisa dar suporte a ela porque do lado do gaste é ela que está sendo trabalhada o gaste nem sabe novamente que está tendo uma camada de virtualização e essa Session ela também vai conter um código compartilhado entre vários codecs porque a gente tem suporte a mais de um codec e por ultima a gente vai falar dessa wrapper crate que novamente a gente pode entender como se fosse um pacote em outras linguagens, um módulo que é uma forma de a gente converter uma API sem segura, olha em Rust a gente chama de um seguro por exemplo uma função que é definida em outra linguagem uma função que é definida em C porque C é uma linguagem que não vai dar a segurança de memória que Rust tem então cabe a nós e isso é uma maneira bem normal, bem cotidiana no ecossistema do Rust Criancia é módulos separados onde esse módulo vai conter todas as chamadas em seguras e nesse módulo a gente vai fazer a nossa verificação para garantir que a gente não tenha nada de errado não tenha um ponteiro zerado não tenha enfim uma corrupção de memória a gente garante ali naqueles pontos específicos e a partir do momento que a gente garantiu isso todo o nosso uso vai ser em Rust seguro e a gente vai poder ter todas as segurança de Rust e também para frente também essa caixa vai utilizar a técnica de RAI que ela vai impedir o vazamento de recurso porque na medida em que as coisas saem desculpa elas automaticamente elas vão rodar um destrutor que em Rust a gente chama de Drop e esse destrutor ela vai fazer a chamada inversa que vai administrar a live do sistema para desfazer o que a gente fez por exemplo no construtor que não tem nenhum recurso base e essa caixa ela vai utilizar algo chamado de Binding que é algo do ecossistema de Rust para gerar esses bindings de FFI para a gente estar se comunicando com as funções em C e por último ela é ligada dinamicamente a biblioteca LVA que está disponível no sistema disponível no Chromebook de tudo isso a gente já está indo para o final quero falar um pouco do que está em Backlog um dos primeiros planos são novas alterações do protocolo do VIRTIO video o upstream desse protocolo porque por enquanto a gente só propôs não teve o upstream de fato a gente vai ter suporte para mais codecs um por exemplo 8VC, AV1 que são os codecs que praticamente são estado da arte a gente vai colocar suporte para codificadores muito embora o foco inicial seja um decodificador porque isso é o que é mais utilizado e as pessoas querem decodificar vídeos muito mais do que codificar mas o suporte para codificadores vai ser utilizado vai ser criado, perdão e a gente vai ter um suporte para back-end me for out to stateless por que? porque existem por exemplo Chromebooks que não tem GPU da Intel por exemplo e esses Chromebooks eles não estão abraçados pela LVA portanto a gente vai precisar de um outro back-end que outro back-end vai ser por exemplo me for out to stateless quando a gente utilizar esse back-end ao invés de fazer a conversão para VA aqui na etapa final a gente vai fazer a conversão por exemplo para ver for out to stateful dependendo do Chromebook que a gente esteja utilizando a gente pode escolher um back-end ou outro quando esses back-ends verem a existir aqui também tem uma questão muito importante se é suporte para QMU atualmente não temos suporte para QMU mas mesmo as comunidades já demonstraram o interesse inicial não tem nenhum tipo de de blocker de nada que impeça que o QMU recebam a implementação do VRail video e aí por último eu quero trazer um resumo que resume bem o que a gente já falou aqui durante esses 30 e poucos minutos o VRail video já está por trás da decodificação de muitos Chromebooks hoje ou seja, já tem um número considerado de usuários mas hoje essa decodificação dá ver que é um tipo de biblioteca que a gente não quer utilizar pelos motivos que a gente já trouxe pela dependência do Chrome, fato de não funcionar fora do Chromebook e a colabora tem trabalhado com os engenheiros do ChromeOS para remover essa dependência e a gente vai colocar no lugar dessa dependência um back-end simples via API que também vai fazer decodificação acelerada em hardware portanto também vai ter uma performance muito boa que significa uma performance quase nativa para decodificação de vídeo em aplicativos Android dentro do ChromeOS isso fará com que o VRail video seja uma tecnologia mais robusta isso fará com que as pessoas consigam desenvolver o VRail video sem necessariamente ter um Chromebook e isso vai ser cada vez mais popular na medida em que novos Chromebooks surgem no mercado e novos Chromebooks Estus que tenham suporte a essa camada nova de virtualização que é o ArchVM isso quer dizer que os usuários cada vez mais vão conseguir desfrutar de aplicativos de vídeo na Play Store que a gente já falou, do aplicativo do YouTube da Netflix, de outros streamings de jogos que tenham ali dentro algum vídeo que precisa de um eventual decodificação e isso é apenas uma das aplicações que a gente tem hoje volta, torna a dizer que novas aplicações ficam aí a cargo da criatividade cada empresa de cada desenvolvedor para seu próprio setor, para o setor automotivo enfim, para N e outras aplicações e aí eu quero terminar essa nossa conversa fazendo aqui uma pergunta de brincadeira que seria a seguinte quais aplicações vocês vão criar utilizando VRail video no futuro é isso, meu nome é Daniel Almeida trabalho na colabora e espero que essa apresentação tenha elucidado que o VRail video, como ele pode ser utilizado e onde a gente tá com VRail video hoje de 2022