⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 twinamp2.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
字号:
/*
 * Copyright (c) 2003-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 "Twinamp2.h"
#include "Tdll.h"
#include "DSP.H"
#include "Twinamp2settings.h"
#include "ffdebug.h"

//============================== Twinamp2 ====================================
Twinamp2::Twinamp2(const char_t *Iwinampdir)
{
 strcpy(winampdir,Iwinampdir);
 strings files;
 char_t mask[MAX_PATH];_makepath(mask,NULL,winampdir,_l("plugins\\dsp*"),_l("dll"));
 findFiles(mask,files);
 for (strings::const_iterator flnm=files.begin();flnm!=files.end();flnm++)
  {
   Twinamp2dspDll *dsp=new Twinamp2dspDll(*flnm);
   if (!dsp->filters.empty())
    dsps.push_back(dsp);
   else
    delete dsp;
  }
}
Twinamp2::~Twinamp2()
{
 for (Twinamp2dspDlls::iterator d=dsps.begin();d!=dsps.end();d++)
  (*d)->release();
}

Twinamp2dspDll* Twinamp2::getFilter(const char_t *flnm)
{
 for (Twinamp2dspDlls::iterator d=dsps.begin();d!=dsps.end();d++)
  if ((*d)->descr==flnm)
   return *d;
 return NULL;
}

Twinamp2dsp* Twinamp2::getFilter(const Twinamp2settings *cfg, int nchannels)
{
 Twinamp2dspDll *d=getFilter(cfg->flnm);
 if (!d) return NULL;
 if (nchannels>2 && !d->isMultichannelAllowed(cfg->allowMultichannelOnlyIn))
   return NULL;
 for (Twinamp2dspDll::Tfilters::iterator f=d->filters.begin();f!=d->filters.end();f++)
  if (strcmp((*f)->descr.c_str(),cfg->modulename)==0)
   {
    return *f;
   }
 return NULL;
}

//=========================== Twinamp2dspDll =================================
Twinamp2dspDll::Twinamp2dspDll(const ffstring &flnm):refcount(1)
{
 dll=NULL;
 winampDSPGetHeaderType=NULL;
 hdr=NULL;
 char_t filename[MAX_PATH],name[MAX_PATH],ext[MAX_PATH];
 _splitpath(flnm.c_str(),NULL,NULL,name,ext);
 _makepath(filename,NULL,NULL,name,ext);
 // DSP stacker and Adapt-X are not compatible with ffdshow currently. Maybe ffdshow's bug, but I can't help...
 if (_strnicmp(_l("dsp_stacker.dll"),filename,16)==0
  || _strnicmp(_l("dsp_adaptx.dll"),filename,15)==0)
  return;
 dll=new Tdll(flnm.c_str(),NULL);
 dll->loadFunction(winampDSPGetHeaderType,"winampDSPGetHeader2");
 if (dll->ok)
  {
   hdr=winampDSPGetHeaderType();
   if (hdr->version!=DSP_HDRVER)
    {
     hdr=NULL;
     return;
    }
   descr=hdr->description;
   dllFileName=filename;
  }
 if (hdr)
  for (int i=0;;i++)
   {
    winampDSPModule *flt=hdr->getModule(i);
    if (!flt) break;
    flt->hDllInstance=dll->hdll;
    filters.push_back(new Twinamp2dsp(this,flt));
   }
}
Twinamp2dspDll::~Twinamp2dspDll()
{
 for (Tfilters::iterator f=filters.begin();f!=filters.end();f++)
  delete *f;
 delete dll;
}
void Twinamp2dspDll::addref(void)
{
 refcount++;
 DPRINTFA("Twinamp2dspDll: %s: %i",hdr->description,refcount);
}
void Twinamp2dspDll::release(void)
{
 refcount--;
 DPRINTFA("Twinamp2dspDll: %s: %i",hdr->description,refcount);
 if (refcount==0)
  {
   DPRINTFA("Twinamp2dspDll: deleting: %s",hdr->description);
   delete this;
  }
}

bool Twinamp2dspDll::isMultichannelAllowed(const char_t *compList) const
{
 strings multichannelDlls;
 strtok(compList,_l(";"),multichannelDlls);
 for (strings::const_iterator b=multichannelDlls.begin();b!=multichannelDlls.end();b++)
  if (DwStrcasecmp(*b,dllFileName)==0)
   return true;
 return false;
}
//============================= Twinamp2dsp ==================================
Twinamp2dsp::Twinamp2dsp(Twinamp2dspDll *Idll,winampDSPModule *Imod):mod(Imod),dll(Idll),h(NULL),hThread(NULL)
{
 descr=mod->description;
 inited=0;
}
Twinamp2dsp::~Twinamp2dsp()
{
 mod->Quit(mod);
}
int Twinamp2dsp::init(void)
{
 if (!inited++ && mod->Init)
  {
   addref();
   unsigned threadID;
   hThread=(HANDLE)_beginthreadex(NULL,65536,threadProc,this,NULL,&threadID);
   while (!h) Sleep(20);
   return (h!=(HWND)-1)?1:(h=NULL,0);
  }
 else
  return 0;
}
void Twinamp2dsp::config(HWND parent)
{
 if (mod->Config)
  {
   mod->hwndParent=parent;
   mod->Config(mod);
  }
}
void Twinamp2dsp::done(void)
{
 if (!inited) return;
 inited--;
 if (inited==0 && h && hThread)
  {
   SendMessage(h,WM_CLOSE,0,0);
   WaitForSingleObject(hThread,INFINITE);
   hThread = NULL;
   h = NULL;
   release();
  }
}
void Twinamp2dsp::addref(void)
{
 dll->addref();
}
void Twinamp2dsp::release(void)
{
 dll->release();
}

size_t Twinamp2dsp::process(int16_t *samples,size_t numsamples,int bps,int nch,int srate)
{
 return mod->ModifySamples?mod->ModifySamples(mod,samples,(int)numsamples,bps,nch,srate):0;
}

LRESULT CALLBACK Twinamp2dsp::wndProc(HWND hwnd, UINT msg, WPARAM wprm, LPARAM lprm)
{
 switch (msg)
  {
   case WM_DESTROY:
    PostQuitMessage(0);
    break;
  }
 return DefWindowProc(hwnd,msg,wprm,lprm);
}

unsigned int __stdcall Twinamp2dsp::threadProc(void *self0)
{
 Twinamp2dsp *self=(Twinamp2dsp*)self0;
 static const char_t *FFDSHOW_WINAMP_CLASS=_l("ffdshow_winamp_class");
 randomize();
 setThreadName(DWORD(-1),"winamp2");

 HINSTANCE hi=self->mod->hDllInstance;
 char_t windowName[80];tsprintf(windowName,_l("%s_window%i"),FFDSHOW_WINAMP_CLASS,rand());
 HWND h=createInvisibleWindow(hi,FFDSHOW_WINAMP_CLASS,windowName,wndProc,self,NULL);
 self->mod->hwndParent=h;
 if (self->mod->Init(self->mod)==0)
  {
   self->h=h;
   if (self->h)
    {
     SetWindowLongPtr(self->h,GWLP_USERDATA,LONG_PTR(self));
     MSG msg;
     while(GetMessage(&msg, NULL, 0, 0))
      {
       TranslateMessage(&msg);
       DispatchMessage(&msg);
      }
    }
  }
 else
  {
   self->h=(HWND)-1;
   DestroyWindow(h);
  }
 UnregisterClass(FFDSHOW_WINAMP_CLASS,hi);
 _endthreadex(0);
 return 0;
}

⌨️ 快捷键说明

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