284 lines
9.8 KiB
C
284 lines
9.8 KiB
C
|
/*
|
||
|
*
|
||
|
* @APPLE_LICENSE_HEADER_START@
|
||
|
*
|
||
|
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||
|
*
|
||
|
* This file contains Original Code and/or Modifications of Original Code
|
||
|
* as defined in and that are subject to the Apple Public Source License
|
||
|
* Version 2.0 (the 'License'). You may not use this file except in
|
||
|
* compliance with the License. Please obtain a copy of the License at
|
||
|
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||
|
* file.
|
||
|
*
|
||
|
* The Original Code and all software distributed under the License are
|
||
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||
|
* Please see the License for the specific language governing rights and
|
||
|
* limitations under the License.
|
||
|
*
|
||
|
* @APPLE_LICENSE_HEADER_END@
|
||
|
*
|
||
|
*/
|
||
|
// $Id: QTRTPFile.h,v 1.1 2006/01/05 13:20:36 murata Exp $
|
||
|
//
|
||
|
// QTRTPFile:
|
||
|
// An interface to QTFile for TimeShare.
|
||
|
|
||
|
#ifndef QTRTPFile_H
|
||
|
#define QTRTPFile_H
|
||
|
|
||
|
|
||
|
//
|
||
|
// Includes
|
||
|
#include "OSHeaders.h"
|
||
|
#include "MyAssert.h"
|
||
|
#include "RTPMetaInfoPacket.h"
|
||
|
#include "QTHintTrack.h"
|
||
|
|
||
|
#ifndef __Win32__
|
||
|
#include <sys/stat.h>
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// Constants
|
||
|
#define QTRTPFILE_MAX_PACKET_LENGTH 2048
|
||
|
|
||
|
|
||
|
//
|
||
|
// QTRTPFile class
|
||
|
class OSMutex;
|
||
|
|
||
|
class QTFile;
|
||
|
class QTFile_FileControlBlock;
|
||
|
class QTHintTrack;
|
||
|
class QTHintTrack_HintTrackControlBlock;
|
||
|
|
||
|
class QTRTPFile {
|
||
|
|
||
|
public:
|
||
|
//
|
||
|
// Class error codes
|
||
|
enum ErrorCode {
|
||
|
errNoError = 0,
|
||
|
errFileNotFound = 1,
|
||
|
errInvalidQuickTimeFile = 2,
|
||
|
errNoHintTracks = 3,
|
||
|
errTrackIDNotFound = 4,
|
||
|
errCallAgain = 5,
|
||
|
errInternalError = 100
|
||
|
};
|
||
|
|
||
|
|
||
|
//
|
||
|
// Class typedefs.
|
||
|
struct RTPFileCacheEntry {
|
||
|
//
|
||
|
// Init mutex (do not use this entry until you have acquired and
|
||
|
// released this.
|
||
|
OSMutex *InitMutex;
|
||
|
|
||
|
//
|
||
|
// File information
|
||
|
char* fFilename;
|
||
|
QTFile *File;
|
||
|
|
||
|
//
|
||
|
// Reference count for this cache entry
|
||
|
int ReferenceCount;
|
||
|
|
||
|
//
|
||
|
// List pointers
|
||
|
RTPFileCacheEntry *PrevEntry, *NextEntry;
|
||
|
};
|
||
|
|
||
|
struct RTPTrackListEntry {
|
||
|
|
||
|
//
|
||
|
// Track information
|
||
|
UInt32 TrackID;
|
||
|
QTHintTrack *HintTrack;
|
||
|
QTHintTrack_HintTrackControlBlock *HTCB;
|
||
|
Bool16 IsTrackActive, IsPacketAvailable;
|
||
|
UInt32 QualityLevel;
|
||
|
|
||
|
//
|
||
|
// Server information
|
||
|
void *Cookie1;
|
||
|
UInt32 Cookie2;
|
||
|
UInt32 SSRC;
|
||
|
UInt16 FileSequenceNumberRandomOffset, BaseSequenceNumberRandomOffset,
|
||
|
LastSequenceNumber;
|
||
|
SInt32 SequenceNumberAdditive;
|
||
|
UInt32 FileTimestampRandomOffset, BaseTimestampRandomOffset;
|
||
|
|
||
|
//
|
||
|
// Sample/Packet information
|
||
|
UInt32 CurSampleNumber;
|
||
|
UInt32 ConsecutivePFramesSent;
|
||
|
UInt32 TargetPercentage;
|
||
|
UInt32 SampleToSeekTo;
|
||
|
UInt32 LastSyncSampleNumber;
|
||
|
UInt32 NextSyncSampleNumber;
|
||
|
UInt16 NumPacketsInThisSample, CurPacketNumber;
|
||
|
|
||
|
Float64 CurPacketTime;
|
||
|
char CurPacket[QTRTPFILE_MAX_PACKET_LENGTH];
|
||
|
UInt32 CurPacketLength;
|
||
|
|
||
|
//
|
||
|
// List pointers
|
||
|
RTPTrackListEntry *NextTrack;
|
||
|
};
|
||
|
|
||
|
|
||
|
public:
|
||
|
//
|
||
|
// Global initialize function; CALL THIS FIRST!
|
||
|
static void Initialize(void);
|
||
|
|
||
|
//
|
||
|
// Returns a static array of the RTP-Meta-Info fields supported by QTFileLib.
|
||
|
// It also returns field IDs for the fields it recommends being compressed.
|
||
|
static const RTPMetaInfoPacket::FieldID* GetSupportedRTPMetaInfoFields() { return kMetaInfoFields; }
|
||
|
|
||
|
//
|
||
|
// Constructors and destructor.
|
||
|
QTRTPFile(Bool16 Debug = false, Bool16 DeepDebug = false);
|
||
|
|
||
|
virtual ~QTRTPFile(void);
|
||
|
|
||
|
|
||
|
//
|
||
|
// Initialization functions.
|
||
|
virtual ErrorCode Initialize(const char * FilePath);
|
||
|
|
||
|
void AllocateSharedBuffers(UInt32 inUnitSizeInK, UInt32 inBufferInc, UInt32 inBufferSizeUnits, UInt32 inMaxBitRateBuffSizeInBlocks)
|
||
|
{ fFile->AllocateBuffers(inUnitSizeInK, inBufferInc, inBufferSizeUnits, inMaxBitRateBuffSizeInBlocks, this->GetBytesPerSecond() * 8 );
|
||
|
}
|
||
|
|
||
|
void AllocatePrivateBuffers(UInt32 inUnitSizeInK, UInt32 inNumBuffSizeUnits, UInt32 inMaxBitRateBuffSizeInBlocks);
|
||
|
|
||
|
//
|
||
|
// Accessors
|
||
|
Float64 GetMovieDuration(void);
|
||
|
UInt64 GetAddedTracksRTPBytes(void);
|
||
|
char * GetSDPFile(int * SDPFileLength);
|
||
|
UInt32 GetBytesPerSecond(void);
|
||
|
|
||
|
char* GetMoviePath();
|
||
|
QTFile* GetQTFile() { return fFile; }
|
||
|
|
||
|
//
|
||
|
// Track functions
|
||
|
|
||
|
//
|
||
|
// AddTrack
|
||
|
//
|
||
|
// If you would like this track to be an RTP-Meta-Info stream, pass in
|
||
|
// the field names you would like to see
|
||
|
ErrorCode AddTrack(UInt32 TrackID, Bool16 UseRandomOffset = true);
|
||
|
|
||
|
|
||
|
Float64 GetTrackDuration(UInt32 TrackID);
|
||
|
UInt32 GetTrackTimeScale(UInt32 TrackID);
|
||
|
|
||
|
void SetTrackSSRC(UInt32 TrackID, UInt32 SSRC);
|
||
|
void SetTrackCookies(UInt32 TrackID, void * Cookie1, UInt32 Cookie2);
|
||
|
void SetAllowInvalidHintRefs(Bool16 inAllowInvalidHintRefs) { fAllowInvalidHintRefs = inAllowInvalidHintRefs; }
|
||
|
|
||
|
//
|
||
|
// If you want QTRTPFile to output an RTP-Meta-Info packet instead
|
||
|
// of a normal RTP packet for this track, call this function and
|
||
|
// pass in a proper Field ID array (see RTPMetaInfoPacket.h) to
|
||
|
// tell QTRTPFile which fields to include and which IDs to use with the fields.
|
||
|
// You have to let this function know whether this is a video track or not.
|
||
|
void SetTrackRTPMetaInfo(UInt32 TrackID, RTPMetaInfoPacket::FieldID* inFieldArray, Bool16 isVideo );
|
||
|
|
||
|
//
|
||
|
// What sort of packets do you want?
|
||
|
enum
|
||
|
{
|
||
|
kAllPackets = 0,
|
||
|
kNoBFrames = 1,
|
||
|
k75PercentPFrames = 2,
|
||
|
k50PercentPFrames = 3,
|
||
|
k25PercentPFrames = 4,
|
||
|
kKeyFramesOnly = 5,
|
||
|
kKeyFramesPlusOneP = 6 //Special quality level with Key frames followed by 1 P frame
|
||
|
};
|
||
|
|
||
|
void SetTrackQualityLevel(RTPTrackListEntry* inEntry, UInt32 inNewLevel);
|
||
|
//
|
||
|
// Packet functions
|
||
|
ErrorCode Seek(Float64 Time, Float64 MaxBackupTime = 3.0);
|
||
|
ErrorCode SeekToPacketNumber(UInt32 inTrackID, UInt64 inPacketNumber);
|
||
|
|
||
|
UInt32 GetSeekTimestamp(UInt32 TrackID);
|
||
|
Float64 GetRequestedSeekTime() { return fRequestedSeekTime; }
|
||
|
Float64 GetActualSeekTime() { return fSeekTime; }
|
||
|
Float64 GetFirstPacketTransmitTime();
|
||
|
RTPTrackListEntry* GetLastPacketTrack() { return fLastPacketTrack; }
|
||
|
UInt32 GetNumSkippedSamples() { return fNumSkippedSamples; }
|
||
|
|
||
|
UInt16 GetNextTrackSequenceNumber(UInt32 TrackID);
|
||
|
Float64 GetNextPacket(char ** Packet, int * PacketLength);
|
||
|
|
||
|
SInt32 GetMovieHintType();
|
||
|
Bool16 DropRepeatPackets() { return fDropRepeatPackets; }
|
||
|
Bool16 SetDropRepeatPackets(Bool16 allowRepeatPackets) { (!fHasRTPMetaInfoFieldArray) ? fDropRepeatPackets = allowRepeatPackets : fDropRepeatPackets = false; return fDropRepeatPackets;}
|
||
|
|
||
|
ErrorCode Error() { return fErr; };
|
||
|
|
||
|
Bool16 FindTrackEntry(UInt32 TrackID, RTPTrackListEntry **TrackEntry);
|
||
|
protected:
|
||
|
//
|
||
|
// Protected cache functions and variables.
|
||
|
static OSMutex *gFileCacheMutex, *gFileCacheAddMutex;
|
||
|
static RTPFileCacheEntry *gFirstFileCacheEntry;
|
||
|
|
||
|
static ErrorCode new_QTFile(const char * FilePath, QTFile ** File, Bool16 Debug = false, Bool16 DeepDebug = false);
|
||
|
static void delete_QTFile(QTFile * File);
|
||
|
|
||
|
static void AddFileToCache(const char *inFilename, QTRTPFile::RTPFileCacheEntry ** NewListEntry);
|
||
|
static Bool16 FindAndRefcountFileCacheEntry(const char *inFilename, QTRTPFile::RTPFileCacheEntry **CacheEntry);
|
||
|
|
||
|
//
|
||
|
// Protected member functions.
|
||
|
Bool16 PrefetchNextPacket(RTPTrackListEntry * TrackEntry, Bool16 doSeek = false);
|
||
|
ErrorCode ScanToCorrectSample();
|
||
|
ErrorCode ScanToCorrectPacketNumber(UInt32 inTrackID, UInt64 inPacketNumber);
|
||
|
|
||
|
//
|
||
|
// Protected member variables.
|
||
|
Bool16 fDebug, fDeepDebug;
|
||
|
|
||
|
QTFile *fFile;
|
||
|
QTFile_FileControlBlock *fFCB;
|
||
|
|
||
|
UInt32 fNumHintTracks;
|
||
|
RTPTrackListEntry *fFirstTrack, *fLastTrack, *fCurSeekTrack;
|
||
|
|
||
|
char *fSDPFile;
|
||
|
UInt32 fSDPFileLength;
|
||
|
UInt32 fNumSkippedSamples;
|
||
|
|
||
|
Float64 fRequestedSeekTime, fSeekTime;
|
||
|
|
||
|
RTPTrackListEntry *fLastPacketTrack;
|
||
|
|
||
|
UInt32 fBytesPerSecond;
|
||
|
|
||
|
Bool16 fHasRTPMetaInfoFieldArray;
|
||
|
Bool16 fWasLastSeekASeekToPacketNumber;
|
||
|
Bool16 fDropRepeatPackets;
|
||
|
Bool16 fAllowInvalidHintRefs;
|
||
|
ErrorCode fErr;
|
||
|
|
||
|
static const RTPMetaInfoPacket::FieldID kMetaInfoFields[];
|
||
|
};
|
||
|
|
||
|
#endif // QTRTPFile
|