• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:動画の遅延再生プログラム)

動画の遅延再生プログラム

このQ&Aのポイント
  • PCとPCカメラを使って、10秒前後の遅延再生する簡易プログラムを作りたいと思っております。
  • 高スペックなPCにもかかわらず、フレームレートがばらつきます。おそらくWindowsかカメラの自動制御が悪さをしていると思われます。
  • ソースの改良、ハードの取替え、動作環境の変更等対策がありましたらご教授願います。なるべくなら、安価に仕上げれるものが望ましいです。

質問者が選んだベストアンサー

  • ベストアンサー
  • hidebun
  • ベストアンサー率50% (92/181)
回答No.5

>サンプルプログラムの普通の動画再生であれば問題ありませんでした サンプルプログラムとあなたのプログラムの違いは、バッファリングするかしないかの違いでしょう? それでは、バッファ長を1にすれば、サンプルプログラムの挙動と一致するのではないのですか?その場合にはきちんと動作しますか? 情報を小出しにされると、こちらから問い合わせをしなければならず、大変です。バッファに10秒溜まったら再生が開始されるのですか。それとも、GUIか何かのボタン押しで再生を開始するのですか。 どれだけのスレッドが走っているのかも重要な情報です。

rairarai
質問者

補足

ありがとうございます。遅延再生は 連続したものであり、起動時から、 アプリケーションの終了時まで 半永久的に動作するものです。 調査したところ、バッファ長は1であっても 100であってもかわりませんでした。 またWEBカメラの設定を完全手動にしたところ、 速度が上がりました。 とはいっても15FPSより大きくはなりませんでした。 とりあえず、明らかな不良はなくなりましたので、 再度自分で調査してみます。 ありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (4)

  • hidebun
  • ベストアンサー率50% (92/181)
回答No.4

ANo.2の >仮に1フレームずつ送る仕様だったとしたら、一番大事なことは、プログラムをデータ受信に専念させたときに、フレーム間隔毎(30fpsなら33msec毎)にデータがとれるかどうか?を確認することです。 については、どうですか? 画像の時刻と、Windowsの取得時刻の両方を比較する必要がありますが、ぱっと見、画像の時刻は、ewc_timeに入っているのではありませんか? それから、受信と表示は別スレッドにしているのですか? CPUはマルチコアでしょうか。データ表示にCPUを使っている間はデータが受信できていない(もしくは、同一バッファ上に上書きされる)と思いますが、そもそもどのようなシステムかわからないので、これ以上はアドバイスできません。 10秒遅延というのは、まずは10秒間データを溜めておき、以後は再生しながら受信を続けるということなのでしょうか?

rairarai
質問者

補足

たびたびありがとうございます。 遅延というのは断続的に行うもので、再生しながら受信するものです。 画像の取得時間はewc_time、timeGetTime()を使う,もしくは 時間取得に関する関数無しで行いましたが、 いずれにしても明らかに遅くなったり、かと思えば、いきなり速くなったりします。 ちなみにフレームレートを30fpsにしても 速くても15fps位までしかいかず、遅いときは5fps以下になってしまいます。 この波も一定ではなく、また撮影対象の光量を落すと、すぐに処理速度が遅くなるわけではありませんが、しばらくするとずっと5fpsくらいになってしまうケースがあります。 まとめると原因がはっきりしないのです。 EWCLIBはDirectShowをつかっているのでこれのせいかもしれません。

全文を見る
すると、全ての回答が全文表示されます。
  • hidebun
  • ベストアンサー率50% (92/181)
回答No.3

そういえば、そのライブラリに、最低限これだけでカメラから取得した動画を表示できる、というようなサンプルプログラムはついていませんでしたか。 もし、サンプルプログラムで、フレームレートがばらつかないようなら、あなたのプログラムに問題があることになりますし、ばらつけば、ハードウェアスペックの問題かもしれません。

rairarai
質問者

補足

ありがとうございます。 サンプルプログラムの普通の 動画再生であれば問題ありませんでしたので、 私のプログラム、Windowsの何らかの制御、またはWEBカメラの自動露出や検知の制御が原因と予測していたのですが、、 プログラムはメモリのリークもないはずですし、変数も動的に 宣言しているので、物理メモリはぜんぜん足りているはずで、 さらにプログラム自体もシンプルこの上ないので、 ドツボにはまっております。

