2 Copyright 2004-2006 Marten Richter
4 This file is part of VOMP.
6 VOMP is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 VOMP is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with VOMP; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "dssourcefilter.h"
22 #define AUDIOPIN_NAME L"Audio"
23 #define VIDEOPIN_NAME L"Video"
25 class DsSFEnumPins: public IEnumPins {
27 DsSFEnumPins(DsSourcePin* audio,DsSourcePin* video,DsSourceFilter *filt,ULONG pos=0);
28 virtual ~DsSFEnumPins();
29 virtual HRESULT STDMETHODCALLTYPE Next(ULONG numpin,IPin **pins,ULONG *fetched);
\r
30 virtual HRESULT STDMETHODCALLTYPE Skip(ULONG numpin);
\r
31 virtual HRESULT STDMETHODCALLTYPE Reset();
\r
32 virtual HRESULT STDMETHODCALLTYPE Clone(IEnumPins **enuma);
\r
33 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id,void ** object);
34 virtual ULONG STDMETHODCALLTYPE AddRef();
\r
35 virtual ULONG STDMETHODCALLTYPE Release();
\r
37 DsSourcePin* audiopin;
\r
38 DsSourcePin* videopin;
\r
39 DsSourceFilter *filter;
\r
44 DsSFEnumPins::DsSFEnumPins(DsSourcePin* audio,DsSourcePin* video,DsSourceFilter *filt,ULONG pos){
\r
52 DsSFEnumPins::~DsSFEnumPins(){
56 HRESULT STDMETHODCALLTYPE DsSFEnumPins::Next(ULONG numpin,IPin **pins,ULONG *fetched) {
\r
58 if (fetched==NULL) return E_POINTER;
\r
59 if (pins==NULL) return E_POINTER;
\r
62 for (i=0;(i<numpin)&& (curpos<2);i++) {
\r
64 case 0: audiopin->AddRef(); pins[i]=(IPin*)audiopin;break;
\r
65 case 1: videopin->AddRef(); pins[i]=(IPin*)videopin;break;
\r
70 if ((*fetched)!=numpin) return S_FALSE;
\r
74 HRESULT STDMETHODCALLTYPE DsSFEnumPins::Skip(ULONG numpin){
\r
76 if (curpos>2) return S_FALSE;
\r
79 HRESULT STDMETHODCALLTYPE DsSFEnumPins::Reset(){
\r
83 HRESULT STDMETHODCALLTYPE DsSFEnumPins::Clone(IEnumPins **enuma){
\r
84 if (enuma==NULL) return E_POINTER;
\r
85 *enuma=new DsSFEnumPins(audiopin,videopin,filter,curpos);
\r
90 HRESULT STDMETHODCALLTYPE DsSFEnumPins::QueryInterface(REFIID id,void ** object){
91 if (object==NULL) return E_POINTER;
92 if (id==IID_IUnknown ||id == IID_IEnumPins) {
93 *object=(IUnknown*)this;
94 ((IUnknown*)object)->AddRef();
104 ULONG STDMETHODCALLTYPE DsSFEnumPins::AddRef(){
\r
105 InterlockedIncrement(&refs);
\r
107 if (tempref>1) return tempref;
\r
111 ULONG STDMETHODCALLTYPE DsSFEnumPins::Release(){
\r
112 long tempref=InterlockedDecrement(&refs);
\r
119 if (tempref>1) return tempref;
\r
130 DsSourceFilter::DsSourceFilter()
134 audiopin=new DsSourcePin(this,&res,L"Vomp Audio Out",true);
135 videopin=new DsSourcePin(this,&res,L"Vomp Video Out",false);
138 mystate=State_Stopped;
141 InitializeCriticalSection(&filterlock);
145 DsSourceFilter::~DsSourceFilter()
147 if (audiopin) delete audiopin;
148 if (videopin) delete videopin;
153 DeleteCriticalSection(&filterlock);
157 HRESULT STDMETHODCALLTYPE DsSourceFilter::GetClassID(CLSID *clsid){
158 if (clsid==NULL) return E_POINTER;
159 *clsid=_uuidof(this);
163 HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryInterface(REFIID id,void ** object){
164 if (object==NULL) return E_POINTER;
165 if (id==IID_IUnknown) {
166 *object=(IUnknown*)this;
167 ((IUnknown*)object)->AddRef();
169 } else if (id==IID_IBaseFilter) {
170 *object=(IBaseFilter*)this;
171 ((IBaseFilter*)object)->AddRef();
173 } else if (id==IID_IMediaFilter) {
174 *object=(IMediaFilter*)this;
175 ((IMediaFilter*)object)->AddRef();
179 return E_NOINTERFACE;
183 ULONG STDMETHODCALLTYPE DsSourceFilter::AddRef(){
\r
184 InterlockedIncrement(&refs);
\r
186 if (tempref>1) return tempref;
\r
189 ULONG STDMETHODCALLTYPE DsSourceFilter::Release(){
\r
190 long tempref=InterlockedDecrement(&refs);
\r
197 if (tempref>1) return tempref;
\r
203 HRESULT STDMETHODCALLTYPE DsSourceFilter::EnumPins(IEnumPins **enumar){
204 if (enumar==NULL) return E_POINTER;
205 *enumar=new DsSFEnumPins(audiopin,videopin, this);
210 HRESULT STDMETHODCALLTYPE DsSourceFilter::FindPin(LPCWSTR iden,IPin **pin){
\r
211 if (pin==NULL) return E_POINTER;
\r
213 if (wcscmp(AUDIOPIN_NAME,iden)==NULL) {
\r
214 *pin=(IPin*)audiopin;
\r
218 if (wcscmp(VIDEOPIN_NAME,iden)==NULL) {
\r
219 *pin=(IPin*)videopin;
\r
225 return VFW_E_NOT_FOUND;
\r
227 HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryFilterInfo(FILTER_INFO *info){
\r
228 if (info==NULL) return E_POINTER;
\r
229 wcsncpy(info->achName,L"VompWinFilter", sizeof(info->achName)/sizeof(WCHAR));
\r
230 info->pGraph=filtergraph;
\r
231 if (info->pGraph!=NULL) info->pGraph->AddRef();
\r
235 HRESULT STDMETHODCALLTYPE DsSourceFilter::JoinFilterGraph(IFilterGraph *graph,LPCWSTR name){
\r
237 EnterCriticalSection(&filterlock);
\r
239 filtergraph->AddRef();
\r
240 //We ignore the name
\r
241 LeaveCriticalSection(&filterlock);
\r
245 HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryVendorInfo(LPWSTR *vendinf) {
\r
251 HRESULT STDMETHODCALLTYPE DsSourceFilter::GetState(DWORD timeout,FILTER_STATE *state){
\r
252 if (state==NULL) return E_POINTER;
\r
257 HRESULT STDMETHODCALLTYPE DsSourceFilter::SetSyncSource(IReferenceClock *uhr){
\r
258 EnterCriticalSection(&filterlock);
\r
266 LeaveCriticalSection(&filterlock);
\r
270 HRESULT STDMETHODCALLTYPE DsSourceFilter::GetSyncSource(IReferenceClock **uhr){
\r
271 if (uhr==NULL) return E_POINTER;
\r
272 EnterCriticalSection(&filterlock);
\r
273 if (clock!=NULL) clock->AddRef();
\r
275 LeaveCriticalSection(&filterlock);
\r
280 HRESULT STDMETHODCALLTYPE DsSourceFilter::Stop(){
\r
281 EnterCriticalSection(&filterlock);
\r
282 HRESULT aphres=S_OK;
\r
283 HRESULT vphres=S_OK;
\r
285 if (audiopin->IsConnected()){
\r
286 aphres=audiopin->Inactive();
\r
288 if (videopin->IsConnected()){
\r
289 vphres=videopin->Inactive();
\r
292 mystate=State_Stopped;
\r
293 LeaveCriticalSection(&filterlock);
\r
294 if (aphres!=S_OK) return aphres;
\r
295 if (vphres!=S_OK) return vphres;
\r
299 HRESULT STDMETHODCALLTYPE DsSourceFilter::Pause(){
\r
300 EnterCriticalSection(&filterlock);
\r
304 if (audiopin->IsConnected()){
\r
305 aphres=audiopin->Active();
\r
306 if (aphres!=S_OK) {
\r
307 LeaveCriticalSection(&filterlock);
\r
311 if (videopin->IsConnected()){
\r
312 vphres=videopin->Active();
\r
313 if (vphres!=S_OK) {
\r
314 LeaveCriticalSection(&filterlock);
\r
319 mystate=State_Paused;
\r
320 LeaveCriticalSection(&filterlock);
\r
325 HRESULT STDMETHODCALLTYPE DsSourceFilter::Run(REFERENCE_TIME start){
\r
329 EnterCriticalSection(&filterlock);
\r
331 if (mystate==State_Stopped) {
\r
332 HRESULT phres=Pause();
\r
333 if (phres!=S_OK) return phres;
\r
339 if (audiopin->IsConnected()){
\r
340 aphres=audiopin->Run(start);
\r
341 if (aphres!=S_OK) {
\r
342 LeaveCriticalSection(&filterlock);
\r
347 if (videopin->IsConnected()){
\r
348 vphres=videopin->Run(start);
\r
349 if (vphres!=S_OK) {
\r
350 LeaveCriticalSection(&filterlock);
\r
355 mystate=State_Running;
\r
356 LeaveCriticalSection(&filterlock);
\r
364 int DsSourceFilter::GetPinCount()
366 return 2; //audio and video
371 int DsSourceFilter::getCurrentAudioMediaSample(IMediaSample** ms)
373 if (!audiopin || !IsActive()) {
376 if (audiopin->getCurrentMediaSample(ms)!=S_OK) {
382 int DsSourceFilter::getCurrentVideoMediaSample(IMediaSample** ms)
384 if (!videopin || !IsActive()) {
387 if (videopin->getCurrentMediaSample(ms)!=S_OK) {
393 int DsSourceFilter::DeliverAudioMediaSample(IMediaSample* ms)
395 if (!audiopin || !IsActive()) {
399 if (audiopin->deliver(ms)!=S_OK) {
408 int DsSourceFilter::DeliverVideoMediaSample(IMediaSample* ms)
410 if (!videopin || !IsActive()) {
414 if (videopin->deliver(ms)!=S_OK) {