[Armadillo:07432] Re: Armadillo-420 MJPG-streamer の画像乱れ問題について
Yasuhisa Nakamura
email@hidden
2011年 7月 29日 (金) 02:00:51 JST
中村です。
数年前、Armadillo-220でこのカメラを使うのに苦労しました。
たまたま今、手元に借り物のこのカメラ(の旧型)があるので、
夕方あたりからArmadillo-440につないで、ちょっと調べてました。
#A-220のときには、VIDIOC_DQBUFのioctl()が帰って来なく
#なることがあるのでその前にselect()でタイムアウトを
#付ける必要があったりとか、古賀さんが説明されているような、
#圧縮がかかりにくい被写体で画像のお尻が、ある解像度以上で
#切れる、という問題がありましたが、どちらも今回の現象とは
#関係はありませんので、その内容は省略。
今回の再現は簡単にできました。
input_uvc.so -f 10 -r 960x720
が、いい(再現しやすい)ようです。
花田さん worte:
> その上で、化け頻度が顕著&mjpg-streamer自体がエラー終了してしまうことは、
> mjpg-streamer動作上の問題(不具合)であると言えそうです。
今まで誰も気づかなかったのはなぜ?と思うような、単純バグでした。
uvcvideoドライバのsyslogへのトレース[*1]をsyslogに出してみて、
気づきました。
「解」は、このメールの最後で。。。。
[*1]
# echo 16 > /sys/module/uvcvideo/parameters/trace
> mjpg-streamerのinput_uvc周りのコードを精査した結果、
> 毎回(余分に)メモリコピーしていることがわかりました。
>
> v4l2でDQUEUE→バッファをtmpにコピー→(再)QUEUE→tmpからネットワーク送出→
これ非常に効率悪いですし、「なんかおかしいぁ〜」という部分が
mjpg-streamerにはたくさんあります。
構造体でデータ管理してますが、構造体に入れず一時的な変数や
バッファでよいものもたくさんありますし。。。。
その元はuvccaptureというソフトのようです。
それから、memcpy_picture()とis_huffman()という関数がありますが、
これは使われていません。でも、これを使わないとダメな、
V4L2_PIX_FMT_MJPEG な UVC カメラも過去に遭遇してます。
> jpegデータが切り詰められすぎている(JPEGヘッダサイズ以下)際は
> データコピーをしない…こんな処理がもともと入っていたのですが、
> これが発生した時に再QUEUEされない不具合があり、結果的に一定回数
> (ドライバで用意されたバッファ数分)のエラーが発生するとDQUEUEできるデータが
> なくなり終了してしまう…これがmjpg_streamerが落ちる原因のようです。
4回(v4l2uvc.h で define されている NB_BUFFER)
Ignoring empty buffer ...
が出ると、そこで落ちますね。
> 前述した正常データ判定に失敗した時も含め、正しく(早く)再QUEUEされるよう修正。
私はこうやりました。
小さなデータを受信してしまったときにre-queueしていないという
単純だけど見落としやすいバグってことで。
--- v4l2uvc.c-orig 2011-03-26 12:37:26.000000000 +0900
+++ v4l2uvc.c 2011-07-29 01:14:08.000000000 +0900
@@ -322,7 +322,7 @@
if (vd->buf.bytesused <= HEADERFRAME1) { /* Prevent crash
* on empty image */
fprintf(stderr, "Ignoring empty buffer ...\n");
- return 0;
+ goto requeue;
}
/* memcpy(vd->tmpbuffer, vd->mem[vd->buf.index], vd->buf.bytesused);
@@ -350,6 +350,7 @@
break;
}
+requeue:
ret = ioctl(vd->fd, VIDIOC_QBUF, &vd->buf);
if (ret < 0) {
perror("Unable to requeue buffer");
--
なかむら
armadillo メーリングリストの案内