Sophie

Sophie

distrib > Mandriva > current > i586 > media > contrib-release-src > by-pkgid > d736cdd43569de8d5f79fe35e35be6e1 > files > 1

vdr-plugin-streamdev-0.5.0-0.pre.20100214.1mdv2010.1.src.rpm

diff -NaurwB streamdev/Makefile streamdev-patched/Makefile
--- streamdev/Makefile	2009-11-04 12:12:20.000000000 +0100
+++ streamdev-patched/Makefile	2010-02-09 15:58:13.000000000 +0100
@@ -65,7 +65,7 @@
 	server/server.o server/component.o server/connection.o \
 	server/componentVTP.o server/componentHTTP.o server/componentIGMP.o \
 	server/connectionVTP.o server/connectionHTTP.o server/connectionIGMP.o \
-	server/streamer.o server/livestreamer.o server/livefilter.o \
+	server/streamer.o server/livestreamer.o server/livefilter.o server/recordingstreamer.o \
 	server/suspend.o server/setup.o server/menuHTTP.o server/recplayer.o \
 	remux/tsremux.o remux/ts2pes.o remux/ts2ps.o remux/ts2es.o remux/extern.o
 	
diff -NaurwB streamdev/server/connectionVTP.c streamdev-patched/server/connectionVTP.c
--- streamdev/server/connectionVTP.c	2010-01-29 13:03:02.000000000 +0100
+++ streamdev-patched/server/connectionVTP.c	2010-02-10 08:56:22.000000000 +0100
@@ -4,6 +4,7 @@
  
 #include "server/connectionVTP.h"
 #include "server/livestreamer.h"
+#include "server/recordingstreamer.h"
 #include "server/suspend.h"
 #include "setup.h"
 
@@ -741,11 +742,11 @@
 		m_FilterSocket(NULL),
 		m_FilterStreamer(NULL),
 		m_RecSocket(NULL),
+		m_RecStreamer(NULL),
 		m_DataSocket(NULL),
 		m_LastCommand(NULL),
 		m_StreamType(stTSPIDS),
 		m_FiltersSupport(false),
-		m_RecPlayer(NULL),
 		m_LSTEHandler(NULL),
 		m_LSTCHandler(NULL),
 		m_LSTTHandler(NULL),
@@ -759,6 +760,7 @@
 		free(m_LastCommand);
 	delete m_LiveStreamer;
 	delete m_LiveSocket;
+	delete m_RecStreamer;
 	delete m_RecSocket;
 	delete m_FilterStreamer;
 	delete m_FilterSocket;
@@ -767,7 +769,6 @@
 	delete m_LSTCHandler;
 	delete m_LSTEHandler;
 	delete m_LSTRHandler;
-	delete m_RecPlayer;
 }
 
 inline bool cConnectionVTP::Abort(void) const
@@ -833,9 +834,10 @@
 	if      (strcasecmp(Cmd, "CAPS") == 0) return CmdCAPS(param);
 	else if (strcasecmp(Cmd, "PROV") == 0) return CmdPROV(param);
 	else if (strcasecmp(Cmd, "PORT") == 0) return CmdPORT(param);
-	else if (strcasecmp(Cmd, "READ") == 0) return CmdREAD(param);
 	else if (strcasecmp(Cmd, "TUNE") == 0) return CmdTUNE(param);
 	else if (strcasecmp(Cmd, "PLAY") == 0) return CmdPLAY(param);
+	else if (strcasecmp(Cmd, "SEEK") == 0) return CmdSEEK(param);
+	else if (strcasecmp(Cmd, "SIZE") == 0) return CmdSIZE(param);
 	else if (strcasecmp(Cmd, "ADDP") == 0) return CmdADDP(param);
 	else if (strcasecmp(Cmd, "DELP") == 0) return CmdDELP(param);
 	else if (strcasecmp(Cmd, "ADDF") == 0) return CmdADDF(param);
@@ -1012,6 +1014,8 @@
 
 		if (!m_RecSocket->SetDSCP())
 			LOG_ERROR_STR("unable to set DSCP sockopt");
