Streaming Media East 2008

Streaming Media East 2008Nesta sexta-feira (16/05) estarei embarcando para Nova York, para o Streaming Media East 2008, um evento voltado para o mercado de distribuição de mídia na internet, e acho que será bastante proveitoso. Este ano a agenda está especialmente interessante, já que teremos mais discussões sobre H.264, o que comprova mais uma vez que este será o codec da nova geração de vídeos na Web e responsável pela tão esperada convergência entre TV e Internet. Além disso, outro assunto que será bastante falado é sobre como ganhar dinheiro com a distribuição de vídeos na internet, ou seja, qual é a melhor forma de inserir peças publicitárias sem prejudicar a experiência do usuário.

Também devo assistir sessões de CDN e P2P, já que em termos de delivery o mercado ainda está bem atrasado, e, usar HTTP unicast certamente não vai atender a crescente demanda existente.

Finalmente, para ninguém dizer que eu tenho má vontade e preconceito com as soluções da Microsoft, devo assistir um workshop de Silverlight. Ainda tenho esperanças de que alguém encontre um argumento à favor do Silverlight, porque até agora está bem difícil.

Bom, irei postar diariamente sobre as novidades, então, podem conferir o que está rolando por aqui.

Advertisements

Scrum, e os benefícios para os Team Members

Freqüentemente leio posts e artigos sobre a utilização do Scrum, entretanto, na maioria das vezes, existe uma grande ênfase nos benefícios obtidos com ele do ponto de vista da empresa, como o aumento na velocidade das entregas, e nem sempre é discutido sobre o que os team members ganham, quais as vantagens para as pessoas que efetivamente desenvolvem as tarefas. Desta forma, achei que seria interessante expor aqui um pouco da experiência que estou tendo na Globo.com, onde atuo como team member de uma equipe desde que adotamos o Scrum oficialmente.

Algumas pessoas, em um primeiro contato com o Scrum, podem apresentar um certo receio sobre uma das prerrogativas propostas pelo framework, que é a disseminação de conhecimento por todo time, com o objetivo de reduzir as chamadas “ilhas de conhecimento” nas equipes. Isto é excelente do ponto de vista da empresa, porém, infelizmente alguns profissionais que detém um conhecimento específico pensam que seu emprego estará “garantido” enquanto ele for o único a dominar determinado assunto. Entretanto, a disseminação do conhecimento por todo time é extremamente positiva para o desenvolvimento profissional de cada um, uma vez que o conhecimento específico de cada membro é compartilhado, estabelecendo uma “via de mão dupla”.

Além disso, cada componente do time é livre para executar qualquer tarefa, seja ele ou não o especialista no assunto. Desta forma, esta transferência de conhecimento pode ser realizada de acordo com a vontade de cada um, até o ponto que o desenvolvedor irá fazer tarefas simples de design, e o designer irá implementar trechos simples de código.

Outro benefício bastante importante é a existência um escopo claro e bem definido daquilo que deve ser realizado, o que evita uma série de transtornos. Ninguém vira a noite se matando para implementar uma funcionalidade não prevista, ou alterando o que foi feito pois houve uma mudança de idéia. No Scrum existe um “compromisso público” que define o que será realizado, não existe margem para alterações não aprovadas pelo próprio time. Além disso, a existência de um backlog priorizado permite uma visão mais clara daquilo que deverá ser realizado, qual é a estratégia e os objetivos existentes.

A existência de reuniões diárias (daily meetings), também ajuda bastante no processo de comunicação entre os membros do time, sendo que cada um sabe exatamente o que o outro fez, e o que irá fazer, e isto é extremamente importante para todos tenham uma visão bem clara do que está sendo feito, quais foram os desafios e como eles foram superados. Finalmente, ao término de cada ciclo (sprint), cada um pode expressar o que foi bom ou ruim no último sprint o que facilita bastante a resolução de problemas de qualquer natureza.

Em suma, o Scrum pode ser bastante positivo também para os profissionais, basta saber aproveitar as novas oportunidades abertas por este modelo de desenvolvimento, em vez de ficar com medo das mudanças que naturalmente vão acontecer.

Escolhendo a melhor arquitetura para delivery de vídeos

