⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 t2ps.cpp

📁 主要完成了视频PS流的分析过程
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//------------------------------------------------------------------------------
// 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 + -