home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Game Programming for Teens / VBGPFT.cdr / DirectX8 / dx8a_sdk.exe / samples / multimedia / directshow / dmo / dmodemo / appstream.cpp next >
Encoding:
C/C++ Source or Header  |  2000-10-02  |  9.8 KB  |  316 lines

  1. //------------------------------------------------------------------------------
  2. // File: AppStream.cpp
  3. //
  4. // Desc: DirectShow sample code - implementation of CAppStream class.
  5. //
  6. // Copyright (c) 2000, Microsoft Corporation.  All rights reserved.
  7. //------------------------------------------------------------------------------
  8.  
  9.  
  10. #include <windows.h>
  11. #include <malloc.h>
  12. #include <mediaobj.h>
  13. #include <mmsystem.h>
  14.  
  15. #include "uuids.h"
  16. #include "dmo.h"
  17. #include "wave.h"
  18. #include "appstream.h"
  19. #include "dxutil.h"     //to use free memory macro
  20.  
  21. //
  22. // CAppStream - reads data from a WAV file, transforms it using a DMO and then 
  23. //              copies the results into an output buffer.  
  24. //
  25. //-----------------------------------------------------------------------------
  26. // Name: CAppStream::CAppStream()
  27. // Desc: Constructor
  28. //-----------------------------------------------------------------------------
  29. CAppStream::CAppStream(): 
  30.     m_pObject(NULL),
  31.     m_pObjectInPlace(NULL),
  32.     m_pbInData(NULL),
  33.     m_pwfx(NULL),
  34.     m_uDataSize(0)
  35. {
  36.     ZeroMemory(&m_mt, sizeof(m_mt));
  37. }
  38.  
  39. //-----------------------------------------------------------------------------
  40. // Name: CAppStream::~CAppStream()
  41. // Desc: Destructor
  42. //-----------------------------------------------------------------------------
  43. CAppStream::~CAppStream() 
  44. {
  45.  
  46.     SAFE_RELEASE( m_pObject);
  47.     SAFE_RELEASE( m_pObjectInPlace);
  48.     SafeGlobalFree(m_pbInData);
  49.  
  50. }
  51.  
  52. //-----------------------------------------------------------------------------
  53. // Name: CAppStream::StreamData()
  54. // Desc: Load data from input file, create media object and set input&output type
  55. //-----------------------------------------------------------------------------
  56.  
  57. HRESULT CAppStream::StreamData( LPTSTR lpszInputFile, 
  58.                                 REFGUID rclsid, 
  59.                                 HWND hDlg,
  60.                                 BYTE **ppbOutData, 
  61.                                 ULONG *pbDataSize, 
  62.                                 LPWAVEFORMATEX  *ppwfx )
  63.  
  64. {
  65.     HRESULT hr;
  66.     hr = Init( lpszInputFile, rclsid, hDlg );
  67.     if ( FAILED( hr ) ) {
  68.        return hr;
  69.     }
  70.  
  71.     hr = Stream( ppbOutData, pbDataSize, ppwfx );
  72.     if ( FAILED( hr )) {
  73.         MessageBox( hDlg, TEXT("Streaming data failed."), TEXT(DEMO_NAME), 
  74.                                     MB_OK | MB_ICONERROR );
  75.         return hr;
  76.     } 
  77.     return S_OK;
  78. }
  79.  
  80.  
  81. //-----------------------------------------------------------------------------
  82. // Name: CAppStream::Init()
  83. // Desc: Load data from input file, create media object and set input&output type
  84. //-----------------------------------------------------------------------------
  85.  
  86. HRESULT CAppStream::Init(LPTSTR lpszInputFile, REFGUID rclsid, HWND hDlg) 
  87. {
  88.  
  89.     // create DMO
  90.     HRESULT hr = CoCreateInstance(rclsid,
  91.                          NULL,
  92.                          CLSCTX_INPROC,
  93.                          IID_IMediaObject,
  94.                          (void **) &m_pObject);
  95.     if ( FAILED( hr ) ){
  96.         MessageBox( hDlg, TEXT("Can't create this DMO."), TEXT(DEMO_NAME),MB_OK|MB_ICONERROR );
  97.         return hr;
  98.     }
  99.  
  100.     hr = m_pObject->QueryInterface(IID_IMediaObjectInPlace, (void**)&m_pObjectInPlace);
  101.     
  102.     // read wave file
  103.     if( WaveLoadFile( lpszInputFile, (UINT*) &m_uDataSize, &m_pwfx, &m_pbInData ) != 0 ){
  104.         MessageBox( hDlg, TEXT("Can't load input file."), TEXT(DEMO_NAME),MB_OK|MB_ICONERROR );
  105.         return E_FAIL;
  106.     }
  107.  
  108.  
  109.     if( m_pwfx->wFormatTag != WAVE_FORMAT_PCM ) {
  110.         MessageBox( hDlg, TEXT("Can't process compressed data."), TEXT(DEMO_NAME),MB_OK|MB_ICONERROR );
  111.         return E_FAIL;
  112.         
  113.     }
  114.  
  115.     m_mt.majortype  = MEDIATYPE_Audio;
  116.     m_mt.subtype    = MEDIASUBTYPE_PCM;
  117.     m_mt.formattype = FORMAT_WaveFormatEx;
  118.     m_mt.cbFormat = sizeof(WAVEFORMATEX);
  119.     m_mt.pbFormat = (BYTE*) (m_pwfx);
  120.     m_mt.pUnk = NULL;       // CopyMediaType will crash if we don't intialize this
  121.    
  122.     hr = m_pObject->SetInputType( 0,    //Input Stream index
  123.                                   &m_mt, 
  124.                                   0 );  // No flags specified
  125.     if ( FAILED( hr ) ){
  126.         MessageBox( hDlg, TEXT("Can't set input type."), TEXT(DEMO_NAME),MB_OK | MB_ICONERROR );
  127.         return hr;
  128.     }
  129.  
  130.     hr = m_pObject->SetOutputType( 0,       // Output Stream Index
  131.                                    &m_mt, 
  132.                                    0);  // No flags specified
  133.     if ( FAILED( hr ) ){
  134.        MessageBox( hDlg, TEXT("Can't set output type."), TEXT(DEMO_NAME),MB_OK | MB_ICONERROR );
  135.        return hr;
  136.     }
  137.  
  138.     return S_OK;
  139. }
  140.  
  141.  
  142. //-----------------------------------------------------------------------------
  143. // Name: CAppStream::Stream()
  144. // Desc: called to get the output from DMO
  145. //-----------------------------------------------------------------------------
  146.  
  147. HRESULT CAppStream::Stream( BYTE **ppbOutData, ULONG *pbDataSize, LPWAVEFORMATEX *ppwfx )
  148. {
  149.     HRESULT         hr = S_OK;
  150.     BYTE            *pOut;
  151.  
  152.     *pbDataSize     = m_uDataSize;
  153.     *ppwfx          = m_pwfx;
  154.  
  155.     if ( m_pObjectInPlace ){
  156.  
  157.         pOut = new BYTE [m_uDataSize];
  158.  
  159.         if( pOut == 0 ){
  160.             return E_OUTOFMEMORY;
  161.         }
  162.         CopyMemory(pOut, m_pbInData, m_uDataSize);
  163.  
  164.         // pass the number of samples to Process()
  165.         hr = m_pObjectInPlace->Process( m_uDataSize, 
  166.                                         pOut, 
  167.                                         0, 
  168.                                         DMO_INPLACE_NORMAL);
  169.         if( FAILED( hr ) ){
  170.             return hr;
  171.         }       
  172.         *ppbOutData = pOut; 
  173.         SAFE_RELEASE( m_pObjectInPlace );
  174.     }
  175.  
  176.     else
  177.     {
  178.         CMediaBuffer            *pInputBuffer;
  179.         const REFERENCE_TIME    rtStart     = 0;
  180.         const REFERENCE_TIME    rtStop      = 0;
  181.         BYTE*                   pBuffer;
  182.         DWORD                   dwLength;
  183.  
  184.         // create and fill CMediaBuffer
  185.         hr = CreateBuffer(m_uDataSize, &pInputBuffer);
  186.         if( FAILED( hr ) ){
  187.             return hr;
  188.         }
  189.         hr = pInputBuffer->GetBufferAndLength( &pBuffer, &dwLength );
  190.         if( FAILED( hr ) ){
  191.             return hr;
  192.         }
  193.         CopyMemory(pBuffer, m_pbInData, m_uDataSize);
  194.         hr = pInputBuffer->SetLength( m_uDataSize );
  195.         if( FAILED( hr ) ){
  196.             return hr;
  197.         }
  198.  
  199.         // call processInput
  200.         hr = m_pObject->ProcessInput( 0,
  201.                                 pInputBuffer,
  202.                                 DMO_INPUT_DATA_BUFFERF_SYNCPOINT,
  203.                                 rtStart,
  204.                                 rtStop - rtStart);
  205.         if( FAILED( hr ) ){
  206.             return hr;
  207.         }
  208.     
  209.         //release input buffer
  210.         SAFE_RELEASE( pInputBuffer );
  211.  
  212.         // retrieve the output data from DMO and put into pOut 
  213.         if(S_FALSE == hr){
  214.             return E_FAIL;
  215.         } else {
  216.             hr = ProcessOutputs( &pOut );
  217.             if( FAILED( hr ) ){
  218.                 return hr;
  219.             }
  220.         }
  221.  
  222.         *ppbOutData = pOut;
  223.         SAFE_RELEASE( m_pObject );
  224.     }
  225.  
  226.     return S_OK;
  227. }
  228.  
  229.  
  230. //-----------------------------------------------------------------------------
  231. // Name: CAppStream::ProcessOutputs()
  232. // Desc: retrieve the output data from DMO
  233. //-----------------------------------------------------------------------------
  234.  
  235. HRESULT CAppStream::ProcessOutputs( BYTE **ppbOutData )
  236. {
  237.     HRESULT hr          = S_OK;
  238.     DWORD   dwStatus;
  239.     ULONG   ulSize;
  240.     BYTE    *pOut;
  241.  
  242.     CMediaBuffer            *pOutputBuffer;
  243.     DMO_OUTPUT_DATA_BUFFER  dataBufferStruct;
  244.  
  245.     hr = CreateBuffer( m_uDataSize,&pOutputBuffer );
  246.     if ( FAILED( hr ) ) {
  247.         return hr;
  248.     }
  249.     dataBufferStruct.pBuffer = pOutputBuffer;
  250.     dataBufferStruct.dwStatus = 0;      // No flag is set
  251.     dataBufferStruct.rtTimestamp = 0;   // not used in ProcessOutput()
  252.     dataBufferStruct.rtTimelength = 0;  // not used in ProcessOutput()
  253.  
  254.     *ppbOutData = new BYTE[m_uDataSize];    
  255.     if( *ppbOutData == 0 ){
  256.        return E_OUTOFMEMORY;
  257.     }
  258.     //process until no more data
  259.     if (SUCCEEDED(hr)) do {
  260.         hr = m_pObject->ProcessOutput(  DMO_PROCESS_OUTPUT_DISCARD_WHEN_NO_BUFFER,
  261.                                         1, //output buffer count
  262.                                         &dataBufferStruct,
  263.                                         &dwStatus );
  264.         if ( FAILED( hr ) ) {             
  265.             return hr;
  266.         }
  267.         
  268.         if( SUCCEEDED(hr) && (hr != S_FALSE) ) {            
  269.             hr = dataBufferStruct.pBuffer->GetBufferAndLength(&pOut, &ulSize);
  270.             if ( FAILED( hr ) ) {
  271.                 return hr;
  272.             }
  273.     
  274.             CopyMemory(*ppbOutData, pOut, m_uDataSize);
  275.  
  276.             hr = dataBufferStruct.pBuffer->SetLength( 0 );
  277.             if( FAILED( hr ) ) {
  278.                 break;
  279.             }
  280.         }
  281.  
  282.     } while ( dataBufferStruct.dwStatus & DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE );
  283.  
  284.     // free output buffer allocated:       
  285.     SAFE_RELEASE( pOutputBuffer );
  286.  
  287.     // Send Discontinuity on output stream
  288.     hr = m_pObject->Discontinuity( 0 );
  289.     if ( FAILED( hr ) ) {      
  290.         return hr;
  291.     }
  292.     
  293.     return hr;
  294. }
  295.  
  296. //-----------------------------------------------------------------------------
  297. // Name: CreateBuffer()
  298. // Desc: create a CMediaBuffer
  299. //-----------------------------------------------------------------------------
  300. HRESULT CreateBuffer(
  301.     DWORD cbMaxLength,
  302.     CMediaBuffer **ppBuffer)
  303. {
  304.     CMediaBuffer *pBuffer = new CMediaBuffer( cbMaxLength );
  305.     if ( pBuffer == NULL || FAILED( pBuffer->Init() ) ) {
  306.         delete pBuffer;
  307.         *ppBuffer = NULL;
  308.         return E_OUTOFMEMORY;
  309.     }
  310.     *ppBuffer = pBuffer;
  311.     (*ppBuffer)->AddRef();
  312.     return S_OK;
  313. }
  314.  
  315.  
  316.