[xiph-commits] r10767 - branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2

illiminable at svn.xiph.org illiminable at svn.xiph.org
Sun Jan 29 04:46:29 PST 2006


Author: illiminable
Date: 2006-01-29 04:46:13 -0800 (Sun, 29 Jan 2006)
New Revision: 10767

Added:
   branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPStreamingFileSource.cpp
   branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPStreamingFileSource.h
Modified:
   branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/FilterFileSource.cpp
   branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/FilterFileSource.h
   branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPFileSource.cpp
   branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPFileSource.h
   branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPSocket.cpp
   branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPSocket.h
   branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/IFilterDataSource.h
   branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/dsfOggDemux2.vcproj
Log:
* Start of changes to stream caching. Previously read ahead as fast as possible caching to disk. This caused problems, because for fast start, the thread reads when the graph is loaded but stopped, but meant that in order to do this, large transfers could occur while the media was supposed to be stopped. Now caches in memory only a certain distance ahead. This will also make it easier to do seeking over http on dumb servers.

Modified: branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/FilterFileSource.cpp
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/FilterFileSource.cpp	2006-01-29 10:16:12 UTC (rev 10766)
+++ branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/FilterFileSource.cpp	2006-01-29 12:46:13 UTC (rev 10767)
@@ -47,7 +47,7 @@
 void FilterFileSource::close() {
 	mSourceFile.close();
 }
-bool FilterFileSource::open(string inSourceLocation) {
+bool FilterFileSource::open(string inSourceLocation, unsigned long) {
 	mSourceFile.open(inSourceLocation.c_str(), ios_base::in|ios_base::binary);
 	return mSourceFile.is_open();
 }

Modified: branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/FilterFileSource.h
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/FilterFileSource.h	2006-01-29 10:16:12 UTC (rev 10766)
+++ branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/FilterFileSource.h	2006-01-29 12:46:13 UTC (rev 10767)
@@ -45,7 +45,7 @@
 	//IFilterDataSource Interface
 	virtual unsigned long seek(unsigned long inPos);
 	virtual void close();
-	virtual bool open(string inSourceLocation);
+	virtual bool open(string inSourceLocation, unsigned long inStartByte = 0);
 	virtual void clear();
 	virtual bool isEOF();
 	virtual bool isError()								{	return false;	}

Modified: branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPFileSource.cpp
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPFileSource.cpp	2006-01-29 10:16:12 UTC (rev 10766)
+++ branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPFileSource.cpp	2006-01-29 12:46:13 UTC (rev 10767)
@@ -367,7 +367,7 @@
 	CallWorker(THREAD_RUN);
 	return true;
 }
