Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members
MP4Decoder.cpp
00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: MP4Decoder.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 // MP4Decoder.cpp: Implementierung der Klasse MP4Decoder. 00045 // 00047 00048 #include "MP4Decoder.hpp" 00049 00050 #include "ESInfo.hpp" 00051 #include "UncompressedVideoFrame.hpp" 00052 #include "IO.hpp" 00053 00054 #define readMarkerBit() readMarkerBitFunc(__LINE__) 00055 00056 // Table 6-3: Start code values 00057 #define VISUAL_OBJECT_SEQUENCE_START_CODE 0x1B0 00058 #define VISUAL_OBJECT_SEQUENCE_END_CODE 0x1B1 00059 #define USER_DATA_START_CODE 0x1B2 00060 #define GROUP_OF_VOP_START_CODE 0x1B3 00061 #define VIDEO_SESSION_ERROR_CODE 0x1B4 00062 #define VISUAL_OBJECT_START_CODE 0x1B5 00063 #define VOP_START_CODE 0x1B6 00064 00065 // Table 6-12: pixel aspect ratio 00066 #define PIXEL_ASPECT_RATIO_Forbidden 0 00067 #define PIXEL_ASPECT_RATIO_1_1 1 00068 #define PIXEL_ASPECT_RATIO_12_11 2 00069 #define PIXEL_ASPECT_RATIO_10_11 3 00070 #define PIXEL_ASPECT_RATIO_16_11 4 00071 #define PIXEL_ASPECT_RATIO_40_33 5 00072 #define PIXEL_ASPECT_RATIO_extended_PAR 0xF 00073 00074 // Table 6-14: VOL shape type 00075 #define VOL_SHAPE_rectangular 0 00076 #define VOL_SHAPE_binary 1 00077 #define VOL_SHAPE_binaryonly 2 00078 #define VOL_SHAPE_grayscale 3 00079 00080 static u32 __inline 00081 log2bin(u32 value) 00082 { 00083 /* Changed by Chenm001 */ 00084 // #if !defined(_MSC_VER) 00085 int n = 0; 00086 00087 while (value) { 00088 value >>= 1; 00089 n++; 00090 } 00091 return n; 00092 /* 00093 #else 00094 __asm { 00095 bsr eax, value 00096 inc eax 00097 } 00098 #endif 00099 */ 00100 } 00101 00102 /***************************************************/ 00103 bool MP4Decoder::isValidVisualFrame(const u8* payload) { // 0 0 1 b6 00104 return (payload && payload[0]==0 && payload[1]==0 00105 && payload[2]==1 && payload[3] > 0xb0); // 0xb6 or 0xb2 00106 } 00107 00108 00109 00110 /***************************************************/ 00111 bool MP4Decoder::isValidDecoderConfig(const u8* payload) { // 0 0 1 X != b6 00112 return (payload && payload[0]==0 && payload[1]==0 00113 && payload[2]==1 && (payload[3] == 0xb0 || payload[3] == 0x01)); 00114 } 00115 00116 00117 00121 MP4Decoder::MP4Decoder(VideoESInfo * pESInfo, bool enableSwitching, UncompressedVideoFrame::ColorSpace colorSpace, meCoderType coderType) { 00122 mpDecoder = NULL; 00123 mpOutBuf=NULL; 00124 this->enableSwitching=enableSwitching; 00125 es = pESInfo; 00126 mColorSpace = colorSpace; 00127 mFrameSize = 0; 00128 decConfig=NULL; 00129 decConfigSize=0; 00130 newDecConfig=NULL; 00131 meCoder = coderType; 00132 initialized = false; 00133 if(coderType==XVID) { 00134 dprintf_full("MP4Decoder::MP4Decoder-XVID\n"); 00135 strcpy(name,"MP4Decoder-XVID"); 00136 } 00137 else { 00138 dprintf_full("MP4Decoder::MP4Decoder-FFMPEG\n"); 00139 strcpy(name,"MP4Decoder-FFMPEG"); 00140 } 00141 auBuffer[0] = NULL; 00142 auBuffer[1] = NULL; 00143 muiWidth=0; 00144 muiHeight=0; 00145 00146 mpBuffer = new char[1024*1024*1]; //1 MByte 00147 00148 dprintf_full("MP4Decoder Construct colorSpace %s, bitDepth %i\n", 00149 colorSpace==UncompressedVideoFrame::ColorSpaceGRAY8?"RGB8gray": 00150 colorSpace==UncompressedVideoFrame::ColorSpaceRGB24?"RGB24": 00151 colorSpace==UncompressedVideoFrame::ColorSpaceRGB32?"RGB32": 00152 colorSpace==UncompressedVideoFrame::ColorSpaceRGB565?"RGB565": 00153 colorSpace==UncompressedVideoFrame::ColorSpaceI420?"I420": 00154 colorSpace==UncompressedVideoFrame::ColorSpaceYV12?"YV12": 00155 "UNKNOWN", 00156 UncompressedVideoFrame::mapColorSpaceToBitDepth(colorSpace)); 00157 } 00158 00159 00160 /***************************************************/ 00161 MP4Decoder::~MP4Decoder() { 00162 dprintf_full("MP4Decoder::~MP4Decoder()\n"); 00163 if (initialized && mpDecoder) { 00164 DecoderClose((char **) (&mpDecoder)); 00165 mpDecoder=NULL; 00166 } 00167 if(decConfig) 00168 delete[] decConfig; 00169 decConfig=NULL; 00170 00171 if(newDecConfig) 00172 delete[] newDecConfig; 00173 newDecConfig=NULL; 00174 00175 if(mpOutBuf) 00176 delete[] mpOutBuf; 00177 mpOutBuf=NULL; 00178 00179 if(auBuffer[0]) 00180 delete auBuffer[0]; 00181 if(auBuffer[1]) 00182 delete auBuffer[1]; 00183 00184 delete [] mpBuffer; 00185 mpBuffer = NULL; 00186 } 00187 00188 00189 /***************************************************/ 00190 void MP4Decoder::initialize() { 00191 if (!es) { 00192 initialized = false; 00193 return; 00194 } 00195 if(initialized) 00196 return; 00197 00198 initializeMP4HeaderStruct(); 00199 00200 if(decConfig) { 00201 delete[] decConfig; 00202 decConfig=NULL; 00203 } 00204 if(newDecConfig) { 00205 delete[] newDecConfig; 00206 newDecConfig=NULL; 00207 } 00208 if(mpOutBuf) { 00209 delete[] mpOutBuf; 00210 mpOutBuf=NULL; 00211 } 00212 if(auBuffer[0]) { 00213 delete auBuffer[0]; 00214 auBuffer[0]=NULL; 00215 } 00216 if(auBuffer[1]) { 00217 delete auBuffer[1]; 00218 auBuffer[1]=NULL; 00219 } 00220 if (mpDecoder) { 00221 DecoderClose((char **) (&mpDecoder)); 00222 mpDecoder=NULL; 00223 } 00224 initialized = true; 00225 //has to keep the old value for switching 00226 if (!enableSwitching) { 00227 muiWidth = 0; 00228 muiHeight = 0; 00229 muiLastFrameStart = 0; 00230 muiLastFrameEnd = 0; 00231 } 00232 muiFrameNumber = 0; 00233 00234 decConfig=NULL; 00235 00236 decConfigSize=0; 00237 newDecConfig=NULL; 00238 00239 // muiLastFrameEnd = pESInfo->getHeaders((u8 *) mpBuffer); 00240 00241 muiLastFrameEnd = es->getHeaders(&decConfig); 00242 decConfigSize=muiLastFrameEnd; 00243 memcpy(mpBuffer,decConfig,muiLastFrameEnd); 00244 00245 00246 dprintf_full("MP4Decoder::initialize() %s\r\n",es->getEncodedDecoderConfig()); 00247 00248 #if VITOOKI_DEBUG_LEVEL >= 2 00249 dprintf_full("MP4Decoder::initialize mpBuffer:: "); 00250 for (uint iiii = 0; iiii < muiLastFrameEnd; iiii++) 00251 printf("%02x ", (u8)mpBuffer[iiii]); 00252 dprintf("\r\n"); 00253 #endif 00254 00255 if (muiLastFrameEnd == 0) { 00256 dprintf_err("MP4Decoder::initialize: failed to get header for ESInfo object\n"); 00257 } 00258 initializeParser((u8 *) mpBuffer, muiLastFrameEnd); 00259 if (!parseVOSHeader()) 00260 dprintf_small("No VOS Header found\n"); 00261 if (!parseVOHeader()) 00262 dprintf_small("No VO Header found\n"); 00263 if (!parseUserData()) 00264 dprintf_small("No UserData found\n"); 00265 if (!parseVideoObjectHeader()) 00266 dprintf_small("No VideoObject Header found\n"); 00267 if (!parseVOLHeader()) 00268 dprintf_small("No VOL Header found\n"); 00269 00270 //on switching, ignore the arriving size, but scale to the very first ES 00271 // if (!enableSwitching || muiWidth == 0) { // only set for first time 00272 if (1==1) { 00273 if(es->getCodecID() == CODEC_ID_MPEG4) { 00274 muiWidth = mp4Header.video_object_layer_width; 00275 muiHeight = mp4Header.video_object_layer_height; 00276 00277 #ifdef WINCE 00278 XvidSetHeight(muiHeight); 00279 XvidSetWidth(muiWidth); 00280 #endif 00281 00282 if(es->getAspectRatio() <= 0.0) 00283 es->setAspectRatio((float)muiWidth/muiHeight); 00284 } 00285 00286 if(muiWidth <=0 || muiHeight <= 0) { 00287 muiWidth = es->getWidth(); 00288 muiHeight = es->getHeight(); 00289 } 00290 } else { 00291 dprintf_full("MP4Decoder::initialize: stream switching: upscale %ix%i --> %ix%i\n", 00292 es->getWidth(),es->getHeight(),muiWidth, muiHeight); 00293 } 00294 00295 dprintf_small("MP4Decoder::initialize: DecoderInit to codec %s (id %i) size %ix%i\n", 00296 es->getCodecID() == CODEC_ID_MPEG4?"MPEG4":"OTHER",es->getCodecID(), muiWidth, muiHeight); 00297 int ret = DecoderInit((char **) (&mpDecoder), es->getCodecID(), muiWidth, muiHeight); 00298 00299 if ((ret != ERR_OK) || (mpDecoder == NULL)) { 00300 dprintf_err("MP4Decoder::initialize: Error creating decoder handle (ret=%d)\n",ret); 00301 exit(-1); 00302 } else { 00303 dprintf_small("MP4Decoder::initialize: ok, Decoder set to size %ix%i\n", muiWidth, muiHeight); 00304 //FIXME: hmm... should this be done after streamSwitching and upscale? 00305 es->setHeight(muiHeight); 00306 es->setWidth(muiWidth); 00307 dprintf_full("Mp4Decoder::init Aspect Info %i height %i width %i\n", 00308 this->mp4Header.aspectRatio.aspect_ratio_info, 00309 this->mp4Header.aspectRatio.par_height, 00310 this->mp4Header.aspectRatio.par_width); 00311 if (mp4Header.vop_time_increment_resolution > 0) { 00312 if (mp4Header.vop_time_increment_resolution < 61) { 00313 // treat as frame rate 00314 // most codecs use it as one 00315 u32 ti = es->getMediaTimeScale() / mp4Header.vop_time_increment_resolution; 00316 if(ti > 0) 00317 es->setVOPTimeIncrement(ti); 00318 } 00319 else if ((es->getMediaTimeScale() > mp4Header.vop_time_increment_resolution) && 00320 ((es->getMediaTimeScale() / mp4Header.vop_time_increment_resolution) < 61)) 00321 es->setVOPTimeIncrement(mp4Header.vop_time_increment_resolution); 00322 } 00323 00324 // Process ONLY colorspaces defined in MP4Decoder.hpp 00325 switch (mColorSpace) { 00326 case UncompressedVideoFrame::ColorSpaceGRAY8: 00327 mFrameSize = sizeof(u8) * muiWidth * muiHeight; 00328 break; 00329 case UncompressedVideoFrame::ColorSpaceRGB565: 00330 mFrameSize = sizeof(u8) * muiWidth * muiHeight * 2; 00331 break; 00332 case UncompressedVideoFrame::ColorSpaceRGB24: 00333 mFrameSize = sizeof(u8) * muiWidth * muiHeight * 3; 00334 break; 00335 case UncompressedVideoFrame::ColorSpaceRGB32: 00336 mFrameSize = sizeof(u8) * muiWidth * muiHeight * 4; 00337 break; 00338 case UncompressedVideoFrame::ColorSpaceYV12: // fall through 00339 case UncompressedVideoFrame::ColorSpaceI420: 00340 mFrameSize = sizeof(u8) * muiWidth * muiHeight * 3 / 2; 00341 break; 00342 default: 00343 dprintf_err("MP4Decoder::initialize: Unknown colorspace\n"); 00344 exit(-1); 00345 } 00346 00347 dprintf_full("MP4Decoder::initialize: Esinfo %llu BufferSize %i W %i H %i\n", 00348 es->getStreamId(), es->getBufferSize(), muiWidth, muiHeight); 00349 } 00350 } 00351 00352 00353 /***************************************************/ 00354 list < Frame * >MP4Decoder::adapt(Frame * frm) { 00355 dprintf_full("MP4Decoder::adapt frame CTS %i size %i\n",frm->getAU()->cts,frm->getAU()->size); 00356 if(es && enableSwitching) { 00357 if(decConfigSize>0) { 00358 if(newDecConfig) { 00359 delete[] newDecConfig; 00360 newDecConfig=NULL; 00361 } 00362 00363 u32 nSize=es->getHeaders(&newDecConfig); 00364 if(nSize != 0 && nSize != decConfigSize) { 00365 // we have a new decConfig 00366 if(decConfig) 00367 delete[] decConfig; 00368 decConfig=newDecConfig; 00369 newDecConfig=NULL; 00370 initialized=false; 00371 } 00372 else if(nSize == decConfigSize) { 00373 // same size but might be different 00374 if(memcmp(decConfig,newDecConfig,decConfigSize)!=0) { 00375 // is different 00376 if(decConfig) 00377 delete[] decConfig; 00378 decConfig=newDecConfig; 00379 newDecConfig=NULL; 00380 initialized=false; 00381 } 00382 } 00383 } 00384 } 00385 00386 00387 if (!initialized) 00388 initialize(); 00389 00390 list < Frame * >frmList; 00391 if (!initialized) 00392 return frmList; 00393 if(mpOutBuf) { 00394 delete[] mpOutBuf; 00395 mpOutBuf=NULL; 00396 } 00397 00398 00399 #ifndef WINCE 00400 00401 mpOutBuf = new u8[mFrameSize]; 00402 00403 // The Decoder expects in case of BFRAMES_DEC enabled the 00404 // B-Frame together with the reference frame. Therefore one frame is 00405 // always buffered for this case. 00406 if (muiFrameNumber == 0) { 00407 //first send the header to the decoder ... 00408 lenDecoded = DecodeFrame((char *) mpDecoder, mpBuffer, muiLastFrameEnd,(char *) mpOutBuf, mColorSpace); 00409 if(lenDecoded <= 0) { 00410 lenDecoded = abs(lenDecoded); 00411 dprintf_err("MP4Decoder::adapt : muiFrameNumber==0, no decoder output for header frame!\n"); 00412 } 00413 00414 // ... and then the first frame. 00415 memcpy(mpBuffer, (u8 *) frm->getAU()->payload, frm->getAU()->size); 00416 muiLastFrameEnd = frm->getAU()->size; 00417 00418 //decode but don't return the output... this saves the first frame in the ffmpeg buffer.... 00419 lenDecoded = DecodeFrame((char *) mpDecoder, mpBuffer, muiLastFrameEnd, 00420 (char *) mpOutBuf, mColorSpace); 00421 dprintf_full("MP4Decoder::adapt : muiFrameNumber==0, decoder output1 len %i\n",lenDecoded); 00422 00423 // ... and again first frame: required to cope with random access after stream switching 00424 memcpy(mpBuffer, (u8 *) frm->getAU()->payload, frm->getAU()->size); 00425 lenDecoded = DecodeFrame((char *) mpDecoder, mpBuffer, muiLastFrameEnd, 00426 (char *) mpOutBuf, mColorSpace); 00427 dprintf_full("MP4Decoder::adapt : muiFrameNumber==0, decoder output2 len %i\n",lenDecoded); 00428 00429 lenDecoded = 0; // cause this frame to be decoded at next adapt() call 00430 if(auBuffer[1]) 00431 delete auBuffer[1]; 00432 auBuffer[1] = new AU(frm->getAU()); 00433 if(mpOutBuf) { 00434 delete[] mpOutBuf; 00435 mpOutBuf=NULL; 00436 } 00437 } else { // muiFrameNumber != 0 00438 00439 00440 // int oldMuiLastFE = muiLastFrameEnd; 00441 00442 if (lenDecoded > 0) { 00443 memmove(mpBuffer, mpBuffer + lenDecoded, muiLastFrameEnd - lenDecoded); 00444 } 00445 00446 //copy input frame to mpBuffer (which is furthermore used by the decoder) 00447 //FIXME: check for BUFFER and frm->size!!! 00448 memcpy(mpBuffer + (muiLastFrameEnd - lenDecoded), 00449 (u8 *) frm->getAU()->payload, frm->getAU()->size); 00450 muiLastFrameStart = 0; 00451 00452 00453 // char *mpBufferToFrame = mpBuffer; 00454 // int currentFrameLen; 00455 muiLastFrameEnd = muiLastFrameEnd - lenDecoded + frm->getAU()->size; 00456 00457 #endif 00458 00459 if(auBuffer[0]) 00460 delete auBuffer[0]; 00461 auBuffer[0] = auBuffer[1]; 00462 //assert(auBuffer[1]); 00463 auBuffer[1] = new AU(frm->getAU()); 00464 00465 00466 #ifndef WINCE 00467 lenDecoded = DecodeFrame((char *) mpDecoder, mpBuffer, muiLastFrameEnd, (char *) mpOutBuf, mColorSpace); 00468 dprintf_full("MP4Decoder::adapt : later frames, decoder output len %i\n",lenDecoded); 00469 00470 #else 00471 00472 u8 *y,*u,*v; 00473 if (muiFrameNumber == 0) { 00474 lenDecoded = XVIDDecodeFrameCE(mpBuffer, //(char*)frm->getAU()->payload, //mpBuffer + (muiLastFrameEnd - lenDecoded), 00475 muiLastFrameEnd, 00476 y, 00477 u, 00478 v); 00479 muiLastFrameEnd = frm->getAU()->size; 00480 auBuffer[0] = new AU(frm->getAU()); 00481 } else { 00482 muiLastFrameEnd = muiLastFrameEnd - lenDecoded + frm->getAU()->size; 00483 } 00484 00485 00486 lenDecoded = XVIDDecodeFrameCE((char*)frm->getAU()->payload, //mpBuffer + (muiLastFrameEnd - lenDecoded), 00487 muiLastFrameEnd, 00488 y, 00489 u, 00490 v); 00491 00492 #endif 00493 00494 00495 if(lenDecoded <= 0) { 00496 lenDecoded = abs(lenDecoded); 00497 dprintf_err("MP4Decoder::adapt Warning: no decoder output for frame %d\n", muiFrameNumber); 00498 // dprintf_full("MP4Decoder::adapt %x %x %x %x\r\n", 00499 // (char)mpBuffer[0],(char) mpBuffer[1],(char)mpBuffer[2],(char)mpBuffer[3]); 00500 } else { 00501 //copy result (decoded frame) to new access unit... 00502 AU * pAU = auBuffer[0]; 00503 auBuffer[0]=NULL; 00504 pAU->size = mFrameSize; 00505 pAU->payload = mpOutBuf; 00506 dprintf_full("MP4Decoder::adapt Decode Frame No %d uncompressed size %d CTS %i\n", 00507 muiFrameNumber, pAU->size, pAU->cts); 00508 Frame::FrameType type; 00509 switch (mColorSpace) { 00510 case UncompressedVideoFrame::ColorSpaceGRAY8: 00511 case UncompressedVideoFrame::ColorSpaceRGB565: 00512 case UncompressedVideoFrame::ColorSpaceRGB24: 00513 case UncompressedVideoFrame::ColorSpaceRGB32: 00514 type = Frame::RGB_VOP; 00515 break; 00516 case UncompressedVideoFrame::ColorSpaceYV12: // fall through 00517 case UncompressedVideoFrame::ColorSpaceI420: 00518 type = Frame::YUV_VOP; 00519 break; 00520 default: 00521 dprintf_err("MP4Decoder::adapt: Unknown colorspace\n"); 00522 exit(-1); 00523 } 00524 UncompressedVideoFrame * decFrame = new UncompressedVideoFrame(type, muiWidth, muiHeight); 00525 decFrame->setAU(pAU); 00526 dprintf_full("MP4Decoder::adapt(): created UncompressedVideoFrame with type=%d, width=%d, height=%d (ausize=%d)\n", type, muiWidth, muiHeight, decFrame->getAU()->size); 00527 dprintf_full("MP4Decoder::adapt(): frametype = %d , type = %d\n", decFrame->getType(), type); 00528 00529 #ifdef WINCE 00530 decFrame->setAUy(y); 00531 decFrame->setAUu(u); 00532 decFrame->setAUv(v); 00533 #endif 00534 00535 decFrame->setMediaTimeScale(frm->getMediaTimeScale()); 00536 decFrame->setColorSpace(mColorSpace); 00537 frmList.push_back(decFrame); 00538 mpOutBuf=NULL; 00539 } 00540 00541 #ifndef WINCE 00542 } 00543 #endif 00544 00545 muiFrameNumber++; 00546 return frmList; 00547 } 00548 00549 00550 /***************************************************/ 00551 list < Frame * >MP4Decoder::close() { 00552 list < Frame * >frmList; 00553 if (!initialized) 00554 return frmList; 00555 if(mpOutBuf) { 00556 delete[] mpOutBuf; 00557 mpOutBuf=NULL; 00558 } 00559 00560 mpOutBuf = new u8[mFrameSize]; 00561 #ifndef WINCE 00562 if (dec != NULL && muiFrameNumber != 0) 00563 #else 00564 if (muiFrameNumber != 0) 00565 #endif 00566 { 00567 #ifndef WINCE 00568 if (DecodeFrame((char *) mpDecoder, mpBuffer + muiLastFrameStart, 00569 muiLastFrameEnd, (char *) mpOutBuf, mColorSpace) == 0) 00570 { 00571 dprintf_err("MP4Decoder::close Error decoding frame %d\n", muiFrameNumber); 00572 delete[] mpOutBuf;mpOutBuf=NULL; 00573 if(auBuffer[1]) { 00574 delete auBuffer[1]; 00575 auBuffer[1]=NULL; 00576 } 00577 } 00578 00579 else 00580 { 00581 AU * pAU = auBuffer[1]; 00582 pAU->size = mFrameSize; 00583 pAU->payload = mpOutBuf; 00584 dprintf_full("MP4Decoder::close Decode Frame No %d uncompressed size %d CTS %i\n", 00585 muiFrameNumber, pAU->size, pAU->cts); 00586 muiFrameNumber++; 00587 Frame::FrameType type; 00588 switch (mColorSpace) { 00589 case UncompressedVideoFrame::ColorSpaceGRAY8: 00590 case UncompressedVideoFrame::ColorSpaceRGB565: 00591 case UncompressedVideoFrame::ColorSpaceRGB24: 00592 case UncompressedVideoFrame::ColorSpaceRGB32: 00593 type = Frame::RGB_VOP; 00594 break; 00595 case UncompressedVideoFrame::ColorSpaceYV12: // fall through 00596 case UncompressedVideoFrame::ColorSpaceI420: 00597 type = Frame::YUV_VOP; 00598 break; 00599 default: 00600 dprintf_err("MP4Decoder::close: Unknown colorspace\n"); 00601 exit(-1); 00602 } 00603 UncompressedVideoFrame * decFrame = new UncompressedVideoFrame(type, muiWidth, muiHeight); 00604 decFrame->setAU(pAU); 00605 dprintf_full("MP4Decoder::close(): created UncompressedVideoFrame with type=%d, width=%d, height=%d (ausize=%d)\n", type, muiWidth, muiHeight, decFrame->getAU()->size); 00606 dprintf_full("MP4Decoder::close(): frametype = %d , type = %d\n", decFrame->getType(), type); 00607 00608 #ifdef WINCE 00609 decFrame->setAUy(y); 00610 decFrame->setAUu(u); 00611 decFrame->setAUv(v); 00612 #endif 00613 00614 decFrame->setMediaTimeScale(es->getMediaTimeScale()); 00615 decFrame->setColorSpace(mColorSpace); 00616 decFrame->setColorSpace(mColorSpace); 00617 frmList.push_back(decFrame); 00618 mpOutBuf=NULL;auBuffer[1]=NULL; 00619 } 00620 #endif 00621 } 00622 else { 00623 delete[] mpOutBuf;mpOutBuf=NULL; 00624 if(auBuffer[1]) { 00625 delete auBuffer[1]; 00626 auBuffer[1]=NULL; 00627 } 00628 } 00629 if (initialized) { 00630 DecoderClose((char **) (&mpDecoder)); 00631 initialized = false; 00632 } 00633 00634 return frmList; 00635 } 00636 00637 00638 /***************************************************/ 00639 Adaptor * MP4Decoder::clone() { 00640 return new MP4Decoder(es,enableSwitching,mColorSpace,meCoder); 00641 } 00642 00643 00644 /***************************************************/ 00645 bool MP4Decoder::parseVOSHeader() { 00646 if (nextBits(32) == VISUAL_OBJECT_SEQUENCE_START_CODE) 00647 { 00648 getBits(32); 00649 mp4Header.profile_and_level_indication = getBits(8); 00650 } 00651 00652 else 00653 return false; 00654 00655 return true; 00656 } 00657 00658 00659 /***************************************************/ 00660 bool MP4Decoder::parseVOHeader() { 00661 if (nextBits(32) == VISUAL_OBJECT_START_CODE) 00662 { 00663 getBits(32); 00664 mp4Header.is_visual_object_identifier = getBit(); 00665 if (mp4Header.is_visual_object_identifier) 00666 { 00667 mp4Header.visual_object_verid = getBits(4); 00668 mp4Header.visual_object_priority = getBits(3); 00669 } 00670 mp4Header.visual_object_type = getBits(4); 00671 if (mp4Header.visual_object_type == 1 /*video ID */ 00672 || mp4Header.visual_object_type == 2 /*still texture ID */ ) 00673 { 00674 video_signal_type_func(); 00675 } 00676 nextStartCode(); 00677 } 00678 00679 else 00680 return false; 00681 return true; 00682 } 00683 00684 00685 /***************************************************/ 00686 bool MP4Decoder::video_signal_type_func() { 00687 int video_signal_type = getBit(); 00688 if (video_signal_type) 00689 { 00690 00691 //no variables needed, but getBits is advancing in memory space! 00692 //int video_format = 00693 getBits(3); 00694 //int video_range = 00695 getBit(); 00696 int colour_description = getBit(); 00697 if (colour_description) 00698 { 00699 //int colour_primaries = 00700 getBits(8); 00701 //int transfer_characteristics = 00702 getBits(8); 00703 //int matrix_coefficients = 00704 getBits(8); 00705 } 00706 } 00707 00708 else 00709 return false; 00710 return true; 00711 } 00712 00713 00714 /***************************************************/ 00715 bool MP4Decoder::parseUserData() { 00716 if (nextBits(32) == USER_DATA_START_CODE) 00717 { 00718 getBits(32); 00719 00720 // FIXME: parse till next startcode 00721 } 00722 00723 else 00724 return false; 00725 return true; 00726 } 00727 00728 00729 /***************************************************/ 00730 bool MP4Decoder::parseVideoObjectHeader() { 00731 int iStartCode = 0; 00732 iStartCode = nextBits(32); 00733 if (iStartCode >= 0x100 && iStartCode <= 0x11F) 00734 { 00735 getBits(32); 00736 mp4Header.video_object_layer_startcode = iStartCode; 00737 } 00738 00739 else 00740 return false; 00741 return true; 00742 } 00743 00744 00745 /***************************************************/ 00746 bool MP4Decoder::parseVOLHeader() { 00747 if (nextBits(32) >= 0x120 && nextBits(32) <= 0x12F) 00748 { 00749 mp4Header.short_video_header = 0; 00750 mp4Header.video_object_layer_start_code = getBits(32); 00751 mp4Header.video_object_layer_id = 00752 mp4Header.video_object_layer_start_code & 0x0F; 00753 mp4Header.random_accessbile_vol = getBit(); 00754 mp4Header.video_object_type_indication = getBits(8); 00755 mp4Header.is_object_layer_identifier = getBit(); 00756 if (mp4Header.is_object_layer_identifier) { 00757 mp4Header.video_object_layer_verid = getBits(4); 00758 mp4Header.video_object_layer_priority = getBits(3); 00759 } 00760 mp4Header.aspectRatio.aspect_ratio_info = getBits(4); 00761 if (mp4Header.aspectRatio.aspect_ratio_info == 00762 PIXEL_ASPECT_RATIO_extended_PAR) { 00763 mp4Header.aspectRatio.par_width = getBits(8); 00764 mp4Header.aspectRatio.par_height = getBits(8); 00765 } 00766 mp4Header.volControlParameters.vol_control_parameters = getBit(); 00767 if (mp4Header.volControlParameters.vol_control_parameters) 00768 { 00769 mp4Header.volControlParameters.chroma_format = getBits(2); 00770 mp4Header.volControlParameters.low_delay = getBit(); 00771 mp4Header.volControlParameters.vbv_parameters = getBit(); 00772 if(mp4Header.volControlParameters.vbv_parameters) { 00773 mp4Header.volControlParameters.first_half_bit_rate = 00774 getBits(15); 00775 readMarkerBit(); 00776 mp4Header.volControlParameters.latter_half_bit_rate = 00777 getBits(15); 00778 readMarkerBit(); 00779 mp4Header.volControlParameters.first_half_vbv_buffer_size = 00780 getBits(15); 00781 readMarkerBit(); 00782 mp4Header.volControlParameters.latter_half_vbv_buffer_size = 00783 getBits(3); 00784 mp4Header.volControlParameters.first_half_vbv_occupancy = 00785 getBits(11); 00786 readMarkerBit(); 00787 mp4Header.volControlParameters.latter_half_vbv_occupancy = 00788 getBits(15); 00789 readMarkerBit(); 00790 } 00791 } 00792 mp4Header.video_object_layer_shape = getBits(2); 00793 readMarkerBit(); 00794 // what does this value tell, its not the vop time increment!!! 00795 // it seems to be the frame rate, tested with 5 videos crated with 3 different codecs 00796 // that's stupid! so ignore... 00797 u32 vop_inc = getBits(16); 00798 dprintf_full("Detected VOPTimeIncrement of %u\n",vop_inc); 00799 if (vop_inc < 9000) //sanity test: inc 9000 means 10 fps.... 00800 mp4Header.vop_time_increment_resolution = vop_inc; 00801 readMarkerBit(); 00802 /* 00803 int i = mp4Header.vop_time_increment_resolution; 00804 while (i > 0) 00805 { 00806 i = i >> 1; 00807 mp4Header.vop_time_incrememt_bits_needed++; 00808 } 00809 */ 00810 mp4Header.vop_time_incrememt_bits_needed = log2bin(mp4Header.vop_time_increment_resolution-1); 00811 mp4Header.fixed_vop_rate = getBit(); 00812 if (mp4Header.fixed_vop_rate) { 00813 mp4Header.fixed_vop_time_increment = getBits(mp4Header.vop_time_incrememt_bits_needed); 00814 // not working 00815 } else 00816 dprintf_full("no fixed VOP TIME Increment!\n"); 00817 00818 if (mp4Header.video_object_layer_shape != VOL_SHAPE_binaryonly) 00819 { 00820 if (mp4Header.video_object_layer_shape == 00821 VOL_SHAPE_rectangular) 00822 { 00823 readMarkerBit(); 00824 mp4Header.video_object_layer_width = getBits(13); 00825 readMarkerBit(); 00826 mp4Header.video_object_layer_height = getBits(13); 00827 readMarkerBit(); 00828 } 00829 mp4Header.interlaced = getBit(); 00830 mp4Header.obmc_disable = getBit(); 00831 mp4Header.sprite_enable = getBit(); 00832 if (mp4Header.sprite_enable) 00833 return false; 00834 mp4Header.not_8_bit = getBit(); 00835 if (mp4Header.not_8_bit) 00836 { 00837 mp4Header.quant_precision = getBits(4); 00838 mp4Header.bits_per_pixel = getBits(4); 00839 } 00840 if (mp4Header.video_object_layer_shape == VOL_SHAPE_grayscale) 00841 { 00842 mp4Header.no_gray_quant_update = getBit(); 00843 mp4Header.composition_method = getBit(); 00844 mp4Header.linear_composition = getBit(); 00845 } 00846 mp4Header.quant.quant_type = getBit(); 00847 if (mp4Header.quant.quant_type) 00848 { 00849 mp4Header.quant.load_intra_quant_mat = getBit(); 00850 if (mp4Header.quant.load_intra_quant_mat) 00851 loadQuantizerMatrix(mp4Header.quant. 00852 intra_quant_matrix); 00853 mp4Header.quant.load_nonintra_quant_mat = getBit(); 00854 if (mp4Header.quant.load_nonintra_quant_mat) 00855 loadQuantizerMatrix(mp4Header.quant. 00856 nonintra_quant_matrix); 00857 if (mp4Header.video_object_layer_shape == 00858 VOL_SHAPE_grayscale) 00859 { 00860 mp4Header.quant.load_intra_quant_mat_grayscale = 00861 getBit(); 00862 if (mp4Header.quant.load_intra_quant_mat_grayscale) 00863 loadQuantizerMatrix(mp4Header.quant. 00864 intra_quant_matrix_grayscale); 00865 mp4Header.quant.load_nonintra_quant_mat_grayscale = 00866 getBit(); 00867 if (mp4Header.quant.load_nonintra_quant_mat_grayscale) 00868 loadQuantizerMatrix(mp4Header.quant. 00869 nonintra_quant_matrix_grayscale); 00870 } 00871 } 00872 mp4Header.complexity_estimation_disable = getBit(); 00873 if (!mp4Header.complexity_estimation_disable) 00874 return false; 00875 mp4Header.resync_marker_disable = getBit(); 00876 mp4Header.data_partitioned = getBit(); 00877 if (mp4Header.data_partitioned) 00878 mp4Header.reversible_vlc = getBit(); 00879 mp4Header.scalability = getBit(); 00880 if (mp4Header.scalability) 00881 return false; 00882 } 00883 00884 else 00885 mp4Header.resync_marker_disable = getBit(); 00886 } 00887 00888 else 00889 { 00890 return false; 00891 } 00892 return true; 00893 } 00894 00895 00896 /***************************************************/ 00897 void MP4Decoder::initializeParser(u8 * pFrame, u32 iSize) { 00898 mcByte = 0; 00899 if (pFrame != NULL) 00900 { 00901 mpcData = pFrame; 00902 miSize = iSize; 00903 00904 00905 /* 00906 u8 * bla = new u8[miSize*2+1]; 00907 ISOMP4ContainerFile::encodeDecoderConfig(bla, mpcData, miSize); 00908 dprintf("---Decoder %s\n", bla); 00909 fflush(stdout); 00910 fflush(stderr); 00911 */ 00912 } 00913 00914 else 00915 { 00916 mpcData = NULL; 00917 miSize = 0; 00918 } 00919 mbEOD = false; 00920 miCurrentNoBytes = 0; 00921 miCurrentBit = -1; 00922 } 00923 00924 00925 /***************************************************/ 00926 void MP4Decoder::initializeMP4HeaderStruct() { 00927 unsigned int intra_quant_mat[64] = 00928 { 8, 17, 18, 19, 21, 23, 25, 27, 17, 18, 19, 21, 23, 25, 27, 28, 00929 20, 00930 21, 22, 23, 24, 26, 28, 30, 21, 22, 23, 24, 26, 28, 30, 32, 22, 00931 23, 24, 00932 26, 28, 30, 32, 35, 23, 24, 26, 00933 28, 30, 32, 35, 38, 25, 26, 28, 30, 32, 35, 38, 41, 27, 28, 30, 00934 32, 35, 00935 38, 41, 45 00936 }; 00937 unsigned int nonintra_quant_mat[64] = 00938 { 16, 17, 18, 19, 20, 21, 22, 23, 17, 18, 19, 20, 21, 22, 23, 24, 00939 18, 00940 19, 20, 21, 22, 23, 24, 25, 19, 20, 21, 22, 23, 24, 26, 27, 20, 00941 21, 22, 00942 23, 25, 26, 27, 28, 21, 22, 23, 24, 00943 26, 27, 28, 30, 22, 23, 24, 26, 27, 28, 30, 31, 23, 24, 25, 27, 00944 28, 30, 00945 31, 33 00946 }; 00947 unsigned int intra_quant_mat_grayscale[64] = 00948 { 8, 17, 18, 19, 21, 23, 25, 27, 17, 18, 19, 21, 23, 25, 27, 28, 00949 20, 00950 21, 22, 23, 24, 26, 28, 30, 21, 22, 23, 24, 26, 28, 30, 32, 22, 00951 23, 24, 00952 26, 28, 30, 32, 35, 23, 24, 26, 28, 30, 00953 32, 35, 38, 25, 26, 28, 30, 32, 35, 38, 41, 27, 28, 30, 32, 35, 00954 38, 41, 00955 45 00956 }; 00957 unsigned int nonintra_quant_mat_grayscale[64] = 00958 { 16, 17, 18, 19, 20, 21, 22, 23, 17, 18, 19, 20, 21, 22, 23, 24, 00959 18, 00960 19, 20, 21, 22, 23, 24, 25, 19, 20, 21, 22, 23, 24, 26, 27, 20, 00961 21, 22, 00962 23, 25, 26, 27, 28, 21, 22, 23, 24, 26, 27, 00963 28, 30, 22, 23, 24, 26, 27, 28, 30, 31, 23, 24, 25, 27, 28, 30, 00964 31, 33 00965 }; 00966 00967 // Visual Object Sequence 00968 mp4Header.profile_and_level_indication = 0; 00969 00970 // Visual Object 00971 mp4Header.is_visual_object_identifier = 0; 00972 mp4Header.visual_object_verid = 0; 00973 mp4Header.visual_object_priority = 0; 00974 mp4Header.visual_object_type = 0; 00975 00976 // Video Object 00977 mp4Header.video_object_layer_startcode = 0; 00978 00979 // Video Object Layer 00980 mp4Header.video_object_layer_start_code = 0; 00981 mp4Header.short_video_header = 0; 00982 mp4Header.video_object_layer_id = 0; 00983 mp4Header.random_accessbile_vol = 0; 00984 mp4Header.video_object_type_indication = 0; 00985 mp4Header.is_object_layer_identifier = 0; 00986 mp4Header.video_object_layer_verid = 0; 00987 mp4Header.video_object_layer_priority = 0; 00988 mp4Header.aspectRatio.aspect_ratio_info = 0; 00989 mp4Header.aspectRatio.par_width = 0; 00990 mp4Header.aspectRatio.par_height = 0; 00991 mp4Header.volControlParameters.vol_control_parameters = 0; 00992 mp4Header.volControlParameters.chroma_format = 0; 00993 mp4Header.volControlParameters.low_delay = 0; 00994 mp4Header.volControlParameters.vbv_parameters = 0; 00995 mp4Header.volControlParameters.first_half_bit_rate = 0; 00996 mp4Header.volControlParameters.latter_half_bit_rate = 0; 00997 mp4Header.volControlParameters.first_half_vbv_buffer_size = 0; 00998 mp4Header.volControlParameters.latter_half_vbv_buffer_size = 0; 00999 mp4Header.volControlParameters.first_half_vbv_occupancy = 0; 01000 mp4Header.volControlParameters.latter_half_vbv_occupancy = 0; 01001 mp4Header.video_object_layer_shape = 0; 01002 mp4Header.vop_time_increment_resolution = 0; 01003 mp4Header.vop_time_incrememt_bits_needed = 0; 01004 mp4Header.fixed_vop_rate = 0; 01005 mp4Header.fixed_vop_time_increment = 0; 01006 mp4Header.video_object_layer_width = 0; 01007 mp4Header.video_object_layer_height = 0; 01008 mp4Header.interlaced = 0; 01009 mp4Header.obmc_disable = 0; 01010 mp4Header.sprite_enable = 0; 01011 mp4Header.not_8_bit = 0; 01012 mp4Header.quant_precision = 0; 01013 mp4Header.bits_per_pixel = 0; 01014 mp4Header.no_gray_quant_update = 0; 01015 mp4Header.composition_method = 0; 01016 mp4Header.linear_composition = 0; 01017 mp4Header.quant.load_intra_quant_mat = 0; 01018 mp4Header.quant.load_nonintra_quant_mat = 0; 01019 mp4Header.quant.load_intra_quant_mat_grayscale = 0; 01020 mp4Header.quant.load_nonintra_quant_mat_grayscale = 0; 01021 memcpy(mp4Header.quant.intra_quant_matrix, intra_quant_mat, 01022 sizeof(mp4Header.quant.intra_quant_matrix)); 01023 memcpy(mp4Header.quant.nonintra_quant_matrix, nonintra_quant_mat, 01024 sizeof(mp4Header.quant.nonintra_quant_matrix)); 01025 memcpy(mp4Header.quant.intra_quant_matrix_grayscale, 01026 intra_quant_mat_grayscale, 01027 sizeof(mp4Header.quant.intra_quant_matrix_grayscale)); 01028 memcpy(mp4Header.quant.nonintra_quant_matrix_grayscale, 01029 nonintra_quant_mat_grayscale, 01030 sizeof(mp4Header.quant.nonintra_quant_matrix_grayscale)); 01031 mp4Header.complexity_estimation_disable = 0; 01032 mp4Header.resync_marker_disable = 0; 01033 mp4Header.data_partitioned = 0; 01034 mp4Header.reversible_vlc = 0; 01035 mp4Header.scalability = 0; 01036 } 01037 01038 01039 /***************************************************/ 01040 void MP4Decoder::nextByte() { 01041 mcByte = mpcData[miCurrentNoBytes]; 01042 miCurrentBit = 7; 01043 miCurrentNoBytes++; 01044 if (miCurrentNoBytes > miSize) 01045 mbEOD = true; 01046 } 01047 01048 01049 /***************************************************/ 01050 bool MP4Decoder::bytealigned() { 01051 if (miCurrentBit == 7) 01052 return true; 01053 else 01054 { 01055 nextByte(); 01056 return true; 01057 } 01058 } 01059 01060 01061 /***************************************************/ 01062 int MP4Decoder::getBit() { 01063 int ret = 0; 01064 if (miCurrentBit == -1) 01065 nextByte(); 01066 ret = (mcByte >> miCurrentBit) & 0x01; 01067 miCurrentBit--; 01068 if (mbEOD == false) 01069 return ret; 01070 01071 else 01072 return EOF; 01073 } 01074 01075 01076 /***************************************************/ 01077 int MP4Decoder::getBits(int iNumber) { 01078 int ret = 0; 01079 int i; 01080 for (i = 0; i < iNumber; i++) 01081 ret = (ret << 1) | getBit(); 01082 if (mbEOD == false) 01083 return ret; 01084 01085 else 01086 return EOF; 01087 } 01088 01089 01090 /***************************************************/ 01091 int MP4Decoder::nextBits(int noBits) { 01092 int ret = 0; 01093 bookmark(); 01094 ret = getBits(32); 01095 restore(); 01096 if (mbEOD == false) 01097 return ret; 01098 01099 else 01100 return EOF; 01101 } 01102 01103 01104 /***************************************************/ 01105 void MP4Decoder::nextStartCode() { 01106 while (!bytealigned()) 01107 getBit(); 01108 } 01109 01110 01111 /***************************************************/ 01112 void MP4Decoder::loadQuantizerMatrix(unsigned int puiMatrix[]) { 01113 int i; // row counter 01114 int j; // column counter 01115 int lastValue = 0; 01116 bool readLastValue = false; 01117 for (i = 0; i < 8; i++) { 01118 for (j = 0; j < 8; j++) { 01119 if (!readLastValue) { 01120 puiMatrix[j + i * 8] = getBits(8); 01121 if (puiMatrix[j + i * 8] == 0) 01122 readLastValue = true; 01123 else 01124 lastValue = puiMatrix[j + i * 8]; 01125 } 01126 else 01127 puiMatrix[j + i * 8] = lastValue; 01128 } 01129 } 01130 } 01131 01132 01133 /***************************************************/ 01134 void MP4Decoder::readMarkerBitFunc(int iLine) { 01135 if (getBit() != 1) { 01136 dprintf_small("Marker bit invalid at line %d\n", iLine); 01137 } 01138 } 01139 01140 01141 /***************************************************/ 01142 void MP4Decoder::bookmark() { 01143 miBookmarkedCurrentBit = miCurrentBit; 01144 miBookmarkedByte = mcByte; 01145 miBookmarkedCurrentNoBytes = miCurrentNoBytes; 01146 } 01147 01148 01149 /***************************************************/ 01150 void MP4Decoder::restore() { 01151 miCurrentBit = miBookmarkedCurrentBit; 01152 mcByte = miBookmarkedByte; 01153 miCurrentNoBytes = miBookmarkedCurrentNoBytes; 01154 } 01155 01156 01157 /***************************************************/ 01158 void MP4Decoder::setCoderType(MP4Decoder::eCoderType coderType) { 01159 meCoder = coderType; 01160 } 01161 01162 01163 /***************************************************/ 01164 void MP4Decoder::DecoderClose(char **pDecoderHandle) { 01165 switch (meCoder) { 01166 case (MP4Decoder::XVID): 01167 XVIDDecoderClose(pDecoderHandle); 01168 break; 01169 #ifdef ENABLE_FFMPEG 01170 case (MP4Decoder::FFMPEG): 01171 FFMPEGDecoderClose(pDecoderHandle); 01172 break; 01173 #endif 01174 default: 01175 dprintf_err("Invalid Coder selected\n"); 01176 break; 01177 } 01178 } 01179 01180 01181 /***************************************************/ 01182 int MP4Decoder::DecoderInit(char **pDecoderHandle, CodecID codecID, unsigned int uiWidth, unsigned int uiHeight) { 01183 switch (meCoder) { 01184 case (MP4Decoder::XVID): 01185 return XVIDDecoderInit2(pDecoderHandle, muiWidth, muiHeight); 01186 break; 01187 #ifdef ENABLE_FFMPEG 01188 case (MP4Decoder::FFMPEG): 01189 return FFMPEGDecoderInit(pDecoderHandle, codecID, muiWidth, muiHeight); 01190 break; 01191 #endif 01192 default: 01193 dprintf_err("Invalid Coder selected\n"); 01194 break; 01195 } 01196 01197 return ERR; 01198 } 01199 01200 01201 /***************************************************/ 01202 int MP4Decoder::DecodeFrame(char *pDecoderHandle, char *pCompressedFrame, 01203 int iCFSize, char* pYUVFrame, UncompressedVideoFrame::ColorSpace eColorSpace) { 01204 int ret = 0; 01205 01206 switch (meCoder) { 01207 case (MP4Decoder::XVID): 01208 dprintf_full("Decoding : using XVID\n"); 01209 ret = XVIDDecodeFrame(pDecoderHandle, pCompressedFrame, iCFSize, 01210 pYUVFrame, (xvidColorSpace) mapToXVIDColorspace(eColorSpace)); 01211 break; 01212 #ifdef ENABLE_FFMPEG 01213 case (MP4Decoder::FFMPEG): 01214 dprintf_full("Decoding : using FFMPEG\n"); 01215 ret = FFMPEGDecodeFrame(pDecoderHandle, pCompressedFrame, iCFSize, 01216 pYUVFrame, (ffmpegColorSpace) mapToFFMPEGColorspace(eColorSpace)); 01217 break; 01218 #endif 01219 default: 01220 dprintf_err("Invalid Coder selected\n"); 01221 break; 01222 } 01223 return ret; 01224 } 01225 01226 /***************************************************/ 01227 xvidColorSpace MP4Decoder::mapToXVIDColorspace(UncompressedVideoFrame::ColorSpace colorSpace) { 01228 xvidColorSpace ret = XVIDColorSpaceUnknown; 01229 01230 switch (colorSpace) { 01231 case UncompressedVideoFrame::ColorSpaceYV12: 01232 ret = XVIDColorSpaceYV12; 01233 break; 01234 case UncompressedVideoFrame::ColorSpaceRGB24: 01235 ret = XVIDColorSpaceRGB24; 01236 break; 01237 case UncompressedVideoFrame::ColorSpaceI420: 01238 ret = XVIDColorSpaceI420; 01239 break; 01240 case UncompressedVideoFrame::ColorSpaceRGB32: 01241 ret = XVIDColorSpaceRGB32; 01242 break; 01243 default: 01244 ret = XVIDColorSpaceUnknown; 01245 break; 01246 } 01247 01248 return ret; 01249 } 01250 01251 01252 /***************************************************/ 01253 ffmpegColorSpace MP4Decoder::mapToFFMPEGColorspace(UncompressedVideoFrame::ColorSpace colorSpace) { 01254 ffmpegColorSpace ret = FFMPEGColorSpaceUnknown; 01255 01256 switch (colorSpace) { 01257 case UncompressedVideoFrame::ColorSpaceYV12: 01258 ret = FFMPEGColorSpaceYV12; 01259 break; 01260 case UncompressedVideoFrame::ColorSpaceRGB24: 01261 ret = FFMPEGColorSpaceRGB24; 01262 break; 01263 case UncompressedVideoFrame::ColorSpaceI420: 01264 ret = FFMPEGColorSpaceI420; 01265 break; 01266 case UncompressedVideoFrame::ColorSpaceRGB32: 01267 ret = FFMPEGColorSpaceRGB32; 01268 break; 01269 case UncompressedVideoFrame::ColorSpaceRGB565: 01270 ret = FFMPEGColorSpaceRGB565; 01271 break; 01272 case UncompressedVideoFrame::ColorSpaceGRAY8: 01273 ret = FFMPEGColorSpaceGRAY8; 01274 break; 01275 default: 01276 ret = FFMPEGColorSpaceUnknown; 01277 break; 01278 } 01279 01280 return ret; 01281 } 01282 01283 01284 /***************************************************/ 01285 const char* MP4Decoder::codecToString(CodecID codec_id) { 01286 static const char* txt[]={ 01287 "NONE", 01288 "MPEG1VIDEO", 01289 "MPEG2VIDEO", 01290 "MPEG2VIDEO_XVMC", 01291 "H263", 01292 "RV10", 01293 "RV20", 01294 "MP2", 01295 "MP3", 01296 "VORBIS", 01297 "AC3", 01298 "MJPEG", 01299 "MJPEGB", 01300 "LJPEG", 01301 "SP5X", 01302 "MPEG4", 01303 "RAWVIDEO", 01304 "MSMPEG4V1", 01305 "MSMPEG4V2", 01306 "MSMPEG4V3", 01307 "WMV1", 01308 "WMV2", 01309 "H263P", 01310 "H263I", 01311 "FLV1", 01312 "SVQ1", 01313 "SVQ3", 01314 "DVVIDEO", 01315 "DVAUDIO", 01316 "WMAV1", 01317 "WMAV2", 01318 "MACE3", 01319 "MACE6", 01320 "HUFFYUV", 01321 "CYUV", 01322 "H264", 01323 "INDEO3", 01324 "VP3", 01325 "THEORA", 01326 "AAC", 01327 "MPEG4AAC", 01328 "ASV1", 01329 "ASV2", 01330 "FFV1", 01331 "4XM", 01332 "VCR1", 01333 "CLJR", 01334 "MDEC", 01335 "ROQ", 01336 "INTERPLAY_VIDEO", 01337 "XAN_WC3", 01338 "XAN_WC4", 01339 "RPZA", 01340 "CINEPAK", 01341 "WS_VQA", 01342 "MSRLE", 01343 "MSVIDEO1", 01344 "IDCIN", 01345 "8BPS", 01346 "SMC", 01347 "FLIC", 01348 "TRUEMOTION1", 01349 "VMDVIDEO", 01350 "VMDAUDIO", 01351 "MSZH", 01352 "ZLIB", 01353 "PCM_S16LE", 01354 "PCM_S16BE", 01355 "PCM_U16LE", 01356 "PCM_U16BE", 01357 "PCM_S8", 01358 "PCM_U8", 01359 "PCM_MULAW", 01360 "PCM_ALAW", 01361 "ADPCM_IMA_QT", 01362 "ADPCM_IMA_WAV", 01363 "ADPCM_IMA_DK3", 01364 "ADPCM_IMA_DK4", 01365 "ADPCM_IMA_WS", 01366 "ADPCM_MS", 01367 "ADPCM_4XM", 01368 "ADPCM_XA", 01369 "ADPCM_ADX", 01370 "AMR_NB", 01371 "AMR_WB", 01372 "RA_144", 01373 "RA_288", 01374 "ROQ_DPCM", 01375 "INTERPLAY_DPCM", 01376 "XAN_DPCM", 01377 "MPEG2TS", 01378 "UNKNOWN_CODEC" 01379 }; 01380 01381 if(codec_id>=CODEC_ID_NONE&&codec_id<=CODEC_ID_MPEG2TS) { 01382 return txt[codec_id-CODEC_ID_NONE]; 01383 }//if 01384 else{ 01385 return txt[CODEC_ID_MPEG2TS+1]; 01386 }//else 01387 }//codecToString 01388 01389 01390 /***************************************************/ 01391 int MP4Decoder::stringToCodec(const char* codec_string) { 01392 int i; 01393 01394 static const char* txt[]={ 01395 "NONE", 01396 "MPEG1VIDEO", 01397 "MPEG2VIDEO", 01398 "MPEG2VIDEO_XVMC", 01399 "H263", 01400 "RV10", 01401 "RV20", 01402 "MP2", 01403 "MP3", 01404 "VORBIS", 01405 "AC3", 01406 "MJPEG", 01407 "MJPEGB", 01408 "LJPEG", 01409 "SP5X", 01410 "MPEG4", 01411 "RAWVIDEO", 01412 "MSMPEG4V1", 01413 "MSMPEG4V2", 01414 "MSMPEG4V3", 01415 "WMV1", 01416 "WMV2", 01417 "H263P", 01418 "H263I", 01419 "FLV1", 01420 "SVQ1", 01421 "SVQ3", 01422 "DVVIDEO", 01423 "DVAUDIO", 01424 "WMAV1", 01425 "WMAV2", 01426 "MACE3", 01427 "MACE6", 01428 "HUFFYUV", 01429 "CYUV", 01430 "H264", 01431 "INDEO3", 01432 "VP3", 01433 "THEORA", 01434 "AAC", 01435 "MPEG4AAC", 01436 "ASV1", 01437 "ASV2", 01438 "FFV1", 01439 "4XM", 01440 "VCR1", 01441 "CLJR", 01442 "MDEC", 01443 "ROQ", 01444 "INTERPLAY_VIDEO", 01445 "XAN_WC3", 01446 "XAN_WC4", 01447 "RPZA", 01448 "CINEPAK", 01449 "WS_VQA", 01450 "MSRLE", 01451 "MSVIDEO1", 01452 "IDCIN", 01453 "8BPS", 01454 "SMC", 01455 "FLIC", 01456 "TRUEMOTION1", 01457 "VMDVIDEO", 01458 "VMDAUDIO", 01459 "MSZH", 01460 "ZLIB", 01461 "PCM_S16LE", 01462 "PCM_S16BE", 01463 "PCM_U16LE", 01464 "PCM_U16BE", 01465 "PCM_S8", 01466 "PCM_U8", 01467 "PCM_MULAW", 01468 "PCM_ALAW", 01469 "ADPCM_IMA_QT", 01470 "ADPCM_IMA_WAV", 01471 "ADPCM_IMA_DK3", 01472 "ADPCM_IMA_DK4", 01473 "ADPCM_IMA_WS", 01474 "ADPCM_MS", 01475 "ADPCM_4XM", 01476 "ADPCM_XA", 01477 "ADPCM_ADX", 01478 "AMR_NB", 01479 "AMR_WB", 01480 "RA_144", 01481 "RA_288", 01482 "ROQ_DPCM", 01483 "INTERPLAY_DPCM", 01484 "XAN_DPCM", 01485 "MPEG2TS", 01486 "UNKNOWN_CODEC" 01487 }; 01488 01489 01490 for(i=0;txt[i]!="UNKNOWN_CODEC";i++){ 01491 if(strcmp(txt[i],codec_string)==0){ 01492 return i; 01493 }//if 01494 }//for 01495 01496 return (i-1); 01497 01498 }//stringToCodec 01499 01500 01504 u32 MP4Decoder::getTranscodingCosts() const 01505 { 01506 return (u32)(es->getWidth()*es->getHeight()*es->getFPS()); 01507 }