Classe CSourceSeeking
[La funzionalità associata a questa pagina, DirectShow, è una funzionalità legacy. È stata sostituita da MediaPlayer, FMMediaEngine e Audio/Video Capture in Media Foundation. Queste funzionalità sono state ottimizzate per Windows 10 e Windows 11. Microsoft consiglia vivamente che il nuovo codice usi MediaPlayer, FMMediaEngine e Audio/Video Capture in Media Foundation anziché DirectShow, quando possibile. Microsoft suggerisce che il codice esistente che usa le API legacy venga riscritto per usare le nuove API, se possibile.
La classe CSourceSeeking è una classe astratta per implementare la ricerca nei filtri di origine con un pin di output.
Questa classe supporta l'interfaccia IMediaSeeking . Fornisce implementazioni predefinite per tutti i metodi IMediaSeeking . Le variabili membro protette archiviano l'ora di inizio, l'ora di arresto e la frequenza corrente. Per impostazione predefinita, l'unico formato ora supportato dalla classe è TIME_FORMAT_MEDIA_TIME (100-nanosecondi). Per ulteriori informazioni, vedere la sezione Osservazioni.
Variabili membro protette | Descrizione |
---|---|
m_rtDuration | Durata del flusso. |
m_rtStart | Ora di inizio. |
m_rtStop | Arrestare il tempo. |
m_dRateSeeking | Frequenza di riproduzione. |
m_dwSeekingCaps | Ricerca di funzionalità. |
m_pLock | Puntatore a un oggetto sezione critica per il blocco. |
Metodi protetti | Descrizione |
CSourceSeeking | Metodo costruttore. |
Metodi virtuali pure | Descrizione |
ChangeRate | Chiamato quando cambia la frequenza di riproduzione. |
ChangeStart | Chiamato quando cambia la posizione iniziale. |
ChangeStop | Chiamato quando cambia la posizione di arresto. |
Metodi IMediaSeeking | Descrizione |
IsFormatSupported | Determina se è supportato un formato di tempo specificato. |
QueryPreferredFormat | Recupera il formato di tempo preferito dell'oggetto. |
SetTimeFormat | Imposta il formato ora. |
IsUsingTimeFormat | Determina se un formato ora specificato è il formato attualmente in uso. |
GetTimeFormat | Recupera il formato ora corrente. |
GetDuration | Recupera la durata del flusso. |
GetStopPosition | Recupera il tempo in cui la riproduzione si arresterà, rispetto alla durata del flusso. |
GetCurrentPosition | Recupera la posizione corrente, rispetto alla durata totale del flusso. |
GetCapabilities | Recupera tutte le funzionalità di ricerca del flusso. |
CheckCapabilities | Esegue query sul fatto che il flusso abbia specificato le funzionalità di ricerca. |
ConvertTimeFormat | Converte da un formato all'altro. |
SetPositions | Imposta la posizione corrente e la posizione di arresto. |
GetPositions | Recupera la posizione corrente e la posizione di arresto. |
GetAvailable | Recupera l'intervallo di volte in cui la ricerca è efficiente. |
SetRate | Imposta la frequenza di riproduzione. |
GetRate | Recupera la frequenza di riproduzione. |
GetPreroll | Recupera l'ora di preroll. |
Commenti
Ogni volta che la posizione iniziale, la posizione di arresto o la frequenza di riproduzione cambia, l'oggetto CSourceSeeking chiama un metodo virtuale puro corrispondente:
- Posizione iniziale: CSourceSeeking::ChangeStart
- Posizione di arresto: CSourceSeeking::ChangeStop
- Frequenza di riproduzione: CSourceSeeking::ChangeRate
La classe derivata deve implementare questi metodi. Dopo qualsiasi operazione di ricerca, un filtro deve eseguire le operazioni seguenti:
- Chiamare il metodo IPin::BeginFlush nel pin di input downstream.
- Arrestare il thread di lavoro che fornisce i dati.
- Chiamare il metodo IPin::EndFlush nel pin di input.
- Riavviare il thread di lavoro.
- Chiamare il metodo IPin::NewSegment nel pin di input.
- Impostare la proprietà di discontinuità nel primo esempio. Chiamare il metodo IMediaSample::SetDiscontinuity .
La chiamata a BeginFlush libera il thread di lavoro, se il thread è bloccato in attesa di consegnare un esempio.
Nel passaggio 2 assicurarsi che il thread abbia interrotto l'invio di dati. A seconda dell'implementazione, potrebbe essere necessario attendere che il thread venga chiuso o che il thread segnali una risposta di qualche tipo. Se il filtro usa la classe CSourceStream , il metodo CSourceStream::Stop blocca fino a quando il thread di lavoro risponde.
Idealmente, il nuovo segmento (passaggio 5) deve essere recapitato dal thread di lavoro. Può anche essere eseguita dall'oggetto CSourceSeeking , purché il filtro lo serializzi con gli esempi.
Nell'esempio seguente viene illustrata una possibile implementazione. Si presuppone che il pin di output del filtro di origine sia derivato da CSourceSeeking e CSourceStream. In questo esempio viene definito un metodo helper, UpdateFromSeek, che esegue i passaggi 1 4. Il metodo CSourceStream::OnThreadStartPlay viene sottoposto a override per inviare il nuovo segmento e per impostare un flag che indica la discontinuità. Il thread di lavoro seleziona questo flag e chiama il metodo IMediaSample::SetDiscontinuity :
void CMyStream::UpdateFromSeek()
{
if (ThreadExists())
{
DeliverBeginFlush();
Stop();
DeliverEndFlush();
Run();
}
}
HRESULT CMyStream::OnThreadStartPlay()
{
m_bDiscontinuity = TRUE;
return DeliverNewSegment(m_rtStart, m_rtStop, m_dRateSeeking);
}
Supporto di formati di tempo aggiuntivi
Per impostazione predefinita, questa classe supporta la ricerca solo in unità di tempo di riferimento (TIME_FORMAT_MEDIA_TIME). Per supportare formati di tempo aggiuntivi, eseguire l'override dei metodi IMediaSeeking che gestiscono i formati temporali:
- IMediaSeeking::GetTimeFormat
- IMediaSeeking::GetTimeFormat
- IMediaSeeking::IsUsingTimeFormat
- IMediaSeeking::IsUsingTimeFormat
- IMediaSeeking::SetTimeFormat
Inoltre, eseguire l'override dei metodi IMediaSeeking rimanenti per eseguire le conversioni necessarie tra formati di tempo. Dopo aver chiamato il metodo SetTimeFormat , tutti i metodi IMediaSeeking devono considerare i parametri di ora in ingresso e in uscita come nel nuovo formato temporale. Ad esempio, se la variabile m_rtDuration rappresenta la durata in unità di tempo di riferimento, ma il formato ora corrente è frame, il metodo GetDuration deve restituire il valore m_rtDuration convertito in frame. Ad esempio:
STDMETHODIMP GetDuration(LONGLONG *pDuration)
{
HRESULT hr = CSourceSeeking::GetDuration(pDuration);
if (SUCCEEDED(hr))
{
if (m_TimeFormat == TIME_FORMAT_FRAME)
{
// Convert from reference time to frames.
*pDuration = TimeToFrame(*pDuration); // Private method.
}
}
return hr
}
Assicurarsi inoltre di verificare la presenza del flag AM_SEEKING_ReturnTime nel metodo IMediaSeeking::SetPositions . Se questo flag è presente, convertire i valori di posizione in momenti di riferimento quando vengono restituiti al chiamante.
Requisiti
Requisito | Valore |
---|---|
Intestazione |
|
Libreria |
|