00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "MPEG4VideoStreamDiscreteFramer.hh"
00025
00026 MPEG4VideoStreamDiscreteFramer*
00027 MPEG4VideoStreamDiscreteFramer::createNew(UsageEnvironment& env,
00028 FramedSource* inputSource) {
00029
00030 return new MPEG4VideoStreamDiscreteFramer(env, inputSource);
00031 }
00032
00033 MPEG4VideoStreamDiscreteFramer
00034 ::MPEG4VideoStreamDiscreteFramer(UsageEnvironment& env,
00035 FramedSource* inputSource)
00036 : MPEG4VideoStreamFramer(env, inputSource, False),
00037 vop_time_increment_resolution(0), fNumVTIRBits(0),
00038 fLastNonBFrameVop_time_increment(0) {
00039 fLastNonBFramePresentationTime.tv_sec = 0;
00040 fLastNonBFramePresentationTime.tv_usec = 0;
00041 }
00042
00043 MPEG4VideoStreamDiscreteFramer::~MPEG4VideoStreamDiscreteFramer() {
00044 }
00045
00046 void MPEG4VideoStreamDiscreteFramer::doGetNextFrame() {
00047
00048
00049
00050 fInputSource->getNextFrame(fTo, fMaxSize,
00051 afterGettingFrame, this,
00052 FramedSource::handleClosure, this);
00053 }
00054
00055 void MPEG4VideoStreamDiscreteFramer
00056 ::afterGettingFrame(void* clientData, unsigned frameSize,
00057 unsigned numTruncatedBytes,
00058 struct timeval presentationTime,
00059 unsigned durationInMicroseconds) {
00060 MPEG4VideoStreamDiscreteFramer* source = (MPEG4VideoStreamDiscreteFramer*)clientData;
00061 source->afterGettingFrame1(frameSize, numTruncatedBytes,
00062 presentationTime, durationInMicroseconds);
00063 }
00064
00065 void MPEG4VideoStreamDiscreteFramer
00066 ::afterGettingFrame1(unsigned frameSize, unsigned numTruncatedBytes,
00067 struct timeval presentationTime,
00068 unsigned durationInMicroseconds) {
00069
00070 if (frameSize >= 4 && fTo[0] == 0 && fTo[1] == 0 && fTo[2] == 1) {
00071 fPictureEndMarker = True;
00072 unsigned i = 3;
00073 if (fTo[i] == 0xB0) {
00074
00075 if (frameSize >= 5) fProfileAndLevelIndication = fTo[4];
00076
00077
00078
00079 for (i = 7; i < frameSize; ++i) {
00080 if ((fTo[i] == 0xB3 ||
00081 fTo[i] == 0xB6 )
00082 && fTo[i-1] == 1 && fTo[i-2] == 0 && fTo[i-3] == 0) {
00083 break;
00084 }
00085 }
00086 fNumConfigBytes = i-3;
00087 delete[] fConfigBytes; fConfigBytes = new unsigned char[fNumConfigBytes];
00088 for (unsigned j = 0; j < fNumConfigBytes; ++j) fConfigBytes[j] = fTo[j];
00089
00090
00091
00092
00093
00094 analyzeVOLHeader();
00095 }
00096
00097 if (i < frameSize) {
00098 u_int8_t nextCode = fTo[i];
00099
00100 if (nextCode == 0xB3 ) {
00101
00102 for (i += 4; i < frameSize; ++i) {
00103 if (fTo[i] == 0xB6
00104 && fTo[i-1] == 1 && fTo[i-2] == 0 && fTo[i-3] == 0) {
00105 nextCode = fTo[i];
00106 break;
00107 }
00108 }
00109 }
00110
00111 if (nextCode == 0xB6 && i+5 < frameSize) {
00112 ++i;
00113
00114
00115 u_int8_t nextByte = fTo[i++];
00116 u_int8_t vop_coding_type = nextByte>>6;
00117
00118
00119
00120
00121 u_int32_t next4Bytes
00122 = (fTo[i]<<24)|(fTo[i+1]<<16)|(fTo[i+2]<<8)|fTo[i+3];
00123 i += 4;
00124 u_int32_t timeInfo = (nextByte<<(32-6))|(next4Bytes>>6);
00125 unsigned modulo_time_base = 0;
00126 u_int32_t mask = 0x80000000;
00127 while ((timeInfo&mask) != 0) {
00128 ++modulo_time_base;
00129 mask >>= 1;
00130 }
00131 mask >>= 2;
00132
00133
00134 unsigned vop_time_increment = 0;
00135
00136 if ((mask>>(fNumVTIRBits-1)) != 0) {
00137 for (unsigned i = 0; i < fNumVTIRBits; ++i) {
00138 vop_time_increment |= timeInfo&mask;
00139 mask >>= 1;
00140 }
00141 while (mask != 0) {
00142 vop_time_increment >>= 1;
00143 mask >>= 1;
00144 }
00145 }
00146
00147
00148 if (vop_coding_type == 2
00149 && (fLastNonBFramePresentationTime.tv_usec > 0 ||
00150 fLastNonBFramePresentationTime.tv_sec > 0)) {
00151 int timeIncrement
00152 = fLastNonBFrameVop_time_increment - vop_time_increment;
00153 if (timeIncrement<0) timeIncrement += vop_time_increment_resolution;
00154 unsigned const MILLION = 1000000;
00155 double usIncrement = vop_time_increment_resolution == 0 ? 0.0
00156 : ((double)timeIncrement*MILLION)/vop_time_increment_resolution;
00157 unsigned secondsToSubtract = (unsigned)(usIncrement/MILLION);
00158 unsigned uSecondsToSubtract = ((unsigned)usIncrement)%MILLION;
00159
00160 presentationTime = fLastNonBFramePresentationTime;
00161 if ((unsigned)presentationTime.tv_usec < uSecondsToSubtract) {
00162 presentationTime.tv_usec += MILLION;
00163 if (presentationTime.tv_sec > 0) --presentationTime.tv_sec;
00164 }
00165 presentationTime.tv_usec -= uSecondsToSubtract;
00166 if ((unsigned)presentationTime.tv_sec > secondsToSubtract) {
00167 presentationTime.tv_sec -= secondsToSubtract;
00168 } else {
00169 presentationTime.tv_sec = presentationTime.tv_usec = 0;
00170 }
00171 } else {
00172 fLastNonBFramePresentationTime = presentationTime;
00173 fLastNonBFrameVop_time_increment = vop_time_increment;
00174 }
00175 }
00176 }
00177 }
00178
00179
00180 fFrameSize = frameSize;
00181 fNumTruncatedBytes = numTruncatedBytes;
00182 fPresentationTime = presentationTime;
00183 fDurationInMicroseconds = durationInMicroseconds;
00184 afterGetting(this);
00185 }
00186
00187 Boolean MPEG4VideoStreamDiscreteFramer::getNextFrameBit(u_int8_t& result) {
00188 if (fNumBitsSeenSoFar/8 >= fNumConfigBytes) return False;
00189
00190 u_int8_t nextByte = fConfigBytes[fNumBitsSeenSoFar/8];
00191 result = (nextByte>>(7-fNumBitsSeenSoFar%8))&1;
00192 ++fNumBitsSeenSoFar;
00193 return True;
00194 }
00195
00196 Boolean MPEG4VideoStreamDiscreteFramer::getNextFrameBits(unsigned numBits,
00197 u_int32_t& result) {
00198 result = 0;
00199 for (unsigned i = 0; i < numBits; ++i) {
00200 u_int8_t nextBit;
00201 if (!getNextFrameBit(nextBit)) return False;
00202 result = (result<<1)|nextBit;
00203 }
00204 return True;
00205 }
00206
00207 void MPEG4VideoStreamDiscreteFramer::analyzeVOLHeader() {
00208
00209 unsigned i;
00210 for (i = 3; i < fNumConfigBytes; ++i) {
00211 if (fConfigBytes[i] >= 0x20 && fConfigBytes[i] <= 0x2F
00212 && fConfigBytes[i-1] == 1
00213 && fConfigBytes[i-2] == 0 && fConfigBytes[i-3] == 0) {
00214 ++i;
00215 break;
00216 }
00217 }
00218
00219 fNumBitsSeenSoFar = 8*i + 9;
00220 do {
00221 u_int8_t is_object_layer_identifier;
00222 if (!getNextFrameBit(is_object_layer_identifier)) break;
00223 if (is_object_layer_identifier) fNumBitsSeenSoFar += 7;
00224
00225 u_int32_t aspect_ratio_info;
00226 if (!getNextFrameBits(4, aspect_ratio_info)) break;
00227 if (aspect_ratio_info == 15 ) fNumBitsSeenSoFar += 16;
00228
00229 u_int8_t vol_control_parameters;
00230 if (!getNextFrameBit(vol_control_parameters)) break;
00231 if (vol_control_parameters) {
00232 fNumBitsSeenSoFar += 3;
00233 u_int8_t vbw_parameters;
00234 if (!getNextFrameBit(vbw_parameters)) break;
00235 if (vbw_parameters) fNumBitsSeenSoFar += 79;
00236 }
00237
00238 fNumBitsSeenSoFar += 2;
00239 u_int8_t marker_bit;
00240 if (!getNextFrameBit(marker_bit)) break;
00241 if (marker_bit != 1) break;
00242
00243 if (!getNextFrameBits(16, vop_time_increment_resolution)) break;
00244 if (vop_time_increment_resolution == 0) break;
00245
00246
00247 fNumVTIRBits = 0;
00248 for (unsigned test = vop_time_increment_resolution; test>0; test /= 2) {
00249 ++fNumVTIRBits;
00250 }
00251 } while (0);
00252 }