00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "MPEGVideoStreamParser.hh"
00023 #include <GroupsockHelper.hh>
00024
00026
00027 TimeCode::TimeCode()
00028 : days(0), hours(0), minutes(0), seconds(0), pictures(0) {
00029 }
00030
00031 TimeCode::~TimeCode() {
00032 }
00033
00034 int TimeCode::operator==(TimeCode const& arg2) {
00035 return pictures == arg2.pictures && seconds == arg2.seconds
00036 && minutes == arg2.minutes && hours == arg2.hours && days == arg2.days;
00037 }
00038
00040
00041 MPEGVideoStreamFramer::MPEGVideoStreamFramer(UsageEnvironment& env,
00042 FramedSource* inputSource)
00043 : FramedFilter(env, inputSource),
00044 fFrameRate(0.0) ,
00045 fParser(NULL) {
00046 reset();
00047 }
00048
00049 MPEGVideoStreamFramer::~MPEGVideoStreamFramer() {
00050 delete fParser;
00051 }
00052
00053 void MPEGVideoStreamFramer::flushInput() {
00054 reset();
00055 if (fParser != NULL) fParser->flushInput();
00056 }
00057
00058 void MPEGVideoStreamFramer::reset() {
00059 fPictureCount = 0;
00060 fPictureEndMarker = False;
00061 fPicturesAdjustment = 0;
00062 fPictureTimeBase = 0.0;
00063 fTcSecsBase = 0;
00064 fHaveSeenFirstTimeCode = False;
00065
00066
00067 gettimeofday(&fPresentationTimeBase, NULL);
00068 }
00069
00070 #ifdef DEBUG
00071 static struct timeval firstPT;
00072 #endif
00073 void MPEGVideoStreamFramer
00074 ::computePresentationTime(unsigned numAdditionalPictures) {
00075
00076
00077 TimeCode& tc = fCurGOPTimeCode;
00078
00079 unsigned tcSecs
00080 = (((tc.days*24)+tc.hours)*60+tc.minutes)*60+tc.seconds - fTcSecsBase;
00081 double pictureTime = fFrameRate == 0.0 ? 0.0
00082 : (tc.pictures + fPicturesAdjustment + numAdditionalPictures)/fFrameRate;
00083 while (pictureTime < fPictureTimeBase) {
00084 if (tcSecs > 0) tcSecs -= 1;
00085 pictureTime += 1.0;
00086 }
00087 pictureTime -= fPictureTimeBase;
00088 if (pictureTime < 0.0) pictureTime = 0.0;
00089 unsigned pictureSeconds = (unsigned)pictureTime;
00090 double pictureFractionOfSecond = pictureTime - (double)pictureSeconds;
00091
00092 fPresentationTime = fPresentationTimeBase;
00093 fPresentationTime.tv_sec += tcSecs + pictureSeconds;
00094 fPresentationTime.tv_usec += (long)(pictureFractionOfSecond*1000000.0);
00095 if (fPresentationTime.tv_usec >= 1000000) {
00096 fPresentationTime.tv_usec -= 1000000;
00097 ++fPresentationTime.tv_sec;
00098 }
00099 #ifdef DEBUG
00100 if (firstPT.tv_sec == 0 && firstPT.tv_usec == 0) firstPT = fPresentationTime;
00101 struct timeval diffPT;
00102 diffPT.tv_sec = fPresentationTime.tv_sec - firstPT.tv_sec;
00103 diffPT.tv_usec = fPresentationTime.tv_usec - firstPT.tv_usec;
00104 if (fPresentationTime.tv_usec < firstPT.tv_usec) {
00105 --diffPT.tv_sec;
00106 diffPT.tv_usec += 1000000;
00107 }
00108 fprintf(stderr, "MPEGVideoStreamFramer::computePresentationTime(%d) -> %lu.%06ld [%lu.%06ld]\n", numAdditionalPictures, fPresentationTime.tv_sec, fPresentationTime.tv_usec, diffPT.tv_sec, diffPT.tv_usec);
00109 #endif
00110 }
00111
00112 void MPEGVideoStreamFramer
00113 ::setTimeCode(unsigned hours, unsigned minutes, unsigned seconds,
00114 unsigned pictures, unsigned picturesSinceLastGOP) {
00115 TimeCode& tc = fCurGOPTimeCode;
00116 unsigned days = tc.days;
00117 if (hours < tc.hours) {
00118
00119 ++days;
00120 }
00121 tc.days = days;
00122 tc.hours = hours;
00123 tc.minutes = minutes;
00124 tc.seconds = seconds;
00125 tc.pictures = pictures;
00126 if (!fHaveSeenFirstTimeCode) {
00127 fPictureTimeBase = fFrameRate == 0.0 ? 0.0 : tc.pictures/fFrameRate;
00128 fTcSecsBase = (((tc.days*24)+tc.hours)*60+tc.minutes)*60+tc.seconds;
00129 fHaveSeenFirstTimeCode = True;
00130 } else if (fCurGOPTimeCode == fPrevGOPTimeCode) {
00131
00132 fPicturesAdjustment += picturesSinceLastGOP;
00133 } else {
00134
00135 fPrevGOPTimeCode = tc;
00136 fPicturesAdjustment = 0;
00137 }
00138 }
00139
00140 void MPEGVideoStreamFramer::doGetNextFrame() {
00141 fParser->registerReadInterest(fTo, fMaxSize);
00142 continueReadProcessing();
00143 }
00144
00145 void MPEGVideoStreamFramer
00146 ::continueReadProcessing(void* clientData,
00147 unsigned char* , unsigned ,
00148 struct timeval ) {
00149 MPEGVideoStreamFramer* framer = (MPEGVideoStreamFramer*)clientData;
00150 framer->continueReadProcessing();
00151 }
00152
00153 void MPEGVideoStreamFramer::continueReadProcessing() {
00154 unsigned acquiredFrameSize = fParser->parse();
00155 if (acquiredFrameSize > 0) {
00156
00157
00158 fFrameSize = acquiredFrameSize;
00159 fNumTruncatedBytes = fParser->numTruncatedBytes();
00160
00161
00162
00163
00164 fDurationInMicroseconds
00165 = (fFrameRate == 0.0 || ((int)fPictureCount) < 0) ? 0
00166 : (unsigned)((fPictureCount*1000000)/fFrameRate);
00167 #ifdef DEBUG
00168 fprintf(stderr, "fDurationInMicroseconds: %d ((%d*1000000)/%f)\n", fDurationInMicroseconds, fPictureCount, fFrameRate);
00169 #endif
00170 fPictureCount = 0;
00171
00172
00173
00174 afterGetting(this);
00175 } else {
00176
00177
00178
00179 }
00180 }