DirectShowと戦うスレ ..
[2ch|▼Menu]
207:デフォルトの名無しさん
07/02/24 13:07:39
206です。いろいろと検索しております。
URLリンク(homepage1.nifty.com)
こちらにネットワークカメラについての制御の仕方について
少し書いてありました。

USBカメラのように一律なプログラムでなくて、
ネットワークカメラごとに、プログラムを変えないといけないのでしょうか。
なにを考えていけば、わからないのですが。
・ネットワークカメラごとのマニュアルを読んで、HTTPでネットワークカメラに
 接続、画像を取り込む
・そのあとは、USBカメラと処理が同じ
こんな感じなのでしょうか?

具体的なコードはまだわからないのですが、方針として
ネットワークカメラの制御が、HTTPだけですむなら、
USBカメラのプログラムで、画像を渡す部分だけ、
改造すれば大丈夫でしょうか。

スレ違いでしたら、誘導していただけますと助かります。
よろしくお願いします。

208:デフォルトの名無しさん
07/02/24 23:27:29
特殊なカメラ(業務向けの何十万もするような奴)で遠隔地で画像を取ってネットワークにストリームしてくれるカメラならあると思う。
そういう場合、そのカメラを操作するにはそのメーカーが提供するライブラリを使うことになるだろうね。
映像を受ける側はカメラ用のフィルタグラフではなくネットワークからのストリームを受信するような感じになると思う。

209:デフォルトの名無しさん
07/02/25 01:49:42
>>208
お返事ありがとうございます。

livecaptureっていうフリーのすごいソフトありますが、
どうやって複数のネットワークカメラに、対応しているのか疑問でしたが、
メーカーさんが公開しているマニュアルを見て、プログラミングしてるのかもしれないですね。
通信の仕方をメーカーさんが、公開してないとだめなんですね。ふむふむ。。

210:デフォルトの名無しさん
07/02/25 14:22:29
専用のカメラを使ってるね。その手のカメラは買えば当然遠隔操作のコマンドとかマニュアルが付いてくるはず。



211:デフォルトの名無しさん
07/02/26 10:33:36
>>210
>当然遠隔操作のコマンド
付いてくるけど画像ストリームの仕様は無いのよ
とりあえずメーカーに問い合わせてみる


212:デフォルトの名無しさん
07/02/26 18:16:38
っ自分で解析

213:デフォルトの名無しさん
07/02/27 01:19:35
キャプチャデバイスのプロパティへアクセスするにはIAMVideoProcAmpや
IAMCameraControlがありますが、これらでサポートされていないパラメータへ
アクセスする方法はありますか?

具体的には、USB Video Classのサポートで追加された、

KSPROPERTY_VIDEOPROCAMP_DIGITAL_MULTIPLIER
KSPROPERTY_VIDEOPROCAMP_WHITEBALANCE_COMPONENT

辺りへアクセスしたいんですが。(対象デバイスがそれらのプロパティをサポート
してるのは確認しています)
axextend.idlやstrmif.hのenumにはidが定義されていないし、WHITEBALANCE_COMPONENTの
NODE_S2タイプのアクセス関数(パラメータが2個あるタイプ)もヘッダに見つかりません。

これはカスタムで書くしかないんでしょうか。

214:デフォルトの名無しさん
07/02/27 13:54:19
IKsPropertyとかなんかそんな名前のインタフェイスで出来ると思う。

215:デフォルトの名無しさん
07/03/01 02:00:42
キャプチャボードからの映像信号に処理を加えて、それを表示するプログラムを作りたいと思い、
DirectShowの勉強を始めました。
一通り調べた結果、以下の事を勉強する必要があると思いましたが、他にも「これ知っとけ」
みたいなことがあったら教えてください。

〜既にある知識〜
C、Win32API、grapheditの扱い

〜これから学ぶべきと思うこと〜
C++、COM、自作フィルタの作成と登録の方法

216:デフォルトの名無しさん
07/03/01 07:21:37
俺も似たような事やってる…
概念理解が勉強の中心になると思う。ガンガレ〜

既に知ってるとは思うが、「BMP構造」を理解しておくとよいよ。

基本はBMP画像のぱらぱら漫画を加工する事になりますので。

217:215
07/03/01 14:07:11
>>216
ありがとうございます。
BMPについてはWin32APIでいじり倒してきたのでいけると思います。
DirectShowについてはその仕様と情報の少なさに辟易していますが、
地道にがんばろうと思います。

218:デフォルトの名無しさん
07/03/01 17:23:44
>>215
学ぶべきことがわかってるのはすばらしい!

ただし、下手に段階踏むと挫折しかねないので、
とりあえずサンプルコードからはじめるといいと思う。

「これで動くけど、なんでだろー?」って形で勉強するといいかも。

219:デフォルトの名無しさん
07/03/01 21:52:11
簡単なサンプル作ってあげよか?インプレイスフィルタとトランスフォームどっちの変換フィルタ使ったらいいか調べるだけでも最初は一苦労だろ

220:デフォルトの名無しさん
07/03/01 22:30:27
SDKのサンプルが一番いいよ

221:デフォルトの名無しさん
07/03/01 22:44:15
そりゃサンプルで自分も勉強したけど、映像の処理なら「コントラスト」、「RGB」この2つから入ると思う。
この2つを最初にみたとき何が最低限実装が必要なメソッドかわからんかった。
そんな意味でのもっとシンプルなサンプル

222:215
07/03/01 23:19:46
>>218
ありがとうございます。
そうすることにします。
>>219
助かります!
是非お願いします!

223:デフォルトの名無しさん
07/03/02 00:06:52
>>222
ひとまず、君の使ってる環境を教えてくれ。
自分はVC6+DX8SDK、VC2003+DX9(オウガスト)
の2つの環境でやっとる

224:215
07/03/02 00:12:39
>>223
了解です。
VC++2005Express + PlatformSDK + DirectX SDK (June 2006)

225:デフォルトの名無しさん
07/03/02 00:25:29
URLリンク(www.geekpage.jp)
URLリンク(www.geocities.co.jp)
URLリンク(hammer.prohosting.com)
URLリンク(msdn.microsoft.com)

226:デフォルトの名無しさん
07/03/02 02:37:07
>>255
わかったよ。確かにそれみりゃわかるね。
甘やかすのは無用。勉強させろと無言のプレッシャーを感じる…。

227:215
07/03/02 03:03:29
>>225
二つ目のサイト以外は既に目を通したものばかりですが、それでも難しいと思いました。
キャプチャの出力解像度を変えることすらできませんでした・・・。
とりあえずC++から地道にべんきょーします。

228:デフォルトの名無しさん
07/03/02 04:17:44
あとアセンブラの知識が必要になることもあるな

229:デフォルトの名無しさん
07/03/02 08:49:03
マジすか?アセンブラワカンネ。
そしてここはsage進行なんですね。マイナーだからageてました

230:デフォルトの名無しさん
07/03/02 08:53:36
DirectShowの本見ると「この本はC++を3年以上やってる方を対象に書いてます」みたいな事が書いてありますね。
C++経験者でないときついのか。

231:デフォルトの名無しさん
07/03/02 15:09:51
>>227
入門や概説を一通り読んだら、リファレンスを全部読むのを薦めます。

232:213
07/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:デフォルトの名無しさん
07/03/02 21:25:17
DirectShowは最初わかんないことだらけだったな。
今でもわかんないこと多いけど。
サンプルと手助けがないとつらいね。

234:デフォルトの名無しさん
07/03/02 22:02:35
>>232
勘で書いてるんだけど、IKsTopologyInfo:, CreateNodeInstanceでノードを作って、
ノードの方から IKsProperty を QueryInterface で取得して、IKsPropertySet::Setで
プロパティをセットするんじゃないだろうか。


235:デフォルトの名無しさん
07/03/02 23:55:00
>>233
DirectShowは設計がマズイと思う。
フィルタグラフマネージャは自前でスレッドをもってユーザスレッドストリームスレッドとの切り離しをすべきだ。
いつの間にかメインスレッドから呼び出されていたりしてデッドロックとか多い。



236:デフォルトの名無しさん
07/03/03 11:14:01
>>235
ほんとそのとおりだね。
IBasedPin::Reciver内で別スレッド立ててアロケータ確保すると
うまくやらないとアボーンする。。

237:215
07/03/03 23:03:00
>>231
ありがとうございます。
そうしてみます。

C++の入門書を一通り読みましたが、新しいことがいっぱいで疲れました・・・。
次はMSDNのリファレンスを読みます。
早くキャプチャソフト作りたいです。

238:デフォルトの名無しさん
07/03/04 00:56:51
>>234
切り離すモードと切り離さないモードがある。

239:213
07/03/05 22:24:32
>>234
DDKやPlatformSDKの情報からみて、まさに指摘されてるようなことなんじゃないかと
思って試してみてますが、IKsTopologyInfo::CreateNodeInstance自体がエラーになるんですよね。

色々調べてみると、どうもWindowsXPでCreateNodeInstance自体が完全にサポート
されていない雰囲気がするのですよ。UVC extensionを調べててこんな情報がありました。

URLリンク(www.codecomments.com)

自分のやり方が間違ってるかもとも思うんで、しばらく頭を冷やしてもう一度
試してみるつもりです。

240:デフォルトの名無しさん
07/03/05 22:27:24
現在、キャプチャカードからのプレビューをモニタするソフトを作っておりまして、
キャプチャ(640×480出力)→ビデオレンダラ
というふうに繋いでいます。
ビデオレンダラでフルスクリーンにすると、4:3のアスペクト比を守りながら拡大してくれるのは
うれしいのですが、16:9ソースの表示にも対応するために、フルスクリーンの状態で
16:9にしたいです。
しかし、どうしてもできません。
描画されるビデオウィンドウはウィンドウズアプリのメインウィンドウに貼り付けているカタチです。
ソースは640×480を保ったまま、16:9にリサイズしてフルスクリーンにしたいです。
ご助言、よろしくお願いします。

