timgfilterpostproc.cpp

来自「从FFMPEG转换而来的H264解码程序,VC下编译..」· C++ 代码 · 共 1,961 行 · 第 1/5 页

CPP
1,961
字号
/*
 * Copyright (c) 2002-2006 Milan Cutka
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "stdafx.h"
#include "TimgFilterPostproc.h"
#include "TpostprocSettings.h"
#include "Tlibmplayer.h"
#include "TvideoCodec.h"
#include "IffdshowBase.h"
#include "IffdshowDecVideo.h"
#include "Tconfig.h"
#include "nic/nic_postProcess.h"
#include "libavcodec/avcodec.h"
#include "ffdebug.h"

//============================== TimgFilterPostprocBase =============================
const unsigned int TimgFilterPostprocBase::quantsDx=128*2;
const unsigned int TimgFilterPostprocBase::quantsDy= 96*2;

TimgFilterPostprocBase::TimgFilterPostprocBase(IffdshowBase *Ideci,Tfilters *Iparent,bool Ih264):
 TimgFilter(Ideci,Iparent),
 h264(Ih264),testh264(true),oldh264mode(-1),
 wasIP(false),
 oldDeblockStrength(UINT_MAX),
 quants((int8_t*)aligned_calloc(quantsDx,quantsDy))
{
}
TimgFilterPostprocBase::~TimgFilterPostprocBase()
{
 aligned_free(quants);
}

bool TimgFilterPostprocBase::pp_codec(int CodecID)
{
  if(raw_codec(CodecID))
    return true;
	switch (CodecID) {
		case CODEC_ID_MPEG1VIDEO:
		case CODEC_ID_MPEG2VIDEO:
		case CODEC_ID_LIBMPEG2:
		case CODEC_ID_MPEG4:
		case CODEC_ID_MSMPEG4V1:
		case CODEC_ID_MSMPEG4V2:
		case CODEC_ID_MSMPEG4V3:
		case CODEC_ID_H263:
		case CODEC_ID_SVQ1:
		case CODEC_ID_FLV1:
		case CODEC_ID_INDEO2:
		case CODEC_ID_INDEO3:
		case CODEC_ID_XVID4:
		case CODEC_ID_MJPEG:
		case CODEC_ID_MJPEGB:
		case CODEC_ID_MSVIDEO1:
		case CODEC_ID_CINEPAK:
		case CODEC_ID_VP5:
		case CODEC_ID_VP6:
			return true;
		default: return false;
	}
}

int TimgFilterPostprocBase::prepare(const TpostprocSettings *cfg,int maxquant,int frametype)
{
 const TvideoCodecDec *movie=NULL;
 if (!pp_codec(deci->getCurrentCodecId2()))
 return 0;
 currentq=0;
 if (!cfg->isCustom && cfg->autoq && cfg->qual)
  {
   currentq=deci->getParam2(IDFF_currentq);
   #if 1
   int cpuusage=deci->getCpuUsageForPP();
   #else
   int64_t late;deciV->getLate(&late);
   DPRINTF(_l("late:%I64i"),late);
   int cpuusage=late>100*10000LL?91:0;
   #endif
   if (cpuusage>90 && deciV->getQueuedCount()<8)
    {
     if (currentq>0) currentq--;
    }
   else
    {
     if (currentq<cfg->qual) currentq++;
    }
   deci->putParam(IDFF_currentq,currentq);
  }
 else
  deci->putParam(IDFF_currentq,currentq=cfg->qual);
 //DPRINTF("currentq: %i",currentq);
 int ppmode=Tlibmplayer::getPPmode(cfg,currentq);
 if (!ppmode) return ppmode;
 unsigned int deblockStrength=cfg->deblockStrength;
 if (!movie) deciV->getMovieSource(&movie);
 if (!movie || !movie->quants)
  {
   oldDeblockStrength=deblockStrength;
   unsigned char *quant=(unsigned char *)quants;
   for (unsigned int i=0;i<quantsDx*quantsDy;quant+=1,i++)
    {
     int q=((maxquant/2)*deblockStrength)>>8;
     *quant=(unsigned char)limit(q,1,maxquant);
    }
  }
 else
  if (!wasIP || (frametype&FRAME_TYPE::typemask)!=FRAME_TYPE::B)
   {
    wasIP=true;
    const unsigned char *quantsMovie=(const unsigned char*)movie->quants;
    unsigned int quantsDxMovie=movie->quantsDx;
    unsigned int quantsDyMovie=movie->quantsDy;
    unsigned int quantsStrideMovie=movie->quantsStride;
    unsigned int quantBytesMovie=movie->quantBytes;
    int8_t *quants2=quants;
    for (unsigned int y=0;y<quantsDyMovie;quantsMovie+=quantBytesMovie*quantsStrideMovie,quants2+=quantsDx,y++)
     {
      const unsigned char *quantsMovieln=quantsMovie;
      int8_t *quants2ln=quants2;
      for (unsigned int x=0;x<quantsDxMovie;quantsMovieln+=quantBytesMovie,quants2ln++,x++)
       {
        int q=(*quantsMovieln*deblockStrength)>>8;
        if (movie->quantType==FF_QSCALE_TYPE_MPEG2) q>>=1;
        *quants2ln=(unsigned char)limit(q,1,maxquant);
       }
     }
   }
 return ppmode;
}

void TimgFilterPostprocBase::onSeek(void)
{
 testh264=true;wasIP=false;
}

//============================ TimgFilterPostprocMplayer ============================
TimgFilterPostprocMplayer::TimgFilterPostprocMplayer(IffdshowBase *Ideci,Tfilters *Iparent):TimgFilterPostprocBase(Ideci,Iparent,false)
{
 libmplayer=NULL;
 pp_ctx=NULL;Tlibmplayer::pp_mode_defaults(pp_mode);
}
TimgFilterPostprocMplayer::~TimgFilterPostprocMplayer()
{
 if (libmplayer) libmplayer->Release();
}

void TimgFilterPostprocMplayer::done(void)
{
 if (pp_ctx) libmplayer->pp_free_context(pp_ctx);pp_ctx=NULL;
}
void TimgFilterPostprocMplayer::onSizeChange(void)
{
 done();
}

bool TimgFilterPostprocMplayer::is(const TffPictBase &pict,const TfilterSettingsVideo *cfg0)
{
 const TpostprocSettings *cfg=(const TpostprocSettings*)cfg0;
 if (super::is(pict,cfg) && Tlibmplayer::getPPmode(cfg,cfg->qual))
  {
   Trect r=pict.getRect(cfg->full,cfg->half);
   return pictRect.dx>=16 && pictRect.dy>=16;
  }
 else
  return false;
}

HRESULT TimgFilterPostprocMplayer::process(TfilterQueue::iterator it,TffPict &pict,const TfilterSettingsVideo *cfg0)
{
 const TpostprocSettings *cfg=(const TpostprocSettings*)cfg0;
 if (int ppmode=prepare(cfg,31,0))
  {
   init(pict,cfg->full,cfg->half);
   if (pictRect.dx>=16 && pictRect.dy>=16)
    {
     bool cspChanged=false;
     const unsigned char *tempPict1[4];
     cspChanged|=getCur(FF_CSPS_MASK_YUV_PLANAR,pict,cfg->full,tempPict1);
     unsigned char *tempPict2[4];
     cspChanged|=getNext(csp1,pict,cfg->full,tempPict2);
     if (cspChanged) done();

     if (!pp_ctx)
      {
       if (!libmplayer) deci->getPostproc(&libmplayer);
       pp_ctx=libmplayer->pp_get_context(dx1[0],dy1[0],Tlibmplayer::ppCpuCaps(csp1));
      }
     pp_mode.lumMode=ppmode&15;
     pp_mode.chromMode=(ppmode>>4)&15;
     if (cfg->deblockMplayerAccurate)
      {
       pp_mode.baseDcDiff=128;
       pp_mode.flatnessThreshold=7;
       if (pp_mode.lumMode&H_DEBLOCK) pp_mode.lumMode=(pp_mode.lumMode&~H_DEBLOCK)|H_A_DEBLOCK;
       if (pp_mode.lumMode&V_DEBLOCK) pp_mode.lumMode=(pp_mode.lumMode&~V_DEBLOCK)|V_A_DEBLOCK;
       if (pp_mode.chromMode&H_DEBLOCK) pp_mode.chromMode=(pp_mode.chromMode&~H_DEBLOCK)|H_A_DEBLOCK;
       if (pp_mode.chromMode&V_DEBLOCK) pp_mode.chromMode=(pp_mode.chromMode&~V_DEBLOCK)|V_A_DEBLOCK;
      }
     else
      {
       pp_mode.baseDcDiff=256/8;
       pp_mode.flatnessThreshold=56-16-1;
      }

     if (pp_mode.lumMode&LUM_LEVEL_FIX && cfg->fullYrange)
      {
       pp_mode.minAllowedY=0;
       pp_mode.maxAllowedY=255;
      }
     else
      {
       pp_mode.minAllowedY=16;
       pp_mode.maxAllowedY=234;
      }
     int frametype=pict.frametype&FRAME_TYPE::typemask; //3 = B
     libmplayer->pp_postprocess(tempPict1,stride1,
                                tempPict2,stride2,
                                dx1[0],dy1[0],
                                quants,quantsDx,
                                &pp_mode,pp_ctx,frametype);
    }
  }
 return parent->deliverSample(++it,pict);
}

//============================== TimgFilterPostprocSpp ===============================
#include "csimd.h"

extern "C" void simple_idct_mmx_P(short*);
void TimgFilterPostprocSpp::ff_fdct_mmx2(int16_t *block)
{
 static const int BITS_FRW_ACC=3; //; 2 or 3 for accuracy
 static const int SHIFT_FRW_COL=BITS_FRW_ACC;
 static const int SHIFT_FRW_ROW=(BITS_FRW_ACC + 17 - 3);
 static const int RND_FRW_ROW=(1 << (SHIFT_FRW_ROW-1));

 static __align8(const int16_t,tab_frw_01234567[]) = {  // forward_dct coeff table
   16384,   16384,   22725,   19266,
   16384,   16384,   12873,    4520,
   21407,    8867,   19266,   -4520,
   -8867,  -21407,  -22725,  -12873,
   16384,  -16384,   12873,  -22725,
  -16384,   16384,    4520,   19266,
    8867,  -21407,    4520,  -12873,
   21407,   -8867,   19266,  -22725,

   22725,   22725,   31521,   26722,
   22725,   22725,   17855,    6270,
   29692,   12299,   26722,   -6270,
  -12299,  -29692,  -31521,  -17855,
   22725,  -22725,   17855,  -31521,
  -22725,   22725,    6270,   26722,
   12299,  -29692,    6270,  -17855,
   29692,  -12299,   26722,  -31521,

   21407,   21407,   29692,   25172,
   21407,   21407,   16819,    5906,
   27969,   11585,   25172,   -5906,
  -11585,  -27969,  -29692,  -16819,
   21407,  -21407,   16819,  -29692,
  -21407,   21407,    5906,   25172,
   11585,  -27969,    5906,  -16819,
   27969,  -11585,   25172,  -29692,

   19266,   19266,   26722,   22654,
   19266,   19266,   15137,    5315,
   25172,   10426,   22654,   -5315,
  -10426,  -25172,  -26722,  -15137,
   19266,  -19266,   15137,  -26722,
  -19266,   19266,    5315,   22654,
   10426,  -25172,    5315,  -15137,
   25172,  -10426,   22654,  -26722,

   16384,   16384,   22725,   19266,
   16384,   16384,   12873,    4520,
   21407,    8867,   19266,   -4520,
   -8867,  -21407,  -22725,  -12873,
   16384,  -16384,   12873,  -22725,
  -16384,   16384,    4520,   19266,
    8867,  -21407,    4520,  -12873,
   21407,   -8867,   19266,  -22725,

   19266,   19266,   26722,   22654,
   19266,   19266,   15137,    5315,
   25172,   10426,   22654,   -5315,
  -10426,  -25172,  -26722,  -15137,
   19266,  -19266,   15137,  -26722,
  -19266,   19266,    5315,   22654,
   10426,  -25172,    5315,  -15137,
   25172,  -10426,   22654,  -26722,

   21407,   21407,   29692,   25172,
   21407,   21407,   16819,    5906,
   27969,   11585,   25172,   -5906,
  -11585,  -27969,  -29692,  -16819,
   21407,  -21407,   16819,  -29692,
  -21407,   21407,    5906,   25172,
   11585,  -27969,    5906,  -16819,
   27969,  -11585,   25172,  -29692,

   22725,   22725,   31521,   26722,
   22725,   22725,   17855,    6270,
   29692,   12299,   26722,   -6270,
  -12299,  -29692,  -31521,  -17855,
   22725,  -22725,   17855,  -31521,
  -22725,   22725,    6270,   26722,
   12299,  -29692,    6270,  -17855,
   29692,  -12299,   26722,  -31521,
  };
 static __align8(const int16_t,fdct_tg_all_16[]) = {
    13036, 13036, 13036, 13036,		// tg * (2<<16) + 0.5
    27146, 27146, 27146, 27146,		// tg * (2<<16) + 0.5
    -21746, -21746, -21746, -21746,	// tg * (2<<16) + 0.5
 };
 static const __int64 fdct_one_corr = 0x0001000100010001LL;
 static  __align8(const int16_t,ocos_4_16[4]) = {
    23170, 23170, 23170, 23170,	//cos * (2<<15) + 0.5
 };
 static __align8(const int32_t,fdct_r_row[2])={RND_FRW_ROW, RND_FRW_ROW };

 struct Tcol
  {
   static __forceinline void fdct_col(const int16_t *in, int16_t *out, int offset)
    {
       __m64 mm0,mm1,mm2,mm3,mm4,mm5,mm6,mm7;
       csimd::movq((in + offset + 1 * 8), mm0);
       csimd::movq((in + offset + 6 * 8), mm1);
       csimd::movq(mm0, mm2);
       csimd::movq((in + offset + 2 * 8), mm3);
       csimd::paddsw(mm1, mm0);
       csimd::movq((in + offset + 5 * 8), mm4);
       csimd::psllw(SHIFT_FRW_COL, mm0);
       csimd::movq((in + offset + 0 * 8), mm5);
       csimd::paddsw(mm3, mm4);
       csimd::paddsw((in + offset + 7 * 8), mm5);
       csimd::psllw(SHIFT_FRW_COL, mm4);
       csimd::movq(mm0, mm6);
       csimd::psubsw(mm1, mm2);
       csimd::movq((fdct_tg_all_16 + 4), mm1);
       csimd::psubsw(mm4, mm0);
       csimd::movq((in + offset + 3 * 8), mm7);
       csimd::pmulhw(mm0, mm1);
       csimd::paddsw((in + offset + 4 * 8), mm7);
       csimd::psllw(SHIFT_FRW_COL, mm5);
       csimd::paddsw(mm4, mm6);
       csimd::psllw(SHIFT_FRW_COL, mm7);
       csimd::movq(mm5, mm4);
       csimd::psubsw(mm7, mm5);
       csimd::paddsw(mm5, mm1);
       csimd::paddsw(mm7, mm4);
       csimd::por(fdct_one_corr, mm1);
       csimd::psllw(SHIFT_FRW_COL + 1, mm2);
       csimd::pmulhw((fdct_tg_all_16 + 4), mm5);
       csimd::movq(mm4, mm7);
       csimd::psubsw((in + offset + 5 * 8), mm3);
       csimd::psubsw(mm6, mm4);
       csimd::movq(mm1, (out + offset + 2 * 8));
       csimd::paddsw(mm6, mm7);
       csimd::movq((in + offset + 3 * 8), mm1);
       csimd::psllw(SHIFT_FRW_COL + 1, mm3);
       csimd::psubsw((in + offset + 4 * 8), mm1);
       csimd::movq(mm2, mm6);
       csimd::movq(mm4, (out + offset + 4 * 8));
       csimd::paddsw(mm3, mm2);
       csimd::pmulhw(ocos_4_16, mm2);
       csimd::psubsw(mm3, mm6);
       csimd::pmulhw(ocos_4_16, mm6);
       csimd::psubsw(mm0, mm5);
       csimd::por(fdct_one_corr, mm5);
       csimd::psllw(SHIFT_FRW_COL, mm1);
       csimd::por(fdct_one_corr, mm2);
       csimd::movq(mm1, mm4);
       csimd::movq((in + offset + 0 * 8), mm3);
       csimd::paddsw(mm6, mm1);
       csimd::psubsw((in + offset + 7 * 8), mm3);
       csimd::psubsw(mm6, mm4);
       csimd::movq((fdct_tg_all_16 + 0), mm0);
       csimd::psllw(SHIFT_FRW_COL, mm3);
       csimd::movq((fdct_tg_all_16 + 8), mm6);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?