GB28181 ps流解析出h264

PS流格式可以自行网上搜索很多资料,参考网址:https://blog.csdn.net/u012519333/article/details/53208767

#ifndef __ACTIVE_PS_PARSER_H_ 
#define __ACTIVE_PS_PARSER_H_ 

typedef void APSPARSER_H;  //ACTIVE_PS_PARSER_HANDLE 
typedef void APSPARSER_USERDATA;

typedef struct{
	unsigned char es_type;
	unsigned char es_id;
	unsigned char *es_data;
	unsigned int es_data_length;
	unsigned long dts;
	unsigned long pts;
}PES_PACKET_S;

typedef struct{
	unsigned char *scr;
	unsigned char *program_mux_rate;
	unsigned long pack_id;
	PES_PACKET_S *pstPESPacket;
}PS_PACKET_S;

typedef int(*cbDataHandle)(PS_PACKET_S *pstPSPacket, APSPARSER_H * phParser, APSPARSER_USERDATA *pUserData);

#define STREAMID_MAP_SIZE 256 


class CTParserBufferManager
{
public:
	CTParserBufferManager();
	~CTParserBufferManager();

public:
	int StartVisitBuffer(unsigned char *pu8PSData, unsigned int u32PSDataLength);
	int EndVisitBuffer();
	int PopParsedBuffer();
	unsigned char	*ReadBytes(unsigned int u32Size);
	int				ReadBinary(unsigned int *pu32Out, unsigned int u32Size);
	int				SeekBytes(int s32Size);	
private:
	unsigned char * GetOutputBuffer(unsigned int u32NeedBytes);

private:
	unsigned char	*m_pu8Data;
	unsigned int	m_u32DataLength;

private:
	unsigned char	*m_pu8CacheBuffer;
	unsigned int	m_u32CacheBufferSize;
	unsigned int	m_u32CacheDataLength;

private:
	unsigned char   *m_pu8OutputBuffer;
	unsigned int	m_u32OutputBufferSize;

private:
	enum CUR_READ_SEGMENT
	{
		READ_CACHE_SEGMENT,
		READ_CURBUFFER_SEGMENT,
	}m_enReadSegment, m_enPopSegment;
	unsigned char	*m_pu8ReadPos;
	unsigned char	*m_pu8PopPos;
};

class CTActivePSParser : public CTParserBufferManager
{
public:
	CTActivePSParser(cbDataHandle cbDataHandleFuncs, APSPARSER_USERDATA *pUserData);
	~CTActivePSParser();

	int ParsePSData(unsigned char *pu8PSData, unsigned int u32PSDataLength);

private:
	int ParseSystemHeader();
	int ParsePESPacket();

	int WriteInOutputBuffer(unsigned char *pu8Data, unsigned int u32DataLength);

private:
	cbDataHandle m_cbDataHandleFuncs;
	APSPARSER_USERDATA *m_pUserData;

	unsigned char	*m_pu8OutputBuffer;
	unsigned int	m_u32OutputBufferSize;

	unsigned int	m_u32OutputBufferDataLength;
private:
	unsigned char	m_StreamIDMap[STREAMID_MAP_SIZE];
	bool			m_bParseSystemHead;
	unsigned long	m_PacketCounter;

private:
	unsigned char	m_u8MergeID;
	bool			m_bMergeFlag;
};


#endif
#include "stdafx.h"
#include    
#include    
#include    
#include    

#include "PsDemux.h"   

#define CACHE_BUFFSIZE_INC_UNIT (32 * 1024)   
#define MAX_CACHE_BUFFSIZE      (32 * 1024 * 20)   

#define MERGE_BUFFSIZE_INC_UNIT (128 * 1024)   
#define MERGE_BUFFER_SIZE       (65500)   
#define MAX_MERGE_BUFFER_SIZE   (128 * 1024 * 10)   

#define PACKET_START_CODE_PREFIX    (0x00000100)   
#define PACK_START_CODE             (0xBA)   
#define SYSTEM_HEADER_START_CODE    (0xBB)   
#define MAP_STREAM_ID               (0xBC)   

