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

📄 h264.cpp

📁 This the source release kit for the following system configuration(s): - AMD Alchemy(TM) DBAu1200(
💻 CPP
📖 第 1 页 / 共 3 页
字号:
          return E_FAIL;
        } else
        {
          //Success buffer written to decoder, tell decoder to process this buffer so we can release it
          int eReadResult = DIU_STATUS_OK;
          unsigned char *pbuf = NULL;
          unsigned int flags = 0;
          LONGLONG pts = 0;
          unsigned int size = 0;

          eReadResult = DIUComp_GetBuffer(m_hDecoder, pbuf, &size, &pts, &flags);
          if (eReadResult!=DIU_STATUS_OK && eReadResult!=DIU_STATUS_NEEDMOREINPUT)
          {
            DP_ERROR((TEXT("ProcessInput DIUComp_GetBuffer(m_hDecoder) Send Header failed: 0x%08X"), eReadResult));
            return E_FAIL;
          }
          DP_INFO((TEXT("ProcessInput Send Header complete(%d)"), ulHeaderSize));
        }
        MoFreeMediaType(&mtInput);
      }
      else if (mtInput.formattype == FORMAT_VideoInfo)
      {
        VIDEOINFOHEADER* pvih = (VIDEOINFOHEADER*)mtInput.pbFormat;
        unsigned long ulHeaderSize = sizeof(VIDEOINFOHEADER);
        unsigned char *pHeaderBuf = (unsigned char*)pvih;
        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("Process DIUComp_PutBuffer(m_hDecoder) Send Header failed: 0x%08X"), eWriteResult));
          return E_FAIL;
        } else
        {
          //Success buffer written to decoder, tell decoder to process this buffer so we can release it
          int eReadResult = DIU_STATUS_OK;
          unsigned char *pbuf = NULL;
          unsigned int flags = 0;
          LONGLONG pts = 0;
          unsigned int size = 0;

          eReadResult = DIUComp_GetBuffer(m_hDecoder, pbuf, &size, &pts, &flags);
          if (eReadResult!=DIU_STATUS_OK && eReadResult!=DIU_STATUS_NEEDMOREINPUT)
          {
            DP_ERROR((TEXT("ProcessInput DIUComp_GetBuffer(m_hDecoder) Send Header failed: 0x%08X"), eReadResult));
            return E_FAIL;
          }
          DP_INFO((TEXT("ProcessInput Send Header complete(%d)"), ulHeaderSize));
        }
        MoFreeMediaType(&mtInput);
      }
      else
      {
        DP_ERROR((TEXT("GetInputCurrentType() returned unsupported format")));
        DP_INFO((TEXT("  formattype {%08X-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X}"), mtInput.formattype.Data1, mtInput.formattype.Data2, mtInput.formattype.Data3, mtInput.formattype.Data4[0],
          mtInput.formattype.Data4[1], mtInput.formattype.Data4[2], mtInput.formattype.Data4[3], mtInput.formattype.Data4[4], mtInput.formattype.Data4[5], mtInput.formattype.Data4[6], mtInput.formattype.Data4[7]));
        
        MoFreeMediaType(&mtInput);
        return E_FAIL;
      }
    }
    m_bSentHeader = true;
  }

  if (dwDMOFlags & DMO_INPUT_DATA_BUFFERF_TIME)
  {
    //Codecs expect time stamps to be in milliseconds instead of 100ns units of dshow
    tStartMS = (LONGLONG)(rtTimestamp/10000);
    dwFlags |= DIU_FLAG_PTS;
  }
  
  hr = pBuffer->GetBufferAndLength(&pInBuf, &ulDataSize);
  if (FAILED(hr)) 
  {
    DP_ERROR((TEXT("InternalProcessInput GetBufferAndLength FAILED (0x%08X)"), hr));
    return hr;
  }
  
  hr = pBuffer->GetMaxLength(&ulMaxSize);
  if (FAILED(hr)) 
  {
    DP_ERROR((TEXT("InternalProcessInput GetMaxLength FAILED (0x%08X)"), hr));
    return hr;
  }
  
  //Hold the pointer to the buffer
  m_pBuffer = pBuffer;

  if (ulDataSize < ulMaxSize)
  {
    //here we set frame ending if less than max size
    // If it is equal (will never be greater) to max size then we have 2 outcomes
    // 1- we broke up a frame so don't send the frame end flag (it will be sent on 
    //    next time through when it is less than max size) or
    // 2- the frame is exactly the size of the buffer (unlikely) in which case we won't
    //    set the frame end which is okay will just delay the decode to next frame until
    //    the next frame end flag.  It is highly improbable to have more than one frame
    //    in a row equal to max size
    dwFlags |= DIU_FLAG_FRAMEEND;
  }
  
  if (m_bDiscontinuity)
  {
    //this is first new sample after discountinuity
    dwFlags |= DIU_FLAG_DATADISCON;
    m_bDiscontinuity = false;
    DP_INFO((TEXT("InternalProcessInput DATADISCON")));
  }
  #ifdef DUMP_FILE
    fwrite(pInBuf, 1, ulDataSize, s_InDataFile);
  #endif
