AVISubsessionIOState Class Reference

Collaboration diagram for AVISubsessionIOState:

Collaboration graph
[legend]

Public Member Functions

 AVISubsessionIOState (AVIFileSink &sink, MediaSubsession &subsession)
virtual ~AVISubsessionIOState ()
void setAVIstate (unsigned subsessionIndex)
void setFinalAVIstate ()
void afterGettingFrame (unsigned packetDataSize, struct timeval presentationTime)
void onSourceClosure ()
UsageEnvironmentenvir () const

Data Fields

SubsessionBufferfBuffer
SubsessionBufferfPrevBuffer
AVIFileSinkfOurSink
MediaSubsessionfOurSubsession
unsigned short fLastPacketRTPSeqNum
Boolean fOurSourceIsActive
timeval fPrevPresentationTime
unsigned fMaxBytesPerSecond
Boolean fIsVideo
Boolean fIsAudio
Boolean fIsByteSwappedAudio
unsigned fAVISubsessionTag
unsigned fAVICodecHandlerType
unsigned fAVISamplingFrequency
u_int16_t fWAVCodecTag
unsigned fAVIScale
unsigned fAVIRate
unsigned fAVISize
unsigned fNumFrames
unsigned fSTRHFrameCountPosition

Private Member Functions

void useFrame (SubsessionBuffer &buffer)

Detailed Description

Definition at line 58 of file AVIFileSink.cpp.


Constructor & Destructor Documentation

AVISubsessionIOState::AVISubsessionIOState ( AVIFileSink sink,
MediaSubsession subsession 
)

Definition at line 326 of file AVIFileSink.cpp.

References fBuffer, AVIFileSink::fBufferSize, fOurSink, fOurSourceIsActive, AVIFileSink::fPacketLossCompensate, fPrevBuffer, fPrevPresentationTime, NULL, MediaSubsession::readSource(), and subsession.

00328   : fOurSink(sink), fOurSubsession(subsession),
00329     fMaxBytesPerSecond(0), fNumFrames(0) {
00330   fBuffer = new SubsessionBuffer(fOurSink.fBufferSize);
00331   fPrevBuffer = sink.fPacketLossCompensate
00332     ? new SubsessionBuffer(fOurSink.fBufferSize) : NULL;
00333 
00334   FramedSource* subsessionSource = subsession.readSource();
00335   fOurSourceIsActive = subsessionSource != NULL;
00336 
00337   fPrevPresentationTime.tv_sec = 0;
00338   fPrevPresentationTime.tv_usec = 0;
00339 }

AVISubsessionIOState::~AVISubsessionIOState (  )  [virtual]

Definition at line 341 of file AVIFileSink.cpp.

References fBuffer, and fPrevBuffer.

00341                                             {
00342   delete fBuffer; delete fPrevBuffer;
00343 }


Member Function Documentation

void AVISubsessionIOState::setAVIstate ( unsigned  subsessionIndex  ) 

Definition at line 345 of file AVIFileSink.cpp.

References MediaSubsession::codecName(), False, fAVICodecHandlerType, fAVIRate, fAVISamplingFrequency, fAVIScale, fAVISize, fAVISubsessionTag, fIsAudio, fIsByteSwappedAudio, fIsVideo, AVIFileSink::fMovieFPS, AVIFileSink::fMovieHeight, AVIFileSink::fMovieWidth, fourChar, fOurSink, fOurSubsession, fWAVCodecTag, MediaSubsession::mediumName(), MediaSubsession::numChannels(), MediaSubsession::rtpTimestampFrequency(), and True.

Referenced by while().

00345                                                                {
00346   fIsVideo = strcmp(fOurSubsession.mediumName(), "video") == 0;
00347   fIsAudio = strcmp(fOurSubsession.mediumName(), "audio") == 0;
00348 
00349   if (fIsVideo) {
00350     fAVISubsessionTag
00351       = fourChar('0'+subsessionIndex/10,'0'+subsessionIndex%10,'d','c');
00352     if (strcmp(fOurSubsession.codecName(), "JPEG") == 0) {
00353       fAVICodecHandlerType = fourChar('m','j','p','g');
00354     } else if (strcmp(fOurSubsession.codecName(), "MP4V-ES") == 0) {
00355       fAVICodecHandlerType = fourChar('D','I','V','X');
00356     } else if (strcmp(fOurSubsession.codecName(), "MPV") == 0) {
00357       fAVICodecHandlerType = fourChar('m','p','g','1'); // what about MPEG-2?
00358     } else if (strcmp(fOurSubsession.codecName(), "H263-1998") == 0 ||
00359                strcmp(fOurSubsession.codecName(), "H263-2000") == 0) {
00360       fAVICodecHandlerType = fourChar('H','2','6','3');
00361     } else if (strcmp(fOurSubsession.codecName(), "H264") == 0) {
00362       fAVICodecHandlerType = fourChar('H','2','6','4');
00363     } else {
00364       fAVICodecHandlerType = fourChar('?','?','?','?');
00365     }
00366     fAVIScale = 1; // ??? #####
00367     fAVIRate = fOurSink.fMovieFPS; // ??? #####
00368     fAVISize = fOurSink.fMovieWidth*fOurSink.fMovieHeight*3; // ??? #####
00369   } else if (fIsAudio) {
00370     fIsByteSwappedAudio = False; // by default
00371     fAVISubsessionTag
00372       = fourChar('0'+subsessionIndex/10,'0'+subsessionIndex%10,'w','b');
00373     fAVICodecHandlerType = 1; // ??? ####
00374     unsigned numChannels = fOurSubsession.numChannels();
00375     fAVISamplingFrequency = fOurSubsession.rtpTimestampFrequency(); // default
00376     if (strcmp(fOurSubsession.codecName(), "L16") == 0) {
00377       fIsByteSwappedAudio = True; // need to byte-swap data before writing it
00378       fWAVCodecTag = 0x0001;
00379       fAVIScale = fAVISize = 2*numChannels; // 2 bytes/sample
00380       fAVIRate = fAVISize*fAVISamplingFrequency;
00381     } else if (strcmp(fOurSubsession.codecName(), "L8") == 0) {
00382       fWAVCodecTag = 0x0001;
00383       fAVIScale = fAVISize = numChannels; // 1 byte/sample
00384       fAVIRate = fAVISize*fAVISamplingFrequency;
00385     } else if (strcmp(fOurSubsession.codecName(), "PCMA") == 0) {
00386       fWAVCodecTag = 0x0006;
00387       fAVIScale = fAVISize = numChannels; // 1 byte/sample
00388       fAVIRate = fAVISize*fAVISamplingFrequency;
00389     } else if (strcmp(fOurSubsession.codecName(), "PCMU") == 0) {
00390       fWAVCodecTag = 0x0007;
00391       fAVIScale = fAVISize = numChannels; // 1 byte/sample
00392       fAVIRate = fAVISize*fAVISamplingFrequency;
00393     } else if (strcmp(fOurSubsession.codecName(), "MPA") == 0) {
00394       fWAVCodecTag = 0x0050;
00395       fAVIScale = fAVISize = 1;
00396       fAVIRate = 0; // ??? #####
00397     } else {
00398       fWAVCodecTag = 0x0001; // ??? #####
00399       fAVIScale = fAVISize = 1;
00400       fAVIRate = 0; // ??? #####
00401     }
00402   } else { // unknown medium
00403     fAVISubsessionTag
00404       = fourChar('0'+subsessionIndex/10,'0'+subsessionIndex%10,'?','?');
00405     fAVICodecHandlerType = 0;
00406     fAVIScale = fAVISize = 1;
00407     fAVIRate = 0; // ??? #####
00408   }
00409 }

void AVISubsessionIOState::setFinalAVIstate (  ) 

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

Definition at line 411 of file AVIFileSink.cpp.

References SubsessionBuffer::addBytes(), SubsessionBuffer::bytesInUse(), AVIFileSink::continuePlaying(), RTPSource::curPacketRTPSeqNum(), fBuffer, fLastPacketRTPSeqNum, fOurSink, fOurSubsession, AVIFileSink::fPacketLossCompensate, fPrevBuffer, SubsessionBuffer::reset(), MediaSubsession::rtpSource(), SubsessionBuffer::setPresentationTime(), and useFrame().

Referenced by AVIFileSink::afterGettingFrame().

00412                                                                            {
00413   // Begin by checking whether there was a gap in the RTP stream.
00414   // If so, try to compensate for this (if desired):
00415   unsigned short rtpSeqNum
00416     = fOurSubsession.rtpSource()->curPacketRTPSeqNum();
00417   if (fOurSink.fPacketLossCompensate && fPrevBuffer->bytesInUse() > 0) {
00418     short seqNumGap = rtpSeqNum - fLastPacketRTPSeqNum;
00419     for (short i = 1; i < seqNumGap; ++i) {
00420       // Insert a copy of the previous frame, to compensate for the loss:
00421       useFrame(*fPrevBuffer);
00422     }
00423   }
00424   fLastPacketRTPSeqNum = rtpSeqNum;
00425 
00426   // Now, continue working with the frame that we just got
00427   if (fBuffer->bytesInUse() == 0) {
00428     fBuffer->setPresentationTime(presentationTime);
00429   }
00430   fBuffer->addBytes(packetDataSize);
00431 
00432   useFrame(*fBuffer);
00433   if (fOurSink.fPacketLossCompensate) {
00434     // Save this frame, in case we need it for recovery:
00435     SubsessionBuffer* tmp = fPrevBuffer; // assert: != NULL
00436     fPrevBuffer = fBuffer;
00437     fBuffer = tmp;
00438   }
00439   fBuffer->reset(); // for the next input
00440 
00441   // Now, try getting more frames:
00442   fOurSink.continuePlaying();
00443 }

void AVISubsessionIOState::onSourceClosure (  ) 

Definition at line 483 of file AVIFileSink.cpp.

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

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

00483                                            {
00484   fOurSourceIsActive = False;
00485   fOurSink.onSourceClosure1();
00486 }

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

Definition at line 70 of file AVIFileSink.cpp.

References Medium::envir(), and fOurSink.

Referenced by AVIFileSink::onRTCPBye().

00070 { return fOurSink.envir(); }

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

Definition at line 445 of file AVIFileSink.cpp.

References AVIFileSink::addByte(), AVIFileSink::addWord(), SubsessionBuffer::bytesInUse(), SubsessionBuffer::dataStart(), fAVISubsessionTag, fIsByteSwappedAudio, fMaxBytesPerSecond, AVIFileSink::fNumBytesWritten, fNumFrames, fOurSink, AVIFileSink::fOutFid, fPrevPresentationTime, frameSize, and SubsessionBuffer::presentationTime().

Referenced by afterGettingFrame().

00445                                                             {
00446   unsigned char* const frameSource = buffer.dataStart();
00447   unsigned const frameSize = buffer.bytesInUse();
00448   struct timeval const& presentationTime = buffer.presentationTime();
00449   if (fPrevPresentationTime.tv_usec != 0||fPrevPresentationTime.tv_sec != 0) {
00450     int uSecondsDiff
00451       = (presentationTime.tv_sec - fPrevPresentationTime.tv_sec)*1000000
00452       + (presentationTime.tv_usec - fPrevPresentationTime.tv_usec);
00453     if (uSecondsDiff > 0) {
00454       unsigned bytesPerSecond = (unsigned)((frameSize*1000000.0)/uSecondsDiff);
00455       if (bytesPerSecond > fMaxBytesPerSecond) {
00456         fMaxBytesPerSecond = bytesPerSecond;
00457       }
00458     }
00459   }
00460   fPrevPresentationTime = presentationTime;
00461 
00462   if (fIsByteSwappedAudio) {
00463     // We need to swap the 16-bit audio samples from big-endian
00464     // to little-endian order, before writing them to a file:
00465     for (unsigned i = 0; i < frameSize; i += 2) {
00466       unsigned char tmp = frameSource[i];
00467       frameSource[i] = frameSource[i+1];
00468       frameSource[i+1] = tmp;
00469     }
00470   }
00471 
00472   // Write the data into the file:
00473   fOurSink.fNumBytesWritten += fOurSink.addWord(fAVISubsessionTag);
00474   fOurSink.fNumBytesWritten += fOurSink.addWord(frameSize);
00475   fwrite(frameSource, 1, frameSize, fOurSink.fOutFid);
00476   fOurSink.fNumBytesWritten += frameSize;
00477   // Pad to an even length:
00478   if (frameSize%2 != 0) fOurSink.fNumBytesWritten += fOurSink.addByte(0);
00479 
00480   ++fNumFrames;
00481 }


