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 59 of file AVIFileSink.cpp.


Constructor & Destructor Documentation

AVISubsessionIOState::AVISubsessionIOState ( AVIFileSink sink,
MediaSubsession subsession 
)

Definition at line 327 of file AVIFileSink.cpp.

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

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

AVISubsessionIOState::~AVISubsessionIOState (  )  [virtual]

Definition at line 342 of file AVIFileSink.cpp.

References fBuffer, and fPrevBuffer.

00342                                             {
00343   delete fBuffer; delete fPrevBuffer;
00344 }


Member Function Documentation

void AVISubsessionIOState::setAVIstate ( unsigned  subsessionIndex  ) 

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

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

void AVISubsessionIOState::setFinalAVIstate (  ) 

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

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

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

void AVISubsessionIOState::onSourceClosure (  ) 

Definition at line 484 of file AVIFileSink.cpp.

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

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

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

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

Definition at line 71 of file AVIFileSink.cpp.

References Medium::envir(), and fOurSink.

Referenced by AVIFileSink::onRTCPBye().

00071 { return fOurSink.envir(); }

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

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

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


Field Documentation

SubsessionBuffer* AVISubsessionIOState::fBuffer

Definition at line 74 of file AVIFileSink.cpp.

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

SubsessionBuffer * AVISubsessionIOState::fPrevBuffer

Definition at line 74 of file AVIFileSink.cpp.

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

AVIFileSink& AVISubsessionIOState::fOurSink

Definition at line 75 of file AVIFileSink.cpp.

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

MediaSubsession& AVISubsessionIOState::fOurSubsession

Definition at line 76 of file AVIFileSink.cpp.

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

unsigned short AVISubsessionIOState::fLastPacketRTPSeqNum

Definition at line 78 of file AVIFileSink.cpp.

Referenced by afterGettingFrame().

Boolean AVISubsessionIOState::fOurSourceIsActive

Definition at line 79 of file AVIFileSink.cpp.

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

struct timeval AVISubsessionIOState::fPrevPresentationTime [read]

Definition at line 80 of file AVIFileSink.cpp.

Referenced by AVISubsessionIOState(), and useFrame().

unsigned AVISubsessionIOState::fMaxBytesPerSecond

Definition at line 81 of file AVIFileSink.cpp.

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

Boolean AVISubsessionIOState::fIsVideo

Definition at line 82 of file AVIFileSink.cpp.

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

Boolean AVISubsessionIOState::fIsAudio

Definition at line 82 of file AVIFileSink.cpp.

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

Boolean AVISubsessionIOState::fIsByteSwappedAudio

Definition at line 82 of file AVIFileSink.cpp.

Referenced by setAVIstate(), and useFrame().

unsigned AVISubsessionIOState::fAVISubsessionTag

Definition at line 83 of file AVIFileSink.cpp.

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

unsigned AVISubsessionIOState::fAVICodecHandlerType

Definition at line 84 of file AVIFileSink.cpp.

Referenced by setAVIstate().

unsigned AVISubsessionIOState::fAVISamplingFrequency

Definition at line 85 of file AVIFileSink.cpp.

Referenced by setAVIstate().

u_int16_t AVISubsessionIOState::fWAVCodecTag

Definition at line 86 of file AVIFileSink.cpp.

Referenced by setAVIstate().

unsigned AVISubsessionIOState::fAVIScale

Definition at line 87 of file AVIFileSink.cpp.

Referenced by setAVIstate().

unsigned AVISubsessionIOState::fAVIRate

Definition at line 88 of file AVIFileSink.cpp.

Referenced by setAVIstate().

unsigned AVISubsessionIOState::fAVISize

Definition at line 89 of file AVIFileSink.cpp.

Referenced by setAVIstate().

unsigned AVISubsessionIOState::fNumFrames

Definition at line 90 of file AVIFileSink.cpp.

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

unsigned AVISubsessionIOState::fSTRHFrameCountPosition

Definition at line 91 of file AVIFileSink.cpp.

Referenced by AVIFileSink::completeOutputFile().


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