00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _AVI_FILE_SINK_HH
00022 #define _AVI_FILE_SINK_HH
00023
00024 #ifndef _MEDIA_SESSION_HH
00025 #include "MediaSession.hh"
00026 #endif
00027
00028 class AVIFileSink: public Medium {
00029 public:
00030 static AVIFileSink* createNew(UsageEnvironment& env,
00031 MediaSession& inputSession,
00032 char const* outputFileName,
00033 unsigned bufferSize = 20000,
00034 unsigned short movieWidth = 240,
00035 unsigned short movieHeight = 180,
00036 unsigned movieFPS = 15,
00037 Boolean packetLossCompensate = False);
00038
00039 typedef void (afterPlayingFunc)(void* clientData);
00040 Boolean startPlaying(afterPlayingFunc* afterFunc,
00041 void* afterClientData);
00042
00043 unsigned numActiveSubsessions() const { return fNumSubsessions; }
00044
00045 private:
00046 AVIFileSink(UsageEnvironment& env, MediaSession& inputSession,
00047 char const* outputFileName, unsigned bufferSize,
00048 unsigned short movieWidth, unsigned short movieHeight,
00049 unsigned movieFPS, Boolean packetLossCompensate);
00050
00051 virtual ~AVIFileSink();
00052
00053 Boolean continuePlaying();
00054 static void afterGettingFrame(void* clientData, unsigned frameSize,
00055 unsigned numTruncatedBytes,
00056 struct timeval presentationTime,
00057 unsigned durationInMicroseconds);
00058 static void onSourceClosure(void* clientData);
00059 void onSourceClosure1();
00060 static void onRTCPBye(void* clientData);
00061 void addIndexRecord(class AVIIndexRecord* newIndexRecord);
00062 void completeOutputFile();
00063
00064 private:
00065 friend class AVISubsessionIOState;
00066 MediaSession& fInputSession;
00067 FILE* fOutFid;
00068 class AVIIndexRecord *fIndexRecordsHead, *fIndexRecordsTail;
00069 unsigned fNumIndexRecords;
00070 unsigned fBufferSize;
00071 Boolean fPacketLossCompensate;
00072 Boolean fAreCurrentlyBeingPlayed;
00073 afterPlayingFunc* fAfterFunc;
00074 void* fAfterClientData;
00075 unsigned fNumSubsessions;
00076 unsigned fNumBytesWritten;
00077 struct timeval fStartTime;
00078 Boolean fHaveCompletedOutputFile;
00079
00080 private:
00082
00083 unsigned addWord(unsigned word);
00084 unsigned addHalfWord(unsigned short halfWord);
00085 unsigned addByte(unsigned char byte) {
00086 putc(byte, fOutFid);
00087 return 1;
00088 }
00089 unsigned addZeroWords(unsigned numWords);
00090 unsigned add4ByteString(char const* str);
00091 void setWord(unsigned filePosn, unsigned size);
00092
00093
00094 #define _header(name) unsigned addFileHeader_##name()
00095 _header(AVI);
00096 _header(hdrl);
00097 _header(avih);
00098 _header(strl);
00099 _header(strh);
00100 _header(strf);
00101 _header(JUNK);
00102
00103 _header(movi);
00104 private:
00105 unsigned short fMovieWidth, fMovieHeight;
00106 unsigned fMovieFPS;
00107 unsigned fRIFFSizePosition, fRIFFSizeValue;
00108 unsigned fAVIHMaxBytesPerSecondPosition;
00109 unsigned fAVIHFrameCountPosition;
00110 unsigned fMoviSizePosition, fMoviSizeValue;
00111 class AVISubsessionIOState* fCurrentIOState;
00112 unsigned fJunkNumber;
00113 };
00114
00115 #endif