FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
dshow_filter.c
Go to the documentation of this file.
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 
25  { {&IID_IUnknown,0}, {&IID_IBaseFilter,0} })
28 
29 long WINAPI
31 {
32  dshowdebug("libAVFilter_GetClassID(%p)\n", this);
33  /* I'm not creating a ClassID just for this. */
34  return E_FAIL;
35 }
36 long WINAPI
38 {
39  dshowdebug("libAVFilter_Stop(%p)\n", this);
40  this->state = State_Stopped;
41  return S_OK;
42 }
43 long WINAPI
45 {
46  dshowdebug("libAVFilter_Pause(%p)\n", this);
47  this->state = State_Paused;
48  return S_OK;
49 }
50 long WINAPI
51 libAVFilter_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 }
58 long WINAPI
59 libAVFilter_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 }
67 long WINAPI
68 libAVFilter_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 }
82 long WINAPI
83 libAVFilter_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 }
95 long WINAPI
96 libAVFilter_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 }
110 long WINAPI
111 libAVFilter_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 }
128 long WINAPI
129 libAVFilter_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 }
141 long WINAPI
142 libAVFilter_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 }
153 long WINAPI
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 
165 static int
166 libAVFilter_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 }
194 static int
196 {
197  libAVPin_Release(this->pin);
198  return 1;
199 }
200 DECLARE_CREATE(libAVFilter, libAVFilter_Setup(this, priv_data, callback, type),
201  void *priv_data, void *callback, enum dshowDeviceType type)