2 * Copyright (C) 2003-2006 Gabest
3 * http://www.gabest.org
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with GNU Make; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
22 // PlayerCaptureDialog.cpp : implementation file
28 #include "PlayerCaptureDialog.h"
29 #include "..\..\DSUtil\DSUtil.h"
30 #include "..\..\..\include\moreuuids.h"
31 #include "..\..\filters\muxer\wavdest\wavdest.h"
32 #include "..\..\filters\muxer\MatroskaMuxer\MatroskaMuxer.h"
33 #include "..\..\filters\muxer\DSMMuxer\DSMMuxer.h"
35 static bool LoadMediaType(CStringW DisplayName
, AM_MEDIA_TYPE
** ppmt
)
39 if(!ppmt
) return(fRet
);
41 *ppmt
= (AM_MEDIA_TYPE
*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
));
42 if(!*ppmt
) return(fRet
);
44 memset(*ppmt
, 0, sizeof(AM_MEDIA_TYPE
));
48 if(AfxGetApp()->GetProfileBinary(_T("Capture\\") + CString(DisplayName
), _T("MediaType"), &pData
, &len
))
50 if(len
!= sizeof(AM_MEDIA_TYPE
)) return(fRet
);
51 memcpy(*ppmt
, pData
, len
);
54 (*ppmt
)->cbFormat
= 0;
55 (*ppmt
)->pbFormat
= NULL
;
59 if(AfxGetApp()->GetProfileBinary(_T("Capture\\") + CString(DisplayName
), _T("Format"), &pData
, &len
))
61 if(!len
) return(fRet
);
62 (*ppmt
)->cbFormat
= len
;
63 (*ppmt
)->pbFormat
= (BYTE
*)CoTaskMemAlloc(len
);
64 memcpy((*ppmt
)->pbFormat
, pData
, len
);
73 static void SaveMediaType(CStringW DisplayName
, AM_MEDIA_TYPE
* pmt
)
75 if(DisplayName
.IsEmpty() || !pmt
) return;
77 AfxGetApp()->WriteProfileBinary(_T("Capture\\") + CString(DisplayName
), _T("MediaType"), (BYTE
*)pmt
, sizeof(AM_MEDIA_TYPE
));
78 AfxGetApp()->WriteProfileBinary(_T("Capture\\") + CString(DisplayName
), _T("Format"), pmt
->pbFormat
, pmt
->cbFormat
);
81 static void LoadDefaultCodec(CAtlArray
<Codec
>& codecs
, CComboBox
& box
, const GUID
& cat
)
83 int len
= box
.GetCount();
84 if(len
>= 0) box
.SetCurSel(0);
86 if(cat
== GUID_NULL
) return;
88 CString DisplayName
= AfxGetApp()->GetProfileString(_T("Capture\\") + CStringFromGUID(cat
), _T("DisplayName"));
90 for(int i
= 0; i
< len
; i
++)
92 int iSel
= box
.GetItemData(i
);
93 if(iSel
< 0) continue;
95 Codec
& c
= codecs
[iSel
];
96 if(DisplayName
== c
.DisplayName
)
100 c
.pMoniker
->BindToObject(NULL
, NULL
, __uuidof(IBaseFilter
), (void**)&c
.pBF
);
106 static void SaveDefaultCodec(CAtlArray
<Codec
>& codecs
, CComboBox
& box
, const GUID
& cat
)
108 if(cat
== GUID_NULL
) return;
110 CString guid
= CStringFromGUID(cat
);
112 AfxGetApp()->WriteProfileString(_T("Capture\\") + guid
, NULL
, NULL
);
114 int iSel
= box
.GetCurSel();
116 iSel
= box
.GetItemData(iSel
);
119 Codec
& codec
= codecs
[iSel
];
121 AfxGetApp()->WriteProfileString(_T("Capture\\") + guid
, _T("DisplayName"), CString(codec
.DisplayName
));
124 static void SetupDefaultCaps(AM_MEDIA_TYPE
* pmt
, VIDEO_STREAM_CONFIG_CAPS
& caps
)
126 memset(&caps
, 0, sizeof(caps
));
130 VIDEOINFOHEADER
* vih
= (VIDEOINFOHEADER
*)pmt
->pbFormat
;
132 BITMAPINFOHEADER
* bih
= (pmt
->formattype
== FORMAT_VideoInfo
)
133 ? &((VIDEOINFOHEADER
*)pmt
->pbFormat
)->bmiHeader
134 : (pmt
->formattype
== FORMAT_VideoInfo2
)
135 ? &((VIDEOINFOHEADER2
*)pmt
->pbFormat
)->bmiHeader
138 caps
.guid
= GUID_NULL
;
139 caps
.VideoStandard
= 0;
140 caps
.InputSize
.cx
= bih
->biWidth
;
141 caps
.InputSize
.cy
= abs(bih
->biHeight
);
142 caps
.MinCroppingSize
= caps
.MaxCroppingSize
= caps
.InputSize
;
143 caps
.CropGranularityX
= caps
.CropGranularityY
= 1;
144 caps
.CropAlignX
= caps
.CropAlignY
= 1;
145 caps
.MinOutputSize
= CSize(64, 64);
146 caps
.MaxOutputSize
= CSize(768, 576);
147 caps
.OutputGranularityX
= 16;
148 caps
.OutputGranularityY
= 1;
149 caps
.StretchTapsX
= caps
.StretchTapsY
= 0;
150 caps
.ShrinkTapsX
= caps
.ShrinkTapsY
= 0;
151 caps
.MinFrameInterval
= 100000i64
;
152 caps
.MaxFrameInterval
= 100000000i64
;
153 caps
.MinBitsPerSecond
= caps
.MaxBitsPerSecond
= 0;
156 static void SetupDefaultCaps(AM_MEDIA_TYPE
* pmt
, AUDIO_STREAM_CONFIG_CAPS
& caps
)
158 memset(&caps
, 0, sizeof(caps
));
162 WAVEFORMATEX
* wfe
= (WAVEFORMATEX
*)pmt
->pbFormat
;
164 caps
.guid
= GUID_NULL
;
165 caps
.MinimumChannels
= caps
.MaximumChannels
= wfe
->nChannels
;
166 caps
.ChannelsGranularity
= 1;
167 caps
.MinimumBitsPerSample
= caps
.MaximumBitsPerSample
= wfe
->wBitsPerSample
;
168 caps
.BitsPerSampleGranularity
= 1;
169 caps
.MinimumSampleFrequency
= caps
.MaximumSampleFrequency
= wfe
->nSamplesPerSec
;
170 caps
.SampleFrequencyGranularity
= 1;
174 static void SetupMediaTypes(CComPtr
<IAMStreamConfig
> pAMSC
, CFormatArray
<T
>& tfa
, CComboBox
& type
, CComboBox
& dim
, CMediaType
& mt
)
179 type
.EnableWindow(FALSE
);
180 dim
.EnableWindow(FALSE
);
184 AM_MEDIA_TYPE
* pcurmt
= NULL
;
185 pAMSC
->GetFormat(&pcurmt
);
187 int iCount
= 0, iSize
;
188 if(SUCCEEDED(pAMSC
->GetNumberOfCapabilities(&iCount
, &iSize
))
189 && iSize
== sizeof(T
) && iCount
> 0)
191 for(int i
= 0; i
< iCount
; i
++)
194 AM_MEDIA_TYPE
* pmt
= NULL
;
195 if(SUCCEEDED(pAMSC
->GetStreamCaps(i
, &pmt
, (BYTE
*)&caps
)))
197 tfa
.AddFormat(pmt
, caps
);
201 if(iSize
== sizeof(VIDEO_STREAM_CONFIG_CAPS
))
203 for(int i
= 0, cnt
= tfa
.GetCount(); i
< cnt
; i
++)
205 if(tfa
[i
]->GetCount() != 1) continue;
207 CFormatElem
<T
>* pfe
= tfa
[i
]->GetAt(0);
209 if(pfe
->mt
.formattype
!= FORMAT_VideoInfo
210 && pfe
->mt
.formattype
!= FORMAT_VideoInfo2
)
213 static SIZE presets
[] =
215 {160, 120}, {192, 144},
216 {320, 240}, {384, 288},
217 {480, 240}, {512, 288},
218 {480, 360}, {512, 384},
219 {640, 240}, {768, 288},
220 {640, 480}, {768, 576},
221 {704, 240}, {704, 288},
222 {704, 480}, {704, 576},
223 {720, 240}, {720, 288},
224 {720, 480}, {720, 576},
225 {768, 240}, {768, 288},
226 {768, 480}, {768, 576},
229 VIDEO_STREAM_CONFIG_CAPS
* pcaps
= (VIDEO_STREAM_CONFIG_CAPS
*)&pfe
->caps
;
230 BITMAPINFOHEADER bihCur
;
231 ExtractBIH(&pfe
->mt
, &bihCur
);
233 for(int j
= 0; j
< countof(presets
); j
++)
235 if(presets
[j
].cx
== bihCur
.biWidth
236 && presets
[j
].cy
== abs(bihCur
.biHeight
)
237 || presets
[j
].cx
< pcaps
->MinOutputSize
.cx
238 || presets
[j
].cx
> pcaps
->MaxOutputSize
.cx
239 || presets
[j
].cy
< pcaps
->MinOutputSize
.cy
240 || presets
[j
].cy
> pcaps
->MaxOutputSize
.cy
241 || presets
[j
].cx
% pcaps
->OutputGranularityX
242 || presets
[j
].cy
% pcaps
->OutputGranularityY
)
245 CMediaType mt
= pfe
->mt
;
247 if(mt
.formattype
== FORMAT_VideoInfo
)
249 VIDEOINFOHEADER
* vih
= (VIDEOINFOHEADER
*)mt
.pbFormat
;
250 if(!vih
->bmiHeader
.biHeight
) vih
->bmiHeader
.biHeight
= 1;
251 vih
->bmiHeader
.biWidth
= presets
[j
].cx
;
252 vih
->bmiHeader
.biHeight
= presets
[j
].cy
*(vih
->bmiHeader
.biHeight
/vih
->bmiHeader
.biHeight
);
253 vih
->bmiHeader
.biSizeImage
= presets
[j
].cx
*presets
[j
].cy
*vih
->bmiHeader
.biBitCount
>>3;
255 AM_MEDIA_TYPE
* pmt
= (AM_MEDIA_TYPE
*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
));
256 CopyMediaType(pmt
, &mt
);
257 tfa
.AddFormat(pmt
, pcaps
, sizeof(*pcaps
));
259 if(presets
[j
].cx
*3 != presets
[j
].cy
*4)
261 int extra
= mt
.cbFormat
- sizeof(VIDEOINFOHEADER
);
262 int bmiHeaderSize
= sizeof(vih
->bmiHeader
) + extra
;
263 BYTE
* pbmiHeader
= new BYTE
[bmiHeaderSize
];
264 memcpy(pbmiHeader
, &vih
->bmiHeader
, bmiHeaderSize
);
265 mt
.ReallocFormatBuffer(FIELD_OFFSET(VIDEOINFOHEADER2
, bmiHeader
) + bmiHeaderSize
);
266 VIDEOINFOHEADER2
* vih2
= (VIDEOINFOHEADER2
*)mt
.pbFormat
;
267 memcpy(&vih2
->bmiHeader
, pbmiHeader
, bmiHeaderSize
);
268 delete [] pbmiHeader
;
269 vih2
->dwInterlaceFlags
= vih2
->dwCopyProtectFlags
= 0;
270 vih2
->dwReserved1
= vih2
->dwReserved2
= 0;
271 vih2
->dwPictAspectRatioX
= 4;
272 vih2
->dwPictAspectRatioY
= 3;
274 AM_MEDIA_TYPE
* pmt
= (AM_MEDIA_TYPE
*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
));
275 CopyMediaType(pmt
, &mt
);
276 tfa
.AddFormat(pmt
, pcaps
, sizeof(*pcaps
));
279 else if(mt
.formattype
== FORMAT_VideoInfo2
)
281 VIDEOINFOHEADER2
* vih2
= (VIDEOINFOHEADER2
*)mt
.pbFormat
;
282 if(!vih2
->bmiHeader
.biHeight
) vih2
->bmiHeader
.biHeight
= 1;
283 vih2
->bmiHeader
.biWidth
= presets
[j
].cx
;
284 vih2
->bmiHeader
.biHeight
= presets
[j
].cy
*(vih2
->bmiHeader
.biHeight
/vih2
->bmiHeader
.biHeight
);
285 vih2
->bmiHeader
.biSizeImage
= presets
[j
].cx
*presets
[j
].cy
*vih2
->bmiHeader
.biBitCount
>>3;
286 vih2
->dwPictAspectRatioX
= 4;
287 vih2
->dwPictAspectRatioY
= 3;
289 AM_MEDIA_TYPE
* pmt
= (AM_MEDIA_TYPE
*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
));
290 CopyMediaType(pmt
, &mt
);
291 tfa
.AddFormat(pmt
, pcaps
, sizeof(*pcaps
));
298 if(tfa
.GetCount() == 0)
300 if(pcurmt
&& (pcurmt
->majortype
== MEDIATYPE_Video
|| pcurmt
->majortype
== MEDIATYPE_Audio
))
302 AM_MEDIA_TYPE
* pmt
= (AM_MEDIA_TYPE
*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
));
303 CopyMediaType(pmt
, pcurmt
);
305 SetupDefaultCaps(pmt
, caps
);
306 tfa
.AddFormat(pmt
, caps
);
310 mt
.majortype
= GUID_NULL
;
311 if(pcurmt
) DeleteMediaType(pcurmt
);
316 for(int i
= 0; i
< (int)tfa
.GetCount(); i
++)
318 CFormat
<T
>* pf
= tfa
[i
];
319 int j
= type
.AddString(pf
->name
);
320 type
.SetItemData(j
, (DWORD_PTR
)pf
);
323 CFormat
<T
>* pf
= NULL
;
324 CFormatElem
<T
>* pfe
= NULL
;
331 else if(!tfa
.FindFormat(pcurmt
, NULL
, &pf
, &pfe
) && !tfa
.FindFormat(pcurmt
, &pf
))
333 if(pcurmt
) DeleteMediaType(pcurmt
);
337 for(int i
= 0; i
< (int)pf
->GetCount(); i
++)
339 CFormatElem
<T
>* pfe
= pf
->GetAt(i
);
340 int j
= dim
.AddString(tfa
.MakeDimensionName(pfe
));
341 dim
.SetItemData(j
, (DWORD_PTR
)pfe
);
344 int iType
= type
.SetCurSel(type
.FindStringExact(0, pf
->name
));
345 if(iType
< 0 && type
.GetCount()) type
.SetCurSel(0);
346 int iDim
= dim
.SetCurSel(dim
.FindStringExact(0, tfa
.MakeDimensionName(pfe
)));
347 // if(iDim < 0 && dim.GetCount()) dim.SetCurSel(iDim = 0);
349 CorrectComboListWidth(type
, type
.GetParent()->GetFont());
350 CorrectComboListWidth(dim
, dim
.GetParent()->GetFont());
352 if(iDim
>= 0) mt
= ((CFormatElem
<T
>*)dim
.GetItemData(iDim
))->mt
;
353 else if(pcurmt
) mt
= *pcurmt
;
355 type
.EnableWindow(type
.GetCount() > 0);
356 dim
.EnableWindow(dim
.GetCount() > 0);
358 if(pcurmt
) DeleteMediaType(pcurmt
);
362 static bool SetupDimension(CFormatArray
<T
>& tfa
, CComboBox
& type
, CComboBox
& dim
)
365 dim
.GetWindowText(str
);
368 dim
.EnableWindow(FALSE
);
370 int iSel
= type
.GetCurSel();
371 if(iSel
< 0) return(false);
373 CFormat
<T
>* pf
= (CFormat
<T
>*)type
.GetItemData(iSel
);
375 for(int i
= 0; i
< (int)pf
->GetCount(); i
++)
377 CFormatElem
<T
>* pfe
= pf
->GetAt(i
);
378 dim
.SetItemData(dim
.AddString(tfa
.MakeDimensionName(pfe
)), (DWORD_PTR
)pfe
);
381 CorrectComboListWidth(dim
, dim
.GetParent()->GetFont());
383 dim
.SetCurSel(dim
.FindStringExact(0, str
));
384 dim
.EnableWindow(dim
.GetCount() > 0);
386 return(dim
.GetCurSel() >= 0);
389 static void InitCodecList(CAtlArray
<Codec
>& codecs
, CComboBox
& box
, const GUID
& cat
)
393 box
.EnableWindow(FALSE
);
395 box
.SetItemData(box
.AddString(_T("Uncompressed")), (DWORD_PTR
)-1);
397 BeginEnumSysDev(cat
, pMoniker
)
401 c
.pMoniker
= pMoniker
;
403 CComPtr<IBaseFilter> pBF;
404 if(FAILED(pMoniker->BindToObject(0, 0, IID_IBaseFilter, (void**)&pBF)) || !pBF)
409 LPOLESTR strName
= NULL
;
410 if(FAILED(pMoniker
->GetDisplayName(NULL
, NULL
, &strName
)))
413 c
.DisplayName
= strName
;
414 CoTaskMemFree(strName
);
416 CComPtr
<IPropertyBag
> pPB
;
417 pMoniker
->BindToStorage(0, 0, IID_IPropertyBag
, (void**)&pPB
);
420 if(FAILED(pPB
->Read(CComBSTR(_T("FriendlyName")), &var
, NULL
)))
423 c
.FriendlyName
= var
.bstrVal
;
425 CStringW str
= CStringW(c
.DisplayName
).MakeLower();
426 if(str
.Find(L
"@device:dmo:") == 0)
427 c
.FriendlyName
= _T("(DMO) ") + c
.FriendlyName
;
428 else if(str
.Find(L
"@device:sw:") == 0)
429 c
.FriendlyName
= _T("(DS) ") + c
.FriendlyName
;
430 else if(str
.Find(L
"@device:cm:") == 0)
431 c
.FriendlyName
= _T("(VfW) ") + c
.FriendlyName
;
434 box
.AddString(c
.FriendlyName
),
435 (DWORD_PTR
)codecs
.Add(c
));
439 box
.EnableWindow(box
.GetCount() > 1);
441 CorrectComboListWidth(box
, box
.GetParent()->GetFont());
443 LoadDefaultCodec(codecs
, box
, cat
);
446 static int ShowPPage(CAtlArray
<Codec
>& codecs
, CComboBox
& box
, HWND hWnd
= NULL
)
448 int iSel
= box
.GetCurSel();
449 if(iSel
< 0) return(-1);
451 iSel
= box
.GetItemData(iSel
);
452 if(iSel
< 0) return(-1);
454 Codec
& c
= codecs
[iSel
];
458 c
.pMoniker
->BindToObject(NULL
, NULL
, __uuidof(IBaseFilter
), (void**)&c
.pBF
);
461 if(CComQIPtr
<ISpecifyPropertyPages
> pSPP
= c
.pBF
)
464 caGUID
.pElems
= NULL
;
465 if(SUCCEEDED(pSPP
->GetPages(&caGUID
)))
467 IUnknown
* lpUnk
= NULL
;
468 pSPP
.QueryInterface(&lpUnk
);
469 OleCreatePropertyFrame(
470 hWnd
, 0, 0, CStringW(c
.FriendlyName
),
471 1, (IUnknown
**)&lpUnk
,
472 caGUID
.cElems
, caGUID
.pElems
,
476 if(caGUID
.pElems
) CoTaskMemFree(caGUID
.pElems
);
479 else if(CComQIPtr
<IAMVfwCompressDialogs
> pAMVfWCD
= c
.pBF
)
481 if(pAMVfWCD
->ShowDialog(VfwCompressDialog_QueryConfig
, NULL
) == S_OK
)
482 pAMVfWCD
->ShowDialog(VfwCompressDialog_Config
, hWnd
);
488 // CPlayerCaptureDialog dialog
490 //IMPLEMENT_DYNAMIC(CPlayerCaptureDialog, CResizableDialog)
491 CPlayerCaptureDialog::CPlayerCaptureDialog()
492 : CResizableDialog(CPlayerCaptureDialog::IDD
, NULL
)
497 , m_fVidPreview(FALSE
)
498 , m_fAudPreview(FALSE
)
508 CPlayerCaptureDialog::~CPlayerCaptureDialog()
514 BOOL
CPlayerCaptureDialog::Create(CWnd
* pParent
)
516 if(!__super::Create(IDD
, pParent
))
525 void CPlayerCaptureDialog::DoDataExchange(CDataExchange
* pDX
)
527 __super::DoDataExchange(pDX
);
528 DDX_Control(pDX
, IDC_COMBO4
, m_vidinput
);
529 DDX_Control(pDX
, IDC_COMBO1
, m_vidtype
);
530 DDX_Control(pDX
, IDC_COMBO5
, m_viddimension
);
531 DDX_Control(pDX
, IDC_SPIN1
, m_vidhor
);
532 DDX_Control(pDX
, IDC_SPIN2
, m_vidver
);
533 DDX_Control(pDX
, IDC_EDIT1
, m_vidhoredit
);
534 DDX_Control(pDX
, IDC_EDIT2
, m_vidveredit
);
535 DDX_Control(pDX
, IDC_EDIT3
, m_vidfpsedit
);
536 DDX_Control(pDX
, IDC_BUTTON1
, m_vidsetres
);
537 DDX_Control(pDX
, IDC_COMBO3
, m_audinput
);
538 DDX_Control(pDX
, IDC_COMBO2
, m_audtype
);
539 DDX_Control(pDX
, IDC_COMBO6
, m_auddimension
);
540 DDX_Control(pDX
, IDC_COMBO7
, m_vidcodec
);
541 DDX_Control(pDX
, IDC_COMBO9
, m_vidcodectype
);
542 DDX_Control(pDX
, IDC_COMBO10
, m_vidcodecdimension
);
543 DDX_Check(pDX
, IDC_CHECK1
, m_fVidOutput
);
544 DDX_Control(pDX
, IDC_CHECK1
, m_vidoutput
);
545 DDX_Check(pDX
, IDC_CHECK2
, m_fVidPreview
);
546 DDX_Control(pDX
, IDC_CHECK2
, m_vidpreview
);
547 DDX_Control(pDX
, IDC_COMBO8
, m_audcodec
);
548 DDX_Control(pDX
, IDC_COMBO12
, m_audcodectype
);
549 DDX_Control(pDX
, IDC_COMBO11
, m_audcodecdimension
);
550 DDX_Check(pDX
, IDC_CHECK3
, m_fAudOutput
);
551 DDX_Control(pDX
, IDC_CHECK3
, m_audoutput
);
552 DDX_Check(pDX
, IDC_CHECK4
, m_fAudPreview
);
553 DDX_Control(pDX
, IDC_CHECK4
, m_audpreview
);
554 DDX_Text(pDX
, IDC_EDIT4
, m_file
);
555 DDX_Control(pDX
, IDC_BUTTON2
, m_recordbtn
);
556 DDX_Text(pDX
, IDC_EDIT5
, m_nVidBuffers
);
557 DDX_Text(pDX
, IDC_EDIT6
, m_nAudBuffers
);
558 DDX_Check(pDX
, IDC_CHECK5
, m_fSepAudio
);
559 DDX_CBIndex(pDX
, IDC_COMBO14
, m_muxtype
);
560 DDX_Control(pDX
, IDC_COMBO14
, m_muxctrl
);
563 BOOL
CPlayerCaptureDialog::PreTranslateMessage(MSG
* pMsg
)
565 if(pMsg
->message
== WM_KEYDOWN
)
567 if(pMsg
->wParam
== VK_RETURN
)
569 CWnd
* pFocused
= GetFocus();
570 if(pFocused
&& pFocused
->m_hWnd
== m_vidfpsedit
.m_hWnd
)
577 return __super::PreTranslateMessage(pMsg
);
581 void CPlayerCaptureDialog::EmptyVideo()
583 // first save channel from previous session
585 if(m_pAMTuner
&& !m_VidDisplayName
.IsEmpty())
587 long lChannel
= 0, lVivSub
= 0, lAudSub
= 0;
588 m_pAMTuner
->get_Channel(&lChannel
, &lVivSub
, &lAudSub
);
589 AfxGetApp()->WriteProfileInt(_T("Capture\\") + CString(m_VidDisplayName
), _T("Channel"), lChannel
);
602 m_vidinput
.ResetContent();
603 m_vidinput
.EnableWindow(FALSE
);
604 m_vidtype
.ResetContent();
605 m_vidtype
.EnableWindow(FALSE
);
606 m_viddimension
.ResetContent();
607 m_viddimension
.EnableWindow(FALSE
);
608 m_vidhor
.EnableWindow(FALSE
);
609 m_vidver
.EnableWindow(FALSE
);
610 m_vidhoredit
.EnableWindow(FALSE
);
611 m_vidveredit
.EnableWindow(FALSE
);
612 m_vidfpsedit
.EnableWindow(FALSE
);
614 m_vidsetres
.EnableWindow(FALSE
);
619 void CPlayerCaptureDialog::EmptyAudio()
624 m_pAMAIM
.RemoveAll();
628 m_audinput
.ResetContent();
629 m_audinput
.EnableWindow(FALSE
);
630 m_audtype
.ResetContent();
631 m_audtype
.EnableWindow(FALSE
);
632 m_auddimension
.ResetContent();
633 m_auddimension
.EnableWindow(FALSE
);
638 void CPlayerCaptureDialog::UpdateMediaTypes()
645 m_vidfpsedit
.GetWindowText(fps
);
649 _stscanf(fps
, _T("%f"), &ffps
);
650 if(ffps
> 0) m_vidfps
= ffps
;
656 AM_MEDIA_TYPE
* pmt
= NULL
;
657 VIDEO_STREAM_CONFIG_CAPS
* pcaps
= NULL
;
659 int i
= m_viddimension
.GetCurSel();
662 pmt
= (AM_MEDIA_TYPE
*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
));
663 CopyMediaType(pmt
, &((CVidFormatElem
*)m_viddimension
.GetItemData(i
))->mt
);
664 pcaps
= &((CVidFormatElem
*)m_viddimension
.GetItemData(i
))->caps
;
668 m_pAMVSC
->GetFormat(&pmt
);
675 REFERENCE_TIME atpf
= (REFERENCE_TIME
)(10000000.0 / m_vidfps
);
679 // FIXME: some drivers do not set the interval right and they still accept the preferable but unfortunately out-of-range fps
680 // atpf = min(max(atpf, pcaps->MinFrameInterval), pcaps->MaxFrameInterval);
683 if(pmt
->formattype
== FORMAT_VideoInfo
)
684 ((VIDEOINFOHEADER
*)pmt
->pbFormat
)->AvgTimePerFrame
= atpf
;
685 else if(pmt
->formattype
== FORMAT_VideoInfo2
)
686 ((VIDEOINFOHEADER2
*)pmt
->pbFormat
)->AvgTimePerFrame
= atpf
;
689 BITMAPINFOHEADER
* bih
= (pmt
->formattype
== FORMAT_VideoInfo
)
690 ? &((VIDEOINFOHEADER
*)pmt
->pbFormat
)->bmiHeader
691 : (pmt
->formattype
== FORMAT_VideoInfo2
)
692 ? &((VIDEOINFOHEADER2
*)pmt
->pbFormat
)->bmiHeader
695 bih
->biWidth
= m_vidhor
.GetPos();
696 bih
->biHeight
= m_vidver
.GetPos();
697 bih
->biSizeImage
= bih
->biWidth
*bih
->biHeight
*bih
->biBitCount
>>3;
699 SaveMediaType(m_VidDisplayName
, pmt
);
702 DeleteMediaType(pmt
);
709 AM_MEDIA_TYPE
* pmt
= NULL
;
711 int i
= m_auddimension
.GetCurSel();
714 pmt
= (AM_MEDIA_TYPE
*)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE
));
715 CopyMediaType(pmt
, &((CAudFormatElem
*)m_auddimension
.GetItemData(i
))->mt
);
719 m_pAMASC
->GetFormat(&pmt
);
724 SaveMediaType(m_AudDisplayName
, pmt
);
727 DeleteMediaType(pmt
);
732 void CPlayerCaptureDialog::UpdateUserDefinableControls()
734 int iSel
= m_viddimension
.GetCurSel();
737 CVidFormatElem
* pvfe
= (CVidFormatElem
*)m_viddimension
.GetItemData(iSel
);
740 if(!m_pAMVSC
) return;
742 AM_MEDIA_TYPE
* pmt
= NULL
;
743 m_pAMVSC
->GetFormat(&pmt
);
746 BITMAPINFOHEADER
* bih
= (pmt
->formattype
== FORMAT_VideoInfo
)
747 ? &((VIDEOINFOHEADER
*)pmt
->pbFormat
)->bmiHeader
748 : (pmt
->formattype
== FORMAT_VideoInfo2
)
749 ? &((VIDEOINFOHEADER2
*)pmt
->pbFormat
)->bmiHeader
754 UDACCEL ua
[3] = {{0,0},{2,0},{4,0}};
756 int w
= m_vidhor
.GetPos(), h
= m_vidver
.GetPos();
758 m_vidhor
.SetRange((short)pvfe
->caps
.MinOutputSize
.cx
, (short)pvfe
->caps
.MaxOutputSize
.cx
);
759 /* 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
760 pvfe->caps.OutputGranularityX = 64;
762 ua
[0].nInc
= pvfe
->caps
.OutputGranularityX
;
763 ua
[1].nInc
= pvfe
->caps
.OutputGranularityX
*2;
764 ua
[2].nInc
= pvfe
->caps
.OutputGranularityX
*4;
765 m_vidhor
.SetAccel(3, ua
);
767 m_vidver
.SetRange((short)pvfe
->caps
.MinOutputSize
.cy
, (short)pvfe
->caps
.MaxOutputSize
.cy
);
768 ua
[0].nInc
= pvfe
->caps
.OutputGranularityY
;
769 ua
[1].nInc
= pvfe
->caps
.OutputGranularityY
*2;
770 ua
[2].nInc
= pvfe
->caps
.OutputGranularityY
*4;
771 m_vidver
.SetAccel(3, ua
);
773 m_vidhor
.SetPos(bih
->biWidth
);
774 m_vidver
.SetPos(abs(bih
->biHeight
));
777 fps
.Format(_T("%.4f"), (float)(10000000.0 / ((VIDEOINFOHEADER
*)pmt
->pbFormat
)->AvgTimePerFrame
));
778 m_vidfpsedit
.SetWindowText(fps
);
780 DeleteMediaType(pmt
);
783 void CPlayerCaptureDialog::UpdateVideoCodec()
785 int iSel
= m_vidcodec
.GetCurSel();
786 if(iSel
>= 0) iSel
= m_vidcodec
.GetItemData(iSel
);
788 m_pVidEnc
= iSel
< 0 ? NULL
: m_pVidEncArray
[iSel
].pBF
;
789 m_pVidEncMoniker
= iSel
< 0 ? NULL
: m_pVidEncArray
[iSel
].pMoniker
;
791 // CString DisplayName = iSel < 0 ? _T("") : CString(m_pVidEncArray[iSel].DisplayName.m_str);
792 CComQIPtr
<IAMStreamConfig
> pAMSC
= GetFirstPin(m_pVidEnc
, PINDIR_OUTPUT
);
794 SetupMediaTypes(pAMSC
, m_vcfa
, m_vidcodectype
, m_vidcodecdimension
, m_mtcv
);
796 SaveDefaultCodec(m_pVidEncArray
, m_vidcodec
, CLSID_VideoCompressorCategory
);
798 // SaveMediaType(DisplayName, &m_mtcv);
801 void CPlayerCaptureDialog::UpdateAudioCodec()
803 int iSel
= m_audcodec
.GetCurSel();
804 if(iSel
>= 0) iSel
= m_audcodec
.GetItemData(iSel
);
806 m_pAudEnc
= iSel
< 0 ? NULL
: m_pAudEncArray
[iSel
].pBF
;
807 m_pAudEncMoniker
= iSel
< 0 ? NULL
: m_pAudEncArray
[iSel
].pMoniker
;
809 // CString DisplayName = iSel < 0 ? _T("") : CString(m_pAudEncArray[iSel].DisplayName.m_str);
810 CComQIPtr
<IAMStreamConfig
> pAMSC
= GetFirstPin(m_pAudEnc
, PINDIR_OUTPUT
);
812 SetupMediaTypes(pAMSC
, m_acfa
, m_audcodectype
, m_audcodecdimension
, m_mtca
);
814 SaveDefaultCodec(m_pAudEncArray
, m_audcodec
, CLSID_AudioCompressorCategory
);
816 // SaveMediaType(DisplayName, &m_mtca);
819 void CPlayerCaptureDialog::UpdateMuxer()
828 if(m_muxtype
== 0) m_pMux
.CoCreateInstance(CLSID_AviDest
);
829 else if(m_muxtype
== 1) m_pMux
.CoCreateInstance(CLSID_OggMux
);
830 else if(m_muxtype
== 2) m_pMux
= new CMatroskaMuxerFilter(NULL
, &hr
);
831 else if(m_muxtype
== 3) m_pMux
= new CDSMMuxerFilter(NULL
, &hr
);
834 if(m_fSepAudio
) m_pAudMux
= new CWavDestFilter(NULL
, &hr
);
837 void CPlayerCaptureDialog::UpdateOutputControls()
841 m_recordbtn
.EnableWindow(!m_file
.IsEmpty() && (m_pAMVSC
&& m_fVidOutput
|| m_pAMASC
&& m_fAudOutput
));
842 m_vidcodec
.EnableWindow(TRUE
);
843 m_audcodec
.EnableWindow(TRUE
);
846 void CPlayerCaptureDialog::UpdateGraph()
852 ((CMainFrame
*)AfxGetMainWnd())->BuildGraphVideoAudio(m_fVidPreview
, false, m_fAudPreview
, false);
854 UpdateUserDefinableControls();
857 void CPlayerCaptureDialog::EnableControls(CWnd
* pWnd
, bool fEnable
)
861 for(CWnd
* pChild
= pWnd
->GetWindow(GW_CHILD
); pChild
; pChild
= pChild
->GetNextWindow())
864 if(m_wndenabledmap
.Lookup(pChild
->m_hWnd
, fEnabled
))
865 pChild
->EnableWindow(fEnabled
);
866 EnableControls(pChild
, fEnable
);
869 if(pWnd
->m_hWnd
== m_hWnd
)
870 m_wndenabledmap
.RemoveAll();
872 m_recordbtn
.SetWindowText(_T("Record"));
876 if(pWnd
->m_hWnd
== m_hWnd
)
877 m_wndenabledmap
.RemoveAll();
879 for(CWnd
* pChild
= pWnd
->GetWindow(GW_CHILD
); pChild
; pChild
= pChild
->GetNextWindow())
881 m_wndenabledmap
[pChild
->m_hWnd
] = pChild
->IsWindowEnabled();
882 pChild
->EnableWindow(FALSE
);
883 EnableControls(pChild
, fEnable
);
886 m_recordbtn
.EnableWindow(TRUE
);
887 m_recordbtn
.SetWindowText(_T("Stop"));
891 void CPlayerCaptureDialog::SetupVideoControls(
892 CStringW DisplayName
,
893 CComPtr
<IAMStreamConfig
> pAMSC
, CComPtr
<IAMCrossbar
> pAMXB
, CComPtr
<IAMTVTuner
> pAMTuner
)
901 long OutputPinCount
, InputPinCount
;
902 if(SUCCEEDED(pAMXB
->get_PinCounts(&OutputPinCount
, &InputPinCount
)))
904 for(int i
= 0; i
< InputPinCount
; i
++)
906 long PinIndexRelated
, PhysicalType
;
907 if(FAILED(pAMXB
->get_CrossbarPinInfo(TRUE
, i
, &PinIndexRelated
, &PhysicalType
)))
910 if(PhysicalType
>= PhysConn_Audio_Tuner
)
916 case PhysConn_Video_Tuner
: str
= _T("Tuner"); break;
917 case PhysConn_Video_Composite
: str
= _T("Composite"); break;
918 case PhysConn_Video_SVideo
: str
= _T("SVideo"); break;
919 case PhysConn_Video_RGB
: str
= _T("RGB"); break;
920 case PhysConn_Video_YRYBY
: str
= _T("YRYBY"); break;
921 case PhysConn_Video_SerialDigital
: str
= _T("SerialDigital"); break;
922 case PhysConn_Video_ParallelDigital
: str
= _T("ParallelDigital"); break;
923 case PhysConn_Video_SCSI
: str
= _T("SCSI"); break;
924 case PhysConn_Video_AUX
: str
= _T("AUX"); break;
925 case PhysConn_Video_1394
: str
= _T("1394"); break;
926 case PhysConn_Video_USB
: str
= _T("USB"); break;
927 case PhysConn_Video_VideoDecoder
: str
= _T("VideoDecoder"); break;
928 case PhysConn_Video_VideoEncoder
: str
= _T("VideoEncoder"); break;
929 case PhysConn_Video_SCART
: str
= _T("SCART"); break;
930 default: str
.Format(_T("PhysicalType %d"), PhysicalType
); break;
933 m_vidinput
.SetItemData(m_vidinput
.AddString(str
), i
);
938 if(m_vidinput
.GetCount() > 0)
940 m_vidinput
.EnableWindow(TRUE
);
942 long OutputPinCount
, InputPinCount
;
943 if(SUCCEEDED(pAMXB
->get_PinCounts(&OutputPinCount
, &InputPinCount
)))
945 for(int i
= 0; i
< OutputPinCount
; i
++)
948 if(S_OK
== pAMXB
->get_IsRoutedTo(i
, &InputPinIndex
))
950 for(int j
= 0; j
< m_vidinput
.GetCount(); j
++)
952 if(m_vidinput
.GetItemData(j
) == InputPinIndex
)
954 m_vidinput
.SetCurSel(j
);
968 if(m_pAMTuner
= pAMTuner
)
977 m_VidDisplayName
= DisplayName
;
980 if(LoadMediaType(DisplayName
, &pmt
))
982 pAMSC
->SetFormat(pmt
);
983 DeleteMediaType(pmt
);
986 SetupMediaTypes(pAMSC
, m_vfa
, m_vidtype
, m_viddimension
, m_mtv
);
989 if(m_vidtype
.GetCount() > 0)
991 m_vidfpsedit
.EnableWindow(TRUE
);
992 m_vidhor
.EnableWindow(TRUE
);
993 m_vidver
.EnableWindow(TRUE
);
994 m_vidhoredit
.EnableWindow(TRUE
);
995 m_vidveredit
.EnableWindow(TRUE
);
996 m_vidsetres
.EnableWindow(TRUE
);
1000 m_vidoutput
.EnableWindow(TRUE
);
1001 m_vidpreview
.EnableWindow(TRUE
);
1006 UpdateUserDefinableControls();
1008 UpdateOutputControls();
1011 void CPlayerCaptureDialog::SetupVideoControls(
1012 CStringW DisplayName
,
1013 CComPtr
<IAMStreamConfig
> pAMSC
, CComPtr
<IAMVfwCaptureDialogs
> pAMVfwCD
)
1017 if(m_pAMVfwCD
= pAMVfwCD
)
1019 if(S_OK
== m_pAMVfwCD
->HasDialog(VfwCaptureDialog_Source
))
1020 m_vidinput
.SetItemData(m_vidinput
.AddString(_T("Source")), (DWORD_PTR
)VfwCaptureDialog_Source
);
1021 if(S_OK
== m_pAMVfwCD
->HasDialog(VfwCaptureDialog_Format
))
1022 m_vidinput
.SetItemData(m_vidinput
.AddString(_T("Format")), (DWORD_PTR
)VfwCaptureDialog_Format
);
1023 if(S_OK
== m_pAMVfwCD
->HasDialog(VfwCaptureDialog_Display
))
1024 m_vidinput
.SetItemData(m_vidinput
.AddString(_T("Display")), (DWORD_PTR
)VfwCaptureDialog_Display
);
1026 if(m_vidinput
.GetCount() > 0)
1028 m_vidinput
.EnableWindow(TRUE
);
1029 m_vidinput
.SetCurSel(0);
1035 if(m_pAMVSC
= pAMSC
)
1037 m_VidDisplayName
= DisplayName
;
1040 if(LoadMediaType(DisplayName
, &pmt
))
1042 pAMSC
->SetFormat(pmt
);
1043 DeleteMediaType(pmt
);
1046 SetupMediaTypes(pAMSC
, m_vfa
, m_vidtype
, m_viddimension
, m_mtv
);
1049 if(m_vidtype
.GetCount() > 0)
1051 m_vidfpsedit
.EnableWindow(TRUE
);
1052 m_vidhor
.EnableWindow(TRUE
);
1053 m_vidver
.EnableWindow(TRUE
);
1054 m_vidhoredit
.EnableWindow(TRUE
);
1055 m_vidveredit
.EnableWindow(TRUE
);
1056 m_vidsetres
.EnableWindow(TRUE
);
1060 m_vidoutput
.EnableWindow(TRUE
);
1061 m_vidpreview
.EnableWindow(TRUE
);
1066 UpdateUserDefinableControls();
1068 UpdateOutputControls();
1071 void CPlayerCaptureDialog::SetupAudioControls(
1072 CStringW DisplayName
,
1073 CComPtr
<IAMStreamConfig
> pAMSC
, CInterfaceArray
<IAMAudioInputMixer
>& pAMAIM
)
1079 if(pAMAIM
.GetCount() > 0)
1081 m_pAMAIM
.Copy(pAMAIM
);
1085 for(int i
= 0; i
< (int)m_pAMAIM
.GetCount(); i
++)
1087 CComQIPtr
<IPin
> pPin
= m_pAMAIM
[i
];
1088 m_audinput
.SetItemData(m_audinput
.AddString(CString(GetPinName(pPin
))), (DWORD_PTR
)i
);
1091 if(SUCCEEDED(m_pAMAIM
[i
]->get_Enable(&fEnable
)) && fEnable
)
1095 if(m_audinput
.GetCount() > 0)
1097 for(int i
= 0; i
< m_audinput
.GetCount(); i
++)
1099 if(m_audinput
.GetItemData(i
) == iSel
)
1101 m_audinput
.SetCurSel(i
);
1106 m_audinput
.EnableWindow(TRUE
);
1112 if(m_pAMASC
= pAMSC
)
1114 m_AudDisplayName
= DisplayName
;
1117 if(LoadMediaType(DisplayName
, &pmt
))
1119 pAMSC
->SetFormat(pmt
);
1120 DeleteMediaType(pmt
);
1123 SetupMediaTypes(pAMSC
, m_afa
, m_audtype
, m_auddimension
, m_mta
);
1126 // if(m_audtype.GetCount() > 0)
1128 m_audoutput
.EnableWindow(TRUE
);
1129 m_audpreview
.EnableWindow(TRUE
);
1134 UpdateUserDefinableControls();
1136 UpdateOutputControls();
1139 bool CPlayerCaptureDialog::IsTunerActive()
1141 int iSel
= m_vidinput
.GetCurSel();
1142 if(iSel
< 0) return(false);
1143 iSel
= m_vidinput
.GetItemData(iSel
);
1144 if(iSel
< 0) return(false);
1146 long PinIndexRelated
, PhysicalType
;
1148 && SUCCEEDED(m_pAMXB
->get_CrossbarPinInfo(TRUE
, iSel
, &PinIndexRelated
, &PhysicalType
))
1149 && PhysicalType
== PhysConn_Video_Tuner
);
1152 bool CPlayerCaptureDialog::SetVideoInput(int input
)
1154 if(!m_pAMXB
|| input
< 0) return false;
1156 for(int i
= 0; i
< m_vidinput
.GetCount(); i
++)
1158 if(m_vidinput
.GetItemData(i
) == input
)
1160 m_vidinput
.SetCurSel(i
);
1169 bool CPlayerCaptureDialog::SetVideoChannel(int channel
)
1171 if(!m_pAMTuner
|| channel
< 0) return false;
1173 return SUCCEEDED(m_pAMTuner
->put_Channel(channel
, AMTUNER_SUBCHAN_DEFAULT
, AMTUNER_SUBCHAN_DEFAULT
));
1176 bool CPlayerCaptureDialog::SetAudioInput(int input
)
1178 if(input
< 0) return false;
1180 for(int i
= 0; i
< m_audinput
.GetCount(); i
++)
1182 if(m_audinput
.GetItemData(i
) == input
)
1184 m_audinput
.SetCurSel(i
);
1193 int CPlayerCaptureDialog::GetVideoInput()
1195 int i
= m_vidinput
.GetCurSel();
1196 if(i
< 0) return -1;
1197 return m_vidinput
.GetItemData(i
);
1200 int CPlayerCaptureDialog::GetVideoChannel()
1202 long lChannel
, lVivSub
, lAudSub
;
1203 return m_pAMTuner
&& SUCCEEDED(m_pAMTuner
->get_Channel(&lChannel
, &lVivSub
, &lAudSub
)) ? lChannel
: -1;
1206 int CPlayerCaptureDialog::GetAudioInput()
1208 int i
= m_audinput
.GetCurSel();
1209 if(i
< 0) return -1;
1210 return m_audinput
.GetItemData(i
);
1213 BEGIN_MESSAGE_MAP(CPlayerCaptureDialog
, CResizableDialog
)
1215 ON_CBN_SELCHANGE(IDC_COMBO4
, OnVideoInput
)
1216 ON_CBN_SELCHANGE(IDC_COMBO1
, OnVideoType
)
1217 ON_CBN_SELCHANGE(IDC_COMBO5
, OnVideoDimension
)
1218 ON_BN_CLICKED(IDC_BUTTON1
, OnOverrideVideoDimension
)
1219 ON_CBN_SELCHANGE(IDC_COMBO3
, OnAudioInput
)
1220 ON_CBN_SELCHANGE(IDC_COMBO2
, OnAudioType
)
1221 ON_CBN_SELCHANGE(IDC_COMBO6
, OnAudioDimension
)
1222 ON_BN_CLICKED(IDC_CHECK1
, OnRecordVideo
)
1223 ON_CBN_SELCHANGE(IDC_COMBO7
, OnVideoCodec
)
1224 ON_CBN_SELCHANGE(IDC_COMBO9
, OnVideoCodecType
)
1225 ON_CBN_SELCHANGE(IDC_COMBO10
, OnVideoCodecDimension
)
1226 ON_BN_CLICKED(IDC_CHECK3
, OnRecordAudio
)
1227 ON_CBN_SELCHANGE(IDC_COMBO8
, OnAudioCodec
)
1228 ON_CBN_SELCHANGE(IDC_COMBO12
, OnAudioCodecType
)
1229 ON_CBN_SELCHANGE(IDC_COMBO11
, OnAudioCodecDimension
)
1230 ON_BN_CLICKED(IDC_BUTTON3
, OnOpenFile
)
1231 ON_BN_CLICKED(IDC_BUTTON2
, OnRecord
)
1232 ON_EN_CHANGE(IDC_EDIT5
, OnEnChangeEdit9
)
1233 ON_EN_CHANGE(IDC_EDIT6
, OnEnChangeEdit12
)
1235 ON_BN_CLICKED(IDC_CHECK2
, OnBnClickedVidAudPreview
)
1236 ON_BN_CLICKED(IDC_CHECK4
, OnBnClickedVidAudPreview
)
1237 ON_BN_CLICKED(IDC_CHECK5
, OnBnClickedCheck7
)
1238 ON_CBN_SELCHANGE(IDC_COMBO14
, OnCbnSelchangeCombo14
)
1242 // CPlayerCaptureDialog message handlers
1244 BOOL
CPlayerCaptureDialog::OnInitDialog()
1246 __super::OnInitDialog();
1248 InitCodecList(m_pVidEncArray
, m_vidcodec
, CLSID_VideoCompressorCategory
);
1251 InitCodecList(m_pAudEncArray
, m_audcodec
, CLSID_AudioCompressorCategory
);
1254 m_fEnableOgm
= IsCLSIDRegistered(_T("{8cae96b7-85b1-4605-b23c-17ff5262b296}"));
1256 m_nVidBuffers
= AfxGetApp()->GetProfileInt(_T("Capture"), _T("VidBuffers"), 50);
1257 m_nAudBuffers
= AfxGetApp()->GetProfileInt(_T("Capture"), _T("AudBuffers"), 50);
1258 m_fVidOutput
= !!AfxGetApp()->GetProfileInt(_T("Capture"), _T("VidOutput"), TRUE
);
1259 m_fAudOutput
= !!AfxGetApp()->GetProfileInt(_T("Capture"), _T("AudOutput"), TRUE
);
1260 m_fVidPreview
= AfxGetApp()->GetProfileInt(_T("Capture"), _T("VidPreview"), TRUE
);
1261 m_fAudPreview
= AfxGetApp()->GetProfileInt(_T("Capture"), _T("AudPreview"), TRUE
);
1262 m_muxtype
= AfxGetApp()->GetProfileInt(_T("Capture"), _T("FileFormat"), 0);
1263 m_file
= AfxGetApp()->GetProfileString(_T("Capture"), _T("FileName"), _T(""));
1264 m_fSepAudio
= AfxGetApp()->GetProfileInt(_T("Capture"), _T("SepAudio"), TRUE
);
1266 m_muxctrl
.AddString(_T("AVI"));
1267 m_muxctrl
.AddString(_T("Ogg Media"));
1268 m_muxctrl
.AddString(_T("Matroska"));
1269 m_muxctrl
.AddString(_T("DirectShow Media"));
1275 OnCbnSelchangeCombo14();
1277 return TRUE
; // return TRUE unless you set the focus to a control
1278 // EXCEPTION: OCX Property Pages should return FALSE
1281 void CPlayerCaptureDialog::OnDestroy()
1285 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("VidOutput"), m_fVidOutput
);
1286 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("AudOutput"), m_fAudOutput
);
1287 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("VidPreview"), m_fVidPreview
);
1288 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("AudPreview"), m_fAudPreview
);
1289 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("FileFormat"), m_muxtype
);
1290 AfxGetApp()->WriteProfileString(_T("Capture"), _T("FileName"), m_file
);
1291 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("SepAudio"), m_fSepAudio
);
1293 __super::OnDestroy();
1296 void CPlayerCaptureDialog::OnVideoInput()
1298 int iSel
= m_vidinput
.GetCurSel();
1299 if(iSel
< 0) return;
1300 iSel
= m_vidinput
.GetItemData(iSel
);
1301 if(iSel
< 0) return;
1305 long PinIndexRelated
, PhysicalType
;
1306 if(FAILED(m_pAMXB
->get_CrossbarPinInfo(TRUE
, iSel
, &PinIndexRelated
, &PhysicalType
)))
1309 long OutputPinCount
, InputPinCount
;
1310 if(FAILED(m_pAMXB
->get_PinCounts(&OutputPinCount
, &InputPinCount
)))
1313 for(int i
= 0; i
< OutputPinCount
; i
++)
1315 if(S_OK
== m_pAMXB
->CanRoute(i
, iSel
))
1317 m_pAMXB
->Route(i
, iSel
);
1322 if(PinIndexRelated
>= 0)
1324 for(int i
= 0; i
< OutputPinCount
; i
++)
1326 if(S_OK
== m_pAMXB
->CanRoute(i
, PinIndexRelated
))
1328 m_pAMXB
->Route(i
, PinIndexRelated
);
1336 if(S_OK
== m_pAMVfwCD
->HasDialog(iSel
))
1338 HRESULT hr
= m_pAMVfwCD
->ShowDialog(iSel
, m_hWnd
);
1340 if(VFW_E_NOT_STOPPED
== hr
)
1342 ((CMainFrame
*)AfxGetMainWnd())->SendMessage(WM_COMMAND
, ID_PLAY_STOP
);
1343 hr
= m_pAMVfwCD
->ShowDialog(iSel
, m_hWnd
);
1344 ((CMainFrame
*)AfxGetMainWnd())->SendMessage(WM_COMMAND
, ID_PLAY_PLAY
);
1347 if(VFW_E_CANNOT_CONNECT
== hr
)
1353 void CPlayerCaptureDialog::OnVideoType()
1355 if(SetupDimension(m_vfa
, m_vidtype
, m_viddimension
))
1359 void CPlayerCaptureDialog::OnVideoDimension()
1361 int iSel
= m_viddimension
.GetCurSel();
1362 if(iSel
< 0) return;
1364 CVidFormatElem
* pvfe
= (CVidFormatElem
*)m_viddimension
.GetItemData(iSel
);
1367 BITMAPINFOHEADER
* bih
= (pvfe
->mt
.formattype
== FORMAT_VideoInfo
)
1368 ? &((VIDEOINFOHEADER
*)pvfe
->mt
.pbFormat
)->bmiHeader
1369 : (pvfe
->mt
.formattype
== FORMAT_VideoInfo2
)
1370 ? &((VIDEOINFOHEADER2
*)pvfe
->mt
.pbFormat
)->bmiHeader
1373 m_vidhor
.SetRange(0, 32767);
1374 m_vidver
.SetRange(0, 32767);
1375 m_vidhor
.SetPos(bih
->biWidth
);
1376 m_vidver
.SetPos(abs(bih
->biHeight
));
1378 fps
.Format(_T("%.4f"), (float)(10000000.0 / ((VIDEOINFOHEADER
*)pvfe
->mt
.pbFormat
)->AvgTimePerFrame
));
1379 m_vidfpsedit
.SetWindowText(fps
);
1384 void CPlayerCaptureDialog::OnOverrideVideoDimension()
1389 void CPlayerCaptureDialog::OnAudioInput()
1391 int iSel
= m_audinput
.GetCurSel();
1393 for(int i
= 0; i
< (int)m_pAMAIM
.GetCount(); i
++)
1395 m_pAMAIM
[m_audinput
.GetItemData(i
)]->put_Enable(i
== iSel
? TRUE
: FALSE
);
1399 void CPlayerCaptureDialog::OnAudioType()
1401 if(SetupDimension(m_afa
, m_audtype
, m_auddimension
))
1405 void CPlayerCaptureDialog::OnAudioDimension()
1410 void CPlayerCaptureDialog::OnRecordVideo()
1412 UpdateOutputControls();
1415 void CPlayerCaptureDialog::OnVideoCodec()
1417 ShowPPage(m_pVidEncArray
, m_vidcodec
, m_hWnd
);
1421 void CPlayerCaptureDialog::OnVideoCodecType()
1423 if(SetupDimension(m_vcfa
, m_vidcodectype
, m_vidcodecdimension
))
1424 OnVideoCodecDimension();
1427 void CPlayerCaptureDialog::OnVideoCodecDimension()
1429 int i
= m_vidcodecdimension
.GetCurSel();
1432 m_mtcv
= ((CVidFormatElem
*)m_vidcodecdimension
.GetItemData(i
))->mt
;
1434 // we have to recreate the encoder, otherwise it will accept the new media type for only the first time
1436 m_pVidEncMoniker
->BindToObject(0, 0, IID_IBaseFilter
, (void**)&m_pVidEnc
);
1440 void CPlayerCaptureDialog::OnRecordAudio()
1442 UpdateOutputControls();
1445 void CPlayerCaptureDialog::OnAudioCodec()
1447 ShowPPage(m_pAudEncArray
, m_audcodec
, m_hWnd
);
1451 void CPlayerCaptureDialog::OnAudioCodecType()
1453 if(SetupDimension(m_acfa
, m_audcodectype
, m_audcodecdimension
))
1454 OnAudioCodecDimension();
1457 void CPlayerCaptureDialog::OnAudioCodecDimension()
1459 int i
= m_audcodecdimension
.GetCurSel();
1462 m_mtca
= ((CAudFormatElem
*)m_audcodecdimension
.GetItemData(i
))->mt
;
1464 // we have to recreate the encoder, otherwise it will accept the new media type for only the first time
1466 m_pAudEncMoniker
->BindToObject(0, 0, IID_IBaseFilter
, (void**)&m_pAudEnc
);
1469 CString(m_pAudEncArray[m_audcodec.GetItemData(m_audcodec.GetCurSel())].DisplayName.m_str),
1474 void CPlayerCaptureDialog::OnOpenFile()
1476 CFileDialog
fd(FALSE
, NULL
, NULL
,
1477 OFN_EXPLORER
|OFN_ENABLESIZING
|OFN_HIDEREADONLY
|OFN_OVERWRITEPROMPT
,
1478 _T("Media files (*.avi,*.ogm,*.mkv,*.dsm)|*.avi;*.ogm;*.mkv;*.dsm|"), this, 0);
1480 if(fd
.DoModal() == IDOK
)
1482 CString str
= fd
.GetPathName();
1484 CString ext
= str
.Mid(str
.ReverseFind('.')+1).MakeLower();
1485 if(ext
== _T("avi")) m_muxtype
= 0;
1486 else if(ext
== _T("ogm")) m_muxtype
= 1;
1487 else if(ext
== _T("mkv")) m_muxtype
= 2;
1488 else if(ext
== _T("dsm")) m_muxtype
= 3;
1491 if(m_muxtype
== 0) str
+= _T(".avi");
1492 else if(m_muxtype
== 1) str
+= _T(".ogm");
1493 else if(m_muxtype
== 2) str
+= _T(".mkv");
1494 else if(m_muxtype
== 3) str
+= _T(".dsm");
1502 UpdateOutputControls();
1505 void CPlayerCaptureDialog::OnRecord()
1509 CMainFrame
* pFrame
= (CMainFrame
*)AfxGetMainWnd();
1512 if(!pFrame
->m_fCapturing
)
1516 CComQIPtr
<IFileSinkFilter2
> pFSF
= m_pMux
;
1524 m_pDst
.CoCreateInstance(CLSID_FileWriter
);
1529 || FAILED(pFSF
->SetFileName(CStringW(m_file
), NULL
))
1530 || FAILED(pFSF
->SetMode(AM_FILE_OVERWRITE
)))
1532 AfxMessageBox(_T("Error initializing the output file"));
1536 CString audfn
= m_file
.Left(m_file
.ReverseFind('.')+1);
1537 if(m_fSepAudio
&& m_fAudOutput
&& m_pAudMux
&& !audfn
.IsEmpty())
1541 CComQIPtr
<IFileSinkFilter2
> pFSF
= m_pAudMux
;
1544 m_pAudDst
= m_pAudMux
;
1549 m_pAudDst
.CoCreateInstance(CLSID_FileWriter
);
1554 || FAILED(pFSF
->SetFileName(CStringW(audfn
), NULL
))
1555 || FAILED(pFSF
->SetMode(AM_FILE_OVERWRITE
)))
1557 AfxMessageBox(_T("Error initializing the audio output file"));
1562 m_pVidBuffer
= m_fVidOutput
&& m_nVidBuffers
> 0 && m_muxtype
!= 2 && m_muxtype
!= 3 ? new CBufferFilter(NULL
, NULL
) : NULL
;
1563 if(CComQIPtr
<IBufferFilter
> pVB
= m_pVidBuffer
)
1564 {pVB
->SetBuffers(m_nVidBuffers
); pVB
->SetPriority(THREAD_PRIORITY_NORMAL
);}
1566 m_pAudBuffer
= m_fAudOutput
&& m_nAudBuffers
> 0 && m_muxtype
!= 2 && m_muxtype
!= 3 ? new CBufferFilter(NULL
, NULL
) : NULL
;
1567 if(CComQIPtr
<IBufferFilter
> pAB
= m_pAudBuffer
)
1568 {pAB
->SetBuffers(m_nAudBuffers
); pAB
->SetPriority(THREAD_PRIORITY_ABOVE_NORMAL
);}
1570 EnableControls(this, false);
1572 pFrame
->StartCapture();
1574 SetTimer(1, 100, NULL
);
1580 pFrame
->StopCapture();
1583 if(FILE* f = _tfopen(m_file, _T("rb+")))
1585 fseek(f, 0x20, SEEK_SET);
1586 unsigned short mspf = (unsigned short)(((VIDEOINFOHEADER*)m_mtv.pbFormat)->AvgTimePerFrame / 10);
1587 fwrite(&mspf, 1, 2, f);
1592 EnableControls(this, true);
1594 m_pVidBuffer
= NULL
;
1595 m_pAudBuffer
= NULL
;
1599 void CPlayerCaptureDialog::OnEnChangeEdit9()
1602 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("VidBuffers"), max(m_nVidBuffers
, 0));
1605 void CPlayerCaptureDialog::OnEnChangeEdit12()
1608 AfxGetApp()->WriteProfileInt(_T("Capture"), _T("AudBuffers"), max(m_nAudBuffers
, 0));
1611 void CPlayerCaptureDialog::OnTimer(UINT nIDEvent
)
1615 if(((CMainFrame
*)AfxGetMainWnd())->m_fCapturing
)
1617 ULARGE_INTEGER FreeBytesAvailable
, TotalNumberOfBytes
, TotalNumberOfFreeBytes
;
1618 if(GetDiskFreeSpaceEx(m_file
.Left(m_file
.ReverseFind('\\')+1), &FreeBytesAvailable
, &TotalNumberOfBytes
, &TotalNumberOfFreeBytes
)
1619 && FreeBytesAvailable
.QuadPart
< 1024i64
*1024*10)
1626 __super::OnTimer(nIDEvent
);
1629 void CPlayerCaptureDialog::OnBnClickedVidAudPreview()
1635 void CPlayerCaptureDialog::OnBnClickedCheck7()
1640 void CPlayerCaptureDialog::OnCbnSelchangeCombo14()
1644 CString ext
= m_file
.Mid(m_file
.ReverseFind('.')+1).MakeLower();
1646 if(m_muxtype
== 0 && ext
!= _T("avi"))
1647 m_file
= m_file
.Left(m_file
.GetLength()-4) + _T(".avi");
1648 else if(m_muxtype
== 1 && ext
!= _T("ogm"))
1649 m_file
= m_file
.Left(m_file
.GetLength()-4) + _T(".ogm");
1650 else if(m_muxtype
== 2 && ext
!= _T("mkv"))
1651 m_file
= m_file
.Left(m_file
.GetLength()-4) + _T(".mkv");
1652 else if(m_muxtype
== 3 && ext
!= _T("dsm"))
1653 m_file
= m_file
.Left(m_file
.GetLength()-4) + _T(".dsm");
1657 GetDlgItem(IDC_EDIT5
)->EnableWindow(m_muxtype
!= 2 && m_muxtype
!= 3);
1658 GetDlgItem(IDC_EDIT6
)->EnableWindow(m_muxtype
!= 2 && m_muxtype
!= 3);
1660 m_recordbtn
.EnableWindow(m_muxtype
!= 1 || m_fEnableOgm
);