DTSAC3Source.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 <mmreg.h>
00024 #include <ks.h>
00025 #include <initguid.h>
00026 #include <uuids.h>
00027 #include "..\..\..\..\include\moreuuids.h"
00028 #include "dtsac3source.h"
00029 #include "..\..\..\DSUtil\DSUtil.h"
00030 
00031 #ifdef REGISTER_FILTER
00032 
00033 const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
00034 {
00035         {&MEDIATYPE_Audio, &MEDIASUBTYPE_DTS},
00036         {&MEDIATYPE_DVD_ENCRYPTED_PACK, &MEDIASUBTYPE_DTS},
00037         {&MEDIATYPE_Audio, &MEDIASUBTYPE_DOLBY_AC3},
00038         {&MEDIATYPE_DVD_ENCRYPTED_PACK, &MEDIASUBTYPE_DOLBY_AC3},
00039 };
00040 
00041 const AMOVIESETUP_PIN sudOpPin[] =
00042 {
00043         {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut), sudPinTypesOut}
00044 };
00045 
00046 const AMOVIESETUP_FILTER sudFilter[] =
00047 {
00048         {&__uuidof(CDTSAC3Source), L"DTS/AC3 Source", MERIT_UNLIKELY, countof(sudOpPin), sudOpPin}
00049 };
00050 
00051 CFactoryTemplate g_Templates[] =
00052 {
00053         {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CDTSAC3Source>, NULL, &sudFilter[0]}
00054 };
00055 
00056 int g_cTemplates = countof(g_Templates);
00057 
00058 STDAPI DllRegisterServer()
00059 {
00060         SetRegKeyValue(
00061                 _T("Media Type\\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{B4A7BE85-551D-4594-BDC7-832B09185041}"), 
00062                 _T("0"), _T("0,4,,7FFE8001"));
00063 
00064         SetRegKeyValue(
00065                 _T("Media Type\\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{B4A7BE85-551D-4594-BDC7-832B09185041}"), 
00066                 _T("1"), _T("0,2,,0B77"));
00067 
00068         SetRegKeyValue(
00069                 _T("Media Type\\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{B4A7BE85-551D-4594-BDC7-832B09185041}"), 
00070                 _T("2"), _T("0,2,,770B"));
00071 
00072         SetRegKeyValue(
00073                 _T("Media Type\\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{B4A7BE85-551D-4594-BDC7-832B09185041}"), 
00074                 _T("Source Filter"), _T("{B4A7BE85-551D-4594-BDC7-832B09185041}"));
00075 
00076         SetRegKeyValue(
00077                 _T("Media Type\\Extensions"), _T(".dts"), 
00078                 _T("Source Filter"), _T("{B4A7BE85-551D-4594-BDC7-832B09185041}"));
00079 
00080         SetRegKeyValue(
00081                 _T("Media Type\\Extensions"), _T(".ac3"), 
00082                 _T("Source Filter"), _T("{B4A7BE85-551D-4594-BDC7-832B09185041}"));
00083 
00084         return AMovieDllRegisterServer2(TRUE);
00085 }
00086 
00087 STDAPI DllUnregisterServer()
00088 {
00089         DeleteRegKey(_T("Media Type\\{e436eb83-524f-11ce-9f53-0020af0ba770}"), _T("{B4A7BE85-551D-4594-BDC7-832B09185041}"));
00090         DeleteRegKey(_T("Media Type\\Extensions"), _T(".dts"));
00091         DeleteRegKey(_T("Media Type\\Extensions"), _T(".ac3"));
00092 
00093         return AMovieDllRegisterServer2(FALSE);
00094 }
00095 
00096 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
00097 
00098 BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
00099 {
00100     return DllEntryPoint((HINSTANCE)hModule, dwReason, 0); // "DllMain" of the dshow baseclasses;
00101 }
00102 
00103 #endif
00104 
00105 //
00106 // CDTSAC3Source
00107 //
00108 
00109 CDTSAC3Source::CDTSAC3Source(LPUNKNOWN lpunk, HRESULT* phr)
00110         : CBaseSource<CDTSAC3Stream>(NAME("CDTSAC3Source"), lpunk, phr, __uuidof(this))
00111 {
00112 }
00113 
00114 CDTSAC3Source::~CDTSAC3Source()
00115 {
00116 }
00117 
00118 // CDTSAC3Stream
00119 
00120 CDTSAC3Stream::CDTSAC3Stream(const WCHAR* wfn, CSource* pParent, HRESULT* phr) 
00121         : CBaseStream(NAME("CDTSAC3Stream"), pParent, phr)
00122         , m_nFileOffset(0)
00123 {
00124         CAutoLock cAutoLock(&m_cSharedState);
00125 
00126         m_subtype = GUID_NULL;
00127         m_wFormatTag = 0;
00128         m_streamid = 0;
00129 
00130         CString fn(wfn);
00131 
00132         if(!m_file.Open(fn, CFile::modeRead|CFile::shareDenyWrite))
00133         {
00134                 if(phr) *phr = E_FAIL;
00135                 return;
00136         }
00137 
00138         DWORD id = 0;
00139         if(m_file.Read(&id, sizeof(id)) != sizeof(id)
00140         || id != 0x0180FE7F && (WORD)id != 0x0b77 && (WORD)id != 0x770b)
00141         {
00142                 if(phr) *phr = E_FAIL;
00143                 return;
00144         }
00145 
00146         if(id == 0x0180FE7F)
00147         {
00148                 BYTE buff[8];
00149                 m_file.Read(buff, 8);
00150 
00151                 int frametype = (buff[0]>>7); // 1
00152                 int deficitsamplecount = (buff[0]>>2)&31; // 5
00153                 int crcpresent = (buff[0]>>1)&1; // 1
00154                 int npcmsampleblocks = ((buff[0]&1)<<6)|(buff[1]>>2); // 7
00155                 int framebytes = (((buff[1]&3)<<12)|(buff[2]<<4)|(buff[3]>>4)) + 1; // 14
00156                 int audiochannelarrangement = (buff[3]&15)<<2|(buff[4]>>6); // 6
00157                 int freq = (buff[4]>>2)&15; // 4
00158                 int transbitrate = ((buff[4]&3)<<3)|(buff[5]>>5); // 5
00159 
00160                 int freqtbl[] = 
00161                 {
00162                         0,8000,16000,32000,
00163                         0,0,
00164                         11025,22050,44100,
00165                         0,0,
00166                         12000,24000,48000,
00167                         0,0
00168                 };
00169 
00170                 int bitratetbl[] = 
00171                 {
00172                         32000,56000,64000,96000,112000,128000,192000,224000,
00173                         256000,320000,384000,448000,512000,576000,640000,754500,
00174                         960000,1024000,1152000,1280000,1344000,1408000,1411200,1472000,
00175                         1509750,1920000,2048000,3072000,3840000,0,0,0
00176                 };
00177 
00178                 m_nSamplesPerSec = freqtbl[freq];
00179                 m_nAvgBytesPerSec = (bitratetbl[transbitrate] + 4) / 8;
00180 //              m_nBytesPerFrame = m_nAvgBytesPerSec*10.656063618290258449304174950298/1000 + 0.5;
00181                 m_nBytesPerFrame = framebytes;
00182                 m_AvgTimePerFrame = 10000000i64 * m_nBytesPerFrame * 8 / bitratetbl[transbitrate];
00183 
00184                 m_subtype = MEDIASUBTYPE_DTS;
00185                 m_wFormatTag = WAVE_FORMAT_DVD_DTS;
00186                 m_streamid = 0x88;
00187         }
00188         else
00189         {
00190                 BYTE info;
00191                 if((BYTE)id == 0x77) m_file.Seek(1, CFile::current); // LE
00192                 m_file.Read(&info, 1);
00193 
00194                 BYTE freq = info>>6;
00195                 BYTE bitrate = info&0x3f;
00196 
00197                 if(bitrate >= 38)
00198                 {
00199                         if(phr) *phr = E_FAIL;
00200                         return;
00201                 }
00202 
00203                 int freqtbl[] = {48000,44000,32000,48000};
00204 
00205                 int bitratetbl[] =
00206                 {
00207                         32000,32000,40000,40000,48000,48000,56000,56000,64000,64000,
00208                         80000,80000,96000,96000,112000,112000,128000,128000,160000,160000,
00209                         192000,192000,224000,224000,256000,256000,320000,320000,384000,384000,
00210                         448000,448000,512000,512000,576000,576000,640000,640000
00211                 };
00212 
00213                 m_nSamplesPerSec = freqtbl[freq];
00214                 m_nAvgBytesPerSec = (bitratetbl[bitrate] + 4) / 8;
00215                 m_nBytesPerFrame = m_nAvgBytesPerSec*32/1000;
00216                 m_AvgTimePerFrame = 10000000i64 * m_nBytesPerFrame * 8 / bitratetbl[bitrate];
00217 
00218                 m_subtype = MEDIASUBTYPE_DOLBY_AC3;
00219                 m_wFormatTag = WAVE_FORMAT_DOLBY_AC3;
00220                 m_streamid = 0x80;
00221         }
00222 
00223         m_rtDuration = m_AvgTimePerFrame * m_file.GetLength() / m_nBytesPerFrame;
00224         m_rtStop = m_rtDuration;
00225 }
00226 
00227 CDTSAC3Stream::~CDTSAC3Stream()
00228 {
00229 }
00230 
00231 HRESULT CDTSAC3Stream::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties)
00232 {
00233     ASSERT(pAlloc);
00234     ASSERT(pProperties);
00235 
00236     HRESULT hr = NOERROR;
00237 
00238         pProperties->cBuffers = 1;
00239         pProperties->cbBuffer = m_nBytesPerFrame+35;
00240 
00241     ALLOCATOR_PROPERTIES Actual;
00242     if(FAILED(hr = pAlloc->SetProperties(pProperties, &Actual))) return hr;
00243 
00244     if(Actual.cbBuffer < pProperties->cbBuffer) return E_FAIL;
00245     ASSERT(Actual.cBuffers == pProperties->cBuffers);
00246 
00247     return NOERROR;
00248 }
00249 
00250 HRESULT CDTSAC3Stream::FillBuffer(IMediaSample* pSample, int nFrame, BYTE* pOut, long& len)
00251 {
00252         BYTE* pOutOrg = pOut;
00253 
00254         const GUID* majortype = &m_mt.majortype;
00255         const GUID* subtype = &m_mt.subtype;
00256 
00257         if(*majortype == MEDIATYPE_DVD_ENCRYPTED_PACK)
00258         {
00259                 BYTE PESHeader[] = 
00260                 {
00261                         0x00,0x00,0x01,0xBA,                    // PES id
00262                         0x44,0x00,0x04,0x00,0x04,0x01,  // SCR (0)
00263                         0x01,0x89,0xC3,0xF8,                    // mux rate (1260000 bytes/sec, 22bits), marker (2bits), reserved (~0, 5bits), stuffing (0, 3bits)
00264                 };
00265 
00266                 memcpy(pOut, &PESHeader, sizeof(PESHeader));
00267                 pOut += sizeof(PESHeader);
00268 
00269                 majortype = &MEDIATYPE_MPEG2_PES;
00270         }
00271 
00272         if(*majortype == MEDIATYPE_MPEG2_PES)
00273         {
00274                 BYTE Private1Header[] = 
00275                 {
00276                         0x00,0x00,0x01,0xBD,                    // private stream 1 id
00277                         0x07,0xEC,                                              // packet length (TODO: modify it later)
00278                         0x81,0x80,                                              // marker, original, PTS - flags
00279                         0x08,                                                   // packet data starting offset
00280                         0x21,0x00,0x01,0x00,0x01,               // PTS (0)
00281                         0xFF,0xFF,0xFF,                                 // stuffing
00282                         m_streamid,                                             // stream id (0)
00283                         0x01,0x00,0x01,                                 // no idea about this (might be the current sector on the disc), but dvd2avi doesn't output it to the ac3/dts file so we have to put it back
00284                 };
00285 
00286                 memcpy(pOut, &Private1Header, sizeof(Private1Header));
00287                 pOut += sizeof(Private1Header);
00288 
00289                 majortype = &MEDIATYPE_Audio;
00290         }
00291 
00292         if(*majortype == MEDIATYPE_Audio)
00293         {
00294                 m_file.Seek(m_nFileOffset + nFrame*m_nBytesPerFrame, CFile::begin);
00295                 if(m_file.Read(pOut, m_nBytesPerFrame) < m_nBytesPerFrame) return S_FALSE;
00296                 pOut += m_nBytesPerFrame;
00297         }
00298 
00299         len = pOut - pOutOrg;
00300 
00301         return S_OK;
00302 }
00303 
00304 bool CDTSAC3Stream::CheckDTS(const CMediaType* pmt)
00305 {
00306         return (pmt->majortype == MEDIATYPE_Audio
00307                         || pmt->majortype == MEDIATYPE_MPEG2_PES 
00308                         || pmt->majortype == MEDIATYPE_DVD_ENCRYPTED_PACK)
00309                 && pmt->subtype == MEDIASUBTYPE_DTS;
00310 }
00311 
00312 bool CDTSAC3Stream::CheckWAVEDTS(const CMediaType* pmt)
00313 {
00314         return pmt->majortype == MEDIATYPE_Audio
00315                 && pmt->subtype == MEDIASUBTYPE_WAVE_DTS
00316                 && pmt->formattype == FORMAT_WaveFormatEx
00317                 && ((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag == WAVE_FORMAT_DVD_DTS;
00318 }
00319 
00320 bool CDTSAC3Stream::CheckAC3(const CMediaType* pmt)
00321 {
00322         return (pmt->majortype == MEDIATYPE_Audio
00323                         || pmt->majortype == MEDIATYPE_MPEG2_PES 
00324                         || pmt->majortype == MEDIATYPE_DVD_ENCRYPTED_PACK)
00325                 && pmt->subtype == MEDIASUBTYPE_DOLBY_AC3;
00326 }
00327 
00328 bool CDTSAC3Stream::CheckWAVEAC3(const CMediaType* pmt)
00329 {
00330         return pmt->majortype == MEDIATYPE_Audio
00331                 && pmt->subtype == MEDIASUBTYPE_DOLBY_AC3
00332                 && pmt->formattype == FORMAT_WaveFormatEx
00333                 && ((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag == WAVE_FORMAT_DOLBY_AC3;
00334 }
00335 
00336 HRESULT CDTSAC3Stream::GetMediaType(int iPosition, CMediaType* pmt)
00337 {
00338     CAutoLock cAutoLock(m_pFilter->pStateLock());
00339 
00340         if(iPosition >= 0 && iPosition < 5)
00341         {
00342                 pmt->subtype = m_subtype;
00343                 pmt->formattype = FORMAT_WaveFormatEx;
00344                 WAVEFORMATEX* wfe = (WAVEFORMATEX*)pmt->AllocFormatBuffer(sizeof(WAVEFORMATEX));
00345                 memset(wfe, 0, sizeof(WAVEFORMATEX));
00346                 wfe->cbSize = sizeof(WAVEFORMATEX);
00347                 wfe->wFormatTag = WAVE_FORMAT_PCM;
00348                 wfe->nSamplesPerSec = m_nSamplesPerSec;
00349                 wfe->nAvgBytesPerSec = m_nAvgBytesPerSec;
00350                 wfe->nChannels = 6;
00351 
00352                 switch(iPosition)
00353                 {
00354                 case 0:
00355                         pmt->majortype = MEDIATYPE_Audio;
00356                         break;
00357                 case 1:
00358                         pmt->ResetFormatBuffer();
00359                         pmt->formattype = FORMAT_None;
00360                 case 2:
00361                         pmt->majortype = MEDIATYPE_MPEG2_PES;
00362                         break;
00363                 case 3:
00364                         pmt->ResetFormatBuffer();
00365                         pmt->formattype = FORMAT_None;
00366                 case 4:
00367                         pmt->majortype = MEDIATYPE_DVD_ENCRYPTED_PACK;
00368                         break;
00369                 default:
00370                         return E_INVALIDARG;
00371                 }
00372         }
00373         else if(iPosition == 5)
00374         {
00375                 pmt->majortype = MEDIATYPE_Audio;
00376                 pmt->subtype = FOURCCMap(m_wFormatTag);
00377                 pmt->formattype = FORMAT_WaveFormatEx;
00378                 WAVEFORMATEX* wfe = (WAVEFORMATEX*)pmt->AllocFormatBuffer(sizeof(WAVEFORMATEX));
00379                 memset(wfe, 0, sizeof(WAVEFORMATEX));
00380                 wfe->cbSize = sizeof(WAVEFORMATEX);
00381                 wfe->wFormatTag = m_wFormatTag;
00382                 wfe->nSamplesPerSec = m_nSamplesPerSec;
00383                 wfe->nAvgBytesPerSec = m_nAvgBytesPerSec;
00384                 wfe->nChannels = 2;
00385                 wfe->nBlockAlign = 1;
00386         }
00387         else
00388         {
00389                 return VFW_S_NO_MORE_ITEMS;
00390         }
00391 
00392     pmt->SetTemporalCompression(FALSE);
00393 
00394         return S_OK;
00395 }
00396 
00397 HRESULT CDTSAC3Stream::CheckMediaType(const CMediaType* pmt)
00398 {
00399         return CheckDTS(pmt) || CheckWAVEDTS(pmt)
00400                 || CheckAC3(pmt) || CheckWAVEAC3(pmt)
00401                 ? S_OK
00402                 : E_INVALIDARG;
00403 }

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