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

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

00385   : fOurSink(sink), fOurSubsession(subsession),
00386     fMaxBytesPerSecond(0), fIsVideo(False), fIsAudio(False), fIsByteSwappedAudio(False), fNumFrames(0) {
00387   fBuffer = new SubsessionBuffer(fOurSink.fBufferSize);
00388   fPrevBuffer = sink.fPacketLossCompensate
00389     ? new SubsessionBuffer(fOurSink.fBufferSize) : NULL;
00390 
00391   FramedSource* subsessionSource = subsession.readSource();
00392   fOurSourceIsActive = subsessionSource != NULL;
00393 
00394   fPrevPresentationTime.tv_sec = 0;
00395   fPrevPresentationTime.tv_usec = 0;
00396 }

AVISubsessionIOState::~AVISubsessionIOState (  )  [virtual]

Definition at line 398 of file AVIFileSink.cpp.

References fBuffer, and fPrevBuffer.

00398                                             {
00399   delete fBuffer; delete fPrevBuffer;
00400 }


Member Function Documentation

void AVISubsessionIOState::setAVIstate ( unsigned  subsessionIndex  ) 

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

00402                                                                {
00403   fIsVideo = strcmp(fOurSubsession.mediumName(), "video") == 0;
00404   fIsAudio = strcmp(fOurSubsession.mediumName(), "audio") == 0;
00405 
00406   if (fIsVideo) {
00407     fAVISubsessionTag
00408       = fourChar('0'+subsessionIndex/10,'0'+subsessionIndex%10,'d','c');
00409     if (strcmp(fOurSubsession.codecName(), "JPEG") == 0) {
00410       fAVICodecHandlerType = fourChar('m','j','p','g');
00411     } else if (strcmp(fOurSubsession.codecName(), "MP4V-ES") == 0) {
00412       fAVICodecHandlerType = fourChar('D','I','V','X');
00413     } else if (strcmp(fOurSubsession.codecName(), "MPV") == 0) {
00414       fAVICodecHandlerType = fourChar('m','p','g','1'); // what about MPEG-2?
00415     } else if (strcmp(fOurSubsession.codecName(), "H263-1998") == 0 ||
00416                strcmp(fOurSubsession.codecName(), "H263-2000") == 0) {
00417       fAVICodecHandlerType = fourChar('H','2','6','3');
00418     } else if (strcmp(fOurSubsession.codecName(), "H264") == 0) {
00419       fAVICodecHandlerType = fourChar('H','2','6','4');
00420     } else {
00421       fAVICodecHandlerType = fourChar('?','?','?','?');
00422     }
00423     fAVIScale = 1; // ??? #####
00424     fAVIRate = fOurSink.fMovieFPS; // ??? #####
00425     fAVISize = fOurSink.fMovieWidth*fOurSink.fMovieHeight*3; // ??? #####
00426   } else if (fIsAudio) {
00427     fIsByteSwappedAudio = False; // by default
00428     fAVISubsessionTag
00429       = fourChar('0'+subsessionIndex/10,'0'+subsessionIndex%10,'w','b');
00430     fAVICodecHandlerType = 1; // ??? ####
00431     unsigned numChannels = fOurSubsession.numChannels();
00432     fAVISamplingFrequency = fOurSubsession.rtpTimestampFrequency(); // default
00433     if (strcmp(fOurSubsession.codecName(), "L16") == 0) {
00434       fIsByteSwappedAudio = True; // need to byte-swap data before writing it
00435       fWAVCodecTag = 0x0001;
00436       fAVIScale = fAVISize = 2*numChannels; // 2 bytes/sample
00437       fAVIRate = fAVISize*fAVISamplingFrequency;
00438     } else if (strcmp(fOurSubsession.codecName(), "L8") == 0) {
00439       fWAVCodecTag = 0x0001;
00440       fAVIScale = fAVISize = numChannels; // 1 byte/sample
00441       fAVIRate = fAVISize*fAVISamplingFrequency;
00442     } else if (strcmp(fOurSubsession.codecName(), "PCMA") == 0) {
00443       fWAVCodecTag = 0x0006;
00444       fAVIScale = fAVISize = numChannels; // 1 byte/sample
00445       fAVIRate = fAVISize*fAVISamplingFrequency;
00446     } else if (strcmp(fOurSubsession.codecName(), "PCMU") == 0) {
00447       fWAVCodecTag = 0x0007;
00448       fAVIScale = fAVISize = numChannels; // 1 byte/sample
00449       fAVIRate = fAVISize*fAVISamplingFrequency;
00450     } else if (strcmp(fOurSubsession.codecName(), "MPA") == 0) {
00451       fWAVCodecTag = 0x0050;
00452       fAVIScale = fAVISize = 1;
00453       fAVIRate = 0; // ??? #####
00454     } else {
00455       fWAVCodecTag = 0x0001; // ??? #####
00456       fAVIScale = fAVISize = 1;
00457       fAVIRate = 0; // ??? #####
00458     }
00459   } else { // unknown medium
00460     fAVISubsessionTag
00461       = fourChar('0'+subsessionIndex/10,'0'+subsessionIndex%10,'?','?');
00462     fAVICodecHandlerType = 0;
00463     fAVIScale = fAVISize = 1;
00464     fAVIRate = 0; // ??? #####
00465   }
00466 }

void AVISubsessionIOState::setFinalAVIstate (  ) 

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

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

