6

Sto cercando di eseguire la codifica hardware (avc) del flusso NV12 utilizzando l'API Android MediaCodec.Utilizzo degli encoder QualComm tramite MediaCodec API

Quando si utilizza OMX.qcom.video.encoder.avc, risoluzioni 1280x720 e 640x480 bel lavoro, mentre gli altri (cioè 640x360, 320x240, 800x480) produrre un output in cui componente chroma sembra spostato (vedi snapshot).

Ho verificato che l'immagine di input sia corretta salvandola in un file jpeg. Questo problema si verifica solo sui dispositivi QualComm (ad esempio Samsung Galaxy S4).

Chiunque funziona correttamente? Qualche setup/quirks aggiuntivi necessari?

+1

Android 4.3 ha aggiunto alcune utili nuove funzionalità e ha aggiunto anche test CTS che alimentano i dati YUV in 'MediaCodec'. I test buffer-to-buffer e buffer-to-surface in http://bigflake.com/mediacodec/#EncodeDecodeTest possono essere istruttivi. – fadden

+1

BTW, c'è discussione nella piattaforma Android Google Group che menziona gli encoder QualComm: https://groups.google.com/d/msg/android-platform/awaNwgb6EbY/a-YiIOwaL0QJ Uno dei commentatori afferma che il piano chroma deve essere allineato entro il limite di 2048 byte, ma funziona solo parzialmente per me. Alcune risoluzioni sono ancora buggy, 176x144, per esempio. –

risposta

3

Decoder (MediaCodec) ha il suo MediaFormat, può essere ricevuto utilizzando getOutputFormat. L'istanza restituita può essere stampata per registrare. E qui puoi vedere alcune informazioni utili. Ad esempio nel tuo caso il valore come "slice-height" potrebbe essere utile. Sospetto che sia uguale all'altezza per 1280x720 e 640x480 e differisca per altre risoluzioni. Probabilmente dovresti usare questo valore per ottenere l'offset cromatico.

+0

Come soluzione rapida, ho cambiato le risoluzioni in base a ciò che ho visto in 'slice-height' e 'stride' del decoder. Ad esempio, 640x384 anziché 640x360 e 384x256 anziché 320x200. Quindi ha funzionato bene :) Grazie! – badbadboy

+0

@badbadboy hai trovato un modo per calcolare dinamicamente lo stride e sliceHeight dato una risoluzione fissa per il codificatore Qualcomm? – dmarcato

+0

@dmarcato Non l'ho ancora cercato ... – badbadboy

3

Sì, il file OMX.qcom.video.encoder.avc lo fa ma non su tutti i dispositivi/versione di Android. Sul mio Nexus 4 con Android 4.3 l'encoder funziona bene, ma non sul mio S3 (in esecuzione 4.1)

La soluzione per un S3 in esecuzione 4.1 con OMX.qcom.video.encoder.avc (sembra che alcuni S3 abbiano un altro encoder) consiste nell'aggiungere 1024 byte subito prima del riquadro Chroma.

// The encoder may need some padding before the Chroma pane 
int padding = 1024;      
if ((mWidth==640 && mHeight==480) || mWidth==1280 && mHeight==720) padding = 0; 

// Interleave the U and V channel 
System.arraycopy(buffer, 0, tmp, 0, mYSize); // Y 
for (i = 0; i < mUVSize; i++) { 
    tmp[mYSize + i*2 + padding] = buffer[mYSize + i + mUVSize]; // Cb (U) 
    tmp[mYSize + i*2+1 + padding] = buffer[mYSize + i]; // Cr (V) 
} 
return tmp; 

La fotocamera è usando YV12 e l'encoder COLOR_FormatYUV420SemiPlanar.

L'istantanea mostra lo stesso tipo di manufatti che ho avuto, potrebbe essere necessario un hack simile per alcune risoluzioni, magari con un'altra lunghezza imbottitura

Si dovrebbe anche evitare di risoluzioni che non sono un multiplo di 16, anche su 4.3 apparentemente (http://code.google.com/p/android/issues/detail?id=37769)!

+0

come posso determinare mYSize e mUVSize? –