SubsessionIOState Class Reference

Collaboration diagram for SubsessionIOState:

Collaboration graph
[legend]

Public Types

typedef unsigned(QuickTimeFileSink::*) atomCreationFunc ()

Public Member Functions

 SubsessionIOState (QuickTimeFileSink &sink, MediaSubsession &subsession)
virtual ~SubsessionIOState ()
Boolean setQTstate ()
void setFinalQTstate ()
void afterGettingFrame (unsigned packetDataSize, struct timeval presentationTime)
void onSourceClosure ()
Boolean syncOK (struct timeval presentationTime)
Boolean isHintTrack () const
Boolean hasHintTrack () const
UsageEnvironmentenvir () const

Static Public Member Functions

static void setHintTrack (SubsessionIOState *hintedTrack, SubsessionIOState *hintTrack)

Data Fields

unsigned fTrackID
SubsessionIOStatefHintTrackForUs
SubsessionIOStatefTrackHintedByUs
SubsessionBufferfBuffer
SubsessionBufferfPrevBuffer
QuickTimeFileSinkfOurSink
MediaSubsessionfOurSubsession
unsigned short fLastPacketRTPSeqNum
Boolean fOurSourceIsActive
Boolean fHaveBeenSynced
timeval fSyncTime
Boolean fQTEnableTrack
unsigned fQTcomponentSubtype
char const * fQTcomponentName
atomCreationFunc fQTMediaInformationAtomCreator
atomCreationFunc fQTMediaDataAtomCreator
char const * fQTAudioDataType
unsigned short fQTSoundSampleVersion
unsigned fQTTimeScale
unsigned fQTTimeUnitsPerSample
unsigned fQTBytesPerFrame
unsigned fQTSamplesPerFrame
unsigned fQTTotNumSamples
unsigned fQTDurationM
unsigned fQTDurationT
int64_t fTKHD_durationPosn
unsigned fQTInitialOffsetDuration
ChunkDescriptorfHeadChunk
ChunkDescriptorfTailChunk
unsigned fNumChunks
SyncFramefHeadSyncFrame
SyncFramefTailSyncFrame
SubsessionIOState::hinf fHINF
unsigned frameSize
timeval presentationTime
int64_t destFileOffset
unsigned startSampleNumber
unsigned short seqNum
unsigned rtpHeader
unsigned char numSpecialHeaders
unsigned specialHeaderBytesLength
unsigned char specialHeaderBytes [SPECIAL_HEADER_BUFFER_SIZE]
unsigned packetSizes [256]

Static Public Attributes

static unsigned fCurrentTrackNumber = 0

Private Member Functions

void useFrame (SubsessionBuffer &buffer)
void useFrameForHinting (unsigned frameSize, struct timeval presentationTime, unsigned startSampleNumber)
unsigned useFrame1 (unsigned sourceDataSize, struct timeval presentationTime, unsigned frameDuration, int64_t destFileOffset)

Private Attributes

struct {
   unsigned   frameSize
   timeval   presentationTime
   int64_t   destFileOffset
   unsigned   startSampleNumber
   unsigned short   seqNum
   unsigned   rtpHeader
   unsigned char   numSpecialHeaders
   unsigned   specialHeaderBytesLength
   unsigned char   specialHeaderBytes [SPECIAL_HEADER_BUFFER_SIZE]
   unsigned   packetSizes [256]
fPrevFrameState

Data Structures

struct  hinf

Detailed Description

Definition at line 111 of file QuickTimeFileSink.cpp.


Member Typedef Documentation

typedef unsigned(QuickTimeFileSink::*) SubsessionIOState::atomCreationFunc()

Definition at line 151 of file QuickTimeFileSink.cpp.


Constructor & Destructor Documentation

SubsessionIOState::SubsessionIOState ( QuickTimeFileSink sink,
MediaSubsession subsession 
)

Definition at line 524 of file QuickTimeFileSink.cpp.

References fBuffer, QuickTimeFileSink::fBufferSize, fCurrentTrackNumber, fOurSink, fOurSourceIsActive, QuickTimeFileSink::fPacketLossCompensate, fPrevBuffer, fPrevFrameState, fTrackID, NULL, MediaSubsession::readSource(), and subsession.

00526   : fHintTrackForUs(NULL), fTrackHintedByUs(NULL),
00527     fOurSink(sink), fOurSubsession(subsession),
00528     fLastPacketRTPSeqNum(0), fHaveBeenSynced(False), fQTTotNumSamples(0), 
00529     fHeadChunk(NULL), fTailChunk(NULL), fNumChunks(0),
00530     fHeadSyncFrame(NULL), fTailSyncFrame(NULL) {
00531   fTrackID = ++fCurrentTrackNumber;
00532 
00533   fBuffer = new SubsessionBuffer(fOurSink.fBufferSize);
00534   fPrevBuffer = sink.fPacketLossCompensate
00535     ? new SubsessionBuffer(fOurSink.fBufferSize) : NULL;
00536 
00537   FramedSource* subsessionSource = subsession.readSource();
00538   fOurSourceIsActive = subsessionSource != NULL;
00539 
00540   fPrevFrameState.presentationTime.tv_sec = 0;
00541   fPrevFrameState.presentationTime.tv_usec = 0;
00542   fPrevFrameState.seqNum = 0;
00543 }

SubsessionIOState::~SubsessionIOState (  )  [virtual]

Definition at line 545 of file QuickTimeFileSink.cpp.

References fBuffer, fHeadChunk, fHeadSyncFrame, and fPrevBuffer.

00545                                       {
00546   delete fBuffer; delete fPrevBuffer;
00547   delete fHeadChunk; delete fHeadSyncFrame;
00548 }


Member Function Documentation

Boolean SubsessionIOState::setQTstate (  ) 

Definition at line 550 of file QuickTimeFileSink.cpp.

References QuickTimeFileSink::addAtom_dummy(), QuickTimeFileSink::addAtom_genericMedia(), QuickTimeFileSink::addAtom_soundMediaGeneral(), MediaSubsession::codecName(), envir(), False, QuickTimeFileSink::fMovieFPS, MediaSubsession::fmtp_config(), fourChar, fOurSink, fOurSubsession, fQTAudioDataType, fQTBytesPerFrame, fQTcomponentName, fQTcomponentSubtype, fQTEnableTrack, fQTMediaDataAtomCreator, fQTMediaInformationAtomCreator, fQTSamplesPerFrame, fQTSoundSampleVersion, fQTTimeScale, fQTTimeUnitsPerSample, isHintTrack(), MediaSubsession::mediumName(), MediaSubsession::rtpTimestampFrequency(), samplingFrequencyFromAudioSpecificConfig(), and True.

Referenced by QuickTimeFileSink::QuickTimeFileSink().

00550                                       {
00551   char const* noCodecWarning1 = "Warning: We don't implement a QuickTime ";
00552   char const* noCodecWarning2 = " Media Data Type for the \"";
00553   char const* noCodecWarning3 = "\" track, so we'll insert a dummy \"????\" Media Data Atom instead.  A separate, codec-specific editing pass will be needed before this track can be played.\n";
00554 
00555   do {
00556     fQTEnableTrack = True; // enable this track in the movie by default
00557     fQTTimeScale = fOurSubsession.rtpTimestampFrequency(); // by default
00558     fQTTimeUnitsPerSample = 1; // by default
00559     fQTBytesPerFrame = 0;
00560         // by default - indicates that the whole packet data is a frame
00561     fQTSamplesPerFrame = 1; // by default
00562 
00563     // Make sure our subsession's medium is one that we know how to
00564     // represent in a QuickTime file:
00565     if (isHintTrack()) {
00566       // Hint tracks are treated specially
00567       fQTEnableTrack = False; // hint tracks are marked as inactive
00568       fQTcomponentSubtype = fourChar('h','i','n','t');
00569       fQTcomponentName = "hint media handler";
00570       fQTMediaInformationAtomCreator = &QuickTimeFileSink::addAtom_gmhd;
00571       fQTMediaDataAtomCreator = &QuickTimeFileSink::addAtom_rtp;
00572     } else if (strcmp(fOurSubsession.mediumName(), "audio") == 0) {
00573       fQTcomponentSubtype = fourChar('s','o','u','n');
00574       fQTcomponentName = "Apple Sound Media Handler";
00575       fQTMediaInformationAtomCreator = &QuickTimeFileSink::addAtom_smhd;
00576       fQTMediaDataAtomCreator
00577         = &QuickTimeFileSink::addAtom_soundMediaGeneral; // by default
00578       fQTSoundSampleVersion = 0; // by default
00579 
00580       // Make sure that our subsession's codec is one that we can handle:
00581       if (strcmp(fOurSubsession.codecName(), "X-QT") == 0 ||
00582           strcmp(fOurSubsession.codecName(), "X-QUICKTIME") == 0) {
00583         fQTMediaDataAtomCreator = &QuickTimeFileSink::addAtom_genericMedia;
00584       } else if (strcmp(fOurSubsession.codecName(), "PCMU") == 0) {
00585         fQTAudioDataType = "ulaw";
00586         fQTBytesPerFrame = 1;
00587       } else if (strcmp(fOurSubsession.codecName(), "GSM") == 0) {
00588         fQTAudioDataType = "agsm";
00589         fQTBytesPerFrame = 33;
00590         fQTSamplesPerFrame = 160;
00591       } else if (strcmp(fOurSubsession.codecName(), "PCMA") == 0) {
00592         fQTAudioDataType = "alaw";
00593         fQTBytesPerFrame = 1;
00594       } else if (strcmp(fOurSubsession.codecName(), "QCELP") == 0) {
00595         fQTMediaDataAtomCreator = &QuickTimeFileSink::addAtom_Qclp;
00596         fQTSamplesPerFrame = 160;
00597       } else if (strcmp(fOurSubsession.codecName(), "MPEG4-GENERIC") == 0 ||
00598                  strcmp(fOurSubsession.codecName(), "MP4A-LATM") == 0) {
00599         fQTMediaDataAtomCreator = &QuickTimeFileSink::addAtom_mp4a;
00600         fQTTimeUnitsPerSample = 1024; // QT considers each frame to be a 'sample'
00601         // The time scale (frequency) comes from the 'config' information.
00602         // It might be different from the RTP timestamp frequency (e.g., aacPlus).
00603         unsigned frequencyFromConfig
00604           = samplingFrequencyFromAudioSpecificConfig(fOurSubsession.fmtp_config());
00605         if (frequencyFromConfig != 0) fQTTimeScale = frequencyFromConfig;
00606       } else {
00607         envir() << noCodecWarning1 << "Audio" << noCodecWarning2
00608                 << fOurSubsession.codecName() << noCodecWarning3;
00609         fQTMediaDataAtomCreator = &QuickTimeFileSink::addAtom_dummy;
00610         fQTEnableTrack = False; // disable this track in the movie
00611       }
00612     } else if (strcmp(fOurSubsession.mediumName(), "video") == 0) {
00613       fQTcomponentSubtype = fourChar('v','i','d','e');
00614       fQTcomponentName = "Apple Video Media Handler";
00615       fQTMediaInformationAtomCreator = &QuickTimeFileSink::addAtom_vmhd;
00616 
00617       // Make sure that our subsession's codec is one that we can handle:
00618       if (strcmp(fOurSubsession.codecName(), "X-QT") == 0 ||
00619           strcmp(fOurSubsession.codecName(), "X-QUICKTIME") == 0) {
00620         fQTMediaDataAtomCreator = &QuickTimeFileSink::addAtom_genericMedia;
00621       } else if (strcmp(fOurSubsession.codecName(), "H263-1998") == 0 ||
00622                  strcmp(fOurSubsession.codecName(), "H263-2000") == 0) {
00623         fQTMediaDataAtomCreator = &QuickTimeFileSink::addAtom_h263;
00624         fQTTimeScale = 600;
00625         fQTTimeUnitsPerSample = fQTTimeScale/fOurSink.fMovieFPS;
00626       } else if (strcmp(fOurSubsession.codecName(), "H264") == 0) {
00627         fQTMediaDataAtomCreator = &QuickTimeFileSink::addAtom_avc1;
00628         fQTTimeScale = 600;
00629         fQTTimeUnitsPerSample = fQTTimeScale/fOurSink.fMovieFPS;
00630       } else if (strcmp(fOurSubsession.codecName(), "MP4V-ES") == 0) {
00631         fQTMediaDataAtomCreator = &QuickTimeFileSink::addAtom_mp4v;
00632         fQTTimeScale = 600;
00633         fQTTimeUnitsPerSample = fQTTimeScale/fOurSink.fMovieFPS;
00634       } else {
00635         envir() << noCodecWarning1 << "Video" << noCodecWarning2
00636                 << fOurSubsession.codecName() << noCodecWarning3;
00637         fQTMediaDataAtomCreator = &QuickTimeFileSink::addAtom_dummy;
00638         fQTEnableTrack = False; // disable this track in the movie
00639       }
00640     } else {
00641       envir() << "Warning: We don't implement a QuickTime Media Handler for media type \""
00642               << fOurSubsession.mediumName() << "\"";
00643       break;
00644     }
00645 
00646 #ifdef QT_SUPPORT_PARTIALLY_ONLY
00647     envir() << "Warning: We don't have sufficient codec-specific information (e.g., sample sizes) to fully generate the \""
00648             << fOurSubsession.mediumName() << "/" << fOurSubsession.codecName()
00649             << "\" track, so we'll disable this track in the movie.  A separate, codec-specific editing pass will be needed before this track can be played\n";
00650     fQTEnableTrack = False; // disable this track in the movie
00651 #endif
00652 
00653     return True;
00654   } while (0);
00655 
00656   envir() << ", so a track for the \"" << fOurSubsession.mediumName()
00657           << "/" << fOurSubsession.codecName()
00658           << "\" subsession will not be included in the output QuickTime file\n";
00659   return False;
00660 }

void SubsessionIOState::setFinalQTstate (  ) 

Definition at line 662 of file QuickTimeFileSink.cpp.

References chunk, ChunkDescriptor::fFrameDuration, fHeadChunk, QuickTimeFileSink::fMaxTrackDurationM, ChunkDescriptor::fNextChunk, ChunkDescriptor::fNumFrames, fOurSink, fQTDurationM, fQTDurationT, fQTTimeScale, QuickTimeFileSink::movieTimeScale(), and NULL.

Referenced by QuickTimeFileSink::completeOutputFile().

00662                                         {
00663   // Compute derived parameters, by running through the list of chunks:
00664   fQTDurationT = 0;
00665 
00666   ChunkDescriptor* chunk = fHeadChunk;
00667   while (chunk != NULL) {
00668     unsigned const numFrames = chunk->fNumFrames;
00669     unsigned const dur = numFrames*chunk->fFrameDuration;
00670     fQTDurationT += dur;
00671 
00672     chunk = chunk->fNextChunk;
00673   }
00674 
00675   // Convert this duration from track to movie time scale:
00676   double scaleFactor = fOurSink.movieTimeScale()/(double)fQTTimeScale;
00677   fQTDurationM = (unsigned)(fQTDurationT*scaleFactor);
00678 
00679   if (fQTDurationM > fOurSink.fMaxTrackDurationM) {
00680     fOurSink.fMaxTrackDurationM = fQTDurationM;
00681   }
00682 }

void SubsessionIOState::afterGettingFrame ( unsigned  packetDataSize,
struct timeval  presentationTime 
)

Definition at line 684 of file QuickTimeFileSink.cpp.

References QuickTimeFileSink::addAtom_genericMedia(), SubsessionBuffer::addBytes(), SubsessionBuffer::bytesInUse(), QuickTimeFileSink::continuePlaying(), RTPSource::curPacketRTPSeqNum(), fBuffer, fLastPacketRTPSeqNum, QuickTimeFileSink::fMovieFPS, QuickTimeFileSink::fMovieHeight, QuickTimeFileSink::fMovieWidth, fourChar, fOurSink, fOurSubsession, QuickTimeFileSink::fPacketLossCompensate, fPrevBuffer, fQTBytesPerFrame, fQTMediaDataAtomCreator, fQTSamplesPerFrame, fQTTimeScale, fQTTimeUnitsPerSample, QuickTimeGenericRTPSource::QTState::height, QuickTimeGenericRTPSource::qtState, SubsessionBuffer::reset(), MediaSubsession::rtpSource(), QuickTimeGenericRTPSource::QTState::sdAtom, QuickTimeGenericRTPSource::QTState::sdAtomSize, SubsessionBuffer::setPresentationTime(), QuickTimeGenericRTPSource::QTState::timescale, useFrame(), and QuickTimeGenericRTPSource::QTState::width.

Referenced by QuickTimeFileSink::afterGettingFrame().

00685                                                                            {
00686   // Begin by checking whether there was a gap in the RTP stream.
00687   // If so, try to compensate for this (if desired):
00688   unsigned short rtpSeqNum
00689     = fOurSubsession.rtpSource()->curPacketRTPSeqNum();
00690   if (fOurSink.fPacketLossCompensate && fPrevBuffer->bytesInUse() > 0) {
00691     short seqNumGap = rtpSeqNum - fLastPacketRTPSeqNum;
00692     for (short i = 1; i < seqNumGap; ++i) {
00693       // Insert a copy of the previous frame, to compensate for the loss:
00694       useFrame(*fPrevBuffer);
00695     }
00696   }
00697   fLastPacketRTPSeqNum = rtpSeqNum;
00698 
00699   // Now, continue working with the frame that we just got
00700   if (fBuffer->bytesInUse() == 0) {
00701     fBuffer->setPresentationTime(presentationTime);
00702   }
00703   fBuffer->addBytes(packetDataSize);
00704 
00705   // If our RTP source is a "QuickTimeGenericRTPSource", then
00706   // use its 'qtState' to set some parameters that we need:
00707   if (fQTMediaDataAtomCreator == &QuickTimeFileSink::addAtom_genericMedia){
00708     QuickTimeGenericRTPSource* rtpSource
00709       = (QuickTimeGenericRTPSource*)fOurSubsession.rtpSource();
00710     QuickTimeGenericRTPSource::QTState& qtState = rtpSource->qtState;
00711     fQTTimeScale = qtState.timescale;
00712     if (qtState.width != 0) {
00713       fOurSink.fMovieWidth = qtState.width;
00714     }
00715     if (qtState.height != 0) {
00716       fOurSink.fMovieHeight = qtState.height;
00717     }
00718 
00719     // Also, if the media type in the "sdAtom" is one that we recognize
00720     // to have a special parameters, then fix this here:
00721     if (qtState.sdAtomSize >= 8) {
00722       char const* atom = qtState.sdAtom;
00723       unsigned mediaType = fourChar(atom[4],atom[5],atom[6],atom[7]);
00724       switch (mediaType) {
00725       case fourChar('a','g','s','m'): {
00726         fQTBytesPerFrame = 33;
00727         fQTSamplesPerFrame = 160;
00728         break;
00729       }
00730       case fourChar('Q','c','l','p'): {
00731         fQTBytesPerFrame = 35;
00732         fQTSamplesPerFrame = 160;
00733         break;
00734       }
00735       case fourChar('H','c','l','p'): {
00736         fQTBytesPerFrame = 17;
00737         fQTSamplesPerFrame = 160;
00738         break;
00739       }
00740       case fourChar('h','2','6','3'): {
00741         fQTTimeUnitsPerSample = fQTTimeScale/fOurSink.fMovieFPS;
00742         break;
00743       }
00744       }
00745     }
00746   } else if (fQTMediaDataAtomCreator == &QuickTimeFileSink::addAtom_Qclp) {
00747     // For QCELP data, make a note of the frame size (even though it's the
00748     // same as the packet data size), because it varies depending on the
00749     // 'rate' of the stream, and this size gets used later when setting up
00750     // the 'Qclp' QuickTime atom:
00751     fQTBytesPerFrame = packetDataSize;
00752   }
00753 
00754   useFrame(*fBuffer);
00755   if (fOurSink.fPacketLossCompensate) {
00756     // Save this frame, in case we need it for recovery:
00757     SubsessionBuffer* tmp = fPrevBuffer; // assert: != NULL
00758     fPrevBuffer = fBuffer;
00759     fBuffer = tmp;
00760   }
00761   fBuffer->reset(); // for the next input
00762 
00763   // Now, try getting more frames:
00764   fOurSink.continuePlaying();
00765 }

void SubsessionIOState::onSourceClosure (  ) 

Definition at line 1070 of file QuickTimeFileSink.cpp.

References False, fOurSink, fOurSourceIsActive, and QuickTimeFileSink::onSourceClosure1().

Referenced by QuickTimeFileSink::onRTCPBye(), and QuickTimeFileSink::onSourceClosure().

01070                                         {
01071   fOurSourceIsActive = False;
01072   fOurSink.onSourceClosure1();
01073 }

Boolean SubsessionIOState::syncOK ( struct timeval  presentationTime  ) 

Definition at line 1075 of file QuickTimeFileSink.cpp.

References SubsessionBuffer::dataStart(), False, fBuffer, fHaveBeenSynced, QuickTimeFileSink::fNumSubsessions, QuickTimeFileSink::fNumSyncedSubsessions, fOurSink, fOurSubsession, fQTMediaDataAtomCreator, QuickTimeFileSink::fSyncStreams, fSyncTime, H264_IDR_FRAME, RTPSource::hasBeenSynchronizedUsingRTCP(), MediaSubsession::rtpSource(), timevalGE(), and True.

Referenced by QuickTimeFileSink::afterGettingFrame().

01075                                                                  {
01076   QuickTimeFileSink& s = fOurSink; // abbreviation
01077   if (!s.fSyncStreams) return True; // we don't care
01078 
01079   if (s.fNumSyncedSubsessions < s.fNumSubsessions) {
01080     // Not all subsessions have yet been synced.  Check whether ours was
01081     // one of the unsynced ones, and, if so, whether it is now synced:
01082     if (!fHaveBeenSynced) {
01083       // We weren't synchronized before
01084       if (fOurSubsession.rtpSource()->hasBeenSynchronizedUsingRTCP()) {
01085         // H264 ?
01086         if (fQTMediaDataAtomCreator == &QuickTimeFileSink::addAtom_avc1) {
01087           // special case: audio + H264 video: wait until audio is in sync
01088           if ((s.fNumSubsessions == 2) && (s.fNumSyncedSubsessions < (s.fNumSubsessions - 1))) return False;
01089 
01090           // if audio is in sync, wait for the next IDR frame to start
01091           unsigned char* const frameSource = fBuffer->dataStart();
01092           if (*frameSource != H264_IDR_FRAME) return False;
01093         }
01094         // But now we are
01095         fHaveBeenSynced = True;
01096         fSyncTime = presentationTime;
01097         ++s.fNumSyncedSubsessions;
01098 
01099         if (timevalGE(fSyncTime, s.fNewestSyncTime)) {
01100           s.fNewestSyncTime = fSyncTime;
01101         }
01102       }
01103     }
01104   }
01105 
01106   // Check again whether all subsessions have been synced:
01107   if (s.fNumSyncedSubsessions < s.fNumSubsessions) return False;
01108 
01109   // Allow this data if it is more recent than the newest sync time:
01110   return timevalGE(presentationTime, s.fNewestSyncTime);
01111 }

void SubsessionIOState::setHintTrack ( SubsessionIOState hintedTrack,
SubsessionIOState hintTrack 
) [static]

Definition at line 1113 of file QuickTimeFileSink.cpp.

References fHintTrackForUs, fTrackHintedByUs, hintedTrack, and NULL.

Referenced by QuickTimeFileSink::QuickTimeFileSink().

01114                                                                    {
01115   if (hintedTrack != NULL) hintedTrack->fHintTrackForUs = hintTrack;
01116   if (hintTrack != NULL) hintTrack->fTrackHintedByUs = hintedTrack;
01117 }

Boolean SubsessionIOState::isHintTrack (  )  const [inline]

Definition at line 128 of file QuickTimeFileSink.cpp.

References fTrackHintedByUs, and NULL.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), and setQTstate().

