annotate ffmpeg/libavdevice/dshow_pin.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * DirectShow capture interface
yading@10 3 * Copyright (c) 2010 Ramiro Polla
yading@10 4 *
yading@10 5 * This file is part of FFmpeg.
yading@10 6 *
yading@10 7 * FFmpeg is free software; you can redistribute it and/or
yading@10 8 * modify it under the terms of the GNU Lesser General Public
yading@10 9 * License as published by the Free Software Foundation; either
yading@10 10 * version 2.1 of the License, or (at your option) any later version.
yading@10 11 *
yading@10 12 * FFmpeg is distributed in the hope that it will be useful,
yading@10 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 15 * Lesser General Public License for more details.
yading@10 16 *
yading@10 17 * You should have received a copy of the GNU Lesser General Public
yading@10 18 * License along with FFmpeg; if not, write to the Free Software
yading@10 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 20 */
yading@10 21
yading@10 22 #include "dshow_capture.h"
yading@10 23
yading@10 24 #include <stddef.h>
yading@10 25 #define imemoffset offsetof(libAVPin, imemvtbl)
yading@10 26
yading@10 27 DECLARE_QUERYINTERFACE(libAVPin,
yading@10 28 { {&IID_IUnknown,0}, {&IID_IPin,0}, {&IID_IMemInputPin,imemoffset} })
yading@10 29 DECLARE_ADDREF(libAVPin)
yading@10 30 DECLARE_RELEASE(libAVPin)
yading@10 31
yading@10 32 long WINAPI
yading@10 33 libAVPin_Connect(libAVPin *this, IPin *pin, const AM_MEDIA_TYPE *type)
yading@10 34 {
yading@10 35 dshowdebug("libAVPin_Connect(%p, %p, %p)\n", this, pin, type);
yading@10 36 /* Input pins receive connections. */
yading@10 37 return S_FALSE;
yading@10 38 }
yading@10 39 long WINAPI
yading@10 40 libAVPin_ReceiveConnection(libAVPin *this, IPin *pin,
yading@10 41 const AM_MEDIA_TYPE *type)
yading@10 42 {
yading@10 43 enum dshowDeviceType devtype = this->filter->type;
yading@10 44 dshowdebug("libAVPin_ReceiveConnection(%p)\n", this);
yading@10 45
yading@10 46 if (!pin)
yading@10 47 return E_POINTER;
yading@10 48 if (this->connectedto)
yading@10 49 return VFW_E_ALREADY_CONNECTED;
yading@10 50
yading@10 51 ff_print_AM_MEDIA_TYPE(type);
yading@10 52 if (devtype == VideoDevice) {
yading@10 53 if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Video))
yading@10 54 return VFW_E_TYPE_NOT_ACCEPTED;
yading@10 55 } else {
yading@10 56 if (!IsEqualGUID(&type->majortype, &MEDIATYPE_Audio))
yading@10 57 return VFW_E_TYPE_NOT_ACCEPTED;
yading@10 58 }
yading@10 59
yading@10 60 IPin_AddRef(pin);
yading@10 61 this->connectedto = pin;
yading@10 62
yading@10 63 ff_copy_dshow_media_type(&this->type, type);
yading@10 64
yading@10 65 return S_OK;
yading@10 66 }
yading@10 67 long WINAPI
yading@10 68 libAVPin_Disconnect(libAVPin *this)
yading@10 69 {
yading@10 70 dshowdebug("libAVPin_Disconnect(%p)\n", this);
yading@10 71
yading@10 72 if (this->filter->state != State_Stopped)
yading@10 73 return VFW_E_NOT_STOPPED;
yading@10 74 if (!this->connectedto)
yading@10 75 return S_FALSE;
yading@10 76 IPin_Release(this->connectedto);
yading@10 77 this->connectedto = NULL;
yading@10 78
yading@10 79 return S_OK;
yading@10 80 }
yading@10 81 long WINAPI
yading@10 82 libAVPin_ConnectedTo(libAVPin *this, IPin **pin)
yading@10 83 {
yading@10 84 dshowdebug("libAVPin_ConnectedTo(%p)\n", this);
yading@10 85
yading@10 86 if (!pin)
yading@10 87 return E_POINTER;
yading@10 88 if (!this->connectedto)
yading@10 89 return VFW_E_NOT_CONNECTED;
yading@10 90 IPin_AddRef(this->connectedto);
yading@10 91 *pin = this->connectedto;
yading@10 92
yading@10 93 return S_OK;
yading@10 94 }
yading@10 95 long WINAPI
yading@10 96 libAVPin_ConnectionMediaType(libAVPin *this, AM_MEDIA_TYPE *type)
yading@10 97 {
yading@10 98 dshowdebug("libAVPin_ConnectionMediaType(%p)\n", this);
yading@10 99
yading@10 100 if (!type)
yading@10 101 return E_POINTER;
yading@10 102 if (!this->connectedto)
yading@10 103 return VFW_E_NOT_CONNECTED;
yading@10 104
yading@10 105 return ff_copy_dshow_media_type(type, &this->type);
yading@10 106 }
yading@10 107 long WINAPI
yading@10 108 libAVPin_QueryPinInfo(libAVPin *this, PIN_INFO *info)
yading@10 109 {
yading@10 110 dshowdebug("libAVPin_QueryPinInfo(%p)\n", this);
yading@10 111
yading@10 112 if (!info)
yading@10 113 return E_POINTER;
yading@10 114
yading@10 115 if (this->filter)
yading@10 116 libAVFilter_AddRef(this->filter);
yading@10 117
yading@10 118 info->pFilter = (IBaseFilter *) this->filter;
yading@10 119 info->dir = PINDIR_INPUT;
yading@10 120 wcscpy(info->achName, L"Capture");
yading@10 121
yading@10 122 return S_OK;
yading@10 123 }
yading@10 124 long WINAPI
yading@10 125 libAVPin_QueryDirection(libAVPin *this, PIN_DIRECTION *dir)
yading@10 126 {
yading@10 127 dshowdebug("libAVPin_QueryDirection(%p)\n", this);
yading@10 128 if (!dir)
yading@10 129 return E_POINTER;
yading@10 130 *dir = PINDIR_INPUT;
yading@10 131 return S_OK;
yading@10 132 }
yading@10 133 long WINAPI
yading@10 134 libAVPin_QueryId(libAVPin *this, wchar_t **id)
yading@10 135 {
yading@10 136 dshowdebug("libAVPin_QueryId(%p)\n", this);
yading@10 137
yading@10 138 if (!id)
yading@10 139 return E_POINTER;
yading@10 140
yading@10 141 *id = wcsdup(L"libAV Pin");
yading@10 142
yading@10 143 return S_OK;
yading@10 144 }
yading@10 145 long WINAPI
yading@10 146 libAVPin_QueryAccept(libAVPin *this, const AM_MEDIA_TYPE *type)
yading@10 147 {
yading@10 148 dshowdebug("libAVPin_QueryAccept(%p)\n", this);
yading@10 149 return S_FALSE;
yading@10 150 }
yading@10 151 long WINAPI
yading@10 152 libAVPin_EnumMediaTypes(libAVPin *this, IEnumMediaTypes **enumtypes)
yading@10 153 {
yading@10 154 const AM_MEDIA_TYPE *type = NULL;
yading@10 155 libAVEnumMediaTypes *new;
yading@10 156 dshowdebug("libAVPin_EnumMediaTypes(%p)\n", this);
yading@10 157
yading@10 158 if (!enumtypes)
yading@10 159 return E_POINTER;
yading@10 160 new = libAVEnumMediaTypes_Create(type);
yading@10 161 if (!new)
yading@10 162 return E_OUTOFMEMORY;
yading@10 163
yading@10 164 *enumtypes = (IEnumMediaTypes *) new;
yading@10 165 return S_OK;
yading@10 166 }
yading@10 167 long WINAPI
yading@10 168 libAVPin_QueryInternalConnections(libAVPin *this, IPin **pin,
yading@10 169 unsigned long *npin)
yading@10 170 {
yading@10 171 dshowdebug("libAVPin_QueryInternalConnections(%p)\n", this);
yading@10 172 return E_NOTIMPL;
yading@10 173 }
yading@10 174 long WINAPI
yading@10 175 libAVPin_EndOfStream(libAVPin *this)
yading@10 176 {
yading@10 177 dshowdebug("libAVPin_EndOfStream(%p)\n", this);
yading@10 178 /* I don't care. */
yading@10 179 return S_OK;
yading@10 180 }
yading@10 181 long WINAPI
yading@10 182 libAVPin_BeginFlush(libAVPin *this)
yading@10 183 {
yading@10 184 dshowdebug("libAVPin_BeginFlush(%p)\n", this);
yading@10 185 /* I don't care. */
yading@10 186 return S_OK;
yading@10 187 }
yading@10 188 long WINAPI
yading@10 189 libAVPin_EndFlush(libAVPin *this)
yading@10 190 {
yading@10 191 dshowdebug("libAVPin_EndFlush(%p)\n", this);
yading@10 192 /* I don't care. */
yading@10 193 return S_OK;
yading@10 194 }
yading@10 195 long WINAPI
yading@10 196 libAVPin_NewSegment(libAVPin *this, REFERENCE_TIME start, REFERENCE_TIME stop,
yading@10 197 double rate)
yading@10 198 {
yading@10 199 dshowdebug("libAVPin_NewSegment(%p)\n", this);
yading@10 200 /* I don't care. */
yading@10 201 return S_OK;
yading@10 202 }
yading@10 203
yading@10 204 static int
yading@10 205 libAVPin_Setup(libAVPin *this, libAVFilter *filter)
yading@10 206 {
yading@10 207 IPinVtbl *vtbl = this->vtbl;
yading@10 208 IMemInputPinVtbl *imemvtbl;
yading@10 209
yading@10 210 if (!filter)
yading@10 211 return 0;
yading@10 212
yading@10 213 imemvtbl = av_malloc(sizeof(IMemInputPinVtbl));
yading@10 214 if (!imemvtbl)
yading@10 215 return 0;
yading@10 216
yading@10 217 SETVTBL(imemvtbl, libAVMemInputPin, QueryInterface);
yading@10 218 SETVTBL(imemvtbl, libAVMemInputPin, AddRef);
yading@10 219 SETVTBL(imemvtbl, libAVMemInputPin, Release);
yading@10 220 SETVTBL(imemvtbl, libAVMemInputPin, GetAllocator);
yading@10 221 SETVTBL(imemvtbl, libAVMemInputPin, NotifyAllocator);
yading@10 222 SETVTBL(imemvtbl, libAVMemInputPin, GetAllocatorRequirements);
yading@10 223 SETVTBL(imemvtbl, libAVMemInputPin, Receive);
yading@10 224 SETVTBL(imemvtbl, libAVMemInputPin, ReceiveMultiple);
yading@10 225 SETVTBL(imemvtbl, libAVMemInputPin, ReceiveCanBlock);
yading@10 226
yading@10 227 this->imemvtbl = imemvtbl;
yading@10 228
yading@10 229 SETVTBL(vtbl, libAVPin, QueryInterface);
yading@10 230 SETVTBL(vtbl, libAVPin, AddRef);
yading@10 231 SETVTBL(vtbl, libAVPin, Release);
yading@10 232 SETVTBL(vtbl, libAVPin, Connect);
yading@10 233 SETVTBL(vtbl, libAVPin, ReceiveConnection);
yading@10 234 SETVTBL(vtbl, libAVPin, Disconnect);
yading@10 235 SETVTBL(vtbl, libAVPin, ConnectedTo);
yading@10 236 SETVTBL(vtbl, libAVPin, ConnectionMediaType);
yading@10 237 SETVTBL(vtbl, libAVPin, QueryPinInfo);
yading@10 238 SETVTBL(vtbl, libAVPin, QueryDirection);
yading@10 239 SETVTBL(vtbl, libAVPin, QueryId);
yading@10 240 SETVTBL(vtbl, libAVPin, QueryAccept);
yading@10 241 SETVTBL(vtbl, libAVPin, EnumMediaTypes);
yading@10 242 SETVTBL(vtbl, libAVPin, QueryInternalConnections);
yading@10 243 SETVTBL(vtbl, libAVPin, EndOfStream);
yading@10 244 SETVTBL(vtbl, libAVPin, BeginFlush);
yading@10 245 SETVTBL(vtbl, libAVPin, EndFlush);
yading@10 246 SETVTBL(vtbl, libAVPin, NewSegment);
yading@10 247
yading@10 248 this->filter = filter;
yading@10 249
yading@10 250 return 1;
yading@10 251 }
yading@10 252 DECLARE_CREATE(libAVPin, libAVPin_Setup(this, filter), libAVFilter *filter)
yading@10 253 DECLARE_DESTROY(libAVPin, nothing)
yading@10 254
yading@10 255 /*****************************************************************************
yading@10 256 * libAVMemInputPin
yading@10 257 ****************************************************************************/
yading@10 258 long WINAPI
yading@10 259 libAVMemInputPin_QueryInterface(libAVMemInputPin *this, const GUID *riid,
yading@10 260 void **ppvObject)
yading@10 261 {
yading@10 262 libAVPin *pin = (libAVPin *) ((uint8_t *) this - imemoffset);
yading@10 263 dshowdebug("libAVMemInputPin_QueryInterface(%p)\n", this);
yading@10 264 return libAVPin_QueryInterface(pin, riid, ppvObject);
yading@10 265 }
yading@10 266 unsigned long WINAPI
yading@10 267 libAVMemInputPin_AddRef(libAVMemInputPin *this)
yading@10 268 {
yading@10 269 libAVPin *pin = (libAVPin *) ((uint8_t *) this - imemoffset);
yading@10 270 dshowdebug("libAVMemInputPin_AddRef(%p)\n", this);
yading@10 271 return libAVPin_AddRef(pin);
yading@10 272 }
yading@10 273 unsigned long WINAPI
yading@10 274 libAVMemInputPin_Release(libAVMemInputPin *this)
yading@10 275 {
yading@10 276 libAVPin *pin = (libAVPin *) ((uint8_t *) this - imemoffset);
yading@10 277 dshowdebug("libAVMemInputPin_Release(%p)\n", this);
yading@10 278 return libAVPin_Release(pin);
yading@10 279 }
yading@10 280 long WINAPI
yading@10 281 libAVMemInputPin_GetAllocator(libAVMemInputPin *this, IMemAllocator **alloc)
yading@10 282 {
yading@10 283 dshowdebug("libAVMemInputPin_GetAllocator(%p)\n", this);
yading@10 284 return VFW_E_NO_ALLOCATOR;
yading@10 285 }
yading@10 286 long WINAPI
yading@10 287 libAVMemInputPin_NotifyAllocator(libAVMemInputPin *this, IMemAllocator *alloc,
yading@10 288 BOOL rdwr)
yading@10 289 {
yading@10 290 dshowdebug("libAVMemInputPin_NotifyAllocator(%p)\n", this);
yading@10 291 return S_OK;
yading@10 292 }
yading@10 293 long WINAPI
yading@10 294 libAVMemInputPin_GetAllocatorRequirements(libAVMemInputPin *this,
yading@10 295 ALLOCATOR_PROPERTIES *props)
yading@10 296 {
yading@10 297 dshowdebug("libAVMemInputPin_GetAllocatorRequirements(%p)\n", this);
yading@10 298 return E_NOTIMPL;
yading@10 299 }
yading@10 300 long WINAPI
yading@10 301 libAVMemInputPin_Receive(libAVMemInputPin *this, IMediaSample *sample)
yading@10 302 {
yading@10 303 libAVPin *pin = (libAVPin *) ((uint8_t *) this - imemoffset);
yading@10 304 enum dshowDeviceType devtype = pin->filter->type;
yading@10 305 void *priv_data;
yading@10 306 uint8_t *buf;
yading@10 307 int buf_size;
yading@10 308 int index;
yading@10 309 int64_t curtime;
yading@10 310
yading@10 311 dshowdebug("libAVMemInputPin_Receive(%p)\n", this);
yading@10 312
yading@10 313 if (!sample)
yading@10 314 return E_POINTER;
yading@10 315
yading@10 316 if (devtype == VideoDevice) {
yading@10 317 /* PTS from video devices is unreliable. */
yading@10 318 IReferenceClock *clock = pin->filter->clock;
yading@10 319 IReferenceClock_GetTime(clock, &curtime);
yading@10 320 } else {
yading@10 321 int64_t dummy;
yading@10 322 IMediaSample_GetTime(sample, &curtime, &dummy);
yading@10 323 curtime += pin->filter->start_time;
yading@10 324 }
yading@10 325
yading@10 326 buf_size = IMediaSample_GetActualDataLength(sample);
yading@10 327 IMediaSample_GetPointer(sample, &buf);
yading@10 328 priv_data = pin->filter->priv_data;
yading@10 329 index = pin->filter->stream_index;
yading@10 330
yading@10 331 pin->filter->callback(priv_data, index, buf, buf_size, curtime);
yading@10 332
yading@10 333 return S_OK;
yading@10 334 }
yading@10 335 long WINAPI
yading@10 336 libAVMemInputPin_ReceiveMultiple(libAVMemInputPin *this,
yading@10 337 IMediaSample **samples, long n, long *nproc)
yading@10 338 {
yading@10 339 int i;
yading@10 340 dshowdebug("libAVMemInputPin_ReceiveMultiple(%p)\n", this);
yading@10 341
yading@10 342 for (i = 0; i < n; i++)
yading@10 343 libAVMemInputPin_Receive(this, samples[i]);
yading@10 344
yading@10 345 *nproc = n;
yading@10 346 return S_OK;
yading@10 347 }
yading@10 348 long WINAPI
yading@10 349 libAVMemInputPin_ReceiveCanBlock(libAVMemInputPin *this)
yading@10 350 {
yading@10 351 dshowdebug("libAVMemInputPin_ReceiveCanBlock(%p)\n", this);
yading@10 352 /* I swear I will not block. */
yading@10 353 return S_FALSE;
yading@10 354 }
yading@10 355
yading@10 356 void
yading@10 357 libAVMemInputPin_Destroy(libAVMemInputPin *this)
yading@10 358 {
yading@10 359 libAVPin *pin = (libAVPin *) ((uint8_t *) this - imemoffset);
yading@10 360 dshowdebug("libAVMemInputPin_Destroy(%p)\n", this);
yading@10 361 libAVPin_Destroy(pin);
yading@10 362 }