void QTFile_FileControlBlock::Set( char * DataPath)
{
#if DSS_USE_API_CALLBACKS
    (void)QTSS_OpenFileObject(DataPath, qtssOpenFileReadAhead, &fDataFD);
#else
    fDataFD.Set(DataPath);
#endif

}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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));
    }
예제 #6
0
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;
}