Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

MPGStream.cpp

Go to the documentation of this file.
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     // open the file
00012     file.setName(fname);
00013     if (!file.open(IO_ReadOnly)) {
00014                 cerr << "Can't open " << fname.ascii() << "!\n\n";
00015                 exit(ERR_FILE);         // use exception here l8er
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     // set file to start position
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     // go through the header
00035     parseHeader();
00036 
00037     // now read all VOPs
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     // resize the buffer now!
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     // fill it now!
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     // read until next I_VOP
00164     if (!frameAligned) {
00165                 if (lastReadFrame != NULL) {
00166                 lastReadFrame->setNoInGOP(p->getFrameCount());
00167                 lastReadFrame->setNoInDisplay(dispNoFrames++);
00168                 lastReadFrame->setGOP(p);
00169                 p->addFrame(lastReadFrame);     // this was the old I_VOP
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                                 //~ p->addBVOPsByteSize(frame->getByteSize());
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     // frameAligned, ignore I_VOP patterns, 
00196     // break pattern down to frame rate (frames per second)
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                                 //~ p->addBVOPsByteSize(frame->getByteSize());
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     //  p->printInfo();
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 }

Generated on Wed Mar 19 11:57:43 2003 for qctva4lv by doxygen1.2.17