+		if(m_RecSocket)
+			m_RecStreamer->Start(m_RecSocket);
 
 		return Respond(220, "Port command ok, data connection opened");
 		break;
@@ -1034,35 +1038,6 @@
 	}
 }
 
-bool cConnectionVTP::CmdREAD(char *Opts)
-{
-	if (*Opts) {
-		char *tail;
-		uint64_t position = strtoll(Opts, &tail, 10);
-		if (tail && tail != Opts) {
-			tail = skipspace(tail);
-			if (tail && tail != Opts) {
-				int size = strtol(tail, NULL, 10);
-				uint8_t* data = (uint8_t*)malloc(size+4);
-				unsigned long count_readed = m_RecPlayer->getBlock(data, position, size);
-				unsigned long count_written = m_RecSocket->SysWrite(data, count_readed);
-
-				free(data);
-				return Respond(220, "%lu Bytes submitted", count_written);
-			}
-			else {
-				return Respond(501, "Missing position");
-			}
-		}
-		else {
-			return Respond(501, "Missing size");
-		}
-	}
-	else {
-		return Respond(501, "Missing position");
-	}
-}
-
 bool cConnectionVTP::CmdTUNE(char *Opts) 
 {
 	const cChannel *chan;
@@ -1096,27 +1071,40 @@
 
 bool cConnectionVTP::CmdPLAY(char *Opts)
 {
-	if (*Opts) {
-		if (isnumber(Opts)) {
-			cRecording *recording = Recordings.Get(strtol(Opts, NULL, 10) - 1);
-			if (recording) {
-				if (m_RecPlayer) {
-					delete m_RecPlayer;
-				}
-				m_RecPlayer = new RecPlayer(recording);
-				return Respond(220, "%llu (Bytes), %u (Frames)", (long long unsigned int) m_RecPlayer->getLengthBytes(), (unsigned int) m_RecPlayer->getLengthFrames());
-			}
-			else {
-				return Respond(550, "Recording \"%s\" not found", Opts);
-			}
-		}
-		else {
-			return Respond(500, "Use: PLAY record");
+	const cRecording *recording;
+	cDevice *dev;
+
+	if ((recording = Recordings.Get(strtol(Opts, NULL, 10) - 1)) == NULL)
+		return Respond(550, "Undefined recording \"%s\"", Opts);
+
+	delete m_RecStreamer;
+	m_RecStreamer = new cStreamdevRecStreamer(recording);
+	if(m_RecSocket)
+		m_RecStreamer->Start(m_RecSocket);
+
+	return Respond(220, "Recording opened");
 		}
+
+bool cConnectionVTP::CmdSEEK(char *Opts)
+{
+	if (m_RecStreamer)
+	{
+		uint64_t TotalBytesWritten = m_RecStreamer->getTotalBytesWritten();
+		uint64_t newPosition = atoll(Opts);
+		m_RecStreamer->seekPosition(newPosition);
+
+		return Respond(220, "%llu (TCP Stack Position) %llu (New Position)", TotalBytesWritten, newPosition);
 	}
-	else {
-		return Respond(500, "Use: PLAY record");
+
+	return Respond(550, "Curretly no record playing");
 	}
+
+bool cConnectionVTP::CmdSIZE(char *Opts)
+{
+	if (m_RecStreamer)
+		return Respond(220, "%llu (Bytes), %u (Frames)", (long long unsigned int) m_RecStreamer->getLengthBytes(), (unsigned int) m_RecStreamer->getLengthFrames());
+
+	return Respond(550, "Curretly no record playing");
 }
 
 bool cConnectionVTP::CmdADDP(char *Opts) 
@@ -1215,7 +1203,7 @@
 		DELETENULL(m_FilterSocket);
 		break;
 	case siReplay:
-		DELETENULL(m_RecPlayer);
+		DELETENULL(m_RecStreamer);
 		DELETENULL(m_RecSocket);
 		break;
 	case siDataRespond:
diff -NaurwB streamdev/server/connectionVTP.h streamdev-patched/server/connectionVTP.h
--- streamdev/server/connectionVTP.h	2009-07-01 12:46:16.000000000 +0200
+++ streamdev-patched/server/connectionVTP.h	2010-02-09 18:08:35.000000000 +0100
@@ -7,6 +7,7 @@
 class cTBSocket;
 class cStreamdevLiveStreamer;
 class cStreamdevFilterStreamer;
+class cStreamdevRecStreamer;
 class cLSTEHandler;
 class cLSTCHandler;
 class cLSTTHandler;
@@ -24,12 +25,12 @@
 	cTBSocket                *m_FilterSocket;
 	cStreamdevFilterStreamer *m_FilterStreamer;
 	cTBSocket                *m_RecSocket;
+	cStreamdevRecStreamer    *m_RecStreamer;
 	cTBSocket                *m_DataSocket;
 
 	char                   *m_LastCommand;
 	eStreamType             m_StreamType;
 	bool                    m_FiltersSupport;
-	RecPlayer              *m_RecPlayer;
 
 	// Members adopted for SVDRP
 	cLSTEHandler *m_LSTEHandler;
@@ -56,9 +57,10 @@
 	bool CmdCAPS(char *Opts);
 	bool CmdPROV(char *Opts);
 	bool CmdPORT(char *Opts);
-	bool CmdREAD(char *Opts);
 	bool CmdTUNE(char *Opts);
 	bool CmdPLAY(char *Opts);
+	bool CmdSEEK(char *Opts);
+	bool CmdSIZE(char *Opts);
 	bool CmdADDP(char *Opts);
 	bool CmdDELP(char *Opts);
 	bool CmdADDF(char *Opts);
diff -NaurwB streamdev/server/recordingstreamer.c streamdev-patched/server/recordingstreamer.c
--- streamdev/server/recordingstreamer.c	1970-01-01 01:00:00.000000000 +0100
+++ streamdev-patched/server/recordingstreamer.c	2010-02-10 08:58:01.000000000 +0100
@@ -0,0 +1,89 @@
+#include <vdr/recording.h>
+
+#include "tools/socket.h"
+#include "tools/select.h"
+
+#include "server/recordingstreamer.h"
+#include "recplayer.h"
+#include "common.h"
+
+// --- cStreamdevRecStreamer -------------------------------------------------
+
+cStreamdevRecStreamer::cStreamdevRecStreamer(const cRecording *Recording):
+		cThread("streamdev-recordingstreaming"),
+		m_Recording(Recording),
+		m_RecPlayer(new cRecPlayer(Recording)),
+		m_Position(0),
+		m_TotalBytesWritten(0)
+{
+}
+
+cStreamdevRecStreamer::~cStreamdevRecStreamer()
+{
+	Dprintf("Desctructing Recording streamer\n");
+	Stop();
+
+	DELETENULL(m_RecPlayer);
+}
+
+void cStreamdevRecStreamer::Start(cTBSocket *Socket)
+{
+	Dprintf("start streamer\n");
+	m_Socket = Socket;
+	cThread::Start();
+}
+
+void cStreamdevRecStreamer::Stop(void)
+{
+	if (Running()) {
+		Dprintf("stopping streamer\n");
+		Cancel(3);
+	}
+}
+
+uint64_t cStreamdevRecStreamer::getLengthBytes()
+{
+	return m_RecPlayer->getLengthBytes();
+}
+
+uint32_t cStreamdevRecStreamer::getLengthFrames()
+{
+	return m_RecPlayer->getLengthFrames();
+}
+
+void cStreamdevRecStreamer::seekPosition(uint64_t position)
+{
+	m_Position = position;
+}
+
+void cStreamdevRecStreamer::Action(void)
+{
+	cTBSelect sel;
+	uint8_t data[32768];
+	Dprintf("Writer start\n");
+
+	sel.Clear();
+	sel.Add(*m_Socket, true);
+	while (Running()) {
+
+		if (sel.Select(15000) == -1) {
+			esyslog("ERROR: streamdev-server: couldn't send recording data: %m");
+			continue; /* Continue here instead of break, the recording playback can be paused */
+		}
+
+		if (sel.CanWrite(*m_Socket)) {
+			int written;
+			unsigned long readed = m_RecPlayer->getBlock(&*data, m_Position, sizeof(data));
+			if (readed <= 0)
+				continue;
+
+			if ((written = m_Socket->Write(&*data, readed)) == -1) {
+				esyslog("ERROR: streamdev-server: couldn't send %d bytes: %m", written);
+				break;
+			}
+
+			m_Position += written;
+			m_TotalBytesWritten += written;
+		}
+	}
+}
diff -NaurwB streamdev/server/recordingstreamer.h streamdev-patched/server/recordingstreamer.h
--- streamdev/server/recordingstreamer.h	1970-01-01 01:00:00.000000000 +0100
+++ streamdev-patched/server/recordingstreamer.h	2010-02-10 08:58:13.000000000 +0100
@@ -0,0 +1,38 @@
+#ifndef VDR_STREAMDEV_RECORDINGSTREAMER_H
+#define VDR_STREAMDEV_RECORDINGSTREAMER_H
+
+#include <vdr/thread.h>
+#include <vdr/config.h>
+#include <vdr/receiver.h>
+
+#include "common.h"
+
+class cRecording;
+class cRecPlayer;
+
+// --- cStreamdevRecStreamer -------------------------------------------------
+
+class cStreamdevRecStreamer: public cThread  {
+private:
+	const cRecording       *m_Recording;
+	cRecPlayer             *m_RecPlayer;
+	cTBSocket              *m_Socket;
+	uint64_t                m_Position;
+	uint64_t                m_TotalBytesWritten;
+
+protected:
+	virtual void Action(void);
+
+public:
+	cStreamdevRecStreamer(const cRecording *Recording);
+	virtual ~cStreamdevRecStreamer();
+
+	void Start(cTBSocket *Socket);
+	void Stop(void);
+	uint64_t getTotalBytesWritten() { return m_TotalBytesWritten; }
+	uint64_t getLengthBytes();
+	uint32_t getLengthFrames();
+	void seekPosition(uint64_t position);
+};
+
+#endif // VDR_STREAMDEV_RECORDINGSTREAMER_H
diff -NaurwB streamdev/server/recplayer.c streamdev-patched/server/recplayer.c
--- streamdev/server/recplayer.c	2009-07-01 13:00:49.000000000 +0200
+++ streamdev-patched/server/recplayer.c	2010-02-10 08:24:01.000000000 +0100
@@ -24,7 +24,7 @@
 #define _XOPEN_SOURCE 600
 #include <fcntl.h>
 
-RecPlayer::RecPlayer(cRecording* rec)
+cRecPlayer::cRecPlayer(const cRecording* rec)
 {
   file = NULL;
   fileOpen = 0;
@@ -44,7 +44,7 @@
   scan();
 }
 
-void RecPlayer::scan()
+void cRecPlayer::scan()
 {
   if (file) fclose(file);
   totalLength = 0;
@@ -60,7 +60,7 @@
 
 #if APIVERSNUM < 10703
     snprintf(fileName, 2047, "%s/%03i.vdr", recording->FileName(), i);
-    //log->log("RecPlayer", Log::DEBUG, "FILENAME: %s", fileName);
+    //log->log("cRecPlayer", Log::DEBUG, "FILENAME: %s", fileName);
     file = fopen(fileName, "r");
 #else
     snprintf(fileName, 2047, "%s/%05i.ts", recording->FileName(), i);
@@ -77,7 +77,7 @@
     fseek(file, 0, SEEK_END);
     totalLength += ftell(file);
     totalFrames = indexFile->Last();
-    //log->log("RecPlayer", Log::DEBUG, "File %i found, totalLength now %llu, numFrames = %lu", i, totalLength, totalFrames);
+    //log->log("cRecPlayer", Log::DEBUG, "File %i found, totalLength now %llu, numFrames = %lu", i, totalLength, totalFrames);
     segments[i]->end = totalLength;
     fclose(file);
   }
@@ -85,15 +85,15 @@
   file = NULL;
 }
 
-RecPlayer::~RecPlayer()
+cRecPlayer::~cRecPlayer()
 {
-  //log->log("RecPlayer", Log::DEBUG, "destructor");
+  //log->log("cRecPlayer", Log::DEBUG, "destructor");
   int i = 1;
   while(segments[i++]) delete segments[i];
   if (file) fclose(file);
 }
 
-int RecPlayer::openFile(int index)
+int cRecPlayer::openFile(int index)
 {
   if (file) fclose(file);
 
@@ -113,7 +113,7 @@
 
   snprintf(fileName, 2047, "%s/%03i.vdr", recording->FileName(), index);
   isyslog("openFile called for index %i string:%s", index, fileName);
-  //log->log("RecPlayer", Log::DEBUG, "openFile called for index %i string:%s", index, fileName);
+  //log->log("cRecPlayer", Log::DEBUG, "openFile called for index %i string:%s", index, fileName);
 
   file = fopen(fileName, "r");
   if (file)
@@ -122,38 +122,58 @@
     return 1;
   }
 
-  //log->log("RecPlayer", Log::DEBUG, "file failed to open");
+  //log->log("cRecPlayer", Log::DEBUG, "file failed to open");
   fileOpen = 0;
   return 0;
 }
 
-uint64_t RecPlayer::getLengthBytes()
+uint64_t cRecPlayer::getLengthBytes()
 {
+  int totalLength = 0;
+  char fileName[2048];
+  struct stat st;
+
+  for(int i = 1; i < 1000; i++)
+  {
+#if APIVERSNUM < 10703
+    snprintf(fileName, 2047, "%s/%03i.vdr", recording->FileName(), i);
+#else
+    snprintf(fileName, 2047, "%s/%05i.ts", recording->FileName(), i);
+    if (stat(fileName, &st) < 0) {
+      snprintf(fileName, 2047, "%s/%03i.vdr", recording->FileName(), i);
+    }
+#endif
+
+    if (stat(fileName, &st) == 0) {
+      totalLength += st.st_size;
+    }
+  }
+
   return totalLength;
 }
 
-uint32_t RecPlayer::getLengthFrames()
+uint32_t cRecPlayer::getLengthFrames()
 {
   return totalFrames;
 }
 
-unsigned long RecPlayer::getBlock(unsigned char* buffer, uint64_t position, unsigned long amount)
+unsigned long cRecPlayer::getBlock(uint8_t* buffer, uint64_t position, unsigned long amount)
 {
   if ((amount > totalLength) || (amount > 500000))
   {
-    //log->log("RecPlayer", Log::DEBUG, "Amount %lu requested and rejected", amount);
+    //log->log("cRecPlayer", Log::DEBUG, "Amount %lu requested and rejected", amount);
     return 0;
   }
 
   if (position >= totalLength)
   {
-    //log->log("RecPlayer", Log::DEBUG, "Client asked for data starting past end of recording!");
+    //log->log("cRecPlayer", Log::DEBUG, "Client asked for data starting past end of recording!");
     return 0;
   }
 
   if ((position + amount) > totalLength)
   {
-    //log->log("RecPlayer", Log::DEBUG, "Client asked for some data past the end of recording, adjusting amount");
+    //log->log("cRecPlayer", Log::DEBUG, "Client asked for some data past the end of recording, adjusting amount");
     amount = totalLength - position;
   }
 
@@ -208,17 +228,17 @@
   return got;
 }
 
-uint64_t RecPlayer::getLastPosition()
+uint64_t cRecPlayer::getLastPosition()
 {
   return lastPosition;
 }
 
-cRecording* RecPlayer::getCurrentRecording()
+const cRecording* cRecPlayer::getCurrentRecording()
 {
   return recording;
 }
 
-uint64_t RecPlayer::positionFromFrameNumber(uint32_t frameNumber)
+uint64_t cRecPlayer::positionFromFrameNumber(uint32_t frameNumber)
 {
   if (!indexFile) return 0;
 
@@ -235,21 +255,21 @@
     return 0;
   }
 
-//  log->log("RecPlayer", Log::DEBUG, "FN: %u FO: %i", retFileNumber, retFileOffset);
+//  log->log("cRecPlayer", Log::DEBUG, "FN: %u FO: %i", retFileNumber, retFileOffset);
   if (!segments[retFileNumber]) return 0;
   uint64_t position = segments[retFileNumber]->start + retFileOffset;
-//  log->log("RecPlayer", Log::DEBUG, "Pos: %llu", position);
+//  log->log("cRecPlayer", Log::DEBUG, "Pos: %llu", position);
 
   return position;
 }
 
-uint32_t RecPlayer::frameNumberFromPosition(uint64_t position)
+uint32_t cRecPlayer::frameNumberFromPosition(uint64_t position)
 {
   if (!indexFile) return 0;
 
   if (position >= totalLength)
   {
-    //log->log("RecPlayer", Log::DEBUG, "Client asked for data starting past end of recording!");
+    //log->log("cRecPlayer", Log::DEBUG, "Client asked for data starting past end of recording!");
     return 0;
   }
 
@@ -265,7 +285,7 @@
 }
 
 
-bool RecPlayer::getNextIFrame(uint32_t frameNumber, uint32_t direction, uint64_t* rfilePosition, uint32_t* rframeNumber, uint32_t* rframeLength)
+bool cRecPlayer::getNextIFrame(uint32_t frameNumber, uint32_t direction, uint64_t* rfilePosition, uint32_t* rframeNumber, uint32_t* rframeLength)
 {
   // 0 = backwards
   // 1 = forwards
@@ -276,7 +296,7 @@
   int indexReturnFrameNumber;
 
   indexReturnFrameNumber = (uint32_t)indexFile->GetNextIFrame(frameNumber, (direction==1 ? true : false), NULL, NULL, &iframeLength);
-  //log->log("RecPlayer", Log::DEBUG, "GNIF input framenumber:%lu, direction=%lu, output:framenumber=%i, framelength=%i", frameNumber, direction, indexReturnFrameNumber, iframeLength);
+  //log->log("cRecPlayer", Log::DEBUG, "GNIF input framenumber:%lu, direction=%lu, output:framenumber=%i, framelength=%i", frameNumber, direction, indexReturnFrameNumber, iframeLength);
 
   if (indexReturnFrameNumber == -1) return false;
 
diff -NaurwB streamdev/server/recplayer.h streamdev-patched/server/recplayer.h
--- streamdev/server/recplayer.h	2009-07-01 13:00:49.000000000 +0200
+++ streamdev-patched/server/recplayer.h	2010-02-09 17:18:23.000000000 +0100
@@ -33,24 +33,24 @@
     uint64_t end;
 };
 
-class RecPlayer
+class cRecPlayer
 {
   public:
-    RecPlayer(cRecording* rec);
-    ~RecPlayer();
+    cRecPlayer(const cRecording* rec);
+    ~cRecPlayer();
     uint64_t getLengthBytes();
     uint32_t getLengthFrames();
-    unsigned long getBlock(unsigned char* buffer, uint64_t position, unsigned long amount);
+    unsigned long getBlock(uint8_t* buffer, uint64_t position, unsigned long amount);
     int openFile(int index);
     uint64_t getLastPosition();
-    cRecording* getCurrentRecording();
+    const cRecording* getCurrentRecording();
     void scan();
     uint64_t positionFromFrameNumber(uint32_t frameNumber);
     uint32_t frameNumberFromPosition(uint64_t position);
     bool getNextIFrame(uint32_t frameNumber, uint32_t direction, uint64_t* rfilePosition, uint32_t* rframeNumber, uint32_t* rframeLength);
 
   private:
-    cRecording* recording;
+    const cRecording* recording;
     cIndexFile* indexFile;
     FILE* file;
     int fileOpen;