00128 { return fTrackHintedByUs != NULL; }

Boolean SubsessionIOState::hasHintTrack (  )  const [inline]

Definition at line 129 of file QuickTimeFileSink.cpp.

References fHintTrackForUs, and NULL.

Referenced by QuickTimeFileSink::completeOutputFile(), useFrame(), and while().

00129 { return fHintTrackForUs != NULL; }

UsageEnvironment& SubsessionIOState::envir (  )  const [inline]

Definition at line 131 of file QuickTimeFileSink.cpp.

References Medium::envir(), and fOurSink.

Referenced by QuickTimeFileSink::onRTCPBye(), setQTstate(), and useFrameForHinting().

00131 { return fOurSink.envir(); }

void SubsessionIOState::useFrame ( SubsessionBuffer buffer  )  [private]

Definition at line 767 of file QuickTimeFileSink.cpp.

References QuickTimeFileSink::addWord(), SubsessionBuffer::bytesInUse(), SubsessionBuffer::dataStart(), destFileOffset, duration, fHaveBeenSynced, fHeadSyncFrame, fHintTrackForUs, fourChar, fOurSink, fOurSubsession, QuickTimeFileSink::fOutFid, fPrevFrameState, fQTcomponentSubtype, fQTMediaDataAtomCreator, fQTSamplesPerFrame, fQTTimeScale, fQTTimeUnitsPerSample, fQTTotNumSamples, frameSize, QuickTimeFileSink::fSyncStreams, fTailSyncFrame, H264_IDR_FRAME, RTPSource::hasBeenSynchronizedUsingRTCP(), hasHintTrack(), SyncFrame::nextSyncFrame, NULL, SubsessionBuffer::presentationTime(), presentationTime, MediaSubsession::rtpSource(), TellFile64(), useFrame1(), and useFrameForHinting().

