演示live555-liveMedia中BitVector class 比特流类的使用

#include "stdafx.h"
#include "CppUnitTest.h"

using namespace Microsoft::VisualStudio::CppUnitTestFramework;


/*
Ttile: 演示live555-liveMedia中BitVector class 比特流类的使用.
Author: Kagula
Date: 2019-1-16
environment: Visual studio community 2017 update5
             Live555 reference MEDIA_SERVER_VERSION_STRING "0.93"
			 Native unit test project
Description:
  通过对AudioSpecificConfig结构体前两个字节的读写
  演示[1]字节流转比特流工具的使用[2]如何从比特流中解析数据[3]如何把bit结构数据写到比特流中.
  相对于C++自带的bit struct, 好处是没有自动单,双,四字节对齐的问题.
  比如说7字节的AAC头的解析和合成, 就不能用c++ bit struct正确读写了.
Note:
  实际用的时候, 可以把BitVector从live555中提取出来.
*/

#include 

#include "../KagulaCommon/AAC.h"
#include "../liveMedia/include/BitVector.hh"

using namespace std;

namespace UnitTestBitVector
{		
	TEST_CLASS(UnitTest1)
	{
	public:
		
		TEST_METHOD(TestBitStream)
		{
			//下面测试读比特流
			kagula::AudioSpecificConfig asc;
			std::string strASCIIHex("121056E500");
			asc.parseFromASCIIHexStr(strASCIIHex);

			stringstream ss;
			ss << "audioObjectType = " << asc.audioObjectType << ","
				<< "samplingFrequencyIndex = " << asc.samplingFrequencyIndex << ","
				<< "channelConfiguration = " << asc.channelConfiguration << ","
				<< "frameLengthFlag = " << asc.frameLengthFlag << ","
				<< "dependsOnCoreCoder = " << asc.dependsOnCoreCoder << ","
				<< "extensionFlag = " << asc.extensionFlag << "\n";

			Logger::WriteMessage(ss.str().c_str());

			Assert::AreEqual(true, asc.audioObjectType == 2);

			//下面测试写比特流
			unsigned char data[2] = { 0 };
			BitVector bv(data, 0, sizeof(data) * 8);
			
			bv.putBits(asc.audioObjectType, 5);
			bv.putBits(asc.samplingFrequencyIndex, 4);
			bv.putBits(asc.channelConfiguration, 4);
			bv.putBits(asc.frameLengthFlag, 1);
			bv.put1Bit(asc.dependsOnCoreCoder);
			bv.put1Bit(asc.extensionFlag);

			Assert::AreEqual(true, data[0] == 0x12);
			Assert::AreEqual(true, data[1] == 0x10);

			//下面测试C++ bit struct
			//如果不存在对齐问题, 例如本例,  那是c++ bit struct比较方便.
			union AudioSpecificConfig_
			{
				kagula::AudioSpecificConfig asc;
				unsigned char data[2];
			} myBitStruct;
			myBitStruct.asc = asc;
			Assert::AreEqual(true, myBitStruct.data[0] == 0x10);//低字节
			Assert::AreEqual(true, myBitStruct.data[1] == 0x12);//高字节
		}
	};
}

