00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #pragma once
00023 #include "afxwin.h"
00024 #include "afxcmn.h"
00025 #include "..\..\filters\transform\bufferfilter\bufferfilter.h"
00026 #include "FloatEdit.h"
00027
00028
00029
00030 template<class T>
00031 class CFormatElem
00032 {
00033 public:
00034 CMediaType mt;
00035 T caps;
00036 };
00037
00038 template<class T>
00039 class CFormat : public CAutoPtrArray<CFormatElem<T> >
00040 {
00041 public:
00042 CString name;
00043 CFormat(CString name = _T("")) {this->name = name;}
00044 virtual ~CFormat() {}
00045 };
00046
00047 template<class T>
00048 class CFormatArray : public CAutoPtrArray<CFormat<T> >
00049 {
00050 public:
00051 virtual ~CFormatArray() {}
00052
00053 CFormat<T>* Find(CString name, bool fCreate = false)
00054 {
00055 for(int i = 0; i < (int)GetCount(); i++)
00056 {
00057 if(GetAt(i)->name == name)
00058 return(GetAt(i));
00059 }
00060
00061 if(fCreate)
00062 {
00063 CAutoPtr<CFormat<T> > pf(new CFormat<T>(name));
00064 CFormat<T>* tmp = pf;
00065 Add(pf);
00066 return(tmp);
00067 }
00068
00069 return(NULL);
00070 }
00071
00072 bool FindFormat(AM_MEDIA_TYPE* pmt, CFormat<T>** ppf)
00073 {
00074 if(!pmt) return(false);
00075
00076 for(int i = 0; i < (int)GetCount(); i++)
00077 {
00078 CFormat<T>* pf = GetAt(i);
00079 for(int j = 0; j < (int)pf->GetCount(); j++)
00080 {
00081 CFormatElem<T>* pfe = pf->GetAt(j);
00082 if(!pmt || (pfe->mt.majortype == pmt->majortype && pfe->mt.subtype == pmt->subtype))
00083 {
00084 if(ppf) *ppf = pf;
00085 return(true);
00086 }
00087 }
00088 }
00089
00090 return(false);
00091 }
00092
00093 bool FindFormat(AM_MEDIA_TYPE* pmt, T* pcaps, CFormat<T>** ppf, CFormatElem<T>** ppfe)
00094 {
00095 if(!pmt && !pcaps) return(false);
00096
00097 for(int i = 0; i < (int)GetCount(); i++)
00098 {
00099 CFormat<T>* pf = GetAt(i);
00100 for(int j = 0; j < (int)pf->GetCount(); j++)
00101 {
00102 CFormatElem<T>* pfe = pf->GetAt(j);
00103 if((!pmt || pfe->mt == *pmt) && (!pcaps || !memcmp(pcaps, &pfe->caps, sizeof(T))))
00104 {
00105 if(ppf) *ppf = pf;
00106 if(ppfe) *ppfe = pfe;
00107 return(true);
00108 }
00109 }
00110 }
00111
00112 return(false);
00113 }
00114
00115 bool AddFormat(AM_MEDIA_TYPE* pmt, T caps)
00116 {
00117 if(!pmt) return(false);
00118
00119 if(FindFormat(pmt, NULL, NULL, NULL)) {DeleteMediaType(pmt); return(false);}
00120
00121
00122 CFormat<T>* pf = Find(MakeFormatName(pmt), true);
00123 if(!pf) {DeleteMediaType(pmt); return(false);}
00124
00125 CAutoPtr<CFormatElem<T> > pfe(new CFormatElem<T>());
00126 pfe->mt = *pmt;
00127 pfe->caps = caps;
00128 pf->Add(pfe);
00129
00130 return(true);
00131 }
00132
00133 bool AddFormat(AM_MEDIA_TYPE* pmt, void* pcaps, int size)
00134 {
00135 if(!pcaps) return false;
00136 ASSERT(size == sizeof(T));
00137 return AddFormat(pmt, *(T*)pcaps);
00138 }
00139
00140 virtual CString MakeFormatName(AM_MEDIA_TYPE* pmt) = 0;
00141 virtual CString MakeDimensionName(CFormatElem<T>* pfe) = 0;
00142 };
00143
00144 typedef CFormatElem<VIDEO_STREAM_CONFIG_CAPS> CVidFormatElem;
00145 typedef CFormat<VIDEO_STREAM_CONFIG_CAPS> CVidFormat;
00146
00147 class CVidFormatArray : public CFormatArray<VIDEO_STREAM_CONFIG_CAPS>
00148 {
00149 public:
00150 CString MakeFormatName(AM_MEDIA_TYPE* pmt)
00151 {
00152 CString str(_T("Default"));
00153
00154 if(!pmt) return(str);
00155
00156 BITMAPINFOHEADER* bih = (pmt->formattype == FORMAT_VideoInfo)
00157 ? &((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader
00158 : (pmt->formattype == FORMAT_VideoInfo2)
00159 ? &((VIDEOINFOHEADER2*)pmt->pbFormat)->bmiHeader
00160 : NULL;
00161
00162 if(!bih)
00163 {
00164
00165
00166 WCHAR guid[100];
00167 memset(guid, 0, 100*sizeof(WCHAR));
00168 StringFromGUID2(pmt->subtype, guid, 100);
00169
00170 if(CStringW(guid).MakeUpper().Find(L"0000-0010-8000-00AA00389B71") >= 0)
00171 {
00172 str.Format(_T("%c%c%c%c"),
00173 (TCHAR)((pmt->subtype.Data1>>0)&0xff), (TCHAR)((pmt->subtype.Data1>>8)&0xff),
00174 (TCHAR)((pmt->subtype.Data1>>16)&0xff), (TCHAR)((pmt->subtype.Data1>>24)&0xff));
00175 }
00176
00177 return(str);
00178 }
00179
00180 switch(bih->biCompression)
00181 {
00182 case BI_RGB: str.Format(_T("RGB%d"), bih->biBitCount); break;
00183 case BI_RLE8: str = _T("RLE8"); break;
00184 case BI_RLE4: str = _T("RLE4"); break;
00185 case BI_BITFIELDS: str.Format(_T("BITF%d"), bih->biBitCount); break;
00186 case BI_JPEG: str = _T("JPEG"); break;
00187 case BI_PNG: str = _T("PNG"); break;
00188 default:
00189 str.Format(_T("%c%c%c%c"),
00190 (TCHAR)((bih->biCompression>>0)&0xff), (TCHAR)((bih->biCompression>>8)&0xff),
00191 (TCHAR)((bih->biCompression>>16)&0xff), (TCHAR)((bih->biCompression>>24)&0xff));
00192 break;
00193 }
00194
00195 return(str);
00196 }
00197
00198 CString MakeDimensionName(CVidFormatElem* pfe)
00199 {
00200 CString str(_T("Default"));
00201
00202 if(!pfe) return(str);
00203
00204 BITMAPINFOHEADER* bih = (pfe->mt.formattype == FORMAT_VideoInfo)
00205 ? &((VIDEOINFOHEADER*)pfe->mt.pbFormat)->bmiHeader
00206 : (pfe->mt.formattype == FORMAT_VideoInfo2)
00207 ? &((VIDEOINFOHEADER2*)pfe->mt.pbFormat)->bmiHeader
00208 : NULL;
00209
00210 if(bih == NULL) return(str);
00211
00212 str.Format(_T("%dx%d %.2f"), bih->biWidth, bih->biHeight, (float)10000000/((VIDEOINFOHEADER*)pfe->mt.pbFormat)->AvgTimePerFrame);
00213
00214 if(pfe->mt.formattype == FORMAT_VideoInfo2)
00215 {
00216 VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)pfe->mt.pbFormat;
00217 CString str2;
00218 str2.Format(_T(" i%02x %d:%d"), vih2->dwInterlaceFlags, vih2->dwPictAspectRatioX, vih2->dwPictAspectRatioY);
00219 str += str2;
00220 }
00221
00222 return(str);
00223 }
00224 };
00225
00226 typedef CFormatElem<AUDIO_STREAM_CONFIG_CAPS> CAudFormatElem;
00227 typedef CFormat<AUDIO_STREAM_CONFIG_CAPS> CAudFormat;
00228
00229 class CAudFormatArray : public CFormatArray<AUDIO_STREAM_CONFIG_CAPS>
00230 {
00231 public:
00232 CString MakeFormatName(AM_MEDIA_TYPE* pmt)
00233 {
00234 CString str(_T("Unknown"));
00235
00236 if(!pmt) return(str);
00237
00238 WAVEFORMATEX* wfe = (pmt->formattype == FORMAT_WaveFormatEx)
00239 ? (WAVEFORMATEX*)pmt->pbFormat
00240 : NULL;
00241
00242 if(!wfe)
00243 {
00244 WCHAR guid[100];
00245 memset(guid, 0, 100*sizeof(WCHAR));
00246 StringFromGUID2(pmt->subtype, guid, 100);
00247
00248 if(CStringW(guid).MakeUpper().Find(L"0000-0010-8000-00AA00389B71") >= 0)
00249 {
00250 str.Format(_T("0x%04x"), pmt->subtype.Data1);
00251 }
00252
00253 return(str);
00254 }
00255
00256 switch(wfe->wFormatTag)
00257 {
00258 case 1: str = _T("PCM "); break;
00259 default: str.Format(_T("0x%03x "), wfe->wFormatTag); break;
00260 }
00261
00262 return(str);
00263 }
00264
00265 CString MakeDimensionName(CAudFormatElem* pfe)
00266 {
00267 CString str(_T("Unknown"));
00268
00269 if(!pfe) return(str);
00270
00271 WAVEFORMATEX* wfe = (pfe->mt.formattype == FORMAT_WaveFormatEx)
00272 ? (WAVEFORMATEX*)pfe->mt.pbFormat
00273 : NULL;
00274
00275 if(!wfe) return(str);
00276
00277 str.Empty();
00278 CString str2;
00279
00280 str2.Format(_T("%6dKHz "), wfe->nSamplesPerSec); str += str2;
00281
00282 str2.Format(_T("%dbps "), wfe->wBitsPerSample); str += str2;
00283
00284 switch(wfe->nChannels)
00285 {
00286 case 1: str += _T("mono "); break;
00287 case 2: str += _T("stereo "); break;
00288 default: str2.Format(_T("%d channels "), wfe->nChannels); str += str2; break;
00289 }
00290
00291 str2.Format(_T("%3dkbps "), wfe->nAvgBytesPerSec*8/1000); str += str2;
00292
00293 return(str);
00294 }
00295 };
00296
00297
00298
00299 typedef struct
00300 {
00301 CComPtr<IMoniker> pMoniker;
00302 CComPtr<IBaseFilter> pBF;
00303 CString FriendlyName;
00304 CComBSTR DisplayName;
00305 } Codec;
00306
00307 typedef CArray<Codec> CCodecArray;
00308
00309
00310
00311 class CPlayerCaptureDialog : public CDialog
00312 {
00313 DECLARE_DYNAMIC(CPlayerCaptureDialog)
00314
00315
00316 CStringW m_VidDisplayName;
00317 CComPtr<IAMStreamConfig> m_pAMVSC;
00318 CComPtr<IAMCrossbar> m_pAMXB;
00319 CComPtr<IAMTVTuner> m_pAMTuner;
00320 CComPtr<IAMVfwCaptureDialogs> m_pAMVfwCD;
00321 CVidFormatArray m_vfa;
00322
00323
00324 CStringW m_AudDisplayName;
00325 CComPtr<IAMStreamConfig> m_pAMASC;
00326 CInterfaceArray<IAMAudioInputMixer> m_pAMAIM;
00327 CAudFormatArray m_afa;
00328
00329
00330 CCodecArray m_pVidEncArray;
00331 CVidFormatArray m_vcfa;
00332
00333
00334 CCodecArray m_pAudEncArray;
00335 CAudFormatArray m_acfa;
00336
00337 void EmptyVideo();
00338 void EmptyAudio();
00339
00340 void UpdateMediaTypes();
00341 void UpdateUserDefinableControls();
00342 void UpdateVideoCodec();
00343 void UpdateAudioCodec();
00344 void UpdateMuxer();
00345 void UpdateOutputControls();
00346
00347 void UpdateGraph();
00348
00349 CMap<HWND, HWND&, BOOL, BOOL&> m_wndenabledmap;
00350 void EnableControls(CWnd* pWnd, bool fEnable);
00351
00352 bool m_fEnableOgm;
00353
00354 public:
00355 CPlayerCaptureDialog();
00356 virtual ~CPlayerCaptureDialog();
00357
00358 BOOL Create(CWnd* pParent = NULL);
00359
00360
00361 enum { IDD = IDD_CAPTUREDIALOG };
00362
00363 CComboBox m_vidinput;
00364 CComboBox m_vidtype;
00365 CComboBox m_viddimension;
00366 CSpinButtonCtrl m_vidhor;
00367 CSpinButtonCtrl m_vidver;
00368 CEdit m_vidhoredit;
00369 CEdit m_vidveredit;
00370 CFloatEdit m_vidfpsedit;
00371 float m_vidfps;
00372 CButton m_vidsetres;
00373 CComboBox m_audinput;
00374 CComboBox m_audtype;
00375 CComboBox m_auddimension;
00376 CComboBox m_vidcodec;
00377 CComboBox m_vidcodectype;
00378 CComboBox m_vidcodecdimension;
00379 BOOL m_fVidOutput;
00380 CButton m_vidoutput;
00381 BOOL m_fVidPreview;
00382 CButton m_vidpreview;
00383 CComboBox m_audcodec;
00384 CComboBox m_audcodectype;
00385 CComboBox m_audcodecdimension;
00386 BOOL m_fAudOutput;
00387 CButton m_audoutput;
00388 BOOL m_fAudPreview;
00389 CButton m_audpreview;
00390 int m_nVidBuffers;
00391 int m_nAudBuffers;
00392 CString m_file;
00393 CButton m_recordbtn;
00394 BOOL m_fSepAudio;
00395 int m_muxtype;
00396 CComboBox m_muxctrl;
00397
00398 CMediaType m_mtv, m_mta, m_mtcv, m_mtca;
00399 CComPtr<IBaseFilter> m_pVidEnc, m_pAudEnc, m_pMux, m_pDst, m_pAudMux, m_pAudDst;
00400 CComPtr<IMoniker> m_pVidEncMoniker, m_pAudEncMoniker;
00401 CComPtr<IBaseFilter> m_pVidBuffer, m_pAudBuffer;
00402
00403 public:
00404 void SetupVideoControls(CStringW DisplayName, CComPtr<IAMStreamConfig> pAMSC, CComPtr<IAMCrossbar> pAMXB, CComPtr<IAMTVTuner> pAMTuner);
00405 void SetupVideoControls(CStringW DisplayName, CComPtr<IAMStreamConfig> pAMSC, CComPtr<IAMVfwCaptureDialogs> pAMVfwCD);
00406 void SetupAudioControls(CStringW DisplayName, CComPtr<IAMStreamConfig> pAMSC, CInterfaceArray<IAMAudioInputMixer>& pAMAIM);
00407
00408 bool IsTunerActive();
00409
00410 bool SetVideoInput(int input);
00411 bool SetVideoChannel(int channel);
00412 bool SetAudioInput(int input);
00413
00414 int GetVideoInput();
00415 int GetVideoChannel();
00416 int GetAudioInput();
00417
00418 protected:
00419 virtual void DoDataExchange(CDataExchange* pDX);
00420 virtual BOOL PreTranslateMessage(MSG* pMsg);
00421 virtual BOOL OnInitDialog();
00422 virtual void OnOK() {}
00423 virtual void OnCancel() {}
00424
00425 DECLARE_MESSAGE_MAP()
00426
00427 public:
00428 afx_msg void OnDestroy();
00429 afx_msg void OnVideoInput();
00430 afx_msg void OnVideoType();
00431 afx_msg void OnVideoDimension();
00432 afx_msg void OnOverrideVideoDimension();
00433 afx_msg void OnAudioInput();
00434 afx_msg void OnAudioType();
00435 afx_msg void OnAudioDimension();
00436 afx_msg void OnRecordVideo();
00437 afx_msg void OnVideoCodec();
00438 afx_msg void OnVideoCodecType();
00439 afx_msg void OnVideoCodecDimension();
00440 afx_msg void OnRecordAudio();
00441 afx_msg void OnAudioCodec();
00442 afx_msg void OnAudioCodecType();
00443 afx_msg void OnAudioCodecDimension();
00444 afx_msg void OnOpenFile();
00445 afx_msg void OnRecord();
00446 afx_msg void OnEnChangeEdit9();
00447 afx_msg void OnEnChangeEdit12();
00448 afx_msg void OnTimer(UINT nIDEvent);
00449 afx_msg void OnBnClickedVidAudPreview();
00450 afx_msg void OnBnClickedCheck7();
00451 afx_msg void OnCbnSelchangeCombo14();
00452 };