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 "flacdecodeinputpin.h"
00034
00035 FLACDecodeInputPin::FLACDecodeInputPin(AbstractTransformFilter* inParentFilter, CCritSec* inFilterLock, AbstractTransformOutputPin* inOutputPin, vector<CMediaType*> inAcceptableMediaTypes)
00036 : AbstractTransformInputPin(inParentFilter, inFilterLock, inOutputPin, NAME("FLACDecodeInputPin"), L"FLAC In", inAcceptableMediaTypes)
00037 , mGotMetaData(false)
00038 , mCodecLock(NULL)
00039 , mFLACType(FT_UNKNOWN)
00040 , mMetadataPacket(NULL)
00041 , mSetupState(VSS_SEEN_NOTHING)
00042 , mDecodedByteCount(0)
00043 , mDecodedBuffer(NULL)
00044 , mRateNumerator(RATE_DENOMINATOR)
00045
00046 , mUptoFrame(0)
00047
00048 {
00049
00050 mCodecLock = new CCritSec;
00051 ConstructCodec();
00052
00053 mDecodedBuffer = new unsigned char[DECODED_BUFFER_SIZE];
00054 }
00055
00056 FLACDecodeInputPin::~FLACDecodeInputPin(void)
00057 {
00058
00059 delete mCodecLock;
00060 delete mMetadataPacket;
00061 delete mDecodedBuffer;
00062
00063 }
00064
00065 STDMETHODIMP FLACDecodeInputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
00066 {
00067 if (riid == IID_IMediaSeeking) {
00068 *ppv = (IMediaSeeking*)this;
00069 ((IUnknown*)*ppv)->AddRef();
00070 return NOERROR;
00071 } else if (riid == IID_IOggDecoder) {
00072 *ppv = (IOggDecoder*)this;
00073
00074 return NOERROR;
00075
00076 }
00077
00078 return CBaseInputPin::NonDelegatingQueryInterface(riid, ppv);
00079 }
00080 bool FLACDecodeInputPin::ConstructCodec()
00081 {
00082 mFLACDecoder.initCodec();
00083
00084 return true;
00085 }
00086 void FLACDecodeInputPin::DestroyCodec()
00087 {
00088
00089 }
00090 STDMETHODIMP FLACDecodeInputPin::NewSegment(REFERENCE_TIME inStartTime, REFERENCE_TIME inStopTime, double inRate)
00091 {
00092 CAutoLock locLock(mStreamLock);
00093
00094 mUptoFrame = 0;
00095 return AbstractTransformInputPin::NewSegment(inStartTime, inStopTime, inRate);
00096
00097 }
00098
00099
00100
00101 STDMETHODIMP FLACDecodeInputPin::Receive(IMediaSample* inSample)
00102 {
00103 CAutoLock locLock(mStreamLock);
00104
00105 HRESULT locHR = CheckStreaming();
00106
00107 if (locHR == S_OK) {
00108 BYTE* locBuff = NULL;
00109 locHR = inSample->GetPointer(&locBuff);
00110
00111 if ((inSample->GetActualDataLength() > 1) && ((locBuff[0] != 0xff) || (locBuff[1] != 0xf8))) {
00112
00113
00114
00115 return S_OK;
00116 }
00117
00118
00119
00120 if (locHR != S_OK) {
00121
00122 return locHR;
00123 } else {
00124 REFERENCE_TIME locStart = -1;
00125 REFERENCE_TIME locEnd = -1;
00126 __int64 locSampleDuration = 0;
00127 inSample->GetTime(&locStart, &locEnd);
00128
00129 HRESULT locResult = TransformData(locBuff, inSample->GetActualDataLength());
00130 if (locResult != S_OK) {
00131 return S_FALSE;
00132 }
00133 if (locEnd > 0) {
00134
00135 IMediaSample* locSample;
00136 unsigned long locBytesCopied = 0;
00137 unsigned long locBytesToCopy = 0;
00138
00139 locStart = convertGranuleToTime(locEnd) - (((mDecodedByteCount / mFLACDecoder.frameSize()) * UNITS) / mFLACDecoder.sampleRate());
00140 do {
00141 HRESULT locHR = mOutputPin->GetDeliveryBuffer(&locSample, NULL, NULL, NULL);
00142 if (locHR != S_OK) {
00143 return locHR;
00144 }
00145
00146 BYTE* locBuffer = NULL;
00147 locHR = locSample->GetPointer(&locBuffer);
00148
00149 if (locHR != S_OK) {
00150 return locHR;
00151 }
00152
00153 locBytesToCopy = ((mDecodedByteCount - locBytesCopied) <= locSample->GetSize()) ? (mDecodedByteCount - locBytesCopied) : locSample->GetSize();
00154
00155
00156 locSampleDuration = (((locBytesToCopy/mFLACDecoder.frameSize()) * UNITS) / mFLACDecoder.sampleRate());
00157 locEnd = locStart + locSampleDuration;
00158
00159
00160 REFERENCE_TIME locAdjustedStart = (locStart * RATE_DENOMINATOR) / mRateNumerator;
00161 REFERENCE_TIME locAdjustedEnd = (locEnd * RATE_DENOMINATOR) / mRateNumerator;
00162 locAdjustedStart -= m_tStart;
00163 locAdjustedEnd -= m_tStart;
00164
00165 __int64 locSeekStripOffset = 0;
00166 if (locAdjustedEnd < 0) {
00167 locSample->Release();
00168 } else {
00169 if (locAdjustedStart < 0) {
00170 locSeekStripOffset = (-locAdjustedStart) * mFLACDecoder.sampleRate();
00171 locSeekStripOffset *= mFLACDecoder.frameSize();
00172 locSeekStripOffset /= UNITS;
00173 locSeekStripOffset += (mFLACDecoder.frameSize() - (locSeekStripOffset % mFLACDecoder.frameSize()));
00174 __int64 locStrippedDuration = (((locSeekStripOffset/mFLACDecoder.frameSize()) * UNITS) / mFLACDecoder.sampleRate());
00175 locAdjustedStart += locStrippedDuration;
00176 }
00177
00178
00179
00180
00181 memcpy((void*)locBuffer, (const void*)&mDecodedBuffer[locBytesCopied + locSeekStripOffset], locBytesToCopy - locSeekStripOffset);
00182
00183 locSample->SetTime(&locAdjustedStart, &locAdjustedEnd);
00184 locSample->SetMediaTime(&locStart, &locEnd);
00185 locSample->SetSyncPoint(TRUE);
00186 locSample->SetActualDataLength(locBytesToCopy - locSeekStripOffset);
00187 locHR = ((FLACDecodeOutputPin*)(mOutputPin))->mDataQueue->Receive(locSample);
00188 if (locHR != S_OK) {
00189 return locHR;
00190 }
00191 locStart += locSampleDuration;
00192
00193 }
00194 locBytesCopied += locBytesToCopy;
00195
00196
00197 } while(locBytesCopied < mDecodedByteCount);
00198
00199 mDecodedByteCount = 0;
00200
00201 }
00202 return S_OK;
00203
00204 }
00205 } else {
00206
00207 return S_FALSE;
00208 }
00209 }
00210
00211
00212
00213
00214 HRESULT FLACDecodeInputPin::TransformData(BYTE* inBuf, long inNumBytes)
00215 {
00216
00217
00218
00219
00220 if (CheckStreaming() == S_OK) {
00221 unsigned char* locInBuff = new unsigned char[inNumBytes];
00222 memcpy((void*)locInBuff, (const void*)inBuf, inNumBytes);
00223 OggPacket* locInputPacket = new OggPacket(locInBuff, inNumBytes, false, false);
00224
00225
00226 StampedOggPacket* locStamped = (StampedOggPacket*)mFLACDecoder.decodeFLAC(locInputPacket)->clone();
00227
00228 FLACDecodeFilter* locFilter = reinterpret_cast<FLACDecodeFilter*>(m_pFilter);
00229
00230
00231
00232 unsigned long locActualSize = locStamped->packetSize();
00233
00234 unsigned long locBufferRemaining = DECODED_BUFFER_SIZE - mDecodedByteCount;
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 if (locBufferRemaining >= locActualSize) {
00248
00249 memcpy((void*)&mDecodedBuffer[mDecodedByteCount], (const void*)locStamped->packetData(), locActualSize);
00250
00251 mDecodedByteCount += locActualSize;
00252 delete locStamped;
00253 return S_OK;
00254 } else {
00255 throw 0;
00256 }
00257 } else {
00258 DbgLog((LOG_TRACE,1,TEXT("Not streaming")));
00259 return -1;
00260 }
00261
00262 }
00263
00264
00265 STDMETHODIMP FLACDecodeInputPin::BeginFlush() {
00266 CAutoLock locLock(m_pLock);
00267
00268
00269
00270 HRESULT locHR = AbstractTransformInputPin::BeginFlush();
00271 {
00272 CAutoLock locCodecLock(mCodecLock);
00273 mFLACDecoder.flushCodec();
00274 }
00275 return locHR;
00276
00277 }
00278
00279 STDMETHODIMP FLACDecodeInputPin::EndFlush()
00280 {
00281 CAutoLock locLock(m_pLock);
00282
00283 HRESULT locHR = AbstractTransformInputPin::EndFlush();
00284 mDecodedByteCount = 0;
00285 return locHR;
00286 }
00287
00288 STDMETHODIMP FLACDecodeInputPin::EndOfStream(void) {
00289 CAutoLock locStreamLock(mStreamLock);
00290 {
00291 CAutoLock locCodecLock(mCodecLock);
00292 mFLACDecoder.flushCodec();
00293 }
00294
00295 return AbstractTransformInputPin::EndOfStream();
00296 }
00297
00298 HRESULT FLACDecodeInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *outRequestedProps)
00299 {
00300 outRequestedProps->cbBuffer = FLAC_BUFFER_SIZE;
00301 outRequestedProps->cBuffers = FLAC_NUM_BUFFERS;
00302 outRequestedProps->cbAlign = 1;
00303 outRequestedProps->cbPrefix = 0;
00304
00305 return S_OK;
00306 }
00307 HRESULT FLACDecodeInputPin::CheckMediaType(const CMediaType *inMediaType)
00308 {
00309 if (AbstractTransformInputPin::CheckMediaType(inMediaType) == S_OK) {
00310 if (inMediaType->cbFormat == 4) {
00311 if (strncmp((char*)inMediaType->pbFormat, "fLaC", 4) == 0) {
00312
00313 return S_OK;
00314 }
00315 } else if (inMediaType->cbFormat > 4) {
00316 if (strncmp((char*)inMediaType->pbFormat, "\177FLAC", 5) == 0) {
00317
00318 return S_OK;
00319 }
00320 }
00321 }
00322 return S_FALSE;
00323
00324 }
00325 HRESULT FLACDecodeInputPin::SetMediaType(const CMediaType* inMediaType) {
00326
00327
00328 if (CheckMediaType(inMediaType) == S_OK) {
00329
00330 if (inMediaType->cbFormat == 4) {
00331 if (strncmp((char*)inMediaType->pbFormat, "fLaC", 4) == 0) {
00332 mFLACType = FT_CLASSIC;
00333 return S_OK;
00334 }
00335 } else if (inMediaType->cbFormat > 4) {
00336 if (strncmp((char*)inMediaType->pbFormat, "\177FLAC", 5) == 0) {
00337 mFLACType = FT_OGG_FLAC_1;
00338 return S_OK;
00339
00340 }
00341 }
00342 return S_FALSE;
00343
00344 } else {
00345 throw 0;
00346 }
00347
00348
00349 return CBaseInputPin::SetMediaType(inMediaType);
00350 }
00351
00352 LOOG_INT64 FLACDecodeInputPin::convertGranuleToTime(LOOG_INT64 inGranule)
00353 {
00354
00355 return (inGranule * UNITS) / ((FLACDecodeFilter*)mParentFilter)->getFLACFormatBlock()->samplesPerSec;
00356
00357 }
00358
00359 LOOG_INT64 FLACDecodeInputPin::mustSeekBefore(LOOG_INT64 inGranule)
00360 {
00361
00362 return inGranule;
00363 }
00364 IOggDecoder::eAcceptHeaderResult FLACDecodeInputPin::showHeaderPacket(OggPacket* inCodecHeaderPacket)
00365 {
00366 const unsigned char MORE_HEADERS_MASK = 128;
00367 switch (mFLACType) {
00368 case FT_CLASSIC:
00369 switch (mSetupState) {
00370 case VSS_SEEN_NOTHING:
00371 if (strncmp((char*)inCodecHeaderPacket->packetData(), "fLaC", 4) == 0) {
00372 mSetupState = VSS_SEEN_BOS;
00373 delete mMetadataPacket;
00374 mMetadataPacket = inCodecHeaderPacket->clone();
00375 return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
00376 }
00377
00378
00379 mSetupState = VSS_ERROR;
00380 return IOggDecoder::AHR_INVALID_HEADER;
00381 case VSS_SEEN_BOS:
00382 mMetadataPacket->merge(inCodecHeaderPacket);
00383 if ((inCodecHeaderPacket->packetData()[0] & MORE_HEADERS_MASK) != 0) {
00384
00385 mSetupState = VSS_ALL_HEADERS_SEEN;
00386 ((FLACDecodeFilter*)mParentFilter)->setFLACFormatBlock(mMetadataPacket->packetData());
00387 mFLACDecoder.acceptMetadata(mMetadataPacket);
00388 mMetadataPacket = NULL;
00389
00390
00391
00392 return IOggDecoder::AHR_ALL_HEADERS_RECEIVED;
00393 }
00394
00395 return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
00396 default:
00397 return IOggDecoder::AHR_UNEXPECTED;
00398 }
00399
00400 case FT_OGG_FLAC_1:
00401 switch(mSetupState) {
00402 case VSS_SEEN_NOTHING:
00403 if (strncmp((char*)inCodecHeaderPacket->packetData(), "\177FLAC", 5) == 0) {
00404 mSetupState = VSS_SEEN_BOS;
00405 delete mMetadataPacket;
00406 unsigned char* locBuff = new unsigned char[inCodecHeaderPacket->packetSize() - 9];
00407 memcpy((void*)locBuff, (const void*)(inCodecHeaderPacket->packetData() + 9), inCodecHeaderPacket->packetSize() - 9);
00408 mMetadataPacket = new OggPacket(locBuff, inCodecHeaderPacket->packetSize() - 9, false, false);
00409 return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
00410 }
00411
00412
00413 mSetupState = VSS_ERROR;
00414 return IOggDecoder::AHR_INVALID_HEADER;
00415 case VSS_SEEN_BOS:
00416 mMetadataPacket->merge(inCodecHeaderPacket);
00417 if ((inCodecHeaderPacket->packetData()[0] & MORE_HEADERS_MASK) != 0) {
00418
00419 mSetupState = VSS_ALL_HEADERS_SEEN;
00420 ((FLACDecodeFilter*)mParentFilter)->setFLACFormatBlock(mMetadataPacket->packetData());
00421 mFLACDecoder.acceptMetadata(mMetadataPacket);
00422 mMetadataPacket = NULL;
00423
00424
00425
00426 return IOggDecoder::AHR_ALL_HEADERS_RECEIVED;
00427 }
00428
00429 return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
00430 default:
00431 return IOggDecoder::AHR_UNEXPECTED;
00432
00433
00434 };
00435 default:
00436 return IOggDecoder::AHR_INVALID_HEADER;
00437
00438
00439 }
00440
00441 }
00442 string FLACDecodeInputPin::getCodecShortName()
00443 {
00444 return "flac";
00445 }
00446 string FLACDecodeInputPin::getCodecIdentString()
00447 {
00448
00449 return "flac";
00450 }
00451