@@ -53,15 +53,14 @@ USBVideoQueueIsoRead(
5353 Urb -> UrbIsochronousTransfer .Hdr .Length = GET_ISO_URB_SIZE (DeviceExtension -> IsoPacketCount );
5454 Urb -> UrbIsochronousTransfer .PipeHandle = DeviceExtension -> hPipe ;
5555 Urb -> UrbIsochronousTransfer .TransferFlags = USBD_TRANSFER_DIRECTION_IN | USBD_START_ISO_TRANSFER_ASAP ;
56- Urb -> UrbIsochronousTransfer .TransferBufferLength = DeviceExtension -> dwMaxPayloadTransferSize * DeviceExtension -> IsoPacketCount ;
56+ Urb -> UrbIsochronousTransfer .TransferBufferLength = ( DeviceExtension -> dwMaxPayloadTransferSize ) * DeviceExtension -> IsoPacketCount ;
5757 Urb -> UrbIsochronousTransfer .TransferBuffer = TransferBuffer ;
5858 Urb -> UrbIsochronousTransfer .NumberOfPackets = DeviceExtension -> IsoPacketCount ;
5959 Urb -> UrbIsochronousTransfer .StartFrame = 0 ;
6060
6161 for (Index = 0 ; Index < DeviceExtension -> IsoPacketCount ; Index ++ )
6262 {
63- Urb -> UrbIsochronousTransfer .IsoPacket [Index ].Offset = Index * DeviceExtension -> dwMaxPayloadTransferSize ;
64- Urb -> UrbIsochronousTransfer .IsoPacket [Index ].Length = DeviceExtension -> dwMaxPayloadTransferSize ;
63+ Urb -> UrbIsochronousTransfer .IsoPacket [Index ].Offset = Index * (DeviceExtension -> dwMaxPayloadTransferSize );
6564 }
6665 /* setup next stack location */
6766 IoStack = IoGetNextIrpStackLocation (Irp );
@@ -109,16 +108,64 @@ USBVideoIsoReadComplete(
109108 return STATUS_MORE_PROCESSING_REQUIRED ;
110109 }
111110 BytesReceived = 0 ;
111+ UCHAR FirstFID = 0xFF , NewFid = 0xFF ;
112+ ULONG PacketFIDChange = -1 ;
113+ Data = (PUCHAR )Urb -> UrbIsochronousTransfer .TransferBuffer ;
112114
113115 for (Index = 0 ; Index < Urb -> UrbIsochronousTransfer .NumberOfPackets ; Index ++ )
114116 {
115117 //DPRINT1("Index %u Length %u\n", Index, Urb->UrbIsochronousTransfer.IsoPacket[Index].Length);
116118 BytesReceived += Urb -> UrbIsochronousTransfer .IsoPacket [Index ].Length ;
119+ if (Urb -> UrbIsochronousTransfer .IsoPacket [Index ].Status != USBD_STATUS_SUCCESS )
120+ {
121+ DPRINT ("Status %x failed for packet %u\n" , Urb -> UrbIsochronousTransfer .IsoPacket [Index ].Status , Index );
122+ continue ;
123+ }
124+ Offset = Urb -> UrbIsochronousTransfer .IsoPacket [Index ].Offset ;
125+ Hdr = (PUVC_PAYLOAD_HEADER )(Data + Offset );
126+ HeaderLen = Hdr -> bHeaderLength ;
127+ /* validate header length */
128+ if (HeaderLen < 2 || HeaderLen > 12 || Offset + HeaderLen > BytesReceived )
129+ {
130+ DPRINT ("Invalid packet atIso Index %u Offset %u HeaderLen %u BytesReceived %u\n" , Index ,
131+ Offset , HeaderLen , BytesReceived );
132+ continue ;
133+ }
134+ if (FirstFID == 0xFF )
135+ {
136+ /* valid first packet */
137+ FirstFID = Hdr -> FID ;
138+ continue ;
139+ }
140+ if (FirstFID != Hdr -> FID )
141+ {
142+ if (PacketFIDChange == (ULONG )- 1 )
143+ {
144+ PUCHAR DataBuffer = (PUCHAR )(Data + Offset + HeaderLen );
145+ if (DataBuffer [0 ] == 0xFF && DataBuffer [1 ] == 0xD8 )
146+ {
147+ /* fid changed at packet */
148+ PacketFIDChange = Index ;
149+ NewFid = Hdr -> FID ;
150+ }
151+ }
152+ }
117153 }
118154
119- Data = (PUCHAR )Urb -> UrbIsochronousTransfer .TransferBuffer ;
120155 Offset = 0 ;
121- for (Index = 0 ; Index < Urb -> UrbIsochronousTransfer .NumberOfPackets ; Index ++ )
156+ if (PacketFIDChange != (ULONG )- 1 )
157+ {
158+ Index = PacketFIDChange ;
159+ Frame -> LastFid = NewFid ;
160+ Frame -> FrameSize = 0 ;
161+ Frame -> FrameStarted = TRUE;
162+ //DPRINT1("FIDChange at Packet Index %u\n", Index);
163+ }
164+ else
165+ {
166+ Index = Urb -> UrbIsochronousTransfer .NumberOfPackets + 1 ; // throw away packet
167+ }
168+ for (; Index < Urb -> UrbIsochronousTransfer .NumberOfPackets ; Index ++ )
122169 {
123170 if (Urb -> UrbIsochronousTransfer .IsoPacket [Index ].Status != USBD_STATUS_SUCCESS )
124171 {
@@ -136,19 +183,28 @@ USBVideoIsoReadComplete(
136183 Offset , HeaderLen , BytesReceived );
137184 continue ;
138185 }
139- #if 0
186+
187+ /* discard packet if EOH bit is not set */
188+ if (Hdr -> EOH == 0 ) {
189+ DPRINT1 ("EOH bit not set at IsoPacket Index %u\n" , Index );//, Value[0], Status);
190+ continue ;
191+ }
192+
193+ /* discard packet if RES bit is set */
194+ if (Hdr -> RES ) {
195+ DPRINT1 ("RES bit set at IsoPacket Index %u\n" , Index );//, Value[0], Status);
196+ continue ;
197+ }
198+
140199 /* discard frame if err bit is set */
141200 if (Hdr -> ERR ) {
142- //PUCHAR Value = AllocFunction(sizeof(UCHAR)*2);
143- //NTSTATUS Status = USBVideoTransferControlPacket(Pin, Value, sizeof(UCHAR)*2, USBD_TRANSFER_DIRECTION_IN, 0x81, 0x0200, 0x00);
144201 DPRINT1 ("ERR bit set at IsoPacket Index %u\n" , Index );//, Value[0], Status);
145202 Frame -> FrameStarted = FALSE;
146203 Frame -> FrameSize = 0 ;
147- break ;
204+ continue ;
148205 }
149- #endif
150206 /* check FID */
151- if (Frame -> FrameStarted && (Hdr -> FID != Frame -> LastFid || Hdr -> EOF )) {
207+ if (Frame -> FrameStarted && Frame -> FrameSize > 0 && (Hdr -> FID != Frame -> LastFid )) {
152208 USBVideoDeliverFrame (DeviceExtension ,
153209 Frame -> FrameBuffer ,
154210 Frame -> FrameSize );
@@ -159,12 +215,13 @@ USBVideoIsoReadComplete(
159215
160216 /* copy payload */
161217 ULONG PayloadDataOffset = Offset + HeaderLen ;
162- ULONG PayloadDataLen = DeviceExtension -> dwMaxPayloadTransferSize - HeaderLen ;
163-
218+ ULONG Length = Urb -> UrbIsochronousTransfer .IsoPacket [Index ].Length ;
219+ ULONG PayloadDataLen = Length - HeaderLen ;
220+ #if 0
164221 /* validate payload length*/
165222 if (PayloadDataOffset + PayloadDataLen > BytesReceived )
166223 PayloadDataLen = BytesReceived - PayloadDataOffset ;
167-
224+ #endif
168225 if (PayloadDataLen > 0 && Frame -> FrameSize + PayloadDataLen <= Frame -> MaxFrameSize ) {
169226
170227 RtlCopyMemory (
@@ -177,6 +234,19 @@ USBVideoIsoReadComplete(
177234 Frame -> FrameStarted = TRUE;
178235 }
179236
237+ /* check FID */
238+ if (Frame -> FrameStarted && Frame -> FrameSize > 2 && Hdr -> EOF ) {
239+ if (Frame -> FrameBuffer [Frame -> FrameSize - 2 ] == 0xFF &&
240+ Frame -> FrameBuffer [Frame -> FrameSize - 1 ] == 0xD9 )
241+ {
242+ USBVideoDeliverFrame (DeviceExtension ,
243+ Frame -> FrameBuffer ,
244+ Frame -> FrameSize );
245+ Frame -> FrameSize = 0 ;
246+ Frame -> FrameStarted = FALSE;
247+ }
248+ }
249+
180250 if (Frame -> FrameSize == Frame -> MaxFrameSize )
181251 {
182252 DPRINT1 ("Buffer full discarding\n" );
0 commit comments