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

📄 genprofile_lib.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//*****************************************************************************
//
// Microsoft Windows Media
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// FileName:            GenProfile_lib.cpp
//
// Abstract:            The implementation for the GenProfile static library.
//
//*****************************************************************************

#include "stdafx.h"
#include <assert.h>
#include "GenProfile_lib.h"
#include "Twmv9dll.h"

#define SAFE_RELEASE( x )   \
    if ( x )                \
    {                       \
        x->Release();       \
        x = NULL;           \
    }

#define SAFE_ADDREF( x )    \
    if ( x )                \
    {                       \
        x->AddRef();        \
    }

#define SAFE_DELETE( x )    \
    if ( x )                \
    {                       \
        delete x;           \
        x = NULL;           \
    }

#define SAFE_ARRAYDELETE( x )   \
    if ( x )                    \
    {                           \
        delete[] x;             \
        x = NULL;               \
    }

#define SAFE_SYSFREESTRING( x ) \
    if ( x )                    \
    {                           \
        SysFreeString( x );     \
        x = NULL;               \
    }

#define SAFE_CLOSEHANDLE( x )               \
    if ( x && INVALID_HANDLE_VALUE != x )   \
    {                                       \
        CloseHandle( x );                   \
        x = NULL;                           \
    }

struct PIXEL_FORMAT
 {
  const GUID* guidFormat;
  DWORD dwFourCC;
  WORD wBitsPerPixel;
 };

PIXEL_FORMAT PixelFormats[] =
 {
  { &WMMEDIASUBTYPE_RGB555,   BI_RGB,         16 },
  { &WMMEDIASUBTYPE_RGB24,    BI_RGB,         24 },
  { &WMMEDIASUBTYPE_RGB32,    BI_RGB,         32 },
  { &WMMEDIASUBTYPE_I420,     0x30323449,     12 },
  { &WMMEDIASUBTYPE_IYUV,     0x56555949,     12 },
  { &WMMEDIASUBTYPE_YV12,     0x32315659,     12 },
  { &WMMEDIASUBTYPE_YUY2,     0x32595559,     16 },
  { &WMMEDIASUBTYPE_UYVY,     0x59565955,     16 },
  { &WMMEDIASUBTYPE_YVYU,     0x55595659,     16 }
 };


DWORD WaveFrequency[] =
 {
  8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000
 };


//------------------------------------------------------------------------------
// Name: CopyMediaType()
// Desc: Allocates memory for a WM_MEDIA_TYPE and its format data and
//       copies an existing media type into it.
//------------------------------------------------------------------------------
STDMETHODIMP CopyMediaType( WM_MEDIA_TYPE** ppmtDestination,
                            WM_MEDIA_TYPE* pmtSource )
{
 if ( !ppmtDestination )
  {
   return E_POINTER;
  }
 if ( !pmtSource )
  {
   return E_NOTIMPL;
  }

 //
 // Create enough space for the media type and its format data
 //
 *ppmtDestination = (WM_MEDIA_TYPE*) new BYTE[ sizeof( WM_MEDIA_TYPE ) + pmtSource->cbFormat ];
 if ( !*ppmtDestination)
  {
   return E_OUTOFMEMORY;
  }

 //
 // Copy the media type and the format data
 //
 memcpy( *ppmtDestination, pmtSource, sizeof( WM_MEDIA_TYPE ) );
 (*ppmtDestination)->pbFormat = ( ((BYTE*) *ppmtDestination) + sizeof( WM_MEDIA_TYPE ) ); // Format data is immediately after media type
 memcpy( (*ppmtDestination)->pbFormat, pmtSource->pbFormat, pmtSource->cbFormat );

 return S_OK;
}


//------------------------------------------------------------------------------
// Name: EnsureIWMCodecInfo3()
// Desc: Creates an IWMCodecInfo3 interface if none exists, and ensures
//       an outstanding reference either way.  This way the IWMCodecInfo3
//       object is guaranteed to exist and isn't released too many times.
//------------------------------------------------------------------------------
STDMETHODIMP EnsureIWMCodecInfo3( Twmv9dll *dll,IWMCodecInfo3** ppCodecInfo3 )
{
 HRESULT hr = S_OK;

 if ( !ppCodecInfo3 )
  {
   return E_POINTER;
  }

 do
  {
   if ( !*ppCodecInfo3 )
    {
     //
     // Create a new IWMCodecInfo3 object
     //
     IWMProfileManager* pProfileManager;
     hr = dll->WMCreateProfileManager( &pProfileManager );
     if ( FAILED( hr ) )
      {
       break;
      }
     assert( pProfileManager );

     hr = pProfileManager->QueryInterface( IID_IWMCodecInfo3, (void**) ppCodecInfo3 );
     SAFE_RELEASE( pProfileManager );
     if ( FAILED( hr ) )
      {
       break;
      }
    }
   else
    {
     //
     // Add a reference to the existing object, so that it won't be destroyed during cleanup
     //
     SAFE_ADDREF( (*ppCodecInfo3) );
    }
   assert( *ppCodecInfo3 );

   //
   // It should now not matter if the IWMCodecInfo3 was just created or was passed in
   //
  }
 while ( FALSE );

 return hr;
}


