2011-11-07 16 views
6

Attualmente sto programmando un'app che estrae i fotogrammi da un clip filmato. L'ho progettato in modo che l'estrazione venga eseguita su una filettatura separata per impedire il congelamento dell'applicazione. Il processo di estrazione in sé richiede molte risorse, ma funziona bene se usato nel simulatore. Tuttavia, ci sono problemi quando lo costruisci per l'iPad. Quando eseguo un'altra azione (sto dicendo al mio riproduttore AV di suonare mentre estraggo i frame), il thread inaspettatamente smette di funzionare, e credo che venga ucciso.Il thread viene ucciso dall'OS

Suppongo sia perché sto usando molte risorse, ma non del tutto sicuro.

Ecco le mie domande: 1. Come posso sapere se/perché il mio thread si arresta? 2. Se si tratta davvero di un'ulteriore elaborazione, cosa devo fare? Ho davvero bisogno che questa azione sia implementata.

Heres alcuni im codice utilizzando: Per creare il filo:

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

vi posterò tutte le informazioni necessarie, Grazie mille!

Aggiornamento Attualmente sto utilizzando GCD e compila i thread per me. Tuttavia il sistema operativo uccide ancora i thread.

So esattamente quando succede. quando dico al mio [gioco di AVplayer]; uccide il filo.

Questo problema sta accadendo solo nel reale iPad e non sul simulatore

+0

Se si deve chiedere, provare invece a utilizzare un'astrazione di livello superiore, come le code di invio (GCD) o le code di operazioni (NSOperationQueue).Vedi [The Move Away from Threads] (http://developer.apple.com/library/mac/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/ConcurrencyandApplicationDesign/ConcurrencyandApplicationDesign.html#//apple_ref/doc/uid/TP40008091-CH100- SW8) per una discussione estesa o cercare un esempio [GCD] (http://stackoverflow.com/questions/7941860/#7941898) o [NSOperationQueue] (http://stackoverflow.com/questions/830218/). È roba molto utile. – Jano

+1

la tua app si arresta in modo anomalo? se sì, cosa dice il rapporto sul crash? sei sicuro che AVPlayer sia protetto da thread? perché se stai chiamando [riproduzione di AVplayer] e accedendo allo stesso tempo in un thread in background, questo potrebbe essere il problema. – JeanLuc

+0

Il thread di estrazione è in esecuzione come thread in background? Sto imparando Objective-C ma, se si è in grado di eseguirlo come thread in background può aiutare a non essere ucciso dal sistema operativo. –

risposta

0

Quando qualcosa funziona nel simulatore e non funziona su un dispositivo, una spiegazione ovvia è una questione vincolo risorsa di sicuro. Ma a volte il simulatore non riesce a simulare accuratamente anche altri aspetti del funzionamento del dispositivo. Quindi mi chiedevo se ci potesse essere un'altra interpretazione della situazione. Una possibilità mi è sembrata che potesse essere una competizione per un accesso limitato alle risorse nell'Asset- to AV, il che significa che quando inizi a giocare, non è più disponibile per essere elaborato (e per qualche ragione un bug nel simulatore non visualizza questa limitazione)

Negli AV Foundation Programming Guide, under "Playing Assets" di Apple afferma:.

Anche se in ultima analisi, si vuole giocare un bene, non si forniscono beni direttamente ad un oggetto AVPlayer. Invece, si fornisce un'istanza di AVPlayerItem. Un elemento giocatore gestisce lo stato di presentazione di un bene a cui è associato. Un elemento giocatore contiene tracce elemento giocatore - istanze di AVPlayerItemTrack - che corrispondono alle tracce nella risorsa.

Questa astrazione significa che è possibile giocare a una determinata risorsa utilizzando diversi giocatori contemporaneamente, ma resi in modi diversi da ogni giocatore. Utilizzando le tracce degli elementi, è possibile, ad esempio, disabilitare una particolare traccia durante la riproduzione (potrebbe non essere possibile riprodurre il componente audio).

