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

📄 h264.cpp

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

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

  if (dwTypeIndex != 0) 
  {
    return DMO_E_NO_MORE_ITEMS;
  }

  // If GetOutputType()'s pmt parameter is NULL, return S_OK if the type exists.
  // Return DMO_E_NO_MORE_ITEMS if the type does not exists.  See the 
  // documentation for IMediaObject::GetOutputType() for more information.
  if (NULL != pmt) 
  {
    hr = MoInitMediaType(pmt, sizeof(VIDEOINFOHEADER));
    if (FAILED(hr))
    {
      DP_ERROR((TEXT("MoInitMediaType FAILED (%08X)"),hr));
      return hr;
    } else
    {
      VIDEOINFOHEADER* pvih = (VIDEOINFOHEADER*)pmt->pbFormat;
      memset(pvih, 0, sizeof(VIDEOINFOHEADER));
      DMO_MEDIA_TYPE mtInput;
      hr = GetInputCurrentType(0, &mtInput);
      if (FAILED(hr))
      {
        DP_ERROR((TEXT("GetInputCurrentType FAILED (%08X)"), hr));
        MoFreeMediaType(pmt);
        return hr;
      } else
      {
        if (mtInput.formattype == FORMAT_H264VideoInfo)
        {
          H264VIDEOINFOHEADER* pInH264Vih = (H264VIDEOINFOHEADER*)mtInput.pbFormat;
          if (pvih)
          {
            pvih->rcSource = pInH264Vih->rcSource;
            pvih->rcTarget = pInH264Vih->rcTarget;
            pvih->bmiHeader.biWidth = pInH264Vih->bmiHeader.biWidth;
            pvih->bmiHeader.biHeight = pInH264Vih->bmiHeader.biHeight;
            pvih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
            pvih->bmiHeader.biPlanes = 1;
            pvih->bmiHeader.biBitCount = 8;
            pvih->bmiHeader.biCompression = BI_RGB;
            pvih->bmiHeader.biSizeImage = pvih->bmiHeader.biWidth * pvih->bmiHeader.biHeight * pvih->bmiHeader.biBitCount / 8;
          }
        } else if (mtInput.formattype == FORMAT_VideoInfo)
        {
          VIDEOINFOHEADER* pInVih = (VIDEOINFOHEADER*)mtInput.pbFormat;
          if (pvih)
          {
            pvih->rcSource = pInVih->rcSource;
            pvih->rcTarget = pInVih->rcTarget;
            pvih->bmiHeader.biWidth = pInVih->bmiHeader.biWidth;
            pvih->bmiHeader.biHeight = pInVih->bmiHeader.biHeight;
            pvih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
            pvih->bmiHeader.biPlanes = 1;
            pvih->bmiHeader.biBitCount = 8;
            pvih->bmiHeader.biCompression = BI_RGB;
            pvih->bmiHeader.biSizeImage = pvih->bmiHeader.biWidth * pvih->bmiHeader.biHeight * pvih->bmiHeader.biBitCount / 8;
          }
        } else
        {
          //Set some defaults
          DP_INFO((TEXT("VideoInfo not found on Input pin using defaults")));
          if (pvih)
          {
            pvih->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
            pvih->bmiHeader.biWidth = 720;
            pvih->bmiHeader.biHeight = 480;
            pvih->bmiHeader.biPlanes = 1;
            pvih->bmiHeader.biBitCount = 8;
            pvih->bmiHeader.biCompression = BI_RGB;
            pvih->bmiHeader.biSizeImage = pvih->bmiHeader.biWidth * pvih->bmiHeader.biHeight * pvih->bmiHeader.biBitCount / 8;
          }
        }
        MoFreeMediaType(&mtInput);
      }
      pmt->majortype = MEDIATYPE_Video;
      pmt->subtype = MEDIASUBTYPE_Overlay;
      pmt->bFixedSizeSamples = FALSE;
      pmt->bTemporalCompression = FALSE;
      pmt->formattype = FORMAT_VideoInfo;
      pmt->lSampleSize = pvih->bmiHeader.biSizeImage;
      pmt->cbFormat = sizeof(VIDEOINFOHEADER);
      return S_OK;
    }
  }
  DP_ERROR((TEXT("GetInputCurrentType FAILED to get valid media type)")));
  return E_FAIL;
}

