
・目的は、
ネットワークカメラBB-HCM311
http://panasonic.biz/netsys/netwkcam/lineup/hcm3 …
http://panasonic.biz/netsys/netwkcam/support/dow …
から流れてくるMotionJpegをパソコンのファイルに格納すると言うものです。
・現状としては、MotionJpegのJpegを切り出して保存することが出来ています。
・未解決の問題は、カメラから配信されているデータを100%取得できていないと言う所です。なぜならば、下のソースに示すように、Read()でバッファに格納しもう一度Read()を行うまでにf()を実行するために、f()の実行中にカメラからの配信が進んでしまうためです。
通常のファイルをサーバーから取得する場合は順次読み込めば問題ないと思うのですが、このようなストリーム配信の場合、何か参考になるものをご存じないですか?
よろしくお願いします。
開発環境 VC6.0, OS WinXP Pro
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
>スレッド中でRead()だけを繰り返し処理した場合に、Read()が終わって次のRead()を呼ぶ間に必ず遅延が起こると思っているからです。
よーく考えてみてくださいね。
これがちゃんと出来なきゃ何にもできませんよねぇ(^^;;;
無限大のバッファなんて準備できないんですから。
>OSがWindowsXPですから、リアルタイム性は保証して無いだろうと思っているわけです。
うーん、ネットワーク、TCP/IPという時点で、リアルタイム性はそこまで意味は無いかと・・・
あくまでも受信データの取りこぼしが無ければいいのですから。十分なサイズのバッファと、単位時間に送られてくるデータ量以上の速さでデータをOSのバッファから自分の準備した領域に取り出せればいいんですよね。OS側のバッファがあふれる前に。
あと、
>あとマルチスレッドなら、取りこぼし防ぐために受信スレッドの方をプライオリティをあげておいたほうがいいでしょう。
確かに受信スレッドのプライオリティあげるべきですけど、それによってファイル書き込みが間に合わなくなると本末転倒ですのでバランスが肝心です。
いやー。 たのしいっすねここ。
まわりにこういうネタについてきてくれる人がいなくて(汗) 所詮私も含めて開発系には弱いということでしょうか・・・。
よーく考えてやってみます。
No.3
- 回答日時:
ダブルバッファでは足らないこともあるように思えますので、
さらに多くのバッファを用意して、
既に回答があるようにファイル書き込みを別スレッドで行うか、
非同期I/O(オーバーラップ I/O)を使うかでしょうね。
あとマルチスレッドなら、取りこぼし防ぐために受信スレッドの方をプライオリティをあげておいたほうがいいでしょう。
ありがとうございます。今のネットワーク環境の転送速度のせいか、取りこぼしを考慮して1秒間に8枚程度しかデータが流れてきていないようです。ということで、ダブルバッファリングを使ってもうちょっときっちりやってみます。
taka_tetsuさんterra5さん、また後日報告いたします。
No.2
- 回答日時:
>ダブルバッファリング+(スレッドで2回線つないで交互に取り込む)も考えましたが、どうも接続数を増やすとパフォーマンスが落ちてあまり速度が得られないようです。
なぜ接続数を増やすんですか?
Read()を連続しておこないたいんですよね?
別スレッド内で処理を行えばいいのはf()なんですから。
Read()をしてるメインスレッド内のループはバッファに書き込むだけ、f()の内部処理を行うスレッドのループは1つのバッファが満杯になったかチェックし、なってたらファイル格納を行うようにするのが普通かと。
ありがとうございます。
接続数を増やし2回線で冗長に取り込もうと思った理由について→スレッド中でRead()だけを繰り返し処理した場合に、Read()が終わって次のRead()を呼ぶ間に必ず遅延が起こると思っているからです。
OSがWindowsXPですから、リアルタイム性は保証して無いだろうと思っているわけです。
ちょっと詳しく実験してみます。
スレッドはあまり詳しくないので、まずf()で何もせずにRead()を繰り返してみました。その時つなぎ目が怪しかったので、私のプログラムにどこかにバグがあるかもしれません。少しお時間をください。
No.1
- 回答日時:
一般的にはダブルバッファリングでしょう。
バッファを2つ以上準備し、1つのバッファが満杯になったら別スレッドで保存を行い、データの受信は残りのバッファで行えばいいかと。
この回答への補足
ソースを補足します。
const int max_2len=一度に取得するデータの大きさ;
UINT nRead=0;
CInternetSession session;
CHttpConnection* pConnection
= session.GetHttpConnection( "IPアドレス" , ポート番号 , "ID" , "パスワード");
CHttpFile* pFile[2];
pFile[0]= pConnection->OpenRequest
( CHttpConnection::HTTP_VERB_GET
, "/nphMotionJpeg?Resolution=640x480&Quality=Motion HTTP/1.0\r\n" );
pFile[0]->SendRequest();
DWORD dwRet;
pFile[0]->QueryInfoStatusCode( dwRet );
if( dwRet == HTTP_STATUS_OK )
{
BYTE* m_cambuf[2];// カメラからのデータを格納
m_cambuf[0]=new BYTE[max_2len];
int gflag[2]={0};
while( 1 )
{
nRead = pFile[0]->Read( m_cambuf[0], max_2len );// カメラからデータ取得
f(); // カメラからのデータをファイルに保存等
}
delete[] m_buf;
delete[] m_cambuf[0];
}
delete pFile[0];
delete pConnection;
session.Close();
お返事ありがとうございます。
私もそう思いますが、カメラ(HTTPサーバー)より送られてくる信号は、ソース中のRead()を間髪いれずに実行し続けなければ連続データを取り込むことができないようなのです。なぜかというと、Webカメラの画像をリアルタイムで配信する特性上、受け取らなかったデータは捨てて、常に新しいデータを配信する必要性があるからです。
ダブルバッファリング+(スレッドで2回線つないで交互に取り込む)も考えましたが、どうも接続数を増やすとパフォーマンスが落ちてあまり速度が得られないようです。
むしろ、リングバッファのようなイメージで、途切れず取り込みながら保存していく方法って無いかと模索中です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
「スイッチングハブのバッファ...
-
シリアル通信の出力バッファと...
-
socket: recvはいつ,どれだけ...
-
mscommの受信バッファ異常について
-
WriteFile()でのデータ送信がで...
-
COMポートの同時オープン同時読...
-
WinsockAPIのrecvfromの受信デ...
-
ftplibのエラー処理
-
RS232C通信(PC⇔PLC)
-
winsockでソケット通信の開発を...
-
0byteデータの送信と受信
-
RS232C通信のC言語プログラム:...
-
ClearCommError呼び出し時のCE_...
-
RS-232Cでバイナリデータを受信...
-
Macターミナルで実行中のプログ...
-
TCP/IP通信時のサーバーからの受信
-
バックグラウンドのプロセスの...
-
Windows上で、シグナル(SIGTERM...
-
SQLの速度をあげるには・・・
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C# シリアル通信でデータ受信...
-
「スイッチングハブのバッファ...
-
WriteFile()でのデータ送信がで...
-
socket: recvはいつ,どれだけ...
-
winsockでソケット通信の開発を...
-
RS-232Cでバイナリデータを受信...
-
SerialPortのDataReceivedイベ...
-
シリアル通信エラー
-
C#で通信処理。応答がない場合...
-
Linuxでのシリアル通信について...
-
シリアル通信の出力バッファと...
-
バイナリデータ受信時のデータ順
-
ReadFileについて
-
トラックバック機能を作りたい
-
ソケット通信内 read関数について
-
recv関数の受信結果について
-
ReadFile(GPSとの通信)Win7で...
-
visual c# 2010 シリアル通信ア...
-
WinsockAPIのrecvfromの受信デ...
-
popen実行時にバッファが空の場合
おすすめ情報