라이브 카메라 데이터 (Y 평면에서)에 대해 CPU 측 읽기 전용 프로세스를 수행 한 다음 GPU에서 렌더링해야합니다. 처리가 완료 될 때까지 프레임이 렌더링되어서는 안됩니다. (그래서 항상 카메라에서 최신 프레임을 렌더링하고 싶지는 않습니다. CPU 쪽에서 처리가 끝난 최신 프레임 만 렌더링합니다.) 렌더링은 카메라 처리와 분리되어 카메라 프레임이 그보다 낮은 속도로 도착하더라도 60FPS를 목표로합니다.안드로이드에서 제로 복사 카메라 처리 및 렌더링 파이프 라인
관련 그러나 높은 수준의 질문에 이상있다 : Lowest overhead camera to CPU to GPU approach on android
좀 더 구체적으로 현재 설정을 설명하기 위해 우리가 버퍼 중 하나 "무료"입니다 카메라 데이터에 대한 응용 프로그램 측 버퍼 풀을 가지고, "in display"또는 "pending display"를 선택하십시오. 카메라의 새로운 프레임이 도착하면 사용 가능한 버퍼를 확보하고 거기에 실제 데이터가있는 경우 프레임 참조 (또는 시스템 참조 버퍼 풀에있는 참조)를 저장하고 처리 한 다음 결과를 버퍼에 저장합니다. 버퍼를 "pending display"로 설정하십시오. 렌더러 스레드에서 렌더링 루프의 시작 부분에 버퍼링 "표시 대기 중"이 있으면 대신 "디스플레이 중"으로 래칭하여 카메라를 렌더링하고 동일한 루프에서 계산 된 처리 된 정보를 사용하여 다른 내용을 렌더링합니다 카메라 프레임입니다.
위의 질문에 대한 @ fadden의 답변 덕분에 이제 Android camera2 API의 "병렬 출력"기능이 다양한 출력 대기열 사이의 버퍼를 공유하므로 데이터 사본을 포함하지 않아야합니다. 현대 안드로이드.
의견에는 SurfaceTexture 및 ImageReader 출력을 동시에 래치 할 수 있으며 처리가 완료 될 때까지 "버퍼에 앉는다"는 제안이있었습니다. 불행히도 필자는 여전히 60 FPS로 구동하고 싶은 분리 된 렌더링으로 인해 내 경우에는 적용 할 수 없다고 생각하며, 이전 프레임에 대한 액세스가 필요하지만 새로운 프레임이 처리되지 않는 것을 보장하기 위해 계속 처리해야합니다. 싱크 아웃
마음에 떠오르는 한 가지 해결책은 여러 개의 SurfaceTexture (각 3 개의 앱 사이드 버퍼에 하나씩)를 사용하는 것입니다. 우리가 새로운 카메라 프레임을 얻었을 때, 우리는 앱 측 풀에서 무료 버퍼를 얻을 수있었습니다. 그런 다음 ImageReader에 acquireLatestImage()
을 호출하여 처리 할 데이터를 얻은 다음 사용 가능한 버퍼의 SurfaceTexture에 updateTexImage()
을 호출합니다. 렌더링시 우리는 "디스플레이에있는"버퍼의 SufaceTexture가 GL에 바인드 된 버퍼인지 확인해야합니다. 대부분의 경우 동기화가 이루어져야합니다 (@fadden이 updateTexImage()
과 acquireLatestImage()
을 호출하는 경합이 있다고 설명했기 때문에). 하지만 그 시간 창은 희소성을 줄 수있을만큼 작아야하고 어쨌든 버퍼의 타임 스탬프를 사용하여 수정 및 수정 가능할 수 있습니다.
SurfaceTexture가 GL 컨텍스트에 바인딩 된 경우에만 updateTexImage()
이 호출 될 수 있다는 점에 유의하십시오. 카메라 처리 스레드에서도 GL 컨텍스트가 필요하므로 SurfaceTexture에서 updateTexImage()
을 수행 할 수 있습니다. 렌더링 스레드가 여전히 "디스플레이중인"버퍼의 SurfaceTexture에서 렌더링 할 수있는 동안 "자유"버퍼에 저장됩니다.
그래서, 질문에 :
는- 이 합리적인 접근 방식처럼 보이는가?
- SurfaceTexture는 기본적으로 공유 버퍼 풀을 둘러싼 가벼운 래퍼입니까? 아니면 제한된 하드웨어 리소스를 소비합니까?
- SurfaceTexture 호출이 충분히 저렴하여 여러 것을 사용하면 데이터를 복사하는 것보다 여전히 큰 이점이 있습니까?
- 각기 다른 SurfaceTexture를 사용하여 구별되는 GL 문맥이있는 두 개의 스레드가 작동 할 계획입니까 아니면 고통과 버그가 많은 드라이버가 필요한지 묻고 싶습니까?
나는 그것이 가야할만큼 유망한 것으로 들린다. 아무리 나쁜 생각이라도 간과 해 버린 내부 세부 사항을 알고있는 사람 (기본적으로 @fadden!)이 있으면 여기에 질문 할 가치가 있다고 생각했습니다.
큰 설명에 감사 드리며 실행 가능한 접근 방식처럼 들립니다. 주말에 내가 조롱 할거야. 아마도 이것을 github에 넣을 것입니까? – tangobravo
"동기화를위한 일반적인 단계"에 따르면 렌더 스레드가 렌더링을 위해 첨부하기 전에'updateTexImage()'를 호출하는 스레드가 반드시'detachFromGLContext()'를 호출 했어야합니다. 연결된 grafika 버그에서 언급 한 것처럼 텍스처가 공유되도록 설정된 경우에 필요한 'glFinish()'요구 사항은 없습니까? – tangobravo
API 19의 이미지에는 ['getTimestamp()'] (https://developer.android.com/reference/android/media/Image.html#getTimestamp())가 있습니다. 타임 스탬프를 SurfaceTexture로 사용하지만 접근 방식을 테스트 할 때이를 확인할 것입니다. – tangobravo