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;
96 if (id==IID_IUnknown ||id == IID_IEnumPins) {
97 *object=(IUnknown*)this;
98 ((IUnknown*)object)->AddRef();
102 return E_NOINTERFACE;
108 ULONG STDMETHODCALLTYPE DsSFEnumPins::AddRef(){
109 InterlockedIncrement(&refs);
111 if (tempref>1) return tempref;
115 ULONG STDMETHODCALLTYPE DsSFEnumPins::Release(){
116 long tempref=InterlockedDecrement(&refs);
123 if (tempref>1) return tempref;
134 DsSourceFilter::DsSourceFilter()
138 audiopin=new DsSourcePin(this,&res,L"Vomp Audio Out",true);
139 videopin=new DsSourcePin(this,&res,L"Vomp Video Out",false);
142 mystate=State_Stopped;
145 InitializeCriticalSection(&filterlock);
149 DsSourceFilter::~DsSourceFilter()
151 if (audiopin) delete audiopin;
152 if (videopin) delete videopin;
157 DeleteCriticalSection(&filterlock);
161 HRESULT STDMETHODCALLTYPE DsSourceFilter::GetClassID(CLSID *clsid){
162 if (clsid==NULL) return E_POINTER;
163 *clsid=_uuidof(this);
167 HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryInterface(REFIID id,void ** object){
168 if (object==NULL) return E_POINTER;
169 if (id==IID_IUnknown) {
170 *object=(IUnknown*)this;
173 } else if (id==IID_IBaseFilter) {
174 *object=(IBaseFilter*)this;
177 } else if (id==IID_IMediaFilter) {
178 *object=(IMediaFilter*)this;
183 return E_NOINTERFACE;
187 ULONG STDMETHODCALLTYPE DsSourceFilter::AddRef(){
188 InterlockedIncrement(&refs);
190 if (tempref>1) return tempref;
193 ULONG STDMETHODCALLTYPE DsSourceFilter::Release(){
194 long tempref=InterlockedDecrement(&refs);
201 if (tempref>1) return tempref;
207 HRESULT STDMETHODCALLTYPE DsSourceFilter::EnumPins(IEnumPins **enumar){
208 if (enumar==NULL) return E_POINTER;
209 *enumar=new DsSFEnumPins(audiopin,videopin, this);
214 HRESULT STDMETHODCALLTYPE DsSourceFilter::FindPin(LPCWSTR iden,IPin **pin){
215 if (pin==NULL) return E_POINTER;
216 EnterCriticalSection(&filterlock);
218 if (wcscmp(AUDIOPIN_NAME,iden)==NULL) {
219 *pin=(IPin*)audiopin;
221 LeaveCriticalSection(&filterlock);
224 if (wcscmp(VIDEOPIN_NAME,iden)==NULL) {
225 *pin=(IPin*)videopin;
227 LeaveCriticalSection(&filterlock);
232 LeaveCriticalSection(&filterlock);
233 return VFW_E_NOT_FOUND;
235 HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryFilterInfo(FILTER_INFO *info){
236 if (info==NULL) return E_POINTER;
237 wcsncpy(info->achName,L"VompWinFilter", sizeof(info->achName)/sizeof(WCHAR));
238 info->pGraph=filtergraph;
239 if (info->pGraph!=NULL) info->pGraph->AddRef();
243 HRESULT STDMETHODCALLTYPE DsSourceFilter::JoinFilterGraph(IFilterGraph *graph,LPCWSTR name){
245 EnterCriticalSection(&filterlock);
247 //filtergraph->AddRef();
249 LeaveCriticalSection(&filterlock);
253 HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryVendorInfo(LPWSTR *vendinf) {
259 HRESULT STDMETHODCALLTYPE DsSourceFilter::GetState(DWORD timeout,FILTER_STATE *state){
260 if (state==NULL) return E_POINTER;
261 EnterCriticalSection(&filterlock);
263 LeaveCriticalSection(&filterlock);
267 HRESULT STDMETHODCALLTYPE DsSourceFilter::SetSyncSource(IReferenceClock *uhr){
268 EnterCriticalSection(&filterlock);
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 bool DsSourceFilter::supportsAc3()
423 if (!audiopin || !IsActive()) {
426 return audiopin->supportsAc3();
429 int DsSourceFilter::DeliverVideoMediaSample(IMediaSample* ms)
431 if (!videopin || !IsActive()) {
435 if (videopin->deliver(ms)!=S_OK) {
444 bool DsSourceFilter::changeAType(int type,IMediaSample* ms)
449 audiopin->SetPinMode(type);
450 audiopin->SetMsToMt(ms);