예제 #1
0
HRESULT CStreamParser::ParsePlanarPCM(Packet *pPacket)
{
  CMediaType mt = m_pPin->GetActiveMediaType();

  WORD nChannels = 0, nBPS = 0, nBlockAlign = 0;
  audioFormatTypeHandler(mt.Format(), mt.FormatType(), nullptr, &nChannels, &nBPS, &nBlockAlign, nullptr);

  // Mono needs no special handling
  if (nChannels == 1)
    return Queue(pPacket);

  Packet *out = new Packet();
  out->CopyProperties(pPacket);
  out->SetDataSize(pPacket->GetDataSize());

  int nBytesPerChannel = nBPS / 8;
  int nAudioBlocks = pPacket->GetDataSize() / nChannels;
  BYTE *out_data = out->GetData();
  const BYTE *in_data = pPacket->GetData();

  for (int i = 0; i < nAudioBlocks; i += nBytesPerChannel) {
    // interleave the channels into audio blocks
    for (int c = 0; c < nChannels; c++) {
      memcpy(out_data + (c * nBytesPerChannel), in_data + (nAudioBlocks * c), nBytesPerChannel);
    }
    // Skip to the next output block
    out_data += nChannels * nBytesPerChannel;

    // skip to the next input sample
    in_data += nBytesPerChannel;
  }

  return Queue(out);
}
예제 #2
0
bool mt2spk(CMediaType mt, Speakers &spk)
{
  const GUID type = *mt.Type();
  const GUID subtype = *mt.Subtype();
  const GUID formattype = *mt.FormatType();

  WAVEFORMAT *wf = 0;
  size_t wf_size = 0;
  int sample_rate = 0;

  if ((formattype == FORMAT_WaveFormatEx) &&
      (mt.FormatLength() > sizeof(WAVEFORMAT)))
  {
    wf = (WAVEFORMAT *)mt.Format();
    wf_size = mt.FormatLength();
    sample_rate = wf->nSamplesPerSec;
  }

  /////////////////////////////////////////////////////////
  // HD LPCM

  if (type == MEDIATYPE_Audio &&
      subtype == MEDIASUBTYPE_HDMV_LPCM_AUDIO &&
      wf && wf->wFormatTag == 1)
  {
    spk = wf2spk(wf, wf_size);
    switch (spk.format)
    {
      case FORMAT_PCM16: spk.format = FORMAT_PCM16_BE; return true;
      case FORMAT_PCM24: spk.format = FORMAT_PCM24_BE; return true;
      case FORMAT_PCM32: spk.format = FORMAT_PCM32_BE; return true;
      default: return false;
    }
  }

  /////////////////////////////////////////////////////////
  // Compressed formats

  if (type == MEDIATYPE_MPEG2_PES ||
      type == MEDIATYPE_MPEG2_PACK ||
      type == MEDIATYPE_DVD_ENCRYPTED_PACK)
    if (subtype == MEDIASUBTYPE_DOLBY_AC3 ||
        subtype == MEDIASUBTYPE_DTS ||
        subtype == MEDIASUBTYPE_MPEG1AudioPayload ||
        subtype == MEDIASUBTYPE_MPEG2_AUDIO ||
        subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO)
    {
      spk = Speakers(FORMAT_PES, 0, sample_rate);
      return true;
    }

  if (subtype == MEDIASUBTYPE_DOLBY_AC3 || 
      subtype == MEDIASUBTYPE_AVI_AC3)
  {
    // It may be AC3 or EAC3
    spk = Speakers(FORMAT_DOLBY, 0, sample_rate);
    return true;
  }

  if (subtype == MEDIASUBTYPE_DOLBY_DDPLUS)
  {
    spk = Speakers(FORMAT_EAC3, 0, sample_rate);
    return true;
  }

  if (subtype == MEDIASUBTYPE_DOLBY_TRUEHD)
  {
    spk = Speakers(FORMAT_TRUEHD, 0, sample_rate);
    return true;
  }

  if (subtype == MEDIASUBTYPE_DTS || 
      subtype == MEDIASUBTYPE_DTS_HD ||
      subtype == MEDIASUBTYPE_AVI_DTS)
  {
    spk = Speakers(FORMAT_DTS, 0, sample_rate);
    return true;
  }

  if (subtype == MEDIASUBTYPE_MPEG1AudioPayload ||
      subtype == MEDIASUBTYPE_MPEG2_AUDIO)
  {
    spk = Speakers(FORMAT_MPA, 0, sample_rate);
    return true;
  }

  if (subtype == MEDIASUBTYPE_DOLBY_AC3_SPDIF)
  {
    spk = Speakers(FORMAT_SPDIF, 0, sample_rate);
    return true;
  }
/*
  if (subtype == MEDIASUBTYPE_Vorbis &&
      formattype == FORMAT_Vorbis && 
      mt.FormatLength() > sizeof(VORBISFORMAT))
  {
    VORBISFORMAT *format = (VORBISFORMAT *)mt.Format();
    spk = Speakers(FORMAT_VORBIS, 0, format->samplesPerSec);
    spk.set_format_data(mt.Format(), mt.FormatLength());
  }
*/
  if (subtype == MEDIASUBTYPE_Vorbis2 &&
      formattype == FORMAT_Vorbis2 &&
      mt.FormatLength() > sizeof(VORBISFORMAT2))
  {
    VORBISFORMAT2 *format = (VORBISFORMAT2 *)mt.Format();
    spk = Speakers(FORMAT_VORBIS, 0, format->samplesPerSec);
    spk.set_format_data(mt.Format(), mt.FormatLength());
    return true;
  }

  /////////////////////////////////////////////////////////
  // LPCM

  if (subtype == MEDIASUBTYPE_DVD_LPCM_AUDIO)
  {
    PCMWAVEFORMAT *pcmwf = wf_cast<PCMWAVEFORMAT>(wf, wf_size);
    if (!pcmwf) return false;

    int format, mode;
    switch (pcmwf->wBitsPerSample)
    {
      case 16: format = FORMAT_PCM16_BE; break;
      case 20: format = FORMAT_LPCM20; break;
      case 24: format = FORMAT_LPCM24; break;
      default: return false;
    }
    switch (pcmwf->wf.nChannels)
    {
      case 1: mode = MODE_MONO; break;
      case 2: mode = MODE_STEREO; break;
      default: return false;
    }
    spk = Speakers(format, mode, sample_rate);
    return true;
  }

  /////////////////////////////////////////////////////////
  // General WAVEFORMAT conversion

  spk = Speakers();
  if (wf)
    spk = wf2spk(wf, wf_size);
  return !spk.is_unknown();
}