00001 #include "MPGStream.hpp"
00002
00003 MPGStream::~MPGStream() {
00004 file.close();
00005 }
00006
00007
00008 MPGStream::MPGStream(const QString & fname, bool preRead,
00009 uint numFrames):Stream(fname, preRead) {
00010
00011
00012 file.setName(fname);
00013 if (!file.open(IO_ReadOnly)) {
00014 cerr << "Can't open " << fname.ascii() << "!\n\n";
00015 exit(ERR_FILE);
00016 }
00017 #if MYDEBUG >= 4
00018 printf("MPGStream Constructor: opening \"%s\" as input file (%li bytes)\n",
00019 fname.data(), file.size());
00020 #endif
00021
00022
00023 if (!file.at(0)) {
00024 cerr << "can't go to file position 0!";
00025 exit(-1);
00026 }
00027 fileSize = file.size();
00028
00029 gopList.setAutoDelete(TRUE);
00030 noFrames = 0;
00031 lastReadFrame = NULL;
00032 lastRefFrame = NULL;
00033
00034
00035 parseHeader();
00036
00037
00038 if (preRead)
00039 while (addNextGOP(numFrames) != NULL);
00040 }
00041
00042
00043 void MPGStream::parseHeader() {
00044 int ch;
00045 uint code = 0;
00046
00047 do {
00048 ch = file.getch();
00049 code = (code << 8) | ch;
00050 } while ((ch != EOF) && (code != VOP_START_CODE));
00051
00052 #if MYDEBUG >= 4
00053 printf("[%i:0x%x] ", ch, code);
00054 printf("getHeader finished at file pos %li\n", file.at());
00055 #endif
00056
00057 this->headerSize = file.at();
00058 }
00059
00060
00061
00062 bool MPGStream::fillHeaderBuffer() {
00063
00064 if (!file.at(0)) {
00065 return false;
00066 }
00067
00068 if (!headerBuffer.resize(headerSize)) {
00069 #if MYDEBUG >= 1
00070 cout << "Can't resize the buffer to " << headerSize << " bytes!\n";
00071 #endif
00072 return false;
00073 }
00074
00075 if (!file.readBlock(headerBuffer.data(), headerSize)) {
00076 #if MYDEBUG >= 1
00077 cout << "Can't read " << headerSize << " bytes from stream!\n";
00078 #endif
00079 }
00080 return true;
00081 }
00082
00083
00084 MPGFrame *MPGStream::getNextFrame() {
00085 int ch;
00086 uint code = 0;
00087 MPGFrame *frame;
00088 uint frsize = 4;
00089 uint frOffset;
00090 FrameType type = NN_VOP;
00091
00092 if (file.atEnd())
00093 return NULL;
00094
00095 frOffset = file.at() - 4;
00096
00097 do {
00098 ch = file.getch();
00099 if (frsize == 4) {
00100 type = (FrameType) (ch >> 6);
00101 if (type != 0 && type != 1 && type != 2)
00102 wmsg(0, "Frame: " << noFrames << ", FrameType: " << type);
00103 }
00104 code = (code << 8) | ch;
00105 frsize++;
00106 } while (ch != EOF && code != VOP_START_CODE);
00107
00108 frame = new MPGFrame(type, frsize);
00109 frame->setFileOffset(frOffset);
00110 frame->setByteSize(frsize);
00111 frame->setNoInStream(noFrames);
00112
00113 #if MYDEBUG >= 4
00114 printf("getNextFrame %i (%i,0x%x) from file pos %9li (of %li)",
00115 noFrames, ch, code, file.at(), fileSize);
00116 printf("[%s%9i]\n",
00117 (type == I_VOP) ? "I" : (type == P_VOP) ? "P" : (type ==
00118 B_VOP) ? "B" :
00119 "U", frsize);
00120 #endif
00121
00122 #if MYDEBUG == 3
00123 printf("%s",
00124 (type == I_VOP) ? "I" : (type == P_VOP) ? "P" : (type ==
00125 B_VOP) ? "B" :
00126 "U");
00127 #endif
00128
00129 lastReadFrame = frame;
00130 noFrames++;
00131 return frame;
00132 }
00133
00134
00135 GOP *MPGStream::addNextGOP(uint numFrames) {
00136 MPGGOP *p;
00137 MPGFrame *frame;
00138 bool frameAligned;
00139 uint dispNoFrames;
00140
00141 if ((p = (MPGGOP *) gopList.last()) != NULL) {
00142 frame = (MPGFrame *) p->getFrame(p->getFrameCount() - 1);
00143 ASSERT(frame != NULL);
00144 dispNoFrames = frame->getNoInDisplay() + 1;
00145 } else
00146 dispNoFrames = 0;
00147
00148 frameAligned = (numFrames != 0);
00149
00150 #if MYDEBUG >= 4
00151 printf("MPGaddNextGOP from file pos %ld ", file.at());
00152 if (numFrames == 0)
00153 printf("\n");
00154 else
00155 printf("maxFrames: %i)\n", numFrames);
00156 #endif
00157
00158 if (file.atEnd())
00159 return NULL;
00160
00161 p = new MPGGOP(this, gopList.count());
00162
00163
00164 if (!frameAligned) {
00165 if (lastReadFrame != NULL) {
00166 lastReadFrame->setNoInGOP(p->getFrameCount());
00167 lastReadFrame->setNoInDisplay(dispNoFrames++);
00168 lastReadFrame->setGOP(p);
00169 p->addFrame(lastReadFrame);
00170 }
00171
00172 while ((frame = getNextFrame()) != NULL) {
00173 if ((noFrames > 1) && (frame->getType() == I_VOP)) {
00174 break;
00175 }
00176 if (frame->getType() == B_VOP) {
00177 frame->setNoInGOP(p->getFrameCount());
00178 frame->setNoInDisplay(dispNoFrames++);
00179 frame->setGOP(p);
00180 p->incNoBVOPs();
00181
00182 p->addFrame(frame);
00183 }
00184 else {
00185 if (lastRefFrame != NULL) {
00186 lastRefFrame->setNoInGOP(p->getFrameCount());
00187 lastReadFrame->setNoInDisplay(dispNoFrames++);
00188 lastReadFrame->setGOP(p);
00189 p->addFrame(lastRefFrame);
00190 }
00191 lastRefFrame = frame;
00192 }
00193 }
00194 }
00195
00196
00197 else {
00198 while ((frame = getNextFrame()) != NULL) {
00199 if (frame->getType() == B_VOP) {
00200 frame->setNoInGOP(p->getFrameCount());
00201 frame->setNoInDisplay(dispNoFrames++);
00202 frame->setGOP(p);
00203 p->incNoBVOPs();
00204
00205 p->addFrame(frame);
00206
00207 if (--numFrames == 0)
00208 break;
00209 }
00210 else {
00211 if (lastRefFrame != NULL) {
00212 lastRefFrame->setNoInGOP(p->getFrameCount());
00213 lastRefFrame->setNoInDisplay(dispNoFrames++);
00214 lastRefFrame->setGOP(p);
00215 p->addFrame(lastRefFrame);
00216 if (--numFrames == 0)
00217 break;
00218 }
00219 lastRefFrame = frame;
00220 }
00221 }
00222 }
00223
00224
00225 #if MYDEBUG >= 3
00226 cout << " (" << gopList.count() << "|" << p->getFrameCount() << ")" << nl;
00227 #endif
00228 p->calcByteSize();
00229 gopList.append(p);
00230
00231 return p;
00232 }
00233
00234
00235 long MPGStream::getFileSize() {
00236 return fileSize;
00237 }
00238
00239
00240 long MPGStream::getAvgFrameSize() {
00241 return fileSize / noFrames;
00242 }
00243
00244
00245 long MPGStream::getAvgGOPSize() {
00246 return fileSize / gopList.count();
00247 }
00248
00249
00250 uint MPGStream::getHeaderSize() {
00251 return headerSize;
00252 }
00253
00254 char* MPGStream::getHeaderBuffer() {
00255 return headerBuffer.data();
00256 }