UVC host library

Dependents:   LifeCam WebcamServer

Committer:
va009039
Date:
Wed Aug 15 13:52:53 2012 +0000
Revision:
3:3eb41d749f9a
Parent:
0:b0f04c137829
add USB_USE_MALLOC

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:b0f04c137829 1 #include "mbed.h"
va009039 0:b0f04c137829 2 #include "uvc.h"
va009039 0:b0f04c137829 3 #define __DEBUG
va009039 0:b0f04c137829 4 #include "mydbg.h"
va009039 0:b0f04c137829 5 #include "stcamcfg.h"
va009039 0:b0f04c137829 6 #include "Utils.h"
va009039 0:b0f04c137829 7
va009039 0:b0f04c137829 8 #define DESCRIPTOR_TYPE_DEVICE 1
va009039 0:b0f04c137829 9 #define DESCRIPTOR_TYPE_CONFIGURATION 2
va009039 0:b0f04c137829 10 #define DESCRIPTOR_TYPE_STRING 3
va009039 0:b0f04c137829 11 #define DESCRIPTOR_TYPE_INTERFACE 4
va009039 0:b0f04c137829 12 #define DESCRIPTOR_TYPE_ENDPOINT 5
va009039 0:b0f04c137829 13
va009039 0:b0f04c137829 14 #define DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION 0x0b
va009039 0:b0f04c137829 15
va009039 0:b0f04c137829 16 #define DESCRIPTOR_TYPE_HID 0x21
va009039 0:b0f04c137829 17 #define DESCRIPTOR_TYPE_REPORT 0x22
va009039 0:b0f04c137829 18 #define DESCRIPTOR_TYPE_PHYSICAL 0x23
va009039 0:b0f04c137829 19 #define DESCRIPTOR_TYPE_CS_INTERFACE 0x24
va009039 0:b0f04c137829 20 #define DESCRIPTOR_TYPE_CS_ENDPOINT 0x25
va009039 0:b0f04c137829 21 #define DESCRIPTOR_TYPE_HUB 0x29
va009039 0:b0f04c137829 22
va009039 0:b0f04c137829 23 #define CLASS_AUDIO 0x02
va009039 0:b0f04c137829 24 #define CLASS_HUB 0x09
va009039 0:b0f04c137829 25
va009039 0:b0f04c137829 26 #define IF_EQ_THEN_PRINTF(A,B) if (A == B) {VERBOSE("%s\n", #A);
va009039 0:b0f04c137829 27 #define ENDIF }
va009039 0:b0f04c137829 28
va009039 0:b0f04c137829 29 #define CC_AUDIO 0x01
va009039 0:b0f04c137829 30 #define SC_AUDIOCONTROL 0x01
va009039 0:b0f04c137829 31 #define SC_AUDIOSTREAMING 0x02
va009039 0:b0f04c137829 32
va009039 0:b0f04c137829 33 #define AC_HEADER 0x01
va009039 0:b0f04c137829 34 #define AC_INPUT_TERMINAL 0x02
va009039 0:b0f04c137829 35 #define AC_OUTPUT_TERMINAL 0x03
va009039 0:b0f04c137829 36 #define AC_FEATURE_UNIT 0x06
va009039 0:b0f04c137829 37
va009039 0:b0f04c137829 38 // Input Terminal Types
va009039 0:b0f04c137829 39 #define ITT_CAMERA 0x0201
va009039 0:b0f04c137829 40
va009039 0:b0f04c137829 41
va009039 0:b0f04c137829 42 void _parserAudioControl(uint8_t* buf, int len) {
va009039 0:b0f04c137829 43 int subtype = buf[2];
va009039 0:b0f04c137829 44 IF_EQ_THEN_PRINTF(AC_HEADER, subtype)
va009039 0:b0f04c137829 45 VERBOSE("ADC: %04x\n", LE16(buf+3));
va009039 0:b0f04c137829 46 VERBOSE("TotalLength: %d\n", LE16(buf+5));
va009039 0:b0f04c137829 47 VERBOSE("InCollection: %d\n", buf[7]);
va009039 0:b0f04c137829 48 for (int n = 1; n <= buf[7]; n++) {
va009039 0:b0f04c137829 49 VERBOSE("aInterfaceNr(%d): %d\n", n, buf[8+n-1]);
va009039 0:b0f04c137829 50 }
va009039 0:b0f04c137829 51 ENDIF
va009039 0:b0f04c137829 52 IF_EQ_THEN_PRINTF(AC_INPUT_TERMINAL, subtype)
va009039 0:b0f04c137829 53 VERBOSE("TerminalID: %d\n", buf[3]);
va009039 0:b0f04c137829 54 VERBOSE("TerminalType: %04X\n", LE16(buf+4));
va009039 0:b0f04c137829 55 VERBOSE("AssocTermianl: %d\n", buf[6]);
va009039 0:b0f04c137829 56 VERBOSE("NrChannels: %d\n", buf[7]);
va009039 0:b0f04c137829 57 ENDIF
va009039 0:b0f04c137829 58 IF_EQ_THEN_PRINTF(AC_OUTPUT_TERMINAL, subtype)
va009039 0:b0f04c137829 59 VERBOSE("TerminalID: %d\n", buf[3]);
va009039 0:b0f04c137829 60 VERBOSE("TerminalType: %04X\n", LE16(buf+4));
va009039 0:b0f04c137829 61 VERBOSE("AssocTermianl: %d\n", buf[6]);
va009039 0:b0f04c137829 62 ENDIF
va009039 0:b0f04c137829 63 IF_EQ_THEN_PRINTF(AC_FEATURE_UNIT, subtype)
va009039 0:b0f04c137829 64 VERBOSE("UnitID: %d\n", buf[3]);
va009039 0:b0f04c137829 65 VERBOSE("SourceID: %d\n", buf[4]);
va009039 0:b0f04c137829 66 VERBOSE("ControlSize: %d\n", buf[5]);
va009039 0:b0f04c137829 67 ENDIF
va009039 0:b0f04c137829 68 }
va009039 0:b0f04c137829 69
va009039 0:b0f04c137829 70 #define AS_GENERAL 0x01
va009039 0:b0f04c137829 71 #define AS_FORMAT_TYPE 0x02
va009039 0:b0f04c137829 72
va009039 0:b0f04c137829 73 void _parserAudioStream(uint8_t* buf, int len) {
va009039 0:b0f04c137829 74 int subtype = buf[2];
va009039 0:b0f04c137829 75 IF_EQ_THEN_PRINTF(AS_GENERAL, subtype)
va009039 0:b0f04c137829 76 VERBOSE("TerminalLink: %d\n", buf[3]);
va009039 0:b0f04c137829 77 VERBOSE("Delay: %d\n", buf[4]);
va009039 0:b0f04c137829 78 VERBOSE("FormatTag: %04x\n", LE16(buf+5));
va009039 0:b0f04c137829 79 ENDIF
va009039 0:b0f04c137829 80 IF_EQ_THEN_PRINTF(AS_FORMAT_TYPE, subtype)
va009039 0:b0f04c137829 81 VERBOSE("FormatType: %d\n", buf[3]);
va009039 0:b0f04c137829 82 VERBOSE("NrChannels: %d\n", buf[4]);
va009039 0:b0f04c137829 83 VERBOSE("SubFrameSize: %d\n", buf[5]);
va009039 0:b0f04c137829 84 VERBOSE("BitResolution: %d\n", buf[6]);
va009039 0:b0f04c137829 85 VERBOSE("SamFreqType: %d\n", buf[7]);
va009039 0:b0f04c137829 86 VERBOSE("SamFreq(1): %d\n", LE24(buf+8));
va009039 0:b0f04c137829 87 ENDIF
va009039 0:b0f04c137829 88 }
va009039 0:b0f04c137829 89
va009039 0:b0f04c137829 90 #define CC_VIDEO 0x0e
va009039 0:b0f04c137829 91
va009039 0:b0f04c137829 92 #define SC_VIDEOCONTROL 0x01
va009039 0:b0f04c137829 93 #define SC_VIDEOSTREAMING 0x02
va009039 0:b0f04c137829 94
va009039 0:b0f04c137829 95 #define VC_HEADER 0x01
va009039 0:b0f04c137829 96 #define VC_INPUT_TERMINAL 0x02
va009039 0:b0f04c137829 97 #define VC_OUTPUT_TERMINAL 0x03
va009039 0:b0f04c137829 98 #define VC_SELECTOR_UNIT 0x04
va009039 0:b0f04c137829 99 #define VC_PROCESSING_UNIT 0x05
va009039 0:b0f04c137829 100 #define VC_EXTENSION_UNIT 0x06
va009039 0:b0f04c137829 101
va009039 0:b0f04c137829 102 void _parserVideoControl(struct stcamcfg* cfg, uint8_t* buf, int len) {
va009039 0:b0f04c137829 103 int subtype = buf[2];
va009039 0:b0f04c137829 104 IF_EQ_THEN_PRINTF(VC_HEADER, subtype)
va009039 0:b0f04c137829 105 cfg->bcdUVC = LE16(buf+3);
va009039 0:b0f04c137829 106 VERBOSE("UVC: %04x\n", cfg->bcdUVC);
va009039 0:b0f04c137829 107 VERBOSE("TotalLength: %d\n", LE16(buf+5));
va009039 0:b0f04c137829 108 VERBOSE("ClockFrequency: %d\n", LE32(buf+7));
va009039 0:b0f04c137829 109 VERBOSE("InCollection: %d\n", buf[11]);
va009039 0:b0f04c137829 110 VERBOSE("aInterfaceNr(1): %d\n", buf[12]);
va009039 0:b0f04c137829 111 ENDIF
va009039 0:b0f04c137829 112 IF_EQ_THEN_PRINTF(VC_INPUT_TERMINAL, subtype)
va009039 0:b0f04c137829 113 VERBOSE("TerminalID: %d\n", buf[3]);
va009039 0:b0f04c137829 114 uint16_t tt = LE16(buf+4);
va009039 0:b0f04c137829 115 VERBOSE("TerminalType: %04X\n", tt);
va009039 0:b0f04c137829 116 VERBOSE("AssocTerminal: %d\n", buf[6]);
va009039 0:b0f04c137829 117 VERBOSE("Terminal: %d\n", buf[7]);
va009039 0:b0f04c137829 118 if (tt == ITT_CAMERA) { // camera
va009039 0:b0f04c137829 119 int bControlSize = buf[14];
va009039 0:b0f04c137829 120 VERBOSE("ControlSize: %d\n", bControlSize);
va009039 0:b0f04c137829 121 for(int i = 0; i < bControlSize; i++) {
va009039 0:b0f04c137829 122 uint8_t bControls = buf[15+i];
va009039 0:b0f04c137829 123 VERBOSE("Controls(%d): %02X\n", i, bControls);
va009039 0:b0f04c137829 124 }
va009039 0:b0f04c137829 125 }
va009039 0:b0f04c137829 126 ENDIF
va009039 0:b0f04c137829 127 IF_EQ_THEN_PRINTF(VC_OUTPUT_TERMINAL, subtype)
va009039 0:b0f04c137829 128 VERBOSE("TerminalID: %d\n", buf[3]);
va009039 0:b0f04c137829 129 VERBOSE("TerminalType: %04X\n", LE16(buf+4));
va009039 0:b0f04c137829 130 VERBOSE("AssocTerminal: %d\n", buf[6]);
va009039 0:b0f04c137829 131 VERBOSE("SourceID: %d\n", buf[7]);
va009039 0:b0f04c137829 132 VERBOSE("Terminal: %d\n", buf[8]);
va009039 0:b0f04c137829 133 ENDIF
va009039 0:b0f04c137829 134 IF_EQ_THEN_PRINTF(VC_SELECTOR_UNIT, subtype)
va009039 0:b0f04c137829 135 VERBOSE("UnitID: %d\n", buf[3]);
va009039 0:b0f04c137829 136 ENDIF
va009039 0:b0f04c137829 137 IF_EQ_THEN_PRINTF(VC_PROCESSING_UNIT, subtype)
va009039 0:b0f04c137829 138 VERBOSE("UnitID: %d\n", buf[3]);
va009039 0:b0f04c137829 139 VERBOSE("SourceID: %d\n", buf[4]);
va009039 0:b0f04c137829 140 VERBOSE("MaxMultiplier: %d\n", LE16(buf+5));
va009039 0:b0f04c137829 141 VERBOSE("ControlSize: %d\n", buf[7]);
va009039 0:b0f04c137829 142 int pos = 8;
va009039 0:b0f04c137829 143 for (int n = 1; n <= buf[7]; n++) {
va009039 0:b0f04c137829 144 VERBOSE("Controls(%d): %02X\n", n , buf[pos]);
va009039 0:b0f04c137829 145 pos++;
va009039 0:b0f04c137829 146 }
va009039 0:b0f04c137829 147 VERBOSE("Processing: %d\n", buf[pos]);
va009039 0:b0f04c137829 148 pos++;
va009039 0:b0f04c137829 149 VERBOSE("VideoStanders: %02X\n", buf[pos]);
va009039 0:b0f04c137829 150 ENDIF
va009039 0:b0f04c137829 151 IF_EQ_THEN_PRINTF(VC_EXTENSION_UNIT, subtype)
va009039 0:b0f04c137829 152 VERBOSE("UnitID: %d\n", buf[3]);
va009039 0:b0f04c137829 153 ENDIF
va009039 0:b0f04c137829 154 }
va009039 0:b0f04c137829 155
va009039 0:b0f04c137829 156 #define VS_INPUT_HEADER 0x01
va009039 0:b0f04c137829 157 #define VS_STILL_FRAME 0x03
va009039 0:b0f04c137829 158 #define VS_FORMAT_UNCOMPRESSED 0x04
va009039 0:b0f04c137829 159 #define VS_FRAME_UNCOMPRESSED 0x05
va009039 0:b0f04c137829 160 #define VS_FORMAT_MJPEG 0x06
va009039 0:b0f04c137829 161 #define VS_FRAME_MJPEG 0x07
va009039 0:b0f04c137829 162 #define VS_COLOR_FORMAT 0x0d
va009039 0:b0f04c137829 163
va009039 0:b0f04c137829 164 void _parserVideoStream(struct stcamcfg* cfg, uint8_t* buf, int len) {
va009039 0:b0f04c137829 165 int subtype = buf[2];
va009039 0:b0f04c137829 166 IF_EQ_THEN_PRINTF(VS_INPUT_HEADER, subtype)
va009039 0:b0f04c137829 167 VERBOSE("NumFormats: %d\n", buf[3]);
va009039 0:b0f04c137829 168 VERBOSE("TotalLength: %d\n", LE16(buf+4));
va009039 0:b0f04c137829 169 VERBOSE("EndpointAddress: %02X\n", buf[6]);
va009039 0:b0f04c137829 170 VERBOSE("Info: %02X\n", buf[7]);
va009039 0:b0f04c137829 171 VERBOSE("TerminalLink: %d\n", buf[8]);
va009039 0:b0f04c137829 172 VERBOSE("StillCaptureMethod: %d\n", buf[9]);
va009039 0:b0f04c137829 173 VERBOSE("TriggerSupport: %d\n", buf[10]);
va009039 0:b0f04c137829 174 VERBOSE("TriggerUsage: %d\n", buf[11]);
va009039 0:b0f04c137829 175 VERBOSE("ControlSize: %d\n", buf[12]);
va009039 0:b0f04c137829 176 int pos = 13;
va009039 0:b0f04c137829 177 for (int n = 1; n <= buf[12]; n++) {
va009039 0:b0f04c137829 178 VERBOSE("Controls(%d): %02X\n", n, buf[pos]);
va009039 0:b0f04c137829 179 pos++;
va009039 0:b0f04c137829 180 }
va009039 0:b0f04c137829 181 cfg->bEndpointAddress = buf[6];
va009039 0:b0f04c137829 182 ENDIF
va009039 0:b0f04c137829 183 IF_EQ_THEN_PRINTF(VS_STILL_FRAME, subtype)
va009039 0:b0f04c137829 184 VERBOSE("EndpointAdress: %02X\n", buf[3]);
va009039 0:b0f04c137829 185 VERBOSE("NumImageSizePatterns: %d\n", buf[4]);
va009039 0:b0f04c137829 186 int ptn = buf[4];
va009039 0:b0f04c137829 187 int pos = 5;
va009039 0:b0f04c137829 188 for (int n = 1; n <= ptn; n++) {
va009039 0:b0f04c137829 189 VERBOSE("Width(%d): %d\n", n, LE16(buf+pos));
va009039 0:b0f04c137829 190 VERBOSE("Height(%d): %d\n", n, LE16(buf+pos+2));
va009039 0:b0f04c137829 191 pos += 4;
va009039 0:b0f04c137829 192 }
va009039 0:b0f04c137829 193 VERBOSE("NumCompressPtn: %d\n", buf[pos]);
va009039 0:b0f04c137829 194 ptn = buf[pos++];
va009039 0:b0f04c137829 195 for (int n = 1; n <= ptn; n++) {
va009039 0:b0f04c137829 196 VERBOSE("Compress(%d): %d\n", n, buf[pos]);
va009039 0:b0f04c137829 197 pos++;
va009039 0:b0f04c137829 198 }
va009039 0:b0f04c137829 199 ENDIF
va009039 0:b0f04c137829 200 IF_EQ_THEN_PRINTF(VS_FORMAT_UNCOMPRESSED, subtype)
va009039 0:b0f04c137829 201 VERBOSE("FormatIndex: %d\n", buf[3]);
va009039 0:b0f04c137829 202 VERBOSE("NumFrameDescriptors: %d\n", buf[4]);
va009039 0:b0f04c137829 203 uint32_t guid = LE32(buf+5);
va009039 0:b0f04c137829 204 if (guid == 0x32595559) {
va009039 0:b0f04c137829 205 VERBOSE("GUID: YUY2\n");
va009039 0:b0f04c137829 206 } else if (guid == 0x3231564e) {
va009039 0:b0f04c137829 207 VERBOSE("GUID: NV12\n");
va009039 0:b0f04c137829 208 } else {
va009039 0:b0f04c137829 209 VERBOSE("GUID: %08x\n", guid);
va009039 0:b0f04c137829 210 }
va009039 0:b0f04c137829 211 VERBOSE("DefaultFrameIndex: %d\n", buf[22]);
va009039 0:b0f04c137829 212 if (cfg->payload == PAYLOAD_YUY2) {
va009039 0:b0f04c137829 213 cfg->FormatIndex = buf[3];
va009039 0:b0f04c137829 214 }
va009039 0:b0f04c137829 215 ENDIF
va009039 0:b0f04c137829 216 IF_EQ_THEN_PRINTF(VS_FRAME_UNCOMPRESSED, subtype)
va009039 0:b0f04c137829 217 VERBOSE("FrameIndex: %d\n", buf[3]);
va009039 0:b0f04c137829 218 VERBOSE("Capabilites: %d\n", buf[4]);
va009039 0:b0f04c137829 219 VERBOSE("Width: %d\n", LE16(buf+5));
va009039 0:b0f04c137829 220 VERBOSE("Height: %d\n", LE16(buf+7));
va009039 0:b0f04c137829 221 VERBOSE("MinBitRate: %d\n", LE32(buf+9));
va009039 0:b0f04c137829 222 VERBOSE("MaxBitRate: %d\n", LE32(buf+13));
va009039 0:b0f04c137829 223 VERBOSE("MaxVideoFrameBufferSize: %d\n", LE32(buf+17));
va009039 0:b0f04c137829 224 VERBOSE("DefaultFrameInterval: %d\n", LE32(buf+21));
va009039 0:b0f04c137829 225 VERBOSE("FrameIntervalType: %d\n", buf[25]);
va009039 0:b0f04c137829 226 int it = buf[25];
va009039 0:b0f04c137829 227 uint32_t max_fi = 333333; // 30.0fps
va009039 0:b0f04c137829 228 if (it == 0) {
va009039 0:b0f04c137829 229 VERBOSE("FrameMinInterval: %d\n", buf[26]);
va009039 0:b0f04c137829 230 VERBOSE("FrameMaxInterval: %d\n", buf[30]);
va009039 0:b0f04c137829 231 VERBOSE("FrameIntervalStep: %d\n", buf[34]);
va009039 0:b0f04c137829 232 } else {
va009039 0:b0f04c137829 233 int pos = 26;
va009039 0:b0f04c137829 234 for (int n = 1; n <= it; n++) {
va009039 0:b0f04c137829 235 uint32_t fi = LE32(buf+pos);
va009039 0:b0f04c137829 236 if (fi >= max_fi) {
va009039 0:b0f04c137829 237 max_fi = fi;
va009039 0:b0f04c137829 238 }
va009039 0:b0f04c137829 239 float fps = 1e+7 / fi;
va009039 0:b0f04c137829 240 VERBOSE("FrameInterval(%u): %d (%.1f fps)\n", n, fi, fps);
va009039 0:b0f04c137829 241 pos += 4;
va009039 0:b0f04c137829 242 }
va009039 0:b0f04c137829 243 }
va009039 0:b0f04c137829 244 if (cfg->payload == PAYLOAD_YUY2) {
va009039 0:b0f04c137829 245 if (cfg->width == LE16(buf+5) && cfg->height == LE16(buf+7)) {
va009039 0:b0f04c137829 246 cfg->FrameIndex = buf[3];
va009039 0:b0f04c137829 247 }
va009039 0:b0f04c137829 248 if (cfg->dwFrameInterval == 0) {
va009039 0:b0f04c137829 249 cfg->dwFrameInterval = max_fi;
va009039 0:b0f04c137829 250 }
va009039 0:b0f04c137829 251 }
va009039 0:b0f04c137829 252 ENDIF
va009039 0:b0f04c137829 253 IF_EQ_THEN_PRINTF(VS_FORMAT_MJPEG, subtype)
va009039 0:b0f04c137829 254 VERBOSE("FormatIndex: %d\n", buf[3]);
va009039 0:b0f04c137829 255 VERBOSE("NumFrameDescriptors: %d\n", buf[4]);
va009039 0:b0f04c137829 256 VERBOSE("Flags: %d\n", buf[5]);
va009039 0:b0f04c137829 257 VERBOSE("DefaultFrameIndex: %d\n", buf[6]);
va009039 0:b0f04c137829 258 if (cfg->payload == PAYLOAD_MJPEG) {
va009039 0:b0f04c137829 259 cfg->FormatIndex = buf[3];
va009039 0:b0f04c137829 260 }
va009039 0:b0f04c137829 261 ENDIF
va009039 0:b0f04c137829 262 IF_EQ_THEN_PRINTF(VS_FRAME_MJPEG, subtype)
va009039 0:b0f04c137829 263 VERBOSE("FrameIndex: %d\n", buf[3]);
va009039 0:b0f04c137829 264 VERBOSE("Capabilites: %d\n", buf[4]);
va009039 0:b0f04c137829 265 VERBOSE("Width: %d\n", LE16(buf+5));
va009039 0:b0f04c137829 266 VERBOSE("Height: %d\n", LE16(buf+7));
va009039 0:b0f04c137829 267 VERBOSE("MinBitRate: %d\n", LE32(buf+9));
va009039 0:b0f04c137829 268 VERBOSE("MaxBitRate: %d\n", LE32(buf+13));
va009039 0:b0f04c137829 269 VERBOSE("MaxVideoFrameBufferSize: %d\n", LE32(buf+17));
va009039 0:b0f04c137829 270 VERBOSE("DefaultFrameInterval: %d\n", LE32(buf+21));
va009039 0:b0f04c137829 271 VERBOSE("FrameIntervalType: %d\n", buf[25]);
va009039 0:b0f04c137829 272 int it = buf[25];
va009039 0:b0f04c137829 273 uint32_t max_fi = 333333; // 30.0fps
va009039 0:b0f04c137829 274 if (it == 0) {
va009039 0:b0f04c137829 275 VERBOSE("FrameMinInterval: %d\n", buf[26]);
va009039 0:b0f04c137829 276 VERBOSE("FrameMaxInterval: %d\n", buf[30]);
va009039 0:b0f04c137829 277 VERBOSE("FrameIntervalStep: %d\n", buf[34]);
va009039 0:b0f04c137829 278 } else {
va009039 0:b0f04c137829 279 int pos = 26;
va009039 0:b0f04c137829 280 for (int n = 1; n <= it; n++) {
va009039 0:b0f04c137829 281 uint32_t fi = LE32(buf+pos);
va009039 0:b0f04c137829 282 if (fi >= max_fi) {
va009039 0:b0f04c137829 283 max_fi = fi;
va009039 0:b0f04c137829 284 }
va009039 0:b0f04c137829 285 float fps = 1e+7 / fi;
va009039 0:b0f04c137829 286 VERBOSE("FrameInterval(%u): %d (%.1f fps)\n", n, fi, fps);
va009039 0:b0f04c137829 287 pos += 4;
va009039 0:b0f04c137829 288 }
va009039 0:b0f04c137829 289 }
va009039 0:b0f04c137829 290 if (cfg->payload == PAYLOAD_MJPEG) {
va009039 0:b0f04c137829 291 if (cfg->width == LE16(buf+5) && cfg->height == LE16(buf+7)) {
va009039 0:b0f04c137829 292 cfg->FrameIndex = buf[3];
va009039 0:b0f04c137829 293 }
va009039 0:b0f04c137829 294 if (cfg->dwFrameInterval == 0) {
va009039 0:b0f04c137829 295 cfg->dwFrameInterval = max_fi;
va009039 0:b0f04c137829 296 }
va009039 0:b0f04c137829 297 }
va009039 0:b0f04c137829 298 ENDIF
va009039 0:b0f04c137829 299 IF_EQ_THEN_PRINTF(VS_COLOR_FORMAT, subtype)
va009039 0:b0f04c137829 300 ENDIF
va009039 0:b0f04c137829 301 }
va009039 0:b0f04c137829 302
va009039 0:b0f04c137829 303 void _parserConfigurationDescriptor(struct stcamcfg* cfg, uint8_t* buf, int len) {
va009039 0:b0f04c137829 304 //DBG("buf=%p len=%d\n", buf, len);
va009039 0:b0f04c137829 305 //DBG_HEX(buf, len);
va009039 0:b0f04c137829 306 int pos = 0;
va009039 0:b0f04c137829 307 cfg->_IfClass = 0;
va009039 0:b0f04c137829 308 cfg->_IfSubClass = 0;
va009039 0:b0f04c137829 309 while (pos < len) {
va009039 0:b0f04c137829 310 int type = buf[pos+1];
va009039 0:b0f04c137829 311 //DBG_BYTES(TYPE_Str(type), buf+pos, buf[pos]);
va009039 0:b0f04c137829 312 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_CONFIGURATION, type)
va009039 0:b0f04c137829 313 VERBOSE("NumInterfaces: %d\n", buf[pos+4]);
va009039 0:b0f04c137829 314 ENDIF
va009039 0:b0f04c137829 315 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION, type)
va009039 0:b0f04c137829 316 VERBOSE("FirstInterface: %d\n", buf[pos+2]);
va009039 0:b0f04c137829 317 VERBOSE("InterfaceCount: %d\n", buf[pos+3]);
va009039 0:b0f04c137829 318 VERBOSE("FunctionClass: %02X\n", buf[pos+4]);
va009039 0:b0f04c137829 319 VERBOSE("FunctionSubClass: %02X\n", buf[pos+5]);
va009039 0:b0f04c137829 320 VERBOSE("FunctionProtocol: %02X\n", buf[pos+6]);
va009039 0:b0f04c137829 321 VERBOSE("Function: %d\n", buf[pos+7]);
va009039 0:b0f04c137829 322 ENDIF
va009039 0:b0f04c137829 323 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_INTERFACE,type)
va009039 0:b0f04c137829 324 VERBOSE("InterfaceNumber: %d\n", buf[pos+2]);
va009039 0:b0f04c137829 325 VERBOSE("AlternateSetting: %d\n", buf[pos+3]);
va009039 0:b0f04c137829 326 VERBOSE("NumEndpoint: %d\n", buf[pos+4]);
va009039 0:b0f04c137829 327 VERBOSE("InterfaceClass: %02X\n", buf[pos+5]);
va009039 0:b0f04c137829 328 VERBOSE("InterfaceSubClass: %02X\n", buf[pos+6]);
va009039 0:b0f04c137829 329 VERBOSE("InterfaceProtocol: %02X\n", buf[pos+7]);
va009039 0:b0f04c137829 330 VERBOSE("Interface: %d\n", buf[pos+8]);
va009039 0:b0f04c137829 331 cfg->_If = buf[pos+2];
va009039 0:b0f04c137829 332 cfg->_Ifalt = buf[pos+3];
va009039 0:b0f04c137829 333 cfg->_IfClass = buf[pos+5];
va009039 0:b0f04c137829 334 cfg->_IfSubClass = buf[pos+6];
va009039 0:b0f04c137829 335 ENDIF
va009039 0:b0f04c137829 336 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_ENDPOINT, type)
va009039 0:b0f04c137829 337 VERBOSE("EndpointAddress: %02X\n", buf[pos+2]);
va009039 0:b0f04c137829 338 VERBOSE("Attributes: %02X\n", buf[pos+3]);
va009039 0:b0f04c137829 339 VERBOSE("MaxPacketSize: %d\n", LE16(buf+pos+4));
va009039 0:b0f04c137829 340 VERBOSE("Interval: %d\n", buf[pos+6]);
va009039 0:b0f04c137829 341 if (cfg->_IfClass == CC_VIDEO && cfg->_IfSubClass == SC_VIDEOSTREAMING) {
va009039 0:b0f04c137829 342 if (cfg->bEndpointAddress == buf[pos+2]) {
va009039 0:b0f04c137829 343 if (cfg->wMaxPacketSize == 0) {
va009039 0:b0f04c137829 344 cfg->wMaxPacketSize = LE16(buf+pos+4);
va009039 0:b0f04c137829 345 }
va009039 0:b0f04c137829 346 if (cfg->wMaxPacketSize == LE16(buf+pos+4)) {
va009039 0:b0f04c137829 347 cfg->bInterface = cfg->_If;
va009039 0:b0f04c137829 348 cfg->bAlternate = cfg->_Ifalt;
va009039 0:b0f04c137829 349 }
va009039 0:b0f04c137829 350 }
va009039 0:b0f04c137829 351 }
va009039 0:b0f04c137829 352 ENDIF
va009039 0:b0f04c137829 353 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_CS_INTERFACE, type)
va009039 0:b0f04c137829 354 IF_EQ_THEN_PRINTF(CC_VIDEO, cfg->_IfClass)
va009039 0:b0f04c137829 355 IF_EQ_THEN_PRINTF(SC_VIDEOCONTROL, cfg->_IfSubClass)
va009039 0:b0f04c137829 356 _parserVideoControl(cfg, buf+pos, buf[pos]);
va009039 0:b0f04c137829 357 ENDIF
va009039 0:b0f04c137829 358 IF_EQ_THEN_PRINTF(SC_VIDEOSTREAMING, cfg->_IfSubClass)
va009039 0:b0f04c137829 359 _parserVideoStream(cfg, buf+pos, buf[pos]);
va009039 0:b0f04c137829 360 ENDIF
va009039 0:b0f04c137829 361 ENDIF
va009039 0:b0f04c137829 362 IF_EQ_THEN_PRINTF(CC_AUDIO, cfg->_IfClass)
va009039 0:b0f04c137829 363 IF_EQ_THEN_PRINTF(SC_AUDIOCONTROL, cfg->_IfSubClass)
va009039 0:b0f04c137829 364 _parserAudioControl(buf+pos, buf[pos]);
va009039 0:b0f04c137829 365 ENDIF
va009039 0:b0f04c137829 366 IF_EQ_THEN_PRINTF(SC_AUDIOSTREAMING, cfg->_IfSubClass)
va009039 0:b0f04c137829 367 _parserAudioStream(buf+pos, buf[pos]);
va009039 0:b0f04c137829 368 ENDIF
va009039 0:b0f04c137829 369 ENDIF
va009039 0:b0f04c137829 370 ENDIF
va009039 0:b0f04c137829 371 IF_EQ_THEN_PRINTF(DESCRIPTOR_TYPE_HUB, type)
va009039 0:b0f04c137829 372 ENDIF
va009039 0:b0f04c137829 373 pos += buf[pos];
va009039 0:b0f04c137829 374 }
va009039 0:b0f04c137829 375 }
va009039 0:b0f04c137829 376
va009039 0:b0f04c137829 377 void uvc::_config(struct stcamcfg* cfg)
va009039 0:b0f04c137829 378 {
va009039 0:b0f04c137829 379 DBG_ASSERT(cfg);
va009039 0:b0f04c137829 380 int index = 0;
va009039 0:b0f04c137829 381 uint8_t temp[4];
va009039 0:b0f04c137829 382 int rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index, temp, sizeof(temp));
va009039 0:b0f04c137829 383 DBG_ASSERT(rc == USBERR_OK);
va009039 0:b0f04c137829 384 DBG_BYTES("Config Descriptor 4bytes", temp, sizeof(temp));
va009039 0:b0f04c137829 385 DBG_ASSERT(temp[0] == 9);
va009039 0:b0f04c137829 386 DBG_ASSERT(temp[1] == 0x02);
va009039 0:b0f04c137829 387 int TotalLength = LE16(temp+2);
va009039 0:b0f04c137829 388 DBG("TotalLength: %d\n", TotalLength);
va009039 0:b0f04c137829 389
va009039 0:b0f04c137829 390 uint8_t* buf = new uint8_t[TotalLength];
va009039 0:b0f04c137829 391 DBG_ASSERT(buf);
va009039 0:b0f04c137829 392 rc = m_pDev->GetDescriptor(USB_DESCRIPTOR_TYPE_CONFIGURATION, index,
va009039 0:b0f04c137829 393 buf, TotalLength);
va009039 0:b0f04c137829 394 DBG_ASSERT(rc == USBERR_OK);
va009039 0:b0f04c137829 395
va009039 0:b0f04c137829 396 _parserConfigurationDescriptor(cfg, buf, TotalLength);
va009039 0:b0f04c137829 397
va009039 0:b0f04c137829 398 DBG("cfg->FormatIndex=%d\n", cfg->FormatIndex);
va009039 0:b0f04c137829 399 DBG("cfg->FrameIndex=%d\n", cfg->FrameIndex);
va009039 0:b0f04c137829 400 DBG("cfg->dwFrameInterval=%u\n", cfg->dwFrameInterval);
va009039 0:b0f04c137829 401
va009039 0:b0f04c137829 402 //DBG_ASSERT(cfg->FormatIndex >= 1);
va009039 0:b0f04c137829 403 //DBG_ASSERT(cfg->FormatIndex <= 2);
va009039 0:b0f04c137829 404 //DBG_ASSERT(cfg->FrameIndex >= 1);
va009039 0:b0f04c137829 405 //DBG_ASSERT(cfg->FrameIndex <= 6);
va009039 0:b0f04c137829 406
va009039 0:b0f04c137829 407 delete[] buf;
va009039 0:b0f04c137829 408 }