Date: Wed, 14 Nov 2012 00:23:06 +0900 (JST) From: SAITOU Toshihide <toshi@ruby.ocn.ne.jp> To: hselasky@c2i.net Cc: freebsd-usb@freebsd.org Subject: Re: isochronous transfer packet is out of sequence Message-ID: <20121114.002306.36926536.toshi@ruby.ocn.ne.jp> In-Reply-To: <201211131452.16508.hselasky@c2i.net> References: <201211121342.47141.hselasky@c2i.net> <20121113.222652.71084426.toshi@ruby.ocn.ne.jp> <201211131452.16508.hselasky@c2i.net>
next in thread | previous in thread | raw e-mail | index | archive | help
In message: <201211131452.16508.hselasky@c2i.net> Hans Petter Selasky <hselasky@c2i.net> writes: > On Tuesday 13 November 2012 14:26:52 SAITOU Toshihide wrote: >> In message: <201211121342.47141.hselasky@c2i.net> >> >> Hans Petter Selasky <hselasky@c2i.net> writes: >> > On Monday 12 November 2012 12:52:08 SAITOU Toshihide wrote: >> >> I have tryed the USB isochronous transfer for UVC cam using libusb >> >> interface and I find the packet fragment is out of sequence on the >> >> FreeBSD(1). But I don't find it on the MacBook(2). >> >> >> >> (1) FreeBSD 9.1-RC2, Intel Core i7 3770T >> >> (2) Mac OS X 10.6.8, Intel Core 2 Duo, libusb 1.0.9 (single core) >> >> >> >> Can I prevent this behaviour using libusb interface or is >> >> this an expected behaviour? >> >> >> >> The bellow I issued two libusb_submit_transfer at the beginning. >> >> >> >> >> >> ----- log (1) >> >> 049 4437e06b 0 c 818 >> >> 04a 4437e06b 0 c c00 >> >> 04b 4437e06b 0 c 818 >> >> UVC_STREAM_EOF >> >> total a1400 >> >> 04c 4402516b 1 c b9c >> >> 04d 4402516b 1 c 87c >> >> 04e 4402516b 1 c 800 >> >> 04f 4402516b 1 c c00 >> >> 050 4402516b 1 c 800 >> >> 051 4437e06b 0 c c00 >> >> 052 4437e06b 0 c 744 >> >> 053 4437e06b 0 c c00 >> >> >> >> >> >> ----- callback function >> >> 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; >> >> >> >> if (plen < 2) >> >> >> >> continue; >> >> >> >> if (p[1] & UVC_STREAM_ERR) // bmHeaderInfo >> >> >> >> continue; >> >> >> >> fprintf(stderr, "%03x ", i); >> >> fprintf(stderr, "%08x ", p[2] | p[3]<<8 | >> >> p[4]<<16 >> >> | >> >> | p[5]<<24); // pts fprintf(stderr, "%01x ", p[1] & UVC_STREAM_FID); // >> >> >> >> fid fprintf(stderr, "%01x ", p[0]); // header length fprintf(stderr, >> >> "%x\n", plen); // actual length >> >> >> >> total += plen - p[0]; >> >> >> >> if (p[1] & UVC_STREAM_EOF) >> >> { >> >> >> >> fprintf(stderr, "UVC_STREAM_EOF\n", total); >> >> fprintf(stderr, "total %x\n", total); >> >> >> >> if (total < FrameSize) >> >> { >> >> >> >> fprintf(stderr, "insufficient frame data.\n"); >> >> write(fd, padding, FrameSize - total); // zero padding >> >> >> >> } >> >> >> >> total = 0; >> >> >> >> } >> >> >> >> write(fd, p + p[0], plen - p[0]); // write payload data >> >> >> >> } >> >> >> >> } >> >> >> >> if (libusb_submit_transfer(xfer) != 0) >> >> { >> >> >> >> fprintf(stderr, "submit transfer failed.\n"); >> >> >> >> } >> >> >> >> } >> > >> > Hi, >> > >> > You need to submit two transfers for continued operation. >> >> I may have a misunderstanding but I submit two transfers at start and >> it is resubmited in the callback function, then I see the packet group >> in the wrong place. It seems that the callback function was excuted >> exclusively so the iso packets in the data buffer were out of order, >> just like the packet does not correctly assign to the two transfers. >> >> I can get the video on the MacBook(2). I confirmed using mplayer. > > Hi, > > Some more checkpoints: > > What is the number of ISO-FRAMEs you are submitting? You should not submit too > few and not too many. And the number of frames should be divisible by 8. Reducing the number of PKTS_PER_XFER make effect! from 0x80 to 0x20, packet sequence is normal but sometimes drop the data yet. I also concern about pwcview + webcamd may be using 0x80 for PKTS_PER_XFER without problem. #define PKT_LEN 0xc00 #define PKTS_PER_XFER 0x80 #define NUM_TRANSFER 2 struct libusb_transfer * xfers[NUM_TRANSFER]; for (i=0; i<NUM_TRANSFER; i++) { xfers[i] = libusb_alloc_transfer(PKTS_PER_XFER); uint8_t *data = malloc(PKT_LEN*PKTS_PER_XFER); libusb_fill_iso_transfer( xfers[i], handle, Endpoint, data, PKT_LEN*PKTS_PER_XFER, PKTS_PER_XFER, cb, NULL, 0); libusb_set_iso_packet_lengths(xfers[i], PKT_LEN); } for (i=0; i<NUM_TRANSFER; i++) { if (libusb_submit_transfer(xfers[i]) != 0) { fprintf(stderr, "submit xfer failed.\n"); } } > Check the timing using the usbdump tool. my program PKTS_PER_XFER: 0x80 23:01:33.370412 usbus2.4 SUBM-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0 23:01:33.389032 usbus2.4 SUBM-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0 23:01:33.389042 usbus2.4 DONE-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0,ERR=0 23:01:33.404949 usbus2.4 SUBM-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0 23:01:33.405265 usbus2.4 DONE-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0,ERR=0 23:01:33.420945 usbus2.4 SUBM-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0 23:01:33.420955 usbus2.4 DONE-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0,ERR=0 23:01:33.436940 usbus2.4 SUBM-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0 23:01:33.437194 usbus2.4 DONE-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0,ERR=0 23:01:33.452938 usbus2.4 SUBM-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0 pcwview + webcamd 23:03:26.129895 usbus2.4 SUBM-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0 23:03:26.148288 usbus2.4 SUBM-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0 23:03:26.148331 usbus2.4 DONE-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0,ERR=0 23:03:26.164211 usbus2.4 SUBM-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0 23:03:26.164930 usbus2.4 DONE-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0,ERR=0 23:03:26.180201 usbus2.4 SUBM-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0 23:03:26.180241 usbus2.4 DONE-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0,ERR=0 23:03:26.196163 usbus2.4 SUBM-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0 23:03:26.196761 usbus2.4 DONE-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0,ERR=0 23:03:26.212158 usbus2.4 SUBM-ISOC-EP=00000082,SPD=HIGH,NFR=128,SLEN=0,IVAL=0 There is no significant differences about submit-done sequence. About submit-done response time, former is faster than latter a little. --- SAITOU Toshihide
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20121114.002306.36926536.toshi>