- 1 名前:デフォルトの名無しさん [2006/11/08(水) 00:25:56 ]
- 前スレ
pc8.2ch.net/test/read.cgi/tech/1026666092/
- 231 名前:デフォルトの名無しさん mailto:sage [2007/03/02(金) 15:09:51 ]
- >>227
入門や概説を一通り読んだら、リファレンスを全部読むのを薦めます。
- 232 名前:213 mailto:sage [2007/03/02(金) 21:13:20 ]
- >>214
色々調べて試したみたところ、IKsPropertySetが使えそうなのは判りました。 ただ、これでVideoProcAmpのプロパティへアクセスしてみたところ、 旧来のKSPROPERTY_VIDEOPROCAMP_BRIGHTNESSのようなFilterベースの プロパティアクセスをサポートしているものはうまく動作しますが、 KSPROPERTY_VIDEOPROCAMP_WHITEBALANCE_COMPONENTのような ノードベースのアクセスしかサポートされていないパラメータへはアクセス出来ないようです。 入力インスタンス構造体のFlagsにKSPROPERTY_TYPE_TOPOLOGYをつけて Get()を使ってみてますが、正常終了するものの中身が0です。 旧来のパラメータもノードベースでアクセス出来るようなので試したみたところ、 入力インスタンス構造体をノードベース(KSP_NODE)ではなくフィルタベース(KSPROPERTY)で 見ているようです。 どうもIKsPropertySetはフィルタベースのアクセスしかサポートしていないのでは、と 推測してるのですがどうなんでしょうか。 IKsControlを使うべきなのかと思い試してますが、こっちはnot supportedのえらーコードが返ります。
- 233 名前:デフォルトの名無しさん mailto:sage [2007/03/02(金) 21:25:17 ]
- DirectShowは最初わかんないことだらけだったな。
今でもわかんないこと多いけど。 サンプルと手助けがないとつらいね。
- 234 名前:デフォルトの名無しさん mailto:sage [2007/03/02(金) 22:02:35 ]
- >>232
勘で書いてるんだけど、IKsTopologyInfo:, CreateNodeInstanceでノードを作って、 ノードの方から IKsProperty を QueryInterface で取得して、IKsPropertySet::Setで プロパティをセットするんじゃないだろうか。
- 235 名前:デフォルトの名無しさん mailto:sage [2007/03/02(金) 23:55:00 ]
- >>233
DirectShowは設計がマズイと思う。 フィルタグラフマネージャは自前でスレッドをもってユーザスレッドストリームスレッドとの切り離しをすべきだ。 いつの間にかメインスレッドから呼び出されていたりしてデッドロックとか多い。
- 236 名前:デフォルトの名無しさん mailto:sage [2007/03/03(土) 11:14:01 ]
- >>235
ほんとそのとおりだね。 IBasedPin::Reciver内で別スレッド立ててアロケータ確保すると うまくやらないとアボーンする。。
- 237 名前:215 mailto:sage [2007/03/03(土) 23:03:00 ]
- >>231
ありがとうございます。 そうしてみます。 C++の入門書を一通り読みましたが、新しいことがいっぱいで疲れました・・・。 次はMSDNのリファレンスを読みます。 早くキャプチャソフト作りたいです。
- 238 名前:デフォルトの名無しさん mailto:sage [2007/03/04(日) 00:56:51 ]
- >>234
切り離すモードと切り離さないモードがある。
- 239 名前:213 mailto:sage [2007/03/05(月) 22:24:32 ]
- >>234
DDKやPlatformSDKの情報からみて、まさに指摘されてるようなことなんじゃないかと 思って試してみてますが、IKsTopologyInfo::CreateNodeInstance自体がエラーになるんですよね。 色々調べてみると、どうもWindowsXPでCreateNodeInstance自体が完全にサポート されていない雰囲気がするのですよ。UVC extensionを調べててこんな情報がありました。 ttp://www.codecomments.com/archive421-2005-11-657282.html 自分のやり方が間違ってるかもとも思うんで、しばらく頭を冷やしてもう一度 試してみるつもりです。
- 240 名前:デフォルトの名無しさん mailto:sage [2007/03/05(月) 22:27:24 ]
- 現在、キャプチャカードからのプレビューをモニタするソフトを作っておりまして、
キャプチャ(640×480出力)→ビデオレンダラ というふうに繋いでいます。 ビデオレンダラでフルスクリーンにすると、4:3のアスペクト比を守りながら拡大してくれるのは うれしいのですが、16:9ソースの表示にも対応するために、フルスクリーンの状態で 16:9にしたいです。 しかし、どうしてもできません。 描画されるビデオウィンドウはウィンドウズアプリのメインウィンドウに貼り付けているカタチです。 ソースは640×480を保ったまま、16:9にリサイズしてフルスクリーンにしたいです。 ご助言、よろしくお願いします。
- 241 名前:デフォルトの名無しさん mailto:sage [2007/03/05(月) 22:40:46 ]
- >>240
ビデオレンダラーから(フィルタグラフからでもいいのか?) IVMRAspectRatioControl、IVMRAspectRatioControl9 や IVMRWindowlessControl を取得して、 SetAspectRatioModeでアスペクトレシオを無視するようにする。 レンダラのサイズは自前で16:9にしておく。
- 242 名前:デフォルトの名無しさん [2007/03/05(月) 22:57:06 ]
- 変換フィルタを作成しているのですが、再生中にいきなりビデオのサイズが変わるような場合に、
再接続することなく対応したいのですが、レンダラへ新しい縦横サイズは教えてやれたのですが、 バッファサイズを変更できませんでした。 マニュアルには現在より大きなバッファサイズが必要な場合は、ReceiveConnectionを使えとありますが、 フィルタのどこにどのようなコードを追加すればよいのか分かりません。 デタラメな文章ですが、アドバイスありますでしょうか。。
- 243 名前:240 mailto:sage [2007/03/06(火) 00:47:31 ]
- >>241
ありがとうございます! まずウィンドウレスモードですが、試そうとしたところ、ビデオをウィンドウに転送するところで 強制再起動が掛かかるなど恐ろしいことになってしまったので、ちょっと置いておきます。 ウィンドウモードで作りこんでしまったこともあり、できればこのままで解決したいと思っております。 他の試みとして、IVMRAspectRatioControlをVMR7から呼び出してSetAspectRatioModeで アスペクト比固定をしないよう設定したのですが、相変わらずアス比固定でフルスクリーン になりました・・・。 GetAspectRatioModeで確認しましたが、ちゃんとVMR_ARMODE_NONEになっていました。 そこで、grapheditで調べましたところ、 ttp://vista.jeez.jp/img/vi7310912755.jpg 二つあるフルスクリーンボタンのうち、「Set Full Screen」のほうはアス比固定拡大、「Full Screen Window」 のほうは全体に引き伸ばして表示される、という結果になりました。 先に試したプログラムのほうでは、前者のほうになっているのではないかと考えられます。 後者の「Full Screen Window」ボタンを押すことと等価な処理としては何が考えられるでしょうか?
- 244 名前:240 mailto:sage [2007/03/06(火) 01:37:56 ]
- ttp://msdn.microsoft.com/library/ja/directx9_c/directx/htm/usingwindowlessmodewiththevmr.asp?frame=true
ここのウィンドウレスモードの説明を見ていると、こちらのほうが良さそうですし、なんとか ウィンドウレスモードで動くようにしてみます。
- 245 名前:デフォルトの名無しさん mailto:sage [2007/03/06(火) 15:01:49 ]
- >>243
古来より DirectShow でフルスクリーン再生をする際には、 レンダラをフルスクリーンモードにするのではなく 単に全画面のウィンドウで再生する方が好しということになっています。 後者はそれでしょう。
- 246 名前:240 mailto:sage [2007/03/06(火) 16:27:28 ]
- ウィンドウレスモードで解決しました!
>>245 なるほど、そういうことですか。
- 247 名前:デフォルトの名無しさん mailto:sage [2007/03/07(水) 21:22:13 ]
- 二つのキャプチャデバイスが接続されているPC上で、ボタンをクリックする度に
IEnumMoniker::Next()を繰り返すことでキャプチャデバイスを切り替えるというプログラムを組んでいます。 デバイスが検出されなくなったら、IEnumMoniker::Reset()をして先頭から数えなおすように しています。 一回の切り替えを細かく説明すると、 ストリームの停止→キャプチャフィルタの削除→上記メソッドで検出した新たなデバイスをグラフに追加 →ICaptureGraphBuilder2::RenderStream()でグラフをVMR9に直に接続→再生 という流れです。 これに問題がありまして、この切り替えを8回繰り返す(4順する)と必ず画面が最後のフレームを 表示したまま固まってしまいます。 考えられる原因や対処法がありましたら、ご教授お願いします。
- 248 名前:デフォルトの名無しさん mailto:sage [2007/03/08(木) 02:22:27 ]
- どこがデッドロックしているか調べるといい
- 249 名前:213 mailto:sage [2007/03/08(木) 03:23:24 ]
- USB Video Classキャプチャデバイスのプロパティアクセスについて質問をしていた213です。
問題が度解決できました。この辺を触る人はあまりいなさそうですがご報告だけでも。 結論からいうと、IKsTopologyInfoを使ってKSNODETYPE_VIDEO_PROCESSINGノードを 検索し、そのノードからIVideoProcAmpインタフェイスをCreateNodeInnstanceで生成することで、 拡張されたプロパティへアクセス出来ました。(IAMVideoProcAmpやIKsPropertySetではなく) IVideoProcAmpはノードベースのインタフェイスとしてvidcap.hで定義されてますが、 Vista用のWindowsSDKで配布されているバージョンでないと定義自体存在しません。 USB Video ClassがXPSP2以降のサポートだったのでPlatform SDK(2003R2)を使っていたのですが、 これがまず失敗でした。 また、NTDDI_VERSIONとsdkddkver.hを使い、XPSP2以降であることを明示する必要がありました。 あと細かい話ですが、MSDNやWindowsSDKのドキュメントには、IVideoProcAmpノードの 生成時にIIDとしてIID_IVideoProcAmpを指定しろ、と書かれてますが、こいつのオブジェクトが どこにも存在せずリンクエラーになります。_uuidof(IVideoProcAmp)で指定しないと駄目な模様です。
- 250 名前:247 mailto:sage [2007/03/08(木) 17:52:00 ]
- 解決しました!
原因は二つ目のキャプチャデバイスをRenderStream()するときのみ、間に色空間変換フィルタが 挿入され、キャプチャフィルタを削除したときに色空間変換フィルタ、VMR9間のピンが持つ アロケータにバッファがどんどん蓄積されていくためだったようです。 デバイスを切り替える度、VMR9との接続を切るようにすると、うまく動作するようになりました。
- 251 名前:デフォルトの名無しさん mailto:sage [2007/03/09(金) 00:51:33 ]
- フィルタをビルドするためにstrmbasd.libとstrmbase.libが必要なのですが、それを作成するための
ビルドがどうしてもできません。 お持ちの方がおられましたらお譲りください。 お願いします。 アップローダ ttp://www.rupan.net/uploader/ 環境 WindowsXP SP2 Platform SDK for Windows Server 2003 SP1 Visual Studio 2005 Express Edition
- 252 名前:デフォルトの名無しさん mailto:sage [2007/03/09(金) 02:40:17 ]
- baseclasses.sln をダブルクリックして開いてビルドを実行するだけだろ。
- 253 名前:251 mailto:sage [2007/03/09(金) 03:08:44 ]
- >>252
いえ、最近になって.slnや.dswのファイルが付属しなくなりまして、makefileがついているんです。 それで ttp://www.shader.jp/xoops/html/modules/xfsection/article.php?articleid=17 このページと同じように進めてもcl.exeが見つからないようなことを示すエラーが出て、 それじゃあとcl.exeのあるフォルダを環境変数のPathに設定してやると今度はmspdb80.dllが 見つからないと言われて失敗します。
- 254 名前:デフォルトの名無しさん mailto:sage [2007/03/09(金) 04:01:11 ]
- さすがマイクロソフト
- 255 名前:デフォルトの名無しさん mailto:sage [2007/03/09(金) 04:16:23 ]
- 俺の所の 2006 9月版には、baseclasses.slnがあるけどな。
お前の最近は2年前か?
- 256 名前:251 mailto:sage [2007/03/09(金) 04:29:10 ]
- >>255
え!?そうなんですか!? ttp://www.microsoft.com/downloads/details.aspx?FamilyId=A55B6B43-E24F-4EA3-A93E-40C0EC4F68E5&displaylang=en ここのPSDK-x86.exeをダウンロードしてインストールしたのですが、違うのでしょうか? >>255さんの入手経路を教えてください。
- 257 名前:デフォルトの名無しさん mailto:sage [2007/03/09(金) 05:18:47 ]
- blogs.msdn.com/windowssdk/
- 258 名前:251 mailto:sage [2007/03/09(金) 07:07:13 ]
- できました!!
ttp://ugd555.blog1.fc2.com/page-13.html 同じ症状を解決した方のページを見つけました。 最終的に別のフォルダから5つファイルを持ってこなければいけませんでした。 この問題に18時間費やしました・・・
- 259 名前:251 mailto:sage [2007/03/09(金) 09:44:34 ]
- 早速、いろいろなフィルタサンプルのビルドを試してみましたが、どれもPC内に存在しない
ライブラリファイルが無い、と言われどうしようもありません。 そういえば、VC2005EEでDirectShowフィルタを開発したという話を聞いたことがありません。 ちゃんとしたVCを買え、ということでFAでしょうか? もしそうなら、観念して買いに行きます・・・
- 260 名前:デフォルトの名無しさん mailto:sage [2007/03/09(金) 09:45:26 ]
- EEどうかは関係ない気がする、2005だといろいろ不便
- 261 名前:デフォルトの名無しさん mailto:sage [2007/03/09(金) 16:37:13 ]
- いい加減最新のSDKダウンロードしろ。うざい。
- 262 名前:デフォルトの名無しさん mailto:sage [2007/03/09(金) 16:42:53 ]
- >>259
初心者スレにでも行け DirectShowスレで語るべき内容ではないだろ
- 263 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 01:13:37 ]
- どんな内容なら語ってもいいのですか?玄人の>>262さん。
- 264 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 02:25:22 ]
- >>251や>>263みたいな質問以外ですな
- 265 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 05:35:57 ]
- キャプチャフィルタ→変換フィルタ→色空間変換フィルタ→VMR9
という構成の中の変換フィルタで、キャプチャフィルタからサンプルが1枚くる度に サンプルに対し処理Aを実行→出力→表示 サンプルに対し処理Bを実行→出力→表示 というように2回の処理、出力を行いたい(フレームレートを倍化したい)のですが、 どうすればよいでしょうか? なお、キャプチャ出力のフレームレートは上限に設定しています。 タイムスタンプをいじるだけではうまくいきませんでした。 IMemInputPin::Receiveを使うにしても、それを呼び出す頻度をどのようにすれば 合わせられるかが分からずできません。
- 266 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 07:16:47 ]
- 出力ピンのメディアタイプのレートを2倍に設定して、サンプルを1つ受け取ったら2つ出力すればいいのでは
- 267 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 11:46:39 ]
- タイムスタンプは修正してやらないと駄目だろう。
仮にキャプチャフィルタが30f/secで投げてくるなら0.033...秒間隔のスタンプが設定されているだろうから 自分でつくる変換フィルタは2枚目に0.033.../2秒のタイムスタンプを足して設定してやる。 んで自分が出力ピンからDeliverするときに、自分で送りたい2枚分、下段の入力ピンReceiveを呼ぶ。 2回送信完了してから、上段にDeliverの結果を返す。
- 268 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 17:49:27 ]
- pc11.2ch.net/test/read.cgi/tech/1168354839/
の658です。 たぶんこっちで質問したほうがいい気がしたので。 何度やっても同じところ(CopyMemory)で落ちます。 原因として思い当たる件があったらご教示願います。
- 269 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 18:11:41 ]
- サイズチェックくらいしろ。
24bit以上のソースなら、BITMAPINFOHEADERだな。
- 270 名前:268 mailto:sage [2007/03/10(土) 18:21:52 ]
- >>269
つまり、サイズが足りないということでしょうか?
- 271 名前:268 mailto:sage [2007/03/10(土) 19:24:59 ]
- サンプルファイルを出力したところ、24bitであることは確認しました。
どこが悪いんでしょう?
- 272 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 19:32:55 ]
- >>268
これか、 CopyMemory( &BitmapInfo.bmiHeader, &(pVideoHeader->bmiHeader), sizeof(BITMAPINFOHEADER)); 探すの面倒だから直リンして欲しいな。 pc11.2ch.net/test/read.cgi/tech/1168354839/658 コピー先と、コピーするサイズとか確認してみれば。 &BitmapInfo.bmiHeader が有効なメモリを指してる? &(pVideoHeader->bmiHeader) が有効なメモリを指してる? sizeof(BITMAPINFOHEADER) これはあっていると思うけどさ。
- 273 名前:268 mailto:sage [2007/03/10(土) 19:37:59 ]
- &BitmapInfo.bmiHeader:1000E380
&(pVideoHeader->bmiHeader):30 むう?
- 274 名前:268 mailto:sage [2007/03/10(土) 19:41:33 ]
- Bitmapinfoをローカルにすると
&BitmapInfo.bmiHeader:12F044 &(pVideoHeader->bmiHeader):30 &BitmapInfo.bmiHeaderが怪しいですね。
- 275 名前:268 mailto:sage [2007/03/10(土) 19:42:42 ]
- で、怪しいのはわかったんですが対処方法がわかりませんorz
- 276 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 19:49:11 ]
- 何かおかしいときはリビルドすると直ったりするんだよ
- 277 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 19:50:18 ]
- ヘッダに書いただけで動かなくなるとは思えないしさ!
- 278 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 19:51:15 ]
- >>276
もう8回くらいリビルドしてますorz 手動でbmiHeaderを初期化したりしてもダメでした。
- 279 名前:デフォルトの名無しさん mailto:sage [2007/03/10(土) 20:06:49 ]
- 初心者スレに戻りなはれ
- 280 名前:268 mailto:sage [2007/03/10(土) 20:09:10 ]
- そうします。orz
- 281 名前:265 mailto:sage [2007/03/10(土) 23:31:42 ]
- >>266
その方法を試すために、まず出力ピンのメディアタイプを取得しようとしたのですが、 原因不明のエラーが出ます。 何がまずいのでしょうか? HRESULT (作成した変換フィルタクラス名)::Transform( IMediaSample *pIn , IMediaSample *pOut ){ ・・・ //出力ピンのメディアタイプを探す IEnumPins *pEnumPins; IPin *pPin; PIN_DIRECTION PinDirThis; AM_MEDIA_TYPE *pmt; this->EnumPins( &pEnumPins ); pEnumPins->Reset(); while( pEnumPins->Next( 1 , &pPin , NULL ) == S_OK ){ pPin->QueryDirection( &PinDirThis ); if ( PinDirThis == PINDIR_OUTPUT ){ pPin->ConnectionMediaType( pmt ); ←定義されてないのに使ってるというようなエラー } } DeleteMediaType( pmt ); ←上と同じエラー ・・・ }
- 282 名前:265 mailto:sage [2007/03/10(土) 23:36:19 ]
- >>267
タイムスタンプ修正は行えるのですが、下段の入力ピンのIMemInputPin::Receiveを どのようにすれば呼び出せるのかが分かりません。 >>281で示したようなコードでIPinクラスは取得できるのですが、 ttp://msdn.microsoft.com/library/ja/jpdx8_c/ds/ref/class/CBaseInputPin.asp?frame=true#CBaseInputPin ここを見ると、IMemInputPinはIPinの子クラスなので、それに実装されているReceiveメンバに アクセスできません。 ご教授願います。
- 283 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 00:38:34 ]
- トランスフォームフィルタのソースがベースクラスとして公開されてるんだから勉強するといいよ
CTransformFilter、CTransformInputPin、CTransformOutputPinね 入力サンプルがどう入ってきてどこで変換してどうやって出て行くのか 更にしたのベースクラスの知識も必要になるだろうけどさ 既に下段に接続してる相手のメディアタイプが欲しいなら 出力ピンのCurrentMediaTypeでいいだろ
- 284 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 01:14:56 ]
- >>282
m_pOutput->Deliver するだけでOK
- 285 名前:265 mailto:sage [2007/03/11(日) 03:49:55 ]
- >>283
ありがとうございます。 m_pOutput->CurrentMediaTypeでメディアタイプを取得し、pbFormat(VIDEOINFOHEADER)内の AvgTimePerFrameを変更してやることでフレームレートの変更を試みてみました。 しかし、今まで通りの10000000/29.97[100ns]であれば下流のフィルタ(色空間変換フィルタ)に 繋がるのですが、倍の10000000/59.94[100ns]では接続できませんでした。 残念ながら対応していないようです。
- 286 名前:265 mailto:sage [2007/03/11(日) 03:50:22 ]
- >>284
ありがとうございます。 一枚のサンプルに対し二度出力できるようになりました。 しかし、fpsがきれいに倍化する期間と倍にならない期間が移り変わってうなりのようになっています。 二度の出力中、一枚目のスタートと二枚目のエンドのタイムスタンプはいじっていないので、 そこでの同期は保障されていると思ったのですが・・・ どのようにすれば改善できるでしょうか? 一枚のサンプルに対して行う処理を以下に示しておきます。 //一枚目の処理 ・・・ // 入力サンプルのタイムスタンプを取得する pIn->GetTime( &TimeStart , &TimeEnd ); //エンドタイムを1/59.94[s]早める TimeEnd -= 166833; //[100ns] pOut->SetTime( &TimeStart , &TimeEnd ); //下流フィルタにDeliverする m_pOutput->Deliver( pOut ); //二枚目の処理 ・・・ // 入力サンプルのタイムスタンプを取得する pIn->GetTime( &TimeStart , &TimeEnd ); //スタートタイムを1/59.94[s]遅くする TimeStart += 166833;//[100ns] pOut->SetTime( &TimeStart , &TimeEnd ); //下流フィルタにDeliverする m_pOutput->Deliver( pOut );
- 287 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 05:56:40 ]
- >>266 でも書かれているが、GetMediaType時にAvgTimePerFrameの時間を半分にして接続を完了させればいいんでね?
部分的コードなのでわからないが、サンプル使いまわしたりはしていないよね?
- 288 名前:265 mailto:sage [2007/03/11(日) 09:37:13 ]
- >>287
試しに AvgTimePerFrame /= 2; としてみましたが、やはり受け付けませんでした。 AvgTimePerFrame /= 1; だったら大丈夫です。 >サンプル使いまわしたりはしていないよね? 他の方が作られたサンプルを使いまわししてます。 ですが、Transformメソッドをいじるだけくらいのシンプルな変換フィルタでして、その処理部分に関しては すべて書き換えています。
- 289 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 11:18:23 ]
- タイムスタンプの変更は問題ないです。EndTimeが0で来る場合もあるのでチェックして下さい。
> Transformメソッドをいじるだけくらい CTransformFilter::Receive内でもDeliverしてるからな。その辺り大丈夫だよね? 文面から察するに OutputPin::CurrentMediaTypeでメディアタイプ取得できるってことはピンが繋がっている状態なのだが 一旦Pin接続解除した後にフレームレート倍のメディアタイプを色変換に提示(OutputPin::GetMediaTypeで設定)して 再接続を試みてるんだよね?
- 290 名前:265 mailto:sage [2007/03/11(日) 11:56:35 ]
- >>289
>EndTimeが0で来る場合もあるのでチェックして下さい。 チェックしてみましたが、EndTimeが0で来る様子は見られませんでした。 >CTransformFilter::Receive内でもDeliverしてるからな。その辺り大丈夫だよね? どうなんでしょう・・・影響があるかは判断しかねます・・・ メディアタイプ変更の件ですが、グラフエディタ上で接続が断たれた状態からピンを繋ごうとしたとき、 キャプチャフィルタのメディアタイプから変更しなかった場合は成功し、変更すると失敗する、というかんじです。 フレームレートの不安定ですが、もしかしたら処理負荷が大きいためかもしれません。 表示ウィンドウのサイズを大きくする(ネイティブサイズは同じ)とフレームレートが落ちていきます。 CPUの使用率は60〜70%ですが、VMR9側の問題でこのようなことになっているのかもしれません。 この負荷の原因として、変換フィルタとVMR9との間に挟まっている色空間変換フィルタが挙げられます。 キャプチャフィルタから直接VMR9に繋ぐときは介在せず、CPU負荷も小さいです。 ところが、同じメディアタイプを設定しているにも関わらず、変換フィルタを挟むと、その後に色空間変換フィルタ入ってきます。 キャプチャから直接VMR9の場合はシステムメモリは介さず、直接ビデオRAMに移す、というようなことでもしているから こんなことになるのでしょうか? もし変換フィルタから直接VMR9に繋げられるような方法がありましたら教えてください。
- 291 名前:268 mailto:sage [2007/03/11(日) 16:50:34 ]
- 別のソースを元にいろいろいじってたんですよ。
(そっちのソースはCopyMemoryで落ちないので) で、そっちのBitmapInfoのbmiHeaderを調べてみたところ、他の値は想定の範囲内なんですが BitmapInfo.bmiHeader.biCompression = 1685288548 とdでもない値が入っていて、どうやらこいつが原因だと判明。 これって何なんでしょ? ぐぐったらdvsdとか出てきたんですがよくわかりません。
- 292 名前:268 mailto:sage [2007/03/11(日) 16:54:12 ]
- ちなみに
BitmapInfo.bmiHeader.biCompression=BI_RGB; なんてことをやると一応動くようにはなりました。 ただ取得できる値がおかしいので正確に動いてる感じではありませんが。
- 293 名前:268 mailto:sage [2007/03/11(日) 17:04:27 ]
- 取得部分は以下のような感じです。
void Cam::getImage() { HRESULT hr; // ビットマップ ヘッダーから DIB を作成し、バッファへのポインタを獲得する。 hBitmap = CreateDIBSection(0, &BitmapInfo, DIB_RGB_COLORS, (void **)&buffer, NULL, 0); firstDIB = FALSE; // イメージをバッファにコピーする。 DIBBuffer = (long *)GlobalAlloc(GPTR,bufsize); hr = pGrab->GetCurrentBuffer(DIBBuffer,NULL); hr = pGrab->GetCurrentBuffer(DIBBuffer,(long *)buffer); } AVIを無理やりBITMAPにしているから無理が生じているような予感がちらほら。
- 294 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 18:34:30 ]
- 帰れといっただろ
- 295 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 18:42:48 ]
- >>290
レンダラに直接接続したければ、すべてのフォーマットを出力で対応する必要がある。 まあでも32bitでだいたいの環境はいける。 接続できなければレンダラが対応していないのだろう。正しい接続の仕方ならばね・・・。
- 296 名前:268 mailto:sage [2007/03/11(日) 20:31:37 ]
- >>294
向こうで聞くべき質問じゃないと思ったので・・・。orz
- 297 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 20:32:01 ]
- FilterのサンプルにNullInplaceフィルタってのがあるんだけどさ
それをキャプチャデバイスとレンダラの間に入れてみてくれ。 やっぱり色空間変換フィルタが必要とされるか?されないか?
- 298 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 20:35:02 ]
- dvsdはDVのSD形式。それがわかんねーなら帰れw
- 299 名前:265 mailto:sage [2007/03/11(日) 21:09:48 ]
- >>297
自前のWindowsSDKにないのでDirectXのExtrasをダウンロードし、その中からNullInplaceフィルタを見つけたのですが、 ビルドすると、PC内に存在しないatlbase.hが無いと言われてしまいます。 無念です・・・
- 300 名前:デフォルトの名無しさん mailto:sage [2007/03/11(日) 21:44:59 ]
- > >CTransformFilter::Receive内でもDeliverしてるからな。その辺り大丈夫だよね?
> どうなんでしょう・・・影響があるかは判断しかねます・・・ どう実装してるかわからんけど、もしかしてTransformメソッドの中で2回Deliverしてる? CTransformFilter::Receive良く読んで理解してるよね?
- 301 名前:デフォルトの名無しさん [2007/03/12(月) 08:02:05 ]
- 俺もフレームレート変換フィルタを作って断念した者ですが、
上流フィルタからの映像が来る来ないに関わらず非同期でフレームレートを作るフィルタが出来なかったんだよな。 今悩んでいる子がここまでやるのなら全力でサポートするよ
- 302 名前:デフォルトの名無しさん mailto:sage [2007/03/12(月) 08:04:43 ]
- 最近変換フィルタの話題がちょくちょく出ててうれしい。
- 303 名前:265 mailto:sage [2007/03/12(月) 08:07:00 ]
- >>300
そうです、Transformメソッドの中で2回Deliverしてます。 サンプルの流れがいまいち理解できないです。 そこで今行っている処理の流れを分かる範囲でまとめてみました。 [キャプチャフィルタ]-[変換フィルタ(自作)]-[色空間変換フィルタ]-[VMR9] [色空間変換フィルタ]の入力ピンからの[変換フィルタ]への呼び出し CTransformFilter::Receive (CTransformFilter::InitializeOutputSampleを呼び出す) ↓ CTransformFilter::InitializeOutputSample (新しいサンプルを[キャプチャフィルタ]の出力ピンから取得する) ↓ CTransformFilter::Transform (サンプルの処理) ↓ CBaseOutputPin::Deliver (IMemInputPin::Receiveを呼び出す) ←これを>>286のように2回呼び出しています ↓ IMemInputPin::Receive ([変換フィルタ]の出力サンプルを取得する) ↓ [色空間変換フィルタ]での処理 ↓ [VMR9]が付与されたタイムスタンプに従って画面に表示 疑問点 ・>>289さんの言う、CTransformFilter::Receive内でもDeliverしている、という記述がMSDNで見つけられませんでした。 上記で言えばどの時点で発生するのでしょうか? ・最初のCTransformFilter::Receiveが呼び出されるタイミングが分かりません。 サンプルが変換フィルタで処理されるサイクルはどのようになっているのでしょうか?
- 304 名前:265 mailto:sage [2007/03/12(月) 10:06:54 ]
- この問題に関していろいろと試してみた結果を書いておきます。
・タイムスタンプがないプレビューピンからの映像に対して変換を行ったところ、同じうなり現象(>>284)が起きた。 ・一枚のサンプルに対して二度の処理を行うが、片方の絵を真っ黒にしてみると、フレームが倍化していないときは 二枚目の絵のみが表示される状態であることが分かった。 ・二度目のDeliverを外したところ、フレーム倍化の時間が若干延び、倍化していない期間においても 一枚目の絵と二枚目の絵が交互に表示された。 このとき、キャプチャーピンからの映像では倍化していない期間で絵が0.5秒ほどストップすることが頻繁に起こった。 プレビューピンからの映像ではこのストップ現象は起きない。
- 305 名前:265 mailto:sage [2007/03/12(月) 10:08:49 ]
- すみません、
>>284じゃなくて>>286です。
- 306 名前:268 mailto:sage [2007/03/12(月) 13:35:12 ]
- >>298
SD形式はいいんですが、これって普通にBITMAPINMFO構造体として取り出せないんでしょうか?
- 307 名前:265 mailto:sage [2007/03/12(月) 17:31:09 ]
- 特定の場合についてのみですが、フレームレートの倍化(30fps→60fps)ができました。
(同時にこの手法のダメさを裏付けるものでもありましたが・・・) 条件は ・キャプチャフィルタのプレビューピンに繋げる(よってタイムスタンプの設定は意味なし) ・二度目のDeliverを無くす(あるともたつきが起こる) ・画面表示をビデオのネイティブサイズである640×480に対し、約2倍以上にするとフレームレートのうなり現象が 無くなり約60fpsで一定となる。 このとき、CPUの使用率はサイズが大きくなるにつれて上がる。 これらの現象から導き出される結論として、 一度目のDeliverと二度目の(本来行われる)Deliverは連続ですぐに行われ、二度目のDeliverにより送信された 二枚目は一枚目で設定したタイムスタンプがあろうが無かろうが即座に描画される。 CPUの負荷が上がり、すぐに二度目のDeliverが処理できない場合、その間一枚目が表示されることとなり、この時間が ちょうど1/60秒となるときキレイにフレームが倍化されることとなる。 描画サイズが小さいときはCPUに余裕がある期間が存在し、そのときは二枚目のみが表示される。(フレームが倍化されない) ということが言えると思います。 よって、一度のTransformメソッドで二度のDeliverを用いる作戦はアウトということになりました・・・。
- 308 名前:デフォルトの名無しさん mailto:sage [2007/03/12(月) 18:47:41 ]
- 何度も書かれているけど、接続状態がその倍のレートでないと、レンダラはそのfpsで処理してくれないと思うよ。つまり余計に送られてきたサンプルは捨てる。
出力メディアタイプと違うサンプルを出力しても、期待した通りに動かないよね。 あと処理が間に合わない時も、どこかのフィルタが捨てると思う。 一度CPU負荷がほとんど発生しないプロトタイプを作って実験して、処理遅れなのかそれとも別の問題なのか調べて見ては?接続の問題も解決を。 リアルタイムで処理したいんだよね? それとDirectShowで「サンプル」といえば、IMediaSample2などのデータの事をしめします。 >>287 は、一度ダウンストリームに送信したサンプルをまた再利用するなよってこと。
- 309 名前:デフォルトの名無しさん mailto:sage [2007/03/12(月) 21:53:42 ]
- ビデオレンダラからの品質メッセージをNotifyで受け取ってQuality::Lateを見てみると良いよ。
これがマイナスだとレンダラに間に合って届いている。 プラスだと間に合ってないので到着したとたんにレンダリングされたりして 動きがギクシャクしたり捨てられてカクついたりする
- 310 名前:デフォルトの名無しさん mailto:sage [2007/03/12(月) 22:14:45 ]
- 休日の夜中になっても頑張ってるから応援したくなるよ あんまり教えすぎはよくないんだけど
>303 サンプルの流れについて まず上流(キャプチャデバイス)の出力ピンが、変換フィルタの入力ピンCTransformInputPin::Recieveにサンプルを渡す。 入力ピンRecieveはCTranscormFilter::Receiveを呼ぶ。んでTransformメソッドでサンプルを変換した後、 出力ピンから下流(色変換フィルタ)のRecieveを呼び出す(サンプルを渡す) という流れ >289で「Deliverしてる」って表現したのはマズかったかな。要は下流にサンプルを渡すってことなんだ。 下流の入力ピンのReceiveを呼び出す(サンプルを渡す)。コレがDeliverの正体。 CBaseOutputPin::Deliverメソッドのソースを見てみるといいよ(Baseclassesのamfilter.cppな) んでTransformフィルタなんだけど、出力ピンのDeliverメソッドは呼んでいないんだ どうやって送信してるかというと、CTransformFilter::Receiveの中に次のコードがある hr = m_pOutput->m_pInputPin->Receive(pOutSample); これ。ここで送信してる。直訳(?)すると、自分の出力ピンに繋がってる入力ピンのReceiveに Transoformメソッドで変更を加えたサンプルを渡す ってこと。 長いので続く
- 311 名前:デフォルトの名無しさん mailto:sage [2007/03/12(月) 22:48:26 ]
- 303のカキコミについて説明していくよ
> CTransformFilter::InitializeOutputSample (新しいサンプルを[キャプチャフィルタ]の出力ピンから取得する) InitializeOutputSampleは出力するサンプルの準備をするメソッドなんだ。 ここでは送信するサンプルのバッファをサンプルと結びつける(バッファ自体は出力ピンが確保してる) HRESULT hr = m_pOutput->m_pAllocator->GetBuffer( その後で、上流から受け取ったサンプルのプロパティ(各種フラグと言ったほうがわかりやすいか)や時間情報を 出力するサンプルに設定していく。これがInitializeOutputSampleの役割。 このことから、上流から受けたサンプルと、自分で送るサンプルは全くの別物であるということがわかる。 送信が済んだら、このサンプルをリリースすることでバッファの開放などが行われる (CTransformFilter::Receiveの最後の方 pOutSample->Release(); ) ちなみに上流から受けたサンプルをダイレクトにそのまま下流に出力するのはCTransInPlaceFilterだ つづく
- 312 名前:デフォルトの名無しさん mailto:sage [2007/03/12(月) 23:10:36 ]
- 早い話、君は2回送ってるつもりでも、3回送っていると思われる
しかも3回目のサンプルの時間情報は上流から受けた時間そのもの
- 313 名前:デフォルトの名無しさん mailto:sage [2007/03/12(月) 23:13:13 ]
- Transformメソッドはサンプルの内容を変更するだけじゃないと ブー
そういう設計なんでこざいます だからここから送信したら ブーブー TransformInputPin::Receiveをオーバーライドしないとアカンねん
- 314 名前:デフォルトの名無しさん mailto:sage [2007/03/12(月) 23:23:29 ]
- まちがえた TransformFilter::Receiveな 酒のんでるからすまんの
サンプルのタイムスタンプ見てレンダラが表示のタイミングを待ったり、時には捨てたりするアルよ サンプルの不連続性(Discontinuity)とか同期ポイント(SyncPoint)を示すフラグの扱いとか 注意してくれよ キレイなフィルタを作りましょう。んじゃ頑張れ
- 315 名前:265 mailto:sage [2007/03/12(月) 23:33:31 ]
- >>308
了解です。 >それとDirectShowで「サンプル」といえば、IMediaSample2などのデータの事をしめします。 そういうことでしたか・・・ 失礼しました。 >>309 ありがとうございます。 調べてみます。 >>310-314 とても丁寧にありがとうございます。 がんばります。
- 316 名前:デフォルトの名無しさん mailto:sage [2007/03/14(水) 22:52:01 ]
- >>306
dvsdなんかではCreateDIBSectionに失敗しそうな気がするけど、それはないの? あと、フィルタいじれるなら入力ピンのCheckMediaTypeでMEDIASUBTYPEの RGB24かRGB32以外を弾くようにすれば、その辺不問にできるような気がするけど・・・。
- 317 名前:デフォルトの名無しさん mailto:sage [2007/03/15(木) 01:14:32 ]
- すみません。
DVDをAVIにして保存したいんですが、YUYをRGBに変換するフィルタとAVIを書くフィルタは自前で作るのですか? 色々やってみてダメだったらヒントください。 ちょっと頑張ってくる。
- 318 名前:268 mailto:sage [2007/03/15(木) 14:03:14 ]
- >>316
はい、失敗します。orz 他の方法でやらなきゃいけないんでしょうか?
- 319 名前:デフォルトの名無しさん mailto:sage [2007/03/15(木) 14:11:19 ]
- >>318
(1) 普通のDIBを用意して、そこにDrawDibDrawで描く (2) 入力ピンのフォーマットをRGB24/RGB32に限定して、フィルタグラフ側で変換してもらう (3) 自分でDVをでコードする 1,2は実質的にはaviのというかvfwのdvコーデックが使われる。 「やらなきゃいけない」かどうかは自分で決めればいい。 やりたくないならやらなくていいんじゃない?
- 320 名前:268 mailto:sage [2007/03/15(木) 16:40:18 ]
- >>319
うお、ありがとうございます! ちょっくら試してみます!
- 321 名前:268 mailto:sage [2007/03/15(木) 18:38:43 ]
- とりあえず(1)はDrawDibOpenの時点で落ちるので保留。
(2)を試してみます。 ttp://webcamxtra.sourceforge.net/ これを活用すればいけそうな気もしてるんですけどね・・・。 今までウェブカメラは自力で処理できていたのでどうにかしたいもんです。orz
- 322 名前:268 mailto:sage [2007/03/15(木) 18:52:30 ]
- ん、DrawDibOpen動いた。
あとはDrawDibDrawの引数だけだと思うので、ちょっくら追ってみます。
- 323 名前:デフォルトの名無しさん mailto:sage [2007/03/15(木) 23:07:58 ]
- ICaptureGraphBuilderを利用してSetOutputFileNameやって、
DVD Navigaterのフィルタを取ってRenderStreamすればAVIにできると思ったのにダメでした。 DVDをAVIにして保存する方法って何かあるんでしょうか。 サンプルグラバつなげられれば保存できる気もするんだけどPINをつなげられない。
- 324 名前:デフォルトの名無しさん mailto:sage [2007/03/16(金) 00:54:44 ]
- ビデオ形式
ビデオ タイプについては、サンプル グラバは VIDEOINFOHEADER 形式を必要とします。VIDEOINFOHEADER2 や DVINFO などの 他の形式タイプを必要とするフィルタに接続することはできません。 このため、MPEG-2 や DV ビデオ、またはフィールド ベースの (インターレース) ビデオとの互換性はありません。 www.microsoft.com/japan/msdn/directx/techart/grabbersample.aspx#limitationsofthedirectshowsamplegrabber うぉー、絶望的なことかいてあった。orz.... サンプルグラバに繋がらないわけだ。 Overlay Mixer −> サンプルグラバ −>AVIMUX という流れができるか明日ためしてみる。
- 325 名前:268 mailto:sage [2007/03/16(金) 16:53:10 ]
- DrawDibBeginがfalseを返す・・・。orz
というわけで他の方法試してみます。
- 326 名前:デフォルトの名無しさん mailto:sage [2007/03/16(金) 16:55:37 ]
- BeginとEndは実は要らない。
- 327 名前:268 mailto:sage [2007/03/16(金) 17:12:04 ]
- >>319
> (3) 自分でDVをでコードする って、サンプルとかないですよね・・・。orz
- 328 名前:326 mailto:sage [2007/03/16(金) 17:19:30 ]
- >>326
ま、マジですか。 ちょっくら試してみます。
- 329 名前:368 mailto:sage [2007/03/16(金) 17:20:05 ]
- あせって名前間違えた。orz
>>328は自分です。
- 330 名前:268 mailto:sage [2007/03/16(金) 17:24:46 ]
- うーん、DrawDibDrawがやっぱりfalse。
何か記述が足りない気がしてきた。 サンプル探してるんですけど全然見つからないんですよね。orz
- 331 名前:デフォルトの名無しさん mailto:sage [2007/03/16(金) 21:58:23 ]
- >>330
サンプルグラバ使ってるんですよね? SetMediaTypeでMEDIASUBTYPE_RGB24指定して dvsdで流れてこないようにしたらどうですか? あなたのレスをすべて追っかけてるわけじゃないんで、外してるかもしれませんが。
|

|