DataSink.cpp

00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: DataSink.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 "DataSink.hpp" 00045 #include "adaptors/Forwarder.hpp" 00046 00047 DataSink::DataSink(u32 id, IO * out, const char *addr, int prt, 00048 Adaptor * adaptor) { 00049 // try to set the address 00050 // if this fails we have a name not an ip-address 00051 // perform a dns lookup, but don't use qt -> signals 00052 if (addr) { 00053 adr = new char[strlen(addr) + 1]; 00054 strcpy(adr, addr); 00055 } else { 00056 adr = NULL; 00057 } 00058 if (adaptor == NULL) 00059 localAdaptor = new Forwarder(); 00060 else 00061 localAdaptor = adaptor; 00062 port = prt; 00063 output = out; 00064 lastFrm = NULL; 00065 clientId=id; 00066 } 00067 00068 00069 DataSink::~DataSink() { 00070 dprintf_full("DataSink::Destructor\n"); 00071 if (output) { 00072 if (output->getState() != IO::CLOSED) 00073 output->close(true); 00074 if(output->running()) 00075 output->wait(); 00076 delete output; 00077 } 00078 if (adr) 00079 delete[] adr; 00080 if(localAdaptor) { 00081 dprintf_full("DataSink::~DataSink() deleting %s\n", localAdaptor->getName()); 00082 delete localAdaptor; 00083 } 00084 } 00085 00086 00087 const char *DataSink::getAddress() const { 00088 return adr; 00089 } 00090 00091 00092 bool DataSink::send(Frame * frm) { 00093 #ifdef VITOOKI_DEBUG 00094 double start_dtime, now_dtime; 00095 struct timeval now_tv; 00096 #endif 00097 00098 lastFrm = frm; 00099 bool retVal = true; 00100 if (output) { 00101 assert(frm != NULL); 00102 assert(frm->getAU() != NULL); 00103 dprintf_full("DataSink::send: Output is set at client. Got frame with CTS %i prio %i size %i\n", 00104 frm->getAU()->cts, frm->getAU()->prio, frm->getAU()->size); 00105 if (output->getState() != IO::OPEN && 00106 output->getState() != IO::MUTED && 00107 output->getState() != IO::PAUSED) 00108 output->open(); 00109 //first, output should always be set to IO::OPEN 00110 if (output->getState() != IO::OPEN && 00111 output->getState() != IO::MUTED && 00112 output->getState() != IO::PAUSED) { 00113 dprintf_err("DataSink::send: State = %i failed to open OUTPUT\n", output->getState()); 00114 return false; 00115 } 00116 00117 00118 if (output->getState() != IO::MUTED) { 00119 // everything ok, 00120 // now adapt the data 00121 00122 #ifdef VITOOKI_DEBUG 00123 gettimeofday(&now_tv,NULL); 00124 start_dtime = now_tv.tv_sec + now_tv.tv_usec/1000000.0; 00125 #endif 00126 00127 list < Frame * >fr; 00128 fr = localAdaptor->adapt(frm); 00129 00130 #ifdef VITOOKI_DEBUG 00131 gettimeofday(&now_tv,NULL); 00132 now_dtime = now_tv.tv_sec + now_tv.tv_usec/1000000.0; 00133 00134 if (localAdaptor != NULL) 00135 dprintf_full("DataSink::send(): local adaptation (%s) worked for %2.0f msecs\n",localAdaptor->getName(), 00136 (now_dtime-start_dtime)*1000.0); 00137 #endif 00138 00139 list < Frame * >::iterator fI; 00140 while (!fr.empty()) { 00141 // now write the data 00142 fI = fr.begin(); 00143 int i = output->writeFrame((*fI)); 00144 if (*fI != frm) 00145 delete *fI; 00146 fr.pop_front(); 00147 if (i <= 0) { 00148 dprintf_small("DataSink: Failed to write frame? %i\n", i); 00149 retVal = false; 00150 } 00151 } 00152 }//not MUTED 00153 else { 00154 //completely ignore frame, since no output could handle still encoded frame! 00155 /* 00156 // give the un-adapted frame to output, so CTS might still be 00157 //used for synchronization, but the frame cannot be viewed!!! 00158 int i = output->writeFrame(frm); 00159 //still encoded frm will deleted within DataChannel 00160 if (i <= 0) { 00161 dprintf_small("DataSink: Failed to write muted frame? %i\n", i); 00162 retVal = false; 00163 } 00164 */ 00165 } 00166 00167 return retVal; 00168 } 00169 return false; // no output is set 00170 } 00171 00172 00174 bool DataSink::close(bool immediate) { 00175 list < Frame * >lFrm2 = localAdaptor->close(); 00176 list < Frame * >::iterator lFrm2I; 00177 int i; 00178 00179 dprintf_full("DataSink::close\n"); 00180 while (!lFrm2.empty()) { 00181 lFrm2I = lFrm2.begin(); 00182 if (output && !immediate) { 00183 i = output->writeFrame((*lFrm2I)); 00184 } 00185 if (*lFrm2I != lastFrm) 00186 delete *lFrm2I; 00187 lFrm2.pop_front(); 00188 } 00189 if (output) 00190 return output->close(immediate); 00191 return false; 00192 } 00193 00194 00195 void DataSink::pauseOutput() { 00196 if (output) 00197 output->pause(); 00198 } 00199 00200 00201 void DataSink::playOutput(double prefetch) { 00202 if (output) 00203 output->play(prefetch); 00204 } 00205 00206 00207 void DataSink::muteOutput() { 00208 if (output) 00209 output->mute(); 00210 }