BaseSplitterFileEx.cpp

00001 /* 
00002  *      Copyright (C) 2003-2005 Gabest
00003  *      http://www.gabest.org
00004  *
00005  *  This Program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2, or (at your option)
00008  *  any later version.
00009  *   
00010  *  This Program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013  *  GNU General Public License for more details.
00014  *   
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with GNU Make; see the file COPYING.  If not, write to
00017  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
00018  *  http://www.gnu.org/copyleft/gpl.html
00019  *
00020  */
00021 
00022 #include "StdAfx.h"
00023 #include "BaseSplitterFileEx.h"
00024 #include <mmreg.h>
00025 #include "..\..\..\DSUtil\DSUtil.h"
00026 #include <initguid.h>
00027 #include "..\..\..\..\include\moreuuids.h"
00028 #include "..\..\..\..\include\matroska\matroska.h"
00029 
00030 //
00031 // CBaseSplitterFileEx
00032 //
00033 
00034 CBaseSplitterFileEx::CBaseSplitterFileEx(IAsyncReader* pReader, HRESULT& hr, int cachelen)
00035         : CBaseSplitterFile(pReader, hr, cachelen)
00036         , m_tslen(0)
00037 {
00038 }
00039 
00040 CBaseSplitterFileEx::~CBaseSplitterFileEx()
00041 {
00042 }
00043 
00044 //
00045 
00046 bool CBaseSplitterFileEx::NextMpegStartCode(BYTE& code, __int64 len)
00047 {
00048         BitByteAlign();
00049         DWORD dw = -1;
00050         do
00051         {
00052                 if(len-- == 0 || GetPos() >= GetLength()) return(false);
00053                 dw = (dw << 8) | (BYTE)BitRead(8);
00054         }
00055         while((dw&0xffffff00) != 0x00000100);
00056         code = (BYTE)(dw&0xff);
00057         return(true);
00058 }
00059 
00060 //
00061 
00062 #define MARKER if(BitRead(1) != 1) {ASSERT(0); return(false);}
00063 
00064 bool CBaseSplitterFileEx::Read(pshdr& h)
00065 {
00066         memset(&h, 0, sizeof(h));
00067 
00068         BYTE b = (BYTE)BitRead(8, true);
00069 
00070         if((b&0xf1) == 0x21)
00071         {
00072                 h.type = mpeg1;
00073 
00074                 EXECUTE_ASSERT(BitRead(4) == 2);
00075 
00076                 h.scr = 0;
00077                 h.scr |= BitRead(3) << 30; MARKER; // 32..30
00078                 h.scr |= BitRead(15) << 15; MARKER; // 29..15
00079                 h.scr |= BitRead(15); MARKER; MARKER; // 14..0
00080                 h.bitrate = BitRead(22); MARKER;
00081         }
00082         else if((b&0xc4) == 0x44)
00083         {
00084                 h.type = mpeg2;
00085 
00086                 EXECUTE_ASSERT(BitRead(2) == 1);
00087 
00088                 h.scr = 0;
00089                 h.scr |= BitRead(3) << 30; MARKER; // 32..30
00090                 h.scr |= BitRead(15) << 15; MARKER; // 29..15
00091                 h.scr |= BitRead(15); MARKER; // 14..0
00092                 h.scr = h.scr*300 + BitRead(9); MARKER;
00093                 h.bitrate = BitRead(22); MARKER; MARKER;
00094                 BitRead(5); // reserved
00095                 UINT64 stuffing = BitRead(3);
00096                 while(stuffing-- > 0) EXECUTE_ASSERT(BitRead(8) == 0xff);
00097         }
00098         else
00099         {
00100                 return(false);
00101         }
00102 
00103         h.bitrate *= 400;
00104 
00105         return(true);
00106 }
00107 
00108 bool CBaseSplitterFileEx::Read(pssyshdr& h)
00109 {
00110         memset(&h, 0, sizeof(h));
00111 
00112         WORD len = (WORD)BitRead(16); MARKER;
00113         h.rate_bound = (DWORD)BitRead(22); MARKER;
00114         h.audio_bound = (BYTE)BitRead(6);
00115         h.fixed_rate = !!BitRead(1);
00116         h.csps = !!BitRead(1);
00117         h.sys_audio_loc_flag = !!BitRead(1);
00118         h.sys_video_loc_flag = !!BitRead(1); MARKER;
00119         h.video_bound = (BYTE)BitRead(5);
00120 
00121         EXECUTE_ASSERT((BitRead(8)&0x7f) == 0x7f); // reserved (should be 0xff, but not in reality)
00122 
00123         for(len -= 6; len > 3; len -= 3) // TODO: also store these, somewhere, if needed
00124         {
00125                 UINT64 stream_id = BitRead(8);
00126                 EXECUTE_ASSERT(BitRead(2) == 3);
00127                 UINT64 p_std_buff_size_bound = (BitRead(1)?1024:128)*BitRead(13);
00128         }
00129 
00130         return(true);
00131 }
00132 
00133 bool CBaseSplitterFileEx::Read(peshdr& h, BYTE code)
00134 {
00135         memset(&h, 0, sizeof(h));
00136 
00137         if(!(code >= 0xbd && code < 0xf0))
00138                 return(false);
00139 
00140         h.len = (WORD)BitRead(16);
00141 
00142         if(code == 0xbe || code == 0xbf)
00143                 return(true);
00144 
00145         // mpeg1 stuffing (ff ff .. , max 16x)
00146         for(int i = 0; i < 16 && BitRead(8, true) == 0xff; i++)
00147         {
00148                 BitRead(8); 
00149                 if(h.len) h.len--;
00150         }
00151 
00152         h.type = (BYTE)BitRead(2, true) == mpeg2 ? mpeg2 : mpeg1;
00153 
00154         if(h.type == mpeg1)
00155         {
00156                 BYTE b = (BYTE)BitRead(2);
00157 
00158                 if(b == 1)
00159                 {
00160                         h.std_buff_size = (BitRead(1)?1024:128)*BitRead(13);
00161                         if(h.len) h.len -= 2;
00162                         b = (BYTE)BitRead(2);
00163                 }
00164 
00165                 if(b == 0)
00166                 {
00167                         h.fpts = (BYTE)BitRead(1);
00168                         h.fdts = (BYTE)BitRead(1);
00169                 }
00170         }
00171         else if(h.type == mpeg2)
00172         {
00173                 EXECUTE_ASSERT(BitRead(2) == mpeg2);
00174                 h.scrambling = (BYTE)BitRead(2);
00175                 h.priority = (BYTE)BitRead(1);
00176                 h.alignment = (BYTE)BitRead(1);
00177                 h.copyright = (BYTE)BitRead(1);
00178                 h.original = (BYTE)BitRead(1);
00179                 h.fpts = (BYTE)BitRead(1);
00180                 h.fdts = (BYTE)BitRead(1);
00181                 h.escr = (BYTE)BitRead(1);
00182                 h.esrate = (BYTE)BitRead(1);
00183                 h.dsmtrickmode = (BYTE)BitRead(1);
00184                 h.morecopyright = (BYTE)BitRead(1);
00185                 h.crc = (BYTE)BitRead(1);
00186                 h.extension = (BYTE)BitRead(1);
00187                 h.hdrlen = (BYTE)BitRead(8);
00188         }
00189         else
00190         {
00191                 if(h.len) while(h.len-- > 0) BitRead(8);
00192                 return(false);
00193         }
00194 
00195         if(h.fpts)
00196         {
00197                 if(h.type == mpeg2)
00198                 {
00199                         BYTE b = (BYTE)BitRead(4);
00200                         if(!(h.fdts && b == 3 || !h.fdts && b == 2)) {ASSERT(0); return(false);}
00201                 }
00202 
00203                 h.pts = 0;
00204                 h.pts |= BitRead(3) << 30; MARKER; // 32..30
00205                 h.pts |= BitRead(15) << 15; MARKER; // 29..15
00206                 h.pts |= BitRead(15); MARKER; // 14..0
00207                 h.pts = 10000*h.pts/90;
00208         }
00209 
00210         if(h.fdts)
00211         {
00212                 if((BYTE)BitRead(4) != 1) {ASSERT(0); return(false);}
00213 
00214                 h.dts = 0;
00215                 h.dts |= BitRead(3) << 30; MARKER; // 32..30
00216                 h.dts |= BitRead(15) << 15; MARKER; // 29..15
00217                 h.dts |= BitRead(15); MARKER; // 14..0
00218                 h.dts = 10000*h.dts/90;
00219         }
00220 
00221         // skip to the end of header
00222 
00223         if(h.type == mpeg1)
00224         {
00225                 if(!h.fpts && !h.fdts && BitRead(4) != 0xf) {/*ASSERT(0);*/ return(false);}
00226 
00227                 if(h.len)
00228                 {
00229                         h.len--;
00230                         if(h.pts) h.len -= 4;
00231                         if(h.dts) h.len -= 5;
00232                 }
00233         }
00234 
00235         if(h.type == mpeg2)
00236         {
00237                 if(h.len) h.len -= 3+h.hdrlen;
00238 
00239                 int left = h.hdrlen;
00240                 if(h.fpts) left -= 5;
00241                 if(h.fdts) left -= 5;
00242                 while(left-- > 0) BitRead(8);
00243 /*
00244                 // mpeg2 stuffing (ff ff .. , max 32x)
00245                 while(BitRead(8, true) == 0xff) {BitRead(8); if(h.len) h.len--;}
00246                 Seek(GetPos()); // put last peeked byte back for Read()
00247 
00248                 // FIXME: this doesn't seems to be here, 
00249                 // infact there can be ff's as part of the data 
00250                 // right at the beginning of the packet, which 
00251                 // we should not skip...
00252 */
00253         }
00254 
00255         return(true);
00256 }
00257 
00258 bool CBaseSplitterFileEx::Read(seqhdr& h, int len, CMediaType* pmt)
00259 {
00260         __int64 endpos = GetPos() + len; // - sequence header length
00261 
00262         BYTE id = 0;
00263 
00264         while(GetPos() < endpos && id != 0xb3)
00265         {
00266                 if(!NextMpegStartCode(id, len))
00267                         return(false);
00268         }
00269 
00270         if(id != 0xb3)
00271                 return(false);
00272 
00273         __int64 shpos = GetPos() - 4;
00274 
00275         h.width = (WORD)BitRead(12);
00276         h.height = (WORD)BitRead(12);
00277         h.ar = BitRead(4);
00278     static int ifps[16] = {0, 1126125, 1125000, 1080000, 900900, 900000, 540000, 450450, 450000, 0, 0, 0, 0, 0, 0, 0};
00279         h.ifps = ifps[BitRead(4)];
00280         h.bitrate = (DWORD)BitRead(18); MARKER;
00281         h.vbv = (DWORD)BitRead(10);
00282         h.constrained = BitRead(1);
00283 
00284         if(h.fiqm = BitRead(1))
00285                 for(int i = 0; i < countof(h.iqm); i++)
00286                         h.iqm[i] = (BYTE)BitRead(8);
00287 
00288         if(h.fniqm = BitRead(1))
00289                 for(int i = 0; i < countof(h.niqm); i++)
00290                         h.niqm[i] = (BYTE)BitRead(8);
00291 
00292         __int64 shlen = GetPos() - shpos;
00293 
00294         static float ar[] = 
00295         {
00296                 1.0000f,1.0000f,0.6735f,0.7031f,0.7615f,0.8055f,0.8437f,0.8935f,
00297                 0.9157f,0.9815f,1.0255f,1.0695f,1.0950f,1.1575f,1.2015f,1.0000f
00298         };
00299 
00300         h.arx = (int)((float)h.width / ar[h.ar] + 0.5);
00301         h.ary = h.height;
00302 
00303         mpeg_t type = mpeg1;
00304 
00305         __int64 shextpos = 0, shextlen = 0;
00306 
00307         if(NextMpegStartCode(id, 8) && id == 0xb5) // sequence header ext
00308         {
00309                 shextpos = GetPos() - 4;
00310 
00311                 h.startcodeid = BitRead(4);
00312                 h.profile_levelescape = BitRead(1); // reserved, should be 0
00313                 h.profile = BitRead(3);
00314                 h.level = BitRead(4);
00315                 h.progressive = BitRead(1);
00316                 h.chroma = BitRead(2);
00317                 h.width |= (BitRead(2)<<12);
00318                 h.height |= (BitRead(2)<<12);
00319                 h.bitrate |= (BitRead(12)<<18); MARKER;
00320                 h.vbv |= (BitRead(8)<<10);
00321                 h.lowdelay = BitRead(1);
00322                 h.ifps = (DWORD)(h.ifps * (BitRead(2)+1) / (BitRead(5)+1));
00323 
00324                 shextlen = GetPos() - shextpos;
00325 
00326                 struct {DWORD x, y;} ar[] = {{h.width,h.height},{4,3},{16,9},{221,100},{h.width,h.height}};
00327                 int i = min(max(h.ar, 1), 5)-1;
00328                 h.arx = ar[i].x;
00329                 h.ary = ar[i].y;
00330 
00331                 type = mpeg2;
00332         }
00333 
00334         h.ifps = 10 * h.ifps / 27;
00335         h.bitrate = h.bitrate == (1<<30)-1 ? 0 : h.bitrate * 400;
00336 
00337         DWORD a = h.arx, b = h.ary;
00338     while(a) {DWORD tmp = a; a = b % tmp; b = tmp;}
00339         if(b) h.arx /= b, h.ary /= b;
00340 
00341         if(!pmt) return(true);
00342 
00343         pmt->majortype = MEDIATYPE_Video;
00344 
00345         if(type == mpeg1)
00346         {
00347                 pmt->subtype = MEDIASUBTYPE_MPEG1Payload;
00348                 pmt->formattype = FORMAT_MPEGVideo;
00349                 int len = FIELD_OFFSET(MPEG1VIDEOINFO, bSequenceHeader) + shlen + shextlen;
00350                 MPEG1VIDEOINFO* vi = (MPEG1VIDEOINFO*)new BYTE[len];
00351                 memset(vi, 0, len);
00352                 vi->hdr.dwBitRate = h.bitrate;
00353                 vi->hdr.AvgTimePerFrame = h.ifps;
00354                 vi->hdr.bmiHeader.biSize = sizeof(vi->hdr.bmiHeader);
00355                 vi->hdr.bmiHeader.biWidth = h.width;
00356                 vi->hdr.bmiHeader.biHeight = h.height;
00357                 vi->hdr.bmiHeader.biXPelsPerMeter = h.width * h.ary;
00358                 vi->hdr.bmiHeader.biYPelsPerMeter = h.height * h.arx;
00359                 vi->cbSequenceHeader = shlen;
00360                 Seek(shpos);
00361                 Read((BYTE*)&vi->bSequenceHeader[0], shlen);
00362                 if(shextpos && shextlen) Seek(shextpos);
00363                 Read((BYTE*)&vi->bSequenceHeader[0] + shlen, shextlen);
00364                 pmt->SetFormat((BYTE*)vi, len);
00365                 delete [] vi;
00366         }
00367         else if(type == mpeg2)
00368         {
00369                 pmt->subtype = MEDIASUBTYPE_MPEG2_VIDEO;
00370                 pmt->formattype = FORMAT_MPEG2_VIDEO;
00371                 int len = FIELD_OFFSET(MPEG2VIDEOINFO, dwSequenceHeader) + shlen + shextlen;
00372                 MPEG2VIDEOINFO* vi = (MPEG2VIDEOINFO*)new BYTE[len];
00373                 memset(vi, 0, len);
00374                 vi->hdr.dwBitRate = h.bitrate;
00375                 vi->hdr.AvgTimePerFrame = h.ifps;
00376                 vi->hdr.dwPictAspectRatioX = h.arx;
00377                 vi->hdr.dwPictAspectRatioY = h.ary;
00378                 vi->hdr.bmiHeader.biSize = sizeof(vi->hdr.bmiHeader);
00379                 vi->hdr.bmiHeader.biWidth = h.width;
00380                 vi->hdr.bmiHeader.biHeight = h.height;
00381                 vi->dwProfile = h.profile;
00382                 vi->dwLevel = h.level;
00383                 vi->cbSequenceHeader = shlen;
00384                 Seek(shpos);
00385                 Read((BYTE*)&vi->dwSequenceHeader[0], shlen);
00386                 if(shextpos && shextlen) Seek(shextpos);
00387                 Read((BYTE*)&vi->dwSequenceHeader[0] + shlen, shextlen);
00388                 pmt->SetFormat((BYTE*)vi, len);
00389                 delete [] vi;
00390         }
00391         else
00392         {
00393                 return(false);
00394         }
00395 
00396         return(true);
00397 }
00398 
00399 bool CBaseSplitterFileEx::Read(mpahdr& h, int len, bool fAllowV25, CMediaType* pmt)
00400 {
00401         memset(&h, 0, sizeof(h));
00402 
00403         int syncbits = fAllowV25 ? 11 : 12;
00404 
00405         for(; len >= 4 && BitRead(syncbits, true) != (1<<syncbits) - 1; len--)
00406                 BitRead(8);
00407 
00408         if(len < 4)
00409                 return(false);
00410 
00411         h.sync = BitRead(11);
00412         h.version = BitRead(2);
00413         h.layer = BitRead(2);
00414         h.crc = BitRead(1);
00415         h.bitrate = BitRead(4);
00416         h.freq = BitRead(2);
00417         h.padding = BitRead(1);
00418         h.privatebit = BitRead(1);
00419         h.channels = BitRead(2);
00420         h.modeext = BitRead(2);
00421         h.copyright = BitRead(1);
00422         h.original = BitRead(1);
00423         h.emphasis = BitRead(2);
00424 
00425         if(h.version == 1 || h.layer == 0 || h.freq == 3 || h.bitrate == 15 || h.emphasis == 2)
00426                 return(false);
00427 
00428         if(h.version == 3 && h.layer == 2)
00429         {
00430                 if((h.bitrate == 1 || h.bitrate == 2 || h.bitrate == 3 || h.bitrate == 5) && h.channels != 3
00431                 && (h.bitrate >= 11 && h.bitrate <= 14) && h.channels == 3)
00432                         return(false);
00433         }
00434 
00435         h.layer = 4 - h.layer;
00436 
00437         //
00438 
00439         static int brtbl[][5] = 
00440         {
00441                 {0,0,0,0,0},
00442                 {32,32,32,32,8},
00443                 {64,48,40,48,16},
00444                 {96,56,48,56,24},
00445                 {128,64,56,64,32},
00446                 {160,80,64,80,40},
00447                 {192,96,80,96,48},
00448                 {224,112,96,112,56},
00449                 {256,128,112,128,64},
00450                 {288,160,128,144,80},
00451                 {320,192,160,160,96},
00452                 {352,224,192,176,112},
00453                 {384,256,224,192,128},
00454                 {416,320,256,224,144},
00455                 {448,384,320,256,160},
00456                 {0,0,0,0,0},
00457         };
00458 
00459         static int brtblcol[][4] = {{0,3,4,4},{0,0,1,2}};
00460         int bitrate = 1000*brtbl[h.bitrate][brtblcol[h.version&1][h.layer]];
00461         if(bitrate == 0) return(false);
00462 
00463         static int freq[][4] = {{11025,0,22050,44100},{12000,0,24000,48000},{8000,0,16000,32000}};
00464 
00465         bool l3ext = h.layer == 3 && !(h.version&1);
00466 
00467         h.nSamplesPerSec = freq[h.freq][h.version];
00468         h.FrameSize = h.layer == 1
00469                 ? (12 * bitrate / h.nSamplesPerSec + h.padding) * 4
00470                 : (l3ext ? 72 : 144) * bitrate / h.nSamplesPerSec + h.padding;
00471         h.rtDuration = 10000000i64 * (h.layer == 1 ? 384 : l3ext ? 576 : 1152) / h.nSamplesPerSec;// / (h.channels == 3 ? 1 : 2);
00472         h.nBytesPerSec = bitrate / 8;
00473 
00474         if(!pmt) return(true);
00475 
00476         /*int*/ len = h.layer == 3 
00477                 ? sizeof(WAVEFORMATEX/*MPEGLAYER3WAVEFORMAT*/) // no need to overcomplicate this...
00478                 : sizeof(MPEG1WAVEFORMAT);
00479         WAVEFORMATEX* wfe = (WAVEFORMATEX*)new BYTE[len];
00480         memset(wfe, 0, len);
00481         wfe->cbSize = len - sizeof(WAVEFORMATEX);
00482 
00483         if(h.layer == 3)
00484         {
00485                 wfe->wFormatTag = WAVE_FORMAT_MP3;
00486 
00487 /*              MPEGLAYER3WAVEFORMAT* f = (MPEGLAYER3WAVEFORMAT*)wfe;
00488                 f->wfx.wFormatTag = WAVE_FORMAT_MP3;
00489                 f->wID = MPEGLAYER3_ID_UNKNOWN;
00490                 f->fdwFlags = h.padding ? MPEGLAYER3_FLAG_PADDING_ON : MPEGLAYER3_FLAG_PADDING_OFF; // _OFF or _ISO ?
00491 */
00492         }
00493         else
00494         {
00495                 MPEG1WAVEFORMAT* f = (MPEG1WAVEFORMAT*)wfe;
00496                 f->wfx.wFormatTag = WAVE_FORMAT_MPEG;
00497                 f->fwHeadMode = 1 << h.channels;
00498                 f->fwHeadModeExt = 1 << h.modeext;
00499                 f->wHeadEmphasis = h.emphasis+1;
00500                 if(h.privatebit) f->fwHeadFlags |= ACM_MPEG_PRIVATEBIT;
00501                 if(h.copyright) f->fwHeadFlags |= ACM_MPEG_COPYRIGHT;
00502                 if(h.original) f->fwHeadFlags |= ACM_MPEG_ORIGINALHOME;
00503                 if(h.crc == 0) f->fwHeadFlags |= ACM_MPEG_PROTECTIONBIT;
00504                 if(h.version == 3) f->fwHeadFlags |= ACM_MPEG_ID_MPEG1;
00505                 f->fwHeadLayer = 1 << (h.layer-1);
00506                 f->dwHeadBitrate = bitrate;
00507         }
00508 
00509         wfe->nChannels = h.channels == 3 ? 1 : 2;
00510         wfe->nSamplesPerSec = h.nSamplesPerSec;
00511         wfe->nBlockAlign = h.FrameSize;
00512         wfe->nAvgBytesPerSec = h.nBytesPerSec;
00513 
00514         pmt->majortype = MEDIATYPE_Audio;
00515         pmt->subtype = FOURCCMap(wfe->wFormatTag);
00516         pmt->formattype = FORMAT_WaveFormatEx;
00517         pmt->SetFormat((BYTE*)wfe, sizeof(WAVEFORMATEX) + wfe->cbSize);
00518 
00519         delete [] wfe;
00520 
00521         return(true);
00522 }
00523 
00524 bool CBaseSplitterFileEx::Read(aachdr& h, int len, CMediaType* pmt)
00525 {
00526         memset(&h, 0, sizeof(h));
00527 
00528         for(; len >= 7 && BitRead(12, true) != 0xfff; len--)
00529                 BitRead(8);
00530 
00531         if(len < 7)
00532                 return(false);
00533 
00534         h.sync = BitRead(12);
00535         h.version = BitRead(1);
00536         h.layer = BitRead(2);
00537         h.fcrc = BitRead(1);
00538         h.profile = BitRead(2);
00539         h.freq = BitRead(4);
00540         h.privatebit = BitRead(1);
00541         h.channels = BitRead(3);
00542         h.original = BitRead(1);
00543         h.home = BitRead(1);
00544 
00545         h.copyright_id_bit = BitRead(1);
00546         h.copyright_id_start = BitRead(1);
00547         h.aac_frame_length = BitRead(13);
00548         h.adts_buffer_fullness = BitRead(11);
00549         h.no_raw_data_blocks_in_frame = BitRead(2);
00550 
00551         if(h.fcrc == 0) h.crc = BitRead(16);
00552 
00553         if(h.layer != 0 || h.freq >= 12 || h.aac_frame_length <= (h.fcrc == 0 ? 9 : 7))
00554                 return(false);
00555 
00556         h.FrameSize = h.aac_frame_length - (h.fcrc == 0 ? 9 : 7);
00557     static int freq[] = {96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000};
00558         h.nBytesPerSec = h.aac_frame_length * freq[h.freq] / 1024; // ok?
00559         h.rtDuration = 10000000i64 * 1024 / freq[h.freq]; // ok?
00560 
00561         if(!pmt) return(true);
00562 
00563         WAVEFORMATEX* wfe = (WAVEFORMATEX*)new BYTE[sizeof(WAVEFORMATEX)+5];
00564         memset(wfe, 0, sizeof(WAVEFORMATEX)+5);
00565         wfe->wFormatTag = WAVE_FORMAT_AAC;
00566         wfe->nChannels = h.channels <= 6 ? h.channels : 2;
00567         wfe->nSamplesPerSec = freq[h.freq];
00568         wfe->nBlockAlign = h.aac_frame_length;
00569         wfe->nAvgBytesPerSec = h.nBytesPerSec;
00570         wfe->cbSize = MakeAACInitData((BYTE*)(wfe+1), h.profile, wfe->nSamplesPerSec, wfe->nChannels);
00571 
00572         pmt->majortype = MEDIATYPE_Audio;
00573         pmt->subtype = MEDIASUBTYPE_AAC;
00574         pmt->formattype = FORMAT_WaveFormatEx;
00575         pmt->SetFormat((BYTE*)wfe, sizeof(WAVEFORMATEX)+wfe->cbSize);
00576 
00577         delete [] wfe;
00578 
00579         return(true);
00580 }
00581 
00582 bool CBaseSplitterFileEx::Read(ac3hdr& h, int len, CMediaType* pmt)
00583 {
00584         memset(&h, 0, sizeof(h));
00585 
00586         for(; len >= 7 && BitRead(16, true) != 0x0b77; len--)
00587                 BitRead(8);
00588 
00589         if(len < 7)
00590                 return(false);
00591 
00592         h.sync = (WORD)BitRead(16);
00593         h.crc1 = (WORD)BitRead(16);
00594         h.fscod = BitRead(2);
00595         h.frmsizecod = BitRead(6);
00596         h.bsid = BitRead(5);
00597         h.bsmod = BitRead(3);
00598         h.acmod = BitRead(3);
00599         if((h.acmod & 1) && h.acmod != 1) h.cmixlev = BitRead(2);
00600         if(h.acmod & 4) h.surmixlev = BitRead(2);
00601         if(h.acmod == 2) h.dsurmod = BitRead(2);
00602         h.lfeon = BitRead(1);
00603 
00604         if(h.bsid >= 12 || h.fscod == 3 || h.frmsizecod >= 38)
00605                 return(false);
00606 
00607         if(!pmt) return(true);
00608 
00609         WAVEFORMATEX wfe;
00610         memset(&wfe, 0, sizeof(wfe));
00611         wfe.wFormatTag = WAVE_FORMAT_DOLBY_AC3;
00612 
00613         static int channels[] = {2, 1, 2, 3, 3, 4, 4, 5};
00614         wfe.nChannels = channels[h.acmod] + h.lfeon;
00615 
00616         static int freq[] = {48000, 44100, 32000, 0};
00617         wfe.nSamplesPerSec = freq[h.fscod];
00618 
00619         switch(h.bsid)
00620         {
00621         case 9: wfe.nSamplesPerSec >>= 1; break;
00622         case 10: wfe.nSamplesPerSec >>= 2; break;
00623         case 11: wfe.nSamplesPerSec >>= 3; break;
00624         default: break;
00625         }
00626 
00627         static int rate[] = {32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640};
00628 
00629         wfe.nAvgBytesPerSec = rate[h.frmsizecod>>1] * 1000 / 8;
00630         wfe.nBlockAlign = (WORD)(1536 * wfe.nAvgBytesPerSec / wfe.nSamplesPerSec);
00631 
00632         pmt->majortype = MEDIATYPE_Audio;
00633         pmt->subtype = MEDIASUBTYPE_DOLBY_AC3;
00634         pmt->formattype = FORMAT_WaveFormatEx;
00635         pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
00636 
00637         return(true);
00638 }
00639 
00640 bool CBaseSplitterFileEx::Read(dtshdr& h, int len, CMediaType* pmt)
00641 {
00642         memset(&h, 0, sizeof(h));
00643 
00644         for(; len >= 10 && BitRead(32, true) != 0x7ffe8001; len--)
00645                 BitRead(8);
00646 
00647         if(len < 10)
00648                 return(false);
00649 
00650         h.sync = (DWORD)BitRead(32);
00651         h.frametype = BitRead(1);
00652         h.deficitsamplecount = BitRead(5);
00653         h.fcrc = BitRead(1);
00654         h.nblocks = BitRead(7);
00655         h.framebytes = (WORD)BitRead(14)+1;
00656         h.amode = BitRead(6);
00657         h.sfreq = BitRead(4);
00658         h.rate = BitRead(5);
00659 
00660         if(!pmt) return(true);
00661 
00662         WAVEFORMATEX wfe;
00663         memset(&wfe, 0, sizeof(wfe));
00664         wfe.wFormatTag = WAVE_FORMAT_DVD_DTS;
00665 
00666         static int channels[] = {1, 2, 2, 2, 2, 3, 3, 4, 4, 5, 6, 6, 6, 7, 8, 8};
00667         if(h.amode < countof(channels)) wfe.nChannels = channels[h.amode];
00668 
00669         static int freq[] = {0,8000,16000,32000,0,0,11025,22050,44100,0,0,12000,24000,48000,0,0};
00670         wfe.nSamplesPerSec = freq[h.sfreq];
00671 
00672         static int rate[] = 
00673         {
00674                 32000,56000,64000,96000,112000,128000,192000,224000,
00675                 256000,320000,384000,448000,512000,576000,640000,754500,
00676                 960000,1024000,1152000,1280000,1344000,1408000,1411200,1472000,
00677                 1509750,1920000,2048000,3072000,3840000,0,0,0
00678         };
00679         
00680         wfe.nAvgBytesPerSec = rate[h.rate] * 1000 / 8;
00681         wfe.nBlockAlign = h.framebytes;
00682 
00683         pmt->majortype = MEDIATYPE_Audio;
00684         pmt->subtype = MEDIASUBTYPE_DTS;
00685         pmt->formattype = FORMAT_WaveFormatEx;
00686         pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
00687 
00688         return(true);
00689 }
00690 
00691 bool CBaseSplitterFileEx::Read(lpcmhdr& h, CMediaType* pmt)
00692 {
00693         memset(&h, 0, sizeof(h));
00694 
00695         h.emphasis = BitRead(1);
00696         h.mute = BitRead(1);
00697         h.reserved1 = BitRead(1);
00698         h.framenum = BitRead(5);
00699         h.quantwordlen = BitRead(2);
00700         h.freq = BitRead(2);
00701         h.reserved2 = BitRead(1);
00702         h.channels = BitRead(3);
00703         h.drc = (BYTE)BitRead(8);
00704 
00705         if(h.channels > 2 || h.reserved1 || h.reserved2)
00706                 return(false);
00707 
00708         if(!pmt) return(true);
00709 
00710         WAVEFORMATEX wfe;
00711         memset(&wfe, 0, sizeof(wfe));
00712         wfe.wFormatTag = WAVE_FORMAT_PCM;
00713         wfe.nChannels = h.channels+1;
00714         static int freq[] = {48000, 96000, 44100, 32000};
00715         wfe.nSamplesPerSec = freq[h.freq];
00716         wfe.wBitsPerSample = 16;
00717         wfe.nBlockAlign = wfe.nChannels*wfe.wBitsPerSample>>3;
00718         wfe.nAvgBytesPerSec = wfe.nBlockAlign*wfe.nSamplesPerSec;
00719 
00720         pmt->majortype = MEDIATYPE_Audio;
00721         pmt->subtype = MEDIASUBTYPE_DVD_LPCM_AUDIO;
00722         pmt->formattype = FORMAT_WaveFormatEx;
00723         pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
00724 
00725         // TODO: what to do with dvd-audio lpcm?
00726 
00727         return(true);
00728 }
00729 
00730 bool CBaseSplitterFileEx::Read(dvdspuhdr& h, CMediaType* pmt)
00731 {
00732         memset(&h, 0, sizeof(h));
00733 
00734         if(!pmt) return(true);
00735 
00736         pmt->majortype = MEDIATYPE_Video;
00737         pmt->subtype = MEDIASUBTYPE_DVD_SUBPICTURE;
00738         pmt->formattype = FORMAT_None;
00739 
00740         return(true);
00741 }
00742 
00743 bool CBaseSplitterFileEx::Read(svcdspuhdr& h, CMediaType* pmt)
00744 {
00745         memset(&h, 0, sizeof(h));
00746 
00747         if(!pmt) return(true);
00748 
00749         pmt->majortype = MEDIATYPE_Video;
00750         pmt->subtype = MEDIASUBTYPE_SVCD_SUBPICTURE;
00751         pmt->formattype = FORMAT_None;
00752 
00753         return(true);
00754 }
00755 
00756 bool CBaseSplitterFileEx::Read(cvdspuhdr& h, CMediaType* pmt)
00757 {
00758         memset(&h, 0, sizeof(h));
00759 
00760         if(!pmt) return(true);
00761 
00762         pmt->majortype = MEDIATYPE_Video;
00763         pmt->subtype = MEDIASUBTYPE_CVD_SUBPICTURE;
00764         pmt->formattype = FORMAT_None;
00765 
00766         return(true);
00767 }
00768 
00769 bool CBaseSplitterFileEx::Read(ps2audhdr& h, CMediaType* pmt)
00770 {
00771         memset(&h, 0, sizeof(h));
00772 
00773         if(BitRead(16, true) != 'SS')
00774                 return(false);
00775 
00776         __int64 pos = GetPos();
00777 
00778         while(BitRead(16, true) == 'SS')
00779         {
00780                 DWORD tag = (DWORD)BitRead(32, true);
00781                 DWORD size = 0;
00782                 
00783                 if(tag == 'SShd')
00784                 {
00785                         BitRead(32);
00786                         Read((BYTE*)&size, sizeof(size));
00787                         ASSERT(size == 0x18);
00788                         Seek(GetPos());
00789                         Read((BYTE*)&h, sizeof(h));
00790                 }
00791                 else if(tag == 'SSbd')
00792                 {
00793                         BitRead(32);
00794                         Read((BYTE*)&size, sizeof(size));
00795                         break;
00796                 }
00797         }
00798 
00799         Seek(pos);
00800 
00801         if(!pmt) return(true);
00802 
00803         WAVEFORMATEXPS2 wfe;
00804         wfe.wFormatTag = 
00805                 h.unk1 == 0x01 ? WAVE_FORMAT_PS2_PCM : 
00806                 h.unk1 == 0x10 ? WAVE_FORMAT_PS2_ADPCM :
00807                 WAVE_FORMAT_UNKNOWN;
00808         wfe.nChannels = (WORD)h.channels;
00809         wfe.nSamplesPerSec = h.freq;
00810         wfe.wBitsPerSample = 16; // always?
00811         wfe.nBlockAlign = wfe.nChannels*wfe.wBitsPerSample>>3;
00812         wfe.nAvgBytesPerSec = wfe.nBlockAlign*wfe.nSamplesPerSec;
00813         wfe.dwInterleave = h.interleave;
00814 
00815         pmt->majortype = MEDIATYPE_Audio;
00816         pmt->subtype = FOURCCMap(wfe.wFormatTag);
00817         pmt->formattype = FORMAT_WaveFormatEx;
00818         pmt->SetFormat((BYTE*)&wfe, sizeof(wfe));
00819 
00820         return(true);
00821 }
00822 
00823 bool CBaseSplitterFileEx::Read(ps2subhdr& h, CMediaType* pmt)
00824 {
00825         memset(&h, 0, sizeof(h));
00826 
00827         if(!pmt) return(true);
00828 
00829         pmt->majortype = MEDIATYPE_Subtitle;
00830         pmt->subtype = MEDIASUBTYPE_PS2_SUB;
00831         pmt->formattype = FORMAT_None;
00832 
00833         return(true);
00834 }
00835 
00836 bool CBaseSplitterFileEx::Read(trhdr& h, bool fSync)
00837 {
00838         memset(&h, 0, sizeof(h));
00839 
00840         BitByteAlign();
00841 
00842         if(m_tslen == 0)
00843         {
00844                 __int64 pos = GetPos();
00845 
00846                 for(int i = 0; i < 192; i++)
00847                 {
00848                         if(BitRead(8, true) == 0x47)
00849                         {
00850                                 __int64 pos = GetPos();
00851                                 Seek(pos + 188);
00852                                 if(BitRead(8, true) == 0x47) {m_tslen = 188; break;}
00853                                 Seek(pos + 192);
00854                                 if(BitRead(8, true) == 0x47) {m_tslen = 192; break;}
00855                         }
00856 
00857                         BitRead(8);
00858                 }
00859 
00860                 Seek(pos);
00861 
00862                 if(m_tslen == 0)
00863                 {
00864                         return(false);
00865                 }
00866         }
00867 
00868         if(fSync)
00869         {
00870                 for(int i = 0; i < m_tslen; i++)
00871                 {
00872                         if(BitRead(8, true) == 0x47)
00873                         {
00874                                 if(i == 0) break;
00875                                 Seek(GetPos()+m_tslen);
00876                                 if(BitRead(8, true) == 0x47) {Seek(GetPos()-m_tslen); break;}
00877                         }
00878 
00879                         BitRead(8);
00880 
00881                         if(i == m_tslen-1)
00882                                 return(false);
00883                 }
00884         }
00885 
00886         if(BitRead(8, true) != 0x47)
00887                 return(false);
00888 
00889         h.next = GetPos() + m_tslen;
00890 
00891         h.sync = (BYTE)BitRead(8);
00892         h.error = BitRead(1);
00893         h.payloadstart = BitRead(1);
00894         h.transportpriority = BitRead(1);
00895         h.pid = BitRead(13);
00896         h.scrambling = BitRead(2);
00897         h.adapfield = BitRead(1);
00898         h.payload = BitRead(1);
00899         h.counter = BitRead(4);
00900 
00901         h.bytes = 184;
00902 
00903         if(h.adapfield)
00904         {
00905                 h.length = (BYTE)BitRead(8);
00906                 h.discontinuity = BitRead(1);
00907                 h.randomaccess = BitRead(1);
00908                 h.priority = BitRead(1);
00909                 h.PCR = BitRead(1);
00910                 h.OPCR = BitRead(1);
00911                 h.splicingpoint = BitRead(1);
00912                 h.privatedata = BitRead(1);
00913                 h.extension = BitRead(1);
00914                 if(!(0 < h.length && h.length <= 183))
00915                         return(false);
00916                 for(int i = 1; i < h.length; i++)
00917                         BitRead(8);
00918 
00919                 h.bytes = 183 - h.length;
00920         }
00921 
00922         return(true);
00923 }
00924 
00925 bool CBaseSplitterFileEx::Read(pvahdr& h, bool fSync)
00926 {
00927         memset(&h, 0, sizeof(h));
00928 
00929         BitByteAlign();
00930 
00931         if(fSync)
00932         {
00933                 for(int i = 0; i < 65536; i++)
00934                 {
00935                         if((BitRead(64, true)&0xfffffc00ffe00000i64) == 0x4156000055000000i64) 
00936                                 break;
00937                         BitRead(8);
00938                 }
00939         }
00940 
00941         if((BitRead(64, true)&0xfffffc00ffe00000i64) != 0x4156000055000000i64)
00942                 return(false);
00943 
00944         h.sync = (WORD)BitRead(16);
00945         h.streamid = (BYTE)BitRead(8);
00946         h.counter = (BYTE)BitRead(8);
00947         h.res1 = (BYTE)BitRead(8);
00948         h.res2 = BitRead(3);
00949         h.fpts = BitRead(1);
00950         h.postbytes = BitRead(2);
00951         h.prebytes = BitRead(2);
00952         h.length = (WORD)BitRead(16);
00953 
00954         if(h.length > 6136)
00955                 return(false);
00956 
00957         __int64 pos = GetPos();
00958 
00959         if(h.streamid == 1 && h.fpts)
00960         {
00961                 h.pts = 10000*BitRead(32)/90;
00962         }
00963         else if(h.streamid == 2 && (h.fpts || (BitRead(32, true)&0xffffffe0) == 0x000001c0))
00964         {
00965                 BYTE b;
00966                 if(!NextMpegStartCode(b, 4)) return(false);
00967                 peshdr h2;
00968                 if(!Read(h2, b)) return(false);
00969                 if(h.fpts = h2.fpts) h.pts = h2.pts;
00970         }
00971 
00972         BitRead(8*h.prebytes);
00973 
00974         h.length -= GetPos() - pos;
00975 
00976         return(true);
00977 }
00978 
00979 bool CBaseSplitterFileEx::Read(avchdr& h, int len, CMediaType* pmt)
00980 {
00981         __int64 endpos = GetPos() + len; // - sequence header length
00982 
00983         __int64 spspos = 0, spslen = 0;
00984         __int64 ppspos = 0, ppslen = 0;
00985 
00986         while(GetPos() < endpos+4 && BitRead(32, true) == 0x00000001)
00987         {
00988                 __int64 pos = GetPos();
00989 
00990                 BitRead(32);
00991                 BYTE id = BitRead(8);
00992 
00993                 if(spspos != 0 && spslen == 0) spslen = pos - spspos;
00994                 else if(ppspos != 0 && ppslen == 0) ppslen = pos - ppspos;
00995                 
00996                 if((id&0x9f) == 0x07 && (id&0x60) != 0)
00997                 {
00998                         spspos = pos;
00999 
01000                         h.profile = (BYTE)BitRead(8);
01001                         BitRead(8);
01002                         h.level = (BYTE)BitRead(8);
01003 
01004                         UExpGolombRead(); // seq_parameter_set_id
01005                         UExpGolombRead(); // log2_max_frame_num_minus4
01006 
01007                         UINT64 pic_order_cnt_type = UExpGolombRead();
01008 
01009                         if(pic_order_cnt_type == 0)
01010                         {
01011                                 UExpGolombRead(); // log2_max_pic_order_cnt_lsb_minus4
01012                         }
01013                         else if(pic_order_cnt_type == 1)
01014                         {
01015                                 BitRead(1); // delta_pic_order_always_zero_flag
01016                                 SExpGolombRead(); // offset_for_non_ref_pic
01017                                 SExpGolombRead(); // offset_for_top_to_bottom_field
01018                                 UINT64 num_ref_frames_in_pic_order_cnt_cycle = UExpGolombRead();
01019                                 for(int i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++)
01020                                         SExpGolombRead(); // offset_for_ref_frame[i]
01021                         }
01022 
01023                         UExpGolombRead(); // num_ref_frames
01024                         BitRead(1); // gaps_in_frame_num_value_allowed_flag
01025 
01026                         UINT64 pic_width_in_mbs_minus1 = UExpGolombRead();
01027                         UINT64 pic_height_in_map_units_minus1 = UExpGolombRead();
01028                         BYTE frame_mbs_only_flag = (BYTE)BitRead(1);
01029 
01030                         h.width = (pic_width_in_mbs_minus1 + 1) * 16;
01031                         h.height = (2 - frame_mbs_only_flag) * (pic_height_in_map_units_minus1 + 1) * 16;
01032                 }
01033                 else if((id&0x9f) == 0x08 && (id&0x60) != 0)
01034                 {
01035                         ppspos = pos;
01036                 }
01037 
01038                 BitByteAlign();
01039 
01040                 while(GetPos() < endpos+4 && BitRead(32, true) != 0x00000001)
01041                         BitRead(8);
01042         }
01043 
01044         if(!spspos || !spslen || !ppspos || !ppslen) 
01045                 return(false);
01046 
01047         if(!pmt) return(true);
01048 
01049         {
01050                 pmt->majortype = MEDIATYPE_Video;
01051                 pmt->subtype = MEDIASUBTYPE_MPEG2_VIDEO;
01052                 pmt->formattype = FORMAT_MPEG2_VIDEO;
01053                 int len = FIELD_OFFSET(MPEG2VIDEOINFO, dwSequenceHeader) + spslen + ppslen;
01054                 MPEG2VIDEOINFO* vi = (MPEG2VIDEOINFO*)new BYTE[len];
01055                 memset(vi, 0, len);
01056                 // vi->hdr.dwBitRate = ;
01057                 // vi->hdr.AvgTimePerFrame = ;
01058                 vi->hdr.dwPictAspectRatioX = h.width;
01059                 vi->hdr.dwPictAspectRatioY = h.height;
01060                 vi->hdr.bmiHeader.biSize = sizeof(vi->hdr.bmiHeader);
01061                 vi->hdr.bmiHeader.biWidth = h.width;
01062                 vi->hdr.bmiHeader.biHeight = h.height;
01063                 vi->hdr.bmiHeader.biCompression = '1cva';
01064                 vi->dwProfile = h.profile;
01065                 vi->dwFlags = 4; // ?
01066                 vi->dwLevel = h.level;
01067                 vi->cbSequenceHeader = spslen + ppslen;
01068                 Seek(spspos);
01069                 Read((BYTE*)&vi->dwSequenceHeader[0], spslen);
01070                 Seek(ppspos);
01071                 Read((BYTE*)&vi->dwSequenceHeader[0] + spslen, ppslen);
01072                 pmt->SetFormat((BYTE*)vi, len);
01073                 delete [] vi;
01074         }
01075 
01076         return(true);
01077 }

Generated on Tue Dec 13 14:47:11 2005 for guliverkli by  doxygen 1.4.5