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

📄 reader.cpp

📁 介绍IStream接口的代码,方便学习,很有参考价值
💻 CPP
字号:
//*****************************************************************************
//
// Microsoft Windows Media
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// FileName:            Reader.cpp
//
// Abstract:            Implementation of class CReader, which provides the
//                      functionality of reading from an IStream.
//
//*****************************************************************************

#include "stdafx.h"
#include "Reader.h"
#include "ROStream.h"
//------------------------------------------------------------------------------
// Name: CReader()
// Desc: Constructor.
//------------------------------------------------------------------------------
CReader::CReader()
{
    m_cRef      = 1;
    m_pReader   = NULL;
    m_pReader2  = NULL;
    m_hEvent    = INVALID_HANDLE_VALUE;
    m_pStream   = NULL;
    m_hrAsync   = S_OK;
}

//------------------------------------------------------------------------------
// Name: ~CReader()
// Desc: Destructor.
//------------------------------------------------------------------------------
CReader::~CReader()
{

    SAFE_RELEASE( m_pReader );
    SAFE_RELEASE( m_pReader2 );
    SAFE_RELEASE( m_pStream );

    if( NULL != m_hEvent )
    {
        CloseHandle( m_hEvent );
        m_hEvent = INVALID_HANDLE_VALUE;
    }
}

//------------------------------------------------------------------------------
// Implementation of IUnknown methods
//------------------------------------------------------------------------------
HRESULT STDMETHODCALLTYPE CReader::QueryInterface( /* [in] */ REFIID riid,
                                                   /* [out] */ void __RPC_FAR *__RPC_FAR *ppvObject ) 
{
    if( ( IID_IWMReaderCallback == riid ) ||
        ( IID_IUnknown == riid ) )
    {
        *ppvObject = static_cast< IWMReaderCallback* >( this );
        AddRef();
        return( S_OK );
    }

    *ppvObject = NULL;
    return( E_NOINTERFACE );
}

ULONG STDMETHODCALLTYPE CReader::AddRef()
{
    return( InterlockedIncrement( &m_cRef ) );
}

ULONG STDMETHODCALLTYPE CReader::Release()
{
    if( 0 == InterlockedDecrement( &m_cRef ) )
    {
        delete this;
        return( 0 );
    }

    return( m_cRef );
}

//------------------------------------------------------------------------------
// Name: CReader::OnSample()
// Desc: Implementation of IWMReaderCallback::OnSample.
//------------------------------------------------------------------------------
HRESULT CReader::OnSample( /* [in] */ DWORD dwOutputNum,
                           /* [in] */ QWORD cnsSampleTime,
                           /* [in] */ QWORD cnsSampleDuration,
                           /* [in] */ DWORD dwFlags,
                           /* [in] */ INSSBuffer __RPC_FAR *pSample,
                           /* [in] */ void __RPC_FAR *pvContext )
{
    //
    // Add your code here
    //
    return( S_OK );
}

//------------------------------------------------------------------------------
// Name: CReader::OnStatus()
// Desc: Implementation of IWMStatusCallback::OnStatus.
//------------------------------------------------------------------------------
HRESULT CReader::OnStatus( /* [in] */ WMT_STATUS Status,
                           /* [in] */ HRESULT hr,
                           /* [in] */ WMT_ATTR_DATATYPE dwType,
                           /* [in] */ BYTE __RPC_FAR *pValue,
                           /* [in] */ void __RPC_FAR *pvContext )
{
    switch( Status )
    {
    case WMT_OPENED:
        m_hrAsync = hr;
        SetEvent( m_hEvent );        
        printf( "Opened the file ...\n" );
        break;

    case WMT_STARTED:
        m_hrAsync = hr;
        SetEvent( m_hEvent );        
        printf( "Started ...\n" );
        break;

    case WMT_STOPPED:
        m_hrAsync = hr;
        SetEvent( m_hEvent );        
        printf( "Stopped ...\n" );
        break;

    case WMT_CLOSED:
        m_hrAsync = hr;
        SetEvent( m_hEvent );
        printf( "Closed the file ...\n" );
        break;
 
    case WMT_EOF:
        m_hrAsync = hr;
        SetEvent( m_hEvent );
        printf( "End of file ...\n" );
        break;
    }

    return( S_OK );
}

