« BCBのコードをVCでデバッグしたい | メイン | ピリオドイベントと無音MPEGの動作確認 »

2004年10月04日

吉里吉里2/KAG3ムービー拡張日誌:: ストリーム タイムを追う

    

時間について少し整理する

基準タイム
基準タイムは、基準クロックから返される絶対タイムである。

ストリーム タイム
ストリーム タイムは、グラフが最後に実行を開始したときを基準に定義される。
・グラフが実行しているときは、ストリーム タイムは、基準タイムから開始タイムを差し引いた値に等しい。
・グラフがポーズしているときは、ストリーム タイムはポーズされたときのストリーム タイムに留まる。
・グラフが停止しているときは、ストリーム タイムはゼロである。
・シーク処理後には、ストリーム タイムはゼロにリセットされる。

タイム スタンプ(サンプルタイム)
タイム スタンプは、ストリーム タイムで示されるサンプルの開始タイムと終了タイムを定義する。タイム スタンプは、プレゼンテーション時間と呼ばれることもある。

メディア タイム
メディア タイムは、シーク可能なメディア内のサンプルの本来の位置 (たとえばディスク上のファイル) を指定する。ビデオの場合、メディア タイムはフレーム番号を表す。


シーク処理後には、ストリーム タイムはゼロにリセットされるって、あかんやん。
でも、IMediaSeeking::GetCurrentPosition を使えば正しい位置が返ってくる。
だから、IMediaSeeking::GetCurrentPosition を使えればいいのだが・・・

調べるとちょうどいいのがあった。
CBaseRenderer::GetMediaPositionInterface
フィルタの IMediaPosition および IMediaSeeking インターフェイス ポインタを取得する。
前調べた時はフィルタグラフにばかり目がいって気付かなかった。
じゃ、さっそくこれを使ってみよう。

だめだ、CBaseRenderer::GetMediaPositionInterface で返ってくるインターフェイスからIMediaSeeking::GetCurrentPosition で時間を取得しても、ストリームタイムが返ってくる。

CBaseFilter.m_pGraph がフィルタグラフをおさえている。
このフィルタグラフにクエリーをかけてIMediaSeeking インターフェイスを取得すればうまくいきそうだ。
とりあえず、コンストラクタで・・・ って、コンストラクタがコールされる時にはまだフィルタグラフに参加していないからダメだ。
DoRenderSample で未取得なら取得するようにした。
で、動作チェック。
キターッ!
きちんと取得できた。
ループもきちんと行われている。

再生が終了してしまうと言う問題だが、あれは勘違いだった。
最終フレームに到達しても再生は終了しないんだった。
そして、シークしてまだ残りフレームがある位置に移動すると、再びヘッドが進み出す。
なんの問題もなかった。


2つほど不具合を発見し修正。
ダブルバッファリングにしたはずが、一部ずっと同じバッファを指していたために、無駄なメモリコピーが発生してしまっていた不具合を修正。
なんか重くなったような気がするなぁと思っていた原因はこれだったのか。

ループを設定して、KAGスクリプトが何もない状態になった時に終了するとプロセスが残ってしまう問題を発見。
tTVPDSMovie::ReleaseAll() のm_MediaControl->Stop(); が返ってこなくなっていた。
tTVPDSLayerVideo のデストラクタでもReleaseAll() をコールするようにしたらそのようなことはなくなった。
ReleaseAll() は何度呼んでも良いようにしているが、なんでそんなことが?
呼び出し過程で問題が発生するような呼び出し順序にしているつもりはなかったのだが・・・ 違う、デストラクタで消えていく順番が怪しい。
派生側が持っているメンバが先に消えてしまっていてどうしよう?状態になりそうだ。
そして、そのメンバにはフィルタグラフに参加しているグラフのインターフェイスもあるし。
でも、まあこれでプロセスが残る問題は解決。

以上で、セグメントループの基本的な動作確認は終了。



投稿者 Takenori : 2004年10月04日 01:49




comments powered by Disqus
Total : Today : Yesterday : なかのひと