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

📄 videoenc.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//*@@@+++@@@@******************************************************************
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//*@@@---@@@@******************************************************************

//
//  Interlace encoding mode is disabled by default.
//  Interlace WMV 9 (4cc WMV3) bit streams should not
//  currently be created in AVI, because AVI does not
//  provide the ability to specify top-field-first or
//  bottom-field-first at frame level. However, the code
//  is provided in case the user may want to wrap interlace
//  WMV 9 streams in other file formats.
//

#include "stdafx.h"
#include <strmif.h>
#include "baseclasses/amvideo.h"
#include <uuids.h>
#include "baseclasses/dvdmedia.h"
#include <wmcodeciface.h>
#include "wmsbuffer.h"
#include "encappErr.h"
#include "videoenc.h"
#include "encode.h"

//////////////////////////////////////////////////////////////////////////////
HRESULT MakeVideoOutputType(IMediaObject   *pDMO,
                            AM_MEDIA_TYPE  *pmtIn,
                            VideoEncParams *pParams,
                            AM_MEDIA_TYPE  *pmt      )
{

 HRESULT             hr                   = S_OK;
 VIDEOINFOHEADER2    *pvih2               = NULL;
 VIDEOINFOHEADER     vih;
 IWMCodecPrivateData *pWMCodecPrivateData = NULL;
 DWORD               cbPrivateData        = 0;
 BYTE                *pbPrivateData       = NULL;
 BYTE                *pNewFormat          = NULL;

 if( NULL == pDMO    ||
     NULL == pmtIn   ||
     NULL == pParams ||
     NULL == pmt     )
  {
   return ( E_INVALIDARG );
  }

 if( NULL == pmtIn->pbFormat || pmtIn->cbFormat < sizeof( VIDEOINFOHEADER ) )
  {
   return ( E_INVALIDARG );
  }

 // make up a partial media type
 pmt->majortype            = MEDIATYPE_Video;
 pmt->formattype           = FORMAT_VideoInfo;
 pmt->bFixedSizeSamples    = FALSE;
 pmt->bTemporalCompression = TRUE;

 if( pmtIn->formattype == FORMAT_VideoInfo )
  {
   vih = *(VIDEOINFOHEADER*)pmtIn->pbFormat;
  }
 else if( pmtIn->formattype == FORMAT_VideoInfo2 )
  {
   pvih2 = (VIDEOINFOHEADER2*)pmtIn->pbFormat;
   vih.rcSource        = pvih2->rcSource;
   vih.rcTarget        = pvih2->rcTarget;
   vih.AvgTimePerFrame = pvih2->AvgTimePerFrame;
   vih.bmiHeader       = pvih2->bmiHeader;
  }
 else
  return ( E_VIDEO_INVALID_INPUT_TYPE );

 vih.dwBitRate            = (DWORD)pParams->nBitrate;
 vih.dwBitErrorRate       = 0;
 vih.bmiHeader.biPlanes   = 1;
 vih.bmiHeader.biBitCount = 24;
 pmt->subtype = WMCMEDIASUBTYPE_WMV1;
 pmt->subtype.Data1=pParams->dwTag;
 vih.bmiHeader.biCompression = pParams->dwTag;
 //
 //use the partial format above to get the private data
 //
 pmt->pbFormat = (BYTE*)CoTaskMemAlloc( sizeof( VIDEOINFOHEADER));
 memcpy( pmt->pbFormat , &vih, sizeof( VIDEOINFOHEADER));
 pmt->cbFormat = sizeof( vih );

 do
  {
   hr = pDMO->QueryInterface(IID_IWMCodecPrivateData, (void**)&pWMCodecPrivateData);
   if( FAILED( hr ) )
    {
     hr = E_NO_PRIVATE_DATA;
     break;
    }

   hr = pWMCodecPrivateData->SetPartialOutputType( pmt );
   if( FAILED( hr ) )
    {
     hr = E_PARTIAL_TYPE_REJECTED;
     break;
    }

   hr = pWMCodecPrivateData->GetPrivateData( NULL, &cbPrivateData );
   if( FAILED( hr ) )
    {
     hr = E_NO_PRIVATE_DATA_COUNT;
     break;
    }

   if( 0 == cbPrivateData )
    { // No private data
     hr = S_OK;
     break;
    }
   pbPrivateData = new BYTE[ cbPrivateData ];
   if( pbPrivateData == NULL )
    {
     hr = E_OUTOFMEMORY;
     break;
    }
   //
   // get the private data
   //
   hr = pWMCodecPrivateData->GetPrivateData( pbPrivateData, &cbPrivateData );
   if( FAILED( hr ) )
    {
     hr = E_PRIVATE_DATA_FAILED;
     break;
    }

   //
   //modify the media type accordingly
   //
   pNewFormat = (BYTE*)CoTaskMemAlloc( sizeof( VIDEOINFOHEADER) + cbPrivateData );
   if( NULL == pNewFormat )
    {
     hr = E_OUTOFMEMORY;
     break;
    }

   memcpy( pNewFormat, pmt->pbFormat, sizeof( VIDEOINFOHEADER));
   CoTaskMemFree(pmt->pbFormat);
   memcpy( pNewFormat + sizeof( VIDEOINFOHEADER), pbPrivateData, cbPrivateData);
   pmt->pbFormat = pNewFormat;
   pmt->cbFormat = sizeof( VIDEOINFOHEADER) + cbPrivateData;
   ((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader.biSize         += cbPrivateData;
   ((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader.biClrUsed       = 0;
   ((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader.biClrImportant  = 0;
   ((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader.biXPelsPerMeter = 0;
   ((VIDEOINFOHEADER*)pmt->pbFormat)->bmiHeader.biYPelsPerMeter = 0;
  }
 while( FALSE );

 SAFERELEASE( pWMCodecPrivateData );
 SAFEDELETE( pbPrivateData );

 return ( hr );
}

//////////////////////////////////////////////////////////////////////////////
HRESULT SetVideoTypes( IMediaObject   *pDMO,    \
                       AM_MEDIA_TYPE  *pmtIn,   \
                       VideoEncParams *pParams, \
                       AM_MEDIA_TYPE  *pmtOut,  \
                       DWORD *pcbIn,            \
                       DWORD *pcbOut )
{
 HRESULT hr;
 DWORD   dwDummy;

 hr = pDMO->SetInputType(0, pmtIn, 0);
 if( S_OK != hr )
  {
   return ( hr );
  }

 hr = MakeVideoOutputType( pDMO, pmtIn, pParams, pmtOut );
 if( FAILED( hr ) )
  {
   return ( hr );
  }

 hr = pDMO->SetOutputType(0, pmtOut, 0);
 if( S_OK != hr )
  {
   return ( hr );
  }

 hr = pDMO->GetInputSizeInfo( 0, pcbIn, &dwDummy, &dwDummy);
 if( FAILED(hr) )
  {
   return ( hr );
  }

 hr = pDMO->GetOutputSizeInfo( 0, pcbOut, &dwDummy);
 if( FAILED( hr ) )
  {
   return ( hr );
  }

 return ( hr == S_FALSE ? E_VIDEO_TYPE_NOT_SET: hr );
}

//////////////////////////////////////////////////////////////////////////////
HRESULT SetVideoParams( IMediaObject *pDMO, VideoEncParams *pParams )
{
 HRESULT      hr;
 VARIANT      varg;
 IPropertyBag *pPropertyBag = NULL;

 if( NULL == pDMO || NULL == pParams )
  {
   return ( E_INVALIDARG );
  }

 do
  {
   //
   // Get the IPropertyBag IF and set the appropriate params
   //
   hr = pDMO->QueryInterface(IID_IPropertyBag, (void**)&pPropertyBag);
   if( FAILED( hr ) )
    {
     break;
    }
   //
   //set the encoder in VBR mode if required
   //
   if( pParams->fIsVBR == TRUE )
    {
     ::VariantInit(&varg);
     varg.vt      = VT_BOOL;
     varg.boolVal = TRUE;

     hr = pPropertyBag->Write( g_wszWMVCVBREnabled, &varg );
     if( FAILED( hr ) )
      {
       hr = E_VIDEO_VBR_NOT_SUPPORTED;
       break;
      }
     //
     // if it is 1 pass VBR set the Quality param
     //
     if( pParams->nPasses == 1 )
      {
       ::VariantInit(&varg);
       varg.vt = VT_I4;
       varg.lVal = pParams->nVBRQuality;
       hr = pPropertyBag->Write( g_wszWMVCVBRQuality, &varg );
       if( FAILED( hr ) )
        {
         hr = E_VBR_QUALITY_REJECTED;
         break;
        }
      }
    }
   //
   //set the number of passes
   //
   if( pParams->nPasses > 1 )
    {
     ::VariantInit(&varg);
     varg.vt   = VT_I4;
     varg.lVal = pParams->nPasses;

     hr = pPropertyBag->Write( g_wszWMVCPassesUsed, &varg );
     if( FAILED( hr ) )
      {
       hr = E_VIDEO_NPASS_NOT_SUPPORTED;
       break;
      }
    }
   //
   // set the bitrate for all the modes except 1 pass VBR
   //
   if( !( pParams->fIsVBR == TRUE && pParams->nPasses == 1 ) )
    {
     ::VariantInit(&varg);
     varg.vt = VT_I4;
     varg.lVal = pParams->nBitrate;
     hr = pPropertyBag->Write( g_wszWMVCAvgBitrate, &varg );
     if( FAILED( hr ) )
      {
       hr = E_VIDEO_BITRATE_REJECTED;
       break;
      }
    }
   //
   // set the buffer window
   //
   ::VariantInit(&varg);
   varg.vt = VT_I4;
   varg.lVal = pParams->nBufferDelay;
   hr = pPropertyBag->Write( g_wszWMVCVideoWindow, &varg );
   if( FAILED( hr ) )
    {
     hr = E_VIDEO_BUFFER_REJECTED;
     break;
    }

   if( pParams->fIsConstrained == TRUE )
    {
     ::VariantInit(&varg);
     varg.vt   = VT_I4;
     varg.lVal = pParams->nPeakBitrate;

     hr = pPropertyBag->Write( g_wszWMVCMaxBitrate, &varg );
     if( FAILED( hr ) )
      {
       hr = E_VIDEO_PEAK_BITRATE_REJECTED;
       break;
      }

     ::VariantInit(&varg);
     varg.vt   = VT_I4;
     varg.lVal = pParams->nPeakBuffer;

     hr = pPropertyBag->Write( g_wszWMVCBMax, &varg );
     if( FAILED( hr ) )

⌨️ 快捷键说明

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