//------------------------------------------------------------------------------
// Name: CReader::Open()
// Desc: Creates the reader and opens the file.
//------------------------------------------------------------------------------
HRESULT CReader::Open( /* [in] */ const TCHAR *ptszFile )
{
    HRESULT hr = S_OK;

    do
    {
        m_hrAsync = S_OK;

		if( NULL == m_pStream )
        {
            m_pStream = new CROStream;
	        if( NULL == m_pStream )
	        {
                hr = E_OUTOFMEMORY;
                break;
	        }
        }

        //
        // Open input file
        //
        hr = m_pStream->Open( ptszFile );
        if( FAILED( hr ) )
        {
            break;
        }

        //
        // Create the event handle as automatic reset; initial state is not set.
        //
        if( INVALID_HANDLE_VALUE == m_hEvent )
        {
            m_hEvent = CreateEvent( NULL, FALSE, FALSE, NULL );
            if( NULL == m_hEvent )
            {
                hr = HRESULT_FROM_WIN32( GetLastError() );
                printf( "Could not Create Event. (hr=%#X)\n", hr );
                break;
            }
        }

        ResetEvent( m_hEvent );

        //
        // Create reader object
        //
        SAFE_RELEASE( m_pReader );
        SAFE_RELEASE( m_pReader2 );

        hr = WMCreateReader( NULL, WMT_RIGHT_PLAYBACK, &m_pReader );
        if( FAILED( hr ) )
        {
            printf( "Could not create reader (hr=%#X).\n", hr );
            break;
        }

        //
        // QI for IWMReaderAdvanced2 
        //
        hr = m_pReader->QueryInterface( IID_IWMReaderAdvanced2, ( void** )&m_pReader2 );
        if( FAILED( hr ) )
        {
            printf( "Could not QI for IWMReaderAdvanced2 (hr=%#X).\n", hr );
            break;
        }

        //
        // Open the stream
        //
        hr = m_pReader2->OpenStream( m_pStream, this, NULL );
        if( FAILED( hr ) )
        {
            printf( "Could not open reader from stream (hr=%#X).\n", hr );
            break;
        }
    
        //
        // Wait for the open to finish
        //
        hr = WaitForEvent();
        if( FAILED( hr ) )
        {
            printf( "Stream open failed (hr=%#X).\n", hr );
            break;
        }

        //
        // Check open operation result
        //
        if( FAILED( m_hrAsync ) )
        {
            hr = m_hrAsync;
            printf( "Open failed (hr=%#X).\n", m_hrAsync );
            break;
        }
    }
    while( FALSE );

    return( hr );
}

//------------------------------------------------------------------------------
// Name: CReader::Start()
// Desc: Plays the file.
//------------------------------------------------------------------------------
HRESULT CReader::Start()
{
    HRESULT hr = S_OK;

    if( NULL == m_pReader )
    {
        return( E_UNEXPECTED );
    }

    //
    // Start the reader to play the stream normally
    //
    m_hrAsync = S_OK;

    hr = m_pReader->Start( 0, 0, 1.0, NULL );
    if( FAILED( hr ) )
    {
        printf( "Could not start IWMReader (hr=%#X).\n", hr );
        return( hr );
    }

    printf( "Playing......\n" );

    //
    // Wait until all data has been sent to output.
    // We don't know the file's duration, so simply wait forever and hope for the best.
    // In a real application, you might want to query for the file's duration.
    //
    hr = WaitForEvent( INFINITE );
    if( FAILED( hr ) )
    {
        printf( "Read operation failed (hr=%#X).\n", hr );
        return( hr );
    }

    //
    // Check playback results
    //
    if( FAILED( m_hrAsync ) )
    {
        printf( "IWMReader playback failed (hr=%#X).\n", m_hrAsync );
        return( hr );
    }

    printf( "Playback finished.\n" );

    return( S_OK );
}

//------------------------------------------------------------------------------
// Name: CReader::Close()
// Desc: Closes the reader.
//------------------------------------------------------------------------------
HRESULT CReader::Close()
{
    HRESULT hr = S_OK;

    if( NULL == m_pReader )
    {
        return( S_FALSE );
    }

    hr = m_pReader->Close();
    if( FAILED ( hr ) )
    {
        printf( "Could not close Reader (hr=%#X).\n", hr );
        return hr;
    }

    hr = WaitForEvent();
    if( FAILED( hr ) )
    {
        printf( "Close operation failed (hr=%#X).\n", hr );
        return( hr );
    }

    return( hr );
}

//------------------------------------------------------------------------------
// Name: CReader::WaitForEvent()
// Desc: Waits for the event to be signaled.
//------------------------------------------------------------------------------
HRESULT CReader::WaitForEvent( /* [in] */ DWORD msWait )
{
    DWORD   dwRet = 0;
    DWORD   dwLastError = 0;
    HRESULT hr = S_OK;

    dwRet = WaitForSingleObject( m_hEvent, msWait );
    if( WAIT_OBJECT_0 == dwRet )
    {
        return( S_OK );
    }

    if( WAIT_TIMEOUT == dwRet )
    {
        printf( "Time out waiting for the event.\n" );
        return( HRESULT_FROM_WIN32( WAIT_TIMEOUT ) );
    }

    if( WAIT_FAILED == dwRet )
    {
        dwLastError = GetLastError();
        printf( "WaitForSingleObject() failed (LastError=%ld).\n", dwLastError );
        return( HRESULT_FROM_WIN32( dwLastError ) );
    }

    return( S_OK );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -