题目:

在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;
}