Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members
AdaptorChain.cpp
00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: AdaptorChain.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 00045 #include "AdaptorChain.hpp" 00046 #include "UncompressedVideoFrame.hpp" 00047 00048 AdaptorChain::AdaptorChain() 00049 { 00050 initialized = false; 00051 strcpy(name,"AdaptorChain"); 00052 } 00053 00054 00055 AdaptorChain::~AdaptorChain() 00056 { 00057 dprintf_full("AdaptorChain::~AdaptorChain()\n"); 00058 list < Adaptor * >::iterator adaptorIterator; 00059 for (adaptorIterator = mAdaptorList.begin(); 00060 adaptorIterator != mAdaptorList.end(); adaptorIterator++) { 00061 if (*adaptorIterator != NULL) 00062 delete *adaptorIterator; 00063 } 00064 00065 } 00066 00067 00068 void AdaptorChain::initialize() 00069 { 00070 list < Adaptor * >::iterator adaptorIterator; 00071 00072 initialized = true; 00073 for (adaptorIterator = mAdaptorList.begin(); 00074 adaptorIterator != mAdaptorList.end(); adaptorIterator++) { 00075 (*adaptorIterator)->initialize(); 00076 } 00077 }; 00078 00079 00080 list < Frame * >AdaptorChain::close() 00081 { 00082 list < Frame * >l; 00083 list < Adaptor * >::iterator adaptorIterator; 00084 list < Frame * >::iterator li; 00085 for (adaptorIterator = mAdaptorList.begin(); 00086 adaptorIterator != mAdaptorList.end(); adaptorIterator++) { 00087 int size = l.size(); 00088 00089 // feed all from l into the next adaptor 00090 // and store the returned results at the end of l 00091 while (size > 0) { 00092 li = l.begin(); 00093 list < Frame * >l2 = (*adaptorIterator)->adapt(*li); 00094 00095 if( (*li) != (*(l2.begin())) ) 00096 delete (*li); 00097 list < Frame * >::iterator li2; 00098 while (!l2.empty()) { 00099 li2 = l2.begin(); 00100 l.push_back(*li2); 00101 l2.pop_front(); 00102 } 00103 l.pop_front(); // remove the first element, which is already adapted 00104 --size; 00105 } 00106 // after we have sent all frames returned from the previous close, 00107 // close this adaptor so that it is guaranteed empty 00108 list < Frame * >l2 = (*adaptorIterator)->close(); 00109 list < Frame * >::iterator li2; 00110 while (!l2.empty()) { 00111 li2 = l2.begin(); 00112 l.push_back(*li2); 00113 l2.pop_front(); 00114 } 00115 } 00116 return l; 00117 } 00118 00119 00120 list < Frame * >AdaptorChain::adapt(Frame * frm) 00121 { 00122 list < Frame * >*inFrameList=NULL; 00123 list < Frame * >*outFrameList=NULL; 00124 list < Frame * >retFrameList; 00125 list < Adaptor * >::iterator adaptorIterator; 00126 Adaptor *adaptor=NULL; 00127 Frame *frame=NULL; 00128 Frame *tmpFrame=NULL; 00129 00130 if (!initialized) 00131 initialize(); 00132 00133 dprintf_full("AdaptorChain::adapt Input Frame is %p\n",frm); 00134 00135 if (!initialized) { 00136 list<Frame*> tmp; 00137 return tmp; 00138 } 00139 00140 inFrameList = new list < Frame * >; 00141 outFrameList = new list < Frame * >; 00142 inFrameList->push_back(frm); 00143 00144 for (adaptorIterator = mAdaptorList.begin(); 00145 adaptorIterator != mAdaptorList.end(); adaptorIterator++) { 00146 adaptor = *adaptorIterator; 00147 //dprintf_full("AdaptorChain::adapt will use sub-adaptor %s\n",adaptor->getName()); 00148 00149 // WARNING: 00150 // we never delete input frames 00151 // only intermediate frames created by an adaptor are deleted 00152 frame=NULL; 00153 while (!inFrameList->empty()) { 00154 frame = inFrameList->front(); 00155 //dprintf_full("AdaptorChain::adapt getting from inList Frame %p\n",frame); 00156 00157 retFrameList = adaptor->adapt(frame); 00158 tmpFrame=NULL; 00159 while (!retFrameList.empty()) { 00160 tmpFrame=retFrameList.front(); 00161 retFrameList.pop_front(); 00162 //dprintf_full("AdaptorChain::adapt getting adaptation result Frame %p\n",tmpFrame); 00163 outFrameList->push_back(tmpFrame); 00164 if(frame && frame!=tmpFrame && frame!=frm) { 00165 dprintf_full("AdaptorChain::adapt deleting Frame %p\n",frame); 00166 delete frame; 00167 frame=NULL; 00168 } 00169 } 00170 if(frame && frame!=tmpFrame && frame!=frm) { 00171 // caching adaptors have to deep-copy 00172 dprintf_full("AdaptorChain::adapt deleting cached Frame %p\n",frame); 00173 delete frame; 00174 frame=NULL; 00175 } 00176 inFrameList->pop_front(); 00177 } 00178 delete inFrameList; 00179 00180 // moving to next adaptor, outFrameList is going to be the new inFrameList 00181 inFrameList = outFrameList; 00182 outFrameList = new list < Frame * >; 00183 } 00184 00185 delete outFrameList; 00186 list<Frame*> resultList=*inFrameList; 00187 00188 delete inFrameList; 00189 return resultList; 00190 } 00191 00192 00193 bool AdaptorChain::addAdaptor(Adaptor * pAdaptor) 00194 { 00195 // Some tricky check if inserting pAdaptor creates 00196 // a valid chain should be done here! 00197 mAdaptorList.push_back(pAdaptor); 00198 return true; 00199 } 00200 00201 00203 bool AdaptorChain::pushFrontAdaptor(Adaptor * pAdaptor){ 00204 mAdaptorList.push_front(pAdaptor); 00205 return true; 00206 } 00207 00208 00210 u32 AdaptorChain::getTranscodingCosts() const 00211 { 00212 std::list < Adaptor * >::const_iterator adaptorIterator; 00213 u32 sumC=0u; 00214 for (adaptorIterator = mAdaptorList.begin(); 00215 adaptorIterator != mAdaptorList.end(); 00216 adaptorIterator++) { 00217 00218 if (*adaptorIterator != NULL) { 00219 sumC+=(*adaptorIterator)->getTranscodingCosts(); 00220 } 00221 } 00222 return sumC; 00223 } 00224