From owner-freebsd-users-jp@FreeBSD.ORG Tue Sep 9 04:24:55 2014 Return-Path: Delivered-To: freebsd-users-jp@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id C91424A7 for ; Tue, 9 Sep 2014 04:24:55 +0000 (UTC) Received: from mail-qa0-x22c.google.com (mail-qa0-x22c.google.com [IPv6:2607:f8b0:400d:c00::22c]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 8BCC8AB2 for ; Tue, 9 Sep 2014 04:24:55 +0000 (UTC) Received: by mail-qa0-f44.google.com with SMTP id j7so14961514qaq.17 for ; Mon, 08 Sep 2014 21:24:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:reply-to:sender:date:message-id:subject:from:to :content-type:content-transfer-encoding; bh=LFicc47ZBexqqc+zKhy29XE79krZWx8ekqqPcU95yAE=; b=mA+DNDKOhncTk63E0kCduBjuZZ5OZKCvCN1Gscer2FCYVyj8GmDlXISnhImH2FeEF8 3lNB/ktLro/ykaKM8U9YXvOKJMP+YRgx5ja5knwWtiOfA3mUmVLNIRoV23SA84iA3nuO mpWPj28MV7izmbHDZfvItPD/tfRcAGv21QnJ0wMhaPhCHM8DkpLTdSpVrk7zVDx+zxgh Ulb6Ewc7a03g7CtHPM4h4zMtmTQjGAWDdPYCH0LDqZYVIB3N7cKfRJXQZBzw/Chy8Cd8 VxDGe1j6LIDRAlYgrzTLBqhXKYYzIe1tRgPLMa8kIdEa0ZTG3fqQNKBerUV4nHrDFVKb 5TkQ== MIME-Version: 1.0 X-Received: by 10.140.31.133 with SMTP id f5mr7696431qgf.34.1410236694143; Mon, 08 Sep 2014 21:24:54 -0700 (PDT) Reply-To: hiroo.ono+freebsd@gmail.com Sender: hiroo.ono@gmail.com Received: by 10.140.19.9 with HTTP; Mon, 8 Sep 2014 21:24:53 -0700 (PDT) Date: Tue, 9 Sep 2014 13:24:53 +0900 X-Google-Sender-Auth: 9DrGU4R9-7hnQ7m2tCE-8aSThyI Message-ID: From: =?UTF-8?B?SGlyb28gT25vICjlsI/ph47lr5vnlJ8p?= To: freebsd-users-jp@freebsd.org Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: base64 Subject: [FreeBSD-users-jp 95274] =?utf-8?b?5YuV55S744Gu44Kt44Oj44OX44OB44Oj?= X-BeenThere: freebsd-users-jp@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Discussion relevant to FreeBSD communities in Japan List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Sep 2014 04:24:55 -0000 5bCP6YeO5a+b55Sf44Gn44GZ44CCDQoNCkZyZWVCU0Qg44GnIFVWQyDjgarjg4fjg5DjgqTjgrnj gYvjgonli5XnlLvjgpLjgarjgpPjgonjgYvjga7lvaLlvI/jga7jg5XjgqHjgqTjg6vjgavjgq3j g6Pjg5fjg4Hjg6PjgZnjgovjgZPjgajjga/jgafjgY3jgovjga7jgafjgZfjgofjgYbjgYs/DQoN CndlYmNhbWQgKCsgY3VzZS5rbykgKyBwd2N2aWV3IOOBrue1hOOBv+WQiOOCj+OBm+OBpyBVVkMg 44Gq44OH44OQ44Kk44K544GL44KJ55S75YOP44Gu44Kt44Oj44OX44OB44Oj44GM5Ye65p2l44Gm 44GE44G+44GZ44CCDQrjgaTjgb7jgorjgIENCiMgcHdjdmlldyAtcyB2Z2EgLWYgMzANCuOBr+WL leOBjeOBvuOBmeOAgg0KDQrjgZ/jgaDjgIFwd2N2aWV3IOOBr+ODleOCoeOCpOODq+OBuOOBruS/ neWtmOOBryBqcGVnIOeUu+WDj+OCkuikh+aVsOOBqOOBhOOBhuW9ouOBp+OBl+OBi+OBp+OBjeOB quOBhOOCiOOBhuOBquOBruOBp+OAgeS9leOBi+OBl+OCieOBruWLleeUuw0K5b2i5byP44Gn5L+d 5a2Y44Gn44GN44KL44KC44Gu44GM44Gq44GE44GL5o6i44GX44Gm44GE44G+44GZ44CCDQrkvZXj gYvpganlvZPjgarjgr3jg5Xjg4jjgqbjgqfjgqLjga/jgYLjgorjgb7jgZnjgafjgZfjgofjgYbj gYs/DQoNCuOBquOBiuOAgWZmbXBlZyDjgpLmrKHjga7jgojjgYbjgavli5XjgYvjgZfjgabjgb/j gZ/jgajjgZPjgo3jgIFtbWFwIOOCqOODqeODvOOBjOWHuuOBpuWLleOBjeOBvuOBm+OCk+OBp+OB l+OBn+OAgg0KDQojIGZmbXBlZyAtcyA2NDB4NDgwIC1yIDMwIC1mIHY0bDIgLWkgL2Rldi92aWRl bzAgLWYgbXBlZzJ2aWRlbyB0dC5tcGcNCi4uLg0KICBsaWJhdnV0aWwgICAgICA1Mi4gNjYuMTAw IC8gNTIuIDY2LjEwMA0KICBsaWJhdmNvZGVjICAgICA1NS4gNTIuMTAyIC8gNTUuIDUyLjEwMg0K ICBsaWJhdmZvcm1hdCAgICA1NS4gMzMuMTAwIC8gNTUuIDMzLjEwMA0KICBsaWJhdmRldmljZSAg ICA1NS4gMTAuMTAwIC8gNTUuIDEwLjEwMA0KICBsaWJhdmZpbHRlciAgICAgNC4gIDIuMTAwIC8g IDQuICAyLjEwMA0KICBsaWJhdnJlc2FtcGxlICAgMS4gIDIuICAwIC8gIDEuICAyLiAgMA0KICBs aWJzd3NjYWxlICAgICAgMi4gIDUuMTAyIC8gIDIuICA1LjEwMg0KICBsaWJzd3Jlc2FtcGxlICAg MC4gMTguMTAwIC8gIDAuIDE4LjEwMA0KICBsaWJwb3N0cHJvYyAgICA1Mi4gIDMuMTAwIC8gNTIu ICAzLjEwMA0KW3ZpZGVvNGxpbnV4Mix2NGwyIEAgMHgyZDAyYTQxMF0gbW1hcDogSW52YWxpZCBh cmd1bWVudA0KL2Rldi92aWRlbzA6IEludmFsaWQgYXJndW1lbnQNCkNvbnZlcnNpb24gZmFpbGVk IQ0K From owner-freebsd-users-jp@FreeBSD.ORG Tue Sep 9 11:05:54 2014 Return-Path: Delivered-To: freebsd-users-jp@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 0D24193A for ; Tue, 9 Sep 2014 11:05:54 +0000 (UTC) Received: from msgw002-02.ocn.ad.jp (msgw002-02.ocn.ad.jp [180.37.203.77]) by mx1.freebsd.org (Postfix) with ESMTP id 6AA937EC for ; Tue, 9 Sep 2014 11:05:52 +0000 (UTC) Received: from localhost (p8148-ipngn100303sizuokaden.shizuoka.ocn.ne.jp [180.4.39.148]) by msgw002-02.ocn.ad.jp (Postfix) with ESMTP id 0E0231F7096; Tue, 9 Sep 2014 20:05:50 +0900 (JST) Date: Tue, 09 Sep 2014 20:05:50 +0900 (JST) Message-Id: <20140909.200550.1315917916182598029.toshi@ruby.ocn.ne.jp> To: hiroo.ono+freebsd@gmail.com From: SAITOU Toshihide In-Reply-To: References: X-GPG-fingerprint: 34B3 0B6A 8520 F5B0 EBC7 69F6 C055 9F8A 0D49 F8FC X-Mailer: Mew version 6.6 on Emacs 24.3 / Mule 6.0 (HANACHIRUSATO) Mime-Version: 1.0 Content-Type: Multipart/Mixed; boundary="--Next_Part(Tue_Sep__9_20_05_50_2014_507)--" Content-Transfer-Encoding: 7bit X-Mailman-Approved-At: Tue, 09 Sep 2014 13:33:08 +0000 Cc: freebsd-users-jp@freebsd.org Subject: [FreeBSD-users-jp 95275] Re: =?iso-2022-jp?b?GyRCRjAyaCROJS0lYyVXJUElYxsoQg==?= X-BeenThere: freebsd-users-jp@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Discussion relevant to FreeBSD communities in Japan List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Sep 2014 11:05:54 -0000 ----Next_Part(Tue_Sep__9_20_05_50_2014_507)-- Content-Type: Text/Plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit In message: Hiroo Ono (小野寛生) writes: > > FreeBSD で UVC なデバイスから動画をなんらかの形式のファイルにキャプチャすることはできるのでしょうか? libusb を使う手はどうでしょう.利点として Mac や Android で もだいたい同じようにして使えることがあげられます. 添付ファイルは UVC の Uncompressed な形式の画像を出力します. 以下コマンドに渡して再生できていたと思います. mplayer - -demuxer rawvideo -rawvideo fps=30:w=640:h=480:yuy2 少しの変更で MJPEG も取り出せ,もう少し変更すればバルク転送 のデバイスにも対応できると思います. mplayer - -demuxer lavf -lavfdopts format=mjpeg fps=60 〜 UVC カメラを実験器具として利用しようと思って(レーザポインタ をアパチャー越しにセンサーにあててエアリーディスクが観察でき ないかとか)用意したのですが放置状態でした.USB3 のカメラモ ジュールなども廉価で出ているようで一つ買ってあるのですが(バ ルク転送で BY8 出力だったものとか)やはり放置状態です.(^_^; 齊藤 ----Next_Part(Tue_Sep__9_20_05_50_2014_507)-- Content-Type: Text/Plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ex44.c" /* * Copyright (c) 2012 SAITOU Toshihide * All rights reserved. * * A sample program for LibUSB isochronous transfer using UVC cam. * * * Compiling and Running * * (Mac OS) $ cc -Wall -o ex44 ex44.c -I/opt/local/include/libusb-1.0 -L/opt/local/lib -lusb-1.0 * (FreeBSD) $ cc -Wall -o ex44 ex44.c -lusb * * $ ./ex44 * * * Reference * * [PL_UnComp] * (USB_Video_Payload_Uncompressed_1.5.pdf), * . * * [UVC1.5] Universal Serial Bus Device Class Definition for Video Devices, * (UVC 1.5 Class specification.pdf), * . * * [USB2.0] USB 2.0 Specification Universal Serial Bus Revision 2.0 specification, * (usb_20.pdf), . */ #include #include #include #include #include #include #include #include "payload.h" typedef struct uvc_device { uint16_t VID; uint16_t PID; uint8_t ConfIdx; // Configuration Index uint8_t ConfVal; // Configuration Value uint8_t IfNum; // Interface Number uint8_t AltIfNum; // Alternate Interface Number uint8_t Endpoint; // Interface 1 Alt 1 Endpoint 0 Address 0x82 uint8_t FrameIndex; // FrameIndex for 640x480 } uvc_device; uvc_device uvc_device_list[] = { { 0x0458, 0x7081, 0, 1, 1, 1, 0x82, 1 }, // BSW20K07HWH -- iBUFFALO, BSW20K07HWH { 0x056e, 0x7008, 0, 1, 1, 7, 0x82, 1 }, // UCAM-DLY300TA -- ELECOM, UCAM-DLY300TA { 0, 0, 0, 0, 0, 0, 0 } }; uvc_device uvc; #define FrameSize (640*480) #define FrameBufferSize (2*FrameSize) uint8_t padding[FrameBufferSize]; #define PKT_LEN 0xc00 #define PKTS_PER_XFER 0x40 #define NUM_TRANSFER 2 #define TIMEOUT 500 // 500 ms libusb_context *ctx = NULL; libusb_device_handle *handle; struct libusb_transfer * xfers[NUM_TRANSFER]; int fd; int total = 0; int16_t brightness; // for debug struct timeval tv1; struct timeval tv2; struct timezone tz; int totalFrame = 0; void signal_callback_handler(int signum) { uint8_t buf[2]; switch (signum) { case SIGUSR1: // BSW20K07HWH // min: 0xff81, max: 0x0080, res: 0x0001 // UCAM-DLY300TA // min: 0x000a, max: 0xfff6, res: 0x0001 // 前者は cur を段階的に設定できたが後者は 2 値のみ受け付けた. // 別のもの設定と連動しているかあるいは何れかの値がおかしい. // いずれも VC_PROCESSING_UNIT の bUnitID が 2 であり // 下記の通りこの値が固定かつ同一のコーディングとなっている. // PU_BRIGHTNESS_CONTROL(0x02), GET_MIN(0x82) [UVC1.5, p. 160, 158, 96] libusb_control_transfer(handle, 0xa1, 0x82, 0x0200, 0x0200, buf, 2, TIMEOUT); fprintf(stderr, "brightness min: %02x%02x\n", buf[1], buf[0]); // PU_BRIGHTNESS_CONTROL(0x02), GET_MAX(0x83) [UVC1.5, p. 160, 158, 96] libusb_control_transfer(handle, 0xa1, 0x83, 0x0200, 0x0200, buf, 2, TIMEOUT); fprintf(stderr, "brightness max: %02x%02x\n", buf[1], buf[0]); // PU_BRIGHTNESS_CONTROL(0x02), GET_RES(0x84) [UVC1.5, p. 160, 158, 96] libusb_control_transfer(handle, 0xa1, 0x84, 0x0200, 0x0200, buf, 2, TIMEOUT); fprintf(stderr, "brightness res: %02x%02x\n", buf[1], buf[0]); // PU_BRIGHTNESS_CONTROL(0x02), GET_CUR(0x81) [UVC1.5, p. 160, 158, 96] libusb_control_transfer(handle, 0xa1, 0x81, 0x0200, 0x0200, buf, 2, TIMEOUT); fprintf(stderr, "brightness cur: %02x%02x\n", buf[1], buf[0]); // change brightness brightness = buf[1]<<8 | buf[0]; brightness -= 30; buf[1] = brightness<<8; buf[0] = brightness & 0xff; // PU_BRIGHTNESS_CONTROL(0x02), SET_CUR(0x01) [UVC1.5, p. 160, 158, 96] libusb_control_transfer(handle, 0x21, 0x01, 0x0200, 0x0200, buf, 2, TIMEOUT); // PU_BRIGHTNESS_CONTROL(0x02), GET_CUR(0x81) [UVC1.5, p. 160, 158, 96] libusb_control_transfer(handle, 0xa1, 0x81, 0x0200, 0x0200, buf, 2, TIMEOUT); fprintf(stderr, "brightness: %02x%02x\n", buf[1], buf[0]); break; case SIGUSR2: // はパッケージにオート・ // フォーカス対応とあるが対応する機能はディスクリプタ // の VC_EXTENSION_UNIT に示されているようだ.ただしこ // のビットマップの詳細はベンダーの情報がないと分から // ない.この拡張の Entity ID は aSourceID から 1 であ // り CS には CT_FOCUS_AUTO_CONTROL を使ってみるとやは // りオート・フォーカスの機能を制御できた. // CT_FOCUS_AUTO_CONTROL(0x08), GET_CUR(0x81) [UVC1.5, p. 160, 159, 86] libusb_control_transfer(handle, 0xa1, 0x81, 0x0800, 0x0100, buf, 1, TIMEOUT); buf[0] = !buf[0]; // CT_FOCUS_AUTO_CONTROL(0x08), SET_CUR(0x01) [UVC1.5, p. 160, 159, 86] libusb_control_transfer(handle, 0x21, 0x01, 0x0800, 0x0100, buf, 1, TIMEOUT); fprintf(stderr, "auto focus control: %02x\n", buf[0]); break; case SIGINT: gettimeofday(&tv2, &tz); fprintf(stderr, "time lapse: %ld\n", ((tv2.tv_sec - tv1.tv_sec) * 1000000) + tv2.tv_usec - tv1.tv_usec); fprintf(stderr, "fps: %d\n", (1000000*totalFrame) / (int)(((tv2.tv_sec - tv1.tv_sec) * 1000000) + tv2.tv_usec - tv1.tv_usec) ); if (libusb_cancel_transfer(xfers[0])) fprintf(stderr, "cancel transfer 0 failed\n"); if (libusb_cancel_transfer(xfers[1])) fprintf(stderr, "cancel transfer 1 failed\n"); libusb_free_transfer(xfers[0]); libusb_free_transfer(xfers[1]); // このインタフェースと代替設定は存在しないので失敗するが // これにより NOT STREAMING 状態への遷移には成功する. libusb_set_interface_alt_setting(handle, 1, 0); //libusb_reset_device(handle); //libusb_close(handle); libusb_exit(ctx); close(fd); exit(signum); default: break; } } static void cb(struct libusb_transfer *xfer) { uint8_t *p; int plen; int i; p = xfer->buffer; for (i = 0; i < xfer->num_iso_packets; i++, p += PKT_LEN) { if (xfer->iso_packet_desc[i].status == LIBUSB_TRANSFER_COMPLETED) { plen = xfer->iso_packet_desc[i].actual_length; // packet only contains an acknowledge? if (plen < 2) continue; // error packet if (p[1] & UVC_STREAM_ERR) // bmHeaderInfo continue; // subtract the header size plen -= p[0]; // check the data size before write if (plen + total > FrameBufferSize) { fprintf(stderr, "truncate the excess payload length.\n"); plen = FrameBufferSize - total; } write(fd, p + p[0], plen); // update padding data memcpy(padding + total, p + p[0], plen); total += plen; // ストリームが EOF の場合の処理 if (p[1] & UVC_STREAM_EOF) { if (total < FrameBufferSize) { fprintf(stderr, "insufficient frame data.\n"); // data padding with previous frame. write(fd, padding + total - plen, FrameBufferSize - total); } total = 0; fprintf(stderr, "%d\n", ++totalFrame); } } } if (libusb_submit_transfer(xfer) != 0) { fprintf(stderr, "submit transfer failed.\n"); } } int main( int argc, char **argv) { libusb_device **devs; libusb_device *dev; struct libusb_device_descriptor desc; struct libusb_config_descriptor *confDesc; uint8_t buf[64]; int i; int j; if (argv[1] != NULL) { if ( (fd = open(argv[1], O_CREAT|O_TRUNC|O_RDWR, 0600)) < 0) { fprintf(stderr, "open file failed.\n"); exit(0); } } else { fd = open("/dev/stdout", O_WRONLY, 0); } signal(SIGINT, signal_callback_handler); signal(SIGUSR1, signal_callback_handler); signal(SIGUSR2, signal_callback_handler); // get cam device // libusb_init(&ctx); // handle = libusb_open_device_with_vid_pid(ctx, VID, PID); // dev = libusb_get_device(handle); libusb_init(NULL); libusb_get_device_list(NULL, &devs); i = 0; while ((dev = devs[i++]) != NULL) { libusb_get_device_descriptor(dev, &desc); for (j = 0; uvc_device_list[j].VID != 0; j++) { uvc = uvc_device_list[j]; if (uvc.VID == desc.idVendor && uvc.PID == desc.idProduct) goto FOUND; } } FOUND: // libusb_free_device_list(devs, 1); libusb_open(dev, &handle); // if kernel driver is active, detach a kernel driver. libusb_get_config_descriptor(dev, uvc.ConfIdx, &confDesc); // kokokokokokokkokoko const struct libusb_interface *intf; const struct libusb_interface_descriptor *intfDesc; intf = confDesc->interface; intfDesc = &intf->altsetting[0]; printf("length: %d\n", intfDesc->extra_length); printf("addr: %ld\n", (long)intfDesc); intfDesc = &intf->altsetting[1]; printf("length: %d\n", intfDesc->extra_length); printf("addr: %ld\n", (long)intfDesc); exit(1); for (i=0; ibNumInterfaces; i++) { if (libusb_kernel_driver_active(handle, i) == 1) { fprintf(stderr, "detaching kernel driver for interface %d.\n", i); if (libusb_detach_kernel_driver(handle, i) != 0) { fprintf(stderr, "detach failed.\n"); } } } libusb_free_config_descriptor(confDesc); // set the active configuration if (libusb_set_configuration(handle, uvc.ConfVal) != 0) { fprintf(stderr, "set configuration failed.\n"); } // claim an interface in a given libusb_handle. if (libusb_claim_interface(handle, 0) != 0) { fprintf(stderr, "claim interface failed.\n"); } // ------------------------------------------------------------ // negotiate the streaming parameters // Device State Transition [UVC1.5, p. 107] // Video Probe and Commit Controls [UVC1.5, p. 134] // set some parameters described to be set by the host. [UVC1.5, p. 134] buf[0] = 0x01; // what fields shall be kept fixed (0x01: dwFrameInterval) buf[1] = 0x00; // buf[2] = 0x01; // Video format index (Uncompressed) buf[3] = uvc.FrameIndex; // Video frame index buf[4] = 0x15; // Frame interval in 100ns buf[5] = 0x16; // propose: 0x00051615 (33ms) buf[6] = 0x05; // buf[7] = 0x00; // buf[8] = 0x00; // Key frame rate in key-frame per videoframe units buf[9] = 0x00; // buf[10] = 0x00; // PFrame rate in PFrame/key frame units. buf[11] = 0x00; // buf[12] = 0x00; // Compression quality control in abstract units 1 to 10000. buf[13] = 0x00; // buf[14] = 0x00; // Window size for average bit rate control. buf[15] = 0x00; // Window size for average bit rate control. buf[16] = 0x00; // Internal video streaming interface latency in ms. buf[17] = 0x00; // buf[18] = 0x00; // Maximum video frame or codec-specific segment size in bytes (ro) buf[19] = 0x00; // buf[20] = 0x00; // buf[21] = 0x00; // buf[22] = 0x00; // Specifies the maximum number of bytes (ro) buf[23] = 0x00; // buf[24] = 0x00; // buf[25] = 0x00; // // VS_PROBE_CONTROL(0x01), SET_CUR(0x01) [UVC1.5, p. 161, 158] libusb_control_transfer(handle, 0x21, 0x01, 0x0100, 0x0001, buf, 26, TIMEOUT); // VS_PROBE_CONTROL(0x01), GET_MIN(0x82) [UVC1.5, p. 161, 158] libusb_control_transfer(handle, 0xa1, 0x82, 0x0100, 0x0001, buf, 26, TIMEOUT); #if DEBUG for (i=0; i<26; i++) { fprintf(stderr, "%02x ", buf[i]); } fprintf(stderr, "\n"); #endif // VS_COMMIT_CONTROL(0x02), SET_CUR(0x01) [UVC1.5, p. 161, 158] libusb_control_transfer(handle, 0x21, 0x01, 0x0200, 0x0001, buf, 26, TIMEOUT); // ------------------------------------------------------------ // set interface, set alt interface [USB2.0, p. 250] // claim an interface in a given libusb_handle. if (libusb_claim_interface(handle, uvc.IfNum) != 0) { fprintf(stderr, "claim interface failed.\n"); } // activate an alternate setting for an interface. if (libusb_set_interface_alt_setting(handle, uvc.IfNum, uvc.AltIfNum) != 0) { fprintf(stderr, "activate an alternate setting failed.\n"); } // ------------------------------------------------------------ // BSW20K07HWH.dump_curr_config_desc.txt でみると // UCAM-DLY300TA.dump_curr_config_desc.txt でみると // // Entity ID は bUnitID として示されている. // たとえば を上記のディスクリプタの例でみると // いずれも bUnitID: 02 となっていることがわかる. // PU_GAMMA_CONTROL(0x09), GET_MIN(0x82) [UVC1.5, p. 160, 100, 96] #if 0 // EU_MIN_FRAME_INTERVAL_CONTROL(0x04), SET_CUR(0x01) [UVC1.5, p. 160, 100, 86] buf[0] = 0x2a; // Frame interval in 100ns buf[1] = 0x2c; // propose: 0x000a2c2a (66ms) buf[2] = 0x0a; // buf[3] = 0x00; // libusb_control_transfer(handle, 0x21, 0x01, 0x0400, 0x0001, buf, 4, TIMEOUT); libusb_control_transfer(handle, 0xa1, 0x81, 0x0400, 0x0001, buf, 4, TIMEOUT); fprintf(stderr, "intval cur: 0x%02x%02x%02x%02x\n", buf[3], buf[2], buf[1], buf[0]); #endif // CT_AE_PRIORITY_CONTROL(0x03), SET_CUR(0x01) [UVC1.5, p. 159, 100, 86] // libusb_control_transfer(handle, 0x21, 0x01, 0x0300, 0x0100, buf, 4, TIMEOUT); // CT_AE_MODE_CONTROL(0x02), GET_CUR(0x81) [UVC1.5, p. 159, 100, 86] libusb_control_transfer(handle, 0xa1, 0x81, 0x0200, 0x0100, buf, 1, TIMEOUT); fprintf(stderr, "CT_AE_MODE_CONTROL: 0x%02x\n", buf[0]); // CT_AE_PRIORITY_CONTROL(0x03), GET_CUR(0x81) [UVC1.5, p. 159, 100, 86] libusb_control_transfer(handle, 0xa1, 0x81, 0x0300, 0x0100, buf, 1, TIMEOUT); fprintf(stderr, "CT_AE_PRIORITY_CONTROL: 0x%02x\n", buf[0]); // CT_AE_EXPOSURE_TIME_ABSOLUTE_CONTROL(0x04), GET_CUR(0x81) [UVC1.5, p. 159, 100, 86] libusb_control_transfer(handle, 0xa1, 0x81, 0x0400, 0x0100, buf, 4, TIMEOUT); fprintf(stderr, "CT_AE_EXPOSURE_TIME_ABSOLUTE_CONTROL(cur): 0x%02x%02x%02x%02x\n", buf[3], buf[2], buf[1], buf[0]); // CT_AE_EXPOSURE_TIME_ABSOLUTE_CONTROL(0x04), GET_MIN(0x82) [UVC1.5, p. 159, 100, 86] libusb_control_transfer(handle, 0xa1, 0x82, 0x0400, 0x0100, buf, 4, TIMEOUT); fprintf(stderr, "CT_AE_EXPOSURE_TIME_ABSOLUTE_CONTROL(min): 0x%02x%02x%02x%02x\n", buf[3], buf[2], buf[1], buf[0]); // CT_AE_EXPOSURE_TIME_ABSOLUTE_CONTROL(0x04), GET_MAX(0x83) [UVC1.5, p. 159, 100, 86] libusb_control_transfer(handle, 0xa1, 0x83, 0x0400, 0x0100, buf, 4, TIMEOUT); fprintf(stderr, "CT_AE_EXPOSURE_TIME_ABSOLUTE_CONTROL(max): 0x%02x%02x%02x%02x\n", buf[3], buf[2], buf[1], buf[0]); // CT_AE_EXPOSURE_TIME_ABSOLUTE_CONTROL(0x04), GET_MAX(0x84) [UVC1.5, p. 159, 100, 86] libusb_control_transfer(handle, 0xa1, 0x84, 0x0400, 0x0100, buf, 4, TIMEOUT); fprintf(stderr, "CT_AE_EXPOSURE_TIME_ABSOLUTE_CONTROL(res): 0x%02x%02x%02x%02x\n", buf[3], buf[2], buf[1], buf[0]); // CT_AE_EXPOSURE_TIME_RELATIVE_CONTROL(0x05), GET_CUR(0x81) [UVC1.5, p. 159, 100, 86] libusb_control_transfer(handle, 0xa1, 0x81, 0x0500, 0x0100, buf, 1, TIMEOUT); fprintf(stderr, "CT_AE_EXPOSURE_TIME_RELATIVE_CONTROL(cur): 0x%02x\n", buf[0]); // CT_AE_EXPOSURE_TIME_RELATIVE_CONTROL(0x05), GET_MIN(0x82) [UVC1.5, p. 159, 100, 86] libusb_control_transfer(handle, 0xa1, 0x82, 0x0500, 0x0100, buf, 1, TIMEOUT); fprintf(stderr, "CT_AE_EXPOSURE_TIME_RELATIVE_CONTROL(min): 0x%02x\n", buf[0]); // CT_AE_EXPOSURE_TIME_RELATIVE_CONTROL(0x05), GET_MAX(0x83) [UVC1.5, p. 159, 100, 86] libusb_control_transfer(handle, 0xa1, 0x83, 0x0500, 0x0100, buf, 1, TIMEOUT); fprintf(stderr, "CT_AE_EXPOSURE_TIME_RELATIVE_CONTROL(max): 0x%02x\n", buf[0]); // CT_AE_EXPOSURE_TIME_RELATIVE_CONTROL(0x05), GET_RES(0x84) [UVC1.5, p. 159, 100, 86] libusb_control_transfer(handle, 0xa1, 0x84, 0x0500, 0x0100, buf, 1, TIMEOUT); fprintf(stderr, "CT_AE_EXPOSURE_TIME_RELATIVE_CONTROL(res): 0x%02x\n", buf[0]); #if 1 buf[0] = 0x08; // 0x01 / 0x08 // CT_AE_MODE_CONTROL(0x02), SET_CUR(0x01) [UVC1.5, p. 159, 100, 86] libusb_control_transfer(handle, 0x21, 0x01, 0x0200, 0x0100, buf, 1, TIMEOUT); buf[0] = 0x00; // CT_AE_PRIORITY_CONTROL(0x03), SET_CUR(0x01) [UVC1.5, p. 159, 100, 86] libusb_control_transfer(handle, 0x21, 0x01, 0x0300, 0x0100, buf, 1, TIMEOUT); buf[0] = 0x08; buf[1] = 0x00; buf[2] = 0x00; buf[3] = 0x00; // CT_AE_EXPOSURE_TIME_ABSOLUTE_CONTROL(0x04), SET_CUR(0x01) [UVC1.5, p. 159, 100, 86] libusb_control_transfer(handle, 0x21, 0x01, 0x0400, 0x0100, buf, 4, TIMEOUT); buf[0] = 0x01; // CT_AE_EXPOSURE_TIME_RELATIVE_CONTROL(0x05), SET_CUR(0x01) [UVC1.5, p. 159, 100, 86] libusb_control_transfer(handle, 0x21, 0x01, 0x0500, 0x0100, buf, 1, TIMEOUT); // CT_AE_MODE_CONTROL(0x02), GET_CUR(0x81) [UVC1.5, p. 159, 100, 86] libusb_control_transfer(handle, 0xa1, 0x81, 0x0200, 0x0100, buf, 1, TIMEOUT); fprintf(stderr, "CT_AE_MODE_CONTROL: 0x%02x\n", buf[0]); // CT_AE_EXPOSURE_TIME_ABSOLUTE_CONTROL では範囲を越える値を設 // 定するときちんと再設定しないと正しい表示とならない. // AE をマニュアルに設定するとオートの時の明るさを再現できない // のはなぜか? #endif // ------------------------------------------------------------ // do an isochronous transfer for (i=0; i Delivered-To: freebsd-users-jp@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 8A0EF89D for ; Tue, 9 Sep 2014 13:39:56 +0000 (UTC) Received: from msgw002-02.ocn.ad.jp (msgw002-02.ocn.ad.jp [180.37.203.77]) by mx1.freebsd.org (Postfix) with ESMTP id EB797C16 for ; Tue, 9 Sep 2014 13:39:55 +0000 (UTC) Received: from localhost (p8148-ipngn100303sizuokaden.shizuoka.ocn.ne.jp [180.4.39.148]) by msgw002-02.ocn.ad.jp (Postfix) with ESMTP id 433001F7096; Tue, 9 Sep 2014 22:39:54 +0900 (JST) Date: Tue, 09 Sep 2014 22:39:52 +0900 (JST) Message-Id: <20140909.223952.345652369461779432.toshi@ruby.ocn.ne.jp> To: hiroo.ono+freebsd@gmail.com From: SAITOU Toshihide In-Reply-To: <20140909.200550.1315917916182598029.toshi@ruby.ocn.ne.jp> References: <20140909.200550.1315917916182598029.toshi@ruby.ocn.ne.jp> X-GPG-fingerprint: 34B3 0B6A 8520 F5B0 EBC7 69F6 C055 9F8A 0D49 F8FC X-Mailer: Mew version 6.6 on Emacs 24.3 / Mule 6.0 (HANACHIRUSATO) Mime-Version: 1.0 Content-Type: Multipart/Mixed; boundary="--Next_Part(Tue_Sep__9_22_39_52_2014_517)--" Content-Transfer-Encoding: 7bit X-Mailman-Approved-At: Tue, 09 Sep 2014 13:43:58 +0000 Cc: freebsd-users-jp@freebsd.org Subject: [FreeBSD-users-jp 95276] Re: =?iso-2022-jp?b?GyRCRjAyaCROJS0lYyVXJUElYxsoQg==?= X-BeenThere: freebsd-users-jp@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Discussion relevant to FreeBSD communities in Japan List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Sep 2014 13:39:56 -0000 ----Next_Part(Tue_Sep__9_22_39_52_2014_517)-- Content-Type: Text/Plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit In message: <20140909.200550.1315917916182598029.toshi@ruby.ocn.ne.jp> SAITOU Toshihide writes: > > 添付ファイルは UVC の Uncompressed な形式の画像を出力します. > 以下コマンドに渡して再生できていたと思います. すみません.添付ファイルの差し替えと不足のファイルを添付しま した.Mac と 6 月ころの FreeBSD 11.0-Current で試して動いて るみたいいです. 齊藤 ----Next_Part(Tue_Sep__9_22_39_52_2014_517)-- Content-Type: Text/Plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ex41.c" /* * Copyright (c) 2012-2014 SAITOU Toshihide * All rights reserved. * * A sample program for LibUSB isochronous transfer using UVC cam. * * * Compiling and Running * * (Mac OS) * * $ cc -Wall -I/opt/local/include/libusb-1.0 -L/opt/local/lib -lusb-1.0 * -o ex41 ex41.c * * (FreeBSD) * * $ cc -Wall -lusb -o ex41 ex41.c * * (Run) * * $ ./ex41 bFrameIndex [file] * $ ./ex41 1 | mplayer - -demuxer rawvideo -rawvideo w=640:h=480:yuy2 * $ ./ex41 1 | ffmpeg -f rawvideo -s 1280x720 -i - tmp.avi * * show all frame indexes and sizes. * * $ ./ex41 0 * * Reference * * [PL_UnComp] * * (USB_Video_Payload_Uncompressed_1.5.pdf), * . * * [UVC1.5] * * Universal Serial Bus Device Class Definition for Video Devices, (UVC 1.5 * Class specification.pdf), . * * [USB2.0] * * USB 2.0 Specification Universal Serial Bus Revision 2.0 specification, * (usb_20.pdf), . */ #include #include #include #include #include #include #include #include "payload.h" typedef struct uvc_device { uint16_t VID; uint16_t PID; uint8_t ConfIdx; /* configuration index */ uint8_t ConfVal; /* configuration value */ uint8_t IfNum; /* interface number */ uint8_t AltSetting; /* alternate setting of the interface */ uint8_t Endpoint; /* endpoint */ uint8_t FrameIndex; /* FrameIndex for 640x480 */ uint16_t PuId; /* VC_PROCESSING_UNIT, bUnitID<<8 */ uint16_t TermId; /* VC_INPUT_TERMINAL, bTerminalID<<8 */ } uvc_device; uvc_device uvc_device_list[] = { /* Isochronous */ /* MSK-1425: Microsoft, Microsoft LifeCam StudioTM */ { 0x045e, 0x0772, 0, 1, 1, 0, 0x81, 2, 0x0400, 0x0100 }, /* BSW20K07HWH: iBUFFALO, BSW20K07HWH */ { 0x0458, 0x7081, 0, 1, 1, 0, 0x82, 7, 0x0200, 0x0100 }, /* UCAM-DLY300TA: Etron Technology, Inc., UCAM-DLY300TA */ { 0x056e, 0x7008, 0, 1, 1, 0, 0x82, 1, 0x0200, 0x0100 }, /* C920: Logitech Inc., LOGICOOL HD Webcam C920 */ { 0x046d, 0x082d, 0, 1, 1, 10, 0x81, 1, 0x0300, 0x0100 }, /* UCAM-MS130: Etron Technology, Inc., UCAM-MS130SV */ { 0x056e, 0x7012, 0, 1, 1, 0, 0x81, 2, 0x0300, 0x0100 }, /* KBCR-S01MU */ { 0x05ca, 0x18d0, 0, 1, 1, 0, 0x82, 1, 0x0200, 0x0400 }, /* Bulk */ /* ESCH021: e-con System Pvt. Ltd., See3CAM_10CUG_CH */ { 0x2560, 0xc111, 0, 1, 1, 0, 0x83, 1, 0x0200, 0x0100 }, /* ESMH156: e-con System Pvt. Ltd., See3CAM_10CUG_MH */ { 0x2560, 0xc110, 0, 1, 1, 0, 0x83, 1, 0x0200, 0x0100 }, { 0, 0, 0, 0, 0, 0, 0 } }; uvc_device uvc; int width; int height; int XferType; /* isochronous / bulk */ int BitPerPixel; /* 8: 1 byte/pixel, 16: 2 byte/pxel */ int FrameSize; int FrameBufferSize; /* FrameSize * BitPerPixel */ uint8_t *padding; /* padding data */ uint32_t PKT_LEN; /* dwMaxPayloadTransferSize 0xc00, 0xa80,... */ #define PKTS_PER_XFER 0x40 #define NUM_TRANSFER 2 #define TIMEOUT 500 /* 500 ms */ libusb_context *ctx = NULL; libusb_device_handle *handle; struct libusb_transfer * xfers[NUM_TRANSFER]; int fd; int total = 0; int16_t brightness; /* for debug */ struct timeval tv1; struct timeval tv2; struct timezone tz; int totalFrame = 0; /* boolean */ #define TRUE 1 #define FALSE 0 void signal_callback_handler(int signum) { uint8_t buf[2]; int i; switch (signum) { case SIGUSR1: /* * BSW20K07HWH * min: 0xff81, max: 0x0080, res: 0x0001 * UCAM-DLY300TA * min: 0x000a, max: 0xfff6, res: 0x0001 * 前者は cur を段階的に設定できたが後者は 2 値のみ受け付けた. * 別の設定と連動しているかあるいは何れかの値がおかしい. * * いずれも VC_PROCESSING_UNIT の bUnitID が 2 であり * 下記の通りこの値が固定かつ同一のコーディングとなっている. */ /* * PU_BRIGHTNESS_CONTROL(0x02), GET_MIN(0x82) [UVC1.5, p. 160, * 158, 96] */ libusb_control_transfer( handle, 0xa1, 0x82, 0x0200, uvc.PuId, buf, 2, TIMEOUT); fprintf(stderr, "brightness min: %02x%02x\n", buf[1], buf[0]); /* * PU_BRIGHTNESS_CONTROL(0x02), GET_MAX(0x83) [UVC1.5, p. 160, * 158, 96] */ libusb_control_transfer( handle, 0xa1, 0x83, 0x0200, uvc.PuId, buf, 2, TIMEOUT); fprintf(stderr, "brightness max: %02x%02x\n", buf[1], buf[0]); /* * PU_BRIGHTNESS_CONTROL(0x02), GET_RES(0x84) [UVC1.5, p. 160, * 158, 96] */ libusb_control_transfer( handle, 0xa1, 0x84, 0x0200, uvc.PuId, buf, 2, TIMEOUT); fprintf(stderr, "brightness res: %02x%02x\n", buf[1], buf[0]); /* * PU_BRIGHTNESS_CONTROL(0x02), GET_CUR(0x81) [UVC1.5, p. 160, * 158, 96] */ libusb_control_transfer( handle, 0xa1, 0x81, 0x0200, uvc.PuId, buf, 2, TIMEOUT); fprintf(stderr, "brightness cur: %02x%02x\n", buf[1], buf[0]); /* change brightness */ brightness = buf[1]<<8 | buf[0]; // brightness += 30; brightness += 1; buf[1] = brightness<<8; buf[0] = brightness & 0xff; /* * PU_BRIGHTNESS_CONTROL(0x02), SET_CUR(0x01) [UVC1.5, p. 160, * 158, 96] */ libusb_control_transfer( handle, 0x21, 0x01, 0x0200, uvc.PuId, buf, 2, TIMEOUT); /* * PU_BRIGHTNESS_CONTROL(0x02), GET_CUR(0x81) [UVC1.5, p. 160, * 158, 96] */ libusb_control_transfer( handle, 0xa1, 0x81, 0x0200, uvc.PuId, buf, 2, TIMEOUT); fprintf(stderr, "brightness: %02x%02x\n", buf[1], buf[0]); /* * こんだけコマンドを一度に送信するとデータが乱れる. */ break; case SIGUSR2: /* * では,パッケージにオート・フォー * カス対応とあり CT_FOCUS_AUTO_CONTROL で機能を制御できた. */ /* * CT_FOCUS_AUTO_CONTROL(0x08), GET_CUR(0x81) [UVC1.5, p. 160, * 159, 86] */ libusb_control_transfer( handle, 0xa1, 0x81, 0x0800, uvc.TermId, buf, 1, TIMEOUT); buf[0] = !buf[0]; /* * CT_FOCUS_AUTO_CONTROL(0x08), SET_CUR(0x01) [UVC1.5, p. 160, * 159, 86] */ libusb_control_transfer( handle, 0x21, 0x01, 0x0800, uvc.TermId, buf, 1, TIMEOUT); fprintf(stderr, "auto focus control: %02x\n", buf[0]); break; case SIGINT: case SIGPIPE: gettimeofday(&tv2, &tz); fprintf(stderr, "time lapse: %ld\n", ((tv2.tv_sec - tv1.tv_sec) * 1000000) + tv2.tv_usec - tv1.tv_usec); fprintf(stderr, "fps: %d\n", (int) ((1000000*totalFrame) / (long)(((tv2.tv_sec - tv1.tv_sec) * 1000000) + tv2.tv_usec - tv1.tv_usec)) ); for (i=0; ibuffer; for (i = 0; i < xfer->num_iso_packets; i++, p += PKT_LEN) { if (xfer->iso_packet_desc[i].status != LIBUSB_TRANSFER_COMPLETED) continue; plen = xfer->iso_packet_desc[i].actual_length; /* packet only contains an acknowledge? */ if (plen < 2) continue; /* error packet */ if (p[1] & UVC_STREAM_ERR) /* bmHeaderInfo */ continue; /* subtract the header size */ plen -= p[0]; /* check the data size before write */ if (plen + total > FrameBufferSize) { #if DEBUG fprintf(stderr, "truncate the excess payload length.\n"); #endif plen = FrameBufferSize - total; } write(fd, p + p[0], plen); /* update padding data */ memcpy(padding + total, p + p[0], plen); total += plen; /* this is the EOF data. */ if (p[1] & UVC_STREAM_EOF) { fprintf(stderr, "%d\n", total); if (total < FrameBufferSize) { /* * insufficient frame data, so pad with the * previous frame data. */ write(fd, padding + total, FrameBufferSize - total); fprintf(stderr, "insufficient frame data.\n"); } total = 0; fprintf(stderr, "%d\n", ++totalFrame); } } /* re-submit a transfer before returning. */ if (libusb_submit_transfer(xfer) != 0) { fprintf(stderr, "submit transfer failed.\n"); } } int main( int argc, char **argv) { libusb_device **devs; libusb_device *dev; const struct libusb_interface *intf; struct libusb_device_descriptor desc; struct libusb_config_descriptor *confDesc; struct libusb_interface_descriptor *intfDesc; struct libusb_endpoint_descriptor *ep; int frameIndex; uint8_t *buf = (void *)malloc(1024); int i; int j; int k; int foundIt; int maxPktSize; int altSetting; /* * handle the command argument. */ if (argc < 2 || argc > 3) { fprintf(stderr, "Usage: ex41 bFrameIndex [file]\n"); exit(1); } frameIndex = strtol( argv[1], NULL, 0 ); if (argv[2] != NULL) { if ( (fd = open(argv[2], O_CREAT|O_TRUNC|O_RDWR, 0600)) < 0) { fprintf(stderr, "open file failed.\n"); exit(0); } } else fd = open("/dev/stdout", O_WRONLY, 0); /* * regsiter the signal callback. */ signal(SIGINT, signal_callback_handler); signal(SIGPIPE, signal_callback_handler); signal(SIGUSR1, signal_callback_handler); signal(SIGUSR2, signal_callback_handler); /* * get cam device. */ libusb_init(&ctx); #if DEBUG libusb_set_debug(ctx, 1); #endif libusb_get_device_list(ctx, &devs); foundIt = FALSE; i = 0; while ((dev = devs[i++]) != NULL) { libusb_get_device_descriptor(dev, &desc); for (j = 0; uvc_device_list[j].VID != 0; j++) { uvc = uvc_device_list[j]; if (uvc.VID == desc.idVendor && uvc.PID == desc.idProduct) { foundIt = TRUE; goto FOUND; } } } FOUND: if (!foundIt) { fprintf(stderr, "device not found.\n"); exit(1); } libusb_open(dev, &handle); libusb_free_device_list(devs, 1); /* * if the kernel driver is active, detach it. */ libusb_get_config_descriptor(dev, uvc.ConfIdx, &confDesc); for (i=0; ibNumInterfaces; i++) { if (libusb_kernel_driver_active(handle, i) == 1) { fprintf(stderr, "detaching kernel driver for interface %d.\n", i); if (libusb_detach_kernel_driver(handle, i) != 0) { fprintf(stderr, "detach failed.\n"); } } } /* * search user-specified bFrameIndex which usually located at interface 1. */ foundIt = FALSE; for (i = 1; i < confDesc->bNumInterfaces; i++) /* seek interfaces */ { intf = (void *) &confDesc->interface[i]; intfDesc = (void *) &intf->altsetting[0]; /* interface i alt 0 */ /* CC_VIDEO && SC_VIDEOSTREAMING */ if (intfDesc->bInterfaceClass == 0x0e && intfDesc->bInterfaceSubClass == 0x02) { uvc.IfNum = i; buf = (void *) intfDesc->extra; foundIt = TRUE; break; } } if (!foundIt) { fprintf(stderr, "no SC_VIDEOSTREAMING.\n"); exit(1); } for (i = 0; i < intfDesc->extra_length;) { /* CS_INTERFACE && VS_FRAME_UNCOMPRESSED */ if (buf[i+1] == 0x24 && buf[i+2] == 0x05) { width = (buf[i+6]<<8) | buf[i+5]; height = (buf[i+8]<<8) | buf[i+7]; fprintf(stderr, "%d: %dx%d\n", buf[i+3], width, height); if (buf[i+3] == frameIndex) { foundIt = TRUE; break; } } i += buf[i+0]; } if (!foundIt) { fprintf(stderr, "Can't find the frame index.\n"); exit(1); } /* * search VS_FORMAT_UNCOMPRESSED and see what bBitsPerPixel is. */ foundIt = FALSE; for (i = 0; i < intfDesc->extra_length;) { /* CS_INTERFACE && VS_FORMAT_UNCOMPRESSED */ if (buf[i+1] == 0x24 && buf[i+2] == 0x04) { BitPerPixel = buf[i+11]; foundIt = TRUE; break; } i += buf[i+0]; } if (!foundIt) { fprintf(stderr, "no VS_FORMAT_UNCOMPRESSED.\n"); exit(1); } /* * search payload transfer endpoint. */ foundIt = FALSE; maxPktSize = 0; altSetting = 0; for (i = 1; i < confDesc->bNumInterfaces; i++) /* seek interfaces */ { intf = (void *) &confDesc->interface[i]; for (j = 0; j < intf->num_altsetting; j++) /* seek alt settings */ { intfDesc = (void *) &intf->altsetting[j]; /* CC_VIDEO && SC_VIDEOSTREAMING */ if (intfDesc->bInterfaceClass == 0x0e && intfDesc->bInterfaceSubClass == 0x02 && intfDesc->bNumEndpoints != 0) { for (k = 0; k < intfDesc->bNumEndpoints; k++) { ep = (void *) &intfDesc->endpoint[k]; if (ep->wMaxPacketSize > maxPktSize) { maxPktSize = ep->wMaxPacketSize; altSetting = j; foundIt = TRUE; } } } } } if (!foundIt) { fprintf(stderr, "Can't find the appropriate endpoint.\n"); exit(1); } if (uvc.AltSetting == 0) uvc.AltSetting = altSetting; if (ep->bmAttributes == 0x05) /* isochronous ? */ XferType = LIBUSB_TRANSFER_TYPE_ISOCHRONOUS; else XferType = LIBUSB_TRANSFER_TYPE_BULK; fprintf(stderr, "XferType: %x\n", XferType); uvc.FrameIndex = frameIndex; FrameSize = width * height; if (BitPerPixel == 16) FrameBufferSize = 2*FrameSize; else if (BitPerPixel == 8) FrameBufferSize = 1*FrameSize; padding = (void *) malloc(FrameBufferSize); libusb_free_config_descriptor(confDesc); /* set the active configuration */ if (libusb_set_configuration(handle, uvc.ConfVal) != 0) fprintf(stderr, "set configuration failed.\n"); /* claim an interface in a given libusb_handle. */ if (libusb_claim_interface(handle, 0) != 0) fprintf(stderr, "claim interface failed.\n"); /* * negotiate the streaming parameters * * Device State Transition [UVC1.5, p. 107] * Video Probe and Commit Controls [UVC1.5, p. 134] * * [0] what fields shall be kept fixed * [1] * [2] Video format index (Uncompressed) * [3] Video frame index * [4] Frame interval in 100ns * [5] * [6] * [7] * [8] Key frame rate in key-frame per videoframe units * [9] * [10] PFrame rate in PFrame/key frame units. * [11] * [12] Compression quality control in abstract units 1 to 10000. * [13] * [14] Window size for average bit rate control. * [15] * [16] Internal video streaming interface latency in ms. * [17] * [18] Max. video frame or codec-specific segment size in bytes (ro) * [19] (dwMaxVideoFrameSize) * [20] * [21] * [22] Specifies the maximum number of bytes (ro) * [23] (dwMaxPayloadTransferSize) * [24] * [25] */ buf[0] = 0x01; buf[1] = 0x00; buf[2] = 0x01; buf[3] = uvc.FrameIndex; buf[4] = 0x15; /* propose: 0x00051615 (33ms) */ buf[5] = 0x16; buf[6] = 0x05; buf[7] = 0x00; buf[8] = 0x00; buf[9] = 0x00; buf[10] = 0x00; buf[11] = 0x00; buf[12] = 0x00; buf[13] = 0x00; buf[14] = 0x00; buf[15] = 0x00; buf[16] = 0x00; buf[17] = 0x00; buf[18] = 0x00; buf[19] = 0x00; buf[20] = 0x00; buf[21] = 0x00; buf[22] = 0x00; buf[23] = 0x00; buf[24] = 0x00; buf[25] = 0x00; /* VS_PROBE_CONTROL(0x01), SET_CUR(0x01) [UVC1.5, p. 161, 158] */ libusb_control_transfer( handle, 0x21, 0x01, 0x0100, 0x0001, buf, 26, TIMEOUT); /* VS_PROBE_CONTROL(0x01), GET_MIN(0x82) [UVC1.5, p. 161, 158] */ libusb_control_transfer( handle, 0xa1, 0x82, 0x0100, 0x0001, buf, 26, TIMEOUT); /* VS_COMMIT_CONTROL(0x02), SET_CUR(0x01) [UVC1.5, p. 161, 158] */ libusb_control_transfer( handle, 0x21, 0x01, 0x0200, 0x0001, buf, 26, TIMEOUT); #if DEBUG for (i = 0; i < 26; i++) fprintf(stderr, "%02x ", buf[i]); fprintf(stderr, "\n"); #endif /* PKT_LEN */ PKT_LEN = (buf[25]<<24 | buf[24]<<16 | buf[23]<<8 | buf[22]); fprintf(stderr, "dwMaxPayloadTransferSize: %08x\n", PKT_LEN); /* * set interface, set alt interface [USB2.0, p. 250] */ /* claim an interface in a given libusb_handle. */ if (libusb_claim_interface(handle, uvc.IfNum) != 0) fprintf(stderr, "claim interface failed.\n"); /* activate an alternate setting for an interface. */ if (uvc.AltSetting != 0) if (libusb_set_interface_alt_setting( handle, uvc.IfNum, uvc.AltSetting) != 0) fprintf(stderr, "activate an alternate setting failed.\n"); /* * do an isochronous / bulk transfer */ for (i=0; i Delivered-To: freebsd-users-jp@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 316BD488 for ; Tue, 9 Sep 2014 23:30:37 +0000 (UTC) Received: from mail-qc0-x233.google.com (mail-qc0-x233.google.com [IPv6:2607:f8b0:400d:c01::233]) (using TLSv1 with cipher ECDHE-RSA-RC4-SHA (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id E0A059BD for ; Tue, 9 Sep 2014 23:30:36 +0000 (UTC) Received: by mail-qc0-f179.google.com with SMTP id o8so2240011qcw.38 for ; Tue, 09 Sep 2014 16:30:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:reply-to:sender:in-reply-to:references:date:message-id :subject:from:to:content-type:content-transfer-encoding; bh=xdfOsGafKJ1V650fKTf5bNiwTdHMMfn6aFDNw82/IGE=; b=GN8COeUT7u+G6wPVq3TofwFzCWYgsDnW1k2dkvu0E062bCQamvvni95ko5VWANA7V2 nMfpzYHJyVRGtHT8UNoWQ6D6ybzcNJVEPs55r9OVyTyWUzODEnZbWY5ojDpbAXKtg5I9 G7T1dxBeYMuiU2tBJtotHnqUnZQvO+ccR9bFhdijAwaMANxpJ+FfF0nnE5ONvrwOfhSA z0S58DzSj4H1ubAPDg/9f2NmTOl3+GgOcTZHUziEYEGKF1ZTX4q4VTFPbDI4lMU+qeC5 3GBplh34JTmoFCu8T5Ag/n/gb0JJfiPw2wTug6G/fjbg3tEkkfiwYbxJQF5XoI7PoHE5 axSw== MIME-Version: 1.0 X-Received: by 10.224.128.9 with SMTP id i9mr56395062qas.50.1410305435894; Tue, 09 Sep 2014 16:30:35 -0700 (PDT) Reply-To: hiroo.ono+freebsd@gmail.com Sender: hiroo.ono@gmail.com Received: by 10.140.19.9 with HTTP; Tue, 9 Sep 2014 16:30:35 -0700 (PDT) In-Reply-To: References: Date: Wed, 10 Sep 2014 08:30:35 +0900 X-Google-Sender-Auth: RAAvKGPOqgfZJT82Y54xI4TXVGU Message-ID: From: =?UTF-8?B?SGlyb28gT25vICjlsI/ph47lr5vnlJ8p?= To: freebsd-users-jp@freebsd.org Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: base64 Subject: [FreeBSD-users-jp 95277] Re: =?utf-8?b?5YuV55S744Gu44Kt44Oj44OX44OB44Oj?= X-BeenThere: freebsd-users-jp@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Discussion relevant to FreeBSD communities in Japan List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Sep 2014 23:30:37 -0000 44GT44Gs44G+5qeY44CB6b2K6Jek5qeYDQoNCuOBguOCiuOBjOOBqOOBhuOBlOOBluOBhOOBvuOB meOAgg0KDQoyMDE05bm0OeaciDnml6UgMTk6NDQgTWFzYWtpIEtvbnVtYSA8a29udW1hLm1hc2Fr aUBnbWFpbC5jb20+Og0KPiDjgZPjgazjgb7jgafjgZnjgIINCj4NCj4gMjAxNC0wOS0wOSAxMzoy NCBHTVQrMDk6MDAgSGlyb28gT25vICjlsI/ph47lr5vnlJ8pIDxoaXJvby5vbm8rZnJlZWJzZEBn bWFpbC5jb20+Og0KPj4g5bCP6YeO5a+b55Sf44Gn44GZ44CCDQo+Pg0KPj4gRnJlZUJTRCDjgacg VVZDIOOBquODh+ODkOOCpOOCueOBi+OCieWLleeUu+OCkuOBquOCk+OCieOBi+OBruW9ouW8j+OB ruODleOCoeOCpOODq+OBq+OCreODo+ODl+ODgeODo+OBmeOCi+OBk+OBqOOBr+OBp+OBjeOCi+OB ruOBp+OBl+OCh+OBhuOBiz8NCj4NCj4gbWVuY29kZXIg44GnIG1wZWc0IOOBq+WkieaPm+OBl+OB puOBhOOBvuOBmeOAgg0KPg0KPiDjgbvjgajjgpPjganjgIENCj4gICBodHRwOi8vd3d3Lm1lbGVu Lm9yZy91L2phbi93cC8/cD00Nw0KPiDjga7jgb7jgb7jgafjgZnjgIINCg0K44G+44Ga44Gv44GT 44Gh44KJ44KS6Kmm44GX44Gm44G/44KI44GG44Go5oCd44GE44G+44GZ44CCDQo=