- ベストアンサー
BiilderとD-Show フレームレート変更
- USB複数カメラのプログラム開発中に、複数カメラ使用で帯域超過を解決するためにフレームレートを低くしようとしていますが、うまくいっていません。
- フレームレートを取得する方法としてAvgTimePerFrameとGetOutputFPSがあります。AvgTimePerFrameは実装され、テストも終了しましたが、書き込みはできません。GetOutputFPSはどの解像度でも15FPSしか返しません。
- GetOutputFPSから選択された解像度に従ったフレームレートを出力する方法、または他の方法で選択された解像度のフレームレートを変更する方法を教えてください。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
いやまてよ >問題は複数カメラを使用するとPICバスの帯域を越えてしまうので、フレームレートを低くしようとしていますが、うまく行って居ません。 ここなんですよね? 改めて名前と解説から考えると IAMStreamConfig が気になります。 pStreamConfig->GetStreamCaps(Index,&pmt,(BYTE*)&scc); で得たAM_MEDIA_TYPEを hr = pStreamConfig->SetFormat(pmt); するまえに ((VIDEOINFOHEADER*)pmt->pbFormat)->AvgTimePerFrame = 数値; 的なことをするとどうなるのでしょうか? (関係ないかな?)
その他の回答 (4)
- LongSecret
- ベストアンサー率68% (22/32)
>ところでLongSecretさん、Builderやdirectxの質問サイトご存知ありませんか? 私はC++関連については専らVisual C++ を使ってきたので、Builderについては分かりません。 ただ、C++についての質問サイトということであれば Visual C++サイドのそれを利用しても、一応問題はないはずです。(C++ Builder使いながらMSDNのVC++のフォーラムで質問する、となると、ちょっとどうなのか分かりませんが…w ただ、そう言う点を除けばMSDNのVC++フォーラムとかは有力だとは思います。) また、DirectXはBuilderでも対応してるのは間違いないと思いますが Microsoft DirectXという名の通りMicrosoftが作ったAPIで、(全部は未確認ですが、おそらくManaged DirectXとか以外ネイティブな)C++で書かれているので 情報が充実している といえば、その中でもC++コードを非常に簡単に扱える 同じくMicrosoftが作ったVisual C++関連のサイトに、必然的に落ち着いてくると思います。 単純に、C++の基本的なクラスの仕様を煮詰めたい場合であれば C++関係の質問の場なら、ここでもMSDNのフォーラムでもYahoo知恵袋でも… 大抵の場所でなら教えてもらえるはずです。 あとは調べるときの「勘」とか「検索技術」は 実はかなり重要なポイントだったりするかもしれません。
お礼
色々ありがとうございました。 本日も色々試行錯誤していましたが、フレームレートの設定には至りませんでした。 とりあえずこちらの質問を締め切らせて頂きます。 もう一つの方は、今日の帰りがけにやって見たい事が出来てしまったので。来年、それを確認してから締め切ります。
- LongSecret
- ベストアンサー率68% (22/32)
>私としてはDirectShowもクラスの事もわからず、先人の物を引き継がされてしまっていますが、うちの部にはソフト屋さんは他に居ないので思い付いた事はやって見るだけです。 なかなか不憫な事でございますね。 とりあえず、私もちょろっとではありますが調べたことですので 下記内容を試してみて、出来るか出来ないかは教えていただけるとすっきりします(笑) 出来ないとしても各関数の戻り値などから活路が分かるかもしれませんし DirectShow等も結局「誰かが作ったもの」で、型や関数の意味だけ知ってればいいし、実装部は見えない(或いは見る必要がない)という扱いになってるので それぞれについて細かいことについて調べようとすれば、そのライブラリを作った人以外は、誰であっても ・ネットや書籍で調べる ・自分で実験してみる ・人に教わる といった方法しかないはずです。 とはいえ、C++のclassの詳細が分かっていれば、見た目が見慣れない型名や関数名などで、ぱっと見「うわぁ」と思う事はあったりはしても、丁寧に見たり実験していくことで、それぞれの意味を必ず理解出来るようになるはずです。 時間が全くないならひとまずおいとくとしても 今後C++に触る可能性が0でないなら、classの仕様について、ある程度把握しておくとかなり良い、かもしれません。 深いところに突っ込みだすとキリがないですが、基本的にはCのstructが拡張されたものだとお考えください。 ・Cのstructは、(表記上)変数だけで構成されていますが、C++のclassは、変数だけでなく関数もメンバに持っています。 ・C++ではstructもclassも「継承」が可能です。 ・Cのstructは、メンバに対して無制限にどこからでもアクセスできる(ため、意図しないところで書き換えられたりする危険がある)のですが、C++のclassやstructはアクセス修飾子、publicやprivate、あるいは継承先からのみ使用protectedを指定でき、どこからアクセスされるかを細かくコントロールできます。 ・C++のstructとC++のclassは、なにもアクセス修飾子を書かない時のデフォルトが、前者はpublic、後者はprivateになっていて、それ以外は前方宣言の時にしっかり class A; struct B; と、区別して書かないといけないといった細かいこと以外同じものです。 などなど。
お礼
>なかなか不憫な事でございますね。 そうなんですよね。カメラのIOは動くものとして、アプリケーションを組んで居たのに、カメラのIOの部分が仕様を満足しないから改造しないといけなく成るなんて。 私はクラスも分かりませんが、継承も漠然としか理解して居ないので大変です。 ところでLongSecretさん、Builderやdirectxの質問サイトご存知ありませんか? もっともMSDNのフォーラム追いかけていったら英語のサイトに繋がってしまって、おまけに2008年辺りで交信が切れていたり。 ゲーム作成のサイトはにぎやかそうですが、やっている内容が全然分かりませんでした。 私レベルだとこのサイト位が一番いいんでしょうかね。 何度か画像処理は辞めたいと申告したんですが、却下されてしまい、今はやるしか無い状態です。 まぁ、今回の件は今までUSBカメラのキャプチャーに1~2秒かかって居たのが100mS程度でキャプチャー出来るので、現場が遅いプログラムでも何とか待つて居てくれていますが、原因が判ったので早く実装させたい機能です。 ぼやいてすみません。
- LongSecret
- ベストアンサー率68% (22/32)
あ、もちろん No1のコードはテストコードなので戻り値チェックとかはしていませんが 実際にはご質問のコードのようにそれぞれの場所で hr = pStreamConfig->GetStreamCaps(Index,&pmt,(BYTE*)&scc); if ( hr != S_OK ){ 等々のチェックをちゃんと行ってください。
お礼
はい、とりあえず動作出来たらその後で追加致します。 ありがとうございます。
- LongSecret
- ベストアンサー率68% (22/32)
こんばんは。 ハードが関連しそうなことはモノ(この場合Webカメラ)がないと把握が難しいので 相変わらず詳しいところは全く分かっていませんが PutOutputFPSではなくSetOutputFPSではないでしょうか? http://msdn.microsoft.com/ja-jp/library/cc355147.aspx >もっとも、後半のプログラムはどの解像度を選択されているか関数に伝わって居ないと思われるので当然でしょうけど。 おっしゃるとおり、たぶん下の方は単純に、タイムラインってやつを生成したり 生成直後の状態をGetしたりしてる(?) 感じのコードに思いますし // ここからGetOutputFPS用のプログラム 以降 pStreamConfig->Release(); の手前まで 上の部分で使った変数名が一個も出てこないのですが とりあえず、下のほうの部分についてだけ てきとーなコードでSetOutputFPSがS_OKを返してくる(成功する)ことは確認できました。 Debug::f(引数); は単に、デバッグ簡単にするために使ってる自作関数です。 上述の通りS_OKを表示してくれました IAMTimelineObj* obj; IAMTimeline* tline; CoCreateInstance(CLSID_AMTimeline, NULL, CLSCTX_INPROC_SERVER, IID_IAMTimeline, (void**)&tline); tline->CreateEmptyNode( &obj, TIMELINE_MAJOR_TYPE_GROUP ); IAMTimelineGroup* group; obj->QueryInterface(IID_IAMTimelineGroup, (void**)&group); double dTmp; Debug::f( group->SetOutputFPS( 60.0 ) ); //現状よく分かってないので数値は適当です tline->AddGroup( obj ); ///つくったものは1対1の対応で全て解放をお忘れなく(DirectX(やCOM?)関連のインターフェースはRelease関数で解放というのが多いです。)/// obj->Release(); tline->Release(); group->Release(); ///CoInitializeを呼び出したら、いつかはCoUninitializeするのをお忘れなく/// CoUninitialize(); あとは、AvgTimePerFrameのやつで、一致させられる …ということでいいのかどうかは、ご確認ください。
お礼
こちらの問題もご回答頂いてありがとうございます。 >PutOutputFPSではなくSetOutputFPSではないでしょうか? 打ち間違いです。すみません。 >///CoInitializeを呼び出したら、いつかはCoUninitializeするのをお忘れなく/// はい、プログラムの開始と終了の所でやっています。 >上の部分で使った変数名が一個も出てこないのですが そうなんです、どうやって関連付けて良いかわからなくて、今日半日MSDS等を見ていましたが、結局判りませんでした。 明日、家のPCで出来るかやってみます。そうで無ければ月曜までまって、会社のpCでやらざるを得ないのですが。 ここの所が解決すると、かなり処理が速く成るので何とかしたい所です。 自分のPCで出来て、何で現場のPCで出来ないのか長い間疑問でしたが、PCIバスの帯域らしい事が判ったら、今度は先人の作成したプログラムにはフレームレートの制御部分が無くて、八方ふさがりです。 兎に角、知識が無いので色々やって見るしかありません。 ありがとうございました。
お礼
私としてはDirectShowもクラスの事もわからず、先人の物を引き継がされてしまっていますが、うちの部にはソフト屋さんは他に居ないので思い付いた事はやって見るだけです。 ありがとうございました。