├── include ├── raw_quic_api.h └── raw_quic_define.h ├── lib └── linux │ └── librawquic.so ├── README.md └── src └── trunk ├── research └── librtmp │ └── srs_h264_raw_publish.c └── out └── srs_librtmp.h /include/raw_quic_api.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonysuqin/SrsQuic/HEAD/include/raw_quic_api.h -------------------------------------------------------------------------------- /include/raw_quic_define.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonysuqin/SrsQuic/HEAD/include/raw_quic_define.h -------------------------------------------------------------------------------- /lib/linux/librawquic.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sonysuqin/SrsQuic/HEAD/lib/linux/librawquic.so -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SrsQuic 2 | 3 | This project use srs-librtmp exported from [srs project](https://github.com/ossrs/srs) to push rtmp stream over quic with [RawQuic library](https://github.com/sonysuqin/RawQuic). 4 | 5 | ## Supported platform 6 | Currently tested on Linux/Windows, other platforms like android/ios should also be all right. 7 | 8 | ## srs-librtmp 9 | Base on srs 2.0release, exported as single file, added some platform specified adaption. 10 | See 11 | ``` 12 | SrsQuic/trunk/out/srs_librtmp.h 13 | SrsQuic/trunk/out/srs_librtmp.cpp 14 | ``` 15 | 16 | ## Server 17 | We provide [nginx-quic](https://github.com/evansun922/nginx-quic) with quic patched, rtmp module with quic also supported now. 18 | Rtmp additional configure 19 | ``` 20 | rtmp { 21 | log_format rtmp_log '$remote_addr [$time_local] $command "$app" "$name" "$args" ' 22 | '$bytes_received $bytes_sent $session_time ' 23 | '"$pageurl" "$tcurl" "$swfurl" "$flashver"'; 24 | 25 | access_log logs/rtmp.log rtmp_log; 26 | 27 | server { 28 | listen 1935 so_keepalive=on; 29 | listen 1935 quic; 30 | 31 | ssl_certificate /etc/letsencrypt/live/roblin.cn/fullchain.pem; # managed by Certbot 32 | ssl_certificate_key /etc/letsencrypt/live/roblin.cn/privkey.pem; # managed by Certbot 33 | 34 | max_message 10M; 35 | publish_time_fix on; 36 | chunk_size 4096; 37 | out_queue 17; 38 | 39 | application live { 40 | live on; 41 | idle_streams off; 42 | drop_idle_publisher 1800s; 43 | sync 1s; 44 | wait_key on; 45 | wait_video off; 46 | notify_method get; 47 | } 48 | } 49 | } 50 | ``` 51 | 52 | ## How to use 53 | 54 | ### Build RawQuic library 55 | Under ubuntu 1604, a prebuilt RawQuic shared library librawquic.so provided under SrsQuic/lib/linux. 56 | Custom build refer to [RawQuic library](https://github.com/sonysuqin/RawQuic). 57 | 58 | ### Integrate sources 59 | Integrate files bellow to your project 60 | ``` 61 | SrsQuic/include/raw_quic_api.h 62 | SrsQuic/include/raw_quic_define.h 63 | SrsQuic/trunk/out/srs_librtmp.h 64 | SrsQuic/trunk/out/srs_librtmp.cpp 65 | librawquic.so 66 | ``` 67 | 68 | ### Call api in srs_librtmp.h 69 | For using rtmp over quic, you should call srs_rtmp_over_quic_create instead of srs_rtmp_create. 70 | 71 | ## Demo 72 | ### Build 73 | ``` 74 | cd SrsQuic/build 75 | cmake . 76 | make 77 | ``` 78 | This will build src/trunk/research/librtmp/srs_h264_raw_publish.c with srs-librtmp and RawQuic library, this demo can only push raw h264 stream. 79 | 80 | ### Prepare h264 raw file 81 | ``` 82 | ffmpeg -i 1.mp4 -c:v copy -bsf:v h264_mp4toannexb -an 1.h264 83 | ``` 84 | 85 | ### Push stream 86 | A test [server](https://github.com/evansun922/nginx-quic) is running on roblin.cn, you SHOULD setup your own, please refer to [nginx-quic](https://github.com/evansun922/nginx-quic). 87 | ``` 88 | cd SrsQuic/bin 89 | ./raw_h264_publisher 1.h264 rtmp://roblin.cn:1935/live/1 25 90 | ``` 91 | 92 | ### Pull stream 93 | You can pull with fflay or vlc. 94 | ``` 95 | ffplay 'rtmp://roblin.cn:1935/live/1' 96 | ``` 97 | 98 | Copyright © 2020 Sohu.com Inc. All Rights Reserved. 99 | -------------------------------------------------------------------------------- /src/trunk/research/librtmp/srs_h264_raw_publish.c: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 SRS(ossrs) 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | /** 24 | gcc srs_h264_raw_publish.c ../../objs/lib/srs_librtmp.a -g -O0 -lstdc++ -o srs_h264_raw_publish 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | // for open h264 raw file. 32 | #include 33 | #include 34 | #include 35 | 36 | #include "srs_librtmp.h" 37 | 38 | int read_h264_frame(char* data, int size, char** pp, int* pnb_start_code, int fps, 39 | char** frame, int* frame_size, int* dts, int* pts) 40 | { 41 | char* p = *pp; 42 | 43 | // @remark, for this demo, to publish h264 raw file to SRS, 44 | // we search the h264 frame from the buffer which cached the h264 data. 45 | // please get h264 raw data from device, it always a encoded frame. 46 | if (!srs_h264_startswith_annexb(p, size - (p - data), pnb_start_code)) { 47 | srs_human_trace("h264 raw data invalid."); 48 | return -1; 49 | } 50 | 51 | // @see srs_write_h264_raw_frames 52 | // each frame prefixed h.264 annexb header, by N[00] 00 00 01, where N>=0, 53 | // for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40) 54 | *frame = p; 55 | p += *pnb_start_code; 56 | 57 | for (;p < data + size; p++) { 58 | if (srs_h264_startswith_annexb(p, size - (p - data), NULL)) { 59 | break; 60 | } 61 | } 62 | 63 | *pp = p; 64 | *frame_size = p - *frame; 65 | if (*frame_size <= 0) { 66 | srs_human_trace("h264 raw data invalid."); 67 | return -1; 68 | } 69 | 70 | // @remark, please get the dts and pts from device, 71 | // we assume there is no B frame, and the fps can guess the fps and dts, 72 | // while the dts and pts must read from encode lib or device. 73 | *dts += 1000 / fps; 74 | *pts = *dts; 75 | 76 | return 0; 77 | } 78 | 79 | int main(int argc, char** argv) 80 | { 81 | printf("publish raw h.264 as rtmp stream to server like FMLE/FFMPEG/Encoder\n"); 82 | printf("SRS(ossrs) client librtmp library.\n"); 83 | printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); 84 | 85 | if (argc <= 3) { 86 | printf("Usage: %s \n", argv[0]); 87 | printf(" h264_raw_file: the h264 raw steam file.\n"); 88 | printf(" rtmp_publish_url: the rtmp publish url.\n"); 89 | printf(" fps: the video average fps, for example, 25.\n"); 90 | printf("For example:\n"); 91 | printf(" %s ./720p.h264.raw rtmp://127.0.0.1:1935/live/livestream 25\n", argv[0]); 92 | printf("Where the file: http://winlinvip.github.io/srs.release/3rdparty/720p.h264.raw\n"); 93 | printf(" See: https://github.com/ossrs/srs/issues/66\n"); 94 | exit(-1); 95 | } 96 | 97 | const char* raw_file = argv[1]; 98 | const char* rtmp_url = argv[2]; 99 | // @remark, the dts and pts if read from device, for instance, the encode lib, 100 | // so we assume the fps is 25, and each h264 frame is 1000ms/25fps=40ms/f. 101 | double fps = atof(argv[3]); 102 | srs_human_trace("raw_file=%s, rtmp_url=%s, fps=%.2f", raw_file, rtmp_url, fps); 103 | 104 | // open file 105 | int raw_fd = open(raw_file, O_RDONLY); 106 | if (raw_fd < 0) { 107 | srs_human_trace("open h264 raw file %s failed.", raw_file); 108 | goto rtmp_destroy; 109 | } 110 | 111 | off_t file_size = lseek(raw_fd, 0, SEEK_END); 112 | if (file_size <= 0) { 113 | srs_human_trace("h264 raw file %s empty.", raw_file); 114 | goto rtmp_destroy; 115 | } 116 | srs_human_trace("read entirely h264 raw file, size=%dKB", (int)(file_size / 1024)); 117 | 118 | char* h264_raw = (char*)malloc(file_size); 119 | if (!h264_raw) { 120 | srs_human_trace("alloc raw buffer failed for file %s.", raw_file); 121 | goto rtmp_destroy; 122 | } 123 | 124 | lseek(raw_fd, 0, SEEK_SET); 125 | ssize_t nb_read = 0; 126 | if ((nb_read = read(raw_fd, h264_raw, file_size)) != file_size) { 127 | srs_human_trace("buffer %s failed, expect=%dKB, actual=%dKB.", 128 | raw_file, (int)(file_size / 1024), (int)(nb_read / 1024)); 129 | goto rtmp_destroy; 130 | } 131 | 132 | // connect rtmp context 133 | //srs_rtmp_t rtmp = srs_rtmp_create(rtmp_url); 134 | srs_rtmp_t rtmp = srs_rtmp_over_quic_create(rtmp_url); 135 | 136 | if (srs_rtmp_handshake(rtmp) != 0) { 137 | srs_human_trace("simple handshake failed."); 138 | goto rtmp_destroy; 139 | } 140 | srs_human_trace("simple handshake success"); 141 | 142 | if (srs_rtmp_connect_app(rtmp) != 0) { 143 | srs_human_trace("connect vhost/app failed."); 144 | goto rtmp_destroy; 145 | } 146 | srs_human_trace("connect vhost/app success"); 147 | 148 | if (srs_rtmp_publish_stream(rtmp) != 0) { 149 | srs_human_trace("publish stream failed."); 150 | goto rtmp_destroy; 151 | } 152 | srs_human_trace("publish stream success"); 153 | 154 | int dts = 0; 155 | int pts = 0; 156 | // @remark, to decode the file. 157 | char* p = h264_raw; 158 | int count = 0; 159 | for (; p < h264_raw + file_size;) { 160 | // @remark, read a frame from file buffer. 161 | char* data = NULL; 162 | int size = 0; 163 | int nb_start_code = 0; 164 | if (read_h264_frame(h264_raw, (int)file_size, &p, &nb_start_code, fps, &data, &size, &dts, &pts) < 0) { 165 | srs_human_trace("read a frame from file buffer failed."); 166 | goto rtmp_destroy; 167 | } 168 | 169 | // send out the h264 packet over RTMP 170 | int ret = srs_h264_write_raw_frames(rtmp, data, size, dts, pts); 171 | if (ret != 0) { 172 | if (srs_h264_is_dvbsp_error(ret)) { 173 | srs_human_trace("ignore drop video error, code=%d", ret); 174 | } else if (srs_h264_is_duplicated_sps_error(ret)) { 175 | srs_human_trace("ignore duplicated sps, code=%d", ret); 176 | } else if (srs_h264_is_duplicated_pps_error(ret)) { 177 | srs_human_trace("ignore duplicated pps, code=%d", ret); 178 | } else { 179 | srs_human_trace("send h264 raw data failed. ret=%d", ret); 180 | goto rtmp_destroy; 181 | } 182 | } 183 | 184 | // 5bits, 7.3.1 NAL unit syntax, 185 | // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. 186 | // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame, 9: AUD, 6: SEI 187 | u_int8_t nut = (char)data[nb_start_code] & 0x1f; 188 | srs_human_trace("sent packet: type=%s, time=%d, size=%d, fps=%.2f, b[%d]=%#x(%s)", 189 | srs_human_flv_tag_type2string(SRS_RTMP_TYPE_VIDEO), dts, size, fps, nb_start_code, (char)data[nb_start_code], 190 | (nut == 7? "SPS":(nut == 8? "PPS":(nut == 5? "I":(nut == 1? "P":(nut == 9? "AUD":(nut == 6? "SEI":"Unknown"))))))); 191 | 192 | // @remark, when use encode device, it not need to sleep. 193 | if (count++ == 9) { 194 | usleep(1000 * 1000 * count / fps); 195 | count = 0; 196 | } 197 | } 198 | srs_human_trace("h264 raw data completed"); 199 | 200 | rtmp_destroy: 201 | srs_rtmp_destroy(rtmp); 202 | close(raw_fd); 203 | free(h264_raw); 204 | 205 | return 0; 206 | } 207 | 208 | -------------------------------------------------------------------------------- /src/trunk/out/srs_librtmp.h: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 SRS(ossrs) 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | 24 | #ifndef SRS_LIB_RTMP_HPP 25 | #define SRS_LIB_RTMP_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | /** 32 | * srs-librtmp is a librtmp like library, 33 | * used to play/publish rtmp stream from/to rtmp server. 34 | * socket: use sync and block socket to connect/recv/send data with server. 35 | * depends: no need other libraries; depends on ssl if use srs_complex_handshake. 36 | * thread-safe: no 37 | */ 38 | 39 | /************************************************************* 40 | ************************************************************** 41 | * Windows SRS-LIBRTMP pre-declare 42 | ************************************************************** 43 | *************************************************************/ 44 | // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 45 | #ifdef _WIN32 46 | // include windows first. 47 | #include 48 | #include 49 | #include 50 | // the type used by this header for windows. 51 | typedef unsigned long long u_int64_t; 52 | typedef unsigned int u_int32_t; 53 | typedef unsigned char u_int8_t; 54 | typedef unsigned short u_int16_t; 55 | typedef int64_t ssize_t; 56 | struct iovec { 57 | void *iov_base; /* Starting address */ 58 | size_t iov_len; /* Number of bytes to transfer */ 59 | }; 60 | #endif 61 | 62 | #include 63 | 64 | #ifdef __cplusplus 65 | extern "C"{ 66 | #endif 67 | 68 | // Log callback. 69 | typedef void(RtmpLogCallback)(void *opaque, int level, const char* log); 70 | 71 | // typedefs 72 | typedef int srs_bool; 73 | 74 | /************************************************************* 75 | ************************************************************** 76 | * srs-librtmp version 77 | ************************************************************** 78 | *************************************************************/ 79 | extern int srs_version_major(); 80 | extern int srs_version_minor(); 81 | extern int srs_version_revision(); 82 | 83 | /************************************************************* 84 | ************************************************************** 85 | * RTMP protocol context 86 | ************************************************************** 87 | *************************************************************/ 88 | // the RTMP handler. 89 | typedef void* srs_rtmp_t; 90 | typedef void* srs_amf0_t; 91 | 92 | extern void srs_rtmp_set_log_callback(RtmpLogCallback callback, void* opaque); 93 | 94 | /** 95 | * create/destroy a rtmp protocol stack. 96 | * @url rtmp url, for example: 97 | * rtmp://localhost/live/livestream 98 | * @remark default timeout to 30s if not set by srs_rtmp_set_timeout. 99 | * 100 | * @return a rtmp handler, or NULL if error occured. 101 | */ 102 | extern srs_rtmp_t srs_rtmp_create(const char* url); 103 | /** 104 | * create/destroy a rtmp over quic protocol stack. 105 | * @url rtmp url, for example: 106 | * rtmp://localhost/live/livestream 107 | * @remark default timeout to 30s if not set by srs_rtmp_set_timeout. 108 | * 109 | * @return a rtmp handler, or NULL if error occured. 110 | */ 111 | extern srs_rtmp_t srs_rtmp_over_quic_create(const char* url); 112 | /** 113 | * create rtmp with url, used for connection specified application. 114 | * @param url the tcUrl, for exmple: 115 | * rtmp://localhost/live 116 | * @remark this is used to create application connection-oriented, 117 | * for example, the bandwidth client used this, no stream specified. 118 | * @remark default timeout to 30s if not set by srs_rtmp_set_timeout. 119 | * 120 | * @return a rtmp handler, or NULL if error occured. 121 | */ 122 | extern srs_rtmp_t srs_rtmp_create2(const char* url); 123 | /** 124 | * set socket timeout 125 | * @param recv_timeout_ms the timeout for receiving messages in ms. 126 | * @param send_timeout_ms the timeout for sending message in ms. 127 | * @remark user can set timeout once srs_rtmp_create/srs_rtmp_create2, 128 | * or before srs_rtmp_handshake or srs_rtmp_dns_resolve to connect to server. 129 | * @remark default timeout to 30s if not set by srs_rtmp_set_timeout. 130 | * 131 | * @return 0, success; otherswise, failed. 132 | */ 133 | extern int srs_rtmp_set_timeout(srs_rtmp_t rtmp, int recv_timeout_ms, int send_timeout_ms); 134 | /** 135 | * close and destroy the rtmp stack. 136 | * @remark, user should never use the rtmp again. 137 | */ 138 | extern void srs_rtmp_destroy(srs_rtmp_t rtmp); 139 | 140 | /************************************************************* 141 | ************************************************************** 142 | * RTMP protocol stack 143 | ************************************************************** 144 | *************************************************************/ 145 | /** 146 | * connect and handshake with server 147 | * category: publish/play 148 | * previous: rtmp-create 149 | * next: connect-app 150 | * 151 | * @return 0, success; otherswise, failed. 152 | */ 153 | /** 154 | * simple handshake specifies in rtmp 1.0, 155 | * not depends on ssl. 156 | */ 157 | /** 158 | * srs_rtmp_handshake equals to invoke: 159 | * srs_rtmp_dns_resolve() 160 | * srs_rtmp_connect_server() 161 | * srs_rtmp_do_simple_handshake() 162 | * user can use these functions if needed. 163 | */ 164 | extern int srs_rtmp_handshake(srs_rtmp_t rtmp); 165 | // parse uri, create socket, resolve host 166 | extern int srs_rtmp_dns_resolve(srs_rtmp_t rtmp); 167 | // connect socket to server 168 | extern int srs_rtmp_connect_server(srs_rtmp_t rtmp); 169 | // disconnect socket to server 170 | extern int srs_rtmp_disconnect_server(srs_rtmp_t rtmp); 171 | // do simple handshake over socket. 172 | extern int srs_rtmp_do_simple_handshake(srs_rtmp_t rtmp); 173 | // do complex handshake over socket. 174 | extern int srs_rtmp_do_complex_handshake(srs_rtmp_t rtmp); 175 | 176 | /** 177 | * set the args of connect packet for rtmp. 178 | * @param args, the extra amf0 object args. 179 | * @remark, all params can be NULL to ignore. 180 | * @remark, user should never free the args for we directly use it. 181 | */ 182 | extern int srs_rtmp_set_connect_args(srs_rtmp_t rtmp, 183 | const char* tcUrl, const char* swfUrl, const char* pageUrl, srs_amf0_t args 184 | ); 185 | 186 | /** 187 | * connect to rtmp vhost/app 188 | * category: publish/play 189 | * previous: handshake 190 | * next: publish or play 191 | * 192 | * @return 0, success; otherswise, failed. 193 | */ 194 | extern int srs_rtmp_connect_app(srs_rtmp_t rtmp); 195 | 196 | /** 197 | * connect to server, get the debug srs info. 198 | * 199 | * SRS debug info: 200 | * @param srs_server_ip, 128bytes, debug info, server ip client connected at. 201 | * @param srs_server, 128bytes, server info. 202 | * @param srs_primary, 128bytes, primary authors. 203 | * @param srs_authors, 128bytes, authors. 204 | * @param srs_version, 32bytes, server version. 205 | * @param srs_id, int, debug info, client id in server log. 206 | * @param srs_pid, int, debug info, server pid in log. 207 | * 208 | * @return 0, success; otherswise, failed. 209 | */ 210 | extern int srs_rtmp_connect_app2(srs_rtmp_t rtmp, 211 | char srs_server_ip[128], char srs_server[128], 212 | char srs_primary[128], char srs_authors[128], 213 | char srs_version[32], int* srs_id, int* srs_pid 214 | ); 215 | 216 | /** 217 | * play a live/vod stream. 218 | * category: play 219 | * previous: connect-app 220 | * next: destroy 221 | * @return 0, success; otherwise, failed. 222 | */ 223 | extern int srs_rtmp_play_stream(srs_rtmp_t rtmp); 224 | 225 | /** 226 | * publish a live stream. 227 | * category: publish 228 | * previous: connect-app 229 | * next: destroy 230 | * @return 0, success; otherwise, failed. 231 | */ 232 | extern int srs_rtmp_publish_stream(srs_rtmp_t rtmp); 233 | 234 | /** 235 | * do bandwidth check with srs server. 236 | * 237 | * bandwidth info: 238 | * @param start_time, output the start time, in ms. 239 | * @param end_time, output the end time, in ms. 240 | * @param play_kbps, output the play/download kbps. 241 | * @param publish_kbps, output the publish/upload kbps. 242 | * @param play_bytes, output the play/download bytes. 243 | * @param publish_bytes, output the publish/upload bytes. 244 | * @param play_duration, output the play/download test duration, in ms. 245 | * @param publish_duration, output the publish/upload test duration, in ms. 246 | * 247 | * @return 0, success; otherswise, failed. 248 | */ 249 | extern int srs_rtmp_bandwidth_check(srs_rtmp_t rtmp, 250 | int64_t* start_time, int64_t* end_time, 251 | int* play_kbps, int* publish_kbps, 252 | int* play_bytes, int* publish_bytes, 253 | int* play_duration, int* publish_duration 254 | ); 255 | 256 | /** 257 | * E.4.1 FLV Tag, page 75 258 | */ 259 | // 8 = audio 260 | #define SRS_RTMP_TYPE_AUDIO 8 261 | // 9 = video 262 | #define SRS_RTMP_TYPE_VIDEO 9 263 | // 18 = script data 264 | #define SRS_RTMP_TYPE_SCRIPT 18 265 | /** 266 | * read a audio/video/script-data packet from rtmp stream. 267 | * @param type, output the packet type, macros: 268 | * SRS_RTMP_TYPE_AUDIO, FlvTagAudio 269 | * SRS_RTMP_TYPE_VIDEO, FlvTagVideo 270 | * SRS_RTMP_TYPE_SCRIPT, FlvTagScript 271 | * otherswise, invalid type. 272 | * @param timestamp, in ms, overflow in 50days 273 | * @param data, the packet data, according to type: 274 | * FlvTagAudio, @see "E.4.2.1 AUDIODATA" 275 | * FlvTagVideo, @see "E.4.3.1 VIDEODATA" 276 | * FlvTagScript, @see "E.4.4.1 SCRIPTDATA" 277 | * @param size, size of packet. 278 | * @return the error code. 0 for success; otherwise, error. 279 | * 280 | * @remark: for read, user must free the data. 281 | * @remark: for write, user should never free the data, even if error. 282 | * @example /trunk/research/librtmp/srs_play.c 283 | * @example /trunk/research/librtmp/srs_publish.c 284 | * 285 | * @return 0, success; otherswise, failed. 286 | */ 287 | extern int srs_rtmp_read_packet(srs_rtmp_t rtmp, 288 | char* type, u_int32_t* timestamp, char** data, int* size 289 | ); 290 | extern int srs_rtmp_write_packet(srs_rtmp_t rtmp, 291 | char type, u_int32_t timestamp, char* data, int size 292 | ); 293 | 294 | /** 295 | * whether type is script data and the data is onMetaData. 296 | */ 297 | extern srs_bool srs_rtmp_is_onMetaData(char type, char* data, int size); 298 | 299 | /************************************************************* 300 | ************************************************************** 301 | * audio raw codec 302 | ************************************************************** 303 | *************************************************************/ 304 | /** 305 | * write an audio raw frame to srs. 306 | * not similar to h.264 video, the audio never aggregated, always 307 | * encoded one frame by one, so this api is used to write a frame. 308 | * 309 | * @param sound_format Format of SoundData. The following values are defined: 310 | * 0 = Linear PCM, platform endian 311 | * 1 = ADPCM 312 | * 2 = MP3 313 | * 3 = Linear PCM, little endian 314 | * 4 = Nellymoser 16 kHz mono 315 | * 5 = Nellymoser 8 kHz mono 316 | * 6 = Nellymoser 317 | * 7 = G.711 A-law logarithmic PCM 318 | * 8 = G.711 mu-law logarithmic PCM 319 | * 9 = reserved 320 | * 10 = AAC 321 | * 11 = Speex 322 | * 14 = MP3 8 kHz 323 | * 15 = Device-specific sound 324 | * Formats 7, 8, 14, and 15 are reserved. 325 | * AAC is supported in Flash Player 9,0,115,0 and higher. 326 | * Speex is supported in Flash Player 10 and higher. 327 | * @param sound_rate Sampling rate. The following values are defined: 328 | * 0 = 5.5 kHz 329 | * 1 = 11 kHz 330 | * 2 = 22 kHz 331 | * 3 = 44 kHz 332 | * @param sound_size Size of each audio sample. This parameter only pertains to 333 | * uncompressed formats. Compressed formats always decode 334 | * to 16 bits internally. 335 | * 0 = 8-bit samples 336 | * 1 = 16-bit samples 337 | * @param sound_type Mono or stereo sound 338 | * 0 = Mono sound 339 | * 1 = Stereo sound 340 | * @param timestamp The timestamp of audio. 341 | * 342 | * @example /trunk/research/librtmp/srs_aac_raw_publish.c 343 | * @example /trunk/research/librtmp/srs_audio_raw_publish.c 344 | * 345 | * @remark for aac, the frame must be in ADTS format. 346 | * @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 75, 1.A.2.2 ADTS 347 | * @remark for aac, only support profile 1-4, AAC main/LC/SSR/LTP, 348 | * @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 23, 1.5.1.1 Audio object type 349 | * 350 | * @see https://github.com/ossrs/srs/issues/212 351 | * @see E.4.2.1 AUDIODATA of video_file_format_spec_v10_1.pdf 352 | * 353 | * @return 0, success; otherswise, failed. 354 | */ 355 | extern int srs_audio_write_raw_frame(srs_rtmp_t rtmp, 356 | char sound_format, char sound_rate, char sound_size, char sound_type, 357 | char* frame, int frame_size, u_int32_t timestamp 358 | ); 359 | 360 | /** 361 | * whether aac raw data is in adts format, 362 | * which bytes sequence matches '1111 1111 1111'B, that is 0xFFF. 363 | * @param aac_raw_data the input aac raw data, a encoded aac frame data. 364 | * @param ac_raw_size the size of aac raw data. 365 | * 366 | * @reamrk used to check whether current frame is in adts format. 367 | * @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 75, 1.A.2.2 ADTS 368 | * @example /trunk/research/librtmp/srs_aac_raw_publish.c 369 | * 370 | * @return 0 false; otherwise, true. 371 | */ 372 | extern srs_bool srs_aac_is_adts(char* aac_raw_data, int ac_raw_size); 373 | 374 | /** 375 | * parse the adts header to get the frame size, 376 | * which bytes sequence matches '1111 1111 1111'B, that is 0xFFF. 377 | * @param aac_raw_data the input aac raw data, a encoded aac frame data. 378 | * @param ac_raw_size the size of aac raw data. 379 | * 380 | * @return failed when <=0 failed; otherwise, ok. 381 | */ 382 | extern int srs_aac_adts_frame_size(char* aac_raw_data, int ac_raw_size); 383 | 384 | /************************************************************* 385 | ************************************************************** 386 | * h264 raw codec 387 | ************************************************************** 388 | *************************************************************/ 389 | /** 390 | * write h.264 raw frame over RTMP to rtmp server. 391 | * @param frames the input h264 raw data, encoded h.264 I/P/B frames data. 392 | * frames can be one or more than one frame, 393 | * each frame prefixed h.264 annexb header, by N[00] 00 00 01, where N>=0, 394 | * for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40) 395 | * about annexb, @see H.264-AVC-ISO_IEC_14496-10.pdf, page 211. 396 | * @param frames_size the size of h264 raw data. 397 | * assert frames_size > 0, at least has 1 bytes header. 398 | * @param dts the dts of h.264 raw data. 399 | * @param pts the pts of h.264 raw data. 400 | * 401 | * @remark, user should free the frames. 402 | * @remark, the tbn of dts/pts is 1/1000 for RTMP, that is, in ms. 403 | * @remark, cts = pts - dts 404 | * @remark, use srs_h264_startswith_annexb to check whether frame is annexb format. 405 | * @example /trunk/research/librtmp/srs_h264_raw_publish.c 406 | * @see https://github.com/ossrs/srs/issues/66 407 | * 408 | * @return 0, success; otherswise, failed. 409 | * for dvbsp error, @see srs_h264_is_dvbsp_error(). 410 | * for duplictated sps error, @see srs_h264_is_duplicated_sps_error(). 411 | * for duplictated pps error, @see srs_h264_is_duplicated_pps_error(). 412 | */ 413 | /** 414 | For the example file: 415 | http://winlinvip.github.io/srs.release/3rdparty/720p.h264.raw 416 | The data sequence is: 417 | // SPS 418 | 000000016742802995A014016E40 419 | // PPS 420 | 0000000168CE3880 421 | // IFrame 422 | 0000000165B8041014C038008B0D0D3A071..... 423 | // PFrame 424 | 0000000141E02041F8CDDC562BBDEFAD2F..... 425 | User can send the SPS+PPS, then each frame: 426 | // SPS+PPS 427 | srs_h264_write_raw_frames('000000016742802995A014016E400000000168CE3880', size, dts, pts) 428 | // IFrame 429 | srs_h264_write_raw_frames('0000000165B8041014C038008B0D0D3A071......', size, dts, pts) 430 | // PFrame 431 | srs_h264_write_raw_frames('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts) 432 | User also can send one by one: 433 | // SPS 434 | srs_h264_write_raw_frames('000000016742802995A014016E4', size, dts, pts) 435 | // PPS 436 | srs_h264_write_raw_frames('00000000168CE3880', size, dts, pts) 437 | // IFrame 438 | srs_h264_write_raw_frames('0000000165B8041014C038008B0D0D3A071......', size, dts, pts) 439 | // PFrame 440 | srs_h264_write_raw_frames('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts) 441 | */ 442 | extern int srs_h264_write_raw_frames(srs_rtmp_t rtmp, 443 | char* frames, int frames_size, u_int32_t dts, u_int32_t pts 444 | ); 445 | /** 446 | * whether error_code is dvbsp(drop video before sps/pps/sequence-header) error. 447 | * 448 | * @see https://github.com/ossrs/srs/issues/203 449 | * @example /trunk/research/librtmp/srs_h264_raw_publish.c 450 | * @remark why drop video? 451 | * some encoder, for example, ipcamera, will send sps/pps before each IFrame, 452 | * so, when error and reconnect the rtmp, the first video is not sps/pps(sequence header), 453 | * this will cause SRS server to disable HLS. 454 | */ 455 | extern srs_bool srs_h264_is_dvbsp_error(int error_code); 456 | /** 457 | * whether error_code is duplicated sps error. 458 | * 459 | * @see https://github.com/ossrs/srs/issues/204 460 | * @example /trunk/research/librtmp/srs_h264_raw_publish.c 461 | */ 462 | extern srs_bool srs_h264_is_duplicated_sps_error(int error_code); 463 | /** 464 | * whether error_code is duplicated pps error. 465 | * 466 | * @see https://github.com/ossrs/srs/issues/204 467 | * @example /trunk/research/librtmp/srs_h264_raw_publish.c 468 | */ 469 | extern srs_bool srs_h264_is_duplicated_pps_error(int error_code); 470 | /** 471 | * whether h264 raw data starts with the annexb, 472 | * which bytes sequence matches N[00] 00 00 01, where N>=0. 473 | * @param h264_raw_data the input h264 raw data, a encoded h.264 I/P/B frame data. 474 | * @paam h264_raw_size the size of h264 raw data. 475 | * @param pnb_start_code output the size of start code, must >=3. 476 | * NULL to ignore. 477 | * 478 | * @reamrk used to check whether current frame is in annexb format. 479 | * @example /trunk/research/librtmp/srs_h264_raw_publish.c 480 | * 481 | * @return 0 false; otherwise, true. 482 | */ 483 | extern srs_bool srs_h264_startswith_annexb( 484 | char* h264_raw_data, int h264_raw_size, 485 | int* pnb_start_code 486 | ); 487 | 488 | /************************************************************* 489 | ************************************************************** 490 | * flv codec 491 | * @example /trunk/research/librtmp/srs_flv_injecter.c 492 | * @example /trunk/research/librtmp/srs_flv_parser.c 493 | * @example /trunk/research/librtmp/srs_ingest_flv.c 494 | * @example /trunk/research/librtmp/srs_ingest_rtmp.c 495 | ************************************************************** 496 | *************************************************************/ 497 | typedef void* srs_flv_t; 498 | /* open flv file for both read/write. */ 499 | extern srs_flv_t srs_flv_open_read(const char* file); 500 | extern srs_flv_t srs_flv_open_write(const char* file); 501 | extern void srs_flv_close(srs_flv_t flv); 502 | /** 503 | * read the flv header. 9bytes header. 504 | * @param header, @see E.2 The FLV header, flv_v10_1.pdf in SRS doc. 505 | * 3bytes, signature, "FLV", 506 | * 1bytes, version, 0x01, 507 | * 1bytes, flags, UB[5] 0, UB[1] audio present, UB[1] 0, UB[1] video present. 508 | * 4bytes, dataoffset, 0x09, The length of this header in bytes 509 | * 510 | * @return 0, success; otherswise, failed. 511 | * @remark, drop the 4bytes zero previous tag size. 512 | */ 513 | extern int srs_flv_read_header(srs_flv_t flv, char header[9]); 514 | /** 515 | * read the flv tag header, 1bytes tag, 3bytes data_size, 516 | * 4bytes time, 3bytes stream id. 517 | * @param ptype, output the type of tag, macros: 518 | * SRS_RTMP_TYPE_AUDIO, FlvTagAudio 519 | * SRS_RTMP_TYPE_VIDEO, FlvTagVideo 520 | * SRS_RTMP_TYPE_SCRIPT, FlvTagScript 521 | * @param pdata_size, output the size of tag data. 522 | * @param ptime, output the time of tag, the dts in ms. 523 | * 524 | * @return 0, success; otherswise, failed. 525 | * @remark, user must ensure the next is a tag, srs never check it. 526 | */ 527 | extern int srs_flv_read_tag_header(srs_flv_t flv, 528 | char* ptype, int32_t* pdata_size, u_int32_t* ptime 529 | ); 530 | /** 531 | * read the tag data. drop the 4bytes previous tag size 532 | * @param data, the data to read, user alloc and free it. 533 | * @param size, the size of data to read, get by srs_flv_read_tag_header(). 534 | * @remark, srs will ignore and drop the 4bytes previous tag size. 535 | */ 536 | extern int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size); 537 | /** 538 | * write the flv header. 9bytes header. 539 | * @param header, @see E.2 The FLV header, flv_v10_1.pdf in SRS doc. 540 | * 3bytes, signature, "FLV", 541 | * 1bytes, version, 0x01, 542 | * 1bytes, flags, UB[5] 0, UB[1] audio present, UB[1] 0, UB[1] video present. 543 | * 4bytes, dataoffset, 0x09, The length of this header in bytes 544 | * 545 | * @return 0, success; otherswise, failed. 546 | * @remark, auto write the 4bytes zero previous tag size. 547 | */ 548 | extern int srs_flv_write_header(srs_flv_t flv, char header[9]); 549 | /** 550 | * write the flv tag to file. 551 | * 552 | * @return 0, success; otherswise, failed. 553 | * @remark, auto write the 4bytes zero previous tag size. 554 | */ 555 | /* write flv tag to file, auto write the 4bytes previous tag size */ 556 | extern int srs_flv_write_tag(srs_flv_t flv, 557 | char type, int32_t time, char* data, int size 558 | ); 559 | /** 560 | * get the tag size, for flv injecter to adjust offset, 561 | * size = tag_header(11B) + data_size + previous_tag(4B) 562 | * @return the size of tag. 563 | */ 564 | extern int srs_flv_size_tag(int data_size); 565 | /* file stream */ 566 | /* file stream tellg to get offset */ 567 | extern int64_t srs_flv_tellg(srs_flv_t flv); 568 | /* seek file stream, offset is form the start of file */ 569 | extern void srs_flv_lseek(srs_flv_t flv, int64_t offset); 570 | /* error code */ 571 | /* whether the error code indicates EOF */ 572 | extern srs_bool srs_flv_is_eof(int error_code); 573 | /* media codec */ 574 | /** 575 | * whether the video body is sequence header 576 | * @param data, the data of tag, read by srs_flv_read_tag_data(). 577 | * @param size, the size of tag, read by srs_flv_read_tag_data(). 578 | */ 579 | extern srs_bool srs_flv_is_sequence_header(char* data, int32_t size); 580 | /** 581 | * whether the video body is keyframe 582 | * @param data, the data of tag, read by srs_flv_read_tag_data(). 583 | * @param size, the size of tag, read by srs_flv_read_tag_data(). 584 | */ 585 | extern srs_bool srs_flv_is_keyframe(char* data, int32_t size); 586 | 587 | /************************************************************* 588 | ************************************************************** 589 | * amf0 codec 590 | * @example /trunk/research/librtmp/srs_ingest_flv.c 591 | * @example /trunk/research/librtmp/srs_ingest_rtmp.c 592 | ************************************************************** 593 | *************************************************************/ 594 | /* the output handler. */ 595 | typedef double srs_amf0_number; 596 | /** 597 | * parse amf0 from data. 598 | * @param nparsed, the parsed size, NULL to ignore. 599 | * @return the parsed amf0 object. NULL for error. 600 | * @remark user must free the parsed or created object by srs_amf0_free. 601 | */ 602 | extern srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed); 603 | extern srs_amf0_t srs_amf0_create_string(const char* value); 604 | extern srs_amf0_t srs_amf0_create_number(srs_amf0_number value); 605 | extern srs_amf0_t srs_amf0_create_ecma_array(); 606 | extern srs_amf0_t srs_amf0_create_strict_array(); 607 | extern srs_amf0_t srs_amf0_create_object(); 608 | extern srs_amf0_t srs_amf0_ecma_array_to_object(srs_amf0_t ecma_arr); 609 | extern void srs_amf0_free(srs_amf0_t amf0); 610 | /* size and to bytes */ 611 | extern int srs_amf0_size(srs_amf0_t amf0); 612 | extern int srs_amf0_serialize(srs_amf0_t amf0, char* data, int size); 613 | /* type detecter */ 614 | extern srs_bool srs_amf0_is_string(srs_amf0_t amf0); 615 | extern srs_bool srs_amf0_is_boolean(srs_amf0_t amf0); 616 | extern srs_bool srs_amf0_is_number(srs_amf0_t amf0); 617 | extern srs_bool srs_amf0_is_null(srs_amf0_t amf0); 618 | extern srs_bool srs_amf0_is_object(srs_amf0_t amf0); 619 | extern srs_bool srs_amf0_is_ecma_array(srs_amf0_t amf0); 620 | extern srs_bool srs_amf0_is_strict_array(srs_amf0_t amf0); 621 | /* value converter */ 622 | extern const char* srs_amf0_to_string(srs_amf0_t amf0); 623 | extern srs_bool srs_amf0_to_boolean(srs_amf0_t amf0); 624 | extern srs_amf0_number srs_amf0_to_number(srs_amf0_t amf0); 625 | /* value setter */ 626 | extern void srs_amf0_set_number(srs_amf0_t amf0, srs_amf0_number value); 627 | /* object value converter */ 628 | extern int srs_amf0_object_property_count(srs_amf0_t amf0); 629 | extern const char* srs_amf0_object_property_name_at(srs_amf0_t amf0, int index); 630 | extern srs_amf0_t srs_amf0_object_property_value_at(srs_amf0_t amf0, int index); 631 | extern srs_amf0_t srs_amf0_object_property(srs_amf0_t amf0, const char* name); 632 | extern void srs_amf0_object_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value); 633 | extern void srs_amf0_object_clear(srs_amf0_t amf0); 634 | /* ecma array value converter */ 635 | extern int srs_amf0_ecma_array_property_count(srs_amf0_t amf0); 636 | extern const char* srs_amf0_ecma_array_property_name_at(srs_amf0_t amf0, int index); 637 | extern srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index); 638 | extern srs_amf0_t srs_amf0_ecma_array_property(srs_amf0_t amf0, const char* name); 639 | extern void srs_amf0_ecma_array_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value); 640 | /* strict array value converter */ 641 | extern int srs_amf0_strict_array_property_count(srs_amf0_t amf0); 642 | extern srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index); 643 | extern void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value); 644 | 645 | /************************************************************* 646 | ************************************************************** 647 | * utilities 648 | ************************************************************** 649 | *************************************************************/ 650 | /** 651 | * get the current system time in ms. 652 | * use gettimeofday() to get system time. 653 | */ 654 | extern int64_t srs_utils_time_ms(); 655 | 656 | /** 657 | * get the send bytes. 658 | */ 659 | extern int64_t srs_utils_send_bytes(srs_rtmp_t rtmp); 660 | 661 | /** 662 | * get the recv bytes. 663 | */ 664 | extern int64_t srs_utils_recv_bytes(srs_rtmp_t rtmp); 665 | 666 | /** 667 | * parse the dts and pts by time in header and data in tag, 668 | * or to parse the RTMP packet by srs_rtmp_read_packet(). 669 | * 670 | * @param time, the timestamp of tag, read by srs_flv_read_tag_header(). 671 | * @param type, the type of tag, read by srs_flv_read_tag_header(). 672 | * @param data, the data of tag, read by srs_flv_read_tag_data(). 673 | * @param size, the size of tag, read by srs_flv_read_tag_header(). 674 | * @param ppts, output the pts in ms, 675 | * 676 | * @return 0, success; otherswise, failed. 677 | * @remark, the dts always equals to @param time. 678 | * @remark, the pts=dts for audio or data. 679 | * @remark, video only support h.264. 680 | */ 681 | extern int srs_utils_parse_timestamp( 682 | u_int32_t time, char type, char* data, int size, 683 | u_int32_t* ppts 684 | ); 685 | 686 | /** 687 | * whether the flv tag specified by param type is ok. 688 | * @return true when tag is video/audio/script-data; otherwise, false. 689 | */ 690 | extern srs_bool srs_utils_flv_tag_is_ok(char type); 691 | extern srs_bool srs_utils_flv_tag_is_audio(char type); 692 | extern srs_bool srs_utils_flv_tag_is_video(char type); 693 | extern srs_bool srs_utils_flv_tag_is_av(char type); 694 | 695 | /** 696 | * get the CodecID of video tag. 697 | * Codec Identifier. The following values are defined: 698 | * 2 = Sorenson H.263 699 | * 3 = Screen video 700 | * 4 = On2 VP6 701 | * 5 = On2 VP6 with alpha channel 702 | * 6 = Screen video version 2 703 | * 7 = AVC 704 | * @return the code id. 0 for error. 705 | */ 706 | extern char srs_utils_flv_video_codec_id(char* data, int size); 707 | 708 | /** 709 | * get the AVCPacketType of video tag. 710 | * The following values are defined: 711 | * 0 = AVC sequence header 712 | * 1 = AVC NALU 713 | * 2 = AVC end of sequence (lower level NALU sequence ender is 714 | * not required or supported) 715 | * @return the avc packet type. -1(0xff) for error. 716 | */ 717 | extern char srs_utils_flv_video_avc_packet_type(char* data, int size); 718 | 719 | /** 720 | * get the FrameType of video tag. 721 | * Type of video frame. The following values are defined: 722 | * 1 = key frame (for AVC, a seekable frame) 723 | * 2 = inter frame (for AVC, a non-seekable frame) 724 | * 3 = disposable inter frame (H.263 only) 725 | * 4 = generated key frame (reserved for server use only) 726 | * 5 = video info/command frame 727 | * @return the frame type. 0 for error. 728 | */ 729 | extern char srs_utils_flv_video_frame_type(char* data, int size); 730 | 731 | /** 732 | * get the SoundFormat of audio tag. 733 | * Format of SoundData. The following values are defined: 734 | * 0 = Linear PCM, platform endian 735 | * 1 = ADPCM 736 | * 2 = MP3 737 | * 3 = Linear PCM, little endian 738 | * 4 = Nellymoser 16 kHz mono 739 | * 5 = Nellymoser 8 kHz mono 740 | * 6 = Nellymoser 741 | * 7 = G.711 A-law logarithmic PCM 742 | * 8 = G.711 mu-law logarithmic PCM 743 | * 9 = reserved 744 | * 10 = AAC 745 | * 11 = Speex 746 | * 14 = MP3 8 kHz 747 | * 15 = Device-specific sound 748 | * Formats 7, 8, 14, and 15 are reserved. 749 | * AAC is supported in Flash Player 9,0,115,0 and higher. 750 | * Speex is supported in Flash Player 10 and higher. 751 | * @return the sound format. -1(0xff) for error. 752 | */ 753 | extern char srs_utils_flv_audio_sound_format(char* data, int size); 754 | 755 | /** 756 | * get the SoundRate of audio tag. 757 | * Sampling rate. The following values are defined: 758 | * 0 = 5.5 kHz 759 | * 1 = 11 kHz 760 | * 2 = 22 kHz 761 | * 3 = 44 kHz 762 | * @return the sound rate. -1(0xff) for error. 763 | */ 764 | extern char srs_utils_flv_audio_sound_rate(char* data, int size); 765 | 766 | /** 767 | * get the SoundSize of audio tag. 768 | * Size of each audio sample. This parameter only pertains to 769 | * uncompressed formats. Compressed formats always decode 770 | * to 16 bits internally. 771 | * 0 = 8-bit samples 772 | * 1 = 16-bit samples 773 | * @return the sound size. -1(0xff) for error. 774 | */ 775 | extern char srs_utils_flv_audio_sound_size(char* data, int size); 776 | 777 | /** 778 | * get the SoundType of audio tag. 779 | * Mono or stereo sound 780 | * 0 = Mono sound 781 | * 1 = Stereo sound 782 | * @return the sound type. -1(0xff) for error. 783 | */ 784 | extern char srs_utils_flv_audio_sound_type(char* data, int size); 785 | 786 | /** 787 | * get the AACPacketType of audio tag. 788 | * The following values are defined: 789 | * 0 = AAC sequence header 790 | * 1 = AAC raw 791 | * @return the aac packet type. -1(0xff) for error. 792 | */ 793 | extern char srs_utils_flv_audio_aac_packet_type(char* data, int size); 794 | 795 | /************************************************************* 796 | ************************************************************** 797 | * human readable print. 798 | ************************************************************** 799 | *************************************************************/ 800 | /** 801 | * human readable print 802 | * @param pdata, output the heap data, NULL to ignore. 803 | * user must use srs_amf0_free_bytes to free it. 804 | * @return return the *pdata for print. NULL to ignore. 805 | */ 806 | extern char* srs_human_amf0_print(srs_amf0_t amf0, char** pdata, int* psize); 807 | /** 808 | * convert the flv tag type to string. 809 | * SRS_RTMP_TYPE_AUDIO to "Audio" 810 | * SRS_RTMP_TYPE_VIDEO to "Video" 811 | * SRS_RTMP_TYPE_SCRIPT to "Data" 812 | * otherwise, "Unknown" 813 | * @remark user never free the return char*, 814 | * it's static shared const string. 815 | */ 816 | extern const char* srs_human_flv_tag_type2string(char type); 817 | 818 | /** 819 | * get the codec id string. 820 | * H.263 = Sorenson H.263 821 | * Screen = Screen video 822 | * VP6 = On2 VP6 823 | * VP6Alpha = On2 VP6 with alpha channel 824 | * Screen2 = Screen video version 2 825 | * H.264 = AVC 826 | * otherwise, "Unknown" 827 | * @remark user never free the return char*, 828 | * it's static shared const string. 829 | */ 830 | extern const char* srs_human_flv_video_codec_id2string(char codec_id); 831 | 832 | /** 833 | * get the avc packet type string. 834 | * SH = AVC sequence header 835 | * Nalu = AVC NALU 836 | * SpsPpsEnd = AVC end of sequence 837 | * otherwise, "Unknown" 838 | * @remark user never free the return char*, 839 | * it's static shared const string. 840 | */ 841 | extern const char* srs_human_flv_video_avc_packet_type2string(char avc_packet_type); 842 | 843 | /** 844 | * get the frame type string. 845 | * I = key frame (for AVC, a seekable frame) 846 | * P/B = inter frame (for AVC, a non-seekable frame) 847 | * DI = disposable inter frame (H.263 only) 848 | * GI = generated key frame (reserved for server use only) 849 | * VI = video info/command frame 850 | * otherwise, "Unknown" 851 | * @remark user never free the return char*, 852 | * it's static shared const string. 853 | */ 854 | extern const char* srs_human_flv_video_frame_type2string(char frame_type); 855 | 856 | /** 857 | * get the SoundFormat string. 858 | * Format of SoundData. The following values are defined: 859 | * LinearPCM = Linear PCM, platform endian 860 | * ADPCM = ADPCM 861 | * MP3 = MP3 862 | * LinearPCMLe = Linear PCM, little endian 863 | * NellymoserKHz16 = Nellymoser 16 kHz mono 864 | * NellymoserKHz8 = Nellymoser 8 kHz mono 865 | * Nellymoser = Nellymoser 866 | * G711APCM = G.711 A-law logarithmic PCM 867 | * G711MuPCM = G.711 mu-law logarithmic PCM 868 | * Reserved = reserved 869 | * AAC = AAC 870 | * Speex = Speex 871 | * MP3KHz8 = MP3 8 kHz 872 | * DeviceSpecific = Device-specific sound 873 | * otherwise, "Unknown" 874 | * @remark user never free the return char*, 875 | * it's static shared const string. 876 | */ 877 | extern const char* srs_human_flv_audio_sound_format2string(char sound_format); 878 | 879 | /** 880 | * get the SoundRate of audio tag. 881 | * Sampling rate. The following values are defined: 882 | * 5.5KHz = 5.5 kHz 883 | * 11KHz = 11 kHz 884 | * 22KHz = 22 kHz 885 | * 44KHz = 44 kHz 886 | * otherwise, "Unknown" 887 | * @remark user never free the return char*, 888 | * it's static shared const string. 889 | */ 890 | extern const char* srs_human_flv_audio_sound_rate2string(char sound_rate); 891 | 892 | /** 893 | * get the SoundSize of audio tag. 894 | * Size of each audio sample. This parameter only pertains to 895 | * uncompressed formats. Compressed formats always decode 896 | * to 16 bits internally. 897 | * 8bit = 8-bit samples 898 | * 16bit = 16-bit samples 899 | * otherwise, "Unknown" 900 | * @remark user never free the return char*, 901 | * it's static shared const string. 902 | */ 903 | extern const char* srs_human_flv_audio_sound_size2string(char sound_size); 904 | 905 | /** 906 | * get the SoundType of audio tag. 907 | * Mono or stereo sound 908 | * Mono = Mono sound 909 | * Stereo = Stereo sound 910 | * otherwise, "Unknown" 911 | * @remark user never free the return char*, 912 | * it's static shared const string. 913 | */ 914 | extern const char* srs_human_flv_audio_sound_type2string(char sound_type); 915 | 916 | /** 917 | * get the AACPacketType of audio tag. 918 | * The following values are defined: 919 | * SH = AAC sequence header 920 | * Raw = AAC raw 921 | * otherwise, "Unknown" 922 | * @remark user never free the return char*, 923 | * it's static shared const string. 924 | */ 925 | extern const char* srs_human_flv_audio_aac_packet_type2string(char aac_packet_type); 926 | 927 | /** 928 | * print the rtmp packet, use srs_human_trace/srs_human_verbose for packet, 929 | * and use srs_human_raw for script data body. 930 | * @return an error code for parse the timetstamp to dts and pts. 931 | */ 932 | extern int srs_human_print_rtmp_packet(char type, u_int32_t timestamp, char* data, int size); 933 | /** 934 | * @param pre_timestamp the previous timestamp in ms to calc the diff. 935 | */ 936 | extern int srs_human_print_rtmp_packet2(char type, u_int32_t timestamp, char* data, int size, u_int32_t pre_timestamp); 937 | /** 938 | * @param pre_now the previous system time in ms to calc the ndiff. 939 | */ 940 | extern int srs_human_print_rtmp_packet3(char type, u_int32_t timestamp, char* data, int size, u_int32_t pre_timestamp, int64_t pre_now); 941 | /** 942 | * @param starttime the rtmpdump starttime in ms. 943 | * @param nb_packets the number of packets received, to calc the packets interval in ms. 944 | */ 945 | extern int srs_human_print_rtmp_packet4(char type, u_int32_t timestamp, char* data, int size, u_int32_t pre_timestamp, int64_t pre_now, int64_t starttime, int64_t nb_packets); 946 | 947 | // log to console, for use srs-librtmp application. 948 | extern const char* srs_human_format_time(); 949 | 950 | // when disabled log, donot compile it. 951 | #ifdef SRS_DISABLE_LOG 952 | #define srs_human_trace(msg, ...) (void)0 953 | #define srs_human_verbose(msg, ...) (void)0 954 | #define srs_human_raw(msg, ...) (void)0 955 | #else 956 | #ifdef ANDROID 957 | #include 958 | #define TAG "SRS" 959 | #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__) 960 | #define srs_human_trace(msg, ...) ALOGE("[%s] ", srs_human_format_time());ALOGE(msg, ##__VA_ARGS__); 961 | #define srs_human_verbose(msg, ...) ALOGE("[%s] ", srs_human_format_time());ALOGE(msg, ##__VA_ARGS__); 962 | #define srs_human_raw(msg, ...) ALOGE(msg, ##__VA_ARGS__) 963 | #else 964 | #define srs_human_trace(msg, ...) printf("[%s] ", srs_human_format_time());printf(msg, ##__VA_ARGS__);printf("\n") 965 | #define srs_human_verbose(msg, ...) printf("[%s] ", srs_human_format_time());printf(msg, ##__VA_ARGS__);printf("\n") 966 | #define srs_human_raw(msg, ...) printf(msg, ##__VA_ARGS__) 967 | #endif 968 | #endif 969 | 970 | /************************************************************* 971 | ************************************************************** 972 | * IO hijack, use your specified io functions. 973 | ************************************************************** 974 | *************************************************************/ 975 | // the void* will convert to your handler for io hijack. 976 | typedef void* srs_hijack_io_t; 977 | #ifdef SRS_HIJACK_IO 978 | #ifndef _WIN32 979 | // for iovec. 980 | #include 981 | #endif 982 | /** 983 | * get the hijack io object in rtmp protocol sdk. 984 | * @remark, user should never provides this method, srs-librtmp provides it. 985 | */ 986 | extern srs_hijack_io_t srs_hijack_io_get(srs_rtmp_t rtmp); 987 | #endif 988 | // define the following macro and functions in your module to hijack the io. 989 | // the example @see https://github.com/winlinvip/st-load 990 | // which use librtmp but use its own io(use st also). 991 | #ifdef SRS_HIJACK_IO 992 | /** 993 | * create hijack. 994 | * @return NULL for error; otherwise, ok. 995 | */ 996 | extern srs_hijack_io_t srs_hijack_io_create(); 997 | /** 998 | * destroy the context, user must close the socket. 999 | */ 1000 | extern void srs_hijack_io_destroy(srs_hijack_io_t ctx); 1001 | /** 1002 | * create socket, not connect yet. 1003 | * @return 0, success; otherswise, failed. 1004 | */ 1005 | extern int srs_hijack_io_create_socket(srs_hijack_io_t ctx); 1006 | /** 1007 | * connect socket at server_ip:port. 1008 | * @return 0, success; otherswise, failed. 1009 | */ 1010 | extern int srs_hijack_io_connect(srs_hijack_io_t ctx, const char* server_ip, int port); 1011 | /** 1012 | * read from socket. 1013 | * @return 0, success; otherswise, failed. 1014 | */ 1015 | extern int srs_hijack_io_read(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread); 1016 | /** 1017 | * set the socket recv timeout. 1018 | * @return 0, success; otherswise, failed. 1019 | */ 1020 | extern int srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t timeout_us); 1021 | /** 1022 | * get the socket recv timeout. 1023 | * @return 0, success; otherswise, failed. 1024 | */ 1025 | extern int64_t srs_hijack_io_get_recv_timeout(srs_hijack_io_t ctx); 1026 | /** 1027 | * get the socket recv bytes. 1028 | * @return 0, success; otherswise, failed. 1029 | */ 1030 | extern int64_t srs_hijack_io_get_recv_bytes(srs_hijack_io_t ctx); 1031 | /** 1032 | * set the socket send timeout. 1033 | * @return 0, success; otherswise, failed. 1034 | */ 1035 | extern int srs_hijack_io_set_send_timeout(srs_hijack_io_t ctx, int64_t timeout_us); 1036 | /** 1037 | * get the socket send timeout. 1038 | * @return 0, success; otherswise, failed. 1039 | */ 1040 | extern int64_t srs_hijack_io_get_send_timeout(srs_hijack_io_t ctx); 1041 | /** 1042 | * get the socket send bytes. 1043 | * @return 0, success; otherswise, failed. 1044 | */ 1045 | extern int64_t srs_hijack_io_get_send_bytes(srs_hijack_io_t ctx); 1046 | /** 1047 | * writev of socket. 1048 | * @return 0, success; otherswise, failed. 1049 | */ 1050 | extern int srs_hijack_io_writev(srs_hijack_io_t ctx, const iovec *iov, int iov_size, ssize_t* nwrite); 1051 | /** 1052 | * whether the timeout is never timeout. 1053 | * @return 0, success; otherswise, failed. 1054 | */ 1055 | extern bool srs_hijack_io_is_never_timeout(srs_hijack_io_t ctx, int64_t timeout_us); 1056 | /** 1057 | * read fully, fill the buf exactly size bytes. 1058 | * @return 0, success; otherswise, failed. 1059 | */ 1060 | extern int srs_hijack_io_read_fully(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread); 1061 | /** 1062 | * write bytes to socket. 1063 | * @return 0, success; otherswise, failed. 1064 | */ 1065 | extern int srs_hijack_io_write(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nwrite); 1066 | #endif 1067 | 1068 | /************************************************************* 1069 | ************************************************************** 1070 | * Windows SRS-LIBRTMP solution 1071 | ************************************************************** 1072 | *************************************************************/ 1073 | // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 1074 | #ifdef _WIN32 1075 | // for time. 1076 | #ifndef _CRT_SECURE_NO_WARNINGS 1077 | #define _CRT_SECURE_NO_WARNINGS 1078 | #endif 1079 | #include 1080 | int gettimeofday(struct timeval* tv, struct timezone* tz); 1081 | #define PRId64 "lld" 1082 | 1083 | // for inet helpers. 1084 | typedef int socklen_t; 1085 | const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); 1086 | 1087 | // for mkdir(). 1088 | #include 1089 | 1090 | // for open(). 1091 | typedef int mode_t; 1092 | #define S_IRUSR 0 1093 | #define S_IWUSR 0 1094 | #define S_IXUSR 0 1095 | #define S_IRGRP 0 1096 | #define S_IWGRP 0 1097 | #define S_IXGRP 0 1098 | #define S_IROTH 0 1099 | #define S_IXOTH 0 1100 | 1101 | // for file seek. 1102 | #include 1103 | #include 1104 | #define open _open 1105 | #define close _close 1106 | #define lseek _lseek 1107 | #define write _write 1108 | #define read _read 1109 | 1110 | // for pid. 1111 | typedef int pid_t; 1112 | pid_t getpid(void); 1113 | 1114 | // for socket. 1115 | ssize_t writev(int fd, const struct iovec *iov, int iovcnt); 1116 | typedef int64_t useconds_t; 1117 | int usleep(useconds_t usec); 1118 | int socket_setup(); 1119 | int socket_cleanup(); 1120 | 1121 | // others. 1122 | //#define snprintf _snprintf 1123 | #endif 1124 | 1125 | #ifdef __cplusplus 1126 | } 1127 | #endif 1128 | 1129 | #endif 1130 | 1131 | --------------------------------------------------------------------------------