00001
00002
00003
00004
00005
00006 #include <streams.h>
00007 #include <measure.h>
00008
00009 CVideoTransformFilter::CVideoTransformFilter
00010 ( TCHAR *pName, LPUNKNOWN pUnk, REFCLSID clsid)
00011 : CTransformFilter(pName, pUnk, clsid)
00012 , m_itrLate(0)
00013 , m_nKeyFramePeriod(0)
00014 , m_nFramesSinceKeyFrame(0)
00015 , m_bSkipping(FALSE)
00016 , m_tDecodeStart(0)
00017 , m_itrAvgDecode(300000)
00018 , m_bQualityChanged(FALSE)
00019 {
00020 #ifdef PERF
00021 RegisterPerfId();
00022 #endif
00023 }
00024
00025 CVideoTransformFilter::~CVideoTransformFilter()
00026 {
00027
00028 }
00029
00030 HRESULT CVideoTransformFilter::StartStreaming()
00031 {
00032 m_itrLate = 0;
00033 m_nKeyFramePeriod = 0;
00034 m_nFramesSinceKeyFrame = 0;
00035 m_bSkipping = FALSE;
00036 m_tDecodeStart = 0;
00037 m_itrAvgDecode = 300000;
00038 m_bQualityChanged = FALSE;
00039 m_bSampleSkipped = FALSE;
00040 return NOERROR;
00041 }
00042
00043 HRESULT CVideoTransformFilter::EndFlush()
00044 {
00045 {
00046
00047 CAutoLock lck(&m_csReceive);
00048
00049
00050
00051
00052
00053
00054 CVideoTransformFilter::StartStreaming();
00055 }
00056 return CTransformFilter::EndFlush();
00057 }
00058
00059 HRESULT CVideoTransformFilter::AbortPlayback(HRESULT hr)
00060 {
00061 NotifyEvent(EC_ERRORABORT, hr, 0);
00062 m_pOutput->DeliverEndOfStream();
00063 return hr;
00064 }
00065
00066 HRESULT CVideoTransformFilter::Receive(IMediaSample *pSample)
00067 {
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 ASSERT(CritCheckIn(&m_csReceive));
00080 AM_MEDIA_TYPE *pmtOut, *pmt;
00081 #ifdef DEBUG
00082 FOURCCMap fccOut;
00083 #endif
00084 HRESULT hr;
00085 ASSERT(pSample);
00086 IMediaSample * pOutSample;
00087
00088
00089 ASSERT (m_pOutput != NULL) ;
00090
00091
00092
00093
00094
00095
00096
00097 #define rcS1 ((VIDEOINFOHEADER *)(pmt->pbFormat))->rcSource
00098 #define rcT1 ((VIDEOINFOHEADER *)(pmt->pbFormat))->rcTarget
00099
00100 pSample->GetMediaType(&pmt);
00101 if (pmt != NULL && pmt->pbFormat != NULL) {
00102
00103
00104 ASSERT(!IsEqualGUID(pmt->majortype, GUID_NULL));
00105 #ifdef DEBUG
00106 fccOut.SetFOURCC(&pmt->subtype);
00107 LONG lCompression = HEADER(pmt->pbFormat)->biCompression;
00108 LONG lBitCount = HEADER(pmt->pbFormat)->biBitCount;
00109 LONG lStride = (HEADER(pmt->pbFormat)->biWidth * lBitCount + 7) / 8;
00110 lStride = (lStride + 3) & ~3;
00111 DbgLog((LOG_TRACE,3,TEXT("*Changing input type on the fly to")));
00112 DbgLog((LOG_TRACE,3,TEXT("FourCC: %lx Compression: %lx BitCount: %ld"),
00113 fccOut.GetFOURCC(), lCompression, lBitCount));
00114 DbgLog((LOG_TRACE,3,TEXT("biHeight: %ld rcDst: (%ld, %ld, %ld, %ld)"),
00115 HEADER(pmt->pbFormat)->biHeight,
00116 rcT1.left, rcT1.top, rcT1.right, rcT1.bottom));
00117 DbgLog((LOG_TRACE,3,TEXT("rcSrc: (%ld, %ld, %ld, %ld) Stride: %ld"),
00118 rcS1.left, rcS1.top, rcS1.right, rcS1.bottom,
00119 lStride));
00120 #endif
00121
00122
00123
00124
00125
00126 StopStreaming();
00127 m_pInput->CurrentMediaType() = *pmt;
00128 DeleteMediaType(pmt);
00129
00130 hr = StartStreaming();
00131 if (FAILED(hr)) {
00132 return AbortPlayback(hr);
00133 }
00134 }
00135
00136
00137
00138
00139 if (ShouldSkipFrame(pSample)) {
00140 MSR_NOTE(m_idSkip);
00141 m_bSampleSkipped = TRUE;
00142 return NOERROR;
00143 }
00144
00145
00146 hr = InitializeOutputSample(pSample, &pOutSample);
00147
00148 if (FAILED(hr)) {
00149 return hr;
00150 }
00151
00152 m_bSampleSkipped = FALSE;
00153
00154
00155
00156
00157 #define rcS ((VIDEOINFOHEADER *)(pmtOut->pbFormat))->rcSource
00158 #define rcT ((VIDEOINFOHEADER *)(pmtOut->pbFormat))->rcTarget
00159
00160 pOutSample->GetMediaType(&pmtOut);
00161 if (pmtOut != NULL && pmtOut->pbFormat != NULL) {
00162
00163
00164 ASSERT(!IsEqualGUID(pmtOut->majortype, GUID_NULL));
00165 #ifdef DEBUG
00166 fccOut.SetFOURCC(&pmtOut->subtype);
00167 LONG lCompression = HEADER(pmtOut->pbFormat)->biCompression;
00168 LONG lBitCount = HEADER(pmtOut->pbFormat)->biBitCount;
00169 LONG lStride = (HEADER(pmtOut->pbFormat)->biWidth * lBitCount + 7) / 8;
00170 lStride = (lStride + 3) & ~3;
00171 DbgLog((LOG_TRACE,3,TEXT("*Changing output type on the fly to")));
00172 DbgLog((LOG_TRACE,3,TEXT("FourCC: %lx Compression: %lx BitCount: %ld"),
00173 fccOut.GetFOURCC(), lCompression, lBitCount));
00174 DbgLog((LOG_TRACE,3,TEXT("biHeight: %ld rcDst: (%ld, %ld, %ld, %ld)"),
00175 HEADER(pmtOut->pbFormat)->biHeight,
00176 rcT.left, rcT.top, rcT.right, rcT.bottom));
00177 DbgLog((LOG_TRACE,3,TEXT("rcSrc: (%ld, %ld, %ld, %ld) Stride: %ld"),
00178 rcS.left, rcS.top, rcS.right, rcS.bottom,
00179 lStride));
00180 #endif
00181
00182
00183
00184
00185
00186 StopStreaming();
00187 m_pOutput->CurrentMediaType() = *pmtOut;
00188 DeleteMediaType(pmtOut);
00189 hr = StartStreaming();
00190
00191 if (SUCCEEDED(hr)) {
00192
00193
00194
00195 DbgLog((LOG_TRACE,3,TEXT("Output format change means we must wait for a keyframe")));
00196 m_nWaitForKey = 30;
00197
00198
00199 } else {
00200
00201
00202
00203
00204 pOutSample->Release();
00205 AbortPlayback(hr);
00206 return hr;
00207 }
00208 }
00209
00210
00211 if (pSample->IsDiscontinuity() == S_OK) {
00212 DbgLog((LOG_TRACE,3,TEXT("Non-key discontinuity - wait for keyframe")));
00213 m_nWaitForKey = 30;
00214 }
00215
00216
00217
00218 if (SUCCEEDED(hr)) {
00219 m_tDecodeStart = timeGetTime();
00220 MSR_START(m_idTransform);
00221
00222
00223 hr = Transform(pSample, pOutSample);
00224
00225
00226 MSR_STOP(m_idTransform);
00227 m_tDecodeStart = timeGetTime()-m_tDecodeStart;
00228 m_itrAvgDecode = m_tDecodeStart*(10000/16) + 15*(m_itrAvgDecode/16);
00229
00230
00231 if (m_nWaitForKey)
00232 m_nWaitForKey--;
00233 if (m_nWaitForKey && pSample->IsSyncPoint() == S_OK)
00234 m_nWaitForKey = FALSE;
00235
00236
00237 if (m_nWaitForKey && hr == NOERROR) {
00238 DbgLog((LOG_TRACE,3,TEXT("still waiting for a keyframe")));
00239 hr = S_FALSE;
00240 }
00241 }
00242
00243 if (FAILED(hr)) {
00244 DbgLog((LOG_TRACE,1,TEXT("Error from video transform")));
00245 } else {
00246
00247
00248
00249
00250
00251
00252 if (hr == NOERROR) {
00253 hr = m_pOutput->Deliver(pOutSample);
00254 } else {
00255
00256
00257
00258
00259 if (S_FALSE == hr) {
00260
00261
00262
00263
00264
00265 pOutSample->Release();
00266 m_bSampleSkipped = TRUE;
00267 if (!m_bQualityChanged) {
00268 m_bQualityChanged = TRUE;
00269 NotifyEvent(EC_QUALITY_CHANGE,0,0);
00270 }
00271 return NOERROR;
00272 }
00273 }
00274 }
00275
00276
00277
00278 pOutSample->Release();
00279 ASSERT(CritCheckIn(&m_csReceive));
00280
00281 return hr;
00282 }
00283
00284 BOOL CVideoTransformFilter::ShouldSkipFrame( IMediaSample * pIn)
00285 {
00286 REFERENCE_TIME trStart, trStopAt;
00287 HRESULT hr = pIn->GetTime(&trStart, &trStopAt);
00288
00289
00290 if (hr != S_OK)
00291 return FALSE;
00292
00293 int itrFrame = (int)(trStopAt - trStart);
00294
00295 if(S_OK==pIn->IsSyncPoint()) {
00296 MSR_INTEGER(m_idFrameType, 1);
00297 if ( m_nKeyFramePeriod < m_nFramesSinceKeyFrame ) {
00298
00299 m_nKeyFramePeriod = m_nFramesSinceKeyFrame;
00300 }
00301 m_nFramesSinceKeyFrame = 0;
00302 m_bSkipping = FALSE;
00303 } else {
00304 MSR_INTEGER(m_idFrameType, 2);
00305 if ( m_nFramesSinceKeyFrame>m_nKeyFramePeriod
00306 && m_nKeyFramePeriod>0
00307 ) {
00308
00309
00310 m_nKeyFramePeriod = m_nFramesSinceKeyFrame;
00311 }
00312 }
00313
00314
00315
00316
00317
00318
00319 if (m_itrAvgDecode*4>itrFrame) {
00320
00321
00322
00323 if ( m_itrLate > itrFrame ) {
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 if (m_nKeyFramePeriod>0) {
00339
00340
00341
00342
00343 int it = (itrFrame/10000)
00344 * (m_nKeyFramePeriod-m_nFramesSinceKeyFrame - 1);
00345 MSR_INTEGER(m_idTimeTillKey, it);
00346
00347
00348 #ifdef VTRANSPERF
00349 MSR_INTEGER(0, itrFrame);
00350 MSR_INTEGER(0, m_nFramesSinceKeyFrame);
00351 MSR_INTEGER(0, m_nKeyFramePeriod);
00352 #endif
00353 if (m_itrLate/10000 > it) {
00354 m_bSkipping = TRUE;
00355
00356
00357 } else {
00358 #ifdef VTRANSPERF
00359 MSR_INTEGER(0, 777770);
00360 #endif
00361 }
00362 } else {
00363 #ifdef VTRANSPERF
00364 MSR_INTEGER(0, 777771);
00365 #endif
00366 }
00367 } else {
00368 #ifdef VTRANSPERF
00369 MSR_INTEGER(0, 777772);
00370 MSR_INTEGER(0, m_itrLate);
00371 MSR_INTEGER(0, itrFrame);
00372 #endif
00373 }
00374 } else {
00375 #ifdef VTRANSPERF
00376 MSR_INTEGER(0, 777773);
00377 MSR_INTEGER(0, m_itrAvgDecode);
00378 MSR_INTEGER(0, itrFrame);
00379 #endif
00380 }
00381
00382 ++m_nFramesSinceKeyFrame;
00383
00384 if (m_bSkipping) {
00385
00386
00387
00388
00389
00390
00391
00392 m_itrLate = m_itrLate - itrFrame;
00393 }
00394
00395 MSR_INTEGER(m_idLate, (int)m_itrLate/10000 );
00396 if (m_bSkipping) {
00397 if (!m_bQualityChanged) {
00398 m_bQualityChanged = TRUE;
00399 NotifyEvent(EC_QUALITY_CHANGE,0,0);
00400 }
00401 }
00402 return m_bSkipping;
00403 }
00404
00405 HRESULT CVideoTransformFilter::AlterQuality(Quality q)
00406 {
00407
00408
00409 if (m_itrLate>300000000) {
00410
00411 m_itrLate = 300000000;
00412 } else {
00413 m_itrLate = (int)q.Late;
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 return E_FAIL;
00425
00426 }
00427
00428 #pragma warning(disable:4514)
00429