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 <atlbase.h>
00024 #include "avi2ac3filter.h"
00025 #include "..\..\..\DSUtil\DSUtil.h"
00026
00027 #include <initguid.h>
00028 #include "..\..\..\..\include\moreuuids.h"
00029
00030 #ifdef REGISTER_FILTER
00031
00032 const AMOVIESETUP_MEDIATYPE sudPinTypesIn[] =
00033 {
00034 {&MEDIATYPE_Audio, &MEDIASUBTYPE_WAVE_DOLBY_AC3},
00035 {&MEDIATYPE_Audio, &MEDIASUBTYPE_WAVE_DTS},
00036 };
00037
00038 const AMOVIESETUP_MEDIATYPE sudPinTypesOut[] =
00039 {
00040 {&MEDIATYPE_Audio, &MEDIASUBTYPE_NULL},
00041 };
00042
00043 const AMOVIESETUP_PIN sudpPins[] =
00044 {
00045 {L"Input", FALSE, FALSE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesIn), sudPinTypesIn},
00046 {L"Output", FALSE, TRUE, FALSE, FALSE, &CLSID_NULL, NULL, countof(sudPinTypesOut), sudPinTypesOut}
00047 };
00048
00049 const AMOVIESETUP_FILTER sudFilter[] =
00050 {
00051 {&__uuidof(CAVI2AC3Filter), L"AVI<->AC3/DTS", MERIT_UNLIKELY, countof(sudpPins), sudpPins}
00052 };
00053
00054 CFactoryTemplate g_Templates[] =
00055 {
00056 {sudFilter[0].strName, sudFilter[0].clsID, CreateInstance<CAVI2AC3Filter>, NULL, &sudFilter[0]}
00057 };
00058
00059 int g_cTemplates = countof(g_Templates);
00060
00061 STDAPI DllRegisterServer()
00062 {
00063 return AMovieDllRegisterServer2(TRUE);
00064 }
00065
00066 STDAPI DllUnregisterServer()
00067 {
00068 return AMovieDllRegisterServer2(FALSE);
00069 }
00070
00071 extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
00072
00073 BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
00074 {
00075 return DllEntryPoint((HINSTANCE)hModule, dwReason, 0);
00076 }
00077
00078 #endif
00079
00080
00081
00082
00083
00084 CAVI2AC3Filter::CAVI2AC3Filter(LPUNKNOWN lpunk, HRESULT* phr)
00085 : CTransformFilter(NAME("CAVI2AC3Filter"), lpunk, __uuidof(this))
00086 {
00087 if(phr) *phr = S_OK;
00088 }
00089
00090 CAVI2AC3Filter::~CAVI2AC3Filter()
00091 {
00092 }
00093
00094 HRESULT CAVI2AC3Filter::Transform(IMediaSample* pSample, IMediaSample* pOutSample)
00095 {
00096 HRESULT hr;
00097
00098 BYTE* pIn = NULL;
00099 if(FAILED(hr = pSample->GetPointer(&pIn))) return hr;
00100 BYTE* pInOrg = pIn;
00101
00102 long len = pSample->GetActualDataLength();
00103 if(len <= 0) return S_FALSE;
00104
00105 BYTE* pOut = NULL;
00106 if(FAILED(hr = pOutSample->GetPointer(&pOut))) return hr;
00107 BYTE* pOutOrg = pOut;
00108
00109 int size = pOutSample->GetSize();
00110
00111 if((CheckAC3(&m_pInput->CurrentMediaType()) || CheckDTS(&m_pInput->CurrentMediaType()))
00112 && (CheckWAVEAC3(&m_pOutput->CurrentMediaType()) || CheckWAVEDTS(&m_pOutput->CurrentMediaType())))
00113 {
00114 if(*(DWORD*)pIn == 0xBA010000)
00115 {
00116 pIn += 14;
00117 }
00118
00119 if(*(DWORD*)pIn == 0xBD010000)
00120 {
00121 pIn += 8 + 1 + pIn[8] + 1 + 3;
00122 }
00123
00124 len -= (pInOrg - pIn);
00125
00126 if(size < len) return E_FAIL;
00127
00128 memcpy(pOut, pIn, len);
00129 pOut += len;
00130 }
00131 else if((CheckWAVEAC3(&m_pInput->CurrentMediaType()) || CheckWAVEDTS(&m_pInput->CurrentMediaType()))
00132 && (CheckAC3(&m_pOutput->CurrentMediaType()) || CheckDTS(&m_pOutput->CurrentMediaType())))
00133 {
00134 if((m_pOutput->CurrentMediaType().majortype == MEDIATYPE_DVD_ENCRYPTED_PACK
00135 || m_pOutput->CurrentMediaType().majortype == MEDIATYPE_MPEG2_PES)
00136 && (len + 12 + 3) >= 0x10000)
00137 {
00138 REFERENCE_TIME rtStart = 0, rtStop = 1;
00139 bool fHasTime = (S_OK == pSample->GetTime(&rtStart, &rtStop));
00140
00141 bool fDiscontinuity = (S_OK == pOutSample->IsDiscontinuity());
00142
00143 int pos = 0;
00144 while(pos < len)
00145 {
00146 int curlen = min(len - pos, 2013);
00147 pos += 2013;
00148
00149 CComPtr<IMediaSample> pOutSample;
00150 hr = InitializeOutputSample(pSample, &pOutSample);
00151
00152 if(fDiscontinuity)
00153 {
00154 if(fHasTime)
00155 {
00156 rtStop = rtStart + (rtStop - rtStart) * curlen / len;
00157 pOutSample->SetTime(&rtStart, &rtStop);
00158 }
00159
00160 fDiscontinuity = false;
00161 }
00162 else
00163 {
00164 pOutSample->SetTime(NULL, NULL);
00165 pOutSample->SetDiscontinuity(FALSE);
00166 }
00167
00168 BYTE* pOut = NULL;
00169 if(FAILED(hr = pOutSample->GetPointer(&pOut))) return hr;
00170 BYTE* pOutOrg = pOut;
00171
00172 int size = pOutSample->GetSize();
00173
00174 const GUID* majortype = &m_pOutput->CurrentMediaType().majortype;
00175 const GUID* subtype = &m_pOutput->CurrentMediaType().subtype;
00176
00177 if(*majortype == MEDIATYPE_DVD_ENCRYPTED_PACK)
00178 {
00179 if(size < curlen + 32 + 3) return E_FAIL;
00180
00181 BYTE PESHeader[] =
00182 {
00183 0x00,0x00,0x01,0xBA,
00184 0x44,0x00,0x04,0x00,0x04,0x01,
00185 0x01,0x89,0xC3,0xF8,
00186 };
00187
00188 memcpy(pOut, &PESHeader, sizeof(PESHeader));
00189 pOut += sizeof(PESHeader);
00190
00191 majortype = &MEDIATYPE_MPEG2_PES;
00192 }
00193
00194 if(*majortype == MEDIATYPE_MPEG2_PES)
00195 {
00196 if(size < curlen + 20 + 3) return E_FAIL;
00197
00198 BYTE Private1Header[] =
00199 {
00200 0x00,0x00,0x01,0xBD,
00201 0x07,0xEC,
00202 0x81,0x80,
00203 0x08,
00204 0x21,0x00,0x01,0x00,0x01,
00205 0xFF,0xFF,0xFF,
00206 0x80,
00207 0x01,0x00,0x01,
00208 };
00209
00210 int packetlen = curlen + 12 + 3;
00211 ASSERT(packetlen <= 0xffff);
00212 Private1Header[4] = (packetlen>>8)&0xff;
00213 Private1Header[5] = packetlen&0xff;
00214
00215 if(*subtype == MEDIASUBTYPE_DTS)
00216 {
00217 Private1Header[17] += 8;
00218 }
00219
00220 if(*subtype == MEDIASUBTYPE_DOLBY_AC3)
00221 {
00222 for(int i = 0; i < curlen; i++)
00223 {
00224 if(*(DWORD*)&pIn[i] == 0x770B)
00225 {
00226 i++;
00227 Private1Header[19] = (i>>8)&0xff;
00228 Private1Header[20] = i&0xff;
00229 break;
00230 }
00231 }
00232 }
00233 else if(*subtype == MEDIASUBTYPE_DTS)
00234 {
00235 for(int i = 0; i < curlen; i++)
00236 {
00237 if(*(DWORD*)&pIn[i] == 0x0180FE7F)
00238 {
00239 i++;
00240 Private1Header[19] = (i>>8)&0xff;
00241 Private1Header[20] = i&0xff;
00242 break;
00243 }
00244 }
00245 }
00246
00247 memcpy(pOut, &Private1Header, sizeof(Private1Header));
00248 pOut += sizeof(Private1Header);
00249
00250 majortype = &MEDIATYPE_Audio;
00251 }
00252
00253 if(*majortype == MEDIATYPE_Audio)
00254 {
00255 if(size < curlen) return E_FAIL;
00256 memcpy(pOut, pIn, curlen);
00257 pIn += curlen;
00258 pOut += curlen;
00259 }
00260
00261 pOutSample->SetActualDataLength(pOut - pOutOrg);
00262
00263 hr = m_pOutput->Deliver(pOutSample);
00264 }
00265
00266 return S_FALSE;
00267 }
00268 else
00269 {
00270 const GUID* majortype = &m_pOutput->CurrentMediaType().majortype;
00271 const GUID* subtype = &m_pOutput->CurrentMediaType().subtype;
00272
00273 if(*majortype == MEDIATYPE_DVD_ENCRYPTED_PACK)
00274 {
00275 if(size < len + 32 + 3) return E_FAIL;
00276
00277 BYTE PESHeader[] =
00278 {
00279 0x00,0x00,0x01,0xBA,
00280 0x44,0x00,0x04,0x00,0x04,0x01,
00281 0x01,0x89,0xC3,0xF8,
00282 };
00283
00284 memcpy(pOut, &PESHeader, sizeof(PESHeader));
00285 pOut += sizeof(PESHeader);
00286
00287 majortype = &MEDIATYPE_MPEG2_PES;
00288 }
00289
00290 if(*majortype == MEDIATYPE_MPEG2_PES)
00291 {
00292 if(size < len + 20 + 3) return E_FAIL;
00293
00294 BYTE Private1Header[] =
00295 {
00296 0x00,0x00,0x01,0xBD,
00297 0x07,0xEC,
00298 0x81,0x80,
00299 0x08,
00300 0x21,0x00,0x01,0x00,0x01,
00301 0xFF,0xFF,0xFF,
00302 0x80,
00303 0x01,0x00,0x01,
00304 };
00305
00306 int packetlen = len + 12 + 3;
00307 ASSERT(packetlen <= 0xffff);
00308 Private1Header[4] = (packetlen>>8)&0xff;
00309 Private1Header[5] = packetlen&0xff;
00310
00311 if(*subtype == MEDIASUBTYPE_DTS)
00312 {
00313 Private1Header[17] += 8;
00314 }
00315
00316 memcpy(pOut, &Private1Header, sizeof(Private1Header));
00317 pOut += sizeof(Private1Header);
00318
00319 majortype = &MEDIATYPE_Audio;
00320 }
00321
00322 if(*majortype == MEDIATYPE_Audio)
00323 {
00324 if(size < len) return E_FAIL;
00325
00326 memcpy(pOut, pIn, len);
00327 pIn += len;
00328 pOut += len;
00329 }
00330 }
00331 }
00332 else
00333 {
00334 return E_FAIL;
00335 }
00336
00337 pOutSample->SetActualDataLength(pOut - pOutOrg);
00338
00339 return S_OK;
00340 }
00341
00342 bool CAVI2AC3Filter::CheckAC3(const CMediaType* pmt)
00343 {
00344 return (pmt->majortype == MEDIATYPE_Audio
00345 || pmt->majortype == MEDIATYPE_MPEG2_PES
00346 || pmt->majortype == MEDIATYPE_DVD_ENCRYPTED_PACK)
00347 && pmt->subtype == MEDIASUBTYPE_DOLBY_AC3;
00348 }
00349
00350 bool CAVI2AC3Filter::CheckDTS(const CMediaType* pmt)
00351 {
00352 return (pmt->majortype == MEDIATYPE_Audio
00353 || pmt->majortype == MEDIATYPE_MPEG2_PES
00354 || pmt->majortype == MEDIATYPE_DVD_ENCRYPTED_PACK)
00355 && pmt->subtype == MEDIASUBTYPE_DTS;
00356 }
00357
00358 bool CAVI2AC3Filter::CheckWAVEAC3(const CMediaType* pmt)
00359 {
00360 return pmt->majortype == MEDIATYPE_Audio
00361 && pmt->subtype == MEDIASUBTYPE_WAVE_DOLBY_AC3
00362 && pmt->formattype == FORMAT_WaveFormatEx
00363 && ((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag == WAVE_FORMAT_DOLBY_AC3;
00364 }
00365
00366 bool CAVI2AC3Filter::CheckWAVEDTS(const CMediaType* pmt)
00367 {
00368 return pmt->majortype == MEDIATYPE_Audio
00369 && pmt->subtype == MEDIASUBTYPE_WAVE_DTS
00370 && pmt->formattype == FORMAT_WaveFormatEx
00371 && ((WAVEFORMATEX*)pmt->pbFormat)->wFormatTag == WAVE_FORMAT_DVD_DTS;
00372 }
00373
00374 HRESULT CAVI2AC3Filter::CheckInputType(const CMediaType* mtIn)
00375 {
00376 bool fWaveFormatEx = !!(mtIn->formattype == FORMAT_WaveFormatEx);
00377
00378 return CheckAC3(mtIn) && fWaveFormatEx || CheckDTS(mtIn) && fWaveFormatEx
00379 || CheckWAVEAC3(mtIn) || CheckWAVEDTS(mtIn)
00380 ? S_OK
00381 : VFW_E_TYPE_NOT_ACCEPTED;
00382 }
00383
00384 HRESULT CAVI2AC3Filter::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
00385 {
00386 return CheckAC3(mtIn) && CheckWAVEAC3(mtOut)
00387 || CheckWAVEAC3(mtIn) && CheckAC3(mtOut)
00388 || CheckDTS(mtIn) && CheckWAVEDTS(mtOut)
00389 || CheckWAVEDTS(mtIn) && CheckDTS(mtOut)
00390 ? S_OK
00391 : VFW_E_TYPE_NOT_ACCEPTED;
00392 }
00393
00394 HRESULT CAVI2AC3Filter::DecideBufferSize(IMemAllocator* pAllocator, ALLOCATOR_PROPERTIES* pProperties)
00395 {
00396 if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
00397
00398 CComPtr<IMemAllocator> pAllocatorIn;
00399 m_pInput->GetAllocator(&pAllocatorIn);
00400 if(!pAllocatorIn) return E_UNEXPECTED;
00401
00402 pAllocatorIn->GetProperties(pProperties);
00403
00404 pProperties->cBuffers = 2;
00405 pProperties->cbBuffer = max(pProperties->cbBuffer, 1024*1024);
00406 pProperties->cbAlign = 1;
00407 pProperties->cbPrefix = 0;
00408
00409 HRESULT hr;
00410 ALLOCATOR_PROPERTIES Actual;
00411 if(FAILED(hr = pAllocator->SetProperties(pProperties, &Actual)))
00412 return hr;
00413
00414 return(pProperties->cBuffers > Actual.cBuffers || pProperties->cbBuffer > Actual.cbBuffer
00415 ? E_FAIL
00416 : NOERROR);
00417 }
00418
00419 HRESULT CAVI2AC3Filter::GetMediaType(int iPosition, CMediaType* pMediaType)
00420 {
00421 if(m_pInput->IsConnected() == FALSE) return E_UNEXPECTED;
00422
00423 const GUID& majortype = m_pInput->CurrentMediaType().majortype;
00424 const GUID& subtype = m_pInput->CurrentMediaType().subtype;
00425
00426 if(CheckAC3(&m_pInput->CurrentMediaType()) || CheckDTS(&m_pInput->CurrentMediaType()))
00427 {
00428 if(iPosition < 0) return E_INVALIDARG;
00429 if(iPosition > 0) return VFW_S_NO_MORE_ITEMS;
00430
00431 pMediaType->majortype = MEDIATYPE_Audio;
00432
00433 pMediaType->formattype = FORMAT_WaveFormatEx;
00434 WAVEFORMATEX* wfe = (WAVEFORMATEX*)pMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEX));
00435 memset(wfe, 0, sizeof(WAVEFORMATEX));
00436 wfe->cbSize = sizeof(WAVEFORMATEX);
00437 wfe->nAvgBytesPerSec = ((WAVEFORMATEX*)m_pInput->CurrentMediaType().pbFormat)->nAvgBytesPerSec;
00438 wfe->nSamplesPerSec = ((WAVEFORMATEX*)m_pInput->CurrentMediaType().pbFormat)->nSamplesPerSec;
00439 wfe->wBitsPerSample = ((WAVEFORMATEX*)m_pInput->CurrentMediaType().pbFormat)->wBitsPerSample;
00440 wfe->nChannels = 2;
00441 wfe->nBlockAlign = 1;
00442
00443 if(subtype == MEDIASUBTYPE_DOLBY_AC3)
00444 {
00445 pMediaType->subtype = MEDIASUBTYPE_WAVE_DOLBY_AC3;
00446 wfe->wFormatTag = WAVE_FORMAT_DOLBY_AC3;
00447 }
00448 else if(subtype == MEDIASUBTYPE_DTS)
00449 {
00450 pMediaType->subtype = MEDIASUBTYPE_WAVE_DTS;
00451 wfe->wFormatTag = WAVE_FORMAT_DVD_DTS;
00452 }
00453 else
00454 {
00455 return E_INVALIDARG;
00456 }
00457 }
00458 else if(CheckWAVEAC3(&m_pInput->CurrentMediaType()) || CheckWAVEDTS(&m_pInput->CurrentMediaType()))
00459 {
00460 if(iPosition < 0) return E_INVALIDARG;
00461 if(iPosition > 4) return VFW_S_NO_MORE_ITEMS;
00462
00463 if(subtype == MEDIASUBTYPE_WAVE_DOLBY_AC3)
00464 {
00465 pMediaType->subtype = MEDIASUBTYPE_DOLBY_AC3;
00466
00467 pMediaType->formattype = FORMAT_WaveFormatEx;
00468 DOLBYAC3WAVEFORMAT* wfe = (DOLBYAC3WAVEFORMAT*)pMediaType->AllocFormatBuffer(sizeof(DOLBYAC3WAVEFORMAT));
00469 memset(wfe, 0, sizeof(DOLBYAC3WAVEFORMAT));
00470
00471
00472
00473 wfe->wfx.cbSize = sizeof(DOLBYAC3WAVEFORMAT) - sizeof(WAVEFORMATEX);
00474 wfe->wfx.wFormatTag = WAVE_FORMAT_DOLBY_AC3;
00475 wfe->wfx.nSamplesPerSec = 48000;
00476 wfe->wfx.nChannels = 6;
00477 wfe->bBigEndian = TRUE;
00478 }
00479 else if(subtype == MEDIASUBTYPE_WAVE_DTS)
00480 {
00481 pMediaType->subtype = MEDIASUBTYPE_DTS;
00482
00483 pMediaType->formattype = FORMAT_WaveFormatEx;
00484 WAVEFORMATEX* wfe = (WAVEFORMATEX*)pMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEX));
00485 memset(wfe, 0, sizeof(WAVEFORMATEX));
00486
00487 wfe->cbSize = sizeof(WAVEFORMATEX);
00488 wfe->wFormatTag = WAVE_FORMAT_PCM;
00489 wfe->nSamplesPerSec = 48000;
00490 wfe->nChannels = 6;
00491 }
00492 else
00493 {
00494 return E_INVALIDARG;
00495 }
00496
00497 switch(iPosition)
00498 {
00499 case 0:
00500 pMediaType->majortype = MEDIATYPE_Audio;
00501 break;
00502 case 1:
00503 pMediaType->ResetFormatBuffer();
00504 pMediaType->formattype = FORMAT_None;
00505 case 2:
00506 pMediaType->majortype = MEDIATYPE_MPEG2_PES;
00507 break;
00508 case 3:
00509 pMediaType->ResetFormatBuffer();
00510 pMediaType->formattype = FORMAT_None;
00511 case 4:
00512 pMediaType->majortype = MEDIATYPE_DVD_ENCRYPTED_PACK;
00513 break;
00514 default:
00515 return E_INVALIDARG;
00516 }
00517 }
00518 else
00519 {
00520 return VFW_S_NO_MORE_ITEMS;
00521 }
00522
00523 return S_OK;
00524 }