#define MPEG_PROGRAM_END_CODE       (0xB9)   

// typedef struct{   
//  unsigned int pack_start_code;   
//  unsigned int marker_bit1 : 2;   
//  unsigned int system_clock_reference_base_32_30  : 3;   
//  unsigned int marker_bit2 : 1;   
//  unsigned int system_clock_reference_base_29_15  : 15;   
//  unsigned int marker_bit3 : 1;   
//  unsigned int system_clock_reference_base_14_0   : 15;   
//  unsigned int marker_bit4 : 1;   
//  unsigned int system_clock_reference_extension   : 9;   
//  unsigned int marker_bit5 : 1;   
//  unsigned int program_mux_rate                   : 22;   
//  unsigned int marker_bit6 : 1;   
//  unsigned int reserved : 5;   
//  unsigned int pack_stuffing_length               : 3;   
// }pack_header;   

CTParserBufferManager::CTParserBufferManager()
{
m_pu8CacheBuffer = NULL;
m_u32CacheBufferSize = 0;
m_u32CacheDataLength = 0;

m_pu8ReadPos = NULL;
m_pu8PopPos = NULL;

m_pu8OutputBuffer = NULL;
m_u32OutputBufferSize = 0;

m_enReadSegment = m_enPopSegment = READ_CACHE_SEGMENT;
}

CTParserBufferManager::~CTParserBufferManager()
{
if (m_pu8CacheBuffer)
{
	delete[]m_pu8CacheBuffer;
	m_pu8CacheBuffer = NULL;
}

if (m_pu8OutputBuffer)
{
	delete[]m_pu8OutputBuffer;
	m_pu8OutputBuffer = NULL;
}
}

int CTParserBufferManager::StartVisitBuffer(unsigned char *pu8PSData, unsigned int u32PSDataLength)
{
m_pu8Data = pu8PSData;
m_u32DataLength = u32PSDataLength;


if (m_u32CacheDataLength > 0)
{
	m_enPopSegment = m_enReadSegment = READ_CACHE_SEGMENT;
	m_pu8PopPos = m_pu8ReadPos = m_pu8CacheBuffer;
}
else
{
	m_enPopSegment = m_enReadSegment = READ_CURBUFFER_SEGMENT;
	m_pu8PopPos = m_pu8ReadPos = m_pu8Data;
}

return 0;
}