00469                                                                            {
00470   // Begin by checking whether there was a gap in the RTP stream.
00471   // If so, try to compensate for this (if desired):
00472   unsigned short rtpSeqNum
00473     = fOurSubsession.rtpSource()->curPacketRTPSeqNum();
00474   if (fOurSink.fPacketLossCompensate && fPrevBuffer->bytesInUse() > 0) {
00475     short seqNumGap = rtpSeqNum - fLastPacketRTPSeqNum;
00476     for (short i = 1; i < seqNumGap; ++i) {
00477       // Insert a copy of the previous frame, to compensate for the loss:
00478       useFrame(*fPrevBuffer);
00479     }
00480   }
00481   fLastPacketRTPSeqNum = rtpSeqNum;
00482 
00483   // Now, continue working with the frame that we just got
00484   if (fBuffer->bytesInUse() == 0) {
00485     fBuffer->setPresentationTime(presentationTime);
00486   }
00487   fBuffer->addBytes(packetDataSize);
00488 
00489   useFrame(*fBuffer);
00490   if (fOurSink.fPacketLossCompensate) {
00491     // Save this frame, in case we need it for recovery:
00492     SubsessionBuffer* tmp = fPrevBuffer; // assert: != NULL
00493     fPrevBuffer = fBuffer;
00494     fBuffer = tmp;
00495   }
00496   fBuffer->reset(); // for the next input
00497 
00498   // Now, try getting more frames:
00499   fOurSink.continuePlaying();
00500 }

void AVISubsessionIOState::onSourceClosure (  ) 

Definition at line 554 of file AVIFileSink.cpp.

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

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

00554                                            {
00555   fOurSourceIsActive = False;
00556   fOurSink.onSourceClosure1();
00557 }

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

References AVIFileSink::addByte(), AVIFileSink::addIndexRecord(), AVIFileSink::addWord(), SubsessionBuffer::bytesInUse(), MediaSubsession::codecName(), SubsessionBuffer::dataStart(), fAVISubsessionTag, fIsByteSwappedAudio, fMaxBytesPerSecond, AVIFileSink::fMoviSizePosition, AVIFileSink::fNumBytesWritten, fNumFrames, fourChar, fOurSink, fOurSubsession, AVIFileSink::fOutFid, fPrevPresentationTime, frameSize, and SubsessionBuffer::presentationTime().

Referenced by afterGettingFrame().

00502                                                             {
00503   unsigned char* const frameSource = buffer.dataStart();
00504   unsigned const frameSize = buffer.bytesInUse();
00505   struct timeval const& presentationTime = buffer.presentationTime();
00506   if (fPrevPresentationTime.tv_usec != 0||fPrevPresentationTime.tv_sec != 0) {
00507     int uSecondsDiff
00508       = (presentationTime.tv_sec - fPrevPresentationTime.tv_sec)*1000000
00509       + (presentationTime.tv_usec - fPrevPresentationTime.tv_usec);
00510     if (uSecondsDiff > 0) {
00511       unsigned bytesPerSecond = (unsigned)((frameSize*1000000.0)/uSecondsDiff);
00512       if (bytesPerSecond > fMaxBytesPerSecond) {
00513         fMaxBytesPerSecond = bytesPerSecond;
00514       }
00515     }
00516   }
00517   fPrevPresentationTime = presentationTime;
00518 
00519   if (fIsByteSwappedAudio) {
00520     // We need to swap the 16-bit audio samples from big-endian
00521     // to little-endian order, before writing them to a file:
00522     for (unsigned i = 0; i < frameSize; i += 2) {
00523       unsigned char tmp = frameSource[i];
00524       frameSource[i] = frameSource[i+1];
00525       frameSource[i+1] = tmp;
00526     }
00527   }
00528 
00529   // Add an index record for this frame:
00530   AVIIndexRecord* newIndexRecord
00531     = new AVIIndexRecord(fAVISubsessionTag, // chunk id
00532                          frameSource[0] == 0x67 ? 0x10 : 0, // flags
00533                          fOurSink.fMoviSizePosition + 8 + fOurSink.fNumBytesWritten, // offset (note: 8 == size + 'movi')
00534                          frameSize + 4); // size
00535   fOurSink.addIndexRecord(newIndexRecord);
00536 
00537   // Write the data into the file:
00538   fOurSink.fNumBytesWritten += fOurSink.addWord(fAVISubsessionTag);
00539   if (strcmp(fOurSubsession.codecName(), "H264") == 0) {
00540     // Insert a 'start code' (0x00 0x00 0x00 0x01) in front of the frame:
00541     fOurSink.fNumBytesWritten += fOurSink.addWord(4+frameSize);
00542     fOurSink.fNumBytesWritten += fOurSink.addWord(fourChar(0x00, 0x00, 0x00, 0x01));//add start code
00543   } else {
00544     fOurSink.fNumBytesWritten += fOurSink.addWord(frameSize);
00545   }
00546   fwrite(frameSource, 1, frameSize, fOurSink.fOutFid);
00547   fOurSink.fNumBytesWritten += frameSize;
00548   // Pad to an even length:
00549   if (frameSize%2 != 0) fOurSink.fNumBytesWritten += fOurSink.addByte(0);
00550 
00551   ++fNumFrames;
00552 }


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(), setAVIstate(), and useFrame().

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 Tue Jun 18 13:20:07 2013 for live by  doxygen 1.5.2