Skip to content

Commit

Permalink
MpegSplitter - улучшен парсинг DTS-HD дорожек.
Browse files Browse the repository at this point in the history
Улучшены проверки DTS-HD HRA профиля - так же учитываем и DTS:X профили (это конечно хоть и редкость, но бывает).
  • Loading branch information
Aleksoid1978 committed Jul 16, 2024
1 parent 865c311 commit 5cac357
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 32 deletions.
4 changes: 2 additions & 2 deletions src/filters/parser/MP4Splitter/MP4Splitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ HRESULT CMP4SplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader)
wfe->wBitsPerSample = aframe.param1;
}
wfe->nBlockAlign = (wfe->nChannels * wfe->wBitsPerSample) / 8;
if (aframe.param2 == DCA_PROFILE_HD_HRA) {
if (aframe.param2 == DCA_PROFILE_HD_HRA || aframe.param2 == DCA_PROFILE_HD_HRA_X || aframe.param2 == DCA_PROFILE_HD_HRA_X_IMAX) {
wfe->nAvgBytesPerSec += CalcBitrate(aframe) / 8;
} else {
wfe->nAvgBytesPerSec = 0;
Expand Down Expand Up @@ -1820,7 +1820,7 @@ HRESULT CMP4SplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader)
wfe->wBitsPerSample = aframe.param1;
}
wfe->nBlockAlign = (wfe->nChannels * wfe->wBitsPerSample) / 8;
if (aframe.param2 == DCA_PROFILE_HD_HRA) {
if (aframe.param2 == DCA_PROFILE_HD_HRA || aframe.param2 == DCA_PROFILE_HD_HRA_X || aframe.param2 == DCA_PROFILE_HD_HRA_X_IMAX) {
// DTS-HD High Resolution Audio
wfe->nAvgBytesPerSec += CalcBitrate(aframe) / 8;
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/filters/parser/MatroskaSplitter/MatroskaSplitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1254,7 +1254,7 @@ HRESULT CMatroskaSplitterFilter::CreateOutputs(IAsyncReader* pAsyncReader)
wfe->wBitsPerSample = aframe.param1;
}
wfe->nBlockAlign = wfe->nChannels * wfe->wBitsPerSample / 8;
if (aframe.param2 == DCA_PROFILE_HD_HRA) {
if (aframe.param2 == DCA_PROFILE_HD_HRA || aframe.param2 == DCA_PROFILE_HD_HRA_X || aframe.param2 == DCA_PROFILE_HD_HRA_X_IMAX) {
wfe->nAvgBytesPerSec += CalcBitrate(aframe) / 8;
} else {
wfe->nAvgBytesPerSec = 0;
Expand Down
16 changes: 12 additions & 4 deletions src/filters/parser/MpegSplitter/MpegSplitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,10 +398,18 @@ static CString GetMediaTypeDesc(const CMediaType *pMediaType, const CHdmvClipInf
}
break;
case WAVE_FORMAT_DTS2: {
if (pPresentationDesc) {
Infos.emplace_back(pPresentationDesc);
} else {
Infos.emplace_back(L"DTS");
CStringW codecName;
if (pInfo->cbSize == 1) {
const auto profile = (reinterpret_cast<const BYTE*>(pInfo + 1))[0];
GetDTSHDDescription(profile, codecName);
Infos.emplace_back(codecName);
}
if (codecName.IsEmpty()) {
if (pPresentationDesc) {
Infos.emplace_back(pPresentationDesc);
} else {
Infos.emplace_back(L"DTS");
}
}
}
break;
Expand Down
65 changes: 48 additions & 17 deletions src/filters/parser/MpegSplitter/MpegSplitterFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -420,9 +420,13 @@ HRESULT CMpegSplitterFile::Init(IAsyncReader* pAsyncReader)

m_pmt_streams.clear();
m_ProgramData.clear();

mpeg_streams.clear();
avc_streams.clear();
hevc_streams.clear();
vvc_streams.clear();
dtshd_streams.clear();

m_SyncPoints.clear();

Seek(m_posMin);
Expand Down Expand Up @@ -667,6 +671,8 @@ void CMpegSplitterFile::SearchStreams(const __int64 start, const __int64 stop, c
mpeg_streams.clear();
avc_streams.clear();
hevc_streams.clear();
vvc_streams.clear();
dtshd_streams.clear();

Seek(start);

Expand Down Expand Up @@ -1265,6 +1271,14 @@ DWORD CMpegSplitterFile::AddStream(const WORD pid, BYTE pesid, const BYTE ext_id
if (Read(h, len, &s.mt, false)) {
s.dts.bDTSCore = true;
type = stream_type::audio;

if (pes_stream_type == AUDIO_STREAM_DTS_HD || pes_stream_type == AUDIO_STREAM_DTS_HD_MASTER_AUDIO) {
Seek(start);
auto& h = dtshd_streams[s];
h.pData.reserve(static_cast<size_t>(16)* KILOBYTE);
h.pData.resize(static_cast<size_t>(len));
ByteRead(h.pData.data(), len);
}
}
}

Expand Down Expand Up @@ -1361,29 +1375,46 @@ DWORD CMpegSplitterFile::AddStream(const WORD pid, BYTE pesid, const BYTE ext_id
if (pes_stream_type == AUDIO_STREAM_DTS_HD || pes_stream_type == AUDIO_STREAM_DTS_HD_MASTER_AUDIO) {
stream* source = (stream*)m_streams[stream_type::audio].GetStream(s);
if (source && source->dts.bDTSCore && !source->dts.bDTSHD && source->mt.pbFormat) {
Seek(start);
if (BitRead(32, true) == FCC(DTS_SYNCWORD_SUBSTREAM)) {
BYTE* buf = DNew BYTE[len];
auto& h = dtshd_streams[s];
auto size = h.pData.size();
h.pData.resize(size + len);
ByteRead(h.pData.data() + size, len);

if (h.pData.size() >= static_cast<size_t>(16) * KILOBYTE) {
BYTE* start = h.pData.data();
BYTE* end = start + h.pData.size();
audioframe_t aframe;
if (ByteRead(buf, len) == S_OK && ParseDTSHDHeader(buf, len, &aframe)) {
WAVEFORMATEX* wfe = (WAVEFORMATEX*)source->mt.pbFormat;
wfe->nSamplesPerSec = aframe.samplerate;
wfe->nChannels = aframe.channels;
if (aframe.param1) {
wfe->wBitsPerSample = aframe.param1;
}
if (aframe.param2 == DCA_PROFILE_HD_HRA) {
wfe->nAvgBytesPerSec += CalcBitrate(aframe) / 8;
} else {
wfe->nAvgBytesPerSec = 0;
int size = ParseDTSHeader(start, &aframe);
if (size) {
auto wfe = reinterpret_cast<WAVEFORMATEX*>(source->mt.pbFormat);
if (aframe.samples) {
wfe->nAvgBytesPerSec = size * aframe.samplerate / aframe.samples;
}
if (start + size + 40 <= end) {
if (ParseDTSHDHeader(start + size, end - start - size, &aframe)) {
wfe->nSamplesPerSec = aframe.samplerate;
wfe->nChannels = aframe.channels;
if (aframe.param1) {
wfe->wBitsPerSample = aframe.param1;
}
wfe->nBlockAlign = wfe->nChannels * wfe->wBitsPerSample / 8;
if (aframe.param2 == DCA_PROFILE_HD_HRA || aframe.param2 == DCA_PROFILE_HD_HRA_X || aframe.param2 == DCA_PROFILE_HD_HRA_X_IMAX) {
wfe->nAvgBytesPerSec += CalcBitrate(aframe) / 8;
} else {
wfe->nAvgBytesPerSec = 0;
}

source->dts.bDTSHD = true;
wfe = reinterpret_cast<WAVEFORMATEX*>(source->mt.ReallocFormatBuffer(sizeof(WAVEFORMATEX) + 1));
wfe->cbSize = 1;
((BYTE*)(wfe + 1))[0] = aframe.param2;
}
}
}
delete [] buf;

source->dts.bDTSHD = true;
}
}
} else if (pes_stream_type == AUDIO_STREAM_AC3 || pes_stream_type == AUDIO_STREAM_AC3_PLUS || pes_stream_type == AUDIO_STREAM_EAC3 || pes_stream_type == SECONDARY_AUDIO_AC3_PLUS) {
} else if (pes_stream_type == AUDIO_STREAM_AC3 || pes_stream_type == AUDIO_STREAM_AC3_PLUS || pes_stream_type == AUDIO_STREAM_EAC3 || pes_stream_type == SECONDARY_AUDIO_AC3_PLUS) {
stream* source = (stream*)m_streams[stream_type::audio].GetStream(s);
if (source && source->mt.pbFormat && source->bParseEAC3SubStream) {
Seek(start);
Expand Down
6 changes: 6 additions & 0 deletions src/filters/parser/MpegSplitter/MpegSplitterFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ class CMpegSplitterFile : public CBaseSplitterFileEx
};
std::map<DWORD, vvc_data> vvc_streams;

struct dtshd_data {
dtshdr h;
std::vector<BYTE> pData;
};
std::map<DWORD, dtshd_data> dtshd_streams;

template<class T, BYTE validCount = 5>
class CValidStream {
BYTE m_nValidStream = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/filters/source/DTSAC3Source/DTSAC3Source.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* (C) 2003-2006 Gabest
* (C) 2006-2023 see Authors.txt
* (C) 2006-2024 see Authors.txt
*
* This file is part of MPC-BE.
*
Expand Down Expand Up @@ -313,7 +313,7 @@ CDTSAC3Stream::CDTSAC3Stream(const WCHAR* wfn, CSource* pParent, HRESULT* phr)

if (HD_size) {
m_framesize += HD_size;
if (aframe.param2 == DCA_PROFILE_HD_HRA) {
if (aframe.param2 == DCA_PROFILE_HD_HRA || aframe.param2 == DCA_PROFILE_HD_HRA_X || aframe.param2 == DCA_PROFILE_HD_HRA_X_IMAX) {
m_bitrate += CalcBitrate(aframe);
} else {
m_bitrate = 0;
Expand Down
18 changes: 12 additions & 6 deletions src/filters/transform/MpaDecFilter/MpaDecFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1909,9 +1909,12 @@ HRESULT CMpaDecFilter::DeliverBitstream(BYTE* pBuff, const int size, const REFER
}
break;
case IEC61937_DTSHD:
length = m_DTSHDProfile == DCA_PROFILE_HD_HRA ? BS_DTSHD_SIZE / 4 : BS_DTSHD_SIZE;
subtype = m_DTSHDProfile == DCA_PROFILE_HD_HRA ? 2 : 4;
isHDMI = true;
{
bool bIsDTSHDHRA = m_DTSHDProfile == DCA_PROFILE_HD_HRA || m_DTSHDProfile == DCA_PROFILE_HD_HRA_X || m_DTSHDProfile == DCA_PROFILE_HD_HRA_X_IMAX;
length = bIsDTSHDHRA ? BS_DTSHD_SIZE / 4 : BS_DTSHD_SIZE;
subtype = bIsDTSHDHRA ? 2 : 4;
isHDMI = true;
}
break;
case IEC61937_EAC3:
length = BS_EAC3_SIZE;
Expand Down Expand Up @@ -2195,9 +2198,12 @@ CMediaType CMpaDecFilter::CreateMediaTypeHDMI(WORD type)

switch(type) {
case IEC61937_DTSHD:
wfex.Format.nChannels = m_DTSHDProfile == DCA_PROFILE_HD_HRA ? 2 : 8;
wfex.dwChannelMask = m_DTSHDProfile == DCA_PROFILE_HD_HRA ? KSAUDIO_SPEAKER_STEREO : KSAUDIO_SPEAKER_7POINT1_SURROUND;
subtype = KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD;
{
bool bIsDTSHDHRA = m_DTSHDProfile == DCA_PROFILE_HD_HRA || m_DTSHDProfile == DCA_PROFILE_HD_HRA_X || m_DTSHDProfile == DCA_PROFILE_HD_HRA_X_IMAX;
wfex.Format.nChannels = bIsDTSHDHRA ? 2 : 8;
wfex.dwChannelMask = bIsDTSHDHRA ? KSAUDIO_SPEAKER_STEREO : KSAUDIO_SPEAKER_7POINT1_SURROUND;
subtype = KSDATAFORMAT_SUBTYPE_IEC61937_DTS_HD;
}
break;
case IEC61937_EAC3:
wfex.Format.nChannels = 2;
Expand Down

0 comments on commit 5cac357

Please sign in to comment.