int CTParserBufferManager::EndVisitBuffer()
{
unsigned int u32PrepareCacheSize = 0;

if (((m_enPopSegment == READ_CACHE_SEGMENT) && (m_pu8PopPos > (m_pu8CacheBuffer + m_u32CacheDataLength)))
	|| ((m_enPopSegment == READ_CURBUFFER_SEGMENT) && (m_pu8PopPos > (m_pu8Data + m_u32DataLength))))
{
	ASSERT(0);
	return -1;
}

if (m_enPopSegment == READ_CACHE_SEGMENT)
{
	u32PrepareCacheSize = ((m_u32CacheDataLength - (m_pu8PopPos - m_pu8CacheBuffer)) + m_u32DataLength);
	if (m_u32CacheBufferSize < u32PrepareCacheSize)
	{
		unsigned char *pu8Tmp = NULL;
		pu8Tmp = new unsigned char[(u32PrepareCacheSize + CACHE_BUFFSIZE_INC_UNIT) / CACHE_BUFFSIZE_INC_UNIT * CACHE_BUFFSIZE_INC_UNIT];
		ASSERT(pu8Tmp != NULL);
		m_u32CacheBufferSize = ((u32PrepareCacheSize + CACHE_BUFFSIZE_INC_UNIT) / CACHE_BUFFSIZE_INC_UNIT * CACHE_BUFFSIZE_INC_UNIT);

		memmove(pu8Tmp, m_pu8PopPos, (m_u32CacheDataLength - (m_pu8PopPos - m_pu8CacheBuffer)));
		m_u32CacheDataLength = (m_u32CacheDataLength - (m_pu8CacheBuffer - m_pu8PopPos));

		if (m_pu8CacheBuffer)
		{
			delete[]m_pu8CacheBuffer;
		}
		m_pu8CacheBuffer = pu8Tmp;
	}
	else
	{
		if (m_pu8PopPos != m_pu8CacheBuffer)
		{
			memmove(m_pu8CacheBuffer, m_pu8PopPos, (m_u32CacheDataLength - (m_pu8PopPos - m_pu8CacheBuffer)));
			m_u32CacheDataLength = (m_u32CacheDataLength - (m_pu8PopPos - m_pu8CacheBuffer));
		}
	}

	memmove(m_pu8CacheBuffer + m_u32CacheDataLength, m_pu8Data, m_u32DataLength);
	m_u32CacheDataLength += m_u32DataLength;
}
else if (m_enPopSegment == READ_CURBUFFER_SEGMENT)
{
	u32PrepareCacheSize = (m_u32DataLength - (m_pu8PopPos - m_pu8Data));

	if (m_u32CacheBufferSize < u32PrepareCacheSize)
	{
		if (u32PrepareCacheSize > MAX_CACHE_BUFFSIZE)
		{
			ASSERT(0);
			return -1;
		}

		unsigned char *pu8Tmp = NULL;
		pu8Tmp = new unsigned char[(u32PrepareCacheSize + CACHE_BUFFSIZE_INC_UNIT) / CACHE_BUFFSIZE_INC_UNIT * CACHE_BUFFSIZE_INC_UNIT];
		ASSERT(pu8Tmp != NULL);

		if (m_pu8CacheBuffer)
		{
			delete[]m_pu8CacheBuffer;
		}

		m_pu8CacheBuffer = pu8Tmp;
		m_u32CacheBufferSize = ((u32PrepareCacheSize + CACHE_BUFFSIZE_INC_UNIT) / CACHE_BUFFSIZE_INC_UNIT * CACHE_BUFFSIZE_INC_UNIT);
	}

	memmove(m_pu8CacheBuffer, m_pu8PopPos, u32PrepareCacheSize);
	m_u32CacheDataLength = u32PrepareCacheSize;
}
}

int CTParserBufferManager::PopParsedBuffer()
{
m_enPopSegment = m_enReadSegment;
m_pu8PopPos = m_pu8ReadPos;

return 0;
}

unsigned char * CTParserBufferManager::GetOutputBuffer(unsigned int u32NeedBytes)
{
if (u32NeedBytes > m_u32OutputBufferSize)
{
	unsigned char *pu8TmpBuffer = new unsigned char[(u32NeedBytes + CACHE_BUFFSIZE_INC_UNIT) / CACHE_BUFFSIZE_INC_UNIT * CACHE_BUFFSIZE_INC_UNIT];
	if (!pu8TmpBuffer)
	{
		return NULL;
	}
	if (m_pu8OutputBuffer)
	{
		delete[]m_pu8OutputBuffer;
	}

	m_pu8OutputBuffer = pu8TmpBuffer;
	m_u32OutputBufferSize = (u32NeedBytes + CACHE_BUFFSIZE_INC_UNIT) / CACHE_BUFFSIZE_INC_UNIT * CACHE_BUFFSIZE_INC_UNIT;
}

return m_pu8OutputBuffer;
}

