2011-11-07 8 views
6

Obecnie programuję aplikację, która wyodrębnia klatki z klipu filmowego. Zaprojektowałem go tak, aby ekstrakcja odbywała się na oddzielnym wątku, aby zapobiec zamarznięciu aplikacji. Sam proces ekstrakcji zabiera wiele zasobów, ale działa dobrze, gdy jest wykorzystywany w symulatorze. Są jednak problemy z budową iPada. Kiedy wykonuję kolejną akcję (mówię odtwarzaczowi AV, żebym grał, podczas gdy wyodrębniam ramki), wątek niespodziewanie przestaje działać i uważam, że został zabity.Wątek jest zabijany przez OS

Zakładam, że to dlatego, że używam dużych zasobów, ale nie jestem do końca pewien.

Oto moje pytania: 1. Jak mogę sprawdzić, czy/dlaczego moja wątek się zatrzymuje? 2. Jeśli naprawdę chodzi o przerost przetwarzania, co powinienem zrobić? Naprawdę potrzebuję tej akcji do wdrożenia.

Herezje niektóre kod im przy: Aby utworzyć wątek:

[NSThread detachNewThreadSelector:@selector(startReading) toTarget:self withObject:nil];

wyślę wszelkich potrzebnych informacji, Dzięki tak dużo!

Aktualizacja Używam GCD teraz i zapełnia dla mnie wątki. Jednak system operacyjny nadal zabija wątki.

Wiem dokładnie, kiedy to się dzieje. kiedy mówię mojemu [gra AVPlayer]; zabija wątek.

Ten problem dzieje się tylko w rzeczywistym iPada, a nie na symulatorze

+0

Jeśli musisz zapytać, spróbuj użyć abstrakcji wyższego poziomu, na przykład kolejek wysyłkowych (GCD) lub kolejek operacyjnych (NSOperationQueue).Zobacz [Przenoszenie z wątków] (http://developer.apple.com/library/mac/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/ConcurrencyandApplicationDesign/ConcurrencyandApplicationDesign.html#//apple_ref/doc/uid/TP40008091-CH100- SW8) do rozszerzonej dyskusji lub poszukaj przykładu [GCD] (http://stackoverflow.com/questions/7941860/#7941898) lub [NSOperationQueue] (http://stackoverflow.com/questions/830218/). To bardzo przydatne rzeczy. – Jano

+1

powoduje awarię Twojej aplikacji? jeśli tak, co mówi raport o awarii? jesteś pewien, że AVPlayer jest bezpieczny dla wątków? ponieważ jeśli dzwonisz do [odtwarzania AVplayer] i uzyskujesz dostęp do niego w tym samym czasie w wątku tła, może to być problem. – JeanLuc

+0

Czy twój wątek do ekstrakcji działa jako wątek tła? Uczę się Objective-C, ale jeśli jesteś w stanie uruchomić go jako wątek w tle, możesz pomóc nie zostać zabitym przez system operacyjny. –

Odpowiedz

0

Kiedy coś działa w symulatorze i nie działa na urządzeniu, oczywistym wyjaśnieniem jest to kwestia ograniczenia zasobów na pewno. Ale czasami symulator nie potrafi dokładnie symulować innych aspektów działania urządzenia. Zastanawiałem się, czy w tej sytuacji mogłaby być jakakolwiek inna interpretacja. Jedna możliwość przyszła mi do głowy, że może to być rywalizacja o ograniczony dostęp do zasobów AV - co oznacza, że ​​po rozpoczęciu gry nie jest już dostępna do przetworzenia (i z jakiegoś powodu błąd w symulatorze) nie wyświetla to ograniczenie)

W AV Foundation Programming Guide, under "Playing Assets" stanach firmy Apple.

Chociaż ostatecznie chcesz grać atut, nie dostarczają aktywa bezpośrednio do obiektu AVPlayer. Zamiast tego podajesz instancję AVPlayerItem. Element gracza zarządza stanem prezentacji zasobu, z którym jest powiązany. Pozycja gracza zawiera elementy odtwarzacza - wystąpienia AVPlayerItemTrack - odpowiadające utworom w zasobie.

Ta abstrakcja oznacza, że ​​możesz odtwarzać dane zasoby przy użyciu różnych graczy jednocześnie, ale renderowane na różne sposoby przez każdego gracza. Korzystając ze ścieżek elementów, możesz na przykład wyłączyć określoną ścieżkę podczas odtwarzania (możesz nie chcieć odtwarzać komponentu dźwiękowego).

