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

📄 videoenc.cpp

📁 从FFMPEG转换而来的H264解码程序,VC下编译..
💻 CPP
📖 第 1 页 / 共 2 页
字号:
      {
       hr = E_VIDEO_PEAK_BUFFER_REJECTED;
       break;
      }
    }

   //
   // set the profile for WMV# only
   //
   hr = S_OK;
   BSTR bstrIn=NULL;
   if( pParams->dwTag == WMCFOURCC_WMV3 )
    {
     switch( pParams->nProfile )
      {
      case P_MAIN:
       bstrIn = ::SysAllocString(L"MP");
       break;
      case P_SIMPLE:
       bstrIn = ::SysAllocString(L"SP");
       break;
      case P_COMPLEX:
       bstrIn = ::SysAllocString(L"CP");
       break;
      default:
       hr = E_VIDEO_INVALID_PROFILE;
       break;
      }
     if( FAILED( hr ) ) break;

     ::VariantInit(&varg);
     varg.vt      = VT_BSTR;
     varg.bstrVal = bstrIn;
     hr = pPropertyBag->Write( g_wszWMVCDecoderComplexityRequested, &varg );
     ::SysFreeString( bstrIn );
     if( FAILED( hr ) )
      {
       hr = E_VIDEO_PROFILE_REJECTED;
       break;
      }
    }

   //
   // set the complexity param
   //
   ::VariantInit(&varg);
   varg.vt = VT_I4;
   varg.lVal = pParams->nComplexity;
   hr = pPropertyBag->Write( g_wszWMVCComplexityEx, &varg );
   if( FAILED( hr ) )
    {
     hr = E_VIDEO_KEYDIST_REJECTED;
     break;
    }

   //
   // set the max distance between the key frames
   //
   ::VariantInit(&varg);
   varg.vt = VT_I4;
   varg.lVal = pParams->nKeyDist;
   hr = pPropertyBag->Write( g_wszWMVCKeyframeDistance, &varg );
   if( FAILED( hr ) )
    {
     hr = E_VIDEO_KEYDIST_REJECTED;
     break;
    }

   //
   // set the crispness params for WMV# only
   //
   if( pParams->dwTag == WMCFOURCC_WMV3 || pParams->dwTag == WMCFOURCC_WMV2 || pParams->dwTag == WMCFOURCC_WMV1 )
    {
     ::VariantInit(&varg);
     varg.vt = VT_I4;
     varg.lVal = pParams->nCrisp;
     hr = pPropertyBag->Write( g_wszWMVCCrisp, &varg );
     if( FAILED( hr ) )
      {
       hr = E_VIDEO_CRISPNESS_REJECTED;
       break;
      }
    }

   if ( pParams->fIsVBR)
    {
     ::VariantInit(&varg);
     varg.vt = VT_I4;
     varg.lVal = pParams->nQuality;
     hr = pPropertyBag->Write( g_wszWMVCVBRQuality, &varg );
     if( FAILED( hr ) )
      {
       hr = E_VIDEO_QUALITY_REJECTED;
       break;
      }
    }

#ifdef SUPPORT_INTERLACE
   //
   // set the interlace mode for WMV# only
   //
   if( pParams->dwTag == WMCFOURCC_WMV3 && pParams->fIsInterlaced)
    {
     ::VariantInit(&varg);
     varg.vt = VT_BOOL;
     varg.boolVal = TRUE;
     hr = pPropertyBag->Write( g_wszWMVCInterlacedCodingEnabled, &varg );
     if( FAILED( hr ) )
      {
       hr = E_VIDEO_INTERLACE_REJECTED;
       break;
      }
    }
#endif //SUPPORT_INTERLACE

  }
 while( FALSE );
 SAFERELEASE( pPropertyBag );
 return ( hr );
}

//////////////////////////////////////////////////////////////////////////////
// a decent guess would be 0.4 bits per pixel
HRESULT DefaultVideoBitrate( AM_MEDIA_TYPE *pmt, double dFramesPerSec, int *pBitrate )
{
 if( NULL == pmt || NULL == pBitrate )
  {
   return ( E_INVALIDARG );
  }

 if( NULL == pmt->pbFormat || pmt->cbFormat <= 0 )
  {
   return ( E_INVALIDARG );
  }

 if( FORMAT_VideoInfo == pmt->formattype )
  {
   VIDEOINFOHEADER *pvih = (VIDEOINFOHEADER*)pmt->pbFormat;

   *pBitrate = ( pvih->bmiHeader.biWidth * pvih->bmiHeader.biHeight * 2 ) / 5;
   if( dFramesPerSec == 0 )
    { // use the input rate
     if( pvih->AvgTimePerFrame > 0 )
      {
       dFramesPerSec = 10000000.0 / pvih->AvgTimePerFrame;
      }
     else
      {
       dFramesPerSec = 29.97;   // 30 frames per sec
      }
    }
  }
 else if( FORMAT_VideoInfo2 == pmt->formattype  )
  {
   VIDEOINFOHEADER2 *pvih = (VIDEOINFOHEADER2*)pmt->pbFormat;

   *pBitrate = ( pvih->bmiHeader.biWidth * pvih->bmiHeader.biHeight * 2 ) / 5;

   if( dFramesPerSec == 0 )
    { // use the input rate
     if( pvih->AvgTimePerFrame > 0 )
      {
       dFramesPerSec = 10000000.0 / pvih->AvgTimePerFrame;
      }
     else
      {
       dFramesPerSec = 29.97;   // 30 frames per sec
      }
    }
  }
 else
  {
   return ( E_VIDEO_INVALID_INPUT_TYPE );
  }

 *pBitrate = (int)( *pBitrate * dFramesPerSec );
 return ( S_OK );
}

