00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "StdAfx.h"
00033 #include "OggRawAudioExtractorFilter.h"
00034
00035
00036
00037
00038 CFactoryTemplate g_Templates[] =
00039 {
00040 {
00041 L"Ogg Raw Audio Extractor Filter",
00042 &CLSID_OggRawAudioExtractorFilter,
00043 OggRawAudioExtractorFilter::CreateInstance,
00044 NULL,
00045 NULL
00046 }
00047
00048 };
00049
00050
00051 int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
00052
00053 OggRawAudioExtractorFilter::OggRawAudioExtractorFilter()
00054 : CTransformFilter(NAME("Ogg Raw Audio Extractor"), NULL, CLSID_OggRawAudioExtractorFilter)
00055 , mInputPin(NULL)
00056 , mOutputPin(NULL)
00057
00058 , mWorkingBuff(NULL)
00059 , mBytesBuffered(0)
00060
00061 , mSegStart(0)
00062 , mSegEnd(0)
00063 , mSegRate(0)
00064
00065 {
00066 mWorkingBuff = new unsigned char[1<<20];
00067
00068 }
00069
00070
00071
00072 OggRawAudioExtractorFilter::~OggRawAudioExtractorFilter(void)
00073 {
00074 delete[] mWorkingBuff;
00075 }
00076
00077 CUnknown* WINAPI OggRawAudioExtractorFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr)
00078 {
00079
00080 OggRawAudioExtractorFilter *pNewObject = new OggRawAudioExtractorFilter();
00081 if (pNewObject == NULL) {
00082 *pHr = E_OUTOFMEMORY;
00083 }
00084 return pNewObject;
00085 }
00086
00087 HRESULT OggRawAudioExtractorFilter::CheckInputType(const CMediaType* inMediaType)
00088 {
00089 return mInputPin->CheckMediaType(inMediaType);
00090 }
00091 HRESULT OggRawAudioExtractorFilter::CheckTransform(const CMediaType* inInputMediaType, const CMediaType* inOutputMediaType)
00092 {
00093
00094 return S_OK;
00095 }
00096 HRESULT OggRawAudioExtractorFilter::DecideBufferSize(IMemAllocator* inAllocator, ALLOCATOR_PROPERTIES* inPropertyRequest)
00097 {
00098 HRESULT locHR = S_OK;
00099
00100 ALLOCATOR_PROPERTIES locReqAlloc;
00101 ALLOCATOR_PROPERTIES locActualAlloc;
00102
00103 if (inPropertyRequest->cbAlign <= 0) {
00104 locReqAlloc.cbAlign = 1;
00105 } else {
00106 locReqAlloc.cbAlign = inPropertyRequest->cbAlign;
00107 }
00108
00109
00110 if (inPropertyRequest->cbBuffer == 0) {
00111 locReqAlloc.cbBuffer = 65536*16;
00112 } else {
00113 locReqAlloc.cbBuffer = inPropertyRequest->cbBuffer;
00114 }
00115
00116
00117 if (inPropertyRequest->cbPrefix < 0) {
00118 locReqAlloc.cbPrefix = 0;
00119 } else {
00120 locReqAlloc.cbPrefix = inPropertyRequest->cbPrefix;
00121 }
00122
00123 if (inPropertyRequest->cBuffers == 0) {
00124 locReqAlloc.cBuffers = 5;
00125 } else {
00126 locReqAlloc.cBuffers = inPropertyRequest->cBuffers;
00127 }
00128
00129
00130 locHR = inAllocator->SetProperties(&locReqAlloc, &locActualAlloc);
00131
00132 if (locHR != S_OK) {
00133
00134 return locHR;
00135 } else {
00136
00137 locHR = inAllocator->Commit();
00138
00139
00140 return locHR;
00141 }
00142
00143 }
00144
00145 HRESULT OggRawAudioExtractorFilter::NewSegment(REFERENCE_TIME inStartTime, REFERENCE_TIME inStopTime, double inRate)
00146 {
00147 mSegStart = inStartTime;
00148 mSegEnd = inStopTime;
00149 mSegRate = inRate;
00150 return CTransformFilter::NewSegment(inStartTime, inStopTime, inRate);
00151 }
00152 HRESULT OggRawAudioExtractorFilter::GetMediaType(int inPosition, CMediaType* outMediaType)
00153 {
00154
00155 if (inPosition < 0) {
00156 return E_INVALIDARG;
00157 }
00158
00159 if ((inPosition == 0) && (mInputPin != NULL) && (mInputPin->IsConnected())) {
00160
00161 WAVEFORMATEX* locWaveFormat = (WAVEFORMATEX*)outMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEX));
00162
00163
00164 sOggRawAudioFormatBlock locOggFormat = mInputPin->getFormatBlock();
00165 locWaveFormat->wFormatTag = WAVE_FORMAT_PCM;
00166 locWaveFormat->nChannels = locOggFormat.numChannels;
00167 locWaveFormat->nSamplesPerSec = locOggFormat.samplesPerSec;
00168 locWaveFormat->wBitsPerSample = locOggFormat.bitsPerSample;
00169 locWaveFormat->nBlockAlign = (locWaveFormat->nChannels) * (locWaveFormat->wBitsPerSample >> 3);
00170 locWaveFormat->nAvgBytesPerSec = ((locWaveFormat->nChannels) * (locWaveFormat->wBitsPerSample >> 3)) * locWaveFormat->nSamplesPerSec;
00171 locWaveFormat->cbSize = 0;
00172
00173 outMediaType->majortype = MEDIATYPE_Audio;
00174 outMediaType->subtype = MEDIASUBTYPE_PCM;
00175 outMediaType->formattype = FORMAT_WaveFormatEx;
00176
00177 return S_OK;
00178 } else {
00179 return VFW_S_NO_MORE_ITEMS;
00180 }
00181
00182
00183 }
00184
00185 HRESULT OggRawAudioExtractorFilter::Receive(IMediaSample* inSample)
00186 {
00187 BYTE* locInBuff = NULL;
00188 HRESULT locHR = inSample->GetPointer(&locInBuff);
00189
00190 if (locHR == S_OK) {
00191 REFERENCE_TIME locStart = -1;
00192 REFERENCE_TIME locEnd = -1;
00193 inSample->GetTime(&locStart, &locEnd);
00194 if (locEnd == 0) {
00195 return S_OK;
00196 }
00197
00198 memcpy((void*)&mWorkingBuff[mBytesBuffered], (const void*)locInBuff, inSample->GetActualDataLength());
00199 mBytesBuffered += inSample->GetActualDataLength();
00200
00201
00202
00203 if (locEnd > 0) {
00204
00205 IMediaSample* locSample;
00206 unsigned long locSampleDuration = 0;
00207 unsigned long locBytesCopied = 0;
00208 unsigned long locBytesToCopy = 0;
00209 unsigned long locSampleRate = mInputPin->getFormatBlock().samplesPerSec;
00210 unsigned long locFrameSize = (mInputPin->getFormatBlock().bitsPerSample * mInputPin->getFormatBlock().numChannels) >> 3;
00211
00212 locStart = mInputPin->convertGranuleToTime(locEnd) - (((mBytesBuffered / locFrameSize) * UNITS) / locSampleRate);
00213 do {
00214
00215 HRESULT locHR = InitializeOutputSample(inSample, &locSample);
00216 if (locHR != S_OK) {
00217 return locHR;
00218 }
00219
00220 BYTE* locBuffer = NULL;
00221 locHR = locSample->GetPointer(&locBuffer);
00222
00223 if (locHR != S_OK) {
00224 return locHR;
00225 }
00226
00227 locBytesToCopy = ((mBytesBuffered - locBytesCopied) <= locSample->GetSize()) ? (mBytesBuffered - locBytesCopied) : locSample->GetSize();
00228
00229
00230 locSampleDuration = (((locBytesToCopy/locFrameSize) * UNITS) / locSampleRate);
00231 locEnd = locStart + locSampleDuration;
00232
00233
00234 REFERENCE_TIME locAdjustedStart = locStart;
00235 REFERENCE_TIME locAdjustedEnd = locEnd;
00236 locAdjustedStart -= mSegStart;
00237 locAdjustedEnd -= mSegStart;
00238
00239 __int64 locSeekStripOffset = 0;
00240 if (locAdjustedEnd < 0) {
00241 locSample->Release();
00242 } else {
00243 if (locAdjustedStart < 0) {
00244 locSeekStripOffset = (-locAdjustedStart) * locSampleRate;
00245 locSeekStripOffset *= locFrameSize;
00246 locSeekStripOffset /= UNITS;
00247 locSeekStripOffset += (locFrameSize - (locSeekStripOffset % locFrameSize));
00248 __int64 locStrippedDuration = (((locSeekStripOffset/locFrameSize) * UNITS) / locSampleRate);
00249 locAdjustedStart += locStrippedDuration;
00250 }
00251
00252
00253
00254
00255 memcpy((void*)locBuffer, (const void*)&mWorkingBuff[locBytesCopied + locSeekStripOffset], locBytesToCopy - locSeekStripOffset);
00256
00257 locSample->SetTime(&locAdjustedStart, &locAdjustedEnd);
00258 locSample->SetMediaTime(&locStart, &locEnd);
00259 locSample->SetSyncPoint(TRUE);
00260 locSample->SetActualDataLength(locBytesToCopy - locSeekStripOffset);
00261 locHR = mOutputPin->Deliver(locSample);
00262 locSample->Release();
00263 if (locHR != S_OK) {
00264 return locHR;
00265 }
00266 locStart += locSampleDuration;
00267
00268 }
00269 locBytesCopied += locBytesToCopy;
00270
00271
00272 } while(locBytesCopied < mBytesBuffered);
00273
00274 mBytesBuffered = 0;
00275
00276 }
00277
00278 return S_OK;
00279
00280 }
00281
00282 return S_FALSE;
00283
00284 }
00285
00286 HRESULT OggRawAudioExtractorFilter::Transform(IMediaSample* inInputSample, IMediaSample* inOutputSample)
00287 {
00288
00289 return E_NOTIMPL;
00290 }
00291
00292 CBasePin* OggRawAudioExtractorFilter::GetPin(int inPinNo)
00293 {
00294
00295 HRESULT locHR = S_OK;
00296
00297
00298
00299 if (m_pInput == NULL) {
00300
00301 m_pInput = new OggRawAudioExtractorInputPin(this, &locHR);
00302
00303
00304 mInputPin = (OggRawAudioExtractorInputPin*)m_pInput;
00305 m_pOutput = new CTransformOutputPin(NAME("PCM Out"), this, &locHR, L"PCM Out");
00306 mOutputPin = m_pOutput;
00307
00308
00309 }
00310
00311
00312
00313 if (inPinNo == 0) {
00314 return m_pInput;
00315 } else if (inPinNo == 1) {
00316 return m_pOutput;
00317 } else {
00318 return NULL;
00319 }
00320
00321 }