// // CFilePlayer::IsOvMConnected(): Private method to detect if the video stream // is passing through the Overlay Mixer (i.e, is it connected?). // BOOL CFilePlayer::IsOvMConnected(IBaseFilter *pOvM) { DbgLog((LOG_TRACE, 5, TEXT("CFilePlayer::IsOvMConnected() entered"))) ; IEnumPins *pEnumPins ; IPin *pPin ; IPin *pPin2 ; ULONG ul ; HRESULT hr ; BOOL bConnected = FALSE ; pOvM->EnumPins(&pEnumPins) ; while (S_OK == pEnumPins->Next(1, &pPin, &ul) && 1 == ul) { hr = pPin->ConnectedTo(&pPin2) ; if (SUCCEEDED(hr) && pPin2) { DbgLog((LOG_TRACE, 3, TEXT("Found pin %s connected to pin %s"), (LPCTSTR)CDisp(pPin), (LPCTSTR)CDisp(pPin2))) ; bConnected = TRUE ; pPin2->Release() ; } pPin->Release() ; } pEnumPins->Release() ; return bConnected ; }
// // Receive // // Do something with this media sample // STDMETHODIMP CDumpInputPin::Receive(IMediaSample *pSample) { CheckPointer(pSample,E_POINTER); CAutoLock lock(m_pReceiveLock); PBYTE pbData; // Has the filter been stopped yet? if (m_pDump->m_hFile == INVALID_HANDLE_VALUE) { return NOERROR; } REFERENCE_TIME tStart, tStop; pSample->GetTime(&tStart, &tStop); DbgLog((LOG_TRACE, 1, TEXT("tStart(%s), tStop(%s), Diff(%d ms), Bytes(%d)"), (LPCTSTR) CDisp(tStart), (LPCTSTR) CDisp(tStop), (LONG)((tStart - m_tLast) / 10000), pSample->GetActualDataLength())); m_tLast = tStart; // Copy the data to the file HRESULT hr = pSample->GetPointer(&pbData); if (FAILED(hr)) { return hr; } WriteStringInfo(pSample); }
/*****************************Private*Routine******************************\ * FormatRefTime * * Formats the given RefTime into the passed in character buffer, * returns a pointer to the character buffer. * \**************************************************************************/ TCHAR * FormatRefTime( TCHAR *sz, REFTIME rt, size_t len ) { // If we are not seeking in time then format differently HRESULT hr; if(pMovie && pMovie->GetTimeFormat() != TIME_FORMAT_MEDIA_TIME) { hr = StringCchPrintf(sz,len, TEXT("%s\0"),(LPCTSTR) CDisp((LONGLONG) rt,CDISP_DEC)); return sz; } int hrs, mins, secs; rt += 0.49; hrs = (int)rt / 3600; mins = ((int)rt % 3600) / 60; secs = ((int)rt % 3600) % 60; hr = StringCchPrintf(sz,len, TEXT("%02d:%02d:%02d h:m:s\0"),hrs, mins, secs); return sz; }
// // CFilePlayer::PutVideoThroughOvM(): Private method to connect the decoded video // stream through the OverlayMixer. // HRESULT CFilePlayer::PutVideoThroughOvM(IBaseFilter *pOvM, IBaseFilter *pVR) { DbgLog((LOG_TRACE, 5, TEXT("CFilePlayer::PutVideoThroughOvM() entered"))) ; IEnumPins *pEnumPins ; IPin *pPinVR ; IPin *pPinConnectedTo ; IPin *pPinOvM ; ULONG ul ; PIN_DIRECTION pd ; HRESULT hr ; // Get the video renderer's (only) in pin hr = pVR->EnumPins(&pEnumPins) ; ASSERT(SUCCEEDED(hr)) ; hr = pEnumPins->Next(1, &pPinVR, &ul) ; ASSERT(S_OK == hr && 1 == ul) ; pPinVR->QueryDirection(&pd) ; ASSERT(PINDIR_INPUT == pd) ; pEnumPins->Release() ; // Disconnect VR from upstream filter and put OvMixer in between them hr = pPinVR->ConnectedTo(&pPinConnectedTo) ; ASSERT(SUCCEEDED(hr) && pPinConnectedTo) ; hr = m_pGraph->Disconnect(pPinVR) ; ASSERT(SUCCEEDED(hr)) ; hr = m_pGraph->Disconnect(pPinConnectedTo) ; ASSERT(SUCCEEDED(hr)) ; // Now connect the upstream filter's out pin to OvM's in pin // (and remove Video Renderer from the graph). hr = pOvM->EnumPins(&pEnumPins) ; ASSERT(SUCCEEDED(hr)) ; int iInConns = 0 ; while (iInConns == 0 && // input pin not connected yet S_OK == pEnumPins->Next(1, &pPinOvM, &ul) && 1 == ul) // pin left to try { pPinOvM->QueryDirection(&pd) ; if (PINDIR_INPUT == pd) // OvM's in pin <- Upstream filter's pin { if (0 == iInConns) // We want to connect only one input pin { hr = m_pGraph->Connect(pPinConnectedTo, pPinOvM) ; // , NULL) ; // direct?? ASSERT(SUCCEEDED(hr)) ; if (FAILED(hr)) DbgLog((LOG_ERROR, 0, TEXT("ERROR: m_pGraph->Connect() failed (Error 0x%lx)"), hr)) ; else { DbgLog((LOG_TRACE, 5, TEXT("Pin %s connected to pin %s"), (LPCTSTR) CDisp(pPinConnectedTo), (LPCTSTR) CDisp(pPinOvM))) ; iInConns++ ; } } // else ignore } else DbgLog((LOG_ERROR, 1, TEXT("OVMixer still has an out pin!!!"))) ; pPinOvM->Release() ; } pEnumPins->Release() ; pPinConnectedTo->Release() ; // done with upstream pin pPinVR->Release() ; // done with VR pin m_pGraph->RemoveFilter(pVR) ; // by force remove the VR from graph // Just to check... if (0 == iInConns) // input pin not connected!! { DbgLog((LOG_ERROR, 0, TEXT("WARNING: Couldn't connect any out pin to OvMixer's 1st in pin"))) ; return E_FAIL ; // failure } return S_OK ; // success!! }
// // WriteStringInfo // // Write to the file as text form // HRESULT CDumpInputPin::WriteStringInfo(IMediaSample *pSample) { CheckPointer(pSample,E_POINTER); TCHAR TempString[256],FileString[256]; PBYTE pbData; // Retrieve the time stamps from this sample REFERENCE_TIME tStart, tStop; pSample->GetTime(&tStart, &tStop); m_tLast = tStart; // Write the sample time stamps out HRESULT hr = StringCchPrintf(FileString,256,TEXT("\r\nRenderer received sample (%dms)\0"),timeGetTime()); m_pDump->WriteString(FileString); hr = StringCchPrintf(FileString,256,TEXT(" Start time (%s)\0"),(LPCTSTR)CDisp(tStart, CDISP_DEC)); m_pDump->WriteString(FileString); hr = StringCchPrintf(FileString,256,TEXT(" End time (%s)\0"),(LPCTSTR)CDisp(tStop, CDISP_DEC)); m_pDump->WriteString(FileString); // Display the media times for this sample hr = pSample->GetMediaTime(&tStart, &tStop); if (hr == NOERROR) { hr = StringCchPrintf(FileString,256,TEXT(" Start media time (%s)\0"),(LPCTSTR)CDisp(tStart, CDISP_DEC)); m_pDump->WriteString(FileString); hr = StringCchPrintf(FileString,256,TEXT(" End media time (%s)\0"),(LPCTSTR)CDisp(tStop, CDISP_DEC)); m_pDump->WriteString(FileString); } // Is this a sync point sample hr = pSample->IsSyncPoint(); hr = StringCchPrintf(FileString,256,TEXT(" Sync point (%d)\0"),(hr == S_OK)); m_pDump->WriteString(FileString); // Is this a preroll sample hr = pSample->IsPreroll(); hr = StringCchPrintf(FileString,256,TEXT(" Preroll (%d)\0"),(hr == S_OK)); m_pDump->WriteString(FileString); // Is this a discontinuity sample hr = pSample->IsDiscontinuity(); hr = StringCchPrintf(FileString,256,TEXT(" Discontinuity (%d)\0"),(hr == S_OK)); m_pDump->WriteString(FileString); // Write the actual data length LONG DataLength = pSample->GetActualDataLength(); hr = StringCchPrintf(FileString,256,TEXT(" Actual data length (%d)\0"),DataLength); m_pDump->WriteString(FileString); // Does the sample have a type change aboard AM_MEDIA_TYPE *pMediaType; pSample->GetMediaType(&pMediaType); hr = StringCchPrintf(FileString,256,TEXT(" Type changed (%d)\0"), (pMediaType ? TRUE : FALSE)); m_pDump->WriteString(FileString); DeleteMediaType(pMediaType); // Copy the data to the file hr = pSample->GetPointer(&pbData); if (FAILED(hr)) { return hr; } // Write each complete line out in BYTES_PER_LINES groups for (int Loop = 0;Loop < (DataLength / BYTES_PER_LINE);Loop++) { hr = StringCchPrintf(FileString,256,FIRST_HALF_LINE, pbData[0],pbData[1],pbData[2], pbData[3],pbData[4],pbData[5],pbData[6], pbData[7],pbData[8],pbData[9]); hr = StringCchPrintf(TempString,256, SECOND_HALF_LINE, pbData[10],pbData[11],pbData[12], pbData[13],pbData[14],pbData[15],pbData[16], pbData[17],pbData[18],pbData[19]); hr = StringCchCat(FileString,256,TempString); m_pDump->WriteString(FileString); pbData += BYTES_PER_LINE; } // Write the last few bytes out afterwards hr = StringCchPrintf(FileString,256,TEXT(" \0")); for (int Loop = 0;Loop < (DataLength % BYTES_PER_LINE);Loop++) { hr = StringCchPrintf(FileString,256,TEXT("%x \0"),pbData[Loop]); hr = StringCchCat(FileString,256,TempString); } m_pDump->WriteString(FileString); return NOERROR; }