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

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

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

AVISubsessionIOState::~AVISubsessionIOState (  )  [virtual]

Definition at line 347 of file AVIFileSink.cpp.

References fBuffer, and fPrevBuffer.

00347                                             {
00348   delete fBuffer; delete fPrevBuffer;
00349 }


Member Function Documentation

void AVISubsessionIOState::setAVIstate ( unsigned  subsessionIndex  ) 

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

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

void AVISubsessionIOState::setFinalAVIstate (  ) 

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

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

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

void AVISubsessionIOState::onSourceClosure (  ) 

Definition at line 489 of file AVIFileSink.cpp.

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

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

00489                                            {
00490   fOurSourceIsActive = False;
00491   fOurSink.onSourceClosure1();
00492 }

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

Definition at line 71 of file AVIFileSink.cpp.

References Medium::envir(), and fOurSink.

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

00071 { return fOurSink.envir(); }

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

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

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


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