-bool HTTPFileSource::open(string inSourceLocation) {
+bool HTTPFileSource::open(string inSourceLocation, unsigned long inStartByte) {
 	//Open network connection and start feeding data into a buffer
 	//
 	mSeenResponse = false;

Modified: branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPFileSource.h
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPFileSource.h	2006-01-29 10:16:12 UTC (rev 10766)
+++ branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPFileSource.h	2006-01-29 12:46:13 UTC (rev 10767)
@@ -56,7 +56,7 @@
 	//IFilterDataSource Interface
 	virtual unsigned long seek(unsigned long inPos);
 	virtual void close() ;
-	virtual bool open(string inSourceLocation);
+	virtual bool open(string inSourceLocation, unsigned long inStartByte = 0);
 	virtual void clear();
 	virtual bool isEOF();
 	virtual bool isError();

Modified: branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPSocket.cpp
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPSocket.cpp	2006-01-29 10:16:12 UTC (rev 10766)
+++ branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPSocket.cpp	2006-01-29 12:46:13 UTC (rev 10767)
@@ -64,8 +64,10 @@
 }
 
 
-bool HTTPSocket::setupSocket(string inSourceLocation) {
-	
+bool HTTPSocket::setupSocket(string inSourceLocation) 
+{
+
+	mSourceLocation = inSourceLocation;
 	//debugLog2<<"Setup Socket:"<<endl;
 	IN_ADDR locAddress;  //iaHost
 	LPHOSTENT locHostData;;  //lpHost
@@ -131,9 +133,15 @@
 
 }
 
-string HTTPSocket::assembleRequest(string inFilePath) {
+string HTTPSocket::assembleRequest(string inFilePath, unsigned long inStartByte) {
 	string retRequest;
-	retRequest = "GET " + inFilePath+ " HTTP/1.1\r\n" + "Host: " + mServerName+ "\r\n" + "Connection: close" + "\r\n\r\n";
+	retRequest = "GET " + inFilePath+ " HTTP/1.1\r\n" + "Host: " + mServerName+ "\r\n" + "Connection: close";
+	
+	if (inStartByte != 0) {
+		retRequest = retRequest + "\r\n" + "Range: bytes=" + StringHelper::numToString(inStartByte) + "-";
+	}
+	
+	retRequest += "\r\n\r\n";
 	//debugLog2<<"Assembled Req : "<<endl<<retRequest<<endl;
 	return retRequest;
 }

Modified: branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPSocket.h
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPSocket.h	2006-01-29 10:16:12 UTC (rev 10766)
+++ branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPSocket.h	2006-01-29 12:46:13 UTC (rev 10767)
@@ -43,7 +43,8 @@
 	virtual bool setupSocket(string inSourceLocation);
 	virtual void closeSocket();
 	virtual bool splitURL(string inURL);
-	virtual string assembleRequest(string inFilePath);
+	virtual string assembleRequest(string inFilePath, unsigned long inStartByte = 0);
+	//virtual string assembleRequest(string inFilePath);
 	bool httpRequest(string inRequest);
 protected:
 	string mServerName;
@@ -52,6 +53,8 @@
 	string mLastResponse;
 	SOCKET mSocket;
 
+	string mSourceLocation;
+
 	bool mIsEOF;
 	bool mWasError;
 	bool mIsOpen;

Added: branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPStreamingFileSource.cpp
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPStreamingFileSource.cpp	2006-01-29 10:16:12 UTC (rev 10766)
+++ branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPStreamingFileSource.cpp	2006-01-29 12:46:13 UTC (rev 10767)
@@ -0,0 +1,510 @@
+//===========================================================================
+//Copyright (C) 2003, 2004 Zentaro Kavanagh
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+//- Redistributions of source code must retain the above copyright
+//  notice, this list of conditions and the following disclaimer.
+//
+//- Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//
+//- Neither the name of Zentaro Kavanagh nor the names of contributors 
+//  may be used to endorse or promote products derived from this software 
+//  without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+//PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
+//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+//EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+//PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+//PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+//LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//===========================================================================
+#include "stdafx.h"
+#include "HTTPStreamingFileSource.h"
+
+#define OGGCODECS_LOGGING
+HTTPStreamingFileSource::HTTPStreamingFileSource(void)
+	:	mBufferLock(NULL)
+	,	mIsChunked(false)
+	,	mIsFirstChunk(true)
+	,	mChunkRemains(0)
+	,	mNumLeftovers(0)
+	,	mMemoryBuffer(NULL)
+	,	mContentLength(-1)
+{
+	mBufferLock = new CCritSec;
+#ifdef OGGCODECS_LOGGING
+	debugLog.open("d:\\zen\\logs\\htttp.log", ios_base::out | ios_base::app);
+	fileDump.open("d:\\zen\\logs\\filedump.ogg", ios_base::out|ios_base::binary);
+	rawDump.open("D:\\zen\\logs\\rawdump.out", ios_base::out|ios_base::binary);
+#endif
+	
+	mInterBuff = new unsigned char[RECV_BUFF_SIZE* 2];
+	mMemoryBuffer = new CircularBuffer(MEMORY_BUFFER_SIZE);
+
+}
+
+HTTPStreamingFileSource::~HTTPStreamingFileSource(void)
+{
+	//debugLog<<"About to close socket"<<endl;
+	close();
+	//debugLog<<"Winsock ended"<<endl;
+#ifdef OGGCODECS_LOGGING
+	debugLog.close();
+	fileDump.close();
+	rawDump.close();
+#endif
+	delete mBufferLock;
+	delete mInterBuff;
+
+	delete mMemoryBuffer;
+}
+
+void HTTPStreamingFileSource::unChunk(unsigned char* inBuff, unsigned long inNumBytes) 
+{
+
+	//This method is a bit rough and ready !!
+	ASSERT(inNumBytes > 2);
+	rawDump.write((char*)inBuff, inNumBytes);
+	//debugLog<<"UnChunk"<<endl;
+	unsigned long locNumBytesLeft = inNumBytes;
+
+	memcpy((void*)(mInterBuff + mNumLeftovers), (const void*)inBuff, inNumBytes);
+	locNumBytesLeft +=  mNumLeftovers;
+	mNumLeftovers = 0;
+	unsigned char* locWorkingBuffPtr = mInterBuff;
+
+	//debugLog<<"inNumBytes = "<<inNumBytes<<endl;
+
+	while (locNumBytesLeft > 8) {
+		//debugLog<<"---"<<endl;
+		//debugLog<<"Bytes left = "<<locNumBytesLeft<<endl;
+		//debugLog<<"ChunkRemaining = "<<mChunkRemains<<endl;
+
+		if (mChunkRemains == 0) {
+			//debugLog<<"Zero bytes of chunk remains"<<endl;
+
+			//Assign to a string for easy manipulation of the hex size
+			string locTemp;
+		
+			if (mIsFirstChunk) {
+				//debugLog<<"It's the first chunk"<<endl;
+				mIsFirstChunk = false;
+				locTemp = (char*)locWorkingBuffPtr;
+			} else {
+				//debugLog<<"Not the first chunk"<<endl;
+				//debugLog<<"Skip bytes = "<<(int)locWorkingBuffPtr[0]<<(int)locWorkingBuffPtr[1]<<endl;
+				locTemp = (char*)(locWorkingBuffPtr + 2);
+				locWorkingBuffPtr+=2;
+				locNumBytesLeft -= 2;
+			}
+
+	/*		if (mLeftOver != "") {
+				debugLog<<"Sticking the leftovers back together..."<<endl;
+				locTemp = mLeftOver + locTemp;
+				mLeftOver = "";
+			}*/
+
+			size_t locChunkSizePos = locTemp.find("\r\n");
+			
+			
+			if (locChunkSizePos != string::npos) {
+				//debugLog<<"Found the size bytes "<<endl;
+				//Get a string representation of the hex string that tells us the size of the chunk
+				string locChunkSizeStr = locTemp.substr(0, locChunkSizePos);
+				//debugLog<<"Sizingbuytes " << locChunkSizeStr<<endl;
+				char* locDummyPtr = NULL;
+
+				//Convert it to a number
+				mChunkRemains = strtol(locChunkSizeStr.c_str(), &locDummyPtr, 16);
+
+				//debugLog<<"Chunk reamining "<<mChunkRemains<<endl;
+				//The size of the crlf 's and the chunk size value
+				unsigned long locGuffSize = (unsigned long)(locChunkSizeStr.size() + 2);
+				locWorkingBuffPtr +=  locGuffSize;
+				locNumBytesLeft -= locGuffSize;
+			} else {
+				//debugLog<<"************************************** "<<endl;
+			
+
+			}
+		}
+
+		//This is the end of file
+		if (mChunkRemains == 0) {
+			//debugLog<<"EOF"<<endl;
+			return;
+		}
+
+		//If theres less bytes than the remainder of the chunk
+		if (locNumBytesLeft < mChunkRemains) {
+			//debugLog<<"less bytes remain than the chunk needs"<<endl;
+			
+			mMemoryBuffer->write((const unsigned char*)locWorkingBuffPtr, locNumBytesLeft );
+			fileDump.write((char*)locWorkingBuffPtr, locNumBytesLeft);
+			locWorkingBuffPtr += locNumBytesLeft;
+			mChunkRemains -= locNumBytesLeft;
+			locNumBytesLeft = 0;
+		} else {
+			//debugLog<<"more bytes remain than the chunk needs"<<endl;
+			mMemoryBuffer->write((const unsigned char*)locWorkingBuffPtr, mChunkRemains );
+			fileDump.write((char*)locWorkingBuffPtr, mChunkRemains);
+			locWorkingBuffPtr += mChunkRemains;
+			locNumBytesLeft -= mChunkRemains;
+			mChunkRemains = 0;
+		}
+
+	}
+
+	if (locNumBytesLeft != 0) {
+		//debugLog<<"There is a non- zero amount of bytes leftover... buffer them up for next time..."<<endl;
+		memcpy((void*)mInterBuff, (const void*)locWorkingBuffPtr, locNumBytesLeft);
+		mNumLeftovers = locNumBytesLeft;
+	}
+}
+void HTTPStreamingFileSource::DataProcessLoop() {
+	//debugLog<<"DataProcessLoop: "<<endl;
+	int locNumRead = 0;
+	char* locBuff = NULL;
+	DWORD locCommand = 0;
+	bool locSeenAny = false;
+	debugLog<<"Starting dataprocessloop"<<endl;
+
+	locBuff = new char[RECV_BUFF_SIZE];
+
+	while(true) {
+		if(CheckRequest(&locCommand) == TRUE) {
+			debugLog<<"Thread Data Process loop received breakout signal..."<<endl;
+			delete[] locBuff;
+			return;
+		}
+		//debugLog<<"About to call recv"<<endl;
+		locNumRead = recv(mSocket, locBuff, RECV_BUFF_SIZE, 0);
+		//debugLog<<"recv complete"<<endl;
+		if (locNumRead == SOCKET_ERROR) {
+			int locErr = WSAGetLastError();
+			debugLog<<"Socket error receiving - Err No = "<<locErr<<endl;
+			mWasError = true;
+			break;
+		}
+
+		if (locNumRead == 0) {
+			debugLog<<"Read last bytes..."<<endl;
+			mIsEOF = true;
+			delete[] locBuff;
+			return;
+		}
+
+		{//CRITICAL SECTION - PROTECTING BUFFER STATE
+			CAutoLock locLock(mBufferLock);
+			//debugLog <<"Num Read = "<<locNumRead<<endl;
+			if (mSeenResponse) {
+				//Add to buffer
+
+				if (mIsChunked) {
+					unChunk((unsigned char*)locBuff, locNumRead);
+				} else {
+					mMemoryBuffer->write((const unsigned char*)locBuff, locNumRead);
+				}
+			
+				//Dump to file
+				//fileDump.write(locBuff, locNumRead);
+			} else {
+				//if (!locSeenAny) {
+				//	locSeenAny = true;
+				//	//Start of response
+				//	if (locBuff[0] != '2') {
+				//		mWasError = true;
+				//		delete[] locBuff;
+				//		return;
+				//	}
+				//}
+				string locTemp = locBuff;
+				//debugLog<<"Binary follows... "<<endl<<locTemp<<endl;
+				size_t locPos = locTemp.find("\r\n\r\n");
+				if (locPos != string::npos) {
+					//Found the break
+					//debugLog<<"locPos = "<<locPos<<endl;
+					mSeenResponse = true;
+					mLastResponse = locTemp.substr(0, locPos);
+					debugLog<<"HTTP Response:"<<endl;
+					debugLog<<mLastResponse<<endl;
+
+					unsigned short locResponseCode = getHTTPResponseCode(mLastResponse);
+
+					mRetryAt = "";
+					if (locResponseCode == 301) {
+						size_t locLocPos = mLastResponse.find("Location: ");
+						if (locLocPos != string::npos) {
+							locLocPos += 10;
+							size_t locEndPos = mLastResponse.find("\r", locLocPos);
+							if (locEndPos != string::npos) {
+								if (locEndPos > locLocPos) {
+									mRetryAt = mLastResponse.substr(locLocPos, locEndPos - locLocPos);
+									debugLog<<"Retry URL = "<<mRetryAt<<endl;
+								}
+							}
+						}
+
+						debugLog<<"Setting error to true"<<endl;
+						mIsEOF = true;
+						mWasError = true;
+						//close();
+					} else if (locResponseCode >= 300) {
+						debugLog<<"Setting error to true"<<endl;
+						mIsEOF = true;
+						mWasError = true;
+						//close();
+					} else {
+						//Good response
+
+						//Check for content-length
+						mContentLength = -1;
+						size_t locContentLengthPos = mLastResponse.find("Content-Length: ");
+						if (locContentLengthPos != string::npos) {
+							locContentLengthPos += 16;
+
+							size_t locEndPos = mLastResponse.find("\r", locContentLengthPos);
+							if ((locEndPos != string::npos) && (locEndPos > locContentLengthPos)) {
+								string locLengthString = mLastResponse.substr(locContentLengthPos, locEndPos - locContentLengthPos);
+
+								
+								try {
+									__int64 locContentLength = StringHelper::stringToNum(locLengthString);
+									mContentLength = locContentLength;
+								} catch(...) {
+									mContentLength = -1;
+								}
+							}
+						}
+					}
+
+					if (locTemp.find("Transfer-Encoding: chunked") != string::npos) {
+						mIsChunked = true;
+					}
+
+					char* locBuff2 = locBuff + locPos + 4;  //View only - don't delete.
+					locTemp = locBuff2;
+
+					if (mIsChunked) {
+						if (locNumRead - locPos - 4 > 0) {
+							unChunk((unsigned char*)locBuff2, locNumRead - locPos - 4);
+						}
+					} else {
+                        //debugLog<<"Start of data follows"<<endl<<locTemp<<endl;
+						if (locNumRead - locPos - 4 > 0) {
+							mMemoryBuffer->write((const unsigned char*)locBuff2, (locNumRead - (locPos + 4)));
+						}
+					}
+				}
+			}
+		} //END CRITICAL SECTION
+	}
+
+	delete[] locBuff;
+}
+
+unsigned short HTTPStreamingFileSource::getHTTPResponseCode(string inHTTPResponse)
+{
+	size_t locPos = inHTTPResponse.find(" ");
+	if (locPos != string::npos) {
+		string locCodeString = inHTTPResponse.substr(locPos + 1, 3);
+		try {
+			unsigned short locCode = (unsigned short)StringHelper::stringToNum(locCodeString);
+			return locCode;
+		} catch(...) {
+			return 0;
+		}
+	} else {
+		return 0;
+	}
+}
+string HTTPStreamingFileSource::shouldRetryAt()
+{
+	return mRetryAt;
+}
+
+DWORD HTTPStreamingFileSource::ThreadProc(void) {
+	//debugLog<<"ThreadProc:"<<endl;
+	while(true) {
+		DWORD locThreadCommand = GetRequest();
+		
+		switch(locThreadCommand) {
+			case THREAD_EXIT:
+				
+				Reply(S_OK);
+				return S_OK;
+
+			case THREAD_RUN:
+				
+				Reply(S_OK);
+				DataProcessLoop();
+				break;
+				//return S_OK;
+		}
+
+
+	}
+	return S_OK;
+}
+unsigned long HTTPStreamingFileSource::seek(unsigned long inPos) 
+{
+	//Close the socket down
+	//Open up a new one to the same place.
+	//Make the partial content request.
+	//debugLog<<"Seeking to "<<inPos<<endl;
+	
+	if (mContentLength != -1) {
+		close();
+		closeSocket();
+		clear();
+
+		open(mSourceLocation, inPos);
+
+	} else {
+		return (unsigned long) -1;
+	}
+	//if (mFileCache.readSeek(inPos)) {
+	//	return inPos;
+	//} else {
+	//	return (unsigned long) -1;
+	//}
+	
+}
+
+
+void HTTPStreamingFileSource::close() {
+	//Killing thread
+	//debugLog<<"HTTPStreamingFileSource::close()"<<endl;
+	if (ThreadExists() == TRUE) {
+		//debugLog<<"Calling Thread to EXIT"<<endl;
+		CallWorker(THREAD_EXIT);
+		//debugLog<<"Killing thread..."<<endl;
+		Close();
+		//debugLog<<"After Close called on CAMThread"<<endl;
+	}
+
+
+	
+	//debugLog<<"Closing socket..."<<endl;
+	//Close the socket down.
+	closeSocket();
+}
+
+bool HTTPStreamingFileSource::startThread() {
+	if (ThreadExists() == FALSE) {
+		Create();
+	}
+	CallWorker(THREAD_RUN);
+	return true;
+}
+bool HTTPStreamingFileSource::open(string inSourceLocation, unsigned long inStartByte) {
+	//Open network connection and start feeding data into a buffer
+	//
+	mSeenResponse = false;
+	mLastResponse = "";
+	//debugLog<<"Open: "<<inSourceLocation<<endl;
+
+	{ //CRITICAL SECTION - PROTECTING STREAM BUFFER
+		CAutoLock locLock(mBufferLock);
+		
+		////Init rand number generator
+		//LARGE_INTEGER locTicks;
+		//QueryPerformanceCounter(&locTicks);
+		//srand((unsigned int)locTicks.LowPart);
+
+		//int locRand = rand();
+
+		//string locCacheFileName = getenv("TEMP");
+		////debugLog<<"Temp = "<<locCacheFileName<<endl;
+		//locCacheFileName += "\\filecache";
+		//
+		//locCacheFileName += StringHelper::numToString(locRand);
+		//locCacheFileName += ".ogg";
+		//debugLog<<"Cache file  = "<<locCacheFileName<<endl;
+		//if(mFileCache.open(locCacheFileName)) {
+		//	//debugLog<<"OPEN : Cach file opened"<<endl;
+		//}
+
+		mMemoryBuffer->reset();
+	} //END CRITICAL SECTION
+
+	bool locIsOK = setupSocket(inSourceLocation);
+
+	if (!locIsOK) {
+		//debugLog<<"Setup socket FAILED"<<endl;
+		closeSocket();
+		return false;
+	}
+
+	//debugLog<<"Sending request..."<<endl;
+
+	//How is filename already set ??
+	httpRequest(assembleRequest(mFileName, inStartByte));
+	//debugLog<<"Socket ok... starting thread"<<endl;
+	locIsOK = startThread();
+
+
+	return locIsOK;
+}
+void HTTPStreamingFileSource::clear() {
+	//Reset flags.
+	debugLog<<"Setting error to false";
+	mIsEOF = false;
+	mWasError = false;
+	mRetryAt = "";
+	mSourceLocation = "";
+	mContentLength = -1;
+}
+bool HTTPStreamingFileSource::isError()
+{
+	return mWasError;
+}
+bool HTTPStreamingFileSource::isEOF() {
+	{ //CRITICAL SECTION - PROTECTING STREAM BUFFER
+		CAutoLock locLock(mBufferLock);
+		unsigned long locSizeBuffed = mMemoryBuffer->numBytesAvail(); //mFileCache.bytesAvail();;
+	
+		//debugLog<<"isEOF : Amount Buffered avail = "<<locSizeBuffed<<endl;
+		if ((locSizeBuffed == 0) && mIsEOF) {
+			//debugLog<<"isEOF : It is EOF"<<endl;
+			return true;
+		} else {
+			//debugLog<<"isEOF : It's not EOF"<<endl;
+			return false;
+		}
+	} //END CRITICAL SECTION
+
+}
+unsigned long HTTPStreamingFileSource::read(char* outBuffer, unsigned long inNumBytes) {
+	//Reads from the buffer, will return 0 if nothing in buffer.
+	// If it returns 0 check the isEOF flag to see if it was the end of file or the network is just slow.
+
+	{ //CRITICAL SECTION - PROTECTING STREAM BUFFER
+		CAutoLock locLock(mBufferLock);
+		
+		//debugLog<<"Read:"<<endl;
+		if((mMemoryBuffer->numBytesAvail() == 0) || mWasError) {
+			//debugLog<<"read : Can't read is error or eof"<<endl;
+			return 0;
+		} else {
+			//debugLog<<"Reading from buffer"<<endl;
+			
+			unsigned long locNumRead = mMemoryBuffer->read((unsigned char*)outBuffer, inNumBytes);
+
+			if (locNumRead > 0) {
+				debugLog<<locNumRead<<" bytes read from buffer"<<endl;
+			}
+			return locNumRead;
+		}
+	} //END CRITICAL SECTION
+}

Added: branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPStreamingFileSource.h
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPStreamingFileSource.h	2006-01-29 10:16:12 UTC (rev 10766)
+++ branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/HTTPStreamingFileSource.h	2006-01-29 12:46:13 UTC (rev 10767)
@@ -0,0 +1,100 @@
+
+//===========================================================================
+//Copyright (C) 2003-2006 Zentaro Kavanagh
+//
+//Redistribution and use in source and binary forms, with or without
+//modification, are permitted provided that the following conditions
+//are met:
+//
+//- Redistributions of source code must retain the above copyright
+//  notice, this list of conditions and the following disclaimer.
+//
+//- Redistributions in binary form must reproduce the above copyright
+//  notice, this list of conditions and the following disclaimer in the
+//  documentation and/or other materials provided with the distribution.
+//
+//- Neither the name of Zentaro Kavanagh nor the names of contributors 
+//  may be used to endorse or promote products derived from this software 
+//  without specific prior written permission.
+//
+//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+//``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+//PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE ORGANISATION OR
+//CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+//EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+//PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+//PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+//LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+//NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//===========================================================================
+#pragma once
+#include "oggdllstuff.h"
+
+#include "HTTPSocket.h"
+#include "IFilterDataSource.h"
+#include <string>
+#include <sstream>
+#include <fstream>
+
+using namespace std;
+
+class OGG_DEMUX2_API HTTPStreamingFileSource
+	:	public IFilterDataSource
+	,	public CAMThread
+	,	protected HTTPSocket	
+{
+public:
+	HTTPStreamingFileSource(void);
+	virtual ~HTTPStreamingFileSource(void);
+
+	//Consts
+	static const unsigned long MEMORY_BUFFER_SIZE = 1024 * 1024 * 2;
+	//Thread commands
+	static const int THREAD_RUN = 0;
+	static const int THREAD_EXIT = 1;
+
+	//IFilterDataSource Interface
+	virtual unsigned long seek(unsigned long inPos);
+	virtual void close() ;
+	virtual bool open(string inSourceLocation, unsigned long inStartByte = 0);
+	virtual void clear();
+	virtual bool isEOF();
+	virtual bool isError();
+	virtual unsigned long read(char* outBuffer, unsigned long inNumBytes);
+	virtual string shouldRetryAt();
+
+	
+	//CAMThread pure virtuals
+	DWORD ThreadProc();
+
+
+
+protected:
+	void unChunk(unsigned char* inBuff, unsigned long inNumBytes);
+	unsigned short getHTTPResponseCode(string inHTTPResponse);
+	bool startThread();
+	void DataProcessLoop();
+
+	//SingleMediaFileCache mFileCache;
+	CircularBuffer* mMemoryBuffer;
+
+	bool mIsChunked;
+	unsigned long mChunkRemains;
+
+	bool mIsFirstChunk;
+	string mRetryAt;
+
+	fstream debugLog;
+	fstream fileDump;
+	fstream rawDump;
+
+	unsigned char* mInterBuff;
+	unsigned long mNumLeftovers;
+	static	const unsigned long RECV_BUFF_SIZE = 1024;
+
+	__int64 mContentLength;
+
+	CCritSec* mBufferLock;
+};

Modified: branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/IFilterDataSource.h
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/IFilterDataSource.h	2006-01-29 10:16:12 UTC (rev 10766)
+++ branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/IFilterDataSource.h	2006-01-29 12:46:13 UTC (rev 10767)
@@ -40,7 +40,7 @@
 
 	virtual unsigned long seek(unsigned long inPos) = 0;
 	virtual void close()  = 0;
-	virtual bool open(string inSourceLocation) = 0;
+	virtual bool open(string inSourceLocation, unsigned long inStartByte = 0) = 0;
 	virtual void clear() = 0;
 	virtual bool isEOF() = 0;
 	virtual bool isError() = 0;

Modified: branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/dsfOggDemux2.vcproj
===================================================================
--- branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/dsfOggDemux2.vcproj	2006-01-29 10:16:12 UTC (rev 10766)
+++ branches/oggdsf_new_demux/src/lib/core/directshow/dsfOggDemux2/dsfOggDemux2.vcproj	2006-01-29 12:46:13 UTC (rev 10767)
@@ -140,6 +140,9 @@
 				RelativePath=".\HTTPSocket.cpp">
 			</File>
 			<File
+				RelativePath=".\HTTPStreamingFileSource.cpp">
+			</File>
+			<File
 				RelativePath=".\OggDemuxPacketSourceFilter.cpp">
 			</File>
 			<File
@@ -193,6 +196,9 @@
 				RelativePath=".\HTTPSocket.h">
 			</File>
 			<File
+				RelativePath=".\HTTPStreamingFileSource.h">
+			</File>
+			<File
 				RelativePath=".\IFilterDataSource.h">
 			</File>
 			<File
@@ -202,6 +208,9 @@
 				RelativePath=".\IOggDecoder.h">
 			</File>
 			<File
+				RelativePath=".\IOggFilterSeeker.h">
+			</File>
+			<File
 				RelativePath=".\IOggOutputPin.h">
 			</File>
 			<File



More information about the commits mailing list