| 1 | /* --------------------------------------------------------------------------- |
| 2 | ** This software is in the public domain, furnished "as is", without technical |
| 3 | ** support, and with no warranty, express or implied, as to its usefulness for |
| 4 | ** any purpose. |
| 5 | ** |
| 6 | ** V4l2DeviceSource.h |
| 7 | ** |
| 8 | ** V4L2 live555 source |
| 9 | ** |
| 10 | ** -------------------------------------------------------------------------*/ |
| 11 | |
| 12 | |
| 13 | #ifndef DEVICE_SOURCE |
| 14 | #define DEVICE_SOURCE |
| 15 | |
| 16 | #include <string> |
| 17 | #include <list> |
| 18 | #include <iostream> |
| 19 | #include <iomanip> |
| 20 | |
| 21 | #include <pthread.h> |
| 22 | |
| 23 | // live555 |
| 24 | #include <liveMedia.hh> |
| 25 | |
| 26 | #include "DeviceInterface.h" |
| 27 | |
| 28 | class V4L2DeviceSource: public FramedSource |
| 29 | { |
| 30 | public: |
| 31 | // --------------------------------- |
| 32 | // Captured frame |
| 33 | // --------------------------------- |
| 34 | struct Frame |
| 35 | { |
| 36 | Frame(char* buffer, int size, timeval timestamp) : m_buffer(buffer), m_size(size), m_timestamp(timestamp) {}; |
| 37 | Frame(const Frame&); |
| 38 | Frame& operator=(const Frame&); |
| 39 | ~Frame() { delete [] m_buffer; }; |
| 40 | |
| 41 | char* m_buffer; |
| 42 | unsigned int m_size; |
| 43 | timeval m_timestamp; |
| 44 | }; |
| 45 | |
| 46 | // --------------------------------- |
| 47 | // Compute simple stats |
| 48 | // --------------------------------- |
| 49 | class Stats |
| 50 | { |
| 51 | public: |
| 52 | Stats(const std::string & msg) : m_fps(0), m_fps_sec(0), m_size(0), m_msg(msg) {}; |
| 53 | |
| 54 | public: |
| 55 | int notify(int tv_sec, int framesize); |
| 56 | |
| 57 | protected: |
| 58 | int m_fps; |
| 59 | int m_fps_sec; |
| 60 | int m_size; |
| 61 | const std::string m_msg; |
| 62 | }; |
| 63 | |
| 64 | public: |
| 65 | static V4L2DeviceSource* createNew(UsageEnvironment& env, DeviceInterface * device, int outputFd, unsigned int queueSize, bool useThread) ; |
| 66 | std::string getAuxLine() { return m_auxLine; }; |
| 67 | void setAuxLine(const std::string auxLine) { m_auxLine = auxLine; }; |
| 68 | int getWidth() { return m_device->getWidth(); }; |
| 69 | int getHeight() { return m_device->getHeight(); }; |
| 70 | int getCaptureFormat() { return m_device->getCaptureFormat(); }; |
| 71 | |
| 72 | protected: |
| 73 | V4L2DeviceSource(UsageEnvironment& env, DeviceInterface * device, int outputFd, unsigned int queueSize, bool useThread); |
| 74 | virtual ~V4L2DeviceSource(); |
| 75 | |
| 76 | protected: |
| 77 | static void* threadStub(void* clientData) { return ((V4L2DeviceSource*) clientData)->thread();}; |
| 78 | void* thread(); |
| 79 | static void deliverFrameStub(void* clientData) {((V4L2DeviceSource*) clientData)->deliverFrame();}; |
| 80 | void deliverFrame(); |
| 81 | static void incomingPacketHandlerStub(void* clientData, int mask) { ((V4L2DeviceSource*) clientData)->incomingPacketHandler(); }; |
| 82 | void incomingPacketHandler(); |
| 83 | int getNextFrame(); |
| 84 | void processFrame(char * frame, int frameSize, const timeval &ref); |
| 85 | void queueFrame(char * frame, int frameSize, const timeval &tv); |
| 86 | |
| 87 | // split packet in frames |
| 88 | virtual std::list< std::pair<unsigned char*,size_t> > splitFrames(unsigned char* frame, unsigned frameSize); |
| 89 | |
| 90 | // overide FramedSource |
| 91 | virtual void doGetNextFrame(); |
| 92 | virtual void doStopGettingFrames(); |
| 93 | |
| 94 | protected: |
| 95 | std::list<Frame*> m_captureQueue; |
| 96 | Stats m_in; |
| 97 | Stats m_out; |
| 98 | EventTriggerId m_eventTriggerId; |
| 99 | int m_outfd; |
| 100 | DeviceInterface * m_device; |
| 101 | unsigned int m_queueSize; |
| 102 | pthread_t m_thid; |
| 103 | pthread_mutex_t m_mutex; |
| 104 | std::string m_auxLine; |
| 105 | }; |
| 106 | |
| 107 | #endif |
| 108 | |