6

Próbuję wykonać kodowanie sprzętowe (avc) strumienia NV12 za pomocą interfejsu API Android MediaCodec.Uzyskiwanie koderów QualComm do pracy za pomocą MediaCodec API

Podczas korzystania OMX.qcom.video.encoder.avc uchwały 1280x720 i 640x480 działają dobrze, podczas gdy inni (czyli 640x360, 320x240, 800x480) wytwarzają wyjście gdzie składowa chrominancji wydaje przesunięte (patrz snapshot).

Dwa razy sprawdziłem, czy obraz wejściowy jest poprawny, zapisując go w pliku jpeg. Ten problem występuje tylko na urządzeniach QualComm (np. Samsung Galaxy S4).

Ktoś to działa poprawnie? Jakieś dodatkowe ustawienia/dziwactwa konieczne?

+1

Android 4.3 dodał kilka przydatnych nowych funkcji, a także dodał testy CTS, które zasilają dane YUV do "MediaCodec". Testy bufor-bufor i bufor-na powierzchni w http://bigflake.com/mediacodec/#EncodeDecodeTest mogą być przydatne. – fadden

+1

BTW, jest dyskusja na platformie Google Group w Androidzie, która wspomina o koderach QualComm: https://groups.google.com/d/msg/android-platform/awaNwgb6EbY/a-YiIOwaL0QJ Jeden z komentatorów stwierdza, że ​​płaszczyzna chroma powinna być wyrównana przez granicę 2048 bajtów, ale to działa tylko dla mnie. Niektóre rozdzielczości są nadal błędne, na przykład 176x144. –

Odpowiedz

3

Dekoder (MediaCodec) ma MediaFormat, może być odbierany za pomocą getOutputFormat. Zwrócone wystąpienie można wydrukować w celu zalogowania. I tam możesz zobaczyć kilka przydatnych informacji. Na przykład w przypadku twojego przypadku wartość "wysokość-plastra" może być przydatna. Podejrzewam, że jest równa wysokości dla 1280x720 i 640x480 i różni się dla innych rozdzielczości. Prawdopodobnie powinieneś użyć tej wartości, aby uzyskać przesunięcie chrominancji.

+0

Jako szybkie rozwiązanie, zmieniłem rozdzielczości zgodnie z tym, co widziałem w 'slice-height' i 'kroku' dekodera. Na przykład 640x384 zamiast 640x360 i 384x256 zamiast 320x200. Potem zadziałało dobrze :) Dzięki! – badbadboy

+0

@badbadboy czy znalazłeś sposób na dynamiczne obliczanie kroku i sliceHeight ze stałą rozdzielczością dla enkodera qualcomm? – dmarcato

+0

@dmarcato Jeszcze się tym nie zajrzałem. – badbadboy

3

Tak, OMX.qcom.video.encoder.avc robi to, ale nie na wszystkich urządzeniach/wersji Android. Na moim Nexusie 4 z Androidem 4.3 koder działa dobrze, ale nie na moim S3 (w wersji 4.1)

Rozwiązanie dla S3 z wersją 4.1 z OMX.qcom.video.encoder.avc (wygląda na to, że niektóre S3 mają inny koder) ma dodać 1024 bajty tuż przed panelem 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; 

Aparat korzysta YV12 i enkoder COLOR_FormatYUV420SemiPlanar.

Twój zrzut pokazuje ten sam rodzaj artefaktów miałem, konieczne może być podobny trik dla niektórych uchwał, może z inną długością dopełnienia

Należy również unikać uchwał, które nie są wielokrotnością 16, nawet na 4.3 podobno (http://code.google.com/p/android/issues/detail?id=37769)!

+0

Jak określić mysize i mUVSize? –