Index: DirectShowFilters/MPWriter/source/MPFileWriter.cpp
===================================================================
--- DirectShowFilters/MPWriter/source/MPFileWriter.cpp	(revision 27233)
+++ DirectShowFilters/MPWriter/source/MPFileWriter.cpp	(working copy)
@@ -564,6 +564,12 @@
 	if (pSubChannel==NULL) return S_OK;
 	return pSubChannel->SetTimeShiftParams(minFiles, maxFiles,maxFileSize);
 }
+STDMETHODIMP CMPFileWriter::SetChannelType(int subChannelId, int channelType)
+{
+	CSubChannel* pSubChannel=GetSubChannel(subChannelId);
+	if (pSubChannel==NULL) return S_OK;
+	return pSubChannel->SetChannelType(channelType);
+}
 STDMETHODIMP CMPFileWriter::StartTimeShifting(int subChannelId)
 {
 	CSubChannel* pSubChannel=GetSubChannel(subChannelId);
Index: DirectShowFilters/MPWriter/source/MPFileWriter.h
===================================================================
--- DirectShowFilters/MPWriter/source/MPFileWriter.h	(revision 27233)
+++ DirectShowFilters/MPWriter/source/MPFileWriter.h	(working copy)
@@ -46,6 +46,7 @@
 	STDMETHOD(IsReceiving)(THIS_ BOOL* yesNo)PURE;
 	STDMETHOD(Reset)(THIS_)PURE;
 	STDMETHOD(SetTimeShiftFileName)(THIS_ int subChannelId, char* pszFileName)PURE;
+	STDMETHOD(SetChannelType)(THIS_ int subChannelId, int channelType)PURE;
 	STDMETHOD(StartTimeShifting)(THIS_ int subChannelId)PURE;
 	STDMETHOD(StopTimeShifting)(THIS_ int subChannelId)PURE;
 	STDMETHOD(PauseTimeShifting)(THIS_ int subChannelId, int onOff)PURE;
@@ -147,6 +148,7 @@
 	STDMETHODIMP Reset();
 
 	STDMETHODIMP SetTimeShiftFileName(int subChannelId, char* pszFileName);
+	STDMETHODIMP SetChannelType(int subChannelId, int channelType);
 	STDMETHODIMP StartTimeShifting(int subChannelId);
 	STDMETHODIMP StopTimeShifting(int subChannelId);
 	STDMETHODIMP PauseTimeShifting(int subChannelId, int onOff);
Index: DirectShowFilters/MPWriter/source/MultiFileWriter.cpp
===================================================================
--- DirectShowFilters/MPWriter/source/MultiFileWriter.cpp	(revision 27233)
+++ DirectShowFilters/MPWriter/source/MultiFileWriter.cpp	(working copy)
@@ -408,12 +408,19 @@
 
 	// Write current position of most recent file.
 	__int64 currentPointer = m_pCurrentTSFile->GetFilePointer();
-	WriteFile(m_hTSBufferFile, &currentPointer, sizeof(currentPointer), &written, NULL);
 
-	// Write filesAdded and filesRemoved values
-	WriteFile(m_hTSBufferFile, &m_filesAdded, sizeof(m_filesAdded), &written, NULL);
-	WriteFile(m_hTSBufferFile, &m_filesRemoved, sizeof(m_filesRemoved), &written, NULL);
+	BYTE* writeBuffer = new BYTE[65536];
+	BYTE* writePointer = writeBuffer;
 
+	*((__int64*)writePointer) = currentPointer;
+	writePointer += sizeof(__int64);
+	
+	*((long*)writePointer) = m_filesAdded;
+	writePointer += sizeof(long);
+	
+	*((long*)writePointer) = m_filesRemoved;
+	writePointer += sizeof(long);
+
 	// Write out all the filenames (null terminated)
 	std::vector<LPWSTR>::iterator it = m_tsFileNames.begin();
 	for ( ; it < m_tsFileNames.end() ; it++ )
@@ -421,16 +428,32 @@
 		LPWSTR pFilename = *it;
 		long length = wcslen(pFilename)+1;
 		length *= sizeof(wchar_t);
-		WriteFile(m_hTSBufferFile, pFilename, length, &written, NULL);
+		//WriteFile(m_hTSBufferFile, pFilename, length, &written, NULL);
+		memcpy(writePointer, pFilename, length);
+		writePointer += length;
+
+		if((writePointer - writeBuffer) > 60000)
+		{
+			LogDebug("MultiFileWriter: TS buffer file has exceeded maximum length.  Reduce the number of timeshifting files");
+			delete[] writeBuffer;
+			return S_FALSE;
+		}
 	}
 
 	// Finish up with a unicode null character in case we want to put stuff after this in the future.
 	wchar_t temp = 0;
-	WriteFile(m_hTSBufferFile, &temp, sizeof(temp), &written, NULL);
+	*((wchar_t*)writePointer) = temp;
+	writePointer += sizeof(wchar_t);
+	
+	
+	*((long*)writePointer) = m_filesAdded;
+	writePointer += sizeof(long);
+	
+	*((long*)writePointer) = m_filesRemoved;
+	writePointer += sizeof(long);
 
-	// Write again filesAdded and filesRemoved values for integrity check.
-	WriteFile(m_hTSBufferFile, &m_filesAdded, sizeof(m_filesAdded), &written, NULL);
-	WriteFile(m_hTSBufferFile, &m_filesRemoved, sizeof(m_filesRemoved), &written, NULL);
+	WriteFile(m_hTSBufferFile, writeBuffer, writePointer - writeBuffer, &written, NULL);
+	delete[] writeBuffer;
 
 	//randomly park the file pointer to help minimise HDD clogging
 //	if(m_pCurrentTSFile && m_pCurrentTSFile->GetFilePointer()&1)
Index: DirectShowFilters/MPWriter/source/MultiWriterFileSink.cpp
===================================================================
--- DirectShowFilters/MPWriter/source/MultiWriterFileSink.cpp	(revision 27233)
+++ DirectShowFilters/MPWriter/source/MultiWriterFileSink.cpp	(working copy)
@@ -17,9 +17,36 @@
 	m_highestPcr=0;
 	m_bDetermineNewStartPcr=false;
 	m_bStartPcrFound=false;
-	m_pWriteBuffer = new byte[WRITE_BUFFER_SIZE];
+
+	m_iWriteBufferSize = THROTTLE_MAXIMUM_TV_PACKETS * TS_PACKET_SIZE;
+	m_pWriteBuffer = new byte[m_iWriteBufferSize];
 	m_iWriteBufferPos = 0;
 
+	//	Populate the throttle
+	m_iThrottleBufferSizes[0] = 2;		//	2 total
+	m_iThrottleBufferSizes[1] = 3;		//	5
+	m_iThrottleBufferSizes[2] = 5;		//	10
+	m_iThrottleBufferSizes[3] = 5;		//	15
+	m_iThrottleBufferSizes[4] = 5;		//	20
+	m_iThrottleBufferSizes[5] = 5;		//	25
+	m_iThrottleBufferSizes[6] = 5;		//	30
+	m_iThrottleBufferSizes[7] = 10;		//	40
+	m_iThrottleBufferSizes[8] = 10;		//	50
+	m_iThrottleBufferSizes[9] = 10;		//	60
+	m_iThrottleBufferSizes[10] = 10;	//	70
+	m_iThrottleBufferSizes[11] = 10;	//	80
+	m_iThrottleBufferSizes[12] = 20;	//	100
+	m_iThrottleBufferSizes[13] = 20;	//	120
+	m_iThrottleBufferSizes[14] = 20;	//	140
+	m_iThrottleBufferSizes[15] = 32;	//	172	*sync with streamingserver
+	m_iThrottleBufferSizes[16] = 40;	//	212
+	m_iThrottleBufferSizes[17] = 50;	//	262
+	m_iThrottleBufferSizes[18] = 82;	//	344	*sync with streamingserver
+	m_iThrottleBufferSizes[19] = 172;	//	516	*sync with streamingserver
+
+	m_iWriteBufferThrottle = 0;
+	m_bThrottleAtMax = FALSE;
+
 	LogDebug("CMultiWriterFileSink::ctor");
 
 }
@@ -37,7 +64,7 @@
 	delete[] m_pWriteBuffer;
 }
 
-CMultiWriterFileSink* CMultiWriterFileSink::createNew(UsageEnvironment& env, char const* fileName,int minFiles, int maxFiles, ULONG maxFileSize,unsigned bufferSize, Boolean oneFilePerFrame) 
+CMultiWriterFileSink* CMultiWriterFileSink::createNew(UsageEnvironment& env, char const* fileName,int minFiles, int maxFiles, ULONG maxFileSize,unsigned bufferSize, Boolean oneFilePerFrame, int channelType) 
 {
 	do 
 	{
@@ -55,12 +82,40 @@
 			delete fid;
 			return NULL;
 		}
-		return new CMultiWriterFileSink(env, fid, bufferSize, NULL);
+		CMultiWriterFileSink *newMultiWriterFileSink = new CMultiWriterFileSink(env, fid, bufferSize, NULL);
+
+		//	Set the channel type
+		newMultiWriterFileSink->SetChannelType(channelType);
+
+		return newMultiWriterFileSink;
 	} while (0);
 
 	return NULL;
 }
 
