diff options
Diffstat (limited to 'libavdevice/dshow_filter.c')
-rw-r--r-- | libavdevice/dshow_filter.c | 202 |
1 files changed, 202 insertions, 0 deletions
diff --git a/libavdevice/dshow_filter.c b/libavdevice/dshow_filter.c new file mode 100644 index 0000000..7360adc --- /dev/null +++ b/libavdevice/dshow_filter.c @@ -0,0 +1,202 @@ +/* + * DirectShow capture interface + * Copyright (c) 2010 Ramiro Polla + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "dshow_capture.h" + +DECLARE_QUERYINTERFACE(libAVFilter, + { {&IID_IUnknown,0}, {&IID_IBaseFilter,0} }) +DECLARE_ADDREF(libAVFilter) +DECLARE_RELEASE(libAVFilter) + +long WINAPI +libAVFilter_GetClassID(libAVFilter *this, CLSID *id) +{ + dshowdebug("libAVFilter_GetClassID(%p)\n", this); + /* I'm not creating a ClassID just for this. */ + return E_FAIL; +} +long WINAPI +libAVFilter_Stop(libAVFilter *this) +{ + dshowdebug("libAVFilter_Stop(%p)\n", this); + this->state = State_Stopped; + return S_OK; +} +long WINAPI +libAVFilter_Pause(libAVFilter *this) +{ + dshowdebug("libAVFilter_Pause(%p)\n", this); + this->state = State_Paused; + return S_OK; +} +long WINAPI +libAVFilter_Run(libAVFilter *this, REFERENCE_TIME start) +{ + dshowdebug("libAVFilter_Run(%p) %"PRId64"\n", this, start); + this->state = State_Running; + this->start_time = start; + return S_OK; +} +long WINAPI +libAVFilter_GetState(libAVFilter *this, DWORD ms, FILTER_STATE *state) +{ + dshowdebug("libAVFilter_GetState(%p)\n", this); + if (!state) + return E_POINTER; + *state = this->state; + return S_OK; +} +long WINAPI +libAVFilter_SetSyncSource(libAVFilter *this, IReferenceClock *clock) +{ + dshowdebug("libAVFilter_SetSyncSource(%p)\n", this); + + if (this->clock != clock) { + if (this->clock) + IReferenceClock_Release(this->clock); + this->clock = clock; + if (clock) + IReferenceClock_AddRef(clock); + } + + return S_OK; +} +long WINAPI +libAVFilter_GetSyncSource(libAVFilter *this, IReferenceClock **clock) +{ + dshowdebug("libAVFilter_GetSyncSource(%p)\n", this); + + if (!clock) + return E_POINTER; + if (this->clock) + IReferenceClock_AddRef(this->clock); + *clock = this->clock; + + return S_OK; +} +long WINAPI +libAVFilter_EnumPins(libAVFilter *this, IEnumPins **enumpin) +{ + libAVEnumPins *new; + dshowdebug("libAVFilter_EnumPins(%p)\n", this); + + if (!enumpin) + return E_POINTER; + new = libAVEnumPins_Create(this->pin, this); + if (!new) + return E_OUTOFMEMORY; + + *enumpin = (IEnumPins *) new; + return S_OK; +} +long WINAPI +libAVFilter_FindPin(libAVFilter *this, const wchar_t *id, IPin **pin) +{ + libAVPin *found = NULL; + dshowdebug("libAVFilter_FindPin(%p)\n", this); + + if (!id || !pin) + return E_POINTER; + if (!wcscmp(id, L"In")) { + found = this->pin; + libAVPin_AddRef(found); + } + *pin = (IPin *) found; + if (!found) + return VFW_E_NOT_FOUND; + + return S_OK; +} +long WINAPI +libAVFilter_QueryFilterInfo(libAVFilter *this, FILTER_INFO *info) +{ + dshowdebug("libAVFilter_QueryFilterInfo(%p)\n", this); + + if (!info) + return E_POINTER; + if (this->info.pGraph) + IFilterGraph_AddRef(this->info.pGraph); + *info = this->info; + + return S_OK; +} +long WINAPI +libAVFilter_JoinFilterGraph(libAVFilter *this, IFilterGraph *graph, + const wchar_t *name) +{ + dshowdebug("libAVFilter_JoinFilterGraph(%p)\n", this); + + this->info.pGraph = graph; + if (name) + wcscpy(this->info.achName, name); + + return S_OK; +} +long WINAPI +libAVFilter_QueryVendorInfo(libAVFilter *this, wchar_t **info) +{ + dshowdebug("libAVFilter_QueryVendorInfo(%p)\n", this); + + if (!info) + return E_POINTER; + *info = wcsdup(L"libAV"); + + return S_OK; +} + +static int +libAVFilter_Setup(libAVFilter *this, void *priv_data, void *callback, + enum dshowDeviceType type) +{ + IBaseFilterVtbl *vtbl = this->vtbl; + SETVTBL(vtbl, libAVFilter, QueryInterface); + SETVTBL(vtbl, libAVFilter, AddRef); + SETVTBL(vtbl, libAVFilter, Release); + SETVTBL(vtbl, libAVFilter, GetClassID); + SETVTBL(vtbl, libAVFilter, Stop); + SETVTBL(vtbl, libAVFilter, Pause); + SETVTBL(vtbl, libAVFilter, Run); + SETVTBL(vtbl, libAVFilter, GetState); + SETVTBL(vtbl, libAVFilter, SetSyncSource); + SETVTBL(vtbl, libAVFilter, GetSyncSource); + SETVTBL(vtbl, libAVFilter, EnumPins); + SETVTBL(vtbl, libAVFilter, FindPin); + SETVTBL(vtbl, libAVFilter, QueryFilterInfo); + SETVTBL(vtbl, libAVFilter, JoinFilterGraph); + SETVTBL(vtbl, libAVFilter, QueryVendorInfo); + + this->pin = libAVPin_Create(this); + + this->priv_data = priv_data; + this->callback = callback; + this->type = type; + + return 1; +} +static int +libAVFilter_Cleanup(libAVFilter *this) +{ + libAVPin_Release(this->pin); + return 1; +} +DECLARE_CREATE(libAVFilter, libAVFilter_Setup(this, priv_data, callback, type), + void *priv_data, void *callback, enum dshowDeviceType type) +DECLARE_DESTROY(libAVFilter, libAVFilter_Cleanup) |