Apesar de parecer algo simples, a escolha correta de uma arquitetura de delivery de mídia é tão fundamental para o serviço quanto a definição dos parâmetros de codificação, isto porque ela também pode impactar de forma decisiva na qualidade da experiência do usuário. Distribuir um vídeo que demora muito para carregar, ou que “trava” constantemente, muitas vezes é pior do que ter uma experiência contínua porém com pior qualidade. Por isso, a escolha da arquitetura de delivery está fortemente atrelada ao target bitrate escolhido.

Existem duas formas básicas de se distribuir vídeos na internet: via Streaming ou Progressive Download. O streaming é a tecnologia que permite o envio de informação através de pacotes, que são solicitados sob demanda pelo cliente, ou seja, o cliente solicita ao servidor apenas os pacotes necessários para exibir o conteúdo em um determinado momento. Uma vez consumidos, os pacotes deixam de existir na máquina do cliente. O progressive download, nada mais é que um simples download, porém com a vantagem de que o usuário pode começar a reproduzir o conteúdo sem que seja necessário que o download esteja finalizado. No progressive download, o conteúdo é efetivamente copiado para a máquina do usuário, e, de acordo com as diretivas de cache, pode ficar armazenado lá por um determinado período de tempo.

Vocês agora podem se perguntar qual dessas duas opções é melhor, e a resposta é simples: depende dos seus objetivos e das características do cenário em que a solução será utilizada. Simplificando, você deve se fazer as seguintes perguntas antes de escolher qual modelo de distribuição será utilizado:

  • Qual o target bitrate total dos vídeos que serão distribuídos?
  • Qual é a largura de banda disponível média dos usuários que irão acessar o conteúdo?
  • A segurança do conteúdo é uma prioridade? (Pirataria)
  • Os custos da infra-estrutura são um fator limitante?

Se suas respostas indicam que a largura de banda disponível média dos usuários é pelo menos 20% maior que o target bitrate total dos vídeos que serão distribuídos, então a situação é bastante confortável, e a escolha entre streaming e progressive download será decidida nas outras duas questões. Caso a segurança seja uma preocupação primordial, ou seja, o conteúdo oferecido é altamente sensível à pirataria, então recomendo fortemente a utilização do streaming. Isto porque o conteúdo distribuído via streaming não fica armazenado no cliente após a reprodução, o que dificulta um pouco as coisas para o lado de quem quer copiar. Além disso, não é possível fazer o download do arquivo através de um simples GET HTTP, já que a maioria dos servidores de streaming utilizam protocolos diferentes (rtmp para Flash e rtsp para WMV). Entretanto, não pense que será impossível copiar o conteúdo, já que existem alguns programas que “tocam” o vídeo como se fossem um player, mas na verdade estão copiando o bitstream para um arquivo local (WMRecoder, etc).

Por outro lado, ainda no cenário ideal onde a disponibilidade de banda é maior que o target bitrate, caso os custos sejam uma preocupação crítica, então a melhor opção seria o progressive download, já que podemos montar um servidor utilizando apenas tecnologias open-source (Apache), e podemos compartilhar os recursos com outras aplicações, como um web-server. Desta forma, não é necessário um hardware dedicado ao serviço, o que pode acontecer utilizando streaming, principalmente em Windows Media. Além disso, um servidor de progressive download suporta, naturalmente, mais conexões que um servidor de streaming, já que ele dispensa uma série de controles do fluxo de bits de cada conexão.

Voltando ao mundo real, o que acontece quando a disponibilidade de banda dos usuários não é lá grandes coisas? Neste caso, a melhor opção é sem dúvidas o progressive download. Caso o usuário não tenha uma banda disponível suficiente e a distribuição seja feita via streaming, a reprodução do conteúdo será interrompida constantemente para rebufferings, já que o fluxo de bits de saída é maior que o de entrada, e não há nada mais irritante para o usuário do que interrupções na reprodução. O mesmo problema acontece para o progressive download, com um porém: o YouTube ensinou uma valiosa lição para o usuário, “aperte o pause e espere carregar”! Assim, a diferença, neste caso, entre o streaming e o progressive download, está na possibilidade de pausar a reprodução até que o conteúdo esteja suficientemente carregado para uma reprodução contínua. Esta é uma “feature” que definitivamente faz toda diferença quando falamos na satisfação do usuário.

