diff options
Diffstat (limited to 'receiver')
-rw-r--r-- | receiver/filehandle.h | 90 | ||||
-rw-r--r-- | receiver/livereceiver.cpp | 28 | ||||
-rw-r--r-- | receiver/livereceiver.h | 66 | ||||
-rw-r--r-- | receiver/recplayer.cpp | 10 | ||||
-rw-r--r-- | receiver/recplayer.h | 18 |
5 files changed, 186 insertions, 26 deletions
diff --git a/receiver/filehandle.h b/receiver/filehandle.h index 37f06e8..1dc57bf 100644 --- a/receiver/filehandle.h +++ b/receiver/filehandle.h @@ -11,12 +11,94 @@ #include <upnp/upnp.h> #include "../common.h" +/** + * Interface for File Handles + * + * This class is a pure virtual class to act as an interface for file handles + * used by the webserver. + */ class cFileHandle { public: - virtual void open(UpnpOpenFileMode mode) = 0; - virtual int read(char* buf, size_t buflen) = 0; - virtual int write(char* buf, size_t buflen) = 0; - virtual int seek(off_t offset, int whence) = 0; + /** + * Opens the file + * + * Opens the file at the given mode. These can be: + * - \b UPNP_READ, to read from the file + * - \b UPNP_WRITE, to write to the file + * + * @param mode The file mode, i.e. one of the following + * - \b UPNP_READ + * - \b UPNP_WRITE + */ + virtual void open( + UpnpOpenFileMode mode ///< The file mode, i.e. one of the following + ///< - \b UPNP_READ + ///< - \b UPNP_WRITE + ) = 0; + /** + * Reads from the file + * + * Reads from the file a certain amount of bytes and stores them in a buffer + * + * @return returns + * - \b <0, in case of an error + * - \b 0, when reading was successful + * + * @param buf The char buffer + * @param buflen The size of the buffer + */ + virtual int read( + char* buf, ///< The char buffer + size_t buflen ///< The size of the buffer + ) = 0; + /** + * Writes to the file + * + * Writes to the file a certain amount of bytes which are stored in a buffer + * + * @return returns + * - \b <0, in case of an error + * - \b 0, when reading was successful + * + * @param buf The char buffer + * @param buflen The size of the buffer + */ + virtual int write( + char* buf, ///< The char buffer + size_t buflen ///< The size of the buffer + ) = 0; + /** + * Seeks in the file + * + * Seeks in the file where the offset is the relativ position depending on + * the second parameter. This means, in case of + * + * - \b SEEK_SET, the offset is relative to the beginning of the file + * - \b SEEK_CUR, it is relative to the current position or + * - \b SEEK_END, relative to the end of the file. + * + * @return returns + * - \b <0, in case of an error + * - \b 0, when reading was successful + * + * @param offset The byte offset in the file + * @param whence one of the following + * - \b SEEK_SET, + * - \b SEEK_CUR, + * - \b SEEK_END + */ + virtual int seek( + off_t offset, ///< The byte offset in the file + int whence ///< one of the following + ///< - \b SEEK_SET, + ///< - \b SEEK_CUR, + ///< - \b SEEK_END + ) = 0; + /** + * Closes the open file + * + * This will close open file handles and frees the memory obtained by it. + */ virtual void close() = 0; virtual ~cFileHandle(){}; private: diff --git a/receiver/livereceiver.cpp b/receiver/livereceiver.cpp index 189f4a4..8ca560f 100644 --- a/receiver/livereceiver.cpp +++ b/receiver/livereceiver.cpp @@ -22,7 +22,7 @@ cLiveReceiver* cLiveReceiver::newInstance(cChannel* Channel, int Priority){ cLiveReceiver *Receiver = new cLiveReceiver(Channel, Device); if(Receiver){ - MESSAGE("Receiver for channel \"%s\" created successfully.", Channel->Name()); + MESSAGE(VERBOSE_SDK, "Receiver for channel \"%s\" created successfully.", Channel->Name()); return Receiver; } else { @@ -62,13 +62,13 @@ void cLiveReceiver::open(UpnpOpenFileMode){ void cLiveReceiver::Activate(bool On){ if(On){ this->Start(); - MESSAGE("Live receiver started."); + MESSAGE(VERBOSE_LIVE_TV, "Live receiver started."); } else { if(this->Running()){ this->Cancel(2); } - MESSAGE("Live receiver stopped"); + MESSAGE(VERBOSE_LIVE_TV, "Live receiver stopped"); } } @@ -82,20 +82,20 @@ void cLiveReceiver::Receive(uchar* Data, int Length){ } void cLiveReceiver::Action(void){ - MESSAGE("Started buffering..."); + MESSAGE(VERBOSE_LIVE_TV, "Started buffering..."); while(this->Running()){ int bytesRead; - //MESSAGE("Buffer is filled with %d bytes", this->mLiveBuffer->Available()); + MESSAGE(VERBOSE_BUFFERS, "Buffer is filled with %d bytes", this->mLiveBuffer->Available()); uchar* bytes = this->mLiveBuffer->Get(bytesRead); if(bytes){ int count = this->mFrameDetector->Analyze(bytes, bytesRead); if(count){ - //MESSAGE("%d bytes analyzed", count); - //MESSAGE("%2.2f FPS", this->mFrameDetector->FramesPerSecond()); + MESSAGE(VERBOSE_BUFFERS, "%d bytes analyzed", count); + MESSAGE(VERBOSE_BUFFERS, "%2.2f FPS", this->mFrameDetector->FramesPerSecond()); if(!this->Running() && this->mFrameDetector->IndependentFrame()) break; if(this->mFrameDetector->Synced()){ - //MESSAGE("Frame detector synced to data stream"); + MESSAGE(VERBOSE_BUFFERS, "Frame detector synced to data stream"); if(this->mFrameDetector->IndependentFrame()){ this->mOutputBuffer->Put(this->mPatPmtGenerator.GetPat(), TS_SIZE); int i = 0; @@ -107,7 +107,7 @@ void cLiveReceiver::Action(void){ if(bytesWrote != count){ this->mLiveBuffer->ReportOverflow(count - bytesWrote); } - //MESSAGE("Wrote %d to output buffer", bytesWrote); + MESSAGE(VERBOSE_BUFFERS, "Wrote %d to output buffer", bytesWrote); if(bytesWrote){ this->mLiveBuffer->Del(bytesWrote); } @@ -121,7 +121,7 @@ void cLiveReceiver::Action(void){ } } } - MESSAGE("Receiver was detached from device"); + MESSAGE(VERBOSE_LIVE_TV, "Receiver was detached from device"); } int cLiveReceiver::read(char* buf, size_t buflen){ @@ -135,7 +135,7 @@ int cLiveReceiver::read(char* buf, size_t buflen){ WARNING("Too few data, waiting..."); cCondWait::SleepMs(RECEIVER_WAIT_ON_NODATA); if(!this->IsAttached()){ - MESSAGE("Lost device..."); + MESSAGE(VERBOSE_LIVE_TV, "Lost device..."); return 0; } WaitTimeout-=RECEIVER_WAIT_ON_NODATA; @@ -160,7 +160,7 @@ int cLiveReceiver::read(char* buf, size_t buflen){ } } - MESSAGE("Read %d bytes from live feed", bytesRead); + MESSAGE(VERBOSE_BUFFERS, "Read %d bytes from live feed", bytesRead); return bytesRead; } @@ -175,10 +175,10 @@ int cLiveReceiver::write(char*, size_t){ } void cLiveReceiver::close(){ - MESSAGE("Closing live receiver"); + MESSAGE(VERBOSE_SDK, "Closing live receiver"); this->Detach(); delete this->mOutputBuffer; this->mOutputBuffer = NULL; delete this->mLiveBuffer; this->mLiveBuffer = NULL; this->mFrameDetector = NULL; - MESSAGE("Live receiver closed."); + MESSAGE(VERBOSE_LIVE_TV, "Live receiver closed."); }
\ No newline at end of file diff --git a/receiver/livereceiver.h b/receiver/livereceiver.h index 6b04619..92fe140 100644 --- a/receiver/livereceiver.h +++ b/receiver/livereceiver.h @@ -17,18 +17,78 @@ #define RECEIVER_WAIT_ON_NODATA 50 // 50 ms #define RECEIVER_WAIT_ON_NODATA_TIMEOUT 1000 * 2 // 2s +/** + * A receiver for live TV + * + * This is a receiver object which is attached to a VDR tv card device. + * It is receiving transport stream packages and generates a single MPEG2 + * transport stream which can be distributed through the network. + * + */ class cLiveReceiver : public cReceiver, public cThread, public cFileHandle { public: - static cLiveReceiver* newInstance(cChannel *Channel, int Priority); + /** + * Creates a new receiver instance + * + * This will create a new instance of a live receiver for the specified + * channel at the specified priority level. + * + * A negativ priority means that the receiver may being detached from a + * device. + * + * The receiver must be free'd with delete after it is not used anylonger. + * + * @return returns a new liveReceiver instance + */ + static cLiveReceiver* newInstance( + cChannel *Channel, ///< the channel which shall be tuned + int Priority ///< the priority level + ); virtual ~cLiveReceiver(void); + /*! @copydoc cFileHandle::open(UpnpOpenFileMode) */ virtual void open(UpnpOpenFileMode mode); + /*! @copydoc cFileHandle::read(char*,size_t) */ virtual int read(char* buf, size_t buflen); + /*! @copydoc cFileHandle::write(char*,size_t) */ virtual int write(char* buf, size_t buflen); + /*! @copydoc cFileHandle::seek(off_t,int) */ virtual int seek(off_t offset, int whence); + /*! @copydoc cFileHandle::close() */ virtual void close(); protected: - virtual void Receive(uchar *Data, int Length); - virtual void Activate(bool On); + /** + * Receives data from VDR + * + * This is the interface for receiving packet data from the VDR. It buffers + * the incoming transport stream packets in a linear ringbuffer and returns + * immediatelly + */ + virtual void Receive( + uchar *Data, ///< The data received from VDR + int Length ///< The length of the data packet, usually 188 bytes + ); + /** + * Activates the receiver + * + * This activates the receiver which initializes internal data structures to + * be prepared for receiving data from the VDR + * + * If the parameter is \bc true, the receiver will be activated. If it is + * \bc false, the receiver will be deactivated and stops its threads. + */ + virtual void Activate( + bool On ///< Activates the receiver thread + ); + /** + * The receiver thread action + * + * This actually is the receiver thread, which runs consequitivelly and + * buffers any received video data from the interal incoming buffer to the + * internal outgoing buffer. + * + * While doing so, it tries to syncronize with the stream and creates new + * MPEG2-TS PATs and PMTs for a single MPEG2-TS stream + */ virtual void Action(void); private: cLiveReceiver(cChannel *Channel, cDevice *Device); diff --git a/receiver/recplayer.cpp b/receiver/recplayer.cpp index d968ae7..a9ea85b 100644 --- a/receiver/recplayer.cpp +++ b/receiver/recplayer.cpp @@ -25,7 +25,7 @@ cRecordingPlayer::~cRecordingPlayer() { } cRecordingPlayer::cRecordingPlayer(cRecording *Recording) { - MESSAGE("Created Recplayer"); + MESSAGE(VERBOSE_SDK, "Created Recplayer"); this->mFile = NULL; this->mTotalLenght = 0; this->mRecording = Recording; @@ -118,11 +118,11 @@ int cRecordingPlayer::seek(off_t offset, int origin){ } void cRecordingPlayer::Scan(){ - MESSAGE("Scanning video files..."); + MESSAGE(VERBOSE_RECORDS, "Scanning video files..."); // Reset the offsets int i = 1; while(this->mOffsets[i++]) this->mOffsets[i] = 0; - MESSAGE("Offsets reseted."); + MESSAGE(VERBOSE_RECORDS, "Offsets reseted."); i = 0; FILE *File; @@ -133,7 +133,7 @@ void cRecordingPlayer::Scan(){ } fseek(File, 0, SEEK_END); off_t offset = ftell(File); - MESSAGE("File %d has its last offset at %ld", i, offset); + MESSAGE(VERBOSE_RECORDS, "File %d has its last offset at %ld", i, offset); this->mOffsets[i+1] = this->mOffsets[i] + offset; this->mTotalLenght = this->mOffsets[i+1]; i++; @@ -150,7 +150,7 @@ FILE *cRecordingPlayer::GetFile(int Index){ if(this->mFile) fclose(this->mFile); char *filename = new char[VDR_FILENAME_BUFSIZE]; snprintf(filename, VDR_FILENAME_BUFSIZE, VDR_RECORDFILE_PATTERN_TS, this->mRecording->FileName(), Index ); - MESSAGE("Filename: %s", filename); + MESSAGE(VERBOSE_BUFFERS, "Filename: %s", filename); this->mFile = NULL; if(this->mFile = fopen(filename, "r")){ this->mIndex = Index; diff --git a/receiver/recplayer.h b/receiver/recplayer.h index 8295539..a2e69ac 100644 --- a/receiver/recplayer.h +++ b/receiver/recplayer.h @@ -12,8 +12,26 @@ #include "filehandle.h" #include <vdr/recording.h> +/** + * The recording player + * + * This class provides the ability to play VDR records. The difference between + * usual files and VDR recording files is, that recordings are possibly splitted + * into multiple files. The class will scan those files and tries to dynamically + * navigate in them like it would do, if it is a single file. + * + */ class cRecordingPlayer : cFileHandle { public: + /** + * Get a new instance of a recording player + * + * This returns a new instance of a recording player which plays the + * specified VDR recording. + * + * @param Recording the recording to play + * @return the new instance of the recording player + */ static cRecordingPlayer *newInstance(cRecording *Recording); virtual ~cRecordingPlayer(); virtual void open(UpnpOpenFileMode mode); |