unsigned char * CTParserBufferManager::ReadBytes(unsigned int u32Size)
{
unsigned int u32CacheHaveDataLength, u32CurBufferHaveDataLength;
unsigned int u32NeedBytes = 0;
unsigned char *pu8OutputBuffer = NULL;
bool bUseOutputBuffer = false;

if (u32Size == 0)
{
	return m_pu8ReadPos;
}

if (m_enReadSegment == READ_CACHE_SEGMENT)
{
	u32CacheHaveDataLength = (m_pu8CacheBuffer + m_u32CacheDataLength - m_pu8ReadPos);
	u32CurBufferHaveDataLength = m_u32DataLength;
}
else
{
	u32CacheHaveDataLength = 0;
	u32CurBufferHaveDataLength = (m_pu8Data + m_u32DataLength - m_pu8ReadPos);
}

if (u32Size > (u32CacheHaveDataLength + u32CurBufferHaveDataLength))
{
	return NULL; 
}

u32NeedBytes = u32Size;

if (m_enReadSegment == READ_CACHE_SEGMENT)
{
	if (u32NeedBytes <= u32CacheHaveDataLength)
	{
		//memcpy(GetOutputBuffer(u32NeedBytes), m_pu8ReadPos, u32NeedBytes);   
		pu8OutputBuffer = m_pu8ReadPos;
		m_pu8ReadPos += u32NeedBytes;

		u32NeedBytes = 0;
	}
	else
	{
		if (u32CacheHaveDataLength > 0)
		{
			pu8OutputBuffer = GetOutputBuffer(u32NeedBytes);

			memcpy(pu8OutputBuffer, m_pu8ReadPos, u32CacheHaveDataLength);
			u32NeedBytes -= u32CacheHaveDataLength;
			u32CacheHaveDataLength = 0;

			bUseOutputBuffer = true;
		}

		m_enReadSegment = READ_CURBUFFER_SEGMENT;
		m_pu8ReadPos = m_pu8Data;
	}
}

if ((u32NeedBytes > 0) && (m_enReadSegment == READ_CURBUFFER_SEGMENT))
{
	if (u32NeedBytes > m_u32DataLength)
	{
		ASSERT(0);
		return NULL;
	}
	else
	{
		if (bUseOutputBuffer == true)
		{
			memcpy(pu8OutputBuffer + (u32Size - u32NeedBytes), m_pu8ReadPos, u32NeedBytes);
		}
		else
		{
			pu8OutputBuffer = m_pu8ReadPos;
		}

		m_pu8ReadPos += u32NeedBytes;
	}
}

return pu8OutputBuffer;
}

int CTParserBufferManager::ReadBinary(unsigned int *pu32Out, unsigned int u32Size)
{
unsigned int x = 0;
unsigned char c;
unsigned char *pu8Out = NULL;

for (unsigned int i = 0; i < u32Size; i++){
	if ((pu8Out = ReadBytes(1)) == NULL)
	{
		return -1;
	}

	c = *pu8Out;
	x |= c << ((u32Size - i - 1) * 8);
}

*pu32Out = x;

return 0;
}

int CTParserBufferManager::SeekBytes(int s32Size)
{

if (s32Size > 0)
{
	if (ReadBytes((unsigned int)s32Size) != 0)
	{
		return -1;
	}
	else
	{
		return 0;
	}
}
else if (s32Size < 0)
{
	unsigned int u32Size = abs(s32Size);
	if (m_enReadSegment == READ_CACHE_SEGMENT)
	{
		if (u32Size <= (m_pu8ReadPos - m_pu8CacheBuffer))
		{
			m_pu8ReadPos -= u32Size;
		}
		else
		{
			return -1;
		}
	}
	else
	{
		if (u32Size <= (m_pu8ReadPos - m_pu8Data))
		{
			m_pu8ReadPos -= u32Size;
		}
		else if (u32Size <= ((m_pu8ReadPos - m_pu8Data) + m_u32CacheDataLength))
		{
			m_pu8ReadPos = (m_pu8CacheBuffer + (m_u32CacheDataLength - (u32Size - (m_pu8ReadPos - m_pu8Data))));
			m_enReadSegment = READ_CACHE_SEGMENT;
		}
		else
		{
			return -1;
		}
	}
}

return 0;
}

#define READ_BYTE(OUT_UCHAR, FAIL) \
do{ \
	unsigned char *pTmp; \
	if ((pTmp = ReadBytes(1)) == NULL)   \
	{   \
	goto FAIL;  \
	}   \
	else    \
	{   \
	OUT_UCHAR = *pTmp;  \
	}   \
} while (0) \

