MJPEG 画像インターネット ストリーム ビューアーを書きたいと思います。ソケットを使用して jpeg 画像を取得するのはそれほど難しい問題ではないと思います。しかし、正確なストリーミングを行う方法を知りたいです。
while (1)
{
get_image()
show_image()
sleep (SOME_TIME) // how to make it accurate?
}
どんな提案も素晴らしいでしょう。
正確にするために、次の 2 つの可能性があります。
ストリーミング サーバーのフレームレートを使用する。この場合、クライアントは同じフレームレートを維持する必要があります (フレームを取得するたびに計算し、フィードバックを使用して可変時間表示およびスリープします: 計算されたフレームレートがサーバーよりも高い場合 -> もっとスリープ; 低い場合-> スリープが少なくなると、クライアント側のフレームレートはサーバーからの元の値の周りにドリフトします)。ストリーミング接続の初期化中 (画像サイズやその他のパラメーターを取得するとき) にサーバーから受信するか、構成することができます。
実際、最も正確なアプローチは、フレームごとにサーバーからのタイムスタンプを使用することです (デマルチプレクサによってファイルから取得されるか、カメラ デバイスの場合はイメージ センサー ドライバーで生成されます)。MJPEG が RTP ストリームにパケット化されている場合、これらのタイムスタンプは既に RTP ヘッダーにあります。したがって、クライアントのタスクは簡単です: タイム オフセット、現在のタイムスタンプ、およびタイム ベースから計算された時間を使用して画像を表示します。
更新 最初のソリューションの場合:
time_to_sleep = time_to_sleep_base = 1/framerate;
number_of_frames = 0;
time = current_time();
while (1)
{
get_image();
show_image();
sleep (time_to_sleep);
/* update time to sleep */
number_of_frames++;
cur_time = current_time();
cur_framerate = number_of_frames/(cur_time - time);
if (cur_framerate > framerate)
time_to_sleep += alpha*time_to_sleep;
else
time_to_sleep -= alpha*time_to_sleep;
time = cur_time;
}
ここで、alpha はフィードバックの反応性の定数パラメーター (0.1..0.5) です。
ただし、表示プロセスをスムーズにするために、入力画像のキューを整理することをお勧めします。キューのサイズはパラメータ化でき、表示時間は約 1 秒、つまり数値的にはフレームレートに等しくなります。