Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FatFileSystem TB6612FNG2 mbed
uvc/usb_mjpeg.cpp@0:de03cbbcd0ff, 2015-11-30 (annotated)
- Committer:
- mbed_Cookbook_SE
- Date:
- Mon Nov 30 09:32:15 2015 +0000
- Revision:
- 0:de03cbbcd0ff
??
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 1 | #include "mbed.h" |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 2 | #include "usb_mjpeg.h" |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 3 | //#define __DEBUG |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 4 | #define __DEBUG2 |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 5 | #include "mydbg.h" |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 6 | #include "Utils.h" |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 7 | #include "myjpeg.h" |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 8 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 9 | #ifdef __DEBUG |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 10 | extern DigitalOut led4; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 11 | #endif // __DEBUG |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 12 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 13 | #define MJPEG_FID 0x01 |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 14 | #define MJPEG_EOF 0x02 |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 15 | #define MJPEG_PTS 0x04 |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 16 | #define MJPEG_SCR 0x08 |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 17 | #define MJPEG_STI 0x20 |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 18 | #define MJPEG_ERR 0x40 |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 19 | #define MJPEG_EOH 0x80 |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 20 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 21 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 22 | usb_mjpeg::usb_mjpeg(uint8_t* buf, int size) |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 23 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 24 | DBG_ASSERT(size >= 1024 && size <= 16000); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 25 | m_size = size; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 26 | m_seq = 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 27 | m_buf = buf; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 28 | ReportErrorFID = 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 29 | ReportErrorPTS = 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 30 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 31 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 32 | usb_mjpeg::~usb_mjpeg() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 33 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 34 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 35 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 36 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 37 | void usb_mjpeg::input(uint16_t frame, uint8_t* buf, int len) |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 38 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 39 | uint8_t* StreamHeader = buf; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 40 | DBG_ASSERT(buf); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 41 | if (len > 12) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 42 | //DBG_PRINTF("%d %02X %d\n", frame, buf[1], len); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 43 | //DBG_HEX(buf, len); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 44 | DBG_ASSERT(StreamHeader[0] == 0x0c); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 45 | //DBG_ASSERT(buf[1] == 0x8c || buf[1] == 0x8d); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 46 | //DBG("bfh:%02X\n", buf[1]); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 47 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 48 | DBG_ASSERT(len >= 2); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 49 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 50 | int hle = StreamHeader[0]; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 51 | uint8_t bfh = StreamHeader[1]; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 52 | DBG_ASSERT(len >= hle); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 53 | DBG_ASSERT(hle == 12); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 54 | uint8_t* data = buf + hle; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 55 | int data_len = len - hle; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 56 | if (m_seq == 0) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 57 | if (check_SOI(buf, len)) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 58 | DBG_PRINTF("%04X SOI\n", frame); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 59 | DBG_BYTES("SOI", buf, 16); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 60 | _open(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 61 | m_bfh = bfh; // save FID |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 62 | if (bfh & MJPEG_PTS) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 63 | m_pts = LE32(StreamHeader+2); // save PTS |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 64 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 65 | _wrtie(data, data_len); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 66 | m_seq++; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 67 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 68 | } else if (m_seq == 1) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 69 | if (len > hle) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 70 | _wrtie(data, data_len); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 71 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 72 | if (check_EOI(buf, len)) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 73 | DBG_PRINTF("%04X EOI\n", frame); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 74 | DBG_BYTES("EOI", buf, 12); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 75 | _close(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 76 | m_seq = 2; // done |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 77 | } else if ((m_bfh ^ bfh) & MJPEG_FID) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 78 | ReportErrorFID++; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 79 | DBG("ReportErrorFID=%d\n", ReportErrorFID); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 80 | m_seq = 0; // restart |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 81 | } else if ((bfh & MJPEG_PTS) && m_pts != LE32(StreamHeader+2)) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 82 | ReportErrorPTS++; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 83 | DBG("ReportErrorPTS=%d\n", ReportErrorPTS); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 84 | m_seq = 0; // restart |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 85 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 86 | } else { // done |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 87 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 88 | DBG_LED4(buf[1] & MJPEG_FID); // FID |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 89 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 90 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 91 | int usb_mjpeg::status() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 92 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 93 | if (m_seq <= 1) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 94 | return USBERR_PROCESSING; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 95 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 96 | return m_pos; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 97 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 98 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 99 | bool usb_mjpeg::check_SOI(uint8_t* buf, int len) |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 100 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 101 | if (len >= (12+2)) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 102 | if (buf[12] == 0xff && buf[13] == 0xd8) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 103 | return true; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 104 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 105 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 106 | return false; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 107 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 108 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 109 | bool usb_mjpeg::check_EOI(uint8_t* buf, int len) |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 110 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 111 | if (len >= 12) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 112 | if (buf[1] & MJPEG_EOF) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 113 | return true; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 114 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 115 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 116 | return false; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 117 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 118 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 119 | void usb_mjpeg::_open() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 120 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 121 | m_pos = 0; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 122 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 123 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 124 | void usb_mjpeg::_wrtie(uint8_t* buf, int len) |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 125 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 126 | if (m_buf == NULL) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 127 | return; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 128 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 129 | for(int i = 0; i < len && m_pos < m_size; i++) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 130 | m_buf[m_pos++] = buf[i]; |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 131 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 132 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 133 | |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 134 | void usb_mjpeg::_close() |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 135 | { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 136 | //DBG("m_pos=%d\n", m_pos); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 137 | //DBG_HEX(m_buf, m_pos); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 138 | myjpeg JPEG(m_buf, m_pos, m_size); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 139 | JPEG.analytics(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 140 | if (JPEG.DHT_pos == 0) { |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 141 | m_pos = JPEG.insertDHT(); |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 142 | } |
| mbed_Cookbook_SE | 0:de03cbbcd0ff | 143 | } |