- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# AVI2AC3Filter.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 <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); // "DllMain" of the dshow baseclasses;
    00076 }
    00077
    00078 #endif
    00079
    00080 //
    00081 // CAVI2AC3Filter
    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) // damn, this can happen if the interleave time is too big
    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,                    // PES id
    00184                                                 0x44,0x00,0x04,0x00,0x04,0x01,  // SCR (0)
    00185                                                 0x01,0x89,0xC3,0xF8,                    // mux rate (1260000 bytes/sec, 22bits), marker (2bits), reserved (~0, 5bits), stuffing (0, 3bits)
    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,                    // private stream 1 id
    00201                                                 0x07,0xEC,                                              // packet length (TODO: modify it later)
    00202                                                 0x81,0x80,                                              // marker, original, PTS - flags
    00203                                                 0x08,                                                   // packet data starting offset
    00204                                                 0x21,0x00,0x01,0x00,0x01,               // PTS (0)
    00205                                                 0xFF,0xFF,0xFF,                                 // stuffing
    00206                                                 0x80,                                                   // stream id (0)
    00207                                                 0x01,0x00,0x01,                                 // no idea about the first byte, the sencond+third seem to show the ac3/dts header sync offset plus one (dvd2avi doesn't output it to the ac3/dts file so we have to put it back)
    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 // phew, we can do the easier way
    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,                    // PES id
    00280                                         0x44,0x00,0x04,0x00,0x04,0x01,  // SCR (0)
    00281                                         0x01,0x89,0xC3,0xF8,                    // mux rate (1260000 bytes/sec, 22bits), marker (2bits), reserved (~0, 5bits), stuffing (0, 3bits)
    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,                    // private stream 1 id
    00297                                         0x07,0xEC,                                              // packet length (TODO: modify it later)
    00298                                         0x81,0x80,                                              // marker, original, PTS - flags
    00299                                         0x08,                                                   // packet data starting offset
    00300                                         0x21,0x00,0x01,0x00,0x01,               // PTS (0)
    00301                                         0xFF,0xFF,0xFF,                                 // stuffing
    00302                                         0x80,                                                   // stream id (0)
    00303                                         0x01,0x00,0x01,                                 // no idea about the first byte, the sencond+third seem to show the ac3/dts header sync offset plus one (dvd2avi doesn't output it to the ac3/dts file so we have to put it back)
    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); // this should be enough...
    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                         // unfortunately we can't tell what we are going to get in transform,
    00471                         // so we just set the most common values and hope that the ac3 decoder
    00472                         // is flexible enough (it is usually :) to find out these from the bitstream
    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                         // same case as with ac3, but this time we don't even know the structure
    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 }