Zastanawiam się - czy używasz AVPlayerItems do uzyskiwania dostępu do zasobów, co pozwoliłoby obu operacjom jednocześnie? Jeśli tak, to przynajmniej ten konkretny kierunek jest wykluczony. Ale jeśli nie, warto byłoby zbadać, czy to rozwiązuje problem.

Może być chwytający za słomki. Ale może gdzieś poprowadzić.

+0

Teraz wiem, że po przeczytaniu ramek z zasobu po tym, jak zainicjowałem AVPlayer z tym zasobem, wątek się zatrzymuje, ale jak mogę to pominąć? –

+0

Jeśli nie uzyskujesz dostępu do zasobu za pośrednictwem elementu AVPlayerItem, powinieneś podać jedną instancję AVPlayerItem do odtworzenia zasobu oraz drugą instancję AVPlayerItem do odczytywania klatek z zasobu. Powinno to pozwolić na jednoczesne wystąpienie obu. –

+0

Używam zasobu AVPlayer do odtworzenia zasobu, ale nie odczytu ramek. Do tego używam AVAssetReader Który jest inicjowany z samym zasobem. Jak możesz to zaproponować? –

0

W sekcji „Ustawianie rozmiaru stosu wątku” firmy Apple Programowanie Threading podręczniku, strona 27 mówi:

w iOS i Mac OS X 10.5 i nowszych, przydzielać i zainicjować NSThread obiektu (nie używać detachNewThreadSelector: toTarget: withObject: metoda)

Nawet na stronie 22 mówi detachNewThreadSelector jest jednym ze sposobów, aby tworzyć wątki używając NSThread.

I to daje ten przykład na stronie 23 jak rozpocząć wątek:

NSThread* myThread = [[NSThread alloc] initWithTarget:self selector:@selector(myThreadMainMethod:) object:nil]; 
[myThread start]; 

Według przewodnika, który stworzy wolnostojący wątek w swojej aplikacji. Spróbuj utworzyć wątek w ten sposób i sprawdź, czy system operacyjny przestaje zabijać twój wątek.

Dla odniesienia tu jest link do przewodnika

http://developer.apple.com/library/ios/iPad/#documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html#//apple_ref/doc/uid/10000057i-CH15-SW2

wspomina również na stronie 29, że jeśli aplikacja korzysta z zarządzanego modelu pamięci, co wydaje Ci się, tworząc basen autorelease w swoim wątku Procedura wprowadzania powinna być pierwszą rzeczą, którą robisz i podobnie niszcząc ją, ostatnią rzeczą, którą robi wątek. Nie jestem pewien, czy nie spowodowałoby to zabicia twojego wątku, ale zweryfikuj to.

Posiadanie bloku prób/catch w procedurze wprowadzania wątku może nie rozwiązać problemu zabicia, ale pozwoli uniknąć zamykania aplikacji, jeśli wystąpi błąd w wątku.

Zapomniałem wspomnieć o tej drugiej końcówce projektu, która może pomóc w ograniczeniu zasobów, jak wspomniał Duncan. Według strony prowadnicy 18:

Unikaj Struktury danych udostępnionych

Najprostszym i najłatwiejszym sposobem na uniknięcie związanych z nici-resource konfliktów jest, aby każdy wątek w programie własną kopię cokolwiek dane, wymagania. Kod równoległy działa najlepiej, gdy zminimalizujesz komunikację i rywalizację o zasoby między wątkami.

Co, myślę, że możesz to zrobić w swojej aplikacji. Oprócz robienia tego, o czym wspomniał Duncan, "nie dostarczaj zasobów bezpośrednio do obiektu AVPlayer, ale zamiast tego dostarczaj instancji AVPlayerItem", rób to, tworząc oddzielne instancje dla każdego wątku, jedną instancję AVPlayerItem dla wątku odtwarzacza i jedną instancję AVPlayerItem dla nitka ekstrakcyjna.

1

Wydaje mi się, że próbujesz odkodować dwa klipy wideo w tym samym czasie. Ze względu na sprzętowy charakter dekodowania iPada, może on obsługiwać tylko jeden proces dekodowania naraz. Podczas odtwarzania nowego przedmiotu stare zostanie anulowane. To wyjaśniałoby, dlaczego działa w symulatorze, ale nie na urządzeniu.

Jeśli chodzi o rozwiązanie, można przełączyć się na czysty programowy dekoder, taki jak libav (GPL) lub CoreAVC SDK (komercyjny). W ten sposób nie będziesz zakłócać odtwarzania dekodera HW.

Powiązane problemy