Skip site navigation (1)Skip section navigation (2)
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>