+//	Sets the channel type
+void CMultiWriterFileSink::SetChannelType(int channelType)
+{
+	try
+	{
+		//	If tv (0)
+		if(channelType == 0)
+			m_eChannelType = TV;
+
+		//	Else assume radio
+		else
+			m_eChannelType = Radio;
+
+		//	Reset the throttle
+		m_iWriteBufferThrottle = 0;	
+		m_bThrottleAtMax = FALSE;
+	}
+	catch(...)
+	{
+		LogDebug("SetCCMultiWriterFileSink::SetChannelType() - Exception");
+	}
+}
+
 Boolean CMultiWriterFileSink::continuePlaying() 
 {
 	if (fSource == NULL) return False;
@@ -98,17 +153,59 @@
 
 void CMultiWriterFileSink::OnTsPacket(byte* tsPacket)
 {
-	if(m_iWriteBufferPos +TS_PACKET_LEN >= WRITE_BUFFER_SIZE){
-		fOutFid->Write(m_pWriteBuffer, m_iWriteBufferPos);
+	if(m_iWriteBufferPos < 0 || (m_iWriteBufferPos + TS_PACKET_LEN) > m_iWriteBufferSize)
+	{
+		LogDebug("CMultiWriterFileSink::OnTsPacket() - Buffer overflow");
 		m_iWriteBufferPos = 0;
 	}
+
 	memcpy(&m_pWriteBuffer[m_iWriteBufferPos],tsPacket,TS_PACKET_LEN);
 	m_iWriteBufferPos += TS_PACKET_LEN;
+	
+
+	//	Perform throttling
+	if(m_iWriteBufferThrottle < 0)
+		m_iWriteBufferThrottle = 0;
+
+	if(m_iWriteBufferThrottle >= NUMBER_THROTTLE_BUFFER_SIZES)
+		m_iWriteBufferThrottle = NUMBER_THROTTLE_BUFFER_SIZES - 1;
+
+	int currentThrottlePackets = m_iThrottleBufferSizes[m_iWriteBufferThrottle];
+	int currentThrottleBufferSize = currentThrottlePackets * TS_PACKET_LEN;
+
+
+    if (m_iWriteBufferPos >= currentThrottleBufferSize)
+	{
+		int throttleToNumberPackets = THROTTLE_MAXIMUM_TV_PACKETS;
+
+		//	If radio, we want to throttle to a smaller buffer size
+		if(m_eChannelType == Radio)
+			throttleToNumberPackets = THROTTLE_MAXIMUM_RADIO_PACKETS;
+
+		//	Throttle up if we are not at maximum		
+		if(currentThrottlePackets < throttleToNumberPackets)
+		{	
+			if(m_iWriteBufferThrottle < (NUMBER_THROTTLE_BUFFER_SIZES - 1))
+				LogDebug("CMultiWriterFileSink::OnTsPacket() - Throttle to %d bytes", m_iWriteBufferPos);
+
+			m_iWriteBufferThrottle++;
+		}
+		else if(currentThrottlePackets == throttleToNumberPackets && m_bThrottleAtMax == FALSE)
+		{
+			m_bThrottleAtMax = TRUE;
+			LogDebug("CMultiWriterFileSink::OnTsPacket() - Throttle to %d bytes (max)", m_iWriteBufferPos);
+		}
+
+		fOutFid->Write(m_pWriteBuffer, m_iWriteBufferPos);
+		m_iWriteBufferPos = 0;
+	}
 }
 
 
 void CMultiWriterFileSink::ClearStreams()
 {
 	m_bDetermineNewStartPcr=true;
+
+	m_iWriteBufferThrottle = 0;
 }
 
Index: DirectShowFilters/MPWriter/source/MultiWriterFileSink.h
===================================================================
--- DirectShowFilters/MPWriter/source/MultiWriterFileSink.h	(revision 27233)
+++ DirectShowFilters/MPWriter/source/MultiWriterFileSink.h	(working copy)
@@ -9,12 +9,26 @@
 #include "MultiFileWriter.h"
 #include "packetsync.h" 
 
-const int WRITE_BUFFER_SIZE = 188*10;
+#define TS_PACKET_SIZE	188
+#define THROTTLE_MAXIMUM_RADIO_PACKETS			10		//	Throttle to 10 for radio
+#define THROTTLE_MAXIMUM_TV_PACKETS				172		//	Throttle to 172 fo tv for reduced disk IOs
 
+
+//	Incremental buffer sizes
+#define NUMBER_THROTTLE_BUFFER_SIZES	20
+
+
+enum ChannelType
+{
+	TV = 0,
+	Radio = 1,
+};
+
+
 class CMultiWriterFileSink: public MediaSink,public CPacketSync 
 {
 public:
-  static CMultiWriterFileSink* createNew(UsageEnvironment& env, char const* fileName,int minFiles, int maxFiles, ULONG maxFileSize,unsigned bufferSize = 20000,Boolean oneFilePerFrame = False);
+  static CMultiWriterFileSink* createNew(UsageEnvironment& env, char const* fileName,int minFiles, int maxFiles, ULONG maxFileSize,unsigned bufferSize = 20000,Boolean oneFilePerFrame = False, int channelType = 0);
   // "bufferSize" should be at least as large as the largest expected
   //   input frame.
   // "oneFilePerFrame" - if True - specifies that each input frame will
@@ -25,7 +39,8 @@
   virtual ~CMultiWriterFileSink();
   void addData(unsigned char* data, unsigned dataSize,struct timeval presentationTime);
   // (Available in case a client wants to add extra data to the output file)
-
+
+  void SetChannelType(int channelType);
 	virtual void OnTsPacket(byte* tsPacket);
   void ClearStreams();
 protected:
@@ -50,6 +65,11 @@
   bool    m_bStartPcrFound;
   	byte*	m_pWriteBuffer;
 	int     m_iWriteBufferPos;
+	int		m_iWriteBufferSize;
+  int				m_iWriteBufferThrottle;
+  BOOL				m_bThrottleAtMax;
+  ChannelType		m_eChannelType;
+  int			m_iThrottleBufferSizes[NUMBER_THROTTLE_BUFFER_SIZES];
 
 private: // redefined virtual functions:
   CCritSec m_Lock;
Index: DirectShowFilters/MPWriter/source/ProgramToTransportStream.cpp
===================================================================
--- DirectShowFilters/MPWriter/source/ProgramToTransportStream.cpp	(revision 27233)
+++ DirectShowFilters/MPWriter/source/ProgramToTransportStream.cpp	(working copy)
@@ -76,6 +76,16 @@
 	m_maxFiles=maxFiles;
 	m_maxFileSize=maxFileSize;
 }
+void CProgramToTransportStream::SetChannelType(int channelType)
+{
+	if(m_outputSink == NULL)
+	{
+		LogDebug("CProgramToTransportStream::SetChannelType() - Error, tried to set channel type before initialization");
+		return;
+	}
+
+	m_outputSink->SetChannelType(channelType);
+}
 void CProgramToTransportStream::ClearStreams()
 {
 	LogDebug("CProgramToTransportStream::ClearStreams()");
Index: DirectShowFilters/MPWriter/source/ProgramToTransportStream.h
===================================================================
--- DirectShowFilters/MPWriter/source/ProgramToTransportStream.h	(revision 27233)
+++ DirectShowFilters/MPWriter/source/ProgramToTransportStream.h	(working copy)
@@ -1,6 +1,6 @@
 #pragma once
 
-#include "livemedia.hh"
+#include "livemedia.hh"
 #include "BasicUsageEnvironment.hh"
 #include "MPTaskScheduler.h"
 #include "MemoryBuffer.h"
@@ -16,6 +16,7 @@
 	virtual ~CProgramToTransportStream(void);
 	void Initialize(char* fileNameOut);
 	void SetTimeShiftParams( int minFiles, int maxFiles, ULONG maxFileSize);
+	void SetChannelType(int channelType);
 	void ClearStreams();
 	void Close();
 	void Write(byte* data, int len);
@@ -27,7 +28,7 @@
 	bool m_BufferThreadActive;
 	void SetVideoAudioObserver(IAnalogVideoAudioObserver* callback);
 
-private:
+private:
 	UsageEnvironment* m_env;
 	CMemoryBuffer m_buffer;
 	CMultiWriterFileSink* m_outputSink;
Index: DirectShowFilters/MPWriter/source/SubChannel.cpp
===================================================================
--- DirectShowFilters/MPWriter/source/SubChannel.cpp	(revision 27233)
+++ DirectShowFilters/MPWriter/source/SubChannel.cpp	(working copy)
@@ -95,6 +95,12 @@
 	return S_OK;
 }
 
+STDMETHODIMP CSubChannel::SetChannelType(int channelType)
+{
+	m_pTsWriter->SetChannelType(channelType);
+	return S_OK;
+}
+
 STDMETHODIMP CSubChannel::SetTimeShiftParams(int minFiles, int maxFiles, ULONG maxFileSize)
 {
 	m_pTsWriter->SetTimeShiftParams(  minFiles,  maxFiles,  maxFileSize);
Index: DirectShowFilters/MPWriter/source/SubChannel.h
===================================================================
--- DirectShowFilters/MPWriter/source/SubChannel.h	(revision 27233)
+++ DirectShowFilters/MPWriter/source/SubChannel.h	(working copy)
@@ -39,6 +39,7 @@
 	STDMETHODIMP StopRecord();
 
 	STDMETHODIMP SetTimeShiftFileName(char* pszFileName);
+	STDMETHODIMP SetChannelType(int channelType);
 	STDMETHODIMP StartTimeShifting();
 	STDMETHODIMP StopTimeShifting();
 	STDMETHODIMP PauseTimeShifting(int onOff);
Index: DirectShowFilters/StreamingServer/Source/FileReader.cpp
===================================================================
--- DirectShowFilters/StreamingServer/Source/FileReader.cpp	(revision 27233)
+++ DirectShowFilters/StreamingServer/Source/FileReader.cpp	(working copy)
@@ -162,8 +162,8 @@
 	}
 	else
 	{
-		LogDebug("FileReader::OpenFile(), open file %ws failed.", pFileName);
 		DWORD dwErr = GetLastError();
+		LogDebug("FileReader::OpenFile(), open file %ws failed. Error code %d", pFileName, dwErr);
 		return HRESULT_FROM_WIN32(dwErr);
 	}
 
Index: DirectShowFilters/StreamingServer/Source/main.cpp
===================================================================
--- DirectShowFilters/StreamingServer/Source/main.cpp	(revision 27233)
+++ DirectShowFilters/StreamingServer/Source/main.cpp	(working copy)
@@ -55,8 +55,8 @@
 void StreamShutdown();
 void StreamRun();
 void announceStream(RTSPServer* rtspServer, ServerMediaSession* sms,char * streamName, char * inputFileName); // fwd
-void StreamAddTimeShiftFile(char* streamName, char* fileName,bool isProgramStream);
-void StreamAddMpegFile(char* streamName, char* fileName);
+void StreamAddTimeShiftFile(char* streamName, char* fileName,bool isProgramStream,int channelType);
+void StreamAddMpegFile(char* streamName, char* fileName, int channelType);
 void StreamRemove(char* streamName);
 
 extern netAddressBits SendingInterfaceAddr ;
@@ -67,7 +67,7 @@
 int main(int argc, char* argv[])
 {
 	StreamSetup("192.168.1.130");
-	StreamAddTimeShiftFile("test1", "C:\\1\\live5-0.ts.tsbuffer",false);
+	StreamAddTimeShiftFile("test1", "C:\\1\\live5-0.ts.tsbuffer",false,0);
 	//StreamAddMpegFile("test2", "C:\\media\\movies\\NED 1.mpg");
 	//StreamAddMpegFile("test3", "C:\\media\\movies\\PREMIERE 420070201-1146.ts");
 	while (true)
@@ -190,13 +190,13 @@
 }
 
 //**************************************************************************************
-void StreamAddTimeShiftFile(char* streamName, char* fileName,bool isProgramStream)
+void StreamAddTimeShiftFile(char* streamName, char* fileName,bool isProgramStream,int channelType)
 {
 	try
 	{
 		LogDebug("Stream server: add timeshift  mpeg-2 transport stream %s filename:%s", streamName,fileName);
 		ServerMediaSession* sms= ServerMediaSession::createNew(*m_env, streamName, streamName,STREAM_DESCRIPTION,false);
-		sms->addSubsession(TsMPEG2TransportFileServerMediaSubsession::createNew(*m_env, fileName, false,true));
+		sms->addSubsession(TsMPEG2TransportFileServerMediaSubsession::createNew(*m_env, fileName, false,true,channelType));
 		m_rtspServer->addServerMediaSession(sms);
 
 		announceStream(m_rtspServer, sms, streamName, fileName);
@@ -208,13 +208,13 @@
 }
 
 //**************************************************************************************
-void StreamAddMpegFile(char* streamName, char* fileName)
+void StreamAddMpegFile(char* streamName, char* fileName, int channelType)
 {
 	try
 	{
 		LogDebug("Stream server: add mpeg-2 ts stream %s filename:%s", streamName,fileName);
 		ServerMediaSession* sms= ServerMediaSession::createNew(*m_env, streamName, streamName,STREAM_DESCRIPTION,false);
-		sms->addSubsession(TsMPEG2TransportFileServerMediaSubsession::createNew(*m_env, fileName, false,false));
+		sms->addSubsession(TsMPEG2TransportFileServerMediaSubsession::createNew(*m_env, fileName, false,false,channelType));
 		m_rtspServer->addServerMediaSession(sms);
 		announceStream(m_rtspServer, sms, streamName, fileName);
 	}
Index: DirectShowFilters/StreamingServer/Source/MultiFileReader.cpp
===================================================================
--- DirectShowFilters/StreamingServer/Source/MultiFileReader.cpp	(revision 27233)
+++ DirectShowFilters/StreamingServer/Source/MultiFileReader.cpp	(working copy)
@@ -306,28 +306,43 @@
   long Loop=10 ;
 
   LPWSTR pBuffer ;
-  	
+  	 	
   do
   {
-    Error=0  ;
+    Error=0;
+	currentPosition = -1;
+	filesAdded = -1;
+	filesRemoved = -1;
+	filesAdded2 = -2;
+	filesRemoved2 = -2;
+
   	m_TSBufferFile.SetFilePointer(0, FILE_END);
 	  __int64 fileLength = m_TSBufferFile.GetFilePointer();
 
     // Min file length is Header ( __int64 + long + long ) + filelist ( > 0 ) + Footer ( long + long ) 
     if (fileLength <= (sizeof(__int64) + sizeof(long) + sizeof(long) + sizeof(wchar_t) + sizeof(long) + sizeof(long)))
-			return S_FALSE;
+		return S_FALSE;
 
-	  m_TSBufferFile.SetFilePointer(0, FILE_BEGIN);
-	
-	  result=m_TSBufferFile.Read((LPBYTE)&currentPosition, sizeof(currentPosition), &bytesRead);
-    if (!SUCCEEDED(result)|| bytesRead!=sizeof(currentPosition)) Error|=0x02;
+	m_TSBufferFile.SetFilePointer(0, FILE_BEGIN);
 
-	  result=m_TSBufferFile.Read((LPBYTE)&filesAdded, sizeof(filesAdded), &bytesRead);
-    if (!SUCCEEDED(result)|| bytesRead!=sizeof(filesAdded)) Error=0x04;
+	int readLength = sizeof(currentPosition) + sizeof(filesAdded) + sizeof(filesRemoved);
 
-	  result=m_TSBufferFile.Read((LPBYTE)&filesRemoved, sizeof(filesRemoved), &bytesRead);
-    if (!SUCCEEDED(result)||  bytesRead!=sizeof(filesRemoved)) Error=0x08;
+	LPBYTE readBuffer = new BYTE[readLength];
 
+	result = m_TSBufferFile.Read(readBuffer, readLength, &bytesRead);
+
+    if (!SUCCEEDED(result) || bytesRead != readLength) 
+		Error |= 0x02;
+
+	if(Error == 0)
+	{
+		currentPosition = *((__int64*)(readBuffer + 0));
+		filesAdded = *((long*)(readBuffer + sizeof(__int64)));
+		filesRemoved = *((long*)(readBuffer + sizeof(__int64) + sizeof(long)));
+	}
+
+	delete readBuffer;
+
     // If no files added or removed, break the loop !
     if ((m_filesAdded == filesAdded) && (m_filesRemoved == filesRemoved)) 
 			break ;
@@ -335,23 +350,42 @@
     __int64 remainingLength = fileLength - sizeof(__int64) - sizeof(long) - sizeof(long) - sizeof(long) - sizeof(long) ;
 
     // Above 100kb seems stupid and figure out a problem !!!
-		if (remainingLength > 100000) Error=0x10;;
+	if (remainingLength > 100000) 
+		Error = 0x10;
   
     pBuffer = (LPWSTR)new BYTE[(UINT)remainingLength];
 
-		result=m_TSBufferFile.Read((LPBYTE)pBuffer, (ULONG)remainingLength, &bytesRead);
+	result=m_TSBufferFile.Read((LPBYTE)pBuffer, (ULONG)remainingLength, &bytesRead);
     if (!SUCCEEDED(result)||  bytesRead != remainingLength) Error=0x20 ;
 
-   	result=m_TSBufferFile.Read((LPBYTE)&filesAdded2, sizeof(filesAdded2), &bytesRead);
-    if (!SUCCEEDED(result)|| bytesRead!=sizeof(filesAdded2)) Error=0x40 ;
+	
+	readLength = sizeof(filesAdded) + sizeof(filesRemoved);
 
-   	result=m_TSBufferFile.Read((LPBYTE)&filesRemoved2, sizeof(filesRemoved2), &bytesRead);
-    if (!SUCCEEDED(result)|| bytesRead!=sizeof(filesRemoved2)) Error=0x40 ;
+	readBuffer = new BYTE[readLength];
 
-    if ((filesAdded2!=filesAdded) || (filesRemoved2!=filesRemoved))
+	result = m_TSBufferFile.Read(readBuffer, readLength, &bytesRead);
+
+    if (!SUCCEEDED(result) || bytesRead != readLength) 
+		Error |= 0x40;
+
+	if(Error == 0)
+	{
+		filesAdded2 = *((long*)(readBuffer + 0));
+		filesRemoved2 = *((long*)(readBuffer + sizeof(long)));
+	}
+
+	delete readBuffer;
+
+    if ((filesAdded2 != filesAdded) || (filesRemoved2 != filesRemoved))
     {
-      Sleep(10) ;
-      Error=0x80 ;
+      Error = 0x80;
+
+	  LogDebug("MultiFileReader has error 0x80 in Loop %d. Try to clear SMB Cache.", 10-Loop);
+	  
+	  // try to clear local / remote SMB file cache. This should happen when we close the filehandle
+      m_TSBufferFile.CloseFile();
+	  m_TSBufferFile.OpenFile();
+	  Sleep(5);
     }
 
     if (Error) delete[] pBuffer;
Index: DirectShowFilters/StreamingServer/Source/TSBuffer.cpp
===================================================================
--- DirectShowFilters/StreamingServer/Source/TSBuffer.cpp	(revision 27233)
+++ DirectShowFilters/StreamingServer/Source/TSBuffer.cpp	(working copy)
@@ -33,12 +33,15 @@
 #include "global.h"
 #include "entercriticalsection.h"
 
+#define TV_BUFFER_ITEM_SIZE	32336
+#define RADIO_BUFFER_ITEM_SIZE	1880
+
 extern void LogDebug(const char *fmt, ...) ;
 CTSBuffer::CTSBuffer()
 {
 	m_pFileReader = NULL;
 	m_lItemOffset = 0;
-	m_lTSBufferItemSize = 8084 ; //128028;
+	m_lTSBufferItemSize = TV_BUFFER_ITEM_SIZE; 
 
 	//round to nearest byte boundary.
 
@@ -89,6 +92,29 @@
 	return bytesAvailable;
 }
 
+void CTSBuffer::SetChannelType(int channelType)
+{
+	Mediaportal::CEnterCriticalSection lock(m_BufferLock);
+
+	Clear();
+
+	//	Tv
+	if(channelType == 0)
+	{
+		LogDebug("CTSBuffer::SetChannelType() - Buffer size set to TV (%d)", TV_BUFFER_ITEM_SIZE);
+		m_lTSBufferItemSize = TV_BUFFER_ITEM_SIZE;
+		m_eChannelType = TV;
+	}
+
+	//	Radio
+	else
+	{
+		LogDebug("CTSBuffer::SetChannelType() - Buffer size set to radio (%d)", RADIO_BUFFER_ITEM_SIZE);
+		m_lTSBufferItemSize = RADIO_BUFFER_ITEM_SIZE;
+		m_eChannelType = Radio;
+	}
+}
+
 HRESULT CTSBuffer::Require(long nBytes, BOOL bIgnoreDelay)
 {
 	if (!m_pFileReader)
@@ -99,90 +125,64 @@
 	if (nBytes <= bytesAvailable)
 		return S_OK;
 
-	while (nBytes > bytesAvailable)
-	{
-		BYTE *newItem = new BYTE[m_lTSBufferItemSize];
-		ULONG ulBytesRead = 0;
+	//	Calculate how many data items we need
+	UINT bytesRequired = nBytes - bytesAvailable;
+	UINT dataItemsRequired = bytesRequired / m_lTSBufferItemSize;
 
-		__int64 currPosition = m_pFileReader->GetFilePointer();
-		HRESULT hr = m_pFileReader->Read(newItem, m_lTSBufferItemSize, &ulBytesRead);
-		if (FAILED(hr)){
+	if((bytesRequired % m_lTSBufferItemSize) > 0)
+		dataItemsRequired++;
 
-			delete[] newItem;
-			return hr;
-		}
+	//	Work out the total number of bytes we need to read and allocate a buffer
+	UINT bytesToRead = dataItemsRequired * m_lTSBufferItemSize;
+	BYTE* readBuffer = new BYTE[bytesToRead];
 
-		if (ulBytesRead < (ULONG)m_lTSBufferItemSize) 
+	UINT totalBytesRead = 0;
+	UINT iteration = 0;
+
+	do
+	{
+		if(iteration > 0)
 		{
-			WORD wReadOnly = 0;
-			m_pFileReader->get_ReadOnly(&wReadOnly);
-			if (wReadOnly && !bIgnoreDelay)
-			{
-				m_loopCount = max(2, m_loopCount);
-				m_loopCount = min(20, m_loopCount);
-//				int count = 220; // 2 second max delay
-				while (ulBytesRead < (ULONG)m_lTSBufferItemSize && m_loopCount) 
-				{
-          //Log("TSBuffer::Require() Waiting for file to grow:%d",bDelay);
-//					::OutputDebugString(TEXT("TSBuffer::Require() Waiting for file to grow.\n"));
+			//	Sleep for 4ms per iteration (TV)
+			int sleepPerIteration = 4;
 
-					WORD bDelay = 0;
-					m_pFileReader->get_DelayMode(&bDelay);
-					m_loopCount--;
+			//	If radio set to 20ms
+			if(m_eChannelType == Radio)
+				sleepPerIteration = 20;
 
-					if (bDelay > 0)
-					{
-						Sleep(2000);
-						m_loopCount = 0;
-					}
-					else
-					{
-						if (!m_loopCount)
-						{
-							m_loopCount = 20;
-							delete[] newItem;
-							return hr;
-						}
-						Sleep(100);
-					}
+			Sleep(iteration * sleepPerIteration);
+		}
 
-					ULONG ulNextBytesRead = 0;				
-					m_pFileReader->SetFilePointer(currPosition, FILE_BEGIN);
-					HRESULT hr = m_pFileReader->Read(newItem, m_lTSBufferItemSize, &ulNextBytesRead);
-					if (FAILED(hr) && !m_loopCount){
+		ULONG bytesRead = 0;
+		HRESULT hr = m_pFileReader->Read(readBuffer + totalBytesRead, bytesToRead - totalBytesRead, &bytesRead);
 
-						m_loopCount = 20;
-						delete[] newItem;
-						return hr;
-					}
+		if(FAILED(hr) || iteration >= 20)
+		{
+			LogDebug("TSBuffer::Require() - Failed to read buffer file");
+			
+			delete readBuffer;
 
-					if (((ulNextBytesRead == 0) | (ulNextBytesRead == ulBytesRead)) && !m_loopCount){
+			return hr;
+		}
 
-						m_loopCount = 20;
-						delete[] newItem;
-						return E_FAIL;
-					}
+		totalBytesRead += bytesRead;
+		iteration++;
+	}
+	while(totalBytesRead < bytesToRead);
 
-					ulBytesRead = ulNextBytesRead;
-				}
-			}
-			else
-			{
-				delete[] newItem;
-				return E_FAIL;
-			}
-		}
 
-		m_loopCount = 20;
-		if (newItem)
-		{
-			m_Array.push_back(newItem);
-			bytesAvailable += m_lTSBufferItemSize;
-		}
+	//	Success! Copy all bytes to data items
+	for(int i = 0; i < dataItemsRequired; i++)
+	{
+		BYTE* newDataItem = new BYTE[m_lTSBufferItemSize];
+		memcpy(newDataItem, readBuffer + (i * m_lTSBufferItemSize), m_lTSBufferItemSize);
 
-//		m_pFileReader->setBufferPointer();
+		m_Array.push_back(newDataItem);
+		bytesAvailable += m_lTSBufferItemSize;
+	}
 
-	}
+	delete readBuffer;
+
 	return S_OK;
 }
 
Index: DirectShowFilters/StreamingServer/Source/TSBuffer.h
===================================================================
--- DirectShowFilters/StreamingServer/Source/TSBuffer.h	(revision 27233)
+++ DirectShowFilters/StreamingServer/Source/TSBuffer.h	(working copy)
@@ -31,6 +31,12 @@
 #include "FileReader.h"
 #include "CriticalSection.h"
 
+enum ChannelType
+{
+	TV = 0,
+	Radio = 1,
+};
+
 class CTSBuffer 
 {
 public:
@@ -40,6 +46,7 @@
 
 	void Clear();
 	long Count();
+	void SetChannelType(int channelType);
 	HRESULT Require(long nBytes, BOOL bIgnoreDelay = FALSE);
 	HRESULT DequeFromBuffer(BYTE *pbData, long lDataLength);
 	HRESULT ReadFromBuffer(BYTE *pbData, long lDataLength, long lOffset);
@@ -52,6 +59,7 @@
   Mediaportal::CCriticalSection m_BufferLock;
 
 	long m_lTSBufferItemSize;
+	ChannelType	m_eChannelType;
 	int debugcount;
 	int m_ParserLock;
 
Index: DirectShowFilters/StreamingServer/Source/TsMPEG2TransportFileServerMediaSubsession.cpp
===================================================================
--- DirectShowFilters/StreamingServer/Source/TsMPEG2TransportFileServerMediaSubsession.cpp	(revision 27233)
+++ DirectShowFilters/StreamingServer/Source/TsMPEG2TransportFileServerMediaSubsession.cpp	(working copy)
@@ -8,16 +8,17 @@
 
 extern void LogDebug(const char *fmt, ...) ;
 
-TsMPEG2TransportFileServerMediaSubsession* TsMPEG2TransportFileServerMediaSubsession::createNew(UsageEnvironment& env,char const* fileName,Boolean reuseFirstSource, Boolean timeshifting) 
+TsMPEG2TransportFileServerMediaSubsession* TsMPEG2TransportFileServerMediaSubsession::createNew(UsageEnvironment& env,char const* fileName,Boolean reuseFirstSource, Boolean timeshifting, int channelType) 
 {
-	return new TsMPEG2TransportFileServerMediaSubsession(env, fileName, reuseFirstSource,timeshifting);
+	return new TsMPEG2TransportFileServerMediaSubsession(env, fileName, reuseFirstSource,timeshifting, channelType);
 }
 
-TsMPEG2TransportFileServerMediaSubsession::TsMPEG2TransportFileServerMediaSubsession(UsageEnvironment& env,char const* fileName, Boolean reuseFirstSource, Boolean timeshifting)
+TsMPEG2TransportFileServerMediaSubsession::TsMPEG2TransportFileServerMediaSubsession(UsageEnvironment& env,char const* fileName, Boolean reuseFirstSource, Boolean timeshifting, int channelType)
 : FileServerMediaSubsession(env, fileName, reuseFirstSource) 
 {
 	strcpy(m_fileName,fFileName);
 	m_bTimeshifting = timeshifting;
+	m_iChannelType = channelType;
 
   m_pDuration = new CTsDuration();
 }
@@ -38,7 +39,7 @@
 
 	// Create the video source:
 	unsigned const inputDataChunkSize= TRANSPORT_PACKETS_PER_NETWORK_PACKET*TRANSPORT_PACKET_SIZE;
-	TsStreamFileSource* fileSource= TsStreamFileSource::createNew(envir(), fFileName, inputDataChunkSize);
+	TsStreamFileSource* fileSource= TsStreamFileSource::createNew(envir(), fFileName, inputDataChunkSize, 0, m_iChannelType);
 	if (fileSource == NULL) return NULL;
 	fFileSize = fileSource->fileSize();
 	strcpy(m_fileName,fFileName);
@@ -105,10 +106,10 @@
   return fileSizeTmp;
 }
 
-FileReader* TsMPEG2TransportFileServerMediaSubsession::OpenFileDuration() const
-{
-  FileReader *pFileDuration;
-
+FileReader* TsMPEG2TransportFileServerMediaSubsession::OpenFileDuration() const
+{
+  FileReader *pFileDuration;
+
   if (strstr(m_fileName,".tsbuffer")!=NULL)
   {
     pFileDuration = new MultiFileReader();
@@ -122,22 +123,22 @@
   WCHAR wFileName[1024];
   MultiByteToWideChar(CP_ACP,0,m_fileName,-1,wFileName,1024);
   pFileDuration->SetFileName(wFileName);
-  if(FAILED(pFileDuration->OpenFile()))
-  {
-    CloseFileDuration(pFileDuration);
-    pFileDuration = NULL;
-  }
-
-  m_pDuration->SetFileReader(pFileDuration);
-  return pFileDuration;
-}
-
-void TsMPEG2TransportFileServerMediaSubsession::CloseFileDuration(FileReader *pFileDuration) const
-{
-  if(pFileDuration)
-  {
-    pFileDuration->CloseFile();
-    m_pDuration->SetFileReader(NULL);
-    delete pFileDuration;
-  }
-}
+  if(FAILED(pFileDuration->OpenFile()))
+  {
+    CloseFileDuration(pFileDuration);
+    pFileDuration = NULL;
+  }
+
+  m_pDuration->SetFileReader(pFileDuration);
+  return pFileDuration;
+}
+
+void TsMPEG2TransportFileServerMediaSubsession::CloseFileDuration(FileReader *pFileDuration) const
+{
+  if(pFileDuration)
+  {
+    pFileDuration->CloseFile();
+    m_pDuration->SetFileReader(NULL);
+    delete pFileDuration;
+  }
+}
Index: DirectShowFilters/StreamingServer/Source/TsMPEG2TransportFileServerMediaSubsession.h
===================================================================
--- DirectShowFilters/StreamingServer/Source/TsMPEG2TransportFileServerMediaSubsession.h	(revision 27233)
+++ DirectShowFilters/StreamingServer/Source/TsMPEG2TransportFileServerMediaSubsession.h	(working copy)
@@ -9,12 +9,12 @@
 class TsMPEG2TransportFileServerMediaSubsession: public FileServerMediaSubsession{
 public:
 	static TsMPEG2TransportFileServerMediaSubsession*
-		createNew(UsageEnvironment& env, char const* fileName, Boolean reuseFirstSource, Boolean timeshifting);
+		createNew(UsageEnvironment& env, char const* fileName, Boolean reuseFirstSource, Boolean timeshifting, int channelType);
 
 protected:
 	TsMPEG2TransportFileServerMediaSubsession(UsageEnvironment& env,
 		char const* fileName,
-		Boolean reuseFirstSource, Boolean timeshifting);
+		Boolean reuseFirstSource, Boolean timeshifting, int channelType);
 	// called only by createNew();
 	virtual ~TsMPEG2TransportFileServerMediaSubsession();
 	virtual float duration() const;
@@ -33,6 +33,7 @@
 		FramedSource* inputSource);
 	char m_fileName[MAX_PATH];
 	Boolean m_bTimeshifting;
+	int m_iChannelType;
 };
 
 #endif
Index: DirectShowFilters/StreamingServer/Source/TsMPEG2TransportStreamFramer.cpp
===================================================================
--- DirectShowFilters/StreamingServer/Source/TsMPEG2TransportStreamFramer.cpp	(revision 27233)
+++ DirectShowFilters/StreamingServer/Source/TsMPEG2TransportStreamFramer.cpp	(working copy)
@@ -106,13 +106,17 @@
 struct timeval presentationTime) {
 	fFrameSize += frameSize;
 	unsigned const numTSPackets = fFrameSize/TRANSPORT_PACKET_SIZE;
+  unsigned const dataGoingToBeLost=fFrameSize % TRANSPORT_PACKET_SIZE;
 	fFrameSize = numTSPackets*TRANSPORT_PACKET_SIZE; // an integral # of TS packets
 	if (fFrameSize == 0) {
 		// We didn't read a complete TS packet; assume that the input source has closed.
 		handleClosure(this);
 		return;
 	}
-
+  if (dataGoingToBeLost>0)
+  {
+    //need to handle a mid buffer
+  }
 	// Make sure the data begins with a sync byte:
 	unsigned syncBytePosition;
 	for (syncBytePosition = 0; syncBytePosition < fFrameSize; ++syncBytePosition) {
@@ -125,14 +129,36 @@
 	} else if (syncBytePosition > 0) {
 		// There's a sync byte, but not at the start of the data.  Move the good data
 		// to the start of the buffer, then read more to fill it up again:
-		memmove(fTo, &fTo[syncBytePosition], fFrameSize - syncBytePosition);
-		fFrameSize -= syncBytePosition;
+		memmove(fTo, &fTo[syncBytePosition], frameSize - syncBytePosition);
+		fFrameSize -= syncBytePosition-dataGoingToBeLost;
 		fInputSource->getNextFrame(&fTo[fFrameSize], syncBytePosition,
 			afterGettingFrame, this,
 			FramedSource::handleClosure, this);
 		return;
-	} // else normal case: the data begins with a sync byte
+	}
+  else if (dataGoingToBeLost>0)// there is a problem in the buffer somewhere
+  {
+    unsigned badPacket;
+    for (int badPacket=0;badPacket<numTSPackets;badPacket++)
+    {
+      if (fTo[badPacket*TRANSPORT_PACKET_SIZE]!=TRANSPORT_SYNC_BYTE && badPacket*TRANSPORT_PACKET_SIZE<frameSize) break;
+    }
+    //we know it's the previous one...
+    if (badPacket!=0)
+    {
+	    for (syncBytePosition = 1; syncBytePosition < TRANSPORT_PACKET_SIZE; ++syncBytePosition) {
+		    if (fTo[badPacket*TRANSPORT_PACKET_SIZE-syncBytePosition] == TRANSPORT_SYNC_BYTE) break;
+	    }
+   		memmove(&fTo[(badPacket-1)*TRANSPORT_PACKET_SIZE], &fTo[badPacket*TRANSPORT_PACKET_SIZE-syncBytePosition], frameSize - (badPacket*TRANSPORT_PACKET_SIZE-syncBytePosition));
+		  fFrameSize -= TRANSPORT_PACKET_SIZE-syncBytePosition-dataGoingToBeLost;
+		  fInputSource->getNextFrame(&fTo[fFrameSize], syncBytePosition,
+			  afterGettingFrame, this,
+			  FramedSource::handleClosure, this);
+		  return;
+    }
+  }// else normal case: the data begins with a sync byte
 
+
 	fPresentationTime = presentationTime;
 
 	// Scan through the TS packets that we read, and update our estimate of
Index: DirectShowFilters/StreamingServer/Source/TsStreamFileSource.cpp
===================================================================
--- DirectShowFilters/StreamingServer/Source/TsStreamFileSource.cpp	(revision 27233)
+++ DirectShowFilters/StreamingServer/Source/TsStreamFileSource.cpp	(working copy)
@@ -37,7 +37,7 @@
 TsStreamFileSource*
 TsStreamFileSource::createNew(UsageEnvironment& env, char const* fileName,
 							  unsigned preferredFrameSize,
-							  unsigned playTimePerFrame) 
+							  unsigned playTimePerFrame, int channelType) 
 {
 	LogDebug("ts:open %s",fileName);  
 	FileReader* reader;
@@ -57,7 +57,7 @@
 
 
 	Boolean deleteFidOnClose = true;
-	TsStreamFileSource* newSource = new TsStreamFileSource(env, (FILE*)reader, deleteFidOnClose, preferredFrameSize, playTimePerFrame);
+	TsStreamFileSource* newSource = new TsStreamFileSource(env, (FILE*)reader, deleteFidOnClose, preferredFrameSize, playTimePerFrame, channelType);
 	newSource->fFileSize = reader->GetFileSize();
 	LogDebug("ts:size %d",(DWORD)newSource->fFileSize);  
 	return newSource;
@@ -67,10 +67,11 @@
 TsStreamFileSource::createNew(UsageEnvironment& env, FILE* fid,
 							  Boolean deleteFidOnClose,
 							  unsigned preferredFrameSize,
-							  unsigned playTimePerFrame) {
+							  unsigned playTimePerFrame,
+							  int channelType) {
 								  if (fid == NULL) return NULL;
 
-								  TsStreamFileSource* newSource = new TsStreamFileSource(env, fid, deleteFidOnClose, preferredFrameSize, playTimePerFrame);
+								  TsStreamFileSource* newSource = new TsStreamFileSource(env, fid, deleteFidOnClose, preferredFrameSize, playTimePerFrame, channelType);
 								  MultiFileReader* reader = (MultiFileReader*)fid;
 								  newSource->fFileSize = reader->GetFileSize();
 								  LogDebug("ts:createNew size %d",(DWORD)newSource->fFileSize);  
@@ -119,7 +120,8 @@
 TsStreamFileSource::TsStreamFileSource(UsageEnvironment& env, FILE* fid,
 									   Boolean deleteFidOnClose,
 									   unsigned preferredFrameSize,
-									   unsigned playTimePerFrame)
+									   unsigned playTimePerFrame,
+									   int channelType)
 									   : FramedFileSource(env, fid), fPreferredFrameSize(preferredFrameSize),
 									   fPlayTimePerFrame(playTimePerFrame), fLastPlayTime(0), fFileSize(0),
 									   fDeleteFidOnClose(deleteFidOnClose) 
@@ -127,7 +129,9 @@
 	LogDebug("ts:ctor:%x",this);  
 	MultiFileReader* reader = (MultiFileReader*)fFid;
 	m_buffer.Clear();
+	m_buffer.SetChannelType(channelType);
 	m_buffer.SetFileReader(reader);
+
 }
 
 TsStreamFileSource::~TsStreamFileSource() 
Index: DirectShowFilters/StreamingServer/Source/TsStreamFileSource.h
===================================================================
--- DirectShowFilters/StreamingServer/Source/TsStreamFileSource.h	(revision 27233)
+++ DirectShowFilters/StreamingServer/Source/TsStreamFileSource.h	(working copy)
@@ -35,15 +35,18 @@
 	static TsStreamFileSource* createNew(UsageEnvironment& env,
 		char const* fileName,
 		unsigned preferredFrameSize = 0,
-		unsigned playTimePerFrame = 0);
+		unsigned playTimePerFrame = 0,
+		int channelType = 0);
 	// "preferredFrameSize" == 0 means 'no preference'
 	// "playTimePerFrame" is in microseconds
+	//	channelType determines the buffer size (for more reliable streaming)
 
 	static TsStreamFileSource* createNew(UsageEnvironment& env,
 		FILE* fid,
 		Boolean deleteFidOnClose = False,
 		unsigned preferredFrameSize = 0,
-		unsigned playTimePerFrame = 0);
+		unsigned playTimePerFrame = 0,
+		int channelType = 0);
 	// an alternative version of "createNew()" that's used if you already have
 	// an open file.
 
@@ -58,7 +61,8 @@
 	TsStreamFileSource(UsageEnvironment& env,
 		FILE* fid, Boolean deleteFidOnClose,
 		unsigned preferredFrameSize,
-		unsigned playTimePerFrame);
+		unsigned playTimePerFrame,
+		int channelType);
 	// called only by createNew()
 
 	virtual ~TsStreamFileSource();
Index: DirectShowFilters/TsReader/source/FileReader.cpp
===================================================================
--- DirectShowFilters/TsReader/source/FileReader.cpp	(revision 27233)
+++ DirectShowFilters/TsReader/source/FileReader.cpp	(working copy)
@@ -165,8 +165,8 @@
 	}
 	else
 	{
-		LogDebug("FileReader::OpenFile(), open file %ws failed.", pFileName);
 		DWORD dwErr = GetLastError();
+		LogDebug("FileReader::OpenFile(), open file %ws failed. Error code %d", pFileName, dwErr);
 		return HRESULT_FROM_WIN32(dwErr);
 	}
 
