本文中的程序是一个UDP/RTP协议流媒体数据解析器。该程序可以分析UDP协议中的RTP 包头中的内容,以及RTP负载中MPEG-TS封装格式的信息。通过修改该程序可以实现不同的UDP/RTP协议数据处理功能。
原理
MPEG-TS封装格式数据打包并通过RTP/UDP协议然后发送出去:
1、7个MPEG-TS Packet + RTP头👉👉👉RTP
2、UDP头 + RTP包👉👉UDP包
本文记录的程序是一个收取流媒体的程序,因此本文程序的流程和上述发送MPEG-TS的流程正好是相反的。该程序可以通过Socket编程收取UDP包,解析其中的RTP包的信息,然后再解析RTP包中MPEG-TS Packet的信息。
代码
整个程序位于simplest_udp_parser()函数中,如下所示。
/**
* 最简单的视音频数据处理示例
* Simplest MediaData Test
*
* 雷霄骅 Lei Xiaohua
* leixiaohua1020@126.com
* 中国传媒大学/数字电视技术
* Communication University of China / Digital TV Technology
* http://blog.youkuaiyun.com/leixiaohua1020
*
* from https://blog.youkuaiyun.com/leixiaohua1020/article/details/50535230
*/
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
#pragma pack(1)
/*
* [memo] FFmpeg stream Command:
* ffmpeg -re -i sintel.ts -f mpegts udp://127.0.0.1:8880
* ffmpeg -re -i sintel.ts -f rtp_mpegts udp://127.0.0.1:8880
*/
typedef struct RTP_FIXED_HEADER{
/* byte 0 */
unsigned char csrc_len:4; /* expect 0 */
unsigned char extension:1; /* expect 1 */
unsigned char padding:1; /* expect 0 */
unsigned char version:2; /* expect 2 */
/* byte 1 */
unsigned char payload:7;
unsigned char marker:1; /* expect 1 */
/* bytes 2, 3 */
unsigned short seq_no; //序列号
/* bytes 4-7 */
unsigned long timestamp;
/* bytes 8-11 */
unsigned long ssrc; /*同步源标识 stream number is used here. */
} RTP_FIXED_HEADER;
typedef struct MPEGTS_FIXED_HEADER {
unsigned sync_byte: 8;
unsigned transport_error_indicator: 1;
unsigned payload_unit_start_indicator: 1;
unsigned transport_priority: 1;
unsigned PID: 13;
unsigned scrambling_control: 2;
unsigned adaptation_field_exist: 2;
unsigned continuity_counter