Domanda

C'è un modo per rilevare che un filtro grafico DirectShow ha raggiunto la fine del suo file? Alla fine del suo file, intendo che un filtrografo con un filtro SampleGrabber non riceverà mai un'altra chiamata SampleCB.

Ecco alcune cose che non funzionano:

  • Trust IMediaDet :: get_StreamLength (spesso dice che ci sono più frame in un video di quanti ne esistano davvero)
  • Trust IMediaSeeking :: GetDuration (è coerente con IMediaDet, +/- un frame)
  • Utilizza IMediaControl :: GetState (il filtro grafico rimane in esecuzione anche se tutti i frame sono già stati elaborati da un file)

Sfondo:

Sto elaborando un video e ho una classe che crea un filtrografo con un SampleGrabber. Ogni volta che viene chiamato SampleGrabber :: SampleCB , lo blocco con un mutex in modo da poter eseguire il filtro in modalità pull. Quando sono pronto per un altro fotogramma, sblocco il mutex nel mio thread principale e aspetto SampleGrabber :: SampleCB per inviarmi un segnale di completamento. Per alcuni video, IMediaDet :: get_StreamLength mi dice che il video ha più frame di quanti realmente esistano. Dopo aver estratto il fotogramma finale e averne richiesto uno in più di quello effettivamente esistente, il thread principale si blocca per sempre perché SampleGrabber :: SampleCB non verrà più richiamato. Mi piacerebbe essere in grado di rilevare quando SampleGrabber :: SampleCB non verrà mai chiamato per le origini dei file. Applicazioni come Windows Media Player sono in grado di farlo in qualche modo perché la GUI segnala che il video è terminato dopo l'ultimo fotogramma reale, quindi apparentemente c'è un modo per farlo.

Modifica

Sto usando WaitForSingleObject per implementare il blocco del thread principale. La soluzione alternativa che ho usato finora è fare ciò che Greg ha suggerito: avere un timeout limitato. Sfortunatamente, questo diventa un po 'complicato. L'attesa può fallire per molte ragioni come un vero eof, un filesystem di rete lento, una connessione di rete persa, un decodificatore lento, ecc.

È stato utile?

Soluzione

Forse usando l'interfaccia IMediaEventEx ? Uno dei codici evento è EC_COMPLETE documentato come "Tutti i dati di un determinato flusso sono stati resi."

Altri suggerimenti

Supponendo che il thread principale sia bloccato su WaitForSingleObject , non è possibile specificare un timeout per l'attesa? Quindi se l'attesa ritorna perché è scaduto piuttosto che perché ha ricevuto un segnale, saprai che è l'ultimo frame.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top