timgfilterosd.cpp

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

CPP
542
字号
  name[0]='\0';
}
TimgFilterOSD::Tosds::~Tosds()
{
 freeOsds();
}

void TimgFilterOSD::Tosds::init(bool allowSave,IffdshowBase *deci,IffdshowDec *deciD,IffdshowDecVideo *deciV,const Tconfig *config,TfontSettingsOSD *oldFont,const TOSDsettings *cfg,int framecnt)
{
 if (framecnt<startupDuration || provider->isOSD())
  {
   is=true;
   const char_t *format;
   if (framecnt<startupDuration)
    format=startupFormat.c_str();
   else
    format=provider->getFormat();

   int cfgIsSave=false;const char_t* cfgSaveFlnm;provider->getSave(&cfgIsSave,&cfgSaveFlnm);
   int initSave=-1;
   if (oldSave!=cfgIsSave || stricmp(oldSaveFlnm,cfgSaveFlnm))
    {
     oldSave=cfgIsSave;strcpy(oldSaveFlnm,cfgSaveFlnm);
     initSave=allowSave && cfgIsSave && cfgSaveFlnm[0]!='\0'?1:0;
    }
   if (strcmp(oldFormat,format)!=0)
    {
     strcpy(oldFormat,format);
     freeOsds();
     if (name)
      push_back(new TosdLine(deci,deciD,deciV,config,ffstring(_l("user"))+ffstring(name),oldFont,0,provider,true));
     if (strncmp(format,_l("user"),4)==0)
      {
       strings lines;
       strtok(format,_l("\\n"),lines);
       for (size_t i=0;i<lines.size();i++)
        push_back(new TosdLine(deci,deciD,deciV,config,ffstring(i==0?_l(""):_l("user"))+lines[i],oldFont,0,provider));
       initSave=0;
      }
     else
      {
       ints types;strtok(format,_l(" "),types);
       for (size_t i=0;i<types.size();i++)
        {
         char_t pomS[10];
         push_back(new TosdLine(deci,deciD,deciV,config,ffstring(_l("%"))+ffstring(_itoa(types[i],pomS,10)),oldFont,0,provider));
        }
       initSave=cfgIsSave && cfgSaveFlnm[0]!='\0'?1:0;
      }
    }
   if (initSave!=-1)
    {
     done();
     if (initSave==1)
      {
       f=fopen(cfgSaveFlnm,_l("wt"));
       if (f)
        {
         for (const_iterator o=begin();o!=end();o++)
          tfprintf(f,_l("%s%s"),(*o)->getName(0),o!=end()-1?_l(";"):_l(""));
         tfprintf(f,_l("\n"));
        }
      }
    }
  }
 else
  {
   is=false;
   oldFormat[0]='\0';
  }
}

void TimgFilterOSD::Tosds::fontInit(const TfontSettingsOSD *fontSettings)
{
 for (iterator i=begin();i!=end();i++)
  (*i)->font.init(fontSettings);
}

void TimgFilterOSD::Tosds::print(IffdshowBase *deci,const TffPict &pict,unsigned char *dst[4],stride_t stride2[4],unsigned int dxY,unsigned int dyY,unsigned int x,unsigned int &y,int linespace,bool fileonly)
{
 for (iterator o=begin();o!=end() && y<dyY;)
  {
   (*o)->print(deci,pict,dst,stride2,dxY,dyY,x,y,linespace,f,fileonly);
   if (f && o!=end()-1)
    fprintf(f,";");

   if ((*o)->duration>0)
    {
     (*o)->duration--;
     if ((*o)->duration==0)
      {
       delete *o;
       o=erase(o);
       continue;
      }
    }
   o++;
  }
 if (f) fprintf(f,"\n");
}

void TimgFilterOSD::Tosds::done(void)
{
 if (f) fclose(f);f=NULL;
}
void TimgFilterOSD::Tosds::freeOsds(void)
{
 for (Tosds::iterator i=begin();i!=end();i++)
  delete *i;
 clear();
}

//===================================== TimgFilterOSD ========================================
bool TimgFilterOSD::TprovOSDs::empty(void) const
{
 if (std::vector<Tosds*>::empty()) return true;
 for (const_iterator op=begin();op!=end();op++)
  if ((*op)->is && !(*op)->empty())
   return false;
 return true;
}

//===================================== TimgFilterOSD ========================================
TimgFilterOSD::TimgFilterOSD(IffdshowBase *Ideci,Tfilters *Iparent):
 TimgFilter(Ideci,Iparent),
 parent((TimgFiltersPlayer*)Iparent),
 fontUser(Ideci),
 subUser(0),
 framecnt(0),
 oldFont((TfontSettingsOSD*)malloc(sizeof(TfontSettingsOSD))),
 trans(NULL),
 shortOSD(this),
 TOSDprovider(deci,deciD)
{
 provOSDs.push_back(new Tosds(this));
 oldFont->weight=-1;
 oldLinesUser[0]='\0';
}
TimgFilterOSD::~TimgFilterOSD()
{
 CAutoLock l(&csProvider);
 for (TprovOSDs::iterator po=provOSDs.begin();po!=provOSDs.end();po++)
  delete *po;
 ::free(oldFont);
 if (trans) trans->release();
}
void TimgFilterOSD::done(void)
{
 CAutoLock l(&csProvider);
 for (TprovOSDs::iterator po=provOSDs.begin();po!=provOSDs.end();po++)
  (*po)->done();
}

