?? dsrecv.cpp
字號(hào):
//------------------------------------------------------------------------------
// File: DSRecv.cpp
//
// Desc: DirectShow sample code - implementation of DSNetwork sample filters
//
// Copyright (c) 2000-2002 Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
#include "precomp.h"
#include "le.h"
#include "nutil.h"
#include "dsnetifc.h"
#include "buffpool.h"
#include "netrecv.h"
#include "dsrecv.h"
#include "mspool.h"
#include "alloc.h"
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
CNetOutputPin::CNetOutputPin (
IN TCHAR * szName,
IN CBaseFilter * pFilter,
IN CCritSec * pLock,
OUT HRESULT * pHr,
IN LPCWSTR pszName
) : CBaseOutputPin (szName,
pFilter,
pLock,
pHr,
pszName
)
{
}
CNetOutputPin::~CNetOutputPin (
)
{
}
HRESULT
CNetOutputPin::GetMediaType (
IN int iPosition,
OUT CMediaType * pmt
)
{
HRESULT hr ;
if (iPosition == 0) {
ASSERT (pmt) ;
pmt -> InitMediaType () ;
////////修改了DSnetwork原有的MPEG2的MEDIATYPE和MEDIASUBTYPE, 注意DIVX是在dsrecv.h定義的GUID
pmt -> SetType (& MEDIATYPE_Video) ;
pmt -> SetSubtype (& DIVX) ;
////////設(shè)置outputpin的Format
VIDEOINFO *pvi = (VIDEOINFO *) pmt->AllocFormatBuffer(sizeof(VIDEOINFO));
ZeroMemory(pvi, sizeof(VIDEOINFO));
DWORD fccXvid = '3VID';
pvi->bmiHeader.biCompression = fccXvid;
pvi->bmiHeader.biBitCount = 24;
pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pvi->bmiHeader.biWidth = 320;
pvi->bmiHeader.biHeight = 240;
//pvi->bmiHeader.biPlanes = 1;
pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
SetRectEmpty(&(pvi->rcSource));
SetRectEmpty(&(pvi->rcTarget));
pmt->SetFormatType(&FORMAT_VideoInfo);
//pmt->SetTemporalCompression(FALSE);
pmt->SetSampleSize(pvi->bmiHeader.biSizeImage);
///////////////////////////
hr = S_OK ;
}
else {
hr = VFW_S_NO_MORE_ITEMS ;
}
return hr ;
}
HRESULT
CNetOutputPin::CheckMediaType (
IN const CMediaType * pmt
)
{
HRESULT hr ;
ASSERT (pmt) ;
////////去除check功能
/*
if (pmt -> majortype == MEDIATYPE_Video &&
pmt -> subtype == DIVX) {
hr = S_OK ;
}
else {
hr = S_FALSE ;
}
return hr ;
*/
return S_OK;
}
HRESULT
CNetOutputPin::InitAllocator (
OUT IMemAllocator ** ppAlloc
)
{
(* ppAlloc) = NET_RECV (m_pFilter) -> GetRecvAllocator () ;
(* ppAlloc) -> AddRef () ;
return S_OK ;
}
HRESULT
CNetOutputPin::DecideBufferSize (
IN IMemAllocator * pIMemAllocator,
OUT ALLOCATOR_PROPERTIES * pProp
)
{
HRESULT hr ;
if (pIMemAllocator == NET_RECV (m_pFilter) -> GetRecvAllocator ()) {
// we're the allocator; get the properties and succeed
hr = NET_RECV (m_pFilter) -> GetRecvAllocator () -> GetProperties (pProp) ;
}
else {
// this is not our allocator; fail the call
hr = E_FAIL ;
}
return hr ;
}
// ---------------------------------------------------------------------------
// ---------------------------------------------------------------------------
CNetworkReceiverFilter::CNetworkReceiverFilter (
IN TCHAR * tszName,
IN LPUNKNOWN punk,
OUT HRESULT * phr
) : CBaseFilter (
tszName,
punk,
& m_crtFilterLock,
CLSID_DSNetSend
),
CPersistStream (punk,
phr
),
m_pOutput (NULL),
m_pIMemAllocator (NULL),
m_ulIP ((unsigned long) UNDEFINED),
m_ulNIC ((unsigned long) UNDEFINED),
m_pBufferPool (NULL),
m_pNetReceiver (NULL),
m_pMSPool (NULL),
m_pNetRecvAlloc (NULL)
{
// instantiate the output pin
m_pOutput = new CNetOutputPin (
NAME ("CNetOutputPin"),
this,
& m_crtFilterLock,
phr,
L"DIVX" //修改
) ;
if (m_pOutput == NULL ||
FAILED (* phr)) {
(* phr) = (FAILED (* phr) ? * phr : E_OUTOFMEMORY) ;
return ;
}
// the buffer pool
m_pBufferPool = new CBufferPool (POOL_SIZE, MAX_IOBUFFER_LENGTH, phr) ;
if (m_pBufferPool == NULL ||
FAILED (*phr)) {
(* phr) = (FAILED (* phr) ? * phr : E_OUTOFMEMORY) ;
return ;
}
// the receiver object
m_pNetReceiver = new CNetReceiver (m_pBufferPool, this, phr) ;
if (m_pNetReceiver == NULL ||
FAILED (*phr)) {
(* phr) = (FAILED (* phr) ? * phr : E_OUTOFMEMORY) ;
return ;
}
// the media sample pool
m_pMSPool = new CTSMediaSamplePool (MEDIA_SAMPLE_POOL_SIZE, this, phr) ;
if (m_pMSPool == NULL ||
FAILED (*phr)) {
(* phr) = (FAILED (* phr) ? * phr : E_OUTOFMEMORY) ;
return ;
}
// IMemAllocator
m_pNetRecvAlloc = new CNetRecvAlloc (m_pBufferPool, m_pMSPool, this) ;
if (m_pNetRecvAlloc == NULL) {
(* phr) = E_OUTOFMEMORY ;
return ;
}
}
CNetworkReceiverFilter::~CNetworkReceiverFilter ()
{
delete m_pNetReceiver ;
delete m_pOutput ;
RELEASE_AND_CLEAR (m_pIMemAllocator) ;
delete m_pBufferPool ;
delete m_pMSPool ;
delete m_pNetRecvAlloc ;
}
CBasePin *
CNetworkReceiverFilter::GetPin (
IN int Index
)
{
CBasePin * pPin ;
LockFilter () ;
if (Index == 0) {
pPin = m_pOutput ;
}
else {
pPin = NULL ;
}
UnlockFilter () ;
return pPin ;
}
STDMETHODIMP
CNetworkReceiverFilter::Pause (
)
{
HRESULT hr ;
LockFilter () ;
if (m_ulIP == UNDEFINED ||
m_ulNIC == UNDEFINED) {
hr = E_FAIL ;
}
else if (m_State == State_Stopped) {
// --------------------------------------------------------------------
// stopped -> pause transition; get the filter up and running
// activate the receiver; joins the multicast group and starts the
// thread
hr = m_pNetReceiver -> Activate (m_ulIP, m_usPort, m_ulNIC) ;
if (SUCCEEDED (hr)) {
m_State = State_Paused ;
if (m_pOutput &&
m_pOutput -> IsConnected ()) {
m_pOutput -> Active () ;
}
}
}
else {
// --------------------------------------------------------------------
// run -> pause transition; do nothing but set the state
m_State = State_Paused ;
hr = S_OK ;
}
UnlockFilter () ;
return hr ;
}
STDMETHODIMP
CNetworkReceiverFilter::Stop (
)
{
LockFilter () ;
// synchronous call to stop the receiver (leaves the multicast group
// and terminates the thread)
m_pNetReceiver -> Stop () ;
// if we have an output pin (we should) stop it
if (m_pOutput) {
m_pOutput -> Inactive () ;
}
m_State = State_Stopped ;
UnlockFilter () ;
return S_OK ;
}
CUnknown *
CNetworkReceiverFilter::CreateInstance (
IN LPUNKNOWN punk,
OUT HRESULT * phr
)
{
CNetworkReceiverFilter * pnf ;
(* phr) = S_OK ;
pnf = new CNetworkReceiverFilter (
NAME ("CNetworkReceiverFilter"),
punk,
phr
) ;
if (pnf == NULL ||
FAILED (* phr)) {
(* phr) = (FAILED (* phr) ? (* phr) : E_OUTOFMEMORY) ;
DELETE_RESET (pnf) ;
}
return pnf ;
}
STDMETHODIMP
CNetworkReceiverFilter::NonDelegatingQueryInterface (
IN REFIID riid,
OUT void ** ppv
)
{
// property pages
if (riid == IID_ISpecifyPropertyPages) {
return GetInterface (
(ISpecifyPropertyPages *) this,
ppv
) ;
}
// multicast config
else if (riid == IID_IMulticastConfig) {
return GetInterface (
(IMulticastConfig *) this,
ppv
) ;
}
// we do persist
else if (riid == IID_IPersistStream) {
return GetInterface (
(IPersistStream *) this,
ppv
) ;
}
// fallback - call the baseclass
else {
return CBaseFilter::NonDelegatingQueryInterface (riid, ppv) ;
}
}
STDMETHODIMP
CNetworkReceiverFilter::GetPages (
IN OUT CAUUID * pPages
)
{
HRESULT hr ;
pPages -> cElems = 1 ;
pPages -> pElems = (GUID *) CoTaskMemAlloc (pPages -> cElems * sizeof GUID) ;
if (pPages -> pElems) {
(pPages -> pElems) [0] = CLSID_IPMulticastRecvProppage ;
hr = S_OK ;
}
else {
hr = E_OUTOFMEMORY ;
}
return hr ;
}
STDMETHODIMP
CNetworkReceiverFilter::SetNetworkInterface (
IN ULONG ulNIC
)
{
HRESULT hr ;
LockFilter () ;
if (m_State != State_Stopped) {
hr = E_UNEXPECTED ;
}
else if (IsUnicastIP (ulNIC) ||
ulNIC == INADDR_ANY) {
m_ulNIC = ulNIC ;
hr = S_OK ;
}
else {
hr = E_INVALIDARG ;
}
UnlockFilter () ;
return hr ;
}
STDMETHODIMP
CNetworkReceiverFilter::GetNetworkInterface (
OUT ULONG * pulNIC
)
{
HRESULT hr ;
LockFilter () ;
if (pulNIC) {
(* pulNIC) = m_ulNIC ;
hr = S_OK ;
}
else {
hr = E_INVALIDARG ;
}
UnlockFilter () ;
return hr ;
}
STDMETHODIMP
CNetworkReceiverFilter::SetMulticastGroup (
IN ULONG ulIP,
IN USHORT usPort
)
{
HRESULT hr ;
LockFilter () ;
if (m_State != State_Stopped) {
hr = E_UNEXPECTED ;
}
else if (IsMulticastIP (ulIP)) {
m_ulIP = ulIP ;
m_usPort = usPort ;
hr = S_OK ;
}
else {
hr = E_INVALIDARG ;
}
UnlockFilter () ;
return hr ;
}
STDMETHODIMP
CNetworkReceiverFilter::GetMulticastGroup (
OUT ULONG * pIP,
OUT USHORT * pPort
)
{
HRESULT hr ;
LockFilter () ;
if (pIP &&
pPort) {
(* pIP) = m_ulIP ;
(* pPort) = m_usPort ;
hr = S_OK ;
}
else {
hr = E_INVALIDARG ;
}
UnlockFilter () ;
return hr ;
}
STDMETHODIMP
CNetworkReceiverFilter::GetClassID (
OUT CLSID * pCLSID
)
{
(* pCLSID) = CLSID_DSNetReceive ;
return S_OK ;
}
HRESULT
CNetworkReceiverFilter::WriteToStream (
IN IStream * pIStream
)
{
HRESULT hr ;
LockFilter () ;
hr = pIStream -> Write ((BYTE *) & m_ulIP, sizeof m_ulIP, NULL) ;
if (SUCCEEDED (hr)) {
hr = pIStream -> Write ((BYTE *) & m_usPort, sizeof m_usPort, NULL) ;
if (SUCCEEDED (hr)) {
hr = pIStream -> Write ((BYTE *) & m_ulNIC, sizeof m_ulNIC, NULL) ;
}
}
UnlockFilter () ;
return hr ;
}
HRESULT
CNetworkReceiverFilter::ReadFromStream (
IN IStream * pIStream
)
{
HRESULT hr ;
LockFilter () ;
hr = pIStream -> Read ((BYTE *) & m_ulIP, sizeof m_ulIP, NULL) ;
if (SUCCEEDED (hr)) {
hr = pIStream -> Read ((BYTE *) & m_usPort, sizeof m_usPort, NULL) ;
if (SUCCEEDED (hr)) {
hr = pIStream -> Read ((BYTE *) & m_ulNIC, sizeof m_ulNIC, NULL) ;
}
}
UnlockFilter () ;
return hr ;
}
void
CNetworkReceiverFilter::ProcessBuffer (
IN CBuffer * pBuffer
)
{
HRESULT hr ;
IMediaSample2 * pIMediaSample ;
ASSERT (pBuffer) ;
hr = m_pMSPool -> GetMediaSampleSynchronous (
pBuffer,
pBuffer -> GetBuffer (),
pBuffer -> GetPayloadLength (),
& pIMediaSample
) ;
if (SUCCEEDED (hr)) {
ASSERT (pIMediaSample) ;
m_pOutput -> Deliver (pIMediaSample) ;
pIMediaSample -> Release () ;
}
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -