// ServerDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Server.h"
#include "ServerDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
#define ID_PAUSE_STATE_PAUSE "Pause"
#define ID_PAUSE_STATE_RUN "Run"
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CServerDlg dialog
CServerDlg::CServerDlg(CWnd* pParent /*=NULL*/)
: CDialog(CServerDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CServerDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_pWriter2 = NULL;
m_pNetSink = NULL;
m_pProvider = NULL;
m_pGraph=NULL;
}
void CServerDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CServerDlg)
DDX_Control(pDX, IDC_STATIC_URL, m_StaticUrl);
DDX_Control(pDX, IDC_EDIT_PORT, m_EditPort);
DDX_Control(pDX, IDC_BUTTON_STOP, m_btnStop);
DDX_Control(pDX, IDC_BUTTON_PAUSE, m_btnPause);
DDX_Control(pDX, IDC_BUTTON_START, m_btnStart);
DDX_Control(pDX, IDC_COMBO_AUDEO_DEVICES, m_CboAudioDevices);
DDX_Control(pDX, IDC_COMBO_VIDEO_DEVICES, m_CboVideoDevices);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CServerDlg, CDialog)
//{{AFX_MSG_MAP(CServerDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDC_BUTTON_START, OnButtonStart)
ON_BN_CLICKED(IDC_BUTTON_PAUSE, OnButtonPause)
ON_BN_CLICKED(IDC_BUTTON_STOP, OnButtonStop)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CServerDlg message handlers
BOOL CServerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
GetVideoDevices("",NULL);//Fill video device combo
GetAudeoDevices("",NULL);//Fill audeo device combo
return TRUE; // return TRUE unless you set the focus to a control
}
void CServerDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CServerDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CServerDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CServerDlg::OnButtonStart()
{
if(StartStreaming())
{
m_btnStart.EnableWindow(FALSE);
m_btnPause.EnableWindow(TRUE);
m_btnStop.EnableWindow(TRUE);
AfxMessageBox("Streaming started successfully");
}
else
{
AfxMessageBox("Start streaming failed");
}
}
CServerDlg::GetVideoDevices(CString strDevName,IBaseFilter **pFilter)
{
try
{
CoInitialize(NULL);
int id = 0;
ULONG cRetrieved;
IMoniker *pM;
// enumerate all video capture devices
CComPtr<ICreateDevEnum> pCreateDevEnum;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void**)&pCreateDevEnum);
if (FAILED(hr))
{
return FALSE;
}
CComPtr<IEnumMoniker> pEm;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
&pEm, 0);
if (FAILED(hr))
{
return FALSE;
}
pEm->Reset();
while(hr = pEm->Next(1, &pM, &cRetrieved), hr==S_OK)
{
IPropertyBag *pBag;
hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
if(SUCCEEDED(hr))
{
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName", &var, NULL);
if (hr == NOERROR)
{
TCHAR strdev[2048];
WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, strdev, 2048, NULL, NULL);
if(strDevName=="")
{
m_CboVideoDevices.AddString(strdev);
}
else
{
if(strDevName==strdev)
{
pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter);
break;
}
}
SysFreeString(var.bstrVal);
}
pBag->Release();
}
pM->Release();
}
return TRUE;
}
catch(...)
{
return FALSE;
}
}
CServerDlg::GetAudeoDevices(CString strDevName,IBaseFilter **pFilter)
{
try
{
CoInitialize(NULL);
int id = 0;
ULONG cRetrieved;
IMoniker *pM;
// enumerate all video capture devices
CComPtr<ICreateDevEnum> pCreateDevEnum;
HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
IID_ICreateDevEnum, (void**)&pCreateDevEnum);
if (hr != NOERROR)
{
return FALSE;
}
CComPtr<IEnumMoniker> pEm;
hr = pCreateDevEnum->CreateClassEnumerator(CLSID_AudioInputDeviceCategory,
&pEm, 0);
if (hr != NOERROR)
{
return FALSE;
}
pEm->Reset();
while(hr = pEm->Next(1, &pM, &cRetrieved), hr==S_OK)
{
IPropertyBag *pBag;
hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
if(SUCCEEDED(hr))
{
VARIANT var;
var.vt = VT_BSTR;
hr = pBag->Read(L"FriendlyName", &var, NULL);
if (hr == NOERROR)
{
TCHAR strDev[2048];
WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, strDev, 2048, NULL, NULL);
if(strDevName=="")
{
m_CboAudioDevices.AddString(strDev);
}
else
{
if(strDevName==strDev)
{
pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter);
break;
}
}
SysFreeString(var.bstrVal);
}
pBag->Release();
}
pM->Release();
}
return TRUE;
}
catch(...)
{
return FALSE;
}
}
HRESULT CServerDlg::ConnectFilters(IGraphBuilder *pGraph,
IBaseFilter *pFirst, IBaseFilter *pSecond)
{
try
{
//CString strAsfVideoPin="Video Input 01";
IPin *pOut = NULL, *pIn = NULL;
HRESULT hr = GetPin(pSecond, PINDIR_INPUT, &pIn);
if (FAILED(hr)) return hr;
// The previous filter may have multiple outputs, so try each one!
IEnumPins *pEnum;
pFirst->EnumPins(&pEnum);
while(pEnum->Next(1, &pOut, 0) == S_OK)
{
PIN_DIRECTION PinDirThis;
pOut->QueryDirection(&PinDirThis);
if (PINDIR_OUTPUT == PinDirThis)
{
hr = pGraph->Connect(pOut, pIn);
switch(hr)
{
case S_OK:
break;
case VFW_S_PARTIAL_RENDER:
AfxMessageBox("VFW_S_PARTIAL_RENDER");
break;
case E_ABORT:
AfxMessageBox("E_ABORT");
break;
case E_POINTER:
AfxMessageBox("E_POINTER");
break;
case VFW_E_CANNOT_CONNECT:
AfxMessageBox("VFW_E_CANNOT_CONNECT");
break;
case VFW_E_NOT_IN_GRAPH:
AfxMessageBox("VFW_E_NOT_IN_GRAPH");
break;
}
if(!FAILED(hr))
{
break;
}
}
pOut->Release();
}
pEnum->Release();
pIn->Release();
pOut->Release();
return hr;
}
catch(...)
{
return -1;
}
}
HRESULT CServerDlg::GetPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin)
{
try
{
int i=0;
IEnumPins *pEnum;
IPin *pPin;
pFilter->EnumPins(&pEnum);
while(pEnum->Next(1, &pPin, 0) == S_OK)
{
PIN_DIRECTION PinDirThis;
pPin->QueryDirection(&PinDirThis);
if (PinDir == PinDirThis)
{
pEnum->Release();
*ppPin = pPin;
return S_OK;
}
pPin->Release();
}
pEnum->Release();
return E_FAIL;
}
catch(...)
{
return E_FAIL;
}
}
BOOL CServerDlg::StartStreaming()
{
///////////////////////////////////////////////////////////////////////////////////
//CREATING GRAPH
///////////////////////////////////////////////////////////////////////////////////
HRESULT hr = CoInitialize(NULL);
if(FAILED(hr))
return FALSE;
hr = CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, (void **)&m_pGraph);
if(FAILED(hr))
return FALSE;
///////////////////////////////////////////////////////////////////////////////////
/*///////////////////////////////////////////////////////
Get the Device and add to graph
///////////////////////////////////////////////////////*/
CString strVidDevName,strAudDevice;
m_CboVideoDevices.GetWindowText(strVidDevName);
m_CboAudioDevices.GetWindowText(strAudDevice);
if(!GetVideoDevices(strVidDevName, &m_pVidDeviceFilter))
return FALSE;
if(!GetAudeoDevices(strAudDevice, &m_pAudDeviceFilter))
return FALSE;
hr=m_pGraph->AddFilter(m_pVidDeviceFilter,L"Vid Capture Filter");
if(FAILED(hr))
return FALSE;
hr=m_pGraph->AddFilter(m_pAudDeviceFilter,L"Aud Capture Filter");
if(FAILED(hr))
return FALSE;
hr = CoCreateInstance(CLSID_WMAsfWriter,NULL,CLSCTX_INPROC_SERVER,
IID_IBaseFilter, (void **) &m_pWMASFWritter);
if(FAILED(hr))
return FALSE;
hr=m_pGraph->AddFilter(m_pWMASFWritter,L"ASF Writter");
if(FAILED(hr))
return FALSE;
hr = m_pWMASFWritter->QueryInterface( IID_IFileSinkFilter, (void**)&m_pFileSinkFilter );
if(FAILED(hr))
return FALSE;
hr = m_pFileSinkFilter->SetFileName(L"C:\\test.wmv", NULL);
if(FAILED(hr))
return FALSE;
if (FAILED(hr = m_pWMASFWritter->QueryInterface(IID_IServiceProvider, (void**)&m_pProvider)))
{
AfxMessageBox("Getting service provider failed");
return FALSE;
}
if (FAILED(hr = m_pProvider->QueryService(IID_IWMWriterAdvanced2, IID_IWMWriterAdvanced2, (void**)&m_pWriter2)))
{
AfxMessageBox ("Query Service form IServiceProvider failed");
return FALSE;
}
if (FAILED(hr = m_pWriter2->SetLiveSource(TRUE)))
{
AfxMessageBox ("Setting live source failed");
return FALSE;
}
if (FAILED(hr = m_pWriter2->RemoveSink(0)))//For the time being we removing the default sink...
{
AfxMessageBox (" Remove Sink failed");
return FALSE;
}
m_pProvider->Release();
if (FAILED(hr = WMCreateWriterNetworkSink(&m_pNetSink)))
{
AfxMessageBox ("WMCreateWriterNetworkSink failed");
return FALSE;
}
CString strPort="";
m_EditPort.GetWindowText(strPort);
DWORD dwPort = 8080;
if(strPort!="")
{
dwPort=atoi(strPort);
}
if (FAILED(hr = m_pNetSink->Open(&dwPort)))
{
AfxMessageBox ("Port opening failed");
return FALSE;
}
WCHAR url[256];
DWORD len = 256;
hr = m_pNetSink->GetHostURL(url, &len);
if(SUCCEEDED(hr))
{
CString strUrl(url);
m_StaticUrl.SetWindowText(strUrl);
}
if (FAILED(m_pWriter2->AddSink(m_pNetSink)))
{
AfxMessageBox ("AddSink failed");
return FALSE;
}
///////////////////////////////////////////////////////////////////////////
//Run the graph
///////////////////////////////////////////////////////////////////////////
hr=ConnectFilters(m_pGraph, m_pVidDeviceFilter,m_pWMASFWritter,"Video Input 01");
if(FAILED(hr))
return FALSE;
hr=ConnectFilters(m_pGraph, m_pAudDeviceFilter,m_pWMASFWritter);
if(FAILED(hr))
return FALSE;
hr = m_pGraph->QueryInterface(IID_IMediaControl, (void **)&m_pMediaControl);
if(FAILED(hr))
return FALSE;
hr = m_pGraph->QueryInterface(IID_IMediaEvent, (void **)&m_pEvent);
if(FAILED(hr))
return FALSE;
hr = m_pMediaControl -> Run( );
if(FAILED(hr))
{
AfxMessageBox ("Media Control Run failed");
return FALSE;
}
long evCode=0;
//hr=pEvent->WaitForCompletion(INFINITE, &evCode); // Wait till its done.
return TRUE;
}
IPin* CServerDlg::GetPinByName(IBaseFilter *pFilter, LPCOLESTR pinname)
{
try
{
// GET PIN BY NAME
IEnumPins* pEnum;
IPin* pPin;
HRESULT hr = pFilter->EnumPins(&pEnum);
if (FAILED(hr))
return NULL;
while(pEnum->Next(1, &pPin, 0) == S_OK)
{
PIN_INFO pinfo;
pPin->QueryPinInfo(&pinfo);
BOOL found = !_wcsicmp(pinname, pinfo.achName);
if (pinfo.pFilter)
pinfo.pFilter->Release();
if (found)
{
return pPin;
};
pPin->Release();
}
return NULL;
}
catch(...)
{
return NULL;
}
}
HRESULT CServerDlg::ConnectFilters(IGraphBuilder *pGraph,
IBaseFilter *pFirst, IBaseFilter *pSecond,CString strAsfFilterPin)
{
try
{
IPin *pOut = NULL, *pIn = NULL;
HRESULT hr=0;
//HRESULT hr = GetPin(pSecond, PINDIR_INPUT, &pIn);
pIn=GetPinByName(pSecond,strAsfFilterPin.AllocSysString()); //Get pin by name...
if (FAILED(hr)) return hr;
// The previous filter may have multiple outputs, so try each one!
IEnumPins *pEnum;
pFirst->EnumPins(&pEnum);
while(pEnum->Next(1, &pOut, 0) == S_OK)
{
PIN_DIRECTION PinDirThis;
pOut->QueryDirection(&PinDirThis);
if (PINDIR_OUTPUT == PinDirThis)
{
hr = pGraph->Connect(pOut, pIn);
switch(hr)
{
case S_OK:
//AfxMessageBox("Connection Success");
break;
case VFW_S_PARTIAL_RENDER:
AfxMessageBox("VFW_S_PARTIAL_RENDER");
break;
case E_ABORT:
AfxMessageBox("E_ABORT");
break;
case E_POINTER:
AfxMessageBox("E_POINTER");
break;
case VFW_E_CANNOT_CONNECT:
AfxMessageBox("VFW_E_CANNOT_CONNECT");
break;
case VFW_E_NOT_IN_GRAPH:
AfxMessageBox("VFW_E_NOT_IN_GRAPH");
break;
}
if(!FAILED(hr))
{
break;
}
}
pOut->Release();
}
pEnum->Release();
pIn->Release();
pOut->Release();
return hr;
}
catch(...)
{
return -1;
}
}
void CServerDlg::OnButtonPause()
{
HRESULT hr=0;
CString strPauseState;
m_btnPause.GetWindowText(strPauseState);
if(strPauseState==ID_PAUSE_STATE_PAUSE)
{
if(m_pMediaControl)
{
hr=m_pMediaControl->Pause();
if(!(FAILED(hr)))
{
m_btnPause.SetWindowText(ID_PAUSE_STATE_RUN);
m_btnStop.EnableWindow(TRUE);
}
}
}
else if(strPauseState==ID_PAUSE_STATE_RUN)
{
if(m_pMediaControl)
{
hr=m_pMediaControl->Run();
if(!(FAILED(hr)))
{
m_btnPause.SetWindowText(ID_PAUSE_STATE_PAUSE);
m_btnStop.EnableWindow(TRUE);
}
}
}
}
void CServerDlg::OnButtonStop()
{
HRESULT hr=0;
if(m_pMediaControl)
{
hr=m_pMediaControl->Stop();
if((!FAILED(hr)))
{
m_btnPause.EnableWindow(FALSE);
m_btnStop.EnableWindow(FALSE);
m_btnStart.EnableWindow(FALSE);
}
}
}