AudioSpecificConfig的声明

	/*
	The Audio Specific Config is the global header for MPEG-4 Audio:
	该结构在“ISO-14496-3 Audio”中描述.
	*/
	struct EXT_CLASS AudioSpecificConfig
	{
		unsigned int extensionFlag : 1;
		unsigned int dependsOnCoreCoder : 1;
		unsigned int frameLengthFlag : 1;

		/*
		These are the channel configurations:
		0: Defined in AOT Specifc Config
		1: 1 channel: front-center
		2: 2 channels: front-left, front-right
		3: 3 channels: front-center, front-left, front-right
		4: 4 channels: front-center, front-left, front-right, back-center
		5: 5 channels: front-center, front-left, front-right, back-left, back-right
		6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
		7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel
		8-15: Reserved
		*/
		unsigned int channelConfiguration : 4;

		/*
		There are 13 supported frequencies:
		0: 96000 Hz
		1: 88200 Hz
		2: 64000 Hz
		3: 48000 Hz
		4: 44100 Hz
		5: 32000 Hz
		6: 24000 Hz
		7: 22050 Hz
		8: 16000 Hz
		9: 12000 Hz
		10: 11025 Hz
		11: 8000 Hz
		12: 7350 Hz
		13: Reserved
		14: Reserved
		*/
		unsigned int samplingFrequencyIndex : 4;

		/*
		MPEG-4 Audio Object Types:
		0: Null
		1: AAC Main
		2: AAC LC (Low Complexity)
		3: AAC SSR (Scalable Sample Rate)
		4: AAC LTP (Long Term Prediction)
		5: SBR (Spectral Band Replication)
		6: AAC Scalable
		7: TwinVQ
		8: CELP (Code Excited Linear Prediction)
		9: HXVC (Harmonic Vector eXcitation Coding)
		10: Reserved
		11: Reserved
		12: TTSI (Text-To-Speech Interface)
		13: Main Synthesis
		14: Wavetable Synthesis
		15: General MIDI
		16: Algorithmic Synthesis and Audio Effects
		17: ER (Error Resilient) AAC LC
		18: Reserved
		19: ER AAC LTP
		20: ER AAC Scalable
		21: ER TwinVQ
		22: ER BSAC (Bit-Sliced Arithmetic Coding)
		23: ER AAC LD (Low Delay)
		24: ER CELP
		25: ER HVXC
		26: ER HILN (Harmonic and Individual Lines plus Noise)
		27: ER Parametric
		28: SSC (SinuSoidal Coding)
		29: PS (Parametric Stereo)
		30: MPEG Surround
		31: (Escape value)
		32: Layer-1
		33: Layer-2
		34: Layer-3
		35: DST (Direct Stream Transfer)
		36: ALS (Audio Lossless)
		37: SLS (Scalable LosslesS)
		38: SLS non-core
		39: ER AAC ELD (Enhanced Low Delay)
		40: SMR (Symbolic Music Representation) Simple
		41: SMR Main
		42: USAC (Unified Speech and Audio Coding) (no SBR)
		43: SAOC (Spatial Audio Object Coding)
		44: LD MPEG Surround
		45: USAC
		*/
		unsigned int audioObjectType : 5;//audioObjectType = profile(x) + 1 = x + 1


		//这里传的是"a=fmtp:97 profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3; config=128856E500"字符串中的子字符串"128856E500".
		void parseFromASCIIHexStr(std::string &config);
	};

相关定义

	/*
	入口参数:src  源字符串
	出口参数:dest  存放运算结果
		返回:true  转换成功
			  false 失败
	*/
	bool String2Hex(std::string &src, unsigned char *dest)
	{
		unsigned char hb;
		unsigned char lb;

		if (src.size() % 2 != 0)
			return false;

		std::transform(src.begin(), src.end(), src.begin(), toupper);

		for (int i = 0, j = 0; i < src.size(); i++)
		{
			hb = src[i];
			if (hb >= 'A' && hb <= 'F')
				hb = hb - 'A' + 10;
			else if (hb >= '0' && hb <= '9')
				hb = hb - '0';
			else
				return false;

			i++;
			lb = src[i];
			if (lb >= 'A' && lb <= 'F')
				lb = lb - 'A' + 10;
			else if (lb >= '0' && lb <= '9')
				lb = lb - '0';
			else
				return false;

			dest[j++] = (hb << 4) | (lb);
		}
		return true;
	}
	void AudioSpecificConfig::parseFromASCIIHexStr(std::string & config)
	{
		if (config.size() < 2)
			return;


		unsigned char *data = new unsigned char[config.size()]();
		String2Hex(config, data);

		//比下面的代码更简单的办法是双字节数据直接映射到bit struct.
		BitVector bv(data, 0, 2 * 8);//我们只需要处理前面两个字节
		
		audioObjectType = bv.getBits(5);
		samplingFrequencyIndex = bv.getBits(4);
		channelConfiguration = bv.getBits(4);
		frameLengthFlag = bv.get1Bit();
		dependsOnCoreCoder = bv.get1Bit();
		extensionFlag = bv.get1Bit();
	}

注意

[1]BitVector的getBits方法最大只支持32位比特读取, 超过32位,  就自动设置为32位读取., 不会抛出任何异常.

你可能感兴趣的:(C++)