📄 rmsource.cpp
字号:
//==========================================================================;
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
// PURPOSE.
//
// Copyright (c) 1997 Sigma Designs.
//
// fsource.cpp
//
// Source Filter RTSP - Sends data from a RTSP server to a pin.
// Uses the "push" model for data transfer.
//
//--------------------------------------------------------------------------;
#include "osinc.h"
#include "os.h"
#include <streams.h>
#include <olectl.h>
#include <initguid.h>
#include <commdlg.h>
#include "irtsp.h"
#include "rmsource.h"
#include "rtspprop.h"
// Setup data
//////////////////////////////////////////////////////////////////////////
const AMOVIESETUP_MEDIATYPE sudOpPinTypes =
{
&MEDIATYPE_Stream, // Major type
&MEDIASUBTYPE_NULL // Minor type
};
const AMOVIESETUP_PIN sudOpPin =
{
L"Output", // Pin string name
FALSE, // Is it rendered
TRUE, // Is it an output
FALSE, // Can we have none
FALSE, // Can we have many
&CLSID_NULL, // Connects to filter
NULL, // Connects to pin
1, // Number of types
&sudOpPinTypes }; // Pin details
const AMOVIESETUP_FILTER sudax =
{
&CLSID_RMSourceFilter, // Filter CLSID
L"Sigma Designs RTSP Push Filter", // String name
MERIT_DO_NOT_USE, // Filter merit
1, // Number pins
&sudOpPin // Pin details
};
// COM global table of objects in this dll
CFactoryTemplate g_Templates[] = {
{ L"Sigma Designs RTSP Push Filter"
, &CLSID_RMSourceFilter
, CRMSource::CreateInstance
, NULL
, &sudax }
,
{ L"RTSP Property Page"
, &CLSID_RTSPPropertyPage
, CRTSPPropertyPage::CreateInstance }
};
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
// DllRegisterServer
// Exported entry points for registration and unregistration
//////////////////////////////////////////////////////////////////////////
STDAPI DllRegisterServer()
{
return AMovieDllRegisterServer2( TRUE );
} // DllRegisterServer
// DllUnregisterServer
//////////////////////////////////////////////////////////////////////////
STDAPI DllUnregisterServer()
{
return AMovieDllRegisterServer2( FALSE );
} // DllUnregisterServer
// CreateInstance
//////////////////////////////////////////////////////////////////////////
CUnknown * WINAPI CRMSource::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr)
{
CUnknown *punk = new CRMSource(lpunk, phr);
if (punk == NULL) {
*phr = E_OUTOFMEMORY;
}
return punk;
} // CreateInstance
// Constructor
// Initialise a CRMSourceStream object so that we have a pin.
//////////////////////////////////////////////////////////////////////////
CRMSource::CRMSource(LPUNKNOWN lpunk, HRESULT *phr) :
CSource(NAME("Sigma Designs RTSP Push Filter"),
lpunk,
CLSID_RMSourceFilter)
,CPersistStream(lpunk, phr)
{
CAutoLock cAutoLock(&m_cStateLock);
m_paStreams = (CSourceStream **) new CRMSourceStream*[1];
if (m_paStreams == NULL) {
*phr = E_OUTOFMEMORY;
return;
}
m_paStreams[0] = new CRMSourceStream(phr, this, L"Output");
if (m_paStreams[0] == NULL) {
*phr = E_OUTOFMEMORY;
return;
}
m_pCrmSourceStream = (CRMSourceStream *)m_paStreams[0];
m_pCrmSourceStream->m_pConnParams->cont_type = MPEG1;
m_pCrmSourceStream->outpin = (IPin *) m_paStreams[0];
// m_bDirty = FALSE;
} // (Constructor)
//////////////////////////////////////////////////////////////////////////
CRMSource::~CRMSource ()
{
}
#define MAXFILENAME 256 // maximum length of file pathname
//
// Constructor
//////////////////////////////////////////////////////////////////////////
CRMSourceStream::CRMSourceStream(HRESULT *phr,
CRMSource *pParent,
LPCWSTR pPinName) :
CSourceStream(NAME("Sigma Designs RTSP Push Filter"),phr, pParent, pPinName),
m_pAlloc(NULL),
m_bInit(FALSE)
{
m_pConnParams = (CONN_DATA*) malloc(sizeof(CONN_DATA));
ASSERT(pParent);
m_pRMSource = pParent;
m_pConnParams->finished = 0;
memcpy(m_pConnParams->mpg_Tpe[MPEG1], (void *)"OGF/OGP\0", 8);
memcpy(m_pConnParams->mpg_Tpe[MPEG2], (void *)"MP2T/H2221\0", 11);
// m_pConnParams->rmprops.servertype = OVS;
// OSstrcpy(m_pConnParams->sServerIp, "172.30.5.153");
// OSstrcpy
// (m_pConnParams->rmprops.browseinfo,"rtsp://172.30.5.153/asset/mds:lair.mpi");
CreateRtspInstance((void**)&pIRtsp);
CreateSockInstance((void**)&(m_pConnParams->pISock));
ISock_SocketStartup(m_pConnParams->pISock);
m_RTPsock = NULL;
// dataout = fopen("tempff.mpg","wb");
} // (Constructor)
//
// Destructor
//////////////////////////////////////////////////////////////////////////
CRMSourceStream::~CRMSourceStream()
{
IRtsp_Close(pIRtsp, m_pConnParams);
// if OVS, we have to terminate the ping thread
if (m_pConnParams->rmprops.servertype == OVS)
{
DEBUG_PRINT(("\nClosing ping"));
// wait for thead to terminate
SetEvent (m_Event);
WaitForSingleObject (m_hPingThread, INFINITE);
CloseHandle (m_Event);
CloseHandle(m_hPingThread);
// ok thread has exited for sure
}
Sleep(1); // don't know why, but the sleep(1) seems necessary...
m_pConnParams->socket = NULL;
if (m_pAlloc != NULL)
{
m_pAlloc->Release ();
m_pAlloc = NULL;
}
ISock_SocketShutDown(m_pConnParams->pISock);
DeleteSockInstance(m_pConnParams->pISock);
DeleteRtspInstance(pIRtsp);
DEBUG_PRINT(("\nThreads are destroyed"));
// fclose(dataout);
free(m_pConnParams);
OutputDebugString("\nDestroyed");
} // (Destructor)
/*****************************************************************************************
* OSKeepAlive - pings the server regularly to avoid timeouts *
* *
* input: pointer to the CONN_DATA structure *
* output: 0 *
*****************************************************************************************/
DWORD WINAPI OSKeepAlive(void* local_struct)
{
int status;
DWORD retval;
CRMSourceStream *pRMSourceStream = (CRMSourceStream *)local_struct;
do
{
// wait for an exit event or a time out
retval = WaitForSingleObject (pRMSourceStream->m_Event, pRMSourceStream->m_pConnParams->dwTimeOut * 1000);
if (retval == WAIT_OBJECT_0)
{
// event set
break;
}
else if (retval == WAIT_TIMEOUT)
{
// ping - assumes this does NOT block
status = IRtsp_Ping(pRMSourceStream->pIRtsp, pRMSourceStream->m_pConnParams);
}
}
while (status == 200); // while the session is still active
// if the session is not any more active, the server will
// respond "RTSP/1.0 454 Session Not Found ...."
DEBUG_PRINT( ("\ndone!"));
return 0;
}
//////////////////////////////////////////////////////////////////////////
STDMETHODIMP CRMSource::GetPages(CAUUID * pPages)
{
pPages->cElems = 1;
pPages->pElems = (GUID *) CoTaskMemAlloc(pPages->cElems * sizeof(GUID));
if (pPages->pElems == NULL)
return E_OUTOFMEMORY;
pPages->pElems[0] = CLSID_RTSPPropertyPage;
return NOERROR;
}
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CRMSource::Load( IPropertyBag __RPC_FAR *pPropBag,
IErrorLog __RPC_FAR *pErrorLog)
{
CAutoLock l(&m_cStateLock);
VARIANT v_path, v_type, v_addr;
wchar_t w_prop_name[30];
v_path.vt = VT_BSTR;
v_type.vt = VT_INT;
v_addr.vt = VT_BSTR;
mbstowcs(w_prop_name,"RTSP path property",sizeof("RTSP path property"));
pPropBag->Read(w_prop_name,&v_path,pErrorLog);
wcstombs(m_pCrmSourceStream->m_pConnParams->rmprops.browseinfo,v_path.bstrVal,
sizeof(m_pCrmSourceStream->m_pConnParams->rmprops.browseinfo));
SysFreeString(v_path.bstrVal);
mbstowcs(w_prop_name,"RTSP type property",sizeof("RTSP type property"));
pPropBag->Read(w_prop_name,&v_type,pErrorLog);
m_pCrmSourceStream->m_pConnParams->rmprops.servertype = v_type.intVal;
mbstowcs(w_prop_name,"RTSP addr property",sizeof("RTSP addr property"));
pPropBag->Read(w_prop_name,&v_addr,pErrorLog);
wcstombs(m_pCrmSourceStream->m_pConnParams->rmprops.serverIp,v_addr.bstrVal,
sizeof(m_pCrmSourceStream->m_pConnParams->rmprops.serverIp));
SysFreeString(v_addr.bstrVal);
SetDirty(TRUE);
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CRMSource::Save(
IPropertyBag __RPC_FAR *pPropBag,
BOOL fClearDirty,
BOOL fSaveAllProperties)
{
CAutoLock l(&m_cStateLock);
VARIANT v_path, v_type, v_addr;
wchar_t w_prop_name[30],temp[1024];
v_path.vt = VT_BSTR;
v_type.vt = VT_INT;
v_addr.vt = VT_BSTR;
mbstowcs(w_prop_name,"RTSP path property",sizeof("RTSP path property"));
mbstowcs(temp,m_pCrmSourceStream->m_pConnParams->rmprops.browseinfo,
sizeof(m_pCrmSourceStream->m_pConnParams->rmprops.browseinfo));
v_path.bstrVal = SysAllocString(temp);
pPropBag->Write(w_prop_name,&v_path);
SysFreeString(v_path.bstrVal);
mbstowcs(w_prop_name,"RTSP type property",sizeof("RTSP type property"));
v_type.intVal = m_pCrmSourceStream->m_pConnParams->rmprops.servertype;
pPropBag->Write(w_prop_name,&v_type);
mbstowcs(w_prop_name,"RTSP addr property",sizeof("RTSP addr property"));
mbstowcs(temp,m_pCrmSourceStream->m_pConnParams->rmprops.serverIp,
sizeof(m_pCrmSourceStream->m_pConnParams->rmprops.serverIp));
v_addr.bstrVal = SysAllocString(temp);
pPropBag->Write(w_prop_name,&v_addr);
SysFreeString(v_addr.bstrVal);
SetDirty(FALSE);
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CRMSourceStream::Load(
IPropertyBag __RPC_FAR *pPropBag,
IErrorLog __RPC_FAR *pErrorLog)
{
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CRMSourceStream::Save(
IPropertyBag __RPC_FAR *pPropBag,
BOOL fClearDirty,
BOOL fSaveAllProperties)
{
return S_OK;
}
// IPersistStream::ReadFromStream - read the entire parameter structure,
// but do not overwrite session-specific ones!
//////////////////////////////////////////////////////////////////////////
HRESULT CRMSource::ReadFromStream(IStream *pStream)
{
return S_OK;
}
// IPersistStream::WriteToStream - writes the entire parameter structure,
//////////////////////////////////////////////////////////////////////////
HRESULT CRMSource::WriteToStream(IStream *pStream)
{
return S_OK;
}
// we don't send any data during PAUSE, so to avoid hanging renderers, we
// need to return VFW_S_CANT_CUE when paused
//////////////////////////////////////////////////////////////////////////
STDMETHODIMP CRMSource::GetState(DWORD dwMSecs, FILTER_STATE *State)
{
UNREFERENCED_PARAMETER(dwMSecs);
CheckPointer(State,E_POINTER);
ValidateReadWritePtr(State,sizeof(FILTER_STATE));
*State = m_State;
if (m_State == State_Paused)
return VFW_S_CANT_CUE;
else
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CRMSource::SetPlayRate(DWORD rate)
{
if(m_pCrmSourceStream->m_pConnParams->cont_type == MPEG2)
{
IRtsp_Pause(m_pCrmSourceStream->pIRtsp, m_pCrmSourceStream->m_pConnParams);
IRtsp_SetPlayRate(m_pCrmSourceStream->pIRtsp, m_pCrmSourceStream->m_pConnParams,
(long)rate);
return S_OK;
}
return S_FALSE;
}
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CRMSource::MpegType()
{
return (m_pCrmSourceStream->m_pConnParams->cont_type);
}
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CRMSourceStream::get_ConnParams(CONN_DATA **pConnParams)
{
*pConnParams = m_pConnParams;
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CRMSourceStream::get_pRMSource(CRMSource **pRMSource)
{
*pRMSource = m_pRMSource;
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CRMSourceStream::get_pRMProps(CRMProps **pRMProps)
{
*pRMProps = &(m_pConnParams->rmprops);
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CRMSourceStream::get_pIRTSP(IRtsp **pIRTSP)
{
*pIRTSP = pIRtsp;
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CRMSourceStream::put_ConnParams(CONN_DATA connParams)
{
*m_pConnParams = connParams;
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CRMSourceStream::put_pRMSource(CRMSource crmSource)
{
m_pRMSource = &crmSource;
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CRMSourceStream::put_pRMProps(CRMProps rmProps)
{
m_pConnParams->rmprops = rmProps;
return S_OK;
}
//////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE CRMSourceStream::put_pIRTSP(IRtsp irtsp)
{
*pIRtsp = irtsp;
return S_OK;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -