1 | //////////////////////////////////////////////////////////// |
---|
2 | // Copyright (C) Roman Ryltsov, 2013 |
---|
3 | // Created by Roman Ryltsov roman@alax.info |
---|
4 | |
---|
5 | #include "stdafx.h" |
---|
6 | #include <dshow.h> |
---|
7 | |
---|
8 | #pragma comment(lib, "strmiids.lib") |
---|
9 | |
---|
10 | #pragma region Windows SDK Tribute, qedit.h |
---|
11 | |
---|
12 | struct __declspec(uuid("0579154a-2b53-4994-b0d0-e773148eff85")) |
---|
13 | ISampleGrabberCB : IUnknown |
---|
14 | { |
---|
15 | // |
---|
16 | // Raw methods provided by interface |
---|
17 | // |
---|
18 | |
---|
19 | virtual HRESULT __stdcall SampleCB ( |
---|
20 | double SampleTime, |
---|
21 | struct IMediaSample * pSample ) = 0; |
---|
22 | virtual HRESULT __stdcall BufferCB ( |
---|
23 | double SampleTime, |
---|
24 | unsigned char * pBuffer, |
---|
25 | long BufferLen ) = 0; |
---|
26 | }; |
---|
27 | |
---|
28 | struct __declspec(uuid("6b652fff-11fe-4fce-92ad-0266b5d7c78f")) |
---|
29 | ISampleGrabber : IUnknown |
---|
30 | { |
---|
31 | // |
---|
32 | // Raw methods provided by interface |
---|
33 | // |
---|
34 | |
---|
35 | virtual HRESULT __stdcall SetOneShot ( |
---|
36 | long OneShot ) = 0; |
---|
37 | virtual HRESULT __stdcall SetMediaType ( |
---|
38 | struct _AMMediaType * pType ) = 0; |
---|
39 | virtual HRESULT __stdcall GetConnectedMediaType ( |
---|
40 | struct _AMMediaType * pType ) = 0; |
---|
41 | virtual HRESULT __stdcall SetBufferSamples ( |
---|
42 | long BufferThem ) = 0; |
---|
43 | virtual HRESULT __stdcall GetCurrentBuffer ( |
---|
44 | /*[in,out]*/ long * pBufferSize, |
---|
45 | /*[out]*/ long * pBuffer ) = 0; |
---|
46 | virtual HRESULT __stdcall GetCurrentSample ( |
---|
47 | /*[out,retval]*/ struct IMediaSample * * ppSample ) = 0; |
---|
48 | virtual HRESULT __stdcall SetCallback ( |
---|
49 | struct ISampleGrabberCB * pCallback, |
---|
50 | long WhichMethodToCallback ) = 0; |
---|
51 | }; |
---|
52 | |
---|
53 | struct __declspec(uuid("c1f400a0-3f08-11d3-9f0b-006008039e37")) |
---|
54 | SampleGrabber; |
---|
55 | // [ default ] interface ISampleGrabber |
---|
56 | |
---|
57 | #pragma endregion |
---|
58 | |
---|
59 | #define __C ATLENSURE_SUCCEEDED |
---|
60 | |
---|
61 | CComPtr<IPin> GetFilterPin(const CComPtr<IBaseFilter>& pBaseFilter, PIN_DIRECTION Direction, SIZE_T nIndex = 0) |
---|
62 | { |
---|
63 | if(pBaseFilter) |
---|
64 | { |
---|
65 | CComPtr<IEnumPins> pEnumPins; |
---|
66 | pBaseFilter->EnumPins(&pEnumPins); |
---|
67 | for(; ; ) |
---|
68 | { |
---|
69 | CComPtr<IPin> pPin; |
---|
70 | if(pEnumPins->Next(1, &pPin, NULL) != S_OK) |
---|
71 | break; |
---|
72 | PIN_DIRECTION PinDirection; |
---|
73 | __C(pPin->QueryDirection(&PinDirection)); |
---|
74 | if(PinDirection == Direction) |
---|
75 | if(!nIndex--) |
---|
76 | return pPin; |
---|
77 | pPin.Release(); |
---|
78 | } |
---|
79 | } |
---|
80 | return NULL; |
---|
81 | } |
---|
82 | VOID Do(LPCTSTR pszPath, SIZE_T nOutputPinIndex = 0) |
---|
83 | { |
---|
84 | CComPtr<IFilterGraph2> pFilterGraph2; |
---|
85 | __C(pFilterGraph2.CoCreateInstance(CLSID_FilterGraph)); |
---|
86 | CComPtr<IPin> pCurrentPin; |
---|
87 | #pragma region WM Reader |
---|
88 | { |
---|
89 | CComPtr<IBaseFilter> pBaseFilter; |
---|
90 | __C(pBaseFilter.CoCreateInstance(CLSID_WMAsfReader)); |
---|
91 | const CComQIPtr<IFileSourceFilter> pFileSourceFilter = pBaseFilter; |
---|
92 | __C(pFileSourceFilter->Load(CT2COLE(pszPath), NULL)); |
---|
93 | __C(pFilterGraph2->AddFilter(pBaseFilter, NULL)); |
---|
94 | pCurrentPin = GetFilterPin(pBaseFilter, PINDIR_OUTPUT, nOutputPinIndex); |
---|
95 | } |
---|
96 | #pragma endregion |
---|
97 | #pragma region Sample Grabber (Force 32-bit RGB) |
---|
98 | { |
---|
99 | CComPtr<IBaseFilter> pBaseFilter; |
---|
100 | __C(pBaseFilter.CoCreateInstance(__uuidof(SampleGrabber))); |
---|
101 | __C(pFilterGraph2->AddFilter(pBaseFilter, CT2CW(_T("Sample Grabber")))); |
---|
102 | const CComQIPtr<ISampleGrabber> pSampleGrabber = pBaseFilter; |
---|
103 | AM_MEDIA_TYPE MediaType; |
---|
104 | ZeroMemory(&MediaType, sizeof MediaType); |
---|
105 | MediaType.majortype = MEDIATYPE_Video; |
---|
106 | MediaType.subtype = MEDIASUBTYPE_RGB32; |
---|
107 | __C(pSampleGrabber->SetMediaType(&MediaType)); |
---|
108 | __C(pFilterGraph2->Connect(pCurrentPin, GetFilterPin(pBaseFilter, PINDIR_INPUT))); |
---|
109 | pCurrentPin = GetFilterPin(pBaseFilter, PINDIR_OUTPUT); |
---|
110 | } |
---|
111 | #pragma endregion |
---|
112 | __C(pFilterGraph2->Render(pCurrentPin)); |
---|
113 | //MessageBox(GetActiveWindow(), _T("Grab the Topology!"), _T("Debug"), MB_ICONINFORMATION | MB_OK); |
---|
114 | const CComQIPtr<IMediaControl> pMediaControl = pFilterGraph2; |
---|
115 | __C(pMediaControl->Run()); |
---|
116 | const CComQIPtr<IMediaEvent> pMediaEvent = pFilterGraph2; |
---|
117 | LONG nCode; |
---|
118 | __C(pMediaEvent->WaitForCompletion(INFINITE, &nCode)); |
---|
119 | } |
---|
120 | int _tmain(int argc, _TCHAR* argv[]) |
---|
121 | { |
---|
122 | __C(CoInitialize(NULL)); |
---|
123 | Do(_T("E:\\Media\\Robotica_1080.wmv"), 1); |
---|
124 | CoUninitialize(); |
---|
125 | return 0; |
---|
126 | } |
---|
127 | |
---|