ISOMP4ContainerFile.cpp

00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: ISOMP4ContainerFile.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 00047 #include "ISOMP4ContainerFile.hpp" 00048 #include "ContainerInfo.hpp" 00049 #include "ESInfo.hpp" 00050 #include "DataChannel.hpp" 00051 #include "DataSink.hpp" 00052 #include "MPGStreamIO.hpp" 00053 #include "Adaptor.hpp" 00054 #include "AdaptorChain.hpp" 00055 #include "MP4Decoder.hpp" 00056 #include "Renderer.hpp" 00057 #include "DevNull.hpp" 00058 #include "MPGSDLRenderer.hpp" 00059 #include "Url.hpp" 00060 #include "SDP.hpp" 00061 #include <string.h> 00062 00066 ContainerInfo *ISOMP4ContainerFile::loadContainerInfo(const char *fileName,const Url* uri) 00067 { 00068 const char* pUri=NULL; 00069 if(uri) 00070 pUri=uri->toString(); 00071 00072 ContainerInfo * result = new ContainerInfo(pUri,fileName, ContainerInfo::MP4); 00073 00074 dprintf_full("ISOMP4ContainerFile::loadMP4Info START-MARK\r\n"); 00075 00076 ISOErr err; 00077 ISOMovie moov; 00078 00079 char *mp4File = new char[strlen(fileName) + 1]; 00080 strcpy(mp4File, fileName); 00081 00082 err = ISOOpenMovieFile(&moov, mp4File, MP4OpenMovieNormal); 00083 if (err != MP4NoErr) { 00084 dprintf_err("ISOOpenMovieFile failed\r\n"); 00085 delete result; 00086 delete mp4File; 00087 return NULL; 00088 } 00089 dprintf_full("ISOOpenMovieFile is ok\r\n"); 00090 00091 u32 timeScale = 0; 00092 err = MP4GetMovieTimeScale(moov, &timeScale); 00093 if (err != MP4NoErr) { 00094 dprintf_err("Failed to get timeScale\r\n"); 00095 timeScale = 0; 00096 } 00097 00098 ISOHandle iodhandle; 00099 err = ISONewHandle(0, &iodhandle); 00100 if (err != MP4NoErr) { 00101 dprintf_err("ISONewHandle failed\r\n"); 00102 ISODisposeMovie(moov); 00103 delete result; 00104 delete mp4File; 00105 return NULL; 00106 } 00107 00108 err = MP4GetMovieInitialObjectDescriptor(moov, iodhandle); 00109 if (err != MP4NoErr) { 00110 dprintf_err("MP4GetMovieInitialObjectDescriptor failed\r\n"); 00111 ISODisposeMovie(moov); 00112 delete result; 00113 delete mp4File; 00114 return NULL; 00115 } 00116 u32 iodHandleSize = 0; 00117 MP4GetHandleSize(iodhandle, &iodHandleSize); 00118 result->setIODHandle((u8 *) * iodhandle, iodHandleSize); 00119 00120 // now parse for streams 00121 u32 streamcnt = 0; 00122 err = ISOGetMovieTrackCount(moov, &streamcnt); 00123 if (err != MP4NoErr) { 00124 dprintf_err("ISOGetMovieTrackCount failed\r\n"); 00125 ISODisposeMovie(moov); 00126 delete result; 00127 delete mp4File; 00128 return NULL; 00129 } 00130 ISOTrack trak; 00131 u32 trackId; 00132 u32 size = 0; 00133 for (u32 i = 1; i <= streamcnt; i++) { 00134 err = MP4GetMovieIndTrack(moov, i, &trak); 00135 if (err != MP4NoErr) { 00136 ISODisposeMovie(moov); 00137 delete result; 00138 delete mp4File; 00139 return NULL; 00140 } 00141 err = MP4GetTrackID(trak, &trackId); 00142 if (err != MP4NoErr) { 00143 ISODisposeMovie(moov); 00144 delete result; 00145 delete mp4File; 00146 return NULL; 00147 } 00148 ESInfo *es = ISOMP4ContainerFile::loadESInfo(moov, result, trackId); 00149 if (!es) { 00150 delete es; 00151 ISODisposeMovie(moov); 00152 delete result; 00153 delete mp4File; 00154 return NULL; 00155 } 00156 dprintf_full("loadFromISOMP4ContainerFile creating ES %i\r\n", i); 00157 es->setInput(mp4File); 00158 00159 result->addESInfo(es); 00160 size += es->getOrigMediaSize(); 00161 } 00162 00163 ISODisposeMovie(moov); 00164 ISODisposeHandle(iodhandle); 00165 00166 QualityInfo *qi = result->getQualityInfo(); 00167 qi->steps[0]->size = size; 00168 return result; 00169 }; 00170 00171 00172 ESInfo *ISOMP4ContainerFile::loadESInfo(ISOMovie & moov, ContainerInfo * vob, 00173 u32 streamId) 00174 { 00175 ISOTrack trak; 00176 ISOErr err; 00177 err = ISOGetMovieTrack(moov, streamId, &trak); 00178 if (err != MP4NoErr) { 00179 return NULL; 00180 } 00181 00182 ISOMedia media; 00183 err = ISOGetTrackMedia(trak, &media); 00184 if (err != MP4NoErr) { 00185 return NULL; 00186 } 00187 u32 width = 0, height = 0; 00188 // FIXME: returns invalid dimension???? 00189 err = MJ2GetTrackDimensions(trak, &width, &height); 00190 if (err != MP4NoErr) { 00191 width = 0; 00192 height = 0; 00193 00194 } 00195 u32 handlerType; 00196 err = ISOGetMediaHandlerDescription(media, &handlerType, 0); 00197 if (err != MP4NoErr) { 00198 return NULL; 00199 } 00200 ISOTrackReader reader; 00201 err = ISOCreateTrackReader(trak, &reader); 00202 if (err != MP4NoErr) { 00203 return NULL; 00204 } 00205 00206 ISOHandle dcHandle; 00207 err = ISONewHandle(0, &dcHandle); 00208 if (err != MP4NoErr) { 00209 return NULL; 00210 } 00211 err = MP4TrackReaderGetCurrentDecoderConfig(reader, dcHandle); 00212 if (err != MP4NoErr) { 00213 return NULL; 00214 } 00215 00216 u32 mediaTimeScale = 0; 00217 u32 totalSamples = 0; 00218 ISOGetMediaTimeScale(media, &mediaTimeScale); 00219 ISOGetMediaSampleCount(media, &totalSamples); 00220 u64 duration = 0; 00221 ISOGetMediaDuration(media, &duration); 00222 u32 ticksDiff=duration/totalSamples; 00223 dprintf_full("Ticks/sec %i DurationinTicks %i numberofSamples %u\n", mediaTimeScale, 00224 int (duration),totalSamples); 00225 u32 dcsize = 0; 00226 MP4GetHandleSize(dcHandle, &dcsize); 00227 00228 u8 *dptr = (u8 *) (*dcHandle); 00229 00230 u8 *encodedDecoderConfig = new u8[dcsize * 2 + 1]; 00231 SDP::encodeDecoderConfig(encodedDecoderConfig, dptr, dcsize); 00232 00233 u32 objectType, streamType, bufferSize, upstream, maxbit = 0, avgbit = 00234 0; 00235 //MP4GetMediaDecoderType(media, 1, &objectType, &streamType, &bufferSize, 0); 00236 00237 MP4GetMediaDecoderInformation(media, 1, &objectType, &streamType, 00238 &bufferSize, &upstream, &maxbit, &avgbit, 00239 0); 00240 00241 // determine the size of the ES 00242 u32 mediaSize = 0; 00243 u32 tmpSize = 0; 00244 u32 dummy; 00245 u32 dummy2, dummy3; 00246 while (MP4TrackReaderGetNextAccessUnit 00247 (reader, dcHandle, &tmpSize, &dummy, &dummy2, 00248 &dummy3) == MP4NoErr) { 00249 mediaSize += tmpSize; 00250 } 00251 ISODisposeHandle(dcHandle); 00252 ISODisposeTrackReader(reader); 00253 return new ESInfo(streamId, handlerType, vob, ticksDiff, encodedDecoderConfig, 00254 objectType, streamType, bufferSize, width, height, 00255 avgbit, maxbit, mediaTimeScale, duration, mediaSize, 00256 totalSamples); 00257 }; 00258 00259 00260 #endif