1
/* $Id: dshowclasses.cpp 4062 2012-04-19 06:36:57Z ming $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
5
* This program is free software; you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation; either version 2 of the License, or
8
* (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
#include <pjmedia-videodev/config.h>
23
#if defined(PJMEDIA_VIDEO_DEV_HAS_DSHOW) && PJMEDIA_VIDEO_DEV_HAS_DSHOW != 0
29
typedef void (*input_callback)(void *user_data, IMediaSample *pMediaSample);
31
const GUID CLSID_NullRenderer = {0xF9168C5E, 0xCEB2, 0x4FAA, {0xB6, 0xBF,
32
0x32, 0x9B, 0xF3, 0x9F, 0xA1, 0xE4}};
34
const GUID CLSID_SourceFilter = {0xF9168C5E, 0xCEB2, 0x4FAA, {0xB6, 0xBF,
35
0x32, 0x9B, 0xF3, 0x9F, 0xA1, 0xE5}};
37
class NullRenderer: public CBaseRenderer
40
NullRenderer(HRESULT *pHr);
41
virtual ~NullRenderer();
43
virtual HRESULT CheckMediaType(const CMediaType *pmt);
44
virtual HRESULT DoRenderSample(IMediaSample *pMediaSample);
46
input_callback input_cb;
50
class OutputPin: public CBaseOutputPin
53
OutputPin(CBaseFilter *pFilter, CCritSec *pLock, HRESULT *pHr);
56
HRESULT Push(void *buf, long size);
58
virtual HRESULT CheckMediaType(const CMediaType *pmt);
59
virtual HRESULT DecideBufferSize(IMemAllocator *pAlloc,
60
ALLOCATOR_PROPERTIES *ppropInputRequest);
66
class SourceFilter: public CBaseFilter
73
CBasePin* GetPin(int n);
80
OutputPin::OutputPin(CBaseFilter *pFilter, CCritSec *pLock, HRESULT *pHr):
81
CBaseOutputPin("OutputPin", pFilter, pLock, pHr, L"OutputPin")
85
OutputPin::~OutputPin()
89
HRESULT OutputPin::CheckMediaType(const CMediaType *pmt)
94
HRESULT OutputPin::DecideBufferSize(IMemAllocator *pAlloc,
95
ALLOCATOR_PROPERTIES *ppropInputRequest)
97
ALLOCATOR_PROPERTIES properties;
99
ppropInputRequest->cbBuffer = bufSize;
100
ppropInputRequest->cBuffers = 1;
102
/* First set the buffer descriptions we're interested in */
103
pAlloc->SetProperties(ppropInputRequest, &properties);
108
HRESULT OutputPin::Push(void *buf, long size)
111
IMediaSample *pSample;
117
* Hold the critical section here as the pin might get disconnected
118
* during the Deliver() method call.
122
hr = GetDeliveryBuffer(&pSample, NULL, NULL, 0);
126
pSample->GetMediaType(&pmt);
129
bufSize = pmt->lSampleSize;
132
pSample->GetPointer(&dst_buf);
133
vi = (VIDEOINFOHEADER *)mediaType.pbFormat;
134
if (vi->rcSource.right == vi->bmiHeader.biWidth) {
135
assert(pSample->GetSize() >= size);
136
memcpy(dst_buf, buf, size);
139
unsigned dststride, srcstride;
140
BYTE *src_buf = (BYTE *)buf;
142
bpp = size / abs(vi->bmiHeader.biHeight) / vi->rcSource.right;
143
dststride = vi->bmiHeader.biWidth * bpp;
144
srcstride = vi->rcSource.right * bpp;
145
for (i = abs(vi->bmiHeader.biHeight); i > 0; i--) {
146
memcpy(dst_buf, src_buf, srcstride);
147
dst_buf += dststride;
148
src_buf += srcstride;
151
pSample->SetActualDataLength(size);
153
hr = Deliver(pSample);
162
SourceFilter::SourceFilter(): CBaseFilter("SourceFilter", NULL, &lock,
166
outPin = new OutputPin(this, &lock, &hr);
169
SourceFilter::~SourceFilter()
173
int SourceFilter::GetPinCount()
178
CBasePin* SourceFilter::GetPin(int n)
183
NullRenderer::NullRenderer(HRESULT *pHr): CBaseRenderer(CLSID_NullRenderer,
190
NullRenderer::~NullRenderer()
194
HRESULT NullRenderer::CheckMediaType(const CMediaType *pmt)
199
HRESULT NullRenderer::DoRenderSample(IMediaSample *pMediaSample)
202
input_cb(user_data, pMediaSample);
207
extern "C" IBaseFilter* NullRenderer_Create(input_callback input_cb,
211
NullRenderer *renderer = new NullRenderer(&hr);
213
renderer->input_cb = input_cb;
214
renderer->user_data = user_data;
216
return (CBaseFilter *)renderer;
219
extern "C" IBaseFilter* SourceFilter_Create(SourceFilter **pSrc)
221
SourceFilter *src = new SourceFilter();
225
return (CBaseFilter *)src;
228
extern "C" HRESULT SourceFilter_Deliver(SourceFilter *src,
229
void *buf, long size)
231
return ((OutputPin *)src->GetPin(0))->Push(buf, size);
234
extern "C" void SourceFilter_SetMediaType(SourceFilter *src,
237
((OutputPin *)src->GetPin(0))->mediaType.Set(*pmt);
238
((OutputPin *)src->GetPin(0))->bufSize = pmt->lSampleSize;
242
#endif /* PJMEDIA_VIDEO_DEV_HAS_DSHOW */