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
25 #include "..\..\filters\transform\bufferfilter\bufferfilter.h"
26 #include "FloatEdit.h"
39 class CFormat
: public CAutoPtrArray
<CFormatElem
<T
> >
43 CFormat(CString name
= _T("")) {this->name
= name
;}
48 class CFormatArray
: public CAutoPtrArray
<CFormat
<T
> >
51 virtual ~CFormatArray() {}
53 CFormat
<T
>* Find(CString name
, bool fCreate
= false)
55 for(int i
= 0; i
< (int)GetCount(); i
++)
57 if(GetAt(i
)->name
== name
)
63 CAutoPtr
<CFormat
<T
> > pf(new CFormat
<T
>(name
));
72 bool FindFormat(AM_MEDIA_TYPE
* pmt
, CFormat
<T
>** ppf
)
74 if(!pmt
) return(false);
76 for(int i
= 0; i
< (int)GetCount(); i
++)
78 CFormat
<T
>* pf
= GetAt(i
);
79 for(int j
= 0; j
< (int)pf
->GetCount(); j
++)
81 CFormatElem
<T
>* pfe
= pf
->GetAt(j
);
82 if(!pmt
|| (pfe
->mt
.majortype
== pmt
->majortype
&& pfe
->mt
.subtype
== pmt
->subtype
))
93 bool FindFormat(AM_MEDIA_TYPE
* pmt
, T
* pcaps
, CFormat
<T
>** ppf
, CFormatElem
<T
>** ppfe
)
95 if(!pmt
&& !pcaps
) return(false);
97 for(int i
= 0; i
< (int)GetCount(); i
++)
99 CFormat
<T
>* pf
= GetAt(i
);
100 for(int j
= 0; j
< (int)pf
->GetCount(); j
++)
102 CFormatElem
<T
>* pfe
= pf
->GetAt(j
);
103 if((!pmt
|| pfe
->mt
== *pmt
) && (!pcaps
|| !memcmp(pcaps
, &pfe
->caps
, sizeof(T
))))
106 if(ppfe
) *ppfe
= pfe
;
115 bool AddFormat(AM_MEDIA_TYPE
* pmt
, T caps
)
117 if(!pmt
) return(false);
119 if(FindFormat(pmt
, NULL
, NULL
, NULL
)) {DeleteMediaType(pmt
); return(false);}
120 // if(pmt->formattype == FORMAT_VideoInfo2) {DeleteMediaType(pmt); return(false);} // TODO
122 CFormat
<T
>* pf
= Find(MakeFormatName(pmt
), true);
123 if(!pf
) {DeleteMediaType(pmt
); return(false);}
125 CAutoPtr
<CFormatElem
<T
> > pfe(new CFormatElem
<T
>());
133 bool AddFormat(AM_MEDIA_TYPE
* pmt
, void* pcaps
, int size
)
135 if(!pcaps
) return false;
136 ASSERT(size
== sizeof(T
));
137 return AddFormat(pmt
, *(T
*)pcaps
);
140 virtual CString
MakeFormatName(AM_MEDIA_TYPE
* pmt
) = 0;
141 virtual CString
MakeDimensionName(CFormatElem
<T
>* pfe
) = 0;
144 typedef CFormatElem
<VIDEO_STREAM_CONFIG_CAPS
> CVidFormatElem
;
145 typedef CFormat
<VIDEO_STREAM_CONFIG_CAPS
> CVidFormat
;
147 class CVidFormatArray
: public CFormatArray
<VIDEO_STREAM_CONFIG_CAPS
>
150 CString
MakeFormatName(AM_MEDIA_TYPE
* pmt
)
152 CString
str(_T("Default"));
154 if(!pmt
) return(str
);
156 BITMAPINFOHEADER
* bih
= (pmt
->formattype
== FORMAT_VideoInfo
)
157 ? &((VIDEOINFOHEADER
*)pmt
->pbFormat
)->bmiHeader
158 : (pmt
->formattype
== FORMAT_VideoInfo2
)
159 ? &((VIDEOINFOHEADER2
*)pmt
->pbFormat
)->bmiHeader
164 // it may have a fourcc in the mediasubtype, let's check that
167 memset(guid
, 0, 100*sizeof(WCHAR
));
168 StringFromGUID2(pmt
->subtype
, guid
, 100);
170 if(CStringW(guid
).MakeUpper().Find(L
"0000-0010-8000-00AA00389B71") >= 0)
172 str
.Format(_T("%c%c%c%c"),
173 (TCHAR
)((pmt
->subtype
.Data1
>>0)&0xff), (TCHAR
)((pmt
->subtype
.Data1
>>8)&0xff),
174 (TCHAR
)((pmt
->subtype
.Data1
>>16)&0xff), (TCHAR
)((pmt
->subtype
.Data1
>>24)&0xff));
180 switch(bih
->biCompression
)
182 case BI_RGB
: str
.Format(_T("RGB%d"), bih
->biBitCount
); break;
183 case BI_RLE8
: str
= _T("RLE8"); break;
184 case BI_RLE4
: str
= _T("RLE4"); break;
185 case BI_BITFIELDS
: str
.Format(_T("BITF%d"), bih
->biBitCount
); break;
186 case BI_JPEG
: str
= _T("JPEG"); break;
187 case BI_PNG
: str
= _T("PNG"); break;
189 str
.Format(_T("%c%c%c%c"),
190 (TCHAR
)((bih
->biCompression
>>0)&0xff), (TCHAR
)((bih
->biCompression
>>8)&0xff),
191 (TCHAR
)((bih
->biCompression
>>16)&0xff), (TCHAR
)((bih
->biCompression
>>24)&0xff));
198 CString
MakeDimensionName(CVidFormatElem
* pfe
)
200 CString
str(_T("Default"));
202 if(!pfe
) return(str
);
204 BITMAPINFOHEADER
* bih
= (pfe
->mt
.formattype
== FORMAT_VideoInfo
)
205 ? &((VIDEOINFOHEADER
*)pfe
->mt
.pbFormat
)->bmiHeader
206 : (pfe
->mt
.formattype
== FORMAT_VideoInfo2
)
207 ? &((VIDEOINFOHEADER2
*)pfe
->mt
.pbFormat
)->bmiHeader
210 if(bih
== NULL
) return(str
);
212 str
.Format(_T("%dx%d %.2f"), bih
->biWidth
, bih
->biHeight
, (float)10000000/((VIDEOINFOHEADER
*)pfe
->mt
.pbFormat
)->AvgTimePerFrame
);
214 if(pfe
->mt
.formattype
== FORMAT_VideoInfo2
)
216 VIDEOINFOHEADER2
* vih2
= (VIDEOINFOHEADER2
*)pfe
->mt
.pbFormat
;
218 str2
.Format(_T(" i%02x %d:%d"), vih2
->dwInterlaceFlags
, vih2
->dwPictAspectRatioX
, vih2
->dwPictAspectRatioY
);
226 typedef CFormatElem
<AUDIO_STREAM_CONFIG_CAPS
> CAudFormatElem
;
227 typedef CFormat
<AUDIO_STREAM_CONFIG_CAPS
> CAudFormat
;
229 class CAudFormatArray
: public CFormatArray
<AUDIO_STREAM_CONFIG_CAPS
>
232 CString
MakeFormatName(AM_MEDIA_TYPE
* pmt
)
234 CString
str(_T("Unknown"));
236 if(!pmt
) return(str
);
238 WAVEFORMATEX
* wfe
= (pmt
->formattype
== FORMAT_WaveFormatEx
)
239 ? (WAVEFORMATEX
*)pmt
->pbFormat
245 memset(guid
, 0, 100*sizeof(WCHAR
));
246 StringFromGUID2(pmt
->subtype
, guid
, 100);
248 if(CStringW(guid
).MakeUpper().Find(L
"0000-0010-8000-00AA00389B71") >= 0)
250 str
.Format(_T("0x%04x"), pmt
->subtype
.Data1
);
256 switch(wfe
->wFormatTag
)
258 case 1: str
= _T("PCM "); break;
259 default: str
.Format(_T("0x%03x "), wfe
->wFormatTag
); break;
265 CString
MakeDimensionName(CAudFormatElem
* pfe
)
267 CString
str(_T("Unknown"));
269 if(!pfe
) return(str
);
271 WAVEFORMATEX
* wfe
= (pfe
->mt
.formattype
== FORMAT_WaveFormatEx
)
272 ? (WAVEFORMATEX
*)pfe
->mt
.pbFormat
275 if(!wfe
) return(str
);
280 str2
.Format(_T("%6dKHz "), wfe
->nSamplesPerSec
); str
+= str2
;
282 str2
.Format(_T("%dbps "), wfe
->wBitsPerSample
); str
+= str2
;
284 switch(wfe
->nChannels
)
286 case 1: str
+= _T("mono "); break;
287 case 2: str
+= _T("stereo "); break;
288 default: str2
.Format(_T("%d channels "), wfe
->nChannels
); str
+= str2
; break;
291 str2
.Format(_T("%3dkbps "), wfe
->nAvgBytesPerSec
*8/1000); str
+= str2
;
301 CComPtr
<IMoniker
> pMoniker
;
302 CComPtr
<IBaseFilter
> pBF
;
303 CString FriendlyName
;
304 CComBSTR DisplayName
;
307 typedef CAtlArray
<Codec
> CCodecArray
;
309 // CPlayerCaptureDialog dialog
311 class CPlayerCaptureDialog
: public CResizableDialog
//CDialog
313 //DECLARE_DYNAMIC(CPlayerCaptureDialog)
316 CStringW m_VidDisplayName
;
317 CComPtr
<IAMStreamConfig
> m_pAMVSC
;
318 CComPtr
<IAMCrossbar
> m_pAMXB
;
319 CComPtr
<IAMTVTuner
> m_pAMTuner
;
320 CComPtr
<IAMVfwCaptureDialogs
> m_pAMVfwCD
;
321 CVidFormatArray m_vfa
;
324 CStringW m_AudDisplayName
;
325 CComPtr
<IAMStreamConfig
> m_pAMASC
;
326 CInterfaceArray
<IAMAudioInputMixer
> m_pAMAIM
;
327 CAudFormatArray m_afa
;
330 CCodecArray m_pVidEncArray
;
331 CVidFormatArray m_vcfa
;
334 CCodecArray m_pAudEncArray
;
335 CAudFormatArray m_acfa
;
340 void UpdateMediaTypes();
341 void UpdateUserDefinableControls();
342 void UpdateVideoCodec();
343 void UpdateAudioCodec();
345 void UpdateOutputControls();
349 CMap
<HWND
, HWND
&, BOOL
, BOOL
&> m_wndenabledmap
;
350 void EnableControls(CWnd
* pWnd
, bool fEnable
);
355 CPlayerCaptureDialog(); // standard constructor
356 virtual ~CPlayerCaptureDialog();
358 BOOL
Create(CWnd
* pParent
= NULL
);
361 enum { IDD
= IDD_CAPTURE_DLG
};
363 CComboBox m_vidinput
;
365 CComboBox m_viddimension
;
366 CSpinButtonCtrl m_vidhor
;
367 CSpinButtonCtrl m_vidver
;
370 CFloatEdit m_vidfpsedit
;
373 CComboBox m_audinput
;
375 CComboBox m_auddimension
;
376 CComboBox m_vidcodec
;
377 CComboBox m_vidcodectype
;
378 CComboBox m_vidcodecdimension
;
382 CButton m_vidpreview
;
383 CComboBox m_audcodec
;
384 CComboBox m_audcodectype
;
385 CComboBox m_audcodecdimension
;
389 CButton m_audpreview
;
398 CMediaType m_mtv
, m_mta
, m_mtcv
, m_mtca
;
399 CComPtr
<IBaseFilter
> m_pVidEnc
, m_pAudEnc
, m_pMux
, m_pDst
, m_pAudMux
, m_pAudDst
;
400 CComPtr
<IMoniker
> m_pVidEncMoniker
, m_pAudEncMoniker
;
401 CComPtr
<IBaseFilter
> m_pVidBuffer
, m_pAudBuffer
;
404 void SetupVideoControls(CStringW DisplayName
, CComPtr
<IAMStreamConfig
> pAMSC
, CComPtr
<IAMCrossbar
> pAMXB
, CComPtr
<IAMTVTuner
> pAMTuner
);
405 void SetupVideoControls(CStringW DisplayName
, CComPtr
<IAMStreamConfig
> pAMSC
, CComPtr
<IAMVfwCaptureDialogs
> pAMVfwCD
);
406 void SetupAudioControls(CStringW DisplayName
, CComPtr
<IAMStreamConfig
> pAMSC
, CInterfaceArray
<IAMAudioInputMixer
>& pAMAIM
);
408 bool IsTunerActive();
410 bool SetVideoInput(int input
);
411 bool SetVideoChannel(int channel
);
412 bool SetAudioInput(int input
);
415 int GetVideoChannel();
419 virtual void DoDataExchange(CDataExchange
* pDX
); // DDX/DDV support
420 virtual BOOL
PreTranslateMessage(MSG
* pMsg
);
421 virtual BOOL
OnInitDialog();
422 virtual void OnOK() {}
423 virtual void OnCancel() {}
425 DECLARE_MESSAGE_MAP()
428 afx_msg
void OnDestroy();
429 afx_msg
void OnVideoInput();
430 afx_msg
void OnVideoType();
431 afx_msg
void OnVideoDimension();
432 afx_msg
void OnOverrideVideoDimension();
433 afx_msg
void OnAudioInput();
434 afx_msg
void OnAudioType();
435 afx_msg
void OnAudioDimension();
436 afx_msg
void OnRecordVideo();
437 afx_msg
void OnVideoCodec();
438 afx_msg
void OnVideoCodecType();
439 afx_msg
void OnVideoCodecDimension();
440 afx_msg
void OnRecordAudio();
441 afx_msg
void OnAudioCodec();
442 afx_msg
void OnAudioCodecType();
443 afx_msg
void OnAudioCodecDimension();
444 afx_msg
void OnOpenFile();
445 afx_msg
void OnRecord();
446 afx_msg
void OnEnChangeEdit9();
447 afx_msg
void OnEnChangeEdit12();
448 afx_msg
void OnTimer(UINT nIDEvent
);
449 afx_msg
void OnBnClickedVidAudPreview();
450 afx_msg
void OnBnClickedCheck7();
451 afx_msg
void OnCbnSelchangeCombo14();