[xiph-commits] r16644 - trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource
cristianadam at svn.xiph.org
cristianadam at svn.xiph.org
Tue Oct 13 14:54:34 PDT 2009
Author: cristianadam
Date: 2009-10-13 14:54:34 -0700 (Tue, 13 Oct 2009)
New Revision: 16644
Added:
trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/Resources.rc
trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/resource.h
Modified:
trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.cpp
trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.h
trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp
trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.h
trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/dsfNativeFLACSource.cpp
trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/dsfNativeFLACSource.h
trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/stdafx.h
Log:
Fixed Ticket #1491 (oggcodecs doesn't work with 6-channel FLACs). Added support for FLAC files bigger than 2Gbytes, support for 7.1 channels and logging support.
Modified: trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.cpp 2009-10-12 22:20:48 UTC (rev 16643)
+++ trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.cpp 2009-10-13 21:54:34 UTC (rev 16644)
@@ -1,5 +1,6 @@
//===========================================================================
//Copyright (C) 2003, 2004 Zentaro Kavanagh
+//Copyright (C) 2008, 2009 Cristian Adam
//
//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions
@@ -29,16 +30,18 @@
//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//===========================================================================
#include "stdafx.h"
-#include ".\NativeFLACSourceFilter.h"
+#include "NativeFLACSourceFilter.h"
+#include "dsfNativeFLACSource.h"
+#include <sstream>
CFactoryTemplate g_Templates[] =
{
{
- L"Native FLAC SourceFilter", // Name
- &CLSID_NativeFLACSourceFilter, // CLSID
- NativeFLACSourceFilter::CreateInstance, // Method to create an instance of MyComponent
- NULL, // Initialization function
- NULL // Set-up information (for filters)
+ L"Native FLAC SourceFilter", // Name
+ &CLSID_NativeFLACSourceFilter, // CLSID
+ NativeFLACSourceFilter::CreateInstance, // Method to create an instance of MyComponent
+ NULL, // Initialization function
+ NULL // Set-up information (for filters)
}
};
@@ -46,291 +49,381 @@
// Generic way of determining the number of items in the template
int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
+#ifdef WINCE
+LPAMOVIESETUP_FILTER NativeFLACSourceFilter::GetSetupData()
+{
+ return (LPAMOVIESETUP_FILTER)(&NativeFLACSourceFilterReg);
+}
+#endif
CUnknown* WINAPI NativeFLACSourceFilter::CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr)
{
- NativeFLACSourceFilter *pNewObject = new NativeFLACSourceFilter();
- if (pNewObject == NULL) {
+ NativeFLACSourceFilter *pNewObject = new (std::nothrow) NativeFLACSourceFilter();
+ if (pNewObject == NULL)
+ {
*pHr = E_OUTOFMEMORY;
}
return pNewObject;
}
-NativeFLACSourceFilter::NativeFLACSourceFilter(void)
- : CBaseFilter(NAME("NativeFLACSourceFilter"), NULL, m_pLock, CLSID_NativeFLACSourceFilter)
- , mNumChannels(0)
- , mSampleRate(0)
- , mBitsPerSample(0)
- , mSignificantBitsPerSample(0)
- , mBegun(false)
- , mUpto(0)
- , mJustSeeked(true)
- , mSeekRequest(0)
- , mTotalNumSamples(0)
- , mWasEOF(false)
+NativeFLACSourceFilter::NativeFLACSourceFilter(void) :
+CBaseFilter(NAME("NativeFLACSourceFilter"), NULL, m_pLock, CLSID_NativeFLACSourceFilter),
+m_numChannels(0),
+m_sampleRate(0),
+m_bitsPerSample(0),
+m_significantBitsPerSample(0),
+m_begun(false),
+m_upTo(0),
+m_justSeeked(true),
+m_seekRequest(0),
+m_totalNumSamples(0),
+m_wasEof(false),
+m_inputFileHandle(INVALID_HANDLE_VALUE)
{
- m_pLock = new CCritSec;
- mFLACSourcePin = new NativeFLACSourcePin(this, m_pLock);
+ m_pLock = new CCritSec;
+ m_flacSourcePin = new NativeFLACSourcePin(this, m_pLock);
+
+ LOG(logINFO) << L"NativeFLACSourceFilter object created!" << std::endl;
}
NativeFLACSourceFilter::~NativeFLACSourceFilter(void)
{
- delete mFLACSourcePin;
- mFLACSourcePin = NULL;
+ ::CloseHandle(m_inputFileHandle);
+
+ delete m_flacSourcePin;
+ m_flacSourcePin = NULL;
}
//BaseFilter Interface
int NativeFLACSourceFilter::GetPinCount()
{
- return 1;
+ return 1;
}
+
CBasePin* NativeFLACSourceFilter::GetPin(int inPinNo)
{
- if (inPinNo == 0) {
- return mFLACSourcePin;
- } else {
- return NULL;
- }
+ if (inPinNo == 0)
+ {
+ return m_flacSourcePin;
+ }
+ else
+ {
+ return NULL;
+ }
}
//IAMFilterMiscFlags Interface
-ULONG NativeFLACSourceFilter::GetMiscFlags(void)
+ULONG NativeFLACSourceFilter::GetMiscFlags()
{
- return AM_FILTER_MISC_FLAGS_IS_SOURCE;
+ return AM_FILTER_MISC_FLAGS_IS_SOURCE;
}
- //IFileSource Interface
-STDMETHODIMP NativeFLACSourceFilter::GetCurFile(LPOLESTR* outFileName, AM_MEDIA_TYPE* outMediaType)
+//IFileSource Interface
+HRESULT __stdcall NativeFLACSourceFilter::GetCurFile(LPOLESTR* outFileName, AM_MEDIA_TYPE* outMediaType)
{
CheckPointer(outFileName, E_POINTER);
*outFileName = NULL;
- if (!mFileName.empty()) {
- unsigned int size = sizeof(WCHAR) * (mFileName.size() + 1);
+ if (!m_fileName.empty())
+ {
+ unsigned int size = sizeof(WCHAR) * (m_fileName.size() + 1);
*outFileName = (LPOLESTR) CoTaskMemAlloc(size);
- if (*outFileName != NULL) {
- CopyMemory(*outFileName, mFileName.c_str(), size);
+ if (*outFileName != NULL)
+ {
+ CopyMemory(*outFileName, m_fileName.c_str(), size);
}
}
-
- return S_OK;
+
+ return S_OK;
}
+__int64 NativeFLACSourceFilter::SeekFile(__int64 distance, unsigned long moveMethod)
+{
+ LARGE_INTEGER current;
-STDMETHODIMP NativeFLACSourceFilter::Load(LPCOLESTR inFileName, const AM_MEDIA_TYPE* inMediaType)
+ current.QuadPart = distance;
+ current.LowPart = ::SetFilePointer(m_inputFileHandle, current.LowPart, ¤t.HighPart, moveMethod);
+
+ if (current.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
+ {
+ current.QuadPart = -1;
+ }
+
+ return current.QuadPart;
+}
+
+__int64 NativeFLACSourceFilter::SeekFile(LARGE_INTEGER distance, unsigned long moveMethod)
{
- //Initialise the file here and setup the stream
- CAutoLock locLock(m_pLock);
- mFileName = inFileName;
+ return SeekFile(distance.QuadPart, moveMethod);
+}
- mInputFile.open(mFileName.c_str(), ios_base::in | ios_base::binary);
+HRESULT __stdcall NativeFLACSourceFilter::Load(LPCOLESTR inFileName, const AM_MEDIA_TYPE* inMediaType)
+{
+ //Initialize the file here and setup the stream
+ CAutoLock locLock(m_pLock);
+ m_fileName = inFileName;
- //CT> Added header check (for FLAC files with ID3 v1/2 tags in them)
- // We'll look in the first 128kb of the file
- unsigned long locStart = 0;
- int locHeaderFound = 0;
- for(int j = 0; !locHeaderFound && j < 128; j++) {
- unsigned char locTempBuf[1024]={0,};
- mInputFile.read((char*)&locTempBuf, sizeof(locTempBuf));
- unsigned char* locPtr = locTempBuf;
- for(int i = 0; i < 1023; i++) {
- if(locPtr[i]=='f' && locPtr[i+1]=='L' && locPtr[i+2]=='a' && locPtr[i+3]=='C') {
- locHeaderFound = 1;
- locStart = i + (j * 1024);
- break;
- }
- }
- }
- if(!locHeaderFound) {
- return E_FAIL;
- }
+ LOG(logINFO) << L"NativeFLACSourceFilter::Load(" << m_fileName << L")";
- mInputFile.seekg(0, ios_base::end);
- mFileSize = mInputFile.tellg();
- mFileSize -= locStart;
- mInputFile.seekg(locStart, ios_base::beg);
+ if (m_inputFileHandle != INVALID_HANDLE_VALUE)
+ {
+ ::CloseHandle(m_inputFileHandle);
+ }
- unsigned char locBuff[64];
- mInputFile.read((char*)&locBuff, 64);
- const unsigned char FLAC_CHANNEL_MASK = 14; //00001110
- const unsigned char FLAC_BPS_START_MASK = 1; //00000001
- const unsigned char FLAC_BPS_END_MASK = 240; //11110000
+ m_inputFileHandle = ::CreateFile(m_fileName.c_str(), GENERIC_READ, FILE_SHARE_READ, 0,
+ OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
- mNumChannels = (((locBuff[20]) & FLAC_CHANNEL_MASK) >> 1) + 1;
- mSampleRate = (iBE_Math::charArrToULong(&locBuff[18])) >> 12;
- mSignificantBitsPerSample = (((locBuff[20] & FLAC_BPS_START_MASK) << 4) | ((locBuff[21] & FLAC_BPS_END_MASK) >> 4)) + 1;
+ if (m_inputFileHandle == INVALID_HANDLE_VALUE)
+ {
+ LOG(logERROR) << L"CreateFile(" << m_fileName << L") failed! GetLastError: 0x"
+ << std::hex << ::GetLastError();
- mBitsPerSample = (mSignificantBitsPerSample + 7) & 0xfffffff8UL;
+ return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
+ }
- if (mBitsPerSample == 24) {
- mBitsPerSample = 32;
+ //CT> Added header check (for FLAC files with ID3 v1/2 tags in them)
+ // We'll look in the first 128kb of the file
+ unsigned long locStart = 0;
+ bool headerFound = false;
+ for (int j = 0; !headerFound && j < 128; j++)
+ {
+ unsigned char locTempBuf[1024] = {0};
+
+ unsigned long readBytes = 0;
+ ::ReadFile(m_inputFileHandle, &locTempBuf, sizeof(locTempBuf), &readBytes, 0);
+
+ unsigned char* locPtr = locTempBuf;
+ for (int i = 0; i < 1023; i++)
+ {
+ if (locPtr[i]=='f' && locPtr[i+1]=='L' && locPtr[i+2]=='a' && locPtr[i+3]=='C')
+ {
+ headerFound = true;
+ locStart = i + (j * 1024);
+ break;
+ }
+ }
}
- mTotalNumSamples = (((__int64)(locBuff[21] % 16)) << 32) + ((__int64)(iBE_Math::charArrToULong(&locBuff[22])));
+ if (!headerFound)
+ {
+ LOG(logERROR) << "No FLAC Header Found!";
+ return E_FAIL;
+ }
- //TODO::: NEed to handle the case where the number of samples is zero by making it non-seekable.
- mInputFile.seekg(locStart, ios_base::beg);
+ LARGE_INTEGER fileSize;
+ fileSize.LowPart = ::GetFileSize(m_inputFileHandle, (unsigned long*)&fileSize.HighPart);
+ m_fileSize = fileSize.QuadPart;
+
+ m_extraBeginDataLength = locStart;
- init();
- bool locResult = process_until_end_of_metadata();
+ set_md5_checking(false);
+ set_metadata_ignore_all();
+ set_metadata_respond(FLAC__METADATA_TYPE_STREAMINFO);
+ set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT);
- return (locResult ? S_OK : E_FAIL);
+ //TODO::: Need to handle the case where the number of samples is zero by making it non-seekable.
+ SeekFile(locStart, FILE_BEGIN);
+
+ init();
+ bool locResult = process_until_end_of_metadata();
+
+ if (!locResult)
+ {
+ LOG(logERROR) << L"process_until_end_of_metadata returned false!";
+ }
+
+ return locResult ? S_OK : E_FAIL;
}
-STDMETHODIMP NativeFLACSourceFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)
+HRESULT __stdcall NativeFLACSourceFilter::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
- if (riid == IID_IFileSourceFilter) {
- *ppv = (IFileSourceFilter*)this;
- ((IUnknown*)*ppv)->AddRef();
- return NOERROR;
- }
+ LOG(logDEBUG) << L"NonDelegatingQueryInterface: " << riid;
- return CBaseFilter::NonDelegatingQueryInterface(riid, ppv);
+ if (riid == IID_IFileSourceFilter)
+ {
+ return GetInterface((IFileSourceFilter*)this, ppv);
+ }
+
+ return CBaseFilter::NonDelegatingQueryInterface(riid, ppv);
}
-//IMEdiaStreaming
-STDMETHODIMP NativeFLACSourceFilter::Run(REFERENCE_TIME tStart)
+//IMediaStreaming
+HRESULT __stdcall NativeFLACSourceFilter::Run(REFERENCE_TIME tStart)
{
- CAutoLock locLock(m_pLock);
- return CBaseFilter::Run(tStart);
+ LOG(logINFO) << "Run: " << ReferenceTime(tStart);
+ CAutoLock locLock(m_pLock);
+ return CBaseFilter::Run(tStart);
}
-STDMETHODIMP NativeFLACSourceFilter::Pause(void)
+
+HRESULT __stdcall NativeFLACSourceFilter::Pause()
{
- CAutoLock locLock(m_pLock);
- if (m_State == State_Stopped) {
- if (ThreadExists() == FALSE) {
- Create();
- }
- CallWorker(THREAD_RUN);
- }
+ LOG(logINFO) << "Pause";
+ CAutoLock locLock(m_pLock);
+ if (m_State == State_Stopped)
+ {
+ if (ThreadExists() == FALSE)
+ {
+ Create();
+ }
+ CallWorker(THREAD_RUN);
+ }
- HRESULT locHR = CBaseFilter::Pause();
- return locHR;
-
+ HRESULT locHR = CBaseFilter::Pause();
+ return locHR;
+
}
-STDMETHODIMP NativeFLACSourceFilter::Stop(void)
+HRESULT __stdcall NativeFLACSourceFilter::Stop()
{
- CAutoLock locLock(m_pLock);
- CallWorker(THREAD_EXIT);
- Close();
- mJustSeeked = true;
- mSeekRequest = 0;
- mUpto = 0;
- mFLACSourcePin->DeliverBeginFlush();
- mFLACSourcePin->DeliverEndFlush();
- return CBaseFilter::Stop();
+ LOG(logINFO) << "Stop";
+ CAutoLock locLock(m_pLock);
+ CallWorker(THREAD_EXIT);
+ Close();
+
+ m_seekRequest = 0;
+ m_upTo = 0;
+
+ m_flacSourcePin->DeliverBeginFlush();
+ m_flacSourcePin->DeliverEndFlush();
+
+ SeekFile(0, FILE_BEGIN);
+
+ return CBaseFilter::Stop();
}
-HRESULT NativeFLACSourceFilter::DataProcessLoop() {
- DWORD locCommand = 0;
- bool res = false;
- while (true) {
- if(CheckRequest(&locCommand) == TRUE) {
- return S_OK;
- }
- {
- if (mJustSeeked) {
- mUpto = 0;
- mJustSeeked = false;
- bool res2 = false;
- res2 = seek_absolute(mSeekRequest);
- if (!res2)
- {
- //ERROR???
- flush();
- break;
- }
- }
-
- res = process_single();
- if (!res)
- {
- //ERROR???
- flush();
- }
+HRESULT NativeFLACSourceFilter::DataProcessLoop()
+{
+ while (true)
+ {
+ DWORD locCommand = 0;
+ if (CheckRequest(&locCommand) == TRUE)
+ {
+ return S_OK;
+ }
- if (mWasEOF) {
- break;
- }
-
- }
- }
+ if (m_justSeeked)
+ {
+ m_upTo = 0;
+ m_justSeeked = false;
- mInputFile.clear();
- mInputFile.seekg(0);
- mWasEOF = false;
- mFLACSourcePin->DeliverEndOfStream();
- return S_OK;
+ LOG(logINFO) << "DataProcessLoop: seek_absolute(" << m_seekRequest << ")";
+ if (!seek_absolute(m_seekRequest))
+ {
+ //ERROR???
+
+ LOG(logERROR) << "DataProcessLoop: seek_absolute failed!";
+ flush();
+ break;
+ }
+ }
+
+ if (!process_single())
+ {
+ //ERROR???
+
+ LOG(logERROR) << "DataProcessLoop: process_single failed!";
+ flush();
+ }
+
+ if (m_wasEof)
+ {
+ break;
+ }
+ }
+
+ SeekFile(0, FILE_BEGIN);
+ m_wasEof = false;
+ m_flacSourcePin->DeliverEndOfStream();
+
+ return S_OK;
}
//CAMThread Stuff
DWORD NativeFLACSourceFilter::ThreadProc(void)
{
- while(true) {
- DWORD locThreadCommand = GetRequest();
- switch(locThreadCommand) {
- case THREAD_EXIT:
- Reply(S_OK);
- return S_OK;
+ while(true)
+ {
+ DWORD locThreadCommand = GetRequest();
+ switch(locThreadCommand)
+ {
+ case THREAD_EXIT:
+ Reply(S_OK);
+ return S_OK;
- case THREAD_RUN:
- Reply(S_OK);
- DataProcessLoop();
- break;
+ case THREAD_RUN:
+ Reply(S_OK);
+ DataProcessLoop();
+ break;
//OTHER CASES?
- }
- }
- return S_OK;
+ }
+ }
+ return S_OK;
}
::FLAC__StreamDecoderReadStatus NativeFLACSourceFilter::read_callback(FLAC__byte outBuffer[], size_t* outNumBytes)
{
- const unsigned long BUFF_SIZE = 8192;
- mInputFile.read((char*)outBuffer, BUFF_SIZE);
- *outNumBytes = mInputFile.gcount();
- mWasEOF = mInputFile.eof();
- return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
+ unsigned long bytesRead = 0;
+ BOOL result = ::ReadFile(m_inputFileHandle, outBuffer, BUFF_SIZE, &bytesRead, 0);
+ *outNumBytes = bytesRead;
+
+ if (!result && ::GetLastError() == ERROR_HANDLE_EOF || eof_callback())
+ {
+ m_wasEof = true;
+ }
+
+ return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
}
+
::FLAC__StreamDecoderSeekStatus NativeFLACSourceFilter::seek_callback(FLAC__uint64 inSeekPos)
{
- mInputFile.seekg(inSeekPos);
- return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
+ LOG(logDEBUG) << "seek_callback: pos " << inSeekPos;
+
+ if (SeekFile(inSeekPos, FILE_BEGIN) < 0)
+ {
+ return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
+ }
+
+ return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
}
+
::FLAC__StreamDecoderTellStatus NativeFLACSourceFilter::tell_callback(FLAC__uint64* outTellPos)
{
- *outTellPos = mInputFile.tellg();
- return FLAC__STREAM_DECODER_TELL_STATUS_OK;
+ __int64 currentPosition = SeekFile(0, FILE_CURRENT);
+ if (currentPosition < 0)
+ {
+ return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
+ }
+
+ *outTellPos = currentPosition;
+
+ return FLAC__STREAM_DECODER_TELL_STATUS_OK;
}
+
::FLAC__StreamDecoderLengthStatus NativeFLACSourceFilter::length_callback(FLAC__uint64* outLength)
{
- *outLength = mFileSize;
- return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
+ *outLength = m_fileSize - m_extraBeginDataLength;
+ return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
}
+
::FLAC__StreamDecoderWriteStatus NativeFLACSourceFilter::write_callback(const FLAC__Frame* inFrame,const FLAC__int32 *const inBuffer[])
{
-
-
+ if (!m_begun)
+ {
+ m_begun = true;
- if (! mBegun) {
- mBegun = true;
-
-
- mNumChannels = inFrame->header.channels;
- mFrameSize = mNumChannels * (mBitsPerSample >> 3);
+ m_numChannels = static_cast<unsigned short>(inFrame->header.channels);
+ m_frameSize = m_numChannels * (m_bitsPerSample >> 3);
- mSampleRate = inFrame->header.sample_rate;
- }
+ m_sampleRate = inFrame->header.sample_rate;
+ }
- unsigned long locNumFrames = inFrame->header.blocksize;
- unsigned long locBufferSize = locNumFrames * mFrameSize;
- unsigned long locTotalFrameCount = locNumFrames * mNumChannels;
+ unsigned long numFrames = inFrame->header.blocksize;
+ unsigned long bufferSize = numFrames * m_frameSize;
+ unsigned long totalFrameCount = numFrames * m_numChannels;
-
-
// TODO::: It's not clear whether in the 32 bit flac sample, the significant bits are always rightmost (
// ie justified into the least significant bits. They seem to be for nbits = 16. But it's unclear
// whether eg a 20 bit sample is 0000 0000 1111 1111 1111 1111 1111 0000 so it's still a valid
@@ -340,180 +433,380 @@
//It could actually be a single buffer for the class.????
- unsigned char* locBuff = new unsigned char[locBufferSize]; //Gives to the deliverdata method
- unsigned long locLeftShift = mBitsPerSample - mSignificantBitsPerSample;
+ unsigned char* buffer = new unsigned char[bufferSize]; //Gives to the deliverdata method
+ unsigned long leftShift = m_bitsPerSample - m_significantBitsPerSample;
- if (mBitsPerSample == 8) {
- unsigned char* locByteBuffer = (unsigned char*)locBuff;
+ if (m_bitsPerSample == 8)
+ {
+ unsigned char* locByteBuffer = (unsigned char*)buffer;
- if (locLeftShift == 0) {
- for(unsigned long i = 0; i < locNumFrames; i++) {
- for (unsigned long j = 0; j < mNumChannels; j++) {
+ if (leftShift == 0)
+ {
+ for(unsigned long i = 0; i < numFrames; i++)
+ {
+ for (unsigned long j = 0; j < m_numChannels; j++)
+ {
*(locByteBuffer++) = (unsigned char)(inFrame + 128);
}
-
}
- } else {
- for(unsigned long i = 0; i < locNumFrames; i++) {
- for (unsigned long j = 0; j < mNumChannels; j++) {
- *(locByteBuffer++) = (unsigned char)(inFrame + 128) << locLeftShift;
+ }
+ else
+ {
+ for(unsigned long i = 0; i < numFrames; i++)
+ {
+ for (unsigned long j = 0; j < m_numChannels; j++)
+ {
+ *(locByteBuffer++) = (unsigned char)(inFrame + 128) << leftShift;
}
-
}
-
}
-
-
- } else if (mBitsPerSample == 16) {
- signed short* locShortBuffer = (signed short*)locBuff; //Don't delete this.
- if (locLeftShift == 0) {
-
- for(unsigned long i = 0; i < locNumFrames; i++) {
- for (unsigned long j = 0; j < mNumChannels; j++) {
-
+ }
+ else if (m_bitsPerSample == 16)
+ {
+ signed short* locShortBuffer = (signed short*)buffer; //Don't delete this.
+ if (leftShift == 0)
+ {
+ for(unsigned long i = 0; i < numFrames; i++)
+ {
+ for (unsigned long j = 0; j < m_numChannels; j++)
+ {
*(locShortBuffer++) = (signed short)inBuffer[j][i];
- //tempLong = inBuffer[j][i];
+ //tempLong = inBuffer[j][i];
- ////FIX::: Why on earth are you dividing by 2 ? It does not make sense !
- ////tempInt = (signed short)(tempLong/2);
- //tempInt = (signed short)(tempLong);
-
- //*locShortBuffer = tempInt;
- //locShortBuffer++;
- }
- }
- } else {
- for(unsigned long i = 0; i < locNumFrames; i++) {
- for (unsigned long j = 0; j < mNumChannels; j++) {
-
- *(locShortBuffer++) = (signed short)inBuffer[j][i] << locLeftShift;
- }
- }
+ ////FIX::: Why on earth are you dividing by 2 ? It does not make sense !
+ ////tempInt = (signed short)(tempLong/2);
+ //tempInt = (signed short)(tempLong);
+
+ //*locShortBuffer = tempInt;
+ //locShortBuffer++;
+ }
+ }
+ }
+ else
+ {
+ for(unsigned long i = 0; i < numFrames; i++)
+ {
+ for (unsigned long j = 0; j < m_numChannels; j++)
+ {
+ *(locShortBuffer++) = (signed short)inBuffer[j][i] << leftShift;
+ }
+ }
}
- } else if (mBitsPerSample == 32) {
- signed long* locLongBuffer = (signed long*)locBuff;
- if (locLeftShift == 8) {
- //Special case for 24 bit, let the shift be hardcoded.
- for(unsigned long i = 0; i < locNumFrames; i++) {
- for (unsigned long j = 0; j < mNumChannels; j++) {
+ }
+ else if (m_bitsPerSample == 32)
+ {
+ signed long* locLongBuffer = (signed long*)buffer;
+ if (leftShift == 8)
+ {
+ //Special case for 24 bit, let the shift be hard coded.
+ for(unsigned long i = 0; i < numFrames; i++)
+ {
+ for (unsigned long j = 0; j < m_numChannels; j++)
+ {
*(locLongBuffer++) = inBuffer[j][i] << 8;
}
}
- } else if (locLeftShift == 0) {
+ }
+ else if (leftShift == 0)
+ {
//Real 32 bit data
- for(unsigned long i = 0; i < locNumFrames; i++) {
- for (unsigned long j = 0; j < mNumChannels; j++) {
+ for(unsigned long i = 0; i < numFrames; i++)
+ {
+ for (unsigned long j = 0; j < m_numChannels; j++)
+ {
*(locLongBuffer++) = inBuffer[j][i];
}
}
-
- } else {
-
- for(unsigned long i = 0; i < locNumFrames; i++) {
- for (unsigned long j = 0; j < mNumChannels; j++) {
- *(locLongBuffer++) = inBuffer[j][i] << locLeftShift;
+ }
+ else
+ {
+ for(unsigned long i = 0; i < numFrames; i++)
+ {
+ for (unsigned long j = 0; j < m_numChannels; j++)
+ {
+ *(locLongBuffer++) = inBuffer[j][i] << leftShift;
}
}
+ }
+ }
+
+ __int64 start = m_upTo * UNITS / m_sampleRate;
+ __int64 stop = (m_upTo + numFrames) * UNITS / m_sampleRate;
+ m_flacSourcePin->DeliverData(buffer, bufferSize, start, stop);
+ m_upTo += numFrames;
+
+ return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+}
+
+std::wstring NativeFLACSourceFilter::VorbisCommentToString( const FLAC__StreamMetadata_VorbisComment_Entry& comment )
+{
+ std::wstring stringComment;
+
+ // Transform it from UTF-8 in wide chars
+ int chars = ::MultiByteToWideChar(CP_UTF8, 0, reinterpret_cast<const char*>(comment.entry), comment.length, 0, 0);
+ stringComment.resize(chars);
+
+ ::MultiByteToWideChar(CP_UTF8, 0, reinterpret_cast<const char*>(comment.entry), comment.length, &*stringComment.begin(), chars);
+
+ return stringComment;
+}
+
+void NativeFLACSourceFilter::metadata_callback(const FLAC__StreamMetadata* metadata)
+{
+ if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO)
+ {
+ m_numChannels = metadata->data.stream_info.channels;
+ m_sampleRate = metadata->data.stream_info.sample_rate;
+ m_significantBitsPerSample = metadata->data.stream_info.bits_per_sample;
+
+ m_bitsPerSample = (m_significantBitsPerSample + 7) & 0xfff8;
+
+ if (m_bitsPerSample == 24)
+ {
+ m_bitsPerSample = 32;
}
+
+ m_totalNumSamples = metadata->data.stream_info.total_samples;
+
+ LOG(logINFO) << L"NumChannels: " << m_numChannels;
+ LOG(logINFO) << L"SampleRate: " << m_sampleRate;
+ LOG(logINFO) << L"SignificantBitsPerSample: " << m_significantBitsPerSample;
+ LOG(logINFO) << L"BitsPerSample: " << m_bitsPerSample;
+ LOG(logINFO) << L"TotalNumSamples: " << m_totalNumSamples;
}
+ else if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT)
+ {
+ LOG(logINFO) << L"Vorbis Comment: " << metadata->data.vorbis_comment.num_comments;
+ LOG(logINFO) << L"Vendor String: " << VorbisCommentToString(metadata->data.vorbis_comment.vendor_string);
+ for (int i = 0; i < metadata->data.vorbis_comment.num_comments; ++i)
+ {
+ std::wstring comment = VorbisCommentToString(metadata->data.vorbis_comment.comments[i]);
+ LOG(logINFO) << comment;
-
- mFLACSourcePin->deliverData(locBuff, locBufferSize, (mUpto*UNITS) / mSampleRate, ((mUpto+locNumFrames)*UNITS) / mSampleRate);
- mUpto += locNumFrames;
- return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
+ int pos = comment.find_first_of(L'=');
+
+ std::wstring key = comment.substr(0, pos);
+ std::wstring value = comment.substr(pos + 1);
+
+ m_vorbisCommentsMap.insert(std::make_pair(key, value));
+ }
+ }
}
-void NativeFLACSourceFilter::metadata_callback(const FLAC__StreamMetadata* inMetaData) {
+void NativeFLACSourceFilter::error_callback(FLAC__StreamDecoderErrorStatus inStatus)
+{
+ LOG(logERROR) << "error_callback: status - " << inStatus;
}
-void NativeFLACSourceFilter::error_callback(FLAC__StreamDecoderErrorStatus inStatus) {
+bool NativeFLACSourceFilter::eof_callback()
+{
+ __int64 currentPosition = SeekFile(0, FILE_CURRENT);
+
+ bool isEof = false;
+ if (currentPosition == m_fileSize)
+ {
+ isEof = true;
+ }
+
+ return isEof;
}
-bool NativeFLACSourceFilter::eof_callback(void) {
- return mInputFile.eof();
+HRESULT __stdcall NativeFLACSourceFilter::GetCapabilities(DWORD* inCapabilities)
+{
+ *inCapabilities = AM_SEEKING_CanSeekAbsolute
+ | AM_SEEKING_CanSeekForwards
+ | AM_SEEKING_CanSeekBackwards
+ | AM_SEEKING_CanGetStopPos
+ | AM_SEEKING_CanGetDuration
+ | AM_SEEKING_CanGetCurrentPos;
+
+ LOG(logDEBUG) << "IMediaSeeking::GetCapabilities([out] " << std::hex << *inCapabilities << ") -> 0x" << std::hex << S_OK;
+
+ return S_OK;
}
+HRESULT __stdcall NativeFLACSourceFilter::CheckCapabilities(DWORD *pCapabilities)
+{
+ HRESULT result = S_OK;
+ DWORD dwActual;
+ GetCapabilities(&dwActual);
+ if (*pCapabilities & (~dwActual))
+ {
+ result = S_FALSE;
+ }
-STDMETHODIMP NativeFLACSourceFilter::GetCapabilities(DWORD* inCapabilities) {
- *inCapabilities = AM_SEEKING_CanSeekAbsolute |
- AM_SEEKING_CanSeekForwards |
- AM_SEEKING_CanSeekBackwards |
- AM_SEEKING_CanGetCurrentPos |
- AM_SEEKING_CanGetStopPos |
- AM_SEEKING_CanGetDuration;
- return S_OK;
+ LOG(logDEBUG) << "IMediaSeeking::CheckCapabilities([out] " << *pCapabilities << ") -> 0x" << std::hex << result;
+
+ return result;
}
-STDMETHODIMP NativeFLACSourceFilter::CheckCapabilities(DWORD *pCapabilities) {
- return E_NOTIMPL;
+
+HRESULT __stdcall NativeFLACSourceFilter::IsFormatSupported(const GUID *pFormat)
+{
+ HRESULT result = S_FALSE;
+
+ if (*pFormat == TIME_FORMAT_MEDIA_TIME)
+ {
+ result = S_OK;
+ }
+
+ LOG(logDEBUG) << "IMediaSeeking::IsFormatSupported([in] " << ToString(*pFormat) << ") -> 0x" << std::hex << result;
+
+ return result;
}
-STDMETHODIMP NativeFLACSourceFilter::IsFormatSupported(const GUID *pFormat) {
- if (*pFormat == TIME_FORMAT_MEDIA_TIME) {
- return S_OK;
- } else {
- return S_FALSE;
- }
+
+HRESULT __stdcall NativeFLACSourceFilter::QueryPreferredFormat(GUID *pFormat)
+{
+ *pFormat = TIME_FORMAT_MEDIA_TIME;
+
+ LOG(logDEBUG) << "IMediaSeeking::QueryPreferredFormat([out] " << ToString(*pFormat) << ") -> 0x" << std::hex << S_OK;
+
+ return S_OK;
}
-STDMETHODIMP NativeFLACSourceFilter::QueryPreferredFormat(GUID *pFormat) {
- *pFormat = TIME_FORMAT_MEDIA_TIME;
- return S_OK;
+
+HRESULT __stdcall NativeFLACSourceFilter::SetTimeFormat(const GUID *pFormat)
+{
+ LOG(logDEBUG) << "IMediaSeeking::SetTimeFormat([in] " << ToString(pFormat) << ") -> 0x" << std::hex << E_NOTIMPL;
+
+ return E_NOTIMPL;
}
-STDMETHODIMP NativeFLACSourceFilter::SetTimeFormat(const GUID *pFormat) {
- return E_NOTIMPL;
+
+HRESULT __stdcall NativeFLACSourceFilter::GetTimeFormat( GUID *pFormat)
+{
+ *pFormat = TIME_FORMAT_MEDIA_TIME;
+
+ LOG(logDEBUG) << "IMediaSeeking::GetTimeFormat([out] " << ToString(*pFormat) << ") -> 0x" << std::hex << S_OK;
+
+ return S_OK;
}
-STDMETHODIMP NativeFLACSourceFilter::GetTimeFormat( GUID *pFormat) {
- *pFormat = TIME_FORMAT_MEDIA_TIME;
- return S_OK;
+
+HRESULT __stdcall NativeFLACSourceFilter::GetDuration(LONGLONG *pDuration)
+{
+ *pDuration = m_totalNumSamples * UNITS / m_sampleRate;
+
+ LOG(logDEBUG) << "IMediaSeeking::GetDuration([out] " << ToString(*pDuration) << ") -> 0x" << std::hex << S_OK;
+
+ return S_OK;
}
-STDMETHODIMP NativeFLACSourceFilter::GetDuration(LONGLONG *pDuration) {
- *pDuration = (mTotalNumSamples * UNITS) / mSampleRate;
- return S_OK;
+
+HRESULT __stdcall NativeFLACSourceFilter::GetStopPosition(LONGLONG *pStop)
+{
+ *pStop = m_totalNumSamples * UNITS / m_sampleRate;
+
+ LOG(logDEBUG) << "IMediaSeeking::GetStopPosition([out] " << ToString(*pStop) << ") -> 0x" << std::hex << S_OK;
+
+ return S_OK;
}
-STDMETHODIMP NativeFLACSourceFilter::GetStopPosition(LONGLONG *pStop) {
- *pStop = (mTotalNumSamples * UNITS) / mSampleRate;
- return S_OK;
+
+HRESULT __stdcall NativeFLACSourceFilter::GetCurrentPosition(LONGLONG *pCurrent)
+{
+ *pCurrent = m_upTo * UNITS / m_sampleRate;
+
+ LOG(logDEBUG) << "IMediaSeeking::GetCurrentPosition([out] " << ToString(*pCurrent) << ") -> 0x" << std::hex << S_OK;
+
+ return S_OK;
}
-STDMETHODIMP NativeFLACSourceFilter::GetCurrentPosition(LONGLONG *pCurrent){
- return E_NOTIMPL;
+
+HRESULT __stdcall NativeFLACSourceFilter::ConvertTimeFormat(LONGLONG *pTarget, const GUID *pTargetFormat, LONGLONG Source, const GUID *pSourceFormat)
+{
+ LOG(logDEBUG) << "IMediaSeeking::ConvertTimeFormat([out] " << ToString(pTarget)
+ << ", [in] " << ToString(pTargetFormat) << ", [in] " << ToString(Source)
+ << ", [in] " << ToString(pSourceFormat) << ") -> 0x" << std::hex << E_NOTIMPL;
+
+ return E_NOTIMPL;
}
-STDMETHODIMP NativeFLACSourceFilter::ConvertTimeFormat(LONGLONG *pTarget, const GUID *pTargetFormat, LONGLONG Source, const GUID *pSourceFormat){
- return E_NOTIMPL;
+
+HRESULT __stdcall NativeFLACSourceFilter::SetPositions(LONGLONG *pCurrent,DWORD dwCurrentFlags,LONGLONG *pStop,DWORD dwStopFlags)
+{
+ unsigned __int64 locSampleToSeek = (*pCurrent) * m_sampleRate/ UNITS;
+
+ LOG(logDEBUG) << "IMediaSeeking::SetPositions([in, out] " << ToString(pCurrent) << ", [in] " << dwCurrentFlags
+ << ", [in, out] " << ToString(pStop) << ", [in] " << dwStopFlags << ") -> 0x" << std::hex << S_OK;
+
+ m_flacSourcePin->DeliverBeginFlush();
+ m_flacSourcePin->DeliverEndFlush();
+
+ m_seekRequest = locSampleToSeek;
+ m_justSeeked = true;
+
+
+ return S_OK;
}
-STDMETHODIMP NativeFLACSourceFilter::SetPositions(LONGLONG *pCurrent,DWORD dwCurrentFlags,LONGLONG *pStop,DWORD dwStopFlags){
- unsigned __int64 locSampleToSeek = (*pCurrent) * mSampleRate/ UNITS;
- mFLACSourcePin->DeliverBeginFlush();
- mFLACSourcePin->DeliverEndFlush();
- mJustSeeked = true;
- mSeekRequest = locSampleToSeek;
-
- return S_OK;
+HRESULT __stdcall NativeFLACSourceFilter::GetPositions(LONGLONG *pCurrent, LONGLONG *pStop)
+{
+ *pCurrent = m_upTo * UNITS / m_sampleRate;
+ *pStop = m_totalNumSamples * UNITS / m_sampleRate;
+
+ LOG(logDEBUG) << "IMediaSeeking::GetPositions([out] " << ToString(*pCurrent) << ", [out] " << ToString(*pStop)
+ << ") -> 0x" << std::hex << S_OK;
+
+ return S_OK;
}
-STDMETHODIMP NativeFLACSourceFilter::GetPositions(LONGLONG *pCurrent, LONGLONG *pStop){
- return E_NOTIMPL;
+
+HRESULT __stdcall NativeFLACSourceFilter::GetAvailable(LONGLONG *pEarliest, LONGLONG *pLatest)
+{
+ *pEarliest = 0;
+ *pLatest = m_totalNumSamples * UNITS / m_sampleRate;
+
+ LOG(logDEBUG) << "IMediaSeeking::GetAvailable([out] " << ToString(*pEarliest) << ", [out] " << ToString(*pLatest)
+ << ") -> 0x" << std::hex << S_OK;
+
+ return S_OK;
}
-STDMETHODIMP NativeFLACSourceFilter::GetAvailable(LONGLONG *pEarliest, LONGLONG *pLatest){
- *pEarliest = 0;
- *pLatest = (mTotalNumSamples * UNITS) / mSampleRate;
- return S_OK;
+
+HRESULT __stdcall NativeFLACSourceFilter::SetRate(double dRate)
+{
+ HRESULT result = VFW_E_UNSUPPORTED_AUDIO;
+
+ if (dRate == 1.00f)
+ {
+ result = S_OK;
+ }
+ else if (dRate <= 0.00f)
+ {
+ result = E_INVALIDARG;
+ }
+
+ LOG(logDEBUG) << "IMediaSeeking::SetRate([in] " << std::setprecision(3) << std::showpoint
+ << dRate << ") -> 0x" << std::hex << result;
+
+ return result;
}
-STDMETHODIMP NativeFLACSourceFilter::SetRate(double dRate){
- return E_NOTIMPL;
+
+HRESULT __stdcall NativeFLACSourceFilter::GetRate(double *dRate)
+{
+ *dRate = 1.0;
+
+ LOG(logDEBUG) << "IMediaSeeking::GetRate([out] " << std::setprecision(3) << std::showpoint
+ << *dRate << ") -> 0x" << std::hex << S_OK;
+
+ return S_OK;
}
-STDMETHODIMP NativeFLACSourceFilter::GetRate(double *dRate){
- *dRate = 1.0;
- return S_OK;
+
+HRESULT __stdcall NativeFLACSourceFilter::GetPreroll(LONGLONG *pllPreroll)
+{
+ *pllPreroll = 0;
+
+ LOG(logDEBUG) << "IMediaSeeking::GetPreroll([out] " << ToString(*pllPreroll) << ") -> 0x" << std::hex << S_OK;
+
+ return S_OK;
}
-STDMETHODIMP NativeFLACSourceFilter::GetPreroll(LONGLONG *pllPreroll){
- *pllPreroll = 0;
- return S_OK;
+
+HRESULT __stdcall NativeFLACSourceFilter::IsUsingTimeFormat(const GUID *pFormat)
+{
+ HRESULT result = S_FALSE;
+
+ if (*pFormat == TIME_FORMAT_MEDIA_TIME)
+ {
+ result = S_OK;
+ }
+
+ LOG(logDEBUG) << "IMediaSeeking::IsUsingTimeFormat([in] " << ToString(*pFormat) << ") -> 0x" << std::hex << result;
+
+ return result;
}
-STDMETHODIMP NativeFLACSourceFilter::IsUsingTimeFormat(const GUID *pFormat){
- if (*pFormat == TIME_FORMAT_MEDIA_TIME) {
- return S_OK;
- } else {
- return S_FALSE;
- }
-}
\ No newline at end of file
+
+
Modified: trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.h 2009-10-12 22:20:48 UTC (rev 16643)
+++ trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.h 2009-10-13 21:54:34 UTC (rev 16644)
@@ -1,5 +1,6 @@
//===========================================================================
//Copyright (C) 2003, 2004 Zentaro Kavanagh
+//Copyright (C) 2008, 2009 Cristian Adam
//
//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions
@@ -29,126 +30,125 @@
//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//===========================================================================
#pragma once
-//Local Includes
-#include "dsfNativeFLACSource.h"
-#include "NativeFLACSourcePin.h"
-//Library Includes
-#include "FLAC++/decoder.h"
-#include <libilliCore/StringHelper.h>
-#include <libilliCore/iBE_Math.h>
-#include "FLAC/seekable_stream_decoder.h"
-#include "FLAC/stream_decoder.h"
-using namespace FLAC::Decoder;
+#include <FLAC++/decoder.h>
+#include <FLAC/seekable_stream_decoder.h>
+#include <FLAC/stream_decoder.h>
-//STL Includes
-#include <string>
-using namespace std;
-
//Forward Declarations
class NativeFLACSourcePin;
-class NativeFLACSourceFilter
- //Base Classes
- : public CBaseFilter
- , public IFileSourceFilter
- , public IAMFilterMiscFlags
- , public IMediaSeeking
- , public CAMThread
- , protected FLAC::Decoder::Stream
+class NativeFLACSourceFilter: public CBaseFilter, public IFileSourceFilter, public IAMFilterMiscFlags,
+ public IMediaSeeking, public CAMThread, protected FLAC::Decoder::Stream
{
public:
- //Friends
- friend class NativeFLACSourcePin;
+ //Friends
+ friend class NativeFLACSourcePin;
- //Constants
- enum eThreadCommands {
- THREAD_EXIT = 0,
- THREAD_PAUSE = 1,
- THREAD_RUN = 2
- };
+ //Constants
+ enum eThreadCommands
+ {
+ THREAD_EXIT = 0,
+ THREAD_PAUSE = 1,
+ THREAD_RUN = 2
+ };
- //COM Stuff
- DECLARE_IUNKNOWN
- STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
- static CUnknown* WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr);
+ static const unsigned long BUFF_SIZE = 8192;
- //Constructors
- NativeFLACSourceFilter(void);
- virtual ~NativeFLACSourceFilter(void);
+#ifdef WINCE
+ // returns setup data for filter registration
+ LPAMOVIESETUP_FILTER GetSetupData();
+#endif
- //IBaseFilter Pure Virtuals
- virtual int GetPinCount();
- virtual CBasePin* GetPin(int inPinNo);
+ //COM Stuff
+ DECLARE_IUNKNOWN
+ HRESULT __stdcall NonDelegatingQueryInterface(REFIID riid, void **ppv);
+ static CUnknown* WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *pHr);
- //IAMFilterMiscFlags Interface
- ULONG STDMETHODCALLTYPE GetMiscFlags(void);
+ NativeFLACSourceFilter();
+ virtual ~NativeFLACSourceFilter();
- //IFileSource Interface
- virtual STDMETHODIMP GetCurFile(LPOLESTR* outFileName, AM_MEDIA_TYPE* outMediaType);
- virtual STDMETHODIMP Load(LPCOLESTR inFileName, const AM_MEDIA_TYPE* inMediaType);
+ //IBaseFilter Pure virtuals
+ virtual int GetPinCount();
+ virtual CBasePin* GetPin(int inPinNo);
- //Streaming MEthods
- STDMETHODIMP Run(REFERENCE_TIME tStart);
- STDMETHODIMP Pause(void);
- STDMETHODIMP Stop(void);
+ //IAMFilterMiscFlags Interface
+ ULONG __stdcall GetMiscFlags();
- //CAMThread
- virtual DWORD ThreadProc(void);
+ //IFileSource Interface
+ virtual HRESULT __stdcall GetCurFile(LPOLESTR* outFileName, AM_MEDIA_TYPE* outMediaType);
+ virtual HRESULT __stdcall Load(LPCOLESTR inFileName, const AM_MEDIA_TYPE* inMediaType);
- //FLAC Virtuals
- virtual ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte outBuffer[], size_t* outNumBytes);
- virtual ::FLAC__StreamDecoderSeekStatus seek_callback(FLAC__uint64 inSeekPos);
- virtual ::FLAC__StreamDecoderTellStatus tell_callback(FLAC__uint64* outTellPos);
- virtual ::FLAC__StreamDecoderLengthStatus length_callback(FLAC__uint64* outLength);
- virtual ::FLAC__StreamDecoderWriteStatus write_callback(const FLAC__Frame* outFrame,const FLAC__int32 *const outBuffer[]);
- virtual void metadata_callback(const FLAC__StreamMetadata* inMetaData);
- virtual void error_callback(FLAC__StreamDecoderErrorStatus inStatus);
- virtual bool eof_callback(void);
+ //Streaming Methods
+ HRESULT __stdcall Run(REFERENCE_TIME tStart);
+ HRESULT __stdcall Pause();
+ HRESULT __stdcall Stop();
- //IMediaSeeking Interface
- virtual STDMETHODIMP GetCapabilities(DWORD *pCapabilities);
- virtual STDMETHODIMP CheckCapabilities(DWORD *pCapabilities);
- virtual STDMETHODIMP IsFormatSupported(const GUID *pFormat);
- virtual STDMETHODIMP QueryPreferredFormat(GUID *pFormat);
- virtual STDMETHODIMP SetTimeFormat(const GUID *pFormat);
- virtual STDMETHODIMP GetTimeFormat( GUID *pFormat);
- virtual STDMETHODIMP GetDuration(LONGLONG *pDuration);
- virtual STDMETHODIMP GetStopPosition(LONGLONG *pStop);
- virtual STDMETHODIMP GetCurrentPosition(LONGLONG *pCurrent);
- virtual STDMETHODIMP ConvertTimeFormat(LONGLONG *pTarget, const GUID *pTargetFormat, LONGLONG Source, const GUID *pSourceFormat);
- virtual STDMETHODIMP SetPositions(LONGLONG *pCurrent,DWORD dwCurrentFlags,LONGLONG *pStop,DWORD dwStopFlags);
- virtual STDMETHODIMP GetPositions(LONGLONG *pCurrent, LONGLONG *pStop);
- virtual STDMETHODIMP GetAvailable(LONGLONG *pEarliest, LONGLONG *pLatest);
- virtual STDMETHODIMP SetRate(double dRate);
- virtual STDMETHODIMP GetRate(double *dRate);
- virtual STDMETHODIMP GetPreroll(LONGLONG *pllPreroll);
- virtual STDMETHODIMP IsUsingTimeFormat(const GUID *pFormat);
+ //CAMThread
+ virtual DWORD ThreadProc();
+ //FLAC virtuals
+ virtual ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte outBuffer[], size_t* outNumBytes);
+ virtual ::FLAC__StreamDecoderSeekStatus seek_callback(FLAC__uint64 inSeekPos);
+ virtual ::FLAC__StreamDecoderTellStatus tell_callback(FLAC__uint64* outTellPos);
+ virtual ::FLAC__StreamDecoderLengthStatus length_callback(FLAC__uint64* outLength);
+ virtual ::FLAC__StreamDecoderWriteStatus write_callback(const FLAC__Frame* outFrame,const FLAC__int32 *const outBuffer[]);
+ virtual void metadata_callback(const FLAC__StreamMetadata* inMetaData);
+ virtual void error_callback(FLAC__StreamDecoderErrorStatus inStatus);
+ virtual bool eof_callback();
+
+ //IMediaSeeking Interface
+ HRESULT __stdcall GetCapabilities(DWORD *pCapabilities);
+ HRESULT __stdcall CheckCapabilities(DWORD *pCapabilities);
+ HRESULT __stdcall IsFormatSupported(const GUID *pFormat);
+ HRESULT __stdcall QueryPreferredFormat(GUID *pFormat);
+ HRESULT __stdcall SetTimeFormat(const GUID *pFormat);
+ HRESULT __stdcall GetTimeFormat(GUID *pFormat);
+ HRESULT __stdcall GetDuration(LONGLONG *pDuration);
+ HRESULT __stdcall GetStopPosition(LONGLONG *pStop);
+ HRESULT __stdcall GetCurrentPosition(LONGLONG *pCurrent);
+ HRESULT __stdcall ConvertTimeFormat(LONGLONG *pTarget, const GUID *pTargetFormat, LONGLONG Source, const GUID *pSourceFormat);
+ HRESULT __stdcall SetPositions(LONGLONG *pCurrent,DWORD dwCurrentFlags,LONGLONG *pStop,DWORD dwStopFlags);
+ HRESULT __stdcall GetPositions(LONGLONG *pCurrent, LONGLONG *pStop);
+ HRESULT __stdcall GetAvailable(LONGLONG *pEarliest, LONGLONG *pLatest);
+ HRESULT __stdcall SetRate(double dRate);
+ HRESULT __stdcall GetRate(double *dRate);
+ HRESULT __stdcall GetPreroll(LONGLONG *pllPreroll);
+ HRESULT __stdcall IsUsingTimeFormat(const GUID *pFormat);
+
protected:
- //Helper Methods
- HRESULT DataProcessLoop();
+ //Helper Methods
+ HRESULT DataProcessLoop();
- //Pin Class
- NativeFLACSourcePin* mFLACSourcePin;
+ __int64 SeekFile(__int64 distance, unsigned long moveMethod);
+ __int64 SeekFile(LARGE_INTEGER distance, unsigned long moveMethod);
- //Source File Members
- wstring mFileName;
- fstream mInputFile;
- unsigned long mFileSize;
+ std::wstring VorbisCommentToString(const FLAC__StreamMetadata_VorbisComment_Entry& comment);
- //State Variables
- bool mBegun;
- bool mJustSeeked;
- __int64 mSeekRequest;
- bool mWasEOF;
- unsigned long mUpto;
+ //Pin Class
+ NativeFLACSourcePin* m_flacSourcePin;
- //Stream info data.
- unsigned long mNumChannels;
- unsigned long mFrameSize;
- unsigned long mSampleRate;
- unsigned long mBitsPerSample;
- unsigned long mSignificantBitsPerSample;
- __int64 mTotalNumSamples;
+ //Source File Members
+ std::wstring m_fileName;
+ HANDLE m_inputFileHandle;
+ __int64 m_fileSize;
+ unsigned long m_extraBeginDataLength;
+
+ //State Variables
+ bool m_begun;
+ bool m_justSeeked;
+ __int64 m_seekRequest;
+ bool m_wasEof;
+ unsigned long m_upTo;
+
+ //Stream info data.
+ unsigned short m_numChannels;
+ unsigned long m_frameSize;
+ unsigned long m_sampleRate;
+ unsigned short m_bitsPerSample;
+ unsigned short m_significantBitsPerSample;
+ __int64 m_totalNumSamples;
+
+ typedef std::multimap<std::wstring, std::wstring> VorbisCommentMap;
+ VorbisCommentMap m_vorbisCommentsMap;
};
Modified: trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp 2009-10-12 22:20:48 UTC (rev 16643)
+++ trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp 2009-10-13 21:54:34 UTC (rev 16644)
@@ -1,5 +1,6 @@
//===========================================================================
//Copyright (C) 2003, 2004 Zentaro Kavanagh
+//Copyright (C) 2008, 2009 Cristian Adam
//
//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions
@@ -29,277 +30,321 @@
//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//===========================================================================
#include "stdafx.h"
-#include ".\NativeFLACSourcePin.h"
+#include "NativeFLACSourcePin.h"
+#include "dsfNativeFLACSource.h"
-NativeFLACSourcePin::NativeFLACSourcePin(NativeFLACSourceFilter* inParentFilter, CCritSec* inFilterLock)
- : CBaseOutputPin(NAME("Native FLAC Source Pin"), inParentFilter, inFilterLock, &mFilterHR, L"PCM Out")
- , mParentFilter(inParentFilter)
- , mDataQueue(NULL)
+#include <sstream>
+NativeFLACSourcePin::NativeFLACSourcePin(NativeFLACSourceFilter* inParentFilter, CCritSec* inFilterLock):
+CBaseOutputPin(NAME("Native FLAC Source Pin"), inParentFilter, inFilterLock, &m_filterHR, L"PCM Out"),
+m_parentFilter(inParentFilter),
+m_dataQueue(NULL),
+m_haveDiscontinuity(true)
{
- //Subvert COM and do this directly... this way, the source filter won't expose the interface to the
- // graph but we can still delegate to it.
- IMediaSeeking* locSeeker = NULL;
- locSeeker = (IMediaSeeking*)mParentFilter;
- SetDelegate(locSeeker);
+ //Subvert COM and do this directly... this way, the source filter won't expose the interface to the
+ // graph but we can still delegate to it.
+ IMediaSeeking* locSeeker = NULL;
+ locSeeker = (IMediaSeeking*)m_parentFilter;
+ SetDelegate(locSeeker);
}
NativeFLACSourcePin::~NativeFLACSourcePin(void)
{
- SetDelegate(NULL); //Avoid infinite destructor loop.
- delete mDataQueue;
- mDataQueue = NULL;
+ SetDelegate(NULL); //Avoid infinite destructor loop.
+ delete m_dataQueue;
+ m_dataQueue = NULL;
}
-STDMETHODIMP NativeFLACSourcePin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
+HRESULT __stdcall NativeFLACSourcePin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
- if (riid == IID_IMediaSeeking) {
- *ppv = (IMediaSeeking*)this;
- ((IUnknown*)*ppv)->AddRef();
- return NOERROR;
- }
- return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv);
+ if (riid == IID_IMediaSeeking)
+ {
+ return GetInterface((IMediaSeeking*) this, ppv);
+ }
+
+ return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv);
}
HRESULT NativeFLACSourcePin::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate)
{
- mDataQueue->NewSegment(tStart, tStop, dRate);
- return S_OK;
+ LOG(logINFO) << "DeliverNewSegment: start " << ReferenceTime(tStart) << ", end " << ReferenceTime(tStop);
+
+ if (m_dataQueue != 0)
+ {
+ m_dataQueue->NewSegment(tStart, tStop, dRate);
+ }
+
+ return S_OK;
}
-HRESULT NativeFLACSourcePin::DeliverEndOfStream(void)
+
+HRESULT NativeFLACSourcePin::DeliverEndOfStream()
{
- mDataQueue->EOS();
+ if (m_dataQueue != 0)
+ {
+ m_dataQueue->EOS();
+ }
+
return S_OK;
}
-HRESULT NativeFLACSourcePin::DeliverEndFlush(void)
+HRESULT NativeFLACSourcePin::DeliverEndFlush()
{
- mDataQueue->EndFlush();
+ if (m_dataQueue != 0)
+ {
+ m_dataQueue->EndFlush();
+ }
+
+ m_haveDiscontinuity = true;
+
return S_OK;
}
-HRESULT NativeFLACSourcePin::DeliverBeginFlush(void)
+HRESULT NativeFLACSourcePin::DeliverBeginFlush()
{
- mDataQueue->BeginFlush();
+ if (m_dataQueue != 0)
+ {
+ m_dataQueue->BeginFlush();
+ }
+
return S_OK;
}
HRESULT NativeFLACSourcePin::CompleteConnect (IPin *inReceivePin)
{
- mFilterHR = S_OK;
- //Deleted in destructor
- mDataQueue = new COutputQueue (inReceivePin, &mFilterHR, FALSE, TRUE,1,TRUE, NUM_BUFFERS);
- if (FAILED(mFilterHR)) {
- //TODO::: Probably should handle this !
+ m_filterHR = S_OK;
+ //Deleted in destructor
+ m_dataQueue = new COutputQueue (inReceivePin, &m_filterHR, FALSE, TRUE, 1, TRUE, NUM_BUFFERS);
+
+ if (FAILED(m_filterHR))
+ {
+ //TODO::: Probably should handle this !
//CHECK::: See if it ever silently reports failure but actually does work before bailing here.
-
- mFilterHR = mFilterHR;
- }
-
- return CBaseOutputPin::CompleteConnect(inReceivePin);
+ }
+
+ return CBaseOutputPin::CompleteConnect(inReceivePin);
}
-HRESULT NativeFLACSourcePin::BreakConnect(void) {
- delete mDataQueue;
- mDataQueue = NULL;
- return CBaseOutputPin::BreakConnect();
+HRESULT NativeFLACSourcePin::BreakConnect()
+{
+ delete m_dataQueue;
+ m_dataQueue = NULL;
+ return CBaseOutputPin::BreakConnect();
}
-
HRESULT NativeFLACSourcePin::SetMediaType(const CMediaType* inMediaType)
{
-
- if (((WAVEFORMATEX*)inMediaType->pbFormat)->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
- //mUsingExtendedWave = true;
- } else if (((WAVEFORMATEX*)inMediaType->pbFormat)->wFormatTag == WAVE_FORMAT_PCM) {
- //mUsingExtendedWave = false;
- }
-
return CBaseOutputPin::SetMediaType(inMediaType);
+}
-}
-HRESULT NativeFLACSourcePin::GetMediaType(int inPosition, CMediaType* outMediaType)
+void NativeFLACSourcePin::FillMediaType(CMediaType& mediaType, bool useWaveFormatEx)
{
- //WFE::: Also offer extensible format
- if (inPosition == 0) {
- outMediaType->SetType(&MEDIATYPE_Audio);
- outMediaType->SetSubtype(&MEDIASUBTYPE_PCM);
- outMediaType->SetFormatType(&FORMAT_WaveFormatEx);
- outMediaType->SetTemporalCompression(FALSE);
- outMediaType->SetSampleSize(0);
+ if (useWaveFormatEx)
+ {
+ // Windows CE doesn't have ksmedia.h, or at least Windows CE 5.0
+#ifndef WINCE
+ mediaType.SetType(&MEDIATYPE_Audio);
+ mediaType.SetSubtype(&MEDIASUBTYPE_PCM);
+ mediaType.SetFormatType(&FORMAT_WaveFormatEx);
+ mediaType.SetTemporalCompression(FALSE);
+ mediaType.SetSampleSize(0);
- WAVEFORMATEXTENSIBLE* locFormatEx = (WAVEFORMATEXTENSIBLE*)outMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEXTENSIBLE));
-
- locFormatEx->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
+ WAVEFORMATEXTENSIBLE* formatEx = (WAVEFORMATEXTENSIBLE*)mediaType.AllocFormatBuffer(sizeof(WAVEFORMATEXTENSIBLE));
- locFormatEx->Format.nChannels = (WORD)mParentFilter->mNumChannels;
- locFormatEx->Format.nSamplesPerSec = mParentFilter->mSampleRate;
+ formatEx->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
-
- locFormatEx->Samples.wValidBitsPerSample = (WORD)mParentFilter->mSignificantBitsPerSample;
+ formatEx->Format.nChannels = m_parentFilter->m_numChannels;
+ formatEx->Format.nSamplesPerSec = m_parentFilter->m_sampleRate;
- switch (locFormatEx->Format.nChannels)
+ formatEx->Samples.wValidBitsPerSample = m_parentFilter->m_significantBitsPerSample;
+
+ switch (formatEx->Format.nChannels)
{
case 1:
- locFormatEx->dwChannelMask = SPEAKER_FRONT_LEFT;
+ formatEx->dwChannelMask = KSAUDIO_SPEAKER_MONO;
break;
case 2:
- locFormatEx->dwChannelMask = SPEAKER_FRONT_LEFT |
- SPEAKER_FRONT_RIGHT;
+ formatEx->dwChannelMask = KSAUDIO_SPEAKER_STEREO;
break;
case 3:
- locFormatEx->dwChannelMask = SPEAKER_FRONT_LEFT |
- SPEAKER_FRONT_RIGHT |
- SPEAKER_FRONT_CENTER;
+ formatEx->dwChannelMask = SPEAKER_FRONT_LEFT
+ | SPEAKER_FRONT_RIGHT
+ | SPEAKER_FRONT_CENTER;
break;
case 4:
- locFormatEx->dwChannelMask = SPEAKER_FRONT_LEFT |
- SPEAKER_FRONT_RIGHT |
- SPEAKER_BACK_LEFT |
- SPEAKER_BACK_RIGHT;
+ formatEx->dwChannelMask = KSAUDIO_SPEAKER_QUAD;
break;
case 5:
- locFormatEx->dwChannelMask = SPEAKER_FRONT_LEFT |
- SPEAKER_FRONT_RIGHT |
- SPEAKER_FRONT_CENTER |
- SPEAKER_BACK_LEFT |
- SPEAKER_BACK_RIGHT;
+ formatEx->dwChannelMask = SPEAKER_FRONT_LEFT
+ | SPEAKER_FRONT_RIGHT
+ | SPEAKER_FRONT_CENTER
+ | SPEAKER_BACK_LEFT
+ | SPEAKER_BACK_RIGHT;
break;
-
case 6:
- locFormatEx->dwChannelMask = SPEAKER_FRONT_LEFT |
- SPEAKER_FRONT_RIGHT |
- SPEAKER_FRONT_CENTER |
- SPEAKER_LOW_FREQUENCY |
- SPEAKER_BACK_LEFT |
- SPEAKER_BACK_RIGHT;
+ formatEx->dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
break;
-
+ case 8:
+ formatEx->dwChannelMask = KSAUDIO_SPEAKER_7POINT1;
+ break;
default:
- locFormatEx->dwChannelMask = 0;
+ formatEx->dwChannelMask = 0;
break;
-
-
}
- ////TODO::: Round up to multiple of 8 or something
- //if (mParentFilter->mBitsPerSample <= 16) {
- // //Round up to multiple of 8, ie 8 or 16
- // locFormatEx->Format.wBitsPerSample = (WORD)(mParentFilter->mBitsPerSample + 7) & 0xfff8;
- //} else if (mParentFilter->mBitsPerSample <= 32) {
- // //Just use 32
- // locFormatEx->Format.wBitsPerSample = 32;
- //}
- locFormatEx->Format.wBitsPerSample = (WORD)mParentFilter->mBitsPerSample;
- locFormatEx->Format.nBlockAlign = (WORD)((mParentFilter->mNumChannels) * (mParentFilter->mBitsPerSample >> 3));
- locFormatEx->Format.nAvgBytesPerSec = ((mParentFilter->mNumChannels) * (mParentFilter->mBitsPerSample >> 3)) * mParentFilter->mSampleRate;
- locFormatEx->Format.cbSize = 22; //sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
- locFormatEx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+ formatEx->Format.wBitsPerSample = m_parentFilter->m_bitsPerSample;
+ formatEx->Format.nBlockAlign = m_parentFilter->m_numChannels * (m_parentFilter->m_bitsPerSample >> 3);
+ formatEx->Format.nAvgBytesPerSec = formatEx->Format.nBlockAlign * m_parentFilter->m_sampleRate;
+ formatEx->Format.cbSize = 22; //sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
+ formatEx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+#endif
+ }
+ else
+ {
+ mediaType.SetType(&MEDIATYPE_Audio);
+ mediaType.SetSubtype(&MEDIASUBTYPE_PCM);
+ mediaType.SetFormatType(&FORMAT_WaveFormatEx);
+ mediaType.SetTemporalCompression(FALSE);
+ mediaType.SetSampleSize(0);
- return S_OK;
+ WAVEFORMATEX* format = (WAVEFORMATEX*)mediaType.AllocFormatBuffer(sizeof(WAVEFORMATEX));
+ format->wFormatTag = WAVE_FORMAT_PCM;
- //mUsingExtendedWav = true;
- } else if (inPosition == 1) {
- outMediaType->SetType(&MEDIATYPE_Audio);
- outMediaType->SetSubtype(&MEDIASUBTYPE_PCM);
- outMediaType->SetFormatType(&FORMAT_WaveFormatEx);
- outMediaType->SetTemporalCompression(FALSE);
- outMediaType->SetSampleSize(0);
+ format->nChannels = m_parentFilter->m_numChannels;
+ format->nSamplesPerSec = m_parentFilter->m_sampleRate;
+ format->wBitsPerSample = m_parentFilter->m_bitsPerSample;
+ format->nBlockAlign = m_parentFilter->m_numChannels * (m_parentFilter->m_bitsPerSample >> 3);
+ format->nAvgBytesPerSec = format->nBlockAlign * m_parentFilter->m_sampleRate;
+ format->cbSize = 0;
+ }
+}
- WAVEFORMATEX* locFormat = (WAVEFORMATEX*)outMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEX));
- locFormat->wFormatTag = WAVE_FORMAT_PCM;
+HRESULT NativeFLACSourcePin::GetMediaType(int inPosition, CMediaType* outMediaType)
+{
+ if (outMediaType == 0)
+ {
+ return E_POINTER;
+ }
- locFormat->nChannels = (WORD)mParentFilter->mNumChannels;
- locFormat->nSamplesPerSec = mParentFilter->mSampleRate;
- locFormat->wBitsPerSample = (WORD)mParentFilter->mBitsPerSample;
- locFormat->nBlockAlign = (WORD)((mParentFilter->mNumChannels) * (mParentFilter->mBitsPerSample >> 3));
- locFormat->nAvgBytesPerSec = ((mParentFilter->mNumChannels) * (mParentFilter->mBitsPerSample >> 3)) * mParentFilter->mSampleRate;
- locFormat->cbSize = 0;
- //mUsingExtendedWav = false;
-
- return S_OK;
+ HRESULT result = VFW_S_NO_MORE_ITEMS;
- } else {
- return VFW_S_NO_MORE_ITEMS;
- }
+#ifdef WINCE
+ if (inPosition == 0)
+ {
+ FillMediaType(*outMediaType, false);
+ result = S_OK;
+ }
+#else
+ if (inPosition == 0)
+ {
+ FillMediaType(*outMediaType, true);
+
+ result = S_OK;
+ }
+ else if (inPosition == 1)
+ {
+ FillMediaType(*outMediaType, false);
+
+ result = S_OK;
+ }
+#endif
+
+ return result;
}
+
HRESULT NativeFLACSourcePin::CheckMediaType(const CMediaType* inMediaType)
{
//WFE::: Do check for extensible type
- if ( (inMediaType->majortype == MEDIATYPE_Audio)
- && (inMediaType->subtype == MEDIASUBTYPE_PCM)
- && (inMediaType->formattype == FORMAT_WaveFormatEx)) {
- return S_OK;
- } else {
- return E_FAIL;
- }
+ if (inMediaType->majortype == MEDIATYPE_Audio &&
+ inMediaType->subtype == MEDIASUBTYPE_PCM &&
+ inMediaType->formattype == FORMAT_WaveFormatEx)
+ {
+ return S_OK;
+ }
+ else
+ {
+ return E_FAIL;
+ }
}
+
HRESULT NativeFLACSourcePin::DecideBufferSize(IMemAllocator* inoutAllocator, ALLOCATOR_PROPERTIES* inoutInputRequest)
{
- HRESULT locHR = S_OK;
+ HRESULT hr = S_OK;
- ALLOCATOR_PROPERTIES locReqAlloc;
- ALLOCATOR_PROPERTIES locActualAlloc;
+ ALLOCATOR_PROPERTIES reqAlloc;
+ ALLOCATOR_PROPERTIES actualAlloc;
- locReqAlloc.cbAlign = 1;
- locReqAlloc.cbBuffer = BUFFER_SIZE;
- locReqAlloc.cbPrefix = 0;
- locReqAlloc.cBuffers = NUM_BUFFERS;
+ reqAlloc.cbAlign = 1;
+ reqAlloc.cbBuffer = m_parentFilter->m_numChannels * (m_parentFilter->m_bitsPerSample >> 3) * m_parentFilter->m_sampleRate;
+ reqAlloc.cbPrefix = 0;
+ reqAlloc.cBuffers = NUM_BUFFERS;
- locHR = inoutAllocator->SetProperties(&locReqAlloc, &locActualAlloc);
+ hr = inoutAllocator->SetProperties(&reqAlloc, &actualAlloc);
- if (locHR != S_OK) {
- return locHR;
- }
-
- locHR = inoutAllocator->Commit();
+ if (hr != S_OK)
+ {
+ return hr;
+ }
+
+ hr = inoutAllocator->Commit();
- return locHR;
+ return hr;
}
//This method is responsible for deleting the incoming buffer.
-HRESULT NativeFLACSourcePin::deliverData(unsigned char* inBuff, unsigned long inBuffSize, __int64 inStart, __int64 inEnd)
+HRESULT NativeFLACSourcePin::DeliverData(unsigned char* inBuff, unsigned long inBuffSize, __int64 inStart, __int64 inEnd)
{
- //Locks !!
-
- IMediaSample* locSample = NULL;
- REFERENCE_TIME locStart = inStart;
- REFERENCE_TIME locStop = inEnd;
-
- HRESULT locHR = GetDeliveryBuffer(&locSample, &locStart, &locStop, NULL);
-
- //Error checks
- if (locHR != S_OK) {
- delete[] inBuff;
- return locHR;
- }
+ //Locks !!
+
+ IMediaSample* pSample = NULL;
+ REFERENCE_TIME locStart = inStart;
+ REFERENCE_TIME locStop = inEnd;
+
+ HRESULT locHR = GetDeliveryBuffer(&pSample, &locStart, &locStop, NULL);
+
+ //Error checks
+ if (locHR != S_OK)
+ {
+ delete[] inBuff;
+ return locHR;
+ }
- locSample->SetTime(&locStart, &locStop);
-
- locSample->SetSyncPoint(TRUE);
+ pSample->SetTime(&locStart, &locStop);
+
+ pSample->SetSyncPoint(TRUE);
- // Create a pointer for the samples buffer
- BYTE* locBuffer = NULL;
- locSample->GetPointer(&locBuffer);
+ // Create a pointer for the samples buffer
+ BYTE* locBuffer = NULL;
+ pSample->GetPointer(&locBuffer);
- //*** WARNING 4018 ::: leave this.
- if (locSample->GetSize() >= inBuffSize) {
- memcpy((void*)locBuffer, (const void*)inBuff, inBuffSize);
- locSample->SetActualDataLength(inBuffSize);
+ unsigned long sampleSize = pSample->GetSize();
- locHR = mDataQueue->Receive(locSample);
+ if (m_haveDiscontinuity)
+ {
+ m_haveDiscontinuity = false;
- if (locHR != S_OK) {
- delete[] inBuff;
- return locHR;
-
- } else {
- delete[] inBuff;
- return S_OK;
- }
- } else {
- delete[] inBuff;
- throw 0;
- }
+ pSample->SetDiscontinuity(true);
+
+ DeliverNewSegment(locStart, locStop, 1.0);
+ }
+
+ if (sampleSize >= inBuffSize)
+ {
+ memcpy((void*)locBuffer, (const void*)inBuff, inBuffSize);
+ pSample->SetActualDataLength(inBuffSize);
+
+ locHR = m_dataQueue->Receive(pSample);
+
+ LOG(logDEBUG3) << "Deliver Data: size " << inBuffSize << ", hr: 0x" << std::hex << locHR
+ << ", Start: " << ToString(locStart) << ", Stop: " << ToString(locStop);
+
+ delete [] inBuff;
+ return locHR;
+ }
+ else
+ {
+ delete[] inBuff;
+ throw 0;
+ }
}
+
Modified: trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.h 2009-10-12 22:20:48 UTC (rev 16643)
+++ trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.h 2009-10-13 21:54:34 UTC (rev 16644)
@@ -1,5 +1,6 @@
//===========================================================================
//Copyright (C) 2003, 2004 Zentaro Kavanagh
+//Copyright (C) 2008, 2009 Cristian Adam
//
//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions
@@ -31,56 +32,52 @@
#pragma once
-//Local Includes
-#include "dsfNativeFLACSource.h"
-
//Library Includes
#include "BasicSeekPassThrough.h"
-//Kernel streaming header for KSDATA_FORMAT_SUBTYPE_PCM
-#include "ks.h"
-#include "ksmedia.h"
-
//Forward Declararions.
class NativeFLACSourceFilter;
-class NativeFLACSourcePin
- //Base classes.
- : public CBaseOutputPin
- , public BasicSeekPassThrough
+
+class NativeFLACSourcePin: public CBaseOutputPin, public BasicSeekPassThrough
{
public:
- //COM Stuff
- DECLARE_IUNKNOWN
- STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
+ //Constants
+ static const unsigned long NUM_BUFFERS = 4;
- //Constructors.
- NativeFLACSourcePin( NativeFLACSourceFilter* inParentFilter, CCritSec* inFilterLock);
- virtual ~NativeFLACSourcePin(void);
+public:
+ //COM Stuff
+ DECLARE_IUNKNOWN
+ HRESULT __stdcall NonDelegatingQueryInterface(REFIID riid, void **ppv);
- //Constants
- static const unsigned long BUFFER_SIZE = 65536; //What should this be ????
- static const unsigned long NUM_BUFFERS = 10;
+ //Constructors.
+ NativeFLACSourcePin(NativeFLACSourceFilter* inParentFilter, CCritSec* inFilterLock);
+ virtual ~NativeFLACSourcePin(void);
- //CBaseOutputPin virtuals
- virtual HRESULT GetMediaType(int inPosition, CMediaType* outMediaType);
+ //CBaseOutputPin virtuals
+ virtual HRESULT GetMediaType(int inPosition, CMediaType* outMediaType);
virtual HRESULT SetMediaType(const CMediaType* inMediaType);
- virtual HRESULT CheckMediaType(const CMediaType* inMediaType);
- virtual HRESULT DecideBufferSize(IMemAllocator* inoutAllocator, ALLOCATOR_PROPERTIES* inoutInputRequest);
+ virtual HRESULT CheckMediaType(const CMediaType* inMediaType);
+ virtual HRESULT DecideBufferSize(IMemAllocator* inoutAllocator, ALLOCATOR_PROPERTIES* inoutInputRequest);
- //IPin virtuals
- virtual HRESULT CompleteConnect (IPin *inReceivePin);
- virtual HRESULT BreakConnect(void);
- virtual HRESULT DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
- virtual HRESULT DeliverEndOfStream(void);
- virtual HRESULT DeliverEndFlush(void);
- virtual HRESULT DeliverBeginFlush(void);
+ //IPin virtuals
+ virtual HRESULT CompleteConnect (IPin *inReceivePin);
+ virtual HRESULT BreakConnect(void);
+ virtual HRESULT DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
+ virtual HRESULT DeliverEndOfStream(void);
+ virtual HRESULT DeliverEndFlush(void);
+ virtual HRESULT DeliverBeginFlush(void);
- //Helper method
- HRESULT deliverData(unsigned char* inBuff, unsigned long inBuffSize, __int64 inStart, __int64 inEnd);
+ //Helper method
+ HRESULT DeliverData(unsigned char* inBuff, unsigned long inBuffSize, __int64 inStart, __int64 inEnd);
+
+ void FillMediaType(CMediaType& mediaType, bool useWaveFormatEx);
+
protected:
- HRESULT mFilterHR;
-
- //Member variables.
- COutputQueue* mDataQueue;
- NativeFLACSourceFilter* mParentFilter;
+ HRESULT m_filterHR;
+
+ //Member variables.
+ COutputQueue* m_dataQueue;
+ NativeFLACSourceFilter* m_parentFilter;
+
+ bool m_haveDiscontinuity;
};
Added: trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/Resources.rc
===================================================================
--- trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/Resources.rc (rev 0)
+++ trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/Resources.rc 2009-10-13 21:54:34 UTC (rev 16644)
@@ -0,0 +1,56 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Romanian resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ROM)
+#ifdef _WIN32
+LANGUAGE LANG_ROMANIAN, SUBLANG_DEFAULT
+#pragma code_page(1250)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Romanian resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
Modified: trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/dsfNativeFLACSource.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/dsfNativeFLACSource.cpp 2009-10-12 22:20:48 UTC (rev 16643)
+++ trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/dsfNativeFLACSource.cpp 2009-10-13 21:54:34 UTC (rev 16644)
@@ -1,5 +1,6 @@
//===========================================================================
//Copyright (C) 2003, 2004 Zentaro Kavanagh
+//Copyright (C) 2008, 2009 Cristian Adam
//
//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions
@@ -29,90 +30,107 @@
//SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//===========================================================================
#include "stdafx.h"
+#include <initguid.h>
+#include "NativeFLACSourceFilter.h"
+#include "dsfNativeFLACSource.h"
+#include "common/util.h"
+extern "C" BOOL WINAPI DllEntryPoint(HANDLE, ULONG, LPVOID);
-
-
-extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID);
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
- return DllEntryPoint((HINSTANCE)(hModule), dwReason, lpReserved);
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ util::ConfigureLog(hModule);
+ }
+
+ return DllEntryPoint(hModule, dwReason, lpReserved);
}
-//The folowing two functions do the registration and deregistration of the dll and it's contained com objects.
+//The foLlowing two functions do the registration and deregistration of the dll and it's contained com objects.
STDAPI DllRegisterServer()
-{
-
- //TO DO::: Should we be releasing the filter mapper even when we return early ?
- HRESULT hr;
- IFilterMapper2* locFilterMapper = NULL;
-
- hr = AMovieDllRegisterServer2(TRUE);
- if (FAILED(hr)) {
-
+{
+ HRESULT hr = AMovieDllRegisterServer2(TRUE);
+
+ if (FAILED(hr))
+ {
return hr;
- }
-
-
+ }
+
+#ifndef WINCE
+ CComPtr<IFilterMapper2> filterMapper;
- hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, IID_IFilterMapper2, (void **)&locFilterMapper);
+ hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER, IID_IFilterMapper2, (void **)&filterMapper);
-
- if (FAILED(hr)) {
+ if (FAILED(hr))
+ {
return hr;
- }
-
- hr = locFilterMapper->RegisterFilter(
- CLSID_NativeFLACSourceFilter, // Filter CLSID.
- L"Native FLAC Source Filter", // Filter name.
- NULL, // Device moniker.
- &CLSID_LegacyAmFilterCategory, // Direct Show general category
- NULL, // Instance data. ???????
- &NativeFLACSourceFilterReg // Pointer to filter information.
+ }
+
+ hr = filterMapper->RegisterFilter(
+ CLSID_NativeFLACSourceFilter, // Filter CLSID.
+ L"Native FLAC Source Filter", // Filter name.
+ NULL, // Device moniker.
+ &CLSID_LegacyAmFilterCategory, // Direct Show general category
+ NULL, // Instance data. ???????
+ &NativeFLACSourceFilterReg // Pointer to filter information.
);
+#else
+ CComPtr<IFilterMapper> filterMapper;
+ hr = CoCreateInstance(CLSID_FilterMapper, NULL, CLSCTX_INPROC_SERVER, IID_IFilterMapper, (void **)&filterMapper);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
- //Only call once... if you need multiple you have to fix the hack job in RegWrap !
- //RegWrap::addMediaPlayerDesc("Ogg File", "*.ogg;*.ogv;*.oga;*.spx");
+ hr = filterMapper->RegisterFilter(
+ CLSID_NativeFLACSourceFilter, // Filter CLSID.
+ L"Native FLAC Source Filter", // Filter name.
+ MERIT_NORMAL
+ );
+#endif
-
-
-
-
- locFilterMapper->Release();
-
return hr;
- //return S_OK;
}
STDAPI DllUnregisterServer()
{
- //This is not a general purpose function.
- //RegWrap::removeMediaDesc();
+ HRESULT hr = S_OK;
+
+ hr = AMovieDllRegisterServer2(FALSE);
- HRESULT hr;
- IFilterMapper2* locFilterMapper = NULL;
+ if (FAILED(hr))
+ {
+ return hr;
+ }
- hr = AMovieDllRegisterServer2(FALSE);
- if (FAILED(hr)) {
-
- return hr;
- }
-
+#ifndef WINCE
+ CComPtr<IFilterMapper2> locFilterMapper;
+
hr = CoCreateInstance(CLSID_FilterMapper2, NULL, CLSCTX_INPROC_SERVER,
IID_IFilterMapper2, (void **)&locFilterMapper);
- if (FAILED(hr)) {
+ if (FAILED(hr))
+ {
return hr;
- }
-
+ }
hr = locFilterMapper->UnregisterFilter(&CLSID_LegacyAmFilterCategory,
NULL, CLSID_NativeFLACSourceFilter);
- //
- locFilterMapper->Release();
- return hr;
-
+#else
+ CComPtr<IFilterMapper> filterMapper;
+
+ hr = CoCreateInstance(CLSID_FilterMapper, NULL, CLSCTX_INPROC_SERVER, IID_IFilterMapper, (void **)&filterMapper);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
+
+ hr = filterMapper->UnregisterFilter(CLSID_NativeFLACSourceFilter);
+#endif
+
+ return hr;
}
Modified: trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/dsfNativeFLACSource.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/dsfNativeFLACSource.h 2009-10-12 22:20:48 UTC (rev 16643)
+++ trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/dsfNativeFLACSource.h 2009-10-13 21:54:34 UTC (rev 16644)
@@ -1,5 +1,6 @@
//===========================================================================
//Copyright (C) 2003, 2004 Zentaro Kavanagh
+//Copyright (C) 2008, 2009 Cristian Adam
//
//Redistribution and use in source and binary forms, with or without
//modification, are permitted provided that the following conditions
@@ -30,49 +31,66 @@
//===========================================================================
#pragma once
-#include <streams.h>
-#include <pullpin.h>
-#include <initguid.h>
#include "dsfNativeFLACSource.h"
#include "NativeFLACSourceFilter.h"
#include "NativeFLACSourcePin.h"
+
+
// {6DDA37BA-0553-499a-AE0D-BEBA67204548}
DEFINE_GUID(CLSID_NativeFLACSourceFilter,
0x6dda37ba, 0x553, 0x499a, 0xae, 0xd, 0xbe, 0xba, 0x67, 0x20, 0x45, 0x48);
+const REGPINTYPES FLACSourceOutputTypes =
+{
+ &MEDIATYPE_Audio,
+ &MEDIASUBTYPE_PCM
+};
+#ifndef WINCE
+const REGFILTERPINS FLACSourcePinReg[] =
+{
+ {
+ L"PCM Output", //Name (obsoleted)
+ FALSE, //Renders from this pin ?? Not sure about this.
+ TRUE, //Is an output pin
+ FALSE, //Cannot have zero instances of this pin
+ FALSE, //Cannot have more than one instance of this pin
+ NULL, //Connects to filter (obsoleted)
+ NULL, //Connects to pin (obsoleted)
+ 1, //Only support one media type
+ &FLACSourceOutputTypes //Pointer to media type (Audio/PCM)
+ }
+};
-const REGPINTYPES FLACSourceOutputTypes = {
- &MEDIATYPE_Audio,
- &MEDIASUBTYPE_PCM
+const REGFILTER2 NativeFLACSourceFilterReg =
+{
+ 1,
+ MERIT_NORMAL,
+ 0,
+ FLACSourcePinReg
};
+#else
-const REGFILTERPINS FLACSourcePinReg[] = {
- {
- L"PCM Output", //Name (obsoleted)
- FALSE, //Renders from this pin ?? Not sure about this.
- TRUE, //Is an output pin
- FALSE, //Cannot have zero instances of this pin
- FALSE, //Cannot have more than one instance of this pin
- NULL, //Connects to filter (obsoleted)
- NULL, //Connects to pin (obsoleted)
- 1, //Only support one media type
- &FLACSourceOutputTypes //Pointer to media type (Audio/PCM)
-
- }
+const AMOVIESETUP_PIN FLACSourcePinReg = {
+ L"PCM Output", //Name (obsoleted)
+ FALSE, //Renders from this pin ?? Not sure about this.
+ TRUE, //Is an output pin
+ FALSE, //Cannot have zero instances of this pin
+ FALSE, //Cannot have more than one instance of this pin
+ &CLSID_NULL, //Connects to filter (obsoleted)
+ NULL, //Connects to pin (obsoleted)
+ 1, //Only support one media type
+ &FLACSourceOutputTypes //Pointer to media type (Audio/PCM)
};
-
-
-const REGFILTER2 NativeFLACSourceFilterReg = {
- 1,
- MERIT_NORMAL,
- 0,
- FLACSourcePinReg
-
+static const AMOVIESETUP_FILTER NativeFLACSourceFilterReg = {
+ &CLSID_NativeFLACSourceFilter, // Filter CLSID.
+ L"Native FLAC SourceFilter", // Filter name.
+ MERIT_NORMAL, // Merit.
+ 1, // Number of pin types.
+ &FLACSourcePinReg // Pointer to pin information.
};
-
-
+#endif
Added: trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/resource.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/resource.h (rev 0)
+++ trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/resource.h 2009-10-13 21:54:34 UTC (rev 16644)
@@ -0,0 +1,15 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by Resources.rc
+//
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 102
+#define _APS_NEXT_COMMAND_VALUE 40002
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
Modified: trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/stdafx.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/stdafx.h 2009-10-12 22:20:48 UTC (rev 16643)
+++ trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/stdafx.h 2009-10-13 21:54:34 UTC (rev 16644)
@@ -6,9 +6,26 @@
#pragma once
-#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
+#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
-// TODO: reference additional headers your program requires here
-#include "dsfNativeFLACSource.h"
\ No newline at end of file
+#include <streams.h>
+#include <pullpin.h>
+
+#ifndef _WIN32_WCE
+//Kernel streaming header for KSDATA_FORMAT_SUBTYPE_PCM
+#include <ks.h>
+#include <ksmedia.h>
+#include <initguid.h>
+#endif
+
+#include <string>
+#include <set>
+
+#include "common/Log.h"
+
+#include <atlbase.h>
+#include <atlcom.h>
+
+#define FLAC__NO_DLL
More information about the commits
mailing list