home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 24 / AACD 24.iso / AACD / Sound / LAME / WarpOS / src / dshow / Mpegac.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-15  |  38.6 KB  |  1,421 lines

  1. /*
  2.  *    MPEG Audio Encoder for DirectShow
  3.  *
  4.  *    Copyright (c) 2000 Marie Orlova, Peter Gubanov, Elecard Ltd.
  5.  *
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Library General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.     See the GNU
  14.  * Library General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Library General Public
  17.  * License along with this library; if not, write to the
  18.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19.  * Boston, MA 02111-1307, USA.
  20.  */
  21.  
  22. #include <streams.h>
  23. #include <olectl.h>
  24. #include <initguid.h>
  25. #include <olectlid.h>
  26. #include "uids.h"
  27. #include "iaudioprops.h"
  28. #include "mpegac.h"
  29. #include "resource.h"
  30.  
  31. #include "PropPage.h"
  32. #include "PropPage_adv.h"
  33. #include "aboutprp.h"
  34.  
  35. #include "Encoder.h"
  36. #include "Reg.h"
  37.  
  38. #ifndef _INC_MMREG
  39. #include <mmreg.h>
  40. #endif
  41.  
  42. // default parameters
  43. #define         DEFAULT_LAYER                3
  44. #define         DEFAULT_STEREO_MODE            JOINT_STEREO
  45. #define            DEFAULT_FORCE_MS            0
  46. #define            DEFAULT_MODE_FIXED            0
  47. #define            DEFAULT_ENFORCE_MIN            0
  48. #define            DEFAULT_VOICE                0
  49. #define            DEFAULT_KEEP_ALL_FREQ        0
  50. #define            DEFAULT_STRICT_ISO            0
  51. #define            DEFAULT_DISABLE_SHORT_BLOCK    0
  52. #define            DEFAULT_XING_TAG    0
  53. #define         DEFAULT_SAMPLE_RATE            44100        
  54. #define         DEFAULT_BITRATE                128        //Work with all mode
  55. #define         DEFAULT_VARIABLE             0     
  56. #define         DEFAULT_CRC                 0     
  57. #define         DEFAULT_COPYRIGHT             0     
  58. #define         DEFAULT_ORIGINAL             0     
  59. #define         DEFAULT_VARIABLEMIN            80        //Work with all mode
  60. #define         DEFAULT_VARIABLEMAX            160        //Work with all mode
  61. #define         DEFAULT_ENCODING_QUALITY    5
  62. #define         DEFAULT_VBR_QUALITY            4 
  63. #define         DEFAULT_PES                 0     
  64.  
  65.  
  66. /*  Registration setup stuff */
  67. //  Setup data
  68.  
  69. AMOVIESETUP_MEDIATYPE sudMpgInputType[] =
  70. {
  71.     { &MEDIATYPE_Audio, &MEDIASUBTYPE_PCM }
  72. };
  73. AMOVIESETUP_MEDIATYPE sudMpgOutputType[] =
  74. {
  75.     { &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload },
  76.     { &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG2_AUDIO },
  77. };
  78.  
  79. AMOVIESETUP_PIN sudMpgPins[3] =
  80. {
  81.     { L"PCM Input",
  82.       FALSE,                               // bRendered
  83.       FALSE,                               // bOutput
  84.       FALSE,                               // bZero
  85.       FALSE,                               // bMany
  86.       &CLSID_NULL,                         // clsConnectsToFilter
  87.       NULL,                                // ConnectsToPin
  88.       NUMELMS(sudMpgInputType),            // Number of media types
  89.       sudMpgInputType
  90.     },
  91.     { L"MPEG Output",
  92.       FALSE,                               // bRendered
  93.       TRUE,                                // bOutput
  94.       FALSE,                               // bZero
  95.       FALSE,                               // bMany
  96.       &CLSID_NULL,                         // clsConnectsToFilter
  97.       NULL,                                // ConnectsToPin
  98.       NUMELMS(sudMpgOutputType),           // Number of media types
  99.       sudMpgOutputType
  100.     }
  101. };
  102.  
  103. AMOVIESETUP_FILTER sudMpgAEnc =
  104. {
  105.     &CLSID_LAMEDShowFilter,
  106.     L"LAME MPEG Layer III Audio Encoder",
  107.     MERIT_SW_COMPRESSOR,                   // Don't use us for real!
  108.     NUMELMS(sudMpgPins),                   // 3 pins
  109.     sudMpgPins
  110. };
  111.  
  112. /*****************************************************************************/
  113. // COM Global table of objects in this dll
  114. CFactoryTemplate g_Templates[] = 
  115. {
  116.   { L"LAME MPEG Layer III Audio Encoder", &CLSID_LAMEDShowFilter, CMpegAudEnc::CreateInstance, NULL, &sudMpgAEnc },
  117.   { L"LAME MPEG Layer III Audio Encoder Property Page", &CLSID_LAMEDShow_PropertyPage, CMpegAudEncPropertyPage::CreateInstance},
  118.   { L"LAME MPEG Layer III Audio Encoder Advanced Property Page", &CLSID_LAMEDShow_PropertyPageAdv, CMpegAudEncPropertyPageAdv::CreateInstance},
  119.   { L"LAME MPEG Layer III Audio Encoder About", &CLSID_LAMEDShow_About, CMAEAbout::CreateInstance}
  120. };
  121. // Count of objects listed in g_cTemplates
  122. int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
  123.  
  124. CUnknown *CMpegAudEnc::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr) 
  125. {
  126.     CUnknown *punk = new CMpegAudEnc(lpunk, phr);
  127.     if (punk == NULL) 
  128.         *phr = E_OUTOFMEMORY;
  129.     return punk;
  130. }
  131.  
  132. CMpegAudEnc::CMpegAudEnc(LPUNKNOWN lpunk, HRESULT *phr)
  133.  :    CTransformFilter(NAME("LAME MPEG Layer III Audio Encoder"), lpunk, 
  134.     CLSID_LAMEDShowFilter),
  135.     CPersistStream(lpunk, phr)
  136. {
  137.     MPEG_ENCODER_CONFIG mec;
  138.     ReadPresetSettings(&mec);
  139.     m_VEncoder.SetOutputType(mec);
  140. }
  141.  
  142. CMpegAudEnc::~CMpegAudEnc(void)
  143. {
  144. }
  145.  
  146. LPAMOVIESETUP_FILTER CMpegAudEnc::GetSetupData()
  147. {
  148.     return &sudMpgAEnc;
  149. }
  150.  
  151. ////////////////////////////////////////////////////////////////////////////
  152. //    Transform - function where actual data transformations is performed
  153. ////////////////////////////////////////////////////////////////////////////
  154. HRESULT CMpegAudEnc::Transform(IMediaSample* pSource, IMediaSample* pDest)
  155. {    
  156.     if(m_State == State_Stopped)// if filter stoped do noting
  157.     {    
  158.         pDest->SetActualDataLength(0);
  159.         return S_OK;
  160.     }
  161.  
  162.     // Copy the sample data
  163.     DWORD    dwDstSize;
  164.     BYTE    *pSourceBuffer, *pDestBuffer;
  165.     long    lSourceSize        = pSource->GetActualDataLength();
  166.     long    lDestSize        = pDest->GetSize();        
  167.  
  168.     // Copy the sample times
  169.     REFERENCE_TIME TimeStart, TimeEnd;
  170.     if(SUCCEEDED(pSource->GetTime(&TimeStart, &TimeEnd))) {
  171.         pDest->SetTime(&TimeStart, &TimeEnd);
  172.         m_rtLast = TimeEnd;
  173.     }
  174.  
  175.     // Get source and destination data buffers
  176.     pSource->GetPointer(&pSourceBuffer);
  177.     pDest->GetPointer(&pDestBuffer);        
  178.  
  179.     // Encode data
  180.     if(FAILED(m_VEncoder.Encode(pSourceBuffer, lSourceSize,
  181.                                 pDestBuffer, &dwDstSize, TimeStart)))
  182.         return E_UNEXPECTED;
  183.  
  184.     ASSERT(DWORD(lDestSize) >= dwDstSize);
  185.     // Copy the actual data length
  186.     pDest->SetActualDataLength(dwDstSize);
  187.     
  188.  
  189.     LONGLONG MediaStart, MediaEnd;
  190.     if (pSource->GetMediaTime(&MediaStart,&MediaEnd) == NOERROR) 
  191.         pDest->SetMediaTime(&MediaStart,&MediaEnd);
  192.         // Copy the Sync point property
  193.  
  194.     HRESULT hr = pSource->IsSyncPoint();
  195.     if (hr == S_OK) 
  196.         pDest->SetSyncPoint(TRUE);
  197.     else if (hr == S_FALSE) 
  198.         pDest->SetSyncPoint(FALSE);
  199.     else // an unexpected error has occured...
  200.         return E_UNEXPECTED;
  201.     
  202.     // Copy the media type
  203.     AM_MEDIA_TYPE *pMediaType;
  204.     pSource->GetMediaType(&pMediaType);
  205.     pDest->SetMediaType(pMediaType);
  206.         DeleteMediaType(pMediaType);
  207.  
  208.     // Copy the preroll property
  209.     hr = pSource->IsPreroll();
  210.     if (hr == S_OK) 
  211.         pDest->SetPreroll(TRUE);
  212.     else if (hr == S_FALSE) 
  213.         pDest->SetPreroll(FALSE);
  214.     else // an unexpected error has occured...
  215.         return E_UNEXPECTED;
  216.  
  217.     // Copy the discontinuity property
  218.  
  219.     hr = pSource->IsDiscontinuity();
  220.     if (hr == S_OK) 
  221.         pDest->SetDiscontinuity(TRUE);
  222.     else if (hr == S_FALSE) 
  223.         pDest->SetDiscontinuity(FALSE);
  224.     else // an unexpected error has occured...
  225.         return E_UNEXPECTED;
  226.  
  227.     return S_OK;
  228. }
  229.  
  230. ////////////////////////////////////////////////////////////////////////////
  231. //    StartStreaming - prepare to recive new data
  232. ////////////////////////////////////////////////////////////////////////////
  233. HRESULT CMpegAudEnc::StartStreaming()
  234. {
  235.     m_rtLast = CRefTime(0L);
  236.  
  237.     // Initialize encoder
  238.     m_VEncoder.Init(); 
  239.     return S_OK;    
  240. }
  241.  
  242. ////////////////////////////////////////////////////////////////////////////
  243. //     EndOfStream - stop data processing 
  244. ////////////////////////////////////////////////////////////////////////////
  245. HRESULT CMpegAudEnc::EndOfStream()
  246. {
  247.     // Close encoder
  248.     m_VEncoder.Close(); 
  249.     return CTransformFilter::EndOfStream();
  250. }
  251.  
  252. ////////////////////////////////////////////////////////////////////////////
  253. //    BeginFlush  - stop data processing 
  254. ////////////////////////////////////////////////////////////////////////////
  255. HRESULT CMpegAudEnc::BeginFlush()
  256. {
  257.     BYTE *pBuffer;
  258.     IMediaSample *pSample;
  259.  
  260.     m_pOutput->GetDeliveryBuffer(&pSample,NULL,NULL,0L);
  261.     pSample->GetPointer(&pBuffer);
  262.  
  263.     DWORD dwSize = pSample->GetSize();
  264.     m_VEncoder.Finish(pBuffer,&dwSize);
  265.     if (dwSize>0) {
  266.         pSample->SetActualDataLength(dwSize);
  267.         m_pOutput->Deliver(pSample);
  268.     }
  269.     pSample->Release();
  270.  
  271.     // Close encoder
  272.     m_VEncoder.Close(); 
  273.     return CTransformFilter::BeginFlush();
  274. }
  275.  
  276. ////////////////////////////////////////////////////////////////////////////
  277. //    SetMediaType - called when filters are connecting
  278. ////////////////////////////////////////////////////////////////////////////
  279. HRESULT CMpegAudEnc::SetMediaType(PIN_DIRECTION direction,const CMediaType *pmt)
  280. {
  281.     HRESULT hr = CTransformFilter::SetMediaType(direction, pmt);
  282.  
  283.     if (*pmt->FormatType() != FORMAT_WaveFormatEx)
  284.         return VFW_E_INVALIDMEDIATYPE;
  285.  
  286.     if (pmt->FormatLength() < sizeof(WAVEFORMATEX))
  287.         return VFW_E_INVALIDMEDIATYPE;
  288.  
  289.     if(direction == PINDIR_INPUT)
  290.     {    
  291.         DbgLog((LOG_TRACE,1,TEXT("CMpegAudEnc::SetMediaType(), direction = PINDIR_INPUT")));
  292.  
  293.         // Pass input media type to encoder
  294.         m_VEncoder.SetInputType((LPWAVEFORMATEX)pmt->Format());
  295.  
  296.         // Set default output MPEG audio settings according to
  297.         // input type
  298.         SetOutMediaType();
  299.         Reconnect();
  300.     }
  301.     else if (direction == PINDIR_OUTPUT)
  302.     {
  303.         WAVEFORMATEX wfIn;
  304.         m_VEncoder.GetInputType(&wfIn);
  305.  
  306.         if (wfIn.nSamplesPerSec %
  307.             ((LPWAVEFORMATEX)pmt->Format())->nSamplesPerSec != 0)
  308.             return VFW_E_TYPE_NOT_ACCEPTED;
  309.     }
  310.  
  311.     return hr;
  312. }
  313.  
  314. ////////////////////////////////////////////////////////////////////////////
  315. // CheckInputType - check if you can support mtIn
  316. ////////////////////////////////////////////////////////////////////////////
  317. HRESULT CMpegAudEnc::CheckInputType(const CMediaType* mtIn)
  318. {
  319.     if (*mtIn->Type() == MEDIATYPE_Audio && *mtIn->FormatType() == FORMAT_WaveFormatEx)
  320.         if (mtIn->FormatLength() >= sizeof(WAVEFORMATEX))
  321.             if (mtIn->IsTemporalCompressed() == FALSE)     
  322.             {
  323.                 HRESULT hr = m_VEncoder.SetInputType((LPWAVEFORMATEX)mtIn->Format());
  324.  
  325.                  return hr;
  326.             }
  327.  
  328.     return E_INVALIDARG;
  329. }
  330.  
  331. ////////////////////////////////////////////////////////////////////////////
  332. // CheckTransform - checks if we can support the transform from this input to this output
  333. ////////////////////////////////////////////////////////////////////////////
  334. HRESULT CMpegAudEnc::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
  335. {
  336.     if (*mtOut->FormatType() != FORMAT_WaveFormatEx)
  337.         return VFW_E_INVALIDMEDIATYPE;
  338.  
  339.     if (mtOut->FormatLength() < sizeof(WAVEFORMATEX))
  340.         return VFW_E_INVALIDMEDIATYPE;
  341.  
  342.     MPEG_ENCODER_CONFIG    mec;
  343.     if(FAILED(m_VEncoder.GetOutputType(&mec)))
  344.         return S_OK;
  345.  
  346.     if (((LPWAVEFORMATEX)mtIn->Format())->nSamplesPerSec % mec.dwSampleRate != 0)
  347.         return S_OK;
  348.  
  349.     if (mec.dwSampleRate != ((LPWAVEFORMATEX)mtOut->Format())->nSamplesPerSec)
  350.         return VFW_E_TYPE_NOT_ACCEPTED;
  351.  
  352.     return S_OK;
  353. }
  354.  
  355. ////////////////////////////////////////////////////////////////////////////
  356. // DecideBufferSize - sets output buffers number and size
  357. ////////////////////////////////////////////////////////////////////////////
  358. HRESULT CMpegAudEnc::DecideBufferSize(
  359.                         IMemAllocator*          pAllocator,
  360.                         ALLOCATOR_PROPERTIES* pProperties)
  361. {   
  362.     HRESULT hr = S_OK;
  363.  
  364.     ///
  365.     pProperties->cBuffers = 4;
  366.     pProperties->cbBuffer = OUTPUT_BUFF_SIZE;
  367.     //
  368.  
  369.     ASSERT(pProperties->cbBuffer);
  370.     
  371.     ALLOCATOR_PROPERTIES Actual;
  372.     hr = pAllocator->SetProperties(pProperties,&Actual);
  373.     if(FAILED(hr)) 
  374.         return hr;
  375.  
  376.     ASSERT(Actual.cbAlign == 1);
  377.     ASSERT(Actual.cbPrefix == 0);
  378.  
  379.     if (Actual.cbBuffer < pProperties->cbBuffer ||
  380.         Actual.cBuffers < pProperties->cBuffers) 
  381.     {// can't use this allocator
  382.         return E_INVALIDARG;
  383.     }
  384.     return S_OK;
  385. }
  386.  
  387. ////////////////////////////////////////////////////////////////////////////
  388. // GetMediaType - overrideble for suggesting outpu pin media types
  389. ////////////////////////////////////////////////////////////////////////////
  390. HRESULT CMpegAudEnc::GetMediaType(int iPosition, CMediaType *pMediaType)
  391. {    
  392.     DbgLog((LOG_TRACE,1,TEXT("CMpegAudEnc::GetMediaType()")));
  393.  
  394.     if (iPosition < 0)                        
  395.         return E_INVALIDARG;
  396.     
  397.     
  398.     switch(iPosition)
  399.     {
  400.         case 0:
  401.         {// We can support two output streams - PES or AES    
  402.             if(m_VEncoder.IsPES())
  403.             {
  404.                 pMediaType->SetType(&MEDIATYPE_MPEG2_PES);
  405.                 pMediaType->SetSubtype(&MEDIASUBTYPE_MPEG2_AUDIO);        
  406.             }
  407.             else
  408.             {
  409.                 pMediaType->SetType(&MEDIATYPE_Stream);
  410.                 pMediaType->SetSubtype(&MEDIASUBTYPE_MPEG1Audio);        
  411.             }
  412.             break;
  413.         }
  414.         default: 
  415.             return VFW_S_NO_MORE_ITEMS;
  416.     }    
  417.     
  418.     if (m_pInput->IsConnected() == FALSE)    
  419.     {    
  420.         pMediaType->SetFormatType(&FORMAT_None);
  421.         return NOERROR;
  422.     }                 
  423.     
  424.  
  425.     SetOutMediaType();
  426.     pMediaType->SetSampleSize(4096);    
  427.     pMediaType->SetTemporalCompression(FALSE);    
  428.     pMediaType->AllocFormatBuffer(sizeof(MPEG1WAVEFORMAT));
  429.     pMediaType->SetFormat((LPBYTE)&m_mwf, sizeof(MPEG1WAVEFORMAT));    
  430.     pMediaType->SetFormatType(&FORMAT_WaveFormatEx);
  431.  
  432.     return S_OK;
  433. }
  434.  
  435. ////////////////////////////////////////////////////////////////////////////
  436. //    SetOutMediaType - sets filter output media type according to 
  437. //  current encoder out MPEG audio properties 
  438. ////////////////////////////////////////////////////////////////////////////
  439. void CMpegAudEnc::SetOutMediaType()
  440. {
  441.     MPEG_ENCODER_CONFIG    mec;
  442.     if(FAILED(m_VEncoder.GetOutputType(&mec)))
  443.         return ;
  444.     WAVEFORMATEX wf;
  445.     if(FAILED(m_VEncoder.GetInputType(&wf)))
  446.         return ;
  447.  
  448.     BOOL bDirty = FALSE;
  449.  
  450.     if ((wf.nSamplesPerSec % mec.dwSampleRate) != 0)
  451.     {
  452.         mec.dwSampleRate = wf.nSamplesPerSec;
  453.         m_VEncoder.SetOutputType(mec);
  454.         bDirty = TRUE;
  455.     }
  456.  
  457.     if (wf.nChannels == 1 && mec.dwChMode != MONO)
  458.     {
  459.         mec.dwChMode = MONO;
  460.         m_VEncoder.SetOutputType(mec);
  461.         bDirty = TRUE;
  462.     }
  463.  
  464.     if (wf.nChannels == 2 && mec.dwChMode == MONO)
  465.     {
  466.         mec.dwChMode = STEREO;
  467.         m_VEncoder.SetOutputType(mec);
  468.         bDirty = TRUE;
  469.     }
  470.  
  471.     if (bDirty)
  472.     {
  473.         // we are tied to the registry, especially our configuration
  474.         // so when we change the incorrect sample rate, we need
  475.         // to change the value in registry too. Same to channel mode
  476.         SaveAudioEncoderPropertiesToRegistry();
  477.         DbgLog((LOG_TRACE, 1, TEXT("Changed sampling rate internally")));
  478.     }
  479.  
  480.     // Fill MPEG1WAVEFORMAT DirectShow SDK structure
  481.     m_mwf.wfx.wFormatTag        = WAVE_FORMAT_MPEG;
  482.     m_mwf.wfx.cbSize            = sizeof(MPEG1WAVEFORMAT) - sizeof(WAVEFORMATEX);        
  483.  
  484.     if(mec.dwChMode == MONO)
  485.         m_mwf.wfx.nChannels    = 1;
  486.     else
  487.         m_mwf.wfx.nChannels    = 2;
  488.  
  489.     m_mwf.wfx.nSamplesPerSec    = mec.dwSampleRate;
  490.     m_mwf.wfx.nBlockAlign        = 1;
  491.  
  492.     m_mwf.wfx.wBitsPerSample    = wf.wBitsPerSample; 
  493.     m_mwf.wfx.nAvgBytesPerSec    = mec.dwBitrate/8;    
  494.     m_mwf.fwHeadLayer            = ACM_MPEG_LAYER3;
  495.  
  496.     m_mwf.dwHeadBitrate        = mec.dwBitrate;
  497.  
  498.  
  499.  
  500.     if (mec.dwChMode == MONO)
  501.         m_mwf.fwHeadMode        = ACM_MPEG_SINGLECHANNEL;
  502.     else  if(mec.dwChMode == STEREO)
  503.         m_mwf.fwHeadMode        = ACM_MPEG_STEREO;
  504.     else  if(mec.dwChMode == JOINT_STEREO)
  505.         m_mwf.fwHeadMode        = ACM_MPEG_JOINTSTEREO;
  506.     else  if(mec.dwChMode == DUAL_CHANNEL)
  507.         m_mwf.fwHeadMode        = ACM_MPEG_DUALCHANNEL;
  508.     m_mwf.fwHeadModeExt        = 0;
  509.     m_mwf.wHeadEmphasis        = 0;
  510.     if(mec.bCRCProtect)
  511.         m_mwf.fwHeadFlags        |= ACM_MPEG_PROTECTIONBIT;
  512.  
  513.     if(mec.bOriginal)
  514.         m_mwf.fwHeadFlags        |= ACM_MPEG_ORIGINALHOME;
  515.  
  516.     if(mec.bCopyright)
  517.         m_mwf.fwHeadFlags        |= ACM_MPEG_COPYRIGHT;
  518.  
  519.     m_mwf.fwHeadFlags            |= ACM_MPEG_ID_MPEG1;
  520.  
  521.     m_mwf.dwPTSLow            = 0;
  522.     m_mwf.dwPTSHigh            = 0;
  523. }
  524.  
  525. HRESULT CMpegAudEnc::Reconnect()
  526. {
  527.     if(m_pOutput && m_pOutput->IsConnected())
  528.     {// Reconnect all afterward filters    
  529.  
  530.         MPEG_ENCODER_CONFIG mec;
  531.         ReadPresetSettings(&mec);
  532.         if(m_VEncoder.SetOutputType(mec) == S_FALSE)
  533.             return S_FALSE;
  534.  
  535.         SetOutMediaType();
  536.  
  537. //        FILTER_INFO fInfo;
  538. //        QueryFilterInfo(&fInfo);
  539. //        fInfo.pGraph->Reconnect(m_pOutput);
  540. //        QueryFilterInfoReleaseGraph(fInfo);
  541.  
  542.         DbgLog((LOG_TRACE,1,TEXT("Need to reconnect our streaming pin")));
  543.         CMediaType cmt;
  544.         GetMediaType(0,&cmt);
  545.         if (S_OK == m_pOutput->GetConnected()->QueryAccept(&cmt))
  546.         {
  547.             m_pGraph->Reconnect(m_pOutput);
  548.         } else {
  549.             // We're going to have to get clever and insert some
  550.             // filters between us to help us reconnect
  551.             DbgLog((LOG_TRACE,1,TEXT("Whoa! We *really* need to reconnect!")));
  552.             IPin *pCon = m_pOutput->GetConnected();
  553.             pCon->AddRef();    // or it will go away in Disconnect
  554.             m_pGraph->Disconnect(m_pOutput->GetConnected());
  555.             m_pGraph->Disconnect(m_pOutput);
  556.             IGraphBuilder *pFG;
  557.             HRESULT hr = m_pGraph->QueryInterface(
  558.                 IID_IGraphBuilder, (void **)&pFG);
  559.             if (hr == NOERROR) {
  560.                 hr = pFG->Connect(m_pOutput, pCon);
  561.                 pFG->Release();
  562.             }
  563.             pCon->Release();
  564.             if (hr != NOERROR)
  565.                 DbgLog((LOG_ERROR,1,TEXT("*** RECONNECT FAILED! ***")));
  566.             // !!! We need to notify application that graph is different
  567.         }
  568.     }
  569.  
  570.     return S_OK;
  571. }
  572.  
  573. //
  574. // Read persistent configuration from Registry
  575. //
  576. void CMpegAudEnc::ReadPresetSettings(MPEG_ENCODER_CONFIG * pmec)
  577. {
  578.     DbgLog((LOG_TRACE,1,TEXT("CMpegAudEnc::ReadPresetSettings()")));
  579.  
  580.     CRegKey        rk(HKEY_LOCAL_MACHINE, KEY_LAME_ENCODER);
  581.  
  582.     pmec->dwBitrate            = rk.getDWORD(VALUE_BITRATE,DEFAULT_BITRATE);
  583.     pmec->dwVariableMin        = rk.getDWORD(VALUE_VARIABLEMIN,DEFAULT_VARIABLEMIN);
  584.     pmec->dwVariableMax        = rk.getDWORD(VALUE_VARIABLEMAX,DEFAULT_VARIABLEMAX);
  585.     pmec->vmVariable        = rk.getDWORD(VALUE_VARIABLE, DEFAULT_VARIABLE) ? vbr_rh : vbr_off;
  586.     pmec->dwQuality            = rk.getDWORD(VALUE_QUALITY,DEFAULT_ENCODING_QUALITY);
  587.     pmec->dwVBRq                = rk.getDWORD(VALUE_VBR_QUALITY,DEFAULT_VBR_QUALITY);
  588.     pmec->lLayer                = rk.getDWORD(VALUE_LAYER, DEFAULT_LAYER);
  589.     pmec->bCRCProtect            = rk.getDWORD(VALUE_CRC, DEFAULT_CRC);
  590.     pmec->bCopyright            = rk.getDWORD(VALUE_COPYRIGHT, DEFAULT_COPYRIGHT); 
  591.     pmec->bOriginal            = rk.getDWORD(VALUE_ORIGINAL, DEFAULT_ORIGINAL); 
  592.     pmec->dwSampleRate        = rk.getDWORD(VALUE_SAMPLE_RATE, DEFAULT_SAMPLE_RATE);
  593.     pmec->dwPES                = rk.getDWORD(VALUE_PES, DEFAULT_PES); 
  594.  
  595.     pmec->dwChMode            = rk.getDWORD(VALUE_STEREO_MODE, DEFAULT_STEREO_MODE);
  596.     pmec->dwForceMS            = rk.getDWORD(VALUE_FORCE_MS, DEFAULT_FORCE_MS);
  597.  
  598.     pmec->dwEnforceVBRmin        = rk.getDWORD(VALUE_ENFORCE_MIN, DEFAULT_ENFORCE_MIN);
  599.     pmec->dwVoiceMode            = rk.getDWORD(VALUE_VOICE, DEFAULT_VOICE); 
  600.     pmec->dwKeepAllFreq        = rk.getDWORD(VALUE_KEEP_ALL_FREQ, DEFAULT_KEEP_ALL_FREQ); 
  601.     pmec->dwStrictISO            = rk.getDWORD(VALUE_STRICT_ISO, DEFAULT_STRICT_ISO); 
  602.     pmec->dwNoShortBlock        = rk.getDWORD(VALUE_DISABLE_SHORT_BLOCK, DEFAULT_DISABLE_SHORT_BLOCK); 
  603.     pmec->dwXingTag            = rk.getDWORD(VALUE_XING_TAG, DEFAULT_XING_TAG); 
  604.     pmec->dwModeFixed            = rk.getDWORD(VALUE_MODE_FIXED, DEFAULT_MODE_FIXED); 
  605.  
  606.  
  607.     rk.Close();
  608. }
  609.  
  610. ////////////////////////////////////////////////////////////////
  611. //  Property page handling 
  612. ////////////////////////////////////////////////////////////////
  613. HRESULT CMpegAudEnc::GetPages(CAUUID *pcauuid) 
  614. {
  615.     GUID *pguid;
  616.    
  617.     pcauuid->cElems = 3;
  618.     pcauuid->pElems = pguid = (GUID *) CoTaskMemAlloc(sizeof(GUID) * pcauuid->cElems);
  619.  
  620.     if (pcauuid->pElems == NULL)
  621.         return E_OUTOFMEMORY;
  622.  
  623.     pguid[0] = CLSID_LAMEDShow_About;
  624.     pguid[1] = CLSID_LAMEDShow_PropertyPage;
  625.     pguid[2] = CLSID_LAMEDShow_PropertyPageAdv;
  626.     
  627.  
  628.  
  629.     return S_OK;
  630. }
  631.  
  632. STDMETHODIMP CMpegAudEnc::NonDelegatingQueryInterface(REFIID riid, void ** ppv) 
  633. {
  634.  
  635.     if (riid == IID_ISpecifyPropertyPages)
  636.         return GetInterface((ISpecifyPropertyPages *) this, ppv);
  637.     else if(riid == IID_IPersistStream)
  638.         return GetInterface((IPersistStream *)this, ppv);
  639. //    else if (riid == IID_IVAudioEncSettings)
  640. //        return GetInterface((IVAudioEncSettings*) this, ppv);
  641.     else if (riid == IID_IAudioEncoderProperties)
  642.         return GetInterface((IAudioEncoderProperties*) this, ppv);
  643.  
  644.     return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
  645. }
  646.  
  647. ////////////////////////////////////////////////////////////////
  648. //IVAudioEncSettings interface methods
  649. ////////////////////////////////////////////////////////////////
  650.  
  651. /*
  652. STDMETHODIMP CMpegAudEnc::SetOutputType(MPEG_ENCODER_CONFIG mec, BOOL bPES)
  653. {
  654.     m_VEncoder.SetPES(bPES);
  655.     return m_VEncoder.SetOutputType(mec);
  656. }
  657.  
  658. STDMETHODIMP CMpegAudEnc::GetOutputType(MPEG_ENCODER_CONFIG *pmec, BOOL *pbPuase)
  659. {
  660.     *pbPuase = m_VEncoder.IsPES();
  661.     return m_VEncoder.GetOutputType(pmec);
  662. }
  663. */
  664.  
  665. //
  666. // IAudioEncoderProperties
  667. //
  668. STDMETHODIMP CMpegAudEnc::get_PESOutputEnabled(DWORD *dwEnabled)
  669. {
  670.     *dwEnabled = (DWORD)m_VEncoder.IsPES();
  671.     DbgLog((LOG_TRACE, 1, TEXT("get_PESOutputEnabled -> %d"), *dwEnabled));
  672.  
  673.     return S_OK;
  674. }
  675.  
  676. STDMETHODIMP CMpegAudEnc::set_PESOutputEnabled(DWORD dwEnabled)
  677. {
  678.     m_VEncoder.SetPES((BOOL)!!dwEnabled);
  679.     DbgLog((LOG_TRACE, 1, TEXT("set_PESOutputEnabled(%d)"), !!dwEnabled));
  680.  
  681.     return S_OK;
  682. }
  683.  
  684. STDMETHODIMP CMpegAudEnc::get_MPEGLayer(DWORD *dwLayer)
  685. {
  686.     MPEG_ENCODER_CONFIG mec;
  687.     m_VEncoder.GetOutputType(&mec);
  688.     *dwLayer = (DWORD)mec.lLayer;
  689.  
  690.     DbgLog((LOG_TRACE, 1, TEXT("get_MPEGLayer -> %d"), *dwLayer));
  691.     return S_OK;
  692. }
  693.  
  694. STDMETHODIMP CMpegAudEnc::set_MPEGLayer(DWORD dwLayer)
  695. {
  696.     MPEG_ENCODER_CONFIG mec;
  697.     m_VEncoder.GetOutputType(&mec);
  698.     if (dwLayer == 2)
  699.         mec.lLayer = 2;
  700.     else if (dwLayer == 1)
  701.         mec.lLayer = 1;
  702.     m_VEncoder.SetOutputType(mec);
  703.  
  704.     DbgLog((LOG_TRACE, 1, TEXT("set_MPEGLayer(%d)"), dwLayer));
  705.     return S_OK;
  706. }
  707.  
  708. STDMETHODIMP CMpegAudEnc::get_Bitrate(DWORD *dwBitrate)
  709. {
  710.     MPEG_ENCODER_CONFIG mec;
  711.     m_VEncoder.GetOutputType(&mec);
  712.     *dwBitrate = (DWORD)mec.dwBitrate;
  713.     DbgLog((LOG_TRACE, 1, TEXT("get_Bitrate -> %d"), *dwBitrate));
  714.     return S_OK;
  715. }
  716.  
  717. STDMETHODIMP CMpegAudEnc::set_Bitrate(DWORD dwBitrate)
  718. {
  719.     MPEG_ENCODER_CONFIG mec;
  720.     m_VEncoder.GetOutputType(&mec);
  721.     mec.dwBitrate = dwBitrate;
  722.     m_VEncoder.SetOutputType(mec);
  723.     DbgLog((LOG_TRACE, 1, TEXT("set_Bitrate(%d)"), dwBitrate));
  724.     return S_OK;
  725. }
  726.  
  727. STDMETHODIMP CMpegAudEnc::get_Variable(DWORD *dwVariable)
  728. {
  729.     MPEG_ENCODER_CONFIG mec;
  730.     m_VEncoder.GetOutputType(&mec);
  731.     *dwVariable = (DWORD)(mec.vmVariable == vbr_off ? 0 : 1);
  732.     DbgLog((LOG_TRACE, 1, TEXT("get_Variable -> %d"), *dwVariable));
  733.     return S_OK;
  734. }
  735.  
  736. STDMETHODIMP CMpegAudEnc::set_Variable(DWORD dwVariable)
  737. {
  738.     MPEG_ENCODER_CONFIG mec;
  739.     m_VEncoder.GetOutputType(&mec);
  740.  
  741.     mec.vmVariable = dwVariable ? vbr_rh : vbr_off;
  742.     m_VEncoder.SetOutputType(mec);
  743.     DbgLog((LOG_TRACE, 1, TEXT("set_Variable(%d)"), dwVariable));
  744.     return S_OK;
  745. }
  746.  
  747. STDMETHODIMP CMpegAudEnc::get_VariableMin(DWORD *dwMin)
  748. {
  749.     MPEG_ENCODER_CONFIG mec;
  750.     m_VEncoder.GetOutputType(&mec);
  751.     *dwMin = (DWORD)mec.dwVariableMin;
  752.     DbgLog((LOG_TRACE, 1, TEXT("get_Variablemin -> %d"), *dwMin));
  753.     return S_OK;
  754. }
  755.  
  756. STDMETHODIMP CMpegAudEnc::set_VariableMin(DWORD dwMin)
  757. {
  758.     MPEG_ENCODER_CONFIG mec;
  759.     m_VEncoder.GetOutputType(&mec);
  760.     mec.dwVariableMin = dwMin;
  761.     m_VEncoder.SetOutputType(mec);
  762.     DbgLog((LOG_TRACE, 1, TEXT("set_Variablemin(%d)"), dwMin));
  763.     return S_OK;
  764. }
  765.  
  766. STDMETHODIMP CMpegAudEnc::get_VariableMax(DWORD *dwMax)
  767. {
  768.     MPEG_ENCODER_CONFIG mec;
  769.     m_VEncoder.GetOutputType(&mec);
  770.     *dwMax = (DWORD)mec.dwVariableMax;
  771.     DbgLog((LOG_TRACE, 1, TEXT("get_Variablemax -> %d"), *dwMax));
  772.     return S_OK;
  773. }
  774.  
  775. STDMETHODIMP CMpegAudEnc::set_VariableMax(DWORD dwMax)
  776. {
  777.     MPEG_ENCODER_CONFIG mec;
  778.     m_VEncoder.GetOutputType(&mec);
  779.     mec.dwVariableMax = dwMax;
  780.     m_VEncoder.SetOutputType(mec);
  781.     DbgLog((LOG_TRACE, 1, TEXT("set_Variablemax(%d)"), dwMax));
  782.     return S_OK;
  783. }
  784.  
  785. STDMETHODIMP CMpegAudEnc::get_Quality(DWORD *dwQuality)             
  786. {
  787.     MPEG_ENCODER_CONFIG mec;
  788.     m_VEncoder.GetOutputType(&mec);
  789.     *dwQuality=(DWORD)mec.dwQuality;
  790.     DbgLog((LOG_TRACE, 1, TEXT("get_Quality -> %d"), *dwQuality));
  791.     return S_OK;
  792. }
  793.  
  794. STDMETHODIMP CMpegAudEnc::set_Quality(DWORD dwQuality)             
  795. {
  796.     MPEG_ENCODER_CONFIG mec;
  797.     m_VEncoder.GetOutputType(&mec);
  798.     mec.dwQuality = dwQuality;
  799.     m_VEncoder.SetOutputType(mec);
  800.     DbgLog((LOG_TRACE, 1, TEXT("set_Quality(%d)"), dwQuality));
  801.     return S_OK;
  802. }
  803. STDMETHODIMP CMpegAudEnc::get_VariableQ(DWORD *dwVBRq)             
  804. {
  805.     MPEG_ENCODER_CONFIG mec;
  806.     m_VEncoder.GetOutputType(&mec);
  807.     *dwVBRq=(DWORD)mec.dwVBRq;
  808.     DbgLog((LOG_TRACE, 1, TEXT("get_VariableQ -> %d"), *dwVBRq));
  809.     return S_OK;
  810. }
  811.  
  812. STDMETHODIMP CMpegAudEnc::set_VariableQ(DWORD dwVBRq)             
  813. {
  814.     MPEG_ENCODER_CONFIG mec;
  815.     m_VEncoder.GetOutputType(&mec);
  816.     mec.dwVBRq = dwVBRq;
  817.     m_VEncoder.SetOutputType(mec);
  818.     DbgLog((LOG_TRACE, 1, TEXT("set_VariableQ(%d)"), dwVBRq));
  819.     return S_OK;
  820. }
  821.  
  822.  
  823. STDMETHODIMP CMpegAudEnc::get_SourceSampleRate(DWORD *dwSampleRate)
  824. {
  825.     *dwSampleRate = 0;
  826.  
  827.     WAVEFORMATEX wf;
  828.     if(FAILED(m_VEncoder.GetInputType(&wf)))
  829.         return E_FAIL;
  830.  
  831.     *dwSampleRate = wf.nSamplesPerSec;
  832.     DbgLog((LOG_TRACE, 1, TEXT("get_SourceSampleRate -> %d"), *dwSampleRate));
  833.     return S_OK;
  834. }
  835.  
  836. STDMETHODIMP CMpegAudEnc::get_SourceChannels(DWORD *dwChannels)
  837. {
  838.     WAVEFORMATEX wf;
  839.     if(FAILED(m_VEncoder.GetInputType(&wf)))
  840.         return E_FAIL;
  841.  
  842.     *dwChannels = wf.nChannels;
  843.     DbgLog((LOG_TRACE, 1, TEXT("get_SourceChannels -> %d"), *dwChannels));
  844.     return S_OK;
  845. }
  846.  
  847. STDMETHODIMP CMpegAudEnc::get_SampleRate(DWORD *dwSampleRate)
  848. {
  849.     MPEG_ENCODER_CONFIG mec;
  850.     m_VEncoder.GetOutputType(&mec);
  851.     *dwSampleRate = mec.dwSampleRate;
  852.     DbgLog((LOG_TRACE, 1, TEXT("get_SampleRate -> %d"), *dwSampleRate));
  853.     return S_OK;
  854. }
  855.  
  856. STDMETHODIMP CMpegAudEnc::set_SampleRate(DWORD dwSampleRate)
  857. {
  858.     MPEG_ENCODER_CONFIG mec;
  859.     m_VEncoder.GetOutputType(&mec);
  860.     mec.dwSampleRate = dwSampleRate;
  861.     m_VEncoder.SetOutputType(mec);
  862.     DbgLog((LOG_TRACE, 1, TEXT("set_SampleRate(%d)"), dwSampleRate));
  863.     return S_OK;
  864. }
  865.  
  866. STDMETHODIMP CMpegAudEnc::get_ChannelMode(DWORD *dwChannelMode)
  867. {
  868.     MPEG_ENCODER_CONFIG mec;
  869.     m_VEncoder.GetOutputType(&mec);
  870.     *dwChannelMode = mec.dwChMode;
  871.     DbgLog((LOG_TRACE, 1, TEXT("get_ChannelMode -> %d"), *dwChannelMode));
  872.     return S_OK;
  873. }
  874.  
  875. STDMETHODIMP CMpegAudEnc::set_ChannelMode(DWORD dwChannelMode)
  876. {
  877.     MPEG_ENCODER_CONFIG mec;
  878.     m_VEncoder.GetOutputType(&mec);
  879.     mec.dwChMode = dwChannelMode;
  880.     m_VEncoder.SetOutputType(mec);
  881.     DbgLog((LOG_TRACE, 1, TEXT("set_ChannelMode(%d)"), dwChannelMode));
  882.     return S_OK;
  883. }
  884.  
  885. STDMETHODIMP CMpegAudEnc::get_ForceMS(DWORD *dwFlag)
  886. {
  887.     MPEG_ENCODER_CONFIG mec;
  888.     m_VEncoder.GetOutputType(&mec);
  889.     *dwFlag = mec.dwForceMS;
  890.     DbgLog((LOG_TRACE, 1, TEXT("get_ForceMS -> %d"), *dwFlag));
  891.     return S_OK;
  892. }
  893.  
  894. STDMETHODIMP CMpegAudEnc::set_ForceMS(DWORD dwFlag)
  895. {
  896.     MPEG_ENCODER_CONFIG mec;
  897.     m_VEncoder.GetOutputType(&mec);
  898.     mec.dwForceMS = dwFlag;
  899.     m_VEncoder.SetOutputType(mec);
  900.     DbgLog((LOG_TRACE, 1, TEXT("set_ForceMS(%d)"), dwFlag));
  901.     return S_OK;
  902. }
  903.  
  904.  
  905. STDMETHODIMP CMpegAudEnc::get_CRCFlag(DWORD *dwFlag)
  906. {
  907.     MPEG_ENCODER_CONFIG mec;
  908.     m_VEncoder.GetOutputType(&mec);
  909.     *dwFlag = mec.bCRCProtect;
  910.     DbgLog((LOG_TRACE, 1, TEXT("get_CRCFlag -> %d"), *dwFlag));
  911.     return S_OK;
  912. }
  913.  
  914. STDMETHODIMP CMpegAudEnc::set_CRCFlag(DWORD dwFlag)
  915. {
  916.     MPEG_ENCODER_CONFIG mec;
  917.     m_VEncoder.GetOutputType(&mec);
  918.     mec.bCRCProtect = dwFlag;
  919.     m_VEncoder.SetOutputType(mec);
  920.     DbgLog((LOG_TRACE, 1, TEXT("set_CRCFlag(%d)"), dwFlag));
  921.     return S_OK;
  922. }
  923.  
  924. STDMETHODIMP CMpegAudEnc::get_EnforceVBRmin(DWORD *dwFlag)
  925. {
  926.     MPEG_ENCODER_CONFIG mec;
  927.     m_VEncoder.GetOutputType(&mec);
  928.     *dwFlag = mec.dwEnforceVBRmin;
  929.     DbgLog((LOG_TRACE, 1, TEXT("get_EnforceVBRmin -> %d"), *dwFlag));
  930.     return S_OK;
  931. }
  932.  
  933. STDMETHODIMP CMpegAudEnc::set_EnforceVBRmin(DWORD dwFlag)
  934. {
  935.     MPEG_ENCODER_CONFIG mec;
  936.     m_VEncoder.GetOutputType(&mec);
  937.     mec.dwEnforceVBRmin = dwFlag;
  938.     m_VEncoder.SetOutputType(mec);
  939.     DbgLog((LOG_TRACE, 1, TEXT("set_EnforceVBRmin(%d)"), dwFlag));
  940.     return S_OK;
  941. }
  942.  
  943. STDMETHODIMP CMpegAudEnc::get_VoiceMode(DWORD *dwFlag)
  944. {
  945.     MPEG_ENCODER_CONFIG mec;
  946.     m_VEncoder.GetOutputType(&mec);
  947.     *dwFlag = mec.dwVoiceMode;
  948.     DbgLog((LOG_TRACE, 1, TEXT("get_VoiceMode -> %d"), *dwFlag));
  949.     return S_OK;
  950. }
  951.  
  952. STDMETHODIMP CMpegAudEnc::set_VoiceMode(DWORD dwFlag)
  953. {
  954.     MPEG_ENCODER_CONFIG mec;
  955.     m_VEncoder.GetOutputType(&mec);
  956.     mec.dwVoiceMode = dwFlag;
  957.     m_VEncoder.SetOutputType(mec);
  958.     DbgLog((LOG_TRACE, 1, TEXT("set_VoiceMode(%d)"), dwFlag));
  959.     return S_OK;
  960. }
  961.  
  962. STDMETHODIMP CMpegAudEnc::get_KeepAllFreq(DWORD *dwFlag)
  963. {
  964.     MPEG_ENCODER_CONFIG mec;
  965.     m_VEncoder.GetOutputType(&mec);
  966.     *dwFlag = mec.dwKeepAllFreq;
  967.     DbgLog((LOG_TRACE, 1, TEXT("get_KeepAllFreq -> %d"), *dwFlag));
  968.     return S_OK;
  969. }
  970.  
  971. STDMETHODIMP CMpegAudEnc::set_KeepAllFreq(DWORD dwFlag)
  972. {
  973.     MPEG_ENCODER_CONFIG mec;
  974.     m_VEncoder.GetOutputType(&mec);
  975.     mec.dwKeepAllFreq = dwFlag;
  976.     m_VEncoder.SetOutputType(mec);
  977.     DbgLog((LOG_TRACE, 1, TEXT("set_KeepAllFreq(%d)"), dwFlag));
  978.     return S_OK;
  979. }
  980.  
  981. STDMETHODIMP CMpegAudEnc::get_StrictISO(DWORD *dwFlag)
  982. {
  983.     MPEG_ENCODER_CONFIG mec;
  984.     m_VEncoder.GetOutputType(&mec);
  985.     *dwFlag = mec.dwStrictISO;
  986.     DbgLog((LOG_TRACE, 1, TEXT("get_StrictISO -> %d"), *dwFlag));
  987.     return S_OK;
  988. }
  989.  
  990. STDMETHODIMP CMpegAudEnc::set_StrictISO(DWORD dwFlag)
  991. {
  992.     MPEG_ENCODER_CONFIG mec;
  993.     m_VEncoder.GetOutputType(&mec);
  994.     mec.dwStrictISO = dwFlag;
  995.     m_VEncoder.SetOutputType(mec);
  996.     DbgLog((LOG_TRACE, 1, TEXT("set_StrictISO(%d)"), dwFlag));
  997.     return S_OK;
  998. }
  999.  
  1000. STDMETHODIMP CMpegAudEnc::get_NoShortBlock(DWORD *dwNoShortBlock)
  1001. {
  1002.     MPEG_ENCODER_CONFIG mec;
  1003.     m_VEncoder.GetOutputType(&mec);
  1004.     *dwNoShortBlock = mec.dwNoShortBlock;
  1005.     DbgLog((LOG_TRACE, 1, TEXT("get_NoShortBlock -> %d"), *dwNoShortBlock));
  1006.     return S_OK;
  1007. }
  1008.  
  1009. STDMETHODIMP CMpegAudEnc::set_NoShortBlock(DWORD dwNoShortBlock)
  1010. {
  1011.     MPEG_ENCODER_CONFIG mec;
  1012.     m_VEncoder.GetOutputType(&mec);
  1013.     mec.dwNoShortBlock = dwNoShortBlock;
  1014.     m_VEncoder.SetOutputType(mec);
  1015.     DbgLog((LOG_TRACE, 1, TEXT("set_NoShortBlock(%d)"), dwNoShortBlock));
  1016.     return S_OK;
  1017. }
  1018.  
  1019. STDMETHODIMP CMpegAudEnc::get_XingTag(DWORD *dwXingTag)
  1020. {
  1021.     MPEG_ENCODER_CONFIG mec;
  1022.     m_VEncoder.GetOutputType(&mec);
  1023.     *dwXingTag = mec.dwXingTag;
  1024.     DbgLog((LOG_TRACE, 1, TEXT("get_XingTag -> %d"), *dwXingTag));
  1025.     return S_OK;
  1026. }
  1027.  
  1028. STDMETHODIMP CMpegAudEnc::set_XingTag(DWORD dwXingTag)
  1029. {
  1030.     MPEG_ENCODER_CONFIG mec;
  1031.     m_VEncoder.GetOutputType(&mec);
  1032.     mec.dwXingTag = dwXingTag;
  1033.     m_VEncoder.SetOutputType(mec);
  1034.     DbgLog((LOG_TRACE, 1, TEXT("set_XingTag(%d)"), dwXingTag));
  1035.     return S_OK;
  1036. }
  1037.  
  1038.  
  1039.  
  1040. STDMETHODIMP CMpegAudEnc::get_OriginalFlag(DWORD *dwFlag)
  1041. {
  1042.     MPEG_ENCODER_CONFIG mec;
  1043.     m_VEncoder.GetOutputType(&mec);
  1044.     *dwFlag = mec.bOriginal;
  1045.     DbgLog((LOG_TRACE, 1, TEXT("get_OriginalFlag -> %d"), *dwFlag));
  1046.     return S_OK;
  1047. }
  1048.  
  1049. STDMETHODIMP CMpegAudEnc::set_OriginalFlag(DWORD dwFlag)
  1050. {
  1051.     MPEG_ENCODER_CONFIG mec;
  1052.     m_VEncoder.GetOutputType(&mec);
  1053.     mec.bOriginal = dwFlag;
  1054.     m_VEncoder.SetOutputType(mec);
  1055.     DbgLog((LOG_TRACE, 1, TEXT("set_OriginalFlag(%d)"), dwFlag));
  1056.     return S_OK;
  1057. }
  1058.  
  1059. STDMETHODIMP CMpegAudEnc::get_CopyrightFlag(DWORD *dwFlag)
  1060. {
  1061.     MPEG_ENCODER_CONFIG mec;
  1062.     m_VEncoder.GetOutputType(&mec);
  1063.     *dwFlag = mec.bCopyright;
  1064.     DbgLog((LOG_TRACE, 1, TEXT("get_CopyrightFlag -> %d"), *dwFlag));
  1065.     return S_OK;
  1066. }
  1067.  
  1068. STDMETHODIMP CMpegAudEnc::set_CopyrightFlag(DWORD dwFlag)
  1069. {
  1070.     MPEG_ENCODER_CONFIG mec;
  1071.     m_VEncoder.GetOutputType(&mec);
  1072.     mec.bCopyright = dwFlag;
  1073.     m_VEncoder.SetOutputType(mec);
  1074.     DbgLog((LOG_TRACE, 1, TEXT("set_CopyrightFlag(%d)"), dwFlag));
  1075.     return S_OK;
  1076. }
  1077.  
  1078. STDMETHODIMP CMpegAudEnc::get_ModeFixed(DWORD *dwModeFixed)
  1079. {
  1080.     MPEG_ENCODER_CONFIG mec;
  1081.     m_VEncoder.GetOutputType(&mec);
  1082.     *dwModeFixed = mec.dwModeFixed;
  1083.     DbgLog((LOG_TRACE, 1, TEXT("get_ModeFixed -> %d"), *dwModeFixed));
  1084.     return S_OK;
  1085. }
  1086.  
  1087. STDMETHODIMP CMpegAudEnc::set_ModeFixed(DWORD dwModeFixed)
  1088. {
  1089.     MPEG_ENCODER_CONFIG mec;
  1090.     m_VEncoder.GetOutputType(&mec);
  1091.     mec.dwModeFixed = dwModeFixed;
  1092.     m_VEncoder.SetOutputType(mec);
  1093.     DbgLog((LOG_TRACE, 1, TEXT("set_ModeFixed(%d)"), dwModeFixed));
  1094.     return S_OK;
  1095. }
  1096.  
  1097. STDMETHODIMP CMpegAudEnc::get_ParameterBlockSize(BYTE *pcBlock, DWORD *pdwSize)
  1098. {
  1099.     DbgLog((LOG_TRACE, 1, TEXT("get_ParameterBlockSize -> %d%d"), *pcBlock, *pdwSize));
  1100.  
  1101.     if (pcBlock != NULL) {
  1102.         if (*pdwSize >= sizeof(MPEG_ENCODER_CONFIG)) {
  1103.             m_VEncoder.GetOutputType((MPEG_ENCODER_CONFIG*)pcBlock);
  1104.             return S_OK;
  1105.         }
  1106.         else {
  1107.             *pdwSize = sizeof(MPEG_ENCODER_CONFIG);
  1108.             return E_FAIL;
  1109.         }
  1110.     }
  1111.     else if (pdwSize != NULL) {
  1112.         *pdwSize = sizeof(MPEG_ENCODER_CONFIG);
  1113.         return S_OK;
  1114.     }
  1115.  
  1116.     return E_FAIL;
  1117. }
  1118.  
  1119. STDMETHODIMP CMpegAudEnc::set_ParameterBlockSize(BYTE *pcBlock, DWORD dwSize)
  1120. {
  1121.     DbgLog((LOG_TRACE, 1, TEXT("get_ParameterBlockSize(%d, %d)"), *pcBlock, dwSize));
  1122.     if (sizeof(MPEG_ENCODER_CONFIG) == dwSize){
  1123.         m_VEncoder.SetOutputType(*(MPEG_ENCODER_CONFIG*)pcBlock);
  1124.         return S_OK;
  1125.     }
  1126.     else return E_FAIL;    
  1127. }
  1128.  
  1129.  
  1130. STDMETHODIMP CMpegAudEnc::DefaultAudioEncoderProperties()
  1131. {
  1132.     DbgLog((LOG_TRACE, 1, TEXT("DefaultAudioEncoderProperties()")));
  1133.  
  1134.     HRESULT hr = InputTypeDefined();
  1135.     if (FAILED(hr))
  1136.         return hr;
  1137.  
  1138.     DWORD dwSourceSampleRate;
  1139.     get_SourceSampleRate(&dwSourceSampleRate);
  1140.  
  1141.     set_PESOutputEnabled(DEFAULT_PES);
  1142.     set_MPEGLayer(DEFAULT_LAYER);
  1143.  
  1144.     set_Bitrate(DEFAULT_BITRATE);
  1145.     set_Variable(FALSE);
  1146.     set_VariableMin(DEFAULT_VARIABLEMIN);
  1147.     set_VariableMax(DEFAULT_VARIABLEMAX);
  1148.     set_Quality(DEFAULT_ENCODING_QUALITY);
  1149.     set_VariableQ(DEFAULT_VBR_QUALITY);
  1150.  
  1151.     set_SampleRate(dwSourceSampleRate);
  1152.     set_CRCFlag(FALSE);
  1153.     set_OriginalFlag(FALSE);
  1154.     set_CopyrightFlag(FALSE);
  1155.  
  1156.     set_EnforceVBRmin(DEFAULT_ENFORCE_MIN);
  1157.     set_VoiceMode(DEFAULT_VOICE);
  1158.     set_KeepAllFreq(DEFAULT_KEEP_ALL_FREQ);
  1159.     set_StrictISO(DEFAULT_STRICT_ISO);
  1160.     set_NoShortBlock(DEFAULT_DISABLE_SHORT_BLOCK);
  1161.     set_XingTag(DEFAULT_XING_TAG);
  1162.     set_ForceMS(DEFAULT_FORCE_MS);
  1163.     set_ChannelMode(DEFAULT_STEREO_MODE);
  1164.     set_ModeFixed(DEFAULT_MODE_FIXED);
  1165.  
  1166.     return S_OK;
  1167. }
  1168.  
  1169. STDMETHODIMP CMpegAudEnc::LoadAudioEncoderPropertiesFromRegistry()
  1170. {
  1171.     DbgLog((LOG_TRACE, 1, TEXT("LoadAudioEncoderPropertiesFromRegistry()")));
  1172.  
  1173.     MPEG_ENCODER_CONFIG mec;
  1174.     ReadPresetSettings(&mec);
  1175.     if(m_VEncoder.SetOutputType(mec) == S_FALSE)
  1176.         return S_FALSE;
  1177.     return S_OK;
  1178. }
  1179.  
  1180. STDMETHODIMP CMpegAudEnc::SaveAudioEncoderPropertiesToRegistry()
  1181. {
  1182.     DbgLog((LOG_TRACE, 1, TEXT("SaveAudioEncoderPropertiesToRegistry()")));
  1183.     CRegKey        rk;
  1184.  
  1185.     MPEG_ENCODER_CONFIG mec;
  1186.     if(m_VEncoder.GetOutputType(&mec) == S_FALSE)
  1187.         return E_FAIL;
  1188.  
  1189.     if(rk.Create(HKEY_LOCAL_MACHINE, KEY_LAME_ENCODER))
  1190.     {
  1191.         rk.setDWORD(VALUE_BITRATE, mec.dwBitrate);
  1192.         rk.setDWORD(VALUE_VARIABLE, mec.vmVariable);
  1193.         rk.setDWORD(VALUE_VARIABLEMIN, mec.dwVariableMin);
  1194.         rk.setDWORD(VALUE_VARIABLEMAX, mec.dwVariableMax);
  1195.         rk.setDWORD(VALUE_QUALITY, mec.dwQuality);
  1196.         rk.setDWORD(VALUE_VBR_QUALITY, mec.dwVBRq);
  1197.  
  1198.         rk.setDWORD(VALUE_CRC, mec.bCRCProtect);
  1199.         rk.setDWORD(VALUE_PES, mec.dwPES);
  1200.         rk.setDWORD(VALUE_COPYRIGHT, mec.bCopyright); 
  1201.         rk.setDWORD(VALUE_ORIGINAL, mec.bOriginal); 
  1202.         rk.setDWORD(VALUE_SAMPLE_RATE, mec.dwSampleRate); 
  1203.  
  1204.         rk.setDWORD(VALUE_STEREO_MODE, mec.dwChMode);
  1205.         rk.setDWORD(VALUE_FORCE_MS, mec.dwForceMS);
  1206.         rk.setDWORD(VALUE_XING_TAG, mec.dwXingTag);
  1207.         rk.setDWORD(VALUE_DISABLE_SHORT_BLOCK, mec.dwNoShortBlock);
  1208.         rk.setDWORD(VALUE_STRICT_ISO, mec.dwStrictISO);
  1209.         rk.setDWORD(VALUE_KEEP_ALL_FREQ, mec.dwKeepAllFreq);
  1210.         rk.setDWORD(VALUE_VOICE, mec.dwVoiceMode);
  1211.         rk.setDWORD(VALUE_ENFORCE_MIN, mec.dwEnforceVBRmin);
  1212.         rk.setDWORD(VALUE_MODE_FIXED, mec.dwModeFixed);
  1213.     
  1214.         rk.Close();
  1215.     }
  1216.  
  1217.     // Reconnect filter graph
  1218.     Reconnect(); 
  1219.  
  1220.     return S_OK;
  1221. }
  1222.  
  1223. STDMETHODIMP CMpegAudEnc::InputTypeDefined()
  1224. {
  1225.     WAVEFORMATEX wf;
  1226.     if(FAILED(m_VEncoder.GetInputType(&wf)))
  1227.     {
  1228.         DbgLog((LOG_TRACE, 1, TEXT("!InputTypeDefined()")));
  1229.         return E_FAIL;
  1230.     }  
  1231.  
  1232.     DbgLog((LOG_TRACE, 1, TEXT("InputTypeDefined()")));
  1233.     return S_OK;
  1234. }
  1235.  
  1236.  
  1237. //
  1238. // CPersistStream stuff
  1239. //
  1240.  
  1241. // what is our class ID?
  1242. STDMETHODIMP CMpegAudEnc::GetClassID(CLSID *pClsid)
  1243. {
  1244.     CheckPointer(pClsid, E_POINTER);
  1245.     *pClsid = CLSID_LAMEDShowFilter;
  1246.     return S_OK;
  1247. }
  1248.  
  1249. HRESULT CMpegAudEnc::WriteToStream(IStream *pStream)
  1250. {
  1251.     CAutoLock l(&m_VEncoder);
  1252.  
  1253.     DbgLog((LOG_TRACE,1,TEXT("WriteToStream()")));
  1254.  
  1255.     MPEG_ENCODER_CONFIG mec;
  1256.  
  1257.     if(m_VEncoder.GetOutputType(&mec) == S_FALSE)
  1258.         return E_FAIL;
  1259.  
  1260.     return pStream->Write(&mec, sizeof(mec), 0);
  1261. }
  1262.  
  1263.  
  1264. // what device should we use?  Used to re-create a .GRF file that we
  1265. // are in
  1266. HRESULT CMpegAudEnc::ReadFromStream(IStream *pStream)
  1267. {
  1268.     CAutoLock l(&m_VEncoder);
  1269.  
  1270.     MPEG_ENCODER_CONFIG mec;
  1271.  
  1272.     HRESULT hr = pStream->Read(&mec, sizeof(mec), 0);
  1273.     if(FAILED(hr))
  1274.         return hr;
  1275.  
  1276.     if(m_VEncoder.SetOutputType(mec) == S_FALSE)
  1277.         return S_FALSE;
  1278.  
  1279.     DbgLog((LOG_TRACE,1,TEXT("ReadFromStream() succeeded")));
  1280.  
  1281.     hr = S_OK;
  1282.     return hr;
  1283. }
  1284.  
  1285.  
  1286. // How long is our data?
  1287. int CMpegAudEnc::SizeMax()
  1288. {
  1289.     return sizeof(MPEG_ENCODER_CONFIG);
  1290. }
  1291.  
  1292. /*
  1293. //
  1294. // IPersistPropertyBag stuff
  1295. //
  1296. // Load is called to tell us what device to use.  There may be several
  1297. // capture cards on the system that we could use
  1298. STDMETHODIMP CMpegAudEnc::Load(LPPROPERTYBAG pPropBag, LPERRORLOG pErrorLog)
  1299. {
  1300.     HRESULT hr;
  1301.     CAutoLock l(&m_VEncoder);
  1302.  
  1303.     DbgLog((LOG_TRACE,1,TEXT("Load...")));
  1304.  
  1305.     // Default settings
  1306.     if (pPropBag == NULL) {
  1307.         DbgLog((LOG_TRACE,1,TEXT("Using default settings")));
  1308.         return hr;
  1309.     }
  1310.  
  1311.     MPEG_ENCODER_CONFIG mec;
  1312.     if(m_VEncoder.GetOutputType(&mec) == S_FALSE)
  1313.         return E_FAIL;
  1314.  
  1315.     // find out what device to use
  1316.     // different filters look in different places to find this info
  1317.     VARIANT var;
  1318.     var.vt = VT_UI4;
  1319.     hr = pPropBag->Read(OLESTR(VALUE_BITRATE), &var, 0);
  1320.     if(SUCCEEDED(hr))
  1321.     {
  1322.         mec.dwBitrate = var.ulVal;
  1323.     }
  1324.  
  1325.     if(m_VEncoder.SetOutputType(mec) == S_FALSE)
  1326.         return S_FALSE;
  1327.  
  1328.     return hr;
  1329. }
  1330.  
  1331.  
  1332. STDMETHODIMP CMpegAudEnc::Save(
  1333.     LPPROPERTYBAG pPropBag, BOOL fClearDirty,
  1334.     BOOL fSaveAllProperties)
  1335. {
  1336.     CAutoLock l(&m_VEncoder);
  1337.  
  1338.     MPEG_ENCODER_CONFIG mec;
  1339.     if(m_VEncoder.GetOutputType(&mec) == S_FALSE)
  1340.         return E_FAIL;
  1341.  
  1342.     HRESULT hr;
  1343.     VARIANT var;
  1344.  
  1345.     var.vt = VT_UI4;
  1346.     var.ulVal = mec.dwBitrate;
  1347.     hr = pPropBag->Write(OLESTR(VALUE_BITRATE),&var);
  1348.  
  1349.     rk.setDWORD(VALUE_BITRATE, mec.dwBitrate);
  1350.     rk.setDWORD(VALUE_VARIABLE, mec.dwVariable);
  1351.     rk.setDWORD(VALUE_VARIABLEMIN, mec.dwVariableMin);
  1352.     rk.setDWORD(VALUE_VARIABLEMAX, mec.dwVariableMax);
  1353.     rk.setDWORD(VALUE_QUALITY, mec.dwQuality);
  1354.     rk.setDWORD(VALUE_VBR_QUALITY, mec.dwVBRq);
  1355.  
  1356.     rk.setDWORD(VALUE_CRC, mec.bCRCProtect);
  1357.     rk.setDWORD(VALUE_PES, mec.dwPES);
  1358.     rk.setDWORD(VALUE_COPYRIGHT, mec.bCopyright); 
  1359.     rk.setDWORD(VALUE_ORIGINAL, mec.bOriginal); 
  1360.     rk.setDWORD(VALUE_SAMPLE_RATE, mec.dwSampleRate); 
  1361.  
  1362.     rk.setDWORD(VALUE_STEREO_MODE, mec.dwChMode);
  1363.     rk.setDWORD(VALUE_FORCE_MS, mec.dwForceMS);
  1364.     rk.setDWORD(VALUE_XING_TAG, mec.dwXingTag);
  1365.     rk.setDWORD(VALUE_DISABLE_SHORT_BLOCK, mec.dwNoShortBlock);
  1366.     rk.setDWORD(VALUE_STRICT_ISO, mec.dwStrictISO);
  1367.     rk.setDWORD(VALUE_KEEP_ALL_FREQ, mec.dwKeepAllFreq);
  1368.     rk.setDWORD(VALUE_VOICE, mec.dwVoiceMode);
  1369.     rk.setDWORD(VALUE_ENFORCE_MIN, mec.dwEnforceVBRmin);
  1370.     rk.setDWORD(VALUE_MODE_FIXED, mec.dwModeFixed);
  1371.  
  1372.     // E_NOTIMPL is not really a valid return code as any object implementing
  1373.     // this interface must support the entire functionality of the
  1374.     // interface.
  1375.     return E_NOTIMPL;
  1376.  
  1377.   return hr;
  1378. }
  1379.  
  1380.  
  1381. // have we been initialized yet?  (Has somebody called Load)
  1382. STDMETHODIMP CMpegAudEnc::InitNew()
  1383. {
  1384.     CAutoLock l(&m_VEncoder);
  1385.  
  1386.     return HRESULT_FROM_WIN32(ERROR_ALREADY_INITIALIZED);
  1387. //    return S_OK;
  1388. }
  1389. */
  1390.  
  1391. ////////////////////////////////////////////
  1392. STDAPI DllRegisterServer()
  1393. {
  1394.     // Create entry in HKEY_CLASSES_ROOT\Filter
  1395.     OLECHAR szCLSID[CHARS_IN_GUID];
  1396.     TCHAR achTemp[MAX_PATH];
  1397.     HKEY hKey;
  1398.  
  1399.     HRESULT hr = StringFromGUID2(*g_Templates[0].m_ClsID, szCLSID, CHARS_IN_GUID);
  1400.     wsprintf(achTemp, TEXT("Filter\\%ls"), szCLSID);
  1401.     // create key
  1402.     RegCreateKey(HKEY_CLASSES_ROOT, (LPCTSTR)achTemp, &hKey);
  1403.     RegCloseKey(hKey);
  1404.     return AMovieDllRegisterServer2(TRUE);
  1405. }
  1406.  
  1407. STDAPI DllUnregisterServer()
  1408. {
  1409.     // Delete entry in HKEY_CLASSES_ROOT\Filter
  1410.     OLECHAR szCLSID[CHARS_IN_GUID];
  1411.     TCHAR achTemp[MAX_PATH];
  1412.  
  1413.     HRESULT hr = StringFromGUID2(*g_Templates[0].m_ClsID, szCLSID, CHARS_IN_GUID);
  1414.     wsprintf(achTemp, TEXT("Filter\\%ls"), szCLSID);
  1415.     // create key
  1416.     RegDeleteKey(HKEY_CLASSES_ROOT, (LPCTSTR)achTemp);
  1417.     return AMovieDllRegisterServer2(FALSE);
  1418. }
  1419.  
  1420.  
  1421.