1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * DirectShow capture interface 3cabdff1aSopenharmony_ci * Copyright (c) 2010 Ramiro Polla 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#include "dshow_capture.h" 23cabdff1aSopenharmony_ci 24cabdff1aSopenharmony_ci#include <stddef.h> 25cabdff1aSopenharmony_ci#define imemoffset offsetof(DShowPin, imemvtbl) 26cabdff1aSopenharmony_ci 27cabdff1aSopenharmony_ciDECLARE_QUERYINTERFACE(pin, DShowPin, 28cabdff1aSopenharmony_ci { {&IID_IUnknown,0}, {&IID_IPin,0}, {&IID_IMemInputPin,imemoffset} }) 29cabdff1aSopenharmony_ciDECLARE_ADDREF(pin, DShowPin) 30cabdff1aSopenharmony_ciDECLARE_RELEASE(pin, DShowPin) 31cabdff1aSopenharmony_ci 32cabdff1aSopenharmony_cilong WINAPI ff_dshow_pin_Connect(DShowPin *this, IPin *pin, const AM_MEDIA_TYPE *type) 33cabdff1aSopenharmony_ci{ 34cabdff1aSopenharmony_ci dshowdebug("ff_dshow_pin_Connect(%p, %p, %p)\n", this, pin, type); 35cabdff1aSopenharmony_ci /* Input pins receive connections. */ 36cabdff1aSopenharmony_ci return S_FALSE; 37cabdff1aSopenharmony_ci} 38cabdff1aSopenharmony_cilong WINAPI ff_dshow_pin_ReceiveConnection(DShowPin *this, IPin *pin, 39cabdff1aSopenharmony_ci const AM_MEDIA_TYPE *type) 40cabdff1aSopenharmony_ci{ 41cabdff1aSopenharmony_ci enum dshowDeviceType devtype = this->filter->type; 42cabdff1aSopenharmony_ci dshowdebug("ff_dshow_pin_ReceiveConnection(%p)\n", this); 43cabdff1aSopenharmony_ci 44cabdff1aSopenharmony_ci if (!pin) 45cabdff1aSopenharmony_ci return E_POINTER; 46cabdff1aSopenharmony_ci if (this->connectedto) 47cabdff1aSopenharmony_ci return VFW_E_ALREADY_CONNECTED; 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_ci ff_print_AM_MEDIA_TYPE(type); 50cabdff1aSopenharmony_ci if (devtype == VideoDevice) { 51cabdff1aSopenharmony_ci if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Video)) 52cabdff1aSopenharmony_ci return VFW_E_TYPE_NOT_ACCEPTED; 53cabdff1aSopenharmony_ci } else { 54cabdff1aSopenharmony_ci if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Audio)) 55cabdff1aSopenharmony_ci return VFW_E_TYPE_NOT_ACCEPTED; 56cabdff1aSopenharmony_ci } 57cabdff1aSopenharmony_ci 58cabdff1aSopenharmony_ci IPin_AddRef(pin); 59cabdff1aSopenharmony_ci this->connectedto = pin; 60cabdff1aSopenharmony_ci 61cabdff1aSopenharmony_ci ff_copy_dshow_media_type(&this->type, type); 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_ci return S_OK; 64cabdff1aSopenharmony_ci} 65cabdff1aSopenharmony_cilong WINAPI ff_dshow_pin_Disconnect(DShowPin *this) 66cabdff1aSopenharmony_ci{ 67cabdff1aSopenharmony_ci dshowdebug("ff_dshow_pin_Disconnect(%p)\n", this); 68cabdff1aSopenharmony_ci 69cabdff1aSopenharmony_ci if (this->filter->state != State_Stopped) 70cabdff1aSopenharmony_ci return VFW_E_NOT_STOPPED; 71cabdff1aSopenharmony_ci if (!this->connectedto) 72cabdff1aSopenharmony_ci return S_FALSE; 73cabdff1aSopenharmony_ci IPin_Release(this->connectedto); 74cabdff1aSopenharmony_ci this->connectedto = NULL; 75cabdff1aSopenharmony_ci 76cabdff1aSopenharmony_ci return S_OK; 77cabdff1aSopenharmony_ci} 78cabdff1aSopenharmony_cilong WINAPI ff_dshow_pin_ConnectedTo(DShowPin *this, IPin **pin) 79cabdff1aSopenharmony_ci{ 80cabdff1aSopenharmony_ci dshowdebug("ff_dshow_pin_ConnectedTo(%p)\n", this); 81cabdff1aSopenharmony_ci 82cabdff1aSopenharmony_ci if (!pin) 83cabdff1aSopenharmony_ci return E_POINTER; 84cabdff1aSopenharmony_ci if (!this->connectedto) 85cabdff1aSopenharmony_ci return VFW_E_NOT_CONNECTED; 86cabdff1aSopenharmony_ci IPin_AddRef(this->connectedto); 87cabdff1aSopenharmony_ci *pin = this->connectedto; 88cabdff1aSopenharmony_ci 89cabdff1aSopenharmony_ci return S_OK; 90cabdff1aSopenharmony_ci} 91cabdff1aSopenharmony_cilong WINAPI ff_dshow_pin_ConnectionMediaType(DShowPin *this, AM_MEDIA_TYPE *type) 92cabdff1aSopenharmony_ci{ 93cabdff1aSopenharmony_ci dshowdebug("ff_dshow_pin_ConnectionMediaType(%p)\n", this); 94cabdff1aSopenharmony_ci 95cabdff1aSopenharmony_ci if (!type) 96cabdff1aSopenharmony_ci return E_POINTER; 97cabdff1aSopenharmony_ci if (!this->connectedto) 98cabdff1aSopenharmony_ci return VFW_E_NOT_CONNECTED; 99cabdff1aSopenharmony_ci 100cabdff1aSopenharmony_ci return ff_copy_dshow_media_type(type, &this->type); 101cabdff1aSopenharmony_ci} 102cabdff1aSopenharmony_cilong WINAPI ff_dshow_pin_QueryPinInfo(DShowPin *this, PIN_INFO *info) 103cabdff1aSopenharmony_ci{ 104cabdff1aSopenharmony_ci dshowdebug("ff_dshow_pin_QueryPinInfo(%p)\n", this); 105cabdff1aSopenharmony_ci 106cabdff1aSopenharmony_ci if (!info) 107cabdff1aSopenharmony_ci return E_POINTER; 108cabdff1aSopenharmony_ci 109cabdff1aSopenharmony_ci if (this->filter) 110cabdff1aSopenharmony_ci ff_dshow_filter_AddRef(this->filter); 111cabdff1aSopenharmony_ci 112cabdff1aSopenharmony_ci info->pFilter = (IBaseFilter *) this->filter; 113cabdff1aSopenharmony_ci info->dir = PINDIR_INPUT; 114cabdff1aSopenharmony_ci wcscpy(info->achName, L"Capture"); 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci return S_OK; 117cabdff1aSopenharmony_ci} 118cabdff1aSopenharmony_cilong WINAPI ff_dshow_pin_QueryDirection(DShowPin *this, PIN_DIRECTION *dir) 119cabdff1aSopenharmony_ci{ 120cabdff1aSopenharmony_ci dshowdebug("ff_dshow_pin_QueryDirection(%p)\n", this); 121cabdff1aSopenharmony_ci if (!dir) 122cabdff1aSopenharmony_ci return E_POINTER; 123cabdff1aSopenharmony_ci *dir = PINDIR_INPUT; 124cabdff1aSopenharmony_ci return S_OK; 125cabdff1aSopenharmony_ci} 126cabdff1aSopenharmony_cilong WINAPI ff_dshow_pin_QueryId(DShowPin *this, wchar_t **id) 127cabdff1aSopenharmony_ci{ 128cabdff1aSopenharmony_ci dshowdebug("ff_dshow_pin_QueryId(%p)\n", this); 129cabdff1aSopenharmony_ci 130cabdff1aSopenharmony_ci if (!id) 131cabdff1aSopenharmony_ci return E_POINTER; 132cabdff1aSopenharmony_ci 133cabdff1aSopenharmony_ci *id = wcsdup(L"libAV Pin"); 134cabdff1aSopenharmony_ci 135cabdff1aSopenharmony_ci return S_OK; 136cabdff1aSopenharmony_ci} 137cabdff1aSopenharmony_cilong WINAPI ff_dshow_pin_QueryAccept(DShowPin *this, const AM_MEDIA_TYPE *type) 138cabdff1aSopenharmony_ci{ 139cabdff1aSopenharmony_ci dshowdebug("ff_dshow_pin_QueryAccept(%p)\n", this); 140cabdff1aSopenharmony_ci return S_FALSE; 141cabdff1aSopenharmony_ci} 142cabdff1aSopenharmony_cilong WINAPI ff_dshow_pin_EnumMediaTypes(DShowPin *this, IEnumMediaTypes **enumtypes) 143cabdff1aSopenharmony_ci{ 144cabdff1aSopenharmony_ci const AM_MEDIA_TYPE *type = NULL; 145cabdff1aSopenharmony_ci DShowEnumMediaTypes *new; 146cabdff1aSopenharmony_ci dshowdebug("ff_dshow_pin_EnumMediaTypes(%p)\n", this); 147cabdff1aSopenharmony_ci 148cabdff1aSopenharmony_ci if (!enumtypes) 149cabdff1aSopenharmony_ci return E_POINTER; 150cabdff1aSopenharmony_ci new = ff_dshow_enummediatypes_Create(type); 151cabdff1aSopenharmony_ci if (!new) 152cabdff1aSopenharmony_ci return E_OUTOFMEMORY; 153cabdff1aSopenharmony_ci 154cabdff1aSopenharmony_ci *enumtypes = (IEnumMediaTypes *) new; 155cabdff1aSopenharmony_ci return S_OK; 156cabdff1aSopenharmony_ci} 157cabdff1aSopenharmony_cilong WINAPI ff_dshow_pin_QueryInternalConnections(DShowPin *this, IPin **pin, 158cabdff1aSopenharmony_ci unsigned long *npin) 159cabdff1aSopenharmony_ci{ 160cabdff1aSopenharmony_ci dshowdebug("ff_dshow_pin_QueryInternalConnections(%p)\n", this); 161cabdff1aSopenharmony_ci return E_NOTIMPL; 162cabdff1aSopenharmony_ci} 163cabdff1aSopenharmony_cilong WINAPI ff_dshow_pin_EndOfStream(DShowPin *this) 164cabdff1aSopenharmony_ci{ 165cabdff1aSopenharmony_ci dshowdebug("ff_dshow_pin_EndOfStream(%p)\n", this); 166cabdff1aSopenharmony_ci /* I don't care. */ 167cabdff1aSopenharmony_ci return S_OK; 168cabdff1aSopenharmony_ci} 169cabdff1aSopenharmony_cilong WINAPI ff_dshow_pin_BeginFlush(DShowPin *this) 170cabdff1aSopenharmony_ci{ 171cabdff1aSopenharmony_ci dshowdebug("ff_dshow_pin_BeginFlush(%p)\n", this); 172cabdff1aSopenharmony_ci /* I don't care. */ 173cabdff1aSopenharmony_ci return S_OK; 174cabdff1aSopenharmony_ci} 175cabdff1aSopenharmony_cilong WINAPI ff_dshow_pin_EndFlush(DShowPin *this) 176cabdff1aSopenharmony_ci{ 177cabdff1aSopenharmony_ci dshowdebug("ff_dshow_pin_EndFlush(%p)\n", this); 178cabdff1aSopenharmony_ci /* I don't care. */ 179cabdff1aSopenharmony_ci return S_OK; 180cabdff1aSopenharmony_ci} 181cabdff1aSopenharmony_cilong WINAPI ff_dshow_pin_NewSegment(DShowPin *this, REFERENCE_TIME start, REFERENCE_TIME stop, 182cabdff1aSopenharmony_ci double rate) 183cabdff1aSopenharmony_ci{ 184cabdff1aSopenharmony_ci dshowdebug("ff_dshow_pin_NewSegment(%p)\n", this); 185cabdff1aSopenharmony_ci /* I don't care. */ 186cabdff1aSopenharmony_ci return S_OK; 187cabdff1aSopenharmony_ci} 188cabdff1aSopenharmony_ci 189cabdff1aSopenharmony_cistatic int ff_dshow_pin_Setup(DShowPin *this, DShowFilter *filter) 190cabdff1aSopenharmony_ci{ 191cabdff1aSopenharmony_ci IPinVtbl *vtbl = this->vtbl; 192cabdff1aSopenharmony_ci IMemInputPinVtbl *imemvtbl; 193cabdff1aSopenharmony_ci 194cabdff1aSopenharmony_ci if (!filter) 195cabdff1aSopenharmony_ci return 0; 196cabdff1aSopenharmony_ci 197cabdff1aSopenharmony_ci imemvtbl = av_malloc(sizeof(IMemInputPinVtbl)); 198cabdff1aSopenharmony_ci if (!imemvtbl) 199cabdff1aSopenharmony_ci return 0; 200cabdff1aSopenharmony_ci 201cabdff1aSopenharmony_ci SETVTBL(imemvtbl, meminputpin, QueryInterface); 202cabdff1aSopenharmony_ci SETVTBL(imemvtbl, meminputpin, AddRef); 203cabdff1aSopenharmony_ci SETVTBL(imemvtbl, meminputpin, Release); 204cabdff1aSopenharmony_ci SETVTBL(imemvtbl, meminputpin, GetAllocator); 205cabdff1aSopenharmony_ci SETVTBL(imemvtbl, meminputpin, NotifyAllocator); 206cabdff1aSopenharmony_ci SETVTBL(imemvtbl, meminputpin, GetAllocatorRequirements); 207cabdff1aSopenharmony_ci SETVTBL(imemvtbl, meminputpin, Receive); 208cabdff1aSopenharmony_ci SETVTBL(imemvtbl, meminputpin, ReceiveMultiple); 209cabdff1aSopenharmony_ci SETVTBL(imemvtbl, meminputpin, ReceiveCanBlock); 210cabdff1aSopenharmony_ci 211cabdff1aSopenharmony_ci this->imemvtbl = imemvtbl; 212cabdff1aSopenharmony_ci 213cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, QueryInterface); 214cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, AddRef); 215cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, Release); 216cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, Connect); 217cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, ReceiveConnection); 218cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, Disconnect); 219cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, ConnectedTo); 220cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, ConnectionMediaType); 221cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, QueryPinInfo); 222cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, QueryDirection); 223cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, QueryId); 224cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, QueryAccept); 225cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, EnumMediaTypes); 226cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, QueryInternalConnections); 227cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, EndOfStream); 228cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, BeginFlush); 229cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, EndFlush); 230cabdff1aSopenharmony_ci SETVTBL(vtbl, pin, NewSegment); 231cabdff1aSopenharmony_ci 232cabdff1aSopenharmony_ci this->filter = filter; 233cabdff1aSopenharmony_ci 234cabdff1aSopenharmony_ci return 1; 235cabdff1aSopenharmony_ci} 236cabdff1aSopenharmony_ci 237cabdff1aSopenharmony_cistatic void ff_dshow_pin_Free(DShowPin *this) 238cabdff1aSopenharmony_ci{ 239cabdff1aSopenharmony_ci if (!this) 240cabdff1aSopenharmony_ci return; 241cabdff1aSopenharmony_ci av_freep(&this->imemvtbl); 242cabdff1aSopenharmony_ci if (this->type.pbFormat) { 243cabdff1aSopenharmony_ci CoTaskMemFree(this->type.pbFormat); 244cabdff1aSopenharmony_ci this->type.pbFormat = NULL; 245cabdff1aSopenharmony_ci } 246cabdff1aSopenharmony_ci} 247cabdff1aSopenharmony_ciDECLARE_CREATE(pin, DShowPin, ff_dshow_pin_Setup(this, filter), DShowFilter *filter) 248cabdff1aSopenharmony_ciDECLARE_DESTROY(pin, DShowPin, ff_dshow_pin_Free) 249cabdff1aSopenharmony_ci 250cabdff1aSopenharmony_ci/***************************************************************************** 251cabdff1aSopenharmony_ci * DShowMemInputPin 252cabdff1aSopenharmony_ci ****************************************************************************/ 253cabdff1aSopenharmony_cilong WINAPI ff_dshow_meminputpin_QueryInterface(DShowMemInputPin *this, const GUID *riid, 254cabdff1aSopenharmony_ci void **ppvObject) 255cabdff1aSopenharmony_ci{ 256cabdff1aSopenharmony_ci DShowPin *pin = (DShowPin *) ((uint8_t *) this - imemoffset); 257cabdff1aSopenharmony_ci dshowdebug("ff_dshow_meminputpin_QueryInterface(%p)\n", this); 258cabdff1aSopenharmony_ci return ff_dshow_pin_QueryInterface(pin, riid, ppvObject); 259cabdff1aSopenharmony_ci} 260cabdff1aSopenharmony_ciunsigned long WINAPI ff_dshow_meminputpin_AddRef(DShowMemInputPin *this) 261cabdff1aSopenharmony_ci{ 262cabdff1aSopenharmony_ci DShowPin *pin = (DShowPin *) ((uint8_t *) this - imemoffset); 263cabdff1aSopenharmony_ci dshowdebug("ff_dshow_meminputpin_AddRef(%p)\n", this); 264cabdff1aSopenharmony_ci return ff_dshow_pin_AddRef(pin); 265cabdff1aSopenharmony_ci} 266cabdff1aSopenharmony_ciunsigned long WINAPI ff_dshow_meminputpin_Release(DShowMemInputPin *this) 267cabdff1aSopenharmony_ci{ 268cabdff1aSopenharmony_ci DShowPin *pin = (DShowPin *) ((uint8_t *) this - imemoffset); 269cabdff1aSopenharmony_ci dshowdebug("ff_dshow_meminputpin_Release(%p)\n", this); 270cabdff1aSopenharmony_ci return ff_dshow_pin_Release(pin); 271cabdff1aSopenharmony_ci} 272cabdff1aSopenharmony_cilong WINAPI ff_dshow_meminputpin_GetAllocator(DShowMemInputPin *this, IMemAllocator **alloc) 273cabdff1aSopenharmony_ci{ 274cabdff1aSopenharmony_ci dshowdebug("ff_dshow_meminputpin_GetAllocator(%p)\n", this); 275cabdff1aSopenharmony_ci return VFW_E_NO_ALLOCATOR; 276cabdff1aSopenharmony_ci} 277cabdff1aSopenharmony_cilong WINAPI ff_dshow_meminputpin_NotifyAllocator(DShowMemInputPin *this, IMemAllocator *alloc, 278cabdff1aSopenharmony_ci BOOL rdwr) 279cabdff1aSopenharmony_ci{ 280cabdff1aSopenharmony_ci dshowdebug("ff_dshow_meminputpin_NotifyAllocator(%p)\n", this); 281cabdff1aSopenharmony_ci return S_OK; 282cabdff1aSopenharmony_ci} 283cabdff1aSopenharmony_cilong WINAPI ff_dshow_meminputpin_GetAllocatorRequirements(DShowMemInputPin *this, 284cabdff1aSopenharmony_ci ALLOCATOR_PROPERTIES *props) 285cabdff1aSopenharmony_ci{ 286cabdff1aSopenharmony_ci dshowdebug("ff_dshow_meminputpin_GetAllocatorRequirements(%p)\n", this); 287cabdff1aSopenharmony_ci return E_NOTIMPL; 288cabdff1aSopenharmony_ci} 289cabdff1aSopenharmony_cilong WINAPI ff_dshow_meminputpin_Receive(DShowMemInputPin *this, IMediaSample *sample) 290cabdff1aSopenharmony_ci{ 291cabdff1aSopenharmony_ci DShowPin *pin = (DShowPin *) ((uint8_t *) this - imemoffset); 292cabdff1aSopenharmony_ci enum dshowDeviceType devtype = pin->filter->type; 293cabdff1aSopenharmony_ci void *priv_data; 294cabdff1aSopenharmony_ci AVFormatContext *s; 295cabdff1aSopenharmony_ci uint8_t *buf; 296cabdff1aSopenharmony_ci int buf_size; /* todo should be a long? */ 297cabdff1aSopenharmony_ci int index; 298cabdff1aSopenharmony_ci int64_t chosentime = 0; 299cabdff1aSopenharmony_ci int64_t sampletime = 0; 300cabdff1aSopenharmony_ci int64_t graphtime = 0; 301cabdff1aSopenharmony_ci int use_sample_time = 1; 302cabdff1aSopenharmony_ci const char *devtypename = (devtype == VideoDevice) ? "video" : "audio"; 303cabdff1aSopenharmony_ci IReferenceClock *clock = pin->filter->clock; 304cabdff1aSopenharmony_ci int64_t dummy; 305cabdff1aSopenharmony_ci struct dshow_ctx *ctx; 306cabdff1aSopenharmony_ci HRESULT hr; 307cabdff1aSopenharmony_ci 308cabdff1aSopenharmony_ci 309cabdff1aSopenharmony_ci dshowdebug("ff_dshow_meminputpin_Receive(%p)\n", this); 310cabdff1aSopenharmony_ci 311cabdff1aSopenharmony_ci if (!sample) 312cabdff1aSopenharmony_ci return E_POINTER; 313cabdff1aSopenharmony_ci 314cabdff1aSopenharmony_ci priv_data = pin->filter->priv_data; 315cabdff1aSopenharmony_ci s = priv_data; 316cabdff1aSopenharmony_ci ctx = s->priv_data; 317cabdff1aSopenharmony_ci 318cabdff1aSopenharmony_ci hr = IMediaSample_GetTime(sample, &sampletime, &dummy); 319cabdff1aSopenharmony_ci IReferenceClock_GetTime(clock, &graphtime); 320cabdff1aSopenharmony_ci if (devtype == VideoDevice && !ctx->use_video_device_timestamps) { 321cabdff1aSopenharmony_ci /* PTS from video devices is unreliable. */ 322cabdff1aSopenharmony_ci chosentime = graphtime; 323cabdff1aSopenharmony_ci use_sample_time = 0; 324cabdff1aSopenharmony_ci } else { 325cabdff1aSopenharmony_ci if (hr == VFW_E_SAMPLE_TIME_NOT_SET || sampletime == 0) { 326cabdff1aSopenharmony_ci chosentime = graphtime; 327cabdff1aSopenharmony_ci use_sample_time = 0; 328cabdff1aSopenharmony_ci av_log(s, AV_LOG_DEBUG, 329cabdff1aSopenharmony_ci "frame with missing sample timestamp encountered, falling back to graph timestamp\n"); 330cabdff1aSopenharmony_ci } 331cabdff1aSopenharmony_ci else if (sampletime > 400000000000000000LL) { 332cabdff1aSopenharmony_ci /* initial frames sometimes start < 0 (shown as a very large number here, 333cabdff1aSopenharmony_ci like 437650244077016960 which FFmpeg doesn't like). 334cabdff1aSopenharmony_ci TODO figure out math. For now just drop them. */ 335cabdff1aSopenharmony_ci av_log(s, AV_LOG_DEBUG, 336cabdff1aSopenharmony_ci "dropping initial (or ending) sample with odd PTS too high %"PRId64"\n", sampletime); 337cabdff1aSopenharmony_ci return S_OK; 338cabdff1aSopenharmony_ci } else 339cabdff1aSopenharmony_ci chosentime = sampletime; 340cabdff1aSopenharmony_ci } 341cabdff1aSopenharmony_ci // media sample time is relative to graph start time 342cabdff1aSopenharmony_ci sampletime += pin->filter->start_time; 343cabdff1aSopenharmony_ci if (use_sample_time) 344cabdff1aSopenharmony_ci chosentime += pin->filter->start_time; 345cabdff1aSopenharmony_ci 346cabdff1aSopenharmony_ci buf_size = IMediaSample_GetActualDataLength(sample); 347cabdff1aSopenharmony_ci IMediaSample_GetPointer(sample, &buf); 348cabdff1aSopenharmony_ci index = pin->filter->stream_index; 349cabdff1aSopenharmony_ci 350cabdff1aSopenharmony_ci av_log(s, AV_LOG_VERBOSE, "passing through packet of type %s size %8d " 351cabdff1aSopenharmony_ci "timestamp %"PRId64" orig timestamp %"PRId64" graph timestamp %"PRId64" diff %"PRId64" %s\n", 352cabdff1aSopenharmony_ci devtypename, buf_size, chosentime, sampletime, graphtime, graphtime - sampletime, ctx->device_name[devtype]); 353cabdff1aSopenharmony_ci pin->filter->callback(priv_data, index, buf, buf_size, chosentime, devtype); 354cabdff1aSopenharmony_ci 355cabdff1aSopenharmony_ci return S_OK; 356cabdff1aSopenharmony_ci} 357cabdff1aSopenharmony_cilong WINAPI ff_dshow_meminputpin_ReceiveMultiple(DShowMemInputPin *this, 358cabdff1aSopenharmony_ci IMediaSample **samples, long n, long *nproc) 359cabdff1aSopenharmony_ci{ 360cabdff1aSopenharmony_ci int i; 361cabdff1aSopenharmony_ci dshowdebug("ff_dshow_meminputpin_ReceiveMultiple(%p)\n", this); 362cabdff1aSopenharmony_ci 363cabdff1aSopenharmony_ci for (i = 0; i < n; i++) 364cabdff1aSopenharmony_ci ff_dshow_meminputpin_Receive(this, samples[i]); 365cabdff1aSopenharmony_ci 366cabdff1aSopenharmony_ci *nproc = n; 367cabdff1aSopenharmony_ci return S_OK; 368cabdff1aSopenharmony_ci} 369cabdff1aSopenharmony_cilong WINAPI ff_dshow_meminputpin_ReceiveCanBlock(DShowMemInputPin *this) 370cabdff1aSopenharmony_ci{ 371cabdff1aSopenharmony_ci dshowdebug("ff_dshow_meminputpin_ReceiveCanBlock(%p)\n", this); 372cabdff1aSopenharmony_ci /* I swear I will not block. */ 373cabdff1aSopenharmony_ci return S_FALSE; 374cabdff1aSopenharmony_ci} 375cabdff1aSopenharmony_ci 376cabdff1aSopenharmony_civoid ff_dshow_meminputpin_Destroy(DShowMemInputPin *this) 377cabdff1aSopenharmony_ci{ 378cabdff1aSopenharmony_ci DShowPin *pin = (DShowPin *) ((uint8_t *) this - imemoffset); 379cabdff1aSopenharmony_ci dshowdebug("ff_dshow_meminputpin_Destroy(%p)\n", this); 380cabdff1aSopenharmony_ci ff_dshow_pin_Destroy(pin); 381cabdff1aSopenharmony_ci} 382