[xiph-commits] r17758 - in trunk/oggdsf: . src/lib/codecs/flac/filters/dsfNativeFLACSource src/lib/codecs/vorbis/filters/dsfVorbisDecoder src/lib/codecs/vorbis/libs/libOOVorbis src/lib/helper/common
cristianadam at svn.xiph.org
cristianadam at svn.xiph.org
Wed Dec 15 12:24:02 PST 2010
Author: cristianadam
Date: 2010-12-15 12:24:02 -0800 (Wed, 15 Dec 2010)
New Revision: 17758
Added:
trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/IDownmixAudio.h
Modified:
trunk/oggdsf/ChangeLog.txt
trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp
trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.cpp
trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.h
trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.cpp
trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.h
trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeOutputPin.cpp
trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.cpp
trunk/oggdsf/src/lib/helper/common/VorbisTypes.h
Log:
Merged patch from Google regarding multi channel Vorbis and stereo downmix. Downmix can be enabled by using the IDownmixAudio interface of the Vorbis decoder input pin.
Fixed #1748: opencodecs unable to cope with less usual audio setups (ogg 6.1, possibly 7.1 and other non-stereo ones)
Modified: trunk/oggdsf/ChangeLog.txt
===================================================================
--- trunk/oggdsf/ChangeLog.txt 2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/ChangeLog.txt 2010-12-15 20:24:02 UTC (rev 17758)
@@ -11,6 +11,8 @@
* Theora Decoder filter can now be connected to the output of the Theora Encoder filter.
* Fixed graph freeze when a Vorbis Decoder filter was connected to the output of a
Vorbis Encoder filter.
+ * Fixed #1748: opencodecs unable to cope with less usual audio setups (ogg 6.1, possibly 7.1
+ and other non-stereo ones)
Version 0.84.17359 - 04.08.2010
Modified: trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp 2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/codecs/flac/filters/dsfNativeFLACSource/NativeFLACSourcePin.cpp 2010-12-15 20:24:02 UTC (rev 17758)
@@ -184,6 +184,10 @@
case 6:
formatEx->dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
break;
+ case 7:
+ formatEx->dwChannelMask = KSAUDIO_SPEAKER_5POINT1_SURROUND
+ | SPEAKER_BACK_CENTER;
+ break;
case 8:
formatEx->dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND;
break;
Added: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/IDownmixAudio.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/IDownmixAudio.h (rev 0)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/IDownmixAudio.h 2010-12-15 20:24:02 UTC (rev 17758)
@@ -0,0 +1,8 @@
+#pragma once
+
+//Interface to set/get downmix
+DECLARE_INTERFACE_(IDownmixAudio, IUnknown)
+{
+ virtual void __stdcall setDownmixAudio(const bool setDownmix) = 0;
+ virtual bool __stdcall getDownmixAudio() = 0;
+};
Modified: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.cpp 2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.cpp 2010-12-15 20:24:02 UTC (rev 17758)
@@ -264,10 +264,10 @@
void VorbisDecodeFilter::PrintVorbisFormatInfo()
{
- LOG(logINFO) << "Vorbis Version: " << mVorbisFormatInfo->vorbisVersion
- << " Channels: " << mVorbisFormatInfo->numChannels
- << " SamplesPerSec: " << mVorbisFormatInfo->samplesPerSec
- << " MaxBitsPerSec: " << mVorbisFormatInfo->maxBitsPerSec
- << " AvgBitsPerSec: " << mVorbisFormatInfo->avgBitsPerSec
- << " MinBitsPerSec: " << mVorbisFormatInfo->minBitsPerSec;
+ LOG(logINFO) << "Vorbis Version: " << mVorbisFormatInfo->vorbisVersion;
+ LOG(logINFO) << "Channels: " << mVorbisFormatInfo->numChannels;
+ LOG(logINFO) << "SamplesPerSec: " << mVorbisFormatInfo->samplesPerSec;
+ LOG(logINFO) << "MaxBitsPerSec: " << mVorbisFormatInfo->maxBitsPerSec;
+ LOG(logINFO) << "AvgBitsPerSec: " << mVorbisFormatInfo->avgBitsPerSec;
+ LOG(logINFO) << "MinBitsPerSec: " << mVorbisFormatInfo->minBitsPerSec;
}
Modified: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.h 2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.h 2010-12-15 20:24:02 UTC (rev 17758)
@@ -89,6 +89,4 @@
//Format Block
VORBISFORMAT* mVorbisFormatInfo;
-
- static const bool USE_CORRECT_VORBIS_CHANNEL_MAPPING = true;
};
Modified: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.cpp 2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.cpp 2010-12-15 20:24:02 UTC (rev 17758)
@@ -36,56 +36,61 @@
#include <assert.h>
-VorbisDecodeInputPin::VorbisDecodeInputPin(AbstractTransformFilter* inFilter, CCritSec* inFilterLock,
+VorbisDecodeInputPin::VorbisDecodeInputPin(AbstractTransformFilter* inFilter, CCritSec* inFilterLock,
AbstractTransformOutputPin* inOutputPin,
- vector<CMediaType*> inAcceptableMediaTypes) :
-AbstractTransformInputPin (inFilter, inFilterLock, inOutputPin, NAME("VorbisDecodeInputPin"),
- L"Vorbis In", inAcceptableMediaTypes),
-mBegun(false),
-mNumChannels(0),
-mFrameSize(0),
+ vector<CMediaType*> inAcceptableMediaTypes) :
+AbstractTransformInputPin (inFilter, inFilterLock, inOutputPin, NAME("VorbisDecodeInputPin"),
+ L"Vorbis In", inAcceptableMediaTypes),
+mBegun(false),
+mNumChannels(0),
+mFrameSize(0),
mSampleRate(0),
// mUptoFrame(0),
-mSetupState(VSS_SEEN_NOTHING),
-mDecodedBuffer(NULL),
-mDecodedByteCount(0),
-mRateNumerator(RATE_DENOMINATOR),
-mOggOutputPinInterface(NULL),
+mSetupState(VSS_SEEN_NOTHING),
+mDecodedBuffer(NULL),
+mDecodedByteCount(0),
+mRateNumerator(RATE_DENOMINATOR),
+mOggOutputPinInterface(NULL),
mSentStreamOffset(false),
-m_isVorbisFormat2(false)
+m_isVorbisFormat2(false),
+m_isDownmix(false)
{
- LOG(logDEBUG) << "Pin constructor";
- ConstructCodec();
- LOG(logDEBUG) << "Pin constructor - post construct codec";
+ LOG(logDEBUG) << "Pin constructor";
+ ConstructCodec();
+ LOG(logDEBUG) << "Pin constructor - post construct codec";
- mDecodedBuffer = new unsigned char[DECODED_BUFFER_SIZE];
+ mDecodedBuffer = new unsigned char[DECODED_BUFFER_SIZE];
}
VorbisDecodeInputPin::~VorbisDecodeInputPin(void)
{
- DestroyCodec();
- delete[] mDecodedBuffer;
+ DestroyCodec();
+ delete[] mDecodedBuffer;
}
//Is this needed ??
STDMETHODIMP VorbisDecodeInputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv)
{
- if (riid == IID_IMediaSeeking)
+ if (riid == IID_IMediaSeeking)
{
return GetInterface((IMediaSeeking*)this, ppv);
- }
+ }
else if (riid == IID_IOggDecoder)
{
return GetInterface((IOggDecoder*)this, ppv);
- }
+ }
+ else if (riid == IID_IDownmixAudio)
+ {
+ return GetInterface((IDownmixAudio*)this, ppv);
+ }
- return AbstractTransformInputPin::NonDelegatingQueryInterface(riid, ppv);
+ return AbstractTransformInputPin::NonDelegatingQueryInterface(riid, ppv);
}
bool VorbisDecodeInputPin::ConstructCodec()
{
- return true;
- //Vorbis decoder should be good to go
+ return true;
+ //Vorbis decoder should be good to go
}
void VorbisDecodeInputPin::DestroyCodec()
@@ -95,30 +100,30 @@
STDMETHODIMP VorbisDecodeInputPin::NewSegment(REFERENCE_TIME inStartTime, REFERENCE_TIME inStopTime, double inRate)
{
- CAutoLock locLock(mStreamLock);
- //LOG(logDEBUG) << "New segment " << inStartTime<< " - " << inStopTime;
- //mUptoFrame = 0;
- mRateNumerator = RATE_DENOMINATOR * inRate;
- if (mRateNumerator > RATE_DENOMINATOR)
+ CAutoLock locLock(mStreamLock);
+ //LOG(logDEBUG) << "New segment " << inStartTime<< " - " << inStopTime;
+ //mUptoFrame = 0;
+ mRateNumerator = RATE_DENOMINATOR * inRate;
+ if (mRateNumerator > RATE_DENOMINATOR)
{
- mRateNumerator = RATE_DENOMINATOR;
- }
- return AbstractTransformInputPin::NewSegment(inStartTime, inStopTime, inRate);
+ mRateNumerator = RATE_DENOMINATOR;
+ }
+ return AbstractTransformInputPin::NewSegment(inStartTime, inStopTime, inRate);
}
STDMETHODIMP VorbisDecodeInputPin::EndFlush()
{
- CAutoLock locLock(m_pLock);
-
- HRESULT locHR = AbstractTransformInputPin::EndFlush();
- mDecodedByteCount = 0;
+ CAutoLock locLock(m_pLock);
+
+ HRESULT locHR = AbstractTransformInputPin::EndFlush();
+ mDecodedByteCount = 0;
return locHR;
}
STDMETHODIMP VorbisDecodeInputPin::Receive(IMediaSample* inSample)
{
- CAutoLock locLock(mStreamLock);
+ CAutoLock locLock(mStreamLock);
HRESULT hr = CheckStreaming();
@@ -158,8 +163,8 @@
if (hr != S_OK)
return hr;
- //TODO: Handling multi-channels such as 5.1 or 7.1, right now only handle one or two channels.
- memcpy((void*)buffer, (const void*)mDecodedBuffer, mDecodedByteCount);
+ reorderChannels(buffer, mDecodedBuffer, mDecodedByteCount);
+ //memcpy((void*)buffer, (const void*)mDecodedBuffer, mDecodedByteCount);
sample->SetTime(&tStart, &tStop);
sample->SetSyncPoint(TRUE);
@@ -179,7 +184,7 @@
}
if (tStop > 0)
{
- //Can dump it all downstream now
+ //Can dump it all downstream now
IMediaSample* sample;
unsigned long bytesCopied = 0;
unsigned long bytesToCopy = 0;
@@ -194,7 +199,7 @@
if (!mSentStreamOffset && (mOggOutputPinInterface != NULL))
{
mOggOutputPinInterface->notifyStreamBaseTime(tStart);
- mSentStreamOffset = true;
+ mSentStreamOffset = true;
}
if (mOggOutputPinInterface != NULL)
@@ -227,8 +232,6 @@
}
LOG(logDEBUG4) << __FUNCTIONW__ << " Bytes to copy: " << bytesToCopy;
- LOG(logDEBUG4) << __FUNCTIONW__ << " Actual Buffer count = " << mOutputPin->actualBufferCount();
- //bytesCopied += bytesToCopy;
sampleDuration = (((bytesToCopy/mFrameSize) * UNITS) / mSampleRate);
tStop = tStart + sampleDuration;
@@ -254,7 +257,7 @@
seekStripOffset += (mFrameSize - (seekStripOffset % mFrameSize));
__int64 strippedDuration = (((seekStripOffset/mFrameSize) * UNITS) / mSampleRate);
adjustedStart += strippedDuration;
- }
+ }
LOG(logDEBUG4) << __FUNCTIONW__ << " Seek strip offset: " << seekStripOffset;
@@ -284,6 +287,8 @@
} while(bytesCopied < mDecodedByteCount);
+ LOG(logDEBUG4) << __FUNCTIONW__ << " Decoded byte count: " << mDecodedByteCount;
+
mDecodedByteCount = 0;
}
@@ -291,82 +296,134 @@
return S_OK;
}
+
+
void VorbisDecodeInputPin::reorderChannels(unsigned char* inDestBuffer, const unsigned char* inSourceBuffer, unsigned long inNumBytes)
{
- //memcpy((void*)locBuffer, (const void*)&mDecodedBuffer[bytesCopied + seekStripOffset], bytesToCopy - seekStripOffset);
+ const short* channel_order;
+ const short channel_order_mono[] = {0};
+ const short channel_order_stereo[] = {0, 1};
+ const short channel_order_three[] = {0, 2, 1};
+ const short channel_order_four[] = {0, 1, 2, 3};
+ const short channel_order_five[] = {0, 2, 1, 3, 4};
+ const short channel_order_5_1[] = {0, 2, 1, 5, 3, 4};
+ const short channel_order_6_1[] = {0, 2, 1, 6, 5, 3, 4};
+ const short channel_order_7_1[] = {0, 2, 1, 7, 5, 6, 3, 4};
- if (GetFilter()->USE_CORRECT_VORBIS_CHANNEL_MAPPING &&
- (mNumChannels == 6 || mNumChannels == 3 || mNumChannels == 5))
- {
- //We only have to reorder the channels if we are using the extended format, we have declared that we want to map correctly
- // and the number channels is 3 or 6. All other cases we just memcpy
-
- unsigned long locSampleCount = inNumBytes / (mNumChannels * sizeof(short));
+ switch (mNumChannels) {
+ case 1: // mono ch.
+ channel_order = channel_order_mono;
+ break;
+ case 2: // stereo ch.
+ channel_order = channel_order_stereo;
+ break;
+ case 3: // 3 ch.
+ channel_order = channel_order_three;
+ break;
+ case 4: // 4 ch.
+ channel_order = channel_order_four;
+ break;
+ case 5: // 5 ch.
+ channel_order = channel_order_five;
+ break;
+ case 6: // 5.1 ch.
+ channel_order = channel_order_5_1;
+ break;
+ case 7: // 6.1 ch.
+ channel_order = channel_order_6_1;
+ break;
+ case 8: // 7.1 ch.
+ channel_order = channel_order_7_1;
+ break;
+ default:
+ memcpy((void*)inDestBuffer, (const void*)inSourceBuffer, inNumBytes);
+ return;
+ }
- short* locDest = (short*)inDestBuffer;
- const short* locSource = (short*)inSourceBuffer;
+ const unsigned long locSampleCount = inNumBytes / (mNumChannels * sizeof(short));
- if (mNumChannels == 6)
- {
- for (unsigned long i = 0; i < locSampleCount; i++)
- {
- *locDest++ = *locSource;
- *locDest++ = locSource[2];
- *locDest++ = locSource[1];
- *locDest++ = locSource[5];
- *locDest++ = locSource[3];
- *locDest++ = locSource[4];
+ short* locDest = (short*)inDestBuffer;
+ const short* locSource = (short*)inSourceBuffer;
- locSource += 6;
- }
+ //Test code
+ //bool setDownmix = true;
+ //setDownmixAudio(setDownmix);
- }
- else if (mNumChannels == 3)
+ if (getDownmixAudio())
+ {
+ for (unsigned long i = 0; i < locSampleCount; ++i)
{
- //3 channels
- for (unsigned long i = 0; i < locSampleCount; i++)
+ for (unsigned long chan = 0; chan < mNumChannels; ++chan)
{
- *locDest++ = *locSource;
- *locDest++ = locSource[2];
- *locDest++ = locSource[1];
- locSource += 3;
+ switch (mNumChannels)
+ {
+ case 3: // 3 ch.
+ locDest[0] = locSource[0] + static_cast<short>(0.7 * locSource[1]);
+ locDest[1] = locSource[2] + static_cast<short>(0.7 * locSource[1]);
+ break;
+ case 4: // 4 ch.
+ locDest[0] = locSource[0] + locSource[2];
+ locDest[1] = locSource[1] + locSource[3];
+ break;
+ case 5: // 5 ch.
+ locDest[0] = locSource[0] + static_cast<short>(0.7 * locSource[1]) + static_cast<short>(0.7 * locSource[3]);
+ locDest[1] = locSource[2] + static_cast<short>(0.7 * locSource[1]) + static_cast<short>(0.7 * locSource[4]);
+ break;
+ case 6: // 5.1 ch.
+ locDest[0] = locSource[0] + locSource[5] + static_cast<short>(0.7 * locSource[1])\
+ + static_cast<short>(0.7 * locSource[3]);
+ locDest[1] = locSource[2] + locSource[5] + static_cast<short>(0.7 * locSource[1])\
+ + static_cast<short>(0.7 * locSource[4]);
+ break;
+ case 7: // 6.1 ch.
+ locDest[0] = locSource[0] + locSource[7] + static_cast<short>(0.7 * locSource[1])\
+ + static_cast<short>(0.7 * locSource[3]) + static_cast<short>(0.7 * locSource[5]);
+ locDest[1] = locSource[2] + locSource[7] + static_cast<short>(0.7 * locSource[1])\
+ + static_cast<short>(0.7 * locSource[4]) + static_cast<short>(0.7 * locSource[6]);
+ break;
+ case 8: // 7.1 ch.
+ locDest[0] = locSource[0] + locSource[7] + static_cast<short>(0.7 * locSource[1])\
+ + static_cast<short>(0.7 * locSource[3]) + static_cast<short>(0.7 * locSource[5]);
+ locDest[1] = locSource[2] + locSource[7] + static_cast<short>(0.7 * locSource[1])\
+ + static_cast<short>(0.7 * locSource[4]) + static_cast<short>(0.7 * locSource[6]);
+ break;
+ }
+ locDest += mNumChannels;
+ locSource += mNumChannels;
}
- }
- else
+ }
+ }
+ else
+ {
+ for (unsigned long i = 0; i < locSampleCount; ++i)
{
- //5 channels
- for (unsigned long i = 0; i < locSampleCount; i++)
+ for (unsigned long chan = 0; chan < mNumChannels; ++chan)
{
- *locDest++ = *locSource;
- *locDest++ = locSource[2];
- *locDest++ = locSource[1];
- *locDest++ = locSource[3];
- *locDest++ = locSource[4];
- locSource += 5;
+ *locDest++ = locSource[channel_order[chan]];
}
+ locSource += mNumChannels;
}
- return;
}
-
- memcpy((void*)inDestBuffer, (const void*)inSourceBuffer, inNumBytes);
+
+ return;
}
HRESULT VorbisDecodeInputPin::TransformData(BYTE* inBuf, long inNumBytes)
{
- //TODO::: Return types !!!
+ //TODO::: Return types !!!
- VorbisDecoder::eVorbisResult locResult;
- unsigned long locNumSamples = 0;
- locResult = mVorbisDecoder.DecodePacket(inBuf, inNumBytes,(short*) (mDecodedBuffer + mDecodedByteCount), locNumSamples);
+ VorbisDecoder::eVorbisResult locResult;
+ unsigned long locNumSamples = 0;
+ locResult = mVorbisDecoder.DecodePacket(inBuf, inNumBytes,(short*) (mDecodedBuffer + mDecodedByteCount), locNumSamples);
- if (locResult == VorbisDecoder::VORBIS_DATA_OK)
+ if (locResult == VorbisDecoder::VORBIS_DATA_OK)
{
- mDecodedByteCount += locNumSamples * mFrameSize;
- return S_OK;
- }
+ mDecodedByteCount += locNumSamples * mFrameSize;
+ return S_OK;
+ }
- //For now, just silently ignore busted packets.
- return S_OK;
+ //For now, just silently ignore busted packets.
+ return S_OK;
}
HRESULT VorbisDecodeInputPin::TransformVorbis2(const BYTE* const buffer, const long length_of_buffer)
@@ -393,15 +450,15 @@
{
LOG(logDEBUG) << __FUNCTIONW__;
- //FIX:::Error checking
- if (CheckMediaType(inMediaType) == S_OK)
+ //FIX:::Error checking
+ if (CheckMediaType(inMediaType) == S_OK)
{
if (inMediaType->majortype == MEDIATYPE_OggPacketStream &&
inMediaType->formattype == FORMAT_OggIdentHeader &&
inMediaType->cbFormat == VORBIS_IDENT_HEADER_SIZE)
{
LOG(logINFO) << __FUNCTIONW__ << " MEDIATYPE_OggPacketStream, FORMAT_OggIdentHeader";
- GetFilter()->setVorbisFormat(inMediaType->pbFormat);
+ GetFilter()->setVorbisFormat(inMediaType->pbFormat);
}
else if (inMediaType->majortype == MEDIATYPE_Audio &&
inMediaType->subtype == MEDIASUBTYPE_Vorbis &&
@@ -421,28 +478,27 @@
mVorbisDecoder.Init(reinterpret_cast<VORBISFORMAT2*>(inMediaType->pbFormat));
}
- }
+ }
else
{
LOG(logERROR) << __FUNCTIONW__ << " MediaType not OK, Exiting";
- throw 0;
- }
-
+ throw 0;
+ }
+
return CBaseInputPin::SetMediaType(inMediaType);
}
-
HRESULT VorbisDecodeInputPin::CheckMediaType(const CMediaType *inMediaType)
{
- if (inMediaType->majortype == MEDIATYPE_OggPacketStream &&
+ if (inMediaType->majortype == MEDIATYPE_OggPacketStream &&
inMediaType->formattype == FORMAT_OggIdentHeader &&
inMediaType->cbFormat == VORBIS_IDENT_HEADER_SIZE)
{
- if (strncmp((char*)inMediaType->pbFormat, "\001vorbis", 7) == 0)
+ if (strncmp((char*)inMediaType->pbFormat, "\001vorbis", 7) == 0)
{
LOG(logDEBUG) << "Check media type OK (MEDIATYPE_OggPacketStream)";
return S_OK;
- }
- }
+ }
+ }
else if (inMediaType->majortype == MEDIATYPE_Audio &&
inMediaType->subtype == MEDIASUBTYPE_Vorbis &&
inMediaType->formattype == FORMAT_Vorbis)
@@ -471,126 +527,126 @@
HRESULT VorbisDecodeInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *outRequestedProps)
{
- outRequestedProps->cbBuffer = VORBIS_BUFFER_SIZE;
- outRequestedProps->cBuffers = VORBIS_NUM_BUFFERS;
- outRequestedProps->cbAlign = 1;
- outRequestedProps->cbPrefix = 0;
+ outRequestedProps->cbBuffer = VORBIS_BUFFER_SIZE;
+ outRequestedProps->cBuffers = VORBIS_NUM_BUFFERS;
+ outRequestedProps->cbAlign = 1;
+ outRequestedProps->cbPrefix = 0;
- return S_OK;
+ return S_OK;
}
LOOG_INT64 VorbisDecodeInputPin::convertGranuleToTime(LOOG_INT64 inGranule)
{
- if (mBegun)
- {
- return (inGranule * UNITS) / mSampleRate;
- }
+ if (mBegun)
+ {
+ return (inGranule * UNITS) / mSampleRate;
+ }
else
{
- return -1;
- }
+ return -1;
+ }
}
LOOG_INT64 VorbisDecodeInputPin::mustSeekBefore(LOOG_INT64 inGranule)
{
- //TODO::: Get adjustment from block size info... for now, it doesn't matter if no preroll
+ //TODO::: Get adjustment from block size info... for now, it doesn't matter if no preroll
//return (inGranule <= 4096) ? 0 : (inGranule - 4096);
return inGranule;
}
IOggDecoder::eAcceptHeaderResult VorbisDecodeInputPin::showHeaderPacket(OggPacket* inCodecHeaderPacket)
{
LOG(logDEBUG) << __FUNCTIONW__ << " SetupState: " << mSetupState;
- unsigned long locDummy;
- switch (mSetupState)
+ unsigned long locDummy;
+ switch (mSetupState)
{
- case VSS_SEEN_NOTHING:
- if (strncmp((char*)inCodecHeaderPacket->packetData(), "\001vorbis", 7) == 0)
+ case VSS_SEEN_NOTHING:
+ if (strncmp((char*)inCodecHeaderPacket->packetData(), "\001vorbis", 7) == 0)
{
- //TODO::: Possibly verify version
- if (mVorbisDecoder.DecodePacket( inCodecHeaderPacket->packetData()
- , inCodecHeaderPacket->packetSize()
- , NULL
- , locDummy) == VorbisDecoder::VORBIS_HEADER_OK) {
- mSetupState = VSS_SEEN_BOS;
- LOG(logDEBUG) << "Saw first header";
- return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
- }
- }
- return IOggDecoder::AHR_INVALID_HEADER;
-
-
- case VSS_SEEN_BOS:
- if (strncmp((char*)inCodecHeaderPacket->packetData(), "\003vorbis", 7) == 0)
+ //TODO::: Possibly verify version
+ if (mVorbisDecoder.DecodePacket( inCodecHeaderPacket->packetData()
+ , inCodecHeaderPacket->packetSize()
+ , NULL
+ , locDummy) == VorbisDecoder::VORBIS_HEADER_OK) {
+ mSetupState = VSS_SEEN_BOS;
+ LOG(logDEBUG) << "Saw first header";
+ return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
+ }
+ }
+ return IOggDecoder::AHR_INVALID_HEADER;
+
+
+ case VSS_SEEN_BOS:
+ if (strncmp((char*)inCodecHeaderPacket->packetData(), "\003vorbis", 7) == 0)
{
- if (mVorbisDecoder.DecodePacket( inCodecHeaderPacket->packetData()
- , inCodecHeaderPacket->packetSize()
- , NULL
- , locDummy) == VorbisDecoder::VORBIS_COMMENT_OK) {
+ if (mVorbisDecoder.DecodePacket( inCodecHeaderPacket->packetData()
+ , inCodecHeaderPacket->packetSize()
+ , NULL
+ , locDummy) == VorbisDecoder::VORBIS_COMMENT_OK) {
- mSetupState = VSS_SEEN_COMMENT;
- LOG(logDEBUG) << "Saw second header";
- return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
- }
- }
- return IOggDecoder::AHR_INVALID_HEADER;
-
-
- case VSS_SEEN_COMMENT:
- if (strncmp((char*)inCodecHeaderPacket->packetData(), "\005vorbis", 7) == 0)
+ mSetupState = VSS_SEEN_COMMENT;
+ LOG(logDEBUG) << "Saw second header";
+ return IOggDecoder::AHR_MORE_HEADERS_TO_COME;
+ }
+ }
+ return IOggDecoder::AHR_INVALID_HEADER;
+
+
+ case VSS_SEEN_COMMENT:
+ if (strncmp((char*)inCodecHeaderPacket->packetData(), "\005vorbis", 7) == 0)
{
- if (mVorbisDecoder.DecodePacket( inCodecHeaderPacket->packetData()
- , inCodecHeaderPacket->packetSize()
- , NULL
- , locDummy) == VorbisDecoder::VORBIS_CODEBOOK_OK) {
+ if (mVorbisDecoder.DecodePacket( inCodecHeaderPacket->packetData()
+ , inCodecHeaderPacket->packetSize()
+ , NULL
+ , locDummy) == VorbisDecoder::VORBIS_CODEBOOK_OK) {
-
- //Is mBegun useful ?
- mBegun = true;
-
- mNumChannels = mVorbisDecoder.numChannels();
- mFrameSize = mNumChannels * SIZE_16_BITS;
- mSampleRate = mVorbisDecoder.sampleRate();
+
+ //Is mBegun useful ?
+ mBegun = true;
+
+ mNumChannels = mVorbisDecoder.numChannels();
+ mFrameSize = mNumChannels * SIZE_16_BITS;
+ mSampleRate = mVorbisDecoder.sampleRate();
-
- mSetupState = VSS_ALL_HEADERS_SEEN;
- LOG(logDEBUG) << "Saw third header";
- return IOggDecoder::AHR_ALL_HEADERS_RECEIVED;
- }
-
- }
- return IOggDecoder::AHR_INVALID_HEADER;
-
- case VSS_ALL_HEADERS_SEEN:
- case VSS_ERROR:
- default:
- return IOggDecoder::AHR_UNEXPECTED;
- }
+
+ mSetupState = VSS_ALL_HEADERS_SEEN;
+ LOG(logDEBUG) << "Saw third header";
+ return IOggDecoder::AHR_ALL_HEADERS_RECEIVED;
+ }
+
+ }
+ return IOggDecoder::AHR_INVALID_HEADER;
+
+ case VSS_ALL_HEADERS_SEEN:
+ case VSS_ERROR:
+ default:
+ return IOggDecoder::AHR_UNEXPECTED;
+ }
}
string VorbisDecodeInputPin::getCodecShortName()
{
- return "vorbis";
+ return "vorbis";
}
string VorbisDecodeInputPin::getCodecIdentString()
{
- //TODO::: Get full ident string
- return "vorbis";
+ //TODO::: Get full ident string
+ return "vorbis";
}
HRESULT VorbisDecodeInputPin::CompleteConnect(IPin *inReceivePin)
{
- IOggOutputPin* locOggOutput = NULL;
- mSentStreamOffset = false;
- HRESULT locHR = inReceivePin->QueryInterface(IID_IOggOutputPin, (void**)&locOggOutput);
- if (locHR == S_OK)
+ IOggOutputPin* locOggOutput = NULL;
+ mSentStreamOffset = false;
+ HRESULT locHR = inReceivePin->QueryInterface(IID_IOggOutputPin, (void**)&locOggOutput);
+ if (locHR == S_OK)
{
- mOggOutputPinInterface = locOggOutput;
- }
+ mOggOutputPinInterface = locOggOutput;
+ }
else
{
- mOggOutputPinInterface = NULL;
- }
+ mOggOutputPinInterface = NULL;
+ }
LOG(logDEBUG) << __FUNCTIONW__ << " QueryInterface(IOggOutputPin) " << std::boolalpha
<< (mOggOutputPinInterface != NULL ? "succeeded" : "failed");
@@ -603,3 +659,14 @@
return AbstractTransformInputPin::CompleteConnect(inReceivePin);
}
+
+void VorbisDecodeInputPin::setDownmixAudio(const bool setDownmix)
+{
+ m_isDownmix = setDownmix;
+ return;
+}
+
+bool VorbisDecodeInputPin::getDownmixAudio()
+{
+ return m_isDownmix;
+}
Modified: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.h 2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.h 2010-12-15 20:24:02 UTC (rev 17758)
@@ -37,95 +37,102 @@
#include "VorbisDecodeInputPin.h"
#include "VorbisDecodeFilter.h"
#include "VorbisDecoder.h"
+#include "IDownmixAudio.h"
class VorbisDecodeFilter;
class VorbisDecodeOutputPin;
class VorbisDecodeInputPin
- : public AbstractTransformInputPin
- , public IOggDecoder
+ : public AbstractTransformInputPin
+ , public IOggDecoder
+ , public IDownmixAudio
{
public:
- DECLARE_IUNKNOWN
- STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
+ DECLARE_IUNKNOWN
+ STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv);
- VorbisDecodeInputPin(AbstractTransformFilter* inFilter, CCritSec* inFilterLock, AbstractTransformOutputPin* inOutputPin, vector<CMediaType*> inAcceptableMediaTypes);
- virtual ~VorbisDecodeInputPin(void);
+ VorbisDecodeInputPin(AbstractTransformFilter* inFilter, CCritSec* inFilterLock, AbstractTransformOutputPin* inOutputPin, vector<CMediaType*> inAcceptableMediaTypes);
+ virtual ~VorbisDecodeInputPin(void);
- virtual HRESULT SetMediaType(const CMediaType* inMediaType);
- virtual HRESULT CheckMediaType(const CMediaType *inMediaType);
- virtual STDMETHODIMP NewSegment(REFERENCE_TIME inStartTime, REFERENCE_TIME inStopTime, double inRate);
- virtual STDMETHODIMP EndFlush();
+ virtual HRESULT SetMediaType(const CMediaType* inMediaType);
+ virtual HRESULT CheckMediaType(const CMediaType *inMediaType);
+ virtual STDMETHODIMP NewSegment(REFERENCE_TIME inStartTime, REFERENCE_TIME inStopTime, double inRate);
+ virtual STDMETHODIMP EndFlush();
- virtual STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *outRequestedProps);
- virtual HRESULT CompleteConnect(IPin *inReceivePin);
+ virtual STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *outRequestedProps);
+ virtual HRESULT CompleteConnect(IPin *inReceivePin);
- //Overriden from AbstractTransform input pin
- virtual STDMETHODIMP Receive(IMediaSample* inSample);
+ //Overriden from AbstractTransform input pin
+ virtual STDMETHODIMP Receive(IMediaSample* inSample);
- //IOggDecoder Interface
- virtual LOOG_INT64 __stdcall convertGranuleToTime(LOOG_INT64 inGranule);
- virtual LOOG_INT64 __stdcall mustSeekBefore(LOOG_INT64 inGranule);
- virtual IOggDecoder::eAcceptHeaderResult __stdcall showHeaderPacket(OggPacket* inCodecHeaderPacket);
- virtual string __stdcall getCodecShortName();
- virtual string __stdcall getCodecIdentString();
+ //IOggDecoder Interface
+ virtual LOOG_INT64 __stdcall convertGranuleToTime(LOOG_INT64 inGranule);
+ virtual LOOG_INT64 __stdcall mustSeekBefore(LOOG_INT64 inGranule);
+ virtual IOggDecoder::eAcceptHeaderResult __stdcall showHeaderPacket(OggPacket* inCodecHeaderPacket);
+ virtual string __stdcall getCodecShortName();
+ virtual string __stdcall getCodecIdentString();
+ //IDownmixAudio Interface
+ virtual void __stdcall setDownmixAudio(const bool setDownmix);
+ virtual bool __stdcall getDownmixAudio();
+
protected:
- static const unsigned long DECODED_BUFFER_SIZE = 1<<20; //1 Meg buffer
+ static const unsigned long DECODED_BUFFER_SIZE = 1<<21; //2 Meg buffer
- enum eVorbisSetupState {
- VSS_SEEN_NOTHING,
- VSS_SEEN_BOS,
- VSS_SEEN_COMMENT,
- VSS_ALL_HEADERS_SEEN,
- VSS_ERROR
- };
+ enum eVorbisSetupState {
+ VSS_SEEN_NOTHING,
+ VSS_SEEN_BOS,
+ VSS_SEEN_COMMENT,
+ VSS_ALL_HEADERS_SEEN,
+ VSS_ERROR
+ };
- eVorbisSetupState mSetupState;
+ eVorbisSetupState mSetupState;
- static const unsigned long VORBIS_IDENT_HEADER_SIZE = 30;
+ static const unsigned long VORBIS_IDENT_HEADER_SIZE = 30;
#ifdef WINCE
- static const unsigned long VORBIS_NUM_BUFFERS = 50;
- static const unsigned long VORBIS_BUFFER_SIZE = 8192;
+ static const unsigned long VORBIS_NUM_BUFFERS = 50;
+ static const unsigned long VORBIS_BUFFER_SIZE = 8192;
#else
- static const unsigned long VORBIS_NUM_BUFFERS = 75;
- static const unsigned long VORBIS_BUFFER_SIZE = 65536;
+ static const unsigned long VORBIS_NUM_BUFFERS = 75;
+ static const unsigned long VORBIS_BUFFER_SIZE = 65536;
#endif
- //Implementation of virtuals from AbstractTransform Filter
- virtual bool ConstructCodec();
- virtual void DestroyCodec();
- virtual HRESULT TransformData(unsigned char* inBuf, long inNumBytes);
- virtual HRESULT TransformVorbis2(const BYTE* const in_buffer, const long size_of_in_buffer);
+ //Implementation of virtuals from AbstractTransform Filter
+ virtual bool ConstructCodec();
+ virtual void DestroyCodec();
+ virtual HRESULT TransformData(unsigned char* inBuf, long inNumBytes);
+ virtual HRESULT TransformVorbis2(const BYTE* const in_buffer, const long size_of_in_buffer);
void reorderChannels(unsigned char* inDestBuffer, const unsigned char* inSourceBuffer, unsigned long inNumBytes);
- VorbisDecodeFilter* GetFilter();
+ VorbisDecodeFilter* GetFilter();
- //TODO::: Are these needed?
- bool mBegun;
- //unsigned int mUptoFrame;
- //HRESULT mHR;
+ //TODO::: Are these needed?
+ bool mBegun;
+ //unsigned int mUptoFrame;
+ //HRESULT mHR;
- int mNumChannels;
- int mFrameSize;
- int mSampleRate;
+ int mNumChannels;
+ int mFrameSize;
+ int mSampleRate;
- VorbisDecoder mVorbisDecoder;
+ VorbisDecoder mVorbisDecoder;
- unsigned char* mDecodedBuffer;
- unsigned long mDecodedByteCount;
+ unsigned char* mDecodedBuffer;
+ unsigned long mDecodedByteCount;
- __int64 mRateNumerator;
- static const __int64 RATE_DENOMINATOR = 65536;
+ __int64 mRateNumerator;
+ static const __int64 RATE_DENOMINATOR = 65536;
- IOggOutputPin* mOggOutputPinInterface;
- bool mSentStreamOffset;
+ IOggOutputPin* mOggOutputPinInterface;
+ bool mSentStreamOffset;
private:
- bool m_isVorbisFormat2;
+ bool m_isVorbisFormat2;
+ bool m_isDownmix;
};
Modified: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeOutputPin.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeOutputPin.cpp 2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeOutputPin.cpp 2010-12-15 20:24:02 UTC (rev 17758)
@@ -58,7 +58,8 @@
HRESULT hr = AbstractTransformOutputPin::DecideBufferSize(inAllocator, inReqAllocProps);
LOG(logINFO) << "Desired buffer size: " << mDesiredBufferSize << ", buffers: " << mDesiredBufferCount
- << " Actual buffer size: " << mActualBufferSize << ", buffers: " << mActualBufferCount;
+ << " Actual buffer size: " << mActualBufferSize << ", buffers: " << mActualBufferCount
+ << " Result: 0x" << std::hex << hr;
return hr;
}
@@ -127,22 +128,26 @@
break;
case 3:
formatEx->dwChannelMask = SPEAKER_FRONT_LEFT
- | SPEAKER_FRONT_RIGHT
- | SPEAKER_FRONT_CENTER;
+ | SPEAKER_FRONT_RIGHT
+ | SPEAKER_FRONT_CENTER;
break;
case 4:
formatEx->dwChannelMask = KSAUDIO_SPEAKER_QUAD;
break;
case 5:
formatEx->dwChannelMask = SPEAKER_FRONT_LEFT
- | SPEAKER_FRONT_RIGHT
- | SPEAKER_FRONT_CENTER
- | SPEAKER_BACK_LEFT
- | SPEAKER_BACK_RIGHT;
+ | SPEAKER_FRONT_RIGHT
+ | SPEAKER_FRONT_CENTER
+ | SPEAKER_BACK_LEFT
+ | SPEAKER_BACK_RIGHT;
break;
case 6:
formatEx->dwChannelMask = KSAUDIO_SPEAKER_5POINT1;
break;
+ case 7:
+ formatEx->dwChannelMask = KSAUDIO_SPEAKER_5POINT1_SURROUND
+ | SPEAKER_BACK_CENTER;
+ break;
case 8:
formatEx->dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND;
break;
Modified: trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.cpp 2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.cpp 2010-12-15 20:24:02 UTC (rev 17758)
@@ -105,8 +105,6 @@
vector<StampedOggPacket*> VorbisEncoder::encodeVorbis(const short* const inSampleBuffer, unsigned long inNumSamplesPerChannel)
{
- //TODO::: Handle 5 channel input
-
if (inNumSamplesPerChannel == 0) {
return vector<StampedOggPacket*>();
}
@@ -115,8 +113,50 @@
float* locOneOutputChannelBuffer = NULL;
const short* locReadChannelBuffer = NULL;
+
+ const short* channel_order;
+ const short channel_order_mono[] = {0};
+ const short channel_order_stereo[] = {0, 1};
+ const short channel_order_three[] = {0, 2, 1};
+ const short channel_order_four[] = {0, 1, 2, 3};
+ const short channel_order_five[] = {0, 2, 1, 3, 4};
+ const short channel_order_5_1[] = {0, 2, 1, 5, 3, 4};
+ const short channel_order_6_1[] = {0, 2, 1, 6, 5, 3, 4};
+ const short channel_order_7_1[] = {0, 2, 1, 7, 5, 6, 3, 4};
+
+ switch (mSettings.mNumChannels) {
+ case 1: // mono ch.
+ channel_order = channel_order_mono;
+ break;
+ case 2: // stereo ch.
+ channel_order = channel_order_stereo;
+ break;
+ case 3: // 3 ch.
+ channel_order = channel_order_three;
+ break;
+ case 4: // 4 ch.
+ channel_order = channel_order_four;
+ break;
+ case 5: // 5 ch.
+ channel_order = channel_order_five;
+ break;
+ case 6: // 5.1 ch.
+ channel_order = channel_order_5_1;
+ break;
+ case 7: // 6.1 ch.
+ channel_order = channel_order_6_1;
+ break;
+ case 8: // 7.1 ch.
+ channel_order = channel_order_7_1;
+ break;
+ default:
+ channel_order = channel_order_mono; //?
+ break;
+ }
+
for (unsigned long chan = 0; chan < mSettings.mNumChannels; chan++) {
- locOneOutputChannelBuffer = locBuffer[chan];
+ //locOneOutputChannelBuffer = locBuffer[chan];
+ locOneOutputChannelBuffer = locBuffer[channel_order[chan]];
locReadChannelBuffer = inSampleBuffer + chan;
for (unsigned long sam = 0; sam < inNumSamplesPerChannel; sam++) {
Modified: trunk/oggdsf/src/lib/helper/common/VorbisTypes.h
===================================================================
--- trunk/oggdsf/src/lib/helper/common/VorbisTypes.h 2010-12-15 17:40:15 UTC (rev 17757)
+++ trunk/oggdsf/src/lib/helper/common/VorbisTypes.h 2010-12-15 20:24:02 UTC (rev 17758)
@@ -82,4 +82,8 @@
DEFINE_GUID(CLSID_VorbisDecodeFilter,
0x5a1d945, 0xa794, 0x44ef, 0xb4, 0x1a, 0x2f, 0x85, 0x1a, 0x11, 0x71, 0x55);
+// {BFF86BE7-9E32-40EF-B200-7BCC7800CC72}
+DEFINE_GUID(IID_IDownmixAudio,
+0xBFF86BE7, 0x9E32, 0x40EF, 0xB2, 0x00, 0x7B, 0xCC, 0x78, 0x00, 0xCC, 0x72);
+
#endif // VORBISTYPES_H
\ No newline at end of file
More information about the commits
mailing list