📄 t2ps.cpp
字号:
//------------------------------------------------------------------------------
// File: t2ps.cpp
//
// Desc: DirectShow code - implementation of a transport stream to transform
// to program stream .
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
//
#include <windows.h>
#include <commdlg.h>
#include <streams.h>
#include <initguid.h>
#include "t2psuids.h"
#include "t2ps.h"
// Setup data
const AMOVIESETUP_MEDIATYPE sudPinTypes =
{
&MEDIATYPE_NULL, // Major type
&MEDIASUBTYPE_NULL // Minor type
};
const AMOVIESETUP_PIN sudPins =
{
L"Input", // Pin string name
FALSE, // Is it rendered
FALSE, // Is it an output
FALSE, // Allowed none
FALSE, // Likewise many
&CLSID_NULL, // Connects to filter
L"Output", // Connects to pin
1, // Number of types
&sudPinTypes // Pin information
};
const AMOVIESETUP_FILTER sudT2ps =
{
&CLSID_T2ps, // Filter CLSID
L"t2ps", // String name
MERIT_DO_NOT_USE, // Filter merit
1, // Number pins
&sudPins // Pin details
};
//
// Object creation stuff
//
CFactoryTemplate g_Templates[]= {
L"T2ps", &CLSID_T2ps, CT2ps::CreateInstance, NULL, &sudT2ps
};
int g_cTemplates = 1;
// Constructor
CT2psFilter::CT2psFilter(CT2ps *pT2ps,
LPUNKNOWN pUnk,
CCritSec *pLock,
HRESULT *phr) :
CBaseFilter(NAME("CT2psFilter"), pUnk, pLock, CLSID_T2ps),
m_pT2ps(pT2ps)
{
}
//
// GetPin
//
CBasePin * CT2psFilter::GetPin(int n)
{
if (n == 0) {
return m_pT2ps->m_pPin;
} else {
return NULL;
}
}
//
// GetPinCount
//
int CT2psFilter::GetPinCount()
{
return 1;
}
//
// Stop
//
// Overriden to close the T2ps file
//
STDMETHODIMP CT2psFilter::Stop()
{
CAutoLock cObjectLock(m_pLock);
if (m_pT2ps)
m_pT2ps->CloseFile();
return CBaseFilter::Stop();
}
//
// Pause
//
// Overriden to open the T2ps file
//
STDMETHODIMP CT2psFilter::Pause()
{
CAutoLock cObjectLock(m_pLock);
if (m_pT2ps)
{
// GraphEdit calls Pause() before calling Stop() for this filter.
// If we have encountered a write error (such as disk full),
// then stopping the graph could cause our log to be deleted
// (because the current log file handle would be invalid).
//
// To preserve the log, don't open/create the log file on pause
// if we have previously encountered an error. The write error
// flag gets cleared when setting a new log file name or
// when restarting the graph with Run().
if (!m_pT2ps->m_fWriteError)
{
m_pT2ps->OpenFile();
}
}
return CBaseFilter::Pause();
}
//
// Run
//
// Overriden to open the T2ps file
//
STDMETHODIMP CT2psFilter::Run(REFERENCE_TIME tStart)
{
CAutoLock cObjectLock(m_pLock);
// Clear the global 'write error' flag that would be set
// if we had encountered a problem writing the previous T2ps file.
// (eg. running out of disk space).
//
// Since we are restarting the graph, a new file will be created.
m_pT2ps->m_fWriteError = FALSE;
if (m_pT2ps)
m_pT2ps->OpenFile();
return CBaseFilter::Run(tStart);
}
//
// Definition of CT2psInputPin
//
CT2psInputPin::CT2psInputPin(CT2ps *pT2ps,
LPUNKNOWN pUnk,
CBaseFilter *pFilter,
CCritSec *pLock,
CCritSec *pReceiveLock,
HRESULT *phr) :
CRenderedInputPin(NAME("CT2psInputPin"),
pFilter, // Filter
pLock, // Locking
phr, // Return code
L"Input"), // Pin name
m_pReceiveLock(pReceiveLock),
m_pT2ps(pT2ps),
m_tLast(0)
{
}
//
// CheckMediaType
//
// Check if the pin can support this specific proposed type and format
//
HRESULT CT2psInputPin::CheckMediaType(const CMediaType *)
{
return S_OK;
}
//
// BreakConnect
//
// Break a connection
//
HRESULT CT2psInputPin::BreakConnect()
{
if (m_pT2ps->m_pPosition != NULL) {
m_pT2ps->m_pPosition->ForceRefresh();
}
return CRenderedInputPin::BreakConnect();
}
//
// ReceiveCanBlock
//
// We don't hold up source threads on Receive
//
STDMETHODIMP CT2psInputPin::ReceiveCanBlock()
{
return S_FALSE;
}
//
// Receive
//
// Do something with this media sample
//
STDMETHODIMP CT2psInputPin::Receive(IMediaSample *pSample)
{
CheckPointer(pSample,E_POINTER);
CAutoLock lock(m_pReceiveLock);
PBYTE pbData;
// Has the filter been stopped yet?
if (m_pT2ps->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;
}
return m_pT2ps->Write(pbData, pSample->GetActualDataLength());
}
//
// WriteStringInfo
//
// Write to the file as text form
//
HRESULT CT2psInputPin::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
wsprintf(FileString,TEXT("\r\nRenderer received sample (%dms)\0"),timeGetTime());
m_pT2ps->WriteString(FileString);
wsprintf(FileString,TEXT(" Start time (%s)\0"),CDisp(tStart));
m_pT2ps->WriteString(FileString);
wsprintf(FileString,TEXT(" End time (%s)\0"),CDisp(tStop));
m_pT2ps->WriteString(FileString);
// Display the media times for this sample
HRESULT hr = pSample->GetMediaTime(&tStart, &tStop);
if (hr == NOERROR)
{
wsprintf(FileString,TEXT(" Start media time (%s)\0"),CDisp(tStart));
m_pT2ps->WriteString(FileString);
wsprintf(FileString,TEXT(" End media time (%s)\0"),CDisp(tStop));
m_pT2ps->WriteString(FileString);
}
// Is this a sync point sample
hr = pSample->IsSyncPoint();
wsprintf(FileString,TEXT(" Sync point (%d)\0"),(hr == S_OK));
m_pT2ps->WriteString(FileString);
// Is this a preroll sample
hr = pSample->IsPreroll();
wsprintf(FileString,TEXT(" Preroll (%d)\0"),(hr == S_OK));
m_pT2ps->WriteString(FileString);
// Is this a discontinuity sample
hr = pSample->IsDiscontinuity();
wsprintf(FileString,TEXT(" Discontinuity (%d)\0"),(hr == S_OK));
m_pT2ps->WriteString(FileString);
// Write the actual data length
LONG DataLength = pSample->GetActualDataLength();
wsprintf(FileString,TEXT(" Actual data length (%d)\0"),DataLength);
m_pT2ps->WriteString(FileString);
// Does the sample have a type change aboard
AM_MEDIA_TYPE *pMediaType;
pSample->GetMediaType(&pMediaType);
wsprintf(FileString,TEXT(" Type changed (%d)\0"),
(pMediaType ? TRUE : FALSE));
m_pT2ps->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++)
{
wsprintf(FileString, FIRST_HALF_LINE,
pbData[0],pbData[1],pbData[2],
pbData[3],pbData[4],pbData[5],pbData[6],
pbData[7],pbData[8],pbData[9]);
wsprintf(TempString, SECOND_HALF_LINE,
pbData[10],pbData[11],pbData[12],
pbData[13],pbData[14],pbData[15],pbData[16],
pbData[17],pbData[18],pbData[19]);
lstrcat(FileString,TempString);
m_pT2ps->WriteString(FileString);
pbData += BYTES_PER_LINE;
}
// Write the last few bytes out afterwards
wsprintf(FileString,TEXT(" \0"));
for (Loop = 0;Loop < (DataLength % BYTES_PER_LINE);Loop++)
{
wsprintf(TempString,TEXT("%x \0"),pbData[Loop]);
lstrcat(FileString,TempString);
}
m_pT2ps->WriteString(FileString);
return NOERROR;
}
//
// EndOfStream
//
STDMETHODIMP CT2psInputPin::EndOfStream(void)
{
CAutoLock lock(m_pReceiveLock);
return CRenderedInputPin::EndOfStream();
} // EndOfStream
//
// NewSegment
//
// Called when we are seeked
//
STDMETHODIMP CT2psInputPin::NewSegment(REFERENCE_TIME tStart,
REFERENCE_TIME tStop,
double dRate)
{
m_tLast = 0;
return S_OK;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -