[xiph-commits] r11867 - trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis

illiminable at svn.xiph.org illiminable at svn.xiph.org
Sat Sep 30 05:01:33 PDT 2006


Author: illiminable
Date: 2006-09-30 05:01:27 -0700 (Sat, 30 Sep 2006)
New Revision: 11867

Modified:
   trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncodeSettings.cpp
   trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncodeSettings.h
   trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.cpp
   trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.h
Log:
* Add basic encoding functionality to oovorbis

Modified: trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncodeSettings.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncodeSettings.cpp	2006-09-30 09:45:51 UTC (rev 11866)
+++ trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncodeSettings.cpp	2006-09-30 12:01:27 UTC (rev 11867)
@@ -49,6 +49,8 @@
     mMaxBitrate = 0;
     mQuality = 30;
     mIsQualitySet = true;
+    mNumChannels = 0;
+    mSampleRate = 0;
 
     //Advanced
     //double mBitrateAverageDamping;
@@ -73,8 +75,23 @@
 
 }
 
-bool VorbisEncodeSettings::setManaged(unsigned int inBitrate, unsigned int inMinBitrate, unsigned int inMaxBitrate)
+bool VorbisEncodeSettings::setBitrateQualityMode(int inBitrate)
 {
+    if (inBitrate > 0) {
+        mMinBitrate = -1;
+        mMaxBitrate = -1;
+        mQuality = 0;
+        mBitrate = inBitrate;
+        
+        mIsManaged = false;
+        mIsQualitySet = true;
+    }
+    return false;
+
+}
+
+bool VorbisEncodeSettings::setManaged(int inBitrate, int inMinBitrate, int inMaxBitrate)
+{
     //TODO::: What other things to check?
     if (inMinBitrate < inMaxBitrate) {
         mBitrate = inBitrate;
@@ -82,7 +99,9 @@
         mMaxBitrate = inMaxBitrate;
         mIsManaged = true;
         mIsQualitySet = false;
+        return true;
     }
+    return false;
 }
 
 bool VorbisEncodeSettings::setAudioParameters(unsigned int inNumChannels, unsigned int inSampleRate)

Modified: trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncodeSettings.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncodeSettings.h	2006-09-30 09:45:51 UTC (rev 11866)
+++ trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncodeSettings.h	2006-09-30 12:01:27 UTC (rev 11867)
@@ -43,16 +43,17 @@
     void setToDefaults();
 
     bool setQuality(int inQuality);
-    bool setManaged(unsigned int inBitrate, unsigned int inMinBitrate, unsigned int inMaxBitrate);
+    bool setBitrateQualityMode(int inBitrate);
+    bool setManaged(int inBitrate, int inMinBitrate, int inMaxBitrate);
     bool setAudioParameters(unsigned int inNumChannels, unsigned int inSampleRate);
 
     unsigned int mNumChannels;
     unsigned int mSampleRate;
 
     bool mIsManaged;
-    unsigned int mBitrate;
-    unsigned int mMinBitrate;
-    unsigned int mMaxBitrate;
+    int mBitrate;
+    int mMinBitrate;
+    int mMaxBitrate;
     int mQuality;
     bool mIsQualitySet;
 

Modified: trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.cpp
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.cpp	2006-09-30 09:45:51 UTC (rev 11866)
+++ trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.cpp	2006-09-30 12:01:27 UTC (rev 11867)
@@ -39,3 +39,134 @@
 VorbisEncoder::~VorbisEncoder(void)
 {
 }
