CSourceSeeking クラス
CSourceSeeking クラスは、1 つの出力ピンを持つソース フィルタで、シークを実装する抽象クラスである。
このクラスは、IMediaSeeking インターフェイスをサポートする。このクラスは、すべての IMediaSeeking メソッドにデフォルトの実装を提供する。プロテクト メンバ変数は、開始タイム、終了タイム、および現在の速度を格納する。デフォルトでは、このクラスによってサポートされる唯一のタイム フォーマットは、TIME_FORMAT_MEDIA_TIME (100 ナノ秒単位) である。詳細は、注意を参照すること。
要件
ヘッダー : Ctlutil.h 内で宣言し、Streams.h をインクルードする。
ライブラリ : Strmbase.lib (リテール ビルド) または Strmbasd.lib (デバッグ ビルド) を使う。
プロテクト メンバ変数 | |
m_rtDuration | ストリームの時間幅。 |
m_rtStart | 開始タイム。 |
m_rtStop | 終了タイム。 |
m_dRateSeeking | 再生速度。 |
m_dwSeekingCaps | シーク能力。 |
m_pLock | ロックのためのクリティカル セクション オブジェクトへのポインタ。 |
プロテクト メソッド | |
CSourceSeeking | コンストラクタ メソッド。 |
純粋仮想メソッド | |
ChangeRate | 再生速度が変更されたときに呼び出される。 |
ChangeStart | 開始位置が変更されたときに呼び出される。 |
ChangeStop | 停止位置が変更されたときに呼び出される。 |
IMediaSeeking メソッド | |
IsFormatSupported | 指定したタイム フォーマットがサポートされているかどうかを調べる。 |
QueryPreferredFormat | オブジェクトの優先タイム フォーマットを取得する。 |
SetTimeFormat | タイム フォーマットを設定する。 |
IsUsingTimeFormat | 指定したタイム フォーマットが現在使われているフォーマットかどうかを調べる。 |
GetTimeFormat | 現在のタイム フォーマットを取得する。 |
GetDuration | ストリームの時間幅を取得する。 |
GetStopPosition | ストリームの時間幅を基準として、再生が停止するタイムを取得する。 |
GetCurrentPosition | ストリームの合計時間幅を基準とする、現在の位置を取得する。 |
GetCapabilities | ストリームのすべてのシーク能力を取得する。 |
CheckCapabilities | 指定したシーク能力をストリームが持っているかどうかを照会する。 |
ConvertTimeFormat | 1 つのタイム フォーマットから別のタイム フォーマットに変換する。 |
SetPositions | 現在位置と停止位置を設定する。 |
GetPositions | 現在位置と停止位置を取得する。 |
GetAvailable | シークが有効なタイムの範囲を取得する。 |
SetRate | 再生速度を設定する。 |
GetRate | 再生速度を取得する。 |
GetPreroll | プリロール タイムを取得する。 |
注意
CSourceSeeking オブジェクトは、開始位置、停止位置、再生速度が変更されるたびに、次のように対応する純粋仮想メソッドを呼び出す。
- 開始位置 : CSourceSeeking::ChangeStart
- 停止位置 : CSourceSeeking::ChangeStop
- 再生速度 : CSourceSeeking::ChangeRate
派生クラスは、これらのメソッドを実装しなければならない。シーク処理後、フィルタは次のことを行う必要がある。
- ダウンストリームの入力ピンで IPin::BeginFlush メソッドを呼び出す。
- データを提供するワーカー スレッドを停止する。
- 入力ピンで IPin::EndFlush メソッドを呼び出す。
- ワーカー スレッドを再起動する。
- 入力ピンで IPin::NewSegment メソッドを呼び出す。
- 最初のサンプルで非継続プロパティを設定する。IMediaSample::SetDiscontinuity メソッドを呼び出す。
ワーカー スレッドがブロックされ、サンプル出力の待機状態になっている場合は、BeginFlush を呼び出してワーカー スレッドを解放する。
ステップ 2 で、スレッドによるデータの送信が停止したことを確認する。実装によっては、スレッドが終了するのを待つか、またはスレッドが何らかの応答を示すまで待つ必要がある。フィルタで CSourceStream クラスを使っている場合、CSourceStream::Stop メソッドは、ワーカー スレッドが応答するまで待機状態となる。
理想的には、新しいセグメント (ステップ 5) がワーカー スレッドから提供されることが望ましい。これは、フィルタがサンプルを使って継続して処理する限り、CSourceSeeking オブジェクトによっても実行できる。
次の例は、可能な実装を示している。ここでは、ソース フィルタの出力ピンが CSourceSeeking と CSourceStream から派生することを想定している。この例では、ステップ 1 ~ 4 を実行するヘルパー メソッド UpdateFromSeek を定義している。CSourceStream::OnThreadStartPlay メソッドはオーバーライドされ、新しいセグメントを送ると共に、非連続を示すフラグを設定する。ワーカー スレッドはこのフラグをピックアップし、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);
}
追加のタイム フォーマットのサポート
デフォルトでは、このクラスは、基準タイム (TIME_FORMAT_MEDIA_TIME) の単位のみのシークをサポートする。追加のタイム フォーマットをサポートするには、タイム フォーマットを扱う IMediaSeeking メソッドをオーバーライドする。
- IMediaSeeking::GetTimeFormat
- IMediaSeeking::IsFormatSupported
- IMediaSeeking::IsUsingTimeFormat
- IMediaSeeking::QueryPreferredFormat
- IMediaSeeking::SetTimeFormat
また、残りの IMediaSeeking メソッドをオーバーライドして、タイム フォーマット間で必要な変換を実行する。SetTimeFormat メソッドが呼び出された後、すべての IMediaSeeking メソッドは、出入りするタイム パラメータが新規のタイム フォーマットであるかのように扱う必要がある。たとえば、m_rtDuration 変数が基準タイムの単位の時間幅を表し、現在のタイム フォーマットがフレームである場合、GetDuration メソッドは、フレームに変換された値 m_rtDuration を返す必要がある。以下に例を示す。
STDMETHODIMP GetDuration(LONGLONG *pDuration)
{
HRESULT hr = CSourceSeeking::GetDuration(pDuration);
if (SUCCEEDED(hr))
{
if (m_TimeFormat == TIME_FORMAT_FRAME)
{
// 基準タイムからフレームへの変換。
*pDuration = TimeToFrame(*pDuration); // プライベート メソッド。
}
}
return hr
}
また、IMediaSeeking::SetPositions メソッドの AM_SEEKING_ReturnTime フラグを確認する必要がある。このフラグがある場合は、呼び出し元に返すときに位置値を基準タイムに変換する。