Referenced by afterGettingFrame().

00767                                                          {
00768   unsigned char* const frameSource = buffer.dataStart();
00769   unsigned const frameSize = buffer.bytesInUse();
00770   struct timeval const& presentationTime = buffer.presentationTime();
00771   int64_t const destFileOffset = TellFile64(fOurSink.fOutFid);
00772   unsigned sampleNumberOfFrameStart = fQTTotNumSamples + 1;
00773   Boolean avcHack = fQTMediaDataAtomCreator == &QuickTimeFileSink::addAtom_avc1;
00774 
00775   // If we're not syncing streams, or this subsession is not video, then
00776   // just give this frame a fixed duration:
00777   if (!fOurSink.fSyncStreams
00778       || fQTcomponentSubtype != fourChar('v','i','d','e')) {
00779     unsigned const frameDuration = fQTTimeUnitsPerSample*fQTSamplesPerFrame;
00780     unsigned frameSizeToUse = frameSize;
00781     if (avcHack) frameSizeToUse += 4; // H.264/AVC gets the frame size prefix
00782 
00783     fQTTotNumSamples += useFrame1(frameSizeToUse, presentationTime, frameDuration, destFileOffset);
00784   } else {
00785     // For synced video streams, we use the difference between successive
00786     // frames' presentation times as the 'frame duration'.  So, record
00787     // information about the *previous* frame:
00788     struct timeval const& ppt = fPrevFrameState.presentationTime; //abbrev
00789     if (ppt.tv_sec != 0 || ppt.tv_usec != 0) {
00790       // There has been a previous frame.
00791       double duration = (presentationTime.tv_sec - ppt.tv_sec)
00792         + (presentationTime.tv_usec - ppt.tv_usec)/1000000.0;
00793       if (duration < 0.0) duration = 0.0;
00794       unsigned frameDuration
00795         = (unsigned)((2*duration*fQTTimeScale+1)/2); // round
00796       unsigned frameSizeToUse = fPrevFrameState.frameSize;
00797       if (avcHack) frameSizeToUse += 4; // H.264/AVC gets the frame size prefix
00798 
00799       unsigned numSamples
00800         = useFrame1(frameSizeToUse, ppt, frameDuration, fPrevFrameState.destFileOffset);
00801       fQTTotNumSamples += numSamples;
00802       sampleNumberOfFrameStart = fQTTotNumSamples + 1;
00803     }
00804 
00805     if (avcHack && (*frameSource == H264_IDR_FRAME)) {
00806       SyncFrame* newSyncFrame = new SyncFrame(fQTTotNumSamples + 1);
00807       if (fTailSyncFrame == NULL) {
00808         fHeadSyncFrame = newSyncFrame;
00809       } else {
00810         fTailSyncFrame->nextSyncFrame = newSyncFrame;
00811       }
00812       fTailSyncFrame = newSyncFrame;
00813     }
00814 
00815     // Remember the current frame for next time:
00816     fPrevFrameState.frameSize = frameSize;
00817     fPrevFrameState.presentationTime = presentationTime;
00818     fPrevFrameState.destFileOffset = destFileOffset;
00819   }
00820 
00821   if (avcHack) fOurSink.addWord(frameSize);
00822 
00823   // Write the data into the file:
00824   fwrite(frameSource, 1, frameSize, fOurSink.fOutFid);
00825 
00826   // If we have a hint track, then write to it also:
00827   if (hasHintTrack()) {
00828     // Because presentation times are used for RTP packet timestamps,
00829     // we don't starting writing to the hint track until we've been synced:
00830     if (!fHaveBeenSynced) {
00831       fHaveBeenSynced
00832         = fOurSubsession.rtpSource()->hasBeenSynchronizedUsingRTCP();
00833     }
00834     if (fHaveBeenSynced) {
00835       fHintTrackForUs->useFrameForHinting(frameSize, presentationTime,
00836                                           sampleNumberOfFrameStart);
00837     }
00838   }
00839 }

