Commit | Line | Data |
---|---|---|
2ba45a60 DM |
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(libAVFilter, | |
25 | { {&IID_IUnknown,0}, {&IID_IBaseFilter,0} }) | |
26 | DECLARE_ADDREF(libAVFilter) | |
27 | DECLARE_RELEASE(libAVFilter) | |
28 | ||
29 | long WINAPI | |
30 | libAVFilter_GetClassID(libAVFilter *this, CLSID *id) | |
31 | { | |
32 | dshowdebug("libAVFilter_GetClassID(%p)\n", this); | |
33 | /* I'm not creating a ClassID just for this. */ | |
34 | return E_FAIL; | |
35 | } | |
36 | long WINAPI | |
37 | libAVFilter_Stop(libAVFilter *this) | |
38 | { | |
39 | dshowdebug("libAVFilter_Stop(%p)\n", this); | |
40 | this->state = State_Stopped; | |
41 | return S_OK; | |
42 | } | |
43 | long WINAPI | |
44 | libAVFilter_Pause(libAVFilter *this) | |
45 | { | |
46 | dshowdebug("libAVFilter_Pause(%p)\n", this); | |
47 | this->state = State_Paused; | |
48 | return S_OK; | |
49 | } | |
50 | long WINAPI | |
51 | libAVFilter_Run(libAVFilter *this, REFERENCE_TIME start) | |
52 | { | |
53 | dshowdebug("libAVFilter_Run(%p) %"PRId64"\n", this, start); | |
54 | this->state = State_Running; | |
55 | this->start_time = start; | |
56 | return S_OK; | |
57 | } | |
58 | long WINAPI | |
59 | libAVFilter_GetState(libAVFilter *this, DWORD ms, FILTER_STATE *state) | |
60 | { | |
61 | dshowdebug("libAVFilter_GetState(%p)\n", this); | |
62 | if (!state) | |
63 | return E_POINTER; | |
64 | *state = this->state; | |
65 | return S_OK; | |
66 | } | |
67 | long WINAPI | |
68 | libAVFilter_SetSyncSource(libAVFilter *this, IReferenceClock *clock) | |
69 | { | |
70 | dshowdebug("libAVFilter_SetSyncSource(%p)\n", this); | |
71 | ||
72 | if (this->clock != clock) { | |
73 | if (this->clock) | |
74 | IReferenceClock_Release(this->clock); | |
75 | this->clock = clock; | |
76 | if (clock) | |
77 | IReferenceClock_AddRef(clock); | |
78 | } | |
79 | ||
80 | return S_OK; | |
81 | } | |
82 | long WINAPI | |
83 | libAVFilter_GetSyncSource(libAVFilter *this, IReferenceClock **clock) | |
84 | { | |
85 | dshowdebug("libAVFilter_GetSyncSource(%p)\n", this); | |
86 | ||
87 | if (!clock) | |
88 | return E_POINTER; | |
89 | if (this->clock) | |
90 | IReferenceClock_AddRef(this->clock); | |
91 | *clock = this->clock; | |
92 | ||
93 | return S_OK; | |
94 | } | |
95 | long WINAPI | |
96 | libAVFilter_EnumPins(libAVFilter *this, IEnumPins **enumpin) | |
97 | { | |
98 | libAVEnumPins *new; | |
99 | dshowdebug("libAVFilter_EnumPins(%p)\n", this); | |
100 | ||
101 | if (!enumpin) | |
102 | return E_POINTER; | |
103 | new = libAVEnumPins_Create(this->pin, this); | |
104 | if (!new) | |
105 | return E_OUTOFMEMORY; | |
106 | ||
107 | *enumpin = (IEnumPins *) new; | |
108 | return S_OK; | |
109 | } | |
110 | long WINAPI | |
111 | libAVFilter_FindPin(libAVFilter *this, const wchar_t *id, IPin **pin) | |
112 | { | |
113 | libAVPin *found = NULL; | |
114 | dshowdebug("libAVFilter_FindPin(%p)\n", this); | |
115 | ||
116 | if (!id || !pin) | |
117 | return E_POINTER; | |
118 | if (!wcscmp(id, L"In")) { | |
119 | found = this->pin; | |
120 | libAVPin_AddRef(found); | |
121 | } | |
122 | *pin = (IPin *) found; | |
123 | if (!found) | |
124 | return VFW_E_NOT_FOUND; | |
125 | ||
126 | return S_OK; | |
127 | } | |
128 | long WINAPI | |
129 | libAVFilter_QueryFilterInfo(libAVFilter *this, FILTER_INFO *info) | |
130 | { | |
131 | dshowdebug("libAVFilter_QueryFilterInfo(%p)\n", this); | |
132 | ||
133 | if (!info) | |
134 | return E_POINTER; | |
135 | if (this->info.pGraph) | |
136 | IFilterGraph_AddRef(this->info.pGraph); | |
137 | *info = this->info; | |
138 | ||
139 | return S_OK; | |
140 | } | |
141 | long WINAPI | |
142 | libAVFilter_JoinFilterGraph(libAVFilter *this, IFilterGraph *graph, | |
143 | const wchar_t *name) | |
144 | { | |
145 | dshowdebug("libAVFilter_JoinFilterGraph(%p)\n", this); | |
146 | ||
147 | this->info.pGraph = graph; | |
148 | if (name) | |
149 | wcscpy(this->info.achName, name); | |
150 | ||
151 | return S_OK; | |
152 | } | |
153 | long WINAPI | |
154 | libAVFilter_QueryVendorInfo(libAVFilter *this, wchar_t **info) | |
155 | { | |
156 | dshowdebug("libAVFilter_QueryVendorInfo(%p)\n", this); | |
157 | ||
158 | if (!info) | |
159 | return E_POINTER; | |
160 | *info = wcsdup(L"libAV"); | |
161 | ||
162 | return S_OK; | |
163 | } | |
164 | ||
165 | static int | |
166 | libAVFilter_Setup(libAVFilter *this, void *priv_data, void *callback, | |
167 | enum dshowDeviceType type) | |
168 | { | |
169 | IBaseFilterVtbl *vtbl = this->vtbl; | |
170 | SETVTBL(vtbl, libAVFilter, QueryInterface); | |
171 | SETVTBL(vtbl, libAVFilter, AddRef); | |
172 | SETVTBL(vtbl, libAVFilter, Release); | |
173 | SETVTBL(vtbl, libAVFilter, GetClassID); | |
174 | SETVTBL(vtbl, libAVFilter, Stop); | |
175 | SETVTBL(vtbl, libAVFilter, Pause); | |
176 | SETVTBL(vtbl, libAVFilter, Run); | |
177 | SETVTBL(vtbl, libAVFilter, GetState); | |
178 | SETVTBL(vtbl, libAVFilter, SetSyncSource); | |
179 | SETVTBL(vtbl, libAVFilter, GetSyncSource); | |
180 | SETVTBL(vtbl, libAVFilter, EnumPins); | |
181 | SETVTBL(vtbl, libAVFilter, FindPin); | |
182 | SETVTBL(vtbl, libAVFilter, QueryFilterInfo); | |
183 | SETVTBL(vtbl, libAVFilter, JoinFilterGraph); | |
184 | SETVTBL(vtbl, libAVFilter, QueryVendorInfo); | |
185 | ||
186 | this->pin = libAVPin_Create(this); | |
187 | ||
188 | this->priv_data = priv_data; | |
189 | this->callback = callback; | |
190 | this->type = type; | |
191 | ||
192 | return 1; | |
193 | } | |
194 | static int | |
195 | libAVFilter_Cleanup(libAVFilter *this) | |
196 | { | |
197 | libAVPin_Release(this->pin); | |
198 | return 1; | |
199 | } | |
200 | DECLARE_CREATE(libAVFilter, libAVFilter_Setup(this, priv_data, callback, type), | |
201 | void *priv_data, void *callback, enum dshowDeviceType type) | |
202 | DECLARE_DESTROY(libAVFilter, libAVFilter_Cleanup) |