Field Documentation

SubsessionBuffer* AVISubsessionIOState::fBuffer

Definition at line 73 of file AVIFileSink.cpp.

Referenced by afterGettingFrame(), AVISubsessionIOState(), AVIFileSink::continuePlaying(), and ~AVISubsessionIOState().

SubsessionBuffer * AVISubsessionIOState::fPrevBuffer

Definition at line 73 of file AVIFileSink.cpp.

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

AVIFileSink& AVISubsessionIOState::fOurSink

Definition at line 74 of file AVIFileSink.cpp.

Referenced by afterGettingFrame(), AVISubsessionIOState(), envir(), AVIFileSink::onRTCPBye(), onSourceClosure(), setAVIstate(), and useFrame().

MediaSubsession& AVISubsessionIOState::fOurSubsession

Definition at line 75 of file AVIFileSink.cpp.

Referenced by afterGettingFrame(), AVIFileSink::onRTCPBye(), and setAVIstate().

unsigned short AVISubsessionIOState::fLastPacketRTPSeqNum

Definition at line 77 of file AVIFileSink.cpp.

Referenced by afterGettingFrame().

Boolean AVISubsessionIOState::fOurSourceIsActive

Definition at line 78 of file AVIFileSink.cpp.

Referenced by AVISubsessionIOState(), onSourceClosure(), and AVIFileSink::onSourceClosure1().

struct timeval AVISubsessionIOState::fPrevPresentationTime [read]

Definition at line 79 of file AVIFileSink.cpp.

Referenced by AVISubsessionIOState(), and useFrame().

unsigned AVISubsessionIOState::fMaxBytesPerSecond

Definition at line 80 of file AVIFileSink.cpp.

Referenced by AVIFileSink::completeOutputFile(), and useFrame().

Boolean AVISubsessionIOState::fIsVideo

Definition at line 81 of file AVIFileSink.cpp.

Referenced by AVIFileSink::completeOutputFile(), and setAVIstate().

Boolean AVISubsessionIOState::fIsAudio

Definition at line 81 of file AVIFileSink.cpp.

Referenced by AVIFileSink::completeOutputFile(), and setAVIstate().

Boolean AVISubsessionIOState::fIsByteSwappedAudio

Definition at line 81 of file AVIFileSink.cpp.

Referenced by setAVIstate(), and useFrame().

unsigned AVISubsessionIOState::fAVISubsessionTag

Definition at line 82 of file AVIFileSink.cpp.

Referenced by if(), setAVIstate(), and useFrame().

unsigned AVISubsessionIOState::fAVICodecHandlerType

Definition at line 83 of file AVIFileSink.cpp.

Referenced by setAVIstate().

unsigned AVISubsessionIOState::fAVISamplingFrequency

Definition at line 84 of file AVIFileSink.cpp.

Referenced by setAVIstate().

u_int16_t AVISubsessionIOState::fWAVCodecTag

Definition at line 85 of file AVIFileSink.cpp.

Referenced by setAVIstate().

unsigned AVISubsessionIOState::fAVIScale

Definition at line 86 of file AVIFileSink.cpp.

Referenced by setAVIstate().

unsigned AVISubsessionIOState::fAVIRate

Definition at line 87 of file AVIFileSink.cpp.

Referenced by setAVIstate().

unsigned AVISubsessionIOState::fAVISize

Definition at line 88 of file AVIFileSink.cpp.

Referenced by setAVIstate().

unsigned AVISubsessionIOState::fNumFrames

Definition at line 89 of file AVIFileSink.cpp.

Referenced by AVIFileSink::completeOutputFile(), and useFrame().

unsigned AVISubsessionIOState::fSTRHFrameCountPosition

Definition at line 90 of file AVIFileSink.cpp.

Referenced by AVIFileSink::completeOutputFile().


The documentation for this class was generated from the following file:
Generated on Tue Oct 7 15:39:35 2008 for live by  doxygen 1.5.2