Um bom argumento daqueles que defendem o uso do streaming é a possibilidade de seek para qualquer posição do vídeo, independente da necessidade de carregamento. Entretanto, se estivermos falando de Flash Vídeo, este argumento é totalmente inválido. Com Flash Vídeo podemos implementar de forma relativamente simples uma solução de seek para qualquer posição, sem que seja necessário que a posição desejada já tenha sido recebida (mod_flv_streaming).

Resumindo, a escolha entre progressive download e streaming deve ser feita baseada nas características específicas de cada situação, e não podemos dizer para usar sempre um ou outro, pois ambos possuem vantagens e desvantagens. Na verdade, a chave para escolha da melhor arquitetura consiste na avaliação correta de todos os pontos envolvidos no processo de delivery, considerando assim os trade-offs de cada solução.

God Damm Flickering!

Nos últimos dias, estava realizando uns testes de reprodução de vídeo no flash player, e percebi algo extremamente desagradável: havia um flickering absolutamente irritante quando estávamos reproduzindo um vídeo de alta qualidade, com grandes dimensões, e com bastante movimento, principalmente vertical. Certo de que este era um problema específico da minha máquina (Linux Ubuntu), não me preocupei muito, e continuei meus testes, até que resolvi testar um vídeo em um Windows rodando em um Dual Quad Core com placa de vídeo de 256MB. Por incrível que pareça, o maldito flickering ainda estava lá.

Reproduzindo os mesmos vídeos em outros players não obtive problemas, o que me leva a desconfiar bastante do flash player. Finalmente, para ter certeza de que não estava fazendo nada errado, resolvi testar as versões HD dos principais sites de vídeo (YouTube, Vimeo, etc)  vendo vídeos com bastante movimento, e o que eu descobri é que todos eles tem o mesmo problema.

Flickering

Se for realmente um problema de Flash Player, aí as coisas ficam realmente complicadas. Como a Adobe quer que as pessoas utilizem o flash player para distribuição de H264 se o vídeo fica flickando?

VP6?! Não faça isso!

Para quem ainda não sabe, o VP6 (na verdade TrueMotion VP6) é um codec de vídeo utilizado para codificação no formato Flash Vídeo, desenvolvido pela On2 em 1992, e é bastante comum em vídeos distribuídos na internet. A cada dia, mais e mais sites YouTube like passam a utilizar este codec para comprimir seus vídeos, e isso é algo que me deixa bastante curioso: o que as pessoas que tomam estas decisões tem na cabeça, para usarem o VP6??? Por isso, resolvi fazer uma lista de argumentos para aqueles que estão pensando em usar Flash Vídeo para alguma coisa, e para aqueles que usam VP6 poderem me dar bons argumentos para tal escolha.

Antes de entrar nos detalhes de porque eu acho o VP6 ruim, vamos avaliar as opções existentes. Se você quer gerar um vídeo para tocar no Flash Player, você pode escolher entre os seguintes codecs: Sorenson, VP6, e H264. O Sorenson é um codec antigo e não muito eficiente, é o que o YouTube utiliza para seus vídeos de baixa definição e existem diversas implementações open-source. O H264 é um codec excepcional, utilizado para TV Digital Terrestre e bastante eficiente. Além disso, o H264 também possui implementações open-source, porém é necessário pagar royalties para utiliza-lo comercialmente.

Dadas as características das opções, a escolha evidente seria o H264. Entretanto, devemos considerar que somente a versão 9.0.r115 do Flash Player toca vídeos em H264, e apenas uma parcela bem pequena dos usuários tem esta versão instalada. Assim, a opção mais óbvia seria utilizar o VP6, já que é um codec mais eficiente e é capaz de gerar vídeo com ótima qualidade. Entretanto, ele é um codec caro, e para produzir vídeos em larga escala, de forma legal, você terá que desembolsar uma boa grana. A questão então é mais de custo x benefício.