Index: DirectShowFilters/TsReader/source/MultiFileReader.cpp
===================================================================
--- DirectShowFilters/TsReader/source/MultiFileReader.cpp	(revision 27233)
+++ DirectShowFilters/TsReader/source/MultiFileReader.cpp	(working copy)
@@ -309,25 +309,40 @@
   	
   do
   {
-    Error=0  ;
+    Error=0;
+	currentPosition = -1;
+	filesAdded = -1;
+	filesRemoved = -1;
+	filesAdded2 = -2;
+	filesRemoved2 = -2;
+
   	m_TSBufferFile.SetFilePointer(0, FILE_END);
 	  __int64 fileLength = m_TSBufferFile.GetFilePointer();
 
     // Min file length is Header ( __int64 + long + long ) + filelist ( > 0 ) + Footer ( long + long ) 
     if (fileLength <= (sizeof(__int64) + sizeof(long) + sizeof(long) + sizeof(wchar_t) + sizeof(long) + sizeof(long)))
-			return S_FALSE;
+		return S_FALSE;
 
-	  m_TSBufferFile.SetFilePointer(0, FILE_BEGIN);
-	
-	  result=m_TSBufferFile.Read((LPBYTE)&currentPosition, sizeof(currentPosition), &bytesRead);
-    if (!SUCCEEDED(result)|| bytesRead!=sizeof(currentPosition)) Error|=0x02;
+	m_TSBufferFile.SetFilePointer(0, FILE_BEGIN);
 
-	  result=m_TSBufferFile.Read((LPBYTE)&filesAdded, sizeof(filesAdded), &bytesRead);
-    if (!SUCCEEDED(result)|| bytesRead!=sizeof(filesAdded)) Error=0x04;
+	int readLength = sizeof(currentPosition) + sizeof(filesAdded) + sizeof(filesRemoved);
 
-	  result=m_TSBufferFile.Read((LPBYTE)&filesRemoved, sizeof(filesRemoved), &bytesRead);
-    if (!SUCCEEDED(result)||  bytesRead!=sizeof(filesRemoved)) Error=0x08;
+	LPBYTE readBuffer = new BYTE[readLength];
 
+	result = m_TSBufferFile.Read(readBuffer, readLength, &bytesRead);
+
+    if (!SUCCEEDED(result) || bytesRead != readLength) 
+		Error |= 0x02;
+
+	if(Error == 0)
+	{
+		currentPosition = *((__int64*)(readBuffer + 0));
+		filesAdded = *((long*)(readBuffer + sizeof(__int64)));
+		filesRemoved = *((long*)(readBuffer + sizeof(__int64) + sizeof(long)));
+	}
+
+	delete[] readBuffer;
+
     // If no files added or removed, break the loop !
     if ((m_filesAdded == filesAdded) && (m_filesRemoved == filesRemoved)) 
 			break ;
@@ -335,20 +350,33 @@
     __int64 remainingLength = fileLength - sizeof(__int64) - sizeof(long) - sizeof(long) - sizeof(long) - sizeof(long) ;
 
     // Above 100kb seems stupid and figure out a problem !!!
-		if (remainingLength > 100000) Error=0x10;;
+	if (remainingLength > 100000) 
+		Error = 0x10;
   
     pBuffer = (LPWSTR)new BYTE[(UINT)remainingLength];
 
-		result=m_TSBufferFile.Read((LPBYTE)pBuffer, (ULONG)remainingLength, &bytesRead);
+	result=m_TSBufferFile.Read((LPBYTE)pBuffer, (ULONG)remainingLength, &bytesRead);
     if (!SUCCEEDED(result)||  bytesRead != remainingLength) Error=0x20 ;
 
-   	result=m_TSBufferFile.Read((LPBYTE)&filesAdded2, sizeof(filesAdded2), &bytesRead);
-    if (!SUCCEEDED(result)|| bytesRead!=sizeof(filesAdded2)) Error=0x40 ;
+	
+	readLength = sizeof(filesAdded) + sizeof(filesRemoved);
 
-   	result=m_TSBufferFile.Read((LPBYTE)&filesRemoved2, sizeof(filesRemoved2), &bytesRead);
-    if (!SUCCEEDED(result)|| bytesRead!=sizeof(filesRemoved2)) Error=0x40 ;
+	readBuffer = new BYTE[readLength];
 
-    if ((filesAdded2!=filesAdded) || (filesRemoved2!=filesRemoved))
+	result = m_TSBufferFile.Read(readBuffer, readLength, &bytesRead);
+
+    if (!SUCCEEDED(result) || bytesRead != readLength) 
+		Error |= 0x40;
+
+	if(Error == 0)
+	{
+		filesAdded2 = *((long*)(readBuffer + 0));
+		filesRemoved2 = *((long*)(readBuffer + sizeof(long)));
+	}
+
+	delete[] readBuffer;
+
+    if ((filesAdded2 != filesAdded) || (filesRemoved2 != filesRemoved))
     {
       Error = 0x80;
 
Index: DirectShowFilters/TsWriter/source/DiskRecorder.cpp
===================================================================
--- DirectShowFilters/TsWriter/source/DiskRecorder.cpp	(revision 27233)
+++ DirectShowFilters/TsWriter/source/DiskRecorder.cpp	(working copy)
@@ -33,7 +33,11 @@
 #include "..\..\shared\dvbutil.h"
 #include "..\..\shared\section.h"
 
-#define WRITE_BUFFER_SIZE (188*10)                  // Reduced from 175 packets ( 32900 ) to 10 for Radio startup ( Ambass )										
+#define TS_PACKET_SIZE	188
+#define THROTTLE_MAXIMUM_RADIO_PACKETS			10		//	Throttle to 10 for radio
+#define THROTTLE_MAXIMUM_TV_PACKETS				172		//	Throttle to 172 fo tv for reduced disk IOs
+
+
 #define IGNORE_AFTER_TUNE 25                        // how many TS packets to ignore after tuning
 
 #define PID_PAT                               0     // PID for PAT table
@@ -95,16 +99,49 @@
 	m_bDetermineNewStartPcr=false;
 	m_iPatVersion=0;
 	m_iPmtVersion=0;
-	if (m_recordingMode==RecordingMode::TimeShift)
-		m_pWriteBuffer = new byte[WRITE_BUFFER_SIZE];
+	m_iWriteBufferSize = 0;
+	m_eChannelType = TV;
+
+	if (m_recordingMode == TimeShift)
+		//	Set the buffer to the maximum it can throttle to
+		m_iWriteBufferSize = THROTTLE_MAXIMUM_TV_PACKETS * TS_PACKET_SIZE;
 	else
-		m_pWriteBuffer = new byte[RECORD_BUFFER_SIZE];
+		m_iWriteBufferSize = RECORD_BUFFER_SIZE;
+
+	m_pWriteBuffer = new byte[m_iWriteBufferSize];
+
 	m_iWriteBufferPos=0;
+	m_iWriteBufferThrottle = 0;
+	m_bThrottleAtMax = FALSE;
 	m_TsPacketCount=0;
 	m_bClearTsQueue=false;
 	m_pPmtParser=new CPmtParser();
 	m_pVideoAudioObserver=NULL;
 	m_mapLastPtsDts.clear();
+
+	//	Populate the throttle
+	m_iThrottleBufferSizes[0] = 2;		//	2 total
+	m_iThrottleBufferSizes[1] = 3;		//	5
+	m_iThrottleBufferSizes[2] = 5;		//	10
+	m_iThrottleBufferSizes[3] = 5;		//	15
+	m_iThrottleBufferSizes[4] = 5;		//	20
+	m_iThrottleBufferSizes[5] = 5;		//	25
+	m_iThrottleBufferSizes[6] = 5;		//	30
+	m_iThrottleBufferSizes[7] = 10;		//	40
+	m_iThrottleBufferSizes[8] = 10;		//	50
+	m_iThrottleBufferSizes[9] = 10;		//	60
+	m_iThrottleBufferSizes[10] = 10;	//	70
+	m_iThrottleBufferSizes[11] = 10;	//	80
+	m_iThrottleBufferSizes[12] = 20;	//	100
+	m_iThrottleBufferSizes[13] = 20;	//	120
+	m_iThrottleBufferSizes[14] = 20;	//	140
+	m_iThrottleBufferSizes[15] = 32;	//	172	*sync with streamingserver
+	m_iThrottleBufferSizes[16] = 40;	//	212
+	m_iThrottleBufferSizes[17] = 50;	//	262
+	m_iThrottleBufferSizes[18] = 82;	//	344	*sync with streamingserver
+	m_iThrottleBufferSizes[19] = 172;	//	516	*sync with streamingserver
+
+
 }
 //*******************************************************************
 //* dtor
@@ -122,6 +159,27 @@
 	delete m_pPmtParser;
 }
 