void SubsessionIOState::useFrameForHinting ( unsigned  frameSize,
struct timeval  presentationTime,
unsigned  startSampleNumber 
) [private]

Definition at line 841 of file QuickTimeFileSink.cpp.

References QuickTimeFileSink::addByte(), QuickTimeFileSink::addHalfWord(), QuickTimeFileSink::addWord(), MediaSubsession::codecName(), RTPSource::curPacketMarkerBit(), SubsessionIOState::hinf::dimm, SubsessionIOState::hinf::dmax, SubsessionIOState::hinf::dmed, duration, envir(), fHINF, MediaSubsession::fmtp_indexlength(), MediaSubsession::fmtp_sizelength(), H263plusVideoRTPSource::fNumSpecialHeaders, fOurSink, fOurSubsession, QuickTimeFileSink::fOutFid, H263plusVideoRTPSource::fPacketSizes, fPrevFrameState, fQTBytesPerFrame, fQTSamplesPerFrame, fQTTimeScale, fQTTimeUnitsPerSample, fQTTotNumSamples, H263plusVideoRTPSource::fSpecialHeaderBytes, H263plusVideoRTPSource::fSpecialHeaderBytesLength, fTrackHintedByUs, if(), maxPacketSize, MediaSubsession::mediumName(), NULL, SubsessionIOState::hinf::nump, SubsessionIOState::hinf::pmax, rtpHeader, RTPSource::rtpPayloadFormat(), MediaSubsession::rtpSource(), MediaSubsession::rtpTimestampFrequency(), seqNum, TellFile64(), SubsessionIOState::hinf::tpyl, SubsessionIOState::hinf::trpy, and useFrame1().

Referenced by useFrame().