//------------------------------------------------------------------------------
// Name: SetCodecVBRSettings()
// Desc: Enables VBR with the specified number of passes, or disables it.
//------------------------------------------------------------------------------
STDMETHODIMP SetCodecVBRSettings( IWMCodecInfo3* pCodecInfo3,
                                  GUID guidCodecType,
                                  DWORD dwCodecIndex,
                                  BOOL fIsVBR,
                                  DWORD dwVBRPasses )
{
 HRESULT hr;

 if ( !pCodecInfo3 )
  {
   return E_INVALIDARG;
  }

 do
  {
   //
   // Configure the codec to use or not use VBR as requested
   //
   hr = pCodecInfo3->SetCodecEnumerationSetting( guidCodecType, dwCodecIndex, g_wszVBREnabled, WMT_TYPE_BOOL, (BYTE*) &fIsVBR, sizeof( BOOL ) );
   if ( FAILED( hr ) )
    {
     //
     // If VBR is requested, then it's a problem, but otherwise the codec may just not support VBR
     //
     if ( ( !fIsVBR ) && ( NS_E_UNSUPPORTED_PROPERTY == hr ) )
      {
       hr = S_OK;
      }
     else
      {
       break;
      }
    }

   if ( fIsVBR )
    {
     hr = pCodecInfo3->SetCodecEnumerationSetting( guidCodecType, dwCodecIndex, g_wszNumPasses, WMT_TYPE_DWORD, (BYTE*) &dwVBRPasses, sizeof( DWORD ) );
     if ( FAILED( hr ) )
      {
       break;
      }
    }

  }
 while ( FALSE );

 return hr;
}


//------------------------------------------------------------------------------
// Name: SetStreamLanguage()
// Desc: Sets the language in the stream configuration.
//------------------------------------------------------------------------------
/*
STDMETHODIMP SetStreamLanguage( IWMStreamConfig * pStreamConfig, LCID dwLanguage )
{
 HRESULT hr = S_OK;
 IWMStreamConfig3 * pStreamConfig3 = NULL;
 IMultiLanguage * pMLang = NULL;
 BSTR bstrLanguage = NULL;

 do
  {
   hr = CoCreateInstance( CLSID_CMultiLanguage,
                          NULL,
                          CLSCTX_ALL,
                          IID_IMultiLanguage,
                          (VOID **) &pMLang );

   if( FAILED( hr ) )
    {
     break;
    }

   hr = pMLang->GetRfc1766FromLcid( dwLanguage, &bstrLanguage );
   if( FAILED( hr ) )
    {
     break;
    }

   hr = pStreamConfig->QueryInterface(	IID_IWMStreamConfig3, (void**)&pStreamConfig3 );
   if(	FAILED(	hr ) )
    {
     break;
    }

   hr = pStreamConfig3->SetLanguage( bstrLanguage );
   if(	FAILED(	hr ) )
    {
     break;
    }
  }
 while (FALSE);

 SAFE_RELEASE( pMLang );
 SAFE_RELEASE( pStreamConfig3 );

 if ( !bstrLanguage )
  {
   SysFreeString( bstrLanguage );
  }

 return hr;
}
*/

/*
** Functions that create media types for the various stream types
*/

//------------------------------------------------------------------------------
// Name: CreateUncompressedAudioMediaType()
// Desc: Initializes a WM_MEDIA_TYPE for uncompressed audio.
//------------------------------------------------------------------------------
STDMETHODIMP CreateUncompressedAudioMediaType(  WM_MEDIA_TYPE** ppmtMediaType,
  DWORD dwSamplesPerSecond,
  WORD wNumChannels,
  WORD wBitsPerSample )
{
 HRESULT hr = S_OK;

 WM_MEDIA_TYPE mtUncompressedAudio;
 WAVEFORMATEX wfxUncompressedAudio;

 if ( !ppmtMediaType )
  {
   return E_POINTER;
  }
 //
 // pCodecInfo3 is allowed to be NULL, since CreateMediatypeForFormat calls EnsureIWMCodecInfo3
 //

 do
  {
   //
   // Setup the local copy of the uncompressed media type
   //
   ZeroMemory( &mtUncompressedAudio, sizeof( mtUncompressedAudio ) );

   mtUncompressedAudio.majortype = WMMEDIATYPE_Audio;
   mtUncompressedAudio.subtype = WMMEDIASUBTYPE_PCM;
   mtUncompressedAudio.bFixedSizeSamples = TRUE;
   mtUncompressedAudio.bTemporalCompression = FALSE;
   mtUncompressedAudio.lSampleSize = wNumChannels * wBitsPerSample / 8;
   mtUncompressedAudio.formattype = WMFORMAT_WaveFormatEx;
   mtUncompressedAudio.pUnk = NULL;
   mtUncompressedAudio.cbFormat = sizeof( WAVEFORMATEX );
   mtUncompressedAudio.pbFormat = (BYTE*) &wfxUncompressedAudio;

   //
   // Configure the WAVEFORMATEX structure for the uncompressed audio
   //
   ZeroMemory( &wfxUncompressedAudio, sizeof( wfxUncompressedAudio ) );

   wfxUncompressedAudio.wFormatTag = 1;
   wfxUncompressedAudio.nChannels = wNumChannels;
   wfxUncompressedAudio.nSamplesPerSec = dwSamplesPerSecond;
   wfxUncompressedAudio.nAvgBytesPerSec = dwSamplesPerSecond * ( wNumChannels * wBitsPerSample / 8 );
   wfxUncompressedAudio.nBlockAlign = wNumChannels * wBitsPerSample / 8;
   wfxUncompressedAudio.wBitsPerSample = wBitsPerSample;
   wfxUncompressedAudio.cbSize = sizeof( WAVEFORMATEX );

   //
   // Return a copy of the media type to the caller, since the mediatype is on the stack
   //
   hr = CopyMediaType( ppmtMediaType, &mtUncompressedAudio );
   if ( FAILED( hr ) )
    {
     break;
    }
  }
 while( FALSE );

 return( hr );
}