241:デフォルトの名無しさん
07/03/05 22:40:46
>>240
ビデオレンダラーから(フィルタグラフからでもいいのか?)
IVMRAspectRatioControl、IVMRAspectRatioControl9 や IVMRWindowlessControl を取得して、
SetAspectRatioModeでアスペクトレシオを無視するようにする。

レンダラのサイズは自前で16:9にしておく。

242:デフォルトの名無しさん
07/03/05 22:57:06
変換フィルタを作成しているのですが、再生中にいきなりビデオのサイズが変わるような場合に、
再接続することなく対応したいのですが、レンダラへ新しい縦横サイズは教えてやれたのですが、
バッファサイズを変更できませんでした。
マニュアルには現在より大きなバッファサイズが必要な場合は、ReceiveConnectionを使えとありますが、
フィルタのどこにどのようなコードを追加すればよいのか分かりません。
デタラメな文章ですが、アドバイスありますでしょうか。。

243:240
07/03/06 00:47:31
>>241
ありがとうございます!
まずウィンドウレスモードですが、試そうとしたところ、ビデオをウィンドウに転送するところで
強制再起動が掛かかるなど恐ろしいことになってしまったので、ちょっと置いておきます。
ウィンドウモードで作りこんでしまったこともあり、できればこのままで解決したいと思っております。

他の試みとして、IVMRAspectRatioControlをVMR7から呼び出してSetAspectRatioModeで
アスペクト比固定をしないよう設定したのですが、相変わらずアス比固定でフルスクリーン
になりました・・・。
GetAspectRatioModeで確認しましたが、ちゃんとVMR_ARMODE_NONEになっていました。
そこで、grapheditで調べましたところ、
URLリンク(vista.jeez.jp)
二つあるフルスクリーンボタンのうち、「Set Full Screen」のほうはアス比固定拡大、「Full Screen Window」
のほうは全体に引き伸ばして表示される、という結果になりました。
先に試したプログラムのほうでは、前者のほうになっているのではないかと考えられます。
後者の「Full Screen Window」ボタンを押すことと等価な処理としては何が考えられるでしょうか?

244:240
07/03/06 01:37:56
URLリンク(msdn.microsoft.com)
ここのウィンドウレスモードの説明を見ていると、こちらのほうが良さそうですし、なんとか
ウィンドウレスモードで動くようにしてみます。

245:デフォルトの名無しさん
07/03/06 15:01:49
>>243
古来より DirectShow でフルスクリーン再生をする際には、
レンダラをフルスクリーンモードにするのではなく
単に全画面のウィンドウで再生する方が好しということになっています。
後者はそれでしょう。

246:240
07/03/06 16:27:28
ウィンドウレスモードで解決しました!

>>245
なるほど、そういうことですか。

247:デフォルトの名無しさん
07/03/07 21:22:13
二つのキャプチャデバイスが接続されているPC上で、ボタンをクリックする度に
IEnumMoniker::Next()を繰り返すことでキャプチャデバイスを切り替えるというプログラムを組んでいます。
デバイスが検出されなくなったら、IEnumMoniker::Reset()をして先頭から数えなおすように
しています。
一回の切り替えを細かく説明すると、
ストリームの停止→キャプチャフィルタの削除→上記メソッドで検出した新たなデバイスをグラフに追加
→ICaptureGraphBuilder2::RenderStream()でグラフをVMR9に直に接続→再生
という流れです。

これに問題がありまして、この切り替えを8回繰り返す(4順する)と必ず画面が最後のフレームを
表示したまま固まってしまいます。
考えられる原因や対処法がありましたら、ご教授お願いします。

248:デフォルトの名無しさん
07/03/08 02:22:27
どこがデッドロックしているか調べるといい

249:213
07/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
07/03/08 17:52:00
解決しました!
原因は二つ目のキャプチャデバイスをRenderStream()するときのみ、間に色空間変換フィルタが
挿入され、キャプチャフィルタを削除したときに色空間変換フィルタ、VMR9間のピンが持つ
アロケータにバッファがどんどん蓄積されていくためだったようです。
デバイスを切り替える度、VMR9との接続を切るようにすると、うまく動作するようになりました。

251:デフォルトの名無しさん
07/03/09 00:51:33
フィルタをビルドするためにstrmbasd.libとstrmbase.libが必要なのですが、それを作成するための
ビルドがどうしてもできません。
お持ちの方がおられましたらお譲りください。
お願いします。

アップローダ
URLリンク(www.rupan.net)

環境
WindowsXP SP2
Platform SDK for Windows Server 2003 SP1
Visual Studio 2005 Express Edition

252:デフォルトの名無しさん
07/03/09 02:40:17
baseclasses.sln をダブルクリックして開いてビルドを実行するだけだろ。

253:251
07/03/09 03:08:44
>>252
いえ、最近になって.slnや.dswのファイルが付属しなくなりまして、makefileがついているんです。
それで
URLリンク(www.shader.jp)
このページと同じように進めてもcl.exeが見つからないようなことを示すエラーが出て、
それじゃあとcl.exeのあるフォルダを環境変数のPathに設定してやると今度はmspdb80.dllが
見つからないと言われて失敗します。

254:デフォルトの名無しさん
07/03/09 04:01:11
さすがマイクロソフト


