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


Member Typedef Documentation

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

Definition at line 149 of file QuickTimeFileSink.cpp.


Constructor & Destructor Documentation

SubsessionIOState::SubsessionIOState ( QuickTimeFileSink sink,
MediaSubsession subsession 
)

Definition at line 527 of file QuickTimeFileSink.cpp.

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

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

SubsessionIOState::~SubsessionIOState (  )  [virtual]

Definition at line 548 of file QuickTimeFileSink.cpp.

References chunk, fBuffer, fHeadChunk, fHeadSyncFrame, ChunkDescriptor::fNextChunk, fPrevBuffer, SyncFrame::nextSyncFrame, and NULL.

00548                                       {
00549   delete fBuffer; delete fPrevBuffer;
00550 
00551   // Delete the list of chunk descriptors:
00552   ChunkDescriptor* chunk = fHeadChunk;
00553   while (chunk != NULL) {
00554     ChunkDescriptor* next = chunk->fNextChunk;
00555     delete chunk;
00556     chunk = next;
00557   }
00558 
00559   // Delete the list of sync frames:
00560   SyncFrame* syncFrame = fHeadSyncFrame;
00561   while (syncFrame != NULL) {
00562     SyncFrame* next = syncFrame->nextSyncFrame;
00563     delete syncFrame;
00564     syncFrame = next;
00565   }
00566 }


Member Function Documentation

Boolean SubsessionIOState::setQTstate (  ) 

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

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

void SubsessionIOState::setFinalQTstate (  ) 

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

00680                                         {
00681   // Compute derived parameters, by running through the list of chunks:
00682   fQTDurationT = 0;
00683 
00684   ChunkDescriptor* chunk = fHeadChunk;
00685   while (chunk != NULL) {
00686     unsigned const numFrames = chunk->fNumFrames;
00687     unsigned const dur = numFrames*chunk->fFrameDuration;
00688     fQTDurationT += dur;
00689 
00690     chunk = chunk->fNextChunk;
00691   }
00692 
00693   // Convert this duration from track to movie time scale:
00694   double scaleFactor = fOurSink.movieTimeScale()/(double)fQTTimeScale;
00695   fQTDurationM = (unsigned)(fQTDurationT*scaleFactor);
00696 
00697   if (fQTDurationM > fOurSink.fMaxTrackDurationM) {
00698     fOurSink.fMaxTrackDurationM = fQTDurationM;
00699   }
00700 }

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

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

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

void SubsessionIOState::onSourceClosure (  ) 

Definition at line 1088 of file QuickTimeFileSink.cpp.

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

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

01088                                         {
01089   fOurSourceIsActive = False;
01090   fOurSink.onSourceClosure1();
01091 }

Boolean SubsessionIOState::syncOK ( struct timeval  presentationTime  ) 

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

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

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

Definition at line 1131 of file QuickTimeFileSink.cpp.

References fHintTrackForUs, fTrackHintedByUs, hintedTrack, and NULL.

Referenced by QuickTimeFileSink::QuickTimeFileSink().

01132                                                                    {
01133   if (hintedTrack != NULL) hintedTrack->fHintTrackForUs = hintTrack;
01134   if (hintTrack != NULL) hintTrack->fTrackHintedByUs = hintedTrack;
01135 }

Boolean SubsessionIOState::isHintTrack (  )  const [inline]

Definition at line 126 of file QuickTimeFileSink.cpp.

References fTrackHintedByUs, and NULL.

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

00126 { return fTrackHintedByUs != NULL; }

Boolean SubsessionIOState::hasHintTrack (  )  const [inline]

Definition at line 127 of file QuickTimeFileSink.cpp.

References fHintTrackForUs, and NULL.

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

00127 { return fHintTrackForUs != NULL; }

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

Definition at line 129 of file QuickTimeFileSink.cpp.

References Medium::envir(), and fOurSink.

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

00129 { return fOurSink.envir(); }

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

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

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

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

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

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

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

Definition at line 1055 of file QuickTimeFileSink.cpp.

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

Referenced by useFrame(), and useFrameForHinting().

01058                                                               {
01059   // Figure out the actual frame size for this data:
01060   unsigned frameSize = fQTBytesPerFrame;
01061   if (frameSize == 0) {
01062     // The entire packet data is assumed to be a frame:
01063     frameSize = sourceDataSize;
01064   }
01065   unsigned const numFrames = sourceDataSize/frameSize;
01066   unsigned const numSamples = numFrames*fQTSamplesPerFrame;
01067 
01068   // Record the information about which 'chunk' this data belongs to:
01069   ChunkDescriptor* newTailChunk;
01070   if (fTailChunk == NULL) {
01071     newTailChunk = fHeadChunk
01072       = new ChunkDescriptor(destFileOffset, sourceDataSize,
01073                             frameSize, frameDuration, presentationTime);
01074   } else {
01075     newTailChunk = fTailChunk->extendChunk(destFileOffset, sourceDataSize,
01076                                            frameSize, frameDuration,
01077                                            presentationTime);
01078   }
01079   if (newTailChunk != fTailChunk) {
01080    // This data created a new chunk, rather than extending the old one
01081     ++fNumChunks;
01082     fTailChunk = newTailChunk;
01083   }
01084 
01085   return numSamples;
01086 }


Field Documentation

unsigned SubsessionIOState::fCurrentTrackNumber = 0 [static]

Definition at line 132 of file QuickTimeFileSink.cpp.

Referenced by SubsessionIOState().

unsigned SubsessionIOState::fTrackID

Definition at line 133 of file QuickTimeFileSink.cpp.

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