Para codificar vídeos em VP6 você tem algumas opções, como o Flash Media Encoder e o Flix. Entretanto, todas elas são bastante limitadas, para não dizer totalmente, sendo que é possível alterar apenas o target bitrate e alguns parâmetros de tolerância. Para quem está acostumado a utilizar o mencoder e o ffmpeg, onde é possível alterar qualquer parâmetro do codificador, isto deixa muito a desejar. Não podemos, por exemplo, configurar o range de motion estimation, ou o tamanho dos macroblocos, nem sequer o posicionamento dos key-frames, ou seja, não existe margem para otimização. Até existe a possibilidade de gerar VP6 com o mencoder, porém trata-se de um hack com a DLL que implementa o codec, e é bastante bugada.

Por outro lado, podemos gerar Sorenson com estas ferramentas open-source, e podemos otimizar tanto o processo de codificação que o vídeo gerado terá uma qualidade semelhante à do VP6, principalmente quando falamos de bitrates entre 400kbps e 800kbps. Além disso, não será necessário gastar nem um centavo para gerar os vídeos. O único problema, no caso, é encontrar a combinação de parâmetros que tenha como output um vídeo de qualidade comparável ao VP6.

Outro ponto importante é o tempo de codificação, ou seja, o tempo necessário para gerar o vídeo comprimido. O Sorenson é um codec extremamento rápido, e, mesmo utilizando dois passos, é possível obter um tempo de codificação menor que a duração do vídeo. Já o VP6 é bem mais lento, e isto pode ser bem crítico dependendo do volume de vídeos processado e da urgência de exibição dos mesmos.

Assim, a única justificativa que vejo para utilizar VP6 é para vídeos em alta-definição, com grande penetração de usuários, e em cenários com grande disponibilidade de banda. Mas se for este o caso, pense bem, porque o H264 vai dominar o mercado antes que você possa imaginar.

Analisando objetivamente a qualidade de um vídeo

Num post anterior aqui do blog, falei sobre alguns dos desafios de se produzir conteúdo em vídeo para distribuição na internet, principalmente no que se refere à relação bitrate vs. qualidade. Entretanto, não deixei claro como chegar em uma relação ideal, ou seja, o quanto podemos diminuir o bitrate de modo que a qualidade fique dentro de um limite aceitável. Na verdade, toda e qualquer análise de bitrate, codec, filtros, etc, consiste em uma avaliação direta de qualidade do vídeo. Mas como saber, de forma objetiva, se um vídeo tem ou não qualidade, já que cada pessoa tem uma percepção visual diferente?

Normalmente, quando deseja-se saber se um determinado vídeo está ou não bom, mostramos ele para outras pessoas para obter uma opinião comum. Porém, este processo não é confiável uma vez que pessoas diferentes podem ter percepções visuais e critérios de avaliação completamente diferentes. Apesar disso, este tipo de avaliação subjetiva também é importante e foi inclusive utilizado na definição do codec para o Padrão Brasileiro de TV Digital.

O método objetivo de avaliação de qualidade de vídeos e imagens mais aceito na comunidade científica hoje é o PSNR (Peak Signal Noise Ratio). Como o próprio nome já diz, o PSNR é uma relação entre o máximo possível de potência de um sinal, pela potência do ruído, quando comparamos um sinal antes e depois de um processo de degradação, sendo que a unidade utilizada para representa-lo é o dB (decibel). Aplicando este conceito em vídeos e imagens, temos que o PSNR é a relação entre a entrada e a saída de um processo de compressão com perdas, que avalia o quanto a compressão introduziu ruídos na imagem ou frame original. Matematicamente o PSNR de uma imagem de dimensão m por n é representado por:

PSNR

onde MAX é o valor máximo possível de um pixel e MSE (Mean Square Error):

MSE

Desta forma, quanto maior o valor do PSNR, maior é a relação entre a potência do sinal pela potência do ruído, o que significa melhor qualidade. Em termos gerais, valores de PSNR acima de 42dB correspondem à compressões que introduzem perdas imperceptíveis ao olho humano, o que significa uma qualidade excepcional. Podemos considerar que vídeos com PSNR acima de 36dB tem qualidade bastante aceitável, entre 30dB e 36dB teremos uma qualidade mediana e abaixo de 30dB a qualidade já é bem ruim. Abaixo temos uma comparação geral dos codecs mostrando a relação entre PSNR e bitrate:

