FrameRotate.cpp

00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: FrameRotate.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 #include "FrameRotate.hpp" 00045 00046 00047 void FrameRotate::setESInfo(ESInfo * esi) 00048 { 00049 es = (VideoESInfo*)esi; 00050 // FIXME??? 00051 // initialized=false; 00052 } 00053 00054 00055 ESInfo *FrameRotate::getESInfo() 00056 { 00057 return es; 00058 } 00059 00060 /***********************************************/ 00061 FrameRotate::FrameRotate(VideoESInfo * pESInfo, u32 degrees) 00062 { 00063 es = pESInfo; 00064 strcpy(name,"FrameRotate"); 00065 initialized = false; 00066 this->degrees = degrees; 00067 switch (degrees) { 00068 case 90: 00069 case 270: 00070 muiTargetWidth = es->getHeight(); 00071 muiTargetHeight = es->getWidth(); 00072 break; 00073 case 180: //mirror 00074 case 360: //ignore and bypass 00075 muiTargetWidth = es->getWidth(); 00076 muiTargetHeight = es->getHeight(); 00077 break; 00078 default: 00079 dprintf_full("FrameRotate: rotating %i degrees is not supported!\n",degrees); 00080 ::exit(1); 00081 break; 00082 } 00083 00084 // initialize(); 00085 } 00086 00087 00088 00089 /***********************************************/ 00090 void FrameRotate::initialize() { 00091 00092 muiWidth = es->getWidth(); 00093 muiHeight = es->getHeight(); 00094 00095 es->setWidth(muiTargetWidth); 00096 es->setHeight(muiTargetHeight); 00097 00098 initialized = true; 00099 00100 dprintf_full("FrameRotate::initialize %ix%i --> %ix%i rotate %i degrees\n", 00101 muiWidth, muiHeight, muiTargetWidth, muiTargetHeight, degrees); 00102 } 00103 00104 00105 00106 /***********************************************/ 00107 FrameRotate::~FrameRotate() { 00108 } 00109 00110 00111 /***********************************************/ 00112 list < Frame * > FrameRotate::adapt(Frame * frm) { 00113 list < Frame * >retFrameList; 00114 00115 UncompressedVideoFrame* ufrm = (UncompressedVideoFrame*)frm; 00116 dprintf_full("FrameRotate::adapt frame %ix%i\n",(u32)ufrm->getWidth(),(u32)ufrm->getHeight() ); 00117 if ( !initialized || ((u32)ufrm->getWidth() != muiWidth) 00118 || ((u32)ufrm->getHeight() != muiHeight) ) { 00119 //resolution has changed because of stream switching 00120 initialize(); 00121 } 00122 00123 //to be save on switching, always set ES dimensions 00124 es->setWidth(muiTargetWidth); 00125 es->setHeight(muiTargetHeight); 00126 00127 dprintf_full("FrameRotate::adapt %ix%i --> %ix%i rotate %i degrees\n", 00128 muiWidth,muiHeight,muiTargetWidth,muiTargetHeight,degrees); 00129 00130 if ( degrees == 360 ) { 00131 retFrameList.push_back(frm); //same size, so leave untouched 00132 return retFrameList; 00133 } 00134 00135 00136 register u8 *origFrame = frm->getAU()->payload; 00137 register u8 *retFrame = new u8[frm->getAU()->size]; 00138 register int w = ufrm->getWidth(); 00139 register int h = ufrm->getHeight(); 00140 register int w2 = muiTargetWidth; 00141 register int h2 = muiTargetHeight; 00142 register int x=0,y=0; 00143 register u8 *p = retFrame; 00144 register u8 bpp = UncompressedVideoFrame::mapColorSpaceToBitDepth(ufrm->getColorSpace())/8; 00145 register u32 value; 00146 register u32 pitch = w*bpp; 00147 register u32 pitch2 = w2*bpp; 00148 00149 // memset(retFrame,0,frm->getAU()->size); 00150 // assert(ufrm->getAU()->size == w * h * bpp); 00151 switch (degrees) { 00152 case 90: // 90 degrees //////////////////////////////////////////// 00153 for (x=0; x < w; x++) { 00154 for (y=h-1; y >= 0; y--) { 00155 value = *(u32*)((u8*)(origFrame)+y*pitch + x*bpp); 00156 00157 switch (ufrm->getColorSpace()) { 00158 case UncompressedVideoFrame::ColorSpaceGRAY8: //1 byte 00159 *(u8*)p = value; 00160 break; 00161 case UncompressedVideoFrame::ColorSpaceRGB565: //2 byte 00162 //assume little endian 00163 p[0] = value & 0xff; 00164 p[1] = (value >> 8) & 0xff; 00165 break; 00166 case UncompressedVideoFrame::ColorSpaceRGB24: //3 byte 00167 //assume little endian 00168 p[0] = value & 0xff; 00169 p[1] = (value >> 8) & 0xff; 00170 p[2] = (value >> 16) & 0xff; 00171 break; 00172 case UncompressedVideoFrame::ColorSpaceRGB32: //4 byte 00173 *(u32*)p = value; 00174 break; 00175 case UncompressedVideoFrame::ColorSpaceYV12: 00176 case UncompressedVideoFrame::ColorSpaceI420: 00177 *(u8*)p = value; // Y component 00178 break; 00179 default: 00180 dprintf_err("FrameRotate::adapt: invalid color space: %d\n", ufrm->getColorSpace()); 00181 ::exit(1); 00182 } 00183 p++; 00184 } 00185 } 00186 00187 //for YUV, write U and V component 00188 if ( (ufrm->getColorSpace() == UncompressedVideoFrame::ColorSpaceYV12) || 00189 (ufrm->getColorSpace() == UncompressedVideoFrame::ColorSpaceI420) ) { 00190 u8 *ofrm = origFrame; 00191 u8 *rfrm = retFrame; 00192 ofrm += pitch*h; 00193 rfrm += pitch2*h2; 00194 p = rfrm; 00195 pitch /= 2; 00196 pitch2 /= 2; 00197 for (int i=0; i<2; i++) { // U or V component 00198 for (x=0; x < w/2; x++) { 00199 for (y=(h/2)-1; y >= 0; y--) { 00200 value = *(u32*)((u8*)(ofrm)+y*pitch + x); 00201 *(u8*)p++ = value; 00202 } 00203 } 00204 ofrm += (pitch*h)/2; 00205 rfrm += (pitch2*h2)/2; 00206 00207 } 00208 } 00209 00210 break; 00211 case 180: // 180 degrees //////////////////////////////////////////// 00212 case 270: // 270 degrees //////////////////////////////////////////// 00213 // case 360: //catched above! 00214 default: 00215 dprintf_err("Sorry, rotating by %i degrees not (yet) supported....\n",degrees); 00216 ::exit(1); 00217 break; 00218 } 00219 00220 00221 00222 00223 00224 frm->getAU()->payload = retFrame; 00225 frm->getAU()->size = frm->getAU()->size; 00226 retFrameList.push_back(frm); 00227 delete origFrame; // not needed any more 00228 00229 return retFrameList; 00230 } 00231 00232 00233 Adaptor *FrameRotate::clone() { 00234 return new FrameRotate(es, degrees); 00235 } 00236