Jak bezpośrednio aktualizować piksele - za pomocą CGImage i bezpośredniego CGDataProvider

Rzeczywiste pytanie

Kilka odpowiedzi rozwiąże mój problem:

Czy mogę wymusićCGImage przeładować swoje dane od bezpośredniego dostawcy danych (utworzonego za pomocąCGDataProviderCreateDirect) lubićCGContextDrawImage robi? A może w jakiś inny sposób mogę ustawić ustawienie self.layer.contents, aby to zrobić?Czy jestCGContext konfiguracja lub sztuczka, której mogę użyć do renderowania obrazów 1024x768 z prędkością co najmniej 30 fpsCGContextDrawImage.Czy ktoś był w stanie z powodzeniem korzystaćCVOpenGLESTextureCacheCreateTextureFromImage dla aktualizacji bufora w czasie rzeczywistym z ich własnymi danymi tekstury? Myślę, że moim największym problemem jest stworzenieCVImageBuffer jak skopiowałem inne właściwości z dokumentacji Jabłek dla tekstur. Gdyby ktoś miał więcej informacji na ten temat, byłby niesamowity.Wszelkie inne wskazówki dotyczące sposobu, w jaki mogę uzyskać obraz z pamięci na ekranie przy 30 fps.

Tło (działki):

Pracuję nad projektem, w którym muszę zmodyfikować piksele danych obrazu NPOT w czasie rzeczywistym (minimum 30 fps) i narysować je na ekranie w iOS.

Moją pierwszą myślą było użycie OpenGL zglTexSubimage2D aby zaktualizować, niestety zakończyło się to bardzo powoli (6 fps na iPadzie), ponieważ sterownik zamienia i konwertuje moje dane RGB na każdą klatkę do BGR. Więc wyślij to w BGR, a ty też, ale z jakiegoś powodu nie możesz zadzwonićglTexSubImage2D zGL_BGR domyśl. Wiem, że niektóre powolności wynikają z braku mocy 2 danych obrazu, ale moje wymagania dyktują to.

Więcej czytania doprowadziło mnie doCVOpenGLESTextureCacheCreateTextureFromImage ale wszystkie przykłady dotyczą bezpośredniego wejścia kamery w celu uzyskaniaCVImageBufferRef Próbowałem użyć dokumentacji (brak oficjalnych, ale tylko nagłówkowych komentarzy), aby mój własny CVImageBuffer tworzył moje dane obrazu, ale nie działałby z tym (bez błędów tylko pusta tekstura w debuggerze), co sprawia, że ​​myślę, że Apple zbudował to specjalnie przetwarzać dane kamery w czasie rzeczywistym i nie zostało przetestowane poza tym obszarem, ale IDK.

W każdym razie po porzuceniu mojej godności przez zrzucenie OpenGL i przełączenie moich myśli na CoreGraphics zostałem poprowadzony do tego pytanianajszybszy sposób na narysowanie bufora ekranu w telefonie iPhone który zaleca używanie aCGImage wspierane przezCGDataProviderCreateDirect, który pozwala na powrót wskaźnika do danych obrazu, gdy CGImage tego potrzebuje, świetny, prawda? Cóż, wydaje się, że nie działa tak, jak reklamowano. Jeśli używamCGContextDrawImage wtedy wszystko działa. Mogę modyfikować bufor pikseli, a każde losowanie żąda danych obrazu od mojego dostawcy danych, tak jak powinien, wywołując metodyCGDataProviderDirectCallbacks (Note: wydają się mieć wbudowaną optymalizację, która ignoruje zaktualizowany wskaźnik, jeśli ma ten sam adres, co poprzedni). CGContextDrawImage nie jest super szybki (około 18 klatek na sekundę), nawet przy wyłączonej interpolacji, która spowodowała wzrost z 6 fps. Dokumenty Apple mówią mi o użyciuself.layer.contents będzie znacznie szybszy niżCGContextDrawImage. Za pomocąself.layer.contents działa dla pierwszego zadania, aleCGImage nigdy nie żąda przeładowania od dostawcy danych, takiego jakCGContextDrawImage robi, nawet gdy dzwonię[layer setNeedsDisplay]. W zadanym przeze mnie pytaniu SO użytkownik pokazuje swoje rozwiązanie problemu, tworząc i niszcząc nowy obraz CGImage ze źródła danych w każdej klatce, beznadziejnie powolny proces (tak, spróbowałem), więc czas na prawdziwe pytanie.

Uwaga: Wyprofilowałem wszystkie te operacje i wiem, że problem naprawdę istniejeglTexSubImage dla OpenGL iCGContextDrawImage to naprawdę problem z CoreGraphics, więc nie ma odpowiedzi „przejdź do profilu”.

EDYTOWAĆ Kod źródłowy demonstrujący tę technikę można teraz znaleźć na stroniehttp://github.com/narpas/image-sequence-streaming

questionAnswers(1)

yourAnswerToTheQuestion