2010-11-21 4 views

Odpowiedz

19

Jako iOS 4.0, można użyć AVCaptureDeviceInput dostać aparat jako urządzenie wejścia i podłączyć go do AVCaptureVideoDataOutput z dowolnego obiektu lubisz ustawionego jako delegata. Po ustawieniu formatu BGRA na poziomie 32bpp dla kamery, obiekt uczestnika otrzyma każdą ramkę z kamery w formacie idealnym do natychmiastowego przekazania do glTexImage2D (lub glTexSubImage2D, jeśli urządzenie nie obsługuje tekstur o braku mocy dwóch; uważam, że urządzenia MBX należą do tej kategorii).

Istnieje wiele opcji rozmiaru klatki i liczby klatek na sekundę; Zgadnij, że będziesz musiał poprawić te, w zależności od tego, ile chcesz użyć GPU. Odkryłem, że całkowicie trywialna scena z tylko teksturowanym quadem, pokazującym ostatnią klatkę, przerysowaną dokładnie wtedy, gdy nowa ramka pojawia się na iPhonie 4, była w stanie wyświetlić maksymalny 720p 24 fps tego urządzenia bez zauważalnego opóźnienia. Nie przeprowadziłem dokładniejszej analizy porównawczej niż ta, więc mam nadzieję, że ktoś inny może doradzić.

Zasadniczo, za pomocą API, ramki mogą powracać z wewnętrznym wypełnieniem pamięci pomiędzy liniami skanowania, co oznaczałoby pewne przetasowanie zawartości przed wysłaniem do GL, więc musisz zaimplementować ścieżkę do tego kodu. W praktyce, mówiąc czysto empirycznie, wydaje się, że obecna wersja iOS nigdy nie zwraca obrazów w tej formie, więc nie jest to naprawdę problem z wydajnością.

EDYCJA: teraz jest bardzo blisko trzy lata później. W międzyczasie Apple wypuściło iOS 5, 6 i 7. Wraz z 5 wprowadzono CVOpenGLESTexture i CVOpenGLESTextureCache, które są teraz inteligentnym sposobem na przesyłanie wideo z urządzenia przechwytującego do OpenGL. Apple dostarcza przykładowy kod here, z którego szczególnie interesujące części znajdują się w RippleViewController.m, w szczególności jego setupAVCapture i captureOutput:didOutputSampleBuffer:fromConnection: - patrz wiersze 196-329. Niestety warunki uniknąć powielania kodu tutaj bez dołączania całego projektu, ale konfiguracja krok po kroku jest:

  1. stworzyć CVOpenGLESTextureCacheCreate i AVCaptureSession;
  2. zgarnij odpowiedni film wideo w postaci AVCaptureDevice;
  3. utwórz urządzenie AVCaptureDeviceInput za pomocą tego urządzenia przechwytującego;
  4. załóż urządzenie AVCaptureVideoDataOutput i powiedz, aby zadzwonił do ciebie jako delegat bufora próbek.

Po otrzymaniu każdego buforu do próbek:

  1. uzyskać CVImageBufferRef od niego;
  2. użyć CVOpenGLESTextureCacheCreateTextureFromImage, aby uzyskać Y i UV CVOpenGLESTextureRef s z bufora obrazu CV;
  3. pobierz obiekty i nazwy tekstur z tekstowych wzorców CV OpenGLES, aby je powiązać;
  4. łączą luminację i chrominację w cieniu.
+0

Dzięki za odpowiedź. Wykopam to. – Eonil

+1

To tylko około 200 linii, aby powiązać całość; Przepraszam, że nie publikuję kodu - rozwiązałem ten problem tylko w pracy, więc nie mam obowiązku publikowania tego, co mam. Ale to naprawdę trywialne rzeczy i zdecydowanie spędziłem dużo dłużej zastanawiając się, które klasy były odpowiednie w dokumentacji, niż kodowanie. – Tommy

+0

@Eonil Jeśli podoba ci się jego odpowiedź, zaznacz ją jako zaakceptowaną odpowiedź. – pr1001

0

Użyj RosyWriter, aby uzyskać lepszy przykład wykonania renderowania wideo OpenGL. Wydajność jest bardzo dobra, szczególnie w przypadku zmniejszenia liczby klatek na sekundę (~ 10% przy 1080P/30,> = 5% przy 1080P/15.

Powiązane problemy