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 529 of file QuickTimeFileSink.cpp.

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

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

SubsessionIOState::~SubsessionIOState (  )  [virtual]

Definition at line 550 of file QuickTimeFileSink.cpp.

References fBuffer, fHeadChunk, fHeadSyncFrame, and fPrevBuffer.

00550                                       {
00551   delete fBuffer; delete fPrevBuffer;
00552   delete fHeadChunk; delete fHeadSyncFrame;
00553 }


Member Function Documentation

Boolean SubsessionIOState::setQTstate (  ) 

Definition at line 555 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().

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

void SubsessionIOState::setFinalQTstate (  ) 

Definition at line 667 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().

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

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

Definition at line 689 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().

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

void SubsessionIOState::onSourceClosure (  ) 

Definition at line 1075 of file QuickTimeFileSink.cpp.

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

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

01075                                         {
01076   fOurSourceIsActive = False;
01077   fOurSink.onSourceClosure1();
01078 }

Boolean SubsessionIOState::syncOK ( struct timeval  presentationTime  ) 

Definition at line 1080 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().

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

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

Definition at line 1118 of file QuickTimeFileSink.cpp.

References fHintTrackForUs, fTrackHintedByUs, hintedTrack, and NULL.

Referenced by QuickTimeFileSink::QuickTimeFileSink().

01119                                                                    {
01120   if (hintedTrack != NULL) hintedTrack->fHintTrackForUs = hintTrack;
01121   if (hintTrack != NULL) hintTrack->fTrackHintedByUs = hintedTrack;
01122 }

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::afterGettingFrame(), QuickTimeFileSink::onRTCPBye(), setQTstate(), and useFrameForHinting().

00131 { return fOurSink.envir(); }

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

Definition at line 772 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().

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

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

Definition at line 846 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().

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

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

Definition at line 1042 of file QuickTimeFileSink.cpp.

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

Referenced by useFrame(), and useFrameForHinting().

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


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 May 17 07:16:23 2012 for live by  doxygen 1.5.2