int QTFileBroadcaster::SetUpAMovie(char *theMovieFileName)
{
    int err = -1;
    QTRTPFile *newRTPFilePtr = NULL;
    do {
        fMovieTracks = 0;
        fMappedMovieTracks = 0;
        
        if (fMovieSDPParser != NULL) delete fMovieSDPParser;
        if (fRTPFilePtr != NULL) delete fRTPFilePtr;
        
        fMovieSDPParser = NULL;
        fRTPFilePtr = NULL;
        
        if (!theMovieFileName)          { err = eMovieFileInvalidName; break; }     
        int nameLen = strlen(theMovieFileName);                     
        if (nameLen > 255)              { err = eMovieFileInvalidName; break; }
        if (0 == nameLen)               { err = eMovieFileInvalidName; break; }
        
        fMovieSDPParser = new SDPFileParser;
        if (NULL == fMovieSDPParser)    { err = eMem; break;}
        
        newRTPFilePtr = new QTRTPFile();
        if (NULL == newRTPFilePtr)      { err = eMem; break;}
        
        QTRTPFile::ErrorCode result = newRTPFilePtr->Initialize(theMovieFileName);
        err = EvalErrorCode(result);
        if (err) break;
        
        fMovieTracks = GetSDPTracks(newRTPFilePtr);
        if (fMovieTracks < 1)           { err = eMovieFileNoHintedTracks; break; }
        
        fMappedMovieTracks = MapMovieToStream();
        if (fMappedMovieTracks < 1)     { err = eMovieFileNoSDPMatches; break; }

        err = AddTrackAndStream(newRTPFilePtr);     
        if (err != 0)                   { err = eMovieFileInvalid; break; }
        
    } while (false);
    
    if (err) 
    {   if (newRTPFilePtr) 
            delete newRTPFilePtr;
        newRTPFilePtr = NULL;
    }
    
    fRTPFilePtr = newRTPFilePtr;
    
    return err;
}
Пример #2
0
int main(int argc, char *argv[]) {
    // Temporary vars
    int         ch;
    struct timeval  tp;

    // General vars
    bool            Debug = false, DeepDebug = false;

    const char      *IPAddress;
    const char      *BasePort;

    const char      *MovieFilename;

    int             s;
    QTRTPFile       *RTPFile;

    int             CurPort;
    Float64         StartTime;
    extern int optind;


    //
    // Read our command line options
    while( (ch = getopt(argc, argv, "dD")) != -1 ) {
        switch( ch ) {
            case 'd':
                Debug = true;
            break;

            case 'D':
                Debug = true;
                DeepDebug = true;
            break;
        }
    }

    argc -= optind;
    argv += optind;

    //
    // Validate our arguments.
    if( argc < 4 ) {
        qtss_printf("usage: QTBroadcaster <ip address> <baseport> <filename> <track#n> <track#n+1> ..\n");
        exit(1);
    }
    
    IPAddress = *argv++; argc--;
    BasePort = *argv++; argc--;
    MovieFilename = *argv++; argc--;


    //
    // Open the movie.
    RTPFile = new QTRTPFile(Debug, DeepDebug);
    switch( RTPFile->Initialize(MovieFilename) ) {
        case QTRTPFile::errNoError:
        break;

        case QTRTPFile::errFileNotFound:
            qtss_printf("Error!  File not found \"%s\"!\n", MovieFilename);
            exit(1);
        case QTRTPFile::errNoHintTracks:
            qtss_printf("Error!  No hint tracks \"%s\"!\n", MovieFilename);
            exit(1);
        case QTRTPFile::errInvalidQuickTimeFile:
            qtss_printf("Error!  Invalid movie file \"%s\"!\n", MovieFilename);
            exit(1);
        case QTRTPFile::errInternalError:
            qtss_printf("Error!  Internal error opening movie file \"%s\"!\n", MovieFilename);
            exit(1);
            
        case QTRTPFile::errTrackIDNotFound:
        case QTRTPFile::errCallAgain:
            //noops
            break;
    }
    
    
    //
    // Add the tracks that we're interested in.
    CurPort = atoi(BasePort);
    while(argc--) {
        switch( RTPFile->AddTrack(atoi(*argv)) ) {
            case QTRTPFile::errNoError:
            case QTRTPFile::errTrackIDNotFound:
            case QTRTPFile::errCallAgain:
            break;

            case QTRTPFile::errFileNotFound:
            case QTRTPFile::errNoHintTracks:
            case QTRTPFile::errInvalidQuickTimeFile:
            case QTRTPFile::errInternalError:
                qtss_printf("Error!  Invalid movie file \"%s\"!\n", MovieFilename);
                exit(1);
        }

        RTPFile->SetTrackCookies(atoi(*argv), NULL, (UInt32 )CurPort);
        CurPort += 2;

        (void)RTPFile->GetSeekTimestamp(atoi(*argv));
        argv++;
    }
    
    
    //
    // Create our socket to broadcast to.
    s = socket(AF_INET, SOCK_DGRAM, 0);
    if( s == -1 ) {
        qtss_printf("Error!  Couldn't create socket!\n");
        exit(1);
    }
    
    
    //
    // Seek to the beginning of the movie.
    if( RTPFile->Seek(0.0) != QTRTPFile::errNoError ) {
        qtss_printf("Error!  Couldn't seek to time 0.0!\n");
        exit(1);
    }
    

    //
    // Send packets..
    gettimeofday(&tp, NULL);
    StartTime = tp.tv_sec + ((Float64)tp.tv_usec / 1000000);
    while(1) {
        // General vars
        char    *Packet;
        int     PacketLength;
        //int       Cookie;

        Float64 SleepTime;

        struct sockaddr_in  sin;
        

        //
        // Get the next packet.
        Float64 TransmitTime = RTPFile->GetNextPacket(&Packet, &PacketLength);
        if( Packet == NULL )
            break;
        
        //
        // Wait until it is time to send the packet.
        gettimeofday(&tp, NULL);
        SleepTime = tp.tv_sec + ((Float64)tp.tv_usec / 1000000);
        SleepTime = (StartTime + TransmitTime) - SleepTime;
        if( SleepTime > 0.0 ) {
            qtss_printf("Sleeping for %.2f seconds (TransmitTime=%.2f).\n", SleepTime, TransmitTime);
            usleep((unsigned int)(SleepTime * 1000000));
        }

        //
        // Send the packet.
        memset(&sin, 0, sizeof(struct sockaddr_in));
        sin.sin_family = AF_INET;
        UInt32 value = RTPFile->GetLastPacketTrack()->Cookie2;

        in_port_t cookievalue = value;
        sin.sin_port = bswap_16( cookievalue  );
        sin.sin_addr.s_addr = inet_addr(IPAddress);
        sendto(s, Packet, PacketLength, 0, (struct sockaddr *)&sin, sizeof(struct sockaddr));
    }

    
    //
    // Close the socket.
    close(s);

    //
    // Close our RTP file.
    delete RTPFile;

    return 0;
}