2013-12-20 1 views
4

MediaCodec 인코더를 위해 보폭과 Y 평면 정렬 값을 얻는 방법 :이 주제에 대한 몇 가지 관련 질문과 토론있다

카메라 미리보기 프레임 (NV21NV12으로 변환) MediaCodec 인코더 (NV12 aka COLOR_FormatYUV420SemiPlanar). 미만의 Android 버전을 실행하는 QualComm 인코더가있는 일부 기기에서는 올바른 색상으로 프레임을 다시 수신하기 위해 일부 입력 프레임 처리를해야합니다.

Android 4.2.2을 실행하면 거의 모든 해상도에서 작동하도록 Y 평면 정렬을 추가해야합니다. 위 코드는 다른 해상도의 경우 322048 바이트로 나눌 수없는 너비에 대해 1024 바이트 정렬을 추가합니다. 16 (176x144의 경우는 UV 평면이 정렬되지 않은 경우를 제외하고)으로 나눌 수있는 모든 해상도에 대해 프레임을 올바르게 인코딩하도록 MediaCodec을 만듭니다.

int getYPadding() { 
    if (mediaCodecInfo.getName().contains("OMX.qcom") && android.os.Build.VERSION.SDK_INT < 18) { 
     if ((getWidth() % 32) != 0) { 
      return (getWidth()*getHeight()) % 1024; 
     } else { 
      return (getWidth()*getHeight()) % 2048; 
     } 
    } 
    return 0; 
} 

나는 같은 Android 4.2.2를 실행하고 QualComm 인코더를 가지고있다 LG G2에서이 정렬을 테스트하기 위해 노력했습니다, 그것이 제대로 작동하지 않는 것 같습니다. UV 평면이 잘못 정렬됩니다 (프레임 하단의 녹색 줄무늬). 두 휴대 전화 모두에서 사용할 패딩을 계산할 수 없었습니다.

나는 Sony Xperia Z1Android 4.3QualComm 칩셋으로도 실행되며 이러한 문제가없는 것처럼 보입니다. 모든 해상도의 비디오는 괜찮아 보이며 Y 평면을 정렬 할 필요가 없습니다.

하드웨어와 관련되어 있고 복잡 할 수도 있음을 알고 있지만, 4.3 이전에 Android를 실행하는 사용자를 지원해야하므로 질문이 있습니다. 인코더가 주어진 색상 형식에 대해 기대하는 평면 정렬 및 수직/수평 스트라이드 값을 프로그래밍 방식으로 결정할 수 있습니까? Y

답변

7

간단히 말해서 문제는 Android 4.3 (API 18)까지 동영상 인코딩에 대해 CTS tests이 없었기 때문입니다.

결과적으로 다른 장치에서 MediaCodec의 동작이 일치하지 않아 몇 가지 버그가 눈에 띄지 않게되었습니다. EncodeDecodeTest 테스트에서는 사용자가 묻는 기능을 연습하므로 결과적으로 YUV 데이터를 4.3+ 장치에 안정적으로 공급할 수 있습니다 (단, 평면 또는 반 평면을 원하는지 여부를 런타임에 파악해야 함).

특정 질문에 대해서는 이전 Qualcomm 기기의 Y 평면이 2K 경계에 정렬되어야합니다. 이는 코드가하는 것과는 다릅니다. 720p 비디오의 경우 자연스럽게 발생합니다 (720 * 1280 == 450 * 2048). 176x144의 경우 UV 플레인을 25344 대신 26624에서 시작하도록 1280으로 조정합니다. 버퍼 내에서 고정 정렬이 아닌 절대 정렬을 설정해야합니다 패딩 양 - uvoffset = (width*height + 2047) & ~2047을 사용하십시오.

코덱 공급 업체 및 Android 소프트웨어 버전을 감지해야하며 4.3 이전 버전의 Qualcomm 인 경우 조정해야합니다. 요구 사항이 변경되고 API 18 이상을 타겟팅 할 수 있다면 이러한 문제는 사라집니다. (Surface 입력을 MediaCodec에 사용할 수 있습니다. 사용자의 필요에 따라 U/V 스왑 문제를 피할 수 있습니다.)

+0

감사합니다. @fadden 굉장합니다! :) 올바른 정렬 방법으로 마침내'Sony Xperia ZR'의 모든 해상도에서 작동하게 만들 수있었습니다. 'LG G2'는 여전히 버그가 있지만, 별도의 질문으로 마무리하고 스크린 샷을 첨부 할 것입니다. –

+1

이것에 덧붙여, Y 평면과 UV 평면을 2K 경계에서 정렬하려고 할 가능성이 높습니다. 예 : 480x480의 RGB 비디오 해상도의 경우 MediaCodec에 전달 될 yuv420Buffer는 다음 크기로 변환되어야합니다. YUVBufferSize + yOffset + uvOffset : (480 * 480 * 1.5) + (2048 - ((480 * 480) % 2048)) + (2048 - ((480 * 480/2) % 2048)). 어떤 인코더가 LG_G2를 사용하는지 알지 못합니다. qcom- 인코더라면이 논리를 시도해보십시오. 희망이 도움이됩니다. – Gagan