//------------------------------------------------------------------------------
// Name: CreateVideoMediaType()
// Desc: Initializes a WM_MEDIA_TYPE for video.
//------------------------------------------------------------------------------
STDMETHODIMP CreateVideoMediaType(  Twmv9dll *dll,
                                    WM_MEDIA_TYPE** ppmtMediaType,
                                    IWMCodecInfo3* pCodecInfo3,
                                    DWORD dwCodecIndex,
                                    double dFPS,
                                    DWORD dwWidth,
                                    DWORD dwHeight,
                                    DWORD dwBitrate,
                                    BOOL fIsVBR,
                                    DWORD dwNumberOfPasses )
{
 HRESULT hr = S_OK;

 WM_MEDIA_TYPE *pMediaType = NULL;
 WMVIDEOINFOHEADER *pVIH;

 if ( !ppmtMediaType )
  {
   return E_POINTER;
  }
 //
 // pCodecInfo3 is allowed to be NULL, since CreateMediatypeForFormat calls EnsureIWMCodecInfo3
 //

 do
  {
   //
   // Get the mediatype for the codec
   //
   hr = CreateMediatypeForFormat( dll,
                                  &pMediaType,
                                  pCodecInfo3,
                                  NULL,
                                  WMMEDIATYPE_Video,
                                  dwCodecIndex,
                                  0,
                                  fIsVBR,
                                  dwNumberOfPasses );
   if( FAILED( hr ) )
    {
     break;
    }
   assert( pMediaType );

   //
   // Configure the WMVIDEOINFOHEADER structure of the media type
   //
   pVIH = (WMVIDEOINFOHEADER*) pMediaType->pbFormat;
   pVIH->dwBitRate = dwBitrate;

   pVIH->rcSource.right = dwWidth;
   pVIH->rcSource.bottom = dwHeight;
   pVIH->rcTarget.right = dwWidth;
   pVIH->rcTarget.bottom = dwHeight;
   pVIH->bmiHeader.biWidth = dwWidth;
   pVIH->bmiHeader.biHeight = dwHeight;

   pVIH->AvgTimePerFrame = ( (LONGLONG) 10000000 ) / ( (LONGLONG) dFPS );

   //
   // Return a copy of the media type to the caller
   //
   hr = CopyMediaType( ppmtMediaType, pMediaType );
   if ( FAILED( hr ) )
    {
     break;
    }
  }
 while( FALSE );

 SAFE_ARRAYDELETE( pMediaType );

 return( hr );
}


//------------------------------------------------------------------------------
// Name: CreateUncompressedVideoMediaType()
// Desc: Initializes a WM_MEDIA_TYPE for uncompressed video.
//------------------------------------------------------------------------------
STDMETHODIMP CreateUncompressedVideoMediaType(  WM_MEDIA_TYPE** ppmtMediaType,
  GUID guidFormat,
  DWORD dwFourCC,
  WORD wBitsPerPixel,
  BYTE* pbPaletteData,
  DWORD cbPaletteDataSize,
  DWORD dwFPS,
  DWORD dwWidth,
  DWORD dwHeight )
{
 const DWORD BITFIELD_DATA_SIZE = sizeof( RGBQUAD ) * 3;

 HRESULT hr;
 WM_MEDIA_TYPE mtUncompressedVideo;
 WMVIDEOINFOHEADER* pvihUncompressedVideo;
 BYTE* pbFormatData = NULL;
 DWORD dwFormatDataSize;
 DWORD dwMaxColors;
 BOOL fPalettePresent;
 BYTE* pbPostVIHData;
 DWORD cbExpectedPostVIHDataSize;
 BOOL fBitfieldsPresent;

 if ( !ppmtMediaType )
  {
   return E_POINTER;
  }
 //
 // pCodecInfo3 is allowed to be NULL, since CreateMediatypeForFormat calls EnsureIWMCodecInfo3
 //

⌨️ 快捷键说明

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