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