isoMP4IO.cpp

00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: isoMP4IO.cpp * 00006 * * 00007 * * 00008 * * 00009 * ITEC institute of the University of Klagenfurt (Austria) * 00010 * http://www.itec.uni-klu.ac.at * 00011 * * 00012 * * 00013 * For more information visit the ViTooKi homepage: * 00014 * http://ViTooKi.sourceforge.net * 00015 * vitooki-user@lists.sourceforge.net * 00016 * vitooki-devel@lists.sourceforge.net * 00017 * * 00018 * This file is part of ViTooKi, a free video toolkit. * 00019 * ViTooKi is free software; you can redistribute it and/or * 00020 * modify it under the terms of the GNU General Public License * 00021 * as published by the Free Software Foundation; either version 2 * 00022 * of the License, or (at your option) any later version. * 00023 * * 00024 * This program is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU General Public License * 00030 * along with this program; if not, write to the Free Software * 00031 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, * 00032 * MA 02111-1307, USA. * 00033 * * 00034 ***********************************************************************/ 00035 00036 /*********************************************************************** 00037 * * 00038 * REVISION HISTORY: * 00039 * * 00040 * * 00041 * * 00042 ***********************************************************************/ 00043 00044 #ifdef ISOMP4 00045 00046 #include "isoMP4IO.hpp" 00047 #include "MPGFrame.hpp" 00048 #include "Frame.hpp" 00049 #include "ESInfo.hpp" 00050 00051 isoMP4IO::isoMP4IO(ESInfo * es, const char *mp4File, bool write) { 00052 streamInfo = es; 00053 state = CLOSED; 00054 input = new char[strlen(mp4File) + 1]; 00055 strcpy(input, mp4File); 00056 writeOnly = write; 00057 dfinitlog(fp, "isoMP4IO", es->getStreamId()); 00058 } 00059 00060 00061 isoMP4IO::~ffMP4IO() { 00062 delete[] input; 00063 close(); 00064 dfclose(fp); 00065 } 00066 00067 00068 Frame* isoMP4IO::getFrame() { 00069 if (state != OPEN || writeOnly) { // FIXME: change this when adding buffering 00070 return NULL; 00071 } 00072 if(this->currentFrameNumber>this->endFrameNumber && endFrameNumber!=0) { 00073 close(true); 00074 state=STREAMEOF; 00075 return NULL; 00076 } 00077 00078 MPGFrame *frm = NULL; 00079 AU *aus = new AU(); 00080 // returns ISOEOF if no more AUs are available 00081 ISOErr err = MP4TrackReaderGetNextAccessUnitWithDuration(reader, au, &aus->size, 00082 &aus->sampleFlags, 00083 &aus->cts, 00084 &aus->dts, 00085 &aus->duration); 00086 switch (err) { 00087 case ISONoErr: 00088 aus->err = SA_OK; 00089 break; 00090 case ISOEOF: 00091 aus->err = SA_EOF; 00092 state = STREAMEOF; 00093 return NULL; 00094 default: 00095 aus->err = SA_Error; 00096 }; 00097 if(framesSeen==0) { 00098 dprintf_full("isoMP4IO::getFrame settingVOPTimeIncrement %u\n",aus->duration); 00099 this->streamInfo->setVOPTimeIncrement(aus->duration); 00100 } 00101 00102 dprintf_full("isoMP4IO::getFrame: Size %i Dur %i cts %i dts %i\n", 00103 aus->size, aus->duration,aus->cts,aus->dts); 00104 // has to do deep-copy, otherwise collision with MP4lib mem handler 00105 aus->payload = new u8[aus->size]; 00106 memcpy(aus->payload, (*(au)), aus->size); 00107 00108 frm = new MPGFrame(Frame::NN_VOP,streamInfo->getWidth(),streamInfo->getHeight()); 00109 currentFrameNumber++; 00110 framesSeen++; 00111 00112 if (!frm->setAU(aus)) { 00113 dfprintf_err(fp, "isoMP4IO::getFrame: Failed to set AU at frame?"); 00114 } 00115 frm->setMediaTimeScale(streamInfo->getMediaTimeScale()); 00116 00117 //FIXME: frame prio not set correctly yet... hack to set some timely distributed values... 00118 //later, this should (could) be read from an additional prio text file 00119 if (frm->getType() == Frame::B_VOP) 00120 if (currentFrameNumber%2) //timely distribution 00121 frm->getAU()->prio = (int)streamInfo->getFPS()*2 00122 - currentFrameNumber % (int)streamInfo->getFPS(); 00123 else 00124 frm->getAU()->prio = currentFrameNumber % (int)streamInfo->getFPS(); 00125 else 00126 frm->getAU()->prio = IO_NETWORK_HIGHEST_PRIORITY; //highest priority is 0 00127 00128 dprintf_full("isoMP4IO::getFrame: setting VOP type %s TS %i prio %i size %i Duration %i\n", 00129 Frame::VOPTypeToChar(frm->getType()),frm->getAU()->dts,frm->getAU()->prio, 00130 aus->size, aus->duration); 00131 00132 #ifdef _POSIX_PRIORITY_SCHEDULING 00133 sched_yield(); //this is necessary to give parallel getFrames a chance 00134 #endif 00135 00136 return frm; 00137 } 00138 00139 00140 bool isoMP4IO::open() { 00141 dprintf_full("isoMP4IO::open()\r\n"); 00142 framesSeen=0; 00143 if(!writeOnly) 00144 return openForReading(); 00145 00146 return openForWriting(); 00147 } 00148 00149 00150 bool isoMP4IO::openForReading() { 00151 state = OPENING; 00152 ISOErr err; 00153 err = ISOOpenMovieFile(&moov, input, MP4OpenMovieNormal); 00154 if (err != ISONoErr) { 00155 dfprintf_err(fp, "ISOOpenMovieFile failed\r\n"); 00156 state = CLOSED; 00157 return false; 00158 } 00159 dfprintf_full(fp, "ISOOpenMovieFile is ok\r\n"); 00160 err = ISOGetMovieTrack(moov, streamInfo->getStreamId(), &trak); 00161 if (err != ISONoErr) { 00162 dfprintf_err(fp, " ISOGetMovieTrack failed\r\n"); 00163 state = CLOSED; 00164 ISODisposeMovie(moov); 00165 return false; 00166 } 00167 00168 ISOMedia media; 00169 err = ISOGetTrackMedia(trak, &media); 00170 if (err != ISONoErr) { 00171 state = CLOSED; 00172 ISODisposeMovie(moov); 00173 dfprintf_err(fp, " ISOGetTrackMedia failed\r\n"); 00174 return false; 00175 } 00176 err = ISOCreateTrackReader(trak, &reader); 00177 if (err != ISONoErr) { 00178 state = CLOSED; 00179 ISODisposeMovie(moov); 00180 dfprintf_err(fp, " ISOCreateTrackReader failed\r\n"); 00181 return false; 00182 } 00183 err = ISONewHandle(sizeof(u32), &au); 00184 state = OPEN; 00185 return true; 00186 } 00187 00188 00189 bool isoMP4IO::openForWriting() { 00190 00191 return false; 00192 } 00193 00194 00195 bool isoMP4IO::close(bool immediate) { 00196 if (state == CLOSED) 00197 return true; 00198 00199 state = CLOSED; 00200 ISOErr err; 00201 err = MP4DisposeHandle(au); 00202 err &= MP4DisposeTrackReader(reader); 00203 err &= MP4DisposeMovie(moov); 00204 return err == ISONoErr; 00205 } 00206 00207 00208 int isoMP4IO::writeFrame(Frame * frm, ESInfo *out_es) { 00209 #ifdef _POSIX_PRIORITY_SCHEDULING 00210 sched_yield(); //this is necessary to give parallel getFrames a chance 00211 #endif 00212 00213 return 0; 00214 } 00215 00216 00219 int isoMP4IO::getBufferFillLevel() const { 00220 if (state == OPEN) 00221 return 50; 00222 else if (state == STREAMEOF) 00223 return -1; 00224 else 00225 return 0; 00226 } 00227 00228 00229 bool isoMP4IO::destroy() { 00230 close(); 00231 return remove(input) == 0; 00232 } 00233 00234 #endif