[xiph-commits] r11844 - trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder

illiminable at svn.xiph.org illiminable at svn.xiph.org
Sun Sep 17 10:57:09 PDT 2006


Author: illiminable
Date: 2006-09-17 10:56:57 -0700 (Sun, 17 Sep 2006)
New Revision: 11844

Modified:
   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/filters/dsfVorbisDecoder/VorbisDecodeOutputPin.h
Log:
* Fix channel order for vorbis. Now properly re-orders when numChannels is 3 or 6, to map onto what windows expects.
* Change from FL   FC   FR   RL   RR   LFE  (vorbis)
* to          FL   FR   FC   LFE  RL   RR   (wav)


Modified: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.cpp	2006-09-17 17:56:26 UTC (rev 11843)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.cpp	2006-09-17 17:56:57 UTC (rev 11844)
@@ -90,6 +90,13 @@
 	
 	locAcceptableTypes.push_back(locAcceptMediaType);
 
+	//Second one the same type... they are actually different one is the extensible format. See CreateAndFill
+	locAcceptMediaType = new CMediaType(&MEDIATYPE_Audio);		//Deleted in pin destructor
+	locAcceptMediaType->subtype = MEDIASUBTYPE_PCM;
+	locAcceptMediaType->formattype = FORMAT_WaveFormatEx;
+	
+	locAcceptableTypes.push_back(locAcceptMediaType);
+
 	//Output pin must be done first because it's passed to the input pin.
 	mOutputPin = new VorbisDecodeOutputPin(this, m_pLock, locAcceptableTypes);			//Deleted in base class destructor
 

Modified: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.h	2006-09-17 17:56:26 UTC (rev 11843)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeFilter.h	2006-09-17 17:56:57 UTC (rev 11844)
@@ -71,4 +71,7 @@
 
 	//Format Block
 	sVorbisFormatBlock* 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	2006-09-17 17:56:26 UTC (rev 11843)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.cpp	2006-09-17 17:56:57 UTC (rev 11844)
@@ -215,7 +215,8 @@
 
 					
 
-						memcpy((void*)locBuffer, (const void*)&mDecodedBuffer[locBytesCopied + locSeekStripOffset], locBytesToCopy - locSeekStripOffset);
+						//memcpy((void*)locBuffer, (const void*)&mDecodedBuffer[locBytesCopied + locSeekStripOffset], locBytesToCopy - locSeekStripOffset);
+                        reorderChannels(locBuffer, &mDecodedBuffer[locBytesCopied + locSeekStripOffset], locBytesToCopy - locSeekStripOffset);
 
 						locSample->SetTime(&locAdjustedStart, &locAdjustedEnd);
 						locSample->SetMediaTime(&locStart, &locEnd);
@@ -245,6 +246,53 @@
 	}
 }
 
+void VorbisDecodeInputPin::reorderChannels(unsigned char* inDestBuffer, const unsigned char* inSourceBuffer, unsigned long inNumBytes)
+{
+    //memcpy((void*)locBuffer, (const void*)&mDecodedBuffer[locBytesCopied + locSeekStripOffset], locBytesToCopy - locSeekStripOffset);
+
+    if (((VorbisDecodeFilter*)m_pFilter)->USE_CORRECT_VORBIS_CHANNEL_MAPPING && ((mNumChannels == 6)  || (mNumChannels == 3))) {
+        //We only have to reorder the channels if we are using the extended format, we have declared that we want to map correctly
+        // and teh number channels is 3 or 6. All other cases we just memcpy
+
+        
+        unsigned long locSampleCount = inNumBytes / (mNumChannels * sizeof(short));
+
+        short* locDest = (short*)inDestBuffer;
+        const short* locSource = (short*)inSourceBuffer;
+
+        if (mNumChannels == 3)
+        {
+            for (unsigned long i = 0; i < locSampleCount; i++)
+            {
+                *locDest++ = *locSource;
+                *locDest++ = locSource[2];
+                *locDest++ = locSource[1];
+                locSource += 3;
+            }
+        } else {
+            for (unsigned long i = 0; i < locSampleCount; i++)
+            {
+                //Must be 6.
+                *locDest++ = *locSource;
+                *locDest++ = locSource[2];
+                *locDest++ = locSource[1];
+                *locDest++ = locSource[5];
+                *locDest++ = locSource[3];
+                *locDest++ = locSource[4];
+
+                locSource += 6;
+                }
+
+
+        }
+        return;
+    }
+    
+    memcpy((void*)inDestBuffer, (const void*)inSourceBuffer, inNumBytes);
+    
+
+}
+
 HRESULT VorbisDecodeInputPin::TransformData(BYTE* inBuf, long inNumBytes) 
 {
 	//TODO::: Return types !!!

Modified: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.h	2006-09-17 17:56:26 UTC (rev 11843)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeInputPin.h	2006-09-17 17:56:57 UTC (rev 11844)
@@ -35,13 +35,10 @@
 using namespace std;
 #include "vorbisdecoderdllstuff.h"
 
-
-
 #include "IOggDecoder.h"
 #include "IOggOutputPin.h"
 #include "AbstractTransformInputPin.h"
 #include "VorbisDecodeInputPin.h"
-
 #include "VorbisDecodeFilter.h"
 
 #ifdef USING_TREMOR
@@ -51,7 +48,6 @@
 #include "VorbisDecoder.h"
 #endif
 
-
 class VorbisDecodeOutputPin;
 
 class VorbisDecodeInputPin 
@@ -115,6 +111,8 @@
 	virtual void DestroyCodec();
 	virtual HRESULT TransformData(unsigned char* inBuf, long inNumBytes);
 
+    void reorderChannels(unsigned char* inDestBuffer, const unsigned char* inSourceBuffer, unsigned long inNumBytes);
+
 	
 
 	//TODO::: Are these needed?

Modified: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeOutputPin.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeOutputPin.cpp	2006-09-17 17:56:26 UTC (rev 11843)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeOutputPin.cpp	2006-09-17 17:56:57 UTC (rev 11844)
@@ -43,6 +43,7 @@
 									,	65536
 									,	20
 									,	inAcceptableMediaTypes)