00843                                                                        {
00844   // At this point, we have a single, combined frame - not individual packets.
00845   // For the hint track, we need to split the frame back up into separate packets.
00846   // However, for some RTP sources, then we also need to reuse the special
00847   // header bytes that were at the start of each of the RTP packets.
00848   Boolean hack263 = strcmp(fOurSubsession.codecName(), "H263-1998") == 0;
00849   Boolean hackm4a_generic = strcmp(fOurSubsession.mediumName(), "audio") == 0
00850     && strcmp(fOurSubsession.codecName(), "MPEG4-GENERIC") == 0;
00851   Boolean hackm4a_latm = strcmp(fOurSubsession.mediumName(), "audio") == 0
00852     && strcmp(fOurSubsession.codecName(), "MP4A-LATM") == 0;
00853   Boolean hackm4a = hackm4a_generic || hackm4a_latm;
00854   Boolean haveSpecialHeaders = (hack263 || hackm4a_generic);
00855 
00856   // If there has been a previous frame, then output a 'hint sample' for it.
00857   // (We use the current frame's presentation time to compute the previous
00858   // hint sample's duration.)
00859   RTPSource* const rs = fOurSubsession.rtpSource(); // abbrev
00860   struct timeval const& ppt = fPrevFrameState.presentationTime; //abbrev
00861   if (ppt.tv_sec != 0 || ppt.tv_usec != 0) {
00862     double duration = (presentationTime.tv_sec - ppt.tv_sec)
00863       + (presentationTime.tv_usec - ppt.tv_usec)/1000000.0;
00864     if (duration < 0.0) duration = 0.0;
00865     unsigned msDuration = (unsigned)(duration*1000); // milliseconds
00866     if (msDuration > fHINF.dmax) fHINF.dmax = msDuration;
00867     unsigned hintSampleDuration
00868       = (unsigned)((2*duration*fQTTimeScale+1)/2); // round
00869     if (hackm4a) {
00870       // Because multiple AAC frames can appear in a RTP packet, the presentation
00871       // times of the second and subsequent frames will not be accurate.
00872       // So, use the known "hintSampleDuration" instead:
00873       hintSampleDuration = fTrackHintedByUs->fQTTimeUnitsPerSample;
00874 
00875       // Also, if the 'time scale' was different from the RTP timestamp frequency,
00876       // (as can happen with aacPlus), then we need to scale "hintSampleDuration"
00877       // accordingly:
00878       if (fTrackHintedByUs->fQTTimeScale != fOurSubsession.rtpTimestampFrequency()) {
00879         unsigned const scalingFactor
00880           = fOurSubsession.rtpTimestampFrequency()/fTrackHintedByUs->fQTTimeScale ;
00881         hintSampleDuration *= scalingFactor;
00882       }
00883     }
00884 
00885     int64_t const hintSampleDestFileOffset = TellFile64(fOurSink.fOutFid);
00886 
00887     unsigned const maxPacketSize = 1450;
00888     unsigned short numPTEntries
00889       = (fPrevFrameState.frameSize + (maxPacketSize-1))/maxPacketSize; // normal case
00890     unsigned char* immediateDataPtr = NULL;
00891     unsigned immediateDataBytesRemaining = 0;
00892     if (haveSpecialHeaders) { // special case
00893       numPTEntries = fPrevFrameState.numSpecialHeaders;
00894       immediateDataPtr = fPrevFrameState.specialHeaderBytes;
00895       immediateDataBytesRemaining
00896         = fPrevFrameState.specialHeaderBytesLength;
00897     }
00898     unsigned hintSampleSize
00899       = fOurSink.addHalfWord(numPTEntries);// Entry count
00900     hintSampleSize += fOurSink.addHalfWord(0x0000); // Reserved
00901 
00902     unsigned offsetWithinSample = 0;
00903     for (unsigned i = 0; i < numPTEntries; ++i) {
00904       // Output a Packet Table entry (representing a single RTP packet):
00905       unsigned short numDTEntries = 1;
00906       unsigned short seqNum = fPrevFrameState.seqNum++;
00907           // Note: This assumes that the input stream had no packets lost #####
00908       unsigned rtpHeader = fPrevFrameState.rtpHeader;
00909       if (i+1 < numPTEntries) {
00910         // This is not the last RTP packet, so clear the marker bit:
00911         rtpHeader &=~ (1<<23);
00912       }
00913       unsigned dataFrameSize = (i+1 < numPTEntries)
00914         ? maxPacketSize : fPrevFrameState.frameSize - i*maxPacketSize; // normal case
00915       unsigned sampleNumber = fPrevFrameState.startSampleNumber;
00916 
00917       unsigned char immediateDataLen = 0;
00918       if (haveSpecialHeaders) { // special case
00919         ++numDTEntries; // to include a Data Table entry for the special hdr
00920         if (immediateDataBytesRemaining > 0) {
00921           if (hack263) {
00922             immediateDataLen = *immediateDataPtr++;
00923             --immediateDataBytesRemaining;
00924             if (immediateDataLen > immediateDataBytesRemaining) {
00925               // shouldn't happen (length byte was bad)
00926               immediateDataLen = immediateDataBytesRemaining;
00927             }
00928           } else {
00929             immediateDataLen = fPrevFrameState.specialHeaderBytesLength;
00930           }
00931         }
00932         dataFrameSize = fPrevFrameState.packetSizes[i] - immediateDataLen;
00933 
00934         if (hack263) {
00935           Boolean PbitSet
00936             = immediateDataLen >= 1 && (immediateDataPtr[0]&0x4) != 0;
00937           if (PbitSet) {
00938             offsetWithinSample += 2; // to omit the two leading 0 bytes
00939           }
00940         }
00941       }
00942 
00943       // Output the Packet Table:
00944       hintSampleSize += fOurSink.addWord(0); // Relative transmission time
00945       hintSampleSize += fOurSink.addWord(rtpHeader|seqNum);
00946           // RTP header info + RTP sequence number
00947       hintSampleSize += fOurSink.addHalfWord(0x0000); // Flags
00948       hintSampleSize += fOurSink.addHalfWord(numDTEntries); // Entry count
00949       unsigned totalPacketSize = 0;
00950 
00951       // Output the Data Table:
00952       if (haveSpecialHeaders) {
00953         //   use the "Immediate Data" format (1):
00954         hintSampleSize += fOurSink.addByte(1); // Source
00955         unsigned char len = immediateDataLen > 14 ? 14 : immediateDataLen;
00956         hintSampleSize += fOurSink.addByte(len); // Length
00957         totalPacketSize += len; fHINF.dimm += len;
00958         unsigned char j;
00959         for (j = 0; j < len; ++j) {
00960           hintSampleSize += fOurSink.addByte(immediateDataPtr[j]); // Data
00961         }
00962         for (j = len; j < 14; ++j) {
00963           hintSampleSize += fOurSink.addByte(0); // Data (padding)
00964         }
00965 
00966         immediateDataPtr += immediateDataLen;
00967         immediateDataBytesRemaining -= immediateDataLen;
00968       }
00969       //   use the "Sample Data" format (2):
00970       hintSampleSize += fOurSink.addByte(2); // Source
00971       hintSampleSize += fOurSink.addByte(0); // Track ref index
00972       hintSampleSize += fOurSink.addHalfWord(dataFrameSize); // Length
00973       totalPacketSize += dataFrameSize; fHINF.dmed += dataFrameSize;
00974       hintSampleSize += fOurSink.addWord(sampleNumber); // Sample number
00975       hintSampleSize += fOurSink.addWord(offsetWithinSample); // Offset
00976       // Get "bytes|samples per compression block" from the hinted track:
00977       unsigned short const bytesPerCompressionBlock
00978         = fTrackHintedByUs->fQTBytesPerFrame;
00979       unsigned short const samplesPerCompressionBlock
00980         = fTrackHintedByUs->fQTSamplesPerFrame;
00981       hintSampleSize += fOurSink.addHalfWord(bytesPerCompressionBlock);
00982       hintSampleSize += fOurSink.addHalfWord(samplesPerCompressionBlock);
00983 
00984       offsetWithinSample += dataFrameSize;// for the next iteration (if any)
00985 
00986       // Tally statistics for this packet:
00987       fHINF.nump += 1;
00988       fHINF.tpyl += totalPacketSize;
00989       totalPacketSize += 12; // add in the size of the RTP header
00990       fHINF.trpy += totalPacketSize;
00991       if (totalPacketSize > fHINF.pmax) fHINF.pmax = totalPacketSize;
00992     }
00993 
00994     // Make note of this completed hint sample frame:
00995     fQTTotNumSamples += useFrame1(hintSampleSize, ppt, hintSampleDuration,
00996                                   hintSampleDestFileOffset);
00997   }
00998 
00999   // Remember this frame for next time:
01000   fPrevFrameState.frameSize = frameSize;
01001   fPrevFrameState.presentationTime = presentationTime;
01002   fPrevFrameState.startSampleNumber = startSampleNumber;
01003   fPrevFrameState.rtpHeader
01004     = rs->curPacketMarkerBit()<<23
01005     | (rs->rtpPayloadFormat()&0x7F)<<16;
01006   if (hack263) {
01007     H263plusVideoRTPSource* rs_263 = (H263plusVideoRTPSource*)rs;
01008     fPrevFrameState.numSpecialHeaders = rs_263->fNumSpecialHeaders;
01009     fPrevFrameState.specialHeaderBytesLength = rs_263->fSpecialHeaderBytesLength;
01010     unsigned i;
01011     for (i = 0; i < rs_263->fSpecialHeaderBytesLength; ++i) {
01012       fPrevFrameState.specialHeaderBytes[i] = rs_263->fSpecialHeaderBytes[i];
01013     }
01014     for (i = 0; i < rs_263->fNumSpecialHeaders; ++i) {
01015       fPrevFrameState.packetSizes[i] = rs_263->fPacketSizes[i];
01016     }
01017   } else if (hackm4a_generic) {
01018     // Synthesize a special header, so that this frame can be in its own RTP packet.
01019     unsigned const sizeLength = fOurSubsession.fmtp_sizelength();
01020     unsigned const indexLength = fOurSubsession.fmtp_indexlength();
01021     if (sizeLength + indexLength != 16) {
01022       envir() << "Warning: unexpected 'sizeLength' " << sizeLength
01023               << " and 'indexLength' " << indexLength
01024               << "seen when creating hint track\n";
01025     }
01026     fPrevFrameState.numSpecialHeaders = 1;
01027     fPrevFrameState.specialHeaderBytesLength = 4;
01028     fPrevFrameState.specialHeaderBytes[0] = 0; // AU_headers_length (high byte)
01029     fPrevFrameState.specialHeaderBytes[1] = 16; // AU_headers_length (low byte)
01030     fPrevFrameState.specialHeaderBytes[2] = ((frameSize<<indexLength)&0xFF00)>>8;
01031     fPrevFrameState.specialHeaderBytes[3] = (frameSize<<indexLength);
01032     fPrevFrameState.packetSizes[0]
01033       = fPrevFrameState.specialHeaderBytesLength + frameSize;
01034   }
01035 }