void TimgFilterOSD::onSizeChange(void)
{
 oldFont->weight=-1;
}

bool TimgFilterOSD::shortOSDmessage(const char_t *msg,unsigned int duration)
{
 cs.Lock();
 shortOSDtemp.push_back(std::make_pair(msg,duration));
 cs.Unlock();
 return true;
}

bool TimgFilterOSD::is(const TffPictBase &pict,const TfilterSettingsVideo *cfg0)
{
 const TOSDsettingsVideo *cfg=(const TOSDsettingsVideo*)cfg0;
 const char_t *startup;
 return cfg->is || ((startup=cfg->getStartupFormat(NULL))!=NULL && startup[0]) || cfg->user[0];
}

HRESULT TimgFilterOSD::process(TfilterQueue::iterator it,TffPict &pict,const TfilterSettingsVideo *cfg0)
{
 const TOSDsettingsVideo *cfg=(const TOSDsettingsVideo*)cfg0;tempcfg=cfg;

 init(pict,true,0);
 csProvider.Lock();
 if (memcmp(oldFont->name,parent->fontSettingsOSD->name,sizeof(TfontSettingsOSD)-sizeof(Toptions))!=0)
  {
   memcpy(oldFont,parent->fontSettingsOSD,sizeof(*oldFont));
   for (TprovOSDs::iterator po=provOSDs.begin();po!=provOSDs.end();po++)
    (*po)->fontInit(oldFont);
   fontUser.init(oldFont);
  }

 for (TprovOSDs::iterator po=provOSDs.begin();po!=provOSDs.end();po++)
  (*po)->init(true,deci,deciD,deciV,parent->config,oldFont,cfg,framecnt);
 framecnt++;

 if (!shortOSDtemp.empty())
  {
   cs.Lock();
   for (std::vector<TshortOsdTemp>::const_iterator o=shortOSDtemp.begin();o!=shortOSDtemp.end();o++)
    shortOSD.push_back(new TosdLine(deci,deciD,deciV,parent->config,_l("shortosd")+o->first,oldFont,o->second,NULL));
   shortOSDtemp.clear();
   cs.Unlock();
  }

 if (!provOSDs.empty()/*!osds.empty()*/ || !shortOSD.empty() || cfg->user[0]!='\0')
  {
   unsigned char *dst[4];
   getCurNext(FF_CSP_420P,pict,true,COPYMODE_FULL,dst);

   unsigned int x=dx1[0]*cfg->posX/100,y=dy1[0]*cfg->posY/100;

   for (TprovOSDs::iterator po=provOSDs.begin();po!=provOSDs.end();po++)
    if ((*po)->is)
     (*po)->print(deci,pict,dst,stride2,dx1[0],dy1[0],x,y,cfg->linespace,!!cfg->saveOnly);
   shortOSD.print(deci,pict,dst,stride2,dx1[0],dy1[0],x,y,cfg->linespace,false);

   if (cfg->user[0]!='\0')
    {
     if (strcmp(oldLinesUser,cfg->user)!=0)
      {
       strcpy(oldLinesUser,cfg->user);
       strtok(cfg->user,_l("\n"),linesUser);
       subUser.set(linesUser);
      }
     TrenderedSubtitleLines::TprintPrefs printprefs(deci);
     printprefs.dst=dst;
     printprefs.stride=stride2;
     printprefs.shiftX=pict.cspInfo.shiftX;printprefs.shiftY=pict.cspInfo.shiftY;
     printprefs.dx=dx1[0];
     printprefs.dy=dy1[0];
     printprefs.xpos=deci->getParam2(IDFF_OSDuserPx);
     printprefs.ypos=deci->getParam2(IDFF_OSDuserPy);
     printprefs.align=ALIGN_LEFT;
     printprefs.linespacing=cfg->linespace;
     printprefs.deci=deci;
     printprefs.config=parent->config;
     fontUser.print(&subUser,true,printprefs);
    }
  }
 csProvider.Unlock();
 return parent->deliverSample(++it,pict);
}

STDMETHODIMP_(const char_t*) TimgFilterOSD::getInfoItemName(int type)
{
 if (!trans)
  deci->getTranslator(&trans);
 const char_t *name=deci->getInfoItemName(type);
 return trans?trans->translate(name):name;
}

HRESULT TimgFilterOSD::registerOSDprovider(IOSDprovider *provider,const char *name)
{
 if (!provider) return E_POINTER;
 CAutoLock l(&csProvider);
 for (TprovOSDs::iterator po=provOSDs.begin();po!=provOSDs.end();po++)
  if ((*po)->provider==provider)
   return E_UNEXPECTED;
 provOSDs.push_back(new Tosds(provider,text<char_t>(name)));
 return S_OK;
}
HRESULT TimgFilterOSD::unregisterOSDprovider(IOSDprovider *provider)
{
 if (!provider) return E_POINTER;
 CAutoLock l(&csProvider);
 for (TprovOSDs::iterator po=provOSDs.begin();po!=provOSDs.end();po++)
  if ((*po)->provider==provider)
   {
    delete *po;
    provOSDs.erase(po);
    return S_OK;
   }
 return VFW_E_NOT_FOUND;
}

⌨️ 快捷键说明

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