#ifdef DUMP_STANDALONE_FILE
    if (s_TestFile)
    {
      STANDALONE_FRAME_HEADER FrameHdr;
      memset(&FrameHdr, 0, sizeof(STANDALONE_FRAME_HEADER));
      char* Padding[3] = {00,00,00};
      unsigned int nPad = 0;
      FrameHdr.frameID[0] = 'S'; 
      FrameHdr.frameID[1] = 'A'; 
      FrameHdr.frameID[2] = 'D'; 
      FrameHdr.frameID[3] = 'F'; 
      FrameHdr.flags = dwFlags;
      FrameHdr.pts = tStartMS;
      //align to 4 byte boundary
      FrameHdr.nFrameSize = (sizeof(STANDALONE_FRAME_HEADER) + ulDataSize)+3 &~3;
      FrameHdr.nPayloadSize = ulDataSize;
      //write frame header structure
      fwrite(&FrameHdr, 1, sizeof(STANDALONE_FRAME_HEADER), s_TestFile);
      //write actual frame data
      fwrite(pInBuf, 1, ulDataSize, s_TestFile);
      //write the padding bytes
      nPad = FrameHdr.nFrameSize - (sizeof(STANDALONE_FRAME_HEADER) + ulDataSize);
      fwrite(Padding, 1, nPad, s_TestFile);
    }
#endif

  if ((dwDMOFlags&DMO_INPUT_DATA_BUFFERF_TIME) == DMO_INPUT_DATA_BUFFERF_TIME)
  {
    DP_DATA((TEXT("InternalProcessInput Calling DIUComp_PutBuffer(%d) pts(%d)"), ulDataSize, (DWORD)tStartMS));
  }else
  {
    DP_DATA((TEXT("InternalProcessInput Calling DIUComp_PutBuffer(%d) no pts"), ulDataSize));
  }
  eWriteResult = DIUComp_PutBuffer(m_hDecoder, pInBuf, ulDataSize, tStartMS, dwFlags, dwDMOFlags);

  if (eWriteResult != DIU_STATUS_OK)
  {
    DP_ERROR((TEXT("InternalProcessInput DIUComp_PutBuffer(m_hDecoder) failed: 0x%08X"), eWriteResult));
    hr = E_FAIL;
  } else
  {
    if ((dwDMOFlags&DMO_INPUT_DATA_BUFFERF_TIME) == DMO_INPUT_DATA_BUFFERF_TIME)
    {
      DP_DATA((TEXT("InternalProcessInput DIUComp_PutBuffer(%d) pts(%d) complete"), ulDataSize, (DWORD)tStartMS));
    }else
    {
      DP_DATA((TEXT("InternalProcessInput DIUComp_PutBuffer(%d) no pts complete"), ulDataSize));
    }
    //Success buffer written to decoder
    hr = S_OK;
  }

  DP_INFO((TEXT("InternalProcessInput: returned 0x%X"), hr));
  return hr;
}

