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); }
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(); }