Um único dispositivo Android pode ter várias câmeras. Cada câmera é um CameraDevice , e um CameraDevice pode gerar diversos streams ao mesmo tempo. Mas por que faríamos isso? Um stream pode ser ideal para um caso de uso específico, como exibir um visor, enquanto que outros podem ser úteis para tirar uma foto ou gravar um vídeo. Podemos imaginar os streams como canais paralelos que processam quadros brutos gerados pela câmera, um quadro de cada vez:
Ilustração do Building a Universal Camera App (Google I/O 2018)
Processamento paralelo indica que podem haver limites de desempenho dependendo do poder de processamento disponível na CPU, na GPU ou em outro componente. Se um canal não conseguir dar conta dos quadros que chegam, começará a ignorá-los.
Veja que cada canal tem seu próprio formato de saída. Os dados brutos que chegam são transformados automaticamente no formato de saída correspondente pela lógica implícita relacionada a cada canal. Mas vamos falar mais sobre isso depois.
O CameraDevice pode ser usado para criar uma CameraCaptureSession, que será específica desse CameraDevice. Um CameraDevice tem que receber uma configuração de quadros pela CameraCaptureSession para cada quadro bruto de saída. Uma configuração entra, um quadro bruto sai. A configuração determina os atributos da câmera, como foco automático, abertura, efeitos e exposição. Devido a limitações de hardware, só uma configuração pode ser ativada no sensor da câmera por vez. Essa é a configuração ativa .
Uma CameraCaptureSession descreve todos os possíveis canais disponíveis para o CameraDevice. Após a criação da sessão, não é possível adicionar ou remover canais. A CameraCaptureSession armazena uma fila de CaptureRequests, que se torna a configuração ativa.
Uma CaptureRequest adiciona uma configuração à fila e seleciona um ou mais (ou até todos) canais disponíveis para receber um quadro do CameraDevice. Você pode enviar muitas solicitações de captura durante o tempo de vida de uma sessão de captura. Cada solicitação pode mudar a configuração ativa e o conjunto de canais de saída que receberão a imagem bruta.
Criação de uma CameraCaptureSession
Para criar uma sessão de câmera, precisamos dar a ela um ou mais buffers para gravar quadros de saída. Cada buffer representa um canal. Você precisa fazer isso antes de começar a usar a câmera para que a biblioteca possa configurar os canais internos do dispositivo e alocar buffers de memória para enviar quadros aos alvos desejados para a saída.
Veja como podemos preparar uma sessão de câmera com dois buffers de saída: um que pertence a SurfaceView e outro, a ImageReader:
Note que, nesse ponto, ainda não definimos a configuração ativa da câmera. Quando a sessão é configurada, podemos criar e enviar solicitações de captura para fazer isso.
Já dissemos antes que todo canal sabe como transformar o formato da entrada gravada no seu buffer no formato correspondente, lembra disso? Essa transformação é determinada pelo tipo de cada alvo, que deve ser uma Surface . A biblioteca do Android sabe como converter uma imagem bruta da configuração ativa em um formato adequado para cada alvo. A conversão é controlada pelo formato e o tamanho dos pixels da Surface envolvida. A biblioteca tenta fazer o melhor que pode, mas uma Surface pode ter uma configuração que não funciona e, nesse caso, podem acontecer várias coisas indesejáveis: a sessão não será criada, você receberá um erro em tempo de execução quando enviar uma solicitação ou o desempenho pode ser pior que o esperado. A biblioteca oferece garantia para combinações específicas de dispositivo, superfície e parâmetros de solicitação. Vamos falar sobre tudo isso em uma próxima postagem. (enquanto isso, se tiver curiosidade, leia a documentação de createCaptureSession ).
CaptureRequests de uma captura
A configuração usada para cada quadro é codificada em uma CaptureRequest , que é enviada à câmera. Para criar uma solicitação de captura, podemos usar um dos modelos predefinidos (ou TEMPLATE_MANUAL para obter controle total). Depois de escolher o modelo, precisamos fornecer um ou mais buffers de saída do alvo para serem usados com a solicitação. Só podemos usar buffers já definidos na sessão de captura que pretendemos usar.
As solicitações de captura usam um padrão de construtor e permitem que os desenvolvedores personalizem diversas opções , como exposição automática , foco automático e abertura da lente . Antes de definir um campo, chame CameraCharacteristics.getAvailableCaptureRequestKeys() para ver se a opção envolvida está disponível no dispositivo e veja também se o valor desejado é compatível checando a característica da câmera (por exemplo, modos de exposição automática disponíveis ).
Para criar uma solicitação de captura simples para a nossa SurfaceView usando o modelo indicado para visualização de vídeo sem nenhuma modificação, use CameraDevice.TEMPLATE_PREVIEW :
Já temos uma solicitação de captura e podemos finalmente enviá-la à sessão da câmera:
Quando um quadro de saída é colocado nos buffers do alvo, um callback da captura é acionado. Em muitos casos, callbacks adicionais serão acionados quando o quadro que contêm forem processados (por exemplo, ImageReader.OnImageAvailableListener ). E é nesse momento que podemos extrair dados da imagem do buffer do alvo.
Repetição de CaptureRequests
Solicitações de câmera de uma captura são fáceis de fazer, mas não são muito úteis para exibir uma visualização ao vivo. Nesse caso, o ideal é recebermos um stream contínuo de quadros, e não um só. Felizmente, há uma forma de criar uma solicitação repetida para a sessão:
Uma solicitação de captura repetida fará com que a câmera capture imagens continuamente usando as configurações definidas na CaptureRequest, usando a maior taxa possível.
Intercalação de CaptureRequests
Vamos complicar um pouco mais as coisas e chegar mais perto de um cenário real... E se quiséssemos enviar uma segunda solicitação de captura enquanto a solicitação repetida está ativa? É isso que um aplicativo precisa fazer para exibir um visor e permitir que os usuários consigam tirar uma foto. Nesse caso, não precisamos parar a solicitação repetida, basta enviar uma solicitação de captura não repetida. Não se esqueça de que os buffers de saída do alvo usados precisam ser configurados como parte da sessão da câmera quando a sessão é criada. É importante destacar que as solicitações repetidas têm menor prioridade do que as solicitações de uma captura ou de disparo contínuo, o que nos permite fazer algo como:
No entanto, essa abordagem tem uma limitação importante: não sabemos exatamente quando a solicitação de captura única vai ocorrer. Na figura abaixo, se A é a solicitação de captura repetida e B é a solicitação de uma captura, a sessão processaria a fila de solicitações da seguinte forma:
Ilustração de uma fila de solicitações para a sessão de câmera ativa
Não há garantias para a latência entre a última solicitação repetida de A antes de a solicitação B entrar em cena e A ser usada pela próxima vez. Portanto, alguns quadros podem ser perdidos. Podemos fazer algumas coisas para minimizar esse problema:
Adicionar os alvos de saída da solicitação A também à solicitação B. Dessa forma, quando o quadro de B estiver pronto, ele será copiado aos alvos de saída de A. Isso é essencial, por exemplo, quando se tiram fotos em vídeo para manter uma taxa de quadros constante. No código acima, simplesmente adicionaríamos singleRequest.addTarget(previewSurface) antes da criação da solicitação.
Usamos uma combinação de modelos desenvolvidos para esse caso específico, como o zero-shutter-lag (comumente abreviado como ZSL).
Se a configuração da solicitação de captura única for a mesma da solicitação repetida, não haverá necessidade de várias solicitações. Configure uma solicitação repetida única para gerar saída para o alvo da solicitação repetida e para o alvo da solicitação de captura única. Embora seja necessário que tenham as mesmas configurações de solicitação de captura, elas podem ter tamanhos e formatos diferentes.
O que aprendemos
É importante entender as sessões de câmera e solicitações de captura para criar aplicativos que usam a API de câmera do Android. Nesta postagem do blog, falamos sobre:
Como as sessões de câmera funcionam
Como as solicitações de captura funcionam, incluindo as de captura única e as repetidas
Como as solicitações de captura são adicionadas a uma fila e diferentes técnicas para enviá-las sem prejudicar streams ativos
Em uma próxima postagem, aprenderemos a tratar as complexidades das solicitações que têm mais de um alvo como parte de uma sessão e como configurar os canais da câmera para extrair o máximo potencial de um dispositivo.
2 comentários :
PINGIN CEPAT KAYA ? Bingung mulai dari mana ? Baru..!! Game judi online 2019 wargapoker terpercaya. Dapatkan bonus-bonus untuk pemain baru, Ada begitu banyak jenis taruhan judi online dengan uang asli yang bisa anda mainkan di afapoker kapan saja dan dimana saja, cukup menggunakan satu user id saja. Anda dipastikan memainkan permainan judi online yang murni dominobet dimana Anda bermain 100% player vs player tanpa ada campur tangan bot link alternatif domino88 2019. Tidak perlu lagi bersusah payah mencari uang, Anda bebas menikmati waktu Anda. Situs link alternatif pokerace 2019 deposit murah yang menyediakan banyak permainan dengan pelayanan berkualitas. Jadi silahkan daftar dan segera mainkan permainan. Dijamin mudah dan cepat. Anda akan diberi pelayanan yang ramah dan cepat saat proses pendaftaran. Didukung dengan sistem terbaru dan tim profesional serta kemudahan bertransaksi. Kami menjamin kerahasiaan data member.
Such A nice post... thanks For Sharing !! Now you can Send Valentine gifts To UK to your love one and spread the joy of this occassion.Flower delivery UK| Send Christmas Gifts To UK to your love one and spread the joy.
Postar um comentário