HRESULT CH264Dmo::InternalProcessOutput(DWORD dwFlags, DWORD cOutputBufferCount, DMO_OUTPUT_DATA_BUFFER *pOutputBuffers, DWORD *pdwStatus)
{
  int eReadResult = DIU_STATUS_OK;
  PBYTE pbData = NULL;
  DWORD cbMaxSize = 0;
  DWORD cbCurrentSize = 0;
  pOutputBuffers->dwStatus = 0;
  unsigned char *pbuf = NULL;
  unsigned int flags = 0;
  LONGLONG pts = 0;
  unsigned int size = 0;

  DP_FUNC((TEXT("InternalProcessOutput(count=%d) enter"), cOutputBufferCount));

  //this is to initialize the stop time since there is an error in the framework where the stop
  // position may not get initialized and could be some very large value delaying EOS processing
  pOutputBuffers->rtTimelength = 1;
  pOutputBuffers->dwStatus |= DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH;

  HRESULT hr = pOutputBuffers->pBuffer->GetBufferAndLength(&pbData, &cbCurrentSize);
  if (FAILED(hr)) 
  {
    DP_ERROR((TEXT("InternalProcessOutput GetBufferAndLength failed: hr=0x%X"), hr)); 
    return hr;
  }

  hr = pOutputBuffers->pBuffer->GetMaxLength(&cbMaxSize);
  if (FAILED(hr)) 
  {
    DP_ERROR((TEXT("InternalProcessOutput GetMaxLength failed: hr=0x%X"), hr)); 
    return hr;
  }

  m_bFrame = FALSE;
  pbuf = pbData;
  size = cbMaxSize;
  
  DP_DATA((TEXT("InternalProcessOutput Calling DIUComp_GetBuffer")));
  eReadResult = DIUComp_GetBuffer(m_hDecoder, pbuf, &size, &pts, &flags);
  
  if (eReadResult == DIU_STATUS_OK || eReadResult == DIU_STATUS_NEEDMOREINPUT)
  {
    DP_INFO((TEXT("DIUComp_GetBuffer output %d  flags %x  pts %u"), size, flags, (unsigned int)pts));
    
    if (flags & DIU_FLAG_NEWFORMAT) /* check for format data */
    {
      DIUMediaType_s *pMT = (DIUMediaType_s *)pbuf;
      DP_INFO((TEXT("Process() New Format: DataSize=%d"), size));
      if (pMT->eMType == DIU_MTYPE_VIDEO)
      {
        DIUMediaTypeVideo_t *pVideoInfo=(DIUMediaTypeVideo_t *)pbuf;
        DP_DATA((TEXT("  Video Format: subtype=0x%X size=%d x %d"), pVideoInfo->MediaTypeInfo.eMSubtype,
          pVideoInfo->uiFinalWidth, pVideoInfo->uiFinalHeight));
      }
    }
    else if (size > 0) /* must be decoded data, so we can pass to renderer */
    {
      //we will get buffers of size 1 since its going to hardware
      m_bFrame = true;
#ifdef DUMP_FILE
      fwrite(pbuf, 1, size, s_OutDataFile);
#endif  
      /* update the length of the buffer */
      hr = pOutputBuffers->pBuffer->SetLength(size);
      if ((flags&DMO_OUTPUT_DATA_BUFFERF_TIME) == DMO_OUTPUT_DATA_BUFFERF_TIME)
      {
        DP_DATA((TEXT("InternalProcessOutput Output(%d) timestamp(%d)"), size, (DWORD)pts));
        pOutputBuffers->dwStatus |= DMO_OUTPUT_DATA_BUFFERF_TIME;
        pOutputBuffers->rtTimestamp = pts * 10000; /* Convert codec millisec timestamps back to dshow time */
      } else
      {
        DP_DATA((TEXT("InternalProcessOutput Output(%d) no timestamp"), size));
      }
    }
    if (eReadResult == DIU_STATUS_OK)
    {
      //processed a buffer but still have input data left, signal another call to process output
      pOutputBuffers->dwStatus |= DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE;
    } else
    {
      //We used up all the data in the write buffer release the input buffer
      DP_DATA((TEXT("DIUComp_ReadBuffer() NEEDMOREINPUT")));
      pOutputBuffers->dwStatus &= ~DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE;
      m_pBuffer = NULL;
    }
  } 
  else
  {
    if (eReadResult == DIU_STATUS_UNSUPPORTEDFORMAT || eReadResult == DIU_STATUS_OPENERROR) 
    {
      //don't output error statement on unsupported formats or when newpred is detected
      DP_INFO((TEXT("Process DIUComp_GetBuffer(m_hDecoder) failed: 0x%08X"), eReadResult));
    } else
    {
      DP_ERROR((TEXT("Process DIUComp_GetBuffer(m_hDecoder) failed: 0x%08X"), eReadResult));
    }
    return E_FAIL;
  }
  return m_bFrame ? S_OK : S_FALSE;
}

⌨️ 快捷键说明

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