isochronous transfer packet is out of sequence
SAITOU Toshihide
toshi at ruby.ocn.ne.jp
Tue Nov 13 16:30:48 UTC 2012
In message: <201211131452.16508.hselasky at c2i.net>
Hans Petter Selasky <hselasky at c2i.net> writes:
> On Tuesday 13 November 2012 14:26:52 SAITOU Toshihide wrote:
>> In message: <201211121342.47141.hselasky at c2i.net>
>>
>> Hans Petter Selasky <hselasky at 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
More information about the freebsd-usb
mailing list