HRESULT CH264Dmo::InternalGetInputSizeInfo(DWORD dwInputStreamIndex, DWORD *pcbSize,
                                             DWORD *pcbMaxLookahead, DWORD *pcbAlignment)
{
  DP_FUNC((TEXT("InternalGetInputSizeInfo")));
  *pcbSize = 1;
  *pcbMaxLookahead = 0;
  *pcbAlignment = 1;
  return S_OK;
}

HRESULT CH264Dmo::InternalGetOutputSizeInfo(DWORD dwOutputStreamIndex, DWORD *pcbSize,
                                              DWORD *pcbAlignment)
{
  DP_FUNC((TEXT("InternalGetOutputSizeInfo")));
  *pcbAlignment = 1;
  *pcbSize = OUTPUT_BUFFER_SIZE;
  return S_OK;
}

HRESULT CH264Dmo::InternalGetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME *prtMaxLatency)
{
  DP_FUNC((TEXT("InternalGetInputMaxLatency")));
  return E_NOTIMPL;
}

HRESULT CH264Dmo::InternalSetInputMaxLatency(DWORD dwInputStreamIndex, REFERENCE_TIME rtMaxLatency)
{
  DP_FUNC((TEXT("InternalSetInputMaxLatency")));
  return E_NOTIMPL;
}

HRESULT CH264Dmo::InternalFlush()
{
  DP_INFO((TEXT("InternalFlush")));
  #ifdef DUMP_FILE
    //close the dump files on flush
    if (s_InDataFile)
    {
      fclose(s_InDataFile);
      s_InDataFile = NULL;
    }
    if (s_OutDataFile)
    {
      fclose(s_OutDataFile);
      s_OutDataFile = NULL;
    }
    //open new dump file
    _tcscat(g_szInDataFile, TEXT("+")); 
    _tcscat(g_szOutDataFile, TEXT("+")); 
    s_InDataFile  = _tfopen(g_szInDataFile, TEXT("wb"));
    s_OutDataFile = _tfopen(g_szOutDataFile, TEXT("wb"));
  #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
  DIUComp_Empty(m_hDecoder);
  m_rtNow = m_rtOld = 0;
  m_pBuffer = NULL;
  m_bFrame = false;
  return S_OK;
}

HRESULT CH264Dmo::InternalDiscontinuity(DWORD dwInputStreamIndex)
{
  DP_INFO((TEXT("InternalDiscontinuity")));
  m_bDiscontinuity   = true;
  return S_OK;
}

HRESULT CH264Dmo::InternalAllocateStreamingResources()
{
  DP_FUNC((TEXT("InternalAllocateStreamingResources")));
  //TODO allocate memory here
  return S_OK;
}

HRESULT CH264Dmo::InternalFreeStreamingResources()
{
  DP_FUNC((TEXT("InternalFreeStreamingResources")));
  //TODO release allocated memory here
  return S_OK;
}

HRESULT CH264Dmo::InternalAcceptingInput(DWORD dwInputStreamIndex)
{
  HRESULT hr = (m_pBuffer == NULL) ? S_OK : S_FALSE;
  DP_FUNC((TEXT("InternalAcceptingInput() hr=0x%08X"), hr));
  return hr;
}

// IDMOQualityControl function
STDMETHODIMP CH264Dmo::SetNow(REFERENCE_TIME rtNow) 
{
  // Remember SetNow values even if quality control is not currently enabled
  CDMOAutoLock l(&m_cs);
  if (m_bQualityControlEnabled)
  {
    m_rtNow = rtNow;
    DP_INFO((TEXT("m_rtNow(ms)=%d : LastUpdate(ms)=%d"), (DWORD)(m_rtNow/10000), (DWORD)(m_rtOld/10000)));
#ifdef DMO_QC_PROCESS
    // only update if its been atleast 100ms since last update
    if (m_rtNow>=(m_rtOld+1000000))
    {
      DWORD dwCurrentTime = (DWORD)(m_rtNow/10000);
      m_rtOld = m_rtNow;
      
      DP_INFO((TEXT("QC Time(ms): %d"), dwCurrentTime));
      DIUComp_UpdateSync(m_hDecoder, dwCurrentTime);
    }
#endif //DMO_QC_PROCESS
  }
  return NOERROR;
}

