00001
00002
00003
00004
00005
00006 #include <streams.h>
00007 #include <measure.h>
00008
00009 CTransformFilter::CTransformFilter(TCHAR *pName,
00010 LPUNKNOWN pUnk,
00011 REFCLSID clsid) :
00012 CBaseFilter(pName,pUnk,&m_csFilter, clsid),
00013 m_pInput(NULL),
00014 m_pOutput(NULL),
00015 m_bEOSDelivered(FALSE),
00016 m_bQualityChanged(FALSE),
00017 m_bSampleSkipped(FALSE)
00018 {
00019 #ifdef PERF
00020 RegisterPerfId();
00021 #endif
00022 }
00023
00024 #ifdef UNICODE
00025 CTransformFilter::CTransformFilter(char *pName,
00026 LPUNKNOWN pUnk,
00027 REFCLSID clsid) :
00028 CBaseFilter(pName,pUnk,&m_csFilter, clsid),
00029 m_pInput(NULL),
00030 m_pOutput(NULL),
00031 m_bEOSDelivered(FALSE),
00032 m_bQualityChanged(FALSE),
00033 m_bSampleSkipped(FALSE)
00034 {
00035 #ifdef PERF
00036 RegisterPerfId();
00037 #endif
00038 }
00039 #endif
00040
00041 CTransformFilter::~CTransformFilter()
00042 {
00043
00044
00045 delete m_pInput;
00046 delete m_pOutput;
00047 }
00048
00049 HRESULT CTransformFilter::Transform(IMediaSample * pIn, IMediaSample *pOut)
00050 {
00051 UNREFERENCED_PARAMETER(pIn);
00052 UNREFERENCED_PARAMETER(pOut);
00053 DbgBreak("CTransformFilter::Transform() should never be called");
00054 return E_UNEXPECTED;
00055 }
00056
00057 int CTransformFilter::GetPinCount()
00058 {
00059 return 2;
00060 }
00061
00062 CBasePin *
00063 CTransformFilter::GetPin(int n)
00064 {
00065 HRESULT hr = S_OK;
00066
00067
00068
00069 if (m_pInput == NULL) {
00070
00071 m_pInput = new CTransformInputPin(NAME("Transform input pin"),
00072 this,
00073 &hr,
00074 L"XForm In");
00075
00076
00077 ASSERT(SUCCEEDED(hr));
00078 if (m_pInput == NULL) {
00079 return NULL;
00080 }
00081 m_pOutput = (CTransformOutputPin *)
00082 new CTransformOutputPin(NAME("Transform output pin"),
00083 this,
00084 &hr,
00085 L"XForm Out");
00086
00087
00088 ASSERT(SUCCEEDED(hr));
00089 if (m_pOutput == NULL) {
00090 delete m_pInput;
00091 m_pInput = NULL;
00092 }
00093 }
00094
00095
00096
00097 if (n == 0) {
00098 return m_pInput;
00099 } else
00100 if (n == 1) {
00101 return m_pOutput;
00102 } else {
00103 return NULL;
00104 }
00105 }
00106
00107 STDMETHODIMP CTransformFilter::FindPin(LPCWSTR Id, IPin **ppPin)
00108 {
00109 CheckPointer(ppPin,E_POINTER);
00110 ValidateReadWritePtr(ppPin,sizeof(IPin *));
00111
00112 if (0==lstrcmpW(Id,L"In")) {
00113 *ppPin = GetPin(0);
00114 } else if (0==lstrcmpW(Id,L"Out")) {
00115 *ppPin = GetPin(1);
00116 } else {
00117 *ppPin = NULL;
00118 return VFW_E_NOT_FOUND;
00119 }
00120
00121 HRESULT hr = NOERROR;
00122
00123 if (*ppPin) {
00124 (*ppPin)->AddRef();
00125 } else {
00126 hr = E_OUTOFMEMORY;
00127 }
00128 return hr;
00129 }
00130
00131 HRESULT
00132 CTransformFilter::StartStreaming()
00133 {
00134 return NOERROR;
00135 }
00136
00137 HRESULT
00138 CTransformFilter::StopStreaming()
00139 {
00140 return NOERROR;
00141 }
00142
00143 HRESULT
00144 CTransformFilter::CheckConnect(PIN_DIRECTION dir,IPin *pPin)
00145 {
00146 UNREFERENCED_PARAMETER(dir);
00147 UNREFERENCED_PARAMETER(pPin);
00148 return NOERROR;
00149 }
00150
00151 HRESULT
00152 CTransformFilter::BreakConnect(PIN_DIRECTION dir)
00153 {
00154 UNREFERENCED_PARAMETER(dir);
00155 return NOERROR;
00156 }
00157
00158 HRESULT
00159 CTransformFilter::CompleteConnect(PIN_DIRECTION direction,IPin *pReceivePin)
00160 {
00161 UNREFERENCED_PARAMETER(direction);
00162 UNREFERENCED_PARAMETER(pReceivePin);
00163 return NOERROR;
00164 }
00165
00166 HRESULT
00167 CTransformFilter::SetMediaType(PIN_DIRECTION direction,const CMediaType *pmt)
00168 {
00169 UNREFERENCED_PARAMETER(direction);
00170 UNREFERENCED_PARAMETER(pmt);
00171 return NOERROR;
00172 }
00173
00174 HRESULT
00175 CTransformFilter::InitializeOutputSample(IMediaSample *pSample, IMediaSample **ppOutSample)
00176 {
00177 IMediaSample *pOutSample;
00178
00179
00180
00181 AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps();
00182 DWORD dwFlags = m_bSampleSkipped ? AM_GBF_PREVFRAMESKIPPED : 0;
00183
00184
00185
00186
00187
00188 if (!(pProps->dwSampleFlags & AM_SAMPLE_SPLICEPOINT)) {
00189 dwFlags |= AM_GBF_NOTASYNCPOINT;
00190 }
00191
00192 ASSERT(m_pOutput->m_pAllocator != NULL);
00193 HRESULT hr = m_pOutput->m_pAllocator->GetBuffer(
00194 &pOutSample
00195 , pProps->dwSampleFlags & AM_SAMPLE_TIMEVALID ?
00196 &pProps->tStart : NULL
00197 , pProps->dwSampleFlags & AM_SAMPLE_STOPVALID ?
00198 &pProps->tStop : NULL
00199 , dwFlags
00200 );
00201 *ppOutSample = pOutSample;
00202 if (FAILED(hr)) {
00203 return hr;
00204 }
00205
00206 ASSERT(pOutSample);
00207 IMediaSample2 *pOutSample2;
00208 if (SUCCEEDED(pOutSample->QueryInterface(IID_IMediaSample2,
00209 (void **)&pOutSample2))) {
00210
00211 AM_SAMPLE2_PROPERTIES OutProps;
00212 EXECUTE_ASSERT(SUCCEEDED(pOutSample2->GetProperties(
00213 FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, tStart), (PBYTE)&OutProps)
00214 ));
00215 OutProps.dwTypeSpecificFlags = pProps->dwTypeSpecificFlags;
00216 OutProps.dwSampleFlags =
00217 (OutProps.dwSampleFlags & AM_SAMPLE_TYPECHANGED) |
00218 (pProps->dwSampleFlags & ~AM_SAMPLE_TYPECHANGED);
00219 OutProps.tStart = pProps->tStart;
00220 OutProps.tStop = pProps->tStop;
00221 OutProps.cbData = FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, dwStreamId);
00222 hr = pOutSample2->SetProperties(
00223 FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, dwStreamId),
00224 (PBYTE)&OutProps
00225 );
00226 if (pProps->dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) {
00227 m_bSampleSkipped = FALSE;
00228 }
00229 pOutSample2->Release();
00230 } else {
00231 if (pProps->dwSampleFlags & AM_SAMPLE_TIMEVALID) {
00232 pOutSample->SetTime(&pProps->tStart,
00233 &pProps->tStop);
00234 }
00235 if (pProps->dwSampleFlags & AM_SAMPLE_SPLICEPOINT) {
00236 pOutSample->SetSyncPoint(TRUE);
00237 }
00238 if (pProps->dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) {
00239 pOutSample->SetDiscontinuity(TRUE);
00240 m_bSampleSkipped = FALSE;
00241 }
00242
00243
00244 LONGLONG MediaStart, MediaEnd;
00245 if (pSample->GetMediaTime(&MediaStart,&MediaEnd) == NOERROR) {
00246 pOutSample->SetMediaTime(&MediaStart,&MediaEnd);
00247 }
00248 }
00249 return S_OK;
00250 }
00251
00252 HRESULT
00253 CTransformFilter::Receive(IMediaSample *pSample)
00254 {
00255
00256 AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps();
00257 if (pProps->dwStreamId != AM_STREAM_MEDIA) {
00258 return m_pOutput->m_pInputPin->Receive(pSample);
00259 }
00260 HRESULT hr;
00261 ASSERT(pSample);
00262 IMediaSample * pOutSample;
00263
00264
00265
00266 ASSERT (m_pOutput != NULL) ;
00267
00268
00269 hr = InitializeOutputSample(pSample, &pOutSample);
00270
00271 if (FAILED(hr)) {
00272 return hr;
00273 }
00274
00275
00276 MSR_START(m_idTransform);
00277
00278
00279
00280 hr = Transform(pSample, pOutSample);
00281
00282
00283 MSR_STOP(m_idTransform);
00284
00285 if (FAILED(hr)) {
00286 DbgLog((LOG_TRACE,1,TEXT("Error from transform")));
00287 } else {
00288
00289
00290
00291 if (hr == NOERROR) {
00292 hr = m_pOutput->m_pInputPin->Receive(pOutSample);
00293 m_bSampleSkipped = FALSE;
00294 } else {
00295
00296
00297
00298
00299 if (S_FALSE == hr) {
00300
00301
00302
00303
00304 pOutSample->Release();
00305 m_bSampleSkipped = TRUE;
00306 if (!m_bQualityChanged) {
00307 NotifyEvent(EC_QUALITY_CHANGE,0,0);
00308 m_bQualityChanged = TRUE;
00309 }
00310 return NOERROR;
00311 }
00312 }
00313 }
00314
00315
00316
00317 pOutSample->Release();
00318
00319 return hr;
00320 }
00321
00322 HRESULT CTransformFilter::AlterQuality(Quality q)
00323 {
00324 UNREFERENCED_PARAMETER(q);
00325 return S_FALSE;
00326 }
00327
00328 HRESULT
00329 CTransformFilter::EndOfStream(void)
00330 {
00331 HRESULT hr = NOERROR;
00332 if (m_pOutput != NULL) {
00333 hr = m_pOutput->DeliverEndOfStream();
00334 }
00335
00336 return hr;
00337 }
00338
00339 HRESULT
00340 CTransformFilter::BeginFlush(void)
00341 {
00342 HRESULT hr = NOERROR;
00343 if (m_pOutput != NULL) {
00344
00345
00346
00347
00348
00349
00350
00351 hr = m_pOutput->DeliverBeginFlush();
00352 }
00353 return hr;
00354 }
00355
00356 HRESULT
00357 CTransformFilter::EndFlush(void)
00358 {
00359
00360
00361
00362
00363
00364 ASSERT (m_pOutput != NULL);
00365 return m_pOutput->DeliverEndFlush();
00366
00367
00368 }
00369
00370 STDMETHODIMP
00371 CTransformFilter::Stop()
00372 {
00373 CAutoLock lck1(&m_csFilter);
00374 if (m_State == State_Stopped) {
00375 return NOERROR;
00376 }
00377
00378
00379
00380 ASSERT(m_pInput == NULL || m_pOutput != NULL);
00381 if (m_pInput == NULL || m_pInput->IsConnected() == FALSE ||
00382 m_pOutput->IsConnected() == FALSE) {
00383 m_State = State_Stopped;
00384 m_bEOSDelivered = FALSE;
00385 return NOERROR;
00386 }
00387
00388 ASSERT(m_pInput);
00389 ASSERT(m_pOutput);
00390
00391
00392 m_pInput->Inactive();
00393
00394
00395
00396 CAutoLock lck2(&m_csReceive);
00397 m_pOutput->Inactive();
00398
00399
00400
00401
00402 HRESULT hr = StopStreaming();
00403 if (SUCCEEDED(hr)) {
00404
00405 m_State = State_Stopped;
00406 m_bEOSDelivered = FALSE;
00407 }
00408 return hr;
00409 }
00410
00411 STDMETHODIMP
00412 CTransformFilter::Pause()
00413 {
00414 CAutoLock lck(&m_csFilter);
00415 HRESULT hr = NOERROR;
00416
00417 if (m_State == State_Paused) {
00418
00419 }
00420
00421
00422
00423
00424
00425
00426 else if (m_pInput == NULL || m_pInput->IsConnected() == FALSE) {
00427 if (m_pOutput && m_bEOSDelivered == FALSE) {
00428 m_pOutput->DeliverEndOfStream();
00429 m_bEOSDelivered = TRUE;
00430 }
00431 m_State = State_Paused;
00432 }
00433
00434
00435
00436
00437 else if (m_pOutput->IsConnected() == FALSE) {
00438 m_State = State_Paused;
00439 }
00440
00441 else {
00442 if (m_State == State_Stopped) {
00443
00444
00445 CAutoLock lck2(&m_csReceive);
00446 hr = StartStreaming();
00447 }
00448 if (SUCCEEDED(hr)) {
00449 hr = CBaseFilter::Pause();
00450 }
00451 }
00452
00453 m_bSampleSkipped = FALSE;
00454 m_bQualityChanged = FALSE;
00455 return hr;
00456 }
00457
00458 HRESULT
00459 CTransformFilter::NewSegment(
00460 REFERENCE_TIME tStart,
00461 REFERENCE_TIME tStop,
00462 double dRate)
00463 {
00464 if (m_pOutput != NULL) {
00465 return m_pOutput->DeliverNewSegment(tStart, tStop, dRate);
00466 }
00467 return S_OK;
00468 }
00469
00470 HRESULT
00471 CTransformInputPin::CheckStreaming()
00472 {
00473 ASSERT(m_pTransformFilter->m_pOutput != NULL);
00474 if (!m_pTransformFilter->m_pOutput->IsConnected()) {
00475 return VFW_E_NOT_CONNECTED;
00476 } else {
00477
00478 ASSERT(IsConnected());
00479
00480
00481 if (m_bFlushing) {
00482 return S_FALSE;
00483 }
00484
00485 if (IsStopped()) {
00486 return VFW_E_WRONG_STATE;
00487 }
00488 if (m_bRunTimeError) {
00489 return VFW_E_RUNTIME_ERROR;
00490 }
00491 return S_OK;
00492 }
00493 }
00494
00495 CTransformInputPin::CTransformInputPin(
00496 TCHAR *pObjectName,
00497 CTransformFilter *pTransformFilter,
00498 HRESULT * phr,
00499 LPCWSTR pName)
00500 : CBaseInputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pName)
00501 {
00502 DbgLog((LOG_TRACE,2,TEXT("CTransformInputPin::CTransformInputPin")));
00503 m_pTransformFilter = pTransformFilter;
00504 }
00505
00506 #ifdef UNICODE
00507 CTransformInputPin::CTransformInputPin(
00508 CHAR *pObjectName,
00509 CTransformFilter *pTransformFilter,
00510 HRESULT * phr,
00511 LPCWSTR pName)
00512 : CBaseInputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pName)
00513 {
00514 DbgLog((LOG_TRACE,2,TEXT("CTransformInputPin::CTransformInputPin")));
00515 m_pTransformFilter = pTransformFilter;
00516 }
00517 #endif
00518
00519 HRESULT
00520 CTransformInputPin::CheckConnect(IPin *pPin)
00521 {
00522 HRESULT hr = m_pTransformFilter->CheckConnect(PINDIR_INPUT,pPin);
00523 if (FAILED(hr)) {
00524 return hr;
00525 }
00526 return CBaseInputPin::CheckConnect(pPin);
00527 }
00528
00529 HRESULT
00530 CTransformInputPin::BreakConnect()
00531 {
00532
00533 ASSERT(IsStopped());
00534 m_pTransformFilter->BreakConnect(PINDIR_INPUT);
00535 return CBaseInputPin::BreakConnect();
00536 }
00537
00538 HRESULT
00539 CTransformInputPin::CompleteConnect(IPin *pReceivePin)
00540 {
00541 HRESULT hr = m_pTransformFilter->CompleteConnect(PINDIR_INPUT,pReceivePin);
00542 if (FAILED(hr)) {
00543 return hr;
00544 }
00545 return CBaseInputPin::CompleteConnect(pReceivePin);
00546 }
00547
00548 HRESULT
00549 CTransformInputPin::CheckMediaType(const CMediaType* pmt)
00550 {
00551
00552
00553 HRESULT hr = m_pTransformFilter->CheckInputType(pmt);
00554 if (S_OK != hr) {
00555 return hr;
00556 }
00557
00558
00559
00560
00561 if ((m_pTransformFilter->m_pOutput != NULL) &&
00562 (m_pTransformFilter->m_pOutput->IsConnected())) {
00563 return m_pTransformFilter->CheckTransform(
00564 pmt,
00565 &m_pTransformFilter->m_pOutput->CurrentMediaType());
00566 } else {
00567 return hr;
00568 }
00569 }
00570
00571 HRESULT
00572 CTransformInputPin::SetMediaType(const CMediaType* mtIn)
00573 {
00574
00575 HRESULT hr = CBasePin::SetMediaType(mtIn);
00576 ASSERT(SUCCEEDED(hr));
00577
00578
00579 ASSERT(SUCCEEDED(m_pTransformFilter->CheckInputType(mtIn)));
00580
00581 m_pTransformFilter->SetMediaType(PINDIR_INPUT,mtIn);
00582 return NOERROR;
00583 }
00584
00585 STDMETHODIMP
00586 CTransformInputPin::EndOfStream(void)
00587 {
00588 CAutoLock lck(&m_pTransformFilter->m_csReceive);
00589 HRESULT hr = CheckStreaming();
00590 if (S_OK == hr) {
00591 hr = m_pTransformFilter->EndOfStream();
00592 }
00593 return hr;
00594 }
00595
00596 STDMETHODIMP
00597 CTransformInputPin::BeginFlush(void)
00598 {
00599 CAutoLock lck(&m_pTransformFilter->m_csFilter);
00600
00601 ASSERT(m_pTransformFilter->m_pOutput != NULL);
00602 if (!IsConnected() ||
00603 !m_pTransformFilter->m_pOutput->IsConnected()) {
00604 return VFW_E_NOT_CONNECTED;
00605 }
00606 HRESULT hr = CBaseInputPin::BeginFlush();
00607 if (FAILED(hr)) {
00608 return hr;
00609 }
00610
00611 return m_pTransformFilter->BeginFlush();
00612 }
00613
00614 STDMETHODIMP
00615 CTransformInputPin::EndFlush(void)
00616 {
00617 CAutoLock lck(&m_pTransformFilter->m_csFilter);
00618
00619 ASSERT(m_pTransformFilter->m_pOutput != NULL);
00620 if (!IsConnected() ||
00621 !m_pTransformFilter->m_pOutput->IsConnected()) {
00622 return VFW_E_NOT_CONNECTED;
00623 }
00624
00625 HRESULT hr = m_pTransformFilter->EndFlush();
00626 if (FAILED(hr)) {
00627 return hr;
00628 }
00629
00630 return CBaseInputPin::EndFlush();
00631 }
00632
00633 HRESULT
00634 CTransformInputPin::Receive(IMediaSample * pSample)
00635 {
00636 HRESULT hr;
00637 CAutoLock lck(&m_pTransformFilter->m_csReceive);
00638 ASSERT(pSample);
00639
00640
00641 hr = CBaseInputPin::Receive(pSample);
00642 if (S_OK == hr) {
00643 hr = m_pTransformFilter->Receive(pSample);
00644 }
00645 return hr;
00646 }
00647
00648 STDMETHODIMP
00649 CTransformInputPin::NewSegment(
00650 REFERENCE_TIME tStart,
00651 REFERENCE_TIME tStop,
00652 double dRate)
00653 {
00654
00655 CBasePin::NewSegment(tStart, tStop, dRate);
00656 return m_pTransformFilter->NewSegment(tStart, tStop, dRate);
00657 }
00658
00659 CTransformOutputPin::CTransformOutputPin(
00660 TCHAR *pObjectName,
00661 CTransformFilter *pTransformFilter,
00662 HRESULT * phr,
00663 LPCWSTR pPinName)
00664 : CBaseOutputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pPinName),
00665 m_pPosition(NULL)
00666 {
00667 DbgLog((LOG_TRACE,2,TEXT("CTransformOutputPin::CTransformOutputPin")));
00668 m_pTransformFilter = pTransformFilter;
00669
00670 }
00671
00672 #ifdef UNICODE
00673 CTransformOutputPin::CTransformOutputPin(
00674 CHAR *pObjectName,
00675 CTransformFilter *pTransformFilter,
00676 HRESULT * phr,
00677 LPCWSTR pPinName)
00678 : CBaseOutputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pPinName),
00679 m_pPosition(NULL)
00680 {
00681 DbgLog((LOG_TRACE,2,TEXT("CTransformOutputPin::CTransformOutputPin")));
00682 m_pTransformFilter = pTransformFilter;
00683
00684 }
00685 #endif
00686
00687 CTransformOutputPin::~CTransformOutputPin()
00688 {
00689 DbgLog((LOG_TRACE,2,TEXT("CTransformOutputPin::~CTransformOutputPin")));
00690
00691 if (m_pPosition) m_pPosition->Release();
00692 }
00693
00694 STDMETHODIMP
00695 CTransformOutputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00696 {
00697 CheckPointer(ppv,E_POINTER);
00698 ValidateReadWritePtr(ppv,sizeof(PVOID));
00699 *ppv = NULL;
00700
00701 if (riid == IID_IMediaPosition || riid == IID_IMediaSeeking) {
00702
00703
00704
00705 ASSERT(m_pTransformFilter->m_pInput != NULL);
00706
00707 if (m_pPosition == NULL) {
00708
00709 HRESULT hr = CreatePosPassThru(
00710 GetOwner(),
00711 FALSE,
00712 (IPin *)m_pTransformFilter->m_pInput,
00713 &m_pPosition);
00714 if (FAILED(hr)) {
00715 return hr;
00716 }
00717 }
00718 return m_pPosition->QueryInterface(riid, ppv);
00719 } else {
00720 return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv);
00721 }
00722 }
00723
00724 HRESULT
00725 CTransformOutputPin::CheckConnect(IPin *pPin)
00726 {
00727
00728
00729 ASSERT(m_pTransformFilter->m_pInput != NULL);
00730 if ((m_pTransformFilter->m_pInput->IsConnected() == FALSE)) {
00731 return E_UNEXPECTED;
00732 }
00733
00734 HRESULT hr = m_pTransformFilter->CheckConnect(PINDIR_OUTPUT,pPin);
00735 if (FAILED(hr)) {
00736 return hr;
00737 }
00738 return CBaseOutputPin::CheckConnect(pPin);
00739 }
00740
00741 HRESULT
00742 CTransformOutputPin::BreakConnect()
00743 {
00744
00745 ASSERT(IsStopped());
00746 m_pTransformFilter->BreakConnect(PINDIR_OUTPUT);
00747 return CBaseOutputPin::BreakConnect();
00748 }
00749
00750 HRESULT
00751 CTransformOutputPin::CompleteConnect(IPin *pReceivePin)
00752 {
00753 HRESULT hr = m_pTransformFilter->CompleteConnect(PINDIR_OUTPUT,pReceivePin);
00754 if (FAILED(hr)) {
00755 return hr;
00756 }
00757 return CBaseOutputPin::CompleteConnect(pReceivePin);
00758 }
00759
00760 HRESULT
00761 CTransformOutputPin::CheckMediaType(const CMediaType* pmtOut)
00762 {
00763
00764 ASSERT(m_pTransformFilter->m_pInput != NULL);
00765 if ((m_pTransformFilter->m_pInput->IsConnected() == FALSE)) {
00766 return E_INVALIDARG;
00767 }
00768
00769 return m_pTransformFilter->CheckTransform(
00770 &m_pTransformFilter->m_pInput->CurrentMediaType(),
00771 pmtOut);
00772 }
00773
00774 HRESULT
00775 CTransformOutputPin::SetMediaType(const CMediaType* pmtOut)
00776 {
00777 HRESULT hr = NOERROR;
00778 ASSERT(m_pTransformFilter->m_pInput != NULL);
00779
00780 ASSERT(m_pTransformFilter->m_pInput->CurrentMediaType().IsValid());
00781
00782
00783 hr = CBasePin::SetMediaType(pmtOut);
00784 ASSERT(SUCCEEDED(hr));
00785
00786 #ifdef DEBUG
00787 if (FAILED(m_pTransformFilter->CheckTransform(&m_pTransformFilter->
00788 m_pInput->CurrentMediaType(),pmtOut))) {
00789 DbgLog((LOG_ERROR,0,TEXT("*** This filter is accepting an output media type")));
00790 DbgLog((LOG_ERROR,0,TEXT(" that it can't currently transform to. I hope")));
00791 DbgLog((LOG_ERROR,0,TEXT(" it's smart enough to reconnect its input.")));
00792 }
00793 #endif
00794
00795 m_pTransformFilter->SetMediaType(PINDIR_OUTPUT,pmtOut);
00796 return NOERROR;
00797 }
00798
00799 HRESULT
00800 CTransformOutputPin::DecideBufferSize(
00801 IMemAllocator * pAllocator,
00802 ALLOCATOR_PROPERTIES* pProp)
00803 {
00804 return m_pTransformFilter->DecideBufferSize(pAllocator, pProp);
00805 }
00806
00807 HRESULT
00808 CTransformOutputPin::GetMediaType(
00809 int iPosition,
00810 CMediaType *pMediaType)
00811 {
00812 ASSERT(m_pTransformFilter->m_pInput != NULL);
00813
00814
00815
00816 if (m_pTransformFilter->m_pInput->IsConnected()) {
00817 return m_pTransformFilter->GetMediaType(iPosition,pMediaType);
00818 } else {
00819 return VFW_S_NO_MORE_ITEMS;
00820 }
00821 }
00822
00823 STDMETHODIMP
00824 CTransformOutputPin::Notify(IBaseFilter * pSender, Quality q)
00825 {
00826 UNREFERENCED_PARAMETER(pSender);
00827 ValidateReadPtr(pSender,sizeof(IBaseFilter));
00828
00829
00830 HRESULT hr = m_pTransformFilter->AlterQuality(q);
00831 if (hr!=S_FALSE) {
00832 return hr;
00833 }
00834
00835
00836
00837
00838 ASSERT(m_pTransformFilter->m_pInput != NULL);
00839
00840 return m_pTransformFilter->m_pInput->PassNotify(q);
00841
00842 }
00843
00844 #pragma warning(disable:4514)