|
Packit |
47f805 |
/*
|
|
Packit |
47f805 |
* LAME MP3 encoder for DirectShow
|
|
Packit |
47f805 |
* DirectShow filter implementation
|
|
Packit |
47f805 |
*
|
|
Packit |
47f805 |
* Copyright (c) 2000-2005 Marie Orlova, Peter Gubanov, Vitaly Ivanov, Elecard Ltd.
|
|
Packit |
47f805 |
*
|
|
Packit |
47f805 |
* This library is free software; you can redistribute it and/or
|
|
Packit |
47f805 |
* modify it under the terms of the GNU Library General Public
|
|
Packit |
47f805 |
* License as published by the Free Software Foundation; either
|
|
Packit |
47f805 |
* version 2 of the License, or (at your option) any later version.
|
|
Packit |
47f805 |
*
|
|
Packit |
47f805 |
* This library is distributed in the hope that it will be useful,
|
|
Packit |
47f805 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
47f805 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
47f805 |
* Library General Public License for more details.
|
|
Packit |
47f805 |
*
|
|
Packit |
47f805 |
* You should have received a copy of the GNU Library General Public
|
|
Packit |
47f805 |
* License along with this library; if not, write to the
|
|
Packit |
47f805 |
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
Packit |
47f805 |
* Boston, MA 02111-1307, USA.
|
|
Packit |
47f805 |
*/
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#include <streams.h>
|
|
Packit |
47f805 |
#include <olectl.h>
|
|
Packit |
47f805 |
#include <initguid.h>
|
|
Packit |
47f805 |
//#include <olectlid.h>
|
|
Packit |
47f805 |
#include "uids.h"
|
|
Packit |
47f805 |
#include "iaudioprops.h"
|
|
Packit |
47f805 |
#include "mpegac.h"
|
|
Packit |
47f805 |
#include "resource.h"
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#include "PropPage.h"
|
|
Packit |
47f805 |
#include "PropPage_adv.h"
|
|
Packit |
47f805 |
#include "aboutprp.h"
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#include "Encoder.h"
|
|
Packit |
47f805 |
#include "Reg.h"
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#ifndef _INC_MMREG
|
|
Packit |
47f805 |
#include <mmreg.h>
|
|
Packit |
47f805 |
#endif
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// default parameters
|
|
Packit |
47f805 |
#define DEFAULT_LAYER 3
|
|
Packit |
47f805 |
#define DEFAULT_STEREO_MODE JOINT_STEREO
|
|
Packit |
47f805 |
#define DEFAULT_FORCE_MS 0
|
|
Packit |
47f805 |
#define DEFAULT_MODE_FIXED 0
|
|
Packit |
47f805 |
#define DEFAULT_ENFORCE_MIN 0
|
|
Packit |
47f805 |
#define DEFAULT_VOICE 0
|
|
Packit |
47f805 |
#define DEFAULT_KEEP_ALL_FREQ 0
|
|
Packit |
47f805 |
#define DEFAULT_STRICT_ISO 0
|
|
Packit |
47f805 |
#define DEFAULT_DISABLE_SHORT_BLOCK 0
|
|
Packit |
47f805 |
#define DEFAULT_XING_TAG 0
|
|
Packit |
47f805 |
#define DEFAULT_SAMPLE_RATE 44100
|
|
Packit |
47f805 |
#define DEFAULT_BITRATE 128
|
|
Packit |
47f805 |
#define DEFAULT_VARIABLE 0
|
|
Packit |
47f805 |
#define DEFAULT_CRC 0
|
|
Packit |
47f805 |
#define DEFAULT_FORCE_MONO 0
|
|
Packit |
47f805 |
#define DEFAULT_SET_DURATION 1
|
|
Packit |
47f805 |
#define DEFAULT_SAMPLE_OVERLAP 1
|
|
Packit |
47f805 |
#define DEFAULT_COPYRIGHT 0
|
|
Packit |
47f805 |
#define DEFAULT_ORIGINAL 0
|
|
Packit |
47f805 |
#define DEFAULT_VARIABLEMIN 80
|
|
Packit |
47f805 |
#define DEFAULT_VARIABLEMAX 160
|
|
Packit |
47f805 |
#define DEFAULT_ENCODING_QUALITY 5
|
|
Packit |
47f805 |
#define DEFAULT_VBR_QUALITY 4
|
|
Packit |
47f805 |
#define DEFAULT_PES 0
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#define DEFAULT_FILTER_MERIT MERIT_DO_NOT_USE // Standard compressor merit value
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
#define GET_DATARATE(kbps) (kbps * 1000 / 8)
|
|
Packit |
47f805 |
#define GET_FRAMELENGTH(bitrate, sample_rate) ((WORD)(((sample_rate < 32000 ? 72000 : 144000) * (bitrate))/(sample_rate)))
|
|
Packit |
47f805 |
#define DECLARE_PTR(type, ptr, expr) type* ptr = (type*)(expr);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Create a list of all (or mostly all) of the encoder CBR output capabilities which
|
|
Packit |
47f805 |
// will be parsed into a list of capabilities used by the IAMStreamConfig Interface
|
|
Packit |
47f805 |
output_caps_t OutputCapabilities[] =
|
|
Packit |
47f805 |
{ // {SampleRate, BitRate}
|
|
Packit |
47f805 |
{ 48000, 320 },{ 48000, 256 },{ 48000, 224 },{ 48000, 192 }, // MPEG 1.0 Spec @ 48KHz
|
|
Packit |
47f805 |
{ 48000, 160 },{ 48000, 128 },{ 48000, 112 },{ 48000, 96 },
|
|
Packit |
47f805 |
{ 48000, 80 },{ 48000, 64 },{ 48000, 56 },{ 48000, 48 },
|
|
Packit |
47f805 |
{ 48000, 40 },{ 48000, 32 },
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
{ 24000, 160 },{ 24000, 144 },{ 24000, 128 },{ 24000, 112 }, // MPEG 2.0 Spec @ 24KHz
|
|
Packit |
47f805 |
{ 24000, 96 },{ 24000, 80 },{ 24000, 64 },{ 24000, 56 },
|
|
Packit |
47f805 |
{ 24000, 48 },{ 24000, 40 },{ 24000, 32 },{ 24000, 24 },
|
|
Packit |
47f805 |
{ 24000, 16 },{ 24000, 8 },
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
{ 12000, 64 },{ 12000, 56 },{ 12000, 48 },{ 12000, 40 }, // MPEG 2.5 Spec @ 12KHz
|
|
Packit |
47f805 |
{ 12000, 32 },{ 12000, 24 },{ 12000, 16 },{ 12000, 8 },
|
|
Packit |
47f805 |
// --------------------------- --------------------------
|
|
Packit |
47f805 |
{ 44100, 320 },{ 44100, 256 },{ 44100, 224 },{ 44100, 192 }, // MPEG 1.0 Spec @ 44.1KHz
|
|
Packit |
47f805 |
{ 44100, 160 },{ 44100, 128 },{ 44100, 112 },{ 44100, 96 },
|
|
Packit |
47f805 |
{ 44100, 80 },{ 44100, 64 },{ 44100, 56 },{ 44100, 48 },
|
|
Packit |
47f805 |
{ 44100, 40 },{ 44100, 32 },
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
{ 22050, 160 },{ 22050, 144 },{ 22050, 128 },{ 22050, 112 }, // MPEG 2.0 Spec @ 22.05KHz
|
|
Packit |
47f805 |
{ 22050, 96 },{ 22050, 80 },{ 22050, 64 },{ 22050, 56 },
|
|
Packit |
47f805 |
{ 22050, 48 },{ 22050, 40 },{ 22050, 32 },{ 22050, 24 },
|
|
Packit |
47f805 |
{ 22050, 16 },{ 22050, 8 },
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
{ 11025, 64 },{ 11025, 56 },{ 11025, 48 },{ 11025, 40 }, // MPEG 2.5 Spec @ 11.025KHz
|
|
Packit |
47f805 |
{ 11025, 32 },{ 11025, 24 },{ 11025, 16 },{ 11025, 8 },
|
|
Packit |
47f805 |
// --------------------------- --------------------------
|
|
Packit |
47f805 |
{ 32000, 320 },{ 32000, 256 },{ 32000, 224 },{ 32000, 192 }, // MPEG 1.0 Spec @ 32KHz
|
|
Packit |
47f805 |
{ 32000, 160 },{ 32000, 128 },{ 32000, 112 },{ 32000, 96 },
|
|
Packit |
47f805 |
{ 32000, 80 },{ 32000, 64 },{ 32000, 56 },{ 32000, 48 },
|
|
Packit |
47f805 |
{ 32000, 40 },{ 32000, 32 },
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
{ 16000, 160 },{ 16000, 144 },{ 16000, 128 },{ 16000, 112 }, // MPEG 2.0 Spec @ 16KHz
|
|
Packit |
47f805 |
{ 16000, 96 },{ 16000, 80 },{ 16000, 64 },{ 16000, 56 },
|
|
Packit |
47f805 |
{ 16000, 48 },{ 16000, 40 },{ 16000, 32 },{ 16000, 24 },
|
|
Packit |
47f805 |
{ 16000, 16 },{ 16000, 8 },
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
{ 8000, 64 },{ 8000, 56 },{ 8000, 48 },{ 8000, 40 }, // MPEG 2.5 Spec @ 8KHz
|
|
Packit |
47f805 |
{ 8000, 32 },{ 8000, 24 },{ 8000, 16 },{ 8000, 8 }
|
|
Packit |
47f805 |
};
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/* Registration setup stuff */
|
|
Packit |
47f805 |
// Setup data
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
AMOVIESETUP_MEDIATYPE sudMpgInputType[] =
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
{ &MEDIATYPE_Audio, &MEDIASUBTYPE_PCM }
|
|
Packit |
47f805 |
};
|
|
Packit |
47f805 |
AMOVIESETUP_MEDIATYPE sudMpgOutputType[] =
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
{ &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload },
|
|
Packit |
47f805 |
{ &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG2_AUDIO },
|
|
Packit |
47f805 |
{ &MEDIATYPE_Audio, &MEDIASUBTYPE_MP3 },
|
|
Packit |
47f805 |
{ &MEDIATYPE_Stream, &MEDIASUBTYPE_MPEG1Audio }
|
|
Packit |
47f805 |
};
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
AMOVIESETUP_PIN sudMpgPins[] =
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
{ L"PCM Input",
|
|
Packit |
47f805 |
FALSE, // bRendered
|
|
Packit |
47f805 |
FALSE, // bOutput
|
|
Packit |
47f805 |
FALSE, // bZero
|
|
Packit |
47f805 |
FALSE, // bMany
|
|
Packit |
47f805 |
&CLSID_NULL, // clsConnectsToFilter
|
|
Packit |
47f805 |
NULL, // ConnectsToPin
|
|
Packit |
47f805 |
NUMELMS(sudMpgInputType), // Number of media types
|
|
Packit |
47f805 |
sudMpgInputType
|
|
Packit |
47f805 |
},
|
|
Packit |
47f805 |
{ L"MPEG Output",
|
|
Packit |
47f805 |
FALSE, // bRendered
|
|
Packit |
47f805 |
TRUE, // bOutput
|
|
Packit |
47f805 |
FALSE, // bZero
|
|
Packit |
47f805 |
FALSE, // bMany
|
|
Packit |
47f805 |
&CLSID_NULL, // clsConnectsToFilter
|
|
Packit |
47f805 |
NULL, // ConnectsToPin
|
|
Packit |
47f805 |
NUMELMS(sudMpgOutputType), // Number of media types
|
|
Packit |
47f805 |
sudMpgOutputType
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
};
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
AMOVIESETUP_FILTER sudMpgAEnc =
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
&CLSID_LAMEDShowFilter,
|
|
Packit |
47f805 |
L"LAME Audio Encoder",
|
|
Packit |
47f805 |
DEFAULT_FILTER_MERIT, // Standard compressor merit value
|
|
Packit |
47f805 |
NUMELMS(sudMpgPins), // 2 pins
|
|
Packit |
47f805 |
sudMpgPins
|
|
Packit |
47f805 |
};
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
/*****************************************************************************/
|
|
Packit |
47f805 |
// COM Global table of objects in this dll
|
|
Packit |
47f805 |
static WCHAR g_wszName[] = L"LAME Audio Encoder";
|
|
Packit |
47f805 |
CFactoryTemplate g_Templates[] =
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
{ g_wszName, &CLSID_LAMEDShowFilter, CMpegAudEnc::CreateInstance, NULL, &sudMpgAEnc },
|
|
Packit |
47f805 |
{ L"LAME Audio Encoder Property Page", &CLSID_LAMEDShow_PropertyPage, CMpegAudEncPropertyPage::CreateInstance},
|
|
Packit |
47f805 |
{ L"LAME Audio Encoder Property Page", &CLSID_LAMEDShow_PropertyPageAdv, CMpegAudEncPropertyPageAdv::CreateInstance},
|
|
Packit |
47f805 |
{ L"LAME Audio Encoder About", &CLSID_LAMEDShow_About, CMAEAbout::CreateInstance}
|
|
Packit |
47f805 |
};
|
|
Packit |
47f805 |
// Count of objects listed in g_cTemplates
|
|
Packit |
47f805 |
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
////////////////////////////////////////////
|
|
Packit |
47f805 |
// Declare the DirectShow filter information.
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Used by IFilterMapper2() in the call to DllRegisterServer()
|
|
Packit |
47f805 |
// to register the filter in the CLSID_AudioCompressorCategory.
|
|
Packit |
47f805 |
REGFILTER2 rf2FilterReg = {
|
|
Packit |
47f805 |
1, // Version number.
|
|
Packit |
47f805 |
DEFAULT_FILTER_MERIT, // Merit. This should match the merit specified in the AMOVIESETUP_FILTER definition
|
|
Packit |
47f805 |
NUMELMS(sudMpgPins), // Number of pins.
|
|
Packit |
47f805 |
sudMpgPins // Pointer to pin information.
|
|
Packit |
47f805 |
};
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDAPI DllRegisterServer(void)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
HRESULT hr = AMovieDllRegisterServer2(TRUE);
|
|
Packit |
47f805 |
if (FAILED(hr)) {
|
|
Packit |
47f805 |
return hr;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
IFilterMapper2 *pFM2 = NULL;
|
|
Packit |
47f805 |
hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, IID_IFilterMapper2, (void **)&pFM2);
|
|
Packit |
47f805 |
if (SUCCEEDED(hr)) {
|
|
Packit |
47f805 |
hr = pFM2->RegisterFilter(
|
|
Packit |
47f805 |
CLSID_LAMEDShowFilter, // Filter CLSID.
|
|
Packit |
47f805 |
g_wszName, // Filter name.
|
|
Packit |
47f805 |
NULL, // Device moniker.
|
|
Packit |
47f805 |
&CLSID_AudioCompressorCategory, // Audio compressor category.
|
|
Packit |
47f805 |
g_wszName, // Instance data.
|
|
Packit |
47f805 |
&rf2FilterReg // Filter information.
|
|
Packit |
47f805 |
);
|
|
Packit |
47f805 |
pFM2->Release();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return hr;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDAPI DllUnregisterServer()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
HRESULT hr = AMovieDllRegisterServer2(FALSE);
|
|
Packit |
47f805 |
if (FAILED(hr)) {
|
|
Packit |
47f805 |
return hr;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
IFilterMapper2 *pFM2 = NULL;
|
|
Packit |
47f805 |
hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, IID_IFilterMapper2, (void **)&pFM2);
|
|
Packit |
47f805 |
if (SUCCEEDED(hr)) {
|
|
Packit |
47f805 |
hr = pFM2->UnregisterFilter(&CLSID_AudioCompressorCategory, g_wszName, CLSID_LAMEDShowFilter);
|
|
Packit |
47f805 |
pFM2->Release();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return hr;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
CUnknown *CMpegAudEnc::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
CMpegAudEnc *punk = new CMpegAudEnc(lpunk, phr);
|
|
Packit |
47f805 |
if (punk == NULL)
|
|
Packit |
47f805 |
*phr = E_OUTOFMEMORY;
|
|
Packit |
47f805 |
return punk;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
CMpegAudEnc::CMpegAudEnc(LPUNKNOWN lpunk, HRESULT *phr)
|
|
Packit |
47f805 |
: CTransformFilter(NAME("LAME Audio Encoder"), lpunk, CLSID_LAMEDShowFilter),
|
|
Packit |
47f805 |
CPersistStream(lpunk, phr)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// ENCODER OUTPUT PIN
|
|
Packit |
47f805 |
// Override the output pin with our own which will implement the IAMStreamConfig Interface
|
|
Packit |
47f805 |
CTransformOutputPin *pOut = new CMpegAudEncOutPin( this, phr );
|
|
Packit |
47f805 |
if (pOut == NULL) {
|
|
Packit |
47f805 |
*phr = E_OUTOFMEMORY;
|
|
Packit |
47f805 |
return;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if (FAILED(*phr)) { // A failed return code should delete the object
|
|
Packit |
47f805 |
delete pOut;
|
|
Packit |
47f805 |
return;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
m_pOutput = pOut;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// ENCODER INPUT PIN
|
|
Packit |
47f805 |
// Since we've created our own output pin we must also create
|
|
Packit |
47f805 |
// the input pin ourselves because the CTransformFilter base class
|
|
Packit |
47f805 |
// will create an extra output pin if the input pin wasn't created.
|
|
Packit |
47f805 |
CTransformInputPin *pIn = new CTransformInputPin(NAME("LameEncoderInputPin"),
|
|
Packit |
47f805 |
this, // Owner filter
|
|
Packit |
47f805 |
phr, // Result code
|
|
Packit |
47f805 |
L"Input"); // Pin name
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (pIn == NULL) {
|
|
Packit |
47f805 |
*phr = E_OUTOFMEMORY;
|
|
Packit |
47f805 |
return;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if (FAILED(*phr)) { // A failed return code should delete the object
|
|
Packit |
47f805 |
delete pIn;
|
|
Packit |
47f805 |
return;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
m_pInput = pIn;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
ReadPresetSettings(&mec;;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
m_CapsNum = 0;
|
|
Packit |
47f805 |
m_hasFinished = TRUE;
|
|
Packit |
47f805 |
m_bStreamOutput = FALSE;
|
|
Packit |
47f805 |
m_currentMediaTypeIndex = 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
CMpegAudEnc::~CMpegAudEnc(void)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
LPAMOVIESETUP_FILTER CMpegAudEnc::GetSetupData()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
return &sudMpgAEnc;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
HRESULT CMpegAudEnc::Receive(IMediaSample * pSample)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
CAutoLock lock(&m_cs);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (!pSample)
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
BYTE * pSourceBuffer = NULL;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (pSample->GetPointer(&pSourceBuffer) != S_OK || !pSourceBuffer)
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
long sample_size = pSample->GetActualDataLength();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
REFERENCE_TIME rtStart, rtStop;
|
|
Packit |
47f805 |
BOOL gotValidTime = (pSample->GetTime(&rtStart, &rtStop) != VFW_E_SAMPLE_TIME_NOT_SET);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (sample_size <= 0 || pSourceBuffer == NULL || m_hasFinished || (gotValidTime && rtStart < 0))
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (gotValidTime)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (m_rtStreamTime < 0)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
m_rtStreamTime = rtStart;
|
|
Packit |
47f805 |
m_rtEstimated = rtStart;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
resync_point_t * sync = m_sync + m_sync_in_idx;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (sync->applied)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
REFERENCE_TIME rtGap = rtStart - m_rtEstimated;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// if old sync data is applied and gap is greater than 1 ms
|
|
Packit |
47f805 |
// then make a new synchronization point
|
|
Packit |
47f805 |
if (rtGap > 10000 || (m_allowOverlap && rtGap < -10000))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
sync->sample = m_samplesIn;
|
|
Packit |
47f805 |
sync->delta = rtGap;
|
|
Packit |
47f805 |
sync->applied = FALSE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
m_rtEstimated += sync->delta;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (m_sync_in_idx < (RESYNC_COUNT - 1))
|
|
Packit |
47f805 |
m_sync_in_idx++;
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
m_sync_in_idx = 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
m_rtEstimated += (LONGLONG)(m_bytesToDuration * sample_size);
|
|
Packit |
47f805 |
m_samplesIn += sample_size / m_bytesPerSample;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
while (sample_size > 0)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
int bytes_processed = m_Encoder.Encode((short *)pSourceBuffer, sample_size);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (bytes_processed <= 0)
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
FlushEncodedSamples();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
sample_size -= bytes_processed;
|
|
Packit |
47f805 |
pSourceBuffer += bytes_processed;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
HRESULT CMpegAudEnc::FlushEncodedSamples()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
IMediaSample * pOutSample = NULL;
|
|
Packit |
47f805 |
BYTE * pDst = NULL;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if(m_bStreamOutput)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
HRESULT hr = S_OK;
|
|
Packit |
47f805 |
const unsigned char * pblock = NULL;
|
|
Packit |
47f805 |
int iBufferSize;
|
|
Packit |
47f805 |
int iBlockLength = m_Encoder.GetBlockAligned(&pblock, &iBufferSize, m_cbStreamAlignment);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if(!iBlockLength)
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
hr = m_pOutput->GetDeliveryBuffer(&pOutSample, NULL, NULL, 0);
|
|
Packit |
47f805 |
if (hr == S_OK && pOutSample)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
hr = pOutSample->GetPointer(&pDst);
|
|
Packit |
47f805 |
if (hr == S_OK && pDst)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
CopyMemory(pDst, pblock, iBlockLength);
|
|
Packit |
47f805 |
REFERENCE_TIME rtEndPos = m_rtBytePos + iBufferSize;
|
|
Packit |
47f805 |
EXECUTE_ASSERT(S_OK == pOutSample->SetTime(&m_rtBytePos, &rtEndPos));
|
|
Packit |
47f805 |
pOutSample->SetActualDataLength(iBufferSize);
|
|
Packit |
47f805 |
m_rtBytePos += iBlockLength;
|
|
Packit |
47f805 |
m_pOutput->Deliver(pOutSample);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
pOutSample->Release();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (m_rtStreamTime < 0)
|
|
Packit |
47f805 |
m_rtStreamTime = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
while (1)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
const unsigned char * pframe = NULL;
|
|
Packit |
47f805 |
int frame_size = m_Encoder.GetFrame(&pframe);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (frame_size <= 0 || !pframe)
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (!m_sync[m_sync_out_idx].applied && m_sync[m_sync_out_idx].sample <= m_samplesOut)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
m_rtStreamTime += m_sync[m_sync_out_idx].delta;
|
|
Packit |
47f805 |
m_sync[m_sync_out_idx].applied = TRUE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (m_sync_out_idx < (RESYNC_COUNT - 1))
|
|
Packit |
47f805 |
m_sync_out_idx++;
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
m_sync_out_idx = 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
REFERENCE_TIME rtStart = m_rtStreamTime;
|
|
Packit |
47f805 |
REFERENCE_TIME rtStop = rtStart + m_rtFrameTime;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
HRESULT hr = S_OK;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
hr = m_pOutput->GetDeliveryBuffer(&pOutSample, NULL, NULL, 0);
|
|
Packit |
47f805 |
if (hr == S_OK && pOutSample)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
hr = pOutSample->GetPointer(&pDst);
|
|
Packit |
47f805 |
if (hr == S_OK && pDst)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
CopyMemory(pDst, pframe, frame_size);
|
|
Packit |
47f805 |
pOutSample->SetActualDataLength(frame_size);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
pOutSample->SetSyncPoint(TRUE);
|
|
Packit |
47f805 |
pOutSample->SetTime(&rtStart, m_setDuration ? &rtStop : NULL);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
m_pOutput->Deliver(pOutSample);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
pOutSample->Release();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
m_samplesOut += m_samplesPerFrame;
|
|
Packit |
47f805 |
m_rtStreamTime = rtStop;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// StartStreaming - prepare to receive new data
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
HRESULT CMpegAudEnc::StartStreaming()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
WAVEFORMATEX * pwfxIn = (WAVEFORMATEX *) m_pInput->CurrentMediaType().Format();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
m_bytesPerSample = pwfxIn->nChannels * sizeof(short);
|
|
Packit |
47f805 |
DWORD dwOutSampleRate;
|
|
Packit |
47f805 |
if(MEDIATYPE_Stream == m_pOutput->CurrentMediaType().majortype)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mcfg;
|
|
Packit |
47f805 |
if(FAILED(m_Encoder.GetOutputType(&mcfg)))
|
|
Packit |
47f805 |
return E_FAIL;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
dwOutSampleRate = mcfg.dwSampleRate;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
dwOutSampleRate = ((WAVEFORMATEX *) m_pOutput->CurrentMediaType().Format())->nSamplesPerSec;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
m_samplesPerFrame = (dwOutSampleRate >= 32000) ? 1152 : 576;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
m_rtFrameTime = MulDiv(10000000, m_samplesPerFrame, dwOutSampleRate);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
m_samplesIn = m_samplesOut = 0;
|
|
Packit |
47f805 |
m_rtStreamTime = -1;
|
|
Packit |
47f805 |
m_rtBytePos = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// initialize encoder
|
|
Packit |
47f805 |
m_Encoder.Init();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
m_hasFinished = FALSE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
for (int i = 0; i < RESYNC_COUNT; i++)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
m_sync[i].sample = 0;
|
|
Packit |
47f805 |
m_sync[i].delta = 0;
|
|
Packit |
47f805 |
m_sync[i].applied = TRUE;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
m_sync_in_idx = 0;
|
|
Packit |
47f805 |
m_sync_out_idx = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
get_SetDuration(&m_setDuration);
|
|
Packit |
47f805 |
get_SampleOverlap(&m_allowOverlap);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
HRESULT CMpegAudEnc::StopStreaming()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
IStream *pStream = NULL;
|
|
Packit |
47f805 |
if(m_bStreamOutput && m_pOutput->IsConnected() != FALSE)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
IPin * pDwnstrmInputPin = m_pOutput->GetConnected();
|
|
Packit |
47f805 |
if(pDwnstrmInputPin && FAILED(pDwnstrmInputPin->QueryInterface(IID_IStream, (LPVOID*)(&pStream))))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
pStream = NULL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
m_Encoder.Close(pStream);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if(pStream)
|
|
Packit |
47f805 |
pStream->Release();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// EndOfStream - stop data processing
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
HRESULT CMpegAudEnc::EndOfStream()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
CAutoLock lock(&m_cs);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Flush data
|
|
Packit |
47f805 |
m_Encoder.Finish();
|
|
Packit |
47f805 |
FlushEncodedSamples();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
IStream *pStream = NULL;
|
|
Packit |
47f805 |
if(m_bStreamOutput && m_pOutput->IsConnected() != FALSE)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
IPin * pDwnstrmInputPin = m_pOutput->GetConnected();
|
|
Packit |
47f805 |
if(pDwnstrmInputPin)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if(FAILED(pDwnstrmInputPin->QueryInterface(IID_IStream, (LPVOID*)(&pStream))))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
pStream = NULL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if(pStream)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
ULARGE_INTEGER size;
|
|
Packit |
47f805 |
size.QuadPart = m_rtBytePos;
|
|
Packit |
47f805 |
pStream->SetSize(size);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
m_Encoder.Close(pStream);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if(pStream)
|
|
Packit |
47f805 |
pStream->Release();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
m_hasFinished = TRUE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return CTransformFilter::EndOfStream();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// BeginFlush - stop data processing
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
HRESULT CMpegAudEnc::BeginFlush()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
HRESULT hr = CTransformFilter::BeginFlush();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (SUCCEEDED(hr))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
CAutoLock lock(&m_cs);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DWORD dwDstSize = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Flush data
|
|
Packit |
47f805 |
m_Encoder.Finish();
|
|
Packit |
47f805 |
FlushEncodedSamples();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
IStream *pStream = NULL;
|
|
Packit |
47f805 |
if(m_bStreamOutput && m_pOutput->IsConnected() != FALSE)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
IPin * pDwnstrmInputPin = m_pOutput->GetConnected();
|
|
Packit |
47f805 |
if(pDwnstrmInputPin && SUCCEEDED(pDwnstrmInputPin->QueryInterface(IID_IStream, (LPVOID*)(&pStream))))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
ULARGE_INTEGER size;
|
|
Packit |
47f805 |
size.QuadPart = m_rtBytePos;
|
|
Packit |
47f805 |
pStream->SetSize(size);
|
|
Packit |
47f805 |
pStream->Release();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
m_rtStreamTime = -1;
|
|
Packit |
47f805 |
m_rtBytePos = 0;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return hr;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// SetMediaType - called when filters are connecting
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
HRESULT CMpegAudEnc::SetMediaType(PIN_DIRECTION direction, const CMediaType * pmt)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
HRESULT hr = S_OK;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (direction == PINDIR_INPUT)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (*pmt->FormatType() != FORMAT_WaveFormatEx)
|
|
Packit |
47f805 |
return VFW_E_INVALIDMEDIATYPE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (pmt->FormatLength() < sizeof(WAVEFORMATEX))
|
|
Packit |
47f805 |
return VFW_E_INVALIDMEDIATYPE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE,1,TEXT("CMpegAudEnc::SetMediaType(), direction = PINDIR_INPUT")));
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Pass input media type to encoder
|
|
Packit |
47f805 |
m_Encoder.SetInputType((LPWAVEFORMATEX)pmt->Format());
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
WAVEFORMATEX * pwfx = (WAVEFORMATEX *)pmt->Format();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (pwfx)
|
|
Packit |
47f805 |
m_bytesToDuration = (float)1.e7 / (float)(pwfx->nChannels * sizeof(short) * pwfx->nSamplesPerSec);
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
m_bytesToDuration = 0.0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Parse the encoder output capabilities into the subset of capabilities that are supported
|
|
Packit |
47f805 |
// for the current input format. This listing will be utilized by the IAMStreamConfig Interface.
|
|
Packit |
47f805 |
LoadOutputCapabilities(pwfx->nSamplesPerSec);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
Reconnect();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if (direction == PINDIR_OUTPUT)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Before we set the output type, we might need to reconnect
|
|
Packit |
47f805 |
// the input pin with a new type.
|
|
Packit |
47f805 |
if (m_pInput && m_pInput->IsConnected())
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Check if the current input type is compatible.
|
|
Packit |
47f805 |
hr = CheckTransform(&m_pInput->CurrentMediaType(), &m_pOutput->CurrentMediaType());
|
|
Packit |
47f805 |
if (FAILED(hr)) {
|
|
Packit |
47f805 |
// We need to reconnect the input pin.
|
|
Packit |
47f805 |
// Note: The CheckMediaType method has already called QueryAccept on the upstream filter.
|
|
Packit |
47f805 |
hr = m_pGraph->Reconnect(m_pInput);
|
|
Packit |
47f805 |
return hr;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// WAVEFORMATEX wfIn;
|
|
Packit |
47f805 |
// m_Encoder.GetInputType(&wfIn);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// if (wfIn.nSamplesPerSec %
|
|
Packit |
47f805 |
// ((LPWAVEFORMATEX)pmt->Format())->nSamplesPerSec != 0)
|
|
Packit |
47f805 |
// return VFW_E_TYPE_NOT_ACCEPTED;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return hr;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// CheckInputType - check if you can support mtIn
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
HRESULT CMpegAudEnc::CheckInputType(const CMediaType* mtIn)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (*mtIn->Type() == MEDIATYPE_Audio && *mtIn->FormatType() == FORMAT_WaveFormatEx)
|
|
Packit |
47f805 |
if (mtIn->FormatLength() >= sizeof(WAVEFORMATEX))
|
|
Packit |
47f805 |
if (mtIn->IsTemporalCompressed() == FALSE)
|
|
Packit |
47f805 |
return m_Encoder.SetInputType((LPWAVEFORMATEX)mtIn->Format(), true);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return E_INVALIDARG;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// CheckTransform - checks if we can support the transform from this input to this output
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
HRESULT CMpegAudEnc::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if(MEDIATYPE_Stream != mtOut->majortype)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (*mtOut->FormatType() != FORMAT_WaveFormatEx)
|
|
Packit |
47f805 |
return VFW_E_INVALIDMEDIATYPE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (mtOut->FormatLength() < sizeof(WAVEFORMATEX))
|
|
Packit |
47f805 |
return VFW_E_INVALIDMEDIATYPE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
if(FAILED(m_Encoder.GetOutputType(&mec)))
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (((LPWAVEFORMATEX)mtIn->Format())->nSamplesPerSec % mec.dwSampleRate != 0)
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (mec.dwSampleRate != ((LPWAVEFORMATEX)mtOut->Format())->nSamplesPerSec)
|
|
Packit |
47f805 |
return VFW_E_TYPE_NOT_ACCEPTED;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if(mtOut->subtype == MEDIASUBTYPE_MPEG1Audio)
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return VFW_E_TYPE_NOT_ACCEPTED;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// DecideBufferSize - sets output buffers number and size
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
HRESULT CMpegAudEnc::DecideBufferSize(
|
|
Packit |
47f805 |
IMemAllocator* pAllocator,
|
|
Packit |
47f805 |
ALLOCATOR_PROPERTIES* pProperties)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
HRESULT hr = S_OK;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if(m_bStreamOutput)
|
|
Packit |
47f805 |
m_cbStreamAlignment = pProperties->cbAlign;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
///
|
|
Packit |
47f805 |
if (pProperties->cBuffers == 0) pProperties->cBuffers = 1; // If downstream filter didn't suggest a buffer count then default to 1
|
|
Packit |
47f805 |
pProperties->cbBuffer = OUT_BUFFER_SIZE;
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
ASSERT(pProperties->cbBuffer);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
ALLOCATOR_PROPERTIES Actual;
|
|
Packit |
47f805 |
hr = pAllocator->SetProperties(pProperties,&Actual);
|
|
Packit |
47f805 |
if(FAILED(hr))
|
|
Packit |
47f805 |
return hr;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (Actual.cbBuffer < pProperties->cbBuffer ||
|
|
Packit |
47f805 |
Actual.cBuffers < pProperties->cBuffers)
|
|
Packit |
47f805 |
{// can't use this allocator
|
|
Packit |
47f805 |
return E_INVALIDARG;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// GetMediaType - overrideable for suggesting output pin media types
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
HRESULT CMpegAudEnc::GetMediaType(int iPosition, CMediaType *pMediaType)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE,1,TEXT("CMpegAudEnc::GetMediaType()")));
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return m_pOutput->GetMediaType(iPosition, pMediaType);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// Reconnect - called after a manual change has been made to the
|
|
Packit |
47f805 |
// encoder parameters to reset the filter output media type structure
|
|
Packit |
47f805 |
// to match the current encoder out MPEG audio properties
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
HRESULT CMpegAudEnc::Reconnect()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
HRESULT hr = S_FALSE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (m_pOutput && m_pOutput->IsConnected() && m_State == State_Stopped)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
hr = m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if ((hr = m_Encoder.SetOutputType(mec)) == S_OK)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Create an updated output MediaType using the current encoder settings
|
|
Packit |
47f805 |
CMediaType cmt;
|
|
Packit |
47f805 |
cmt.InitMediaType();
|
|
Packit |
47f805 |
m_pOutput->GetMediaType(m_currentMediaTypeIndex, &cmt);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// If the updated MediaType matches the current output MediaType no reconnect is needed
|
|
Packit |
47f805 |
if (m_pOutput->CurrentMediaType() == cmt) return S_OK;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Attempt to reconnect the output pin using the updated MediaType
|
|
Packit |
47f805 |
if (S_OK == (hr = m_pOutput->GetConnected()->QueryAccept(&cmt))) {
|
|
Packit |
47f805 |
hr = m_pOutput->SetMediaType(&cmt);
|
|
Packit |
47f805 |
if ( FAILED(hr) ) { return(hr); }
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
hr = m_pGraph->Reconnect(m_pOutput);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else
|
|
Packit |
47f805 |
hr = m_pOutput->SetMediaType(&cmt);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return hr;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// LoadOutputCapabilities - create a list of the currently supported output
|
|
Packit |
47f805 |
// format capabilities which will be used by the IAMStreamConfig Interface
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
void CMpegAudEnc::LoadOutputCapabilities(DWORD sample_rate)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
m_CapsNum = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Clear out any existing output capabilities
|
|
Packit |
47f805 |
ZeroMemory(OutputCaps, sizeof(OutputCaps));
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Create the set of Constant Bit Rate output capabilities that are
|
|
Packit |
47f805 |
// supported for the current input pin sampling rate.
|
|
Packit |
47f805 |
for (int i = 0; i < NUMELMS(OutputCapabilities); i++) {
|
|
Packit |
47f805 |
if (0 == sample_rate % OutputCapabilities[i].nSampleRate) {
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Add this output capability to the OutputCaps list
|
|
Packit |
47f805 |
OutputCaps[m_CapsNum] = OutputCapabilities[i];
|
|
Packit |
47f805 |
m_CapsNum++;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Don't overrun the hard-coded capabilities array limit
|
|
Packit |
47f805 |
if (m_CapsNum > (int)MAX_IAMSTREAMCONFIG_CAPS) break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// Read persistent configuration from Registry
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
void CMpegAudEnc::ReadPresetSettings(MPEG_ENCODER_CONFIG * pmec)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE,1,TEXT("CMpegAudEnc::ReadPresetSettings()")));
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
Lame::CRegKey rk(HKEY_CURRENT_USER, KEY_LAME_ENCODER);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
pmec->dwBitrate = rk.getDWORD(VALUE_BITRATE,DEFAULT_BITRATE);
|
|
Packit |
47f805 |
pmec->dwVariableMin = rk.getDWORD(VALUE_VARIABLEMIN,DEFAULT_VARIABLEMIN);
|
|
Packit |
47f805 |
pmec->dwVariableMax = rk.getDWORD(VALUE_VARIABLEMAX,DEFAULT_VARIABLEMAX);
|
|
Packit |
47f805 |
pmec->vmVariable = rk.getDWORD(VALUE_VARIABLE, DEFAULT_VARIABLE) ? vbr_rh : vbr_off;
|
|
Packit |
47f805 |
pmec->dwQuality = rk.getDWORD(VALUE_QUALITY,DEFAULT_ENCODING_QUALITY);
|
|
Packit |
47f805 |
pmec->dwVBRq = rk.getDWORD(VALUE_VBR_QUALITY,DEFAULT_VBR_QUALITY);
|
|
Packit |
47f805 |
pmec->lLayer = rk.getDWORD(VALUE_LAYER, DEFAULT_LAYER);
|
|
Packit |
47f805 |
pmec->bCRCProtect = rk.getDWORD(VALUE_CRC, DEFAULT_CRC);
|
|
Packit |
47f805 |
pmec->bForceMono = rk.getDWORD(VALUE_FORCE_MONO, DEFAULT_FORCE_MONO);
|
|
Packit |
47f805 |
pmec->bSetDuration = rk.getDWORD(VALUE_SET_DURATION, DEFAULT_SET_DURATION);
|
|
Packit |
47f805 |
pmec->bSampleOverlap = rk.getDWORD(VALUE_SAMPLE_OVERLAP, DEFAULT_SAMPLE_OVERLAP);
|
|
Packit |
47f805 |
pmec->bCopyright = rk.getDWORD(VALUE_COPYRIGHT, DEFAULT_COPYRIGHT);
|
|
Packit |
47f805 |
pmec->bOriginal = rk.getDWORD(VALUE_ORIGINAL, DEFAULT_ORIGINAL);
|
|
Packit |
47f805 |
pmec->dwSampleRate = rk.getDWORD(VALUE_SAMPLE_RATE, DEFAULT_SAMPLE_RATE);
|
|
Packit |
47f805 |
pmec->dwPES = rk.getDWORD(VALUE_PES, DEFAULT_PES);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
pmec->ChMode = (MPEG_mode)rk.getDWORD(VALUE_STEREO_MODE, DEFAULT_STEREO_MODE);
|
|
Packit |
47f805 |
pmec->dwForceMS = rk.getDWORD(VALUE_FORCE_MS, DEFAULT_FORCE_MS);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
pmec->dwEnforceVBRmin = rk.getDWORD(VALUE_ENFORCE_MIN, DEFAULT_ENFORCE_MIN);
|
|
Packit |
47f805 |
pmec->dwVoiceMode = rk.getDWORD(VALUE_VOICE, DEFAULT_VOICE);
|
|
Packit |
47f805 |
pmec->dwKeepAllFreq = rk.getDWORD(VALUE_KEEP_ALL_FREQ, DEFAULT_KEEP_ALL_FREQ);
|
|
Packit |
47f805 |
pmec->dwStrictISO = rk.getDWORD(VALUE_STRICT_ISO, DEFAULT_STRICT_ISO);
|
|
Packit |
47f805 |
pmec->dwNoShortBlock = rk.getDWORD(VALUE_DISABLE_SHORT_BLOCK, DEFAULT_DISABLE_SHORT_BLOCK);
|
|
Packit |
47f805 |
pmec->dwXingTag = rk.getDWORD(VALUE_XING_TAG, DEFAULT_XING_TAG);
|
|
Packit |
47f805 |
pmec->dwModeFixed = rk.getDWORD(VALUE_MODE_FIXED, DEFAULT_MODE_FIXED);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
rk.Close();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// Property page handling
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
HRESULT CMpegAudEnc::GetPages(CAUUID *pcauuid)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
GUID *pguid;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
pcauuid->cElems = 3;
|
|
Packit |
47f805 |
pcauuid->pElems = pguid = (GUID *) CoTaskMemAlloc(sizeof(GUID) * pcauuid->cElems);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (pcauuid->pElems == NULL)
|
|
Packit |
47f805 |
return E_OUTOFMEMORY;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
pguid[0] = CLSID_LAMEDShow_PropertyPage;
|
|
Packit |
47f805 |
pguid[1] = CLSID_LAMEDShow_PropertyPageAdv;
|
|
Packit |
47f805 |
pguid[2] = CLSID_LAMEDShow_About;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::NonDelegatingQueryInterface(REFIID riid, void ** ppv)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (riid == IID_ISpecifyPropertyPages)
|
|
Packit |
47f805 |
return GetInterface((ISpecifyPropertyPages *) this, ppv);
|
|
Packit |
47f805 |
else if(riid == IID_IPersistStream)
|
|
Packit |
47f805 |
return GetInterface((IPersistStream *)this, ppv);
|
|
Packit |
47f805 |
// else if (riid == IID_IVAudioEncSettings)
|
|
Packit |
47f805 |
// return GetInterface((IVAudioEncSettings*) this, ppv);
|
|
Packit |
47f805 |
else if (riid == IID_IAudioEncoderProperties)
|
|
Packit |
47f805 |
return GetInterface((IAudioEncoderProperties*) this, ppv);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return CTransformFilter::NonDelegatingQueryInterface(riid, ppv);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
//IVAudioEncSettings interface methods
|
|
Packit |
47f805 |
////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// IAudioEncoderProperties
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_PESOutputEnabled(DWORD *dwEnabled)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
*dwEnabled = (DWORD)m_Encoder.IsPES();
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_PESOutputEnabled -> %d"), *dwEnabled));
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_PESOutputEnabled(DWORD dwEnabled)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
m_Encoder.SetPES((BOOL)!!dwEnabled);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_PESOutputEnabled(%d)"), !!dwEnabled));
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_MPEGLayer(DWORD *dwLayer)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwLayer = (DWORD)mec.lLayer;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_MPEGLayer -> %d"), *dwLayer));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_MPEGLayer(DWORD dwLayer)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
if (dwLayer == 2)
|
|
Packit |
47f805 |
mec.lLayer = 2;
|
|
Packit |
47f805 |
else if (dwLayer == 1)
|
|
Packit |
47f805 |
mec.lLayer = 1;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_MPEGLayer(%d)"), dwLayer));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_Bitrate(DWORD *dwBitrate)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwBitrate = (DWORD)mec.dwBitrate;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_Bitrate -> %d"), *dwBitrate));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_Bitrate(DWORD dwBitrate)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.dwBitrate = dwBitrate;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_Bitrate(%d)"), dwBitrate));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_Variable(DWORD *dwVariable)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwVariable = (DWORD)(mec.vmVariable == vbr_off ? 0 : 1);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_Variable -> %d"), *dwVariable));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_Variable(DWORD dwVariable)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
mec.vmVariable = dwVariable ? vbr_rh : vbr_off;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_Variable(%d)"), dwVariable));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_VariableMin(DWORD *dwMin)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwMin = (DWORD)mec.dwVariableMin;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_Variablemin -> %d"), *dwMin));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_VariableMin(DWORD dwMin)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.dwVariableMin = dwMin;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_Variablemin(%d)"), dwMin));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_VariableMax(DWORD *dwMax)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwMax = (DWORD)mec.dwVariableMax;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_Variablemax -> %d"), *dwMax));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_VariableMax(DWORD dwMax)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.dwVariableMax = dwMax;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_Variablemax(%d)"), dwMax));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_Quality(DWORD *dwQuality)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwQuality=(DWORD)mec.dwQuality;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_Quality -> %d"), *dwQuality));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_Quality(DWORD dwQuality)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.dwQuality = dwQuality;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_Quality(%d)"), dwQuality));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_VariableQ(DWORD *dwVBRq)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwVBRq=(DWORD)mec.dwVBRq;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_VariableQ -> %d"), *dwVBRq));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_VariableQ(DWORD dwVBRq)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.dwVBRq = dwVBRq;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_VariableQ(%d)"), dwVBRq));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_SourceSampleRate(DWORD *dwSampleRate)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
*dwSampleRate = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
WAVEFORMATEX wf;
|
|
Packit |
47f805 |
if(FAILED(m_Encoder.GetInputType(&wf)))
|
|
Packit |
47f805 |
return E_FAIL;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
*dwSampleRate = wf.nSamplesPerSec;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_SourceSampleRate -> %d"), *dwSampleRate));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_SourceChannels(DWORD *dwChannels)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
WAVEFORMATEX wf;
|
|
Packit |
47f805 |
if(FAILED(m_Encoder.GetInputType(&wf)))
|
|
Packit |
47f805 |
return E_FAIL;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
*dwChannels = wf.nChannels;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_SourceChannels -> %d"), *dwChannels));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_SampleRate(DWORD *dwSampleRate)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwSampleRate = mec.dwSampleRate;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_SampleRate -> %d"), *dwSampleRate));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_SampleRate(DWORD dwSampleRate)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
DWORD dwOldSampleRate = mec.dwSampleRate;
|
|
Packit |
47f805 |
mec.dwSampleRate = dwSampleRate;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_SampleRate(%d)"), dwSampleRate));
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_ChannelMode(DWORD *dwChannelMode)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwChannelMode = mec.ChMode;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_ChannelMode -> %d"), *dwChannelMode));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_ChannelMode(DWORD dwChannelMode)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.ChMode = (MPEG_mode)dwChannelMode;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_ChannelMode(%d)"), dwChannelMode));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_ForceMS(DWORD *dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwFlag = mec.dwForceMS;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_ForceMS -> %d"), *dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_ForceMS(DWORD dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.dwForceMS = dwFlag;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_ForceMS(%d)"), dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_CRCFlag(DWORD *dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwFlag = mec.bCRCProtect;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_CRCFlag -> %d"), *dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_ForceMono(DWORD *dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwFlag = mec.bForceMono;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_ForceMono -> %d"), *dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_SetDuration(DWORD *dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwFlag = mec.bSetDuration;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_SetDuration -> %d"), *dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_SampleOverlap(DWORD *dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwFlag = mec.bSampleOverlap;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_SampleOverlap -> %d"), *dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_CRCFlag(DWORD dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.bCRCProtect = dwFlag;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_CRCFlag(%d)"), dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_ForceMono(DWORD dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.bForceMono = dwFlag;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_ForceMono(%d)"), dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_SetDuration(DWORD dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.bSetDuration = dwFlag;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_SetDuration(%d)"), dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_SampleOverlap(DWORD dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.bSampleOverlap = dwFlag;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_SampleOverlap(%d)"), dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_EnforceVBRmin(DWORD *dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwFlag = mec.dwEnforceVBRmin;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_EnforceVBRmin -> %d"), *dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_EnforceVBRmin(DWORD dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.dwEnforceVBRmin = dwFlag;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_EnforceVBRmin(%d)"), dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_VoiceMode(DWORD *dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwFlag = mec.dwVoiceMode;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_VoiceMode -> %d"), *dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_VoiceMode(DWORD dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.dwVoiceMode = dwFlag;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_VoiceMode(%d)"), dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_KeepAllFreq(DWORD *dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwFlag = mec.dwKeepAllFreq;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_KeepAllFreq -> %d"), *dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_KeepAllFreq(DWORD dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.dwKeepAllFreq = dwFlag;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_KeepAllFreq(%d)"), dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_StrictISO(DWORD *dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwFlag = mec.dwStrictISO;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_StrictISO -> %d"), *dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_StrictISO(DWORD dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.dwStrictISO = dwFlag;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_StrictISO(%d)"), dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_NoShortBlock(DWORD *dwNoShortBlock)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwNoShortBlock = mec.dwNoShortBlock;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_NoShortBlock -> %d"), *dwNoShortBlock));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_NoShortBlock(DWORD dwNoShortBlock)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.dwNoShortBlock = dwNoShortBlock;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_NoShortBlock(%d)"), dwNoShortBlock));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_XingTag(DWORD *dwXingTag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwXingTag = mec.dwXingTag;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_XingTag -> %d"), *dwXingTag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_XingTag(DWORD dwXingTag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.dwXingTag = dwXingTag;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_XingTag(%d)"), dwXingTag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_OriginalFlag(DWORD *dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwFlag = mec.bOriginal;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_OriginalFlag -> %d"), *dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_OriginalFlag(DWORD dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.bOriginal = dwFlag;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_OriginalFlag(%d)"), dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_CopyrightFlag(DWORD *dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwFlag = mec.bCopyright;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_CopyrightFlag -> %d"), *dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_CopyrightFlag(DWORD dwFlag)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.bCopyright = dwFlag;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_CopyrightFlag(%d)"), dwFlag));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_ModeFixed(DWORD *dwModeFixed)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
*dwModeFixed = mec.dwModeFixed;
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_ModeFixed -> %d"), *dwModeFixed));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_ModeFixed(DWORD dwModeFixed)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
mec.dwModeFixed = dwModeFixed;
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("set_ModeFixed(%d)"), dwModeFixed));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::get_ParameterBlockSize(BYTE *pcBlock, DWORD *pdwSize)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_ParameterBlockSize -> %d%d"), *pcBlock, *pdwSize));
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (pcBlock != NULL) {
|
|
Packit |
47f805 |
if (*pdwSize >= sizeof(MPEG_ENCODER_CONFIG)) {
|
|
Packit |
47f805 |
m_Encoder.GetOutputType((MPEG_ENCODER_CONFIG*)pcBlock);
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else {
|
|
Packit |
47f805 |
*pdwSize = sizeof(MPEG_ENCODER_CONFIG);
|
|
Packit |
47f805 |
return E_FAIL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else if (pdwSize != NULL) {
|
|
Packit |
47f805 |
*pdwSize = sizeof(MPEG_ENCODER_CONFIG);
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return E_FAIL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::set_ParameterBlockSize(BYTE *pcBlock, DWORD dwSize)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("get_ParameterBlockSize(%d, %d)"), *pcBlock, dwSize));
|
|
Packit |
47f805 |
if (sizeof(MPEG_ENCODER_CONFIG) == dwSize){
|
|
Packit |
47f805 |
m_Encoder.SetOutputType(*(MPEG_ENCODER_CONFIG*)pcBlock);
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else return E_FAIL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::DefaultAudioEncoderProperties()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("DefaultAudioEncoderProperties()")));
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
HRESULT hr = InputTypeDefined();
|
|
Packit |
47f805 |
if (FAILED(hr))
|
|
Packit |
47f805 |
return hr;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DWORD dwSourceSampleRate;
|
|
Packit |
47f805 |
get_SourceSampleRate(&dwSourceSampleRate);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
set_PESOutputEnabled(DEFAULT_PES);
|
|
Packit |
47f805 |
set_MPEGLayer(DEFAULT_LAYER);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
set_Bitrate(DEFAULT_BITRATE);
|
|
Packit |
47f805 |
set_Variable(FALSE);
|
|
Packit |
47f805 |
set_VariableMin(DEFAULT_VARIABLEMIN);
|
|
Packit |
47f805 |
set_VariableMax(DEFAULT_VARIABLEMAX);
|
|
Packit |
47f805 |
set_Quality(DEFAULT_ENCODING_QUALITY);
|
|
Packit |
47f805 |
set_VariableQ(DEFAULT_VBR_QUALITY);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
set_SampleRate(dwSourceSampleRate);
|
|
Packit |
47f805 |
set_CRCFlag(DEFAULT_CRC);
|
|
Packit |
47f805 |
set_ForceMono(DEFAULT_FORCE_MONO);
|
|
Packit |
47f805 |
set_SetDuration(DEFAULT_SET_DURATION);
|
|
Packit |
47f805 |
set_SampleOverlap(DEFAULT_SAMPLE_OVERLAP);
|
|
Packit |
47f805 |
set_OriginalFlag(DEFAULT_ORIGINAL);
|
|
Packit |
47f805 |
set_CopyrightFlag(DEFAULT_COPYRIGHT);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
set_EnforceVBRmin(DEFAULT_ENFORCE_MIN);
|
|
Packit |
47f805 |
set_VoiceMode(DEFAULT_VOICE);
|
|
Packit |
47f805 |
set_KeepAllFreq(DEFAULT_KEEP_ALL_FREQ);
|
|
Packit |
47f805 |
set_StrictISO(DEFAULT_STRICT_ISO);
|
|
Packit |
47f805 |
set_NoShortBlock(DEFAULT_DISABLE_SHORT_BLOCK);
|
|
Packit |
47f805 |
set_XingTag(DEFAULT_XING_TAG);
|
|
Packit |
47f805 |
set_ForceMS(DEFAULT_FORCE_MS);
|
|
Packit |
47f805 |
set_ChannelMode(DEFAULT_STEREO_MODE);
|
|
Packit |
47f805 |
set_ModeFixed(DEFAULT_MODE_FIXED);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::LoadAudioEncoderPropertiesFromRegistry()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("LoadAudioEncoderPropertiesFromRegistry()")));
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
ReadPresetSettings(&mec;;
|
|
Packit |
47f805 |
if(m_Encoder.SetOutputType(mec) == S_FALSE)
|
|
Packit |
47f805 |
return S_FALSE;
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::SaveAudioEncoderPropertiesToRegistry()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("SaveAudioEncoderPropertiesToRegistry()")));
|
|
Packit |
47f805 |
Lame::CRegKey rk;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
if(m_Encoder.GetOutputType(&mec) == S_FALSE)
|
|
Packit |
47f805 |
return E_FAIL;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if(rk.Create(HKEY_CURRENT_USER, KEY_LAME_ENCODER))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_BITRATE, mec.dwBitrate);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_VARIABLE, mec.vmVariable);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_VARIABLEMIN, mec.dwVariableMin);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_VARIABLEMAX, mec.dwVariableMax);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_QUALITY, mec.dwQuality);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_VBR_QUALITY, mec.dwVBRq);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_CRC, mec.bCRCProtect);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_FORCE_MONO, mec.bForceMono);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_SET_DURATION, mec.bSetDuration);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_SAMPLE_OVERLAP, mec.bSampleOverlap);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_PES, mec.dwPES);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_COPYRIGHT, mec.bCopyright);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_ORIGINAL, mec.bOriginal);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_SAMPLE_RATE, mec.dwSampleRate);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_STEREO_MODE, mec.ChMode);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_FORCE_MS, mec.dwForceMS);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_XING_TAG, mec.dwXingTag);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_DISABLE_SHORT_BLOCK, mec.dwNoShortBlock);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_STRICT_ISO, mec.dwStrictISO);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_KEEP_ALL_FREQ, mec.dwKeepAllFreq);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_VOICE, mec.dwVoiceMode);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_ENFORCE_MIN, mec.dwEnforceVBRmin);
|
|
Packit |
47f805 |
rk.setDWORD(VALUE_MODE_FIXED, mec.dwModeFixed);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
rk.Close();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Reconnect filter graph
|
|
Packit |
47f805 |
Reconnect();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::InputTypeDefined()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
WAVEFORMATEX wf;
|
|
Packit |
47f805 |
if(FAILED(m_Encoder.GetInputType(&wf)))
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("!InputTypeDefined()")));
|
|
Packit |
47f805 |
return E_FAIL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE, 1, TEXT("InputTypeDefined()")));
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::ApplyChanges()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
return Reconnect();
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
// CPersistStream stuff
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// what is our class ID?
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEnc::GetClassID(CLSID *pClsid)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
CheckPointer(pClsid, E_POINTER);
|
|
Packit |
47f805 |
*pClsid = CLSID_LAMEDShowFilter;
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
HRESULT CMpegAudEnc::WriteToStream(IStream *pStream)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE,1,TEXT("WriteToStream()")));
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if(m_Encoder.GetOutputType(&mec) == S_FALSE)
|
|
Packit |
47f805 |
return E_FAIL;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return pStream->Write(&mec, sizeof(mec), 0);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// what device should we use? Used to re-create a .GRF file that we
|
|
Packit |
47f805 |
// are in
|
|
Packit |
47f805 |
HRESULT CMpegAudEnc::ReadFromStream(IStream *pStream)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
HRESULT hr = pStream->Read(&mec, sizeof(mec), 0);
|
|
Packit |
47f805 |
if(FAILED(hr))
|
|
Packit |
47f805 |
return hr;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if(m_Encoder.SetOutputType(mec) == S_FALSE)
|
|
Packit |
47f805 |
return S_FALSE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DbgLog((LOG_TRACE,1,TEXT("ReadFromStream() succeeded")));
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
hr = S_OK;
|
|
Packit |
47f805 |
return hr;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// How long is our data?
|
|
Packit |
47f805 |
int CMpegAudEnc::SizeMax()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
return sizeof(MPEG_ENCODER_CONFIG);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// CMpegAudEncOutPin is the one and only output pin of CMpegAudEnc
|
|
Packit |
47f805 |
//
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
CMpegAudEncOutPin::CMpegAudEncOutPin( CMpegAudEnc * pFilter, HRESULT * pHr ) :
|
|
Packit |
47f805 |
CTransformOutputPin( NAME("LameEncoderOutputPin"), pFilter, pHr, L"Output\0" ),
|
|
Packit |
47f805 |
m_pFilter(pFilter)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
m_SetFormat = FALSE;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
CMpegAudEncOutPin::~CMpegAudEncOutPin()
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
STDMETHODIMP CMpegAudEncOutPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if(riid == IID_IAMStreamConfig) {
|
|
Packit |
47f805 |
CheckPointer(ppv, E_POINTER);
|
|
Packit |
47f805 |
return GetInterface((IAMStreamConfig*)(this), ppv);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// This is called after the output format has been negotiated and
|
|
Packit |
47f805 |
// will update the LAME encoder settings so that it matches the
|
|
Packit |
47f805 |
// settings specified in the MediaType structure.
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
HRESULT CMpegAudEncOutPin::SetMediaType(const CMediaType *pmt)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Retrieve the current LAME encoder configuration
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_pFilter->m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Annotate if we are using the MEDIATYPE_Stream output type
|
|
Packit |
47f805 |
m_pFilter->m_bStreamOutput = (pmt->majortype == MEDIATYPE_Stream);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (pmt->majortype == MEDIATYPE_Stream) {
|
|
Packit |
47f805 |
// Update the encoder configuration using the settings that were
|
|
Packit |
47f805 |
// cached in the CMpegAudEncOutPin::GetMediaType() call
|
|
Packit |
47f805 |
mec.dwSampleRate = m_CurrentOutputFormat.nSampleRate;
|
|
Packit |
47f805 |
mec.dwBitrate = m_CurrentOutputFormat.nBitRate;
|
|
Packit |
47f805 |
mec.ChMode = m_CurrentOutputFormat.ChMode;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else {
|
|
Packit |
47f805 |
// Update the encoder configuration directly using the values
|
|
Packit |
47f805 |
// passed via the CMediaType structure.
|
|
Packit |
47f805 |
MPEGLAYER3WAVEFORMAT *pfmt = (MPEGLAYER3WAVEFORMAT*) pmt->Format();
|
|
Packit |
47f805 |
mec.dwSampleRate = pfmt->wfx.nSamplesPerSec;
|
|
Packit |
47f805 |
mec.dwBitrate = pfmt->wfx.nAvgBytesPerSec * 8 / 1000;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (pfmt->wfx.nChannels == 1) { mec.ChMode = MONO; }
|
|
Packit |
47f805 |
else if (pfmt->wfx.nChannels == 2 && mec.ChMode == MONO && !mec.bForceMono) { mec.ChMode = STEREO; }
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
m_pFilter->m_Encoder.SetOutputType(mec);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Now configure this MediaType on the output pin
|
|
Packit |
47f805 |
HRESULT hr = CTransformOutputPin::SetMediaType(pmt);
|
|
Packit |
47f805 |
return hr;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// Retrieve the various MediaTypes that match the advertised formats
|
|
Packit |
47f805 |
// supported on the output pin and configure an AM_MEDIA_TYPE output
|
|
Packit |
47f805 |
// structure that is based on the selected format.
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
HRESULT CMpegAudEncOutPin::GetMediaType(int iPosition, CMediaType *pmt)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (iPosition < 0) return E_INVALIDARG;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// If iPosition equals zero then we always return the currently configured MediaType
|
|
Packit |
47f805 |
if (iPosition == 0) {
|
|
Packit |
47f805 |
*pmt = m_mt;
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
switch (iPosition)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
case 1:
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
pmt->SetType(&MEDIATYPE_Audio);
|
|
Packit |
47f805 |
pmt->SetSubtype(&MEDIASUBTYPE_MP3);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
case 2:
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
pmt->SetType(&MEDIATYPE_Stream);
|
|
Packit |
47f805 |
pmt->SetSubtype(&MEDIASUBTYPE_MPEG1Audio);
|
|
Packit |
47f805 |
pmt->SetFormatType(&GUID_NULL);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
case 3:
|
|
Packit |
47f805 |
{ // The last case that we evaluate is the MPEG2_PES format, but if the
|
|
Packit |
47f805 |
// encoder isn't configured for it then just return VFW_S_NO_MORE_ITEMS
|
|
Packit |
47f805 |
if ( !m_pFilter->m_Encoder.IsPES() ) { return VFW_S_NO_MORE_ITEMS; }
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
pmt->SetType(&MEDIATYPE_MPEG2_PES);
|
|
Packit |
47f805 |
pmt->SetSubtype(&MEDIASUBTYPE_MPEG2_AUDIO);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
default:
|
|
Packit |
47f805 |
return VFW_S_NO_MORE_ITEMS;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Output capabilities are dependent on the input so insure it is connected
|
|
Packit |
47f805 |
if ( !m_pFilter->m_pInput->IsConnected() ) {
|
|
Packit |
47f805 |
pmt->SetFormatType(&FORMAT_None);
|
|
Packit |
47f805 |
return NOERROR;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Annotate the current MediaType index for recall in CMpegAudEnc::Reconnect()
|
|
Packit |
47f805 |
m_pFilter->m_currentMediaTypeIndex = iPosition;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Configure the remaining AM_MEDIA_TYPE parameters using the cached encoder settings.
|
|
Packit |
47f805 |
// Since MEDIATYPE_Stream doesn't have a format block the current settings
|
|
Packit |
47f805 |
// for CHANNEL MODE, BITRATE and SAMPLERATE are cached in m_CurrentOutputFormat for use
|
|
Packit |
47f805 |
// when we setup the LAME encoder in the call to CMpegAudEncOutPin::SetMediaType()
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_pFilter->m_Encoder.GetOutputType(&mec;; // Retrieve the current encoder config
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
WAVEFORMATEX wf; // Retrieve the input configuration
|
|
Packit |
47f805 |
m_pFilter->m_Encoder.GetInputType(&wf);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Use the current encoder sample rate unless it isn't a modulus of the input rate
|
|
Packit |
47f805 |
if ((wf.nSamplesPerSec % mec.dwSampleRate) == 0) {
|
|
Packit |
47f805 |
m_CurrentOutputFormat.nSampleRate = mec.dwSampleRate;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else {
|
|
Packit |
47f805 |
m_CurrentOutputFormat.nSampleRate = wf.nSamplesPerSec;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Select the output channel config based on the encoder config and input channel count
|
|
Packit |
47f805 |
m_CurrentOutputFormat.ChMode = mec.ChMode;
|
|
Packit |
47f805 |
switch (wf.nChannels) // Determine if we need to alter ChMode based upon the channel count and ForceMono flag
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
case 1:
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
m_CurrentOutputFormat.ChMode = MONO;
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
case 2:
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
if (mec.ChMode == MONO && !mec.bForceMono) { m_CurrentOutputFormat.ChMode = STEREO; }
|
|
Packit |
47f805 |
else if ( mec.bForceMono ) { m_CurrentOutputFormat.ChMode = MONO; }
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Select the encoder bit rate. In VBR mode we set the data rate parameter
|
|
Packit |
47f805 |
// of the WAVE_FORMAT_MPEGLAYER3 structure to the minimum VBR value
|
|
Packit |
47f805 |
m_CurrentOutputFormat.nBitRate = (mec.vmVariable == vbr_off) ? mec.dwBitrate : mec.dwVariableMin;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (pmt->majortype == MEDIATYPE_Stream) return NOERROR; // No further config required for MEDIATYPE_Stream
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Now configure the remainder of the WAVE_FORMAT_MPEGLAYER3 format block
|
|
Packit |
47f805 |
// and its parent AM_MEDIA_TYPE structure
|
|
Packit |
47f805 |
DECLARE_PTR(MPEGLAYER3WAVEFORMAT, p_mp3wvfmt, pmt->AllocFormatBuffer(sizeof(MPEGLAYER3WAVEFORMAT)));
|
|
Packit |
47f805 |
ZeroMemory(p_mp3wvfmt, sizeof(MPEGLAYER3WAVEFORMAT));
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
p_mp3wvfmt->wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
|
|
Packit |
47f805 |
p_mp3wvfmt->wfx.nChannels = (m_CurrentOutputFormat.ChMode == MONO) ? 1 : 2;
|
|
Packit |
47f805 |
p_mp3wvfmt->wfx.nSamplesPerSec = m_CurrentOutputFormat.nSampleRate;
|
|
Packit |
47f805 |
p_mp3wvfmt->wfx.nAvgBytesPerSec = GET_DATARATE(m_CurrentOutputFormat.nBitRate);
|
|
Packit |
47f805 |
p_mp3wvfmt->wfx.nBlockAlign = 1;
|
|
Packit |
47f805 |
p_mp3wvfmt->wfx.wBitsPerSample = 0;
|
|
Packit |
47f805 |
p_mp3wvfmt->wfx.cbSize = sizeof(MPEGLAYER3WAVEFORMAT) - sizeof(WAVEFORMATEX);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
p_mp3wvfmt->wID = MPEGLAYER3_ID_MPEG;
|
|
Packit |
47f805 |
p_mp3wvfmt->fdwFlags = MPEGLAYER3_FLAG_PADDING_ISO;
|
|
Packit |
47f805 |
p_mp3wvfmt->nBlockSize = GET_FRAMELENGTH(m_CurrentOutputFormat.nBitRate, p_mp3wvfmt->wfx.nSamplesPerSec);
|
|
Packit |
47f805 |
p_mp3wvfmt->nFramesPerBlock = 1;
|
|
Packit |
47f805 |
p_mp3wvfmt->nCodecDelay = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
pmt->SetTemporalCompression(FALSE);
|
|
Packit |
47f805 |
pmt->SetSampleSize(OUT_BUFFER_SIZE);
|
|
Packit |
47f805 |
pmt->SetFormat((LPBYTE)p_mp3wvfmt, sizeof(MPEGLAYER3WAVEFORMAT));
|
|
Packit |
47f805 |
pmt->SetFormatType(&FORMAT_WaveFormatEx);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return NOERROR;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// This method is called to see if a given output format is supported
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
HRESULT CMpegAudEncOutPin::CheckMediaType(const CMediaType *pmtOut)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Fail if the input pin is not connected.
|
|
Packit |
47f805 |
if (!m_pFilter->m_pInput->IsConnected()) {
|
|
Packit |
47f805 |
return VFW_E_NOT_CONNECTED;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Reject any media types that we know in advance our
|
|
Packit |
47f805 |
// filter cannot use.
|
|
Packit |
47f805 |
if (pmtOut->majortype != MEDIATYPE_Audio && pmtOut->majortype != MEDIATYPE_Stream) { return S_FALSE; }
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// If SetFormat was previously called, check whether pmtOut exactly
|
|
Packit |
47f805 |
// matches the format that was specified in SetFormat.
|
|
Packit |
47f805 |
// Return S_OK if they match, or VFW_E_INVALIDMEDIATYPE otherwise.)
|
|
Packit |
47f805 |
if ( m_SetFormat ) {
|
|
Packit |
47f805 |
if (*pmtOut != m_mt) { return VFW_E_INVALIDMEDIATYPE; }
|
|
Packit |
47f805 |
else { return S_OK; }
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Now do the normal check for this media type.
|
|
Packit |
47f805 |
HRESULT hr;
|
|
Packit |
47f805 |
hr = m_pFilter->CheckTransform (&m_pFilter->m_pInput->CurrentMediaType(), // The input type.
|
|
Packit |
47f805 |
pmtOut); // The proposed output type.
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (hr == S_OK) {
|
|
Packit |
47f805 |
return S_OK; // This format is compatible with the current input type.
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// This format is not compatible with the current input type.
|
|
Packit |
47f805 |
// Maybe we can reconnect the input pin with a new input type.
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Enumerate the upstream filter's preferred output types, and
|
|
Packit |
47f805 |
// see if one of them will work.
|
|
Packit |
47f805 |
CMediaType *pmtEnum;
|
|
Packit |
47f805 |
BOOL fFound = FALSE;
|
|
Packit |
47f805 |
IEnumMediaTypes *pEnum;
|
|
Packit |
47f805 |
hr = m_pFilter->m_pInput->GetConnected()->EnumMediaTypes(&pEnum);
|
|
Packit |
47f805 |
if (hr != S_OK) {
|
|
Packit |
47f805 |
return E_FAIL;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
while (hr = pEnum->Next(1, (AM_MEDIA_TYPE **)&pmtEnum, NULL), hr == S_OK)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// Check this input type against the proposed output type.
|
|
Packit |
47f805 |
hr = m_pFilter->CheckTransform(pmtEnum, pmtOut);
|
|
Packit |
47f805 |
if (hr != S_OK) {
|
|
Packit |
47f805 |
DeleteMediaType(pmtEnum);
|
|
Packit |
47f805 |
continue; // Try the next one.
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// This input type is a possible candidate. But, we have to make
|
|
Packit |
47f805 |
// sure that the upstream filter can switch to this type.
|
|
Packit |
47f805 |
hr = m_pFilter->m_pInput->GetConnected()->QueryAccept(pmtEnum);
|
|
Packit |
47f805 |
if (hr != S_OK) {
|
|
Packit |
47f805 |
// The upstream filter will not switch to this type.
|
|
Packit |
47f805 |
DeleteMediaType(pmtEnum);
|
|
Packit |
47f805 |
continue; // Try the next one.
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
fFound = TRUE;
|
|
Packit |
47f805 |
DeleteMediaType(pmtEnum);
|
|
Packit |
47f805 |
break;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
pEnum->Release();
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (fFound) {
|
|
Packit |
47f805 |
// This output type is OK, but if we are asked to use it, we will
|
|
Packit |
47f805 |
// need to reconnect our input pin. (See SetFormat, below.)
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
else {
|
|
Packit |
47f805 |
return VFW_E_INVALIDMEDIATYPE;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
// IAMStreamConfig
|
|
Packit |
47f805 |
//////////////////////////////////////////////////////////////////////////
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
HRESULT STDMETHODCALLTYPE CMpegAudEncOutPin::SetFormat(AM_MEDIA_TYPE *pmt)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
CheckPointer(pmt, E_POINTER);
|
|
Packit |
47f805 |
HRESULT hr;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Hold the filter state lock, to make sure that streaming isn't
|
|
Packit |
47f805 |
// in the middle of starting or stopping:
|
|
Packit |
47f805 |
CAutoLock cObjectLock(&m_pFilter->m_csFilter);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Cannot set the format unless the filter is stopped.
|
|
Packit |
47f805 |
if (m_pFilter->m_State != State_Stopped) {
|
|
Packit |
47f805 |
return VFW_E_NOT_STOPPED;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// The set of possible output formats depends on the input format,
|
|
Packit |
47f805 |
// so if the input pin is not connected, return a failure code.
|
|
Packit |
47f805 |
if (!m_pFilter->m_pInput->IsConnected()) {
|
|
Packit |
47f805 |
return VFW_E_NOT_CONNECTED;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// If the pin is already using this format, there's nothing to do.
|
|
Packit |
47f805 |
if (IsConnected() && CurrentMediaType() == *pmt) {
|
|
Packit |
47f805 |
if ( m_SetFormat ) return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// See if this media type is acceptable.
|
|
Packit |
47f805 |
if ((hr = CheckMediaType((CMediaType *)pmt)) != S_OK) {
|
|
Packit |
47f805 |
return hr;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// If we're connected to a downstream filter, we have to make
|
|
Packit |
47f805 |
// sure that the downstream filter accepts this media type.
|
|
Packit |
47f805 |
if (IsConnected()) {
|
|
Packit |
47f805 |
hr = GetConnected()->QueryAccept(pmt);
|
|
Packit |
47f805 |
if (hr != S_OK) {
|
|
Packit |
47f805 |
return VFW_E_INVALIDMEDIATYPE;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Now make a note that from now on, this is the only format allowed,
|
|
Packit |
47f805 |
// and refuse anything but this in the CheckMediaType() code above.
|
|
Packit |
47f805 |
m_SetFormat = TRUE;
|
|
Packit |
47f805 |
m_mt = *pmt;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Changing the format means reconnecting if necessary.
|
|
Packit |
47f805 |
if (IsConnected()) {
|
|
Packit |
47f805 |
m_pFilter->m_pGraph->Reconnect(this);
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return NOERROR;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
HRESULT STDMETHODCALLTYPE CMpegAudEncOutPin::GetFormat(AM_MEDIA_TYPE **ppmt)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
*ppmt = CreateMediaType(&m_mt);
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
HRESULT STDMETHODCALLTYPE CMpegAudEncOutPin::GetNumberOfCapabilities(int *piCount, int *piSize)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// The set of possible output formats depends on the input format,
|
|
Packit |
47f805 |
// so if the input pin is not connected, return a failure code.
|
|
Packit |
47f805 |
if (!m_pFilter->m_pInput->IsConnected()) {
|
|
Packit |
47f805 |
return VFW_E_NOT_CONNECTED;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Retrieve the current encoder configuration
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_pFilter->m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// If the encoder is in VBR mode GetStreamCaps() isn't implemented
|
|
Packit |
47f805 |
if (mec.vmVariable != vbr_off) { *piCount = 0; }
|
|
Packit |
47f805 |
else { *piCount = m_pFilter->m_CapsNum; }
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
*piSize = sizeof(AUDIO_STREAM_CONFIG_CAPS);
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
HRESULT STDMETHODCALLTYPE CMpegAudEncOutPin::GetStreamCaps(int iIndex, AM_MEDIA_TYPE **pmt, BYTE *pSCC)
|
|
Packit |
47f805 |
{
|
|
Packit |
47f805 |
// The set of possible output formats depends on the input format,
|
|
Packit |
47f805 |
// so if the input pin is not connected, return a failure code.
|
|
Packit |
47f805 |
if (!m_pFilter->m_pInput->IsConnected()) {
|
|
Packit |
47f805 |
return VFW_E_NOT_CONNECTED;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// If we don't have a capabilities array GetStreamCaps() isn't implemented
|
|
Packit |
47f805 |
if (m_pFilter->m_CapsNum == 0) return E_NOTIMPL;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// If the encoder is in VBR mode GetStreamCaps() isn't implemented
|
|
Packit |
47f805 |
MPEG_ENCODER_CONFIG mec;
|
|
Packit |
47f805 |
m_pFilter->m_Encoder.GetOutputType(&mec;;
|
|
Packit |
47f805 |
if (mec.vmVariable != vbr_off) return E_NOTIMPL;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
if (iIndex < 0) return E_INVALIDARG;
|
|
Packit |
47f805 |
if (iIndex > m_pFilter->m_CapsNum) return S_FALSE;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Load the MPEG Layer3 WaveFormatEx structure with the appropriate entries
|
|
Packit |
47f805 |
// for this IAMStreamConfig index element.
|
|
Packit |
47f805 |
*pmt = CreateMediaType(&m_mt);
|
|
Packit |
47f805 |
if (*pmt == NULL) return E_OUTOFMEMORY;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
DECLARE_PTR(MPEGLAYER3WAVEFORMAT, p_mp3wvfmt, (*pmt)->pbFormat);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
(*pmt)->majortype = MEDIATYPE_Audio;
|
|
Packit |
47f805 |
(*pmt)->subtype = MEDIASUBTYPE_MP3;
|
|
Packit |
47f805 |
(*pmt)->bFixedSizeSamples = TRUE;
|
|
Packit |
47f805 |
(*pmt)->bTemporalCompression = FALSE;
|
|
Packit |
47f805 |
(*pmt)->lSampleSize = OUT_BUFFER_SIZE;
|
|
Packit |
47f805 |
(*pmt)->formattype = FORMAT_WaveFormatEx;
|
|
Packit |
47f805 |
(*pmt)->cbFormat = sizeof(MPEGLAYER3WAVEFORMAT);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
p_mp3wvfmt->wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3;
|
|
Packit |
47f805 |
p_mp3wvfmt->wfx.nChannels = 2;
|
|
Packit |
47f805 |
p_mp3wvfmt->wfx.nSamplesPerSec = m_pFilter->OutputCaps[iIndex].nSampleRate;
|
|
Packit |
47f805 |
p_mp3wvfmt->wfx.nAvgBytesPerSec = GET_DATARATE(m_pFilter->OutputCaps[iIndex].nBitRate);
|
|
Packit |
47f805 |
p_mp3wvfmt->wfx.nBlockAlign = 1;
|
|
Packit |
47f805 |
p_mp3wvfmt->wfx.wBitsPerSample = 0;
|
|
Packit |
47f805 |
p_mp3wvfmt->wfx.cbSize = sizeof(MPEGLAYER3WAVEFORMAT) - sizeof(WAVEFORMATEX);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
p_mp3wvfmt->wID = MPEGLAYER3_ID_MPEG;
|
|
Packit |
47f805 |
p_mp3wvfmt->fdwFlags = MPEGLAYER3_FLAG_PADDING_ISO;
|
|
Packit |
47f805 |
p_mp3wvfmt->nBlockSize = GET_FRAMELENGTH(m_pFilter->OutputCaps[iIndex].nBitRate, m_pFilter->OutputCaps[iIndex].nSampleRate);
|
|
Packit |
47f805 |
p_mp3wvfmt->nFramesPerBlock = 1;
|
|
Packit |
47f805 |
p_mp3wvfmt->nCodecDelay = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
// Set up the companion AUDIO_STREAM_CONFIG_CAPS structure
|
|
Packit |
47f805 |
// We are only using the CHANNELS element of the structure
|
|
Packit |
47f805 |
DECLARE_PTR(AUDIO_STREAM_CONFIG_CAPS, pascc, pSCC);
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
ZeroMemory(pascc, sizeof(AUDIO_STREAM_CONFIG_CAPS));
|
|
Packit |
47f805 |
pascc->guid = MEDIATYPE_Audio;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
pascc->MinimumChannels = 1;
|
|
Packit |
47f805 |
pascc->MaximumChannels = 2;
|
|
Packit |
47f805 |
pascc->ChannelsGranularity = 1;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
pascc->MinimumSampleFrequency = p_mp3wvfmt->wfx.nSamplesPerSec;
|
|
Packit |
47f805 |
pascc->MaximumSampleFrequency = p_mp3wvfmt->wfx.nSamplesPerSec;
|
|
Packit |
47f805 |
pascc->SampleFrequencyGranularity = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
pascc->MinimumBitsPerSample = p_mp3wvfmt->wfx.wBitsPerSample;
|
|
Packit |
47f805 |
pascc->MaximumBitsPerSample = p_mp3wvfmt->wfx.wBitsPerSample;
|
|
Packit |
47f805 |
pascc->BitsPerSampleGranularity = 0;
|
|
Packit |
47f805 |
|
|
Packit |
47f805 |
return S_OK;
|
|
Packit |
47f805 |
}
|
|
Packit |
47f805 |
|