//////////////////////////////////////////////////////////////////////////////
HRESULT InitializeVideoEncoder(  AM_MEDIA_TYPE      *pmtInput,
                                 VideoEncParams       *pParams,
                                 IMediaObject         **ppDMO,
                                 AM_MEDIA_TYPE        *pmtOutput,
                                 CHandlingMediaBuffer *pMediaBuffer )
{
 HRESULT       hr             = S_OK;
 DWORD         cbInputBuffer  = 0;
 DWORD         cbOutputBuffer = 0;

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

#ifdef SUPPORT_INTERLACE
 //
 // Interlace encoding using IYUV or I420 at the input is not supported
 //
 if( NULL == pmtInput->pbFormat )
  {
   return ( E_INVALIDARG );
  }
 if( WMCFOURCC_IYUV == ((VIDEOINFOHEADER*)pmtInput->pbFormat)->bmiHeader.biCompression ||
     WMCFOURCC_I420 == ((VIDEOINFOHEADER*)pmtInput->pbFormat)->bmiHeader.biCompression )
  {
   if( TRUE == pParams->fIsInterlaced )
    {
     return ( E_VIDEO_INTERLACE_REJECTED );
    }
  }
#endif //SUPPORT_INTERLACE

 *ppDMO = NULL;

 //
 //check to see if the video bitrate has been set; if not calculate the default
 //
 if( pParams->nBitrate <= 0 )
  {
   hr = DefaultVideoBitrate( pmtInput, pParams->dFrameRate, &pParams->nBitrate );
   if( FAILED( hr ) )
    {
     return ( hr );
    }
   if( pParams->nPeakBitrate <= 0 )
    {
     pParams->nPeakBitrate = 3 * pParams->nBitrate;
    }
  }
 do
  {
   //
   // Create the DMO Encoder
   //
   const CLSID *clsid=&CLSID_NULL;
   char fcc[]="1234";memcpy(fcc,&pParams->dwTag,4);
   switch (pParams->dwTag)
    {
     case WMCFOURCC_MSS1:
     case WMCFOURCC_MSS2:
      {
       static const CLSID clsids[]={CLSID_CMSSCEncMediaObject2,CLSID_NULL};
       clsid=clsids;
       break;
      }
     case WMCFOURCC_WMV3:
     case WMCFOURCC_WMVA:
     case WMCFOURCC_WVC1:
     case WMCFOURCC_WVP2:
      {
       static const CLSID clsids[]={CLSID_CWMV9EncMediaObject,CLSID_NULL};
       clsid=clsids;
       break;
      }
     case WMCFOURCC_MP43:
     case WMCFOURCC_MP4S:
     case WMCFOURCC_WMV1:
     case WMCFOURCC_WMV2:
     case WMCFOURCC_WMVP:
     default:
      {
       static const CLSID clsids[]={CLSID_CWMVEncMediaObject2,CLSID_CWMVEncMediaObject2A,CLSID_NULL};
       clsid=clsids;
       break;
      }
    }
  nextclsid:
   hr = CoCreateInstance( *clsid,
                           NULL,
                           CLSCTX_INPROC_SERVER,
                           IID_IMediaObject,
                           (void**)ppDMO);
   clsid++;

   if( FAILED( hr ) )
    if (*clsid==CLSID_NULL)
      break;
    else
      goto nextclsid;

   hr = SetVideoParams( *ppDMO, pParams );
   if( FAILED( hr ) )
    {
     break;
    }

   hr = SetVideoTypes( *ppDMO, pmtInput, pParams, pmtOutput, &cbInputBuffer, &cbOutputBuffer );
   if( FAILED( hr ) )
    {
     break;
    }

#ifdef SUPPORT_INTERLACE
   if( pParams->dwTag == WMCFOURCC_WMV3 && pParams->fIsInterlaced)
    {
     INSSBuffer3 *pINSSBuffer3 = NULL;
     BYTE        bType         = WM_CT_INTERLACED;

     hr = pMediaBuffer->QueryInterface( IID_INSSBuffer3, (void**)&pINSSBuffer3 );
     if( FAILED( hr ) )
      {
       break;
      }
     pINSSBuffer3->SetProperty( WM_SampleExtension_ContentType,
                                &bType,
                                1 );
     SAFERELEASE( pINSSBuffer3 );
    }
#endif //SUPPORT_INTERLACE

  }
 while ( FALSE );

 if( S_OK != hr )
  {
   SAFERELEASE( *ppDMO );
  }

 return ( hr );
}

⌨️ 快捷键说明

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