#define READ_BYTES(OUT_POINT, NUM, FAIL) \
do{ \
	if ((OUT_POINT = ReadBytes(NUM)) == NULL)    \
	{   \
	goto FAIL;  \
	}   \
} while (0) \

#define READ_BINARY(OUT_UINT, NUM, FAIL) \
do{ \
	if (ReadBinary(&OUT_UINT, NUM) < 0)   \
	{   \
	goto FAIL;  \
	}   \
} while (0) \

#define SEEK_BYTES(NUM, FAIL) \
do{ \
	if (SeekBytes(NUM) < 0)   \
	{   \
	goto FAIL;  \
	}   \
} while (0) \

CTActivePSParser::CTActivePSParser(cbDataHandle cbDataHandleFuncs, APSPARSER_USERDATA *pUserData)
: m_cbDataHandleFuncs(cbDataHandleFuncs), m_pUserData(pUserData)
	{
		m_bParseSystemHead = false;
		m_PacketCounter = 0;
		memset(m_StreamIDMap, 0, sizeof(unsigned char) * STREAMID_MAP_SIZE);

		m_pu8OutputBuffer = NULL;
		m_u32OutputBufferSize = 0;

		m_u8MergeID = 0;
		m_bMergeFlag = false;
		m_u32OutputBufferDataLength = 0;

	}

CTActivePSParser::~CTActivePSParser()
{

}

int CTActivePSParser::ParseSystemHeader()
{
	unsigned char *pu8Point = NULL;
	unsigned int system_header_length = 0;

	unsigned int program_stream_map_length = 0;
	unsigned int elementary_stream_map_length = 0;
	unsigned int program_stream_info_length = 0;

	unsigned char stream_type = 0;
	unsigned char elementary_stream_id = 0;
	unsigned int  elementary_stream_info_length = 0;

	do
	{
		do
		{
			READ_BYTES(pu8Point, 1, ParseSystemHeaderFail);
		} while (*pu8Point != SYSTEM_HEADER_START_CODE);

		SEEK_BYTES(-4, ParseSystemHeaderFail);

		PopParsedBuffer();

		READ_BYTES(pu8Point, 4, ParseSystemHeaderFail);

		//if(*((unsigned int *)pu8Point) == (PACKET_START_CODE_PREFIX | SYSTEM_HEADER_START_CODE))   
		if (pu8Point[0] == 0x00 && pu8Point[1] == 0x00 && pu8Point[2] == 0x01 && pu8Point[3] == SYSTEM_HEADER_START_CODE)
		{
			READ_BINARY(system_header_length, 2, ParseSystemHeaderFail); //read  system_header.header_length   
			if (system_header_length > 65535)
			{
				continue;
			}
			READ_BYTES(pu8Point, system_header_length, ParseSystemHeaderFail);

			READ_BYTES(pu8Point, 4, ParseSystemHeaderFail);

			//Parse  program_stream_map()   
			//if(*((unsigned int *)pu8Point) == (PACKET_START_CODE_PREFIX | MAP_STREAM_ID))   
			if (pu8Point[0] == 0x00 && pu8Point[1] == 0x00 && pu8Point[2] == 0x01 && pu8Point[3] == MAP_STREAM_ID)
			{

				// skip program_stream_map_length + map_version   
				READ_BINARY(program_stream_map_length, 2, ParseSystemHeaderFail);

				READ_BYTES(pu8Point, 2, ParseSystemHeaderFail);

				READ_BINARY(program_stream_info_length, 2, ParseSystemHeaderFail);
				if (program_stream_info_length > 65535)
				{
					continue;
				}

				READ_BYTES(pu8Point, program_stream_info_length, ParseSystemHeaderFail);

				READ_BINARY(elementary_stream_map_length, 2, ParseSystemHeaderFail);
				while (elementary_stream_map_length > 4)
				{
					READ_BYTE(stream_type, ParseSystemHeaderFail);
					READ_BYTE(elementary_stream_id, ParseSystemHeaderFail);
					READ_BINARY(elementary_stream_info_length, 2, ParseSystemHeaderFail);

					m_StreamIDMap[elementary_stream_id] = stream_type;
					READ_BYTES(pu8Point, elementary_stream_info_length, ParseSystemHeaderFail); //descriptor()   
					//自己加的
					//elementary_stream_map_length -=elementary_stream_info_length;
					elementary_stream_map_length -= 4;
				}
				m_PacketCounter++;
				m_bParseSystemHead = true;
			}
		}

	} while (m_bParseSystemHead == false);

	return 0;

ParseSystemHeaderFail:

	return -1;
}

