⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rtspplayer.cpp

📁 神龙卡 SDK_84xx_DShow_145_02.zip 这个是 windows 上二个是linux
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************/
/* Created by Kevin Vo
*  Copyright Sigma Designs Inc
*  Sigma Designs Proprietary and confidential
*  Created on 3/12/2001
/************************************************************************/

#include "RtspPlayer.h"

RtspPlayer *g_pPlayer;

/////////////////////////////////////////////////////////////////////////////////////////

RtspPlayer::RtspPlayer(HWND hwnd)
{
	// Used by IVideoWindow interface to reposition the display window.
	m_hwnd = hwnd;

	m_dwPlayrate = 1;
	m_bTvOut = TRUE;
	m_iFullScreen = OATRUE;

	m_szIpAddr[0] = '\0';
	m_szPlayFileName[0] = '\0';
	m_szPlayFilePath[0] = '\0';
	m_szPlayFileFullPath[0] = '\0';
	m_szIniFile[0] = '\0';

	m_pIRmSourceFilter = NULL;
	m_pIGraphBuilder = NULL;
	m_pIMediaControl = NULL;
	m_pIMediaEventEx = NULL;
	m_pIVideoWindow = NULL;
	m_pIBasicVideo = NULL;
	m_pIPin = NULL;
	m_pIMediaFilter = NULL;
	m_pIRefClock = NULL;
	m_pITvVgaOut = NULL;
	m_pIRmSourceStreamEx = NULL;
}

/////////////////////////////////////////////////////////////////////////////////////////

RtspPlayer::~RtspPlayer()
{
	Uninitialize();
}

/////////////////////////////////////////////////////////////////////////////////////////

void RtspPlayer::Uninitialize()
{
	OutputDebugString("\nRtspPlayer Uninitialize");

	if (m_pIMediaControl != NULL)
	{
		m_pIMediaControl->Stop();
		m_pIMediaControl->Release();
	}
	if (m_pIVideoWindow != NULL)
	{
		m_pIVideoWindow->put_Visible(OAFALSE);
		m_pIVideoWindow->put_Owner(NULL);
		m_pIVideoWindow->Release();
	}
	if (m_pITvVgaOut != NULL)
	{
		m_pITvVgaOut->SetTvOutput(FALSE);
		m_pITvVgaOut->Release();
	}
	if (m_pIPin != NULL)			m_pIPin->Release();
	if (m_pIMediaFilter != NULL)	m_pIMediaFilter->Release();
	if (m_pIBasicVideo != NULL)		m_pIBasicVideo->Release();
	if (m_pIMediaEventEx != NULL)	m_pIMediaEventEx->Release();
	if (m_pIRmSourceFilter != NULL)	m_pIRmSourceFilter->Release();
	if (m_pIGraphBuilder != NULL)	m_pIGraphBuilder->Release();
	if (m_pIRmSourceStreamEx != NULL)	m_pIRmSourceStreamEx->Release();

	m_pIPin = NULL;
	m_pIMediaFilter = NULL;
	m_pIRmSourceFilter = NULL;
	m_pIBasicVideo = NULL;
	m_pIVideoWindow = NULL;
	m_pIGraphBuilder = NULL;
	m_pIMediaControl = NULL;
	m_pIMediaEventEx = NULL;
	m_pITvVgaOut = NULL;
	m_pIRmSourceStreamEx = NULL;
}

/////////////////////////////////////////////////////////////////////////////////////////

BOOL RtspPlayer::Initialize()
{
	HRESULT rt = 0;
	char str[50];

	OutputDebugString("\nRtspPlayer Initialize");

	CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, 
			IID_IGraphBuilder, (void **) &m_pIGraphBuilder);
	CoCreateInstance(CLSID_RMSourceFilter, NULL, CLSCTX_INPROC_SERVER, 
			IID_IBaseFilter, (void **) &m_pIRmSourceFilter);

//	m_pIRmSourceFilter->QueryInterface(IID_IMediaFilter, (void **)&m_pIMediaFilter);
	m_pIRmSourceFilter->QueryInterface(IID_IRMSourceStreamEx, (void **)&m_pIRmSourceStreamEx);

	// Initialize the RTSP
	m_pIRmSourceStreamEx->put_ConnectionParams(m_szIpAddr, m_iServerType, m_szPlayFileFullPath);
	rt = m_pIRmSourceStreamEx->StartRtsp();
	if (rt != S_OK)     // Start running the filter
	{
		wsprintf(str, "Unable to start...Error Code %d.", rt);
		MessageBox(m_hwnd, str, NULL, MB_OK);
		Uninitialize();
		return FALSE;
	}

	// Have the graph construct its the appropriate graph automatically
	m_pIGraphBuilder->AddFilter(m_pIRmSourceFilter, NULL);
	m_pIRmSourceFilter->FindPin(L"1", &m_pIPin);
	m_pIGraphBuilder->Render(m_pIPin);

	// QueryInterface for some basic interfaces
	m_pIGraphBuilder->QueryInterface(IID_IMediaControl, (void **)&m_pIMediaControl);
	m_pIGraphBuilder->QueryInterface(IID_IMediaEventEx, (void **)&m_pIMediaEventEx);
	m_pIGraphBuilder->QueryInterface(IID_IVideoWindow, (void **)&m_pIVideoWindow);

	// Have the graph signal event via window callbacks for performance
	m_pIMediaEventEx->SetNotifyWindow((OAHWND)m_hwnd, WM_GRAPHNOTIFY, 0);
	m_pIMediaEventEx->SetNotifyFlags(0);	// Turn on notifications

	// Hide window until displayed at correct position
	if (m_pIVideoWindow != NULL)
	{
		m_pIVideoWindow->put_AutoShow(OAFALSE);
		m_pIVideoWindow->put_WindowStyle(WS_CHILD);
		m_pIVideoWindow->put_Owner((OAHWND)m_hwnd);
		// Send the window messages back to the parent window.
		m_pIVideoWindow->put_MessageDrain((OAHWND)m_hwnd);
	}

	QueryTvVgaOutput();
	GetBasicVideoInterface();
//	m_pIMediaFilter->GetSyncSource(&m_pIRefClock);
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////////////////
// Get the interface to set the video output to TV/VGA
HRESULT RtspPlayer::QueryTvVgaOutput()
{
	IEnumFilters *pEnumFilters;
	#define MAX 15

	m_pIGraphBuilder->EnumFilters(&pEnumFilters);
	if (pEnumFilters != NULL)
	{
		IBaseFilter *Filters[MAX];
		ULONG uActualFilters = 0;
		BOOL bFound = FALSE;
		BYTE bCount = 0;
		do
		{
			pEnumFilters->Next(MAX, (IBaseFilter **) &Filters, &uActualFilters);
			for (ULONG ulFilterNum = 0; ulFilterNum < uActualFilters; ulFilterNum++)
			{
				if (m_pITvVgaOut == NULL)
				{
					Filters[ulFilterNum]->QueryInterface(IID_ITvVgaOutput, (void **)&m_pITvVgaOut);
					if (m_pITvVgaOut != NULL)
						bFound = TRUE;
				}
				Filters[ulFilterNum]->Release();
			}
		} 
		while((!bFound) && (uActualFilters == MAX));

		pEnumFilters->Release();
	}
	return S_OK;
}

/////////////////////////////////////////////////////////////////////////////////////////

// This is a routine that can be used to retrieve IBasicVideo interface from
// Video Renderer or filter connected to Video Renderer when Video Renderer
// is only used as an Overlay surface.
HRESULT RtspPlayer::GetBasicVideoInterface()
{
	TCHAR szFilter[] = "Video Renderer";
	WCHAR wFile[MAX_PATH]; 
	IBaseFilter *m_pfVRender;

	m_pIBasicVideo = NULL;

	MultiByteToWideChar(CP_ACP, 0, szFilter, -1, wFile, MAX_PATH);
	HRESULT hResult = m_pIGraphBuilder->FindFilterByName(wFile, &m_pfVRender);
	// If we fail here, let the graph manager handle this
	if(FAILED(hResult) || !m_pfVRender)
		return m_pIGraphBuilder->QueryInterface(IID_IBasicVideo, (void **) m_pIBasicVideo);

	// Get input pin of video renderer
	IPin *pInputPin = GetFirstPin(m_pfVRender, PINDIR_INPUT);
	m_pfVRender->Release();
	if (!pInputPin)
		return m_pIGraphBuilder->QueryInterface(IID_IBasicVideo, (void **) m_pIBasicVideo);
		
	// Check who is connected
	IPin *pConnectedPin = NULL;
	hResult = pInputPin->ConnectedTo(&pConnectedPin);
	if (FAILED(hResult) || !pConnectedPin)
	{
		pInputPin->Release();
		return m_pIGraphBuilder->QueryInterface(IID_IBasicVideo, (void **) m_pIBasicVideo);
	}
	pInputPin->Release();

	PIN_INFO InInfo;
	hResult = pConnectedPin->QueryPinInfo(&InInfo);
	if (FAILED(hResult) || !InInfo.pFilter)
	{
		pConnectedPin->Release();
		return m_pIGraphBuilder->QueryInterface(IID_IBasicVideo, (void **) m_pIBasicVideo);
	}
	pConnectedPin->Release();

	// Query interface on this filter
	if (FAILED(InInfo.pFilter->QueryInterface(IID_IBasicVideo, 
				(void **) m_pIBasicVideo)) || !m_pIBasicVideo)
	{
		// Finally if previous filter doesn't have this interface, we give up
		hResult = m_pIGraphBuilder->QueryInterface(IID_IBasicVideo, (void **) m_pIBasicVideo);

	}
	InInfo.pFilter->Release();
	return hResult;
}

/////////////////////////////////////////////////////////////////////////////////////////

