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
23
24 #include <stddef.h>
25 #define imemoffset offsetof(libAVPin, imemvtbl)
26
28 { {&IID_IUnknown,0}, {&IID_IPin,0}, {&IID_IMemInputPin,
imemoffset} })
31
32 long WINAPI
34 {
35 dshowdebug(
"libAVPin_Connect(%p, %p, %p)\n",
this, pin, type);
36 /* Input pins receive connections. */
38 }
39 long WINAPI
41 const AM_MEDIA_TYPE *type)
42 {
44 dshowdebug(
"libAVPin_ReceiveConnection(%p)\n",
this);
45
46 if (!pin)
48 if (this->connectedto)
49 return VFW_E_ALREADY_CONNECTED;
50
53 if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Video))
54 return VFW_E_TYPE_NOT_ACCEPTED;
55 } else {
56 if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Audio))
57 return VFW_E_TYPE_NOT_ACCEPTED;
58 }
59
60 IPin_AddRef(pin);
61 this->connectedto = pin;
62
64
66 }
67 long WINAPI
69 {
71
72 if (this->
filter->state != State_Stopped)
73 return VFW_E_NOT_STOPPED;
74 if (!this->connectedto)
76 IPin_Release(this->connectedto);
77 this->connectedto = NULL;
78
80 }
81 long WINAPI
83 {
84 dshowdebug(
"libAVPin_ConnectedTo(%p)\n",
this);
85
86 if (!pin)
88 if (!this->connectedto)
89 return VFW_E_NOT_CONNECTED;
90 IPin_AddRef(this->connectedto);
91 *pin = this->connectedto;
92
94 }
95 long WINAPI
97 {
98 dshowdebug(
"libAVPin_ConnectionMediaType(%p)\n",
this);
99
100 if (!type)
102 if (!this->connectedto)
103 return VFW_E_NOT_CONNECTED;
104
106 }
107 long WINAPI
109 {
110 dshowdebug(
"libAVPin_QueryPinInfo(%p)\n",
this);
111
112 if (!info)
114
117
118 info->pFilter = (IBaseFilter *) this->
filter;
119 info->dir = PINDIR_INPUT;
120 wcscpy(info->achName,
L "Capture");
121
123 }
124 long WINAPI
126 {
127 dshowdebug(
"libAVPin_QueryDirection(%p)\n",
this);
128 if (!dir)
130 *dir = PINDIR_INPUT;
132 }
133 long WINAPI
135 {
137
138 if (!id)
140
141 *
id = wcsdup(
L "libAV Pin");
142
144 }
145 long WINAPI
147 {
148 dshowdebug(
"libAVPin_QueryAccept(%p)\n",
this);
150 }
151 long WINAPI
153 {
154 const AM_MEDIA_TYPE *
type = NULL;
156 dshowdebug(
"libAVPin_EnumMediaTypes(%p)\n",
this);
157
158 if (!enumtypes)
161 if (!new)
163
164 *enumtypes = (IEnumMediaTypes *) new;
166 }
167 long WINAPI
169 unsigned long *npin)
170 {
171 dshowdebug(
"libAVPin_QueryInternalConnections(%p)\n",
this);
172 return E_NOTIMPL;
173 }
174 long WINAPI
176 {
177 dshowdebug(
"libAVPin_EndOfStream(%p)\n",
this);
178 /* I don't care. */
180 }
181 long WINAPI
183 {
184 dshowdebug(
"libAVPin_BeginFlush(%p)\n",
this);
185 /* I don't care. */
187 }
188 long WINAPI
190 {
192 /* I don't care. */
194 }
195 long WINAPI
197 double rate)
198 {
199 dshowdebug(
"libAVPin_NewSegment(%p)\n",
this);
200 /* I don't care. */
202 }
203
204 static int
206 {
207 IPinVtbl *vtbl = this->vtbl;
208 IMemInputPinVtbl *imemvtbl;
209
210 if (!filter)
211 return 0;
212
213 imemvtbl =
av_malloc(
sizeof(IMemInputPinVtbl));
214 if (!imemvtbl)
215 return 0;
216
226
227 this->imemvtbl = imemvtbl;
228
247
249
250 return 1;
251 }
254
255 /*****************************************************************************
256 * libAVMemInputPin
257 ****************************************************************************/
258 long WINAPI
260 void **ppvObject)
261 {
263 dshowdebug(
"libAVMemInputPin_QueryInterface(%p)\n",
this);
265 }
266 unsigned long WINAPI
268 {
270 dshowdebug(
"libAVMemInputPin_AddRef(%p)\n",
this);
272 }
273 unsigned long WINAPI
275 {
277 dshowdebug(
"libAVMemInputPin_Release(%p)\n",
this);
279 }
280 long WINAPI
282 {
283 dshowdebug(
"libAVMemInputPin_GetAllocator(%p)\n",
this);
284 return VFW_E_NO_ALLOCATOR;
285 }
286 long WINAPI
289 {
290 dshowdebug(
"libAVMemInputPin_NotifyAllocator(%p)\n",
this);
292 }
293 long WINAPI
295 ALLOCATOR_PROPERTIES *props)
296 {
297 dshowdebug(
"libAVMemInputPin_GetAllocatorRequirements(%p)\n",
this);
298 return E_NOTIMPL;
299 }
300 long WINAPI
302 {
305 void *priv_data;
307 int buf_size;
309 int64_t curtime;
310
311 dshowdebug(
"libAVMemInputPin_Receive(%p)\n",
this);
312
313 if (!sample)
315
317 /* PTS from video devices is unreliable. */
319 IReferenceClock_GetTime(clock, &curtime);
320 } else {
322 IMediaSample_GetTime(sample, &curtime, &dummy);
324 }
325
326 buf_size = IMediaSample_GetActualDataLength(sample);
327 IMediaSample_GetPointer(sample, &buf);
330
332
334 }
335 long WINAPI
337 IMediaSample **samples,
long n,
long *nproc)
338 {
339 int i;
340 dshowdebug(
"libAVMemInputPin_ReceiveMultiple(%p)\n",
this);
341
342 for (i = 0; i <
n; i++)
344
347 }
348 long WINAPI
350 {
351 dshowdebug(
"libAVMemInputPin_ReceiveCanBlock(%p)\n",
this);
352 /* I swear I will not block. */
354 }
355
356 void
358 {
360 dshowdebug(
"libAVMemInputPin_Destroy(%p)\n",
this);
362 }