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 <mmreg.h>
24159b3361Sopenharmony_ci#include "Encoder.h"
25159b3361Sopenharmony_ci
26159b3361Sopenharmony_ci#define KEY_LAME_ENCODER            "SOFTWARE\\GNU\\LAME MPEG Layer III Audio Encoder Filter"
27159b3361Sopenharmony_ci
28159b3361Sopenharmony_ci#define VALUE_BITRATE               "Bitrate"
29159b3361Sopenharmony_ci#define VALUE_VARIABLE              "Variable"
30159b3361Sopenharmony_ci#define VALUE_VARIABLEMIN           "VariableMin"
31159b3361Sopenharmony_ci#define VALUE_VARIABLEMAX           "VariableMax"
32159b3361Sopenharmony_ci#define VALUE_QUALITY               "Quality"
33159b3361Sopenharmony_ci#define VALUE_VBR_QUALITY           "VBR Quality"
34159b3361Sopenharmony_ci#define VALUE_SAMPLE_RATE           "Sample Rate"
35159b3361Sopenharmony_ci
36159b3361Sopenharmony_ci#define VALUE_STEREO_MODE           "Stereo Mode"
37159b3361Sopenharmony_ci#define VALUE_FORCE_MS              "Force MS"
38159b3361Sopenharmony_ci
39159b3361Sopenharmony_ci#define VALUE_LAYER                 "Layer"
40159b3361Sopenharmony_ci#define VALUE_ORIGINAL              "Original"
41159b3361Sopenharmony_ci#define VALUE_COPYRIGHT             "Copyright"
42159b3361Sopenharmony_ci#define VALUE_CRC                   "CRC"
43159b3361Sopenharmony_ci#define VALUE_FORCE_MONO            "Force Mono"
44159b3361Sopenharmony_ci#define VALUE_SET_DURATION          "Set Duration"
45159b3361Sopenharmony_ci#define VALUE_SAMPLE_OVERLAP        "Allow sample overlap"
46159b3361Sopenharmony_ci#define VALUE_PES                   "PES"
47159b3361Sopenharmony_ci
48159b3361Sopenharmony_ci#define VALUE_ENFORCE_MIN           "EnforceVBRmin"
49159b3361Sopenharmony_ci#define VALUE_VOICE                 "Voice Mode"
50159b3361Sopenharmony_ci#define VALUE_KEEP_ALL_FREQ         "Keep All Frequencies"
51159b3361Sopenharmony_ci#define VALUE_STRICT_ISO            "Strict ISO"
52159b3361Sopenharmony_ci#define VALUE_DISABLE_SHORT_BLOCK   "No Short Block"
53159b3361Sopenharmony_ci#define VALUE_XING_TAG              "Xing Tag"
54159b3361Sopenharmony_ci#define VALUE_MODE_FIXED            "Mode Fixed"
55159b3361Sopenharmony_ci
56159b3361Sopenharmony_ci
57159b3361Sopenharmony_citypedef struct
58159b3361Sopenharmony_ci{
59159b3361Sopenharmony_ci    DWORD      nSampleRate;
60159b3361Sopenharmony_ci    DWORD      nBitRate;
61159b3361Sopenharmony_ci    MPEG_mode  ChMode;                       //Channel coding mode
62159b3361Sopenharmony_ci} current_output_format_t;
63159b3361Sopenharmony_ci
64159b3361Sopenharmony_citypedef struct
65159b3361Sopenharmony_ci{
66159b3361Sopenharmony_ci    DWORD   nSampleRate;
67159b3361Sopenharmony_ci    DWORD   nBitRate;
68159b3361Sopenharmony_ci} output_caps_t;
69159b3361Sopenharmony_ci
70159b3361Sopenharmony_citypedef struct
71159b3361Sopenharmony_ci{
72159b3361Sopenharmony_ci    LONGLONG        sample;
73159b3361Sopenharmony_ci    REFERENCE_TIME  delta;
74159b3361Sopenharmony_ci
75159b3361Sopenharmony_ci    BOOL            applied;
76159b3361Sopenharmony_ci} resync_point_t;
77159b3361Sopenharmony_ci
78159b3361Sopenharmony_ci#define RESYNC_COUNT    4
79159b3361Sopenharmony_ci
80159b3361Sopenharmony_ci// The maximum number of capabilities that we can expose in our IAMStreamConfig
81159b3361Sopenharmony_ci// implementation is currently set to 100. This number is larger than we
82159b3361Sopenharmony_ci// should ever realistically need. However, a cleaner implementation might
83159b3361Sopenharmony_ci// be to use a dynamically sized array like std::vector or CAtlArray to
84159b3361Sopenharmony_ci// hold this data.
85159b3361Sopenharmony_ci#define MAX_IAMSTREAMCONFIG_CAPS 100
86159b3361Sopenharmony_ci
87159b3361Sopenharmony_ci///////////////////////////////////////////////////////////////////
88159b3361Sopenharmony_ci// CMpegAudEnc class - implementation for ITransformFilter interface
89159b3361Sopenharmony_ci///////////////////////////////////////////////////////////////////
90159b3361Sopenharmony_ciclass CMpegAudEncOutPin;
91159b3361Sopenharmony_ciclass CMpegAudEncPropertyPage;
92159b3361Sopenharmony_ciclass CMpegAudEnc : public CTransformFilter,
93159b3361Sopenharmony_ci                    public ISpecifyPropertyPages,
94159b3361Sopenharmony_ci                    public IAudioEncoderProperties,
95159b3361Sopenharmony_ci                    public CPersistStream
96159b3361Sopenharmony_ci{
97159b3361Sopenharmony_cipublic:
98159b3361Sopenharmony_ci    DECLARE_IUNKNOWN
99159b3361Sopenharmony_ci
100159b3361Sopenharmony_ci    static CUnknown *CreateInstance(LPUNKNOWN lpunk, HRESULT *phr);
101159b3361Sopenharmony_ci
102159b3361Sopenharmony_ci    LPAMOVIESETUP_FILTER GetSetupData();
103159b3361Sopenharmony_ci
104159b3361Sopenharmony_ci    HRESULT Reconnect();
105159b3361Sopenharmony_ci
106159b3361Sopenharmony_ci    HRESULT Receive(IMediaSample *pSample);
107159b3361Sopenharmony_ci
108159b3361Sopenharmony_ci    HRESULT CheckInputType(const CMediaType* mtIn);
109159b3361Sopenharmony_ci    HRESULT CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut);
110159b3361Sopenharmony_ci    HRESULT DecideBufferSize(IMemAllocator * pAllocator, ALLOCATOR_PROPERTIES *pProperties);
111159b3361Sopenharmony_ci
112159b3361Sopenharmony_ci    HRESULT GetMediaType  (int iPosition, CMediaType *pMediaType);
113159b3361Sopenharmony_ci    HRESULT SetMediaType  (PIN_DIRECTION direction,const CMediaType *pmt);
114159b3361Sopenharmony_ci
115159b3361Sopenharmony_ci
116159b3361Sopenharmony_ci    //
117159b3361Sopenharmony_ci    HRESULT StartStreaming();
118159b3361Sopenharmony_ci    HRESULT StopStreaming();
119159b3361Sopenharmony_ci    HRESULT EndOfStream();
120159b3361Sopenharmony_ci    HRESULT BeginFlush();
121159b3361Sopenharmony_ci
122159b3361Sopenharmony_ci    ~CMpegAudEnc(void);
123159b3361Sopenharmony_ci
124159b3361Sopenharmony_ci    // ISpecifyPropertyPages
125159b3361Sopenharmony_ci    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
126159b3361Sopenharmony_ci    STDMETHODIMP GetPages(CAUUID *pcauuid);
127159b3361Sopenharmony_ci
128159b3361Sopenharmony_ci    // IAudioEncoderProperties
129159b3361Sopenharmony_ci    STDMETHODIMP get_PESOutputEnabled(DWORD *dwEnabled);    // PES header. Obsolete
130159b3361Sopenharmony_ci    STDMETHODIMP set_PESOutputEnabled(DWORD dwEnabled);     // PES header. Obsolete
131159b3361Sopenharmony_ci
132159b3361Sopenharmony_ci    STDMETHODIMP get_MPEGLayer(DWORD *dwLayer);
133159b3361Sopenharmony_ci    STDMETHODIMP set_MPEGLayer(DWORD dwLayer);
134159b3361Sopenharmony_ci
135159b3361Sopenharmony_ci    STDMETHODIMP get_Bitrate(DWORD *dwBitrate);
136159b3361Sopenharmony_ci    STDMETHODIMP set_Bitrate(DWORD dwBitrate);
137159b3361Sopenharmony_ci    STDMETHODIMP get_Variable(DWORD *dwVariable);
138159b3361Sopenharmony_ci    STDMETHODIMP set_Variable(DWORD dwVariable);
139159b3361Sopenharmony_ci    STDMETHODIMP get_VariableMin(DWORD *dwMin);
140159b3361Sopenharmony_ci    STDMETHODIMP set_VariableMin(DWORD dwMin);
141159b3361Sopenharmony_ci    STDMETHODIMP get_VariableMax(DWORD *dwMax);
142159b3361Sopenharmony_ci    STDMETHODIMP set_VariableMax(DWORD dwMax);
143159b3361Sopenharmony_ci    STDMETHODIMP get_Quality(DWORD *dwQuality);
144159b3361Sopenharmony_ci    STDMETHODIMP set_Quality(DWORD dwQuality);
145159b3361Sopenharmony_ci    STDMETHODIMP get_VariableQ(DWORD *dwVBRq);
146159b3361Sopenharmony_ci    STDMETHODIMP set_VariableQ(DWORD dwVBRq);
147159b3361Sopenharmony_ci    STDMETHODIMP get_SourceSampleRate(DWORD *dwSampleRate);
148159b3361Sopenharmony_ci    STDMETHODIMP get_SourceChannels(DWORD *dwChannels);
149159b3361Sopenharmony_ci    STDMETHODIMP get_SampleRate(DWORD *dwSampleRate);
150159b3361Sopenharmony_ci    STDMETHODIMP set_SampleRate(DWORD dwSampleRate);
151159b3361Sopenharmony_ci
152159b3361Sopenharmony_ci    STDMETHODIMP get_ChannelMode(DWORD *dwChannelMode);
153159b3361Sopenharmony_ci    STDMETHODIMP set_ChannelMode(DWORD dwChannelMode);
154159b3361Sopenharmony_ci    STDMETHODIMP get_ForceMS(DWORD *dwFlag);
155159b3361Sopenharmony_ci    STDMETHODIMP set_ForceMS(DWORD dwFlag);
156159b3361Sopenharmony_ci    STDMETHODIMP get_EnforceVBRmin(DWORD *dwFlag);
157159b3361Sopenharmony_ci    STDMETHODIMP set_EnforceVBRmin(DWORD dwFlag);
158159b3361Sopenharmony_ci    STDMETHODIMP get_VoiceMode(DWORD *dwFlag);
159159b3361Sopenharmony_ci    STDMETHODIMP set_VoiceMode(DWORD dwFlag);
160159b3361Sopenharmony_ci    STDMETHODIMP get_KeepAllFreq(DWORD *dwFlag);
161159b3361Sopenharmony_ci    STDMETHODIMP set_KeepAllFreq(DWORD dwFlag);
162159b3361Sopenharmony_ci    STDMETHODIMP get_StrictISO(DWORD *dwFlag);
163159b3361Sopenharmony_ci    STDMETHODIMP set_StrictISO(DWORD dwFlag);
164159b3361Sopenharmony_ci    STDMETHODIMP get_NoShortBlock(DWORD *dwNoShortBlock);
165159b3361Sopenharmony_ci    STDMETHODIMP set_NoShortBlock(DWORD dwNoShortBlock);
166159b3361Sopenharmony_ci    STDMETHODIMP get_XingTag(DWORD *dwXingTag);
167159b3361Sopenharmony_ci    STDMETHODIMP set_XingTag(DWORD dwXingTag);
168159b3361Sopenharmony_ci    STDMETHODIMP get_ModeFixed(DWORD *dwModeFixed);
169159b3361Sopenharmony_ci    STDMETHODIMP set_ModeFixed(DWORD dwModeFixed);
170159b3361Sopenharmony_ci
171159b3361Sopenharmony_ci
172159b3361Sopenharmony_ci    STDMETHODIMP get_CRCFlag(DWORD *dwFlag);
173159b3361Sopenharmony_ci    STDMETHODIMP set_CRCFlag(DWORD dwFlag);
174159b3361Sopenharmony_ci    STDMETHODIMP get_ForceMono(DWORD *dwFlag);
175159b3361Sopenharmony_ci    STDMETHODIMP set_ForceMono(DWORD dwFlag);
176159b3361Sopenharmony_ci    STDMETHODIMP get_SetDuration(DWORD *dwFlag);
177159b3361Sopenharmony_ci    STDMETHODIMP set_SetDuration(DWORD dwFlag);
178159b3361Sopenharmony_ci    STDMETHODIMP get_OriginalFlag(DWORD *dwFlag);
179159b3361Sopenharmony_ci    STDMETHODIMP set_OriginalFlag(DWORD dwFlag);
180159b3361Sopenharmony_ci    STDMETHODIMP get_CopyrightFlag(DWORD *dwFlag);
181159b3361Sopenharmony_ci    STDMETHODIMP set_CopyrightFlag(DWORD dwFlag);
182159b3361Sopenharmony_ci    STDMETHODIMP get_SampleOverlap(DWORD *dwFlag);
183159b3361Sopenharmony_ci    STDMETHODIMP set_SampleOverlap(DWORD dwFlag);
184159b3361Sopenharmony_ci
185159b3361Sopenharmony_ci    STDMETHODIMP get_ParameterBlockSize(BYTE *pcBlock, DWORD *pdwSize);
186159b3361Sopenharmony_ci    STDMETHODIMP set_ParameterBlockSize(BYTE *pcBlock, DWORD dwSize);
187159b3361Sopenharmony_ci
188159b3361Sopenharmony_ci    STDMETHODIMP DefaultAudioEncoderProperties();
189159b3361Sopenharmony_ci    STDMETHODIMP LoadAudioEncoderPropertiesFromRegistry();
190159b3361Sopenharmony_ci    STDMETHODIMP SaveAudioEncoderPropertiesToRegistry();
191159b3361Sopenharmony_ci    STDMETHODIMP InputTypeDefined();
192159b3361Sopenharmony_ci
193159b3361Sopenharmony_ci    STDMETHODIMP ApplyChanges();
194159b3361Sopenharmony_ci
195159b3361Sopenharmony_ci    // CPersistStream
196159b3361Sopenharmony_ci    HRESULT WriteToStream(IStream *pStream);
197159b3361Sopenharmony_ci    HRESULT ReadFromStream(IStream *pStream);
198159b3361Sopenharmony_ci
199159b3361Sopenharmony_ci    int SizeMax();
200159b3361Sopenharmony_ci    STDMETHODIMP GetClassID(CLSID *pClsid);
201159b3361Sopenharmony_ci
202159b3361Sopenharmony_ciprivate:
203159b3361Sopenharmony_ci    CMpegAudEnc(LPUNKNOWN lpunk, HRESULT *phr);
204159b3361Sopenharmony_ci
205159b3361Sopenharmony_ci    HRESULT FlushEncodedSamples();
206159b3361Sopenharmony_ci
207159b3361Sopenharmony_ci    void ReadPresetSettings(MPEG_ENCODER_CONFIG *pmec);
208159b3361Sopenharmony_ci
209159b3361Sopenharmony_ci    void LoadOutputCapabilities(DWORD sample_rate);
210159b3361Sopenharmony_ci
211159b3361Sopenharmony_ci    // Encoder object
212159b3361Sopenharmony_ci    CEncoder                    m_Encoder;
213159b3361Sopenharmony_ci
214159b3361Sopenharmony_ci    REFERENCE_TIME              m_rtStreamTime;
215159b3361Sopenharmony_ci    REFERENCE_TIME              m_rtFrameTime;
216159b3361Sopenharmony_ci    REFERENCE_TIME              m_rtEstimated;
217159b3361Sopenharmony_ci
218159b3361Sopenharmony_ci    // Synchronization data
219159b3361Sopenharmony_ci    LONGLONG                    m_samplesIn;
220159b3361Sopenharmony_ci    LONGLONG                    m_samplesOut;
221159b3361Sopenharmony_ci    int                         m_samplesPerFrame;
222159b3361Sopenharmony_ci    int                         m_bytesPerSample;
223159b3361Sopenharmony_ci    float                       m_bytesToDuration;
224159b3361Sopenharmony_ci
225159b3361Sopenharmony_ci    resync_point_t              m_sync[RESYNC_COUNT];
226159b3361Sopenharmony_ci    int                         m_sync_in_idx;
227159b3361Sopenharmony_ci    int                         m_sync_out_idx;
228159b3361Sopenharmony_ci
229159b3361Sopenharmony_ci    BOOL                        m_hasFinished;
230159b3361Sopenharmony_ci
231159b3361Sopenharmony_ci    CCritSec                    m_cs;
232159b3361Sopenharmony_ci
233159b3361Sopenharmony_ci    DWORD                       m_setDuration;
234159b3361Sopenharmony_ci    DWORD                       m_allowOverlap;
235159b3361Sopenharmony_ci
236159b3361Sopenharmony_ci	REFERENCE_TIME m_rtBytePos;
237159b3361Sopenharmony_ci
238159b3361Sopenharmony_ci	BOOL						m_bStreamOutput;      // Binary stream output
239159b3361Sopenharmony_ci	long						m_cbStreamAlignment;  // Stream block size
240159b3361Sopenharmony_ci    int                         m_CapsNum;
241159b3361Sopenharmony_ci	int                         m_currentMediaTypeIndex;
242159b3361Sopenharmony_ci    output_caps_t               OutputCaps[MAX_IAMSTREAMCONFIG_CAPS];
243159b3361Sopenharmony_ci
244159b3361Sopenharmony_ciprotected:
245159b3361Sopenharmony_ci    friend class CMpegAudEncOutPin;
246159b3361Sopenharmony_ci    friend class CMpegAudEncPropertyPage;
247159b3361Sopenharmony_ci};
248159b3361Sopenharmony_ci
249159b3361Sopenharmony_ci
250159b3361Sopenharmony_ciclass CMpegAudEncOutPin : public CTransformOutputPin, public IAMStreamConfig
251159b3361Sopenharmony_ci{
252159b3361Sopenharmony_cipublic:
253159b3361Sopenharmony_ci
254159b3361Sopenharmony_ci    //////////////////////////////////////////////////////////////////////////
255159b3361Sopenharmony_ci    //  IUnknown
256159b3361Sopenharmony_ci    //////////////////////////////////////////////////////////////////////////
257159b3361Sopenharmony_ci    DECLARE_IUNKNOWN
258159b3361Sopenharmony_ci    STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv);
259159b3361Sopenharmony_ci
260159b3361Sopenharmony_ci    //////////////////////////////////////////////////////////////////////////
261159b3361Sopenharmony_ci    //  IAMStreamConfig
262159b3361Sopenharmony_ci    //////////////////////////////////////////////////////////////////////////
263159b3361Sopenharmony_ci    HRESULT STDMETHODCALLTYPE SetFormat(AM_MEDIA_TYPE *pmt);
264159b3361Sopenharmony_ci    HRESULT STDMETHODCALLTYPE GetFormat(AM_MEDIA_TYPE **ppmt);
265159b3361Sopenharmony_ci    HRESULT STDMETHODCALLTYPE GetNumberOfCapabilities(int *piCount, int *piSize);
266159b3361Sopenharmony_ci    HRESULT STDMETHODCALLTYPE GetStreamCaps(int iIndex, AM_MEDIA_TYPE **pmt, BYTE *pSCC);
267159b3361Sopenharmony_ci
268159b3361Sopenharmony_ci    //////////////////////////////////////////////////////////////////////////
269159b3361Sopenharmony_ci    //  CTransformOutputPin
270159b3361Sopenharmony_ci    //////////////////////////////////////////////////////////////////////////
271159b3361Sopenharmony_ci    CMpegAudEncOutPin( CMpegAudEnc * pFilter, HRESULT * pHr );
272159b3361Sopenharmony_ci    ~CMpegAudEncOutPin();
273159b3361Sopenharmony_ci
274159b3361Sopenharmony_ci    HRESULT CheckMediaType(const CMediaType *pmtOut);
275159b3361Sopenharmony_ci    HRESULT GetMediaType(int iPosition, CMediaType *pmt);
276159b3361Sopenharmony_ci    HRESULT SetMediaType(const CMediaType *pmt);
277159b3361Sopenharmony_ci
278159b3361Sopenharmony_ciprivate:
279159b3361Sopenharmony_ci    BOOL        m_SetFormat;
280159b3361Sopenharmony_ci    CMpegAudEnc *m_pFilter;
281159b3361Sopenharmony_ci
282159b3361Sopenharmony_ci    current_output_format_t  m_CurrentOutputFormat;
283159b3361Sopenharmony_ci
284159b3361Sopenharmony_ciprotected:
285159b3361Sopenharmony_ci    friend class CMpegAudEnc;
286159b3361Sopenharmony_ci
287159b3361Sopenharmony_ci};
288