diff options
author | Hendrik Leppkes <h.leppkes@gmail.com> | 2017-05-10 12:49:13 +0300 |
---|---|---|
committer | Hendrik Leppkes <h.leppkes@gmail.com> | 2017-05-10 12:49:13 +0300 |
commit | d8c28b11e1133cc04193bfba3c756e5c1741ec8a (patch) | |
tree | 6bef651420bd3888d3b76e1a742991e6044a131a /demuxer | |
parent | 90068718f63bd4ce6c3b410c82144351cc4651dd (diff) |
Interleave planar PCM after demuxing into a standard packed format
Diffstat (limited to 'demuxer')
-rw-r--r-- | demuxer/Demuxers/LAVFAudioHelper.cpp | 25 | ||||
-rw-r--r-- | demuxer/Demuxers/LAVFDemuxer.cpp | 7 | ||||
-rw-r--r-- | demuxer/Demuxers/Packet.h | 1 | ||||
-rw-r--r-- | demuxer/LAVSplitter/StreamParser.cpp | 37 | ||||
-rw-r--r-- | demuxer/LAVSplitter/StreamParser.h | 1 |
5 files changed, 50 insertions, 21 deletions
diff --git a/demuxer/Demuxers/LAVFAudioHelper.cpp b/demuxer/Demuxers/LAVFAudioHelper.cpp index 54c2f1bb..a48dd34f 100644 --- a/demuxer/Demuxers/LAVFAudioHelper.cpp +++ b/demuxer/Demuxers/LAVFAudioHelper.cpp @@ -50,6 +50,9 @@ static FormatMapping audio_map[] = { { AV_CODEC_ID_PCM_S24LE, &MEDIASUBTYPE_PCM, WAVE_FORMAT_PCM, nullptr }, { AV_CODEC_ID_PCM_S32LE, &MEDIASUBTYPE_PCM, WAVE_FORMAT_PCM, nullptr }, { AV_CODEC_ID_PCM_F32LE, &MEDIASUBTYPE_IEEE_FLOAT, WAVE_FORMAT_IEEE_FLOAT, nullptr }, + { AV_CODEC_ID_PCM_S16LE_PLANAR, &MEDIASUBTYPE_PCM, WAVE_FORMAT_PCM, nullptr }, + { AV_CODEC_ID_PCM_S24LE_PLANAR, &MEDIASUBTYPE_PCM, WAVE_FORMAT_PCM, nullptr }, + { AV_CODEC_ID_PCM_S32LE_PLANAR, &MEDIASUBTYPE_PCM, WAVE_FORMAT_PCM, nullptr }, { AV_CODEC_ID_WMAV1, &MEDIASUBTYPE_MSAUDIO1, WAVE_FORMAT_MSAUDIO1, nullptr }, { AV_CODEC_ID_WMAV2, &MEDIASUBTYPE_WMAUDIO2, WAVE_FORMAT_WMAUDIO2, nullptr }, { AV_CODEC_ID_WMAPRO, &MEDIASUBTYPE_WMAUDIO3, WAVE_FORMAT_WMAUDIO3, nullptr }, @@ -72,6 +75,7 @@ static FormatMapping audio_map[] = { { AV_CODEC_ID_TAK, &MEDIASUBTYPE_TAK, 0, nullptr }, { AV_CODEC_ID_S302M, &MEDIASUBTYPE_AES3, 0, nullptr }, { AV_CODEC_ID_PCM_S16BE, &MEDIASUBTYPE_PCM_TWOS, 0, nullptr }, + { AV_CODEC_ID_PCM_S16BE_PLANAR, &MEDIASUBTYPE_PCM_TWOS, 0, nullptr }, { AV_CODEC_ID_PCM_S24BE, &MEDIASUBTYPE_PCM_IN24, 0, nullptr }, { AV_CODEC_ID_PCM_S32BE, &MEDIASUBTYPE_PCM_IN32, 0, nullptr }, { AV_CODEC_ID_QDM2, &MEDIASUBTYPE_QDM2, WAVE_FORMAT_QDESIGN_MUSIC, nullptr }, @@ -93,27 +97,6 @@ CMediaType CLAVFAudioHelper::initAudioType(AVCodecParameters *codecpar, unsigned mediaType.formattype = FORMAT_WaveFormatEx; //default value mediaType.SetSampleSize(256000); - // map mono planar pcm formats (if its mono, planar makes no difference) - if (codecpar->channels == 1) { - switch (codecpar->codec_id) { - case AV_CODEC_ID_PCM_S8_PLANAR: - codecpar->codec_id = AV_CODEC_ID_PCM_S8; - break; - case AV_CODEC_ID_PCM_S16BE_PLANAR: - codecpar->codec_id = AV_CODEC_ID_PCM_S16BE; - break; - case AV_CODEC_ID_PCM_S16LE_PLANAR: - codecpar->codec_id = AV_CODEC_ID_PCM_S16LE; - break; - case AV_CODEC_ID_PCM_S24LE_PLANAR: - codecpar->codec_id = AV_CODEC_ID_PCM_S24LE; - break; - case AV_CODEC_ID_PCM_S32LE_PLANAR: - codecpar->codec_id = AV_CODEC_ID_PCM_S32LE; - break; - } - } - // Check against values from the map above for(unsigned i = 0; i < countof(audio_map); ++i) { if (audio_map[i].codec == codecpar->codec_id) { diff --git a/demuxer/Demuxers/LAVFDemuxer.cpp b/demuxer/Demuxers/LAVFDemuxer.cpp index 288e3f81..a6556cbb 100644 --- a/demuxer/Demuxers/LAVFDemuxer.cpp +++ b/demuxer/Demuxers/LAVFDemuxer.cpp @@ -1320,6 +1320,13 @@ STDMETHODIMP CLAVFDemuxer::GetNextPacket(Packet **ppPacket) } } + if (stream->codecpar->codec_id == AV_CODEC_ID_PCM_S16BE_PLANAR + || stream->codecpar->codec_id == AV_CODEC_ID_PCM_S16LE_PLANAR + || stream->codecpar->codec_id == AV_CODEC_ID_PCM_S24LE_PLANAR + || stream->codecpar->codec_id == AV_CODEC_ID_PCM_S32LE_PLANAR + ) + pPacket->dwFlags |= LAV_PACKET_PLANAR_PCM; + // Update extradata and send new mediatype, when required int sidedata_size = 0; uint8_t *sidedata = av_packet_get_side_data(&pkt, AV_PKT_DATA_NEW_EXTRADATA, &sidedata_size); diff --git a/demuxer/Demuxers/Packet.h b/demuxer/Demuxers/Packet.h index 76325266..ac083a8f 100644 --- a/demuxer/Demuxers/Packet.h +++ b/demuxer/Demuxers/Packet.h @@ -65,6 +65,7 @@ public: #define LAV_PACKET_FORCED_SUBTITLE 0x0004 #define LAV_PACKET_H264_ANNEXB 0x0008 #define LAV_PACKET_SRT 0x0010 +#define LAV_PACKET_PLANAR_PCM 0x0020 DWORD dwFlags = 0; private: diff --git a/demuxer/LAVSplitter/StreamParser.cpp b/demuxer/LAVSplitter/StreamParser.cpp index 45e40ba7..deefce9a 100644 --- a/demuxer/LAVSplitter/StreamParser.cpp +++ b/demuxer/LAVSplitter/StreamParser.cpp @@ -74,6 +74,8 @@ HRESULT CStreamParser::Parse(const GUID &gSubtype, Packet *pPacket) ParseAAC(pPacket); } else if (m_gSubtype == MEDIASUBTYPE_UTF8 && (pPacket->dwFlags & LAV_PACKET_SRT)) { ParseSRT(pPacket); + } else if ((m_gSubtype == MEDIASUBTYPE_PCM || m_gSubtype == MEDIASUBTYPE_PCM_TWOS) && (pPacket->dwFlags & LAV_PACKET_PLANAR_PCM)) { + ParsePlanarPCM(pPacket); } else { Queue(pPacket); } @@ -440,3 +442,38 @@ HRESULT CStreamParser::ParseSRT(Packet *pPacket) SAFE_DELETE(pPacket); return S_FALSE; } + +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); +} diff --git a/demuxer/LAVSplitter/StreamParser.h b/demuxer/LAVSplitter/StreamParser.h index 9419a988..116d429f 100644 --- a/demuxer/LAVSplitter/StreamParser.h +++ b/demuxer/LAVSplitter/StreamParser.h @@ -41,6 +41,7 @@ private: HRESULT ParseMOVText(Packet *pPacket); HRESULT ParseAAC(Packet *pPacket); HRESULT ParseSRT(Packet *pPacket); + HRESULT ParsePlanarPCM(Packet *pPacket); HRESULT Queue(Packet *pPacket) const; |