├── .gitignore ├── README.md └── jni ├── Android.mk ├── Application.mk └── libsrs_rtmp ├── srs_core.cpp ├── srs_core.hpp ├── srs_core_autofree.cpp ├── srs_core_autofree.hpp ├── srs_core_performance.cpp ├── srs_core_performance.hpp ├── srs_kernel_buffer.cpp ├── srs_kernel_buffer.hpp ├── srs_kernel_codec.cpp ├── srs_kernel_codec.hpp ├── srs_kernel_consts.cpp ├── srs_kernel_consts.hpp ├── srs_kernel_error.cpp ├── srs_kernel_error.hpp ├── srs_kernel_log.cpp ├── srs_kernel_log.hpp ├── srs_kernel_stream.cpp ├── srs_kernel_stream.hpp ├── srs_kernel_utility.cpp ├── srs_kernel_utility.hpp ├── srs_lib_bandwidth.cpp ├── srs_lib_bandwidth.hpp ├── srs_lib_simple_socket.cpp ├── srs_lib_simple_socket.hpp ├── srs_librtmp.cpp ├── srs_librtmp.hpp ├── srs_raw_avc.cpp ├── srs_raw_avc.hpp ├── srs_rtmp_amf0.cpp ├── srs_rtmp_amf0.hpp ├── srs_rtmp_buffer.cpp ├── srs_rtmp_buffer.hpp ├── srs_rtmp_handshake.cpp ├── srs_rtmp_handshake.hpp ├── srs_rtmp_io.cpp ├── srs_rtmp_io.hpp ├── srs_rtmp_msg_array.cpp ├── srs_rtmp_msg_array.hpp ├── srs_rtmp_sdk.cpp ├── srs_rtmp_sdk.hpp ├── srs_rtmp_stack.cpp ├── srs_rtmp_stack.hpp ├── srs_rtmp_utility.cpp └── srs_rtmp_utility.hpp /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | 15 | # Gradle files 16 | .gradle/ 17 | build/ 18 | 19 | # Local configuration file (sdk path, etc) 20 | local.properties 21 | 22 | # Proguard folder generated by Eclipse 23 | proguard/ 24 | obj/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | libsrs_rtmp-android 2 | =================== 3 | 4 | Build libsrs_rtmp for android 5 | -------------------------------------------------------------------------------- /jni/Android.mk: -------------------------------------------------------------------------------- 1 | 2 | LOCAL_PATH := $(call my-dir) 3 | 4 | common_SRC_FILES := \ 5 | libsrs_rtmp/srs_core.cpp \ 6 | libsrs_rtmp/srs_core_autofree.cpp \ 7 | libsrs_rtmp/srs_core_performance.cpp \ 8 | libsrs_rtmp/srs_kernel_buffer.cpp \ 9 | libsrs_rtmp/srs_kernel_codec.cpp \ 10 | libsrs_rtmp/srs_kernel_consts.cpp \ 11 | libsrs_rtmp/srs_kernel_error.cpp \ 12 | libsrs_rtmp/srs_kernel_log.cpp \ 13 | libsrs_rtmp/srs_kernel_stream.cpp \ 14 | libsrs_rtmp/srs_kernel_utility.cpp \ 15 | libsrs_rtmp/srs_librtmp.cpp \ 16 | libsrs_rtmp/srs_lib_bandwidth.cpp \ 17 | libsrs_rtmp/srs_lib_simple_socket.cpp \ 18 | libsrs_rtmp/srs_raw_avc.cpp \ 19 | libsrs_rtmp/srs_rtmp_amf0.cpp \ 20 | libsrs_rtmp/srs_rtmp_buffer.cpp \ 21 | libsrs_rtmp/srs_rtmp_handshake.cpp \ 22 | libsrs_rtmp/srs_rtmp_io.cpp \ 23 | libsrs_rtmp/srs_rtmp_msg_array.cpp \ 24 | libsrs_rtmp/srs_rtmp_sdk.cpp \ 25 | libsrs_rtmp/srs_rtmp_stack.cpp \ 26 | libsrs_rtmp/srs_rtmp_utility.cpp 27 | 28 | common_C_INCLUDES = $(LOCAL_PATH)/libsrs_rtmp 29 | 30 | include $(CLEAR_VARS) 31 | LOCAL_MODULE := libsrs_rtmp 32 | LOCAL_SRC_FILES := $(common_SRC_FILES) 33 | LOCAL_CFLAGS := $(common_CFLAGS) 34 | LOCAL_CXXFLAGS := $(LOCAL_CXXFLAGS) -frtti 35 | LOCAL_C_INCLUDES := $(common_C_INCLUDES) 36 | 37 | include $(BUILD_STATIC_LIBRARY) -------------------------------------------------------------------------------- /jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_ABI := all 2 | APP_STL := gnustl_static -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_core.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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 | #include 25 | 26 | 27 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_core.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_CORE_HPP 25 | #define SRS_CORE_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | // current release version 32 | #define VERSION_MAJOR 2 33 | #define VERSION_MINOR 0 34 | #define VERSION_REVISION 161 35 | 36 | // server info. 37 | #define RTMP_SIG_SRS_KEY "SRS" 38 | #define RTMP_SIG_SRS_CODE "ZhouGuowen" 39 | #define RTMP_SIG_SRS_ROLE "origin/edge server" 40 | #define RTMP_SIG_SRS_NAME RTMP_SIG_SRS_KEY"(Simple RTMP Server)" 41 | #define RTMP_SIG_SRS_URL_SHORT "github.com/winlinvip/simple-rtmp-server" 42 | #define RTMP_SIG_SRS_URL "https://"RTMP_SIG_SRS_URL_SHORT 43 | #define RTMP_SIG_SRS_WEB "http://blog.csdn.net/win_lin" 44 | #define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com" 45 | #define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)" 46 | #define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2015 winlin" 47 | #define RTMP_SIG_SRS_PRIMARY "winlin" 48 | #define RTMP_SIG_SRS_AUTHROS "wenjie.zhao" 49 | #define RTMP_SIG_SRS_CONTRIBUTORS_URL RTMP_SIG_SRS_URL"/blob/master/AUTHORS.txt" 50 | #define RTMP_SIG_SRS_HANDSHAKE RTMP_SIG_SRS_KEY"("RTMP_SIG_SRS_VERSION")" 51 | #define RTMP_SIG_SRS_RELEASE RTMP_SIG_SRS_URL"/tree/1.0release" 52 | #define RTMP_SIG_SRS_ISSUES(id) RTMP_SIG_SRS_URL"/issues/"#id 53 | #define RTMP_SIG_SRS_VERSION SRS_XSTR(VERSION_MAJOR)"."SRS_XSTR(VERSION_MINOR)"."SRS_XSTR(VERSION_REVISION) 54 | #define RTMP_SIG_SRS_SERVER RTMP_SIG_SRS_KEY"/"RTMP_SIG_SRS_VERSION"("RTMP_SIG_SRS_CODE")" 55 | 56 | // stable major version 57 | #define VERSION_STABLE 1 58 | #define VERSION_STABLE_BRANCH SRS_XSTR(VERSION_STABLE)".0release" 59 | 60 | // internal macros, covert macro values to str, 61 | // see: read https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification 62 | #define SRS_XSTR(v) SRS_INTERNAL_STR(v) 63 | #define SRS_INTERNAL_STR(v) #v 64 | 65 | /** 66 | * the core provides the common defined macros, utilities, 67 | * user must include the srs_core.hpp before any header, or maybe 68 | * build failed. 69 | */ 70 | 71 | // for 32bit os, 2G big file limit for unistd io, 72 | // ie. read/write/lseek to use 64bits size for huge file. 73 | #ifndef _FILE_OFFSET_BITS 74 | #define _FILE_OFFSET_BITS 64 75 | #endif 76 | 77 | // for int64_t print using PRId64 format. 78 | #ifndef __STDC_FORMAT_MACROS 79 | #define __STDC_FORMAT_MACROS 80 | #endif 81 | 82 | // for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213 83 | #ifndef _WIN32 84 | #include 85 | #endif 86 | 87 | #include 88 | #define srs_assert(expression) assert(expression) 89 | 90 | #include 91 | #include 92 | 93 | // generated by configure. 94 | //#include 95 | // important performance options. 96 | #include 97 | 98 | // free the p and set to NULL. 99 | // p must be a T*. 100 | #define srs_freep(p) \ 101 | if (p) { \ 102 | delete p; \ 103 | p = NULL; \ 104 | } \ 105 | (void)0 106 | // sometimes, the freepa is useless, 107 | // it's recomments to free each elem explicit. 108 | // so we remove the srs_freepa utility. 109 | 110 | /** 111 | * disable copy constructor of class, 112 | * to avoid the memory leak or corrupt by copy instance. 113 | */ 114 | #define disable_default_copy(className)\ 115 | private:\ 116 | /** \ 117 | * disable the copy constructor and operator=, donot allow directly copy. \ 118 | */ \ 119 | className(const className&); \ 120 | className& operator= (const className&) 121 | 122 | #endif 123 | 124 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_core_autofree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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 | #include 25 | 26 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_core_autofree.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_CORE_AUTO_FREE_HPP 25 | #define SRS_CORE_AUTO_FREE_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | /** 34 | * auto free the instance in the current scope, for instance, MyClass* ptr, 35 | * which is a ptr and this class will: 36 | * 1. free the ptr. 37 | * 2. set ptr to NULL. 38 | * Usage: 39 | * MyClass* po = new MyClass(); 40 | * // ...... use po 41 | * SrsAutoFree(MyClass, po); 42 | */ 43 | #define SrsAutoFree(className, instance) \ 44 | impl__SrsAutoFree _auto_free_##instance(&instance) 45 | template 46 | class impl__SrsAutoFree 47 | { 48 | private: 49 | T** ptr; 50 | public: 51 | /** 52 | * auto delete the ptr. 53 | */ 54 | impl__SrsAutoFree(T** _ptr) { 55 | ptr = _ptr; 56 | } 57 | 58 | virtual ~impl__SrsAutoFree() { 59 | if (ptr == NULL || *ptr == NULL) { 60 | return; 61 | } 62 | 63 | delete *ptr; 64 | 65 | *ptr = NULL; 66 | } 67 | }; 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_core_performance.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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 | #include 25 | 26 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_core_performance.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_CORE_PERFORMANCE_HPP 25 | #define SRS_CORE_PERFORMANCE_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | /** 34 | * this file defines the perfromance options. 35 | */ 36 | 37 | /** 38 | * to improve read performance, merge some packets then read, 39 | * when it on and read small bytes, we sleep to wait more data., 40 | * that is, we merge some data to read together. 41 | * @see SrsConfig::get_mr_enabled() 42 | * @see SrsConfig::get_mr_sleep_ms() 43 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 44 | * @example, for the default settings, this algorithm will use: 45 | * that is, when got nread bytes smaller than 4KB, sleep(780ms). 46 | */ 47 | /** 48 | * https://github.com/winlinvip/simple-rtmp-server/issues/241#issuecomment-65554690 49 | * The merged read algorithm is ok and can be simplified for: 50 | * 1. Suppose the client network is ok. All algorithm go wrong when netowrk is not ok. 51 | * 2. Suppose the client send each packet one by one. Although send some together, it's same. 52 | * 3. SRS MR algorithm will read all data then sleep. 53 | * So, the MR algorithm is: 54 | * while true: 55 | * read all data from socket. 56 | * sleep a while 57 | * For example, sleep 120ms. Then there is, and always 120ms data in buffer. 58 | * That is, the latency is 120ms(the sleep time). 59 | */ 60 | #define SRS_PERF_MERGED_READ 61 | // the default config of mr. 62 | #define SRS_PERF_MR_ENABLED false 63 | #define SRS_PERF_MR_SLEEP 350 64 | 65 | /** 66 | * the MW(merged-write) send cache time in ms. 67 | * the default value, user can override it in config. 68 | * to improve send performance, cache msgs and send in a time. 69 | * for example, cache 500ms videos and audios, then convert all these 70 | * msgs to iovecs, finally use writev to send. 71 | * @remark this largely improve performance, from 3.5k+ to 7.5k+. 72 | * the latency+ when cache+. 73 | * @remark the socket send buffer default to 185KB, it large enough. 74 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/194 75 | * @see SrsConfig::get_mw_sleep_ms() 76 | * @remark the mw sleep and msgs to send, maybe: 77 | * mw_sleep msgs iovs 78 | * 350 43 86 79 | * 400 44 88 80 | * 500 46 92 81 | * 600 46 92 82 | * 700 82 164 83 | * 800 81 162 84 | * 900 80 160 85 | * 1000 88 176 86 | * 1100 91 182 87 | * 1200 89 178 88 | * 1300 119 238 89 | * 1400 120 240 90 | * 1500 119 238 91 | * 1600 131 262 92 | * 1700 131 262 93 | * 1800 133 266 94 | * 1900 141 282 95 | * 2000 150 300 96 | */ 97 | // the default config of mw. 98 | #define SRS_PERF_MW_SLEEP 350 99 | /** 100 | * how many msgs can be send entirely. 101 | * for play clients to get msgs then totally send out. 102 | * for the mw sleep set to 1800, the msgs is about 133. 103 | * @remark, recomment to 128. 104 | */ 105 | #define SRS_PERF_MW_MSGS 128 106 | 107 | /** 108 | * whether set the socket send buffer size. 109 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/251 110 | */ 111 | #define SRS_PERF_MW_SO_SNDBUF 112 | 113 | /** 114 | * whether set the socket recv buffer size. 115 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/251 116 | */ 117 | #undef SRS_PERF_MW_SO_RCVBUF 118 | /** 119 | * whether enable the fast vector for qeueue. 120 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/251 121 | */ 122 | #define SRS_PERF_QUEUE_FAST_VECTOR 123 | /** 124 | * whether use cond wait to send messages. 125 | * @remark this improve performance for large connectios. 126 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/251 127 | */ 128 | #define SRS_PERF_QUEUE_COND_WAIT 129 | #ifdef SRS_PERF_QUEUE_COND_WAIT 130 | #define SRS_PERF_MW_MIN_MSGS 8 131 | #endif 132 | /** 133 | * the default value of vhost for 134 | * SRS whether use the min latency mode. 135 | * for min latence mode: 136 | * 1. disable the mr for vhost. 137 | * 2. use timeout for cond wait for consumer queue. 138 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/257 139 | */ 140 | #define SRS_PERF_MIN_LATENCY_ENABLED false 141 | 142 | /** 143 | * how many chunk stream to cache, [0, N]. 144 | * to imporove about 10% performance when chunk size small, and 5% for large chunk. 145 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/249 146 | * @remark 0 to disable the chunk stream cache. 147 | */ 148 | #define SRS_PERF_CHUNK_STREAM_CACHE 16 149 | 150 | /** 151 | * the gop cache and play cache queue. 152 | */ 153 | // whether gop cache is on. 154 | #define SRS_PERF_GOP_CACHE true 155 | // in seconds, the live queue length. 156 | #define SRS_PERF_PLAY_QUEUE 30 157 | 158 | /** 159 | * whether always use complex send algorithm. 160 | * for some network does not support the complex send, 161 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/320 162 | */ 163 | //#undef SRS_PERF_COMPLEX_SEND 164 | #define SRS_PERF_COMPLEX_SEND 165 | /** 166 | * whether enable the TCP_NODELAY 167 | * user maybe need send small tcp packet for some network. 168 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/320 169 | */ 170 | //#define SRS_PERF_TCP_NODELAY 171 | #undef SRS_PERF_TCP_NODELAY 172 | /** 173 | * set the socket send buffer, 174 | * to force the server to send smaller tcp packet. 175 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/320 176 | * @remark undef it to auto calc it by merged write sleep ms. 177 | * @remark only apply it when SRS_PERF_MW_SO_RCVBUF is defined. 178 | */ 179 | #ifdef SRS_PERF_MW_SO_SNDBUF 180 | //#define SRS_PERF_SO_SNDBUF_SIZE 1024 181 | #undef SRS_PERF_SO_SNDBUF_SIZE 182 | #endif 183 | 184 | #endif 185 | 186 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_kernel_buffer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | SrsSimpleBuffer::SrsSimpleBuffer() 32 | { 33 | } 34 | 35 | SrsSimpleBuffer::~SrsSimpleBuffer() 36 | { 37 | } 38 | 39 | int SrsSimpleBuffer::length() 40 | { 41 | int len = (int)data.size(); 42 | srs_assert(len >= 0); 43 | return len; 44 | } 45 | 46 | char* SrsSimpleBuffer::bytes() 47 | { 48 | return (length() == 0)? NULL : &data.at(0); 49 | } 50 | 51 | void SrsSimpleBuffer::erase(int size) 52 | { 53 | if (size <= 0) { 54 | return; 55 | } 56 | 57 | if (size >= length()) { 58 | data.clear(); 59 | return; 60 | } 61 | 62 | data.erase(data.begin(), data.begin() + size); 63 | } 64 | 65 | void SrsSimpleBuffer::append(const char* bytes, int size) 66 | { 67 | srs_assert(size > 0); 68 | 69 | data.insert(data.end(), bytes, bytes + size); 70 | } 71 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_kernel_buffer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_KERNEL_BUFFER_HPP 25 | #define SRS_KERNEL_BUFFER_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | #include 34 | 35 | /** 36 | * the simple buffer use vector to append bytes, 37 | * it's for hls and http, and need to be refined in future. 38 | */ 39 | class SrsSimpleBuffer 40 | { 41 | private: 42 | std::vector data; 43 | public: 44 | SrsSimpleBuffer(); 45 | virtual ~SrsSimpleBuffer(); 46 | public: 47 | /** 48 | * get the length of buffer. empty if zero. 49 | * @remark assert length() is not negative. 50 | */ 51 | virtual int length(); 52 | /** 53 | * get the buffer bytes. 54 | * @return the bytes, NULL if empty. 55 | */ 56 | virtual char* bytes(); 57 | /** 58 | * erase size of bytes from begin. 59 | * @param size to erase size of bytes. 60 | * clear if size greater than or equals to length() 61 | * @remark ignore size is not positive. 62 | */ 63 | virtual void erase(int size); 64 | /** 65 | * append specified bytes to buffer. 66 | * @param size the size of bytes 67 | * @remark assert size is positive. 68 | */ 69 | virtual void append(const char* bytes, int size); 70 | }; 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_kernel_consts.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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 | #include 25 | 26 | 27 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_kernel_consts.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_KERNEL_CONSTS_HPP 25 | #define SRS_KERNEL_CONSTS_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | /////////////////////////////////////////////////////////// 34 | /////////////////////////////////////////////////////////// 35 | /////////////////////////////////////////////////////////// 36 | /////////////////////////////////////////////////////////// 37 | /////////////////////////////////////////////////////////// 38 | /////////////////////////////////////////////////////////// 39 | 40 | /////////////////////////////////////////////////////////// 41 | // RTMP consts values 42 | /////////////////////////////////////////////////////////// 43 | // default vhost of rtmp 44 | #define SRS_CONSTS_RTMP_DEFAULT_VHOST "__defaultVhost__" 45 | // default port of rtmp 46 | #define SRS_CONSTS_RTMP_DEFAULT_PORT "1935" 47 | 48 | // the default chunk size for system. 49 | #define SRS_CONSTS_RTMP_SRS_CHUNK_SIZE 60000 50 | // 6. Chunking, RTMP protocol default chunk size. 51 | #define SRS_CONSTS_RTMP_PROTOCOL_CHUNK_SIZE 128 52 | 53 | /** 54 | * 6. Chunking 55 | * The chunk size is configurable. It can be set using a control 56 | * message(Set Chunk Size) as described in section 7.1. The maximum 57 | * chunk size can be 65536 bytes and minimum 128 bytes. Larger values 58 | * reduce CPU usage, but also commit to larger writes that can delay 59 | * other content on lower bandwidth connections. Smaller chunks are not 60 | * good for high-bit rate streaming. Chunk size is maintained 61 | * independently for each direction. 62 | */ 63 | #define SRS_CONSTS_RTMP_MIN_CHUNK_SIZE 128 64 | #define SRS_CONSTS_RTMP_MAX_CHUNK_SIZE 65536 65 | 66 | 67 | // the following is the timeout for rtmp protocol, 68 | // to avoid death connection. 69 | 70 | // the timeout to send data to client, 71 | // if timeout, close the connection. 72 | #define SRS_CONSTS_RTMP_SEND_TIMEOUT_US (int64_t)(30*1000*1000LL) 73 | 74 | // the timeout to wait client data, 75 | // if timeout, close the connection. 76 | #define SRS_CONSTS_RTMP_RECV_TIMEOUT_US (int64_t)(30*1000*1000LL) 77 | 78 | // the timeout to wait for client control message, 79 | // if timeout, we generally ignore and send the data to client, 80 | // generally, it's the pulse time for data seding. 81 | // @remark, recomment to 500ms. 82 | #define SRS_CONSTS_RTMP_PULSE_TIMEOUT_US (int64_t)(500*1000LL) 83 | 84 | /** 85 | * max rtmp header size: 86 | * 1bytes basic header, 87 | * 11bytes message header, 88 | * 4bytes timestamp header, 89 | * that is, 1+11+4=16bytes. 90 | */ 91 | #define SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE 16 92 | /** 93 | * max rtmp header size: 94 | * 1bytes basic header, 95 | * 4bytes timestamp header, 96 | * that is, 1+4=5bytes. 97 | */ 98 | // always use fmt0 as cache. 99 | #define SRS_CONSTS_RTMP_MAX_FMT3_HEADER_SIZE 5 100 | 101 | /** 102 | * for performance issue, 103 | * the iovs cache, @see https://github.com/winlinvip/simple-rtmp-server/issues/194 104 | * iovs cache for multiple messages for each connections. 105 | * suppose the chunk size is 64k, each message send in a chunk which needs only 2 iovec, 106 | * so the iovs max should be (SRS_PERF_MW_MSGS * 2) 107 | * 108 | * @remark, SRS will realloc when the iovs not enough. 109 | */ 110 | #define SRS_CONSTS_IOVS_MAX (SRS_PERF_MW_MSGS * 2) 111 | /** 112 | * for performance issue, 113 | * the c0c3 cache, @see https://github.com/winlinvip/simple-rtmp-server/issues/194 114 | * c0c3 cache for multiple messages for each connections. 115 | * each c0 <= 16byes, suppose the chunk size is 64k, 116 | * each message send in a chunk which needs only a c0 header, 117 | * so the c0c3 cache should be (SRS_PERF_MW_MSGS * 16) 118 | * 119 | * @remark, SRS will try another loop when c0c3 cache dry, for we cannot realloc it. 120 | * so we use larger c0c3 cache, that is (SRS_PERF_MW_MSGS * 32) 121 | */ 122 | #define SRS_CONSTS_C0C3_HEADERS_MAX (SRS_PERF_MW_MSGS * 32) 123 | 124 | /////////////////////////////////////////////////////////// 125 | /////////////////////////////////////////////////////////// 126 | /////////////////////////////////////////////////////////// 127 | /////////////////////////////////////////////////////////// 128 | /////////////////////////////////////////////////////////// 129 | /////////////////////////////////////////////////////////// 130 | 131 | /////////////////////////////////////////////////////////// 132 | // SRS consts values 133 | /////////////////////////////////////////////////////////// 134 | #define SRS_CONSTS_NULL_FILE "/dev/null" 135 | #define SRS_CONSTS_LOCALHOST "127.0.0.1" 136 | 137 | /////////////////////////////////////////////////////////// 138 | /////////////////////////////////////////////////////////// 139 | /////////////////////////////////////////////////////////// 140 | /////////////////////////////////////////////////////////// 141 | /////////////////////////////////////////////////////////// 142 | /////////////////////////////////////////////////////////// 143 | 144 | /////////////////////////////////////////////////////////// 145 | // log consts values 146 | /////////////////////////////////////////////////////////// 147 | // downloading speed-up, play to edge, ingest from origin 148 | #define SRS_CONSTS_LOG_EDGE_PLAY "EIG" 149 | // uploading speed-up, publish to edge, foward to origin 150 | #define SRS_CONSTS_LOG_EDGE_PUBLISH "EFW" 151 | // edge/origin forwarder. 152 | #define SRS_CONSTS_LOG_FOWARDER "FWR" 153 | // play stream on edge/origin. 154 | #define SRS_CONSTS_LOG_PLAY "PLA" 155 | // client publish to edge/origin 156 | #define SRS_CONSTS_LOG_CLIENT_PUBLISH "CPB" 157 | // web/flash publish to edge/origin 158 | #define SRS_CONSTS_LOG_WEB_PUBLISH "WPB" 159 | // ingester for edge(play)/origin 160 | #define SRS_CONSTS_LOG_INGESTER "IGS" 161 | // hls log id. 162 | #define SRS_CONSTS_LOG_HLS "HLS" 163 | // encoder log id. 164 | #define SRS_CONSTS_LOG_ENCODER "ENC" 165 | // http stream log id. 166 | #define SRS_CONSTS_LOG_HTTP_STREAM "HTS" 167 | // http stream cache log id. 168 | #define SRS_CONSTS_LOG_HTTP_STREAM_CACHE "HTC" 169 | // stream caster log id. 170 | #define SRS_CONSTS_LOG_STREAM_CASTER "SCS" 171 | 172 | /////////////////////////////////////////////////////////// 173 | /////////////////////////////////////////////////////////// 174 | /////////////////////////////////////////////////////////// 175 | /////////////////////////////////////////////////////////// 176 | /////////////////////////////////////////////////////////// 177 | /////////////////////////////////////////////////////////// 178 | 179 | /////////////////////////////////////////////////////////// 180 | // RTMP consts values 181 | /////////////////////////////////////////////////////////// 182 | #define SRS_CONSTS_RTMP_SET_DATAFRAME "@setDataFrame" 183 | #define SRS_CONSTS_RTMP_ON_METADATA "onMetaData" 184 | 185 | /////////////////////////////////////////////////////////// 186 | // HTTP/HLS consts values 187 | /////////////////////////////////////////////////////////// 188 | // @see hls-m3u8-draft-pantos-http-live-streaming-12.pdf, page 4 189 | // Lines are terminated by either a single LF character or a CR 190 | // character followed by an LF character. 191 | // CR = 192 | #define SRS_CONSTS_CR '\r' // 0x0D 193 | // LF = 194 | #define SRS_CONSTS_LF '\n' // 0x0A 195 | 196 | /////////////////////////////////////////////////////////// 197 | // HTTP consts values 198 | /////////////////////////////////////////////////////////// 199 | // linux path seprator 200 | #define SRS_CONSTS_HTTP_PATH_SEP '/' 201 | // query string seprator 202 | #define SRS_CONSTS_HTTP_QUERY_SEP '?' 203 | 204 | // 6.1.1 Status Code and Reason Phrase 205 | #define SRS_CONSTS_HTTP_Continue 100 206 | #define SRS_CONSTS_HTTP_SwitchingProtocols 101 207 | #define SRS_CONSTS_HTTP_OK 200 208 | #define SRS_CONSTS_HTTP_Created 201 209 | #define SRS_CONSTS_HTTP_Accepted 202 210 | #define SRS_CONSTS_HTTP_NonAuthoritativeInformation 203 211 | #define SRS_CONSTS_HTTP_NoContent 204 212 | #define SRS_CONSTS_HTTP_ResetContent 205 213 | #define SRS_CONSTS_HTTP_PartialContent 206 214 | #define SRS_CONSTS_HTTP_MultipleChoices 300 215 | #define SRS_CONSTS_HTTP_MovedPermanently 301 216 | #define SRS_CONSTS_HTTP_Found 302 217 | #define SRS_CONSTS_HTTP_SeeOther 303 218 | #define SRS_CONSTS_HTTP_NotModified 304 219 | #define SRS_CONSTS_HTTP_UseProxy 305 220 | #define SRS_CONSTS_HTTP_TemporaryRedirect 307 221 | #define SRS_CONSTS_HTTP_BadRequest 400 222 | #define SRS_CONSTS_HTTP_Unauthorized 401 223 | #define SRS_CONSTS_HTTP_PaymentRequired 402 224 | #define SRS_CONSTS_HTTP_Forbidden 403 225 | #define SRS_CONSTS_HTTP_NotFound 404 226 | #define SRS_CONSTS_HTTP_MethodNotAllowed 405 227 | #define SRS_CONSTS_HTTP_NotAcceptable 406 228 | #define SRS_CONSTS_HTTP_ProxyAuthenticationRequired 407 229 | #define SRS_CONSTS_HTTP_RequestTimeout 408 230 | #define SRS_CONSTS_HTTP_Conflict 409 231 | #define SRS_CONSTS_HTTP_Gone 410 232 | #define SRS_CONSTS_HTTP_LengthRequired 411 233 | #define SRS_CONSTS_HTTP_PreconditionFailed 412 234 | #define SRS_CONSTS_HTTP_RequestEntityTooLarge 413 235 | #define SRS_CONSTS_HTTP_RequestURITooLarge 414 236 | #define SRS_CONSTS_HTTP_UnsupportedMediaType 415 237 | #define SRS_CONSTS_HTTP_RequestedRangeNotSatisfiable 416 238 | #define SRS_CONSTS_HTTP_ExpectationFailed 417 239 | #define SRS_CONSTS_HTTP_InternalServerError 500 240 | #define SRS_CONSTS_HTTP_NotImplemented 501 241 | #define SRS_CONSTS_HTTP_BadGateway 502 242 | #define SRS_CONSTS_HTTP_ServiceUnavailable 503 243 | #define SRS_CONSTS_HTTP_GatewayTimeout 504 244 | #define SRS_CONSTS_HTTP_HTTPVersionNotSupported 505 245 | 246 | #define SRS_CONSTS_HTTP_Continue_str "Continue" 247 | #define SRS_CONSTS_HTTP_SwitchingProtocols_str "Switching Protocols" 248 | #define SRS_CONSTS_HTTP_OK_str "OK" 249 | #define SRS_CONSTS_HTTP_Created_str "Created" 250 | #define SRS_CONSTS_HTTP_Accepted_str "Accepted" 251 | #define SRS_CONSTS_HTTP_NonAuthoritativeInformation_str "Non Authoritative Information" 252 | #define SRS_CONSTS_HTTP_NoContent_str "No Content" 253 | #define SRS_CONSTS_HTTP_ResetContent_str "Reset Content" 254 | #define SRS_CONSTS_HTTP_PartialContent_str "Partial Content" 255 | #define SRS_CONSTS_HTTP_MultipleChoices_str "Multiple Choices" 256 | #define SRS_CONSTS_HTTP_MovedPermanently_str "Moved Permanently" 257 | #define SRS_CONSTS_HTTP_Found_str "Found" 258 | #define SRS_CONSTS_HTTP_SeeOther_str "See Other" 259 | #define SRS_CONSTS_HTTP_NotModified_str "Not Modified" 260 | #define SRS_CONSTS_HTTP_UseProxy_str "Use Proxy" 261 | #define SRS_CONSTS_HTTP_TemporaryRedirect_str "Temporary Redirect" 262 | #define SRS_CONSTS_HTTP_BadRequest_str "Bad Request" 263 | #define SRS_CONSTS_HTTP_Unauthorized_str "Unauthorized" 264 | #define SRS_CONSTS_HTTP_PaymentRequired_str "Payment Required" 265 | #define SRS_CONSTS_HTTP_Forbidden_str "Forbidden" 266 | #define SRS_CONSTS_HTTP_NotFound_str "Not Found" 267 | #define SRS_CONSTS_HTTP_MethodNotAllowed_str "Method Not Allowed" 268 | #define SRS_CONSTS_HTTP_NotAcceptable_str "Not Acceptable" 269 | #define SRS_CONSTS_HTTP_ProxyAuthenticationRequired_str "Proxy Authentication Required" 270 | #define SRS_CONSTS_HTTP_RequestTimeout_str "Request Timeout" 271 | #define SRS_CONSTS_HTTP_Conflict_str "Conflict" 272 | #define SRS_CONSTS_HTTP_Gone_str "Gone" 273 | #define SRS_CONSTS_HTTP_LengthRequired_str "Length Required" 274 | #define SRS_CONSTS_HTTP_PreconditionFailed_str "Precondition Failed" 275 | #define SRS_CONSTS_HTTP_RequestEntityTooLarge_str "Request Entity Too Large" 276 | #define SRS_CONSTS_HTTP_RequestURITooLarge_str "Request URI Too Large" 277 | #define SRS_CONSTS_HTTP_UnsupportedMediaType_str "Unsupported Media Type" 278 | #define SRS_CONSTS_HTTP_RequestedRangeNotSatisfiable_str "Requested Range Not Satisfiable" 279 | #define SRS_CONSTS_HTTP_ExpectationFailed_str "Expectation Failed" 280 | #define SRS_CONSTS_HTTP_InternalServerError_str "Internal Server Error" 281 | #define SRS_CONSTS_HTTP_NotImplemented_str "Not Implemented" 282 | #define SRS_CONSTS_HTTP_BadGateway_str "Bad Gateway" 283 | #define SRS_CONSTS_HTTP_ServiceUnavailable_str "Service Unavailable" 284 | #define SRS_CONSTS_HTTP_GatewayTimeout_str "Gateway Timeout" 285 | #define SRS_CONSTS_HTTP_HTTPVersionNotSupported_str "HTTP Version Not Supported" 286 | 287 | /////////////////////////////////////////////////////////// 288 | // RTSP consts values 289 | /////////////////////////////////////////////////////////// 290 | // 7.1.1 Status Code and Reason Phrase 291 | #define SRS_CONSTS_RTSP_Continue 100 292 | #define SRS_CONSTS_RTSP_OK 200 293 | #define SRS_CONSTS_RTSP_Created 201 294 | #define SRS_CONSTS_RTSP_LowOnStorageSpace 250 295 | #define SRS_CONSTS_RTSP_MultipleChoices 300 296 | #define SRS_CONSTS_RTSP_MovedPermanently 301 297 | #define SRS_CONSTS_RTSP_MovedTemporarily 302 298 | #define SRS_CONSTS_RTSP_SeeOther 303 299 | #define SRS_CONSTS_RTSP_NotModified 304 300 | #define SRS_CONSTS_RTSP_UseProxy 305 301 | #define SRS_CONSTS_RTSP_BadRequest 400 302 | #define SRS_CONSTS_RTSP_Unauthorized 401 303 | #define SRS_CONSTS_RTSP_PaymentRequired 402 304 | #define SRS_CONSTS_RTSP_Forbidden 403 305 | #define SRS_CONSTS_RTSP_NotFound 404 306 | #define SRS_CONSTS_RTSP_MethodNotAllowed 405 307 | #define SRS_CONSTS_RTSP_NotAcceptable 406 308 | #define SRS_CONSTS_RTSP_ProxyAuthenticationRequired 407 309 | #define SRS_CONSTS_RTSP_RequestTimeout 408 310 | #define SRS_CONSTS_RTSP_Gone 410 311 | #define SRS_CONSTS_RTSP_LengthRequired 411 312 | #define SRS_CONSTS_RTSP_PreconditionFailed 412 313 | #define SRS_CONSTS_RTSP_RequestEntityTooLarge 413 314 | #define SRS_CONSTS_RTSP_RequestURITooLarge 414 315 | #define SRS_CONSTS_RTSP_UnsupportedMediaType 415 316 | #define SRS_CONSTS_RTSP_ParameterNotUnderstood 451 317 | #define SRS_CONSTS_RTSP_ConferenceNotFound 452 318 | #define SRS_CONSTS_RTSP_NotEnoughBandwidth 453 319 | #define SRS_CONSTS_RTSP_SessionNotFound 454 320 | #define SRS_CONSTS_RTSP_MethodNotValidInThisState 455 321 | #define SRS_CONSTS_RTSP_HeaderFieldNotValidForResource 456 322 | #define SRS_CONSTS_RTSP_InvalidRange 457 323 | #define SRS_CONSTS_RTSP_ParameterIsReadOnly 458 324 | #define SRS_CONSTS_RTSP_AggregateOperationNotAllowed 459 325 | #define SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed 460 326 | #define SRS_CONSTS_RTSP_UnsupportedTransport 461 327 | #define SRS_CONSTS_RTSP_DestinationUnreachable 462 328 | #define SRS_CONSTS_RTSP_InternalServerError 500 329 | #define SRS_CONSTS_RTSP_NotImplemented 501 330 | #define SRS_CONSTS_RTSP_BadGateway 502 331 | #define SRS_CONSTS_RTSP_ServiceUnavailable 503 332 | #define SRS_CONSTS_RTSP_GatewayTimeout 504 333 | #define SRS_CONSTS_RTSP_RTSPVersionNotSupported 505 334 | #define SRS_CONSTS_RTSP_OptionNotSupported 551 335 | 336 | #define SRS_CONSTS_RTSP_Continue_str "Continue" 337 | #define SRS_CONSTS_RTSP_OK_str "OK" 338 | #define SRS_CONSTS_RTSP_Created_str "Created" 339 | #define SRS_CONSTS_RTSP_LowOnStorageSpace_str "Low on Storage Space" 340 | #define SRS_CONSTS_RTSP_MultipleChoices_str "Multiple Choices" 341 | #define SRS_CONSTS_RTSP_MovedPermanently_str "Moved Permanently" 342 | #define SRS_CONSTS_RTSP_MovedTemporarily_str "Moved Temporarily" 343 | #define SRS_CONSTS_RTSP_SeeOther_str "See Other" 344 | #define SRS_CONSTS_RTSP_NotModified_str "Not Modified" 345 | #define SRS_CONSTS_RTSP_UseProxy_str "Use Proxy" 346 | #define SRS_CONSTS_RTSP_BadRequest_str "Bad Request" 347 | #define SRS_CONSTS_RTSP_Unauthorized_str "Unauthorized" 348 | #define SRS_CONSTS_RTSP_PaymentRequired_str "Payment Required" 349 | #define SRS_CONSTS_RTSP_Forbidden_str "Forbidden" 350 | #define SRS_CONSTS_RTSP_NotFound_str "Not Found" 351 | #define SRS_CONSTS_RTSP_MethodNotAllowed_str "Method Not Allowed" 352 | #define SRS_CONSTS_RTSP_NotAcceptable_str "Not Acceptable" 353 | #define SRS_CONSTS_RTSP_ProxyAuthenticationRequired_str "Proxy Authentication Required" 354 | #define SRS_CONSTS_RTSP_RequestTimeout_str "Request Timeout" 355 | #define SRS_CONSTS_RTSP_Gone_str "Gone" 356 | #define SRS_CONSTS_RTSP_LengthRequired_str "Length Required" 357 | #define SRS_CONSTS_RTSP_PreconditionFailed_str "Precondition Failed" 358 | #define SRS_CONSTS_RTSP_RequestEntityTooLarge_str "Request Entity Too Large" 359 | #define SRS_CONSTS_RTSP_RequestURITooLarge_str "Request URI Too Large" 360 | #define SRS_CONSTS_RTSP_UnsupportedMediaType_str "Unsupported Media Type" 361 | #define SRS_CONSTS_RTSP_ParameterNotUnderstood_str "Invalid parameter" 362 | #define SRS_CONSTS_RTSP_ConferenceNotFound_str "Illegal Conference Identifier" 363 | #define SRS_CONSTS_RTSP_NotEnoughBandwidth_str "Not Enough Bandwidth" 364 | #define SRS_CONSTS_RTSP_SessionNotFound_str "Session Not Found" 365 | #define SRS_CONSTS_RTSP_MethodNotValidInThisState_str "Method Not Valid In This State" 366 | #define SRS_CONSTS_RTSP_HeaderFieldNotValidForResource_str "Header Field Not Valid" 367 | #define SRS_CONSTS_RTSP_InvalidRange_str "Invalid Range" 368 | #define SRS_CONSTS_RTSP_ParameterIsReadOnly_str "Parameter Is Read-Only" 369 | #define SRS_CONSTS_RTSP_AggregateOperationNotAllowed_str "Aggregate Operation Not Allowed" 370 | #define SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed_str "Only Aggregate Operation Allowed" 371 | #define SRS_CONSTS_RTSP_UnsupportedTransport_str "Unsupported Transport" 372 | #define SRS_CONSTS_RTSP_DestinationUnreachable_str "Destination Unreachable" 373 | #define SRS_CONSTS_RTSP_InternalServerError_str "Internal Server Error" 374 | #define SRS_CONSTS_RTSP_NotImplemented_str "Not Implemented" 375 | #define SRS_CONSTS_RTSP_BadGateway_str "Bad Gateway" 376 | #define SRS_CONSTS_RTSP_ServiceUnavailable_str "Service Unavailable" 377 | #define SRS_CONSTS_RTSP_GatewayTimeout_str "Gateway Timeout" 378 | #define SRS_CONSTS_RTSP_RTSPVersionNotSupported_str "RTSP Version Not Supported" 379 | #define SRS_CONSTS_RTSP_OptionNotSupported_str "Option not support" 380 | 381 | #endif 382 | 383 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_kernel_error.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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 | #include 25 | 26 | bool srs_is_system_control_error(int error_code) 27 | { 28 | return error_code == ERROR_CONTROL_RTMP_CLOSE 29 | || error_code == ERROR_CONTROL_REPUBLISH; 30 | } 31 | 32 | bool srs_is_client_gracefully_close(int error_code) 33 | { 34 | return error_code == ERROR_SOCKET_READ 35 | || error_code == ERROR_SOCKET_READ_FULLY 36 | || error_code == ERROR_SOCKET_WRITE; 37 | } 38 | 39 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_kernel_error.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_KERNEL_ERROR_HPP 25 | #define SRS_KERNEL_ERROR_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | // for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213 34 | #ifndef _WIN32 35 | #define ERROR_SUCCESS 0 36 | #endif 37 | 38 | /////////////////////////////////////////////////////// 39 | // system error. 40 | /////////////////////////////////////////////////////// 41 | #define ERROR_SOCKET_CREATE 1000 42 | #define ERROR_SOCKET_SETREUSE 1001 43 | #define ERROR_SOCKET_BIND 1002 44 | #define ERROR_SOCKET_LISTEN 1003 45 | #define ERROR_SOCKET_CLOSED 1004 46 | #define ERROR_SOCKET_GET_PEER_NAME 1005 47 | #define ERROR_SOCKET_GET_PEER_IP 1006 48 | #define ERROR_SOCKET_READ 1007 49 | #define ERROR_SOCKET_READ_FULLY 1008 50 | #define ERROR_SOCKET_WRITE 1009 51 | #define ERROR_SOCKET_WAIT 1010 52 | #define ERROR_SOCKET_TIMEOUT 1011 53 | #define ERROR_SOCKET_CONNECT 1012 54 | #define ERROR_ST_SET_EPOLL 1013 55 | #define ERROR_ST_INITIALIZE 1014 56 | #define ERROR_ST_OPEN_SOCKET 1015 57 | #define ERROR_ST_CREATE_LISTEN_THREAD 1016 58 | #define ERROR_ST_CREATE_CYCLE_THREAD 1017 59 | #define ERROR_ST_CONNECT 1018 60 | #define ERROR_SYSTEM_PACKET_INVALID 1019 61 | #define ERROR_SYSTEM_CLIENT_INVALID 1020 62 | #define ERROR_SYSTEM_ASSERT_FAILED 1021 63 | #define ERROR_READER_BUFFER_OVERFLOW 1022 64 | #define ERROR_SYSTEM_CONFIG_INVALID 1023 65 | #define ERROR_SYSTEM_CONFIG_DIRECTIVE 1024 66 | #define ERROR_SYSTEM_CONFIG_BLOCK_START 1025 67 | #define ERROR_SYSTEM_CONFIG_BLOCK_END 1026 68 | #define ERROR_SYSTEM_CONFIG_EOF 1027 69 | #define ERROR_SYSTEM_STREAM_BUSY 1028 70 | #define ERROR_SYSTEM_IP_INVALID 1029 71 | #define ERROR_SYSTEM_FORWARD_LOOP 1030 72 | #define ERROR_SYSTEM_WAITPID 1031 73 | #define ERROR_SYSTEM_BANDWIDTH_KEY 1032 74 | #define ERROR_SYSTEM_BANDWIDTH_DENIED 1033 75 | #define ERROR_SYSTEM_PID_ACQUIRE 1034 76 | #define ERROR_SYSTEM_PID_ALREADY_RUNNING 1035 77 | #define ERROR_SYSTEM_PID_LOCK 1036 78 | #define ERROR_SYSTEM_PID_TRUNCATE_FILE 1037 79 | #define ERROR_SYSTEM_PID_WRITE_FILE 1038 80 | #define ERROR_SYSTEM_PID_GET_FILE_INFO 1039 81 | #define ERROR_SYSTEM_PID_SET_FILE_INFO 1040 82 | #define ERROR_SYSTEM_FILE_ALREADY_OPENED 1041 83 | #define ERROR_SYSTEM_FILE_OPENE 1042 84 | #define ERROR_SYSTEM_FILE_CLOSE 1043 85 | #define ERROR_SYSTEM_FILE_READ 1044 86 | #define ERROR_SYSTEM_FILE_WRITE 1045 87 | #define ERROR_SYSTEM_FILE_EOF 1046 88 | #define ERROR_SYSTEM_FILE_RENAME 1047 89 | #define ERROR_SYSTEM_CREATE_PIPE 1048 90 | #define ERROR_SYSTEM_FILE_SEEK 1049 91 | #define ERROR_SYSTEM_IO_INVALID 1050 92 | #define ERROR_ST_EXCEED_THREADS 1051 93 | #define ERROR_SYSTEM_SECURITY 1052 94 | #define ERROR_SYSTEM_SECURITY_DENY 1053 95 | #define ERROR_SYSTEM_SECURITY_ALLOW 1054 96 | #define ERROR_SYSTEM_TIME 1055 97 | #define ERROR_SYSTEM_DIR_EXISTS 1056 98 | #define ERROR_SYSTEM_CREATE_DIR 1057 99 | 100 | /////////////////////////////////////////////////////// 101 | // RTMP protocol error. 102 | /////////////////////////////////////////////////////// 103 | #define ERROR_RTMP_PLAIN_REQUIRED 2000 104 | #define ERROR_RTMP_CHUNK_START 2001 105 | #define ERROR_RTMP_MSG_INVLIAD_SIZE 2002 106 | #define ERROR_RTMP_AMF0_DECODE 2003 107 | #define ERROR_RTMP_AMF0_INVALID 2004 108 | #define ERROR_RTMP_REQ_CONNECT 2005 109 | #define ERROR_RTMP_REQ_TCURL 2006 110 | #define ERROR_RTMP_MESSAGE_DECODE 2007 111 | #define ERROR_RTMP_MESSAGE_ENCODE 2008 112 | #define ERROR_RTMP_AMF0_ENCODE 2009 113 | #define ERROR_RTMP_CHUNK_SIZE 2010 114 | #define ERROR_RTMP_TRY_SIMPLE_HS 2011 115 | #define ERROR_RTMP_CH_SCHEMA 2012 116 | #define ERROR_RTMP_PACKET_SIZE 2013 117 | #define ERROR_RTMP_VHOST_NOT_FOUND 2014 118 | #define ERROR_RTMP_ACCESS_DENIED 2015 119 | #define ERROR_RTMP_HANDSHAKE 2016 120 | #define ERROR_RTMP_NO_REQUEST 2017 121 | #define ERROR_RTMP_HS_SSL_REQUIRE 2018 122 | #define ERROR_RTMP_DURATION_EXCEED 2019 123 | #define ERROR_RTMP_EDGE_PLAY_STATE 2020 124 | #define ERROR_RTMP_EDGE_PUBLISH_STATE 2021 125 | #define ERROR_RTMP_EDGE_PROXY_PULL 2022 126 | #define ERROR_RTMP_EDGE_RELOAD 2023 127 | #define ERROR_RTMP_AGGREGATE 2024 128 | #define ERROR_RTMP_BWTC_DATA 2025 129 | #define ERROR_OpenSslCreateDH 2026 130 | #define ERROR_OpenSslCreateP 2027 131 | #define ERROR_OpenSslCreateG 2028 132 | #define ERROR_OpenSslParseP1024 2029 133 | #define ERROR_OpenSslSetG 2030 134 | #define ERROR_OpenSslGenerateDHKeys 2031 135 | #define ERROR_OpenSslCopyKey 2032 136 | #define ERROR_OpenSslSha256Update 2033 137 | #define ERROR_OpenSslSha256Init 2034 138 | #define ERROR_OpenSslSha256Final 2035 139 | #define ERROR_OpenSslSha256EvpDigest 2036 140 | #define ERROR_OpenSslSha256DigestSize 2037 141 | #define ERROR_OpenSslGetPeerPublicKey 2038 142 | #define ERROR_OpenSslComputeSharedKey 2039 143 | #define ERROR_RTMP_MIC_CHUNKSIZE_CHANGED 2040 144 | #define ERROR_RTMP_MIC_CACHE_OVERFLOW 2041 145 | #define ERROR_RTSP_TOKEN_NOT_NORMAL 2042 146 | #define ERROR_RTSP_REQUEST_HEADER_EOF 2043 147 | #define ERROR_RTP_HEADER_CORRUPT 2044 148 | #define ERROR_RTP_TYPE96_CORRUPT 2045 149 | #define ERROR_RTP_TYPE97_CORRUPT 2046 150 | #define ERROR_RTSP_AUDIO_CONFIG 2047 151 | // 152 | // system control message, 153 | // not an error, but special control logic. 154 | // sys ctl: rtmp close stream, support replay. 155 | #define ERROR_CONTROL_RTMP_CLOSE 2998 156 | // FMLE stop publish and republish. 157 | #define ERROR_CONTROL_REPUBLISH 2999 158 | 159 | /////////////////////////////////////////////////////// 160 | // application level 161 | /////////////////////////////////////////////////////// 162 | #define ERROR_HLS_METADATA 3000 163 | #define ERROR_HLS_DECODE_ERROR 3001 164 | //#define ERROR_HLS_CREATE_DIR 3002 165 | #define ERROR_HLS_OPEN_FAILED 3003 166 | #define ERROR_HLS_WRITE_FAILED 3004 167 | #define ERROR_HLS_AAC_FRAME_LENGTH 3005 168 | #define ERROR_HLS_AVC_SAMPLE_SIZE 3006 169 | #define ERROR_HTTP_PARSE_URI 3007 170 | #define ERROR_HTTP_DATA_INVLIAD 3008 171 | #define ERROR_HTTP_PARSE_HEADER 3009 172 | #define ERROR_HTTP_HANDLER_MATCH_URL 3010 173 | #define ERROR_HTTP_HANDLER_INVALID 3011 174 | #define ERROR_HTTP_API_LOGS 3012 175 | #define ERROR_HTTP_REMUX_SEQUENCE_HEADER 3013 176 | #define ERROR_HTTP_REMUX_OFFSET_OVERFLOW 3014 177 | #define ERROR_ENCODER_VCODEC 3015 178 | #define ERROR_ENCODER_OUTPUT 3016 179 | #define ERROR_ENCODER_ACHANNELS 3017 180 | #define ERROR_ENCODER_ASAMPLE_RATE 3018 181 | #define ERROR_ENCODER_ABITRATE 3019 182 | #define ERROR_ENCODER_ACODEC 3020 183 | #define ERROR_ENCODER_VPRESET 3021 184 | #define ERROR_ENCODER_VPROFILE 3022 185 | #define ERROR_ENCODER_VTHREADS 3023 186 | #define ERROR_ENCODER_VHEIGHT 3024 187 | #define ERROR_ENCODER_VWIDTH 3025 188 | #define ERROR_ENCODER_VFPS 3026 189 | #define ERROR_ENCODER_VBITRATE 3027 190 | #define ERROR_ENCODER_FORK 3028 191 | #define ERROR_ENCODER_LOOP 3029 192 | #define ERROR_ENCODER_OPEN 3030 193 | #define ERROR_ENCODER_DUP2 3031 194 | #define ERROR_ENCODER_PARSE 3032 195 | #define ERROR_ENCODER_NO_INPUT 3033 196 | #define ERROR_ENCODER_NO_OUTPUT 3034 197 | #define ERROR_ENCODER_INPUT_TYPE 3035 198 | #define ERROR_KERNEL_FLV_HEADER 3036 199 | #define ERROR_KERNEL_FLV_STREAM_CLOSED 3037 200 | #define ERROR_KERNEL_STREAM_INIT 3038 201 | #define ERROR_EDGE_VHOST_REMOVED 3039 202 | #define ERROR_HLS_AVC_TRY_OTHERS 3040 203 | #define ERROR_H264_API_NO_PREFIXED 3041 204 | #define ERROR_FLV_INVALID_VIDEO_TAG 3042 205 | #define ERROR_H264_DROP_BEFORE_SPS_PPS 3043 206 | #define ERROR_H264_DUPLICATED_SPS 3044 207 | #define ERROR_H264_DUPLICATED_PPS 3045 208 | #define ERROR_AAC_REQUIRED_ADTS 3046 209 | #define ERROR_AAC_ADTS_HEADER 3047 210 | #define ERROR_AAC_DATA_INVALID 3048 211 | #define ERROR_HLS_TRY_MP3 3049 212 | #define ERROR_HTTP_DVR_DISABLED 3050 213 | #define ERROR_HTTP_DVR_REQUEST 3051 214 | #define ERROR_HTTP_JSON_REQUIRED 3052 215 | #define ERROR_HTTP_DVR_CREATE_REQUEST 3053 216 | #define ERROR_HTTP_DVR_NO_TAEGET 3054 217 | #define ERROR_ADTS_ID_NOT_AAC 3055 218 | // HDS error code 219 | #define ERROR_HDS_OPEN_F4M_FAILED 3056 220 | #define ERROR_HDS_WRITE_F4M_FAILED 3057 221 | #define ERROR_HDS_OPEN_BOOTSTRAP_FAILED 3058 222 | #define ERROR_HDS_WRITE_BOOTSTRAP_FAILED 3059 223 | #define ERROR_HDS_OPEN_FRAGMENT_FAILED 3060 224 | #define ERROR_HDS_WRITE_FRAGMENT_FAILED 3061 225 | 226 | /////////////////////////////////////////////////////// 227 | // HTTP/StreamCaster protocol error. 228 | /////////////////////////////////////////////////////// 229 | #define ERROR_HTTP_PATTERN_EMPTY 4000 230 | #define ERROR_HTTP_PATTERN_DUPLICATED 4001 231 | #define ERROR_HTTP_URL_NOT_CLEAN 4002 232 | #define ERROR_HTTP_CONTENT_LENGTH 4003 233 | #define ERROR_HTTP_LIVE_STREAM_EXT 4004 234 | #define ERROR_HTTP_STATUS_INVLIAD 4005 235 | #define ERROR_KERNEL_AAC_STREAM_CLOSED 4006 236 | #define ERROR_AAC_DECODE_ERROR 4007 237 | #define ERROR_KERNEL_MP3_STREAM_CLOSED 4008 238 | #define ERROR_MP3_DECODE_ERROR 4009 239 | #define ERROR_STREAM_CASTER_ENGINE 4010 240 | #define ERROR_STREAM_CASTER_PORT 4011 241 | #define ERROR_STREAM_CASTER_TS_HEADER 4012 242 | #define ERROR_STREAM_CASTER_TS_SYNC_BYTE 4013 243 | #define ERROR_STREAM_CASTER_TS_AF 4014 244 | #define ERROR_STREAM_CASTER_TS_CRC32 4015 245 | #define ERROR_STREAM_CASTER_TS_PSI 4016 246 | #define ERROR_STREAM_CASTER_TS_PAT 4017 247 | #define ERROR_STREAM_CASTER_TS_PMT 4018 248 | #define ERROR_STREAM_CASTER_TS_PSE 4019 249 | #define ERROR_STREAM_CASTER_TS_ES 4020 250 | #define ERROR_STREAM_CASTER_TS_CODEC 4021 251 | #define ERROR_STREAM_CASTER_AVC_SPS 4022 252 | #define ERROR_STREAM_CASTER_AVC_PPS 4023 253 | #define ERROR_STREAM_CASTER_FLV_TAG 4024 254 | #define ERROR_HTTP_RESPONSE_EOF 4025 255 | #define ERROR_HTTP_INVALID_CHUNK_HEADER 4026 256 | #define ERROR_AVC_NALU_UEV 4027 257 | #define ERROR_AAC_BYTES_INVALID 4028 258 | 259 | /////////////////////////////////////////////////////// 260 | // user-define error. 261 | /////////////////////////////////////////////////////// 262 | #define ERROR_USER_START 9000 263 | #define ERROR_USER_END 9999 264 | 265 | /** 266 | * whether the error code is an system control error. 267 | */ 268 | extern bool srs_is_system_control_error(int error_code); 269 | extern bool srs_is_client_gracefully_close(int error_code); 270 | 271 | /** 272 | @remark: use column copy to generate the new error codes. 273 | 01234567890 274 | 01234567891 275 | 01234567892 276 | 01234567893 277 | 01234567894 278 | 01234567895 279 | 01234567896 280 | 01234567897 281 | 01234567898 282 | 01234567899 283 | */ 284 | 285 | #endif 286 | 287 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_kernel_log.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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 | #include 25 | 26 | #include 27 | 28 | ISrsLog::ISrsLog() 29 | { 30 | } 31 | 32 | ISrsLog::~ISrsLog() 33 | { 34 | } 35 | 36 | int ISrsLog::initialize() 37 | { 38 | return ERROR_SUCCESS; 39 | } 40 | 41 | void ISrsLog::verbose(const char* /*tag*/, int /*context_id*/, const char* /*fmt*/, ...) 42 | { 43 | } 44 | 45 | void ISrsLog::info(const char* /*tag*/, int /*context_id*/, const char* /*fmt*/, ...) 46 | { 47 | } 48 | 49 | void ISrsLog::trace(const char* /*tag*/, int /*context_id*/, const char* /*fmt*/, ...) 50 | { 51 | } 52 | 53 | void ISrsLog::warn(const char* /*tag*/, int /*context_id*/, const char* /*fmt*/, ...) 54 | { 55 | } 56 | 57 | void ISrsLog::error(const char* /*tag*/, int /*context_id*/, const char* /*fmt*/, ...) 58 | { 59 | } 60 | 61 | ISrsThreadContext::ISrsThreadContext() 62 | { 63 | } 64 | 65 | ISrsThreadContext::~ISrsThreadContext() 66 | { 67 | } 68 | 69 | void ISrsThreadContext::generate_id() 70 | { 71 | } 72 | 73 | int ISrsThreadContext::get_id() 74 | { 75 | return 0; 76 | } 77 | 78 | 79 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_kernel_log.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_KERNEL_LOG_HPP 25 | #define SRS_KERNEL_LOG_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | #include 34 | 35 | #include 36 | #include 37 | 38 | #include 39 | 40 | /** 41 | * the log level, for example: 42 | * if specified Debug level, all level messages will be logged. 43 | * if specified Warn level, only Warn/Error/Fatal level messages will be logged. 44 | */ 45 | class SrsLogLevel 46 | { 47 | public: 48 | // only used for very verbose debug, generally, 49 | // we compile without this level for high performance. 50 | static const int Verbose = 0x01; 51 | static const int Info = 0x02; 52 | static const int Trace = 0x03; 53 | static const int Warn = 0x04; 54 | static const int Error = 0x05; 55 | // specified the disabled level, no log, for utest. 56 | static const int Disabled = 0x06; 57 | }; 58 | 59 | /** 60 | * the log interface provides method to write log. 61 | * but we provides some macro, which enable us to disable the log when compile. 62 | * @see also SmtDebug/SmtTrace/SmtWarn/SmtError which is corresponding to Debug/Trace/Warn/Fatal. 63 | */ 64 | class ISrsLog 65 | { 66 | public: 67 | ISrsLog(); 68 | virtual ~ISrsLog(); 69 | public: 70 | /** 71 | * initialize log utilities. 72 | */ 73 | virtual int initialize(); 74 | public: 75 | /** 76 | * log for verbose, very verbose information. 77 | */ 78 | virtual void verbose(const char* tag, int context_id, const char* fmt, ...); 79 | /** 80 | * log for debug, detail information. 81 | */ 82 | virtual void info(const char* tag, int context_id, const char* fmt, ...); 83 | /** 84 | * log for trace, important information. 85 | */ 86 | virtual void trace(const char* tag, int context_id, const char* fmt, ...); 87 | /** 88 | * log for warn, warn is something should take attention, but not a error. 89 | */ 90 | virtual void warn(const char* tag, int context_id, const char* fmt, ...); 91 | /** 92 | * log for error, something error occur, do something about the error, ie. close the connection, 93 | * but we will donot abort the program. 94 | */ 95 | virtual void error(const char* tag, int context_id, const char* fmt, ...); 96 | }; 97 | 98 | // the context for multiple clients. 99 | class ISrsThreadContext 100 | { 101 | public: 102 | ISrsThreadContext(); 103 | virtual ~ISrsThreadContext(); 104 | public: 105 | virtual void generate_id(); 106 | virtual int get_id(); 107 | }; 108 | 109 | // user must provides a log object 110 | extern ISrsLog* _srs_log; 111 | 112 | // user must implements the LogContext and define a global instance. 113 | extern ISrsThreadContext* _srs_context; 114 | 115 | // donot print method 116 | #if 1 117 | #define srs_verbose(msg, ...) _srs_log->verbose(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) 118 | #define srs_info(msg, ...) _srs_log->info(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) 119 | #define srs_trace(msg, ...) _srs_log->trace(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) 120 | #define srs_warn(msg, ...) _srs_log->warn(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) 121 | #define srs_error(msg, ...) _srs_log->error(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) 122 | // use __FUNCTION__ to print c method 123 | #elif 0 124 | #define srs_verbose(msg, ...) _srs_log->verbose(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) 125 | #define srs_info(msg, ...) _srs_log->info(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) 126 | #define srs_trace(msg, ...) _srs_log->trace(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) 127 | #define srs_warn(msg, ...) _srs_log->warn(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) 128 | #define srs_error(msg, ...) _srs_log->error(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) 129 | // use __PRETTY_FUNCTION__ to print c++ class:method 130 | #else 131 | #define srs_verbose(msg, ...) _srs_log->verbose(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) 132 | #define srs_info(msg, ...) _srs_log->info(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) 133 | #define srs_trace(msg, ...) _srs_log->trace(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) 134 | #define srs_warn(msg, ...) _srs_log->warn(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) 135 | #define srs_error(msg, ...) _srs_log->error(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) 136 | #endif 137 | 138 | // TODO: FIXME: add more verbose and info logs. 139 | #ifndef SRS_AUTO_VERBOSE 140 | #undef srs_verbose 141 | #define srs_verbose(msg, ...) (void)0 142 | #endif 143 | #ifndef SRS_AUTO_INFO 144 | #undef srs_info 145 | #define srs_info(msg, ...) (void)0 146 | #endif 147 | #ifndef SRS_AUTO_TRACE 148 | #undef srs_trace 149 | #define srs_trace(msg, ...) (void)0 150 | #endif 151 | 152 | #endif 153 | 154 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_kernel_stream.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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 | #include 25 | 26 | using namespace std; 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | SrsStream::SrsStream() 33 | { 34 | p = _bytes = NULL; 35 | _size = 0; 36 | 37 | // TODO: support both little and big endian. 38 | srs_assert(srs_is_little_endian()); 39 | } 40 | 41 | SrsStream::~SrsStream() 42 | { 43 | } 44 | 45 | int SrsStream::initialize(char* bytes, int size) 46 | { 47 | int ret = ERROR_SUCCESS; 48 | 49 | if (!bytes) { 50 | ret = ERROR_KERNEL_STREAM_INIT; 51 | srs_error("stream param bytes must not be NULL. ret=%d", ret); 52 | return ret; 53 | } 54 | 55 | if (size <= 0) { 56 | ret = ERROR_KERNEL_STREAM_INIT; 57 | srs_error("stream param size must be positive. ret=%d", ret); 58 | return ret; 59 | } 60 | 61 | _size = size; 62 | p = _bytes = bytes; 63 | srs_info("init stream ok, size=%d", size); 64 | 65 | return ret; 66 | } 67 | 68 | char* SrsStream::data() 69 | { 70 | return _bytes; 71 | } 72 | 73 | int SrsStream::size() 74 | { 75 | return _size; 76 | } 77 | 78 | int SrsStream::pos() 79 | { 80 | return p - _bytes; 81 | } 82 | 83 | bool SrsStream::empty() 84 | { 85 | return !_bytes || (p >= _bytes + _size); 86 | } 87 | 88 | bool SrsStream::require(int required_size) 89 | { 90 | srs_assert(required_size > 0); 91 | 92 | return required_size <= _size - (p - _bytes); 93 | } 94 | 95 | void SrsStream::skip(int size) 96 | { 97 | srs_assert(p); 98 | 99 | p += size; 100 | } 101 | 102 | int8_t SrsStream::read_1bytes() 103 | { 104 | srs_assert(require(1)); 105 | 106 | return (int8_t)*p++; 107 | } 108 | 109 | int16_t SrsStream::read_2bytes() 110 | { 111 | srs_assert(require(2)); 112 | 113 | int16_t value; 114 | pp = (char*)&value; 115 | pp[1] = *p++; 116 | pp[0] = *p++; 117 | 118 | return value; 119 | } 120 | 121 | int32_t SrsStream::read_3bytes() 122 | { 123 | srs_assert(require(3)); 124 | 125 | int32_t value = 0x00; 126 | pp = (char*)&value; 127 | pp[2] = *p++; 128 | pp[1] = *p++; 129 | pp[0] = *p++; 130 | 131 | return value; 132 | } 133 | 134 | int32_t SrsStream::read_4bytes() 135 | { 136 | srs_assert(require(4)); 137 | 138 | int32_t value; 139 | pp = (char*)&value; 140 | pp[3] = *p++; 141 | pp[2] = *p++; 142 | pp[1] = *p++; 143 | pp[0] = *p++; 144 | 145 | return value; 146 | } 147 | 148 | int64_t SrsStream::read_8bytes() 149 | { 150 | srs_assert(require(8)); 151 | 152 | int64_t value; 153 | pp = (char*)&value; 154 | pp[7] = *p++; 155 | pp[6] = *p++; 156 | pp[5] = *p++; 157 | pp[4] = *p++; 158 | pp[3] = *p++; 159 | pp[2] = *p++; 160 | pp[1] = *p++; 161 | pp[0] = *p++; 162 | 163 | return value; 164 | } 165 | 166 | string SrsStream::read_string(int len) 167 | { 168 | srs_assert(require(len)); 169 | 170 | std::string value; 171 | value.append(p, len); 172 | 173 | p += len; 174 | 175 | return value; 176 | } 177 | 178 | void SrsStream::read_bytes(char* data, int size) 179 | { 180 | srs_assert(require(size)); 181 | 182 | memcpy(data, p, size); 183 | 184 | p += size; 185 | } 186 | 187 | void SrsStream::write_1bytes(int8_t value) 188 | { 189 | srs_assert(require(1)); 190 | 191 | *p++ = value; 192 | } 193 | 194 | void SrsStream::write_2bytes(int16_t value) 195 | { 196 | srs_assert(require(2)); 197 | 198 | pp = (char*)&value; 199 | *p++ = pp[1]; 200 | *p++ = pp[0]; 201 | } 202 | 203 | void SrsStream::write_4bytes(int32_t value) 204 | { 205 | srs_assert(require(4)); 206 | 207 | pp = (char*)&value; 208 | *p++ = pp[3]; 209 | *p++ = pp[2]; 210 | *p++ = pp[1]; 211 | *p++ = pp[0]; 212 | } 213 | 214 | void SrsStream::write_3bytes(int32_t value) 215 | { 216 | srs_assert(require(3)); 217 | 218 | pp = (char*)&value; 219 | *p++ = pp[2]; 220 | *p++ = pp[1]; 221 | *p++ = pp[0]; 222 | } 223 | 224 | void SrsStream::write_8bytes(int64_t value) 225 | { 226 | srs_assert(require(8)); 227 | 228 | pp = (char*)&value; 229 | *p++ = pp[7]; 230 | *p++ = pp[6]; 231 | *p++ = pp[5]; 232 | *p++ = pp[4]; 233 | *p++ = pp[3]; 234 | *p++ = pp[2]; 235 | *p++ = pp[1]; 236 | *p++ = pp[0]; 237 | } 238 | 239 | void SrsStream::write_string(string value) 240 | { 241 | srs_assert(require(value.length())); 242 | 243 | memcpy(p, value.data(), value.length()); 244 | p += value.length(); 245 | } 246 | 247 | void SrsStream::write_bytes(char* data, int size) 248 | { 249 | srs_assert(require(size)); 250 | 251 | memcpy(p, data, size); 252 | p += size; 253 | } 254 | 255 | SrsBitStream::SrsBitStream() 256 | { 257 | cb = 0; 258 | cb_left = 0; 259 | stream = NULL; 260 | } 261 | 262 | SrsBitStream::~SrsBitStream() 263 | { 264 | } 265 | 266 | int SrsBitStream::initialize(SrsStream* s) { 267 | stream = s; 268 | return ERROR_SUCCESS; 269 | } 270 | 271 | bool SrsBitStream::empty() { 272 | if (cb_left) { 273 | return false; 274 | } 275 | return stream->empty(); 276 | } 277 | 278 | int8_t SrsBitStream::read_bit() { 279 | if (!cb_left) { 280 | srs_assert(!stream->empty()); 281 | cb = stream->read_1bytes(); 282 | cb_left = 8; 283 | } 284 | 285 | int8_t v = (cb >> (cb_left - 1)) & 0x01; 286 | cb_left--; 287 | return v; 288 | } 289 | 290 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_kernel_stream.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_KERNEL_STREAM_HPP 25 | #define SRS_KERNEL_STREAM_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | #include 34 | #include 35 | 36 | /** 37 | * bytes utility, used to: 38 | * convert basic types to bytes, 39 | * build basic types from bytes. 40 | */ 41 | class SrsStream 42 | { 43 | private: 44 | char* p; 45 | char* pp; 46 | char* _bytes; 47 | int _size; 48 | public: 49 | SrsStream(); 50 | virtual ~SrsStream(); 51 | public: 52 | /** 53 | * initialize the stream from bytes. 54 | * @bytes, the bytes to convert from/to basic types. 55 | * @size, the size of bytes. 56 | * @remark, stream never free the bytes, user must free it. 57 | * @remark, return error when bytes NULL. 58 | * @remark, return error when size is not positive. 59 | */ 60 | virtual int initialize(char* bytes, int size); 61 | // get the status of stream 62 | public: 63 | /** 64 | * get data of stream, set by initialize. 65 | * current bytes = data() + pos() 66 | */ 67 | virtual char* data(); 68 | /** 69 | * the total stream size, set by initialize. 70 | * left bytes = size() - pos(). 71 | */ 72 | virtual int size(); 73 | /** 74 | * tell the current pos. 75 | */ 76 | virtual int pos(); 77 | /** 78 | * whether stream is empty. 79 | * if empty, user should never read or write. 80 | */ 81 | virtual bool empty(); 82 | /** 83 | * whether required size is ok. 84 | * @return true if stream can read/write specified required_size bytes. 85 | * @remark assert required_size positive. 86 | */ 87 | virtual bool require(int required_size); 88 | // to change stream. 89 | public: 90 | /** 91 | * to skip some size. 92 | * @param size can be any value. positive to forward; nagetive to backward. 93 | * @remark to skip(pos()) to reset stream. 94 | * @remark assert initialized, the data() not NULL. 95 | */ 96 | virtual void skip(int size); 97 | public: 98 | /** 99 | * get 1bytes char from stream. 100 | */ 101 | virtual int8_t read_1bytes(); 102 | /** 103 | * get 2bytes int from stream. 104 | */ 105 | virtual int16_t read_2bytes(); 106 | /** 107 | * get 3bytes int from stream. 108 | */ 109 | virtual int32_t read_3bytes(); 110 | /** 111 | * get 4bytes int from stream. 112 | */ 113 | virtual int32_t read_4bytes(); 114 | /** 115 | * get 8bytes int from stream. 116 | */ 117 | virtual int64_t read_8bytes(); 118 | /** 119 | * get string from stream, length specifies by param len. 120 | */ 121 | virtual std::string read_string(int len); 122 | /** 123 | * get bytes from stream, length specifies by param len. 124 | */ 125 | virtual void read_bytes(char* data, int size); 126 | public: 127 | /** 128 | * write 1bytes char to stream. 129 | */ 130 | virtual void write_1bytes(int8_t value); 131 | /** 132 | * write 2bytes int to stream. 133 | */ 134 | virtual void write_2bytes(int16_t value); 135 | /** 136 | * write 4bytes int to stream. 137 | */ 138 | virtual void write_4bytes(int32_t value); 139 | /** 140 | * write 3bytes int to stream. 141 | */ 142 | virtual void write_3bytes(int32_t value); 143 | /** 144 | * write 8bytes int to stream. 145 | */ 146 | virtual void write_8bytes(int64_t value); 147 | /** 148 | * write string to stream 149 | */ 150 | virtual void write_string(std::string value); 151 | /** 152 | * write bytes to stream 153 | */ 154 | virtual void write_bytes(char* data, int size); 155 | }; 156 | 157 | /** 158 | * the bit stream. 159 | */ 160 | class SrsBitStream 161 | { 162 | private: 163 | int8_t cb; 164 | u_int8_t cb_left; 165 | SrsStream* stream; 166 | public: 167 | SrsBitStream(); 168 | virtual ~SrsBitStream(); 169 | public: 170 | virtual int initialize(SrsStream* s); 171 | virtual bool empty(); 172 | virtual int8_t read_bit(); 173 | }; 174 | 175 | #endif 176 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_kernel_utility.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_KERNEL_UTILITY_HPP 25 | #define SRS_KERNEL_UTILITY_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | #include 34 | 35 | class SrsStream; 36 | class SrsBitStream; 37 | 38 | // compare 39 | #define srs_min(a, b) (((a) < (b))? (a) : (b)) 40 | #define srs_max(a, b) (((a) < (b))? (b) : (a)) 41 | 42 | // read nalu uev. 43 | extern int srs_avc_nalu_read_uev(SrsBitStream* stream, int32_t& v); 44 | extern int srs_avc_nalu_read_bit(SrsBitStream* stream, int8_t& v); 45 | 46 | // get current system time in ms, use cache to avoid performance problem 47 | extern int64_t srs_get_system_time_ms(); 48 | extern int64_t srs_get_system_startup_time_ms(); 49 | // the deamon st-thread will update it. 50 | extern int64_t srs_update_system_time_ms(); 51 | 52 | // dns resolve utility, return the resolved ip address. 53 | extern std::string srs_dns_resolve(std::string host); 54 | 55 | // whether system is little endian 56 | extern bool srs_is_little_endian(); 57 | 58 | // replace old_str to new_str of str 59 | extern std::string srs_string_replace(std::string str, std::string old_str, std::string new_str); 60 | // trim char in trim_chars of str 61 | extern std::string srs_string_trim_end(std::string str, std::string trim_chars); 62 | // trim char in trim_chars of str 63 | extern std::string srs_string_trim_start(std::string str, std::string trim_chars); 64 | // remove char in remove_chars of str 65 | extern std::string srs_string_remove(std::string str, std::string remove_chars); 66 | // whether string end with 67 | extern bool srs_string_ends_with(std::string str, std::string flag); 68 | // whether string starts with 69 | extern bool srs_string_starts_with(std::string str, std::string flag); 70 | // whether string contains with 71 | extern bool srs_string_contains(std::string str, std::string flag); 72 | 73 | // create dir recursively 74 | extern int srs_create_dir_recursively(std::string dir); 75 | 76 | // whether path exists. 77 | extern bool srs_path_exists(std::string path); 78 | // get the dirname of path 79 | extern std::string srs_path_dirname(std::string path); 80 | // get the basename of path 81 | extern std::string srs_path_basename(std::string path); 82 | 83 | /** 84 | * whether stream starts with the avc NALU in "AnnexB" 85 | * from H.264-AVC-ISO_IEC_14496-10.pdf, page 211. 86 | * start code must be "N[00] 00 00 01" where N>=0 87 | * @param pnb_start_code output the size of start code, must >=3. 88 | * NULL to ignore. 89 | */ 90 | extern bool srs_avc_startswith_annexb(SrsStream* stream, int* pnb_start_code = NULL); 91 | 92 | /** 93 | * whether stream starts with the aac ADTS 94 | * from aac-mp4a-format-ISO_IEC_14496-3+2001.pdf, page 75, 1.A.2.2 ADTS. 95 | * start code must be '1111 1111 1111'B, that is 0xFFF 96 | */ 97 | extern bool srs_aac_startswith_adts(SrsStream* stream); 98 | 99 | /** 100 | * cacl the crc32 of bytes in buf. 101 | */ 102 | extern u_int32_t srs_crc32(const void* buf, int size); 103 | 104 | /** 105 | * Decode a base64-encoded string. 106 | * 107 | * @param out buffer for decoded data 108 | * @param in null-terminated input string 109 | * @param out_size size in bytes of the out buffer, must be at 110 | * least 3/4 of the length of in 111 | * @return number of bytes written, or a negative value in case of 112 | * invalid input 113 | */ 114 | extern int srs_av_base64_decode(u_int8_t* out, const char* in, int out_size); 115 | 116 | /** 117 | * Encode data to base64 and null-terminate. 118 | * 119 | * @param out buffer for encoded data 120 | * @param out_size size in bytes of the out buffer (including the 121 | * null terminator), must be at least AV_BASE64_SIZE(in_size) 122 | * @param in input buffer containing the data to encode 123 | * @param in_size size in bytes of the in buffer 124 | * @return out or NULL in case of error 125 | */ 126 | extern char* srs_av_base64_encode(char* out, int out_size, const u_int8_t* in, int in_size); 127 | 128 | /** 129 | * Calculate the output size needed to base64-encode x bytes to a 130 | * null-terminated string. 131 | */ 132 | #define SRS_AV_BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1) 133 | 134 | /** 135 | * convert hex string to data. 136 | * for example, p=config='139056E5A0' 137 | * output hex to data={0x13, 0x90, 0x56, 0xe5, 0xa0} 138 | */ 139 | extern int ff_hex_to_data(u_int8_t* data, const char* p); 140 | 141 | #endif 142 | 143 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_lib_bandwidth.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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 | #include 25 | 26 | // for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213 27 | #ifndef _WIN32 28 | #include 29 | #endif 30 | 31 | #include 32 | using namespace std; 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | /** 42 | * recv bandwidth helper. 43 | */ 44 | typedef bool (*_CheckPacketType)(SrsBandwidthPacket* pkt); 45 | bool _bandwidth_is_start_play(SrsBandwidthPacket* pkt) 46 | { 47 | return pkt->is_start_play(); 48 | } 49 | bool _bandwidth_is_stop_play(SrsBandwidthPacket* pkt) 50 | { 51 | return pkt->is_stop_play(); 52 | } 53 | bool _bandwidth_is_start_publish(SrsBandwidthPacket* pkt) 54 | { 55 | return pkt->is_start_publish(); 56 | } 57 | bool _bandwidth_is_stop_publish(SrsBandwidthPacket* pkt) 58 | { 59 | return pkt->is_stop_publish(); 60 | } 61 | bool _bandwidth_is_finish(SrsBandwidthPacket* pkt) 62 | { 63 | return pkt->is_finish(); 64 | } 65 | int _srs_expect_bandwidth_packet(SrsRtmpClient* rtmp, _CheckPacketType pfn) 66 | { 67 | int ret = ERROR_SUCCESS; 68 | 69 | while (true) { 70 | SrsCommonMessage* msg = NULL; 71 | SrsBandwidthPacket* pkt = NULL; 72 | if ((ret = rtmp->expect_message(&msg, &pkt)) != ERROR_SUCCESS) { 73 | return ret; 74 | } 75 | SrsAutoFree(SrsCommonMessage, msg); 76 | SrsAutoFree(SrsBandwidthPacket, pkt); 77 | srs_info("get final message success."); 78 | 79 | if (pfn(pkt)) { 80 | return ret; 81 | } 82 | } 83 | 84 | return ret; 85 | } 86 | int _srs_expect_bandwidth_packet2(SrsRtmpClient* rtmp, _CheckPacketType pfn, SrsBandwidthPacket** ppkt) 87 | { 88 | int ret = ERROR_SUCCESS; 89 | 90 | while (true) { 91 | SrsCommonMessage* msg = NULL; 92 | SrsBandwidthPacket* pkt = NULL; 93 | if ((ret = rtmp->expect_message(&msg, &pkt)) != ERROR_SUCCESS) { 94 | return ret; 95 | } 96 | SrsAutoFree(SrsCommonMessage, msg); 97 | srs_info("get final message success."); 98 | 99 | if (pfn(pkt)) { 100 | *ppkt = pkt; 101 | return ret; 102 | } 103 | 104 | srs_freep(pkt); 105 | } 106 | 107 | return ret; 108 | } 109 | 110 | SrsBandwidthClient::SrsBandwidthClient() 111 | { 112 | _rtmp = NULL; 113 | } 114 | 115 | SrsBandwidthClient::~SrsBandwidthClient() 116 | { 117 | } 118 | 119 | int SrsBandwidthClient::initialize(SrsRtmpClient* rtmp) 120 | { 121 | _rtmp = rtmp; 122 | 123 | return ERROR_SUCCESS; 124 | } 125 | 126 | int SrsBandwidthClient::bandwidth_check( 127 | int64_t* start_time, int64_t* end_time, 128 | int* play_kbps, int* publish_kbps, 129 | int* play_bytes, int* publish_bytes, 130 | int* play_duration, int* publish_duration 131 | ) { 132 | int ret = ERROR_SUCCESS; 133 | 134 | srs_update_system_time_ms(); 135 | *start_time = srs_get_system_time_ms(); 136 | 137 | // play 138 | if ((ret = play_start()) != ERROR_SUCCESS) { 139 | return ret; 140 | } 141 | if ((ret = play_checking()) != ERROR_SUCCESS) { 142 | return ret; 143 | } 144 | if ((ret = play_stop()) != ERROR_SUCCESS) { 145 | return ret; 146 | } 147 | 148 | // publish 149 | int duration_ms = 0; 150 | int actual_play_kbps = 0; 151 | if ((ret = publish_start(duration_ms, actual_play_kbps)) != ERROR_SUCCESS) { 152 | return ret; 153 | } 154 | if ((ret = publish_checking(duration_ms, actual_play_kbps)) != ERROR_SUCCESS) { 155 | return ret; 156 | } 157 | if ((ret = publish_stop()) != ERROR_SUCCESS) { 158 | return ret; 159 | } 160 | 161 | SrsBandwidthPacket* pkt = NULL; 162 | if ((ret = final(&pkt)) != ERROR_SUCCESS) { 163 | return ret; 164 | } 165 | SrsAutoFree(SrsBandwidthPacket, pkt); 166 | 167 | // get data 168 | if (true ) { 169 | SrsAmf0Any* prop = NULL; 170 | if ((prop = pkt->data->ensure_property_number("play_kbps")) != NULL) { 171 | *play_kbps = (int)prop->to_number(); 172 | } 173 | if ((prop = pkt->data->ensure_property_number("publish_kbps")) != NULL) { 174 | *publish_kbps = (int)prop->to_number(); 175 | } 176 | if ((prop = pkt->data->ensure_property_number("play_bytes")) != NULL) { 177 | *play_bytes = (int)prop->to_number(); 178 | } 179 | if ((prop = pkt->data->ensure_property_number("publish_bytes")) != NULL) { 180 | *publish_bytes = (int)prop->to_number(); 181 | } 182 | if ((prop = pkt->data->ensure_property_number("play_time")) != NULL) { 183 | *play_duration = (int)prop->to_number(); 184 | } 185 | if ((prop = pkt->data->ensure_property_number("publish_time")) != NULL) { 186 | *publish_duration = (int)prop->to_number(); 187 | } 188 | } 189 | 190 | srs_update_system_time_ms(); 191 | *end_time = srs_get_system_time_ms(); 192 | 193 | return ret; 194 | } 195 | 196 | int SrsBandwidthClient::play_start() 197 | { 198 | int ret = ERROR_SUCCESS; 199 | 200 | if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_start_play)) != ERROR_SUCCESS) { 201 | return ret; 202 | } 203 | srs_info("BW check recv play begin request."); 204 | 205 | if (true) { 206 | // send start play response to server. 207 | SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_starting_play(); 208 | 209 | if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { 210 | srs_error("send bandwidth check start play message failed. ret=%d", ret); 211 | return ret; 212 | } 213 | } 214 | srs_info("BW check play begin."); 215 | 216 | return ret; 217 | } 218 | 219 | int SrsBandwidthClient::play_checking() 220 | { 221 | int ret = ERROR_SUCCESS; 222 | return ret; 223 | } 224 | 225 | int SrsBandwidthClient::play_stop() 226 | { 227 | int ret = ERROR_SUCCESS; 228 | 229 | if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stop_play)) != ERROR_SUCCESS) { 230 | return ret; 231 | } 232 | srs_info("BW check recv play stop request."); 233 | 234 | if (true) { 235 | // send stop play response to server. 236 | SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stopped_play(); 237 | 238 | if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { 239 | srs_error("send bandwidth check stop play message failed. ret=%d", ret); 240 | return ret; 241 | } 242 | } 243 | srs_info("BW check play stop."); 244 | 245 | return ret; 246 | } 247 | 248 | int SrsBandwidthClient::publish_start(int& duration_ms, int& play_kbps) 249 | { 250 | int ret = ERROR_SUCCESS; 251 | 252 | if (true) { 253 | SrsBandwidthPacket* pkt = NULL; 254 | if ((ret = _srs_expect_bandwidth_packet2(_rtmp, _bandwidth_is_start_publish, &pkt)) != ERROR_SUCCESS) { 255 | return ret; 256 | } 257 | SrsAutoFree(SrsBandwidthPacket, pkt); 258 | 259 | SrsAmf0Any* prop = NULL; 260 | if ((prop = pkt->data->ensure_property_number("duration_ms")) != NULL) { 261 | duration_ms = (int)prop->to_number(); 262 | } 263 | if ((prop = pkt->data->ensure_property_number("limit_kbps")) != NULL) { 264 | play_kbps = (int)prop->to_number(); 265 | } 266 | } 267 | srs_info("BW check recv publish begin request."); 268 | 269 | if (true) { 270 | // send start publish response to server. 271 | SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_starting_publish(); 272 | 273 | if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { 274 | srs_error("send bandwidth check start publish message failed. ret=%d", ret); 275 | return ret; 276 | } 277 | } 278 | srs_info("BW check publish begin."); 279 | 280 | return ret; 281 | } 282 | 283 | int SrsBandwidthClient::publish_checking(int duration_ms, int play_kbps) 284 | { 285 | int ret = ERROR_SUCCESS; 286 | 287 | if (duration_ms <= 0) { 288 | ret = ERROR_RTMP_BWTC_DATA; 289 | srs_error("server must specifies the duration, ret=%d", ret); 290 | return ret; 291 | } 292 | 293 | if (play_kbps <= 0) { 294 | ret = ERROR_RTMP_BWTC_DATA; 295 | srs_error("server must specifies the play kbp, ret=%d", ret); 296 | return ret; 297 | } 298 | 299 | int data_count = 1; 300 | srs_update_system_time_ms(); 301 | int64_t starttime = srs_get_system_time_ms(); 302 | while ((srs_get_system_time_ms() - starttime) < duration_ms) { 303 | // TODO: FIXME: use shared ptr message. 304 | SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_publishing(); 305 | 306 | // TODO: FIXME: magic number 307 | for (int i = 0; i < data_count; ++i) { 308 | std::stringstream seq; 309 | seq << i; 310 | std::string play_data = "SRS band check data from server's publishing......"; 311 | pkt->data->set(seq.str(), SrsAmf0Any::str(play_data.c_str())); 312 | } 313 | data_count += 2; 314 | 315 | if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { 316 | srs_error("send bandwidth check publish messages failed. ret=%d", ret); 317 | return ret; 318 | } 319 | 320 | // use the play kbps to control the publish 321 | srs_update_system_time_ms(); 322 | int elaps = (int)(srs_get_system_time_ms() - starttime); 323 | if (elaps > 0) { 324 | int current_kbps = (int)(_rtmp->get_send_bytes() * 8 / elaps); 325 | while (current_kbps > play_kbps) { 326 | srs_update_system_time_ms(); 327 | elaps = (int)(srs_get_system_time_ms() - starttime); 328 | current_kbps = (int)(_rtmp->get_send_bytes() * 8 / elaps); 329 | usleep(100 * 1000); // TODO: FIXME: magic number. 330 | } 331 | } 332 | } 333 | srs_info("BW check send publish bytes over."); 334 | 335 | return ret; 336 | } 337 | 338 | int SrsBandwidthClient::publish_stop() 339 | { 340 | int ret = ERROR_SUCCESS; 341 | 342 | if (true) { 343 | // send start publish response to server. 344 | SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_publish(); 345 | 346 | if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { 347 | srs_error("send bandwidth check stop publish message failed. ret=%d", ret); 348 | return ret; 349 | } 350 | } 351 | srs_info("BW client stop publish request."); 352 | 353 | if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stop_publish)) != ERROR_SUCCESS) { 354 | return ret; 355 | } 356 | srs_info("BW check recv publish stop request."); 357 | 358 | if (true) { 359 | // send start publish response to server. 360 | SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stopped_publish(); 361 | 362 | if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { 363 | srs_error("send bandwidth check stop publish message failed. ret=%d", ret); 364 | return ret; 365 | } 366 | } 367 | srs_info("BW check publish stop."); 368 | 369 | return ret; 370 | } 371 | 372 | int SrsBandwidthClient::final(SrsBandwidthPacket** ppkt) 373 | { 374 | int ret = ERROR_SUCCESS; 375 | 376 | if ((ret = _srs_expect_bandwidth_packet2(_rtmp, _bandwidth_is_finish, ppkt)) != ERROR_SUCCESS) { 377 | return ret; 378 | } 379 | srs_info("BW check recv finish/report request."); 380 | 381 | if (true) { 382 | // send final response to server. 383 | SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_final(); 384 | 385 | if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { 386 | srs_error("send bandwidth check final message failed. ret=%d", ret); 387 | return ret; 388 | } 389 | } 390 | srs_info("BW check final."); 391 | 392 | return ret; 393 | } 394 | 395 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_lib_bandwidth.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_BANDWIDTH_HPP 25 | #define SRS_LIB_BANDWIDTH_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | class SrsRtmpClient; 34 | class SrsBandwidthPacket; 35 | 36 | /** 37 | * bandwith client library for srs-librtmp. 38 | */ 39 | class SrsBandwidthClient 40 | { 41 | private: 42 | SrsRtmpClient* _rtmp; 43 | public: 44 | SrsBandwidthClient(); 45 | virtual ~SrsBandwidthClient(); 46 | public: 47 | /** 48 | * initialize the bandwidth check client. 49 | */ 50 | virtual int initialize(SrsRtmpClient* rtmp); 51 | /** 52 | * do bandwidth check. 53 | * 54 | * bandwidth info: 55 | * @param start_time, output the start time, in ms. 56 | * @param end_time, output the end time, in ms. 57 | * @param play_kbps, output the play/download kbps. 58 | * @param publish_kbps, output the publish/upload kbps. 59 | * @param play_bytes, output the play/download bytes. 60 | * @param publish_bytes, output the publish/upload bytes. 61 | * @param play_duration, output the play/download test duration, in ms. 62 | * @param publish_duration, output the publish/upload test duration, in ms. 63 | */ 64 | virtual int bandwidth_check( 65 | int64_t* start_time, int64_t* end_time, 66 | int* play_kbps, int* publish_kbps, 67 | int* play_bytes, int* publish_bytes, 68 | int* play_duration, int* publish_duration 69 | ); 70 | private: 71 | /** 72 | * play check/test, downloading bandwidth kbps. 73 | */ 74 | virtual int play_start(); 75 | virtual int play_checking(); 76 | virtual int play_stop(); 77 | /** 78 | * publish check/test, publishing bandwidth kbps. 79 | */ 80 | virtual int publish_start(int& duration_ms, int& play_kbps); 81 | virtual int publish_checking(int duration_ms, int play_kbps); 82 | virtual int publish_stop(); 83 | /** 84 | * report and final packet 85 | */ 86 | virtual int final(SrsBandwidthPacket** ppkt); 87 | }; 88 | 89 | #endif 90 | 91 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_lib_simple_socket.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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 | #include 25 | 26 | #include 27 | 28 | // for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213 29 | #ifndef _WIN32 30 | #define SOCKET_ETIME ETIME 31 | #define SOCKET_ECONNRESET ECONNRESET 32 | 33 | #define SOCKET_ERRNO() errno 34 | #define SOCKET_RESET(fd) fd = -1; (void)0 35 | #define SOCKET_CLOSE(fd) \ 36 | if (fd > 0) {\ 37 | ::close(fd); \ 38 | fd = -1; \ 39 | } \ 40 | (void)0 41 | #define SOCKET_VALID(x) (x > 0) 42 | #define SOCKET_SETUP() (void)0 43 | #define SOCKET_CLEANUP() (void)0 44 | #else 45 | #define SOCKET_ETIME WSAETIMEDOUT 46 | #define SOCKET_ECONNRESET WSAECONNRESET 47 | #define SOCKET_ERRNO() WSAGetLastError() 48 | #define SOCKET_RESET(x) x=INVALID_SOCKET 49 | #define SOCKET_CLOSE(x) if(x!=INVALID_SOCKET){::closesocket(x);x=INVALID_SOCKET;} 50 | #define SOCKET_VALID(x) (x!=INVALID_SOCKET) 51 | #define SOCKET_BUFF(x) ((char*)x) 52 | #define SOCKET_SETUP() socket_setup() 53 | #define SOCKET_CLEANUP() socket_cleanup() 54 | #endif 55 | 56 | // for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213 57 | #ifndef _WIN32 58 | #include 59 | #include 60 | #include 61 | #include 62 | #include 63 | #endif 64 | 65 | #include 66 | #include 67 | 68 | #include 69 | 70 | #ifndef ST_UTIME_NO_TIMEOUT 71 | #define ST_UTIME_NO_TIMEOUT -1 72 | #endif 73 | 74 | // when io not hijacked, use simple socket, the block sync stream. 75 | #ifndef SRS_HIJACK_IO 76 | struct SrsBlockSyncSocket 77 | { 78 | SOCKET fd; 79 | int64_t recv_timeout; 80 | int64_t send_timeout; 81 | int64_t recv_bytes; 82 | int64_t send_bytes; 83 | 84 | SrsBlockSyncSocket() { 85 | send_timeout = recv_timeout = ST_UTIME_NO_TIMEOUT; 86 | recv_bytes = send_bytes = 0; 87 | 88 | SOCKET_RESET(fd); 89 | SOCKET_SETUP(); 90 | } 91 | 92 | virtual ~SrsBlockSyncSocket() { 93 | SOCKET_CLOSE(fd); 94 | SOCKET_CLEANUP(); 95 | } 96 | }; 97 | srs_hijack_io_t srs_hijack_io_create() 98 | { 99 | SrsBlockSyncSocket* skt = new SrsBlockSyncSocket(); 100 | return skt; 101 | } 102 | void srs_hijack_io_destroy(srs_hijack_io_t ctx) 103 | { 104 | SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; 105 | srs_freep(skt); 106 | } 107 | int srs_hijack_io_create_socket(srs_hijack_io_t ctx) 108 | { 109 | SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; 110 | 111 | skt->fd = ::socket(AF_INET, SOCK_STREAM, 0); 112 | if (!SOCKET_VALID(skt->fd)) { 113 | return ERROR_SOCKET_CREATE; 114 | } 115 | 116 | return ERROR_SUCCESS; 117 | } 118 | int srs_hijack_io_connect(srs_hijack_io_t ctx, const char* server_ip, int port) 119 | { 120 | SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; 121 | 122 | sockaddr_in addr; 123 | addr.sin_family = AF_INET; 124 | addr.sin_port = htons(port); 125 | addr.sin_addr.s_addr = inet_addr(server_ip); 126 | 127 | if(::connect(skt->fd, (const struct sockaddr*)&addr, sizeof(sockaddr_in)) < 0){ 128 | return ERROR_SOCKET_CONNECT; 129 | } 130 | 131 | return ERROR_SUCCESS; 132 | } 133 | int srs_hijack_io_read(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread) 134 | { 135 | SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; 136 | 137 | int ret = ERROR_SUCCESS; 138 | 139 | ssize_t nb_read = ::recv(skt->fd, (char*)buf, size, 0); 140 | 141 | if (nread) { 142 | *nread = nb_read; 143 | } 144 | 145 | // On success a non-negative integer indicating the number of bytes actually read is returned 146 | // (a value of 0 means the network connection is closed or end of file is reached). 147 | if (nb_read <= 0) { 148 | if (nb_read < 0 && SOCKET_ERRNO() == SOCKET_ETIME) { 149 | return ERROR_SOCKET_TIMEOUT; 150 | } 151 | 152 | if (nb_read == 0) { 153 | errno = SOCKET_ECONNRESET; 154 | } 155 | 156 | return ERROR_SOCKET_READ; 157 | } 158 | 159 | skt->recv_bytes += nb_read; 160 | 161 | return ret; 162 | } 163 | void srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t timeout_us) 164 | { 165 | SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; 166 | skt->recv_timeout = timeout_us; 167 | } 168 | int64_t srs_hijack_io_get_recv_timeout(srs_hijack_io_t ctx) 169 | { 170 | SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; 171 | return skt->recv_timeout; 172 | } 173 | int64_t srs_hijack_io_get_recv_bytes(srs_hijack_io_t ctx) 174 | { 175 | SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; 176 | return skt->recv_bytes; 177 | } 178 | void srs_hijack_io_set_send_timeout(srs_hijack_io_t ctx, int64_t timeout_us) 179 | { 180 | SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; 181 | skt->send_timeout = timeout_us; 182 | } 183 | int64_t srs_hijack_io_get_send_timeout(srs_hijack_io_t ctx) 184 | { 185 | SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; 186 | return skt->send_timeout; 187 | } 188 | int64_t srs_hijack_io_get_send_bytes(srs_hijack_io_t ctx) 189 | { 190 | SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; 191 | return skt->send_bytes; 192 | } 193 | int srs_hijack_io_writev(srs_hijack_io_t ctx, const iovec *iov, int iov_size, ssize_t* nwrite) 194 | { 195 | SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; 196 | 197 | int ret = ERROR_SUCCESS; 198 | 199 | ssize_t nb_write = ::writev(skt->fd, iov, iov_size); 200 | 201 | if (nwrite) { 202 | *nwrite = nb_write; 203 | } 204 | 205 | // On success, the readv() function returns the number of bytes read; 206 | // the writev() function returns the number of bytes written. On error, -1 is 207 | // returned, and errno is set appropriately. 208 | if (nb_write <= 0) { 209 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/200 210 | if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) { 211 | return ERROR_SOCKET_TIMEOUT; 212 | } 213 | 214 | return ERROR_SOCKET_WRITE; 215 | } 216 | 217 | skt->send_bytes += nb_write; 218 | 219 | return ret; 220 | } 221 | bool srs_hijack_io_is_never_timeout(srs_hijack_io_t ctx, int64_t timeout_us) 222 | { 223 | return timeout_us == (int64_t)ST_UTIME_NO_TIMEOUT; 224 | } 225 | int srs_hijack_io_read_fully(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread) 226 | { 227 | SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; 228 | 229 | int ret = ERROR_SUCCESS; 230 | 231 | size_t left = size; 232 | ssize_t nb_read = 0; 233 | 234 | while (left > 0) { 235 | char* this_buf = (char*)buf + nb_read; 236 | ssize_t this_nread; 237 | 238 | if ((ret = srs_hijack_io_read(ctx, this_buf, left, &this_nread)) != ERROR_SUCCESS) { 239 | return ret; 240 | } 241 | 242 | nb_read += this_nread; 243 | left -= (size_t)this_nread; 244 | } 245 | 246 | if (nread) { 247 | *nread = nb_read; 248 | } 249 | skt->recv_bytes += nb_read; 250 | 251 | return ret; 252 | } 253 | int srs_hijack_io_write(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nwrite) 254 | { 255 | SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; 256 | 257 | int ret = ERROR_SUCCESS; 258 | 259 | ssize_t nb_write = ::send(skt->fd, (char*)buf, size, 0); 260 | 261 | if (nwrite) { 262 | *nwrite = nb_write; 263 | } 264 | 265 | if (nb_write <= 0) { 266 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/200 267 | if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) { 268 | return ERROR_SOCKET_TIMEOUT; 269 | } 270 | 271 | return ERROR_SOCKET_WRITE; 272 | } 273 | 274 | skt->send_bytes += nb_write; 275 | 276 | return ret; 277 | } 278 | #endif 279 | 280 | SimpleSocketStream::SimpleSocketStream() 281 | { 282 | io = srs_hijack_io_create(); 283 | } 284 | 285 | SimpleSocketStream::~SimpleSocketStream() 286 | { 287 | if (io) { 288 | srs_hijack_io_destroy(io); 289 | io = NULL; 290 | } 291 | } 292 | 293 | srs_hijack_io_t SimpleSocketStream::hijack_io() 294 | { 295 | return io; 296 | } 297 | 298 | int SimpleSocketStream::create_socket() 299 | { 300 | srs_assert(io); 301 | return srs_hijack_io_create_socket(io); 302 | } 303 | 304 | int SimpleSocketStream::connect(const char* server_ip, int port) 305 | { 306 | srs_assert(io); 307 | return srs_hijack_io_connect(io, server_ip, port); 308 | } 309 | 310 | // ISrsBufferReader 311 | int SimpleSocketStream::read(void* buf, size_t size, ssize_t* nread) 312 | { 313 | srs_assert(io); 314 | return srs_hijack_io_read(io, buf, size, nread); 315 | } 316 | 317 | // ISrsProtocolReader 318 | void SimpleSocketStream::set_recv_timeout(int64_t timeout_us) 319 | { 320 | srs_assert(io); 321 | srs_hijack_io_set_recv_timeout(io, timeout_us); 322 | } 323 | 324 | int64_t SimpleSocketStream::get_recv_timeout() 325 | { 326 | srs_assert(io); 327 | return srs_hijack_io_get_recv_timeout(io); 328 | } 329 | 330 | int64_t SimpleSocketStream::get_recv_bytes() 331 | { 332 | srs_assert(io); 333 | return srs_hijack_io_get_recv_bytes(io); 334 | } 335 | 336 | // ISrsProtocolWriter 337 | void SimpleSocketStream::set_send_timeout(int64_t timeout_us) 338 | { 339 | srs_assert(io); 340 | srs_hijack_io_set_send_timeout(io, timeout_us); 341 | } 342 | 343 | int64_t SimpleSocketStream::get_send_timeout() 344 | { 345 | srs_assert(io); 346 | return srs_hijack_io_get_send_timeout(io); 347 | } 348 | 349 | int64_t SimpleSocketStream::get_send_bytes() 350 | { 351 | srs_assert(io); 352 | return srs_hijack_io_get_send_bytes(io); 353 | } 354 | 355 | int SimpleSocketStream::writev(const iovec *iov, int iov_size, ssize_t* nwrite) 356 | { 357 | srs_assert(io); 358 | return srs_hijack_io_writev(io, iov, iov_size, nwrite); 359 | } 360 | 361 | // ISrsProtocolReaderWriter 362 | bool SimpleSocketStream::is_never_timeout(int64_t timeout_us) 363 | { 364 | srs_assert(io); 365 | return srs_hijack_io_is_never_timeout(io, timeout_us); 366 | } 367 | 368 | int SimpleSocketStream::read_fully(void* buf, size_t size, ssize_t* nread) 369 | { 370 | srs_assert(io); 371 | return srs_hijack_io_read_fully(io, buf, size, nread); 372 | } 373 | 374 | int SimpleSocketStream::write(void* buf, size_t size, ssize_t* nwrite) 375 | { 376 | srs_assert(io); 377 | return srs_hijack_io_write(io, buf, size, nwrite); 378 | } 379 | 380 | 381 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_lib_simple_socket.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_SIMPLE_SOCKET_HPP 25 | #define SRS_LIB_SIMPLE_SOCKET_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | #include 34 | #include 35 | 36 | // for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213 37 | #ifndef _WIN32 38 | #define SOCKET int 39 | #endif 40 | 41 | /** 42 | * simple socket stream, 43 | * use tcp socket, sync block mode, for client like srs-librtmp. 44 | */ 45 | class SimpleSocketStream : public ISrsProtocolReaderWriter 46 | { 47 | private: 48 | srs_hijack_io_t io; 49 | public: 50 | SimpleSocketStream(); 51 | virtual ~SimpleSocketStream(); 52 | public: 53 | virtual srs_hijack_io_t hijack_io(); 54 | virtual int create_socket(); 55 | virtual int connect(const char* server, int port); 56 | // ISrsBufferReader 57 | public: 58 | virtual int read(void* buf, size_t size, ssize_t* nread); 59 | // ISrsProtocolReader 60 | public: 61 | virtual void set_recv_timeout(int64_t timeout_us); 62 | virtual int64_t get_recv_timeout(); 63 | virtual int64_t get_recv_bytes(); 64 | // ISrsProtocolWriter 65 | public: 66 | virtual void set_send_timeout(int64_t timeout_us); 67 | virtual int64_t get_send_timeout(); 68 | virtual int64_t get_send_bytes(); 69 | virtual int writev(const iovec *iov, int iov_size, ssize_t* nwrite); 70 | // ISrsProtocolReaderWriter 71 | public: 72 | virtual bool is_never_timeout(int64_t timeout_us); 73 | virtual int read_fully(void* buf, size_t size, ssize_t* nread); 74 | virtual int write(void* buf, size_t size, ssize_t* nwrite); 75 | }; 76 | 77 | #endif 78 | 79 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_raw_avc.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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 | #include 25 | 26 | #include 27 | using namespace std; 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | SrsRawH264Stream::SrsRawH264Stream() 37 | { 38 | } 39 | 40 | SrsRawH264Stream::~SrsRawH264Stream() 41 | { 42 | } 43 | 44 | int SrsRawH264Stream::annexb_demux(SrsStream* stream, char** pframe, int* pnb_frame) 45 | { 46 | int ret = ERROR_SUCCESS; 47 | 48 | *pframe = NULL; 49 | *pnb_frame = 0; 50 | 51 | while (!stream->empty()) { 52 | // each frame must prefixed by annexb format. 53 | // about annexb, @see H.264-AVC-ISO_IEC_14496-10.pdf, page 211. 54 | int pnb_start_code = 0; 55 | if (!srs_avc_startswith_annexb(stream, &pnb_start_code)) { 56 | return ERROR_H264_API_NO_PREFIXED; 57 | } 58 | int start = stream->pos() + pnb_start_code; 59 | 60 | // find the last frame prefixed by annexb format. 61 | stream->skip(pnb_start_code); 62 | while (!stream->empty()) { 63 | if (srs_avc_startswith_annexb(stream, NULL)) { 64 | break; 65 | } 66 | stream->skip(1); 67 | } 68 | 69 | // demux the frame. 70 | *pnb_frame = stream->pos() - start; 71 | *pframe = stream->data() + start; 72 | break; 73 | } 74 | 75 | return ret; 76 | } 77 | 78 | bool SrsRawH264Stream::is_sps(char* frame, int nb_frame) 79 | { 80 | srs_assert(nb_frame > 0); 81 | 82 | // 5bits, 7.3.1 NAL unit syntax, 83 | // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. 84 | // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame 85 | u_int8_t nal_unit_type = (char)frame[0] & 0x1f; 86 | 87 | return nal_unit_type == 7; 88 | } 89 | 90 | bool SrsRawH264Stream::is_pps(char* frame, int nb_frame) 91 | { 92 | srs_assert(nb_frame > 0); 93 | 94 | // 5bits, 7.3.1 NAL unit syntax, 95 | // H.264-AVC-ISO_IEC_14496-10.pdf, page 44. 96 | // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame 97 | u_int8_t nal_unit_type = (char)frame[0] & 0x1f; 98 | 99 | return nal_unit_type == 8; 100 | } 101 | 102 | int SrsRawH264Stream::sps_demux(char* frame, int nb_frame, string& sps) 103 | { 104 | int ret = ERROR_SUCCESS; 105 | 106 | // atleast 1bytes for SPS to decode the type, profile, constrain and level. 107 | if (nb_frame < 4) { 108 | return ret; 109 | } 110 | 111 | sps = ""; 112 | if (nb_frame > 0) { 113 | sps.append(frame, nb_frame); 114 | } 115 | 116 | // should never be empty. 117 | if (sps.empty()) { 118 | return ERROR_STREAM_CASTER_AVC_SPS; 119 | } 120 | 121 | return ret; 122 | } 123 | 124 | int SrsRawH264Stream::pps_demux(char* frame, int nb_frame, string& pps) 125 | { 126 | int ret = ERROR_SUCCESS; 127 | 128 | pps = ""; 129 | if (nb_frame > 0) { 130 | pps.append(frame, nb_frame); 131 | } 132 | 133 | // should never be empty. 134 | if (pps.empty()) { 135 | return ERROR_STREAM_CASTER_AVC_PPS; 136 | } 137 | 138 | return ret; 139 | } 140 | 141 | int SrsRawH264Stream::mux_sequence_header(string sps, string pps, u_int32_t dts, u_int32_t pts, string& sh) 142 | { 143 | int ret = ERROR_SUCCESS; 144 | 145 | // 5bytes sps/pps header: 146 | // configurationVersion, AVCProfileIndication, profile_compatibility, 147 | // AVCLevelIndication, lengthSizeMinusOne 148 | // 3bytes size of sps: 149 | // numOfSequenceParameterSets, sequenceParameterSetLength(2B) 150 | // Nbytes of sps. 151 | // sequenceParameterSetNALUnit 152 | // 3bytes size of pps: 153 | // numOfPictureParameterSets, pictureParameterSetLength 154 | // Nbytes of pps: 155 | // pictureParameterSetNALUnit 156 | int nb_packet = 5 157 | + 3 + (int)sps.length() 158 | + 3 + (int)pps.length(); 159 | char* packet = new char[nb_packet]; 160 | SrsAutoFree(char, packet); 161 | 162 | // use stream to generate the h264 packet. 163 | SrsStream stream; 164 | if ((ret = stream.initialize(packet, nb_packet)) != ERROR_SUCCESS) { 165 | return ret; 166 | } 167 | 168 | // decode the SPS: 169 | // @see: 7.3.2.1.1, H.264-AVC-ISO_IEC_14496-10-2012.pdf, page 62 170 | if (true) { 171 | srs_assert((int)sps.length() >= 4); 172 | char* frame = (char*)sps.data(); 173 | 174 | // @see: Annex A Profiles and levels, H.264-AVC-ISO_IEC_14496-10.pdf, page 205 175 | // Baseline profile profile_idc is 66(0x42). 176 | // Main profile profile_idc is 77(0x4d). 177 | // Extended profile profile_idc is 88(0x58). 178 | u_int8_t profile_idc = frame[1]; 179 | //u_int8_t constraint_set = frame[2]; 180 | u_int8_t level_idc = frame[3]; 181 | 182 | // generate the sps/pps header 183 | // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16 184 | // configurationVersion 185 | stream.write_1bytes(0x01); 186 | // AVCProfileIndication 187 | stream.write_1bytes(profile_idc); 188 | // profile_compatibility 189 | stream.write_1bytes(0x00); 190 | // AVCLevelIndication 191 | stream.write_1bytes(level_idc); 192 | // lengthSizeMinusOne, or NAL_unit_length, always use 4bytes size, 193 | // so we always set it to 0x03. 194 | stream.write_1bytes(0x03); 195 | } 196 | 197 | // sps 198 | if (true) { 199 | // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16 200 | // numOfSequenceParameterSets, always 1 201 | stream.write_1bytes(0x01); 202 | // sequenceParameterSetLength 203 | stream.write_2bytes(sps.length()); 204 | // sequenceParameterSetNALUnit 205 | stream.write_string(sps); 206 | } 207 | 208 | // pps 209 | if (true) { 210 | // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16 211 | // numOfPictureParameterSets, always 1 212 | stream.write_1bytes(0x01); 213 | // pictureParameterSetLength 214 | stream.write_2bytes(pps.length()); 215 | // pictureParameterSetNALUnit 216 | stream.write_string(pps); 217 | } 218 | 219 | // TODO: FIXME: for more profile. 220 | // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16 221 | // profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 144 222 | 223 | sh = ""; 224 | sh.append(packet, nb_packet); 225 | 226 | return ret; 227 | } 228 | 229 | int SrsRawH264Stream::mux_ipb_frame(char* frame, int nb_frame, string& ibp) 230 | { 231 | int ret = ERROR_SUCCESS; 232 | 233 | // 4bytes size of nalu: 234 | // NALUnitLength 235 | // Nbytes of nalu. 236 | // NALUnit 237 | int nb_packet = 4 + nb_frame; 238 | char* packet = new char[nb_packet]; 239 | SrsAutoFree(char, packet); 240 | 241 | // use stream to generate the h264 packet. 242 | SrsStream stream; 243 | if ((ret = stream.initialize(packet, nb_packet)) != ERROR_SUCCESS) { 244 | return ret; 245 | } 246 | 247 | // 5.3.4.2.1 Syntax, H.264-AVC-ISO_IEC_14496-15.pdf, page 16 248 | // lengthSizeMinusOne, or NAL_unit_length, always use 4bytes size 249 | u_int32_t NAL_unit_length = nb_frame; 250 | 251 | // mux the avc NALU in "ISO Base Media File Format" 252 | // from H.264-AVC-ISO_IEC_14496-15.pdf, page 20 253 | // NALUnitLength 254 | stream.write_4bytes(NAL_unit_length); 255 | // NALUnit 256 | stream.write_bytes(frame, nb_frame); 257 | 258 | ibp = ""; 259 | ibp.append(packet, nb_packet); 260 | 261 | return ret; 262 | } 263 | 264 | int SrsRawH264Stream::mux_avc2flv(string video, int8_t frame_type, int8_t avc_packet_type, u_int32_t dts, u_int32_t pts, char** flv, int* nb_flv) 265 | { 266 | int ret = ERROR_SUCCESS; 267 | 268 | // for h264 in RTMP video payload, there is 5bytes header: 269 | // 1bytes, FrameType | CodecID 270 | // 1bytes, AVCPacketType 271 | // 3bytes, CompositionTime, the cts. 272 | // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78 273 | int size = (int)video.length() + 5; 274 | char* data = new char[size]; 275 | char* p = data; 276 | 277 | // @see: E.4.3 Video Tags, video_file_format_spec_v10_1.pdf, page 78 278 | // Frame Type, Type of video frame. 279 | // CodecID, Codec Identifier. 280 | // set the rtmp header 281 | *p++ = (frame_type << 4) | SrsCodecVideoAVC; 282 | 283 | // AVCPacketType 284 | *p++ = avc_packet_type; 285 | 286 | // CompositionTime 287 | // pts = dts + cts, or 288 | // cts = pts - dts. 289 | // where cts is the header in rtmp video packet payload header. 290 | u_int32_t cts = pts - dts; 291 | char* pp = (char*)&cts; 292 | *p++ = pp[2]; 293 | *p++ = pp[1]; 294 | *p++ = pp[0]; 295 | 296 | // h.264 raw data. 297 | memcpy(p, video.data(), video.length()); 298 | 299 | *flv = data; 300 | *nb_flv = size; 301 | 302 | return ret; 303 | } 304 | 305 | SrsRawAacStream::SrsRawAacStream() 306 | { 307 | } 308 | 309 | SrsRawAacStream::~SrsRawAacStream() 310 | { 311 | } 312 | 313 | int SrsRawAacStream::adts_demux(SrsStream* stream, char** pframe, int* pnb_frame, SrsRawAacStreamCodec& codec) 314 | { 315 | int ret = ERROR_SUCCESS; 316 | 317 | while (!stream->empty()) { 318 | int adts_header_start = stream->pos(); 319 | 320 | // decode the ADTS. 321 | // @see aac-iso-13818-7.pdf, page 26 322 | // 6.2 Audio Data Transport Stream, ADTS 323 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64145885 324 | // byte_alignment() 325 | 326 | // adts_fixed_header: 327 | // 12bits syncword, 328 | // 16bits left. 329 | // adts_variable_header: 330 | // 28bits 331 | // 12+16+28=56bits 332 | // adts_error_check: 333 | // 16bits if protection_absent 334 | // 56+16=72bits 335 | // if protection_absent: 336 | // require(7bytes)=56bits 337 | // else 338 | // require(9bytes)=72bits 339 | if (!stream->require(7)) { 340 | return ERROR_AAC_ADTS_HEADER; 341 | } 342 | 343 | // for aac, the frame must be ADTS format. 344 | if (!srs_aac_startswith_adts(stream)) { 345 | return ERROR_AAC_REQUIRED_ADTS; 346 | } 347 | 348 | // syncword 12 bslbf 349 | stream->read_1bytes(); 350 | // 4bits left. 351 | // adts_fixed_header(), 1.A.2.2.1 Fixed Header of ADTS 352 | // ID 1 bslbf 353 | // layer 2 uimsbf 354 | // protection_absent 1 bslbf 355 | int8_t pav = (stream->read_1bytes() & 0x0f); 356 | int8_t id = (pav >> 3) & 0x01; 357 | /*int8_t layer = (pav >> 1) & 0x03;*/ 358 | int8_t protection_absent = pav & 0x01; 359 | 360 | /** 361 | * ID: MPEG identifier, set to ‘1’ if the audio data in the ADTS stream are MPEG-2 AAC (See ISO/IEC 13818-7) 362 | * and set to ‘0’ if the audio data are MPEG-4. See also ISO/IEC 11172-3, subclause 2.4.2.3. 363 | */ 364 | if (id != 0x01) { 365 | srs_info("adts: id must be 1(aac), actual 0(mp4a). ret=%d", ret); 366 | 367 | // well, some system always use 0, but actually is aac format. 368 | // for example, houjian vod ts always set the aac id to 0, actually 1. 369 | // we just ignore it, and alwyas use 1(aac) to demux. 370 | id = 0x01; 371 | } 372 | 373 | int16_t sfiv = stream->read_2bytes(); 374 | // profile 2 uimsbf 375 | // sampling_frequency_index 4 uimsbf 376 | // private_bit 1 bslbf 377 | // channel_configuration 3 uimsbf 378 | // original/copy 1 bslbf 379 | // home 1 bslbf 380 | int8_t profile = (sfiv >> 14) & 0x03; 381 | int8_t sampling_frequency_index = (sfiv >> 10) & 0x0f; 382 | /*int8_t private_bit = (sfiv >> 9) & 0x01;*/ 383 | int8_t channel_configuration = (sfiv >> 6) & 0x07; 384 | /*int8_t original = (sfiv >> 5) & 0x01;*/ 385 | /*int8_t home = (sfiv >> 4) & 0x01;*/ 386 | //int8_t Emphasis; @remark, Emphasis is removed, @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64154736 387 | // 4bits left. 388 | // adts_variable_header(), 1.A.2.2.2 Variable Header of ADTS 389 | // copyright_identification_bit 1 bslbf 390 | // copyright_identification_start 1 bslbf 391 | /*int8_t fh_copyright_identification_bit = (fh1 >> 3) & 0x01;*/ 392 | /*int8_t fh_copyright_identification_start = (fh1 >> 2) & 0x01;*/ 393 | // frame_length 13 bslbf: Length of the frame including headers and error_check in bytes. 394 | // use the left 2bits as the 13 and 12 bit, 395 | // the frame_length is 13bits, so we move 13-2=11. 396 | int16_t frame_length = (sfiv << 11) & 0x1800; 397 | 398 | int32_t abfv = stream->read_3bytes(); 399 | // frame_length 13 bslbf: consume the first 13-2=11bits 400 | // the fh2 is 24bits, so we move right 24-11=13. 401 | frame_length |= (abfv >> 13) & 0x07ff; 402 | // adts_buffer_fullness 11 bslbf 403 | /*int16_t fh_adts_buffer_fullness = (abfv >> 2) & 0x7ff;*/ 404 | // number_of_raw_data_blocks_in_frame 2 uimsbf 405 | /*int16_t number_of_raw_data_blocks_in_frame = abfv & 0x03;*/ 406 | // adts_error_check(), 1.A.2.2.3 Error detection 407 | if (!protection_absent) { 408 | if (!stream->require(2)) { 409 | return ERROR_AAC_ADTS_HEADER; 410 | } 411 | // crc_check 16 Rpchof 412 | /*int16_t crc_check = */stream->read_2bytes(); 413 | } 414 | 415 | // TODO: check the sampling_frequency_index 416 | // TODO: check the channel_configuration 417 | 418 | // raw_data_blocks 419 | int adts_header_size = stream->pos() - adts_header_start; 420 | int raw_data_size = frame_length - adts_header_size; 421 | if (!stream->require(raw_data_size)) { 422 | return ERROR_AAC_ADTS_HEADER; 423 | } 424 | 425 | // the codec info. 426 | codec.protection_absent = protection_absent; 427 | codec.aac_object = srs_codec_aac_ts2rtmp((SrsAacProfile)profile); 428 | codec.sampling_frequency_index = sampling_frequency_index; 429 | codec.channel_configuration = channel_configuration; 430 | codec.frame_length = frame_length; 431 | 432 | // @see srs_audio_write_raw_frame(). 433 | // TODO: FIXME: maybe need to resample audio. 434 | codec.sound_format = 10; // AAC 435 | if (sampling_frequency_index <= 0x0c && sampling_frequency_index > 0x0a) { 436 | codec.sound_rate = SrsCodecAudioSampleRate5512; 437 | } else if (sampling_frequency_index <= 0x0a && sampling_frequency_index > 0x07) { 438 | codec.sound_rate = SrsCodecAudioSampleRate11025; 439 | } else if (sampling_frequency_index <= 0x07 && sampling_frequency_index > 0x04) { 440 | codec.sound_rate = SrsCodecAudioSampleRate22050; 441 | } else if (sampling_frequency_index <= 0x04) { 442 | codec.sound_rate = SrsCodecAudioSampleRate44100; 443 | } else { 444 | codec.sound_rate = SrsCodecAudioSampleRate44100; 445 | srs_warn("adts invalid sample rate for flv, rate=%#x", sampling_frequency_index); 446 | } 447 | codec.sound_type = srs_max(0, srs_min(1, channel_configuration - 1)); 448 | // TODO: FIXME: finger it out the sound size by adts. 449 | codec.sound_size = 1; // 0(8bits) or 1(16bits). 450 | 451 | // frame data. 452 | *pframe = stream->data() + stream->pos(); 453 | *pnb_frame = raw_data_size; 454 | stream->skip(raw_data_size); 455 | 456 | break; 457 | } 458 | 459 | return ret; 460 | } 461 | 462 | int SrsRawAacStream::mux_sequence_header(SrsRawAacStreamCodec* codec, string& sh) 463 | { 464 | int ret = ERROR_SUCCESS; 465 | 466 | // only support aac profile 1-4. 467 | if (codec->aac_object == SrsAacObjectTypeReserved) { 468 | return ERROR_AAC_DATA_INVALID; 469 | } 470 | 471 | SrsAacObjectType audioObjectType = codec->aac_object; 472 | char channelConfiguration = codec->channel_configuration; 473 | char samplingFrequencyIndex = codec->sampling_frequency_index; 474 | 475 | // override the aac samplerate by user specified. 476 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/212#issuecomment-64146899 477 | switch (codec->sound_rate) { 478 | case SrsCodecAudioSampleRate11025: 479 | samplingFrequencyIndex = 0x0a; break; 480 | case SrsCodecAudioSampleRate22050: 481 | samplingFrequencyIndex = 0x07; break; 482 | case SrsCodecAudioSampleRate44100: 483 | samplingFrequencyIndex = 0x04; break; 484 | default: 485 | break; 486 | } 487 | 488 | sh = ""; 489 | 490 | char ch = 0; 491 | // @see aac-mp4a-format-ISO_IEC_14496-3+2001.pdf 492 | // AudioSpecificConfig (), page 33 493 | // 1.6.2.1 AudioSpecificConfig 494 | // audioObjectType; 5 bslbf 495 | ch = (audioObjectType << 3) & 0xf8; 496 | // 3bits left. 497 | 498 | // samplingFrequencyIndex; 4 bslbf 499 | ch |= (samplingFrequencyIndex >> 1) & 0x07; 500 | sh += ch; 501 | ch = (samplingFrequencyIndex << 7) & 0x80; 502 | if (samplingFrequencyIndex == 0x0f) { 503 | return ERROR_AAC_DATA_INVALID; 504 | } 505 | // 7bits left. 506 | 507 | // channelConfiguration; 4 bslbf 508 | ch |= (channelConfiguration << 3) & 0x78; 509 | // 3bits left. 510 | 511 | // GASpecificConfig(), page 451 512 | // 4.4.1 Decoder configuration (GASpecificConfig) 513 | // frameLengthFlag; 1 bslbf 514 | // dependsOnCoreCoder; 1 bslbf 515 | // extensionFlag; 1 bslbf 516 | sh += ch; 517 | 518 | return ret; 519 | } 520 | 521 | int SrsRawAacStream::mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec* codec, u_int32_t dts, char** flv, int* nb_flv) 522 | { 523 | int ret = ERROR_SUCCESS; 524 | 525 | char sound_format = codec->sound_format; 526 | char sound_type = codec->sound_type; 527 | char sound_size = codec->sound_size; 528 | char sound_rate = codec->sound_rate; 529 | char aac_packet_type = codec->aac_packet_type; 530 | 531 | // for audio frame, there is 1 or 2 bytes header: 532 | // 1bytes, SoundFormat|SoundRate|SoundSize|SoundType 533 | // 1bytes, AACPacketType for SoundFormat == 10, 0 is sequence header. 534 | int size = nb_frame + 1; 535 | if (sound_format == SrsCodecAudioAAC) { 536 | size += 1; 537 | } 538 | char* data = new char[size]; 539 | char* p = data; 540 | 541 | u_int8_t audio_header = sound_type & 0x01; 542 | audio_header |= (sound_size << 1) & 0x02; 543 | audio_header |= (sound_rate << 2) & 0x0c; 544 | audio_header |= (sound_format << 4) & 0xf0; 545 | 546 | *p++ = audio_header; 547 | 548 | if (sound_format == SrsCodecAudioAAC) { 549 | *p++ = aac_packet_type; 550 | } 551 | 552 | memcpy(p, frame, nb_frame); 553 | 554 | *flv = data; 555 | *nb_flv = size; 556 | 557 | return ret; 558 | } 559 | 560 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_raw_avc.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_PROTOCOL_RAW_AVC_HPP 25 | #define SRS_PROTOCOL_RAW_AVC_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | #include 34 | 35 | #include 36 | 37 | class SrsStream; 38 | 39 | /** 40 | * the raw h.264 stream, in annexb. 41 | */ 42 | class SrsRawH264Stream 43 | { 44 | public: 45 | SrsRawH264Stream(); 46 | virtual ~SrsRawH264Stream(); 47 | public: 48 | /** 49 | * demux the stream in annexb format. 50 | * @param stream the input stream bytes. 51 | * @param pframe the output h.264 frame in stream. user should never free it. 52 | * @param pnb_frame the output h.264 frame size. 53 | */ 54 | virtual int annexb_demux(SrsStream* stream, char** pframe, int* pnb_frame); 55 | /** 56 | * whether the frame is sps or pps. 57 | */ 58 | virtual bool is_sps(char* frame, int nb_frame); 59 | virtual bool is_pps(char* frame, int nb_frame); 60 | /** 61 | * demux the sps or pps to string. 62 | * @param sps/pps output the sps/pps. 63 | */ 64 | virtual int sps_demux(char* frame, int nb_frame, std::string& sps); 65 | virtual int pps_demux(char* frame, int nb_frame, std::string& pps); 66 | public: 67 | /** 68 | * h264 raw data to h264 packet, without flv payload header. 69 | * mux the sps/pps to flv sequence header packet. 70 | * @param sh output the sequence header. 71 | */ 72 | virtual int mux_sequence_header(std::string sps, std::string pps, u_int32_t dts, u_int32_t pts, std::string& sh); 73 | /** 74 | * h264 raw data to h264 packet, without flv payload header. 75 | * mux the ibp to flv ibp packet. 76 | * @param ibp output the packet. 77 | * @param frame_type output the frame type. 78 | */ 79 | virtual int mux_ipb_frame(char* frame, int nb_frame, std::string& ibp); 80 | /** 81 | * mux the avc video packet to flv video packet. 82 | * @param frame_type, SrsCodecVideoAVCFrameKeyFrame or SrsCodecVideoAVCFrameInterFrame. 83 | * @param avc_packet_type, SrsCodecVideoAVCTypeSequenceHeader or SrsCodecVideoAVCTypeNALU. 84 | * @param video the h.264 raw data. 85 | * @param flv output the muxed flv packet. 86 | * @param nb_flv output the muxed flv size. 87 | */ 88 | virtual int mux_avc2flv(std::string video, int8_t frame_type, int8_t avc_packet_type, u_int32_t dts, u_int32_t pts, char** flv, int* nb_flv); 89 | }; 90 | 91 | /** 92 | * the header of adts sample. 93 | */ 94 | struct SrsRawAacStreamCodec 95 | { 96 | int8_t protection_absent; 97 | SrsAacObjectType aac_object; 98 | int8_t sampling_frequency_index; 99 | int8_t channel_configuration; 100 | int16_t frame_length; 101 | 102 | char sound_format; 103 | char sound_rate; 104 | char sound_size; 105 | char sound_type; 106 | // 0 for sh; 1 for raw data. 107 | int8_t aac_packet_type; 108 | }; 109 | 110 | /** 111 | * the raw aac stream, in adts. 112 | */ 113 | class SrsRawAacStream 114 | { 115 | public: 116 | SrsRawAacStream(); 117 | virtual ~SrsRawAacStream(); 118 | public: 119 | /** 120 | * demux the stream in adts format. 121 | * @param stream the input stream bytes. 122 | * @param pframe the output aac frame in stream. user should never free it. 123 | * @param pnb_frame the output aac frame size. 124 | * @param codec the output codec info. 125 | */ 126 | virtual int adts_demux(SrsStream* stream, char** pframe, int* pnb_frame, SrsRawAacStreamCodec& codec); 127 | /** 128 | * aac raw data to aac packet, without flv payload header. 129 | * mux the aac specific config to flv sequence header packet. 130 | * @param sh output the sequence header. 131 | */ 132 | virtual int mux_sequence_header(SrsRawAacStreamCodec* codec, std::string& sh); 133 | /** 134 | * mux the aac audio packet to flv audio packet. 135 | * @param frame the aac raw data. 136 | * @param nb_frame the count of aac frame. 137 | * @param codec the codec info of aac. 138 | * @param flv output the muxed flv packet. 139 | * @param nb_flv output the muxed flv size. 140 | */ 141 | virtual int mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec* codec, u_int32_t dts, char** flv, int* nb_flv); 142 | }; 143 | 144 | #endif 145 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_rtmp_buffer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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 | #include 25 | 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | // the default recv buffer size, 128KB. 34 | #define SRS_DEFAULT_RECV_BUFFER_SIZE 131072 35 | 36 | // limit user-space buffer to 256KB, for 3Mbps stream delivery. 37 | // 800*2000/8=200000B(about 195KB). 38 | // @remark it's ok for higher stream, the buffer is ok for one chunk is 256KB. 39 | #define SRS_MAX_SOCKET_BUFFER 262144 40 | 41 | // the max header size, 42 | // @see SrsProtocol::read_message_header(). 43 | #define SRS_RTMP_MAX_MESSAGE_HEADER 11 44 | 45 | #ifdef SRS_PERF_MERGED_READ 46 | IMergeReadHandler::IMergeReadHandler() 47 | { 48 | } 49 | 50 | IMergeReadHandler::~IMergeReadHandler() 51 | { 52 | } 53 | #endif 54 | 55 | SrsFastBuffer::SrsFastBuffer() 56 | { 57 | #ifdef SRS_PERF_MERGED_READ 58 | merged_read = false; 59 | _handler = NULL; 60 | #endif 61 | 62 | nb_buffer = SRS_DEFAULT_RECV_BUFFER_SIZE; 63 | buffer = (char*)malloc(nb_buffer); 64 | p = end = buffer; 65 | } 66 | 67 | SrsFastBuffer::~SrsFastBuffer() 68 | { 69 | free(buffer); 70 | buffer = NULL; 71 | } 72 | 73 | int SrsFastBuffer::size() 74 | { 75 | return end - p; 76 | } 77 | 78 | char* SrsFastBuffer::bytes() 79 | { 80 | return p; 81 | } 82 | 83 | void SrsFastBuffer::set_buffer(int buffer_size) 84 | { 85 | // never exceed the max size. 86 | if (buffer_size > SRS_MAX_SOCKET_BUFFER) { 87 | srs_warn("limit the user-space buffer from %d to %d", 88 | buffer_size, SRS_MAX_SOCKET_BUFFER); 89 | } 90 | 91 | // the user-space buffer size limit to a max value. 92 | int nb_resize_buf = srs_min(buffer_size, SRS_MAX_SOCKET_BUFFER); 93 | 94 | // only realloc when buffer changed bigger 95 | if (nb_resize_buf <= nb_buffer) { 96 | return; 97 | } 98 | 99 | // realloc for buffer change bigger. 100 | int start = p - buffer; 101 | int nb_bytes = end - p; 102 | 103 | buffer = (char*)realloc(buffer, nb_resize_buf); 104 | nb_buffer = nb_resize_buf; 105 | p = buffer + start; 106 | end = p + nb_bytes; 107 | } 108 | 109 | char SrsFastBuffer::read_1byte() 110 | { 111 | srs_assert(end - p >= 1); 112 | return *p++; 113 | } 114 | 115 | char* SrsFastBuffer::read_slice(int size) 116 | { 117 | srs_assert(end - p >= size); 118 | srs_assert(p + size > buffer); 119 | 120 | char* ptr = p; 121 | p += size; 122 | 123 | return ptr; 124 | } 125 | 126 | void SrsFastBuffer::skip(int size) 127 | { 128 | srs_assert(end - p >= size); 129 | srs_assert(p + size > buffer); 130 | p += size; 131 | } 132 | 133 | int SrsFastBuffer::grow(ISrsBufferReader* reader, int required_size) 134 | { 135 | int ret = ERROR_SUCCESS; 136 | 137 | // already got required size of bytes. 138 | if (end - p >= required_size) { 139 | return ret; 140 | } 141 | 142 | // must be positive. 143 | srs_assert(required_size > 0); 144 | 145 | // the free space of buffer, 146 | // buffer = consumed_bytes + exists_bytes + free_space. 147 | int nb_free_space = (int)(buffer + nb_buffer - end); 148 | // resize the space when no left space. 149 | if (nb_free_space < required_size) { 150 | // the bytes already in buffer 151 | int nb_exists_bytes = (int)(end - p); 152 | srs_assert(nb_exists_bytes >= 0); 153 | srs_verbose("move fast buffer %d bytes", nb_exists_bytes); 154 | 155 | // reset or move to get more space. 156 | if (!nb_exists_bytes) { 157 | // reset when buffer is empty. 158 | p = end = buffer; 159 | srs_verbose("all consumed, reset fast buffer"); 160 | } else { 161 | // move the left bytes to start of buffer. 162 | srs_assert(nb_exists_bytes < nb_buffer); 163 | buffer = (char*)memmove(buffer, p, nb_exists_bytes); 164 | p = buffer; 165 | end = p + nb_exists_bytes; 166 | } 167 | 168 | // check whether enough free space in buffer. 169 | nb_free_space = (int)(buffer + nb_buffer - end); 170 | if (nb_free_space < required_size) { 171 | ret = ERROR_READER_BUFFER_OVERFLOW; 172 | srs_error("buffer overflow, required=%d, max=%d, left=%d, ret=%d", 173 | required_size, nb_buffer, nb_free_space, ret); 174 | return ret; 175 | } 176 | } 177 | 178 | // buffer is ok, read required size of bytes. 179 | while (end - p < required_size) { 180 | ssize_t nread; 181 | if ((ret = reader->read(end, nb_free_space, &nread)) != ERROR_SUCCESS) { 182 | return ret; 183 | } 184 | 185 | #ifdef SRS_PERF_MERGED_READ 186 | /** 187 | * to improve read performance, merge some packets then read, 188 | * when it on and read small bytes, we sleep to wait more data., 189 | * that is, we merge some data to read together. 190 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 191 | */ 192 | if (merged_read && _handler) { 193 | _handler->on_read(nread); 194 | } 195 | #endif 196 | 197 | // we just move the ptr to next. 198 | srs_assert((int)nread > 0); 199 | end += nread; 200 | nb_free_space -= nread; 201 | } 202 | 203 | return ret; 204 | } 205 | 206 | #ifdef SRS_PERF_MERGED_READ 207 | void SrsFastBuffer::set_merge_read(bool v, IMergeReadHandler* handler) 208 | { 209 | merged_read = v; 210 | _handler = handler; 211 | } 212 | #endif 213 | 214 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_rtmp_buffer.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_PROTOCOL_BUFFER_HPP 25 | #define SRS_PROTOCOL_BUFFER_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | 37 | #ifdef SRS_PERF_MERGED_READ 38 | /** 39 | * to improve read performance, merge some packets then read, 40 | * when it on and read small bytes, we sleep to wait more data., 41 | * that is, we merge some data to read together. 42 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 43 | */ 44 | class IMergeReadHandler 45 | { 46 | public: 47 | IMergeReadHandler(); 48 | virtual ~IMergeReadHandler(); 49 | public: 50 | /** 51 | * when read from channel, notice the merge handler to sleep for 52 | * some small bytes. 53 | * @remark, it only for server-side, client srs-librtmp just ignore. 54 | */ 55 | virtual void on_read(ssize_t nread) = 0; 56 | }; 57 | #endif 58 | 59 | /** 60 | * the buffer provices bytes cache for protocol. generally, 61 | * protocol recv data from socket, put into buffer, decode to RTMP message. 62 | * Usage: 63 | * ISrsBufferReader* r = ......; 64 | * SrsFastBuffer* fb = ......; 65 | * fb->grow(r, 1024); 66 | * char* header = fb->read_slice(100); 67 | * char* payload = fb->read_payload(924); 68 | */ 69 | // TODO: FIXME: add utest for it. 70 | class SrsFastBuffer 71 | { 72 | private: 73 | #ifdef SRS_PERF_MERGED_READ 74 | // the merged handler 75 | bool merged_read; 76 | IMergeReadHandler* _handler; 77 | #endif 78 | // the user-space buffer to fill by reader, 79 | // which use fast index and reset when chunk body read ok. 80 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/248 81 | // ptr to the current read position. 82 | char* p; 83 | // ptr to the content end. 84 | char* end; 85 | // ptr to the buffer. 86 | // buffer <= p <= end <= buffer+nb_buffer 87 | char* buffer; 88 | // the size of buffer. 89 | int nb_buffer; 90 | public: 91 | SrsFastBuffer(); 92 | virtual ~SrsFastBuffer(); 93 | public: 94 | /** 95 | * get the size of current bytes in buffer. 96 | */ 97 | virtual int size(); 98 | /** 99 | * get the current bytes in buffer. 100 | * @remark user should use read_slice() if possible, 101 | * the bytes() is used to test bytes, for example, to detect the bytes schema. 102 | */ 103 | virtual char* bytes(); 104 | /** 105 | * create buffer with specifeid size. 106 | * @param buffer the size of buffer. ignore when smaller than SRS_MAX_SOCKET_BUFFER. 107 | * @remark when MR(SRS_PERF_MERGED_READ) disabled, always set to 8K. 108 | * @remark when buffer changed, the previous ptr maybe invalid. 109 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 110 | */ 111 | virtual void set_buffer(int buffer_size); 112 | public: 113 | /** 114 | * read 1byte from buffer, move to next bytes. 115 | * @remark assert buffer already grow(1). 116 | */ 117 | virtual char read_1byte(); 118 | /** 119 | * read a slice in size bytes, move to next bytes. 120 | * user can use this char* ptr directly, and should never free it. 121 | * @remark user can use the returned ptr util grow(size), 122 | * for the ptr returned maybe invalid after grow(x). 123 | */ 124 | virtual char* read_slice(int size); 125 | /** 126 | * skip some bytes in buffer. 127 | * @param size the bytes to skip. positive to next; negative to previous. 128 | * @remark assert buffer already grow(size). 129 | * @remark always use read_slice to consume bytes, which will reset for EOF. 130 | * while skip never consume bytes. 131 | */ 132 | virtual void skip(int size); 133 | public: 134 | /** 135 | * grow buffer to the required size, loop to read from skt to fill. 136 | * @param reader, read more bytes from reader to fill the buffer to required size. 137 | * @param required_size, loop to fill to ensure buffer size to required. 138 | * @return an int error code, error if required_size negative. 139 | * @remark, we actually maybe read more than required_size, maybe 4k for example. 140 | */ 141 | virtual int grow(ISrsBufferReader* reader, int required_size); 142 | public: 143 | #ifdef SRS_PERF_MERGED_READ 144 | /** 145 | * to improve read performance, merge some packets then read, 146 | * when it on and read small bytes, we sleep to wait more data., 147 | * that is, we merge some data to read together. 148 | * @param v true to ename merged read. 149 | * @param handler the handler when merge read is enabled. 150 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 151 | * @remark the merged read is optional, ignore if not specifies. 152 | */ 153 | virtual void set_merge_read(bool v, IMergeReadHandler* handler); 154 | #endif 155 | }; 156 | 157 | #endif 158 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_rtmp_handshake.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_RTMP_PROTOCOL_HANDSHKAE_HPP 25 | #define SRS_RTMP_PROTOCOL_HANDSHKAE_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | class ISrsProtocolReaderWriter; 34 | class SrsComplexHandshake; 35 | class SrsHandshakeBytes; 36 | class SrsStream; 37 | 38 | #ifdef SRS_AUTO_SSL 39 | 40 | // for openssl. 41 | #include 42 | 43 | namespace _srs_internal 44 | { 45 | // the digest key generate size. 46 | #define SRS_OpensslHashSize 512 47 | extern u_int8_t SrsGenuineFMSKey[]; 48 | extern u_int8_t SrsGenuineFPKey[]; 49 | int openssl_HMACsha256(const void* key, int key_size, const void* data, int data_size, void* digest); 50 | int openssl_generate_key(char* public_key, int32_t size); 51 | 52 | /** 53 | * the DH wrapper. 54 | */ 55 | class SrsDH 56 | { 57 | private: 58 | DH* pdh; 59 | public: 60 | SrsDH(); 61 | virtual ~SrsDH(); 62 | public: 63 | /** 64 | * initialize dh, generate the public and private key. 65 | * @param ensure_128bytes_public_key whether ensure public key is 128bytes, 66 | * sometimes openssl generate 127bytes public key. 67 | * default to false to donot ensure. 68 | */ 69 | virtual int initialize(bool ensure_128bytes_public_key = false); 70 | /** 71 | * copy the public key. 72 | * @param pkey the bytes to copy the public key. 73 | * @param pkey_size the max public key size, output the actual public key size. 74 | * user should never ignore this size. 75 | * @remark, when ensure_128bytes_public_key, the size always 128. 76 | */ 77 | virtual int copy_public_key(char* pkey, int32_t& pkey_size); 78 | /** 79 | * generate and copy the shared key. 80 | * generate the shared key with peer public key. 81 | * @param ppkey peer public key. 82 | * @param ppkey_size the size of ppkey. 83 | * @param skey the computed shared key. 84 | * @param skey_size the max shared key size, output the actual shared key size. 85 | * user should never ignore this size. 86 | */ 87 | virtual int copy_shared_key(const char* ppkey, int32_t ppkey_size, char* skey, int32_t& skey_size); 88 | private: 89 | virtual int do_initialize(); 90 | }; 91 | /** 92 | * the schema type. 93 | */ 94 | enum srs_schema_type 95 | { 96 | srs_schema_invalid = 2, 97 | 98 | /** 99 | * key-digest sequence 100 | */ 101 | srs_schema0 = 0, 102 | 103 | /** 104 | * digest-key sequence 105 | * @remark, FMS requires the schema1(digest-key), or connect failed. 106 | */ 107 | // 108 | srs_schema1 = 1, 109 | }; 110 | 111 | /** 112 | * 764bytes key structure 113 | * random-data: (offset)bytes 114 | * key-data: 128bytes 115 | * random-data: (764-offset-128-4)bytes 116 | * offset: 4bytes 117 | * @see also: http://blog.csdn.net/win_lin/article/details/13006803 118 | */ 119 | class key_block 120 | { 121 | public: 122 | // (offset)bytes 123 | char* random0; 124 | int random0_size; 125 | 126 | // 128bytes 127 | char key[128]; 128 | 129 | // (764-offset-128-4)bytes 130 | char* random1; 131 | int random1_size; 132 | 133 | // 4bytes 134 | int32_t offset; 135 | public: 136 | key_block(); 137 | virtual ~key_block(); 138 | public: 139 | // parse key block from c1s1. 140 | // if created, user must free it by srs_key_block_free 141 | // @stream contains c1s1_key_bytes the key start bytes 142 | int parse(SrsStream* stream); 143 | private: 144 | // calc the offset of key, 145 | // the key->offset cannot be used as the offset of key. 146 | int calc_valid_offset(); 147 | }; 148 | 149 | /** 150 | * 764bytes digest structure 151 | * offset: 4bytes 152 | * random-data: (offset)bytes 153 | * digest-data: 32bytes 154 | * random-data: (764-4-offset-32)bytes 155 | * @see also: http://blog.csdn.net/win_lin/article/details/13006803 156 | */ 157 | class digest_block 158 | { 159 | public: 160 | // 4bytes 161 | int32_t offset; 162 | 163 | // (offset)bytes 164 | char* random0; 165 | int random0_size; 166 | 167 | // 32bytes 168 | char digest[32]; 169 | 170 | // (764-4-offset-32)bytes 171 | char* random1; 172 | int random1_size; 173 | public: 174 | digest_block(); 175 | virtual ~digest_block(); 176 | public: 177 | // parse digest block from c1s1. 178 | // if created, user must free it by srs_digest_block_free 179 | // @stream contains c1s1_digest_bytes the digest start bytes 180 | int parse(SrsStream* stream); 181 | private: 182 | // calc the offset of digest, 183 | // the key->offset cannot be used as the offset of digest. 184 | int calc_valid_offset(); 185 | }; 186 | 187 | class c1s1; 188 | 189 | /** 190 | * the c1s1 strategy, use schema0 or schema1. 191 | * the template method class to defines common behaviors, 192 | * while the concrete class to implements in schema0 or schema1. 193 | */ 194 | class c1s1_strategy 195 | { 196 | protected: 197 | key_block key; 198 | digest_block digest; 199 | public: 200 | c1s1_strategy(); 201 | virtual ~c1s1_strategy(); 202 | public: 203 | /** 204 | * get the scema. 205 | */ 206 | virtual srs_schema_type schema() = 0; 207 | /** 208 | * get the digest. 209 | */ 210 | virtual char* get_digest(); 211 | /** 212 | * get the key. 213 | */ 214 | virtual char* get_key(); 215 | /** 216 | * copy to bytes. 217 | * @param size must be 1536. 218 | */ 219 | virtual int dump(c1s1* owner, char* _c1s1, int size); 220 | /** 221 | * server: parse the c1s1, discovery the key and digest by schema. 222 | * use the c1_validate_digest() to valid the digest of c1. 223 | */ 224 | virtual int parse(char* _c1s1, int size) = 0; 225 | public: 226 | /** 227 | * client: create and sign c1 by schema. 228 | * sign the c1, generate the digest. 229 | * calc_c1_digest(c1, schema) { 230 | * get c1s1-joined from c1 by specified schema 231 | * digest-data = HMACsha256(c1s1-joined, FPKey, 30) 232 | * return digest-data; 233 | * } 234 | * random fill 1536bytes c1 // also fill the c1-128bytes-key 235 | * time = time() // c1[0-3] 236 | * version = [0x80, 0x00, 0x07, 0x02] // c1[4-7] 237 | * schema = choose schema0 or schema1 238 | * digest-data = calc_c1_digest(c1, schema) 239 | * copy digest-data to c1 240 | */ 241 | virtual int c1_create(c1s1* owner); 242 | /** 243 | * server: validate the parsed c1 schema 244 | */ 245 | virtual int c1_validate_digest(c1s1* owner, bool& is_valid); 246 | /** 247 | * server: create and sign the s1 from c1. 248 | * // decode c1 try schema0 then schema1 249 | * c1-digest-data = get-c1-digest-data(schema0) 250 | * if c1-digest-data equals to calc_c1_digest(c1, schema0) { 251 | * c1-key-data = get-c1-key-data(schema0) 252 | * schema = schema0 253 | * } else { 254 | * c1-digest-data = get-c1-digest-data(schema1) 255 | * if c1-digest-data not equals to calc_c1_digest(c1, schema1) { 256 | * switch to simple handshake. 257 | * return 258 | * } 259 | * c1-key-data = get-c1-key-data(schema1) 260 | * schema = schema1 261 | * } 262 | * 263 | * // generate s1 264 | * random fill 1536bytes s1 265 | * time = time() // c1[0-3] 266 | * version = [0x04, 0x05, 0x00, 0x01] // s1[4-7] 267 | * s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data) 268 | * get c1s1-joined by specified schema 269 | * s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36) 270 | * copy s1-digest-data and s1-key-data to s1. 271 | * @param c1, to get the peer_pub_key of client. 272 | */ 273 | virtual int s1_create(c1s1* owner, c1s1* c1); 274 | /** 275 | * server: validate the parsed s1 schema 276 | */ 277 | virtual int s1_validate_digest(c1s1* owner, bool& is_valid); 278 | public: 279 | /** 280 | * calc the digest for c1 281 | */ 282 | virtual int calc_c1_digest(c1s1* owner, char*& c1_digest); 283 | /** 284 | * calc the digest for s1 285 | */ 286 | virtual int calc_s1_digest(c1s1* owner, char*& s1_digest); 287 | /** 288 | * copy whole c1s1 to bytes. 289 | * @param size must always be 1536 with digest, and 1504 without digest. 290 | */ 291 | virtual int copy_to(c1s1* owner, char* bytes, int size, bool with_digest) = 0; 292 | /** 293 | * copy time and version to stream. 294 | */ 295 | virtual void copy_time_version(SrsStream* stream, c1s1* owner); 296 | /** 297 | * copy key to stream. 298 | */ 299 | virtual void copy_key(SrsStream* stream); 300 | /** 301 | * copy digest to stream. 302 | */ 303 | virtual void copy_digest(SrsStream* stream, bool with_digest); 304 | }; 305 | 306 | /** 307 | * c1s1 schema0 308 | * key: 764bytes 309 | * digest: 764bytes 310 | */ 311 | class c1s1_strategy_schema0 : public c1s1_strategy 312 | { 313 | public: 314 | c1s1_strategy_schema0(); 315 | virtual ~c1s1_strategy_schema0(); 316 | public: 317 | virtual srs_schema_type schema(); 318 | virtual int parse(char* _c1s1, int size); 319 | public: 320 | virtual int copy_to(c1s1* owner, char* bytes, int size, bool with_digest); 321 | }; 322 | 323 | /** 324 | * c1s1 schema1 325 | * digest: 764bytes 326 | * key: 764bytes 327 | */ 328 | class c1s1_strategy_schema1 : public c1s1_strategy 329 | { 330 | public: 331 | c1s1_strategy_schema1(); 332 | virtual ~c1s1_strategy_schema1(); 333 | public: 334 | virtual srs_schema_type schema(); 335 | virtual int parse(char* _c1s1, int size); 336 | public: 337 | virtual int copy_to(c1s1* owner, char* bytes, int size, bool with_digest); 338 | }; 339 | 340 | /** 341 | * c1s1 schema0 342 | * time: 4bytes 343 | * version: 4bytes 344 | * key: 764bytes 345 | * digest: 764bytes 346 | * c1s1 schema1 347 | * time: 4bytes 348 | * version: 4bytes 349 | * digest: 764bytes 350 | * key: 764bytes 351 | * @see also: http://blog.csdn.net/win_lin/article/details/13006803 352 | */ 353 | class c1s1 354 | { 355 | public: 356 | // 4bytes 357 | int32_t time; 358 | // 4bytes 359 | int32_t version; 360 | // 764bytes+764bytes 361 | c1s1_strategy* payload; 362 | public: 363 | c1s1(); 364 | virtual ~c1s1(); 365 | public: 366 | /** 367 | * get the scema. 368 | */ 369 | virtual srs_schema_type schema(); 370 | /** 371 | * get the digest key. 372 | */ 373 | virtual char* get_digest(); 374 | /** 375 | * get the key. 376 | */ 377 | virtual char* get_key(); 378 | public: 379 | /** 380 | * copy to bytes. 381 | * @param size, must always be 1536. 382 | */ 383 | virtual int dump(char* _c1s1, int size); 384 | /** 385 | * server: parse the c1s1, discovery the key and digest by schema. 386 | * @param size, must always be 1536. 387 | * use the c1_validate_digest() to valid the digest of c1. 388 | * use the s1_validate_digest() to valid the digest of s1. 389 | */ 390 | virtual int parse(char* _c1s1, int size, srs_schema_type _schema); 391 | public: 392 | /** 393 | * client: create and sign c1 by schema. 394 | * sign the c1, generate the digest. 395 | * calc_c1_digest(c1, schema) { 396 | * get c1s1-joined from c1 by specified schema 397 | * digest-data = HMACsha256(c1s1-joined, FPKey, 30) 398 | * return digest-data; 399 | * } 400 | * random fill 1536bytes c1 // also fill the c1-128bytes-key 401 | * time = time() // c1[0-3] 402 | * version = [0x80, 0x00, 0x07, 0x02] // c1[4-7] 403 | * schema = choose schema0 or schema1 404 | * digest-data = calc_c1_digest(c1, schema) 405 | * copy digest-data to c1 406 | */ 407 | virtual int c1_create(srs_schema_type _schema); 408 | /** 409 | * server: validate the parsed c1 schema 410 | */ 411 | virtual int c1_validate_digest(bool& is_valid); 412 | public: 413 | /** 414 | * server: create and sign the s1 from c1. 415 | * // decode c1 try schema0 then schema1 416 | * c1-digest-data = get-c1-digest-data(schema0) 417 | * if c1-digest-data equals to calc_c1_digest(c1, schema0) { 418 | * c1-key-data = get-c1-key-data(schema0) 419 | * schema = schema0 420 | * } else { 421 | * c1-digest-data = get-c1-digest-data(schema1) 422 | * if c1-digest-data not equals to calc_c1_digest(c1, schema1) { 423 | * switch to simple handshake. 424 | * return 425 | * } 426 | * c1-key-data = get-c1-key-data(schema1) 427 | * schema = schema1 428 | * } 429 | * 430 | * // generate s1 431 | * random fill 1536bytes s1 432 | * time = time() // c1[0-3] 433 | * version = [0x04, 0x05, 0x00, 0x01] // s1[4-7] 434 | * s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data) 435 | * get c1s1-joined by specified schema 436 | * s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36) 437 | * copy s1-digest-data and s1-key-data to s1. 438 | */ 439 | virtual int s1_create(c1s1* c1); 440 | /** 441 | * server: validate the parsed s1 schema 442 | */ 443 | virtual int s1_validate_digest(bool& is_valid); 444 | }; 445 | 446 | /** 447 | * the c2s2 complex handshake structure. 448 | * random-data: 1504bytes 449 | * digest-data: 32bytes 450 | * @see also: http://blog.csdn.net/win_lin/article/details/13006803 451 | */ 452 | class c2s2 453 | { 454 | public: 455 | char random[1504]; 456 | char digest[32]; 457 | public: 458 | c2s2(); 459 | virtual ~c2s2(); 460 | public: 461 | /** 462 | * copy to bytes. 463 | * @param size, must always be 1536. 464 | */ 465 | virtual int dump(char* _c2s2, int size); 466 | /** 467 | * parse the c2s2 468 | * @param size, must always be 1536. 469 | */ 470 | virtual int parse(char* _c2s2, int size); 471 | public: 472 | /** 473 | * create c2. 474 | * random fill c2s2 1536 bytes 475 | * 476 | * // client generate C2, or server valid C2 477 | * temp-key = HMACsha256(s1-digest, FPKey, 62) 478 | * c2-digest-data = HMACsha256(c2-random-data, temp-key, 32) 479 | */ 480 | virtual int c2_create(c1s1* s1); 481 | 482 | /** 483 | * validate the c2 from client. 484 | */ 485 | virtual int c2_validate(c1s1* s1, bool& is_valid); 486 | public: 487 | /** 488 | * create s2. 489 | * random fill c2s2 1536 bytes 490 | * 491 | * // server generate S2, or client valid S2 492 | * temp-key = HMACsha256(c1-digest, FMSKey, 68) 493 | * s2-digest-data = HMACsha256(s2-random-data, temp-key, 32) 494 | */ 495 | virtual int s2_create(c1s1* c1); 496 | 497 | /** 498 | * validate the s2 from server. 499 | */ 500 | virtual int s2_validate(c1s1* c1, bool& is_valid); 501 | }; 502 | } 503 | 504 | #endif 505 | 506 | /** 507 | * simple handshake. 508 | * user can try complex handshake first, 509 | * rollback to simple handshake if error ERROR_RTMP_TRY_SIMPLE_HS 510 | */ 511 | class SrsSimpleHandshake 512 | { 513 | public: 514 | SrsSimpleHandshake(); 515 | virtual ~SrsSimpleHandshake(); 516 | public: 517 | /** 518 | * simple handshake. 519 | */ 520 | virtual int handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReaderWriter* io); 521 | virtual int handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReaderWriter* io); 522 | }; 523 | 524 | /** 525 | * rtmp complex handshake, 526 | * @see also crtmp(crtmpserver) or librtmp, 527 | * @see also: http://blog.csdn.net/win_lin/article/details/13006803 528 | */ 529 | class SrsComplexHandshake 530 | { 531 | public: 532 | SrsComplexHandshake(); 533 | virtual ~SrsComplexHandshake(); 534 | public: 535 | /** 536 | * complex hanshake. 537 | * @return user must: 538 | * continue connect app if success, 539 | * try simple handshake if error is ERROR_RTMP_TRY_SIMPLE_HS, 540 | * otherwise, disconnect 541 | */ 542 | virtual int handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReaderWriter* io); 543 | virtual int handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReaderWriter* io); 544 | }; 545 | 546 | #endif 547 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_rtmp_io.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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 | #include 25 | 26 | ISrsBufferReader::ISrsBufferReader() 27 | { 28 | } 29 | 30 | ISrsBufferReader::~ISrsBufferReader() 31 | { 32 | } 33 | 34 | ISrsBufferWriter::ISrsBufferWriter() 35 | { 36 | } 37 | 38 | ISrsBufferWriter::~ISrsBufferWriter() 39 | { 40 | } 41 | 42 | ISrsProtocolStatistic::ISrsProtocolStatistic() 43 | { 44 | } 45 | 46 | ISrsProtocolStatistic::~ISrsProtocolStatistic() 47 | { 48 | } 49 | 50 | ISrsProtocolReader::ISrsProtocolReader() 51 | { 52 | } 53 | 54 | ISrsProtocolReader::~ISrsProtocolReader() 55 | { 56 | } 57 | 58 | ISrsProtocolWriter::ISrsProtocolWriter() 59 | { 60 | } 61 | 62 | ISrsProtocolWriter::~ISrsProtocolWriter() 63 | { 64 | } 65 | 66 | ISrsProtocolReaderWriter::ISrsProtocolReaderWriter() 67 | { 68 | } 69 | 70 | ISrsProtocolReaderWriter::~ISrsProtocolReaderWriter() 71 | { 72 | } 73 | 74 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_rtmp_io.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_RTMP_PROTOCOL_IO_HPP 25 | #define SRS_RTMP_PROTOCOL_IO_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | // for srs-librtmp, @see https://github.com/winlinvip/simple-rtmp-server/issues/213 34 | #ifndef _WIN32 35 | #include 36 | #endif 37 | 38 | /** 39 | * the system io reader/writer architecture: 40 | +---------------+ +--------------------+ +---------------+ 41 | | IBufferReader | | IStatistic | | IBufferWriter | 42 | +---------------+ +--------------------+ +---------------+ 43 | | + read() | | + get_recv_bytes() | | + write() | 44 | +------+--------+ | + get_recv_bytes() | | + writev() | 45 | / \ +---+--------------+-+ +-------+-------+ 46 | | / \ / \ / \ 47 | | | | | 48 | +------+------------------+-+ +-----+----------------+--+ 49 | | IProtocolReader | | IProtocolWriter | 50 | +---------------------------+ +-------------------------+ 51 | | + readfully() | | + set_send_timeout() | 52 | | + set_recv_timeout() | +-------+-----------------+ 53 | +------------+--------------+ / \ 54 | / \ | 55 | | | 56 | +--+-----------------------------+-+ 57 | | IProtocolReaderWriter | 58 | +----------------------------------+ 59 | | + is_never_timeout() | 60 | +----------------------------------+ 61 | */ 62 | 63 | /** 64 | * the reader for the buffer to read from whatever channel. 65 | */ 66 | class ISrsBufferReader 67 | { 68 | public: 69 | ISrsBufferReader(); 70 | virtual ~ISrsBufferReader(); 71 | // for protocol/amf0/msg-codec 72 | public: 73 | virtual int read(void* buf, size_t size, ssize_t* nread) = 0; 74 | }; 75 | 76 | /** 77 | * the writer for the buffer to write to whatever channel. 78 | */ 79 | class ISrsBufferWriter 80 | { 81 | public: 82 | ISrsBufferWriter(); 83 | virtual ~ISrsBufferWriter(); 84 | // for protocol 85 | public: 86 | /** 87 | * write bytes over writer. 88 | * @nwrite the actual written bytes. NULL to ignore. 89 | */ 90 | virtual int write(void* buf, size_t size, ssize_t* nwrite) = 0; 91 | /** 92 | * write iov over writer. 93 | * @nwrite the actual written bytes. NULL to ignore. 94 | */ 95 | virtual int writev(const iovec *iov, int iov_size, ssize_t* nwrite) = 0; 96 | }; 97 | 98 | /** 99 | * get the statistic of channel. 100 | */ 101 | class ISrsProtocolStatistic 102 | { 103 | public: 104 | ISrsProtocolStatistic(); 105 | virtual ~ISrsProtocolStatistic(); 106 | // for protocol 107 | public: 108 | /** 109 | * get the total recv bytes over underlay fd. 110 | */ 111 | virtual int64_t get_recv_bytes() = 0; 112 | /** 113 | * get the total send bytes over underlay fd. 114 | */ 115 | virtual int64_t get_send_bytes() = 0; 116 | }; 117 | 118 | /** 119 | * the reader for the protocol to read from whatever channel. 120 | */ 121 | class ISrsProtocolReader : public virtual ISrsBufferReader, public virtual ISrsProtocolStatistic 122 | { 123 | public: 124 | ISrsProtocolReader(); 125 | virtual ~ISrsProtocolReader(); 126 | // for protocol 127 | public: 128 | /** 129 | * set the recv timeout in us, recv will error when timeout. 130 | * @remark, if not set, use ST_UTIME_NO_TIMEOUT, never timeout. 131 | */ 132 | virtual void set_recv_timeout(int64_t timeout_us) = 0; 133 | /** 134 | * get the recv timeout in us. 135 | */ 136 | virtual int64_t get_recv_timeout() = 0; 137 | // for handshake. 138 | public: 139 | /** 140 | * read specified size bytes of data 141 | * @param nread, the actually read size, NULL to ignore. 142 | */ 143 | virtual int read_fully(void* buf, size_t size, ssize_t* nread) = 0; 144 | }; 145 | 146 | /** 147 | * the writer for the protocol to write to whatever channel. 148 | */ 149 | class ISrsProtocolWriter : public virtual ISrsBufferWriter, public virtual ISrsProtocolStatistic 150 | { 151 | public: 152 | ISrsProtocolWriter(); 153 | virtual ~ISrsProtocolWriter(); 154 | // for protocol 155 | public: 156 | /** 157 | * set the send timeout in us, send will error when timeout. 158 | * @remark, if not set, use ST_UTIME_NO_TIMEOUT, never timeout. 159 | */ 160 | virtual void set_send_timeout(int64_t timeout_us) = 0; 161 | /** 162 | * get the send timeout in us. 163 | */ 164 | virtual int64_t get_send_timeout() = 0; 165 | }; 166 | 167 | /** 168 | * the reader and writer. 169 | */ 170 | class ISrsProtocolReaderWriter : public virtual ISrsProtocolReader, public virtual ISrsProtocolWriter 171 | { 172 | public: 173 | ISrsProtocolReaderWriter(); 174 | virtual ~ISrsProtocolReaderWriter(); 175 | // for protocol 176 | public: 177 | /** 178 | * whether the specified timeout_us is never timeout. 179 | */ 180 | virtual bool is_never_timeout(int64_t timeout_us) = 0; 181 | }; 182 | 183 | #endif 184 | 185 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_rtmp_msg_array.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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 | #include 25 | 26 | #include 27 | 28 | SrsMessageArray::SrsMessageArray(int max_msgs) 29 | { 30 | srs_assert(max_msgs > 0); 31 | 32 | msgs = new SrsSharedPtrMessage*[max_msgs]; 33 | max = max_msgs; 34 | 35 | zero(max_msgs); 36 | } 37 | 38 | SrsMessageArray::~SrsMessageArray() 39 | { 40 | // we just free the msgs itself, 41 | // both delete and delete[] is ok, 42 | // for each msg in msgs is already freed by send_and_free_messages. 43 | srs_freep(msgs); 44 | } 45 | 46 | void SrsMessageArray::free(int count) 47 | { 48 | // initialize 49 | for (int i = 0; i < count; i++) { 50 | SrsSharedPtrMessage* msg = msgs[i]; 51 | srs_freep(msg); 52 | 53 | msgs[i] = NULL; 54 | } 55 | } 56 | 57 | void SrsMessageArray::zero(int count) 58 | { 59 | // initialize 60 | for (int i = 0; i < count; i++) { 61 | msgs[i] = NULL; 62 | } 63 | } 64 | 65 | 66 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_rtmp_msg_array.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_RTMP_PROTOCOL_MSG_ARRAY_HPP 25 | #define SRS_RTMP_PROTOCOL_MSG_ARRAY_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | class SrsSharedPtrMessage; 34 | 35 | /** 36 | * the class to auto free the shared ptr message array. 37 | * when need to get some messages, for instance, from Consumer queue, 38 | * create a message array, whose msgs can used to accept the msgs, 39 | * then send each message and set to NULL. 40 | * 41 | * @remark: user must free all msgs in array, for the SRS2.0 protocol stack 42 | * provides an api to send messages, @see send_and_free_messages 43 | */ 44 | class SrsMessageArray 45 | { 46 | public: 47 | /** 48 | * when user already send the msg in msgs, please set to NULL, 49 | * for instance, msg= msgs.msgs[i], msgs.msgs[i]=NULL, send(msg), 50 | * where send(msg) will always send and free it. 51 | */ 52 | SrsSharedPtrMessage** msgs; 53 | int max; 54 | public: 55 | /** 56 | * create msg array, initialize array to NULL ptrs. 57 | */ 58 | SrsMessageArray(int max_msgs); 59 | /** 60 | * free the msgs not sent out(not NULL). 61 | */ 62 | virtual ~SrsMessageArray(); 63 | public: 64 | /** 65 | * free specified count of messages. 66 | */ 67 | virtual void free(int count); 68 | private: 69 | /** 70 | * zero initialize the message array. 71 | */ 72 | virtual void zero(int count); 73 | }; 74 | 75 | #endif 76 | 77 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_rtmp_sdk.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_RTMP_PROTOCOL_RTMP_HPP 25 | #define SRS_RTMP_PROTOCOL_RTMP_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | 31 | #include 32 | 33 | #include 34 | 35 | #include 36 | #include 37 | 38 | class SrsProtocol; 39 | class ISrsProtocolReaderWriter; 40 | class SrsCommonMessage; 41 | class SrsCreateStreamPacket; 42 | class SrsFMLEStartPacket; 43 | class SrsPublishPacket; 44 | class SrsOnMetaDataPacket; 45 | class SrsPlayPacket; 46 | class SrsCommonMessage; 47 | class SrsPacket; 48 | class SrsAmf0Object; 49 | class IMergeReadHandler; 50 | 51 | /** 52 | * the original request from client. 53 | */ 54 | class SrsRequest 55 | { 56 | public: 57 | // client ip. 58 | std::string ip; 59 | public: 60 | /** 61 | * tcUrl: rtmp://request_vhost:port/app/stream 62 | * support pass vhost in query string, such as: 63 | * rtmp://ip:port/app?vhost=request_vhost/stream 64 | * rtmp://ip:port/app...vhost...request_vhost/stream 65 | */ 66 | std::string tcUrl; 67 | std::string pageUrl; 68 | std::string swfUrl; 69 | double objectEncoding; 70 | // data discovery from request. 71 | public: 72 | // discovery from tcUrl and play/publish. 73 | std::string schema; 74 | // the vhost in tcUrl. 75 | std::string vhost; 76 | // the host in tcUrl. 77 | std::string host; 78 | // the port in tcUrl. 79 | std::string port; 80 | // the app in tcUrl, without param. 81 | std::string app; 82 | // the param in tcUrl(app). 83 | std::string param; 84 | // the stream in play/publish 85 | std::string stream; 86 | // for play live stream, 87 | // used to specified the stop when exceed the duration. 88 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/45 89 | // in ms. 90 | double duration; 91 | // the token in the connect request, 92 | // used for edge traverse to origin authentication, 93 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/104 94 | SrsAmf0Object* args; 95 | public: 96 | SrsRequest(); 97 | virtual ~SrsRequest(); 98 | public: 99 | /** 100 | * deep copy the request, for source to use it to support reload, 101 | * for when initialize the source, the request is valid, 102 | * when reload it, the request maybe invalid, so need to copy it. 103 | */ 104 | virtual SrsRequest* copy(); 105 | /** 106 | * update the auth info of request, 107 | * to keep the current request ptr is ok, 108 | * for many components use the ptr of request. 109 | */ 110 | virtual void update_auth(SrsRequest* req); 111 | /** 112 | * get the stream identify, vhost/app/stream. 113 | */ 114 | virtual std::string get_stream_url(); 115 | /** 116 | * strip url, user must strip when update the url. 117 | */ 118 | virtual void strip(); 119 | }; 120 | 121 | /** 122 | * the response to client. 123 | */ 124 | class SrsResponse 125 | { 126 | public: 127 | /** 128 | * the stream id to response client createStream. 129 | */ 130 | int stream_id; 131 | public: 132 | SrsResponse(); 133 | virtual ~SrsResponse(); 134 | }; 135 | 136 | /** 137 | * the rtmp client type. 138 | */ 139 | enum SrsRtmpConnType 140 | { 141 | SrsRtmpConnUnknown, 142 | SrsRtmpConnPlay, 143 | SrsRtmpConnFMLEPublish, 144 | SrsRtmpConnFlashPublish, 145 | }; 146 | std::string srs_client_type_string(SrsRtmpConnType type); 147 | 148 | /** 149 | * store the handshake bytes, 150 | * for smart switch between complex and simple handshake. 151 | */ 152 | class SrsHandshakeBytes 153 | { 154 | public: 155 | // [1+1536] 156 | char* c0c1; 157 | // [1+1536+1536] 158 | char* s0s1s2; 159 | // [1536] 160 | char* c2; 161 | public: 162 | SrsHandshakeBytes(); 163 | virtual ~SrsHandshakeBytes(); 164 | public: 165 | virtual int read_c0c1(ISrsProtocolReaderWriter* io); 166 | virtual int read_s0s1s2(ISrsProtocolReaderWriter* io); 167 | virtual int read_c2(ISrsProtocolReaderWriter* io); 168 | virtual int create_c0c1(); 169 | virtual int create_s0s1s2(const char* c1 = NULL); 170 | virtual int create_c2(); 171 | }; 172 | 173 | /** 174 | * implements the client role protocol. 175 | */ 176 | class SrsRtmpClient 177 | { 178 | private: 179 | SrsHandshakeBytes* hs_bytes; 180 | protected: 181 | SrsProtocol* protocol; 182 | ISrsProtocolReaderWriter* io; 183 | public: 184 | SrsRtmpClient(ISrsProtocolReaderWriter* skt); 185 | virtual ~SrsRtmpClient(); 186 | // protocol methods proxy 187 | public: 188 | /** 189 | * set the recv timeout in us. 190 | * if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. 191 | */ 192 | virtual void set_recv_timeout(int64_t timeout_us); 193 | /** 194 | * set the send timeout in us. 195 | * if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. 196 | */ 197 | virtual void set_send_timeout(int64_t timeout_us); 198 | /** 199 | * get recv/send bytes. 200 | */ 201 | virtual int64_t get_recv_bytes(); 202 | virtual int64_t get_send_bytes(); 203 | /** 204 | * recv a RTMP message, which is bytes oriented. 205 | * user can use decode_message to get the decoded RTMP packet. 206 | * @param pmsg, set the received message, 207 | * always NULL if error, 208 | * NULL for unknown packet but return success. 209 | * never NULL if decode success. 210 | * @remark, drop message when msg is empty or payload length is empty. 211 | */ 212 | virtual int recv_message(SrsCommonMessage** pmsg); 213 | /** 214 | * decode bytes oriented RTMP message to RTMP packet, 215 | * @param ppacket, output decoded packet, 216 | * always NULL if error, never NULL if success. 217 | * @return error when unknown packet, error when decode failed. 218 | */ 219 | virtual int decode_message(SrsCommonMessage* msg, SrsPacket** ppacket); 220 | /** 221 | * send the RTMP message and always free it. 222 | * user must never free or use the msg after this method, 223 | * for it will always free the msg. 224 | * @param msg, the msg to send out, never be NULL. 225 | * @param stream_id, the stream id of packet to send over, 0 for control message. 226 | */ 227 | virtual int send_and_free_message(SrsSharedPtrMessage* msg, int stream_id); 228 | /** 229 | * send the RTMP message and always free it. 230 | * user must never free or use the msg after this method, 231 | * for it will always free the msg. 232 | * @param msgs, the msgs to send out, never be NULL. 233 | * @param nb_msgs, the size of msgs to send out. 234 | * @param stream_id, the stream id of packet to send over, 0 for control message. 235 | */ 236 | virtual int send_and_free_messages(SrsSharedPtrMessage** msgs, int nb_msgs, int stream_id); 237 | /** 238 | * send the RTMP packet and always free it. 239 | * user must never free or use the packet after this method, 240 | * for it will always free the packet. 241 | * @param packet, the packet to send out, never be NULL. 242 | * @param stream_id, the stream id of packet to send over, 0 for control message. 243 | */ 244 | virtual int send_and_free_packet(SrsPacket* packet, int stream_id); 245 | public: 246 | /** 247 | * handshake with server, try complex, then simple handshake. 248 | */ 249 | virtual int handshake(); 250 | /** 251 | * only use simple handshake 252 | */ 253 | virtual int simple_handshake(); 254 | /** 255 | * only use complex handshake 256 | */ 257 | virtual int complex_handshake(); 258 | /** 259 | * set req to use the original request of client: 260 | * pageUrl and swfUrl for refer antisuck. 261 | * args for edge to origin traverse auth, @see SrsRequest.args 262 | */ 263 | virtual int connect_app(std::string app, std::string tc_url, 264 | SrsRequest* req, bool debug_srs_upnode); 265 | /** 266 | * connect to server, get the debug srs info. 267 | * 268 | * @param app, the app to connect at. 269 | * @param tc_url, the tcUrl to connect at. 270 | * @param req, the optional req object, use the swfUrl/pageUrl if specified. NULL to ignore. 271 | * 272 | * SRS debug info: 273 | * @param srs_server_ip, debug info, server ip client connected at. 274 | * @param srs_server, server info. 275 | * @param srs_primary, primary authors. 276 | * @param srs_authors, authors. 277 | * @param srs_id, int, debug info, client id in server log. 278 | * @param srs_pid, int, debug info, server pid in log. 279 | */ 280 | virtual int connect_app2( 281 | std::string app, std::string tc_url, SrsRequest* req, bool debug_srs_upnode, 282 | std::string& srs_server_ip, std::string& srs_server, std::string& srs_primary, 283 | std::string& srs_authors, std::string& srs_version, int& srs_id, 284 | int& srs_pid 285 | ); 286 | /** 287 | * create a stream, then play/publish data over this stream. 288 | */ 289 | virtual int create_stream(int& stream_id); 290 | /** 291 | * start play stream. 292 | */ 293 | virtual int play(std::string stream, int stream_id); 294 | /** 295 | * start publish stream. use flash publish workflow: 296 | * connect-app => create-stream => flash-publish 297 | */ 298 | virtual int publish(std::string stream, int stream_id); 299 | /** 300 | * start publish stream. use FMLE publish workflow: 301 | * connect-app => FMLE publish 302 | */ 303 | virtual int fmle_publish(std::string stream, int& stream_id); 304 | public: 305 | /** 306 | * expect a specified message, drop others util got specified one. 307 | * @pmsg, user must free it. NULL if not success. 308 | * @ppacket, store in the pmsg, user must never free it. NULL if not success. 309 | * @remark, only when success, user can use and must free the pmsg/ppacket. 310 | * for example: 311 | SrsCommonMessage* msg = NULL; 312 | SrsConnectAppResPacket* pkt = NULL; 313 | if ((ret = srs_rtmp_expect_message(protocol, &msg, &pkt)) != ERROR_SUCCESS) { 314 | return ret; 315 | } 316 | // use pkt 317 | * user should never recv message and convert it, use this method instead. 318 | * if need to set timeout, use set timeout of SrsProtocol. 319 | */ 320 | template 321 | int expect_message(SrsCommonMessage** pmsg, T** ppacket) 322 | { 323 | return protocol->expect_message(pmsg, ppacket); 324 | } 325 | }; 326 | 327 | /** 328 | * the rtmp provices rtmp-command-protocol services, 329 | * a high level protocol, media stream oriented services, 330 | * such as connect to vhost/app, play stream, get audio/video data. 331 | */ 332 | class SrsRtmpServer 333 | { 334 | private: 335 | SrsHandshakeBytes* hs_bytes; 336 | SrsProtocol* protocol; 337 | ISrsProtocolReaderWriter* io; 338 | public: 339 | SrsRtmpServer(ISrsProtocolReaderWriter* skt); 340 | virtual ~SrsRtmpServer(); 341 | // protocol methods proxy 342 | public: 343 | /** 344 | * set the auto response message when recv for protocol stack. 345 | * @param v, whether auto response message when recv message. 346 | * @see: https://github.com/winlinvip/simple-rtmp-server/issues/217 347 | */ 348 | virtual void set_auto_response(bool v); 349 | #ifdef SRS_PERF_MERGED_READ 350 | /** 351 | * to improve read performance, merge some packets then read, 352 | * when it on and read small bytes, we sleep to wait more data., 353 | * that is, we merge some data to read together. 354 | * @param v true to ename merged read. 355 | * @param handler the handler when merge read is enabled. 356 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 357 | */ 358 | virtual void set_merge_read(bool v, IMergeReadHandler* handler); 359 | /** 360 | * create buffer with specifeid size. 361 | * @param buffer the size of buffer. 362 | * @remark when MR(SRS_PERF_MERGED_READ) disabled, always set to 8K. 363 | * @remark when buffer changed, the previous ptr maybe invalid. 364 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/241 365 | */ 366 | virtual void set_recv_buffer(int buffer_size); 367 | #endif 368 | /** 369 | * set/get the recv timeout in us. 370 | * if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. 371 | */ 372 | virtual void set_recv_timeout(int64_t timeout_us); 373 | virtual int64_t get_recv_timeout(); 374 | /** 375 | * set/get the send timeout in us. 376 | * if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. 377 | */ 378 | virtual void set_send_timeout(int64_t timeout_us); 379 | virtual int64_t get_send_timeout(); 380 | /** 381 | * get recv/send bytes. 382 | */ 383 | virtual int64_t get_recv_bytes(); 384 | virtual int64_t get_send_bytes(); 385 | /** 386 | * recv a RTMP message, which is bytes oriented. 387 | * user can use decode_message to get the decoded RTMP packet. 388 | * @param pmsg, set the received message, 389 | * always NULL if error, 390 | * NULL for unknown packet but return success. 391 | * never NULL if decode success. 392 | * @remark, drop message when msg is empty or payload length is empty. 393 | */ 394 | virtual int recv_message(SrsCommonMessage** pmsg); 395 | /** 396 | * decode bytes oriented RTMP message to RTMP packet, 397 | * @param ppacket, output decoded packet, 398 | * always NULL if error, never NULL if success. 399 | * @return error when unknown packet, error when decode failed. 400 | */ 401 | virtual int decode_message(SrsCommonMessage* msg, SrsPacket** ppacket); 402 | /** 403 | * send the RTMP message and always free it. 404 | * user must never free or use the msg after this method, 405 | * for it will always free the msg. 406 | * @param msg, the msg to send out, never be NULL. 407 | * @param stream_id, the stream id of packet to send over, 0 for control message. 408 | */ 409 | virtual int send_and_free_message(SrsSharedPtrMessage* msg, int stream_id); 410 | /** 411 | * send the RTMP message and always free it. 412 | * user must never free or use the msg after this method, 413 | * for it will always free the msg. 414 | * @param msgs, the msgs to send out, never be NULL. 415 | * @param nb_msgs, the size of msgs to send out. 416 | * @param stream_id, the stream id of packet to send over, 0 for control message. 417 | * 418 | * @remark performance issue, to support 6k+ 250kbps client, 419 | * @see https://github.com/winlinvip/simple-rtmp-server/issues/194 420 | */ 421 | virtual int send_and_free_messages(SrsSharedPtrMessage** msgs, int nb_msgs, int stream_id); 422 | /** 423 | * send the RTMP packet and always free it. 424 | * user must never free or use the packet after this method, 425 | * for it will always free the packet. 426 | * @param packet, the packet to send out, never be NULL. 427 | * @param stream_id, the stream id of packet to send over, 0 for control message. 428 | */ 429 | virtual int send_and_free_packet(SrsPacket* packet, int stream_id); 430 | public: 431 | /** 432 | * handshake with client, try complex then simple. 433 | */ 434 | virtual int handshake(); 435 | /** 436 | * do connect app with client, to discovery tcUrl. 437 | */ 438 | virtual int connect_app(SrsRequest* req); 439 | /** 440 | * set ack size to client, client will send ack-size for each ack window 441 | */ 442 | virtual int set_window_ack_size(int ack_size); 443 | /** 444 | * @type: The sender can mark this message hard (0), soft (1), or dynamic (2) 445 | * using the Limit type field. 446 | */ 447 | virtual int set_peer_bandwidth(int bandwidth, int type); 448 | /** 449 | * @param server_ip the ip of server. 450 | */ 451 | virtual int response_connect_app(SrsRequest* req, const char* server_ip = NULL); 452 | /** 453 | * reject the connect app request. 454 | */ 455 | virtual void response_connect_reject(SrsRequest* req, const char* desc); 456 | /** 457 | * response client the onBWDone message. 458 | */ 459 | virtual int on_bw_done(); 460 | /** 461 | * recv some message to identify the client. 462 | * @stream_id, client will createStream to play or publish by flash, 463 | * the stream_id used to response the createStream request. 464 | * @type, output the client type. 465 | * @stream_name, output the client publish/play stream name. @see: SrsRequest.stream 466 | * @duration, output the play client duration. @see: SrsRequest.duration 467 | */ 468 | virtual int identify_client(int stream_id, SrsRtmpConnType& type, std::string& stream_name, double& duration); 469 | /** 470 | * set the chunk size when client type identified. 471 | */ 472 | virtual int set_chunk_size(int chunk_size); 473 | /** 474 | * when client type is play, response with packets: 475 | * StreamBegin, 476 | * onStatus(NetStream.Play.Reset), onStatus(NetStream.Play.Start)., 477 | * |RtmpSampleAccess(false, false), 478 | * onStatus(NetStream.Data.Start). 479 | */ 480 | virtual int start_play(int stream_id); 481 | /** 482 | * when client(type is play) send pause message, 483 | * if is_pause, response the following packets: 484 | * onStatus(NetStream.Pause.Notify) 485 | * StreamEOF 486 | * if not is_pause, response the following packets: 487 | * onStatus(NetStream.Unpause.Notify) 488 | * StreamBegin 489 | */ 490 | virtual int on_play_client_pause(int stream_id, bool is_pause); 491 | /** 492 | * when client type is publish, response with packets: 493 | * releaseStream response 494 | * FCPublish 495 | * FCPublish response 496 | * createStream response 497 | * onFCPublish(NetStream.Publish.Start) 498 | * onStatus(NetStream.Publish.Start) 499 | */ 500 | virtual int start_fmle_publish(int stream_id); 501 | /** 502 | * process the FMLE unpublish event. 503 | * @unpublish_tid the unpublish request transaction id. 504 | */ 505 | virtual int fmle_unpublish(int stream_id, double unpublish_tid); 506 | /** 507 | * when client type is publish, response with packets: 508 | * onStatus(NetStream.Publish.Start) 509 | */ 510 | virtual int start_flash_publish(int stream_id); 511 | public: 512 | /** 513 | * expect a specified message, drop others util got specified one. 514 | * @pmsg, user must free it. NULL if not success. 515 | * @ppacket, store in the pmsg, user must never free it. NULL if not success. 516 | * @remark, only when success, user can use and must free the pmsg/ppacket. 517 | * for example: 518 | SrsCommonMessage* msg = NULL; 519 | SrsConnectAppResPacket* pkt = NULL; 520 | if ((ret = srs_rtmp_expect_message(protocol, &msg, &pkt)) != ERROR_SUCCESS) { 521 | return ret; 522 | } 523 | // use pkt 524 | * user should never recv message and convert it, use this method instead. 525 | * if need to set timeout, use set timeout of SrsProtocol. 526 | */ 527 | template 528 | int expect_message(SrsCommonMessage** pmsg, T** ppacket) 529 | { 530 | return protocol->expect_message(pmsg, ppacket); 531 | } 532 | private: 533 | virtual int identify_create_stream_client(SrsCreateStreamPacket* req, int stream_id, SrsRtmpConnType& type, std::string& stream_name, double& duration); 534 | virtual int identify_fmle_publish_client(SrsFMLEStartPacket* req, SrsRtmpConnType& type, std::string& stream_name); 535 | virtual int identify_flash_publish_client(SrsPublishPacket* req, SrsRtmpConnType& type, std::string& stream_name); 536 | private: 537 | virtual int identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& type, std::string& stream_name, double& duration); 538 | }; 539 | 540 | #endif 541 | 542 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_rtmp_utility.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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 | #include 25 | 26 | #include 27 | using namespace std; 28 | 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | 35 | void srs_discovery_tc_url( 36 | string tcUrl, 37 | string& schema, string& host, string& vhost, 38 | string& app, string& port, std::string& param 39 | ) { 40 | size_t pos = std::string::npos; 41 | std::string url = tcUrl; 42 | 43 | if ((pos = url.find("://")) != std::string::npos) { 44 | schema = url.substr(0, pos); 45 | url = url.substr(schema.length() + 3); 46 | srs_info("discovery schema=%s", schema.c_str()); 47 | } 48 | 49 | if ((pos = url.find("/")) != std::string::npos) { 50 | host = url.substr(0, pos); 51 | url = url.substr(host.length() + 1); 52 | srs_info("discovery host=%s", host.c_str()); 53 | } 54 | 55 | port = SRS_CONSTS_RTMP_DEFAULT_PORT; 56 | if ((pos = host.find(":")) != std::string::npos) { 57 | port = host.substr(pos + 1); 58 | host = host.substr(0, pos); 59 | srs_info("discovery host=%s, port=%s", host.c_str(), port.c_str()); 60 | } 61 | 62 | app = url; 63 | vhost = host; 64 | srs_vhost_resolve(vhost, app, param); 65 | } 66 | 67 | void srs_vhost_resolve(string& vhost, string& app, string& param) 68 | { 69 | // get original param 70 | size_t pos = 0; 71 | if ((pos = app.find("?")) != std::string::npos) { 72 | param = app.substr(pos); 73 | } 74 | 75 | // filter tcUrl 76 | app = srs_string_replace(app, ",", "?"); 77 | app = srs_string_replace(app, "...", "?"); 78 | app = srs_string_replace(app, "&&", "?"); 79 | app = srs_string_replace(app, "=", "?"); 80 | 81 | if ((pos = app.find("?")) == std::string::npos) { 82 | return; 83 | } 84 | 85 | std::string query = app.substr(pos + 1); 86 | app = app.substr(0, pos); 87 | 88 | if ((pos = query.find("vhost?")) != std::string::npos) { 89 | query = query.substr(pos + 6); 90 | if (!query.empty()) { 91 | vhost = query; 92 | } 93 | if ((pos = vhost.find("?")) != std::string::npos) { 94 | vhost = vhost.substr(0, pos); 95 | } 96 | } 97 | } 98 | 99 | void srs_random_generate(char* bytes, int size) 100 | { 101 | static bool _random_initialized = false; 102 | if (!_random_initialized) { 103 | srand(0); 104 | _random_initialized = true; 105 | srs_trace("srand initialized the random."); 106 | } 107 | 108 | for (int i = 0; i < size; i++) { 109 | // the common value in [0x0f, 0xf0] 110 | bytes[i] = 0x0f + (rand() % (256 - 0x0f - 0x0f)); 111 | } 112 | } 113 | 114 | string srs_generate_tc_url(string ip, string vhost, string app, string port, string param) 115 | { 116 | string tcUrl = "rtmp://"; 117 | 118 | if (vhost == SRS_CONSTS_RTMP_DEFAULT_VHOST) { 119 | tcUrl += ip; 120 | } else { 121 | tcUrl += vhost; 122 | } 123 | 124 | if (port != SRS_CONSTS_RTMP_DEFAULT_PORT) { 125 | tcUrl += ":"; 126 | tcUrl += port; 127 | } 128 | 129 | tcUrl += "/"; 130 | tcUrl += app; 131 | tcUrl += param; 132 | 133 | return tcUrl; 134 | } 135 | 136 | /** 137 | * compare the memory in bytes. 138 | */ 139 | bool srs_bytes_equals(void* pa, void* pb, int size) 140 | { 141 | u_int8_t* a = (u_int8_t*)pa; 142 | u_int8_t* b = (u_int8_t*)pb; 143 | 144 | if (!a && !b) { 145 | return true; 146 | } 147 | 148 | if (!a || !b) { 149 | return false; 150 | } 151 | 152 | for(int i = 0; i < size; i++){ 153 | if(a[i] != b[i]){ 154 | return false; 155 | } 156 | } 157 | 158 | return true; 159 | } 160 | 161 | int srs_chunk_header_c0( 162 | int perfer_cid, u_int32_t timestamp, int32_t payload_length, 163 | int8_t message_type, int32_t stream_id, 164 | char* cache, int nb_cache 165 | ) 166 | { 167 | // to directly set the field. 168 | char* pp = NULL; 169 | 170 | // generate the header. 171 | char* p = cache; 172 | 173 | // no header. 174 | if (nb_cache < SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE) { 175 | return 0; 176 | } 177 | 178 | // write new chunk stream header, fmt is 0 179 | *p++ = 0x00 | (perfer_cid & 0x3F); 180 | 181 | // chunk message header, 11 bytes 182 | // timestamp, 3bytes, big-endian 183 | if (timestamp < RTMP_EXTENDED_TIMESTAMP) { 184 | pp = (char*)×tamp; 185 | *p++ = pp[2]; 186 | *p++ = pp[1]; 187 | *p++ = pp[0]; 188 | } else { 189 | *p++ = 0xFF; 190 | *p++ = 0xFF; 191 | *p++ = 0xFF; 192 | } 193 | 194 | // message_length, 3bytes, big-endian 195 | pp = (char*)&payload_length; 196 | *p++ = pp[2]; 197 | *p++ = pp[1]; 198 | *p++ = pp[0]; 199 | 200 | // message_type, 1bytes 201 | *p++ = message_type; 202 | 203 | // stream_id, 4bytes, little-endian 204 | pp = (char*)&stream_id; 205 | *p++ = pp[0]; 206 | *p++ = pp[1]; 207 | *p++ = pp[2]; 208 | *p++ = pp[3]; 209 | 210 | // for c0 211 | // chunk extended timestamp header, 0 or 4 bytes, big-endian 212 | // 213 | // for c3: 214 | // chunk extended timestamp header, 0 or 4 bytes, big-endian 215 | // 6.1.3. Extended Timestamp 216 | // This field is transmitted only when the normal time stamp in the 217 | // chunk message header is set to 0x00ffffff. If normal time stamp is 218 | // set to any value less than 0x00ffffff, this field MUST NOT be 219 | // present. This field MUST NOT be present if the timestamp field is not 220 | // present. Type 3 chunks MUST NOT have this field. 221 | // adobe changed for Type3 chunk: 222 | // FMLE always sendout the extended-timestamp, 223 | // must send the extended-timestamp to FMS, 224 | // must send the extended-timestamp to flash-player. 225 | // @see: ngx_rtmp_prepare_message 226 | // @see: http://blog.csdn.net/win_lin/article/details/13363699 227 | // TODO: FIXME: extract to outer. 228 | if (timestamp >= RTMP_EXTENDED_TIMESTAMP) { 229 | pp = (char*)×tamp; 230 | *p++ = pp[3]; 231 | *p++ = pp[2]; 232 | *p++ = pp[1]; 233 | *p++ = pp[0]; 234 | } 235 | 236 | // always has header 237 | return p - cache; 238 | } 239 | 240 | int srs_chunk_header_c3( 241 | int perfer_cid, u_int32_t timestamp, 242 | char* cache, int nb_cache 243 | ) 244 | { 245 | // to directly set the field. 246 | char* pp = NULL; 247 | 248 | // generate the header. 249 | char* p = cache; 250 | 251 | // no header. 252 | if (nb_cache < SRS_CONSTS_RTMP_MAX_FMT3_HEADER_SIZE) { 253 | return 0; 254 | } 255 | 256 | // write no message header chunk stream, fmt is 3 257 | // @remark, if perfer_cid > 0x3F, that is, use 2B/3B chunk header, 258 | // SRS will rollback to 1B chunk header. 259 | *p++ = 0xC0 | (perfer_cid & 0x3F); 260 | 261 | // for c0 262 | // chunk extended timestamp header, 0 or 4 bytes, big-endian 263 | // 264 | // for c3: 265 | // chunk extended timestamp header, 0 or 4 bytes, big-endian 266 | // 6.1.3. Extended Timestamp 267 | // This field is transmitted only when the normal time stamp in the 268 | // chunk message header is set to 0x00ffffff. If normal time stamp is 269 | // set to any value less than 0x00ffffff, this field MUST NOT be 270 | // present. This field MUST NOT be present if the timestamp field is not 271 | // present. Type 3 chunks MUST NOT have this field. 272 | // adobe changed for Type3 chunk: 273 | // FMLE always sendout the extended-timestamp, 274 | // must send the extended-timestamp to FMS, 275 | // must send the extended-timestamp to flash-player. 276 | // @see: ngx_rtmp_prepare_message 277 | // @see: http://blog.csdn.net/win_lin/article/details/13363699 278 | // TODO: FIXME: extract to outer. 279 | if (timestamp >= RTMP_EXTENDED_TIMESTAMP) { 280 | pp = (char*)×tamp; 281 | *p++ = pp[3]; 282 | *p++ = pp[2]; 283 | *p++ = pp[1]; 284 | *p++ = pp[0]; 285 | } 286 | 287 | // always has header 288 | return p - cache; 289 | } 290 | 291 | int srs_do_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, int stream_id, SrsSharedPtrMessage** ppmsg) 292 | { 293 | int ret = ERROR_SUCCESS; 294 | 295 | *ppmsg = NULL; 296 | SrsSharedPtrMessage* msg = NULL; 297 | 298 | if (type == SrsCodecFlvTagAudio) { 299 | SrsMessageHeader header; 300 | header.initialize_audio(size, timestamp, stream_id); 301 | 302 | msg = new SrsSharedPtrMessage(); 303 | if ((ret = msg->create(&header, data, size)) != ERROR_SUCCESS) { 304 | srs_freep(msg); 305 | return ret; 306 | } 307 | } else if (type == SrsCodecFlvTagVideo) { 308 | SrsMessageHeader header; 309 | header.initialize_video(size, timestamp, stream_id); 310 | 311 | msg = new SrsSharedPtrMessage(); 312 | if ((ret = msg->create(&header, data, size)) != ERROR_SUCCESS) { 313 | srs_freep(msg); 314 | return ret; 315 | } 316 | } else if (type == SrsCodecFlvTagScript) { 317 | SrsMessageHeader header; 318 | header.initialize_amf0_script(size, stream_id); 319 | 320 | msg = new SrsSharedPtrMessage(); 321 | if ((ret = msg->create(&header, data, size)) != ERROR_SUCCESS) { 322 | srs_freep(msg); 323 | return ret; 324 | } 325 | } else { 326 | ret = ERROR_STREAM_CASTER_FLV_TAG; 327 | srs_error("rtmp unknown tag type=%#x. ret=%d", type, ret); 328 | return ret; 329 | } 330 | 331 | *ppmsg = msg; 332 | 333 | return ret; 334 | } 335 | 336 | int srs_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, int stream_id, SrsSharedPtrMessage** ppmsg) 337 | { 338 | int ret = ERROR_SUCCESS; 339 | 340 | // only when failed, we must free the data. 341 | if ((ret = srs_do_rtmp_create_msg(type, timestamp, data, size, stream_id, ppmsg)) != ERROR_SUCCESS) { 342 | srs_freep(data); 343 | return ret; 344 | } 345 | 346 | return ret; 347 | } 348 | 349 | -------------------------------------------------------------------------------- /jni/libsrs_rtmp/srs_rtmp_utility.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2013-2015 winlin 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_RTMP_PROTOCOL_CONSTS_HPP 25 | #define SRS_RTMP_PROTOCOL_CONSTS_HPP 26 | 27 | /* 28 | #include 29 | */ 30 | #include 31 | 32 | #include 33 | 34 | #include 35 | 36 | class SrsMessageHeader; 37 | class SrsSharedPtrMessage; 38 | 39 | /** 40 | * parse the tcUrl, output the schema, host, vhost, app and port. 41 | * @param tcUrl, the input tcUrl, for example, 42 | * rtmp://192.168.1.10:19350/live?vhost=vhost.ossrs.net 43 | * @param schema, for example, rtmp 44 | * @param host, for example, 192.168.1.10 45 | * @param vhost, for example, vhost.ossrs.net. 46 | * vhost default to host, when user not set vhost in query of app. 47 | * @param app, for example, live 48 | * @param port, for example, 19350 49 | * default to 1935 if not specified. 50 | * param param, for example, vhost=vhost.ossrs.net 51 | */ 52 | extern void srs_discovery_tc_url( 53 | std::string tcUrl, 54 | std::string& schema, std::string& host, std::string& vhost, 55 | std::string& app, std::string& port, std::string& param 56 | ); 57 | 58 | /** 59 | * resolve the vhost in query string 60 | * @pram vhost, update the vhost if query contains the vhost. 61 | * @param app, may contains the vhost in query string format: 62 | * app?vhost=request_vhost 63 | * app...vhost...request_vhost 64 | * @param param, the query, for example, ?vhost=xxx 65 | */ 66 | extern void srs_vhost_resolve(std::string& vhost, std::string& app, std::string& param); 67 | 68 | /** 69 | * generate ramdom data for handshake. 70 | */ 71 | extern void srs_random_generate(char* bytes, int size); 72 | 73 | /** 74 | * generate the tcUrl. 75 | * @param param, the app parameters in tcUrl. for example, ?key=xxx,vhost=xxx 76 | * @return the tcUrl generated from ip/vhost/app/port. 77 | * @remark when vhost equals to __defaultVhost__, use ip as vhost. 78 | * @remark ignore port if port equals to default port 1935. 79 | */ 80 | extern std::string srs_generate_tc_url( 81 | std::string ip, std::string vhost, std::string app, std::string port, 82 | std::string param 83 | ); 84 | 85 | /** 86 | * compare the memory in bytes. 87 | * @return true if completely equal; otherwise, false. 88 | */ 89 | extern bool srs_bytes_equals(void* pa, void* pb, int size); 90 | 91 | /** 92 | * generate the c0 chunk header for msg. 93 | * @param cache, the cache to write header. 94 | * @param nb_cache, the size of cache. 95 | * @return the size of header. 0 if cache not enough. 96 | */ 97 | extern int srs_chunk_header_c0( 98 | int perfer_cid, u_int32_t timestamp, int32_t payload_length, 99 | int8_t message_type, int32_t stream_id, 100 | char* cache, int nb_cache 101 | ); 102 | 103 | /** 104 | * generate the c3 chunk header for msg. 105 | * @param cache, the cache to write header. 106 | * @param nb_cache, the size of cache. 107 | * @return the size of header. 0 if cache not enough. 108 | */ 109 | extern int srs_chunk_header_c3( 110 | int perfer_cid, u_int32_t timestamp, 111 | char* cache, int nb_cache 112 | ); 113 | 114 | /** 115 | * create shared ptr message from bytes. 116 | * @param data the packet bytes. user should never free it. 117 | * @param ppmsg output the shared ptr message. user should free it. 118 | */ 119 | extern int srs_rtmp_create_msg(char type, u_int32_t timestamp, char* data, int size, int stream_id, SrsSharedPtrMessage** ppmsg); 120 | 121 | #endif 122 | 123 | --------------------------------------------------------------------------------