/// <summary>
/// Gets the H246 from ps.
/// </summary>
/// <param name="pBuffer">流数据.</param>
/// <param name="existBuffer">The exist buffer.</param>
/// <param name="action">解析后数据、是否须要下一个流数据拼接、是不是视频,是不是音频.</param>
public static void GetH246FromPS(byte[] pBuffer, List<byte> existBuffer, Action<byte[], bool, bool, bool> action)
{
List<byte> pH264 = new List<byte>();
byte[] searchBytes = new byte[3] { 0x00, 0x00, 0x01 };
int freamHeaderLength = 0;
int freamLength = 0;
if (pBuffer == null || pBuffer.Length <= 0)
return;
if (existBuffer.Count > 0)
{
existBuffer.AddRange(pBuffer);
pBuffer = existBuffer.ToArray();
existBuffer.Clear();
}
while (true)
{
begin:
if (pBuffer.Count() == 0)
break;
if (pBuffer.Count() < 9)
{
action(pBuffer, true, false, false);
break;
}
pH264.Clear();
if (pBuffer[0] == 0x00
&& pBuffer[1] == 0x00
&& pBuffer[2] == 0x01
&& pBuffer[3] == 0xBA/*ps_header*/)
{
//抛弃数据
if (pBuffer.Count() < 20)
{
action(pBuffer.ToArray(), true, false, false);
break;
}
pBuffer = pBuffer.Skip(20).ToArray();
goto begin;
}
if (pBuffer[0] == 0x00
&& pBuffer[1] == 0x00
&& pBuffer[2] == 0x01
&& (pBuffer[3] == 0xBD/*私有包头*/|| pBuffer[3] == 0xBC/*psm_header*/))
{
//抛弃数据
freamHeaderLength = 9 + (int)pBuffer[8];
freamLength = BitConverter.ToUInt16(new byte[2] { pBuffer[5], pBuffer[4] }, 0);
var nH264Lenth = freamLength + 6 - freamHeaderLength;
if (pBuffer.Count() < freamHeaderLength + nH264Lenth)
{
action(pBuffer.ToArray(), true, false, false);
break;
}
pBuffer = pBuffer.Skip(6 + freamLength).ToArray();
goto begin;
}
if (pBuffer[0] == 0x00
&& pBuffer[1] == 0x00
&& pBuffer[2] == 0x01
&& (pBuffer[3] >= 0xC0 && pBuffer[3] <= 0xDF))//pes_audio_header
{
freamHeaderLength = 9 + (int)pBuffer[8];
freamLength = BitConverter.ToUInt16(new byte[2] { pBuffer[5], pBuffer[4] }, 0);
var nH264Lenth = freamLength + 6 - freamHeaderLength;
if (pBuffer.Count() < freamHeaderLength + nH264Lenth)
{
action(pBuffer.ToArray(), true, false, false);
break;
}
pH264 = pBuffer.Skip(freamHeaderLength).Take(nH264Lenth).ToList();
action(pH264.ToArray(), false, false, true);
pBuffer = pBuffer.Skip(6 + freamLength).ToArray();
goto begin;
}
if (pBuffer[0] == 0x00
&& pBuffer[1] == 0x00
&& pBuffer[2] == 0x01
&& (pBuffer[3] >= 0xE0 && pBuffer[3] <= 0xEF))//pes_video_header
{
freamHeaderLength = 9 + (int)pBuffer[8];//9个为固定的数据包头长度,pBuffer[8]为填充头部分的长度
var beginIndex = IndexOf(pBuffer, searchBytes, freamHeaderLength + 2);
if (beginIndex != -1)
{
if (pBuffer[beginIndex - 1] == 0)//0x00000001
{
beginIndex -= 1;
}
var nH264Lenth = beginIndex - freamHeaderLength;
pH264 = pBuffer.Skip(freamHeaderLength).Take(nH264Lenth).ToList();
action(pH264.ToArray(), false, true, false);
pBuffer = pBuffer.Skip(beginIndex).ToArray();
goto begin;
}
else
{
action(pBuffer.ToArray(), true, false, false);
break;
}
}
if (pBuffer[0] == 0x00
&& pBuffer[1] == 0x00
&& pBuffer[2] == 0x00
&& pBuffer[3] == 0x01)//帧数据
{
freamHeaderLength = 0;
var beginIndex = IndexOf(pBuffer, searchBytes, freamHeaderLength + 2);
if (beginIndex != -1)
{
if (pBuffer[beginIndex - 1] == 0)//0x00000001
{
beginIndex -= 1;
}
var nH264Lenth = beginIndex - freamHeaderLength;
pH264 = pBuffer.Skip(freamHeaderLength).Take(nH264Lenth).ToList();
action(pH264.ToArray(), false, true, false);
pBuffer = pBuffer.Skip(beginIndex).ToArray();
goto begin;
}
else
{
action(pBuffer.ToArray(), true, false, false);
break;
}
}
break;
}
}
/// <summary>
/// 报告指定的 System.Byte[] 在此实例中的第一个匹配项的索引。
/// </summary>
/// <param name="srcBytes">被执行查找的 System.Byte[]。</param>
/// <param name="searchBytes">要查找的 System.Byte[]。</param>
/// <returns>若是找到该字节数组,则为 searchBytes 的索引位置;若是未找到该字节数组,则为 -1。若是 searchBytes 为 null 或者长度为0,则返回值为 -1。</returns>
private static int IndexOf(byte[] srcBytes, byte[] searchBytes, int startIndex = 0)
{
if (srcBytes == null) { return -1; }
if (searchBytes == null) { return -1; }
if (srcBytes.Count() == 0) { return -1; }
if (searchBytes.Length == 0) { return -1; }
if (srcBytes.Count() < searchBytes.Length) { return -1; }
for (int i = startIndex; i < srcBytes.Count() - searchBytes.Length + 1; i++)
{
if (srcBytes[i] == searchBytes[0])
{
if (searchBytes.Length == 1) { return i; }
bool flag = true;
for (int j = 1; j < searchBytes.Length; j++)
{
if (srcBytes[i + j] != searchBytes[j])
{
flag = false;
break;
}
}
if (flag) { return i; }
}
}
return -1;
}