[xiph-commits] r11567 -
branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource
illiminable at svn.xiph.org
illiminable at svn.xiph.org
Tue Jun 13 12:49:36 PDT 2006
Author: illiminable
Date: 2006-06-13 12:49:25 -0700 (Tue, 13 Jun 2006)
New Revision: 11567
Modified:
branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.cpp
branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.h
branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp
branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.h
Log:
* 24/32 bit support to native flac.
Modified: branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.cpp
===================================================================
--- branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.cpp 2006-06-13 17:24:17 UTC (rev 11566)
+++ branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.cpp 2006-06-13 19:49:25 UTC (rev 11567)
@@ -61,6 +61,7 @@
, mNumChannels(0)
, mSampleRate(0)
, mBitsPerSample(0)
+ , mSignificantBitsPerSample(0)
, mBegun(false)
, mUpto(0)
, mJustSeeked(true)
@@ -150,7 +151,14 @@
mNumChannels = (((locBuff[20]) & FLAC_CHANNEL_MASK) >> 1) + 1;
mSampleRate = (iBE_Math::charArrToULong(&locBuff[18])) >> 12;
- mBitsPerSample = (((locBuff[20] & FLAC_BPS_START_MASK) << 4) | ((locBuff[21] & FLAC_BPS_END_MASK) >> 4)) + 1;
+ mSignificantBitsPerSample = (((locBuff[20] & FLAC_BPS_START_MASK) << 4) | ((locBuff[21] & FLAC_BPS_END_MASK) >> 4)) + 1;
+
+ mBitsPerSample = (mSignificantBitsPerSample + 7) & 0xfffffff8UL;
+
+ if (mBitsPerSample == 24) {
+ mBitsPerSample = 32;
+ }
+
mTotalNumSamples = (((__int64)(locBuff[21] % 16)) << 32) + ((__int64)(iBE_Math::charArrToULong(&locBuff[22])));
//TODO::: NEed to handle the case where the number of samples is zero by making it non-seekable.
@@ -289,14 +297,14 @@
{
- //WFE::: wave format extensible
+
if (! mBegun) {
mBegun = true;
- const int SIZE_16_BITS = 2;
-
+
mNumChannels = inFrame->header.channels;
- mFrameSize = mNumChannels * SIZE_16_BITS;
+ mFrameSize = mNumChannels * (mBitsPerSample >> 3);
+
mSampleRate = inFrame->header.sample_rate;
}
@@ -304,27 +312,96 @@
unsigned long locBufferSize = locNumFrames * mFrameSize;
unsigned long locTotalFrameCount = locNumFrames * mNumChannels;
- //BUG::: There's a bug here. Implicitly assumes 2 channels. I think.
- unsigned char* locBuff = new unsigned char[locBufferSize]; //Gives to the deliverdata method
- //It could actually be a single buffer for the class.
- signed short* locShortBuffer = (signed short*)locBuff; //Don't delete this.
-
- signed short tempInt = 0;
- int tempLong = 0;
- float tempFloat = 0;
- for(unsigned long i = 0; i < locNumFrames; i++) {
- for (unsigned long j = 0; j < mNumChannels; j++) {
- 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++;
- }
- }
+ // 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
+ // 24 bit sample, or whether it would require a 4 bit left shift to be a true 24 bit sample.
+
+ // For now, working on the basis that it is truly right shifted.
+
+
+ //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;
+
+ if (mBitsPerSample == 8) {
+ unsigned char* locByteBuffer = (unsigned char*)locBuff;
+
+ if (locLeftShift == 0) {
+ for(unsigned long i = 0; i < locNumFrames; i++) {
+ for (unsigned long j = 0; j < mNumChannels; 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 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++) {
+
+ *(locShortBuffer++) = (signed short)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;
+ }
+ }
+ }
+ } 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++) {
+ *(locLongBuffer++) = inBuffer[j][i] << 8;
+ }
+ }
+ } else if (locLeftShift == 0) {
+ //Real 32 bit data
+ for(unsigned long i = 0; i < locNumFrames; i++) {
+ for (unsigned long j = 0; j < mNumChannels; 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;
+ }
+ }
+
+ }
+ }
+
+
mFLACSourcePin->deliverData(locBuff, locBufferSize, (mUpto*UNITS) / mSampleRate, ((mUpto+locNumFrames)*UNITS) / mSampleRate);
mUpto += locNumFrames;
Modified: branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.h
===================================================================
--- branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.h 2006-06-13 17:24:17 UTC (rev 11566)
+++ branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourceFilter.h 2006-06-13 19:49:25 UTC (rev 11567)
@@ -147,6 +147,7 @@
unsigned long mFrameSize;
unsigned long mSampleRate;
unsigned long mBitsPerSample;
+ unsigned long mSignificantBitsPerSample;
__int64 mTotalNumSamples;
//Critical Section to protect codec.
Modified: branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp
===================================================================
--- branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp 2006-06-13 17:24:17 UTC (rev 11566)
+++ branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp 2006-06-13 19:49:25 UTC (rev 11567)
@@ -105,7 +105,20 @@
return CBaseOutputPin::BreakConnect();
}
- //CSourceStream virtuals
+
+
+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)
{
//WFE::: Also offer extensible format
@@ -116,6 +129,49 @@
outMediaType->SetTemporalCompression(FALSE);
outMediaType->SetSampleSize(0);
+ WAVEFORMATEXTENSIBLE* locFormatEx = (WAVEFORMATEXTENSIBLE*)outMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEXTENSIBLE));
+
+ locFormatEx->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
+
+ locFormatEx->Format.nChannels = (WORD)mParentFilter->mNumChannels;
+ locFormatEx->Format.nSamplesPerSec = mParentFilter->mSampleRate;
+
+
+ locFormatEx->Samples.wValidBitsPerSample = (WORD)mParentFilter->mSignificantBitsPerSample;
+
+ //TODO::: Map this properly! What is the correct mapping ???
+ locFormatEx->dwChannelMask = SPEAKER_FRONT_LEFT
+ | SPEAKER_FRONT_RIGHT
+ | SPEAKER_FRONT_CENTER
+ | SPEAKER_LOW_FREQUENCY
+ | SPEAKER_BACK_LEFT
+ | SPEAKER_BACK_RIGHT
+ ;
+
+ ////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;
+
+ return S_OK;
+
+ //mUsingExtendedWav = true;
+ } else if (inPosition == 1) {
+ outMediaType->SetType(&MEDIATYPE_Audio);
+ outMediaType->SetSubtype(&MEDIASUBTYPE_PCM);
+ outMediaType->SetFormatType(&FORMAT_WaveFormatEx);
+ outMediaType->SetTemporalCompression(FALSE);
+ outMediaType->SetSampleSize(0);
+
WAVEFORMATEX* locFormat = (WAVEFORMATEX*)outMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEX));
locFormat->wFormatTag = WAVE_FORMAT_PCM;
@@ -125,16 +181,20 @@
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;
- } else {
+
+ } else {
return VFW_S_NO_MORE_ITEMS;
}
}
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)) {
+ if ( (inMediaType->majortype == MEDIATYPE_Audio)
+ && (inMediaType->subtype == MEDIASUBTYPE_PCM)
+ && (inMediaType->formattype == FORMAT_WaveFormatEx)) {
return S_OK;
} else {
return E_FAIL;
Modified: branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.h
===================================================================
--- branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.h 2006-06-13 17:24:17 UTC (rev 11566)
+++ branches/oggdsf_ce_port/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.h 2006-06-13 19:49:25 UTC (rev 11567)
@@ -37,6 +37,10 @@
//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
@@ -59,6 +63,7 @@
//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);
More information about the commits
mailing list