+
 {
 
 		
@@ -66,7 +67,113 @@
 
 HRESULT VorbisDecodeOutputPin::CreateAndFillFormatBuffer(CMediaType* outMediaType, int inPosition)
 {
-	if (inPosition == 0) {
+    //WFE::: Extensible format here
+    if (inPosition == 0) {
+        //This is not required... it's done in FillMediaType in the base class
+		//outMediaType->SetType(&MEDIATYPE_Audio);
+		//outMediaType->SetSubtype(&MEDIASUBTYPE_PCM);
+		//outMediaType->SetFormatType(&FORMAT_WaveFormatEx);
+		//outMediaType->SetTemporalCompression(FALSE);
+		//outMediaType->SetSampleSize(0);
+
+		WAVEFORMATEXTENSIBLE* locFormatEx = (WAVEFORMATEXTENSIBLE*)outMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEXTENSIBLE));
+        
+		locFormatEx->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
+
+		locFormatEx->Format.nChannels = (WORD)((VorbisDecodeFilter*)m_pFilter)->mVorbisFormatInfo->numChannels;
+		locFormatEx->Format.nSamplesPerSec =  ((VorbisDecodeFilter*)m_pFilter)->mVorbisFormatInfo->samplesPerSec;
+        locFormatEx->Format.wBitsPerSample = 16;
+
+        
+        locFormatEx->Samples.wValidBitsPerSample = 16;
+
+        if (locFormatEx->Format.nChannels <= 6)
+        {
+            //THis is the incorrect order for vorbis, but we have to reorder it manually on output.
+
+            switch (locFormatEx->Format.nChannels)
+            {
+                case 1:
+                    locFormatEx->dwChannelMask =        SPEAKER_FRONT_LEFT;
+                    break;
+                case 2:
+                    locFormatEx->dwChannelMask =        SPEAKER_FRONT_LEFT
+                                        |   SPEAKER_FRONT_RIGHT;
+                    break;
+                case 3:
+                    locFormatEx->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;
+                    break;
+                case 5:
+                   locFormatEx->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
+                                        ;
+                     break;
+
+                default:
+                    locFormatEx->dwChannelMask = 0;
+                    break;
+
+
+            }
+
+           
+
+            //Assume channels ordered 012345
+
+            //For 1 channel
+            //      Do nothing
+
+            //For 2 channels
+            //      Do nothing
+
+            //For 3 channels
+            //      Swap channels 1 and 2 (the right and centre)
+
+            //For 4 channels
+            //      Do nothing
+
+            //For 5 channels
+            //      Swap channels 1 and 2 (the right and centre)
+
+            //For 6 channels
+            //      Change from FL   FC   FR   RL   RR   LFE
+            //      to          FL   FR   FC   LFE  RL   RR
+
+  
+        } else {
+            //More than 6 channels it's up to the output device to figure it out.
+            locFormatEx->dwChannelMask = 0;
+        }
+
+		locFormatEx->Format.nBlockAlign = (WORD)((locFormatEx->Format.nChannels) * (locFormatEx->Format.wBitsPerSample >> 3));
+		locFormatEx->Format.nAvgBytesPerSec = ((locFormatEx->Format.nChannels) * (locFormatEx->Format.wBitsPerSample >> 3)) * locFormatEx->Format.nSamplesPerSec;
+		locFormatEx->Format.cbSize = 22; //sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
+        locFormatEx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
+
+
+        return S_OK;
+    } else if (inPosition == 1) {
+
 		WAVEFORMATEX* locWaveFormat = (WAVEFORMATEX*)outMediaType->AllocFormatBuffer(sizeof(WAVEFORMATEX));
 		//TODO::: Check for null ?
 
@@ -77,6 +184,8 @@
 		locWaveFormat->nBlockAlign = (locWaveFormat->nChannels) * (locWaveFormat->wBitsPerSample >> 3);
 		locWaveFormat->nAvgBytesPerSec = ((locWaveFormat->nChannels) * (locWaveFormat->wBitsPerSample >> 3)) * locWaveFormat->nSamplesPerSec;
 		locWaveFormat->cbSize = 0;
+
+ 
 		return S_OK;
 	} else {
         return S_FALSE;

Modified: trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeOutputPin.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeOutputPin.h	2006-09-17 17:56:26 UTC (rev 11843)
+++ trunk/oggdsf/src/lib/codecs/vorbis/filters/dsfVorbisDecoder/VorbisDecodeOutputPin.h	2006-09-17 17:56:57 UTC (rev 11844)
@@ -33,6 +33,9 @@
 #include "vorbisdecoderdllstuff.h"
 #include "AbstractTransformOutputPin.h"
 
+//Kernel streaming header for KSDATA_FORMAT_SUBTYPE_PCM
+#include "ks.h"
+#include "ksmedia.h"
 
 class VorbisDecodeFilter;
 class VorbisDecodeOutputPin :
@@ -49,5 +52,7 @@
 	virtual ~VorbisDecodeOutputPin(void);
 protected:
 	virtual HRESULT CreateAndFillFormatBuffer(CMediaType* outMediaType, int inPosition);
+
+
 };
 



More information about the commits mailing list