RenderSetupDlg::RenderSetupDlg(CWnd* pParent /*=NULL*/) : CDialog(RenderSetupDlg::IDD, pParent) , m_pBox(NULL) , m_pLBox(NULL) , m_nListBoxIndex(-1) { m_nAdapter = 0; m_DeviceType = D3DDEVTYPE_HAL; m_bFullScreen = false; m_strDisplayFormat = FmtToString(D3DFMT_X8R8G8B8); m_strBufferFormat = FmtToString(D3DFMT_X8R8G8B8); m_strResolution = "800 * 600"; m_strVertexProcessing = UINTToString(D3DCREATE_SOFTWARE_VERTEXPROCESSING); m_strPresentInterval = UINTToString(D3DPRESENT_INTERVAL_DEFAULT); }
HRESULT RenderSetupDlg::CheckFormat(int nAdapter, D3DDEVTYPE devtype, bool bFullscreen) { SetDlgItemText(IDC_STATIC1,_T("Display Format: ")); DeleteAllItem(m_pBox); if(bFullscreen==false) { D3DDISPLAYMODE d3ddm; m_pD3D->GetAdapterDisplayMode(nAdapter,&d3ddm); m_strDisplayFormat = FmtToString(d3ddm.Format); m_pBox->AddString(m_strDisplayFormat); m_pBox->SetCurSel(0); SetListBox(3,m_strDisplayFormat); return S_OK; } if(SUCCEEDED(m_pD3D->CheckDeviceType(nAdapter,devtype,D3DFMT_X8R8G8B8,D3DFMT_X8R8G8B8,true))) m_pBox->AddString(_T("D3DFMT_X8R8G8B8")); if(SUCCEEDED(m_pD3D->CheckDeviceType(nAdapter,devtype,D3DFMT_X1R5G5B5,D3DFMT_X1R5G5B5,true))) m_pBox->AddString(_T("D3DFMT_X1R5G5B5")); if(SUCCEEDED(m_pD3D->CheckDeviceType(nAdapter,devtype,D3DFMT_R5G6B5,D3DFMT_R5G6B5,true))) m_pBox->AddString(_T("D3DFMT_R5G6B5")); if(SUCCEEDED(m_pD3D->CheckDeviceType(nAdapter,devtype,D3DFMT_A2R10G10B10,D3DFMT_A2R10G10B10,true))) m_pBox->AddString(_T("D3DFMT_A2R10G10B10")); CString str; for(int i=0;i<m_pBox->GetCount();i++){ m_pBox->GetLBText(i,str); if(str==m_strDisplayFormat){ m_pBox->SetCurSel(i); return S_OK; } } m_pBox->SetCurSel(0); return S_OK; }
FilterChain *FilterManager::LoadFilters(QString Filters, VideoFrameType &inpixfmt, VideoFrameType &outpixfmt, int &width, int &height, int &bufsize, int max_threads) { if (Filters.toLower() == "none") return nullptr; vector<const FilterInfo*> FiltInfoChain; FilterChain *FiltChain = new FilterChain; vector<FmtConv*> FmtList; const FilterInfo *FI; const FilterInfo *FI2; QString Opts; const FilterInfo *Convert = GetFilterInfo("convert"); QStringList OptsList; QStringList FilterList = Filters.split(",", QString::SkipEmptyParts); VideoFilter *NewFilt = nullptr; FmtConv *FC, *FC2, *S1, *S2, *S3; VideoFrameType ifmt; int nbufsize; int cbufsize; int postfilt_width = width; int postfilt_height = height; for (auto i = FilterList.begin(); i != FilterList.end(); ++i) { QString FiltName = (*i).section('=', 0, 0); QString FiltOpts = (*i).section('=', 1); if (FiltName.contains("opengl", Qt::CaseInsensitive) || FiltName.contains("vdpau", Qt::CaseInsensitive)) continue; FI = GetFilterInfo(FiltName); if (FI) { FiltInfoChain.push_back(FI); OptsList.push_back(FiltOpts); } else { LOG(VB_GENERAL, LOG_ERR, LOC + QString("Failed to load filter '%1', " "no such filter exists").arg(FiltName)); FiltInfoChain.clear(); break; } } ifmt = inpixfmt; for (uint i = 0; i < FiltInfoChain.size(); i++) { S1 = S2 = S3 = nullptr; FI = FiltInfoChain[i]; if (FiltInfoChain.size() - i == 1) { for (FC = FI->formats; FC->in != FMT_NONE; FC++) { if (FC->out == outpixfmt && FC->in == ifmt) { S1 = FC; break; } if (FC->in == ifmt && !S2) S2 = FC; if (FC->out == outpixfmt && !S3) S3 = FC; } } else { FI2 = FiltInfoChain[i+1]; for (FC = FI->formats; FC->in != FMT_NONE; FC++) { for (FC2 = FI2->formats; FC2->in != FMT_NONE; FC2++) { if (FC->in == ifmt && FC->out == FC2->in) { S1 = FC; break; } if (FC->out == FC2->in && !S3) S3 = FC; } if (S1) break; if (FC->in == ifmt && !S2) S2 = FC; } } if (S1) FC = S1; else if (S2) FC = S2; else if (S3) FC = S3; else FC = FI->formats; if (FC->in != ifmt && (i > 0 || ifmt != FMT_NONE)) { if (!Convert) { LOG(VB_GENERAL, LOG_ERR, "FilterManager: format conversion " "needed but convert filter not found"); FiltInfoChain.clear(); break; } FiltInfoChain.insert(FiltInfoChain.begin() + i, Convert); OptsList.insert(i, QString ()); FmtList.push_back(new FmtConv); if (FmtList.back()) { FmtList.back()->in = ifmt; FmtList.back()->out = FC->in; i++; } else { LOG(VB_GENERAL, LOG_ERR, "FilterManager: memory allocation " "failure, returning empty filter chain"); FiltInfoChain.clear(); break; } } FmtList.push_back(new FmtConv); if (FmtList.back()) { FmtList.back()->in = FC->in; FmtList.back()->out = FC->out; } else { LOG(VB_GENERAL, LOG_ERR, "FilterManager: memory allocation failure, " "returning empty filter chain"); FiltInfoChain.clear(); break; } ifmt = FC->out; } if (ifmt != outpixfmt && outpixfmt != FMT_NONE && (FiltInfoChain.size() || inpixfmt != FMT_NONE)) { if (!Convert) { LOG(VB_GENERAL, LOG_ERR, "FilterManager: format conversion " "needed but convert filter not found"); FiltInfoChain.clear(); } else { FiltInfoChain.push_back(Convert); OptsList.push_back( QString ()); FmtList.push_back(new FmtConv); if (FmtList.back()) { FmtList.back()->in = ifmt; FmtList.back()->out = outpixfmt; } else { LOG(VB_GENERAL, LOG_ERR, "FilterManager: memory allocation " "failure, returning empty filter chain"); FiltInfoChain.clear(); } } } nbufsize = -1; if (FiltInfoChain.empty()) { delete FiltChain; FiltChain = nullptr; } for (uint i = 0; i < FiltInfoChain.size(); i++) { QByteArray tmp = OptsList[i].toLocal8Bit(); NewFilt = LoadFilter(FiltInfoChain[i], FmtList[i]->in, FmtList[i]->out, postfilt_width, postfilt_height, tmp.constData(), max_threads); if (!NewFilt) { delete FiltChain; LOG(VB_GENERAL, LOG_ERR, QString("FilterManager: failed to load " "filter %1 %2->%3 with args %4") .arg(FiltInfoChain[i]->name) .arg(FmtToString(FmtList[i]->in)) .arg(FmtToString(FmtList[i]->out)) .arg(OptsList[i])); FiltChain = nullptr; nbufsize = -1; break; } if (NewFilt->filter && FiltChain) { FiltChain->Append(NewFilt); } else { if (NewFilt->opts) free(NewFilt->opts); if (NewFilt->cleanup) NewFilt->cleanup(NewFilt); dlclose(NewFilt->handle); free(NewFilt); } switch (FmtList[i]->out) { case FMT_YV12: cbufsize = postfilt_width * postfilt_height * 3 / 2; break; case FMT_YUV422P: cbufsize = postfilt_width * postfilt_height * 2; break; case FMT_RGB24: cbufsize = postfilt_width * postfilt_height * 3; break; case FMT_ARGB32: cbufsize = postfilt_width * postfilt_height * 4; break; default: cbufsize = 0; } if (cbufsize > nbufsize) nbufsize = cbufsize; } if (FiltChain) { if (inpixfmt == FMT_NONE) inpixfmt = FmtList.front()->in; if (outpixfmt == FMT_NONE) outpixfmt = FmtList.back()->out; width = postfilt_width; height = postfilt_height; } else { if (inpixfmt == FMT_NONE && outpixfmt == FMT_NONE) inpixfmt = outpixfmt = FMT_YV12; else if (inpixfmt == FMT_NONE) inpixfmt = outpixfmt; else if (outpixfmt == FMT_NONE) outpixfmt = inpixfmt; } switch (inpixfmt) { case FMT_YV12: cbufsize = postfilt_width * postfilt_height * 3 / 2; break; case FMT_YUV422P: cbufsize = postfilt_width * postfilt_height * 2; break; case FMT_RGB24: cbufsize = postfilt_width * postfilt_height * 3; break; case FMT_ARGB32: cbufsize = postfilt_width * postfilt_height * 4; break; default: cbufsize = 0; } if (cbufsize > nbufsize) nbufsize = cbufsize; bufsize = nbufsize; vector<FmtConv*>::iterator it = FmtList.begin(); for (; it != FmtList.end(); ++it) delete *it; FmtList.clear(); return FiltChain; }