全文を見る
すると、全ての回答が全文表示されます。
  • hidebun
  • ベストアンサー率50% (92/181)
回答No.2

イメージバッファとはなんですか?表示用のバッファですか。 もしそうなら、データを格納する処理もコメントアウトして下さい。 (CPU、物理メモリは特にスペックを必要としていない…) から類推するに、表示用のバッファについてのコメントと思うのですが。 >EWCLIB自体は1フレームずつ送っていると思われます。 本当ですか?これ、確認とれてますか。 変数宣言と1フレームずつ送る仕様とは関係がないと思いますよ。 仕様をきちんと確認して下さい。 「思われます」は「あなたが思っているだけ」ということがよくあります。 思い込みからつぶしていかないとバグは消えませんよ。 仮に1フレームずつ送る仕様だったとしたら、一番大事なことは、プログラムをデータ受信に専念させたときに、フレーム間隔毎(30fpsなら33msec毎)にデータがとれるかどうか?を確認することです。 そうすることで、何が問題なのかが見えてきます。 個人的にはIsCapturedの仕様がかなり曖昧な気がします。 取得画像に対しては通常、取得時刻とかフレーム番号とかがついていると思うのですが、そのような情報はないのでしょうか。 質問者さんは、timeGetTime()で自前で作っているように思いますが。 それから1フレームもとりこぼしてはいけないようなプログラムはWindowsでは無理です。取りこぼしも視野に入れて設計する必要があります。

rairarai
質問者

補足

すべて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)
回答No.1

1.データ受信のみなら、受信速度は安定しているのでしょうか。(別スレッドで表示プログラムが動いていたら止める) 2.EWC_IsCapturedの前のsleep(1)ですが、1msec待つ保証はないですが、その辺りは大丈夫ですか?これを削ったらどうなりますか。 3.データは必ず1フレームずつ送られてくるのですか。2フレーム分送られてきたりしないのでしょうか。 問題の切り分けをしていかないと、この手の問題はなかなか収束しないと思います。

rairarai
質問者

お礼

ありがとうございます。 1.各処理速度を測ったところ、イメージバッファへの   データの収納に費やす時間にばらつきがあるみたいです。 2.sleepをはずしてもCPUの稼働率が100%になるだけで   根本的に処理に影響はありません。   (CPU、物理メモリは特にスペックを必要としていない模様で     す。) 3.変数宣言の段階で間違いがなければ、EWCLIB自体は   1フレームずつ送っていると思われます。 よろしくおねがいします

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • vc++2008で画像処理

    こんばんは、最近画像処理に手を出したものの双六が作れる程度の自分なので案の定上手くいきません。 やりたいことはVisual c ++ 2008、esplibとewclibを使って画像をキャプチャ、画像のbitデータの大きさで処理を決めるというシンプルなもののハズが画像の大きさを取得できなくて困ってます。 何回やっても画像保存バッファが表示されるため?比較ができません。 どなたか画像データの大きさで処理をできるようなプログラムをご教授ください。 opencvはあんまり考えていないのですが、opencvでできそうならそちらの方法でも教えてくださいますと大変助かります。 二つのhのヘルプを見てもどうも保存形式が良くわからないとです。int型らしいのですが比較できません。 vc++2008自体に画像データが入っている変数の大きさを測れるようなものがあるなら遠回りはしなくても良いのですが・・・。 カメラは安価なlogicool c270です。 #include <esplib.h> #include <ewclib.h> #include<stdio.h> #define WX 640 #define WY 480 void ESP_Ready(void) { ESP_CreateImage(0,"Camera",0,0,WX,WY,100); ESP_OpenTextWindow(0,86,512,439,135); ESP_Printf("Startをクリックしてください.\n"); } void ESP_Main(void) { ESP_Printf("初期化中...\n"); int r= EWC_Open(0,WX,WY,30.); int set,sset,key; key=0; if(r){ ESP_Printf("Error %d\n",r); return; } for(;;){ if(ESP_STOP) break; if(EWC_IsCaptured(0)){ EWC_GetImage(0,ESP_VramPtr[0]); EWC_GetImage(0,&set); ESP_Update_(0); ESP_Printf("*"); key=key+1; } } EWC_Close(0); ESP_Printf("Stopped\n"); if(key>10){ EWC_GetImage(0,&sset); if(sset<set){//判断部分} else{//逆なら}   ESP_Printf("%d""%d",&set,&sset);//大きさ表示 } } void ESP_Finish(void) { }

  • WEBカメラの動画制御を動的配列で、、

    先日「WEBカメラの画像を一定時間溜め込んで、    任意のタイミングで出力するプログラムのメモリ領域の    確保」に関して質問した者です。2次元配列を当初グローバルに宣言したところ、速度が遅くなってしまったため、動的に宣言したところ目標の速度を達成しました。 しかし停止時に例外が出てしまい、何度もプログラムを繰り返しているとどんどん速度が遅くなってしまいます。 原因を探っておりますがわかりません。 プログラムの変更箇所(動的配列の宣言部)を載せました。 これ以外のところは遅くとも正常に動作していた時と同様です。 例外の具体的な内容を明日にでもアップします。 情報不十分かもしれませんが、明らかな不具合等ありましたら、 お教えいただけますでしょうか? -ーーーーーーーーーーーーーーーーーーーーーーーー #define FRAMES 200 #define WX 640 #define WY 480 //int array[FRAMES][WX*WY]; グローバル宣言時のもの void Main(void) { int **array; array = new int*[FRAMES]; for(int i=0;i<FRAMES+1;i++){ array[i] = new int[WX*WY]; } //array[FRAMES][WX*WY]溜め込んで、     //任意のタイミングでディスプレイに出力します。 if(STOP) goto fin; } fin: for(int i=0;i<FRAMES+1;i++){ delete[] latesc[i]; } delete[] latesc; }

  • 続 仮想メモリの制御

    昨日 http://oshiete1.goo.ne.jp/qa3665270.html で質問させていただいた者です。 沢山の方に多様なアドバイス頂き感謝しております。 さて当方のメモリ使用量に関しまして、調査したところ、 初めの行列の宣言がメモリを食いまくっていることが発覚しました。 そこでグローバルで ------------------- #define FRAMES 1000 #define WX 640 #define WY 480 int arraya[FRAMES][WX*WY]; --------------- の配列を宣言すると 普通に計算すると1000×640×480×4=約1.2GB になるため、さすがに大きすぎると思い、 ------------------- #define FRAMES 300 #define WX 320 #define WY 240 int arraya[FRAMES][WX*WY]; --------------- 約92.16MBにしても両方とも物理メモリ制限一杯の 1.3GBを消費してしまいます。 これはプログラム自体を実行する以前になってしまうため、 宣言自体に問題があるのかと思うのですが、 何か定義したり、設定したりしなければいけないのか、 もしくは、宣言する場所が不適切なのでしょうか? 開発ツールはVC++です。

  • このプログラムを改良して…

    #include<stdio.h> #define NMAX 200 int n; int a[NMAX], x[NMAX]; void yomikomi() { for(n=0; scanf("%d %d",&a[n],&x[n])!=0;n++); return; } void hyouzi() { int i; for(i=0;i<n;i++) printf("%5d %5d\n",a[i],x[i]); return; } void seiretu() { int i,j,max,k,w; for(i=0;i<n-1;i++){ max=x[i];k=i; for(j=i+1;j<n;j++) if(x[j]>max){ max=x[j];k=j; } w=a[k];a[k]=a[i];a[i]=w; x[k]=x[i]; x[i]=max; } return; } main() { printf("Sorting\n"); yomikomi(); printf("\nInput data\n"); hyouzi(); seiretu(); printf("\nSorted data\n"); hyouzi(); return(0); } 以上のプログラムは、 Sorting 1 87 2 91 3 76 4 84 5 61 6 100 7 93 \n\n と入力しますと、 Input data 1 87 2 91 3 76 4 84 5 61 6 100 7 93 Sorted data 6 100 7 93 2 91 1 87 4 84 3 76 5 61 Press any key to continue という結果(左が番号として右が点数とした場合、点数が上位のものから番号を並びかえる)が出るプログラムです。このプログラムを改良して、上の結果を例として、 Input data 1 87 2 91 3 76 4 84 5 61 6 100 7 93 Guusuu   3 76 4 84 6 100 Kisuu 2 91 3 76 5 61 7 93 という風に右側の数が偶数か奇数かでわけて結果を出すことは可能でしょうか?可能であれば教えてください。お願いします。

  • プログラムの添削

    以下のような数当てゲームを作りました.なるべくうまいプログラムを書けるようになりたいのですが,どのような改善点がありますか?よろしくお願いします. /*数当てゲームを作りなさい.*/ #include<stdio.h> void maegaki(void); /*このように関数を定義しまくることに意味はあるのか?main関数はすっきりするけど.*/ void in_check_out(int i); int main(void) { int i; int j; maegaki(); for(j=0;j<10;j++) { scanf("%d",&i); in_check_out(i); if(!(i-1)) return 0; printf("残り%d回です.\n",9-j); } return 0; } void maegaki(void) { printf("数当てゲームをはじめます.\nぼくの好きな整数を当ててください.\nチャンスは10回です.\nヒントはボゾン\n"); } void in_check_out(int i) { if(!(i-1)) { printf("正解!答えは1です.\n"); } else { printf("残念!\n"); if(i>1) printf("%dより小さいです.\n",i); else printf("%dより大きいです.\n",i); } }

  • Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が

    Cプログラムで15パズルを作ってみたのですがうまく動作しません。何処が間違っているのかずっと考えているのですがいまだに解決策が見つかりません。ヒントでもいいのでお願します。 #include <stdio.h> int init(void); void show(void); int chk_cmp(void); char input(void); int move(char cmd); #define N 4 int panel[N][N] = { { 1, 2, 3, 4}, { 5, 6, 7, 8}, { 9, 10, 11, 0}, {13, 14, 15, 12} }; int x, y; int main(void) { printf("これは15パズルです。\n" "左上から右に向かって「1」から「15」が並ぶよう,\n" "「0」を動かしてください。\n" "操作はテンキーで行います。( 8(上),4(左),6(右),2(下) )\n"); if( !init() ) { printf("パネルの初期化に失敗しました。「0」のパネルがありません。\n"); return 1; } while(1) { show(); if( chk_cmp() ) { printf("完成です!\n"); break; } while(1) { if( move(input()) ) { break; } else { printf("そっちには動かせません。\n"); } } } return 0; } int init(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(panel[i][j]==0){ x=j; y=i; return 1; } } } return 0; } void show(void) { int i,j; printf("---------------\n"); for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ printf("%3d",panel[i][j]); } printf("\n"); } printf("---------------\n\n"); } int chk_cmp(void) { int i,j; for(i=0;i<=N-1;i++){ for(j=0;j<=N-1;j++){ if(i==N-1&&j==N-1){ if(panel[i][j]!=0){ return 0; } }else{ if(panel[i][j]!=N*i+j+1){ return 0; } } } } return 1; } char input(void) { int comand; while(1){ scanf("%d",&comand); if(comand==8||comand==4||comand==6||comand==2){ break; } printf("8(上),4(左),6(右),2(下)を入力してください。"); } return comand; } int move(char cmd) { int dx=0, dy=0; if(cmd==8){dy=-1;}//上 if(cmd==4){dx=-1;}//左 if(cmd==6){dx=1;}//右 if(cmd==2){dy=1;}//下 if(x+dx>=0&&x+dx<=N-1&&y+dy>=0&&y+dy<=N-1){ panel[y][x]==panel[y+dy][x+dx]; panel[y+dy][x+dx]==0; y+=dy; x+=dx; return 1; } else{return 0;} }

  • C言語でのプログラム

    全対最短経路(フロイドのアルゴリズム)のプログラムを作成したんですが、以下のようなメッセージが出てしまい、どこが悪いのかさっぱりわかりません。どなたかご教授願えないでしょうか? <プログラム> #include<stdio.h> #define NC 999 /* It should be large enough. */ #define N 5 void floyd(int, int [][], int [][], int [][]); int W[N][N] = { { 0, 1, NC, 1, 5 }, { 9, 0, 3, 2, NC }, { NC, NC, 0, 4, NC }, { NC, NC, 2, 0, 3 }, { 3, NC, NC, NC, 0 }, }; int P[N][N]; int D[N][N]; main() { floyd(N, W, D, P); } void floyd(int n, int W[][], int D[][], int P[][]) { int i, j, k; for(i=0;i<n;i++){ for(j=0;j<n;j++){ P[i][j] = 0; } } for(i=0;i<n;i++){ for(j=0;j<n;j++){ D[i][j] = W[i][j]; } } for(k=0;k<n;k++){ for(i=0;i<n;j++){ for(j=0;j<n;j++){ if(D[i][k]+D[k][j]<D[i][j]){ P[i][j] = k; D[i][j] = D[i][k] + D[k][j]; } } } } printf("?nall pairs of the shortest pathes:?n"); for(i=0;i<n;i++){ for(j=0;j<n;j++){ printf("%3d ", D[i][j]); } printf("?n"); } printf("?n"); } <エラーメッセージ> In function `floyd': :30: error: invalid use of array with unspecified bounds :36: error: invalid use of array with unspecified bounds :43: error: invalid use of array with unspecified bounds :44: error: invalid use of array with unspecified bounds :45: error: invalid use of array with unspecified bounds :54: error: invalid use of array with unspecified bounds

  • プログラム

    教えていただきたいのですが、コマンドプロンプトでコンパイラして、実行結果が 2013 2013 hello 2013 hello nagoya 2013 hello nagoya kobe 2013 hello nagoya kobe osaka となるようにプログラミングしているのですが頭が悪く初心者の私にはできません。 下のプログラムだと間違いのようなのでご指摘お願いします。 #include <stdio.h> void main(void) { int i,j; for(j=1;j <= 5;j++) { for(i=1;i<=j;i++) { printf("2013\n"); printf("hello\n"); printf("nagoya\n"); printf("kobe\n"); printf("osaka\n"); } printf("\n"); } }

  • すいません。。改めて質問!!

    #include<stdio.h> #define NMAX 200 int n; int a[NMAX], x[NMAX]; void yomikomi() { for(n=0; scanf("%d%d",&a[n],&x[n])!=EOF;n++); return; } void hyouzi() { int i; for(i=0;i<n;i++) printf("%5d %5d\n",a[i],x[I]); return; } void seiretu() { int i,j,max,k,w; for(i=0;i<n-1;i++){ max=x[i];k=i; for(j=i+1;j<n;j++) if(x[j]>max){ max=x[j];k=j; } w=a[k];a=[k]=a[i];a[i]=w; x[k]=x[i]; x[i]=max; } return; } main() { printf("sorting\n"); yomikomi(); printf(\nInput data\n"); hyouzi(); seiretu(); printf(\nSorted data\n); hyouzi(); return(0); } これを改良して偶数と奇数に分けてソートするプログラムがわかればいいのですが。。まだ慣れないものですいませんでした。

  • 2×2行列の掛け算をするプログラム

    タイトルのプログラムなんですが、授業で例題としてソース渡されたんですが、学校のUNIXのやつだと動くんですけど、自分の使ってるVC++だと動かないんですよ。 その理由と、VC++で動くようにするにはどうしたらいいかおしえてください。 ソースは、 #include<stdio.h> void get_data(); void write_data(); void product(); main() { double a[2][2],b[2][2],c[2][2]; get_data(a); get_data(b); write_data(a); write_data(b); product(a,b,c); write_data(c); } void get_data(double p[][2]) { int i,j; printf("Input elements\n"); for(i=0;i<2;i++) for(j=0;j<2;j++){ printf("(%d,%d)-th element=",i,j); scanf("%lf",&p[i][j]); } } void write_data(double p[][2]) { int i,j; printf("\n"); for(i=0;i<2;i++){ for(j=0;j<2;j++) printf("(%d,%d)-th element=%lf\t",i,j,p[i][j]); printf("\n"); } printf("\n"); } void product(double u[][2],double v[][2],double w[][2]) { int i,j,k; for(i=0;i<2;i++) for(j=0;j<2;j++){ w[i][j]=0.0; for(k=0;k<2;k++) w[i][j]+=u[i][k]*v[k][j]; } } です。 よろしくおねがいします。