Hatena::Grouptechmemo

USBカメラを使って色々遊ぶ日記(仮)

2008-04-10ちょっとだけコードを書いてみる

USBカメラのcapability

| 01:40 | USBカメラのcapability - USBカメラを使って色々遊ぶ日記(仮) を含むブックマーク はてなブックマーク - USBカメラのcapability - USBカメラを使って色々遊ぶ日記(仮)

luvcviewのヘルプを見たところ、-Lオプションでカメラの能力を調べられるようだ。

頑張って書く必要なかったかも。

$ ./luvcview -L
luvcview version 0.2.3
Video driver: x11
A window manager is available
video /dev/video0
/dev/video0 does not support read i/o
{ pixelformat = 'MJPG', description = 'MJPEG' }
{ discrete: width = 160, height = 120 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 176, height = 144 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 320, height = 240 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 352, height = 288 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 640, height = 480 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 800, height = 600 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 960, height = 720 }
        Time interval between frame: 1/15, 1/10, 1/5,
{ pixelformat = 'YUYV', description = 'YUV 4:2:2 (YUYV)' }
{ discrete: width = 160, height = 120 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 176, height = 144 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 320, height = 240 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 352, height = 288 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 640, height = 480 }
        Time interval between frame: 1/30, 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 800, height = 600 }
        Time interval between frame: 1/25, 1/20, 1/15, 1/10, 1/5,
{ discrete: width = 960, height = 720 }
        Time interval between frame: 1/10, 1/5,
{ discrete: width = 1600, height = 1200 }
        Time interval between frame: 1/5,

いきなり見てもよくわからないんだけどね。

2008-04-08Video4Linuxアプリをいくつか試す

luvcviewのソースを読んでみる(1)

| 23:22 | luvcviewのソースを読んでみる(1) - USBカメラを使って色々遊ぶ日記(仮) を含むブックマーク はてなブックマーク - luvcviewのソースを読んでみる(1) - USBカメラを使って色々遊ぶ日記(仮)

(1)とか付けてみたけど続くかどうかは不明。

まずは、初期化や設定はさておいて、どこでカメラから取得したデータを読んでいるのかを追ってみる。

メインのループは、luvcview.cの485行目付近。

    /* main big loop */
    while (videoIn->signalquit) {
	currtime = SDL_GetTicks();
	if (currtime - lasttime > 0) {
		frmrate = 1000/(currtime - lasttime);
	}
	lasttime = currtime;
	if (uvcGrab(videoIn) < 0) {
	    printf("Error grabbing\n");
	    break;
	}

    /* if we're grabbing video, show the frame rate */
    if (videoIn->toggleAvi)
        printf("\rframe rate: %d     ",frmrate);

	SDL_LockYUVOverlay(overlay);
	memcpy(p, videoIn->framebuffer,
	       videoIn->width * (videoIn->height) * 2);
	SDL_UnlockYUVOverlay(overlay);
	SDL_DisplayYUVOverlay(overlay, &drect);

	if (videoIn->getPict) { 
		switch(videoIn->formatIn){
		case V4L2_PIX_FMT_MJPEG:
			get_picture(videoIn->tmpbuffer,videoIn->buf.bytesused);
			break;
		case V4L2_PIX_FMT_YUYV:
			get_pictureYV2(videoIn->framebuffer,videoIn->width,videoIn->height);
			break;
		default:
		break;
		}
		videoIn->getPict = 0;
		printf("get picture !\n");
	}

	SDL_LockMutex(affmutex);
	ptdata.frmrate = frmrate;
	SDL_WM_SetCaption(videoIn->status, NULL);
	SDL_UnlockMutex(affmutex);
	SDL_Delay(10);

    }

さらに、実際に読んでいるのはuvcGrabという関数(v4l2uvc.c)のようだ。

デバイスを制御するのにはioctl関数を使い、なおかつVIDIOC_で始まるコマンドでvideoデバイス関連のコマンドを実行している。

    ret = ioctl(vd->fd, VIDIOC_DQBUF, &vd->buf);

これが、デバイスのバッファにある撮影したフレームを取り出す部分のようだ。

本関数の最後の方に、

    ret = ioctl(vd->fd, VIDIOC_QBUF, &vd->buf);

とバッファをエンキューしている部分があるので、複数あるバッファに対して、フレームを読み出す→空いたバッファを再度エンキューする、という繰り返しかと想像。

時間のあるときにもうちょっと頑張る。