OGGContainerFile.cpp

00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: OGGContainerFile.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 ENABLE_OGG 00045 00046 #include "OGGContainerFile.hpp" 00047 #include "ContainerInfo.hpp" 00048 #include "VideoESInfo.hpp" 00049 #include "AudioESInfo.hpp" 00050 #include "DataChannel.hpp" 00051 00052 #include "io/UnbufferedFileByteStream.hpp" 00053 #include "io/HttpByteStream.hpp" 00054 #include "io/OGGMuxDemuxIO.hpp" 00055 00056 ContainerInfo *ci = NULL; 00057 OGGHandler *ogh = NULL; 00058 00059 VMutex *oggMutex; 00060 bool initialized = false; 00061 00062 OGGStreamInfo::OGGStreamInfo(){ 00063 dprintf_full("OGGStreamInfo::OGGStreamInfo()\n"); 00064 setNext(NULL); 00065 setStreamID(-1); 00066 setStreamState(NULL); 00067 setCodecInfo(NULL); 00068 setCodecComment(NULL); 00069 setStreamType(OGG_UNKNOWN); 00070 } 00071 00072 OGGStreamInfo::~OGGStreamInfo(){ 00073 dprintf_full("OGGStreamInfo::~OGGStreamInfo()\n"); 00074 if(getNext() != NULL) 00075 delete getNext(); 00076 next=NULL; 00077 00078 if(getStreamState() != NULL) 00079 delete oss; 00080 oss=NULL; 00081 00082 if(getCodecInfo() != NULL){ 00083 if(getStreamType() == OGG_THEORA){ 00084 theora_info_clear((theora_info*)&codec_info); 00085 delete (theora_info*)&codec_info; 00086 } else if(getStreamType() == OGG_VORBIS){ 00087 vorbis_info_clear((vorbis_info*)&codec_info); 00088 delete (vorbis_info*)&codec_info; 00089 } 00090 } 00091 00092 codec_info=NULL; 00093 00094 if(getCodecComment() != NULL){ 00095 if(getStreamType() == OGG_THEORA){ 00096 theora_comment_clear((theora_comment*)&codec_comment); 00097 delete(theora_comment*)&codec_comment; 00098 } else if(getStreamType() == OGG_VORBIS){ 00099 vorbis_comment_clear((vorbis_comment*)&codec_comment); 00100 delete(vorbis_comment*)&codec_comment; 00101 } 00102 } 00103 codec_comment=NULL; 00104 } 00105 00106 00107 void OGGStreamInfo::append(OGGStreamInfo *osi){ 00108 dprintf_full("OGGStreamInfo::append()\n"); 00109 // if first OGGStreamInfo, copy 00110 if(getStreamID() == -1){ 00111 dprintf_full("OGGStreamInfo::append(): inserting...\n"); 00112 setStreamID(osi->getStreamID()); 00113 setStreamState(osi->getStreamState()); 00114 setCodecInfo(osi->getCodecInfo()); 00115 setCodecComment(osi->getCodecComment()); 00116 setStreamType(osi->getStreamType()); 00117 } 00118 // else append 00119 else{ 00120 dprintf_full("OGGStreamInfo::append(): appending...\n"); 00121 OGGStreamInfo *tmp = this; 00122 while(tmp->getNext() != NULL) tmp = tmp->getNext(); 00123 tmp->setNext(osi); 00124 } 00125 } 00126 00127 00128 void OGGStreamInfo::setNext(OGGStreamInfo *osi){ 00129 // dprintf_full("OGGStreamInfo::setNext()\n"); 00130 next = osi; 00131 } 00132 00133 00134 OGGStreamInfo* OGGStreamInfo::getNext(){ 00135 dprintf_full("OGGStreamInfo::getNext()\n"); 00136 return next; 00137 } 00138 00139 00140 void OGGStreamInfo::setStreamID(long id){ 00141 // dprintf_full("OGGStreamInfo::setStreamID(%li)\n",id); 00142 streamid = id; 00143 } 00144 00145 00146 long OGGStreamInfo::getStreamID(){ 00147 // dprintf_full("OGGStreamInfo::getStreamID() = %li\n",streamid); 00148 return streamid; 00149 } 00150 00151 00152 void OGGStreamInfo::setStreamState(ogg_stream_state *o){ 00153 // dprintf_full("OGGStreamInfo::setStreamState()\n"); 00154 oss = o; 00155 } 00156 00157 00158 ogg_stream_state* OGGStreamInfo::getStreamState(){ 00159 // dprintf_full("OGGStreamInfo::getStreamState()\n"); 00160 return oss; 00161 } 00162 00163 00164 ogg_stream_state* OGGStreamInfo::getStreamState(int serial){ 00165 dprintf_full("OGGSTREAMINFO::getStreamState(%i)\n",serial); 00166 if(getStreamID() == serial){ 00167 dprintf_full("OGGStreamInfo::getStreamState(%i): returning Stream with serialno %i\n", 00168 serial, serial); 00169 return getStreamState(); 00170 } 00171 if(!getNext()){ 00172 dprintf_err("OGGStreamInfo::getStreamState(%i): no Stream with Serialno %i found\n", 00173 serial, serial); 00174 return NULL; 00175 } 00176 return 00177 getNext()->getStreamState(serial); 00178 } 00179 00180 00181 void OGGStreamInfo::setCodecInfo(void* ci){ 00182 // dprintf_full("OGGStreamInfo::setCodecInfo()\n"); 00183 codec_info = ci; 00184 } 00185 00186 00187 void* OGGStreamInfo::getCodecInfo(){ 00188 // dprintf_full("OGGStreamInfo::getCodecInfo()\n"); 00189 return codec_info; 00190 } 00191 00192 00193 void OGGStreamInfo::setCodecComment(void* cc){ 00194 // dprintf_full("OGGStreamInfo::setCodecComment()\n"); 00195 codec_comment = cc; 00196 } 00197 00198 00199 void* OGGStreamInfo::getCodecComment(){ 00200 // dprintf_full("OGGStreamInfo::getCodecComment()\n"); 00201 return codec_comment; 00202 } 00203 00204 00205 void OGGStreamInfo::setStreamType(OGGStreamType ost){ 00206 dprintf_full("OGGStreamInfo::setStreamType(%i)\n",ost); 00207 streamtype = ost; 00208 } 00209 00210 00211 OGGStreamType OGGStreamInfo::getStreamType(){ 00212 dprintf_full("OGGStreamInfo::getStreamType() = %i\n",streamtype); 00213 return streamtype; 00214 } 00215 00216 00217 OGGHandler* OGGContainerFile::getOGGHandler(){ 00218 return ogh; 00219 } 00220 00221 00222 #define SIZE 4096 00223 int OGGContainerFile::bufferData(ByteStream *stream, ogg_sync_state *oy) { 00224 int bytes = 0; 00225 char * buffer = ogg_sync_buffer(oy, SIZE); 00226 bytes = stream->read(buffer, SIZE); 00227 if(ogg_sync_wrote(oy, bytes)==-1){ 00228 dprintf_err("OGGContainerFile::bufferData: Buffer overflow in ogg_sync_state!"); 00229 ::exit(0); 00230 } 00231 dprintf_full("OGGContainerFile::bufferData: read %i bytes\n", bytes); 00232 // if(bytes==-1)::exit(0); 00233 return bytes; 00234 } 00235 00236 void OGGContainerFile::initialize(){ 00237 dprintf_full("OGGContainerFile::initialize()\n"); 00238 oggMutex = new VMutex("oggMutex"); 00239 } 00240 00241 void OGGContainerFile::oggMutexLock(const char *s){ 00242 /* 00243 dprintf_full("OGGContainerFile::oggMutexLock(): %s request...\n",s); 00244 oggMutex->lock(); 00245 dprintf_full("OGGContainerFile::oggMutexLock(): %s got lock...\n",s); 00246 */ 00247 } 00248 00249 void OGGContainerFile::oggMutexRelease(const char *s){ 00250 /* 00251 oggMutex->release(); 00252 dprintf_full("OGGContainerFile::oggMutexRelease(): %s released...\n",s); 00253 */ 00254 } 00255 00256 void OGGContainerFile::printOggData(const char* c, const Frame* f){ 00257 ogg_packet *op; 00258 if(f){ 00259 op = (ogg_packet*)f->getAU()->payload; 00260 if(op){ 00261 #if 0 00262 dprintf_full("OggData in %s (packetno: %li) [ogg_packet_p: %p]\n",c, (long)op->packetno, op); 00263 int ret; 00264 for(ret=0; ret<op->bytes; ret++) 00265 printf("%02x ",op->packet[ret]); 00266 printf("\n"); 00267 #endif 00268 }else{ 00269 dprintf_full("OggData in %s contains no data!\n",c); 00270 } 00271 } 00272 } 00273 00274 00275 ContainerInfo *OGGContainerFile::loadContainerInfo(const Url* uri, ByteStream *stream ) { 00276 if(!initialized){ 00277 initialize(); 00278 } 00279 00280 // OGGHandler related 00281 OGGStreamInfo *osi = new OGGStreamInfo(); 00282 ogh = new OGGHandler(); 00283 ogh->osi = osi; 00284 00285 // OGG related 00286 ogg_page og; 00287 ogg_packet op; 00288 00289 // THEORA related 00290 theora_info *ti; 00291 theora_comment *tc; 00292 ogg_stream_state *to; 00293 int theora_found = 0; 00294 int theora_stream_id = 0; 00295 tc = new theora_comment; 00296 ti = new theora_info; 00297 to = new ogg_stream_state; 00298 00299 // VORBIS related 00300 vorbis_info *vi; 00301 vorbis_comment *vc; 00302 ogg_stream_state *vo; 00303 int vorbis_found = 0; 00304 int vorbis_stream_id = 0; 00305 vc = new vorbis_comment; 00306 vi = new vorbis_info; 00307 vo = new ogg_stream_state; 00308 00309 const char* pUri=NULL; 00310 if(uri) 00311 pUri=uri->toString(); 00312 00313 if (stream == NULL) { //reopen the byteStream 00314 if (strstr(uri->getProtocol(), "file")) 00315 stream = new UnbufferedFileByteStream(uri->getPath(), true /* forReading */); 00316 else if (strstr(uri->getProtocol(), "http")) 00317 stream = new HttpByteStream(uri->toString(), true /* forReading */); 00318 } 00319 00320 if (!stream->open()) { 00321 dprintf_err("OGGContainerFile::loadContainerInfo: file not found: %s!\n", pUri); 00322 return NULL; 00323 } 00324 00325 dprintf_full("OGGContainerFile::loadContainerInfo: Init... url %s\n",pUri); 00326 00327 ci = new ContainerInfo(pUri, uri->getPath(), ContainerInfo::OGG); 00328 assert(ci); 00329 ci->setMuxDemuxIO(new OGGMuxDemuxIO(stream)); 00330 00331 /* init ogg sync state */ 00332 ogg_sync_init(&(ogh->oy)); 00333 00334 /* init Theora structures */ 00335 theora_comment_init(tc); 00336 theora_info_init(ti); 00337 00338 /* init Vorbis structures */ 00339 vorbis_comment_init(vc); 00340 vorbis_info_init(vi); 00341 00342 /* open Ogg file and headers 00343 * I'm only interested in Theora and Vorbis streams right now 00344 */ 00345 bool bosFinished = false; 00346 while(!bosFinished){ 00347 int ret = bufferData(stream, &(ogh->oy)); 00348 // FIXME: what to do @ error? 00349 if(ret==0){ 00350 dprintf_err("OGGContainerFile::loadContainerInfo: ERROR! bufferData returned 0!!!\n"); 00351 exit(0); 00352 } 00353 00354 /* 00355 * grep pages which indicate 00356 * 'beginning of stream' (bos) 00357 * out of ogg_sync_state 00358 */ 00359 while(ogg_sync_pageout(&(ogh->oy), &og) > 0){ 00360 /* stream state to get info on a specific stream */ 00361 ogg_stream_state *test; 00362 test = new ogg_stream_state; 00363 00364 /* is this page still a header page 00365 * indicating Beginning Of (logical) Stream? 00366 */ 00367 if(!ogg_page_bos(&og)){ 00368 dprintf_err("OGGContainerFile::loadContainerInfo: EO_BOS\n"); 00369 // save page into stream 00370 // stream will only accept page with equal serial# 00371 dprintf_full("OGGContainerFile::loadContainerInfo: PageSerial was %i\n",ogg_page_serialno(&og)); 00372 ogg_stream_pagein(osi->getStreamState(ogg_page_serialno(&og)),&og); 00373 00374 // finished header parsing... 00375 dprintf_full("OGGContainerFile::loadContainerInfo: bosFinished\n"); 00376 bosFinished = true; 00377 break; 00378 } 00379 00380 /* initialize a test ogg stream with serial# from page */ 00381 ogg_stream_init(test, ogg_page_serialno(&og)); 00382 /* hand page over to stream */ 00383 ogg_stream_pagein(test, &og); 00384 /* grep packet from page in ogg stream */ 00385 ogg_stream_packetout(test, &op); 00386 00387 /* now identify the stream 00388 * for now we only search for THEORA and VORBIS 00389 * FIXME: maybe also other formats??? 00390 */ 00391 int ret; 00392 // check if it is theora 00393 if((ret = theora_decode_header(ti, tc, &op)) >= 0){ 00394 dprintf_full("OGGContainerFile::loadContainerInfo: stream %i is THEORA\n", 00395 ogg_page_serialno(&og)); 00396 // save stream state for further processing 00397 theora_stream_id = ogg_page_serialno(&og); 00398 OGGStreamInfo *tmp = new OGGStreamInfo(); 00399 tmp->setStreamID(ogg_page_serialno(&og)); 00400 tmp->setStreamState(test); 00401 tmp->setCodecInfo(ti); 00402 tmp->setCodecComment(tc); 00403 tmp->setStreamType(OGG_THEORA); 00404 osi->append(tmp); 00405 00406 theora_found = 1; 00407 } 00408 // check if it is vorbis 00409 else if ((ret = vorbis_synthesis_headerin(vi, vc, &op)) >= 0){ 00410 dprintf_full("OGGContainerFile::loadContainerInfo: stream %i is VORBIS\n", 00411 ogg_page_serialno(&og)); 00412 // save stream state for further processing 00413 vorbis_stream_id = ogg_page_serialno(&og); 00414 OGGStreamInfo *tmp = new OGGStreamInfo(); 00415 tmp->setStreamID(ogg_page_serialno(&og)); 00416 tmp->setStreamState(test); 00417 tmp->setCodecInfo(vi); 00418 tmp->setCodecComment(vc); 00419 tmp->setStreamType(OGG_VORBIS); 00420 osi->append(tmp); 00421 00422 vorbis_found = 1; 00423 } else { 00424 // for now we throw away other streams ;) 00425 dprintf_full("OGGContainerFile::loadContainerInfo: stream %i is of unknown TYPE...\ 00426 throwing away!\n", 00427 ogg_page_serialno(&og)); 00428 ogg_stream_clear(test); 00429 delete test; 00430 test = NULL; 00431 } 00432 } 00433 } 00434 00435 // if first streamID is -1, no appropriate Stream has been found :( 00436 if(osi->getStreamID() == -1){ 00437 dprintf_err("OGGContainerFile::loadContainerInfo: \ 00438 NO APPROPRIATE STREAM FOUND :( ... ABORTING."); 00439 exit(0); 00440 } else { 00441 dprintf_full("OGGContainerFile::loadContainerInfo: Found Stream(s) in OGG-Container...\n"); 00442 } 00443 00444 /* 00445 * now we got ogg_streams... 00446 * try further header parsing 00447 * there should be 3 (still 2 more) 00448 * theora and/or vorbis header packets 00449 */ 00450 00451 // bool finished = false; 00452 while((theora_found && theora_found < 3) || 00453 (vorbis_found && vorbis_found < 3)){ 00454 int ret = -1; 00455 00456 // do we have theora and haven't got three header packets 00457 // AND we still get packets out of the theora ogg stream state 00458 if(theora_found){ 00459 to = osi->getStreamState(theora_stream_id); 00460 while((theora_found && theora_found < 3) && 00461 (ret=ogg_stream_packetout(to, &op)) >= 0){ 00462 if(ret < 0){ 00463 dprintf_err("OGGContainerFile::loadContainerInfo: theora packetout: " 00464 "Error parsing Theora stream headers; " 00465 "corrupt stream???\n"); 00466 exit(1); 00467 } 00468 if(theora_decode_header(ti, tc, &op)){ 00469 dprintf_err("OGGContainerFile::loadContainerInfo: theora decode header: " 00470 "Error parsing Theora stream headers; " 00471 "corrupt stream???\n"); 00472 exit(1); 00473 } 00474 dprintf_full("further THEORA-Header found (%i)\n",theora_found); 00475 theora_found++; 00476 } // while 00477 dprintf_full("THEORA RET = %i, theora_found = %i\n",ret,theora_found); 00478 } // if 00479 00480 // parse further vorbis headers 00481 if(vorbis_found){ 00482 vo = osi->getStreamState(vorbis_stream_id); 00483 while((vorbis_found && vorbis_found < 3) && 00484 (ret=ogg_stream_packetout(vo, &op)) > 0){ 00485 if(ret < 0){ 00486 dprintf_err("OGGContainerFile::loadContainerInfo: vorbis packetout: " 00487 "Error parsing Vorbis stream headers; " 00488 "corrupt stream???\n"); 00489 exit(1); 00490 } 00491 if(vorbis_synthesis_headerin(vi,vc,&op)){ 00492 dprintf_err("OGGContainerFile::loadContainerInfo: vorbis headerin: " 00493 "Error parsing Vorbis stream headers; " 00494 "corrupt stream???\n"); 00495 exit(1); 00496 } 00497 dprintf_full("further VORBIS-Header found (%i) (granulepos: %i)\n",vorbis_found,(uint)op.granulepos); 00498 vorbis_found++; 00499 } 00500 dprintf_full("VORBIS RET = %i, vorbis_found = %i\n",ret,vorbis_found); 00501 } 00502 00503 /* 00504 * header is before anything else.. 00505 * so get next page and check if it's 00506 * a header page in next loop 00507 */ 00508 if(ogg_sync_pageout(&(ogh->oy), &og) > 0){ 00509 ogg_stream_pagein(osi->getStreamState(ogg_page_serialno(&og)), &og); 00510 } else { 00511 // if there is no page in sync get next one 00512 if(bufferData(stream, &(ogh->oy)) == 0){ 00513 dprintf_full("OGGContainerFile::loadContainerInfo: EOF while searching for codec headers.\n"); 00514 exit(1); 00515 } 00516 00517 { 00518 // now try a pageout 00519 int ret = 0; 00520 while((ret=ogg_sync_pageout(&(ogh->oy), &og))>0){ 00521 // queue page in appropriate stream 00522 // search for appropriate stream and buffer page 00523 if(osi->getStreamState(ogg_page_serialno(&og))) 00524 ogg_stream_pagein(osi->getStreamState(ogg_page_serialno(&og)), &og); 00525 } 00526 } 00527 } // if(pageout) 00528 } // while theora && / || vorbis < 3 00529 00530 00535 if(theora_found==3){ 00536 dprintf_full(" **************** THEORA ***************\n"); 00537 int i, len; 00538 char *value; 00539 //FILE *out=stdout; 00540 00541 dprintf_full("Encoded By %s\n",tc->vendor); 00542 if(tc->comments){ 00543 dprintf_full("Theora Comment Header:\n"); 00544 for(i=0;i<tc->comments;i++){ 00545 if(tc->user_comments[i]){ 00546 len=tc->comment_lengths[i]; 00547 value=(char*)malloc(len+1); 00548 memcpy(value,tc->user_comments[i],len); 00549 value[len]='\0'; 00550 dprintf_full("\t%s\n", value); 00551 free(value); 00552 } 00553 } 00554 } 00558 dprintf_full("width: %i\n",ti->width); 00559 dprintf_full("height: %i\n",ti->height); 00560 dprintf_full("frame_Width: %i\n",ti->frame_width); 00561 dprintf_full("frame_Height: %i\n",ti->frame_height); 00562 dprintf_full("offset_X: %i\n",ti->offset_x); 00563 dprintf_full("offset_Y: %i\n",ti->offset_y); 00564 dprintf_full("fps_Numerator: %i\n",ti->fps_numerator); 00565 dprintf_full("fps_Denominator: %i\n",ti->fps_denominator); 00566 dprintf_full("aspect_Numerator: %i\n",ti->aspect_numerator); 00567 dprintf_full("aspect_Denominator: %i\n",ti->aspect_denominator); 00568 dprintf_full("colorspace: %s\n", 00569 (ti->colorspace == OC_CS_UNSPECIFIED ? "Oc_Cs_Unspecified" : 00570 ti->colorspace == OC_CS_ITU_REC_470M ? "Oc_Cs_Itu_Rec_470m" : 00571 ti->colorspace == OC_CS_ITU_REC_470BG ? "Oc_Cs_Itu_Rec_470bg" : 00572 "Oc_Cs_Nspaces") 00573 ); 00574 dprintf_full("target_Bitrate: %i\n",ti->target_bitrate); 00575 dprintf_full("quality: %i\n",ti->quality); 00576 dprintf_full("quick_P: %i\n",ti->quick_p); 00577 dprintf_full("version_major: %s\n",&ti->version_major); 00578 dprintf_full("version_minor: %s\n",&ti->version_minor); 00579 dprintf_full("version_subminor: %s\n",&ti->version_subminor); 00580 dprintf_full(" ***************************************\n"); 00581 } 00582 if(vorbis_found==3){ 00583 dprintf_full(" **************** VORBIS ***************\n"); 00584 int i, len; 00585 char *value; 00586 dprintf_full("Encoded By %s\n",vc->vendor); 00587 if(vc->comments){ 00588 dprintf_full("Vorbis Comment Header:\n"); 00589 for(i=0;i<vc->comments;i++){ 00590 if(vc->user_comments[i]){ 00591 len=vc->comment_lengths[i]; 00592 value=(char*)malloc(len+1); 00593 memcpy(value,vc->user_comments[i],len); 00594 value[len]='\0'; 00595 dprintf_full("\t%s\n", value); 00596 free(value); 00597 } 00598 } 00599 } 00603 dprintf_full("version: %i\n",vi->version); 00604 dprintf_full("channels: %i\n",vi->channels); 00605 dprintf_full("rate: %li\n",vi->rate); 00606 dprintf_full("bitrate_upper: %li\n",vi->bitrate_upper); 00607 dprintf_full("bitrate_nominal: %li\n",vi->bitrate_nominal); 00608 dprintf_full("bitrate_lower: %li\n",vi->bitrate_lower); 00609 dprintf_full("bitrate_window: %li\n",vi->bitrate_window); 00610 dprintf_full(" ***************************************\n"); 00611 } 00612 00613 /* 00614 * create the ESInfo-Object 00615 */ 00616 if(vorbis_found){ 00617 ESInfo *esi; 00618 int time_increment = (int)((1024.0/(float)vi->rate)*90000.0); //(int)(1024.0*(90000.0/vi->rate)); //576/vi->rate/2; 00619 int bits_per_sample = 16;//(36864)/(576*vi->channels*2); 00620 dprintf_full("OGGContainerFile::loadContainerInfo: BLA Vorbis_time_increment = %i, BPS = %i, %liHz, %i Channels\n", 00621 time_increment, bits_per_sample, vi->rate, vi->channels); 00622 esi = new AudioESInfo( 00623 vo->serialno, 00624 OGG_VORBIS, 00625 ci, 00626 time_increment, // time increment 00627 NULL, // encodeddecoderconfig 00628 0, 00629 0, 00630 vi->bitrate_nominal, 00631 vi->bitrate_nominal, 00632 90000, 00633 0, // duration 00634 0, // mediaSize 00635 vi->rate, // sampleRate 00636 vi->channels, // channels 00637 true, 00638 CODEC_ID_VORBIS, // CodecID 00639 1.0, // Quality 00640 bits_per_sample // bits_per_sample 00641 ); 00642 ((AudioESInfo*)esi)->setChannelMod(vi->channels); 00643 assert(ci); 00644 ci->addESInfo(esi); 00645 dprintf_full("OGGContainerFile::loadContainerInfo: DescriptionText = %s\n", esi->getDescriptionText()); 00646 } 00647 if(theora_found){ 00648 ESInfo *esi; 00649 float aspectRatio = 1; 00650 int time_increment = (int)(90000.0/((float)(ti->fps_numerator / ti->fps_denominator))); 00651 00652 if((ti->aspect_numerator == 1 && ti->aspect_denominator == 1) || 00653 (ti->aspect_numerator == 0 && ti->aspect_denominator == 0)) 00654 aspectRatio = (float)ti->width / ti->height; 00655 else 00656 aspectRatio = (float)ti->aspect_numerator / ti->aspect_denominator; 00657 esi = new VideoESInfo( 00658 to->serialno, // streamID 00659 OGG_THEORA, // streamtype 00660 ci, // ContainerInfo 00661 time_increment, // 3600, // time Increment 00662 NULL, // encodedDecoderConfig 00663 0, // objtype 00664 0, // bufsize 00665 ti->target_bitrate, // avgBW 00666 ti->target_bitrate, // maxBW 00667 90000, // timescale 00668 0, // duration 00669 0, // mediaSize 00670 ti->width, // width 00671 ti->height, // height 00672 true, // colorVideo 00673 true, // complete 00674 CODEC_ID_THEORA, // CodecID 00675 1.0, // Quality 00676 aspectRatio // aspectratio 00677 ); 00678 00679 //float fps = (float)(((float)ti->fps_numerator) / ((float)ti->fps_denominator)); 00680 //dprintf_full("OGGContainerFile::loadContainerInfo: esi->FPS = %f = ( %i / %i )\n",fps, ti->fps_numerator, ti->fps_denominator); 00681 //((VideoESInfo*)esi)->setFPS((float)((float)ti->fps_numerator / (float)ti->fps_denominator)); 00682 esi->setInput( uri->toString()); 00683 assert(ci); 00684 ci->addESInfo(esi); 00685 00686 00687 //fclose(io); 00688 //exit(0); 00689 } 00690 return ci; 00691 00692 } 00693 00694 #endif // WINCE