// IDMOQualityControl function
STDMETHODIMP CH264Dmo::SetStatus(DWORD dwFlags) 
{
  // Any point in grabbing the object lock here ?
  if (dwFlags & DMO_QUALITY_STATUS_ENABLED) {
    DP_INFO((TEXT("QC enabled")));
    m_bQualityControlEnabled = TRUE;
  }
  else {
    DP_INFO((TEXT("QC disabled")));
    m_bQualityControlEnabled = FALSE;
  }
  return NOERROR;
}

HRESULT CH264Dmo::InternalProcessInput(DWORD dwInputStreamIndex, IMediaBuffer *pBuffer,
                                         DWORD dwDMOFlags, REFERENCE_TIME rtTimestamp,
                                         REFERENCE_TIME rtTimelength)
{
  DP_FUNC((TEXT("InternalProcessInput")));
  //  Check parameters
  _ASSERTE(m_pBuffer == NULL);

  unsigned long ulDataSize = 0;
  unsigned char *pInBuf;
  unsigned long ulMaxSize = 0;
  LONGLONG tStartMS = 0;
  int eWriteResult = DIU_STATUS_OK;
  HRESULT hr = S_OK;
  unsigned int dwFlags = 0;

  DP_INFO((TEXT("ProcessInput Current sample Timestamp(ms): %d"), (DWORD)(rtTimestamp/10000)));

  if (!m_bSentHeader)
  {
    DP_INFO((TEXT("InternalProcessInput Sending Header to decoder")));
    DMO_MEDIA_TYPE mtInput;
    hr = GetInputCurrentType(0, &mtInput);
    if (FAILED(hr))
    {
      DP_ERROR((TEXT("GetInputCurrentType FAILED (%08X)")));
      return hr;
    } else
    {
      if (mtInput.formattype == FORMAT_H264VideoInfo)
      {
        H264VIDEOINFOHEADER* pvih = (H264VIDEOINFOHEADER*)mtInput.pbFormat;
        unsigned long ulHeaderSize = pvih->vihSize - sizeof(H264VIDEOINFOHEADER);
        unsigned char *pHeaderBuf = (unsigned char*)pvih + sizeof(H264VIDEOINFOHEADER);
        unsigned int dwHeaderFlags = DIU_FLAG_NEWFORMAT | DIU_FLAG_FRAMEEND;
        
#ifdef DUMP_STANDALONE_FILE
        if (s_TestFile)
        {
          STANDALONE_FILE_HEADER FileHdr;
          memset(&FileHdr, 0, sizeof(STANDALONE_FILE_HEADER));
          char* Padding[3] = {00,00,00};
          unsigned int nPad = 0;
          FileHdr.fileID[0] = 'S'; 
          FileHdr.fileID[1] = 'A'; 
          FileHdr.fileID[2] = 'D'; 
          FileHdr.fileID[3] = 'H'; 
          FileHdr.format[0] = 'H'; 
          FileHdr.format[1] = '2'; 
          FileHdr.format[2] = '6'; 
          FileHdr.format[3] = '4'; 
          FileHdr.flags = dwHeaderFlags;
          FileHdr.width = pvih->bmiHeader.biWidth;
          FileHdr.height = pvih->bmiHeader.biHeight;
          //align to 4 byte boundary
          FileHdr.nHeaderSize = (sizeof(STANDALONE_FILE_HEADER) + ulHeaderSize)+3 &~3;
          FileHdr.nPayloadSize = ulHeaderSize;
          //write file header structure
          fwrite(&FileHdr, 1, sizeof(STANDALONE_FILE_HEADER), s_TestFile);
          //write actual decoder header data
          fwrite(pHeaderBuf, 1, ulHeaderSize, s_TestFile);
          //write the padding bytes
          nPad = FileHdr.nHeaderSize - (sizeof(STANDALONE_FILE_HEADER) + ulHeaderSize);
          fwrite(Padding, 1, nPad, s_TestFile);
        }
#endif
        eWriteResult = DIUComp_PutBuffer(m_hDecoder, pHeaderBuf, ulHeaderSize, 0, dwHeaderFlags, 0);
        if (eWriteResult!=DIU_STATUS_OK)
        {
          DP_ERROR((TEXT("ProcessInput DIUComp_PutBuffer(m_hDecoder) Send Header failed: 0x%08X"), eWriteResult));

⌨️ 快捷键说明

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