Make mv's use signed chars explicitly.
[xiph/unicode.git] / oggds / VorbEncDS / VorbEncInput.cpp
blob862793af92b0f2e59f15e38058820c05f74b5626
1 #include "VorbEncDS.h"
2 #include "../OggDS.h"
3 #include <mmreg.h>
4 #include <ks.h>
5 #include <ksmedia.h>
6 #include <stdio.h>
8 CVorbisEncInputPin::CVorbisEncInputPin(TCHAR* pObjectName, CVorbisEnc* pFilter, CCritSec* pEncode,
9 CCritSec* pLock, HRESULT *phr, LPCWSTR pName) :
10 CBaseInputPin(pObjectName, pFilter, pLock, phr, pName)
12 m_pVorbisEnc = pFilter;
13 m_pcsEncode = pEncode;
16 HRESULT CVorbisEncInputPin::CompleteConnect(IPin* pReceivePin)
18 HRESULT hr = CBasePin::CompleteConnect(pReceivePin);
19 if FAILED(hr) return hr;
21 // This might be for multiple input pins in future
22 m_pVorbisEnc->CheckFreeInputPin();
24 return m_pVorbisEnc->ReconnectOutput();
27 HRESULT CVorbisEncInputPin::BreakConnect()
29 HRESULT hr = CBasePin::BreakConnect();
30 if FAILED(hr) return hr;
32 WAVEFORMATEX* pwfx = (WAVEFORMATEX*)m_mt.Format();
33 pwfx->nChannels = 0;
34 return m_pVorbisEnc->ReconnectOutput();
38 HRESULT CVorbisEncInputPin::CheckMediaType(const CMediaType *pmt)
40 if (*(pmt->FormatType()) != FORMAT_WaveFormatEx) return VFW_E_TYPE_NOT_ACCEPTED;
42 WAVEFORMATEX* pwfx = (WAVEFORMATEX*) pmt->Format();
44 if (pwfx->wFormatTag != WAVE_FORMAT_PCM &&
45 pwfx->wFormatTag != WAVE_FORMAT_IEEE_FLOAT &&
46 pwfx->wFormatTag != WAVE_FORMAT_EXTENSIBLE) return VFW_E_TYPE_NOT_ACCEPTED;
48 CMediaType* pmtCurr;
50 if (!m_pVorbisEnc->GetCurrentMediaType(&pmtCurr)) return NOERROR;
52 // if there is already a connected pin the sample rate must be the same
53 WAVEFORMATEX* pwfxcurr = (WAVEFORMATEX*) pmtCurr->Format();
55 if (pwfx->nSamplesPerSec != pwfxcurr->nSamplesPerSec) return VFW_E_TYPE_NOT_ACCEPTED;
57 return NOERROR;
60 HRESULT CVorbisEncInputPin::Active()
62 m_bEOSReceived = false;
63 m_bBufferFilled = false;
64 m_iSamplesWritten = 0;
65 return NOERROR;
68 STDMETHODIMP CVorbisEncInputPin::EndOfStream(void)
70 m_bEOSReceived = true;
71 return m_pVorbisEnc->EndOfStream();
74 STDMETHODIMP CVorbisEncInputPin::Receive(IMediaSample *pSample)
76 // Samples written contains the number of samples written to the vorbis buffer
77 HRESULT hr = NOERROR;
78 CAutoLock lck(&m_csReceive); // Serialize Receive() on this pin
80 // check all is well with the base class
81 hr = CBaseInputPin::Receive(pSample);
82 if FAILED(hr) return hr;
84 if (m_SampleProps.dwStreamId != AM_STREAM_MEDIA)
85 return NOERROR;
87 WAVEFORMATEX* pwfx = (WAVEFORMATEX*)m_mt.Format();
89 ogg_int64_t tSample = reference_time_to_mediatime(SEC_IN_REFTIME,
90 pwfx->nSamplesPerSec, m_SampleProps.tStart);
91 int iSamplesRead = 0;
92 int iSamplesAvail = m_SampleProps.lActual / pwfx->nChannels / (pwfx->wBitsPerSample>>3);
96 float** ppfBuffer;
97 ogg_int64_t tBuffer;
99 m_pVorbisEnc->GetBuffer(&ppfBuffer, &tBuffer);
101 // If the buffer pos is before this sample we must pad with 0
102 while ((m_iSamplesWritten<ENCODE_BUFFER_SIZE) &&
103 (m_iSamplesWritten-iSamplesRead < tSample-tBuffer))
105 deb("Padding");
106 for (int iChannel=m_iFirstChannel; iChannel<m_iFirstChannel+pwfx->nChannels; iChannel++)
107 ppfBuffer[iChannel][m_iSamplesWritten] = 0;
108 m_iSamplesWritten++;
111 // If the buffer pos if after this sample we must skip some samples
112 while ((iSamplesRead<iSamplesAvail) &&
113 (m_iSamplesWritten-iSamplesRead > tSample-tBuffer))
115 deb("Adjusting");
116 iSamplesRead++;
119 // Fill the buffer
120 if (pwfx->wBitsPerSample == 32) // 32bit => float data
122 float* pInBuffer = ((float*)m_SampleProps.pbBuffer)+ (iSamplesRead * pwfx->nChannels);
124 while((m_iSamplesWritten<ENCODE_BUFFER_SIZE) && (iSamplesRead<iSamplesAvail))
126 for (int iChannel=m_iFirstChannel; iChannel<m_iFirstChannel+pwfx->nChannels; iChannel++)
128 ppfBuffer[iChannel][m_iSamplesWritten] = *pInBuffer;
129 *pInBuffer++;
131 iSamplesRead++;
132 m_iSamplesWritten++;
135 else
137 ogg_int16_t* pInBuffer = ((ogg_int16_t*)m_SampleProps.pbBuffer)+ (iSamplesRead * pwfx->nChannels);
139 while((m_iSamplesWritten<ENCODE_BUFFER_SIZE) && (iSamplesRead<iSamplesAvail))
141 for (int iChannel=m_iFirstChannel; iChannel<m_iFirstChannel+pwfx->nChannels; iChannel++)
143 ppfBuffer[iChannel][m_iSamplesWritten] = *pInBuffer / 32768.f;
144 *pInBuffer++;
146 iSamplesRead++;
147 m_iSamplesWritten++;
151 if (m_iSamplesWritten == ENCODE_BUFFER_SIZE)
153 if (!m_pVorbisEnc->ProcessBuffer()) // false means we have to wait for other pins
154 m_evWaitBuffer.Wait(INFINITE);
155 else
156 m_evWaitBuffer.Reset();
158 m_iSamplesWritten = 0;
161 } while (iSamplesRead < iSamplesAvail); // Not already all samples used
163 return NOERROR;