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 + -
显示快捷键?