255:デフォルトの名無しさん
07/03/09 04:16:23
俺の所の 2006 9月版には、baseclasses.slnがあるけどな。
お前の最近は2年前か?

256:251
07/03/09 04:29:10
>>255
え!?そうなんですか!?
URLリンク(www.microsoft.com)
ここのPSDK-x86.exeをダウンロードしてインストールしたのですが、違うのでしょうか?
>>255さんの入手経路を教えてください。

257:デフォルトの名無しさん
07/03/09 05:18:47
URLリンク(blogs.msdn.com)

258:251
07/03/09 07:07:13
できました!!
URLリンク(ugd555.blog1.fc2.com)
同じ症状を解決した方のページを見つけました。
最終的に別のフォルダから5つファイルを持ってこなければいけませんでした。
この問題に18時間費やしました・・・

259:251
07/03/09 09:44:34
早速、いろいろなフィルタサンプルのビルドを試してみましたが、どれもPC内に存在しない
ライブラリファイルが無い、と言われどうしようもありません。
そういえば、VC2005EEでDirectShowフィルタを開発したという話を聞いたことがありません。
ちゃんとしたVCを買え、ということでFAでしょうか?
もしそうなら、観念して買いに行きます・・・

260:デフォルトの名無しさん
07/03/09 09:45:26
EEどうかは関係ない気がする、2005だといろいろ不便

261:デフォルトの名無しさん
07/03/09 16:37:13
いい加減最新のSDKダウンロードしろ。うざい。

262:デフォルトの名無しさん
07/03/09 16:42:53
>>259
初心者スレにでも行け
DirectShowスレで語るべき内容ではないだろ

263:デフォルトの名無しさん
07/03/10 01:13:37
どんな内容なら語ってもいいのですか?玄人の>>262さん。


264:デフォルトの名無しさん
07/03/10 02:25:22
>>251>>263みたいな質問以外ですな

265:デフォルトの名無しさん
07/03/10 05:35:57
キャプチャフィルタ→変換フィルタ→色空間変換フィルタ→VMR9
という構成の中の変換フィルタで、キャプチャフィルタからサンプルが1枚くる度に
サンプルに対し処理Aを実行→出力→表示
サンプルに対し処理Bを実行→出力→表示
というように2回の処理、出力を行いたい(フレームレートを倍化したい)のですが、
どうすればよいでしょうか?
なお、キャプチャ出力のフレームレートは上限に設定しています。
タイムスタンプをいじるだけではうまくいきませんでした。
IMemInputPin::Receiveを使うにしても、それを呼び出す頻度をどのようにすれば
合わせられるかが分からずできません。

266:デフォルトの名無しさん
07/03/10 07:16:47
出力ピンのメディアタイプのレートを2倍に設定して、サンプルを1つ受け取ったら2つ出力すればいいのでは

267:デフォルトの名無しさん
07/03/10 11:46:39
タイムスタンプは修正してやらないと駄目だろう。
仮にキャプチャフィルタが30f/secで投げてくるなら0.033...秒間隔のスタンプが設定されているだろうから
自分でつくる変換フィルタは2枚目に0.033.../2秒のタイムスタンプを足して設定してやる。
んで自分が出力ピンからDeliverするときに、自分で送りたい2枚分、下段の入力ピンReceiveを呼ぶ。
2回送信完了してから、上段にDeliverの結果を返す。

268:デフォルトの名無しさん
07/03/10 17:49:27
スレリンク(tech板)
の658です。
たぶんこっちで質問したほうがいい気がしたので。

何度やっても同じところ(CopyMemory)で落ちます。
原因として思い当たる件があったらご教示願います。

269:デフォルトの名無しさん
07/03/10 18:11:41
サイズチェックくらいしろ。
24bit以上のソースなら、BITMAPINFOHEADERだな。

270:268
07/03/10 18:21:52
>>269
つまり、サイズが足りないということでしょうか?

271:268
07/03/10 19:24:59
サンプルファイルを出力したところ、24bitであることは確認しました。
どこが悪いんでしょう?

272:デフォルトの名無しさん
07/03/10 19:32:55
>>268

これか、
CopyMemory( &BitmapInfo.bmiHeader, &(pVideoHeader->bmiHeader), 
                sizeof(BITMAPINFOHEADER));

探すの面倒だから直リンして欲しいな。
スレリンク(tech板:658番)

コピー先と、コピーするサイズとか確認してみれば。

&BitmapInfo.bmiHeader が有効なメモリを指してる?
&(pVideoHeader->bmiHeader) が有効なメモリを指してる?
sizeof(BITMAPINFOHEADER) これはあっていると思うけどさ。


273:268
07/03/10 19:37:59
&BitmapInfo.bmiHeader:1000E380
&(pVideoHeader->bmiHeader):30
むう?

274:268
07/03/10 19:41:33
Bitmapinfoをローカルにすると
&BitmapInfo.bmiHeader:12F044
&(pVideoHeader->bmiHeader):30
&BitmapInfo.bmiHeaderが怪しいですね。

275:268
07/03/10 19:42:42
で、怪しいのはわかったんですが対処方法がわかりませんorz

