📄 ccodecs.cpp
字号:
/*
* 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 "Ccodecs.h"
#include "IffdshowDecVideo.h"
#include "TffdshowPageDec.h"
#include "Tconfig.h"
#include "ffdshow_mediaguids.h"
#include "TsampleFormat.h"
#include "Tcodec.h"
#include "ffImgfmt.h"
//============================== TcodecsPage::Tformat ===============================
TcodecsPage::Tformat::Tformat(const char_t *Idescr,int Iidff,const int *movie_sources,const char_t *Ihint,const Toption *Ioptions,LAVC_STATUS Ilavc_status):
descr(Idescr),
hint(Ihint),
idff(Iidff),
lavc_status(Ilavc_status)
{
for (;*movie_sources;movie_sources++)
decoders.push_back(Tdecoder::init(Tcodec::getMovieSourceName(*movie_sources),*movie_sources));
if (Ioptions)
for (;Ioptions->name;Ioptions++)
options.push_back(*Ioptions);
}
TcodecsPage::Tformat::Tformat(const char_t *Idescr,int Iidff,int movie_source,const char_t *Ihint,const Toption *Ioptions,LAVC_STATUS Ilavc_status):
descr(Idescr),
hint(Ihint),
idff(Iidff),
lavc_status(Ilavc_status)
{
decoders.push_back(Tdecoder::init(Tcodec::getMovieSourceName(movie_source),movie_source));
if (Ioptions)
for (;Ioptions->name;Ioptions++)
options.push_back(*Ioptions);
}
TcodecsPage::Tformat::Tformat(const char_t *Idescr,int Iidff,const char_t *Ihint,LAVC_STATUS Ilavc_status):
descr(Idescr),
hint(Ihint),
idff(Iidff),
lavc_status(Ilavc_status)
{
}
TcodecsPage::Tformat::Tformat(const char_t *Idescr,int Iidff,const Tdecoder *Idecoders,const char_t *Ihint,const Toption *Ioptions,LAVC_STATUS Ilavc_status):
descr(Idescr),
hint(Ihint),
idff(Iidff),
lavc_status(Ilavc_status)
{
for (;Idecoders->name;Idecoders++)
decoders.push_back(*Idecoders);
if (Ioptions)
for (;Ioptions->name;Ioptions++)
options.push_back(*Ioptions);
}
bool TcodecsPage::Tformat::decoderCheck(const Tconfig *config)
{
for (Tdecoders::iterator d=decoders.begin();d!=decoders.end();)
if (!config->isDecoder[d->id])
d=decoders.erase(d);
else
d++;
return decoders.size()>0;
}
const char_t* TcodecsPage::Tformat::getDecoderName(int val) const
{
for (Tdecoders::const_iterator d=decoders.begin();d!=decoders.end();d++)
if (d->id==val)
return d->name;
return _l("");
}
//=================================== TcodecsPage ===================================
TcodecsPage::TcodecsPage(TffdshowPageBase *Iparent):TconfPageBase(Iparent)
{
dialogId=IDD_CODECS;hlv=NULL;setHints=-1;
}
LRESULT TcodecsPage::TwidgetCodecsLv::onKeyDown(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
switch (wParam)
{
case VK_SPACE:
case VK_RETURN:
codecsPage->beginCodecChange(codecsPage->lvGetSelItem(IDC_LV_INCODECS));
return 0;
}
return TwidgetCodecs::onKeyDown(hwnd,uMsg,wParam,lParam);
}
LRESULT TcodecsPage::TwidgetCodecsLv::onVscroll(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
if (IsWindowVisible(codecsPage->hcbx))
{
codecsPage->show(false,IDC_CBX_INCODECS);
//repaint(codecsPage->hcbx);
repaint(hwnd);
}
return TwidgetCodecs::onVscroll(hwnd,uMsg,wParam,lParam);
}
LRESULT TcodecsPage::TwidgetCodecsLv::onHscroll(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
if (IsWindowVisible(codecsPage->hcbx))
{
codecsPage->show(false,IDC_CBX_INCODECS);
//repaint(codecsPage->hcbx);
repaint(hwnd);
}
return TwidgetCodecs::onHscroll(hwnd,uMsg,wParam,lParam);
}
LRESULT TcodecsPage::TwidgetCodecsLv::onPaint(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
if (IsWindowVisible(codecsPage->hcbx))
{
repaint(codecsPage->hcbx);
repaint(hwnd);
}
return TwidgetCodecs::onPaint(hwnd,uMsg,wParam,lParam);
}
LRESULT TcodecsPage::TwidgetCodecsLv::onRbuttonDown(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
static const char_t *items[]=
{
_l("Set all stable formats to libavcodec"),
_l("Set all supported formats to Xvid"),
NULL
};
int cmd=codecsPage->selectFromMenu(items,0);
switch (cmd)
{
case 0:
for (TcodecsPage::Tformats::const_iterator f=codecsPage->formats.begin();f!=codecsPage->formats.end()-1;f++)
if (f->lavc_status==LAVC_STABLE && f->decoders.find(IDFF_MOVIE_LAVC)!=-1)
codecsPage->cfgSet(f->idff,IDFF_MOVIE_LAVC);
repaint(hwnd);
break;
case 1:
for (TcodecsPage::Tformats::const_iterator f=codecsPage->formats.begin();f!=codecsPage->formats.end()-1;f++)
if (f->decoders.find(IDFF_MOVIE_XVID4)!=-1)
codecsPage->cfgSet(f->idff,IDFF_MOVIE_XVID4);
repaint(hwnd);
break;
}
return TwidgetCodecs::onRbuttonDown(hwnd,uMsg,wParam,lParam);
}
LPARAM TcodecsPage::TwidgetCodecsCbx::onKillFocus(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
codecsPage->show(false,IDC_CBX_INCODECS);
return TwidgetCodecs::onKillFocus(hwnd,uMsg,wParam,lParam);
}
LPARAM TcodecsPage::TwidgetCodecsCbx::onGetDlgCode(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
MSG *msg=(MSG*)lParam;
if (msg && (msg->message==WM_KEYDOWN || msg->message==WM_KEYUP) && (msg->wParam==VK_RETURN || msg->wParam==VK_ESCAPE))
{
codecsPage->show(false,IDC_CBX_INCODECS);
SetFocus(codecsPage->hlv);
msg->message=WM_NULL;
}
return DLGC_WANTALLKEYS;
}
void TcodecsPage::initLV(const char_t *IthirdCol)
{
hlv=GetDlgItem(m_hwnd,IDC_LV_INCODECS);
ListView_SetExtendedListViewStyleEx(hlv,LVS_EX_FULLROWSELECT|LVS_EX_INFOTIP|LVS_EX_GRIDLINES,LVS_EX_FULLROWSELECT|LVS_EX_INFOTIP|LVS_EX_GRIDLINES);
int ncol=0;
ListView_AddCol(hlv,ncol,cfgGet(IDFF_lvCodecsWidth0),_(IDC_LV_INCODECS,_l("Format" )),false);
ListView_AddCol(hlv,ncol,cfgGet(IDFF_lvCodecsWidth1),_(IDC_LV_INCODECS,_l("Decoder")),false);
ListView_AddCol(hlv,ncol,cfgGet(IDFF_lvCodecsWidth2),_(IDC_LV_INCODECS,thirdCol=IthirdCol?IthirdCol:_l("Details")),false);
hcbx=GetDlgItem(m_hwnd,IDC_CBX_INCODECS);
formats.clear();fillCodecs();
ListView_SetItemCount(hlv,formats.size());
curitem=cfgGet(IDFF_lvCodecsSelected);
lvSetSelItem(IDC_LV_INCODECS,curitem);
ListView_EnsureVisible(hlv,curitem,FALSE);
options2dlg(curitem);
if (setHints!=-1)
enableHints(!!setHints);
}
void TcodecsPage::enableHints(bool is)
{
if (hlv)
ListView_SetExtendedListViewStyleEx(hlv,LVS_EX_INFOTIP,is?LVS_EX_INFOTIP:0);
else
setHints=is?1:0;
TconfPageBase::enableHints(is);
}
void TcodecsPage::moveCBX(bool isscroll)
{
if (isscroll && !IsWindowVisible(hcbx)) return;
LVCOLUMN lvc0,lvc1;
lvc0.mask=lvc1.mask=LVCF_WIDTH;
ListView_GetColumn(hlv,0,&lvc0);ListView_GetColumn(hlv,1,&lvc1);
RECT lvr;GetWindowRect(hlv,&lvr);
RECT pr;GetWindowRect(GetParent(hlv),&pr);
OffsetRect(&lvr,-pr.left,-pr.top);
RECT ir;
int iItem=lvGetSelItem(IDC_LV_INCODECS);
ListView_GetItemRect(hlv,iItem,&ir,LVIR_BOUNDS);
MoveWindow(hcbx,lvr.left+lvc0.cx+3,lvr.top+ir.top-1,lvc1.cx,12,TRUE);
show(true,IDC_CBX_INCODECS);
SetWindowPos(hcbx,HWND_TOP,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW);
SetFocus(hcbx);
}
void TcodecsPage::beginCodecChange(int iItem)
{
if (iItem<0 || iItem>=(int)formats.size())
{
show(false,IDC_CBX_INCODECS);
curitem=-1;
}
else
{
cbxClear(IDC_CBX_INCODECS);
for (Tformat::Tdecoders::const_iterator d=formats[iItem].decoders.begin();d!=formats[iItem].decoders.end();d++)
cbxAdd(IDC_CBX_INCODECS,_(IDC_CBX_INCODECS,d->name),d->id);
cbxSetDataCurSel(IDC_CBX_INCODECS,cfgGet(formats[iItem].idff));
moveCBX(false);
curitem=iItem;
}
}
void TcodecsPage::options2dlg(int i)
{
static const int idOptions[]={IDC_CHB_CODEC_OPT1,IDC_CHB_CODEC_OPT2,0};
show(0,idOptions);
const Tformat *f=isIn(i,0,(int)formats.size()-1)?&formats[i]:NULL;
for (size_t ii=0;f && ii<f->options.size();ii++)
{
show(1,idOptions[ii]);
const Tformat::Toption &o=f->options[ii];
setText(idOptions[ii],_(idOptions[ii],o.name));
setCheck(idOptions[ii],cfgGet(o.id)&o.val);
enable(o.forCodec==0 || cfgGet(f->idff)==o.forCodec,idOptions[ii]);
}
}
void TcodecsPage::dlg2options(int id)
{
int ii=lvGetSelItem(IDC_LV_INCODECS);
if (isIn(ii,0,(int)formats.size()))
{
const Tformat::Toption &o=formats[ii].options[id==IDC_CHB_CODEC_OPT1?0:1];
int idff=o.id;
int val=cfgGet(idff);
if (getCheck(id))
val|=o.val;
else
val&=~o.val;
cfgSet(idff,val);
}
}
INT_PTR TcodecsPage::msgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DESTROY:
cfgSet(IDFF_lvCodecsWidth0,ListView_GetColumnWidth(hlv,0));
cfgSet(IDFF_lvCodecsWidth1,ListView_GetColumnWidth(hlv,1));
cfgSet(IDFF_lvCodecsWidth2,ListView_GetColumnWidth(hlv,2));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -