Casos de uso de fluxos de câmera simultâneos
Um aplicativo de câmera pode querer usar mais do que um fluxo de quadros em determinado momento e, em alguns casos, fluxos diferentes ainda precisam de uma resolução de quadros ou formato de pixel diferente. Estes são alguns casos de uso comuns:
Gravação de vídeo: um fluxo para visualização e outro para ser codificado e salvo em arquivo
Leitura de código de barras: um fluxo para visualização e outro para detecção do código de barras
Fotografia computacional: um fluxo para visualização e outro para detecção de face ou cena
Como mencionamos em nossa postagem anterior no blog , o processamento de quadros tem um custo significativo de desempenho, que é multiplicado quando há processamento paralelo de fluxos/canais.
Recursos como CPU, GPU e DSP podem conseguir aproveitar a capacidade de reprocessamento da biblioteca, mas a memória crescerá linearmente.
Diversos destinos por solicitação
Vários fluxos de câmera podem ser combinados em uma única CameraCaptureRequest por meio de um procedimento relativamente burocrático. O snippet de código abaixo ilustra como configurar uma sessão da câmera com um fluxo para a visualização do vídeo e outro para o processamento da imagem:
Se você configurar corretamente a superfície dos destinos, o código produzirá apenas fluxos que respeitem o FPS mínimo determinado por StreamComfigurationMap.GetOutputMinFrameDuration(int, Size) e StreamComfigurationMap.GetOutputStallDuration(int, Size) . Apesar de o desempenho real variar de acordo com o dispositivo, o Android oferece algumas garantias quanto ao suporte a combinações específicas de acordo com três variáveis: tipo de saída , tamanho da saída e nível de hardware . O uso de uma combinação de parâmetros não suportada pode funcionar com taxas de quadro mais baixas ou pode simplesmente não funcionar, acionando um dos callbacks de erro. A documentação descreve detalhadamente o que tem funcionamento garantido. Recomendamos a leitura de toda a documentação, mas descreveremos os aspectos básicos.
Tipo de saída
O tipo de saída é o formato em que os quadros são codificados. Os valores possíveis, descritos na documentação, são PRIV, YUV, JPEG e RAW. A documentação explica cada um deles melhor:
PRIV é qualquer destino cujos tamanhos disponíveis usam StreamConfigurationMap.getOutputSizes(Class) sem formato direto visível pelo aplicativo
YUV é uma superfície de destino que usa o formato ImageFormat.YUV_420_888
JPEG é o formato ImageFormat.JPEG
RAW é o formato ImageFormat.RAW_SENSOR .
Ao escolher o tipo de saída do aplicativo, se o objetivo é maximizar a compatibilidade, a recomendação é usar ImageFormat.YUV_420_888 para análise de quadros e ImageFormat.JPEG para imagens estáticas. Para cenários de visualização e gravação, você provavelmente usará SurfaceView, TextureView, MediaRecorder, MediaCodec ou RenderScript.Allocation. Nesses casos, não especifique um formato de imagem e, para fins de compatibilidade, a gravação será considerada uma ImageFormat.PRIVATE (independentemente do formato real usado internamente). Para consultar os formatos compatíveis com determinado dispositivo considerando suas CameraCharacteristics , use o código abaixo:
Tamanho da saída
Todos os tamanhos de saída disponíveis são listados ao chamar StreamConfigurationMap.getOutputSizes() , mas na questão da compatibilidade, só precisamos nos preocupar com dois deles: PREVIEW e MAXIMUM. Você pode considerar esses tamanhos como limites superiores. Se a documentação disser que algo com tamanho PREVIEW funciona, tudo com tamanho menor que PREVIEW também funcionará. E o mesmo princípio se aplica a MAXIMUM. Este é trecho importante da documentação :
Para a coluna de tamanho máximo, PREVIEW é o tamanho mais indicado para a resolução da tela do dispositivo, ou para 1080p (1.920 x 1.080), o que for menor. RECORD indica a resolução de gravação máxima oferecida pelo dispositivo da câmera, como determinado por CamcorderProfile . E MAXIMUM representa a resolução de saída máxima do dispositivo da câmera para determinado formato ou destino de StreamConfigurationMap.getOutputSizes(int) .
Veja que os tamanhos de saída disponíveis dependem da escolha do formato. Considerando CameraCharacteristics e um formato, podemos consultar assim os tamanhos de saída disponíveis:
Nos casos de uso da câmera para visualização e gravação, devemos usar a classe de destino para determinar os tamanhos compatíveis, já que o formato será tratado pela própria biblioteca da câmera:
Encontrar o tamanho MAXIMUM é fácil, basta ordenar os tamanhos de saída por área e retornar o maior:
Mas a determinação do tamanho de PREVIEW exige um pouco mais de raciocínio. Lembre-se de que PREVIEW é o tamanho mais adequado para a resolução da tela do dispositivo, ou para 1080p (1.920 x 1.080), o que for menor. Considere também que a taxa de proporção pode não corresponder exatamente à taxa de proporção da tela. Portanto, poderá ser necessário aplicar letterbox ou recortar o fluxo se a ideia for exibir em modo de tela cheia. Para encontrar o tamanho certo para a visualização, precisamos comparar os tamanhos de saída disponíveis com o tamanho da tela, sem esquecer também que a tela pode ser girada. Neste código, definimos ainda uma classe auxiliar SmartSize que facilita um pouco as comparações de tamanho:
Nível de hardware
Para determinar os recursos disponíveis em tempo de execução, a informação mais importante para um aplicativo de câmera é o nível de hardware compatível. Mais uma vez, podemos usar a documentação para explicar essa ideia:
O nível de hardware compatível é uma descrição geral dos recursos do dispositivo da câmera, resumindo diversas funcionalidades em um campo. Cada nível agrega outros recursos ao anterior e é sempre um superconjunto invariável do nível anterior. A ordem é LEGACY < LIMITED < FULL < LEVEL_3.
Com um objeto CameraCharacteristics , podemos determinar o nível de hardware em uma única declaração:
Montagem de todas as peças
Depois de entender tipo de saída, tamanho de saída e nível de hardware, podemos determinar que combinações de fluxo são válidas. Por exemplo, temos aqui uma imagem das configurações compatíveis com um CameraDevice com nível de hardware LEGACY . A imagem foi extraída da documentação e representa o método createCaptureSession :
Como LEGACY é um nível de hardware mais baixo possível, podemos deduzir, a partir da tabela anterior, que todo dispositivo compatível com Camera2 (ou seja, API de nível 21 e posteriores) pode gerar até três fluxos simultâneos usando a configuração correta — e isso é ótimo! No entanto, talvez não seja possível atingir a capacidade máxima disponível em muitos dispositivos porque seu próprio código poderá gerar sobrecarga, o que criará outras limitações que afetam o desempenho, como restrições de memória, CPU e até térmicas.
Agora que temos o conhecimento necessário para criar dois fluxos simultâneos com compatibilidade garantida pela biblioteca, podemos entrar em mais detalhes sobre a configuração de buffers de saída de destino. Por exemplo, se estamos trabalhando com um dispositivo com nível de hardware LEGACY , podemos criar duas superfícies de saída de destino: uma usando ImageFormat.PRIVATE e outra, ImageFormat.YUV_420_888 . Segundo a tabela acima, essa é uma combinação compatível, mas só se usarmos o tamanho PREVIEW. Usando a função definida acima, fica bem simples encontrar os tamanhos PREVIEW, ou de visualização, necessários com um ID de câmera:
Temos que esperar a SurfaceView ficar pronta usando os callbacks indicados, assim:
Podemos até forçar a SurfaceView a se igualar ao tamanho de saída da câmera chamando SurfaceHolder.setFixedSize() , mas talvez seja melhor, em termos de IU, adotar uma abordagem parecida com FixedAspectSurfaceView do exemplo de visor HDR no GitHub , que define um tamanho absoluto considerando tanto a taxa de proporção quanto o espaço disponível e ajustando-se automaticamente quando alterações são aplicadas à atividade.
Configurar a outra superfície com ImageReader no formato desejado é mais fácil ainda, já que não é preciso esperar nenhum callback:
Quando usamos um buffer de destino bloqueador, como o ImageReader, precisamos descartar os quadros depois de usá-los:
É importante não esquecer que estamos buscando trabalhar com o menor denominador comum: dispositivos com nível de hardware LEGACY. Podemos adicionar ramificações condicionais e usar o tamanho RECORD em uma das superfícies de saída de destino em dispositivos com nível de hardware LIMITED ou até mesmo pular para o tamanho MAXIMUM em dispositivos com nível de hardware FULL.
Resumo
Neste artigo, falamos sobre:
Como usar um único dispositivo de câmera para criar vários fluxos simultâneos
As regras para combinar diferentes destinos em uma única solicitação de captura
Como consultar e selecionar o tipo de saída, o tamanho de saída e o nível de hardware certos
Como criar e usar uma Surface fornecida por SurfaceView e pelo ImageReader
Com esse conhecimento, podemos criar um aplicativo de câmera que tem a capacidade de exibir um fluxo de visualização enquanto executa em outro fluxo uma análise assíncrona dos quadros recebidos.
2 comentários :
Situs poker online dan agen judi terpercaya capsa365, disini kami memberi kenyamanan dan keamanan dalam bermain supaya anda dapat menghasilkan banyak uang. Permainan di website ini pokerlegendaterbilang cukup mudah seperti poker, domino dan bandar. Dilayani oleh admin-admin profesional karena kepuasan adalah target kami. Situs ini link alternatif pokeronlinecc 2019terbukti sudah masuk 5 besar situs penghasil uang cepat terbaik serta banyak penawaran spesial untuk anda karena disini rajacapsa anda bisa bermain dengan jaminan VIP cukup deposit rendah anda bisa memainkan langsung game pencetak uang asli ini. Kami sudah menambahkan game-game baru yang bisa anda mainkan dengan mudah untuk mempercepat penambahan dana. Mainkan setiap hari dan dapatkan keuntungan lebih dari situs pencari uang kami link alternatif ratucapsa 2019. Slot anda sudah kami persiapkan, selamat bermain dan menjadi kaya.
Situs poker online dan agen judi terpercaya, disini sobatpoker kami memberi kenyamanan dan keamanan dalam bermain supaya anda dapat menghasilkan banyak uang. Permainan di website ini link alternatif ubcpoker 2019 terbilang cukup mudah seperti poker,domino dan bandar. Dilayani oleh admin-admin profesional karena kepuasan adalah target kami. Situs ini wargakartu terbukti sudah masuk 5 besar situs penghasil uang cepat terbaik serta banyak penawaran spesial untuk anda karena disini pokerclub 88 anda bisa bermain dengan jaminan VIP cukup deposit rendah anda bisa memainkan langsung game pencetak uang asli ini link alternatif rajaqq 2019. Kami sudah menambahkan game-game baru yang bisa anda mainkan dengan mudah untuk mempercepat penambahan dana. Mainkan setiap hari dan dapatkan keuntungan lebih dari situs pencari uang kami. Slot anda sudah kami persiapkan, selamat bermain dan menjadi kaya.
Postar um comentário