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();
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
;
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
;
60 HRESULT
CVorbisEncInputPin::Active()
62 m_bEOSReceived
= false;
63 m_bBufferFilled
= false;
64 m_iSamplesWritten
= 0;
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
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
)
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
);
92 int iSamplesAvail
= m_SampleProps
.lActual
/ pwfx
->nChannels
/ (pwfx
->wBitsPerSample
>>3);
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
))
106 for (int iChannel
=m_iFirstChannel
; iChannel
<m_iFirstChannel
+pwfx
->nChannels
; iChannel
++)
107 ppfBuffer
[iChannel
][m_iSamplesWritten
] = 0;
111 // If the buffer pos if after this sample we must skip some samples
112 while ((iSamplesRead
<iSamplesAvail
) &&
113 (m_iSamplesWritten
-iSamplesRead
> tSample
-tBuffer
))
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
;
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
;
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
);
156 m_evWaitBuffer
.Reset();
158 m_iSamplesWritten
= 0;
161 } while (iSamplesRead
< iSamplesAvail
); // Not already all samples used