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

📄 h264.cpp

📁 This the source release kit for the following system configuration(s): - AMD Alchemy(TM) DBAu1200(
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//------------------------------------------------------------------------------
// File: H264.cpp
//------------------------------------------------------------------------------


#include "stdafx.h"

#define FIX_LOCK_NAME
#include <dmo.h>

#include <limits.h>     //  _I64_MAX
#ifndef UNDER_CE
  #include <crtdbg.h>
#endif
#include <dmoimpl.h>
#include <uuids.h>      // DirectShow media type guids
#include <amvideo.h>    // VIDEOINFOHEADER definition
#include "resource.h"

#include "H264.h"
#include "debug.h"
#include "MAECommon.h"

#define DMO_QC_PROCESS /* enable quality control (frame skipping) */

#pragma warning(disable:4100)  // Disable C4100: unreferenced formal parameter

//#define DUMP_FILE           //dumps input and output of the dmo for verification
//#define DUMP_STANDALONE_FILE  //Creates a video elementary file for standalone testdecoder.exe application 

#if defined DUMP_FILE || defined DUMP_STANDALONE_FILE
  #include "stdio.h"
#endif

#ifdef DUMP_FILE
  static FILE  *s_InDataFile  = NULL;
  static FILE  *s_OutDataFile = NULL;
  TCHAR g_szInDataFile[100];
  TCHAR g_szOutDataFile[100];
#endif

#ifdef DUMP_STANDALONE_FILE
  #undef DMO_QC_PROCESS //disable frame skipping when creating standalone files
  #include "sadecoder.h"
  #define TEST_FILENAME TEXT("\\Hard Disk2\\H264VideoOnly.vid")
  static FILE  *s_TestFile = NULL;
  TCHAR g_szTestFile[100];
#endif

#define FOURCC_H264    0x34363248
// {0x34363248-0000-0010-8000-00AA00389B71}
DEFINE_GUID(MEDIASUBTYPE_H264, 
0x34363248, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);

#define FOURCC_h264    0x34363268
// {0x34363268-0000-0010-8000-00AA00389B71}
DEFINE_GUID(MEDIASUBTYPE_h264, 
0x34363268, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);

// {05589f91-c356-11ce-bf01-00aa0055595a}
DEFINE_GUID(FORMAT_H264VideoInfo,
0x05589f91, 0xc356, 0x11ce, 0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a);

typedef struct tagH264VIDEOINFOHEADER 
{
  RECT            rcSource;          // The bit we really want to use
  RECT            rcTarget;          // Where the video should go
  DWORD           dwBitRate;         // Approximate bit data rate
  DWORD           dwBitErrorRate;    // Bit error rate for this stream
  REFERENCE_TIME  AvgTimePerFrame;   // Average time per frame (100ns units)
  BITMAPINFOHEADER bmiHeader;
  DWORD           vihSize;           // amount of extra decoder config info at end of stucture
} H264VIDEOINFOHEADER;

#define FOURCC_YV12    0x32315659

CH264Dmo::CH264Dmo()
{
  DP_FUNC((TEXT("CH264Dmo::CH264Dmo")));
  m_pUnkMarshaler = NULL;
  m_hDecoder = M_HANDLE_INVALID;
  #ifdef DUMP_FILE
    #ifdef UNDER_CE
      DP_ERROR((TEXT("Creating input/output dump files!")));
      _tcscpy(g_szInDataFile, TEXT("\\Hard Disk\\h264InputCE.dmp")); 
      _tcscpy(g_szOutDataFile, TEXT("\\Hard Disk\\h264OutputCE.dmp")); 
    #else
      _tcscpy(g_szInDataFile, TEXT("c:\\h264Input.dmp")); 
      _tcscpy(g_szOutDataFile, TEXT("c:\\h264Output.dmp")); 
    #endif
    s_InDataFile  = _tfopen(g_szInDataFile, TEXT("wb"));
    s_OutDataFile = _tfopen(g_szOutDataFile, TEXT("wb"));
  #endif
  #ifdef DUMP_STANDALONE_FILE
    DP_ERROR((TEXT("Creating Standalone test file %s!"), TEST_FILENAME));
    _tcscpy(g_szTestFile, TEST_FILENAME); 
    s_TestFile  = _tfopen(g_szTestFile, TEXT("wb"));
  #endif
  DecoderOpen(&m_hDecoder);
  m_rtNow = m_rtOld = 0;
  DP_INFO((TEXT("Loaded H264 Video Decoder (%08X)"), m_hDecoder));
  //initialize everything
  m_pBuffer = NULL;
  m_bFrame = false;
  m_bSentHeader = false;
  m_bDiscontinuity = false;

  Init(); //initialize quality control specifics

  // Open a handle to the mae driver
  open_mae_driver_handle(TEXT("H264DMO"));
}

CH264Dmo::~CH264Dmo()
{
  DP_FUNC((TEXT("~CH264Dmo")));
  if (m_hDecoder != M_HANDLE_INVALID)
  {
    DIUComp_End(m_hDecoder);
    DecoderClose(m_hDecoder);
    m_hDecoder = M_HANDLE_INVALID;
  }
  #ifdef DUMP_FILE
    if (s_InDataFile)
    {
      fclose(s_InDataFile);
      s_InDataFile = NULL;
    }
    if (s_OutDataFile)
    {
      fclose(s_OutDataFile);
      s_OutDataFile = NULL;
    }
  #endif
  #ifdef DUMP_STANDALONE_FILE
    if (s_TestFile)
    {
      DP_ERROR((TEXT("Standalone test file %s complete!"), TEST_FILENAME));
      fclose(s_TestFile);
      s_TestFile = NULL;
    }
  #endif

  // Close a handle to the mae driver
  close_mae_driver_handle();
}

HRESULT CH264Dmo::InternalGetInputStreamInfo(DWORD dwInputStreamIndex, DWORD *pdwFlags)
{
  // We can process data on any boundary
  DP_FUNC((TEXT("InternalGetInputStreamInfo")));
  *pdwFlags = 0;
  return S_OK;
}

HRESULT CH264Dmo::InternalGetOutputStreamInfo(DWORD dwOutputStreamIndex, DWORD *pdwFlags)
{
  //  We output single frames
  DP_FUNC((TEXT("InternalGetOutputStreamInfo")));
  *pdwFlags = 0;
  return S_OK;
}

HRESULT CH264Dmo::InternalCheckInputType(DWORD dwInputStreamIndex, const DMO_MEDIA_TYPE *pmt)
{
  uint32 iMaxMAESize, iClipSize;
  VIDEOINFOHEADER* pvih = (VIDEOINFOHEADER*)pmt->pbFormat;

  DP_FUNC((TEXT("InternalCheckInputType")));
  //Verfiy that we loaded the decoder properly
  if (m_hDecoder == M_HANDLE_INVALID)
  {
    DP_ERROR((TEXT("InternalCheckInputType FAILED No Decoder")));
    return E_FAIL;
  }

  // Get the drivers capabilities for YUV input (ioctl call AU1XXXMAE_GETYUVCONFIG)
  MAE_DISP_STRUCT  disp_struct;

  get_mae_yuv_config(&disp_struct);

  // Update the memory sizes
  iMaxMAESize = (disp_struct.display_linesize * disp_struct.display_height);
  iClipSize = ((uint32)pvih->bmiHeader.biWidth * (uint32)pvih->bmiHeader.biHeight);

  // Check to see that the spatial size is within the driver's capabilities
  if (iClipSize > iMaxMAESize)
  {
    DP_ERROR((TEXT("ClipSize %d is too big for MAE (%d)!!"), iClipSize, iMaxMAESize));
    return DMO_E_INVALIDTYPE;
  }

  //  Check if the type is already set and if so reject any type that's not identical
  if (InputTypeSet(dwInputStreamIndex)) 
  {
    if(pmt->majortype   == InputType(dwInputStreamIndex)->majortype &&
        pmt->subtype     == InputType(dwInputStreamIndex)->subtype &&
        pmt->lSampleSize == InputType(dwInputStreamIndex)->lSampleSize &&
        pmt->formattype  == InputType(dwInputStreamIndex)->formattype &&
        pmt->cbFormat    == InputType(dwInputStreamIndex)->cbFormat &&
        0 == memcmp(pmt->pbFormat, InputType(dwInputStreamIndex)->pbFormat, pmt->cbFormat)) 
    {
      return S_OK;
    } else 
    {
      DP_ERROR((TEXT("InternalCheckInputType InputType is already set and different")));
      return DMO_E_INVALIDTYPE;
    }
  }

  if ((pmt->majortype == MEDIATYPE_Video) &&
      (pmt->subtype == MEDIASUBTYPE_H264 ||
       pmt->subtype == MEDIASUBTYPE_h264))
  {
    return S_OK;
  } else 
  {
    DP_INFO((TEXT("InternalCheckInputType InputType not valid")));
    return DMO_E_INVALIDTYPE;
  }
}

HRESULT CH264Dmo::InternalCheckOutputType(DWORD dwOutputStreamIndex, const DMO_MEDIA_TYPE *pmt)
{
  DP_FUNC((TEXT("InternalCheckOutputType")));
  //Verfiy that we loaded the decoder properly
  if (m_hDecoder == M_HANDLE_INVALID)
  {
    DP_ERROR((TEXT("InternalCheckOutputType FAILED No Decoder")));
    return E_FAIL;
  }

  // Check if the type is already set and if so reject any type that's not identical
  if (OutputTypeSet(dwOutputStreamIndex)) 
  {
    if(pmt->majortype   == OutputType(dwOutputStreamIndex)->majortype &&
       pmt->subtype     == OutputType(dwOutputStreamIndex)->subtype &&
       pmt->lSampleSize == OutputType(dwOutputStreamIndex)->lSampleSize &&
       pmt->formattype  == OutputType(dwOutputStreamIndex)->formattype &&
       pmt->cbFormat    == OutputType(dwOutputStreamIndex)->cbFormat &&
       0 == memcmp(pmt->pbFormat, OutputType(dwOutputStreamIndex)->pbFormat, pmt->cbFormat)) 
    {
      return S_OK;
    } 
    else 
    {
      DP_ERROR((TEXT("InternalCheckOutputType OutputType is set but different")));
      return DMO_E_INVALIDTYPE;
    }
  }

  if (!InputTypeSet(0)) 
  {
    DP_ERROR((TEXT("InternalCheckOutputType InputType not set")));
    return DMO_E_INVALIDTYPE;
  }

  if (pmt->majortype == MEDIATYPE_Video &&
    pmt->subtype == MEDIASUBTYPE_Overlay)
  {
    return S_OK;
  }
  DP_INFO((TEXT("InternalCheckOutputType returning DMO_E_INVALIDTYPE")));
  return DMO_E_INVALIDTYPE;
}


HRESULT CH264Dmo::InternalGetInputType(DWORD dwInputStreamIndex, DWORD dwTypeIndex,
                                         DMO_MEDIA_TYPE *pmt)
{
  DP_FUNC((TEXT("InternalGetInputType")));
  //Verfiy that we loaded the decoder properly
  if (m_hDecoder == M_HANDLE_INVALID)
  {
    DP_ERROR((TEXT("InternalGetInputType FAILED No Decoder")));
    return E_FAIL;
  }

  if (pmt && dwTypeIndex == 0)
  {
    pmt->majortype = MEDIATYPE_Video;
    pmt->subtype = MEDIASUBTYPE_H264;
    pmt->formattype = FORMAT_None;
    return S_OK;
  }
  return DMO_E_NO_MORE_ITEMS;
}

HRESULT CH264Dmo::InternalGetOutputType(DWORD dwOutputStreamIndex, DWORD dwTypeIndex,
                                          DMO_MEDIA_TYPE *pmt)
{
  DP_FUNC((TEXT("InternalGetOutputType")));
  HRESULT hr = S_OK;

  //Verfiy that we loaded the decoder properly
  if (m_hDecoder == M_HANDLE_INVALID)
  {
    DP_ERROR((TEXT("InternalGetOutputType FAILED No Decoder")));
    return E_FAIL;
  }

⌨️ 快捷键说明

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