トップ回答者
DirectShow経由でWMV再生時の挙動について

質問
-
現在DirectShowを使ったカスタムプレイヤをVisual Studio2005でC++を使って作成しています。ひとつどうしても原因のわからない現象があり質問させていただきます。カスタムプレイヤはVMR9をwindowlessモードで使用しています。グラフの構築はWMR9をIGraphBuilder::AddFilter()してIGraphBuilder::RenderFile()を実行するだけで、レンダラ以外はデフォルトのフィルタを使用しています。
問題の現象はWMV再生時のシークの挙動です。今、テスト環境のPCが3台あり、PC1とPC2はWindows XP Pro、PC3はWindows Vistaです。PC1とPC2はWMP10、PC3はWMP11が入っています。WMV再生時にIMediaSeeking::SetPositions()を発行すると、PC2とPC3は指定した位置に正常にシークが実行されますが、PC1は手前にある最も近いキーフレーム(と思われる)位置に見かけ上シークされます。しかし、IMediaSeeking::GetPositions()で再生位置を取得すると、指定した位置が返ってきます。つまり、画面に表示されている位置と論理上の再生位置がずれた状態になります。再生が開始されると、論理上の再生位置(IMediaSeeking::GetPositions()で取得される位置)に画面の表示が追いつくまで早送り状態で再生され、追いつくと正常なスピードに戻るという挙動になります。
こういう仕様であるというのならしょうがないのですが、PC2とPC3では正常な動きをするので、混乱しております。PC1とPC2で、ソフト上で使用されるフィルタを列挙してみたり、GraphEdtで同じ状態を作って見たりしても、PC間の違いはありません。(ソースフィルタはフィルタ名に再生しているファイル名が返ってくるだけなので、正体は見えないのですが)関連すると思われるDLLのバージョンをチェックしてみましたが、qasf.dllとquartz.dllのバージョンも同じ。
PC1をOSクリーンインストールしてみても現象は変化しませんでした。また、PC1はWMP11に変えても挙動は変化なしでした。両者の違いはハードウェアだけに見えます。
PC1でもWMPでWMVを再生すると正常にシークされるのでくやしいです(笑)。WMPはWMVに関してはDirectShowを素で使ってないのでしょうが・・・
回答の付きにくい質問だろうとは思っておりますが、Web検索を行っても、一切情報がでてきません。もし、原因のわかる方がいらっしゃったらお願いします。
回答
すべての返信
-
Win2000+WMP9 の組み合わせでもそのような事象が発生します。
が、WinXP+WMP10 では発生しないので、
もしかすると wmvcore のバージョンが関係しているのではないかと思っています。
なお、手前味噌になりますが、動画を再生するための .NET ライブラリを作ったことがあります。
内部的には DirectShow を使用していて、wmvcore のバージョンは 9 です。
これはクロックを無視して全力でデコードした画像を別メモリにバッファリングし、
音声の時刻に同期する形でオーバーレイ表示するというシロモノですが、
これだと例のシーク直後の早送り現象は起こりません。
-
回答ありがとうございます。ほとんどあきらめかけておりました(笑)
PC1のwmvcore.dllのバージョンを調べてみると、10.0.0.4054でした。qasf.dllとquartz.dllのバージョンが10.0.0.3802でしたので、それより新しいですね。これはVMRを使ってWMVを再生すると、メディアファイルのあるフォルダにdxva_sig.txtというファイルを作ってゴミを撒き散らすという、Windows MediaのBug Fixをあてたからだと思われます。検索すると、バックアップのフォルダに9.0.0.3250と10.0.0.3802のwmvcore.dllが存在しました。まあ、Bug Fixを当てる前と後で、この現象の挙動に変化はなかったですが。
自分的には、ディスプレイカード、もしくは、そのドライバの違いにより、WMV再生時のシークの挙動が変化するんじゃないかと思い始めています。ちなみに、問題のPC1はATIのRADEON X1600、PC2はHP製ノートPCでRADEON EXPRESS X200ってでますね。
確かに、描画を自前でやれば、この現象の出る余地はありませんね(笑)。