Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/LAVFilters.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHendrik Leppkes <h.leppkes@gmail.com>2017-05-10 12:49:13 +0300
committerHendrik Leppkes <h.leppkes@gmail.com>2017-05-10 12:49:13 +0300
commitd8c28b11e1133cc04193bfba3c756e5c1741ec8a (patch)
tree6bef651420bd3888d3b76e1a742991e6044a131a /demuxer
parent90068718f63bd4ce6c3b410c82144351cc4651dd (diff)
Interleave planar PCM after demuxing into a standard packed format
Diffstat (limited to 'demuxer')
-rw-r--r--demuxer/Demuxers/LAVFAudioHelper.cpp25
-rw-r--r--demuxer/Demuxers/LAVFDemuxer.cpp7
-rw-r--r--demuxer/Demuxers/Packet.h1
-rw-r--r--demuxer/LAVSplitter/StreamParser.cpp37
-rw-r--r--demuxer/LAVSplitter/StreamParser.h1
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;