// Get first pin matching a direction on any filter. This is mostly usefull on
// renderers or transform filters which have only one input and/or output pin.
IPin *RtspPlayer::GetFirstPin(IBaseFilter *filter, PIN_DIRECTION PinDir)
{
	IEnumPins	*pEnumPins = NULL;
	IPin		*pRetPin = NULL;
	BOOL		bDone = FALSE;

	filter->EnumPins(&pEnumPins);
	if (pEnumPins)
	{
		ULONG uFetchedPins = 0;
		while ( (!bDone)
			 && (SUCCEEDED(pEnumPins->Next(1, &pRetPin, &uFetchedPins)))
		     && (uFetchedPins == 1) )
		{
			PIN_DIRECTION TempPinDir;
			HRESULT hResult = pRetPin->QueryDirection(&TempPinDir);
			if (hResult == S_OK)
			{
				if (TempPinDir == PinDir)
					bDone = TRUE;
			}
			if (!bDone)
				pRetPin->Release();
		}
		pEnumPins->Release();
	}
	return bDone ? pRetPin : NULL;
}
/////////////////////////////////////////////////////////////////////////////////////////

void RtspPlayer::Play()
{
	// Run the graph if RenderFile succeeded
	if (m_pIMediaControl != NULL)
	{
		m_pIMediaControl->Run();
		// Fix position and then show
		if (m_pIVideoWindow != NULL)
		{
			UpdateWindowPos(m_hwnd);
			m_pIVideoWindow->put_Visible(OATRUE);
			m_pIVideoWindow->put_FullScreenMode(m_iFullScreen);
		}
		if (m_pITvVgaOut != NULL)
			m_pITvVgaOut->SetTvOutput(m_bTvOut);
	}
}

/////////////////////////////////////////////////////////////////////////////////////////

void RtspPlayer::Stop()
{
	if (m_pIVideoWindow != NULL)
	{
		m_pIVideoWindow->put_FullScreenMode(OAFALSE);
		m_pIVideoWindow->put_Visible(OAFALSE);
		UpdateWindowPos(m_hwnd);
	}
	if (m_pIMediaControl != NULL)
	{
		m_pIMediaControl->StopWhenReady();
		m_pIMediaControl->Stop();
	}
}

/////////////////////////////////////////////////////////////////////////////////////////

void RtspPlayer::SetFullScreen(int iFullScreen)
{
	OutputDebugString("\nRtspPlayer SetFullScreen");

	if (iFullScreen == OAFALSE || iFullScreen == OATRUE)
		m_iFullScreen = iFullScreen;

	if (m_pIVideoWindow != NULL)
		m_pIVideoWindow->put_FullScreenMode(m_iFullScreen);
}

/////////////////////////////////////////////////////////////////////////////////////////

void RtspPlayer::SetTvOut(BOOL bVal)
{
	m_bTvOut = bVal;
	if (m_pITvVgaOut != NULL)
		m_pITvVgaOut->SetTvOutput(m_bTvOut);
}

/////////////////////////////////////////////////////////////////////////////////////////

void RtspPlayer::UpdateWindowPos(HWND hWnd)
{
	if (m_pIVideoWindow != NULL)
	{
		RECT rcWndPos;
		GetClientRect(hWnd, &rcWndPos);
		m_pIVideoWindow->SetWindowPosition(rcWndPos.left, rcWndPos.top, 
			rcWndPos.right - rcWndPos.left, rcWndPos.bottom - rcWndPos.top);
	}
}

/////////////////////////////////////////////////////////////////////////////////////////

HRESULT RtspPlayer::GetMediaEvent(long *lEventCode, long *lParam1, long *lParam2, long msTimeout)
{
	if (m_pIMediaEventEx != NULL)
		return m_pIMediaEventEx->GetEvent(lEventCode, lParam1, lParam2, msTimeout);
	else
		return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////

HRESULT RtspPlayer::FreeMediaEventParams(long lEventCode, long lParam1, long lParam2)
{
	if (m_pIMediaEventEx != NULL)
		return m_pIMediaEventEx->FreeEventParams(lEventCode, lParam1, lParam2);
	else
		return 0;
}

/////////////////////////////////////////////////////////////////////////////////////////
// Get the play files from the ini file and display them to the screen.
void RtspPlayer::GetINIInfo(HWND hwnd)
{
	char buffer[256];
	char key;

	// Get the full path of the INI file
	if (strcmp(m_szIniFile, "") == 0)
		GetFullPathName(INI_FILE, sizeof(m_szIniFile), m_szIniFile, NULL);

	SendDlgItemMessage (hwnd, IDC_COMBO_PLAYFILE, CB_RESETCONTENT, 0, 0);
	// Read the file names from INI file and display them on the screen
	for (int i = 1; ; i++)
	{
		itoa(i, &key, 10);
		GetPrivateProfileString("FILE_NAMES", &key, "", buffer, sizeof(buffer), m_szIniFile);
		if (strcmp(buffer, "") == 0)
			break;
		SendDlgItemMessage (hwnd, IDC_COMBO_PLAYFILE, CB_ADDSTRING, 0, (LPARAM)buffer);
	}
	SendDlgItemMessage (hwnd, IDC_COMBO_PLAYFILE, CB_SETCURSEL, 0, 0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -