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 24DECLARE_QUERYINTERFACE(libAVFilter, 25 { {&IID_IUnknown,0}, {&IID_IBaseFilter,0} }) 26DECLARE_ADDREF(libAVFilter) 27DECLARE_RELEASE(libAVFilter) 28 29long WINAPI 30libAVFilter_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} 36long WINAPI 37libAVFilter_Stop(libAVFilter *this) 38{ 39 dshowdebug("libAVFilter_Stop(%p)\n", this); 40 this->state = State_Stopped; 41 return S_OK; 42} 43long WINAPI 44libAVFilter_Pause(libAVFilter *this) 45{ 46 dshowdebug("libAVFilter_Pause(%p)\n", this); 47 this->state = State_Paused; 48 return S_OK; 49} 50long WINAPI 51libAVFilter_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} 58long WINAPI 59libAVFilter_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} 67long WINAPI 68libAVFilter_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} 82long WINAPI 83libAVFilter_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} 95long WINAPI 96libAVFilter_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} 110long WINAPI 111libAVFilter_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} 128long WINAPI 129libAVFilter_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} 141long WINAPI 142libAVFilter_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} 153long WINAPI 154libAVFilter_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 165static int 166libAVFilter_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} 194static int 195libAVFilter_Cleanup(libAVFilter *this) 196{ 197 libAVPin_Release(this->pin); 198 return 1; 199} 200DECLARE_CREATE(libAVFilter, libAVFilter_Setup(this, priv_data, callback, type), 201 void *priv_data, void *callback, enum dshowDeviceType type) 202DECLARE_DESTROY(libAVFilter, libAVFilter_Cleanup) 203