unsigned long get_PTS_DTS(unsigned char *data)
{
	unsigned long t = (*data & 0x0e) << 29 |
		((((*(data + 1)) << 8) | (*(data + 2))) >> 1) << 15 |
		(((*(data + 3)) << 8) | (*(data + 4))) >> 1;
	return t;
}

int CTActivePSParser::ParsePESPacket()
{
	unsigned char u8Value = 0;
	unsigned char *pu8Point = NULL;

	PS_PACKET_S     stPSPacket;
	PES_PACKET_S    stPESPacket;

	unsigned int PES_packet_length = 0;
	unsigned char PTS_DTS_flags = 0;
	unsigned int PES_header_data_length = 0;
	unsigned char * pesinfo = NULL;

	unsigned int es_data_len = 0;
	unsigned char * esdata = NULL;

	do
	{
		do
		{
			READ_BYTE(u8Value, ParsePESPacketFail);
		} while (u8Value != 0x01);

		SEEK_BYTES(-3, ParsePESPacketFail);

		PopParsedBuffer();

		READ_BYTES(pu8Point, 3, ParsePESPacketFail);
		if (pu8Point[0] == 0x00 && pu8Point[1] == 0x00 && pu8Point[2] == 0x01)
		{
			READ_BYTE(u8Value, ParsePESPacketFail); // 224 : E0 | 192 : C0   
			if (u8Value == 0xBA)
			{
				m_PacketCounter++;
			}
			if (m_StreamIDMap[u8Value] != 0)
			{
				PES_packet_length = 0;
				READ_BINARY(PES_packet_length, 2, ParsePESPacketFail);
				// parse pts_dts flag   
				READ_BYTES(pu8Point, 1, ParsePESPacketFail);

				PTS_DTS_flags = 0;
				PES_header_data_length = 0;
				pesinfo = NULL;

				READ_BYTE(PTS_DTS_flags, ParsePESPacketFail);
				READ_BINARY(PES_header_data_length, 1, ParsePESPacketFail);
				READ_BYTES(pesinfo, PES_header_data_length, ParsePESPacketFail);

				if (PTS_DTS_flags & 0x80)
				{
					// pts   
					stPESPacket.pts = get_PTS_DTS(pesinfo);
					if (PTS_DTS_flags & 0x40)
					{
						// dts   
						stPESPacket.dts = get_PTS_DTS(pesinfo + 5);
					}
				}

				// 17126238 unknown why length not correct,skip   
				if (PES_header_data_length > PES_packet_length)
				{
					continue;
				}
				if ((PES_packet_length - PES_header_data_length) <= 3)
				{
					continue;
				}

				es_data_len = PES_packet_length - PES_header_data_length - 3;
				esdata = NULL;

				READ_BYTES(esdata, es_data_len, ParsePESPacketFail);

				if (m_bMergeFlag && u8Value == m_u8MergeID && es_data_len < MERGE_BUFFER_SIZE)
				{
					//if (esdata[0] == 0x0 && esdata[1] == 0x0 && esdata[])
					WriteInOutputBuffer(esdata, es_data_len);

					stPESPacket.es_type = m_StreamIDMap[u8Value];
					stPESPacket.es_id = u8Value;
					stPESPacket.es_data = m_pu8OutputBuffer;
					stPESPacket.es_data_length = m_u32OutputBufferDataLength + es_data_len;
					stPSPacket.pstPESPacket = &stPESPacket;
					stPSPacket.pack_id = m_PacketCounter;
					m_bMergeFlag = false;
					m_u8MergeID = 0;
					m_u32OutputBufferDataLength = 0;

				}
				else
				{
					stPESPacket.es_type = m_StreamIDMap[u8Value];
					stPESPacket.es_id = u8Value;
					stPESPacket.es_data = esdata;
					stPESPacket.es_data_length = es_data_len;
					stPSPacket.pstPESPacket = &stPESPacket;
					stPSPacket.pack_id = m_PacketCounter;
					if (es_data_len == MERGE_BUFFER_SIZE)
					{
						WriteInOutputBuffer(esdata, es_data_len);
						m_bMergeFlag = true;
						m_u8MergeID = u8Value;
						continue;
					}
				}

				if (m_cbDataHandleFuncs)
				{
					m_cbDataHandleFuncs(&stPSPacket, this, m_pUserData);
				}

				PopParsedBuffer();

				// printf("read es data length [%d],counter [%x]\n",es_data_len,rsb.counter);   
				break;
			}
			// audio data   
			if (u8Value >= 0xC0 && u8Value <= 0xDF)
			{
				break;
			}
			// video data   
			if (u8Value >= 0xE0 && u8Value <= 0xEF)
			{
				break;
			}
		}
		else
		{
			continue;
		}
	} while (1);

	return 0;

ParsePESPacketFail:

	return -1;
}

