void QTFile_FileControlBlock::Set( char * DataPath) { #if DSS_USE_API_CALLBACKS (void)QTSS_OpenFileObject(DataPath, qtssOpenFileReadAhead, &fDataFD); #else fDataFD.Set(DataPath); #endif }
char* QTAccessFile::GetAccessFile_Copy( const char* movieRootDir, const char* dirPath) { OSMutexLocker locker(sAccessFileMutex); char* currentDir= NULL; char* lastSlash = NULL; int movieRootDirLen = ::strlen(movieRootDir); int maxLen = strlen(dirPath)+strlen(sQTAccessFileName) + strlen(kPathDelimiterString) + 1; currentDir = NEW char[maxLen]; ::strcpy(currentDir, dirPath); //strip off filename lastSlash = ::strrchr(currentDir, kPathDelimiterChar); if (lastSlash != NULL) lastSlash[0] = '\0'; //check qtaccess files while ( true ) //walk backward up the dir tree. { int curLen = strlen(currentDir) + strlen(sQTAccessFileName) + strlen(kPathDelimiterString); if ( curLen >= maxLen ) break; ::strcat(currentDir, kPathDelimiterString); ::strcat(currentDir, sQTAccessFileName); QTSS_Object fileObject = NULL; if( QTSS_OpenFileObject(currentDir, qtssOpenFileNoFlags, &fileObject) == QTSS_NoErr) { (void)QTSS_CloseFileObject(fileObject); return currentDir; } //strip off the "/qtaccess" lastSlash = ::strrchr(currentDir, kPathDelimiterChar); lastSlash[0] = '\0'; //strip of the tailing directory lastSlash = ::strrchr(currentDir, kPathDelimiterChar); if (lastSlash == NULL) break; else lastSlash[0] = '\0'; if ( (lastSlash-currentDir) < movieRootDirLen ) //bail if we start eating our way out of fMovieRootDir break; } delete[] currentDir; return NULL; }
RTPFileSession::ErrorCode RTPFileSession::Initialize(StrPtrLen& inFilePath, Float32 inBufferSeconds) { Assert(fFile == NULL); // Check to see if this file is already open OSMutexLocker locker(sOpenFileMap.GetMutex()); OSRef* theFileRef = sOpenFileMap.Resolve((StrPtrLen*)&inFilePath); if (theFileRef == NULL) { //qtss_printf("Didn't find file in map. Creating new one\n"); fFile = NEW RTPFile(); ErrorCode theErr = fFile->Initialize(inFilePath); if (theErr != errNoError) { delete fFile; fFile = NULL; return theErr; } OS_Error osErr = sOpenFileMap.Register(fFile->GetRef()); Assert(osErr == OS_NoErr); //unless we do this, the refcount won't increment (and we'll delete the session prematurely OSRef* debug = sOpenFileMap.Resolve((StrPtrLen*)&inFilePath); Assert(debug == fFile->GetRef()); } else { //qtss_printf("Found file. Refcounting.\n"); fFile = (RTPFile*)theFileRef->GetObject(); } //Open the file no matter what //fFileSource.Set(inFilePath.Ptr); //Assert(fFileSource.GetLength() > 0); QTSS_Error theErr = QTSS_OpenFileObject(inFilePath.Ptr, 0, &fFileSource); Assert(theErr == QTSS_NoErr); // // Get the file length UInt32 theLen = sizeof(fFileLength); theErr = QTSS_GetValue(fFileSource, qtssFlObjLength, 0, &fFileLength, &theLen); Assert(theErr == QTSS_NoErr); Assert(theLen == sizeof(fFileLength)); // Allocate our data buffer fDataBufferSize = this->PowerOf2Floor((UInt32)(inBufferSeconds * fFile->GetBytesPerSecond())); // Check to see if the size is out of range. If so, adjust it if (fDataBufferSize > kMaxDataBufferSize) fDataBufferSize = kMaxDataBufferSize; if (fDataBufferSize < kBlockSize) fDataBufferSize = kBlockSize; fReadBuffer = fDataBuffer = NEW UInt8[fDataBufferSize]; // Allocate a buffer of TrackInfos fTrackInfo = NEW RTPFileSessionTrackInfo[fFile->GetMaxTrackNumber() + 1]; ::memset(fTrackInfo, 0, fFile->GetMaxTrackNumber() * sizeof(RTPFileSessionTrackInfo)); return errNoError; }
RTPFileSession::ErrorCode RTPFile::Initialize(const StrPtrLen& inFilePath) { //OSFileSource theFile(inFilePath.Ptr); QTSS_Object theFile = NULL; QTSS_Error theErr = QTSS_OpenFileObject(inFilePath.Ptr, 0, &theFile); if (theErr != QTSS_NoErr) return RTPFileSession::errFileNotFound; // Copy the path. fFilePath.Ptr = NEW char[inFilePath.Len + 1]; ::memcpy(fFilePath.Ptr, inFilePath.Ptr, inFilePath.Len); fFilePath.Len = inFilePath.Len; // Setup our osref fRef.Set(fFilePath, this); // Read the header //OS_Error theErr = theFile.Read(&fHeader, sizeof(fHeader)); UInt32 theLengthRead = 0; theErr = QTSS_Read(theFile, &fHeader, sizeof(fHeader), &theLengthRead); Assert(theErr == QTSS_NoErr); Assert(theLengthRead == sizeof(fHeader)); // Read the SDP data fSDPData.Len = fHeader.fSDPLen; fSDPData.Ptr = NEW char[fSDPData.Len + 1]; //theErr = theFile.Read(fSDPData.Ptr, fSDPData.Len); theErr = QTSS_Read(theFile, fSDPData.Ptr, fSDPData.Len, &theLengthRead); Assert(theErr == QTSS_NoErr); Assert(theLengthRead == fSDPData.Len); // Parse the SDP Information fSourceInfo.Parse(fSDPData.Ptr, fSDPData.Len); // Read the track info fTrackInfo = NEW RTPFileTrackInfo[fHeader.fNumTracks]; //theErr = theFile.Read(fTrackInfo, sizeof(RTPFileTrackInfo) * fHeader.fNumTracks); theErr = QTSS_Read(theFile, fTrackInfo, sizeof(RTPFileTrackInfo) * fHeader.fNumTracks, &theLengthRead); Assert(theErr == QTSS_NoErr); Assert(theLengthRead == sizeof(RTPFileTrackInfo) * fHeader.fNumTracks); // Create and read the block map fBlockMap = NEW UInt8[fHeader.fBlockMapSize]; //theErr = theFile.Read(fBlockMap, fHeader.fBlockMapSize); theErr = QTSS_Read(theFile, fBlockMap, fHeader.fBlockMapSize, &theLengthRead); Assert(theErr == QTSS_NoErr); Assert(theLengthRead == fHeader.fBlockMapSize); // Calculate bit rate of all the tracks combined Float64 totalBytes = 0; for (UInt32 x = 0; x < fHeader.fNumTracks; x++) totalBytes += (Float64)fTrackInfo[x].fBytesInTrack; totalBytes /= fHeader.fMovieDuration; fBytesPerSecond = (UInt32)totalBytes; //Get the max track number fMaxTrackNumber = 0; for (UInt32 y = 0; y < fHeader.fNumTracks; y++) if (fTrackInfo[y].fID > fMaxTrackNumber) fMaxTrackNumber = fTrackInfo[y].fID; (void)QTSS_CloseFileObject(theFile); return RTPFileSession::errNoError; }
QTSS_Error Preprocess(QTSS_StandardRTSP_Params* inParams) { static UInt32 sFileBufSize = 32768; static UInt32 sInitialState = kReadingBufferState; static UInt32 sZero = 0; UInt32 theLen = 0; UInt32* theStateP = NULL; QTSS_Error theErr = QTSS_NoErr; QTSS_Object theFile = NULL; (void)QTSS_GetValuePtr(inParams->inRTSPSession, sStateAttr, 0, (void**)&theStateP, &theLen); if ((theStateP == NULL) || (theLen != sizeof(UInt32))) { // Initial state. We haven't started sending the file yet, so // check to see if this is our request, and if it is, set everything up. // Only operate if this is a DESCRIBE QTSS_RTSPMethod* theMethod = NULL; UInt32 theLen = 0; if ((QTSS_GetValuePtr(inParams->inRTSPRequest, qtssRTSPReqMethod, 0, (void**)&theMethod, &theLen) != QTSS_NoErr) || (theLen != sizeof(QTSS_RTSPMethod))) { Assert(0); return QTSS_RequestFailed; } if (*theMethod != qtssDescribeMethod) return QTSS_RequestFailed; // Check to see if this is a raw file request char* theFilePath = NULL; (void)QTSS_GetValueAsString(inParams->inRTSPRequest, qtssRTSPReqLocalPath, 0, &theFilePath); QTSSCharArrayDeleter theFilePathDeleter(theFilePath); theLen = ::strlen(theFilePath); // Copy the full path, and append a ".raw" OSCharArrayDeleter rawPath(NEW char[theLen + sRawSuffix.Len + 4]); ::memcpy(rawPath.GetObject(), theFilePath, theLen); ::strcpy(rawPath.GetObject() + theLen, sRawSuffix.Ptr); #if RAWFILE_FILE_ASYNC theErr = QTSS_OpenFileObject(rawPath.GetObject(), qtssOpenFileAsync, &theFile); #else theErr = QTSS_OpenFileObject(rawPath.GetObject(), qtssOpenFileAsync, &theFile); #endif // If the file doesn't exist, and if this is a path with a '.raw' at the end, // check to see if the path without the extra .raw exists if (theErr != QTSS_NoErr) { theFile = NULL; rawPath.GetObject()[theLen] = '\0'; if (theLen > sRawSuffix.Len) { StrPtrLen comparer((theFilePath + theLen) - sRawSuffix.Len, sRawSuffix.Len); if (comparer.Equal(sRawSuffix)) { #if RAWFILE_FILE_ASYNC theErr = QTSS_OpenFileObject(rawPath.GetObject(), qtssOpenFileAsync, &theFile); #else theErr = QTSS_OpenFileObject(rawPath.GetObject(), kOpenFileNoFlags, &theFile); #endif } } } // If the file doesn't exist, we should probably return a 404 not found. if (theErr != QTSS_NoErr) return QTSS_RequestFailed; // Before sending any response, set keep alive to off for this connection // Regardless of what the client sends, the server always closes the connection after sending the file static Bool16 sFalse = false; (void)QTSS_SetValue(inParams->inRTSPRequest, qtssRTSPReqRespKeepAlive, 0, &sFalse, sizeof(sFalse)); // We have a real file. Setup all the dictionary values we need (void)QTSS_SetValue(inParams->inRTSPSession, sFileAttr, 0, &theFile, sizeof(theFile)); // Create a buffer to store data. char* theFileBuffer = NEW char[sFileBufSize]; (void)QTSS_SetValue(inParams->inRTSPSession, sFileBufferAttr, 0, &theFileBuffer, sizeof(theFileBuffer)); // Store our initial state (void)QTSS_SetValue(inParams->inRTSPSession, sStateAttr, 0, &sInitialState, sizeof(sInitialState)); theStateP = &sInitialState; // so we can proceed normally (void)QTSS_SetValue(inParams->inRTSPSession, sReadOffsetAttr, 0, &sZero, sizeof(sZero)); (void)QTSS_SetValue(inParams->inRTSPSession, sWriteOffsetAttr, 0, &sZero, sizeof(sZero)); }
QTSS_Error QTSSModuleUtils::ReadEntireFile(char* inPath, StrPtrLen* outData, QTSS_TimeVal inModDate, QTSS_TimeVal* outModDate) { QTSS_Object theFileObject = NULL; QTSS_Error theErr = QTSS_NoErr; outData->Ptr = NULL; outData->Len = 0; do { // Use the QTSS file system API to read the file theErr = QTSS_OpenFileObject(inPath, 0, &theFileObject); if (theErr != QTSS_NoErr) break; UInt32 theParamLen = 0; QTSS_TimeVal* theModDate = NULL; theErr = QTSS_GetValuePtr(theFileObject, qtssFlObjModDate, 0, (void**)(void*)&theModDate, &theParamLen); Assert(theParamLen == sizeof(QTSS_TimeVal)); if(theParamLen != sizeof(QTSS_TimeVal)) break; if(outModDate != NULL) *outModDate = (QTSS_TimeVal)*theModDate; if(inModDate != -1) { // If file hasn't been modified since inModDate, don't have to read the file if(*theModDate <= inModDate) break; } theParamLen = 0; UInt64* theLength = NULL; theErr = QTSS_GetValuePtr(theFileObject, qtssFlObjLength, 0, (void**)(void*)&theLength, &theParamLen); if (theParamLen != sizeof(UInt64)) break; if (*theLength > kSInt32_Max) break; // Allocate memory for the file data outData->Ptr = NEW char[ (SInt32) (*theLength + 1) ]; outData->Len = (SInt32) *theLength; outData->Ptr[outData->Len] = 0; // Read the data UInt32 recvLen = 0; theErr = QTSS_Read(theFileObject, outData->Ptr, outData->Len, &recvLen); if (theErr != QTSS_NoErr) { outData->Delete(); break; } Assert(outData->Len == recvLen); }while(false); // Close the file if(theFileObject != NULL) { theErr = QTSS_CloseFileObject(theFileObject); } return theErr; }