1159b3361Sopenharmony_ci/* 2159b3361Sopenharmony_ci * LAME MP3 encoder for DirectShow 3159b3361Sopenharmony_ci * DirectShow filter implementation 4159b3361Sopenharmony_ci * 5159b3361Sopenharmony_ci * Copyright (c) 2000-2005 Marie Orlova, Peter Gubanov, Vitaly Ivanov, Elecard Ltd. 6159b3361Sopenharmony_ci * 7159b3361Sopenharmony_ci * This library is free software; you can redistribute it and/or 8159b3361Sopenharmony_ci * modify it under the terms of the GNU Library General Public 9159b3361Sopenharmony_ci * License as published by the Free Software Foundation; either 10159b3361Sopenharmony_ci * version 2 of the License, or (at your option) any later version. 11159b3361Sopenharmony_ci * 12159b3361Sopenharmony_ci * This library is distributed in the hope that it will be useful, 13159b3361Sopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14159b3361Sopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15159b3361Sopenharmony_ci * Library General Public License for more details. 16159b3361Sopenharmony_ci * 17159b3361Sopenharmony_ci * You should have received a copy of the GNU Library General Public 18159b3361Sopenharmony_ci * License along with this library; if not, write to the 19159b3361Sopenharmony_ci * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 20159b3361Sopenharmony_ci * Boston, MA 02111-1307, USA. 21159b3361Sopenharmony_ci */ 22159b3361Sopenharmony_ci 23159b3361Sopenharmony_ci#include <streams.h> 24159b3361Sopenharmony_ci#include <olectl.h> 25159b3361Sopenharmony_ci#include <initguid.h> 26159b3361Sopenharmony_ci//#include <olectlid.h> 27159b3361Sopenharmony_ci#include "uids.h" 28159b3361Sopenharmony_ci#include "iaudioprops.h" 29159b3361Sopenharmony_ci#include "mpegac.h" 30159b3361Sopenharmony_ci#include "resource.h" 31159b3361Sopenharmony_ci 32159b3361Sopenharmony_ci#include "PropPage.h" 33159b3361Sopenharmony_ci#include "PropPage_adv.h" 34159b3361Sopenharmony_ci#include "aboutprp.h" 35159b3361Sopenharmony_ci 36159b3361Sopenharmony_ci#include "Encoder.h" 37159b3361Sopenharmony_ci#include "Reg.h" 38159b3361Sopenharmony_ci 39159b3361Sopenharmony_ci#ifndef _INC_MMREG 40159b3361Sopenharmony_ci#include <mmreg.h> 41159b3361Sopenharmony_ci#endif 42159b3361Sopenharmony_ci 43159b3361Sopenharmony_ci// default parameters 44159b3361Sopenharmony_ci#define DEFAULT_LAYER 3 45159b3361Sopenharmony_ci#define DEFAULT_STEREO_MODE JOINT_STEREO 46159b3361Sopenharmony_ci#define DEFAULT_FORCE_MS 0 47159b3361Sopenharmony_ci#define DEFAULT_MODE_FIXED 0 48159b3361Sopenharmony_ci#define DEFAULT_ENFORCE_MIN 0 49159b3361Sopenharmony_ci#define DEFAULT_VOICE 0 50159b3361Sopenharmony_ci#define DEFAULT_KEEP_ALL_FREQ 0 51159b3361Sopenharmony_ci#define DEFAULT_STRICT_ISO 0 52159b3361Sopenharmony_ci#define DEFAULT_DISABLE_SHORT_BLOCK 0 53159b3361Sopenharmony_ci#define DEFAULT_XING_TAG 0 54159b3361Sopenharmony_ci#define DEFAULT_SAMPLE_RATE 44100 55159b3361Sopenharmony_ci#define DEFAULT_BITRATE 128 56159b3361Sopenharmony_ci#define DEFAULT_VARIABLE 0 57159b3361Sopenharmony_ci#define DEFAULT_CRC 0 58159b3361Sopenharmony_ci#define DEFAULT_FORCE_MONO 0 59159b3361Sopenharmony_ci#define DEFAULT_SET_DURATION 1 60159b3361Sopenharmony_ci#define DEFAULT_SAMPLE_OVERLAP 1 61159b3361Sopenharmony_ci#define DEFAULT_COPYRIGHT 0 62159b3361Sopenharmony_ci#define DEFAULT_ORIGINAL 0 63159b3361Sopenharmony_ci#define DEFAULT_VARIABLEMIN 80 64159b3361Sopenharmony_ci#define DEFAULT_VARIABLEMAX 160 65159b3361Sopenharmony_ci#define DEFAULT_ENCODING_QUALITY 5 66159b3361Sopenharmony_ci#define DEFAULT_VBR_QUALITY 4 67159b3361Sopenharmony_ci#define DEFAULT_PES 0 68159b3361Sopenharmony_ci 69159b3361Sopenharmony_ci#define DEFAULT_FILTER_MERIT MERIT_DO_NOT_USE // Standard compressor merit value 70159b3361Sopenharmony_ci 71159b3361Sopenharmony_ci#define GET_DATARATE(kbps) (kbps * 1000 / 8) 72159b3361Sopenharmony_ci#define GET_FRAMELENGTH(bitrate, sample_rate) ((WORD)(((sample_rate < 32000 ? 72000 : 144000) * (bitrate))/(sample_rate))) 73159b3361Sopenharmony_ci#define DECLARE_PTR(type, ptr, expr) type* ptr = (type*)(expr); 74159b3361Sopenharmony_ci 75159b3361Sopenharmony_ci// Create a list of all (or mostly all) of the encoder CBR output capabilities which 76159b3361Sopenharmony_ci// will be parsed into a list of capabilities used by the IAMStreamConfig Interface 77159b3361Sopenharmony_cioutput_caps_t OutputCapabilities[] = 78159b3361Sopenharmony_ci{ // {SampleRate, BitRate} 79159b3361Sopenharmony_ci { 48000, 320 },{ 48000, 256 },{ 48000, 224 },{ 48000, 192 }, // MPEG 1.0 Spec @ 48KHz 80159b3361Sopenharmony_ci { 48000, 160 },{ 48000, 128 },{ 48000, 112 },{ 48000, 96 }, 81159b3361Sopenharmony_ci { 48000, 80 },{ 48000, 64 },{ 48000, 56 },{ 48000, 48 }, 82159b3361Sopenharmony_ci { 48000, 40 },{ 48000, 32 }, 83159b3361Sopenharmony_ci 84159b3361Sopenharmony_ci { 24000, 160 },{ 24000, 144 },{ 24000, 128 },{ 24000, 112 }, // MPEG 2.0 Spec @ 24KHz 85159b3361Sopenharmony_ci { 24000, 96 },{ 24000, 80 },{ 24000, 64 },{ 24000, 56 }, 86159b3361Sopenharmony_ci { 24000, 48 },{ 24000, 40 },{ 24000, 32 },{ 24000, 24 }, 87159b3361Sopenharmony_ci { 24000, 16 },{ 24000, 8 }, 88159b3361Sopenharmony_ci 89159b3361Sopenharmony_ci { 12000, 64 },{ 12000, 56 },{ 12000, 48 },{ 12000, 40 }, // MPEG 2.5 Spec @ 12KHz 90159b3361Sopenharmony_ci { 12000, 32 },{ 12000, 24 },{ 12000, 16 },{ 12000, 8 }, 91159b3361Sopenharmony_ci // --------------------------- -------------------------- 92159b3361Sopenharmony_ci { 44100, 320 },{ 44100, 256 },{ 44100, 224 },{ 44100, 192 }, // MPEG 1.0 Spec @ 44.1KHz 93159b3361Sopenharmony_ci { 44100, 160 },{ 44100, 128 },{ 44100, 112 },{ 44100, 96 }, 94159b3361Sopenharmony_ci { 44100, 80 },{ 44100, 64 },{ 44100, 56 },{ 44100, 48 }, 95159b3361Sopenharmony_ci { 44100, 40 },{ 44100, 32 }, 96159b3361Sopenharmony_ci 97159b3361Sopenharmony_ci { 22050, 160 },{ 22050, 144 },{ 22050, 128 },{ 22050, 112 }, // MPEG 2.0 Spec @ 22.05KHz 98159b3361Sopenharmony_ci { 22050, 96 },{ 22050, 80 },{ 22050, 64 },{ 22050, 56 }, 99159b3361Sopenharmony_ci { 22050, 48 },{ 22050, 40 },{ 22050, 32 },{ 22050, 24 }, 100159b3361Sopenharmony_ci { 22050, 16 },{ 22050, 8 }, 101159b3361Sopenharmony_ci 102159b3361Sopenharmony_ci { 11025, 64 },{ 11025, 56 },{ 11025, 48 },{ 11025, 40 }, // MPEG 2.5 Spec @ 11.025KHz 103159b3361Sopenharmony_ci { 11025, 32 },{ 11025, 24 },{ 11025, 16 },{ 11025, 8 }, 104159b3361Sopenharmony_ci // --------------------------- -------------------------- 105159b3361Sopenharmony_ci { 32000, 320 },{ 32000, 256 },{ 32000, 224 },{ 32000, 192 }, // MPEG 1.0 Spec @ 32KHz 106159b3361Sopenharmony_ci { 32000, 160 },{ 32000, 128 },{ 32000, 112 },{ 32000, 96 }, 107159b3361Sopenharmony_ci { 32000, 80 },{ 32000, 64 },{ 32000, 56 },{ 32000, 48 }, 108159b3361Sopenharmony_ci { 32000, 40 },{ 32000, 32 }, 109159b3361Sopenharmony_ci 110159b3361Sopenharmony_ci { 16000, 160 },{ 16000, 144 },{ 16000, 128 },{ 16000, 112 }, // MPEG 2.0 Spec @ 16KHz 111159b3361Sopenharmony_ci { 16000, 96 },{ 16000, 80 },{ 16000, 64 },{ 16000, 56 }, 112159b3361Sopenharmony_ci { 16000, 48 },{ 16000, 40 },{ 16000, 32 },{ 16000, 24 }, 113159b3361Sopenharmony_ci { 16000, 16 },{ 16000, 8 }, 114159b3361Sopenharmony_ci 115159b3361Sopenharmony_ci { 8000, 64 },{ 8000, 56 },{ 8000, 48 },{ 8000, 40 }, // MPEG 2.5 Spec @ 8KHz 116159b3361Sopenharmony_ci { 8000, 32 },{ 8000, 24 },{ 8000, 16 },{ 8000, 8 } 117159b3361Sopenharmony_ci}; 118159b3361Sopenharmony_ci 119159b3361Sopenharmony_ci 120159b3361Sopenharmony_ci/* Registration setup stuff */ 121159b3361Sopenharmony_ci// Setup data 122159b3361Sopenharmony_ci 123159b3361Sopenharmony_ci 124159b3361Sopenharmony_ciAMOVIESETUP_MEDIATYPE sudMpgInputType[] = 125159b3361Sopenharmony_ci{ 126159b3361Sopenharmony_ci { &MEDIATYPE_Audio, &MEDIASUBTYPE_PCM } 127159b3361Sopenharmony_ci}; 128159b3361Sopenharmony_ciAMOVIESETUP_MEDIATYPE sudMpgOutputType[] = 129159b3361Sopenharmony_ci{ 130159b3361Sopenharmony_ci { &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload }, 131159b3361Sopenharmony_ci { &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG2_AUDIO }, 132159b3361Sopenharmony_ci { &MEDIATYPE_Audio, &MEDIASUBTYPE_MP3 }, 133159b3361Sopenharmony_ci { &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Audio } 134159b3361Sopenharmony_ci}; 135159b3361Sopenharmony_ci 136159b3361Sopenharmony_ciAMOVIESETUP_PIN sudMpgPins[] = 137159b3361Sopenharmony_ci{ 138159b3361Sopenharmony_ci { L"PCM Input", 139159b3361Sopenharmony_ci FALSE, // bRendered 140159b3361Sopenharmony_ci FALSE, // bOutput 141159b3361Sopenharmony_ci FALSE, // bZero 142159b3361Sopenharmony_ci FALSE, // bMany 143159b3361Sopenharmony_ci &CLSID_NULL, // clsConnectsToFilter 144159b3361Sopenharmony_ci NULL, // ConnectsToPin 145159b3361Sopenharmony_ci NUMELMS(sudMpgInputType), // Number of media types 146159b3361Sopenharmony_ci sudMpgInputType 147159b3361Sopenharmony_ci }, 148159b3361Sopenharmony_ci { L"MPEG Output", 149159b3361Sopenharmony_ci FALSE, // bRendered 150159b3361Sopenharmony_ci TRUE, // bOutput 151159b3361Sopenharmony_ci FALSE, // bZero 152159b3361Sopenharmony_ci FALSE, // bMany 153159b3361Sopenharmony_ci &CLSID_NULL, // clsConnectsToFilter 154159b3361Sopenharmony_ci NULL, // ConnectsToPin 155159b3361Sopenharmony_ci NUMELMS(sudMpgOutputType), // Number of media types 156159b3361Sopenharmony_ci sudMpgOutputType 157159b3361Sopenharmony_ci } 158159b3361Sopenharmony_ci}; 159159b3361Sopenharmony_ci 160159b3361Sopenharmony_ciAMOVIESETUP_FILTER sudMpgAEnc = 161159b3361Sopenharmony_ci{ 162159b3361Sopenharmony_ci &CLSID_LAMEDShowFilter, 163159b3361Sopenharmony_ci L"LAME Audio Encoder", 164159b3361Sopenharmony_ci DEFAULT_FILTER_MERIT, // Standard compressor merit value 165159b3361Sopenharmony_ci NUMELMS(sudMpgPins), // 2 pins 166159b3361Sopenharmony_ci sudMpgPins 167159b3361Sopenharmony_ci}; 168159b3361Sopenharmony_ci 169159b3361Sopenharmony_ci/*****************************************************************************/ 170159b3361Sopenharmony_ci// COM Global table of objects in this dll 171159b3361Sopenharmony_cistatic WCHAR g_wszName[] = L"LAME Audio Encoder"; 172159b3361Sopenharmony_ciCFactoryTemplate g_Templates[] = 173159b3361Sopenharmony_ci{ 174159b3361Sopenharmony_ci { g_wszName, &CLSID_LAMEDShowFilter, CMpegAudEnc::CreateInstance, NULL, &sudMpgAEnc }, 175159b3361Sopenharmony_ci { L"LAME Audio Encoder Property Page", &CLSID_LAMEDShow_PropertyPage, CMpegAudEncPropertyPage::CreateInstance}, 176159b3361Sopenharmony_ci { L"LAME Audio Encoder Property Page", &CLSID_LAMEDShow_PropertyPageAdv, CMpegAudEncPropertyPageAdv::CreateInstance}, 177159b3361Sopenharmony_ci { L"LAME Audio Encoder About", &CLSID_LAMEDShow_About, CMAEAbout::CreateInstance} 178159b3361Sopenharmony_ci}; 179159b3361Sopenharmony_ci// Count of objects listed in g_cTemplates 180159b3361Sopenharmony_ciint g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); 181159b3361Sopenharmony_ci 182159b3361Sopenharmony_ci 183159b3361Sopenharmony_ci 184159b3361Sopenharmony_ci//////////////////////////////////////////// 185159b3361Sopenharmony_ci// Declare the DirectShow filter information. 186159b3361Sopenharmony_ci 187159b3361Sopenharmony_ci// Used by IFilterMapper2() in the call to DllRegisterServer() 188159b3361Sopenharmony_ci// to register the filter in the CLSID_AudioCompressorCategory. 189159b3361Sopenharmony_ciREGFILTER2 rf2FilterReg = { 190159b3361Sopenharmony_ci 1, // Version number. 191159b3361Sopenharmony_ci DEFAULT_FILTER_MERIT, // Merit. This should match the merit specified in the AMOVIESETUP_FILTER definition 192159b3361Sopenharmony_ci NUMELMS(sudMpgPins), // Number of pins. 193159b3361Sopenharmony_ci sudMpgPins // Pointer to pin information. 194159b3361Sopenharmony_ci}; 195159b3361Sopenharmony_ci 196159b3361Sopenharmony_ciSTDAPI DllRegisterServer(void) 197159b3361Sopenharmony_ci{ 198159b3361Sopenharmony_ci HRESULT hr = AMovieDllRegisterServer2(TRUE); 199159b3361Sopenharmony_ci if (FAILED(hr)) { 200159b3361Sopenharmony_ci return hr; 201159b3361Sopenharmony_ci } 202159b3361Sopenharmony_ci 203159b3361Sopenharmony_ci IFilterMapper2 *pFM2 = NULL; 204159b3361Sopenharmony_ci hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, IID_IFilterMapper2, (void **)&pFM2); 205159b3361Sopenharmony_ci if (SUCCEEDED(hr)) { 206159b3361Sopenharmony_ci hr = pFM2->RegisterFilter( 207159b3361Sopenharmony_ci CLSID_LAMEDShowFilter, // Filter CLSID. 208159b3361Sopenharmony_ci g_wszName, // Filter name. 209159b3361Sopenharmony_ci NULL, // Device moniker. 210159b3361Sopenharmony_ci &CLSID_AudioCompressorCategory, // Audio compressor category. 211159b3361Sopenharmony_ci g_wszName, // Instance data. 212159b3361Sopenharmony_ci &rf2FilterReg // Filter information. 213159b3361Sopenharmony_ci ); 214159b3361Sopenharmony_ci pFM2->Release(); 215159b3361Sopenharmony_ci } 216159b3361Sopenharmony_ci return hr; 217159b3361Sopenharmony_ci} 218159b3361Sopenharmony_ci 219159b3361Sopenharmony_ciSTDAPI DllUnregisterServer() 220159b3361Sopenharmony_ci{ 221159b3361Sopenharmony_ci HRESULT hr = AMovieDllRegisterServer2(FALSE); 222159b3361Sopenharmony_ci if (FAILED(hr)) { 223159b3361Sopenharmony_ci return hr; 224159b3361Sopenharmony_ci } 225159b3361Sopenharmony_ci 226159b3361Sopenharmony_ci IFilterMapper2 *pFM2 = NULL; 227159b3361Sopenharmony_ci hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, IID_IFilterMapper2, (void **)&pFM2); 228159b3361Sopenharmony_ci if (SUCCEEDED(hr)) { 229159b3361Sopenharmony_ci hr = pFM2->UnregisterFilter(&CLSID_AudioCompressorCategory, g_wszName, CLSID_LAMEDShowFilter); 230159b3361Sopenharmony_ci pFM2->Release(); 231159b3361Sopenharmony_ci } 232159b3361Sopenharmony_ci return hr; 233159b3361Sopenharmony_ci} 234159b3361Sopenharmony_ci 235159b3361Sopenharmony_ci 236159b3361Sopenharmony_ci 237159b3361Sopenharmony_ciCUnknown *CMpegAudEnc::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr) 238159b3361Sopenharmony_ci{ 239159b3361Sopenharmony_ci CMpegAudEnc *punk = new CMpegAudEnc(lpunk, phr); 240159b3361Sopenharmony_ci if (punk == NULL) 241159b3361Sopenharmony_ci *phr = E_OUTOFMEMORY; 242159b3361Sopenharmony_ci return punk; 243159b3361Sopenharmony_ci} 244159b3361Sopenharmony_ci 245159b3361Sopenharmony_ciCMpegAudEnc::CMpegAudEnc(LPUNKNOWN lpunk, HRESULT *phr) 246159b3361Sopenharmony_ci : CTransformFilter(NAME("LAME Audio Encoder"), lpunk, CLSID_LAMEDShowFilter), 247159b3361Sopenharmony_ci CPersistStream(lpunk, phr) 248159b3361Sopenharmony_ci{ 249159b3361Sopenharmony_ci // ENCODER OUTPUT PIN 250159b3361Sopenharmony_ci // Override the output pin with our own which will implement the IAMStreamConfig Interface 251159b3361Sopenharmony_ci CTransformOutputPin *pOut = new CMpegAudEncOutPin( this, phr ); 252159b3361Sopenharmony_ci if (pOut == NULL) { 253159b3361Sopenharmony_ci *phr = E_OUTOFMEMORY; 254159b3361Sopenharmony_ci return; 255159b3361Sopenharmony_ci } 256159b3361Sopenharmony_ci else if (FAILED(*phr)) { // A failed return code should delete the object 257159b3361Sopenharmony_ci delete pOut; 258159b3361Sopenharmony_ci return; 259159b3361Sopenharmony_ci } 260159b3361Sopenharmony_ci m_pOutput = pOut; 261159b3361Sopenharmony_ci 262159b3361Sopenharmony_ci // ENCODER INPUT PIN 263159b3361Sopenharmony_ci // Since we've created our own output pin we must also create 264159b3361Sopenharmony_ci // the input pin ourselves because the CTransformFilter base class 265159b3361Sopenharmony_ci // will create an extra output pin if the input pin wasn't created. 266159b3361Sopenharmony_ci CTransformInputPin *pIn = new CTransformInputPin(NAME("LameEncoderInputPin"), 267159b3361Sopenharmony_ci this, // Owner filter 268159b3361Sopenharmony_ci phr, // Result code 269159b3361Sopenharmony_ci L"Input"); // Pin name 270159b3361Sopenharmony_ci 271159b3361Sopenharmony_ci if (pIn == NULL) { 272159b3361Sopenharmony_ci *phr = E_OUTOFMEMORY; 273159b3361Sopenharmony_ci return; 274159b3361Sopenharmony_ci } 275159b3361Sopenharmony_ci else if (FAILED(*phr)) { // A failed return code should delete the object 276159b3361Sopenharmony_ci delete pIn; 277159b3361Sopenharmony_ci return; 278159b3361Sopenharmony_ci } 279159b3361Sopenharmony_ci m_pInput = pIn; 280159b3361Sopenharmony_ci 281159b3361Sopenharmony_ci 282159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 283159b3361Sopenharmony_ci ReadPresetSettings(&mec); 284159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 285159b3361Sopenharmony_ci 286159b3361Sopenharmony_ci m_CapsNum = 0; 287159b3361Sopenharmony_ci m_hasFinished = TRUE; 288159b3361Sopenharmony_ci m_bStreamOutput = FALSE; 289159b3361Sopenharmony_ci m_currentMediaTypeIndex = 0; 290159b3361Sopenharmony_ci} 291159b3361Sopenharmony_ci 292159b3361Sopenharmony_ciCMpegAudEnc::~CMpegAudEnc(void) 293159b3361Sopenharmony_ci{ 294159b3361Sopenharmony_ci} 295159b3361Sopenharmony_ci 296159b3361Sopenharmony_ciLPAMOVIESETUP_FILTER CMpegAudEnc::GetSetupData() 297159b3361Sopenharmony_ci{ 298159b3361Sopenharmony_ci return &sudMpgAEnc; 299159b3361Sopenharmony_ci} 300159b3361Sopenharmony_ci 301159b3361Sopenharmony_ci 302159b3361Sopenharmony_ciHRESULT CMpegAudEnc::Receive(IMediaSample * pSample) 303159b3361Sopenharmony_ci{ 304159b3361Sopenharmony_ci CAutoLock lock(&m_cs); 305159b3361Sopenharmony_ci 306159b3361Sopenharmony_ci if (!pSample) 307159b3361Sopenharmony_ci return S_OK; 308159b3361Sopenharmony_ci 309159b3361Sopenharmony_ci BYTE * pSourceBuffer = NULL; 310159b3361Sopenharmony_ci 311159b3361Sopenharmony_ci if (pSample->GetPointer(&pSourceBuffer) != S_OK || !pSourceBuffer) 312159b3361Sopenharmony_ci return S_OK; 313159b3361Sopenharmony_ci 314159b3361Sopenharmony_ci long sample_size = pSample->GetActualDataLength(); 315159b3361Sopenharmony_ci 316159b3361Sopenharmony_ci REFERENCE_TIME rtStart, rtStop; 317159b3361Sopenharmony_ci BOOL gotValidTime = (pSample->GetTime(&rtStart, &rtStop) != VFW_E_SAMPLE_TIME_NOT_SET); 318159b3361Sopenharmony_ci 319159b3361Sopenharmony_ci if (sample_size <= 0 || pSourceBuffer == NULL || m_hasFinished || (gotValidTime && rtStart < 0)) 320159b3361Sopenharmony_ci return S_OK; 321159b3361Sopenharmony_ci 322159b3361Sopenharmony_ci if (gotValidTime) 323159b3361Sopenharmony_ci { 324159b3361Sopenharmony_ci if (m_rtStreamTime < 0) 325159b3361Sopenharmony_ci { 326159b3361Sopenharmony_ci m_rtStreamTime = rtStart; 327159b3361Sopenharmony_ci m_rtEstimated = rtStart; 328159b3361Sopenharmony_ci } 329159b3361Sopenharmony_ci else 330159b3361Sopenharmony_ci { 331159b3361Sopenharmony_ci resync_point_t * sync = m_sync + m_sync_in_idx; 332159b3361Sopenharmony_ci 333159b3361Sopenharmony_ci if (sync->applied) 334159b3361Sopenharmony_ci { 335159b3361Sopenharmony_ci REFERENCE_TIME rtGap = rtStart - m_rtEstimated; 336159b3361Sopenharmony_ci 337159b3361Sopenharmony_ci // if old sync data is applied and gap is greater than 1 ms 338159b3361Sopenharmony_ci // then make a new synchronization point 339159b3361Sopenharmony_ci if (rtGap > 10000 || (m_allowOverlap && rtGap < -10000)) 340159b3361Sopenharmony_ci { 341159b3361Sopenharmony_ci sync->sample = m_samplesIn; 342159b3361Sopenharmony_ci sync->delta = rtGap; 343159b3361Sopenharmony_ci sync->applied = FALSE; 344159b3361Sopenharmony_ci 345159b3361Sopenharmony_ci m_rtEstimated += sync->delta; 346159b3361Sopenharmony_ci 347159b3361Sopenharmony_ci if (m_sync_in_idx < (RESYNC_COUNT - 1)) 348159b3361Sopenharmony_ci m_sync_in_idx++; 349159b3361Sopenharmony_ci else 350159b3361Sopenharmony_ci m_sync_in_idx = 0; 351159b3361Sopenharmony_ci } 352159b3361Sopenharmony_ci } 353159b3361Sopenharmony_ci } 354159b3361Sopenharmony_ci } 355159b3361Sopenharmony_ci 356159b3361Sopenharmony_ci m_rtEstimated += (LONGLONG)(m_bytesToDuration * sample_size); 357159b3361Sopenharmony_ci m_samplesIn += sample_size / m_bytesPerSample; 358159b3361Sopenharmony_ci 359159b3361Sopenharmony_ci while (sample_size > 0) 360159b3361Sopenharmony_ci { 361159b3361Sopenharmony_ci int bytes_processed = m_Encoder.Encode((short *)pSourceBuffer, sample_size); 362159b3361Sopenharmony_ci 363159b3361Sopenharmony_ci if (bytes_processed <= 0) 364159b3361Sopenharmony_ci return S_OK; 365159b3361Sopenharmony_ci 366159b3361Sopenharmony_ci FlushEncodedSamples(); 367159b3361Sopenharmony_ci 368159b3361Sopenharmony_ci sample_size -= bytes_processed; 369159b3361Sopenharmony_ci pSourceBuffer += bytes_processed; 370159b3361Sopenharmony_ci } 371159b3361Sopenharmony_ci 372159b3361Sopenharmony_ci return S_OK; 373159b3361Sopenharmony_ci} 374159b3361Sopenharmony_ci 375159b3361Sopenharmony_ci 376159b3361Sopenharmony_ci 377159b3361Sopenharmony_ci 378159b3361Sopenharmony_ciHRESULT CMpegAudEnc::FlushEncodedSamples() 379159b3361Sopenharmony_ci{ 380159b3361Sopenharmony_ci IMediaSample * pOutSample = NULL; 381159b3361Sopenharmony_ci BYTE * pDst = NULL; 382159b3361Sopenharmony_ci 383159b3361Sopenharmony_ci if(m_bStreamOutput) 384159b3361Sopenharmony_ci { 385159b3361Sopenharmony_ci HRESULT hr = S_OK; 386159b3361Sopenharmony_ci const unsigned char * pblock = NULL; 387159b3361Sopenharmony_ci int iBufferSize; 388159b3361Sopenharmony_ci int iBlockLength = m_Encoder.GetBlockAligned(&pblock, &iBufferSize, m_cbStreamAlignment); 389159b3361Sopenharmony_ci 390159b3361Sopenharmony_ci if(!iBlockLength) 391159b3361Sopenharmony_ci return S_OK; 392159b3361Sopenharmony_ci 393159b3361Sopenharmony_ci hr = m_pOutput->GetDeliveryBuffer(&pOutSample, NULL, NULL, 0); 394159b3361Sopenharmony_ci if (hr == S_OK && pOutSample) 395159b3361Sopenharmony_ci { 396159b3361Sopenharmony_ci hr = pOutSample->GetPointer(&pDst); 397159b3361Sopenharmony_ci if (hr == S_OK && pDst) 398159b3361Sopenharmony_ci { 399159b3361Sopenharmony_ci CopyMemory(pDst, pblock, iBlockLength); 400159b3361Sopenharmony_ci REFERENCE_TIME rtEndPos = m_rtBytePos + iBufferSize; 401159b3361Sopenharmony_ci EXECUTE_ASSERT(S_OK == pOutSample->SetTime(&m_rtBytePos, &rtEndPos)); 402159b3361Sopenharmony_ci pOutSample->SetActualDataLength(iBufferSize); 403159b3361Sopenharmony_ci m_rtBytePos += iBlockLength; 404159b3361Sopenharmony_ci m_pOutput->Deliver(pOutSample); 405159b3361Sopenharmony_ci } 406159b3361Sopenharmony_ci pOutSample->Release(); 407159b3361Sopenharmony_ci } 408159b3361Sopenharmony_ci return S_OK; 409159b3361Sopenharmony_ci } 410159b3361Sopenharmony_ci 411159b3361Sopenharmony_ci if (m_rtStreamTime < 0) 412159b3361Sopenharmony_ci m_rtStreamTime = 0; 413159b3361Sopenharmony_ci 414159b3361Sopenharmony_ci while (1) 415159b3361Sopenharmony_ci { 416159b3361Sopenharmony_ci const unsigned char * pframe = NULL; 417159b3361Sopenharmony_ci int frame_size = m_Encoder.GetFrame(&pframe); 418159b3361Sopenharmony_ci 419159b3361Sopenharmony_ci if (frame_size <= 0 || !pframe) 420159b3361Sopenharmony_ci break; 421159b3361Sopenharmony_ci 422159b3361Sopenharmony_ci if (!m_sync[m_sync_out_idx].applied && m_sync[m_sync_out_idx].sample <= m_samplesOut) 423159b3361Sopenharmony_ci { 424159b3361Sopenharmony_ci m_rtStreamTime += m_sync[m_sync_out_idx].delta; 425159b3361Sopenharmony_ci m_sync[m_sync_out_idx].applied = TRUE; 426159b3361Sopenharmony_ci 427159b3361Sopenharmony_ci if (m_sync_out_idx < (RESYNC_COUNT - 1)) 428159b3361Sopenharmony_ci m_sync_out_idx++; 429159b3361Sopenharmony_ci else 430159b3361Sopenharmony_ci m_sync_out_idx = 0; 431159b3361Sopenharmony_ci } 432159b3361Sopenharmony_ci 433159b3361Sopenharmony_ci REFERENCE_TIME rtStart = m_rtStreamTime; 434159b3361Sopenharmony_ci REFERENCE_TIME rtStop = rtStart + m_rtFrameTime; 435159b3361Sopenharmony_ci 436159b3361Sopenharmony_ci HRESULT hr = m_pOutput->GetDeliveryBuffer(&pOutSample, NULL, NULL, 0); 437159b3361Sopenharmony_ci if (hr == S_OK && pOutSample) 438159b3361Sopenharmony_ci { 439159b3361Sopenharmony_ci hr = pOutSample->GetPointer(&pDst); 440159b3361Sopenharmony_ci if (hr == S_OK && pDst) 441159b3361Sopenharmony_ci { 442159b3361Sopenharmony_ci CopyMemory(pDst, pframe, frame_size); 443159b3361Sopenharmony_ci pOutSample->SetActualDataLength(frame_size); 444159b3361Sopenharmony_ci pOutSample->SetSyncPoint(TRUE); 445159b3361Sopenharmony_ci pOutSample->SetTime(&rtStart, m_setDuration ? &rtStop : NULL); 446159b3361Sopenharmony_ci m_pOutput->Deliver(pOutSample); 447159b3361Sopenharmony_ci } 448159b3361Sopenharmony_ci pOutSample->Release(); 449159b3361Sopenharmony_ci } 450159b3361Sopenharmony_ci m_samplesOut += m_samplesPerFrame; 451159b3361Sopenharmony_ci m_rtStreamTime = rtStop; 452159b3361Sopenharmony_ci } 453159b3361Sopenharmony_ci 454159b3361Sopenharmony_ci return S_OK; 455159b3361Sopenharmony_ci} 456159b3361Sopenharmony_ci 457159b3361Sopenharmony_ci 458159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 459159b3361Sopenharmony_ci// StartStreaming - prepare to receive new data 460159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 461159b3361Sopenharmony_ciHRESULT CMpegAudEnc::StartStreaming() 462159b3361Sopenharmony_ci{ 463159b3361Sopenharmony_ci WAVEFORMATEX * pwfxIn = (WAVEFORMATEX *) m_pInput->CurrentMediaType().Format(); 464159b3361Sopenharmony_ci 465159b3361Sopenharmony_ci m_bytesPerSample = pwfxIn->nChannels * sizeof(short); 466159b3361Sopenharmony_ci DWORD dwOutSampleRate; 467159b3361Sopenharmony_ci if(MEDIATYPE_Stream == m_pOutput->CurrentMediaType().majortype) 468159b3361Sopenharmony_ci { 469159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mcfg; 470159b3361Sopenharmony_ci if(FAILED(m_Encoder.GetOutputType(&mcfg))) 471159b3361Sopenharmony_ci return E_FAIL; 472159b3361Sopenharmony_ci dwOutSampleRate = mcfg.dwSampleRate; 473159b3361Sopenharmony_ci } 474159b3361Sopenharmony_ci else 475159b3361Sopenharmony_ci { 476159b3361Sopenharmony_ci dwOutSampleRate = ((WAVEFORMATEX *) m_pOutput->CurrentMediaType().Format())->nSamplesPerSec; 477159b3361Sopenharmony_ci } 478159b3361Sopenharmony_ci m_samplesPerFrame = (dwOutSampleRate >= 32000) ? 1152 : 576; 479159b3361Sopenharmony_ci m_rtFrameTime = MulDiv(10000000, m_samplesPerFrame, dwOutSampleRate); 480159b3361Sopenharmony_ci m_samplesIn = m_samplesOut = 0; 481159b3361Sopenharmony_ci m_rtStreamTime = -1; 482159b3361Sopenharmony_ci m_rtBytePos = 0; 483159b3361Sopenharmony_ci 484159b3361Sopenharmony_ci // initialize encoder 485159b3361Sopenharmony_ci m_Encoder.Init(); 486159b3361Sopenharmony_ci 487159b3361Sopenharmony_ci m_hasFinished = FALSE; 488159b3361Sopenharmony_ci 489159b3361Sopenharmony_ci for (int i = 0; i < RESYNC_COUNT; i++) 490159b3361Sopenharmony_ci { 491159b3361Sopenharmony_ci m_sync[i].sample = 0; 492159b3361Sopenharmony_ci m_sync[i].delta = 0; 493159b3361Sopenharmony_ci m_sync[i].applied = TRUE; 494159b3361Sopenharmony_ci } 495159b3361Sopenharmony_ci 496159b3361Sopenharmony_ci m_sync_in_idx = 0; 497159b3361Sopenharmony_ci m_sync_out_idx = 0; 498159b3361Sopenharmony_ci 499159b3361Sopenharmony_ci get_SetDuration(&m_setDuration); 500159b3361Sopenharmony_ci get_SampleOverlap(&m_allowOverlap); 501159b3361Sopenharmony_ci 502159b3361Sopenharmony_ci return S_OK; 503159b3361Sopenharmony_ci} 504159b3361Sopenharmony_ci 505159b3361Sopenharmony_ci 506159b3361Sopenharmony_ciHRESULT CMpegAudEnc::StopStreaming() 507159b3361Sopenharmony_ci{ 508159b3361Sopenharmony_ci IStream *pStream = NULL; 509159b3361Sopenharmony_ci if(m_bStreamOutput && m_pOutput->IsConnected() != FALSE) 510159b3361Sopenharmony_ci { 511159b3361Sopenharmony_ci IPin * pDwnstrmInputPin = m_pOutput->GetConnected(); 512159b3361Sopenharmony_ci if(pDwnstrmInputPin && FAILED(pDwnstrmInputPin->QueryInterface(IID_IStream, (LPVOID*)(&pStream)))) 513159b3361Sopenharmony_ci { 514159b3361Sopenharmony_ci pStream = NULL; 515159b3361Sopenharmony_ci } 516159b3361Sopenharmony_ci } 517159b3361Sopenharmony_ci 518159b3361Sopenharmony_ci 519159b3361Sopenharmony_ci m_Encoder.Close(pStream); 520159b3361Sopenharmony_ci 521159b3361Sopenharmony_ci if(pStream) 522159b3361Sopenharmony_ci pStream->Release(); 523159b3361Sopenharmony_ci 524159b3361Sopenharmony_ci return S_OK; 525159b3361Sopenharmony_ci} 526159b3361Sopenharmony_ci 527159b3361Sopenharmony_ci 528159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 529159b3361Sopenharmony_ci// EndOfStream - stop data processing 530159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 531159b3361Sopenharmony_ciHRESULT CMpegAudEnc::EndOfStream() 532159b3361Sopenharmony_ci{ 533159b3361Sopenharmony_ci CAutoLock lock(&m_cs); 534159b3361Sopenharmony_ci 535159b3361Sopenharmony_ci // Flush data 536159b3361Sopenharmony_ci m_Encoder.Finish(); 537159b3361Sopenharmony_ci FlushEncodedSamples(); 538159b3361Sopenharmony_ci 539159b3361Sopenharmony_ci IStream *pStream = NULL; 540159b3361Sopenharmony_ci if(m_bStreamOutput && m_pOutput->IsConnected() != FALSE) 541159b3361Sopenharmony_ci { 542159b3361Sopenharmony_ci IPin * pDwnstrmInputPin = m_pOutput->GetConnected(); 543159b3361Sopenharmony_ci if(pDwnstrmInputPin) 544159b3361Sopenharmony_ci { 545159b3361Sopenharmony_ci if(FAILED(pDwnstrmInputPin->QueryInterface(IID_IStream, (LPVOID*)(&pStream)))) 546159b3361Sopenharmony_ci { 547159b3361Sopenharmony_ci pStream = NULL; 548159b3361Sopenharmony_ci } 549159b3361Sopenharmony_ci } 550159b3361Sopenharmony_ci } 551159b3361Sopenharmony_ci 552159b3361Sopenharmony_ci if(pStream) 553159b3361Sopenharmony_ci { 554159b3361Sopenharmony_ci ULARGE_INTEGER size; 555159b3361Sopenharmony_ci size.QuadPart = m_rtBytePos; 556159b3361Sopenharmony_ci pStream->SetSize(size); 557159b3361Sopenharmony_ci } 558159b3361Sopenharmony_ci 559159b3361Sopenharmony_ci m_Encoder.Close(pStream); 560159b3361Sopenharmony_ci 561159b3361Sopenharmony_ci if(pStream) 562159b3361Sopenharmony_ci pStream->Release(); 563159b3361Sopenharmony_ci 564159b3361Sopenharmony_ci m_hasFinished = TRUE; 565159b3361Sopenharmony_ci 566159b3361Sopenharmony_ci return CTransformFilter::EndOfStream(); 567159b3361Sopenharmony_ci} 568159b3361Sopenharmony_ci 569159b3361Sopenharmony_ci 570159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 571159b3361Sopenharmony_ci// BeginFlush - stop data processing 572159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 573159b3361Sopenharmony_ciHRESULT CMpegAudEnc::BeginFlush() 574159b3361Sopenharmony_ci{ 575159b3361Sopenharmony_ci HRESULT hr = CTransformFilter::BeginFlush(); 576159b3361Sopenharmony_ci 577159b3361Sopenharmony_ci if (SUCCEEDED(hr)) 578159b3361Sopenharmony_ci { 579159b3361Sopenharmony_ci CAutoLock lock(&m_cs); 580159b3361Sopenharmony_ci 581159b3361Sopenharmony_ci DWORD dwDstSize = 0; 582159b3361Sopenharmony_ci 583159b3361Sopenharmony_ci // Flush data 584159b3361Sopenharmony_ci m_Encoder.Finish(); 585159b3361Sopenharmony_ci FlushEncodedSamples(); 586159b3361Sopenharmony_ci 587159b3361Sopenharmony_ci IStream *pStream = NULL; 588159b3361Sopenharmony_ci if(m_bStreamOutput && m_pOutput->IsConnected() != FALSE) 589159b3361Sopenharmony_ci { 590159b3361Sopenharmony_ci IPin * pDwnstrmInputPin = m_pOutput->GetConnected(); 591159b3361Sopenharmony_ci if(pDwnstrmInputPin && SUCCEEDED(pDwnstrmInputPin->QueryInterface(IID_IStream, (LPVOID*)(&pStream)))) 592159b3361Sopenharmony_ci { 593159b3361Sopenharmony_ci ULARGE_INTEGER size; 594159b3361Sopenharmony_ci size.QuadPart = m_rtBytePos; 595159b3361Sopenharmony_ci pStream->SetSize(size); 596159b3361Sopenharmony_ci pStream->Release(); 597159b3361Sopenharmony_ci } 598159b3361Sopenharmony_ci } 599159b3361Sopenharmony_ci m_rtStreamTime = -1; 600159b3361Sopenharmony_ci m_rtBytePos = 0; 601159b3361Sopenharmony_ci } 602159b3361Sopenharmony_ci 603159b3361Sopenharmony_ci return hr; 604159b3361Sopenharmony_ci} 605159b3361Sopenharmony_ci 606159b3361Sopenharmony_ci 607159b3361Sopenharmony_ci 608159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 609159b3361Sopenharmony_ci// SetMediaType - called when filters are connecting 610159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 611159b3361Sopenharmony_ciHRESULT CMpegAudEnc::SetMediaType(PIN_DIRECTION direction, const CMediaType * pmt) 612159b3361Sopenharmony_ci{ 613159b3361Sopenharmony_ci if (pmt == NULL) 614159b3361Sopenharmony_ci return E_POINTER; 615159b3361Sopenharmony_ci 616159b3361Sopenharmony_ci HRESULT hr = S_OK; 617159b3361Sopenharmony_ci 618159b3361Sopenharmony_ci if (direction == PINDIR_INPUT) 619159b3361Sopenharmony_ci { 620159b3361Sopenharmony_ci if (*pmt->FormatType() != FORMAT_WaveFormatEx) 621159b3361Sopenharmony_ci return VFW_E_INVALIDMEDIATYPE; 622159b3361Sopenharmony_ci 623159b3361Sopenharmony_ci if (pmt->FormatLength() < sizeof(WAVEFORMATEX)) 624159b3361Sopenharmony_ci return VFW_E_INVALIDMEDIATYPE; 625159b3361Sopenharmony_ci 626159b3361Sopenharmony_ci DbgLog((LOG_TRACE,1,TEXT("CMpegAudEnc::SetMediaType(), direction = PINDIR_INPUT"))); 627159b3361Sopenharmony_ci 628159b3361Sopenharmony_ci // Pass input media type to encoder 629159b3361Sopenharmony_ci m_Encoder.SetInputType((LPWAVEFORMATEX)pmt->Format()); 630159b3361Sopenharmony_ci 631159b3361Sopenharmony_ci WAVEFORMATEX * pwfx = (WAVEFORMATEX *)pmt->Format(); 632159b3361Sopenharmony_ci DWORD sample_rate = 44100; 633159b3361Sopenharmony_ci 634159b3361Sopenharmony_ci if (pwfx) { 635159b3361Sopenharmony_ci sample_rate = pwfx->nSamplesPerSec; 636159b3361Sopenharmony_ci m_bytesToDuration = (float)1.e7 / (float)(pwfx->nChannels * sizeof(short) * pwfx->nSamplesPerSec); 637159b3361Sopenharmony_ci } else { 638159b3361Sopenharmony_ci m_bytesToDuration = 0.0; 639159b3361Sopenharmony_ci } 640159b3361Sopenharmony_ci // Parse the encoder output capabilities into the subset of capabilities that are supported 641159b3361Sopenharmony_ci // for the current input format. This listing will be utilized by the IAMStreamConfig Interface. 642159b3361Sopenharmony_ci LoadOutputCapabilities(sample_rate); 643159b3361Sopenharmony_ci 644159b3361Sopenharmony_ci Reconnect(); 645159b3361Sopenharmony_ci } 646159b3361Sopenharmony_ci else if (direction == PINDIR_OUTPUT) 647159b3361Sopenharmony_ci { 648159b3361Sopenharmony_ci // Before we set the output type, we might need to reconnect 649159b3361Sopenharmony_ci // the input pin with a new type. 650159b3361Sopenharmony_ci if (m_pInput && m_pInput->IsConnected()) 651159b3361Sopenharmony_ci { 652159b3361Sopenharmony_ci // Check if the current input type is compatible. 653159b3361Sopenharmony_ci hr = CheckTransform(&m_pInput->CurrentMediaType(), &m_pOutput->CurrentMediaType()); 654159b3361Sopenharmony_ci if (FAILED(hr)) { 655159b3361Sopenharmony_ci // We need to reconnect the input pin. 656159b3361Sopenharmony_ci // Note: The CheckMediaType method has already called QueryAccept on the upstream filter. 657159b3361Sopenharmony_ci hr = m_pGraph->Reconnect(m_pInput); 658159b3361Sopenharmony_ci return hr; 659159b3361Sopenharmony_ci } 660159b3361Sopenharmony_ci } 661159b3361Sopenharmony_ci 662159b3361Sopenharmony_ci// WAVEFORMATEX wfIn; 663159b3361Sopenharmony_ci// m_Encoder.GetInputType(&wfIn); 664159b3361Sopenharmony_ci 665159b3361Sopenharmony_ci// if (wfIn.nSamplesPerSec % 666159b3361Sopenharmony_ci// ((LPWAVEFORMATEX)pmt->Format())->nSamplesPerSec != 0) 667159b3361Sopenharmony_ci// return VFW_E_TYPE_NOT_ACCEPTED; 668159b3361Sopenharmony_ci } 669159b3361Sopenharmony_ci 670159b3361Sopenharmony_ci return hr; 671159b3361Sopenharmony_ci} 672159b3361Sopenharmony_ci 673159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 674159b3361Sopenharmony_ci// CheckInputType - check if you can support mtIn 675159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 676159b3361Sopenharmony_ciHRESULT CMpegAudEnc::CheckInputType(const CMediaType* mtIn) 677159b3361Sopenharmony_ci{ 678159b3361Sopenharmony_ci if (*mtIn->Type() == MEDIATYPE_Audio && *mtIn->FormatType() == FORMAT_WaveFormatEx) 679159b3361Sopenharmony_ci if (mtIn->FormatLength() >= sizeof(WAVEFORMATEX)) 680159b3361Sopenharmony_ci if (mtIn->IsTemporalCompressed() == FALSE) 681159b3361Sopenharmony_ci return m_Encoder.SetInputType((LPWAVEFORMATEX)mtIn->Format(), true); 682159b3361Sopenharmony_ci 683159b3361Sopenharmony_ci return E_INVALIDARG; 684159b3361Sopenharmony_ci} 685159b3361Sopenharmony_ci 686159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 687159b3361Sopenharmony_ci// CheckTransform - checks if we can support the transform from this input to this output 688159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 689159b3361Sopenharmony_ciHRESULT CMpegAudEnc::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut) 690159b3361Sopenharmony_ci{ 691159b3361Sopenharmony_ci if(MEDIATYPE_Stream != mtOut->majortype) 692159b3361Sopenharmony_ci { 693159b3361Sopenharmony_ci if (*mtOut->FormatType() != FORMAT_WaveFormatEx) 694159b3361Sopenharmony_ci return VFW_E_INVALIDMEDIATYPE; 695159b3361Sopenharmony_ci 696159b3361Sopenharmony_ci if (mtOut->FormatLength() < sizeof(WAVEFORMATEX)) 697159b3361Sopenharmony_ci return VFW_E_INVALIDMEDIATYPE; 698159b3361Sopenharmony_ci 699159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 700159b3361Sopenharmony_ci if(FAILED(m_Encoder.GetOutputType(&mec))) 701159b3361Sopenharmony_ci return S_OK; 702159b3361Sopenharmony_ci 703159b3361Sopenharmony_ci if (((LPWAVEFORMATEX)mtIn->Format())->nSamplesPerSec % mec.dwSampleRate != 0) 704159b3361Sopenharmony_ci return S_OK; 705159b3361Sopenharmony_ci 706159b3361Sopenharmony_ci if (mec.dwSampleRate != ((LPWAVEFORMATEX)mtOut->Format())->nSamplesPerSec) 707159b3361Sopenharmony_ci return VFW_E_TYPE_NOT_ACCEPTED; 708159b3361Sopenharmony_ci 709159b3361Sopenharmony_ci return S_OK; 710159b3361Sopenharmony_ci } 711159b3361Sopenharmony_ci else if(mtOut->subtype == MEDIASUBTYPE_MPEG1Audio) 712159b3361Sopenharmony_ci return S_OK; 713159b3361Sopenharmony_ci 714159b3361Sopenharmony_ci return VFW_E_TYPE_NOT_ACCEPTED; 715159b3361Sopenharmony_ci} 716159b3361Sopenharmony_ci 717159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 718159b3361Sopenharmony_ci// DecideBufferSize - sets output buffers number and size 719159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 720159b3361Sopenharmony_ciHRESULT CMpegAudEnc::DecideBufferSize( 721159b3361Sopenharmony_ci IMemAllocator* pAllocator, 722159b3361Sopenharmony_ci ALLOCATOR_PROPERTIES* pProperties) 723159b3361Sopenharmony_ci{ 724159b3361Sopenharmony_ci HRESULT hr = S_OK; 725159b3361Sopenharmony_ci 726159b3361Sopenharmony_ci if(m_bStreamOutput) 727159b3361Sopenharmony_ci m_cbStreamAlignment = pProperties->cbAlign; 728159b3361Sopenharmony_ci 729159b3361Sopenharmony_ci /// 730159b3361Sopenharmony_ci if (pProperties->cBuffers == 0) pProperties->cBuffers = 1; // If downstream filter didn't suggest a buffer count then default to 1 731159b3361Sopenharmony_ci pProperties->cbBuffer = OUT_BUFFER_SIZE; 732159b3361Sopenharmony_ci // 733159b3361Sopenharmony_ci 734159b3361Sopenharmony_ci ASSERT(pProperties->cbBuffer); 735159b3361Sopenharmony_ci 736159b3361Sopenharmony_ci ALLOCATOR_PROPERTIES Actual; 737159b3361Sopenharmony_ci hr = pAllocator->SetProperties(pProperties,&Actual); 738159b3361Sopenharmony_ci if(FAILED(hr)) 739159b3361Sopenharmony_ci return hr; 740159b3361Sopenharmony_ci 741159b3361Sopenharmony_ci if (Actual.cbBuffer < pProperties->cbBuffer || 742159b3361Sopenharmony_ci Actual.cBuffers < pProperties->cBuffers) 743159b3361Sopenharmony_ci {// can't use this allocator 744159b3361Sopenharmony_ci return E_INVALIDARG; 745159b3361Sopenharmony_ci } 746159b3361Sopenharmony_ci return S_OK; 747159b3361Sopenharmony_ci} 748159b3361Sopenharmony_ci 749159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 750159b3361Sopenharmony_ci// GetMediaType - overrideable for suggesting output pin media types 751159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 752159b3361Sopenharmony_ciHRESULT CMpegAudEnc::GetMediaType(int iPosition, CMediaType *pMediaType) 753159b3361Sopenharmony_ci{ 754159b3361Sopenharmony_ci DbgLog((LOG_TRACE,1,TEXT("CMpegAudEnc::GetMediaType()"))); 755159b3361Sopenharmony_ci 756159b3361Sopenharmony_ci return m_pOutput->GetMediaType(iPosition, pMediaType); 757159b3361Sopenharmony_ci} 758159b3361Sopenharmony_ci 759159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 760159b3361Sopenharmony_ci// Reconnect - called after a manual change has been made to the 761159b3361Sopenharmony_ci// encoder parameters to reset the filter output media type structure 762159b3361Sopenharmony_ci// to match the current encoder out MPEG audio properties 763159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 764159b3361Sopenharmony_ciHRESULT CMpegAudEnc::Reconnect() 765159b3361Sopenharmony_ci{ 766159b3361Sopenharmony_ci HRESULT hr = S_FALSE; 767159b3361Sopenharmony_ci 768159b3361Sopenharmony_ci if (m_pOutput && m_pOutput->IsConnected() && m_State == State_Stopped) 769159b3361Sopenharmony_ci { 770159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 771159b3361Sopenharmony_ci hr = m_Encoder.GetOutputType(&mec); 772159b3361Sopenharmony_ci 773159b3361Sopenharmony_ci if ((hr = m_Encoder.SetOutputType(mec)) == S_OK) 774159b3361Sopenharmony_ci { 775159b3361Sopenharmony_ci // Create an updated output MediaType using the current encoder settings 776159b3361Sopenharmony_ci CMediaType cmt; 777159b3361Sopenharmony_ci cmt.InitMediaType(); 778159b3361Sopenharmony_ci m_pOutput->GetMediaType(m_currentMediaTypeIndex, &cmt); 779159b3361Sopenharmony_ci 780159b3361Sopenharmony_ci // If the updated MediaType matches the current output MediaType no reconnect is needed 781159b3361Sopenharmony_ci if (m_pOutput->CurrentMediaType() == cmt) return S_OK; 782159b3361Sopenharmony_ci 783159b3361Sopenharmony_ci // Attempt to reconnect the output pin using the updated MediaType 784159b3361Sopenharmony_ci if (S_OK == (hr = m_pOutput->GetConnected()->QueryAccept(&cmt))) { 785159b3361Sopenharmony_ci hr = m_pOutput->SetMediaType(&cmt); 786159b3361Sopenharmony_ci if ( FAILED(hr) ) { return(hr); } 787159b3361Sopenharmony_ci 788159b3361Sopenharmony_ci hr = m_pGraph->Reconnect(m_pOutput); 789159b3361Sopenharmony_ci } 790159b3361Sopenharmony_ci else 791159b3361Sopenharmony_ci hr = m_pOutput->SetMediaType(&cmt); 792159b3361Sopenharmony_ci } 793159b3361Sopenharmony_ci } 794159b3361Sopenharmony_ci 795159b3361Sopenharmony_ci return hr; 796159b3361Sopenharmony_ci} 797159b3361Sopenharmony_ci 798159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 799159b3361Sopenharmony_ci// LoadOutputCapabilities - create a list of the currently supported output 800159b3361Sopenharmony_ci// format capabilities which will be used by the IAMStreamConfig Interface 801159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////////////////// 802159b3361Sopenharmony_civoid CMpegAudEnc::LoadOutputCapabilities(DWORD sample_rate) 803159b3361Sopenharmony_ci{ 804159b3361Sopenharmony_ci m_CapsNum = 0; 805159b3361Sopenharmony_ci 806159b3361Sopenharmony_ci // Clear out any existing output capabilities 807159b3361Sopenharmony_ci ZeroMemory(OutputCaps, sizeof(OutputCaps)); 808159b3361Sopenharmony_ci 809159b3361Sopenharmony_ci // Create the set of Constant Bit Rate output capabilities that are 810159b3361Sopenharmony_ci // supported for the current input pin sampling rate. 811159b3361Sopenharmony_ci for (int i = 0; i < NUMELMS(OutputCapabilities); i++) { 812159b3361Sopenharmony_ci if (0 == sample_rate % OutputCapabilities[i].nSampleRate) { 813159b3361Sopenharmony_ci 814159b3361Sopenharmony_ci // Add this output capability to the OutputCaps list 815159b3361Sopenharmony_ci OutputCaps[m_CapsNum] = OutputCapabilities[i]; 816159b3361Sopenharmony_ci m_CapsNum++; 817159b3361Sopenharmony_ci 818159b3361Sopenharmony_ci // Don't overrun the hard-coded capabilities array limit 819159b3361Sopenharmony_ci if (m_CapsNum > (int)MAX_IAMSTREAMCONFIG_CAPS) break; 820159b3361Sopenharmony_ci } 821159b3361Sopenharmony_ci } 822159b3361Sopenharmony_ci} 823159b3361Sopenharmony_ci 824159b3361Sopenharmony_ci 825159b3361Sopenharmony_ci// 826159b3361Sopenharmony_ci// Read persistent configuration from Registry 827159b3361Sopenharmony_ci// 828159b3361Sopenharmony_civoid CMpegAudEnc::ReadPresetSettings(MPEG_ENCODER_CONFIG * pmec) 829159b3361Sopenharmony_ci{ 830159b3361Sopenharmony_ci DbgLog((LOG_TRACE,1,TEXT("CMpegAudEnc::ReadPresetSettings()"))); 831159b3361Sopenharmony_ci 832159b3361Sopenharmony_ci Lame::CRegKey rk(HKEY_CURRENT_USER, KEY_LAME_ENCODER); 833159b3361Sopenharmony_ci 834159b3361Sopenharmony_ci pmec->dwBitrate = rk.getDWORD(VALUE_BITRATE,DEFAULT_BITRATE); 835159b3361Sopenharmony_ci pmec->dwVariableMin = rk.getDWORD(VALUE_VARIABLEMIN,DEFAULT_VARIABLEMIN); 836159b3361Sopenharmony_ci pmec->dwVariableMax = rk.getDWORD(VALUE_VARIABLEMAX,DEFAULT_VARIABLEMAX); 837159b3361Sopenharmony_ci pmec->vmVariable = rk.getDWORD(VALUE_VARIABLE, DEFAULT_VARIABLE) ? vbr_rh : vbr_off; 838159b3361Sopenharmony_ci pmec->dwQuality = rk.getDWORD(VALUE_QUALITY,DEFAULT_ENCODING_QUALITY); 839159b3361Sopenharmony_ci pmec->dwVBRq = rk.getDWORD(VALUE_VBR_QUALITY,DEFAULT_VBR_QUALITY); 840159b3361Sopenharmony_ci pmec->lLayer = rk.getDWORD(VALUE_LAYER, DEFAULT_LAYER); 841159b3361Sopenharmony_ci pmec->bCRCProtect = rk.getDWORD(VALUE_CRC, DEFAULT_CRC); 842159b3361Sopenharmony_ci pmec->bForceMono = rk.getDWORD(VALUE_FORCE_MONO, DEFAULT_FORCE_MONO); 843159b3361Sopenharmony_ci pmec->bSetDuration = rk.getDWORD(VALUE_SET_DURATION, DEFAULT_SET_DURATION); 844159b3361Sopenharmony_ci pmec->bSampleOverlap = rk.getDWORD(VALUE_SAMPLE_OVERLAP, DEFAULT_SAMPLE_OVERLAP); 845159b3361Sopenharmony_ci pmec->bCopyright = rk.getDWORD(VALUE_COPYRIGHT, DEFAULT_COPYRIGHT); 846159b3361Sopenharmony_ci pmec->bOriginal = rk.getDWORD(VALUE_ORIGINAL, DEFAULT_ORIGINAL); 847159b3361Sopenharmony_ci pmec->dwSampleRate = rk.getDWORD(VALUE_SAMPLE_RATE, DEFAULT_SAMPLE_RATE); 848159b3361Sopenharmony_ci pmec->dwPES = rk.getDWORD(VALUE_PES, DEFAULT_PES); 849159b3361Sopenharmony_ci 850159b3361Sopenharmony_ci pmec->ChMode = (MPEG_mode)rk.getDWORD(VALUE_STEREO_MODE, DEFAULT_STEREO_MODE); 851159b3361Sopenharmony_ci pmec->dwForceMS = rk.getDWORD(VALUE_FORCE_MS, DEFAULT_FORCE_MS); 852159b3361Sopenharmony_ci 853159b3361Sopenharmony_ci pmec->dwEnforceVBRmin = rk.getDWORD(VALUE_ENFORCE_MIN, DEFAULT_ENFORCE_MIN); 854159b3361Sopenharmony_ci pmec->dwVoiceMode = rk.getDWORD(VALUE_VOICE, DEFAULT_VOICE); 855159b3361Sopenharmony_ci pmec->dwKeepAllFreq = rk.getDWORD(VALUE_KEEP_ALL_FREQ, DEFAULT_KEEP_ALL_FREQ); 856159b3361Sopenharmony_ci pmec->dwStrictISO = rk.getDWORD(VALUE_STRICT_ISO, DEFAULT_STRICT_ISO); 857159b3361Sopenharmony_ci pmec->dwNoShortBlock = rk.getDWORD(VALUE_DISABLE_SHORT_BLOCK, DEFAULT_DISABLE_SHORT_BLOCK); 858159b3361Sopenharmony_ci pmec->dwXingTag = rk.getDWORD(VALUE_XING_TAG, DEFAULT_XING_TAG); 859159b3361Sopenharmony_ci pmec->dwModeFixed = rk.getDWORD(VALUE_MODE_FIXED, DEFAULT_MODE_FIXED); 860159b3361Sopenharmony_ci 861159b3361Sopenharmony_ci rk.Close(); 862159b3361Sopenharmony_ci} 863159b3361Sopenharmony_ci 864159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////// 865159b3361Sopenharmony_ci// Property page handling 866159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////// 867159b3361Sopenharmony_ciHRESULT CMpegAudEnc::GetPages(CAUUID *pcauuid) 868159b3361Sopenharmony_ci{ 869159b3361Sopenharmony_ci GUID *pguid; 870159b3361Sopenharmony_ci 871159b3361Sopenharmony_ci pcauuid->cElems = 3; 872159b3361Sopenharmony_ci pcauuid->pElems = pguid = (GUID *) CoTaskMemAlloc(sizeof(GUID) * pcauuid->cElems); 873159b3361Sopenharmony_ci 874159b3361Sopenharmony_ci if (pcauuid->pElems == NULL) 875159b3361Sopenharmony_ci return E_OUTOFMEMORY; 876159b3361Sopenharmony_ci 877159b3361Sopenharmony_ci pguid[0] = CLSID_LAMEDShow_PropertyPage; 878159b3361Sopenharmony_ci pguid[1] = CLSID_LAMEDShow_PropertyPageAdv; 879159b3361Sopenharmony_ci pguid[2] = CLSID_LAMEDShow_About; 880159b3361Sopenharmony_ci 881159b3361Sopenharmony_ci return S_OK; 882159b3361Sopenharmony_ci} 883159b3361Sopenharmony_ci 884159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::NonDelegatingQueryInterface(REFIID riid, void ** ppv) 885159b3361Sopenharmony_ci{ 886159b3361Sopenharmony_ci 887159b3361Sopenharmony_ci if (riid == IID_ISpecifyPropertyPages) 888159b3361Sopenharmony_ci return GetInterface((ISpecifyPropertyPages *) this, ppv); 889159b3361Sopenharmony_ci else if(riid == IID_IPersistStream) 890159b3361Sopenharmony_ci return GetInterface((IPersistStream *)this, ppv); 891159b3361Sopenharmony_ci// else if (riid == IID_IVAudioEncSettings) 892159b3361Sopenharmony_ci// return GetInterface((IVAudioEncSettings*) this, ppv); 893159b3361Sopenharmony_ci else if (riid == IID_IAudioEncoderProperties) 894159b3361Sopenharmony_ci return GetInterface((IAudioEncoderProperties*) this, ppv); 895159b3361Sopenharmony_ci 896159b3361Sopenharmony_ci return CTransformFilter::NonDelegatingQueryInterface(riid, ppv); 897159b3361Sopenharmony_ci} 898159b3361Sopenharmony_ci 899159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////// 900159b3361Sopenharmony_ci//IVAudioEncSettings interface methods 901159b3361Sopenharmony_ci//////////////////////////////////////////////////////////////// 902159b3361Sopenharmony_ci 903159b3361Sopenharmony_ci// 904159b3361Sopenharmony_ci// IAudioEncoderProperties 905159b3361Sopenharmony_ci// 906159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_PESOutputEnabled(DWORD *dwEnabled) 907159b3361Sopenharmony_ci{ 908159b3361Sopenharmony_ci *dwEnabled = (DWORD)m_Encoder.IsPES(); 909159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_PESOutputEnabled -> %d"), *dwEnabled)); 910159b3361Sopenharmony_ci 911159b3361Sopenharmony_ci return S_OK; 912159b3361Sopenharmony_ci} 913159b3361Sopenharmony_ci 914159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_PESOutputEnabled(DWORD dwEnabled) 915159b3361Sopenharmony_ci{ 916159b3361Sopenharmony_ci m_Encoder.SetPES((BOOL)!!dwEnabled); 917159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_PESOutputEnabled(%d)"), !!dwEnabled)); 918159b3361Sopenharmony_ci 919159b3361Sopenharmony_ci return S_OK; 920159b3361Sopenharmony_ci} 921159b3361Sopenharmony_ci 922159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_MPEGLayer(DWORD *dwLayer) 923159b3361Sopenharmony_ci{ 924159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 925159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 926159b3361Sopenharmony_ci *dwLayer = (DWORD)mec.lLayer; 927159b3361Sopenharmony_ci 928159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_MPEGLayer -> %d"), *dwLayer)); 929159b3361Sopenharmony_ci return S_OK; 930159b3361Sopenharmony_ci} 931159b3361Sopenharmony_ci 932159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_MPEGLayer(DWORD dwLayer) 933159b3361Sopenharmony_ci{ 934159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 935159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 936159b3361Sopenharmony_ci if (dwLayer == 2) 937159b3361Sopenharmony_ci mec.lLayer = 2; 938159b3361Sopenharmony_ci else if (dwLayer == 1) 939159b3361Sopenharmony_ci mec.lLayer = 1; 940159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 941159b3361Sopenharmony_ci 942159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_MPEGLayer(%d)"), dwLayer)); 943159b3361Sopenharmony_ci return S_OK; 944159b3361Sopenharmony_ci} 945159b3361Sopenharmony_ci 946159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_Bitrate(DWORD *dwBitrate) 947159b3361Sopenharmony_ci{ 948159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 949159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 950159b3361Sopenharmony_ci *dwBitrate = (DWORD)mec.dwBitrate; 951159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_Bitrate -> %d"), *dwBitrate)); 952159b3361Sopenharmony_ci return S_OK; 953159b3361Sopenharmony_ci} 954159b3361Sopenharmony_ci 955159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_Bitrate(DWORD dwBitrate) 956159b3361Sopenharmony_ci{ 957159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 958159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 959159b3361Sopenharmony_ci mec.dwBitrate = dwBitrate; 960159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 961159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_Bitrate(%d)"), dwBitrate)); 962159b3361Sopenharmony_ci return S_OK; 963159b3361Sopenharmony_ci} 964159b3361Sopenharmony_ci 965159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_Variable(DWORD *dwVariable) 966159b3361Sopenharmony_ci{ 967159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 968159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 969159b3361Sopenharmony_ci *dwVariable = (DWORD)(mec.vmVariable == vbr_off ? 0 : 1); 970159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_Variable -> %d"), *dwVariable)); 971159b3361Sopenharmony_ci return S_OK; 972159b3361Sopenharmony_ci} 973159b3361Sopenharmony_ci 974159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_Variable(DWORD dwVariable) 975159b3361Sopenharmony_ci{ 976159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 977159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 978159b3361Sopenharmony_ci 979159b3361Sopenharmony_ci mec.vmVariable = dwVariable ? vbr_rh : vbr_off; 980159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 981159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_Variable(%d)"), dwVariable)); 982159b3361Sopenharmony_ci return S_OK; 983159b3361Sopenharmony_ci} 984159b3361Sopenharmony_ci 985159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_VariableMin(DWORD *dwMin) 986159b3361Sopenharmony_ci{ 987159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 988159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 989159b3361Sopenharmony_ci *dwMin = (DWORD)mec.dwVariableMin; 990159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_Variablemin -> %d"), *dwMin)); 991159b3361Sopenharmony_ci return S_OK; 992159b3361Sopenharmony_ci} 993159b3361Sopenharmony_ci 994159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_VariableMin(DWORD dwMin) 995159b3361Sopenharmony_ci{ 996159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 997159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 998159b3361Sopenharmony_ci mec.dwVariableMin = dwMin; 999159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1000159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_Variablemin(%d)"), dwMin)); 1001159b3361Sopenharmony_ci return S_OK; 1002159b3361Sopenharmony_ci} 1003159b3361Sopenharmony_ci 1004159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_VariableMax(DWORD *dwMax) 1005159b3361Sopenharmony_ci{ 1006159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1007159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1008159b3361Sopenharmony_ci *dwMax = (DWORD)mec.dwVariableMax; 1009159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_Variablemax -> %d"), *dwMax)); 1010159b3361Sopenharmony_ci return S_OK; 1011159b3361Sopenharmony_ci} 1012159b3361Sopenharmony_ci 1013159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_VariableMax(DWORD dwMax) 1014159b3361Sopenharmony_ci{ 1015159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1016159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1017159b3361Sopenharmony_ci mec.dwVariableMax = dwMax; 1018159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1019159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_Variablemax(%d)"), dwMax)); 1020159b3361Sopenharmony_ci return S_OK; 1021159b3361Sopenharmony_ci} 1022159b3361Sopenharmony_ci 1023159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_Quality(DWORD *dwQuality) 1024159b3361Sopenharmony_ci{ 1025159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1026159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1027159b3361Sopenharmony_ci *dwQuality=(DWORD)mec.dwQuality; 1028159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_Quality -> %d"), *dwQuality)); 1029159b3361Sopenharmony_ci return S_OK; 1030159b3361Sopenharmony_ci} 1031159b3361Sopenharmony_ci 1032159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_Quality(DWORD dwQuality) 1033159b3361Sopenharmony_ci{ 1034159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1035159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1036159b3361Sopenharmony_ci mec.dwQuality = dwQuality; 1037159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1038159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_Quality(%d)"), dwQuality)); 1039159b3361Sopenharmony_ci return S_OK; 1040159b3361Sopenharmony_ci} 1041159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_VariableQ(DWORD *dwVBRq) 1042159b3361Sopenharmony_ci{ 1043159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1044159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1045159b3361Sopenharmony_ci *dwVBRq=(DWORD)mec.dwVBRq; 1046159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_VariableQ -> %d"), *dwVBRq)); 1047159b3361Sopenharmony_ci return S_OK; 1048159b3361Sopenharmony_ci} 1049159b3361Sopenharmony_ci 1050159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_VariableQ(DWORD dwVBRq) 1051159b3361Sopenharmony_ci{ 1052159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1053159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1054159b3361Sopenharmony_ci mec.dwVBRq = dwVBRq; 1055159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1056159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_VariableQ(%d)"), dwVBRq)); 1057159b3361Sopenharmony_ci return S_OK; 1058159b3361Sopenharmony_ci} 1059159b3361Sopenharmony_ci 1060159b3361Sopenharmony_ci 1061159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_SourceSampleRate(DWORD *dwSampleRate) 1062159b3361Sopenharmony_ci{ 1063159b3361Sopenharmony_ci *dwSampleRate = 0; 1064159b3361Sopenharmony_ci 1065159b3361Sopenharmony_ci WAVEFORMATEX wf; 1066159b3361Sopenharmony_ci if(FAILED(m_Encoder.GetInputType(&wf))) 1067159b3361Sopenharmony_ci return E_FAIL; 1068159b3361Sopenharmony_ci 1069159b3361Sopenharmony_ci *dwSampleRate = wf.nSamplesPerSec; 1070159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_SourceSampleRate -> %d"), *dwSampleRate)); 1071159b3361Sopenharmony_ci return S_OK; 1072159b3361Sopenharmony_ci} 1073159b3361Sopenharmony_ci 1074159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_SourceChannels(DWORD *dwChannels) 1075159b3361Sopenharmony_ci{ 1076159b3361Sopenharmony_ci WAVEFORMATEX wf; 1077159b3361Sopenharmony_ci if(FAILED(m_Encoder.GetInputType(&wf))) 1078159b3361Sopenharmony_ci return E_FAIL; 1079159b3361Sopenharmony_ci 1080159b3361Sopenharmony_ci *dwChannels = wf.nChannels; 1081159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_SourceChannels -> %d"), *dwChannels)); 1082159b3361Sopenharmony_ci return S_OK; 1083159b3361Sopenharmony_ci} 1084159b3361Sopenharmony_ci 1085159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_SampleRate(DWORD *dwSampleRate) 1086159b3361Sopenharmony_ci{ 1087159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1088159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1089159b3361Sopenharmony_ci *dwSampleRate = mec.dwSampleRate; 1090159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_SampleRate -> %d"), *dwSampleRate)); 1091159b3361Sopenharmony_ci return S_OK; 1092159b3361Sopenharmony_ci} 1093159b3361Sopenharmony_ci 1094159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_SampleRate(DWORD dwSampleRate) 1095159b3361Sopenharmony_ci{ 1096159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1097159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1098159b3361Sopenharmony_ci DWORD dwOldSampleRate = mec.dwSampleRate; 1099159b3361Sopenharmony_ci mec.dwSampleRate = dwSampleRate; 1100159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1101159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_SampleRate(%d)"), dwSampleRate)); 1102159b3361Sopenharmony_ci 1103159b3361Sopenharmony_ci return S_OK; 1104159b3361Sopenharmony_ci} 1105159b3361Sopenharmony_ci 1106159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_ChannelMode(DWORD *dwChannelMode) 1107159b3361Sopenharmony_ci{ 1108159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1109159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1110159b3361Sopenharmony_ci *dwChannelMode = mec.ChMode; 1111159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_ChannelMode -> %d"), *dwChannelMode)); 1112159b3361Sopenharmony_ci return S_OK; 1113159b3361Sopenharmony_ci} 1114159b3361Sopenharmony_ci 1115159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_ChannelMode(DWORD dwChannelMode) 1116159b3361Sopenharmony_ci{ 1117159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1118159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1119159b3361Sopenharmony_ci mec.ChMode = (MPEG_mode)dwChannelMode; 1120159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1121159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_ChannelMode(%d)"), dwChannelMode)); 1122159b3361Sopenharmony_ci return S_OK; 1123159b3361Sopenharmony_ci} 1124159b3361Sopenharmony_ci 1125159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_ForceMS(DWORD *dwFlag) 1126159b3361Sopenharmony_ci{ 1127159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1128159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1129159b3361Sopenharmony_ci *dwFlag = mec.dwForceMS; 1130159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_ForceMS -> %d"), *dwFlag)); 1131159b3361Sopenharmony_ci return S_OK; 1132159b3361Sopenharmony_ci} 1133159b3361Sopenharmony_ci 1134159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_ForceMS(DWORD dwFlag) 1135159b3361Sopenharmony_ci{ 1136159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1137159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1138159b3361Sopenharmony_ci mec.dwForceMS = dwFlag; 1139159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1140159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_ForceMS(%d)"), dwFlag)); 1141159b3361Sopenharmony_ci return S_OK; 1142159b3361Sopenharmony_ci} 1143159b3361Sopenharmony_ci 1144159b3361Sopenharmony_ci 1145159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_CRCFlag(DWORD *dwFlag) 1146159b3361Sopenharmony_ci{ 1147159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1148159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1149159b3361Sopenharmony_ci *dwFlag = mec.bCRCProtect; 1150159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_CRCFlag -> %d"), *dwFlag)); 1151159b3361Sopenharmony_ci return S_OK; 1152159b3361Sopenharmony_ci} 1153159b3361Sopenharmony_ci 1154159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_ForceMono(DWORD *dwFlag) 1155159b3361Sopenharmony_ci{ 1156159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1157159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1158159b3361Sopenharmony_ci *dwFlag = mec.bForceMono; 1159159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_ForceMono -> %d"), *dwFlag)); 1160159b3361Sopenharmony_ci return S_OK; 1161159b3361Sopenharmony_ci} 1162159b3361Sopenharmony_ci 1163159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_SetDuration(DWORD *dwFlag) 1164159b3361Sopenharmony_ci{ 1165159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1166159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1167159b3361Sopenharmony_ci *dwFlag = mec.bSetDuration; 1168159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_SetDuration -> %d"), *dwFlag)); 1169159b3361Sopenharmony_ci return S_OK; 1170159b3361Sopenharmony_ci} 1171159b3361Sopenharmony_ci 1172159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_SampleOverlap(DWORD *dwFlag) 1173159b3361Sopenharmony_ci{ 1174159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1175159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1176159b3361Sopenharmony_ci *dwFlag = mec.bSampleOverlap; 1177159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_SampleOverlap -> %d"), *dwFlag)); 1178159b3361Sopenharmony_ci return S_OK; 1179159b3361Sopenharmony_ci} 1180159b3361Sopenharmony_ci 1181159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_CRCFlag(DWORD dwFlag) 1182159b3361Sopenharmony_ci{ 1183159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1184159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1185159b3361Sopenharmony_ci mec.bCRCProtect = dwFlag; 1186159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1187159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_CRCFlag(%d)"), dwFlag)); 1188159b3361Sopenharmony_ci return S_OK; 1189159b3361Sopenharmony_ci} 1190159b3361Sopenharmony_ci 1191159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_ForceMono(DWORD dwFlag) 1192159b3361Sopenharmony_ci{ 1193159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1194159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1195159b3361Sopenharmony_ci mec.bForceMono = dwFlag; 1196159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1197159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_ForceMono(%d)"), dwFlag)); 1198159b3361Sopenharmony_ci return S_OK; 1199159b3361Sopenharmony_ci} 1200159b3361Sopenharmony_ci 1201159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_SetDuration(DWORD dwFlag) 1202159b3361Sopenharmony_ci{ 1203159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1204159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1205159b3361Sopenharmony_ci mec.bSetDuration = dwFlag; 1206159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1207159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_SetDuration(%d)"), dwFlag)); 1208159b3361Sopenharmony_ci return S_OK; 1209159b3361Sopenharmony_ci} 1210159b3361Sopenharmony_ci 1211159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_SampleOverlap(DWORD dwFlag) 1212159b3361Sopenharmony_ci{ 1213159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1214159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1215159b3361Sopenharmony_ci mec.bSampleOverlap = dwFlag; 1216159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1217159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_SampleOverlap(%d)"), dwFlag)); 1218159b3361Sopenharmony_ci return S_OK; 1219159b3361Sopenharmony_ci} 1220159b3361Sopenharmony_ci 1221159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_EnforceVBRmin(DWORD *dwFlag) 1222159b3361Sopenharmony_ci{ 1223159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1224159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1225159b3361Sopenharmony_ci *dwFlag = mec.dwEnforceVBRmin; 1226159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_EnforceVBRmin -> %d"), *dwFlag)); 1227159b3361Sopenharmony_ci return S_OK; 1228159b3361Sopenharmony_ci} 1229159b3361Sopenharmony_ci 1230159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_EnforceVBRmin(DWORD dwFlag) 1231159b3361Sopenharmony_ci{ 1232159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1233159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1234159b3361Sopenharmony_ci mec.dwEnforceVBRmin = dwFlag; 1235159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1236159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_EnforceVBRmin(%d)"), dwFlag)); 1237159b3361Sopenharmony_ci return S_OK; 1238159b3361Sopenharmony_ci} 1239159b3361Sopenharmony_ci 1240159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_VoiceMode(DWORD *dwFlag) 1241159b3361Sopenharmony_ci{ 1242159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1243159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1244159b3361Sopenharmony_ci *dwFlag = mec.dwVoiceMode; 1245159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_VoiceMode -> %d"), *dwFlag)); 1246159b3361Sopenharmony_ci return S_OK; 1247159b3361Sopenharmony_ci} 1248159b3361Sopenharmony_ci 1249159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_VoiceMode(DWORD dwFlag) 1250159b3361Sopenharmony_ci{ 1251159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1252159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1253159b3361Sopenharmony_ci mec.dwVoiceMode = dwFlag; 1254159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1255159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_VoiceMode(%d)"), dwFlag)); 1256159b3361Sopenharmony_ci return S_OK; 1257159b3361Sopenharmony_ci} 1258159b3361Sopenharmony_ci 1259159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_KeepAllFreq(DWORD *dwFlag) 1260159b3361Sopenharmony_ci{ 1261159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1262159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1263159b3361Sopenharmony_ci *dwFlag = mec.dwKeepAllFreq; 1264159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_KeepAllFreq -> %d"), *dwFlag)); 1265159b3361Sopenharmony_ci return S_OK; 1266159b3361Sopenharmony_ci} 1267159b3361Sopenharmony_ci 1268159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_KeepAllFreq(DWORD dwFlag) 1269159b3361Sopenharmony_ci{ 1270159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1271159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1272159b3361Sopenharmony_ci mec.dwKeepAllFreq = dwFlag; 1273159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1274159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_KeepAllFreq(%d)"), dwFlag)); 1275159b3361Sopenharmony_ci return S_OK; 1276159b3361Sopenharmony_ci} 1277159b3361Sopenharmony_ci 1278159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_StrictISO(DWORD *dwFlag) 1279159b3361Sopenharmony_ci{ 1280159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1281159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1282159b3361Sopenharmony_ci *dwFlag = mec.dwStrictISO; 1283159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_StrictISO -> %d"), *dwFlag)); 1284159b3361Sopenharmony_ci return S_OK; 1285159b3361Sopenharmony_ci} 1286159b3361Sopenharmony_ci 1287159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_StrictISO(DWORD dwFlag) 1288159b3361Sopenharmony_ci{ 1289159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1290159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1291159b3361Sopenharmony_ci mec.dwStrictISO = dwFlag; 1292159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1293159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_StrictISO(%d)"), dwFlag)); 1294159b3361Sopenharmony_ci return S_OK; 1295159b3361Sopenharmony_ci} 1296159b3361Sopenharmony_ci 1297159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_NoShortBlock(DWORD *dwNoShortBlock) 1298159b3361Sopenharmony_ci{ 1299159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1300159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1301159b3361Sopenharmony_ci *dwNoShortBlock = mec.dwNoShortBlock; 1302159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_NoShortBlock -> %d"), *dwNoShortBlock)); 1303159b3361Sopenharmony_ci return S_OK; 1304159b3361Sopenharmony_ci} 1305159b3361Sopenharmony_ci 1306159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_NoShortBlock(DWORD dwNoShortBlock) 1307159b3361Sopenharmony_ci{ 1308159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1309159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1310159b3361Sopenharmony_ci mec.dwNoShortBlock = dwNoShortBlock; 1311159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1312159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_NoShortBlock(%d)"), dwNoShortBlock)); 1313159b3361Sopenharmony_ci return S_OK; 1314159b3361Sopenharmony_ci} 1315159b3361Sopenharmony_ci 1316159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_XingTag(DWORD *dwXingTag) 1317159b3361Sopenharmony_ci{ 1318159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1319159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1320159b3361Sopenharmony_ci *dwXingTag = mec.dwXingTag; 1321159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_XingTag -> %d"), *dwXingTag)); 1322159b3361Sopenharmony_ci return S_OK; 1323159b3361Sopenharmony_ci} 1324159b3361Sopenharmony_ci 1325159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_XingTag(DWORD dwXingTag) 1326159b3361Sopenharmony_ci{ 1327159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1328159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1329159b3361Sopenharmony_ci mec.dwXingTag = dwXingTag; 1330159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1331159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_XingTag(%d)"), dwXingTag)); 1332159b3361Sopenharmony_ci return S_OK; 1333159b3361Sopenharmony_ci} 1334159b3361Sopenharmony_ci 1335159b3361Sopenharmony_ci 1336159b3361Sopenharmony_ci 1337159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_OriginalFlag(DWORD *dwFlag) 1338159b3361Sopenharmony_ci{ 1339159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1340159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1341159b3361Sopenharmony_ci *dwFlag = mec.bOriginal; 1342159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_OriginalFlag -> %d"), *dwFlag)); 1343159b3361Sopenharmony_ci return S_OK; 1344159b3361Sopenharmony_ci} 1345159b3361Sopenharmony_ci 1346159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_OriginalFlag(DWORD dwFlag) 1347159b3361Sopenharmony_ci{ 1348159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1349159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1350159b3361Sopenharmony_ci mec.bOriginal = dwFlag; 1351159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1352159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_OriginalFlag(%d)"), dwFlag)); 1353159b3361Sopenharmony_ci return S_OK; 1354159b3361Sopenharmony_ci} 1355159b3361Sopenharmony_ci 1356159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_CopyrightFlag(DWORD *dwFlag) 1357159b3361Sopenharmony_ci{ 1358159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1359159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1360159b3361Sopenharmony_ci *dwFlag = mec.bCopyright; 1361159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_CopyrightFlag -> %d"), *dwFlag)); 1362159b3361Sopenharmony_ci return S_OK; 1363159b3361Sopenharmony_ci} 1364159b3361Sopenharmony_ci 1365159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_CopyrightFlag(DWORD dwFlag) 1366159b3361Sopenharmony_ci{ 1367159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1368159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1369159b3361Sopenharmony_ci mec.bCopyright = dwFlag; 1370159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1371159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_CopyrightFlag(%d)"), dwFlag)); 1372159b3361Sopenharmony_ci return S_OK; 1373159b3361Sopenharmony_ci} 1374159b3361Sopenharmony_ci 1375159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_ModeFixed(DWORD *dwModeFixed) 1376159b3361Sopenharmony_ci{ 1377159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1378159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1379159b3361Sopenharmony_ci *dwModeFixed = mec.dwModeFixed; 1380159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_ModeFixed -> %d"), *dwModeFixed)); 1381159b3361Sopenharmony_ci return S_OK; 1382159b3361Sopenharmony_ci} 1383159b3361Sopenharmony_ci 1384159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_ModeFixed(DWORD dwModeFixed) 1385159b3361Sopenharmony_ci{ 1386159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1387159b3361Sopenharmony_ci m_Encoder.GetOutputType(&mec); 1388159b3361Sopenharmony_ci mec.dwModeFixed = dwModeFixed; 1389159b3361Sopenharmony_ci m_Encoder.SetOutputType(mec); 1390159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("set_ModeFixed(%d)"), dwModeFixed)); 1391159b3361Sopenharmony_ci return S_OK; 1392159b3361Sopenharmony_ci} 1393159b3361Sopenharmony_ci 1394159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::get_ParameterBlockSize(BYTE *pcBlock, DWORD *pdwSize) 1395159b3361Sopenharmony_ci{ 1396159b3361Sopenharmony_ci if (pcBlock != NULL && pdwSize != NULL) { 1397159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_ParameterBlockSize -> %d%d"), *pcBlock, *pdwSize)); 1398159b3361Sopenharmony_ci if (*pdwSize >= sizeof(MPEG_ENCODER_CONFIG)) { 1399159b3361Sopenharmony_ci m_Encoder.GetOutputType((MPEG_ENCODER_CONFIG*)pcBlock); 1400159b3361Sopenharmony_ci return S_OK; 1401159b3361Sopenharmony_ci } 1402159b3361Sopenharmony_ci else { 1403159b3361Sopenharmony_ci *pdwSize = sizeof(MPEG_ENCODER_CONFIG); 1404159b3361Sopenharmony_ci return E_FAIL; 1405159b3361Sopenharmony_ci } 1406159b3361Sopenharmony_ci } 1407159b3361Sopenharmony_ci else if (pdwSize != NULL) { 1408159b3361Sopenharmony_ci *pdwSize = sizeof(MPEG_ENCODER_CONFIG); 1409159b3361Sopenharmony_ci return S_OK; 1410159b3361Sopenharmony_ci } 1411159b3361Sopenharmony_ci 1412159b3361Sopenharmony_ci return E_FAIL; 1413159b3361Sopenharmony_ci} 1414159b3361Sopenharmony_ci 1415159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::set_ParameterBlockSize(BYTE *pcBlock, DWORD dwSize) 1416159b3361Sopenharmony_ci{ 1417159b3361Sopenharmony_ci if (pcBlock != NULL) { 1418159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("get_ParameterBlockSize(%d, %d)"), *pcBlock, dwSize)); 1419159b3361Sopenharmony_ci if (sizeof(MPEG_ENCODER_CONFIG) == dwSize){ 1420159b3361Sopenharmony_ci m_Encoder.SetOutputType(*(MPEG_ENCODER_CONFIG*)pcBlock); 1421159b3361Sopenharmony_ci return S_OK; 1422159b3361Sopenharmony_ci } 1423159b3361Sopenharmony_ci } 1424159b3361Sopenharmony_ci return E_FAIL; 1425159b3361Sopenharmony_ci} 1426159b3361Sopenharmony_ci 1427159b3361Sopenharmony_ci 1428159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::DefaultAudioEncoderProperties() 1429159b3361Sopenharmony_ci{ 1430159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("DefaultAudioEncoderProperties()"))); 1431159b3361Sopenharmony_ci 1432159b3361Sopenharmony_ci HRESULT hr = InputTypeDefined(); 1433159b3361Sopenharmony_ci if (FAILED(hr)) 1434159b3361Sopenharmony_ci return hr; 1435159b3361Sopenharmony_ci 1436159b3361Sopenharmony_ci DWORD dwSourceSampleRate; 1437159b3361Sopenharmony_ci get_SourceSampleRate(&dwSourceSampleRate); 1438159b3361Sopenharmony_ci 1439159b3361Sopenharmony_ci set_PESOutputEnabled(DEFAULT_PES); 1440159b3361Sopenharmony_ci set_MPEGLayer(DEFAULT_LAYER); 1441159b3361Sopenharmony_ci 1442159b3361Sopenharmony_ci set_Bitrate(DEFAULT_BITRATE); 1443159b3361Sopenharmony_ci set_Variable(FALSE); 1444159b3361Sopenharmony_ci set_VariableMin(DEFAULT_VARIABLEMIN); 1445159b3361Sopenharmony_ci set_VariableMax(DEFAULT_VARIABLEMAX); 1446159b3361Sopenharmony_ci set_Quality(DEFAULT_ENCODING_QUALITY); 1447159b3361Sopenharmony_ci set_VariableQ(DEFAULT_VBR_QUALITY); 1448159b3361Sopenharmony_ci 1449159b3361Sopenharmony_ci set_SampleRate(dwSourceSampleRate); 1450159b3361Sopenharmony_ci set_CRCFlag(DEFAULT_CRC); 1451159b3361Sopenharmony_ci set_ForceMono(DEFAULT_FORCE_MONO); 1452159b3361Sopenharmony_ci set_SetDuration(DEFAULT_SET_DURATION); 1453159b3361Sopenharmony_ci set_SampleOverlap(DEFAULT_SAMPLE_OVERLAP); 1454159b3361Sopenharmony_ci set_OriginalFlag(DEFAULT_ORIGINAL); 1455159b3361Sopenharmony_ci set_CopyrightFlag(DEFAULT_COPYRIGHT); 1456159b3361Sopenharmony_ci 1457159b3361Sopenharmony_ci set_EnforceVBRmin(DEFAULT_ENFORCE_MIN); 1458159b3361Sopenharmony_ci set_VoiceMode(DEFAULT_VOICE); 1459159b3361Sopenharmony_ci set_KeepAllFreq(DEFAULT_KEEP_ALL_FREQ); 1460159b3361Sopenharmony_ci set_StrictISO(DEFAULT_STRICT_ISO); 1461159b3361Sopenharmony_ci set_NoShortBlock(DEFAULT_DISABLE_SHORT_BLOCK); 1462159b3361Sopenharmony_ci set_XingTag(DEFAULT_XING_TAG); 1463159b3361Sopenharmony_ci set_ForceMS(DEFAULT_FORCE_MS); 1464159b3361Sopenharmony_ci set_ChannelMode(DEFAULT_STEREO_MODE); 1465159b3361Sopenharmony_ci set_ModeFixed(DEFAULT_MODE_FIXED); 1466159b3361Sopenharmony_ci 1467159b3361Sopenharmony_ci return S_OK; 1468159b3361Sopenharmony_ci} 1469159b3361Sopenharmony_ci 1470159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::LoadAudioEncoderPropertiesFromRegistry() 1471159b3361Sopenharmony_ci{ 1472159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("LoadAudioEncoderPropertiesFromRegistry()"))); 1473159b3361Sopenharmony_ci 1474159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1475159b3361Sopenharmony_ci ReadPresetSettings(&mec); 1476159b3361Sopenharmony_ci if(m_Encoder.SetOutputType(mec) == S_FALSE) 1477159b3361Sopenharmony_ci return S_FALSE; 1478159b3361Sopenharmony_ci return S_OK; 1479159b3361Sopenharmony_ci} 1480159b3361Sopenharmony_ci 1481159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::SaveAudioEncoderPropertiesToRegistry() 1482159b3361Sopenharmony_ci{ 1483159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("SaveAudioEncoderPropertiesToRegistry()"))); 1484159b3361Sopenharmony_ci Lame::CRegKey rk; 1485159b3361Sopenharmony_ci 1486159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1487159b3361Sopenharmony_ci if(m_Encoder.GetOutputType(&mec) == S_FALSE) 1488159b3361Sopenharmony_ci return E_FAIL; 1489159b3361Sopenharmony_ci 1490159b3361Sopenharmony_ci if(rk.Create(HKEY_CURRENT_USER, KEY_LAME_ENCODER)) 1491159b3361Sopenharmony_ci { 1492159b3361Sopenharmony_ci rk.setDWORD(VALUE_BITRATE, mec.dwBitrate); 1493159b3361Sopenharmony_ci rk.setDWORD(VALUE_VARIABLE, mec.vmVariable); 1494159b3361Sopenharmony_ci rk.setDWORD(VALUE_VARIABLEMIN, mec.dwVariableMin); 1495159b3361Sopenharmony_ci rk.setDWORD(VALUE_VARIABLEMAX, mec.dwVariableMax); 1496159b3361Sopenharmony_ci rk.setDWORD(VALUE_QUALITY, mec.dwQuality); 1497159b3361Sopenharmony_ci rk.setDWORD(VALUE_VBR_QUALITY, mec.dwVBRq); 1498159b3361Sopenharmony_ci 1499159b3361Sopenharmony_ci rk.setDWORD(VALUE_CRC, mec.bCRCProtect); 1500159b3361Sopenharmony_ci rk.setDWORD(VALUE_FORCE_MONO, mec.bForceMono); 1501159b3361Sopenharmony_ci rk.setDWORD(VALUE_SET_DURATION, mec.bSetDuration); 1502159b3361Sopenharmony_ci rk.setDWORD(VALUE_SAMPLE_OVERLAP, mec.bSampleOverlap); 1503159b3361Sopenharmony_ci rk.setDWORD(VALUE_PES, mec.dwPES); 1504159b3361Sopenharmony_ci rk.setDWORD(VALUE_COPYRIGHT, mec.bCopyright); 1505159b3361Sopenharmony_ci rk.setDWORD(VALUE_ORIGINAL, mec.bOriginal); 1506159b3361Sopenharmony_ci rk.setDWORD(VALUE_SAMPLE_RATE, mec.dwSampleRate); 1507159b3361Sopenharmony_ci 1508159b3361Sopenharmony_ci rk.setDWORD(VALUE_STEREO_MODE, mec.ChMode); 1509159b3361Sopenharmony_ci rk.setDWORD(VALUE_FORCE_MS, mec.dwForceMS); 1510159b3361Sopenharmony_ci rk.setDWORD(VALUE_XING_TAG, mec.dwXingTag); 1511159b3361Sopenharmony_ci rk.setDWORD(VALUE_DISABLE_SHORT_BLOCK, mec.dwNoShortBlock); 1512159b3361Sopenharmony_ci rk.setDWORD(VALUE_STRICT_ISO, mec.dwStrictISO); 1513159b3361Sopenharmony_ci rk.setDWORD(VALUE_KEEP_ALL_FREQ, mec.dwKeepAllFreq); 1514159b3361Sopenharmony_ci rk.setDWORD(VALUE_VOICE, mec.dwVoiceMode); 1515159b3361Sopenharmony_ci rk.setDWORD(VALUE_ENFORCE_MIN, mec.dwEnforceVBRmin); 1516159b3361Sopenharmony_ci rk.setDWORD(VALUE_MODE_FIXED, mec.dwModeFixed); 1517159b3361Sopenharmony_ci 1518159b3361Sopenharmony_ci rk.Close(); 1519159b3361Sopenharmony_ci } 1520159b3361Sopenharmony_ci 1521159b3361Sopenharmony_ci // Reconnect filter graph 1522159b3361Sopenharmony_ci Reconnect(); 1523159b3361Sopenharmony_ci 1524159b3361Sopenharmony_ci return S_OK; 1525159b3361Sopenharmony_ci} 1526159b3361Sopenharmony_ci 1527159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::InputTypeDefined() 1528159b3361Sopenharmony_ci{ 1529159b3361Sopenharmony_ci WAVEFORMATEX wf; 1530159b3361Sopenharmony_ci if(FAILED(m_Encoder.GetInputType(&wf))) 1531159b3361Sopenharmony_ci { 1532159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("!InputTypeDefined()"))); 1533159b3361Sopenharmony_ci return E_FAIL; 1534159b3361Sopenharmony_ci } 1535159b3361Sopenharmony_ci 1536159b3361Sopenharmony_ci DbgLog((LOG_TRACE, 1, TEXT("InputTypeDefined()"))); 1537159b3361Sopenharmony_ci return S_OK; 1538159b3361Sopenharmony_ci} 1539159b3361Sopenharmony_ci 1540159b3361Sopenharmony_ci 1541159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::ApplyChanges() 1542159b3361Sopenharmony_ci{ 1543159b3361Sopenharmony_ci return Reconnect(); 1544159b3361Sopenharmony_ci} 1545159b3361Sopenharmony_ci 1546159b3361Sopenharmony_ci// 1547159b3361Sopenharmony_ci// CPersistStream stuff 1548159b3361Sopenharmony_ci// 1549159b3361Sopenharmony_ci 1550159b3361Sopenharmony_ci// what is our class ID? 1551159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEnc::GetClassID(CLSID *pClsid) 1552159b3361Sopenharmony_ci{ 1553159b3361Sopenharmony_ci CheckPointer(pClsid, E_POINTER); 1554159b3361Sopenharmony_ci *pClsid = CLSID_LAMEDShowFilter; 1555159b3361Sopenharmony_ci return S_OK; 1556159b3361Sopenharmony_ci} 1557159b3361Sopenharmony_ci 1558159b3361Sopenharmony_ciHRESULT CMpegAudEnc::WriteToStream(IStream *pStream) 1559159b3361Sopenharmony_ci{ 1560159b3361Sopenharmony_ci DbgLog((LOG_TRACE,1,TEXT("WriteToStream()"))); 1561159b3361Sopenharmony_ci 1562159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1563159b3361Sopenharmony_ci 1564159b3361Sopenharmony_ci if(m_Encoder.GetOutputType(&mec) == S_FALSE) 1565159b3361Sopenharmony_ci return E_FAIL; 1566159b3361Sopenharmony_ci 1567159b3361Sopenharmony_ci return pStream->Write(&mec, sizeof(mec), 0); 1568159b3361Sopenharmony_ci} 1569159b3361Sopenharmony_ci 1570159b3361Sopenharmony_ci 1571159b3361Sopenharmony_ci// what device should we use? Used to re-create a .GRF file that we 1572159b3361Sopenharmony_ci// are in 1573159b3361Sopenharmony_ciHRESULT CMpegAudEnc::ReadFromStream(IStream *pStream) 1574159b3361Sopenharmony_ci{ 1575159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1576159b3361Sopenharmony_ci 1577159b3361Sopenharmony_ci HRESULT hr = pStream->Read(&mec, sizeof(mec), 0); 1578159b3361Sopenharmony_ci if(FAILED(hr)) 1579159b3361Sopenharmony_ci return hr; 1580159b3361Sopenharmony_ci 1581159b3361Sopenharmony_ci if(m_Encoder.SetOutputType(mec) == S_FALSE) 1582159b3361Sopenharmony_ci return S_FALSE; 1583159b3361Sopenharmony_ci 1584159b3361Sopenharmony_ci DbgLog((LOG_TRACE,1,TEXT("ReadFromStream() succeeded"))); 1585159b3361Sopenharmony_ci 1586159b3361Sopenharmony_ci hr = S_OK; 1587159b3361Sopenharmony_ci return hr; 1588159b3361Sopenharmony_ci} 1589159b3361Sopenharmony_ci 1590159b3361Sopenharmony_ci 1591159b3361Sopenharmony_ci// How long is our data? 1592159b3361Sopenharmony_ciint CMpegAudEnc::SizeMax() 1593159b3361Sopenharmony_ci{ 1594159b3361Sopenharmony_ci return sizeof(MPEG_ENCODER_CONFIG); 1595159b3361Sopenharmony_ci} 1596159b3361Sopenharmony_ci 1597159b3361Sopenharmony_ci 1598159b3361Sopenharmony_ci 1599159b3361Sopenharmony_ci 1600159b3361Sopenharmony_ci 1601159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////////// 1602159b3361Sopenharmony_ci// CMpegAudEncOutPin is the one and only output pin of CMpegAudEnc 1603159b3361Sopenharmony_ci// 1604159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////////// 1605159b3361Sopenharmony_ciCMpegAudEncOutPin::CMpegAudEncOutPin( CMpegAudEnc * pFilter, HRESULT * pHr ) : 1606159b3361Sopenharmony_ci CTransformOutputPin( NAME("LameEncoderOutputPin"), pFilter, pHr, L"Output\0" ), 1607159b3361Sopenharmony_ci m_pFilter(pFilter) 1608159b3361Sopenharmony_ci{ 1609159b3361Sopenharmony_ci m_SetFormat = FALSE; 1610159b3361Sopenharmony_ci} 1611159b3361Sopenharmony_ci 1612159b3361Sopenharmony_ciCMpegAudEncOutPin::~CMpegAudEncOutPin() 1613159b3361Sopenharmony_ci{ 1614159b3361Sopenharmony_ci} 1615159b3361Sopenharmony_ci 1616159b3361Sopenharmony_ciSTDMETHODIMP CMpegAudEncOutPin::NonDelegatingQueryInterface(REFIID riid, void **ppv) 1617159b3361Sopenharmony_ci{ 1618159b3361Sopenharmony_ci if(riid == IID_IAMStreamConfig) { 1619159b3361Sopenharmony_ci CheckPointer(ppv, E_POINTER); 1620159b3361Sopenharmony_ci return GetInterface((IAMStreamConfig*)(this), ppv); 1621159b3361Sopenharmony_ci } 1622159b3361Sopenharmony_ci return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv); 1623159b3361Sopenharmony_ci} 1624159b3361Sopenharmony_ci 1625159b3361Sopenharmony_ci 1626159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////////// 1627159b3361Sopenharmony_ci// This is called after the output format has been negotiated and 1628159b3361Sopenharmony_ci// will update the LAME encoder settings so that it matches the 1629159b3361Sopenharmony_ci// settings specified in the MediaType structure. 1630159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////////// 1631159b3361Sopenharmony_ciHRESULT CMpegAudEncOutPin::SetMediaType(const CMediaType *pmt) 1632159b3361Sopenharmony_ci{ 1633159b3361Sopenharmony_ci // Retrieve the current LAME encoder configuration 1634159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1635159b3361Sopenharmony_ci m_pFilter->m_Encoder.GetOutputType(&mec); 1636159b3361Sopenharmony_ci 1637159b3361Sopenharmony_ci // Annotate if we are using the MEDIATYPE_Stream output type 1638159b3361Sopenharmony_ci m_pFilter->m_bStreamOutput = (pmt->majortype == MEDIATYPE_Stream); 1639159b3361Sopenharmony_ci 1640159b3361Sopenharmony_ci if (pmt->majortype == MEDIATYPE_Stream) { 1641159b3361Sopenharmony_ci // Update the encoder configuration using the settings that were 1642159b3361Sopenharmony_ci // cached in the CMpegAudEncOutPin::GetMediaType() call 1643159b3361Sopenharmony_ci mec.dwSampleRate = m_CurrentOutputFormat.nSampleRate; 1644159b3361Sopenharmony_ci mec.dwBitrate = m_CurrentOutputFormat.nBitRate; 1645159b3361Sopenharmony_ci mec.ChMode = m_CurrentOutputFormat.ChMode; 1646159b3361Sopenharmony_ci } 1647159b3361Sopenharmony_ci else { 1648159b3361Sopenharmony_ci // Update the encoder configuration directly using the values 1649159b3361Sopenharmony_ci // passed via the CMediaType structure. 1650159b3361Sopenharmony_ci MPEGLAYER3WAVEFORMAT *pfmt = (MPEGLAYER3WAVEFORMAT*) pmt->Format(); 1651159b3361Sopenharmony_ci mec.dwSampleRate = pfmt->wfx.nSamplesPerSec; 1652159b3361Sopenharmony_ci mec.dwBitrate = pfmt->wfx.nAvgBytesPerSec * 8 / 1000; 1653159b3361Sopenharmony_ci 1654159b3361Sopenharmony_ci if (pfmt->wfx.nChannels == 1) { mec.ChMode = MONO; } 1655159b3361Sopenharmony_ci else if (pfmt->wfx.nChannels == 2 && mec.ChMode == MONO && !mec.bForceMono) { mec.ChMode = STEREO; } 1656159b3361Sopenharmony_ci } 1657159b3361Sopenharmony_ci m_pFilter->m_Encoder.SetOutputType(mec); 1658159b3361Sopenharmony_ci 1659159b3361Sopenharmony_ci // Now configure this MediaType on the output pin 1660159b3361Sopenharmony_ci HRESULT hr = CTransformOutputPin::SetMediaType(pmt); 1661159b3361Sopenharmony_ci return hr; 1662159b3361Sopenharmony_ci} 1663159b3361Sopenharmony_ci 1664159b3361Sopenharmony_ci 1665159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////////// 1666159b3361Sopenharmony_ci// Retrieve the various MediaTypes that match the advertised formats 1667159b3361Sopenharmony_ci// supported on the output pin and configure an AM_MEDIA_TYPE output 1668159b3361Sopenharmony_ci// structure that is based on the selected format. 1669159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////////// 1670159b3361Sopenharmony_ciHRESULT CMpegAudEncOutPin::GetMediaType(int iPosition, CMediaType *pmt) 1671159b3361Sopenharmony_ci{ 1672159b3361Sopenharmony_ci if (iPosition < 0) return E_INVALIDARG; 1673159b3361Sopenharmony_ci 1674159b3361Sopenharmony_ci // If iPosition equals zero then we always return the currently configured MediaType 1675159b3361Sopenharmony_ci if (iPosition == 0) { 1676159b3361Sopenharmony_ci *pmt = m_mt; 1677159b3361Sopenharmony_ci return S_OK; 1678159b3361Sopenharmony_ci } 1679159b3361Sopenharmony_ci 1680159b3361Sopenharmony_ci switch (iPosition) 1681159b3361Sopenharmony_ci { 1682159b3361Sopenharmony_ci case 1: 1683159b3361Sopenharmony_ci { 1684159b3361Sopenharmony_ci pmt->SetType(&MEDIATYPE_Audio); 1685159b3361Sopenharmony_ci pmt->SetSubtype(&MEDIASUBTYPE_MP3); 1686159b3361Sopenharmony_ci break; 1687159b3361Sopenharmony_ci } 1688159b3361Sopenharmony_ci case 2: 1689159b3361Sopenharmony_ci { 1690159b3361Sopenharmony_ci pmt->SetType(&MEDIATYPE_Stream); 1691159b3361Sopenharmony_ci pmt->SetSubtype(&MEDIASUBTYPE_MPEG1Audio); 1692159b3361Sopenharmony_ci pmt->SetFormatType(&GUID_NULL); 1693159b3361Sopenharmony_ci break; 1694159b3361Sopenharmony_ci } 1695159b3361Sopenharmony_ci case 3: 1696159b3361Sopenharmony_ci { // The last case that we evaluate is the MPEG2_PES format, but if the 1697159b3361Sopenharmony_ci // encoder isn't configured for it then just return VFW_S_NO_MORE_ITEMS 1698159b3361Sopenharmony_ci if ( !m_pFilter->m_Encoder.IsPES() ) { return VFW_S_NO_MORE_ITEMS; } 1699159b3361Sopenharmony_ci 1700159b3361Sopenharmony_ci pmt->SetType(&MEDIATYPE_MPEG2_PES); 1701159b3361Sopenharmony_ci pmt->SetSubtype(&MEDIASUBTYPE_MPEG2_AUDIO); 1702159b3361Sopenharmony_ci break; 1703159b3361Sopenharmony_ci } 1704159b3361Sopenharmony_ci default: 1705159b3361Sopenharmony_ci return VFW_S_NO_MORE_ITEMS; 1706159b3361Sopenharmony_ci } 1707159b3361Sopenharmony_ci 1708159b3361Sopenharmony_ci 1709159b3361Sopenharmony_ci // Output capabilities are dependent on the input so insure it is connected 1710159b3361Sopenharmony_ci if ( !m_pFilter->m_pInput->IsConnected() ) { 1711159b3361Sopenharmony_ci pmt->SetFormatType(&FORMAT_None); 1712159b3361Sopenharmony_ci return NOERROR; 1713159b3361Sopenharmony_ci } 1714159b3361Sopenharmony_ci 1715159b3361Sopenharmony_ci 1716159b3361Sopenharmony_ci // Annotate the current MediaType index for recall in CMpegAudEnc::Reconnect() 1717159b3361Sopenharmony_ci m_pFilter->m_currentMediaTypeIndex = iPosition; 1718159b3361Sopenharmony_ci 1719159b3361Sopenharmony_ci // Configure the remaining AM_MEDIA_TYPE parameters using the cached encoder settings. 1720159b3361Sopenharmony_ci // Since MEDIATYPE_Stream doesn't have a format block the current settings 1721159b3361Sopenharmony_ci // for CHANNEL MODE, BITRATE and SAMPLERATE are cached in m_CurrentOutputFormat for use 1722159b3361Sopenharmony_ci // when we setup the LAME encoder in the call to CMpegAudEncOutPin::SetMediaType() 1723159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1724159b3361Sopenharmony_ci m_pFilter->m_Encoder.GetOutputType(&mec); // Retrieve the current encoder config 1725159b3361Sopenharmony_ci 1726159b3361Sopenharmony_ci WAVEFORMATEX wf; // Retrieve the input configuration 1727159b3361Sopenharmony_ci m_pFilter->m_Encoder.GetInputType(&wf); 1728159b3361Sopenharmony_ci 1729159b3361Sopenharmony_ci // Use the current encoder sample rate unless it isn't a modulus of the input rate 1730159b3361Sopenharmony_ci if ((wf.nSamplesPerSec % mec.dwSampleRate) == 0) { 1731159b3361Sopenharmony_ci m_CurrentOutputFormat.nSampleRate = mec.dwSampleRate; 1732159b3361Sopenharmony_ci } 1733159b3361Sopenharmony_ci else { 1734159b3361Sopenharmony_ci m_CurrentOutputFormat.nSampleRate = wf.nSamplesPerSec; 1735159b3361Sopenharmony_ci } 1736159b3361Sopenharmony_ci 1737159b3361Sopenharmony_ci // Select the output channel config based on the encoder config and input channel count 1738159b3361Sopenharmony_ci m_CurrentOutputFormat.ChMode = mec.ChMode; 1739159b3361Sopenharmony_ci switch (wf.nChannels) // Determine if we need to alter ChMode based upon the channel count and ForceMono flag 1740159b3361Sopenharmony_ci { 1741159b3361Sopenharmony_ci case 1: 1742159b3361Sopenharmony_ci { 1743159b3361Sopenharmony_ci m_CurrentOutputFormat.ChMode = MONO; 1744159b3361Sopenharmony_ci break; 1745159b3361Sopenharmony_ci } 1746159b3361Sopenharmony_ci case 2: 1747159b3361Sopenharmony_ci { 1748159b3361Sopenharmony_ci if (mec.ChMode == MONO && !mec.bForceMono) { m_CurrentOutputFormat.ChMode = STEREO; } 1749159b3361Sopenharmony_ci else if ( mec.bForceMono ) { m_CurrentOutputFormat.ChMode = MONO; } 1750159b3361Sopenharmony_ci break; 1751159b3361Sopenharmony_ci } 1752159b3361Sopenharmony_ci } 1753159b3361Sopenharmony_ci 1754159b3361Sopenharmony_ci // Select the encoder bit rate. In VBR mode we set the data rate parameter 1755159b3361Sopenharmony_ci // of the WAVE_FORMAT_MPEGLAYER3 structure to the minimum VBR value 1756159b3361Sopenharmony_ci m_CurrentOutputFormat.nBitRate = (mec.vmVariable == vbr_off) ? mec.dwBitrate : mec.dwVariableMin; 1757159b3361Sopenharmony_ci 1758159b3361Sopenharmony_ci if (pmt->majortype == MEDIATYPE_Stream) return NOERROR; // No further config required for MEDIATYPE_Stream 1759159b3361Sopenharmony_ci 1760159b3361Sopenharmony_ci 1761159b3361Sopenharmony_ci // Now configure the remainder of the WAVE_FORMAT_MPEGLAYER3 format block 1762159b3361Sopenharmony_ci // and its parent AM_MEDIA_TYPE structure 1763159b3361Sopenharmony_ci DECLARE_PTR(MPEGLAYER3WAVEFORMAT, p_mp3wvfmt, pmt->AllocFormatBuffer(sizeof(MPEGLAYER3WAVEFORMAT))); 1764159b3361Sopenharmony_ci ZeroMemory(p_mp3wvfmt, sizeof(MPEGLAYER3WAVEFORMAT)); 1765159b3361Sopenharmony_ci 1766159b3361Sopenharmony_ci p_mp3wvfmt->wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3; 1767159b3361Sopenharmony_ci p_mp3wvfmt->wfx.nChannels = (m_CurrentOutputFormat.ChMode == MONO) ? 1 : 2; 1768159b3361Sopenharmony_ci p_mp3wvfmt->wfx.nSamplesPerSec = m_CurrentOutputFormat.nSampleRate; 1769159b3361Sopenharmony_ci p_mp3wvfmt->wfx.nAvgBytesPerSec = GET_DATARATE(m_CurrentOutputFormat.nBitRate); 1770159b3361Sopenharmony_ci p_mp3wvfmt->wfx.nBlockAlign = 1; 1771159b3361Sopenharmony_ci p_mp3wvfmt->wfx.wBitsPerSample = 0; 1772159b3361Sopenharmony_ci p_mp3wvfmt->wfx.cbSize = sizeof(MPEGLAYER3WAVEFORMAT) - sizeof(WAVEFORMATEX); 1773159b3361Sopenharmony_ci 1774159b3361Sopenharmony_ci p_mp3wvfmt->wID = MPEGLAYER3_ID_MPEG; 1775159b3361Sopenharmony_ci p_mp3wvfmt->fdwFlags = MPEGLAYER3_FLAG_PADDING_ISO; 1776159b3361Sopenharmony_ci p_mp3wvfmt->nBlockSize = GET_FRAMELENGTH(m_CurrentOutputFormat.nBitRate, p_mp3wvfmt->wfx.nSamplesPerSec); 1777159b3361Sopenharmony_ci p_mp3wvfmt->nFramesPerBlock = 1; 1778159b3361Sopenharmony_ci p_mp3wvfmt->nCodecDelay = 0; 1779159b3361Sopenharmony_ci 1780159b3361Sopenharmony_ci pmt->SetTemporalCompression(FALSE); 1781159b3361Sopenharmony_ci pmt->SetSampleSize(OUT_BUFFER_SIZE); 1782159b3361Sopenharmony_ci pmt->SetFormat((LPBYTE)p_mp3wvfmt, sizeof(MPEGLAYER3WAVEFORMAT)); 1783159b3361Sopenharmony_ci pmt->SetFormatType(&FORMAT_WaveFormatEx); 1784159b3361Sopenharmony_ci 1785159b3361Sopenharmony_ci return NOERROR; 1786159b3361Sopenharmony_ci} 1787159b3361Sopenharmony_ci 1788159b3361Sopenharmony_ci 1789159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////////// 1790159b3361Sopenharmony_ci// This method is called to see if a given output format is supported 1791159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////////// 1792159b3361Sopenharmony_ciHRESULT CMpegAudEncOutPin::CheckMediaType(const CMediaType *pmtOut) 1793159b3361Sopenharmony_ci{ 1794159b3361Sopenharmony_ci // Fail if the input pin is not connected. 1795159b3361Sopenharmony_ci if (!m_pFilter->m_pInput->IsConnected()) { 1796159b3361Sopenharmony_ci return VFW_E_NOT_CONNECTED; 1797159b3361Sopenharmony_ci } 1798159b3361Sopenharmony_ci 1799159b3361Sopenharmony_ci // Reject any media types that we know in advance our 1800159b3361Sopenharmony_ci // filter cannot use. 1801159b3361Sopenharmony_ci if (pmtOut->majortype != MEDIATYPE_Audio && pmtOut->majortype != MEDIATYPE_Stream) { return S_FALSE; } 1802159b3361Sopenharmony_ci 1803159b3361Sopenharmony_ci // If SetFormat was previously called, check whether pmtOut exactly 1804159b3361Sopenharmony_ci // matches the format that was specified in SetFormat. 1805159b3361Sopenharmony_ci // Return S_OK if they match, or VFW_E_INVALIDMEDIATYPE otherwise.) 1806159b3361Sopenharmony_ci if ( m_SetFormat ) { 1807159b3361Sopenharmony_ci if (*pmtOut != m_mt) { return VFW_E_INVALIDMEDIATYPE; } 1808159b3361Sopenharmony_ci else { return S_OK; } 1809159b3361Sopenharmony_ci } 1810159b3361Sopenharmony_ci 1811159b3361Sopenharmony_ci // Now do the normal check for this media type. 1812159b3361Sopenharmony_ci HRESULT hr; 1813159b3361Sopenharmony_ci hr = m_pFilter->CheckTransform (&m_pFilter->m_pInput->CurrentMediaType(), // The input type. 1814159b3361Sopenharmony_ci pmtOut); // The proposed output type. 1815159b3361Sopenharmony_ci 1816159b3361Sopenharmony_ci if (hr == S_OK) { 1817159b3361Sopenharmony_ci return S_OK; // This format is compatible with the current input type. 1818159b3361Sopenharmony_ci } 1819159b3361Sopenharmony_ci 1820159b3361Sopenharmony_ci // This format is not compatible with the current input type. 1821159b3361Sopenharmony_ci // Maybe we can reconnect the input pin with a new input type. 1822159b3361Sopenharmony_ci 1823159b3361Sopenharmony_ci // Enumerate the upstream filter's preferred output types, and 1824159b3361Sopenharmony_ci // see if one of them will work. 1825159b3361Sopenharmony_ci CMediaType *pmtEnum; 1826159b3361Sopenharmony_ci BOOL fFound = FALSE; 1827159b3361Sopenharmony_ci IEnumMediaTypes *pEnum; 1828159b3361Sopenharmony_ci hr = m_pFilter->m_pInput->GetConnected()->EnumMediaTypes(&pEnum); 1829159b3361Sopenharmony_ci if (hr != S_OK) { 1830159b3361Sopenharmony_ci return E_FAIL; 1831159b3361Sopenharmony_ci } 1832159b3361Sopenharmony_ci 1833159b3361Sopenharmony_ci while (hr = pEnum->Next(1, (AM_MEDIA_TYPE **)&pmtEnum, NULL), hr == S_OK) 1834159b3361Sopenharmony_ci { 1835159b3361Sopenharmony_ci // Check this input type against the proposed output type. 1836159b3361Sopenharmony_ci hr = m_pFilter->CheckTransform(pmtEnum, pmtOut); 1837159b3361Sopenharmony_ci if (hr != S_OK) { 1838159b3361Sopenharmony_ci DeleteMediaType(pmtEnum); 1839159b3361Sopenharmony_ci continue; // Try the next one. 1840159b3361Sopenharmony_ci } 1841159b3361Sopenharmony_ci 1842159b3361Sopenharmony_ci // This input type is a possible candidate. But, we have to make 1843159b3361Sopenharmony_ci // sure that the upstream filter can switch to this type. 1844159b3361Sopenharmony_ci hr = m_pFilter->m_pInput->GetConnected()->QueryAccept(pmtEnum); 1845159b3361Sopenharmony_ci if (hr != S_OK) { 1846159b3361Sopenharmony_ci // The upstream filter will not switch to this type. 1847159b3361Sopenharmony_ci DeleteMediaType(pmtEnum); 1848159b3361Sopenharmony_ci continue; // Try the next one. 1849159b3361Sopenharmony_ci } 1850159b3361Sopenharmony_ci fFound = TRUE; 1851159b3361Sopenharmony_ci DeleteMediaType(pmtEnum); 1852159b3361Sopenharmony_ci break; 1853159b3361Sopenharmony_ci } 1854159b3361Sopenharmony_ci pEnum->Release(); 1855159b3361Sopenharmony_ci 1856159b3361Sopenharmony_ci if (fFound) { 1857159b3361Sopenharmony_ci // This output type is OK, but if we are asked to use it, we will 1858159b3361Sopenharmony_ci // need to reconnect our input pin. (See SetFormat, below.) 1859159b3361Sopenharmony_ci return S_OK; 1860159b3361Sopenharmony_ci } 1861159b3361Sopenharmony_ci else { 1862159b3361Sopenharmony_ci return VFW_E_INVALIDMEDIATYPE; 1863159b3361Sopenharmony_ci } 1864159b3361Sopenharmony_ci} 1865159b3361Sopenharmony_ci 1866159b3361Sopenharmony_ci 1867159b3361Sopenharmony_ci 1868159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////////// 1869159b3361Sopenharmony_ci// IAMStreamConfig 1870159b3361Sopenharmony_ci////////////////////////////////////////////////////////////////////////// 1871159b3361Sopenharmony_ci 1872159b3361Sopenharmony_ciHRESULT STDMETHODCALLTYPE CMpegAudEncOutPin::SetFormat(AM_MEDIA_TYPE *pmt) 1873159b3361Sopenharmony_ci{ 1874159b3361Sopenharmony_ci CheckPointer(pmt, E_POINTER); 1875159b3361Sopenharmony_ci HRESULT hr; 1876159b3361Sopenharmony_ci 1877159b3361Sopenharmony_ci // Hold the filter state lock, to make sure that streaming isn't 1878159b3361Sopenharmony_ci // in the middle of starting or stopping: 1879159b3361Sopenharmony_ci CAutoLock cObjectLock(&m_pFilter->m_csFilter); 1880159b3361Sopenharmony_ci 1881159b3361Sopenharmony_ci // Cannot set the format unless the filter is stopped. 1882159b3361Sopenharmony_ci if (m_pFilter->m_State != State_Stopped) { 1883159b3361Sopenharmony_ci return VFW_E_NOT_STOPPED; 1884159b3361Sopenharmony_ci } 1885159b3361Sopenharmony_ci 1886159b3361Sopenharmony_ci // The set of possible output formats depends on the input format, 1887159b3361Sopenharmony_ci // so if the input pin is not connected, return a failure code. 1888159b3361Sopenharmony_ci if (!m_pFilter->m_pInput->IsConnected()) { 1889159b3361Sopenharmony_ci return VFW_E_NOT_CONNECTED; 1890159b3361Sopenharmony_ci } 1891159b3361Sopenharmony_ci 1892159b3361Sopenharmony_ci // If the pin is already using this format, there's nothing to do. 1893159b3361Sopenharmony_ci if (IsConnected() && CurrentMediaType() == *pmt) { 1894159b3361Sopenharmony_ci if ( m_SetFormat ) return S_OK; 1895159b3361Sopenharmony_ci } 1896159b3361Sopenharmony_ci 1897159b3361Sopenharmony_ci // See if this media type is acceptable. 1898159b3361Sopenharmony_ci if ((hr = CheckMediaType((CMediaType *)pmt)) != S_OK) { 1899159b3361Sopenharmony_ci return hr; 1900159b3361Sopenharmony_ci } 1901159b3361Sopenharmony_ci 1902159b3361Sopenharmony_ci // If we're connected to a downstream filter, we have to make 1903159b3361Sopenharmony_ci // sure that the downstream filter accepts this media type. 1904159b3361Sopenharmony_ci if (IsConnected()) { 1905159b3361Sopenharmony_ci hr = GetConnected()->QueryAccept(pmt); 1906159b3361Sopenharmony_ci if (hr != S_OK) { 1907159b3361Sopenharmony_ci return VFW_E_INVALIDMEDIATYPE; 1908159b3361Sopenharmony_ci } 1909159b3361Sopenharmony_ci } 1910159b3361Sopenharmony_ci 1911159b3361Sopenharmony_ci // Now make a note that from now on, this is the only format allowed, 1912159b3361Sopenharmony_ci // and refuse anything but this in the CheckMediaType() code above. 1913159b3361Sopenharmony_ci m_SetFormat = TRUE; 1914159b3361Sopenharmony_ci m_mt = *pmt; 1915159b3361Sopenharmony_ci 1916159b3361Sopenharmony_ci // Changing the format means reconnecting if necessary. 1917159b3361Sopenharmony_ci if (IsConnected()) { 1918159b3361Sopenharmony_ci m_pFilter->m_pGraph->Reconnect(this); 1919159b3361Sopenharmony_ci } 1920159b3361Sopenharmony_ci 1921159b3361Sopenharmony_ci return NOERROR; 1922159b3361Sopenharmony_ci} 1923159b3361Sopenharmony_ci 1924159b3361Sopenharmony_ciHRESULT STDMETHODCALLTYPE CMpegAudEncOutPin::GetFormat(AM_MEDIA_TYPE **ppmt) 1925159b3361Sopenharmony_ci{ 1926159b3361Sopenharmony_ci *ppmt = CreateMediaType(&m_mt); 1927159b3361Sopenharmony_ci return S_OK; 1928159b3361Sopenharmony_ci} 1929159b3361Sopenharmony_ci 1930159b3361Sopenharmony_ciHRESULT STDMETHODCALLTYPE CMpegAudEncOutPin::GetNumberOfCapabilities(int *piCount, int *piSize) 1931159b3361Sopenharmony_ci{ 1932159b3361Sopenharmony_ci // The set of possible output formats depends on the input format, 1933159b3361Sopenharmony_ci // so if the input pin is not connected, return a failure code. 1934159b3361Sopenharmony_ci if (!m_pFilter->m_pInput->IsConnected()) { 1935159b3361Sopenharmony_ci return VFW_E_NOT_CONNECTED; 1936159b3361Sopenharmony_ci } 1937159b3361Sopenharmony_ci 1938159b3361Sopenharmony_ci // Retrieve the current encoder configuration 1939159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1940159b3361Sopenharmony_ci m_pFilter->m_Encoder.GetOutputType(&mec); 1941159b3361Sopenharmony_ci 1942159b3361Sopenharmony_ci // If the encoder is in VBR mode GetStreamCaps() isn't implemented 1943159b3361Sopenharmony_ci if (mec.vmVariable != vbr_off) { *piCount = 0; } 1944159b3361Sopenharmony_ci else { *piCount = m_pFilter->m_CapsNum; } 1945159b3361Sopenharmony_ci 1946159b3361Sopenharmony_ci *piSize = sizeof(AUDIO_STREAM_CONFIG_CAPS); 1947159b3361Sopenharmony_ci return S_OK; 1948159b3361Sopenharmony_ci} 1949159b3361Sopenharmony_ci 1950159b3361Sopenharmony_ciHRESULT STDMETHODCALLTYPE CMpegAudEncOutPin::GetStreamCaps(int iIndex, AM_MEDIA_TYPE **pmt, BYTE *pSCC) 1951159b3361Sopenharmony_ci{ 1952159b3361Sopenharmony_ci // The set of possible output formats depends on the input format, 1953159b3361Sopenharmony_ci // so if the input pin is not connected, return a failure code. 1954159b3361Sopenharmony_ci if (!m_pFilter->m_pInput->IsConnected()) { 1955159b3361Sopenharmony_ci return VFW_E_NOT_CONNECTED; 1956159b3361Sopenharmony_ci } 1957159b3361Sopenharmony_ci 1958159b3361Sopenharmony_ci // If we don't have a capabilities array GetStreamCaps() isn't implemented 1959159b3361Sopenharmony_ci if (m_pFilter->m_CapsNum == 0) return E_NOTIMPL; 1960159b3361Sopenharmony_ci 1961159b3361Sopenharmony_ci // If the encoder is in VBR mode GetStreamCaps() isn't implemented 1962159b3361Sopenharmony_ci MPEG_ENCODER_CONFIG mec; 1963159b3361Sopenharmony_ci m_pFilter->m_Encoder.GetOutputType(&mec); 1964159b3361Sopenharmony_ci if (mec.vmVariable != vbr_off) return E_NOTIMPL; 1965159b3361Sopenharmony_ci 1966159b3361Sopenharmony_ci if (iIndex < 0) return E_INVALIDARG; 1967159b3361Sopenharmony_ci if (iIndex > m_pFilter->m_CapsNum) return S_FALSE; 1968159b3361Sopenharmony_ci 1969159b3361Sopenharmony_ci // Load the MPEG Layer3 WaveFormatEx structure with the appropriate entries 1970159b3361Sopenharmony_ci // for this IAMStreamConfig index element. 1971159b3361Sopenharmony_ci *pmt = CreateMediaType(&m_mt); 1972159b3361Sopenharmony_ci if (*pmt == NULL) return E_OUTOFMEMORY; 1973159b3361Sopenharmony_ci 1974159b3361Sopenharmony_ci DECLARE_PTR(MPEGLAYER3WAVEFORMAT, p_mp3wvfmt, (*pmt)->pbFormat); 1975159b3361Sopenharmony_ci 1976159b3361Sopenharmony_ci (*pmt)->majortype = MEDIATYPE_Audio; 1977159b3361Sopenharmony_ci (*pmt)->subtype = MEDIASUBTYPE_MP3; 1978159b3361Sopenharmony_ci (*pmt)->bFixedSizeSamples = TRUE; 1979159b3361Sopenharmony_ci (*pmt)->bTemporalCompression = FALSE; 1980159b3361Sopenharmony_ci (*pmt)->lSampleSize = OUT_BUFFER_SIZE; 1981159b3361Sopenharmony_ci (*pmt)->formattype = FORMAT_WaveFormatEx; 1982159b3361Sopenharmony_ci (*pmt)->cbFormat = sizeof(MPEGLAYER3WAVEFORMAT); 1983159b3361Sopenharmony_ci 1984159b3361Sopenharmony_ci p_mp3wvfmt->wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3; 1985159b3361Sopenharmony_ci p_mp3wvfmt->wfx.nChannels = 2; 1986159b3361Sopenharmony_ci p_mp3wvfmt->wfx.nSamplesPerSec = m_pFilter->OutputCaps[iIndex].nSampleRate; 1987159b3361Sopenharmony_ci p_mp3wvfmt->wfx.nAvgBytesPerSec = GET_DATARATE(m_pFilter->OutputCaps[iIndex].nBitRate); 1988159b3361Sopenharmony_ci p_mp3wvfmt->wfx.nBlockAlign = 1; 1989159b3361Sopenharmony_ci p_mp3wvfmt->wfx.wBitsPerSample = 0; 1990159b3361Sopenharmony_ci p_mp3wvfmt->wfx.cbSize = sizeof(MPEGLAYER3WAVEFORMAT) - sizeof(WAVEFORMATEX); 1991159b3361Sopenharmony_ci 1992159b3361Sopenharmony_ci p_mp3wvfmt->wID = MPEGLAYER3_ID_MPEG; 1993159b3361Sopenharmony_ci p_mp3wvfmt->fdwFlags = MPEGLAYER3_FLAG_PADDING_ISO; 1994159b3361Sopenharmony_ci p_mp3wvfmt->nBlockSize = GET_FRAMELENGTH(m_pFilter->OutputCaps[iIndex].nBitRate, m_pFilter->OutputCaps[iIndex].nSampleRate); 1995159b3361Sopenharmony_ci p_mp3wvfmt->nFramesPerBlock = 1; 1996159b3361Sopenharmony_ci p_mp3wvfmt->nCodecDelay = 0; 1997159b3361Sopenharmony_ci 1998159b3361Sopenharmony_ci // Set up the companion AUDIO_STREAM_CONFIG_CAPS structure 1999159b3361Sopenharmony_ci // We are only using the CHANNELS element of the structure 2000159b3361Sopenharmony_ci DECLARE_PTR(AUDIO_STREAM_CONFIG_CAPS, pascc, pSCC); 2001159b3361Sopenharmony_ci 2002159b3361Sopenharmony_ci ZeroMemory(pascc, sizeof(AUDIO_STREAM_CONFIG_CAPS)); 2003159b3361Sopenharmony_ci pascc->guid = MEDIATYPE_Audio; 2004159b3361Sopenharmony_ci 2005159b3361Sopenharmony_ci pascc->MinimumChannels = 1; 2006159b3361Sopenharmony_ci pascc->MaximumChannels = 2; 2007159b3361Sopenharmony_ci pascc->ChannelsGranularity = 1; 2008159b3361Sopenharmony_ci 2009159b3361Sopenharmony_ci pascc->MinimumSampleFrequency = p_mp3wvfmt->wfx.nSamplesPerSec; 2010159b3361Sopenharmony_ci pascc->MaximumSampleFrequency = p_mp3wvfmt->wfx.nSamplesPerSec; 2011159b3361Sopenharmony_ci pascc->SampleFrequencyGranularity = 0; 2012159b3361Sopenharmony_ci 2013159b3361Sopenharmony_ci pascc->MinimumBitsPerSample = p_mp3wvfmt->wfx.wBitsPerSample; 2014159b3361Sopenharmony_ci pascc->MaximumBitsPerSample = p_mp3wvfmt->wfx.wBitsPerSample; 2015159b3361Sopenharmony_ci pascc->BitsPerSampleGranularity = 0; 2016159b3361Sopenharmony_ci 2017159b3361Sopenharmony_ci return S_OK; 2018159b3361Sopenharmony_ci} 2019159b3361Sopenharmony_ci 2020