YUVScalingAdaptor.cpp

00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: YUVScalingAdaptor.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 "YUVScalingAdaptor.hpp" 00045 #include "UncompressedVideoFrame.hpp" 00046 #include "string.h" 00047 #include "math.h" 00048 00049 00050 /****************************************************/ 00051 YUVScalingAdaptor::YUVScalingAdaptor(VideoESInfo * pESInfo, 00052 u32 width, 00053 u32 height) 00054 { 00055 es = pESInfo; 00056 initialized = false; 00057 muiTargetWidth = width; 00058 muiTargetHeight = height; 00059 strcpy(name,"YUVScalingAdaptor"); 00060 initialize(); 00061 } 00062 00063 00064 /****************************************************/ 00065 void YUVScalingAdaptor::initialize() { 00066 00067 muiWidth = es->getWidth(); 00068 muiHeight = es->getHeight(); 00069 00070 00071 //FIXME: this should go into the out_es (all ViTooKi Adaptors should have this....) 00072 // es->setWidth(muiTargetWidth); 00073 //es->setHeight(muiTargetHeight); 00074 00075 muiScaleFactorWidth = (u32) ((muiTargetWidth * 1000000) / muiWidth) ; 00076 muiScaleFactorHeight = (u32)((muiTargetHeight* 1000000) / muiHeight) ; 00077 initialized = true; 00078 00079 dprintf_full("YUVScalingAdaptor::initialize %ix%i --> %ix%i Scalefactors [w|h]: [%i|%i]\n", 00080 muiWidth,muiHeight,muiTargetWidth,muiTargetHeight,muiScaleFactorWidth, muiScaleFactorHeight); 00081 } 00082 00083 00084 00085 /****************************************************/ 00086 YUVScalingAdaptor::~YUVScalingAdaptor() { 00087 } 00088 00089 00090 /****************************************************/ 00091 list < Frame * > YUVScalingAdaptor::adapt(Frame * frm) { 00092 list < Frame * >retFrameList; 00093 UncompressedVideoFrame* ufrm = (UncompressedVideoFrame*)frm; 00094 00095 if ( ((u32)ufrm->getWidth() != muiWidth) 00096 || ((u32)ufrm->getHeight() != muiHeight) ) { 00097 //resolution has changed because of stream switching 00098 initialize(); 00099 } 00100 00101 if (ufrm->getType() != Frame::YUV_VOP) { 00102 dprintf_err("YUVScalingAdaptor::adapt does only support YUV frames!\n"); 00103 ::exit(1); 00104 } 00105 00106 //to be save on switching, always set ES dimensions 00107 //not anymore: FIXME: this should go into the out_es (all ViTooKi Adaptors should have this....) 00108 // es->setWidth(muiTargetWidth); 00109 //es->setHeight(muiTargetHeight); 00110 00111 dprintf_full("YUVScalingAdaptor::adapt %ix%i --> %ix%i\n", muiWidth,muiHeight,muiTargetWidth,muiTargetHeight); 00112 00113 if ( (muiWidth == muiTargetWidth) && (muiHeight == muiTargetHeight) ) { 00114 retFrameList.push_back(frm); //same size, so leave untouched 00115 return retFrameList; 00116 } 00117 00118 u32 h, w, hOrig, wOrig; 00119 u8 *pOffsetTarget=NULL; 00120 u8 *pOffsetOrig=NULL; 00121 00122 u8 *origFrame = frm->getAU()->payload; 00123 pOffsetOrig = origFrame; 00124 00125 00126 u8 *retFrame = new u8[muiTargetWidth * muiTargetHeight * 3 / 2]; 00127 // memset(retFrame, 128, muiTargetWidth * muiTargetHeight * 3 / 2); 00128 pOffsetTarget = retFrame; 00129 00130 00131 // Y 00132 for (h = 0; h < muiTargetHeight; h++) { 00133 for (w = 0; w < muiTargetWidth; w++) { 00134 hOrig = (u32) ((h * 1000000) / muiScaleFactorHeight); 00135 wOrig = (u32) ((w * 1000000) / muiScaleFactorWidth); 00136 pOffsetTarget[h * muiTargetWidth + w] = pOffsetOrig[hOrig * muiWidth + wOrig]; 00137 } 00138 } 00139 // V 00140 pOffsetOrig = pOffsetOrig + muiWidth * muiHeight; 00141 pOffsetTarget = pOffsetTarget + muiTargetWidth * muiTargetHeight; 00142 for (h = 0; h < muiTargetHeight / 2; h++) { 00143 for (w = 0; w < muiTargetWidth / 2; w++) { 00144 hOrig = (u32) ((h * 1000000) / muiScaleFactorHeight); 00145 wOrig = (u32) ((w * 1000000) / muiScaleFactorWidth); 00146 pOffsetTarget[h * muiTargetWidth / 2 + w] = pOffsetOrig[hOrig * muiWidth / 2 + wOrig]; 00147 } 00148 } 00149 // U 00150 pOffsetOrig = pOffsetOrig + muiWidth * muiHeight / 4; 00151 pOffsetTarget = pOffsetTarget + muiTargetWidth * muiTargetHeight / 4; 00152 for (h = 0; h < muiTargetHeight / 2; h++) { 00153 for (w = 0; w < muiTargetWidth / 2; w++) { 00154 hOrig = (u32) ((h * 1000000) / muiScaleFactorHeight); 00155 wOrig = (u32) ((w * 1000000) / muiScaleFactorWidth); 00156 pOffsetTarget[h * muiTargetWidth / 2 + w] = pOffsetOrig[hOrig * muiWidth / 2 + wOrig]; 00157 } 00158 } 00159 00160 ufrm->setWidth(muiTargetWidth); 00161 ufrm->setHeight(muiTargetHeight); 00162 frm->getAU()->payload = retFrame; 00163 frm->getAU()->size = muiTargetWidth * muiTargetHeight * 3 / 2; // YV12 00164 retFrameList.push_back(frm); 00165 delete origFrame; // not needed any more 00166 00167 return retFrameList; 00168 } 00169 00170 00171 /****************************************************/ 00172 list < Frame * >YUVScalingAdaptor::close() { 00173 list < Frame * >retFrameList; 00174 00175 return retFrameList; 00176 } 00177 00178 00179 00180 /****************************************************/ 00181 Adaptor *YUVScalingAdaptor::clone() { 00182 return new YUVScalingAdaptor(es,muiTargetWidth,muiTargetHeight); 00183 } 00184