PSNR vs. Bitrate

Para facilitar a análise do PSNR, dois dos principais softwares Open Source de codificação de vídeos (mencoder e ffmpeg) já possuem esta funcionalidade integrada, basta colocar a opção -psnr que os valores serão exibidos:

Input #0, flv, from 'xxxxxx.mp4':
  Duration: 00:01:58.7, start: 0.000000, bitrate: 128 kb/s
  Stream #0.0: Video: vp6f, yuv420p, 1280x720, 29.97 fps(r)
  Stream #0.1: Audio: mp3, 44100 Hz, stereo, 128 kb/s
Output #0, avi, to 'teste.avi':
  Stream #0.0: Video: mjpeg, yuvj420p, 1280x720, q=2-31, 0 kb/s, 29.97 fps(c)
  Stream #0.1: Audio: mp2, 44100 Hz, stereo, 64 kb/s
Stream mapping:
  Stream #0.0 -> #0.0
  Stream #0.1 -> #0.1
Press [q] to stop encoding
frame= 434 q=24.8 LPSNR=Y:34.90 U:42.65 V:43.10 *:36.33 size= 14868kB time=14.5 bitrate=8410.7kbits/s

Assim, utilizando o PSNR podemos ter um valor numérico que representa a qualidade geral do vídeo, o que ajuda bastante quando estamos lidando com ajustes finos em parâmetros de encoding.

Otimizando a performance com diferentes estratégias de cache

De todas as maneiras existentes de se otimizar a performance de um software, acredito que a utilização de um cache intensivo é aquela que produz os melhores resultados, principalmente quando falamos de aplicações web. A utilização de uma estrutura de cache eficiente, aumenta significativamente a capacidade de processamento de requisições, uma vez que reduzimos a pressão sobre os gargalos da aplicação, sejam eles relacionados ao IO em disco, a utilização de memória ou a utilização de CPU. Para cada tipo de gargalo, e para cada tipo de aplicação, podemos utilizar uma estratégia de cache diferente, atuando diretamente nos pontos que limitam o desempenho do sistema.

Em uma aplicação web, temos três tipos básicos de cache: o cache no cliente, o cache no web server e o cache na aplicação. O cache no cliente é o método mais simples de redução de carga nos servidores web, principalmente quando falamos de sites simples, e com grande quantidade de conteúdo estático. Imagine, por exemplo, um site que possui muitas imagens e textos estáticos. Se não utilizarmos nenhuma política de cache, a cada request realizado, todos os componentes serão enviados do servidor para o cliente, mesmo que este cliente já tenha visualizado a página diversas vezes. Todas as imagens que já foram transferidas para ele, e que não sofreram alteração, serão novamente enviadas, algo que poderia ser facilmente evitado se o cliente tivesse armazenado previamente este conteúdo estático. Para que o cliente armazene este conteúdo, o servidor deve mandar, juntamente com a resposta, a informação de que aquele conteúdo deve ser cacheado, e por quanto tempo ele será válido no cache. Para isto, existem dois módulos do Apache que permitem uma excelente flexibilidade na definição de qual conteúdo será cacheado e o tempo de expiração do mesmo. São eles: mod_headers e mod_expires.

ExpiresByType text/html “access plus 2 hours”
ExpiresByType image/gif “modification plus 3 minutes”

Algumas vezes, apesar de termos conteúdo estático, a utilização de cache no cliente não faz muito sentido. Imaginem um site de download de músicas, onde temos diversos servidores web servindo conteúdo estático a partir de um repositório central de arquivos (um storage comum). Se vários usuários diferentes tentam realizar o download de um determinado arquivo, a cada requisição o web server irá ler o mesmo arquivo do storage central, gerando uma carga desnecessária no backend. O mesmo pode ser aplicado se no backend temos um servidor de aplicação, onde o conteúdo gerado se altera com pouca freqüência ou com uma periodicidade definida. Neste caso, devemos utilizar uma estratégia de cache no web server, seja no próprio servidor, seja criando uma camada de cache entre ele e o usuário.

Existem diversos modos de se implementar um cache no servidor web, seja utilizando um Squid na frente, seja utilizando um appliance dedicado. Porém, a maneira que eu acho mais eficiente é utilizando o mod_cache. O mod_cache é um módulo do Apache específico para cache no web server, capaz de armazenar conteúdo em disco ou em memória, de acordo com as necessidades da aplicação. Por estar integrado ao Apache, sua configuração é extremamente simples e não existem problemas de compatibilidade, etc. Além disso, ele é bastante confiável (quando utilizado com o Apache 2.2.x) e é Open-Source, sendo suportado por uma comunidade bastante ativa. (para quem quiser saber mais sobre o mod_cache).

Em algumas situações específicas estas duas abordagens de cache não são suficientes, sendo necessário a utilização de uma terceira: o cache da aplicação. Existem casos onde a camada de aplicação necessita de consultar serviços remotos, ou mesmo bancos de dados, para gerar uma determinada saída. Nestes casos, seria razoável que fosse armazenada a resposta de uma determinada consulta, desde que ela possa ser reaproveitada para o processamento de outras requisições. Desta forma, aumentamos a velocidade de resposta, o que bastante interessante do ponto de vista do usuário. Assim, para realizar este tipo de cache, podemos, por exemplo, utilizar o memcached, que é uma excelente ferramenta de cache de dados em memória.

Em suma, temos diferentes tipos de cache para diferentes tipo de problemas, sendo que a utilização de uma política de cache correta garante um ganho substancial de desempenho (podemos ter ganhos de até 70%). Quanto mais intensiva e bem estruturada for a utilização de cache, melhor será a utilização dos recursos para o que realmente importa e menor será o tempo de resposta para o usuário.

Scaling Down

Quando falamos de arquiteturas escaláveis, a primeira coisa que nos vem a mente é ter um projeto de hardware/software que permita o aumento da capacidade de processamento de acordo com o aumento da demanda. Isto significa que o esforço para atender uma demanda crescente deve ser o mínimo possível, limitando-se, na maioria das vezes, apenas em investimento em infra-estrutura de hardware. Entretanto, o conceito de escalabilidade é muito mais amplo que isto, e não deve ser limitado às condições de crescimento da demanda, mas também deve considerar uma redução significativa desta. O problema é que a grande maioria das pessoas que projetam arquiteturas estão preocupadas apenas com o scaling up e se esquecem totalmente do scaling down, e isto pode ser bastante arriscado também. Theo Schlossnagle, no seu livro Scalable Internet Architectures, nos dá inúmeros exemplos de empresas que, por não possuirem uma arquitetura totalmente escalável, simplesmente faliram durante o estouro da bolha da Internet por não serem capazes de cortar seus custos operacionais.

O problema de scaling down geralmente é mais comum em empresas de médio e grande porte, uma vez que a demanda inicial já é bastante grande, o que exige uma arquitetura inicial mais robusta e complexa. Porém, todo software tem um ciclo de vida, e existe uma probabilidade grande de que após alguns anos a demanda torne-se cada vez menor. Neste ponto, quando a demanda atual passa a ser menor que a inicial, muitas vezes a estrutura torna-se super dimensionada, e os custos de operação não são mais justificáveis. Além disso, nem sempre é interessante, do ponto de vista de posicionamento de negócios, tirar o software do ar. É aí que a necessidade de reduzir a estrutura vira uma questão de sobrevivência (sendo um pouco radical).

Você pode estar se perguntando agora: Se eu tenho uma arquitetura que é facilmente “escalável para cima”, porque ela não seria “escalável para baixo”? Quais são as características necessárias para um scaling down? Na verdade, em qualquer arquitetura existe um limite de quão simples e barata ela pode ser. O princípio geral da escalabilidade nos diz que quanto melhor for o isolamento entre as diferentes camadas do software, mais fácil é expandir a capacidade dos gargalos existentes nele. Para um scale down eficiente, também é fundamental que os componentes que foram isolados sejam construídos de forma uniforme, e rodem em plataformas compatíveis, de modo que todos os componentes possam coexistir em um único ambiente, que, no caso mais extremo, seria uma máquina Google Like. Esta é a visão ideal de escalabilidade: ter um software (inclusive com suas dependências), que seja capaz de rodar em uma máquina de supermercado, e que também possa funcionar perfeitamente em 50 servidores Dual Quad Core em cluster, e que a quantidade de informação processada varie linearmente de acordo com o aumento da capacidade.

Para que isto seja viável, é fundamental considerar os requisitos mínimos de cada componente, avaliando a compatibilidade destes requisitos com os demais componentes. Por exemplo, se um determinado componente só roda em Solaris, e o outro só em Windows, a coexistência dos dois em um único hardware fica comprometida. Atualmente, ainda temos a saída da virtualização, mas pode ser que nem todos os componentes rodem sem problemas em ambientes virtualizados. Além disso, requisitos mínimos de memória, disco e processamento irão delimitar o quão simples poderá ser a estrutura.

Resumindo, temos todos que nos preocupar não somente com o que fazer quando as coisas estão se expandindo, mas também é muito importante ter um plano claro de o que pode ser feito para enxugar a estrutura, direcionando os recursos para pontos mais prioritários. Quando você estiver projetando uma arquitetura, lembre-se de que em algum momento o scaling down pode ser a única alternativa para manter um produto no ar.

Keep it Simple

De uns tempos pra cá, desde que começamos a utilizar o Scrum na Globo.com, venho a cada dia reforçando minha idéia de que quanto mais simples, melhor. Muitas vezes, principalmente nós, engenheiros, queremos implementar as soluções mais mirabolantes para problemas muitas vezes não tão complexos, pela simples capacidade criativa que existe em nós. No caso específico de desenvolvimento de software, as vezes ficamos horas e horas tentando otimizar cada linha, cada processo, literalmente escovando bits, para ganhar um mínimo de performance. O problema é que o mercado de internet é extremamente rápido, e existe uma pressão imensa para inovação. Neste cenário, gastar tempo em pontos pouco críticos pode ser desastroso, a medida que a busca por uma solução perfeita pode literalmente impedir que novas funcionalidades sejam implementadas.

Sempre fui adepto do “bom é inimigo do ótimo”, ou seja, a busca ininterrupta por uma solução ótima pode inclusive destruir uma solução suficientemente boa. Entretanto, quando falo “Keep it Simple”, quero dizer: uma vez diante de um problema, tente simplificá-lo ao máximo, crie atalhos nos processos e limite-se naquilo que atende suas necessidades. Não tente criar um canhão para matar uma formiga. Uma solução simples, no meu ponto de vista, é muito mais elegante e melhor que uma solução aparentemente genial. No caso específico de software, quanto mais simples for a solução, mais fácil é o handover para outros membros do time, perde-se menos tempo em desenvolvimento e em manutenção, mais fácil é o teste, existe uma menor quantidade de pontos de falha. Note que ao contrário do que parece, as soluções simples não abrem mão da qualidade em nenhum momento, pelo contrário, elas contribuem para o ganho de qualidade, principalmente à longo prazo. Implementar uma solução simples não significa desenvolver fora dos padrões ou não utilizar as best pratices conhecidas, tanto que, em alguns momentos, ela será mais trabalhosa.

A medida que os membros do time  compartilham esta idéia de simplicidade,  a velocidade do time aumenta, sem comprometimento da qualidade, e os débitos técnicos causados por problemas de implementação tendem a reduzir, uma vez que fica mais fácil integrar novas funcionalidades. No time em que faço parte (time voltado para o produto Globo Vídeos), acredito que todos já tem este mindset, de que entregar muitas coisas simples é melhor do que entregar poucas coisas muito complexas. Por isso, “keep it simple”,  e você vai ver o quanto as soluções simples podem ser extremamente eficientes.

O Dilema da Qualidade dos Vídeos

Freqüentemente, quando encontro alguém que eu não conheço, e digo que trabalho na área de mídia da Globo.com, a primeira pergunta que me fazem é se eu edito os vídeos e coloco eles na internet. Daí eu explico um pouco melhor, dizendo que não, que desenvolvo novos projetos e tecnologias para diferentes etapas do processo de captura/produção/publicação dos vídeos, daí então a segunda pergunta sempre é relacionada a qualidade dos vídeos. Ou perguntam porque não melhoramos a qualidade (essa pergunta já foi bem mais freqüente, e hoje caiu em desuso), ou dizem que demora para carregar, ou dizem que o vídeo é pequeno, ou trava toda hora, etc. De uns tempos pra cá, depois que passamos a utilizar Flash Vídeo, até que as perguntas estão mudando, porque ficou melhor pra muita gente! Em suma, é bem comum que as pessoas questionem a qualidade, até porque elas estão acostumadas com a excelente qualidade da TV Globo.

Outra observação importante que eu fiz é que a maioria das pessoas que fazem essas perguntas não entendem nada de internet, elas são apenas usuários leigos, sem formação ou vocação tecnológica. Então, resolvi escrever um post para tentar explicar de forma bem clara como as coisas funcionam, e como lidamos com o “cobertor curto” diariamente.

Para que um vídeo seja disponibilizado na internet, é necessário percorrer um caminho relativamente simples. Primeiramente, precisamos capturar o sinal de TV e digitalizar ele em arquivos de vídeo. Esse arquivo é o vídeo bruto, em excelente qualidade, que será editado (cortado, etc). Uma vez editado, o vídeo é preparado para distribuição na internet, ou seja, ele é transcodificado. Neste momento, transformamos o vídeo editado de altíssima qualidade para um formato padrão de distribuição na internet. Atualmente utilizamos Flash Vídeo, porém, poderíamos utilizar Windows Media, Real, etc. Uma vez transformado, o vídeo é colocado nos servidores para que os usuários possam acessar.

De todo esse processo, basicamente o que define a qualidade final do vídeo é a transcodificação. Nela não só alteramos o formato (chamado encapsulamento), como também aplicamos uma compressão, e é aí que mora o problema. Se pensarmos um pouco e fizermos uma conta simples, iremos ver que a quantidade de informação de um vídeo de alta qualidade é imensa, e seria impossível transmitir este vídeo na internet. Vejamos: supondo um vídeo com 320 pixels de largura por 240 de altura, teremos por frame de vídeo 76800 pixels; considerando que o vídeo tem 30 frames por segundo; e considerando uma resolução de 8 bits por pixel; desconsiderando o áudio, as cores, etc, teremos:

76800 x 30 x 8 = 18432000 bits/segundo de vídeo = 17.57Mbps

Agora eu pergunto quantas pessoas no Brasil tem 17.57Mbps de conexão de internet?!

A solução para este problema consiste em comprimir a informação do vídeo, retirando as redundâncias existentes nele. Quanto mais redundância tirarmos, menos bits por segundo serão necessários, mais fácil fica ver o vídeo, menos qualidade teremos na imagem. Esta é a relação da discordia. Além disso, existem diferentes forma de retirar a redundância de um vídeo, umas mais e outras menos eficientes. Estas diferentes maneiras são os famigerados codecs (VP6, H264, WMV9, MPEG2, MJPEG, DV, etc ), que implementam os algoritmos de compressão dos vídeos. Atualmente o algoritmo mais eficiente de compressão é o H264, que é inclusive utilizado nas transmissão de TV Digital no Brasil.

Assim, dada que a taxa média de velocidade do usuário brasileiro fica em torno de 300kbps (o que é ridículo!!!), é necessário comprimir bastante, muito mesmo, o que acaba degradando a qualidade. Por outro lado, para ter uma qualidade mais razoável, precisamos de algo em torno de 600kbps, 800kbps, porém iremos onerar a velocidade com que o usuário carrega o vídeo. Conciliar velocidade e qualidade é uma tarefa difícil, mas não impossível. Podemos utilizar uma série de filtros e algoritmos de processamento de imagens para maximizar a percepção de qualidade, e, a medida que a tecnologia avança, podemos melhorar os próprios algoritmos de compressão do vídeo. De qualquer forma, não existe milagre! Maior qualidade, maior tamanho, etc, ocasiona em mais bitrate.

O que eu posso dizer a respeito dos vídeos da Globo.com, é que temos um processo de avaliação de qualidade bastante rígido e objetivo, dentro das limitações de bitrate que definimos. E podem esperar, porque ainda teremos muitas novidades este ano!