0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/usb.h>
0012 #include <linux/kernel.h>
0013 #include <linux/mm.h>
0014
0015 #include "uvcvideo.h"
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035 static int isight_decode(struct uvc_video_queue *queue, struct uvc_buffer *buf,
0036 const u8 *data, unsigned int len)
0037 {
0038 static const u8 hdr[] = {
0039 0x11, 0x22, 0x33, 0x44,
0040 0xde, 0xad, 0xbe, 0xef,
0041 0xde, 0xad, 0xfa, 0xce
0042 };
0043
0044 struct uvc_streaming *stream = uvc_queue_to_stream(queue);
0045 unsigned int maxlen, nbytes;
0046 u8 *mem;
0047 int is_header = 0;
0048
0049 if (buf == NULL)
0050 return 0;
0051
0052 if ((len >= 14 && memcmp(&data[2], hdr, 12) == 0) ||
0053 (len >= 15 && memcmp(&data[3], hdr, 12) == 0)) {
0054 uvc_dbg(stream->dev, FRAME, "iSight header found\n");
0055 is_header = 1;
0056 }
0057
0058
0059 if (buf->state != UVC_BUF_STATE_ACTIVE) {
0060 if (!is_header) {
0061 uvc_dbg(stream->dev, FRAME,
0062 "Dropping packet (out of sync)\n");
0063 return 0;
0064 }
0065
0066 buf->state = UVC_BUF_STATE_ACTIVE;
0067 }
0068
0069
0070
0071
0072
0073
0074
0075 if (is_header && buf->bytesused != 0) {
0076 buf->state = UVC_BUF_STATE_DONE;
0077 return -EAGAIN;
0078 }
0079
0080
0081
0082
0083
0084 if (!is_header) {
0085 maxlen = buf->length - buf->bytesused;
0086 mem = buf->mem + buf->bytesused;
0087 nbytes = min(len, maxlen);
0088 memcpy(mem, data, nbytes);
0089 buf->bytesused += nbytes;
0090
0091 if (len > maxlen || buf->bytesused == buf->length) {
0092 uvc_dbg(stream->dev, FRAME,
0093 "Frame complete (overflow)\n");
0094 buf->state = UVC_BUF_STATE_DONE;
0095 }
0096 }
0097
0098 return 0;
0099 }
0100
0101 void uvc_video_decode_isight(struct uvc_urb *uvc_urb, struct uvc_buffer *buf,
0102 struct uvc_buffer *meta_buf)
0103 {
0104 struct urb *urb = uvc_urb->urb;
0105 struct uvc_streaming *stream = uvc_urb->stream;
0106 int ret, i;
0107
0108 for (i = 0; i < urb->number_of_packets; ++i) {
0109 if (urb->iso_frame_desc[i].status < 0) {
0110 uvc_dbg(stream->dev, FRAME,
0111 "USB isochronous frame lost (%d)\n",
0112 urb->iso_frame_desc[i].status);
0113 }
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125 do {
0126 ret = isight_decode(&stream->queue, buf,
0127 urb->transfer_buffer +
0128 urb->iso_frame_desc[i].offset,
0129 urb->iso_frame_desc[i].actual_length);
0130
0131 if (buf == NULL)
0132 break;
0133
0134 if (buf->state == UVC_BUF_STATE_DONE ||
0135 buf->state == UVC_BUF_STATE_ERROR)
0136 buf = uvc_queue_next_buffer(&stream->queue,
0137 buf);
0138 } while (ret == -EAGAIN);
0139 }
0140 }