summaryrefslogtreecommitdiff
path: root/receiver
diff options
context:
space:
mode:
Diffstat (limited to 'receiver')
-rw-r--r--receiver/filehandle.h90
-rw-r--r--receiver/livereceiver.cpp28
-rw-r--r--receiver/livereceiver.h66
-rw-r--r--receiver/recplayer.cpp10
-rw-r--r--receiver/recplayer.h18
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);