unsigned SubsessionIOState::useFrame1 ( unsigned  sourceDataSize,
struct timeval  presentationTime,
unsigned  frameDuration,
int64_t  destFileOffset 
) [private]

Definition at line 1037 of file QuickTimeFileSink.cpp.

References ChunkDescriptor::extendChunk(), fHeadChunk, fNumChunks, fQTBytesPerFrame, fQTSamplesPerFrame, frameSize, fTailChunk, and NULL.

Referenced by useFrame(), and useFrameForHinting().

01040                                                               {
01041   // Figure out the actual frame size for this data:
01042   unsigned frameSize = fQTBytesPerFrame;
01043   if (frameSize == 0) {
01044     // The entire packet data is assumed to be a frame:
01045     frameSize = sourceDataSize;
01046   }
01047   unsigned const numFrames = sourceDataSize/frameSize;
01048   unsigned const numSamples = numFrames*fQTSamplesPerFrame;
01049 
01050   // Record the information about which 'chunk' this data belongs to:
01051   ChunkDescriptor* newTailChunk;
01052   if (fTailChunk == NULL) {
01053     newTailChunk = fHeadChunk
01054       = new ChunkDescriptor(destFileOffset, sourceDataSize,
01055                             frameSize, frameDuration, presentationTime);
01056   } else {
01057     newTailChunk = fTailChunk->extendChunk(destFileOffset, sourceDataSize,
01058                                            frameSize, frameDuration,
01059                                            presentationTime);
01060   }
01061   if (newTailChunk != fTailChunk) {
01062    // This data created a new chunk, rather than extending the old one
01063     ++fNumChunks;
01064     fTailChunk = newTailChunk;
01065   }
01066 
01067   return numSamples;
01068 }


Field Documentation

unsigned SubsessionIOState::fCurrentTrackNumber = 0 [static]

Definition at line 134 of file QuickTimeFileSink.cpp.

Referenced by SubsessionIOState().

unsigned SubsessionIOState::fTrackID

Definition at line 135 of file QuickTimeFileSink.cpp.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), and SubsessionIOState().

SubsessionIOState* SubsessionIOState::fHintTrackForUs

Definition at line 136 of file QuickTimeFileSink.cpp.

Referenced by QuickTimeFileSink::completeOutputFile(), hasHintTrack(), setHintTrack(), useFrame(), while(), and QuickTimeFileSink::~QuickTimeFileSink().

SubsessionIOState* SubsessionIOState::fTrackHintedByUs

Definition at line 136 of file QuickTimeFileSink.cpp.

Referenced by isHintTrack(), setHintTrack(), and useFrameForHinting().

SubsessionBuffer* SubsessionIOState::fBuffer

Definition at line 138 of file QuickTimeFileSink.cpp.

Referenced by afterGettingFrame(), QuickTimeFileSink::continuePlaying(), SubsessionIOState(), syncOK(), and ~SubsessionIOState().

SubsessionBuffer * SubsessionIOState::fPrevBuffer

Definition at line 138 of file QuickTimeFileSink.cpp.

Referenced by afterGettingFrame(), SubsessionIOState(), and ~SubsessionIOState().

QuickTimeFileSink& SubsessionIOState::fOurSink

Definition at line 139 of file QuickTimeFileSink.cpp.

Referenced by afterGettingFrame(), QuickTimeFileSink::afterGettingFrame(), envir(), QuickTimeFileSink::onRTCPBye(), onSourceClosure(), setFinalQTstate(), setQTstate(), SubsessionIOState(), syncOK(), useFrame(), and useFrameForHinting().

MediaSubsession& SubsessionIOState::fOurSubsession

