• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * DirectShow capture interface
3  * Copyright (c) 2010 Ramiro Polla
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "dshow_capture.h"
23 
24 DECLARE_QUERYINTERFACE(filter, DShowFilter,
25     { {&IID_IUnknown,0}, {&IID_IBaseFilter,0} })
DECLARE_ADDREF(filter,DShowFilter)26 DECLARE_ADDREF(filter, DShowFilter)
27 DECLARE_RELEASE(filter, DShowFilter)
28 
29 long ff_dshow_filter_GetClassID(DShowFilter *this, CLSID *id)
30 {
31     dshowdebug("ff_dshow_filter_GetClassID(%p)\n", this);
32     /* I'm not creating a ClassID just for this. */
33     return E_FAIL;
34 }
ff_dshow_filter_Stop(DShowFilter * this)35 long ff_dshow_filter_Stop(DShowFilter *this)
36 {
37     dshowdebug("ff_dshow_filter_Stop(%p)\n", this);
38     this->state = State_Stopped;
39     return S_OK;
40 }
ff_dshow_filter_Pause(DShowFilter * this)41 long ff_dshow_filter_Pause(DShowFilter *this)
42 {
43     dshowdebug("ff_dshow_filter_Pause(%p)\n", this);
44     this->state = State_Paused;
45     return S_OK;
46 }
ff_dshow_filter_Run(DShowFilter * this,REFERENCE_TIME start)47 long ff_dshow_filter_Run(DShowFilter *this, REFERENCE_TIME start)
48 {
49     dshowdebug("ff_dshow_filter_Run(%p) %"PRId64"\n", this, start);
50     this->state = State_Running;
51     this->start_time = start;
52     return S_OK;
53 }
ff_dshow_filter_GetState(DShowFilter * this,DWORD ms,FILTER_STATE * state)54 long ff_dshow_filter_GetState(DShowFilter *this, DWORD ms, FILTER_STATE *state)
55 {
56     dshowdebug("ff_dshow_filter_GetState(%p)\n", this);
57     if (!state)
58         return E_POINTER;
59     *state = this->state;
60     return S_OK;
61 }
ff_dshow_filter_SetSyncSource(DShowFilter * this,IReferenceClock * clock)62 long ff_dshow_filter_SetSyncSource(DShowFilter *this, IReferenceClock *clock)
63 {
64     dshowdebug("ff_dshow_filter_SetSyncSource(%p)\n", this);
65 
66     if (this->clock != clock) {
67         if (this->clock)
68             IReferenceClock_Release(this->clock);
69         this->clock = clock;
70         if (clock)
71             IReferenceClock_AddRef(clock);
72     }
73 
74     return S_OK;
75 }
ff_dshow_filter_GetSyncSource(DShowFilter * this,IReferenceClock ** clock)76 long ff_dshow_filter_GetSyncSource(DShowFilter *this, IReferenceClock **clock)
77 {
78     dshowdebug("ff_dshow_filter_GetSyncSource(%p)\n", this);
79 
80     if (!clock)
81         return E_POINTER;
82     if (this->clock)
83         IReferenceClock_AddRef(this->clock);
84     *clock = this->clock;
85 
86     return S_OK;
87 }
ff_dshow_filter_EnumPins(DShowFilter * this,IEnumPins ** enumpin)88 long ff_dshow_filter_EnumPins(DShowFilter *this, IEnumPins **enumpin)
89 {
90     DShowEnumPins *new;
91     dshowdebug("ff_dshow_filter_EnumPins(%p)\n", this);
92 
93     if (!enumpin)
94         return E_POINTER;
95     new = ff_dshow_enumpins_Create(this->pin, this);
96     if (!new)
97         return E_OUTOFMEMORY;
98 
99     *enumpin = (IEnumPins *) new;
100     return S_OK;
101 }
ff_dshow_filter_FindPin(DShowFilter * this,const wchar_t * id,IPin ** pin)102 long ff_dshow_filter_FindPin(DShowFilter *this, const wchar_t *id, IPin **pin)
103 {
104     DShowPin *found = NULL;
105     dshowdebug("ff_dshow_filter_FindPin(%p)\n", this);
106 
107     if (!id || !pin)
108         return E_POINTER;
109     if (!wcscmp(id, L"In")) {
110         found = this->pin;
111         ff_dshow_pin_AddRef(found);
112     }
113     *pin = (IPin *) found;
114     if (!found)
115         return VFW_E_NOT_FOUND;
116 
117     return S_OK;
118 }
ff_dshow_filter_QueryFilterInfo(DShowFilter * this,FILTER_INFO * info)119 long ff_dshow_filter_QueryFilterInfo(DShowFilter *this, FILTER_INFO *info)
120 {
121     dshowdebug("ff_dshow_filter_QueryFilterInfo(%p)\n", this);
122 
123     if (!info)
124         return E_POINTER;
125     if (this->info.pGraph)
126         IFilterGraph_AddRef(this->info.pGraph);
127     *info = this->info;
128 
129     return S_OK;
130 }
ff_dshow_filter_JoinFilterGraph(DShowFilter * this,IFilterGraph * graph,const wchar_t * name)131 long ff_dshow_filter_JoinFilterGraph(DShowFilter *this, IFilterGraph *graph,
132                             const wchar_t *name)
133 {
134     dshowdebug("ff_dshow_filter_JoinFilterGraph(%p)\n", this);
135 
136     this->info.pGraph = graph;
137     if (name)
138         wcscpy(this->info.achName, name);
139 
140     return S_OK;
141 }
ff_dshow_filter_QueryVendorInfo(DShowFilter * this,wchar_t ** info)142 long ff_dshow_filter_QueryVendorInfo(DShowFilter *this, wchar_t **info)
143 {
144     dshowdebug("ff_dshow_filter_QueryVendorInfo(%p)\n", this);
145 
146     if (!info)
147         return E_POINTER;
148     return E_NOTIMPL; /* don't have to do anything here */
149 }
150 
151 static int
ff_dshow_filter_Setup(DShowFilter * this,void * priv_data,void * callback,enum dshowDeviceType type)152 ff_dshow_filter_Setup(DShowFilter *this, void *priv_data, void *callback,
153                   enum dshowDeviceType type)
154 {
155     IBaseFilterVtbl *vtbl = this->vtbl;
156     SETVTBL(vtbl, filter, QueryInterface);
157     SETVTBL(vtbl, filter, AddRef);
158     SETVTBL(vtbl, filter, Release);
159     SETVTBL(vtbl, filter, GetClassID);
160     SETVTBL(vtbl, filter, Stop);
161     SETVTBL(vtbl, filter, Pause);
162     SETVTBL(vtbl, filter, Run);
163     SETVTBL(vtbl, filter, GetState);
164     SETVTBL(vtbl, filter, SetSyncSource);
165     SETVTBL(vtbl, filter, GetSyncSource);
166     SETVTBL(vtbl, filter, EnumPins);
167     SETVTBL(vtbl, filter, FindPin);
168     SETVTBL(vtbl, filter, QueryFilterInfo);
169     SETVTBL(vtbl, filter, JoinFilterGraph);
170     SETVTBL(vtbl, filter, QueryVendorInfo);
171 
172     this->pin = ff_dshow_pin_Create(this);
173 
174     this->priv_data = priv_data;
175     this->callback  = callback;
176     this->type      = type;
177 
178     return 1;
179 }
ff_dshow_filter_Cleanup(DShowFilter * this)180 static int ff_dshow_filter_Cleanup(DShowFilter *this)
181 {
182     ff_dshow_pin_Release(this->pin);
183     return 1;
184 }
185 DECLARE_CREATE(filter, DShowFilter, ff_dshow_filter_Setup(this, priv_data, callback, type),
186                void *priv_data, void *callback, enum dshowDeviceType type)
187 DECLARE_DESTROY(filter, DShowFilter, ff_dshow_filter_Cleanup)
188