timgfilterosd.cpp

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

CPP
542
字号
/*
 * 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 "TimgFilterOSD.h"
#include "IffdshowBase.h"
#include "IffdshowDec.h"
#include "IffdshowDecVideo.h"
#include "TOSDsettings.h"
#include "Ttranslate.h"

//=============================== TimgFilterOSD::TosdLine::TosdValue =========================
const char_t* TimgFilterOSD::TosdLine::TosdValue::getName(void) const
{
 if (!name)
  name=provider->getInfoItemName(type);
 return name;
}
const char_t* TimgFilterOSD::TosdLine::TosdValue::getVal(bool &wasChange,bool &splitline,const TffPict &pict)
{
 splitline=false;
 switch (type)
  {
   case IDFF_OSDtype_outputSize:
    {
     char_t news[256];
     tsprintf(news,_l("%ux%u"),pict.rectFull.dx,pict.rectFull.dy);
     if (strcmp(news,s)!=0)
      {
       strcpy(s,news);
       wasChange=true;
      }
     break;
    }
   case IDFF_OSDtype_outputAspect:
    {
     const Rational &sar=pict.rectFull.sar,dar=pict.rectFull.dar();
     bool sarOk=sar;
     bool darOk=dar;
     if (oldSar!=sar || oldDar!=dar)
      {
       if (sarOk)
        tsprintf(s,_l("SAR: %i/%i, "),sar.num,sar.den);
       else
        tsprintf(s,_l("SAR: N/A, "));
       if (darOk)
        strcatf(s,_l("DAR: %i/%i"),dar.num,dar.den);
       else
        strcatf(s,_l("DAR: N/A"));
       wasChange=true;
      }
     oldSar=sar;oldDar=dar;
     break;
    }
   case IDFF_frameType:
    {
     const char_t *ipb0=FRAME_TYPE::name(pict.frametype&FRAME_TYPE::typemask);
     char_t ipb[30];
     strcpy(ipb,stricmp(ipb0,_l("s"))==0?_l("GMC"):ipb0);
     tsprintf(s,_l("%s%s"),strupr(ipb),pict.frametype&FRAME_TYPE::QPEL?_l("\t QPEL"):_l(""));
     wasChange=true;
     break;
    }
   case IDFF_frameSize:
    {
     tsprintf(s,_l("%u"),(unsigned int)pict.srcSize);
     wasChange=true;
     break;
    }
   case IDFF_OSDtype_gmcWarpPoints:
    tsprintf(s,_l("%i (used: %i)"),pict.gmcWarpingPoints,pict.gmcWarpingPointsReal);
    wasChange=strcmp(s,olds)!=0;
    break;
   case IDFF_OSDtype_frameMD5:
    {
     uint32_t sum[4];
     pict.md5sum((uint8_t*)sum);
     tsprintf(s,_l("%08X%08X%08X%08X"),sum[0],sum[1],sum[2],sum[3]);
     wasChange=true;
     break;
    }
   case IDFF_OSDtype_frameTimestamps:
    {
     tsprintf(s,_l("%I64i - %I64i"),pict.rtStart,pict.rtStop);
     wasChange=true;
     break;
    }
   case IDFF_OSDtype_frameDuration:
    {
     double duration=(pict.rtStop-pict.rtStart)/(REF_SECOND_MULT/1000.0);
     tsprintf(s,_l("%g ms"),duration);
     wasChange=duration!=oldDuration;
     oldDuration=duration;
     break;
    }
   default:
    {
     const char_t *val;int wasChangeI,splitlineI;
     if (provider->getInfoItemValue(type,&val,&wasChangeI,&splitlineI)==S_OK)
      {
       strncpy(s,val,countof(s)-1);s[countof(s)-1]='\0';
       wasChange=!!wasChangeI;splitline=!!splitlineI;
      }
     else
      assert(0);
     break;
    }
  }
 strcpy(olds,s);
 return s;
}

//============================== TimgFilterOSD::TosdLine::TosdToken ==========================
const char_t* TimgFilterOSD::TosdLine::TosdToken::getName(void) const
{
 switch (type)
  {
   case TOKEN_VALUE:return val.getName();
   default:
   case TOKEN_STRING:return string.c_str();
  }
}

//================================== TimgFilterOSD::TosdLine =================================
TimgFilterOSD::TosdLine::TosdLine(IffdshowBase *Ideci,IffdshowDec *IdeciD,IffdshowDecVideo *IdeciV,const Tconfig *Iconfig,const ffstring &format,const TfontSettings *fontSettings,unsigned int Iduration,IOSDprovider *Iprovider,bool Iitalic):
// deci(Ideci),
 config(Iconfig),
 font(Ideci),
 sub(0,TSubtitleProps(false,Iitalic,false)),
 provider(Iprovider)
{
 duration=Iduration;
 font.init(fontSettings);
 if (strncmp(format.c_str(),_l("user"),4)==0)
  {
   char_t s0[256]=_l(""),*s=s0;
   for (const char_t *f=format.c_str()+4;*f;)
    if (f[0]=='%' && f[1])
     {
      if (f[1]=='%')
       {
        *s++='%';f+=2;
        continue;
       }
      int idff=0;
      if (isIn(f[1],_l('0'),_l('9')))
       {
        char_t *endl;
        idff=strtol(f+1,&endl,10);
        f=endl;
       }
      else
       {
        int toklen;
        if (int sidff=provider->getInfoShortcutItem(f+1,&toklen))
         {
          idff=sidff;
          f+=toklen+1;
         }
       }
      if (idff)
       {
        if (s0[0])
         {
          *s='\0';
          tokens.push_back(TosdToken(s0));
         }
        tokens.push_back(TosdToken(idff,provider));
        s0[0]='\0';s=s0;
       }
      else
       f++;
     }
    else
     *s++=*f++;
    if (s0[0])
     {
      *s='\0';
      tokens.push_back(TosdToken(s0));
     }
  }
 else if (strncmp(format.c_str(),_l("shortosd"),8)==0)
  tokens.push_back(TosdToken(format.c_str()+8));
 else
  {
   int type=atoi(format.c_str()+1);
   char_t valName[256];
   strcpy(valName,provider->getInfoItemName(type));
   strcat(valName,_l(": "));
   tokens.push_back(TosdToken(valName));
   tokens.push_back(TosdToken(type,provider));
  }
 firsttime=true;
}
const char_t* TimgFilterOSD::TosdLine::getName(unsigned int i) const
{
 return i>=tokens.size()?_l(""):tokens[i].getName();
}

void TimgFilterOSD::TosdLine::print(IffdshowBase *deci,const TffPict &pict,unsigned char *dst[4],stride_t stride[4],unsigned int dxY,unsigned int dyY,unsigned int x,unsigned int &y,int linespace,FILE *f,bool fileonly)
{
 bool wasChange=firsttime,splitline=false;
 firsttime=false;
 ffstring text;
 for (TosdTokens::iterator t=tokens.begin();t!=tokens.end();t++)
  {
   bool wasChange0,splitline0;
   const char_t *val=t->getStr(wasChange0,splitline0,pict);
   if(val[0]!=':') // deleted item
    text+=val;
   wasChange|=wasChange0;splitline|=splitline0;
   if (f && t->type==TosdToken::TOKEN_VALUE)
    tfprintf(f,_l("%s"),val);
  }
 if (!fileonly && !text.empty())
  {
   if (y<dyY)
    {
     TrenderedSubtitleLines::TprintPrefs printprefs(deci);
     printprefs.dst=dst;
     printprefs.stride=stride;
     printprefs.shiftX=pict.cspInfo.shiftX;printprefs.shiftY=pict.cspInfo.shiftY;
     printprefs.dx=dxY;
     printprefs.dy=dyY;
     printprefs.xpos=-1*int(x);
     printprefs.ypos=-1*int(y);
     printprefs.align=ALIGN_LEFT;
     printprefs.linespacing=linespace;
     printprefs.deci=deci;
     printprefs.config=config;
     printprefs.shadowMode=3;
     printprefs.shadowSize=0;
     if (splitline)
      {
       printprefs.fontchangesplit=1;
       printprefs.fontsplit=1;
      }
     sub.set(text);
     font.print(&sub,wasChange,printprefs,&y);
    }
  }
}

//================================== TimgFilterOSD::Tosds ====================================
TimgFilterOSD::Tosds::Tosds(IOSDprovider *Iprovider,const char_t *Iname):f(NULL),provider(Iprovider)
{
 if (const char_t *sfmt=provider->getStartupFormat(&startupDuration))
  startupFormat=sfmt;
 oldFormat[0]='\0';
 oldSave=-1;oldSaveFlnm[0]='\0';
 if (Iname)
  {
   strncpy(name,Iname,260);
   name[259]='\0';
  }
 else

⌨️ 快捷键说明

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