当前位置:网站首页>RTP GB28181 文件测试工具

RTP GB28181 文件测试工具

2022-07-06 04:35:00 qianbo_insist

以下情况时使用了GB28181 中 udp发送视频流的情况,有的相机udp丢包比较严重,有的可以,对有问题的相机着重进行分析

read ps

RTP测试工具进一步升级
今天写了一段程序,为了解决花屏的问题,需要知道问题到底在哪里,保存了几百个ps文件,然后读出按照流程保存成h264文件,使用vlc 工具读,有简单跳帧。

int main_ps()
{
    
	int meetkeyframe = 0;
	const char* buffer = "j:/ps/h264save%d.264";
	char filename[128];
	uint8_t* h264buffer = new uint8_t[1024 * 500];
	int h264length = 0;
	int skip = 0;
	FILE* fpw = fopen("j:/out1.264", "wb");
	for (int i = 0; i < 2855; i++)
	{
    
		sprintf(filename, buffer, i);
		FILE* fp = fopen(filename, "rb");
		if (fp != NULL)
		{
    
			fseek(fp, 0, SEEK_END);
			long len = ftell(fp);
			fseek(fp, 0, SEEK_SET);
			//fread(pp, sizeof(char) * 4, 1, fp);
			uint8_t* data = new uint8_t[len];
			fread(data, len, 1, fp);
			if (*data == 0x00 && *(data + 1) == 0x00 && *(data + 2) == 0x01 && *(data + 3) == 0xba)
			{
    
				GetH264FromPs((char*)data, len, (char*)h264buffer, &h264length);
				if (h264length > 0)
				{
    
					if (meetkeyframe == 0)
					{
    
						uint8_t* pos = h264buffer + 4;
						if ((*pos & 0x1f) == 0x07)
							meetkeyframe = 1;
					}
					if (meetkeyframe == 1)
					{
    
						std::cout << "the length "<<len<< "--" << h264length << std::endl;
						fwrite(h264buffer, h264length, 1, fpw);
					}
					else
					{
    
						std::cout << "skip num" << skip++ << std::endl;
					}
				}
			}
			std::cout << "the file of" << i << std::endl;
			fclose(fp);
		}
	}
	fclose(fpw);
	return 0;
}

在这里插入图片描述

read rtp

为了进一步确定问题,读了1万6000个RTP包存储成文件,在存储成h264看情况如何

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include "../libRtpReceive/analysevideo.h"
#include "../libRtpReceive/c_rtp.h"


s_rtp_context g_ctx;

//解ps流,qianbo 请按照这条路走下去
int live_rtp_unpack_ps(s_rtp_context* ctx, uint8_t* payload, int payloadlen, uint32_t ssrc)
{
    
	uint8_t* buffer = ctx->v_buffer;
	int& buflen = ctx->v_len;
	//analyse_struct &as = ctx->v_as;
#define D(x) *(payload+x)
	if (D(0) == 0x00 && D(1) == 0x00 && D(2) == 0x01 && D(3) == 0xc0)
	{
    
		//(音频数据包)
		//std::cout << "audio packet" << std::endl;
		return 0;
	}

	if (D(0) == 0x00 && D(1) == 0x00 && D(2) == 0x01 && D(3) == 0xba)
	{
    
		if (buflen > 0)//数据已经凑齐,可以发送或者显示
		{
    
#define B(x) *(buffer+x)
			if (B(0) == 0x00 && B(1) == 0x00 && B(2) == 0x01 && B(3) == 0xba)
			{
    
				int h264length = 0;
				uint8_t* h26xbuffer = new uint8_t[buflen];
				GetH264FromPs((char*)buffer, buflen, (char*)h26xbuffer, &h264length);
				if (h264length > 0)
				{
    
					if (g_ctx.v_meet_keyframe == 0)
					{
    
						uint8_t* pos = h26xbuffer + 4;
						if ((*pos & 0x1f) == 0x07)
							g_ctx.v_meet_keyframe = 1;
					}
					if (g_ctx.v_meet_keyframe == 1)
					{
    
						if (g_ctx.fwp == NULL)
							g_ctx.fwp = fopen("j:/out2.264","wb");
						//std::cout << "the length " << len << "--" << h264length << std::endl;
						fwrite(h26xbuffer, h264length, 1, g_ctx.fwp);
					}
					else
					{
    
						//std::cout << "skip num" << skip++ << std::endl;
					}
				}

				if (ctx->v_meet_keyframe == 0)
				{
    
					//写入文件
				}
				delete[]h26xbuffer;
			}
			buflen = 0;
		}
	}
	//合帧
	std::memcpy(buffer + buflen, payload, payloadlen);
	buflen += payloadlen;
	return 0;
}





int ReadRTPPacket(uint8_t* data, int dlen)
{
    

	RTPFrame_ frame(data, (int)dlen);
	uint8_t* payload = frame.GetPayloadPtr();
	int payloadlen = frame.GetPayloadSize();
	uint32_t timestamp = frame.GetTimestamp();
	rtp_header* rtp = (rtp_header*)data;
	//big(net) to little(home)
	uint32_t ssrc = b2l(rtp->ssrc);

#define D(x) *(payload+x)
	//if (ctx->v_is_ps == -1)//未曾确定是否ps流
	if (D(0) == 0x00 && D(1) == 0x00 && D(2) == 0x01 && D(3) == 0xba)
	{
    
		//std::cout << " the stream is " << stream << std::endl;
		g_ctx.v_ssrc = ssrc;
		g_ctx.v_is_ps = 1;
	}
	if (g_ctx.v_is_ps == 1)
	{
    
		uint16_t nowseq = frame.GetSequenceNumber();
		std::cout << "seq:" << nowseq << " ";
		if (nowseq - g_ctx.v_last_sequenceNum != 1)
		{
    
			std::cout << "not continue seq "<< nowseq - g_ctx.v_last_sequenceNum <<std::endl;
		}
		g_ctx.v_last_sequenceNum = frame.GetSequenceNumber();

		g_ctx.v_payloadtype = frame.GetPayloadType();
		live_rtp_unpack_ps(&g_ctx, payload, payloadlen, ssrc);
	}
	return 0;
}
int main()
{
    
	const char* buffer = "j:/rtp/h264saveRTP%d.264";
	char filename[128];
	uint8_t* h264buffer = new uint8_t[1024 * 500];
	int h264length = 0;
	int skip = 0;
	//FILE* fpw = fopen("j:/out2.264", "wb");
	for (int i = 0; i < 16445; i++)
	{
    
		sprintf(filename, buffer, i);
		FILE* fp = fopen(filename, "rb");
		if (fp != NULL)
		{
    
			fseek(fp, 0, SEEK_END);
			long len = ftell(fp);
			fseek(fp, 0, SEEK_SET);
			//fread(pp, sizeof(char) * 4, 1, fp);
			uint8_t* data = new uint8_t[len];
			fread(data, len, 1, fp);
			ReadRTPPacket(data, len);

			//std::cout <<i <<" ";
			fclose(fp);
		}
	}
	if(g_ctx.fwp!=NULL)
		fclose(g_ctx.fwp);

}

通过打印RTP包的sequence number,相减后发现,丢包较多,平均每隔一定的时间会丢3-4个RTP包,有时会丢掉几十个,上几百个包,乱序的情况比较少,有一次,通过seq number相减后会得到负数。

RTP工具以后会同时增加分析RTP协议的可视化。

原网站

版权声明
本文为[qianbo_insist]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qianbo042311/article/details/125629875