1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193 |
////////////////////////////////////////////////////////////
// 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;
}
|