00001
00034 #include "stdafx.h"
00035
00036
00037 #include <cassert>
00038
00039
00040 #include "Tee.h"
00041
00042 CRtvcTee::CRtvcTee()
00043 :CMultiIOBaseFilter(NAME("Meraka RTVC Tee Filter"), 0, CLSID_RtvcTee)
00044 {
00045
00046 Initialise();
00047 }
00048
00049 CRtvcTee::~CRtvcTee()
00050 {;}
00051
00052 CUnknown * WINAPI CRtvcTee::CreateInstance( LPUNKNOWN pUnk, HRESULT *pHr )
00053 {
00054 CRtvcTee *pFilter = new CRtvcTee();
00055 if (pFilter== NULL)
00056 {
00057 *pHr = E_OUTOFMEMORY;
00058 }
00059 return pFilter;
00060 }
00061
00062 HRESULT CRtvcTee::Receive( IMediaSample *pSample, int nIndex )
00063 {
00064 ASSERT(nIndex >= 0);
00065 ASSERT (nIndex < m_vInputPins.size());
00066 ASSERT(pSample);
00067
00068 HRESULT hr;
00069 if (nIndex == 0)
00070 {
00071
00072 CAutoLock lck(&m_csReceive);
00073 AM_SAMPLE2_PROPERTIES * const pProps = m_vInputPins[0]->SampleProps();
00074 if (pProps->dwStreamId != AM_STREAM_MEDIA) {
00075 return m_vInputPins[0]->Receive(pSample);
00076 }
00077
00078
00079 for (size_t i = 0; i < m_vOutputPins.size(); i++)
00080 {
00081 if (m_vOutputPins[i]->IsConnected())
00082 {
00083 IMediaSample * pOutSample;
00084
00085 hr = InitializeOutputSample(pSample, &pOutSample, nIndex, i);
00086
00087 if (FAILED(hr)) {
00088 return hr;
00089 }
00090
00091
00092 MSR_START(m_idTransform);
00093
00094
00095 BYTE *pBufferIn = NULL;
00096 BYTE *pBufferOut = NULL;
00097
00098 if (pSample)
00099 {
00100 HRESULT hr = pSample->GetPointer(&pBufferIn);
00101 if (FAILED(hr))
00102 {
00103 return hr;
00104 }
00105 }
00106
00107 if (pOutSample)
00108 {
00109 HRESULT hr = pOutSample->GetPointer(&pBufferOut);
00110 if (FAILED(hr))
00111 {
00112 return hr;
00113 }
00114 }
00115
00116
00117 int nSize = pSample->GetActualDataLength();
00118 memcpy(pBufferOut, pBufferIn, nSize);
00119
00120 pOutSample->SetActualDataLength(nSize);
00121 pOutSample->SetSyncPoint(TRUE);
00122
00123
00124 MSR_STOP(m_idTransform);
00125
00126 if (FAILED(hr)) {
00127 DbgLog((LOG_TRACE,1,TEXT("Error from transform")));
00128 }
00129 else
00130 {
00131
00132
00133
00134 if (hr == NOERROR)
00135 {
00136 hr = m_vOutputPins[i]->Deliver(pOutSample);
00137
00138 }
00139 else
00140 {
00141
00142
00143
00144
00145 if (S_FALSE == hr)
00146 {
00147
00148
00149
00150 pOutSample->Release();
00151
00152
00153
00154
00155
00156 return NOERROR;
00157 }
00158 }
00159 }
00160
00161
00162 pOutSample->Release();
00163 }
00164 }
00165 return hr;
00166 }
00167 else
00168 {
00169
00170 return E_INVALIDARG;
00171 }
00172 }
00173
00174 void CRtvcTee::InitialiseInputTypes()
00175 {
00176 AddInputType(NULL, NULL, NULL);
00177 }
00178
00179 void CRtvcTee::InitialiseOutputTypes()
00180 {
00181 AddOutputType(NULL, NULL, NULL);
00182 }
00183
00184 HRESULT CRtvcTee::DecideBufferSize( IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pRequestProperties, int m_nIndex )
00185 {
00186
00187 AM_MEDIA_TYPE mt;
00188 HRESULT hr = m_vInputPins[0]->ConnectionMediaType(&mt);
00189 if (FAILED(hr))
00190 {
00191 return hr;
00192 }
00193
00194
00195 assert(mt.formattype == FORMAT_VideoInfo || mt.formattype == FORMAT_WaveFormatEx);
00196 if(mt.formattype == FORMAT_VideoInfo)
00197 {
00198 BITMAPINFOHEADER *pbmi = HEADER(mt.pbFormat);
00199 pRequestProperties->cbBuffer = DIBSIZE(*pbmi);
00200 }
00201 else if (mt.formattype == FORMAT_WaveFormatEx)
00202 {
00203 WAVEFORMATEX *pWavHeader = (WAVEFORMATEX*)mt.pbFormat;
00204 pRequestProperties->cbBuffer = pWavHeader->nSamplesPerSec * pWavHeader->nChannels * (pWavHeader->wBitsPerSample >> 3);
00205 }
00206
00207 if (pRequestProperties->cbAlign == 0)
00208 {
00209 pRequestProperties->cbAlign = 1;
00210 }
00211 if (pRequestProperties->cBuffers == 0)
00212 {
00213 pRequestProperties->cBuffers = 1;
00214 }
00215
00216 FreeMediaType(mt);
00217
00218
00219 ALLOCATOR_PROPERTIES Actual;
00220 hr = pAlloc->SetProperties(pRequestProperties, &Actual);
00221 if (FAILED(hr))
00222 {
00223 return hr;
00224 }
00225
00226 if (pRequestProperties->cbBuffer > Actual.cbBuffer)
00227 {
00228 return E_FAIL;
00229 }
00230 return S_OK;
00231 }
00232
00233 HRESULT CRtvcTee::GetMediaType( int iPosition, CMediaType* pMediaType, int nOutputPinIndex )
00234 {
00235 if (iPosition < 0)
00236 {
00237 return E_INVALIDARG;
00238 }
00239 else if (iPosition == 0)
00240 {
00241 return m_vInputPins[0]->ConnectionMediaType(pMediaType);
00242 }
00243 return VFW_S_NO_MORE_ITEMS;
00244 }
00245
00246 HRESULT CRtvcTee::CheckOutputType( const CMediaType* pMediaType )
00247 {
00248 AM_MEDIA_TYPE mediaType;
00249 HRESULT hr = m_vInputPins[0]->ConnectionMediaType(&mediaType);
00250 if ((*pMediaType->Type() == mediaType.majortype) &&
00251 (*pMediaType->Subtype() == mediaType.subtype) &&
00252 (*pMediaType->FormatType() == mediaType.formattype)
00253 )
00254 {
00255 return S_OK;
00256 }
00257 else
00258 {
00259 return VFW_E_TYPE_NOT_ACCEPTED;
00260 }
00261 }