Definition at line 140 of file QuickTimeFileSink.cpp.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), afterGettingFrame(), QuickTimeFileSink::onRTCPBye(), setQTstate(), syncOK(), useFrame(), useFrameForHinting(), and while().

unsigned short SubsessionIOState::fLastPacketRTPSeqNum

Definition at line 142 of file QuickTimeFileSink.cpp.

Referenced by afterGettingFrame().

Boolean SubsessionIOState::fOurSourceIsActive

Definition at line 143 of file QuickTimeFileSink.cpp.

Referenced by onSourceClosure(), QuickTimeFileSink::onSourceClosure1(), and SubsessionIOState().

Boolean SubsessionIOState::fHaveBeenSynced

Definition at line 145 of file QuickTimeFileSink.cpp.

Referenced by syncOK(), and useFrame().

struct timeval SubsessionIOState::fSyncTime [read]

Definition at line 146 of file QuickTimeFileSink.cpp.

Referenced by syncOK().

Boolean SubsessionIOState::fQTEnableTrack

Definition at line 148 of file QuickTimeFileSink.cpp.

Referenced by setQTstate().

unsigned SubsessionIOState::fQTcomponentSubtype

Definition at line 149 of file QuickTimeFileSink.cpp.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), setQTstate(), and useFrame().

char const* SubsessionIOState::fQTcomponentName

Definition at line 150 of file QuickTimeFileSink.cpp.

Referenced by setQTstate().

atomCreationFunc SubsessionIOState::fQTMediaInformationAtomCreator

Definition at line 152 of file QuickTimeFileSink.cpp.

Referenced by setQTstate().

atomCreationFunc SubsessionIOState::fQTMediaDataAtomCreator

Definition at line 153 of file QuickTimeFileSink.cpp.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), afterGettingFrame(), setQTstate(), syncOK(), and useFrame().

char const* SubsessionIOState::fQTAudioDataType

Definition at line 154 of file QuickTimeFileSink.cpp.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), and setQTstate().

unsigned short SubsessionIOState::fQTSoundSampleVersion

Definition at line 155 of file QuickTimeFileSink.cpp.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), and setQTstate().

unsigned SubsessionIOState::fQTTimeScale

Definition at line 156 of file QuickTimeFileSink.cpp.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), afterGettingFrame(), if(), setFinalQTstate(), setQTstate(), useFrame(), useFrameForHinting(), and while().

unsigned SubsessionIOState::fQTTimeUnitsPerSample

Definition at line 157 of file QuickTimeFileSink.cpp.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), afterGettingFrame(), setQTstate(), useFrame(), and useFrameForHinting().

unsigned SubsessionIOState::fQTBytesPerFrame

Definition at line 158 of file QuickTimeFileSink.cpp.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), afterGettingFrame(), setQTstate(), useFrame1(), and useFrameForHinting().

unsigned SubsessionIOState::fQTSamplesPerFrame

Definition at line 159 of file QuickTimeFileSink.cpp.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), afterGettingFrame(), setQTstate(), useFrame(), useFrame1(), and useFrameForHinting().

unsigned SubsessionIOState::fQTTotNumSamples

Definition at line 162 of file QuickTimeFileSink.cpp.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), useFrame(), and useFrameForHinting().

unsigned SubsessionIOState::fQTDurationM

Definition at line 163 of file QuickTimeFileSink.cpp.

Referenced by if(), and setFinalQTstate().

unsigned SubsessionIOState::fQTDurationT

Definition at line 164 of file QuickTimeFileSink.cpp.

Referenced by if(), and setFinalQTstate().

int64_t SubsessionIOState::fTKHD_durationPosn

Definition at line 165 of file QuickTimeFileSink.cpp.

Referenced by if().

unsigned SubsessionIOState::fQTInitialOffsetDuration

Definition at line 167 of file QuickTimeFileSink.cpp.

ChunkDescriptor* SubsessionIOState::fHeadChunk

Definition at line 170 of file QuickTimeFileSink.cpp.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), QuickTimeFileSink::completeOutputFile(), setFinalQTstate(), useFrame1(), and ~SubsessionIOState().

ChunkDescriptor * SubsessionIOState::fTailChunk

Definition at line 170 of file QuickTimeFileSink.cpp.

Referenced by useFrame1().

unsigned SubsessionIOState::fNumChunks

Definition at line 171 of file QuickTimeFileSink.cpp.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), and useFrame1().

SyncFrame* SubsessionIOState::fHeadSyncFrame

Definition at line 172 of file QuickTimeFileSink.cpp.

Referenced by QuickTimeFileSink::addAtom_hdlr2(), useFrame(), and ~SubsessionIOState().

SyncFrame * SubsessionIOState::fTailSyncFrame

Definition at line 172 of file QuickTimeFileSink.cpp.

Referenced by useFrame().

struct SubsessionIOState::hinf SubsessionIOState::fHINF

Referenced by QuickTimeFileSink::addAtom_hdlr2(), and useFrameForHinting().

unsigned SubsessionIOState::frameSize

Definition at line 203 of file QuickTimeFileSink.cpp.

Referenced by useFrame(), and useFrame1().

struct timeval SubsessionIOState::presentationTime [read]

Definition at line 204 of file QuickTimeFileSink.cpp.

Referenced by useFrame().

int64_t SubsessionIOState::destFileOffset

Definition at line 205 of file QuickTimeFileSink.cpp.

Referenced by useFrame().

unsigned SubsessionIOState::startSampleNumber

Definition at line 208 of file QuickTimeFileSink.cpp.

unsigned short SubsessionIOState::seqNum

Definition at line 209 of file QuickTimeFileSink.cpp.

Referenced by useFrameForHinting().

unsigned SubsessionIOState::rtpHeader

Definition at line 210 of file QuickTimeFileSink.cpp.

Referenced by useFrameForHinting().

unsigned char SubsessionIOState::numSpecialHeaders

Definition at line 211 of file QuickTimeFileSink.cpp.

unsigned SubsessionIOState::specialHeaderBytesLength

Definition at line 212 of file QuickTimeFileSink.cpp.

unsigned char SubsessionIOState::specialHeaderBytes[SPECIAL_HEADER_BUFFER_SIZE]

Definition at line 213 of file QuickTimeFileSink.cpp.

unsigned SubsessionIOState::packetSizes[256]

Definition at line 214 of file QuickTimeFileSink.cpp.

struct { ... } SubsessionIOState::fPrevFrameState [private]

Referenced by SubsessionIOState(), useFrame(), and useFrameForHinting().


The documentation for this class was generated from the following file:
Generated on Thu Feb 2 23:56:00 2012 for live by  doxygen 1.5.2