SubsessionIOState* SubsessionIOState::fHintTrackForUs

Definition at line 134 of file QuickTimeFileSink.cpp.

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

SubsessionIOState* SubsessionIOState::fTrackHintedByUs

Definition at line 134 of file QuickTimeFileSink.cpp.

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

SubsessionBuffer* SubsessionIOState::fBuffer

Definition at line 136 of file QuickTimeFileSink.cpp.

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

SubsessionBuffer * SubsessionIOState::fPrevBuffer

Definition at line 136 of file QuickTimeFileSink.cpp.

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

QuickTimeFileSink& SubsessionIOState::fOurSink

Definition at line 137 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 138 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 140 of file QuickTimeFileSink.cpp.

Referenced by afterGettingFrame().

Boolean SubsessionIOState::fOurSourceIsActive

Definition at line 141 of file QuickTimeFileSink.cpp.

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

Boolean SubsessionIOState::fHaveBeenSynced

Definition at line 143 of file QuickTimeFileSink.cpp.

Referenced by syncOK(), and useFrame().

struct timeval SubsessionIOState::fSyncTime [read]

Definition at line 144 of file QuickTimeFileSink.cpp.

Referenced by syncOK().

Boolean SubsessionIOState::fQTEnableTrack

Definition at line 146 of file QuickTimeFileSink.cpp.

Referenced by setQTstate().

unsigned SubsessionIOState::fQTcomponentSubtype

Definition at line 147 of file QuickTimeFileSink.cpp.

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

char const* SubsessionIOState::fQTcomponentName

Definition at line 148 of file QuickTimeFileSink.cpp.

Referenced by setQTstate().

atomCreationFunc SubsessionIOState::fQTMediaInformationAtomCreator

Definition at line 150 of file QuickTimeFileSink.cpp.

Referenced by setQTstate().

atomCreationFunc SubsessionIOState::fQTMediaDataAtomCreator

Definition at line 151 of file QuickTimeFileSink.cpp.

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

char const* SubsessionIOState::fQTAudioDataType

Definition at line 152 of file QuickTimeFileSink.cpp.

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

unsigned short SubsessionIOState::fQTSoundSampleVersion

Definition at line 153 of file QuickTimeFileSink.cpp.

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

unsigned SubsessionIOState::fQTTimeScale

Definition at line 154 of file QuickTimeFileSink.cpp.

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

unsigned SubsessionIOState::fQTTimeUnitsPerSample

Definition at line 155 of file QuickTimeFileSink.cpp.

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

unsigned SubsessionIOState::fQTBytesPerFrame

Definition at line 156 of file QuickTimeFileSink.cpp.

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

unsigned SubsessionIOState::fQTSamplesPerFrame

Definition at line 157 of file QuickTimeFileSink.cpp.

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

unsigned SubsessionIOState::fQTTotNumSamples

Definition at line 160 of file QuickTimeFileSink.cpp.

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

unsigned SubsessionIOState::fQTDurationM

Definition at line 161 of file QuickTimeFileSink.cpp.

Referenced by if(), and setFinalQTstate().

unsigned SubsessionIOState::fQTDurationT

Definition at line 162 of file QuickTimeFileSink.cpp.

Referenced by if(), and setFinalQTstate().

int64_t SubsessionIOState::fTKHD_durationPosn

Definition at line 163 of file QuickTimeFileSink.cpp.

Referenced by if().

unsigned SubsessionIOState::fQTInitialOffsetDuration

Definition at line 165 of file QuickTimeFileSink.cpp.

ChunkDescriptor* SubsessionIOState::fHeadChunk

Definition at line 168 of file QuickTimeFileSink.cpp.

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

ChunkDescriptor * SubsessionIOState::fTailChunk

Definition at line 168 of file QuickTimeFileSink.cpp.

Referenced by useFrame1().

unsigned SubsessionIOState::fNumChunks

Definition at line 169 of file QuickTimeFileSink.cpp.

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

SyncFrame* SubsessionIOState::fHeadSyncFrame

Definition at line 170 of file QuickTimeFileSink.cpp.

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

SyncFrame * SubsessionIOState::fTailSyncFrame

Definition at line 170 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 201 of file QuickTimeFileSink.cpp.

Referenced by useFrame(), and useFrame1().

struct timeval SubsessionIOState::presentationTime [read]

Definition at line 202 of file QuickTimeFileSink.cpp.

Referenced by useFrame().

int64_t SubsessionIOState::destFileOffset

Definition at line 203 of file QuickTimeFileSink.cpp.

Referenced by useFrame().

unsigned SubsessionIOState::startSampleNumber

Definition at line 206 of file QuickTimeFileSink.cpp.

unsigned short SubsessionIOState::seqNum

Definition at line 207 of file QuickTimeFileSink.cpp.

Referenced by useFrameForHinting().

unsigned SubsessionIOState::rtpHeader

Definition at line 208 of file QuickTimeFileSink.cpp.

Referenced by useFrameForHinting().

unsigned char SubsessionIOState::numSpecialHeaders

Definition at line 209 of file QuickTimeFileSink.cpp.

unsigned SubsessionIOState::specialHeaderBytesLength

Definition at line 210 of file QuickTimeFileSink.cpp.

unsigned char SubsessionIOState::specialHeaderBytes[SPECIAL_HEADER_BUFFER_SIZE]

Definition at line 211 of file QuickTimeFileSink.cpp.

unsigned SubsessionIOState::packetSizes[256]

Definition at line 212 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 Mon Apr 29 13:32:41 2013 for live by  doxygen 1.5.2