MPGStreamIO Class Reference

<class description="" goes="" here=""> <short description=""> More...

#include <MPGStreamIO.hpp>

Inheritance diagram for MPGStreamIO:

IO VThread BufferedHttpMPGStreamReader BufferedMPGStreamReader List of all members.

Public Member Functions

 MPGStreamIO (ESInfo *es, const char *file, bool writeOnly, bool omitHeader=false)
FramegetFrame ()
 returns a frame if one complete frame is available, otherwise null is returned.
int writeFrame (Frame *frm, ESInfo *out_es=NULL)
 returns the number of packets sent.
bool open ()
 opens the IO connection.
bool close (bool immediate=false)
 closes the IO class.
bool destroy ()
 deletes the elementary stream and its extra hint-file
int getBufferFillLevel () const
 returns a value from 0..100 indicating buffer usage.
IOclone () const
const char * getURL () const
 returns a local file name or an URL
bool setToFrameNumber (u32 frameNumber)
 repositions the IO class to the given frame.
long setToClosestIFrame (u32 frameNumber, bool backwards)
 repositions to previous I-VOP,
void setESInfo (ESInfo *esi)
ESInfogetESInfo ()

Protected Attributes

FILE * io
char * url
bool writeOnly
ESInfoes
bool atFileStart
FILE * helpFile
bool writeHelpFile
bool omitHeader
u32 lastCTSSeen

Detailed Description

<class description="" goes="" here=""> <short description="">

Author:
Michael Kropfberger and Peter Schojer
Version:
Id
MPGStreamIO.hpp,v 1.9 2006/01/26 11:42:00 mkropfbe Exp

Definition at line 64 of file MPGStreamIO.hpp.


Member Function Documentation

bool MPGStreamIO::close bool  immediate = false  )  [virtual]
 

closes the IO class.

Parameters:
immediate specifies, if (optional) buffered data should be read/sent to the client (==false), or immediately dumped (==true)

Implements IO.

Reimplemented in BufferedHttpMPGStreamReader.

Definition at line 180 of file MPGStreamIO.cpp.

Referenced by IncompleteIO::close(), destroy(), getFrame(), BufferedMPGStreamReader::getFrame(), setToClosestIFrame(), and setToFrameNumber().

00180 { 00181 state = CLOSING; 00182 if (io) { 00183 fclose(io); 00184 io=NULL; 00185 } 00186 if (helpFile) { 00187 fclose(helpFile); 00188 helpFile=NULL; 00189 } 00190 state = CLOSED; 00191 // this->es->setDuration(lastCTSSeen+es->getVOPTimeIncrement()); 00192 return true; 00193 }

int MPGStreamIO::getBufferFillLevel  )  const [inline, virtual]
 

returns a value from 0..100 indicating buffer usage.

Fixme: returns a constant value of 50

Implements IO.

Definition at line 93 of file MPGStreamIO.hpp.

00093 { 00094 return 50; 00095 };

Frame * MPGStreamIO::getFrame  )  [virtual]
 

returns a frame if one complete frame is available, otherwise null is returned.

This function is typically blocking. Don't use a NULL return value to conclude STREAMEOF, always check with getState()!

Implements IO.

Reimplemented in BufferedHttpMPGStreamReader, and BufferedMPGStreamReader.

Definition at line 262 of file MPGStreamIO.cpp.

References close(), Frame::getAU(), ESInfo::getStreamId(), ESInfo::getVOPTimeIncrement(), ESInfo::isAudioStream(), ESInfo::isVisualStream(), Frame::setAU(), and Frame::setMediaTimeScale().

Referenced by IncompleteIO::getFrame().

