MainFrm.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:234k
- pAS->SetAudioTimeShift(rtShift);
- CString str;
- str.Format(_T("Audio Delay: %I64dms"), rtShift/10000);
- SendStatusMessage(str, 3000);
- }
- }
- void CMainFrame::OnUpdatePlayChangeAudDelay(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable(pGB && !!FindFilter(__uuidof(CAudioSwitcherFilter), pGB));
- }
- #include "ComPropertySheet.h"
- #include ".mainfrm.h"
- void CMainFrame::OnPlayFilters(UINT nID)
- {
- // ShowPPage(m_spparray[nID - ID_FILTERS_SUBITEM_START], m_hWnd);
- CComPtr<ISpecifyPropertyPages> pSPP = m_spparray[nID - ID_FILTERS_SUBITEM_START];
- CComPropertySheet ps(_T("Properties"), this);
- ps.AddPages(pSPP);
- ps.DoModal();
- OpenSetupStatusBar();
- }
- void CMainFrame::OnUpdatePlayFilters(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable(!m_fCapturing);
- }
- void CMainFrame::OnPlayShaders(UINT nID)
- {
- if(nID == ID_SHADERS_START)
- {
- CShaderEditorDlg(m_shaderlabel, m_pCAP, this).DoModal();
- }
- else if(nID == ID_SHADERS_START+1)
- {
- m_pCAP->SetPixelShader(NULL, NULL);
- m_shaderlabel.Empty();
- }
- else if(nID >= ID_SHADERS_START+2)
- {
- nID -= ID_SHADERS_START+2;
- CString str;
- str.Format(_T("%d"), nID);
- CList<CString> sl;
- Explode(AfxGetApp()->GetProfileString(_T("Shaders"), str), sl, '|', 3);
- if(sl.GetCount() != 3) {AfxMessageBox(_T("Invalid shader data"), S_OK); return;}
- CString label = sl.RemoveHead();
- CStringA target = CStringA(sl.RemoveHead());
- CStringA srcdata = CStringA(sl.RemoveHead());
- srcdata.Replace("\n", "n");
- srcdata.Replace("\t", "t");
- HRESULT hr = m_pCAP->SetPixelShader(srcdata, target);
- if(FAILED(hr)) AfxMessageBox(_T("Could not load shader."), MB_OK);
- else {SendStatusMessage(_T("Shader: ") + label, 3000); m_shaderlabel = label;}
- }
- }
- void CMainFrame::OnUpdatePlayShaders(CCmdUI* pCmdUI)
- {
- if(pCmdUI->m_nID > ID_SHADERS_START)
- {
- pCmdUI->Enable(!!m_pCAP);
- if(pCmdUI->m_nID == ID_SHADERS_START+1)
- {
- pCmdUI->SetRadio(m_shaderlabel.IsEmpty());
- }
- else
- {
- CString str;
- m_shaders.GetMenuString(pCmdUI->m_nID, str, MF_BYCOMMAND);
- pCmdUI->SetRadio(str == m_shaderlabel);
- }
- }
- }
- void CMainFrame::OnPlayAudio(UINT nID)
- {
- int i = (int)nID - (1 + ID_AUDIO_SUBITEM_START);
- CComQIPtr<IAMStreamSelect> pSS = FindFilter(__uuidof(CAudioSwitcherFilter), pGB);
- if(!pSS) pSS = FindFilter(L"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB);
- if(i == -1)
- {
- ShowOptions(CPPageAudioSwitcher::IDD);
- }
- else if(i >= 0 && pSS)
- {
- pSS->Enable(i, AMSTREAMSELECTENABLE_ENABLE);
- }
- }
- void CMainFrame::OnUpdatePlayAudio(CCmdUI* pCmdUI)
- {
- UINT nID = pCmdUI->m_nID;
- int i = (int)nID - (1 + ID_AUDIO_SUBITEM_START);
- CComQIPtr<IAMStreamSelect> pSS = FindFilter(__uuidof(CAudioSwitcherFilter), pGB);
- if(!pSS) pSS = FindFilter(L"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB);
- /*if(i == -1)
- {
- // TODO****
- }
- else*/ if(i >= 0 && pSS)
- {
- DWORD flags = 0;
- if(SUCCEEDED(pSS->Info(i, NULL, &flags, NULL, NULL, NULL, NULL, NULL)))
- {
- if(flags&AMSTREAMSELECTINFO_EXCLUSIVE) pCmdUI->SetRadio(TRUE);
- else if(flags&AMSTREAMSELECTINFO_ENABLED) pCmdUI->SetCheck(TRUE);
- else pCmdUI->SetCheck(FALSE);
- }
- else
- {
- pCmdUI->Enable(FALSE);
- }
- }
- }
- void CMainFrame::OnPlaySubtitles(UINT nID)
- {
- int i = (int)nID - (4 + ID_SUBTITLES_SUBITEM_START);
- if(i == -4)
- {
- ShowOptions(CPPageSubtitles::IDD);
- }
- else if(i == -3)
- {
- int i = m_iSubtitleSel;
- POSITION pos = m_pSubStreams.GetHeadPosition();
- while(pos && i >= 0)
- {
- CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
- if(i < pSubStream->GetStreamCount())
- {
- CLSID clsid;
- if(FAILED(pSubStream->GetClassID(&clsid)))
- continue;
- if(clsid == __uuidof(CRenderedTextSubtitle))
- {
- CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)pSubStream;
- CAutoPtrArray<CPPageSubStyle> pages;
- CArray<STSStyle*> styles;
- POSITION pos = pRTS->m_styles.GetStartPosition();
- for(int i = 0; pos; i++)
- {
- CString key;
- void* val;
- pRTS->m_styles.GetNextAssoc(pos, key, val);
- CAutoPtr<CPPageSubStyle> page(new CPPageSubStyle());
- page->InitStyle(key, *(STSStyle*)val);
- pages.Add(page);
- styles.Add((STSStyle*)val);
- }
- CPropertySheet dlg(_T("Styles..."), this);
- for(int i = 0; i < (int)pages.GetCount(); i++)
- dlg.AddPage(pages[i]);
- if(dlg.DoModal() == IDOK)
- {
- for(int j = 0; j < (int)pages.GetCount(); j++)
- pages[j]->GetStyle(*styles[j]);
- UpdateSubtitle(false);
- }
- return;
- }
- }
- i -= pSubStream->GetStreamCount();
- }
- }
- else if(i == -2)
- {
- ReloadSubtitle();
- }
- else if(i == -1)
- {
- m_iSubtitleSel ^= (1<<31);
- UpdateSubtitle();
- }
- else if(i >= 0)
- {
- m_iSubtitleSel = i;
- UpdateSubtitle();
- }
- }
- void CMainFrame::OnUpdatePlaySubtitles(CCmdUI* pCmdUI)
- {
- UINT nID = pCmdUI->m_nID;
- int i = (int)nID - (4 + ID_SUBTITLES_SUBITEM_START);
- pCmdUI->Enable(m_pCAP && !m_fAudioOnly);
- if(i == -3)
- {
- pCmdUI->Enable(FALSE);
- int i = m_iSubtitleSel;
- POSITION pos = m_pSubStreams.GetHeadPosition();
- while(pos && i >= 0)
- {
- CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
- if(i < pSubStream->GetStreamCount())
- {
- CLSID clsid;
- if(FAILED(pSubStream->GetClassID(&clsid)))
- continue;
- if(clsid == __uuidof(CRenderedTextSubtitle))
- {
- pCmdUI->Enable(TRUE);
- break;
- }
- }
- i -= pSubStream->GetStreamCount();
- }
- }
- else if(i == -1)
- {
- pCmdUI->SetCheck(m_iSubtitleSel >= 0);
- }
- else if(i >= 0)
- {
- pCmdUI->SetRadio(i == abs(m_iSubtitleSel));
- }
- }
- void CMainFrame::OnPlayLanguage(UINT nID)
- {
- nID -= ID_FILTERSTREAMS_SUBITEM_START;
- CComPtr<IAMStreamSelect> pAMSS = m_ssarray[nID];
- UINT i = nID;
- while(i > 0 && pAMSS == m_ssarray[i-1]) i--;
- if(FAILED(pAMSS->Enable(nID-i, AMSTREAMSELECTENABLE_ENABLE)))
- MessageBeep(-1);
- OpenSetupStatusBar();
- }
- void CMainFrame::OnUpdatePlayLanguage(CCmdUI* pCmdUI)
- {
- UINT nID = pCmdUI->m_nID;
- nID -= ID_FILTERSTREAMS_SUBITEM_START;
- CComPtr<IAMStreamSelect> pAMSS = m_ssarray[nID];
- UINT i = nID;
- while(i > 0 && pAMSS == m_ssarray[i-1]) i--;
- DWORD flags = 0;
- pAMSS->Info(nID-i, NULL, &flags, NULL, NULL, NULL, NULL, NULL);
- if(flags&AMSTREAMSELECTINFO_EXCLUSIVE) pCmdUI->SetRadio(TRUE);
- else if(flags&AMSTREAMSELECTINFO_ENABLED) pCmdUI->SetCheck(TRUE);
- else pCmdUI->SetCheck(FALSE);
- }
- void CMainFrame::OnPlayVolume(UINT nID)
- {
- if(m_iMediaLoadState == MLS_LOADED)
- pBA->put_Volume(m_wndToolBar.Volume);
- }
- void CMainFrame::OnAfterplayback(UINT nID)
- {
- AppSettings& s = AfxGetAppSettings();
- s.nCLSwitches &= ~CLSW_AFTERPLAYBACK_MASK;
- switch(nID)
- {
- case ID_AFTERPLAYBACK_CLOSE: s.nCLSwitches |= CLSW_CLOSE; break;
- case ID_AFTERPLAYBACK_STANDBY: s.nCLSwitches |= CLSW_STANDBY; break;
- case ID_AFTERPLAYBACK_HIBERNATE: s.nCLSwitches |= CLSW_HIBERNATE; break;
- case ID_AFTERPLAYBACK_SHUTDOWN: s.nCLSwitches |= CLSW_SHUTDOWN; break;
- case ID_AFTERPLAYBACK_LOGOFF: s.nCLSwitches |= CLSW_LOGOFF; break;
- }
- }
- void CMainFrame::OnUpdateAfterplayback(CCmdUI* pCmdUI)
- {
- AppSettings& s = AfxGetAppSettings();
- bool fChecked = false;
- switch(pCmdUI->m_nID)
- {
- case ID_AFTERPLAYBACK_CLOSE: fChecked = !!(s.nCLSwitches & CLSW_CLOSE); break;
- case ID_AFTERPLAYBACK_STANDBY: fChecked = !!(s.nCLSwitches & CLSW_STANDBY); break;
- case ID_AFTERPLAYBACK_HIBERNATE: fChecked = !!(s.nCLSwitches & CLSW_HIBERNATE); break;
- case ID_AFTERPLAYBACK_SHUTDOWN: fChecked = !!(s.nCLSwitches & CLSW_SHUTDOWN); break;
- case ID_AFTERPLAYBACK_LOGOFF: fChecked = !!(s.nCLSwitches & CLSW_LOGOFF); break;
- case ID_AFTERPLAYBACK_DONOTHING: fChecked = !(s.nCLSwitches & CLSW_AFTERPLAYBACK_MASK); break;
- }
- pCmdUI->SetRadio(fChecked);
- }
- // navigate
- void CMainFrame::OnNavigateSkip(UINT nID)
- {
- if(m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE)
- {
- if(m_iPlaybackMode == PM_FILE) SetupChapters();
- if(DWORD nChapters = m_pCB->ChapGetCount())
- {
- REFERENCE_TIME rtCur;
- pMS->GetCurrentPosition(&rtCur);
- REFERENCE_TIME rt = rtCur;
- CComBSTR name;
- long i;
- if(nID == ID_NAVIGATE_SKIPBACK)
- {
- rt -= 30000000;
- i = m_pCB->ChapLookup(&rt, &name);
- }
- else if(nID == ID_NAVIGATE_SKIPFORWARD)
- {
- i = m_pCB->ChapLookup(&rt, &name) + 1;
- name.Empty();
- if(i < nChapters) m_pCB->ChapGet(i, &rt, &name);
- }
- if(i >= 0 && i < nChapters)
- {
- SeekTo(rt);
- SendStatusMessage(_T("Chapter: ") + CString(name), 3000);
- return;
- }
- }
- if(nID == ID_NAVIGATE_SKIPBACK)
- {
- SendMessage(WM_COMMAND, ID_NAVIGATE_SKIPBACKPLITEM);
- }
- else if(nID == ID_NAVIGATE_SKIPFORWARD)
- {
- SendMessage(WM_COMMAND, ID_NAVIGATE_SKIPFORWARDPLITEM);
- }
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- m_iSpeedLevel = 0;
- if(GetMediaState() != State_Running)
- SendMessage(WM_COMMAND, ID_PLAY_PLAY);
- ULONG ulNumOfVolumes, ulVolume;
- DVD_DISC_SIDE Side;
- ULONG ulNumOfTitles = 0;
- pDVDI->GetDVDVolumeInfo(&ulNumOfVolumes, &ulVolume, &Side, &ulNumOfTitles);
- DVD_PLAYBACK_LOCATION2 Location;
- pDVDI->GetCurrentLocation(&Location);
- ULONG ulNumOfChapters = 0;
- pDVDI->GetNumberOfChapters(Location.TitleNum, &ulNumOfChapters);
- if(nID == ID_NAVIGATE_SKIPBACK)
- {
- if(Location.ChapterNum == 1 && Location.TitleNum > 1)
- {
- pDVDI->GetNumberOfChapters(Location.TitleNum-1, &ulNumOfChapters);
- pDVDC->PlayChapterInTitle(Location.TitleNum-1, ulNumOfChapters, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
- }
- else
- {
- pDVDC->PlayPrevChapter(DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
- }
- }
- else if(nID == ID_NAVIGATE_SKIPFORWARD)
- {
- if(Location.ChapterNum == ulNumOfChapters && Location.TitleNum < ulNumOfTitles)
- {
- pDVDC->PlayChapterInTitle(Location.TitleNum+1, 1, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
- }
- else
- {
- pDVDC->PlayNextChapter(DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
- }
- }
- /*
- if(nID == ID_NAVIGATE_SKIPBACK)
- pDVDC->PlayPrevChapter(DVD_CMD_FLAG_Block, NULL);
- else if(nID == ID_NAVIGATE_SKIPFORWARD)
- pDVDC->PlayNextChapter(DVD_CMD_FLAG_Block, NULL);
- */
- }
- }
- void CMainFrame::OnUpdateNavigateSkip(CCmdUI* pCmdUI)
- {
- // moved to the timer callback function, that runs less frequent
- // if(m_iPlaybackMode == PM_FILE) SetupChapters();
- pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED
- && ((m_iPlaybackMode == PM_DVD
- && m_iDVDDomain != DVD_DOMAIN_VideoManagerMenu
- && m_iDVDDomain != DVD_DOMAIN_VideoTitleSetMenu)
- || (m_iPlaybackMode == PM_FILE && (m_wndPlaylistBar.GetCount() > 1/*0*/ || m_pCB->ChapGetCount() > 1))
- || (m_iPlaybackMode == PM_CAPTURE && !m_fCapturing))); // TODO
- }
- void CMainFrame::OnNavigateSkipPlaylistItem(UINT nID)
- {
- if(m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE)
- {
- if(m_wndPlaylistBar.GetCount() == 1)
- {
- SendMessage(WM_COMMAND, ID_PLAY_STOP); // do not remove this, unless you want a circular call with OnPlayPlay()
- SendMessage(WM_COMMAND, ID_PLAY_PLAY);
- }
- else
- {
- if(nID == ID_NAVIGATE_SKIPBACKPLITEM)
- {
- m_wndPlaylistBar.SetPrev();
- }
- else if(nID == ID_NAVIGATE_SKIPFORWARDPLITEM)
- {
- m_wndPlaylistBar.SetNext();
- }
- OpenCurPlaylistItem();
- }
- }
- }
- void CMainFrame::OnUpdateNavigateSkipPlaylistItem(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED
- && ((m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_CAPTURE && !m_fCapturing) && m_wndPlaylistBar.GetCount() > 1/*0*/));
- }
- void CMainFrame::OnNavigateMenu(UINT nID)
- {
- nID -= ID_NAVIGATE_TITLEMENU;
- if(m_iMediaLoadState != MLS_LOADED || m_iPlaybackMode != PM_DVD)
- return;
- m_iSpeedLevel = 0;
- if(GetMediaState() != State_Running)
- SendMessage(WM_COMMAND, ID_PLAY_PLAY);
- pDVDC->ShowMenu((DVD_MENU_ID)(nID+2), DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
- }
- void CMainFrame::OnUpdateNavigateMenu(CCmdUI* pCmdUI)
- {
- UINT nID = pCmdUI->m_nID - ID_NAVIGATE_TITLEMENU;
- ULONG ulUOPs;
- if(m_iMediaLoadState != MLS_LOADED || m_iPlaybackMode != PM_DVD
- || FAILED(pDVDI->GetCurrentUOPS(&ulUOPs)))
- {
- pCmdUI->Enable(FALSE);
- return;
- }
- pCmdUI->Enable(!(ulUOPs & (UOP_FLAG_ShowMenu_Title << nID)));
- }
- void CMainFrame::OnNavigateAudio(UINT nID)
- {
- nID -= ID_NAVIGATE_AUDIO_SUBITEM_START;
- if(m_iPlaybackMode == PM_FILE)
- {
- OnNavStreamSelectSubMenu(nID, 1);
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- pDVDC->SelectAudioStream(nID, DVD_CMD_FLAG_Block, NULL);
- }
- }
- void CMainFrame::OnNavigateSubpic(UINT nID)
- {
- if(m_iPlaybackMode == PM_FILE)
- {
- OnNavStreamSelectSubMenu(nID - ID_NAVIGATE_SUBP_SUBITEM_START, 2);
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- int i = (int)nID - (1 + ID_NAVIGATE_SUBP_SUBITEM_START);
- if(i == -1)
- {
- ULONG ulStreamsAvailable, ulCurrentStream;
- BOOL bIsDisabled;
- if(SUCCEEDED(pDVDI->GetCurrentSubpicture(&ulStreamsAvailable, &ulCurrentStream, &bIsDisabled)))
- pDVDC->SetSubpictureState(bIsDisabled, DVD_CMD_FLAG_Block, NULL);
- }
- else
- {
- pDVDC->SelectSubpictureStream(i, DVD_CMD_FLAG_Block, NULL);
- pDVDC->SetSubpictureState(TRUE, DVD_CMD_FLAG_Block, NULL);
- }
- }
- }
- void CMainFrame::OnNavigateAngle(UINT nID)
- {
- nID -= ID_NAVIGATE_ANGLE_SUBITEM_START;
- if(m_iPlaybackMode == PM_FILE)
- {
- OnNavStreamSelectSubMenu(nID, 0);
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- pDVDC->SelectAngle(nID, DVD_CMD_FLAG_Block, NULL);
- }
- }
- void CMainFrame::OnNavigateChapters(UINT nID)
- {
- nID -= ID_NAVIGATE_CHAP_SUBITEM_START;
- if(m_iPlaybackMode == PM_FILE)
- {
- if((int)nID >= 0 && nID < m_pCB->ChapGetCount())
- {
- REFERENCE_TIME rt;
- CComBSTR name;
- if(SUCCEEDED(m_pCB->ChapGet(nID, &rt, &name)))
- {
- SeekTo(rt);
- SendStatusMessage(_T("Chapter: ") + CString(name), 3000);
- }
- return;
- }
- nID -= m_pCB->ChapGetCount();
- if((int)nID >= 0 && (int)nID < m_wndPlaylistBar.GetCount()
- && m_wndPlaylistBar.GetSelIdx() != (int)nID)
- {
- m_wndPlaylistBar.SetSelIdx(nID);
- OpenCurPlaylistItem();
- }
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- ULONG ulNumOfVolumes, ulVolume;
- DVD_DISC_SIDE Side;
- ULONG ulNumOfTitles = 0;
- pDVDI->GetDVDVolumeInfo(&ulNumOfVolumes, &ulVolume, &Side, &ulNumOfTitles);
- DVD_PLAYBACK_LOCATION2 Location;
- pDVDI->GetCurrentLocation(&Location);
- ULONG ulNumOfChapters = 0;
- pDVDI->GetNumberOfChapters(Location.TitleNum, &ulNumOfChapters);
- nID++;
- if(nID > 0 && nID <= ulNumOfTitles)
- {
- pDVDC->PlayTitle(nID, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL); // sometimes this does not do anything ...
- pDVDC->PlayChapterInTitle(nID, 1, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL); // ... but this does!
- return;
- }
- nID -= ulNumOfTitles;
- if(nID > 0 && nID <= ulNumOfChapters)
- {
- pDVDC->PlayChapter(nID, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
- return;
- }
- }
- }
- void CMainFrame::OnNavigateMenuItem(UINT nID)
- {
- nID -= ID_NAVIGATE_MENU_LEFT;
- if(m_iPlaybackMode == PM_DVD)
- {
- switch(nID)
- {
- case 0: pDVDC->SelectRelativeButton(DVD_Relative_Left); break;
- case 1: pDVDC->SelectRelativeButton(DVD_Relative_Right); break;
- case 2: pDVDC->SelectRelativeButton(DVD_Relative_Upper); break;
- case 3: pDVDC->SelectRelativeButton(DVD_Relative_Lower); break;
- case 4: pDVDC->ActivateButton(); break;
- case 5: pDVDC->ReturnFromSubmenu(DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL); break;
- case 6: pDVDC->Resume(DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL); break;
- default: break;
- }
- }
- }
- void CMainFrame::OnUpdateNavigateMenuItem(CCmdUI* pCmdUI)
- {
- UINT nID = pCmdUI->m_nID - ID_NAVIGATE_MENU_LEFT;
- pCmdUI->Enable(m_iMediaLoadState == MLS_LOADED && m_iPlaybackMode == PM_DVD);
- }
- // favorites
- class CDVDStateStream : public CUnknown, public IStream
- {
- STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv)
- {
- return
- QI(IStream)
- CUnknown::NonDelegatingQueryInterface(riid, ppv);
- }
- __int64 m_pos;
- public:
- CDVDStateStream() : CUnknown(NAME("CDVDStateStream"), NULL) {m_pos = 0;}
- DECLARE_IUNKNOWN;
- CByteArray m_data;
- // ISequentialStream
- STDMETHODIMP Read(void* pv, ULONG cb, ULONG* pcbRead)
- {
- __int64 cbRead = min(m_data.GetCount() - m_pos, (__int64)cb);
- cbRead = max(cbRead, 0);
- memcpy(pv, &m_data[(INT_PTR)m_pos], (int)cbRead);
- if(pcbRead) *pcbRead = (ULONG)cbRead;
- m_pos += cbRead;
- return S_OK;
- }
- STDMETHODIMP Write(const void* pv, ULONG cb, ULONG* pcbWritten)
- {
- BYTE* p = (BYTE*)pv;
- ULONG cbWritten = -1;
- while(++cbWritten < cb)
- m_data.Add(*p++);
- if(pcbWritten) *pcbWritten = cbWritten;
- return S_OK;
- }
- // IStream
- STDMETHODIMP Seek(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) {return E_NOTIMPL;}
- STDMETHODIMP SetSize(ULARGE_INTEGER libNewSize) {return E_NOTIMPL;}
- STDMETHODIMP CopyTo(IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten) {return E_NOTIMPL;}
- STDMETHODIMP Commit(DWORD grfCommitFlags) {return E_NOTIMPL;}
- STDMETHODIMP Revert() {return E_NOTIMPL;}
- STDMETHODIMP LockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {return E_NOTIMPL;}
- STDMETHODIMP UnlockRegion(ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) {return E_NOTIMPL;}
- STDMETHODIMP Stat(STATSTG* pstatstg, DWORD grfStatFlag) {return E_NOTIMPL;}
- STDMETHODIMP Clone(IStream** ppstm) {return E_NOTIMPL;}
- };
- void CMainFrame::OnFavoritesAdd()
- {
- AppSettings& s = AfxGetAppSettings();
- if(m_iPlaybackMode == PM_FILE)
- {
- CString fn = m_wndPlaylistBar.GetCur();
- if(fn.IsEmpty()) return;
- CString desc = fn;
- desc.Replace('\', '/');
- int i = desc.Find(_T("://")), j = desc.Find(_T("?")), k = desc.ReverseFind('/');
- if(i >= 0) desc = j >= 0 ? desc.Left(j) : desc;
- else if(k >= 0) desc = desc.Mid(k+1);
- CFavoriteAddDlg dlg(desc, fn);
- if(dlg.DoModal() != IDOK) return;
- CString str = dlg.m_name;
- str.Remove(';');
- CString pos(_T("0"));
- if(dlg.m_fRememberPos)
- pos.Format(_T("%I64d"), GetPos());
- str += ';';
- str += pos;
- CPlaylistItem pli;
- if(m_wndPlaylistBar.GetCur(pli))
- {
- POSITION pos = pli.m_fns.GetHeadPosition();
- while(pos) str += _T(";") + pli.m_fns.GetNext(pos);
- }
- s.AddFav(FAV_FILE, str);
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- WCHAR path[MAX_PATH];
- ULONG len = 0;
- pDVDI->GetDVDDirectory(path, MAX_PATH, &len);
- CString fn = path;
- fn.TrimRight(_T("/\"));
- DVD_PLAYBACK_LOCATION2 Location;
- pDVDI->GetCurrentLocation(&Location);
- CString desc;
- desc.Format(_T("%s - T%02d C%02d - %02d:%02d:%02d"), fn, Location.TitleNum, Location.ChapterNum,
- Location.TimeCode.bHours, Location.TimeCode.bMinutes, Location.TimeCode.bSeconds);
- CFavoriteAddDlg dlg(fn, desc);
- if(dlg.DoModal() != IDOK) return;
- CString str = dlg.m_name;
- str.Remove(';');
- CString pos(_T("0"));
- if(dlg.m_fRememberPos)
- {
- CDVDStateStream stream;
- stream.AddRef();
- CComPtr<IDvdState> pStateData;
- CComQIPtr<IPersistStream> pPersistStream;
- if(SUCCEEDED(pDVDI->GetState(&pStateData))
- && (pPersistStream = pStateData)
- && SUCCEEDED(OleSaveToStream(pPersistStream, (IStream*)&stream)))
- {
- pos = BinToString(stream.m_data.GetData(), stream.m_data.GetCount());
- }
- }
- str += ';';
- str += pos;
- str += ';';
- str += fn;
- s.AddFav(FAV_DVD, str);
- }
- else if(m_iPlaybackMode == PM_CAPTURE)
- {
- // TODO
- }
- }
- void CMainFrame::OnUpdateFavoritesAdd(CCmdUI* pCmdUI)
- {
- pCmdUI->Enable(m_iPlaybackMode == PM_FILE || m_iPlaybackMode == PM_DVD);
- }
- void CMainFrame::OnFavoritesOrganize()
- {
- CFavoriteOrganizeDlg dlg;
- dlg.DoModal();
- }
- void CMainFrame::OnUpdateFavoritesOrganize(CCmdUI* pCmdUI)
- {
- // TODO: Add your command update UI handler code here
- }
- void CMainFrame::OnFavoritesFile(UINT nID)
- {
- nID -= ID_FAVORITES_FILE_START;
- CList<CString> sl;
- AfxGetAppSettings().GetFav(FAV_FILE, sl);
- if(POSITION pos = sl.FindIndex(nID))
- {
- CList<CString> fns;
- REFERENCE_TIME rtStart = 0;
- int i = 0, j = 0;
- for(CString s1 = sl.GetAt(pos), s2 = s1.Tokenize(_T(";"), i);
- !s2.IsEmpty();
- s2 = s1.Tokenize(_T(";"), i), j++)
- {
- if(j == 0) ; // desc
- else if(j == 1) _stscanf(s2, _T("%I64d"), &rtStart); // pos
- else fns.AddTail(s2); // subs
- }
- m_wndPlaylistBar.Open(fns, false);
- OpenCurPlaylistItem(max(rtStart, 0));
- }
- }
- void CMainFrame::OnUpdateFavoritesFile(CCmdUI* pCmdUI)
- {
- UINT nID = pCmdUI->m_nID - ID_FAVORITES_FILE_START;
- }
- void CMainFrame::OnFavoritesDVD(UINT nID)
- {
- nID -= ID_FAVORITES_DVD_START;
- CList<CString> sl;
- AfxGetAppSettings().GetFav(FAV_DVD, sl);
- if(POSITION pos = sl.FindIndex(nID))
- {
- CString fn;
- CDVDStateStream stream;
- stream.AddRef();
- int i = 0, j = 0;
- for(CString s1 = sl.GetAt(pos), s2 = s1.Tokenize(_T(";"), i);
- !s2.IsEmpty();
- s2 = s1.Tokenize(_T(";"), i), j++)
- {
- if(j == 0) ; // desc
- else if(j == 1 && s2 != _T("0")) // state
- {
- StringToBin(s2, stream.m_data);
- }
- else if(j == 2) fn = s2; // path
- }
- SendMessage(WM_COMMAND, ID_FILE_CLOSEMEDIA);
- CComPtr<IDvdState> pDvdState;
- HRESULT hr = OleLoadFromStream((IStream*)&stream, IID_IDvdState, (void**)&pDvdState);
- CAutoPtr<OpenDVDData> p(new OpenDVDData());
- if(p) {p->path = fn; p->pDvdState = pDvdState;}
- OpenMedia(p);
- }
- }
- void CMainFrame::OnUpdateFavoritesDVD(CCmdUI* pCmdUI)
- {
- UINT nID = pCmdUI->m_nID - ID_FAVORITES_DVD_START;
- }
- void CMainFrame::OnFavoritesDevice(UINT nID)
- {
- nID -= ID_FAVORITES_DEVICE_START;
- }
- void CMainFrame::OnUpdateFavoritesDevice(CCmdUI* pCmdUI)
- {
- UINT nID = pCmdUI->m_nID - ID_FAVORITES_DEVICE_START;
- }
- // help
- void CMainFrame::OnHelpHomepage()
- {
- ShellExecute(m_hWnd, _T("open"), _T("http://gabest.org/"), NULL, NULL, SW_SHOWDEFAULT);
- }
- void CMainFrame::OnHelpDocumentation()
- {
- ShellExecute(m_hWnd, _T("open"), _T("http://sourceforge.net/project/showfiles.php?group_id=82303&package_id=144472"), NULL, NULL, SW_SHOWDEFAULT);
- }
- void CMainFrame::OnHelpDonate()
- {
- const TCHAR URL[] = _T("http://order.kagi.com/?N4A");
- if(CString(URL).Find(CString(_T("A4N")).MakeReverse()) >= 0)
- ShellExecute(m_hWnd, _T("open"), URL, NULL, NULL, SW_SHOWDEFAULT);
- }
- //////////////////////////////////
- void CMainFrame::SetDefaultWindowRect()
- {
- AppSettings& s = AfxGetAppSettings();
- {
- CRect r1, r2;
- GetClientRect(&r1);
- m_wndView.GetClientRect(&r2);
- CSize logosize = m_wndView.GetLogoSize();
- int _DEFCLIENTW = max(logosize.cx, DEFCLIENTW);
- int _DEFCLIENTH = max(logosize.cy, DEFCLIENTH);
- DWORD style = GetStyle();
- MENUBARINFO mbi;
- memset(&mbi, 0, sizeof(mbi));
- mbi.cbSize = sizeof(mbi);
- ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
- int w = _DEFCLIENTW + GetSystemMetrics((style&WS_CAPTION)?SM_CXSIZEFRAME:SM_CXFIXEDFRAME)*2
- + r1.Width() - r2.Width();
- int h = _DEFCLIENTH + GetSystemMetrics((style&WS_CAPTION)?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2
- + (mbi.rcBar.bottom - mbi.rcBar.top)
- + r1.Height() - r2.Height()
- + 1; // ???
- // + 2; // ???
- if(style&WS_CAPTION) h += GetSystemMetrics(SM_CYCAPTION);
- if(s.HasFixedWindowSize())
- {
- w = s.fixedWindowSize.cx;
- h = s.fixedWindowSize.cy;
- }
- else if(s.fRememberWindowSize)
- {
- w = s.rcLastWindowPos.Width();
- h = s.rcLastWindowPos.Height();
- }
- MONITORINFO mi;
- mi.cbSize = sizeof(MONITORINFO);
- GetMonitorInfo(MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &mi);
- int x = (mi.rcWork.left+mi.rcWork.right-w)/2;
- int y = (mi.rcWork.top+mi.rcWork.bottom-h)/2;
- if(s.fRememberWindowPos)
- {
- CRect r = s.rcLastWindowPos;
- // x = r.CenterPoint().x - w/2;
- // y = r.CenterPoint().y - h/2;
- x = r.TopLeft().x;
- y = r.TopLeft().y;
- }
- UINT lastWindowType = s.lastWindowType;
- MoveWindow(x, y, w, h);
- if(s.fRememberWindowSize && s.fRememberWindowPos)
- {
- WINDOWPLACEMENT wp;
- memset(&wp, 0, sizeof(wp));
- wp.length = sizeof(WINDOWPLACEMENT);
- if(lastWindowType == SIZE_MAXIMIZED)
- ShowWindow(SW_MAXIMIZE);
- else if(lastWindowType == SIZE_MINIMIZED)
- ShowWindow(SW_MINIMIZE);
- }
- }
- if(s.fHideCaptionMenu)
- {
- ModifyStyle(WS_CAPTION, 0, SWP_NOZORDER);
- ::SetMenu(m_hWnd, NULL);
- SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
- }
- }
- void CMainFrame::RestoreDefaultWindowRect()
- {
- AppSettings& s = AfxGetAppSettings();
- WINDOWPLACEMENT wp;
- GetWindowPlacement(&wp);
- if(!m_fFullScreen && wp.showCmd != SW_SHOWMAXIMIZED && wp.showCmd != SW_SHOWMINIMIZED
- // && (GetExStyle()&WS_EX_APPWINDOW)
- && !s.fRememberWindowSize)
- {
- CRect r1, r2;
- GetClientRect(&r1);
- m_wndView.GetClientRect(&r2);
- CSize logosize = m_wndView.GetLogoSize();
- int _DEFCLIENTW = max(logosize.cx, DEFCLIENTW);
- int _DEFCLIENTH = max(logosize.cy, DEFCLIENTH);
- DWORD style = GetStyle();
- MENUBARINFO mbi;
- memset(&mbi, 0, sizeof(mbi));
- mbi.cbSize = sizeof(mbi);
- ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
- int w = _DEFCLIENTW + GetSystemMetrics((style&WS_CAPTION)?SM_CXSIZEFRAME:SM_CXFIXEDFRAME)*2
- + r1.Width() - r2.Width();
- int h = _DEFCLIENTH + GetSystemMetrics((style&WS_CAPTION)?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2
- + (mbi.rcBar.bottom - mbi.rcBar.top)
- + r1.Height() - r2.Height()
- + 1; // ???
- // + 2; // ???
- if(style&WS_CAPTION) h += GetSystemMetrics(SM_CYCAPTION);
- if(s.HasFixedWindowSize())
- {
- w = s.fixedWindowSize.cx;
- h = s.fixedWindowSize.cy;
- }
- CRect r;
- GetWindowRect(r);
- int x = r.CenterPoint().x - w/2;
- int y = r.CenterPoint().y - h/2;
- if(s.fRememberWindowPos)
- {
- CRect r = s.rcLastWindowPos;
- x = r.TopLeft().x;
- y = r.TopLeft().y;
- }
- MoveWindow(x, y, w, h);
- }
- }
- OAFilterState CMainFrame::GetMediaState()
- {
- OAFilterState ret = -1;
- if(m_iMediaLoadState == MLS_LOADED) pMC->GetState(0, &ret);
- return(ret);
- }
- CSize CMainFrame::GetVideoSize()
- {
- bool fKeepAspectRatio = AfxGetAppSettings().fKeepAspectRatio;
- bool fCompMonDeskARDiff = AfxGetAppSettings().fCompMonDeskARDiff;
- CSize ret(0,0);
- if(m_iMediaLoadState != MLS_LOADED || m_fAudioOnly)
- return ret;
- CSize wh(0, 0), arxy(0, 0);
- if(m_pCAP)
- {
- wh = m_pCAP->GetVideoSize(false);
- arxy = m_pCAP->GetVideoSize(fKeepAspectRatio);
- }
- else
- {
- pBV->GetVideoSize(&wh.cx, &wh.cy);
- long arx = 0, ary = 0;
- CComQIPtr<IBasicVideo2> pBV2 = pBV;
- if(pBV2 && SUCCEEDED(pBV2->GetPreferredAspectRatio(&arx, &ary)) && arx > 0 && ary > 0)
- arxy.SetSize(arx, ary);
- }
- CSize& ar = AfxGetAppSettings().AspectRatio;
- if(ar.cx && ar.cy) arxy = ar;
- if(wh.cx <= 0 || wh.cy <= 0)
- return ret;
- // with the overlay mixer IBasicVideo2 won't tell the new AR when changed dynamically
- DVD_VideoAttributes VATR;
- if(m_iPlaybackMode == PM_DVD && SUCCEEDED(pDVDI->GetCurrentVideoAttributes(&VATR)))
- arxy.SetSize(VATR.ulAspectX, VATR.ulAspectY);
- ret = (!fKeepAspectRatio || arxy.cx <= 0 || arxy.cy <= 0)
- ? wh
- : CSize(MulDiv(wh.cy, arxy.cx, arxy.cy), wh.cy);
- if(fCompMonDeskARDiff)
- if(HDC hDC = ::GetDC(0))
- {
- int _HORZSIZE = GetDeviceCaps(hDC, HORZSIZE);
- int _VERTSIZE = GetDeviceCaps(hDC, VERTSIZE);
- int _HORZRES = GetDeviceCaps(hDC, HORZRES);
- int _VERTRES = GetDeviceCaps(hDC, VERTRES);
- if(_HORZSIZE > 0 && _VERTSIZE > 0 && _HORZRES > 0 && _VERTRES > 0)
- {
- double a = 1.0*_HORZSIZE/_VERTSIZE;
- double b = 1.0*_HORZRES/_VERTRES;
- if(b < a)
- ret.cy = (DWORD)(1.0*ret.cy * a / b);
- else if(a < b)
- ret.cx = (DWORD)(1.0*ret.cx * b / a);
- }
- ::ReleaseDC(0, hDC);
- }
- return ret;
- }
- void CMainFrame::ToggleFullscreen(bool fToNearest, bool fSwitchScreenResWhenHasTo)
- {
- CRect r;
- // const CWnd* pWndInsertAfter;
- DWORD dwRemove = 0, dwAdd = 0;
- DWORD dwRemoveEx = 0, dwAddEx = 0;
- HMENU hMenu;
- if(!m_fFullScreen)
- {
- GetWindowRect(&m_lastWindowRect);
- dispmode& dm = AfxGetAppSettings().dmFullscreenRes;
- m_dmBeforeFullscreen.fValid = false;
- if(dm.fValid && fSwitchScreenResWhenHasTo)
- {
- GetCurDispMode(m_dmBeforeFullscreen);
- SetDispMode(dm);
- }
- MONITORINFO mi;
- mi.cbSize = sizeof(MONITORINFO);
- GetMonitorInfo(MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &mi);
- dwRemove = WS_CAPTION|WS_THICKFRAME;
- if(fToNearest) r = mi.rcMonitor;
- else GetDesktopWindow()->GetWindowRect(&r);
- hMenu = NULL;
- }
- else
- {
- if(m_dmBeforeFullscreen.fValid)
- SetDispMode(m_dmBeforeFullscreen);
- dwAdd = (AfxGetAppSettings().fHideCaptionMenu ? 0 : WS_CAPTION) | WS_THICKFRAME;
- r = m_lastWindowRect;
- hMenu = AfxGetAppSettings().fHideCaptionMenu ? NULL : m_hMenuDefault;
- }
- m_lastMouseMove.x = m_lastMouseMove.y = -1;
- bool fAudioOnly = m_fAudioOnly;
- m_fAudioOnly = true;
- m_fFullScreen = !m_fFullScreen;
- SetAlwaysOnTop(AfxGetAppSettings().iOnTop);
- ModifyStyle(dwRemove, dwAdd, SWP_NOZORDER);
- ModifyStyleEx(dwRemoveEx, dwAddEx, SWP_NOZORDER);
- ::SetMenu(m_hWnd, hMenu);
- SetWindowPos(NULL, r.left, r.top, r.Width(), r.Height(), SWP_NOZORDER|SWP_NOSENDCHANGING /*SWP_FRAMECHANGED*/);
- if(m_fFullScreen)
- {
- m_fHideCursor = true;
- ShowControls(CS_NONE, false);
- }
- else
- {
- KillTimer(TIMER_FULLSCREENCONTROLBARHIDER);
- KillTimer(TIMER_FULLSCREENMOUSEHIDER);
- m_fHideCursor = false;
- ShowControls(AfxGetAppSettings().nCS);
- }
- m_wndView.SetWindowPos(NULL, 0, 0, 0, 0, SWP_FRAMECHANGED|SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER);
- m_fAudioOnly = fAudioOnly;
- MoveVideoWindow();
- }
- void CMainFrame::MoveVideoWindow(bool fShowStats)
- {
- if(m_iMediaLoadState == MLS_LOADED && !m_fAudioOnly && IsWindowVisible())
- {
- CRect wr;
- if(!m_fFullScreen)
- {
- m_wndView.GetClientRect(wr);
- if(!AfxGetAppSettings().fHideCaptionMenu)
- wr.DeflateRect(2, 2);
- }
- else
- {
- GetWindowRect(&wr);
- // HACK
- CRect r;
- m_wndView.GetWindowRect(&r);
- wr -= r.TopLeft();
- }
- CRect vr = CRect(0,0,0,0);
- OAFilterState fs = GetMediaState();
- if(fs == State_Paused || fs == State_Running || fs == State_Stopped && (m_fShockwaveGraph || m_fQuicktimeGraph))
- {
- CSize arxy = GetVideoSize();
- int iDefaultVideoSize = AfxGetAppSettings().iDefaultVideoSize;
- CSize ws =
- iDefaultVideoSize == DVS_HALF ? CSize(arxy.cx/2, arxy.cy/2) :
- iDefaultVideoSize == DVS_NORMAL ? arxy :
- iDefaultVideoSize == DVS_DOUBLE ? CSize(arxy.cx*2, arxy.cy*2) :
- wr.Size();
- int w = ws.cx;
- int h = ws.cy;
- if(!m_fShockwaveGraph) //&& !m_fQuicktimeGraph)
- {
- if(iDefaultVideoSize == DVS_FROMINSIDE || iDefaultVideoSize == DVS_FROMOUTSIDE)
- {
- h = ws.cy;
- w = MulDiv(h, arxy.cx, arxy.cy);
- if(iDefaultVideoSize == DVS_FROMINSIDE && w > ws.cx
- || iDefaultVideoSize == DVS_FROMOUTSIDE && w < ws.cx)
- {
- w = ws.cx;
- h = MulDiv(w, arxy.cy, arxy.cx);
- }
- }
- }
- CSize size(
- (int)(m_ZoomX*w),
- (int)(m_ZoomY*h));
- CPoint pos(
- (int)(m_PosX*(wr.Width()*3 - m_ZoomX*w) - wr.Width()),
- (int)(m_PosY*(wr.Height()*3 - m_ZoomY*h) - wr.Height()));
- /* CPoint pos(
- (int)(m_PosX*(wr.Width() - size.cx)),
- (int)(m_PosY*(wr.Height() - size.cy)));
- */
- vr = CRect(pos, size);
- }
- wr |= CRect(0,0,0,0);
- vr |= CRect(0,0,0,0);
- if(m_pCAP)
- {
- m_pCAP->SetPosition(wr, vr);
- }
- else
- {
- HRESULT hr;
- hr = pBV->SetDefaultSourcePosition();
- hr = pBV->SetDestinationPosition(vr.left, vr.top, vr.Width(), vr.Height());
- hr = pVW->SetWindowPosition(wr.left, wr.top, wr.Width(), wr.Height());
- }
- m_wndView.SetVideoRect(wr);
- if(fShowStats && vr.Height() > 0)
- {
- CString info;
- info.Format(_T("Pos %.2f %.2f, Zoom %.2f %.2f, AR %.2f"), m_PosX, m_PosY, m_ZoomX, m_ZoomY, (float)vr.Width()/vr.Height());
- SendStatusMessage(info, 3000);
- }
- }
- else
- {
- m_wndView.SetVideoRect();
- }
- }
- void CMainFrame::ZoomVideoWindow(double scale)
- {
- if(m_iMediaLoadState != MLS_LOADED)
- return;
- AppSettings& s = AfxGetAppSettings();
- if(scale <= 0)
- {
- scale = s.iZoomLevel == 0 ? 0.5 : s.iZoomLevel == 2 ? 2.0 : 1.0;
- }
- if(m_fFullScreen)
- {
- OnViewFullscreen();
- }
- MINMAXINFO mmi;
- OnGetMinMaxInfo(&mmi);
- CRect r;
- int w = 0, h = 0;
- if(!m_fAudioOnly)
- {
- CSize arxy = GetVideoSize();
- long lWidth = int(arxy.cx * scale + 0.5);
- long lHeight = int(arxy.cy * scale + 0.5);
- DWORD style = GetStyle();
- CRect r1, r2;
- GetClientRect(&r1);
- m_wndView.GetClientRect(&r2);
- w = GetSystemMetrics((style&WS_CAPTION)?SM_CXSIZEFRAME:SM_CXFIXEDFRAME)*2
- + r1.Width() - r2.Width()
- + lWidth;
- MENUBARINFO mbi;
- memset(&mbi, 0, sizeof(mbi));
- mbi.cbSize = sizeof(mbi);
- ::GetMenuBarInfo(m_hWnd, OBJID_MENU, 0, &mbi);
- h = GetSystemMetrics((style&WS_CAPTION)?SM_CYSIZEFRAME:SM_CYFIXEDFRAME)*2
- + (mbi.rcBar.bottom - mbi.rcBar.top)
- + r1.Height() - r2.Height()
- + lHeight;
- if(style&WS_CAPTION)
- {
- h += GetSystemMetrics(SM_CYCAPTION);
- w += 2; h += 2; // for the 1 pixel wide sunken frame
- w += 2; h += 3; // for the inner black border
- }
- GetWindowRect(r);
- w = max(w, mmi.ptMinTrackSize.x);
- h = max(h, mmi.ptMinTrackSize.y);
- }
- else
- {
- GetWindowRect(r);
- w = r.Width(); // mmi.ptMinTrackSize.x;
- h = mmi.ptMinTrackSize.y;
- }
- // center window
- if(!s.fRememberWindowPos)
- {
- CPoint cp = r.CenterPoint();
- r.left = cp.x - w/2;
- r.top = cp.y - h/2;
- }
- r.right = r.left + w;
- r.bottom = r.top + h;
- MONITORINFO mi;
- mi.cbSize = sizeof(MONITORINFO);
- GetMonitorInfo(MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &mi);
- if(r.right > mi.rcWork.right) r.OffsetRect(mi.rcWork.right-r.right, 0);
- if(r.left < mi.rcWork.left) r.OffsetRect(mi.rcWork.left-r.left, 0);
- if(r.bottom > mi.rcWork.bottom) r.OffsetRect(0, mi.rcWork.bottom-r.bottom);
- if(r.top < mi.rcWork.top) r.OffsetRect(0, mi.rcWork.top-r.top);
- if(m_fFullScreen || !s.HasFixedWindowSize())
- {
- MoveWindow(r);
- }
- // ShowWindow(SW_SHOWNORMAL);
- MoveVideoWindow();
- }
- void CMainFrame::RepaintVideo()
- {
- if(m_pCAP) m_pCAP->Paint(false);
- }
- void CMainFrame::SetBalance(int balance)
- {
- AfxGetAppSettings().nBalance = balance;
- int sign = balance>0?-1:1;
- balance = max(100-abs(balance), 1);
- balance = (int)((log10(1.0*balance)-2)*5000*sign);
- balance = max(min(balance, 10000), -10000);
- if(m_iMediaLoadState == MLS_LOADED)
- pBA->put_Balance(balance);
- }
- void CMainFrame::SetupIViAudReg()
- {
- if(!AfxGetAppSettings().fAutoSpeakerConf) return;
- DWORD spc = 0, defchnum = 0;
- if(AfxGetAppSettings().fAutoSpeakerConf)
- {
- CComPtr<IDirectSound> pDS;
- if(SUCCEEDED(DirectSoundCreate(NULL, &pDS, NULL))
- && SUCCEEDED(pDS->SetCooperativeLevel(m_hWnd, DSSCL_NORMAL)))
- {
- if(SUCCEEDED(pDS->GetSpeakerConfig(&spc)))
- {
- switch(spc)
- {
- case DSSPEAKER_DIRECTOUT: defchnum = 6; break;
- case DSSPEAKER_HEADPHONE: defchnum = 2; break;
- case DSSPEAKER_MONO: defchnum = 1; break;
- case DSSPEAKER_QUAD: defchnum = 4; break;
- default:
- case DSSPEAKER_STEREO: defchnum = 2; break;
- case DSSPEAKER_SURROUND: defchnum = 2; break;
- case DSSPEAKER_5POINT1: defchnum = 5; break;
- case DSSPEAKER_7POINT1: defchnum = 5; break;
- }
- }
- }
- }
- else
- {
- defchnum = 2;
- }
- CRegKey iviaud;
- if(ERROR_SUCCESS == iviaud.Create(HKEY_LOCAL_MACHINE, _T("SOFTWARE\InterVideo\Common\AudioDec")))
- {
- DWORD chnum = 0;
- if(FAILED(iviaud.QueryDWORDValue(_T("AUDIO"), chnum))) chnum = 0;
- if(chnum <= defchnum) // check if the user has already set it..., but we won't skip if it's lower than sensible :P
- iviaud.SetDWORDValue(_T("AUDIO"), defchnum);
- }
- }
- //
- // Open/Close
- //
- void CMainFrame::OpenCreateGraphObject(OpenMediaData* pOMD)
- {
- pGB = NULL;
- m_fCustomGraph = false;
- m_fRealMediaGraph = m_fShockwaveGraph = m_fQuicktimeGraph = false;
- if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD))
- {
- AppSettings& s = AfxGetAppSettings();
- engine_t engine = s.Formats.GetEngine(p->fns.GetHead());
- CStringA ct = GetContentType(p->fns.GetHead());
- if(ct == "video/x-ms-asf")
- {
- // TODO: put something here to make the windows media source filter load later
- }
- else if(ct == "audio/x-pn-realaudio"
- || ct == "audio/x-pn-realaudio-plugin"
- || ct == "audio/x-realaudio-secure"
- || ct == "video/vnd.rn-realvideo-secure"
- || ct == "application/vnd.rn-realmedia"
- || ct.Find("vnd.rn-") >= 0
- || ct.Find("realaudio") >= 0
- || ct.Find("realvideo") >= 0)
- {
- engine = RealMedia;
- }
- else if(ct == "application/x-shockwave-flash")
- {
- engine = ShockWave;
- }
- else if(ct == "video/quicktime"
- || ct == "application/x-quicktimeplayer")
- {
- engine = QuickTime;
- }
- HRESULT hr;
- CComPtr<IUnknown> pUnk;
- if(engine == RealMedia)
- {
- if(!(pUnk = (IUnknown*)(INonDelegatingUnknown*)new CRealMediaGraph(m_wndView.m_hWnd, hr)))
- throw _T("Out of memory");
- m_pCAP = CComQIPtr<ISubPicAllocatorPresenter>(pUnk);
- // if(FAILED(hr) || !(pGB = CComQIPtr<IGraphBuilder>(pUnk)))
- // throw _T("RealMedia files require RealPlayer/RealOne to be installed");
- if(SUCCEEDED(hr) && !!(pGB = CComQIPtr<IGraphBuilder>(pUnk)))
- m_fRealMediaGraph = true;
- }
- else if(engine == ShockWave)
- {
- if(!(pUnk = (IUnknown*)(INonDelegatingUnknown*)new CShockwaveGraph(m_wndView.m_hWnd, hr)))
- throw _T("Out of memory");
- if(FAILED(hr) || !(pGB = CComQIPtr<IGraphBuilder>(pUnk)))
- throw _T("Can't create shockwave control");
- m_fShockwaveGraph = true;
- }
- else if(engine == QuickTime)
- {
- if(!(pUnk = (IUnknown*)(INonDelegatingUnknown*)new CQuicktimeGraph(m_wndView.m_hWnd, hr)))
- throw _T("Out of memory");
- m_pCAP = CComQIPtr<ISubPicAllocatorPresenter>(pUnk);
- // if(FAILED(hr) || !(pGB = CComQIPtr<IGraphBuilder>(pUnk)))
- // throw _T("Can't initialize QuickTime");
- if(SUCCEEDED(hr) && !!(pGB = CComQIPtr<IGraphBuilder>(pUnk)))
- m_fQuicktimeGraph = true;
- }
- m_fCustomGraph = m_fRealMediaGraph || m_fShockwaveGraph || m_fQuicktimeGraph;
- }
- if(!m_fCustomGraph)
- {
- if(FAILED(pGB.CoCreateInstance(CLSID_FilterGraph)))
- {
- throw _T("Failed to create the filter graph object");
- }
- }
- pMC = pGB; pME = pGB; pMS = pGB; // general
- pVW = pGB; pBV = pGB; // video
- pBA = pGB; // audio
- pFS = pGB;
- if(!(pMC && pME && pMS)
- || !(pVW && pBV)
- || !(pBA))
- {
- throw _T("Failed to query the needed interfaces for playback");
- }
- if(FAILED(pME->SetNotifyWindow((OAHWND)m_hWnd, WM_GRAPHNOTIFY, 0)))
- {
- throw _T("Could not set target window for graph notification");
- }
- m_pProv = (IUnknown*)new CKeyProvider();
-
- if(CComQIPtr<IObjectWithSite> pObjectWithSite = pGB)
- pObjectWithSite->SetSite(m_pProv);
- m_pCB = new CDSMChapterBag(NULL, NULL);
- }
- void CMainFrame::OpenFile(OpenFileData* pOFD)
- {
- if(pOFD->fns.IsEmpty())
- throw _T("Invalid argument");
- AppSettings& s = AfxGetAppSettings();
- CGraphBuilderFile gb(pGB, m_wndView.m_hWnd);
- bool fFirst = true;
- POSITION pos = pOFD->fns.GetHeadPosition();
- while(pos)
- {
- CString fn = pOFD->fns.GetNext(pos);
- fn.Trim();
- if(fn.IsEmpty() && !fFirst)
- break;
- HRESULT hr = gb.Render(fn);
- if(FAILED(hr))
- {
- if(fFirst)
- {
- if(s.fReportFailedPins && gb.GetDeadEnd(0))
- {
- CMediaTypesDlg(gb, this).DoModal();
- if(gb.GetStreamCount() == 0)
- throw _T("Cannot render any of the streams");
- }
- CString err;
- switch(hr)
- {
- case E_ABORT: err = _T("Opening aborted"); break;
- case E_FAIL: case E_POINTER: default: err = _T("Failed to render the file"); break;
- case E_INVALIDARG: err = _T("Invalid file name"); break;
- case E_OUTOFMEMORY: err = _T("Out of memory"); break;
- case VFW_E_CANNOT_CONNECT: err = _T("Cannot connect the filters"); break;
- case VFW_E_CANNOT_LOAD_SOURCE_FILTER: err = _T("Cannot load any source filter"); break;
- case VFW_E_CANNOT_RENDER: err = _T("Cannot render the file"); break;
- case VFW_E_INVALID_FILE_FORMAT: err = _T("Invalid file format"); break;
- case VFW_E_NOT_FOUND: err = _T("File not found"); break;
- case VFW_E_UNKNOWN_FILE_TYPE: err = _T("Unknown file type"); break;
- case VFW_E_UNSUPPORTED_STREAM: err = _T("Unsupported stream"); break;
- }
- throw err;
- }
- }
- if(s.fKeepHistory)
- {
- CRecentFileList* pMRU = fFirst ? &s.MRU : &s.MRUDub;
- pMRU->ReadList();
- pMRU->Add(fn);
- pMRU->WriteList();
- }
- if(fFirst)
- {
- pOFD->title = fn;
- }
- fFirst = false;
- if(m_fCustomGraph) break;
- }
- if(s.fReportFailedPins && gb.GetDeadEnd(0))
- CMediaTypesDlg(gb, this).DoModal();
- if(!m_fCustomGraph)
- gb.FindInterface(__uuidof(ISubPicAllocatorPresenter), (void**)&m_pCAP);
- if(!(pAMOP = pGB))
- {
- BeginEnumFilters(pGB, pEF, pBF)
- if(pAMOP = pBF) break;
- EndEnumFilters
- }
- if(FindFilter(__uuidof(CShoutcastSource), pGB))
- m_fUpdateInfoBar = true;
- SetupChapters();
- CComQIPtr<IKeyFrameInfo> pKFI;
- BeginEnumFilters(pGB, pEF, pBF)
- if(pKFI = pBF) break;
- EndEnumFilters
- UINT nKFs = 0, nKFsTmp = 0;
- if(pKFI && S_OK == pKFI->GetKeyFrameCount(nKFs) && nKFs > 0)
- {
- m_kfs.SetSize(nKFsTmp = nKFs);
- if(S_OK != pKFI->GetKeyFrames(&TIME_FORMAT_MEDIA_TIME, m_kfs.GetData(), nKFsTmp) || nKFsTmp != nKFs)
- m_kfs.SetSize(0);
- }
- m_iPlaybackMode = PM_FILE;
- }
- void CMainFrame::SetupChapters()
- {
- ASSERT(m_pCB);
- m_pCB->ChapRemoveAll();
- CInterfaceList<IBaseFilter> pBFs;
- BeginEnumFilters(pGB, pEF, pBF)
- pBFs.AddTail(pBF);
- EndEnumFilters
- POSITION pos;
- pos = pBFs.GetHeadPosition();
- while(pos && !m_pCB->ChapGetCount())
- {
- IBaseFilter* pBF = pBFs.GetNext(pos);
- CComQIPtr<IDSMChapterBag> pCB = pBF;
- if(!pCB) continue;
- for(DWORD i = 0, cnt = pCB->ChapGetCount(); i < cnt; i++)
- {
- REFERENCE_TIME rt;
- CComBSTR name;
- if(SUCCEEDED(pCB->ChapGet(i, &rt, &name)))
- m_pCB->ChapAppend(rt, name);
- }
- }
- pos = pBFs.GetHeadPosition();
- while(pos && !m_pCB->ChapGetCount())
- {
- IBaseFilter* pBF = pBFs.GetNext(pos);
- CComQIPtr<IChapterInfo> pCI = pBF;
- if(!pCI) continue;
- CHAR iso6391[3];
- ::GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, iso6391, 3);
- CStringA iso6392 = ISO6391To6392(iso6391);
- if(iso6392.GetLength() < 3) iso6392 = "eng";
- UINT cnt = pCI->GetChapterCount(CHAPTER_ROOT_ID);
- for(UINT i = 1; i <= cnt; i++)
- {
- UINT cid = pCI->GetChapterId(CHAPTER_ROOT_ID, i);
- ChapterElement ce;
- if(pCI->GetChapterInfo(cid, &ce))
- {
- char pl[3] = {iso6392[0], iso6392[1], iso6392[2]};
- char cc[] = " ";
- CComBSTR name;
- name.Attach(pCI->GetChapterStringInfo(cid, pl, cc));
- m_pCB->ChapAppend(ce.rtStart, name);
- }
- }
- }
- pos = pBFs.GetHeadPosition();
- while(pos && !m_pCB->ChapGetCount())
- {
- IBaseFilter* pBF = pBFs.GetNext(pos);
- CComQIPtr<IAMExtendedSeeking, &IID_IAMExtendedSeeking> pES = pBF;
- if(!pES) continue;
- long MarkerCount = 0;
- if(SUCCEEDED(pES->get_MarkerCount(&MarkerCount)))
- {
- for(long i = 1; i <= MarkerCount; i++)
- {
- double MarkerTime = 0;
- if(SUCCEEDED(pES->GetMarkerTime(i, &MarkerTime)))
- {
- CStringW name;
- name.Format(L"Chapter %d", i);
- CComBSTR bstr;
- if(S_OK == pES->GetMarkerName(i, &bstr))
- name = bstr;
- m_pCB->ChapAppend(REFERENCE_TIME(MarkerTime*10000000), name);
- }
- }
- }
- }
- pos = pBFs.GetHeadPosition();
- while(pos && !m_pCB->ChapGetCount())
- {
- IBaseFilter* pBF = pBFs.GetNext(pos);
- if(GetCLSID(pBF) != CLSID_OggSplitter)
- continue;
- BeginEnumPins(pBF, pEP, pPin)
- {
- if(m_pCB->ChapGetCount()) break;
- if(CComQIPtr<IPropertyBag> pPB = pPin)
- {
- for(int i = 1; ; i++)
- {
- CStringW str;
- CComVariant var;
- var.Clear();
- str.Format(L"CHAPTER%02d", i);
- if(S_OK != pPB->Read(str, &var, NULL))
- break;
- int h, m, s, ms;
- WCHAR wc;
- if(7 != swscanf(CStringW(var), L"%d%c%d%c%d%c%d", &h, &wc, &m, &wc, &s, &wc, &ms))
- break;
- CStringW name;
- name.Format(L"Chapter %d", i);
- var.Clear();
- str += L"NAME";
- if(S_OK == pPB->Read(str, &var, NULL))
- name = var;
- m_pCB->ChapAppend(10000i64*(((h*60 + m)*60 + s)*1000 + ms), name);
- }
- }
- }
- EndEnumPins
- }
- m_pCB->ChapSort();
- }
- void CMainFrame::OpenDVD(OpenDVDData* pODD)
- {
- CGraphBuilderDVD gb(pGB, m_wndView.m_hWnd);
- HRESULT hr = gb.Render(pODD->path, pODD->title);
- AppSettings& s = AfxGetAppSettings();
- if(hr == VFW_E_CANNOT_LOAD_SOURCE_FILTER)
- throw _T("Can't find DVD directory");
- else if(hr == VFW_E_CANNOT_RENDER)
- throw _T("Failed to render all pins of the DVD Navigator filter");
- else if(hr == VFW_S_PARTIAL_RENDER)
- {
- if(s.fReportFailedPins && gb.GetDeadEnd(0))
- CMediaTypesDlg(gb, this).DoModal();
- throw _T("Failed to render some of the pins of the DVD Navigator filter");
- }
- else if(hr == E_NOINTERFACE)
- throw _T("Failed to query the needed interfaces for DVD playback");
- else if(FAILED(hr))
- throw _T("Can't create the DVD Navigator filter");
- gb.FindInterface(__uuidof(ISubPicAllocatorPresenter), (void**)&m_pCAP);
- gb.FindInterface(__uuidof(IDvdControl2), (void**)&pDVDC);
- gb.FindInterface(__uuidof(IDvdInfo2), (void**)&pDVDI);
- if(!pDVDC || !pDVDI)
- throw _T("Failed to query the needed interfaces for DVD playback");
- if(s.idMenuLang)
- pDVDC->SelectDefaultMenuLanguage(s.idMenuLang);
- if(s.idAudioLang)
- pDVDC->SelectDefaultAudioLanguage(s.idAudioLang, DVD_AUD_EXT_NotSpecified);
- if(s.idSubtitlesLang)
- pDVDC->SelectDefaultSubpictureLanguage(s.idSubtitlesLang, DVD_SP_EXT_NotSpecified);
- m_iDVDDomain = DVD_DOMAIN_Stop;
- m_iPlaybackMode = PM_DVD;
- }
- void CMainFrame::OpenCapture(OpenDeviceData* pODD)
- {
- CStringW vidfrname, audfrname;
- CComPtr<IBaseFilter> pVidCapTmp, pAudCapTmp;
- m_VidDispName = pODD->DisplayName[0];
- if(!m_VidDispName.IsEmpty())
- {
- if(!CreateFilter(m_VidDispName, &pVidCapTmp, vidfrname))
- throw _T("Can't create video capture filter");
- }
- m_AudDispName = pODD->DisplayName[1];
- if(!m_AudDispName.IsEmpty())
- {
- if(!CreateFilter(m_AudDispName, &pAudCapTmp, audfrname))
- throw _T("Can't create video capture filter");
- }
- if(!pVidCapTmp && !pAudCapTmp)
- {
- throw _T("No capture filters");
- }
- pCGB = NULL;
- pVidCap = NULL;
- pAudCap = NULL;
- if(FAILED(pCGB.CoCreateInstance(CLSID_CaptureGraphBuilder2)))
- {
- throw _T("Can't create capture graph builder object");
- }
- HRESULT hr;
- pCGB->SetFiltergraph(pGB);
- if(pVidCapTmp)
- {
- if(FAILED(hr = pGB->AddFilter(pVidCapTmp, vidfrname)))
- {
- throw _T("Can't add video capture filter to the graph");
- }
- pVidCap = pVidCapTmp;
- if(!pAudCapTmp)
- {
- if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCCap))
- && FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCCap)))
- TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
- if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Interleaved, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCPrev))
- && FAILED(pCGB->FindInterface(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Video, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCPrev)))
- TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
- if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, pVidCap, IID_IAMStreamConfig, (void **)&pAMASC))
- && FAILED(pCGB->FindInterface(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Audio, pVidCap, IID_IAMStreamConfig, (void **)&pAMASC)))
- {
- TRACE(_T("Warning: No IAMStreamConfig interface for vidcap"));
- }
- else
- {
- pAudCap = pVidCap;
- }
- }
- else
- {
- if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCCap)))
- TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
- if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVidCap, IID_IAMStreamConfig, (void **)&pAMVSCPrev)))
- TRACE(_T("Warning: No IAMStreamConfig interface for vidcap capture"));
- }
- if(FAILED(pCGB->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pVidCap, IID_IAMCrossbar, (void**)&pAMXBar)))
- TRACE(_T("Warning: No IAMCrossbar interface was foundn"));
- if(FAILED(pCGB->FindInterface(&LOOK_UPSTREAM_ONLY, NULL, pVidCap, IID_IAMTVTuner, (void**)&pAMTuner)))
- TRACE(_T("Warning: No IAMTVTuner interface was foundn"));
- /*
- if(pAMVSCCap)
- {
- //DumpStreamConfig(_T("c:\mpclog.txt"), pAMVSCCap);
- CComQIPtr<IAMVfwCaptureDialogs> pVfwCD = pVidCap;
- if(!pAMXBar && pVfwCD)
- {
- m_wndCaptureBar.m_capdlg.SetupVideoControls(viddispname, pAMVSCCap, pVfwCD);
- }
- else
- {
- m_wndCaptureBar.m_capdlg.SetupVideoControls(viddispname, pAMVSCCap, pAMXBar, pAMTuner);
- }
- }
- */
- // TODO: init pAMXBar
- if(pAMTuner) // load saved channel
- {
- pAMTuner->put_CountryCode(AfxGetApp()->GetProfileInt(_T("Capture"), _T("Country"), 1));
- int vchannel = pODD->vchannel;
- if(vchannel < 0) vchannel = AfxGetApp()->GetProfileInt(_T("Capture\") + CString(m_VidDispName), _T("Channel"), -1);
- if(vchannel >= 0)
- {
- OAFilterState fs = State_Stopped;
- pMC->GetState(0, &fs);
- if(fs == State_Running) pMC->Pause();
- pAMTuner->put_Channel(vchannel, AMTUNER_SUBCHAN_DEFAULT, AMTUNER_SUBCHAN_DEFAULT);
- if(fs == State_Running) pMC->Run();
- }
- }
- }
- if(pAudCapTmp)
- {
- if(FAILED(hr = pGB->AddFilter(pAudCapTmp, CStringW(audfrname))))
- {
- throw _T("Can't add audio capture filter to the graph");
- }
- pAudCap = pAudCapTmp;
- if(FAILED(pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, pAudCap, IID_IAMStreamConfig, (void **)&pAMASC))
- && FAILED(pCGB->FindInterface(&PIN_CATEGORY_PREVIEW, &MEDIATYPE_Audio, pAudCap, IID_IAMStreamConfig, (void **)&pAMASC)))
- {
- TRACE(_T("Warning: No IAMStreamConfig interface for vidcap"));
- }
- /*
- CInterfaceArray<IAMAudioInputMixer> pAMAIM;
- BeginEnumPins(pAudCap, pEP, pPin)
- {
- PIN_DIRECTION dir;
- if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_INPUT)
- continue;
- if(CComQIPtr<IAMAudioInputMixer> pAIM = pPin)
- pAMAIM.Add(pAIM);
- }
- EndEnumPins
- if(pAMASC)
- {
- m_wndCaptureBar.m_capdlg.SetupAudioControls(auddispname, pAMASC, pAMAIM);
- }
- */
- }
- if(!(pVidCap || pAudCap))
- {
- throw _T("Couldn't open any device");
- }
- pODD->title = _T("Live");
-
- m_iPlaybackMode = PM_CAPTURE;
- }
- void CMainFrame::OpenCustomizeGraph()
- {
- if(m_iPlaybackMode == PM_CAPTURE)
- return;
- CleanGraph();
- if(m_iPlaybackMode == PM_FILE)
- {
- if(m_pCAP)
- AddTextPassThruFilter();
- }
- if(m_iPlaybackMode == PM_DVD)
- {
- BeginEnumFilters(pGB, pEF, pBF)
- {
- if(CComQIPtr<IDirectVobSub2> pDVS2 = pBF)
- {
- // pDVS2->AdviseSubClock(m_pSubClock = new CSubClock);
- // break;
- // TODO: test multiple dvobsub instances with one clock
- if(!m_pSubClock) m_pSubClock = new CSubClock;
- pDVS2->AdviseSubClock(m_pSubClock);
- }
- }
- EndEnumFilters
- }
- BeginEnumFilters(pGB, pEF, pBF)
- {
- if(GetCLSID(pBF) == CLSID_OggSplitter)
- {
- if(CComQIPtr<IAMStreamSelect> pSS = pBF)
- {
- LCID idAudio = AfxGetAppSettings().idAudioLang;
- if(!idAudio) idAudio = GetUserDefaultLCID();
- LCID idSub = AfxGetAppSettings().idSubtitlesLang;
- if(!idSub) idSub = GetUserDefaultLCID();
- DWORD cnt = 0;
- pSS->Count(&cnt);
- for(DWORD i = 0; i < cnt; i++)
- {
- AM_MEDIA_TYPE* pmt = NULL;
- DWORD dwFlags = 0;
- LCID lcid = 0;
- DWORD dwGroup = 0;
- WCHAR* pszName = NULL;
- if(SUCCEEDED(pSS->Info((long)i, &pmt, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL)))
- {
- CStringW name(pszName), sound(L"Sound"), subtitle(L"Subtitle");
- if(idAudio != -1 && (idAudio&0x3ff) == (lcid&0x3ff) // sublang seems to be zeroed out in ogm...
- && name.GetLength() > sound.GetLength()
- && !name.Left(sound.GetLength()).CompareNoCase(sound))
- {
- if(SUCCEEDED(pSS->Enable(i, AMSTREAMSELECTENABLE_ENABLE)))
- idAudio = -1;
- }
- if(idSub != -1 && (idSub&0x3ff) == (lcid&0x3ff) // sublang seems to be zeroed out in ogm...
- && name.GetLength() > subtitle.GetLength()
- && !name.Left(subtitle.GetLength()).CompareNoCase(subtitle)
- && name.Mid(subtitle.GetLength()).Trim().CompareNoCase(L"off"))
- {
- if(SUCCEEDED(pSS->Enable(i, AMSTREAMSELECTENABLE_ENABLE)))
- idSub = -1;
- }
- if(pmt) DeleteMediaType(pmt);
- if(pszName) CoTaskMemFree(pszName);
- }
- }
- }
- }
- }
- EndEnumFilters
- CleanGraph();
- }
- void CMainFrame::OpenSetupVideo()
- {
- m_fAudioOnly = true;
- if(m_pCAP)
- {
- CSize vs = m_pCAP->GetVideoSize();
- m_fAudioOnly = (vs.cx <= 0 || vs.cy <= 0);
- }
- else
- {
- {
- long w = 0, h = 0;
- if(CComQIPtr<IBasicVideo> pBV = pGB)
- {
- pBV->GetVideoSize(&w, &h);
- }
- if(w > 0 && h > 0)
- {
- m_fAudioOnly = false;
- }
- }
- if(m_fAudioOnly)
- {
- BeginEnumFilters(pGB, pEF, pBF)
- {
- long w = 0, h = 0;
- if(CComQIPtr<IVideoWindow> pVW = pBF)
- {
- long lVisible;
- if(FAILED(pVW->get_Visible(&lVisible)))
- continue;
- pVW->get_Width(&w);
- pVW->get_Height(&h);
- }
- if(w > 0 && h > 0)
- {
- m_fAudioOnly = false;
- break;
- }
- }
- EndEnumFilters
- }
- }
- if(m_fShockwaveGraph)
- {
- m_fAudioOnly = false;
- }
- if(!m_pCAP)
- {
- pVW->put_Owner((OAHWND)m_wndView.m_hWnd);
- pVW->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN);
- pVW->put_MessageDrain((OAHWND)m_hWnd);
- for(CWnd* pWnd = m_wndView.GetWindow(GW_CHILD); pWnd; pWnd = pWnd->GetNextWindow())
- pWnd->EnableWindow(FALSE); // little trick to let WM_SETCURSOR thru
- }
- else
- {
- return;
- /* char pSrcData[] =
- "sampler s0 : register(s0);rn"
- "float4 p0 : register(c0);rn"
- "rn"
- "#define counter (p0[2])rn"
- "#define clock (p0[3])rn"
- "rn"
- "float4 main(float2 t0 : TEXCOORD0) : COLORrn"
- "{rn"
- "tfloat4 c0 = tex2D(s0, t0);rn"
- "tfloat3 lightsrc = float3(sin(clock*3.1415/3000)/2+0.5,cos(clock*3.1415/1000)/2+0.5,1);rn"
- "tfloat3 light = normalize(lightsrc - float3(t0.x,t0.y,0));rn"
- "tc0 *= pow(dot(light, float3(0,0,1)), 10);rn"
- "treturn c0;rn"
- "}rn";
- //CComPtr<ID3DXBuffer> pErrorMsgs;
- HRESULT hr = m_pCAP->SetPixelShader(pSrcData, "ps_2_0");
- if(FAILED(hr))
- {
- CStringA err;
- int len = pErrorMsgs->GetBufferSize();
- memcpy(err.GetBufferSetLength(len), pErrorMsgs->GetBufferPointer(), len);
- if(!err.IsEmpty()) AfxMessageBox(CString(err), MB_OK);
- }
- */
- }
- }
- void CMainFrame::OpenSetupAudio()
- {
- pBA->put_Volume(m_wndToolBar.Volume);
- // FIXME
- int balance = AfxGetAppSettings().nBalance;
- int sign = balance>0?-1:1;
- balance = max(100-abs(balance), 1);
- balance = (int)((log10(1.0*balance)-2)*5000*sign);
- balance = max(min(balance, 10000), -10000);
- pBA->put_Balance(balance);
- }
- /*
- void CMainFrame::OpenSetupToolBar()
- {
- // m_wndToolBar.Volume = AfxGetAppSettings().nVolume;
- // SetBalance(AfxGetAppSettings().nBalance);
- }
- */
- void CMainFrame::OpenSetupCaptureBar()
- {
- if(m_iPlaybackMode == PM_CAPTURE)
- {
- if(pVidCap && pAMVSCCap)
- {
- CComQIPtr<IAMVfwCaptureDialogs> pVfwCD = pVidCap;
- if(!pAMXBar && pVfwCD)
- {
- m_wndCaptureBar.m_capdlg.SetupVideoControls(m_VidDispName, pAMVSCCap, pVfwCD);
- }
- else
- {
- m_wndCaptureBar.m_capdlg.SetupVideoControls(m_VidDispName, pAMVSCCap, pAMXBar, pAMTuner);
- }
- }
- if(pAudCap && pAMASC)
- {
- CInterfaceArray<IAMAudioInputMixer> pAMAIM;
- BeginEnumPins(pAudCap, pEP, pPin)
- {
- PIN_DIRECTION dir;
- if(FAILED(pPin->QueryDirection(&dir)) || dir != PINDIR_INPUT)
- continue;
- if(CComQIPtr<IAMAudioInputMixer> pAIM = pPin)
- pAMAIM.Add(pAIM);
- }
- EndEnumPins
- m_wndCaptureBar.m_capdlg.SetupAudioControls(m_AudDispName, pAMASC, pAMAIM);
- }
- }
- BuildGraphVideoAudio(
- !!m_wndCaptureBar.m_capdlg.m_fVidPreview, false,
- !!m_wndCaptureBar.m_capdlg.m_fAudPreview, false);
- }
- void CMainFrame::OpenSetupInfoBar()
- {
- if(m_iPlaybackMode == PM_FILE)
- {
- bool fEmpty = true;
- BeginEnumFilters(pGB, pEF, pBF)
- {
- if(CComQIPtr<IAMMediaContent, &IID_IAMMediaContent> pAMMC = pBF)
- {
- CComBSTR bstr;
- if(SUCCEEDED(pAMMC->get_Title(&bstr))) {m_wndInfoBar.SetLine(_T("Title"), bstr.m_str); if(bstr.Length()) fEmpty = false;}
- if(SUCCEEDED(pAMMC->get_AuthorName(&bstr))) {m_wndInfoBar.SetLine(_T("Author"), bstr.m_str); if(bstr.Length()) fEmpty = false;}
- if(SUCCEEDED(pAMMC->get_Copyright(&bstr))) {m_wndInfoBar.SetLine(_T("Copyright"), bstr.m_str); if(bstr.Length()) fEmpty = false;}
- if(SUCCEEDED(pAMMC->get_Rating(&bstr))) {m_wndInfoBar.SetLine(_T("Rating"), bstr.m_str); if(bstr.Length()) fEmpty = false;}
- if(SUCCEEDED(pAMMC->get_Description(&bstr))) {m_wndInfoBar.SetLine(_T("Description"), bstr.m_str); if(bstr.Length()) fEmpty = false;}
- if(!fEmpty)
- {
- RecalcLayout();
- break;
- }
- }
- }
- EndEnumFilters
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- CString info('-');
- m_wndInfoBar.SetLine(_T("Domain"), info);
- m_wndInfoBar.SetLine(_T("Location"), info);
- m_wndInfoBar.SetLine(_T("Video"), info);
- m_wndInfoBar.SetLine(_T("Audio"), info);
- m_wndInfoBar.SetLine(_T("Subtitles"), info);
- RecalcLayout();
- }
- }
- void CMainFrame::OpenSetupStatsBar()
- {
- CString info('-');
- BeginEnumFilters(pGB, pEF, pBF)
- {
- if(!pQP && (pQP = pBF))
- {
- m_wndStatsBar.SetLine(_T("Frame-rate"), info);
- m_wndStatsBar.SetLine(_T("Sync Offset"), info);
- m_wndStatsBar.SetLine(_T("Frames"), info);
- m_wndStatsBar.SetLine(_T("Jitter"), info);
- m_wndStatsBar.SetLine(_T("Buffers"), info);
- m_wndStatsBar.SetLine(_T("Bitrate"), info);
- RecalcLayout();
- }
- if(!pBI && (pBI = pBF))
- {
- m_wndStatsBar.SetLine(_T("Buffers"), info);
- m_wndStatsBar.SetLine(_T("Bitrate"), info); // FIXME: shouldn't be here
- RecalcLayout();
- }
- }
- EndEnumFilters
- }
- void CMainFrame::OpenSetupStatusBar()
- {
- m_wndStatusBar.ShowTimer(true);
- //
- if(!m_fCustomGraph)
- {
- UINT id = IDB_NOAUDIO;
- BeginEnumFilters(pGB, pEF, pBF)
- {
- CComQIPtr<IBasicAudio> pBA = pBF;
- if(!pBA) continue;
- BeginEnumPins(pBF, pEP, pPin)
- {
- PIN_DIRECTION dir;
- CComPtr<IPin> pPinTo;
- if(S_OK == pPin->QueryDirection(&dir) && dir == PINDIR_INPUT
- && S_OK == pPin->ConnectedTo(&pPinTo) && pPinTo)
- {
- AM_MEDIA_TYPE mt;
- memset(&mt, 0, sizeof(mt));
- pPin->ConnectionMediaType(&mt);
- if(mt.majortype == MEDIATYPE_Audio
- && mt.formattype == FORMAT_WaveFormatEx)
- {
- switch(((WAVEFORMATEX*)mt.pbFormat)->nChannels)
- {
- case 1: id = IDB_MONO; break;
- case 2: default: id = IDB_STEREO; break;
- }
- break;
- }
- else if(mt.majortype == MEDIATYPE_Midi)
- {
- id = NULL;
- break;
- }
- }
- }
- EndEnumPins
- if(id != IDB_NOAUDIO)
- {
- break;
- }
- }
- EndEnumFilters
- m_wndStatusBar.SetStatusBitmap(id);
- }
- //
- HICON hIcon = NULL;
- if(m_iPlaybackMode == PM_FILE)
- {
- CString fn = m_wndPlaylistBar.GetCur();
- CString ext = fn.Mid(fn.ReverseFind('.')+1);
- hIcon = LoadIcon(ext, true);
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- hIcon = LoadIcon(_T(".ifo"), true);
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- // hIcon = ; // TODO
- }
- m_wndStatusBar.SetStatusTypeIcon(hIcon);
- }
- void CMainFrame::OpenSetupWindowTitle(CString fn)
- {
- CString title(MAKEINTRESOURCE(IDR_MAINFRAME));
- int i = AfxGetAppSettings().iTitleBarTextStyle;
- if(!fn.IsEmpty() && (i == 0 || i == 1))
- {
- if(i == 1)
- {
- if(m_iPlaybackMode == PM_FILE)
- {
- fn.Replace('\', '/');
- CString fn2 = fn.Mid(fn.ReverseFind('/')+1);
- if(!fn2.IsEmpty()) fn = fn2;
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- fn = _T("DVD");
- }
- else if(m_iPlaybackMode == PM_CAPTURE)
- {
- fn = _T("Live");
- }
- }
- title = fn + _T(" - ") + title;
- }
- SetWindowText(title);
- }
- bool CMainFrame::OpenMediaPrivate(CAutoPtr<OpenMediaData> pOMD)
- {
- if(m_iMediaLoadState != MLS_CLOSED)
- {
- ASSERT(0);
- return(false);
- }
- if(!dynamic_cast<OpenFileData*>(pOMD.m_p)
- && !dynamic_cast<OpenDVDData*>(pOMD.m_p)
- && !dynamic_cast<OpenDeviceData*>(pOMD.m_p))
- {
- ASSERT(0);
- return(false);
- }
- if(OpenFileData* pOFD = dynamic_cast<OpenFileData*>(pOMD.m_p))
- {
- if(pOFD->fns.IsEmpty())
- return(false);
- CString fn = pOFD->fns.GetHead();
- int i = fn.Find(_T(":\"));
- if(i > 0)
- {
- CString drive = fn.Left(i+2);
- UINT type = GetDriveType(drive);
- CList<CString> sl;
- if(type == DRIVE_REMOVABLE || type == DRIVE_CDROM && GetCDROMType(drive[0], sl) != CDROM_Audio)
- {
- int ret = IDRETRY;
- while(ret == IDRETRY)
- {
- WIN32_FIND_DATA findFileData;
- HANDLE h = FindFirstFile(fn, &findFileData);
- if(h != INVALID_HANDLE_VALUE)
- {
- FindClose(h);
- ret = IDOK;
- }
- else
- {
- CString msg;
- msg.Format(_T("%s was not found, please insert media containing this file."), fn);
- ret = AfxMessageBox(msg, MB_RETRYCANCEL);
- }
- }
- if(ret != IDOK)
- return(false);
- }
- }
- }
- m_iMediaLoadState = MLS_LOADING;
- // FIXME: Don't show "Closed" initially
- PostMessage(WM_KICKIDLE);
- CString err, aborted(_T("Aborted"));
- m_fUpdateInfoBar = false;
- try
- {
- if(m_fOpeningAborted) throw aborted;
- OpenCreateGraphObject(pOMD);
- AddToRot(pGB, &m_dwRegister);
- if(m_fOpeningAborted) throw aborted;
- SetupIViAudReg();
- if(m_fOpeningAborted) throw aborted;
- if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p))
- {
- OpenFile(p);
- }
- else if(OpenDVDData* p = dynamic_cast<OpenDVDData*>(pOMD.m_p))
- {
- OpenDVD(p);
- }
- else if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p))
- {
- OpenCapture(p);
- }
- else
- {
- throw _T("Can't open, invalid input parameters");
- }
- if(m_fOpeningAborted) throw aborted;
- OpenCustomizeGraph();
- if(m_fOpeningAborted) throw aborted;
- OpenSetupVideo();
- if(m_fOpeningAborted) throw aborted;
- OpenSetupAudio();
- if(m_fOpeningAborted) throw aborted;
- if(m_pCAP && (!m_fAudioOnly || m_fRealMediaGraph))
- {
- POSITION pos = pOMD->subs.GetHeadPosition();
- while(pos) LoadSubtitle(pOMD->subs.GetNext(pos));
- if(m_pSubStreams.GetCount() > 0)
- SetSubtitle(m_pSubStreams.GetHead());
- }
- if(m_fOpeningAborted) throw aborted;
- OpenSetupWindowTitle(pOMD->title);
- if(::GetCurrentThreadId() == AfxGetApp()->m_nThreadID)
- {
- OnFilePostOpenmedia();
- }
- else
- {
- PostMessage(WM_COMMAND, ID_FILE_POST_OPENMEDIA);
- }
- while(m_iMediaLoadState != MLS_LOADED
- && m_iMediaLoadState != MLS_CLOSING // FIXME
- )
- {
- Sleep(50);
- }
- // PostMessage instead of SendMessage because the user might call CloseMedia and then we would deadlock
- PostMessage(WM_COMMAND, ID_PLAY_PAUSE);
- if(!(AfxGetAppSettings().nCLSwitches&CLSW_OPEN))
- PostMessage(WM_COMMAND, ID_PLAY_PLAY);
- AfxGetAppSettings().nCLSwitches &= ~CLSW_OPEN;
- if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p))
- {
- if(p->rtStart > 0)
- PostMessage(WM_RESUMEFROMSTATE, (WPARAM)PM_FILE, (LPARAM)(p->rtStart/10000)); // REFERENCE_TIME doesn't fit in LPARAM under a 32bit env.
- }
- else if(OpenDVDData* p = dynamic_cast<OpenDVDData*>(pOMD.m_p))
- {
- if(p->pDvdState)
- PostMessage(WM_RESUMEFROMSTATE, (WPARAM)PM_DVD, (LPARAM)(CComPtr<IDvdState>(p->pDvdState).Detach())); // must be released by the called message handler
- }
- else if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p))
- {
- m_wndCaptureBar.m_capdlg.SetVideoInput(p->vinput);
- m_wndCaptureBar.m_capdlg.SetVideoChannel(p->vchannel);
- m_wndCaptureBar.m_capdlg.SetAudioInput(p->ainput);
- }
- }
- catch(LPCTSTR msg)
- {
- err = msg;
- }
- catch(CString msg)
- {
- err = msg;
- }
- if(!err.IsEmpty())
- {
- CloseMediaPrivate();
- m_closingmsg = err;
- OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p);
- if(p && err != aborted)
- {
- m_wndPlaylistBar.SetCurValid(false);
- if(m_wndPlaylistBar.GetCount() > 1)
- {
- CPlaylistItem pli[2];
- m_wndPlaylistBar.GetCur(pli[0]);
- m_wndPlaylistBar.SetNext();
- m_wndPlaylistBar.GetCur(pli[1]);
- if(pli[0].m_id != pli[1].m_id)
- {
- CAutoPtr<OpenMediaData> p(m_wndPlaylistBar.GetCurOMD());
- if(p) OpenMediaPrivate(p);
- }
- }
- }
- }
- else
- {
- m_wndPlaylistBar.SetCurValid(true);
- }
- PostMessage(WM_KICKIDLE); // calls main thread to update things
- return(err.IsEmpty());
- }
- void CMainFrame::CloseMediaPrivate()
- {
- m_iMediaLoadState = MLS_CLOSING;
- OnPlayStop(); // SendMessage(WM_COMMAND, ID_PLAY_STOP);
- m_iPlaybackMode = PM_NONE;
- m_iSpeedLevel = 0;
- m_fLiveWM = false;
- m_fEndOfStream = false;
- m_rtDurationOverride = -1;
- m_kfs.RemoveAll();
- m_pCB = NULL;
- RemoveFromRot(m_dwRegister);
- // if(pVW) pVW->put_Visible(OAFALSE);
- // if(pVW) pVW->put_MessageDrain((OAHWND)NULL), pVW->put_Owner((OAHWND)NULL);
- m_pCAP = NULL; // IMPORTANT: IVMRSurfaceAllocatorNotify/IVMRSurfaceAllocatorNotify9 has to be released before the VMR/VMR9, otherwise it will crash in Release()
- m_shaderlabel.Empty();
- pAMXBar.Release(); pAMTuner.Release(); pAMDF.Release();
- pAMVCCap.Release(); pAMVCPrev.Release(); pAMVSCCap.Release(); pAMVSCPrev.Release(); pAMASC.Release();
- pVidCap.Release(); pAudCap.Release();
- pCGB.Release();
- pVMR.Release();
- pDVDC.Release(); pDVDI.Release();
- pQP.Release(); pBI.Release(); pAMOP.Release(); pFS.Release();
- pMC.Release(); pME.Release(); pMS.Release();
- pVW.Release(); pBV.Release();
- pBA.Release();
- pGB.Release();
- m_fRealMediaGraph = m_fShockwaveGraph = m_fQuicktimeGraph = false;
- m_pSubClock = NULL;
- m_pProv.Release();
- {
- CAutoLock cAutoLock(&m_csSubLock);
- m_pSubStreams.RemoveAll();
- }
- m_VidDispName.Empty();
- m_AudDispName.Empty();
- m_closingmsg = _T("Closed");
- AfxGetAppSettings().nCLSwitches &= CLSW_OPEN|CLSW_PLAY|CLSW_AFTERPLAYBACK_MASK|CLSW_NOFOCUS;
- m_iMediaLoadState = MLS_CLOSED;
- }
- // msn
- void CMainFrame::SendNowPlayingToMSN()
- {
- if(!AfxGetAppSettings().fNotifyMSN)
- return;
- CString title, author;
- if(m_iMediaLoadState == MLS_LOADED)
- {
- m_wndInfoBar.GetLine(_T("Title"), title);
- m_wndInfoBar.GetLine(_T("Author"), author);
- if(title.IsEmpty())
- {
- CPlaylistItem pli;
- m_wndPlaylistBar.GetCur(pli);
- if(!pli.m_fns.IsEmpty())
- {
- CString label = !pli.m_label.IsEmpty() ? pli.m_label : pli.m_fns.GetHead();
- if(m_iPlaybackMode == PM_FILE)
- {
- CString fn = label;
- if(fn.Find(_T("://")) >= 0) {int i = fn.Find('?'); if(i >= 0) fn = fn.Left(i);}
- CPath path(fn);
- path.StripPath();
- path.MakePretty();
- path.RemoveExtension();
- title = (LPCTSTR)path;
- author.Empty();
- }
- else if(m_iPlaybackMode == PM_CAPTURE)
- {
- title = label != pli.m_fns.GetHead() ? label : _T("Live");
- author.Empty();
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- title = _T("DVD");
- author.Empty();
- }
- }
- }
- }
- CStringW buff;
- buff += L"\0Music\0";
- buff += title.IsEmpty() ? L"0" : L"1";
- buff += L"\0";
- buff += author.IsEmpty() ? L"{0}" : L"{0} - {1}";
- buff += L"\0";
- if(!author.IsEmpty()) {buff += CStringW(author) + L"\0";}
- buff += CStringW(title) + L"\0";
- buff += L"\0\0";
- COPYDATASTRUCT data;
- data.dwData = 0x0547;
- data.lpData = (PVOID)(LPCWSTR)buff;
- data.cbData = buff.GetLength() * 2 + 2;
- HWND hWnd = NULL;
- while(hWnd = ::FindWindowEx(NULL, hWnd, _T("MsnMsgrUIManager"), NULL))
- ::SendMessage(hWnd, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&data);
- }
- // dynamic menus
- void CMainFrame::SetupOpenCDSubMenu()
- {
- CMenu* pSub = &m_opencds;
- if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
- else while(pSub->RemoveMenu(0, MF_BYPOSITION));
- if(m_iMediaLoadState == MLS_LOADING) return;
- if(AfxGetAppSettings().fHideCDROMsSubMenu) return;
- UINT id = ID_FILE_OPEN_CD_START;
- for(TCHAR drive = 'C'; drive <= 'Z'; drive++)
- {
- CString label = GetDriveLabel(drive), str;
- CList<CString> files;
- switch(GetCDROMType(drive, files))
- {
- case CDROM_Audio:
- if(label.IsEmpty()) label = _T("Audio CD");
- str.Format(_T("%s (%c:)"), label, drive);
- break;
- case CDROM_VideoCD:
- if(label.IsEmpty()) label = _T("(S)VCD");
- str.Format(_T("%s (%c:)"), label, drive);
- break;
- case CDROM_DVDVideo:
- if(label.IsEmpty()) label = _T("DVD Video");
- str.Format(_T("%s (%c:)"), label, drive);
- break;
- default:
- break;
- }
- if(!str.IsEmpty())
- pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, str);
- }
- }
- void CMainFrame::SetupFiltersSubMenu()
- {
- CMenu* pSub = &m_filters;
- if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
- else while(pSub->RemoveMenu(0, MF_BYPOSITION));
- m_filterpopups.RemoveAll();
- m_spparray.RemoveAll();
- m_ssarray.RemoveAll();
- if(m_iMediaLoadState == MLS_LOADED)
- {
- UINT idf = 0;
- UINT ids = ID_FILTERS_SUBITEM_START;
- UINT idl = ID_FILTERSTREAMS_SUBITEM_START;
- BeginEnumFilters(pGB, pEF, pBF)
- {
- CString name(GetFilterName(pBF));
- if(name.GetLength() >= 43) name = name.Left(40) + _T("...");
- CLSID clsid = GetCLSID(pBF);
- if(clsid == CLSID_AVIDec)
- {
- CComPtr<IPin> pPin = GetFirstPin(pBF);
- AM_MEDIA_TYPE mt;
- if(pPin && SUCCEEDED(pPin->ConnectionMediaType(&mt)))
- {
- DWORD c = ((VIDEOINFOHEADER*)mt.pbFormat)->bmiHeader.biCompression;
- switch(c)
- {
- case BI_RGB: name += _T(" (RGB)"); break;
- case BI_RLE4: name += _T(" (RLE4)"); break;
- case BI_RLE8: name += _T(" (RLE8)"); break;
- case BI_BITFIELDS: name += _T(" (BITF)"); break;
- default: name.Format(_T("%s (%c%c%c%c)"),
- CString(name), (TCHAR)((c>>0)&0xff), (TCHAR)((c>>8)&0xff), (TCHAR)((c>>16)&0xff), (TCHAR)((c>>24)&0xff)); break;
- }
- }
- }
- else if(clsid == CLSID_ACMWrapper)
- {
- CComPtr<IPin> pPin = GetFirstPin(pBF);
- AM_MEDIA_TYPE mt;
- if(pPin && SUCCEEDED(pPin->ConnectionMediaType(&mt)))
- {
- WORD c = ((WAVEFORMATEX*)mt.pbFormat)->wFormatTag;
- name.Format(_T("%s (0x%04x)"), CString(name), (int)c);
- }
- }
- else if(clsid == __uuidof(CTextPassThruFilter) || clsid == __uuidof(CNullTextRenderer)
- || clsid == GUIDFromCString(_T("{48025243-2D39-11CE-875D-00608CB78066}"))) // ISCR
- {
- // hide these
- continue;
- }
- CAutoPtr<CMenu> pSubSub(new CMenu);
- pSubSub->CreatePopupMenu();
- int nPPages = 0;
- CComQIPtr<ISpecifyPropertyPages> pSPP = pBF;
- if(pSPP)
- {
- CAUUID caGUID;
- caGUID.pElems = NULL;
- if(SUCCEEDED(pSPP->GetPages(&caGUID)) && caGUID.cElems > 0)
- {
- m_spparray.Add(pSPP);
- pSubSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ids, _T("&Properties..."));
- if(caGUID.pElems) CoTaskMemFree(caGUID.pElems);
- nPPages++;
- }
- }
- BeginEnumPins(pBF, pEP, pPin)
- {
- CString name = GetPinName(pPin);
- name.Replace(_T("&"), _T("&&"));
- if(pSPP = pPin)
- {
- CAUUID caGUID;
- caGUID.pElems = NULL;
- if(SUCCEEDED(pSPP->GetPages(&caGUID)) && caGUID.cElems > 0)
- {
- m_spparray.Add(pSPP);
- pSubSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ids+nPPages, name + _T(" (pin) properties..."));
- if(caGUID.pElems) CoTaskMemFree(caGUID.pElems);
-
- nPPages++;
- }
- }
- }
- EndEnumPins
- CComQIPtr<IAMStreamSelect> pSS = pBF;
- if(pSS)
- {
- DWORD nStreams = 0, flags, group, prevgroup = -1;
- LCID lcid;
- WCHAR* wname = NULL;
- CComPtr<IUnknown> pObj, pUnk;
- pSS->Count(&nStreams);
- if(nStreams > 0 && nPPages > 0) pSubSub->AppendMenu(MF_SEPARATOR|MF_ENABLED);
- UINT idlstart = idl;
- for(DWORD i = 0; i < nStreams; i++, pObj = NULL, pUnk = NULL)
- {
- m_ssarray.Add(pSS);
- flags = group = 0;
- wname = NULL;
- pSS->Info(i, NULL, &flags, &lcid, &group, &wname, &pObj, &pUnk);
- if(group != prevgroup && idl > idlstart)
- pSubSub->AppendMenu(MF_SEPARATOR|MF_ENABLED);
- prevgroup = group;
- if(flags & AMSTREAMSELECTINFO_EXCLUSIVE)
- {
- }
- else if(flags & AMSTREAMSELECTINFO_ENABLED)
- {
- }
- if(!wname)
- {
- CStringW stream(L"Unknown Stream");
- wname = (WCHAR*)CoTaskMemAlloc((stream.GetLength()+3+1)*sizeof(WCHAR));
- swprintf(wname, L"%s %d", stream, min(i+1,999));
- }
- CString name(wname);
- name.Replace(_T("&"), _T("&&"));
- pSubSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, idl++, name);
- CoTaskMemFree(wname);
- }
- if(nStreams == 0) pSS.Release();
- }
- if(nPPages == 1 && !pSS)
- {
- pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ids, name);
- }
- else
- {
- pSub->AppendMenu(MF_BYPOSITION|MF_STRING|MF_DISABLED|MF_GRAYED, idf, name);
- if(nPPages > 0 || pSS)
- {
- MENUITEMINFO mii;
- mii.cbSize = sizeof(mii);
- mii.fMask = MIIM_STATE|MIIM_SUBMENU;
- mii.fType = MF_POPUP;
- mii.hSubMenu = pSubSub->m_hMenu;
- mii.fState = (pSPP || pSS) ? MF_ENABLED : (MF_DISABLED|MF_GRAYED);
- pSub->SetMenuItemInfo(idf, &mii, TRUE);
- m_filterpopups.Add(pSubSub);
- }
- }
- ids += nPPages;
- idf++;
- }
- EndEnumFilters
- }
- }
- void CMainFrame::SetupAudioSwitcherSubMenu()
- {
- CMenu* pSub = &m_audios;
- if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
- else while(pSub->RemoveMenu(0, MF_BYPOSITION));
- if(m_iMediaLoadState == MLS_LOADED)
- {
- UINT id = ID_AUDIO_SUBITEM_START;
- CComQIPtr<IAMStreamSelect> pSS = FindFilter(__uuidof(CAudioSwitcherFilter), pGB);
- if(!pSS) pSS = FindFilter(L"{D3CD7858-971A-4838-ACEC-40CA5D529DC8}", pGB);
- if(pSS)
- {
- DWORD cStreams = 0;
- if(SUCCEEDED(pSS->Count(&cStreams)) && cStreams > 0)
- {
- pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, _T("&Options..."));
- pSub->AppendMenu(MF_SEPARATOR|MF_ENABLED);
- for(int i = 0; i < (int)cStreams; i++)
- {
- WCHAR* pName = NULL;
- if(FAILED(pSS->Info(i, NULL, NULL, NULL, NULL, &pName, NULL, NULL)))
- break;
- CString name(pName);
- name.Replace(_T("&"), _T("&&"));
- pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, name);
- CoTaskMemFree(pName);
- }
- }
- }
- }
- }
- void CMainFrame::SetupSubtitlesSubMenu()
- {
- CMenu* pSub = &m_subtitles;
- if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
- else while(pSub->RemoveMenu(0, MF_BYPOSITION));
- if(m_iMediaLoadState != MLS_LOADED || m_fAudioOnly || !m_pCAP)
- return;
- UINT id = ID_SUBTITLES_SUBITEM_START;
- POSITION pos = m_pSubStreams.GetHeadPosition();
- if(pos)
- {
- pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, _T("&Options..."));
- pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, _T("&Styles..."));
- pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, _T("&Reload"));
- pSub->AppendMenu(MF_SEPARATOR);
- pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, _T("&Enable"));
- pSub->AppendMenu(MF_SEPARATOR);
- }
- while(pos)
- {
- CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
- if(!pSubStream) continue;
- for(int i = 0, j = pSubStream->GetStreamCount(); i < j; i++)
- {
- WCHAR* pName = NULL;
- if(SUCCEEDED(pSubStream->GetStreamInfo(i, &pName, NULL)))
- {
- CString name(pName);
- name.Replace(_T("&"), _T("&&"));
- pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, name);
- CoTaskMemFree(pName);
- }
- else
- {
- pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, id++, _T("<Unknown>"));
- }
- }
- // TODO: find a better way to group these entries
- if(pos && m_pSubStreams.GetAt(pos))
- {
- CLSID cur, next;
- pSubStream->GetClassID(&cur);
- m_pSubStreams.GetAt(pos)->GetClassID(&next);
- if(cur != next)
- pSub->AppendMenu(MF_SEPARATOR);
- }
- }
- }
- void CMainFrame::SetupNavAudioSubMenu()
- {
- CMenu* pSub = &m_navaudio;
- if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
- else while(pSub->RemoveMenu(0, MF_BYPOSITION));
- if(m_iMediaLoadState != MLS_LOADED) return;
- UINT id = ID_NAVIGATE_AUDIO_SUBITEM_START;
- if(m_iPlaybackMode == PM_FILE)
- {
- SetupNavStreamSelectSubMenu(pSub, id, 1);
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- ULONG ulStreamsAvailable, ulCurrentStream;
- if(FAILED(pDVDI->GetCurrentAudio(&ulStreamsAvailable, &ulCurrentStream)))
- return;
- LCID DefLanguage;
- DVD_AUDIO_LANG_EXT ext;
- if(FAILED(pDVDI->GetDefaultAudioLanguage(&DefLanguage, &ext)))
- return;
- for(ULONG i = 0; i < ulStreamsAvailable; i++)
- {
- LCID Language;
- if(FAILED(pDVDI->GetAudioLanguage(i, &Language)))
- continue;
- UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
- if(Language == DefLanguage) flags |= MF_DEFAULT;
- if(i == ulCurrentStream) flags |= MF_CHECKED;
- CString str(_T("Unknown"));
- if(Language)
- {
- int len = GetLocaleInfo(Language, LOCALE_SENGLANGUAGE, str.GetBuffer(256), 256);
- str.ReleaseBufferSetLength(max(len-1, 0));
- }
- DVD_AudioAttributes ATR;
- if(SUCCEEDED(pDVDI->GetAudioAttributes(i, &ATR)))
- {
- switch(ATR.LanguageExtension)
- {
- case DVD_AUD_EXT_NotSpecified:
- default: break;
- case DVD_AUD_EXT_Captions: str += _T(" (Captions)"); break;
- case DVD_AUD_EXT_VisuallyImpaired: str += _T(" (Visually Impaired)"); break;
- case DVD_AUD_EXT_DirectorComments1: str += _T(" (Director Comments 1)"); break;
- case DVD_AUD_EXT_DirectorComments2: str += _T(" (Director Comments 2)"); break;
- }
- }
- str.Replace(_T("&"), _T("&&"));
- pSub->AppendMenu(flags, id++, str);
- }
- }
- }
- void CMainFrame::SetupNavSubtitleSubMenu()
- {
- CMenu* pSub = &m_navsubtitle;
- if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
- else while(pSub->RemoveMenu(0, MF_BYPOSITION));
- if(m_iMediaLoadState != MLS_LOADED) return;
- UINT id = ID_NAVIGATE_SUBP_SUBITEM_START;
- if(m_iPlaybackMode == PM_FILE)
- {
- SetupNavStreamSelectSubMenu(pSub, id, 2);
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- ULONG ulStreamsAvailable, ulCurrentStream;
- BOOL bIsDisabled;
- if(FAILED(pDVDI->GetCurrentSubpicture(&ulStreamsAvailable, &ulCurrentStream, &bIsDisabled))
- || ulStreamsAvailable == 0)
- return;
- LCID DefLanguage;
- DVD_SUBPICTURE_LANG_EXT ext;
- if(FAILED(pDVDI->GetDefaultSubpictureLanguage(&DefLanguage, &ext)))
- return;
- pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|(bIsDisabled?0:MF_CHECKED), id++, _T("Enabled"));
- pSub->AppendMenu(MF_BYCOMMAND|MF_SEPARATOR|MF_ENABLED);
- for(ULONG i = 0; i < ulStreamsAvailable; i++)
- {
- LCID Language;
- if(FAILED(pDVDI->GetSubpictureLanguage(i, &Language)))
- continue;
- UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
- if(Language == DefLanguage) flags |= MF_DEFAULT;
- if(i == ulCurrentStream) flags |= MF_CHECKED;
- CString str(_T("Unknown"));
- if(Language)
- {
- int len = GetLocaleInfo(Language, LOCALE_SENGLANGUAGE, str.GetBuffer(256), 256);
- str.ReleaseBufferSetLength(max(len-1, 0));
- }
- DVD_SubpictureAttributes ATR;
- if(SUCCEEDED(pDVDI->GetSubpictureAttributes(i, &ATR)))
- {
- switch(ATR.LanguageExtension)
- {
- case DVD_SP_EXT_NotSpecified:
- default: break;
- case DVD_SP_EXT_Caption_Normal: str += _T(""); break;
- case DVD_SP_EXT_Caption_Big: str += _T(" (Big)"); break;
- case DVD_SP_EXT_Caption_Children: str += _T(" (Children)"); break;
- case DVD_SP_EXT_CC_Normal: str += _T(" (CC)"); break;
- case DVD_SP_EXT_CC_Big: str += _T(" (CC Big)"); break;
- case DVD_SP_EXT_CC_Children: str += _T(" (CC Children)"); break;
- case DVD_SP_EXT_Forced: str += _T(" (Forced)"); break;
- case DVD_SP_EXT_DirectorComments_Normal: str += _T(" (Director Comments)"); break;
- case DVD_SP_EXT_DirectorComments_Big: str += _T(" (Director Comments, Big)"); break;
- case DVD_SP_EXT_DirectorComments_Children: str += _T(" (Director Comments, Children)"); break;
- }
- }
- str.Replace(_T("&"), _T("&&"));
- pSub->AppendMenu(flags, id++, str);
- }
- }
- }
- void CMainFrame::SetupNavAngleSubMenu()
- {
- CMenu* pSub = &m_navangle;
- if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
- else while(pSub->RemoveMenu(0, MF_BYPOSITION));
- if(m_iMediaLoadState != MLS_LOADED) return;
- UINT id = ID_NAVIGATE_ANGLE_SUBITEM_START;
- if(m_iPlaybackMode == PM_FILE)
- {
- SetupNavStreamSelectSubMenu(pSub, id, 0);
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- ULONG ulStreamsAvailable, ulCurrentStream;
- if(FAILED(pDVDI->GetCurrentAngle(&ulStreamsAvailable, &ulCurrentStream)))
- return;
- if(ulStreamsAvailable < 2) return; // one choice is not a choice...
- for(ULONG i = 0; i < ulStreamsAvailable; i++)
- {
- UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
- if(i == ulCurrentStream) flags |= MF_CHECKED;
- CString str;
- str.Format(_T("Angle %d"), i+1);
- pSub->AppendMenu(flags, id++, str);
- }
- }
- }
- void CMainFrame::SetupNavChaptersSubMenu()
- {
- CMenu* pSub = &m_navchapters;
- if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
- else while(pSub->RemoveMenu(0, MF_BYPOSITION));
- if(m_iMediaLoadState != MLS_LOADED)
- return;
- UINT id = ID_NAVIGATE_CHAP_SUBITEM_START;
- if(m_iPlaybackMode == PM_FILE)
- {
- SetupChapters();
- REFERENCE_TIME rt = GetPos();
- DWORD j = m_pCB->ChapLookup(&rt, NULL);
- for(DWORD i = 0; i < m_pCB->ChapGetCount(); i++, id++)
- {
- rt = 0;
- CComBSTR bstr;
- if(FAILED(m_pCB->ChapGet(i, &rt, &bstr)))
- continue;
- int s = (int)((rt/10000000)%60);
- int m = (int)((rt/10000000/60)%60);
- int h = (int)((rt/10000000/60/60));
- CString time;
- time.Format(_T("[%02d:%02d:%02d] "), h, m, s);
- CString name = CString(bstr);
- name.Replace(_T("&"), _T("&&"));
- name.Replace(_T("t"), _T(" "));
- UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
- if(i == j) flags |= MF_CHECKED;
- if(id != ID_NAVIGATE_CHAP_SUBITEM_START && i == 0) pSub->AppendMenu(MF_SEPARATOR);
- pSub->AppendMenu(flags, id, name + 't' + time);
- }
- if(m_wndPlaylistBar.GetCount() > 1)
- {
- POSITION pos = m_wndPlaylistBar.m_pl.GetHeadPosition();
- while(pos)
- {
- UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
- if(pos == m_wndPlaylistBar.m_pl.GetPos()) flags |= MF_CHECKED;
- if(id != ID_NAVIGATE_CHAP_SUBITEM_START && pos == m_wndPlaylistBar.m_pl.GetHeadPosition())
- pSub->AppendMenu(MF_SEPARATOR);
- CPlaylistItem& pli = m_wndPlaylistBar.m_pl.GetNext(pos);
- CString name = pli.GetLabel();
- name.Replace(_T("&"), _T("&&"));
- pSub->AppendMenu(flags, id++, name);
- }
- }
- }
- else if(m_iPlaybackMode == PM_DVD)
- {
- ULONG ulNumOfVolumes, ulVolume;
- DVD_DISC_SIDE Side;
- ULONG ulNumOfTitles = 0;
- pDVDI->GetDVDVolumeInfo(&ulNumOfVolumes, &ulVolume, &Side, &ulNumOfTitles);
- DVD_PLAYBACK_LOCATION2 Location;
- pDVDI->GetCurrentLocation(&Location);
- ULONG ulNumOfChapters = 0;
- pDVDI->GetNumberOfChapters(Location.TitleNum, &ulNumOfChapters);
- ULONG ulUOPs = 0;
- pDVDI->GetCurrentUOPS(&ulUOPs);
- for(ULONG i = 1; i <= ulNumOfTitles; i++)
- {
- UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
- if(i == Location.TitleNum) flags |= MF_CHECKED;
- if(ulUOPs&UOP_FLAG_Play_Title) flags |= MF_DISABLED|MF_GRAYED;
- CString str;
- str.Format(_T("Title %d"), i);
- pSub->AppendMenu(flags, id++, str);
- }
- for(ULONG i = 1; i <= ulNumOfChapters; i++)
- {
- UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
- if(i == Location.ChapterNum) flags |= MF_CHECKED;
- if(ulUOPs&UOP_FLAG_Play_Chapter) flags |= MF_DISABLED|MF_GRAYED;
- if(i == 1) flags |= MF_MENUBARBREAK;
- CString str;
- str.Format(_T("Chapter %d"), i);
- pSub->AppendMenu(flags, id++, str);
- }
- }
- }
- void CMainFrame::SetupNavStreamSelectSubMenu(CMenu* pSub, UINT id, DWORD dwSelGroup)
- {
- UINT baseid = id;
- CComQIPtr<IAMStreamSelect> pSS = FindFilter(CLSID_OggSplitter, pGB);
- if(!pSS) pSS = FindFilter(L"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB);
- if(!pSS) return;
- DWORD cStreams;
- if(FAILED(pSS->Count(&cStreams)))
- return;
- DWORD dwPrevGroup = -1;
- for(int i = 0, j = cStreams; i < j; i++)
- {
- DWORD dwFlags, dwGroup;
- LCID lcid;
- WCHAR* pszName = NULL;
- if(FAILED(pSS->Info(i, NULL, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL))
- || !pszName)
- continue;
- CStringW name(pszName);
- name.MakeLower();
- if(pszName) CoTaskMemFree(pszName);
- if(dwGroup != dwSelGroup)
- continue;
- if(dwPrevGroup != -1 && dwPrevGroup != dwGroup)
- pSub->AppendMenu(MF_SEPARATOR);
- dwPrevGroup = dwGroup;
- CString str;
- if(name.Find(L" off") >= 0)
- {
- str = _T("Disabled");
- }
- else if(lcid == 0)
- {
- str.Format(_T("Unknown %d"), id - baseid);
- }
- else
- {
- int len = GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, str.GetBuffer(64), 64);
- str.ReleaseBufferSetLength(max(len-1, 0));
- }
- UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
- if(dwFlags) flags |= MF_CHECKED;
-
- str.Replace(_T("&"), _T("&&"));
- pSub->AppendMenu(flags, id++, str);
- }
- }
- void CMainFrame::OnNavStreamSelectSubMenu(UINT id, DWORD dwSelGroup)
- {
- CComQIPtr<IAMStreamSelect> pSS = FindFilter(CLSID_OggSplitter, pGB);
- if(!pSS) pSS = FindFilter(L"{55DA30FC-F16B-49fc-BAA5-AE59FC65F82D}", pGB);
- if(!pSS) return;
- DWORD cStreams;
- if(FAILED(pSS->Count(&cStreams)))
- return;
- for(int i = 0, j = cStreams; i < j; i++)
- {
- DWORD dwFlags, dwGroup;
- LCID lcid;
- WCHAR* pszName = NULL;
- if(FAILED(pSS->Info(i, NULL, &dwFlags, &lcid, &dwGroup, &pszName, NULL, NULL))
- || !pszName)
- continue;
- if(pszName) CoTaskMemFree(pszName);
- if(dwGroup != dwSelGroup)
- continue;
- if(id == 0)
- {
- pSS->Enable(i, AMSTREAMSELECTENABLE_ENABLE);
- break;
- }
- id--;
- }
- }
- void CMainFrame::SetupFavoritesSubMenu()
- {
- CMenu* pSub = &m_favorites;
- if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
- else while(pSub->RemoveMenu(0, MF_BYPOSITION));
- AppSettings& s = AfxGetAppSettings();
- pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ID_FAVORITES_ADD, _T("&Add to Favorites..."));
- pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ID_FAVORITES_ORGANIZE, _T("&Organize Favorites..."));
- int nLastGroupStart = pSub->GetMenuItemCount();
- UINT id = ID_FAVORITES_FILE_START;
- CList<CString> sl;
- AfxGetAppSettings().GetFav(FAV_FILE, sl);
- POSITION pos = sl.GetHeadPosition();
- while(pos)
- {
- UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
- CString str = sl.GetNext(pos);
- str.Replace(_T("&"), _T("&&"));
- str.Replace(_T("t"), _T(" "));
- CList<CString> sl;
- Explode(str, sl, ';', 2);
- str = sl.RemoveHead();
- if(!sl.IsEmpty())
- {
- REFERENCE_TIME rt = 0;
- if(1 == _stscanf(sl.GetHead(), _T("%I64d"), &rt) && rt > 0)
- {
- DVD_HMSF_TIMECODE hmsf = RT2HMSF(rt, 0);
- str.Format(_T("%st[%02d:%02d:%02d]"), CString(str), hmsf.bHours, hmsf.bMinutes, hmsf.bSeconds);
- }
- }
- if(!str.IsEmpty())
- pSub->AppendMenu(flags, id, str);
- id++;
- }
- if(id > ID_FAVORITES_FILE_START)
- pSub->InsertMenu(nLastGroupStart, MF_SEPARATOR|MF_ENABLED|MF_BYPOSITION);
- nLastGroupStart = pSub->GetMenuItemCount();
- id = ID_FAVORITES_DVD_START;
- AfxGetAppSettings().GetFav(FAV_DVD, sl);
- pos = sl.GetHeadPosition();
- while(pos)
- {
- UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
- CString str = sl.GetNext(pos);
- str.Replace(_T("&"), _T("&&"));
- CList<CString> sl;
- Explode(str, sl, ';', 2);
- str = sl.RemoveHead();
- if(!sl.IsEmpty())
- {
- // TODO
- }
- if(!str.IsEmpty())
- pSub->AppendMenu(flags, id, str);
- id++;
- }
- if(id > ID_FAVORITES_DVD_START)
- pSub->InsertMenu(nLastGroupStart, MF_SEPARATOR|MF_ENABLED|MF_BYPOSITION);
- nLastGroupStart = pSub->GetMenuItemCount();
- id = ID_FAVORITES_DEVICE_START;
- AfxGetAppSettings().GetFav(FAV_DEVICE, sl);
- pos = sl.GetHeadPosition();
- while(pos)
- {
- UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
- CString str = sl.GetNext(pos);
- str.Replace(_T("&"), _T("&&"));
- CList<CString> sl;
- Explode(str, sl, ';', 2);
- str = sl.RemoveHead();
- if(!str.IsEmpty())
- pSub->AppendMenu(flags, id, str);
- id++;
- }
- }
- void CMainFrame::SetupShadersSubMenu()
- {
- CMenu* pSub = &m_shaders;
- if(!IsMenu(pSub->m_hMenu)) pSub->CreatePopupMenu();
- else while(pSub->RemoveMenu(0, MF_BYPOSITION));
- CWinApp* pApp = AfxGetApp();
- pSub->AppendMenu(MF_BYCOMMAND|MF_STRING|MF_ENABLED, ID_SHADERS_START, ResStr(IDS_SHADER_EDIT));
- UINT id = ID_SHADERS_START+1;
- for(int i = 0; ; i++)
- {
- CString str;
- str.Format(_T("%d"), i);
- str = pApp->GetProfileString(_T("Shaders"), str);
- CList<CString> sl;
- CString label = Explode(str, sl, '|');
- if(label.IsEmpty()) break;
- UINT flags = MF_BYCOMMAND|MF_STRING|MF_ENABLED;
- if(i == 0)
- {
- pSub->AppendMenu(MF_SEPARATOR);
- pSub->AppendMenu(flags, id++, ResStr(IDS_SHADER_OFF));
- }
- label.Replace(_T("&"), _T("&&"));
- pSub->AppendMenu(flags, id++, label);
- }
- }
- /////////////
- void CMainFrame::ShowControls(int nCS, bool fSave)
- {
- int nCSprev = AfxGetAppSettings().nCS;
- int hbefore = 0, hafter = 0;
- m_pLastBar = NULL;
- POSITION pos = m_bars.GetHeadPosition();
- for(int i = 1; pos; i <<= 1)
- {
- CControlBar* pNext = m_bars.GetNext(pos);
- ShowControlBar(pNext, !!(nCS&i), TRUE);
- if(nCS&i) m_pLastBar = pNext;
- CSize s = pNext->CalcFixedLayout(FALSE, TRUE);
- if(nCSprev&i) hbefore += s.cy;
- if(nCS&i) hafter += s.cy;
- }
- WINDOWPLACEMENT wp;
- wp.length = sizeof(wp);
- GetWindowPlacement(&wp);
- if(wp.showCmd != SW_SHOWMAXIMIZED && !m_fFullScreen)
- {
- CRect r;
- GetWindowRect(r);
- MoveWindow(r.left, r.top, r.Width(), r.Height()+(hafter-hbefore));
- }
- if(fSave)
- AfxGetAppSettings().nCS = nCS;
- RecalcLayout();
- }
- void CMainFrame::SetAlwaysOnTop(int i)
- {
- AfxGetAppSettings().iOnTop = i;
- if(!m_fFullScreen)
- {
- const CWnd* pInsertAfter = NULL;
- if(i == 0)
- pInsertAfter = &wndNoTopMost;
- else if(i == 1)
- pInsertAfter = &wndTopMost;
- else // if(i == 2)
- pInsertAfter = GetMediaState() == State_Running ? &wndTopMost : &wndNoTopMost;
- SetWindowPos(pInsertAfter, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
- }
- else if(!(GetWindowLong(m_hWnd, GWL_EXSTYLE)&WS_EX_TOPMOST))
- {
- SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
- }
- }
- void CMainFrame::AddTextPassThruFilter()
- {
- BeginEnumFilters(pGB, pEF, pBF)
- {
- if(!IsSplitter(pBF)) continue;
- BeginEnumPins(pBF, pEP, pPin)
- {
- CComPtr<IPin> pPinTo;
- AM_MEDIA_TYPE mt;
- if(FAILED(pPin->ConnectedTo(&pPinTo)) || !pPinTo
- || FAILED(pPin->ConnectionMediaType(&mt))
- || mt.majortype != MEDIATYPE_Text && mt.majortype != MEDIATYPE_Subtitle)
- continue;
- CComQIPtr<IBaseFilter> pTPTF = new CTextPassThruFilter(this);
- CStringW name;
- name.Format(L"TextPassThru%08x", pTPTF);
- if(FAILED(pGB->AddFilter(pTPTF, name)))
- continue;
- HRESULT hr;
- hr = pPinTo->Disconnect();
- hr = pPin->Disconnect();
- if(FAILED(hr = pGB->ConnectDirect(pPin, GetFirstPin(pTPTF, PINDIR_INPUT), NULL))
- || FAILED(hr = pGB->ConnectDirect(GetFirstPin(pTPTF, PINDIR_OUTPUT), pPinTo, NULL)))
- hr = pGB->ConnectDirect(pPin, pPinTo, NULL);
- else
- m_pSubStreams.AddTail(CComQIPtr<ISubStream>(pTPTF));
- }
- EndEnumPins
- }
- EndEnumFilters
- }
- bool CMainFrame::LoadSubtitle(CString fn)
- {
- CComPtr<ISubStream> pSubStream;
- // TMP: maybe this will catch something for those who get a runtime error dialog when opening subtitles from cds
- try
- {
- if(!pSubStream)
- {
- CAutoPtr<CVobSubFile> pVSF(new CVobSubFile(&m_csSubLock));
- if(pVSF && pVSF->Open(fn) && pVSF->GetStreamCount() > 0)
- pSubStream = pVSF.Detach();
- }
- if(!pSubStream)
- {
- CAutoPtr<CRenderedTextSubtitle> pRTS(new CRenderedTextSubtitle(&m_csSubLock));
- if(pRTS && pRTS->Open(fn, DEFAULT_CHARSET) && pRTS->GetStreamCount() > 0)
- pSubStream = pRTS.Detach();
- }
- }
- catch(CException* e)
- {
- e->Delete();
- }
- if(pSubStream)
- {
- m_pSubStreams.AddTail(pSubStream);
- }
- return(!!pSubStream);
- }
- void CMainFrame::UpdateSubtitle(bool fApplyDefStyle)
- {
- if(!m_pCAP) return;
- int i = m_iSubtitleSel;
- POSITION pos = m_pSubStreams.GetHeadPosition();
- while(pos && i >= 0)
- {
- CComPtr<ISubStream> pSubStream = m_pSubStreams.GetNext(pos);
- if(i < pSubStream->GetStreamCount())
- {
- CAutoLock cAutoLock(&m_csSubLock);
- pSubStream->SetStream(i);
- SetSubtitle(pSubStream, fApplyDefStyle);
- return;
- }
- i -= pSubStream->GetStreamCount();
- }
- m_pCAP->SetSubPicProvider(NULL);
- }
- void CMainFrame::SetSubtitle(ISubStream* pSubStream, bool fApplyDefStyle)
- {
- AppSettings& s = AfxGetAppSettings();
- if(pSubStream)
- {
- CLSID clsid;
- pSubStream->GetClassID(&clsid);
- if(clsid == __uuidof(CVobSubFile))
- {
- CVobSubFile* pVSF = (CVobSubFile*)(ISubStream*)pSubStream;
- if(fApplyDefStyle)
- {
- pVSF->SetAlignment(s.fOverridePlacement, s.nHorPos, s.nVerPos, 1, 1);
- }
- }
- if(clsid == __uuidof(CVobSubStream))
- {
- CVobSubStream* pVSS = (CVobSubStream*)(ISubStream*)pSubStream;
- if(fApplyDefStyle)
- {
- pVSS->SetAlignment(s.fOverridePlacement, s.nHorPos, s.nVerPos, 1, 1);
- }
- }
- else if(clsid == __uuidof(CRenderedTextSubtitle))
- {
- CRenderedTextSubtitle* pRTS = (CRenderedTextSubtitle*)(ISubStream*)pSubStream;
- STSStyle style;
- if(fApplyDefStyle || pRTS->m_fUsingAutoGeneratedDefaultStyle)
- {
- style = s.subdefstyle;
- if(s.fOverridePlacement)
- {
- style.scrAlignment = 2;
- int w = pRTS->m_dstScreenSize.cx;
- int h = pRTS->m_dstScreenSize.cy;
- int mw = w - style.marginRect.left - style.marginRect.right;
- style.marginRect.bottom = h - MulDiv(h, s.nVerPos, 100);
- style.marginRect.left = MulDiv(w, s.nHorPos, 100) - mw/2;
- style.marginRect.right = w - (style.marginRect.left + mw);
- }
- pRTS->SetDefaultStyle(style);
- }
- if(pRTS->GetDefaultStyle(style) && style.relativeTo == 2)
- {
- style.relativeTo = s.subdefstyle.relativeTo;
- pRTS->SetDefaultStyle(style);
- }
- pRTS->Deinit();
- }
- }
- if(!fApplyDefStyle)
- {
- m_iSubtitleSel = -1;
- if(pSubStream)
- {
- int i = 0;
- POSITION pos = m_pSubStreams.GetHeadPosition();
- while(pos)
- {
- CComPtr<ISubStream> pSubStream2 = m_pSubStreams.GetNext(pos);
- if(pSubStream == pSubStream2)
- {
- m_iSubtitleSel = i + pSubStream2->GetStream();
- break;
- }
- i += pSubStream2->GetStreamCount();
- }
- }
- }
- m_nSubtitleId = (DWORD_PTR)pSubStream;
- if(m_pCAP)
- {
- m_pCAP->SetSubPicProvider(CComQIPtr<ISubPicProvider>(pSubStream));
- m_wndSubresyncBar.SetSubtitle(pSubStream, m_pCAP->GetFPS());
- }
- }
- void CMainFrame::ReplaceSubtitle(ISubStream* pSubStreamOld, ISubStream* pSubStreamNew)
- {
- POSITION pos = m_pSubStreams.GetHeadPosition();
- while(pos)
- {
- POSITION cur = pos;
- if(pSubStreamOld == m_pSubStreams.GetNext(pos))
- {
- m_pSubStreams.SetAt(cur, pSubStreamNew);
- UpdateSubtitle();
- break;
- }
- }
- }
- void CMainFrame::InvalidateSubtitle(DWORD_PTR nSubtitleId, REFERENCE_TIME rtInvalidate)
- {
- if(m_pCAP)
- {
- if(nSubtitleId == -1 || nSubtitleId == m_nSubtitleId)
- m_pCAP->Invalidate(rtInvalidate);
- }
- }
- void CMainFrame::ReloadSubtitle()
- {
- POSITION pos = m_pSubStreams.GetHeadPosition();
- while(pos) m_pSubStreams.GetNext(pos)->Reload();
- UpdateSubtitle();
- }
- REFERENCE_TIME CMainFrame::GetPos()
- {
- return(m_iMediaLoadState == MLS_LOADED ? m_wndSeekBar.GetPos() : 0);
- }
- REFERENCE_TIME CMainFrame::GetDur()
- {
- __int64 start, stop;
- m_wndSeekBar.GetRange(start, stop);
- return(m_iMediaLoadState == MLS_LOADED ? stop : 0);
- }
- void CMainFrame::SeekTo(REFERENCE_TIME rtPos, bool fSeekToKeyFrame)
- {
- OAFilterState fs = GetMediaState();
- if(rtPos < 0) rtPos = 0;
- if(m_iPlaybackMode == PM_FILE)
- {
- if(fs == State_Stopped)
- SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
- HRESULT hr;
- if(fSeekToKeyFrame)
- {
- if(!m_kfs.IsEmpty())
- {
- int i = rangebsearch(rtPos, m_kfs);
- if(i >= 0 && i < m_kfs.GetCount())
- rtPos = m_kfs[i];
- }
- }
- hr = pMS->SetPositions(&rtPos, AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning);
- }
- else if(m_iPlaybackMode == PM_DVD && m_iDVDDomain == DVD_DOMAIN_Title)
- {
- if(fs != State_Running)
- SendMessage(WM_COMMAND, ID_PLAY_PLAY);
- DVD_HMSF_TIMECODE tc = RT2HMSF(rtPos);
- pDVDC->PlayAtTime(&tc, DVD_CMD_FLAG_Block|DVD_CMD_FLAG_Flush, NULL);
- // if(fs != State_Running)
- // SendMessage(WM_COMMAND, ID_PLAY_PAUSE);
- }
- else if(m_iPlaybackMode == PM_CAPTURE)
- {
- TRACE(_T("Warning (CMainFrame::SeekTo): Trying to seek in capture mode"));
- }
- }
- void CMainFrame::CleanGraph()
- {
- if(!pGB) return;
- BeginEnumFilters(pGB, pEF, pBF)
- {
- CComQIPtr<IAMFilterMiscFlags> pAMMF(pBF);
- if(pAMMF && (pAMMF->GetMiscFlags()&AM_FILTER_MISC_FLAGS_IS_SOURCE))
- continue;
- // some capture filters forget to set AM_FILTER_MISC_FLAGS_IS_SOURCE
- // or to implement the IAMFilterMiscFlags interface
- if(pBF == pVidCap || pBF == pAudCap)
- continue;
- if(CComQIPtr<IFileSourceFilter>(pBF))
- continue;
- int nIn, nOut, nInC, nOutC;
- if(CountPins(pBF, nIn, nOut, nInC, nOutC) > 0 && (nInC+nOutC) == 0)
- {
- TRACE(CStringW(L"Removing: ") + GetFilterName(pBF) + 'n');
- pGB->RemoveFilter(pBF);
- pEF->Reset();
- }
- }
- EndEnumFilters
- }
- #define AUDIOBUFFERLEN 500
- static void SetLatency(IBaseFilter* pBF, int cbBuffer)
- {
- BeginEnumPins(pBF, pEP, pPin)
- {
- if(CComQIPtr<IAMBufferNegotiation> pAMBN = pPin)
- {
- ALLOCATOR_PROPERTIES ap;
- ap.cbAlign = -1; // -1 means no preference.
- ap.cbBuffer = cbBuffer;
- ap.cbPrefix = -1;
- ap.cBuffers = -1;
- pAMBN->SuggestAllocatorProperties(&ap);
- }
- }
- EndEnumPins
- }
- HRESULT CMainFrame::BuildCapture(IPin* pPin, IBaseFilter* pBF[3], const GUID& majortype, AM_MEDIA_TYPE* pmt)
- {
- IBaseFilter* pBuff = pBF[0];
- IBaseFilter* pEnc = pBF[1];
- IBaseFilter* pMux = pBF[2];
- if(!pPin || !pMux) return E_FAIL;
- CString err;
- HRESULT hr = S_OK;
- AddFilterToGraph(pGB, pMux, L"Multiplexer");
- IUnknown* pPrev = pPin;
- CStringW prefix, prefixl;
- if(majortype == MEDIATYPE_Video) prefix = L"Video ";
- else if(majortype == MEDIATYPE_Audio) prefix = L"Audio ";
- prefixl = prefix;
- prefixl.MakeLower();
- if(pBuff)
- {
- hr = pGB->AddFilter(pBuff, prefix + L"Buffer");
- if(FAILED(hr))
- {
- err = _T("Can't add ") + CString(prefixl) + _T("buffer filter");
- AfxMessageBox(err);
- return hr;
- }
- hr = pCGB->RenderStream(NULL, &majortype, pPrev, NULL, pBuff);
- if(FAILED(hr))
- {
- err = _T("Error connecting the ") + CString(prefixl) + _T("buffer filter");
- AfxMessageBox(err);
- return(hr);
- }
- pPrev = pBuff;
- }
- if(pEnc)
- {
- hr = pGB->AddFilter(pEnc, prefix + L"Encoder");
- if(FAILED(hr))
- {
- err = _T("Can't add ") + CString(prefixl) + _T("encoder filter");
- AfxMessageBox(err);
- return hr;
- }
- hr = pCGB->RenderStream(NULL, &majortype, pPrev, NULL, pEnc);
- if(FAILED(hr))
- {
- err = _T("Error connecting the ") + CString(prefixl) + _T("encoder filter");
- AfxMessageBox(err);
- return(hr);
- }
- pPrev = pEnc;
- if(CComQIPtr<IAMStreamConfig> pAMSC = GetFirstPin(pEnc, PINDIR_OUTPUT))
- {
- if(pmt->majortype == majortype)
- {
- hr = pAMSC->SetFormat(pmt);
- if(FAILED(hr))
- {
- err = _T("Can't set compression format on the ") + CString(prefixl) + _T("encoder filter");
- AfxMessageBox(err);
- return(hr);
- }
- }
- }
- }
- // if(pMux)
- {
- hr = pCGB->RenderStream(NULL, &majortype, pPrev, NULL, pMux);
- if(FAILED(hr))
- {
- err = _T("Error connecting ") + CString(prefixl) + _T(" to the muliplexer filter");
- AfxMessageBox(err);
- return(hr);
- }
- }
- CleanGraph();
- return S_OK;
- }
- bool CMainFrame::BuildToCapturePreviewPin(
- IBaseFilter* pVidCap, IPin** ppVidCapPin, IPin** ppVidPrevPin,
- IBaseFilter* pAudCap, IPin** ppAudCapPin, IPin** ppAudPrevPin)
- {
- HRESULT hr;
- *ppVidCapPin = *ppVidPrevPin = NULL;
- *ppAudCapPin = *ppAudPrevPin = NULL;
- CComPtr<IPin> pDVAudPin;
- if(pVidCap)
- {
- CComPtr<IPin> pPin;
- if(!pAudCap // only look for interleaved stream when we don't use any other audio capture source
- && SUCCEEDED(pCGB->FindPin(pVidCap, PINDIR_OUTPUT, &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Interleaved, TRUE, 0, &pPin)))
- {
- CComPtr<IBaseFilter> pDVSplitter;
- hr = pDVSplitter.CoCreateInstance(CLSID_DVSplitter);
- hr = pGB->AddFilter(pDVSplitter, L"DV Splitter");
- hr = pCGB->RenderStream(NULL, &MEDIATYPE_Interleaved, pPin, NULL, pDVSplitter);
- pPin = NULL;
- hr = pCGB->FindPin(pDVSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Video, TRUE, 0, &pPin);
- hr = pCGB->FindPin(pDVSplitter, PINDIR_OUTPUT, NULL, &MEDIATYPE_Audio, TRUE, 0, &pDVAudPin);
- CComPtr<IBaseFilter> pDVDec;
- hr = pDVDec.CoCreateInstance(CLSID_DVVideoCodec);
- hr = pGB->AddFilter(pDVDec, L"DV Video Decoder");
- hr = pCGB->RenderStream(NULL, &MEDIATYPE_Video, pPin, NULL, pDVDec);
- pPin = NULL;
- hr = pCGB->FindPin(pDVDec, PINDIR_OUTPUT, NULL, &MEDIATYPE_Video, TRUE, 0, &pPin);
- }
- else if(SUCCEEDED(pCGB->FindPin(pVidCap, PINDIR_OUTPUT, &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, TRUE, 0, &pPin)))
- {
- }
- else
- {
- AfxMessageBox(_T("No video capture pin found"));
- return(false);
- }
- CComPtr<IBaseFilter> pSmartTee;
- hr = pSmartTee.CoCreateInstance(CLSID_SmartTee);
- hr = pGB->AddFilter(pSmartTee, L"Smart Tee (video)");
- hr = pCGB->RenderStream(NULL, &MEDIATYPE_Video, pPin, NULL, pSmartTee);
- hr = pSmartTee->FindPin(L"Preview", ppVidPrevPin);
- hr = pSmartTee->FindPin(L"Capture", ppVidCapPin);
- }
- if(pAudCap || pDVAudPin)
- {
- CComPtr<IPin> pPin;
- if(pDVAudPin)
- {
- pPin = pDVAudPin;
- }
- else if(SUCCEEDED(pCGB->FindPin(pAudCap, PINDIR_OUTPUT, &PIN_CATEGORY_CAPTURE, &MEDIATYPE_Audio, TRUE, 0, &pPin)))
- {
- }
- else
- {
- AfxMessageBox(_T("No audio capture pin found"));
- return(false);
- }
- CComPtr<IBaseFilter> pSmartTee;
- hr = pSmartTee.CoCreateInstance(CLSID_SmartTee);
- hr = pGB->AddFilter(pSmartTee, L"Smart Tee (audio)");
- hr = pCGB->RenderStream(NULL, &MEDIATYPE_Audio, pPin, NULL, pSmartTee);
- hr = pSmartTee->FindPin(L"Preview", ppAudPrevPin);
- hr = pSmartTee->FindPin(L"Capture", ppAudCapPin);
- }
- return(true);
- }
- bool CMainFrame::BuildGraphVideoAudio(bool fVPreview, bool fVCapture, bool fAPreview, bool fACapture)
- {
- if(!pCGB) return(false);
- SaveMediaState;
- HRESULT hr;
- NukeDownstream(pVidCap, pGB);
- NukeDownstream(pAudCap, pGB);
- CleanGraph();
- if(pAMVSCCap) hr = pAMVSCCap->SetFormat(&m_wndCaptureBar.m_capdlg.m_mtv);
- if(pAMVSCPrev) hr = pAMVSCPrev->SetFormat(&m_wndCaptureBar.m_capdlg.m_mtv);
- if(pAMASC) hr = pAMASC->SetFormat(&m_wndCaptureBar.m_capdlg.m_mta);
- CComPtr<IBaseFilter> pVidBuffer = m_wndCaptureBar.m_capdlg.m_pVidBuffer;
- CComPtr<IBaseFilter> pAudBuffer = m_wndCaptureBar.m_capdlg.m_pAudBuffer;
- CComPtr<IBaseFilter> pVidEnc = m_wndCaptureBar.m_capdlg.m_pVidEnc;
- CComPtr<IBaseFilter> pAudEnc = m_wndCaptureBar.m_capdlg.m_pAudEnc;
- CComPtr<IBaseFilter> pMux = m_wndCaptureBar.m_capdlg.m_pMux;
- CComPtr<IBaseFilter> pDst = m_wndCaptureBar.m_capdlg.m_pDst;
- CComPtr<IBaseFilter> pAudMux = m_wndCaptureBar.m_capdlg.m_pAudMux;
- CComPtr<IBaseFilter> pAudDst = m_wndCaptureBar.m_capdlg.m_pAudDst;
- bool fFileOutput = (pMux && pDst) || (pAudMux && pAudDst);
- bool fCapture = (fVCapture || fACapture);
- if(pAudCap)
- {
- AM_MEDIA_TYPE* pmt = &m_wndCaptureBar.m_capdlg.m_mta;
- int ms = (fACapture && fFileOutput && m_wndCaptureBar.m_capdlg.m_fAudOutput) ? AUDIOBUFFERLEN : 60;
- if(pMux != pAudMux && fACapture) SetLatency(pAudCap, -1);
- else if(pmt->pbFormat) SetLatency(pAudCap, ((WAVEFORMATEX*)pmt->pbFormat)->nAvgBytesPerSec * ms / 1000);
- }
- CComPtr<IPin> pVidCapPin, pVidPrevPin, pAudCapPin, pAudPrevPin;
- BuildToCapturePreviewPin(pVidCap, &pVidCapPin, &pVidPrevPin, pAudCap, &pAudCapPin, &pAudPrevPin);
- CGraphBuilderCapture gb(pGB, m_wndView.m_hWnd);
- // if(pVidCap)
- {
- bool fVidPrev = pVidPrevPin && fVPreview;
- bool fVidCap = pVidCapPin && fVCapture && fFileOutput && m_wndCaptureBar.m_capdlg.m_fVidOutput;
- if(fVidPrev && !fVidCap && pVidCapPin)
- {
- pVidPrevPin = pVidCapPin;
- pVidCapPin = NULL;
- }
- if(fVidPrev)
- {
- m_pCAP = NULL;
- gb.Render(pVidPrevPin);
- gb.FindInterface(__uuidof(ISubPicAllocatorPresenter), (void**)&m_pCAP);
- }
- if(fVidCap)
- {
- IBaseFilter* pBF[3] = {pVidBuffer, pVidEnc, pMux};
- HRESULT hr = BuildCapture(pVidCapPin, pBF, MEDIATYPE_Video, &m_wndCaptureBar.m_capdlg.m_mtcv);
- }
- pAMDF = NULL;
- pCGB->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pVidCap, IID_IAMDroppedFrames, (void**)&pAMDF);
- }
- // if(pAudCap)
- {
- bool fAudPrev = pAudPrevPin && fAPreview;
- bool fAudCap = pAudCapPin && fACapture && fFileOutput && m_wndCaptureBar.m_capdlg.m_fAudOutput;
- if(fAudPrev)
- {
- gb.Render(fAudCap ? pAudPrevPin : pAudCapPin);
- }
- if(fAudCap)
- {
- IBaseFilter* pBF[3] = {pAudBuffer, pAudEnc, pAudMux ? pAudMux : pMux};
- HRESULT hr = BuildCapture(pAudCapPin, pBF, MEDIATYPE_Audio, &m_wndCaptureBar.m_capdlg.m_mtca);
- }
- }
- if((pVidCap || pAudCap) && fCapture && fFileOutput)
- {
- if(pMux != pDst)
- {
- hr = pGB->AddFilter(pDst, L"File Writer V/A");
- hr = pCGB->RenderStream(NULL, NULL, pMux, NULL, pDst);
- }
- if(CComQIPtr<IConfigAviMux> pCAM = pMux)
- {
- int nIn, nOut, nInC, nOutC;
- CountPins(pMux, nIn, nOut, nInC, nOutC);
- pCAM->SetMasterStream(nInC-1);
- // pCAM->SetMasterStream(-1);
- pCAM->SetOutputCompatibilityIndex(FALSE);
- }
- if(CComQIPtr<IConfigInterleaving> pCI = pMux)
- {
- // if(FAILED(pCI->put_Mode(INTERLEAVE_CAPTURE)))
- if(FAILED(pCI->put_Mode(INTERLEAVE_NONE_BUFFERED)))
- pCI->put_Mode(INTERLEAVE_NONE);
- REFERENCE_TIME rtInterleave = 10000i64*AUDIOBUFFERLEN, rtPreroll = 0;//10000i64*500
- pCI->put_Interleaving(&rtInterleave, &rtPreroll);
- }
- if(pMux != pAudMux && pAudMux != pAudDst)
- {
- hr = pGB->AddFilter(pAudDst, L"File Writer A");
- hr = pCGB->RenderStream(NULL, NULL, pAudMux, NULL, pAudDst);
- }
- }
- REFERENCE_TIME stop = MAX_TIME;
- hr = pCGB->ControlStream(&PIN_CATEGORY_CAPTURE, NULL, NULL, NULL, &stop, 0, 0); // stop in the infinite
- CleanGraph();
- OpenSetupVideo();
- OpenSetupStatsBar();
- OpenSetupStatusBar();
- RestoreMediaState;
- return(true);
- }
- bool CMainFrame::StartCapture()
- {
- if(!pCGB || m_fCapturing) return(false);
- if(!m_wndCaptureBar.m_capdlg.m_pMux && !m_wndCaptureBar.m_capdlg.m_pDst) return(false);
- HRESULT hr;
- ::SetPriorityClass(::GetCurrentProcess(), HIGH_PRIORITY_CLASS);
- // rare to see two capture filters to support IAMPushSource at the same time...
- // hr = CComQIPtr<IAMGraphStreams>(pGB)->SyncUsingStreamOffset(TRUE); // TODO:
- BuildGraphVideoAudio(
- !!m_wndCaptureBar.m_capdlg.m_fVidPreview, true,
- !!m_wndCaptureBar.m_capdlg.m_fAudPreview, true);
- hr = pME->CancelDefaultHandling(EC_REPAINT);
- SendMessage(WM_COMMAND, ID_PLAY_PLAY);
- m_fCapturing = true;
- return(true);
- }
- bool CMainFrame::StopCapture()
- {
- if(!pCGB || !m_fCapturing) return(false);
- if(!m_wndCaptureBar.m_capdlg.m_pMux && !m_wndCaptureBar.m_capdlg.m_pDst) return(false);
- HRESULT hr;
- m_wndStatusBar.SetStatusMessage(_T("Completing..."));
- m_fCapturing = false;
- BuildGraphVideoAudio(
- !!m_wndCaptureBar.m_capdlg.m_fVidPreview, false,
- !!m_wndCaptureBar.m_capdlg.m_fAudPreview, false);
- hr = pME->RestoreDefaultHandling(EC_REPAINT);
- ::SetPriorityClass(::GetCurrentProcess(), AfxGetAppSettings().priority);
- m_rtDurationOverride = -1;
- return(true);
- }
- //
- void CMainFrame::ShowOptions(int idPage)
- {
- AppSettings& s = AfxGetAppSettings();
- CPPageSheet options(ResStr(IDS_OPTIONS_CAPTION), pGB, this, idPage);
- if(options.DoModal() == IDOK)
- {
- if(!m_fFullScreen)
- SetAlwaysOnTop(s.iOnTop);
- m_wndView.LoadLogo();
- s.UpdateData(true);
- }
- }
- void CMainFrame::StartWebServer(int nPort)
- {
- if(!m_pWebServer)
- m_pWebServer.Attach(new CWebServer(this, nPort));
- }
- void CMainFrame::StopWebServer()
- {
- if(m_pWebServer)
- m_pWebServer.Free();
- }
- CString CMainFrame::GetStatusMessage()
- {
- CString str;
- m_wndStatusBar.m_status.GetWindowText(str);
- return str;
- }
- void CMainFrame::SendStatusMessage(CString msg, int nTimeOut)
- {
- KillTimer(TIMER_STATUSERASER);
- m_playingmsg.Empty();
- if(nTimeOut <= 0) return;
- m_playingmsg = msg;
- SetTimer(TIMER_STATUSERASER, nTimeOut, NULL);
- }
- void CMainFrame::OpenCurPlaylistItem(REFERENCE_TIME rtStart)
- {
- if(m_wndPlaylistBar.GetCount() == 0)
- return;
- CPlaylistItem pli;
- if(!m_wndPlaylistBar.GetCur(pli)) m_wndPlaylistBar.SetFirst();
- if(!m_wndPlaylistBar.GetCur(pli)) return;
- CAutoPtr<OpenMediaData> p(m_wndPlaylistBar.GetCurOMD(rtStart));
- if(p) OpenMedia(p);
- }
- void CMainFrame::AddCurDevToPlaylist()
- {
- if(m_iPlaybackMode == PM_CAPTURE)
- {
- m_wndPlaylistBar.Append(
- m_VidDispName,
- m_AudDispName,
- m_wndCaptureBar.m_capdlg.GetVideoInput(),
- m_wndCaptureBar.m_capdlg.GetVideoChannel(),
- m_wndCaptureBar.m_capdlg.GetAudioInput()
- );
- }
- }
- static int s_fOpenedThruThread = false;
- void CMainFrame::OpenMedia(CAutoPtr<OpenMediaData> pOMD)
- {
- // shortcut
- if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p))
- {
- if(m_iMediaLoadState == MLS_LOADED && pAMTuner
- && m_VidDispName == p->DisplayName[0] && m_AudDispName == p->DisplayName[1])
- {
- m_wndCaptureBar.m_capdlg.SetVideoInput(p->vinput);
- m_wndCaptureBar.m_capdlg.SetVideoChannel(p->vchannel);
- m_wndCaptureBar.m_capdlg.SetAudioInput(p->ainput);
- SendNowPlayingToMSN();
- return;
- }
- }
- if(m_iMediaLoadState != MLS_CLOSED)
- CloseMedia();
- AppSettings& s = AfxGetAppSettings();
- bool fUseThread = true;
- if(OpenFileData* p = dynamic_cast<OpenFileData*>(pOMD.m_p))
- {
- if(p->fns.GetCount() > 0)
- {
- engine_t e = s.Formats.GetEngine(p->fns.GetHead());
- fUseThread = e == DirectShow /*|| e == RealMedia || e == QuickTime*/;
- }
- }
- else if(OpenDeviceData* p = dynamic_cast<OpenDeviceData*>(pOMD.m_p))
- {
- fUseThread = false;
- }
- if(m_pGraphThread && fUseThread
- && AfxGetAppSettings().fEnableWorkerThreadForOpening)
- {
- m_pGraphThread->PostThreadMessage(CGraphThread::TM_OPEN, 0, (LPARAM)pOMD.Detach());
- s_fOpenedThruThread = true;
- }
- else
- {
- OpenMediaPrivate(pOMD);
- s_fOpenedThruThread = false;
- }
- }
- void CMainFrame::CloseMedia()
- {
- if(m_iMediaLoadState == MLS_CLOSING)
- {
- TRACE(_T("WARNING: CMainFrame::CloseMedia() called twice or moren"));
- return;
- }
- int nTimeWaited = 0;
- while(m_iMediaLoadState == MLS_LOADING)
- {
- m_fOpeningAborted = true;
- if(pGB) pGB->Abort(); // TODO: lock on graph objects somehow, this is not thread safe
- if(nTimeWaited > 5*1000 && m_pGraphThread)
- {
- MessageBeep(MB_ICONEXCLAMATION);
- TRACE(_T("CRITICAL ERROR: !!! Must kill opener thread !!!"));
- TerminateThread(m_pGraphThread->m_hThread, -1);
- m_pGraphThread = (CGraphThread*)AfxBeginThread(RUNTIME_CLASS(CGraphThread));
- s_fOpenedThruThread = false;
- break;
- }
- Sleep(50);
- nTimeWaited += 50;
- }
- m_fOpeningAborted = false;
- m_closingmsg.Empty();
- m_iMediaLoadState = MLS_CLOSING;
- OnFilePostClosemedia();
- if(m_pGraphThread && s_fOpenedThruThread)
- {
- CAMEvent e;
- m_pGraphThread->PostThreadMessage(CGraphThread::TM_CLOSE, 0, (LPARAM)&e);
- e.Wait(); // either opening or closing has to be blocked to prevent reentering them, closing is the better choice
- }
- else
- {
- CloseMediaPrivate();
- }
- UnloadExternalObjects();
- }
- //
- // CGraphThread
- //
- IMPLEMENT_DYNCREATE(CGraphThread, CWinThread)
- BOOL CGraphThread::InitInstance()
- {
- AfxSocketInit();
- return SUCCEEDED(CoInitialize(0)) ? TRUE : FALSE;
- }
- int CGraphThread::ExitInstance()
- {
- CoUninitialize();
- return __super::ExitInstance();
- }
- BEGIN_MESSAGE_MAP(CGraphThread, CWinThread)
- ON_THREAD_MESSAGE(TM_EXIT, OnExit)
- ON_THREAD_MESSAGE(TM_OPEN, OnOpen)
- ON_THREAD_MESSAGE(TM_CLOSE, OnClose)
- END_MESSAGE_MAP()
- void CGraphThread::OnExit(WPARAM wParam, LPARAM lParam)
- {
- PostQuitMessage(0);
- if(CAMEvent* e = (CAMEvent*)lParam) e->Set();
- }
- void CGraphThread::OnOpen(WPARAM wParam, LPARAM lParam)
- {
- if(m_pMainFrame)
- {
- CAutoPtr<OpenMediaData> pOMD((OpenMediaData*)lParam);
- m_pMainFrame->OpenMediaPrivate(pOMD);
- }
- }
- void CGraphThread::OnClose(WPARAM wParam, LPARAM lParam)
- {
- if(m_pMainFrame) m_pMainFrame->CloseMediaPrivate();
- if(CAMEvent* e = (CAMEvent*)lParam) e->Set();
- }