root/trunk/RenderStreamTest01/RenderStreamTest01.cpp

User picture

Author: alax

Revision: 306 («Previous)


File Size: 6.8 KB

(March 11, 2011 18:21 UTC) About 1 year ago


  

 
Show/hide line numbers
////////////////////////////////////////////////////////////
// Copyright (C) Roman Ryltsov, 2008-2011
// Created by Roman Ryltsov roman@alax.info
// 
// $Id$

#include "stdafx.h"
#include <dshow.h>
//#include <qedit.h>

#pragma comment(lib, "strmiids.lib")

#pragma region Formerly located in qedit.h in Windows SDK, now obsoleted and defined within project

struct __declspec(uuid("0579154a-2b53-4994-b0d0-e773148eff85"))
ISampleGrabberCB : IUnknown
{
    //
    // Raw methods provided by interface
    //

      virtual HRESULT __stdcall SampleCB (
        double SampleTime,
        struct IMediaSample * pSample ) = 0;
      virtual HRESULT __stdcall BufferCB (
        double SampleTime,
        unsigned char * pBuffer,
        long BufferLen ) = 0;
};

struct __declspec(uuid("6b652fff-11fe-4fce-92ad-0266b5d7c78f"))
ISampleGrabber : IUnknown
{
    //
    // Raw methods provided by interface
    //

      virtual HRESULT __stdcall SetOneShot (
        long OneShot ) = 0;
      virtual HRESULT __stdcall SetMediaType (
        struct _AMMediaType * pType ) = 0;
      virtual HRESULT __stdcall GetConnectedMediaType (
        struct _AMMediaType * pType ) = 0;
      virtual HRESULT __stdcall SetBufferSamples (
        long BufferThem ) = 0;
      virtual HRESULT __stdcall GetCurrentBuffer (
        /*[in,out]*/ long * pBufferSize,
        /*[out]*/ long * pBuffer ) = 0;
      virtual HRESULT __stdcall GetCurrentSample (
        /*[out,retval]*/ struct IMediaSample * * ppSample ) = 0;
      virtual HRESULT __stdcall SetCallback (
        struct ISampleGrabberCB * pCallback,
        long WhichMethodToCallback ) = 0;
};

struct __declspec(uuid("c1f400a0-3f08-11d3-9f0b-006008039e37"))
SampleGrabber;
    // [ default ] interface ISampleGrabber

#pragma endregion

////////////////////////////////////////////////////////////
// Main

CComPtr<IPin> GetPin(IBaseFilter* pBaseFilter, PIN_DIRECTION Direction, const GUID* pMajorType = NULL)
{
	ATLASSERT(pBaseFilter);
	CComPtr<IEnumPins> pEnumPins;
	ATLENSURE_SUCCEEDED(pBaseFilter->EnumPins(&pEnumPins));
	ATLASSERT(pEnumPins);
	CComPtr<IPin> pPin;
	while(pEnumPins->Next(1, &pPin, NULL) == S_OK)
	{
		ATLASSERT(pPin);
		PIN_DIRECTION PinDirection;
		ATLENSURE_SUCCEEDED(pPin->QueryDirection(&PinDirection));
		if(PinDirection == Direction)
		{
			if(pMajorType)
				_ATLTRY
				{
					CComPtr<IEnumMediaTypes> pEnumMediaTypes;
					ATLENSURE_SUCCEEDED(pPin->EnumMediaTypes(&pEnumMediaTypes));
					ATLASSERT(pEnumMediaTypes);
					CComHeapPtr<AM_MEDIA_TYPE> pMediaType;
					if(pEnumMediaTypes->Next(1, &pMediaType, NULL) == S_OK)
					{
						CComHeapPtr<BYTE> pnFormatData;
						pnFormatData.Attach(pMediaType->pbFormat); // Will CoTaskMemFree going out of scope
						if(pMediaType->majortype != *pMajorType)
							pPin.Release(); // Not Requested Major Type
					} else
						pPin.Release(); // No Major Type Available
				}
				_ATLCATCHALL()
				{
					pPin.Release(); // Failed to Match Major Type
				}
			if(pPin)
				return pPin;
		}
		pPin.Release();
	}
	return NULL;
}

