参考链接: 1. PES,TS,PS,RTP等流的打包格式解析之RTP流 https://blog.csdn.net/appledurian/article/details/73135343
2. RTP协议全解析(H264码流和PS流)https://blog.csdn.net/chen495810242/article/details/39207305
(重要)以下代码并未实测,除ts的发送外,其余都是伪代码(并且未搜集资料查询思路是否正确), 这边只为自己记录,参考请谨慎, 自己记录下而已。

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <time.h> 5 #include <getopt.h> 6 #include <errno.h> 7 #include <unistd.h> 8 #include <netinet/in.h> 9 #include <arpa/inet.h> 10 11 static union { char c[4]; unsigned long mylong; } endian_test = {{ 'l', '?', '?', 'b' } }; 12 13 #define ENDIANNESS ((char)endian_test.mylong) 14 15 #define PRINTF_DEBUG 16 #define TAB44 " " 17 18 #define MAX_ARGS_FILEFORMAT 10 19 #define MAX_ARGS_FILEPATH 128 20 #define MAX_RTPURL_IP 128 21 #define MAX_ARGS_RTPURL 256 22 #define MTU 1400 23 24 #define DEFAULT_FILE_PATH "./videos/mux/ts_test.ts" 25 #define DEFAULT_FILE_FORMAT "ts" 26 #define DEFAULT_RTP_URL "rtp://127.0.0.1:8888" 27 28 #define DEFAULT_ARGS {0, DEFAULT_FILE_PATH, DEFAULT_FILE_FORMAT, DEFAULT_RTP_URL} 29 30 /* define4ts */ 31 #define MAX_TS_PACKET_COUNT 7 32 #define TS_PACKET_LEN 188 33 34 /* define4ps */ 35 #define SCODE_PS_END 0x000001B9 36 #define SCODE_PS_HEADER 0x000001BA 37 #define SCODE_PS_SYSTEM_HEADER 0x000001BB 38 #define SCODE_PS_SYSTEM_MAP_HEADER 0x000001BC 39 40 /* define4mpeg2 */ 41 typedef enum e_mpeg2_sc_type 42 { 43 E_SC_MPEG2_SEQ_HEADER = 0x000001B3, 44 E_SC_MPEG2_SEQ_PIC_EXTEN_HEADER = 0x000001B5, 45 E_SC_MPEG2_SEQ_END = 0x000001B7, 46 E_SC_MPEG2_GROUP_HEADER = 0x000001B8, 47 E_SC_MPEG2_PICTURE_HEADER = 0x00000100 48 } E_MPEG2_SC_TYPE; 49 50 typedef enum e_rtp_playload_type 51 { 52 E_RTP_PLAYLOAD_TS = 33, 53 E_RTP_PLAYLOAD_PS = 96, 54 E_RTP_PLAYLOAD_MPEG4 = 97, 55 E_RTP_PLAYLOAD_H264 = 98, 56 } E_RTP_PLAYLOAD_TYPE; 57 58 typedef struct t_args 59 { 60 unsigned short isLoop; 61 62 unsigned char filePath[MAX_ARGS_FILEPATH+1]; 63 unsigned char fileFormat[MAX_ARGS_FILEFORMAT+1]; 64 unsigned char rtpUrl[MAX_ARGS_RTPURL+1]; 65 } T_ARGS; 66 67 /****************************************************** 68 个人理解 69 1. 位域内单字节的内存排布是定义的先后, 先定义的在内存的低地址; 70 2. 位域内单字节, 字节由高到低, 先定义的为高字节; 71 3. 因此对于小端(低地址放低字节). 72 ******************************************************/ 73 typedef struct t_rtp_header 74 { 75 #if 1 /* 小端, BIG_ENDIAN系统宏, 暂不知道怎么用 */ 76 /* bytes 0 */ 77 unsigned char csrc_len:4; 78 unsigned char extension:1; 79 unsigned char padding:1; 80 unsigned char version:2; 81 /* bytes 1*/ 82 unsigned char playload:7; 83 unsigned char marker:1; 84 #else 85 /* bytes 0 */ 86 unsigned char version:2; 87 unsigned char padding:1; 88 unsigned char extension:1; 89 unsigned char csrc_len:4; 90 /* bytes 1*/ 91 unsigned char marker:1; 92 unsigned char playload:7; 93 #endif 94 95 /* byte 2, 3 */ 96 unsigned short seq_no; 97 /* bytess 4-7 */ 98 unsigned int timestamp; 99 /* bytes 8-11 */ 100 unsigned int ssrc; 101 } T_RTP_HEADER; 102 103 /* gloabl data */ 104 FILE *fp = NULL; 105 106 struct sockaddr_in servAddr; 107 108 T_ARGS defaultArgs = DEFAULT_ARGS; 109 110 static void Usage(void) 111 { 112 fprintf(stderr, "usage: rtpserver [options] " 113 "Options: " 114 "-l | --stream_loop Read and send strame for loop " 115 "-i | --filepath File need to send " 116 "-f | --fileformat Container of file(support ts, ps, h264, mpeg2, flv) " 117 "-s | --rtpurl Rtp url include ip and port " 118 "-h | --help Print this message "); 119 } 120 121 /****************************************************************************** 122 1. const char shortOpt[] = "li:f:s:h"; 123 单个字符表示选项; 124 单个字符后接一个冒号, 表示后面必须跟一个参数. 参数紧跟选项后或者加一个空格; 125 单个字符后接两个冒号, 表示可有也可没有, 参数紧跟选项后, 不能加空格. 126 2. 参数的值赋给了optarg; 127 3. c = getopt_long(argc, argv, shortOpt, longOpt, NULL); 128 返回值为参数字符, 若全部解析完成则返回-1. 129 ******************************************************************************/ 130 static void ParseArgs(int argc, char *argv[], T_ARGS *args) 131 { 132 int c = 0; 133 134 const char shortOpt[] = "li:f:s:h"; 135 const struct option longOpt[] = { 136 {"stream_loop", no_argument, NULL, 'l'}, 137 {"filepath", required_argument, NULL, 'i'}, 138 {"fileformat", required_argument, NULL, 'f'}, 139 {"rtpurl", required_argument, NULL, 's'}, 140 {"help", no_argument, NULL, 'h'}, 141 {0, 0, 0, 0} 142 }; 143 144 for (;;) 145 { 146 c = getopt_long(argc, argv, shortOpt, longOpt, NULL); 147 148 if (-1 == c) 149 { 150 break; 151 } 152 153 switch (c) 154 { 155 case 'l': 156 args->isLoop = 1; 157 158 break; 159 160 case 'i': 161 memcpy(args->filePath, optarg, strlen(optarg)); 162 163 args->filePath[strlen(optarg)] = '