diff options
author | v0lt <v0lt@users.sourceforge.net> | 2012-05-30 19:34:30 +0400 |
---|---|---|
committer | v0lt <v0lt@users.sourceforge.net> | 2012-05-30 19:34:30 +0400 |
commit | 8f859059c4fd122f069bab48e120aadc4d570653 (patch) | |
tree | 11b4cb20a47b79937c0038b6974cacdb6fc6814f /src/filters/parser/BaseSplitter | |
parent | 692cce6f91f966253dd3365c79baa6df477769ac (diff) |
BaseSplitter: added header for dvd-audio lpcm, cosmetics.
git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@4948 10f7b99b-c216-0410-bff0-8a66a9350fd8
Diffstat (limited to 'src/filters/parser/BaseSplitter')
-rw-r--r-- | src/filters/parser/BaseSplitter/BaseSplitterFileEx.cpp | 145 | ||||
-rw-r--r-- | src/filters/parser/BaseSplitter/BaseSplitterFileEx.h | 121 |
2 files changed, 162 insertions, 104 deletions
diff --git a/src/filters/parser/BaseSplitter/BaseSplitterFileEx.cpp b/src/filters/parser/BaseSplitter/BaseSplitterFileEx.cpp index ed7d4c7f9..decdad87e 100644 --- a/src/filters/parser/BaseSplitter/BaseSplitterFileEx.cpp +++ b/src/filters/parser/BaseSplitter/BaseSplitterFileEx.cpp @@ -933,49 +933,6 @@ bool CBaseSplitterFileEx::Read(dtshdr& h, int len, CMediaType* pmt, bool find_sy return true;
}
-bool CBaseSplitterFileEx::Read(hdmvlpcmhdr& h, CMediaType* pmt)
-{
- memset(&h, 0, sizeof(h));
-
- h.size = (WORD)BitRead(16);
- h.channels = (BYTE)BitRead(4);
- h.samplerate = (BYTE)BitRead(4);
- h.bitpersample = (BYTE)BitRead(2);
-
- if (h.channels==0 || h.channels==2 ||
- (h.samplerate != 1 && h.samplerate!= 4 && h.samplerate!= 5) ||
- h.bitpersample<0 || h.bitpersample>3) {
- return false;
- }
-
- if (!pmt) {
- return true;
- }
-
- WAVEFORMATEX_HDMV_LPCM wfe;
- wfe.wFormatTag = WAVE_FORMAT_PCM;
-
- static int channels[] = {0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8};
- wfe.nChannels = channels[h.channels];
- wfe.channel_conf = h.channels;
-
- static int freq[] = {0, 48000, 0, 0, 96000, 192000};
- wfe.nSamplesPerSec = freq[h.samplerate];
-
- static int bitspersample[] = {0, 16, 20, 24};
- wfe.wBitsPerSample = bitspersample[h.bitpersample];
-
- wfe.nBlockAlign = wfe.nChannels*wfe.wBitsPerSample>>3;
- wfe.nAvgBytesPerSec = wfe.nBlockAlign*wfe.nSamplesPerSec;
-
- pmt->majortype = MEDIATYPE_Audio;
- pmt->subtype = MEDIASUBTYPE_HDMV_LPCM_AUDIO;
- pmt->formattype = FORMAT_WaveFormatEx;
- pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
-
- return true;
-}
-
bool CBaseSplitterFileEx::Read(lpcmhdr& h, CMediaType* pmt)
{
memset(&h, 0, sizeof(h));
@@ -1023,7 +980,107 @@ bool CBaseSplitterFileEx::Read(lpcmhdr& h, CMediaType* pmt) pmt->formattype = FORMAT_WaveFormatEx;
pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
- // TODO: what to do with dvd-audio lpcm?
+ return true;
+}
+
+bool CBaseSplitterFileEx::Read(dvdalpcmhdr& h, int len, CMediaType* pmt)
+{
+ memset(&h, 0, sizeof(h));
+ if (len < 8) return false;
+
+ h.firstaudioframe = BitRead(16);// Byte pointer to start of first audio frame.
+ h.unknown1 = BitRead(8); // Unknown - e.g. 0x10 for stereo, 0x00 for surround
+ if (h.unknown1!= 0x10 && h.unknown1!= 0x00)
+ return false; // this is not the aob. maybe this is a vob.
+
+ h.bitpersample1 = BitRead(4);
+ h.bitpersample2 = BitRead(4);
+ h.samplerate1 = BitRead(4);
+ h.samplerate2 = BitRead(4);
+ h.unknown2 = BitRead(8); // Unknown - e.g. 0x00
+ h.groupassignment = BitRead(8); // Channel Group Assignment
+ h.unknown3 = BitRead(8); // Unknown - e.g. 0x80
+
+ if (h.bitpersample1 > 2 || (h.samplerate1&7) > 2 || h.groupassignment > 20 ||
+ h.unknown2 != 0x00 || h.unknown3 != 0x80) {
+ return false; // poor parameters or this is a vob.
+ }
+ // decoder limitations
+ if (h.groupassignment > 1 && (h.bitpersample2 != h.bitpersample1 || h.samplerate2 != h.samplerate1)) {
+ return false; // decoder does not support different bit depth and frequency.
+ }
+
+ if (!pmt) {
+ return true;
+ }
+
+ WAVEFORMATEX wfe;
+ memset(&wfe, 0, sizeof(wfe));
+ wfe.wFormatTag = WAVE_FORMAT_UNKNOWN;
+ static const WORD depth[] = {16, 20, 24};
+ static const DWORD freq[] = {48000, 96000, 192000, 0, 0, 0, 0, 0, 44100, 88200, 1764000};
+ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+ static const WORD channels1[] = {1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4};
+ static const WORD channels2[] = {0, 0, 1, 2, 1, 2, 3, 1, 2, 3, 2, 3, 4, 1, 2, 1, 2, 3, 1, 1, 2};
+ wfe.wBitsPerSample = depth[h.bitpersample1];
+ wfe.nSamplesPerSec = freq[h.samplerate1];
+ wfe.nChannels = channels1[h.groupassignment]+channels2[h.groupassignment];
+
+ if (wfe.nChannels > 2) {
+ wfe.nBlockAlign = (depth[h.bitpersample1] * channels1[h.groupassignment] * (freq[h.samplerate1] / freq[h.samplerate2]) +
+ depth[h.bitpersample2] * channels2[h.groupassignment]) * 2 / 8;
+ } else {
+ wfe.nBlockAlign = depth[h.bitpersample1] * channels1[h.groupassignment] * 2 / 8;
+ }
+ wfe.nAvgBytesPerSec = wfe.nBlockAlign * wfe.nSamplesPerSec / 2;
+
+ pmt->majortype = MEDIATYPE_Audio;
+ pmt->subtype = MEDIASUBTYPE_DVD_LPCM_AUDIO;
+ pmt->formattype = FORMAT_WaveFormatEx;
+ pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
+
+ return true;
+}
+
+bool CBaseSplitterFileEx::Read(hdmvlpcmhdr& h, CMediaType* pmt)
+{
+ memset(&h, 0, sizeof(h));
+
+ h.size = (WORD)BitRead(16);
+ h.channels = (BYTE)BitRead(4);
+ h.samplerate = (BYTE)BitRead(4);
+ h.bitpersample = (BYTE)BitRead(2);
+
+ if (h.channels==0 || h.channels==2 ||
+ (h.samplerate != 1 && h.samplerate!= 4 && h.samplerate!= 5) ||
+ h.bitpersample<0 || h.bitpersample>3) {
+ return false;
+ }
+
+ if (!pmt) {
+ return true;
+ }
+
+ WAVEFORMATEX_HDMV_LPCM wfe;
+ wfe.wFormatTag = WAVE_FORMAT_PCM;
+
+ static int channels[] = {0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8};
+ wfe.nChannels = channels[h.channels];
+ wfe.channel_conf = h.channels;
+
+ static int freq[] = {0, 48000, 0, 0, 96000, 192000};
+ wfe.nSamplesPerSec = freq[h.samplerate];
+
+ static int bitspersample[] = {0, 16, 20, 24};
+ wfe.wBitsPerSample = bitspersample[h.bitpersample];
+
+ wfe.nBlockAlign = wfe.nChannels*wfe.wBitsPerSample>>3;
+ wfe.nAvgBytesPerSec = wfe.nBlockAlign*wfe.nSamplesPerSec;
+
+ pmt->majortype = MEDIATYPE_Audio;
+ pmt->subtype = MEDIASUBTYPE_HDMV_LPCM_AUDIO;
+ pmt->formattype = FORMAT_WaveFormatEx;
+ pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
return true;
}
diff --git a/src/filters/parser/BaseSplitter/BaseSplitterFileEx.h b/src/filters/parser/BaseSplitter/BaseSplitterFileEx.h index c57023674..ba32723e7 100644 --- a/src/filters/parser/BaseSplitter/BaseSplitterFileEx.h +++ b/src/filters/parser/BaseSplitter/BaseSplitterFileEx.h @@ -95,15 +95,9 @@ public: BYTE hdrlen;
BYTE id_ext;
-
- struct peshdr() {
- memset(this, 0, sizeof(*this));
- }
};
- class seqhdr
- {
- public:
+ struct seqhdr {
WORD width;
WORD height;
BYTE ar:4;
@@ -127,9 +121,8 @@ public: int arx, ary;
};
- class mpahdr
+ struct mpahdr
{
- public:
WORD sync:11;
WORD version:2;
WORD layer:2;
@@ -148,9 +141,8 @@ public: REFERENCE_TIME rtDuration;
};
- class aachdr
+ struct aachdr
{
- public:
WORD sync:12;
WORD version:1;
WORD layer:2;
@@ -174,15 +166,13 @@ public: REFERENCE_TIME rtDuration;
};
- class latm_aachdr
+ struct latm_aachdr
{
- public:
// nothing ;)
};
- class ac3hdr
+ struct ac3hdr
{
- public:
WORD sync;
WORD crc1;
BYTE fscod:2;
@@ -205,9 +195,8 @@ public: // the rest is unimportant for us
};
- class dtshdr
+ struct dtshdr
{
- public:
DWORD sync;
BYTE frametype:1;
BYTE deficitsamplecount:5;
@@ -228,12 +217,10 @@ public: BYTE aspf:1;
BYTE lfe:2;
BYTE predictor_history:1;
-
};
- class lpcmhdr
+ struct lpcmhdr
{
- public:
BYTE emphasis:1;
BYTE mute:1;
BYTE reserved1:1;
@@ -245,42 +232,50 @@ public: BYTE drc; // 0x80: off
};
- class hdmvlpcmhdr
+ struct dvdalpcmhdr
+ {
+ // http://dvd-audio.sourceforge.net/spec/aob.shtml
+ WORD firstaudioframe;
+ BYTE unknown1;
+ BYTE bitpersample1:4;
+ BYTE bitpersample2:4;
+ BYTE samplerate1:4;
+ BYTE samplerate2:4;
+ BYTE unknown2;
+ BYTE groupassignment;
+ BYTE unknown3;
+ };
+
+ struct hdmvlpcmhdr
{
- public:
WORD size;
BYTE channels:4;
BYTE samplerate:4;
BYTE bitpersample:2;
};
- class dvdspuhdr
+ struct dvdspuhdr
{
- public:
// nothing ;)
};
- class hdmvsubhdr
+ struct hdmvsubhdr
{
- public:
// nothing ;)
};
- class svcdspuhdr
+ struct svcdspuhdr
{
- public:
// nothing ;)
};
- class cvdspuhdr
+ struct cvdspuhdr
{
- public:
// nothing ;)
};
- class ps2audhdr
+ struct ps2audhdr
{
- public:
// 'SShd' + len (0x18)
DWORD unk1;
DWORD freq;
@@ -291,13 +286,13 @@ public: // pcm or adpcm data
};
- class ps2subhdr
+ struct ps2subhdr
{
- public:
// nothing ;)
};
- struct trhdr {
+ struct trhdr
+ {
BYTE sync; // 0x47
BYTE error:1;
BYTE payloadstart:1;
@@ -324,7 +319,8 @@ public: __int64 next;
};
- struct trsechdr {
+ struct trsechdr
+ {
BYTE table_id;
WORD section_syntax_indicator:1;
WORD zero:1;
@@ -338,9 +334,9 @@ public: BYTE last_section_number;
};
- // http://www.technotrend.de/download/av_format_v1.pdf
-
- struct pvahdr {
+ // http://multimedia.cx/mirror/av_format_v1.pdf
+ struct pvahdr
+ {
WORD sync; // 'VA'
BYTE streamid; // 1 - video, 2 - audio
BYTE counter;
@@ -354,20 +350,22 @@ public: };
enum spsppsindex {
- index_unknown = -1,
+ index_unknown = -1,
index_subsetsps = 0,
- index_sps = 1,
- index_pps1 = 2,
- index_pps2 = 3,
+ index_sps = 1,
+ index_pps1 = 2,
+ index_pps2 = 3,
};
- struct spsppsdata {
+ struct spsppsdata
+ {
BYTE buffer[MAX_SPSPPS];
unsigned int size;
bool complete;
};
- struct avchdr {
+ struct avchdr
+ {
BYTE profile, level;
unsigned int width, height;
unsigned int views;
@@ -382,8 +380,7 @@ public: spsppsdata spspps[4];
BYTE lastid;
- avchdr()
- {
+ avchdr() {
memset(spspps, 0, sizeof(spspps));
lastid = 0;
views = 1;
@@ -391,18 +388,19 @@ public: }
};
- struct vc1hdr {
- BYTE profile;
- BYTE level;
- BYTE chromaformat;
- BYTE frmrtq_postproc;
- BYTE bitrtq_postproc;
- BYTE postprocflag;
- BYTE broadcast;
- BYTE interlace;
- BYTE tfcntrflag;
- BYTE finterpflag;
- BYTE psf;
+ struct vc1hdr
+ {
+ BYTE profile;
+ BYTE level;
+ BYTE chromaformat;
+ BYTE frmrtq_postproc;
+ BYTE bitrtq_postproc;
+ BYTE postprocflag;
+ BYTE broadcast;
+ BYTE interlace;
+ BYTE tfcntrflag;
+ BYTE finterpflag;
+ BYTE psf;
unsigned int width, height;
struct sar {
BYTE num;
@@ -410,7 +408,9 @@ public: } sar;
};
- struct dvbsub {
+ struct dvbsub
+ {
+ // nothing ;)
};
#pragma pack(pop)
@@ -425,6 +425,7 @@ public: bool Read(ac3hdr& h, int len, CMediaType* pmt = NULL, bool find_sync = true, bool AC3CoreOnly = true);
bool Read(dtshdr& h, int len, CMediaType* pmt = NULL, bool find_sync = true);
bool Read(lpcmhdr& h, CMediaType* pmt = NULL);
+ bool Read(dvdalpcmhdr& h, int len, CMediaType* pmt = NULL);
bool Read(hdmvlpcmhdr& h, CMediaType* pmt = NULL);
bool Read(dvdspuhdr& h, CMediaType* pmt = NULL);
bool Read(hdmvsubhdr& h, CMediaType* pmt = NULL, const char* language_code = NULL);
|