00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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);
00101 }
00102
00103 #endif
00104
00105
00106
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
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);
00152 int deficitsamplecount = (buff[0]>>2)&31;
00153 int crcpresent = (buff[0]>>1)&1;
00154 int npcmsampleblocks = ((buff[0]&1)<<6)|(buff[1]>>2);
00155 int framebytes = (((buff[1]&3)<<12)|(buff[2]<<4)|(buff[3]>>4)) + 1;
00156 int audiochannelarrangement = (buff[3]&15)<<2|(buff[4]>>6);
00157 int freq = (buff[4]>>2)&15;
00158 int transbitrate = ((buff[4]&3)<<3)|(buff[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
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);
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,
00262 0x44,0x00,0x04,0x00,0x04,0x01,
00263 0x01,0x89,0xC3,0xF8,
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,
00277 0x07,0xEC,
00278 0x81,0x80,
00279 0x08,
00280 0x21,0x00,0x01,0x00,0x01,
00281 0xFF,0xFF,0xFF,
00282 m_streamid,
00283 0x01,0x00,0x01,
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 }