int _tmain(int argc, _TCHAR* argv[])
{
////////////////////////////////////////////////////////
// NOTE: *** Step 1 *** Choose Media File
////////////////////////////////////////////////////////
	static LPCTSTR g_pszPath = 
		// NOTE: Provide a media file here
		_T("F:\\Media\\Robotica_1080.wmv");
		//_T("F:\\Media\\GoPro 2010 Highlights - You in HD - 1920x1080.mp4");
		//_T("F:\\Media\\Californication.S01E01.rus.LostFilm.TV.avi");
	_ATLTRY
	{
		ATLENSURE_SUCCEEDED(CoInitialize(NULL));
		// NOTE: Graceful cleanup omitted for code brevity
		CComPtr<IGraphBuilder> pGraphBuilder;
		ATLENSURE_SUCCEEDED(pGraphBuilder.CoCreateInstance(CLSID_FilterGraph));
		CComPtr<IBaseFilter> pSourceBaseFilter;
		ATLENSURE_SUCCEEDED(pGraphBuilder->AddSourceFilter(CT2CW(g_pszPath), NULL, &pSourceBaseFilter));
		CComPtr<IBaseFilter> pVideoBaseFilter;
		#pragma region Video Transformation Filter
		// NOTE: This assumes you have a video transformation filter you want to connect your input of
		//       A Sample Grabber filter will do just fine for the demo purpose
		ATLENSURE_SUCCEEDED(pVideoBaseFilter.CoCreateInstance(__uuidof(SampleGrabber)));
		CComQIPtr<ISampleGrabber> pSampleGrabber = pVideoBaseFilter;
		AM_MEDIA_TYPE VideoMediaType;
		ZeroMemory(&VideoMediaType, sizeof VideoMediaType);
////////////////////////////////////////////////////////
// NOTE: *** Step 2 *** Choose Media Type, you might want any video (comment subtype line out) , RGB 24-bit video etc.
////////////////////////////////////////////////////////
		VideoMediaType.majortype = MEDIATYPE_Video;
		VideoMediaType.subtype = MEDIASUBTYPE_RGB24;
		ATLENSURE_SUCCEEDED(pSampleGrabber->SetMediaType(&VideoMediaType));
		ATLENSURE_SUCCEEDED(pGraphBuilder->AddFilter(pVideoBaseFilter, _T("Video Filter")));
		#pragma endregion
////////////////////////////////////////////////////////
// NOTE: *** Step 3 *** Choose whether you want capture builder helper to connect pins, or straightforwardly Connect
////////////////////////////////////////////////////////
		HRESULT nResult = S_OK;
		_ATLTRY
		{
			switch(2)
			{
			case 1:
				{
					CComPtr<ICaptureGraphBuilder2> pCaptureGraphBuilder;
					ATLENSURE_SUCCEEDED(pCaptureGraphBuilder.CoCreateInstance(CLSID_CaptureGraphBuilder2));
					ATLENSURE_SUCCEEDED(pCaptureGraphBuilder->SetFiltergraph(pGraphBuilder));
					HRESULT nResult = pCaptureGraphBuilder->RenderStream(NULL, &MEDIATYPE_Video, pSourceBaseFilter, NULL, pVideoBaseFilter);
					if(FAILED(nResult))
						nResult = pCaptureGraphBuilder->RenderStream(NULL, NULL, pSourceBaseFilter, NULL, pVideoBaseFilter);
					ATLENSURE_SUCCEEDED(nResult);
				}
				break;
			case 2:
				{
					CComPtr<IPin> pOutputPin;
					// NOTE: Some source filters are splitters (WM ASF Reader) itself and expose typed output pins, we first attempt to 
					//       get a video pin, or otherwise just any pin
					pOutputPin = GetPin(pSourceBaseFilter, PINDIR_OUTPUT, &MEDIATYPE_Video);
					if(!pOutputPin)
						pOutputPin = GetPin(pSourceBaseFilter, PINDIR_OUTPUT);
					ATLENSURE_THROW(pOutputPin, VFW_E_NOT_FOUND);
					ATLENSURE_SUCCEEDED(pGraphBuilder->Connect(pOutputPin, GetPin(pVideoBaseFilter, PINDIR_INPUT)));
				}
				break;
			}
			nResult = S_OK;
		}
		_ATLCATCH(Exception)
		{
			nResult = Exception;
			ATLASSERT(FAILED(nResult));
		}
		// NOTE: If you have DirectShow Spy installed, you will be able to check the graph while message box is not closed
		CString sMessage;
		sMessage.Format(_T("Graph building result: 0x%08x."), nResult);
		MessageBox(GetActiveWindow(), sMessage, _T("Debug"), MB_ICONINFORMATION | MB_OK);
		ATLENSURE_SUCCEEDED(nResult);
		//CoUninitialize();
	}
	_ATLCATCHALL()
	{
		_tprintf(_T("Fatal Error\n"));
	}
	return 0;
}