276:デフォルトの名無しさん
07/03/10 19:49:11
何かおかしいときはリビルドすると直ったりするんだよ

277:デフォルトの名無しさん
07/03/10 19:50:18
ヘッダに書いただけで動かなくなるとは思えないしさ!

278:デフォルトの名無しさん
07/03/10 19:51:15
>>276
もう8回くらいリビルドしてますorz
手動でbmiHeaderを初期化したりしてもダメでした。

279:デフォルトの名無しさん
07/03/10 20:06:49
初心者スレに戻りなはれ

280:268
07/03/10 20:09:10
そうします。orz

281:265
07/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
07/03/10 23:36:19
>>267
タイムスタンプ修正は行えるのですが、下段の入力ピンのIMemInputPin::Receiveを
どのようにすれば呼び出せるのかが分かりません。
>>281で示したようなコードでIPinクラスは取得できるのですが、
URLリンク(msdn.microsoft.com)
ここを見ると、IMemInputPinはIPinの子クラスなので、それに実装されているReceiveメンバに
アクセスできません。
ご教授願います。

283:デフォルトの名無しさん
07/03/11 00:38:34
トランスフォームフィルタのソースがベースクラスとして公開されてるんだから勉強するといいよ
CTransformFilter、CTransformInputPin、CTransformOutputPinね
入力サンプルがどう入ってきてどこで変換してどうやって出て行くのか
更にしたのベースクラスの知識も必要になるだろうけどさ

既に下段に接続してる相手のメディアタイプが欲しいなら
出力ピンのCurrentMediaTypeでいいだろ

284:デフォルトの名無しさん
07/03/11 01:14:56
>>282
m_pOutput->Deliver するだけでOK

285:265
07/03/11 03:49:55
>>283
ありがとうございます。
m_pOutput->CurrentMediaTypeでメディアタイプを取得し、pbFormat(VIDEOINFOHEADER)内の
AvgTimePerFrameを変更してやることでフレームレートの変更を試みてみました。
しかし、今まで通りの10000000/29.97[100ns]であれば下流のフィルタ(色空間変換フィルタ)に
繋がるのですが、倍の10000000/59.94[100ns]では接続できませんでした。
残念ながら対応していないようです。

286:265
07/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:デフォルトの名無しさん
07/03/11 05:56:40
>>266 でも書かれているが、GetMediaType時にAvgTimePerFrameの時間を半分にして接続を完了させればいいんでね?

部分的コードなのでわからないが、サンプル使いまわしたりはしていないよね?

288:265
07/03/11 09:37:13
>>287
試しに
AvgTimePerFrame /= 2;
としてみましたが、やはり受け付けませんでした。
AvgTimePerFrame /= 1;
だったら大丈夫です。
>サンプル使いまわしたりはしていないよね?
他の方が作られたサンプルを使いまわししてます。
ですが、Transformメソッドをいじるだけくらいのシンプルな変換フィルタでして、その処理部分に関しては
すべて書き換えています。

289:デフォルトの名無しさん
07/03/11 11:18:23
タイムスタンプの変更は問題ないです。EndTimeが0で来る場合もあるのでチェックして下さい。

> Transformメソッドをいじるだけくらい
CTransformFilter::Receive内でもDeliverしてるからな。その辺り大丈夫だよね?

文面から察するに
OutputPin::CurrentMediaTypeでメディアタイプ取得できるってことはピンが繋がっている状態なのだが
一旦Pin接続解除した後にフレームレート倍のメディアタイプを色変換に提示(OutputPin::GetMediaTypeで設定)して
再接続を試みてるんだよね?

290:265
07/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
07/03/11 16:50:34
別のソースを元にいろいろいじってたんですよ。
(そっちのソースはCopyMemoryで落ちないので)
で、そっちのBitmapInfoのbmiHeaderを調べてみたところ、他の値は想定の範囲内なんですが
BitmapInfo.bmiHeader.biCompression = 1685288548
とdでもない値が入っていて、どうやらこいつが原因だと判明。

これって何なんでしょ?
ぐぐったらdvsdとか出てきたんですがよくわかりません。

292:268
07/03/11 16:54:12
ちなみに
BitmapInfo.bmiHeader.biCompression=BI_RGB;
なんてことをやると一応動くようにはなりました。
ただ取得できる値がおかしいので正確に動いてる感じではありませんが。

293:268
07/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:デフォルトの名無しさん
07/03/11 18:34:30
帰れといっただろ

295:デフォルトの名無しさん
07/03/11 18:42:48
>>290
レンダラに直接接続したければ、すべてのフォーマットを出力で対応する必要がある。
まあでも32bitでだいたいの環境はいける。

接続できなければレンダラが対応していないのだろう。正しい接続の仕方ならばね・・・。

296:268
07/03/11 20:31:37
>>294
向こうで聞くべき質問じゃないと思ったので・・・。orz

297:デフォルトの名無しさん
07/03/11 20:32:01
FilterのサンプルにNullInplaceフィルタってのがあるんだけどさ
それをキャプチャデバイスとレンダラの間に入れてみてくれ。
やっぱり色空間変換フィルタが必要とされるか?されないか?

298:デフォルトの名無しさん
07/03/11 20:35:02
dvsdはDVのSD形式。それがわかんねーなら帰れw

299:265
07/03/11 21:09:48
>>297
自前のWindowsSDKにないのでDirectXのExtrasをダウンロードし、その中からNullInplaceフィルタを見つけたのですが、
ビルドすると、PC内に存在しないatlbase.hが無いと言われてしまいます。
無念です・・・

300:デフォルトの名無しさん
07/03/11 21:44:59
> >CTransformFilter::Receive内でもDeliverしてるからな。その辺り大丈夫だよね?
> どうなんでしょう・・・影響があるかは判断しかねます・・・

どう実装してるかわからんけど、もしかしてTransformメソッドの中で2回Deliverしてる?
CTransformFilter::Receive良く読んで理解してるよね?


301:デフォルトの名無しさん
07/03/12 08:02:05
俺もフレームレート変換フィルタを作って断念した者ですが、
上流フィルタからの映像が来る来ないに関わらず非同期でフレームレートを作るフィルタが出来なかったんだよな。
今悩んでいる子がここまでやるのなら全力でサポートするよ

302:デフォルトの名無しさん
07/03/12 08:04:43
最近変換フィルタの話題がちょくちょく出ててうれしい。


303:265
07/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
07/03/12 10:06:54
この問題に関していろいろと試してみた結果を書いておきます。

・タイムスタンプがないプレビューピンからの映像に対して変換を行ったところ、同じうなり現象(>>284)が起きた。
・一枚のサンプルに対して二度の処理を行うが、片方の絵を真っ黒にしてみると、フレームが倍化していないときは
二枚目の絵のみが表示される状態であることが分かった。
・二度目のDeliverを外したところ、フレーム倍化の時間が若干延び、倍化していない期間においても
一枚目の絵と二枚目の絵が交互に表示された。
このとき、キャプチャーピンからの映像では倍化していない期間で絵が0.5秒ほどストップすることが頻繁に起こった。
プレビューピンからの映像ではこのストップ現象は起きない。

305:265
07/03/12 10:08:49
すみません、
>>284じゃなくて>>286です。

306:268
07/03/12 13:35:12
>>298
SD形式はいいんですが、これって普通にBITMAPINMFO構造体として取り出せないんでしょうか?

307:265
07/03/12 17:31:09
特定の場合についてのみですが、フレームレートの倍化(30fps→60fps)ができました。
(同時にこの手法のダメさを裏付けるものでもありましたが・・・)
条件は
・キャプチャフィルタのプレビューピンに繋げる(よってタイムスタンプの設定は意味なし)
・二度目のDeliverを無くす(あるともたつきが起こる)
・画面表示をビデオのネイティブサイズである640×480に対し、約2倍以上にするとフレームレートのうなり現象が
無くなり約60fpsで一定となる。
このとき、CPUの使用率はサイズが大きくなるにつれて上がる。

これらの現象から導き出される結論として、
一度目のDeliverと二度目の(本来行われる)Deliverは連続ですぐに行われ、二度目のDeliverにより送信された
二枚目は一枚目で設定したタイムスタンプがあろうが無かろうが即座に描画される。
CPUの負荷が上がり、すぐに二度目のDeliverが処理できない場合、その間一枚目が表示されることとなり、この時間が
ちょうど1/60秒となるときキレイにフレームが倍化されることとなる。
描画サイズが小さいときはCPUに余裕がある期間が存在し、そのときは二枚目のみが表示される。(フレームが倍化されない)
ということが言えると思います。

よって、一度のTransformメソッドで二度のDeliverを用いる作戦はアウトということになりました・・・。

308:デフォルトの名無しさん
07/03/12 18:47:41
何度も書かれているけど、接続状態がその倍のレートでないと、レンダラはそのfpsで処理してくれないと思うよ。つまり余計に送られてきたサンプルは捨てる。
出力メディアタイプと違うサンプルを出力しても、期待した通りに動かないよね。
あと処理が間に合わない時も、どこかのフィルタが捨てると思う。

一度CPU負荷がほとんど発生しないプロトタイプを作って実験して、処理遅れなのかそれとも別の問題なのか調べて見ては?接続の問題も解決を。

リアルタイムで処理したいんだよね?

それとDirectShowで「サンプル」といえば、IMediaSample2などのデータの事をしめします。
>>287 は、一度ダウンストリームに送信したサンプルをまた再利用するなよってこと。

309:デフォルトの名無しさん
07/03/12 21:53:42
ビデオレンダラからの品質メッセージをNotifyで受け取ってQuality::Lateを見てみると良いよ。
これがマイナスだとレンダラに間に合って届いている。
プラスだと間に合ってないので到着したとたんにレンダリングされたりして
動きがギクシャクしたり捨てられてカクついたりする

310:デフォルトの名無しさん
07/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:デフォルトの名無しさん
07/03/12 22:48:26
303のカキコミについて説明していくよ

> CTransformFilter::InitializeOutputSample (新しいサンプルを[キャプチャフィルタ]の出力ピンから取得する)

InitializeOutputSampleは出力するサンプルの準備をするメソッドなんだ。
ここでは送信するサンプルのバッファをサンプルと結びつける(バッファ自体は出力ピンが確保してる)

HRESULT hr = m_pOutput->m_pAllocator->GetBuffer(

その後で、上流から受け取ったサンプルのプロパティ(各種フラグと言ったほうがわかりやすいか)や時間情報を
出力するサンプルに設定していく。これがInitializeOutputSampleの役割。
このことから、上流から受けたサンプルと、自分で送るサンプルは全くの別物であるということがわかる。
送信が済んだら、このサンプルをリリースすることでバッファの開放などが行われる
(CTransformFilter::Receiveの最後の方 pOutSample->Release(); )

ちなみに上流から受けたサンプルをダイレクトにそのまま下流に出力するのはCTransInPlaceFilterだ

つづく

312:デフォルトの名無しさん
07/03/12 23:10:36
早い話、君は2回送ってるつもりでも、3回送っていると思われる
しかも3回目のサンプルの時間情報は上流から受けた時間そのもの

313:デフォルトの名無しさん
07/03/12 23:13:13
Transformメソッドはサンプルの内容を変更するだけじゃないと ブー
そういう設計なんでこざいます だからここから送信したら ブーブー
TransformInputPin::Receiveをオーバーライドしないとアカンねん

314:デフォルトの名無しさん
07/03/12 23:23:29
まちがえた TransformFilter::Receiveな 酒のんでるからすまんの

サンプルのタイムスタンプ見てレンダラが表示のタイミングを待ったり、時には捨てたりするアルよ
サンプルの不連続性(Discontinuity)とか同期ポイント(SyncPoint)を示すフラグの扱いとか
注意してくれよ キレイなフィルタを作りましょう。んじゃ頑張れ



315:265
07/03/12 23:33:31
>>308
了解です。
>それとDirectShowで「サンプル」といえば、IMediaSample2などのデータの事をしめします。
そういうことでしたか・・・
失礼しました。
>>309
ありがとうございます。
調べてみます。
>>310-314
とても丁寧にありがとうございます。
がんばります。

316:デフォルトの名無しさん
07/03/14 22:52:01
>>306
dvsdなんかではCreateDIBSectionに失敗しそうな気がするけど、それはないの?

あと、フィルタいじれるなら入力ピンのCheckMediaTypeでMEDIASUBTYPEの
RGB24かRGB32以外を弾くようにすれば、その辺不問にできるような気がするけど・・・。

317:デフォルトの名無しさん
07/03/15 01:14:32
すみません。
DVDをAVIにして保存したいんですが、YUYをRGBに変換するフィルタとAVIを書くフィルタは自前で作るのですか?
色々やってみてダメだったらヒントください。
ちょっと頑張ってくる。


318:268
07/03/15 14:03:14
>>316
はい、失敗します。orz
他の方法でやらなきゃいけないんでしょうか?

319:デフォルトの名無しさん
07/03/15 14:11:19
>>318
(1) 普通のDIBを用意して、そこにDrawDibDrawで描く
(2) 入力ピンのフォーマットをRGB24/RGB32に限定して、フィルタグラフ側で変換してもらう
(3) 自分でDVをでコードする

1,2は実質的にはaviのというかvfwのdvコーデックが使われる。

「やらなきゃいけない」かどうかは自分で決めればいい。
やりたくないならやらなくていいんじゃない?

320:268
07/03/15 16:40:18
>>319
うお、ありがとうございます!
ちょっくら試してみます!

321:268
07/03/15 18:38:43
とりあえず(1)はDrawDibOpenの時点で落ちるので保留。
(2)を試してみます。

URLリンク(webcamxtra.sourceforge.net)
これを活用すればいけそうな気もしてるんですけどね・・・。
今までウェブカメラは自力で処理できていたのでどうにかしたいもんです。orz

322:268
07/03/15 18:52:30
ん、DrawDibOpen動いた。
あとはDrawDibDrawの引数だけだと思うので、ちょっくら追ってみます。

323:デフォルトの名無しさん
07/03/15 23:07:58
ICaptureGraphBuilderを利用してSetOutputFileNameやって、
DVD Navigaterのフィルタを取ってRenderStreamすればAVIにできると思ったのにダメでした。

DVDをAVIにして保存する方法って何かあるんでしょうか。
サンプルグラバつなげられれば保存できる気もするんだけどPINをつなげられない。

324:デフォルトの名無しさん
07/03/16 00:54:44
ビデオ形式
ビデオ タイプについては、サンプル グラバは VIDEOINFOHEADER 形式を必要とします。VIDEOINFOHEADER2 や DVINFO などの
他の形式タイプを必要とするフィルタに接続することはできません。
このため、MPEG-2 や DV ビデオ、またはフィールド ベースの (インターレース)
ビデオとの互換性はありません。
URLリンク(www.microsoft.com)

うぉー、絶望的なことかいてあった。orz....
サンプルグラバに繋がらないわけだ。
Overlay Mixer −> サンプルグラバ −>AVIMUX という流れができるか明日ためしてみる。

325:268
07/03/16 16:53:10
DrawDibBeginがfalseを返す・・・。orz
というわけで他の方法試してみます。

326:デフォルトの名無しさん
07/03/16 16:55:37
BeginとEndは実は要らない。

327:268
07/03/16 17:12:04
>>319
> (3) 自分でDVをでコードする
って、サンプルとかないですよね・・・。orz

328:326
07/03/16 17:19:30
>>326
ま、マジですか。
ちょっくら試してみます。

329:368
07/03/16 17:20:05
あせって名前間違えた。orz
>>328は自分です。

330:268
07/03/16 17:24:46
うーん、DrawDibDrawがやっぱりfalse。
何か記述が足りない気がしてきた。

サンプル探してるんですけど全然見つからないんですよね。orz

331:デフォルトの名無しさん
07/03/16 21:58:23
>>330
サンプルグラバ使ってるんですよね?
SetMediaTypeでMEDIASUBTYPE_RGB24指定して
dvsdで流れてこないようにしたらどうですか?

あなたのレスをすべて追っかけてるわけじゃないんで、外してるかもしれませんが。

332:デフォルトの名無しさん
07/03/16 23:26:24
散文だし小出しだし追いかける気になれない。

333:デフォルトの名無しさん
07/03/17 01:06:17
OverlayMixerの後ろにサンプルグラバはつながらないと思うよ。
OverlayMixerはレンダラとつながる。そしてオーバーレイで自分が描画している。
後ろにつながっているビデオレンダラはメディアサンプルを受け取っておらず、
ウインドマネージャを提供しているに過ぎない。
つまりたとえつながってもサンプルを取ることはできない。

はず。


334:デフォルトの名無しさん
07/03/17 01:23:46
>>333
はい。そうでした。全く繋がらなくて1日無駄にしました。
DVDをAVIにしなきゃ行けないんで作り方を模索中。
やるならOverlayの上流にあるDVD用デコーダフィルタですかね。
GraphEditでRendererとサウンドをぶった切ってASFライタを入れると
DVDをWMVにできたりします。
この方式で画質設定と開始位置と終了位置を設定して保存できればいいのかもしれない。

最後にWMVをAVIに変換して終了させるという最低の方法を選ぶ。
AVIMUXにつなぐ方法ありましたらヒントください。

最近のライブラリから外れたBaseClassのCtransなんたらで自作フィルタを作るしかないんですかねぇ。
それでYUYをRGB24とかに変換。

DVD Navigater -> 何かフィルタ -> Video Commplessor -> AVI MUX -> File Writer
という形で保存できればいいんですが。

335:268
07/03/17 21:42:01
動きますた!(・∀・)
原因は>>316>>331あたりが正解だったようです。
ボスに言われてイチから書き直したらうまく動きました。

というわけで、本当にありがとうございました。
DirectShowと戦うことができたのはこのスレのおかげです。

336:デフォルトの名無しさん
07/03/17 22:04:51
>>335
おめっとさん、その二つはいずれも私ですがw
実はDirectorのXtraに興味があってちょっと追いかけてました。
Xtraの描画周りって何を参考にしました?
キャプチャした画像を直接Director上で表示するのでしょうか?

ちょいスレ違いスマソ

337:268
07/03/18 22:28:43
>>336
自分はDirector上での描画はやってないですね。
CreateDIBSectionで取得したピクセル毎のBGR値の差分を比較して使っています。

今回DVカメラを扱う上で参考にしたのは↓ですね。
URLリンク(wwwdoi.elec.nara-k.ac.jp)
処理部分コピペでもとりあえず動きます。
# コンソールも出せるみたいです。

Xtra開発者は海外の人ばっかりなので、日本人も増えてほしいもんです。

338:336
07/03/19 21:42:14
>>337
なるほどどうもっす。
DirectShowのフィルタ書いてお茶を濁そうと思っていたのですが、
クライアントの意向によりXtraを直接弄る必要があり、
ちょいとハマってたところでした。

DirectShowも情報ない方だけど、Xtraはもっと険しい道だなこりゃ・・・。

339:デフォルトの名無しさん
07/03/21 10:49:02
asfを再生しようとすると
DirectShow フィルタ グラフに存在しないピンに操作を実行しようとしました。
になって再生できません、対策はありませんか?

340:デフォルトの名無しさん
07/03/21 20:05:39
どうやって再生しようとしてんの?それじゃ意味わからんよ。

341:デフォルトの名無しさん
07/03/21 20:42:03
若いの オラが村では派遣労働の問題を口にしちゃなんねーだ
お前さんはまだわけぇから言いたいこともあるべぇ
だべな、派遣問題を口にするとバカにされたと思ってムキになって怒る者がおるでよぉ
てめぇでの責任で派遣やってる癖に派遣問題に触れると逆ギレするバカなんだけどよぉ
そんでもこの問題の指摘は駄目だっぺぇ
派遣のことは口にしちゃなんねぇ
この村みたいな民度ゼロの会社で現実忘れるためにはよ
北朝鮮とか宗教団体と一緒でよ、駄目なものを駄目と言ってはなんねえだべさ
タブーを口にしちゃいけねぇだ



次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

4277日前に更新/216 KB
担当:undef