• RTP GB28181 文件测试工具


    以下情况时使用了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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    在这里插入图片描述

    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);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136

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

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

  • 相关阅读:
    JSP Servlet JDBC MySQL CRUD 示例教程
    【二叉树】二叉树最大宽度
    图论应用——拓扑排序
    弹性蛋白酶的用途和化学性质
    【缓存】OS层面缓存设计机制
    猫头虎博主第5️⃣期赠书活动:《Java官方编程手册(第12版·Java 17)套装上下册》
    Hadoop 3.x(MapReduce)----【Hadoop 数据压缩】
    x86和arm框架下的centOS
    VMware虚拟网络编辑器配置
    公司股东退出机制法律分析
  • 原文地址:https://blog.csdn.net/qianbo042311/article/details/125629875