Quindi mi sono chiesto-stai usando AVPlayerItems per accedere alle tue risorse, che permetterebbe ad entrambe le operazioni di accadere contemporaneamente? Se è così, almeno quella direzione specifica è esclusa. Ma se no, potrebbe valere la pena indagare per vedere se risolve il problema.

Potrebbe aggrapparsi a cannucce. Ma potrebbe portare da qualche parte.

+0

Ora so per certo che quando ho letto i frame dalla risorsa dopo aver avviato un AVPlayer con questa risorsa, il thread si interrompe, ma come faccio a ignorarlo? –

+0

Se non si accede alla risorsa tramite AVPlayerItem, è necessario fornire un'istanza di AVPlayerItem per riprodurre la risorsa e una seconda istanza di AVPlayerItem per leggere i frame dalla risorsa. Ciò dovrebbe consentire a entrambi di verificarsi contemporaneamente. –

+0

Uso la risorsa di AVPlayer per riprodurre la risorsa ma non per leggere i frame. Per quel im utilizzando AVAssetReader Che viene avviato con la risorsa stessa. Come ti suggerirei di farlo? –

0

Nella sezione 'Impostazione della dimensione dello stack di un filo' di Guida alla programmazione Threading di Apple, pagina 27 dice:

in IOS e Mac OS X v10.5 e successive, allocare e inizializzare un oggetto NSThread (non usare detachNewThreadSelector: toTarget: withObject: metodo)

Anche se a pagina 22 dice detachNewThreadSelector è uno dei modi per creare discussioni con NSThread.

E dà questo esempio nella pagina 23 di come avviare il filo:

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

Secondo la guida che creerà un filo staccato nella vostra applicazione. Prova a creare il tuo thread in questo modo e vedere se il sistema operativo smette di uccidere il thread.

Per riferimento ecco il link alla guida

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

Si menziona anche nella pagina 29 che se la vostra applicazione utilizza il modello di memoria gestita, che sembra sei, la creazione di una piscina autorelease nel tuo thread la routine di inserimento dovrebbe essere la prima cosa che fai e allo stesso modo distruggerla l'ultima cosa che fa il tuo thread. Non sono sicuro che questo non avrebbe causato l'uccisione della tua discussione, ma verifica che tu faccia questo.

Avere un blocco try/catch nella routine di immissione del thread potrebbe non risolvere il problema dell'uccisione, ma eviterà l'uscita della app se si verifica un errore nel thread.

Ho dimenticato di menzionare questo altro suggerimento di progettazione che può aiutare con i limiti di risorse, come Duncan menzionato. Secondo la pagina di guida 18:

evitare strutture di dati condivisi

Il modo più semplice e più semplice per evitare di thread relativi risorsa conflitti è quello di dare ogni thread nel vostro programma la propria copia di i dati eventualmente esigenze. Il codice parallelo funziona meglio quando si minimizza la comunicazione e la contesa di risorse tra i thread.

Quale, penso che puoi farlo nella tua app. Oltre a fare ciò che ha detto Duncan "non fornire risorse direttamente a un oggetto AVPlayer ma fornire un'istanza di AVPlayerItem", crea istanze separate per ciascuno dei tuoi thread, un'istanza di AVPlayerItem per il thread del lettore e un'istanza di AVPlayerItem per il filo di estrazione.

1

Mi sembra che si stia tentando di decodificare due video allo stesso tempo. A causa della natura di decodifica hardware dell'iPad, può supportare solo un processo di decodifica alla volta. Quando giochi un nuovo oggetto il vecchio sarà cancellato. Questo spiegherebbe perché funziona nel simulatore, ma non sul dispositivo.

Per quanto riguarda una soluzione, è possibile passare a un decodificatore software puro come libav (GPL) o allo CoreAVC SDK (commerciale). In questo modo non interferirai con il decodificatore HW per la riproduzione.

Problemi correlati