UVC host library

Dependents:   LifeCam WebcamServer

Committer:
va009039
Date:
Wed Aug 08 16:21:32 2012 +0000
Revision:
2:812d604caad4
Parent:
0:b0f04c137829
Logitech C270

Who changed what in which revision?

UserRevisionLine numberNew contents of line
va009039 0:b0f04c137829 1 #include "mbed.h"
va009039 0:b0f04c137829 2 #include "usb_mjpeg.h"
va009039 0:b0f04c137829 3 //#define __DEBUG
va009039 0:b0f04c137829 4 #define __DEBUG2
va009039 0:b0f04c137829 5 #include "mydbg.h"
va009039 0:b0f04c137829 6 #include "Utils.h"
va009039 0:b0f04c137829 7 #include "myjpeg.h"
va009039 0:b0f04c137829 8
va009039 0:b0f04c137829 9 #ifdef __DEBUG
va009039 0:b0f04c137829 10 extern DigitalOut led4;
va009039 0:b0f04c137829 11 #endif // __DEBUG
va009039 0:b0f04c137829 12
va009039 0:b0f04c137829 13 #define MJPEG_FID 0x01
va009039 0:b0f04c137829 14 #define MJPEG_EOF 0x02
va009039 0:b0f04c137829 15 #define MJPEG_PTS 0x04
va009039 0:b0f04c137829 16 #define MJPEG_SCR 0x08
va009039 0:b0f04c137829 17 #define MJPEG_STI 0x20
va009039 0:b0f04c137829 18 #define MJPEG_ERR 0x40
va009039 0:b0f04c137829 19 #define MJPEG_EOH 0x80
va009039 0:b0f04c137829 20
va009039 0:b0f04c137829 21
va009039 0:b0f04c137829 22 usb_mjpeg::usb_mjpeg(uint8_t* buf, int size)
va009039 0:b0f04c137829 23 {
va009039 2:812d604caad4 24 DBG_ASSERT(size >= 1024 && size <= 32000);
va009039 0:b0f04c137829 25 m_size = size;
va009039 0:b0f04c137829 26 m_seq = 0;
va009039 0:b0f04c137829 27 m_buf = buf;
va009039 0:b0f04c137829 28 ReportErrorFID = 0;
va009039 0:b0f04c137829 29 ReportErrorPTS = 0;
va009039 0:b0f04c137829 30 }
va009039 0:b0f04c137829 31
va009039 0:b0f04c137829 32 usb_mjpeg::~usb_mjpeg()
va009039 0:b0f04c137829 33 {
va009039 0:b0f04c137829 34
va009039 0:b0f04c137829 35 }
va009039 0:b0f04c137829 36
va009039 0:b0f04c137829 37 void usb_mjpeg::input(uint16_t frame, uint8_t* buf, int len)
va009039 0:b0f04c137829 38 {
va009039 0:b0f04c137829 39 uint8_t* StreamHeader = buf;
va009039 0:b0f04c137829 40 DBG_ASSERT(buf);
va009039 0:b0f04c137829 41 if (len > 12) {
va009039 0:b0f04c137829 42 //DBG_PRINTF("%d %02X %d\n", frame, buf[1], len);
va009039 0:b0f04c137829 43 //DBG_HEX(buf, len);
va009039 0:b0f04c137829 44 DBG_ASSERT(StreamHeader[0] == 0x0c);
va009039 0:b0f04c137829 45 //DBG_ASSERT(buf[1] == 0x8c || buf[1] == 0x8d);
va009039 0:b0f04c137829 46 //DBG("bfh:%02X\n", buf[1]);
va009039 0:b0f04c137829 47 }
va009039 0:b0f04c137829 48 DBG_ASSERT(len >= 2);
va009039 0:b0f04c137829 49
va009039 0:b0f04c137829 50 int hle = StreamHeader[0];
va009039 0:b0f04c137829 51 uint8_t bfh = StreamHeader[1];
va009039 0:b0f04c137829 52 DBG_ASSERT(len >= hle);
va009039 0:b0f04c137829 53 DBG_ASSERT(hle == 12);
va009039 0:b0f04c137829 54 uint8_t* data = buf + hle;
va009039 0:b0f04c137829 55 int data_len = len - hle;
va009039 0:b0f04c137829 56 if (m_seq == 0) {
va009039 0:b0f04c137829 57 if (check_SOI(buf, len)) {
va009039 0:b0f04c137829 58 DBG_PRINTF("%04X SOI\n", frame);
va009039 0:b0f04c137829 59 DBG_BYTES("SOI", buf, 16);
va009039 0:b0f04c137829 60 _open();
va009039 0:b0f04c137829 61 m_bfh = bfh; // save FID
va009039 0:b0f04c137829 62 if (bfh & MJPEG_PTS) {
va009039 0:b0f04c137829 63 m_pts = LE32(StreamHeader+2); // save PTS
va009039 0:b0f04c137829 64 }
va009039 0:b0f04c137829 65 _wrtie(data, data_len);
va009039 0:b0f04c137829 66 m_seq++;
va009039 0:b0f04c137829 67 }
va009039 0:b0f04c137829 68 } else if (m_seq == 1) {
va009039 0:b0f04c137829 69 if (len > hle) {
va009039 0:b0f04c137829 70 _wrtie(data, data_len);
va009039 0:b0f04c137829 71 }
va009039 0:b0f04c137829 72 if (check_EOI(buf, len)) {
va009039 0:b0f04c137829 73 DBG_PRINTF("%04X EOI\n", frame);
va009039 0:b0f04c137829 74 DBG_BYTES("EOI", buf, 12);
va009039 0:b0f04c137829 75 _close();
va009039 0:b0f04c137829 76 m_seq = 2; // done
va009039 0:b0f04c137829 77 } else if ((m_bfh ^ bfh) & MJPEG_FID) {
va009039 0:b0f04c137829 78 ReportErrorFID++;
va009039 0:b0f04c137829 79 DBG("ReportErrorFID=%d\n", ReportErrorFID);
va009039 0:b0f04c137829 80 m_seq = 0; // restart
va009039 0:b0f04c137829 81 } else if ((bfh & MJPEG_PTS) && m_pts != LE32(StreamHeader+2)) {
va009039 0:b0f04c137829 82 ReportErrorPTS++;
va009039 0:b0f04c137829 83 DBG("ReportErrorPTS=%d\n", ReportErrorPTS);
va009039 0:b0f04c137829 84 m_seq = 0; // restart
va009039 0:b0f04c137829 85 }
va009039 0:b0f04c137829 86 } else { // done
va009039 0:b0f04c137829 87 }
va009039 0:b0f04c137829 88 DBG_LED4(buf[1] & MJPEG_FID); // FID
va009039 0:b0f04c137829 89 }
va009039 0:b0f04c137829 90
va009039 0:b0f04c137829 91 int usb_mjpeg::status()
va009039 0:b0f04c137829 92 {
va009039 0:b0f04c137829 93 if (m_seq <= 1) {
va009039 0:b0f04c137829 94 return USBERR_PROCESSING;
va009039 0:b0f04c137829 95 }
va009039 0:b0f04c137829 96 return m_pos;
va009039 0:b0f04c137829 97 }
va009039 0:b0f04c137829 98
va009039 0:b0f04c137829 99 bool usb_mjpeg::check_SOI(uint8_t* buf, int len)
va009039 0:b0f04c137829 100 {
va009039 0:b0f04c137829 101 if (len >= (12+2)) {
va009039 0:b0f04c137829 102 if (buf[12] == 0xff && buf[13] == 0xd8) {
va009039 0:b0f04c137829 103 return true;
va009039 0:b0f04c137829 104 }
va009039 0:b0f04c137829 105 }
va009039 0:b0f04c137829 106 return false;
va009039 0:b0f04c137829 107 }
va009039 0:b0f04c137829 108
va009039 0:b0f04c137829 109 bool usb_mjpeg::check_EOI(uint8_t* buf, int len)
va009039 0:b0f04c137829 110 {
va009039 0:b0f04c137829 111 if (len >= 12) {
va009039 0:b0f04c137829 112 if (buf[1] & MJPEG_EOF) {
va009039 0:b0f04c137829 113 return true;
va009039 0:b0f04c137829 114 }
va009039 0:b0f04c137829 115 }
va009039 0:b0f04c137829 116 return false;
va009039 0:b0f04c137829 117 }
va009039 0:b0f04c137829 118
va009039 0:b0f04c137829 119 void usb_mjpeg::_open()
va009039 0:b0f04c137829 120 {
va009039 0:b0f04c137829 121 m_pos = 0;
va009039 0:b0f04c137829 122 }
va009039 0:b0f04c137829 123
va009039 0:b0f04c137829 124 void usb_mjpeg::_wrtie(uint8_t* buf, int len)
va009039 0:b0f04c137829 125 {
va009039 0:b0f04c137829 126 if (m_buf == NULL) {
va009039 0:b0f04c137829 127 return;
va009039 0:b0f04c137829 128 }
va009039 0:b0f04c137829 129 for(int i = 0; i < len && m_pos < m_size; i++) {
va009039 0:b0f04c137829 130 m_buf[m_pos++] = buf[i];
va009039 0:b0f04c137829 131 }
va009039 0:b0f04c137829 132 }
va009039 0:b0f04c137829 133
va009039 0:b0f04c137829 134 void usb_mjpeg::_close()
va009039 0:b0f04c137829 135 {
va009039 0:b0f04c137829 136 //DBG("m_pos=%d\n", m_pos);
va009039 0:b0f04c137829 137 //DBG_HEX(m_buf, m_pos);
va009039 0:b0f04c137829 138 myjpeg JPEG(m_buf, m_pos, m_size);
va009039 0:b0f04c137829 139 JPEG.analytics();
va009039 0:b0f04c137829 140 if (JPEG.DHT_pos == 0) {
va009039 0:b0f04c137829 141 m_pos = JPEG.insertDHT();
va009039 0:b0f04c137829 142 }
va009039 0:b0f04c137829 143 }