/*
* LAME MP3 encoder for DirectShow
* DirectShow filter implementation
*
* Copyright (c) 2000-2005 Marie Orlova, Peter Gubanov, Vitaly Ivanov, Elecard Ltd.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <streams.h>
#include <olectl.h>
#include <initguid.h>
//#include <olectlid.h>
#include "uids.h"
#include "iaudioprops.h"
#include "mpegac.h"
#include "resource.h"
#include "PropPage.h"
#include "PropPage_adv.h"
#include "aboutprp.h"
#include "Encoder.h"
#include "Reg.h"
#ifndef _INC_MMREG
#include <mmreg.h>
#endif
// default parameters
#define DEFAULT_LAYER 3
#define DEFAULT_STEREO_MODE JOINT_STEREO
#define DEFAULT_FORCE_MS 0
#define DEFAULT_MODE_FIXED 0
#define DEFAULT_ENFORCE_MIN 0
#define DEFAULT_VOICE 0
#define DEFAULT_KEEP_ALL_FREQ 0
#define DEFAULT_STRICT_ISO 0
#define DEFAULT_DISABLE_SHORT_BLOCK 0
#define DEFAULT_XING_TAG 0
#define DEFAULT_SAMPLE_RATE 44100
#define DEFAULT_BITRATE 128
#define DEFAULT_VARIABLE 0
#define DEFAULT_CRC 0
#define DEFAULT_FORCE_MONO 0
#define DEFAULT_SET_DURATION 1
#define DEFAULT_COPYRIGHT 0
#define DEFAULT_ORIGINAL 0
#define DEFAULT_VARIABLEMIN 80
#define DEFAULT_VARIABLEMAX 160
#define DEFAULT_ENCODING_QUALITY 5
#define DEFAULT_VBR_QUALITY 4
#define DEFAULT_PES 0
/* Registration setup stuff */
// Setup data
AMOVIESETUP_MEDIATYPE sudMpgInputType[] =
{
{ &MEDIATYPE_Audio, &MEDIASUBTYPE_PCM }
};
AMOVIESETUP_MEDIATYPE sudMpgOutputType[] =
{
{ &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload },
{ &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG2_AUDIO },
};
AMOVIESETUP_PIN sudMpgPins[3] =
{
{ L"PCM Input",
FALSE, // bRendered
FALSE, // bOutput
FALSE, // bZero
FALSE, // bMany
&CLSID_NULL, // clsConnectsToFilter
NULL, // ConnectsToPin
NUMELMS(sudMpgInputType), // Number of media types
sudMpgInputType
},
{ L"MPEG Output",
FALSE, // bRendered
TRUE, // bOutput
FALSE, // bZero
FALSE, // bMany
&CLSID_NULL, // clsConnectsToFilter
NULL, // ConnectsToPin
NUMELMS(sudMpgOutputType), // Number of media types
sudMpgOutputType
}
};
AMOVIESETUP_FILTER sudMpgAEnc =
{
&CLSID_LAMEDShowFilter,
L"LAME Audio Encoder",
MERIT_SW_COMPRESSOR, // Don't use us for real!
NUMELMS(sudMpgPins), // 3 pins
sudMpgPins
};
/*****************************************************************************/
// COM Global table of objects in this dll
CFactoryTemplate g_Templates[] =
{
{ L"LAME Audio Encoder", &CLSID_LAMEDShowFilter, CMpegAudEnc::CreateInstance, NULL, &sudMpgAEnc },
{ L"LAME Audio Encoder Property Page", &CLSID_LAMEDShow_PropertyPage, CMpegAudEncPropertyPage::CreateInstance},
{ L"LAME Audio Encoder Property Page", &CLSID_LAMEDShow_PropertyPageAdv, CMpegAudEncPropertyPageAdv::CreateInstance},
{ L"LAME Audio Encoder About", &CLSID_LAMEDShow_About, CMAEAbout::CreateInstance}
};
// Count of objects listed in g_cTemplates
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
CUnknown *CMpegAudEnc::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr)
{
CUnknown *punk = new CMpegAudEnc(lpunk, phr);
if (punk == NULL)
*phr = E_OUTOFMEMORY;
return punk;
}
CMpegAudEnc::CMpegAudEnc(LPUNKNOWN lpunk, HRESULT *phr)
: CTransformFilter(NAME("LAME Audio Encoder"), lpunk,
CLSID_LAMEDShowFilter),
CPersistStream(lpunk, phr)
{
MPEG_ENCODER_CONFIG mec;
ReadPresetSettings(&mec);
m_Encoder.SetOutputType(mec);
m_hasFinished = TRUE;
}
CMpegAudEnc::~CMpegAudEnc(void)
{
}
LPAMOVIESETUP_FILTER CMpegAudEnc::GetSetupData()
{
return &sudMpgAEnc;
}
HRESULT CMpegAudEnc::Receive(IMediaSample * pSample)
{
CAutoLock lock(&m_cs);
if (!pSample)
return S_OK;
BYTE * pSourceBuffer = NULL;
if (pSample->GetPointer(&pSourceBuffer) != S_OK || !pSourceBuffer)
return S_OK;
long sample_size = pSample->GetActualDataLength();
REFERENCE_TIME rtStart, rtStop;
BOOL gotValidTime = (pSample->GetTime(&rtStart, &rtStop) != VFW_E_SAMPLE_TIME_NOT_SET);
if (sample_size <= 0 || pSourceBuffer == NULL || m_hasFinished || (gotValidTime && rtStart < 0))
return S_OK;
if (gotValidTime)
{
if (m_rtStreamTime < 0)
{
m_rtStreamTime = rtStart;
m_rtEstimated = rtStart;
}
else
{
resync_point_t * sync = m_sync + m_sync_in_idx;
// if old sync data is applied and gap is greater than 1 ms
// then make a new synchronization point
if (sync->applied && (rtStart - m_rtEstimated > 10000))
{
sync->sample = m_samplesIn;
sync->delta = rtStart - m_rtEstimated;
sync->applied = FALSE;
m_rtEstimated += sync->delta;
if (m_sync_in_idx < (RESYNC_COUNT - 1))
m_sync_in_idx++;
else
m_sync_in_idx = 0;
}
}
}
m_rtEstimated += (LONGLONG)(m_bytesToDuration * sample_size);
m_samplesIn += sample_size / m_bytesPerSample;
while (sample_size > 0)
{
int bytes_processed = m_Encoder.Encode((short *)pSourceBuffer, sample_size);
if (bytes_processed <= 0)
return S_OK;
FlushEncodedSamples();
sample_size -= bytes_processed;
pSourceBuffer += bytes_processed;
}
return S_OK;
}
HRESULT CMpegAudEnc::FlushEncodedSamples()
{
IMediaSample * pOutSample = NULL;
BYTE * pDst = NULL;
if (m_rtStreamTime < 0)
m_rtStreamTime = 0;
while (1)
{
const unsigned char * pframe = NULL;
int frame_size = m_Encoder.GetFrame(&pframe);
if (frame_size <= 0 || !pframe)
break;
if (!m_sync[m_sync_out_idx].applied && m_sync[m_sync_out_idx].sample <= m_samplesOut)
{
m_rtStreamTime += m_sync[m_sync_out_idx].delta;
m_sync[m_sync_out_idx].applied = TRUE;
if (m_sync_out_idx < (RESYNC_COUNT - 1))
m_sync_out_idx++;
else
m_sync_out_idx = 0;
}
REFERENCE_TIME rtStart = m_rtStreamTime;
REFERENCE_TIME rtStop = rtStart + m_rtFrameTime;
HRESULT hr = m_pOutput->GetDeliveryBuffer(&pOutSample, NULL, NULL, 0);
if (hr == S_OK && pOutSample)
{
hr = pOutSample->GetPointer(&pDst);
if (hr == S_OK && pDst)
{
CopyMemory(pDst, pframe, frame_size);
pOutSample->SetSyncPoint(TRUE);
pOutSample->SetActualDataLength(frame_size);
pOutSample->SetTime(&rtStart, m_setDuration ? &rtStop : NULL);
m_pOutput->Deliver(pOutSample);
}
pOutSample->Release();
}
m_samplesOut += m_samplesPerFrame;
m_rtStreamTime = rtStop;
}
return S_OK;
}
////////////////////////////////////////////////////////////////////////////
// StartStreaming - prepare to receive new data
////////////////////////////////////////////////////////////////////////////
HRESULT CMpegAudEnc::StartStreaming()
{
WAVEFORMATEX * pwfxOut = (WAVEFORMATEX *) m_pOutput->CurrentMediaType().Format();
WAVEFORMATEX * pwfxIn = (WAVEFORMATEX *) m_pInput->CurrentMediaType().Format();
m_bytesPerSample = pwfxIn->nChannels * sizeof(short);
m_samplesPerFrame = (pwfxOut->nSamplesPerSec >= 32000) ? 1152 : 576;
m_rtFrameTime = MulDiv(10000000, m_samplesPerFrame, pwfxOut->nSamplesPerSec);
m_samplesIn = m_samplesOut = 0;
m_rtStreamTime = -1;
// initialize encoder
m_Encoder.Init();
m_hasFinished = FALSE;
for (int i = 0; i < RESYNC_COUNT; i++)
{
m_sync[i].sample = 0;
m_sync[i].delta = 0;
m_sync[i].applied = TRUE;
}
m_sync_in_idx = 0;
m_sync_out_idx = 0;
get_SetDuration(&m_setDuration);
return S_OK;
}
HRESULT CMpegAudEnc::StopStreaming()
{
m_Encoder.Close();
return S_OK;
}
////////////////////////////////////////////////////////////////////////////
// EndOfStream - stop data processing
////////////////////////////////////////////////////////////////////////////
HRESULT CMpegAudEnc::EndOfStream()
{
CAutoLock lock(&m_cs);
// Flush data
m_Encoder.Finish();
FlushEncodedSamples();
// Close encoder
m_Encoder.Close();
m_hasFinished = TRUE;
return CTransformFilter::EndOfStream();
}
////////////////////////////////////////////////////////////////////////////
// BeginFlush - stop data processing
////////////////////////////////////////////////////////////////////////////
HRESULT CMpegAudEnc::BeginFlush()
{
HRESULT hr = CTransformFilter::BeginFlush();
if (SUCCEEDED(hr))
{
CAutoLock lock(&m_cs);
DWORD dwDstSize = 0;
// Flush data
m_Encoder.Finish();
FlushEncodedSamples();
m_rtStreamTime = -1;
}
return hr;
}
////////////////////////////////////////////////////////////////////////////
// SetMediaType - called when filters are connecting
////////////////////////////////////////////////////////////////////////////
HRESULT CMpegAudEnc::SetMediaType(PIN_DIRECTION direction, const CMediaType * pmt)
{
HRESULT hr = S_OK;
if (*pmt->FormatType() != FORMAT_WaveFormatEx)
return VFW_E_INVALIDMEDIATYPE;
if (pmt->FormatLength() < sizeof(WAVEFORMATEX))
return VFW_E_INVALIDMEDIATYPE;
if (direction == PINDIR_INPUT)
{
DbgLog((LOG_TRACE,1,TEXT("CMpegAudEnc::SetMediaType(), direction = PINDIR_INPUT")));
// Pass input media type to encoder
m_Encoder.SetInputType((LPWAVEFORMATEX)pmt->Format());
WAVEFORMATEX * pwfx = (WAVEFORMATEX *)pmt->Format();
if (pwfx)
m_bytesToDuration = (float)1.e7 / (float)(pwfx->nChannels * sizeof(short) * pwfx->nSamplesPerSec);
else
m_bytesToDuration = 0.0;
Reconnect();
}
else if (direction == PINDIR_OUTPUT)
{
WAVEFORMATEX wfIn;
m_Encoder.GetInputType(&wfIn);
if (wfIn.nSamplesPerSec %
((LPWAVEFORMATEX)pmt->Format())->nSamplesPerSec != 0)
return VFW_E_TYPE_NOT_ACCEPTED;
}
return hr;
}
////////////////////////////////////////////////////////////////////////////
// CheckInputType - check if you can support mtIn
////////////////////////////////////////////////////////////////////////////
HRESULT CMpegAudEnc::CheckInputType(const CMediaType* mtIn)
{
if (*mtIn->Type() == MEDIATYPE_Audio && *mtIn->FormatType() == FORMAT_WaveFormatEx)
if (mtIn->FormatLength() >= sizeof(WAVEFORMATEX))
if (mtIn->IsTemporalCompressed() == FALSE)
return m_Encoder.SetInputType((LPWAVEFORMATEX)mtIn->Format(), true);
return E_INVALIDARG;
}
////////////////////////////////////////////////////////////////////////////
// CheckTransform - checks if we can support the transform from this input to this output
////////////////////////////////////////////////////////////////////////////
HRESULT CMpegAudEnc::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
{
if (*mtOut->FormatType() != FORMAT_WaveFormatEx)
return VFW_E_INVALIDMEDIATYPE;
if (mtOut->FormatLength() < sizeof(WAVEFORMATEX))
return VFW_E_INVALIDMEDIATYPE;
MPEG_ENCODER_CONFIG mec;
if(FAILED(m_Encoder.GetOutputType(&mec)))
return S_OK;
if (((LPWAVEFORMATEX)mtIn->Format())->nSamplesPerSec % mec.dwSampleRate != 0)
return S_OK;
if (mec.dwSampleRate != ((LPWAVEFORMATEX)mtOut->Format())->nSamplesPerSec)
return VFW_E_TYPE_NOT_ACCEPTED;
return S_OK;
}
////////////////////////////////////////////////////////////////////////////
// DecideBufferSize - sets output buffers number and size
////////////////////////////////////////////////////////////////////////////
HRESULT CMpegAudEnc::DecideBufferSize(
IMemAllocator* pAllocator,
ALLOCATOR_PROPERTIES* pProperties)
{
HRESULT hr = S_OK;
///
pProperties->cBuffers = 1;
pProperties->cbBuffer = OUT_BUFFER_SIZE;
//
ASSERT(pProperties->cbBuffer);
ALLOCATOR_PROPERTIES Actual;
hr = pAllocator->SetProperties(pProperties,&Actual);
if(FAILED(hr))
return hr;
if (Actual.cbBuffer < pProperties->cbBuffer ||
Actual.cBuffers < pProperties->cBuffers)
{// can't use this allocator
return E_INVALIDARG;
}
return S_OK;
}
////////////////////////////////////////////////////////////////////////////
// GetMediaType - overrideble for suggesting outpu pin media types
////////////////////////////////////////////////////////////////////////////
HRESULT CMpegAudEnc::GetMediaType(int iPosition, CMediaType *pMediaType)
{
DbgLog((LOG_TRACE,1,TEXT("CMpegAudEnc::GetMediaType()")));
if (iPosition < 0)
return E_INVALIDARG;
switch (iPosition)
{
case 0:
{// We can support two output streams - PES or AES
if(m_Encoder.IsPES())
{
pMediaType->SetType(&MEDIATYPE_MPEG2_PES);
pMediaType->SetSubtype(&MEDIASUBTYPE_MPEG2_AUDIO);
}
else
{
pMediaType->SetType(&MEDIATYPE_Audio);
pMediaType->SetSubtype(&MEDIASUBTYPE_MP3);
}
break;
}
default:
return VFW_S_NO_MORE_ITEMS;
}
if (m_pInput->IsConnected() == FALSE)
{
pMediaType->SetFormatType(&FORMAT_None);
return NOERROR;
}
SetOutMediaType();
pMediaType->SetSampleSize(OUT_BUFFER_SIZE);
pMediaType->SetTemporalCompression(FALSE);
pMediaType->AllocFormatBuffer(sizeof(MPEGLAYER3WAVEFORMAT));
pMediaType->SetFormat((LPBYTE)&m_mwf, sizeof(MPEGLAYER3WAVEFORMAT));
pMediaType->SetFormatType(&FORMAT_WaveFormatEx);
return S_OK;
}
////////////////////////////////////////////////////////////////////////////
// SetOutMediaType - sets filter output media type according to
// current encoder out MPEG audio properties
////////////////////////////////////////////////////////////////////////////
void CMpegAudEnc::SetOutMediaType()
{
MPEG_ENCODER_CONFIG mec;
if(FAILED(m_Encoder.GetOutputType(&mec)))
return ;
WAVEFORMATEX wf;
if(FAILED(m_Encoder.GetInputType(&wf)))
return ;
// BOOL bDirty = FALSE;
if ((wf.nSamplesPerSec % mec.dwSampleRate) != 0)
{
mec.dwSampleRate = wf.nSamplesPerSec;
m_Encoder.SetOutputType(mec);
// bDirty = TRUE;
}
if (wf.nChannels == 1 && mec.ChMode != MONO)
{
mec.ChMode = MONO;
m_Encoder.SetOutputType(mec);
// bDirty = TRUE;
}
if (wf.nChannels == 2 && !mec.bForceMono && mec.ChMode == MONO)
{
mec.ChMode = STEREO;
m_Encoder.SetOutputType(mec);
// bDirty = TRUE;
}
if (wf.nChannels == 2 && mec.bForceMono)
{
mec.ChMode = MONO;
m_Encoder.SetOutputType(mec);
// bDirty = TRUE;
}
/*
if (bDirty)
{
// we are tied to the registry, especially our configuration
// so when we change the incorrect sample rate, we need
// to change the value in registry too. Same to channel mode
SaveAudioEncoderPropertiesToRegistry();
DbgLog((LOG_TRACE, 1, TEXT("Changed sampling rate internally")));
}
*/
// Fill MPEG1WAVEFORMAT DirectShow SDK structure
m_mwf.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
m_mwf.wfx.cbSize = sizeof(MPEGLAYER3WAVEFORMAT) - sizeof(WAVEFORMATEX);
if(mec.ChMode == MONO)
m_mwf.wfx.nChannels = 1;
else
m_mwf.wfx.nChannels = 2;
m_mwf.wfx.nSamplesPerSec = mec.dwSampleRate;
m_mwf.wfx.nBlockAlign = 1;
m_mwf.wfx.wBitsPerSample = 0;
m_mwf.wfx.nAvgBytesPerSec = mec.dwBitrate * 1000 / 8;
m_mwf.wID = MPEGLAYER3_ID_MPEG;
m_mwf.fdwFlags = MPEGLAYER3_FLAG_PADDING_ISO;
m_mwf.nBlockSize = 1;
m_mwf.nFramesPerBlock = 1;
m_mwf.nCodecDelay = 0;
}
HRESULT CMpegAudEnc::Reconnect()
{
HRESULT hr = S_FALSE;
if (m_pOutput && m_pOutput->IsConnected() && m_State == State_Stopped)
{
MPEG_ENCODER_CONFIG mec;
hr = m_Encoder.GetOutputType(&mec);
if ((hr = m_Encoder.SetOutputType(mec)) == S_OK)
{
CMediaType cmt;
cmt.InitMediaType();
GetMediaType(0, &cmt);
if (S_OK == (hr = m_pOutput->GetConnected()->QueryAccept(&cmt)))
hr = m_pGraph->Reconnect(m_pOutput);
else
hr = m_pOutput->SetMediaType(&cmt);
}
}
return hr;
}
//
// Read persistent configuration from Registry
//
void CMpegAudEnc::ReadPresetSettings(MPEG_ENCODER_CONFIG * pmec)
{
DbgLog((LOG_TRACE,1,TEXT("CMpegAudEnc::ReadPresetSettings()")));
CRegKey rk(HKEY_CURRENT_USER, KEY_LAME_ENCODER);
pmec->dwBitrate = rk.getDWORD(VALUE_BITRATE,DEFAULT_BITRATE);
pmec->dwVariableMin = rk.getDWORD(VALUE_VARIABLEMIN,DEFAULT_VARIABLEMIN);
pmec->dwVariableMax = rk.getDWORD(VALUE_VARIABLEMAX,DEFAULT_VARIABLEMAX);
pmec->vmVariable = rk.getDWORD(VALUE_VARIABLE, DEFAULT_VARIABLE) ? vbr_rh : vbr_off;
pmec->dwQuality = rk.getDWORD(VALUE_QUALITY,DEFAULT_ENCODING_QUALITY);
pmec->dwVBRq = rk.getDWORD(VALUE_VBR_QUALITY,DEFAULT_VBR_QUALITY);
pmec->lLayer = rk.getDWORD(VALUE_LAYER, DEFAULT_LAYER);
pmec->bCRCProtect = rk.getDWORD(VALUE_CRC, DEFAULT_CRC);
pmec->bForceMono = rk.getDWORD(VALUE_FORCE_MONO, DEFAULT_FORCE_MONO);
pmec->bSetDuration = rk.getDWORD(VALUE_SET_DURATION, DEFAULT_SET_DURATION);
pmec->bCopyright = rk.getDWORD(VALUE_COPYRIGHT, DEFAULT_COPYRIGHT);
pmec->bOriginal = rk.getDWORD(VALUE_ORIGINAL, DEFAULT_ORIGINAL);
pmec->dwSampleRate = rk.getDWORD(VALUE_SAMPLE_RATE, DEFAULT_SAMPLE_RATE);
pmec->dwPES = rk.getDWORD(VALUE_PES, DEFAULT_PES);
pmec->ChMode = (MPEG_mode)rk.getDWORD(VALUE_STEREO_MODE, DEFAULT_STEREO_MODE);
pmec->dwForceMS = rk.getDWORD(VALUE_FORCE_MS, DEFAULT_FORCE_MS);
pmec->dwEnforceVBRmin = rk.getDWORD(VALUE_ENFORCE_MIN, DEFAULT_ENFORCE_MIN);
pmec->dwVoiceMode = rk.getDWORD(VALUE_VOICE, DEFAULT_VOICE);
pmec->dwKeepAllFreq = rk.getDWORD(VALUE_KEEP_ALL_FREQ, DEFAULT_KEEP_ALL_FREQ);
pmec->dwStrictISO = rk.getDWORD(VALUE_STRICT_ISO, DEFAULT_STRICT_ISO);
pmec->dwNoShortBlock = rk.getDWORD(VALUE_DISABLE_SHORT_BLOCK, DEFAULT_DISABLE_SHORT_BLOCK);
pmec->dwXingTag = rk.getDWORD(VALUE_XING_TAG, DEFAULT_XING_TAG);
pmec->dwModeFixed = rk.getDWORD(VALUE_MODE_FIXED, DEFAULT_MODE_FIXED);
rk.Close();
}
////////////////////////////////////////////////////////////////
// Property page handling
////////////////////////////////////////////////////////////////
HRESULT CMpegAudEnc::GetPages(CAUUID *pcauuid)
{
GUID *pguid;
pcauuid->cElems = 3;
pcauuid->pElems = pguid = (GUID *) CoTaskMemAlloc(sizeof(GUID) * pcauuid->cElems);
if (pcauuid->pElems == NULL)
return E_OUTOFMEMORY;
pguid[0] = CLSID_LAMEDShow_PropertyPage;
pguid[1] = CLSID_LAMEDShow_PropertyPageAdv;
pguid[2] = CLSID_LAMEDShow_About;
return S_OK;
}
STDMETHODIMP CMpegAudEnc::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
{
if (riid == IID_ISpecifyPropertyPages)
return GetInterface((ISpecifyPropertyPages *) this, ppv);
else if(riid == IID_IPersistStream)
return GetInterface((IPersistStream *)this, ppv);
// else if (riid == IID_IVAudioEncSettings)
// return GetInterface((IVAudioEncSettings*) this, ppv);
else if (riid == IID_IAudioEncoderProperties)
return GetInterface((IAudioEncoderProperties*) this, ppv);
return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
}
////////////////////////////////////////////////////////////////
//IVAudioEncSettings interface methods
////////////////////////////////////////////////////////////////
//
// IAudioEncoderProperties
//
STDMETHODIMP CMpegAudEnc::get_PESOutputEnabled(DWORD *dwEnabled)
{
*dwEnabled = (DWORD)m_Encoder.IsPES();
DbgLog((LOG_TRACE, 1, TEXT("get_PESOutputEnabled -> %d"), *dwEnabled));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_PESOutputEnabled(DWORD dwEnabled)
{
m_Encoder.SetPES((BOOL)!!dwEnabled);
DbgLog((LOG_TRACE, 1, TEXT("set_PESOutputEnabled(%d)"), !!dwEnabled));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_MPEGLayer(DWORD *dwLayer)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwLayer = (DWORD)mec.lLayer;
DbgLog((LOG_TRACE, 1, TEXT("get_MPEGLayer -> %d"), *dwLayer));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_MPEGLayer(DWORD dwLayer)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
if (dwLayer == 2)
mec.lLayer = 2;
else if (dwLayer == 1)
mec.lLayer = 1;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_MPEGLayer(%d)"), dwLayer));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_Bitrate(DWORD *dwBitrate)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwBitrate = (DWORD)mec.dwBitrate;
DbgLog((LOG_TRACE, 1, TEXT("get_Bitrate -> %d"), *dwBitrate));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_Bitrate(DWORD dwBitrate)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.dwBitrate = dwBitrate;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_Bitrate(%d)"), dwBitrate));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_Variable(DWORD *dwVariable)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwVariable = (DWORD)(mec.vmVariable == vbr_off ? 0 : 1);
DbgLog((LOG_TRACE, 1, TEXT("get_Variable -> %d"), *dwVariable));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_Variable(DWORD dwVariable)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.vmVariable = dwVariable ? vbr_rh : vbr_off;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_Variable(%d)"), dwVariable));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_VariableMin(DWORD *dwMin)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwMin = (DWORD)mec.dwVariableMin;
DbgLog((LOG_TRACE, 1, TEXT("get_Variablemin -> %d"), *dwMin));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_VariableMin(DWORD dwMin)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.dwVariableMin = dwMin;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_Variablemin(%d)"), dwMin));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_VariableMax(DWORD *dwMax)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwMax = (DWORD)mec.dwVariableMax;
DbgLog((LOG_TRACE, 1, TEXT("get_Variablemax -> %d"), *dwMax));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_VariableMax(DWORD dwMax)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.dwVariableMax = dwMax;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_Variablemax(%d)"), dwMax));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_Quality(DWORD *dwQuality)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwQuality=(DWORD)mec.dwQuality;
DbgLog((LOG_TRACE, 1, TEXT("get_Quality -> %d"), *dwQuality));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_Quality(DWORD dwQuality)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.dwQuality = dwQuality;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_Quality(%d)"), dwQuality));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_VariableQ(DWORD *dwVBRq)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwVBRq=(DWORD)mec.dwVBRq;
DbgLog((LOG_TRACE, 1, TEXT("get_VariableQ -> %d"), *dwVBRq));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_VariableQ(DWORD dwVBRq)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.dwVBRq = dwVBRq;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_VariableQ(%d)"), dwVBRq));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_SourceSampleRate(DWORD *dwSampleRate)
{
*dwSampleRate = 0;
WAVEFORMATEX wf;
if(FAILED(m_Encoder.GetInputType(&wf)))
return E_FAIL;
*dwSampleRate = wf.nSamplesPerSec;
DbgLog((LOG_TRACE, 1, TEXT("get_SourceSampleRate -> %d"), *dwSampleRate));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_SourceChannels(DWORD *dwChannels)
{
WAVEFORMATEX wf;
if(FAILED(m_Encoder.GetInputType(&wf)))
return E_FAIL;
*dwChannels = wf.nChannels;
DbgLog((LOG_TRACE, 1, TEXT("get_SourceChannels -> %d"), *dwChannels));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_SampleRate(DWORD *dwSampleRate)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwSampleRate = mec.dwSampleRate;
DbgLog((LOG_TRACE, 1, TEXT("get_SampleRate -> %d"), *dwSampleRate));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_SampleRate(DWORD dwSampleRate)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
DWORD dwOldSampleRate = mec.dwSampleRate;
mec.dwSampleRate = dwSampleRate;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_SampleRate(%d)"), dwSampleRate));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_ChannelMode(DWORD *dwChannelMode)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwChannelMode = mec.ChMode;
DbgLog((LOG_TRACE, 1, TEXT("get_ChannelMode -> %d"), *dwChannelMode));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_ChannelMode(DWORD dwChannelMode)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.ChMode = (MPEG_mode)dwChannelMode;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_ChannelMode(%d)"), dwChannelMode));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_ForceMS(DWORD *dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwFlag = mec.dwForceMS;
DbgLog((LOG_TRACE, 1, TEXT("get_ForceMS -> %d"), *dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_ForceMS(DWORD dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.dwForceMS = dwFlag;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_ForceMS(%d)"), dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_CRCFlag(DWORD *dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwFlag = mec.bCRCProtect;
DbgLog((LOG_TRACE, 1, TEXT("get_CRCFlag -> %d"), *dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_ForceMono(DWORD *dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwFlag = mec.bForceMono;
DbgLog((LOG_TRACE, 1, TEXT("get_ForceMono -> %d"), *dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_SetDuration(DWORD *dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwFlag = mec.bSetDuration;
DbgLog((LOG_TRACE, 1, TEXT("get_SetDuration -> %d"), *dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_CRCFlag(DWORD dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.bCRCProtect = dwFlag;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_CRCFlag(%d)"), dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_ForceMono(DWORD dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.bForceMono = dwFlag;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_ForceMono(%d)"), dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_SetDuration(DWORD dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.bSetDuration = dwFlag;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_SetDuration(%d)"), dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_EnforceVBRmin(DWORD *dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwFlag = mec.dwEnforceVBRmin;
DbgLog((LOG_TRACE, 1, TEXT("get_EnforceVBRmin -> %d"), *dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_EnforceVBRmin(DWORD dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.dwEnforceVBRmin = dwFlag;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_EnforceVBRmin(%d)"), dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_VoiceMode(DWORD *dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwFlag = mec.dwVoiceMode;
DbgLog((LOG_TRACE, 1, TEXT("get_VoiceMode -> %d"), *dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_VoiceMode(DWORD dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.dwVoiceMode = dwFlag;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_VoiceMode(%d)"), dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_KeepAllFreq(DWORD *dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwFlag = mec.dwKeepAllFreq;
DbgLog((LOG_TRACE, 1, TEXT("get_KeepAllFreq -> %d"), *dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_KeepAllFreq(DWORD dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.dwKeepAllFreq = dwFlag;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_KeepAllFreq(%d)"), dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_StrictISO(DWORD *dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwFlag = mec.dwStrictISO;
DbgLog((LOG_TRACE, 1, TEXT("get_StrictISO -> %d"), *dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_StrictISO(DWORD dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.dwStrictISO = dwFlag;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_StrictISO(%d)"), dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_NoShortBlock(DWORD *dwNoShortBlock)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwNoShortBlock = mec.dwNoShortBlock;
DbgLog((LOG_TRACE, 1, TEXT("get_NoShortBlock -> %d"), *dwNoShortBlock));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_NoShortBlock(DWORD dwNoShortBlock)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.dwNoShortBlock = dwNoShortBlock;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_NoShortBlock(%d)"), dwNoShortBlock));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_XingTag(DWORD *dwXingTag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwXingTag = mec.dwXingTag;
DbgLog((LOG_TRACE, 1, TEXT("get_XingTag -> %d"), *dwXingTag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_XingTag(DWORD dwXingTag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.dwXingTag = dwXingTag;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_XingTag(%d)"), dwXingTag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_OriginalFlag(DWORD *dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwFlag = mec.bOriginal;
DbgLog((LOG_TRACE, 1, TEXT("get_OriginalFlag -> %d"), *dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_OriginalFlag(DWORD dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.bOriginal = dwFlag;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_OriginalFlag(%d)"), dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_CopyrightFlag(DWORD *dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwFlag = mec.bCopyright;
DbgLog((LOG_TRACE, 1, TEXT("get_CopyrightFlag -> %d"), *dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_CopyrightFlag(DWORD dwFlag)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.bCopyright = dwFlag;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_CopyrightFlag(%d)"), dwFlag));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_ModeFixed(DWORD *dwModeFixed)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
*dwModeFixed = mec.dwModeFixed;
DbgLog((LOG_TRACE, 1, TEXT("get_ModeFixed -> %d"), *dwModeFixed));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::set_ModeFixed(DWORD dwModeFixed)
{
MPEG_ENCODER_CONFIG mec;
m_Encoder.GetOutputType(&mec);
mec.dwModeFixed = dwModeFixed;
m_Encoder.SetOutputType(mec);
DbgLog((LOG_TRACE, 1, TEXT("set_ModeFixed(%d)"), dwModeFixed));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::get_ParameterBlockSize(BYTE *pcBlock, DWORD *pdwSize)
{
DbgLog((LOG_TRACE, 1, TEXT("get_ParameterBlockSize -> %d%d"), *pcBlock, *pdwSize));
if (pcBlock != NULL) {
if (*pdwSize >= sizeof(MPEG_ENCODER_CONFIG)) {
m_Encoder.GetOutputType((MPEG_ENCODER_CONFIG*)pcBlock);
return S_OK;
}
else {
*pdwSize = sizeof(MPEG_ENCODER_CONFIG);
return E_FAIL;
}
}
else if (pdwSize != NULL) {
*pdwSize = sizeof(MPEG_ENCODER_CONFIG);
return S_OK;
}
return E_FAIL;
}
STDMETHODIMP CMpegAudEnc::set_ParameterBlockSize(BYTE *pcBlock, DWORD dwSize)
{
DbgLog((LOG_TRACE, 1, TEXT("get_ParameterBlockSize(%d, %d)"), *pcBlock, dwSize));
if (sizeof(MPEG_ENCODER_CONFIG) == dwSize){
m_Encoder.SetOutputType(*(MPEG_ENCODER_CONFIG*)pcBlock);
return S_OK;
}
else return E_FAIL;
}
STDMETHODIMP CMpegAudEnc::DefaultAudioEncoderProperties()
{
DbgLog((LOG_TRACE, 1, TEXT("DefaultAudioEncoderProperties()")));
HRESULT hr = InputTypeDefined();
if (FAILED(hr))
return hr;
DWORD dwSourceSampleRate;
get_SourceSampleRate(&dwSourceSampleRate);
set_PESOutputEnabled(DEFAULT_PES);
set_MPEGLayer(DEFAULT_LAYER);
set_Bitrate(DEFAULT_BITRATE);
set_Variable(FALSE);
set_VariableMin(DEFAULT_VARIABLEMIN);
set_VariableMax(DEFAULT_VARIABLEMAX);
set_Quality(DEFAULT_ENCODING_QUALITY);
set_VariableQ(DEFAULT_VBR_QUALITY);
set_SampleRate(dwSourceSampleRate);
set_CRCFlag(FALSE);
set_ForceMono(FALSE);
set_SetDuration(FALSE);
set_OriginalFlag(FALSE);
set_CopyrightFlag(FALSE);
set_EnforceVBRmin(DEFAULT_ENFORCE_MIN);
set_VoiceMode(DEFAULT_VOICE);
set_KeepAllFreq(DEFAULT_KEEP_ALL_FREQ);
set_StrictISO(DEFAULT_STRICT_ISO);
set_NoShortBlock(DEFAULT_DISABLE_SHORT_BLOCK);
set_XingTag(DEFAULT_XING_TAG);
set_ForceMS(DEFAULT_FORCE_MS);
set_ChannelMode(DEFAULT_STEREO_MODE);
set_ModeFixed(DEFAULT_MODE_FIXED);
return S_OK;
}
STDMETHODIMP CMpegAudEnc::LoadAudioEncoderPropertiesFromRegistry()
{
DbgLog((LOG_TRACE, 1, TEXT("LoadAudioEncoderPropertiesFromRegistry()")));
MPEG_ENCODER_CONFIG mec;
ReadPresetSettings(&mec);
if(m_Encoder.SetOutputType(mec) == S_FALSE)
return S_FALSE;
return S_OK;
}
STDMETHODIMP CMpegAudEnc::SaveAudioEncoderPropertiesToRegistry()
{
DbgLog((LOG_TRACE, 1, TEXT("SaveAudioEncoderPropertiesToRegistry()")));
CRegKey rk;
MPEG_ENCODER_CONFIG mec;
if(m_Encoder.GetOutputType(&mec) == S_FALSE)
return E_FAIL;
if(rk.Create(HKEY_CURRENT_USER, KEY_LAME_ENCODER))
{
rk.setDWORD(VALUE_BITRATE, mec.dwBitrate);
rk.setDWORD(VALUE_VARIABLE, mec.vmVariable);
rk.setDWORD(VALUE_VARIABLEMIN, mec.dwVariableMin);
rk.setDWORD(VALUE_VARIABLEMAX, mec.dwVariableMax);
rk.setDWORD(VALUE_QUALITY, mec.dwQuality);
rk.setDWORD(VALUE_VBR_QUALITY, mec.dwVBRq);
rk.setDWORD(VALUE_CRC, mec.bCRCProtect);
rk.setDWORD(VALUE_FORCE_MONO, mec.bForceMono);
rk.setDWORD(VALUE_SET_DURATION, mec.bSetDuration);
rk.setDWORD(VALUE_PES, mec.dwPES);
rk.setDWORD(VALUE_COPYRIGHT, mec.bCopyright);
rk.setDWORD(VALUE_ORIGINAL, mec.bOriginal);
rk.setDWORD(VALUE_SAMPLE_RATE, mec.dwSampleRate);
rk.setDWORD(VALUE_STEREO_MODE, mec.ChMode);
rk.setDWORD(VALUE_FORCE_MS, mec.dwForceMS);
rk.setDWORD(VALUE_XING_TAG, mec.dwXingTag);
rk.setDWORD(VALUE_DISABLE_SHORT_BLOCK, mec.dwNoShortBlock);
rk.setDWORD(VALUE_STRICT_ISO, mec.dwStrictISO);
rk.setDWORD(VALUE_KEEP_ALL_FREQ, mec.dwKeepAllFreq);
rk.setDWORD(VALUE_VOICE, mec.dwVoiceMode);
rk.setDWORD(VALUE_ENFORCE_MIN, mec.dwEnforceVBRmin);
rk.setDWORD(VALUE_MODE_FIXED, mec.dwModeFixed);
rk.Close();
}
// Reconnect filter graph
Reconnect();
return S_OK;
}
STDMETHODIMP CMpegAudEnc::InputTypeDefined()
{
WAVEFORMATEX wf;
if(FAILED(m_Encoder.GetInputType(&wf)))
{
DbgLog((LOG_TRACE, 1, TEXT("!InputTypeDefined()")));
return E_FAIL;
}
DbgLog((LOG_TRACE, 1, TEXT("InputTypeDefined()")));
return S_OK;
}
STDMETHODIMP CMpegAudEnc::ApplyChanges()
{
return Reconnect();
}
//
// CPersistStream stuff
//
// what is our class ID?
STDMETHODIMP CMpegAudEnc::GetClassID(CLSID *pClsid)
{
CheckPointer(pClsid, E_POINTER);
*pClsid = CLSID_LAMEDShowFilter;
return S_OK;
}
HRESULT CMpegAudEnc::WriteToStream(IStream *pStream)
{
DbgLog((LOG_TRACE,1,TEXT("WriteToStream()")));
MPEG_ENCODER_CONFIG mec;
if(m_Encoder.GetOutputType(&mec) == S_FALSE)
return E_FAIL;
return pStream->Write(&mec, sizeof(mec), 0);
}
// what device should we use? Used to re-create a .GRF file that we
// are in
HRESULT CMpegAudEnc::ReadFromStream(IStream *pStream)
{
MPEG_ENCODER_CONFIG mec;
HRESULT hr = pStream->Read(&mec, sizeof(mec), 0);
if(FAILED(hr))
return hr;
if(m_Encoder.SetOutputType(mec) == S_FALSE)
return S_FALSE;
DbgLog((LOG_TRACE,1,TEXT("ReadFromStream() succeeded")));
hr = S_OK;
return hr;
}
// How long is our data?
int CMpegAudEnc::SizeMax()
{
return sizeof(MPEG_ENCODER_CONFIG);
}
////////////////////////////////////////////
STDAPI DllRegisterServer()
{
// Create entry in HKEY_CLASSES_ROOT\Filter
OLECHAR szCLSID[CHARS_IN_GUID];
TCHAR achTemp[MAX_PATH];
HKEY hKey;
HRESULT hr = StringFromGUID2(*g_Templates[0].m_ClsID, szCLSID, CHARS_IN_GUID);
wsprintf(achTemp, TEXT("Filter\\%ls"), szCLSID);
// create key
RegCreateKey(HKEY_CLASSES_ROOT, (LPCTSTR)achTemp, &hKey);
RegCloseKey(hKey);
return AMovieDllRegisterServer2(TRUE);
}
STDAPI DllUnregisterServer()
{
// Delete entry in HKEY_CLASSES_ROOT\Filter
OLECHAR szCLSID[CHARS_IN_GUID];
TCHAR achTemp[MAX_PATH];
HRESULT hr = StringFromGUID2(*g_Templates[0].m_ClsID, szCLSID, CHARS_IN_GUID);
wsprintf(achTemp, TEXT("Filter\\%ls"), szCLSID);
// create key
RegDeleteKey(HKEY_CLASSES_ROOT, (LPCTSTR)achTemp);
return AMovieDllRegisterServer2(FALSE);
}