コード例 #1
0
ファイル: DTSDecoder.cpp プロジェクト: jeeb/lavfilters
HRESULT CLAVAudio::InitDTSDecoder()
{
  if (!m_hDllExtraDecoder) {
    // Add path of LAVAudio.ax into the Dll search path
    WCHAR wModuleFile[1024];
    GetModuleFileName(g_hInst, wModuleFile, 1024);
    PathRemoveFileSpecW(wModuleFile);
    wcscat_s(wModuleFile, TEXT("\\dtsdecoderdll.dll"));

    // Try loading from the filters directory
    HMODULE hDll = LoadLibraryEx(wModuleFile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
    // And try from any global directories if this failed
    if (hDll == NULL) {
      hDll = LoadLibrary(TEXT("dtsdecoderdll.dll"));
    }
    CheckPointer(hDll, E_FAIL);

    m_hDllExtraDecoder = hDll;
  }

  DTSDecoder *context = new DTSDecoder();

  context->pDtsOpen = (DtsOpen)GetProcAddress(m_hDllExtraDecoder, "DtsApiDecOpen");
  if(!context->pDtsOpen) goto fail;

  context->pDtsClose = (DtsClose)GetProcAddress(m_hDllExtraDecoder, "DtsApiDecClose");
  if(!context->pDtsClose) goto fail;

  context->pDtsReset = (DtsReset)GetProcAddress(m_hDllExtraDecoder, "DtsApiDecReset");
  if(!context->pDtsReset) goto fail;

  context->pDtsSetParam = (DtsSetParam)GetProcAddress(m_hDllExtraDecoder, "DtsApiDecSetParam");
  if(!context->pDtsSetParam) goto fail;

  context->pDtsDecode = (DtsDecode)GetProcAddress(m_hDllExtraDecoder, "DtsApiDecodeData");
  if(!context->pDtsDecode) goto fail;

  context->dtsContext = context->pDtsOpen();
  if(!context->dtsContext) goto fail;

  context->dtsPCMBuffer = (BYTE *)av_mallocz(LAV_AUDIO_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);

  m_DTSBitDepth = 24;
  m_DTSDecodeChannels = 8;

  m_pDTSDecoderContext = context;

  FlushDTSDecoder();

  return S_OK;
fail:
  SAFE_DELETE(context);
  FreeLibrary(m_hDllExtraDecoder);
  m_hDllExtraDecoder = NULL;
  return E_FAIL;
}
コード例 #2
0
ファイル: DTSDecoder.cpp プロジェクト: 1pi/LAVFilters
HRESULT CLAVAudio::InitDTSDecoder()
{
  if (!m_hDllExtraDecoder) {
    // Add path of LAVAudio.ax into the Dll search path
    WCHAR wModuleFile[1024];
    GetModuleFileName(g_hInst, wModuleFile, 1024);
    PathRemoveFileSpecW(wModuleFile);
    wcscat_s(wModuleFile, TEXT("\\dtsdecoderdll.dll"));

    // Try loading from the filters directory
    HMODULE hDll = LoadLibraryEx(wModuleFile, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);
    // And try from any global directories if this failed
    if (hDll == nullptr) {
      hDll = LoadLibrary(TEXT("dtsdecoderdll.dll"));
    }
    CheckPointer(hDll, E_FAIL);

    BOOL bIncompatibleDecoder = FALSE;
    if (GetModuleFileName(hDll, wModuleFile, 1024) > 0) {
      DWORD dwVersionSize = GetFileVersionInfoSize(wModuleFile, nullptr);
      if (dwVersionSize > 0) {
        void *versionInfo = CoTaskMemAlloc(dwVersionSize);
        BOOL bVersionInfoPresent = GetFileVersionInfo(wModuleFile, 0, dwVersionSize, versionInfo);
        if (bVersionInfoPresent) {
          VS_FIXEDFILEINFO *info;
          unsigned cbInfo;
          BOOL bInfoPresent = VerQueryValue(versionInfo, TEXT("\\"), (LPVOID*)&info, &cbInfo);
          if (bInfoPresent) {
            bInfoPresent = bInfoPresent;
            uint64_t version = info->dwFileVersionMS;
            version <<= 32;
            version += info->dwFileVersionLS;
            if (version && version < 0x0001000100000000i64)
              bIncompatibleDecoder = TRUE;
          }
        }
        CoTaskMemFree(versionInfo);
      }

    }

    if (bIncompatibleDecoder) {
      FreeLibrary(hDll);
      hDll = nullptr;
      return E_FAIL;
    }

    m_hDllExtraDecoder = hDll;
  }

  DTSDecoder *context = new DTSDecoder();

  context->pDtsOpen = (DtsOpen)GetProcAddress(m_hDllExtraDecoder, "DtsApiDecOpen");
  if(!context->pDtsOpen) goto fail;

  context->pDtsClose = (DtsClose)GetProcAddress(m_hDllExtraDecoder, "DtsApiDecClose");
  if(!context->pDtsClose) goto fail;

  context->pDtsReset = (DtsReset)GetProcAddress(m_hDllExtraDecoder, "DtsApiDecReset");
  if(!context->pDtsReset) goto fail;

  context->pDtsSetParam = (DtsSetParam)GetProcAddress(m_hDllExtraDecoder, "DtsApiDecSetParam");
  if(!context->pDtsSetParam) goto fail;

  context->pDtsDecode = (DtsDecode)GetProcAddress(m_hDllExtraDecoder, "DtsApiDecodeData");
  if(!context->pDtsDecode) goto fail;

  context->dtsContext = context->pDtsOpen();
  if(!context->dtsContext) goto fail;

  context->dtsPCMBuffer = (BYTE *)av_mallocz(LAV_AUDIO_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);

  m_DTSBitDepth = 24;
  m_DTSDecodeChannels = 8;

  m_pDTSDecoderContext = context;

  FlushDTSDecoder();

  return S_OK;
fail:
  SAFE_DELETE(context);
  FreeLibrary(m_hDllExtraDecoder);
  m_hDllExtraDecoder = nullptr;
  return E_FAIL;
}
コード例 #3
0
ファイル: DTSDecoder.cpp プロジェクト: 1pi/LAVFilters
HRESULT CLAVAudio::DecodeDTS(const BYTE * pDataBuffer, int buffsize, int &consumed, HRESULT *hrDeliver)
{
  HRESULT hr = S_FALSE;
  int nPCMLength	= 0;

  BOOL bFlush = (pDataBuffer == nullptr);

  BufferDetails out;

  consumed = 0;
  while (buffsize > 0) {
    nPCMLength = 0;
    if (bFlush) buffsize = 0;

    ASSERT(m_pParser);

    BYTE *pOut = nullptr;
    int pOut_size = 0;
    int used_bytes = av_parser_parse2(m_pParser, m_pAVCtx, &pOut, &pOut_size, pDataBuffer, buffsize, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
    if (used_bytes < 0) {
      return E_FAIL;
    } else if(used_bytes == 0 && pOut_size == 0) {
      DbgLog((LOG_TRACE, 50, L"::Decode() - could not process buffer, starving?"));
      break;
    }

    // Timestamp cache to compensate for one frame delay the parser might introduce, in case the frames were already perfectly sliced apart
    // If we used more (or equal) bytes then was output again, we encountered a new frame, update timestamps
    if (used_bytes >= pOut_size && m_bUpdateTimeCache) {
      m_rtStartInputCache = m_rtStartInput;
      m_rtStopInputCache = m_rtStopInput;
      m_rtStartInput = m_rtStopInput = AV_NOPTS_VALUE;
      m_bUpdateTimeCache = FALSE;
    }

    if (!bFlush && used_bytes > 0) {
      buffsize -= used_bytes;
      pDataBuffer += used_bytes;
      consumed += used_bytes;
    }

    if (pOut && pOut_size > 0) {
      // Parse DTS headers
      m_bsParser.Parse(AV_CODEC_ID_DTS, pOut, pOut_size, nullptr);
      unsigned decode_channels = dts_determine_decode_channels(m_bsParser.m_DTSHeader);

      // Init Decoder with new Parameters, if required
      if (m_DTSDecodeChannels != decode_channels) {
        DbgLog((LOG_TRACE, 20, L"::Decode(): Switching to %d channel decoding", decode_channels));
        m_DTSDecodeChannels = decode_channels;

        FlushDTSDecoder();
      }

      int bitdepth = 0, channels = 0, CoreSampleRate = 0, HDSampleRate = 0, profile = 0;
      int unk4 = 0, unk5 = 0;
      nPCMLength = SafeDTSDecode(pOut, pOut_size, m_pDTSDecoderContext->dtsPCMBuffer, 0, 8, &bitdepth, &channels, &CoreSampleRate, &unk4, &HDSampleRate, &unk5, &profile);
      if (nPCMLength > 0 && bitdepth != m_DTSBitDepth) {
        int decodeBits = bitdepth > 16 ? 24 : 16;

        // If the bit-depth changed, instruct the DTS Decoder to decode to the new bit depth, and decode the previous sample again.
        if (decodeBits != m_DTSBitDepth && out.bBuffer->GetCount() == 0) {
          DbgLog((LOG_TRACE, 20, L"::Decode(): The DTS decoder indicated that it outputs %d bits, changing config to %d bits to compensate", bitdepth, decodeBits));
          m_DTSBitDepth = decodeBits;

          FlushDTSDecoder();
          nPCMLength = SafeDTSDecode(pOut, pOut_size, m_pDTSDecoderContext->dtsPCMBuffer, 0, 2, &bitdepth, &channels, &CoreSampleRate, &unk4, &HDSampleRate, &unk5, &profile);
        }
      }
      if (nPCMLength <= 0) {
        DbgLog((LOG_TRACE, 50, L"::Decode() - DTS decoding failed"));
        FlushDTSDecoder(TRUE);
        m_bQueueResync = TRUE;
        continue;
      }

      out.wChannels        = channels;
      out.dwSamplesPerSec  = HDSampleRate;
      out.sfFormat         = m_DTSBitDepth == 24 ? SampleFormat_24 : SampleFormat_16;
      out.dwChannelMask    = get_channel_mask(channels); // TODO
      out.wBitsPerSample   = bitdepth;

      int profile_index = 0;
      while(profile >>= 1) profile_index++;

      if (profile_index > 7)
        m_pAVCtx->profile =  FF_PROFILE_UNKNOWN;
      else if (profile == 0 && !m_bsParser.m_DTSHeader.HasCore)
        m_pAVCtx->profile = FF_PROFILE_DTS_EXPRESS;
      else
        m_pAVCtx->profile = DTSProfiles[profile_index];

      // TODO: get rid of these
      m_pAVCtx->sample_rate = HDSampleRate;
      m_pAVCtx->bits_per_raw_sample = bitdepth;

      // Send current input time to the delivery function
      out.rtStart = m_rtStartInputCache;
      m_rtStartInputCache = AV_NOPTS_VALUE;
      m_bUpdateTimeCache = TRUE;
    }

    // Send to Output
    if (nPCMLength > 0) {
      hr = S_OK;
      out.bBuffer->Append(m_pDTSDecoderContext->dtsPCMBuffer, nPCMLength);
      out.nSamples = out.bBuffer->GetCount() / get_byte_per_sample(out.sfFormat) / out.wChannels;

      if (m_pAVCtx->profile != (1 << 7)) {
        DTSRemapOutputChannels(&out, m_bsParser.m_DTSHeader);
      }

      m_pAVCtx->channels = out.wChannels;
      m_DecodeFormat = out.sfFormat;
      m_DecodeLayout = out.dwChannelMask;

      if (SUCCEEDED(PostProcess(&out))) {
        *hrDeliver = QueueOutput(out);
        if (FAILED(*hrDeliver)) {
          return S_FALSE;
        }
      }
    }
  }