+void CDiskRecorder::SetChannelType(int channelType)
+{
+	CEnterCriticalSection enter(m_section);
+
+	LogDebug("CDiskRecorder::SetChannelType() - Channel type is %d", channelType);
+
+	try
+	{
+		//	If tv (0)
+		if(channelType == 0)
+			m_eChannelType = TV;
+
+		//	Else assume radio
+		else
+			m_eChannelType = Radio;
+	}
+	catch(...)
+	{
+		WriteLog("SetChannelType exception");
+	}
+}
 void CDiskRecorder::SetFileName(char* pszFileName)
 {
 	CEnterCriticalSection enter(m_section);
@@ -136,7 +194,7 @@
 		m_bStartPcrFound=false;
 		m_bDetermineNewStartPcr=false;
 		strcpy(m_szFileName,pszFileName);
-		if (m_recordingMode==RecordingMode::TimeShift)
+		if (m_recordingMode == TimeShift)
 			strcat(m_szFileName,".tsbuffer");
 	}
 	catch(...)
@@ -150,6 +208,13 @@
 	CEnterCriticalSection enter(m_section);
 	try
 	{
+		//	Check buffer is initialized
+		if(m_pWriteBuffer == NULL)
+		{
+			WriteLog("Error, tried to start recording with uninitialized buffer");
+			return false;
+		}
+
 		if (strlen(m_szFileName)==0) return false;
 		::DeleteFile((LPCTSTR) m_szFileName);
 		m_iPart=2;
@@ -257,11 +322,12 @@
 	if (m_bPaused)
   {
 		WriteLog("paused=yes"); 
+		
   }
 	else
 	{
 		WriteLog("paused=no"); 
-		Flush();
+		//Flush();
 		if (m_vecPids.size()==0)
 			WriteLog("PANIC changed status to running but i have not a single stream to record !!!!");
 	}
@@ -292,6 +358,12 @@
 		m_bPaused=FALSE;
 		m_mapLastPtsDts.clear();
     m_iTsContinuityCounter=0;
+
+		//	Reset the write buffer throttle
+		LogDebug("CDiskRecorder::Reset() - Reset write buffer throttle");
+		m_iWriteBufferThrottle = 0;
+		m_bThrottleAtMax = FALSE;
+
 	}
 	catch(...)
 	{
@@ -468,8 +540,13 @@
      {
         WriteLog("clear TS packet queue"); 
         m_bClearTsQueue = false;
-        ZeroMemory(m_pWriteBuffer, WRITE_BUFFER_SIZE);
+        ZeroMemory(m_pWriteBuffer, m_iWriteBufferSize);
         m_iWriteBufferPos = 0;
+		
+		//	Reset the write buffer throttle
+		LogDebug("CDiskRecorder::WriteToRecording() - Reset write buffer throttle");
+		m_iWriteBufferThrottle = 0;
+		m_bThrottleAtMax = FALSE;
       }
       catch(...)
       {
@@ -567,8 +644,13 @@
      {
         WriteLog("clear TS packet queue"); 
         m_bClearTsQueue = false;
-        ZeroMemory(m_pWriteBuffer, WRITE_BUFFER_SIZE);
+        ZeroMemory(m_pWriteBuffer, m_iWriteBufferSize);
         m_iWriteBufferPos = 0;
+		
+		//	Reset the write buffer throttle
+		LogDebug("CDiskRecorder::WriteToTimeshiftFile() - Reset write buffer throttle");
+		m_iWriteBufferThrottle = 0;
+		m_bThrottleAtMax = FALSE;
       }
       catch(...)
       {
@@ -581,7 +663,7 @@
     try  
     {      
       // Copy first TS packet from the queue to the I/O buffer
-      if (m_iWriteBufferPos >= 0 && m_iWriteBufferPos+188 <= WRITE_BUFFER_SIZE)
+      if (m_iWriteBufferPos >= 0 && m_iWriteBufferPos+188 <= m_iWriteBufferSize)
       {
          memcpy(&m_pWriteBuffer[m_iWriteBufferPos], buffer,188);
          m_iWriteBufferPos+=188;
@@ -598,9 +680,38 @@
       return;
     }
 
-    if (m_iWriteBufferPos >= WRITE_BUFFER_SIZE)
-    {
-      Flush();
+	if(m_iWriteBufferThrottle < 0)
+		m_iWriteBufferThrottle = 0;
+
+	if(m_iWriteBufferThrottle >= NUMBER_THROTTLE_BUFFER_SIZES)
+		m_iWriteBufferThrottle = NUMBER_THROTTLE_BUFFER_SIZES - 1;
+
+	int currentThrottlePackets = m_iThrottleBufferSizes[m_iWriteBufferThrottle];
+	int currentThrottleBufferSize = currentThrottlePackets * TS_PACKET_SIZE;
+
+    if (m_iWriteBufferPos >= currentThrottleBufferSize)
+    {	
+		int throttleToNumberPackets = THROTTLE_MAXIMUM_TV_PACKETS;
+
+		//	If radio, we want to throttle to a smaller buffer size
+		if(m_eChannelType == Radio)
+			throttleToNumberPackets = THROTTLE_MAXIMUM_RADIO_PACKETS;
+
+		//	Throttle up if we are not at maximum		
+		if(currentThrottlePackets < throttleToNumberPackets)
+		{	
+			if(m_iWriteBufferThrottle < (NUMBER_THROTTLE_BUFFER_SIZES - 1))
+				LogDebug("CDiskRecorder::Flush() - Throttle to %d bytes", m_iWriteBufferPos);
+
+			m_iWriteBufferThrottle++;
+		}
+		else if(currentThrottlePackets == throttleToNumberPackets && m_bThrottleAtMax == FALSE)
+		{
+			m_bThrottleAtMax = TRUE;
+			LogDebug("CDiskRecorder::Flush() - Throttle to %d bytes (max)", m_iWriteBufferPos);
+		}
+
+		Flush();
     }
   }
 
@@ -753,6 +864,7 @@
 				m_iWriteBufferPos=0;
 			}
 		}
+		
 	}
 	catch(...)
 	{
Index: DirectShowFilters/TsWriter/source/DiskRecorder.h
===================================================================
--- DirectShowFilters/TsWriter/source/DiskRecorder.h	(revision 27233)
+++ DirectShowFilters/TsWriter/source/DiskRecorder.h	(working copy)
@@ -33,6 +33,11 @@
 using namespace Mediaportal;
 
 
+
+//	Incremental buffer sizes
+#define NUMBER_THROTTLE_BUFFER_SIZES	20
+
+
 //* enum which specified the timeshifting mode 
 enum RecordingMode
 {
@@ -48,6 +53,12 @@
   Other=2
 };
 
+enum ChannelType
+{
+	TV = 0,
+	Radio = 1,
+};
+
 typedef struct stLastPtsDtsRecord
 {
   __int64 m_prevPts ;
@@ -72,6 +83,7 @@
 	~CDiskRecorder(void);
 	
 	void SetFileName(char* pszFileName);
+	void SetChannelType(int channelType);
 	bool Start();
 	void Stop();
 	void Pause( BYTE onOff) ;
@@ -145,6 +157,11 @@
 	int             m_iPart;
   byte*           m_pWriteBuffer;
   int             m_iWriteBufferPos;
+  int			  m_iWriteBufferSize;
+  int			m_iThrottleBufferSizes[NUMBER_THROTTLE_BUFFER_SIZES];
+  int				m_iWriteBufferThrottle;
+  BOOL				m_bThrottleAtMax;
+  ChannelType		m_eChannelType;
   CTsHeader       m_tsHeader;
   CAdaptionField  m_adaptionField;
   CPcr            m_prevPcr;
Index: DirectShowFilters/TsWriter/source/MultiFileWriter.cpp
===================================================================
--- DirectShowFilters/TsWriter/source/MultiFileWriter.cpp	(revision 27233)
+++ DirectShowFilters/TsWriter/source/MultiFileWriter.cpp	(working copy)
@@ -405,12 +405,19 @@
 
 	// Write current position of most recent file.
 	__int64 currentPointer = m_pCurrentTSFile->GetFilePointer();
-	WriteFile(m_hTSBufferFile, &currentPointer, sizeof(currentPointer), &written, NULL);
 
-	// Write filesAdded and filesRemoved values
-	WriteFile(m_hTSBufferFile, &m_filesAdded, sizeof(m_filesAdded), &written, NULL);
-	WriteFile(m_hTSBufferFile, &m_filesRemoved, sizeof(m_filesRemoved), &written, NULL);
+	BYTE* writeBuffer = new BYTE[65536];
+	BYTE* writePointer = writeBuffer;
 
+	*((__int64*)writePointer) = currentPointer;
+	writePointer += sizeof(__int64);
+	
+	*((long*)writePointer) = m_filesAdded;
+	writePointer += sizeof(long);
+	
+	*((long*)writePointer) = m_filesRemoved;
+	writePointer += sizeof(long);
+
 	// Write out all the filenames (null terminated)
 	std::vector<LPWSTR>::iterator it = m_tsFileNames.begin();
 	for ( ; it < m_tsFileNames.end() ; it++ )
@@ -418,22 +425,33 @@
 		LPWSTR pFilename = *it;
 		long length = wcslen(pFilename)+1;
 		length *= sizeof(wchar_t);
-		WriteFile(m_hTSBufferFile, pFilename, length, &written, NULL);
+
+		memcpy(writePointer, pFilename, length);
+		writePointer += length;
+
+		if((writePointer - writeBuffer) > 60000)
+		{
+			LogDebug("MultiFileWriter: TS buffer file has exceeded maximum length.  Reduce the number of timeshifting files");
+			delete[] writeBuffer;
+			return S_FALSE;
+		}
 	}
 
 	// Finish up with a unicode null character in case we want to put stuff after this in the future.
 	wchar_t temp = 0;
-	WriteFile(m_hTSBufferFile, &temp, sizeof(temp), &written, NULL);
+	*((wchar_t*)writePointer) = temp;
+	writePointer += sizeof(wchar_t);
+	
+	
+	*((long*)writePointer) = m_filesAdded;
+	writePointer += sizeof(long);
+	
+	*((long*)writePointer) = m_filesRemoved;
+	writePointer += sizeof(long);
 
-	// Write again filesAdded and filesRemoved values for integrity check.
-	WriteFile(m_hTSBufferFile, &m_filesAdded, sizeof(m_filesAdded), &written, NULL);
-	WriteFile(m_hTSBufferFile, &m_filesRemoved, sizeof(m_filesRemoved), &written, NULL);
+	WriteFile(m_hTSBufferFile, writeBuffer, writePointer - writeBuffer, &written, NULL);
+	delete[] writeBuffer;
 
-	//randomly park the file pointer to help minimise HDD clogging
-//	if(m_pCurrentTSFile && m_pCurrentTSFile->GetFilePointer()&1)
-		SetFilePointer(m_hTSBufferFile, 0, NULL, FILE_END);
-//	else
-//		SetFilePointer(m_hTSBufferFile, 0, NULL, FILE_BEGIN);
 
 	return S_OK;
 }
Index: DirectShowFilters/TsWriter/source/TsWriter.cpp
===================================================================
--- DirectShowFilters/TsWriter/source/TsWriter.cpp	(revision 27233)
+++ DirectShowFilters/TsWriter/source/TsWriter.cpp	(working copy)
@@ -697,7 +697,14 @@
   pChannel->m_pTimeShifting->SetFileName( pszFileName);
 	return S_OK;
 }
