/* * $Id$ * * (C) 2003-2006 Gabest * (C) 2006-2010 see AUTHORS * * This file is part of mplayerc. * * Mplayerc is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * Mplayerc is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include "stdafx.h" #include "mplayerc.h" #include "MainFrm.h" #include "PlayerCaptureDialog.h" #include "../../DSUtil/DSUtil.h" #include #include "../../filters/muxer/WavDest/WavDest.h" #include "../../filters/muxer/MatroskaMuxer/MatroskaMuxer.h" #include "../../filters/muxer/DSMMuxer/DSMMuxer.h" static bool LoadMediaType(CStringW DisplayName, AM_MEDIA_TYPE** ppmt) { bool fRet = false; if(!ppmt) return(fRet); *ppmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); if(!*ppmt) return(fRet); memset(*ppmt, 0, sizeof(AM_MEDIA_TYPE)); BYTE* pData; UINT len; if(AfxGetApp()->GetProfileBinary(_T("Capture\\") + CString(DisplayName), _T("MediaType"), &pData, &len)) { if ( len != sizeof(AM_MEDIA_TYPE) ) { delete [] pData; return(fRet); } memcpy(*ppmt, pData, len); delete [] pData; (*ppmt)->cbFormat = 0; (*ppmt)->pbFormat = NULL; fRet = true; if(AfxGetApp()->GetProfileBinary(_T("Capture\\") + CString(DisplayName), _T("Format"), &pData, &len)) { if ( !len ) { delete [] pData; return(fRet); } (*ppmt)->cbFormat = len; (*ppmt)->pbFormat = (BYTE*)CoTaskMemAlloc(len); memcpy((*ppmt)->pbFormat, pData, len); delete [] pData; } } return(fRet); } static void SaveMediaType(CStringW DisplayName, AM_MEDIA_TYPE* pmt) { if(DisplayName.IsEmpty() || !pmt) return; AfxGetApp()->WriteProfileBinary(_T("Capture\\") + CString(DisplayName), _T("MediaType"), (BYTE*)pmt, sizeof(AM_MEDIA_TYPE)); AfxGetApp()->WriteProfileBinary(_T("Capture\\") + CString(DisplayName), _T("Format"), pmt->pbFormat, pmt->cbFormat); } static void LoadDefaultCodec(CAtlArray& codecs, CComboBox& box, const GUID& cat) { int len = box.GetCount(); if(len >= 0) box.SetCurSel(0); if(cat == GUID_NULL) return; CString DisplayName = AfxGetApp()->GetProfileString(_T("Capture\\") + CStringFromGUID(cat), _T("DisplayName")); for(int i = 0; i < len; i++) { int iSel = box.GetItemData(i); if(iSel < 0) continue; Codec& c = codecs[iSel]; if(DisplayName == c.DisplayName) { box.SetCurSel(i); if(!c.pBF) c.pMoniker->BindToObject(NULL, NULL, __uuidof(IBaseFilter), (void**)&c.pBF); break; } } } static void SaveDefaultCodec(CAtlArray& codecs, CComboBox& box, const GUID& cat) { if(cat == GUID_NULL) return; CString guid = CStringFromGUID(cat); AfxGetApp()->WriteProfileString(_T("Capture\\") + guid, NULL, NULL); int iSel = box.GetCurSel(); if(iSel < 0) return; iSel = box.GetItemData(iSel); if(iSel < 0) return; Codec& codec = codecs[iSel]; AfxGetApp()->WriteProfileString(_T("Capture\\") + guid, _T("DisplayName"), CString(codec.DisplayName)); } static void SetupDefaultCaps(AM_MEDIA_TYPE* pmt, VIDEO_STREAM_CONFIG_CAPS& caps) { memset(&caps, 0, sizeof(caps)); if(!pmt) return; VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)pmt->pbFormat; UNUSED_ALWAYS(vih); BITMAPINFOHEADER* bih = (pmt->formattype == FORMAT_VideoInfo) ? &((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader : (pmt->formattype == FORMAT_VideoInfo2) ? &((VIDEOINFOHEADER2*)pmt->pbFormat)->bmiHeader : NULL; caps.guid = GUID_NULL; caps.VideoStandard = 0; caps.InputSize.cx = bih->biWidth; caps.InputSize.cy = abs(bih->biHeight); caps.MinCroppingSize = caps.MaxCroppingSize = caps.InputSize; caps.CropGranularityX = caps.CropGranularityY = 1; caps.CropAlignX = caps.CropAlignY = 1; caps.MinOutputSize = CSize(64, 64); caps.MaxOutputSize = CSize(768, 576); caps.OutputGranularityX = 16; caps.OutputGranularityY = 1; caps.StretchTapsX = caps.StretchTapsY = 0; caps.ShrinkTapsX = caps.ShrinkTapsY = 0; caps.MinFrameInterval = 100000i64; caps.MaxFrameInterval = 100000000i64; caps.MinBitsPerSecond = caps.MaxBitsPerSecond = 0; } static void SetupDefaultCaps(AM_MEDIA_TYPE* pmt, AUDIO_STREAM_CONFIG_CAPS& caps) { memset(&caps, 0, sizeof(caps)); if(!pmt) return; WAVEFORMATEX* wfe = (WAVEFORMATEX*)pmt->pbFormat; caps.guid = GUID_NULL; caps.MinimumChannels = caps.MaximumChannels = wfe->nChannels; caps.ChannelsGranularity = 1; caps.MinimumBitsPerSample = caps.MaximumBitsPerSample = wfe->wBitsPerSample; caps.BitsPerSampleGranularity = 1; caps.MinimumSampleFrequency = caps.MaximumSampleFrequency = wfe->nSamplesPerSec; caps.SampleFrequencyGranularity = 1; } template static void SetupMediaTypes(IAMStreamConfig* pAMSC, CFormatArray& tfa, CComboBox& type, CComboBox& dim, CMediaType& mt) { tfa.RemoveAll(); type.ResetContent(); dim.ResetContent(); type.EnableWindow(FALSE); dim.EnableWindow(FALSE); if(!pAMSC) return; AM_MEDIA_TYPE* pcurmt = NULL; pAMSC->GetFormat(&pcurmt); int iCount = 0, iSize; if(SUCCEEDED(pAMSC->GetNumberOfCapabilities(&iCount, &iSize)) && iSize == sizeof(T) && iCount > 0) { for(int i = 0; i < iCount; i++) { T caps; AM_MEDIA_TYPE* pmt = NULL; if(SUCCEEDED(pAMSC->GetStreamCaps(i, &pmt, (BYTE*)&caps))) { tfa.AddFormat(pmt, caps); } } if(iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS)) { for(int i = 0, cnt = tfa.GetCount(); i < cnt; i++) { if(tfa[i]->GetCount() != 1) continue; CFormatElem* pfe = tfa[i]->GetAt(0); if(pfe->mt.formattype != FORMAT_VideoInfo && pfe->mt.formattype != FORMAT_VideoInfo2) continue; static SIZE presets[] = { {160, 120}, {192, 144}, {320, 240}, {384, 288}, {480, 240}, {512, 288}, {480, 360}, {512, 384}, {640, 240}, {768, 288}, {640, 480}, {768, 576}, {704, 240}, {704, 288}, {704, 480}, {704, 576}, {720, 240}, {720, 288}, {720, 480}, {720, 576}, {768, 240}, {768, 288}, {768, 480}, {768, 576}, }; VIDEO_STREAM_CONFIG_CAPS* pcaps = (VIDEO_STREAM_CONFIG_CAPS*)&pfe->caps; BITMAPINFOHEADER bihCur; ExtractBIH(&pfe->mt, &bihCur); for(int j = 0; j < countof(presets); j++) { if(presets[j].cx == bihCur.biWidth && presets[j].cy == abs(bihCur.biHeight) || presets[j].cx < pcaps->MinOutputSize.cx || presets[j].cx > pcaps->MaxOutputSize.cx || presets[j].cy < pcaps->MinOutputSize.cy || presets[j].cy > pcaps->MaxOutputSize.cy || presets[j].cx % pcaps->OutputGranularityX || presets[j].cy % pcaps->OutputGranularityY) continue; CMediaType mt = pfe->mt; if(mt.formattype == FORMAT_VideoInfo) { VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)mt.pbFormat; if(!vih->bmiHeader.biHeight) vih->bmiHeader.biHeight = 1; vih->bmiHeader.biWidth = presets[j].cx; vih->bmiHeader.biHeight = presets[j].cy*(vih->bmiHeader.biHeight/vih->bmiHeader.biHeight); vih->bmiHeader.biSizeImage = presets[j].cx*presets[j].cy*vih->bmiHeader.biBitCount>>3; AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); CopyMediaType(pmt, &mt); tfa.AddFormat(pmt, pcaps, sizeof(*pcaps)); if(presets[j].cx*3 != presets[j].cy*4) { int extra = mt.cbFormat - sizeof(VIDEOINFOHEADER); int bmiHeaderSize = sizeof(vih->bmiHeader) + extra; BYTE* pbmiHeader = DNew BYTE[bmiHeaderSize]; memcpy(pbmiHeader, &vih->bmiHeader, bmiHeaderSize); mt.ReallocFormatBuffer(FIELD_OFFSET(VIDEOINFOHEADER2, bmiHeader) + bmiHeaderSize); VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)mt.pbFormat; memcpy(&vih2->bmiHeader, pbmiHeader, bmiHeaderSize); delete [] pbmiHeader; vih2->dwInterlaceFlags = vih2->dwCopyProtectFlags = 0; vih2->dwReserved1 = vih2->dwReserved2 = 0; vih2->dwPictAspectRatioX = 4; vih2->dwPictAspectRatioY = 3; AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); CopyMediaType(pmt, &mt); tfa.AddFormat(pmt, pcaps, sizeof(*pcaps)); } } else if(mt.formattype == FORMAT_VideoInfo2) { VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)mt.pbFormat; if(!vih2->bmiHeader.biHeight) vih2->bmiHeader.biHeight = 1; vih2->bmiHeader.biWidth = presets[j].cx; vih2->bmiHeader.biHeight = presets[j].cy*(vih2->bmiHeader.biHeight/vih2->bmiHeader.biHeight); vih2->bmiHeader.biSizeImage = presets[j].cx*presets[j].cy*vih2->bmiHeader.biBitCount>>3; vih2->dwPictAspectRatioX = 4; vih2->dwPictAspectRatioY = 3; AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); CopyMediaType(pmt, &mt); tfa.AddFormat(pmt, pcaps, sizeof(*pcaps)); } } } } } if(tfa.GetCount() == 0) { if(pcurmt && (pcurmt->majortype == MEDIATYPE_Video || pcurmt->majortype == MEDIATYPE_Audio)) { AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); CopyMediaType(pmt, pcurmt); T caps; SetupDefaultCaps(pmt, caps); tfa.AddFormat(pmt, caps); } else { mt.majortype = GUID_NULL; if(pcurmt) DeleteMediaType(pcurmt); return; } } for(int i = 0; i < (int)tfa.GetCount(); i++) { CFormat* pf = tfa[i]; int j = type.AddString(pf->name); type.SetItemData(j, (DWORD_PTR)pf); } CFormat* pf = NULL; CFormatElem* pfe = NULL; if(!pcurmt) { pf = tfa[0]; pfe = pf->GetAt(0); } else if(!tfa.FindFormat(pcurmt, NULL, &pf, &pfe) && !tfa.FindFormat(pcurmt, &pf)) { if(pcurmt) DeleteMediaType(pcurmt); return; } for(int i = 0; i < (int)pf->GetCount(); i++) { CFormatElem* pfe = pf->GetAt(i); int j = dim.AddString(tfa.MakeDimensionName(pfe)); dim.SetItemData(j, (DWORD_PTR)pfe); } int iType = type.SetCurSel(type.FindStringExact(0, pf->name)); if(iType < 0 && type.GetCount()) type.SetCurSel(0); int iDim = dim.SetCurSel(dim.FindStringExact(0, tfa.MakeDimensionName(pfe))); // if(iDim < 0 && dim.GetCount()) dim.SetCurSel(iDim = 0); CorrectComboListWidth(type, type.GetParent()->GetFont()); CorrectComboListWidth(dim, dim.GetParent()->GetFont()); if(iDim >= 0) mt = ((CFormatElem*)dim.GetItemData(iDim))->mt; else if(pcurmt) mt = *pcurmt; type.EnableWindow(type.GetCount() > 0); dim.EnableWindow(dim.GetCount() > 0); if(pcurmt) DeleteMediaType(pcurmt); } template static bool SetupDimension(CFormatArray& tfa, CComboBox& type, CComboBox& dim) { CString str; dim.GetWindowText(str); dim.ResetContent(); dim.EnableWindow(FALSE); int iSel = type.GetCurSel(); if(iSel < 0) return(false); CFormat* pf = (CFormat*)type.GetItemData(iSel); for(int i = 0; i < (int)pf->GetCount(); i++) { CFormatElem* pfe = pf->GetAt(i); dim.SetItemData(dim.AddString(tfa.MakeDimensionName(pfe)), (DWORD_PTR)pfe); } CorrectComboListWidth(dim, dim.GetParent()->GetFont()); dim.SetCurSel(dim.FindStringExact(0, str)); dim.EnableWindow(dim.GetCount() > 0); return(dim.GetCurSel() >= 0); } static void InitCodecList(CAtlArray& codecs, CComboBox& box, const GUID& cat) { codecs.RemoveAll(); box.ResetContent(); box.EnableWindow(FALSE); box.SetItemData(box.AddString(_T("Uncompressed")), (DWORD_PTR)-1); BeginEnumSysDev(cat, pMoniker) { Codec c; c.pMoniker = pMoniker; /* CComPtr pBF; if(FAILED(pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pBF)) || !pBF) continue; c.pBF = pBF; */ LPOLESTR strName = NULL; if(FAILED(pMoniker->GetDisplayName(NULL, NULL, &strName))) continue; c.DisplayName = strName; CoTaskMemFree(strName); CComPtr pPB; pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB); CComVariant var; if(FAILED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL))) continue; c.FriendlyName = var.bstrVal; CStringW str = CStringW(c.DisplayName).MakeLower(); if(str.Find(L"@device:dmo:") == 0) c.FriendlyName = _T("(DMO) ") + c.FriendlyName; else if(str.Find(L"@device:sw:") == 0) c.FriendlyName = _T("(DS) ") + c.FriendlyName; else if(str.Find(L"@device:cm:") == 0) c.FriendlyName = _T("(VfW) ") + c.FriendlyName; box.SetItemData( box.AddString(c.FriendlyName), (DWORD_PTR)codecs.Add(c)); } EndEnumSysDev box.EnableWindow(box.GetCount() > 1); CorrectComboListWidth(box, box.GetParent()->GetFont()); LoadDefaultCodec(codecs, box, cat); } static int ShowPPage(CAtlArray& codecs, CComboBox& box, HWND hWnd = NULL) { int iSel = box.GetCurSel(); if(iSel < 0) return(-1); iSel = box.GetItemData(iSel); if(iSel < 0) return(-1); Codec& c = codecs[iSel]; if(!c.pBF) { c.pMoniker->BindToObject(NULL, NULL, __uuidof(IBaseFilter), (void**)&c.pBF); } if(CComQIPtr pSPP = c.pBF) { CAUUID caGUID; caGUID.pElems = NULL; if(SUCCEEDED(pSPP->GetPages(&caGUID))) { IUnknown* lpUnk = NULL; pSPP.QueryInterface(&lpUnk); OleCreatePropertyFrame( hWnd, 0, 0, CStringW(c.FriendlyName), 1, (IUnknown**)&lpUnk, caGUID.cElems, caGUID.pElems, 0, 0, NULL); lpUnk->Release(); if(caGUID.pElems) CoTaskMemFree(caGUID.pElems); } } else if(CComQIPtr pAMVfWCD = c.pBF) { if(pAMVfWCD->ShowDialog(VfwCompressDialog_QueryConfig, NULL) == S_OK) pAMVfWCD->ShowDialog(VfwCompressDialog_Config, hWnd); } return(iSel); } // CPlayerCaptureDialog dialog //IMPLEMENT_DYNAMIC(CPlayerCaptureDialog, CResizableDialog) CPlayerCaptureDialog::CPlayerCaptureDialog() : CResizableDialog(CPlayerCaptureDialog::IDD, NULL) , m_vidfps(0) , m_file(_T("")) , m_fVidOutput(TRUE) , m_fAudOutput(TRUE) , m_fVidPreview(FALSE) , m_fAudPreview(FALSE) , m_nVidBuffers(0) , m_nAudBuffers(0) , m_pVidBuffer(NULL) , m_pAudBuffer(NULL) , m_fSepAudio(FALSE) , m_muxtype(0) { } CPlayerCaptureDialog::~CPlayerCaptureDialog() { EmptyVideo(); EmptyAudio(); } BOOL CPlayerCaptureDialog::Create(CWnd* pParent) { if(!__super::Create(IDD, pParent)) return FALSE; EmptyVideo(); EmptyAudio(); return TRUE; } void CPlayerCaptureDialog::DoDataExchange(CDataExchange* pDX) { __super::DoDataExchange(pDX); DDX_Control(pDX, IDC_COMBO4, m_vidinput); DDX_Control(pDX, IDC_COMBO1, m_vidtype); DDX_Control(pDX, IDC_COMBO5, m_viddimension); DDX_Control(pDX, IDC_SPIN1, m_vidhor); DDX_Control(pDX, IDC_SPIN2, m_vidver); DDX_Control(pDX, IDC_EDIT1, m_vidhoredit); DDX_Control(pDX, IDC_EDIT2, m_vidveredit); DDX_Control(pDX, IDC_EDIT3, m_vidfpsedit); DDX_Control(pDX, IDC_BUTTON1, m_vidsetres); DDX_Control(pDX, IDC_COMBO3, m_audinput); DDX_Control(pDX, IDC_COMBO2, m_audtype); DDX_Control(pDX, IDC_COMBO6, m_auddimension); DDX_Control(pDX, IDC_COMBO7, m_vidcodec); DDX_Control(pDX, IDC_COMBO9, m_vidcodectype); DDX_Control(pDX, IDC_COMBO10, m_vidcodecdimension); DDX_Check(pDX, IDC_CHECK1, m_fVidOutput); DDX_Control(pDX, IDC_CHECK1, m_vidoutput); DDX_Check(pDX, IDC_CHECK2, m_fVidPreview); DDX_Control(pDX, IDC_CHECK2, m_vidpreview); DDX_Control(pDX, IDC_COMBO8, m_audcodec); DDX_Control(pDX, IDC_COMBO12, m_audcodectype); DDX_Control(pDX, IDC_COMBO11, m_audcodecdimension); DDX_Check(pDX, IDC_CHECK3, m_fAudOutput); DDX_Control(pDX, IDC_CHECK3, m_audoutput); DDX_Check(pDX, IDC_CHECK4, m_fAudPreview); DDX_Control(pDX, IDC_CHECK4, m_audpreview); DDX_Text(pDX, IDC_EDIT4, m_file); DDX_Control(pDX, IDC_BUTTON2, m_recordbtn); DDX_Text(pDX, IDC_EDIT5, m_nVidBuffers); DDX_Text(pDX, IDC_EDIT6, m_nAudBuffers); DDX_Check(pDX, IDC_CHECK5, m_fSepAudio); DDX_CBIndex(pDX, IDC_COMBO14, m_muxtype); DDX_Control(pDX, IDC_COMBO14, m_muxctrl); } BOOL CPlayerCaptureDialog::PreTranslateMessage(MSG* pMsg) { if(pMsg->message == WM_KEYDOWN) { if(pMsg->wParam == VK_RETURN) { CWnd* pFocused = GetFocus(); if(pFocused && pFocused->m_hWnd == m_vidfpsedit.m_hWnd) { UpdateGraph(); } } } return __super::PreTranslateMessage(pMsg); } void CPlayerCaptureDialog::EmptyVideo() { // first save channel from previous session if(m_pAMTuner && !m_VidDisplayName.IsEmpty()) { long lChannel = 0, lVivSub = 0, lAudSub = 0; m_pAMTuner->get_Channel(&lChannel, &lVivSub, &lAudSub); AfxGetApp()->WriteProfileInt(_T("Capture\\") + CString(m_VidDisplayName), _T("Channel"), lChannel); } // m_vfa.RemoveAll(); m_pAMXB = NULL; m_pAMTuner = NULL; m_pAMVSC = NULL; if(IsWindow(m_hWnd)) { m_vidinput.ResetContent(); m_vidinput.EnableWindow(FALSE); m_vidtype.ResetContent(); m_vidtype.EnableWindow(FALSE); m_viddimension.ResetContent(); m_viddimension.EnableWindow(FALSE); m_vidhor.EnableWindow(FALSE); m_vidver.EnableWindow(FALSE); m_vidhoredit.EnableWindow(FALSE); m_vidveredit.EnableWindow(FALSE); m_vidfpsedit.EnableWindow(FALSE); m_vidfps = 0; m_vidsetres.EnableWindow(FALSE); UpdateData(FALSE); } } void CPlayerCaptureDialog::EmptyAudio() { m_afa.RemoveAll(); m_pAMASC = NULL; m_pAMAIM.RemoveAll(); if(IsWindow(m_hWnd)) { m_audinput.ResetContent(); m_audinput.EnableWindow(FALSE); m_audtype.ResetContent(); m_audtype.EnableWindow(FALSE); m_auddimension.ResetContent(); m_auddimension.EnableWindow(FALSE); UpdateData(FALSE); } } void CPlayerCaptureDialog::UpdateMediaTypes() { UpdateData(); // fps CString fps; m_vidfpsedit.GetWindowText(fps); if(!fps.IsEmpty()) { float ffps; _stscanf_s(fps, _T("%f"), &ffps); if(ffps > 0) m_vidfps = ffps; } // video { AM_MEDIA_TYPE* pmt = NULL; VIDEO_STREAM_CONFIG_CAPS* pcaps = NULL; int i = m_viddimension.GetCurSel(); if(i >= 0) { pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); CopyMediaType(pmt, &((CVidFormatElem*)m_viddimension.GetItemData(i))->mt); pcaps = &((CVidFormatElem*)m_viddimension.GetItemData(i))->caps; } else if(m_pAMVSC) { m_pAMVSC->GetFormat(&pmt); } if(pmt) { if(m_vidfps > 0) { REFERENCE_TIME atpf = (REFERENCE_TIME)(10000000.0 / m_vidfps); if(pcaps) { // FIXME: some drivers do not set the interval right and they still accept the preferable but unfortunately out-of-range fps // atpf = min(max(atpf, pcaps->MinFrameInterval), pcaps->MaxFrameInterval); } if(pmt->formattype == FORMAT_VideoInfo) ((VIDEOINFOHEADER*)pmt->pbFormat)->AvgTimePerFrame = atpf; else if(pmt->formattype == FORMAT_VideoInfo2) ((VIDEOINFOHEADER2*)pmt->pbFormat)->AvgTimePerFrame = atpf; } BITMAPINFOHEADER* bih = (pmt->formattype == FORMAT_VideoInfo) ? &((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader : (pmt->formattype == FORMAT_VideoInfo2) ? &((VIDEOINFOHEADER2*)pmt->pbFormat)->bmiHeader : NULL; bih->biWidth = m_vidhor.GetPos(); bih->biHeight = m_vidver.GetPos(); bih->biSizeImage = bih->biWidth*bih->biHeight*bih->biBitCount>>3; SaveMediaType(m_VidDisplayName, pmt); m_mtv = *pmt; DeleteMediaType(pmt); } } // audio { AM_MEDIA_TYPE* pmt = NULL; int i = m_auddimension.GetCurSel(); if(i >= 0) { pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); CopyMediaType(pmt, &((CAudFormatElem*)m_auddimension.GetItemData(i))->mt); } else if(m_pAMASC) { m_pAMASC->GetFormat(&pmt); } if(pmt) { SaveMediaType(m_AudDisplayName, pmt); m_mta = *pmt; DeleteMediaType(pmt); } } } void CPlayerCaptureDialog::UpdateUserDefinableControls() { int iSel = m_viddimension.GetCurSel(); if(iSel < 0) return; CVidFormatElem* pvfe = (CVidFormatElem*)m_viddimension.GetItemData(iSel); if(!pvfe) return; if(!m_pAMVSC) return; AM_MEDIA_TYPE* pmt = NULL; m_pAMVSC->GetFormat(&pmt); if(!pmt) return; BITMAPINFOHEADER* bih = (pmt->formattype == FORMAT_VideoInfo) ? &((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader : (pmt->formattype == FORMAT_VideoInfo2) ? &((VIDEOINFOHEADER2*)pmt->pbFormat)->bmiHeader : NULL; if(!bih) return; UDACCEL ua[3] = {{0,0},{2,0},{4,0}}; int w = m_vidhor.GetPos(), h = m_vidver.GetPos(); UNUSED_ALWAYS(w); UNUSED_ALWAYS(h); m_vidhor.SetRange((short)pvfe->caps.MinOutputSize.cx, (short)pvfe->caps.MaxOutputSize.cx); /* if(bih->biCompression == mmioFOURCC('Y','U','Y','2')) // FIXME: bt8x8 drivers seem to crop the right side in yuv2 mode if the width is not divisable by 64 pvfe->caps.OutputGranularityX = 64; */ ua[0].nInc = pvfe->caps.OutputGranularityX; ua[1].nInc = pvfe->caps.OutputGranularityX*2; ua[2].nInc = pvfe->caps.OutputGranularityX*4; m_vidhor.SetAccel(3, ua); m_vidver.SetRange((short)pvfe->caps.MinOutputSize.cy, (short)pvfe->caps.MaxOutputSize.cy); ua[0].nInc = pvfe->caps.OutputGranularityY; ua[1].nInc = pvfe->caps.OutputGranularityY*2; ua[2].nInc = pvfe->caps.OutputGranularityY*4; m_vidver.SetAccel(3, ua); m_vidhor.SetPos(bih->biWidth); m_vidver.SetPos(abs(bih->biHeight)); CString fps; fps.Format(_T("%.4f"), (float)(10000000.0 / ((VIDEOINFOHEADER*)pmt->pbFormat)->AvgTimePerFrame)); m_vidfpsedit.SetWindowText(fps); DeleteMediaType(pmt); } void CPlayerCaptureDialog::UpdateVideoCodec() { int iSel = m_vidcodec.GetCurSel(); if(iSel >= 0) iSel = m_vidcodec.GetItemData(iSel); m_pVidEnc = iSel < 0 ? NULL : m_pVidEncArray[iSel].pBF; m_pVidEncMoniker = iSel < 0 ? NULL : m_pVidEncArray[iSel].pMoniker; // CString DisplayName = iSel < 0 ? _T("") : CString(m_pVidEncArray[iSel].DisplayName.m_str); CComQIPtr pAMSC = GetFirstPin(m_pVidEnc, PINDIR_OUTPUT); SetupMediaTypes(pAMSC, m_vcfa, m_vidcodectype, m_vidcodecdimension, m_mtcv); SaveDefaultCodec(m_pVidEncArray, m_vidcodec, CLSID_VideoCompressorCategory); // SaveMediaType(DisplayName, &m_mtcv); } void CPlayerCaptureDialog::UpdateAudioCodec() { int iSel = m_audcodec.GetCurSel(); if(iSel >= 0) iSel = m_audcodec.GetItemData(iSel); m_pAudEnc = iSel < 0 ? NULL : m_pAudEncArray[iSel].pBF; m_pAudEncMoniker = iSel < 0 ? NULL : m_pAudEncArray[iSel].pMoniker; // CString DisplayName = iSel < 0 ? _T("") : CString(m_pAudEncArray[iSel].DisplayName.m_str); CComQIPtr pAMSC = GetFirstPin(m_pAudEnc, PINDIR_OUTPUT); SetupMediaTypes(pAMSC, m_acfa, m_audcodectype, m_audcodecdimension, m_mtca); SaveDefaultCodec(m_pAudEncArray, m_audcodec, CLSID_AudioCompressorCategory); // SaveMediaType(DisplayName, &m_mtca); } void CPlayerCaptureDialog::UpdateMuxer() { m_pMux = NULL; m_pAudMux = NULL; UpdateData(); HRESULT hr; if(m_muxtype == 0) m_pMux.CoCreateInstance(CLSID_AviDest); else if(m_muxtype == 1) m_pMux.CoCreateInstance(CLSID_OggMux); else if(m_muxtype == 2) m_pMux = DNew CMatroskaMuxerFilter(NULL, &hr); else if(m_muxtype == 3) m_pMux = DNew CDSMMuxerFilter(NULL, &hr); else return; if(m_fSepAudio) m_pAudMux = DNew CWavDestFilter(NULL, &hr); } void CPlayerCaptureDialog::UpdateOutputControls() { UpdateData(); m_recordbtn.EnableWindow(!m_file.IsEmpty() && (m_pAMVSC && m_fVidOutput || m_pAMASC && m_fAudOutput)); m_vidcodec.EnableWindow(TRUE); m_audcodec.EnableWindow(TRUE); } void CPlayerCaptureDialog::UpdateGraph() { UpdateMediaTypes(); // UpdateMuxer(); ((CMainFrame*)AfxGetMainWnd())->BuildGraphVideoAudio(m_fVidPreview, false, m_fAudPreview, false); UpdateUserDefinableControls(); } void CPlayerCaptureDialog::EnableControls(CWnd* pWnd, bool fEnable) { if(fEnable) { for(CWnd* pChild = pWnd->GetWindow(GW_CHILD); pChild; pChild = pChild->GetNextWindow()) { BOOL fEnabled; if(m_wndenabledmap.Lookup(pChild->m_hWnd, fEnabled)) pChild->EnableWindow(fEnabled); EnableControls(pChild, fEnable); } if(pWnd->m_hWnd == m_hWnd) m_wndenabledmap.RemoveAll(); m_recordbtn.SetWindowText(_T("Record")); } else { if(pWnd->m_hWnd == m_hWnd) m_wndenabledmap.RemoveAll(); for(CWnd* pChild = pWnd->GetWindow(GW_CHILD); pChild; pChild = pChild->GetNextWindow()) { m_wndenabledmap[pChild->m_hWnd] = pChild->IsWindowEnabled(); pChild->EnableWindow(FALSE); EnableControls(pChild, fEnable); } m_recordbtn.EnableWindow(TRUE); m_recordbtn.SetWindowText(_T("Stop")); } } void CPlayerCaptureDialog::SetupVideoControls( CStringW DisplayName, IAMStreamConfig* pAMSC, IAMCrossbar* pAMXB, IAMTVTuner* pAMTuner) { EmptyVideo(); // crossbar if(m_pAMXB = pAMXB) { long OutputPinCount, InputPinCount; if(SUCCEEDED(pAMXB->get_PinCounts(&OutputPinCount, &InputPinCount))) { for(int i = 0; i < InputPinCount; i++) { long PinIndexRelated, PhysicalType; if(FAILED(pAMXB->get_CrossbarPinInfo(TRUE, i, &PinIndexRelated, &PhysicalType))) continue; if(PhysicalType >= PhysConn_Audio_Tuner) continue; CString str; switch(PhysicalType) { case PhysConn_Video_Tuner: str = _T("Tuner"); break; case PhysConn_Video_Composite: str = _T("Composite"); break; case PhysConn_Video_SVideo: str = _T("SVideo"); break; case PhysConn_Video_RGB: str = _T("RGB"); break; case PhysConn_Video_YRYBY: str = _T("YRYBY"); break; case PhysConn_Video_SerialDigital: str = _T("SerialDigital"); break; case PhysConn_Video_ParallelDigital: str = _T("ParallelDigital"); break; case PhysConn_Video_SCSI: str = _T("SCSI"); break; case PhysConn_Video_AUX: str = _T("AUX"); break; case PhysConn_Video_1394: str = _T("1394"); break; case PhysConn_Video_USB: str = _T("USB"); break; case PhysConn_Video_VideoDecoder: str = _T("VideoDecoder"); break; case PhysConn_Video_VideoEncoder: str = _T("VideoEncoder"); break; case PhysConn_Video_SCART: str = _T("SCART"); break; default: str.Format(_T("PhysicalType %d"), PhysicalType); break; } m_vidinput.SetItemData(m_vidinput.AddString(str), i); } } } if(m_vidinput.GetCount() > 0) { m_vidinput.EnableWindow(TRUE); long OutputPinCount, InputPinCount; if(SUCCEEDED(pAMXB->get_PinCounts(&OutputPinCount, &InputPinCount))) { for(int i = 0; i < OutputPinCount; i++) { long InputPinIndex; if(S_OK == pAMXB->get_IsRoutedTo(i, &InputPinIndex)) { for(int j = 0; j < m_vidinput.GetCount(); j++) { if(m_vidinput.GetItemData(j) == (DWORD_PTR)InputPinIndex) { m_vidinput.SetCurSel(j); i = OutputPinCount; break; } } } } } OnVideoInput(); } // tuner if(m_pAMTuner = pAMTuner) { // TODO:... } // streamconfig if(m_pAMVSC = pAMSC) { m_VidDisplayName = DisplayName; AM_MEDIA_TYPE* pmt; if(LoadMediaType(DisplayName, &pmt)) { pAMSC->SetFormat(pmt); DeleteMediaType(pmt); } SetupMediaTypes(pAMSC, m_vfa, m_vidtype, m_viddimension, m_mtv); } if(m_vidtype.GetCount() > 0) { m_vidfpsedit.EnableWindow(TRUE); m_vidhor.EnableWindow(TRUE); m_vidver.EnableWindow(TRUE); m_vidhoredit.EnableWindow(TRUE); m_vidveredit.EnableWindow(TRUE); m_vidsetres.EnableWindow(TRUE); } { m_vidoutput.EnableWindow(TRUE); m_vidpreview.EnableWindow(TRUE); } UpdateMediaTypes(); UpdateUserDefinableControls(); UpdateOutputControls(); } void CPlayerCaptureDialog::SetupVideoControls( CStringW DisplayName, IAMStreamConfig* pAMSC, IAMVfwCaptureDialogs* pAMVfwCD) { EmptyVideo(); if(m_pAMVfwCD = pAMVfwCD) { if(S_OK == m_pAMVfwCD->HasDialog(VfwCaptureDialog_Source)) m_vidinput.SetItemData(m_vidinput.AddString(_T("Source")), (DWORD_PTR)VfwCaptureDialog_Source); if(S_OK == m_pAMVfwCD->HasDialog(VfwCaptureDialog_Format)) m_vidinput.SetItemData(m_vidinput.AddString(_T("Format")), (DWORD_PTR)VfwCaptureDialog_Format); if(S_OK == m_pAMVfwCD->HasDialog(VfwCaptureDialog_Display)) m_vidinput.SetItemData(m_vidinput.AddString(_T("Display")), (DWORD_PTR)VfwCaptureDialog_Display); if(m_vidinput.GetCount() > 0) { m_vidinput.EnableWindow(TRUE); m_vidinput.SetCurSel(0); } } // streamconfig if(m_pAMVSC = pAMSC) { m_VidDisplayName = DisplayName; AM_MEDIA_TYPE* pmt; if(LoadMediaType(DisplayName, &pmt)) { pAMSC->SetFormat(pmt); DeleteMediaType(pmt); } SetupMediaTypes(pAMSC, m_vfa, m_vidtype, m_viddimension, m_mtv); } if(m_vidtype.GetCount() > 0) { m_vidfpsedit.EnableWindow(TRUE); m_vidhor.EnableWindow(TRUE); m_vidver.EnableWindow(TRUE); m_vidhoredit.EnableWindow(TRUE); m_vidveredit.EnableWindow(TRUE); m_vidsetres.EnableWindow(TRUE); } { m_vidoutput.EnableWindow(TRUE); m_vidpreview.EnableWindow(TRUE); } UpdateMediaTypes(); UpdateUserDefinableControls(); UpdateOutputControls(); } void CPlayerCaptureDialog::SetupAudioControls( CStringW DisplayName, IAMStreamConfig* pAMSC, CInterfaceArray& pAMAIM) { EmptyAudio(); // input selection if(pAMAIM.GetCount() > 0) { m_pAMAIM.Copy(pAMAIM); int iSel = -1; for(int i = 0; i < (int)m_pAMAIM.GetCount(); i++) { CComQIPtr pPin = m_pAMAIM[i]; m_audinput.SetItemData(m_audinput.AddString(CString(GetPinName(pPin))), (DWORD_PTR)i); BOOL fEnable; if(SUCCEEDED(m_pAMAIM[i]->get_Enable(&fEnable)) && fEnable) iSel = i; } if(m_audinput.GetCount() > 0) { for(int i = 0; i < m_audinput.GetCount(); i++) { if(m_audinput.GetItemData(i) == (DWORD_PTR)iSel) { m_audinput.SetCurSel(i); break; } } m_audinput.EnableWindow(TRUE); } } // stream config if(m_pAMASC = pAMSC) { m_AudDisplayName = DisplayName; AM_MEDIA_TYPE* pmt; if(LoadMediaType(DisplayName, &pmt)) { pAMSC->SetFormat(pmt); DeleteMediaType(pmt); } SetupMediaTypes(pAMSC, m_afa, m_audtype, m_auddimension, m_mta); } // if(m_audtype.GetCount() > 0) { m_audoutput.EnableWindow(TRUE); m_audpreview.EnableWindow(TRUE); } UpdateMediaTypes(); UpdateUserDefinableControls(); UpdateOutputControls(); } bool CPlayerCaptureDialog::IsTunerActive() { int iSel = m_vidinput.GetCurSel(); if(iSel < 0) return(false); iSel = m_vidinput.GetItemData(iSel); if(iSel < 0) return(false); long PinIndexRelated, PhysicalType; return(m_pAMXB && SUCCEEDED(m_pAMXB->get_CrossbarPinInfo(TRUE, iSel, &PinIndexRelated, &PhysicalType)) && PhysicalType == PhysConn_Video_Tuner); } bool CPlayerCaptureDialog::SetVideoInput(int input) { if(!m_pAMXB || input < 0) return false; for(int i = 0; i < m_vidinput.GetCount(); i++) { if(m_vidinput.GetItemData(i) == (DWORD_PTR)input) { m_vidinput.SetCurSel(i); OnVideoInput(); return true; } } return false; } bool CPlayerCaptureDialog::SetVideoChannel(int channel) { if(!m_pAMTuner || channel < 0) return false; return SUCCEEDED(m_pAMTuner->put_Channel(channel, AMTUNER_SUBCHAN_DEFAULT, AMTUNER_SUBCHAN_DEFAULT)); } bool CPlayerCaptureDialog::SetAudioInput(int input) { if(input < 0) return false; for(int i = 0; i < m_audinput.GetCount(); i++) { if(m_audinput.GetItemData(i) == (DWORD_PTR)input) { m_audinput.SetCurSel(i); OnAudioInput(); return true; } } return false; } int CPlayerCaptureDialog::GetVideoInput() { int i = m_vidinput.GetCurSel(); if(i < 0) return -1; return m_vidinput.GetItemData(i); } int CPlayerCaptureDialog::GetVideoChannel() { long lChannel, lVivSub, lAudSub; return m_pAMTuner && SUCCEEDED(m_pAMTuner->get_Channel(&lChannel, &lVivSub, &lAudSub)) ? lChannel : -1; } int CPlayerCaptureDialog::GetAudioInput() { int i = m_audinput.GetCurSel(); if(i < 0) return -1; return m_audinput.GetItemData(i); } BEGIN_MESSAGE_MAP(CPlayerCaptureDialog, CResizableDialog) ON_WM_DESTROY() ON_CBN_SELCHANGE(IDC_COMBO4, OnVideoInput) ON_CBN_SELCHANGE(IDC_COMBO1, OnVideoType) ON_CBN_SELCHANGE(IDC_COMBO5, OnVideoDimension) ON_BN_CLICKED(IDC_BUTTON1, OnOverrideVideoDimension) ON_CBN_SELCHANGE(IDC_COMBO3, OnAudioInput) ON_CBN_SELCHANGE(IDC_COMBO2, OnAudioType) ON_CBN_SELCHANGE(IDC_COMBO6, OnAudioDimension) ON_BN_CLICKED(IDC_CHECK1, OnRecordVideo) ON_CBN_SELCHANGE(IDC_COMBO7, OnVideoCodec) ON_CBN_SELCHANGE(IDC_COMBO9, OnVideoCodecType) ON_CBN_SELCHANGE(IDC_COMBO10, OnVideoCodecDimension) ON_BN_CLICKED(IDC_CHECK3, OnRecordAudio) ON_CBN_SELCHANGE(IDC_COMBO8, OnAudioCodec) ON_CBN_SELCHANGE(IDC_COMBO12, OnAudioCodecType) ON_CBN_SELCHANGE(IDC_COMBO11, OnAudioCodecDimension) ON_BN_CLICKED(IDC_BUTTON3, OnOpenFile) ON_BN_CLICKED(IDC_BUTTON2, OnRecord) ON_EN_CHANGE(IDC_EDIT5, OnEnChangeEdit9) ON_EN_CHANGE(IDC_EDIT6, OnEnChangeEdit12) ON_WM_TIMER() ON_BN_CLICKED(IDC_CHECK2, OnBnClickedVidAudPreview) ON_BN_CLICKED(IDC_CHECK4, OnBnClickedVidAudPreview) ON_BN_CLICKED(IDC_CHECK5, OnBnClickedCheck7) ON_CBN_SELCHANGE(IDC_COMBO14, OnCbnSelchangeCombo14) END_MESSAGE_MAP() // CPlayerCaptureDialog message handlers BOOL CPlayerCaptureDialog::OnInitDialog() { __super::OnInitDialog(); InitCodecList(m_pVidEncArray, m_vidcodec, CLSID_VideoCompressorCategory); UpdateVideoCodec(); InitCodecList(m_pAudEncArray, m_audcodec, CLSID_AudioCompressorCategory); UpdateAudioCodec(); m_fEnableOgm = IsCLSIDRegistered(_T("{8cae96b7-85b1-4605-b23c-17ff5262b296}")); m_nVidBuffers = AfxGetApp()->GetProfileInt(_T("Capture"), _T("VidBuffers"), 50); m_nAudBuffers = AfxGetApp()->GetProfileInt(_T("Capture"), _T("AudBuffers"), 50); m_fVidOutput = !!AfxGetApp()->GetProfileInt(_T("Capture"), _T("VidOutput"), TRUE); m_fAudOutput = !!AfxGetApp()->GetProfileInt(_T("Capture"), _T("AudOutput"), TRUE); m_fVidPreview = AfxGetApp()->GetProfileInt(_T("Capture"), _T("VidPreview"), TRUE); m_fAudPreview = AfxGetApp()->GetProfileInt(_T("Capture"), _T("AudPreview"), TRUE); m_muxtype = AfxGetApp()->GetProfileInt(_T("Capture"), _T("FileFormat"), 0); m_file = AfxGetApp()->GetProfileString(_T("Capture"), _T("FileName"), _T("")); m_fSepAudio = AfxGetApp()->GetProfileInt(_T("Capture"), _T("SepAudio"), TRUE); m_muxctrl.AddString(_T("AVI")); m_muxctrl.AddString(_T("Ogg Media")); m_muxctrl.AddString(_T("Matroska")); m_muxctrl.AddString(_T("DirectShow Media")); // UpdateMuxer(); UpdateData(FALSE); OnCbnSelchangeCombo14(); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } void CPlayerCaptureDialog::OnDestroy() { UpdateData(); AfxGetApp()->WriteProfileInt(_T("Capture"), _T("VidOutput"), m_fVidOutput); AfxGetApp()->WriteProfileInt(_T("Capture"), _T("AudOutput"), m_fAudOutput); AfxGetApp()->WriteProfileInt(_T("Capture"), _T("VidPreview"), m_fVidPreview); AfxGetApp()->WriteProfileInt(_T("Capture"), _T("AudPreview"), m_fAudPreview); AfxGetApp()->WriteProfileInt(_T("Capture"), _T("FileFormat"), m_muxtype); AfxGetApp()->WriteProfileString(_T("Capture"), _T("FileName"), m_file); AfxGetApp()->WriteProfileInt(_T("Capture"), _T("SepAudio"), m_fSepAudio); __super::OnDestroy(); } void CPlayerCaptureDialog::OnVideoInput() { int iSel = m_vidinput.GetCurSel(); if(iSel < 0) return; iSel = m_vidinput.GetItemData(iSel); if(iSel < 0) return; if(m_pAMXB) { long PinIndexRelated, PhysicalType; if(FAILED(m_pAMXB->get_CrossbarPinInfo(TRUE, iSel, &PinIndexRelated, &PhysicalType))) return; long OutputPinCount, InputPinCount; if(FAILED(m_pAMXB->get_PinCounts(&OutputPinCount, &InputPinCount))) return; for(int i = 0; i < OutputPinCount; i++) { if(S_OK == m_pAMXB->CanRoute(i, iSel)) { m_pAMXB->Route(i, iSel); break; } } if(PinIndexRelated >= 0) { for(int i = 0; i < OutputPinCount; i++) { if(S_OK == m_pAMXB->CanRoute(i, PinIndexRelated)) { m_pAMXB->Route(i, PinIndexRelated); break; } } } } else if(m_pAMVfwCD) { if(S_OK == m_pAMVfwCD->HasDialog(iSel)) { HRESULT hr = m_pAMVfwCD->ShowDialog(iSel, m_hWnd); if(VFW_E_NOT_STOPPED == hr) { ((CMainFrame*)AfxGetMainWnd())->SendMessage(WM_COMMAND, ID_PLAY_STOP); hr = m_pAMVfwCD->ShowDialog(iSel, m_hWnd); ((CMainFrame*)AfxGetMainWnd())->SendMessage(WM_COMMAND, ID_PLAY_PLAY); } if(VFW_E_CANNOT_CONNECT == hr) UpdateGraph(); } } } void CPlayerCaptureDialog::OnVideoType() { if(SetupDimension(m_vfa, m_vidtype, m_viddimension)) OnVideoDimension(); } void CPlayerCaptureDialog::OnVideoDimension() { int iSel = m_viddimension.GetCurSel(); if(iSel < 0) return; CVidFormatElem* pvfe = (CVidFormatElem*)m_viddimension.GetItemData(iSel); if(!pvfe) return; BITMAPINFOHEADER* bih = (pvfe->mt.formattype == FORMAT_VideoInfo) ? &((VIDEOINFOHEADER*)pvfe->mt.pbFormat)->bmiHeader : (pvfe->mt.formattype == FORMAT_VideoInfo2) ? &((VIDEOINFOHEADER2*)pvfe->mt.pbFormat)->bmiHeader : NULL; m_vidhor.SetRange(0, 32767); m_vidver.SetRange(0, 32767); m_vidhor.SetPos(bih->biWidth); m_vidver.SetPos(abs(bih->biHeight)); CString fps; fps.Format(_T("%.4f"), (float)(10000000.0 / ((VIDEOINFOHEADER*)pvfe->mt.pbFormat)->AvgTimePerFrame)); m_vidfpsedit.SetWindowText(fps); UpdateGraph(); } void CPlayerCaptureDialog::OnOverrideVideoDimension() { UpdateGraph(); } void CPlayerCaptureDialog::OnAudioInput() { int iSel = m_audinput.GetCurSel(); for(int i = 0; i < (int)m_pAMAIM.GetCount(); i++) { m_pAMAIM[m_audinput.GetItemData(i)]->put_Enable(i == iSel ? TRUE : FALSE); } } void CPlayerCaptureDialog::OnAudioType() { if(SetupDimension(m_afa, m_audtype, m_auddimension)) OnAudioDimension(); } void CPlayerCaptureDialog::OnAudioDimension() { UpdateGraph(); } void CPlayerCaptureDialog::OnRecordVideo() { UpdateOutputControls(); } void CPlayerCaptureDialog::OnVideoCodec() { ShowPPage(m_pVidEncArray, m_vidcodec, m_hWnd); UpdateVideoCodec(); } void CPlayerCaptureDialog::OnVideoCodecType() { if(SetupDimension(m_vcfa, m_vidcodectype, m_vidcodecdimension)) OnVideoCodecDimension(); } void CPlayerCaptureDialog::OnVideoCodecDimension() { int i = m_vidcodecdimension.GetCurSel(); if(i >= 0) { m_mtcv = ((CVidFormatElem*)m_vidcodecdimension.GetItemData(i))->mt; // we have to recreate the encoder, otherwise it will accept the new media type for only the first time m_pVidEnc = NULL; m_pVidEncMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&m_pVidEnc); } } void CPlayerCaptureDialog::OnRecordAudio() { UpdateOutputControls(); } void CPlayerCaptureDialog::OnAudioCodec() { ShowPPage(m_pAudEncArray, m_audcodec, m_hWnd); UpdateAudioCodec(); } void CPlayerCaptureDialog::OnAudioCodecType() { if(SetupDimension(m_acfa, m_audcodectype, m_audcodecdimension)) OnAudioCodecDimension(); } void CPlayerCaptureDialog::OnAudioCodecDimension() { int i = m_audcodecdimension.GetCurSel(); if(i >= 0) { m_mtca = ((CAudFormatElem*)m_audcodecdimension.GetItemData(i))->mt; // we have to recreate the encoder, otherwise it will accept the new media type for only the first time m_pAudEnc = NULL; m_pAudEncMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&m_pAudEnc); /* SaveMediaType( CString(m_pAudEncArray[m_audcodec.GetItemData(m_audcodec.GetCurSel())].DisplayName.m_str), &m_mtca); */ } } void CPlayerCaptureDialog::OnOpenFile() { CFileDialog fd(FALSE, NULL, NULL, OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, _T("Media files (*.avi,*.ogm,*.mkv,*.dsm)|*.avi;*.ogm;*.mkv;*.dsm|"), this, 0); if(fd.DoModal() == IDOK) { CString str = fd.GetPathName(); CString ext = str.Mid(str.ReverseFind('.')+1).MakeLower(); if(ext == _T("avi")) m_muxtype = 0; else if(ext == _T("ogm")) m_muxtype = 1; else if(ext == _T("mkv")) m_muxtype = 2; else if(ext == _T("dsm")) m_muxtype = 3; else { if(m_muxtype == 0) str += _T(".avi"); else if(m_muxtype == 1) str += _T(".ogm"); else if(m_muxtype == 2) str += _T(".mkv"); else if(m_muxtype == 3) str += _T(".dsm"); } m_file = str; UpdateData(FALSE); } UpdateOutputControls(); } void CPlayerCaptureDialog::OnRecord() { UpdateData(); CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd(); if(!pFrame) return; if(!pFrame->m_fCapturing) { UpdateMuxer(); CComQIPtr pFSF = m_pMux; if(pFSF) { m_pDst = m_pMux; } else { m_pDst = NULL; m_pDst.CoCreateInstance(CLSID_FileWriter); pFSF = m_pDst; } if(!pFSF || FAILED(pFSF->SetFileName(CStringW(m_file), NULL)) || FAILED(pFSF->SetMode(AM_FILE_OVERWRITE))) { AfxMessageBox(_T("Error initializing the output file")); return; } CString audfn = m_file.Left(m_file.ReverseFind('.')+1); if(m_fSepAudio && m_fAudOutput && m_pAudMux && !audfn.IsEmpty()) { audfn += _T("wav"); CComQIPtr pFSF = m_pAudMux; if(pFSF) { m_pAudDst = m_pAudMux; } else { m_pAudDst = NULL; m_pAudDst.CoCreateInstance(CLSID_FileWriter); pFSF = m_pAudDst; } if(!pFSF || FAILED(pFSF->SetFileName(CStringW(audfn), NULL)) || FAILED(pFSF->SetMode(AM_FILE_OVERWRITE))) { AfxMessageBox(_T("Error initializing the audio output file")); return; } } m_pVidBuffer = m_fVidOutput && m_nVidBuffers > 0 && m_muxtype != 2 && m_muxtype != 3 ? DNew CBufferFilter(NULL, NULL) : NULL; if(CComQIPtr pVB = m_pVidBuffer) { pVB->SetBuffers(m_nVidBuffers); pVB->SetPriority(THREAD_PRIORITY_NORMAL); } m_pAudBuffer = m_fAudOutput && m_nAudBuffers > 0 && m_muxtype != 2 && m_muxtype != 3 ? DNew CBufferFilter(NULL, NULL) : NULL; if(CComQIPtr pAB = m_pAudBuffer) { pAB->SetBuffers(m_nAudBuffers); pAB->SetPriority(THREAD_PRIORITY_ABOVE_NORMAL); } EnableControls(this, false); pFrame->StartCapture(); SetTimer(1, 100, NULL); } else { KillTimer(1); pFrame->StopCapture(); /* { if(FILE* f = _tfopen(m_file, _T("rb+"))) { fseek(f, 0x20, SEEK_SET); unsigned short mspf = (unsigned short)(((VIDEOINFOHEADER*)m_mtv.pbFormat)->AvgTimePerFrame / 10); fwrite(&mspf, 1, 2, f); fclose(f); } } */ EnableControls(this, true); m_pVidBuffer = NULL; m_pAudBuffer = NULL; } } void CPlayerCaptureDialog::OnEnChangeEdit9() { UpdateData(); AfxGetApp()->WriteProfileInt(_T("Capture"), _T("VidBuffers"), max(m_nVidBuffers, 0)); } void CPlayerCaptureDialog::OnEnChangeEdit12() { UpdateData(); AfxGetApp()->WriteProfileInt(_T("Capture"), _T("AudBuffers"), max(m_nAudBuffers, 0)); } void CPlayerCaptureDialog::OnTimer(UINT_PTR nIDEvent) { if(nIDEvent == 1) { if(((CMainFrame*)AfxGetMainWnd())->m_fCapturing) { ULARGE_INTEGER FreeBytesAvailable, TotalNumberOfBytes, TotalNumberOfFreeBytes; if(GetDiskFreeSpaceEx(m_file.Left(m_file.ReverseFind('\\')+1), &FreeBytesAvailable, &TotalNumberOfBytes, &TotalNumberOfFreeBytes) && FreeBytesAvailable.QuadPart < 1024i64*1024*10) { OnRecord(); } } } __super::OnTimer(nIDEvent); } void CPlayerCaptureDialog::OnBnClickedVidAudPreview() { UpdateData(); UpdateGraph(); } void CPlayerCaptureDialog::OnBnClickedCheck7() { // UpdateMuxer(); } void CPlayerCaptureDialog::OnCbnSelchangeCombo14() { UpdateData(); CString ext = m_file.Mid(m_file.ReverseFind('.')+1).MakeLower(); if(m_muxtype == 0 && ext != _T("avi")) m_file = m_file.Left(m_file.GetLength()-4) + _T(".avi"); else if(m_muxtype == 1 && ext != _T("ogm")) m_file = m_file.Left(m_file.GetLength()-4) + _T(".ogm"); else if(m_muxtype == 2 && ext != _T("mkv")) m_file = m_file.Left(m_file.GetLength()-4) + _T(".mkv"); else if(m_muxtype == 3 && ext != _T("dsm")) m_file = m_file.Left(m_file.GetLength()-4) + _T(".dsm"); UpdateData(FALSE); GetDlgItem(IDC_EDIT5)->EnableWindow(m_muxtype != 2 && m_muxtype != 3); GetDlgItem(IDC_EDIT6)->EnableWindow(m_muxtype != 2 && m_muxtype != 3); m_recordbtn.EnableWindow(m_muxtype != 1 || m_fEnableOgm); }