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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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);
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;
170 if (id==IID_IUnknown) {
171 *object=(IUnknown*)this;
174 } else if (id==IID_IBaseFilter) {
175 *object=(IBaseFilter*)this;
178 } else if (id==IID_IMediaFilter) {
179 *object=(IMediaFilter*)this;
184 return E_NOINTERFACE;
188 ULONG STDMETHODCALLTYPE DsSourceFilter::AddRef(){
189 InterlockedIncrement(&refs);
191 if (tempref>1) return tempref;
194 ULONG STDMETHODCALLTYPE DsSourceFilter::Release(){
195 long tempref=InterlockedDecrement(&refs);
202 if (tempref>1) return tempref;
208 HRESULT STDMETHODCALLTYPE DsSourceFilter::EnumPins(IEnumPins **enumar){
209 if (enumar==NULL) return E_POINTER;
210 *enumar=new DsSFEnumPins(audiopin,videopin, this);
215 HRESULT STDMETHODCALLTYPE DsSourceFilter::FindPin(LPCWSTR iden,IPin **pin){
216 if (pin==NULL) return E_POINTER;
217 EnterCriticalSection(&filterlock);
219 if (wcscmp(AUDIOPIN_NAME,iden)==NULL) {
220 *pin=(IPin*)audiopin;
222 LeaveCriticalSection(&filterlock);
225 if (wcscmp(VIDEOPIN_NAME,iden)==NULL) {
226 *pin=(IPin*)videopin;
228 LeaveCriticalSection(&filterlock);
233 LeaveCriticalSection(&filterlock);
234 return VFW_E_NOT_FOUND;
236 HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryFilterInfo(FILTER_INFO *info){
237 if (info==NULL) return E_POINTER;
238 wcsncpy(info->achName,L"VompWinFilter", sizeof(info->achName)/sizeof(WCHAR));
239 info->pGraph=filtergraph;
240 if (info->pGraph!=NULL) info->pGraph->AddRef();
244 HRESULT STDMETHODCALLTYPE DsSourceFilter::JoinFilterGraph(IFilterGraph *graph,LPCWSTR name){
246 EnterCriticalSection(&filterlock);
248 //filtergraph->AddRef();
250 LeaveCriticalSection(&filterlock);
254 HRESULT STDMETHODCALLTYPE DsSourceFilter::QueryVendorInfo(LPWSTR *vendinf) {
260 HRESULT STDMETHODCALLTYPE DsSourceFilter::GetState(DWORD timeout,FILTER_STATE *state){
261 if (state==NULL) return E_POINTER;
262 EnterCriticalSection(&filterlock);
264 LeaveCriticalSection(&filterlock);
268 HRESULT STDMETHODCALLTYPE DsSourceFilter::SetSyncSource(IReferenceClock *uhr){
269 EnterCriticalSection(&filterlock);
277 LeaveCriticalSection(&filterlock);
281 HRESULT STDMETHODCALLTYPE DsSourceFilter::GetSyncSource(IReferenceClock **uhr){
282 if (uhr==NULL) return E_POINTER;
283 EnterCriticalSection(&filterlock);
284 if (clock!=NULL) clock->AddRef();
286 LeaveCriticalSection(&filterlock);
291 HRESULT STDMETHODCALLTYPE DsSourceFilter::Stop(){
292 EnterCriticalSection(&filterlock);
296 if (audiopin->IsConnected()){
297 aphres=audiopin->Inactive();
299 if (videopin->IsConnected()){
300 vphres=videopin->Inactive();
303 mystate=State_Stopped;
304 LeaveCriticalSection(&filterlock);
305 if (aphres!=S_OK) return aphres;
306 if (vphres!=S_OK) return vphres;
310 HRESULT STDMETHODCALLTYPE DsSourceFilter::Pause(){
311 EnterCriticalSection(&filterlock);
315 if (audiopin->IsConnected()){
316 aphres=audiopin->Active();
318 LeaveCriticalSection(&filterlock);
322 if (videopin->IsConnected()){
323 vphres=videopin->Active();
325 LeaveCriticalSection(&filterlock);
330 mystate=State_Paused;
331 LeaveCriticalSection(&filterlock);
336 HRESULT STDMETHODCALLTYPE DsSourceFilter::Run(REFERENCE_TIME start){
340 EnterCriticalSection(&filterlock);
342 if (mystate==State_Stopped) {
343 HRESULT phres=Pause();
345 LeaveCriticalSection(&filterlock);
353 if (audiopin->IsConnected()){
354 aphres=audiopin->Run(start);
356 LeaveCriticalSection(&filterlock);
361 if (videopin->IsConnected()){
362 vphres=videopin->Run(start);
364 LeaveCriticalSection(&filterlock);
369 mystate=State_Running;
370 LeaveCriticalSection(&filterlock);
378 int DsSourceFilter::GetPinCount()
380 return 2; //audio and video
385 int DsSourceFilter::getCurrentAudioMediaSample(IMediaSample** ms)
387 if (!audiopin || !IsActive()) {
390 if (audiopin->getCurrentMediaSample(ms)!=S_OK) {
396 int DsSourceFilter::getCurrentVideoMediaSample(IMediaSample** ms)
398 if (!videopin || !IsActive()) {
401 if (videopin->getCurrentMediaSample(ms)!=S_OK) {
407 int DsSourceFilter::DeliverAudioMediaSample(IMediaSample* ms)
409 if (!audiopin || !IsActive()) {
413 if (audiopin->deliver(ms)!=S_OK) {
422 bool DsSourceFilter::supportsAc3()
424 if (!audiopin || !IsActive()) {
427 return audiopin->supportsAc3();
430 int DsSourceFilter::DeliverVideoMediaSample(IMediaSample* ms)
432 if (!videopin || !IsActive()) {
436 if (videopin->deliver(ms)!=S_OK) {
445 bool DsSourceFilter::changeAType(int type,IMediaSample* ms)
450 audiopin->SetPinMode(type);
451 audiopin->SetMsToMt(ms);