-
+STDMETHODIMP CMpTs::TimeShiftSetChannelType(int handle, int channelType)
+{
+  CTsChannel* pChannel=GetTsChannel(handle);
+  if (pChannel==NULL) return S_OK;
+	pChannel->m_pRecorder->SetChannelType(channelType);
+	pChannel->m_pTimeShifting->SetChannelType(channelType);
+	return S_OK;
+}
 STDMETHODIMP CMpTs::TimeShiftStart( int handle )
 {
   CTsChannel* pChannel=GetTsChannel(handle);
Index: DirectShowFilters/TsWriter/source/TsWriter.h
===================================================================
--- DirectShowFilters/TsWriter/source/TsWriter.h	(revision 27233)
+++ DirectShowFilters/TsWriter/source/TsWriter.h	(working copy)
@@ -69,6 +69,7 @@
 	STDMETHOD(RecordSetVideoAudioObserver)(THIS_ int handle, IVideoAudioObserver* callback)PURE;
 
 	STDMETHOD(TimeShiftSetTimeShiftingFileName)(THIS_ int handle, char* pszFileName)PURE;
+    STDMETHOD(TimeShiftSetChannelType)(THIS_ int handle, int channelType)PURE;
 	STDMETHOD(TimeShiftStart)(THIS_ int handle )PURE;
 	STDMETHOD(TimeShiftStop)(THIS_ int handle )PURE;
 	STDMETHOD(TimeShiftReset)(THIS_ int handle )PURE;
@@ -188,6 +189,7 @@
 		STDMETHODIMP RecordSetVideoAudioObserver(int handle, IVideoAudioObserver* callback);
 
 		STDMETHODIMP TimeShiftSetTimeShiftingFileName( int handle, char* pszFileName);
+		STDMETHODIMP TimeShiftSetChannelType(int handle, int channelType);
 		STDMETHODIMP TimeShiftStart( int handle );
 		STDMETHODIMP TimeShiftStop( int handle );
 		STDMETHODIMP TimeShiftReset( int handle );
Index: TvEngine3/TVLibrary/TVLibrary/Implementations/Analog/Graphs/Analog/AnalogSubChannel.cs
===================================================================
--- TvEngine3/TVLibrary/TVLibrary/Implementations/Analog/Graphs/Analog/AnalogSubChannel.cs	(revision 27233)
+++ TvEngine3/TVLibrary/TVLibrary/Implementations/Analog/Graphs/Analog/AnalogSubChannel.cs	(working copy)
@@ -163,6 +163,17 @@
       _mpRecord.SetTimeShiftParams(_subChannelId, parameters.MinimumFiles, parameters.MaximumFiles,
                                    parameters.MaximumFileSize);
       _mpRecord.SetTimeShiftFileName(_subChannelId, fileName);
+
+      //  Set the channel type
+      if (CurrentChannel == null)
+      {
+        Log.Log.Error("Error, CurrentChannel is null when trying to start timeshifting");
+        return false;
+      }
+
+      //  0=tv, 1=radio
+      _mpRecord.SetChannelType(_subChannelId, (CurrentChannel.IsTv ? 0 : 1));
+
       _mpRecord.StartTimeShifting(_subChannelId);
       _dateTimeShiftStarted = DateTime.Now;
       return true;
Index: TvEngine3/TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/HDPVRChannel.cs
===================================================================
--- TvEngine3/TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/HDPVRChannel.cs	(revision 27233)
+++ TvEngine3/TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/HDPVRChannel.cs	(working copy)
@@ -203,6 +203,15 @@
                                             parameters.MaximumFileSize);
       _tsFilterInterface.TimeShiftSetTimeShiftingFileName(_subChannelId, fileName);
 
