2011-03-23 8 views
1

저는 그레이 스케일 비디오를 녹화하고 카메라 롤에 저장해야하는 아이폰 앱을 만들고 있습니다. 나는 이것에 가장 접근하는 방법에 난처하다.아이폰에서 그레이 스케일 비디오를 녹화하는 방법은 무엇입니까?

나는 다음과 같은 라인을 따라 생각하고 :

  1. 가 파일에 비디오를 작성하는
  2. 사용 AVFoundation (AN AVAssetWriterInputPixelBufferAdaptor와 AVAssetWriter)를 그레이 스케일로 비디오를 변환하는 쉐이더 및 OpenGL을 사용합니다.

내 질문은 :

  1. 이 올바른 접근 방법 (간단한, 최상의 성능)인가?
  2. 그렇다면 AVAsetWriterInputPixelBufferAdaptor에 대한 OpenGL 출력에서 ​​CVPixelBufferRef 입력으로 이동하는 가장 좋은 방법은 무엇입니까?
  3. 그렇지 않은 경우 더 나은 방법은 무엇입니까?

올바른 방향으로 조금 움직여주세요.

답변

4

일반적으로이 방법에 동의합니다. OpenGL ES 2.0 쉐이더에서 처리하는 것은 이와 같이 비디오 프레임 변경을 수행하는 가장 효과적인 방법이어야하지만 매우 간단하지는 않습니다. 다행히 이미이를 수행하는 기존 템플리트에서 시작할 수 있습니다.

here (및 설명 된 here) 샘플을 사용할 수 있습니다. 이 예제에서는 사용자 정의 쉐이더를 사용하여 이미지의 색상을 추적하지만,이를 쉽게 변경하여 비디오 프레임을 회색 음영으로 변환 할 수 있습니다 (나는 한 번이 작업을 한 번 보았습니다). 텍스처에 카메라 비디오를 공급하고 처리하기위한 코드는 샘플에서 그대로 사용할 수 있습니다.

해당 응용 프로그램의 표시 옵션 중 하나에서 처리 된 이미지를 먼저 프레임 버퍼 개체로 렌더링 한 다음 glReadPixels()을 사용하여 결과 이미지를 CPU에서 사용할 수있는 바이트로 다시 가져옵니다. 이것을 사용하여 GPU가 프레임을 처리 한 후 원시 이미지 데이터를 얻은 다음 해당 바이트를 CVPixelBufferCreateWithBytes()에 공급하여 디스크에 쓰기위한 CVPixelBufferRef를 생성 할 수 있습니다.

(업데이트 : 2/29/2012) 이에 대한 업데이트로 방금 오픈 소스 GPUImage 프레임 워크에서 이러한 종류의 비디오 레코딩을 구현 했으므로 인코딩 부분의 특정 성능에 대해 언급 할 수 있습니다. 카메라에서 비디오를 캡쳐하고, 라이브 필터링을 수행하고, glReadPixels()을 사용하여 OpenGL ES에서 잡아서 30fps에서 iPhone 4의 640x480 프레임으로 라이브 H.264 비디오로 기록 할 수 있습니다 (최대 카메라 프레임 레이트).

녹음 속도를 높이려면 몇 가지 작업이 필요했습니다. 입력 픽셀 버퍼의 색상 형식으로 kCVPixelFormatType_32BGRA을 사용하도록 AVAssetWriterInputPixelBufferAdaptor를 설정해야합니다. 그런 다음 glReadPixels()을 사용할 때 BGRA 출력을 제공하기 위해 색상 스위 즐링 쉐이더를 사용하여 RGBA 장면을 다시 렌더링해야합니다. 이 색상 설정을 사용하지 않으면 동영상 녹화 프레임 속도가 iPhone 4에서 5-8 FPS로 떨어지며 30 프레임을 쉽게 맞 춥니 다. GPUImageMovieWriter 클래스 소스 코드를 보면 어떻게하는지 알 수 있습니다.

위의 필터링 및 인코딩 작업은 GPUImage 프레임 워크를 사용하여 단순히 GPUImageVideoCamera를 만들고 GPUImageSaturationFilter의 대상을 0으로 설정된 채도에 연결 한 다음 GPUImageMovieWriter를 대상으로 연결하여 처리 할 수 ​​있습니다. 이 프레임 워크는 OpenGL ES 상호 작용을 처리합니다. 나는이 작업을 수행했으며 테스트 한 모든 iOS 장치에서 잘 작동합니다.

+0

귀하의 의견에 감사드립니다. 이 접근법을 구현하고 구현하는 방법을 살펴 보겠습니다. – adriaan

+0

Brad에게 감사합니다! 나는 위대한 작품이 접근법을 시도했지만 한 가지 문제가 있습니다. glReadPixels()을 사용하여 캡처 한 결과 이미지는 미리보기 뷰포트 크기입니다. 캡처중인 비디오는 iPhone 화면 (480 * 640)보다 커야합니다. 스크린에서 축소 된 크기로 볼 수 있고 원본 카메라의 디스크에 저장할 수있는 쉐이더를 적용 할 수있는 방법이 있습니까? 크기 (필자의 경우 640 * 480)? –

+0

@AmirNaor - 예, 처리 할 비디오만큼 큰 오프 스크린 프레임 버퍼를 만들어야합니다. 위의 예에서 필자는 색상 처리를위한 iPhone 4의 디스플레이보다 작은 오프 스크린 버퍼를 작성하므로 대신 화면보다 커질 수 있습니다. 결과를 텍스처로 사용하고 그 텍스처를 화면 크기의 사각형으로 사용한다면 화면을 잘 다운 샘플링 할 수 있어야합니다. –

관련 문제