00262 { 00263 if (writeOnly || state != OPEN) 00264 return NULL; 00265 00266 if (atFileStart) { 00267 atFileStart = false; 00268 //FIXME: why we need to call this for audiostream also? 00269 //if (es->isVisualStream()) { 00270 if (!readHeader()) 00271 state=STREAMERR; 00272 return NULL; 00273 //} 00274 } 00275 if (( (this->currentFrameNumber > this->endFrameNumber) && (endFrameNumber!=0) ) || feof(io)) { 00276 close(true); 00277 state=STREAMEOF; 00278 return NULL; 00279 } 00280 00281 // now read the frame 00282 // first check hintfile 00283 AU *au = new AU(); 00284 Frame *frm = NULL; 00285 Frame::FrameType type = Frame::NN_VOP; 00286 00287 if (writeHelpFile) { 00288 // read one AU entry from the file 00289 int auSize = sizeof(AU) - sizeof(u8 *); 00290 int tmp = 0; 00291 if (auSize != (tmp = fread((char *) &(au->size),sizeof(char),auSize,helpFile))) { 00292 if (tmp <= 0) { 00293 // last frame 00294 state = STREAMEOF; 00295 delete au; 00296 return NULL; 00297 } 00298 dprintf_err("MPGStreamIO::getFrame() esID %llu: Mismatch in hintfile. Expected %i bytes, but just got %i?\r\n", 00299 es->getStreamId(), auSize, tmp); 00300 00301 state = STREAMEOF; 00302 delete au; 00303 return NULL; 00304 } 00305 else { // au is correct 00306 // read the AU 00307 au->payload = new u8[au->size]; 00308 assert(au->payload); 00309 if ((unsigned long) au->size != fread(au->payload,sizeof(char),au->size,io)) { 00310 dprintf_err("MPGStreamIO::getFrame(): Mismatch in data & hintfile. Not enough data?\r\n"); 00311 delete au; 00312 state= STREAMERR; 00313 return NULL; 00314 } 00315 dprintf_full("MPGStreamIO::getFrame(): got hinted info CTS %i prio: %i\n",au->cts,au->prio); 00316 } 00317 } 00318 else { // no help stream available, how to calc cts and dts? 00319 00320 // parse MPGFile for VOB_Code if it is a visual stream 00321 // FIXME: do Audio streams have a different VOP Code?? 00322 00323 if(es->isVisualStream()) { 00324 // 00 00 01 182 dec -> 0x1B6 (=438 dec) 00325 u32 code = 2000; // don't init to 0, we want the code from the 2nd frame, not the first 00326 int ch; 00327 int i = 0; 00328 char *data = new char[MAX_FRAME_SIZE]; 00329 do { 00330 ch = getc(io); 00331 data[i] = (u8)ch; 00332 i++; 00333 code = (code << 8) | (u8)ch; 00334 if ((i==4) && code == VOP_START_CODE) 00335 code =0; //correct beginning, parse until next START_CODE 00336 } 00337 while ((i < MAX_FRAME_SIZE) && (ch != EOF) && (code != VOP_START_CODE)); 00338 00339 if (code == VOP_START_CODE) { 00340 // put back the VOP_HEADER 00341 // seek back 4 bytes 00342 fseek(io, -4, SEEK_CUR); 00343 au->size = i; 00344 } 00345 00346 if (au->size == 0) { 00347 state = STREAMEOF; 00348 delete au; 00349 return NULL; 00350 } 00351 00352 au->payload = new u8[i]; 00353 memcpy(au->payload, data, i); 00354 au->prio = IO_NETWORK_HIGHEST_PRIORITY; 00355 au->duration = es->getVOPTimeIncrement(); 00356 au->cts = currentFrameNumber * es->getVOPTimeIncrement(); 00357 au->dts = currentFrameNumber * es->getVOPTimeIncrement(); 00358 au->sampleFlags = 0; 00359 if (code != VOP_START_CODE) 00360 au->err = SA_EOF; 00361 else 00362 au->err = SA_OK; 00363 00364 00365 delete data; 00366 } 00367 00368 if(es->isAudioStream()) { //XXX not sure if it works properly 00369 dprintf_err("MPGStreamIO audioStream parsing\n\n"); 00370 // start code for MP3 frame is 11111111 111 (first 11 bits set) 00371 u32 code = 2000; // don't init to 0, we want the code from the 2nd frame, not the first 00372 int ch; 00373 int i = 0; 00374 char *data = new char[165536]; 00375 do { 00376 ch = getc(io); 00377 data[i] = ch; 00378 i++; 00379 code = (code << 8) | ch; 00380 } 00381 while ((ch != -1) && 00382 (code>>21 != 0x000007FF /*VOP_START_CODE for audio(actually MP3)*/)) 00383 ; 00384 if (code>>21 == 0x000007FF /*VOP_START_CODE*/) { 00385 // put back the VOP_HEADER 00386 // seek back 4 bytes 00387 fseek(io, -4, SEEK_CUR); 00388 /* 00389 ungetc(182,io); 00390 ungetc(1,io); 00391 ungetc(0,io); 00392 ungetc(0,io); */ 00393 au->size = i; 00394 } 00395 au->payload = new u8[i]; 00396 memcpy(au->payload, data, i); 00397 au->cts = 0; 00398 au->dts = 0; 00399 au->duration = 0; 00400 au->sampleFlags = 0; 00401 if (code>>21 != 0x000007FF /*VOP_START_CODE*/) 00402 au->err = SA_EOF; 00403 else 00404 au->err = SA_OK; 00405 00406 delete [] data; 00407 } 00408 } 00409 00410 00411 //FIXME: quickhack to assign priorities, if no Hint file is avail (eg. direct access to .cmp files!) 00412 if (es->isVisualStream() && !writeHelpFile) { 00413 if (au->payload[0] == 0 && au->payload[1] == 0 && 00414 au->payload[2] == 1 && au->payload[3] == 182) { 00415 type = (Frame::FrameType) ((au->payload[4]) >> 6); 00416 if (type == Frame::I_VOP || type == Frame::P_VOP) 00417 au->prio = IO_NETWORK_HIGHEST_PRIORITY; 00418 else 00419 au->prio = ~IO_NETWORK_HIGHEST_PRIORITY; 00420 } 00421 } 00422 00423 // frame types will be detected in frm->setAU()! 00424 00425 if(es->isVisualStream()) 00426 frm = new CompressedVideoFrame(type, ((VideoESInfo*)es)->getWidth(), ((VideoESInfo*)es)->getHeight()); 00427 else if(es->isAudioStream()) 00428 frm=new CompressedAudioFrame(type); 00429 else 00430 frm = new CompressedVideoFrame(type, 0, 0); 00431 frm->setAU(au); 00432 frm->setMediaTimeScale(es->getMediaTimeScale()); 00433 framesSeen++; 00434 currentFrameNumber++; 00435 dprintf_full("MPGStreamIO::getFrame: file offset %li cts %i dts %i type %s (%x %x %x %x) size %i, frameNo %u\r\n", 00436 ftell(io),au->cts,au->dts, 00437 Frame::VOPTypeToChar((Frame::VOP_TYPE)frm->getAU()->frameType), 00438 frm->getAU()->payload[0],frm->getAU()->payload[1],frm->getAU()->payload[2],frm->getAU()->payload[3], 00439 frm->getAU()->size, 00440 getCurrentFrameNumber()); 00441 00442 #ifdef _POSIX_PRIORITY_SCHEDULING 00443 sched_yield(); 00444 #else 00445 // for windows pthread lib! 00446 #ifdef WIN32 00447 #ifndef WINCE 00448 sched_yield(); 00449 #else 00450 Sleep(0); 00451 #endif 00452 #endif 00453 #endif 00454 00455 return frm; 00456 }

bool MPGStreamIO::open  )  [virtual]
 

opens the IO connection.

State is set to OPENING. Depending on the underlying QIODevice, a network connection is stablished or a file connection. When the connection is ready for use, State is OPEN

Implements IO.

Reimplemented in BufferedHttpMPGStreamReader.

Definition at line 96 of file MPGStreamIO.cpp.

References ESInfo::disableFrameStatistic(), ESInfo::enableFrameStatistic(), ESInfo::getDuration(), ESInfo::getInput(), ESInfo::getNumberOfMediaSamples(), and ESInfo::getVOPTimeIncrement().

Referenced by IncompleteIO::open(), and setToFrameNumber().

00096 { 00097 00098 if(!url) { 00099 // try to get localfile from esinfo 00100 const char* tmpUrl=es->getInput(); 00101 if(tmpUrl) { 00102 url=new char[strlen(tmpUrl)+1]; 00103 strcpy(url,tmpUrl); 00104 } 00105 else 00106 return false; 00107 } 00108 00109 dprintf_full("MPGStreamIO::open() Trying to open %s\r\n", url); 00110 if(state==OPEN) 00111 return true; 00112 00113 bool ret = false; 00114 atFileStart = true; 00115 state = OPENING; 00116 lastCTSSeen=0; 00117 char *name = new char[512]; 00118 strcpy(name,url); 00119 strcat(name,".hint"); 00120 00121 if (writeOnly) { 00122 // we want to write to a local file 00123 // reset statistic 00124 dprintf_full("MPGStreamIO::open(): resetting Statistic to %u dur %u ticks %u\n", 00125 es->getNumberOfMediaSamples(),(unsigned)es->getDuration(), 00126 es->getVOPTimeIncrement()); 00127 es->disableFrameStatistic(); 00128 es->enableFrameStatistic(); 00129 if (writeHelpFile) { 00130 if(helpFile) 00131 fclose(helpFile); 00132 helpFile = fopen(name,"wb"); 00133 if (!helpFile) { 00134 helpFile = NULL; 00135 writeHelpFile = false; 00136 } 00137 } 00138 if(io) { 00139 // safety check, shouldn't happen 00140 fclose(io); 00141 } 00142 io=fopen(url,"wb"); 00143 ret = (io!=NULL); 00144 } else { 00145 // we want to read from a local file 00146 if (writeHelpFile) { 00147 helpFile = fopen(name,"rb"); 00148 if (helpFile) { 00149 fseek(helpFile,0,SEEK_END); 00150 if (ftell(helpFile) == 0){ //zero length 00151 fclose(helpFile); 00152 helpFile = NULL; 00153 } else 00154 fseek(helpFile,0,SEEK_SET); 00155 } 00156 00157 if (!helpFile) { 00158 dprintf_full("MPGStreamIO::open no valid .hint file found, ignoring...\n"); 00159 helpFile = NULL; 00160 writeHelpFile = false; 00161 } else { 00162 dprintf_full("MPGStreamIO::open using and relying on .hint file %s\n",name); 00163 } 00164 } 00165 io=fopen(url,"rb"); 00166 ret = (io!=NULL); 00167 } 00168 00169 if (ret) 00170 state = OPEN; 00171 else 00172 state = CLOSED; 00173 currentFrameNumber=0; 00174 framesSeen=0; 00175 delete [] name; 00176 return ret; 00177 }

long MPGStreamIO::setToClosestIFrame u32  frameNumber,
bool  backwards
[virtual]
 

repositions to previous I-VOP,

Returns:
frameNr or -1 if no previous I-VOP found

Reimplemented from IO.

Reimplemented in BufferedHttpMPGStreamReader.

Definition at line 811 of file MPGStreamIO.cpp.

References close(), ESInfo::getNumberOfMediaSamples(), ESInfo::isAudioStream(), and setToFrameNumber().

Referenced by IncompleteIO::setToClosestIFrame().

00811 { 00812 dprintf_full("MPGStreamIO::setToClosestIFrame searching direction: %s\n",backwards?"backwards":"forwards"); 00813 if(!setToFrameNumber(frameNumber)) 00814 return (-1); 00815 00816 00817 if(frameNumber==0 || es->isAudioStream()) { 00818 dprintf_full("MPGStreamIO::setToClosestIFrame returning %u (%s stream)\n", 00819 frameNumber, es->isAudioStream() ? "audio" : "video"); 00820 return frameNumber; 00821 } 00822 00823 long currentFilePos=ftell(io); 00824 long currentHelpPos=0; 00825 long storedFrameNumber = currentFrameNumber; 00826 int auSize = sizeof(AU) - sizeof(u8 *); 00827 int tmp=0; 00828 AU au; 00829 00830 if(helpFile) 00831 currentHelpPos=ftell(helpFile); 00832 00833 long newFilePos=currentFilePos; 00834 bool firstFrame=true; 00835 00836 // get the AU for the next read Frame call 00837 tmp = fread((char *) &(au.size), 1, auSize, helpFile); 00838 if (auSize==tmp) { 00839 newFilePos+=au.size; 00840 } else { 00841 //FIXME: maybe we have probs on very last frame :( 00842 state=STREAMERR; 00843 } 00844 00845 while ((currentFrameNumber>=0) && (currentFrameNumber <= es->getNumberOfMediaSamples())) { 00846 if (backwards || firstFrame) { 00847 fseek(helpFile, -auSize, SEEK_CUR); 00848 } 00849 tmp = fread((char *) &(au.size), 1, auSize, helpFile); 00850 00851 if(auSize!=tmp) { 00852 // if a seek fails undo all changes to filepointers 00853 fseek(helpFile,currentHelpPos,SEEK_SET); 00854 fseek(io,currentFilePos,SEEK_SET); 00855 currentFrameNumber = storedFrameNumber; 00856 dprintf_err("MPGStreamIO::setToClosestIFrame: failed to set to I-frame\n"); 00857 return currentFrameNumber; 00858 } 00859 dprintf_full("frame %i type %s CTS %i\n",currentFrameNumber,Frame::VOPTypeToChar((Frame::VOP_TYPE)au.frameType),au.cts); 00860 if (backwards) { 00861 fseek(helpFile,-auSize,SEEK_CUR); 00862 newFilePos -= au.size; 00863 } 00864 if (!backwards && !firstFrame) { 00865 newFilePos += au.size; 00866 } 00867 firstFrame=false; 00868 00869 if(au.frameType==(u32)Frame::I_VOP 00870 || au.frameType == (u32) Frame::HEADER_VOP) { 00871 dprintf_full("MPGStreamIO::setToClosestIFrame: found %s at frame %i\n", 00872 Frame::VOPTypeToChar((Frame::VOP_TYPE)au.frameType), currentFrameNumber); 00873 if (!backwards) { //go back to actual frame 00874 newFilePos -= au.size; 00875 fseek(helpFile,-auSize,SEEK_CUR); 00876 } 00877 // point to last read AU in MPGStream 00878 fseek(io,newFilePos,SEEK_SET); 00879 return currentFrameNumber; 00880 } 00881 if (backwards) 00882 currentFrameNumber--; 00883 else 00884 currentFrameNumber++; 00885 } 00886 00887 00888 //error: reset to beginning or end 00889 dprintf_err("MPGStreamIO::setToClosestIFrame() FAILED, currentFrameNumber = %u, nMediaSamples = %u " 00890 "repositioning to %s\n", 00891 currentFrameNumber, es->getNumberOfMediaSamples(), 00892 backwards ? "START" : "END"); 00893 if (backwards) { 00894 fseek(io,0,SEEK_SET); 00895 if(helpFile) 00896 fseek(helpFile,0, SEEK_SET); 00897 atFileStart = true; 00898 currentFrameNumber=0; 00899 } else { 00900 fseek(io,0,SEEK_END); 00901 if(helpFile) 00902 fseek(helpFile,0, SEEK_END); 00903 atFileStart = false; 00904 currentFrameNumber=es->getNumberOfMediaSamples(); 00905 close(true); 00906 state=STREAMEOF; 00907 } 00908 return currentFrameNumber; 00909 }

bool MPGStreamIO::setToFrameNumber u32  frameNumber  )  [virtual]
 

repositions the IO class to the given frame.

Will return false in the following cases:

  • an illegal frame number (too large) was specified
  • the stream is not seekable, because the underlying device is a network device and the requested frame is already out of range: FIXME: implement

Reimplemented from IO.

Reimplemented in BufferedHttpMPGStreamReader.

Definition at line 673 of file MPGStreamIO.cpp.

References close(), ESInfo::getHeaders(), and open().

Referenced by setToClosestIFrame(), and IncompleteIO::setToFrameNumber().

00673 { 00674 // check if valid 00675 // e.g.: writeOnly streams can not be seeked 00676 if(writeOnly) { 00677 dprintf_err("MPGStreamIO::setToFrameNumber(u32 %i) failed: MPGStreamIO opened for writing\n",frameNumber); 00678 return false; 00679 } 00680 dprintf_full("MPGStreamIO::setToFrameNumber: current is %i, new is %i\n",currentFrameNumber,frameNumber); 00681 if(!io) { 00682 // shouldn't happen??? reset class 00683 dprintf_small("MPGStreamIO::setToFrameNumber(u32 %i): called on closed MPGStreamIO\n",frameNumber); 00684 close(true); 00685 open(); 00686 } 00687 if(!io) { 00688 dprintf_err("MPGStreamIO::setToFrameNumber(u32 %i) failed: couldn't open input %s?\n",frameNumber,url); 00689 return false; 00690 } 00691 dprintf_full("MPGStreamIO::setToFrameNumber(u32 %i)\r\n",frameNumber); 00692 long currentFilePos=ftell(io); 00693 long currentHelpPos=0; 00694 00695 if(helpFile) 00696 currentHelpPos=ftell(helpFile); 00697 long newFilePos=currentFilePos; 00698 00699 // readonly stream 00700 if(currentFrameNumber!=frameNumber) { 00701 // reposition 00702 if(frameNumber==0) { 00703 // set to beginning 00704 fseek(io,0,SEEK_SET); 00705 if(helpFile) 00706 fseek(helpFile,0, SEEK_SET); 00707 atFileStart = true; 00708 currentFrameNumber=0; // I-frame always true 00709 return true; 00710 } 00711 else { 00712 int auSize = sizeof(AU) - sizeof(u8 *); 00713 int tmp=0; 00714 00715 AU *au=NULL; 00716 atFileStart = false; 00717 if(currentHelpPos==0) { 00718 readHeader(); 00719 u8* temp=NULL; 00720 newFilePos+=this->es->getHeaders(&temp); 00721 if(temp) 00722 delete[] temp; 00723 } 00724 00725 while(currentFrameNumber!=frameNumber) { 00726 if(writeHelpFile) { 00727 // seeking easy: load data from helpFile 00728 00729 au = new AU(); 00730 00731 //seek forward or backward 00732 00733 if(frameNumber>currentFrameNumber) { 00734 // seek forward 00735 tmp = fread((char *) &(au->size), 1, auSize, helpFile); 00736 if(auSize!=tmp) { 00737 // if a seek fails undo all changes to filepointers 00738 fseek(helpFile,currentHelpPos,SEEK_SET); 00739 fseek(io,currentFilePos,SEEK_SET); 00740 dprintf_err("MPGStreamIO::setToFrameNumber: failed to seek forward\n"); 00741 delete au; 00742 return false; 00743 } 00744 // dprintf_full("MPGStreamIO::setToFrameNumber: cur=%i new=%i newFP=%li addedAUSize=%i\n", 00745 // currentFrameNumber,frameNumber,newFilePos,au->size); 00746 newFilePos+=au->size; 00747 currentFrameNumber++; 00748 delete au; 00749 00750 } 00751 else { // seek backward 00752 // go back one au entry 00753 fseek(helpFile,-auSize,SEEK_CUR); 00754 tmp = fread((char *) &(au->size), 1, auSize, helpFile); 00755 // now that we have read the au, reset it to 00756 // the previous position 00757 fseek(helpFile,-auSize,SEEK_CUR); 00758 00759 if(auSize!=tmp) { 00760 // if a seek fails undo all changes to filepointers 00761 fseek(helpFile,currentHelpPos,SEEK_SET); 00762 fseek(io,currentFilePos,SEEK_SET); 00763 dprintf_err("MPGStreamIO::setToFrameNumber: failed to seek backward\n"); 00764 delete au; 00765 return false; 00766 } 00767 newFilePos-=au->size; 00768 currentFrameNumber--; 00769 delete au; 00770 } 00771 } 00772 else { 00773 // no HelpFile 00774 // we could parse vor VOP header, but we don't :-) 00775 dprintf_err("MPGStreamIO::setToFrameNumber: failed. no helpfile\n"); 00776 return false; 00777 } 00778 } // while 00779 00780 // if we come that far, we can reposition the movie 00781 if(newFilePos>0) { 00782 //helpFile should be at correct position 00783 fseek(io,newFilePos,SEEK_SET); 00784 currentFrameNumber=frameNumber; 00785 return true; 00786 } 00787 else { 00788 // BUG??? We tried to set to a negative position 00789 dprintf_err("MPGStreamIO::setToFrameNumber: Negative new file pointer\r\n"); 00790 // just set to zero; 00791 // set to beginning 00792 fseek(io,0,SEEK_SET); 00793 if(helpFile) 00794 fseek(helpFile,0, SEEK_SET); 00795 atFileStart = true; 00796 currentFrameNumber=0; 00797 00798 return true; 00799 } 00800 } 00801 00802 } 00803 else { 00804 // no need to reposition 00805 return true; 00806 } 00807 return true; 00808 }

int MPGStreamIO::writeFrame Frame frm,
ESInfo out_es = NULL
[virtual]
 

returns the number of packets sent.

Returns 0 on error

Implements IO.

Definition at line 197 of file MPGStreamIO.cpp.

References Frame::getAU(), ESInfo::getFrameStatistic(), ESInfo::getStreamId(), ESInfo::getVOPTimeIncrement(), and BitField::setBit().

00197 { 00198 if(!frm) 00199 return 0; 00200 00201 if (!writeOnly || state != OPEN) { 00202 dprintf_small("MPGStreamIO esID %llu Warning: Output is readonly or not open\n", es->getStreamId()); 00203 return -1; 00204 } 00205 00206 00207 00208 // drop frames we have already written!! 00209 if(lastCTSSeen>=frm->getAU()->cts && lastCTSSeen!=0) { 00210 dprintf_small("MPGStreamIO::writeFrame Dropping Frame %u\n",frm->getAU()->cts); 00211 return 0; 00212 } 00213 else 00214 lastCTSSeen=frm->getAU()->cts; 00215 00216 if (frm->getAU()->size == 0) { 00217 dprintf_small("MPGStreamIO::writeFrame esID %llu: Cannot write zero sized frames\n", es->getStreamId()); 00218 return 0; 00219 } 00220 00221 u32 frmBitIndex=frm->getAU()->cts/es->getVOPTimeIncrement(); 00222 dprintf_full("MPGStreamIO::writeFrame CTS %u(%u), size %u(%u %u %u %u...), VOPINC %u\n", 00223 frm->getAU()->cts,frmBitIndex,frm->getAU()->size,frm->getAU()->payload[0], 00224 frm->getAU()->payload[1],frm->getAU()->payload[2],frm->getAU()->payload[3], 00225 es->getVOPTimeIncrement()); 00226 00227 // write header right in front of first frame!!! 00228 if (atFileStart && !omitHeader) { 00229 atFileStart = false; 00230 if (!saveHeader()) { 00231 dprintf_small("MPGStreamIO::writeFrame esID %llu: failed to save header\n", es->getStreamId()); 00232 return -1; 00233 } 00234 } 00235 00236 // save the frame 00237 int i = (frm->getAU()->size == 00238 fwrite(frm->getAU()->payload,sizeof(char), frm->getAU()->size,io)); 00239 framesSeen++; 00240 es->getFrameStatistic()->setBit(frmBitIndex); 00241 if (writeHelpFile) 00242 writeHelpInfo(frm); 00243 #ifdef _POSIX_PRIORITY_SCHEDULING 00244 sched_yield(); 00245 #else 00246 // for windows pthread lib! 00247 #ifndef WINCE 00248 sched_yield(); 00249 #else 00250 Sleep(0); 00251 #endif 00252 #endif 00253 00254 return i; 00255 }


The documentation for this class was generated from the following files: