
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 () |
| UsageEnvironment & | envir () const |
Data Fields | |
| SubsessionBuffer * | fBuffer |
| SubsessionBuffer * | fPrevBuffer |
| AVIFileSink & | fOurSink |
| MediaSubsession & | fOurSubsession |
| 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) |
Definition at line 58 of file AVIFileSink.cpp.
| 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 }
| 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().
| 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 }
Definition at line 73 of file AVIFileSink.cpp.
Referenced by afterGettingFrame(), AVISubsessionIOState(), AVIFileSink::continuePlaying(), and ~AVISubsessionIOState().
Definition at line 73 of file AVIFileSink.cpp.
Referenced by afterGettingFrame(), AVISubsessionIOState(), and ~AVISubsessionIOState().
Definition at line 74 of file AVIFileSink.cpp.
Referenced by afterGettingFrame(), AVISubsessionIOState(), envir(), AVIFileSink::onRTCPBye(), onSourceClosure(), setAVIstate(), and useFrame().
Definition at line 75 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 AVISubsessionIOState(), onSourceClosure(), and AVIFileSink::onSourceClosure1().
struct timeval AVISubsessionIOState::fPrevPresentationTime [read] |
Definition at line 79 of file AVIFileSink.cpp.
Referenced by AVISubsessionIOState(), and useFrame().
Definition at line 80 of file AVIFileSink.cpp.
Referenced by AVIFileSink::completeOutputFile(), and useFrame().
Definition at line 81 of file AVIFileSink.cpp.
Referenced by AVIFileSink::completeOutputFile(), and setAVIstate().
Definition at line 81 of file AVIFileSink.cpp.
Referenced by AVIFileSink::completeOutputFile(), and setAVIstate().
| u_int16_t AVISubsessionIOState::fWAVCodecTag |
| unsigned AVISubsessionIOState::fAVIScale |
| unsigned AVISubsessionIOState::fAVIRate |
| unsigned AVISubsessionIOState::fAVISize |
| unsigned AVISubsessionIOState::fNumFrames |
Definition at line 89 of file AVIFileSink.cpp.
Referenced by AVIFileSink::completeOutputFile(), and useFrame().
1.5.2