+      if (CurrentChannel == null)
+      {
+        Log.Log.Error("CurrentChannel is null when trying to start timeshifting");
+        return false;
+      }
+
+      //  Set the channel type (0=tv, 1=radio)
+      _tsFilterInterface.TimeShiftSetChannelType(_subChannelId, (CurrentChannel.IsTv ? 0 : 1));
+
       _tsFilterInterface.TimeShiftPause(_subChannelId, 1);
       _tsFilterInterface.TimeShiftSetPmtPid(_subChannelId, 0x0100, 1, _pmtData, _pmtLength);
       _tsFilterInterface.AnalyzerSetVideoPid(_subChannelId, 0x1011);
Index: TvEngine3/TVLibrary/TVLibrary/Implementations/DVB/Graphs/TvDvbChannel.cs
===================================================================
--- TvEngine3/TVLibrary/TVLibrary/Implementations/DVB/Graphs/TvDvbChannel.cs	(revision 27233)
+++ TvEngine3/TVLibrary/TVLibrary/Implementations/DVB/Graphs/TvDvbChannel.cs	(working copy)
@@ -577,6 +577,16 @@
         _tsFilterInterface.TimeShiftSetParams(_subChannelIndex, _parameters.MinimumFiles, _parameters.MaximumFiles,
                                               _parameters.MaximumFileSize);
         _tsFilterInterface.TimeShiftSetTimeShiftingFileName(_subChannelIndex, fileName);
