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