25 #define imemoffset offsetof(DShowPin, imemvtbl)
28 { {&IID_IUnknown,0}, {&IID_IPin,0}, {&IID_IMemInputPin,
imemoffset} })
39 const AM_MEDIA_TYPE *
type)
42 dshowdebug(
"ff_dshow_pin_ReceiveConnection(%p)\n",
this);
46 if (this->connectedto)
47 return VFW_E_ALREADY_CONNECTED;
51 if (!IsEqualGUID(&
type->majortype, &MEDIATYPE_Video))
52 return VFW_E_TYPE_NOT_ACCEPTED;
54 if (!IsEqualGUID(&
type->majortype, &MEDIATYPE_Audio))
55 return VFW_E_TYPE_NOT_ACCEPTED;
59 this->connectedto = pin;
67 dshowdebug(
"ff_dshow_pin_Disconnect(%p)\n",
this);
69 if (this->
filter->state != State_Stopped)
70 return VFW_E_NOT_STOPPED;
71 if (!this->connectedto)
73 IPin_Release(this->connectedto);
74 this->connectedto =
NULL;
80 dshowdebug(
"ff_dshow_pin_ConnectedTo(%p)\n",
this);
84 if (!this->connectedto)
85 return VFW_E_NOT_CONNECTED;
86 IPin_AddRef(this->connectedto);
87 *pin = this->connectedto;
93 dshowdebug(
"ff_dshow_pin_ConnectionMediaType(%p)\n",
this);
97 if (!this->connectedto)
98 return VFW_E_NOT_CONNECTED;
104 dshowdebug(
"ff_dshow_pin_QueryPinInfo(%p)\n",
this);
112 info->pFilter = (IBaseFilter *) this->
filter;
113 info->dir = PINDIR_INPUT;
114 wcscpy(
info->achName,
L"Capture");
120 dshowdebug(
"ff_dshow_pin_QueryDirection(%p)\n",
this);
128 dshowdebug(
"ff_dshow_pin_QueryId(%p)\n",
this);
133 *
id = wcsdup(
L"libAV Pin");
139 dshowdebug(
"ff_dshow_pin_QueryAccept(%p)\n",
this);
146 dshowdebug(
"ff_dshow_pin_EnumMediaTypes(%p)\n",
this);
152 return E_OUTOFMEMORY;
154 *enumtypes = (IEnumMediaTypes *)
new;
160 dshowdebug(
"ff_dshow_pin_QueryInternalConnections(%p)\n",
this);
165 dshowdebug(
"ff_dshow_pin_EndOfStream(%p)\n",
this);
171 dshowdebug(
"ff_dshow_pin_BeginFlush(%p)\n",
this);
177 dshowdebug(
"ff_dshow_pin_EndFlush(%p)\n",
this);
184 dshowdebug(
"ff_dshow_pin_NewSegment(%p)\n",
this);
191 IPinVtbl *vtbl = this->vtbl;
192 IMemInputPinVtbl *imemvtbl;
197 imemvtbl =
av_malloc(
sizeof(IMemInputPinVtbl));
201 SETVTBL(imemvtbl, meminputpin, QueryInterface);
202 SETVTBL(imemvtbl, meminputpin, AddRef);
203 SETVTBL(imemvtbl, meminputpin, Release);
204 SETVTBL(imemvtbl, meminputpin, GetAllocator);
205 SETVTBL(imemvtbl, meminputpin, NotifyAllocator);
206 SETVTBL(imemvtbl, meminputpin, GetAllocatorRequirements);
207 SETVTBL(imemvtbl, meminputpin, Receive);
208 SETVTBL(imemvtbl, meminputpin, ReceiveMultiple);
209 SETVTBL(imemvtbl, meminputpin, ReceiveCanBlock);
211 this->imemvtbl = imemvtbl;
213 SETVTBL(vtbl, pin, QueryInterface);
217 SETVTBL(vtbl, pin, ReceiveConnection);
218 SETVTBL(vtbl, pin, Disconnect);
219 SETVTBL(vtbl, pin, ConnectedTo);
220 SETVTBL(vtbl, pin, ConnectionMediaType);
221 SETVTBL(vtbl, pin, QueryPinInfo);
222 SETVTBL(vtbl, pin, QueryDirection);
224 SETVTBL(vtbl, pin, QueryAccept);
225 SETVTBL(vtbl, pin, EnumMediaTypes);
226 SETVTBL(vtbl, pin, QueryInternalConnections);
227 SETVTBL(vtbl, pin, EndOfStream);
228 SETVTBL(vtbl, pin, BeginFlush);
230 SETVTBL(vtbl, pin, NewSegment);
242 if (this->
type.pbFormat) {
243 CoTaskMemFree(this->
type.pbFormat);
257 dshowdebug(
"ff_dshow_meminputpin_QueryInterface(%p)\n",
this);
263 dshowdebug(
"ff_dshow_meminputpin_AddRef(%p)\n",
this);
269 dshowdebug(
"ff_dshow_meminputpin_Release(%p)\n",
this);
274 dshowdebug(
"ff_dshow_meminputpin_GetAllocator(%p)\n",
this);
275 return VFW_E_NO_ALLOCATOR;
280 dshowdebug(
"ff_dshow_meminputpin_NotifyAllocator(%p)\n",
this);
284 ALLOCATOR_PROPERTIES *props)
286 dshowdebug(
"ff_dshow_meminputpin_GetAllocatorRequirements(%p)\n",
this);
298 int64_t chosentime = 0;
299 int64_t sampletime = 0;
300 int64_t graphtime = 0;
301 int use_sample_time = 1;
302 const char *devtypename = (devtype ==
VideoDevice) ?
"video" :
"audio";
309 dshowdebug(
"ff_dshow_meminputpin_Receive(%p)\n",
this);
318 hr = IMediaSample_GetTime(
sample, &sampletime, &
dummy);
319 IReferenceClock_GetTime(clock, &graphtime);
320 if (devtype ==
VideoDevice && !
ctx->use_video_device_timestamps) {
322 chosentime = graphtime;
325 if (hr == VFW_E_SAMPLE_TIME_NOT_SET || sampletime == 0) {
326 chosentime = graphtime;
329 "frame with missing sample timestamp encountered, falling back to graph timestamp\n");
331 else if (sampletime > 400000000000000000LL) {
336 "dropping initial (or ending) sample with odd PTS too high %"PRId64
"\n", sampletime);
339 chosentime = sampletime;
346 buf_size = IMediaSample_GetActualDataLength(
sample);
347 IMediaSample_GetPointer(
sample, &buf);
351 "timestamp %"PRId64
" orig timestamp %"PRId64
" graph timestamp %"PRId64
" diff %"PRId64
" %s\n",
352 devtypename, buf_size, chosentime, sampletime, graphtime, graphtime - sampletime,
ctx->device_name[devtype]);
358 IMediaSample **
samples,
long n,
long *nproc)
361 dshowdebug(
"ff_dshow_meminputpin_ReceiveMultiple(%p)\n",
this);
363 for (
i = 0;
i < n;
i++)
371 dshowdebug(
"ff_dshow_meminputpin_ReceiveCanBlock(%p)\n",
this);
379 dshowdebug(
"ff_dshow_meminputpin_Destroy(%p)\n",
this);