题目:
在H.264视频编码标准中,编码帧由NALU头和NALU主体组成,其中NALU头由一个字节组成。在实际编码时,在每个NAL前添加起始码 0x000001,解码器在码流中检测到起始码,当前NAL结束。
为了防止NAL内部出现0x000001的数据,在编码完一个NAL时,如果检测出有连续两个0x00字节,就在后面插入一个0x03。
当解码器在NAL内部检测到0x000003的数据,就把0x03抛弃,恢复原始数据。给定一组包含SPS NALU的编码数据,找出解码后的SPS数据。比如:
输入:{0x1f 0x00 0x00 0x01 0x67 0x42 0xd0 0x80 0x00 0x00 0x03 0x00 0x80 0x00 0x0f 0x00 0x00 0x01 0x68 0xce 0x3c 0x80},
处理:在上述例子中,第一个0x00 0x00 0x01为识别到的数据头,0x00 0x00 0x03 0x00数据中,0x03为需抛弃数据,第二个0x00 0x00 0x01为下一个数据头,那么取出两个数据头中间的数据并且抛弃掉此0x03,结果如下:
{0x67 0x42 0xd0 0x80 0x00 0x00 0x00 0x80 0x00 0x0f }。
输入:
输入的第一行指定用例的数量T;
用例的第一行输入指定二进制数据长度N;
用例的第二行输入指定N个二进制数据元素C[i];
输出:
输出解码后的SPS数据
例子:
input:
1
23
0 0 01 67 42 c0 16 d0 80 0 0 03 0 80 0 0f 0 0 01 68 ce 3c 80
output:
67 42 c0 16 d0 80 0 0 0 80 0 0f
解题思路:
思路非常明确,用三个指针遍历即可,当三个指针指向的元素为0 0 01则从01后的元素开始遍历输出,中途三个指针指向的元素为0 0 03则删除03继续遍历输出,最后当三个指针指向的元素为0 0 01则停止输出,结束程序。
其中读入数据我采用了vector<string>,导致0或00没办法区分好,所以在程序中加了很多判断条件来区分,更好的办法是直接用数字读入就不会有这个问题了,由于我用的是string类型来处理,但输出要求用16进制数字,所以需要在输出做一个stoi()转换,并且cout后添加hex表示16进制输出。
#include<iostream>
#include<string>
#include<vector>
using namespace std;
vector<string> findSpsInH264(vector<string> & sps)
{
vector<string>::iterator pFirst = sps.begin();
vector<string>::iterator pSecond = sps.begin() + 1;
vector<string>::iterator pThird = sps.begin() + 2;
vector<string> result;
while ((*pFirst != "0" || *pSecond != "0" || *pThird != "01") && (*pFirst != "00" || *pSecond != "00" || *pThird != "01"))
{
pFirst++;
pSecond++;
pThird++;
}
//此时三个指针指向了0 0 01,可以开始读入
//将三个指针同时加3,就可以从01后的元素开始遍历
pFirst += 3;
pSecond += 3;
pThird += 3;
//在遇到下一个0 0 01之前都要读入
while ((*pFirst != "0" || *pSecond != "0" || *pThird != "01") && (*pFirst != "00" || *pSecond != "00" || *pThird != "01"))
{
//如果遇到0 0 03则删除03,同时维护pThird指针
if ((*pFirst == "0" && *pSecond == "0" && *pThird == "03") || (*pFirst == "00" && *pSecond == "00" && *pThird == "03"))
{
sps.erase(pThird);
pThird = pSecond + 1;
}
//将结果读入result中
result.push_back(*pFirst);
pFirst++;
pSecond++;
pThird++;
}
return result;
}
int main()
{
int k;
cin >> k;
while (k--)
{
int num;
cin >> num;
vector<string> sps;
for (int i = 0; i < num; i++)
{
string temp;
cin >> temp;
sps.push_back(temp);
}
vector<string> result = findSpsInH264(sps);
for (int i = 0; i < result.size(); i++)
cout << hex << stoi(result[i],nullptr,16) << (i == result.size()-1?"\n":" ");
}
return 0;
}