+
+        if (CurrentChannel == null)
+        {
+          Log.Log.Error("CurrentChannel is null when trying to start timeshifting");
+          return false;
+        }
+
+        //  Set the channel type (0=tv, 1=radio)
+        _tsFilterInterface.TimeShiftSetChannelType(_subChannelId, (CurrentChannel.IsTv ? 0 : 1));
+
         Log.Log.WriteFile("subch:{0} SetTimeShiftFileName fill in pids", _subChannelId);
         _startTimeShifting = false;
         SetTimeShiftPids();
Index: TvEngine3/TVLibrary/TVLibrary/Interfaces/Analyzer/IMPRecord.cs
===================================================================
--- TvEngine3/TVLibrary/TVLibrary/Interfaces/Analyzer/IMPRecord.cs	(revision 27233)
+++ TvEngine3/TVLibrary/TVLibrary/Interfaces/Analyzer/IMPRecord.cs	(working copy)
@@ -81,6 +81,15 @@
     int SetTimeShiftFileName(int subChannelId, [In, MarshalAs(UnmanagedType.LPStr)] string fileName);
 
     /// <summary>
+    /// Sets the type of channel we are timeshifting
+    /// </summary>
+    /// <param name="subChannelId">SubChannel id</param>
+    /// <param name="channelType">Channel type (0=tv, 1=radio)</param>
+    /// <returns></returns>
+    [PreserveSig]
+    int SetChannelType(int subChannelId, int channelType);
+
+    /// <summary>
     /// Starts  time shifting.
     /// </summary>
     /// <param name="subChannelId">SubChannel id</param>
Index: TvEngine3/TVLibrary/TVLibrary/Interfaces/Analyzer/ITsFilter.cs
===================================================================
--- TvEngine3/TVLibrary/TVLibrary/Interfaces/Analyzer/ITsFilter.cs	(revision 27233)
+++ TvEngine3/TVLibrary/TVLibrary/Interfaces/Analyzer/ITsFilter.cs	(working copy)
@@ -201,6 +201,15 @@
     int TimeShiftSetTimeShiftingFileName(int handle, [In, MarshalAs(UnmanagedType.LPStr)] string fileName);
 
     /// <summary>
+    /// Sets the channel type of the sub channel
+    /// </summary>
+    /// <param name="handle">Handle of the sub channel</param>
+    /// <param name="channelType">Type of the channel (tv=0, radio=1)</param>
+    /// <returns></returns>
+    [PreserveSig]
+    int TimeShiftSetChannelType(int handle, int channelType);
+
+    /// <summary>
     /// Starts timeshifting on the given sub channel
     /// </summary>
     /// <param name="handle">Handle of the sub channel</param>
Index: TvEngine3/TVLibrary/TVLibrary/Streaming/RtspStream.cs
===================================================================
--- TvEngine3/TVLibrary/TVLibrary/Streaming/RtspStream.cs	(revision 27233)
+++ TvEngine3/TVLibrary/TVLibrary/Streaming/RtspStream.cs	(working copy)
@@ -33,6 +33,7 @@
     private readonly string _streamName;
     private readonly ITVCard _card;
     private readonly string _recording;
+    private readonly bool _isTv;
 
     #endregion
 
@@ -44,12 +45,14 @@
     /// <param name="streamName">Name of the stream.</param>
     /// <param name="fileName">Name of the file.</param>
     /// <param name="card">The card.</param>
-    public RtspStream(string streamName, string fileName, ITVCard card)
+    /// <param name="bool">True if the stream originates from a tv channel, false for a radio channel</param>
+    public RtspStream(string streamName, string fileName, ITVCard card, bool isTv)
     {
       _streamName = streamName;
       _fileName = fileName;
       _recording = "";
       _card = card;
+      _isTv = isTv;
     }
 
     /// <summary>
@@ -106,6 +109,17 @@
       get { return _card; }
     }
 
+    /// <summary>
+    /// Gets if the stream originates from a tv channel (false for radio)
+    /// </summary>
+    public bool IsTv
+    {
+      get
+      {
+        return _isTv;
+      }
+    }
+
     #endregion
   }
 }
\ No newline at end of file
Index: TvEngine3/TVLibrary/TVLibrary/Streaming/RtspStreaming.cs
===================================================================
--- TvEngine3/TVLibrary/TVLibrary/Streaming/RtspStreaming.cs	(revision 27233)
+++ TvEngine3/TVLibrary/TVLibrary/Streaming/RtspStreaming.cs	(working copy)
@@ -45,10 +45,10 @@
     private static extern void StreamRun();
 
     [DllImport("StreamingServer.dll", CharSet = CharSet.Ansi)]
-    private static extern void StreamAddTimeShiftFile(string streamName, string fileName, bool isProgramStream);
+    private static extern void StreamAddTimeShiftFile(string streamName, string fileName, bool isProgramStream, int channelType);
 
     [DllImport("StreamingServer.dll", CharSet = CharSet.Ansi)]
-    private static extern void StreamAddMpegFile(string streamName, string fileName);
+    private static extern void StreamAddMpegFile(string streamName, string fileName, int channelType);
 
     [DllImport("StreamingServer.dll", CharSet = CharSet.Ansi)]
     private static extern void StreamRemove(string streamName);
@@ -276,11 +276,11 @@
         Log.Log.WriteFile("RTSP: add stream {0} file:{1}", stream.Name, stream.FileName);
         if (stream.Card != null)
         {
-          StreamAddTimeShiftFile(stream.Name, stream.FileName, false);
+          StreamAddTimeShiftFile(stream.Name, stream.FileName, false, (stream.IsTv ? 0 : 1));
         }
         else
         {
-          StreamAddMpegFile(stream.Name, stream.FileName);
+          StreamAddMpegFile(stream.Name, stream.FileName,0);
         }
         _streams[stream.Name] = stream;
       }
Index: TvEngine3/TVLibrary/TvService/TVController.cs
===================================================================
--- TvEngine3/TVLibrary/TvService/TVController.cs	(revision 27233)
+++ TvEngine3/TVLibrary/TvService/TVController.cs	(working copy)
@@ -1856,8 +1856,19 @@
             if (File.Exists(fileName))
             {
               _streamer.Start();
+
+              //  Default to tv
+              bool isTv = true;
+
+              ITvSubChannel subChannel = _cards[cardId].Card.GetSubChannel(user.SubChannel);
+
+              if (subChannel != null && subChannel.CurrentChannel != null)
+                isTv = subChannel.CurrentChannel.IsTv;
+              else
+                Log.Error("SubChannel or CurrentChannel is null when starting streaming");
+
               RtspStream stream = new RtspStream(String.Format("stream{0}.{1}", cardId, user.SubChannel), fileName,
-                                                 _cards[cardId].Card);
+                                                 _cards[cardId].Card, isTv);
               _streamer.AddStream(stream);
             }
             else
