LogitechC270 webcam class driver alpha version

Dependencies:   USBHost mbed

Fork of USBHostMSD_HelloWorld by Samuel Mokrani

main.cpp

Committer:
va009039
Date:
2013-03-16
Revision:
9:fecabade834a
Parent:
4:f8a5c8aa895a
Child:
10:387c49b2fc7e

File content as of revision 9:fecabade834a:

// USBHostC270_HelloWorld/main.cpp
#include "mbed.h"
#include "USBHostMSD.h"
#include "USBHostC270.h"
#include "decodeMJPEG.h"
#include "MyThread.h"

#define IMAGE_BUF_SIZE (1024*3)

Serial pc(USBTX, USBRX);
DigitalOut led1(LED1),led2(LED2),led3(LED3);

struct ImageBuffer {
    int pos;
    uint8_t buf[IMAGE_BUF_SIZE];
    void clear() { pos = 0; }
    int size() { return pos; }
    uint8_t get(int pos) { return buf[pos]; } 
    void put(uint8_t c) {
        if (pos < sizeof(buf)) {
            buf[pos++] = c;
        }
    }
};

Mail<ImageBuffer, 1> mail_box;
class captureJPEG : public MyThread, public decodeMJPEG {
public:
    captureJPEG(BaseUvc* cam) : m_cam(cam) {
        m_buf = NULL;
        m_cam->setOnResult(this, &captureJPEG::callback_motion_jpeg);
    }
private:    
    virtual void outputJPEG(uint8_t c, int status) {
        if (m_buf == NULL && status == JPEG_START) {
            m_buf = mail_box.alloc();
            if (m_buf) {
                m_buf->clear();
            }
        }
        if (m_buf) {
            m_buf->put(c);
            if (status == JPEG_END) {
                mail_box.put(m_buf);
                m_buf = NULL;
                led3 = !led3;
            }
        }
    }

    void callback_motion_jpeg(uint16_t frame, uint8_t* buf, int len) {
        inputPacket(buf, len);
        led1 = buf[1]&1;    // FID
        if (buf[1]&2) {     // EOF
            led2 = !led2;
        }
    }

    virtual void run() {
        while(true) {
            if (m_cam) {
                m_cam->poll();
            }
        }
    }
    ImageBuffer* m_buf;
    BaseUvc* m_cam;
};

int main() {
    pc.baud(921600);
    printf("%s\n", __FILE__);

    USBHostMSD* msd = new USBHostMSD("usb");
    while(!msd->connect()) {
        Thread::wait(200);
    }
    

    USBHostC270* cam = new USBHostC270(C270_MJPEG, C270_160x120, _5FPS);
    while(!cam->connect()) {
        Thread::wait(200);
    }

    captureJPEG* capture = new captureJPEG(cam);
    capture->set_stack(512);
    capture->start();

    Timer t;
    t.reset();
    t.start();
    Timer interval_t;
    interval_t.reset();
    interval_t.start();
    int shot = 0;
    while(1) {
        osEvent evt = mail_box.get();
        if (evt.status == osEventMail) {
            ImageBuffer *buf = reinterpret_cast<ImageBuffer*>(evt.value.p);
            if (interval_t.read() > 10) {
                char path[32];
                snprintf(path, sizeof(path), "/usb/image%02d.jpg", shot % 100);
                printf("%d %s %d bytes\n", shot, path, buf->size());
                if (msd->connected()) {
                    FILE* fp = fopen(path, "wb");
                    if (fp) {
                        for(int i = 0; i < buf->size(); i++) {
                            fputc(buf->get(i), fp);
                        }
                        fclose(fp);
                    }
                }
                interval_t.reset();
                shot++;
            }
            mail_box.free(buf);
        }
        if (t.read() > 5) {
            printf("captureJPEG stack used: %d/%d bytes\n", capture->stack_used(), capture->stack_size());
            printf("CC:");
            for(int i = 0; i < 16; i++) {
                printf(" %u", cam->report_cc_count[i]); 
            }
            printf("\nPS:"); 
            for(int i = 0; i < 16; i++) {
                printf(" %u", cam->report_ps_cc_count[i]); 
            }
            printf("\n");
            t.reset();
        }
        if (!msd->connected()) {
            msd->connect();
        }
    }
}