/*
* $Id$
*
* (C) 2003-2006 Gabest
* (C) 2006-2010 see AUTHORS
*
* This file is part of mplayerc.
*
* Mplayerc is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Mplayerc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#pragma once
#include "afxwin.h"
#include "afxcmn.h"
#include "../../filters/transform/BufferFilter/BufferFilter.h"
#include "FloatEdit.h"
//
template
class CFormatElem
{
public:
CMediaType mt;
T caps;
};
template
class CFormat : public CAutoPtrArray >
{
public:
CString name;
CFormat(CString name = _T(""))
{
this->name = name;
}
virtual ~CFormat() {}
};
template
class CFormatArray : public CAutoPtrArray >
{
public:
virtual ~CFormatArray() {}
CFormat* Find(CString name, bool fCreate = false)
{
for(int i = 0; i < (int)GetCount(); i++)
{
if(GetAt(i)->name == name)
return(GetAt(i));
}
if(fCreate)
{
CAutoPtr > pf(DNew CFormat(name));
CFormat* tmp = pf;
Add(pf);
return(tmp);
}
return(NULL);
}
bool FindFormat(AM_MEDIA_TYPE* pmt, CFormat** ppf)
{
if(!pmt) return(false);
for(int i = 0; i < (int)GetCount(); i++)
{
CFormat* pf = GetAt(i);
for(int j = 0; j < (int)pf->GetCount(); j++)
{
CFormatElem* pfe = pf->GetAt(j);
if(!pmt || (pfe->mt.majortype == pmt->majortype && pfe->mt.subtype == pmt->subtype))
{
if(ppf) *ppf = pf;
return(true);
}
}
}
return(false);
}
bool FindFormat(AM_MEDIA_TYPE* pmt, T* pcaps, CFormat** ppf, CFormatElem** ppfe)
{
if(!pmt && !pcaps) return(false);
for(int i = 0; i < (int)GetCount(); i++)
{
CFormat* pf = GetAt(i);
for(int j = 0; j < (int)pf->GetCount(); j++)
{
CFormatElem* pfe = pf->GetAt(j);
if((!pmt || pfe->mt == *pmt) && (!pcaps || !memcmp(pcaps, &pfe->caps, sizeof(T))))
{
if(ppf) *ppf = pf;
if(ppfe) *ppfe = pfe;
return(true);
}
}
}
return(false);
}
bool AddFormat(AM_MEDIA_TYPE* pmt, T caps)
{
if(!pmt) return(false);
if(FindFormat(pmt, NULL, NULL, NULL))
{
DeleteMediaType(pmt);
return(false);
}
// if(pmt->formattype == FORMAT_VideoInfo2) {DeleteMediaType(pmt); return(false);} // TODO
CFormat* pf = Find(MakeFormatName(pmt), true);
if(!pf)
{
DeleteMediaType(pmt);
return(false);
}
CAutoPtr > pfe(DNew CFormatElem());
pfe->mt = *pmt;
pfe->caps = caps;
pf->Add(pfe);
return(true);
}
bool AddFormat(AM_MEDIA_TYPE* pmt, void* pcaps, int size)
{
if(!pcaps) return false;
ASSERT(size == sizeof(T));
return AddFormat(pmt, *(T*)pcaps);
}
virtual CString MakeFormatName(AM_MEDIA_TYPE* pmt) = 0;
virtual CString MakeDimensionName(CFormatElem* pfe) = 0;
};
typedef CFormatElem CVidFormatElem;
typedef CFormat CVidFormat;
class CVidFormatArray : public CFormatArray
{
public:
CString MakeFormatName(AM_MEDIA_TYPE* pmt)
{
CString str(_T("Default"));
if(!pmt) return(str);
BITMAPINFOHEADER* bih = (pmt->formattype == FORMAT_VideoInfo)
? &((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader
: (pmt->formattype == FORMAT_VideoInfo2)
? &((VIDEOINFOHEADER2*)pmt->pbFormat)->bmiHeader
: NULL;
if(!bih)
{
// it may have a fourcc in the mediasubtype, let's check that
WCHAR guid[100];
memset(guid, 0, 100*sizeof(WCHAR));
StringFromGUID2(pmt->subtype, guid, 100);
if(CStringW(guid).MakeUpper().Find(L"0000-0010-8000-00AA00389B71") >= 0)
{
str.Format(_T("%c%c%c%c"),
(TCHAR)((pmt->subtype.Data1>>0)&0xff), (TCHAR)((pmt->subtype.Data1>>8)&0xff),
(TCHAR)((pmt->subtype.Data1>>16)&0xff), (TCHAR)((pmt->subtype.Data1>>24)&0xff));
}
return(str);
}
switch(bih->biCompression)
{
case BI_RGB:
str.Format(_T("RGB%d"), bih->biBitCount);
break;
case BI_RLE8:
str = _T("RLE8");
break;
case BI_RLE4:
str = _T("RLE4");
break;
case BI_BITFIELDS:
str.Format(_T("BITF%d"), bih->biBitCount);
break;
case BI_JPEG:
str = _T("JPEG");
break;
case BI_PNG:
str = _T("PNG");
break;
default:
str.Format(_T("%c%c%c%c"),
(TCHAR)((bih->biCompression>>0)&0xff), (TCHAR)((bih->biCompression>>8)&0xff),
(TCHAR)((bih->biCompression>>16)&0xff), (TCHAR)((bih->biCompression>>24)&0xff));
break;
}
return(str);
}
CString MakeDimensionName(CVidFormatElem* pfe)
{
CString str(_T("Default"));
if(!pfe) return(str);
BITMAPINFOHEADER* bih = (pfe->mt.formattype == FORMAT_VideoInfo)
? &((VIDEOINFOHEADER*)pfe->mt.pbFormat)->bmiHeader
: (pfe->mt.formattype == FORMAT_VideoInfo2)
? &((VIDEOINFOHEADER2*)pfe->mt.pbFormat)->bmiHeader
: NULL;
if(bih == NULL) return(str);
str.Format(_T("%dx%d %.2f"), bih->biWidth, bih->biHeight, (float)10000000/((VIDEOINFOHEADER*)pfe->mt.pbFormat)->AvgTimePerFrame);
if(pfe->mt.formattype == FORMAT_VideoInfo2)
{
VIDEOINFOHEADER2* vih2 = (VIDEOINFOHEADER2*)pfe->mt.pbFormat;
CString str2;
str2.Format(_T(" i%02x %d:%d"), vih2->dwInterlaceFlags, vih2->dwPictAspectRatioX, vih2->dwPictAspectRatioY);
str += str2;
}
return(str);
}
};
typedef CFormatElem CAudFormatElem;
typedef CFormat CAudFormat;
class CAudFormatArray : public CFormatArray
{
public:
CString MakeFormatName(AM_MEDIA_TYPE* pmt)
{
CString str(_T("Unknown"));
if(!pmt) return(str);
WAVEFORMATEX* wfe = (pmt->formattype == FORMAT_WaveFormatEx)
? (WAVEFORMATEX*)pmt->pbFormat
: NULL;
if(!wfe)
{
WCHAR guid[100];
memset(guid, 0, 100*sizeof(WCHAR));
StringFromGUID2(pmt->subtype, guid, 100);
if(CStringW(guid).MakeUpper().Find(L"0000-0010-8000-00AA00389B71") >= 0)
{
str.Format(_T("0x%04x"), pmt->subtype.Data1);
}
return(str);
}
switch(wfe->wFormatTag)
{
case 1:
str = _T("PCM ");
break;
default:
str.Format(_T("0x%03x "), wfe->wFormatTag);
break;
}
return(str);
}
CString MakeDimensionName(CAudFormatElem* pfe)
{
CString str(_T("Unknown"));
if(!pfe) return(str);
WAVEFORMATEX* wfe = (pfe->mt.formattype == FORMAT_WaveFormatEx)
? (WAVEFORMATEX*)pfe->mt.pbFormat
: NULL;
if(!wfe) return(str);
str.Empty();
CString str2;
str2.Format(_T("%6dKHz "), wfe->nSamplesPerSec);
str += str2;
str2.Format(_T("%dbps "), wfe->wBitsPerSample);
str += str2;
switch(wfe->nChannels)
{
case 1:
str += _T("mono ");
break;
case 2:
str += _T("stereo ");
break;
default:
str2.Format(_T("%d channels "), wfe->nChannels);
str += str2;
break;
}
str2.Format(_T("%3dkbps "), wfe->nAvgBytesPerSec*8/1000);
str += str2;
return(str);
}
};
//
typedef struct
{
CComPtr pMoniker;
CComPtr pBF;
CString FriendlyName;
CComBSTR DisplayName;
} Codec;
typedef CAtlArray CCodecArray;
// CPlayerCaptureDialog dialog
class CPlayerCaptureDialog : public CResizableDialog //CDialog
{
//DECLARE_DYNAMIC(CPlayerCaptureDialog)
// video input
CStringW m_VidDisplayName;
CComPtr m_pAMVSC;
CComPtr m_pAMXB;
CComPtr m_pAMTuner;
CComPtr m_pAMVfwCD;
CVidFormatArray m_vfa;
// audio input
CStringW m_AudDisplayName;
CComPtr m_pAMASC;
CInterfaceArray m_pAMAIM;
CAudFormatArray m_afa;
// video codec
CCodecArray m_pVidEncArray;
CVidFormatArray m_vcfa;
// audio codec
CCodecArray m_pAudEncArray;
CAudFormatArray m_acfa;
void EmptyVideo();
void EmptyAudio();
void UpdateMediaTypes();
void UpdateUserDefinableControls();
void UpdateVideoCodec();
void UpdateAudioCodec();
void UpdateMuxer();
void UpdateOutputControls();
void UpdateGraph();
CMap m_wndenabledmap;
void EnableControls(CWnd* pWnd, bool fEnable);
bool m_fEnableOgm;
public:
CPlayerCaptureDialog(); // standard constructor
virtual ~CPlayerCaptureDialog();
BOOL Create(CWnd* pParent = NULL);
// Dialog Data
enum { IDD = IDD_CAPTURE_DLG };
CComboBox m_vidinput;
CComboBox m_vidtype;
CComboBox m_viddimension;
CSpinButtonCtrl m_vidhor;
CSpinButtonCtrl m_vidver;
CEdit m_vidhoredit;
CEdit m_vidveredit;
CFloatEdit m_vidfpsedit;
float m_vidfps;
CButton m_vidsetres;
CComboBox m_audinput;
CComboBox m_audtype;
CComboBox m_auddimension;
CComboBox m_vidcodec;
CComboBox m_vidcodectype;
CComboBox m_vidcodecdimension;
BOOL m_fVidOutput;
CButton m_vidoutput;
int m_fVidPreview;
CButton m_vidpreview;
CComboBox m_audcodec;
CComboBox m_audcodectype;
CComboBox m_audcodecdimension;
BOOL m_fAudOutput;
CButton m_audoutput;
int m_fAudPreview;
CButton m_audpreview;
int m_nVidBuffers;
int m_nAudBuffers;
CString m_file;
CButton m_recordbtn;
BOOL m_fSepAudio;
int m_muxtype;
CComboBox m_muxctrl;
CMediaType m_mtv, m_mta, m_mtcv, m_mtca;
CComPtr m_pVidEnc, m_pAudEnc, m_pMux, m_pDst, m_pAudMux, m_pAudDst;
CComPtr m_pVidEncMoniker, m_pAudEncMoniker;
CComPtr m_pVidBuffer, m_pAudBuffer;
public:
void SetupVideoControls(CStringW DisplayName, IAMStreamConfig* pAMSC, IAMCrossbar* pAMXB, IAMTVTuner* pAMTuner);
void SetupVideoControls(CStringW DisplayName, IAMStreamConfig* pAMSC, IAMVfwCaptureDialogs* pAMVfwCD);
void SetupAudioControls(CStringW DisplayName, IAMStreamConfig* pAMSC, CInterfaceArray& pAMAIM);
bool IsTunerActive();
bool SetVideoInput(int input);
bool SetVideoChannel(int channel);
bool SetAudioInput(int input);
int GetVideoInput();
int GetVideoChannel();
int GetAudioInput();
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual BOOL PreTranslateMessage(MSG* pMsg);
virtual BOOL OnInitDialog();
virtual void OnOK() {}
virtual void OnCancel() {}
DECLARE_MESSAGE_MAP()
public:
afx_msg void OnDestroy();
afx_msg void OnVideoInput();
afx_msg void OnVideoType();
afx_msg void OnVideoDimension();
afx_msg void OnOverrideVideoDimension();
afx_msg void OnAudioInput();
afx_msg void OnAudioType();
afx_msg void OnAudioDimension();
afx_msg void OnRecordVideo();
afx_msg void OnVideoCodec();
afx_msg void OnVideoCodecType();
afx_msg void OnVideoCodecDimension();
afx_msg void OnRecordAudio();
afx_msg void OnAudioCodec();
afx_msg void OnAudioCodecType();
afx_msg void OnAudioCodecDimension();
afx_msg void OnOpenFile();
afx_msg void OnRecord();
afx_msg void OnEnChangeEdit9();
afx_msg void OnEnChangeEdit12();
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnBnClickedVidAudPreview();
afx_msg void OnBnClickedCheck7();
afx_msg void OnCbnSelchangeCombo14();
};