int CTActivePSParser::WriteInOutputBuffer(unsigned char *pu8Data, unsigned int u32DataLength)
{
	if (!pu8Data)
	{
		return -1;
	}

	if (!m_pu8OutputBuffer)
	{
		m_pu8OutputBuffer = new unsigned char[m_u32OutputBufferSize = ((u32DataLength + MERGE_BUFFSIZE_INC_UNIT) / MERGE_BUFFSIZE_INC_UNIT * MERGE_BUFFSIZE_INC_UNIT)];
	}
	else
	{
		if (m_u32OutputBufferSize < (m_u32OutputBufferDataLength + u32DataLength))
		{
			unsigned char *pu8Tmp = new unsigned char[m_u32OutputBufferSize = (((m_u32OutputBufferDataLength + u32DataLength) + MERGE_BUFFSIZE_INC_UNIT) / MERGE_BUFFSIZE_INC_UNIT * MERGE_BUFFSIZE_INC_UNIT)];

			ASSERT(pu8Tmp);
			memcpy(pu8Tmp, m_pu8OutputBuffer, m_u32OutputBufferDataLength);

			delete[]m_pu8OutputBuffer;
			m_pu8OutputBuffer = pu8Tmp;
		}

		memcpy(m_pu8OutputBuffer + m_u32OutputBufferDataLength, pu8Data, u32DataLength);
		m_u32OutputBufferDataLength += u32DataLength;
	}

	return 0;
}

int CTActivePSParser::ParsePSData(unsigned char *pu8PSData, unsigned int u32PSDataLength)
{
	if ((!pu8PSData) || (u32PSDataLength == 0))
	{
		return -1;
	}

	StartVisitBuffer(pu8PSData, u32PSDataLength);

	do
	{
		if (!m_bParseSystemHead)
		{
			if (ParseSystemHeader() < 0)
			{
				break;
			}
		}

		if (ParsePESPacket() < 0)
		{
			break;
		}
	} while (1);

	EndVisitBuffer();

	return 0;
}

此代码可以将GB28181 PS解析成h264,但是海康视频流解析出来的h264通过解码直接给ffmpeg 解码h264会出现如下,下半部分花的情况很是苦闷:

GB28181 ps流解析出h264_第1张图片

但是通过使用一些比较常规播放器除了vlc不能播放,想potplayer,暴风等都能正常播放,说明解析ps流应该是没问题,问题出在了解码上,通过搜索资料查阅大概问题是出在了h264解码器,如果给00 00 00 01 09分隔符,或SEI信息造成的,目前该问题未解决,希望有志之士指点一二。

你可能感兴趣的:(音视频相关,C++)