#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位读取., 不会抛出任何异常.