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

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksoid <aleksoid@users.sourceforge.net>2010-08-17 03:27:58 +0400
committerAleksoid <aleksoid@users.sourceforge.net>2010-08-17 03:27:58 +0400
commit6fe7a2e1e2759d7850c57cbefbb47b1a25513a4c (patch)
treede2fb42f634b597e0eac4cbe69961f48a638e428 /src/filters/parser
parent27da42d7f29c664030cc94e078f9e7d12e201b41 (diff)
Add : E-AC3 support in MPEGSplitter.
Fix : ticket #333 git-svn-id: https://mpc-hc.svn.sourceforge.net/svnroot/mpc-hc/trunk@2259 10f7b99b-c216-0410-bff0-8a66a9350fd8
Diffstat (limited to 'src/filters/parser')
-rw-r--r--src/filters/parser/BaseSplitter/BaseSplitterFileEx.cpp79
-rw-r--r--src/filters/parser/BaseSplitter/BaseSplitterFileEx.h8
2 files changed, 65 insertions, 22 deletions
diff --git a/src/filters/parser/BaseSplitter/BaseSplitterFileEx.cpp b/src/filters/parser/BaseSplitter/BaseSplitterFileEx.cpp
index 0c8626890..f1f3f983c 100644
--- a/src/filters/parser/BaseSplitter/BaseSplitterFileEx.cpp
+++ b/src/filters/parser/BaseSplitter/BaseSplitterFileEx.cpp
@@ -592,6 +592,8 @@ bool CBaseSplitterFileEx::Read(aachdr& h, int len, CMediaType* pmt)
bool CBaseSplitterFileEx::Read(ac3hdr& h, int len, CMediaType* pmt)
{
+ static int freq[] = {48000, 44100, 32000, 0};
+
memset(&h, 0, sizeof(h));
for(; len >= 7 && BitRead(16, true) != 0x0b77; len--)
@@ -603,44 +605,77 @@ bool CBaseSplitterFileEx::Read(ac3hdr& h, int len, CMediaType* pmt)
h.sync = (WORD)BitRead(16);
if(h.sync != 0x0B77)
return(false);
-
+ _int64 pos = GetPos();
h.crc1 = (WORD)BitRead(16);
h.fscod = BitRead(2);
h.frmsizecod = BitRead(6);
h.bsid = BitRead(5);
- h.bsmod = BitRead(3);
- h.acmod = BitRead(3);
- if((h.acmod & 1) && h.acmod != 1) h.cmixlev = BitRead(2);
- if(h.acmod & 4) h.surmixlev = BitRead(2);
- if(h.acmod == 2) h.dsurmod = BitRead(2);
- h.lfeon = BitRead(1);
-
- if(h.bsid >= 17 || h.fscod == 3 || h.frmsizecod >= 48)
+ if(h.bsid > 16)
return(false);
+ if(h.bsid <= 10) {
+ /* Normal AC-3 */
+ if(h.fscod == 3)
+ return(false);
+ if(h.frmsizecod > 37)
+ return(false);
+ h.bsmod = BitRead(3);
+ h.acmod = BitRead(3);
+ if(h.acmod == 2) h.dsurmod = BitRead(2);
+ if((h.acmod & 1) && h.acmod != 1) h.cmixlev = BitRead(2);
+ if(h.acmod & 4) h.surmixlev = BitRead(2);
+ h.lfeon = BitRead(1);
+ h.sr_shift = max(h.bsid, 8) - 8;
+ } else {
+ /* Enhanced AC-3 */
+ Seek(pos);
+ h.frame_type = BitRead(2);
+ if(h.frame_type == 3)
+ return(false);
+ h.substreamid = BitRead(3);
+ h.frame_size = (BitRead(11) + 1) << 1;
+ if(h.frame_size < 7)
+ return(false);
+ h.sr_code = BitRead(2);
+ if(h.sr_code == 3)
+ {
+ int sr_code2 = BitRead(2);
+ if(sr_code2 == 3)
+ return(false);
+ h.sample_rate = freq[sr_code2] / 2;
+ h.sr_shift = 1;
+ }
+ else
+ {
+ static int eac3_blocks[4] = {1, 2, 3, 6};
+ h.num_blocks = eac3_blocks[BitRead(2)];
+ h.sample_rate = freq[h.sr_code];
+ h.sr_shift = 0;
+ }
+ h.acmod = BitRead(3);
+ h.lfeon = BitRead(1);
+ }
if(!pmt) return(true);
WAVEFORMATEX wfe;
memset(&wfe, 0, sizeof(wfe));
wfe.wFormatTag = WAVE_FORMAT_DOLBY_AC3;
-
+
static int channels[] = {2, 1, 2, 3, 3, 4, 4, 5};
wfe.nChannels = channels[h.acmod] + h.lfeon;
- static int freq[] = {48000, 44100, 32000, 0};
- wfe.nSamplesPerSec = freq[h.fscod];
-
- switch(h.bsid)
+ if(h.bsid <= 10)
{
- case 9: wfe.nSamplesPerSec >>= 1; break;
- case 10: wfe.nSamplesPerSec >>= 2; break;
- case 11: wfe.nSamplesPerSec >>= 3; break;
- default: break;
+ wfe.nSamplesPerSec = freq[h.fscod] >> h.sr_shift;
+ static int rate[] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640, 768, 896, 1024, 1152, 1280};
+ wfe.nAvgBytesPerSec = ((rate[h.frmsizecod>>1] * 1000) >> h.sr_shift) / 8;
}
-
- static int rate[] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640, 768, 896, 1024, 1152, 1280};
-
- wfe.nAvgBytesPerSec = (rate[h.frmsizecod>>1] * 1000) / 8;
+ else
+ {
+ wfe.nSamplesPerSec = h.sample_rate;
+ wfe.nAvgBytesPerSec = h.frame_size * h.sample_rate / (h.num_blocks * 256);
+ }
+
wfe.nBlockAlign = (WORD)(1536 * wfe.nAvgBytesPerSec / wfe.nSamplesPerSec);
pmt->majortype = MEDIATYPE_Audio;
diff --git a/src/filters/parser/BaseSplitter/BaseSplitterFileEx.h b/src/filters/parser/BaseSplitter/BaseSplitterFileEx.h
index 72f604c85..c60776311 100644
--- a/src/filters/parser/BaseSplitter/BaseSplitterFileEx.h
+++ b/src/filters/parser/BaseSplitter/BaseSplitterFileEx.h
@@ -161,6 +161,14 @@ public:
BYTE surmixlev:2;
BYTE dsurmod:2;
BYTE lfeon:1;
+ BYTE sr_shift;
+ // E-AC3 header
+ BYTE frame_type;
+ BYTE substreamid;
+ WORD frame_size;
+ BYTE sr_code;
+ WORD sample_rate;
+ BYTE num_blocks;
// the rest is unimportant for us
};