- ベストアンサー
動画の遅延再生プログラム
- PCとPCカメラを使って、10秒前後の遅延再生する簡易プログラムを作りたいと思っております。
- 高スペックなPCにもかかわらず、フレームレートがばらつきます。おそらくWindowsかカメラの自動制御が悪さをしていると思われます。
- ソースの改良、ハードの取替え、動作環境の変更等対策がありましたらご教授願います。なるべくなら、安価に仕上げれるものが望ましいです。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
>サンプルプログラムの普通の動画再生であれば問題ありませんでした サンプルプログラムとあなたのプログラムの違いは、バッファリングするかしないかの違いでしょう? それでは、バッファ長を1にすれば、サンプルプログラムの挙動と一致するのではないのですか?その場合にはきちんと動作しますか? 情報を小出しにされると、こちらから問い合わせをしなければならず、大変です。バッファに10秒溜まったら再生が開始されるのですか。それとも、GUIか何かのボタン押しで再生を開始するのですか。 どれだけのスレッドが走っているのかも重要な情報です。
その他の回答 (4)
- hidebun
- ベストアンサー率50% (92/181)
ANo.2の >仮に1フレームずつ送る仕様だったとしたら、一番大事なことは、プログラムをデータ受信に専念させたときに、フレーム間隔毎(30fpsなら33msec毎)にデータがとれるかどうか?を確認することです。 については、どうですか? 画像の時刻と、Windowsの取得時刻の両方を比較する必要がありますが、ぱっと見、画像の時刻は、ewc_timeに入っているのではありませんか? それから、受信と表示は別スレッドにしているのですか? CPUはマルチコアでしょうか。データ表示にCPUを使っている間はデータが受信できていない(もしくは、同一バッファ上に上書きされる)と思いますが、そもそもどのようなシステムかわからないので、これ以上はアドバイスできません。 10秒遅延というのは、まずは10秒間データを溜めておき、以後は再生しながら受信を続けるということなのでしょうか?
補足
たびたびありがとうございます。 遅延というのは断続的に行うもので、再生しながら受信するものです。 画像の取得時間はewc_time、timeGetTime()を使う,もしくは 時間取得に関する関数無しで行いましたが、 いずれにしても明らかに遅くなったり、かと思えば、いきなり速くなったりします。 ちなみにフレームレートを30fpsにしても 速くても15fps位までしかいかず、遅いときは5fps以下になってしまいます。 この波も一定ではなく、また撮影対象の光量を落すと、すぐに処理速度が遅くなるわけではありませんが、しばらくするとずっと5fpsくらいになってしまうケースがあります。 まとめると原因がはっきりしないのです。 EWCLIBはDirectShowをつかっているのでこれのせいかもしれません。
- hidebun
- ベストアンサー率50% (92/181)
そういえば、そのライブラリに、最低限これだけでカメラから取得した動画を表示できる、というようなサンプルプログラムはついていませんでしたか。 もし、サンプルプログラムで、フレームレートがばらつかないようなら、あなたのプログラムに問題があることになりますし、ばらつけば、ハードウェアスペックの問題かもしれません。
補足
ありがとうございます。 サンプルプログラムの普通の 動画再生であれば問題ありませんでしたので、 私のプログラム、Windowsの何らかの制御、またはWEBカメラの自動露出や検知の制御が原因と予測していたのですが、、 プログラムはメモリのリークもないはずですし、変数も動的に 宣言しているので、物理メモリはぜんぜん足りているはずで、 さらにプログラム自体もシンプルこの上ないので、 ドツボにはまっております。
- hidebun
- ベストアンサー率50% (92/181)
イメージバッファとはなんですか?表示用のバッファですか。 もしそうなら、データを格納する処理もコメントアウトして下さい。 (CPU、物理メモリは特にスペックを必要としていない…) から類推するに、表示用のバッファについてのコメントと思うのですが。 >EWCLIB自体は1フレームずつ送っていると思われます。 本当ですか?これ、確認とれてますか。 変数宣言と1フレームずつ送る仕様とは関係がないと思いますよ。 仕様をきちんと確認して下さい。 「思われます」は「あなたが思っているだけ」ということがよくあります。 思い込みからつぶしていかないとバグは消えませんよ。 仮に1フレームずつ送る仕様だったとしたら、一番大事なことは、プログラムをデータ受信に専念させたときに、フレーム間隔毎(30fpsなら33msec毎)にデータがとれるかどうか?を確認することです。 そうすることで、何が問題なのかが見えてきます。 個人的にはIsCapturedの仕様がかなり曖昧な気がします。 取得画像に対しては通常、取得時刻とかフレーム番号とかがついていると思うのですが、そのような情報はないのでしょうか。 質問者さんは、timeGetTime()で自前で作っているように思いますが。 それから1フレームもとりこぼしてはいけないようなプログラムはWindowsでは無理です。取りこぼしも視野に入れて設計する必要があります。
補足
すべてEWCLIBのヘッダファイル内ですが、 1フレームの取り込みはこの辺だと思います。 ー---------------------------STDMETHODIMP BufferCB(double dblSampleTime, BYTE *pBuffer, long lBufferSize) { ewc_bufsize[i]= lBufferSize; int wx= ewc_wx[i]; int wy= ewc_wy[i]; int byte= lBufferSize/wy; //画像の上下を逆にしてコピー for(int y=0; y<wy; y++){ memcpy((unsigned char *)ewc_pbuf[i]+(wy-1-y)*byte, pBuffer+y*byte,byte); } ewc_time[i]=dblSampleTime; return S_OK; -------------------------------- またバッファはアドレス変更の関数を使っています。 ------------------------------- //バッファアドレスを変更 int EWC_SetBuffer(int num, void *buffer) { if(numCheck(num)) return 1; ewc_pbuf[num]=(int *)buffer; return 0; } ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー 当方知識不足のため、ヘッダファイルはいじっておりません。 やはりヘッダファイルの無駄な命令を削除し、改造するべきなのでしょうか。
- hidebun
- ベストアンサー率50% (92/181)
1.データ受信のみなら、受信速度は安定しているのでしょうか。(別スレッドで表示プログラムが動いていたら止める) 2.EWC_IsCapturedの前のsleep(1)ですが、1msec待つ保証はないですが、その辺りは大丈夫ですか?これを削ったらどうなりますか。 3.データは必ず1フレームずつ送られてくるのですか。2フレーム分送られてきたりしないのでしょうか。 問題の切り分けをしていかないと、この手の問題はなかなか収束しないと思います。
お礼
ありがとうございます。 1.各処理速度を測ったところ、イメージバッファへの データの収納に費やす時間にばらつきがあるみたいです。 2.sleepをはずしてもCPUの稼働率が100%になるだけで 根本的に処理に影響はありません。 (CPU、物理メモリは特にスペックを必要としていない模様で す。) 3.変数宣言の段階で間違いがなければ、EWCLIB自体は 1フレームずつ送っていると思われます。 よろしくおねがいします
補足
ありがとうございます。遅延再生は 連続したものであり、起動時から、 アプリケーションの終了時まで 半永久的に動作するものです。 調査したところ、バッファ長は1であっても 100であってもかわりませんでした。 またWEBカメラの設定を完全手動にしたところ、 速度が上がりました。 とはいっても15FPSより大きくはなりませんでした。 とりあえず、明らかな不良はなくなりましたので、 再度自分で調査してみます。 ありがとうございます。