2017-05-17 1 views
-2

C++로 안드로이드 애플리케이션을 작성 중이며 YUV420sp 이미지가 포함 된 메모리 블록에서 GraphicBuffer를 가져오고 싶습니다. 특히, 비디오 프레임의 이미지가있는 메모리 블록을 제공하는 카메라의 dataCallbackTimestamp 콜백 함수에서 가져온 IMemory가 있으며,이를 memcpy를 수행하지 않고 BufferQueue에 추가하려고합니다. 나는 HAL을 사용하고 있으며 HAL3 또는 Camera2를 내 클라이언트의 HW에서 사용할 수 없습니다 (이것은 간단합니다).zero-copy를 사용하여 안드로이드 메모리를 GraphicBuffer에 매핑하십시오.

특히 제로 복사본 ANativeWindowBuffer 또는 void * 밖으로 GraphicBuffer를 만드는 방법은 무엇입니까? 나는 4K 비디오를 위해 초당 30 개의 GraphicBuffers를 매핑 할 수 있어야한다. 인터넷과 예제를 샅샅이 뒤졌지만 memcpy (내 프레임을 죽이기)없이이 작업을 수행하는 방법을 알아낼 수는 없습니다.

픽셀 형식 등을 처리 할 수 ​​있지만 메모리에서 실제 GraphicBuffer를 만드는 데 도움이 필요합니다.

답변

1

짧은 대답은 할 수 없습니다. GraphicBuffer 뒤에있는 메모리는 액세스해야하는 하드웨어 유닛 (gpu, 카메라, 비디오 코덱, 디스플레이 등)의 요구 사항을 기반으로 OS에 의해 할당되어야하며 프로세스에서 안전하게 공유 할 수 있어야합니다. void * 이러한 요구 사항을 충족하지 못합니다.

저는 카메라 API에 익숙하지 않지만 버퍼를 소비 할 시스템에서 Surface를 가져 와서 버퍼를 생성 할 수 있도록 Surface를 카메라 API에 제공합니다. 아래에서는 제작자 (카메라)와 소비자 모두와 호환되는 GraphicBuffers 집합을 할당하고 하드웨어에서 가능하면 0 복사본으로 프레임을 스트림합니다.

0

Jesse의 말에 더하여, IMemory는 GraphicBuffer와는 다른 공유 메모리 버퍼 (ashmem 기반)이며 직접 호환되지 않습니다.

또한 dataCallbackTimestamp에 직접 연결하여 공용 카메라 API 외부에서 구현 세부 정보로 이동하고 있습니다. 이러한 것들은 동일한 릴리스 - 투 - 릴리즈를 유지하는 것이 보장되지 않으므로,이를 사용함으로써 향후 (또는 과거의) OS 릴리스에서 애플리케이션을 무방비로 만들 위험이 있습니다.

더 이상 사용되지 않는 카메라 API (잘, 그것의 내부 구조)와 오래된 HAL을 사용하고 있기 때문에, 일종의 memcpy 없이는 할 수있는 일이별로 없습니다.

GPU SurfaceTexture를 카메라 API의 미리보기로 전달한 다음 MediaCodec의 Surface에 EGL의 4K 텍스처를 그릴 수 있습니다 (비디오를 인코딩하려는 경우 어쨌든 GraphicBuffers가 진행).

관련 문제