+
+vector<StampedOggPacket*> VorbisEncoder::setupCodec(VorbisEncodeSettings inSettings)
+{
+    mSettings = inSettings;
+    vector<StampedOggPacket*> retPackets;
+
+    int ret = 0;
+    vorbis_info_init(&mVorbisInfo);
+    vorbis_comment_init(&mVorbisComment);
+    //TODO::: Add version/encoder info here?
+
+    //TODO::: Allow max and min in unmanaged mode
+    //TODO::: Allow advanced bitrate management
+
+
+
+
+    if (mSettings.mIsQualitySet) {
+        ret = vorbis_encode_setup_vbr(&mVorbisInfo, mSettings.mNumChannels, mSettings.mSampleRate, (float)inSettings.mQuality / 100.0f);
+        if (ret != 0) {
+            vorbis_info_clear(&mVorbisInfo);
+            return retPackets;
+        }
+    } else {
+        ret = vorbis_encode_setup_managed(&mVorbisInfo, mSettings.mNumChannels, mSettings.mSampleRate, mSettings.mMaxBitrate * 1000, mSettings.mBitrate * 1000, mSettings.mMinBitrate * 1000);
+        if (ret != 0) {
+            vorbis_info_clear(&mVorbisInfo);
+            return retPackets;
+        }
+
+
+    }
+
+    if (!mSettings.mIsManaged) {
+        vorbis_encode_ctl(&mVorbisInfo, OV_ECTL_RATEMANAGE2_SET, NULL);
+    }
+
+    //Advanced options?
+
+    vorbis_encode_setup_init(&mVorbisInfo);
+    vorbis_analysis_init(&mVorbisDSPState, &mVorbisInfo);
+    vorbis_block_init(&mVorbisDSPState, &mVorbisBlock);
+
+    ogg_packet locIdentHeader;
+    ogg_packet locCommentHeader;
+    ogg_packet locCodebookHeader;
+
+    vorbis_analysis_headerout(&mVorbisDSPState, &mVorbisComment, &locIdentHeader, &locCommentHeader, &locCodebookHeader);
+    
+    retPackets.push_back(oldToNewPacket(&locIdentHeader));
+    retPackets.push_back(oldToNewPacket(&locCommentHeader));
+    retPackets.push_back(oldToNewPacket(&locCodebookHeader));
+
+    return retPackets;
+
+
+
+
+}
+
+StampedOggPacket* VorbisEncoder::oldToNewPacket(ogg_packet* inOldPacket)
+{
+    //This is duplicated from the theora encoder... do something about that.
+	const unsigned char NOT_USED = 0;
+
+	//Need to clone the packet data
+	unsigned char* locBuff = new unsigned char[inOldPacket->bytes];
+	memcpy((void*)locBuff, (const void*)inOldPacket->packet, inOldPacket->bytes);
+																					//Not truncated or continued... it's a full packet.
+	StampedOggPacket* locOggPacket = new StampedOggPacket(locBuff, inOldPacket->bytes, false, false, NOT_USED, inOldPacket->granulepos, StampedOggPacket::OGG_END_ONLY);
+	return locOggPacket;
+
+}
+
+vector<StampedOggPacket*> VorbisEncoder::encodeVorbis(const short* const inSampleBuffer, unsigned long inNumSamplesPerChannel)
+{
+
+    //Check if active?
+    //Is it worth breaking up incoming buffers? Probably not.
+    //TODO::: Handle 5 channel input
+
+    
+
+    if (inNumSamplesPerChannel == 0) {
+        return vector<StampedOggPacket*>();
+    }
+
+    //Check if this is correct with the last parameter, i think its samples per channel?
+    float** locBuffer = vorbis_analysis_buffer(&mVorbisDSPState, inNumSamplesPerChannel);
+
+    float* locOneOutputChannelBuffer = NULL;
+    const short* locReadChannelBuffer = NULL;
+    for (unsigned long chan = 0; chan < mSettings.mNumChannels; chan++) {
+        locOneOutputChannelBuffer = locBuffer[chan];
+        locReadChannelBuffer = inSampleBuffer + chan;
+        for (unsigned long sam = 0; sam < inNumSamplesPerChannel; sam++) {
+            locOneOutputChannelBuffer[sam] = ((float)(*locReadChannelBuffer)) / 32768.0f;
+            locReadChannelBuffer += mSettings.mNumChannels;
+        }
+    }
+
+    vorbis_analysis_wrote(&mVorbisDSPState, inNumSamplesPerChannel);
+
+    return extractOutputPackets();
+}
+
+vector<StampedOggPacket*> VorbisEncoder::flush()
+{
+    vorbis_analysis_wrote(&mVorbisDSPState, 0);
+
+    return extractOutputPackets();
+
+}
+
+vector<StampedOggPacket*> VorbisEncoder::extractOutputPackets()
+{
+    vector<StampedOggPacket*> retPackets;
+    ogg_packet locWorkingPacket;
+
+    while (vorbis_analysis_blockout(&mVorbisDSPState, &mVorbisBlock) == 1) {
+
+        vorbis_analysis(&mVorbisBlock, NULL);
+        vorbis_bitrate_addblock(&mVorbisBlock);
+
+        while (vorbis_bitrate_flushpacket(&mVorbisDSPState, &locWorkingPacket)) {
+            retPackets.push_back(oldToNewPacket(&locWorkingPacket));
+        }
+    }
+
+    return retPackets;
+}

Modified: trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.h
===================================================================
--- trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.h	2006-09-30 09:45:51 UTC (rev 11866)
+++ trunk/oggdsf/src/lib/codecs/vorbis/libs/libOOVorbis/VorbisEncoder.h	2006-09-30 12:01:27 UTC (rev 11867)
@@ -31,11 +31,19 @@
 
 #pragma once
 
+
+
+#include <vorbis/vorbisenc.h>
+
 #include <libOOOgg/dllstuff.h>
 #include <libOOOgg/StampedOggPacket.h>
 
 #include "VorbisEncodeSettings.h"
 
+#include <vector>
+
+using namespace std;
+
 class VorbisEncoder
 {
 public:
@@ -43,6 +51,19 @@
     ~VorbisEncoder(void);
 
 
-    bool setupCodec(VorbisEncodeSettings inSettings);
-    StampedOggPacket* encodeVorbis(unsigned short* inSampleBuffer, unsigned long inNumSamples);
+    vector<StampedOggPacket*> setupCodec(VorbisEncodeSettings inSettings);
+    vector<StampedOggPacket*> encodeVorbis(const short* const inSampleBuffer, unsigned long inNumSamplesPerChannel);
+    vector<StampedOggPacket*> flush();
+protected:
+	/// Converts a xiph like ogg packet into a StampedOggPacket.
+	StampedOggPacket* oldToNewPacket(ogg_packet* inPacket);
+
+    vector<StampedOggPacket*> extractOutputPackets();
+
+    vorbis_info mVorbisInfo;
+    vorbis_comment mVorbisComment;
+    vorbis_dsp_state mVorbisDSPState;
+    vorbis_block mVorbisBlock;
+
+    VorbisEncodeSettings mSettings;
 };



More information about the commits mailing list