VideoESInfo.cpp

00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: VideoESInfo.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 #include "VideoESInfo.hpp" 00036 #include "adaptors/MP4Decoder.hpp" 00037 #include "ReferenceCounter.hpp" 00038 #include "BitField.hpp" 00039 00048 VideoESInfo::VideoESInfo(u32 streamId, u32 streamtype, ContainerInfo * vob, u32 timeIncrement, 00049 u8 * encodeddecconf, u32 objtype, u32 bufsize, 00050 u32 avgBW, u32 maxBW, u32 timeScale, 00051 u64 duration, u32 size, 00052 u32 w, u32 h, bool isColorVideo, 00053 bool complete, 00054 CodecID codec_id, float quality, float AspectRatio, bool staticFrameP, u32 gop_size, 00055 u32 B_Frames,float avgBFrmeSize) 00056 : ESInfo(streamId, 00057 streamtype,vob,timeIncrement,encodeddecconf, 00058 objtype,bufsize,avgBW,maxBW, 00059 timeScale,duration,size,complete,codec_id,quality) 00060 { 00061 width = w; 00062 height = h; 00063 aspect_ratio = AspectRatio; 00064 hasColor=isColorVideo; 00065 GOP_size = gop_size; 00066 num_B_frames = B_Frames; 00067 staticFramePattern=staticFrameP; 00068 setAvgBFrameSize(avgBFrameSize); 00069 00070 // if ffmpeg fails to give width & height for video then get it from the ES 00071 #ifndef ISOMP4 00072 if (w <= 0 || h <= 0) { 00073 00074 MP4Decoder *mp4 = new MP4Decoder(this,false); 00075 mp4->initialize(); 00076 delete mp4; 00077 } 00078 00079 #else 00080 if (handlerType == MP4VisualHandlerType) { 00081 MP4Decoder *mp4 = new MP4Decoder(this,false); 00082 mp4->initialize(); 00083 delete mp4; 00084 } 00085 #endif 00086 generateDescriptionText(); 00087 dprintf_full("VideoESInfo created with size %ix%i aspect %2.2f color %i\n",width,height,aspect_ratio,hasColor); 00088 }; 00089 00090 void VideoESInfo::setAvgBFrameSize(float avgBFrmeSize) 00091 { 00092 if(avgBFrmeSize<0.0 || avgBFrmeSize>=1.0) { 00093 // GUESS values 00094 // for non-static patterns assume 20% 00095 if(!staticFramePattern) 00096 avgBFrameSize=0.2f; 00097 else { 00098 //assume 20% for 1 B-frame between, +10% for each additional B-frame 00099 if(num_B_frames==0) 00100 avgBFrameSize=0.0; 00101 else { 00102 avgBFrameSize=0.2+ (num_B_frames-1)*0.1; 00103 if(avgBFrameSize>0.9) 00104 avgBFrameSize=0.9f; 00105 } 00106 00107 } 00108 } 00109 else 00110 avgBFrameSize=avgBFrmeSize; 00111 generateDescriptionText(); 00112 }; 00113 00114 float VideoESInfo::getAvgBFrameSize() const 00115 { 00116 return avgBFrameSize; 00117 } 00118 00119 u32 VideoESInfo::getHandlerType() const 00120 { 00121 return MP4VisualHandlerType; 00122 }; 00123 00124 u32 VideoESInfo::getWidth() const { 00125 return width; 00126 }; 00127 u32 VideoESInfo::getHeight() const { 00128 return height; 00129 }; 00130 void VideoESInfo::setWidth(u32 uiWidth) { 00131 width = uiWidth; 00132 generateDescriptionText(); 00133 }; 00134 void VideoESInfo::setHeight(u32 uiHeight) { 00135 height = uiHeight; 00136 generateDescriptionText(); 00137 }; 00138 00139 float VideoESInfo::getAspectRatio() const { 00140 return aspect_ratio; 00141 } 00142 00143 void VideoESInfo::setAspectRatio(float AspectRatio) { 00144 aspect_ratio = AspectRatio; 00145 generateDescriptionText(); 00146 } 00147 00148 u32 VideoESInfo::getGOP_size() const { 00149 return GOP_size; 00150 } 00151 00152 void VideoESInfo::setGOP_size(u32 gop_size) { 00153 GOP_size = gop_size; 00154 generateDescriptionText(); 00155 } 00156 00157 u32 VideoESInfo::getNum_B_frames() const { 00158 return num_B_frames; 00159 } 00160 00161 void VideoESInfo::setNum_B_frames(u32 n_B_Frames) { 00162 num_B_frames = n_B_Frames; 00163 generateDescriptionText(); 00164 } 00165 00166 void VideoESInfo::setFPS(float fps) { 00167 assert(mediaTimeScale > 0); 00168 vopTimeIncrement = (u32)ceil(mediaTimeScale / fps); 00169 } 00170 00172 float VideoESInfo::getFPS() const { 00173 if(vopTimeIncrement==0) 00174 return 0.0; 00175 return (float)((double)mediaTimeScale)/((double)vopTimeIncrement); 00176 }; 00177 00178 00179 bool VideoESInfo::getHasColor() const 00180 { 00181 return hasColor; 00182 }; 00183 00184 void VideoESInfo::setHasColor(bool col) 00185 { 00186 hasColor=col; 00187 generateDescriptionText(); 00188 }; 00189 00190 bool VideoESInfo::isVisualStream() const 00191 { 00192 return true; 00193 }; 00194 bool VideoESInfo::isAudioStream() const 00195 { 00196 return false; 00197 }; 00198 bool VideoESInfo::isODStream() const 00199 { 00200 return false; 00201 }; 00202 bool VideoESInfo::isSceneDescriptionStream() const 00203 { 00204 return false; 00205 }; 00206 00207 void VideoESInfo::setEncodedDecoderConfig(u8 * enc) 00208 { 00209 if (encodedDecoderConfig) 00210 delete encodedDecoderConfig; 00211 encodedDecoderConfig = enc; 00212 /* FIXME: WHY IS THIS NEEDED???? it breaks a working decoding/adapting/encoding chain! */ 00213 /* 00214 if (this->isVisualStream() ) { //hack to get decoded config 00215 MP4Decoder *mp4 = new MP4Decoder(this,false); 00216 mp4->initialize(); 00217 delete mp4; 00218 } 00219 */ 00220 decConfUpdated=true; 00221 }; 00222 00223 bool VideoESInfo::hasStaticFramePattern() const 00224 { 00225 return staticFramePattern; 00226 } 00227 00228 void VideoESInfo::setStaticFramePattern(bool pattern) 00229 { 00230 staticFramePattern=pattern; 00231 generateDescriptionText(); 00232 } 00233 00235 ESInfo *VideoESInfo::clone(ContainerInfo * mp4) 00236 { 00237 dprintf_full("ESInfo::clone id %llu\n",streamId); 00238 u8 *decConf = NULL; 00239 if (encodedDecoderConfig) 00240 { 00241 decConf = new u8[strlen((char *) encodedDecoderConfig) + 1]; 00242 strcpy((char *) decConf, (const char *) encodedDecoderConfig); 00243 } 00244 ESInfo *es = new VideoESInfo(streamId, streamType, mp4, vopTimeIncrement, decConf, objectType, 00245 bufferSize, avgBandwidth, maxBandwidth, 00246 mediaTimeScale, duration, mediaSize, width, height, 00247 hasColor,complete, codec_id, this->quality, aspect_ratio, staticFramePattern, 00248 GOP_size, num_B_frames); 00249 es->setInput(input); 00250 00251 if(!existingClones) { 00252 existingClones=new ReferenceCounter(); 00253 existingClones->increase(); // for this object 00254 } 00255 existingClones->increase(); // for clone object 00256 es->setCloneCounter(existingClones); 00257 BitField* fs=getFrameStatistic(); 00258 if(fs) { 00259 es->setFrameStatistic(fs->createWithNewSize(fs->getSize(),false)); 00260 } 00261 return es; 00262 }; 00263 00264 void VideoESInfo::generateDescriptionText() { 00265 char *codecName = new char[MAX_STR_LEN]; 00266 strcpy(codecName,"Unknown"); 00267 #ifdef ENABLE_FFMPEG 00268 AVCodec* av=avcodec_find_decoder(this->codec_id); 00269 if(av) 00270 strcpy(codecName,av->name); 00271 #endif 00272 snprintf(description,MAX_STR_LEN,"%10s: %4ukBps; %4ux%4u; %2.1f/%1uB", 00273 codecName,avgBandwidth/1024,width,height,getFPS(),num_B_frames); 00274 delete [] codecName; 00275 }