PSNR.cpp

00001 /*********************************************************************** 00002 * * 00003 * ViTooKi * 00004 * * 00005 * title: PSNR.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 "PSNR.hpp" 00045 #include "UncompressedVideoFrame.hpp" 00046 #include "Statistics.hpp" 00047 #include <float.h> 00048 00049 00050 PSNR::PSNR(VideoESInfo* esi, YUVStreamIO *OrigYUVStream, Statistics *statistics, FILE* psnrFP) { 00051 00052 es = esi; 00053 yuvOrig = OrigYUVStream; 00054 sumPSNR = 0.0; 00055 dummyFrame = NULL; 00056 numFrames = 0; 00057 numFramesNotInf = 0; 00058 lastAU.payload = NULL; 00059 stats = statistics; 00060 strcpy(name,"PSNR"); 00061 assert (yuvOrig->open()); 00062 psnrInfo=psnrFP; 00063 initialized=false; 00064 } 00065 00066 00067 PSNR::~PSNR() { 00068 00069 delete yuvOrig; 00070 if (dummyFrame) { 00071 dummyFrame->unsetAU(); 00072 delete dummyFrame; 00073 } 00074 if(psnrInfo) 00075 fclose(psnrInfo); 00076 } 00077 00078 00079 void PSNR::initialize() { 00080 if(!initialized) { 00081 if(psnrInfo) { 00082 fprintf(psnrInfo,"Second status Orig_CTS Compr_CTS framePSNR thisSecAvgPSNR totalAvgPSNR numFramesPerSec SumNumFrames SumNumFramesNotInfinite\n"); 00083 } 00084 initialized=true; 00085 } 00086 } 00087 00088 00089 /***************************************************************/ 00090 list < Frame * > PSNR::adapt(Frame * frm) { 00091 list < Frame * >tmp; 00092 u32 thisCTS; 00093 double psnr; 00094 int thisSec; 00095 int done=0; 00096 if(!this->initialized) 00097 initialize(); 00098 00099 UncompressedVideoFrame *thisFrame = (UncompressedVideoFrame*)frm; 00100 thisCTS = frm->getAU()->cts; 00101 thisSec = (int)floor((double)thisCTS / es->getMediaTimeScale()); 00102 UncompressedVideoFrame *origFrame; 00103 dprintf_full("PSNR::adapt frame CTS %i, VOP increment %i, playoutSec: %6.3f\n", 00104 thisCTS,es->getVOPTimeIncrement(),stats->getPlayoutSec()); 00105 00106 //first frame, malloc payload, size is always the same for YUV frames! 00107 if (!lastAU.payload) { 00108 dprintf_full("PSNR::adapt creating initial buffers\n"); 00109 lastPayload = (u8*)malloc(thisFrame->getAU()->size); 00110 lastAU.payload = lastPayload; 00111 lastAU.size = thisFrame->getAU()->size; 00112 dummyFrame = new UncompressedVideoFrame(Frame::NN_VOP, thisFrame->getWidth(), thisFrame->getHeight()); 00113 dummyFrame->setMediaTimeScale(thisFrame->getMediaTimeScale()); 00114 dummyFrame->setAU(&lastAU,false); //disable detectFrameType() for efficiency! 00115 } 00116 00117 while(!done) { 00118 numFrames++; 00119 origFrame = (UncompressedVideoFrame *)yuvOrig->getFrame(); 00120 assert(origFrame); 00121 assert(origFrame->getAU()->cts <= thisCTS); 00122 psnr=0; 00123 00124 if (origFrame->getAU()->cts == thisCTS) { //NO FRAME LOSS 00125 psnr = thisFrame->computePSNR(origFrame); 00126 done=1; 00127 } else { //catch up BECAUSE OF FRAME LOSS 00128 psnr = dummyFrame->computePSNR(origFrame); 00129 dprintf_full("PSNR::adapt dummyADAPT!\n"); 00130 } 00131 if (psnr < DBL_MAX) { 00132 numFramesNotInf++; 00133 sumPSNR+=psnr; 00134 stats->incPlayoutSecPSNR(thisSec, psnr); 00135 } 00136 00137 if (done) { 00138 dprintf_full("PSNR::adapt: (sec %i), origFrame CTS %8i thisFrame CTS %8i: thisPSNR %3.3f thisSecAvgPSNR %3.3f thisSecFPS %i overallPSNR %3.3f\n", 00139 thisSec, origFrame->getAU()->cts, thisCTS, psnr, 00140 stats->getPlayoutSecPSNR(thisSec), stats->getPlayoutSecFPS(thisSec), 00141 sumPSNR/numFramesNotInf); 00142 } else { 00143 dprintf_full("PSNR::adapt: (sec %i), origFrame CTS %8i dummyFrame CTS %8i: thisPSNR %3.3f thisSecAvgPSNR %3.3f thisSecFPS %i overallPSNR %3.3f\n", 00144 thisSec, origFrame->getAU()->cts, dummyFrame->getAU()->cts, psnr, 00145 stats->getPlayoutSecPSNR(thisSec), stats->getPlayoutSecFPS(thisSec), 00146 sumPSNR/numFramesNotInf); 00147 } 00148 00149 if(psnrInfo) { 00150 fprintf(psnrInfo,"%8i %s %8i %8i %6.3f %6.3f %6.3f %8i %8i %8i\n", 00151 thisSec, done?"OK ":"DROP", origFrame->getAU()->cts, done?thisCTS:dummyFrame->getAU()->cts, psnr, 00152 stats->getPlayoutSecPSNR(thisSec), sumPSNR/numFramesNotInf, 00153 stats->getPlayoutSecFPS(thisSec), numFrames, numFramesNotInf); 00154 } 00155 delete origFrame; 00156 } 00157 00158 00159 assert(lastAU.size == thisFrame->getAU()->size); 00160 dummyFrame->unsetAU(); 00161 lastAU = thisFrame->getAU(); 00162 lastAU.payload = lastPayload; 00163 lastAU.size = thisFrame->getAU()->size; 00164 memcpy(lastAU.payload, thisFrame->getAU()->payload, thisFrame->getAU()->size); 00165 dummyFrame->setAU(&lastAU,false); //disable detectFrameType() for efficiency! 00166 00167 //standard forwarding adaptor behaviour 00168 tmp.push_front(frm); 00169 return tmp; 00170 }