00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "stdafx.h"
00026 #include "mplayerc.h"
00027 #include "mainfrm.h"
00028 #include "PlayerCaptureDialog.h"
00029 #include "..\..\DSUtil\DSUtil.h"
00030 #include "..\..\..\include\Ogg\OggDS.h"
00031 #include "..\..\filters\muxer\wavdest\wavdest.h"
00032 #include "..\..\filters\muxer\MatroskaMuxer\MatroskaMuxer.h"
00033 #include "..\..\filters\muxer\DSMMuxer\DSMMuxer.h"
00034 #include ".\playercapturedialog.h"
00035
00036 static bool LoadMediaType(CStringW DisplayName, AM_MEDIA_TYPE** ppmt)
00037 {
00038 bool fRet = false;
00039
00040 if(!ppmt) return(fRet);
00041
00042 *ppmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
00043 if(!*ppmt) return(fRet);
00044
00045 memset(*ppmt, 0, sizeof(AM_MEDIA_TYPE));
00046
00047 BYTE* pData;
00048 UINT len;
00049 if(AfxGetApp()->GetProfileBinary(_T("Capture\\") + CString(DisplayName), _T("MediaType"), &pData, &len))
00050 {
00051 if(len != sizeof(AM_MEDIA_TYPE)) return(fRet);
00052 memcpy(*ppmt, pData, len);
00053 delete [] pData;
00054
00055 (*ppmt)->cbFormat = 0;
00056 (*ppmt)->pbFormat = NULL;
00057
00058 fRet = true;
00059
00060 if(AfxGetApp()->GetProfileBinary(_T("Capture\\") + CString(DisplayName), _T("Format"), &pData, &len))
00061 {
00062 if(!len) return(fRet);
00063 (*ppmt)->cbFormat = len;
00064 (*ppmt)->pbFormat = (BYTE*)CoTaskMemAlloc(len);
00065 memcpy((*ppmt)->pbFormat, pData, len);
00066 delete [] pData;
00067
00068 }
00069 }
00070
00071 return(fRet);
00072 }
00073
00074 static void SaveMediaType(CStringW DisplayName, AM_MEDIA_TYPE* pmt)
00075 {
00076 if(DisplayName.IsEmpty() || !pmt) return;
00077
00078 AfxGetApp()->WriteProfileBinary(_T("Capture\\") + CString(DisplayName), _T("MediaType"), (BYTE*)pmt, sizeof(AM_MEDIA_TYPE));
00079 AfxGetApp()->WriteProfileBinary(_T("Capture\\") + CString(DisplayName), _T("Format"), pmt->pbFormat, pmt->cbFormat);
00080 }
00081
00082 static void LoadDefaultCodec(CArray<Codec>& codecs, CComboBox& box, const GUID& cat)
00083 {
00084 int len = box.GetCount();
00085 if(len >= 0) box.SetCurSel(0);
00086
00087 if(cat == GUID_NULL) return;
00088
00089 CString DisplayName = AfxGetApp()->GetProfileString(_T("Capture\\") + CStringFromGUID(cat), _T("DisplayName"));
00090
00091 for(int i = 0; i < len; i++)
00092 {
00093 int iSel = box.GetItemData(i);
00094 if(iSel < 0) continue;
00095
00096 Codec& c = codecs[iSel];
00097 if(DisplayName == c.DisplayName)
00098 {
00099 box.SetCurSel(i);
00100 if(!c.pBF)
00101 c.pMoniker->BindToObject(NULL, NULL, __uuidof(IBaseFilter), (void**)&c.pBF);
00102 break;
00103 }
00104 }
00105 }
00106
00107 static void SaveDefaultCodec(CArray<Codec>& codecs, CComboBox& box, const GUID& cat)
00108 {
00109 if(cat == GUID_NULL) return;
00110
00111 CString guid = CStringFromGUID(cat);
00112
00113 AfxGetApp()->WriteProfileString(_T("Capture\\") + guid, NULL, NULL);
00114
00115 int iSel = box.GetCurSel();
00116 if(iSel < 0) return;
00117 iSel = box.GetItemData(iSel);
00118 if(iSel < 0) return;
00119
00120 Codec& codec = codecs[iSel];
00121
00122 AfxGetApp()->WriteProfileString(_T("Capture\\") + guid, _T("DisplayName"), CString(codec.DisplayName));
00123 }
00124
00125 static void SetupDefaultCaps(AM_MEDIA_TYPE* pmt, VIDEO_STREAM_CONFIG_CAPS& caps)
00126 {
00127 memset(&caps, 0, sizeof(caps));
00128
00129 if(!pmt) return;
00130
00131 VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)pmt->pbFormat;
00132
00133 BITMAPINFOHEADER* bih = (pmt->formattype == FORMAT_VideoInfo)
00134 ? &((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader
00135 : (pmt->formattype == FORMAT_VideoInfo2)
00136 ? &((VIDEOINFOHEADER2*)pmt->pbFormat)->bmiHeader
00137 : NULL;
00138
00139 caps.guid = GUID_NULL;
00140 caps.VideoStandard = 0;
00141 caps.InputSize.cx = bih->biWidth;
00142 caps.InputSize.cy = abs(bih->biHeight);
00143 caps.MinCroppingSize = caps.MaxCroppingSize = caps.InputSize;
00144 caps.CropGranularityX = caps.CropGranularityY = 1;
00145 caps.CropAlignX = caps.CropAlignY = 1;
00146 caps.MinOutputSize = CSize(64, 64);
00147 caps.MaxOutputSize = CSize(768, 576);
00148 caps.OutputGranularityX = 16;
00149 caps.OutputGranularityY = 1;
00150 caps.StretchTapsX = caps.StretchTapsY = 0;
00151 caps.ShrinkTapsX = caps.ShrinkTapsY = 0;
00152 caps.MinFrameInterval = 100000i64;
00153 caps.MaxFrameInterval = 100000000i64;
00154 caps.MinBitsPerSecond = caps.MaxBitsPerSecond = 0;
00155 }
00156
00157 static void SetupDefaultCaps(AM_MEDIA_TYPE* pmt, AUDIO_STREAM_CONFIG_CAPS& caps)
00158 {
00159 memset(&caps, 0, sizeof(caps));
00160
00161 if(!pmt) return;
00162
00163 WAVEFORMATEX* wfe = (WAVEFORMATEX*)pmt->pbFormat;
00164
00165 caps.guid = GUID_NULL;
00166 caps.MinimumChannels = caps.MaximumChannels = wfe->nChannels;
00167 caps.ChannelsGranularity = 1;
00168 caps.MinimumBitsPerSample = caps.MaximumBitsPerSample = wfe->wBitsPerSample;
00169 caps.BitsPerSampleGranularity = 1;
00170 caps.MinimumSampleFrequency = caps.MaximumSampleFrequency = wfe->nSamplesPerSec;
00171 caps.SampleFrequencyGranularity = 1;
00172 }
00173
00174 template<class T>
00175 static void SetupMediaTypes(CComPtr<IAMStreamConfig> pAMSC, CFormatArray<T>& tfa, CComboBox& type, CComboBox& dim, CMediaType& mt)
00176 {
00177 tfa.RemoveAll();
00178 type.ResetContent();
00179 dim.ResetContent();
00180 type.EnableWindow(FALSE);
00181 dim.EnableWindow(FALSE);
00182
00183 if(!pAMSC) return;
00184
00185 AM_MEDIA_TYPE* pcurmt = NULL;
00186 pAMSC->GetFormat(&pcurmt);
00187
00188 int iCount = 0, iSize;
00189 if(SUCCEEDED(pAMSC->GetNumberOfCapabilities(&iCount, &iSize))
00190 && iSize == sizeof(T) && iCount > 0)
00191 {
00192 for(int i = 0; i < iCount; i++)
00193 {
00194 T caps;
00195 AM_MEDIA_TYPE* pmt = NULL;
00196 if(SUCCEEDED(pAMSC->GetStreamCaps(i, &pmt, (BYTE*)&caps)))
00197 {
00198 tfa.AddFormat(pmt, caps);
00199 }
00200 }
00201
00202 if(iSize == sizeof(VIDEO_STREAM_CONFIG_CAPS))
00203 {
00204 for(int i = 0, cnt = tfa.GetCount(); i < cnt; i++)
00205 {
00206 if(tfa[i]->GetCount() != 1) continue;
00207
00208 CFormatElem<T>* pfe = tfa[i]->GetAt(0);
00209
00210 if(pfe->mt.formattype != FORMAT_VideoInfo
00211 && pfe->mt.formattype != FORMAT_VideoInfo2)
00212 continue;
00213
00214 static SIZE presets[] =
00215 {
00216 {160, 120}, {192, 144},
00217 {320, 240}, {384, 288},
00218 {480, 240}, {512, 288},
00219 {480, 360}, {512, 384},
00220 {640, 240}, {768, 288},
00221 {640, 480}, {768, 576},
00222 {704, 240}, {704, 288},
00223 {704, 480}, {704, 576},
00224 {720, 240}, {720, 288},
00225 {720, 480}, {720, 576},
00226 {768, 240}, {768, 288},
00227 {768, 480}, {768, 576},
00228 };
00229
00230 VIDEO_STREAM_CONFIG_CAPS* pcaps = (VIDEO_STREAM_CONFIG_CAPS*)&pfe->caps;
00231 BITMAPINFOHEADER bihCur;
00232 ExtractBIH(&pfe->mt, &bihCur);
00233
00234 for(int j = 0; j < countof(presets); j++)
00235 {
00236 if(presets[j].cx == bihCur.biWidth
00237 && presets[j].cy == abs(bihCur.biHeight)
00238 || presets[j].cx < pcaps->MinOutputSize.cx
00239 || presets[j].cx > pcaps->MaxOutputSize.cx
00240 || presets[j].cy < pcaps->MinOutputSize.cy
00241 || presets[j].cy > pcaps->MaxOutputSize.cy
00242 || presets[j].cx % pcaps->OutputGranularityX
00243 || presets[j].cy % pcaps->OutputGranularityY)
00244 continue;
00245
00246 CMediaType mt = pfe->mt;
00247
00248 if(mt.formattype == FORMAT_VideoInfo)
00249 {
00250 VIDEOINFOHEADER* vih = (VIDEOINFOHEADER*)mt.pbFormat;
00251 if(!vih->bmiHeader.biHeight) vih->bmiHeader.biHeight = 1;
00252 vih->bmiHeader.biWidth = presets[j].cx;
00253 vih->bmiHeader.biHeight = presets[j].cy*(vih->bmiHeader.biHeight/vih->bmiHeader.biHeight);
00254 vih->bmiHeader.biSizeImage = presets[j].cx*presets[j].cy*vih->bmiHeader.biBitCount>>3;
00255
00256 AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
00257 CopyMediaType(pmt, &mt);
00258 tfa.AddFormat(pmt, pcaps, sizeof(*pcaps));
00259
00260 if(presets[j].cx*3 != presets[j].cy*4)
00261 {
00262 int extra = mt.cbFormat - sizeof(VIDEOINFOHEADER);
00263 int bmiHeaderSize = sizeof(vih->bmiHeader) + extra;
00264 BYTE* pbmiHeader = new BYTE[bmiHeaderSize];
00265 memcpy(pbmiHeader, &vih->bmiHeader, bmiHeaderSize);
00266 mt.ReallocFormatBuffer(FIELD_OFFSET(VIDEOINFOHEADER2, bmiHeader) + bmiHeaderSize);
00267 VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)mt.pbFormat;
00268 memcpy(&vih2->bmiHeader, pbmiHeader, bmiHeaderSize);
00269 delete [] pbmiHeader;
00270 vih2->dwInterlaceFlags = vih2->dwCopyProtectFlags = 0;
00271 vih2->dwReserved1 = vih2->dwReserved2 = 0;
00272 vih2->dwPictAspectRatioX = 4;
00273 vih2->dwPictAspectRatioY = 3;
00274
00275 AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
00276 CopyMediaType(pmt, &mt);
00277 tfa.AddFormat(pmt, pcaps, sizeof(*pcaps));
00278 }
00279 }
00280 else if(mt.formattype == FORMAT_VideoInfo2)
00281 {
00282 VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)mt.pbFormat;
00283 if(!vih2->bmiHeader.biHeight) vih2->bmiHeader.biHeight = 1;
00284 vih2->bmiHeader.biWidth = presets[j].cx;
00285 vih2->bmiHeader.biHeight = presets[j].cy*(vih2->bmiHeader.biHeight/vih2->bmiHeader.biHeight);
00286 vih2->bmiHeader.biSizeImage = presets[j].cx*presets[j].cy*vih2->bmiHeader.biBitCount>>3;
00287 vih2->dwPictAspectRatioX = 4;
00288 vih2->dwPictAspectRatioY = 3;
00289
00290 AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
00291 CopyMediaType(pmt, &mt);
00292 tfa.AddFormat(pmt, pcaps, sizeof(*pcaps));
00293 }
00294 }
00295 }
00296 }
00297 }
00298
00299 if(tfa.GetCount() == 0)
00300 {
00301 if(pcurmt && (pcurmt->majortype == MEDIATYPE_Video || pcurmt->majortype == MEDIATYPE_Audio))
00302 {
00303 AM_MEDIA_TYPE* pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
00304 CopyMediaType(pmt, pcurmt);
00305 T caps;
00306 SetupDefaultCaps(pmt, caps);
00307 tfa.AddFormat(pmt, caps);
00308 }
00309 else
00310 {
00311 mt.majortype = GUID_NULL;
00312 if(pcurmt) DeleteMediaType(pcurmt);
00313 return;
00314 }
00315 }
00316
00317 for(int i = 0; i < (int)tfa.GetCount(); i++)
00318 {
00319 CFormat<T>* pf = tfa[i];
00320 int j = type.AddString(pf->name);
00321 type.SetItemData(j, (DWORD_PTR)pf);
00322 }
00323
00324 CFormat<T>* pf = NULL;
00325 CFormatElem<T>* pfe = NULL;
00326
00327 if(!pcurmt)
00328 {
00329 pf = tfa[0];
00330 pfe = pf->GetAt(0);
00331 }
00332 else if(!tfa.FindFormat(pcurmt, NULL, &pf, &pfe) && !tfa.FindFormat(pcurmt, &pf))
00333 {
00334 if(pcurmt) DeleteMediaType(pcurmt);
00335 return;
00336 }
00337
00338 for(int i = 0; i < (int)pf->GetCount(); i++)
00339 {
00340 CFormatElem<T>* pfe = pf->GetAt(i);
00341 int j = dim.AddString(tfa.MakeDimensionName(pfe));
00342 dim.SetItemData(j, (DWORD_PTR)pfe);
00343 }
00344
00345 int iType = type.SetCurSel(type.FindStringExact(0, pf->name));
00346 if(iType < 0 && type.GetCount()) type.SetCurSel(0);
00347 int iDim = dim.SetCurSel(dim.FindStringExact(0, tfa.MakeDimensionName(pfe)));
00348
00349
00350 CorrectComboListWidth(type, type.GetParent()->GetFont());
00351 CorrectComboListWidth(dim, dim.GetParent()->GetFont());
00352
00353 if(iDim >= 0) mt = ((CFormatElem<T>*)dim.GetItemData(iDim))->mt;
00354 else if(pcurmt) mt = *pcurmt;
00355
00356 type.EnableWindow(type.GetCount() > 0);
00357 dim.EnableWindow(dim.GetCount() > 0);
00358
00359 if(pcurmt) DeleteMediaType(pcurmt);
00360 }
00361
00362 template<class T>
00363 static bool SetupDimension(CFormatArray<T>& tfa, CComboBox& type, CComboBox& dim)
00364 {
00365 CString str;
00366 dim.GetWindowText(str);
00367
00368 dim.ResetContent();
00369 dim.EnableWindow(FALSE);
00370
00371 int iSel = type.GetCurSel();
00372 if(iSel < 0) return(false);
00373
00374 CFormat<T>* pf = (CFormat<T>*)type.GetItemData(iSel);
00375
00376 for(int i = 0; i < (int)pf->GetCount(); i++)
00377 {
00378 CFormatElem<T>* pfe = pf->GetAt(i);
00379 dim.SetItemData(dim.AddString(tfa.MakeDimensionName(pfe)), (DWORD_PTR)pfe);
00380 }
00381
00382 CorrectComboListWidth(dim, dim.GetParent()->GetFont());
00383
00384 dim.SetCurSel(dim.FindStringExact(0, str));
00385 dim.EnableWindow(dim.GetCount() > 0);
00386
00387 return(dim.GetCurSel() >= 0);
00388 }
00389
00390 static void InitCodecList(CArray<Codec>& codecs, CComboBox& box, const GUID& cat)
00391 {
00392 codecs.RemoveAll();
00393 box.ResetContent();
00394 box.EnableWindow(FALSE);
00395
00396 box.SetItemData(box.AddString(_T("Uncompressed")), (DWORD_PTR)-1);
00397
00398 BeginEnumSysDev(cat, pMoniker)
00399 {
00400 Codec c;
00401
00402 c.pMoniker = pMoniker;
00403
00404
00405
00406
00407
00408
00409
00410 LPOLESTR strName = NULL;
00411 if(FAILED(pMoniker->GetDisplayName(NULL, NULL, &strName)))
00412 continue;
00413
00414 c.DisplayName = strName;
00415 CoTaskMemFree(strName);
00416
00417 CComPtr<IPropertyBag> pPB;
00418 pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB);
00419
00420 CComVariant var;
00421 if(FAILED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL)))
00422 continue;
00423
00424 c.FriendlyName = var.bstrVal;
00425
00426 CStringW str = CStringW(c.DisplayName).MakeLower();
00427 if(str.Find(L"@device:dmo:") == 0)
00428 c.FriendlyName = _T("(DMO) ") + c.FriendlyName;
00429 else if(str.Find(L"@device:sw:") == 0)
00430 c.FriendlyName = _T("(DS) ") + c.FriendlyName;
00431 else if(str.Find(L"@device:cm:") == 0)
00432 c.FriendlyName = _T("(VfW) ") + c.FriendlyName;
00433
00434 box.SetItemData(
00435 box.AddString(c.FriendlyName),
00436 (DWORD_PTR)codecs.Add(c));
00437 }
00438 EndEnumSysDev
00439
00440 box.EnableWindow(box.GetCount() > 1);
00441
00442 CorrectComboListWidth(box, box.GetParent()->GetFont());
00443
00444 LoadDefaultCodec(codecs, box, cat);
00445 }
00446
00447 static int ShowPPage(CArray<Codec>& codecs, CComboBox& box, HWND hWnd = NULL)
00448 {
00449 int iSel = box.GetCurSel();
00450 if(iSel < 0) return(-1);
00451
00452 iSel = box.GetItemData(iSel);
00453 if(iSel < 0) return(-1);
00454
00455 Codec& c = codecs[iSel];
00456
00457 if(!c.pBF)
00458 {
00459 c.pMoniker->BindToObject(NULL, NULL, __uuidof(IBaseFilter), (void**)&c.pBF);
00460 }
00461
00462 if(CComQIPtr<ISpecifyPropertyPages> pSPP = c.pBF)
00463 {
00464 CAUUID caGUID;
00465 caGUID.pElems = NULL;
00466 if(SUCCEEDED(pSPP->GetPages(&caGUID)))
00467 {
00468 IUnknown* lpUnk = NULL;
00469 pSPP.QueryInterface(&lpUnk);
00470 OleCreatePropertyFrame(
00471 hWnd, 0, 0, CStringW(c.FriendlyName),
00472 1, (IUnknown**)&lpUnk,
00473 caGUID.cElems, caGUID.pElems,
00474 0, 0, NULL);
00475 lpUnk->Release();
00476
00477 if(caGUID.pElems) CoTaskMemFree(caGUID.pElems);
00478 }
00479 }
00480 else if(CComQIPtr<IAMVfwCompressDialogs> pAMVfWCD = c.pBF)
00481 {
00482 if(pAMVfWCD->ShowDialog(VfwCompressDialog_QueryConfig, NULL) == S_OK)
00483 pAMVfWCD->ShowDialog(VfwCompressDialog_Config, hWnd);
00484 }
00485
00486 return(iSel);
00487 }
00488
00489
00490
00491 IMPLEMENT_DYNAMIC(CPlayerCaptureDialog, CDialog)
00492 CPlayerCaptureDialog::CPlayerCaptureDialog()
00493 : CDialog(CPlayerCaptureDialog::IDD, NULL)
00494 , m_vidfps(0)
00495 , m_file(_T(""))
00496 , m_fVidOutput(TRUE)
00497 , m_fAudOutput(TRUE)
00498 , m_fVidPreview(FALSE)
00499 , m_fAudPreview(FALSE)
00500 , m_nVidBuffers(0)
00501 , m_nAudBuffers(0)
00502 , m_pVidBuffer(NULL)
00503 , m_pAudBuffer(NULL)
00504 , m_fSepAudio(FALSE)
00505 , m_muxtype(0)
00506 {
00507 }
00508
00509 CPlayerCaptureDialog::~CPlayerCaptureDialog()
00510 {
00511 EmptyVideo();
00512 EmptyAudio();
00513 }
00514
00515 BOOL CPlayerCaptureDialog::Create(CWnd* pParent)
00516 {
00517 if(!__super::Create(IDD, pParent))
00518 return FALSE;
00519
00520 EmptyVideo();
00521 EmptyAudio();
00522
00523 return TRUE;
00524 }
00525
00526 void CPlayerCaptureDialog::DoDataExchange(CDataExchange* pDX)
00527 {
00528 __super::DoDataExchange(pDX);
00529 DDX_Control(pDX, IDC_COMBO4, m_vidinput);
00530 DDX_Control(pDX, IDC_COMBO1, m_vidtype);
00531 DDX_Control(pDX, IDC_COMBO5, m_viddimension);
00532 DDX_Control(pDX, IDC_SPIN1, m_vidhor);
00533 DDX_Control(pDX, IDC_SPIN2, m_vidver);
00534 DDX_Control(pDX, IDC_EDIT1, m_vidhoredit);
00535 DDX_Control(pDX, IDC_EDIT2, m_vidveredit);
00536 DDX_Control(pDX, IDC_EDIT3, m_vidfpsedit);
00537 DDX_Control(pDX, IDC_BUTTON1, m_vidsetres);
00538 DDX_Control(pDX, IDC_COMBO3, m_audinput);
00539 DDX_Control(pDX, IDC_COMBO2, m_audtype);
00540 DDX_Control(pDX, IDC_COMBO6, m_auddimension);
00541 DDX_Control(pDX, IDC_COMBO7, m_vidcodec);
00542 DDX_Control(pDX, IDC_COMBO9, m_vidcodectype);
00543 DDX_Control(pDX, IDC_COMBO10, m_vidcodecdimension);
00544 DDX_Check(pDX, IDC_CHECK2, m_fVidOutput);
00545 DDX_Control(pDX, IDC_CHECK2, m_vidoutput);
00546 DDX_Check(pDX, IDC_CHECK4, m_fVidPreview);
00547 DDX_Control(pDX, IDC_CHECK4, m_vidpreview);
00548 DDX_Control(pDX, IDC_COMBO8, m_audcodec);
00549 DDX_Control(pDX, IDC_COMBO12, m_audcodectype);
00550 DDX_Control(pDX, IDC_COMBO11, m_audcodecdimension);
00551 DDX_Check(pDX, IDC_CHECK3, m_fAudOutput);
00552 DDX_Control(pDX, IDC_CHECK3, m_audoutput);
00553 DDX_Check(pDX, IDC_CHECK5, m_fAudPreview);
00554 DDX_Control(pDX, IDC_CHECK5, m_audpreview);
00555 DDX_Text(pDX, IDC_EDIT4, m_file);
00556 DDX_Control(pDX, IDC_BUTTON2, m_recordbtn);
00557 DDX_Text(pDX, IDC_EDIT9, m_nVidBuffers);
00558 DDX_Text(pDX, IDC_EDIT12, m_nAudBuffers);
00559 DDX_Check(pDX, IDC_CHECK7, m_fSepAudio);
00560 DDX_CBIndex(pDX, IDC_COMBO14, m_muxtype);
00561 DDX_Control(pDX, IDC_COMBO14, m_muxctrl);
00562 }
00563
00564 BOOL CPlayerCaptureDialog::PreTranslateMessage(MSG* pMsg)
00565 {
00566 if(pMsg->message == WM_KEYDOWN)
00567 {
00568 if(pMsg->wParam == VK_RETURN)
00569 {
00570 CWnd* pFocused = GetFocus();
00571 if(pFocused && pFocused->m_hWnd == m_vidfpsedit.m_hWnd)
00572 {
00573 UpdateGraph();
00574 }
00575 }
00576 }
00577
00578 return __super::PreTranslateMessage(pMsg);
00579 }
00580
00581
00582 void CPlayerCaptureDialog::EmptyVideo()
00583 {
00584
00585
00586 if(m_pAMTuner && !m_VidDisplayName.IsEmpty())
00587 {
00588 long lChannel = 0, lVivSub = 0, lAudSub = 0;
00589 m_pAMTuner->get_Channel(&lChannel, &lVivSub, &lAudSub);
00590 AfxGetApp()->WriteProfileInt(_T("Capture\\") + CString(m_VidDisplayName), _T("Channel"), lChannel);
00591 }
00592
00593
00594
00595 m_vfa.RemoveAll();
00596
00597 m_pAMXB = NULL;
00598 m_pAMTuner = NULL;
00599 m_pAMVSC = NULL;
00600
00601 if(IsWindow(m_hWnd))
00602 {
00603 m_vidinput.ResetContent();
00604 m_vidinput.EnableWindow(FALSE);
00605 m_vidtype.ResetContent();
00606 m_vidtype.EnableWindow(FALSE);
00607 m_viddimension.ResetContent();
00608 m_viddimension.EnableWindow(FALSE);
00609 m_vidhor.EnableWindow(FALSE);
00610 m_vidver.EnableWindow(FALSE);
00611 m_vidhoredit.EnableWindow(FALSE);
00612 m_vidveredit.EnableWindow(FALSE);
00613 m_vidfpsedit.EnableWindow(FALSE);
00614 m_vidfps = 0;
00615 m_vidsetres.EnableWindow(FALSE);
00616 UpdateData(FALSE);
00617 }
00618 }
00619
00620 void CPlayerCaptureDialog::EmptyAudio()
00621 {
00622 m_afa.RemoveAll();
00623
00624 m_pAMASC = NULL;
00625 m_pAMAIM.RemoveAll();
00626
00627 if(IsWindow(m_hWnd))
00628 {
00629 m_audinput.ResetContent();
00630 m_audinput.EnableWindow(FALSE);
00631 m_audtype.ResetContent();
00632 m_audtype.EnableWindow(FALSE);
00633 m_auddimension.ResetContent();
00634 m_auddimension.EnableWindow(FALSE);
00635 UpdateData(FALSE);
00636 }
00637 }
00638
00639 void CPlayerCaptureDialog::UpdateMediaTypes()
00640 {
00641 UpdateData();
00642
00643
00644
00645 CString fps;
00646 m_vidfpsedit.GetWindowText(fps);
00647 if(!fps.IsEmpty())
00648 {
00649 float ffps;
00650 _stscanf(fps, _T("%f"), &ffps);
00651 if(ffps > 0) m_vidfps = ffps;
00652 }
00653
00654
00655
00656 {
00657 AM_MEDIA_TYPE* pmt = NULL;
00658 VIDEO_STREAM_CONFIG_CAPS* pcaps = NULL;
00659
00660 int i = m_viddimension.GetCurSel();
00661 if(i >= 0)
00662 {
00663 pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
00664 CopyMediaType(pmt, &((CVidFormatElem*)m_viddimension.GetItemData(i))->mt);
00665 pcaps = &((CVidFormatElem*)m_viddimension.GetItemData(i))->caps;
00666 }
00667 else if(m_pAMVSC)
00668 {
00669 m_pAMVSC->GetFormat(&pmt);
00670 }
00671
00672 if(pmt)
00673 {
00674 if(m_vidfps > 0)
00675 {
00676 REFERENCE_TIME atpf = (REFERENCE_TIME)(10000000.0 / m_vidfps);
00677
00678 if(pcaps)
00679 {
00680
00681
00682 }
00683
00684 if(pmt->formattype == FORMAT_VideoInfo)
00685 ((VIDEOINFOHEADER*)pmt->pbFormat)->AvgTimePerFrame = atpf;
00686 else if(pmt->formattype == FORMAT_VideoInfo2)
00687 ((VIDEOINFOHEADER2*)pmt->pbFormat)->AvgTimePerFrame = atpf;
00688 }
00689
00690 BITMAPINFOHEADER* bih = (pmt->formattype == FORMAT_VideoInfo)
00691 ? &((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader
00692 : (pmt->formattype == FORMAT_VideoInfo2)
00693 ? &((VIDEOINFOHEADER2*)pmt->pbFormat)->bmiHeader
00694 : NULL;
00695
00696 bih->biWidth = m_vidhor.GetPos();
00697 bih->biHeight = m_vidver.GetPos();
00698 bih->biSizeImage = bih->biWidth*bih->biHeight*bih->biBitCount>>3;
00699
00700 SaveMediaType(m_VidDisplayName, pmt);
00701
00702 m_mtv = *pmt;
00703 DeleteMediaType(pmt);
00704 }
00705 }
00706
00707
00708
00709 {
00710 AM_MEDIA_TYPE* pmt = NULL;
00711
00712 int i = m_auddimension.GetCurSel();
00713 if(i >= 0)
00714 {
00715 pmt = (AM_MEDIA_TYPE*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
00716 CopyMediaType(pmt, &((CAudFormatElem*)m_auddimension.GetItemData(i))->mt);
00717 }
00718 else if(m_pAMASC)
00719 {
00720 m_pAMASC->GetFormat(&pmt);
00721 }
00722
00723 if(pmt)
00724 {
00725 SaveMediaType(m_AudDisplayName, pmt);
00726
00727 m_mta = *pmt;
00728 DeleteMediaType(pmt);
00729 }
00730 }
00731 }
00732
00733 void CPlayerCaptureDialog::UpdateUserDefinableControls()
00734 {
00735 int iSel = m_viddimension.GetCurSel();
00736 if(iSel < 0) return;
00737
00738 CVidFormatElem* pvfe = (CVidFormatElem*)m_viddimension.GetItemData(iSel);
00739 if(!pvfe) return;
00740
00741 if(!m_pAMVSC) return;
00742
00743 AM_MEDIA_TYPE* pmt = NULL;
00744 m_pAMVSC->GetFormat(&pmt);
00745 if(!pmt) return;
00746
00747 BITMAPINFOHEADER* bih = (pmt->formattype == FORMAT_VideoInfo)
00748 ? &((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader
00749 : (pmt->formattype == FORMAT_VideoInfo2)
00750 ? &((VIDEOINFOHEADER2*)pmt->pbFormat)->bmiHeader
00751 : NULL;
00752
00753 if(!bih) return;
00754
00755 UDACCEL ua[3] = {{0,0},{2,0},{4,0}};
00756
00757 int w = m_vidhor.GetPos(), h = m_vidver.GetPos();
00758
00759 m_vidhor.SetRange((short)pvfe->caps.MinOutputSize.cx, (short)pvfe->caps.MaxOutputSize.cx);
00760
00761
00762
00763 ua[0].nInc = pvfe->caps.OutputGranularityX;
00764 ua[1].nInc = pvfe->caps.OutputGranularityX*2;
00765 ua[2].nInc = pvfe->caps.OutputGranularityX*4;
00766 m_vidhor.SetAccel(3, ua);
00767
00768 m_vidver.SetRange((short)pvfe->caps.MinOutputSize.cy, (short)pvfe->caps.MaxOutputSize.cy);
00769 ua[0].nInc = pvfe->caps.OutputGranularityY;
00770 ua[1].nInc = pvfe->caps.OutputGranularityY*2;
00771 ua[2].nInc = pvfe->caps.OutputGranularityY*4;
00772 m_vidver.SetAccel(3, ua);
00773
00774 m_vidhor.SetPos(bih->biWidth);
00775 m_vidver.SetPos(abs(bih->biHeight));
00776
00777 CString fps;
00778 fps.Format(_T("%.4f"), (float)(10000000.0 / ((VIDEOINFOHEADER*)pmt->pbFormat)->AvgTimePerFrame));
00779 m_vidfpsedit.SetWindowText(fps);
00780
00781 DeleteMediaType(pmt);
00782 }
00783
00784 void CPlayerCaptureDialog::UpdateVideoCodec()
00785 {
00786 int iSel = m_vidcodec.GetCurSel();
00787 if(iSel >= 0) iSel = m_vidcodec.GetItemData(iSel);
00788
00789 m_pVidEnc = iSel < 0 ? NULL : m_pVidEncArray[iSel].pBF;
00790 m_pVidEncMoniker = iSel < 0 ? NULL : m_pVidEncArray[iSel].pMoniker;
00791
00792
00793 CComQIPtr<IAMStreamConfig> pAMSC = GetFirstPin(m_pVidEnc, PINDIR_OUTPUT);
00794
00795 SetupMediaTypes(pAMSC, m_vcfa, m_vidcodectype, m_vidcodecdimension, m_mtcv);
00796
00797 SaveDefaultCodec(m_pVidEncArray, m_vidcodec, CLSID_VideoCompressorCategory);
00798
00799
00800 }
00801
00802 void CPlayerCaptureDialog::UpdateAudioCodec()
00803 {
00804 int iSel = m_audcodec.GetCurSel();
00805 if(iSel >= 0) iSel = m_audcodec.GetItemData(iSel);
00806
00807 m_pAudEnc = iSel < 0 ? NULL : m_pAudEncArray[iSel].pBF;
00808 m_pAudEncMoniker = iSel < 0 ? NULL : m_pAudEncArray[iSel].pMoniker;
00809
00810
00811 CComQIPtr<IAMStreamConfig> pAMSC = GetFirstPin(m_pAudEnc, PINDIR_OUTPUT);
00812
00813 SetupMediaTypes(pAMSC, m_acfa, m_audcodectype, m_audcodecdimension, m_mtca);
00814
00815 SaveDefaultCodec(m_pAudEncArray, m_audcodec, CLSID_AudioCompressorCategory);
00816
00817
00818 }
00819
00820 void CPlayerCaptureDialog::UpdateMuxer()
00821 {
00822 m_pMux = NULL;
00823 m_pAudMux = NULL;
00824
00825 UpdateData();
00826
00827 HRESULT hr;
00828
00829 if(m_muxtype == 0) m_pMux.CoCreateInstance(CLSID_AviDest);
00830 else if(m_muxtype == 1) m_pMux.CoCreateInstance(CLSID_OggMux);
00831 else if(m_muxtype == 2) m_pMux = new CMatroskaMuxerFilter(NULL, &hr);
00832 else if(m_muxtype == 3) m_pMux = new CDSMMuxerFilter(NULL, &hr);
00833 else return;
00834
00835 if(m_fSepAudio) m_pAudMux = new CWavDestFilter(NULL, &hr);
00836 }
00837
00838 void CPlayerCaptureDialog::UpdateOutputControls()
00839 {
00840 UpdateData();
00841
00842 m_recordbtn.EnableWindow(!m_file.IsEmpty() && (m_pAMVSC && m_fVidOutput || m_pAMASC && m_fAudOutput));
00843 m_vidcodec.EnableWindow(TRUE);
00844 m_audcodec.EnableWindow(TRUE);
00845 }
00846
00847 void CPlayerCaptureDialog::UpdateGraph()
00848 {
00849 UpdateMediaTypes();
00850
00851
00852
00853 ((CMainFrame*)AfxGetMainWnd())->BuildGraphVideoAudio(!!m_fVidPreview, false, !!m_fAudPreview, false);
00854
00855 UpdateUserDefinableControls();
00856 }
00857
00858 void CPlayerCaptureDialog::EnableControls(CWnd* pWnd, bool fEnable)
00859 {
00860 if(fEnable)
00861 {
00862 for(CWnd* pChild = pWnd->GetWindow(GW_CHILD); pChild; pChild = pChild->GetNextWindow())
00863 {
00864 BOOL fEnabled;
00865 if(m_wndenabledmap.Lookup(pChild->m_hWnd, fEnabled))
00866 pChild->EnableWindow(fEnabled);
00867 EnableControls(pChild, fEnable);
00868 }
00869
00870 if(pWnd->m_hWnd == m_hWnd)
00871 m_wndenabledmap.RemoveAll();
00872
00873 m_recordbtn.SetWindowText(_T("Record"));
00874 }
00875 else
00876 {
00877 if(pWnd->m_hWnd == m_hWnd)
00878 m_wndenabledmap.RemoveAll();
00879
00880 for(CWnd* pChild = pWnd->GetWindow(GW_CHILD); pChild; pChild = pChild->GetNextWindow())
00881 {
00882 m_wndenabledmap[pChild->m_hWnd] = pChild->IsWindowEnabled();
00883 pChild->EnableWindow(FALSE);
00884 EnableControls(pChild, fEnable);
00885 }
00886
00887 m_recordbtn.EnableWindow(TRUE);
00888 m_recordbtn.SetWindowText(_T("Stop"));
00889 }
00890 }
00891
00892 void CPlayerCaptureDialog::SetupVideoControls(
00893 CStringW DisplayName,
00894 CComPtr<IAMStreamConfig> pAMSC, CComPtr<IAMCrossbar> pAMXB, CComPtr<IAMTVTuner> pAMTuner)
00895 {
00896 EmptyVideo();
00897
00898
00899
00900 if(m_pAMXB = pAMXB)
00901 {
00902 long OutputPinCount, InputPinCount;
00903 if(SUCCEEDED(pAMXB->get_PinCounts(&OutputPinCount, &InputPinCount)))
00904 {
00905 for(int i = 0; i < InputPinCount; i++)
00906 {
00907 long PinIndexRelated, PhysicalType;
00908 if(FAILED(pAMXB->get_CrossbarPinInfo(TRUE, i, &PinIndexRelated, &PhysicalType)))
00909 continue;
00910
00911 if(PhysicalType >= PhysConn_Audio_Tuner)
00912 continue;
00913
00914 CString str;
00915 switch(PhysicalType)
00916 {
00917 case PhysConn_Video_Tuner: str = _T("Tuner"); break;
00918 case PhysConn_Video_Composite: str = _T("Composite"); break;
00919 case PhysConn_Video_SVideo: str = _T("SVideo"); break;
00920 case PhysConn_Video_RGB: str = _T("RGB"); break;
00921 case PhysConn_Video_YRYBY: str = _T("YRYBY"); break;
00922 case PhysConn_Video_SerialDigital: str = _T("SerialDigital"); break;
00923 case PhysConn_Video_ParallelDigital: str = _T("ParallelDigital"); break;
00924 case PhysConn_Video_SCSI: str = _T("SCSI"); break;
00925 case PhysConn_Video_AUX: str = _T("AUX"); break;
00926 case PhysConn_Video_1394: str = _T("1394"); break;
00927 case PhysConn_Video_USB: str = _T("USB"); break;
00928 case PhysConn_Video_VideoDecoder: str = _T("VideoDecoder"); break;
00929 case PhysConn_Video_VideoEncoder: str = _T("VideoEncoder"); break;
00930 case PhysConn_Video_SCART: str = _T("SCART"); break;
00931 default: str.Format(_T("PhysicalType %d"), PhysicalType); break;
00932 }
00933
00934 m_vidinput.SetItemData(m_vidinput.AddString(str), i);
00935 }
00936 }
00937 }
00938
00939 if(m_vidinput.GetCount() > 0)
00940 {
00941 m_vidinput.EnableWindow(TRUE);
00942
00943 long OutputPinCount, InputPinCount;
00944 if(SUCCEEDED(pAMXB->get_PinCounts(&OutputPinCount, &InputPinCount)))
00945 {
00946 for(int i = 0; i < OutputPinCount; i++)
00947 {
00948 long InputPinIndex;
00949 if(S_OK == pAMXB->get_IsRoutedTo(i, &InputPinIndex))
00950 {
00951 for(int j = 0; j < m_vidinput.GetCount(); j++)
00952 {
00953 if(m_vidinput.GetItemData(j) == InputPinIndex)
00954 {
00955 m_vidinput.SetCurSel(j);
00956 i = OutputPinCount;
00957 break;
00958 }
00959 }
00960 }
00961 }
00962 }
00963 }
00964
00965
00966
00967 if(m_pAMTuner = pAMTuner)
00968 {
00969
00970 }
00971
00972
00973
00974 if(m_pAMVSC = pAMSC)
00975 {
00976 m_VidDisplayName = DisplayName;
00977
00978 AM_MEDIA_TYPE* pmt;
00979 if(LoadMediaType(DisplayName, &pmt))
00980 {
00981 pAMSC->SetFormat(pmt);
00982 DeleteMediaType(pmt);
00983 }
00984
00985 SetupMediaTypes(pAMSC, m_vfa, m_vidtype, m_viddimension, m_mtv);
00986 }
00987
00988 if(m_vidtype.GetCount() > 0)
00989 {
00990 m_vidfpsedit.EnableWindow(TRUE);
00991 m_vidhor.EnableWindow(TRUE);
00992 m_vidver.EnableWindow(TRUE);
00993 m_vidhoredit.EnableWindow(TRUE);
00994 m_vidveredit.EnableWindow(TRUE);
00995 m_vidsetres.EnableWindow(TRUE);
00996 }
00997
00998 {
00999 m_vidoutput.EnableWindow(TRUE);
01000 m_vidpreview.EnableWindow(TRUE);
01001 }
01002
01003 UpdateMediaTypes();
01004
01005 UpdateUserDefinableControls();
01006
01007 UpdateOutputControls();
01008 }
01009
01010 void CPlayerCaptureDialog::SetupVideoControls(
01011 CStringW DisplayName,
01012 CComPtr<IAMStreamConfig> pAMSC, CComPtr<IAMVfwCaptureDialogs> pAMVfwCD)
01013 {
01014 EmptyVideo();
01015
01016 if(m_pAMVfwCD = pAMVfwCD)
01017 {
01018 if(S_OK == m_pAMVfwCD->HasDialog(VfwCaptureDialog_Source))
01019 m_vidinput.SetItemData(m_vidinput.AddString(_T("Source")), (DWORD_PTR)VfwCaptureDialog_Source);
01020 if(S_OK == m_pAMVfwCD->HasDialog(VfwCaptureDialog_Format))
01021 m_vidinput.SetItemData(m_vidinput.AddString(_T("Format")), (DWORD_PTR)VfwCaptureDialog_Format);
01022 if(S_OK == m_pAMVfwCD->HasDialog(VfwCaptureDialog_Display))
01023 m_vidinput.SetItemData(m_vidinput.AddString(_T("Display")), (DWORD_PTR)VfwCaptureDialog_Display);
01024
01025 if(m_vidinput.GetCount() > 0)
01026 {
01027 m_vidinput.EnableWindow(TRUE);
01028 m_vidinput.SetCurSel(0);
01029 }
01030 }
01031
01032
01033
01034 if(m_pAMVSC = pAMSC)
01035 {
01036 m_VidDisplayName = DisplayName;
01037
01038 AM_MEDIA_TYPE* pmt;
01039 if(LoadMediaType(DisplayName, &pmt))
01040 {
01041 pAMSC->SetFormat(pmt);
01042 DeleteMediaType(pmt);
01043 }
01044
01045 SetupMediaTypes(pAMSC, m_vfa, m_vidtype, m_viddimension, m_mtv);
01046 }
01047
01048 if(m_vidtype.GetCount() > 0)
01049 {
01050 m_vidfpsedit.EnableWindow(TRUE);
01051 m_vidhor.EnableWindow(TRUE);
01052 m_vidver.EnableWindow(TRUE);
01053 m_vidhoredit.EnableWindow(TRUE);
01054 m_vidveredit.EnableWindow(TRUE);
01055 m_vidsetres.EnableWindow(TRUE);
01056 }
01057
01058 {
01059 m_vidoutput.EnableWindow(TRUE);
01060 m_vidpreview.EnableWindow(TRUE);
01061 }
01062
01063 UpdateMediaTypes();
01064
01065 UpdateUserDefinableControls();
01066
01067 UpdateOutputControls();
01068 }
01069
01070 void CPlayerCaptureDialog::SetupAudioControls(
01071 CStringW DisplayName,
01072 CComPtr<IAMStreamConfig> pAMSC, CInterfaceArray<IAMAudioInputMixer>& pAMAIM)
01073 {
01074 EmptyAudio();
01075
01076
01077
01078 if(pAMAIM.GetCount() > 0)
01079 {
01080 m_pAMAIM.Copy(pAMAIM);
01081
01082 int iSel = -1;
01083
01084 for(int i = 0; i < (int)m_pAMAIM.GetCount(); i++)
01085 {
01086 CComQIPtr<IPin> pPin = m_pAMAIM[i];
01087 m_audinput.SetItemData(m_audinput.AddString(CString(GetPinName(pPin))), (DWORD_PTR)i);
01088
01089 BOOL fEnable;
01090 if(SUCCEEDED(m_pAMAIM[i]->get_Enable(&fEnable)) && fEnable)
01091 iSel = i;
01092 }
01093
01094 if(m_audinput.GetCount() > 0)
01095 {
01096 for(int i = 0; i < m_audinput.GetCount(); i++)
01097 {
01098 if(m_audinput.GetItemData(i) == iSel)
01099 {
01100 m_audinput.SetCurSel(i);
01101 break;
01102 }
01103 }
01104
01105 m_audinput.EnableWindow(TRUE);
01106 }
01107 }
01108
01109
01110
01111 if(m_pAMASC = pAMSC)
01112 {
01113 m_AudDisplayName = DisplayName;
01114
01115 AM_MEDIA_TYPE* pmt;
01116 if(LoadMediaType(DisplayName, &pmt))
01117 {
01118 pAMSC->SetFormat(pmt);
01119 DeleteMediaType(pmt);
01120 }
01121
01122 SetupMediaTypes(pAMSC, m_afa, m_audtype, m_auddimension, m_mta);
01123 }
01124
01125
01126 {
01127 m_audoutput.EnableWindow(TRUE);
01128 m_audpreview.EnableWindow(TRUE);
01129 }
01130
01131 UpdateMediaTypes();
01132
01133 UpdateUserDefinableControls();
01134
01135 UpdateOutputControls();
01136 }
01137
01138 bool CPlayerCaptureDialog::IsTunerActive()
01139 {
01140 int iSel = m_vidinput.GetCurSel();
01141 if(iSel < 0) return(false);
01142 iSel = m_vidinput.GetItemData(iSel);
01143 if(iSel < 0) return(false);
01144
01145 long PinIndexRelated, PhysicalType;
01146 return(m_pAMXB
01147 && SUCCEEDED(m_pAMXB->get_CrossbarPinInfo(TRUE, iSel, &PinIndexRelated, &PhysicalType))
01148 && PhysicalType == PhysConn_Video_Tuner);
01149 }
01150
01151 bool CPlayerCaptureDialog::SetVideoInput(int input)
01152 {
01153 if(!m_pAMXB || input < 0) return false;
01154
01155 for(int i = 0; i < m_vidinput.GetCount(); i++)
01156 {
01157 if(m_vidinput.GetItemData(i) == input)
01158 {
01159 m_vidinput.SetCurSel(i);
01160 OnVideoInput();
01161 return true;
01162 }
01163 }
01164
01165 return false;
01166 }
01167
01168 bool CPlayerCaptureDialog::SetVideoChannel(int channel)
01169 {
01170 if(!m_pAMTuner || channel < 0) return false;
01171
01172 return SUCCEEDED(m_pAMTuner->put_Channel(channel, AMTUNER_SUBCHAN_DEFAULT, AMTUNER_SUBCHAN_DEFAULT));
01173 }
01174
01175 bool CPlayerCaptureDialog::SetAudioInput(int input)
01176 {
01177 if(input < 0) return false;
01178
01179 for(int i = 0; i < m_audinput.GetCount(); i++)
01180 {
01181 if(m_audinput.GetItemData(i) == input)
01182 {
01183 m_audinput.SetCurSel(i);
01184 OnAudioInput();
01185 return true;
01186 }
01187 }
01188
01189 return false;
01190 }
01191
01192 int CPlayerCaptureDialog::GetVideoInput()
01193 {
01194 int i = m_vidinput.GetCurSel();
01195 if(i < 0) return -1;
01196 return m_vidinput.GetItemData(i);
01197 }
01198
01199 int CPlayerCaptureDialog::GetVideoChannel()
01200 {
01201 long lChannel, lVivSub, lAudSub;
01202 return m_pAMTuner && SUCCEEDED(m_pAMTuner->get_Channel(&lChannel, &lVivSub, &lAudSub)) ? lChannel : -1;
01203 }
01204
01205 int CPlayerCaptureDialog::GetAudioInput()
01206 {
01207 int i = m_audinput.GetCurSel();
01208 if(i < 0) return -1;
01209 return m_audinput.GetItemData(i);
01210 }
01211
01212 BEGIN_MESSAGE_MAP(CPlayerCaptureDialog, CDialog)
01213 ON_WM_DESTROY()
01214 ON_CBN_SELCHANGE(IDC_COMBO4, OnVideoInput)
01215 ON_CBN_SELCHANGE(IDC_COMBO1, OnVideoType)
01216 ON_CBN_SELCHANGE(IDC_COMBO5, OnVideoDimension)
01217 ON_BN_CLICKED(IDC_BUTTON1, OnOverrideVideoDimension)
01218 ON_CBN_SELCHANGE(IDC_COMBO3, OnAudioInput)
01219 ON_CBN_SELCHANGE(IDC_COMBO2, OnAudioType)
01220 ON_CBN_SELCHANGE(IDC_COMBO6, OnAudioDimension)
01221 ON_BN_CLICKED(IDC_CHECK2, OnRecordVideo)
01222 ON_CBN_SELCHANGE(IDC_COMBO7, OnVideoCodec)
01223 ON_CBN_SELCHANGE(IDC_COMBO9, OnVideoCodecType)
01224 ON_CBN_SELCHANGE(IDC_COMBO10, OnVideoCodecDimension)
01225 ON_BN_CLICKED(IDC_CHECK3, OnRecordAudio)
01226 ON_CBN_SELCHANGE(IDC_COMBO8, OnAudioCodec)
01227 ON_CBN_SELCHANGE(IDC_COMBO12, OnAudioCodecType)
01228 ON_CBN_SELCHANGE(IDC_COMBO11, OnAudioCodecDimension)
01229 ON_BN_CLICKED(IDC_BUTTON3, OnOpenFile)
01230 ON_BN_CLICKED(IDC_BUTTON2, OnRecord)
01231 ON_EN_CHANGE(IDC_EDIT9, OnEnChangeEdit9)
01232 ON_EN_CHANGE(IDC_EDIT12, OnEnChangeEdit12)
01233 ON_WM_TIMER()
01234 ON_BN_CLICKED(IDC_CHECK4, OnBnClickedVidAudPreview)
01235 ON_BN_CLICKED(IDC_CHECK5, OnBnClickedVidAudPreview)
01236 ON_BN_CLICKED(IDC_CHECK7, OnBnClickedCheck7)
01237 ON_CBN_SELCHANGE(IDC_COMBO14, OnCbnSelchangeCombo14)
01238 END_MESSAGE_MAP()
01239
01240
01241
01242
01243 BOOL CPlayerCaptureDialog::OnInitDialog()
01244 {
01245 __super::OnInitDialog();
01246
01247 InitCodecList(m_pVidEncArray, m_vidcodec, CLSID_VideoCompressorCategory);
01248 UpdateVideoCodec();
01249
01250 InitCodecList(m_pAudEncArray, m_audcodec, CLSID_AudioCompressorCategory);
01251 UpdateAudioCodec();
01252
01253 m_fEnableOgm = IsCLSIDRegistered(_T("{8cae96b7-85b1-4605-b23c-17ff5262b296}"));
01254
01255 m_nVidBuffers = AfxGetApp()->GetProfileInt(_T("Capture"), _T("VidBuffers"), 50);
01256 m_nAudBuffers = AfxGetApp()->GetProfileInt(_T("Capture"), _T("AudBuffers"), 50);
01257 m_fVidOutput = !!AfxGetApp()->GetProfileInt(_T("Capture"), _T("VidOutput"), TRUE);
01258 m_fAudOutput = !!AfxGetApp()->GetProfileInt(_T("Capture"), _T("AudOutput"), TRUE);
01259 m_fVidPreview = !!AfxGetApp()->GetProfileInt(_T("Capture"), _T("VidPreview"), TRUE);
01260 m_fAudPreview = !!AfxGetApp()->GetProfileInt(_T("Capture"), _T("AudPreview"), TRUE);
01261 m_muxtype = AfxGetApp()->GetProfileInt(_T("Capture"), _T("FileFormat"), 0);
01262 m_file = AfxGetApp()->GetProfileString(_T("Capture"), _T("FileName"), _T(""));
01263 m_fSepAudio = AfxGetApp()->GetProfileInt(_T("Capture"), _T("SepAudio"), TRUE);
01264
01265 m_muxctrl.AddString(_T("AVI"));
01266 m_muxctrl.AddString(_T("Ogg Media"));
01267 m_muxctrl.AddString(_T("Matroska"));
01268 m_muxctrl.AddString(_T("DirectShow Media"));
01269
01270
01271
01272 UpdateData(FALSE);
01273
01274 OnCbnSelchangeCombo14();
01275
01276 return TRUE;
01277
01278 }
01279
01280 void CPlayerCaptureDialog::OnDestroy()
01281 {
01282 UpdateData();
01283
01284 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("VidOutput"), m_fVidOutput);
01285 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("AudOutput"), m_fAudOutput);
01286 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("VidPreview"), m_fVidPreview);
01287 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("AudPreview"), m_fAudPreview);
01288 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("FileFormat"), m_muxtype);
01289 AfxGetApp()->WriteProfileString(_T("Capture"), _T("FileName"), m_file);
01290 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("SepAudio"), m_fSepAudio);
01291
01292 __super::OnDestroy();
01293 }
01294
01295 void CPlayerCaptureDialog::OnVideoInput()
01296 {
01297 int iSel = m_vidinput.GetCurSel();
01298 if(iSel < 0) return;
01299 iSel = m_vidinput.GetItemData(iSel);
01300 if(iSel < 0) return;
01301
01302 if(m_pAMXB)
01303 {
01304 long PinIndexRelated, PhysicalType;
01305 if(FAILED(m_pAMXB->get_CrossbarPinInfo(TRUE, iSel, &PinIndexRelated, &PhysicalType)))
01306 return;
01307
01308 long OutputPinCount, InputPinCount;
01309 if(FAILED(m_pAMXB->get_PinCounts(&OutputPinCount, &InputPinCount)))
01310 return;
01311
01312 for(int i = 0; i < OutputPinCount; i++)
01313 {
01314 if(S_OK == m_pAMXB->CanRoute(i, iSel))
01315 {
01316 m_pAMXB->Route(i, iSel);
01317 break;
01318 }
01319 }
01320
01321 if(PinIndexRelated >= 0)
01322 {
01323 for(int i = 0; i < OutputPinCount; i++)
01324 {
01325 if(S_OK == m_pAMXB->CanRoute(i, PinIndexRelated))
01326 {
01327 m_pAMXB->Route(i, PinIndexRelated);
01328 break;
01329 }
01330 }
01331 }
01332 }
01333 else if(m_pAMVfwCD)
01334 {
01335 if(S_OK == m_pAMVfwCD->HasDialog(iSel))
01336 {
01337 HRESULT hr = m_pAMVfwCD->ShowDialog(iSel, m_hWnd);
01338
01339 if(VFW_E_NOT_STOPPED == hr)
01340 {
01341 ((CMainFrame*)AfxGetMainWnd())->SendMessage(WM_COMMAND, ID_PLAY_STOP);
01342 hr = m_pAMVfwCD->ShowDialog(iSel, m_hWnd);
01343 ((CMainFrame*)AfxGetMainWnd())->SendMessage(WM_COMMAND, ID_PLAY_PLAY);
01344 }
01345
01346 if(VFW_E_CANNOT_CONNECT == hr)
01347 UpdateGraph();
01348 }
01349 }
01350 }
01351
01352 void CPlayerCaptureDialog::OnVideoType()
01353 {
01354 if(SetupDimension(m_vfa, m_vidtype, m_viddimension))
01355 OnVideoDimension();
01356 }
01357
01358 void CPlayerCaptureDialog::OnVideoDimension()
01359 {
01360 int iSel = m_viddimension.GetCurSel();
01361 if(iSel < 0) return;
01362
01363 CVidFormatElem* pvfe = (CVidFormatElem*)m_viddimension.GetItemData(iSel);
01364 if(!pvfe) return;
01365
01366 BITMAPINFOHEADER* bih = (pvfe->mt.formattype == FORMAT_VideoInfo)
01367 ? &((VIDEOINFOHEADER*)pvfe->mt.pbFormat)->bmiHeader
01368 : (pvfe->mt.formattype == FORMAT_VideoInfo2)
01369 ? &((VIDEOINFOHEADER2*)pvfe->mt.pbFormat)->bmiHeader
01370 : NULL;
01371
01372 m_vidhor.SetRange(0, 32767);
01373 m_vidver.SetRange(0, 32767);
01374 m_vidhor.SetPos(bih->biWidth);
01375 m_vidver.SetPos(abs(bih->biHeight));
01376 CString fps;
01377 fps.Format(_T("%.4f"), (float)(10000000.0 / ((VIDEOINFOHEADER*)pvfe->mt.pbFormat)->AvgTimePerFrame));
01378 m_vidfpsedit.SetWindowText(fps);
01379
01380 UpdateGraph();
01381 }
01382
01383 void CPlayerCaptureDialog::OnOverrideVideoDimension()
01384 {
01385 UpdateGraph();
01386 }
01387
01388 void CPlayerCaptureDialog::OnAudioInput()
01389 {
01390 int iSel = m_audinput.GetCurSel();
01391
01392 for(int i = 0; i < (int)m_pAMAIM.GetCount(); i++)
01393 {
01394 m_pAMAIM[m_audinput.GetItemData(i)]->put_Enable(i == iSel ? TRUE : FALSE);
01395 }
01396 }
01397
01398 void CPlayerCaptureDialog::OnAudioType()
01399 {
01400 if(SetupDimension(m_afa, m_audtype, m_auddimension))
01401 OnAudioDimension();
01402 }
01403
01404 void CPlayerCaptureDialog::OnAudioDimension()
01405 {
01406 UpdateGraph();
01407 }
01408
01409 void CPlayerCaptureDialog::OnRecordVideo()
01410 {
01411 UpdateOutputControls();
01412 }
01413
01414 void CPlayerCaptureDialog::OnVideoCodec()
01415 {
01416 ShowPPage(m_pVidEncArray, m_vidcodec, m_hWnd);
01417 UpdateVideoCodec();
01418 }
01419
01420 void CPlayerCaptureDialog::OnVideoCodecType()
01421 {
01422 if(SetupDimension(m_vcfa, m_vidcodectype, m_vidcodecdimension))
01423 OnVideoCodecDimension();
01424 }
01425
01426 void CPlayerCaptureDialog::OnVideoCodecDimension()
01427 {
01428 int i = m_vidcodecdimension.GetCurSel();
01429 if(i >= 0)
01430 {
01431 m_mtcv = ((CVidFormatElem*)m_vidcodecdimension.GetItemData(i))->mt;
01432
01433
01434 m_pVidEnc = NULL;
01435 m_pVidEncMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&m_pVidEnc);
01436 }
01437 }
01438
01439 void CPlayerCaptureDialog::OnRecordAudio()
01440 {
01441 UpdateOutputControls();
01442 }
01443
01444 void CPlayerCaptureDialog::OnAudioCodec()
01445 {
01446 ShowPPage(m_pAudEncArray, m_audcodec, m_hWnd);
01447 UpdateAudioCodec();
01448 }
01449
01450 void CPlayerCaptureDialog::OnAudioCodecType()
01451 {
01452 if(SetupDimension(m_acfa, m_audcodectype, m_audcodecdimension))
01453 OnAudioCodecDimension();
01454 }
01455
01456 void CPlayerCaptureDialog::OnAudioCodecDimension()
01457 {
01458 int i = m_audcodecdimension.GetCurSel();
01459 if(i >= 0)
01460 {
01461 m_mtca = ((CAudFormatElem*)m_audcodecdimension.GetItemData(i))->mt;
01462
01463
01464 m_pAudEnc = NULL;
01465 m_pAudEncMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&m_pAudEnc);
01466
01467
01468
01469
01470 }
01471 }
01472
01473 void CPlayerCaptureDialog::OnOpenFile()
01474 {
01475 CFileDialog fd(FALSE, NULL, NULL,
01476 OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,
01477 _T("Media files (*.avi,*.ogm,*.mkv,*.dsm)|*.avi;*.ogm;*.mkv;*.dsm|"), this, 0);
01478
01479 if(fd.DoModal() == IDOK)
01480 {
01481 CString str = fd.GetPathName();
01482
01483 CString ext = str.Mid(str.ReverseFind('.')+1).MakeLower();
01484 if(ext == _T("avi")) m_muxtype = 0;
01485 else if(ext == _T("ogm")) m_muxtype = 1;
01486 else if(ext == _T("mkv")) m_muxtype = 2;
01487 else if(ext == _T("dsm")) m_muxtype = 3;
01488 else
01489 {
01490 if(m_muxtype == 0) str += _T(".avi");
01491 else if(m_muxtype == 1) str += _T(".ogm");
01492 else if(m_muxtype == 2) str += _T(".mkv");
01493 else if(m_muxtype == 3) str += _T(".dsm");
01494 }
01495
01496 m_file = str;
01497
01498 UpdateData(FALSE);
01499 }
01500
01501 UpdateOutputControls();
01502 }
01503
01504 void CPlayerCaptureDialog::OnRecord()
01505 {
01506 UpdateData();
01507
01508 CMainFrame* pFrame = (CMainFrame*)AfxGetMainWnd();
01509 if(!pFrame) return;
01510
01511 if(!pFrame->m_fCapturing)
01512 {
01513 UpdateMuxer();
01514
01515 CComQIPtr<IFileSinkFilter2> pFSF = m_pMux;
01516 if(pFSF)
01517 {
01518 m_pDst = m_pMux;
01519 }
01520 else
01521 {
01522 m_pDst = NULL;
01523 m_pDst.CoCreateInstance(CLSID_FileWriter);
01524 pFSF = m_pDst;
01525 }
01526
01527 if(!pFSF
01528 || FAILED(pFSF->SetFileName(CStringW(m_file), NULL))
01529 || FAILED(pFSF->SetMode(AM_FILE_OVERWRITE)))
01530 {
01531 AfxMessageBox(_T("Error initializing the output file"));
01532 return;
01533 }
01534
01535 CString audfn = m_file.Left(m_file.ReverseFind('.')+1);
01536 if(m_fSepAudio && m_fAudOutput && m_pAudMux && !audfn.IsEmpty())
01537 {
01538 audfn += _T("wav");
01539
01540 CComQIPtr<IFileSinkFilter2> pFSF = m_pAudMux;
01541 if(pFSF)
01542 {
01543 m_pAudDst = m_pAudMux;
01544 }
01545 else
01546 {
01547 m_pAudDst = NULL;
01548 m_pAudDst.CoCreateInstance(CLSID_FileWriter);
01549 pFSF = m_pAudDst;
01550 }
01551
01552 if(!pFSF
01553 || FAILED(pFSF->SetFileName(CStringW(audfn), NULL))
01554 || FAILED(pFSF->SetMode(AM_FILE_OVERWRITE)))
01555 {
01556 AfxMessageBox(_T("Error initializing the audio output file"));
01557 return;
01558 }
01559 }
01560
01561 m_pVidBuffer = m_fVidOutput && m_nVidBuffers > 0 && m_muxtype != 2 && m_muxtype != 3 ? new CBufferFilter(NULL, NULL) : NULL;
01562 if(CComQIPtr<IBufferFilter> pVB = m_pVidBuffer)
01563 {pVB->SetBuffers(m_nVidBuffers); pVB->SetPriority(THREAD_PRIORITY_NORMAL);}
01564
01565 m_pAudBuffer = m_fAudOutput && m_nAudBuffers > 0 && m_muxtype != 2 && m_muxtype != 3 ? new CBufferFilter(NULL, NULL) : NULL;
01566 if(CComQIPtr<IBufferFilter> pAB = m_pAudBuffer)
01567 {pAB->SetBuffers(m_nAudBuffers); pAB->SetPriority(THREAD_PRIORITY_ABOVE_NORMAL);}
01568
01569 EnableControls(this, false);
01570
01571 pFrame->StartCapture();
01572
01573 SetTimer(1, 100, NULL);
01574 }
01575 else
01576 {
01577 KillTimer(1);
01578
01579 pFrame->StopCapture();
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591 EnableControls(this, true);
01592
01593 m_pVidBuffer = NULL;
01594 m_pAudBuffer = NULL;
01595 }
01596 }
01597
01598 void CPlayerCaptureDialog::OnEnChangeEdit9()
01599 {
01600 UpdateData();
01601 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("VidBuffers"), max(m_nVidBuffers, 0));
01602 }
01603
01604 void CPlayerCaptureDialog::OnEnChangeEdit12()
01605 {
01606 UpdateData();
01607 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("AudBuffers"), max(m_nAudBuffers, 0));
01608 }
01609
01610 void CPlayerCaptureDialog::OnTimer(UINT nIDEvent)
01611 {
01612 if(nIDEvent == 1)
01613 {
01614 if(((CMainFrame*)AfxGetMainWnd())->m_fCapturing)
01615 {
01616 ULARGE_INTEGER FreeBytesAvailable, TotalNumberOfBytes, TotalNumberOfFreeBytes;
01617 if(GetDiskFreeSpaceEx(m_file.Left(m_file.ReverseFind('\\')+1), &FreeBytesAvailable, &TotalNumberOfBytes, &TotalNumberOfFreeBytes)
01618 && FreeBytesAvailable.QuadPart < 1024i64*1024*10)
01619 {
01620 OnRecord();
01621 }
01622 }
01623 }
01624
01625 __super::OnTimer(nIDEvent);
01626 }
01627
01628 void CPlayerCaptureDialog::OnBnClickedVidAudPreview()
01629 {
01630 UpdateData();
01631 UpdateGraph();
01632 }
01633
01634 void CPlayerCaptureDialog::OnBnClickedCheck7()
01635 {
01636
01637 }
01638
01639 void CPlayerCaptureDialog::OnCbnSelchangeCombo14()
01640 {
01641 UpdateData();
01642
01643 CString ext = m_file.Mid(m_file.ReverseFind('.')+1).MakeLower();
01644
01645 if(m_muxtype == 0 && ext != _T("avi"))
01646 m_file = m_file.Left(m_file.GetLength()-4) + _T(".avi");
01647 else if(m_muxtype == 1 && ext != _T("ogm"))
01648 m_file = m_file.Left(m_file.GetLength()-4) + _T(".ogm");
01649 else if(m_muxtype == 2 && ext != _T("mkv"))
01650 m_file = m_file.Left(m_file.GetLength()-4) + _T(".mkv");
01651 else if(m_muxtype == 3 && ext != _T("dsm"))
01652 m_file = m_file.Left(m_file.GetLength()-4) + _T(".dsm");
01653
01654 UpdateData(FALSE);
01655
01656 GetDlgItem(IDC_EDIT9)->EnableWindow(m_muxtype != 2 && m_muxtype != 3);
01657 GetDlgItem(IDC_EDIT12)->EnableWindow(m_muxtype != 2 && m_muxtype != 3);
01658
01659 m_recordbtn.EnableWindow(m_muxtype != 1 || m_fEnableOgm);
01660 }