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);
30 virtual HRESULT STDMETHODCALLTYPE Skip(ULONG numpin);
31 virtual HRESULT STDMETHODCALLTYPE Reset();
32 virtual HRESULT STDMETHODCALLTYPE Clone(IEnumPins **enuma);
33 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id,void ** object);
34 virtual ULONG STDMETHODCALLTYPE AddRef();
35 virtual ULONG STDMETHODCALLTYPE Release();
37 DsSourcePin* audiopin;
38 DsSourcePin* videopin;
39 DsSourceFilter *filter;
44 DsSFEnumPins::DsSFEnumPins(DsSourcePin* audio,DsSourcePin* video,DsSourceFilter *filt,ULONG pos){
54 DsSFEnumPins::~DsSFEnumPins(){
59 HRESULT STDMETHODCALLTYPE DsSFEnumPins::Next(ULONG numpin,IPin **pins,ULONG *fetched) {
61 if (fetched==NULL) return E_POINTER;
62 if (pins==NULL) return E_POINTER;
65 for (i=0;(i<numpin)&& (curpos<2);i++) {
67 case 0: audiopin->AddRef(); pins[i]=(IPin*)audiopin;break;
68 case 1: videopin->AddRef(); pins[i]=(IPin*)videopin;break;
73 if ((*fetched)!=numpin) return S_FALSE;
77 HRESULT STDMETHODCALLTYPE DsSFEnumPins::Skip(ULONG numpin){
79 if (curpos>2) return S_FALSE;
82 HRESULT STDMETHODCALLTYPE DsSFEnumPins::Reset(){
86 HRESULT STDMETHODCALLTYPE DsSFEnumPins::Clone(IEnumPins **enuma){
87 if (enuma==NULL) return E_POINTER;
88 *enuma=new DsSFEnumPins(audiopin,videopin,filter,curpos);
93 HRESULT STDMETHODCALLTYPE DsSFEnumPins::QueryInterface(REFIID id,void ** object){
94 if (object==NULL) return E_POINTER;
95 if (id==IID_IUnknown ||id == IID_IEnumPins) {
96 *object=(IUnknown*)this;
97 ((IUnknown*)object)->AddRef();
101 return E_NOINTERFACE;
107 ULONG STDMETHODCALLTYPE DsSFEnumPins::AddRef(){
108 InterlockedIncrement(&refs);
110 if (tempref>1) return tempref;
114 ULONG STDMETHODCALLTYPE DsSFEnumPins::Release(){
115 long tempref=InterlockedDecrement(&refs);
122 if (tempref>1) return tempref;
133 DsSourceFilter::DsSourceFilter()
137 audiopin=new DsSourcePin(this,&res,L"Vomp Audio Out",true);
138 videopin=new DsSourcePin(this,&res,L"Vomp Video Out",false);
141 mystate=State_Stopped;
144 InitializeCriticalSection(&filterlock);
148 DsSourceFilter::~DsSourceFilter()
150 if (audiopin) delete audiopin;
151 if (videopin) delete videopin;
156 DeleteCriticalSection(&filterlock);
160 HRESULT STDMETHODCALLTYPE DsSourceFilter::GetClassID(CLSID *clsid){
161 if (clsid==NULL) return E_POINTER;
162 *clsid=_uuidof(this);
166 HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryInterface(REFIID id,void ** object){
167 if (object==NULL) return E_POINTER;
168 if (id==IID_IUnknown) {
169 *object=(IUnknown*)this;
172 } else if (id==IID_IBaseFilter) {
173 *object=(IBaseFilter*)this;
176 } else if (id==IID_IMediaFilter) {
177 *object=(IMediaFilter*)this;
182 return E_NOINTERFACE;
186 ULONG STDMETHODCALLTYPE DsSourceFilter::AddRef(){
187 InterlockedIncrement(&refs);
189 if (tempref>1) return tempref;
192 ULONG STDMETHODCALLTYPE DsSourceFilter::Release(){
193 long tempref=InterlockedDecrement(&refs);
200 if (tempref>1) return tempref;
206 HRESULT STDMETHODCALLTYPE DsSourceFilter::EnumPins(IEnumPins **enumar){
207 if (enumar==NULL) return E_POINTER;
208 *enumar=new DsSFEnumPins(audiopin,videopin, this);
213 HRESULT STDMETHODCALLTYPE DsSourceFilter::FindPin(LPCWSTR iden,IPin **pin){
214 if (pin==NULL) return E_POINTER;
215 EnterCriticalSection(&filterlock);
217 if (wcscmp(AUDIOPIN_NAME,iden)==NULL) {
218 *pin=(IPin*)audiopin;
220 LeaveCriticalSection(&filterlock);
223 if (wcscmp(VIDEOPIN_NAME,iden)==NULL) {
224 *pin=(IPin*)videopin;
226 LeaveCriticalSection(&filterlock);
231 LeaveCriticalSection(&filterlock);
232 return VFW_E_NOT_FOUND;
234 HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryFilterInfo(FILTER_INFO *info){
235 if (info==NULL) return E_POINTER;
236 wcsncpy(info->achName,L"VompWinFilter", sizeof(info->achName)/sizeof(WCHAR));
237 info->pGraph=filtergraph;
238 if (info->pGraph!=NULL) info->pGraph->AddRef();
242 HRESULT STDMETHODCALLTYPE DsSourceFilter::JoinFilterGraph(IFilterGraph *graph,LPCWSTR name){
244 EnterCriticalSection(&filterlock);
246 //filtergraph->AddRef();
248 LeaveCriticalSection(&filterlock);
252 HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryVendorInfo(LPWSTR *vendinf) {
258 HRESULT STDMETHODCALLTYPE DsSourceFilter::GetState(DWORD timeout,FILTER_STATE *state){
259 if (state==NULL) return E_POINTER;
260 EnterCriticalSection(&filterlock);
262 LeaveCriticalSection(&filterlock);
266 HRESULT STDMETHODCALLTYPE DsSourceFilter::SetSyncSource(IReferenceClock *uhr){
267 EnterCriticalSection(&filterlock);
268 //MessageBox(0,"Sets ync","",0);
276 LeaveCriticalSection(&filterlock);
280 HRESULT STDMETHODCALLTYPE DsSourceFilter::GetSyncSource(IReferenceClock **uhr){
281 if (uhr==NULL) return E_POINTER;
282 EnterCriticalSection(&filterlock);
283 if (clock!=NULL) clock->AddRef();
285 LeaveCriticalSection(&filterlock);
290 HRESULT STDMETHODCALLTYPE DsSourceFilter::Stop(){
291 EnterCriticalSection(&filterlock);
295 if (audiopin->IsConnected()){
296 aphres=audiopin->Inactive();
298 if (videopin->IsConnected()){
299 vphres=videopin->Inactive();
302 mystate=State_Stopped;
303 LeaveCriticalSection(&filterlock);
304 if (aphres!=S_OK) return aphres;
305 if (vphres!=S_OK) return vphres;
309 HRESULT STDMETHODCALLTYPE DsSourceFilter::Pause(){
310 EnterCriticalSection(&filterlock);
314 if (audiopin->IsConnected()){
315 aphres=audiopin->Active();
317 LeaveCriticalSection(&filterlock);
321 if (videopin->IsConnected()){
322 vphres=videopin->Active();
324 LeaveCriticalSection(&filterlock);
329 mystate=State_Paused;
330 LeaveCriticalSection(&filterlock);
335 HRESULT STDMETHODCALLTYPE DsSourceFilter::Run(REFERENCE_TIME start){
339 EnterCriticalSection(&filterlock);
341 if (mystate==State_Stopped) {
342 HRESULT phres=Pause();
344 LeaveCriticalSection(&filterlock);
352 if (audiopin->IsConnected()){
353 aphres=audiopin->Run(start);
355 LeaveCriticalSection(&filterlock);
360 if (videopin->IsConnected()){
361 vphres=videopin->Run(start);
363 LeaveCriticalSection(&filterlock);
368 mystate=State_Running;
369 LeaveCriticalSection(&filterlock);
377 int DsSourceFilter::GetPinCount()
379 return 2; //audio and video
384 int DsSourceFilter::getCurrentAudioMediaSample(IMediaSample** ms)
386 if (!audiopin || !IsActive()) {
389 if (audiopin->getCurrentMediaSample(ms)!=S_OK) {
395 int DsSourceFilter::getCurrentVideoMediaSample(IMediaSample** ms)
397 if (!videopin || !IsActive()) {
400 if (videopin->getCurrentMediaSample(ms)!=S_OK) {
406 int DsSourceFilter::DeliverAudioMediaSample(IMediaSample* ms)
408 if (!audiopin || !IsActive()) {
412 if (audiopin->deliver(ms)!=S_OK) {
421 int DsSourceFilter::DeliverVideoMediaSample(IMediaSample* ms)
423 if (!videopin || !IsActive()) {
427 if (videopin->deliver(ms)!=S_OK) {