From 98adbc413071059b25345ff7efdc1854f00829e4 Mon Sep 17 00:00:00 2001 From: winlin Date: Mon, 22 Apr 2019 08:19:03 +0800 Subject: [PATCH 01/25] Refine typo. --- trunk/src/core/srs_core.hpp | 42 +++++++++++++------------------------ 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 2fb4a3b0a..f2f638a9f 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -24,22 +24,20 @@ #ifndef SRS_CORE_HPP #define SRS_CORE_HPP -// current release version +// The version config. #define VERSION_MAJOR 3 #define VERSION_MINOR 0 #define VERSION_REVISION 49 -// generated by configure, only macros. +// The macros generated by configure script. #include -// provider info. +// The project informations, may sent to client in HTTP header or RTMP metadata. #define RTMP_SIG_SRS_KEY "SRS" #define RTMP_SIG_SRS_CODE "OuXuli" #define RTMP_SIG_SRS_AUTHROS "winlin,wenjie.zhao" -// contact info. #define RTMP_SIG_SRS_WEB "http://ossrs.net" #define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com" -// debug info. #define RTMP_SIG_SRS_ROLE "cluster" #define RTMP_SIG_SRS_URL "https://github.com/ossrs/srs" #define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)" @@ -49,33 +47,27 @@ #define RTMP_SIG_SRS_VERSION SRS_XSTR(VERSION_MAJOR) "." SRS_XSTR(VERSION_MINOR) "." SRS_XSTR(VERSION_REVISION) #define RTMP_SIG_SRS_SERVER RTMP_SIG_SRS_KEY "/" RTMP_SIG_SRS_VERSION "(" RTMP_SIG_SRS_CODE ")" -// stable major version +// The current stable release. #define VERSION_STABLE 2 #define VERSION_STABLE_BRANCH SRS_XSTR(VERSION_STABLE)".0release" -// internal macros, covert macro values to str, -// see: read https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification +// To convert macro values to string. +// @see https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification #define SRS_XSTR(v) SRS_INTERNAL_STR(v) #define SRS_INTERNAL_STR(v) #v -/** - * the core provides the common defined macros, utilities, - * user must include the srs_core.hpp before any header, or maybe - * build failed. - */ - -// for 32bit os, 2G big file limit for unistd io, +// For 32bit os, 2G big file limit for unistd io, // ie. read/write/lseek to use 64bits size for huge file. #ifndef _FILE_OFFSET_BITS #define _FILE_OFFSET_BITS 64 #endif -// for int64_t print using PRId64 format. +// For int64_t print using PRId64 format. #ifndef __STDC_FORMAT_MACROS #define __STDC_FORMAT_MACROS #endif -// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 +// For srs-librtmp, @see https://github.com/ossrs/srs/issues/213 #ifndef _WIN32 #include #endif @@ -86,22 +78,21 @@ #include #include -// Time defines. +// The time unit for timeout, interval or duration. #include // Some important performance options. #include -// free the p and set to NULL. -// p must be a T*. +// To free the p and set to NULL. +// @remark The p must be a pointer T*. #define srs_freep(p) \ if (p) { \ delete p; \ p = NULL; \ } \ (void)0 -// please use the freepa(T[]) to free an array, -// or the behavior is undefined. +// Please use the freepa(T[]) to free an array, otherwise the behavior is undefined. #define srs_freepa(pa) \ if (pa) { \ delete[] pa; \ @@ -109,11 +100,8 @@ } \ (void)0 -/** - * important check for st(state-threads), - * only support the following cpus: i386/amd64/x86_64/arm - * @reamrk to patch ST for arm, read https://github.com/ossrs/state-threads/issues/1 - */ +// Checking for st(state-threads), only support the following cpus: i386/amd64/x86_64/arm +// @reamrk to patch ST for arm, read https://github.com/ossrs/state-threads/issues/1 #if !defined(__amd64__) && !defined(__x86_64__) && !defined(__i386__) && !defined(__arm__) #error "only support i386/amd64/x86_64/arm cpu" #endif From 735176cab4e35a7ffa6417eb5235ba2e854c5928 Mon Sep 17 00:00:00 2001 From: winlin Date: Mon, 22 Apr 2019 08:21:56 +0800 Subject: [PATCH 02/25] Refine typo for core --- trunk/src/core/srs_core_autofree.hpp | 5 +---- trunk/src/core/srs_core_mem_watch.hpp | 8 +++++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/trunk/src/core/srs_core_autofree.hpp b/trunk/src/core/srs_core_autofree.hpp index 3945325d5..7844eed68 100644 --- a/trunk/src/core/srs_core_autofree.hpp +++ b/trunk/src/core/srs_core_autofree.hpp @@ -27,7 +27,7 @@ #include /** - * auto free the instance in the current scope, for instance, MyClass* ptr, + * To free the instance in the current scope, for instance, MyClass* ptr, * which is a ptr and this class will: * 1. free the ptr. * 2. set ptr to NULL. @@ -56,9 +56,6 @@ private: T** ptr; bool is_array; public: - /** - * auto delete the ptr. - */ impl_SrsAutoFree(T** p, bool array) { ptr = p; is_array = array; diff --git a/trunk/src/core/srs_core_mem_watch.hpp b/trunk/src/core/srs_core_mem_watch.hpp index 580007372..7339d5c6a 100644 --- a/trunk/src/core/srs_core_mem_watch.hpp +++ b/trunk/src/core/srs_core_mem_watch.hpp @@ -28,15 +28,17 @@ #ifdef SRS_AUTO_MEM_WATCH +#warning "MemoryWatch is deprecated." + #include -// watch the specified memory. +// Watch the specified memory. extern void srs_memory_watch(void* ptr, std::string category, int size); -// unwatch the specified memory. +// Unwatch the specified memory. extern void srs_memory_unwatch(void* ptr); -// report the memory watch. +// Report the memory watch. extern void srs_memory_report(); #endif From 35fe05d62c31326ef17041a3d620f8a14bf7155c Mon Sep 17 00:00:00 2001 From: winlin Date: Mon, 22 Apr 2019 09:19:05 +0800 Subject: [PATCH 03/25] Refine typo in kernel. --- trunk/src/core/srs_core.hpp | 2 +- trunk/src/kernel/srs_kernel_aac.hpp | 18 +- trunk/src/kernel/srs_kernel_consts.hpp | 138 ++- trunk/src/kernel/srs_kernel_error.hpp | 26 +- trunk/src/kernel/srs_kernel_flv.hpp | 581 ++++------ trunk/src/kernel/srs_kernel_log.hpp | 88 +- trunk/src/kernel/srs_kernel_mp4.hpp | 906 ++++++--------- trunk/src/kernel/srs_kernel_ts.hpp | 1406 +++++++++-------------- trunk/src/kernel/srs_kernel_utility.hpp | 132 +-- 9 files changed, 1321 insertions(+), 1976 deletions(-) diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index f2f638a9f..201263148 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -101,7 +101,7 @@ (void)0 // Checking for st(state-threads), only support the following cpus: i386/amd64/x86_64/arm -// @reamrk to patch ST for arm, read https://github.com/ossrs/state-threads/issues/1 +// @reamrk To patch ST for arm, read https://github.com/ossrs/state-threads/issues/1 #if !defined(__amd64__) && !defined(__x86_64__) && !defined(__i386__) && !defined(__arm__) #error "only support i386/amd64/x86_64/arm cpu" #endif diff --git a/trunk/src/kernel/srs_kernel_aac.hpp b/trunk/src/kernel/srs_kernel_aac.hpp index 09ff0f7cc..187e50ad2 100644 --- a/trunk/src/kernel/srs_kernel_aac.hpp +++ b/trunk/src/kernel/srs_kernel_aac.hpp @@ -35,9 +35,7 @@ class SrsBuffer; class ISrsStreamWriter; -/** - * Transmux the RTMP packets to AAC stream. - */ +// Transmux the RTMP packets to AAC stream. class SrsAacTransmuxer { private: @@ -51,17 +49,13 @@ public: SrsAacTransmuxer(); virtual ~SrsAacTransmuxer(); public: - /** - * initialize the underlayer file stream. - * @remark user can initialize multiple times to encode multiple aac files. - * @remark, user must free the fs, aac encoder never close/free it. - */ + // Initialize the underlayer file stream. + // @remark User can initialize multiple times to encode multiple aac files. + // @remark User must free the fs, aac encoder never close/free it. virtual srs_error_t initialize(ISrsStreamWriter* fs); public: - /** - * write audio/video packet. - * @remark assert data is not NULL. - */ + // Write audio/video packet. + // @remark The assert data should not be NULL. virtual srs_error_t write_audio(int64_t timestamp, char* data, int size); }; diff --git a/trunk/src/kernel/srs_kernel_consts.hpp b/trunk/src/kernel/srs_kernel_consts.hpp index 692f89624..8f09912ff 100644 --- a/trunk/src/kernel/srs_kernel_consts.hpp +++ b/trunk/src/kernel/srs_kernel_consts.hpp @@ -36,82 +36,72 @@ /////////////////////////////////////////////////////////// // RTMP consts values /////////////////////////////////////////////////////////// -// default vhost of rtmp +// Default vhost of rtmp #define SRS_CONSTS_RTMP_DEFAULT_VHOST "__defaultVhost__" #define SRS_CONSTS_RTMP_DEFAULT_APP "__defaultApp__" -// default port of rtmp +// Default port of rtmp #define SRS_CONSTS_RTMP_DEFAULT_PORT 1935 -// the default chunk size for system. +// The default chunk size for system. #define SRS_CONSTS_RTMP_SRS_CHUNK_SIZE 60000 // 6. Chunking, RTMP protocol default chunk size. #define SRS_CONSTS_RTMP_PROTOCOL_CHUNK_SIZE 128 -/** - * 6. Chunking - * The chunk size is configurable. It can be set using a control - * message(Set Chunk Size) as described in section 7.1. The maximum - * chunk size can be 65536 bytes and minimum 128 bytes. Larger values - * reduce CPU usage, but also commit to larger writes that can delay - * other content on lower bandwidth connections. Smaller chunks are not - * good for high-bit rate streaming. Chunk size is maintained - * independently for each direction. - */ +// 6. Chunking +// The chunk size is configurable. It can be set using a control +// message(Set Chunk Size) as described in section 7.1. The maximum +// chunk size can be 65536 bytes and minimum 128 bytes. Larger values +// reduce CPU usage, but also commit to larger writes that can delay +// other content on lower bandwidth connections. Smaller chunks are not +// good for high-bit rate streaming. Chunk size is maintained +// independently for each direction. #define SRS_CONSTS_RTMP_MIN_CHUNK_SIZE 128 #define SRS_CONSTS_RTMP_MAX_CHUNK_SIZE 65536 -// the following is the timeout for rtmp protocol, +// The following is the timeout for rtmp protocol, // to avoid death connection. -// the common io timeout, for connect, recv or send. +// The common io timeout, for connect, recv or send. // TODO: FIXME: Maybe change to smaller value, such as 3s? #define SRS_CONSTS_RTMP_TIMEOUT (30 * SRS_UTIME_SECONDS) -// the timeout to wait for client control message, +// The timeout to wait for client control message, // if timeout, we generally ignore and send the data to client, // generally, it's the pulse time for data seding. // @remark, recomment to 500ms. #define SRS_CONSTS_RTMP_PULSE (500 * SRS_UTIME_MILLISECONDS) -/** - * max rtmp header size: - * 1bytes basic header, - * 11bytes message header, - * 4bytes timestamp header, - * that is, 1+11+4=16bytes. - */ +// The max rtmp header size: +// 1bytes basic header, +// 11bytes message header, +// 4bytes timestamp header, +// that is, 1+11+4=16bytes. #define SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE 16 -/** - * max rtmp header size: - * 1bytes basic header, - * 4bytes timestamp header, - * that is, 1+4=5bytes. - */ +// The max rtmp header size: +// 1bytes basic header, +// 4bytes timestamp header, +// that is, 1+4=5bytes. // always use fmt0 as cache. #define SRS_CONSTS_RTMP_MAX_FMT3_HEADER_SIZE 5 -/** - * for performance issue, - * the iovs cache, @see https://github.com/ossrs/srs/issues/194 - * iovs cache for multiple messages for each connections. - * suppose the chunk size is 64k, each message send in a chunk which needs only 2 iovec, - * so the iovs max should be (SRS_PERF_MW_MSGS * 2) - * - * @remark, SRS will realloc when the iovs not enough. - */ +// For performance issue, +// the iovs cache, @see https://github.com/ossrs/srs/issues/194 +// iovs cache for multiple messages for each connections. +// suppose the chunk size is 64k, each message send in a chunk which needs only 2 iovec, +// so the iovs max should be (SRS_PERF_MW_MSGS * 2) +// +// @remark, SRS will realloc when the iovs not enough. #define SRS_CONSTS_IOVS_MAX (SRS_PERF_MW_MSGS * 2) -/** - * for performance issue, - * the c0c3 cache, @see https://github.com/ossrs/srs/issues/194 - * c0c3 cache for multiple messages for each connections. - * each c0 <= 16byes, suppose the chunk size is 64k, - * each message send in a chunk which needs only a c0 header, - * so the c0c3 cache should be (SRS_PERF_MW_MSGS * 16) - * - * @remark, SRS will try another loop when c0c3 cache dry, for we cannot realloc it. - * so we use larger c0c3 cache, that is (SRS_PERF_MW_MSGS * 32) - */ +// For performance issue, +// the c0c3 cache, @see https://github.com/ossrs/srs/issues/194 +// c0c3 cache for multiple messages for each connections. +// each c0 <= 16byes, suppose the chunk size is 64k, +// each message send in a chunk which needs only a c0 header, +// so the c0c3 cache should be (SRS_PERF_MW_MSGS * 16) +// +// @remark, SRS will try another loop when c0c3 cache dry, for we cannot realloc it. +// so we use larger c0c3 cache, that is (SRS_PERF_MW_MSGS * 32) #define SRS_CONSTS_C0C3_HEADERS_MAX (SRS_PERF_MW_MSGS * 32) /////////////////////////////////////////////////////////// @@ -127,16 +117,16 @@ #define SRS_CONSTS_NULL_FILE "/dev/null" #define SRS_CONSTS_LOCALHOST "127.0.0.1" -// signal defines. -// reload the config file and apply new config. +// The signal defines. +// To reload the config file and apply new config. #define SRS_SIGNAL_RELOAD SIGHUP -// reopen the log file. +// Reopen the log file. #define SRS_SIGNAL_REOPEN_LOG SIGUSR1 -// srs should gracefully quit, do dispose then exit. +// The signal for srs to gracefully quit, do dispose then exit. #define SRS_SIGNAL_GRACEFULLY_QUIT SIGTERM -// application level signals. -// persistence the config in memory to config file. +// The application level signals. +// Persistence the config in memory to config file. // @see https://github.com/ossrs/srs/issues/319#issuecomment-134993922 // @remark we actually don't handle the signal for it's not a valid os signal. #define SRS_SIGNAL_PERSISTENCE_CONFIG 1000 @@ -149,33 +139,33 @@ /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// -// log consts values +// The log consts values /////////////////////////////////////////////////////////// -// downloading speed-up, play to edge, ingest from origin +// Downloading speed-up, play to edge, ingest from origin #define SRS_CONSTS_LOG_EDGE_PLAY "EIG" -// uploading speed-up, publish to edge, foward to origin +// Uploading speed-up, publish to edge, foward to origin #define SRS_CONSTS_LOG_EDGE_PUBLISH "EFW" -// edge/origin forwarder. +// The edge/origin forwarder. #define SRS_CONSTS_LOG_FOWARDER "FWR" -// play stream on edge/origin. +// Play stream on edge/origin. #define SRS_CONSTS_LOG_PLAY "PLA" -// client publish to edge/origin +// Client publish to edge/origin #define SRS_CONSTS_LOG_CLIENT_PUBLISH "CPB" -// web/flash publish to edge/origin +// The web/flash publish to edge/origin #define SRS_CONSTS_LOG_WEB_PUBLISH "WPB" -// ingester for edge(play)/origin +// Ingester for edge(play)/origin #define SRS_CONSTS_LOG_INGESTER "IGS" -// hls log id. +// The hls log id. #define SRS_CONSTS_LOG_HLS "HLS" -// encoder log id. +// The encoder log id. #define SRS_CONSTS_LOG_ENCODER "ENC" -// http stream log id. +// The http stream log id. #define SRS_CONSTS_LOG_HTTP_STREAM "HTS" -// http stream cache log id. +// The http stream cache log id. #define SRS_CONSTS_LOG_HTTP_STREAM_CACHE "HTC" -// stream caster log id. +// The stream caster log id. #define SRS_CONSTS_LOG_STREAM_CASTER "SCS" -// the nginx exec log id. +// The nginx exec log id. #define SRS_CONSTS_LOG_EXEC "EXE" /////////////////////////////////////////////////////////// @@ -213,14 +203,14 @@ /////////////////////////////////////////////////////////// // HTTP consts values /////////////////////////////////////////////////////////// -// the default http port. +// The default http port. #define SRS_CONSTS_HTTP_DEFAULT_PORT 80 -// linux path seprator +// The linux path seprator #define SRS_CONSTS_HTTP_PATH_SEP '/' -// query string seprator +// Query string seprator #define SRS_CONSTS_HTTP_QUERY_SEP '?' -// the default recv timeout. +// The default recv timeout. #define SRS_HTTP_RECV_TIMEOUT (60 * SRS_UTIME_SECONDS) // 6.1.1 Status Code and Reason Phrase @@ -405,7 +395,7 @@ /////////////////////////////////////////////////////////// #define SRS_CONSTS_KAFKA_DEFAULT_PORT 9092 -// the common io timeout, for both recv and send. +// The common io timeout, for both recv and send. #define SRS_CONSTS_KAFKA_TIMEOUT (30 * SRS_UTIME_MILLISECONDS) #endif diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index 62c776636..95ab4cd36 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -28,13 +28,13 @@ #include -// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 +// For srs-librtmp, @see https://github.com/ossrs/srs/issues/213 #ifndef _WIN32 #define ERROR_SUCCESS 0 #endif /////////////////////////////////////////////////////// -// system error. +// The system error. /////////////////////////////////////////////////////// #define ERROR_SOCKET_CREATE 1000 #define ERROR_SOCKET_SETREUSE 1001 @@ -173,18 +173,18 @@ #define ERROR_RTMP_STREAM_NAME_EMPTY 2051 #define ERROR_HTTP_HIJACK 2052 // -// system control message, -// not an error, but special control logic. +// The system control message, +// It's not an error, but special control logic. // -// connection is redirect to another server. +// When connection is redirect to another server. #define ERROR_CONTROL_REDIRECT 2997 -// sys ctl: rtmp close stream, support replay. +// For sys ctl: rtmp close stream, support replay. #define ERROR_CONTROL_RTMP_CLOSE 2998 -// FMLE stop publish and republish. +// When FMLE stop publish and republish. #define ERROR_CONTROL_REPUBLISH 2999 /////////////////////////////////////////////////////// -// application level +// The application level errors. /////////////////////////////////////////////////////// #define ERROR_HLS_METADATA 3000 #define ERROR_HLS_DECODE_ERROR 3001 @@ -329,23 +329,23 @@ //#define ERROR_API_METHOD_NOT_ALLOWD /////////////////////////////////////////////////////// -// user-define error. +// For user-define error. /////////////////////////////////////////////////////// #define ERROR_USER_START 9000 //#define ERROR_USER_DISCONNECT 9001 #define ERROR_SOURCE_NOT_FOUND 9002 #define ERROR_USER_END 9999 -/** - * whether the error code is an system control error. - */ +// Whether the error code is an system control error. // TODO: FIXME: Remove it from underlayer for confused with error and logger. extern bool srs_is_system_control_error(int error_code); extern bool srs_is_system_control_error(srs_error_t err); extern bool srs_is_client_gracefully_close(int error_code); extern bool srs_is_client_gracefully_close(srs_error_t err); -// Use complex errors, @read https://github.com/ossrs/srs/issues/913 +// The complex error carries code, message, callstack and instant variables, +// which is more strong and easy to locate problem by log, +// please @read https://github.com/ossrs/srs/issues/913 class SrsCplxError { private: diff --git a/trunk/src/kernel/srs_kernel_flv.hpp b/trunk/src/kernel/srs_kernel_flv.hpp index 685bf7284..80cd62e9c 100644 --- a/trunk/src/kernel/srs_kernel_flv.hpp +++ b/trunk/src/kernel/srs_kernel_flv.hpp @@ -28,7 +28,7 @@ #include -// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 +// For srs-librtmp, @see https://github.com/ossrs/srs/issues/213 #ifndef _WIN32 #include #endif @@ -40,19 +40,13 @@ class SrsFileReader; #define SRS_FLV_TAG_HEADER_SIZE 11 #define SRS_FLV_PREVIOUS_TAG_SIZE 4 - -/**************************************************************************** - ***************************************************************************** - ****************************************************************************/ -/** - 5. Protocol Control Messages - RTMP reserves message type IDs 1-7 for protocol control messages. - These messages contain information needed by the RTM Chunk Stream - protocol or RTMP itself. Protocol messages with IDs 1 & 2 are - reserved for usage with RTM Chunk Stream protocol. Protocol messages - with IDs 3-6 are reserved for usage of RTMP. Protocol message with ID - 7 is used between edge server and origin server. - */ +// 5. Protocol Control Messages +// RTMP reserves message type IDs 1-7 for protocol control messages. +// These messages contain information needed by the RTM Chunk Stream +// protocol or RTMP itself. Protocol messages with IDs 1 & 2 are +// reserved for usage with RTM Chunk Stream protocol. Protocol messages +// with IDs 3-6 are reserved for usage of RTMP. Protocol message with ID +// 7 is used between edge server and origin server. #define RTMP_MSG_SetChunkSize 0x01 #define RTMP_MSG_AbortMessage 0x02 #define RTMP_MSG_Acknowledgement 0x03 @@ -60,167 +54,121 @@ class SrsFileReader; #define RTMP_MSG_WindowAcknowledgementSize 0x05 #define RTMP_MSG_SetPeerBandwidth 0x06 #define RTMP_MSG_EdgeAndOriginServerCommand 0x07 -/** - 3. Types of messages - The server and the client send messages over the network to - communicate with each other. The messages can be of any type which - includes audio messages, video messages, command messages, shared - object messages, data messages, and user control messages. - 3.1. Command message - Command messages carry the AMF-encoded commands between the client - and the server. These messages have been assigned message type value - of 20 for AMF0 encoding and message type value of 17 for AMF3 - encoding. These messages are sent to perform some operations like - connect, createStream, publish, play, pause on the peer. Command - messages like onstatus, result etc. are used to inform the sender - about the status of the requested commands. A command message - consists of command name, transaction ID, and command object that - contains related parameters. A client or a server can request Remote - Procedure Calls (RPC) over streams that are communicated using the - command messages to the peer. - */ +// 3. Types of messages +// The server and the client send messages over the network to +// communicate with each other. The messages can be of any type which +// includes audio messages, video messages, command messages, shared +// object messages, data messages, and user control messages. +// 3.1. Command message +// Command messages carry the AMF-encoded commands between the client +// and the server. These messages have been assigned message type value +// of 20 for AMF0 encoding and message type value of 17 for AMF3 +// encoding. These messages are sent to perform some operations like +// connect, createStream, publish, play, pause on the peer. Command +// messages like onstatus, result etc. are used to inform the sender +// about the status of the requested commands. A command message +// consists of command name, transaction ID, and command object that +// contains related parameters. A client or a server can request Remote +// Procedure Calls (RPC) over streams that are communicated using the +// command messages to the peer. #define RTMP_MSG_AMF3CommandMessage 17 // 0x11 #define RTMP_MSG_AMF0CommandMessage 20 // 0x14 -/** - 3.2. Data message - The client or the server sends this message to send Metadata or any - user data to the peer. Metadata includes details about the - data(audio, video etc.) like creation time, duration, theme and so - on. These messages have been assigned message type value of 18 for - AMF0 and message type value of 15 for AMF3. - */ +// 3.2. Data message +// The client or the server sends this message to send Metadata or any +// user data to the peer. Metadata includes details about the +// data(audio, video etc.) like creation time, duration, theme and so +// on. These messages have been assigned message type value of 18 for +// AMF0 and message type value of 15 for AMF3. #define RTMP_MSG_AMF0DataMessage 18 // 0x12 #define RTMP_MSG_AMF3DataMessage 15 // 0x0F -/** - 3.3. Shared object message - A shared object is a Flash object (a collection of name value pairs) - that are in synchronization across multiple clients, instances, and - so on. The message types kMsgContainer=19 for AMF0 and - kMsgContainerEx=16 for AMF3 are reserved for shared object events. - Each message can contain multiple events. - */ +// 3.3. Shared object message +// A shared object is a Flash object (a collection of name value pairs) +// that are in synchronization across multiple clients, instances, and +// so on. The message types kMsgContainer=19 for AMF0 and +// kMsgContainerEx=16 for AMF3 are reserved for shared object events. +// Each message can contain multiple events. #define RTMP_MSG_AMF3SharedObject 16 // 0x10 #define RTMP_MSG_AMF0SharedObject 19 // 0x13 -/** - 3.4. Audio message - The client or the server sends this message to send audio data to the - peer. The message type value of 8 is reserved for audio messages. - */ +// 3.4. Audio message +// The client or the server sends this message to send audio data to the +// peer. The message type value of 8 is reserved for audio messages. #define RTMP_MSG_AudioMessage 8 // 0x08 -/* * - 3.5. Video message - The client or the server sends this message to send video data to the - peer. The message type value of 9 is reserved for video messages. - These messages are large and can delay the sending of other type of - messages. To avoid such a situation, the video message is assigned - the lowest priority. - */ +// 3.5. Video message +// The client or the server sends this message to send video data to the +// peer. The message type value of 9 is reserved for video messages. +// These messages are large and can delay the sending of other type of +// messages. To avoid such a situation, the video message is assigned +// The lowest priority. #define RTMP_MSG_VideoMessage 9 // 0x09 -/** - 3.6. Aggregate message - An aggregate message is a single message that contains a list of submessages. - The message type value of 22 is reserved for aggregate - messages. - */ +// 3.6. Aggregate message +// An aggregate message is a single message that contains a list of submessages. +// The message type value of 22 is reserved for aggregate +// messages. #define RTMP_MSG_AggregateMessage 22 // 0x16 - -/**************************************************************************** - ***************************************************************************** - ****************************************************************************/ -/** - * the chunk stream id used for some under-layer message, - * for example, the PC(protocol control) message. - */ +// The chunk stream id used for some under-layer message, +// For example, the PC(protocol control) message. #define RTMP_CID_ProtocolControl 0x02 -/** - * the AMF0/AMF3 command message, invoke method and return the result, over NetConnection. - * generally use 0x03. - */ +// The AMF0/AMF3 command message, invoke method and return the result, over NetConnection. +// generally use 0x03. #define RTMP_CID_OverConnection 0x03 -/** - * the AMF0/AMF3 command message, invoke method and return the result, over NetConnection, - * the midst state(we guess). - * rarely used, e.g. onStatus(NetStream.Play.Reset). - */ +// The AMF0/AMF3 command message, invoke method and return the result, over NetConnection, +// The midst state(we guess). +// rarely used, e.g. onStatus(NetStream.Play.Reset). #define RTMP_CID_OverConnection2 0x04 -/** - * the stream message(amf0/amf3), over NetStream. - * generally use 0x05. - */ +// The stream message(amf0/amf3), over NetStream. +// generally use 0x05. #define RTMP_CID_OverStream 0x05 -/** - * the stream message(amf0/amf3), over NetStream, the midst state(we guess). - * rarely used, e.g. play("mp4:mystram.f4v") - */ +// The stream message(amf0/amf3), over NetStream, the midst state(we guess). +// rarely used, e.g. play("mp4:mystram.f4v") #define RTMP_CID_OverStream2 0x08 -/** - * the stream message(video), over NetStream - * generally use 0x06. - */ +// The stream message(video), over NetStream +// generally use 0x06. #define RTMP_CID_Video 0x06 -/** - * the stream message(audio), over NetStream. - * generally use 0x07. - */ +// The stream message(audio), over NetStream. +// generally use 0x07. #define RTMP_CID_Audio 0x07 -/** - * 6.1. Chunk Format - * Extended timestamp: 0 or 4 bytes - * This field MUST be sent when the normal timsestamp is set to - * 0xffffff, it MUST NOT be sent if the normal timestamp is set to - * anything else. So for values less than 0xffffff the normal - * timestamp field SHOULD be used in which case the extended timestamp - * MUST NOT be present. For values greater than or equal to 0xffffff - * the normal timestamp field MUST NOT be used and MUST be set to - * 0xffffff and the extended timestamp MUST be sent. - */ +// 6.1. Chunk Format +// Extended timestamp: 0 or 4 bytes +// This field MUST be sent when the normal timsestamp is set to +// 0xffffff, it MUST NOT be sent if the normal timestamp is set to +// anything else. So for values less than 0xffffff the normal +// timestamp field SHOULD be used in which case the extended timestamp +// MUST NOT be present. For values greater than or equal to 0xffffff +// The normal timestamp field MUST NOT be used and MUST be set to +// 0xffffff and the extended timestamp MUST be sent. #define RTMP_EXTENDED_TIMESTAMP 0xFFFFFF -/** - * 4.1. Message Header - */ +// 4.1. Message Header class SrsMessageHeader { public: - /** - * 3bytes. - * Three-byte field that contains a timestamp delta of the message. - * @remark, only used for decoding message from chunk stream. - */ + // 3bytes. + // Three-byte field that contains a timestamp delta of the message. + // @remark, only used for decoding message from chunk stream. int32_t timestamp_delta; - /** - * 3bytes. - * Three-byte field that represents the size of the payload in bytes. - * It is set in big-endian format. - */ + // 3bytes. + // Three-byte field that represents the size of the payload in bytes. + // It is set in big-endian format. int32_t payload_length; - /** - * 1byte. - * One byte field to represent the message type. A range of type IDs - * (1-7) are reserved for protocol control messages. - */ + // 1byte. + // One byte field to represent the message type. A range of type IDs + // (1-7) are reserved for protocol control messages. int8_t message_type; - /** - * 4bytes. - * Four-byte field that identifies the stream of the message. These - * bytes are set in little-endian format. - */ + // 4bytes. + // Four-byte field that identifies the stream of the message. These + // bytes are set in little-endian format. int32_t stream_id; - /** - * Four-byte field that contains a timestamp of the message. - * The 4 bytes are packed in the big-endian order. - * @remark, used as calc timestamp when decode and encode time. - * @remark, we use 64bits for large time for jitter detect and hls. - */ + // Four-byte field that contains a timestamp of the message. + // The 4 bytes are packed in the big-endian order. + // @remark, used as calc timestamp when decode and encode time. + // @remark, we use 64bits for large time for jitter detect and hls. int64_t timestamp; public: - /** - * get the perfered cid(chunk stream id) which sendout over. - * set at decoding, and canbe used for directly send message, - * for example, dispatch to all connections. - */ + // Get the perfered cid(chunk stream id) which sendout over. + // set at decoding, and canbe used for directly send message, + // For example, dispatch to all connections. int perfer_cid; public: SrsMessageHeader(); @@ -239,149 +187,114 @@ public: bool is_set_peer_bandwidth(); bool is_aggregate(); public: - /** - * create a amf0 script header, set the size and stream_id. - */ + // Create a amf0 script header, set the size and stream_id. void initialize_amf0_script(int size, int stream); - /** - * create a audio header, set the size, timestamp and stream_id. - */ + // Create a audio header, set the size, timestamp and stream_id. void initialize_audio(int size, uint32_t time, int stream); - /** - * create a video header, set the size, timestamp and stream_id. - */ + // Create a video header, set the size, timestamp and stream_id. void initialize_video(int size, uint32_t time, int stream); }; -/** - * message is raw data RTMP message, bytes oriented, - * protcol always recv RTMP message, and can send RTMP message or RTMP packet. - * the common message is read from underlay protocol sdk. - * while the shared ptr message used to copy and send. - */ +// The message is raw data RTMP message, bytes oriented, +// protcol always recv RTMP message, and can send RTMP message or RTMP packet. +// The common message is read from underlay protocol sdk. +// while the shared ptr message used to copy and send. class SrsCommonMessage { - // 4.1. Message Header +// 4.1. Message Header public: SrsMessageHeader header; - // 4.2. Message Payload +// 4.2. Message Payload public: - /** - * current message parsed size, - * size <= header.payload_length - * for the payload maybe sent in multiple chunks. - */ + // The current message parsed size, + // size <= header.payload_length + // For the payload maybe sent in multiple chunks. int size; - /** - * the payload of message, the SrsCommonMessage never know about the detail of payload, - * user must use SrsProtocol.decode_message to get concrete packet. - * @remark, not all message payload can be decoded to packet. for example, - * video/audio packet use raw bytes, no video/audio packet. - */ + // The payload of message, the SrsCommonMessage never know about the detail of payload, + // user must use SrsProtocol.decode_message to get concrete packet. + // @remark, not all message payload can be decoded to packet. for example, + // video/audio packet use raw bytes, no video/audio packet. char* payload; public: SrsCommonMessage(); virtual ~SrsCommonMessage(); public: - /** - * alloc the payload to specified size of bytes. - */ + // Alloc the payload to specified size of bytes. virtual void create_payload(int size); public: - /** - * create common message, - * from the header and body. - * @remark user should never free the body. - * @param pheader, the header to copy to the message. NULL to ignore. - */ + // Create common message, + // from the header and body. + // @remark user should never free the body. + // @param pheader, the header to copy to the message. NULL to ignore. virtual srs_error_t create(SrsMessageHeader* pheader, char* body, int size); }; -/** - * the message header for shared ptr message. - * only the message for all msgs are same. - */ +// The message header for shared ptr message. +// only the message for all msgs are same. struct SrsSharedMessageHeader { - /** - * 3bytes. - * Three-byte field that represents the size of the payload in bytes. - * It is set in big-endian format. - */ + // 3bytes. + // Three-byte field that represents the size of the payload in bytes. + // It is set in big-endian format. int32_t payload_length; - /** - * 1byte. - * One byte field to represent the message type. A range of type IDs - * (1-7) are reserved for protocol control messages. - */ + // 1byte. + // One byte field to represent the message type. A range of type IDs + // (1-7) are reserved for protocol control messages. int8_t message_type; - /** - * get the perfered cid(chunk stream id) which sendout over. - * set at decoding, and canbe used for directly send message, - * for example, dispatch to all connections. - */ + // Get the perfered cid(chunk stream id) which sendout over. + // set at decoding, and canbe used for directly send message, + // For example, dispatch to all connections. int perfer_cid; SrsSharedMessageHeader(); virtual ~SrsSharedMessageHeader(); }; -/** - * shared ptr message. - * for audio/video/data message that need less memory copy. - * and only for output. - * - * create first object by constructor and create(), - * use copy if need reference count message. - * - */ +// The shared ptr message. +// For audio/video/data message that need less memory copy. +// and only for output. +// +// Create first object by constructor and create(), +// use copy if need reference count message. class SrsSharedPtrMessage { - // 4.1. Message Header +// 4.1. Message Header public: - // the header can shared, only set the timestamp and stream id. + // The header can shared, only set the timestamp and stream id. // @see https://github.com/ossrs/srs/issues/251 //SrsSharedMessageHeader header; - /** - * Four-byte field that contains a timestamp of the message. - * The 4 bytes are packed in the big-endian order. - * @remark, used as calc timestamp when decode and encode time. - * @remark, we use 64bits for large time for jitter detect and hls. - */ + // Four-byte field that contains a timestamp of the message. + // The 4 bytes are packed in the big-endian order. + // @remark, used as calc timestamp when decode and encode time. + // @remark, we use 64bits for large time for jitter detect and hls. int64_t timestamp; - /** - * 4bytes. - * Four-byte field that identifies the stream of the message. These - * bytes are set in big-endian format. - */ + // 4bytes. + // Four-byte field that identifies the stream of the message. These + // bytes are set in big-endian format. int32_t stream_id; // 4.2. Message Payload public: - /** - * current message parsed size, - * size <= header.payload_length - * for the payload maybe sent in multiple chunks. - */ + // The current message parsed size, + // size <= header.payload_length + // For the payload maybe sent in multiple chunks. int size; - /** - * the payload of message, the SrsCommonMessage never know about the detail of payload, - * user must use SrsProtocol.decode_message to get concrete packet. - * @remark, not all message payload can be decoded to packet. for example, - * video/audio packet use raw bytes, no video/audio packet. - */ + // The payload of message, the SrsCommonMessage never know about the detail of payload, + // user must use SrsProtocol.decode_message to get concrete packet. + // @remark, not all message payload can be decoded to packet. for example, + // video/audio packet use raw bytes, no video/audio packet. char* payload; private: class SrsSharedPtrPayload { public: - // shared message header. + // The shared message header. // @see https://github.com/ossrs/srs/issues/251 SrsSharedMessageHeader header; - // actual shared payload. + // The actual shared payload. char* payload; - // size of payload. + // The size of payload. int size; - // the reference count + // The reference count int shared_count; public: SrsSharedPtrPayload(); @@ -392,54 +305,40 @@ public: SrsSharedPtrMessage(); virtual ~SrsSharedPtrMessage(); public: - /** - * create shared ptr message, - * copy header, manage the payload of msg, - * set the payload to NULL to prevent double free. - * @remark payload of msg set to NULL if success. - */ + // Create shared ptr message, + // copy header, manage the payload of msg, + // set the payload to NULL to prevent double free. + // @remark payload of msg set to NULL if success. virtual srs_error_t create(SrsCommonMessage* msg); - /** - * create shared ptr message, - * from the header and payload. - * @remark user should never free the payload. - * @param pheader, the header to copy to the message. NULL to ignore. - */ + // Create shared ptr message, + // from the header and payload. + // @remark user should never free the payload. + // @param pheader, the header to copy to the message. NULL to ignore. virtual srs_error_t create(SrsMessageHeader* pheader, char* payload, int size); - /** - * get current reference count. - * when this object created, count set to 0. - * if copy() this object, count increase 1. - * if this or copy deleted, free payload when count is 0, or count--. - * @remark, assert object is created. - */ + // Get current reference count. + // when this object created, count set to 0. + // if copy() this object, count increase 1. + // if this or copy deleted, free payload when count is 0, or count--. + // @remark, assert object is created. virtual int count(); - /** - * check perfer cid and stream id. - * @return whether stream id already set. - */ + // check perfer cid and stream id. + // @return whether stream id already set. virtual bool check(int stream_id); public: virtual bool is_av(); virtual bool is_audio(); virtual bool is_video(); public: - /** - * generate the chunk header to cache. - * @return the size of header. - */ + // generate the chunk header to cache. + // @return the size of header. virtual int chunk_header(char* cache, int nb_cache, bool c0); public: - /** - * copy current shared ptr message, use ref-count. - * @remark, assert object is created. - */ + // copy current shared ptr message, use ref-count. + // @remark, assert object is created. virtual SrsSharedPtrMessage* copy(); }; -/** - * Transmux RTMP packets to FLV stream. - */ +// Transmux RTMP packets to FLV stream. class SrsFlvTransmuxer { private: @@ -450,60 +349,48 @@ public: SrsFlvTransmuxer(); virtual ~SrsFlvTransmuxer(); public: - /** - * initialize the underlayer file stream. - * @remark user can initialize multiple times to encode multiple flv files. - * @remark, user must free the @param fw, flv encoder never close/free it. - */ + // Initialize the underlayer file stream. + // @remark user can initialize multiple times to encode multiple flv files. + // @remark, user must free the @param fw, flv encoder never close/free it. virtual srs_error_t initialize(ISrsWriter* fw); public: - /** - * write flv header. - * write following: - * 1. E.2 The FLV header - * 2. PreviousTagSize0 UI32 Always 0 - * that is, 9+4=13bytes. - */ + // Write flv header. + // Write following: + // 1. E.2 The FLV header + // 2. PreviousTagSize0 UI32 Always 0 + // that is, 9+4=13bytes. virtual srs_error_t write_header(); virtual srs_error_t write_header(char flv_header[9]); - /** - * write flv metadata. - * @param type, the type of data, or other message type. - * @see SrsFrameType - * @param data, the amf0 metadata which serialize from: - * AMF0 string: onMetaData, - * AMF0 object: the metadata object. - * @remark assert data is not NULL. - */ + // Write flv metadata. + // @param type, the type of data, or other message type. + // @see SrsFrameType + // @param data, the amf0 metadata which serialize from: + // AMF0 string: onMetaData, + // AMF0 object: the metadata object. + // @remark assert data is not NULL. virtual srs_error_t write_metadata(char type, char* data, int size); - /** - * write audio/video packet. - * @remark assert data is not NULL. - */ + // Write audio/video packet. + // @remark assert data is not NULL. virtual srs_error_t write_audio(int64_t timestamp, char* data, int size); virtual srs_error_t write_video(int64_t timestamp, char* data, int size); public: - /** - * get the tag size, - * including the tag header, body, and 4bytes previous tag size. - * @remark assert data_size is not negative. - */ + // Get the tag size, + // including the tag header, body, and 4bytes previous tag size. + // @remark assert data_size is not negative. static int size_tag(int data_size); #ifdef SRS_PERF_FAST_FLV_ENCODER private: - // cache tag header. + // The cache tag header. int nb_tag_headers; char* tag_headers; - // cache pps(previous tag size) + // The cache pps(previous tag size) int nb_ppts; char* ppts; - // cache iovss. + // The cache iovss. int nb_iovss_cache; iovec* iovss_cache; public: - /** - * write the tags in a time. - */ + // Write the tags in a time. virtual srs_error_t write_tags(SrsSharedPtrMessage** msgs, int count); #endif private: @@ -514,9 +401,7 @@ private: virtual srs_error_t write_tag(char* header, int header_size, char* tag, int tag_size); }; -/** - * decode flv file. - */ +// Decode flv file. class SrsFlvDecoder { private: @@ -525,40 +410,28 @@ public: SrsFlvDecoder(); virtual ~SrsFlvDecoder(); public: - /** - * initialize the underlayer file stream - * @remark user can initialize multiple times to decode multiple flv files. - * @remark user must free the @param fr, flv decoder never close/free it - */ + // Initialize the underlayer file stream + // @remark user can initialize multiple times to decode multiple flv files. + // @remark user must free the @param fr, flv decoder never close/free it virtual srs_error_t initialize(ISrsReader* fr); public: - /** - * read the flv header, donot including the 4bytes previous tag size. - * @remark assert header not NULL. - */ + // Read the flv header, donot including the 4bytes previous tag size. + // @remark assert header not NULL. virtual srs_error_t read_header(char header[9]); - /** - * read the tag header infos. - * @remark assert ptype/pdata_size/ptime not NULL. - */ + // Read the tag header infos. + // @remark assert ptype/pdata_size/ptime not NULL. virtual srs_error_t read_tag_header(char* ptype, int32_t* pdata_size, uint32_t* ptime); - /** - * read the tag data. - * @remark assert data not NULL. - */ + // Read the tag data. + // @remark assert data not NULL. virtual srs_error_t read_tag_data(char* data, int32_t size); - /** - * read the 4bytes previous tag size. - * @remark assert previous_tag_size not NULL. - */ + // Read the 4bytes previous tag size. + // @remark assert previous_tag_size not NULL. virtual srs_error_t read_previous_tag_size(char previous_tag_size[4]); }; -/** - * decode flv fast by only decoding the header and tag. - * used for vod flv stream to read the header and sequence header, - * then seek to specified offset. - */ +// Decode flv fast by only decoding the header and tag. +// used for vod flv stream to read the header and sequence header, +// then seek to specified offset. class SrsFlvVodStreamDecoder { private: @@ -567,31 +440,23 @@ public: SrsFlvVodStreamDecoder(); virtual ~SrsFlvVodStreamDecoder(); public: - /** - * initialize the underlayer file stream - * @remark user can initialize multiple times to decode multiple flv files. - * @remark user must free the @param fr, flv decoder never close/free it. - */ + // Initialize the underlayer file stream + // @remark user can initialize multiple times to decode multiple flv files. + // @remark user must free the @param fr, flv decoder never close/free it. virtual srs_error_t initialize(ISrsReader* fr); public: - /** - * read the flv header and its size. - * @param header, fill it 13bytes(9bytes header, 4bytes previous tag size). - * @remark assert header not NULL. - */ + // Read the flv header and its size. + // @param header, fill it 13bytes(9bytes header, 4bytes previous tag size). + // @remark assert header not NULL. virtual srs_error_t read_header_ext(char header[13]); - /** - * read the sequence header tags offset and its size. - * @param pstart, the start offset of sequence header. - * @param psize, output the size, (tag header)+(tag body)+(4bytes previous tag size). - * @remark we think the first audio/video is sequence header. - * @remark assert pstart/psize not NULL. - */ + // Read the sequence header tags offset and its size. + // @param pstart, the start offset of sequence header. + // @param psize, output the size, (tag header)+(tag body)+(4bytes previous tag size). + // @remark we think the first audio/video is sequence header. + // @remark assert pstart/psize not NULL. virtual srs_error_t read_sequence_header_summary(int64_t* pstart, int* psize); public: - /** - * for start offset, seed to this position and response flv stream. - */ + // For start offset, seed to this position and response flv stream. virtual srs_error_t seek2(int64_t offset); }; diff --git a/trunk/src/kernel/srs_kernel_log.hpp b/trunk/src/kernel/srs_kernel_log.hpp index f371455e4..23d4399c4 100644 --- a/trunk/src/kernel/srs_kernel_log.hpp +++ b/trunk/src/kernel/srs_kernel_log.hpp @@ -33,15 +33,13 @@ #include -/** - * the log level, for example: - * if specified Debug level, all level messages will be logged. - * if specified Warn level, only Warn/Error/Fatal level messages will be logged. - */ +// The log level, for example: +// if specified Debug level, all level messages will be logged. +// if specified Warn level, only Warn/Error/Fatal level messages will be logged. enum SrsLogLevel { SrsLogLevelForbidden = 0x00, - // only used for very verbose debug, generally, + // Only used for very verbose debug, generally, // we compile without this level for high performance. SrsLogLevelVerbose = 0x01, SrsLogLevelInfo = 0x02, @@ -51,85 +49,63 @@ enum SrsLogLevel SrsLogLevelDisabled = 0x20, }; -/** - * the log interface provides method to write log. - * but we provides some macro, which enable us to disable the log when compile. - * @see also SmtDebug/SmtTrace/SmtWarn/SmtError which is corresponding to Debug/Trace/Warn/Fatal. - */ +// The log interface provides method to write log. +// but we provides some macro, which enable us to disable the log when compile. +// @see also SmtDebug/SmtTrace/SmtWarn/SmtError which is corresponding to Debug/Trace/Warn/Fatal. class ISrsLog { public: ISrsLog(); virtual ~ISrsLog(); public: - /** - * initialize log utilities. - */ + // Initialize log utilities. virtual srs_error_t initialize(); - /** - * reopen the log file for log rotate. - */ + // Reopen the log file for log rotate. virtual void reopen(); public: - /** - * log for verbose, very verbose information. - */ + // The log for verbose, very verbose information. virtual void verbose(const char* tag, int context_id, const char* fmt, ...); - /** - * log for debug, detail information. - */ + // The log for debug, detail information. virtual void info(const char* tag, int context_id, const char* fmt, ...); - /** - * log for trace, important information. - */ + // The log for trace, important information. virtual void trace(const char* tag, int context_id, const char* fmt, ...); - /** - * log for warn, warn is something should take attention, but not a error. - */ + // The log for warn, warn is something should take attention, but not a error. virtual void warn(const char* tag, int context_id, const char* fmt, ...); - /** - * log for error, something error occur, do something about the error, ie. close the connection, - * but we will donot abort the program. - */ + // The log for error, something error occur, do something about the error, ie. close the connection, + // but we will donot abort the program. virtual void error(const char* tag, int context_id, const char* fmt, ...); }; -/** - * the context id manager to identify context, for instance, the green-thread. - * usage: - * _srs_context->generate_id(); // when thread start. - * _srs_context->get_id(); // get current generated id. - * int old_id = _srs_context->set_id(1000); // set context id if need to merge thread context. - */ -// the context for multiple clients. +// The context id manager to identify context, for instance, the green-thread. +// Usage: +// _srs_context->generate_id(); // when thread start. +// _srs_context->get_id(); // get current generated id. +// int old_id = _srs_context->set_id(1000); // set context id if need to merge thread context. +// The context for multiple clients. class ISrsThreadContext { public: ISrsThreadContext(); virtual ~ISrsThreadContext(); public: - /** - * generate the id for current context. - */ + // Generate the id for current context. virtual int generate_id(); - /** - * get the generated id of current context. - */ + // Get the generated id of current context. virtual int get_id(); - /** - * set the id of current context. - * @return the previous id value; 0 if no context. - */ + // Set the id of current context. + // @return the previous id value; 0 if no context. virtual int set_id(int v); }; -// @global user must provides a log object +// @global User must provides a log object extern ISrsLog* _srs_log; -// @global user must implements the LogContext and define a global instance. +// @global User must implements the LogContext and define a global instance. extern ISrsThreadContext* _srs_context; -// donot print method +// Log style. +// Use __FUNCTION__ to print c method +// Use __PRETTY_FUNCTION__ to print c++ class:method #if 1 #define srs_verbose(msg, ...) _srs_log->verbose(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_info(msg, ...) _srs_log->info(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) @@ -137,7 +113,6 @@ extern ISrsThreadContext* _srs_context; #define srs_warn(msg, ...) _srs_log->warn(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_error(msg, ...) _srs_log->error(NULL, _srs_context->get_id(), msg, ##__VA_ARGS__) #endif -// use __FUNCTION__ to print c method #if 0 #define srs_verbose(msg, ...) _srs_log->verbose(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_info(msg, ...) _srs_log->info(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) @@ -145,7 +120,6 @@ extern ISrsThreadContext* _srs_context; #define srs_warn(msg, ...) _srs_log->warn(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_error(msg, ...) _srs_log->error(__FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) #endif -// use __PRETTY_FUNCTION__ to print c++ class:method #if 0 #define srs_verbose(msg, ...) _srs_log->verbose(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) #define srs_info(msg, ...) _srs_log->info(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) @@ -154,7 +128,7 @@ extern ISrsThreadContext* _srs_context; #define srs_error(msg, ...) _srs_log->error(__PRETTY_FUNCTION__, _srs_context->get_id(), msg, ##__VA_ARGS__) #endif -// TODO: FIXME: add more verbose and info logs. +// TODO: FIXME: Add more verbose and info logs. #ifndef SRS_AUTO_VERBOSE #undef srs_verbose #define srs_verbose(msg, ...) (void)0 diff --git a/trunk/src/kernel/srs_kernel_mp4.hpp b/trunk/src/kernel/srs_kernel_mp4.hpp index 6b3bed71b..593eb56b8 100644 --- a/trunk/src/kernel/srs_kernel_mp4.hpp +++ b/trunk/src/kernel/srs_kernel_mp4.hpp @@ -71,10 +71,8 @@ class SrsMp4TrackFragmentHeaderBox; class SrsMp4TrackFragmentDecodeTimeBox; class SrsMp4TrackFragmentRunBox; -/** - * 4.2 Object Structure - * ISO_IEC_14496-12-base-format-2012.pdf, page 16 - */ +// 4.2 Object Structure +// ISO_IEC_14496-12-base-format-2012.pdf, page 16 enum SrsMp4BoxType { SrsMp4BoxTypeForbidden = 0x00, @@ -127,10 +125,8 @@ enum SrsMp4BoxType SrsMp4BoxTypeTRUN = 0x7472756e, // 'trun' }; -/** - * 8.4.3.3 Semantics - * ISO_IEC_14496-12-base-format-2012.pdf, page 37 - */ +// 8.4.3.3 Semantics +// ISO_IEC_14496-12-base-format-2012.pdf, page 37 enum SrsMp4HandlerType { SrsMp4HandlerTypeForbidden = 0x00, @@ -139,10 +135,8 @@ enum SrsMp4HandlerType SrsMp4HandlerTypeSOUN = 0x736f756e, // 'soun' }; -/** - * File format brands - * ISO_IEC_14496-12-base-format-2012.pdf, page 166 - */ +// File format brands +// ISO_IEC_14496-12-base-format-2012.pdf, page 166 enum SrsMp4BoxBrand { SrsMp4BoxBrandForbidden = 0x00, @@ -156,9 +150,7 @@ enum SrsMp4BoxBrand SrsMp4BoxBrandMSDH = 0x6d736468, // 'msdh' }; -/** - * The context to dump. - */ +// The context to dump. struct SrsMp4DumpContext { int level; @@ -167,15 +159,13 @@ struct SrsMp4DumpContext SrsMp4DumpContext indent(); }; -/** - * 4.2 Object Structure - * ISO_IEC_14496-12-base-format-2012.pdf, page 16 - */ +// 4.2 Object Structure +// ISO_IEC_14496-12-base-format-2012.pdf, page 16 class SrsMp4Box : public ISrsCodec { private: // The size is the entire size of the box, including the size and type header, fields, - // and all contained boxes. This facilitates general parsing of the file. + // And all contained boxes. This facilitates general parsing of the file. // // if size is 1 then the actual size is in the field largesize; // if size is 0, then this box is the last one in the file, and its contents @@ -185,7 +175,7 @@ private: public: // identifies the box type; standard boxes use a compact type, which is normally four printable // characters, to permit ease of identification, and is shown so in the boxes below. User extensions use - // an extended type; in this case, the type field is set to ‘uuid’. + // An extended type; in this case, the type field is set to ‘uuid’. SrsMp4BoxType type; // For box 'uuid'. std::vector usertype; @@ -218,10 +208,8 @@ public: virtual int remove(SrsMp4BoxType bt); // Dumps the box and all contained boxes. virtual std::stringstream& dumps(std::stringstream& ss, SrsMp4DumpContext dc); - /** - * Discovery the box from buffer. - * @param ppbox Output the discoveried box, which user must free it. - */ + // Discovery the box from buffer. + // @param ppbox Output the discoveried box, which user must free it. static srs_error_t discovery(SrsBuffer* buf, SrsMp4Box** ppbox); // Interface ISrsCodec public: @@ -250,16 +238,14 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 4.2 Object Structure - * ISO_IEC_14496-12-base-format-2012.pdf, page 17 - */ +// 4.2 Object Structure +// ISO_IEC_14496-12-base-format-2012.pdf, page 17 class SrsMp4FullBox : public SrsMp4Box { public: - // an integer that specifies the version of this format of the box. + // An integer that specifies the version of this format of the box. uint8_t version; - // a map of flags + // A map of flags uint32_t flags; public: SrsMp4FullBox(); @@ -272,23 +258,21 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 4.3 File Type Box (ftyp) - * ISO_IEC_14496-12-base-format-2012.pdf, page 17 - * Files written to this version of this specification must contain a file-type box. For compatibility with an earlier - * version of this specification, files may be conformant to this specification and not contain a file-type box. Files - * with no file-type box should be read as if they contained an FTYP box with Major_brand='mp41', minor_version=0, and - * the single compatible brand 'mp41'. - */ +// 4.3 File Type Box (ftyp) +// ISO_IEC_14496-12-base-format-2012.pdf, page 17 +// Files written to this version of this specification must contain a file-type box. For compatibility with an earlier +// version of this specification, files may be conformant to this specification and not contain a file-type box. Files +// with no file-type box should be read as if they contained an FTYP box with Major_brand='mp41', minor_version=0, and +// The single compatible brand 'mp41'. class SrsMp4FileTypeBox : public SrsMp4Box { public: - // a brand identifier + // A brand identifier SrsMp4BoxBrand major_brand; - // an informative integer for the minor version of the major brand + // An informative integer for the minor version of the major brand uint32_t minor_version; private: - // a list, to the end of the box, of brands + // A list, to the end of the box, of brands std::vector compatible_brands; public: SrsMp4FileTypeBox(); @@ -304,13 +288,11 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.16.2 Segment Type Box (styp) - * ISO_IEC_14496-12-base-format-2012.pdf, page 105 - * If segments are stored in separate files (e.g. on a standard HTTP server) it is recommended that these - * 'segment files' contain a segment-type box, which must be first if present, to enable identification of those files, - * and declaration of the specifications with which they are compliant. - */ +// 8.16.2 Segment Type Box (styp) +// ISO_IEC_14496-12-base-format-2012.pdf, page 105 +// If segments are stored in separate files (e.g. on a standard HTTP server) it is recommended that these +// 'segment files' contain a segment-type box, which must be first if present, to enable identification of those files, +// And declaration of the specifications with which they are compliant. class SrsMp4SegmentTypeBox : public SrsMp4FileTypeBox { public: @@ -318,14 +300,12 @@ public: virtual ~SrsMp4SegmentTypeBox(); }; -/** - * 8.8.4 Movie Fragment Box (moof) - * ISO_IEC_14496-12-base-format-2012.pdf, page 66 - * The movie fragments extend the presentation in time. They provide the information that would previously have - * been in the Movie Box. The actual samples are in Media Data Boxes, as usual, if they are in the same file. - * The data reference index is in the sample description, so it is possible to build incremental presentations - * where the media data is in files other than the file containing the Movie Box. - */ +// 8.8.4 Movie Fragment Box (moof) +// ISO_IEC_14496-12-base-format-2012.pdf, page 66 +// The movie fragments extend the presentation in time. They provide the information that would previously have +// been in the Movie Box. The actual samples are in Media Data Boxes, as usual, if they are in the same file. +// The data reference index is in the sample description, so it is possible to build incremental presentations +// where the media data is in files other than the file containing the Movie Box. class SrsMp4MovieFragmentBox : public SrsMp4Box { public: @@ -340,18 +320,16 @@ public: virtual void set_traf(SrsMp4TrackFragmentBox* v); }; -/** - * 8.8.5 Movie Fragment Header Box (mfhd) - * ISO_IEC_14496-12-base-format-2012.pdf, page 67 - * The movie fragment header contains a sequence number, as a safety check. The sequence number usually - * starts at 1 and must increase for each movie fragment in the file, in the order in which they occur. This allows - * readers to verify integrity of the sequence; it is an error to construct a file where the fragments are out of - * sequence. - */ +// 8.8.5 Movie Fragment Header Box (mfhd) +// ISO_IEC_14496-12-base-format-2012.pdf, page 67 +// The movie fragment header contains a sequence number, as a safety check. The sequence number usually +// starts at 1 and must increase for each movie fragment in the file, in the order in which they occur. This allows +// readers to verify integrity of the sequence; it is an error to construct a file where the fragments are out of +// sequence. class SrsMp4MovieFragmentHeaderBox : public SrsMp4FullBox { public: - // the ordinal number of this fragment, in increasing order + // The ordinal number of this fragment, in increasing order uint32_t sequence_number; public: SrsMp4MovieFragmentHeaderBox(); @@ -364,13 +342,11 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.8.6 Track Fragment Box (traf) - * ISO_IEC_14496-12-base-format-2012.pdf, page 67 - * Within the movie fragment there is a set of track fragments, zero or more per track. The track fragments in - * turn contain zero or more track runs, each of which document a contiguous run of samples for that track. - * Within these structures, many fields are optional and can be defaulted. - */ +// 8.8.6 Track Fragment Box (traf) +// ISO_IEC_14496-12-base-format-2012.pdf, page 67 +// Within the movie fragment there is a set of track fragments, zero or more per track. The track fragments in +// turn contain zero or more track runs, each of which document a contiguous run of samples for that track. +// Within these structures, many fields are optional and can be defaulted. class SrsMp4TrackFragmentBox : public SrsMp4Box { public: @@ -388,59 +364,47 @@ public: virtual void set_trun(SrsMp4TrackFragmentRunBox* v); }; -/** - * The tf_flags of tfhd. - * ISO_IEC_14496-12-base-format-2012.pdf, page 68 - */ +// The tf_flags of tfhd. +// ISO_IEC_14496-12-base-format-2012.pdf, page 68 enum SrsMp4TfhdFlags { - /** - * indicates the presence of the base-data-offset field. This provides - * an explicit anchor for the data offsets in each track run (see below). If not provided, the base-data- - * offset for the first track in the movie fragment is the position of the first byte of the enclosing Movie - * Fragment Box, and for second and subsequent track fragments, the default is the end of the data - * defined by the preceding fragment. Fragments 'inheriting' their offset in this way must all use - * the same data-reference (i.e., the data for these tracks must be in the same file). - */ + // indicates the presence of the base-data-offset field. This provides + // An explicit anchor for the data offsets in each track run (see below). If not provided, the base-data- + // offset for the first track in the movie fragment is the position of the first byte of the enclosing Movie + // Fragment Box, and for second and subsequent track fragments, the default is the end of the data + // defined by the preceding fragment. Fragments 'inheriting' their offset in this way must all use + // The same data-reference (i.e., the data for these tracks must be in the same file). SrsMp4TfhdFlagsBaseDataOffset = 0x000001, - /** - * indicates the presence of this field, which over-rides, in this - * fragment, the default set up in the Track Extends Box. - */ + // indicates the presence of this field, which over-rides, in this + // fragment, the default set up in the Track Extends Box. SrsMp4TfhdFlagsSampleDescriptionIndex = 0x000002, SrsMp4TfhdFlagsDefaultSampleDuration = 0x000008, SrsMp4TfhdFlagsDefautlSampleSize = 0x000010, SrsMp4TfhdFlagsDefaultSampleFlags = 0x000020, - /** - * this indicates that the duration provided in either default-sample-duration, - * or by the default-duration in the Track Extends Box, is empty, i.e. that there are no samples for this - * time interval. It is an error to make a presentation that has both edit lists in the Movie Box, and empty- - * duration fragments. - */ + // this indicates that the duration provided in either default-sample-duration, + // or by the default-duration in the Track Extends Box, is empty, i.e. that there are no samples for this + // time interval. It is an error to make a presentation that has both edit lists in the Movie Box, and empty- + // duration fragments. SrsMp4TfhdFlagsDurationIsEmpty = 0x010000, - /** - * if base-data-offset-present is zero, this indicates that the base-data- - * offset for this track fragment is the position of the first byte of the enclosing Movie Fragment Box. - * Support for the default-base-is-moof flag is required under the ‘iso5’ brand, and it shall not be used in - * brands or compatible brands earlier than iso5. - */ + // if base-data-offset-present is zero, this indicates that the base-data- + // offset for this track fragment is the position of the first byte of the enclosing Movie Fragment Box. + // Support for the default-base-is-moof flag is required under the ‘iso5’ brand, and it shall not be used in + // brands or compatible brands earlier than iso5. SrsMp4TfhdFlagsDefaultBaseIsMoof = 0x020000, }; -/** - * 8.8.7 Track Fragment Header Box (tfhd) - * ISO_IEC_14496-12-base-format-2012.pdf, page 68 - * Each movie fragment can add zero or more fragments to each track; and a track fragment can add zero or - * more contiguous runs of samples. The track fragment header sets up information and defaults used for those - * runs of samples. - */ +// 8.8.7 Track Fragment Header Box (tfhd) +// ISO_IEC_14496-12-base-format-2012.pdf, page 68 +// Each movie fragment can add zero or more fragments to each track; and a track fragment can add zero or +// more contiguous runs of samples. The track fragment header sets up information and defaults used for those +// runs of samples. class SrsMp4TrackFragmentHeaderBox : public SrsMp4FullBox { public: uint32_t track_id; // all the following are optional fields public: - // the base offset to use when calculating data offsets + // The base offset to use when calculating data offsets uint64_t base_data_offset; uint32_t sample_description_index; uint32_t default_sample_duration; @@ -457,15 +421,13 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.8.12 Track fragment decode time (tfdt) - * ISO_IEC_14496-12-base-format-2012.pdf, page 72 - * The Track Fragment Base Media Decode Time Box provides the absolute decode time, measured on - * the media timeline, of the first sample in decode order in the track fragment. This can be useful, for example, - * when performing random access in a file; it is not necessary to sum the sample durations of all preceding - * samples in previous fragments to find this value (where the sample durations are the deltas in the Decoding - * Time to Sample Box and the sample_durations in the preceding track runs). - */ +// 8.8.12 Track fragment decode time (tfdt) +// ISO_IEC_14496-12-base-format-2012.pdf, page 72 +// The Track Fragment Base Media Decode Time Box provides the absolute decode time, measured on +// The media timeline, of the first sample in decode order in the track fragment. This can be useful, for example, +// when performing random access in a file; it is not necessary to sum the sample durations of all preceding +// samples in previous fragments to find this value (where the sample durations are the deltas in the Decoding +// Time to Sample Box and the sample_durations in the preceding track runs). class SrsMp4TrackFragmentDecodeTimeBox : public SrsMp4FullBox { public: @@ -482,10 +444,8 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * The tr_flags for trun - * ISO_IEC_14496-12-base-format-2012.pdf, page 69 - */ +// The tr_flags for trun +// ISO_IEC_14496-12-base-format-2012.pdf, page 69 enum SrsMp4TrunFlags { // data-offset-present. @@ -497,18 +457,16 @@ enum SrsMp4TrunFlags SrsMp4TrunFlagsFirstSample = 0x000004, // indicates that each sample has its own duration, otherwise the default is used. SrsMp4TrunFlagsSampleDuration = 0x000100, - // each sample has its own size, otherwise the default is used. + // Each sample has its own size, otherwise the default is used. SrsMp4TrunFlagsSampleSize = 0x000200, - // each sample has its own flags, otherwise the default is used. + // Each sample has its own flags, otherwise the default is used. SrsMp4TrunFlagsSampleFlag = 0x000400, - // each sample has a composition time offset (e.g. as used for I/P/B video in MPEG). + // Each sample has a composition time offset (e.g. as used for I/P/B video in MPEG). SrsMp4TrunFlagsSampleCtsOffset = 0x000800, }; -/** - * Entry for trun. - * ISO_IEC_14496-12-base-format-2012.pdf, page 69 - */ +// Entry for trun. +// ISO_IEC_14496-12-base-format-2012.pdf, page 69 struct SrsMp4TrunEntry { SrsMp4FullBox* owner; @@ -528,19 +486,17 @@ struct SrsMp4TrunEntry virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.8.8 Track Fragment Run Box (trun) - * ISO_IEC_14496-12-base-format-2012.pdf, page 69 - * Within the Track Fragment Box, there are zero or more Track Run Boxes. If the duration-is-empty flag is set in - * the tf_flags, there are no track runs. A track run documents a contiguous set of samples for a track. - */ +// 8.8.8 Track Fragment Run Box (trun) +// ISO_IEC_14496-12-base-format-2012.pdf, page 69 +// Within the Track Fragment Box, there are zero or more Track Run Boxes. If the duration-is-empty flag is set in +// The tf_flags, there are no track runs. A track run documents a contiguous set of samples for a track. class SrsMp4TrackFragmentRunBox : public SrsMp4FullBox { public: - // the number of samples being added in this run; also the number of rows in the following + // The number of samples being added in this run; also the number of rows in the following // table (the rows can be empty) uint32_t sample_count; -// the following are optional fields +// The following are optional fields public: // added to the implicit or explicit data_offset established in the track fragment header. int32_t data_offset; @@ -560,53 +516,51 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.1.1 Media Data Box (mdat) - * ISO_IEC_14496-12-base-format-2012.pdf, page 29 - * This box contains the media data. In video tracks, this box would contain video frames. - * A presentation may contain zero or more Media Data Boxes. The actual media data follows the type field; - * its structure is described by the metadata (see particularly the sample table, subclause 8.5, and the - * item location box, subclause 8.11.3). - * - * @remark The mdat box only decode and encode the header, - * so user must read and write the data by yourself. - * To encode mdat: - * SrsMp4MediaDataBox* mdat = new SrsMp4MediaDataBox(); - * mdat->nb_data = 1024000; - * - * char* buffer = new char[mdat->sz_header()]; - * SrsBuffer* buf = new SrsBuffer(buffer); - * mdat->encode(buf); - * - * file->write(buffer, mdat->sz_header()); // Write the mdat box header. - * file->write(data, size); // Write the mdat box data. - * - * To decode mdat: - * SrsMp4MediaDataBox* mdat = new SrsMp4MediaDataBox(); - * char* buffer = new char[mdat->sz_header()]; - * SrsBuffer* buf = ...; // Read mdat->sz_header() data from io. - * - * mdat->decode(buf); // The buf should be empty now. - * file->lseek(mdat->nb_data, SEEK_CUR); // Skip the mdat data in file. - * - * To discovery any box from file: - * SrsSimpleStream* stream = new SrsSimpleStream(); - * SrsBuffer* buf = new SrsBuffer(stream...); // Create read buffer from stream. - * - * // We don't know what's the next box, so try to read 4bytes and discovery it. - * append(file, stream, 4); // Append 4bytes from file to stream. - * - * SrsMp4Box* box = NULL; - * SrsMp4Box::discovery(buf, &box); - * - * required = (box->is_mdat()? box->sz_header():box->sz()); // Now we know how many bytes we needed. - * append(file, stream, required); - * box->decode(buf); - * - * if (box->is_mdat()) { - * file->lseek(mdat->nb_data, SEEK_CUR); // Skip the mdat data in file. - * } - */ +// 8.1.1 Media Data Box (mdat) +// ISO_IEC_14496-12-base-format-2012.pdf, page 29 +// This box contains the media data. In video tracks, this box would contain video frames. +// A presentation may contain zero or more Media Data Boxes. The actual media data follows the type field; +// its structure is described by the metadata (see particularly the sample table, subclause 8.5, and the +// item location box, subclause 8.11.3). +// +// @remark The mdat box only decode and encode the header, +// so user must read and write the data by yourself. +// To encode mdat: +// SrsMp4MediaDataBox* mdat = new SrsMp4MediaDataBox(); +// mdat->nb_data = 1024000; +// +// char* buffer = new char[mdat->sz_header()]; +// SrsBuffer* buf = new SrsBuffer(buffer); +// mdat->encode(buf); +// +// file->write(buffer, mdat->sz_header()); // Write the mdat box header. +// file->write(data, size); // Write the mdat box data. +// +// To decode mdat: +// SrsMp4MediaDataBox* mdat = new SrsMp4MediaDataBox(); +// char* buffer = new char[mdat->sz_header()]; +// SrsBuffer* buf = ...; // Read mdat->sz_header() data from io. +// +// mdat->decode(buf); // The buf should be empty now. +// file->lseek(mdat->nb_data, SEEK_CUR); // Skip the mdat data in file. +// +// To discovery any box from file: +// SrsSimpleStream* stream = new SrsSimpleStream(); +// SrsBuffer* buf = new SrsBuffer(stream...); // Create read buffer from stream. +// +// // We don't know what's the next box, so try to read 4bytes and discovery it. +// append(file, stream, 4); // Append 4bytes from file to stream. +// +// SrsMp4Box* box = NULL; +// SrsMp4Box::discovery(buf, &box); +// +// required = (box->is_mdat()? box->sz_header():box->sz()); // Now we know how many bytes we needed. +// append(file, stream, required); +// box->decode(buf); +// +// if (box->is_mdat()) { +// file->lseek(mdat->nb_data, SEEK_CUR); // Skip the mdat data in file. +// } class SrsMp4MediaDataBox : public SrsMp4Box { public: @@ -634,10 +588,8 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.1.2 Free Space Box (free or skip) - * ISO_IEC_14496-12-base-format-2012.pdf, page 29 - */ +// 8.1.2 Free Space Box (free or skip) +// ISO_IEC_14496-12-base-format-2012.pdf, page 29 class SrsMp4FreeSpaceBox : public SrsMp4Box { private: @@ -653,12 +605,10 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.2.1 Movie Box (moov) - * ISO_IEC_14496-12-base-format-2012.pdf, page 30 - * The metadata for a presentation is stored in the single Movie Box which occurs at the top-level of a file. - * Normally this box is close to the beginning or end of the file, though this is not required. - */ +// 8.2.1 Movie Box (moov) +// ISO_IEC_14496-12-base-format-2012.pdf, page 30 +// The metadata for a presentation is stored in the single Movie Box which occurs at the top-level of a file. +// Normally this box is close to the beginning or end of the file, though this is not required. class SrsMp4MovieBox : public SrsMp4Box { public: @@ -687,40 +637,38 @@ protected: virtual srs_error_t decode_header(SrsBuffer* buf); }; -/** - * 8.2.2 Movie Header Box (mvhd) - * ISO_IEC_14496-12-base-format-2012.pdf, page 31 - */ +// 8.2.2 Movie Header Box (mvhd) +// ISO_IEC_14496-12-base-format-2012.pdf, page 31 class SrsMp4MovieHeaderBox : public SrsMp4FullBox { public: - // an integer that declares the creation time of the presentation (in seconds since + // An integer that declares the creation time of the presentation (in seconds since // midnight, Jan. 1, 1904, in UTC time) uint64_t creation_time; - // an integer that declares the most recent time the presentation was modified (in + // An integer that declares the most recent time the presentation was modified (in // seconds since midnight, Jan. 1, 1904, in UTC time) uint64_t modification_time; public: - // an integer that specifies the time-scale for the entire presentation; this is the number of + // An integer that specifies the time-scale for the entire presentation; this is the number of // time units that pass in one second. For example, a time coordinate system that measures time in // sixtieths of a second has a time scale of 60. uint32_t timescale; - // an integer that declares length of the presentation (in the indicated timescale). This property + // An integer that declares length of the presentation (in the indicated timescale). This property // is derived from the presentation’s tracks: the value of this field corresponds to the duration of the // longest track in the presentation. If the duration cannot be determined then duration is set to all 1s. uint64_t duration_in_tbn; public: - // a fixed point 16.16 number that indicates the preferred rate to play the presentation; 1.0 + // A fixed point 16.16 number that indicates the preferred rate to play the presentation; 1.0 // (0x00010000) is normal forward playback uint32_t rate; - // a fixed point 8.8 number that indicates the preferred playback volume. 1.0 (0x0100) is full volume. + // A fixed point 8.8 number that indicates the preferred playback volume. 1.0 (0x0100) is full volume. uint16_t volume; uint16_t reserved0; uint64_t reserved1; - // a transformation matrix for the video; (u,v,w) are restricted here to (0,0,1), hex values (0,0,0x40000000). + // A transformation matrix for the video; (u,v,w) are restricted here to (0,0,1), hex values (0,0,0x40000000). int32_t matrix[9]; uint32_t pre_defined[6]; - // a non-zero integer that indicates a value to use for the track ID of the next track to be + // A non-zero integer that indicates a value to use for the track ID of the next track to be // added to this presentation. Zero is not a valid track ID value. The value of next_track_ID shall be // larger than the largest track-ID in use. If this value is equal to all 1s (32-bit maxint), and a new media // track is to be added, then a search must be made in the file for an unused track identifier. @@ -747,13 +695,11 @@ enum SrsMp4TrackType SrsMp4TrackTypeVideo = 0x02, }; -/** - * 8.8.1 Movie Extends Box (mvex) - * ISO_IEC_14496-12-base-format-2012.pdf, page 64 - * This box warns readers that there might be Movie Fragment Boxes in this file. To know of all samples in the - * tracks, these Movie Fragment Boxes must be found and scanned in order, and their information logically - * added to that found in the Movie Box. - */ +// 8.8.1 Movie Extends Box (mvex) +// ISO_IEC_14496-12-base-format-2012.pdf, page 64 +// This box warns readers that there might be Movie Fragment Boxes in this file. To know of all samples in the +// tracks, these Movie Fragment Boxes must be found and scanned in order, and their information logically +// added to that found in the Movie Box. class SrsMp4MovieExtendsBox : public SrsMp4Box { public: @@ -765,16 +711,14 @@ public: virtual void set_trex(SrsMp4TrackExtendsBox* v); }; -/** - * 8.8.3 Track Extends Box(trex) - * ISO_IEC_14496-12-base-format-2012.pdf, page 65 - */ +// 8.8.3 Track Extends Box(trex) +// ISO_IEC_14496-12-base-format-2012.pdf, page 65 class SrsMp4TrackExtendsBox : public SrsMp4FullBox { public: // identifies the track; this shall be the track ID of a track in the Movie Box uint32_t track_ID; - // these fields set up defaults used in the track fragments. + // These fields set up defaults used in the track fragments. uint32_t default_sample_description_index; uint32_t default_sample_duration; uint32_t default_sample_size; @@ -790,13 +734,11 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.3.1 Track Box (trak) - * ISO_IEC_14496-12-base-format-2012.pdf, page 32 - * This is a container box for a single track of a presentation. A presentation consists of one or more tracks. - * Each track is independent of the other tracks in the presentation and carries its own temporal and spatial - * information. Each track will contain its associated Media Box. - */ +// 8.3.1 Track Box (trak) +// ISO_IEC_14496-12-base-format-2012.pdf, page 32 +// This is a container box for a single track of a presentation. A presentation consists of one or more tracks. +// Each track is independent of the other tracks in the presentation and carries its own temporal and spatial +// information. Each track will contain its associated Media Box. class SrsMp4TrackBox : public SrsMp4Box { public: @@ -851,26 +793,24 @@ public: virtual SrsMp4AudioSampleEntry* mp4a(); }; -/** - * 8.3.2 Track Header Box (tkhd) - * ISO_IEC_14496-12-base-format-2012.pdf, page 32 - */ +// 8.3.2 Track Header Box (tkhd) +// ISO_IEC_14496-12-base-format-2012.pdf, page 32 class SrsMp4TrackHeaderBox : public SrsMp4FullBox { public: - // an integer that declares the creation time of the presentation (in seconds since + // An integer that declares the creation time of the presentation (in seconds since // midnight, Jan. 1, 1904, in UTC time) uint64_t creation_time; - // an integer that declares the most recent time the presentation was modified (in + // An integer that declares the most recent time the presentation was modified (in // seconds since midnight, Jan. 1, 1904, in UTC time) uint64_t modification_time; - // an integer that uniquely identifies this track over the entire life-time of this presentation. + // An integer that uniquely identifies this track over the entire life-time of this presentation. // Track IDs are never re-used and cannot be zero. uint32_t track_ID; uint32_t reserved0; - // an integer that indicates the duration of this track (in the timescale indicated in the Movie + // An integer that indicates the duration of this track (in the timescale indicated in the Movie // Header Box). The value of this field is equal to the sum of the durations of all of the track’s edits. If - // there is no edit list, then the duration is the sum of the sample durations, converted into the timescale + // There is no edit list, then the duration is the sum of the sample durations, converted into the timescale // in the Movie Header Box. If the duration of this track cannot be determined then duration is set to all // 1s. uint64_t duration; @@ -879,25 +819,25 @@ public: // specifies the front-to-back ordering of video tracks; tracks with lower numbers are closer to the // viewer. 0 is the normal value, and -1 would be in front of track 0, and so on. int16_t layer; - // an integer that specifies a group or collection of tracks. If this field is 0 there is no + // An integer that specifies a group or collection of tracks. If this field is 0 there is no // information on possible relations to other tracks. If this field is not 0, it should be the same for tracks // that contain alternate data for one another and different for tracks belonging to different such groups. // Only one track within an alternate group should be played or streamed at any one time, and must be // distinguishable from other tracks in the group via attributes such as bitrate, codec, language, packet // size etc. A group may have only one member. int16_t alternate_group; - // a fixed 8.8 value specifying the track's relative audio volume. Full volume is 1.0 (0x0100) and + // A fixed 8.8 value specifying the track's relative audio volume. Full volume is 1.0 (0x0100) and // is the normal value. Its value is irrelevant for a purely visual track. Tracks may be composed by // combining them according to their volume, and then using the overall Movie Header Box volume // setting; or more complex audio composition (e.g. MPEG-4 BIFS) may be used. int16_t volume; uint16_t reserved2; - // a transformation matrix for the video; (u,v,w) are restricted here to (0,0,1), hex (0,0,0x40000000). + // A transformation matrix for the video; (u,v,w) are restricted here to (0,0,1), hex (0,0,0x40000000). int32_t matrix[9]; - // the track's visual presentation size as fixed-point 16.16 values. These need + // The track's visual presentation size as fixed-point 16.16 values. These need // not be the same as the pixel dimensions of the images, which is documented in the sample // description(s); all images in the sequence are scaled to this size, before any overall transformation of - // the track represented by the matrix. The pixel dimensions of the images are the default values. + // The track represented by the matrix. The pixel dimensions of the images are the default values. int32_t width; int32_t height; public: @@ -911,12 +851,10 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.6.5 Edit Box (edts) - * ISO_IEC_14496-12-base-format-2012.pdf, page 54 - * An Edit Box maps the presentation time-line to the media time-line as it is stored in the file. - * The Edit Box is a container for the edit lists. - */ +// 8.6.5 Edit Box (edts) +// ISO_IEC_14496-12-base-format-2012.pdf, page 54 +// An Edit Box maps the presentation time-line to the media time-line as it is stored in the file. +// The Edit Box is a container for the edit lists. class SrsMp4EditBox : public SrsMp4Box { public: @@ -924,24 +862,22 @@ public: virtual ~SrsMp4EditBox(); }; -/** - * 8.6.6 Edit List Box - * ISO_IEC_14496-12-base-format-2012.pdf, page 55 - */ +// 8.6.6 Edit List Box +// ISO_IEC_14496-12-base-format-2012.pdf, page 55 struct SrsMp4ElstEntry { public: - // an integer that specifies the duration of this edit segment in units of the timescale + // An integer that specifies the duration of this edit segment in units of the timescale // in the Movie Header Box uint64_t segment_duration; - // an integer containing the starting time within the media of this edit segment (in media time + // An integer containing the starting time within the media of this edit segment (in media time // scale units, in composition time). If this field is set to –1, it is an empty edit. The last edit in a track // shall never be an empty edit. Any difference between the duration in the Movie Header Box, and the // track’s duration is expressed as an implicit empty edit at the end. int64_t media_time; public: // specifies the relative rate at which to play the media corresponding to this edit segment. If this value is 0, - // then the edit is specifying a ‘dwell’: the media at media-time is presented for the segment-duration. Otherwise + // Then the edit is specifying a ‘dwell’: the media at media-time is presented for the segment-duration. Otherwise // this field shall contain the value 1. int16_t media_rate_integer; int16_t media_rate_fraction; @@ -953,17 +889,15 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.6.6 Edit List Box (elst) - * ISO_IEC_14496-12-base-format-2012.pdf, page 54 - * This box contains an explicit timeline map. Each entry defines part of the track time-line: by mapping part of - * the media time-line, or by indicating ‘empty’ time, or by defining a ‘dwell’, where a single time-point in the - * media is held for a period. - */ +// 8.6.6 Edit List Box (elst) +// ISO_IEC_14496-12-base-format-2012.pdf, page 54 +// This box contains an explicit timeline map. Each entry defines part of the track time-line: by mapping part of +// The media time-line, or by indicating ‘empty’ time, or by defining a ‘dwell’, where a single time-point in the +// media is held for a period. class SrsMp4EditListBox : public SrsMp4FullBox { public: - // an integer that gives the number of entries in the following table + // An integer that gives the number of entries in the following table std::vector entries; public: SrsMp4EditListBox(); @@ -976,12 +910,10 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.4.1 Media Box (mdia) - * ISO_IEC_14496-12-base-format-2012.pdf, page 36 - * The media declaration container contains all the objects that declare information about the media data within a - * track. - */ +// 8.4.1 Media Box (mdia) +// ISO_IEC_14496-12-base-format-2012.pdf, page 36 +// The media declaration container contains all the objects that declare information about the media data within a +// track. class SrsMp4MediaBox : public SrsMp4Box { public: @@ -1003,31 +935,29 @@ public: virtual void set_minf(SrsMp4MediaInformationBox* v); }; -/** - * 8.4.2 Media Header Box (mdhd) - * ISO_IEC_14496-12-base-format-2012.pdf, page 36 - * The media declaration container contains all the objects that declare information about the media data within a - * track. - */ +// 8.4.2 Media Header Box (mdhd) +// ISO_IEC_14496-12-base-format-2012.pdf, page 36 +// The media declaration container contains all the objects that declare information about the media data within a +// track. class SrsMp4MediaHeaderBox : public SrsMp4FullBox { public: - // an integer that declares the creation time of the presentation (in seconds since + // An integer that declares the creation time of the presentation (in seconds since // midnight, Jan. 1, 1904, in UTC time) uint64_t creation_time; - // an integer that declares the most recent time the presentation was modified (in + // An integer that declares the most recent time the presentation was modified (in // seconds since midnight, Jan. 1, 1904, in UTC time) uint64_t modification_time; - // an integer that specifies the time-scale for the entire presentation; this is the number of + // An integer that specifies the time-scale for the entire presentation; this is the number of // time units that pass in one second. For example, a time coordinate system that measures time in // sixtieths of a second has a time scale of 60. uint32_t timescale; - // an integer that declares length of the presentation (in the indicated timescale). This property + // An integer that declares length of the presentation (in the indicated timescale). This property // is derived from the presentation’s tracks: the value of this field corresponds to the duration of the // longest track in the presentation. If the duration cannot be determined then duration is set to all 1s. uint64_t duration; private: - // the language code for this media. See ISO 639-2/T for the set of three character + // The language code for this media. See ISO 639-2/T for the set of three character // codes. Each character is packed as the difference between its ASCII value and 0x60. Since the code // is confined to being three lower-case letters, these values are strictly positive. uint16_t language; @@ -1036,7 +966,7 @@ public: SrsMp4MediaHeaderBox(); virtual ~SrsMp4MediaHeaderBox(); public: - // the language code for this media. See ISO 639-2/T for the set of three character + // The language code for this media. See ISO 639-2/T for the set of three character // codes. Each character is packed as the difference between its ASCII value and 0x60. Since the code // is confined to being three lower-case letters, these values are strictly positive. // @param v The ASCII, for example, 'u'. @@ -1056,22 +986,20 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.4.3 Handler Reference Box (hdlr) - * ISO_IEC_14496-12-base-format-2012.pdf, page 37 - * This box within a Media Box declares the process by which the media-data in the track is presented, and thus, - * the nature of the media in a track. For example, a video track would be handled by a video handler. - */ +// 8.4.3 Handler Reference Box (hdlr) +// ISO_IEC_14496-12-base-format-2012.pdf, page 37 +// This box within a Media Box declares the process by which the media-data in the track is presented, and thus, +// The nature of the media in a track. For example, a video track would be handled by a video handler. class SrsMp4HandlerReferenceBox : public SrsMp4FullBox { public: uint32_t pre_defined; - // an integer containing one of the following values, or a value from a derived specification: + // An integer containing one of the following values, or a value from a derived specification: // ‘vide’, Video track // ‘soun’, Audio track SrsMp4HandlerType handler_type; uint32_t reserved[3]; - // a null-terminated string in UTF-8 characters which gives a human-readable name for the track + // A null-terminated string in UTF-8 characters which gives a human-readable name for the track // type (for debugging and inspection purposes). std::string name; public: @@ -1088,11 +1016,9 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.4.4 Media Information Box (minf) - * ISO_IEC_14496-12-base-format-2012.pdf, page 38 - * This box contains all the objects that declare characteristic information of the media in the track. - */ +// 8.4.4 Media Information Box (minf) +// ISO_IEC_14496-12-base-format-2012.pdf, page 38 +// This box contains all the objects that declare characteristic information of the media in the track. class SrsMp4MediaInformationBox : public SrsMp4Box { public: @@ -1113,20 +1039,18 @@ public: virtual void set_stbl(SrsMp4SampleTableBox* v); }; -/** - * 8.4.5.2 Video Media Header Box (vmhd) - * ISO_IEC_14496-12-base-format-2012.pdf, page 38 - * The video media header contains general presentation information, independent of the coding, for video - * media. Note that the flags field has the value 1. - */ +// 8.4.5.2 Video Media Header Box (vmhd) +// ISO_IEC_14496-12-base-format-2012.pdf, page 38 +// The video media header contains general presentation information, independent of the coding, for video +// media. Note that the flags field has the value 1. class SrsMp4VideoMeidaHeaderBox : public SrsMp4FullBox { public: - // a composition mode for this video track, from the following enumerated set, + // A composition mode for this video track, from the following enumerated set, // which may be extended by derived specifications: // copy = 0 copy over the existing image uint16_t graphicsmode; - // a set of 3 colour values (red, green, blue) available for use by graphics modes + // A set of 3 colour values (red, green, blue) available for use by graphics modes uint16_t opcolor[3]; public: SrsMp4VideoMeidaHeaderBox(); @@ -1137,16 +1061,14 @@ protected: virtual srs_error_t decode_header(SrsBuffer* buf); }; -/** - * 8.4.5.3 Sound Media Header Box (smhd) - * ISO_IEC_14496-12-base-format-2012.pdf, page 39 - * The sound media header contains general presentation information, independent of the coding, for audio - * media. This header is used for all tracks containing audio. - */ +// 8.4.5.3 Sound Media Header Box (smhd) +// ISO_IEC_14496-12-base-format-2012.pdf, page 39 +// The sound media header contains general presentation information, independent of the coding, for audio +// media. This header is used for all tracks containing audio. class SrsMp4SoundMeidaHeaderBox : public SrsMp4FullBox { public: - // a fixed-point 8.8 number that places mono audio tracks in a stereo space; 0 is centre (the + // A fixed-point 8.8 number that places mono audio tracks in a stereo space; 0 is centre (the // normal value); full left is -1.0 and full right is 1.0. int16_t balance; uint16_t reserved; @@ -1159,11 +1081,9 @@ protected: virtual srs_error_t decode_header(SrsBuffer* buf); }; -/** - * 8.7.1 Data Information Box (dinf) - * ISO_IEC_14496-12-base-format-2012.pdf, page 56 - * The data information box contains objects that declare the location of the media information in a track. - */ +// 8.7.1 Data Information Box (dinf) +// ISO_IEC_14496-12-base-format-2012.pdf, page 56 +// The data information box contains objects that declare the location of the media information in a track. class SrsMp4DataInformationBox : public SrsMp4Box { public: @@ -1175,12 +1095,10 @@ public: virtual void set_dref(SrsMp4DataReferenceBox* v); }; -/** - * 8.7.2 Data Reference Box - * ISO_IEC_14496-12-base-format-2012.pdf, page 56 - * a 24-bit integer with flags; one flag is defined (x000001) which means that the media - * data is in the same file as the Movie Box containing this data reference. - */ +// 8.7.2 Data Reference Box +// ISO_IEC_14496-12-base-format-2012.pdf, page 56 +// A 24-bit integer with flags; one flag is defined (x000001) which means that the media +// data is in the same file as the Movie Box containing this data reference. class SrsMp4DataEntryBox : public SrsMp4FullBox { public: @@ -1190,10 +1108,8 @@ public: virtual ~SrsMp4DataEntryBox(); }; -/** - * 8.7.2 Data Reference Box (url ) - * ISO_IEC_14496-12-base-format-2012.pdf, page 56 - */ +// 8.7.2 Data Reference Box (url ) +// ISO_IEC_14496-12-base-format-2012.pdf, page 56 class SrsMp4DataEntryUrlBox : public SrsMp4DataEntryBox { public: @@ -1207,10 +1123,8 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.7.2 Data Reference Box (urn ) - * ISO_IEC_14496-12-base-format-2012.pdf, page 56 - */ +// 8.7.2 Data Reference Box (urn ) +// ISO_IEC_14496-12-base-format-2012.pdf, page 56 class SrsMp4DataEntryUrnBox : public SrsMp4DataEntryBox { public: @@ -1226,13 +1140,11 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.7.2 Data Reference Box (dref) - * ISO_IEC_14496-12-base-format-2012.pdf, page 56 - * The data reference object contains a table of data references (normally URLs) that declare the location(s) of - * the media data used within the presentation. The data reference index in the sample description ties entries - * in this table to the samples in the track. A track may be split over several sources in this way. - */ +// 8.7.2 Data Reference Box (dref) +// ISO_IEC_14496-12-base-format-2012.pdf, page 56 +// The data reference object contains a table of data references (normally URLs) that declare the location(s) of +// The media data used within the presentation. The data reference index in the sample description ties entries +// in this table to the samples in the track. A track may be split over several sources in this way. class SrsMp4DataReferenceBox : public SrsMp4FullBox { private: @@ -1252,13 +1164,11 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.5.1 Sample Table Box (stbl) - * ISO_IEC_14496-12-base-format-2012.pdf, page 40 - * The sample table contains all the time and data indexing of the media samples in a track. Using the tables - * here, it is possible to locate samples in time, determine their type (e.g. I-frame or not), and determine their - * size, container, and offset into that container. - */ +// 8.5.1 Sample Table Box (stbl) +// ISO_IEC_14496-12-base-format-2012.pdf, page 40 +// The sample table contains all the time and data indexing of the media samples in a track. Using the tables +// here, it is possible to locate samples in time, determine their type (e.g. I-frame or not), and determine their +// size, container, and offset into that container. class SrsMp4SampleTableBox : public SrsMp4Box { public: @@ -1292,15 +1202,13 @@ protected: virtual srs_error_t decode_header(SrsBuffer* buf); }; -/** - * 8.5.2 Sample Description Box - * ISO_IEC_14496-12-base-format-2012.pdf, page 43 - */ +// 8.5.2 Sample Description Box +// ISO_IEC_14496-12-base-format-2012.pdf, page 43 class SrsMp4SampleEntry : public SrsMp4Box { public: uint8_t reserved[6]; - // an integer that contains the index of the data reference to use to retrieve + // An integer that contains the index of the data reference to use to retrieve // data associated with samples that use this sample description. Data references are stored in Data // Reference Boxes. The index ranges from 1 to the number of data references. uint16_t data_reference_index; @@ -1315,17 +1223,15 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.5.2 Sample Description Box (avc1) - * ISO_IEC_14496-12-base-format-2012.pdf, page 44 - */ +// 8.5.2 Sample Description Box (avc1) +// ISO_IEC_14496-12-base-format-2012.pdf, page 44 class SrsMp4VisualSampleEntry : public SrsMp4SampleEntry { public: uint16_t pre_defined0; uint16_t reserved0; uint32_t pre_defined1[3]; - // the maximum visual width and height of the stream described by this sample + // The maximum visual width and height of the stream described by this sample // description, in pixels uint16_t width; uint16_t height; @@ -1335,9 +1241,9 @@ public: // how many frames of compressed video are stored in each sample. The default is // 1, for one frame per sample; it may be more than 1 for multiple frames per sample uint16_t frame_count; - // a name, for informative purposes. It is formatted in a fixed 32-byte field, with the first + // A name, for informative purposes. It is formatted in a fixed 32-byte field, with the first // byte set to the number of bytes to be displayed, followed by that number of bytes of displayable data, - // and then padding to complete 32 bytes total (including the size byte). The field may be set to 0. + // And then padding to complete 32 bytes total (including the size byte). The field may be set to 0. char compressorname[32]; // one of the following values // 0x0018 – images are in colour with no alpha @@ -1358,10 +1264,8 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 5.3.4 AVC Video Stream Definition (avcC) - * ISO_IEC_14496-15-AVC-format-2012.pdf, page 19 - */ +// 5.3.4 AVC Video Stream Definition (avcC) +// ISO_IEC_14496-15-AVC-format-2012.pdf, page 19 class SrsMp4AvccBox : public SrsMp4Box { public: @@ -1377,10 +1281,8 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.5.2 Sample Description Box (mp4a) - * ISO_IEC_14496-12-base-format-2012.pdf, page 45 - */ +// 8.5.2 Sample Description Box (mp4a) +// ISO_IEC_14496-12-base-format-2012.pdf, page 45 class SrsMp4AudioSampleEntry : public SrsMp4SampleEntry { public: @@ -1420,10 +1322,8 @@ enum SrsMp4ESTagEs { SrsMp4ESTagESExtSLConfigDescrTag = 0x064, }; -/** - * 7.2.2.2 BaseDescriptor - * ISO_IEC_14496-1-System-2010.pdf, page 32 - */ +// 7.2.2.2 BaseDescriptor +// ISO_IEC_14496-1-System-2010.pdf, page 32 class SrsMp4BaseDescriptor : public ISrsCodec { public: @@ -1472,10 +1372,8 @@ enum SrsMp4StreamType SrsMp4StreamTypeAudioStream = 0x05, }; -/** - * 7.2.6.7 DecoderSpecificInfo - * ISO_IEC_14496-1-System-2010.pdf, page 51 - */ +// 7.2.6.7 DecoderSpecificInfo +// ISO_IEC_14496-1-System-2010.pdf, page 51 class SrsMp4DecoderSpecificInfo : public SrsMp4BaseDescriptor { public: @@ -1493,14 +1391,12 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 7.2.6.6 DecoderConfigDescriptor - * ISO_IEC_14496-1-System-2010.pdf, page 48 - */ +// 7.2.6.6 DecoderConfigDescriptor +// ISO_IEC_14496-1-System-2010.pdf, page 48 class SrsMp4DecoderConfigDescriptor : public SrsMp4BaseDescriptor { public: - // an indication of the object or scene description type that needs to be supported + // An indication of the object or scene description type that needs to be supported // by the decoder for this elementary stream as per Table 5. SrsMp4ObjectType objectTypeIndication; // bit(8) SrsMp4StreamType streamType; // bit(6) @@ -1521,10 +1417,8 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 7.3.2.3 SL Packet Header Configuration - * ISO_IEC_14496-1-System-2010.pdf, page 92 - */ +// 7.3.2.3 SL Packet Header Configuration +// ISO_IEC_14496-1-System-2010.pdf, page 92 class SrsMp4SLConfigDescriptor : public SrsMp4BaseDescriptor { public: @@ -1538,10 +1432,8 @@ protected: virtual srs_error_t decode_payload(SrsBuffer* buf); }; -/** - * 7.2.6.5 ES_Descriptor - * ISO_IEC_14496-1-System-2010.pdf, page 47 - */ +// 7.2.6.5 ES_Descriptor +// ISO_IEC_14496-1-System-2010.pdf, page 47 class SrsMp4ES_Descriptor : public SrsMp4BaseDescriptor { public: @@ -1569,12 +1461,10 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 5.6 Sample Description Boxes - * Elementary Stream Descriptors (esds) - * ISO_IEC_14496-14-MP4-2003.pdf, page 15 - * @see http://www.mp4ra.org/codecs.html - */ +// 5.6 Sample Description Boxes +// Elementary Stream Descriptors (esds) +// ISO_IEC_14496-14-MP4-2003.pdf, page 15 +// @see http://www.mp4ra.org/codecs.html class SrsMp4EsdsBox : public SrsMp4FullBox { public: @@ -1593,12 +1483,10 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.5.2 Sample Description Box (stsd), for Audio/Video. - * ISO_IEC_14496-12-base-format-2012.pdf, page 40 - * The sample description table gives detailed information about the coding type used, and any initialization - * information needed for that coding. - */ +// 8.5.2 Sample Description Box (stsd), for Audio/Video. +// ISO_IEC_14496-12-base-format-2012.pdf, page 40 +// The sample description table gives detailed information about the coding type used, and any initialization +// information needed for that coding. class SrsMp4SampleDescriptionBox : public SrsMp4FullBox { private: @@ -1624,16 +1512,14 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.6.1.2 Decoding Time to Sample Box (stts), for Audio/Video. - * ISO_IEC_14496-12-base-format-2012.pdf, page 48 - */ +// 8.6.1.2 Decoding Time to Sample Box (stts), for Audio/Video. +// ISO_IEC_14496-12-base-format-2012.pdf, page 48 struct SrsMp4SttsEntry { - // an integer that counts the number of consecutive samples that have the given + // An integer that counts the number of consecutive samples that have the given // duration. uint32_t sample_count; - // an integer that gives the delta of these samples in the time-scale of the media. + // An integer that gives the delta of these samples in the time-scale of the media. uint32_t sample_delta; // Constructor SrsMp4SttsEntry(); @@ -1642,18 +1528,16 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.6.1.2 Decoding Time to Sample Box (stts), for Audio/Video. - * ISO_IEC_14496-12-base-format-2012.pdf, page 48 - * This box contains a compact version of a table that allows indexing from decoding time to sample number. - * Other tables give sample sizes and pointers, from the sample number. Each entry in the table gives the - * number of consecutive samples with the same time delta, and the delta of those samples. By adding the - * deltas a complete time-to-sample map may be built. - */ +// 8.6.1.2 Decoding Time to Sample Box (stts), for Audio/Video. +// ISO_IEC_14496-12-base-format-2012.pdf, page 48 +// This box contains a compact version of a table that allows indexing from decoding time to sample number. +// Other tables give sample sizes and pointers, from the sample number. Each entry in the table gives the +// number of consecutive samples with the same time delta, and the delta of those samples. By adding the +// deltas a complete time-to-sample map may be built. class SrsMp4DecodingTime2SampleBox : public SrsMp4FullBox { public: - // an integer that gives the number of entries in the following table. + // An integer that gives the number of entries in the following table. std::vector entries; private: // The index for counter to calc the dts for samples. @@ -1675,17 +1559,15 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.6.1.3 Composition Time to Sample Box (ctts), for Video. - * ISO_IEC_14496-12-base-format-2012.pdf, page 49 - */ +// 8.6.1.3 Composition Time to Sample Box (ctts), for Video. +// ISO_IEC_14496-12-base-format-2012.pdf, page 49 struct SrsMp4CttsEntry { - // an integer that counts the number of consecutive samples that have the given offset. + // An integer that counts the number of consecutive samples that have the given offset. uint32_t sample_count; // uint32_t for version=0 // int32_t for version=1 - // an integer that gives the offset between CT and DT, such that CT(n) = DT(n) + + // An integer that gives the offset between CT and DT, such that CT(n) = DT(n) + // CTTS(n). int64_t sample_offset; // Constructor @@ -1695,20 +1577,18 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.6.1.3 Composition Time to Sample Box (ctts), for Video. - * ISO_IEC_14496-12-base-format-2012.pdf, page 49 - * This box provides the offset between decoding time and composition time. In version 0 of this box the - * decoding time must be less than the composition time, and the offsets are expressed as unsigned numbers - * such that CT(n) = DT(n) + CTTS(n) where CTTS(n) is the (uncompressed) table entry for sample n. In version - * 1 of this box, the composition timeline and the decoding timeline are still derived from each other, but the - * offsets are signed. It is recommended that for the computed composition timestamps, there is exactly one with - * the value 0 (zero). - */ +// 8.6.1.3 Composition Time to Sample Box (ctts), for Video. +// ISO_IEC_14496-12-base-format-2012.pdf, page 49 +// This box provides the offset between decoding time and composition time. In version 0 of this box the +// decoding time must be less than the composition time, and the offsets are expressed as unsigned numbers +// such that CT(n) = DT(n) + CTTS(n) where CTTS(n) is the (uncompressed) table entry for sample n. In version +// 1 of this box, the composition timeline and the decoding timeline are still derived from each other, but the +// offsets are signed. It is recommended that for the computed composition timestamps, there is exactly one with +// The value 0 (zero). class SrsMp4CompositionTime2SampleBox : public SrsMp4FullBox { public: - // an integer that gives the number of entries in the following table. + // An integer that gives the number of entries in the following table. std::vector entries; private: // The index for counter to calc the dts for samples. @@ -1730,19 +1610,17 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.6.2 Sync Sample Box (stss), for Video. - * ISO_IEC_14496-12-base-format-2012.pdf, page 51 - * This box provides a compact marking of the sync samples within the stream. The table is arranged in strictly - * increasing order of sample number. - */ +// 8.6.2 Sync Sample Box (stss), for Video. +// ISO_IEC_14496-12-base-format-2012.pdf, page 51 +// This box provides a compact marking of the sync samples within the stream. The table is arranged in strictly +// increasing order of sample number. class SrsMp4SyncSampleBox : public SrsMp4FullBox { public: - // an integer that gives the number of entries in the following table. If entry_count is zero, - // there are no sync samples within the stream and the following table is empty. + // An integer that gives the number of entries in the following table. If entry_count is zero, + // There are no sync samples within the stream and the following table is empty. uint32_t entry_count; - // the numbers of the samples that are sync samples in the stream. + // The numbers of the samples that are sync samples in the stream. uint32_t* sample_numbers; public: SrsMp4SyncSampleBox(); @@ -1758,20 +1636,18 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.7.4 Sample To Chunk Box (stsc), for Audio/Video. - * ISO_IEC_14496-12-base-format-2012.pdf, page 58 - */ +// 8.7.4 Sample To Chunk Box (stsc), for Audio/Video. +// ISO_IEC_14496-12-base-format-2012.pdf, page 58 struct SrsMp4StscEntry { - // an integer that gives the index of the first chunk in this run of chunks that share the + // An integer that gives the index of the first chunk in this run of chunks that share the // same samples-per-chunk and sample-description-index; the index of the first chunk in a track has the // value 1 (the first_chunk field in the first record of this box has the value 1, identifying that the first // sample maps to the first chunk). uint32_t first_chunk; - // an integer that gives the number of samples in each of these chunks + // An integer that gives the number of samples in each of these chunks uint32_t samples_per_chunk; - // an integer that gives the index of the sample entry that describes the + // An integer that gives the index of the sample entry that describes the // samples in this chunk. The index ranges from 1 to the number of sample entries in the Sample // Description Box uint32_t sample_description_index; @@ -1781,19 +1657,17 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.7.4 Sample To Chunk Box (stsc), for Audio/Video. - * ISO_IEC_14496-12-base-format-2012.pdf, page 58 - * Samples within the media data are grouped into chunks. Chunks can be of different sizes, and the samples - * within a chunk can have different sizes. This table can be used to find the chunk that contains a sample, - * its position, and the associated sample description. - */ +// 8.7.4 Sample To Chunk Box (stsc), for Audio/Video. +// ISO_IEC_14496-12-base-format-2012.pdf, page 58 +// Samples within the media data are grouped into chunks. Chunks can be of different sizes, and the samples +// within a chunk can have different sizes. This table can be used to find the chunk that contains a sample, +// its position, and the associated sample description. class SrsMp4Sample2ChunkBox : public SrsMp4FullBox { public: - // an integer that gives the number of entries in the following table + // An integer that gives the number of entries in the following table uint32_t entry_count; - // the numbers of the samples that are sync samples in the stream. + // The numbers of the samples that are sync samples in the stream. SrsMp4StscEntry* entries; private: // The index for counter to calc the dts for samples. @@ -1814,19 +1688,17 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.7.5 Chunk Offset Box (stco), for Audio/Video. - * ISO_IEC_14496-12-base-format-2012.pdf, page 59 - * The chunk offset table gives the index of each chunk into the containing file. There are two variants, permitting - * the use of 32-bit or 64-bit offsets. The latter is useful when managing very large presentations. At most one of - * these variants will occur in any single instance of a sample table. - */ +// 8.7.5 Chunk Offset Box (stco), for Audio/Video. +// ISO_IEC_14496-12-base-format-2012.pdf, page 59 +// The chunk offset table gives the index of each chunk into the containing file. There are two variants, permitting +// The use of 32-bit or 64-bit offsets. The latter is useful when managing very large presentations. At most one of +// These variants will occur in any single instance of a sample table. class SrsMp4ChunkOffsetBox : public SrsMp4FullBox { public: - // an integer that gives the number of entries in the following table + // An integer that gives the number of entries in the following table uint32_t entry_count; - // a 32 bit integer that gives the offset of the start of a chunk into its containing + // A 32 bit integer that gives the offset of the start of a chunk into its containing // media file. uint32_t* entries; public: @@ -1840,19 +1712,17 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.7.5 Chunk Large Offset Box (co64), for Audio/Video. - * ISO_IEC_14496-12-base-format-2012.pdf, page 59 - * The chunk offset table gives the index of each chunk into the containing file. There are two variants, permitting - * the use of 32-bit or 64-bit offsets. The latter is useful when managing very large presentations. At most one of - * these variants will occur in any single instance of a sample table. - */ +// 8.7.5 Chunk Large Offset Box (co64), for Audio/Video. +// ISO_IEC_14496-12-base-format-2012.pdf, page 59 +// The chunk offset table gives the index of each chunk into the containing file. There are two variants, permitting +// The use of 32-bit or 64-bit offsets. The latter is useful when managing very large presentations. At most one of +// These variants will occur in any single instance of a sample table. class SrsMp4ChunkLargeOffsetBox : public SrsMp4FullBox { public: - // an integer that gives the number of entries in the following table + // An integer that gives the number of entries in the following table uint32_t entry_count; - // a 64 bit integer that gives the offset of the start of a chunk into its containing + // A 64 bit integer that gives the offset of the start of a chunk into its containing // media file. uint64_t* entries; public: @@ -1866,24 +1736,22 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.7.3.2 Sample Size Box (stsz), for Audio/Video. - * ISO_IEC_14496-12-base-format-2012.pdf, page 58 - * This box contains the sample count and a table giving the size in bytes of each sample. This allows the media data - * itself to be unframed. The total number of samples in the media is always indicated in the sample count. - */ +// 8.7.3.2 Sample Size Box (stsz), for Audio/Video. +// ISO_IEC_14496-12-base-format-2012.pdf, page 58 +// This box contains the sample count and a table giving the size in bytes of each sample. This allows the media data +// itself to be unframed. The total number of samples in the media is always indicated in the sample count. class SrsMp4SampleSizeBox : public SrsMp4FullBox { public: - // the default sample size. If all the samples are the same size, this field + // The default sample size. If all the samples are the same size, this field // contains that size value. If this field is set to 0, then the samples have different sizes, and those sizes // are stored in the sample size table. If this field is not 0, it specifies the constant sample size, and no // array follows. uint32_t sample_size; - // an integer that gives the number of samples in the track; if sample-size is 0, then it is + // An integer that gives the number of samples in the track; if sample-size is 0, then it is // also the number of entries in the following table. uint32_t sample_count; - // each entry_size is an integer specifying the size of a sample, indexed by its number. + // Each entry_size is an integer specifying the size of a sample, indexed by its number. uint32_t* entry_sizes; public: SrsMp4SampleSizeBox(); @@ -1899,12 +1767,10 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * 8.10.1 User Data Box (udta) - * ISO_IEC_14496-12-base-format-2012.pdf, page 78 - * This box contains objects that declare user information about the containing box and its data (presentation or - * track). - */ +// 8.10.1 User Data Box (udta) +// ISO_IEC_14496-12-base-format-2012.pdf, page 78 +// This box contains objects that declare user information about the containing box and its data (presentation or +// track). class SrsMp4UserDataBox : public SrsMp4Box { public: @@ -1920,9 +1786,7 @@ public: virtual std::stringstream& dumps_detail(std::stringstream& ss, SrsMp4DumpContext dc); }; -/** - * Generally, a MP4 sample contains a frame, for example, a video frame or audio frame. - */ +// Generally, a MP4 sample contains a frame, for example, a video frame or audio frame. class SrsMp4Sample { public: @@ -1956,17 +1820,15 @@ public: virtual uint32_t pts_ms(); }; -/** - * Build samples from moov, or write samples to moov. - * One or more sample are grouped to a chunk, each track contains one or more chunks. - * The offset of chunk is specified by stco. - * The chunk-sample series is speicified by stsc. - * The sample size is specified by stsz. - * The dts is specified by stts. - * For video: - * The cts/pts is specified by ctts. - * The keyframe is specified by stss. - */ +// Build samples from moov, or write samples to moov. +// One or more sample are grouped to a chunk, each track contains one or more chunks. +// The offset of chunk is specified by stco. +// The chunk-sample series is speicified by stsc. +// The sample size is specified by stsz. +// The dts is specified by stts. +// For video: +// The cts/pts is specified by ctts. +// The keyframe is specified by stss. class SrsMp4SampleManager { public: @@ -2002,10 +1864,8 @@ private: SrsMp4DecodingTime2SampleBox* stts, SrsMp4CompositionTime2SampleBox* ctts, SrsMp4SyncSampleBox* stss); }; -/** - * The MP4 box reader, to get the RAW boxes without decode. - * @remark For mdat box, we only decode the header, then skip the data. - */ +// The MP4 box reader, to get the RAW boxes without decode. +// @remark For mdat box, we only decode the header, then skip the data. class SrsMp4BoxReader { private: @@ -2024,9 +1884,7 @@ public: virtual srs_error_t skip(SrsMp4Box* box, SrsSimpleStream* stream); }; -/** - * The MP4 demuxer. - */ +// The MP4 demuxer. class SrsMp4Decoder { private: @@ -2075,24 +1933,20 @@ public: SrsMp4Decoder(); virtual ~SrsMp4Decoder(); public: - /** - * Initialize the decoder with a reader r. - * @param r The underlayer io reader, user must manage it. - */ + // Initialize the decoder with a reader r. + // @param r The underlayer io reader, user must manage it. virtual srs_error_t initialize(ISrsReadSeeker* rs); - /** - * Read a sample from mp4. - * @param pht The sample hanler type, audio/soun or video/vide. - * @param pft, The frame type. For video, it's SrsVideoAvcFrameType. For audio, ignored. - * @param pct, The codec type. For video, it's SrsVideoAvcFrameTrait. For audio, it's SrsAudioAacFrameTrait. - * @param pdts The output dts in milliseconds. - * @param ppts The output pts in milliseconds. - * @param pnb_sample The output size of payload. - * @param psample The output payload, user must free it. - * @remark The decoder will generate the first two audio/video sequence header. - */ + // Read a sample from mp4. + // @param pht The sample hanler type, audio/soun or video/vide. + // @param pft, The frame type. For video, it's SrsVideoAvcFrameType. For audio, ignored. + // @param pct, The codec type. For video, it's SrsVideoAvcFrameTrait. For audio, it's SrsAudioAacFrameTrait. + // @param pdts The output dts in milliseconds. + // @param ppts The output pts in milliseconds. + // @param pnb_sample The output size of payload. + // @param psample The output payload, user must free it. + // @remark The decoder will generate the first two audio/video sequence header. virtual srs_error_t read_sample(SrsMp4HandlerType* pht, uint16_t* pft, uint16_t* pct, - uint32_t* pdts, uint32_t* ppts, uint8_t** psample, uint32_t* pnb_sample); + uint32_t* pdts, uint32_t* ppts, uint8_t** psample, uint32_t* pnb_sample); private: virtual srs_error_t parse_ftyp(SrsMp4FileTypeBox* ftyp); virtual srs_error_t parse_moov(SrsMp4MovieBox* moov); @@ -2104,9 +1958,7 @@ private: virtual srs_error_t do_load_next_box(SrsMp4Box** ppbox, uint32_t required_box_type); }; -/** - * The MP4 muxer. - */ +// The MP4 muxer. class SrsMp4Encoder { private: @@ -2172,9 +2024,7 @@ private: virtual srs_error_t do_write_sample(SrsMp4Sample* ps, uint8_t* sample, uint32_t nb_sample); }; -/** - * A fMP4 encoder, to write the init.mp4 with sequence header. - */ +// A fMP4 encoder, to write the init.mp4 with sequence header. class SrsMp4M2tsInitEncoder { private: @@ -2189,10 +2039,8 @@ public: virtual srs_error_t write(SrsFormat* format, bool video, int tid); }; -/** - * A fMP4 encoder, to cache segments then flush to disk, because the fMP4 should write - * trun box before mdat. - */ +// A fMP4 encoder, to cache segments then flush to disk, because the fMP4 should write +// trun box before mdat. class SrsMp4M2tsSegmentEncoder { private: diff --git a/trunk/src/kernel/srs_kernel_ts.hpp b/trunk/src/kernel/srs_kernel_ts.hpp index c31dd4eb2..d076bfbe7 100644 --- a/trunk/src/kernel/srs_kernel_ts.hpp +++ b/trunk/src/kernel/srs_kernel_ts.hpp @@ -5,15 +5,15 @@ * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to + * The Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, + * The Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * The SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER @@ -51,14 +51,12 @@ class SrsTsContext; // Transport Stream packets are 188 bytes in length. #define SRS_TS_PACKET_SIZE 188 -// the aggregate pure audio for hls, in ts tbn(ms * 90). +// The aggregate pure audio for hls, in ts tbn(ms * 90). #define SRS_CONSTS_HLS_PURE_AUDIO_AGGREGATE 720 * 90 -/** - * the pid of ts packet, - * Table 2-3 - PID table, hls-mpeg-ts-iso13818-1.pdf, page 37 - * NOTE - The transport packets with PID values 0x0000, 0x0001, and 0x0010-0x1FFE are allowed to carry a PCR. - */ +// The pid of ts packet, +// Table 2-3 - PID table, hls-mpeg-ts-iso13818-1.pdf, page 37 +// NOTE - The transport packets with PID values 0x0000, 0x0001, and 0x0010-0x1FFE are allowed to carry a PCR. enum SrsTsPid { // Program Association Table(see Table 2-25). @@ -73,14 +71,12 @@ enum SrsTsPid // May be assigned as network_PID, Program_map_PID, elementary_PID, or for other purposes SrsTsPidAppStart = 0x10, SrsTsPidAppEnd = 0x1ffe, - // null packets (see Table 2-3) + // For null packets (see Table 2-3) SrsTsPidNULL = 0x01FFF, }; -/** - * the transport_scrambling_control of ts packet, - * Table 2-4 - Scrambling control values, hls-mpeg-ts-iso13818-1.pdf, page 38 - */ +// The transport_scrambling_control of ts packet, +// Table 2-4 - Scrambling control values, hls-mpeg-ts-iso13818-1.pdf, page 38 enum SrsTsScrambled { // Not scrambled @@ -93,10 +89,8 @@ enum SrsTsScrambled SrsTsScrambledUserDefined3 = 0x03, }; -/** - * the adaption_field_control of ts packet, - * Table 2-5 - Adaptation field control values, hls-mpeg-ts-iso13818-1.pdf, page 38 - */ +// the adaption_field_control of ts packet, +// Table 2-5 - Adaptation field control values, hls-mpeg-ts-iso13818-1.pdf, page 38 enum SrsTsAdaptationFieldType { // Reserved for future use by ISO/IEC @@ -109,10 +103,8 @@ enum SrsTsAdaptationFieldType SrsTsAdaptationFieldTypeBoth = 0x03, }; -/** - * the actually parsed ts pid, - * @see SrsTsPid, some pid, for example, PMT/Video/Audio is specified by PAT or other tables. - */ +// the actually parsed ts pid, +// @see SrsTsPid, some pid, for example, PMT/Video/Audio is specified by PAT or other tables. enum SrsTsPidApply { SrsTsPidApplyReserved = 0, // TSPidTypeReserved, nothing parsed, used reserved. @@ -124,9 +116,7 @@ enum SrsTsPidApply SrsTsPidApplyAudio, // vor audio }; -/** - * Table 2-29 - Stream type assignments - */ +// Table 2-29 - Stream type assignments enum SrsTsStream { // ITU-T | ISO/IEC Reserved @@ -166,9 +156,7 @@ enum SrsTsStream }; std::string srs_ts_stream2string(SrsTsStream stream); -/** - * the ts channel. - */ +// The ts channel. struct SrsTsChannel { int pid; @@ -183,10 +171,8 @@ struct SrsTsChannel virtual ~SrsTsChannel(); }; -/** - * the stream_id of PES payload of ts packet. - * Table 2-18 - Stream_id assignments, hls-mpeg-ts-iso13818-1.pdf, page 52. - */ +// The stream_id of PES payload of ts packet. +// Table 2-18 - Stream_id assignments, hls-mpeg-ts-iso13818-1.pdf, page 52. enum SrsTsPESStreamId { // program_stream_map @@ -244,104 +230,82 @@ enum SrsTsPESStreamId SrsTsPESStreamIdProgramStreamDirectory = 0xff, // 0b11111111 }; -/** - * the media audio/video message parsed from PES packet. - */ +// The media audio/video message parsed from PES packet. class SrsTsMessage { public: - // decoder only, + // For decoder only, // the ts messgae does not use them, // for user to get the channel and packet. SrsTsChannel* channel; SrsTsPacket* packet; public: - // the audio cache buffer start pts, to flush audio if full. + // The audio cache buffer start pts, to flush audio if full. // @remark the pts is not the adjust one, it's the orignal pts. int64_t start_pts; - // whether this message with pcr info, + // Whether this message with pcr info, // generally, the video IDR(I frame, the keyframe of h.264) carray the pcr info. bool write_pcr; - // whether got discontinuity ts, for example, sequence header changed. + // Whether got discontinuity ts, for example, sequence header changed. bool is_discontinuity; public: - // the timestamp in 90khz + // The timestamp in 90khz int64_t dts; int64_t pts; - // the id of pes stream to indicates the payload codec. + // The id of pes stream to indicates the payload codec. // @remark use is_audio() and is_video() to check it, and stream_number() to finger it out. SrsTsPESStreamId sid; - // the size of payload, 0 indicates the length() of payload. + // The size of payload, 0 indicates the length() of payload. uint16_t PES_packet_length; - // the chunk id. + // The chunk id. uint8_t continuity_counter; - // the payload bytes. + // The payload bytes. SrsSimpleStream* payload; public: SrsTsMessage(SrsTsChannel* c = NULL, SrsTsPacket* p = NULL); virtual ~SrsTsMessage(); - // decoder +// For decoder public: - /** - * dumps all bytes in stream to ts message. - */ - virtual srs_error_t dump(SrsBuffer* stream, int* pnb_bytes); - /** - * whether ts message is completed to reap. - * @param payload_unit_start_indicator whether new ts message start. - * PES_packet_length is 0, the payload_unit_start_indicator=1 to reap ts message. - * PES_packet_length > 0, the payload.length() == PES_packet_length to reap ts message. - * @remark when PES_packet_length>0, the payload_unit_start_indicator should never be 1 when not completed. - * @remark when fresh, the payload_unit_start_indicator should be 1. - */ + // To dumps all bytes in stream to ts message. + virtual srs_error_t dump(SrsBuffer* stream, int* pnb_bytes); + // Whether ts message is completed to reap. + // @param payload_unit_start_indicator whether new ts message start. + // PES_packet_length is 0, the payload_unit_start_indicator=1 to reap ts message. + // PES_packet_length > 0, the payload.length() == PES_packet_length to reap ts message. + // @remark when PES_packet_length>0, the payload_unit_start_indicator should never be 1 when not completed. + // @remark when fresh, the payload_unit_start_indicator should be 1. virtual bool completed(int8_t payload_unit_start_indicator); - /** - * whether the message is fresh. - */ + // Whether the message is fresh. virtual bool fresh(); public: - /** - * whether the sid indicates the elementary stream audio. - */ + // Whether the sid indicates the elementary stream audio. virtual bool is_audio(); - /** - * whether the sid indicates the elementary stream video. - */ + // Whether the sid indicates the elementary stream video. virtual bool is_video(); - /** - * when audio or video, get the stream number which specifies the format of stream. - * @return the stream number for audio/video; otherwise, -1. - */ + // When audio or video, get the stream number which specifies the format of stream. + // @return the stream number for audio/video; otherwise, -1. virtual int stream_number(); public: - /** - * detach the ts message, - * for user maybe need to parse the message by queue. - * @remark we always use the payload of original message. - */ + // Detach the ts message, + // for user maybe need to parse the message by queue. + // @remark we always use the payload of original message. virtual SrsTsMessage* detach(); }; -/** - * the ts message handler. - */ +// The ts message handler. class ISrsTsHandler { public: ISrsTsHandler(); virtual ~ISrsTsHandler(); public: - /** - * when ts context got message, use handler to process it. - * @param msg the ts msg, user should never free it. - * @return an int error code. - */ + // When ts context got message, use handler to process it. + // @param msg the ts msg, user should never free it. + // @return an int error code. virtual srs_error_t on_ts_message(SrsTsMessage* msg) = 0; }; -/** - * the context of ts, to decode the ts stream. - */ +// The context of ts, to decode the ts stream. class SrsTsContext { private: @@ -363,151 +327,117 @@ public: SrsTsContext(); virtual ~SrsTsContext(); public: - /** - * whether the hls stream is pure audio stream. - */ - // TODO: FIXME: merge with muxer codec detect. + // Whether the hls stream is pure audio stream. + // TODO: FIXME: merge with muxer codec detect. virtual bool is_pure_audio(); - /** - * when PMT table parsed, we know some info about stream. - */ + // When PMT table parsed, we know some info about stream. virtual void on_pmt_parsed(); - /** - * reset the context for a new ts segment start. - */ + // Reset the context for a new ts segment start. virtual void reset(); // codec public: - /** - * get the pid apply, the parsed pid. - * @return the apply channel; NULL for invalid. - */ + // Get the pid apply, the parsed pid. + // @return the apply channel; NULL for invalid. virtual SrsTsChannel* get(int pid); - /** - * set the pid apply, the parsed pid. - */ + // Set the pid apply, the parsed pid. virtual void set(int pid, SrsTsPidApply apply_pid, SrsTsStream stream = SrsTsStreamReserved); // decode methods public: - /** - * the stream contains only one ts packet. - * @param handler the ts message handler to process the msg. - * @remark we will consume all bytes in stream. - */ + // The stream contains only one ts packet. + // @param handler the ts message handler to process the msg. + // @remark we will consume all bytes in stream. virtual srs_error_t decode(SrsBuffer* stream, ISrsTsHandler* handler); // encode methods public: - /** - * write the PES packet, the video/audio stream. - * @param msg the video/audio msg to write to ts. - * @param vc the video codec, write the PAT/PMT table when changed. - * @param ac the audio codec, write the PAT/PMT table when changed. - */ + // Write the PES packet, the video/audio stream. + // @param msg the video/audio msg to write to ts. + // @param vc the video codec, write the PAT/PMT table when changed. + // @param ac the audio codec, write the PAT/PMT table when changed. virtual srs_error_t encode(ISrsStreamWriter* writer, SrsTsMessage* msg, SrsVideoCodecId vc, SrsAudioCodecId ac); // drm methods public: - /** - * set sync byte of ts segment. - * replace the standard ts sync byte to bravo sync byte. - */ + // Set sync byte of ts segment. + // replace the standard ts sync byte to bravo sync byte. virtual void set_sync_byte(int8_t sb); private: virtual srs_error_t encode_pat_pmt(ISrsStreamWriter* writer, int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as); virtual srs_error_t encode_pes(ISrsStreamWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid, bool pure_audio); }; -/** - * the packet in ts stream, - * 2.4.3.2 Transport Stream packet layer, hls-mpeg-ts-iso13818-1.pdf, page 36 - * Transport Stream packets shall be 188 bytes long. - */ +// The packet in ts stream, +// 2.4.3.2 Transport Stream packet layer, hls-mpeg-ts-iso13818-1.pdf, page 36 +// Transport Stream packets shall be 188 bytes long. class SrsTsPacket { public: // 1B - /** - * The sync_byte is a fixed 8-bit field whose value is '0100 0111' (0x47). Sync_byte emulation in the choice of - * values for other regularly occurring fields, such as PID, should be avoided. - */ + // The sync_byte is a fixed 8-bit field whose value is '0100 0111' (0x47). Sync_byte emulation in the choice of + // values for other regularly occurring fields, such as PID, should be avoided. int8_t sync_byte; //8bits // 2B - /** - * The transport_error_indicator is a 1-bit flag. When set to '1' it indicates that at least - * 1 uncorrectable bit error exists in the associated Transport Stream packet. This bit may be set to '1' by entities external to - * the transport layer. When set to '1' this bit shall not be reset to '0' unless the bit value(s) in error have been corrected. - */ + // The transport_error_indicator is a 1-bit flag. When set to '1' it indicates that at least + // 1 uncorrectable bit error exists in the associated Transport Stream packet. This bit may be set to '1' by entities external to + // the transport layer. When set to '1' this bit shall not be reset to '0' unless the bit value(s) in error have been corrected. int8_t transport_error_indicator; //1bit - /** - * The payload_unit_start_indicator is a 1-bit flag which has normative meaning for - * Transport Stream packets that carry PES packets (refer to 2.4.3.6) or PSI data (refer to 2.4.4). - * - * When the payload of the Transport Stream packet contains PES packet data, the payload_unit_start_indicator has the - * following significance: a '1' indicates that the payload of this Transport Stream packet will commence(start) with the first byte - * of a PES packet and a '0' indicates no PES packet shall start in this Transport Stream packet. If the - * payload_unit_start_indicator is set to '1', then one and only one PES packet starts in this Transport Stream packet. This - * also applies to private streams of stream_type 6 (refer to Table 2-29). - * - * When the payload of the Transport Stream packet contains PSI data, the payload_unit_start_indicator has the following - * significance: if the Transport Stream packet carries the first byte of a PSI section, the payload_unit_start_indicator value - * shall be '1', indicating that the first byte of the payload of this Transport Stream packet carries the pointer_field. If the - * Transport Stream packet does not carry the first byte of a PSI section, the payload_unit_start_indicator value shall be '0', - * indicating that there is no pointer_field in the payload. Refer to 2.4.4.1 and 2.4.4.2. This also applies to private streams of - * stream_type 5 (refer to Table 2-29). - * - * For null packets the payload_unit_start_indicator shall be set to '0'. - * - * The meaning of this bit for Transport Stream packets carrying only private data is not defined in this Specification. - */ + // The payload_unit_start_indicator is a 1-bit flag which has normative meaning for + // Transport Stream packets that carry PES packets (refer to 2.4.3.6) or PSI data (refer to 2.4.4). + // + // When the payload of the Transport Stream packet contains PES packet data, the payload_unit_start_indicator has the + // following significance: a '1' indicates that the payload of this Transport Stream packet will commence(start) with the first byte + // of a PES packet and a '0' indicates no PES packet shall start in this Transport Stream packet. If the + // payload_unit_start_indicator is set to '1', then one and only one PES packet starts in this Transport Stream packet. This + // also applies to private streams of stream_type 6 (refer to Table 2-29). + // + // When the payload of the Transport Stream packet contains PSI data, the payload_unit_start_indicator has the following + // significance: if the Transport Stream packet carries the first byte of a PSI section, the payload_unit_start_indicator value + // shall be '1', indicating that the first byte of the payload of this Transport Stream packet carries the pointer_field. If the + // Transport Stream packet does not carry the first byte of a PSI section, the payload_unit_start_indicator value shall be '0', + // indicating that there is no pointer_field in the payload. Refer to 2.4.4.1 and 2.4.4.2. This also applies to private streams of + // stream_type 5 (refer to Table 2-29). + // + // For null packets the payload_unit_start_indicator shall be set to '0'. + // + // The meaning of this bit for Transport Stream packets carrying only private data is not defined in this Specification. int8_t payload_unit_start_indicator; //1bit - /** - * The transport_priority is a 1-bit indicator. When set to '1' it indicates that the associated packet is - * of greater priority than other packets having the same PID which do not have the bit set to '1'. The transport mechanism - * can use this to prioritize its data within an elementary stream. Depending on the application the transport_priority field - * may be coded regardless of the PID or within one PID only. This field may be changed by channel specific encoders or - * decoders. - */ + // The transport_priority is a 1-bit indicator. When set to '1' it indicates that the associated packet is + // of greater priority than other packets having the same PID which do not have the bit set to '1'. The transport mechanism + // can use this to prioritize its data within an elementary stream. Depending on the application the transport_priority field + // may be coded regardless of the PID or within one PID only. This field may be changed by channel specific encoders or + // decoders. int8_t transport_priority; //1bit - /** - * The PID is a 13-bit field, indicating the type of the data stored in the packet payload. PID value 0x0000 is - * reserved for the Program Association Table (see Table 2-25). PID value 0x0001 is reserved for the Conditional Access - * Table (see Table 2-27). PID values 0x0002 - 0x000F are reserved. PID value 0x1FFF is reserved for null packets (see - * Table 2-3). - */ + // The PID is a 13-bit field, indicating the type of the data stored in the packet payload. PID value 0x0000 is + // reserved for the Program Association Table (see Table 2-25). PID value 0x0001 is reserved for the Conditional Access + // Table (see Table 2-27). PID values 0x0002 - 0x000F are reserved. PID value 0x1FFF is reserved for null packets (see + // Table 2-3). SrsTsPid pid; //13bits // 1B - /** - * This 2-bit field indicates the scrambling mode of the Transport Stream packet payload. - * The Transport Stream packet header, and the adaptation field when present, shall not be scrambled. In the case of a null - * packet the value of the transport_scrambling_control field shall be set to '00' (see Table 2-4). - */ + // This 2-bit field indicates the scrambling mode of the Transport Stream packet payload. + // The Transport Stream packet header, and the adaptation field when present, shall not be scrambled. In the case of a null + // packet the value of the transport_scrambling_control field shall be set to '00' (see Table 2-4). SrsTsScrambled transport_scrambling_control; //2bits - /** - * This 2-bit field indicates whether this Transport Stream packet header is followed by an - * adaptation field and/or payload (see Table 2-5). - * - * ITU-T Rec. H.222.0 | ISO/IEC 13818-1 decoders shall discard Transport Stream packets with the - * adaptation_field_control field set to a value of '00'. In the case of a null packet the value of the adaptation_field_control - * shall be set to '01'. - */ + // This 2-bit field indicates whether this Transport Stream packet header is followed by an + // adaptation field and/or payload (see Table 2-5). + // + // ITU-T Rec. H.222.0 | ISO/IEC 13818-1 decoders shall discard Transport Stream packets with the + // adaptation_field_control field set to a value of '00'. In the case of a null packet the value of the adaptation_field_control + // shall be set to '01'. SrsTsAdaptationFieldType adaption_field_control; //2bits - /** - * The continuity_counter is a 4-bit field incrementing with each Transport Stream packet with the - * same PID. The continuity_counter wraps around to 0 after its maximum value. The continuity_counter shall not be - * incremented when the adaptation_field_control of the packet equals '00'(reseverd) or '10'(adaptation field only). - * - * In Transport Streams, duplicate packets may be sent as two, and only two, consecutive Transport Stream packets of the - * same PID. The duplicate packets shall have the same continuity_counter value as the original packet and the - * adaptation_field_control field shall be equal to '01'(payload only) or '11'(both). In duplicate packets each byte of the original packet shall be - * duplicated, with the exception that in the program clock reference fields, if present, a valid value shall be encoded. - * - * The continuity_counter in a particular Transport Stream packet is continuous when it differs by a positive value of one - * from the continuity_counter value in the previous Transport Stream packet of the same PID, or when either of the nonincrementing - * conditions (adaptation_field_control set to '00' or '10', or duplicate packets as described above) are met. - * The continuity counter may be discontinuous when the discontinuity_indicator is set to '1' (refer to 2.4.3.4). In the case of - * a null packet the value of the continuity_counter is undefined. - */ + // The continuity_counter is a 4-bit field incrementing with each Transport Stream packet with the + // same PID. The continuity_counter wraps around to 0 after its maximum value. The continuity_counter shall not be + // incremented when the adaptation_field_control of the packet equals '00'(reseverd) or '10'(adaptation field only). + // + // In Transport Streams, duplicate packets may be sent as two, and only two, consecutive Transport Stream packets of the + // same PID. The duplicate packets shall have the same continuity_counter value as the original packet and the + // adaptation_field_control field shall be equal to '01'(payload only) or '11'(both). In duplicate packets each byte of the original packet shall be + // duplicated, with the exception that in the program clock reference fields, if present, a valid value shall be encoded. + // + // The continuity_counter in a particular Transport Stream packet is continuous when it differs by a positive value of one + // from the continuity_counter value in the previous Transport Stream packet of the same PID, or when either of the nonincrementing + // conditions (adaptation_field_control set to '00' or '10', or duplicate packets as described above) are met. + // The continuity counter may be discontinuous when the discontinuity_indicator is set to '1' (refer to 2.4.3.4). In the case of + // a null packet the value of the continuity_counter is undefined. uint8_t continuity_counter; //4bits private: SrsTsAdaptationField* adaptation_field; @@ -526,289 +456,239 @@ public: public: static SrsTsPacket* create_pat(SrsTsContext* context, int16_t pmt_number, int16_t pmt_pid); static SrsTsPacket* create_pmt(SrsTsContext* context, int16_t pmt_number, int16_t pmt_pid, - int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as); + int16_t vpid, SrsTsStream vs, int16_t apid, SrsTsStream as); static SrsTsPacket* create_pes_first(SrsTsContext* context, int16_t pid, SrsTsPESStreamId sid, - uint8_t continuity_counter, bool discontinuity, int64_t pcr, int64_t dts, int64_t pts, int size); + uint8_t continuity_counter, bool discontinuity, int64_t pcr, int64_t dts, int64_t pts, int size); static SrsTsPacket* create_pes_continue(SrsTsContext* context, - int16_t pid, SrsTsPESStreamId sid, uint8_t continuity_counter); + int16_t pid, SrsTsPESStreamId sid, uint8_t continuity_counter); }; -/** - * the adaption field of ts packet. - * 2.4.3.5 Semantic definition of fields in adaptation field, hls-mpeg-ts-iso13818-1.pdf, page 39 - * Table 2-6 - Transport Stream adaptation field, hls-mpeg-ts-iso13818-1.pdf, page 40 - */ +// The adaption field of ts packet. +// 2.4.3.5 Semantic definition of fields in adaptation field, hls-mpeg-ts-iso13818-1.pdf, page 39 +// Table 2-6 - Transport Stream adaptation field, hls-mpeg-ts-iso13818-1.pdf, page 40 class SrsTsAdaptationField { public: // 1B - /** - * The adaptation_field_length is an 8-bit field specifying the number of bytes in the - * adaptation_field immediately following the adaptation_field_length. The value 0 is for inserting a single stuffing byte in - * a Transport Stream packet. When the adaptation_field_control value is '11', the value of the adaptation_field_length shall - * be in the range 0 to 182. When the adaptation_field_control value is '10', the value of the adaptation_field_length shall - * be 183. For Transport Stream packets carrying PES packets, stuffing is needed when there is insufficient PES packet data - * to completely fill the Transport Stream packet payload bytes. Stuffing is accomplished by defining an adaptation field - * longer than the sum of the lengths of the data elements in it, so that the payload bytes remaining after the adaptation field - * exactly accommodates the available PES packet data. The extra space in the adaptation field is filled with stuffing bytes. - * - * This is the only method of stuffing allowed for Transport Stream packets carrying PES packets. For Transport Stream - * packets carrying PSI, an alternative stuffing method is described in 2.4.4. - */ + // The adaptation_field_length is an 8-bit field specifying the number of bytes in the + // adaptation_field immediately following the adaptation_field_length. The value 0 is for inserting a single stuffing byte in + // a Transport Stream packet. When the adaptation_field_control value is '11', the value of the adaptation_field_length shall + // be in the range 0 to 182. When the adaptation_field_control value is '10', the value of the adaptation_field_length shall + // be 183. For Transport Stream packets carrying PES packets, stuffing is needed when there is insufficient PES packet data + // to completely fill the Transport Stream packet payload bytes. Stuffing is accomplished by defining an adaptation field + // longer than the sum of the lengths of the data elements in it, so that the payload bytes remaining after the adaptation field + // exactly accommodates the available PES packet data. The extra space in the adaptation field is filled with stuffing bytes. + // + // This is the only method of stuffing allowed for Transport Stream packets carrying PES packets. For Transport Stream + // packets carrying PSI, an alternative stuffing method is described in 2.4.4. uint8_t adaption_field_length; //8bits // 1B - /** - * This is a 1-bit field which when set to '1' indicates that the discontinuity state is true for the - * current Transport Stream packet. When the discontinuity_indicator is set to '0' or is not present, the discontinuity state is - * false. The discontinuity indicator is used to indicate two types of discontinuities, system time-base discontinuities and - * continuity_counter discontinuities. - * - * A system time-base discontinuity is indicated by the use of the discontinuity_indicator in Transport Stream packets of a - * PID designated as a PCR_PID (refer to 2.4.4.9). When the discontinuity state is true for a Transport Stream packet of a - * PID designated as a PCR_PID, the next PCR in a Transport Stream packet with that same PID represents a sample of a - * new system time clock for the associated program. The system time-base discontinuity point is defined to be the instant - * in time when the first byte of a packet containing a PCR of a new system time-base arrives at the input of the T-STD. - * The discontinuity_indicator shall be set to '1' in the packet in which the system time-base discontinuity occurs. The - * discontinuity_indicator bit may also be set to '1' in Transport Stream packets of the same PCR_PID prior to the packet - * which contains the new system time-base PCR. In this case, once the discontinuity_indicator has been set to '1', it shall - * continue to be set to '1' in all Transport Stream packets of the same PCR_PID up to and including the Transport Stream - * packet which contains the first PCR of the new system time-base. After the occurrence of a system time-base - * discontinuity, no fewer than two PCRs for the new system time-base shall be received before another system time-base - * discontinuity can occur. Further, except when trick mode status is true, data from no more than two system time-bases - * shall be present in the set of T-STD buffers for one program at any time. - * - * Prior to the occurrence of a system time-base discontinuity, the first byte of a Transport Stream packet which contains a - * PTS or DTS which refers to the new system time-base shall not arrive at the input of the T-STD. After the occurrence of - * a system time-base discontinuity, the first byte of a Transport Stream packet which contains a PTS or DTS which refers - * to the previous system time-base shall not arrive at the input of the T-STD. - * - * A continuity_counter discontinuity is indicated by the use of the discontinuity_indicator in any Transport Stream packet. - * When the discontinuity state is true in any Transport Stream packet of a PID not designated as a PCR_PID, the - * continuity_counter in that packet may be discontinuous with respect to the previous Transport Stream packet of the same - * PID. When the discontinuity state is true in a Transport Stream packet of a PID that is designated as a PCR_PID, the - * continuity_counter may only be discontinuous in the packet in which a system time-base discontinuity occurs. A - * continuity counter discontinuity point occurs when the discontinuity state is true in a Transport Stream packet and the - * continuity_counter in the same packet is discontinuous with respect to the previous Transport Stream packet of the same - * PID. A continuity counter discontinuity point shall occur at most one time from the initiation of the discontinuity state - * until the conclusion of the discontinuity state. Furthermore, for all PIDs that are not designated as PCR_PIDs, when the - * discontinuity_indicator is set to '1' in a packet of a specific PID, the discontinuity_indicator may be set to '1' in the next - * Transport Stream packet of that same PID, but shall not be set to '1' in three consecutive Transport Stream packet of that - * same PID. - * - * For the purpose of this clause, an elementary stream access point is defined as follows: - * Video - The first byte of a video sequence header. - * Audio - The first byte of an audio frame. - * - * After a continuity counter discontinuity in a Transport packet which is designated as containing elementary stream data, - * the first byte of elementary stream data in a Transport Stream packet of the same PID shall be the first byte of an - * elementary stream access point or in the case of video, the first byte of an elementary stream access point or a - * sequence_end_code followed by an access point. Each Transport Stream packet which contains elementary stream data - * with a PID not designated as a PCR_PID, and in which a continuity counter discontinuity point occurs, and in which a - * PTS or DTS occurs, shall arrive at the input of the T-STD after the system time-base discontinuity for the associated - * program occurs. In the case where the discontinuity state is true, if two consecutive Transport Stream packets of the same - * PID occur which have the same continuity_counter value and have adaptation_field_control values set to '01' or '11', the - * second packet may be discarded. A Transport Stream shall not be constructed in such a way that discarding such a packet - * will cause the loss of PES packet payload data or PSI data. - * - * After the occurrence of a discontinuity_indicator set to '1' in a Transport Stream packet which contains PSI information, - * a single discontinuity in the version_number of PSI sections may occur. At the occurrence of such a discontinuity, a - * version of the TS_program_map_sections of the appropriate program shall be sent with section_length = = 13 and the - * current_next_indicator = = 1, such that there are no program_descriptors and no elementary streams described. This shall - * then be followed by a version of the TS_program_map_section for each affected program with the version_number - * incremented by one and the current_next_indicator = = 1, containing a complete program definition. This indicates a - * version change in PSI data. - */ + // This is a 1-bit field which when set to '1' indicates that the discontinuity state is true for the + // current Transport Stream packet. When the discontinuity_indicator is set to '0' or is not present, the discontinuity state is + // false. The discontinuity indicator is used to indicate two types of discontinuities, system time-base discontinuities and + // continuity_counter discontinuities. + // + // A system time-base discontinuity is indicated by the use of the discontinuity_indicator in Transport Stream packets of a + // PID designated as a PCR_PID (refer to 2.4.4.9). When the discontinuity state is true for a Transport Stream packet of a + // PID designated as a PCR_PID, the next PCR in a Transport Stream packet with that same PID represents a sample of a + // new system time clock for the associated program. The system time-base discontinuity point is defined to be the instant + // in time when the first byte of a packet containing a PCR of a new system time-base arrives at the input of the T-STD. + // The discontinuity_indicator shall be set to '1' in the packet in which the system time-base discontinuity occurs. The + // discontinuity_indicator bit may also be set to '1' in Transport Stream packets of the same PCR_PID prior to the packet + // which contains the new system time-base PCR. In this case, once the discontinuity_indicator has been set to '1', it shall + // continue to be set to '1' in all Transport Stream packets of the same PCR_PID up to and including the Transport Stream + // packet which contains the first PCR of the new system time-base. After the occurrence of a system time-base + // discontinuity, no fewer than two PCRs for the new system time-base shall be received before another system time-base + // discontinuity can occur. Further, except when trick mode status is true, data from no more than two system time-bases + // shall be present in the set of T-STD buffers for one program at any time. + // + // Prior to the occurrence of a system time-base discontinuity, the first byte of a Transport Stream packet which contains a + // PTS or DTS which refers to the new system time-base shall not arrive at the input of the T-STD. After the occurrence of + // a system time-base discontinuity, the first byte of a Transport Stream packet which contains a PTS or DTS which refers + // to the previous system time-base shall not arrive at the input of the T-STD. + // + // A continuity_counter discontinuity is indicated by the use of the discontinuity_indicator in any Transport Stream packet. + // When the discontinuity state is true in any Transport Stream packet of a PID not designated as a PCR_PID, the + // continuity_counter in that packet may be discontinuous with respect to the previous Transport Stream packet of the same + // PID. When the discontinuity state is true in a Transport Stream packet of a PID that is designated as a PCR_PID, the + // continuity_counter may only be discontinuous in the packet in which a system time-base discontinuity occurs. A + // continuity counter discontinuity point occurs when the discontinuity state is true in a Transport Stream packet and the + // continuity_counter in the same packet is discontinuous with respect to the previous Transport Stream packet of the same + // PID. A continuity counter discontinuity point shall occur at most one time from the initiation of the discontinuity state + // until the conclusion of the discontinuity state. Furthermore, for all PIDs that are not designated as PCR_PIDs, when the + // discontinuity_indicator is set to '1' in a packet of a specific PID, the discontinuity_indicator may be set to '1' in the next + // Transport Stream packet of that same PID, but shall not be set to '1' in three consecutive Transport Stream packet of that + // same PID. + // + // For the purpose of this clause, an elementary stream access point is defined as follows: + // Video - The first byte of a video sequence header. + // Audio - The first byte of an audio frame. + // + // After a continuity counter discontinuity in a Transport packet which is designated as containing elementary stream data, + // the first byte of elementary stream data in a Transport Stream packet of the same PID shall be the first byte of an + // elementary stream access point or in the case of video, the first byte of an elementary stream access point or a + // sequence_end_code followed by an access point. Each Transport Stream packet which contains elementary stream data + // with a PID not designated as a PCR_PID, and in which a continuity counter discontinuity point occurs, and in which a + // PTS or DTS occurs, shall arrive at the input of the T-STD after the system time-base discontinuity for the associated + // program occurs. In the case where the discontinuity state is true, if two consecutive Transport Stream packets of the same + // PID occur which have the same continuity_counter value and have adaptation_field_control values set to '01' or '11', the + // second packet may be discarded. A Transport Stream shall not be constructed in such a way that discarding such a packet + // will cause the loss of PES packet payload data or PSI data. + // + // After the occurrence of a discontinuity_indicator set to '1' in a Transport Stream packet which contains PSI information, + // a single discontinuity in the version_number of PSI sections may occur. At the occurrence of such a discontinuity, a + // version of the TS_program_map_sections of the appropriate program shall be sent with section_length = = 13 and the + // current_next_indicator = = 1, such that there are no program_descriptors and no elementary streams described. This shall + // then be followed by a version of the TS_program_map_section for each affected program with the version_number + // incremented by one and the current_next_indicator = = 1, containing a complete program definition. This indicates a + // version change in PSI data. int8_t discontinuity_indicator; //1bit - /** - * The random_access_indicator is a 1-bit field that indicates that the current Transport - * Stream packet, and possibly subsequent Transport Stream packets with the same PID, contain some information to aid - * random access at this point. Specifically, when the bit is set to '1', the next PES packet to start in the payload of Transport - * Stream packets with the current PID shall contain the first byte of a video sequence header if the PES stream type (refer - * to Table 2-29) is 1 or 2, or shall contain the first byte of an audio frame if the PES stream type is 3 or 4. In addition, in - * the case of video, a presentation timestamp shall be present in the PES packet containing the first picture following the - * sequence header. In the case of audio, the presentation timestamp shall be present in the PES packet containing the first - * byte of the audio frame. In the PCR_PID the random_access_indicator may only be set to '1' in Transport Stream packet - * containing the PCR fields. - */ + // The random_access_indicator is a 1-bit field that indicates that the current Transport + // Stream packet, and possibly subsequent Transport Stream packets with the same PID, contain some information to aid + // random access at this point. Specifically, when the bit is set to '1', the next PES packet to start in the payload of Transport + // Stream packets with the current PID shall contain the first byte of a video sequence header if the PES stream type (refer + // to Table 2-29) is 1 or 2, or shall contain the first byte of an audio frame if the PES stream type is 3 or 4. In addition, in + // the case of video, a presentation timestamp shall be present in the PES packet containing the first picture following the + // sequence header. In the case of audio, the presentation timestamp shall be present in the PES packet containing the first + // byte of the audio frame. In the PCR_PID the random_access_indicator may only be set to '1' in Transport Stream packet + // containing the PCR fields. int8_t random_access_indicator; //1bit - /** - * The elementary_stream_priority_indicator is a 1-bit field. It indicates, among - * packets with the same PID, the priority of the elementary stream data carried within the payload of this Transport Stream - * packet. A '1' indicates that the payload has a higher priority than the payloads of other Transport Stream packets. In the - * case of video, this field may be set to '1' only if the payload contains one or more bytes from an intra-coded slice. A - * value of '0' indicates that the payload has the same priority as all other packets which do not have this bit set to '1'. - */ + // The elementary_stream_priority_indicator is a 1-bit field. It indicates, among + // packets with the same PID, the priority of the elementary stream data carried within the payload of this Transport Stream + // packet. A '1' indicates that the payload has a higher priority than the payloads of other Transport Stream packets. In the + // case of video, this field may be set to '1' only if the payload contains one or more bytes from an intra-coded slice. A + // value of '0' indicates that the payload has the same priority as all other packets which do not have this bit set to '1'. int8_t elementary_stream_priority_indicator; //1bit - /** - * The PCR_flag is a 1-bit flag. A value of '1' indicates that the adaptation_field contains a PCR field coded in - * two parts. A value of '0' indicates that the adaptation field does not contain any PCR field. - */ + // The PCR_flag is a 1-bit flag. A value of '1' indicates that the adaptation_field contains a PCR field coded in + // two parts. A value of '0' indicates that the adaptation field does not contain any PCR field. int8_t PCR_flag; //1bit - /** - * The OPCR_flag is a 1-bit flag. A value of '1' indicates that the adaptation_field contains an OPCR field - * coded in two parts. A value of '0' indicates that the adaptation field does not contain any OPCR field. - */ + // The OPCR_flag is a 1-bit flag. A value of '1' indicates that the adaptation_field contains an OPCR field + // coded in two parts. A value of '0' indicates that the adaptation field does not contain any OPCR field. int8_t OPCR_flag; //1bit - /** - * The splicing_point_flag is a 1-bit flag. When set to '1', it indicates that a splice_countdown field - * shall be present in the associated adaptation field, specifying the occurrence of a splicing point. A value of '0' indicates - * that a splice_countdown field is not present in the adaptation field. - */ + // The splicing_point_flag is a 1-bit flag. When set to '1', it indicates that a splice_countdown field + // shall be present in the associated adaptation field, specifying the occurrence of a splicing point. A value of '0' indicates + // that a splice_countdown field is not present in the adaptation field. int8_t splicing_point_flag; //1bit - /** - * The transport_private_data_flag is a 1-bit flag. A value of '1' indicates that the - * adaptation field contains one or more private_data bytes. A value of '0' indicates the adaptation field does not contain any - * private_data bytes. - */ + // The transport_private_data_flag is a 1-bit flag. A value of '1' indicates that the + // adaptation field contains one or more private_data bytes. A value of '0' indicates the adaptation field does not contain any + // private_data bytes. int8_t transport_private_data_flag; //1bit - /** - * The adaptation_field_extension_flag is a 1-bit field which when set to '1' indicates - * the presence of an adaptation field extension. A value of '0' indicates that an adaptation field extension is not present in - * the adaptation field. - */ + // The adaptation_field_extension_flag is a 1-bit field which when set to '1' indicates + // the presence of an adaptation field extension. A value of '0' indicates that an adaptation field extension is not present in + // the adaptation field. int8_t adaptation_field_extension_flag; //1bit - // if PCR_flag, 6B - /** - * The program_clock_reference (PCR) is a - * 42-bit field coded in two parts. The first part, program_clock_reference_base, is a 33-bit field whose value is given by - * PCR_base(i), as given in equation 2-2. The second part, program_clock_reference_extension, is a 9-bit field whose value - * is given by PCR_ext(i), as given in equation 2-3. The PCR indicates the intended time of arrival of the byte containing - * the last bit of the program_clock_reference_base at the input of the system target decoder. - */ + // If PCR_flag, 6B + // The program_clock_reference (PCR) is a + // 42-bit field coded in two parts. The first part, program_clock_reference_base, is a 33-bit field whose value is given by + // PCR_base(i), as given in equation 2-2. The second part, program_clock_reference_extension, is a 9-bit field whose value + // is given by PCR_ext(i), as given in equation 2-3. The PCR indicates the intended time of arrival of the byte containing + // the last bit of the program_clock_reference_base at the input of the system target decoder. int64_t program_clock_reference_base; //33bits - /** - * 6bits reserved, must be '1' - */ + // 6bits reserved, must be '1' int8_t const1_value0; // 6bits int16_t program_clock_reference_extension; //9bits - // if OPCR_flag, 6B - /** - * The optional original - * program reference (OPCR) is a 42-bit field coded in two parts. These two parts, the base and the extension, are coded - * identically to the two corresponding parts of the PCR field. The presence of the OPCR is indicated by the OPCR_flag. - * The OPCR field shall be coded only in Transport Stream packets in which the PCR field is present. OPCRs are permitted - * in both single program and multiple program Transport Streams. - * - * OPCR assists in the reconstruction of a single program Transport Stream from another Transport Stream. When - * reconstructing the original single program Transport Stream, the OPCR may be copied to the PCR field. The resulting - * PCR value is valid only if the original single program Transport Stream is reconstructed exactly in its entirety. This - * would include at least any PSI and private data packets which were present in the original Transport Stream and would - * possibly require other private arrangements. It also means that the OPCR must be an identical copy of its associated PCR - * in the original single program Transport Stream. - */ + // If OPCR_flag, 6B + // The optional original + // program reference (OPCR) is a 42-bit field coded in two parts. These two parts, the base and the extension, are coded + // identically to the two corresponding parts of the PCR field. The presence of the OPCR is indicated by the OPCR_flag. + // The OPCR field shall be coded only in Transport Stream packets in which the PCR field is present. OPCRs are permitted + // in both single program and multiple program Transport Streams. + // + // OPCR assists in the reconstruction of a single program Transport Stream from another Transport Stream. When + // reconstructing the original single program Transport Stream, the OPCR may be copied to the PCR field. The resulting + // PCR value is valid only if the original single program Transport Stream is reconstructed exactly in its entirety. This + // would include at least any PSI and private data packets which were present in the original Transport Stream and would + // possibly require other private arrangements. It also means that the OPCR must be an identical copy of its associated PCR + // in the original single program Transport Stream. int64_t original_program_clock_reference_base; //33bits - /** - * 6bits reserved, must be '1' - */ + // 6bits reserved, must be '1' int8_t const1_value2; // 6bits int16_t original_program_clock_reference_extension; //9bits - // if splicing_point_flag, 1B - /** - * The splice_countdown is an 8-bit field, representing a value which may be positive or negative. A - * positive value specifies the remaining number of Transport Stream packets, of the same PID, following the associated - * Transport Stream packet until a splicing point is reached. Duplicate Transport Stream packets and Transport Stream - * packets which only contain adaptation fields are excluded. The splicing point is located immediately after the last byte of - * the Transport Stream packet in which the associated splice_countdown field reaches zero. In the Transport Stream packet - * where the splice_countdown reaches zero, the last data byte of the Transport Stream packet payload shall be the last byte - * of a coded audio frame or a coded picture. In the case of video, the corresponding access unit may or may not be - * terminated by a sequence_end_code. Transport Stream packets with the same PID, which follow, may contain data from - * a different elementary stream of the same type. - * - * The payload of the next Transport Stream packet of the same PID (duplicate packets and packets without payload being - * excluded) shall commence with the first byte of a PES packet.In the case of audio, the PES packet payload shall - * commence with an access point. In the case of video, the PES packet payload shall commence with an access point, or - * with a sequence_end_code, followed by an access point. Thus, the previous coded audio frame or coded picture aligns - * with the packet boundary, or is padded to make this so. Subsequent to the splicing point, the countdown field may also - * be present. When the splice_countdown is a negative number whose value is minus n(-n), it indicates that the associated - * Transport Stream packet is the n-th packet following the splicing point (duplicate packets and packets without payload - * being excluded). - * - * For the purposes of this subclause, an access point is defined as follows: - * Video - The first byte of a video_sequence_header. - * Audio - The first byte of an audio frame. - */ + // If splicing_point_flag, 1B + // The splice_countdown is an 8-bit field, representing a value which may be positive or negative. A + // positive value specifies the remaining number of Transport Stream packets, of the same PID, following the associated + // Transport Stream packet until a splicing point is reached. Duplicate Transport Stream packets and Transport Stream + // packets which only contain adaptation fields are excluded. The splicing point is located immediately after the last byte of + // the Transport Stream packet in which the associated splice_countdown field reaches zero. In the Transport Stream packet + // where the splice_countdown reaches zero, the last data byte of the Transport Stream packet payload shall be the last byte + // of a coded audio frame or a coded picture. In the case of video, the corresponding access unit may or may not be + // terminated by a sequence_end_code. Transport Stream packets with the same PID, which follow, may contain data from + // a different elementary stream of the same type. + // + // The payload of the next Transport Stream packet of the same PID (duplicate packets and packets without payload being + // excluded) shall commence with the first byte of a PES packet.In the case of audio, the PES packet payload shall + // commence with an access point. In the case of video, the PES packet payload shall commence with an access point, or + // with a sequence_end_code, followed by an access point. Thus, the previous coded audio frame or coded picture aligns + // with the packet boundary, or is padded to make this so. Subsequent to the splicing point, the countdown field may also + // be present. When the splice_countdown is a negative number whose value is minus n(-n), it indicates that the associated + // Transport Stream packet is the n-th packet following the splicing point (duplicate packets and packets without payload + // being excluded). + // + // For the purposes of this subclause, an access point is defined as follows: + // Video - The first byte of a video_sequence_header. + // Audio - The first byte of an audio frame. int8_t splice_countdown; //8bits - // if transport_private_data_flag, 1+p[0] B + // If transport_private_data_flag, 1+p[0] B std::vector transport_private_data; //[transport_private_data_length]bytes - // if adaptation_field_extension_flag, 2+x B - /** - * The adaptation_field_extension_length is an 8-bit field. It indicates the number of - * bytes of the extended adaptation field data immediately following this field, including reserved bytes if present. - */ + // If adaptation_field_extension_flag, 2+x B + // The adaptation_field_extension_length is an 8-bit field. It indicates the number of + // bytes of the extended adaptation field data immediately following this field, including reserved bytes if present. uint8_t adaptation_field_extension_length; //8bits - /** - * This is a 1-bit field which when set to '1' indicates the presence of the ltw_offset - * field. - */ + // This is a 1-bit field which when set to '1' indicates the presence of the ltw_offset + // field. int8_t ltw_flag; //1bit - /** - * This is a 1-bit field which when set to '1' indicates the presence of the piecewise_rate field. - */ + // This is a 1-bit field which when set to '1' indicates the presence of the piecewise_rate field. int8_t piecewise_rate_flag; //1bit - /** - * This is a 1-bit flag which when set to '1' indicates that the splice_type and DTS_next_AU fields - * are present. A value of '0' indicates that neither splice_type nor DTS_next_AU fields are present. This field shall not be - * set to '1' in Transport Stream packets in which the splicing_point_flag is not set to '1'. Once it is set to '1' in a Transport - * Stream packet in which the splice_countdown is positive, it shall be set to '1' in all the subsequent Transport Stream - * packets of the same PID that have the splicing_point_flag set to '1', until the packet in which the splice_countdown - * reaches zero (including this packet). When this flag is set, if the elementary stream carried in this PID is an audio stream, - * the splice_type field shall be set to '0000'. If the elementary stream carried in this PID is a video stream, it shall fulfil the - * constraints indicated by the splice_type value. - */ + // This is a 1-bit flag which when set to '1' indicates that the splice_type and DTS_next_AU fields + // are present. A value of '0' indicates that neither splice_type nor DTS_next_AU fields are present. This field shall not be + // set to '1' in Transport Stream packets in which the splicing_point_flag is not set to '1'. Once it is set to '1' in a Transport + // Stream packet in which the splice_countdown is positive, it shall be set to '1' in all the subsequent Transport Stream + // packets of the same PID that have the splicing_point_flag set to '1', until the packet in which the splice_countdown + // reaches zero (including this packet). When this flag is set, if the elementary stream carried in this PID is an audio stream, + // the splice_type field shall be set to '0000'. If the elementary stream carried in this PID is a video stream, it shall fulfil the + // constraints indicated by the splice_type value. int8_t seamless_splice_flag; //1bit - /** - * reserved 5bits, must be '1' - */ + // reserved 5bits, must be '1' int8_t const1_value1; //5bits // if ltw_flag, 2B - /** - * (legal time window_valid_flag) - This is a 1-bit field which when set to '1' indicates that the value of the - * ltw_offset shall be valid. A value of '0' indicates that the value in the ltw_offset field is undefined. - */ + // (legal time window_valid_flag) - This is a 1-bit field which when set to '1' indicates that the value of the + // ltw_offset shall be valid. A value of '0' indicates that the value in the ltw_offset field is undefined. int8_t ltw_valid_flag; //1bit - /** - * (legal time window offset) - This is a 15-bit field, the value of which is defined only if the ltw_valid flag has - * a value of '1'. When defined, the legal time window offset is in units of (300/fs) seconds, where fs is the system clock - * frequency of the program that this PID belongs to, and fulfils: - * offset = t1(i) - t(i) - * ltw_offset = offset//1 - * where i is the index of the first byte of this Transport Stream packet, offset is the value encoded in this field, t(i) is the - * arrival time of byte i in the T-STD, and t1(i) is the upper bound in time of a time interval called the Legal Time Window - * which is associated with this Transport Stream packet. - */ + // (legal time window offset) - This is a 15-bit field, the value of which is defined only if the ltw_valid flag has + // a value of '1'. When defined, the legal time window offset is in units of (300/fs) seconds, where fs is the system clock + // frequency of the program that this PID belongs to, and fulfils: + // offset = t1(i) - t(i) + // ltw_offset = offset//1 + // where i is the index of the first byte of this Transport Stream packet, offset is the value encoded in this field, t(i) is the + // arrival time of byte i in the T-STD, and t1(i) is the upper bound in time of a time interval called the Legal Time Window + // which is associated with this Transport Stream packet. int16_t ltw_offset; //15bits // if piecewise_rate_flag, 3B //2bits reserved - /** - * The meaning of this 22-bit field is only defined when both the ltw_flag and the ltw_valid_flag are set - * to '1'. When defined, it is a positive integer specifying a hypothetical bitrate R which is used to define the end times of - * the Legal Time Windows of Transport Stream packets of the same PID that follow this packet but do not include the - * legal_time_window_offset field. - */ + // The meaning of this 22-bit field is only defined when both the ltw_flag and the ltw_valid_flag are set + // to '1'. When defined, it is a positive integer specifying a hypothetical bitrate R which is used to define the end times of + // the Legal Time Windows of Transport Stream packets of the same PID that follow this packet but do not include the + // legal_time_window_offset field. int32_t piecewise_rate; //22bits // if seamless_splice_flag, 5B - /** - * This is a 4-bit field. From the first occurrence of this field onwards, it shall have the same value in all the - * subsequent Transport Stream packets of the same PID in which it is present, until the packet in which the - * splice_countdown reaches zero (including this packet). If the elementary stream carried in that PID is an audio stream, - * this field shall have the value '0000'. If the elementary stream carried in that PID is a video stream, this field indicates the - * conditions that shall be respected by this elementary stream for splicing purposes. These conditions are defined as a - * function of profile, level and splice_type in Table 2-7 through Table 2-16. - */ + // This is a 4-bit field. From the first occurrence of this field onwards, it shall have the same value in all the + // subsequent Transport Stream packets of the same PID in which it is present, until the packet in which the + // splice_countdown reaches zero (including this packet). If the elementary stream carried in that PID is an audio stream, + // this field shall have the value '0000'. If the elementary stream carried in that PID is a video stream, this field indicates the + // conditions that shall be respected by this elementary stream for splicing purposes. These conditions are defined as a + // function of profile, level and splice_type in Table 2-7 through Table 2-16. int8_t splice_type; //4bits - /** - * (decoding time stamp next access unit) - This is a 33-bit field, coded in three parts. In the case of - * continuous and periodic decoding through this splicing point it indicates the decoding time of the first access unit - * following the splicing point. This decoding time is expressed in the time base which is valid in the Transport Stream - * packet in which the splice_countdown reaches zero. From the first occurrence of this field onwards, it shall have the - * same value in all the subsequent Transport Stream packets of the same PID in which it is present, until the packet in - * which the splice_countdown reaches zero (including this packet). - */ + // (decoding time stamp next access unit) - This is a 33-bit field, coded in three parts. In the case of + // continuous and periodic decoding through this splicing point it indicates the decoding time of the first access unit + // following the splicing point. This decoding time is expressed in the time base which is valid in the Transport Stream + // packet in which the splice_countdown reaches zero. From the first occurrence of this field onwards, it shall have the + // same value in all the subsequent Transport Stream packets of the same PID in which it is present, until the packet in + // which the splice_countdown reaches zero (including this packet). int8_t DTS_next_AU0; //3bits int8_t marker_bit0; //1bit int16_t DTS_next_AU1; //15bits @@ -816,17 +696,13 @@ public: int16_t DTS_next_AU2; //15bits int8_t marker_bit2; //1bit // left bytes. - /** - * This is a fixed 8-bit value equal to '1111 1111' that can be inserted by the encoder. It is discarded by the - * decoder. - */ + // This is a fixed 8-bit value equal to '1111 1111' that can be inserted by the encoder. It is discarded by the + // decoder. int nb_af_ext_reserved; // left bytes. - /** - * This is a fixed 8-bit value equal to '1111 1111' that can be inserted by the encoder. It is discarded by the - * decoder. - */ + // This is a fixed 8-bit value equal to '1111 1111' that can be inserted by the encoder. It is discarded by the + // decoder. int nb_af_reserved; private: SrsTsPacket* packet; @@ -840,10 +716,8 @@ public: virtual srs_error_t encode(SrsBuffer* stream); }; -/** - * 2.4.4.4 Table_id assignments, hls-mpeg-ts-iso13818-1.pdf, page 62 - * The table_id field identifies the contents of a Transport Stream PSI section as shown in Table 2-26. - */ +// 2.4.4.4 Table_id assignments, hls-mpeg-ts-iso13818-1.pdf, page 62 +// The table_id field identifies the contents of a Transport Stream PSI section as shown in Table 2-26. enum SrsTsPsiId { // program_association_section @@ -871,9 +745,7 @@ enum SrsTsPsiId SrsTsPsiIdForbidden = 0xFF, }; -/** - * the payload of ts packet, can be PES or PSI payload. - */ +// The payload of ts packet, can be PES or PSI payload. class SrsTsPayload { protected: @@ -888,131 +760,93 @@ public: virtual srs_error_t encode(SrsBuffer* stream) = 0; }; -/** - * the PES payload of ts packet. - * 2.4.3.6 PES packet, hls-mpeg-ts-iso13818-1.pdf, page 49 - */ +// The PES payload of ts packet. +// 2.4.3.6 PES packet, hls-mpeg-ts-iso13818-1.pdf, page 49 class SrsTsPayloadPES : public SrsTsPayload { public: // 3B - /** - * The packet_start_code_prefix is a 24-bit code. Together with the stream_id that follows it - * constitutes a packet start code that identifies the beginning of a packet. The packet_start_code_prefix is the bit string - * '0000 0000 0000 0000 0000 0001' (0x000001). - */ + // The packet_start_code_prefix is a 24-bit code. Together with the stream_id that follows it + // constitutes a packet start code that identifies the beginning of a packet. The packet_start_code_prefix is the bit string + // '0000 0000 0000 0000 0000 0001' (0x000001). int32_t packet_start_code_prefix; //24bits // 1B - /** - * In Program Streams, the stream_id specifies the type and number of the elementary stream as defined by the - * stream_id Table 2-18. In Transport Streams, the stream_id may be set to any valid value which correctly describes the - * elementary stream type as defined in Table 2-18. In Transport Streams, the elementary stream type is specified in the - * Program Specific Information as specified in 2.4.4. - */ + // In Program Streams, the stream_id specifies the type and number of the elementary stream as defined by the + // stream_id Table 2-18. In Transport Streams, the stream_id may be set to any valid value which correctly describes the + // elementary stream type as defined in Table 2-18. In Transport Streams, the elementary stream type is specified in the + // Program Specific Information as specified in 2.4.4. // @see SrsTsPESStreamId, value can be SrsTsPESStreamIdAudioCommon or SrsTsPESStreamIdVideoCommon. uint8_t stream_id; //8bits // 2B - /** - * A 16-bit field specifying the number of bytes in the PES packet following the last byte of the - * field. A value of 0 indicates that the PES packet length is neither specified nor bounded and is allowed only in - * PES packets whose payload consists of bytes from a video elementary stream contained in Transport Stream packets. - */ + // A 16-bit field specifying the number of bytes in the PES packet following the last byte of the + // field. A value of 0 indicates that the PES packet length is neither specified nor bounded and is allowed only in + // PES packets whose payload consists of bytes from a video elementary stream contained in Transport Stream packets. uint16_t PES_packet_length; //16bits // 1B - /** - * 2bits const '10' - */ + // 2bits const '10' int8_t const2bits; //2bits - /** - * The 2-bit PES_scrambling_control field indicates the scrambling mode of the PES packet - * payload. When scrambling is performed at the PES level, the PES packet header, including the optional fields when - * present, shall not be scrambled (see Table 2-19). - */ + // The 2-bit PES_scrambling_control field indicates the scrambling mode of the PES packet + // payload. When scrambling is performed at the PES level, the PES packet header, including the optional fields when + // present, shall not be scrambled (see Table 2-19). int8_t PES_scrambling_control; //2bits - /** - * This is a 1-bit field indicating the priority of the payload in this PES packet. A '1' indicates a higher - * priority of the payload of the PES packet payload than a PES packet payload with this field set to '0'. A multiplexor can - * use the PES_priority bit to prioritize its data within an elementary stream. This field shall not be changed by the transport - * mechanism. - */ + // This is a 1-bit field indicating the priority of the payload in this PES packet. A '1' indicates a higher + // priority of the payload of the PES packet payload than a PES packet payload with this field set to '0'. A multiplexor can + // use the PES_priority bit to prioritize its data within an elementary stream. This field shall not be changed by the transport + // mechanism. int8_t PES_priority; //1bit - /** - * This is a 1-bit flag. When set to a value of '1' it indicates that the PES packet header is - * immediately followed by the video start code or audio syncword indicated in the data_stream_alignment_descriptor - * in 2.6.10 if this descriptor is present. If set to a value of '1' and the descriptor is not present, alignment as indicated in - * alignment_type '01' in Table 2-47 and Table 2-48 is required. When set to a value of '0' it is not defined whether any such - * alignment occurs or not. - */ + // This is a 1-bit flag. When set to a value of '1' it indicates that the PES packet header is + // immediately followed by the video start code or audio syncword indicated in the data_stream_alignment_descriptor + // in 2.6.10 if this descriptor is present. If set to a value of '1' and the descriptor is not present, alignment as indicated in + // alignment_type '01' in Table 2-47 and Table 2-48 is required. When set to a value of '0' it is not defined whether any such + // alignment occurs or not. int8_t data_alignment_indicator; //1bit - /** - * This is a 1-bit field. When set to '1' it indicates that the material of the associated PES packet payload is - * protected by copyright. When set to '0' it is not defined whether the material is protected by copyright. A copyright - * descriptor described in 2.6.24 is associated with the elementary stream which contains this PES packet and the copyright - * flag is set to '1' if the descriptor applies to the material contained in this PES packet - */ + // This is a 1-bit field. When set to '1' it indicates that the material of the associated PES packet payload is + // protected by copyright. When set to '0' it is not defined whether the material is protected by copyright. A copyright + // descriptor described in 2.6.24 is associated with the elementary stream which contains this PES packet and the copyright + // flag is set to '1' if the descriptor applies to the material contained in this PES packet int8_t copyright; //1bit - /** - * This is a 1-bit field. When set to '1' the contents of the associated PES packet payload is an original. - * When set to '0' it indicates that the contents of the associated PES packet payload is a copy. - */ + // This is a 1-bit field. When set to '1' the contents of the associated PES packet payload is an original. + // When set to '0' it indicates that the contents of the associated PES packet payload is a copy. int8_t original_or_copy; //1bit // 1B - /** - * This is a 2-bit field. When the PTS_DTS_flags field is set to '10', the PTS fields shall be present in - * the PES packet header. When the PTS_DTS_flags field is set to '11', both the PTS fields and DTS fields shall be present - * in the PES packet header. When the PTS_DTS_flags field is set to '00' no PTS or DTS fields shall be present in the PES - * packet header. The value '01' is forbidden. - */ + // This is a 2-bit field. When the PTS_DTS_flags field is set to '10', the PTS fields shall be present in + // the PES packet header. When the PTS_DTS_flags field is set to '11', both the PTS fields and DTS fields shall be present + // in the PES packet header. When the PTS_DTS_flags field is set to '00' no PTS or DTS fields shall be present in the PES + // packet header. The value '01' is forbidden. int8_t PTS_DTS_flags; //2bits - /** - * A 1-bit flag, which when set to '1' indicates that ESCR base and extension fields are present in the PES - * packet header. When set to '0' it indicates that no ESCR fields are present. - */ + // A 1-bit flag, which when set to '1' indicates that ESCR base and extension fields are present in the PES + // packet header. When set to '0' it indicates that no ESCR fields are present. int8_t ESCR_flag; //1bit - /** - * A 1-bit flag, which when set to '1' indicates that the ES_rate field is present in the PES packet header. - * When set to '0' it indicates that no ES_rate field is present. - */ + // A 1-bit flag, which when set to '1' indicates that the ES_rate field is present in the PES packet header. + // When set to '0' it indicates that no ES_rate field is present. int8_t ES_rate_flag; //1bit - /** - * A 1-bit flag, which when set to '1' it indicates the presence of an 8-bit trick mode field. When - * set to '0' it indicates that this field is not present. - */ + // A 1-bit flag, which when set to '1' it indicates the presence of an 8-bit trick mode field. When + // set to '0' it indicates that this field is not present. int8_t DSM_trick_mode_flag; //1bit - /** - * A 1-bit flag, which when set to '1' indicates the presence of the additional_copy_info field. - * When set to '0' it indicates that this field is not present. - */ + // A 1-bit flag, which when set to '1' indicates the presence of the additional_copy_info field. + // When set to '0' it indicates that this field is not present. int8_t additional_copy_info_flag; //1bit - /** - * A 1-bit flag, which when set to '1' indicates that a CRC field is present in the PES packet. When set to - * '0' it indicates that this field is not present. - */ + // A 1-bit flag, which when set to '1' indicates that a CRC field is present in the PES packet. When set to + // '0' it indicates that this field is not present. int8_t PES_CRC_flag; //1bit - /** - * A 1-bit flag, which when set to '1' indicates that an extension field exists in this PES packet - * header. When set to '0' it indicates that this field is not present. - */ + // A 1-bit flag, which when set to '1' indicates that an extension field exists in this PES packet + // header. When set to '0' it indicates that this field is not present. int8_t PES_extension_flag; //1bit // 1B - /** - * An 8-bit field specifying the total number of bytes occupied by the optional fields and any - * stuffing bytes contained in this PES packet header. The presence of optional fields is indicated in the byte that precedes - * the PES_header_data_length field. - */ + // An 8-bit field specifying the total number of bytes occupied by the optional fields and any + // stuffing bytes contained in this PES packet header. The presence of optional fields is indicated in the byte that precedes + // the PES_header_data_length field. uint8_t PES_header_data_length; //8bits // 5B - /** - * Presentation times shall be related to decoding times as follows: The PTS is a 33-bit - * number coded in three separate fields. It indicates the time of presentation, tp n (k), in the system target decoder of a - * presentation unit k of elementary stream n. The value of PTS is specified in units of the period of the system clock - * frequency divided by 300 (yielding 90 kHz). The presentation time is derived from the PTS according to equation 2-11 - * below. Refer to 2.7.4 for constraints on the frequency of coding presentation timestamps. - */ + // Presentation times shall be related to decoding times as follows: The PTS is a 33-bit + // number coded in three separate fields. It indicates the time of presentation, tp n (k), in the system target decoder of a + // presentation unit k of elementary stream n. The value of PTS is specified in units of the period of the system clock + // frequency divided by 300 (yielding 90 kHz). The presentation time is derived from the PTS according to equation 2-11 + // below. Refer to 2.7.4 for constraints on the frequency of coding presentation timestamps. // ===========1B // 4bits const // 3bits PTS [32..30] @@ -1026,11 +860,9 @@ public: int64_t pts; // 33bits // 5B - /** - * The DTS is a 33-bit number coded in three separate fields. It indicates the decoding time, - * td n (j), in the system target decoder of an access unit j of elementary stream n. The value of DTS is specified in units of - * the period of the system clock frequency divided by 300 (yielding 90 kHz). - */ + // The DTS is a 33-bit number coded in three separate fields. It indicates the decoding time, + // td n (j), in the system target decoder of an access unit j of elementary stream n. The value of DTS is specified in units of + // the period of the system clock frequency divided by 300 (yielding 90 kHz). // ===========1B // 4bits const // 3bits DTS [32..30] @@ -1044,13 +876,11 @@ public: int64_t dts; // 33bits // 6B - /** - * The elementary stream clock reference is a 42-bit field coded in two parts. The first - * part, ESCR_base, is a 33-bit field whose value is given by ESCR_base(i), as given in equation 2-14. The second part, - * ESCR_ext, is a 9-bit field whose value is given by ESCR_ext(i), as given in equation 2-15. The ESCR field indicates the - * intended time of arrival of the byte containing the last bit of the ESCR_base at the input of the PES-STD for PES streams - * (refer to 2.5.2.4). - */ + // The elementary stream clock reference is a 42-bit field coded in two parts. The first + // part, ESCR_base, is a 33-bit field whose value is given by ESCR_base(i), as given in equation 2-14. The second part, + // ESCR_ext, is a 9-bit field whose value is given by ESCR_ext(i), as given in equation 2-15. The ESCR field indicates the + // intended time of arrival of the byte containing the last bit of the ESCR_base at the input of the PES-STD for PES streams + // (refer to 2.5.2.4). // 2bits reserved // 3bits ESCR_base[32..30] // 1bit const '1' @@ -1064,83 +894,61 @@ public: int16_t ESCR_extension; //9bits // 3B - /** - * The ES_rate field is a 22-bit unsigned integer specifying the rate at which the - * system target decoder receives bytes of the PES packet in the case of a PES stream. The ES_rate is valid in the PES - * packet in which it is included and in subsequent PES packets of the same PES stream until a new ES_rate field is - * encountered. The value of the ES_rate is measured in units of 50 bytes/second. The value 0 is forbidden. The value of the - * ES_rate is used to define the time of arrival of bytes at the input of a P-STD for PES streams defined in 2.5.2.4. The - * value encoded in the ES_rate field may vary from PES_packet to PES_packet. - */ + // The ES_rate field is a 22-bit unsigned integer specifying the rate at which the + // system target decoder receives bytes of the PES packet in the case of a PES stream. The ES_rate is valid in the PES + // packet in which it is included and in subsequent PES packets of the same PES stream until a new ES_rate field is + // encountered. The value of the ES_rate is measured in units of 50 bytes/second. The value 0 is forbidden. The value of the + // ES_rate is used to define the time of arrival of bytes at the input of a P-STD for PES streams defined in 2.5.2.4. The + // value encoded in the ES_rate field may vary from PES_packet to PES_packet. // 1bit const '1' // 22bits ES_rate // 1bit const '1' int32_t ES_rate; //22bits // 1B - /** - * A 3-bit field that indicates which trick mode is applied to the associated video stream. In cases of - * other types of elementary streams, the meanings of this field and those defined by the following five bits are undefined. - * For the definition of trick_mode status, refer to the trick mode section of 2.4.2.3. - */ + // A 3-bit field that indicates which trick mode is applied to the associated video stream. In cases of + // other types of elementary streams, the meanings of this field and those defined by the following five bits are undefined. + // For the definition of trick_mode status, refer to the trick mode section of 2.4.2.3. int8_t trick_mode_control; //3bits int8_t trick_mode_value; //5bits // 1B // 1bit const '1' - /** - * This 7-bit field contains private data relating to copyright information. - */ + // This 7-bit field contains private data relating to copyright information. int8_t additional_copy_info; //7bits // 2B - /** - * The previous_PES_packet_CRC is a 16-bit field that contains the CRC value that yields - * a zero output of the 16 registers in the decoder similar to the one defined in Annex A, - */ + // The previous_PES_packet_CRC is a 16-bit field that contains the CRC value that yields + // a zero output of the 16 registers in the decoder similar to the one defined in Annex A, int16_t previous_PES_packet_CRC; //16bits // 1B - /** - * A 1-bit flag which when set to '1' indicates that the PES packet header contains private data. - * When set to a value of '0' it indicates that private data is not present in the PES header. - */ + // A 1-bit flag which when set to '1' indicates that the PES packet header contains private data. + // When set to a value of '0' it indicates that private data is not present in the PES header. int8_t PES_private_data_flag; //1bit - /** - * A 1-bit flag which when set to '1' indicates that an ISO/IEC 11172-1 pack header or a - * Program Stream pack header is stored in this PES packet header. If this field is in a PES packet that is contained in a - * Program Stream, then this field shall be set to '0'. In a Transport Stream, when set to the value '0' it indicates that no pack - * header is present in the PES header. - */ + // A 1-bit flag which when set to '1' indicates that an ISO/IEC 11172-1 pack header or a + // Program Stream pack header is stored in this PES packet header. If this field is in a PES packet that is contained in a + // Program Stream, then this field shall be set to '0'. In a Transport Stream, when set to the value '0' it indicates that no pack + // header is present in the PES header. int8_t pack_header_field_flag; //1bit - /** - * A 1-bit flag which when set to '1' indicates that the - * program_packet_sequence_counter, MPEG1_MPEG2_identifier, and original_stuff_length fields are present in this - * PES packet. When set to a value of '0' it indicates that these fields are not present in the PES header. - */ + // A 1-bit flag which when set to '1' indicates that the + // program_packet_sequence_counter, MPEG1_MPEG2_identifier, and original_stuff_length fields are present in this + // PES packet. When set to a value of '0' it indicates that these fields are not present in the PES header. int8_t program_packet_sequence_counter_flag; //1bit - /** - * A 1-bit flag which when set to '1' indicates that the P-STD_buffer_scale and P-STD_buffer_size - * are present in the PES packet header. When set to a value of '0' it indicates that these fields are not present in the - * PES header. - */ + // A 1-bit flag which when set to '1' indicates that the P-STD_buffer_scale and P-STD_buffer_size + // are present in the PES packet header. When set to a value of '0' it indicates that these fields are not present in the + // PES header. int8_t P_STD_buffer_flag; //1bit - /** - * reverved value, must be '1' - */ + // reverved value, must be '1' int8_t const1_value0; //3bits - /** - * A 1-bit field which when set to '1' indicates the presence of the PES_extension_field_length - * field and associated fields. When set to a value of '0' this indicates that the PES_extension_field_length field and any - * associated fields are not present. - */ + // A 1-bit field which when set to '1' indicates the presence of the PES_extension_field_length + // field and associated fields. When set to a value of '0' this indicates that the PES_extension_field_length field and any + // associated fields are not present. int8_t PES_extension_flag_2; //1bit // 16B - /** - * This is a 16-byte field which contains private data. This data, combined with the fields before and - * after, shall not emulate the packet_start_code_prefix (0x000001). - */ + // This is a 16-byte field which contains private data. This data, combined with the fields before and + // after, shall not emulate the packet_start_code_prefix (0x000001). std::vector PES_private_data; //128bits // (1+x)B @@ -1148,44 +956,34 @@ public: // 2B // 1bit const '1' - /** - * The program_packet_sequence_counter field is a 7-bit field. It is an optional - * counter that increments with each successive PES packet from a Program Stream or from an ISO/IEC 11172-1 Stream or - * the PES packets associated with a single program definition in a Transport Stream, providing functionality similar to a - * continuity counter (refer to 2.4.3.2). This allows an application to retrieve the original PES packet sequence of a Program - * Stream or the original packet sequence of the original ISO/IEC 11172-1 stream. The counter will wrap around to 0 after - * its maximum value. Repetition of PES packets shall not occur. Consequently, no two consecutive PES packets in the - * program multiplex shall have identical program_packet_sequence_counter values. - */ + // The program_packet_sequence_counter field is a 7-bit field. It is an optional + // counter that increments with each successive PES packet from a Program Stream or from an ISO/IEC 11172-1 Stream or + // the PES packets associated with a single program definition in a Transport Stream, providing functionality similar to a + // continuity counter (refer to 2.4.3.2). This allows an application to retrieve the original PES packet sequence of a Program + // Stream or the original packet sequence of the original ISO/IEC 11172-1 stream. The counter will wrap around to 0 after + // its maximum value. Repetition of PES packets shall not occur. Consequently, no two consecutive PES packets in the + // program multiplex shall have identical program_packet_sequence_counter values. int8_t program_packet_sequence_counter; //7bits // 1bit const '1' - /** - * A 1-bit flag which when set to '1' indicates that this PES packet carries information from - * an ISO/IEC 11172-1 stream. When set to '0' it indicates that this PES packet carries information from a Program Stream. - */ + // A 1-bit flag which when set to '1' indicates that this PES packet carries information from + // an ISO/IEC 11172-1 stream. When set to '0' it indicates that this PES packet carries information from a Program Stream. int8_t MPEG1_MPEG2_identifier; //1bit - /** - * This 6-bit field specifies the number of stuffing bytes used in the original ITU-T - * Rec. H.222.0 | ISO/IEC 13818-1 PES packet header or in the original ISO/IEC 11172-1 packet header. - */ + // This 6-bit field specifies the number of stuffing bytes used in the original ITU-T + // Rec. H.222.0 | ISO/IEC 13818-1 PES packet header or in the original ISO/IEC 11172-1 packet header. int8_t original_stuff_length; //6bits // 2B // 2bits const '01' - /** - * The P-STD_buffer_scale is a 1-bit field, the meaning of which is only defined if this PES packet - * is contained in a Program Stream. It indicates the scaling factor used to interpret the subsequent P-STD_buffer_size field. - * If the preceding stream_id indicates an audio stream, P-STD_buffer_scale shall have the value '0'. If the preceding - * stream_id indicates a video stream, P-STD_buffer_scale shall have the value '1'. For all other stream types, the value - * may be either '1' or '0'. - */ + // The P-STD_buffer_scale is a 1-bit field, the meaning of which is only defined if this PES packet + // is contained in a Program Stream. It indicates the scaling factor used to interpret the subsequent P-STD_buffer_size field. + // If the preceding stream_id indicates an audio stream, P-STD_buffer_scale shall have the value '0'. If the preceding + // stream_id indicates a video stream, P-STD_buffer_scale shall have the value '1'. For all other stream types, the value + // may be either '1' or '0'. int8_t P_STD_buffer_scale; //1bit - /** - * The P-STD_buffer_size is a 13-bit unsigned integer, the meaning of which is only defined if this - * PES packet is contained in a Program Stream. It defines the size of the input buffer, BS n , in the P-STD. If - * P-STD_buffer_scale has the value '0', then the P-STD_buffer_size measures the buffer size in units of 128 bytes. If - * P-STD_buffer_scale has the value '1', then the P-STD_buffer_size measures the buffer size in units of 1024 bytes. - */ + // The P-STD_buffer_size is a 13-bit unsigned integer, the meaning of which is only defined if this + // PES packet is contained in a Program Stream. It defines the size of the input buffer, BS n , in the P-STD. If + // P-STD_buffer_scale has the value '0', then the P-STD_buffer_size measures the buffer size in units of 128 bytes. If + // P-STD_buffer_scale has the value '1', then the P-STD_buffer_size measures the buffer size in units of 1024 bytes. int16_t P_STD_buffer_size; //13bits // (1+x)B @@ -1193,32 +991,26 @@ public: std::vector PES_extension_field; //[PES_extension_field_length] bytes // NB - /** - * This is a fixed 8-bit value equal to '1111 1111' that can be inserted by the encoder, for example to meet - * the requirements of the channel. It is discarded by the decoder. No more than 32 stuffing bytes shall be present in one - * PES packet header. - */ + // This is a fixed 8-bit value equal to '1111 1111' that can be inserted by the encoder, for example to meet + // the requirements of the channel. It is discarded by the decoder. No more than 32 stuffing bytes shall be present in one + // PES packet header. int nb_stuffings; // NB - /** - * PES_packet_data_bytes shall be contiguous bytes of data from the elementary stream - * indicated by the packet's stream_id or PID. When the elementary stream data conforms to ITU-T - * Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 13818-3, the PES_packet_data_bytes shall be byte aligned to the bytes of this - * Recommendation | International Standard. The byte-order of the elementary stream shall be preserved. The number of - * PES_packet_data_bytes, N, is specified by the PES_packet_length field. N shall be equal to the value indicated in the - * PES_packet_length minus the number of bytes between the last byte of the PES_packet_length field and the first - * PES_packet_data_byte. - * - * In the case of a private_stream_1, private_stream_2, ECM_stream, or EMM_stream, the contents of the - * PES_packet_data_byte field are user definable and will not be specified by ITU-T | ISO/IEC in the future. - */ + // PES_packet_data_bytes shall be contiguous bytes of data from the elementary stream + // indicated by the packet's stream_id or PID. When the elementary stream data conforms to ITU-T + // Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 13818-3, the PES_packet_data_bytes shall be byte aligned to the bytes of this + // Recommendation | International Standard. The byte-order of the elementary stream shall be preserved. The number of + // PES_packet_data_bytes, N, is specified by the PES_packet_length field. N shall be equal to the value indicated in the + // PES_packet_length minus the number of bytes between the last byte of the PES_packet_length field and the first + // PES_packet_data_byte. + // + // In the case of a private_stream_1, private_stream_2, ECM_stream, or EMM_stream, the contents of the + // PES_packet_data_byte field are user definable and will not be specified by ITU-T | ISO/IEC in the future. int nb_bytes; // NB - /** - * This is a fixed 8-bit value equal to '1111 1111'. It is discarded by the decoder. - */ + // This is a fixed 8-bit value equal to '1111 1111'. It is discarded by the decoder. int nb_paddings; public: SrsTsPayloadPES(SrsTsPacket* p); @@ -1233,59 +1025,43 @@ private: virtual srs_error_t encode_33bits_dts_pts(SrsBuffer* stream, uint8_t fb, int64_t v); }; -/** - * the PSI payload of ts packet. - * 2.4.4 Program specific information, hls-mpeg-ts-iso13818-1.pdf, page 59 - */ +// The PSI payload of ts packet. +// 2.4.4 Program specific information, hls-mpeg-ts-iso13818-1.pdf, page 59 class SrsTsPayloadPSI : public SrsTsPayload { public: // 1B - /** - * This is an 8-bit field whose value shall be the number of bytes, immediately following the pointer_field - * until the first byte of the first section that is present in the payload of the Transport Stream packet (so a value of 0x00 in - * the pointer_field indicates that the section starts immediately after the pointer_field). When at least one section begins in - * a given Transport Stream packet, then the payload_unit_start_indicator (refer to 2.4.3.2) shall be set to 1 and the first - * byte of the payload of that Transport Stream packet shall contain the pointer. When no section begins in a given - * Transport Stream packet, then the payload_unit_start_indicator shall be set to 0 and no pointer shall be sent in the - * payload of that packet. - */ + // This is an 8-bit field whose value shall be the number of bytes, immediately following the pointer_field + // until the first byte of the first section that is present in the payload of the Transport Stream packet (so a value of 0x00 in + // The pointer_field indicates that the section starts immediately after the pointer_field). When at least one section begins in + // a given Transport Stream packet, then the payload_unit_start_indicator (refer to 2.4.3.2) shall be set to 1 and the first + // byte of the payload of that Transport Stream packet shall contain the pointer. When no section begins in a given + // Transport Stream packet, then the payload_unit_start_indicator shall be set to 0 and no pointer shall be sent in the + // payload of that packet. int8_t pointer_field; public: // 1B - /** - * This is an 8-bit field, which shall be set to 0x00 as shown in Table 2-26. - */ + // This is an 8-bit field, which shall be set to 0x00 as shown in Table 2-26. SrsTsPsiId table_id; //8bits // 2B - /** - * The section_syntax_indicator is a 1-bit field which shall be set to '1'. - */ + // The section_syntax_indicator is a 1-bit field which shall be set to '1'. int8_t section_syntax_indicator; //1bit - /** - * const value, must be '0' - */ + // const value, must be '0' int8_t const0_value; //1bit - /** - * reverved value, must be '1' - */ + // reverved value, must be '1' int8_t const1_value; //2bits - /** - * This is a 12-bit field, the first two bits of which shall be '00'. The remaining 10 bits specify the number - * of bytes of the section, starting immediately following the section_length field, and including the CRC. The value in this - * field shall not exceed 1021 (0x3FD). - */ + // This is a 12-bit field, the first two bits of which shall be '00'. The remaining 10 bits specify the number + // of bytes of the section, starting immediately following the section_length field, and including the CRC. The value in this + // field shall not exceed 1021 (0x3FD). uint16_t section_length; //12bits public: // the specified psi info, for example, PAT fields. public: // 4B - /** - * This is a 32-bit field that contains the CRC value that gives a zero output of the registers in the decoder - * defined in Annex A after processing the entire section. - * @remark crc32(bytes without pointer field, before crc32 field) - */ + // This is a 32-bit field that contains the CRC value that gives a zero output of the registers in the decoder + // defined in Annex A after processing the entire section. + // @remark crc32(bytes without pointer field, before crc32 field) int32_t CRC_32; //32bits public: SrsTsPayloadPSI(SrsTsPacket* p); @@ -1301,31 +1077,23 @@ protected: virtual srs_error_t psi_decode(SrsBuffer* stream) = 0; }; -/** - * the program of PAT of PSI ts packet. - */ +// The program of PAT of PSI ts packet. class SrsTsPayloadPATProgram { public: // 4B - /** - * Program_number is a 16-bit field. It specifies the program to which the program_map_PID is - * applicable. When set to 0x0000, then the following PID reference shall be the network PID. For all other cases the value - * of this field is user defined. This field shall not take any single value more than once within one version of the Program - * Association Table. - */ + // Program_number is a 16-bit field. It specifies the program to which the program_map_PID is + // applicable. When set to 0x0000, then the following PID reference shall be the network PID. For all other cases the value + // of this field is user defined. This field shall not take any single value more than once within one version of the Program + // Association Table. int16_t number; // 16bits - /** - * reverved value, must be '1' - */ + // reverved value, must be '1' int8_t const1_value; //3bits - /** - * program_map_PID/network_PID 13bits - * network_PID - The network_PID is a 13-bit field, which is used only in conjunction with the value of the - * program_number set to 0x0000, specifies the PID of the Transport Stream packets which shall contain the Network - * Information Table. The value of the network_PID field is defined by the user, but shall only take values as specified in - * Table 2-3. The presence of the network_PID is optional. - */ + // program_map_PID/network_PID 13bits + // network_PID - The network_PID is a 13-bit field, which is used only in conjunction with the value of the + // program_number set to 0x0000, specifies the PID of the Transport Stream packets which shall contain the Network + // Information Table. The value of the network_PID field is defined by the user, but shall only take values as specified in + // Table 2-3. The presence of the network_PID is optional. int16_t pid; //13bits public: SrsTsPayloadPATProgram(int16_t n = 0, int16_t p = 0); @@ -1337,56 +1105,42 @@ public: virtual srs_error_t encode(SrsBuffer* stream); }; -/** - * the PAT payload of PSI ts packet. - * 2.4.4.3 Program association Table, hls-mpeg-ts-iso13818-1.pdf, page 61 - * The Program Association Table provides the correspondence between a program_number and the PID value of the - * Transport Stream packets which carry the program definition. The program_number is the numeric label associated with - * a program. - */ +// The PAT payload of PSI ts packet. +// 2.4.4.3 Program association Table, hls-mpeg-ts-iso13818-1.pdf, page 61 +// The Program Association Table provides the correspondence between a program_number and the PID value of the +// Transport Stream packets which carry the program definition. The program_number is the numeric label associated with +// a program. class SrsTsPayloadPAT : public SrsTsPayloadPSI { public: // 2B - /** - * This is a 16-bit field which serves as a label to identify this Transport Stream from any other - * multiplex within a network. Its value is defined by the user. - */ + // This is a 16-bit field which serves as a label to identify this Transport Stream from any other + // multiplex within a network. Its value is defined by the user. uint16_t transport_stream_id; //16bits // 1B - /** - * reverved value, must be '1' - */ + // reverved value, must be '1' int8_t const3_value; //2bits - /** - * This 5-bit field is the version number of the whole Program Association Table. The version number - * shall be incremented by 1 modulo 32 whenever the definition of the Program Association Table changes. When the - * current_next_indicator is set to '1', then the version_number shall be that of the currently applicable Program Association - * Table. When the current_next_indicator is set to '0', then the version_number shall be that of the next applicable Program - * Association Table. - */ + // This 5-bit field is the version number of the whole Program Association Table. The version number + // shall be incremented by 1 modulo 32 whenever the definition of the Program Association Table changes. When the + // current_next_indicator is set to '1', then the version_number shall be that of the currently applicable Program Association + // Table. When the current_next_indicator is set to '0', then the version_number shall be that of the next applicable Program + // Association Table. int8_t version_number; //5bits - /** - * A 1-bit indicator, which when set to '1' indicates that the Program Association Table sent is - * currently applicable. When the bit is set to '0', it indicates that the table sent is not yet applicable and shall be the next - * table to become valid. - */ + // A 1-bit indicator, which when set to '1' indicates that the Program Association Table sent is + // currently applicable. When the bit is set to '0', it indicates that the table sent is not yet applicable and shall be the next + // table to become valid. int8_t current_next_indicator; //1bit // 1B - /** - * This 8-bit field gives the number of this section. The section_number of the first section in the - * Program Association Table shall be 0x00. It shall be incremented by 1 with each additional section in the Program - * Association Table. - */ + // This 8-bit field gives the number of this section. The section_number of the first section in the + // Program Association Table shall be 0x00. It shall be incremented by 1 with each additional section in the Program + // Association Table. uint8_t section_number; //8bits // 1B - /** - * This 8-bit field specifies the number of the last section (that is, the section with the highest - * section_number) of the complete Program Association Table. - */ + // This 8-bit field specifies the number of the last section (that is, the section with the highest + // section_number) of the complete Program Association Table. uint8_t last_section_number; //8bits // multiple 4B program data. @@ -1401,34 +1155,24 @@ protected: virtual srs_error_t psi_encode(SrsBuffer* stream); }; -/** - * the esinfo for PMT program. - */ +// The esinfo for PMT program. class SrsTsPayloadPMTESInfo { public: // 1B - /** - * This is an 8-bit field specifying the type of program element carried within the packets with the PID - * whose value is specified by the elementary_PID. The values of stream_type are specified in Table 2-29. - */ + // This is an 8-bit field specifying the type of program element carried within the packets with the PID + // whose value is specified by the elementary_PID. The values of stream_type are specified in Table 2-29. SrsTsStream stream_type; //8bits // 2B - /** - * reverved value, must be '1' - */ + // reverved value, must be '1' int8_t const1_value0; //3bits - /** - * This is a 13-bit field specifying the PID of the Transport Stream packets which carry the associated - * program element. - */ + // This is a 13-bit field specifying the PID of the Transport Stream packets which carry the associated + // program element. int16_t elementary_PID; //13bits // (2+x)B - /** - * reverved value, must be '1' - */ + // reverved value, must be '1' int8_t const1_value1; //4bits std::vector ES_info; //[ES_info_length] bytes. public: @@ -1441,82 +1185,62 @@ public: virtual srs_error_t encode(SrsBuffer* stream); }; -/** - * the PMT payload of PSI ts packet. - * 2.4.4.8 Program Map Table, hls-mpeg-ts-iso13818-1.pdf, page 64 - * The Program Map Table provides the mappings between program numbers and the program elements that comprise - * them. A single instance of such a mapping is referred to as a "program definition". The program map table is the - * complete collection of all program definitions for a Transport Stream. This table shall be transmitted in packets, the PID - * values of which are selected by the encoder. More than one PID value may be used, if desired. The table is contained in - * one or more sections with the following syntax. It may be segmented to occupy multiple sections. In each section, the - * section number field shall be set to zero. Sections are identified by the program_number field. - */ +// The PMT payload of PSI ts packet. +// 2.4.4.8 Program Map Table, hls-mpeg-ts-iso13818-1.pdf, page 64 +// The Program Map Table provides the mappings between program numbers and the program elements that comprise +// Them. A single instance of such a mapping is referred to as a "program definition". The program map table is the +// complete collection of all program definitions for a Transport Stream. This table shall be transmitted in packets, the PID +// values of which are selected by the encoder. More than one PID value may be used, if desired. The table is contained in +// one or more sections with the following syntax. It may be segmented to occupy multiple sections. In each section, the +// section number field shall be set to zero. Sections are identified by the program_number field. class SrsTsPayloadPMT : public SrsTsPayloadPSI { public: // 2B - /** - * program_number is a 16-bit field. It specifies the program to which the program_map_PID is - * applicable. One program definition shall be carried within only one TS_program_map_section. This implies that a - * program definition is never longer than 1016 (0x3F8). See Informative Annex C for ways to deal with the cases when - * that length is not sufficient. The program_number may be used as a designation for a broadcast channel, for example. By - * describing the different program elements belonging to a program, data from different sources (e.g. sequential events) - * can be concatenated together to form a continuous set of streams using a program_number. For examples of applications - * refer to Annex C. - */ + // program_number is a 16-bit field. It specifies the program to which the program_map_PID is + // applicable. One program definition shall be carried within only one TS_program_map_section. This implies that a + // program definition is never longer than 1016 (0x3F8). See Informative Annex C for ways to deal with the cases when + // that length is not sufficient. The program_number may be used as a designation for a broadcast channel, for example. By + // describing the different program elements belonging to a program, data from different sources (e.g. sequential events) + // can be concatenated together to form a continuous set of streams using a program_number. For examples of applications + // refer to Annex C. uint16_t program_number; //16bits // 1B - /** - * reverved value, must be '1' - */ + // reverved value, must be '1' int8_t const1_value0; //2bits - /** - * This 5-bit field is the version number of the TS_program_map_section. The version number shall be - * incremented by 1 modulo 32 when a change in the information carried within the section occurs. Version number refers - * to the definition of a single program, and therefore to a single section. When the current_next_indicator is set to '1', then - * the version_number shall be that of the currently applicable TS_program_map_section. When the current_next_indicator - * is set to '0', then the version_number shall be that of the next applicable TS_program_map_section. - */ + // This 5-bit field is the version number of the TS_program_map_section. The version number shall be + // incremented by 1 modulo 32 when a change in the information carried within the section occurs. Version number refers + // to the definition of a single program, and therefore to a single section. When the current_next_indicator is set to '1', then + // The version_number shall be that of the currently applicable TS_program_map_section. When the current_next_indicator + // is set to '0', then the version_number shall be that of the next applicable TS_program_map_section. int8_t version_number; //5bits - /** - * A 1-bit field, which when set to '1' indicates that the TS_program_map_section sent is - * currently applicable. When the bit is set to '0', it indicates that the TS_program_map_section sent is not yet applicable - * and shall be the next TS_program_map_section to become valid. - */ + // A 1-bit field, which when set to '1' indicates that the TS_program_map_section sent is + // currently applicable. When the bit is set to '0', it indicates that the TS_program_map_section sent is not yet applicable + // and shall be the next TS_program_map_section to become valid. int8_t current_next_indicator; //1bit // 1B - /** - * The value of this 8-bit field shall be 0x00. - */ + // The value of this 8-bit field shall be 0x00. uint8_t section_number; //8bits // 1B - /** - * The value of this 8-bit field shall be 0x00. - */ + // The value of this 8-bit field shall be 0x00. uint8_t last_section_number; //8bits // 2B - /** - * reverved value, must be '1' - */ + // reverved value, must be '1' int8_t const1_value1; //3bits - /** - * This is a 13-bit field indicating the PID of the Transport Stream packets which shall contain the PCR fields - * valid for the program specified by program_number. If no PCR is associated with a program definition for private - * streams, then this field shall take the value of 0x1FFF. Refer to the semantic definition of PCR in 2.4.3.5 and Table 2-3 - * for restrictions on the choice of PCR_PID value. - */ + // This is a 13-bit field indicating the PID of the Transport Stream packets which shall contain the PCR fields + // valid for the program specified by program_number. If no PCR is associated with a program definition for private + // streams, then this field shall take the value of 0x1FFF. Refer to the semantic definition of PCR in 2.4.3.5 and Table 2-3 + // for restrictions on the choice of PCR_PID value. int16_t PCR_PID; //13bits // 2B int8_t const1_value2; //4bits - /** - * This is a 12-bit field, the first two bits of which shall be '00'. The remaining 10 bits specify the - * number of bytes of the descriptors immediately following the program_info_length field. - */ + // This is a 12-bit field, the first two bits of which shall be '00'. The remaining 10 bits specify the + // number of bytes of the descriptors immediately following the program_info_length field. std::vector program_info_desc; //[program_info_length]bytes // array of TSPMTESInfo. @@ -1531,9 +1255,7 @@ protected: virtual srs_error_t psi_encode(SrsBuffer* stream); }; -/** - * Write the TS message to TS context. - */ +// Write the TS message to TS context. class SrsTsContextWriter { private: @@ -1549,24 +1271,16 @@ public: SrsTsContextWriter(ISrsStreamWriter* w, SrsTsContext* c, SrsAudioCodecId ac, SrsVideoCodecId vc); virtual ~SrsTsContextWriter(); public: - /** - * write an audio frame to ts, - */ + // Write an audio frame to ts, virtual srs_error_t write_audio(SrsTsMessage* audio); - /** - * write a video frame to ts, - */ + // Write a video frame to ts, virtual srs_error_t write_video(SrsTsMessage* video); public: - /** - * get the video codec of ts muxer. - */ + // get the video codec of ts muxer. virtual SrsVideoCodecId video_codec(); }; -/* - * Used for HLS Encryption - */ +// Used for HLS Encryption class SrsEncFileWriter: public SrsFileWriter { public: @@ -1585,27 +1299,21 @@ private: int nb_buf; }; -/** - * TS messages cache, to group frames to TS message, - * for example, we may write multiple AAC RAW frames to a TS message. - */ +// TS messages cache, to group frames to TS message, +// for example, we may write multiple AAC RAW frames to a TS message. class SrsTsMessageCache { public: - // current ts message. + // The current ts message. SrsTsMessage* audio; SrsTsMessage* video; public: SrsTsMessageCache(); virtual ~SrsTsMessageCache(); public: - /** - * write audio to cache - */ + // Write audio to cache virtual srs_error_t cache_audio(SrsAudioFrame* frame, int64_t dts); - /** - * write video to muxer. - */ + // Write video to muxer. virtual srs_error_t cache_video(SrsVideoFrame* frame, int64_t dts); private: virtual srs_error_t do_cache_mp3(SrsAudioFrame* frame); @@ -1613,9 +1321,7 @@ private: virtual srs_error_t do_cache_avc(SrsVideoFrame* frame); }; -/** - * Transmux the RTMP stream to HTTP-TS stream. - */ +// Transmux the RTMP stream to HTTP-TS stream. class SrsTsTransmuxer { private: @@ -1629,16 +1335,12 @@ public: SrsTsTransmuxer(); virtual ~SrsTsTransmuxer(); public: - /** - * initialize the underlayer file stream. - * @param fw the writer to use for ts encoder, user must free it. - */ + // Initialize the underlayer file stream. + // @param fw the writer to use for ts encoder, user must free it. virtual srs_error_t initialize(ISrsStreamWriter* fw); public: - /** - * write audio/video packet. - * @remark assert data is not NULL. - */ + // Write audio/video packet. + // @remark assert data is not NULL. virtual srs_error_t write_audio(int64_t timestamp, char* data, int size); virtual srs_error_t write_video(int64_t timestamp, char* data, int size); private: diff --git a/trunk/src/kernel/srs_kernel_utility.hpp b/trunk/src/kernel/srs_kernel_utility.hpp index 2d22391a2..56bb78771 100644 --- a/trunk/src/kernel/srs_kernel_utility.hpp +++ b/trunk/src/kernel/srs_kernel_utility.hpp @@ -33,160 +33,132 @@ class SrsBuffer; class SrsBitBuffer; -// compare +// Basic compare function. #define srs_min(a, b) (((a) < (b))? (a) : (b)) #define srs_max(a, b) (((a) < (b))? (b) : (a)) -// read nalu uev. +// To read H.264 NALU uev. extern srs_error_t srs_avc_nalu_read_uev(SrsBitBuffer* stream, int32_t& v); extern srs_error_t srs_avc_nalu_read_bit(SrsBitBuffer* stream, int8_t& v); -// get current system time in srs_utime_t, use cache to avoid performance problem +// Get current system time in srs_utime_t, use cache to avoid performance problem extern srs_utime_t srs_get_system_time(); extern srs_utime_t srs_get_system_startup_time(); -// the deamon st-thread will update it. +// A daemon st-thread updates it. extern srs_utime_t srs_update_system_time(); -// the any address for listener, -// it's "0.0.0.0" for ipv4, and "::" for ipv6. +// The "ANY" address to listen, it's "0.0.0.0" for ipv4, and "::" for ipv6. extern std::string srs_any_address4listener(); -// dns resolve utility, return the resolved ip address. +// The dns resolve utility, return the resolved ip address. extern std::string srs_dns_resolve(std::string host, int& family); -// split the host:port to host and port. +// Split the host:port to host and port. // @remark the hostport format in , where port is optional. extern void srs_parse_hostport(const std::string& hostport, std::string& host, int& port); -// parse the endpoint to ip and port. -// @remark hostport format in <[ip:]port>, where ip is default to "0.0.0.0". +// Parse the endpoint to ip and port. +// @remark The hostport format in <[ip:]port>, where ip is default to "0.0.0.0". extern void srs_parse_endpoint(std::string hostport, std::string& ip, int& port); -// parse the int64 value to string. +// Parse the int64 value to string. extern std::string srs_int2str(int64_t value); -// parse the float value to string, precise is 2. +// Parse the float value to string, precise is 2. extern std::string srs_float2str(double value); -// convert bool to switch value, true to "on", false to "off". +// Convert bool to switch value, true to "on", false to "off". extern std::string srs_bool2switch(bool v); -// whether system is little endian +// Whether system is little endian extern bool srs_is_little_endian(); -// replace old_str to new_str of str +// Replace old_str to new_str of str extern std::string srs_string_replace(std::string str, std::string old_str, std::string new_str); -// trim char in trim_chars of str +// Trim char in trim_chars of str extern std::string srs_string_trim_end(std::string str, std::string trim_chars); -// trim char in trim_chars of str +// Trim char in trim_chars of str extern std::string srs_string_trim_start(std::string str, std::string trim_chars); -// remove char in remove_chars of str +// Remove char in remove_chars of str extern std::string srs_string_remove(std::string str, std::string remove_chars); -// remove first substring from str +// Remove first substring from str extern std::string srs_erase_first_substr(std::string str, std::string erase_string); -// remove last substring from str +// Remove last substring from str extern std::string srs_erase_last_substr(std::string str, std::string erase_string); -// whether string end with +// Whether string end with extern bool srs_string_ends_with(std::string str, std::string flag); extern bool srs_string_ends_with(std::string str, std::string flag0, std::string flag1); extern bool srs_string_ends_with(std::string str, std::string flag0, std::string flag1, std::string flag2); extern bool srs_string_ends_with(std::string str, std::string flag0, std::string flag1, std::string flag2, std::string flag3); -// whether string starts with +// Whether string starts with extern bool srs_string_starts_with(std::string str, std::string flag); extern bool srs_string_starts_with(std::string str, std::string flag0, std::string flag1); extern bool srs_string_starts_with(std::string str, std::string flag0, std::string flag1, std::string flag2); extern bool srs_string_starts_with(std::string str, std::string flag0, std::string flag1, std::string flag2, std::string flag3); -// whether string contains with +// Whether string contains with extern bool srs_string_contains(std::string str, std::string flag); extern bool srs_string_contains(std::string str, std::string flag0, std::string flag1); extern bool srs_string_contains(std::string str, std::string flag0, std::string flag1, std::string flag2); -// find the min match in str for flags. +// Find the min match in str for flags. extern std::string srs_string_min_match(std::string str, std::vector flags); -// split the string by flag to array. +// Split the string by flag to array. extern std::vector srs_string_split(std::string str, std::string flag); extern std::vector srs_string_split(std::string str, std::vector flags); -/** - * compare the memory in bytes. - * @return true if completely equal; otherwise, false. - */ +// Compare the memory in bytes. +// @return true if completely equal; otherwise, false. extern bool srs_bytes_equals(void* pa, void* pb, int size); -// create dir recursively +// Create dir recursively extern srs_error_t srs_create_dir_recursively(std::string dir); -// whether path exists. +// Whether path exists. extern bool srs_path_exists(std::string path); -// get the dirname of path, for instance, dirname("/live/livestream")="/live" +// Get the dirname of path, for instance, dirname("/live/livestream")="/live" extern std::string srs_path_dirname(std::string path); -// get the basename of path, for instance, basename("/live/livestream")="livestream" +// Get the basename of path, for instance, basename("/live/livestream")="livestream" extern std::string srs_path_basename(std::string path); -// get the filename of path, for instance, filename("livestream.flv")="livestream" +// Get the filename of path, for instance, filename("livestream.flv")="livestream" extern std::string srs_path_filename(std::string path); -// get the file extension of path, for instance, filext("live.flv")=".flv" +// Get the file extension of path, for instance, filext("live.flv")=".flv" extern std::string srs_path_filext(std::string path); -/** - * whether stream starts with the avc NALU in "AnnexB" - * from ISO_IEC_14496-10-AVC-2003.pdf, page 211. - * start code must be "N[00] 00 00 01" where N>=0 - * @param pnb_start_code output the size of start code, must >=3. - * NULL to ignore. - */ +// Whether stream starts with the avc NALU in "AnnexB" from ISO_IEC_14496-10-AVC-2003.pdf, page 211. +// The start code must be "N[00] 00 00 01" where N>=0 +// @param pnb_start_code output the size of start code, must >=3. NULL to ignore. extern bool srs_avc_startswith_annexb(SrsBuffer* stream, int* pnb_start_code = NULL); -/** - * whether stream starts with the aac ADTS - * from ISO_IEC_14496-3-AAC-2001.pdf, page 75, 1.A.2.2 ADTS. - * start code must be '1111 1111 1111'B, that is 0xFFF - */ +// Whether stream starts with the aac ADTS from ISO_IEC_14496-3-AAC-2001.pdf, page 75, 1.A.2.2 ADTS. +// The start code must be '1111 1111 1111'B, that is 0xFFF extern bool srs_aac_startswith_adts(SrsBuffer* stream); -/** - * cacl the crc32 of bytes in buf, for ffmpeg. - */ +// Cacl the crc32 of bytes in buf, for ffmpeg. extern uint32_t srs_crc32_mpegts(const void* buf, int size); -/** - * calc the crc32 of bytes in buf by IEEE, for zip. - */ +// Calc the crc32 of bytes in buf by IEEE, for zip. extern uint32_t srs_crc32_ieee(const void* buf, int size, uint32_t previous = 0); -/** - * Decode a base64-encoded string. - */ +// Decode a base64-encoded string. extern srs_error_t srs_av_base64_decode(std::string cipher, std::string& plaintext); -/** - * Calculate the output size needed to base64-encode x bytes to a - * null-terminated string. - */ +// Calculate the output size needed to base64-encode x bytes to a null-terminated string. #define SRS_AV_BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1) -/** - * convert hex string to data. - * for example, p=config='139056E5A0' - * output hex to data={0x13, 0x90, 0x56, 0xe5, 0xa0} - */ +// Convert hex string to data, for example, p=config='139056E5A0' +// The output data in hex {0x13, 0x90, 0x56, 0xe5, 0xa0} as such. extern int srs_hex_to_data(uint8_t* data, const char* p, int size); -/** - * convert data string to hex. - */ +// Convert data string to hex. extern char *srs_data_to_hex(char *des, const uint8_t *src, int len); -/** - * generate the c0 chunk header for msg. - * @param cache, the cache to write header. - * @param nb_cache, the size of cache. - * @return the size of header. 0 if cache not enough. - */ +// Generate the c0 chunk header for msg. +// @param cache, the cache to write header. +// @param nb_cache, the size of cache. +// @return The size of header. 0 if cache not enough. extern int srs_chunk_header_c0(int perfer_cid, uint32_t timestamp, int32_t payload_length, int8_t message_type, int32_t stream_id, char* cache, int nb_cache); -/** - * generate the c3 chunk header for msg. - * @param cache, the cache to write header. - * @param nb_cache, the size of cache. - * @return the size of header. 0 if cache not enough. - */ +// Generate the c3 chunk header for msg. +// @param cache, the cache to write header. +// @param nb_cache, the size of cache. +// @return the size of header. 0 if cache not enough. extern int srs_chunk_header_c3(int perfer_cid, uint32_t timestamp, char* cache, int nb_cache); #endif From 8bc77387ff7f17997e6b6a9bc642379433739eaf Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 23 Apr 2019 08:06:50 +0800 Subject: [PATCH 04/25] Refine typo in protocol. --- trunk/src/protocol/srs_http_stack.hpp | 360 ++--- trunk/src/protocol/srs_protocol_json.hpp | 56 +- trunk/src/protocol/srs_raw_avc.hpp | 98 +- trunk/src/protocol/srs_rtmp_handshake.hpp | 490 +++--- trunk/src/protocol/srs_rtmp_msg_array.hpp | 40 +- trunk/src/protocol/srs_rtmp_stack.hpp | 1741 ++++++++------------- trunk/src/protocol/srs_rtsp_stack.hpp | 660 ++++---- 7 files changed, 1328 insertions(+), 2117 deletions(-) diff --git a/trunk/src/protocol/srs_http_stack.hpp b/trunk/src/protocol/srs_http_stack.hpp index f20a7aaa1..e68fe7b4e 100644 --- a/trunk/src/protocol/srs_http_stack.hpp +++ b/trunk/src/protocol/srs_http_stack.hpp @@ -26,7 +26,7 @@ #include -// default http listen port. +// Default http listen port. #define SRS_DEFAULT_HTTP_PORT 80 #if !defined(SRS_EXPORT_LIBRTMP) @@ -35,7 +35,7 @@ #include #include -// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 +// For srs-librtmp, @see https://github.com/ossrs/srs/issues/213 #ifndef _WIN32 #include #endif @@ -46,7 +46,7 @@ class ISrsHttpMessage; class SrsHttpMuxEntry; class ISrsHttpResponseWriter; -// http specification +// From http specification // CR = #define SRS_HTTP_CR SRS_CONSTS_CR // 0x0D // LF = @@ -65,10 +65,10 @@ class ISrsHttpResponseWriter; // @see ISrsHttpMessage._http_ts_send_buffer #define SRS_HTTP_TS_SEND_BUFFER_SIZE 4096 -// for ead all of http body, read each time. +// For ead all of http body, read each time. #define SRS_HTTP_READ_CACHE_BYTES 4096 -// for http parser macros +// For http parser macros #define SRS_CONSTS_HTTP_OPTIONS HTTP_OPTIONS #define SRS_CONSTS_HTTP_GET HTTP_GET #define SRS_CONSTS_HTTP_POST HTTP_POST @@ -80,10 +80,10 @@ class ISrsHttpResponseWriter; extern srs_error_t srs_go_http_error(ISrsHttpResponseWriter* w, int code); extern srs_error_t srs_go_http_error(ISrsHttpResponseWriter* w, int code, std::string error); -// get the status text of code. +// Get the status text of code. extern std::string srs_generate_http_status_text(int status); -// bodyAllowedForStatus reports whether a given response status code +// It reports whether a given response status code // permits a body. See RFC2616, section 4.4. extern bool srs_go_http_body_allowd(int status); @@ -95,7 +95,7 @@ extern bool srs_go_http_body_allowd(int status); // returns "application/octet-stream". extern std::string srs_go_http_detect(char* data, int size); -// state of message +// The state of HTTP message enum SrsHttpParseState { SrsHttpParseStateInit = 0, SrsHttpParseStateStart, @@ -121,27 +121,17 @@ public: // with CanonicalHeaderKey. virtual std::string get(std::string key); public: - /** - * get the content length. -1 if not set. - */ + // Get the content length. -1 if not set. virtual int64_t content_length(); - /** - * set the content length by header "Content-Length" - */ + // set the content length by header "Content-Length" virtual void set_content_length(int64_t size); public: - /** - * get the content type. empty string if not set. - */ + // Get the content type. empty string if not set. virtual std::string content_type(); - /** - * set the content type by header "Content-Type" - */ + // set the content type by header "Content-Type" virtual void set_content_type(std::string ct); public: - /** - * write all headers to string stream. - */ + // write all headers to string stream. virtual void write(std::stringstream& ss); }; @@ -176,9 +166,9 @@ public: ISrsHttpResponseWriter(); virtual ~ISrsHttpResponseWriter(); public: - // when chunked mode, + // When chunked mode, // final the request to complete the chunked encoding. - // for no-chunked mode, + // For no-chunked mode, // final to send request, for example, content-length is 0. virtual srs_error_t final_request() = 0; @@ -191,13 +181,11 @@ public: // If WriteHeader has not yet been called, Write calls WriteHeader(http.StatusOK) // before writing the data. If the Header does not contain a // Content-Type line, Write adds a Content-Type set to the result of passing - // the initial 512 bytes of written data to DetectContentType. + // The initial 512 bytes of written data to DetectContentType. // @param data, the data to send. NULL to flush header only. virtual srs_error_t write(char* data, int size) = 0; - /** - * for the HTTP FLV, to writev to improve performance. - * @see https://github.com/ossrs/srs/issues/405 - */ + // for the HTTP FLV, to writev to improve performance. + // @see https://github.com/ossrs/srs/issues/405 virtual srs_error_t writev(const iovec* iov, int iovcnt, ssize_t* pnwrite) = 0; // WriteHeader sends an HTTP response header with status code. @@ -209,32 +197,26 @@ public: virtual void write_header(int code) = 0; }; -/** - * the reader interface for http response. - */ +// The reader interface for http response. class ISrsHttpResponseReader { public: ISrsHttpResponseReader(); virtual ~ISrsHttpResponseReader(); public: - /** - * whether response read EOF. - */ + // Whether response read EOF. virtual bool eof() = 0; - /** - * read from the response body. - * @param data, the buffer to read data buffer to. - * @param nb_data, the max size of data buffer. - * @param nb_read, the actual read size of bytes. NULL to ignore. - * @remark when eof(), return error. - * @remark for some server, the content-length not specified and not chunked, - * which is actually the infinite chunked encoding, which after http header - * is http response data, it's ok for browser. that is, - * when user call this read, please ensure there is data to read(by content-length - * or by chunked), because the sdk never know whether there is no data or - * infinite chunked. - */ + // Read from the response body. + // @param data, the buffer to read data buffer to. + // @param nb_data, the max size of data buffer. + // @param nb_read, the actual read size of bytes. NULL to ignore. + // @remark when eof(), return error. + // @remark for some server, the content-length not specified and not chunked, + // which is actually the infinite chunked encoding, which after http header + // is http response data, it's ok for browser. that is, + // when user call this read, please ensure there is data to read(by content-length + // or by chunked), because the sdk never know whether there is no data or + // infinite chunked. virtual srs_error_t read(char* data, int nb_data, int* nb_read) = 0; }; @@ -245,7 +227,7 @@ public: // ServeHTTP should write reply headers and data to the ResponseWriter // and then return. Returning signals that the request is finished // and that the HTTP server can move on to the next request on -// the connection. +// The connection. class ISrsHttpHandler { public: @@ -300,33 +282,25 @@ public: public: virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); private: - /** - * serve the file by specified path - */ + // Serve the file by specified path virtual srs_error_t serve_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath); virtual srs_error_t serve_flv_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath); virtual srs_error_t serve_mp4_file(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath); protected: - /** - * when access flv file with x.flv?start=xxx - */ + // When access flv file with x.flv?start=xxx virtual srs_error_t serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int offset); - /** - * when access mp4 file with x.mp4?range=start-end - * @param start the start offset in bytes. - * @param end the end offset in bytes. -1 to end of file. - * @remark response data in [start, end]. - */ + // When access mp4 file with x.mp4?range=start-end + // @param start the start offset in bytes. + // @param end the end offset in bytes. -1 to end of file. + // @remark response data in [start, end]. virtual srs_error_t serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int start, int end); protected: - /** - * copy the fs to response writer in size bytes. - */ + // Copy the fs to response writer in size bytes. virtual srs_error_t copy(ISrsHttpResponseWriter* w, SrsFileReader* fs, ISrsHttpMessage* r, int size); }; -// the mux entry for server mux. -// the matcher info, for example, the pattern and handler. +// The mux entry for server mux. +// The matcher info, for example, the pattern and handler. class SrsHttpMuxEntry { public: @@ -339,26 +313,20 @@ public: virtual ~SrsHttpMuxEntry(); }; -/** - * the hijacker for http pattern match. - */ +// The hijacker for http pattern match. class ISrsHttpMatchHijacker { public: ISrsHttpMatchHijacker(); virtual ~ISrsHttpMatchHijacker(); public: - /** - * when match the request failed, no handler to process request. - * @param request the http request message to match the handler. - * @param ph the already matched handler, hijack can rewrite it. - */ + // When match the request failed, no handler to process request. + // @param request the http request message to match the handler. + // @param ph the already matched handler, hijack can rewrite it. virtual srs_error_t hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) = 0; }; -/** - * the server mux, all http server should implements it. - */ +// The server mux, all http server should implements it. class ISrsHttpServeMux { public: @@ -383,7 +351,7 @@ public: // "/images/" subtree. // // Note that since a pattern ending in a slash names a rooted subtree, -// the pattern "/" matches all paths not matched by other registered +// The pattern "/" matches all paths not matched by other registered // patterns, not just the URL with Path == "/". // // Patterns may optionally begin with a host name, restricting matches to @@ -398,29 +366,25 @@ public: class SrsHttpServeMux : public ISrsHttpServeMux { private: - // the pattern handler, to handle the http request. + // The pattern handler, to handle the http request. std::map entries; - // the vhost handler. - // when find the handler to process the request, + // The vhost handler. + // When find the handler to process the request, // append the matched vhost when pattern not starts with /, - // for example, for pattern /live/livestream.flv of vhost ossrs.net, - // the path will rewrite to ossrs.net/live/livestream.flv + // For example, for pattern /live/livestream.flv of vhost ossrs.net, + // The path will rewrite to ossrs.net/live/livestream.flv std::map vhosts; // all hijackers for http match. - // for example, the hstrs(http stream trigger rtmp source) + // For example, the hstrs(http stream trigger rtmp source) // can hijack and install handler when request incoming and no handler. std::vector hijackers; public: SrsHttpServeMux(); virtual ~SrsHttpServeMux(); public: - /** - * initialize the http serve mux. - */ + // Initialize the http serve mux. virtual srs_error_t initialize(); - /** - * hijack the http match. - */ + // hijack the http match. virtual void hijack(ISrsHttpMatchHijacker* h); virtual void unhijack(ISrsHttpMatchHijacker* h); public: @@ -437,10 +401,8 @@ private: virtual bool path_match(std::string pattern, std::string path); }; -/** - * The filter http mux, directly serve the http CORS requests, - * while proxy to the worker mux for services. - */ +// The filter http mux, directly serve the http CORS requests, +// while proxy to the worker mux for services. class SrsHttpCorsMux : public ISrsHttpServeMux { private: @@ -457,7 +419,7 @@ public: virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); }; -// for http header. +// For http header. typedef std::pair SrsHttpHeaderField; // A Request represents an HTTP request received by a server @@ -473,34 +435,28 @@ typedef std::pair SrsHttpHeaderField; // 3. no body or user not confirmed infinite chunked. // For example: // ISrsHttpMessage* r = ...; -// while (!r->eof()) r->read(); // read in mode 1 or 3. +// while (!r->eof()) r->read(); // Read in mode 1 or 3. // For some server, we can confirm the body is infinite chunked: // ISrsHttpMessage* r = ...; // r->enter_infinite_chunked(); -// while (!r->eof()) r->read(); // read in mode 2 +// while (!r->eof()) r->read(); // Read in mode 2 // @rmark for mode 2, the infinite chunked, all left data is body. class ISrsHttpMessage { private: - /** - * use a buffer to read and send ts file. - */ + // Use a buffer to read and send ts file. // TODO: FIXME: remove it. char* _http_ts_send_buffer; public: ISrsHttpMessage(); virtual ~ISrsHttpMessage(); public: - /** - * the http request level cache. - */ + // The http request level cache. virtual char* http_ts_send_buffer(); public: virtual uint8_t method() = 0; virtual uint16_t status_code() = 0; - /** - * method helpers. - */ + // Method helpers. virtual std::string method_str() = 0; virtual bool is_http_get() = 0; virtual bool is_http_put() = 0; @@ -508,94 +464,74 @@ public: virtual bool is_http_delete() = 0; virtual bool is_http_options() = 0; public: - /** - * whether should keep the connection alive. - */ + // Whether should keep the connection alive. virtual bool is_keep_alive() = 0; - /** - * the uri contains the host and path. - */ + // The uri contains the host and path. virtual std::string uri() = 0; - /** - * the url maybe the path. - */ + // The url maybe the path. virtual std::string url() = 0; virtual std::string host() = 0; virtual std::string path() = 0; virtual std::string query() = 0; virtual std::string ext() = 0; - /** - * get the RESTful id, - * for example, pattern is /api/v1/streams, path is /api/v1/streams/100, - * then the rest id is 100. - * @param pattern the handler pattern which will serve the request. - * @return the REST id; -1 if not matched. - */ + // Get the RESTful id, + // for example, pattern is /api/v1/streams, path is /api/v1/streams/100, + // then the rest id is 100. + // @param pattern the handler pattern which will serve the request. + // @return the REST id; -1 if not matched. virtual int parse_rest_id(std::string pattern) = 0; public: - /** - * the left all data is chunked body, the infinite chunked mode, - * which is chunked encoding without chunked header. - * @remark error when message is in chunked or content-length specified. - */ + // The left all data is chunked body, the infinite chunked mode, + // which is chunked encoding without chunked header. + // @remark error when message is in chunked or content-length specified. virtual srs_error_t enter_infinite_chunked() = 0; - /** - * read body to string. - * @remark for small http body. - */ + // Read body to string. + // @remark for small http body. virtual srs_error_t body_read_all(std::string& body) = 0; - /** - * get the body reader, to read one by one. - * @remark when body is very large, or chunked, use this. - */ + // Get the body reader, to read one by one. + // @remark when body is very large, or chunked, use this. virtual ISrsHttpResponseReader* body_reader() = 0; - /** - * the content length, -1 for chunked or not set. - */ + // The content length, -1 for chunked or not set. virtual int64_t content_length() = 0; public: - /** - * get the param in query string, - * for instance, query is "start=100&end=200", - * then query_get("start") is "100", and query_get("end") is "200" - */ + // Get the param in query string, + // for instance, query is "start=100&end=200", + // then query_get("start") is "100", and query_get("end") is "200" virtual std::string query_get(std::string key) = 0; - /** - * get the headers. - */ + // Get the headers. virtual int request_header_count() = 0; virtual std::string request_header_key_at(int index) = 0; virtual std::string request_header_value_at(int index) = 0; public: - /** - * whether the current request is JSONP, - * which has a "callback=xxx" in QueryString. - */ + // Whether the current request is JSONP, + // which has a "callback=xxx" in QueryString. virtual bool is_jsonp() = 0; }; #endif -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ +// The http-parser is license under MIT at https://github.com/nodejs/http-parser/blob/master/LICENSE-MIT +// Version: 2.1 from https://github.com/nodejs/http-parser/releases/tag/v2.1 + +//Copyright Joyent, Inc. and other Node contributors. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// The SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. #ifndef http_parser_h #define http_parser_h #ifdef __cplusplus @@ -621,9 +557,8 @@ extern "C" { #include #endif - /* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run - * faster - */ + // Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run + // faster #ifndef HTTP_PARSER_STRICT # define HTTP_PARSER_STRICT 1 #endif @@ -636,19 +571,18 @@ extern "C" { typedef struct http_parser_settings http_parser_settings; - /* Callbacks should return non-zero to indicate an error. The parser will - * then halt execution. - * - * The one exception is on_headers_complete. In a HTTP_RESPONSE parser - * returning '1' from on_headers_complete will tell the parser that it - * should not expect a body. This is used when receiving a response to a - * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: - * chunked' headers that indicate the presence of a body. - * - * http_data_cb does not return data chunks. It will be call arbitrarally - * many times for each string. E.G. you might get 10 callbacks for "on_url" - * each providing just a few characters more data. - */ + // Callbacks should return non-zero to indicate an error. The parser will + // then halt execution. + // + // The one exception is on_headers_complete. In a HTTP_RESPONSE parser + // returning '1' from on_headers_complete will tell the parser that it + // should not expect a body. This is used when receiving a response to a + // HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: + // chunked' headers that indicate the presence of a body. + // + // http_data_cb does not return data chunks. It will be call arbitrarally + // many times for each string. E.G. you might get 10 callbacks for "on_url" + // each providing just a few characters more data. typedef int (*http_data_cb) (http_parser*, const char *at, size_t length); typedef int (*http_cb) (http_parser*); @@ -709,10 +643,8 @@ extern "C" { }; - /* Map for errno-related constants - * - * The provided argument should be a macro that takes 2 arguments. - */ + // Map for errno-related constants + // The provided argument should be a macro that takes 2 arguments. #define HTTP_ERRNO_MAP(XX) \ /* No error */ \ XX(OK, "success") \ @@ -785,11 +717,10 @@ extern "C" { unsigned char method; /* requests only */ unsigned char http_errno : 7; - /* 1 = Upgrade header was present and the parser has exited because of that. - * 0 = No upgrade header present. - * Should be checked when http_parser_execute() returns in addition to - * error checking. - */ + // 1 = Upgrade header was present and the parser has exited because of that. + // 0 = No upgrade header present. + // Should be checked when http_parser_execute() returns in addition to + // error checking. unsigned char upgrade : 1; /** PUBLIC **/ @@ -821,13 +752,11 @@ extern "C" { }; - /* Result structure for http_parser_parse_url(). - * - * Callers should index into field_data[] with UF_* values iff field_set - * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and - * because we probably have padding left over), we convert any port to - * a uint16_t. - */ + // Result structure for http_parser_parse_url(). + // Callers should index into field_data[] with UF_* values iff field_set + // has the relevant (1 << UF_*) bit set. As a courtesy to clients (and + // because we probably have padding left over), we convert any port to + // a uint16_t. struct http_parser_url { uint16_t field_set; /* Bitmask of (1 << UF_*) values */ uint16_t port; /* Converted UF_PORT string */ @@ -848,12 +777,11 @@ extern "C" { size_t len); - /* If http_should_keep_alive() in the on_headers_complete or - * on_message_complete callback returns 0, then this should be - * the last message on the connection. - * If you are the server, respond with the "Connection: close" header. - * If you are the client, close the connection. - */ + // If http_should_keep_alive() in the on_headers_complete or + // on_message_complete callback returns 0, then this should be + // The last message on the connection. + // If you are the server, respond with the "Connection: close" header. + // If you are the client, close the connection. int http_should_keep_alive(const http_parser *parser); /* Returns a string version of the HTTP method. */ @@ -881,9 +809,7 @@ extern "C" { #endif #endif -/** - * used to resolve the http uri. - */ +// Used to resolve the http uri. class SrsHttpUri { private: @@ -897,9 +823,7 @@ public: SrsHttpUri(); virtual ~SrsHttpUri(); public: - /** - * initialize the http uri. - */ + // Initialize the http uri. virtual srs_error_t initialize(std::string _url); public: virtual std::string get_url(); @@ -909,10 +833,8 @@ public: virtual std::string get_path(); virtual std::string get_query(); private: - /** - * get the parsed url field. - * @return return empty string if not set. - */ + // Get the parsed url field. + // @return return empty string if not set. virtual std::string get_uri_field(std::string uri, http_parser_url* hp_u, http_parser_url_fields field); }; diff --git a/trunk/src/protocol/srs_protocol_json.hpp b/trunk/src/protocol/srs_protocol_json.hpp index 4fa5702cc..1eedd9b23 100644 --- a/trunk/src/protocol/srs_protocol_json.hpp +++ b/trunk/src/protocol/srs_protocol_json.hpp @@ -32,7 +32,7 @@ //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -// json decode +// JSON decode // 1. SrsJsonAny: read any from str:char* // SrsJsonAny* any = NULL; // if ((any = SrsJsonAny::loads(str)) == NULL) { @@ -45,7 +45,7 @@ // string v = any->to_str(); // } // -// for detail usage, see interfaces of each object. +// For detail usage, see interfaces of each object. //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// @@ -59,8 +59,8 @@ class SrsJsonAny { public: char marker; - // donot directly create this object, - // instead, for examle, use SrsJsonAny::str() to create a concreated one. + // Don't directly create this object, + // please use SrsJsonAny::str() to create a concreated one. protected: SrsJsonAny(); public: @@ -74,35 +74,23 @@ public: virtual bool is_array(); virtual bool is_null(); public: - /** - * get the string of any when is_string() indicates true. - * user must ensure the type is a string, or assert failed. - */ + // Get the string of any when is_string() indicates true. + // user must ensure the type is a string, or assert failed. virtual std::string to_str(); - /** - * get the boolean of any when is_boolean() indicates true. - * user must ensure the type is a boolean, or assert failed. - */ + // Get the boolean of any when is_boolean() indicates true. + // user must ensure the type is a boolean, or assert failed. virtual bool to_boolean(); - /** - * get the integer of any when is_integer() indicates true. - * user must ensure the type is a integer, or assert failed. - */ + // Get the integer of any when is_integer() indicates true. + // user must ensure the type is a integer, or assert failed. virtual int64_t to_integer(); - /** - * get the number of any when is_number() indicates true. - * user must ensure the type is a number, or assert failed. - */ + // Get the number of any when is_number() indicates true. + // user must ensure the type is a number, or assert failed. virtual double to_number(); - /** - * get the object of any when is_object() indicates true. - * user must ensure the type is a object, or assert failed. - */ + // Get the object of any when is_object() indicates true. + // user must ensure the type is a object, or assert failed. virtual SrsJsonObject* to_object(); - /** - * get the ecma array of any when is_ecma_array() indicates true. - * user must ensure the type is a ecma array, or assert failed. - */ + // Get the ecma array of any when is_ecma_array() indicates true. + // user must ensure the type is a ecma array, or assert failed. virtual SrsJsonArray* to_array(); public: virtual std::string dumps(); @@ -117,10 +105,8 @@ public: static SrsJsonObject* object(); static SrsJsonArray* array(); public: - /** - * read json tree from string. - * @return json object. NULL if error. - */ + // Read json tree from string. + // @return json object. NULL if error. static SrsJsonAny* loads(const std::string& str); }; @@ -130,7 +116,7 @@ private: typedef std::pair SrsJsonObjectPropertyType; std::vector properties; private: - // use SrsJsonAny::object() to create it. + // Use SrsJsonAny::object() to create it. friend class SrsJsonAny; SrsJsonObject(); public: @@ -161,7 +147,7 @@ private: std::vector properties; private: - // use SrsJsonAny::array() to create it. + // Use SrsJsonAny::array() to create it. friend class SrsJsonAny; SrsJsonArray(); public: @@ -181,6 +167,6 @@ public: //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// -// json encode, please use JSON.dumps() to encode json object. +// JSON encode, please use JSON.dumps() to encode json object. #endif diff --git a/trunk/src/protocol/srs_raw_avc.hpp b/trunk/src/protocol/srs_raw_avc.hpp index 620534bf4..36fbfe411 100644 --- a/trunk/src/protocol/srs_raw_avc.hpp +++ b/trunk/src/protocol/srs_raw_avc.hpp @@ -32,61 +32,45 @@ class SrsBuffer; -/** - * the raw h.264 stream, in annexb. - */ +// The raw h.264 stream, in annexb. class SrsRawH264Stream { public: SrsRawH264Stream(); virtual ~SrsRawH264Stream(); public: - /** - * demux the stream in annexb format. - * @param stream the input stream bytes. - * @param pframe the output h.264 frame in stream. user should never free it. - * @param pnb_frame the output h.264 frame size. - */ + // Demux the stream in annexb format. + // @param stream the input stream bytes. + // @param pframe the output h.264 frame in stream. user should never free it. + // @param pnb_frame the output h.264 frame size. virtual srs_error_t annexb_demux(SrsBuffer* stream, char** pframe, int* pnb_frame); - /** - * whether the frame is sps or pps. - */ + // whether the frame is sps or pps. virtual bool is_sps(char* frame, int nb_frame); virtual bool is_pps(char* frame, int nb_frame); - /** - * demux the sps or pps to string. - * @param sps/pps output the sps/pps. - */ + // Demux the sps or pps to string. + // @param sps/pps output the sps/pps. virtual srs_error_t sps_demux(char* frame, int nb_frame, std::string& sps); virtual srs_error_t pps_demux(char* frame, int nb_frame, std::string& pps); public: - /** - * h264 raw data to h264 packet, without flv payload header. - * mux the sps/pps to flv sequence header packet. - * @param sh output the sequence header. - */ + // The h264 raw data to h264 packet, without flv payload header. + // Mux the sps/pps to flv sequence header packet. + // @param sh output the sequence header. virtual srs_error_t mux_sequence_header(std::string sps, std::string pps, uint32_t dts, uint32_t pts, std::string& sh); - /** - * h264 raw data to h264 packet, without flv payload header. - * mux the ibp to flv ibp packet. - * @param ibp output the packet. - * @param frame_type output the frame type. - */ + // The h264 raw data to h264 packet, without flv payload header. + // Mux the ibp to flv ibp packet. + // @param ibp output the packet. + // @param frame_type output the frame type. virtual srs_error_t mux_ipb_frame(char* frame, int nb_frame, std::string& ibp); - /** - * mux the avc video packet to flv video packet. - * @param frame_type, SrsVideoAvcFrameTypeKeyFrame or SrsVideoAvcFrameTypeInterFrame. - * @param avc_packet_type, SrsVideoAvcFrameTraitSequenceHeader or SrsVideoAvcFrameTraitNALU. - * @param video the h.264 raw data. - * @param flv output the muxed flv packet. - * @param nb_flv output the muxed flv size. - */ + // Mux the avc video packet to flv video packet. + // @param frame_type, SrsVideoAvcFrameTypeKeyFrame or SrsVideoAvcFrameTypeInterFrame. + // @param avc_packet_type, SrsVideoAvcFrameTraitSequenceHeader or SrsVideoAvcFrameTraitNALU. + // @param video the h.264 raw data. + // @param flv output the muxed flv packet. + // @param nb_flv output the muxed flv size. virtual srs_error_t mux_avc2flv(std::string video, int8_t frame_type, int8_t avc_packet_type, uint32_t dts, uint32_t pts, char** flv, int* nb_flv); }; -/** - * the header of adts sample. - */ +// The header of adts sample. struct SrsRawAacStreamCodec { int8_t protection_absent; @@ -103,37 +87,29 @@ struct SrsRawAacStreamCodec int8_t aac_packet_type; }; -/** - * the raw aac stream, in adts. - */ +// The raw aac stream, in adts. class SrsRawAacStream { public: SrsRawAacStream(); virtual ~SrsRawAacStream(); public: - /** - * demux the stream in adts format. - * @param stream the input stream bytes. - * @param pframe the output aac frame in stream. user should never free it. - * @param pnb_frame the output aac frame size. - * @param codec the output codec info. - */ + // Demux the stream in adts format. + // @param stream the input stream bytes. + // @param pframe the output aac frame in stream. user should never free it. + // @param pnb_frame the output aac frame size. + // @param codec the output codec info. virtual srs_error_t adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame, SrsRawAacStreamCodec& codec); - /** - * aac raw data to aac packet, without flv payload header. - * mux the aac specific config to flv sequence header packet. - * @param sh output the sequence header. - */ + // Mux aac raw data to aac packet, without flv payload header. + // Mux the aac specific config to flv sequence header packet. + // @param sh output the sequence header. virtual srs_error_t mux_sequence_header(SrsRawAacStreamCodec* codec, std::string& sh); - /** - * mux the aac audio packet to flv audio packet. - * @param frame the aac raw data. - * @param nb_frame the count of aac frame. - * @param codec the codec info of aac. - * @param flv output the muxed flv packet. - * @param nb_flv output the muxed flv size. - */ + // Mux the aac audio packet to flv audio packet. + // @param frame the aac raw data. + // @param nb_frame the count of aac frame. + // @param codec the codec info of aac. + // @param flv output the muxed flv packet. + // @param nb_flv output the muxed flv size. virtual srs_error_t mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec* codec, uint32_t dts, char** flv, int* nb_flv); }; diff --git a/trunk/src/protocol/srs_rtmp_handshake.hpp b/trunk/src/protocol/srs_rtmp_handshake.hpp index befdb2d78..9029e55fd 100644 --- a/trunk/src/protocol/srs_rtmp_handshake.hpp +++ b/trunk/src/protocol/srs_rtmp_handshake.hpp @@ -31,21 +31,19 @@ class SrsComplexHandshake; class SrsHandshakeBytes; class SrsBuffer; -// for openssl. +// For openssl. #include namespace _srs_internal { - // the digest key generate size. + // The digest key generate size. #define SRS_OpensslHashSize 512 extern uint8_t SrsGenuineFMSKey[]; extern uint8_t SrsGenuineFPKey[]; srs_error_t openssl_HMACsha256(const void* key, int key_size, const void* data, int data_size, void* digest); srs_error_t openssl_generate_key(char* public_key, int32_t size); - /** - * the DH wrapper. - */ + // The DH wrapper. class SrsDH { private: @@ -56,62 +54,48 @@ namespace _srs_internal private: virtual void close(); public: - /** - * initialize dh, generate the public and private key. - * @param ensure_128bytes_public_key whether ensure public key is 128bytes, - * sometimes openssl generate 127bytes public key. - * default to false to donot ensure. - */ + // Initialize dh, generate the public and private key. + // @param ensure_128bytes_public_key whether ensure public key is 128bytes, + // sometimes openssl generate 127bytes public key. + // default to false to donot ensure. virtual srs_error_t initialize(bool ensure_128bytes_public_key = false); - /** - * copy the public key. - * @param pkey the bytes to copy the public key. - * @param pkey_size the max public key size, output the actual public key size. - * user should never ignore this size. - * @remark, when ensure_128bytes_public_key, the size always 128. - */ + // Copy the public key. + // @param pkey the bytes to copy the public key. + // @param pkey_size the max public key size, output the actual public key size. + // user should never ignore this size. + // @remark, when ensure_128bytes_public_key, the size always 128. virtual srs_error_t copy_public_key(char* pkey, int32_t& pkey_size); - /** - * generate and copy the shared key. - * generate the shared key with peer public key. - * @param ppkey peer public key. - * @param ppkey_size the size of ppkey. - * @param skey the computed shared key. - * @param skey_size the max shared key size, output the actual shared key size. - * user should never ignore this size. - */ + // Generate and copy the shared key. + // Generate the shared key with peer public key. + // @param ppkey peer public key. + // @param ppkey_size the size of ppkey. + // @param skey the computed shared key. + // @param skey_size the max shared key size, output the actual shared key size. + // user should never ignore this size. virtual srs_error_t copy_shared_key(const char* ppkey, int32_t ppkey_size, char* skey, int32_t& skey_size); private: virtual srs_error_t do_initialize(); }; - /** - * the schema type. - */ + // The schema type. enum srs_schema_type { srs_schema_invalid = 2, - /** - * key-digest sequence - */ + // The key-digest sequence srs_schema0 = 0, - /** - * digest-key sequence - * @remark, FMS requires the schema1(digest-key), or connect failed. - */ + // The digest-key sequence + // @remark, FMS requires the schema1(digest-key), or connect failed. // srs_schema1 = 1, }; - /** - * 764bytes key structure - * random-data: (offset)bytes - * key-data: 128bytes - * random-data: (764-offset-128-4)bytes - * offset: 4bytes - * @see also: http://blog.csdn.net/win_lin/article/details/13006803 - */ + // The 764bytes key structure + // random-data: (offset)bytes + // key-data: 128bytes + // random-data: (764-offset-128-4)bytes + // offset: 4bytes + // @see also: http://blog.csdn.net/win_lin/article/details/13006803 class key_block { public: @@ -132,24 +116,22 @@ namespace _srs_internal key_block(); virtual ~key_block(); public: - // parse key block from c1s1. + // Parse key block from c1s1. // if created, user must free it by srs_key_block_free // @stream contains c1s1_key_bytes the key start bytes srs_error_t parse(SrsBuffer* stream); private: - // calc the offset of key, - // the key->offset cannot be used as the offset of key. + // Calculate the offset of key, + // The key->offset cannot be used as the offset of key. int calc_valid_offset(); }; - /** - * 764bytes digest structure - * offset: 4bytes - * random-data: (offset)bytes - * digest-data: 32bytes - * random-data: (764-4-offset-32)bytes - * @see also: http://blog.csdn.net/win_lin/article/details/13006803 - */ + // The 764bytes digest structure + // offset: 4bytes + // random-data: (offset)bytes + // digest-data: 32bytes + // random-data: (764-4-offset-32)bytes + // @see also: http://blog.csdn.net/win_lin/article/details/13006803 class digest_block { public: @@ -170,23 +152,21 @@ namespace _srs_internal digest_block(); virtual ~digest_block(); public: - // parse digest block from c1s1. + // Parse digest block from c1s1. // if created, user must free it by srs_digest_block_free // @stream contains c1s1_digest_bytes the digest start bytes srs_error_t parse(SrsBuffer* stream); private: - // calc the offset of digest, - // the key->offset cannot be used as the offset of digest. + // Calculate the offset of digest, + // The key->offset cannot be used as the offset of digest. int calc_valid_offset(); }; class c1s1; - /** - * the c1s1 strategy, use schema0 or schema1. - * the template method class to defines common behaviors, - * while the concrete class to implements in schema0 or schema1. - */ + // The c1s1 strategy, use schema0 or schema1. + // The template method class to defines common behaviors, + // while the concrete class to implements in schema0 or schema1. class c1s1_strategy { protected: @@ -196,114 +176,82 @@ namespace _srs_internal c1s1_strategy(); virtual ~c1s1_strategy(); public: - /** - * get the scema. - */ + // Get the scema. virtual srs_schema_type schema() = 0; - /** - * get the digest. - */ + // Get the digest. virtual char* get_digest(); - /** - * get the key. - */ + // Get the key. virtual char* get_key(); - /** - * copy to bytes. - * @param size must be 1536. - */ + // Copy to bytes. + // @param size must be 1536. virtual srs_error_t dump(c1s1* owner, char* _c1s1, int size); - /** - * server: parse the c1s1, discovery the key and digest by schema. - * use the c1_validate_digest() to valid the digest of c1. - */ + // For server: parse the c1s1, discovery the key and digest by schema. + // use the c1_validate_digest() to valid the digest of c1. virtual srs_error_t parse(char* _c1s1, int size) = 0; public: - /** - * client: create and sign c1 by schema. - * sign the c1, generate the digest. - * calc_c1_digest(c1, schema) { - * get c1s1-joined from c1 by specified schema - * digest-data = HMACsha256(c1s1-joined, FPKey, 30) - * return digest-data; - * } - * random fill 1536bytes c1 // also fill the c1-128bytes-key - * time = time() // c1[0-3] - * version = [0x80, 0x00, 0x07, 0x02] // c1[4-7] - * schema = choose schema0 or schema1 - * digest-data = calc_c1_digest(c1, schema) - * copy digest-data to c1 - */ + // For client: create and sign c1 by schema. + // sign the c1, generate the digest. + // calc_c1_digest(c1, schema) { + // get c1s1-joined from c1 by specified schema + // digest-data = HMACsha256(c1s1-joined, FPKey, 30) + // return digest-data; + // } + // random fill 1536bytes c1 // also fill the c1-128bytes-key + // time = time() // c1[0-3] + // version = [0x80, 0x00, 0x07, 0x02] // c1[4-7] + // schema = choose schema0 or schema1 + // digest-data = calc_c1_digest(c1, schema) + // copy digest-data to c1 virtual srs_error_t c1_create(c1s1* owner); - /** - * server: validate the parsed c1 schema - */ + // For server: validate the parsed c1 schema virtual srs_error_t c1_validate_digest(c1s1* owner, bool& is_valid); - /** - * server: create and sign the s1 from c1. - * // decode c1 try schema0 then schema1 - * c1-digest-data = get-c1-digest-data(schema0) - * if c1-digest-data equals to calc_c1_digest(c1, schema0) { - * c1-key-data = get-c1-key-data(schema0) - * schema = schema0 - * } else { - * c1-digest-data = get-c1-digest-data(schema1) - * if c1-digest-data not equals to calc_c1_digest(c1, schema1) { - * switch to simple handshake. - * return - * } - * c1-key-data = get-c1-key-data(schema1) - * schema = schema1 - * } - * - * // generate s1 - * random fill 1536bytes s1 - * time = time() // c1[0-3] - * version = [0x04, 0x05, 0x00, 0x01] // s1[4-7] - * s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data) - * get c1s1-joined by specified schema - * s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36) - * copy s1-digest-data and s1-key-data to s1. - * @param c1, to get the peer_pub_key of client. - */ + // For server: create and sign the s1 from c1. + // // decode c1 try schema0 then schema1 + // c1-digest-data = get-c1-digest-data(schema0) + // if c1-digest-data equals to calc_c1_digest(c1, schema0) { + // c1-key-data = get-c1-key-data(schema0) + // schema = schema0 + // } else { + // c1-digest-data = get-c1-digest-data(schema1) + // if c1-digest-data not equals to calc_c1_digest(c1, schema1) { + // switch to simple handshake. + // return + // } + // c1-key-data = get-c1-key-data(schema1) + // schema = schema1 + // } + // + // // Generate s1 + // random fill 1536bytes s1 + // time = time() // c1[0-3] + // version = [0x04, 0x05, 0x00, 0x01] // s1[4-7] + // s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data) + // get c1s1-joined by specified schema + // s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36) + // copy s1-digest-data and s1-key-data to s1. + // @param c1, to get the peer_pub_key of client. virtual srs_error_t s1_create(c1s1* owner, c1s1* c1); - /** - * server: validate the parsed s1 schema - */ + // For server: validate the parsed s1 schema virtual srs_error_t s1_validate_digest(c1s1* owner, bool& is_valid); public: - /** - * calc the digest for c1 - */ + // Calculate the digest for c1 virtual srs_error_t calc_c1_digest(c1s1* owner, char*& c1_digest); - /** - * calc the digest for s1 - */ + // Calculate the digest for s1 virtual srs_error_t calc_s1_digest(c1s1* owner, char*& s1_digest); - /** - * copy whole c1s1 to bytes. - * @param size must always be 1536 with digest, and 1504 without digest. - */ + // Copy whole c1s1 to bytes. + // @param size must always be 1536 with digest, and 1504 without digest. virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest) = 0; - /** - * copy time and version to stream. - */ + // Copy time and version to stream. virtual void copy_time_version(SrsBuffer* stream, c1s1* owner); - /** - * copy key to stream. - */ + // Copy key to stream. virtual void copy_key(SrsBuffer* stream); - /** - * copy digest to stream. - */ + // Copy digest to stream. virtual void copy_digest(SrsBuffer* stream, bool with_digest); }; - /** - * c1s1 schema0 - * key: 764bytes - * digest: 764bytes - */ + // The c1s1 schema0 + // key: 764bytes + // digest: 764bytes class c1s1_strategy_schema0 : public c1s1_strategy { public: @@ -316,11 +264,9 @@ namespace _srs_internal virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest); }; - /** - * c1s1 schema1 - * digest: 764bytes - * key: 764bytes - */ + // The c1s1 schema1 + // digest: 764bytes + // key: 764bytes class c1s1_strategy_schema1 : public c1s1_strategy { public: @@ -333,19 +279,17 @@ namespace _srs_internal virtual srs_error_t copy_to(c1s1* owner, char* bytes, int size, bool with_digest); }; - /** - * c1s1 schema0 - * time: 4bytes - * version: 4bytes - * key: 764bytes - * digest: 764bytes - * c1s1 schema1 - * time: 4bytes - * version: 4bytes - * digest: 764bytes - * key: 764bytes - * @see also: http://blog.csdn.net/win_lin/article/details/13006803 - */ + // The c1s1 schema0 + // time: 4bytes + // version: 4bytes + // key: 764bytes + // digest: 764bytes + // The c1s1 schema1 + // time: 4bytes + // version: 4bytes + // digest: 764bytes + // key: 764bytes + // @see also: http://blog.csdn.net/win_lin/article/details/13006803 class c1s1 { public: @@ -359,92 +303,72 @@ namespace _srs_internal c1s1(); virtual ~c1s1(); public: - /** - * get the scema. - */ + // Get the scema. virtual srs_schema_type schema(); - /** - * get the digest key. - */ + // Get the digest key. virtual char* get_digest(); - /** - * get the key. - */ + // Get the key. virtual char* get_key(); public: - /** - * copy to bytes. - * @param size, must always be 1536. - */ + // Copy to bytes. + // @param size, must always be 1536. virtual srs_error_t dump(char* _c1s1, int size); - /** - * server: parse the c1s1, discovery the key and digest by schema. - * @param size, must always be 1536. - * use the c1_validate_digest() to valid the digest of c1. - * use the s1_validate_digest() to valid the digest of s1. - */ + // For server: parse the c1s1, discovery the key and digest by schema. + // @param size, must always be 1536. + // use the c1_validate_digest() to valid the digest of c1. + // use the s1_validate_digest() to valid the digest of s1. virtual srs_error_t parse(char* _c1s1, int size, srs_schema_type _schema); public: - /** - * client: create and sign c1 by schema. - * sign the c1, generate the digest. - * calc_c1_digest(c1, schema) { - * get c1s1-joined from c1 by specified schema - * digest-data = HMACsha256(c1s1-joined, FPKey, 30) - * return digest-data; - * } - * random fill 1536bytes c1 // also fill the c1-128bytes-key - * time = time() // c1[0-3] - * version = [0x80, 0x00, 0x07, 0x02] // c1[4-7] - * schema = choose schema0 or schema1 - * digest-data = calc_c1_digest(c1, schema) - * copy digest-data to c1 - */ + // For client: create and sign c1 by schema. + // sign the c1, generate the digest. + // calc_c1_digest(c1, schema) { + // get c1s1-joined from c1 by specified schema + // digest-data = HMACsha256(c1s1-joined, FPKey, 30) + // return digest-data; + // } + // random fill 1536bytes c1 // also fill the c1-128bytes-key + // time = time() // c1[0-3] + // version = [0x80, 0x00, 0x07, 0x02] // c1[4-7] + // schema = choose schema0 or schema1 + // digest-data = calc_c1_digest(c1, schema) + // copy digest-data to c1 virtual srs_error_t c1_create(srs_schema_type _schema); - /** - * server: validate the parsed c1 schema - */ + // For server: validate the parsed c1 schema virtual srs_error_t c1_validate_digest(bool& is_valid); public: - /** - * server: create and sign the s1 from c1. - * // decode c1 try schema0 then schema1 - * c1-digest-data = get-c1-digest-data(schema0) - * if c1-digest-data equals to calc_c1_digest(c1, schema0) { - * c1-key-data = get-c1-key-data(schema0) - * schema = schema0 - * } else { - * c1-digest-data = get-c1-digest-data(schema1) - * if c1-digest-data not equals to calc_c1_digest(c1, schema1) { - * switch to simple handshake. - * return - * } - * c1-key-data = get-c1-key-data(schema1) - * schema = schema1 - * } - * - * // generate s1 - * random fill 1536bytes s1 - * time = time() // c1[0-3] - * version = [0x04, 0x05, 0x00, 0x01] // s1[4-7] - * s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data) - * get c1s1-joined by specified schema - * s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36) - * copy s1-digest-data and s1-key-data to s1. - */ + // For server: create and sign the s1 from c1. + // // decode c1 try schema0 then schema1 + // c1-digest-data = get-c1-digest-data(schema0) + // if c1-digest-data equals to calc_c1_digest(c1, schema0) { + // c1-key-data = get-c1-key-data(schema0) + // schema = schema0 + // } else { + // c1-digest-data = get-c1-digest-data(schema1) + // if c1-digest-data not equals to calc_c1_digest(c1, schema1) { + // switch to simple handshake. + // return + // } + // c1-key-data = get-c1-key-data(schema1) + // schema = schema1 + // } + // + // // Generate s1 + // random fill 1536bytes s1 + // time = time() // c1[0-3] + // version = [0x04, 0x05, 0x00, 0x01] // s1[4-7] + // s1-key-data=shared_key=DH_compute_key(peer_pub_key=c1-key-data) + // get c1s1-joined by specified schema + // s1-digest-data = HMACsha256(c1s1-joined, FMSKey, 36) + // copy s1-digest-data and s1-key-data to s1. virtual srs_error_t s1_create(c1s1* c1); - /** - * server: validate the parsed s1 schema - */ + // For server: validate the parsed s1 schema virtual srs_error_t s1_validate_digest(bool& is_valid); }; - /** - * the c2s2 complex handshake structure. - * random-data: 1504bytes - * digest-data: 32bytes - * @see also: http://blog.csdn.net/win_lin/article/details/13006803 - */ + // The c2s2 complex handshake structure. + // random-data: 1504bytes + // digest-data: 32bytes + // @see also: http://blog.csdn.net/win_lin/article/details/13006803 class c2s2 { public: @@ -454,85 +378,65 @@ namespace _srs_internal c2s2(); virtual ~c2s2(); public: - /** - * copy to bytes. - * @param size, must always be 1536. - */ + // Copy to bytes. + // @param size, must always be 1536. virtual srs_error_t dump(char* _c2s2, int size); - /** - * parse the c2s2 - * @param size, must always be 1536. - */ + // Parse the c2s2 + // @param size, must always be 1536. virtual srs_error_t parse(char* _c2s2, int size); public: - /** - * create c2. - * random fill c2s2 1536 bytes - * - * // client generate C2, or server valid C2 - * temp-key = HMACsha256(s1-digest, FPKey, 62) - * c2-digest-data = HMACsha256(c2-random-data, temp-key, 32) - */ + // Create c2. + // random fill c2s2 1536 bytes + // + // // client generate C2, or server valid C2 + // temp-key = HMACsha256(s1-digest, FPKey, 62) + // c2-digest-data = HMACsha256(c2-random-data, temp-key, 32) virtual srs_error_t c2_create(c1s1* s1); - /** - * validate the c2 from client. - */ + // Validate the c2 from client. virtual srs_error_t c2_validate(c1s1* s1, bool& is_valid); public: - /** - * create s2. - * random fill c2s2 1536 bytes - * - * // server generate S2, or client valid S2 - * temp-key = HMACsha256(c1-digest, FMSKey, 68) - * s2-digest-data = HMACsha256(s2-random-data, temp-key, 32) - */ + // Create s2. + // random fill c2s2 1536 bytes + // + // For server generate S2, or client valid S2 + // temp-key = HMACsha256(c1-digest, FMSKey, 68) + // s2-digest-data = HMACsha256(s2-random-data, temp-key, 32) virtual srs_error_t s2_create(c1s1* c1); - /** - * validate the s2 from server. - */ + // Validate the s2 from server. virtual srs_error_t s2_validate(c1s1* c1, bool& is_valid); }; } -/** - * simple handshake. - * user can try complex handshake first, - * rollback to simple handshake if error ERROR_RTMP_TRY_SIMPLE_HS - */ +// Simple handshake. +// user can try complex handshake first, +// rollback to simple handshake if error ERROR_RTMP_TRY_SIMPLE_HS class SrsSimpleHandshake { public: SrsSimpleHandshake(); virtual ~SrsSimpleHandshake(); public: - /** - * simple handshake. - */ + // Simple handshake. virtual srs_error_t handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io); virtual srs_error_t handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io); }; -/** - * rtmp complex handshake, - * @see also crtmp(crtmpserver) or librtmp, - * @see also: http://blog.csdn.net/win_lin/article/details/13006803 - */ +// Complex handshake, +// @see also crtmp(crtmpserver) or librtmp, +// @see also: http://blog.csdn.net/win_lin/article/details/13006803 class SrsComplexHandshake { public: SrsComplexHandshake(); virtual ~SrsComplexHandshake(); public: - /** - * complex hanshake. - * @return user must: - * continue connect app if success, - * try simple handshake if error is ERROR_RTMP_TRY_SIMPLE_HS, - * otherwise, disconnect - */ + // Complex hanshake. + // @return user must: + // continue connect app if success, + // try simple handshake if error is ERROR_RTMP_TRY_SIMPLE_HS, + // otherwise, disconnect virtual srs_error_t handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io); virtual srs_error_t handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReadWriter* io); }; diff --git a/trunk/src/protocol/srs_rtmp_msg_array.hpp b/trunk/src/protocol/srs_rtmp_msg_array.hpp index 90b67f158..6364829fd 100644 --- a/trunk/src/protocol/srs_rtmp_msg_array.hpp +++ b/trunk/src/protocol/srs_rtmp_msg_array.hpp @@ -28,43 +28,31 @@ class SrsSharedPtrMessage; -/** - * the class to auto free the shared ptr message array. - * when need to get some messages, for instance, from Consumer queue, - * create a message array, whose msgs can used to accept the msgs, - * then send each message and set to NULL. - * - * @remark: user must free all msgs in array, for the SRS2.0 protocol stack - * provides an api to send messages, @see send_and_free_messages - */ +// The class to auto free the shared ptr message array. +// When need to get some messages, for instance, from Consumer queue, +// create a message array, whose msgs can used to accept the msgs, +// then send each message and set to NULL. +// +// @remark: user must free all msgs in array, for the SRS2.0 protocol stack +// provides an api to send messages, @see send_and_free_messages class SrsMessageArray { public: - /** - * when user already send all msgs, please set to NULL, - * for instance, msg= msgs.msgs[i], msgs.msgs[i]=NULL, send(msg), - * where send(msg) will always send and free it. - */ + // When user already send all msgs, please set to NULL, + // for instance, msg= msgs.msgs[i], msgs.msgs[i]=NULL, send(msg), + // where send(msg) will always send and free it. SrsSharedPtrMessage** msgs; int max; public: - /** - * create msg array, initialize array to NULL ptrs. - */ + // Create msg array, initialize array to NULL ptrs. SrsMessageArray(int max_msgs); - /** - * free the msgs not sent out(not NULL). - */ + // Free the msgs not sent out(not NULL). virtual ~SrsMessageArray(); public: - /** - * free specified count of messages. - */ + // Free specified count of messages. virtual void free(int count); private: - /** - * zero initialize the message array. - */ + // Zero initialize the message array. virtual void zero(int count); }; diff --git a/trunk/src/protocol/srs_rtmp_stack.hpp b/trunk/src/protocol/srs_rtmp_stack.hpp index dd4c497bf..0159485fa 100644 --- a/trunk/src/protocol/srs_rtmp_stack.hpp +++ b/trunk/src/protocol/srs_rtmp_stack.hpp @@ -30,7 +30,7 @@ #include #include -// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 +// For srs-librtmp, @see https://github.com/ossrs/srs/issues/213 #ifndef _WIN32 #include #endif @@ -61,12 +61,7 @@ class SrsAmf0Object; class IMergeReadHandler; class SrsCallPacket; -/**************************************************************************** - ***************************************************************************** - ****************************************************************************/ -/** - * amf0 command message, command name macros - */ +// The amf0 command message, command name macros #define RTMP_AMF0_COMMAND_CONNECT "connect" #define RTMP_AMF0_COMMAND_CREATE_STREAM "createStream" #define RTMP_AMF0_COMMAND_CLOSE_STREAM "closeStream" @@ -82,26 +77,22 @@ class SrsCallPacket; #define RTMP_AMF0_COMMAND_PUBLISH "publish" #define RTMP_AMF0_DATA_SAMPLE_ACCESS "|RtmpSampleAccess" -/** - * the signature for packets to client. - */ +// The signature for packets to client. #define RTMP_SIG_FMS_VER "3,5,3,888" #define RTMP_SIG_AMF0_VER 0 #define RTMP_SIG_CLIENT_ID "ASAICiss" -/** - * onStatus consts. - */ +// The onStatus consts. #define StatusLevel "level" #define StatusCode "code" #define StatusDescription "description" #define StatusDetails "details" #define StatusClientId "clientid" -// status value +// The status value #define StatusLevelStatus "status" -// status error +// The status error #define StatusLevelError "error" -// code value +// The code value #define StatusCodeConnectSuccess "NetConnection.Connect.Success" #define StatusCodeConnectRejected "NetConnection.Connect.Rejected" #define StatusCodeStreamReset "NetStream.Play.Reset" @@ -112,69 +103,49 @@ class SrsCallPacket; #define StatusCodeDataStart "NetStream.Data.Start" #define StatusCodeUnpublishSuccess "NetStream.Unpublish.Success" -/**************************************************************************** - ***************************************************************************** - ****************************************************************************/ - -/** - * the decoded message payload. - * @remark we seperate the packet from message, - * for the packet focus on logic and domain data, - * the message bind to the protocol and focus on protocol, such as header. - * we can merge the message and packet, using OOAD hierachy, packet extends from message, - * it's better for me to use components -- the message use the packet as payload. - */ +// The decoded message payload. +// @remark we seperate the packet from message, +// for the packet focus on logic and domain data, +// the message bind to the protocol and focus on protocol, such as header. +// we can merge the message and packet, using OOAD hierachy, packet extends from message, +// it's better for me to use components -- the message use the packet as payload. class SrsPacket { public: SrsPacket(); virtual ~SrsPacket(); public: - /** - * the subpacket can override this encode, - * for example, video and audio will directly set the payload withou memory copy, - * other packet which need to serialize/encode to bytes by override the - * get_size and encode_packet. - */ + // The subpacket can override this encode, + // For example, video and audio will directly set the payload withou memory copy, + // other packet which need to serialize/encode to bytes by override the + // get_size and encode_packet. virtual srs_error_t encode(int& size, char*& payload); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: - /** - * subpacket must override to decode packet from stream. - * @remark never invoke the super.decode, it always failed. - */ + // The subpacket must override to decode packet from stream. + // @remark never invoke the super.decode, it always failed. virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: - /** - * the cid(chunk id) specifies the chunk to send data over. - * generally, each message perfer some cid, for example, - * all protocol control messages perfer RTMP_CID_ProtocolControl, - * SrsSetWindowAckSizePacket is protocol control message. - */ + // The cid(chunk id) specifies the chunk to send data over. + // Generally, each message perfer some cid, for example, + // all protocol control messages perfer RTMP_CID_ProtocolControl, + // SrsSetWindowAckSizePacket is protocol control message. virtual int get_prefer_cid(); - /** - * subpacket must override to provide the right message type. - * the message type set the RTMP message type in header. - */ + // The subpacket must override to provide the right message type. + // The message type set the RTMP message type in header. virtual int get_message_type(); protected: - /** - * subpacket can override to calc the packet size. - */ + // The subpacket can override to calc the packet size. virtual int get_size(); - /** - * subpacket can override to encode the payload to stream. - * @remark never invoke the super.encode_packet, it always failed. - */ + // The subpacket can override to encode the payload to stream. + // @remark never invoke the super.encode_packet, it always failed. virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * the protocol provides the rtmp-message-protocol services, - * to recv RTMP message from RTMP chunk stream, - * and to send out RTMP message over RTMP chunk stream. - */ +// The protocol provides the rtmp-message-protocol services, +// To recv RTMP message from RTMP chunk stream, +// and to send out RTMP message over RTMP chunk stream. class SrsProtocol { private: @@ -189,40 +160,28 @@ private: AckWindowSize(); }; - // peer in/out +// For peer in/out private: - /** - * underlayer socket object, send/recv bytes. - */ + // The underlayer socket object, send/recv bytes. ISrsProtocolReadWriter* skt; - /** - * requests sent out, used to build the response. - * key: transactionId - * value: the request command name - */ + // The requests sent out, used to build the response. + // key: transactionId + // value: the request command name std::map requests; -// peer in +// For peer in private: - /** - * chunk stream to decode RTMP messages. - */ + // The chunk stream to decode RTMP messages. std::map chunk_streams; - /** - * cache some frequently used chunk header. - * cs_cache, the chunk stream cache. - * @see https://github.com/ossrs/srs/issues/249 - */ + // Cache some frequently used chunk header. + // cs_cache, the chunk stream cache. + // @see https://github.com/ossrs/srs/issues/249 SrsChunkStream** cs_cache; - /** - * bytes buffer cache, recv from skt, provide services for stream. - */ + // The bytes buffer cache, recv from skt, provide services for stream. SrsFastStream* in_buffer; - /** - * input chunk size, default to 128, set by peer packet. - */ + // The input chunk size, default to 128, set by peer packet. int32_t in_chunk_size; // The input ack window, to response acknowledge to peer, - // for example, to respose the encoder, for server got lots of packets. + // For example, to respose the encoder, for server got lots of packets. AckWindowSize in_ack_size; // The output ack window, to require peer to response the ack. AckWindowSize out_ack_size; @@ -231,93 +190,69 @@ private: // Whether print the protocol level debug info. // Generally we print the debug info when got or send first A/V packet. bool show_debug_info; - /** - * whether auto response when recv messages. - * default to true for it's very easy to use the protocol stack. - * @see: https://github.com/ossrs/srs/issues/217 - */ + // Whether auto response when recv messages. + // default to true for it's very easy to use the protocol stack. + // @see: https://github.com/ossrs/srs/issues/217 bool auto_response_when_recv; - /** - * when not auto response message, manual flush the messages in queue. - */ + // When not auto response message, manual flush the messages in queue. std::vector manual_response_queue; -// peer out +// For peer out private: - /** - * cache for multiple messages send, - * initialize to iovec[SRS_CONSTS_IOVS_MAX] and realloc when consumed, - * it's ok to realloc the iovs cache, for all ptr is ok. - */ + // Cache for multiple messages send, + // initialize to iovec[SRS_CONSTS_IOVS_MAX] and realloc when consumed, + // it's ok to realloc the iovs cache, for all ptr is ok. iovec* out_iovs; int nb_out_iovs; - /** - * output header cache. - * used for type0, 11bytes(or 15bytes with extended timestamp) header. - * or for type3, 1bytes(or 5bytes with extended timestamp) header. - * the c0c3 caches must use unit SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE bytes. - * - * @remark, the c0c3 cache cannot be realloc. - */ + // The output header cache. + // used for type0, 11bytes(or 15bytes with extended timestamp) header. + // or for type3, 1bytes(or 5bytes with extended timestamp) header. + // The c0c3 caches must use unit SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE bytes. + // + // @remark, the c0c3 cache cannot be realloc. char out_c0c3_caches[SRS_CONSTS_C0C3_HEADERS_MAX]; - // whether warned user to increase the c0c3 header cache. + // Whether warned user to increase the c0c3 header cache. bool warned_c0c3_cache_dry; - /** - * output chunk size, default to 128, set by config. - */ + // The output chunk size, default to 128, set by config. int32_t out_chunk_size; public: SrsProtocol(ISrsProtocolReadWriter* io); virtual ~SrsProtocol(); public: - /** - * set the auto response message when recv for protocol stack. - * @param v, whether auto response message when recv message. - * @see: https://github.com/ossrs/srs/issues/217 - */ + // Set the auto response message when recv for protocol stack. + // @param v, whether auto response message when recv message. + // @see: https://github.com/ossrs/srs/issues/217 virtual void set_auto_response(bool v); - /** - * flush for manual response when the auto response is disabled - * by set_auto_response(false), we default use auto response, so donot - * need to call this api(the protocol sdk will auto send message). - * @see the auto_response_when_recv and manual_response_queue. - */ + // Flush for manual response when the auto response is disabled + // by set_auto_response(false), we default use auto response, so donot + // need to call this api(the protocol sdk will auto send message). + // @see the auto_response_when_recv and manual_response_queue. virtual srs_error_t manual_response_flush(); public: #ifdef SRS_PERF_MERGED_READ - /** - * to improve read performance, merge some packets then read, - * when it on and read small bytes, we sleep to wait more data., - * that is, we merge some data to read together. - * @param v true to ename merged read. - * @param handler the handler when merge read is enabled. - * @see https://github.com/ossrs/srs/issues/241 - */ + // To improve read performance, merge some packets then read, + // When it on and read small bytes, we sleep to wait more data., + // that is, we merge some data to read together. + // @param v true to ename merged read. + // @param handler the handler when merge read is enabled. + // @see https://github.com/ossrs/srs/issues/241 virtual void set_merge_read(bool v, IMergeReadHandler* handler); - /** - * create buffer with specifeid size. - * @param buffer the size of buffer. - * @remark when MR(SRS_PERF_MERGED_READ) disabled, always set to 8K. - * @remark when buffer changed, the previous ptr maybe invalid. - * @see https://github.com/ossrs/srs/issues/241 - */ + // Create buffer with specifeid size. + // @param buffer the size of buffer. + // @remark when MR(SRS_PERF_MERGED_READ) disabled, always set to 8K. + // @remark when buffer changed, the previous ptr maybe invalid. + // @see https://github.com/ossrs/srs/issues/241 virtual void set_recv_buffer(int buffer_size); #endif public: - /** - * set/get the recv timeout in srs_utime_t. - * if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. - */ + // To set/get the recv timeout in srs_utime_t. + // if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. virtual void set_recv_timeout(srs_utime_t tm); virtual srs_utime_t get_recv_timeout(); - /** - * set/get the send timeout in srs_utime_t. - * if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. - */ + // To set/get the send timeout in srs_utime_t. + // if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. virtual void set_send_timeout(srs_utime_t tm); virtual srs_utime_t get_send_timeout(); - /** - * get recv/send bytes. - */ + // Get recv/send bytes. virtual int64_t get_recv_bytes(); virtual int64_t get_send_bytes(); public: @@ -325,70 +260,58 @@ public: // but for some encoder, it never send the ack message while it default to a none zone size. // This will cause the encoder to block after publishing some messages to server, // because it wait for server to send acknowledge, but server default to 0 which means no need - // to ack encoder. We can change the default input ack size. We will always response the + // To ack encoder. We can change the default input ack size. We will always response the // ack size whatever the encoder set or not. virtual srs_error_t set_in_window_ack_size(int ack_size); public: - /** - * recv a RTMP message, which is bytes oriented. - * user can use decode_message to get the decoded RTMP packet. - * @param pmsg, set the received message, - * always NULL if error, - * NULL for unknown packet but return success. - * never NULL if decode success. - * @remark, drop message when msg is empty or payload length is empty. - */ + // Recv a RTMP message, which is bytes oriented. + // user can use decode_message to get the decoded RTMP packet. + // @param pmsg, set the received message, + // always NULL if error, + // NULL for unknown packet but return success. + // never NULL if decode success. + // @remark, drop message when msg is empty or payload length is empty. virtual srs_error_t recv_message(SrsCommonMessage** pmsg); - /** - * decode bytes oriented RTMP message to RTMP packet, - * @param ppacket, output decoded packet, - * always NULL if error, never NULL if success. - * @return error when unknown packet, error when decode failed. - */ + // Decode bytes oriented RTMP message to RTMP packet, + // @param ppacket, output decoded packet, + // always NULL if error, never NULL if success. + // @return error when unknown packet, error when decode failed. virtual srs_error_t decode_message(SrsCommonMessage* msg, SrsPacket** ppacket); - /** - * send the RTMP message and always free it. - * user must never free or use the msg after this method, - * for it will always free the msg. - * @param msg, the msg to send out, never be NULL. - * @param stream_id, the stream id of packet to send over, 0 for control message. - */ + // Send the RTMP message and always free it. + // user must never free or use the msg after this method, + // For it will always free the msg. + // @param msg, the msg to send out, never be NULL. + // @param stream_id, the stream id of packet to send over, 0 for control message. virtual srs_error_t send_and_free_message(SrsSharedPtrMessage* msg, int stream_id); - /** - * send the RTMP message and always free it. - * user must never free or use the msg after this method, - * for it will always free the msg. - * @param msgs, the msgs to send out, never be NULL. - * @param nb_msgs, the size of msgs to send out. - * @param stream_id, the stream id of packet to send over, 0 for control message. - */ + // Send the RTMP message and always free it. + // user must never free or use the msg after this method, + // For it will always free the msg. + // @param msgs, the msgs to send out, never be NULL. + // @param nb_msgs, the size of msgs to send out. + // @param stream_id, the stream id of packet to send over, 0 for control message. virtual srs_error_t send_and_free_messages(SrsSharedPtrMessage** msgs, int nb_msgs, int stream_id); - /** - * send the RTMP packet and always free it. - * user must never free or use the packet after this method, - * for it will always free the packet. - * @param packet, the packet to send out, never be NULL. - * @param stream_id, the stream id of packet to send over, 0 for control message. - */ + // Send the RTMP packet and always free it. + // user must never free or use the packet after this method, + // For it will always free the packet. + // @param packet, the packet to send out, never be NULL. + // @param stream_id, the stream id of packet to send over, 0 for control message. virtual srs_error_t send_and_free_packet(SrsPacket* packet, int stream_id); public: - /** - * expect a specified message, drop others util got specified one. - * @pmsg, user must free it. NULL if not success. - * @ppacket, user must free it, which decode from payload of message. NULL if not success. - * @remark, only when success, user can use and must free the pmsg and ppacket. - * for example: - * SrsCommonMessage* msg = NULL; - * SrsConnectAppResPacket* pkt = NULL; - * if ((ret = protocol->expect_message(protocol, &msg, &pkt)) != ERROR_SUCCESS) { - * return ret; - * } - * // use then free msg and pkt - * srs_freep(msg); - * srs_freep(pkt); - * user should never recv message and convert it, use this method instead. - * if need to set timeout, use set timeout of SrsProtocol. - */ + // Expect a specified message, drop others util got specified one. + // @pmsg, user must free it. NULL if not success. + // @ppacket, user must free it, which decode from payload of message. NULL if not success. + // @remark, only when success, user can use and must free the pmsg and ppacket. + // For example: + // SrsCommonMessage* msg = NULL; + // SrsConnectAppResPacket* pkt = NULL; + // if ((ret = protocol->expect_message(protocol, &msg, &pkt)) != ERROR_SUCCESS) { + // return ret; + // } + // // Use then free msg and pkt + // srs_freep(msg); + // srs_freep(pkt); + // user should never recv message and convert it, use this method instead. + // if need to set timeout, use set timeout of SrsProtocol. template srs_error_t expect_message(SrsCommonMessage** pmsg, T** ppacket) { @@ -425,150 +348,106 @@ public: return err; } private: - /** - * send out the messages, donot free it, - * the caller must free the param msgs. - */ + // Send out the messages, donot free it, + // The caller must free the param msgs. virtual srs_error_t do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs); - /** - * send iovs. send multiple times if exceed limits. - */ + // Send iovs. send multiple times if exceed limits. virtual srs_error_t do_iovs_send(iovec* iovs, int size); - /** - * underlayer api for send and free packet. - */ + // The underlayer api for send and free packet. virtual srs_error_t do_send_and_free_packet(SrsPacket* packet, int stream_id); - /** - * use simple algorithm to send the header and bytes. - * @remark, for do_send_and_free_packet to send. - */ + // Use simple algorithm to send the header and bytes. + // @remark, for do_send_and_free_packet to send. virtual srs_error_t do_simple_send(SrsMessageHeader* mh, char* payload, int size); - /** - * imp for decode_message - */ + // The imp for decode_message virtual srs_error_t do_decode_message(SrsMessageHeader& header, SrsBuffer* stream, SrsPacket** ppacket); - /** - * recv bytes oriented RTMP message from protocol stack. - * return error if error occur and nerver set the pmsg, - * return success and pmsg set to NULL if no entire message got, - * return success and pmsg set to entire message if got one. - */ + // Recv bytes oriented RTMP message from protocol stack. + // return error if error occur and nerver set the pmsg, + // return success and pmsg set to NULL if no entire message got, + // return success and pmsg set to entire message if got one. virtual srs_error_t recv_interlaced_message(SrsCommonMessage** pmsg); - /** - * read the chunk basic header(fmt, cid) from chunk stream. - * user can discovery a SrsChunkStream by cid. - */ + // Read the chunk basic header(fmt, cid) from chunk stream. + // user can discovery a SrsChunkStream by cid. virtual srs_error_t read_basic_header(char& fmt, int& cid); - /** - * read the chunk message header(timestamp, payload_length, message_type, stream_id) - * from chunk stream and save to SrsChunkStream. - */ + // Read the chunk message header(timestamp, payload_length, message_type, stream_id) + // From chunk stream and save to SrsChunkStream. virtual srs_error_t read_message_header(SrsChunkStream* chunk, char fmt); - /** - * read the chunk payload, remove the used bytes in buffer, - * if got entire message, set the pmsg. - */ + // Read the chunk payload, remove the used bytes in buffer, + // if got entire message, set the pmsg. virtual srs_error_t read_message_payload(SrsChunkStream* chunk, SrsCommonMessage** pmsg); - /** - * when recv message, update the context. - */ + // When recv message, update the context. virtual srs_error_t on_recv_message(SrsCommonMessage* msg); - /** - * when message sentout, update the context. - */ + // When message sentout, update the context. virtual srs_error_t on_send_packet(SrsMessageHeader* mh, SrsPacket* packet); private: - /** - * auto response the ack message. - */ + // Auto response the ack message. virtual srs_error_t response_acknowledgement_message(); - /** - * auto response the ping message. - */ + // Auto response the ping message. virtual srs_error_t response_ping_message(int32_t timestamp); private: virtual void print_debug_info(); }; -/** - * incoming chunk stream maybe interlaced, - * use the chunk stream to cache the input RTMP chunk streams. - */ +// incoming chunk stream maybe interlaced, +// Use the chunk stream to cache the input RTMP chunk streams. class SrsChunkStream { public: - /** - * represents the basic header fmt, - * which used to identify the variant message header type. - */ + // Represents the basic header fmt, + // which used to identify the variant message header type. char fmt; - /** - * represents the basic header cid, - * which is the chunk stream id. - */ + // Represents the basic header cid, + // which is the chunk stream id. int cid; - /** - * cached message header - */ + // Cached message header SrsMessageHeader header; - /** - * whether the chunk message header has extended timestamp. - */ + // Whether the chunk message header has extended timestamp. bool extended_timestamp; - /** - * partially read message. - */ + // The partially read message. SrsCommonMessage* msg; - /** - * decoded msg count, to identify whether the chunk stream is fresh. - */ + // Decoded msg count, to identify whether the chunk stream is fresh. int64_t msg_count; public: SrsChunkStream(int _cid); virtual ~SrsChunkStream(); }; -/** - * the original request from client. - */ +// The original request from client. class SrsRequest { public: - // client ip. + // The client ip. std::string ip; public: - /** - * tcUrl: rtmp://request_vhost:port/app/stream - * support pass vhost in query string, such as: - * rtmp://ip:port/app?vhost=request_vhost/stream - * rtmp://ip:port/app...vhost...request_vhost/stream - */ + // The tcUrl: rtmp://request_vhost:port/app/stream + // support pass vhost in query string, such as: + // rtmp://ip:port/app?vhost=request_vhost/stream + // rtmp://ip:port/app...vhost...request_vhost/stream std::string tcUrl; std::string pageUrl; std::string swfUrl; double objectEncoding; - // data discovery from request. +// The data discovery from request. public: - // discovery from tcUrl and play/publish. + // Discovery from tcUrl and play/publish. std::string schema; - // the vhost in tcUrl. + // The vhost in tcUrl. std::string vhost; - // the host in tcUrl. + // The host in tcUrl. std::string host; - // the port in tcUrl. + // The port in tcUrl. int port; - // the app in tcUrl, without param. + // The app in tcUrl, without param. std::string app; - // the param in tcUrl(app). + // The param in tcUrl(app). std::string param; - // the stream in play/publish + // The stream in play/publish std::string stream; - // for play live stream, + // For play live stream, // used to specified the stop when exceed the duration. // @see https://github.com/ossrs/srs/issues/45 // in srs_utime_t. srs_utime_t duration; - // the token in the connect request, + // The token in the connect request, // used for edge traverse to origin authentication, // @see https://github.com/ossrs/srs/issues/104 SrsAmf0Object* args; @@ -576,49 +455,35 @@ public: SrsRequest(); virtual ~SrsRequest(); public: - /** - * deep copy the request, for source to use it to support reload, - * for when initialize the source, the request is valid, - * when reload it, the request maybe invalid, so need to copy it. - */ + // Deep copy the request, for source to use it to support reload, + // For when initialize the source, the request is valid, + // When reload it, the request maybe invalid, so need to copy it. virtual SrsRequest* copy(); - /** - * update the auth info of request, - * to keep the current request ptr is ok, - * for many components use the ptr of request. - */ + // update the auth info of request, + // To keep the current request ptr is ok, + // For many components use the ptr of request. virtual void update_auth(SrsRequest* req); - /** - * get the stream identify, vhost/app/stream. - */ + // Get the stream identify, vhost/app/stream. virtual std::string get_stream_url(); - /** - * strip url, user must strip when update the url. - */ + // To strip url, user must strip when update the url. virtual void strip(); public: // Transform it as HTTP request. virtual SrsRequest* as_http(); }; -/** - * the response to client. - */ +// The response to client. class SrsResponse { public: - /** - * the stream id to response client createStream. - */ + // The stream id to response client createStream. int stream_id; public: SrsResponse(); virtual ~SrsResponse(); }; -/** - * the rtmp client type. - */ +// The rtmp client type. enum SrsRtmpConnType { SrsRtmpConnUnknown, @@ -630,10 +495,8 @@ enum SrsRtmpConnType std::string srs_client_type_string(SrsRtmpConnType type); bool srs_client_type_is_publish(SrsRtmpConnType type); -/** - * store the handshake bytes, - * for smart switch between complex and simple handshake. - */ +// store the handshake bytes, +// For smart switch between complex and simple handshake. class SrsHandshakeBytes { public: @@ -655,9 +518,7 @@ public: virtual srs_error_t create_c2(); }; -/** - * The information return from RTMP server. - */ +// The information return from RTMP server. struct SrsServerInfo { std::string ip; @@ -672,9 +533,7 @@ struct SrsServerInfo SrsServerInfo(); }; -/** - * implements the client role protocol. - */ +// implements the client role protocol. class SrsRtmpClient { private: @@ -685,7 +544,7 @@ protected: public: SrsRtmpClient(ISrsProtocolReadWriter* skt); virtual ~SrsRtmpClient(); -// protocol methods proxy +// Protocol methods proxy public: virtual void set_recv_timeout(srs_utime_t tm); virtual void set_send_timeout(srs_utime_t tm); @@ -697,64 +556,46 @@ public: virtual srs_error_t send_and_free_messages(SrsSharedPtrMessage** msgs, int nb_msgs, int stream_id); virtual srs_error_t send_and_free_packet(SrsPacket* packet, int stream_id); public: - /** - * handshake with server, try complex, then simple handshake. - */ + // handshake with server, try complex, then simple handshake. virtual srs_error_t handshake(); - /** - * only use simple handshake - */ + // only use simple handshake virtual srs_error_t simple_handshake(); - /** - * only use complex handshake - */ + // only use complex handshake virtual srs_error_t complex_handshake(); - /** - * Connect to RTMP tcUrl and app, get the server info. - * - * @param app, The app to connect at, for example, live. - * @param tcUrl, The tcUrl to connect at, for example, rtmp://ossrs.net/live. - * @param req, the optional req object, use the swfUrl/pageUrl if specified. NULL to ignore. - * @param dsu, Whether debug SRS upnode. For edge, set to true to send its info to upnode. - * @param si, The server information, retrieve from response of connect app request. NULL to ignore. - */ + // Connect to RTMP tcUrl and app, get the server info. + // + // @param app, The app to connect at, for example, live. + // @param tcUrl, The tcUrl to connect at, for example, rtmp://ossrs.net/live. + // @param req, the optional req object, use the swfUrl/pageUrl if specified. NULL to ignore. + // @param dsu, Whether debug SRS upnode. For edge, set to true to send its info to upnode. + // @param si, The server information, retrieve from response of connect app request. NULL to ignore. virtual srs_error_t connect_app(std::string app, std::string tcUrl, SrsRequest* r, bool dsu, SrsServerInfo* si); - /** - * create a stream, then play/publish data over this stream. - */ + // Create a stream, then play/publish data over this stream. virtual srs_error_t create_stream(int& stream_id); - /** - * start play stream. - */ + // start play stream. virtual srs_error_t play(std::string stream, int stream_id, int chunk_size); - /** - * start publish stream. use flash publish workflow: - * connect-app => create-stream => flash-publish - */ + // start publish stream. use flash publish workflow: + // connect-app => create-stream => flash-publish virtual srs_error_t publish(std::string stream, int stream_id, int chunk_size); - /** - * start publish stream. use FMLE publish workflow: - * connect-app => FMLE publish - */ + // start publish stream. use FMLE publish workflow: + // connect-app => FMLE publish virtual srs_error_t fmle_publish(std::string stream, int& stream_id); public: - /** - * expect a specified message, drop others util got specified one. - * @pmsg, user must free it. NULL if not success. - * @ppacket, user must free it, which decode from payload of message. NULL if not success. - * @remark, only when success, user can use and must free the pmsg and ppacket. - * for example: - * SrsCommonMessage* msg = NULL; - * SrsConnectAppResPacket* pkt = NULL; - * if ((ret = client->expect_message(protocol, &msg, &pkt)) != ERROR_SUCCESS) { - * return ret; - * } - * // use then free msg and pkt - * srs_freep(msg); - * srs_freep(pkt); - * user should never recv message and convert it, use this method instead. - * if need to set timeout, use set timeout of SrsProtocol. - */ + // Expect a specified message, drop others util got specified one. + // @pmsg, user must free it. NULL if not success. + // @ppacket, user must free it, which decode from payload of message. NULL if not success. + // @remark, only when success, user can use and must free the pmsg and ppacket. + // For example: + // SrsCommonMessage* msg = NULL; + // SrsConnectAppResPacket* pkt = NULL; + // if ((ret = client->expect_message(protocol, &msg, &pkt)) != ERROR_SUCCESS) { + // return ret; + // } + // // Use then free msg and pkt + // srs_freep(msg); + // srs_freep(pkt); + // user should never recv message and convert it, use this method instead. + // if need to set timeout, use set timeout of SrsProtocol. template srs_error_t expect_message(SrsCommonMessage** pmsg, T** ppacket) { @@ -762,11 +603,9 @@ public: } }; -/** - * the rtmp provices rtmp-command-protocol services, - * a high level protocol, media stream oriented services, - * such as connect to vhost/app, play stream, get audio/video data. - */ +// The rtmp provices rtmp-command-protocol services, +// a high level protocol, media stream oriented services, +// such as connect to vhost/app, play stream, get audio/video data. class SrsRtmpServer { private: @@ -776,207 +615,151 @@ private: public: SrsRtmpServer(ISrsProtocolReadWriter* skt); virtual ~SrsRtmpServer(); -// protocol methods proxy +// Protocol methods proxy public: - /** - * set the auto response message when recv for protocol stack. - * @param v, whether auto response message when recv message. - * @see: https://github.com/ossrs/srs/issues/217 - */ + // Set the auto response message when recv for protocol stack. + // @param v, whether auto response message when recv message. + // @see: https://github.com/ossrs/srs/issues/217 virtual void set_auto_response(bool v); #ifdef SRS_PERF_MERGED_READ - /** - * to improve read performance, merge some packets then read, - * when it on and read small bytes, we sleep to wait more data., - * that is, we merge some data to read together. - * @param v true to ename merged read. - * @param handler the handler when merge read is enabled. - * @see https://github.com/ossrs/srs/issues/241 - */ + // To improve read performance, merge some packets then read, + // When it on and read small bytes, we sleep to wait more data., + // that is, we merge some data to read together. + // @param v true to ename merged read. + // @param handler the handler when merge read is enabled. + // @see https://github.com/ossrs/srs/issues/241 virtual void set_merge_read(bool v, IMergeReadHandler* handler); - /** - * create buffer with specifeid size. - * @param buffer the size of buffer. - * @remark when MR(SRS_PERF_MERGED_READ) disabled, always set to 8K. - * @remark when buffer changed, the previous ptr maybe invalid. - * @see https://github.com/ossrs/srs/issues/241 - */ + // Create buffer with specifeid size. + // @param buffer the size of buffer. + // @remark when MR(SRS_PERF_MERGED_READ) disabled, always set to 8K. + // @remark when buffer changed, the previous ptr maybe invalid. + // @see https://github.com/ossrs/srs/issues/241 virtual void set_recv_buffer(int buffer_size); #endif - /** - * set/get the recv timeout in srs_utime_t. - * if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. - */ + // To set/get the recv timeout in srs_utime_t. + // if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. virtual void set_recv_timeout(srs_utime_t tm); virtual srs_utime_t get_recv_timeout(); - /** - * set/get the send timeout in srs_utime_t. - * if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. - */ + // To set/get the send timeout in srs_utime_t. + // if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. virtual void set_send_timeout(srs_utime_t tm); virtual srs_utime_t get_send_timeout(); - /** - * get recv/send bytes. - */ + // Get recv/send bytes. virtual int64_t get_recv_bytes(); virtual int64_t get_send_bytes(); - /** - * recv a RTMP message, which is bytes oriented. - * user can use decode_message to get the decoded RTMP packet. - * @param pmsg, set the received message, - * always NULL if error, - * NULL for unknown packet but return success. - * never NULL if decode success. - * @remark, drop message when msg is empty or payload length is empty. - */ + // Recv a RTMP message, which is bytes oriented. + // user can use decode_message to get the decoded RTMP packet. + // @param pmsg, set the received message, + // always NULL if error, + // NULL for unknown packet but return success. + // never NULL if decode success. + // @remark, drop message when msg is empty or payload length is empty. virtual srs_error_t recv_message(SrsCommonMessage** pmsg); - /** - * decode bytes oriented RTMP message to RTMP packet, - * @param ppacket, output decoded packet, - * always NULL if error, never NULL if success. - * @return error when unknown packet, error when decode failed. - */ + // Decode bytes oriented RTMP message to RTMP packet, + // @param ppacket, output decoded packet, + // always NULL if error, never NULL if success. + // @return error when unknown packet, error when decode failed. virtual srs_error_t decode_message(SrsCommonMessage* msg, SrsPacket** ppacket); - /** - * send the RTMP message and always free it. - * user must never free or use the msg after this method, - * for it will always free the msg. - * @param msg, the msg to send out, never be NULL. - * @param stream_id, the stream id of packet to send over, 0 for control message. - */ + // Send the RTMP message and always free it. + // user must never free or use the msg after this method, + // For it will always free the msg. + // @param msg, the msg to send out, never be NULL. + // @param stream_id, the stream id of packet to send over, 0 for control message. virtual srs_error_t send_and_free_message(SrsSharedPtrMessage* msg, int stream_id); - /** - * send the RTMP message and always free it. - * user must never free or use the msg after this method, - * for it will always free the msg. - * @param msgs, the msgs to send out, never be NULL. - * @param nb_msgs, the size of msgs to send out. - * @param stream_id, the stream id of packet to send over, 0 for control message. - * - * @remark performance issue, to support 6k+ 250kbps client, - * @see https://github.com/ossrs/srs/issues/194 - */ + // Send the RTMP message and always free it. + // user must never free or use the msg after this method, + // For it will always free the msg. + // @param msgs, the msgs to send out, never be NULL. + // @param nb_msgs, the size of msgs to send out. + // @param stream_id, the stream id of packet to send over, 0 for control message. + // + // @remark performance issue, to support 6k+ 250kbps client, + // @see https://github.com/ossrs/srs/issues/194 virtual srs_error_t send_and_free_messages(SrsSharedPtrMessage** msgs, int nb_msgs, int stream_id); - /** - * send the RTMP packet and always free it. - * user must never free or use the packet after this method, - * for it will always free the packet. - * @param packet, the packet to send out, never be NULL. - * @param stream_id, the stream id of packet to send over, 0 for control message. - */ + // Send the RTMP packet and always free it. + // user must never free or use the packet after this method, + // For it will always free the packet. + // @param packet, the packet to send out, never be NULL. + // @param stream_id, the stream id of packet to send over, 0 for control message. virtual srs_error_t send_and_free_packet(SrsPacket* packet, int stream_id); public: - /** - * handshake with client, try complex then simple. - */ + // Do handshake with client, try complex then simple. virtual srs_error_t handshake(); - /** - * do connect app with client, to discovery tcUrl. - */ + // Do connect app with client, to discovery tcUrl. virtual srs_error_t connect_app(SrsRequest* req); - /** - * set output ack size to client, client will send ack-size for each ack window - */ + // Set output ack size to client, client will send ack-size for each ack window virtual srs_error_t set_window_ack_size(int ack_size); // Set the default input ack size value. virtual srs_error_t set_in_window_ack_size(int ack_size); - /** - * @type: The sender can mark this message hard (0), soft (1), or dynamic (2) - * using the Limit type field. - */ + // @type: The sender can mark this message hard (0), soft (1), or dynamic (2) + // using the Limit type field. virtual srs_error_t set_peer_bandwidth(int bandwidth, int type); - /** - * @param server_ip the ip of server. - */ + // @param server_ip the ip of server. virtual srs_error_t response_connect_app(SrsRequest* req, const char* server_ip = NULL); - /** - * redirect the connection to another rtmp server. - * @param the hostname or ip of target. - * @param whether the client accept the redirect. - */ + // Redirect the connection to another rtmp server. + // @param the hostname or ip of target. + // @param whether the client accept the redirect. virtual srs_error_t redirect(SrsRequest* r, std::string host, int port, bool& accepted); - /** - * reject the connect app request. - */ + // Reject the connect app request. virtual void response_connect_reject(SrsRequest* req, const char* desc); - /** - * response client the onBWDone message. - */ + // Response client the onBWDone message. virtual srs_error_t on_bw_done(); - /** - * recv some message to identify the client. - * @stream_id, client will createStream to play or publish by flash, - * the stream_id used to response the createStream request. - * @type, output the client type. - * @stream_name, output the client publish/play stream name. @see: SrsRequest.stream - * @duration, output the play client duration. @see: SrsRequest.duration - */ + // Recv some message to identify the client. + // @stream_id, client will createStream to play or publish by flash, + // the stream_id used to response the createStream request. + // @type, output the client type. + // @stream_name, output the client publish/play stream name. @see: SrsRequest.stream + // @duration, output the play client duration. @see: SrsRequest.duration virtual srs_error_t identify_client(int stream_id, SrsRtmpConnType& type, std::string& stream_name, srs_utime_t& duration); - /** - * set the chunk size when client type identified. - */ + // Set the chunk size when client type identified. virtual srs_error_t set_chunk_size(int chunk_size); - /** - * when client type is play, response with packets: - * StreamBegin, - * onStatus(NetStream.Play.Reset), onStatus(NetStream.Play.Start)., - * |RtmpSampleAccess(false, false), - * onStatus(NetStream.Data.Start). - */ + // When client type is play, response with packets: + // StreamBegin, + // onStatus(NetStream.Play.Reset), onStatus(NetStream.Play.Start)., + // |RtmpSampleAccess(false, false), + // onStatus(NetStream.Data.Start). virtual srs_error_t start_play(int stream_id); - /** - * when client(type is play) send pause message, - * if is_pause, response the following packets: - * onStatus(NetStream.Pause.Notify) - * StreamEOF - * if not is_pause, response the following packets: - * onStatus(NetStream.Unpause.Notify) - * StreamBegin - */ + // When client(type is play) send pause message, + // if is_pause, response the following packets: + // onStatus(NetStream.Pause.Notify) + // StreamEOF + // if not is_pause, response the following packets: + // onStatus(NetStream.Unpause.Notify) + // StreamBegin virtual srs_error_t on_play_client_pause(int stream_id, bool is_pause); - /** - * when client type is publish, response with packets: - * releaseStream response - * FCPublish - * FCPublish response - * createStream response - * onFCPublish(NetStream.Publish.Start) - * onStatus(NetStream.Publish.Start) - */ + // When client type is publish, response with packets: + // releaseStream response + // FCPublish + // FCPublish response + // createStream response + // onFCPublish(NetStream.Publish.Start) + // onStatus(NetStream.Publish.Start) virtual srs_error_t start_fmle_publish(int stream_id); - /** - * For encoder of Haivision, response the startup request. - * @see https://github.com/ossrs/srs/issues/844 - */ + // For encoder of Haivision, response the startup request. + // @see https://github.com/ossrs/srs/issues/844 virtual srs_error_t start_haivision_publish(int stream_id); - /** - * process the FMLE unpublish event. - * @unpublish_tid the unpublish request transaction id. - */ + // process the FMLE unpublish event. + // @unpublish_tid the unpublish request transaction id. virtual srs_error_t fmle_unpublish(int stream_id, double unpublish_tid); - /** - * when client type is publish, response with packets: - * onStatus(NetStream.Publish.Start) - */ + // When client type is publish, response with packets: + // onStatus(NetStream.Publish.Start) virtual srs_error_t start_flash_publish(int stream_id); public: - /** - * expect a specified message, drop others util got specified one. - * @pmsg, user must free it. NULL if not success. - * @ppacket, user must free it, which decode from payload of message. NULL if not success. - * @remark, only when success, user can use and must free the pmsg and ppacket. - * for example: - * SrsCommonMessage* msg = NULL; - * SrsConnectAppResPacket* pkt = NULL; - * if ((ret = server->expect_message(&msg, &pkt)) != ERROR_SUCCESS) { - * return ret; - * } - * // use then free msg and pkt - * srs_freep(msg); - * srs_freep(pkt); - * user should never recv message and convert it, use this method instead. - * if need to set timeout, use set timeout of SrsProtocol. - */ + // Expect a specified message, drop others util got specified one. + // @pmsg, user must free it. NULL if not success. + // @ppacket, user must free it, which decode from payload of message. NULL if not success. + // @remark, only when success, user can use and must free the pmsg and ppacket. + // For example: + // SrsCommonMessage* msg = NULL; + // SrsConnectAppResPacket* pkt = NULL; + // if ((ret = server->expect_message(&msg, &pkt)) != ERROR_SUCCESS) { + // return ret; + // } + // // Use then free msg and pkt + // srs_freep(msg); + // srs_freep(pkt); + // user should never recv message and convert it, use this method instead. + // if need to set timeout, use set timeout of SrsProtocol. template srs_error_t expect_message(SrsCommonMessage** pmsg, T** ppacket) { @@ -991,41 +774,31 @@ private: virtual srs_error_t identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& type, std::string& stream_name, srs_utime_t& duration); }; -/** - * 4.1.1. connect - * The client sends the connect command to the server to request - * connection to a server application instance. - */ +// 4.1.1. connect +// The client sends the connect command to the server to request +// connection to a server application instance. class SrsConnectAppPacket : public SrsPacket { public: - /** - * Name of the command. Set to "connect". - */ + // Name of the command. Set to "connect". std::string command_name; - /** - * Always set to 1. - */ + // Always set to 1. double transaction_id; - /** - * Command information object which has the name-value pairs. - * @remark: alloc in packet constructor, user can directly use it, - * user should never alloc it again which will cause memory leak. - * @remark, never be NULL. - */ + // Command information object which has the name-value pairs. + // @remark: alloc in packet constructor, user can directly use it, + // user should never alloc it again which will cause memory leak. + // @remark, never be NULL. SrsAmf0Object* command_object; - /** - * Any optional information - * @remark, optional, init to and maybe NULL. - */ + // Any optional information + // @remark, optional, init to and maybe NULL. SrsAmf0Object* args; public: SrsConnectAppPacket(); virtual ~SrsConnectAppPacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1033,38 +806,28 @@ protected: virtual int get_size(); virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * response for SrsConnectAppPacket. - */ +// Response for SrsConnectAppPacket. class SrsConnectAppResPacket : public SrsPacket { public: - /** - * _result or _error; indicates whether the response is result or error. - */ + // The _result or _error; indicates whether the response is result or error. std::string command_name; - /** - * Transaction ID is 1 for call connect responses - */ + // Transaction ID is 1 for call connect responses double transaction_id; - /** - * Name-value pairs that describe the properties(fmsver etc.) of the connection. - * @remark, never be NULL. - */ + // Name-value pairs that describe the properties(fmsver etc.) of the connection. + // @remark, never be NULL. SrsAmf0Object* props; - /** - * Name-value pairs that describe the response from|the server. 'code', - * 'level', 'description' are names of few among such information. - * @remark, never be NULL. - */ + // Name-value pairs that describe the response from|the server. 'code', + // 'level', 'description' are names of few among such information. + // @remark, never be NULL. SrsAmf0Object* info; public: SrsConnectAppResPacket(); virtual ~SrsConnectAppResPacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1073,41 +836,31 @@ protected: virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * 4.1.2. Call - * The call method of the NetConnection object runs remote procedure - * calls (RPC) at the receiving end. The called RPC name is passed as a - * parameter to the call command. - */ +// 4.1.2. Call +// The call method of the NetConnection object runs remote procedure +// calls (RPC) at the receiving end. The called RPC name is passed as a +// parameter to the call command. class SrsCallPacket : public SrsPacket { public: - /** - * Name of the remote procedure that is called. - */ + // Name of the remote procedure that is called. std::string command_name; - /** - * If a response is expected we give a transaction Id. Else we pass a value of 0 - */ + // If a response is expected we give a transaction Id. Else we pass a value of 0 double transaction_id; - /** - * If there exists any command info this - * is set, else this is set to null type. - * @remark, optional, init to and maybe NULL. - */ + // If there exists any command info this + // is set, else this is set to null type. + // @remark, optional, init to and maybe NULL. SrsAmf0Any* command_object; - /** - * Any optional arguments to be provided - * @remark, optional, init to and maybe NULL. - */ + // Any optional arguments to be provided + // @remark, optional, init to and maybe NULL. SrsAmf0Any* arguments; public: SrsCallPacket(); virtual ~SrsCallPacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1115,34 +868,24 @@ protected: virtual int get_size(); virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * response for SrsCallPacket. - */ +// Response for SrsCallPacket. class SrsCallResPacket : public SrsPacket { public: - /** - * Name of the command. - */ + // Name of the command. std::string command_name; - /** - * ID of the command, to which the response belongs to - */ + // ID of the command, to which the response belongs to double transaction_id; - /** - * If there exists any command info this is set, else this is set to null type. - * @remark, optional, init to and maybe NULL. - */ + // If there exists any command info this is set, else this is set to null type. + // @remark, optional, init to and maybe NULL. SrsAmf0Any* command_object; - /** - * Response from the method that was called. - * @remark, optional, init to and maybe NULL. - */ + // Response from the method that was called. + // @remark, optional, init to and maybe NULL. SrsAmf0Any* response; public: SrsCallResPacket(double _transaction_id); virtual ~SrsCallResPacket(); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1151,36 +894,28 @@ protected: virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * 4.1.3. createStream - * The client sends this command to the server to create a logical - * channel for message communication The publishing of audio, video, and - * metadata is carried out over stream channel created using the - * createStream command. - */ +// 4.1.3. createStream +// The client sends this command to the server to create a logical +// channel for message communication The publishing of audio, video, and +// metadata is carried out over stream channel created using the +// createStream command. class SrsCreateStreamPacket : public SrsPacket { public: - /** - * Name of the command. Set to "createStream". - */ + // Name of the command. Set to "createStream". std::string command_name; - /** - * Transaction ID of the command. - */ + // Transaction ID of the command. double transaction_id; - /** - * If there exists any command info this is set, else this is set to null type. - * @remark, never be NULL, an AMF0 null instance. - */ + // If there exists any command info this is set, else this is set to null type. + // @remark, never be NULL, an AMF0 null instance. SrsAmf0Any* command_object; // null public: SrsCreateStreamPacket(); virtual ~SrsCreateStreamPacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1188,36 +923,26 @@ protected: virtual int get_size(); virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * response for SrsCreateStreamPacket. - */ +// Response for SrsCreateStreamPacket. class SrsCreateStreamResPacket : public SrsPacket { public: - /** - * _result or _error; indicates whether the response is result or error. - */ + // The _result or _error; indicates whether the response is result or error. std::string command_name; - /** - * ID of the command that response belongs to. - */ + // ID of the command that response belongs to. double transaction_id; - /** - * If there exists any command info this is set, else this is set to null type. - * @remark, never be NULL, an AMF0 null instance. - */ + // If there exists any command info this is set, else this is set to null type. + // @remark, never be NULL, an AMF0 null instance. SrsAmf0Any* command_object; // null - /** - * The return value is either a stream ID or an error information object. - */ + // The return value is either a stream ID or an error information object. double stream_id; public: SrsCreateStreamResPacket(double _transaction_id, double _stream_id); virtual ~SrsCreateStreamResPacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1226,105 +951,77 @@ protected: virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * client close stream packet. - */ +// client close stream packet. class SrsCloseStreamPacket : public SrsPacket { public: - /** - * Name of the command, set to "closeStream". - */ + // Name of the command, set to "closeStream". std::string command_name; - /** - * Transaction ID set to 0. - */ + // Transaction ID set to 0. double transaction_id; - /** - * Command information object does not exist. Set to null type. - * @remark, never be NULL, an AMF0 null instance. - */ + // Command information object does not exist. Set to null type. + // @remark, never be NULL, an AMF0 null instance. SrsAmf0Any* command_object; // null public: SrsCloseStreamPacket(); virtual ~SrsCloseStreamPacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); }; -/** - * FMLE start publish: ReleaseStream/PublishStream/FCPublish/FCUnpublish - */ +// FMLE start publish: ReleaseStream/PublishStream/FCPublish/FCUnpublish class SrsFMLEStartPacket : public SrsPacket { public: - /** - * Name of the command - */ + // Name of the command std::string command_name; - /** - * the transaction ID to get the response. - */ + // The transaction ID to get the response. double transaction_id; - /** - * If there exists any command info this is set, else this is set to null type. - * @remark, never be NULL, an AMF0 null instance. - */ + // If there exists any command info this is set, else this is set to null type. + // @remark, never be NULL, an AMF0 null instance. SrsAmf0Any* command_object; // null - /** - * the stream name to start publish or release. - */ + // The stream name to start publish or release. std::string stream_name; public: SrsFMLEStartPacket(); virtual ~SrsFMLEStartPacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); protected: virtual int get_size(); virtual srs_error_t encode_packet(SrsBuffer* stream); -// factory method to create specified FMLE packet. +// Factory method to create specified FMLE packet. public: static SrsFMLEStartPacket* create_release_stream(std::string stream); static SrsFMLEStartPacket* create_FC_publish(std::string stream); }; -/** - * response for SrsFMLEStartPacket. - */ +// Response for SrsFMLEStartPacket. class SrsFMLEStartResPacket : public SrsPacket { public: - /** - * Name of the command - */ + // Name of the command std::string command_name; - /** - * the transaction ID to get the response. - */ + // The transaction ID to get the response. double transaction_id; - /** - * If there exists any command info this is set, else this is set to null type. - * @remark, never be NULL, an AMF0 null instance. - */ + // If there exists any command info this is set, else this is set to null type. + // @remark, never be NULL, an AMF0 null instance. SrsAmf0Any* command_object; // null - /** - * the optional args, set to undefined. - * @remark, never be NULL, an AMF0 undefined instance. - */ + // The optional args, set to undefined. + // @remark, never be NULL, an AMF0 undefined instance. SrsAmf0Any* args; // undefined public: SrsFMLEStartResPacket(double _transaction_id); virtual ~SrsFMLEStartResPacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1333,53 +1030,41 @@ protected: virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * FMLE/flash publish - * 4.2.6. Publish - * The client sends the publish command to publish a named stream to the - * server. Using this name, any client can play this stream and receive - * the published audio, video, and data messages. - */ +// FMLE/flash publish +// 4.2.6. Publish +// The client sends the publish command to publish a named stream to the +// server. Using this name, any client can play this stream and receive +// The published audio, video, and data messages. class SrsPublishPacket : public SrsPacket { public: - /** - * Name of the command, set to "publish". - */ + // Name of the command, set to "publish". std::string command_name; - /** - * Transaction ID set to 0. - */ + // Transaction ID set to 0. double transaction_id; - /** - * Command information object does not exist. Set to null type. - * @remark, never be NULL, an AMF0 null instance. - */ + // Command information object does not exist. Set to null type. + // @remark, never be NULL, an AMF0 null instance. SrsAmf0Any* command_object; // null - /** - * Name with which the stream is published. - */ + // Name with which the stream is published. std::string stream_name; - /** - * Type of publishing. Set to "live", "record", or "append". - * record: The stream is published and the data is recorded to a new file.The file - * is stored on the server in a subdirectory within the directory that - * contains the server application. If the file already exists, it is - * overwritten. - * append: The stream is published and the data is appended to a file. If no file - * is found, it is created. - * live: Live data is published without recording it in a file. - * @remark, SRS only support live. - * @remark, optional, default to live. - */ + // Type of publishing. Set to "live", "record", or "append". + // record: The stream is published and the data is recorded to a new file.The file + // is stored on the server in a subdirectory within the directory that + // contains the server application. If the file already exists, it is + // overwritten. + // append: The stream is published and the data is appended to a file. If no file + // is found, it is created. + // live: Live data is published without recording it in a file. + // @remark, SRS only support live. + // @remark, optional, default to live. std::string type; public: SrsPublishPacket(); virtual ~SrsPublishPacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1388,117 +1073,89 @@ protected: virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * 4.2.8. pause - * The client sends the pause command to tell the server to pause or - * start playing. - */ +// 4.2.8. pause +// The client sends the pause command to tell the server to pause or +// start playing. class SrsPausePacket : public SrsPacket { public: - /** - * Name of the command, set to "pause". - */ + // Name of the command, set to "pause". std::string command_name; - /** - * There is no transaction ID for this command. Set to 0. - */ + // There is no transaction ID for this command. Set to 0. double transaction_id; - /** - * Command information object does not exist. Set to null type. - * @remark, never be NULL, an AMF0 null instance. - */ + // Command information object does not exist. Set to null type. + // @remark, never be NULL, an AMF0 null instance. SrsAmf0Any* command_object; // null - /** - * true or false, to indicate pausing or resuming play - */ + // true or false, to indicate pausing or resuming play bool is_pause; - /** - * Number of milliseconds at which the the stream is paused or play resumed. - * This is the current stream time at the Client when stream was paused. When the - * playback is resumed, the server will only send messages with timestamps - * greater than this value. - */ + // Number of milliseconds at which the the stream is paused or play resumed. + // This is the current stream time at the Client when stream was paused. When the + // playback is resumed, the server will only send messages with timestamps + // greater than this value. double time_ms; public: SrsPausePacket(); virtual ~SrsPausePacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); }; -/** - * 4.2.1. play - * The client sends this command to the server to play a stream. - */ +// 4.2.1. play +// The client sends this command to the server to play a stream. class SrsPlayPacket : public SrsPacket { public: - /** - * Name of the command. Set to "play". - */ + // Name of the command. Set to "play". std::string command_name; - /** - * Transaction ID set to 0. - */ + // Transaction ID set to 0. double transaction_id; - /** - * Command information does not exist. Set to null type. - * @remark, never be NULL, an AMF0 null instance. - */ + // Command information does not exist. Set to null type. + // @remark, never be NULL, an AMF0 null instance. SrsAmf0Any* command_object; // null - /** - * Name of the stream to play. - * To play video (FLV) files, specify the name of the stream without a file - * extension (for example, "sample"). - * To play back MP3 or ID3 tags, you must precede the stream name with mp3: - * (for example, "mp3:sample".) - * To play H.264/AAC files, you must precede the stream name with mp4: and specify the - * file extension. For example, to play the file sample.m4v, specify - * "mp4:sample.m4v" - */ + // Name of the stream to play. + // To play video (FLV) files, specify the name of the stream without a file + // extension (for example, "sample"). + // To play back MP3 or ID3 tags, you must precede the stream name with mp3: + // (for example, "mp3:sample".) + // To play H.264/AAC files, you must precede the stream name with mp4: and specify the + // file extension. For example, to play the file sample.m4v, specify + // "mp4:sample.m4v" std::string stream_name; - /** - * An optional parameter that specifies the start time in seconds. - * The default value is -2, which means the subscriber first tries to play the live - * stream specified in the Stream Name field. If a live stream of that name is - * not found, it plays the recorded stream specified in the Stream Name field. - * If you pass -1 in the Start field, only the live stream specified in the Stream - * Name field is played. - * If you pass 0 or a positive number in the Start field, a recorded stream specified - * in the Stream Name field is played beginning from the time specified in the - * Start field. - * If no recorded stream is found, the next item in the playlist is played. - */ + // An optional parameter that specifies the start time in seconds. + // The default value is -2, which means the subscriber first tries to play the live + // stream specified in the Stream Name field. If a live stream of that name is + // not found, it plays the recorded stream specified in the Stream Name field. + // If you pass -1 in the Start field, only the live stream specified in the Stream + // Name field is played. + // If you pass 0 or a positive number in the Start field, a recorded stream specified + // in the Stream Name field is played beginning from the time specified in the + // Start field. + // If no recorded stream is found, the next item in the playlist is played. double start; - /** - * An optional parameter that specifies the duration of playback in seconds. - * The default value is -1. The -1 value means a live stream is played until it is no - * longer available or a recorded stream is played until it ends. - * If u pass 0, it plays the single frame since the time specified in the Start field - * from the beginning of a recorded stream. It is assumed that the value specified - * in the Start field is equal to or greater than 0. - * If you pass a positive number, it plays a live stream for the time period specified - * in the Duration field. After that it becomes available or plays a recorded - * stream for the time specified in the Duration field. (If a stream ends before the - * time specified in the Duration field, playback ends when the stream ends.) - * If you pass a negative number other than -1 in the Duration field, it interprets the - * value as if it were -1. - */ + // An optional parameter that specifies the duration of playback in seconds. + // The default value is -1. The -1 value means a live stream is played until it is no + // longer available or a recorded stream is played until it ends. + // If u pass 0, it plays the single frame since the time specified in the Start field + // from the beginning of a recorded stream. It is assumed that the value specified + // in the Start field is equal to or greater than 0. + // If you pass a positive number, it plays a live stream for the time period specified + // in the Duration field. After that it becomes available or plays a recorded + // stream for the time specified in the Duration field. (If a stream ends before the + // time specified in the Duration field, playback ends when the stream ends.) + // If you pass a negative number other than -1 in the Duration field, it interprets the + // value as if it were -1. double duration; - /** - * An optional Boolean value or number that specifies whether to flush any - * previous playlist. - */ + // An optional Boolean value or number that specifies whether to flush any + // previous playlist. bool reset; public: SrsPlayPacket(); virtual ~SrsPlayPacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1507,38 +1164,28 @@ protected: virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * response for SrsPlayPacket. - * @remark, user must set the stream_id in header. - */ +// Response for SrsPlayPacket. +// @remark, user must set the stream_id in header. class SrsPlayResPacket : public SrsPacket { public: - /** - * Name of the command. If the play command is successful, the command - * name is set to onStatus. - */ + // Name of the command. If the play command is successful, the command + // name is set to onStatus. std::string command_name; - /** - * Transaction ID set to 0. - */ + // Transaction ID set to 0. double transaction_id; - /** - * Command information does not exist. Set to null type. - * @remark, never be NULL, an AMF0 null instance. - */ + // Command information does not exist. Set to null type. + // @remark, never be NULL, an AMF0 null instance. SrsAmf0Any* command_object; // null - /** - * If the play command is successful, the client receives OnStatus message from - * server which is NetStream.Play.Start. If the specified stream is not found, - * NetStream.Play.StreamNotFound is received. - * @remark, never be NULL, an AMF0 object instance. - */ + // If the play command is successful, the client receives OnStatus message from + // server which is NetStream.Play.Start. If the specified stream is not found, + // NetStream.Play.StreamNotFound is received. + // @remark, never be NULL, an AMF0 object instance. SrsAmf0Object* desc; public: SrsPlayResPacket(); virtual ~SrsPlayResPacket(); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1547,29 +1194,21 @@ protected: virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * when bandwidth test done, notice client. - */ +// When bandwidth test done, notice client. class SrsOnBWDonePacket : public SrsPacket { public: - /** - * Name of command. Set to "onBWDone" - */ + // Name of command. Set to "onBWDone" std::string command_name; - /** - * Transaction ID set to 0. - */ + // Transaction ID set to 0. double transaction_id; - /** - * Command information does not exist. Set to null type. - * @remark, never be NULL, an AMF0 null instance. - */ + // Command information does not exist. Set to null type. + // @remark, never be NULL, an AMF0 null instance. SrsAmf0Any* args; // null public: SrsOnBWDonePacket(); virtual ~SrsOnBWDonePacket(); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1578,36 +1217,26 @@ protected: virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * onStatus command, AMF0 Call - * @remark, user must set the stream_id by SrsCommonMessage.set_packet(). - */ +// onStatus command, AMF0 Call +// @remark, user must set the stream_id by SrsCommonMessage.set_packet(). class SrsOnStatusCallPacket : public SrsPacket { public: - /** - * Name of command. Set to "onStatus" - */ + // Name of command. Set to "onStatus" std::string command_name; - /** - * Transaction ID set to 0. - */ + // Transaction ID set to 0. double transaction_id; - /** - * Command information does not exist. Set to null type. - * @remark, never be NULL, an AMF0 null instance. - */ + // Command information does not exist. Set to null type. + // @remark, never be NULL, an AMF0 null instance. SrsAmf0Any* args; // null - /** - * Name-value pairs that describe the response from the server. - * 'code','level', 'description' are names of few among such information. - * @remark, never be NULL, an AMF0 object instance. - */ + // Name-value pairs that describe the response from the server. + // 'code','level', 'description' are names of few among such information. + // @remark, never be NULL, an AMF0 object instance. SrsAmf0Object* data; public: SrsOnStatusCallPacket(); virtual ~SrsOnStatusCallPacket(); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1616,41 +1245,31 @@ protected: virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * the special packet for the bandwidth test. - * actually, it's a SrsOnStatusCallPacket, but - * 1. encode with data field, to send data to client. - * 2. decode ignore the data field, donot care. - */ +// The special packet for the bandwidth test. +// actually, it's a SrsOnStatusCallPacket, but +// 1. encode with data field, to send data to client. +// 2. decode ignore the data field, donot care. class SrsBandwidthPacket : public SrsPacket { public: - /** - * Name of command. - */ + // Name of command. std::string command_name; - /** - * Transaction ID set to 0. - */ + // Transaction ID set to 0. double transaction_id; - /** - * Command information does not exist. Set to null type. - * @remark, never be NULL, an AMF0 null instance. - */ + // Command information does not exist. Set to null type. + // @remark, never be NULL, an AMF0 null instance. SrsAmf0Any* args; // null - /** - * Name-value pairs that describe the response from the server. - * 'code','level', 'description' are names of few among such information. - * @remark, never be NULL, an AMF0 object instance. - */ + // Name-value pairs that describe the response from the server. + // 'code','level', 'description' are names of few among such information. + // @remark, never be NULL, an AMF0 object instance. SrsAmf0Object* data; public: SrsBandwidthPacket(); virtual ~SrsBandwidthPacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1685,27 +1304,21 @@ private: virtual SrsBandwidthPacket* set_command(std::string command); }; -/** - * onStatus data, AMF0 Data - * @remark, user must set the stream_id by SrsCommonMessage.set_packet(). - */ +// onStatus data, AMF0 Data +// @remark, user must set the stream_id by SrsCommonMessage.set_packet(). class SrsOnStatusDataPacket : public SrsPacket { public: - /** - * Name of command. Set to "onStatus" - */ + // Name of command. Set to "onStatus" std::string command_name; - /** - * Name-value pairs that describe the response from the server. - * 'code', are names of few among such information. - * @remark, never be NULL, an AMF0 object instance. - */ + // Name-value pairs that describe the response from the server. + // 'code', are names of few among such information. + // @remark, never be NULL, an AMF0 object instance. SrsAmf0Object* data; public: SrsOnStatusDataPacket(); virtual ~SrsOnStatusDataPacket(); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1714,33 +1327,25 @@ protected: virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * AMF0Data RtmpSampleAccess - * @remark, user must set the stream_id by SrsCommonMessage.set_packet(). - */ +// AMF0Data RtmpSampleAccess +// @remark, user must set the stream_id by SrsCommonMessage.set_packet(). class SrsSampleAccessPacket : public SrsPacket { public: - /** - * Name of command. Set to "|RtmpSampleAccess". - */ + // Name of command. Set to "|RtmpSampleAccess". std::string command_name; - /** - * whether allow access the sample of video. - * @see: https://github.com/ossrs/srs/issues/49 - * @see: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#videoSampleAccess - */ + // Whether allow access the sample of video. + // @see: https://github.com/ossrs/srs/issues/49 + // @see: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#videoSampleAccess bool video_sample_access; - /** - * whether allow access the sample of audio. - * @see: https://github.com/ossrs/srs/issues/49 - * @see: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#audioSampleAccess - */ + // Whether allow access the sample of audio. + // @see: https://github.com/ossrs/srs/issues/49 + // @see: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/NetStream.html#audioSampleAccess bool audio_sample_access; public: SrsSampleAccessPacket(); virtual ~SrsSampleAccessPacket(); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1749,30 +1354,24 @@ protected: virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * the stream metadata. - * FMLE: @setDataFrame - * others: onMetaData - */ +// The stream metadata. +// FMLE: @setDataFrame +// others: onMetaData class SrsOnMetaDataPacket : public SrsPacket { public: - /** - * Name of metadata. Set to "onMetaData" - */ + // Name of metadata. Set to "onMetaData" std::string name; - /** - * Metadata of stream. - * @remark, never be NULL, an AMF0 object instance. - */ + // Metadata of stream. + // @remark, never be NULL, an AMF0 object instance. SrsAmf0Object* metadata; public: SrsOnMetaDataPacket(); virtual ~SrsOnMetaDataPacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1781,11 +1380,9 @@ protected: virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * 5.5. Window Acknowledgement Size (5) - * The client or the server sends this message to inform the peer which - * window size to use when sending acknowledgment. - */ +// 5.5. Window Acknowledgement Size (5) +// The client or the server sends this message to inform the peer which +// window size to use when sending acknowledgment. class SrsSetWindowAckSizePacket : public SrsPacket { public: @@ -1793,10 +1390,10 @@ public: public: SrsSetWindowAckSizePacket(); virtual ~SrsSetWindowAckSizePacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1805,11 +1402,9 @@ protected: virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * 5.3. Acknowledgement (3) - * The client or the server sends the acknowledgment to the peer after - * receiving bytes equal to the window size. - */ +// 5.3. Acknowledgement (3) +// The client or the server sends the acknowledgment to the peer after +// receiving bytes equal to the window size. class SrsAcknowledgementPacket : public SrsPacket { public: @@ -1817,10 +1412,10 @@ public: public: SrsAcknowledgementPacket(); virtual ~SrsAcknowledgementPacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1829,26 +1424,22 @@ protected: virtual srs_error_t encode_packet(SrsBuffer* stream); }; -/** - * 7.1. Set Chunk Size - * Protocol control message 1, Set Chunk Size, is used to notify the - * peer about the new maximum chunk size. - */ +// 7.1. Set Chunk Size +// Protocol control message 1, Set Chunk Size, is used to notify the +// peer about the new maximum chunk size. class SrsSetChunkSizePacket : public SrsPacket { public: - /** - * The maximum chunk size can be 65536 bytes. The chunk size is - * maintained independently for each direction. - */ + // The maximum chunk size can be 65536 bytes. The chunk size is + // maintained independently for each direction. int32_t chunk_size; public: SrsSetChunkSizePacket(); virtual ~SrsSetChunkSizePacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1867,11 +1458,9 @@ enum SrsPeerBandwidthType SrsPeerBandwidthDynamic = 2, }; -/** - * 5.6. Set Peer Bandwidth (6) - * The client or the server sends this message to update the output - * bandwidth of the peer. - */ +// 5.6. Set Peer Bandwidth (6) +// The client or the server sends this message to update the output +// bandwidth of the peer. class SrsSetPeerBandwidthPacket : public SrsPacket { public: @@ -1881,7 +1470,7 @@ public: public: SrsSetPeerBandwidthPacket(); virtual ~SrsSetPeerBandwidthPacket(); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); @@ -1893,130 +1482,106 @@ protected: // 3.7. User Control message enum SrcPCUCEventType { - // generally, 4bytes event-data + // Generally, 4bytes event-data - /** - * The server sends this event to notify the client - * that a stream has become functional and can be - * used for communication. By default, this event - * is sent on ID 0 after the application connect - * command is successfully received from the - * client. The event data is 4-byte and represents - * the stream ID of the stream that became - * functional. - */ + // The server sends this event to notify the client + // that a stream has become functional and can be + // used for communication. By default, this event + // is sent on ID 0 after the application connect + // command is successfully received from the + // client. The event data is 4-byte and represents + // The stream ID of the stream that became + // Functional. SrcPCUCStreamBegin = 0x00, - /** - * The server sends this event to notify the client - * that the playback of data is over as requested - * on this stream. No more data is sent without - * issuing additional commands. The client discards - * the messages received for the stream. The - * 4 bytes of event data represent the ID of the - * stream on which playback has ended. - */ + // The server sends this event to notify the client + // that the playback of data is over as requested + // on this stream. No more data is sent without + // issuing additional commands. The client discards + // The messages received for the stream. The + // 4 bytes of event data represent the ID of the + // stream on which playback has ended. SrcPCUCStreamEOF = 0x01, - /** - * The server sends this event to notify the client - * that there is no more data on the stream. If the - * server does not detect any message for a time - * period, it can notify the subscribed clients - * that the stream is dry. The 4 bytes of event - * data represent the stream ID of the dry stream. - */ + // The server sends this event to notify the client + // that there is no more data on the stream. If the + // server does not detect any message for a time + // period, it can notify the subscribed clients + // that the stream is dry. The 4 bytes of event + // data represent the stream ID of the dry stream. SrcPCUCStreamDry = 0x02, - /** - * The client sends this event to inform the server - * of the buffer size (in milliseconds) that is - * used to buffer any data coming over a stream. - * This event is sent before the server starts - * processing the stream. The first 4 bytes of the - * event data represent the stream ID and the next - * 4 bytes represent the buffer length, in - * milliseconds. - */ + // The client sends this event to inform the server + // of the buffer size (in milliseconds) that is + // used to buffer any data coming over a stream. + // This event is sent before the server starts + // processing the stream. The first 4 bytes of the + // event data represent the stream ID and the next + // 4 bytes represent the buffer length, in + // milliseconds. SrcPCUCSetBufferLength = 0x03, // 8bytes event-data - /** - * The server sends this event to notify the client - * that the stream is a recorded stream. The - * 4 bytes event data represent the stream ID of - * the recorded stream. - */ + // The server sends this event to notify the client + // that the stream is a recorded stream. The + // 4 bytes event data represent the stream ID of + // The recorded stream. SrcPCUCStreamIsRecorded = 0x04, - /** - * The server sends this event to test whether the - * client is reachable. Event data is a 4-byte - * timestamp, representing the local server time - * when the server dispatched the command. The - * client responds with kMsgPingResponse on - * receiving kMsgPingRequest. - */ + // The server sends this event to test whether the + // client is reachable. Event data is a 4-byte + // timestamp, representing the local server time + // When the server dispatched the command. The + // client responds with kMsgPingResponse on + // receiving kMsgPingRequest. SrcPCUCPingRequest = 0x06, - /** - * The client sends this event to the server in - * response to the ping request. The event data is - * a 4-byte timestamp, which was received with the - * kMsgPingRequest request. - */ + // The client sends this event to the server in + // Response to the ping request. The event data is + // a 4-byte timestamp, which was received with the + // kMsgPingRequest request. SrcPCUCPingResponse = 0x07, - /** - * For PCUC size=3, for example the payload is "00 1A 01", - * it's a FMS control event, where the event type is 0x001a and event data is 0x01, - * please notice that the event data is only 1 byte for this event. - */ + // For PCUC size=3, for example the payload is "00 1A 01", + // it's a FMS control event, where the event type is 0x001a and event data is 0x01, + // please notice that the event data is only 1 byte for this event. SrsPCUCFmsEvent0 = 0x1a, }; -/** - * 5.4. User Control Message (4) - * - * for the EventData is 4bytes. - * Stream Begin(=0) 4-bytes stream ID - * Stream EOF(=1) 4-bytes stream ID - * StreamDry(=2) 4-bytes stream ID - * SetBufferLength(=3) 8-bytes 4bytes stream ID, 4bytes buffer length. - * StreamIsRecorded(=4) 4-bytes stream ID - * PingRequest(=6) 4-bytes timestamp local server time - * PingResponse(=7) 4-bytes timestamp received ping request. - * - * 3.7. User Control message - * +------------------------------+------------------------- - * | Event Type ( 2- bytes ) | Event Data - * +------------------------------+------------------------- - * Figure 5 Pay load for the 'User Control Message'. - */ +// 5.4. User Control Message (4) +// +// For the EventData is 4bytes. +// Stream Begin(=0) 4-bytes stream ID +// Stream EOF(=1) 4-bytes stream ID +// StreamDry(=2) 4-bytes stream ID +// SetBufferLength(=3) 8-bytes 4bytes stream ID, 4bytes buffer length. +// StreamIsRecorded(=4) 4-bytes stream ID +// PingRequest(=6) 4-bytes timestamp local server time +// PingResponse(=7) 4-bytes timestamp received ping request. +// +// 3.7. User Control message +// +------------------------------+------------------------- +// | Event Type ( 2- bytes ) | Event Data +// +------------------------------+------------------------- +// Figure 5 Pay load for the 'User Control Message'. class SrsUserControlPacket : public SrsPacket { public: - /** - * Event type is followed by Event data. - * @see: SrcPCUCEventType - */ + // Event type is followed by Event data. + // @see: SrcPCUCEventType int16_t event_type; - /** - * the event data generally in 4bytes. - * @remark for event type is 0x001a, only 1bytes. - * @see SrsPCUCFmsEvent0 - */ + // The event data generally in 4bytes. + // @remark for event type is 0x001a, only 1bytes. + // @see SrsPCUCFmsEvent0 int32_t event_data; - /** - * 4bytes if event_type is SetBufferLength; otherwise 0. - */ + // 4bytes if event_type is SetBufferLength; otherwise 0. int32_t extra_data; public: SrsUserControlPacket(); virtual ~SrsUserControlPacket(); -// decode functions for concrete packet to override. +// Decode functions for concrete packet to override. public: virtual srs_error_t decode(SrsBuffer* stream); -// encode functions for concrete packet to override. +// Encode functions for concrete packet to override. public: virtual int get_prefer_cid(); virtual int get_message_type(); diff --git a/trunk/src/protocol/srs_rtsp_stack.hpp b/trunk/src/protocol/srs_rtsp_stack.hpp index 3efdbb192..7732c4138 100644 --- a/trunk/src/protocol/srs_rtsp_stack.hpp +++ b/trunk/src/protocol/srs_rtsp_stack.hpp @@ -38,7 +38,7 @@ class SrsSimpleStream; class SrsAudioFrame; class ISrsProtocolReadWriter; -// rtsp specification +// From rtsp specification // CR = #define SRS_RTSP_CR SRS_CONSTS_CR // 0x0D // LF = @@ -78,38 +78,28 @@ class ISrsProtocolReadWriter; // RTSP-Version #define SRS_RTSP_VERSION "RTSP/1.0" -/** - * the rtsp sdp parse state. - */ +// The rtsp sdp parse state. enum SrsRtspSdpState { - /** - * other sdp properties. - */ + // Other sdp properties. SrsRtspSdpStateOthers, - /** - * parse sdp audio state. - */ + // Parse sdp audio state. SrsRtspSdpStateAudio, - /** - * parse sdp video state. - */ + // Parse sdp video state. SrsRtspSdpStateVideo, }; -/** - * 10 Method Definitions, @see rfc2326-1998-rtsp.pdf, page 57 - * The method token indicates the method to be performed on the resource - * identified by the Request-URI. The method is case-sensitive. New - * methods may be defined in the future. Method names may not start with - * a $ character (decimal 24) and must be a token. Methods are - * summarized in Table 2. - * Notes on Table 2: PAUSE is recommended, but not required in that a - * fully functional server can be built that does not support this - * method, for example, for live feeds. If a server does not support a - * particular method, it MUST return "501 Not Implemented" and a client - * SHOULD not try this method again for this server. - */ +// 10 Method Definitions, @see rfc2326-1998-rtsp.pdf, page 57 +// The method token indicates the method to be performed on the resource +// identified by the Request-URI. The method is case-sensitive. New +// methods may be defined in the future. Method names may not start with +// a $ character (decimal 24) and must be a token. Methods are +// summarized in Table 2. +// Notes on Table 2: PAUSE is recommended, but not required in that a +// fully functional server can be built that does not support this +// method, for example, for live feeds. If a server does not support a +// particular method, it MUST return "501 Not Implemented" and a client +// SHOULD not try this method again for this server. enum SrsRtspMethod { SrsRtspMethodDescribe = 0x0001, @@ -125,237 +115,187 @@ enum SrsRtspMethod SrsRtspMethodTeardown = 0x0400, }; -/** - * the state of rtsp token. - */ +// The state of rtsp token. enum SrsRtspTokenState { - /** - * parse token failed, default state. - */ + // Parse token failed, default state. SrsRtspTokenStateError = 100, - /** - * when SP follow the token. - */ + // When SP follow the token. SrsRtspTokenStateNormal = 101, - /** - * when CRLF follow the token. - */ + // When CRLF follow the token. SrsRtspTokenStateEOF = 102, }; -/** - * the rtp packet. - * 5. RTP Data Transfer Protocol, @see rfc3550-2003-rtp.pdf, page 12 - */ +// The rtp packet. +// 5. RTP Data Transfer Protocol, @see rfc3550-2003-rtp.pdf, page 12 class SrsRtpPacket { public: - /** - * version (V): 2 bits - * This field identifies the version of RTP. The version defined by this specification is two (2). - * (The value 1 is used by the first draft version of RTP and the value 0 is used by the protocol - * initially implemented in the \vat" audio tool.) - */ + // The version (V): 2 bits + // This field identifies the version of RTP. The version defined by this specification is two (2). + // (The value 1 is used by the first draft version of RTP and the value 0 is used by the protocol + // initially implemented in the \vat" audio tool.) int8_t version; //2bits - /** - * padding (P): 1 bit - * If the padding bit is set, the packet contains one or more additional padding octets at the - * end which are not part of the payload. The last octet of the padding contains a count of - * how many padding octets should be ignored, including itself. Padding may be needed by - * some encryption algorithms with fixed block sizes or for carrying several RTP packets in a - * lower-layer protocol data unit. - */ + // The padding (P): 1 bit + // If the padding bit is set, the packet contains one or more additional padding octets at the + // end which are not part of the payload. The last octet of the padding contains a count of + // how many padding octets should be ignored, including itself. Padding may be needed by + // some encryption algorithms with fixed block sizes or for carrying several RTP packets in a + // lower-layer protocol data unit. int8_t padding; //1bit - /** - * extension (X): 1 bit - * If the extension bit is set, the fixed header must be followed by exactly one header extension, - * with a format defined in Section 5.3.1. - */ + // The extension (X): 1 bit + // If the extension bit is set, the fixed header must be followed by exactly one header extension, + // with a format defined in Section 5.3.1. int8_t extension; //1bit - /** - * CSRC count (CC): 4 bits - * The CSRC count contains the number of CSRC identifiers that follow the fixed header. - */ + // The CSRC count (CC): 4 bits + // The CSRC count contains the number of CSRC identifiers that follow the fixed header. int8_t csrc_count; //4bits - /** - * marker (M): 1 bit - * The interpretation of the marker is defined by a profile. It is intended to allow significant - * events such as frame boundaries to be marked in the packet stream. A profile may define - * additional marker bits or specify that there is no marker bit by changing the number of bits - * in the payload type field (see Section 5.3). - */ + // The marker (M): 1 bit + // The interpretation of the marker is defined by a profile. It is intended to allow significant + // events such as frame boundaries to be marked in the packet stream. A profile may define + // additional marker bits or specify that there is no marker bit by changing the number of bits + // in the payload type field (see Section 5.3). int8_t marker; //1bit - /** - * payload type (PT): 7 bits - * This field identifies the format of the RTP payload and determines its interpretation by the - * application. A profile may specify a default static mapping of payload type codes to payload - * formats. Additional payload type codes may be defined dynamically through non-RTP means - * (see Section 3). A set of default mappings for audio and video is specified in the companion - * RFC 3551 [1]. An RTP source may change the payload type during a session, but this field - * should not be used for multiplexing separate media streams (see Section 5.2). - * A receiver must ignore packets with payload types that it does not understand. - */ + // The payload type (PT): 7 bits + // This field identifies the format of the RTP payload and determines its interpretation by the + // application. A profile may specify a default static mapping of payload type codes to payload + // formats. Additional payload type codes may be defined dynamically through non-RTP means + // (see Section 3). A set of default mappings for audio and video is specified in the companion + // RFC 3551 [1]. An RTP source may change the payload type during a session, but this field + // should not be used for multiplexing separate media streams (see Section 5.2). + // A receiver must ignore packets with payload types that it does not understand. int8_t payload_type; //7bits - /** - * sequence number: 16 bits - * The sequence number increments by one for each RTP data packet sent, and may be used - * by the receiver to detect packet loss and to restore packet sequence. The initial value of the - * sequence number should be random (unpredictable) to make known-plaintext attacks on - * encryption more dicult, even if the source itself does not encrypt according to the method - * in Section 9.1, because the packets may flow through a translator that does. Techniques for - * choosing unpredictable numbers are discussed in [17]. - */ + // The sequence number: 16 bits + // The sequence number increments by one for each RTP data packet sent, and may be used + // by the receiver to detect packet loss and to restore packet sequence. The initial value of the + // sequence number should be random (unpredictable) to make known-plaintext attacks on + // encryption more dicult, even if the source itself does not encrypt according to the method + // in Section 9.1, because the packets may flow through a translator that does. Techniques for + // choosing unpredictable numbers are discussed in [17]. uint16_t sequence_number; //16bits - /** - * timestamp: 32 bits - * The timestamp reflects the sampling instant of the first octet in the RTP data packet. The - * sampling instant must be derived from a clock that increments monotonically and linearly - * in time to allow synchronization and jitter calculations (see Section 6.4.1). The resolution - * of the clock must be sucient for the desired synchronization accuracy and for measuring - * packet arrival jitter (one tick per video frame is typically not sucient). The clock frequency - * is dependent on the format of data carried as payload and is specified statically in the profile - * or payload format specification that defines the format, or may be specified dynamically for - * payload formats defined through non-RTP means. If RTP packets are generated periodically, - * the nominal sampling instant as determined from the sampling clock is to be used, not a - * reading of the system clock. As an example, for fixed-rate audio the timestamp clock would - * likely increment by one for each sampling period. If an audio application reads blocks covering - * 160 sampling periods from the input device, the timestamp would be increased by 160 for - * each such block, regardless of whether the block is transmitted in a packet or dropped as - * silent. - * - * The initial value of the timestamp should be random, as for the sequence number. Several - * consecutive RTP packets will have equal timestamps if they are (logically) generated at once, - * e.g., belong to the same video frame. Consecutive RTP packets may contain timestamps that - * are not monotonic if the data is not transmitted in the order it was sampled, as in the case - * of MPEG interpolated video frames. (The sequence numbers of the packets as transmitted - * will still be monotonic.) - * - * RTP timestamps from different media streams may advance at different rates and usually - * have independent, random offsets. Therefore, although these timestamps are sucient to - * reconstruct the timing of a single stream, directly comparing RTP timestamps from different - * media is not effective for synchronization. Instead, for each medium the RTP timestamp - * is related to the sampling instant by pairing it with a timestamp from a reference clock - * (wallclock) that represents the time when the data corresponding to the RTP timestamp was - * sampled. The reference clock is shared by all media to be synchronized. The timestamp - * pairs are not transmitted in every data packet, but at a lower rate in RTCP SR packets as - * described in Section 6.4. - * - * The sampling instant is chosen as the point of reference for the RTP timestamp because it is - * known to the transmitting endpoint and has a common definition for all media, independent - * of encoding delays or other processing. The purpose is to allow synchronized presentation of - * all media sampled at the same time. - * - * Applications transmitting stored data rather than data sampled in real time typically use a - * virtual presentation timeline derived from wallclock time to determine when the next frame - * or other unit of each medium in the stored data should be presented. In this case, the RTP - * timestamp would reflect the presentation time for each unit. That is, the RTP timestamp for - * each unit would be related to the wallclock time at which the unit becomes current on the - * virtual presentation timeline. Actual presentation occurs some time later as determined by - * the receiver. - * - * An example describing live audio narration of prerecorded video illustrates the significance - * of choosing the sampling instant as the reference point. In this scenario, the video would - * be presented locally for the narrator to view and would be simultaneously transmitted using - * RTP. The sampling instant" of a video frame transmitted in RTP would be established by - * referencing its timestamp to the wallclock time when that video frame was presented to the - * narrator. The sampling instant for the audio RTP packets containing the narrator's speech - * would be established by referencing the same wallclock time when the audio was sampled. - * The audio and video may even be transmitted by different hosts if the reference clocks on - * the two hosts are synchronized by some means such as NTP. A receiver can then synchronize - * presentation of the audio and video packets by relating their RTP timestamps using the - * timestamp pairs in RTCP SR packets. - */ + // The timestamp: 32 bits + // The timestamp reflects the sampling instant of the first octet in the RTP data packet. The + // sampling instant must be derived from a clock that increments monotonically and linearly + // in time to allow synchronization and jitter calculations (see Section 6.4.1). The resolution + // of the clock must be sucient for the desired synchronization accuracy and for measuring + // packet arrival jitter (one tick per video frame is typically not sucient). The clock frequency + // is dependent on the format of data carried as payload and is specified statically in the profile + // or payload format specification that defines the format, or may be specified dynamically for + // payload formats defined through non-RTP means. If RTP packets are generated periodically, + // The nominal sampling instant as determined from the sampling clock is to be used, not a + // reading of the system clock. As an example, for fixed-rate audio the timestamp clock would + // likely increment by one for each sampling period. If an audio application reads blocks covering + // 160 sampling periods from the input device, the timestamp would be increased by 160 for + // each such block, regardless of whether the block is transmitted in a packet or dropped as + // silent. + // + // The initial value of the timestamp should be random, as for the sequence number. Several + // consecutive RTP packets will have equal timestamps if they are (logically) generated at once, + // e.g., belong to the same video frame. Consecutive RTP packets may contain timestamps that + // are not monotonic if the data is not transmitted in the order it was sampled, as in the case + // of MPEG interpolated video frames. (The sequence numbers of the packets as transmitted + // will still be monotonic.) + // + // RTP timestamps from different media streams may advance at different rates and usually + // have independent, random offsets. Therefore, although these timestamps are sucient to + // reconstruct the timing of a single stream, directly comparing RTP timestamps from different + // media is not effective for synchronization. Instead, for each medium the RTP timestamp + // is related to the sampling instant by pairing it with a timestamp from a reference clock + // (wallclock) that represents the time when the data corresponding to the RTP timestamp was + // sampled. The reference clock is shared by all media to be synchronized. The timestamp + // pairs are not transmitted in every data packet, but at a lower rate in RTCP SR packets as + // described in Section 6.4. + // + // The sampling instant is chosen as the point of reference for the RTP timestamp because it is + // known to the transmitting endpoint and has a common definition for all media, independent + // of encoding delays or other processing. The purpose is to allow synchronized presentation of + // all media sampled at the same time. + // + // Applications transmitting stored data rather than data sampled in real time typically use a + // virtual presentation timeline derived from wallclock time to determine when the next frame + // or other unit of each medium in the stored data should be presented. In this case, the RTP + // timestamp would reflect the presentation time for each unit. That is, the RTP timestamp for + // each unit would be related to the wallclock time at which the unit becomes current on the + // virtual presentation timeline. Actual presentation occurs some time later as determined by + // The receiver. + // + // An example describing live audio narration of prerecorded video illustrates the significance + // of choosing the sampling instant as the reference point. In this scenario, the video would + // be presented locally for the narrator to view and would be simultaneously transmitted using + // RTP. The sampling instant" of a video frame transmitted in RTP would be established by + // referencing its timestamp to the wallclock time when that video frame was presented to the + // narrator. The sampling instant for the audio RTP packets containing the narrator's speech + // would be established by referencing the same wallclock time when the audio was sampled. + // The audio and video may even be transmitted by different hosts if the reference clocks on + // The two hosts are synchronized by some means such as NTP. A receiver can then synchronize + // presentation of the audio and video packets by relating their RTP timestamps using the + // timestamp pairs in RTCP SR packets. uint32_t timestamp; //32bits - /** - * SSRC: 32 bits - * The SSRC field identifies the synchronization source. This identifier should be chosen - * randomly, with the intent that no two synchronization sources within the same RTP session - * will have the same SSRC identifier. An example algorithm for generating a random identifier - * is presented in Appendix A.6. Although the probability of multiple sources choosing the same - * identifier is low, all RTP implementations must be prepared to detect and resolve collisions. - * Section 8 describes the probability of collision along with a mechanism for resolving collisions - * and detecting RTP-level forwarding loops based on the uniqueness of the SSRC identifier. If - * a source changes its source transport address, it must also choose a new SSRC identifier to - * avoid being interpreted as a looped source (see Section 8.2). - */ + // The SSRC: 32 bits + // The SSRC field identifies the synchronization source. This identifier should be chosen + // randomly, with the intent that no two synchronization sources within the same RTP session + // will have the same SSRC identifier. An example algorithm for generating a random identifier + // is presented in Appendix A.6. Although the probability of multiple sources choosing the same + // identifier is low, all RTP implementations must be prepared to detect and resolve collisions. + // Section 8 describes the probability of collision along with a mechanism for resolving collisions + // and detecting RTP-level forwarding loops based on the uniqueness of the SSRC identifier. If + // a source changes its source transport address, it must also choose a new SSRC identifier to + // avoid being interpreted as a looped source (see Section 8.2). uint32_t ssrc; //32bits - // the payload. + // The payload. SrsSimpleStream* payload; - // whether transport in chunked payload. + // Whether transport in chunked payload. bool chunked; - // whether message is completed. + // Whether message is completed. // normal message always completed. // while chunked completed when the last chunk arriaved. bool completed; - /** - * the audio samples, one rtp packets may contains multiple audio samples. - */ + // The audio samples, one rtp packets may contains multiple audio samples. SrsAudioFrame* audio; public: SrsRtpPacket(); virtual ~SrsRtpPacket(); public: - /** - * copy the header from src. - */ + // copy the header from src. virtual void copy(SrsRtpPacket* src); - /** - * reap the src to this packet, reap the payload. - */ + // reap the src to this packet, reap the payload. virtual void reap(SrsRtpPacket* src); - /** - * decode rtp packet from stream. - */ + // decode rtp packet from stream. virtual srs_error_t decode(SrsBuffer* stream); private: virtual srs_error_t decode_97(SrsBuffer* stream); virtual srs_error_t decode_96(SrsBuffer* stream); }; -/** - * the sdp in announce, @see rfc2326-1998-rtsp.pdf, page 159 - * Appendix C: Use of SDP for RTSP Session Descriptions - * The Session Description Protocol (SDP, RFC 2327 [6]) may be used to - * describe streams or presentations in RTSP. - */ +// The sdp in announce, @see rfc2326-1998-rtsp.pdf, page 159 +// Appendix C: Use of SDP for RTSP Session Descriptions +// The Session Description Protocol (SDP, RFC 2327 [6]) may be used to +// describe streams or presentations in RTSP. class SrsRtspSdp { private: SrsRtspSdpState state; public: - /** - * the version of sdp. - */ + // The version of sdp. std::string version; - /** - * the owner/creator of sdp. - */ + // The owner/creator of sdp. std::string owner_username; std::string owner_session_id; std::string owner_session_version; std::string owner_network_type; std::string owner_address_type; std::string owner_address; - /** - * the session name of sdp. - */ + // The session name of sdp. std::string session_name; - /** - * the connection info of sdp. - */ + // The connection info of sdp. std::string connection_network_type; std::string connection_address_type; std::string connection_address; - /** - * the tool attribute of sdp. - */ + // The tool attribute of sdp. std::string tool; - /** - * the video attribute of sdp. - */ + // The video attribute of sdp. std::string video_port; std::string video_protocol; std::string video_transport_format; @@ -363,13 +303,11 @@ public: std::string video_codec; std::string video_sample_rate; std::string video_stream_id; - // fmtp + // The fmtp std::string video_packetization_mode; std::string video_sps; // sequence header: sps. std::string video_pps; // sequence header: pps. - /** - * the audio attribute of sdp. - */ + // The audio attribute of sdp. std::string audio_port; std::string audio_protocol; std::string audio_transport_format; @@ -378,7 +316,7 @@ public: std::string audio_sample_rate; std::string audio_channel; std::string audio_stream_id; - // fmtp + // The fmtp std::string audio_profile_level_id; std::string audio_mode; std::string audio_size_length; @@ -389,34 +327,24 @@ public: SrsRtspSdp(); virtual ~SrsRtspSdp(); public: - /** - * parse a line of token for sdp. - */ + // Parse a line of token for sdp. virtual srs_error_t parse(std::string token); private: - /** - * generally, the fmtp is the sequence header for video or audio. - */ + // generally, the fmtp is the sequence header for video or audio. virtual srs_error_t parse_fmtp_attribute(std::string attr); - /** - * generally, the control is the stream info for video or audio. - */ + // generally, the control is the stream info for video or audio. virtual srs_error_t parse_control_attribute(std::string attr); - /** - * decode the string by base64. - */ + // decode the string by base64. virtual std::string base64_decode(std::string value); }; -/** - * the rtsp transport. - * 12.39 Transport, @see rfc2326-1998-rtsp.pdf, page 115 - * This request header indicates which transport protocol is to be used - * and configures its parameters such as destination address, - * compression, multicast time-to-live and destination port for a single - * stream. It sets those values not already determined by a presentation - * description. - */ +// The rtsp transport. +// 12.39 Transport, @see rfc2326-1998-rtsp.pdf, page 115 +// This request header indicates which transport protocol is to be used +// and configures its parameters such as destination address, +// compression, multicast time-to-live and destination port for a single +// stream. It sets those values not already determined by a presentation +// description. class SrsRtspTransport { public: @@ -431,7 +359,7 @@ public: // Clients that are capable of handling both unicast and // multicast transmission MUST indicate such capability by // including two full transport-specs with separate parameters - // for each. + // For each. std::string cast_type; // The mode parameter indicates the methods to be supported for // this session. Valid values are PLAY and RECORD. If not @@ -449,79 +377,59 @@ public: SrsRtspTransport(); virtual ~SrsRtspTransport(); public: - /** - * parse a line of token for transport. - */ + // Parse a line of token for transport. virtual srs_error_t parse(std::string attr); }; -/** - * the rtsp request message. - * 6 Request, @see rfc2326-1998-rtsp.pdf, page 39 - * A request message from a client to a server or vice versa includes, - * within the first line of that message, the method to be applied to - * the resource, the identifier of the resource, and the protocol - * version in use. - * Request = Request-Line ; Section 6.1 - * *( general-header ; Section 5 - * | request-header ; Section 6.2 - * | entity-header ) ; Section 8.1 - * CRLF - * [ message-body ] ; Section 4.3 - */ +// The rtsp request message. +// 6 Request, @see rfc2326-1998-rtsp.pdf, page 39 +// A request message from a client to a server or vice versa includes, +// within the first line of that message, the method to be applied to +// The resource, the identifier of the resource, and the protocol +// version in use. +// Request = Request-Line ; Section 6.1 +// // ( general-header ; Section 5 +// | request-header ; Section 6.2 +// | entity-header ) ; Section 8.1 +// CRLF +// [ message-body ] ; Section 4.3 class SrsRtspRequest { public: - /** - * 6.1 Request Line - * Request-Line = Method SP Request-URI SP RTSP-Version CRLF - */ + // 6.1 Request Line + // Request-Line = Method SP Request-URI SP RTSP-Version CRLF std::string method; std::string uri; std::string version; - /** - * 12.17 CSeq - * The CSeq field specifies the sequence number for an RTSP requestresponse - * pair. This field MUST be present in all requests and - * responses. For every RTSP request containing the given sequence - * number, there will be a corresponding response having the same - * number. Any retransmitted request must contain the same sequence - * number as the original (i.e. the sequence number is not incremented - * for retransmissions of the same request). - */ + // 12.17 CSeq + // The CSeq field specifies the sequence number for an RTSP requestresponse + // pair. This field MUST be present in all requests and + // responses. For every RTSP request containing the given sequence + // number, there will be a corresponding response having the same + // number. Any retransmitted request must contain the same sequence + // number as the original (i.e. the sequence number is not incremented + // For retransmissions of the same request). long seq; - /** - * 12.16 Content-Type, @see rfc2326-1998-rtsp.pdf, page 99 - * See [H14.18]. Note that the content types suitable for RTSP are - * likely to be restricted in practice to presentation descriptions and - * parameter-value types. - */ + // 12.16 Content-Type, @see rfc2326-1998-rtsp.pdf, page 99 + // See [H14.18]. Note that the content types suitable for RTSP are + // likely to be restricted in practice to presentation descriptions and + // parameter-value types. std::string content_type; - /** - * 12.14 Content-Length, @see rfc2326-1998-rtsp.pdf, page 99 - * This field contains the length of the content of the method (i.e. - * after the double CRLF following the last header). Unlike HTTP, it - * MUST be included in all messages that carry content beyond the header - * portion of the message. If it is missing, a default value of zero is - * assumed. It is interpreted according to [H14.14]. - */ + // 12.14 Content-Length, @see rfc2326-1998-rtsp.pdf, page 99 + // This field contains the length of the content of the method (i.e. + // after the double CRLF following the last header). Unlike HTTP, it + // MUST be included in all messages that carry content beyond the header + // portion of the message. If it is missing, a default value of zero is + // assumed. It is interpreted according to [H14.14]. long content_length; - /** - * the session id. - */ + // The session id. std::string session; - /** - * the sdp in announce, NULL for no sdp. - */ + // The sdp in announce, NULL for no sdp. SrsRtspSdp* sdp; - /** - * the transport in setup, NULL for no transport. - */ + // The transport in setup, NULL for no transport. SrsRtspTransport* transport; - /** - * for setup message, parse the stream id from uri. - */ + // For setup message, parse the stream id from uri. int stream_id; public: SrsRtspRequest(); @@ -533,79 +441,63 @@ public: virtual bool is_record(); }; -/** - * the rtsp response message. - * 7 Response, @see rfc2326-1998-rtsp.pdf, page 43 - * [H6] applies except that HTTP-Version is replaced by RTSP-Version. - * Also, RTSP defines additional status codes and does not define some - * HTTP codes. The valid response codes and the methods they can be used - * with are defined in Table 1. - * After receiving and interpreting a request message, the recipient - * responds with an RTSP response message. - * Response = Status-Line ; Section 7.1 - * *( general-header ; Section 5 - * | response-header ; Section 7.1.2 - * | entity-header ) ; Section 8.1 - * CRLF - * [ message-body ] ; Section 4.3 - */ +// The rtsp response message. +// 7 Response, @see rfc2326-1998-rtsp.pdf, page 43 +// [H6] applies except that HTTP-Version is replaced by RTSP-Version. +// Also, RTSP defines additional status codes and does not define some +// HTTP codes. The valid response codes and the methods they can be used +// with are defined in Table 1. +// After receiving and interpreting a request message, the recipient +// responds with an RTSP response message. +// Response = Status-Line ; Section 7.1 +// // ( general-header ; Section 5 +// | response-header ; Section 7.1.2 +// | entity-header ) ; Section 8.1 +// CRLF +// [ message-body ] ; Section 4.3 class SrsRtspResponse { public: - /** - * 7.1 Status-Line - * The first line of a Response message is the Status-Line, consisting - * of the protocol version followed by a numeric status code, and the - * textual phrase associated with the status code, with each element - * separated by SP characters. No CR or LF is allowed except in the - * final CRLF sequence. - * Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF - */ + // 7.1 Status-Line + // The first line of a Response message is the Status-Line, consisting + // of the protocol version followed by a numeric status code, and the + // textual phrase associated with the status code, with each element + // separated by SP characters. No CR or LF is allowed except in the + // final CRLF sequence. + // Status-Line = RTSP-Version SP Status-Code SP Reason-Phrase CRLF // @see about the version of rtsp, see SRS_RTSP_VERSION // @see about the status of rtsp, see SRS_CONSTS_RTSP_OK int status; - /** - * 12.17 CSeq, @see rfc2326-1998-rtsp.pdf, page 99 - * The CSeq field specifies the sequence number for an RTSP requestresponse - * pair. This field MUST be present in all requests and - * responses. For every RTSP request containing the given sequence - * number, there will be a corresponding response having the same - * number. Any retransmitted request must contain the same sequence - * number as the original (i.e. the sequence number is not incremented - * for retransmissions of the same request). - */ + // 12.17 CSeq, @see rfc2326-1998-rtsp.pdf, page 99 + // The CSeq field specifies the sequence number for an RTSP requestresponse + // pair. This field MUST be present in all requests and + // responses. For every RTSP request containing the given sequence + // number, there will be a corresponding response having the same + // number. Any retransmitted request must contain the same sequence + // number as the original (i.e. the sequence number is not incremented + // For retransmissions of the same request). long seq; - /** - * the session id. - */ + // The session id. std::string session; public: SrsRtspResponse(int cseq); virtual ~SrsRtspResponse(); public: - /** - * encode message to string. - */ + // Encode message to string. virtual srs_error_t encode(std::stringstream& ss); protected: - /** - * sub classes override this to encode the headers. - */ + // Sub classes override this to encode the headers. virtual srs_error_t encode_header(std::stringstream& ss); }; -/** - * 10.1 OPTIONS, @see rfc2326-1998-rtsp.pdf, page 59 - * The behavior is equivalent to that described in [H9.2]. An OPTIONS - * request may be issued at any time, e.g., if the client is about to - * try a nonstandard request. It does not influence server state. - */ +// 10.1 OPTIONS, @see rfc2326-1998-rtsp.pdf, page 59 +// The behavior is equivalent to that described in [H9.2]. An OPTIONS +// request may be issued at any time, e.g., if the client is about to +// try a nonstandard request. It does not influence server state. class SrsRtspOptionsResponse : public SrsRtspResponse { public: - /** - * join of SrsRtspMethod - */ + // Join of SrsRtspMethod SrsRtspMethod methods; public: SrsRtspOptionsResponse(int cseq); @@ -614,28 +506,26 @@ protected: virtual srs_error_t encode_header(std::stringstream& ss); }; -/** - * 10.4 SETUP, @see rfc2326-1998-rtsp.pdf, page 65 - * The SETUP request for a URI specifies the transport mechanism to be - * used for the streamed media. A client can issue a SETUP request for a - * stream that is already playing to change transport parameters, which - * a server MAY allow. If it does not allow this, it MUST respond with - * error "455 Method Not Valid In This State". For the benefit of any - * intervening firewalls, a client must indicate the transport - * parameters even if it has no influence over these parameters, for - * example, where the server advertises a fixed multicast address. - */ +// 10.4 SETUP, @see rfc2326-1998-rtsp.pdf, page 65 +// The SETUP request for a URI specifies the transport mechanism to be +// used for the streamed media. A client can issue a SETUP request for a +// stream that is already playing to change transport parameters, which +// a server MAY allow. If it does not allow this, it MUST respond with +// error "455 Method Not Valid In This State". For the benefit of any +// intervening firewalls, a client must indicate the transport +// parameters even if it has no influence over these parameters, for +// example, where the server advertises a fixed multicast address. class SrsRtspSetupResponse : public SrsRtspResponse { public: - // the client specified port. + // The client specified port. int client_port_min; int client_port_max; - // client will use the port in: + // The client will use the port in: // [local_port_min, local_port_max) int local_port_min; int local_port_max; - // session. + // The session. std::string session; public: SrsRtspSetupResponse(int cseq); @@ -644,65 +534,45 @@ protected: virtual srs_error_t encode_header(std::stringstream& ss); }; -/** - * the rtsp protocol stack to parse the rtsp packets. - */ +// The rtsp protocol stack to parse the rtsp packets. class SrsRtspStack { private: - /** - * cached bytes buffer. - */ + // The cached bytes buffer. SrsSimpleStream* buf; - /** - * underlayer socket object, send/recv bytes. - */ + // The underlayer socket object, send/recv bytes. ISrsProtocolReadWriter* skt; public: SrsRtspStack(ISrsProtocolReadWriter* s); virtual ~SrsRtspStack(); public: - /** - * recv rtsp message from underlayer io. - * @param preq the output rtsp request message, which user must free it. - * @return an int error code. - * ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF. - */ + // Recv rtsp message from underlayer io. + // @param preq the output rtsp request message, which user must free it. + // @return an int error code. + // ERROR_RTSP_REQUEST_HEADER_EOF indicates request header EOF. virtual srs_error_t recv_message(SrsRtspRequest** preq); - /** - * send rtsp message over underlayer io. - * @param res the rtsp response message, which user should never free it. - * @return an int error code. - */ + // Send rtsp message over underlayer io. + // @param res the rtsp response message, which user should never free it. + // @return an int error code. virtual srs_error_t send_message(SrsRtspResponse* res); private: - /** - * recv the rtsp message. - */ + // Recv the rtsp message. virtual srs_error_t do_recv_message(SrsRtspRequest* req); - /** - * read a normal token from io, error when token state is not normal. - */ + // Read a normal token from io, error when token state is not normal. virtual srs_error_t recv_token_normal(std::string& token); - /** - * read a normal token from io, error when token state is not eof. - */ + // Read a normal token from io, error when token state is not eof. virtual srs_error_t recv_token_eof(std::string& token); - /** - * read the token util got eof, for example, to read the response status Reason-Phrase - * @param pconsumed, output the token parsed length. NULL to ignore. - */ + // Read the token util got eof, for example, to read the response status Reason-Phrase + // @param pconsumed, output the token parsed length. NULL to ignore. virtual srs_error_t recv_token_util_eof(std::string& token, int* pconsumed = NULL); - /** - * read a token from io, split by SP, endswith CRLF: - * token1 SP token2 SP ... tokenN CRLF - * @param token, output the read token. - * @param state, output the token parse state. - * @param normal_ch, the char to indicates the normal token. - * the SP use to indicates the normal token, @see SRS_RTSP_SP - * the 0x00 use to ignore normal token flag. @see recv_token_util_eof - * @param pconsumed, output the token parsed length. NULL to ignore. - */ + // Read a token from io, split by SP, endswith CRLF: + // token1 SP token2 SP ... tokenN CRLF + // @param token, output the read token. + // @param state, output the token parse state. + // @param normal_ch, the char to indicates the normal token. + // the SP use to indicates the normal token, @see SRS_RTSP_SP + // the 0x00 use to ignore normal token flag. @see recv_token_util_eof + // @param pconsumed, output the token parsed length. NULL to ignore. virtual srs_error_t recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch = SRS_RTSP_SP, int* pconsumed = NULL); }; From b285029e15209924aafac9221b3b081b6e49d939 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 23 Apr 2019 08:17:59 +0800 Subject: [PATCH 05/25] Refine SrsHttpUri.get_uri_field, without depends on http parser. --- trunk/src/protocol/srs_http_stack.cpp | 5 ++++- trunk/src/protocol/srs_http_stack.hpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/trunk/src/protocol/srs_http_stack.cpp b/trunk/src/protocol/srs_http_stack.cpp index c23911266..b869a8f6c 100644 --- a/trunk/src/protocol/srs_http_stack.cpp +++ b/trunk/src/protocol/srs_http_stack.cpp @@ -3094,8 +3094,11 @@ string SrsHttpUri::get_query() return query; } -string SrsHttpUri::get_uri_field(string uri, http_parser_url* hp_u, http_parser_url_fields field) +string SrsHttpUri::get_uri_field(string uri, void* php_u, int ifield) { + http_parser_url* hp_u = (http_parser_url*)php_u; + http_parser_url_fields field = (http_parser_url_fields)ifield; + if((hp_u->field_set & (1 << field)) == 0){ return ""; } diff --git a/trunk/src/protocol/srs_http_stack.hpp b/trunk/src/protocol/srs_http_stack.hpp index e68fe7b4e..dfa587df6 100644 --- a/trunk/src/protocol/srs_http_stack.hpp +++ b/trunk/src/protocol/srs_http_stack.hpp @@ -835,7 +835,7 @@ public: private: // Get the parsed url field. // @return return empty string if not set. - virtual std::string get_uri_field(std::string uri, http_parser_url* hp_u, http_parser_url_fields field); + virtual std::string get_uri_field(std::string uri, void* hp_u, int field); }; #endif From 6e9bba4220c37a97541477b1fe45ad06002342f6 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 23 Apr 2019 08:26:15 +0800 Subject: [PATCH 06/25] Refine SrsHttpUri. --- trunk/src/protocol/srs_http_stack.cpp | 203 ++++++++++++-------------- trunk/src/protocol/srs_http_stack.hpp | 59 ++++---- 2 files changed, 120 insertions(+), 142 deletions(-) diff --git a/trunk/src/protocol/srs_http_stack.cpp b/trunk/src/protocol/srs_http_stack.cpp index b869a8f6c..404c6cc61 100644 --- a/trunk/src/protocol/srs_http_stack.cpp +++ b/trunk/src/protocol/srs_http_stack.cpp @@ -819,6 +819,96 @@ char* ISrsHttpMessage::http_ts_send_buffer() return _http_ts_send_buffer; } +SrsHttpUri::SrsHttpUri() +{ + port = SRS_DEFAULT_HTTP_PORT; +} + +SrsHttpUri::~SrsHttpUri() +{ +} + +srs_error_t SrsHttpUri::initialize(string _url) +{ + srs_error_t err = srs_success; + + schema = host = path = query = ""; + + url = _url; + const char* purl = url.c_str(); + + http_parser_url hp_u; + int r0; + if((r0 = http_parser_parse_url(purl, url.length(), 0, &hp_u)) != 0){ + return srs_error_new(ERROR_HTTP_PARSE_URI, "parse url %s failed, code=%d", purl, r0); + } + + std::string field = get_uri_field(url, &hp_u, UF_SCHEMA); + if(!field.empty()){ + schema = field; + } + + host = get_uri_field(url, &hp_u, UF_HOST); + + field = get_uri_field(url, &hp_u, UF_PORT); + if(!field.empty()){ + port = atoi(field.c_str()); + } + if(port<=0){ + port = SRS_DEFAULT_HTTP_PORT; + } + + path = get_uri_field(url, &hp_u, UF_PATH); + query = get_uri_field(url, &hp_u, UF_QUERY); + + return err; +} + +string SrsHttpUri::get_url() +{ + return url; +} + +string SrsHttpUri::get_schema() +{ + return schema; +} + +string SrsHttpUri::get_host() +{ + return host; +} + +int SrsHttpUri::get_port() +{ + return port; +} + +string SrsHttpUri::get_path() +{ + return path; +} + +string SrsHttpUri::get_query() +{ + return query; +} + +string SrsHttpUri::get_uri_field(string uri, void* php_u, int ifield) +{ + http_parser_url* hp_u = (http_parser_url*)php_u; + http_parser_url_fields field = (http_parser_url_fields)ifield; + + if((hp_u->field_set & (1 << field)) == 0){ + return ""; + } + + int offset = hp_u->field_data[field].off; + int len = hp_u->field_data[field].len; + + return uri.substr(offset, len); +} + #endif /* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev @@ -2997,116 +3087,3 @@ http_body_is_final(const struct http_parser *parser) { return parser->state == s_message_done; } -/* - The MIT License (MIT) - - Copyright (c) 2013-2019 Winlin - - Permission is hereby granted, free of charge, to any person obtaining a copy of - this software and associated documentation files (the "Software"), to deal in - the Software without restriction, including without limitation the rights to - use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - the Software, and to permit persons to whom the Software is furnished to do so, - subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -SrsHttpUri::SrsHttpUri() -{ - port = SRS_DEFAULT_HTTP_PORT; -} - -SrsHttpUri::~SrsHttpUri() -{ -} - -srs_error_t SrsHttpUri::initialize(string _url) -{ - srs_error_t err = srs_success; - - schema = host = path = query = ""; - - url = _url; - const char* purl = url.c_str(); - - http_parser_url hp_u; - int r0; - if((r0 = http_parser_parse_url(purl, url.length(), 0, &hp_u)) != 0){ - return srs_error_new(ERROR_HTTP_PARSE_URI, "parse url %s failed, code=%d", purl, r0); - } - - std::string field = get_uri_field(url, &hp_u, UF_SCHEMA); - if(!field.empty()){ - schema = field; - } - - host = get_uri_field(url, &hp_u, UF_HOST); - - field = get_uri_field(url, &hp_u, UF_PORT); - if(!field.empty()){ - port = atoi(field.c_str()); - } - if(port<=0){ - port = SRS_DEFAULT_HTTP_PORT; - } - - path = get_uri_field(url, &hp_u, UF_PATH); - query = get_uri_field(url, &hp_u, UF_QUERY); - - return err; -} - -string SrsHttpUri::get_url() -{ - return url; -} - -string SrsHttpUri::get_schema() -{ - return schema; -} - -string SrsHttpUri::get_host() -{ - return host; -} - -int SrsHttpUri::get_port() -{ - return port; -} - -string SrsHttpUri::get_path() -{ - return path; -} - -string SrsHttpUri::get_query() -{ - return query; -} - -string SrsHttpUri::get_uri_field(string uri, void* php_u, int ifield) -{ - http_parser_url* hp_u = (http_parser_url*)php_u; - http_parser_url_fields field = (http_parser_url_fields)ifield; - - if((hp_u->field_set & (1 << field)) == 0){ - return ""; - } - - int offset = hp_u->field_data[field].off; - int len = hp_u->field_data[field].len; - - return uri.substr(offset, len); -} - - diff --git a/trunk/src/protocol/srs_http_stack.hpp b/trunk/src/protocol/srs_http_stack.hpp index dfa587df6..b450780f6 100644 --- a/trunk/src/protocol/srs_http_stack.hpp +++ b/trunk/src/protocol/srs_http_stack.hpp @@ -508,10 +508,40 @@ public: virtual bool is_jsonp() = 0; }; +// Used to resolve the http uri. +class SrsHttpUri +{ +private: + std::string url; + std::string schema; + std::string host; + int port; + std::string path; + std::string query; +public: + SrsHttpUri(); + virtual ~SrsHttpUri(); +public: + // Initialize the http uri. + virtual srs_error_t initialize(std::string _url); +public: + virtual std::string get_url(); + virtual std::string get_schema(); + virtual std::string get_host(); + virtual int get_port(); + virtual std::string get_path(); + virtual std::string get_query(); +private: + // Get the parsed url field. + // @return return empty string if not set. + virtual std::string get_uri_field(std::string uri, void* hp_u, int field); +}; + #endif // The http-parser is license under MIT at https://github.com/nodejs/http-parser/blob/master/LICENSE-MIT // Version: 2.1 from https://github.com/nodejs/http-parser/releases/tag/v2.1 +// File: https://github.com/nodejs/http-parser/blob/80819384450b5511a3d1c424dd92a5843c891364/http_parser.h //Copyright Joyent, Inc. and other Node contributors. All rights reserved. // @@ -809,34 +839,5 @@ extern "C" { #endif #endif -// Used to resolve the http uri. -class SrsHttpUri -{ -private: - std::string url; - std::string schema; - std::string host; - int port; - std::string path; - std::string query; -public: - SrsHttpUri(); - virtual ~SrsHttpUri(); -public: - // Initialize the http uri. - virtual srs_error_t initialize(std::string _url); -public: - virtual std::string get_url(); - virtual std::string get_schema(); - virtual std::string get_host(); - virtual int get_port(); - virtual std::string get_path(); - virtual std::string get_query(); -private: - // Get the parsed url field. - // @return return empty string if not set. - virtual std::string get_uri_field(std::string uri, void* hp_u, int field); -}; - #endif From 646d490a1828644fbae31ada755ae40b0140e353 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 23 Apr 2019 08:31:21 +0800 Subject: [PATCH 07/25] Reset http-parser 2.1 --- trunk/src/protocol/srs_http_stack.cpp | 3834 +++++++++++++------------ trunk/src/protocol/srs_http_stack.hpp | 574 ++-- 2 files changed, 2235 insertions(+), 2173 deletions(-) diff --git a/trunk/src/protocol/srs_http_stack.cpp b/trunk/src/protocol/srs_http_stack.cpp index 404c6cc61..fe479c35e 100644 --- a/trunk/src/protocol/srs_http_stack.cpp +++ b/trunk/src/protocol/srs_http_stack.cpp @@ -909,8 +909,34 @@ string SrsHttpUri::get_uri_field(string uri, void* php_u, int ifield) return uri.substr(offset, len); } +// For #if !defined(SRS_EXPORT_LIBRTMP) #endif +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + /* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev * * Additional changes are licensed under the same terms as NGINX and @@ -956,8 +982,8 @@ string SrsHttpUri::get_uri_field(string uri, void* php_u, int ifield) #ifndef BIT_AT # define BIT_AT(a, i) \ -(!!((unsigned int) (a)[(unsigned int) (i) >> 3] & \ -(1 << ((unsigned int) (i) & 7)))) + (!!((unsigned int) (a)[(unsigned int) (i) >> 3] & \ + (1 << ((unsigned int) (i) & 7)))) #endif #ifndef ELEM_AT @@ -966,25 +992,25 @@ string SrsHttpUri::get_uri_field(string uri, void* php_u, int ifield) #define SET_ERRNO(e) \ do { \ -parser->http_errno = (e); \ + parser->http_errno = (e); \ } while(0) /* Run the notify callback FOR, returning ER if it fails */ #define CALLBACK_NOTIFY_(FOR, ER) \ do { \ -assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ -\ -if (settings->on_##FOR) { \ -if (0 != settings->on_##FOR(parser)) { \ -SET_ERRNO(HPE_CB_##FOR); \ -} \ -\ -/* We either errored above or got paused; get out */ \ -if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { \ -return (ER); \ -} \ -} \ + assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ + \ + if (settings->on_##FOR) { \ + if (0 != settings->on_##FOR(parser)) { \ + SET_ERRNO(HPE_CB_##FOR); \ + } \ + \ + /* We either errored above or got paused; get out */ \ + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { \ + return (ER); \ + } \ + } \ } while (0) /* Run the notify callback FOR and consume the current byte */ @@ -996,37 +1022,37 @@ return (ER); \ /* Run data callback FOR with LEN bytes, returning ER if it fails */ #define CALLBACK_DATA_(FOR, LEN, ER) \ do { \ -assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ -\ -if (FOR##_mark) { \ -if (settings->on_##FOR) { \ -if (0 != settings->on_##FOR(parser, FOR##_mark, (LEN))) { \ -SET_ERRNO(HPE_CB_##FOR); \ -} \ -\ -/* We either errored above or got paused; get out */ \ -if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { \ -return (ER); \ -} \ -} \ -FOR##_mark = NULL; \ -} \ + assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ + \ + if (FOR##_mark) { \ + if (settings->on_##FOR) { \ + if (0 != settings->on_##FOR(parser, FOR##_mark, (LEN))) { \ + SET_ERRNO(HPE_CB_##FOR); \ + } \ + \ + /* We either errored above or got paused; get out */ \ + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { \ + return (ER); \ + } \ + } \ + FOR##_mark = NULL; \ + } \ } while (0) /* Run the data callback FOR and consume the current byte */ #define CALLBACK_DATA(FOR) \ -CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1) + CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1) /* Run the data callback FOR and don't consume the current byte */ #define CALLBACK_DATA_NOADVANCE(FOR) \ -CALLBACK_DATA_(FOR, p - FOR##_mark, p - data) + CALLBACK_DATA_(FOR, p - FOR##_mark, p - data) /* Set the mark FOR; non-destructive if mark is already set */ #define MARK(FOR) \ do { \ -if (!FOR##_mark) { \ -FOR##_mark = p; \ -} \ + if (!FOR##_mark) { \ + FOR##_mark = p; \ + } \ } while (0) @@ -1041,11 +1067,11 @@ FOR##_mark = p; \ static const char *method_strings[] = -{ + { #define XX(num, name, string) #string, - HTTP_METHOD_MAP(XX) + HTTP_METHOD_MAP(XX) #undef XX -}; + }; /* Tokens as defined by rfc 2616. Also lowercases them. @@ -1056,50 +1082,50 @@ static const char *method_strings[] = * | "{" | "}" | SP | HT */ static const char tokens[256] = { - /* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ - 0, 0, 0, 0, 0, 0, 0, 0, - /* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ - 0, '!', 0, '#', '$', '%', '&', '\'', - /* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ - 0, 0, '*', '+', 0, '-', '.', 0, - /* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ - '0', '1', '2', '3', '4', '5', '6', '7', - /* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ - '8', '9', 0, 0, 0, 0, 0, 0, - /* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ - 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', - /* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ - 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', - /* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', - /* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ - 'x', 'y', 'z', 0, 0, 0, '^', '_', - /* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ - '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', - /* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ - 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', - /* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', - /* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ - 'x', 'y', 'z', 0, '|', 0, '~', 0 }; +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + 0, 0, 0, 0, 0, 0, 0, 0, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + 0, '!', 0, '#', '$', '%', '&', '\'', +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 0, 0, '*', '+', 0, '-', '.', 0, +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + '0', '1', '2', '3', '4', '5', '6', '7', +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + '8', '9', 0, 0, 0, 0, 0, 0, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + 'x', 'y', 'z', 0, 0, 0, '^', '_', +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + 'x', 'y', 'z', 0, '|', 0, '~', 0 }; static const int8_t unhex[256] = -{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 - ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 - ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 - , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1 - ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 - ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 - ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 - ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 -}; + {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 + ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 + }; #if HTTP_PARSER_STRICT @@ -1110,159 +1136,159 @@ static const int8_t unhex[256] = static const uint8_t normal_url_char[32] = { - /* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ - 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, - /* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ - 0 | T(2) | 0 | 0 | T(16) | 0 | 0 | 0, - /* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ - 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, - /* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ - 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, - /* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ - 0 | 2 | 4 | 0 | 16 | 32 | 64 | 128, - /* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, - /* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, - /* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, - /* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, - /* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, - /* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, - /* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, - /* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, - /* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, - /* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, - /* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ - 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, }; +/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ + 0 | T(2) | 0 | 0 | T(16) | 0 | 0 | 0, +/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ + 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, +/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ + 0 | 2 | 4 | 0 | 16 | 32 | 64 | 128, +/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, +/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, +/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ + 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, }; #undef T enum state -{ s_dead = 1 /* important that this is > 0 */ - - , s_start_req_or_res - , s_res_or_resp_H - , s_start_res - , s_res_H - , s_res_HT - , s_res_HTT - , s_res_HTTP - , s_res_first_http_major - , s_res_http_major - , s_res_first_http_minor - , s_res_http_minor - , s_res_first_status_code - , s_res_status_code - , s_res_status - , s_res_line_almost_done - - , s_start_req - - , s_req_method - , s_req_spaces_before_url - , s_req_schema - , s_req_schema_slash - , s_req_schema_slash_slash - , s_req_server_start - , s_req_server - , s_req_server_with_at - , s_req_path - , s_req_query_string_start - , s_req_query_string - , s_req_fragment_start - , s_req_fragment - , s_req_http_start - , s_req_http_H - , s_req_http_HT - , s_req_http_HTT - , s_req_http_HTTP - , s_req_first_http_major - , s_req_http_major - , s_req_first_http_minor - , s_req_http_minor - , s_req_line_almost_done - - , s_header_field_start - , s_header_field - , s_header_value_start - , s_header_value - , s_header_value_lws - - , s_header_almost_done - - , s_chunk_size_start - , s_chunk_size - , s_chunk_parameters - , s_chunk_size_almost_done - - , s_headers_almost_done - , s_headers_done - - /* Important: 's_headers_done' must be the last 'header' state. All - * states beyond this must be 'body' states. It is used for overflow - * checking. See the PARSING_HEADER() macro. - */ - - , s_chunk_data - , s_chunk_data_almost_done - , s_chunk_data_done - - , s_body_identity - , s_body_identity_eof - - , s_message_done -}; + { s_dead = 1 /* important that this is > 0 */ + + , s_start_req_or_res + , s_res_or_resp_H + , s_start_res + , s_res_H + , s_res_HT + , s_res_HTT + , s_res_HTTP + , s_res_first_http_major + , s_res_http_major + , s_res_first_http_minor + , s_res_http_minor + , s_res_first_status_code + , s_res_status_code + , s_res_status + , s_res_line_almost_done + + , s_start_req + + , s_req_method + , s_req_spaces_before_url + , s_req_schema + , s_req_schema_slash + , s_req_schema_slash_slash + , s_req_server_start + , s_req_server + , s_req_server_with_at + , s_req_path + , s_req_query_string_start + , s_req_query_string + , s_req_fragment_start + , s_req_fragment + , s_req_http_start + , s_req_http_H + , s_req_http_HT + , s_req_http_HTT + , s_req_http_HTTP + , s_req_first_http_major + , s_req_http_major + , s_req_first_http_minor + , s_req_http_minor + , s_req_line_almost_done + + , s_header_field_start + , s_header_field + , s_header_value_start + , s_header_value + , s_header_value_lws + + , s_header_almost_done + + , s_chunk_size_start + , s_chunk_size + , s_chunk_parameters + , s_chunk_size_almost_done + + , s_headers_almost_done + , s_headers_done + + /* Important: 's_headers_done' must be the last 'header' state. All + * states beyond this must be 'body' states. It is used for overflow + * checking. See the PARSING_HEADER() macro. + */ + + , s_chunk_data + , s_chunk_data_almost_done + , s_chunk_data_done + + , s_body_identity + , s_body_identity_eof + + , s_message_done + }; #define PARSING_HEADER(state) (state <= s_headers_done) enum header_states -{ h_general = 0 - , h_C - , h_CO - , h_CON - - , h_matching_connection - , h_matching_proxy_connection - , h_matching_content_length - , h_matching_transfer_encoding - , h_matching_upgrade - - , h_connection - , h_content_length - , h_transfer_encoding - , h_upgrade - - , h_matching_transfer_encoding_chunked - , h_matching_connection_keep_alive - , h_matching_connection_close - - , h_transfer_encoding_chunked - , h_connection_keep_alive - , h_connection_close -}; + { h_general = 0 + , h_C + , h_CO + , h_CON + + , h_matching_connection + , h_matching_proxy_connection + , h_matching_content_length + , h_matching_transfer_encoding + , h_matching_upgrade + + , h_connection + , h_content_length + , h_transfer_encoding + , h_upgrade + + , h_matching_transfer_encoding_chunked + , h_matching_connection_keep_alive + , h_matching_connection_close + + , h_transfer_encoding_chunked + , h_connection_keep_alive + , h_connection_close + }; enum http_host_state -{ + { s_http_host_dead = 1 - , s_http_userinfo_start - , s_http_userinfo - , s_http_host_start - , s_http_host_v6_start - , s_http_host - , s_http_host_v6 - , s_http_host_v6_end - , s_http_host_port_start - , s_http_host_port + , s_http_userinfo_start + , s_http_userinfo + , s_http_host_start + , s_http_host_v6_start + , s_http_host + , s_http_host_v6 + , s_http_host_v6_end + , s_http_host_port_start + , s_http_host_port }; /* Macros for character classes; depends on strict-mode */ @@ -1274,11 +1300,11 @@ enum http_host_state #define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c)) #define IS_HEX(c) (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f')) #define IS_MARK(c) ((c) == '-' || (c) == '_' || (c) == '.' || \ -(c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \ -(c) == ')') + (c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \ + (c) == ')') #define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \ -(c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \ -(c) == '$' || (c) == ',') + (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \ + (c) == '$' || (c) == ',') #if HTTP_PARSER_STRICT #define TOKEN(c) (tokens[(unsigned char)c]) @@ -1287,9 +1313,9 @@ enum http_host_state #else #define TOKEN(c) ((c == ' ') ? ' ' : tokens[(unsigned char)c]) #define IS_URL_CHAR(c) \ -(BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80)) + (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80)) #define IS_HOST_CHAR(c) \ -(IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_') + (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_') #endif @@ -1299,10 +1325,10 @@ enum http_host_state #if HTTP_PARSER_STRICT # define STRICT_CHECK(cond) \ do { \ -if (cond) { \ -SET_ERRNO(HPE_STRICT); \ -goto error; \ -} \ + if (cond) { \ + SET_ERRNO(HPE_STRICT); \ + goto error; \ + } \ } while (0) # define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead) #else @@ -1314,10 +1340,10 @@ goto error; \ /* Map errno values to strings for human-readable output */ #define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s }, static struct { - const char *name; - const char *description; + const char *name; + const char *description; } http_strerror_tab[] = { - HTTP_ERRNO_MAP(HTTP_STRERROR_GEN) + HTTP_ERRNO_MAP(HTTP_STRERROR_GEN) }; #undef HTTP_STRERROR_GEN @@ -1337,149 +1363,149 @@ int http_message_needs_eof(const http_parser *parser); static enum state parse_url_char(enum state s, const char ch) { - if (ch == ' ' || ch == '\r' || ch == '\n') { - return s_dead; - } - -#if HTTP_PARSER_STRICT - if (ch == '\t' || ch == '\f') { - return s_dead; - } -#endif - - switch (s) { - case s_req_spaces_before_url: - /* Proxied requests are followed by scheme of an absolute URI (alpha). - * All methods except CONNECT are followed by '/' or '*'. - */ - - if (ch == '/' || ch == '*') { - return s_req_path; - } - - if (IS_ALPHA(ch)) { - return s_req_schema; - } - - break; - - case s_req_schema: - if (IS_ALPHA(ch)) { - return s; - } - - if (ch == ':') { - return s_req_schema_slash; - } - - break; - - case s_req_schema_slash: - if (ch == '/') { - return s_req_schema_slash_slash; - } - - break; - - case s_req_schema_slash_slash: - if (ch == '/') { - return s_req_server_start; - } - - break; - - case s_req_server_with_at: - if (ch == '@') { - return s_dead; - } - - /* FALLTHROUGH */ - case s_req_server_start: - case s_req_server: - if (ch == '/') { - return s_req_path; - } - - if (ch == '?') { - return s_req_query_string_start; - } - - if (ch == '@') { - return s_req_server_with_at; - } - - if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') { - return s_req_server; - } - - break; - - case s_req_path: - if (IS_URL_CHAR(ch)) { - return s; - } - - switch (ch) { - case '?': - return s_req_query_string_start; - - case '#': - return s_req_fragment_start; - } - - break; - - case s_req_query_string_start: - case s_req_query_string: - if (IS_URL_CHAR(ch)) { - return s_req_query_string; - } - - switch (ch) { - case '?': - /* allow extra '?' in query string */ - return s_req_query_string; - - case '#': - return s_req_fragment_start; - } - - break; - - case s_req_fragment_start: - if (IS_URL_CHAR(ch)) { - return s_req_fragment; - } - - switch (ch) { - case '?': - return s_req_fragment; - - case '#': - return s; - } - - break; - - case s_req_fragment: - if (IS_URL_CHAR(ch)) { - return s; - } - - switch (ch) { - case '?': - case '#': - return s; - } - - break; - - default: - break; - } - - /* We should never fall out of the switch above unless there's an error */ + if (ch == ' ' || ch == '\r' || ch == '\n') { return s_dead; + } + +#if HTTP_PARSER_STRICT + if (ch == '\t' || ch == '\f') { + return s_dead; + } +#endif + + switch (s) { + case s_req_spaces_before_url: + /* Proxied requests are followed by scheme of an absolute URI (alpha). + * All methods except CONNECT are followed by '/' or '*'. + */ + + if (ch == '/' || ch == '*') { + return s_req_path; + } + + if (IS_ALPHA(ch)) { + return s_req_schema; + } + + break; + + case s_req_schema: + if (IS_ALPHA(ch)) { + return s; + } + + if (ch == ':') { + return s_req_schema_slash; + } + + break; + + case s_req_schema_slash: + if (ch == '/') { + return s_req_schema_slash_slash; + } + + break; + + case s_req_schema_slash_slash: + if (ch == '/') { + return s_req_server_start; + } + + break; + + case s_req_server_with_at: + if (ch == '@') { + return s_dead; + } + + /* FALLTHROUGH */ + case s_req_server_start: + case s_req_server: + if (ch == '/') { + return s_req_path; + } + + if (ch == '?') { + return s_req_query_string_start; + } + + if (ch == '@') { + return s_req_server_with_at; + } + + if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') { + return s_req_server; + } + + break; + + case s_req_path: + if (IS_URL_CHAR(ch)) { + return s; + } + + switch (ch) { + case '?': + return s_req_query_string_start; + + case '#': + return s_req_fragment_start; + } + + break; + + case s_req_query_string_start: + case s_req_query_string: + if (IS_URL_CHAR(ch)) { + return s_req_query_string; + } + + switch (ch) { + case '?': + /* allow extra '?' in query string */ + return s_req_query_string; + + case '#': + return s_req_fragment_start; + } + + break; + + case s_req_fragment_start: + if (IS_URL_CHAR(ch)) { + return s_req_fragment; + } + + switch (ch) { + case '?': + return s_req_fragment; + + case '#': + return s; + } + + break; + + case s_req_fragment: + if (IS_URL_CHAR(ch)) { + return s; + } + + switch (ch) { + case '?': + case '#': + return s; + } + + break; + + default: + break; + } + + /* We should never fall out of the switch above unless there's an error */ + return s_dead; } size_t http_parser_execute (http_parser *parser, @@ -1487,1274 +1513,1274 @@ size_t http_parser_execute (http_parser *parser, const char *data, size_t len) { - char c, ch; - int8_t unhex_val; - const char *p = data; - const char *header_field_mark = 0; - const char *header_value_mark = 0; - const char *url_mark = 0; - const char *body_mark = 0; - - /* We're in an error state. Don't bother doing anything. */ - if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { - return 0; - } - - if (len == 0) { - switch (parser->state) { - case s_body_identity_eof: - /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if - * we got paused. - */ - CALLBACK_NOTIFY_NOADVANCE(message_complete); - return 0; - - case s_dead: - case s_start_req_or_res: - case s_start_res: - case s_start_req: - return 0; - - default: - SET_ERRNO(HPE_INVALID_EOF_STATE); - return 1; - } - } - - - if (parser->state == s_header_field) - header_field_mark = data; - if (parser->state == s_header_value) - header_value_mark = data; + char c, ch; + int8_t unhex_val; + const char *p = data; + const char *header_field_mark = 0; + const char *header_value_mark = 0; + const char *url_mark = 0; + const char *body_mark = 0; + + /* We're in an error state. Don't bother doing anything. */ + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { + return 0; + } + + if (len == 0) { switch (parser->state) { - case s_req_path: - case s_req_schema: - case s_req_schema_slash: - case s_req_schema_slash_slash: - case s_req_server_start: - case s_req_server: - case s_req_server_with_at: - case s_req_query_string_start: - case s_req_query_string: - case s_req_fragment_start: - case s_req_fragment: - url_mark = data; - break; + case s_body_identity_eof: + /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if + * we got paused. + */ + CALLBACK_NOTIFY_NOADVANCE(message_complete); + return 0; + + case s_dead: + case s_start_req_or_res: + case s_start_res: + case s_start_req: + return 0; + + default: + SET_ERRNO(HPE_INVALID_EOF_STATE); + return 1; } - - for (p=data; p != data + len; p++) { - ch = *p; - - if (PARSING_HEADER(parser->state)) { - ++parser->nread; - /* Buffer overflow attack */ - if (parser->nread > HTTP_MAX_HEADER_SIZE) { - SET_ERRNO(HPE_HEADER_OVERFLOW); - goto error; - } - } - + } + + + if (parser->state == s_header_field) + header_field_mark = data; + if (parser->state == s_header_value) + header_value_mark = data; + switch (parser->state) { + case s_req_path: + case s_req_schema: + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + case s_req_server: + case s_req_server_with_at: + case s_req_query_string_start: + case s_req_query_string: + case s_req_fragment_start: + case s_req_fragment: + url_mark = data; + break; + } + + for (p=data; p != data + len; p++) { + ch = *p; + + if (PARSING_HEADER(parser->state)) { + ++parser->nread; + /* Buffer overflow attack */ + if (parser->nread > HTTP_MAX_HEADER_SIZE) { + SET_ERRNO(HPE_HEADER_OVERFLOW); + goto error; + } + } + reexecute_byte: - switch (parser->state) { - - case s_dead: - /* this state is used after a 'Connection: close' message - * the parser will error out if it reads another message - */ - if (ch == CR || ch == LF) - break; - - SET_ERRNO(HPE_CLOSED_CONNECTION); - goto error; - - case s_start_req_or_res: - { - if (ch == CR || ch == LF) - break; - parser->flags = 0; - parser->content_length = ULLONG_MAX; - - if (ch == 'H') { - parser->state = s_res_or_resp_H; - - CALLBACK_NOTIFY(message_begin); - } else { - parser->type = HTTP_REQUEST; - parser->state = s_start_req; - goto reexecute_byte; - } - - break; - } - - case s_res_or_resp_H: - if (ch == 'T') { - parser->type = HTTP_RESPONSE; - parser->state = s_res_HT; - } else { - if (ch != 'E') { - SET_ERRNO(HPE_INVALID_CONSTANT); - goto error; - } - - parser->type = HTTP_REQUEST; - parser->method = HTTP_HEAD; - parser->index = 2; - parser->state = s_req_method; - } - break; - - case s_start_res: - { - parser->flags = 0; - parser->content_length = ULLONG_MAX; - - switch (ch) { - case 'H': - parser->state = s_res_H; - break; - - case CR: - case LF: - break; - - default: - SET_ERRNO(HPE_INVALID_CONSTANT); - goto error; - } - - CALLBACK_NOTIFY(message_begin); - break; - } - - case s_res_H: - STRICT_CHECK(ch != 'T'); - parser->state = s_res_HT; - break; - - case s_res_HT: - STRICT_CHECK(ch != 'T'); - parser->state = s_res_HTT; - break; - - case s_res_HTT: - STRICT_CHECK(ch != 'P'); - parser->state = s_res_HTTP; - break; - - case s_res_HTTP: - STRICT_CHECK(ch != '/'); - parser->state = s_res_first_http_major; - break; - - case s_res_first_http_major: - if (ch < '0' || ch > '9') { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_major = ch - '0'; - parser->state = s_res_http_major; - break; - - /* major HTTP version or dot */ - case s_res_http_major: - { - if (ch == '.') { - parser->state = s_res_first_http_minor; - break; - } - - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_major *= 10; - parser->http_major += ch - '0'; - - if (parser->http_major > 999) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - break; - } - - /* first digit of minor HTTP version */ - case s_res_first_http_minor: - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_minor = ch - '0'; - parser->state = s_res_http_minor; - break; - - /* minor HTTP version or end of request line */ - case s_res_http_minor: - { - if (ch == ' ') { - parser->state = s_res_first_status_code; - break; - } - - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_minor *= 10; - parser->http_minor += ch - '0'; - - if (parser->http_minor > 999) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - break; - } - - case s_res_first_status_code: - { - if (!IS_NUM(ch)) { - if (ch == ' ') { - break; - } - - SET_ERRNO(HPE_INVALID_STATUS); - goto error; - } - parser->status_code = ch - '0'; - parser->state = s_res_status_code; - break; - } - - case s_res_status_code: - { - if (!IS_NUM(ch)) { - switch (ch) { - case ' ': - parser->state = s_res_status; - break; - case CR: - parser->state = s_res_line_almost_done; - break; - case LF: - parser->state = s_header_field_start; - break; - default: - SET_ERRNO(HPE_INVALID_STATUS); - goto error; - } - break; - } - - parser->status_code *= 10; - parser->status_code += ch - '0'; - - if (parser->status_code > 999) { - SET_ERRNO(HPE_INVALID_STATUS); - goto error; - } - - break; - } - - case s_res_status: - /* the human readable status. e.g. "NOT FOUND" - * we are not humans so just ignore this */ - if (ch == CR) { - parser->state = s_res_line_almost_done; - break; - } - - if (ch == LF) { - parser->state = s_header_field_start; - break; - } - break; - - case s_res_line_almost_done: - STRICT_CHECK(ch != LF); - parser->state = s_header_field_start; - CALLBACK_NOTIFY(status_complete); - break; - - case s_start_req: - { - if (ch == CR || ch == LF) - break; - parser->flags = 0; - parser->content_length = ULLONG_MAX; - - if (!IS_ALPHA(ch)) { - SET_ERRNO(HPE_INVALID_METHOD); - goto error; - } - - parser->method = (enum http_method) 0; - parser->index = 1; - switch (ch) { - case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break; - case 'D': parser->method = HTTP_DELETE; break; - case 'G': parser->method = HTTP_GET; break; - case 'H': parser->method = HTTP_HEAD; break; - case 'L': parser->method = HTTP_LOCK; break; - case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH */ break; - case 'N': parser->method = HTTP_NOTIFY; break; - case 'O': parser->method = HTTP_OPTIONS; break; - case 'P': parser->method = HTTP_POST; - /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */ - break; - case 'R': parser->method = HTTP_REPORT; break; - case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break; - case 'T': parser->method = HTTP_TRACE; break; - case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE */ break; - default: - SET_ERRNO(HPE_INVALID_METHOD); - goto error; - } - parser->state = s_req_method; - - CALLBACK_NOTIFY(message_begin); - - break; - } - - case s_req_method: - { - const char *matcher; - if (ch == '\0') { - SET_ERRNO(HPE_INVALID_METHOD); - goto error; - } - - matcher = method_strings[parser->method]; - if (ch == ' ' && matcher[parser->index] == '\0') { - parser->state = s_req_spaces_before_url; - } else if (ch == matcher[parser->index]) { - ; /* nada */ - } else if (parser->method == HTTP_CONNECT) { - if (parser->index == 1 && ch == 'H') { - parser->method = HTTP_CHECKOUT; - } else if (parser->index == 2 && ch == 'P') { - parser->method = HTTP_COPY; - } else { - goto error; - } - } else if (parser->method == HTTP_MKCOL) { - if (parser->index == 1 && ch == 'O') { - parser->method = HTTP_MOVE; - } else if (parser->index == 1 && ch == 'E') { - parser->method = HTTP_MERGE; - } else if (parser->index == 1 && ch == '-') { - parser->method = HTTP_MSEARCH; - } else if (parser->index == 2 && ch == 'A') { - parser->method = HTTP_MKACTIVITY; - } else { - goto error; - } - } else if (parser->method == HTTP_SUBSCRIBE) { - if (parser->index == 1 && ch == 'E') { - parser->method = HTTP_SEARCH; - } else { - goto error; - } - } else if (parser->index == 1 && parser->method == HTTP_POST) { - if (ch == 'R') { - parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */ - } else if (ch == 'U') { - parser->method = HTTP_PUT; /* or HTTP_PURGE */ - } else if (ch == 'A') { - parser->method = HTTP_PATCH; - } else { - goto error; - } - } else if (parser->index == 2) { - if (parser->method == HTTP_PUT) { - if (ch == 'R') parser->method = HTTP_PURGE; - } else if (parser->method == HTTP_UNLOCK) { - if (ch == 'S') parser->method = HTTP_UNSUBSCRIBE; - } - } else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') { - parser->method = HTTP_PROPPATCH; - } else { - SET_ERRNO(HPE_INVALID_METHOD); - goto error; - } - - ++parser->index; - break; - } - - case s_req_spaces_before_url: - { - if (ch == ' ') break; - - MARK(url); - if (parser->method == HTTP_CONNECT) { - parser->state = s_req_server_start; - } - - parser->state = parse_url_char((enum state)parser->state, ch); - if (parser->state == s_dead) { - SET_ERRNO(HPE_INVALID_URL); - goto error; - } - - break; - } - - case s_req_schema: - case s_req_schema_slash: - case s_req_schema_slash_slash: - case s_req_server_start: - { - switch (ch) { - /* No whitespace allowed here */ - case ' ': - case CR: - case LF: - SET_ERRNO(HPE_INVALID_URL); - goto error; - default: - parser->state = parse_url_char((enum state)parser->state, ch); - if (parser->state == s_dead) { - SET_ERRNO(HPE_INVALID_URL); - goto error; - } - } - - break; - } - - case s_req_server: - case s_req_server_with_at: - case s_req_path: - case s_req_query_string_start: - case s_req_query_string: - case s_req_fragment_start: - case s_req_fragment: - { - switch (ch) { - case ' ': - parser->state = s_req_http_start; - CALLBACK_DATA(url); - break; - case CR: - case LF: - parser->http_major = 0; - parser->http_minor = 9; - parser->state = (ch == CR) ? - s_req_line_almost_done : - s_header_field_start; - CALLBACK_DATA(url); - break; - default: - parser->state = parse_url_char((enum state)parser->state, ch); - if (parser->state == s_dead) { - SET_ERRNO(HPE_INVALID_URL); - goto error; - } - } - break; - } - - case s_req_http_start: - switch (ch) { - case 'H': - parser->state = s_req_http_H; - break; - case ' ': - break; - default: - SET_ERRNO(HPE_INVALID_CONSTANT); - goto error; - } - break; - - case s_req_http_H: - STRICT_CHECK(ch != 'T'); - parser->state = s_req_http_HT; - break; - - case s_req_http_HT: - STRICT_CHECK(ch != 'T'); - parser->state = s_req_http_HTT; - break; - - case s_req_http_HTT: - STRICT_CHECK(ch != 'P'); - parser->state = s_req_http_HTTP; - break; - - case s_req_http_HTTP: - STRICT_CHECK(ch != '/'); - parser->state = s_req_first_http_major; - break; - - /* first digit of major HTTP version */ - case s_req_first_http_major: - if (ch < '1' || ch > '9') { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_major = ch - '0'; - parser->state = s_req_http_major; - break; - - /* major HTTP version or dot */ - case s_req_http_major: - { - if (ch == '.') { - parser->state = s_req_first_http_minor; - break; - } - - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_major *= 10; - parser->http_major += ch - '0'; - - if (parser->http_major > 999) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - break; - } - - /* first digit of minor HTTP version */ - case s_req_first_http_minor: - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_minor = ch - '0'; - parser->state = s_req_http_minor; - break; - - /* minor HTTP version or end of request line */ - case s_req_http_minor: - { - if (ch == CR) { - parser->state = s_req_line_almost_done; - break; - } - - if (ch == LF) { - parser->state = s_header_field_start; - break; - } - - /* XXX allow spaces after digit? */ - - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_minor *= 10; - parser->http_minor += ch - '0'; - - if (parser->http_minor > 999) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - break; - } - - /* end of request line */ - case s_req_line_almost_done: - { - if (ch != LF) { - SET_ERRNO(HPE_LF_EXPECTED); - goto error; - } - - parser->state = s_header_field_start; - break; - } - - case s_header_field_start: - { - if (ch == CR) { - parser->state = s_headers_almost_done; - break; - } - - if (ch == LF) { - /* they might be just sending \n instead of \r\n so this would be - * the second \n to denote the end of headers*/ - parser->state = s_headers_almost_done; - goto reexecute_byte; - } - - c = TOKEN(ch); - - if (!c) { - SET_ERRNO(HPE_INVALID_HEADER_TOKEN); - goto error; - } - - MARK(header_field); - - parser->index = 0; - parser->state = s_header_field; - - switch (c) { - case 'c': - parser->header_state = h_C; - break; - - case 'p': - parser->header_state = h_matching_proxy_connection; - break; - - case 't': - parser->header_state = h_matching_transfer_encoding; - break; - - case 'u': - parser->header_state = h_matching_upgrade; - break; - - default: - parser->header_state = h_general; - break; - } - break; - } - - case s_header_field: - { - c = TOKEN(ch); - - if (c) { - switch (parser->header_state) { - case h_general: - break; - - case h_C: - parser->index++; - parser->header_state = (c == 'o' ? h_CO : h_general); - break; - - case h_CO: - parser->index++; - parser->header_state = (c == 'n' ? h_CON : h_general); - break; - - case h_CON: - parser->index++; - switch (c) { - case 'n': - parser->header_state = h_matching_connection; - break; - case 't': - parser->header_state = h_matching_content_length; - break; - default: - parser->header_state = h_general; - break; - } - break; - - /* connection */ - - case h_matching_connection: - parser->index++; - if (parser->index > sizeof(CONNECTION)-1 - || c != CONNECTION[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(CONNECTION)-2) { - parser->header_state = h_connection; - } - break; - - /* proxy-connection */ - - case h_matching_proxy_connection: - parser->index++; - if (parser->index > sizeof(PROXY_CONNECTION)-1 - || c != PROXY_CONNECTION[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(PROXY_CONNECTION)-2) { - parser->header_state = h_connection; - } - break; - - /* content-length */ - - case h_matching_content_length: - parser->index++; - if (parser->index > sizeof(CONTENT_LENGTH)-1 - || c != CONTENT_LENGTH[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(CONTENT_LENGTH)-2) { - parser->header_state = h_content_length; - } - break; - - /* transfer-encoding */ - - case h_matching_transfer_encoding: - parser->index++; - if (parser->index > sizeof(TRANSFER_ENCODING)-1 - || c != TRANSFER_ENCODING[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) { - parser->header_state = h_transfer_encoding; - } - break; - - /* upgrade */ - - case h_matching_upgrade: - parser->index++; - if (parser->index > sizeof(UPGRADE)-1 - || c != UPGRADE[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(UPGRADE)-2) { - parser->header_state = h_upgrade; - } - break; - - case h_connection: - case h_content_length: - case h_transfer_encoding: - case h_upgrade: - if (ch != ' ') parser->header_state = h_general; - break; - - default: - assert(0 && "Unknown header_state"); - break; - } - break; - } - - if (ch == ':') { - parser->state = s_header_value_start; - CALLBACK_DATA(header_field); - break; - } - - if (ch == CR) { - parser->state = s_header_almost_done; - CALLBACK_DATA(header_field); - break; - } - - if (ch == LF) { - parser->state = s_header_field_start; - CALLBACK_DATA(header_field); - break; - } - - SET_ERRNO(HPE_INVALID_HEADER_TOKEN); - goto error; - } - - case s_header_value_start: - { - if (ch == ' ' || ch == '\t') break; - - MARK(header_value); - - parser->state = s_header_value; - parser->index = 0; - - if (ch == CR) { - parser->header_state = h_general; - parser->state = s_header_almost_done; - CALLBACK_DATA(header_value); - break; - } - - if (ch == LF) { - parser->state = s_header_field_start; - CALLBACK_DATA(header_value); - break; - } - - c = LOWER(ch); - - switch (parser->header_state) { - case h_upgrade: - parser->flags |= F_UPGRADE; - parser->header_state = h_general; - break; - - case h_transfer_encoding: - /* looking for 'Transfer-Encoding: chunked' */ - if ('c' == c) { - parser->header_state = h_matching_transfer_encoding_chunked; - } else { - parser->header_state = h_general; - } - break; - - case h_content_length: - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); - goto error; - } - - parser->content_length = ch - '0'; - break; - - case h_connection: - /* looking for 'Connection: keep-alive' */ - if (c == 'k') { - parser->header_state = h_matching_connection_keep_alive; - /* looking for 'Connection: close' */ - } else if (c == 'c') { - parser->header_state = h_matching_connection_close; - } else { - parser->header_state = h_general; - } - break; - - default: - parser->header_state = h_general; - break; - } - break; - } - - case s_header_value: - { - - if (ch == CR) { - parser->state = s_header_almost_done; - CALLBACK_DATA(header_value); - break; - } - - if (ch == LF) { - parser->state = s_header_almost_done; - CALLBACK_DATA_NOADVANCE(header_value); - goto reexecute_byte; - } - - c = LOWER(ch); - - switch (parser->header_state) { - case h_general: - break; - - case h_connection: - case h_transfer_encoding: - assert(0 && "Shouldn't get here."); - break; - - case h_content_length: - { - uint64_t t; - - if (ch == ' ') break; - - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); - goto error; - } - - t = parser->content_length; - t *= 10; - t += ch - '0'; - - /* Overflow? */ - if (t < parser->content_length || t == ULLONG_MAX) { - SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); - goto error; - } - - parser->content_length = t; - break; - } - - /* Transfer-Encoding: chunked */ - case h_matching_transfer_encoding_chunked: - parser->index++; - if (parser->index > sizeof(CHUNKED)-1 - || c != CHUNKED[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(CHUNKED)-2) { - parser->header_state = h_transfer_encoding_chunked; - } - break; - - /* looking for 'Connection: keep-alive' */ - case h_matching_connection_keep_alive: - parser->index++; - if (parser->index > sizeof(KEEP_ALIVE)-1 - || c != KEEP_ALIVE[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(KEEP_ALIVE)-2) { - parser->header_state = h_connection_keep_alive; - } - break; - - /* looking for 'Connection: close' */ - case h_matching_connection_close: - parser->index++; - if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(CLOSE)-2) { - parser->header_state = h_connection_close; - } - break; - - case h_transfer_encoding_chunked: - case h_connection_keep_alive: - case h_connection_close: - if (ch != ' ') parser->header_state = h_general; - break; - - default: - parser->state = s_header_value; - parser->header_state = h_general; - break; - } - break; - } - - case s_header_almost_done: - { - STRICT_CHECK(ch != LF); - - parser->state = s_header_value_lws; - - switch (parser->header_state) { - case h_connection_keep_alive: - parser->flags |= F_CONNECTION_KEEP_ALIVE; - break; - case h_connection_close: - parser->flags |= F_CONNECTION_CLOSE; - break; - case h_transfer_encoding_chunked: - parser->flags |= F_CHUNKED; - break; - default: - break; - } - - break; - } - - case s_header_value_lws: - { - if (ch == ' ' || ch == '\t') - parser->state = s_header_value_start; - else - { - parser->state = s_header_field_start; - goto reexecute_byte; - } - break; - } - - case s_headers_almost_done: - { - STRICT_CHECK(ch != LF); - - if (parser->flags & F_TRAILING) { - /* End of a chunked request */ - parser->state = NEW_MESSAGE(); - CALLBACK_NOTIFY(message_complete); - break; - } - - parser->state = s_headers_done; - - /* Set this here so that on_headers_complete() callbacks can see it */ - parser->upgrade = - (parser->flags & F_UPGRADE || parser->method == HTTP_CONNECT); - - /* Here we call the headers_complete callback. This is somewhat - * different than other callbacks because if the user returns 1, we - * will interpret that as saying that this message has no body. This - * is needed for the annoying case of recieving a response to a HEAD - * request. - * - * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so - * we have to simulate it by handling a change in errno below. - */ - if (settings->on_headers_complete) { - switch (settings->on_headers_complete(parser)) { - case 0: - break; - - case 1: - parser->flags |= F_SKIPBODY; - break; - - default: - SET_ERRNO(HPE_CB_headers_complete); - return p - data; /* Error */ - } - } - - if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { - return p - data; - } - - goto reexecute_byte; - } - - case s_headers_done: - { - STRICT_CHECK(ch != LF); - - parser->nread = 0; - - /* Exit, the rest of the connect is in a different protocol. */ - if (parser->upgrade) { - parser->state = NEW_MESSAGE(); - CALLBACK_NOTIFY(message_complete); - return (p - data) + 1; - } - - if (parser->flags & F_SKIPBODY) { - parser->state = NEW_MESSAGE(); - CALLBACK_NOTIFY(message_complete); - } else if (parser->flags & F_CHUNKED) { - /* chunked encoding - ignore Content-Length header */ - parser->state = s_chunk_size_start; - } else { - if (parser->content_length == 0) { - /* Content-Length header given but zero: Content-Length: 0\r\n */ - parser->state = NEW_MESSAGE(); - CALLBACK_NOTIFY(message_complete); - } else if (parser->content_length != ULLONG_MAX) { - /* Content-Length header given and non-zero */ - parser->state = s_body_identity; - } else { - if (parser->type == HTTP_REQUEST || - !http_message_needs_eof(parser)) { - /* Assume content-length 0 - read the next */ - parser->state = NEW_MESSAGE(); - CALLBACK_NOTIFY(message_complete); - } else { - /* Read body until EOF */ - parser->state = s_body_identity_eof; - } - } - } - - break; - } - - case s_body_identity: - { - uint64_t to_read = MIN(parser->content_length, - (uint64_t) ((data + len) - p)); - - assert(parser->content_length != 0 - && parser->content_length != ULLONG_MAX); - - /* The difference between advancing content_length and p is because - * the latter will automaticaly advance on the next loop iteration. - * Further, if content_length ends up at 0, we want to see the last - * byte again for our message complete callback. - */ - MARK(body); - parser->content_length -= to_read; - p += to_read - 1; - - if (parser->content_length == 0) { - parser->state = s_message_done; - - /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte. - * - * The alternative to doing this is to wait for the next byte to - * trigger the data callback, just as in every other case. The - * problem with this is that this makes it difficult for the test - * harness to distinguish between complete-on-EOF and - * complete-on-length. It's not clear that this distinction is - * important for applications, but let's keep it for now. - */ - CALLBACK_DATA_(body, p - body_mark + 1, p - data); - goto reexecute_byte; - } - - break; - } - - /* read until EOF */ - case s_body_identity_eof: - MARK(body); - p = data + len - 1; - - break; - - case s_message_done: - parser->state = NEW_MESSAGE(); - CALLBACK_NOTIFY(message_complete); - break; - - case s_chunk_size_start: - { - assert(parser->nread == 1); - assert(parser->flags & F_CHUNKED); - - unhex_val = unhex[(unsigned char)ch]; - if (unhex_val == -1) { - SET_ERRNO(HPE_INVALID_CHUNK_SIZE); - goto error; - } - - parser->content_length = unhex_val; - parser->state = s_chunk_size; - break; - } - - case s_chunk_size: - { - uint64_t t; - - assert(parser->flags & F_CHUNKED); - - if (ch == CR) { - parser->state = s_chunk_size_almost_done; - break; - } - - unhex_val = unhex[(unsigned char)ch]; - - if (unhex_val == -1) { - if (ch == ';' || ch == ' ') { - parser->state = s_chunk_parameters; - break; - } - - SET_ERRNO(HPE_INVALID_CHUNK_SIZE); - goto error; - } - - t = parser->content_length; - t *= 16; - t += unhex_val; - - /* Overflow? */ - if (t < parser->content_length || t == ULLONG_MAX) { - SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); - goto error; - } - - parser->content_length = t; - break; - } - - case s_chunk_parameters: - { - assert(parser->flags & F_CHUNKED); - /* just ignore this shit. TODO check for overflow */ - if (ch == CR) { - parser->state = s_chunk_size_almost_done; - break; - } - break; - } - - case s_chunk_size_almost_done: - { - assert(parser->flags & F_CHUNKED); - STRICT_CHECK(ch != LF); - - parser->nread = 0; - - if (parser->content_length == 0) { - parser->flags |= F_TRAILING; - parser->state = s_header_field_start; - } else { - parser->state = s_chunk_data; - } - break; - } - - case s_chunk_data: - { - uint64_t to_read = MIN(parser->content_length, - (uint64_t) ((data + len) - p)); - - assert(parser->flags & F_CHUNKED); - assert(parser->content_length != 0 - && parser->content_length != ULLONG_MAX); - - /* See the explanation in s_body_identity for why the content - * length and data pointers are managed this way. - */ - MARK(body); - parser->content_length -= to_read; - p += to_read - 1; - - if (parser->content_length == 0) { - parser->state = s_chunk_data_almost_done; - } - - break; - } - - case s_chunk_data_almost_done: - assert(parser->flags & F_CHUNKED); - assert(parser->content_length == 0); - STRICT_CHECK(ch != CR); - parser->state = s_chunk_data_done; - CALLBACK_DATA(body); - break; - - case s_chunk_data_done: - assert(parser->flags & F_CHUNKED); - STRICT_CHECK(ch != LF); - parser->nread = 0; - parser->state = s_chunk_size_start; - break; - - default: - assert(0 && "unhandled state"); - SET_ERRNO(HPE_INVALID_INTERNAL_STATE); - goto error; + switch (parser->state) { + + case s_dead: + /* this state is used after a 'Connection: close' message + * the parser will error out if it reads another message + */ + if (ch == CR || ch == LF) + break; + + SET_ERRNO(HPE_CLOSED_CONNECTION); + goto error; + + case s_start_req_or_res: + { + if (ch == CR || ch == LF) + break; + parser->flags = 0; + parser->content_length = ULLONG_MAX; + + if (ch == 'H') { + parser->state = s_res_or_resp_H; + + CALLBACK_NOTIFY(message_begin); + } else { + parser->type = HTTP_REQUEST; + parser->state = s_start_req; + goto reexecute_byte; } + + break; + } + + case s_res_or_resp_H: + if (ch == 'T') { + parser->type = HTTP_RESPONSE; + parser->state = s_res_HT; + } else { + if (ch != 'E') { + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + + parser->type = HTTP_REQUEST; + parser->method = HTTP_HEAD; + parser->index = 2; + parser->state = s_req_method; + } + break; + + case s_start_res: + { + parser->flags = 0; + parser->content_length = ULLONG_MAX; + + switch (ch) { + case 'H': + parser->state = s_res_H; + break; + + case CR: + case LF: + break; + + default: + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + + CALLBACK_NOTIFY(message_begin); + break; + } + + case s_res_H: + STRICT_CHECK(ch != 'T'); + parser->state = s_res_HT; + break; + + case s_res_HT: + STRICT_CHECK(ch != 'T'); + parser->state = s_res_HTT; + break; + + case s_res_HTT: + STRICT_CHECK(ch != 'P'); + parser->state = s_res_HTTP; + break; + + case s_res_HTTP: + STRICT_CHECK(ch != '/'); + parser->state = s_res_first_http_major; + break; + + case s_res_first_http_major: + if (ch < '0' || ch > '9') { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major = ch - '0'; + parser->state = s_res_http_major; + break; + + /* major HTTP version or dot */ + case s_res_http_major: + { + if (ch == '.') { + parser->state = s_res_first_http_minor; + break; + } + + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major *= 10; + parser->http_major += ch - '0'; + + if (parser->http_major > 999) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + /* first digit of minor HTTP version */ + case s_res_first_http_minor: + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor = ch - '0'; + parser->state = s_res_http_minor; + break; + + /* minor HTTP version or end of request line */ + case s_res_http_minor: + { + if (ch == ' ') { + parser->state = s_res_first_status_code; + break; + } + + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor *= 10; + parser->http_minor += ch - '0'; + + if (parser->http_minor > 999) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + case s_res_first_status_code: + { + if (!IS_NUM(ch)) { + if (ch == ' ') { + break; + } + + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + parser->status_code = ch - '0'; + parser->state = s_res_status_code; + break; + } + + case s_res_status_code: + { + if (!IS_NUM(ch)) { + switch (ch) { + case ' ': + parser->state = s_res_status; + break; + case CR: + parser->state = s_res_line_almost_done; + break; + case LF: + parser->state = s_header_field_start; + break; + default: + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + break; + } + + parser->status_code *= 10; + parser->status_code += ch - '0'; + + if (parser->status_code > 999) { + SET_ERRNO(HPE_INVALID_STATUS); + goto error; + } + + break; + } + + case s_res_status: + /* the human readable status. e.g. "NOT FOUND" + * we are not humans so just ignore this */ + if (ch == CR) { + parser->state = s_res_line_almost_done; + break; + } + + if (ch == LF) { + parser->state = s_header_field_start; + break; + } + break; + + case s_res_line_almost_done: + STRICT_CHECK(ch != LF); + parser->state = s_header_field_start; + CALLBACK_NOTIFY(status_complete); + break; + + case s_start_req: + { + if (ch == CR || ch == LF) + break; + parser->flags = 0; + parser->content_length = ULLONG_MAX; + + if (!IS_ALPHA(ch)) { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + parser->method = (enum http_method) 0; + parser->index = 1; + switch (ch) { + case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break; + case 'D': parser->method = HTTP_DELETE; break; + case 'G': parser->method = HTTP_GET; break; + case 'H': parser->method = HTTP_HEAD; break; + case 'L': parser->method = HTTP_LOCK; break; + case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH */ break; + case 'N': parser->method = HTTP_NOTIFY; break; + case 'O': parser->method = HTTP_OPTIONS; break; + case 'P': parser->method = HTTP_POST; + /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */ + break; + case 'R': parser->method = HTTP_REPORT; break; + case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break; + case 'T': parser->method = HTTP_TRACE; break; + case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE */ break; + default: + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + parser->state = s_req_method; + + CALLBACK_NOTIFY(message_begin); + + break; + } + + case s_req_method: + { + const char *matcher; + if (ch == '\0') { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + matcher = method_strings[parser->method]; + if (ch == ' ' && matcher[parser->index] == '\0') { + parser->state = s_req_spaces_before_url; + } else if (ch == matcher[parser->index]) { + ; /* nada */ + } else if (parser->method == HTTP_CONNECT) { + if (parser->index == 1 && ch == 'H') { + parser->method = HTTP_CHECKOUT; + } else if (parser->index == 2 && ch == 'P') { + parser->method = HTTP_COPY; + } else { + goto error; + } + } else if (parser->method == HTTP_MKCOL) { + if (parser->index == 1 && ch == 'O') { + parser->method = HTTP_MOVE; + } else if (parser->index == 1 && ch == 'E') { + parser->method = HTTP_MERGE; + } else if (parser->index == 1 && ch == '-') { + parser->method = HTTP_MSEARCH; + } else if (parser->index == 2 && ch == 'A') { + parser->method = HTTP_MKACTIVITY; + } else { + goto error; + } + } else if (parser->method == HTTP_SUBSCRIBE) { + if (parser->index == 1 && ch == 'E') { + parser->method = HTTP_SEARCH; + } else { + goto error; + } + } else if (parser->index == 1 && parser->method == HTTP_POST) { + if (ch == 'R') { + parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */ + } else if (ch == 'U') { + parser->method = HTTP_PUT; /* or HTTP_PURGE */ + } else if (ch == 'A') { + parser->method = HTTP_PATCH; + } else { + goto error; + } + } else if (parser->index == 2) { + if (parser->method == HTTP_PUT) { + if (ch == 'R') parser->method = HTTP_PURGE; + } else if (parser->method == HTTP_UNLOCK) { + if (ch == 'S') parser->method = HTTP_UNSUBSCRIBE; + } + } else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') { + parser->method = HTTP_PROPPATCH; + } else { + SET_ERRNO(HPE_INVALID_METHOD); + goto error; + } + + ++parser->index; + break; + } + + case s_req_spaces_before_url: + { + if (ch == ' ') break; + + MARK(url); + if (parser->method == HTTP_CONNECT) { + parser->state = s_req_server_start; + } + + parser->state = parse_url_char((enum state)parser->state, ch); + if (parser->state == s_dead) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + + break; + } + + case s_req_schema: + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + { + switch (ch) { + /* No whitespace allowed here */ + case ' ': + case CR: + case LF: + SET_ERRNO(HPE_INVALID_URL); + goto error; + default: + parser->state = parse_url_char((enum state)parser->state, ch); + if (parser->state == s_dead) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + } + + break; + } + + case s_req_server: + case s_req_server_with_at: + case s_req_path: + case s_req_query_string_start: + case s_req_query_string: + case s_req_fragment_start: + case s_req_fragment: + { + switch (ch) { + case ' ': + parser->state = s_req_http_start; + CALLBACK_DATA(url); + break; + case CR: + case LF: + parser->http_major = 0; + parser->http_minor = 9; + parser->state = (ch == CR) ? + s_req_line_almost_done : + s_header_field_start; + CALLBACK_DATA(url); + break; + default: + parser->state = parse_url_char((enum state)parser->state, ch); + if (parser->state == s_dead) { + SET_ERRNO(HPE_INVALID_URL); + goto error; + } + } + break; + } + + case s_req_http_start: + switch (ch) { + case 'H': + parser->state = s_req_http_H; + break; + case ' ': + break; + default: + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; + } + break; + + case s_req_http_H: + STRICT_CHECK(ch != 'T'); + parser->state = s_req_http_HT; + break; + + case s_req_http_HT: + STRICT_CHECK(ch != 'T'); + parser->state = s_req_http_HTT; + break; + + case s_req_http_HTT: + STRICT_CHECK(ch != 'P'); + parser->state = s_req_http_HTTP; + break; + + case s_req_http_HTTP: + STRICT_CHECK(ch != '/'); + parser->state = s_req_first_http_major; + break; + + /* first digit of major HTTP version */ + case s_req_first_http_major: + if (ch < '1' || ch > '9') { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major = ch - '0'; + parser->state = s_req_http_major; + break; + + /* major HTTP version or dot */ + case s_req_http_major: + { + if (ch == '.') { + parser->state = s_req_first_http_minor; + break; + } + + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_major *= 10; + parser->http_major += ch - '0'; + + if (parser->http_major > 999) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + /* first digit of minor HTTP version */ + case s_req_first_http_minor: + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor = ch - '0'; + parser->state = s_req_http_minor; + break; + + /* minor HTTP version or end of request line */ + case s_req_http_minor: + { + if (ch == CR) { + parser->state = s_req_line_almost_done; + break; + } + + if (ch == LF) { + parser->state = s_header_field_start; + break; + } + + /* XXX allow spaces after digit? */ + + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + parser->http_minor *= 10; + parser->http_minor += ch - '0'; + + if (parser->http_minor > 999) { + SET_ERRNO(HPE_INVALID_VERSION); + goto error; + } + + break; + } + + /* end of request line */ + case s_req_line_almost_done: + { + if (ch != LF) { + SET_ERRNO(HPE_LF_EXPECTED); + goto error; + } + + parser->state = s_header_field_start; + break; + } + + case s_header_field_start: + { + if (ch == CR) { + parser->state = s_headers_almost_done; + break; + } + + if (ch == LF) { + /* they might be just sending \n instead of \r\n so this would be + * the second \n to denote the end of headers*/ + parser->state = s_headers_almost_done; + goto reexecute_byte; + } + + c = TOKEN(ch); + + if (!c) { + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + MARK(header_field); + + parser->index = 0; + parser->state = s_header_field; + + switch (c) { + case 'c': + parser->header_state = h_C; + break; + + case 'p': + parser->header_state = h_matching_proxy_connection; + break; + + case 't': + parser->header_state = h_matching_transfer_encoding; + break; + + case 'u': + parser->header_state = h_matching_upgrade; + break; + + default: + parser->header_state = h_general; + break; + } + break; + } + + case s_header_field: + { + c = TOKEN(ch); + + if (c) { + switch (parser->header_state) { + case h_general: + break; + + case h_C: + parser->index++; + parser->header_state = (c == 'o' ? h_CO : h_general); + break; + + case h_CO: + parser->index++; + parser->header_state = (c == 'n' ? h_CON : h_general); + break; + + case h_CON: + parser->index++; + switch (c) { + case 'n': + parser->header_state = h_matching_connection; + break; + case 't': + parser->header_state = h_matching_content_length; + break; + default: + parser->header_state = h_general; + break; + } + break; + + /* connection */ + + case h_matching_connection: + parser->index++; + if (parser->index > sizeof(CONNECTION)-1 + || c != CONNECTION[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CONNECTION)-2) { + parser->header_state = h_connection; + } + break; + + /* proxy-connection */ + + case h_matching_proxy_connection: + parser->index++; + if (parser->index > sizeof(PROXY_CONNECTION)-1 + || c != PROXY_CONNECTION[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(PROXY_CONNECTION)-2) { + parser->header_state = h_connection; + } + break; + + /* content-length */ + + case h_matching_content_length: + parser->index++; + if (parser->index > sizeof(CONTENT_LENGTH)-1 + || c != CONTENT_LENGTH[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CONTENT_LENGTH)-2) { + parser->header_state = h_content_length; + } + break; + + /* transfer-encoding */ + + case h_matching_transfer_encoding: + parser->index++; + if (parser->index > sizeof(TRANSFER_ENCODING)-1 + || c != TRANSFER_ENCODING[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) { + parser->header_state = h_transfer_encoding; + } + break; + + /* upgrade */ + + case h_matching_upgrade: + parser->index++; + if (parser->index > sizeof(UPGRADE)-1 + || c != UPGRADE[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(UPGRADE)-2) { + parser->header_state = h_upgrade; + } + break; + + case h_connection: + case h_content_length: + case h_transfer_encoding: + case h_upgrade: + if (ch != ' ') parser->header_state = h_general; + break; + + default: + assert(0 && "Unknown header_state"); + break; + } + break; + } + + if (ch == ':') { + parser->state = s_header_value_start; + CALLBACK_DATA(header_field); + break; + } + + if (ch == CR) { + parser->state = s_header_almost_done; + CALLBACK_DATA(header_field); + break; + } + + if (ch == LF) { + parser->state = s_header_field_start; + CALLBACK_DATA(header_field); + break; + } + + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + case s_header_value_start: + { + if (ch == ' ' || ch == '\t') break; + + MARK(header_value); + + parser->state = s_header_value; + parser->index = 0; + + if (ch == CR) { + parser->header_state = h_general; + parser->state = s_header_almost_done; + CALLBACK_DATA(header_value); + break; + } + + if (ch == LF) { + parser->state = s_header_field_start; + CALLBACK_DATA(header_value); + break; + } + + c = LOWER(ch); + + switch (parser->header_state) { + case h_upgrade: + parser->flags |= F_UPGRADE; + parser->header_state = h_general; + break; + + case h_transfer_encoding: + /* looking for 'Transfer-Encoding: chunked' */ + if ('c' == c) { + parser->header_state = h_matching_transfer_encoding_chunked; + } else { + parser->header_state = h_general; + } + break; + + case h_content_length: + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + parser->content_length = ch - '0'; + break; + + case h_connection: + /* looking for 'Connection: keep-alive' */ + if (c == 'k') { + parser->header_state = h_matching_connection_keep_alive; + /* looking for 'Connection: close' */ + } else if (c == 'c') { + parser->header_state = h_matching_connection_close; + } else { + parser->header_state = h_general; + } + break; + + default: + parser->header_state = h_general; + break; + } + break; + } + + case s_header_value: + { + + if (ch == CR) { + parser->state = s_header_almost_done; + CALLBACK_DATA(header_value); + break; + } + + if (ch == LF) { + parser->state = s_header_almost_done; + CALLBACK_DATA_NOADVANCE(header_value); + goto reexecute_byte; + } + + c = LOWER(ch); + + switch (parser->header_state) { + case h_general: + break; + + case h_connection: + case h_transfer_encoding: + assert(0 && "Shouldn't get here."); + break; + + case h_content_length: + { + uint64_t t; + + if (ch == ' ') break; + + if (!IS_NUM(ch)) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + t = parser->content_length; + t *= 10; + t += ch - '0'; + + /* Overflow? */ + if (t < parser->content_length || t == ULLONG_MAX) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + parser->content_length = t; + break; + } + + /* Transfer-Encoding: chunked */ + case h_matching_transfer_encoding_chunked: + parser->index++; + if (parser->index > sizeof(CHUNKED)-1 + || c != CHUNKED[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CHUNKED)-2) { + parser->header_state = h_transfer_encoding_chunked; + } + break; + + /* looking for 'Connection: keep-alive' */ + case h_matching_connection_keep_alive: + parser->index++; + if (parser->index > sizeof(KEEP_ALIVE)-1 + || c != KEEP_ALIVE[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(KEEP_ALIVE)-2) { + parser->header_state = h_connection_keep_alive; + } + break; + + /* looking for 'Connection: close' */ + case h_matching_connection_close: + parser->index++; + if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) { + parser->header_state = h_general; + } else if (parser->index == sizeof(CLOSE)-2) { + parser->header_state = h_connection_close; + } + break; + + case h_transfer_encoding_chunked: + case h_connection_keep_alive: + case h_connection_close: + if (ch != ' ') parser->header_state = h_general; + break; + + default: + parser->state = s_header_value; + parser->header_state = h_general; + break; + } + break; + } + + case s_header_almost_done: + { + STRICT_CHECK(ch != LF); + + parser->state = s_header_value_lws; + + switch (parser->header_state) { + case h_connection_keep_alive: + parser->flags |= F_CONNECTION_KEEP_ALIVE; + break; + case h_connection_close: + parser->flags |= F_CONNECTION_CLOSE; + break; + case h_transfer_encoding_chunked: + parser->flags |= F_CHUNKED; + break; + default: + break; + } + + break; + } + + case s_header_value_lws: + { + if (ch == ' ' || ch == '\t') + parser->state = s_header_value_start; + else + { + parser->state = s_header_field_start; + goto reexecute_byte; + } + break; + } + + case s_headers_almost_done: + { + STRICT_CHECK(ch != LF); + + if (parser->flags & F_TRAILING) { + /* End of a chunked request */ + parser->state = NEW_MESSAGE(); + CALLBACK_NOTIFY(message_complete); + break; + } + + parser->state = s_headers_done; + + /* Set this here so that on_headers_complete() callbacks can see it */ + parser->upgrade = + (parser->flags & F_UPGRADE || parser->method == HTTP_CONNECT); + + /* Here we call the headers_complete callback. This is somewhat + * different than other callbacks because if the user returns 1, we + * will interpret that as saying that this message has no body. This + * is needed for the annoying case of recieving a response to a HEAD + * request. + * + * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so + * we have to simulate it by handling a change in errno below. + */ + if (settings->on_headers_complete) { + switch (settings->on_headers_complete(parser)) { + case 0: + break; + + case 1: + parser->flags |= F_SKIPBODY; + break; + + default: + SET_ERRNO(HPE_CB_headers_complete); + return p - data; /* Error */ + } + } + + if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { + return p - data; + } + + goto reexecute_byte; + } + + case s_headers_done: + { + STRICT_CHECK(ch != LF); + + parser->nread = 0; + + /* Exit, the rest of the connect is in a different protocol. */ + if (parser->upgrade) { + parser->state = NEW_MESSAGE(); + CALLBACK_NOTIFY(message_complete); + return (p - data) + 1; + } + + if (parser->flags & F_SKIPBODY) { + parser->state = NEW_MESSAGE(); + CALLBACK_NOTIFY(message_complete); + } else if (parser->flags & F_CHUNKED) { + /* chunked encoding - ignore Content-Length header */ + parser->state = s_chunk_size_start; + } else { + if (parser->content_length == 0) { + /* Content-Length header given but zero: Content-Length: 0\r\n */ + parser->state = NEW_MESSAGE(); + CALLBACK_NOTIFY(message_complete); + } else if (parser->content_length != ULLONG_MAX) { + /* Content-Length header given and non-zero */ + parser->state = s_body_identity; + } else { + if (parser->type == HTTP_REQUEST || + !http_message_needs_eof(parser)) { + /* Assume content-length 0 - read the next */ + parser->state = NEW_MESSAGE(); + CALLBACK_NOTIFY(message_complete); + } else { + /* Read body until EOF */ + parser->state = s_body_identity_eof; + } + } + } + + break; + } + + case s_body_identity: + { + uint64_t to_read = MIN(parser->content_length, + (uint64_t) ((data + len) - p)); + + assert(parser->content_length != 0 + && parser->content_length != ULLONG_MAX); + + /* The difference between advancing content_length and p is because + * the latter will automaticaly advance on the next loop iteration. + * Further, if content_length ends up at 0, we want to see the last + * byte again for our message complete callback. + */ + MARK(body); + parser->content_length -= to_read; + p += to_read - 1; + + if (parser->content_length == 0) { + parser->state = s_message_done; + + /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte. + * + * The alternative to doing this is to wait for the next byte to + * trigger the data callback, just as in every other case. The + * problem with this is that this makes it difficult for the test + * harness to distinguish between complete-on-EOF and + * complete-on-length. It's not clear that this distinction is + * important for applications, but let's keep it for now. + */ + CALLBACK_DATA_(body, p - body_mark + 1, p - data); + goto reexecute_byte; + } + + break; + } + + /* read until EOF */ + case s_body_identity_eof: + MARK(body); + p = data + len - 1; + + break; + + case s_message_done: + parser->state = NEW_MESSAGE(); + CALLBACK_NOTIFY(message_complete); + break; + + case s_chunk_size_start: + { + assert(parser->nread == 1); + assert(parser->flags & F_CHUNKED); + + unhex_val = unhex[(unsigned char)ch]; + if (unhex_val == -1) { + SET_ERRNO(HPE_INVALID_CHUNK_SIZE); + goto error; + } + + parser->content_length = unhex_val; + parser->state = s_chunk_size; + break; + } + + case s_chunk_size: + { + uint64_t t; + + assert(parser->flags & F_CHUNKED); + + if (ch == CR) { + parser->state = s_chunk_size_almost_done; + break; + } + + unhex_val = unhex[(unsigned char)ch]; + + if (unhex_val == -1) { + if (ch == ';' || ch == ' ') { + parser->state = s_chunk_parameters; + break; + } + + SET_ERRNO(HPE_INVALID_CHUNK_SIZE); + goto error; + } + + t = parser->content_length; + t *= 16; + t += unhex_val; + + /* Overflow? */ + if (t < parser->content_length || t == ULLONG_MAX) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + } + + parser->content_length = t; + break; + } + + case s_chunk_parameters: + { + assert(parser->flags & F_CHUNKED); + /* just ignore this shit. TODO check for overflow */ + if (ch == CR) { + parser->state = s_chunk_size_almost_done; + break; + } + break; + } + + case s_chunk_size_almost_done: + { + assert(parser->flags & F_CHUNKED); + STRICT_CHECK(ch != LF); + + parser->nread = 0; + + if (parser->content_length == 0) { + parser->flags |= F_TRAILING; + parser->state = s_header_field_start; + } else { + parser->state = s_chunk_data; + } + break; + } + + case s_chunk_data: + { + uint64_t to_read = MIN(parser->content_length, + (uint64_t) ((data + len) - p)); + + assert(parser->flags & F_CHUNKED); + assert(parser->content_length != 0 + && parser->content_length != ULLONG_MAX); + + /* See the explanation in s_body_identity for why the content + * length and data pointers are managed this way. + */ + MARK(body); + parser->content_length -= to_read; + p += to_read - 1; + + if (parser->content_length == 0) { + parser->state = s_chunk_data_almost_done; + } + + break; + } + + case s_chunk_data_almost_done: + assert(parser->flags & F_CHUNKED); + assert(parser->content_length == 0); + STRICT_CHECK(ch != CR); + parser->state = s_chunk_data_done; + CALLBACK_DATA(body); + break; + + case s_chunk_data_done: + assert(parser->flags & F_CHUNKED); + STRICT_CHECK(ch != LF); + parser->nread = 0; + parser->state = s_chunk_size_start; + break; + + default: + assert(0 && "unhandled state"); + SET_ERRNO(HPE_INVALID_INTERNAL_STATE); + goto error; } - - /* Run callbacks for any marks that we have leftover after we ran our of - * bytes. There should be at most one of these set, so it's OK to invoke - * them in series (unset marks will not result in callbacks). - * - * We use the NOADVANCE() variety of callbacks here because 'p' has already - * overflowed 'data' and this allows us to correct for the off-by-one that - * we'd otherwise have (since CALLBACK_DATA() is meant to be run with a 'p' - * value that's in-bounds). - */ - - assert(((header_field_mark ? 1 : 0) + - (header_value_mark ? 1 : 0) + - (url_mark ? 1 : 0) + - (body_mark ? 1 : 0)) <= 1); - - CALLBACK_DATA_NOADVANCE(header_field); - CALLBACK_DATA_NOADVANCE(header_value); - CALLBACK_DATA_NOADVANCE(url); - CALLBACK_DATA_NOADVANCE(body); - - return len; - + } + + /* Run callbacks for any marks that we have leftover after we ran our of + * bytes. There should be at most one of these set, so it's OK to invoke + * them in series (unset marks will not result in callbacks). + * + * We use the NOADVANCE() variety of callbacks here because 'p' has already + * overflowed 'data' and this allows us to correct for the off-by-one that + * we'd otherwise have (since CALLBACK_DATA() is meant to be run with a 'p' + * value that's in-bounds). + */ + + assert(((header_field_mark ? 1 : 0) + + (header_value_mark ? 1 : 0) + + (url_mark ? 1 : 0) + + (body_mark ? 1 : 0)) <= 1); + + CALLBACK_DATA_NOADVANCE(header_field); + CALLBACK_DATA_NOADVANCE(header_value); + CALLBACK_DATA_NOADVANCE(url); + CALLBACK_DATA_NOADVANCE(body); + + return len; + error: - if (HTTP_PARSER_ERRNO(parser) == HPE_OK) { - SET_ERRNO(HPE_UNKNOWN); - } - - return (p - data); + if (HTTP_PARSER_ERRNO(parser) == HPE_OK) { + SET_ERRNO(HPE_UNKNOWN); + } + + return (p - data); } @@ -2762,324 +2788,324 @@ error: int http_message_needs_eof (const http_parser *parser) { - if (parser->type == HTTP_REQUEST) { - return 0; - } - - /* See RFC 2616 section 4.4 */ - if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */ - parser->status_code == 204 || /* No Content */ - parser->status_code == 304 || /* Not Modified */ - parser->flags & F_SKIPBODY) { /* response to a HEAD request */ - return 0; - } - - if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) { - return 0; - } - - return 1; + if (parser->type == HTTP_REQUEST) { + return 0; + } + + /* See RFC 2616 section 4.4 */ + if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */ + parser->status_code == 204 || /* No Content */ + parser->status_code == 304 || /* Not Modified */ + parser->flags & F_SKIPBODY) { /* response to a HEAD request */ + return 0; + } + + if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) { + return 0; + } + + return 1; } int http_should_keep_alive (const http_parser *parser) { - if (parser->http_major > 0 && parser->http_minor > 0) { - /* HTTP/1.1 */ - if (parser->flags & F_CONNECTION_CLOSE) { - return 0; - } - } else { - /* HTTP/1.0 or earlier */ - if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) { - return 0; - } + if (parser->http_major > 0 && parser->http_minor > 0) { + /* HTTP/1.1 */ + if (parser->flags & F_CONNECTION_CLOSE) { + return 0; } - - return !http_message_needs_eof(parser); + } else { + /* HTTP/1.0 or earlier */ + if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) { + return 0; + } + } + + return !http_message_needs_eof(parser); } const char * http_method_str (enum http_method m) { - return ELEM_AT(method_strings, m, ""); + return ELEM_AT(method_strings, m, ""); } void http_parser_init (http_parser *parser, enum http_parser_type t) { - void *data = parser->data; /* preserve application data */ - memset(parser, 0, sizeof(*parser)); - parser->data = data; - parser->type = t; - parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res)); - parser->http_errno = HPE_OK; + void *data = parser->data; /* preserve application data */ + memset(parser, 0, sizeof(*parser)); + parser->data = data; + parser->type = t; + parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res)); + parser->http_errno = HPE_OK; } const char * http_errno_name(enum http_errno err) { - assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0]))); - return http_strerror_tab[err].name; + assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0]))); + return http_strerror_tab[err].name; } const char * http_errno_description(enum http_errno err) { - assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0]))); - return http_strerror_tab[err].description; + assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0]))); + return http_strerror_tab[err].description; } static enum http_host_state http_parse_host_char(enum http_host_state s, const char ch) { - switch(s) { - case s_http_userinfo: - case s_http_userinfo_start: - if (ch == '@') { - return s_http_host_start; - } - - if (IS_USERINFO_CHAR(ch)) { - return s_http_userinfo; - } - break; - - case s_http_host_start: - if (ch == '[') { - return s_http_host_v6_start; - } - - if (IS_HOST_CHAR(ch)) { - return s_http_host; - } - - break; - - case s_http_host: - if (IS_HOST_CHAR(ch)) { - return s_http_host; - } - - /* FALLTHROUGH */ - case s_http_host_v6_end: - if (ch == ':') { - return s_http_host_port_start; - } - - break; - - case s_http_host_v6: - if (ch == ']') { - return s_http_host_v6_end; - } - - /* FALLTHROUGH */ - case s_http_host_v6_start: - if (IS_HEX(ch) || ch == ':' || ch == '.') { - return s_http_host_v6; - } - - break; - - case s_http_host_port: - case s_http_host_port_start: - if (IS_NUM(ch)) { - return s_http_host_port; - } - - break; - - default: - break; - } - return s_http_host_dead; + switch(s) { + case s_http_userinfo: + case s_http_userinfo_start: + if (ch == '@') { + return s_http_host_start; + } + + if (IS_USERINFO_CHAR(ch)) { + return s_http_userinfo; + } + break; + + case s_http_host_start: + if (ch == '[') { + return s_http_host_v6_start; + } + + if (IS_HOST_CHAR(ch)) { + return s_http_host; + } + + break; + + case s_http_host: + if (IS_HOST_CHAR(ch)) { + return s_http_host; + } + + /* FALLTHROUGH */ + case s_http_host_v6_end: + if (ch == ':') { + return s_http_host_port_start; + } + + break; + + case s_http_host_v6: + if (ch == ']') { + return s_http_host_v6_end; + } + + /* FALLTHROUGH */ + case s_http_host_v6_start: + if (IS_HEX(ch) || ch == ':' || ch == '.') { + return s_http_host_v6; + } + + break; + + case s_http_host_port: + case s_http_host_port_start: + if (IS_NUM(ch)) { + return s_http_host_port; + } + + break; + + default: + break; + } + return s_http_host_dead; } static int http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { - enum http_host_state s; - - const char *p; - size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len; - - u->field_data[UF_HOST].len = 0; - - s = found_at ? s_http_userinfo_start : s_http_host_start; - - for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) { - enum http_host_state new_s = http_parse_host_char(s, *p); - - if (new_s == s_http_host_dead) { - return 1; - } - - switch(new_s) { - case s_http_host: - if (s != s_http_host) { - u->field_data[UF_HOST].off = p - buf; - } - u->field_data[UF_HOST].len++; - break; - - case s_http_host_v6: - if (s != s_http_host_v6) { - u->field_data[UF_HOST].off = p - buf; - } - u->field_data[UF_HOST].len++; - break; - - case s_http_host_port: - if (s != s_http_host_port) { - u->field_data[UF_PORT].off = p - buf; - u->field_data[UF_PORT].len = 0; - u->field_set |= (1 << UF_PORT); - } - u->field_data[UF_PORT].len++; - break; - - case s_http_userinfo: - if (s != s_http_userinfo) { - u->field_data[UF_USERINFO].off = p - buf; - u->field_data[UF_USERINFO].len = 0; - u->field_set |= (1 << UF_USERINFO); - } - u->field_data[UF_USERINFO].len++; - break; - - default: - break; - } - s = new_s; + enum http_host_state s; + + const char *p; + size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len; + + u->field_data[UF_HOST].len = 0; + + s = found_at ? s_http_userinfo_start : s_http_host_start; + + for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) { + enum http_host_state new_s = http_parse_host_char(s, *p); + + if (new_s == s_http_host_dead) { + return 1; } - - /* Make sure we don't end somewhere unexpected */ - switch (s) { - case s_http_host_start: - case s_http_host_v6_start: - case s_http_host_v6: - case s_http_host_port_start: - case s_http_userinfo: - case s_http_userinfo_start: - return 1; - default: - break; + + switch(new_s) { + case s_http_host: + if (s != s_http_host) { + u->field_data[UF_HOST].off = p - buf; + } + u->field_data[UF_HOST].len++; + break; + + case s_http_host_v6: + if (s != s_http_host_v6) { + u->field_data[UF_HOST].off = p - buf; + } + u->field_data[UF_HOST].len++; + break; + + case s_http_host_port: + if (s != s_http_host_port) { + u->field_data[UF_PORT].off = p - buf; + u->field_data[UF_PORT].len = 0; + u->field_set |= (1 << UF_PORT); + } + u->field_data[UF_PORT].len++; + break; + + case s_http_userinfo: + if (s != s_http_userinfo) { + u->field_data[UF_USERINFO].off = p - buf ; + u->field_data[UF_USERINFO].len = 0; + u->field_set |= (1 << UF_USERINFO); + } + u->field_data[UF_USERINFO].len++; + break; + + default: + break; } - - return 0; + s = new_s; + } + + /* Make sure we don't end somewhere unexpected */ + switch (s) { + case s_http_host_start: + case s_http_host_v6_start: + case s_http_host_v6: + case s_http_host_port_start: + case s_http_userinfo: + case s_http_userinfo_start: + return 1; + default: + break; + } + + return 0; } int http_parser_parse_url(const char *buf, size_t buflen, int is_connect, struct http_parser_url *u) { - enum state s; - const char *p; - enum http_parser_url_fields uf, old_uf; - int found_at = 0; - - u->port = u->field_set = 0; - s = is_connect ? s_req_server_start : s_req_spaces_before_url; - uf = old_uf = UF_MAX; - - for (p = buf; p < buf + buflen; p++) { - s = parse_url_char(s, *p); - - /* Figure out the next field that we're operating on */ - switch (s) { - case s_dead: - return 1; - - /* Skip delimeters */ - case s_req_schema_slash: - case s_req_schema_slash_slash: - case s_req_server_start: - case s_req_query_string_start: - case s_req_fragment_start: - continue; - - case s_req_schema: - uf = UF_SCHEMA; - break; - - case s_req_server_with_at: - found_at = 1; - - /* FALLTROUGH */ - case s_req_server: - uf = UF_HOST; - break; - - case s_req_path: - uf = UF_PATH; - break; - - case s_req_query_string: - uf = UF_QUERY; - break; - - case s_req_fragment: - uf = UF_FRAGMENT; - break; - - default: - assert(!"Unexpected state"); - return 1; - } - - /* Nothing's changed; soldier on */ - if (uf == old_uf) { - u->field_data[uf].len++; - continue; - } - - u->field_data[uf].off = p - buf; - u->field_data[uf].len = 1; - - u->field_set |= (1 << uf); - old_uf = uf; - } - - /* host must be present if there is a schema */ - /* parsing http:///toto will fail */ - if ((u->field_set & ((1 << UF_SCHEMA) | (1 << UF_HOST))) != 0) { - if (http_parse_host(buf, u, found_at) != 0) { - return 1; - } - } - - /* CONNECT requests can only contain "hostname:port" */ - if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) { + enum state s; + const char *p; + enum http_parser_url_fields uf, old_uf; + int found_at = 0; + + u->port = u->field_set = 0; + s = is_connect ? s_req_server_start : s_req_spaces_before_url; + uf = old_uf = UF_MAX; + + for (p = buf; p < buf + buflen; p++) { + s = parse_url_char(s, *p); + + /* Figure out the next field that we're operating on */ + switch (s) { + case s_dead: + return 1; + + /* Skip delimeters */ + case s_req_schema_slash: + case s_req_schema_slash_slash: + case s_req_server_start: + case s_req_query_string_start: + case s_req_fragment_start: + continue; + + case s_req_schema: + uf = UF_SCHEMA; + break; + + case s_req_server_with_at: + found_at = 1; + + /* FALLTROUGH */ + case s_req_server: + uf = UF_HOST; + break; + + case s_req_path: + uf = UF_PATH; + break; + + case s_req_query_string: + uf = UF_QUERY; + break; + + case s_req_fragment: + uf = UF_FRAGMENT; + break; + + default: + assert(!"Unexpected state"); return 1; } - - if (u->field_set & (1 << UF_PORT)) { - /* Don't bother with endp; we've already validated the string */ - unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10); - - /* Ports have a max value of 2^16 */ - if (v > 0xffff) { - return 1; - } - - u->port = (uint16_t) v; + + /* Nothing's changed; soldier on */ + if (uf == old_uf) { + u->field_data[uf].len++; + continue; } - - return 0; + + u->field_data[uf].off = p - buf; + u->field_data[uf].len = 1; + + u->field_set |= (1 << uf); + old_uf = uf; + } + + /* host must be present if there is a schema */ + /* parsing http:///toto will fail */ + if ((u->field_set & ((1 << UF_SCHEMA) | (1 << UF_HOST))) != 0) { + if (http_parse_host(buf, u, found_at) != 0) { + return 1; + } + } + + /* CONNECT requests can only contain "hostname:port" */ + if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) { + return 1; + } + + if (u->field_set & (1 << UF_PORT)) { + /* Don't bother with endp; we've already validated the string */ + unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10); + + /* Ports have a max value of 2^16 */ + if (v > 0xffff) { + return 1; + } + + u->port = (uint16_t) v; + } + + return 0; } void http_parser_pause(http_parser *parser, int paused) { - /* Users should only be pausing/unpausing a parser that is not in an error - * state. In non-debug builds, there's not much that we can do about this - * other than ignore it. - */ - if (HTTP_PARSER_ERRNO(parser) == HPE_OK || - HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) { - SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK); - } else { - assert(0 && "Attempting to pause parser in error state"); - } + /* Users should only be pausing/unpausing a parser that is not in an error + * state. In non-debug builds, there's not much that we can do about this + * other than ignore it. + */ + if (HTTP_PARSER_ERRNO(parser) == HPE_OK || + HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) { + SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK); + } else { + assert(0 && "Attempting to pause parser in error state"); + } } int diff --git a/trunk/src/protocol/srs_http_stack.hpp b/trunk/src/protocol/srs_http_stack.hpp index b450780f6..5f4b033fa 100644 --- a/trunk/src/protocol/srs_http_stack.hpp +++ b/trunk/src/protocol/srs_http_stack.hpp @@ -537,307 +537,343 @@ private: virtual std::string get_uri_field(std::string uri, void* hp_u, int field); }; +// For #if !defined(SRS_EXPORT_LIBRTMP) +#endif + +// For #ifndef SRS_PROTOCOL_HTTP_HPP #endif // The http-parser is license under MIT at https://github.com/nodejs/http-parser/blob/master/LICENSE-MIT // Version: 2.1 from https://github.com/nodejs/http-parser/releases/tag/v2.1 // File: https://github.com/nodejs/http-parser/blob/80819384450b5511a3d1c424dd92a5843c891364/http_parser.h -//Copyright Joyent, Inc. and other Node contributors. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// The SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////// + +/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ #ifndef http_parser_h #define http_parser_h #ifdef __cplusplus extern "C" { #endif - + #define HTTP_PARSER_VERSION_MAJOR 2 #define HTTP_PARSER_VERSION_MINOR 1 - + #include #if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600) #include #include - typedef __int8 int8_t; - typedef unsigned __int8 uint8_t; - typedef __int16 int16_t; - typedef unsigned __int16 uint16_t; - typedef __int32 int32_t; - typedef unsigned __int32 uint32_t; - typedef __int64 int64_t; - typedef unsigned __int64 uint64_t; +typedef __int8 int8_t; +typedef unsigned __int8 uint8_t; +typedef __int16 int16_t; +typedef unsigned __int16 uint16_t; +typedef __int32 int32_t; +typedef unsigned __int32 uint32_t; +typedef __int64 int64_t; +typedef unsigned __int64 uint64_t; #else #include #endif - - // Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run - // faster + +/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run + * faster + */ #ifndef HTTP_PARSER_STRICT # define HTTP_PARSER_STRICT 1 #endif - - /* Maximium header size allowed */ -#define HTTP_MAX_HEADER_SIZE (80*1024) - - - typedef struct http_parser http_parser; - typedef struct http_parser_settings http_parser_settings; - - - // Callbacks should return non-zero to indicate an error. The parser will - // then halt execution. - // - // The one exception is on_headers_complete. In a HTTP_RESPONSE parser - // returning '1' from on_headers_complete will tell the parser that it - // should not expect a body. This is used when receiving a response to a - // HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: - // chunked' headers that indicate the presence of a body. - // - // http_data_cb does not return data chunks. It will be call arbitrarally - // many times for each string. E.G. you might get 10 callbacks for "on_url" - // each providing just a few characters more data. - typedef int (*http_data_cb) (http_parser*, const char *at, size_t length); - typedef int (*http_cb) (http_parser*); - - - /* Request Methods */ -#define HTTP_METHOD_MAP(XX) \ - XX(0, DELETE, DELETE) \ - XX(1, GET, GET) \ - XX(2, HEAD, HEAD) \ - XX(3, POST, POST) \ - XX(4, PUT, PUT) \ - /* pathological */ \ - XX(5, CONNECT, CONNECT) \ - XX(6, OPTIONS, OPTIONS) \ - XX(7, TRACE, TRACE) \ - /* webdav */ \ - XX(8, COPY, COPY) \ - XX(9, LOCK, LOCK) \ - XX(10, MKCOL, MKCOL) \ - XX(11, MOVE, MOVE) \ - XX(12, PROPFIND, PROPFIND) \ - XX(13, PROPPATCH, PROPPATCH) \ - XX(14, SEARCH, SEARCH) \ - XX(15, UNLOCK, UNLOCK) \ - /* subversion */ \ - XX(16, REPORT, REPORT) \ - XX(17, MKACTIVITY, MKACTIVITY) \ - XX(18, CHECKOUT, CHECKOUT) \ - XX(19, MERGE, MERGE) \ - /* upnp */ \ - XX(20, MSEARCH, M-SEARCH) \ - XX(21, NOTIFY, NOTIFY) \ - XX(22, SUBSCRIBE, SUBSCRIBE) \ - XX(23, UNSUBSCRIBE, UNSUBSCRIBE) \ - /* RFC-5789 */ \ - XX(24, PATCH, PATCH) \ - XX(25, PURGE, PURGE) \ - enum http_method - { +/* Maximium header size allowed */ +#define HTTP_MAX_HEADER_SIZE (80*1024) + + +typedef struct http_parser http_parser; +typedef struct http_parser_settings http_parser_settings; + + +/* Callbacks should return non-zero to indicate an error. The parser will + * then halt execution. + * + * The one exception is on_headers_complete. In a HTTP_RESPONSE parser + * returning '1' from on_headers_complete will tell the parser that it + * should not expect a body. This is used when receiving a response to a + * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: + * chunked' headers that indicate the presence of a body. + * + * http_data_cb does not return data chunks. It will be call arbitrarally + * many times for each string. E.G. you might get 10 callbacks for "on_url" + * each providing just a few characters more data. + */ +typedef int (*http_data_cb) (http_parser*, const char *at, size_t length); +typedef int (*http_cb) (http_parser*); + + +/* Request Methods */ +#define HTTP_METHOD_MAP(XX) \ + XX(0, DELETE, DELETE) \ + XX(1, GET, GET) \ + XX(2, HEAD, HEAD) \ + XX(3, POST, POST) \ + XX(4, PUT, PUT) \ + /* pathological */ \ + XX(5, CONNECT, CONNECT) \ + XX(6, OPTIONS, OPTIONS) \ + XX(7, TRACE, TRACE) \ + /* webdav */ \ + XX(8, COPY, COPY) \ + XX(9, LOCK, LOCK) \ + XX(10, MKCOL, MKCOL) \ + XX(11, MOVE, MOVE) \ + XX(12, PROPFIND, PROPFIND) \ + XX(13, PROPPATCH, PROPPATCH) \ + XX(14, SEARCH, SEARCH) \ + XX(15, UNLOCK, UNLOCK) \ + /* subversion */ \ + XX(16, REPORT, REPORT) \ + XX(17, MKACTIVITY, MKACTIVITY) \ + XX(18, CHECKOUT, CHECKOUT) \ + XX(19, MERGE, MERGE) \ + /* upnp */ \ + XX(20, MSEARCH, M-SEARCH) \ + XX(21, NOTIFY, NOTIFY) \ + XX(22, SUBSCRIBE, SUBSCRIBE) \ + XX(23, UNSUBSCRIBE, UNSUBSCRIBE) \ + /* RFC-5789 */ \ + XX(24, PATCH, PATCH) \ + XX(25, PURGE, PURGE) \ + +enum http_method + { #define XX(num, name, string) HTTP_##name = num, - HTTP_METHOD_MAP(XX) + HTTP_METHOD_MAP(XX) #undef XX - }; - - - enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH }; - - - /* Flag values for http_parser.flags field */ - enum flags - { F_CHUNKED = 1 << 0 - , F_CONNECTION_KEEP_ALIVE = 1 << 1 - , F_CONNECTION_CLOSE = 1 << 2 - , F_TRAILING = 1 << 3 - , F_UPGRADE = 1 << 4 - , F_SKIPBODY = 1 << 5 - }; - - - // Map for errno-related constants - // The provided argument should be a macro that takes 2 arguments. + }; + + +enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH }; + + +/* Flag values for http_parser.flags field */ +enum flags + { F_CHUNKED = 1 << 0 + , F_CONNECTION_KEEP_ALIVE = 1 << 1 + , F_CONNECTION_CLOSE = 1 << 2 + , F_TRAILING = 1 << 3 + , F_UPGRADE = 1 << 4 + , F_SKIPBODY = 1 << 5 + }; + + +/* Map for errno-related constants + * + * The provided argument should be a macro that takes 2 arguments. + */ #define HTTP_ERRNO_MAP(XX) \ - /* No error */ \ - XX(OK, "success") \ - \ - /* Callback-related errors */ \ - XX(CB_message_begin, "the on_message_begin callback failed") \ - XX(CB_status_complete, "the on_status_complete callback failed") \ - XX(CB_url, "the on_url callback failed") \ - XX(CB_header_field, "the on_header_field callback failed") \ - XX(CB_header_value, "the on_header_value callback failed") \ - XX(CB_headers_complete, "the on_headers_complete callback failed") \ - XX(CB_body, "the on_body callback failed") \ - XX(CB_message_complete, "the on_message_complete callback failed") \ - \ - /* Parsing-related errors */ \ - XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \ - XX(HEADER_OVERFLOW, \ - "too many header bytes seen; overflow detected") \ - XX(CLOSED_CONNECTION, \ - "data received after completed connection: close message") \ - XX(INVALID_VERSION, "invalid HTTP version") \ - XX(INVALID_STATUS, "invalid HTTP status code") \ - XX(INVALID_METHOD, "invalid HTTP method") \ - XX(INVALID_URL, "invalid URL") \ - XX(INVALID_HOST, "invalid host") \ - XX(INVALID_PORT, "invalid port") \ - XX(INVALID_PATH, "invalid path") \ - XX(INVALID_QUERY_STRING, "invalid query string") \ - XX(INVALID_FRAGMENT, "invalid fragment") \ - XX(LF_EXPECTED, "LF character expected") \ - XX(INVALID_HEADER_TOKEN, "invalid character in header") \ - XX(INVALID_CONTENT_LENGTH, \ - "invalid character in content-length header") \ - XX(INVALID_CHUNK_SIZE, \ - "invalid character in chunk size header") \ - XX(INVALID_CONSTANT, "invalid constant string") \ - XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\ - XX(STRICT, "strict mode assertion failed") \ - XX(PAUSED, "parser is paused") \ - XX(UNKNOWN, "an unknown error occurred") - - - /* Define HPE_* values for each errno value above */ + /* No error */ \ + XX(OK, "success") \ + \ + /* Callback-related errors */ \ + XX(CB_message_begin, "the on_message_begin callback failed") \ + XX(CB_status_complete, "the on_status_complete callback failed") \ + XX(CB_url, "the on_url callback failed") \ + XX(CB_header_field, "the on_header_field callback failed") \ + XX(CB_header_value, "the on_header_value callback failed") \ + XX(CB_headers_complete, "the on_headers_complete callback failed") \ + XX(CB_body, "the on_body callback failed") \ + XX(CB_message_complete, "the on_message_complete callback failed") \ + \ + /* Parsing-related errors */ \ + XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \ + XX(HEADER_OVERFLOW, \ + "too many header bytes seen; overflow detected") \ + XX(CLOSED_CONNECTION, \ + "data received after completed connection: close message") \ + XX(INVALID_VERSION, "invalid HTTP version") \ + XX(INVALID_STATUS, "invalid HTTP status code") \ + XX(INVALID_METHOD, "invalid HTTP method") \ + XX(INVALID_URL, "invalid URL") \ + XX(INVALID_HOST, "invalid host") \ + XX(INVALID_PORT, "invalid port") \ + XX(INVALID_PATH, "invalid path") \ + XX(INVALID_QUERY_STRING, "invalid query string") \ + XX(INVALID_FRAGMENT, "invalid fragment") \ + XX(LF_EXPECTED, "LF character expected") \ + XX(INVALID_HEADER_TOKEN, "invalid character in header") \ + XX(INVALID_CONTENT_LENGTH, \ + "invalid character in content-length header") \ + XX(INVALID_CHUNK_SIZE, \ + "invalid character in chunk size header") \ + XX(INVALID_CONSTANT, "invalid constant string") \ + XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\ + XX(STRICT, "strict mode assertion failed") \ + XX(PAUSED, "parser is paused") \ + XX(UNKNOWN, "an unknown error occurred") + + +/* Define HPE_* values for each errno value above */ #define HTTP_ERRNO_GEN(n, s) HPE_##n, - enum http_errno { - HTTP_ERRNO_MAP(HTTP_ERRNO_GEN) - }; +enum http_errno { + HTTP_ERRNO_MAP(HTTP_ERRNO_GEN) +}; #undef HTTP_ERRNO_GEN - - - /* Get an http_errno value from an http_parser */ + + +/* Get an http_errno value from an http_parser */ #define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno) - - - struct http_parser { - /** PRIVATE **/ - unsigned char type : 2; /* enum http_parser_type */ - unsigned char flags : 6; /* F_* values from 'flags' enum; semi-public */ - unsigned char state; /* enum state from http_parser.c */ - unsigned char header_state; /* enum header_state from http_parser.c */ - unsigned char index; /* index into current matcher */ - - uint32_t nread; /* # bytes read in various scenarios */ - uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */ - - /** READ-ONLY **/ - unsigned short http_major; - unsigned short http_minor; - unsigned short status_code; /* responses only */ - unsigned char method; /* requests only */ - unsigned char http_errno : 7; - - // 1 = Upgrade header was present and the parser has exited because of that. - // 0 = No upgrade header present. - // Should be checked when http_parser_execute() returns in addition to - // error checking. - unsigned char upgrade : 1; - - /** PUBLIC **/ - void *data; /* A pointer to get hook to the "connection" or "socket" object */ - }; - - - struct http_parser_settings { - http_cb on_message_begin; - http_data_cb on_url; - http_cb on_status_complete; - http_data_cb on_header_field; - http_data_cb on_header_value; - http_cb on_headers_complete; - http_data_cb on_body; - http_cb on_message_complete; - }; - - - enum http_parser_url_fields - { UF_SCHEMA = 0 - , UF_HOST = 1 - , UF_PORT = 2 - , UF_PATH = 3 - , UF_QUERY = 4 - , UF_FRAGMENT = 5 - , UF_USERINFO = 6 - , UF_MAX = 7 - }; - - - // Result structure for http_parser_parse_url(). - // Callers should index into field_data[] with UF_* values iff field_set - // has the relevant (1 << UF_*) bit set. As a courtesy to clients (and - // because we probably have padding left over), we convert any port to - // a uint16_t. - struct http_parser_url { - uint16_t field_set; /* Bitmask of (1 << UF_*) values */ - uint16_t port; /* Converted UF_PORT string */ - - struct { - uint16_t off; /* Offset into buffer in which field starts */ - uint16_t len; /* Length of run in buffer */ - } field_data[UF_MAX]; - }; - - - void http_parser_init(http_parser *parser, enum http_parser_type type); - - - size_t http_parser_execute(http_parser *parser, - const http_parser_settings *settings, - const char *data, - size_t len); - - - // If http_should_keep_alive() in the on_headers_complete or - // on_message_complete callback returns 0, then this should be - // The last message on the connection. - // If you are the server, respond with the "Connection: close" header. - // If you are the client, close the connection. - int http_should_keep_alive(const http_parser *parser); - - /* Returns a string version of the HTTP method. */ - const char *http_method_str(enum http_method m); - - /* Return a string name of the given error */ - const char *http_errno_name(enum http_errno err); - - /* Return a string description of the given error */ - const char *http_errno_description(enum http_errno err); - - /* Parse a URL; return nonzero on failure */ - int http_parser_parse_url(const char *buf, size_t buflen, - int is_connect, - struct http_parser_url *u); - - /* Pause or un-pause the parser; a nonzero value pauses */ - void http_parser_pause(http_parser *parser, int paused); - - /* Checks if this is the final chunk of the body. */ - int http_body_is_final(const http_parser *parser); - + + +struct http_parser { + /** PRIVATE **/ + unsigned char type : 2; /* enum http_parser_type */ + unsigned char flags : 6; /* F_* values from 'flags' enum; semi-public */ + unsigned char state; /* enum state from http_parser.c */ + unsigned char header_state; /* enum header_state from http_parser.c */ + unsigned char index; /* index into current matcher */ + + uint32_t nread; /* # bytes read in various scenarios */ + uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */ + + /** READ-ONLY **/ + unsigned short http_major; + unsigned short http_minor; + unsigned short status_code; /* responses only */ + unsigned char method; /* requests only */ + unsigned char http_errno : 7; + + /* 1 = Upgrade header was present and the parser has exited because of that. + * 0 = No upgrade header present. + * Should be checked when http_parser_execute() returns in addition to + * error checking. + */ + unsigned char upgrade : 1; + + /** PUBLIC **/ + void *data; /* A pointer to get hook to the "connection" or "socket" object */ +}; + + +struct http_parser_settings { + http_cb on_message_begin; + http_data_cb on_url; + http_cb on_status_complete; + http_data_cb on_header_field; + http_data_cb on_header_value; + http_cb on_headers_complete; + http_data_cb on_body; + http_cb on_message_complete; +}; + + +enum http_parser_url_fields + { UF_SCHEMA = 0 + , UF_HOST = 1 + , UF_PORT = 2 + , UF_PATH = 3 + , UF_QUERY = 4 + , UF_FRAGMENT = 5 + , UF_USERINFO = 6 + , UF_MAX = 7 + }; + + +/* Result structure for http_parser_parse_url(). + * + * Callers should index into field_data[] with UF_* values iff field_set + * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and + * because we probably have padding left over), we convert any port to + * a uint16_t. + */ +struct http_parser_url { + uint16_t field_set; /* Bitmask of (1 << UF_*) values */ + uint16_t port; /* Converted UF_PORT string */ + + struct { + uint16_t off; /* Offset into buffer in which field starts */ + uint16_t len; /* Length of run in buffer */ + } field_data[UF_MAX]; +}; + + +void http_parser_init(http_parser *parser, enum http_parser_type type); + + +size_t http_parser_execute(http_parser *parser, + const http_parser_settings *settings, + const char *data, + size_t len); + + +/* If http_should_keep_alive() in the on_headers_complete or + * on_message_complete callback returns 0, then this should be + * the last message on the connection. + * If you are the server, respond with the "Connection: close" header. + * If you are the client, close the connection. + */ +int http_should_keep_alive(const http_parser *parser); + +/* Returns a string version of the HTTP method. */ +const char *http_method_str(enum http_method m); + +/* Return a string name of the given error */ +const char *http_errno_name(enum http_errno err); + +/* Return a string description of the given error */ +const char *http_errno_description(enum http_errno err); + +/* Parse a URL; return nonzero on failure */ +int http_parser_parse_url(const char *buf, size_t buflen, + int is_connect, + struct http_parser_url *u); + +/* Pause or un-pause the parser; a nonzero value pauses */ +void http_parser_pause(http_parser *parser, int paused); + +/* Checks if this is the final chunk of the body. */ +int http_body_is_final(const http_parser *parser); + #ifdef __cplusplus } #endif #endif -#endif - From cfc92d5e93f715e87a9c528ec669990c3394f8ef Mon Sep 17 00:00:00 2001 From: winlin Date: Wed, 24 Apr 2019 09:37:25 +0800 Subject: [PATCH 08/25] Use http-parser 2.9.2 --- trunk/src/protocol/srs_http_stack.cpp | 1137 ++++++++++++------- trunk/src/protocol/srs_http_stack.hpp | 205 +++- trunk/src/service/srs_service_http_conn.cpp | 6 + trunk/src/service/srs_service_http_conn.hpp | 2 +- trunk/src/utest/srs_utest_protocol.cpp | 309 ++++- 5 files changed, 1196 insertions(+), 463 deletions(-) diff --git a/trunk/src/protocol/srs_http_stack.cpp b/trunk/src/protocol/srs_http_stack.cpp index fe479c35e..3f4db8559 100644 --- a/trunk/src/protocol/srs_http_stack.cpp +++ b/trunk/src/protocol/srs_http_stack.cpp @@ -937,10 +937,7 @@ string SrsHttpUri::get_uri_field(string uri, void* php_u, int ifield) ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// -/* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev - * - * Additional changes are licensed under the same terms as NGINX and - * copyright Joyent, Inc. and other Node contributors. All rights reserved. +/* Copyright Joyent, Inc. and other Node contributors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -964,10 +961,11 @@ string SrsHttpUri::get_uri_field(string uri, void* php_u, int ifield) #include #include #include -#include #include #include +static uint32_t max_header_size = HTTP_MAX_HEADER_SIZE; + #ifndef ULLONG_MAX # define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */ #endif @@ -992,22 +990,45 @@ string SrsHttpUri::get_uri_field(string uri, void* php_u, int ifield) #define SET_ERRNO(e) \ do { \ + parser->nread = nread; \ parser->http_errno = (e); \ } while(0) +#define CURRENT_STATE() p_state +#define UPDATE_STATE(V) p_state = (enum state) (V); +#define RETURN(V) \ +do { \ + parser->nread = nread; \ + parser->state = CURRENT_STATE(); \ + return (V); \ +} while (0); +#define REEXECUTE() \ + goto reexecute; \ + + +#ifdef __GNUC__ +# define LIKELY(X) __builtin_expect(!!(X), 1) +# define UNLIKELY(X) __builtin_expect(!!(X), 0) +#else +# define LIKELY(X) (X) +# define UNLIKELY(X) (X) +#endif + /* Run the notify callback FOR, returning ER if it fails */ #define CALLBACK_NOTIFY_(FOR, ER) \ do { \ assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ \ - if (settings->on_##FOR) { \ - if (0 != settings->on_##FOR(parser)) { \ + if (LIKELY(settings->on_##FOR)) { \ + parser->state = CURRENT_STATE(); \ + if (UNLIKELY(0 != settings->on_##FOR(parser))) { \ SET_ERRNO(HPE_CB_##FOR); \ } \ + UPDATE_STATE(parser->state); \ \ /* We either errored above or got paused; get out */ \ - if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { \ + if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ return (ER); \ } \ } \ @@ -1025,13 +1046,16 @@ do { \ assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ \ if (FOR##_mark) { \ - if (settings->on_##FOR) { \ - if (0 != settings->on_##FOR(parser, FOR##_mark, (LEN))) { \ + if (LIKELY(settings->on_##FOR)) { \ + parser->state = CURRENT_STATE(); \ + if (UNLIKELY(0 != \ + settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \ SET_ERRNO(HPE_CB_##FOR); \ } \ + UPDATE_STATE(parser->state); \ \ /* We either errored above or got paused; get out */ \ - if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { \ + if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ return (ER); \ } \ } \ @@ -1055,6 +1079,26 @@ do { \ } \ } while (0) +/* Don't allow the total size of the HTTP headers (including the status + * line) to exceed max_header_size. This check is here to protect + * embedders against denial-of-service attacks where the attacker feeds + * us a never-ending header that the embedder keeps buffering. + * + * This check is arguably the responsibility of embedders but we're doing + * it on the embedder's behalf because most won't bother and this way we + * make the web a little safer. max_header_size is still far bigger + * than any reasonable request or response so this should never affect + * day-to-day operation. + */ +#define COUNT_HEADER_SIZE(V) \ +do { \ + nread += (uint32_t)(V); \ + if (UNLIKELY(nread > max_header_size)) { \ + SET_ERRNO(HPE_HEADER_OVERFLOW); \ + goto error; \ + } \ +} while (0) + #define PROXY_CONNECTION "proxy-connection" #define CONNECTION "connection" @@ -1091,7 +1135,7 @@ static const char tokens[256] = { /* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ 0, 0, 0, 0, 0, 0, 0, 0, /* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ - 0, '!', 0, '#', '$', '%', '&', '\'', + ' ', '!', 0, '#', '$', '%', '&', '\'', /* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ 0, 0, '*', '+', 0, '-', '.', 0, /* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ @@ -1181,12 +1225,13 @@ enum state , s_res_HT , s_res_HTT , s_res_HTTP - , s_res_first_http_major , s_res_http_major - , s_res_first_http_minor + , s_res_http_dot , s_res_http_minor + , s_res_http_end , s_res_first_status_code , s_res_status_code + , s_res_status_start , s_res_status , s_res_line_almost_done @@ -1210,14 +1255,19 @@ enum state , s_req_http_HT , s_req_http_HTT , s_req_http_HTTP - , s_req_first_http_major + , s_req_http_I + , s_req_http_IC , s_req_http_major - , s_req_first_http_minor + , s_req_http_dot , s_req_http_minor + , s_req_http_end , s_req_line_almost_done , s_header_field_start , s_header_field + , s_header_value_discard_ws + , s_header_value_discard_ws_almost_done + , s_header_value_discard_lws , s_header_value_start , s_header_value , s_header_value_lws @@ -1265,16 +1315,22 @@ enum header_states , h_connection , h_content_length + , h_content_length_num + , h_content_length_ws , h_transfer_encoding , h_upgrade , h_matching_transfer_encoding_chunked + , h_matching_connection_token_start , h_matching_connection_keep_alive , h_matching_connection_close + , h_matching_connection_upgrade + , h_matching_connection_token , h_transfer_encoding_chunked , h_connection_keep_alive , h_connection_close + , h_connection_upgrade }; enum http_host_state @@ -1287,6 +1343,8 @@ enum http_host_state , s_http_host , s_http_host_v6 , s_http_host_v6_end + , s_http_host_v6_zone_start + , s_http_host_v6_zone , s_http_host_port_start , s_http_host_port }; @@ -1306,18 +1364,26 @@ enum http_host_state (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \ (c) == '$' || (c) == ',') +#define STRICT_TOKEN(c) ((c == ' ') ? 0 : tokens[(unsigned char)c]) + #if HTTP_PARSER_STRICT -#define TOKEN(c) (tokens[(unsigned char)c]) +#define TOKEN(c) STRICT_TOKEN(c) #define IS_URL_CHAR(c) (BIT_AT(normal_url_char, (unsigned char)c)) #define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-') #else -#define TOKEN(c) ((c == ' ') ? ' ' : tokens[(unsigned char)c]) +#define TOKEN(c) tokens[(unsigned char)c] #define IS_URL_CHAR(c) \ (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80)) #define IS_HOST_CHAR(c) \ (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_') #endif +/** + * Verify that a char is a valid visible (printable) US-ASCII + * character or %x80-FF + **/ +#define IS_HEADER_CHAR(ch) \ + (ch == CR || ch == LF || ch == 9 || ((unsigned char)ch > 31 && ch != 127)) #define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res) @@ -1419,7 +1485,7 @@ parse_url_char(enum state s, const char ch) return s_dead; } - /* FALLTHROUGH */ + /* fall through */ case s_req_server_start: case s_req_server: if (ch == '/') { @@ -1520,6 +1586,10 @@ size_t http_parser_execute (http_parser *parser, const char *header_value_mark = 0; const char *url_mark = 0; const char *body_mark = 0; + const char *status_mark = 0; + enum state p_state = (enum state) parser->state; + const unsigned int lenient = parser->lenient_http_headers; + uint32_t nread = parser->nread; /* We're in an error state. Don't bother doing anything. */ if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { @@ -1527,7 +1597,7 @@ size_t http_parser_execute (http_parser *parser, } if (len == 0) { - switch (parser->state) { + switch (CURRENT_STATE()) { case s_body_identity_eof: /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if * we got paused. @@ -1548,11 +1618,11 @@ size_t http_parser_execute (http_parser *parser, } - if (parser->state == s_header_field) + if (CURRENT_STATE() == s_header_field) header_field_mark = data; - if (parser->state == s_header_value) + if (CURRENT_STATE() == s_header_value) header_value_mark = data; - switch (parser->state) { + switch (CURRENT_STATE()) { case s_req_path: case s_req_schema: case s_req_schema_slash: @@ -1566,28 +1636,27 @@ size_t http_parser_execute (http_parser *parser, case s_req_fragment: url_mark = data; break; + case s_res_status: + status_mark = data; + break; + default: + break; } for (p=data; p != data + len; p++) { ch = *p; - if (PARSING_HEADER(parser->state)) { - ++parser->nread; - /* Buffer overflow attack */ - if (parser->nread > HTTP_MAX_HEADER_SIZE) { - SET_ERRNO(HPE_HEADER_OVERFLOW); - goto error; - } - } + if (PARSING_HEADER(CURRENT_STATE())) + COUNT_HEADER_SIZE(1); - reexecute_byte: - switch (parser->state) { +reexecute: + switch (CURRENT_STATE()) { case s_dead: /* this state is used after a 'Connection: close' message * the parser will error out if it reads another message */ - if (ch == CR || ch == LF) + if (LIKELY(ch == CR || ch == LF)) break; SET_ERRNO(HPE_CLOSED_CONNECTION); @@ -1601,13 +1670,13 @@ size_t http_parser_execute (http_parser *parser, parser->content_length = ULLONG_MAX; if (ch == 'H') { - parser->state = s_res_or_resp_H; + UPDATE_STATE(s_res_or_resp_H); CALLBACK_NOTIFY(message_begin); } else { parser->type = HTTP_REQUEST; - parser->state = s_start_req; - goto reexecute_byte; + UPDATE_STATE(s_start_req); + REEXECUTE(); } break; @@ -1616,9 +1685,9 @@ size_t http_parser_execute (http_parser *parser, case s_res_or_resp_H: if (ch == 'T') { parser->type = HTTP_RESPONSE; - parser->state = s_res_HT; + UPDATE_STATE(s_res_HT); } else { - if (ch != 'E') { + if (UNLIKELY(ch != 'E')) { SET_ERRNO(HPE_INVALID_CONSTANT); goto error; } @@ -1626,27 +1695,22 @@ size_t http_parser_execute (http_parser *parser, parser->type = HTTP_REQUEST; parser->method = HTTP_HEAD; parser->index = 2; - parser->state = s_req_method; + UPDATE_STATE(s_req_method); } break; case s_start_res: { + if (ch == CR || ch == LF) + break; parser->flags = 0; parser->content_length = ULLONG_MAX; - switch (ch) { - case 'H': - parser->state = s_res_H; - break; - - case CR: - case LF: - break; - - default: - SET_ERRNO(HPE_INVALID_CONSTANT); - goto error; + if (ch == 'H') { + UPDATE_STATE(s_res_H); + } else { + SET_ERRNO(HPE_INVALID_CONSTANT); + goto error; } CALLBACK_NOTIFY(message_begin); @@ -1655,90 +1719,63 @@ size_t http_parser_execute (http_parser *parser, case s_res_H: STRICT_CHECK(ch != 'T'); - parser->state = s_res_HT; + UPDATE_STATE(s_res_HT); break; case s_res_HT: STRICT_CHECK(ch != 'T'); - parser->state = s_res_HTT; + UPDATE_STATE(s_res_HTT); break; case s_res_HTT: STRICT_CHECK(ch != 'P'); - parser->state = s_res_HTTP; + UPDATE_STATE(s_res_HTTP); break; case s_res_HTTP: STRICT_CHECK(ch != '/'); - parser->state = s_res_first_http_major; + UPDATE_STATE(s_res_http_major); break; - case s_res_first_http_major: - if (ch < '0' || ch > '9') { + case s_res_http_major: + if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major = ch - '0'; - parser->state = s_res_http_major; + UPDATE_STATE(s_res_http_dot); break; - /* major HTTP version or dot */ - case s_res_http_major: + case s_res_http_dot: { - if (ch == '.') { - parser->state = s_res_first_http_minor; - break; - } - - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_major *= 10; - parser->http_major += ch - '0'; - - if (parser->http_major > 999) { + if (UNLIKELY(ch != '.')) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } + UPDATE_STATE(s_res_http_minor); break; } - /* first digit of minor HTTP version */ - case s_res_first_http_minor: - if (!IS_NUM(ch)) { + case s_res_http_minor: + if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor = ch - '0'; - parser->state = s_res_http_minor; + UPDATE_STATE(s_res_http_end); break; - /* minor HTTP version or end of request line */ - case s_res_http_minor: + case s_res_http_end: { - if (ch == ' ') { - parser->state = s_res_first_status_code; - break; - } - - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_minor *= 10; - parser->http_minor += ch - '0'; - - if (parser->http_minor > 999) { + if (UNLIKELY(ch != ' ')) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } + UPDATE_STATE(s_res_first_status_code); break; } @@ -1753,7 +1790,7 @@ size_t http_parser_execute (http_parser *parser, goto error; } parser->status_code = ch - '0'; - parser->state = s_res_status_code; + UPDATE_STATE(s_res_status_code); break; } @@ -1762,13 +1799,12 @@ size_t http_parser_execute (http_parser *parser, if (!IS_NUM(ch)) { switch (ch) { case ' ': - parser->state = s_res_status; + UPDATE_STATE(s_res_status_start); break; case CR: - parser->state = s_res_line_almost_done; - break; case LF: - parser->state = s_header_field_start; + UPDATE_STATE(s_res_status_start); + REEXECUTE(); break; default: SET_ERRNO(HPE_INVALID_STATUS); @@ -1780,7 +1816,7 @@ size_t http_parser_execute (http_parser *parser, parser->status_code *= 10; parser->status_code += ch - '0'; - if (parser->status_code > 999) { + if (UNLIKELY(parser->status_code > 999)) { SET_ERRNO(HPE_INVALID_STATUS); goto error; } @@ -1788,24 +1824,36 @@ size_t http_parser_execute (http_parser *parser, break; } + case s_res_status_start: + { + MARK(status); + UPDATE_STATE(s_res_status); + parser->index = 0; + + if (ch == CR || ch == LF) + REEXECUTE(); + + break; + } + case s_res_status: - /* the human readable status. e.g. "NOT FOUND" - * we are not humans so just ignore this */ if (ch == CR) { - parser->state = s_res_line_almost_done; + UPDATE_STATE(s_res_line_almost_done); + CALLBACK_DATA(status); break; } if (ch == LF) { - parser->state = s_header_field_start; + UPDATE_STATE(s_header_field_start); + CALLBACK_DATA(status); break; } + break; case s_res_line_almost_done: STRICT_CHECK(ch != LF); - parser->state = s_header_field_start; - CALLBACK_NOTIFY(status_complete); + UPDATE_STATE(s_header_field_start); break; case s_start_req: @@ -1815,7 +1863,7 @@ size_t http_parser_execute (http_parser *parser, parser->flags = 0; parser->content_length = ULLONG_MAX; - if (!IS_ALPHA(ch)) { + if (UNLIKELY(!IS_ALPHA(ch))) { SET_ERRNO(HPE_INVALID_METHOD); goto error; } @@ -1823,26 +1871,28 @@ size_t http_parser_execute (http_parser *parser, parser->method = (enum http_method) 0; parser->index = 1; switch (ch) { + case 'A': parser->method = HTTP_ACL; break; + case 'B': parser->method = HTTP_BIND; break; case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break; case 'D': parser->method = HTTP_DELETE; break; case 'G': parser->method = HTTP_GET; break; case 'H': parser->method = HTTP_HEAD; break; - case 'L': parser->method = HTTP_LOCK; break; - case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH */ break; + case 'L': parser->method = HTTP_LOCK; /* or LINK */ break; + case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break; case 'N': parser->method = HTTP_NOTIFY; break; case 'O': parser->method = HTTP_OPTIONS; break; case 'P': parser->method = HTTP_POST; /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */ break; - case 'R': parser->method = HTTP_REPORT; break; - case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break; + case 'R': parser->method = HTTP_REPORT; /* or REBIND */ break; + case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH, SOURCE */ break; case 'T': parser->method = HTTP_TRACE; break; - case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE */ break; + case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE, UNBIND, UNLINK */ break; default: SET_ERRNO(HPE_INVALID_METHOD); goto error; } - parser->state = s_req_method; + UPDATE_STATE(s_req_method); CALLBACK_NOTIFY(message_begin); @@ -1852,60 +1902,47 @@ size_t http_parser_execute (http_parser *parser, case s_req_method: { const char *matcher; - if (ch == '\0') { + if (UNLIKELY(ch == '\0')) { SET_ERRNO(HPE_INVALID_METHOD); goto error; } matcher = method_strings[parser->method]; if (ch == ' ' && matcher[parser->index] == '\0') { - parser->state = s_req_spaces_before_url; + UPDATE_STATE(s_req_spaces_before_url); } else if (ch == matcher[parser->index]) { ; /* nada */ - } else if (parser->method == HTTP_CONNECT) { - if (parser->index == 1 && ch == 'H') { - parser->method = HTTP_CHECKOUT; - } else if (parser->index == 2 && ch == 'P') { - parser->method = HTTP_COPY; - } else { - goto error; + } else if ((ch >= 'A' && ch <= 'Z') || ch == '-') { + + switch (parser->method << 16 | parser->index << 8 | ch) { +#define XX(meth, pos, ch, new_meth) \ + case (HTTP_##meth << 16 | pos << 8 | ch): \ + parser->method = HTTP_##new_meth; break; + + XX(POST, 1, 'U', PUT) + XX(POST, 1, 'A', PATCH) + XX(POST, 1, 'R', PROPFIND) + XX(PUT, 2, 'R', PURGE) + XX(CONNECT, 1, 'H', CHECKOUT) + XX(CONNECT, 2, 'P', COPY) + XX(MKCOL, 1, 'O', MOVE) + XX(MKCOL, 1, 'E', MERGE) + XX(MKCOL, 1, '-', MSEARCH) + XX(MKCOL, 2, 'A', MKACTIVITY) + XX(MKCOL, 3, 'A', MKCALENDAR) + XX(SUBSCRIBE, 1, 'E', SEARCH) + XX(SUBSCRIBE, 1, 'O', SOURCE) + XX(REPORT, 2, 'B', REBIND) + XX(PROPFIND, 4, 'P', PROPPATCH) + XX(LOCK, 1, 'I', LINK) + XX(UNLOCK, 2, 'S', UNSUBSCRIBE) + XX(UNLOCK, 2, 'B', UNBIND) + XX(UNLOCK, 3, 'I', UNLINK) +#undef XX + default: + SET_ERRNO(HPE_INVALID_METHOD); + goto error; } - } else if (parser->method == HTTP_MKCOL) { - if (parser->index == 1 && ch == 'O') { - parser->method = HTTP_MOVE; - } else if (parser->index == 1 && ch == 'E') { - parser->method = HTTP_MERGE; - } else if (parser->index == 1 && ch == '-') { - parser->method = HTTP_MSEARCH; - } else if (parser->index == 2 && ch == 'A') { - parser->method = HTTP_MKACTIVITY; - } else { - goto error; - } - } else if (parser->method == HTTP_SUBSCRIBE) { - if (parser->index == 1 && ch == 'E') { - parser->method = HTTP_SEARCH; - } else { - goto error; - } - } else if (parser->index == 1 && parser->method == HTTP_POST) { - if (ch == 'R') { - parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */ - } else if (ch == 'U') { - parser->method = HTTP_PUT; /* or HTTP_PURGE */ - } else if (ch == 'A') { - parser->method = HTTP_PATCH; - } else { - goto error; - } - } else if (parser->index == 2) { - if (parser->method == HTTP_PUT) { - if (ch == 'R') parser->method = HTTP_PURGE; - } else if (parser->method == HTTP_UNLOCK) { - if (ch == 'S') parser->method = HTTP_UNSUBSCRIBE; - } - } else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') { - parser->method = HTTP_PROPPATCH; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; @@ -1921,11 +1958,11 @@ size_t http_parser_execute (http_parser *parser, MARK(url); if (parser->method == HTTP_CONNECT) { - parser->state = s_req_server_start; + UPDATE_STATE(s_req_server_start); } - parser->state = parse_url_char((enum state)parser->state, ch); - if (parser->state == s_dead) { + UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); + if (UNLIKELY(CURRENT_STATE() == s_dead)) { SET_ERRNO(HPE_INVALID_URL); goto error; } @@ -1946,8 +1983,8 @@ size_t http_parser_execute (http_parser *parser, SET_ERRNO(HPE_INVALID_URL); goto error; default: - parser->state = parse_url_char((enum state)parser->state, ch); - if (parser->state == s_dead) { + UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); + if (UNLIKELY(CURRENT_STATE() == s_dead)) { SET_ERRNO(HPE_INVALID_URL); goto error; } @@ -1966,21 +2003,21 @@ size_t http_parser_execute (http_parser *parser, { switch (ch) { case ' ': - parser->state = s_req_http_start; + UPDATE_STATE(s_req_http_start); CALLBACK_DATA(url); break; case CR: case LF: parser->http_major = 0; parser->http_minor = 9; - parser->state = (ch == CR) ? + UPDATE_STATE((ch == CR) ? s_req_line_almost_done : - s_header_field_start; + s_header_field_start); CALLBACK_DATA(url); break; default: - parser->state = parse_url_char((enum state)parser->state, ch); - if (parser->state == s_dead) { + UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); + if (UNLIKELY(CURRENT_STATE() == s_dead)) { SET_ERRNO(HPE_INVALID_URL); goto error; } @@ -1990,11 +2027,17 @@ size_t http_parser_execute (http_parser *parser, case s_req_http_start: switch (ch) { - case 'H': - parser->state = s_req_http_H; - break; case ' ': break; + case 'H': + UPDATE_STATE(s_req_http_H); + break; + case 'I': + if (parser->method == HTTP_SOURCE) { + UPDATE_STATE(s_req_http_I); + break; + } + /* fall through */ default: SET_ERRNO(HPE_INVALID_CONSTANT); goto error; @@ -2003,130 +2046,111 @@ size_t http_parser_execute (http_parser *parser, case s_req_http_H: STRICT_CHECK(ch != 'T'); - parser->state = s_req_http_HT; + UPDATE_STATE(s_req_http_HT); break; case s_req_http_HT: STRICT_CHECK(ch != 'T'); - parser->state = s_req_http_HTT; + UPDATE_STATE(s_req_http_HTT); break; case s_req_http_HTT: STRICT_CHECK(ch != 'P'); - parser->state = s_req_http_HTTP; + UPDATE_STATE(s_req_http_HTTP); + break; + + case s_req_http_I: + STRICT_CHECK(ch != 'C'); + UPDATE_STATE(s_req_http_IC); + break; + + case s_req_http_IC: + STRICT_CHECK(ch != 'E'); + UPDATE_STATE(s_req_http_HTTP); /* Treat "ICE" as "HTTP". */ break; case s_req_http_HTTP: STRICT_CHECK(ch != '/'); - parser->state = s_req_first_http_major; + UPDATE_STATE(s_req_http_major); break; - /* first digit of major HTTP version */ - case s_req_first_http_major: - if (ch < '1' || ch > '9') { + case s_req_http_major: + if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major = ch - '0'; - parser->state = s_req_http_major; + UPDATE_STATE(s_req_http_dot); break; - /* major HTTP version or dot */ - case s_req_http_major: + case s_req_http_dot: { - if (ch == '.') { - parser->state = s_req_first_http_minor; - break; - } - - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_major *= 10; - parser->http_major += ch - '0'; - - if (parser->http_major > 999) { + if (UNLIKELY(ch != '.')) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } + UPDATE_STATE(s_req_http_minor); break; } - /* first digit of minor HTTP version */ - case s_req_first_http_minor: - if (!IS_NUM(ch)) { + case s_req_http_minor: + if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor = ch - '0'; - parser->state = s_req_http_minor; + UPDATE_STATE(s_req_http_end); break; - /* minor HTTP version or end of request line */ - case s_req_http_minor: + case s_req_http_end: { if (ch == CR) { - parser->state = s_req_line_almost_done; + UPDATE_STATE(s_req_line_almost_done); break; } if (ch == LF) { - parser->state = s_header_field_start; + UPDATE_STATE(s_header_field_start); break; } - /* XXX allow spaces after digit? */ - - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_minor *= 10; - parser->http_minor += ch - '0'; - - if (parser->http_minor > 999) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - + SET_ERRNO(HPE_INVALID_VERSION); + goto error; break; } /* end of request line */ case s_req_line_almost_done: { - if (ch != LF) { + if (UNLIKELY(ch != LF)) { SET_ERRNO(HPE_LF_EXPECTED); goto error; } - parser->state = s_header_field_start; + UPDATE_STATE(s_header_field_start); break; } case s_header_field_start: { if (ch == CR) { - parser->state = s_headers_almost_done; + UPDATE_STATE(s_headers_almost_done); break; } if (ch == LF) { /* they might be just sending \n instead of \r\n so this would be * the second \n to denote the end of headers*/ - parser->state = s_headers_almost_done; - goto reexecute_byte; + UPDATE_STATE(s_headers_almost_done); + REEXECUTE(); } c = TOKEN(ch); - if (!c) { + if (UNLIKELY(!c)) { SET_ERRNO(HPE_INVALID_HEADER_TOKEN); goto error; } @@ -2134,7 +2158,7 @@ size_t http_parser_execute (http_parser *parser, MARK(header_field); parser->index = 0; - parser->state = s_header_field; + UPDATE_STATE(s_header_field); switch (c) { case 'c': @@ -2162,12 +2186,23 @@ size_t http_parser_execute (http_parser *parser, case s_header_field: { - c = TOKEN(ch); + const char* start = p; + for (; p != data + len; p++) { + ch = *p; + c = TOKEN(ch); + + if (!c) + break; - if (c) { switch (parser->header_state) { - case h_general: + case h_general: { + size_t left = data + len - p; + const char* pe = p + MIN(left, max_header_size); + while (p+1 < pe && TOKEN(p[1])) { + p++; + } break; + } case h_C: parser->index++; @@ -2265,23 +2300,18 @@ size_t http_parser_execute (http_parser *parser, assert(0 && "Unknown header_state"); break; } + } + + if (p == data + len) { + --p; + COUNT_HEADER_SIZE(p - start); break; } + COUNT_HEADER_SIZE(p - start); + if (ch == ':') { - parser->state = s_header_value_start; - CALLBACK_DATA(header_field); - break; - } - - if (ch == CR) { - parser->state = s_header_almost_done; - CALLBACK_DATA(header_field); - break; - } - - if (ch == LF) { - parser->state = s_header_field_start; + UPDATE_STATE(s_header_value_discard_ws); CALLBACK_DATA(header_field); break; } @@ -2290,28 +2320,28 @@ size_t http_parser_execute (http_parser *parser, goto error; } - case s_header_value_start: - { + case s_header_value_discard_ws: if (ch == ' ' || ch == '\t') break; - MARK(header_value); - - parser->state = s_header_value; - parser->index = 0; - if (ch == CR) { - parser->header_state = h_general; - parser->state = s_header_almost_done; - CALLBACK_DATA(header_value); + UPDATE_STATE(s_header_value_discard_ws_almost_done); break; } if (ch == LF) { - parser->state = s_header_field_start; - CALLBACK_DATA(header_value); + UPDATE_STATE(s_header_value_discard_lws); break; } + /* fall through */ + + case s_header_value_start: + { + MARK(header_value); + + UPDATE_STATE(s_header_value); + parser->index = 0; + c = LOWER(ch); switch (parser->header_state) { @@ -2330,12 +2360,24 @@ size_t http_parser_execute (http_parser *parser, break; case h_content_length: - if (!IS_NUM(ch)) { + if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); goto error; } + if (parser->flags & F_CONTENTLENGTH) { + SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH); + goto error; + } + + parser->flags |= F_CONTENTLENGTH; parser->content_length = ch - '0'; + parser->header_state = h_content_length_num; + break; + + /* when obsolete line folding is encountered for content length + * continue to the s_header_value state */ + case h_content_length_ws: break; case h_connection: @@ -2345,11 +2387,17 @@ size_t http_parser_execute (http_parser *parser, /* looking for 'Connection: close' */ } else if (c == 'c') { parser->header_state = h_matching_connection_close; + } else if (c == 'u') { + parser->header_state = h_matching_connection_upgrade; } else { - parser->header_state = h_general; + parser->header_state = h_matching_connection_token; } break; + /* Multi-value `Connection` header */ + case h_matching_connection_token_start: + break; + default: parser->header_state = h_general; break; @@ -2359,107 +2407,228 @@ size_t http_parser_execute (http_parser *parser, case s_header_value: { - - if (ch == CR) { - parser->state = s_header_almost_done; - CALLBACK_DATA(header_value); - break; - } - - if (ch == LF) { - parser->state = s_header_almost_done; - CALLBACK_DATA_NOADVANCE(header_value); - goto reexecute_byte; - } - - c = LOWER(ch); - - switch (parser->header_state) { - case h_general: - break; - - case h_connection: - case h_transfer_encoding: - assert(0 && "Shouldn't get here."); - break; - - case h_content_length: - { - uint64_t t; - - if (ch == ' ') break; - - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); - goto error; - } - - t = parser->content_length; - t *= 10; - t += ch - '0'; - - /* Overflow? */ - if (t < parser->content_length || t == ULLONG_MAX) { - SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); - goto error; - } - - parser->content_length = t; + const char* start = p; + enum header_states h_state = (enum header_states) parser->header_state; + for (; p != data + len; p++) { + ch = *p; + if (ch == CR) { + UPDATE_STATE(s_header_almost_done); + parser->header_state = h_state; + CALLBACK_DATA(header_value); break; } - /* Transfer-Encoding: chunked */ - case h_matching_transfer_encoding_chunked: - parser->index++; - if (parser->index > sizeof(CHUNKED)-1 - || c != CHUNKED[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(CHUNKED)-2) { - parser->header_state = h_transfer_encoding_chunked; + if (ch == LF) { + UPDATE_STATE(s_header_almost_done); + COUNT_HEADER_SIZE(p - start); + parser->header_state = h_state; + CALLBACK_DATA_NOADVANCE(header_value); + REEXECUTE(); + } + + if (!lenient && !IS_HEADER_CHAR(ch)) { + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + + c = LOWER(ch); + + switch (h_state) { + case h_general: + { + size_t left = data + len - p; + const char* pe = p + MIN(left, max_header_size); + + for (; p != pe; p++) { + ch = *p; + if (ch == CR || ch == LF) { + --p; + break; + } + if (!lenient && !IS_HEADER_CHAR(ch)) { + SET_ERRNO(HPE_INVALID_HEADER_TOKEN); + goto error; + } + } + if (p == data + len) + --p; + break; + } + + case h_connection: + case h_transfer_encoding: + assert(0 && "Shouldn't get here."); + break; + + case h_content_length: + if (ch == ' ') break; + h_state = h_content_length_num; + /* fall through */ + + case h_content_length_num: + { + uint64_t t; + + if (ch == ' ') { + h_state = h_content_length_ws; + break; + } + + if (UNLIKELY(!IS_NUM(ch))) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + parser->header_state = h_state; + goto error; + } + + t = parser->content_length; + t *= 10; + t += ch - '0'; + + /* Overflow? Test against a conservative limit for simplicity. */ + if (UNLIKELY((ULLONG_MAX - 10) / 10 < parser->content_length)) { + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + parser->header_state = h_state; + goto error; + } + + parser->content_length = t; + break; } - break; - /* looking for 'Connection: keep-alive' */ - case h_matching_connection_keep_alive: - parser->index++; - if (parser->index > sizeof(KEEP_ALIVE)-1 - || c != KEEP_ALIVE[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(KEEP_ALIVE)-2) { - parser->header_state = h_connection_keep_alive; - } - break; + case h_content_length_ws: + if (ch == ' ') break; + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + parser->header_state = h_state; + goto error; - /* looking for 'Connection: close' */ - case h_matching_connection_close: - parser->index++; - if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) { - parser->header_state = h_general; - } else if (parser->index == sizeof(CLOSE)-2) { - parser->header_state = h_connection_close; - } - break; + /* Transfer-Encoding: chunked */ + case h_matching_transfer_encoding_chunked: + parser->index++; + if (parser->index > sizeof(CHUNKED)-1 + || c != CHUNKED[parser->index]) { + h_state = h_general; + } else if (parser->index == sizeof(CHUNKED)-2) { + h_state = h_transfer_encoding_chunked; + } + break; - case h_transfer_encoding_chunked: - case h_connection_keep_alive: - case h_connection_close: - if (ch != ' ') parser->header_state = h_general; - break; + case h_matching_connection_token_start: + /* looking for 'Connection: keep-alive' */ + if (c == 'k') { + h_state = h_matching_connection_keep_alive; + /* looking for 'Connection: close' */ + } else if (c == 'c') { + h_state = h_matching_connection_close; + } else if (c == 'u') { + h_state = h_matching_connection_upgrade; + } else if (STRICT_TOKEN(c)) { + h_state = h_matching_connection_token; + } else if (c == ' ' || c == '\t') { + /* Skip lws */ + } else { + h_state = h_general; + } + break; - default: - parser->state = s_header_value; - parser->header_state = h_general; - break; + /* looking for 'Connection: keep-alive' */ + case h_matching_connection_keep_alive: + parser->index++; + if (parser->index > sizeof(KEEP_ALIVE)-1 + || c != KEEP_ALIVE[parser->index]) { + h_state = h_matching_connection_token; + } else if (parser->index == sizeof(KEEP_ALIVE)-2) { + h_state = h_connection_keep_alive; + } + break; + + /* looking for 'Connection: close' */ + case h_matching_connection_close: + parser->index++; + if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) { + h_state = h_matching_connection_token; + } else if (parser->index == sizeof(CLOSE)-2) { + h_state = h_connection_close; + } + break; + + /* looking for 'Connection: upgrade' */ + case h_matching_connection_upgrade: + parser->index++; + if (parser->index > sizeof(UPGRADE) - 1 || + c != UPGRADE[parser->index]) { + h_state = h_matching_connection_token; + } else if (parser->index == sizeof(UPGRADE)-2) { + h_state = h_connection_upgrade; + } + break; + + case h_matching_connection_token: + if (ch == ',') { + h_state = h_matching_connection_token_start; + parser->index = 0; + } + break; + + case h_transfer_encoding_chunked: + if (ch != ' ') h_state = h_general; + break; + + case h_connection_keep_alive: + case h_connection_close: + case h_connection_upgrade: + if (ch == ',') { + if (h_state == h_connection_keep_alive) { + parser->flags |= F_CONNECTION_KEEP_ALIVE; + } else if (h_state == h_connection_close) { + parser->flags |= F_CONNECTION_CLOSE; + } else if (h_state == h_connection_upgrade) { + parser->flags |= F_CONNECTION_UPGRADE; + } + h_state = h_matching_connection_token_start; + parser->index = 0; + } else if (ch != ' ') { + h_state = h_matching_connection_token; + } + break; + + default: + UPDATE_STATE(s_header_value); + h_state = h_general; + break; + } } + parser->header_state = h_state; + + if (p == data + len) + --p; + + COUNT_HEADER_SIZE(p - start); break; } case s_header_almost_done: { - STRICT_CHECK(ch != LF); + if (UNLIKELY(ch != LF)) { + SET_ERRNO(HPE_LF_EXPECTED); + goto error; + } - parser->state = s_header_value_lws; + UPDATE_STATE(s_header_value_lws); + break; + } + case s_header_value_lws: + { + if (ch == ' ' || ch == '\t') { + if (parser->header_state == h_content_length_num) { + /* treat obsolete line folding as space */ + parser->header_state = h_content_length_ws; + } + UPDATE_STATE(s_header_value_start); + REEXECUTE(); + } + + /* finished the header */ switch (parser->header_state) { case h_connection_keep_alive: parser->flags |= F_CONNECTION_KEEP_ALIVE; @@ -2470,23 +2639,58 @@ size_t http_parser_execute (http_parser *parser, case h_transfer_encoding_chunked: parser->flags |= F_CHUNKED; break; + case h_connection_upgrade: + parser->flags |= F_CONNECTION_UPGRADE; + break; default: break; } + UPDATE_STATE(s_header_field_start); + REEXECUTE(); + } + + case s_header_value_discard_ws_almost_done: + { + STRICT_CHECK(ch != LF); + UPDATE_STATE(s_header_value_discard_lws); break; } - case s_header_value_lws: + case s_header_value_discard_lws: { - if (ch == ' ' || ch == '\t') - parser->state = s_header_value_start; - else - { - parser->state = s_header_field_start; - goto reexecute_byte; + if (ch == ' ' || ch == '\t') { + UPDATE_STATE(s_header_value_discard_ws); + break; + } else { + switch (parser->header_state) { + case h_connection_keep_alive: + parser->flags |= F_CONNECTION_KEEP_ALIVE; + break; + case h_connection_close: + parser->flags |= F_CONNECTION_CLOSE; + break; + case h_connection_upgrade: + parser->flags |= F_CONNECTION_UPGRADE; + break; + case h_transfer_encoding_chunked: + parser->flags |= F_CHUNKED; + break; + case h_content_length: + /* do not allow empty content length */ + SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); + goto error; + break; + default: + break; + } + + /* header value was empty */ + MARK(header_value); + UPDATE_STATE(s_header_field_start); + CALLBACK_DATA_NOADVANCE(header_value); + REEXECUTE(); } - break; } case s_headers_almost_done: @@ -2495,16 +2699,33 @@ size_t http_parser_execute (http_parser *parser, if (parser->flags & F_TRAILING) { /* End of a chunked request */ - parser->state = NEW_MESSAGE(); - CALLBACK_NOTIFY(message_complete); - break; + UPDATE_STATE(s_message_done); + CALLBACK_NOTIFY_NOADVANCE(chunk_complete); + REEXECUTE(); } - parser->state = s_headers_done; + /* Cannot use chunked encoding and a content-length header together + per the HTTP specification. */ + if ((parser->flags & F_CHUNKED) && + (parser->flags & F_CONTENTLENGTH)) { + SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH); + goto error; + } + + UPDATE_STATE(s_headers_done); /* Set this here so that on_headers_complete() callbacks can see it */ - parser->upgrade = - (parser->flags & F_UPGRADE || parser->method == HTTP_CONNECT); + if ((parser->flags & F_UPGRADE) && + (parser->flags & F_CONNECTION_UPGRADE)) { + /* For responses, "Upgrade: foo" and "Connection: upgrade" are + * mandatory only when it is a 101 Switching Protocols response, + * otherwise it is purely informational, to announce support. + */ + parser->upgrade = + (parser->type == HTTP_REQUEST || parser->status_code == 101); + } else { + parser->upgrade = (parser->method == HTTP_CONNECT); + } /* Here we call the headers_complete callback. This is somewhat * different than other callbacks because if the user returns 1, we @@ -2520,59 +2741,67 @@ size_t http_parser_execute (http_parser *parser, case 0: break; + case 2: + parser->upgrade = 1; + + /* fall through */ case 1: parser->flags |= F_SKIPBODY; break; default: SET_ERRNO(HPE_CB_headers_complete); - return p - data; /* Error */ + RETURN(p - data); /* Error */ } } if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { - return p - data; + RETURN(p - data); } - goto reexecute_byte; + REEXECUTE(); } case s_headers_done: { + int hasBody; STRICT_CHECK(ch != LF); parser->nread = 0; + nread = 0; - /* Exit, the rest of the connect is in a different protocol. */ - if (parser->upgrade) { - parser->state = NEW_MESSAGE(); + hasBody = parser->flags & F_CHUNKED || + (parser->content_length > 0 && parser->content_length != ULLONG_MAX); + if (parser->upgrade && (parser->method == HTTP_CONNECT || + (parser->flags & F_SKIPBODY) || !hasBody)) { + /* Exit, the rest of the message is in a different protocol. */ + UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); - return (p - data) + 1; + RETURN((p - data) + 1); } if (parser->flags & F_SKIPBODY) { - parser->state = NEW_MESSAGE(); + UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); } else if (parser->flags & F_CHUNKED) { /* chunked encoding - ignore Content-Length header */ - parser->state = s_chunk_size_start; + UPDATE_STATE(s_chunk_size_start); } else { if (parser->content_length == 0) { /* Content-Length header given but zero: Content-Length: 0\r\n */ - parser->state = NEW_MESSAGE(); + UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); } else if (parser->content_length != ULLONG_MAX) { /* Content-Length header given and non-zero */ - parser->state = s_body_identity; + UPDATE_STATE(s_body_identity); } else { - if (parser->type == HTTP_REQUEST || - !http_message_needs_eof(parser)) { + if (!http_message_needs_eof(parser)) { /* Assume content-length 0 - read the next */ - parser->state = NEW_MESSAGE(); + UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); } else { /* Read body until EOF */ - parser->state = s_body_identity_eof; + UPDATE_STATE(s_body_identity_eof); } } } @@ -2598,7 +2827,7 @@ size_t http_parser_execute (http_parser *parser, p += to_read - 1; if (parser->content_length == 0) { - parser->state = s_message_done; + UPDATE_STATE(s_message_done); /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte. * @@ -2610,7 +2839,7 @@ size_t http_parser_execute (http_parser *parser, * important for applications, but let's keep it for now. */ CALLBACK_DATA_(body, p - body_mark + 1, p - data); - goto reexecute_byte; + REEXECUTE(); } break; @@ -2624,23 +2853,27 @@ size_t http_parser_execute (http_parser *parser, break; case s_message_done: - parser->state = NEW_MESSAGE(); + UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); + if (parser->upgrade) { + /* Exit, the rest of the message is in a different protocol. */ + RETURN((p - data) + 1); + } break; case s_chunk_size_start: { - assert(parser->nread == 1); + assert(nread == 1); assert(parser->flags & F_CHUNKED); unhex_val = unhex[(unsigned char)ch]; - if (unhex_val == -1) { + if (UNLIKELY(unhex_val == -1)) { SET_ERRNO(HPE_INVALID_CHUNK_SIZE); goto error; } parser->content_length = unhex_val; - parser->state = s_chunk_size; + UPDATE_STATE(s_chunk_size); break; } @@ -2651,7 +2884,7 @@ size_t http_parser_execute (http_parser *parser, assert(parser->flags & F_CHUNKED); if (ch == CR) { - parser->state = s_chunk_size_almost_done; + UPDATE_STATE(s_chunk_size_almost_done); break; } @@ -2659,7 +2892,7 @@ size_t http_parser_execute (http_parser *parser, if (unhex_val == -1) { if (ch == ';' || ch == ' ') { - parser->state = s_chunk_parameters; + UPDATE_STATE(s_chunk_parameters); break; } @@ -2671,8 +2904,8 @@ size_t http_parser_execute (http_parser *parser, t *= 16; t += unhex_val; - /* Overflow? */ - if (t < parser->content_length || t == ULLONG_MAX) { + /* Overflow? Test against a conservative limit for simplicity. */ + if (UNLIKELY((ULLONG_MAX - 16) / 16 < parser->content_length)) { SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); goto error; } @@ -2686,7 +2919,7 @@ size_t http_parser_execute (http_parser *parser, assert(parser->flags & F_CHUNKED); /* just ignore this shit. TODO check for overflow */ if (ch == CR) { - parser->state = s_chunk_size_almost_done; + UPDATE_STATE(s_chunk_size_almost_done); break; } break; @@ -2698,13 +2931,15 @@ size_t http_parser_execute (http_parser *parser, STRICT_CHECK(ch != LF); parser->nread = 0; + nread = 0; if (parser->content_length == 0) { parser->flags |= F_TRAILING; - parser->state = s_header_field_start; + UPDATE_STATE(s_header_field_start); } else { - parser->state = s_chunk_data; + UPDATE_STATE(s_chunk_data); } + CALLBACK_NOTIFY(chunk_header); break; } @@ -2725,7 +2960,7 @@ size_t http_parser_execute (http_parser *parser, p += to_read - 1; if (parser->content_length == 0) { - parser->state = s_chunk_data_almost_done; + UPDATE_STATE(s_chunk_data_almost_done); } break; @@ -2735,7 +2970,7 @@ size_t http_parser_execute (http_parser *parser, assert(parser->flags & F_CHUNKED); assert(parser->content_length == 0); STRICT_CHECK(ch != CR); - parser->state = s_chunk_data_done; + UPDATE_STATE(s_chunk_data_done); CALLBACK_DATA(body); break; @@ -2743,7 +2978,9 @@ size_t http_parser_execute (http_parser *parser, assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != LF); parser->nread = 0; - parser->state = s_chunk_size_start; + nread = 0; + UPDATE_STATE(s_chunk_size_start); + CALLBACK_NOTIFY(chunk_complete); break; default: @@ -2753,7 +2990,7 @@ size_t http_parser_execute (http_parser *parser, } } - /* Run callbacks for any marks that we have leftover after we ran our of + /* Run callbacks for any marks that we have leftover after we ran out of * bytes. There should be at most one of these set, so it's OK to invoke * them in series (unset marks will not result in callbacks). * @@ -2766,21 +3003,23 @@ size_t http_parser_execute (http_parser *parser, assert(((header_field_mark ? 1 : 0) + (header_value_mark ? 1 : 0) + (url_mark ? 1 : 0) + - (body_mark ? 1 : 0)) <= 1); + (body_mark ? 1 : 0) + + (status_mark ? 1 : 0)) <= 1); CALLBACK_DATA_NOADVANCE(header_field); CALLBACK_DATA_NOADVANCE(header_value); CALLBACK_DATA_NOADVANCE(url); CALLBACK_DATA_NOADVANCE(body); + CALLBACK_DATA_NOADVANCE(status); - return len; + RETURN(len); error: if (HTTP_PARSER_ERRNO(parser) == HPE_OK) { SET_ERRNO(HPE_UNKNOWN); } - return (p - data); + RETURN(p - data); } @@ -2833,6 +3072,16 @@ http_method_str (enum http_method m) return ELEM_AT(method_strings, m, ""); } +const char * +http_status_str (enum http_status s) +{ + switch (s) { +#define XX(num, name, string) case HTTP_STATUS_##name: return #string; + HTTP_STATUS_MAP(XX) +#undef XX + default: return ""; + } +} void http_parser_init (http_parser *parser, enum http_parser_type t) @@ -2845,15 +3094,21 @@ http_parser_init (http_parser *parser, enum http_parser_type t) parser->http_errno = HPE_OK; } +void +http_parser_settings_init(http_parser_settings *settings) +{ + memset(settings, 0, sizeof(*settings)); +} + const char * http_errno_name(enum http_errno err) { - assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0]))); + assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab)); return http_strerror_tab[err].name; } const char * http_errno_description(enum http_errno err) { - assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0]))); + assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab)); return http_strerror_tab[err].description; } @@ -2887,7 +3142,7 @@ http_parse_host_char(enum http_host_state s, const char ch) { return s_http_host; } - /* FALLTHROUGH */ + /* fall through */ case s_http_host_v6_end: if (ch == ':') { return s_http_host_port_start; @@ -2900,12 +3155,29 @@ http_parse_host_char(enum http_host_state s, const char ch) { return s_http_host_v6_end; } - /* FALLTHROUGH */ + /* fall through */ case s_http_host_v6_start: if (IS_HEX(ch) || ch == ':' || ch == '.') { return s_http_host_v6; } + if (s == s_http_host_v6 && ch == '%') { + return s_http_host_v6_zone_start; + } + break; + + case s_http_host_v6_zone: + if (ch == ']') { + return s_http_host_v6_end; + } + + /* fall through */ + case s_http_host_v6_zone_start: + /* RFC 6874 Zone ID consists of 1*( unreserved / pct-encoded) */ + if (IS_ALPHANUM(ch) || ch == '%' || ch == '.' || ch == '-' || ch == '_' || + ch == '~') { + return s_http_host_v6_zone; + } break; case s_http_host_port: @@ -2929,6 +3201,8 @@ http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { const char *p; size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len; + assert(u->field_set & (1 << UF_HOST)); + u->field_data[UF_HOST].len = 0; s = found_at ? s_http_userinfo_start : s_http_host_start; @@ -2943,21 +3217,26 @@ http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { switch(new_s) { case s_http_host: if (s != s_http_host) { - u->field_data[UF_HOST].off = p - buf; + u->field_data[UF_HOST].off = (uint16_t)(p - buf); } u->field_data[UF_HOST].len++; break; case s_http_host_v6: if (s != s_http_host_v6) { - u->field_data[UF_HOST].off = p - buf; + u->field_data[UF_HOST].off = (uint16_t)(p - buf); } u->field_data[UF_HOST].len++; break; + case s_http_host_v6_zone_start: + case s_http_host_v6_zone: + u->field_data[UF_HOST].len++; + break; + case s_http_host_port: if (s != s_http_host_port) { - u->field_data[UF_PORT].off = p - buf; + u->field_data[UF_PORT].off = (uint16_t)(p - buf); u->field_data[UF_PORT].len = 0; u->field_set |= (1 << UF_PORT); } @@ -2966,7 +3245,7 @@ http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { case s_http_userinfo: if (s != s_http_userinfo) { - u->field_data[UF_USERINFO].off = p - buf ; + u->field_data[UF_USERINFO].off = (uint16_t)(p - buf); u->field_data[UF_USERINFO].len = 0; u->field_set |= (1 << UF_USERINFO); } @@ -2984,6 +3263,8 @@ http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { case s_http_host_start: case s_http_host_v6_start: case s_http_host_v6: + case s_http_host_v6_zone_start: + case s_http_host_v6_zone: case s_http_host_port_start: case s_http_userinfo: case s_http_userinfo_start: @@ -2995,6 +3276,11 @@ http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { return 0; } +void +http_parser_url_init(struct http_parser_url *u) { + memset(u, 0, sizeof(*u)); +} + int http_parser_parse_url(const char *buf, size_t buflen, int is_connect, struct http_parser_url *u) @@ -3004,9 +3290,13 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect, enum http_parser_url_fields uf, old_uf; int found_at = 0; + if (buflen == 0) { + return 1; + } + u->port = u->field_set = 0; s = is_connect ? s_req_server_start : s_req_spaces_before_url; - uf = old_uf = UF_MAX; + old_uf = UF_MAX; for (p = buf; p < buf + buflen; p++) { s = parse_url_char(s, *p); @@ -3031,7 +3321,7 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect, case s_req_server_with_at: found_at = 1; - /* FALLTROUGH */ + /* fall through */ case s_req_server: uf = UF_HOST; break; @@ -3059,7 +3349,7 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect, continue; } - u->field_data[uf].off = p - buf; + u->field_data[uf].off = (uint16_t)(p - buf); u->field_data[uf].len = 1; u->field_set |= (1 << uf); @@ -3068,7 +3358,12 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect, /* host must be present if there is a schema */ /* parsing http:///toto will fail */ - if ((u->field_set & ((1 << UF_SCHEMA) | (1 << UF_HOST))) != 0) { + if ((u->field_set & (1 << UF_SCHEMA)) && + (u->field_set & (1 << UF_HOST)) == 0) { + return 1; + } + + if (u->field_set & (1 << UF_HOST)) { if (http_parse_host(buf, u, found_at) != 0) { return 1; } @@ -3080,12 +3375,27 @@ http_parser_parse_url(const char *buf, size_t buflen, int is_connect, } if (u->field_set & (1 << UF_PORT)) { - /* Don't bother with endp; we've already validated the string */ - unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10); + uint16_t off; + uint16_t len; + const char* p; + const char* end; + unsigned long v; - /* Ports have a max value of 2^16 */ - if (v > 0xffff) { - return 1; + off = u->field_data[UF_PORT].off; + len = u->field_data[UF_PORT].len; + end = buf + off + len; + + /* NOTE: The characters are already validated and are in the [0-9] range */ + assert(off + len <= buflen && "Port number overflow"); + v = 0; + for (p = buf + off; p < end; p++) { + v *= 10; + v += *p - '0'; + + /* Ports have a max value of 2^16 */ + if (v > 0xffff) { + return 1; + } } u->port = (uint16_t) v; @@ -3102,6 +3412,7 @@ http_parser_pause(http_parser *parser, int paused) { */ if (HTTP_PARSER_ERRNO(parser) == HPE_OK || HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) { + uint32_t nread = parser->nread; /* used by the SET_ERRNO macro */ SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK); } else { assert(0 && "Attempting to pause parser in error state"); @@ -3113,3 +3424,15 @@ http_body_is_final(const struct http_parser *parser) { return parser->state == s_message_done; } +unsigned long +http_parser_version(void) { + return HTTP_PARSER_VERSION_MAJOR * 0x10000 | + HTTP_PARSER_VERSION_MINOR * 0x00100 | + HTTP_PARSER_VERSION_PATCH * 0x00001; +} + +void +http_parser_set_max_header_size(uint32_t size) { + max_header_size = size; +} + diff --git a/trunk/src/protocol/srs_http_stack.hpp b/trunk/src/protocol/srs_http_stack.hpp index 5f4b033fa..321c97325 100644 --- a/trunk/src/protocol/srs_http_stack.hpp +++ b/trunk/src/protocol/srs_http_stack.hpp @@ -544,8 +544,8 @@ private: #endif // The http-parser is license under MIT at https://github.com/nodejs/http-parser/blob/master/LICENSE-MIT -// Version: 2.1 from https://github.com/nodejs/http-parser/releases/tag/v2.1 -// File: https://github.com/nodejs/http-parser/blob/80819384450b5511a3d1c424dd92a5843c891364/http_parser.h +// Version: 2.9.2 from https://github.com/nodejs/http-parser/releases/tag/v2.9.2 +// File: https://raw.githubusercontent.com/nodejs/http-parser/5c17dad400e45c5a442a63f250fff2638d144682/http_parser.h ///////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////// @@ -598,13 +598,15 @@ private: extern "C" { #endif +/* Also update SONAME in the Makefile whenever you change these. */ #define HTTP_PARSER_VERSION_MAJOR 2 -#define HTTP_PARSER_VERSION_MINOR 1 +#define HTTP_PARSER_VERSION_MINOR 9 +#define HTTP_PARSER_VERSION_PATCH 2 -#include -#if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600) -#include #include +#if defined(_WIN32) && !defined(__MINGW32__) && \ + (!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__) +#include typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; @@ -624,9 +626,16 @@ typedef unsigned __int64 uint64_t; # define HTTP_PARSER_STRICT 1 #endif -/* Maximium header size allowed */ -#define HTTP_MAX_HEADER_SIZE (80*1024) - +/* Maximium header size allowed. If the macro is not defined + * before including this header then the default is used. To + * change the maximum header size, define the macro in the build + * environment (e.g. -DHTTP_MAX_HEADER_SIZE=). To remove + * the effective limit on the size of the header, define the macro + * to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff) + */ +#ifndef HTTP_MAX_HEADER_SIZE +# define HTTP_MAX_HEADER_SIZE (80*1024) +#endif typedef struct http_parser http_parser; typedef struct http_parser_settings http_parser_settings; @@ -641,7 +650,12 @@ typedef struct http_parser_settings http_parser_settings; * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: * chunked' headers that indicate the presence of a body. * - * http_data_cb does not return data chunks. It will be call arbitrarally + * Returning `2` from on_headers_complete will tell parser that it should not + * expect neither a body nor any futher responses on this connection. This is + * useful for handling responses to a CONNECT request which may not contain + * `Upgrade` or `Connection: upgrade` headers. + * + * http_data_cb does not return data chunks. It will be called arbitrarily * many times for each string. E.G. you might get 10 callbacks for "on_url" * each providing just a few characters more data. */ @@ -649,6 +663,76 @@ typedef int (*http_data_cb) (http_parser*, const char *at, size_t length); typedef int (*http_cb) (http_parser*); +/* Status Codes */ +#define HTTP_STATUS_MAP(XX) \ + XX(100, CONTINUE, Continue) \ + XX(101, SWITCHING_PROTOCOLS, Switching Protocols) \ + XX(102, PROCESSING, Processing) \ + XX(200, OK, OK) \ + XX(201, CREATED, Created) \ + XX(202, ACCEPTED, Accepted) \ + XX(203, NON_AUTHORITATIVE_INFORMATION, Non-Authoritative Information) \ + XX(204, NO_CONTENT, No Content) \ + XX(205, RESET_CONTENT, Reset Content) \ + XX(206, PARTIAL_CONTENT, Partial Content) \ + XX(207, MULTI_STATUS, Multi-Status) \ + XX(208, ALREADY_REPORTED, Already Reported) \ + XX(226, IM_USED, IM Used) \ + XX(300, MULTIPLE_CHOICES, Multiple Choices) \ + XX(301, MOVED_PERMANENTLY, Moved Permanently) \ + XX(302, FOUND, Found) \ + XX(303, SEE_OTHER, See Other) \ + XX(304, NOT_MODIFIED, Not Modified) \ + XX(305, USE_PROXY, Use Proxy) \ + XX(307, TEMPORARY_REDIRECT, Temporary Redirect) \ + XX(308, PERMANENT_REDIRECT, Permanent Redirect) \ + XX(400, BAD_REQUEST, Bad Request) \ + XX(401, UNAUTHORIZED, Unauthorized) \ + XX(402, PAYMENT_REQUIRED, Payment Required) \ + XX(403, FORBIDDEN, Forbidden) \ + XX(404, NOT_FOUND, Not Found) \ + XX(405, METHOD_NOT_ALLOWED, Method Not Allowed) \ + XX(406, NOT_ACCEPTABLE, Not Acceptable) \ + XX(407, PROXY_AUTHENTICATION_REQUIRED, Proxy Authentication Required) \ + XX(408, REQUEST_TIMEOUT, Request Timeout) \ + XX(409, CONFLICT, Conflict) \ + XX(410, GONE, Gone) \ + XX(411, LENGTH_REQUIRED, Length Required) \ + XX(412, PRECONDITION_FAILED, Precondition Failed) \ + XX(413, PAYLOAD_TOO_LARGE, Payload Too Large) \ + XX(414, URI_TOO_LONG, URI Too Long) \ + XX(415, UNSUPPORTED_MEDIA_TYPE, Unsupported Media Type) \ + XX(416, RANGE_NOT_SATISFIABLE, Range Not Satisfiable) \ + XX(417, EXPECTATION_FAILED, Expectation Failed) \ + XX(421, MISDIRECTED_REQUEST, Misdirected Request) \ + XX(422, UNPROCESSABLE_ENTITY, Unprocessable Entity) \ + XX(423, LOCKED, Locked) \ + XX(424, FAILED_DEPENDENCY, Failed Dependency) \ + XX(426, UPGRADE_REQUIRED, Upgrade Required) \ + XX(428, PRECONDITION_REQUIRED, Precondition Required) \ + XX(429, TOO_MANY_REQUESTS, Too Many Requests) \ + XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \ + XX(451, UNAVAILABLE_FOR_LEGAL_REASONS, Unavailable For Legal Reasons) \ + XX(500, INTERNAL_SERVER_ERROR, Internal Server Error) \ + XX(501, NOT_IMPLEMENTED, Not Implemented) \ + XX(502, BAD_GATEWAY, Bad Gateway) \ + XX(503, SERVICE_UNAVAILABLE, Service Unavailable) \ + XX(504, GATEWAY_TIMEOUT, Gateway Timeout) \ + XX(505, HTTP_VERSION_NOT_SUPPORTED, HTTP Version Not Supported) \ + XX(506, VARIANT_ALSO_NEGOTIATES, Variant Also Negotiates) \ + XX(507, INSUFFICIENT_STORAGE, Insufficient Storage) \ + XX(508, LOOP_DETECTED, Loop Detected) \ + XX(510, NOT_EXTENDED, Not Extended) \ + XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \ + +enum http_status + { +#define XX(num, name, string) HTTP_STATUS_##name = num, + HTTP_STATUS_MAP(XX) +#undef XX + }; + + /* Request Methods */ #define HTTP_METHOD_MAP(XX) \ XX(0, DELETE, DELETE) \ @@ -660,7 +744,7 @@ typedef int (*http_cb) (http_parser*); XX(5, CONNECT, CONNECT) \ XX(6, OPTIONS, OPTIONS) \ XX(7, TRACE, TRACE) \ - /* webdav */ \ + /* WebDAV */ \ XX(8, COPY, COPY) \ XX(9, LOCK, LOCK) \ XX(10, MKCOL, MKCOL) \ @@ -669,19 +753,30 @@ typedef int (*http_cb) (http_parser*); XX(13, PROPPATCH, PROPPATCH) \ XX(14, SEARCH, SEARCH) \ XX(15, UNLOCK, UNLOCK) \ + XX(16, BIND, BIND) \ + XX(17, REBIND, REBIND) \ + XX(18, UNBIND, UNBIND) \ + XX(19, ACL, ACL) \ /* subversion */ \ - XX(16, REPORT, REPORT) \ - XX(17, MKACTIVITY, MKACTIVITY) \ - XX(18, CHECKOUT, CHECKOUT) \ - XX(19, MERGE, MERGE) \ + XX(20, REPORT, REPORT) \ + XX(21, MKACTIVITY, MKACTIVITY) \ + XX(22, CHECKOUT, CHECKOUT) \ + XX(23, MERGE, MERGE) \ /* upnp */ \ - XX(20, MSEARCH, M-SEARCH) \ - XX(21, NOTIFY, NOTIFY) \ - XX(22, SUBSCRIBE, SUBSCRIBE) \ - XX(23, UNSUBSCRIBE, UNSUBSCRIBE) \ + XX(24, MSEARCH, M-SEARCH) \ + XX(25, NOTIFY, NOTIFY) \ + XX(26, SUBSCRIBE, SUBSCRIBE) \ + XX(27, UNSUBSCRIBE, UNSUBSCRIBE) \ /* RFC-5789 */ \ - XX(24, PATCH, PATCH) \ - XX(25, PURGE, PURGE) \ + XX(28, PATCH, PATCH) \ + XX(29, PURGE, PURGE) \ + /* CalDAV */ \ + XX(30, MKCALENDAR, MKCALENDAR) \ + /* RFC-2068, section 19.6.1.2 */ \ + XX(31, LINK, LINK) \ + XX(32, UNLINK, UNLINK) \ + /* icecast */ \ + XX(33, SOURCE, SOURCE) \ enum http_method { @@ -699,9 +794,11 @@ enum flags { F_CHUNKED = 1 << 0 , F_CONNECTION_KEEP_ALIVE = 1 << 1 , F_CONNECTION_CLOSE = 1 << 2 - , F_TRAILING = 1 << 3 - , F_UPGRADE = 1 << 4 - , F_SKIPBODY = 1 << 5 + , F_CONNECTION_UPGRADE = 1 << 3 + , F_TRAILING = 1 << 4 + , F_UPGRADE = 1 << 5 + , F_SKIPBODY = 1 << 6 + , F_CONTENTLENGTH = 1 << 7 }; @@ -715,13 +812,15 @@ enum flags \ /* Callback-related errors */ \ XX(CB_message_begin, "the on_message_begin callback failed") \ - XX(CB_status_complete, "the on_status_complete callback failed") \ XX(CB_url, "the on_url callback failed") \ XX(CB_header_field, "the on_header_field callback failed") \ XX(CB_header_value, "the on_header_value callback failed") \ XX(CB_headers_complete, "the on_headers_complete callback failed") \ XX(CB_body, "the on_body callback failed") \ XX(CB_message_complete, "the on_message_complete callback failed") \ + XX(CB_status, "the on_status callback failed") \ + XX(CB_chunk_header, "the on_chunk_header callback failed") \ + XX(CB_chunk_complete, "the on_chunk_complete callback failed") \ \ /* Parsing-related errors */ \ XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \ @@ -742,6 +841,8 @@ enum flags XX(INVALID_HEADER_TOKEN, "invalid character in header") \ XX(INVALID_CONTENT_LENGTH, \ "invalid character in content-length header") \ + XX(UNEXPECTED_CONTENT_LENGTH, \ + "unexpected content-length header") \ XX(INVALID_CHUNK_SIZE, \ "invalid character in chunk size header") \ XX(INVALID_CONSTANT, "invalid constant string") \ @@ -765,11 +866,12 @@ enum http_errno { struct http_parser { /** PRIVATE **/ - unsigned char type : 2; /* enum http_parser_type */ - unsigned char flags : 6; /* F_* values from 'flags' enum; semi-public */ - unsigned char state; /* enum state from http_parser.c */ - unsigned char header_state; /* enum header_state from http_parser.c */ - unsigned char index; /* index into current matcher */ + unsigned int type : 2; /* enum http_parser_type */ + unsigned int flags : 8; /* F_* values from 'flags' enum; semi-public */ + unsigned int state : 7; /* enum state from http_parser.c */ + unsigned int header_state : 7; /* enum header_state from http_parser.c */ + unsigned int index : 7; /* index into current matcher */ + unsigned int lenient_http_headers : 1; uint32_t nread; /* # bytes read in various scenarios */ uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */ @@ -777,16 +879,16 @@ struct http_parser { /** READ-ONLY **/ unsigned short http_major; unsigned short http_minor; - unsigned short status_code; /* responses only */ - unsigned char method; /* requests only */ - unsigned char http_errno : 7; + unsigned int status_code : 16; /* responses only */ + unsigned int method : 8; /* requests only */ + unsigned int http_errno : 7; /* 1 = Upgrade header was present and the parser has exited because of that. * 0 = No upgrade header present. * Should be checked when http_parser_execute() returns in addition to * error checking. */ - unsigned char upgrade : 1; + unsigned int upgrade : 1; /** PUBLIC **/ void *data; /* A pointer to get hook to the "connection" or "socket" object */ @@ -796,12 +898,17 @@ struct http_parser { struct http_parser_settings { http_cb on_message_begin; http_data_cb on_url; - http_cb on_status_complete; + http_data_cb on_status; http_data_cb on_header_field; http_data_cb on_header_value; http_cb on_headers_complete; http_data_cb on_body; http_cb on_message_complete; + /* When on_chunk_header is called, the current chunk length is stored + * in parser->content_length. + */ + http_cb on_chunk_header; + http_cb on_chunk_complete; }; @@ -835,9 +942,28 @@ struct http_parser_url { }; +/* Returns the library version. Bits 16-23 contain the major version number, + * bits 8-15 the minor version number and bits 0-7 the patch level. + * Usage example: + * + * unsigned long version = http_parser_version(); + * unsigned major = (version >> 16) & 255; + * unsigned minor = (version >> 8) & 255; + * unsigned patch = version & 255; + * printf("http_parser v%u.%u.%u\n", major, minor, patch); + */ +unsigned long http_parser_version(void); + void http_parser_init(http_parser *parser, enum http_parser_type type); +/* Initialize http_parser_settings members to 0 + */ +void http_parser_settings_init(http_parser_settings *settings); + + +/* Executes the parser. Returns number of parsed bytes. Sets + * `parser->http_errno` on error. */ size_t http_parser_execute(http_parser *parser, const http_parser_settings *settings, const char *data, @@ -855,12 +981,18 @@ int http_should_keep_alive(const http_parser *parser); /* Returns a string version of the HTTP method. */ const char *http_method_str(enum http_method m); +/* Returns a string version of the HTTP status code. */ +const char *http_status_str(enum http_status s); + /* Return a string name of the given error */ const char *http_errno_name(enum http_errno err); /* Return a string description of the given error */ const char *http_errno_description(enum http_errno err); +/* Initialize all http_parser_url members to 0 */ +void http_parser_url_init(struct http_parser_url *u); + /* Parse a URL; return nonzero on failure */ int http_parser_parse_url(const char *buf, size_t buflen, int is_connect, @@ -872,6 +1004,9 @@ void http_parser_pause(http_parser *parser, int paused); /* Checks if this is the final chunk of the body. */ int http_body_is_final(const http_parser *parser); +/* Change the maximum header size provided at compile time. */ +void http_parser_set_max_header_size(uint32_t size); + #ifdef __cplusplus } #endif diff --git a/trunk/src/service/srs_service_http_conn.cpp b/trunk/src/service/srs_service_http_conn.cpp index ba556fe80..338a1b4b6 100644 --- a/trunk/src/service/srs_service_http_conn.cpp +++ b/trunk/src/service/srs_service_http_conn.cpp @@ -248,6 +248,12 @@ int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length) { SrsHttpParser* obj = (SrsHttpParser*)parser->data; srs_assert(obj); + + // When got body, but no header-parsed, we update it manually. + char* p = obj->buffer->bytes(); + if (!obj->header_parsed && p < at) { + obj->header_parsed = int(at - p); + } srs_info("Body: %.*s", (int)length, at); diff --git a/trunk/src/service/srs_service_http_conn.hpp b/trunk/src/service/srs_service_http_conn.hpp index 24a57d976..1eba2023f 100644 --- a/trunk/src/service/srs_service_http_conn.hpp +++ b/trunk/src/service/srs_service_http_conn.hpp @@ -69,7 +69,7 @@ public: * one parser can only parse request or response messages. * @param allow_jsonp whether allow jsonp parser, which indicates the method in query string. */ - virtual srs_error_t initialize(enum http_parser_type type, bool allow_jsonp); + virtual srs_error_t initialize(enum http_parser_type type, bool allow_jsonp = false); /** * always parse a http message, * that is, the *ppmsg always NOT-NULL when return success. diff --git a/trunk/src/utest/srs_utest_protocol.cpp b/trunk/src/utest/srs_utest_protocol.cpp index b873f203b..919349696 100644 --- a/trunk/src/utest/srs_utest_protocol.cpp +++ b/trunk/src/utest/srs_utest_protocol.cpp @@ -5597,8 +5597,282 @@ VOID TEST(ProtocolRTMPTest, RTMPHandshakeBytes) EXPECT_TRUE(bytes.s0s1s2 != NULL); } +struct MockStage +{ + http_parser parser; + const char* at; + size_t length; + + MockStage(http_parser* from); +}; + +MockStage::MockStage(http_parser* from) +{ + parser = *from; + at = NULL; + length = 0; +} + +class MockParser +{ +private: + http_parser_settings settings; + http_parser* parser; +public: + MockStage* message_begin; + MockStage* url; + MockStage* status; + MockStage* header_field; + MockStage* header_value; + MockStage* headers_complete; + MockStage* body; + MockStage* message_complete; + MockStage* chunk_header; + MockStage* chunk_complete; +public: + MockParser(); + virtual ~MockParser(); +public: + srs_error_t parse(string data); +private: + static int on_message_begin(http_parser* parser); + static int on_url(http_parser* parser, const char* at, size_t length); + static int on_status(http_parser* parser, const char* at, size_t length); + static int on_header_field(http_parser* parser, const char* at, size_t length); + static int on_header_value(http_parser* parser, const char* at, size_t length); + static int on_headers_complete(http_parser* parser); + static int on_body(http_parser* parser, const char* at, size_t length); + static int on_message_complete(http_parser* parser); + static int on_chunk_header(http_parser* parser); + static int on_chunk_complete(http_parser* parser); +}; + +MockParser::MockParser() +{ + parser = new http_parser(); + http_parser_init(parser, HTTP_REQUEST); + parser->data = (void*)this; + + memset(&settings, 0, sizeof(settings)); + settings.on_message_begin = on_message_begin; + settings.on_url = on_url; + settings.on_status = on_status; + settings.on_header_field = on_header_field; + settings.on_header_value = on_header_value; + settings.on_headers_complete = on_headers_complete; + settings.on_body = on_body; + settings.on_message_complete = on_message_complete; + settings.on_chunk_header = on_chunk_header; + settings.on_chunk_complete = on_chunk_complete; + + message_begin = NULL; + url = NULL; + status = NULL; + header_field = NULL; + header_value = NULL; + headers_complete = NULL; + body = NULL; + message_complete = NULL; + chunk_header = NULL; + chunk_complete = NULL; +} + +MockParser::~MockParser() +{ + srs_freep(parser); + + srs_freep(message_begin); + srs_freep(url); + srs_freep(status); + srs_freep(header_field); + srs_freep(header_value); + srs_freep(headers_complete); + srs_freep(body); + srs_freep(message_complete); + srs_freep(chunk_header); + srs_freep(chunk_complete); +} + +srs_error_t MockParser::parse(string data) +{ + srs_error_t err = srs_success; + + const char* buf = (const char*)data.data(); + size_t size = (size_t)data.length(); + size_t nparsed = http_parser_execute(parser, &settings, buf, size); + if (nparsed != size) { + return srs_error_new(-1, "nparsed=%d, size=%d", nparsed, size); + } + + return err; +} + +int MockParser::on_message_begin(http_parser* parser) +{ + MockParser* obj = (MockParser*)parser->data; + srs_assert(obj); + + srs_freep(obj->message_begin); + obj->message_begin = new MockStage(parser); + + return 0; +} + +int MockParser::on_url(http_parser* parser, const char* at, size_t length) +{ + MockParser* obj = (MockParser*)parser->data; + srs_assert(obj); + + srs_freep(obj->url); + obj->url = new MockStage(parser); + obj->url->at = at; + obj->url->length = length; + + return 0; +} + +int MockParser::on_status(http_parser* parser, const char* at, size_t length) +{ + MockParser* obj = (MockParser*)parser->data; + srs_assert(obj); + + srs_freep(obj->status); + obj->status = new MockStage(parser); + obj->status->at = at; + obj->status->length = length; + + return 0; +} + +int MockParser::on_header_field(http_parser* parser, const char* at, size_t length) +{ + MockParser* obj = (MockParser*)parser->data; + srs_assert(obj); + + srs_freep(obj->header_field); + obj->header_field = new MockStage(parser); + obj->header_field->at = at; + obj->header_field->length = length; + + return 0; +} + +int MockParser::on_header_value(http_parser* parser, const char* at, size_t length) +{ + MockParser* obj = (MockParser*)parser->data; + srs_assert(obj); + + srs_freep(obj->header_value); + obj->header_value = new MockStage(parser); + obj->header_value->at = at; + obj->header_value->length = length; + + return 0; +} + +int MockParser::on_headers_complete(http_parser* parser) +{ + MockParser* obj = (MockParser*)parser->data; + srs_assert(obj); + + srs_freep(obj->headers_complete); + obj->headers_complete = new MockStage(parser); + + return 0; +} + +int MockParser::on_body(http_parser* parser, const char* at, size_t length) +{ + MockParser* obj = (MockParser*)parser->data; + srs_assert(obj); + + srs_freep(obj->body); + obj->body = new MockStage(parser); + obj->body->at = at; + obj->body->length = length; + + return 0; +} + +int MockParser::on_message_complete(http_parser* parser) +{ + MockParser* obj = (MockParser*)parser->data; + srs_assert(obj); + + srs_freep(obj->message_complete); + obj->message_complete = new MockStage(parser); + + return 0; +} + +int MockParser::on_chunk_header(http_parser* parser) +{ + MockParser* obj = (MockParser*)parser->data; + srs_assert(obj); + + srs_freep(obj->chunk_header); + obj->chunk_header = new MockStage(parser); + + return 0; +} + +int MockParser::on_chunk_complete(http_parser* parser) +{ + MockParser* obj = (MockParser*)parser->data; + srs_assert(obj); + + srs_freep(obj->chunk_complete); + obj->chunk_complete = new MockStage(parser); + + return 0; +} + +#define HELPER_EXPECT_SUCCESS(x) EXPECT_TRUE(srs_success == (err = x)); srs_freep(err) +#define HELPER_EXPECT_FAILED(x) EXPECT_TRUE(srs_success != (err = x)); srs_freep(err) + +VOID TEST(ProtocolHTTPTest, HTTPParser) +{ + srs_error_t err; + + if (true) { + MockParser parser; + HELPER_EXPECT_SUCCESS(parser.parse("GE")); + HELPER_EXPECT_FAILED(parser.parse("")); + } + + if (true) { + MockParser parser; + HELPER_EXPECT_SUCCESS(parser.parse("GE")); + HELPER_EXPECT_FAILED(parser.parse("X")); + } + + if (true) { + MockParser parser; + HELPER_EXPECT_SUCCESS(parser.parse("GE")); + HELPER_EXPECT_SUCCESS(parser.parse("T")); + } + + if (true) { + MockParser parser; + HELPER_EXPECT_SUCCESS(parser.parse("GET")); + } +} + VOID TEST(ProtocolHTTPTest, ParseHTTPMessage) { + if (true) { + MockBufferIO bio; + SrsHttpParser hp; + + bio.append("GET"); + EXPECT_TRUE(0 == hp.initialize(HTTP_REQUEST, false)); + + // Should fail if not completed message. + ISrsHttpMessage* req = NULL; + ASSERT_FALSE(0 == hp.parse_message(&bio, &req)); + srs_freep(req); + } + if (true) { MockBufferIO bio; SrsHttpParser hp; @@ -5606,26 +5880,21 @@ VOID TEST(ProtocolHTTPTest, ParseHTTPMessage) bio.append("GET /gslb/v1/versions HTTP/1.1\r\nContent-Length: 5\r\n\r\nHello"); EXPECT_TRUE(0 == hp.initialize(HTTP_REQUEST, false)); - if (true) { - ISrsHttpMessage* req = NULL; - SrsAutoFree(ISrsHttpMessage, req); - ASSERT_TRUE(0 == hp.parse_message(&bio, &req)); - - // We should read body, or next parsing message will fail. - // @see https://github.com/ossrs/srs/issues/1181 - EXPECT_FALSE(req->body_reader()->eof()); - } - - if (true) { - bio.append("GET /gslb/v1/versions HTTP/1.1\r\nContent-Length: 5\r\n\r\nHello"); - - // Should fail because there is body which not read. - // @see https://github.com/ossrs/srs/issues/1181 - - ISrsHttpMessage* req = NULL; - SrsAutoFree(ISrsHttpMessage, req); - ASSERT_FALSE(0 == hp.parse_message(&bio, &req)); - } + ISrsHttpMessage* req = NULL; + ASSERT_TRUE(0 == hp.parse_message(&bio, &req)); + + // We should read body, or next parsing message will fail. + // @see https://github.com/ossrs/srs/issues/1181 + EXPECT_FALSE(req->body_reader()->eof()); + srs_freep(req); + + // Got new packet, notice that previous body still exists in bio. + bio.append("GET /gslb/v2/versions HTTP/1.1\r\nContent-Length: 5\r\n\r\nHello"); + + // Should fail because there is body which not read. + // @see https://github.com/ossrs/srs/issues/1181 + ASSERT_FALSE(0 == hp.parse_message(&bio, &req)); + srs_freep(req); } if (true) { From 0ee386b656d7924c1c69ab1050c26ff9f2385ba6 Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 25 Apr 2019 08:51:38 +0800 Subject: [PATCH 09/25] Refine http parser code. --- trunk/src/utest/srs_utest.hpp | 4 ++++ trunk/src/utest/srs_utest_protocol.cpp | 29 ++++++++++++-------------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/trunk/src/utest/srs_utest.hpp b/trunk/src/utest/srs_utest.hpp index f9222fe43..fb96274e6 100644 --- a/trunk/src/utest/srs_utest.hpp +++ b/trunk/src/utest/srs_utest.hpp @@ -40,6 +40,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // we add an empty macro for upp to show the smart tips. #define VOID +// For errors. +#define HELPER_EXPECT_SUCCESS(x) EXPECT_TRUE(srs_success == (err = x)); srs_freep(err) +#define HELPER_EXPECT_FAILED(x) EXPECT_TRUE(srs_success != (err = x)); srs_freep(err) + // the asserts of gtest: // * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual // * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 diff --git a/trunk/src/utest/srs_utest_protocol.cpp b/trunk/src/utest/srs_utest_protocol.cpp index 919349696..b704c0ee5 100644 --- a/trunk/src/utest/srs_utest_protocol.cpp +++ b/trunk/src/utest/srs_utest_protocol.cpp @@ -5693,20 +5693,6 @@ MockParser::~MockParser() srs_freep(chunk_complete); } -srs_error_t MockParser::parse(string data) -{ - srs_error_t err = srs_success; - - const char* buf = (const char*)data.data(); - size_t size = (size_t)data.length(); - size_t nparsed = http_parser_execute(parser, &settings, buf, size); - if (nparsed != size) { - return srs_error_new(-1, "nparsed=%d, size=%d", nparsed, size); - } - - return err; -} - int MockParser::on_message_begin(http_parser* parser) { MockParser* obj = (MockParser*)parser->data; @@ -5827,8 +5813,19 @@ int MockParser::on_chunk_complete(http_parser* parser) return 0; } -#define HELPER_EXPECT_SUCCESS(x) EXPECT_TRUE(srs_success == (err = x)); srs_freep(err) -#define HELPER_EXPECT_FAILED(x) EXPECT_TRUE(srs_success != (err = x)); srs_freep(err) +srs_error_t MockParser::parse(string data) +{ + srs_error_t err = srs_success; + + const char* buf = (const char*)data.data(); + size_t size = (size_t)data.length(); + size_t nparsed = http_parser_execute(parser, &settings, buf, size); + if (nparsed != size) { + return srs_error_new(-1, "nparsed=%d, size=%d", nparsed, size); + } + + return err; +} VOID TEST(ProtocolHTTPTest, HTTPParser) { From 8a94ac4b49d04711b2d88921ef7b45e82cd26033 Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 25 Apr 2019 10:39:38 +0800 Subject: [PATCH 10/25] Upgrade http-parser to 2.9.2 --- trunk/src/protocol/srs_http_stack.hpp | 1 + trunk/src/service/srs_service_http_conn.cpp | 66 +++---- trunk/src/service/srs_service_http_conn.hpp | 2 +- trunk/src/utest/srs_utest_protocol.cpp | 207 ++++++++++++++++++-- 4 files changed, 226 insertions(+), 50 deletions(-) diff --git a/trunk/src/protocol/srs_http_stack.hpp b/trunk/src/protocol/srs_http_stack.hpp index 321c97325..28a511145 100644 --- a/trunk/src/protocol/srs_http_stack.hpp +++ b/trunk/src/protocol/srs_http_stack.hpp @@ -100,6 +100,7 @@ enum SrsHttpParseState { SrsHttpParseStateInit = 0, SrsHttpParseStateStart, SrsHttpParseStateHeaderComplete, + SrsHttpParseStateBody, SrsHttpParseStateMessageComplete }; diff --git a/trunk/src/service/srs_service_http_conn.cpp b/trunk/src/service/srs_service_http_conn.cpp index 338a1b4b6..2a746bce3 100644 --- a/trunk/src/service/srs_service_http_conn.cpp +++ b/trunk/src/service/srs_service_http_conn.cpp @@ -82,7 +82,7 @@ srs_error_t SrsHttpParser::parse_message(ISrsReader* reader, ISrsHttpMessage** p header = http_parser(); url = ""; headers.clear(); - header_parsed = 0; + pbody = NULL; // do parse if ((err = parse_message_imp(reader)) != srs_success) { @@ -110,37 +110,34 @@ srs_error_t SrsHttpParser::parse_message_imp(ISrsReader* reader) while (true) { ssize_t nparsed = 0; - - // when got entire http header, parse it. - // @see https://github.com/ossrs/srs/issues/400 + char* start = buffer->bytes(); - char* end = start + buffer->size(); - for (char* p = start; p <= end - 4; p++) { - // SRS_HTTP_CRLFCRLF "\r\n\r\n" // 0x0D0A0D0A - if (p[0] == SRS_CONSTS_CR && p[1] == SRS_CONSTS_LF && p[2] == SRS_CONSTS_CR && p[3] == SRS_CONSTS_LF) { - nparsed = http_parser_execute(&parser, &settings, buffer->bytes(), buffer->size()); - srs_info("buffer=%d, nparsed=%d, header=%d", buffer->size(), (int)nparsed, header_parsed); - break; - } - } - - // consume the parsed bytes. - if (nparsed && header_parsed) { - buffer->read_slice(header_parsed); - } - - // ok atleast header completed, - // never wait for body completed, for maybe chunked. - if (state == SrsHttpParseStateHeaderComplete || state == SrsHttpParseStateMessageComplete) { - break; + if (buffer->size() > 0) { + nparsed = http_parser_execute(&parser, &settings, buffer->bytes(), buffer->size()); + if (buffer->size() != nparsed) { + return srs_error_new(ERROR_HTTP_PARSE_HEADER, "parse failed, nparsed=%d, size=%d", nparsed, buffer->size()); + } + + // The consumed size, does not include the body. + ssize_t consumed = nparsed; + if (pbody && start < pbody) { + consumed = pbody - start; + } + srs_info("size=%d, nparsed=%d, consumed=%d", buffer->size(), (int)nparsed, consumed); + + // Only consume the header bytes. + buffer->read_slice(consumed); + + // Done when header completed, never wait for body completed, because it maybe chunked. + if (state >= SrsHttpParseStateHeaderComplete) { + break; + } } // when nothing parsed, read more to parse. - if (nparsed == 0) { - // when requires more, only grow 1bytes, but the buffer will cache more. - if ((err = buffer->grow(reader, buffer->size() + 1)) != srs_success) { - return srs_error_wrap(err, "grow buffer"); - } + // when requires more, only grow 1bytes, but the buffer will cache more. + if ((err = buffer->grow(reader, buffer->size() + 1)) != srs_success) { + return srs_error_wrap(err, "grow buffer"); } } @@ -172,8 +169,7 @@ int SrsHttpParser::on_headers_complete(http_parser* parser) obj->header = *parser; // save the parser when header parse completed. obj->state = SrsHttpParseStateHeaderComplete; - obj->header_parsed = (int)parser->nread; - + srs_info("***HEADERS COMPLETE***"); // see http_parser.c:1570, return 1 to skip body. @@ -249,11 +245,11 @@ int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length) SrsHttpParser* obj = (SrsHttpParser*)parser->data; srs_assert(obj); - // When got body, but no header-parsed, we update it manually. - char* p = obj->buffer->bytes(); - if (!obj->header_parsed && p < at) { - obj->header_parsed = int(at - p); - } + // save the parser when body parsed. + obj->state = SrsHttpParseStateBody; + + // Save the body position. + obj->pbody = at; srs_info("Body: %.*s", (int)length, at); diff --git a/trunk/src/service/srs_service_http_conn.hpp b/trunk/src/service/srs_service_http_conn.hpp index 1eba2023f..3ebfc335a 100644 --- a/trunk/src/service/srs_service_http_conn.hpp +++ b/trunk/src/service/srs_service_http_conn.hpp @@ -59,7 +59,7 @@ private: http_parser header; std::string url; std::vector headers; - int header_parsed; + const char* pbody; public: SrsHttpParser(); virtual ~SrsHttpParser(); diff --git a/trunk/src/utest/srs_utest_protocol.cpp b/trunk/src/utest/srs_utest_protocol.cpp index b704c0ee5..86a7af41c 100644 --- a/trunk/src/utest/srs_utest_protocol.cpp +++ b/trunk/src/utest/srs_utest_protocol.cpp @@ -5618,6 +5618,7 @@ class MockParser private: http_parser_settings settings; http_parser* parser; + size_t parsed; public: MockStage* message_begin; MockStage* url; @@ -5652,6 +5653,7 @@ MockParser::MockParser() parser = new http_parser(); http_parser_init(parser, HTTP_REQUEST); parser->data = (void*)this; + parsed = 0; memset(&settings, 0, sizeof(settings)); settings.on_message_begin = on_message_begin; @@ -5820,6 +5822,8 @@ srs_error_t MockParser::parse(string data) const char* buf = (const char*)data.data(); size_t size = (size_t)data.length(); size_t nparsed = http_parser_execute(parser, &settings, buf, size); + parsed = nparsed; + if (nparsed != size) { return srs_error_new(-1, "nparsed=%d, size=%d", nparsed, size); } @@ -5833,25 +5837,200 @@ VOID TEST(ProtocolHTTPTest, HTTPParser) if (true) { MockParser parser; + // size = 70, nparsed = 70, nread = 0 + HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\n")); + EXPECT_EQ(70, parser.parsed); + EXPECT_EQ(0, parser.parser->nread); + EXPECT_TRUE(!parser.body); + EXPECT_TRUE(parser.headers_complete); + EXPECT_TRUE(!parser.message_complete); + } + + if (true) { + MockParser parser; + // size = 75, nparsed = 75, nread = 0 + HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello")); + EXPECT_EQ(75, parser.parsed); + EXPECT_EQ(0, parser.parser->nread); + EXPECT_TRUE(parser.body && 5 == parser.body->length); + EXPECT_TRUE(parser.headers_complete); + EXPECT_TRUE(parser.message_complete); + } + + if (true) { + MockParser parser; + // size = 150, nparsed = 150, nread = 0 + HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHelloGET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nWorld")); + EXPECT_EQ(150, parser.parsed); + EXPECT_EQ(0, parser.parser->nread); + } + + if (true) { + MockParser parser; + // size = 70, nparsed = 70, nread = 0, content_length = 5, Header("Content-Length", 5) + HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\n")); + EXPECT_EQ(70, parser.parsed); + EXPECT_EQ(0, parser.parser->nread); + EXPECT_EQ(5, parser.parser->content_length); + + // size = 79, nparsed = 5, nread = 1, content_length = -1, Header("Content-Length", 5) + HELPER_EXPECT_FAILED(parser.parse("elloGET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello")); + EXPECT_EQ(5, parser.parsed); + EXPECT_EQ(1, parser.parser->nread); + EXPECT_EQ(-1, (int64_t)parser.parser->content_length); + } + + if (true) { + MockParser parser; + // size = 70, nparsed = 70, nread = 0, content_length = 5, Header("Content-Length", 5) + HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\n")); + EXPECT_EQ(70, parser.parsed); + EXPECT_EQ(0, parser.parser->nread); + EXPECT_EQ(5, parser.parser->content_length); + + // size = 80, nparsed = 70, nread = 0, content_length = 0, Header("Content-Length", 5) + HELPER_EXPECT_SUCCESS(parser.parse("HelloGET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nWorld")); + EXPECT_EQ(80, parser.parsed); + EXPECT_EQ(0, parser.parser->nread); + EXPECT_EQ(0, parser.parser->content_length); + } + + if (true) { + MockParser parser; + // size = 73, nparsed = 73, nread = 0, content_length = 2, Header("Content-Length", 5) + HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHel")); + EXPECT_EQ(73, parser.parsed); + EXPECT_EQ(0, parser.parser->nread); + EXPECT_EQ(2, parser.parser->content_length); + } + + if (true) { + MockParser parser; + // size = 82, nparsed = 75, nread = 1, content_length = -1, Header("Content-Length", 5) + HELPER_EXPECT_FAILED(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello World!")); + EXPECT_EQ(75, parser.parsed); + EXPECT_EQ(1, parser.parser->nread); + EXPECT_EQ(-1, (int64_t)parser.parser->content_length); + } + + if (true) { + MockParser parser; + // size = 34, nparsed = 34, nread = 34 + HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHo")); + EXPECT_EQ(34, parser.parsed); + EXPECT_EQ(34, parser.parser->nread); + + // size = 41, nparsed = 41, nread = 0 + HELPER_EXPECT_SUCCESS(parser.parse("st: ossrs.net\r\nContent-Length: 5\r\n\r\nHello")); + EXPECT_EQ(41, parser.parsed); + EXPECT_EQ(0, parser.parser->nread); + } + + if (true) { + MockParser parser; + // size = 41, nparsed = 41, nread = 41 + HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: oss")); + EXPECT_EQ(41, parser.parsed); + EXPECT_EQ(41, parser.parser->nread); + + // size = 34, nparsed = 34, nread = 0 + HELPER_EXPECT_SUCCESS(parser.parse("rs.net\r\nContent-Length: 5\r\n\r\nHello")); + EXPECT_EQ(34, parser.parsed); + EXPECT_EQ(0, parser.parser->nread); + } + + if (true) { + MockParser parser; + // size = 48, nparsed = 48, nread = 48 + HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r")); + EXPECT_EQ(48, parser.parsed); + EXPECT_EQ(48, parser.parser->nread); + + // size = 27, nparsed = 27, nread = 0 + HELPER_EXPECT_SUCCESS(parser.parse("\nContent-Length: 5\r\n\r\nHello")); + EXPECT_EQ(27, parser.parsed); + EXPECT_EQ(0, parser.parser->nread); + } + + if (true) { + MockParser parser; + // size = 68, nparsed = 68, nread = 68 + HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n")); + EXPECT_EQ(68, parser.parsed); + EXPECT_EQ(68, parser.parser->nread); + + // size = 7, nparsed = 7, nread = 0 + HELPER_EXPECT_SUCCESS(parser.parse("\r\nHello")); + EXPECT_EQ(7, parser.parsed); + EXPECT_EQ(0, parser.parser->nread); + } + + if (true) { + MockParser parser; + // size = 69, nparsed = 69, nread = 69 + HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r")); + EXPECT_EQ(69, parser.parsed); + EXPECT_EQ(69, parser.parser->nread); + + // size = 6, nparsed = 6, nread = 0 + HELPER_EXPECT_SUCCESS(parser.parse("\nHello")); + EXPECT_EQ(6, parser.parsed); + EXPECT_EQ(0, parser.parser->nread); + } + + if (true) { + MockParser parser; + // size = 75, nparsed = 75, nread = 0 + HELPER_EXPECT_SUCCESS(parser.parse("GET /gslb/v1/versions HTTP/1.1\r\nHost: ossrs.net\r\nContent-Length: 5\r\n\r\nHello")); + EXPECT_EQ(75, parser.parsed); + EXPECT_EQ(0, parser.parser->nread); + } + + if (true) { + MockParser parser; + // nparsed = 2, size = 2, nread = 2 HELPER_EXPECT_SUCCESS(parser.parse("GE")); + EXPECT_EQ(2, parser.parsed); + EXPECT_EQ(2, parser.parser->nread); + + // size = 0, nparsed = 1, nread=2 HELPER_EXPECT_FAILED(parser.parse("")); + EXPECT_EQ(1, parser.parsed); + EXPECT_EQ(2, parser.parser->nread); } if (true) { MockParser parser; + // size = 2, nparsed = 2, nread = 2 HELPER_EXPECT_SUCCESS(parser.parse("GE")); + EXPECT_EQ(2, parser.parsed); + EXPECT_EQ(2, parser.parser->nread); + + // size = 1, nparsed = 0, nread = 3 HELPER_EXPECT_FAILED(parser.parse("X")); + EXPECT_EQ(0, parser.parsed); + EXPECT_EQ(3, parser.parser->nread); } if (true) { MockParser parser; + // size = 2, nparsed = 2, nread = 2 HELPER_EXPECT_SUCCESS(parser.parse("GE")); + EXPECT_EQ(2, parser.parsed); + EXPECT_EQ(2, parser.parser->nread); + + // size = 1, nparsed = 1, nread = 3 HELPER_EXPECT_SUCCESS(parser.parse("T")); + EXPECT_EQ(1, parser.parsed); + EXPECT_EQ(3, parser.parser->nread); } if (true) { MockParser parser; + // size = 3, nparsed = 3, nread = 3 HELPER_EXPECT_SUCCESS(parser.parse("GET")); + EXPECT_EQ(3, parser.parsed); + EXPECT_EQ(3, parser.parser->nread); } } @@ -5861,22 +6040,9 @@ VOID TEST(ProtocolHTTPTest, ParseHTTPMessage) MockBufferIO bio; SrsHttpParser hp; - bio.append("GET"); - EXPECT_TRUE(0 == hp.initialize(HTTP_REQUEST, false)); - - // Should fail if not completed message. - ISrsHttpMessage* req = NULL; - ASSERT_FALSE(0 == hp.parse_message(&bio, &req)); - srs_freep(req); - } - - if (true) { - MockBufferIO bio; - SrsHttpParser hp; - bio.append("GET /gslb/v1/versions HTTP/1.1\r\nContent-Length: 5\r\n\r\nHello"); EXPECT_TRUE(0 == hp.initialize(HTTP_REQUEST, false)); - + ISrsHttpMessage* req = NULL; ASSERT_TRUE(0 == hp.parse_message(&bio, &req)); @@ -5893,6 +6059,19 @@ VOID TEST(ProtocolHTTPTest, ParseHTTPMessage) ASSERT_FALSE(0 == hp.parse_message(&bio, &req)); srs_freep(req); } + + if (true) { + MockBufferIO bio; + SrsHttpParser hp; + + bio.append("GET"); + EXPECT_TRUE(0 == hp.initialize(HTTP_REQUEST, false)); + + // Should fail if not completed message. + ISrsHttpMessage* req = NULL; + ASSERT_FALSE(0 == hp.parse_message(&bio, &req)); + srs_freep(req); + } if (true) { MockBufferIO bio; From c933f8a870beaaf5eb4d80e2dc20de3a1d52ff82 Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 25 Apr 2019 10:41:59 +0800 Subject: [PATCH 11/25] Upgrade http-parser from 2.1 to 2.9.2 and cover it. 3.0.50 --- README.md | 1 + trunk/src/core/srs_core.hpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a3e663510..3e5ee0be1 100755 --- a/README.md +++ b/README.md @@ -164,6 +164,7 @@ Please select according to languages: ### V3 changes +* v3.0, 2019-04-25, Upgrade http-parser from 2.1 to 2.9.2 and cover it. 3.0.50 * v3.0, 2019-04-22, Refine in time unit. 3.0.49 * v3.0, 2019-04-07, Cover ST Coroutine and time unit. 3.0.48 * v3.0, 2019-04-06, Merge [#1304][bug #1304], Fix ST coroutine pull error. 3.0.47 diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 201263148..27eec767b 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -27,7 +27,7 @@ // The version config. #define VERSION_MAJOR 3 #define VERSION_MINOR 0 -#define VERSION_REVISION 49 +#define VERSION_REVISION 50 // The macros generated by configure script. #include From fbe40dc42c8c267a3690358530ee847cdcc54968 Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 25 Apr 2019 11:04:10 +0800 Subject: [PATCH 12/25] Refine code --- trunk/src/service/srs_service_http_conn.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/trunk/src/service/srs_service_http_conn.cpp b/trunk/src/service/srs_service_http_conn.cpp index 2a746bce3..c7cd873e0 100644 --- a/trunk/src/service/srs_service_http_conn.cpp +++ b/trunk/src/service/srs_service_http_conn.cpp @@ -109,19 +109,16 @@ srs_error_t SrsHttpParser::parse_message_imp(ISrsReader* reader) srs_error_t err = srs_success; while (true) { - ssize_t nparsed = 0; - - char* start = buffer->bytes(); if (buffer->size() > 0) { - nparsed = http_parser_execute(&parser, &settings, buffer->bytes(), buffer->size()); + ssize_t nparsed = http_parser_execute(&parser, &settings, buffer->bytes(), buffer->size()); if (buffer->size() != nparsed) { return srs_error_new(ERROR_HTTP_PARSE_HEADER, "parse failed, nparsed=%d, size=%d", nparsed, buffer->size()); } // The consumed size, does not include the body. ssize_t consumed = nparsed; - if (pbody && start < pbody) { - consumed = pbody - start; + if (pbody && buffer->bytes() < pbody) { + consumed = pbody - buffer->bytes(); } srs_info("size=%d, nparsed=%d, consumed=%d", buffer->size(), (int)nparsed, consumed); From 224d7c539f24ce908c8964c8be061d1bf6d59a3f Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 28 Apr 2019 08:21:48 +0800 Subject: [PATCH 13/25] Refine typo in service. --- trunk/src/service/srs_service_conn.hpp | 12 +- trunk/src/service/srs_service_http_client.hpp | 58 +++--- trunk/src/service/srs_service_http_conn.hpp | 182 ++++++------------ trunk/src/service/srs_service_log.hpp | 22 +-- trunk/src/service/srs_service_rtmp_conn.hpp | 16 +- trunk/src/service/srs_service_st.hpp | 62 +++--- trunk/src/service/srs_service_utility.hpp | 8 +- 7 files changed, 129 insertions(+), 231 deletions(-) diff --git a/trunk/src/service/srs_service_conn.hpp b/trunk/src/service/srs_service_conn.hpp index 6e10fbe57..02841a260 100644 --- a/trunk/src/service/srs_service_conn.hpp +++ b/trunk/src/service/srs_service_conn.hpp @@ -26,9 +26,7 @@ #include -/** - * The connection interface for all HTTP/RTMP/RTSP object. - */ +// The connection interface for all HTTP/RTMP/RTSP object. class ISrsConnection { public: @@ -36,18 +34,14 @@ public: virtual ~ISrsConnection(); }; -/** - * the manager for connection. - */ +// The manager for connection. class IConnectionManager { public: IConnectionManager(); virtual ~IConnectionManager(); public: - /** - * Remove then free the specified connection. - */ + // Remove then free the specified connection. virtual void remove(ISrsConnection* c) = 0; }; diff --git a/trunk/src/service/srs_service_http_client.hpp b/trunk/src/service/srs_service_http_client.hpp index 238eb8f44..9c07dd817 100644 --- a/trunk/src/service/srs_service_http_client.hpp +++ b/trunk/src/service/srs_service_http_client.hpp @@ -40,18 +40,16 @@ class SrsKbps; class SrsWallClock; class SrsTcpClient; -// the default timeout for http client. -#define SRS_HTTP_CLIENT_TIMEOUT (30 * SRS_UTIME_SECONDS) +// The default timeout for http client. +#define SRS_HTTP_CLIENT_TIMEOUT (30// SRS_UTIME_SECONDS) -/** - * The client to GET/POST/PUT/DELETE over HTTP. - * @remark We will reuse the TCP transport until initialize or channel error, - * such as send/recv failed. - * Usage: - * SrsHttpClient hc; - * hc.initialize("127.0.0.1", 80, 9000); - * hc.post("/api/v1/version", "Hello world!", NULL); - */ +// The client to GET/POST/PUT/DELETE over HTTP. +// @remark We will reuse the TCP transport until initialize or channel error, +// such as send/recv failed. +// Usage: +// SrsHttpClient hc; +// hc.initialize("127.0.0.1", 80, 9000); +// hc.post("/api/v1/version", "Hello world!", NULL); class SrsHttpClient { private: @@ -72,33 +70,25 @@ public: SrsHttpClient(); virtual ~SrsHttpClient(); public: - /** - * Initliaze the client, disconnect the transport, renew the HTTP parser. - * @param tm The underlayer TCP transport timeout in srs_utime_t. - * @remark we will set default values in headers, which can be override by set_header. - */ + // Initliaze the client, disconnect the transport, renew the HTTP parser. + // @param tm The underlayer TCP transport timeout in srs_utime_t. + // @remark we will set default values in headers, which can be override by set_header. virtual srs_error_t initialize(std::string h, int p, srs_utime_t tm = SRS_HTTP_CLIENT_TIMEOUT); - /** - * Set HTTP request header in header[k]=v. - * @return the HTTP client itself. - */ + // Set HTTP request header in header[k]=v. + // @return the HTTP client itself. virtual SrsHttpClient* set_header(std::string k, std::string v); public: - /** - * to post data to the uri. - * @param the path to request on. - * @param req the data post to uri. empty string to ignore. - * @param ppmsg output the http message to read the response. - * @remark user must free the ppmsg if not NULL. - */ + // Post data to the uri. + // @param the path to request on. + // @param req the data post to uri. empty string to ignore. + // @param ppmsg output the http message to read the response. + // @remark user must free the ppmsg if not NULL. virtual srs_error_t post(std::string path, std::string req, ISrsHttpMessage** ppmsg); - /** - * to get data from the uri. - * @param the path to request on. - * @param req the data post to uri. empty string to ignore. - * @param ppmsg output the http message to read the response. - * @remark user must free the ppmsg if not NULL. - */ + // Get data from the uri. + // @param the path to request on. + // @param req the data post to uri. empty string to ignore. + // @param ppmsg output the http message to read the response. + // @remark user must free the ppmsg if not NULL. virtual srs_error_t get(std::string path, std::string req, ISrsHttpMessage** ppmsg); private: virtual void set_recv_timeout(srs_utime_t tm); diff --git a/trunk/src/service/srs_service_http_conn.hpp b/trunk/src/service/srs_service_http_conn.hpp index 3ebfc335a..633ba8634 100644 --- a/trunk/src/service/srs_service_http_conn.hpp +++ b/trunk/src/service/srs_service_http_conn.hpp @@ -37,18 +37,16 @@ class ISrsReader; class SrsHttpResponseReader; class SrsStSocket; -/** - * wrapper for http-parser, - * provides HTTP message originted service. - */ +// A wrapper for http-parser, +// provides HTTP message originted service. class SrsHttpParser { private: http_parser_settings settings; http_parser parser; - // the global parse buffer. + // The global parse buffer. SrsFastStream* buffer; - // whether allow jsonp parse. + // Whether allow jsonp parse. bool jsonp; private: // http parse data, reset before parse message. @@ -64,24 +62,18 @@ public: SrsHttpParser(); virtual ~SrsHttpParser(); public: - /** - * initialize the http parser with specified type, - * one parser can only parse request or response messages. - * @param allow_jsonp whether allow jsonp parser, which indicates the method in query string. - */ + // initialize the http parser with specified type, + // one parser can only parse request or response messages. + // @param allow_jsonp whether allow jsonp parser, which indicates the method in query string. virtual srs_error_t initialize(enum http_parser_type type, bool allow_jsonp = false); - /** - * always parse a http message, - * that is, the *ppmsg always NOT-NULL when return success. - * or error and *ppmsg must be NULL. - * @remark, if success, *ppmsg always NOT-NULL, *ppmsg always is_complete(). - * @remark user must free the ppmsg if not NULL. - */ + // always parse a http message, + // that is, the *ppmsg always NOT-NULL when return success. + // or error and *ppmsg must be NULL. + // @remark, if success, *ppmsg always NOT-NULL, *ppmsg always is_complete(). + // @remark user must free the ppmsg if not NULL. virtual srs_error_t parse_message(ISrsReader* reader, ISrsHttpMessage** ppmsg); private: - /** - * parse the HTTP message to member field: msg. - */ + // parse the HTTP message to member field: msg. virtual srs_error_t parse_message_imp(ISrsReader* reader); private: static int on_message_begin(http_parser* parser); @@ -105,62 +97,41 @@ typedef std::pair SrsHttpHeaderField; class SrsHttpMessage : public ISrsHttpMessage { private: - /** - * parsed url. - */ + // The parsed url. std::string _url; - /** - * the extension of file, for example, .flv - */ + // The extension of file, for example, .flv std::string _ext; - /** - * parsed http header. - */ + // parsed http header. http_parser _header; - /** - * body object, reader object. - * @remark, user can get body in string by get_body(). - */ + // The body object, reader object. + // @remark, user can get body in string by get_body(). SrsHttpResponseReader* _body; - /** - * whether the body is chunked. - */ + // Whether the body is chunked. bool chunked; - /** - * whether the body is infinite chunked. - */ + // Whether the body is infinite chunked. bool infinite_chunked; - /** - * whether the request indicates should keep alive - * for the http connection. - */ + // Whether the request indicates should keep alive for the http connection. bool keep_alive; - /** - * uri parser - */ + // The uri parser SrsHttpUri* _uri; - /** - * use a buffer to read and send ts file. - */ + // Use a buffer to read and send ts file. // TODO: FIXME: remove it. char* _http_ts_send_buffer; - // http headers + // The http headers std::vector _headers; - // the query map + // The query map std::map _query; - // the transport connection, can be NULL. + // The transport connection, can be NULL. SrsConnection* owner_conn; - // whether request is jsonp. + // Whether request is jsonp. bool jsonp; - // the method in QueryString will override the HTTP method. + // The method in QueryString will override the HTTP method. std::string jsonp_method; public: SrsHttpMessage(ISrsReader* io); virtual ~SrsHttpMessage(); public: - /** - * set the original messages, then update the message. - */ + // set the original messages, then update the message. virtual srs_error_t update(std::string url, bool allow_jsonp, http_parser* header, SrsFastStream* body, std::vector& headers); public: // Get the owner connection, maybe NULL. @@ -169,91 +140,62 @@ public: public: virtual uint8_t method(); virtual uint16_t status_code(); - /** - * method helpers. - */ + // The method helpers. virtual std::string method_str(); virtual bool is_http_get(); virtual bool is_http_put(); virtual bool is_http_post(); virtual bool is_http_delete(); virtual bool is_http_options(); - /** - * whether body is chunked encoding, for reader only. - */ + // Whether body is chunked encoding, for reader only. virtual bool is_chunked(); - /** - * whether body is infinite chunked encoding. - * @remark set by enter_infinite_chunked. - */ + // Whether body is infinite chunked encoding. + // @remark set by enter_infinite_chunked. virtual bool is_infinite_chunked(); - /** - * whether should keep the connection alive. - */ + // Whether should keep the connection alive. virtual bool is_keep_alive(); - /** - * the uri contains the host and path. - */ + // The uri contains the host and path. virtual std::string uri(); - /** - * the url maybe the path. - */ + // The url maybe the path. virtual std::string url(); virtual std::string host(); virtual std::string path(); virtual std::string query(); virtual std::string ext(); - /** - * get the RESTful matched id. - */ + // Get the RESTful matched id. virtual int parse_rest_id(std::string pattern); public: virtual srs_error_t enter_infinite_chunked(); public: - /** - * read body to string. - * @remark for small http body. - */ + // Read body to string. + // @remark for small http body. virtual srs_error_t body_read_all(std::string& body); - /** - * get the body reader, to read one by one. - * @remark when body is very large, or chunked, use this. - */ + // Get the body reader, to read one by one. + // @remark when body is very large, or chunked, use this. virtual ISrsHttpResponseReader* body_reader(); - /** - * the content length, -1 for chunked or not set. - */ + // The content length, -1 for chunked or not set. virtual int64_t content_length(); - /** - * get the param in query string, - * for instance, query is "start=100&end=200", - * then query_get("start") is "100", and query_get("end") is "200" - */ + // Get the param in query string, for instance, query is "start=100&end=200", + // then query_get("start") is "100", and query_get("end") is "200" virtual std::string query_get(std::string key); - /** - * get the headers. - */ + // Get the headers. virtual int request_header_count(); virtual std::string request_header_key_at(int index); virtual std::string request_header_value_at(int index); virtual std::string get_request_header(std::string name); public: - /** - * convert the http message to a request. - * @remark user must free the return request. - */ + // Convert the http message to a request. + // @remark user must free the return request. virtual SrsRequest* to_request(std::string vhost); public: virtual bool is_jsonp(); }; -// the http chunked header size, +// The http chunked header size, // for writev, there always one chunk to send it. #define SRS_HTTP_HEADER_CACHE_SIZE 64 -/** - * response writer use st socket - */ +// Response writer use st socket class SrsHttpResponseWriter : public ISrsHttpResponseWriter { private: @@ -264,17 +206,17 @@ private: iovec* iovss_cache; int nb_iovss_cache; private: - // reply header has been (logically) written + // Reply header has been (logically) written bool header_wrote; - // status code passed to WriteHeader + // The status code passed to WriteHeader int status; private: - // explicitly-declared Content-Length; or -1 + // The explicitly-declared Content-Length; or -1 int64_t content_length; - // number of bytes written in body + // The number of bytes written in body int64_t written; private: - // wroteHeader tells whether the header's been written to "the + // The wroteHeader tells whether the header's been written to "the // wire" (or rather: w.conn.buf). this is unlike // (*response).wroteHeader, which tells only whether it was // logically written. @@ -291,9 +233,7 @@ public: virtual srs_error_t send_header(char* data, int size); }; -/** - * response reader use st socket. - */ +// Response reader use st socket. class SrsHttpResponseReader : virtual public ISrsHttpResponseReader { private: @@ -301,21 +241,19 @@ private: SrsHttpMessage* owner; SrsFastStream* buffer; bool is_eof; - // the left bytes in chunk. + // The left bytes in chunk. int nb_left_chunk; - // the number of bytes of current chunk. + // The number of bytes of current chunk. int nb_chunk; - // already read total bytes. + // Already read total bytes. int64_t nb_total_read; public: SrsHttpResponseReader(SrsHttpMessage* msg, ISrsReader* reader); virtual ~SrsHttpResponseReader(); public: - /** - * initialize the response reader with buffer. - */ + // Initialize the response reader with buffer. virtual srs_error_t initialize(SrsFastStream* buffer); - // interface ISrsHttpResponseReader +// interface ISrsHttpResponseReader public: virtual bool eof(); virtual srs_error_t read(char* data, int nb_data, int* nb_read); diff --git a/trunk/src/service/srs_service_log.hpp b/trunk/src/service/srs_service_log.hpp index 127c31637..fc2d49198 100644 --- a/trunk/src/service/srs_service_log.hpp +++ b/trunk/src/service/srs_service_log.hpp @@ -31,10 +31,8 @@ #include #include -/** - * st thread context, get_id will get the st-thread id, - * which identify the client. - */ +// The st thread context, get_id will get the st-thread id, +// which identify the client. class SrsThreadContext : public ISrsThreadContext { private: @@ -50,9 +48,7 @@ public: virtual void clear_cid(); }; -/** - * The basic console log, which write log to console. - */ +// The basic console log, which write log to console. class SrsConsoleLog : public ISrsLog { private: @@ -74,13 +70,11 @@ public: virtual void error(const char* tag, int context_id, const char* fmt, ...); }; -/** - * Generate the log header. - * @param dangerous Whether log is warning or error, log the errno if true. - * @param utc Whether use UTC time format in the log header. - * @param psize Output the actual header size. - * @remark It's a internal API. - */ +// Generate the log header. +// @param dangerous Whether log is warning or error, log the errno if true. +// @param utc Whether use UTC time format in the log header. +// @param psize Output the actual header size. +// @remark It's a internal API. bool srs_log_header(char* buffer, int size, bool utc, bool dangerous, const char* tag, int cid, const char* level, int* psize); #endif diff --git a/trunk/src/service/srs_service_rtmp_conn.hpp b/trunk/src/service/srs_service_rtmp_conn.hpp index 9538ce4d7..105f3fcc2 100644 --- a/trunk/src/service/srs_service_rtmp_conn.hpp +++ b/trunk/src/service/srs_service_rtmp_conn.hpp @@ -37,15 +37,13 @@ class SrsPacket; class SrsKbps; class SrsWallClock; -/** - * The simple RTMP client, provides friendly APIs. - * @remark Should never use client when closed. - * Usage: - * SrsBasicRtmpClient client("rtmp://127.0.0.1:1935/live/livestream", 3000, 9000); - * client.connect(); - * client.play(); - * client.close(); - */ +// The simple RTMP client, provides friendly APIs. +// @remark Should never use client when closed. +// Usage: +// SrsBasicRtmpClient client("rtmp://127.0.0.1:1935/live/livestream", 3000, 9000); +// client.connect(); +// client.play(); +// client.close(); class SrsBasicRtmpClient { private: diff --git a/trunk/src/service/srs_service_st.hpp b/trunk/src/service/srs_service_st.hpp index 87d8bde17..f6843c8ac 100644 --- a/trunk/src/service/srs_service_st.hpp +++ b/trunk/src/service/srs_service_st.hpp @@ -36,10 +36,10 @@ typedef void* srs_thread_t; typedef void* srs_cond_t; typedef void* srs_mutex_t; -// initialize st, requires epoll. +// Initialize st, requires epoll. extern srs_error_t srs_st_init(); -// close the netfd, and close the underlayer fd. +// Close the netfd, and close the underlayer fd. // @remark when close, user must ensure io completed. extern void srs_close_stfd(srs_netfd_t& stfd); @@ -81,9 +81,7 @@ extern srs_netfd_t srs_accept(srs_netfd_t stfd, struct sockaddr *addr, int *addr extern ssize_t srs_read(srs_netfd_t stfd, void *buf, size_t nbyte, srs_utime_t timeout); -/** - * The mutex locker. - */ +// The mutex locker. #define SrsLocker(instance) \ impl__SrsLocker _srs_auto_free_##instance(&instance) @@ -102,10 +100,8 @@ public: } }; -/** - * the socket provides TCP socket over st, - * that is, the sync socket mechanism. - */ +// the socket provides TCP socket over st, +// that is, the sync socket mechanism. class SrsStSocket : public ISrsProtocolReadWriter { private: @@ -133,28 +129,22 @@ public: virtual int64_t get_recv_bytes(); virtual int64_t get_send_bytes(); public: - /** - * @param nread, the actual read bytes, ignore if NULL. - */ + // @param nread, the actual read bytes, ignore if NULL. virtual srs_error_t read(void* buf, size_t size, ssize_t* nread); virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread); - /** - * @param nwrite, the actual write bytes, ignore if NULL. - */ + // @param nwrite, the actual write bytes, ignore if NULL. virtual srs_error_t write(void* buf, size_t size, ssize_t* nwrite); virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t* nwrite); }; -/** - * The client to connect to server over TCP. - * User must never reuse the client when close it. - * Usage: - * SrsTcpClient client("127.0.0.1", 1935, 9 * SRS_UTIME_SECONDS); - * client.connect(); - * client.write("Hello world!", 12, NULL); - * client.read(buf, 4096, NULL); - * @remark User can directly free the object, which will close the fd. - */ +// The client to connect to server over TCP. +// User must never reuse the client when close it. +// Usage: +// SrsTcpClient client("127.0.0.1", 1935, 9// SRS_UTIME_SECONDS); +// client.connect(); +// client.write("Hello world!", 12, NULL); +// client.read(buf, 4096, NULL); +// @remark User can directly free the object, which will close the fd. class SrsTcpClient : public ISrsProtocolReadWriter { private: @@ -166,25 +156,19 @@ private: // The timeout in srs_utime_t. srs_utime_t timeout; public: - /** - * Constructor. - * @param h the ip or hostname of server. - * @param p the port to connect to. - * @param tm the timeout in srs_utime_t. - */ + // Constructor. + // @param h the ip or hostname of server. + // @param p the port to connect to. + // @param tm the timeout in srs_utime_t. SrsTcpClient(std::string h, int p, srs_utime_t tm); virtual ~SrsTcpClient(); public: - /** - * Connect to server over TCP. - * @remark We will close the exists connection before do connect. - */ + // Connect to server over TCP. + // @remark We will close the exists connection before do connect. virtual srs_error_t connect(); private: - /** - * Close the connection to server. - * @remark User should never use the client when close it. - */ + // Close the connection to server. + // @remark User should never use the client when close it. virtual void close(); // interface ISrsProtocolReadWriter public: diff --git a/trunk/src/service/srs_service_utility.hpp b/trunk/src/service/srs_service_utility.hpp index 58db1e001..86a8e85e8 100644 --- a/trunk/src/service/srs_service_utility.hpp +++ b/trunk/src/service/srs_service_utility.hpp @@ -32,17 +32,17 @@ #include -// whether the url is starts with http:// or https:// +// Whether the url is starts with http:// or https:// extern bool srs_string_is_http(std::string url); extern bool srs_string_is_rtmp(std::string url); -// get local ip, fill to @param ips +// Get local ip, fill to @param ips extern std::vector& srs_get_local_ips(); -// get local public ip, empty string if no public internet address found. +// Get local public ip, empty string if no public internet address found. extern std::string srs_get_public_internet_address(); -// detect whether specified device is internet public address. +// Detect whether specified device is internet public address. extern bool srs_net_device_is_internet(std::string ifname); extern bool srs_net_device_is_internet(const sockaddr* addr); From 4d25520f99292cef322f1155a90589b1fec86307 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 28 Apr 2019 08:23:16 +0800 Subject: [PATCH 14/25] Refine typo in service. --- trunk/src/service/srs_service_http_client.hpp | 2 +- trunk/src/service/srs_service_st.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/trunk/src/service/srs_service_http_client.hpp b/trunk/src/service/srs_service_http_client.hpp index 9c07dd817..9781cbced 100644 --- a/trunk/src/service/srs_service_http_client.hpp +++ b/trunk/src/service/srs_service_http_client.hpp @@ -41,7 +41,7 @@ class SrsWallClock; class SrsTcpClient; // The default timeout for http client. -#define SRS_HTTP_CLIENT_TIMEOUT (30// SRS_UTIME_SECONDS) +#define SRS_HTTP_CLIENT_TIMEOUT (30 * SRS_UTIME_SECONDS) // The client to GET/POST/PUT/DELETE over HTTP. // @remark We will reuse the TCP transport until initialize or channel error, diff --git a/trunk/src/service/srs_service_st.hpp b/trunk/src/service/srs_service_st.hpp index f6843c8ac..7c1bcba2c 100644 --- a/trunk/src/service/srs_service_st.hpp +++ b/trunk/src/service/srs_service_st.hpp @@ -140,7 +140,7 @@ public: // The client to connect to server over TCP. // User must never reuse the client when close it. // Usage: -// SrsTcpClient client("127.0.0.1", 1935, 9// SRS_UTIME_SECONDS); +// SrsTcpClient client("127.0.0.1", 1935, 9 * SRS_UTIME_SECONDS); // client.connect(); // client.write("Hello world!", 12, NULL); // client.read(buf, 4096, NULL); From aac8a13f42b4223a8212aa08e7960b4497fa618a Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 28 Apr 2019 09:08:05 +0800 Subject: [PATCH 15/25] Refine typo in app. --- trunk/src/app/srs_app_async_call.hpp | 35 +- trunk/src/app/srs_app_bandwidth.hpp | 218 ++-- trunk/src/app/srs_app_caster_flv.hpp | 23 +- trunk/src/app/srs_app_config.hpp | 1420 +++++++++----------------- trunk/src/app/srs_app_conn.hpp | 86 +- trunk/src/app/srs_app_coworkers.hpp | 1 + trunk/src/app/srs_app_heartbeat.hpp | 5 +- trunk/src/app/srs_app_hls.hpp | 196 ++-- trunk/src/app/srs_app_ingest.hpp | 19 +- trunk/src/app/srs_app_kafka.hpp | 68 +- trunk/src/app/srs_app_server.hpp | 195 ++-- trunk/src/app/srs_app_source.hpp | 396 +++---- trunk/src/app/srs_app_statistic.hpp | 128 +-- trunk/src/app/srs_app_thread.hpp | 14 +- trunk/src/app/srs_app_utility.hpp | 223 ++-- 15 files changed, 1065 insertions(+), 1962 deletions(-) diff --git a/trunk/src/app/srs_app_async_call.hpp b/trunk/src/app/srs_app_async_call.hpp index 61afcc1ac..183533457 100644 --- a/trunk/src/app/srs_app_async_call.hpp +++ b/trunk/src/app/srs_app_async_call.hpp @@ -31,38 +31,29 @@ #include -/** - * the async call for http hooks, - * for the http hooks will switch st-thread, - * so we must use isolate thread to avoid the thread corrupt, - * for example, when dvr call http hooks, the video receive thread got - * a video and pass it to the dvr again. - * futhurmore, the aync call never block the main worker thread. - */ +// The async call for http hooks, for the http hooks will switch st-thread, +// so we must use isolate thread to avoid the thread corrupt, +// for example, when dvr call http hooks, the video receive thread got +// a video and pass it to the dvr again. +// Futhurmore, the aync call never block the main worker thread. class ISrsAsyncCallTask { public: ISrsAsyncCallTask(); virtual ~ISrsAsyncCallTask(); public: - /** - * execute the task async. - * this method is the actual execute method of task, - * for example, to notify callback server. - */ + // Execute the task async. + // This method is the actual execute method of task, + // for example, to notify callback server. virtual srs_error_t call() = 0; - /** - * convert task to string to describe it. - * used for logger. - */ + // Convert task to string to describe it. + // It's used for logger. virtual std::string to_string() = 0; }; -/** - * the async callback for dvr, callback and other async worker. - * when worker call with the task, the worker will do it in isolate thread. - * that is, the task is execute/call in async mode. - */ +// The async callback for dvr, callback and other async worker. +// When worker call with the task, the worker will do it in isolate thread. +// That is, the task is execute/call in async mode. class SrsAsyncCallWorker : public ISrsCoroutineHandler { private: diff --git a/trunk/src/app/srs_app_bandwidth.hpp b/trunk/src/app/srs_app_bandwidth.hpp index 0afdf9e07..af7b232ab 100644 --- a/trunk/src/app/srs_app_bandwidth.hpp +++ b/trunk/src/app/srs_app_bandwidth.hpp @@ -36,85 +36,69 @@ class SrsRtmpServer; class SrsKbpsLimit; class ISrsProtocolStatistic; -/** - * bandwidth check/test sample. - */ +// The bandwidth check/test sample. class SrsBandwidthSample { public: - /** - * the plan, how long to do the test, in ms, - * if exceed the duration, abort the test. - */ + // The plan, how long to do the test, in ms, + // if exceed the duration, abort the test. int duration_ms; - /** - * the plan, interval for each check/test packet, in ms - */ + // The plan, interval for each check/test packet, in ms int interval_ms; public: - /** - * the actual test duration, in ms. - */ + // The actual test duration, in ms. int actual_duration_ms; - /** - * the actual test bytes - */ + // The actual test bytes int bytes; - /** - * the actual test kbps - */ + // The actual test kbps int kbps; public: SrsBandwidthSample(); virtual ~SrsBandwidthSample(); public: - /** - * update the bytes and actual duration, then calc the kbps. - * @param _bytes update the sample bytes. - * @param _duration update the actual duration, in ms. - */ + // Update the bytes and actual duration, then calc the kbps. + // @param _bytes update the sample bytes. + // @param _duration update the actual duration, in ms. virtual void calc_kbps(int _bytes, int _duration); }; -/** - * bandwidth test agent which provides the interfaces for bandwidth check. - * 1. if vhost disabled bandwidth check, ignore. - * 2. otherwise, check the key, error if verify failed. - * 3. check the interval limit, error if bandwidth in the interval window. - * 4. check the bandwidth under the max kbps. - * 5. send the bandwidth data to client. - * bandwidth workflow: - * +------------+ +----------+ - * | Client | | Server | - * +-----+------+ +-----+----+ - * | | - * | connect vhost------> | if vhost enable bandwidth, - * | <-----result(success) | do bandwidth check. - * | | - * | <----call(start play) | onSrsBandCheckStartPlayBytes - * | result(playing)-----> | onSrsBandCheckStartingPlayBytes - * | <-------data(playing) | onSrsBandCheckStartingPlayBytes - * | <-----call(stop play) | onSrsBandCheckStopPlayBytes - * | result(stopped)-----> | onSrsBandCheckStoppedPlayBytes - * | | - * | <-call(start publish) | onSrsBandCheckStartPublishBytes - * | result(publishing)--> | onSrsBandCheckStartingPublishBytes - * | data(publishing)(3)-> | onSrsBandCheckStartingPublishBytes - * | <--call(stop publish) | onSrsBandCheckStopPublishBytes - * | result(stopped)(1)--> | onSrsBandCheckStoppedPublishBytes - * | | - * | <--------------report | - * | final(2)------------> | finalClientPacket - * | | - * - * 1. when flash client, server never wait the stop publish response, - * for the flash client queue is fullfill with other packets. - * 2. when flash client, server never wait the final packet, - * for the flash client directly close when got report packet. - * 3. for linux client, it will send the publish data then send a stop publish, - * for the linux client donot know when to stop the publish. - * when server got publishing and stop publish, stop publish. - */ +// The bandwidth test agent which provides the interfaces for bandwidth check. +// 1. if vhost disabled bandwidth check, ignore. +// 2. otherwise, check the key, error if verify failed. +// 3. check the interval limit, error if bandwidth in the interval window. +// 4. check the bandwidth under the max kbps. +// 5. send the bandwidth data to client. +// bandwidth workflow: +// +------------+ +----------+ +// | Client | | Server | +// +-----+------+ +-----+----+ +// | | +// | connect vhost------> | if vhost enable bandwidth, +// | <-----result(success) | do bandwidth check. +// | | +// | <----call(start play) | onSrsBandCheckStartPlayBytes +// | result(playing)-----> | onSrsBandCheckStartingPlayBytes +// | <-------data(playing) | onSrsBandCheckStartingPlayBytes +// | <-----call(stop play) | onSrsBandCheckStopPlayBytes +// | result(stopped)-----> | onSrsBandCheckStoppedPlayBytes +// | | +// | <-call(start publish) | onSrsBandCheckStartPublishBytes +// | result(publishing)--> | onSrsBandCheckStartingPublishBytes +// | data(publishing)(3)-> | onSrsBandCheckStartingPublishBytes +// | <--call(stop publish) | onSrsBandCheckStopPublishBytes +// | result(stopped)(1)--> | onSrsBandCheckStoppedPublishBytes +// | | +// | <--------------report | +// | final(2)------------> | finalClientPacket +// | | +// +// 1. when flash client, server never wait the stop publish response, +// for the flash client queue is fullfill with other packets. +// 2. when flash client, server never wait the final packet, +// for the flash client directly close when got report packet. +// 3. for linux client, it will send the publish data then send a stop publish, +// for the linux client donot know when to stop the publish. +// when server got publishing and stop publish, stop publish. class SrsBandwidth { private: @@ -124,81 +108,61 @@ public: SrsBandwidth(); virtual ~SrsBandwidth(); public: - /** - * do the bandwidth check. - * @param rtmp, server RTMP protocol object, send/recv RTMP packet to/from client. - * @param io_stat, the underlayer io statistic, provides send/recv bytes count. - * @param req, client request object, specifies the request info from client. - * @param local_ip, the ip of server which client connected at - */ + // Do the bandwidth check. + // @param rtmp, server RTMP protocol object, send/recv RTMP packet to/from client. + // @param io_stat, the underlayer io statistic, provides send/recv bytes count. + // @param req, client request object, specifies the request info from client. + // @param local_ip, the ip of server which client connected at virtual srs_error_t bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io_stat, SrsRequest* req, std::string local_ip); private: - /** - * used to process band width check from client. - * @param limit, the bandwidth limit object, to slowdown if exceed the kbps. - */ + // Used to process band width check from client. + // @param limit, the bandwidth limit object, to slowdown if exceed the kbps. virtual srs_error_t do_bandwidth_check(SrsKbpsLimit* limit); // play check/test, downloading bandwidth kbps. private: - /** - * start play/download bandwidth check/test, - * send start-play command to client, client must response starting-play - * to start the test. - */ + // Start play/download bandwidth check/test, + // send start-play command to client, client must response starting-play + // to start the test. virtual srs_error_t play_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit); - /** - * do play/download bandwidth check/test, - * server send call messages to client in specified time, - * calc the time and bytes sent, then we got the kbps. - */ + // Do play/download bandwidth check/test, + // server send call messages to client in specified time, + // calc the time and bytes sent, then we got the kbps. virtual srs_error_t play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit); - /** - * stop play/download bandwidth check/test, - * send stop-play command to client, client must response stopped-play - * to stop the test. - */ + // stop play/download bandwidth check/test, + // send stop-play command to client, client must response stopped-play + // to stop the test. virtual srs_error_t play_stop(SrsBandwidthSample* sample, SrsKbpsLimit* limit); // publish check/test, publishing bandwidth kbps. private: - /** - * start publish/upload bandwidth check/test, - * send start-publish command to client, client must response starting-publish - * to start the test. - */ + // Start publish/upload bandwidth check/test, + // send start-publish command to client, client must response starting-publish + // to start the test. virtual srs_error_t publish_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit); - /** - * do publish/upload bandwidth check/test, - * client send call messages to client in specified time, - * server calc the time and bytes received, then we got the kbps. - * @remark, for linux client, it will send a stop publish client, server will stop publishing. - * then enter the publish-stop stage with client. - * @remark, for flash client, it will send many many call messages, that is, - * the send queue is fullfill with call messages, so we should never expect the - * response message in the publish-stop stage. - */ + // Do publish/upload bandwidth check/test, + // client send call messages to client in specified time, + // server calc the time and bytes received, then we got the kbps. + // @remark, for linux client, it will send a stop publish client, server will stop publishing. + // then enter the publish-stop stage with client. + // @remark, for flash client, it will send many many call messages, that is, + // the send queue is fullfill with call messages, so we should never expect the + // response message in the publish-stop stage. virtual srs_error_t publish_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit); - /** - * stop publish/upload bandwidth check/test, - * send stop-publish command to client, - * for linux client, always expect a stopped-publish response from client, - * for flash client, the sent queue is fullfill with publishing call messages, - * so server never expect the stopped-publish from it. - */ + // Stop publish/upload bandwidth check/test, + // send stop-publish command to client, + // for linux client, always expect a stopped-publish response from client, + // for flash client, the sent queue is fullfill with publishing call messages, + // so server never expect the stopped-publish from it. virtual srs_error_t publish_stop(SrsBandwidthSample* sample, SrsKbpsLimit* limit); private: - /** - * report and final packet - * report a finish packet, with the bytes/time/kbps bandwidth check/test result, - * for linux client, server always expect a final packet from client, - * for flash client, the sent queue is fullfill with publishing call messages, - * so server never expect the final packet from it. - */ + // Report and final packet + // report a finish packet, with the bytes/time/kbps bandwidth check/test result, + // for linux client, server always expect a final packet from client, + // for flash client, the sent queue is fullfill with publishing call messages, + // so server never expect the final packet from it. virtual srs_error_t do_final(SrsBandwidthSample& play_sample, SrsBandwidthSample& publish_sample, srs_utime_t start_time, srs_utime_t& end_time); }; -/** - * the kbps limit, if exceed the kbps, slow down. - */ +// The kbps limit, if exceed the kbps, slow down. class SrsKbpsLimit { private: @@ -208,17 +172,11 @@ public: SrsKbpsLimit(SrsKbps* kbps, int limit_kbps); virtual ~SrsKbpsLimit(); public: - /** - * get the system limit kbps. - */ + // Get the system limit kbps. virtual int limit_kbps(); - /** - * limit the recv bandwidth. - */ + // Limit the recv bandwidth. virtual void recv_limit(); - /** - * limit the send bandwidth. - */ + // Limit the send bandwidth. virtual void send_limit(); }; diff --git a/trunk/src/app/srs_app_caster_flv.hpp b/trunk/src/app/srs_app_caster_flv.hpp index 3e3d44f7c..8305d86c5 100644 --- a/trunk/src/app/srs_app_caster_flv.hpp +++ b/trunk/src/app/srs_app_caster_flv.hpp @@ -46,9 +46,7 @@ class SrsSimpleRtmpClient; #include #include -/** - * the stream caster for flv stream over HTTP POST. - */ +// The stream caster for flv stream over HTTP POST. class SrsAppCasterFlv : virtual public ISrsTcpHandler , virtual public IConnectionManager, virtual public ISrsHttpHandler { @@ -62,20 +60,18 @@ public: virtual ~SrsAppCasterFlv(); public: virtual srs_error_t initialize(); -// ISrsTcpHandler +// interface ISrsTcpHandler public: virtual srs_error_t on_tcp_client(srs_netfd_t stfd); -// IConnectionManager +// interface IConnectionManager public: virtual void remove(ISrsConnection* c); -// ISrsHttpHandler +// interface ISrsHttpHandler public: virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); }; -/** - * the dynamic http connection, never drop the body. - */ +// The dynamic http connection, never drop the body. class SrsDynamicHttpConn : public SrsHttpConn { private: @@ -93,10 +89,7 @@ private: virtual srs_error_t do_proxy(ISrsHttpResponseReader* rr, SrsFlvDecoder* dec); }; -/** - * the http wrapper for file reader, - * to read http post stream like a file. - */ +// The http wrapper for file reader, to read http post stream like a file. class SrsHttpFileReader : public SrsFileReader { private: @@ -105,9 +98,7 @@ public: SrsHttpFileReader(ISrsHttpResponseReader* h); virtual ~SrsHttpFileReader(); public: - /** - * open file reader, can open then close then open... - */ + // Open file reader, can open then close then open... virtual srs_error_t open(std::string file); virtual void close(); public: diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index be985a00a..6d52eb18e 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -49,47 +49,37 @@ class SrsConfDirective; namespace _srs_internal { - /** - * the buffer of config content. - */ + // The buffer of config content. class SrsConfigBuffer { protected: - // last available position. + // The last available position. char* last; - // end of buffer. + // The end of buffer. char* end; - // start of buffer. + // The start of buffer. char* start; public: - // current consumed position. + // Current consumed position. char* pos; - // current parsed line. + // Current parsed line. int line; public: SrsConfigBuffer(); virtual ~SrsConfigBuffer(); public: - /** - * fullfill the buffer with content of file specified by filename. - */ + // Fullfill the buffer with content of file specified by filename. virtual srs_error_t fullfill(const char* filename); - /** - * whether buffer is empty. - */ + // Whether buffer is empty. virtual bool empty(); }; }; -/** - * deep compare directive. - */ +// Deep compare directive. extern bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b); extern bool srs_directive_equals(SrsConfDirective* a, SrsConfDirective* b, std::string except); -/** - * helper utilities, used for compare the consts values. - */ +// The helper utilities, used for compare the consts values. extern bool srs_config_hls_is_on_error_ignore(std::string strategy); extern bool srs_config_hls_is_on_error_continue(std::string strategy); extern bool srs_config_ingest_is_file(std::string type); @@ -99,415 +89,277 @@ extern bool srs_config_dvr_is_plan_session(std::string plan); extern bool srs_stream_caster_is_udp(std::string caster); extern bool srs_stream_caster_is_rtsp(std::string caster); extern bool srs_stream_caster_is_flv(std::string caster); -// whether the dvr_apply active the stream specified by req. +// Whether the dvr_apply active the stream specified by req. extern bool srs_config_apply_filter(SrsConfDirective* dvr_apply, SrsRequest* req); -/** - * convert bool in str to on/off - */ +// Convert bool in str to on/off extern std::string srs_config_bool2switch(const std::string& sbool); -/** - * parse loaded vhost directives to compatible mode. - * for exmaple, SRS1/2 use the follow refer style: - * refer a.domain.com b.domain.com; - * while SRS3 use the following: - * refer { - * enabled on; - * all a.domain.com b.domain.com; - * } - * so we must transform the vhost directive anytime load the config. - * @param root the root directive to transform, in and out parameter. - */ +// Parse loaded vhost directives to compatible mode. +// For exmaple, SRS1/2 use the follow refer style: +// refer a.domain.com b.domain.com; +// while SRS3 use the following: +// refer { +// enabled on; +// all a.domain.com b.domain.com; +// } +// so we must transform the vhost directive anytime load the config. +// @param root the root directive to transform, in and out parameter. extern srs_error_t srs_config_transform_vhost(SrsConfDirective* root); // @global config object. extern SrsConfig* _srs_config; -/** - * the config directive. - * the config file is a group of directives, - * all directive has name, args and child-directives. - * for example, the following config text: - vhost vhost.ossrs.net { - enabled on; - ingest livestream { - enabled on; - ffmpeg /bin/ffmpeg; - } - } - * will be parsed to: - * SrsConfDirective: name="vhost", arg0="vhost.ossrs.net", child-directives=[ - * SrsConfDirective: name="enabled", arg0="on", child-directives=[] - * SrsConfDirective: name="ingest", arg0="livestream", child-directives=[ - * SrsConfDirective: name="enabled", arg0="on", child-directives=[] - * SrsConfDirective: name="ffmpeg", arg0="/bin/ffmpeg", child-directives=[] - * ] - * ] - * @remark, allow empty directive, for example: "dir0 {}" - * @remark, don't allow empty name, for example: ";" or "{dir0 arg0;} - */ +// The config directive. +// The config file is a group of directives, +// all directive has name, args and child-directives. +// For example, the following config text: +// vhost vhost.ossrs.net { +// enabled on; +// ingest livestream { +// enabled on; +// ffmpeg /bin/ffmpeg; +// } +// } +// will be parsed to: +// SrsConfDirective: name="vhost", arg0="vhost.ossrs.net", child-directives=[ +// SrsConfDirective: name="enabled", arg0="on", child-directives=[] +// SrsConfDirective: name="ingest", arg0="livestream", child-directives=[ +// SrsConfDirective: name="enabled", arg0="on", child-directives=[] +// SrsConfDirective: name="ffmpeg", arg0="/bin/ffmpeg", child-directives=[] +// ] +// ] +// @remark, allow empty directive, for example: "dir0 {}" +// @remark, don't allow empty name, for example: ";" or "{dir0 arg0;} class SrsConfDirective { public: - /** - * the line of config file in which the directive from - */ + // The line of config file in which the directive from int conf_line; - /** - * the name of directive, for example, the following config text: - * enabled on; - * will be parsed to a directive, its name is "enalbed" - */ + // The name of directive, for example, the following config text: + // enabled on; + // will be parsed to a directive, its name is "enalbed" std::string name; - /** - * the args of directive, for example, the following config text: - * listen 1935 1936; - * will be parsed to a directive, its args is ["1935", "1936"]. - */ + // The args of directive, for example, the following config text: + // listen 1935 1936; + // will be parsed to a directive, its args is ["1935", "1936"]. std::vector args; - /** - * the child directives, for example, the following config text: - * vhost vhost.ossrs.net { - * enabled on; - * } - * will be parsed to a directive, its directives is a vector contains - * a directive, which is: - * name:"enalbed", args:["on"], directives:[] - * - * @remark, the directives can contains directives. - */ + // The child directives, for example, the following config text: + // vhost vhost.ossrs.net { + // enabled on; + // } + // will be parsed to a directive, its directives is a vector contains + // a directive, which is: + // name:"enalbed", args:["on"], directives:[] + // + // @remark, the directives can contains directives. std::vector directives; public: SrsConfDirective(); virtual ~SrsConfDirective(); public: - /** - * deep copy the directive, for SrsConfig to use it to support reload in upyun cluster, - * for when reload the upyun dynamic config, the root will be changed, - * so need to copy it to an old root directive, and use the copy result to do reload. - */ + // Deep copy the directive, for SrsConfig to use it to support reload in upyun cluster, + // For when reload the upyun dynamic config, the root will be changed, + // so need to copy it to an old root directive, and use the copy result to do reload. virtual SrsConfDirective* copy(); // @param except the name of sub directive. virtual SrsConfDirective* copy(std::string except); // args public: - /** - * get the args0,1,2, if user want to get more args, - * directly use the args.at(index). - */ + // Get the args0,1,2, if user want to get more args, + // directly use the args.at(index). virtual std::string arg0(); virtual std::string arg1(); virtual std::string arg2(); virtual std::string arg3(); // directives public: - /** - * get the directive by index. - * @remark, assert the index& args, int& line_start); }; -/** - * the config service provider. - * for the config supports reload, so never keep the reference cross st-thread, - * that is, never save the SrsConfDirective* get by any api of config, - * for it maybe free in the reload st-thread cycle. - * you can keep it before st-thread switch, or simply never keep it. - */ +// The config service provider. +// For the config supports reload, so never keep the reference cross st-thread, +// that is, never save the SrsConfDirective* get by any api of config, +// For it maybe free in the reload st-thread cycle. +// You could keep it before st-thread switch, or simply never keep it. class SrsConfig { // user command private: - /** - * whether srs is run in dolphin mode. - * @see https://github.com/ossrs/srs-dolphin - */ + // Whether srs is run in dolphin mode. + // @see https://github.com/ossrs/srs-dolphin bool dolphin; std::string dolphin_rtmp_port; std::string dolphin_http_port; - /** - * whether show help and exit. - */ + // Whether show help and exit. bool show_help; - /** - * whether test config file and exit. - */ + // Whether test config file and exit. bool test_conf; - /** - * whether show SRS version and exit. - */ + // Whether show SRS version and exit. bool show_version; - /** - * whether show SRS signature and exit. - */ + // Whether show SRS signature and exit. bool show_signature; // global env variables. private: - /** - * the user parameters, the argc and argv. - * the argv is " ".join(argv), where argv is from main(argc, argv). - */ + // The user parameters, the argc and argv. + // The argv is " ".join(argv), where argv is from main(argc, argv). std::string _argv; - /** - * current working directory. - */ + // current working directory. std::string _cwd; - // config section + // Config section private: - /** - * the last parsed config file. - * if reload, reload the config file. - */ + // The last parsed config file. + // If reload, reload the config file. std::string config_file; protected: - /** - * the directive root. - */ + // The directive root. SrsConfDirective* root; -// reload section +// Reload section private: - /** - * the reload subscribers, when reload, callback all handlers. - */ + // The reload subscribers, when reload, callback all handlers. std::vector subscribes; public: SrsConfig(); virtual ~SrsConfig(); // dolphin public: - /** - * whether srs is in dolphin mode. - */ + // Whether srs is in dolphin mode. virtual bool is_dolphin(); private: virtual void set_config_directive(SrsConfDirective* parent, std::string dir, std::string value); -// reload +// Reload public: - /** - * for reload handler to register itself, - * when config service do the reload, callback the handler. - */ + // For reload handler to register itself, + // when config service do the reload, callback the handler. virtual void subscribe(ISrsReloadHandler* handler); - /** - * for reload handler to unregister itself. - */ + // For reload handler to unregister itself. virtual void unsubscribe(ISrsReloadHandler* handler); - /** - * reload the config file. - * @remark, user can test the config before reload it. - */ + // Reload the config file. + // @remark, user can test the config before reload it. virtual srs_error_t reload(); private: - /** - * reload the vhost section of config. - */ + // Reload the vhost section of config. virtual srs_error_t reload_vhost(SrsConfDirective* old_root); protected: - /** - * reload from the config. - * @remark, use protected for the utest to override with mock. - */ + // Reload from the config. + // @remark, use protected for the utest to override with mock. virtual srs_error_t reload_conf(SrsConfig* conf); private: - /** - * reload the http_api section of config. - */ + // Reload the http_api section of config. virtual srs_error_t reload_http_api(SrsConfDirective* old_root); - /** - * reload the http_stream section of config. - */ + // Reload the http_stream section of config. // TODO: FIXME: rename to http_server. virtual srs_error_t reload_http_stream(SrsConfDirective* old_root); - /** - * reload the transcode section of vhost of config. - */ + // Reload the transcode section of vhost of config. virtual srs_error_t reload_transcode(SrsConfDirective* new_vhost, SrsConfDirective* old_vhost); - /** - * reload the ingest section of vhost of config. - */ + // Reload the ingest section of vhost of config. virtual srs_error_t reload_ingest(SrsConfDirective* new_vhost, SrsConfDirective* old_vhost); - // parse options and file +// Parse options and file public: - /** - * parse the cli, the main(argc,argv) function. - */ + // Parse the cli, the main(argc,argv) function. virtual srs_error_t parse_options(int argc, char** argv); - /** - * initialize the cwd for server, - * because we may change the workdir. - */ + // initialize the cwd for server, + // because we may change the workdir. virtual srs_error_t initialize_cwd(); - /** - * persistence current config to file. - */ + // Marshal current config to file. virtual srs_error_t persistence(); private: virtual srs_error_t do_persistence(SrsFileWriter* fw); public: - /** - * dumps the global sections to json. - */ + // Dumps the global sections to json. virtual srs_error_t global_to_json(SrsJsonObject* obj); - /** - * dumps the minimal sections to json. - */ + // Dumps the minimal sections to json. virtual srs_error_t minimal_to_json(SrsJsonObject* obj); - /** - * dumps the vhost section to json. - */ + // Dumps the vhost section to json. virtual srs_error_t vhost_to_json(SrsConfDirective* vhost, SrsJsonObject* obj); - /** - * dumps the http_api sections to json for raw api info. - */ + // Dumps the http_api sections to json for raw api info. virtual srs_error_t raw_to_json(SrsJsonObject* obj); - /** - * raw set the global listen. - */ + // RAW set the global listen. virtual srs_error_t raw_set_listen(const std::vector& eps, bool& applied); - /** - * raw set the global pid. - */ + // RAW set the global pid. virtual srs_error_t raw_set_pid(std::string pid, bool& applied); - /** - * raw set the global chunk size. - */ + // RAW set the global chunk size. virtual srs_error_t raw_set_chunk_size(std::string chunk_size, bool& applied); - /** - * raw set the global ffmpeg log dir. - */ + // RAW set the global ffmpeg log dir. virtual srs_error_t raw_set_ff_log_dir(std::string ff_log_dir, bool& applied); - /** - * raw set the global log tank. - */ + // RAW set the global log tank. virtual srs_error_t raw_set_srs_log_tank(std::string srs_log_tank, bool& applied); - /** - * raw set the global log level. - */ + // RAW set the global log level. virtual srs_error_t raw_set_srs_log_level(std::string srs_log_level, bool& applied); - /** - * raw set the global log file path for file tank. - */ + // RAW set the global log file path for file tank. virtual srs_error_t raw_set_srs_log_file(std::string srs_log_file, bool& applied); - /** - * raw set the global max connections of srs. - */ + // RAW set the global max connections of srs. virtual srs_error_t raw_set_max_connections(std::string max_connections, bool& applied); - /** - * raw set the global whether use utc time. - */ + // RAW set the global whether use utc time. virtual srs_error_t raw_set_utc_time(std::string utc_time, bool& applied); - /** - * raw set the global pithy print interval in ms. - */ + // RAW set the global pithy print interval in ms. virtual srs_error_t raw_set_pithy_print_ms(std::string pithy_print_ms, bool& applied); - /** - * raw create the new vhost. - */ + // RAW create the new vhost. virtual srs_error_t raw_create_vhost(std::string vhost, bool& applied); - /** - * raw update the disabled vhost name. - */ + // RAW update the disabled vhost name. virtual srs_error_t raw_update_vhost(std::string vhost, std::string name, bool& applied); - /** - * raw delete the disabled vhost. - */ + // RAW delete the disabled vhost. virtual srs_error_t raw_delete_vhost(std::string vhost, bool& applied); - /** - * raw disable the enabled vhost. - */ + // RAW disable the enabled vhost. virtual srs_error_t raw_disable_vhost(std::string vhost, bool& applied); - /** - * raw enable the disabled vhost. - */ + // RAW enable the disabled vhost. virtual srs_error_t raw_enable_vhost(std::string vhost, bool& applied); - /** - * raw enable the dvr of stream of vhost. - */ + // RAW enable the dvr of stream of vhost. virtual srs_error_t raw_enable_dvr(std::string vhost, std::string stream, bool& applied); - /** - * raw disable the dvr of stream of vhost. - */ + // RAW disable the dvr of stream of vhost. virtual srs_error_t raw_disable_dvr(std::string vhost, std::string stream, bool& applied); private: virtual srs_error_t do_reload_listen(); @@ -522,627 +374,393 @@ private: virtual srs_error_t do_reload_vhost_removed(std::string vhost); virtual srs_error_t do_reload_vhost_dvr_apply(std::string vhost); public: - /** - * get the config file path. - */ + // Get the config file path. virtual std::string config(); private: - /** - * parse each argv. - */ + // Parse each argv. virtual srs_error_t parse_argv(int& i, char** argv); - /** - * print help and exit. - */ + // Print help and exit. virtual void print_help(char** argv); public: - /** - * parse the config file, which is specified by cli. - */ + // Parse the config file, which is specified by cli. virtual srs_error_t parse_file(const char* filename); - /** - * check the parsed config. - */ + // Check the parsed config. virtual srs_error_t check_config(); protected: virtual srs_error_t check_normal_config(); virtual srs_error_t check_number_connections(); protected: - /** - * parse config from the buffer. - * @param buffer, the config buffer, user must delete it. - * @remark, use protected for the utest to override with mock. - */ + // Parse config from the buffer. + // @param buffer, the config buffer, user must delete it. + // @remark, use protected for the utest to override with mock. virtual srs_error_t parse_buffer(_srs_internal::SrsConfigBuffer* buffer); // global env public: - /** - * get the current work directory. - */ + // Get the current work directory. virtual std::string cwd(); - /** - * get the cli, the main(argc,argv), program start command. - */ + // Get the cli, the main(argc,argv), program start command. virtual std::string argv(); // global section public: - /** - * get the directive root, corresponding to the config file. - * the root directive, no name and args, contains directives. - * all directive parsed can retrieve from root. - */ + // Get the directive root, corresponding to the config file. + // The root directive, no name and args, contains directives. + // All directive parsed can retrieve from root. virtual SrsConfDirective* get_root(); - /** - * get the deamon config. - * if true, SRS will run in deamon mode, fork and fork to reap the - * grand-child process to init process. - */ + // Get the deamon config. + // If true, SRS will run in deamon mode, fork and fork to reap the + // grand-child process to init process. virtual bool get_deamon(); - /** - * get the max connections limit of system. - * if exceed the max connection, SRS will disconnect the connection. - * @remark, linux will limit the connections of each process, - * for example, when you need SRS to service 10000+ connections, - * user must use "ulimit -HSn 10000" and config the max connections - * of SRS. - */ + // Get the max connections limit of system. + // If exceed the max connection, SRS will disconnect the connection. + // @remark, linux will limit the connections of each process, + // for example, when you need SRS to service 10000+ connections, + // user must use "ulimit -HSn 10000" and config the max connections + // of SRS. virtual int get_max_connections(); - /** - * get the listen port of SRS. - * user can specifies multiple listen ports, - * each args of directive is a listen port. - */ + // Get the listen port of SRS. + // user can specifies multiple listen ports, + // each args of directive is a listen port. virtual std::vector get_listens(); - /** - * get the pid file path. - * the pid file is used to save the pid of SRS, - * use file lock to prevent multiple SRS starting. - * @remark, if user need to run multiple SRS instance, - * for example, to start multiple SRS for multiple CPUs, - * user can use different pid file for each process. - */ + // Get the pid file path. + // The pid file is used to save the pid of SRS, + // use file lock to prevent multiple SRS starting. + // @remark, if user need to run multiple SRS instance, + // for example, to start multiple SRS for multiple CPUs, + // user can use different pid file for each process. virtual std::string get_pid_file(); - /** - * get pithy print pulse in srs_utime_t, - * for example, all rtmp connections only print one message - * every this interval in ms. - */ + // Get pithy print pulse in srs_utime_t, + // For example, all rtmp connections only print one message + // every this interval in ms. virtual srs_utime_t get_pithy_print(); - /** - * whether use utc-time to format the time. - */ + // Whether use utc-time to format the time. virtual bool get_utc_time(); - /** - * get the configed work dir. - * ignore if empty string. - */ + // Get the configed work dir. + // ignore if empty string. virtual std::string get_work_dir(); - // whether use asprocess mode. + // Whether use asprocess mode. virtual bool get_asprocess(); // stream_caster section public: - /** - * get all stream_caster in config file. - */ + // Get all stream_caster in config file. virtual std::vector get_stream_casters(); - /** - * get whether the specified stream_caster is enabled. - */ + // Get whether the specified stream_caster is enabled. virtual bool get_stream_caster_enabled(SrsConfDirective* conf); - /** - * get the engine of stream_caster, the caster config. - */ + // Get the engine of stream_caster, the caster config. virtual std::string get_stream_caster_engine(SrsConfDirective* conf); - /** - * get the output rtmp url of stream_caster, the output config. - */ + // Get the output rtmp url of stream_caster, the output config. virtual std::string get_stream_caster_output(SrsConfDirective* conf); - /** - * get the listen port of stream caster. - */ + // Get the listen port of stream caster. virtual int get_stream_caster_listen(SrsConfDirective* conf); - /** - * get the min udp port for rtp of stream caster rtsp. - */ + // Get the min udp port for rtp of stream caster rtsp. virtual int get_stream_caster_rtp_port_min(SrsConfDirective* conf); - /** - * get the max udp port for rtp of stream caster rtsp. - */ + // Get the max udp port for rtp of stream caster rtsp. virtual int get_stream_caster_rtp_port_max(SrsConfDirective* conf); // kafka section. public: - /** - * whether the kafka enabled. - */ + // Whether the kafka enabled. virtual bool get_kafka_enabled(); - /** - * get the broker list, each is format in . - */ + // Get the broker list, each is format in . virtual SrsConfDirective* get_kafka_brokers(); - /** - * get the kafka topic to use for srs. - */ + // Get the kafka topic to use for srs. virtual std::string get_kafka_topic(); // vhost specified section public: - /** - * get the vhost directive by vhost name. - * @param vhost, the name of vhost to get. - * @param try_default_vhost whether try default when get specified vhost failed. - */ + // Get the vhost directive by vhost name. + // @param vhost, the name of vhost to get. + // @param try_default_vhost whether try default when get specified vhost failed. virtual SrsConfDirective* get_vhost(std::string vhost, bool try_default_vhost = true); - /** - * get all vhosts in config file. - */ + // Get all vhosts in config file. virtual void get_vhosts(std::vector& vhosts); - /** - * whether vhost is enabled - * @param vhost, the vhost name. - * @return true when vhost is ok; otherwise, false. - */ + // Whether vhost is enabled + // @param vhost, the vhost name. + // @return true when vhost is ok; otherwise, false. virtual bool get_vhost_enabled(std::string vhost); - /** - * whether vhost is enabled - * @param vhost, the vhost directive. - * @return true when vhost is ok; otherwise, false. - */ + // Whether vhost is enabled + // @param vhost, the vhost directive. + // @return true when vhost is ok; otherwise, false. virtual bool get_vhost_enabled(SrsConfDirective* conf); - /** - * whether gop_cache is enabled of vhost. - * gop_cache used to cache last gop, for client to fast startup. - * @return true when gop_cache is ok; otherwise, false. - * @remark, default true. - */ + // Whether gop_cache is enabled of vhost. + // gop_cache used to cache last gop, for client to fast startup. + // @return true when gop_cache is ok; otherwise, false. + // @remark, default true. virtual bool get_gop_cache(std::string vhost); - /** - * whether debug_srs_upnode is enabled of vhost. - * debug_srs_upnode is very important feature for tracable log, - * but some server, for instance, flussonic donot support it. - * @see https://github.com/ossrs/srs/issues/160 - * @return true when debug_srs_upnode is ok; otherwise, false. - * @remark, default true. - */ + // Whether debug_srs_upnode is enabled of vhost. + // debug_srs_upnode is very important feature for tracable log, + // but some server, for instance, flussonic donot support it. + // @see https://github.com/ossrs/srs/issues/160 + // @return true when debug_srs_upnode is ok; otherwise, false. + // @remark, default true. virtual bool get_debug_srs_upnode(std::string vhost); - /** - * whether atc is enabled of vhost. - * atc always use encoder timestamp, SRS never adjust the time. - * @return true when atc is ok; otherwise, false. - * @remark, default false. - */ + // Whether atc is enabled of vhost. + // atc always use encoder timestamp, SRS never adjust the time. + // @return true when atc is ok; otherwise, false. + // @remark, default false. virtual bool get_atc(std::string vhost); - /** - * whether atc_auto is enabled of vhost. - * atc_auto used to auto enable atc, when metadata specified the bravo_atc. - * @return true when atc_auto is ok; otherwise, false. - * @remark, default true. - */ + // Whether atc_auto is enabled of vhost. + // atc_auto used to auto enable atc, when metadata specified the bravo_atc. + // @return true when atc_auto is ok; otherwise, false. + // @remark, default true. virtual bool get_atc_auto(std::string vhost); - /** - * get the time_jitter algorithm. - * @return the time_jitter algorithm, defined in SrsRtmpJitterAlgorithm. - * @remark, default full. - */ + // Get the time_jitter algorithm. + // @return the time_jitter algorithm, defined in SrsRtmpJitterAlgorithm. + // @remark, default full. virtual int get_time_jitter(std::string vhost); - /** - * whether use mix correct algorithm to ensure the timestamp - * monotonically increase. - */ + // Whether use mix correct algorithm to ensure the timestamp + // monotonically increase. virtual bool get_mix_correct(std::string vhost); - /** - * get the cache queue length, in srs_utime_t. - * when exceed the queue length, drop packet util I frame. - * @remark, default 10s. - */ + // Get the cache queue length, in srs_utime_t. + // when exceed the queue length, drop packet util I frame. + // @remark, default 10s. virtual srs_utime_t get_queue_length(std::string vhost); - /** - * whether the refer hotlink-denial enabled. - */ + // Whether the refer hotlink-denial enabled. virtual bool get_refer_enabled(std::string vhost); - /** - * get the refer hotlink-denial for all type. - * @return the refer, NULL for not configed. - */ + // Get the refer hotlink-denial for all type. + // @return the refer, NULL for not configed. virtual SrsConfDirective* get_refer_all(std::string vhost); - /** - * get the refer hotlink-denial for play. - * @return the refer, NULL for not configed. - */ + // Get the refer hotlink-denial for play. + // @return the refer, NULL for not configed. virtual SrsConfDirective* get_refer_play(std::string vhost); - /** - * get the refer hotlink-denial for publish. - * @return the refer, NULL for not configed. - */ + // Get the refer hotlink-denial for publish. + // @return the refer, NULL for not configed. virtual SrsConfDirective* get_refer_publish(std::string vhost); // Get the input default ack size, which is generally set by message from peer. virtual int get_in_ack_size(std::string vhost); // Get the output default ack size, to notify the peer to send acknowledge to server. virtual int get_out_ack_size(std::string vhost); - /** - * get the chunk size of vhost. - * @param vhost, the vhost to get the chunk size. use global if not specified. - * empty string to get the global. - * @remark, default 60000. - */ + // Get the chunk size of vhost. + // @param vhost, the vhost to get the chunk size. use global if not specified. + // empty string to get the global. + // @remark, default 60000. virtual int get_chunk_size(std::string vhost); - /** - * whether parse the sps when publish stream to SRS. - */ + // Whether parse the sps when publish stream to SRS. virtual bool get_parse_sps(std::string vhost); - /** - * whether mr is enabled for vhost. - * @param vhost, the vhost to get the mr. - */ + // Whether mr is enabled for vhost. + // @param vhost, the vhost to get the mr. virtual bool get_mr_enabled(std::string vhost); - /** - * get the mr sleep time in srs_utime_t for vhost. - * @param vhost, the vhost to get the mr sleep time. - */ + // Get the mr sleep time in srs_utime_t for vhost. + // @param vhost, the vhost to get the mr sleep time. // TODO: FIXME: add utest for mr config. virtual srs_utime_t get_mr_sleep(std::string vhost); - /** - * get the mw sleep time in srs_utime_t for vhost. - * @param vhost, the vhost to get the mw sleep time. - */ + // Get the mw sleep time in srs_utime_t for vhost. + // @param vhost, the vhost to get the mw sleep time. // TODO: FIXME: add utest for mw config. virtual srs_utime_t get_mw_sleep(std::string vhost); - /** - * whether min latency mode enabled. - * @param vhost, the vhost to get the min_latency. - */ + // Whether min latency mode enabled. + // @param vhost, the vhost to get the min_latency. // TODO: FIXME: add utest for min_latency. virtual bool get_realtime_enabled(std::string vhost); - /** - * whether enable tcp nodelay for all clients of vhost. - */ + // Whether enable tcp nodelay for all clients of vhost. virtual bool get_tcp_nodelay(std::string vhost); - /** - * the minimal send interval in srs_utime_t. - */ + // The minimal send interval in srs_utime_t. virtual srs_utime_t get_send_min_interval(std::string vhost); - /** - * whether reduce the sequence header. - */ + // Whether reduce the sequence header. virtual bool get_reduce_sequence_header(std::string vhost); - /** - * the 1st packet timeout in srs_utime_t for encoder. - */ + // The 1st packet timeout in srs_utime_t for encoder. virtual srs_utime_t get_publish_1stpkt_timeout(std::string vhost); - /** - * the normal packet timeout in srs_utime_t for encoder. - */ + // The normal packet timeout in srs_utime_t for encoder. virtual srs_utime_t get_publish_normal_timeout(std::string vhost); private: - /** - * get the global chunk size. - */ + // Get the global chunk size. virtual int get_global_chunk_size(); // forward section public: - /** - * whether the forwarder enabled. - */ + // Whether the forwarder enabled. virtual bool get_forward_enabled(std::string vhost); - /** - * get the forward directive of vhost. - */ + // Get the forward directive of vhost. virtual SrsConfDirective* get_forwards(std::string vhost); // http_hooks section private: - /** - * get the http_hooks directive of vhost. - */ + // Get the http_hooks directive of vhost. virtual SrsConfDirective* get_vhost_http_hooks(std::string vhost); public: - /** - * whether vhost http-hooks enabled. - * @remark, if not enabled, donot callback all http hooks. - */ + // Whether vhost http-hooks enabled. + // @remark, if not enabled, donot callback all http hooks. virtual bool get_vhost_http_hooks_enabled(std::string vhost); - /** - * get the on_connect callbacks of vhost. - * @return the on_connect callback directive, the args is the url to callback. - */ + // Get the on_connect callbacks of vhost. + // @return the on_connect callback directive, the args is the url to callback. virtual SrsConfDirective* get_vhost_on_connect(std::string vhost); - /** - * get the on_close callbacks of vhost. - * @return the on_close callback directive, the args is the url to callback. - */ + // Get the on_close callbacks of vhost. + // @return the on_close callback directive, the args is the url to callback. virtual SrsConfDirective* get_vhost_on_close(std::string vhost); - /** - * get the on_publish callbacks of vhost. - * @return the on_publish callback directive, the args is the url to callback. - */ + // Get the on_publish callbacks of vhost. + // @return the on_publish callback directive, the args is the url to callback. virtual SrsConfDirective* get_vhost_on_publish(std::string vhost); - /** - * get the on_unpublish callbacks of vhost. - * @return the on_unpublish callback directive, the args is the url to callback. - */ + // Get the on_unpublish callbacks of vhost. + // @return the on_unpublish callback directive, the args is the url to callback. virtual SrsConfDirective* get_vhost_on_unpublish(std::string vhost); - /** - * get the on_play callbacks of vhost. - * @return the on_play callback directive, the args is the url to callback. - */ + // Get the on_play callbacks of vhost. + // @return the on_play callback directive, the args is the url to callback. virtual SrsConfDirective* get_vhost_on_play(std::string vhost); - /** - * get the on_stop callbacks of vhost. - * @return the on_stop callback directive, the args is the url to callback. - */ + // Get the on_stop callbacks of vhost. + // @return the on_stop callback directive, the args is the url to callback. virtual SrsConfDirective* get_vhost_on_stop(std::string vhost); - /** - * get the on_dvr callbacks of vhost. - * @return the on_dvr callback directive, the args is the url to callback. - */ + // Get the on_dvr callbacks of vhost. + // @return the on_dvr callback directive, the args is the url to callback. virtual SrsConfDirective* get_vhost_on_dvr(std::string vhost); - /** - * get the on_hls callbacks of vhost. - * @return the on_hls callback directive, the args is the url to callback. - */ + // Get the on_hls callbacks of vhost. + // @return the on_hls callback directive, the args is the url to callback. virtual SrsConfDirective* get_vhost_on_hls(std::string vhost); - /** - * get the on_hls_notify callbacks of vhost. - * @return the on_hls_notify callback directive, the args is the url to callback. - */ + // Get the on_hls_notify callbacks of vhost. + // @return the on_hls_notify callback directive, the args is the url to callback. virtual SrsConfDirective* get_vhost_on_hls_notify(std::string vhost); // bwct(bandwidth check tool) section public: - /** - * whether bw check enabled for vhost. - * if enabled, serve all clients with bandwidth check services. - * oterwise, serve all cleints with stream. - */ + // Whether bw check enabled for vhost. + // If enabled, serve all clients with bandwidth check services. + // oterwise, serve all cleints with stream. virtual bool get_bw_check_enabled(std::string vhost); - /** - * the key of server, if client key mot match, reject. - */ + // The key of server, if client key mot match, reject. virtual std::string get_bw_check_key(std::string vhost); - /** - * the check interval, in srs_utime_t. - * if the client request check in very short time(in the interval), - * SRS will reject client. - * @remark this is used to prevent the bandwidth check attack. - */ + // The check interval, in srs_utime_t. + // If the client request check in very short time(in the interval), + // SRS will reject client. + // @remark this is used to prevent the bandwidth check attack. virtual srs_utime_t get_bw_check_interval(std::string vhost); - /** - * the max kbps that user can test, - * if exceed the kbps, server will slowdown the send-recv. - * @remark this is used to protect the service bandwidth. - */ + // The max kbps that user can test, + // If exceed the kbps, server will slowdown the send-recv. + // @remark this is used to protect the service bandwidth. virtual int get_bw_check_limit_kbps(std::string vhost); // vhost cluster section public: - /** - * whether vhost is edge mode. - * for edge, publish client will be proxyed to upnode, - * for edge, play client will share a connection to get stream from upnode. - */ + // Whether vhost is edge mode. + // For edge, publish client will be proxyed to upnode, + // For edge, play client will share a connection to get stream from upnode. virtual bool get_vhost_is_edge(std::string vhost); - /** - * whether vhost is edge mode. - * for edge, publish client will be proxyed to upnode, - * for edge, play client will share a connection to get stream from upnode. - */ + // Whether vhost is edge mode. + // For edge, publish client will be proxyed to upnode, + // For edge, play client will share a connection to get stream from upnode. virtual bool get_vhost_is_edge(SrsConfDirective* conf); - /** - * get the origin config of edge, - * specifies the origin ip address, port. - */ + // Get the origin config of edge, + // specifies the origin ip address, port. virtual SrsConfDirective* get_vhost_edge_origin(std::string vhost); - /** - * whether edge token tranverse is enabled, - * if true, edge will send connect origin to verfy the token of client. - * for example, we verify all clients on the origin FMS by server-side as, - * all clients connected to edge must be tranverse to origin to verify. - */ + // Whether edge token tranverse is enabled, + // If true, edge will send connect origin to verfy the token of client. + // For example, we verify all clients on the origin FMS by server-side as, + // all clients connected to edge must be tranverse to origin to verify. virtual bool get_vhost_edge_token_traverse(std::string vhost); - /** - * get the transformed vhost for edge, - * @see https://github.com/ossrs/srs/issues/372 - */ + // Get the transformed vhost for edge, + // @see https://github.com/ossrs/srs/issues/372 virtual std::string get_vhost_edge_transform_vhost(std::string vhost); - /** - * Whether enable the origin cluster. - * @see https://github.com/ossrs/srs/wiki/v3_EN_OriginCluster - */ + // Whether enable the origin cluster. + // @see https://github.com/ossrs/srs/wiki/v3_EN_OriginCluster virtual bool get_vhost_origin_cluster(std::string vhost); - /** - * Get the co-workers of origin cluster. - * @see https://github.com/ossrs/srs/wiki/v3_EN_OriginCluster - */ + // Get the co-workers of origin cluster. + // @see https://github.com/ossrs/srs/wiki/v3_EN_OriginCluster virtual std::vector get_vhost_coworkers(std::string vhost); // vhost security section public: - /** - * whether the secrity of vhost enabled. - */ + // Whether the secrity of vhost enabled. virtual bool get_security_enabled(std::string vhost); - /** - * get the security rules. - */ + // Get the security rules. virtual SrsConfDirective* get_security_rules(std::string vhost); // vhost transcode section public: - /** - * get the transcode directive of vhost in specified scope. - * @param vhost, the vhost name to get the transcode directive. - * @param scope, the scope, empty to get all. for example, user can transcode - * the app scope stream, by config with app: - * transcode live {...} - * when the scope is "live", this directive is matched. - * the scope can be: empty for all, app, app/stream. - * @remark, please see the samples of full.conf, the app.transcode.srs.com - * and stream.transcode.srs.com. - */ + // Get the transcode directive of vhost in specified scope. + // @param vhost, the vhost name to get the transcode directive. + // @param scope, the scope, empty to get all. for example, user can transcode + // the app scope stream, by config with app: + // transcode live {...} + // when the scope is "live", this directive is matched. + // the scope can be: empty for all, app, app/stream. + // @remark, please see the samples of full.conf, the app.transcode.srs.com + // and stream.transcode.srs.com. virtual SrsConfDirective* get_transcode(std::string vhost, std::string scope); - /** - * whether the transcode directive is enabled. - */ + // Whether the transcode directive is enabled. virtual bool get_transcode_enabled(SrsConfDirective* conf); - /** - * get the ffmpeg tool path of transcode. - */ + // Get the ffmpeg tool path of transcode. virtual std::string get_transcode_ffmpeg(SrsConfDirective* conf); - /** - * get the engines of transcode. - */ + // Get the engines of transcode. virtual std::vector get_transcode_engines(SrsConfDirective* conf); - /** - * whether the engine is enabled. - */ + // Whether the engine is enabled. virtual bool get_engine_enabled(SrsConfDirective* conf); - /** - * get the perfile of engine - */ + // Get the perfile of engine virtual std::vector get_engine_perfile(SrsConfDirective* conf); - /** - * get the iformat of engine - */ + // Get the iformat of engine virtual std::string get_engine_iformat(SrsConfDirective* conf); - /** - * get the vfilter of engine, - * the video filter set before the vcodec of FFMPEG. - */ + // Get the vfilter of engine, + // The video filter set before the vcodec of FFMPEG. virtual std::vector get_engine_vfilter(SrsConfDirective* conf); - /** - * get the vcodec of engine, - * the codec of video, can be vn, copy or libx264 - */ + // Get the vcodec of engine, + // The codec of video, can be vn, copy or libx264 virtual std::string get_engine_vcodec(SrsConfDirective* conf); - /** - * get the vbitrate of engine, - * the bitrate in kbps of video, for example, 800kbps - */ + // Get the vbitrate of engine, + // The bitrate in kbps of video, for example, 800kbps virtual int get_engine_vbitrate(SrsConfDirective* conf); - /** - * get the vfps of engine. - * the video fps, for example, 25fps - */ + // Get the vfps of engine. + // The video fps, for example, 25fps virtual double get_engine_vfps(SrsConfDirective* conf); - /** - * get the vwidth of engine, - * the video width, for example, 1024 - */ + // Get the vwidth of engine, + // The video width, for example, 1024 virtual int get_engine_vwidth(SrsConfDirective* conf); - /** - * get the vheight of engine, - * the video height, for example, 576 - */ + // Get the vheight of engine, + // The video height, for example, 576 virtual int get_engine_vheight(SrsConfDirective* conf); - /** - * get the vthreads of engine, - * the video transcode libx264 threads, for instance, 8 - */ + // Get the vthreads of engine, + // The video transcode libx264 threads, for instance, 8 virtual int get_engine_vthreads(SrsConfDirective* conf); - /** - * get the vprofile of engine, - * the libx264 profile, can be high,main,baseline - */ + // Get the vprofile of engine, + // The libx264 profile, can be high,main,baseline virtual std::string get_engine_vprofile(SrsConfDirective* conf); - /** - * get the vpreset of engine, - * the libx264 preset, can be ultrafast,superfast,veryfast,faster,fast,medium,slow,slower,veryslow,placebo - */ + // Get the vpreset of engine, + // The libx264 preset, can be ultrafast,superfast,veryfast,faster,fast,medium,slow,slower,veryslow,placebo virtual std::string get_engine_vpreset(SrsConfDirective* conf); - /** - * get the additional video params. - */ + // Get the additional video params. virtual std::vector get_engine_vparams(SrsConfDirective* conf); - /** - * get the acodec of engine, - * the audio codec can be an, copy or libfdk_aac - */ + // Get the acodec of engine, + // The audio codec can be an, copy or libfdk_aac virtual std::string get_engine_acodec(SrsConfDirective* conf); - /** - * get the abitrate of engine, - * the audio bitrate in kbps, for instance, 64kbps. - */ + // Get the abitrate of engine, + // The audio bitrate in kbps, for instance, 64kbps. virtual int get_engine_abitrate(SrsConfDirective* conf); - /** - * get the asample_rate of engine, - * the audio sample_rate, for instance, 44100HZ - */ + // Get the asample_rate of engine, + // The audio sample_rate, for instance, 44100HZ virtual int get_engine_asample_rate(SrsConfDirective* conf); - /** - * get the achannels of engine, - * the audio channel, for instance, 1 for mono, 2 for stereo. - */ + // Get the achannels of engine, + // The audio channel, for instance, 1 for mono, 2 for stereo. virtual int get_engine_achannels(SrsConfDirective* conf); - /** - * get the aparams of engine, - * the audio additional params. - */ + // Get the aparams of engine, + // The audio additional params. virtual std::vector get_engine_aparams(SrsConfDirective* conf); - /** - * get the oformat of engine - */ + // Get the oformat of engine virtual std::string get_engine_oformat(SrsConfDirective* conf); - /** - * get the output of engine, for example, rtmp://localhost/live/livestream, - * @remark, we will use some variable, for instance, [vhost] to substitude with vhost. - */ + // Get the output of engine, for example, rtmp://localhost/live/livestream, + // @remark, we will use some variable, for instance, [vhost] to substitude with vhost. virtual std::string get_engine_output(SrsConfDirective* conf); // vhost exec secion private: - /** - * get the exec directive of vhost. - */ + // Get the exec directive of vhost. virtual SrsConfDirective* get_exec(std::string vhost); public: - /** - * whether the exec is enabled of vhost. - */ + // Whether the exec is enabled of vhost. virtual bool get_exec_enabled(std::string vhost); - /** - * get all exec publish directives of vhost. - */ + // Get all exec publish directives of vhost. virtual std::vector get_exec_publishs(std::string vhost); // vhost ingest section public: - /** - * get the ingest directives of vhost. - */ + // Get the ingest directives of vhost. virtual std::vector get_ingesters(std::string vhost); - /** - * get specified ingest. - */ + // Get specified ingest. virtual SrsConfDirective* get_ingest_by_id(std::string vhost, std::string ingest_id); - /** - * whether ingest is enalbed. - */ + // Whether ingest is enalbed. virtual bool get_ingest_enabled(SrsConfDirective* conf); - /** - * get the ingest ffmpeg tool - */ + // Get the ingest ffmpeg tool virtual std::string get_ingest_ffmpeg(SrsConfDirective* conf); - /** - * get the ingest input type, file or stream. - */ + // Get the ingest input type, file or stream. virtual std::string get_ingest_input_type(SrsConfDirective* conf); - /** - * get the ingest input url. - */ + // Get the ingest input url. virtual std::string get_ingest_input_url(SrsConfDirective* conf); // log section public: - /** - * whether log to file. - */ + // Whether log to file. virtual bool get_log_tank_file(); - /** - * get the log level. - */ + // Get the log level. virtual std::string get_log_level(); - /** - * get the log file path. - */ + // Get the log file path. virtual std::string get_log_file(); - /** - * whether ffmpeg log enabled - */ + // Whether ffmpeg log enabled virtual bool get_ffmpeg_log_enabled(); - /** - * the ffmpeg log dir. - * @remark, /dev/null to disable it. - */ + // The ffmpeg log dir. + // @remark, /dev/null to disable it. virtual std::string get_ffmpeg_log_dir(); // The MPEG-DASH section. private: @@ -1162,299 +780,171 @@ public: virtual std::string get_dash_mpd_file(std::string vhost); // hls section private: - /** - * get the hls directive of vhost. - */ + // Get the hls directive of vhost. virtual SrsConfDirective* get_hls(std::string vhost); public: - /** - * whether HLS is enabled. - */ + // Whether HLS is enabled. virtual bool get_hls_enabled(std::string vhost); - /** - * get the HLS m3u8 list ts segment entry prefix info. - */ + // Get the HLS m3u8 list ts segment entry prefix info. virtual std::string get_hls_entry_prefix(std::string vhost); - /** - * get the HLS ts/m3u8 file store path. - */ + // Get the HLS ts/m3u8 file store path. virtual std::string get_hls_path(std::string vhost); - /** - * get the HLS m3u8 file path template. - */ + // Get the HLS m3u8 file path template. virtual std::string get_hls_m3u8_file(std::string vhost); - /** - * get the HLS ts file path template. - */ + // Get the HLS ts file path template. virtual std::string get_hls_ts_file(std::string vhost); - /** - * whether enable the floor(timestamp/hls_fragment) for variable timestamp. - */ + // Whether enable the floor(timestamp/hls_fragment) for variable timestamp. virtual bool get_hls_ts_floor(std::string vhost); - /** - * get the hls fragment time, in srs_utime_t. - */ + // Get the hls fragment time, in srs_utime_t. virtual srs_utime_t get_hls_fragment(std::string vhost); - /** - * get the hls td(target duration) ratio. - */ + // Get the hls td(target duration) ratio. virtual double get_hls_td_ratio(std::string vhost); - /** - * get the hls aof(audio overflow) ratio. - */ + // Get the hls aof(audio overflow) ratio. virtual double get_hls_aof_ratio(std::string vhost); - /** - * get the hls window time, in srs_utime_t. - * a window is a set of ts, the ts collection in m3u8. - * @remark SRS will delete the ts exceed the window. - */ + // Get the hls window time, in srs_utime_t. + // a window is a set of ts, the ts collection in m3u8. + // @remark SRS will delete the ts exceed the window. virtual srs_utime_t get_hls_window(std::string vhost); - /** - * get the hls hls_on_error config. - * the ignore will ignore error and disable hls. - * the disconnect will disconnect publish connection. - * @see https://github.com/ossrs/srs/issues/264 - */ + // Get the hls hls_on_error config. + // The ignore will ignore error and disable hls. + // The disconnect will disconnect publish connection. + // @see https://github.com/ossrs/srs/issues/264 virtual std::string get_hls_on_error(std::string vhost); - /** - * get the HLS default audio codec. - */ + // Get the HLS default audio codec. virtual std::string get_hls_acodec(std::string vhost); - /** - * get the HLS default video codec. - */ + // Get the HLS default video codec. virtual std::string get_hls_vcodec(std::string vhost); - /** - * whether cleanup the old ts files. - */ + // Whether cleanup the old ts files. virtual bool get_hls_cleanup(std::string vhost); - /** - * the timeout in srs_utime_t to dispose the hls. - */ + // The timeout in srs_utime_t to dispose the hls. virtual srs_utime_t get_hls_dispose(std::string vhost); - /** - * whether reap the ts when got keyframe. - */ + // Whether reap the ts when got keyframe. virtual bool get_hls_wait_keyframe(std::string vhost); - /** - * encrypt ts or not - */ + // encrypt ts or not virtual bool get_hls_keys(std::string vhost); - /** - * how many fragments can one key encrypted. - */ + // how many fragments can one key encrypted. virtual int get_hls_fragments_per_key(std::string vhost); - /** - * get the HLS key file path template. - */ + // Get the HLS key file path template. virtual std::string get_hls_key_file(std::string vhost); - /** - * get the HLS key file store path. - */ + // Get the HLS key file store path. virtual std::string get_hls_key_file_path(std::string vhost); - /** - * get the HLS key file url which will be put in m3u8 - */ + // Get the HLS key file url which will be put in m3u8 virtual std::string get_hls_key_url(std::string vhost); - /** - * get the size of bytes to read from cdn network, for the on_hls_notify callback, - * that is, to read max bytes of the bytes from the callback, or timeout or error. - */ + // Get the size of bytes to read from cdn network, for the on_hls_notify callback, + // that is, to read max bytes of the bytes from the callback, or timeout or error. virtual int get_vhost_hls_nb_notify(std::string vhost); // hds section private: - /** - * get the hds directive of vhost. - */ + // Get the hds directive of vhost. virtual SrsConfDirective* get_hds(const std::string &vhost); public: - /** - * whether HDS is enabled. - */ + // Whether HDS is enabled. virtual bool get_hds_enabled(const std::string &vhost); - /** - * get the HDS file store path. - */ + // Get the HDS file store path. virtual std::string get_hds_path(const std::string &vhost); - /** - * get the hds fragment time, in srs_utime_t. - */ + // Get the hds fragment time, in srs_utime_t. virtual srs_utime_t get_hds_fragment(const std::string &vhost); - /** - * get the hds window time, in srs_utime_t. - * a window is a set of hds fragments. - */ + // Get the hds window time, in srs_utime_t. + // a window is a set of hds fragments. virtual srs_utime_t get_hds_window(const std::string &vhost); // dvr section private: - /** - * get the dvr directive. - */ + // Get the dvr directive. virtual SrsConfDirective* get_dvr(std::string vhost); public: - /** - * whether dvr is enabled. - */ + // Whether dvr is enabled. virtual bool get_dvr_enabled(std::string vhost); - /** - * get the filter of dvr to apply to. - * @remark user can use srs_config_apply_filter(conf, req):bool to check it. - */ + // Get the filter of dvr to apply to. + // @remark user can use srs_config_apply_filter(conf, req):bool to check it. virtual SrsConfDirective* get_dvr_apply(std::string vhost); - /** - * get the dvr path, the flv file to save in. - */ + // Get the dvr path, the flv file to save in. virtual std::string get_dvr_path(std::string vhost); - /** - * get the plan of dvr, how to reap the flv file. - */ + // Get the plan of dvr, how to reap the flv file. virtual std::string get_dvr_plan(std::string vhost); - /** - * get the duration of dvr flv. - */ + // Get the duration of dvr flv. virtual srs_utime_t get_dvr_duration(std::string vhost); - /** - * whether wait keyframe to reap segment. - */ + // Whether wait keyframe to reap segment. virtual bool get_dvr_wait_keyframe(std::string vhost); - /** - * get the time_jitter algorithm for dvr. - */ + // Get the time_jitter algorithm for dvr. virtual int get_dvr_time_jitter(std::string vhost); // http api section private: - /** - * whether http api enabled - */ + // Whether http api enabled virtual bool get_http_api_enabled(SrsConfDirective* conf); public: - /** - * whether http api enabled. - */ + // Whether http api enabled. virtual bool get_http_api_enabled(); - /** - * get the http api listen port. - */ + // Get the http api listen port. virtual std::string get_http_api_listen(); - /** - * whether enable crossdomain for http api. - */ + // Whether enable crossdomain for http api. virtual bool get_http_api_crossdomain(); - /** - * whether enable the HTTP RAW API. - */ + // Whether enable the HTTP RAW API. virtual bool get_raw_api(); - /** - * whether allow rpc reload. - */ + // Whether allow rpc reload. virtual bool get_raw_api_allow_reload(); - /** - * whether allow rpc query. - */ + // Whether allow rpc query. virtual bool get_raw_api_allow_query(); - /** - * whether allow rpc update. - */ + // Whether allow rpc update. virtual bool get_raw_api_allow_update(); // http stream section private: - /** - * whether http stream enabled. - */ + // Whether http stream enabled. virtual bool get_http_stream_enabled(SrsConfDirective* conf); public: - /** - * whether http stream enabled. - */ + // Whether http stream enabled. // TODO: FIXME: rename to http_static. virtual bool get_http_stream_enabled(); - /** - * get the http stream listen port. - */ + // Get the http stream listen port. virtual std::string get_http_stream_listen(); - /** - * get the http stream root dir. - */ + // Get the http stream root dir. virtual std::string get_http_stream_dir(); - /** - * whether enable crossdomain for http static and stream server. - */ + // Whether enable crossdomain for http static and stream server. virtual bool get_http_stream_crossdomain(); public: - /** - * get whether vhost enabled http stream - */ + // Get whether vhost enabled http stream virtual bool get_vhost_http_enabled(std::string vhost); - /** - * get the http mount point for vhost. - * for example, http://vhost/live/livestream - */ + // Get the http mount point for vhost. + // For example, http://vhost/live/livestream virtual std::string get_vhost_http_mount(std::string vhost); - /** - * get the http dir for vhost. - * the path on disk for mount root of http vhost. - */ + // Get the http dir for vhost. + // The path on disk for mount root of http vhost. virtual std::string get_vhost_http_dir(std::string vhost); // flv live streaming section public: - /** - * get whether vhost enabled http flv live stream - */ + // Get whether vhost enabled http flv live stream virtual bool get_vhost_http_remux_enabled(std::string vhost); - /** - * get the fast cache duration for http audio live stream. - */ + // Get the fast cache duration for http audio live stream. virtual srs_utime_t get_vhost_http_remux_fast_cache(std::string vhost); - /** - * get the http flv live stream mount point for vhost. - * used to generate the flv stream mount path. - */ + // Get the http flv live stream mount point for vhost. + // used to generate the flv stream mount path. virtual std::string get_vhost_http_remux_mount(std::string vhost); // http heartbeart section private: - /** - * get the heartbeat directive. - */ + // Get the heartbeat directive. virtual SrsConfDirective* get_heartbeart(); public: - /** - * whether heartbeat enabled. - */ + // Whether heartbeat enabled. virtual bool get_heartbeat_enabled(); - /** - * get the heartbeat interval, in srs_utime_t. - */ + // Get the heartbeat interval, in srs_utime_t. virtual srs_utime_t get_heartbeat_interval(); - /** - * get the heartbeat report url. - */ + // Get the heartbeat report url. virtual std::string get_heartbeat_url(); - /** - * get the device id of heartbeat, to report to server. - */ + // Get the device id of heartbeat, to report to server. virtual std::string get_heartbeat_device_id(); - /** - * whether report with summaries of http api: /api/v1/summaries. - */ + // Whether report with summaries of http api: /api/v1/summaries. virtual bool get_heartbeat_summaries(); // stats section private: - /** - * get the stats directive. - */ + // Get the stats directive. virtual SrsConfDirective* get_stats(); public: - /** - * get the network device index, used to retrieve the ip of device, - * for heartbeat to report to server, or to get the local ip. - * for example, 0 means the eth0 maybe. - */ + // Get the network device index, used to retrieve the ip of device, + // For heartbeat to report to server, or to get the local ip. + // For example, 0 means the eth0 maybe. virtual int get_stats_network(); - /** - * get the disk stat device name list. - * the device name configed in args of directive. - * @return the disk device name to stat. NULL if not configed. - */ + // Get the disk stat device name list. + // The device name configed in args of directive. + // @return the disk device name to stat. NULL if not configed. virtual SrsConfDirective* get_stats_disk_device(); }; diff --git a/trunk/src/app/srs_app_conn.hpp b/trunk/src/app/srs_app_conn.hpp index 7a723dfbf..bd5922688 100644 --- a/trunk/src/app/srs_app_conn.hpp +++ b/trunk/src/app/srs_app_conn.hpp @@ -36,48 +36,32 @@ class SrsWallClock; -/** - * the basic connection of SRS, - * all connections accept from listener must extends from this base class, - * server will add the connection to manager, and delete it when remove. - */ +// The basic connection of SRS, +// all connections accept from listener must extends from this base class, +// server will add the connection to manager, and delete it when remove. class SrsConnection : virtual public ISrsConnection, virtual public ISrsCoroutineHandler , virtual public ISrsKbpsDelta, virtual public ISrsReloadHandler { protected: - /** - * each connection start a green thread, - * when thread stop, the connection will be delete by server. - */ + // Each connection start a green thread, + // when thread stop, the connection will be delete by server. SrsCoroutine* trd; - /** - * the manager object to manage the connection. - */ + // The manager object to manage the connection. IConnectionManager* manager; - /** - * the underlayer st fd handler. - */ + // The underlayer st fd handler. srs_netfd_t stfd; - /** - * the ip of client. - */ + // The ip of client. std::string ip; - /** - * the underlayer socket. - */ + // The underlayer socket. SrsStSocket* skt; - /** - * connection total kbps. - * not only the rtmp or http connection, all type of connection are - * need to statistic the kbps of io. - * the SrsStatistic will use it indirectly to statistic the bytes delta of current connection. - */ + // The connection total kbps. + // not only the rtmp or http connection, all type of connection are + // need to statistic the kbps of io. + // The SrsStatistic will use it indirectly to statistic the bytes delta of current connection. SrsKbps* kbps; SrsWallClock* clk; - /** - * the create time in milliseconds. - * for current connection to log self create time and calculate the living time. - */ + // The create time in milliseconds. + // for current connection to log self create time and calculate the living time. int64_t create_time; public: SrsConnection(IConnectionManager* cm, srs_netfd_t c, std::string cip); @@ -86,19 +70,15 @@ public: public: virtual void remark(int64_t* in, int64_t* out); public: - /** - * to dipose the connection. - */ + // To dipose the connection. virtual void dispose(); - /** - * start the client green thread. - * when server get a client from listener, - * 1. server will create an concrete connection(for instance, RTMP connection), - * 2. then add connection to its connection manager, - * 3. start the client thread by invoke this start() - * when client cycle thread stop, invoke the on_thread_stop(), which will use server - * to remove the client by server->remove(this). - */ + // Start the client green thread. + // when server get a client from listener, + // 1. server will create an concrete connection(for instance, RTMP connection), + // 2. then add connection to its connection manager, + // 3. start the client thread by invoke this start() + // when client cycle thread stop, invoke the on_thread_stop(), which will use server + // To remove the client by server->remove(this). virtual srs_error_t start(); // Set socket option TCP_NODELAY. virtual srs_error_t set_tcp_nodelay(bool v); @@ -106,25 +86,17 @@ public: virtual srs_error_t set_socket_buffer(srs_utime_t buffer_v); // interface ISrsOneCycleThreadHandler public: - /** - * the thread cycle function, - * when serve connection completed, terminate the loop which will terminate the thread, - * thread will invoke the on_thread_stop() when it terminated. - */ + // The thread cycle function, + // when serve connection completed, terminate the loop which will terminate the thread, + // thread will invoke the on_thread_stop() when it terminated. virtual srs_error_t cycle(); public: - /** - * get the srs id which identify the client. - */ + // Get the srs id which identify the client. virtual int srs_id(); - /** - * set connection to expired. - */ + // Set connection to expired. virtual void expire(); protected: - /** - * for concrete connection to do the cycle. - */ + // For concrete connection to do the cycle. virtual srs_error_t do_cycle() = 0; }; diff --git a/trunk/src/app/srs_app_coworkers.hpp b/trunk/src/app/srs_app_coworkers.hpp index 60c460159..b7be73dca 100644 --- a/trunk/src/app/srs_app_coworkers.hpp +++ b/trunk/src/app/srs_app_coworkers.hpp @@ -33,6 +33,7 @@ class SrsJsonAny; class SrsRequest; class SrsSource; +// For origin cluster. class SrsCoWorkers { private: diff --git a/trunk/src/app/srs_app_heartbeat.hpp b/trunk/src/app/srs_app_heartbeat.hpp index e08275ca2..32d7b97dc 100644 --- a/trunk/src/app/srs_app_heartbeat.hpp +++ b/trunk/src/app/srs_app_heartbeat.hpp @@ -26,10 +26,7 @@ #include -/** - * the http heartbeat to api-server to notice api - * that the information of SRS. - */ +// The http heartbeat to api-server to notice api that the information of SRS. class SrsHttpHeartbeat { public: diff --git a/trunk/src/app/srs_app_hls.hpp b/trunk/src/app/srs_app_hls.hpp index d51ad7efb..cb95ac738 100644 --- a/trunk/src/app/srs_app_hls.hpp +++ b/trunk/src/app/srs_app_hls.hpp @@ -50,12 +50,10 @@ class SrsTsMessageCache; class SrsHlsSegment; class SrsTsContext; -/** - * the wrapper of m3u8 segment from specification: - * - * 3.3.2. EXTINF - * The EXTINF tag specifies the duration of a media segment. - */ +// The wrapper of m3u8 segment from specification: +// +// 3.3.2. EXTINF +// The EXTINF tag specifies the duration of a media segment. class SrsHlsSegment : public SrsFragment { public: @@ -63,7 +61,7 @@ public: int sequence_no; // ts uri in m3u8. std::string uri; - // the underlayer file writer. + // The underlayer file writer. SrsFileWriter* writer; // The TS context writer to write TS to file. SrsTsContextWriter* tscw; @@ -78,9 +76,7 @@ public: void config_cipher(unsigned char* key,unsigned char* iv); }; -/** - * the hls async call: on_hls - */ +// The hls async call: on_hls class SrsDvrAsyncCallOnHls : public ISrsAsyncCallTask { private: @@ -101,9 +97,7 @@ public: virtual std::string to_string(); }; -/** - * the hls async call: on_hls_notify - */ +// The hls async call: on_hls_notify class SrsDvrAsyncCallOnHlsNotify : public ISrsAsyncCallTask { private: @@ -118,14 +112,12 @@ public: virtual std::string to_string(); }; -/** - * muxer the HLS stream(m3u8 and ts files). - * generally, the m3u8 muxer only provides methods to open/close segments, - * to flush video/audio, without any mechenisms. - * - * that is, user must use HlsCache, which will control the methods of muxer, - * and provides HLS mechenisms. - */ +// Mux the HLS stream(m3u8 and ts files). +// Generally, the m3u8 muxer only provides methods to open/close segments, +// to flush video/audio, without any mechenisms. +// +// That is, user must use HlsCache, which will control the methods of muxer, +// and provides HLS mechenisms. class SrsHlsMuxer { private: @@ -143,26 +135,26 @@ private: srs_utime_t hls_window; SrsAsyncCallWorker* async; private: - // whether use floor algorithm for timestamp. + // Whether use floor algorithm for timestamp. bool hls_ts_floor; - // the deviation in piece to adjust the fragment to be more + // The deviation in piece to adjust the fragment to be more // bigger or smaller. int deviation_ts; - // the previous reap floor timestamp, + // The previous reap floor timestamp, // used to detect the dup or jmp or ts. int64_t accept_floor_ts; int64_t previous_floor_ts; private: - // encrypted or not + // Whether encrypted or not bool hls_keys; int hls_fragments_per_key; - // key file name + // The key file name std::string hls_key_file; - // key file path + // The key file path std::string hls_key_file_path; - // key file url + // The key file url std::string hls_key_url; - // key and iv. + // The key and iv. unsigned char key[16]; unsigned char iv[16]; SrsFileWriter *writer; @@ -176,10 +168,8 @@ private: SrsFragmentWindow* segments; // The current writing segment. SrsHlsSegment* current; - /** - * the ts context, to keep cc continous between ts. - * @see https://github.com/ossrs/srs/issues/375 - */ + // The ts context, to keep cc continous between ts. + // @see https://github.com/ossrs/srs/issues/375 SrsTsContext* context; public: SrsHlsMuxer(); @@ -192,48 +182,32 @@ public: virtual srs_utime_t duration(); virtual int deviation(); public: - /** - * initialize the hls muxer. - */ + // Initialize the hls muxer. virtual srs_error_t initialize(); - /** - * when publish, update the config for muxer. - */ + // When publish, update the config for muxer. virtual srs_error_t update_config(SrsRequest* r, std::string entry_prefix, std::string path, std::string m3u8_file, std::string ts_file, srs_utime_t fragment, srs_utime_t window, bool ts_floor, double aof_ratio, bool cleanup, bool wait_keyframe, bool keys, int fragments_per_key, std::string key_file, std::string key_file_path, std::string key_url); - /** - * open a new segment(a new ts file) - */ + // Open a new segment(a new ts file) virtual srs_error_t segment_open(); virtual srs_error_t on_sequence_header(); - /** - * whether segment overflow, - * that is whether the current segment duration>=(the segment in config) - */ + // Whether segment overflow, + // that is whether the current segment duration>=(the segment in config) virtual bool is_segment_overflow(); - /** - * whether wait keyframe to reap the ts. - */ + // Whether wait keyframe to reap the ts. virtual bool wait_keyframe(); - /** - * whether segment absolutely overflow, for pure audio to reap segment, - * that is whether the current segment duration>=2*(the segment in config) - * @see https://github.com/ossrs/srs/issues/151#issuecomment-71155184 - */ + // Whether segment absolutely overflow, for pure audio to reap segment, + // that is whether the current segment duration>=2*(the segment in config) + // @see https://github.com/ossrs/srs/issues/151#issuecomment-71155184 virtual bool is_segment_absolutely_overflow(); public: - /** - * whether current hls muxer is pure audio mode. - */ + // Whether current hls muxer is pure audio mode. virtual bool pure_audio(); virtual srs_error_t flush_audio(SrsTsMessageCache* cache); virtual srs_error_t flush_video(SrsTsMessageCache* cache); - /** - * Close segment(ts). - */ + // Close segment(ts). virtual srs_error_t segment_close(); private: virtual srs_error_t do_segment_close(); @@ -242,23 +216,21 @@ private: virtual srs_error_t _refresh_m3u8(std::string m3u8_file); }; -/** - * hls stream cache, - * use to cache hls stream and flush to hls muxer. - * - * when write stream to ts file: - * video frame will directly flush to M3u8Muxer, - * audio frame need to cache, because it's small and flv tbn problem. - * - * whatever, the Hls cache used to cache video/audio, - * and flush video/audio to m3u8 muxer if needed. - * - * about the flv tbn problem: - * flv tbn is 1/1000, ts tbn is 1/90000, - * when timestamp convert to flv tbn, it will loose precise, - * so we must gather audio frame together, and recalc the timestamp @see SrsTsAacJitter, - * we use a aac jitter to correct the audio pts. - */ +// The hls stream cache, +// use to cache hls stream and flush to hls muxer. +// +// When write stream to ts file: +// video frame will directly flush to M3u8Muxer, +// audio frame need to cache, because it's small and flv tbn problem. +// +// Whatever, the Hls cache used to cache video/audio, +// and flush video/audio to m3u8 muxer if needed. +// +// About the flv tbn problem: +// flv tbn is 1/1000, ts tbn is 1/90000, +// when timestamp convert to flv tbn, it will loose precise, +// so we must gather audio frame together, and recalc the timestamp @see SrsTsAacJitter, +// we use a aac jitter to correct the audio pts. class SrsHlsController { private: @@ -278,40 +250,28 @@ public: virtual srs_utime_t duration(); virtual int deviation(); public: - /** - * when publish or unpublish stream. - */ + // When publish or unpublish stream. virtual srs_error_t on_publish(SrsRequest* req); virtual srs_error_t on_unpublish(); - /** - * when get sequence header, - * must write a #EXT-X-DISCONTINUITY to m3u8. - * @see: hls-m3u8-draft-pantos-http-live-streaming-12.txt - * @see: 3.4.11. EXT-X-DISCONTINUITY - */ + // When get sequence header, + // must write a #EXT-X-DISCONTINUITY to m3u8. + // @see: hls-m3u8-draft-pantos-http-live-streaming-12.txt + // @see: 3.4.11. EXT-X-DISCONTINUITY virtual srs_error_t on_sequence_header(); - /** - * write audio to cache, if need to flush, flush to muxer. - */ + // write audio to cache, if need to flush, flush to muxer. virtual srs_error_t write_audio(SrsAudioFrame* frame, int64_t pts); - /** - * write video to muxer. - */ + // write video to muxer. virtual srs_error_t write_video(SrsVideoFrame* frame, int64_t dts); private: - /** - * reopen the muxer for a new hls segment, - * close current segment, open a new segment, - * then write the key frame to the new segment. - * so, user must reap_segment then flush_video to hls muxer. - */ + // Reopen the muxer for a new hls segment, + // close current segment, open a new segment, + // then write the key frame to the new segment. + // so, user must reap_segment then flush_video to hls muxer. virtual srs_error_t reap_segment(); }; -/** - * Transmux RTMP stream to HLS(m3u8 and ts). - * TODO: FIXME: add utest for hls. - */ +// Transmux RTMP stream to HLS(m3u8 and ts). +// TODO: FIXME: add utest for hls. class SrsHls { private: @@ -338,31 +298,21 @@ public: virtual void dispose(); virtual srs_error_t cycle(); public: - /** - * initialize the hls by handler and source. - */ + // Initialize the hls by handler and source. virtual srs_error_t initialize(SrsOriginHub* h, SrsRequest* r); - /** - * publish stream event, continue to write the m3u8, - * for the muxer object not destroyed. - * @param fetch_sequence_header whether fetch sequence from source. - */ + // Publish stream event, continue to write the m3u8, + // for the muxer object not destroyed. + // @param fetch_sequence_header whether fetch sequence from source. virtual srs_error_t on_publish(); - /** - * the unpublish event, only close the muxer, donot destroy the - * muxer, for when we continue to publish, the m3u8 will continue. - */ + // The unpublish event, only close the muxer, donot destroy the + // muxer, for when we continue to publish, the m3u8 will continue. virtual void on_unpublish(); - /** - * mux the audio packets to ts. - * @param shared_audio, directly ptr, copy it if need to save it. - */ + // Mux the audio packets to ts. + // @param shared_audio, directly ptr, copy it if need to save it. virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format); - /** - * mux the video packets to ts. - * @param shared_video, directly ptr, copy it if need to save it. - * @param is_sps_pps whether the video is h.264 sps/pps. - */ + // Mux the video packets to ts. + // @param shared_video, directly ptr, copy it if need to save it. + // @param is_sps_pps whether the video is h.264 sps/pps. // TODO: FIXME: Remove param is_sps_pps. virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format); private: diff --git a/trunk/src/app/srs_app_ingest.hpp b/trunk/src/app/srs_app_ingest.hpp index 9e16f6906..79659439f 100644 --- a/trunk/src/app/srs_app_ingest.hpp +++ b/trunk/src/app/srs_app_ingest.hpp @@ -35,9 +35,7 @@ class SrsFFMPEG; class SrsConfDirective; class SrsPithyPrint; -/** - * ingester ffmpeg object. - */ +// Ingester ffmpeg object. class SrsIngesterFFMPEG { private: @@ -50,9 +48,9 @@ public: virtual ~SrsIngesterFFMPEG(); public: virtual srs_error_t initialize(SrsFFMPEG* ff, std::string v, std::string i); - // the ingest uri, [vhost]/[ingest id] + // The ingest uri, [vhost]/[ingest id] virtual std::string uri(); - // the alive in srs_utime_t. + // The alive in srs_utime_t. virtual srs_utime_t alive(); virtual bool equals(std::string v, std::string i); virtual bool equals(std::string v); @@ -64,11 +62,9 @@ public: virtual void fast_stop(); }; -/** - * ingest file/stream/device, - * encode with FFMPEG(optional), - * push to SRS(or any RTMP server) over RTMP. - */ +// Ingest file/stream/device, +// encode with FFMPEG(optional), +// push to SRS(or any RTMP server) over RTMP. class SrsIngester : public ISrsCoroutineHandler, public ISrsReloadHandler { private: @@ -76,8 +72,7 @@ private: private: SrsCoroutine* trd; SrsPithyPrint* pprint; - // whether the ingesters are expired, - // for example, the listen port changed, + // Whether the ingesters are expired, for example, the listen port changed, // all ingesters must be restart. bool expired; public: diff --git a/trunk/src/app/srs_app_kafka.hpp b/trunk/src/app/srs_app_kafka.hpp index 37101cb8f..38e0ca20e 100644 --- a/trunk/src/app/srs_app_kafka.hpp +++ b/trunk/src/app/srs_app_kafka.hpp @@ -42,14 +42,10 @@ class SrsKafkaProducer; #ifdef SRS_AUTO_KAFKA -/** - * the partition messages cache. - */ +// The partition messages cache. typedef std::vector SrsKafkaPartitionCache; -/** - * the kafka partition info. - */ +// The kafka partition info. struct SrsKafkaPartition { private: @@ -75,9 +71,7 @@ private: virtual void disconnect(); }; -/** - * the following is all types of kafka messages. - */ +// The following is all types of kafka messages. class SrsKafkaMessage : public ISrsAsyncCallTask { private: @@ -93,19 +87,17 @@ public: virtual std::string to_string(); }; -/** - * a message cache for kafka. - */ +// A message cache for kafka. class SrsKafkaCache { public: - // the total partitions, + // The total partitions, // for the key to map to the parition by key%nb_partitions. int nb_partitions; private: - // total messages for all partitions. + // Total messages for all partitions. int count; - // key is the partition id, value is the message set to write to this partition. + // The key is the partition id, value is the message set to write to this partition. // @remark, when refresh metadata, the partition will increase, // so maybe some message will dispatch to new partition. std::map< int32_t, SrsKafkaPartitionCache*> cache; @@ -115,37 +107,27 @@ public: public: virtual void append(int key, SrsJsonObject* obj); virtual int size(); - /** - * fetch out a available partition cache. - * @return true when got a key and pc; otherwise, false. - */ + // Fetch out a available partition cache. + // @return true when got a key and pc; otherwise, false. virtual bool fetch(int* pkey, SrsKafkaPartitionCache** ppc); - /** - * flush the specified partition cache. - */ + // Flush the specified partition cache. virtual srs_error_t flush(SrsKafkaPartition* partition, int key, SrsKafkaPartitionCache* pc); }; -/** - * the kafka cluster interface. - */ +// The kafka cluster interface. class ISrsKafkaCluster { public: ISrsKafkaCluster(); virtual ~ISrsKafkaCluster(); public: - /** - * when got any client connect to SRS, notify kafka. - * @param key the partition map key, the client id or hash(ip). - * @param type the type of client. - * @param ip the peer ip of client. - */ + // When got any client connect to SRS, notify kafka. + // @param key the partition map key, the client id or hash(ip). + // @param type the type of client. + // @param ip the peer ip of client. virtual srs_error_t on_client(int key, SrsListenerType type, std::string ip) = 0; - /** - * when client close or disconnect for error. - * @param key the partition map key, the client id or hash(ip). - */ + // When client close or disconnect for error. + // @param key the partition map key, the client id or hash(ip). virtual srs_error_t on_close(int key) = 0; }; @@ -155,9 +137,7 @@ extern ISrsKafkaCluster* _srs_kafka; extern srs_error_t srs_initialize_kafka(); extern void srs_dispose_kafka(); -/** - * the kafka producer used to save log to kafka cluster. - */ +// The kafka producer used to save log to kafka cluster. class SrsKafkaProducer : virtual public ISrsCoroutineHandler, virtual public ISrsKafkaCluster { private: @@ -183,12 +163,10 @@ public: virtual void stop(); // internal: for worker to call task to send object. public: - /** - * send json object to kafka cluster. - * the producer will aggregate message and send in kafka message set. - * @param key the key to map to the partition, user can use cid or hash. - * @param obj the json object; user must never free it again. - */ + // Send json object to kafka cluster. + // The producer will aggregate message and send in kafka message set. + // @param key the key to map to the partition, user can use cid or hash. + // @param obj the json object; user must never free it again. virtual srs_error_t send(int key, SrsJsonObject* obj); // interface ISrsKafkaCluster public: @@ -201,7 +179,7 @@ private: virtual void clear_metadata(); virtual srs_error_t do_cycle(); virtual srs_error_t request_metadata(); - // set the metadata to invalid and refresh it. + // Set the metadata to invalid and refresh it. virtual void refresh_metadata(); virtual srs_error_t flush(); }; diff --git a/trunk/src/app/srs_app_server.hpp b/trunk/src/app/srs_app_server.hpp index 9f0b437d1..437e99db4 100644 --- a/trunk/src/app/srs_app_server.hpp +++ b/trunk/src/app/srs_app_server.hpp @@ -55,7 +55,7 @@ class SrsKafkaProducer; #endif class SrsCoroutineManager; -// listener type for server to identify the connection, +// The listener type for server to identify the connection, // that is, use different type to process the connection. enum SrsListenerType { @@ -73,9 +73,7 @@ enum SrsListenerType SrsListenerFlv = 5, }; -/** - * the common tcp listener, for RTMP/HTTP server. - */ +// A common tcp listener, for RTMP/HTTP server. class SrsListener { protected: @@ -92,9 +90,7 @@ public: virtual srs_error_t listen(std::string i, int p) = 0; }; -/** - * tcp listener. - */ +// A buffered TCP listener. class SrsBufferListener : virtual public SrsListener, virtual public ISrsTcpHandler { private: @@ -104,14 +100,12 @@ public: virtual ~SrsBufferListener(); public: virtual srs_error_t listen(std::string ip, int port); -// ISrsTcpHandler +// interface ISrsTcpHandler public: virtual srs_error_t on_tcp_client(srs_netfd_t stfd); }; -/** - * the tcp listener, for rtsp server. - */ +// A TCP listener, for rtsp server. class SrsRtspListener : virtual public SrsListener, virtual public ISrsTcpHandler { private: @@ -122,14 +116,12 @@ public: virtual ~SrsRtspListener(); public: virtual srs_error_t listen(std::string i, int p); -// ISrsTcpHandler +// interface ISrsTcpHandler public: virtual srs_error_t on_tcp_client(srs_netfd_t stfd); }; -/** - * the tcp listener, for flv stream server. - */ +// A TCP listener, for flv stream server. class SrsHttpFlvListener : virtual public SrsListener, virtual public ISrsTcpHandler { private: @@ -140,14 +132,12 @@ public: virtual ~SrsHttpFlvListener(); public: virtual srs_error_t listen(std::string i, int p); -// ISrsTcpHandler +// interface ISrsTcpHandler public: virtual srs_error_t on_tcp_client(srs_netfd_t stfd); }; -/** - * the udp listener, for udp server. - */ +// A UDP listener, for udp server. class SrsUdpStreamListener : public SrsListener { protected: @@ -160,9 +150,7 @@ public: virtual srs_error_t listen(std::string i, int p); }; -/** - * the udp listener, for udp stream caster server. - */ +// A UDP listener, for udp stream caster server. class SrsUdpCasterListener : public SrsUdpStreamListener { public: @@ -170,15 +158,13 @@ public: virtual ~SrsUdpCasterListener(); }; -/** - * convert signal to io, - * @see: st-1.9/docs/notes.html - */ +// Convert signal to io, +// @see: st-1.9/docs/notes.html class SrsSignalManager : public ISrsCoroutineHandler { private: - /* Per-process pipe which is used as a signal queue. */ - /* Up to PIPE_BUF/sizeof(int) signals can be queued up. */ + // Per-process pipe which is used as a signal queue. + // Up to PIPE_BUF/sizeof(int) signals can be queued up. int sig_pipe[2]; srs_netfd_t signal_read_stfd; private: @@ -194,43 +180,30 @@ public: public: virtual srs_error_t cycle(); private: - // global singleton instance + // Global singleton instance static SrsSignalManager* instance; - /* Signal catching function. */ - /* Converts signal event to I/O event. */ + // Signal catching function. + // Converts signal event to I/O event. static void sig_catcher(int signo); }; -/** - * the handler to the handle cycle in SRS RTMP server. - */ +// A handler to the handle cycle in SRS RTMP server. class ISrsServerCycle { public: ISrsServerCycle(); virtual ~ISrsServerCycle(); public: - /** - * initialize the cycle handler. - */ + // Initialize the cycle handler. virtual srs_error_t initialize() = 0; - /** - * do on_cycle while server doing cycle. - */ + // Do on_cycle while server doing cycle. virtual srs_error_t on_cycle() = 0; - /** - * callback the handler when got client. - */ + // Callback the handler when got client. virtual srs_error_t on_accept_client(int max, int cur) = 0; }; -/** - * SRS RTMP server, initialize and listen, - * start connection service thread, destroy client. - */ -class SrsServer : virtual public ISrsReloadHandler - , virtual public ISrsSourceHandler - , virtual public IConnectionManager +// SRS RTMP server, initialize and listen, start connection service thread, destroy client. +class SrsServer : virtual public ISrsReloadHandler, virtual public ISrsSourceHandler, virtual public IConnectionManager { private: // TODO: FIXME: rename to http_api @@ -240,59 +213,41 @@ private: SrsIngester* ingester; SrsCoroutineManager* conn_manager; private: - /** - * the pid file fd, lock the file write when server is running. - * @remark the init.d script should cleanup the pid file, when stop service, - * for the server never delete the file; when system startup, the pid in pid file - * maybe valid but the process is not SRS, the init.d script will never start server. - */ + // The pid file fd, lock the file write when server is running. + // @remark the init.d script should cleanup the pid file, when stop service, + // for the server never delete the file; when system startup, the pid in pid file + // maybe valid but the process is not SRS, the init.d script will never start server. int pid_fd; - /** - * all connections, connection manager - */ + // All connections, connection manager std::vector conns; - /** - * all listners, listener manager. - */ + // All listners, listener manager. std::vector listeners; - /** - * signal manager which convert gignal to io message. - */ + // Signal manager which convert gignal to io message. SrsSignalManager* signal_manager; - /** - * handle in server cycle. - */ + // Handle in server cycle. ISrsServerCycle* handler; - /** - * user send the signal, convert to variable. - */ + // User send the signal, convert to variable. bool signal_reload; bool signal_persistence_config; bool signal_gmc_stop; bool signal_gracefully_quit; - // parent pid for asprocess. + // Parent pid for asprocess. int ppid; public: SrsServer(); virtual ~SrsServer(); private: - /** - * the destroy is for gmc to analysis the memory leak, - * if not destroy global/static data, the gmc will warning memory leak. - * in service, server never destroy, directly exit when restart. - */ + // The destroy is for gmc to analysis the memory leak, + // if not destroy global/static data, the gmc will warning memory leak. + // In service, server never destroy, directly exit when restart. virtual void destroy(); - /** - * when SIGTERM, SRS should do cleanup, for example, - * to stop all ingesters, cleanup HLS and dvr. - */ + // When SIGTERM, SRS should do cleanup, for example, + // to stop all ingesters, cleanup HLS and dvr. virtual void dispose(); // server startup workflow, @see run_master() public: - /** - * initialize server with callback handler ch. - * @remark user must free the handler. - */ + // Initialize server with callback handler ch. + // @remark user must free the handler. virtual srs_error_t initialize(ISrsServerCycle* ch); virtual srs_error_t initialize_st(); virtual srs_error_t initialize_signal(); @@ -304,62 +259,48 @@ public: virtual srs_error_t cycle(); // server utilities. public: - /** - * callback for signal manager got a signal. - * the signal manager convert signal to io message, - * whatever, we will got the signo like the orignal signal(int signo) handler. - * @param signo the signal number from user, where: - * SRS_SIGNAL_GRACEFULLY_QUIT, the SIGTERM, dispose then quit. - * SRS_SIGNAL_REOPEN_LOG, the SIGUSR1, reopen the log file. - * SRS_SIGNAL_RELOAD, the SIGHUP, reload the config. - * SRS_SIGNAL_PERSISTENCE_CONFIG, application level signal, persistence config to file. - * @remark, for SIGINT: - * no gmc, directly exit. - * for gmc, set the variable signal_gmc_stop, the cycle will return and cleanup for gmc. - * @remark, maybe the HTTP RAW API will trigger the on_signal() also. - */ + // The callback for signal manager got a signal. + // The signal manager convert signal to io message, + // whatever, we will got the signo like the orignal signal(int signo) handler. + // @param signo the signal number from user, where: + // SRS_SIGNAL_GRACEFULLY_QUIT, the SIGTERM, dispose then quit. + // SRS_SIGNAL_REOPEN_LOG, the SIGUSR1, reopen the log file. + // SRS_SIGNAL_RELOAD, the SIGHUP, reload the config. + // SRS_SIGNAL_PERSISTENCE_CONFIG, application level signal, persistence config to file. + // @remark, for SIGINT: + // no gmc, directly exit. + // for gmc, set the variable signal_gmc_stop, the cycle will return and cleanup for gmc. + // @remark, maybe the HTTP RAW API will trigger the on_signal() also. virtual void on_signal(int signo); private: - /** - * the server thread main cycle, - * update the global static data, for instance, the current time, - * the cpu/mem/network statistic. - */ + // The server thread main cycle, + // update the global static data, for instance, the current time, + // the cpu/mem/network statistic. virtual srs_error_t do_cycle(); - /** - * listen at specified protocol. - */ + // listen at specified protocol. virtual srs_error_t listen_rtmp(); virtual srs_error_t listen_http_api(); virtual srs_error_t listen_http_stream(); virtual srs_error_t listen_stream_caster(); - /** - * close the listeners for specified type, - * remove the listen object from manager. - */ + // Close the listeners for specified type, + // Remove the listen object from manager. virtual void close_listeners(SrsListenerType type); - /** - * resample the server kbs. - */ + // Resample the server kbs. virtual void resample_kbps(); - // internal only +// For internal only public: - /** - * when listener got a fd, notice server to accept it. - * @param type, the client type, used to create concrete connection, - * for instance RTMP connection to serve client. - * @param stfd, the client fd in st boxed, the underlayer fd. - */ + // When listener got a fd, notice server to accept it. + // @param type, the client type, used to create concrete connection, + // for instance RTMP connection to serve client. + // @param stfd, the client fd in st boxed, the underlayer fd. virtual srs_error_t accept_client(SrsListenerType type, srs_netfd_t stfd); private: virtual srs_error_t fd2conn(SrsListenerType type, srs_netfd_t stfd, SrsConnection** pconn); - // IConnectionManager +// interface IConnectionManager public: - /** - * callback for connection to remove itself. - * when connection thread cycle terminated, callback this to delete connection. - * @see SrsConnection.on_thread_stop(). - */ + // A callback for connection to remove itself. + // When connection thread cycle terminated, callback this to delete connection. + // @see SrsConnection.on_thread_stop(). virtual void remove(ISrsConnection* c); // interface ISrsReloadHandler. public: diff --git a/trunk/src/app/srs_app_source.hpp b/trunk/src/app/srs_app_source.hpp index a4c50d96d..bed9850bf 100644 --- a/trunk/src/app/srs_app_source.hpp +++ b/trunk/src/app/srs_app_source.hpp @@ -61,12 +61,10 @@ class SrsBuffer; class SrsHds; #endif -/** - * the time jitter algorithm: - * 1. full, to ensure stream start at zero, and ensure stream monotonically increasing. - * 2. zero, only ensure sttream start at zero, ignore timestamp jitter. - * 3. off, disable the time jitter algorithm, like atc. - */ +// The time jitter algorithm: +// 1. full, to ensure stream start at zero, and ensure stream monotonically increasing. +// 2. zero, only ensure sttream start at zero, ignore timestamp jitter. +// 3. off, disable the time jitter algorithm, like atc. enum SrsRtmpJitterAlgorithm { SrsRtmpJitterAlgorithmFULL = 0x01, @@ -75,10 +73,7 @@ enum SrsRtmpJitterAlgorithm }; int _srs_time_jitter_string2int(std::string time_jitter); -/** - * time jitter detect and correct, - * to ensure the rtmp stream is monotonically. - */ +// Time jitter detect and correct, to ensure the rtmp stream is monotonically. class SrsRtmpJitter { private: @@ -88,23 +83,16 @@ public: SrsRtmpJitter(); virtual ~SrsRtmpJitter(); public: - /** - * detect the time jitter and correct it. - * @param ag the algorithm to use for time jitter. - */ + // detect the time jitter and correct it. + // @param ag the algorithm to use for time jitter. virtual srs_error_t correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag); - /** - * get current client time, the last packet time. - */ + // Get current client time, the last packet time. virtual int64_t get_time(); }; #ifdef SRS_PERF_QUEUE_FAST_VECTOR -/** - * to alloc and increase fixed space, - * fast remove and insert for msgs sender. - * @see https://github.com/ossrs/srs/issues/251 - */ +// To alloc and increase fixed space, fast remove and insert for msgs sender. +// @see https://github.com/ossrs/srs/issues/251 class SrsFastVector { private: @@ -127,10 +115,8 @@ public: }; #endif -/** - * the message queue for the consumer(client), forwarder. - * we limit the size in seconds, drop old messages(the whole gop) if full. - */ +// The message queue for the consumer(client), forwarder. +// We limit the size in seconds, drop old messages(the whole gop) if full. class SrsMessageQueue { private: @@ -151,85 +137,63 @@ public: SrsMessageQueue(bool ignore_shrink = false); virtual ~SrsMessageQueue(); public: - /** - * get the size of queue. - */ + // Get the size of queue. virtual int size(); - /** - * get the duration of queue. - */ + // Get the duration of queue. virtual srs_utime_t duration(); - /** - * set the queue size - * @param queue_size the queue size in srs_utime_t. - */ + // Set the queue size + // @param queue_size the queue size in srs_utime_t. virtual void set_queue_size(srs_utime_t queue_size); public: - /** - * enqueue the message, the timestamp always monotonically. - * @param msg, the msg to enqueue, user never free it whatever the return code. - * @param is_overflow, whether overflow and shrinked. NULL to ignore. - */ + // Enqueue the message, the timestamp always monotonically. + // @param msg, the msg to enqueue, user never free it whatever the return code. + // @param is_overflow, whether overflow and shrinked. NULL to ignore. virtual srs_error_t enqueue(SrsSharedPtrMessage* msg, bool* is_overflow = NULL); - /** - * get packets in consumer queue. - * @pmsgs SrsSharedPtrMessage*[], used to store the msgs, user must alloc it. - * @count the count in array, output param. - * @max_count the max count to dequeue, must be positive. - */ + // Get packets in consumer queue. + // @pmsgs SrsSharedPtrMessage*[], used to store the msgs, user must alloc it. + // @count the count in array, output param. + // @max_count the max count to dequeue, must be positive. virtual srs_error_t dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, int& count); - /** - * dumps packets to consumer, use specified args. - * @remark the atc/tba/tbv/ag are same to SrsConsumer.enqueue(). - */ + // Dumps packets to consumer, use specified args. + // @remark the atc/tba/tbv/ag are same to SrsConsumer.enqueue(). virtual srs_error_t dump_packets(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm ag); private: - /** - * remove a gop from the front. - * if no iframe found, clear it. - */ + // Remove a gop from the front. + // if no iframe found, clear it. virtual void shrink(); public: - /** - * clear all messages in queue. - */ + // clear all messages in queue. virtual void clear(); }; -/** - * the wakable used for some object - * which is waiting on cond. - */ +// The wakable used for some object +// which is waiting on cond. class ISrsWakable { public: ISrsWakable(); virtual ~ISrsWakable(); public: - /** - * when the consumer(for player) got msg from recv thread, - * it must be processed for maybe it's a close msg, so the cond - * wait must be wakeup. - */ + // when the consumer(for player) got msg from recv thread, + // it must be processed for maybe it's a close msg, so the cond + // wait must be wakeup. virtual void wakeup() = 0; }; -/** - * the consumer for SrsSource, that is a play client. - */ +// The consumer for SrsSource, that is a play client. class SrsConsumer : public ISrsWakable { private: SrsRtmpJitter* jitter; SrsSource* source; SrsMessageQueue* queue; - // the owner connection for debug, maybe NULL. + // The owner connection for debug, maybe NULL. SrsConnection* conn; bool paused; // when source id changed, notice all consumers bool should_update_source_id; #ifdef SRS_PERF_QUEUE_COND_WAIT - // the cond wait for mw. + // The cond wait for mw. // @see https://github.com/ossrs/srs/issues/251 srs_cond_t mw_wait; bool mw_waiting; @@ -240,159 +204,109 @@ public: SrsConsumer(SrsSource* s, SrsConnection* c); virtual ~SrsConsumer(); public: - /** - * set the size of queue. - */ + // Set the size of queue. virtual void set_queue_size(srs_utime_t queue_size); - /** - * when source id changed, notice client to print. - */ + // when source id changed, notice client to print. virtual void update_source_id(); public: - /** - * get current client time, the last packet time. - */ + // Get current client time, the last packet time. virtual int64_t get_time(); - /** - * enqueue an shared ptr message. - * @param shared_msg, directly ptr, copy it if need to save it. - * @param whether atc, donot use jitter correct if true. - * @param ag the algorithm of time jitter. - */ + // Enqueue an shared ptr message. + // @param shared_msg, directly ptr, copy it if need to save it. + // @param whether atc, donot use jitter correct if true. + // @param ag the algorithm of time jitter. virtual srs_error_t enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitterAlgorithm ag); - /** - * get packets in consumer queue. - * @param msgs the msgs array to dump packets to send. - * @param count the count in array, intput and output param. - * @remark user can specifies the count to get specified msgs; 0 to get all if possible. - */ + // Get packets in consumer queue. + // @param msgs the msgs array to dump packets to send. + // @param count the count in array, intput and output param. + // @remark user can specifies the count to get specified msgs; 0 to get all if possible. virtual srs_error_t dump_packets(SrsMessageArray* msgs, int& count); #ifdef SRS_PERF_QUEUE_COND_WAIT - /** - * wait for messages incomming, atleast nb_msgs and in duration. - * @param nb_msgs the messages count to wait. - * @param msgs_duration the messages duration to wait. - */ + // wait for messages incomming, atleast nb_msgs and in duration. + // @param nb_msgs the messages count to wait. + // @param msgs_duration the messages duration to wait. virtual void wait(int nb_msgs, srs_utime_t msgs_duration); #endif - /** - * when client send the pause message. - */ + // when client send the pause message. virtual srs_error_t on_play_client_pause(bool is_pause); // ISrsWakable public: - /** - * when the consumer(for player) got msg from recv thread, - * it must be processed for maybe it's a close msg, so the cond - * wait must be wakeup. - */ + // when the consumer(for player) got msg from recv thread, + // it must be processed for maybe it's a close msg, so the cond + // wait must be wakeup. virtual void wakeup(); }; -/** - * cache a gop of video/audio data, - * delivery at the connect of flash player, - * to enable it to fast startup. - */ +// cache a gop of video/audio data, +// delivery at the connect of flash player, +// To enable it to fast startup. class SrsGopCache { private: - /** - * if disabled the gop cache, - * the client will wait for the next keyframe for h264, - * and will be black-screen. - */ + // if disabled the gop cache, + // The client will wait for the next keyframe for h264, + // and will be black-screen. bool enable_gop_cache; - /** - * the video frame count, avoid cache for pure audio stream. - */ + // The video frame count, avoid cache for pure audio stream. int cached_video_count; - /** - * when user disabled video when publishing, and gop cache enalbed, - * we will cache the audio/video for we already got video, but we never - * know when to clear the gop cache, for there is no video in future, - * so we must guess whether user disabled the video. - * when we got some audios after laster video, for instance, 600 audio packets, - * about 3s(26ms per packet) 115 audio packets, clear gop cache. - * - * @remark, it is ok for performance, for when we clear the gop cache, - * gop cache is disabled for pure audio stream. - * @see: https://github.com/ossrs/srs/issues/124 - */ + // when user disabled video when publishing, and gop cache enalbed, + // We will cache the audio/video for we already got video, but we never + // know when to clear the gop cache, for there is no video in future, + // so we must guess whether user disabled the video. + // when we got some audios after laster video, for instance, 600 audio packets, + // about 3s(26ms per packet) 115 audio packets, clear gop cache. + // + // @remark, it is ok for performance, for when we clear the gop cache, + // gop cache is disabled for pure audio stream. + // @see: https://github.com/ossrs/srs/issues/124 int audio_after_last_video_count; - /** - * cached gop. - */ + // cached gop. std::vector gop_cache; public: SrsGopCache(); virtual ~SrsGopCache(); public: - /** - * cleanup when system quit. - */ + // cleanup when system quit. virtual void dispose(); - /** - * to enable or disable the gop cache. - */ + // To enable or disable the gop cache. virtual void set(bool v); virtual bool enabled(); - /** - * only for h264 codec - * 1. cache the gop when got h264 video packet. - * 2. clear gop when got keyframe. - * @param shared_msg, directly ptr, copy it if need to save it. - */ + // only for h264 codec + // 1. cache the gop when got h264 video packet. + // 2. clear gop when got keyframe. + // @param shared_msg, directly ptr, copy it if need to save it. virtual srs_error_t cache(SrsSharedPtrMessage* shared_msg); - /** - * clear the gop cache. - */ + // clear the gop cache. virtual void clear(); - /** - * dump the cached gop to consumer. - */ + // dump the cached gop to consumer. virtual srs_error_t dump(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm jitter_algorithm); - /** - * used for atc to get the time of gop cache, - * the atc will adjust the sequence header timestamp to gop cache. - */ + // used for atc to get the time of gop cache, + // The atc will adjust the sequence header timestamp to gop cache. virtual bool empty(); - /** - * get the start time of gop cache, in srs_utime_t. - * @return 0 if no packets. - */ + // Get the start time of gop cache, in srs_utime_t. + // @return 0 if no packets. virtual srs_utime_t start_time(); - /** - * whether current stream is pure audio, - * when no video in gop cache, the stream is pure audio right now. - */ + // whether current stream is pure audio, + // when no video in gop cache, the stream is pure audio right now. virtual bool pure_audio(); }; -/** - * the handler to handle the event of srs source. - * for example, the http flv streaming module handle the event and - * mount http when rtmp start publishing. - */ +// The handler to handle the event of srs source. +// For example, the http flv streaming module handle the event and +// mount http when rtmp start publishing. class ISrsSourceHandler { public: ISrsSourceHandler(); virtual ~ISrsSourceHandler(); public: - /** - * when stream start publish, mount stream. - */ + // when stream start publish, mount stream. virtual srs_error_t on_publish(SrsSource* s, SrsRequest* r) = 0; - /** - * when stream stop publish, unmount stream. - */ + // when stream stop publish, unmount stream. virtual void on_unpublish(SrsSource* s, SrsRequest* r) = 0; }; -/** - * the mix queue to correct the timestamp for mix_correct algorithm. - */ +// The mix queue to correct the timestamp for mix_correct algorithm. class SrsMixQueue { private: @@ -408,11 +322,9 @@ public: virtual SrsSharedPtrMessage* pop(); }; -/** - * The hub for origin is a collection of utilities for origin only, - * for example, DVR, HLS, Forward and Transcode are only available for origin, - * they are meanless for edge server. - */ +// The hub for origin is a collection of utilities for origin only, +// For example, DVR, HLS, Forward and Transcode are only available for origin, +// they are meanless for edge server. class SrsOriginHub : public ISrsReloadHandler { private: @@ -437,7 +349,7 @@ private: #endif // nginx-rtmp exec feature. SrsNgExec* ng_exec; - // to forward stream to other servers + // To forward stream to other servers std::vector forwarders; public: SrsOriginHub(); @@ -447,10 +359,10 @@ public: // @param r The request object, managed by source. virtual srs_error_t initialize(SrsSource* s, SrsRequest* r); // Dispose the hub, release utilities resource, - // for example, delete all HLS pieces. + // For example, delete all HLS pieces. virtual void dispose(); // Cycle the hub, process some regular events, - // for example, dispose hls in cycle. + // For example, dispose hls in cycle. virtual srs_error_t cycle(); public: // When got a parsed metadata. @@ -466,9 +378,9 @@ public: virtual void on_unpublish(); // Internal callback. public: - // for the SrsForwarder to callback to request the sequence headers. + // For the SrsForwarder to callback to request the sequence headers. virtual srs_error_t on_forwarder_start(SrsForwarder* forwarder); - // for the SrsDvr to callback to request the sequence headers. + // For the SrsDvr to callback to request the sequence headers. virtual srs_error_t on_dvr_request_sh(); // interface ISrsReloadHandler public: @@ -484,10 +396,8 @@ private: virtual void destroy_forwarders(); }; -/** - * Each stream have optional meta(sps/pps in sequence header and metadata). - * This class cache and update the meta. - */ +// Each stream have optional meta(sps/pps in sequence header and metadata). +// This class cache and update the meta. class SrsMetaCache { private: @@ -528,46 +438,35 @@ public: virtual srs_error_t update_vsh(SrsSharedPtrMessage* msg); }; -/** - * live streaming source. - */ +// live streaming source. class SrsSource : public ISrsReloadHandler { friend class SrsOriginHub; private: static std::map pool; public: - /** - * create source when fetch from cache failed. - * @param r the client request. - * @param h the event handler for source. - * @param pps the matched source, if success never be NULL. - */ + // create source when fetch from cache failed. + // @param r the client request. + // @param h the event handler for source. + // @param pps the matched source, if success never be NULL. static srs_error_t fetch_or_create(SrsRequest* r, ISrsSourceHandler* h, SrsSource** pps); private: - /** - * get the exists source, NULL when not exists. - * update the request and return the exists source. - */ + // Get the exists source, NULL when not exists. + // update the request and return the exists source. static SrsSource* fetch(SrsRequest* r); public: - /** - * dispose and cycle all sources. - */ + // dispose and cycle all sources. static void dispose_all(); static srs_error_t cycle_all(); private: static srs_error_t do_cycle_all(); public: - /** - * when system exit, destroy the sources, - * for gmc to analysis mem leaks. - */ + // when system exit, destroy the sources, + // For gmc to analysis mem leaks. static void destroy(); private: - // source id, - // for publish, it's the publish client id. - // for edge, it's the edge ingest id. + // For publish, it's the publish client id. + // For edge, it's the edge ingest id. // when source id changed, for example, the edge reconnect, // invoke the on_source_id_changed() to let all clients know. int _source_id; @@ -575,31 +474,29 @@ private: int _pre_source_id; // deep copy of client request. SrsRequest* req; - // to delivery stream to clients. + // To delivery stream to clients. std::vector consumers; - // the time jitter algorithm for vhost. + // The time jitter algorithm for vhost. SrsRtmpJitterAlgorithm jitter_algorithm; - // for play, whether use interlaced/mixed algorithm to correct timestamp. + // For play, whether use interlaced/mixed algorithm to correct timestamp. bool mix_correct; - // the mix queue to implements the mix correct algorithm. + // The mix queue to implements the mix correct algorithm. SrsMixQueue* mix_queue; - /** - * for play, whether enabled atc. - * atc whether atc(use absolute time and donot adjust time), - * directly use msg time and donot adjust if atc is true, - * otherwise, adjust msg time to start from 0 to make flash happy. - */ + // For play, whether enabled atc. + // The atc(use absolute time and donot adjust time), + // directly use msg time and donot adjust if atc is true, + // otherwise, adjust msg time to start from 0 to make flash happy. bool atc; // whether stream is monotonically increase. bool is_monotonically_increase; - // the time of the packet we just got. + // The time of the packet we just got. int64_t last_packet_time; - // the event handler. + // The event handler. ISrsSourceHandler* handler; - // edge control service + // The edge control service SrsPlayEdge* play_edge; SrsPublishEdge* publish_edge; - // gop cache for client fast startup. + // The gop cache for client fast startup. SrsGopCache* gop_cache; // The hub for origin server. SrsOriginHub* hub; @@ -609,7 +506,7 @@ private: // Whether source is avaiable for publishing. bool _can_publish; // The last die time, when all consumers quit and no publisher, - // we will remove the source when source die. + // We will remove the source when source die. srs_utime_t die_at; public: SrsSource(); @@ -617,26 +514,23 @@ public: public: virtual void dispose(); virtual srs_error_t cycle(); - // remove source when expired. + // Remove source when expired. virtual bool expired(); -// initialize, get and setter. public: - // initialize the hls with handlers. + // Initialize the hls with handlers. virtual srs_error_t initialize(SrsRequest* r, ISrsSourceHandler* h); // interface ISrsReloadHandler public: virtual srs_error_t on_reload_vhost_play(std::string vhost); -// for the tools callback public: - // source id changed. + // The source id changed. virtual srs_error_t on_source_id_changed(int id); - // get current source id. + // Get current source id. virtual int source_id(); virtual int pre_source_id(); // Whether source is inactive, which means there is no publishing stream source. // @remark For edge, it's inactive util stream has been pulled from origin. virtual bool inactive(); -// logic data methods public: virtual bool can_publish(bool is_edge); virtual srs_error_t on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata); @@ -650,33 +544,27 @@ private: virtual srs_error_t on_video_imp(SrsSharedPtrMessage* video); public: virtual srs_error_t on_aggregate(SrsCommonMessage* msg); - /** - * publish stream event notify. - * @param _req the request from client, the source will deep copy it, - * for when reload the request of client maybe invalid. - */ + // Publish stream event notify. + // @param _req the request from client, the source will deep copy it, + // for when reload the request of client maybe invalid. virtual srs_error_t on_publish(); virtual void on_unpublish(); -// consumer methods public: - /** - * create consumer and dumps packets in cache. - * @param consumer, output the create consumer. - * @param ds, whether dumps the sequence header. - * @param dm, whether dumps the metadata. - * @param dg, whether dumps the gop cache. - */ + // Create consumer and dumps packets in cache. + // @param consumer, output the create consumer. + // @param ds, whether dumps the sequence header. + // @param dm, whether dumps the metadata. + // @param dg, whether dumps the gop cache. virtual srs_error_t create_consumer(SrsConnection* conn, SrsConsumer*& consumer, bool ds = true, bool dm = true, bool dg = true); virtual void on_consumer_destroy(SrsConsumer* consumer); virtual void set_cache(bool enabled); virtual SrsRtmpJitterAlgorithm jitter(); -// internal public: - // for edge, when publish edge stream, check the state + // For edge, when publish edge stream, check the state virtual srs_error_t on_edge_start_publish(); - // for edge, proxy the publish + // For edge, proxy the publish virtual srs_error_t on_edge_proxy_publish(SrsCommonMessage* msg); - // for edge, proxy stop publish + // For edge, proxy stop publish virtual void on_edge_proxy_unpublish(); public: virtual std::string get_curr_origin(); diff --git a/trunk/src/app/srs_app_statistic.hpp b/trunk/src/app/srs_app_statistic.hpp index c9d5661c0..c9e475ace 100644 --- a/trunk/src/app/srs_app_statistic.hpp +++ b/trunk/src/app/srs_app_statistic.hpp @@ -48,9 +48,7 @@ public: int nb_streams; int nb_clients; public: - /** - * vhost total kbps. - */ + // The vhost total kbps. SrsKbps* kbps; SrsWallClock* clk; public: @@ -73,19 +71,17 @@ public: int nb_clients; uint64_t nb_frames; public: - /** - * stream total kbps. - */ + // The stream total kbps. SrsKbps* kbps; SrsWallClock* clk; public: bool has_video; SrsVideoCodecId vcodec; - // profile_idc, ISO_IEC_14496-10-AVC-2003.pdf, page 45. + // The profile_idc, ISO_IEC_14496-10-AVC-2003.pdf, page 45. SrsAvcProfile avc_profile; - // level_idc, ISO_IEC_14496-10-AVC-2003.pdf, page 45. + // The level_idc, ISO_IEC_14496-10-AVC-2003.pdf, page 45. SrsAvcLevel avc_level; - // the width and height in codec info. + // The width and height in codec info. int width; int height; public: @@ -93,12 +89,10 @@ public: SrsAudioCodecId acodec; SrsAudioSampleRate asample_rate; SrsAudioChannels asound_type; - /** - * audio specified - * audioObjectType, in 1.6.2.1 AudioSpecificConfig, page 33, - * 1.5.1.1 Audio object type definition, page 23, - * in ISO_IEC_14496-3-AAC-2001.pdf. - */ + // The audio specified + // audioObjectType, in 1.6.2.1 AudioSpecificConfig, page 33, + // 1.5.1.1 Audio object type definition, page 23, + // in ISO_IEC_14496-3-AAC-2001.pdf. SrsAacObjectType aac_object; public: SrsStatisticStream(); @@ -106,13 +100,9 @@ public: public: virtual srs_error_t dumps(SrsJsonObject* obj); public: - /** - * publish the stream. - */ + // Publish the stream. virtual void publish(int cid); - /** - * close the stream. - */ + // Close the stream. virtual void close(); }; @@ -136,24 +126,24 @@ class SrsStatistic { private: static SrsStatistic *_instance; - // the id to identify the sever. + // The id to identify the sever. int64_t _server_id; private: - // key: vhost id, value: vhost object. + // The key: vhost id, value: vhost object. std::map vhosts; - // key: vhost url, value: vhost Object. + // The key: vhost url, value: vhost Object. // @remark a fast index for vhosts. std::map rvhosts; private: - // key: stream id, value: stream Object. + // The key: stream id, value: stream Object. std::map streams; - // key: stream url, value: stream Object. + // The key: stream url, value: stream Object. // @remark a fast index for streams. std::map rstreams; private: - // key: client id, value: stream object. + // The key: client id, value: stream object. std::map clients; - // server total kbps. + // The server total kbps. SrsKbps* kbps; SrsWallClock* clk; private: @@ -167,77 +157,51 @@ public: virtual SrsStatisticStream* find_stream(int sid); virtual SrsStatisticClient* find_client(int cid); public: - /** - * when got video info for stream. - */ + // When got video info for stream. virtual srs_error_t on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level, int width, int height); - /** - * when got audio info for stream. - */ + // When got audio info for stream. virtual srs_error_t on_audio_info(SrsRequest* req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, SrsAacObjectType aac_object); - /** - * When got videos, update the frames. - * We only stat the total number of video frames. - */ + // When got videos, update the frames. + // We only stat the total number of video frames. virtual srs_error_t on_video_frames(SrsRequest* req, int nb_frames); - /** - * when publish stream. - * @param req the request object of publish connection. - * @param cid the cid of publish connection. - */ + // When publish stream. + // @param req the request object of publish connection. + // @param cid the cid of publish connection. virtual void on_stream_publish(SrsRequest* req, int cid); - /** - * when close stream. - */ + // When close stream. virtual void on_stream_close(SrsRequest* req); public: - /** - * when got a client to publish/play stream, - * @param id, the client srs id. - * @param req, the client request object. - * @param conn, the physical absract connection object. - * @param type, the type of connection. - */ + // When got a client to publish/play stream, + // @param id, the client srs id. + // @param req, the client request object. + // @param conn, the physical absract connection object. + // @param type, the type of connection. virtual srs_error_t on_client(int id, SrsRequest* req, SrsConnection* conn, SrsRtmpConnType type); - /** - * client disconnect - * @remark the on_disconnect always call, while the on_client is call when - * only got the request object, so the client specified by id maybe not - * exists in stat. - */ + // Client disconnect + // @remark the on_disconnect always call, while the on_client is call when + // only got the request object, so the client specified by id maybe not + // exists in stat. virtual void on_disconnect(int id); - /** - * sample the kbps, add delta bytes of conn. - * use kbps_sample() to get all result of kbps stat. - */ + // Sample the kbps, add delta bytes of conn. + // Use kbps_sample() to get all result of kbps stat. // TODO: FIXME: the add delta must use ISrsKbpsDelta interface instead. virtual void kbps_add_delta(SrsConnection* conn); - /** - * calc the result for all kbps. - * @return the server kbps. - */ + // Calc the result for all kbps. + // @return the server kbps. virtual SrsKbps* kbps_sample(); public: - /** - * get the server id, used to identify the server. - * for example, when restart, the server id must changed. - */ + // Get the server id, used to identify the server. + // For example, when restart, the server id must changed. virtual int64_t server_id(); - /** - * dumps the vhosts to amf0 array. - */ + // Dumps the vhosts to amf0 array. virtual srs_error_t dumps_vhosts(SrsJsonArray* arr); - /** - * dumps the streams to amf0 array. - */ + // Dumps the streams to amf0 array. virtual srs_error_t dumps_streams(SrsJsonArray* arr); - /** - * dumps the clients to amf0 array - * @param start the start index, from 0. - * @param count the max count of clients to dump. - */ + // Dumps the clients to amf0 array + // @param start the start index, from 0. + // @param count the max count of clients to dump. virtual srs_error_t dumps_clients(SrsJsonArray* arr, int start, int count); private: virtual SrsStatisticVhost* create_vhost(SrsRequest* req); diff --git a/trunk/src/app/srs_app_thread.hpp b/trunk/src/app/srs_app_thread.hpp index 4c55cc4c4..f02deb8d2 100644 --- a/trunk/src/app/srs_app_thread.hpp +++ b/trunk/src/app/srs_app_thread.hpp @@ -31,12 +31,10 @@ #include #include -/** - * The coroutine manager use a thread to delete a connection, which will stop the service - * thread, for example, when the RTMP connection thread cycle terminated, it will notify - * the manager(the server) to remove the connection from list of server and push it to - * the manager thread to delete it, finally the thread of connection will stop. - */ +// The coroutine manager use a thread to delete a connection, which will stop the service +// thread, for example, when the RTMP connection thread cycle terminated, it will notify +// the manager(the server) to remove the connection from list of server and push it to +// the manager thread to delete it, finally the thread of connection will stop. class SrsCoroutineManager : virtual public ISrsCoroutineHandler, virtual public IConnectionManager { private: @@ -48,10 +46,10 @@ public: virtual ~SrsCoroutineManager(); public: srs_error_t start(); -// ISrsCoroutineHandler +// interface ISrsCoroutineHandler public: virtual srs_error_t cycle(); -// IConnectionManager +// interface IConnectionManager public: virtual void remove(ISrsConnection* c); private: diff --git a/trunk/src/app/srs_app_utility.hpp b/trunk/src/app/srs_app_utility.hpp index 82cdfb45e..2cf3ee54c 100644 --- a/trunk/src/app/srs_app_utility.hpp +++ b/trunk/src/app/srs_app_utility.hpp @@ -41,51 +41,43 @@ class SrsKbps; class SrsBuffer; class SrsJsonObject; -/** - * convert level in string to log level in int. - * @return the log level defined in SrsLogLevel. - */ +// Convert level in string to log level in int. +// @return the log level defined in SrsLogLevel. extern SrsLogLevel srs_get_log_level(std::string level); -/** - * build the path according to vhost/app/stream, where replace variables: - * [vhost], the vhost of stream. - * [app], the app of stream. - * [stream], the stream name of stream. - * @return the replaced path. - */ +// Build the path according to vhost/app/stream, where replace variables: +// [vhost], the vhost of stream. +// [app], the app of stream. +// [stream], the stream name of stream. +// @return the replaced path. extern std::string srs_path_build_stream(std::string template_path, std::string vhost, std::string app, std::string stream); -/** - * build the path according to timestamp, where replace variables: - * [2006], replace this const to current year. - * [01], replace this const to current month. - * [02], replace this const to current date. - * [15], replace this const to current hour. - * [04], repleace this const to current minute. - * [05], repleace this const to current second. - * [999], repleace this const to current millisecond. - * [timestamp],replace this const to current UNIX timestamp in ms. - * @return the replaced path. - */ +// Build the path according to timestamp, where replace variables: +// [2006], replace this const to current year. +// [01], replace this const to current month. +// [02], replace this const to current date. +// [15], replace this const to current hour. +// [04], repleace this const to current minute. +// [05], repleace this const to current second. +// [999], repleace this const to current millisecond. +// [timestamp],replace this const to current UNIX timestamp in ms. +// @return the replaced path. extern std::string srs_path_build_timestamp(std::string template_path); -/** - * kill the pid by SIGINT, then wait to quit, - * kill the pid by SIGKILL again when exceed the timeout. - * @param pid the pid to kill. ignore for -1. set to -1 when killed. - * @return an int error code. - */ +// Kill the pid by SIGINT, then wait to quit, +// Kill the pid by SIGKILL again when exceed the timeout. +// @param pid the pid to kill. ignore for -1. set to -1 when killed. +// @return an int error code. extern srs_error_t srs_kill_forced(int& pid); -// current process resouce usage. +// Current process resouce usage. // @see: man getrusage class SrsRusage { public: - // whether the data is ok. + // Whether the data is ok. bool ok; - // the time in ms when sample. + // The time in ms when sample. int64_t sample_time; public: @@ -95,21 +87,21 @@ public: SrsRusage(); }; -// get system rusage, use cache to avoid performance problem. +// Get system rusage, use cache to avoid performance problem. extern SrsRusage* srs_get_system_rusage(); -// the deamon st-thread will update it. +// The deamon st-thread will update it. extern void srs_update_system_rusage(); -// to stat the process info. +// To stat the process info. // @see: man 5 proc, /proc/[pid]/stat class SrsProcSelfStat { public: - // whether the data is ok. + // Whether the data is ok. bool ok; - // the time in ms when sample. + // The time in ms when sample. int64_t sample_time; - // the percent of usage. 0.153 is 15.3%. + // The percent of usage. 0.153 is 15.3%. float percent; // data of /proc/[pid]/stat @@ -256,49 +248,47 @@ public: SrsProcSelfStat(); }; -// to stat the cpu time. +// To stat the cpu time. // @see: man 5 proc, /proc/stat -/** - * about the cpu time, @see: http://stackoverflow.com/questions/16011677/calculating-cpu-usage-using-proc-files - * for example, for ossrs.net, a single cpu machine: - * [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat - * 5275153.01 4699624.99 - * cpu 43506750 973 8545744 466133337 4149365 190852 804666 0 0 - * where the uptime is 5275153.01s - * generally, USER_HZ sysconf(_SC_CLK_TCK)=100, which means the unit of /proc/stat is "1/100ths seconds" - * that is, USER_HZ=1/100 seconds - * cpu total = 43506750+973+8545744+466133337+4149365+190852+804666+0+0 (USER_HZ) - * = 523331687 (USER_HZ) - * = 523331687 * 1/100 (seconds) - * = 5233316.87 seconds - * the cpu total seconds almost the uptime, the delta is more precise. - * - * we run the command about 26minutes: - * [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat - * 5276739.83 4701090.76 - * cpu 43514105 973 8548948 466278556 4150480 190899 804937 0 0 - * where the uptime is 5276739.83s - * cpu total = 43514105+973+8548948+466278556+4150480+190899+804937+0+0 (USER_HZ) - * = 523488898 (USER_HZ) - * = 523488898 * 1/100 (seconds) - * = 5234888.98 seconds - * where: - * uptime delta = 1586.82s - * cpu total delta = 1572.11s - * the deviation is more smaller. - */ +// about the cpu time, @see: http://stackoverflow.com/questions/16011677/calculating-cpu-usage-using-proc-files +// for example, for ossrs.net, a single cpu machine: +// [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat +// 5275153.01 4699624.99 +// cpu 43506750 973 8545744 466133337 4149365 190852 804666 0 0 +// Where the uptime is 5275153.01s +// generally, USER_HZ sysconf(_SC_CLK_TCK)=100, which means the unit of /proc/stat is "1/100ths seconds" +// that is, USER_HZ=1/100 seconds +// cpu total = 43506750+973+8545744+466133337+4149365+190852+804666+0+0 (USER_HZ) +// = 523331687 (USER_HZ) +// = 523331687 * 1/100 (seconds) +// = 5233316.87 seconds +// The cpu total seconds almost the uptime, the delta is more precise. +// +// we run the command about 26minutes: +// [winlin@SRS ~]$ cat /proc/uptime && cat /proc/stat +// 5276739.83 4701090.76 +// cpu 43514105 973 8548948 466278556 4150480 190899 804937 0 0 +// Where the uptime is 5276739.83s +// cpu total = 43514105+973+8548948+466278556+4150480+190899+804937+0+0 (USER_HZ) +// = 523488898 (USER_HZ) +// = 523488898 * 1/100 (seconds) +// = 5234888.98 seconds +// where: +// uptime delta = 1586.82s +// cpu total delta = 1572.11s +// The deviation is more smaller. class SrsProcSystemStat { public: - // whether the data is ok. + // Whether the data is ok. bool ok; - // the time in ms when sample. + // The time in ms when sample. int64_t sample_time; - // the percent of usage. 0.153 is 15.3%. - // the percent is in [0, 1], where 1 is 100%. + // The percent of usage. 0.153 is 15.3%. + // The percent is in [0, 1], where 1 is 100%. // for multiple core cpu, max also is 100%. float percent; - // the total cpu time units + // The total cpu time units // @remark, zero for the previous total() is zero. // the usaged_cpu_delta = total_delta * percent // previous cpu total = this->total() - total_delta @@ -310,7 +300,7 @@ public: // (1/100ths of a second on most architectures, use // sysconf(_SC_CLK_TCK) to obtain the right value) // - // the system spent in user mode, + // The system spent in user mode, unsigned long long user; // user mode with low priority (nice), unsigned long long nice; @@ -341,18 +331,18 @@ public: public: SrsProcSystemStat(); - // get total cpu units. + // Get total cpu units. int64_t total(); }; -// get system cpu stat, use cache to avoid performance problem. +// Get system cpu stat, use cache to avoid performance problem. extern SrsProcSelfStat* srs_get_self_proc_stat(); -// get system cpu stat, use cache to avoid performance problem. +// Get system cpu stat, use cache to avoid performance problem. extern SrsProcSystemStat* srs_get_system_proc_stat(); -// the deamon st-thread will update it. +// The deamon st-thread will update it. extern void srs_update_proc_stat(); -// stat disk iops +// Stat disk iops // @see: http://stackoverflow.com/questions/4458183/how-the-util-of-iostat-is-computed // for total disk io, @see: cat /proc/vmstat |grep pgpg // for device disk io, @see: cat /proc/diskstats @@ -364,9 +354,9 @@ extern void srs_update_proc_stat(); class SrsDiskStat { public: - // whether the data is ok. + // Whether the data is ok. bool ok; - // the time in ms when sample. + // The time in ms when sample. int64_t sample_time; // input(read) KBytes per seconds @@ -382,10 +372,10 @@ public: public: // @see: cat /proc/vmstat - // the in(read) page count, pgpgin*1024 is the read bytes. + // The in(read) page count, pgpgin*1024 is the read bytes. // Total number of kilobytes the system paged in from disk per second. unsigned long pgpgin; - // the out(write) page count, pgpgout*1024 is the write bytes. + // The out(write) page count, pgpgout*1024 is the write bytes. // Total number of kilobytes the system paged out to disk per second. unsigned long pgpgout; @@ -415,7 +405,7 @@ public: // Write I/O operations unsigned int wr_ios; // Number of writes merged Reads and writes which are adjacent - // to each other may be merged for efficiency. Thus two 4K + // To each other may be merged for efficiency. Thus two 4K // reads may become one 8K read before it is ultimately // handed to the disk, and so it will be counted (and queued) // as only one I/O. This field lets you know how often this was done. @@ -446,7 +436,7 @@ public: // progress (field 9) times the number of milliseconds spent // doing I/O since the last update of this field. This can // provide an easy measure of both I/O completion time and - // the backlog that may be accumulating. + // The backlog that may be accumulating. // Average queue length unsigned int aveq; @@ -454,21 +444,21 @@ public: SrsDiskStat(); }; -// get disk stat, use cache to avoid performance problem. +// Get disk stat, use cache to avoid performance problem. extern SrsDiskStat* srs_get_disk_stat(); -// the deamon st-thread will update it. +// The deamon st-thread will update it. extern void srs_update_disk_stat(); -// stat system memory info +// Stat system memory info // @see: cat /proc/meminfo class SrsMemInfo { public: - // whether the data is ok. + // Whether the data is ok. bool ok; - // the time in ms when sample. + // The time in ms when sample. int64_t sample_time; - // the percent of usage. 0.153 is 15.3%. + // The percent of usage. 0.153 is 15.3%. float percent_ram; float percent_swap; @@ -495,9 +485,9 @@ public: SrsMemInfo(); }; -// get system meminfo, use cache to avoid performance problem. +// Get system meminfo, use cache to avoid performance problem. extern SrsMemInfo* srs_get_meminfo(); -// the deamon st-thread will update it. +// The deamon st-thread will update it. extern void srs_update_meminfo(); // system cpu hardware info. @@ -506,7 +496,7 @@ extern void srs_update_meminfo(); class SrsCpuInfo { public: - // whether the data is ok. + // Whether the data is ok. bool ok; // data of /proc/cpuinfo @@ -520,14 +510,14 @@ public: SrsCpuInfo(); }; -// get system cpu info, use cache to avoid performance problem. +// Get system cpu info, use cache to avoid performance problem. extern SrsCpuInfo* srs_get_cpuinfo(); -// platform(os, srs) uptime/load summary +// The platform(os, srs) uptime/load summary class SrsPlatformInfo { public: - // whether the data is ok. + // Whether the data is ok. bool ok; // srs startup time, in ms. @@ -551,22 +541,21 @@ public: SrsPlatformInfo(); }; -// get platform info, use cache to avoid performance problem. +// Get platform info, use cache to avoid performance problem. extern SrsPlatformInfo* srs_get_platform_info(); -// the deamon st-thread will update it. +// The deamon st-thread will update it. extern void srs_update_platform_info(); -// network device summary for each network device, -// for example, eth0, eth1, ethN +// The network device summary for each network device, for example, eth0, eth1, ethN class SrsNetworkDevices { public: - // whether the network device is ok. + // Whether the network device is ok. bool ok; // 6-chars interfaces name char name[7]; - // the sample time in ms. + // The sample time in ms. int64_t sample_time; public: @@ -594,20 +583,20 @@ public: SrsNetworkDevices(); }; -// get network devices info, use cache to avoid performance problem. +// Get network devices info, use cache to avoid performance problem. extern SrsNetworkDevices* srs_get_network_devices(); extern int srs_get_network_devices_count(); -// the deamon st-thread will update it. +// The deamon st-thread will update it. extern void srs_update_network_devices(); -// system connections, and srs rtmp network summary +// The system connections, and srs rtmp network summary class SrsNetworkRtmpServer { public: - // whether the network device is ok. + // Whether the network device is ok. bool ok; - // the sample time in ms. + // The sample time in ms. int64_t sample_time; public: @@ -638,32 +627,32 @@ public: SrsNetworkRtmpServer(); }; -// get network devices info, use cache to avoid performance problem. +// Get network devices info, use cache to avoid performance problem. extern SrsNetworkRtmpServer* srs_get_network_rtmp_server(); -// the deamon st-thread will update it. +// The deamon st-thread will update it. extern void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps); -// get local or peer ip. -// where local ip is the server ip which client connected. +// Get local or peer ip. +// Where local ip is the server ip which client connected. extern std::string srs_get_local_ip(int fd); -// get the local id port. +// Get the local id port. extern int srs_get_local_port(int fd); -// where peer ip is the client public ip which connected to server. +// Where peer ip is the client public ip which connected to server. extern std::string srs_get_peer_ip(int fd); -// whether string is digit number +// Whether string is digit number // is_digit("1234567890") === true // is_digit("0123456789") === false // is_digit("1234567890a") === false // is_digit("a1234567890") === false extern bool srs_is_digit_number(const std::string& str); -// whether string is boolean +// Whether string is boolean // is_bool("true") == true // is_bool("false") == true // otherwise, false. extern bool srs_is_boolean(const std::string& str); -// dump summaries for /api/v1/summaries. +// Dump summaries for /api/v1/summaries. extern void srs_api_dump_summaries(SrsJsonObject* obj); #endif From 45009785fb56b00f89064fef644a951660a136cc Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 30 Apr 2019 08:24:52 +0800 Subject: [PATCH 16/25] Refine typo in app. --- trunk/src/app/srs_app_dash.hpp | 20 +--- trunk/src/app/srs_app_dvr.hpp | 70 ++++---------- trunk/src/app/srs_app_edge.hpp | 84 +++++----------- trunk/src/app/srs_app_encoder.hpp | 6 +- trunk/src/app/srs_app_ffmpeg.hpp | 5 +- trunk/src/app/srs_app_forward.hpp | 31 ++---- trunk/src/app/srs_app_fragment.hpp | 10 +- trunk/src/app/srs_app_hds.hpp | 1 + trunk/src/app/srs_app_hourglass.hpp | 69 ++++++------- trunk/src/app/srs_app_http_api.hpp | 2 +- trunk/src/app/srs_app_http_conn.hpp | 25 ++--- trunk/src/app/srs_app_http_hooks.hpp | 109 +++++++++------------ trunk/src/app/srs_app_http_static.hpp | 16 ++- trunk/src/app/srs_app_http_stream.hpp | 84 +++++----------- trunk/src/app/srs_app_listener.hpp | 42 +++----- trunk/src/app/srs_app_log.hpp | 19 ++-- trunk/src/app/srs_app_mpegts_udp.hpp | 17 ++-- trunk/src/app/srs_app_ng_exec.hpp | 8 +- trunk/src/app/srs_app_pithy_print.hpp | 62 +++++------- trunk/src/app/srs_app_process.hpp | 88 +++++++---------- trunk/src/app/srs_app_recv_thread.hpp | 84 ++++++---------- trunk/src/app/srs_app_refer.hpp | 8 +- trunk/src/app/srs_app_reload.hpp | 12 +-- trunk/src/app/srs_app_rtmp_conn.hpp | 44 ++++----- trunk/src/app/srs_app_rtsp.hpp | 34 ++----- trunk/src/app/srs_app_security.hpp | 28 ++---- trunk/src/app/srs_app_st.hpp | 134 +++++++++++--------------- 27 files changed, 409 insertions(+), 703 deletions(-) diff --git a/trunk/src/app/srs_app_dash.hpp b/trunk/src/app/srs_app_dash.hpp index 88f9c8489..0cb6bbc46 100644 --- a/trunk/src/app/srs_app_dash.hpp +++ b/trunk/src/app/srs_app_dash.hpp @@ -40,9 +40,7 @@ class SrsMpdWriter; class SrsMp4M2tsInitEncoder; class SrsMp4M2tsSegmentEncoder; -/** - * The init mp4 for FMP4. - */ +// The init mp4 for FMP4. class SrsInitMp4 : public SrsFragment { private: @@ -56,9 +54,7 @@ public: virtual srs_error_t write(SrsFormat* format, bool video, int tid); }; -/** - * The FMP4(Fragmented MP4) for DASH streaming. - */ +// The FMP4(Fragmented MP4) for DASH streaming. class SrsFragmentedMp4 : public SrsFragment { private: @@ -76,9 +72,7 @@ public: virtual srs_error_t reap(uint64_t& dts); }; -/** - * The writer to write MPD for DASH. - */ +// The writer to write MPD for DASH. class SrsMpdWriter { private: @@ -113,9 +107,7 @@ public: virtual srs_error_t get_fragment(bool video, std::string& home, std::string& filename, int64_t& sn, srs_utime_t& basetime); }; -/** - * The controller for DASH, control the MPD and FMP4 generating system. - */ +// The controller for DASH, control the MPD and FMP4 generating system. class SrsDashController { private: @@ -149,9 +141,7 @@ private: virtual srs_error_t refresh_init_mp4(SrsSharedPtrMessage* msg, SrsFormat* format); }; -/** - * The MPEG-DASH encoder, transmux RTMP to DASH. - */ +// The MPEG-DASH encoder, transmux RTMP to DASH. class SrsDash { private: diff --git a/trunk/src/app/srs_app_dvr.hpp b/trunk/src/app/srs_app_dvr.hpp index 453f52e86..ddbb80c8b 100644 --- a/trunk/src/app/srs_app_dvr.hpp +++ b/trunk/src/app/srs_app_dvr.hpp @@ -49,9 +49,7 @@ class SrsFormat; #include #include -/** - * The segmenter for DVR, to write a segment file in flv/mp4. - */ +// The segmenter for DVR, to write a segment file in flv/mp4. class SrsDvrSegmenter : public ISrsReloadHandler { protected: @@ -110,9 +108,7 @@ public: virtual srs_error_t on_reload_vhost_dvr(std::string vhost); }; -/** - * The FLV segmenter to use FLV encoder to write file. - */ +// The FLV segmenter to use FLV encoder to write file. class SrsDvrFlvSegmenter : public SrsDvrSegmenter { private: @@ -140,9 +136,7 @@ protected: virtual srs_error_t close_encoder(); }; -/** - * The MP4 segmenter to use MP4 encoder to write file. - */ +// The MP4 segmenter to use MP4 encoder to write file. class SrsDvrMp4Segmenter : public SrsDvrSegmenter { private: @@ -161,9 +155,7 @@ protected: virtual srs_error_t close_encoder(); }; -/** - * the dvr async call. - */ +// the dvr async call. class SrsDvrAsyncCallOnDvr : public ISrsAsyncCallTask { private: @@ -178,9 +170,7 @@ public: virtual std::string to_string(); }; -/** - * The DVR plan, when and how to reap segment. - */ +// The DVR plan, when and how to reap segment. class SrsDvrPlan : public ISrsReloadHandler { public: @@ -208,9 +198,7 @@ public: static srs_error_t create_plan(std::string vhost, SrsDvrPlan** pplan); }; -/** - * The DVR session plan: reap flv when session complete(unpublish) - */ +// The DVR session plan: reap flv when session complete(unpublish) class SrsDvrSessionPlan : public SrsDvrPlan { public: @@ -221,9 +209,7 @@ public: virtual void on_unpublish(); }; -/** - * The DVR segment plan: reap flv when duration exceed. - */ +// The DVR segment plan: reap flv when duration exceed. class SrsDvrSegmentPlan : public SrsDvrPlan { private: @@ -246,9 +232,7 @@ public: virtual srs_error_t on_reload_vhost_dvr(std::string vhost); }; -/** - * DVR(Digital Video Recorder) to record RTMP stream to flv/mp4 file. - */ +// DVR(Digital Video Recorder) to record RTMP stream to flv/mp4 file. class SrsDvr : public ISrsReloadHandler { private: @@ -264,36 +248,24 @@ public: SrsDvr(); virtual ~SrsDvr(); public: - /** - * initialize dvr, create dvr plan. - * when system initialize(encoder publish at first time, or reload), - * initialize the dvr will reinitialize the plan, the whole dvr framework. - */ + // initialize dvr, create dvr plan. + // when system initialize(encoder publish at first time, or reload), + // initialize the dvr will reinitialize the plan, the whole dvr framework. virtual srs_error_t initialize(SrsOriginHub* h, SrsRequest* r); - /** - * publish stream event, - * when encoder start to publish RTMP stream. - * @param fetch_sequence_header whether fetch sequence from source. - */ + // publish stream event, + // when encoder start to publish RTMP stream. + // @param fetch_sequence_header whether fetch sequence from source. virtual srs_error_t on_publish(); - /** - * the unpublish event., - * when encoder stop(unpublish) to publish RTMP stream. - */ + // the unpublish event., + // when encoder stop(unpublish) to publish RTMP stream. virtual void on_unpublish(); - /** - * get some information from metadata, it's optinal. - */ + // get some information from metadata, it's optinal. virtual srs_error_t on_meta_data(SrsSharedPtrMessage* metadata); - /** - * mux the audio packets to dvr. - * @param shared_audio, directly ptr, copy it if need to save it. - */ + // mux the audio packets to dvr. + // @param shared_audio, directly ptr, copy it if need to save it. virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* foramt); - /** - * mux the video packets to dvr. - * @param shared_video, directly ptr, copy it if need to save it. - */ + // mux the video packets to dvr. + // @param shared_video, directly ptr, copy it if need to save it. virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format); // interface ISrsReloadHandler public: diff --git a/trunk/src/app/srs_app_edge.hpp b/trunk/src/app/srs_app_edge.hpp index ab3f2f5c5..426b47587 100644 --- a/trunk/src/app/srs_app_edge.hpp +++ b/trunk/src/app/srs_app_edge.hpp @@ -47,34 +47,28 @@ class SrsTcpClient; class SrsSimpleRtmpClient; class SrsPacket; -/** - * the state of edge, auto machine - */ +// The state of edge, auto machine enum SrsEdgeState { SrsEdgeStateInit = 0, - // for play edge + // For play edge SrsEdgeStatePlay = 100, // play stream from origin, ingest stream SrsEdgeStateIngestConnected = 101, - // for publish edge + // For publish edge SrsEdgeStatePublish = 200, }; -/** - * the state of edge from user, manual machine - */ +// The state of edge from user, manual machine enum SrsEdgeUserState { SrsEdgeUserStateInit = 0, SrsEdgeUserStateReloading = 100, }; -/** - * the upstream of edge, can be rtmp or http. - */ +// The upstream of edge, can be rtmp or http. class SrsEdgeUpstream { public: @@ -93,7 +87,7 @@ public: class SrsEdgeRtmpUpstream : public SrsEdgeUpstream { private: - // for RTMP 302, if not empty, + // For RTMP 302, if not empty, // use this as upstream. std::string redirect; SrsSimpleRtmpClient* sdk; @@ -111,9 +105,7 @@ public: virtual void kbps_sample(const char* label, int64_t age); }; -/** - * edge used to ingest stream from origin. - */ +// The edge used to ingest stream from origin. class SrsEdgeIngester : public ISrsCoroutineHandler { private: @@ -123,7 +115,7 @@ private: SrsCoroutine* trd; SrsLbRoundRobin* lb; SrsEdgeUpstream* upstream; - // for RTMP 302 redirect. + // For RTMP 302 redirect. std::string redirect; public: SrsEdgeIngester(); @@ -143,9 +135,7 @@ private: virtual srs_error_t process_publish_message(SrsCommonMessage* msg); }; -/** - * edge used to forward stream to origin. - */ +// The edge used to forward stream to origin. class SrsEdgeForwarder : public ISrsCoroutineHandler { private: @@ -155,16 +145,12 @@ private: SrsCoroutine* trd; SrsSimpleRtmpClient* sdk; SrsLbRoundRobin* lb; - /** - * we must ensure one thread one fd principle, - * that is, a fd must be write/read by the one thread. - * the publish service thread will proxy(msg), and the edge forward thread - * will cycle(), so we use queue for cycle to send the msg of proxy. - */ + // we must ensure one thread one fd principle, + // that is, a fd must be write/read by the one thread. + // The publish service thread will proxy(msg), and the edge forward thread + // will cycle(), so we use queue for cycle to send the msg of proxy. SrsMessageQueue* queue; - /** - * error code of send, for edge proxy thread to query. - */ + // error code of send, for edge proxy thread to query. int send_error_code; public: SrsEdgeForwarder(); @@ -184,10 +170,7 @@ public: virtual srs_error_t proxy(SrsCommonMessage* msg); }; -/** - * play edge control service. - * downloading edge speed-up. - */ +// The play edge control service. class SrsPlayEdge { private: @@ -197,32 +180,21 @@ public: SrsPlayEdge(); virtual ~SrsPlayEdge(); public: - /** - * always use the req of source, - * for we assume all client to edge is invalid, - * if auth open, edge must valid it from origin, then service it. - */ + // Always use the req of source, + // For we assume all client to edge is invalid, + // if auth open, edge must valid it from origin, then service it. virtual srs_error_t initialize(SrsSource* source, SrsRequest* req); - /** - * when client play stream on edge. - */ + // When client play stream on edge. virtual srs_error_t on_client_play(); - /** - * when all client stopped play, disconnect to origin. - */ + // When all client stopped play, disconnect to origin. virtual void on_all_client_stop(); virtual std::string get_curr_origin(); public: - /** - * when ingester start to play stream. - */ + // When ingester start to play stream. virtual srs_error_t on_ingest_play(); }; -/** - * publish edge control service. - * uploading edge speed-up. - */ +// The publish edge control service. class SrsPublishEdge { private: @@ -236,17 +208,11 @@ public: public: virtual srs_error_t initialize(SrsSource* source, SrsRequest* req); virtual bool can_publish(); - /** - * when client publish stream on edge. - */ + // When client publish stream on edge. virtual srs_error_t on_client_publish(); - /** - * proxy publish stream to edge - */ + // Proxy publish stream to edge virtual srs_error_t on_proxy_publish(SrsCommonMessage* msg); - /** - * proxy unpublish stream to edge. - */ + // Proxy unpublish stream to edge. virtual void on_proxy_unpublish(); }; diff --git a/trunk/src/app/srs_app_encoder.hpp b/trunk/src/app/srs_app_encoder.hpp index 8dc56d259..4417e5ab7 100644 --- a/trunk/src/app/srs_app_encoder.hpp +++ b/trunk/src/app/srs_app_encoder.hpp @@ -36,10 +36,8 @@ class SrsRequest; class SrsPithyPrint; class SrsFFMPEG; -/** - * the encoder for a stream, - * may use multiple ffmpegs to transcode the specified stream. - */ +// The encoder for a stream, may use multiple +// ffmpegs to transcode the specified stream. class SrsEncoder : public ISrsCoroutineHandler { private: diff --git a/trunk/src/app/srs_app_ffmpeg.hpp b/trunk/src/app/srs_app_ffmpeg.hpp index f3cf85b26..77c1aab1e 100644 --- a/trunk/src/app/srs_app_ffmpeg.hpp +++ b/trunk/src/app/srs_app_ffmpeg.hpp @@ -35,10 +35,7 @@ class SrsConfDirective; class SrsPithyPrint; class SrsProcess; -/** - * a transcode engine: ffmepg, - * used to transcode a stream to another. - */ +// A transcode engine: ffmepg, used to transcode a stream to another. class SrsFFMPEG { private: diff --git a/trunk/src/app/srs_app_forward.hpp b/trunk/src/app/srs_app_forward.hpp index f2edc7067..785e07add 100644 --- a/trunk/src/app/srs_app_forward.hpp +++ b/trunk/src/app/srs_app_forward.hpp @@ -43,14 +43,11 @@ class SrsOriginHub; class SrsKbps; class SrsSimpleRtmpClient; -/** - * forward the stream to other servers. - */ -// TODO: FIXME: refine the error log, comments it. +// Forward the stream to other servers. class SrsForwarder : public ISrsCoroutineHandler { private: - // the ep to forward, server[:port]. + // The ep to forward, server[:port]. std::string ep_forward; SrsRequest* req; private: @@ -60,10 +57,8 @@ private: SrsSimpleRtmpClient* sdk; SrsRtmpJitter* jitter; SrsMessageQueue* queue; - /** - * cache the sequence header for retry when slave is failed. - * @see https://github.com/ossrs/srs/issues/150 - */ + // Cache the sequence header for retry when slave is failed. + // @see https://github.com/ossrs/srs/issues/150 SrsSharedPtrMessage* sh_audio; SrsSharedPtrMessage* sh_video; public: @@ -75,20 +70,14 @@ public: public: virtual srs_error_t on_publish(); virtual void on_unpublish(); - /** - * forward the audio packet. - * @param shared_metadata, directly ptr, copy it if need to save it. - */ + // Forward the audio packet. + // @param shared_metadata, directly ptr, copy it if need to save it. virtual srs_error_t on_meta_data(SrsSharedPtrMessage* shared_metadata); - /** - * forward the audio packet. - * @param shared_audio, directly ptr, copy it if need to save it. - */ + // Forward the audio packet. + // @param shared_audio, directly ptr, copy it if need to save it. virtual srs_error_t on_audio(SrsSharedPtrMessage* shared_audio); - /** - * forward the video packet. - * @param shared_video, directly ptr, copy it if need to save it. - */ + // Forward the video packet. + // @param shared_video, directly ptr, copy it if need to save it. virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video); // interface ISrsReusableThread2Handler. public: diff --git a/trunk/src/app/srs_app_fragment.hpp b/trunk/src/app/srs_app_fragment.hpp index c06add374..c7c1125ec 100644 --- a/trunk/src/app/srs_app_fragment.hpp +++ b/trunk/src/app/srs_app_fragment.hpp @@ -29,10 +29,8 @@ #include #include -/** - * Represent a fragment, such as HLS segment, DVR segment or DASH segment. - * It's a media file, for example FLV or MP4, with duration. - */ +// Represent a fragment, such as HLS segment, DVR segment or DASH segment. +// It's a media file, for example FLV or MP4, with duration. class SrsFragment { private: @@ -75,9 +73,7 @@ public: virtual srs_error_t rename(); }; -/** - * The fragment window manage a series of fragment. - */ +// The fragment window manage a series of fragment. class SrsFragmentWindow { private: diff --git a/trunk/src/app/srs_app_hds.hpp b/trunk/src/app/srs_app_hds.hpp index 1cb437d6c..0fb5b30e7 100644 --- a/trunk/src/app/srs_app_hds.hpp +++ b/trunk/src/app/srs_app_hds.hpp @@ -35,6 +35,7 @@ class SrsSharedPtrMessage; class SrsHdsFragment; class SrsSource; +// Mux RTMP to Adobe HDS streaming. class SrsHds { public: diff --git a/trunk/src/app/srs_app_hourglass.hpp b/trunk/src/app/srs_app_hourglass.hpp index d5b18e799..6a0f624e6 100644 --- a/trunk/src/app/srs_app_hourglass.hpp +++ b/trunk/src/app/srs_app_hourglass.hpp @@ -28,68 +28,63 @@ #include -/** - * the handler for the tick. - */ +// The handler for the tick. class ISrsHourGlass { public: ISrsHourGlass(); virtual ~ISrsHourGlass(); public: - /** - * notify the handler, the type and tick. - */ + // When time is ticked, this function is called. virtual srs_error_t notify(int type, srs_utime_t interval, srs_utime_t tick) = 0; }; -/** - * the hourglass used to do some specieal task, - * while these task is cycle when some interval, for example, - * there are N=3 tasks to do: - * 1. heartbeat every 3s. - * 2. print message every 5s. - * 3. notify backend every 7s. - * the hourglass will call back when ticks: - * 1. notify(type=1, time=3) - * 2. notify(type=2, time=5) - * 3. notify(type=1, time=6) - * 4. notify(type=3, time=7) - * 5. notify(type=1, time=9) - * 6. notify(type=2, time=10) - * this is used for server and bocar server and other manager. - * - * Usage: - * SrsHourGlass* hg = new SrsHourGlass(handler, 1 * SRS_UTIME_MILLISECONDS); - * hg->tick(1, 3 * SRS_UTIME_MILLISECONDS); - * hg->tick(2, 5 * SRS_UTIME_MILLISECONDS); - * hg->tick(3, 7 * SRS_UTIME_MILLISECONDS); - * // create a thread to cycle, which will call handerl when ticked. - * while (true) { - * hg->cycle(); - * } - */ +// he hourglass used to do some specieal task, +// while these task is cycle when some interval, for example, +// there are N=3 tasks to do: +// 1. heartbeat every 3s. +// 2. print message every 5s. +// 3. notify backend every 7s. +// The hourglass will call back when ticks: +// 1. notify(type=1, time=3) +// 2. notify(type=2, time=5) +// 3. notify(type=1, time=6) +// 4. notify(type=3, time=7) +// 5. notify(type=1, time=9) +// 6. notify(type=2, time=10) +// This is used for server and bocar server and other manager. +// +// Usage: +// SrsHourGlass* hg = new SrsHourGlass(handler, 1 * SRS_UTIME_MILLISECONDS); +// hg->tick(1, 3 * SRS_UTIME_MILLISECONDS); +// hg->tick(2, 5 * SRS_UTIME_MILLISECONDS); +// hg->tick(3, 7 * SRS_UTIME_MILLISECONDS); +// // create a thread to cycle, which will call handerl when ticked. +// while (true) { +// hg->cycle(); +// } class SrsHourGlass { private: ISrsHourGlass* handler; srs_utime_t _resolution; - // key: the type of tick. - // value: the interval of tick. + // The ticks: + // key: the type of tick. + // value: the interval of tick. std::map ticks; - // the total elapsed time, + // The total elapsed time, // for each cycle, we increase it with a resolution. srs_utime_t total_elapse; public: SrsHourGlass(ISrsHourGlass* h, srs_utime_t resolution); virtual ~SrsHourGlass(); public: - // add a pair of tick(type, interval). + // Add a pair of tick(type, interval). // @param type the type of tick. // @param interval the interval in srs_utime_t of tick. virtual srs_error_t tick(int type, srs_utime_t interval); public: - // cycle the hourglass, which will sleep resolution every time. + // Cycle the hourglass, which will sleep resolution every time. // and call handler when ticked. virtual srs_error_t cycle(); }; diff --git a/trunk/src/app/srs_app_http_api.hpp b/trunk/src/app/srs_app_http_api.hpp index e83e72d71..a7eee7481 100644 --- a/trunk/src/app/srs_app_http_api.hpp +++ b/trunk/src/app/srs_app_http_api.hpp @@ -37,7 +37,7 @@ class SrsServer; #include #include -// for http root. +// For http root. class SrsGoApiRoot : public ISrsHttpHandler { public: diff --git a/trunk/src/app/srs_app_http_conn.hpp b/trunk/src/app/srs_app_http_conn.hpp index 8d9a524ec..beaa4d943 100644 --- a/trunk/src/app/srs_app_http_conn.hpp +++ b/trunk/src/app/srs_app_http_conn.hpp @@ -55,9 +55,7 @@ class SrsHttpMessage; class SrsHttpStreamServer; class SrsHttpStaticServer; -/** - * The http connection which request the static or stream content. - */ +// The http connection which request the static or stream content. class SrsHttpConn : public SrsConnection { protected: @@ -73,26 +71,22 @@ public: protected: virtual srs_error_t do_cycle(); protected: - // when got http message, + // When got http message, // for the static service or api, discard any body. // for the stream caster, for instance, http flv streaming, may discard the flv header or not. virtual srs_error_t on_got_http_message(ISrsHttpMessage* msg) = 0; private: virtual srs_error_t process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); - /** - * when the connection disconnect, call this method. - * e.g. log msg of connection and report to other system. - * @param request: request which is converted by the last http message. - */ + // When the connection disconnect, call this method. + // e.g. log msg of connection and report to other system. + // @param request: request which is converted by the last http message. virtual srs_error_t on_disconnect(SrsRequest* req); // interface ISrsReloadHandler public: virtual srs_error_t on_reload_http_stream_crossdomain(); }; -/** - * drop body of request, only process the response. - */ +// Drop body of request, only process the response. class SrsResponseOnlyHttpConn : public SrsHttpConn { public: @@ -109,9 +103,7 @@ public: virtual srs_error_t on_got_http_message(ISrsHttpMessage* msg); }; -/** - * the http server, use http stream or static server to serve requests. - */ +// The http server, use http stream or static server to serve requests. class SrsHttpServer : public ISrsHttpServeMux { private: @@ -123,10 +115,9 @@ public: virtual ~SrsHttpServer(); public: virtual srs_error_t initialize(); - // ISrsHttpServeMux +// interface ISrsHttpServeMux public: virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); - // http flv/ts/mp3/aac stream public: virtual srs_error_t http_mount(SrsSource* s, SrsRequest* r); virtual void http_unmount(SrsSource* s, SrsRequest* r); diff --git a/trunk/src/app/srs_app_http_hooks.hpp b/trunk/src/app/srs_app_http_hooks.hpp index 0dfb0f3c9..a3579cd34 100644 --- a/trunk/src/app/srs_app_http_hooks.hpp +++ b/trunk/src/app/srs_app_http_hooks.hpp @@ -34,11 +34,10 @@ class SrsRequest; class SrsHttpParser; class SrsHttpClient; -/** - * the http hooks, http callback api, - * for some event, such as on_connect, call - * a http api(hooks). - */ +// the http hooks, http callback api, +// for some event, such as on_connect, call +// a http api(hooks). +// TODO: Refine to global variable. class SrsHttpHooks { private: @@ -46,76 +45,56 @@ private: public: virtual ~SrsHttpHooks(); public: - /** - * on_connect hook, when client connect to srs. - * @param url the api server url, to valid the client. - * ignore if empty. - */ + // The on_connect hook, when client connect to srs. + // @param url the api server url, to valid the client. + // ignore if empty. static srs_error_t on_connect(std::string url, SrsRequest* req); - /** - * on_close hook, when client disconnect to srs, where client is valid by on_connect. - * @param url the api server url, to process the event. - * ignore if empty. - */ + // The on_close hook, when client disconnect to srs, where client is valid by on_connect. + // @param url the api server url, to process the event. + // ignore if empty. static void on_close(std::string url, SrsRequest* req, int64_t send_bytes, int64_t recv_bytes); - /** - * on_publish hook, when client(encoder) start to publish stream - * @param url the api server url, to valid the client. - * ignore if empty. - */ + // The on_publish hook, when client(encoder) start to publish stream + // @param url the api server url, to valid the client. + // ignore if empty. static srs_error_t on_publish(std::string url, SrsRequest* req); - /** - * on_unpublish hook, when client(encoder) stop publish stream. - * @param url the api server url, to process the event. - * ignore if empty. - */ + // The on_unpublish hook, when client(encoder) stop publish stream. + // @param url the api server url, to process the event. + // ignore if empty. static void on_unpublish(std::string url, SrsRequest* req); - /** - * on_play hook, when client start to play stream. - * @param url the api server url, to valid the client. - * ignore if empty. - */ + // The on_play hook, when client start to play stream. + // @param url the api server url, to valid the client. + // ignore if empty. static srs_error_t on_play(std::string url, SrsRequest* req); - /** - * on_stop hook, when client stop to play the stream. - * @param url the api server url, to process the event. - * ignore if empty. - */ + // The on_stop hook, when client stop to play the stream. + // @param url the api server url, to process the event. + // ignore if empty. static void on_stop(std::string url, SrsRequest* req); - /** - * on_dvr hook, when reap a dvr file. - * @param url the api server url, to process the event. - * ignore if empty. - * @param file the file path, can be relative or absolute path. - * @param cid the source connection cid, for the on_dvr is async call. - */ + // The on_dvr hook, when reap a dvr file. + // @param url the api server url, to process the event. + // ignore if empty. + // @param file the file path, can be relative or absolute path. + // @param cid the source connection cid, for the on_dvr is async call. static srs_error_t on_dvr(int cid, std::string url, SrsRequest* req, std::string file); - /** - * when hls reap segment, callback. - * @param url the api server url, to process the event. - * ignore if empty. - * @param file the ts file path, can be relative or absolute path. - * @param ts_url the ts url, which used for m3u8. - * @param m3u8 the m3u8 file path, can be relative or absolute path. - * @param m3u8_url the m3u8 url, which is used for the http mount path. - * @param sn the seq_no, the sequence number of ts in hls/m3u8. - * @param duration the segment duration in srs_utime_t. - * @param cid the source connection cid, for the on_dvr is async call. - */ + // When hls reap segment, callback. + // @param url the api server url, to process the event. + // ignore if empty. + // @param file the ts file path, can be relative or absolute path. + // @param ts_url the ts url, which used for m3u8. + // @param m3u8 the m3u8 file path, can be relative or absolute path. + // @param m3u8_url the m3u8 url, which is used for the http mount path. + // @param sn the seq_no, the sequence number of ts in hls/m3u8. + // @param duration the segment duration in srs_utime_t. + // @param cid the source connection cid, for the on_dvr is async call. static srs_error_t on_hls(int cid, std::string url, SrsRequest* req, std::string file, std::string ts_url, std::string m3u8, std::string m3u8_url, int sn, srs_utime_t duration); - /** - * when hls reap segment, callback. - * @param url the api server url, to process the event. - * ignore if empty. - * @param ts_url the ts uri, used to replace the variable [ts_url] in url. - * @param nb_notify the max bytes to read from notify server. - * @param cid the source connection cid, for the on_dvr is async call. - */ + // When hls reap segment, callback. + // @param url the api server url, to process the event. + // ignore if empty. + // @param ts_url the ts uri, used to replace the variable [ts_url] in url. + // @param nb_notify the max bytes to read from notify server. + // @param cid the source connection cid, for the on_dvr is async call. static srs_error_t on_hls_notify(int cid, std::string url, SrsRequest* req, std::string ts_url, int nb_notify); - /** - * Discover co-workers for origin cluster. - */ + // Discover co-workers for origin cluster. static srs_error_t discover_co_workers(std::string url, std::string& host, int& port); private: static srs_error_t do_post(SrsHttpClient* hc, std::string url, std::string req, int& code, std::string& res); diff --git a/trunk/src/app/srs_app_http_static.hpp b/trunk/src/app/srs_app_http_static.hpp index 0dc734265..f7e5a2fa0 100644 --- a/trunk/src/app/srs_app_http_static.hpp +++ b/trunk/src/app/srs_app_http_static.hpp @@ -28,12 +28,10 @@ #include -/** - * the flv vod stream supports flv?start=offset-bytes. - * for example, http://server/file.flv?start=10240 - * server will write flv header and sequence header, - * then seek(10240) and response flv tag data. - */ +// The flv vod stream supports flv?start=offset-bytes. +// For example, http://server/file.flv?start=10240 +// server will write flv header and sequence header, +// then seek(10240) and response flv tag data. class SrsVodStream : public SrsHttpFileServer { public: @@ -44,10 +42,8 @@ protected: virtual srs_error_t serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, std::string fullpath, int start, int end); }; -/** - * the http static server instance, - * serve http static file and flv/mp4 vod stream. - */ +// The http static server instance, +// serve http static file and flv/mp4 vod stream. class SrsHttpStaticServer : virtual public ISrsReloadHandler { private: diff --git a/trunk/src/app/srs_app_http_stream.hpp b/trunk/src/app/srs_app_http_stream.hpp index bfbe35761..75ca812bc 100755 --- a/trunk/src/app/srs_app_http_stream.hpp +++ b/trunk/src/app/srs_app_http_stream.hpp @@ -33,9 +33,7 @@ class SrsMp3Transmuxer; class SrsFlvTransmuxer; class SrsTsTransmuxer; -/** - * A cache for HTTP Live Streaming encoder, to make android(weixin) happy. - */ +// A cache for HTTP Live Streaming encoder, to make android(weixin) happy. class SrsBufferCache : public ISrsCoroutineHandler { private: @@ -57,43 +55,31 @@ public: virtual srs_error_t cycle(); }; -/** - * The encoder to transmux RTMP stream. - */ +// The encoder to transmux RTMP stream. class ISrsBufferEncoder { public: ISrsBufferEncoder(); virtual ~ISrsBufferEncoder(); public: - /** - * initialize the encoder with file writer(to http response) and stream cache. - * @param w the writer to write to http response. - * @param c the stream cache for audio stream fast startup. - */ + // Initialize the encoder with file writer(to http response) and stream cache. + // @param w the writer to write to http response. + // @param c the stream cache for audio stream fast startup. virtual srs_error_t initialize(SrsFileWriter* w, SrsBufferCache* c) = 0; - /** - * write rtmp video/audio/metadata. - */ + // Write rtmp video/audio/metadata. virtual srs_error_t write_audio(int64_t timestamp, char* data, int size) = 0; virtual srs_error_t write_video(int64_t timestamp, char* data, int size) = 0; virtual srs_error_t write_metadata(int64_t timestamp, char* data, int size) = 0; public: - /** - * for some stream, for example, mp3 and aac, the audio stream, - * we use large gop cache in encoder, for the gop cache of SrsSource is ignore audio. - * @return true to use gop cache of encoder; otherwise, use SrsSource. - */ + // For some stream, for example, mp3 and aac, the audio stream, + // we use large gop cache in encoder, for the gop cache of SrsSource is ignore audio. + // @return true to use gop cache of encoder; otherwise, use SrsSource. virtual bool has_cache() = 0; - /** - * dumps the cache of encoder to consumer. - */ + // Dumps the cache of encoder to consumer. virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter) = 0; }; -/** - * Transmux RTMP to HTTP Live Streaming. - */ +// Transmux RTMP to HTTP Live Streaming. class SrsFlvStreamEncoder : public ISrsBufferEncoder { protected: @@ -112,26 +98,20 @@ public: }; #ifdef SRS_PERF_FAST_FLV_ENCODER -/** - * A Fast HTTP FLV Live Streaming, to write multiple tags by writev. - * @see https://github.com/ossrs/srs/issues/405 - */ +// A Fast HTTP FLV Live Streaming, to write multiple tags by writev. +// @see https://github.com/ossrs/srs/issues/405 class SrsFastFlvStreamEncoder : public SrsFlvStreamEncoder { public: SrsFastFlvStreamEncoder(); virtual ~SrsFastFlvStreamEncoder(); public: - /** - * write the tags in a time. - */ + // Write the tags in a time. virtual srs_error_t write_tags(SrsSharedPtrMessage** msgs, int count); }; #endif -/** - * Transmux RTMP to HTTP TS Streaming. - */ +// Transmux RTMP to HTTP TS Streaming. class SrsTsStreamEncoder : public ISrsBufferEncoder { private: @@ -149,9 +129,7 @@ public: virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter); }; -/** - * Transmux RTMP with AAC stream to HTTP AAC Streaming. - */ +// Transmux RTMP with AAC stream to HTTP AAC Streaming. class SrsAacStreamEncoder : public ISrsBufferEncoder { private: @@ -170,9 +148,7 @@ public: virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter); }; -/** - * Transmux RTMP with MP3 stream to HTTP MP3 Streaming. - */ +// Transmux RTMP with MP3 stream to HTTP MP3 Streaming. class SrsMp3StreamEncoder : public ISrsBufferEncoder { private: @@ -191,9 +167,7 @@ public: virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter); }; -/** - * write stream to http response direclty. - */ +// Write stream to http response direclty. class SrsBufferWriter : public SrsFileWriter { private: @@ -212,9 +186,7 @@ public: virtual srs_error_t writev(const iovec* iov, int iovcnt, ssize_t* pnwrite); }; -/** - * HTTP Live Streaming, to transmux RTMP to HTTP FLV or other format. - */ +// HTTP Live Streaming, to transmux RTMP to HTTP FLV or other format. class SrsLiveStream : public ISrsHttpHandler { private: @@ -234,9 +206,7 @@ private: virtual srs_error_t streaming_send_messages(ISrsBufferEncoder* enc, SrsSharedPtrMessage** msgs, int nb_msgs); }; -/** - * The Live Entry, to handle HTTP Live Streaming. - */ +// The Live Entry, to handle HTTP Live Streaming. struct SrsLiveEntry { private: @@ -248,8 +218,8 @@ public: SrsRequest* req; SrsSource* source; public: - // for template, the mount contains variables. - // for concrete stream, the mount is url to access. + // For template, the mount contains variables. + // For concrete stream, the mount is url to access. std::string mount; SrsLiveStream* stream; @@ -263,9 +233,7 @@ public: bool is_aac(); }; -/** - * The HTTP Live Streaming Server, to serve FLV/TS/MP3/AAC stream. - */ +// The HTTP Live Streaming Server, to serve FLV/TS/MP3/AAC stream. // TODO: Support multiple stream. class SrsHttpStreamServer : virtual public ISrsReloadHandler , virtual public ISrsHttpMatchHijacker @@ -274,17 +242,17 @@ private: SrsServer* server; public: SrsHttpServeMux mux; - // the http live streaming template, to create streams. + // The http live streaming template, to create streams. std::map tflvs; - // the http live streaming streams, crote by template. + // The http live streaming streams, crote by template. std::map sflvs; public: SrsHttpStreamServer(SrsServer* svr); virtual ~SrsHttpStreamServer(); public: virtual srs_error_t initialize(); - // http flv/ts/mp3/aac stream public: + // HTTP flv/ts/mp3/aac stream virtual srs_error_t http_mount(SrsSource* s, SrsRequest* r); virtual void http_unmount(SrsSource* s, SrsRequest* r); // interface ISrsReloadHandler. diff --git a/trunk/src/app/srs_app_listener.hpp b/trunk/src/app/srs_app_listener.hpp index 8754a1105..22e84b278 100644 --- a/trunk/src/app/srs_app_listener.hpp +++ b/trunk/src/app/srs_app_listener.hpp @@ -33,51 +33,39 @@ struct sockaddr; -/** - * the udp packet handler. - */ +// The udp packet handler. class ISrsUdpHandler { public: ISrsUdpHandler(); virtual ~ISrsUdpHandler(); public: - /** - * when fd changed, for instance, reload the listen port, - * notify the handler and user can do something. - */ + // When fd changed, for instance, reload the listen port, + // notify the handler and user can do something. virtual srs_error_t on_stfd_change(srs_netfd_t fd); public: - /** - * when udp listener got a udp packet, notice server to process it. - * @param type, the client type, used to create concrete connection, - * for instance RTMP connection to serve client. - * @param from, the udp packet from address. - * @param buf, the udp packet bytes, user should copy if need to use. - * @param nb_buf, the size of udp packet bytes. - * @remark user should never use the buf, for it's a shared memory bytes. - */ + // When udp listener got a udp packet, notice server to process it. + // @param type, the client type, used to create concrete connection, + // for instance RTMP connection to serve client. + // @param from, the udp packet from address. + // @param buf, the udp packet bytes, user should copy if need to use. + // @param nb_buf, the size of udp packet bytes. + // @remark user should never use the buf, for it's a shared memory bytes. virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf) = 0; }; -/** - * the tcp connection handler. - */ +// The tcp connection handler. class ISrsTcpHandler { public: ISrsTcpHandler(); virtual ~ISrsTcpHandler(); public: - /** - * when got tcp client. - */ + // When got tcp client. virtual srs_error_t on_tcp_client(srs_netfd_t stfd) = 0; }; -/** - * bind udp port, start thread to recv packet and handler it. - */ +// Bind udp port, start thread to recv packet and handler it. class SrsUdpListener : public ISrsCoroutineHandler { private: @@ -104,9 +92,7 @@ public: virtual srs_error_t cycle(); }; -/** - * bind and listen tcp port, use handler to process the client. - */ +// Bind and listen tcp port, use handler to process the client. class SrsTcpListener : public ISrsCoroutineHandler { private: diff --git a/trunk/src/app/srs_app_log.hpp b/trunk/src/app/srs_app_log.hpp index 368a004fe..afb58b1cc 100644 --- a/trunk/src/app/srs_app_log.hpp +++ b/trunk/src/app/srs_app_log.hpp @@ -32,24 +32,21 @@ #include #include -/** - * we use memory/disk cache and donot flush when write log. - * it's ok to use it without config, which will log to console, and default trace level. - * when you want to use different level, override this classs, set the protected _level. - */ +// Use memory/disk cache and donot flush when write log. +// it's ok to use it without config, which will log to console, and default trace level. +// when you want to use different level, override this classs, set the protected _level. class SrsFastLog : public ISrsLog, public ISrsReloadHandler { -// for utest to override -protected: - // defined in SrsLogLevel. +private: + // Defined in SrsLogLevel. SrsLogLevel level; private: char* log_data; - // log to file if specified srs_log_file + // Log to file if specified srs_log_file int fd; - // whether log to file tank + // Whether log to file tank bool log_to_file_tank; - // whether use utc time. + // Whether use utc time. bool utc; public: SrsFastLog(); diff --git a/trunk/src/app/srs_app_mpegts_udp.hpp b/trunk/src/app/srs_app_mpegts_udp.hpp index 3b537294e..403a496ba 100644 --- a/trunk/src/app/srs_app_mpegts_udp.hpp +++ b/trunk/src/app/srs_app_mpegts_udp.hpp @@ -48,15 +48,13 @@ class SrsSimpleRtmpClient; #include #include -/** - * the queue for mpegts over udp to send packets. - * for the aac in mpegts contains many flv packets in a pes packet, - * we must recalc the timestamp. - */ +// The queue for mpegts over udp to send packets. +// For the aac in mpegts contains many flv packets in a pes packet, +// we must recalc the timestamp. class SrsMpegtsQueue { private: - // key: dts, value: msg. + // The key: dts, value: msg. std::map msgs; int nb_audios; int nb_videos; @@ -68,11 +66,8 @@ public: virtual SrsSharedPtrMessage* dequeue(); }; -/** - * the mpegts over udp stream caster. - */ -class SrsMpegtsOverUdp : virtual public ISrsTsHandler -, virtual public ISrsUdpHandler +// The mpegts over udp stream caster. +class SrsMpegtsOverUdp : virtual public ISrsTsHandler, virtual public ISrsUdpHandler { private: SrsTsContext* context; diff --git a/trunk/src/app/srs_app_ng_exec.hpp b/trunk/src/app/srs_app_ng_exec.hpp index aeee0c4ff..d47dc42e2 100644 --- a/trunk/src/app/srs_app_ng_exec.hpp +++ b/trunk/src/app/srs_app_ng_exec.hpp @@ -35,11 +35,9 @@ class SrsRequest; class SrsPithyPrint; class SrsProcess; -/** - * the ng-exec is the exec feature introduced by nginx-rtmp, - * @see https://github.com/arut/nginx-rtmp-module/wiki/Directives#exec_push - * @see https://github.com/ossrs/srs/issues/367 - */ +// The ng-exec is the exec feature introduced by nginx-rtmp, +// @see https://github.com/arut/nginx-rtmp-module/wiki/Directives#exec_push +// @see https://github.com/ossrs/srs/issues/367 class SrsNgExec : public ISrsCoroutineHandler { private: diff --git a/trunk/src/app/srs_app_pithy_print.hpp b/trunk/src/app/srs_app_pithy_print.hpp index ee0f9be52..4d1e26741 100644 --- a/trunk/src/app/srs_app_pithy_print.hpp +++ b/trunk/src/app/srs_app_pithy_print.hpp @@ -28,9 +28,7 @@ #include -/** - * the stage info to calc the age. - */ +// The stage info to calc the age. class SrsStageInfo : public ISrsReloadHandler { public: @@ -50,26 +48,24 @@ public: virtual srs_error_t on_reload_pithy_print(); }; -/** - * the stage is used for a collection of object to do print, - * the print time in a stage is constant and not changed, - * that is, we always got one message to print every specified time. - * - * for example, stage #1 for all play clients, print time is 3s, - * if there is 1client, it will print every 3s. - * if there is 10clients, random select one to print every 3s. - * Usage: - * SrsPithyPrint* pprint = SrsPithyPrint::create_rtmp_play(); - * SrsAutoFree(SrsPithyPrint, pprint); - * while (true) { - * pprint->elapse(); - * if (pprint->can_print()) { - * // print pithy message. - * // user can get the elapse time by: pprint->age() - * } - * // read and write RTMP messages. - * } - */ +// The stage is used for a collection of object to do print, +// the print time in a stage is constant and not changed, +// that is, we always got one message to print every specified time. +// +// For example, stage #1 for all play clients, print time is 3s, +// if there is 1client, it will print every 3s. +// if there is 10clients, random select one to print every 3s. +// Usage: +// SrsPithyPrint* pprint = SrsPithyPrint::create_rtmp_play(); +// SrsAutoFree(SrsPithyPrint, pprint); +// while (true) { +// pprint->elapse(); +// if (pprint->can_print()) { +// // print pithy message. +// // user can get the elapse time by: pprint->age() +// } +// // read and write RTMP messages. +// } class SrsPithyPrint { private: @@ -93,26 +89,16 @@ public: static SrsPithyPrint* create_http_stream_cache(); virtual ~SrsPithyPrint(); private: - /** - * enter the specified stage, return the client id. - */ + // Enter the specified stage, return the client id. virtual int enter_stage(); - /** - * leave the specified stage, release the client id. - */ + // Leave the specified stage, release the client id. virtual void leave_stage(); public: - /** - * auto calc the elapse time - */ + // Auto calc the elapse time virtual void elapse(); - /** - * whether current client can print. - */ + // Whether current client can print. virtual bool can_print(); - /** - * get the elapsed time in srs_utime_t. - */ + // Get the elapsed time in srs_utime_t. virtual srs_utime_t age(); }; diff --git a/trunk/src/app/srs_app_process.hpp b/trunk/src/app/srs_app_process.hpp index 100e1e550..62e95129c 100644 --- a/trunk/src/app/srs_app_process.hpp +++ b/trunk/src/app/srs_app_process.hpp @@ -29,26 +29,24 @@ #include #include -/** - * to start and stop a process, cycle to restart the process when terminated. - * the usage: - * // the binary is the process to fork. - * binary = "./objs/ffmpeg/bin/ffmpeg"; - * // where argv is a array contains each params. - * argv = ["./objs/ffmpeg/bin/ffmpeg", "-i", "in.flv", "1", ">", "/dev/null", "2", ">", "/dev/null"]; - * - * process = new SrsProcess(); - * if ((ret = process->initialize(binary, argv)) != ERROR_SUCCESS) { return ret; } - * if ((ret = process->start()) != ERROR_SUCCESS) { return ret; } - * if ((ret = process->cycle()) != ERROR_SUCCESS) { return ret; } - * process->fast_stop(); - * process->stop(); - */ +// Start and stop a process. Call cycle to restart the process when terminated. +// The usage: +// // the binary is the process to fork. +// binary = "./objs/ffmpeg/bin/ffmpeg"; +// // where argv is a array contains each params. +// argv = ["./objs/ffmpeg/bin/ffmpeg", "-i", "in.flv", "1", ">", "/dev/null", "2", ">", "/dev/null"]; +// +// process = new SrsProcess(); +// if ((ret = process->initialize(binary, argv)) != ERROR_SUCCESS) { return ret; } +// if ((ret = process->start()) != ERROR_SUCCESS) { return ret; } +// if ((ret = process->cycle()) != ERROR_SUCCESS) { return ret; } +// process->fast_stop(); +// process->stop(); class SrsProcess { private: bool is_started; - // whether SIGTERM send but need to wait or SIGKILL. + // Whether SIGTERM send but need to wait or SIGKILL. bool fast_stopped; pid_t pid; private: @@ -56,56 +54,42 @@ private: std::string stdout_file; std::string stderr_file; std::vector params; - // the cli to fork process. + // The cli to fork process. std::string cli; std::string actual_cli; public: SrsProcess(); virtual ~SrsProcess(); public: - /** - * get pid of process. - */ + // Get pid of process. virtual int get_pid(); - /** - * whether process is already started. - */ + // whether process is already started. virtual bool started(); - /** - * initialize the process with binary and argv. - * @param binary the binary path to exec. - * @param argv the argv for binary path, the argv[0] generally is the binary. - * @remark the argv[0] must be the binary. - */ + // Initialize the process with binary and argv. + // @param binary the binary path to exec. + // @param argv the argv for binary path, the argv[0] generally is the binary. + // @remark the argv[0] must be the binary. virtual srs_error_t initialize(std::string binary, std::vector argv); public: - /** - * start the process, ignore when already started. - */ + // Start the process, ignore when already started. virtual srs_error_t start(); - /** - * cycle check the process, update the state of process. - * @remark when process terminated(not started), user can restart it again by start(). - */ + // cycle check the process, update the state of process. + // @remark when process terminated(not started), user can restart it again by start(). virtual srs_error_t cycle(); - /** - * send SIGTERM then SIGKILL to ensure the process stopped. - * the stop will wait [0, SRS_PROCESS_QUIT_TIMEOUT_MS] depends on the - * process quit timeout. - * @remark use fast_stop before stop one by one, when got lots of process to quit. - */ + // Send SIGTERM then SIGKILL to ensure the process stopped. + // the stop will wait [0, SRS_PROCESS_QUIT_TIMEOUT_MS] depends on the + // process quit timeout. + // @remark use fast_stop before stop one by one, when got lots of process to quit. virtual void stop(); public: - /** - * the fast stop is to send a SIGTERM. - * for example, the ingesters owner lots of FFMPEG, it will take a long time - * to stop one by one, instead the ingesters can fast_stop all FFMPEG, then - * wait one by one to stop, it's more faster. - * @remark user must use stop() to ensure the ffmpeg to stopped. - * @remark we got N processes to stop, compare the time we spend, - * when use stop without fast_stop, we spend maybe [0, SRS_PROCESS_QUIT_TIMEOUT_MS * N] - * but use fast_stop then stop, the time is almost [0, SRS_PROCESS_QUIT_TIMEOUT_MS]. - */ + // The fast stop is to send a SIGTERM. + // for example, the ingesters owner lots of FFMPEG, it will take a long time + // to stop one by one, instead the ingesters can fast_stop all FFMPEG, then + // wait one by one to stop, it's more faster. + // @remark user must use stop() to ensure the ffmpeg to stopped. + // @remark we got N processes to stop, compare the time we spend, + // when use stop without fast_stop, we spend maybe [0, SRS_PROCESS_QUIT_TIMEOUT_MS * N] + // but use fast_stop then stop, the time is almost [0, SRS_PROCESS_QUIT_TIMEOUT_MS]. virtual void fast_stop(); }; diff --git a/trunk/src/app/srs_app_recv_thread.hpp b/trunk/src/app/srs_app_recv_thread.hpp index d11f55dd3..940b91564 100644 --- a/trunk/src/app/srs_app_recv_thread.hpp +++ b/trunk/src/app/srs_app_recv_thread.hpp @@ -42,54 +42,38 @@ class SrsConsumer; class SrsHttpConn; class SrsResponseOnlyHttpConn; -/** - * The message consumer which consume a message. - */ +// The message consumer which consume a message. class ISrsMessageConsumer { public: ISrsMessageConsumer(); virtual ~ISrsMessageConsumer(); public: - /** - * Consume the received message. - * @remark user must free this message. - */ + // Consume the received message. + // @remark user must free this message. virtual srs_error_t consume(SrsCommonMessage* msg) = 0; }; -/** - * The message pumper to pump messages to processer. - */ +// The message pumper to pump messages to processer. class ISrsMessagePumper : public ISrsMessageConsumer { public: ISrsMessagePumper(); virtual ~ISrsMessagePumper(); public: - /** - * Whether the pumper is interrupted. - * For example, when pumpter is busy, it's interrupted, - * please wait for a while then try to feed the pumper. - */ + // Whether the pumper is interrupted. + // For example, when pumpter is busy, it's interrupted, + // please wait for a while then try to feed the pumper. virtual bool interrupted() = 0; - /** - * Interrupt the pumper for a error. - */ + // Interrupt the pumper for a error. virtual void interrupt(srs_error_t error) = 0; - /** - * When start the pumper. - */ + // When start the pumper. virtual void on_start() = 0; - /** - * When stop the pumper. - */ + // When stop the pumper. virtual void on_stop() = 0; }; -/** - * the recv thread, use message handler to handle each received message. - */ +// The recv thread, use message handler to handle each received message. class SrsRecvThread : public ISrsCoroutineHandler { protected: @@ -117,19 +101,17 @@ private: virtual srs_error_t do_cycle(); }; -/** - * the recv thread used to replace the timeout recv, - * which hurt performance for the epoll_ctrl is frequently used. - * @see: SrsRtmpConn::playing - * @see: https://github.com/ossrs/srs/issues/217 - */ +// The recv thread used to replace the timeout recv, +// which hurt performance for the epoll_ctrl is frequently used. +// @see: SrsRtmpConn::playing +// @see: https://github.com/ossrs/srs/issues/217 class SrsQueueRecvThread : public ISrsMessagePumper { private: std::vector queue; SrsRecvThread trd; SrsRtmpServer* rtmp; - // the recv thread error code. + // The recv thread error code. srs_error_t recv_error; SrsConsumer* _consumer; public: @@ -153,10 +135,8 @@ public: virtual void on_stop(); }; -/** - * the publish recv thread got message and callback the source method to process message. - * @see: https://github.com/ossrs/srs/issues/237 - */ +// The publish recv thread got message and callback the source method to process message. +// @see: https://github.com/ossrs/srs/issues/237 class SrsPublishRecvThread : virtual public ISrsMessagePumper, virtual public ISrsReloadHandler #ifdef SRS_PERF_MERGED_READ , virtual public IMergeReadHandler @@ -166,27 +146,27 @@ private: SrsRecvThread trd; SrsRtmpServer* rtmp; SrsRequest* req; - // the msgs already got. + // The msgs already got. int64_t _nb_msgs; // The video frames we got. uint64_t video_frames; - // for mr(merged read), + // For mr(merged read), // @see https://github.com/ossrs/srs/issues/241 bool mr; int mr_fd; srs_utime_t mr_sleep; - // for realtime + // For realtime // @see https://github.com/ossrs/srs/issues/257 bool realtime; - // the recv thread error code. + // The recv thread error code. srs_error_t recv_error; SrsRtmpConn* _conn; - // the params for conn callback. + // The params for conn callback. SrsSource* _source; - // the error timeout cond + // The error timeout cond // @see https://github.com/ossrs/srs/issues/244 srs_cond_t error; - // merged context id. + // The merged context id. int cid; int ncid; public: @@ -194,9 +174,7 @@ public: int mr_sock_fd, srs_utime_t tm, SrsRtmpConn* conn, SrsSource* source, int parent_cid); virtual ~SrsPublishRecvThread(); public: - /** - * wait for error for some timeout. - */ + // Wait for error for some timeout. virtual srs_error_t wait(srs_utime_t tm); virtual int64_t nb_msgs(); virtual uint64_t nb_video_frames(); @@ -226,12 +204,10 @@ private: virtual void set_socket_buffer(srs_utime_t sleep_v); }; -/** - * The HTTP receive thread, try to read messages util EOF. - * For example, the HTTP FLV serving thread will use the receive thread to break - * when client closed the request, to avoid FD leak. - * @see https://github.com/ossrs/srs/issues/636#issuecomment-298208427 - */ +// The HTTP receive thread, try to read messages util EOF. +// For example, the HTTP FLV serving thread will use the receive thread to break +// when client closed the request, to avoid FD leak. +// @see https://github.com/ossrs/srs/issues/636#issuecomment-298208427 class SrsHttpRecvThread : public ISrsCoroutineHandler { private: diff --git a/trunk/src/app/srs_app_refer.hpp b/trunk/src/app/srs_app_refer.hpp index 75f712d3c..7b348e890 100644 --- a/trunk/src/app/srs_app_refer.hpp +++ b/trunk/src/app/srs_app_refer.hpp @@ -36,11 +36,9 @@ public: SrsRefer(); virtual ~SrsRefer(); public: - /** - * to check the refer. - * @param page_url the client page url. - * @param refer the refer in config. - */ + // Check the refer. + // @param page_url the client page url. + // @param refer the refer in config. virtual srs_error_t check(std::string page_url, SrsConfDirective* refer); private: virtual srs_error_t check_single_refer(std::string page_url, std::string refer); diff --git a/trunk/src/app/srs_app_reload.hpp b/trunk/src/app/srs_app_reload.hpp index 9b1c35f1c..6ffc10d07 100644 --- a/trunk/src/app/srs_app_reload.hpp +++ b/trunk/src/app/srs_app_reload.hpp @@ -28,13 +28,11 @@ #include -/** - * the handler for config reload. - * when reload callback, the config is updated yet. - * - * features not support reload, - * @see: https://github.com/ossrs/srs/wiki/v1_CN_Reload#notsupportedfeatures - */ +// The handler for config reload. +// When reload callback, the config is updated yet. +// +// Features not support reload, +// @see: https://github.com/ossrs/srs/wiki/v1_CN_Reload#notsupportedfeatures class ISrsReloadHandler { public: diff --git a/trunk/src/app/srs_app_rtmp_conn.hpp b/trunk/src/app/srs_app_rtmp_conn.hpp index 905779572..0f5cdc932 100644 --- a/trunk/src/app/srs_app_rtmp_conn.hpp +++ b/trunk/src/app/srs_app_rtmp_conn.hpp @@ -58,9 +58,7 @@ class SrsPacket; class ISrsKafkaCluster; #endif -/** - * The simple rtmp client for SRS. - */ +// The simple rtmp client for SRS. class SrsSimpleRtmpClient : public SrsBasicRtmpClient { public: @@ -70,9 +68,7 @@ protected: virtual srs_error_t connect_app(); }; -/** - * Some information of client. - */ +// Some information of client. class SrsClientInfo { public: @@ -89,12 +85,10 @@ public: virtual ~SrsClientInfo(); }; -/** - * the client provides the main logic control for RTMP clients. - */ +// The client provides the main logic control for RTMP clients. class SrsRtmpConn : virtual public SrsConnection, virtual public ISrsReloadHandler { - // for the thread to directly access any field of connection. + // For the thread to directly access any field of connection. friend class SrsPublishRecvThread; private: SrsServer* server; @@ -102,27 +96,27 @@ private: SrsRefer* refer; SrsBandwidth* bandwidth; SrsSecurity* security; - // the wakable handler, maybe NULL. + // The wakable handler, maybe NULL. // TODO: FIXME: Should refine the state for receiving thread. ISrsWakable* wakable; - // elapse duration in srs_utime_t - // for live play duration, for instance, rtmpdump to record. + // The elapsed duration in srs_utime_t + // For live play duration, for instance, rtmpdump to record. // @see https://github.com/ossrs/srs/issues/47 srs_utime_t duration; - // the MR(merged-write) sleep time in srs_utime_t. + // The MR(merged-write) sleep time in srs_utime_t. srs_utime_t mw_sleep; - // the MR(merged-write) only enabled for play. + // The MR(merged-write) only enabled for play. int mw_enabled; - // for realtime + // For realtime // @see https://github.com/ossrs/srs/issues/257 bool realtime; - // the minimal interval in srs_utime_t for delivery stream. + // The minimal interval in srs_utime_t for delivery stream. srs_utime_t send_min_interval; - // publish 1st packet timeout in srs_utime_t + // The publish 1st packet timeout in srs_utime_t srs_utime_t publish_1stpkt_timeout; - // publish normal packet timeout in srs_utime_t + // The publish normal packet timeout in srs_utime_t srs_utime_t publish_normal_timeout; - // whether enable the tcp_nodelay. + // Whether enable the tcp_nodelay. bool tcp_nodelay; // About the rtmp client. SrsClientInfo* info; @@ -144,9 +138,9 @@ public: public: virtual void remark(int64_t* in, int64_t* out); private: - // when valid and connected to vhost/app, service the client. + // When valid and connected to vhost/app, service the client. virtual srs_error_t service_cycle(); - // stream(play/publish) service cycle, identify client first. + // The stream(play/publish) service cycle, identify client first. virtual srs_error_t stream_service_cycle(); virtual srs_error_t check_vhost(bool try_default_vhost); virtual srs_error_t playing(SrsSource* source); @@ -164,10 +158,8 @@ private: virtual srs_error_t check_edge_token_traverse_auth(); virtual srs_error_t do_token_traverse_auth(SrsRtmpClient* client); private: - /** - * when the connection disconnect, call this method. - * e.g. log msg of connection and report to other system. - */ + // When the connection disconnect, call this method. + // e.g. log msg of connection and report to other system. virtual srs_error_t on_disconnect(); private: virtual srs_error_t http_hooks_on_connect(); diff --git a/trunk/src/app/srs_app_rtsp.hpp b/trunk/src/app/srs_app_rtsp.hpp index 697df6869..28d6014ab 100644 --- a/trunk/src/app/srs_app_rtsp.hpp +++ b/trunk/src/app/srs_app_rtsp.hpp @@ -52,9 +52,7 @@ class SrsSimpleStream; class SrsPithyPrint; class SrsSimpleRtmpClient; -/** - * a rtp connection which transport a stream. - */ +// A rtp connection which transport a stream. class SrsRtpConn: public ISrsUdpHandler { private: @@ -75,9 +73,7 @@ public: virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf); }; -/** - * audio is group by frames. - */ +// The audio cache, audio is grouped by frames. struct SrsRtspAudioCache { int64_t dts; @@ -88,9 +84,7 @@ struct SrsRtspAudioCache virtual ~SrsRtspAudioCache(); }; -/** - * the time jitter correct for rtsp. - */ +// The time jitter correct for rtsp. class SrsRtspJitter { private: @@ -105,9 +99,7 @@ public: virtual srs_error_t correct(int64_t& ts); }; -/** - * the rtsp connection serve the fd. - */ +// The rtsp connection serve the fd. class SrsRtspConn : public ISrsCoroutineHandler { private: @@ -176,16 +168,14 @@ private: virtual void close(); }; -/** - * the caster for rtsp. - */ +// The caster for rtsp. class SrsRtspCaster : public ISrsTcpHandler { private: std::string output; int local_port_min; int local_port_max; - // key: port, value: whether used. + // The key: port, value: whether used. std::map used_ports; private: std::vector clients; @@ -193,19 +183,15 @@ public: SrsRtspCaster(SrsConfDirective* c); virtual ~SrsRtspCaster(); public: - /** - * alloc a rtp port from local ports pool. - * @param pport output the rtp port. - */ + // Alloc a rtp port from local ports pool. + // @param pport output the rtp port. virtual srs_error_t alloc_port(int* pport); - /** - * free the alloced rtp port. - */ + // Free the alloced rtp port. virtual void free_port(int lpmin, int lpmax); // interface ISrsTcpHandler public: virtual srs_error_t on_tcp_client(srs_netfd_t stfd); - // internal methods. +// internal methods. public: virtual void remove(SrsRtspConn* conn); }; diff --git a/trunk/src/app/srs_app_security.hpp b/trunk/src/app/srs_app_security.hpp index 47485030c..31bdcc709 100644 --- a/trunk/src/app/srs_app_security.hpp +++ b/trunk/src/app/srs_app_security.hpp @@ -32,33 +32,25 @@ class SrsConfDirective; -/** - * the security apply on vhost. - * @see https://github.com/ossrs/srs/issues/211 - */ +// The security apply on vhost. +// @see https://github.com/ossrs/srs/issues/211 class SrsSecurity { public: SrsSecurity(); virtual ~SrsSecurity(); public: - /** - * security check the client apply by vhost security strategy - * @param type the client type, publish or play. - * @param ip the ip address of client. - * @param req the request object of client. - */ + // Security check the client apply by vhost security strategy + // @param type the client type, publish or play. + // @param ip the ip address of client. + // @param req the request object of client. virtual srs_error_t check(SrsRtmpConnType type, std::string ip, SrsRequest* req); private: - /** - * security check the allow, - * @return, if allowed, ERROR_SYSTEM_SECURITY_ALLOW. - */ + // Security check the allow, + // @return, if allowed, ERROR_SYSTEM_SECURITY_ALLOW. virtual int allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip); - /** - * security check the deny, - * @return, if denied, ERROR_SYSTEM_SECURITY_DENY. - */ + // Security check the deny, + // @return, if denied, ERROR_SYSTEM_SECURITY_DENY. virtual int deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std::string ip); }; diff --git a/trunk/src/app/srs_app_st.hpp b/trunk/src/app/srs_app_st.hpp index cc837ccd3..e5120de95 100644 --- a/trunk/src/app/srs_app_st.hpp +++ b/trunk/src/app/srs_app_st.hpp @@ -31,49 +31,43 @@ #include #include -/** - * Each ST-coroutine must implements this interface, - * to do the cycle job and handle some events. - * - * Thread do a job then terminated normally, it's a SrsOneCycleThread: - * class SrsOneCycleThread : public ISrsCoroutineHandler { - * public: SrsCoroutine trd; - * public: virtual srs_error_t cycle() { - * // Do something, then return this cycle and thread terminated normally. - * } - * }; - * - * Thread has its inside loop, such as the RTMP receive thread: - * class SrsReceiveThread : public ISrsCoroutineHandler { - * public: SrsCoroutine* trd; - * public: virtual srs_error_t cycle() { - * while (true) { - * // Check whether thread interrupted. - * if ((err = trd->pull()) != srs_success) { - * return err; - * } - * // Do something, such as st_read() packets, it'll be wakeup - * // when user stop or interrupt the thread. - * } - * } - * }; - */ +// Each ST-coroutine must implements this interface, +// to do the cycle job and handle some events. +// +// Thread do a job then terminated normally, it's a SrsOneCycleThread: +// class SrsOneCycleThread : public ISrsCoroutineHandler { +// public: SrsCoroutine trd; +// public: virtual srs_error_t cycle() { +// // Do something, then return this cycle and thread terminated normally. +// } +// }; +// +// Thread has its inside loop, such as the RTMP receive thread: +// class SrsReceiveThread : public ISrsCoroutineHandler { +// public: SrsCoroutine* trd; +// public: virtual srs_error_t cycle() { +// while (true) { +// // Check whether thread interrupted. +// if ((err = trd->pull()) != srs_success) { +// return err; +// } +// // Do something, such as st_read() packets, it'll be wakeup +// // when user stop or interrupt the thread. +// } +// } +// }; class ISrsCoroutineHandler { public: ISrsCoroutineHandler(); virtual ~ISrsCoroutineHandler(); public: - /** - * Do the work. The ST-coroutine will terminated normally if it returned. - * @remark If the cycle has its own loop, it must check the thread pull. - */ + // Do the work. The ST-coroutine will terminated normally if it returned. + // @remark If the cycle has its own loop, it must check the thread pull. virtual srs_error_t cycle() = 0; }; -/** - * The corotine object. - */ +// The corotine object. class SrsCoroutine { public: @@ -89,10 +83,8 @@ public: virtual int cid() = 0; }; -/** - * An empty coroutine, user can default to this object before create any real coroutine. - * @see https://github.com/ossrs/srs/pull/908 - */ +// An empty coroutine, user can default to this object before create any real coroutine. +// @see https://github.com/ossrs/srs/pull/908 class SrsDummyCoroutine : public SrsCoroutine { public: @@ -110,20 +102,18 @@ public: typedef void* (*_ST_THREAD_CREATE_PFN)(void *(*start)(void *arg), void *arg, int joinable, int stack_size); extern _ST_THREAD_CREATE_PFN _pfn_st_thread_create; -/** - * A ST-coroutine is a lightweight thread, just like the goroutine. - * But the goroutine maybe run on different thread, while ST-coroutine only - * run in single thread, because it use setjmp and longjmp, so it may cause - * problem in multiple threads. For SRS, we only use single thread module, - * like NGINX to get very high performance, with asynchronous and non-blocking - * sockets. - * @reamrk For multiple processes, please use go-oryx to fork many SRS processes. - * Please read https://github.com/ossrs/go-oryx - * @remark For debugging of ST-coroutine, read _st_iterate_threads_flag of ST/README - * https://github.com/ossrs/state-threads/blob/st-1.9/README#L115 - * @remark We always create joinable thread, so we must join it or memory leak, - * Please read https://github.com/ossrs/srs/issues/78 - */ +// A ST-coroutine is a lightweight thread, just like the goroutine. +// But the goroutine maybe run on different thread, while ST-coroutine only +// run in single thread, because it use setjmp and longjmp, so it may cause +// problem in multiple threads. For SRS, we only use single thread module, +// like NGINX to get very high performance, with asynchronous and non-blocking +// sockets. +// @reamrk For multiple processes, please use go-oryx to fork many SRS processes. +// Please read https://github.com/ossrs/go-oryx +// @remark For debugging of ST-coroutine, read _st_iterate_threads_flag of ST/README +// https://github.com/ossrs/state-threads/blob/st-1.9/README#L115 +// @remark We always create joinable thread, so we must join it or memory leak, +// Please read https://github.com/ossrs/srs/issues/78 class SrsSTCoroutine : public SrsCoroutine { private: @@ -145,35 +135,25 @@ public: SrsSTCoroutine(const std::string& n, ISrsCoroutineHandler* h, int cid = 0); virtual ~SrsSTCoroutine(); public: - /** - * Start the thread. - * @remark Should never start it when stopped or terminated. - */ + // Start the thread. + // @remark Should never start it when stopped or terminated. virtual srs_error_t start(); - /** - * Interrupt the thread then wait to terminated. - * @remark If user want to notify thread to quit async, for example if there are - * many threads to stop like the encoder, use the interrupt to notify all threads - * to terminate then use stop to wait for each to terminate. - */ + // Interrupt the thread then wait to terminated. + // @remark If user want to notify thread to quit async, for example if there are + // many threads to stop like the encoder, use the interrupt to notify all threads + // to terminate then use stop to wait for each to terminate. virtual void stop(); - /** - * Interrupt the thread and notify it to terminate, it will be wakeup if it's blocked - * in some IO operations, such as st_read or st_write, then it will found should quit, - * finally the thread should terminated normally, user can use the stop to join it. - */ + // Interrupt the thread and notify it to terminate, it will be wakeup if it's blocked + // in some IO operations, such as st_read or st_write, then it will found should quit, + // finally the thread should terminated normally, user can use the stop to join it. virtual void interrupt(); - /** - * Check whether thread is terminated normally or error(stopped or termianted with error), - * and the thread should be running if it return ERROR_SUCCESS. - * @remark Return specified error when thread terminated normally with error. - * @remark Return ERROR_THREAD_TERMINATED when thread terminated normally without error. - * @remark Return ERROR_THREAD_INTERRUPED when thread is interrupted. - */ + // Check whether thread is terminated normally or error(stopped or termianted with error), + // and the thread should be running if it return ERROR_SUCCESS. + // @remark Return specified error when thread terminated normally with error. + // @remark Return ERROR_THREAD_TERMINATED when thread terminated normally without error. + // @remark Return ERROR_THREAD_INTERRUPED when thread is interrupted. virtual srs_error_t pull(); - /** - * Get the context id of thread. - */ + // Get the context id of thread. virtual int cid(); private: virtual srs_error_t cycle(); From 6b2c71d385c6b69497ba3fc4d1098248b9cbca5b Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 30 Apr 2019 08:30:13 +0800 Subject: [PATCH 17/25] Refine typo in files. 3.0.51 --- README.md | 1 + trunk/src/app/srs_app_async_call.hpp | 2 +- trunk/src/app/srs_app_caster_flv.hpp | 6 ++-- trunk/src/app/srs_app_conn.hpp | 4 +-- trunk/src/app/srs_app_dvr.hpp | 6 ++-- trunk/src/app/srs_app_edge.hpp | 4 +-- trunk/src/app/srs_app_encoder.hpp | 2 +- trunk/src/app/srs_app_forward.hpp | 2 +- trunk/src/app/srs_app_http_api.hpp | 6 ++-- trunk/src/app/srs_app_http_conn.hpp | 6 ++-- trunk/src/app/srs_app_http_static.hpp | 2 +- trunk/src/app/srs_app_http_stream.hpp | 6 ++-- trunk/src/app/srs_app_ingest.hpp | 4 +-- trunk/src/app/srs_app_kafka.hpp | 6 ++-- trunk/src/app/srs_app_listener.hpp | 4 +-- trunk/src/app/srs_app_log.hpp | 4 +-- trunk/src/app/srs_app_mpegts_udp.hpp | 4 +-- trunk/src/app/srs_app_ng_exec.hpp | 2 +- trunk/src/app/srs_app_recv_thread.hpp | 12 +++---- trunk/src/app/srs_app_rtmp_conn.hpp | 4 +-- trunk/src/app/srs_app_rtsp.hpp | 6 ++-- trunk/src/app/srs_app_server.hpp | 14 ++++---- trunk/src/app/srs_app_source.hpp | 4 +-- trunk/src/app/srs_app_thread.hpp | 4 +-- trunk/src/core/srs_core.hpp | 2 +- trunk/src/main/srs_main_ingest_hls.cpp | 4 +-- trunk/src/main/srs_main_server.cpp | 10 ++---- trunk/src/protocol/srs_http_stack.hpp | 4 +-- trunk/src/protocol/srs_kafka_stack.hpp | 36 ++++++++++----------- trunk/src/protocol/srs_protocol_kbps.hpp | 6 ++-- trunk/src/service/srs_service_http_conn.hpp | 2 +- trunk/src/service/srs_service_log.hpp | 2 +- trunk/src/service/srs_service_st.hpp | 2 +- 33 files changed, 90 insertions(+), 93 deletions(-) diff --git a/README.md b/README.md index 3e5ee0be1..2df020941 100755 --- a/README.md +++ b/README.md @@ -164,6 +164,7 @@ Please select according to languages: ### V3 changes +* v3.0, 2019-04-30, Refine typo in files. 3.0.51 * v3.0, 2019-04-25, Upgrade http-parser from 2.1 to 2.9.2 and cover it. 3.0.50 * v3.0, 2019-04-22, Refine in time unit. 3.0.49 * v3.0, 2019-04-07, Cover ST Coroutine and time unit. 3.0.48 diff --git a/trunk/src/app/srs_app_async_call.hpp b/trunk/src/app/srs_app_async_call.hpp index 183533457..bcadd891f 100644 --- a/trunk/src/app/srs_app_async_call.hpp +++ b/trunk/src/app/srs_app_async_call.hpp @@ -70,7 +70,7 @@ public: public: virtual srs_error_t start(); virtual void stop(); -// interface ISrsReusableThreadHandler +// Interface ISrsReusableThreadHandler public: virtual srs_error_t cycle(); }; diff --git a/trunk/src/app/srs_app_caster_flv.hpp b/trunk/src/app/srs_app_caster_flv.hpp index 8305d86c5..0db9a4588 100644 --- a/trunk/src/app/srs_app_caster_flv.hpp +++ b/trunk/src/app/srs_app_caster_flv.hpp @@ -60,13 +60,13 @@ public: virtual ~SrsAppCasterFlv(); public: virtual srs_error_t initialize(); -// interface ISrsTcpHandler +// Interface ISrsTcpHandler public: virtual srs_error_t on_tcp_client(srs_netfd_t stfd); -// interface IConnectionManager +// Interface IConnectionManager public: virtual void remove(ISrsConnection* c); -// interface ISrsHttpHandler +// Interface ISrsHttpHandler public: virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); }; diff --git a/trunk/src/app/srs_app_conn.hpp b/trunk/src/app/srs_app_conn.hpp index bd5922688..433da688d 100644 --- a/trunk/src/app/srs_app_conn.hpp +++ b/trunk/src/app/srs_app_conn.hpp @@ -66,7 +66,7 @@ protected: public: SrsConnection(IConnectionManager* cm, srs_netfd_t c, std::string cip); virtual ~SrsConnection(); -// interface ISrsKbpsDelta +// Interface ISrsKbpsDelta public: virtual void remark(int64_t* in, int64_t* out); public: @@ -84,7 +84,7 @@ public: virtual srs_error_t set_tcp_nodelay(bool v); // Set socket option SO_SNDBUF in srs_utime_t. virtual srs_error_t set_socket_buffer(srs_utime_t buffer_v); -// interface ISrsOneCycleThreadHandler +// Interface ISrsOneCycleThreadHandler public: // The thread cycle function, // when serve connection completed, terminate the loop which will terminate the thread, diff --git a/trunk/src/app/srs_app_dvr.hpp b/trunk/src/app/srs_app_dvr.hpp index ddbb80c8b..0b66b521b 100644 --- a/trunk/src/app/srs_app_dvr.hpp +++ b/trunk/src/app/srs_app_dvr.hpp @@ -103,7 +103,7 @@ private: virtual std::string generate_path(); // When update the duration of segment by rtmp msg. virtual srs_error_t on_update_duration(SrsSharedPtrMessage* msg); -// interface ISrsReloadHandler +// Interface ISrsReloadHandler public: virtual srs_error_t on_reload_vhost_dvr(std::string vhost); }; @@ -227,7 +227,7 @@ public: virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format); private: virtual srs_error_t update_duration(SrsSharedPtrMessage* msg); -// interface ISrsReloadHandler +// Interface ISrsReloadHandler public: virtual srs_error_t on_reload_vhost_dvr(std::string vhost); }; @@ -267,7 +267,7 @@ public: // mux the video packets to dvr. // @param shared_video, directly ptr, copy it if need to save it. virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format); -// interface ISrsReloadHandler +// Interface ISrsReloadHandler public: virtual srs_error_t on_reload_vhost_dvr_apply(std::string vhost); }; diff --git a/trunk/src/app/srs_app_edge.hpp b/trunk/src/app/srs_app_edge.hpp index 426b47587..24512dc86 100644 --- a/trunk/src/app/srs_app_edge.hpp +++ b/trunk/src/app/srs_app_edge.hpp @@ -125,7 +125,7 @@ public: virtual srs_error_t start(); virtual void stop(); virtual std::string get_curr_origin(); -// interface ISrsReusableThread2Handler +// Interface ISrsReusableThread2Handler public: virtual srs_error_t cycle(); private: @@ -161,7 +161,7 @@ public: virtual srs_error_t initialize(SrsSource* s, SrsPublishEdge* e, SrsRequest* r); virtual srs_error_t start(); virtual void stop(); -// interface ISrsReusableThread2Handler +// Interface ISrsReusableThread2Handler public: virtual srs_error_t cycle(); private: diff --git a/trunk/src/app/srs_app_encoder.hpp b/trunk/src/app/srs_app_encoder.hpp index 4417e5ab7..c66724bcf 100644 --- a/trunk/src/app/srs_app_encoder.hpp +++ b/trunk/src/app/srs_app_encoder.hpp @@ -52,7 +52,7 @@ public: public: virtual srs_error_t on_publish(SrsRequest* req); virtual void on_unpublish(); -// interface ISrsReusableThreadHandler. +// Interface ISrsReusableThreadHandler. public: virtual srs_error_t cycle(); private: diff --git a/trunk/src/app/srs_app_forward.hpp b/trunk/src/app/srs_app_forward.hpp index 785e07add..c23cd8da1 100644 --- a/trunk/src/app/srs_app_forward.hpp +++ b/trunk/src/app/srs_app_forward.hpp @@ -79,7 +79,7 @@ public: // Forward the video packet. // @param shared_video, directly ptr, copy it if need to save it. virtual srs_error_t on_video(SrsSharedPtrMessage* shared_video); -// interface ISrsReusableThread2Handler. +// Interface ISrsReusableThread2Handler. public: virtual srs_error_t cycle(); private: diff --git a/trunk/src/app/srs_app_http_api.hpp b/trunk/src/app/srs_app_http_api.hpp index a7eee7481..62e3aca02 100644 --- a/trunk/src/app/srs_app_http_api.hpp +++ b/trunk/src/app/srs_app_http_api.hpp @@ -187,7 +187,7 @@ public: virtual ~SrsGoApiRaw(); public: virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); -// interface ISrsReloadHandler +// Interface ISrsReloadHandler public: virtual srs_error_t on_reload_http_api_raw_api(); }; @@ -219,14 +219,14 @@ private: public: SrsHttpApi(IConnectionManager* cm, srs_netfd_t fd, SrsHttpServeMux* m, std::string cip); virtual ~SrsHttpApi(); -// interface ISrsKbpsDelta +// Interface ISrsKbpsDelta public: virtual void remark(int64_t* in, int64_t* out); protected: virtual srs_error_t do_cycle(); private: virtual srs_error_t process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); -// interface ISrsReloadHandler +// Interface ISrsReloadHandler public: virtual srs_error_t on_reload_http_api_crossdomain(); }; diff --git a/trunk/src/app/srs_app_http_conn.hpp b/trunk/src/app/srs_app_http_conn.hpp index beaa4d943..40e97f728 100644 --- a/trunk/src/app/srs_app_http_conn.hpp +++ b/trunk/src/app/srs_app_http_conn.hpp @@ -65,7 +65,7 @@ protected: public: SrsHttpConn(IConnectionManager* cm, srs_netfd_t fd, ISrsHttpServeMux* m, std::string cip); virtual ~SrsHttpConn(); -// interface ISrsKbpsDelta +// Interface ISrsKbpsDelta public: virtual void remark(int64_t* in, int64_t* out); protected: @@ -81,7 +81,7 @@ private: // e.g. log msg of connection and report to other system. // @param request: request which is converted by the last http message. virtual srs_error_t on_disconnect(SrsRequest* req); -// interface ISrsReloadHandler +// Interface ISrsReloadHandler public: virtual srs_error_t on_reload_http_stream_crossdomain(); }; @@ -115,7 +115,7 @@ public: virtual ~SrsHttpServer(); public: virtual srs_error_t initialize(); -// interface ISrsHttpServeMux +// Interface ISrsHttpServeMux public: virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); public: diff --git a/trunk/src/app/srs_app_http_static.hpp b/trunk/src/app/srs_app_http_static.hpp index f7e5a2fa0..61e153953 100644 --- a/trunk/src/app/srs_app_http_static.hpp +++ b/trunk/src/app/srs_app_http_static.hpp @@ -57,7 +57,7 @@ public: virtual srs_error_t initialize(); private: virtual srs_error_t mount_vhost(std::string vhost, std::string& pmount); -// interface ISrsReloadHandler. +// Interface ISrsReloadHandler. public: virtual srs_error_t on_reload_vhost_added(std::string vhost); virtual srs_error_t on_reload_vhost_http_updated(); diff --git a/trunk/src/app/srs_app_http_stream.hpp b/trunk/src/app/srs_app_http_stream.hpp index 75ca812bc..d04c05df4 100755 --- a/trunk/src/app/srs_app_http_stream.hpp +++ b/trunk/src/app/srs_app_http_stream.hpp @@ -50,7 +50,7 @@ public: public: virtual srs_error_t start(); virtual srs_error_t dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter); -// interface ISrsEndlessThreadHandler. +// Interface ISrsEndlessThreadHandler. public: virtual srs_error_t cycle(); }; @@ -255,11 +255,11 @@ public: // HTTP flv/ts/mp3/aac stream virtual srs_error_t http_mount(SrsSource* s, SrsRequest* r); virtual void http_unmount(SrsSource* s, SrsRequest* r); -// interface ISrsReloadHandler. +// Interface ISrsReloadHandler. public: virtual srs_error_t on_reload_vhost_added(std::string vhost); virtual srs_error_t on_reload_vhost_http_remux_updated(std::string vhost); -// interface ISrsHttpMatchHijacker +// Interface ISrsHttpMatchHijacker public: virtual srs_error_t hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph); private: diff --git a/trunk/src/app/srs_app_ingest.hpp b/trunk/src/app/srs_app_ingest.hpp index 79659439f..2314bc726 100644 --- a/trunk/src/app/srs_app_ingest.hpp +++ b/trunk/src/app/srs_app_ingest.hpp @@ -85,7 +85,7 @@ public: virtual void stop(); private: virtual void fast_stop(); -// interface ISrsReusableThreadHandler. +// Interface ISrsReusableThreadHandler. public: virtual srs_error_t cycle(); private: @@ -97,7 +97,7 @@ private: virtual srs_error_t parse_engines(SrsConfDirective* vhost, SrsConfDirective* ingest); virtual srs_error_t initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, SrsConfDirective* ingest, SrsConfDirective* engine); virtual void show_ingest_log_message(); -// interface ISrsReloadHandler. +// Interface ISrsReloadHandler. public: virtual srs_error_t on_reload_vhost_removed(std::string vhost); virtual srs_error_t on_reload_vhost_added(std::string vhost); diff --git a/trunk/src/app/srs_app_kafka.hpp b/trunk/src/app/srs_app_kafka.hpp index 38e0ca20e..835a09686 100644 --- a/trunk/src/app/srs_app_kafka.hpp +++ b/trunk/src/app/srs_app_kafka.hpp @@ -81,7 +81,7 @@ private: public: SrsKafkaMessage(SrsKafkaProducer* p, int k, SrsJsonObject* j); virtual ~SrsKafkaMessage(); -// interface ISrsAsyncCallTask +// Interface ISrsAsyncCallTask public: virtual srs_error_t call(); virtual std::string to_string(); @@ -168,11 +168,11 @@ public: // @param key the key to map to the partition, user can use cid or hash. // @param obj the json object; user must never free it again. virtual srs_error_t send(int key, SrsJsonObject* obj); -// interface ISrsKafkaCluster +// Interface ISrsKafkaCluster public: virtual srs_error_t on_client(int key, SrsListenerType type, std::string ip); virtual srs_error_t on_close(int key); -// interface ISrsReusableThreadHandler +// Interface ISrsReusableThreadHandler public: virtual srs_error_t cycle(); private: diff --git a/trunk/src/app/srs_app_listener.hpp b/trunk/src/app/srs_app_listener.hpp index 22e84b278..538ecf1b9 100644 --- a/trunk/src/app/srs_app_listener.hpp +++ b/trunk/src/app/srs_app_listener.hpp @@ -87,7 +87,7 @@ public: virtual srs_netfd_t stfd(); public: virtual srs_error_t listen(); -// interface ISrsReusableThreadHandler. +// Interface ISrsReusableThreadHandler. public: virtual srs_error_t cycle(); }; @@ -110,7 +110,7 @@ public: virtual int fd(); public: virtual srs_error_t listen(); -// interface ISrsReusableThreadHandler. +// Interface ISrsReusableThreadHandler. public: virtual srs_error_t cycle(); }; diff --git a/trunk/src/app/srs_app_log.hpp b/trunk/src/app/srs_app_log.hpp index afb58b1cc..c1618243c 100644 --- a/trunk/src/app/srs_app_log.hpp +++ b/trunk/src/app/srs_app_log.hpp @@ -51,7 +51,7 @@ private: public: SrsFastLog(); virtual ~SrsFastLog(); -// interface ISrsLog +// Interface ISrsLog public: virtual srs_error_t initialize(); virtual void reopen(); @@ -60,7 +60,7 @@ public: virtual void trace(const char* tag, int context_id, const char* fmt, ...); virtual void warn(const char* tag, int context_id, const char* fmt, ...); virtual void error(const char* tag, int context_id, const char* fmt, ...); -// interface ISrsReloadHandler. +// Interface ISrsReloadHandler. public: virtual srs_error_t on_reload_utc_time(); virtual srs_error_t on_reload_log_tank(); diff --git a/trunk/src/app/srs_app_mpegts_udp.hpp b/trunk/src/app/srs_app_mpegts_udp.hpp index 403a496ba..b14eb775e 100644 --- a/trunk/src/app/srs_app_mpegts_udp.hpp +++ b/trunk/src/app/srs_app_mpegts_udp.hpp @@ -91,12 +91,12 @@ private: public: SrsMpegtsOverUdp(SrsConfDirective* c); virtual ~SrsMpegtsOverUdp(); -// interface ISrsUdpHandler +// Interface ISrsUdpHandler public: virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf); private: virtual srs_error_t on_udp_bytes(std::string host, int port, char* buf, int nb_buf); -// interface ISrsTsHandler +// Interface ISrsTsHandler public: virtual srs_error_t on_ts_message(SrsTsMessage* msg); private: diff --git a/trunk/src/app/srs_app_ng_exec.hpp b/trunk/src/app/srs_app_ng_exec.hpp index d47dc42e2..8cdf1e96d 100644 --- a/trunk/src/app/srs_app_ng_exec.hpp +++ b/trunk/src/app/srs_app_ng_exec.hpp @@ -51,7 +51,7 @@ public: public: virtual srs_error_t on_publish(SrsRequest* req); virtual void on_unpublish(); -// interface ISrsReusableThreadHandler. +// Interface ISrsReusableThreadHandler. public: virtual srs_error_t cycle(); private: diff --git a/trunk/src/app/srs_app_recv_thread.hpp b/trunk/src/app/srs_app_recv_thread.hpp index 940b91564..65206353f 100644 --- a/trunk/src/app/srs_app_recv_thread.hpp +++ b/trunk/src/app/srs_app_recv_thread.hpp @@ -94,7 +94,7 @@ public: virtual srs_error_t start(); virtual void stop(); virtual void stop_loop(); -// interface ISrsReusableThread2Handler +// Interface ISrsReusableThread2Handler public: virtual srs_error_t cycle(); private: @@ -126,7 +126,7 @@ public: virtual int size(); virtual SrsCommonMessage* pump(); virtual srs_error_t error_code(); -// interface ISrsMessagePumper +// Interface ISrsMessagePumper public: virtual srs_error_t consume(SrsCommonMessage* msg); virtual bool interrupted(); @@ -184,19 +184,19 @@ public: public: virtual srs_error_t start(); virtual void stop(); -// interface ISrsMessagePumper +// Interface ISrsMessagePumper public: virtual srs_error_t consume(SrsCommonMessage* msg); virtual bool interrupted(); virtual void interrupt(srs_error_t err); virtual void on_start(); virtual void on_stop(); -// interface IMergeReadHandler +// Interface IMergeReadHandler public: #ifdef SRS_PERF_MERGED_READ virtual void on_read(ssize_t nread); #endif -// interface ISrsReloadHandler +// Interface ISrsReloadHandler public: virtual srs_error_t on_reload_vhost_publish(std::string vhost); virtual srs_error_t on_reload_vhost_realtime(std::string vhost); @@ -220,7 +220,7 @@ public: virtual srs_error_t start(); public: virtual srs_error_t pull(); -// interface ISrsOneCycleThreadHandler +// Interface ISrsOneCycleThreadHandler public: virtual srs_error_t cycle(); }; diff --git a/trunk/src/app/srs_app_rtmp_conn.hpp b/trunk/src/app/srs_app_rtmp_conn.hpp index 0f5cdc932..b84d6f4a8 100644 --- a/trunk/src/app/srs_app_rtmp_conn.hpp +++ b/trunk/src/app/srs_app_rtmp_conn.hpp @@ -127,14 +127,14 @@ public: virtual void dispose(); protected: virtual srs_error_t do_cycle(); -// interface ISrsReloadHandler +// Interface ISrsReloadHandler public: virtual srs_error_t on_reload_vhost_removed(std::string vhost); virtual srs_error_t on_reload_vhost_play(std::string vhost); virtual srs_error_t on_reload_vhost_tcp_nodelay(std::string vhost); virtual srs_error_t on_reload_vhost_realtime(std::string vhost); virtual srs_error_t on_reload_vhost_publish(std::string vhost); -// interface ISrsKbpsDelta +// Interface ISrsKbpsDelta public: virtual void remark(int64_t* in, int64_t* out); private: diff --git a/trunk/src/app/srs_app_rtsp.hpp b/trunk/src/app/srs_app_rtsp.hpp index 28d6014ab..7a1ac77fc 100644 --- a/trunk/src/app/srs_app_rtsp.hpp +++ b/trunk/src/app/srs_app_rtsp.hpp @@ -68,7 +68,7 @@ public: public: virtual int port(); virtual srs_error_t listen(); -// interface ISrsUdpHandler +// Interface ISrsUdpHandler public: virtual srs_error_t on_udp_packet(const sockaddr* from, const int fromlen, char* buf, int nb_buf); }; @@ -148,7 +148,7 @@ private: // internal methods public: virtual srs_error_t on_rtp_packet(SrsRtpPacket* pkt, int stream_id); -// interface ISrsOneCycleThreadHandler +// Interface ISrsOneCycleThreadHandler public: virtual srs_error_t cycle(); private: @@ -188,7 +188,7 @@ public: virtual srs_error_t alloc_port(int* pport); // Free the alloced rtp port. virtual void free_port(int lpmin, int lpmax); -// interface ISrsTcpHandler +// Interface ISrsTcpHandler public: virtual srs_error_t on_tcp_client(srs_netfd_t stfd); // internal methods. diff --git a/trunk/src/app/srs_app_server.hpp b/trunk/src/app/srs_app_server.hpp index 437e99db4..b8366ea21 100644 --- a/trunk/src/app/srs_app_server.hpp +++ b/trunk/src/app/srs_app_server.hpp @@ -100,7 +100,7 @@ public: virtual ~SrsBufferListener(); public: virtual srs_error_t listen(std::string ip, int port); -// interface ISrsTcpHandler +// Interface ISrsTcpHandler public: virtual srs_error_t on_tcp_client(srs_netfd_t stfd); }; @@ -116,7 +116,7 @@ public: virtual ~SrsRtspListener(); public: virtual srs_error_t listen(std::string i, int p); -// interface ISrsTcpHandler +// Interface ISrsTcpHandler public: virtual srs_error_t on_tcp_client(srs_netfd_t stfd); }; @@ -132,7 +132,7 @@ public: virtual ~SrsHttpFlvListener(); public: virtual srs_error_t listen(std::string i, int p); -// interface ISrsTcpHandler +// Interface ISrsTcpHandler public: virtual srs_error_t on_tcp_client(srs_netfd_t stfd); }; @@ -176,7 +176,7 @@ public: public: virtual srs_error_t initialize(); virtual srs_error_t start(); -// interface ISrsEndlessThreadHandler. +// Interface ISrsEndlessThreadHandler. public: virtual srs_error_t cycle(); private: @@ -296,13 +296,13 @@ public: virtual srs_error_t accept_client(SrsListenerType type, srs_netfd_t stfd); private: virtual srs_error_t fd2conn(SrsListenerType type, srs_netfd_t stfd, SrsConnection** pconn); -// interface IConnectionManager +// Interface IConnectionManager public: // A callback for connection to remove itself. // When connection thread cycle terminated, callback this to delete connection. // @see SrsConnection.on_thread_stop(). virtual void remove(ISrsConnection* c); -// interface ISrsReloadHandler. +// Interface ISrsReloadHandler. public: virtual srs_error_t on_reload_listen(); virtual srs_error_t on_reload_pid(); @@ -313,7 +313,7 @@ public: virtual srs_error_t on_reload_http_stream_enabled(); virtual srs_error_t on_reload_http_stream_disabled(); virtual srs_error_t on_reload_http_stream_updated(); -// interface ISrsSourceHandler +// Interface ISrsSourceHandler public: virtual srs_error_t on_publish(SrsSource* s, SrsRequest* r); virtual void on_unpublish(SrsSource* s, SrsRequest* r); diff --git a/trunk/src/app/srs_app_source.hpp b/trunk/src/app/srs_app_source.hpp index bed9850bf..6e730cde6 100644 --- a/trunk/src/app/srs_app_source.hpp +++ b/trunk/src/app/srs_app_source.hpp @@ -382,7 +382,7 @@ public: virtual srs_error_t on_forwarder_start(SrsForwarder* forwarder); // For the SrsDvr to callback to request the sequence headers. virtual srs_error_t on_dvr_request_sh(); -// interface ISrsReloadHandler +// Interface ISrsReloadHandler public: virtual srs_error_t on_reload_vhost_forward(std::string vhost); virtual srs_error_t on_reload_vhost_dash(std::string vhost); @@ -519,7 +519,7 @@ public: public: // Initialize the hls with handlers. virtual srs_error_t initialize(SrsRequest* r, ISrsSourceHandler* h); -// interface ISrsReloadHandler +// Interface ISrsReloadHandler public: virtual srs_error_t on_reload_vhost_play(std::string vhost); public: diff --git a/trunk/src/app/srs_app_thread.hpp b/trunk/src/app/srs_app_thread.hpp index f02deb8d2..2d542d941 100644 --- a/trunk/src/app/srs_app_thread.hpp +++ b/trunk/src/app/srs_app_thread.hpp @@ -46,10 +46,10 @@ public: virtual ~SrsCoroutineManager(); public: srs_error_t start(); -// interface ISrsCoroutineHandler +// Interface ISrsCoroutineHandler public: virtual srs_error_t cycle(); -// interface IConnectionManager +// Interface IConnectionManager public: virtual void remove(ISrsConnection* c); private: diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 27eec767b..56a727ed4 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -27,7 +27,7 @@ // The version config. #define VERSION_MAJOR 3 #define VERSION_MINOR 0 -#define VERSION_REVISION 50 +#define VERSION_REVISION 51 // The macros generated by configure script. #include diff --git a/trunk/src/main/srs_main_ingest_hls.cpp b/trunk/src/main/srs_main_ingest_hls.cpp index e9cdb29dd..1c7f02955 100644 --- a/trunk/src/main/srs_main_ingest_hls.cpp +++ b/trunk/src/main/srs_main_ingest_hls.cpp @@ -662,10 +662,10 @@ private: public: SrsIngestHlsOutput(SrsHttpUri* rtmp); virtual ~SrsIngestHlsOutput(); -// interface ISrsTsHandler +// Interface ISrsTsHandler public: virtual srs_error_t on_ts_message(SrsTsMessage* msg); -// interface IAacHandler +// Interface IAacHandler public: virtual int on_aac_frame(char* frame, int frame_size, double duration); private: diff --git a/trunk/src/main/srs_main_server.cpp b/trunk/src/main/srs_main_server.cpp index 08db48944..25577f7d4 100644 --- a/trunk/src/main/srs_main_server.cpp +++ b/trunk/src/main/srs_main_server.cpp @@ -373,17 +373,13 @@ string srs_getenv(const char* name) srs_error_t run(SrsServer* svr) { srs_error_t err = srs_success; - - /** - * we do nothing in the constructor of server, - * and use initialize to create members, set hooks for instance the reload handler, - * all initialize will done in this stage. - */ + + // Initialize the whole system, set hooks to handle server level events. if ((err = svr->initialize(NULL)) != srs_success) { return srs_error_wrap(err, "server initialize"); } - // if not deamon, directly run master. + // If not deamon, directly run master. if (!_srs_config->get_deamon()) { if ((err = run_master(svr)) != srs_success) { return srs_error_wrap(err, "run master"); diff --git a/trunk/src/protocol/srs_http_stack.hpp b/trunk/src/protocol/srs_http_stack.hpp index 28a511145..062178d57 100644 --- a/trunk/src/protocol/srs_http_stack.hpp +++ b/trunk/src/protocol/srs_http_stack.hpp @@ -392,7 +392,7 @@ public: // Handle registers the handler for the given pattern. // If a handler already exists for pattern, Handle panics. virtual srs_error_t handle(std::string pattern, ISrsHttpHandler* handler); -// interface ISrsHttpServeMux +// Interface ISrsHttpServeMux public: virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); public: @@ -415,7 +415,7 @@ public: virtual ~SrsHttpCorsMux(); public: virtual srs_error_t initialize(ISrsHttpServeMux* worker, bool cros_enabled); -// interface ISrsHttpServeMux +// Interface ISrsHttpServeMux public: virtual srs_error_t serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); }; diff --git a/trunk/src/protocol/srs_kafka_stack.hpp b/trunk/src/protocol/srs_kafka_stack.hpp index d871bcf95..8665d74fa 100644 --- a/trunk/src/protocol/srs_kafka_stack.hpp +++ b/trunk/src/protocol/srs_kafka_stack.hpp @@ -77,7 +77,7 @@ public: virtual bool empty(); virtual std::string to_str(); virtual void set_value(std::string v); -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); @@ -106,7 +106,7 @@ public: virtual void set_value(std::string v); virtual void set_value(const char* v, int nb_v); virtual uint32_t crc32(uint32_t previous); -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); @@ -164,7 +164,7 @@ public: { return elems.at(index); } -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes() { @@ -251,7 +251,7 @@ public: { return elems.at(index); } -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes() { @@ -400,7 +400,7 @@ public: virtual bool is_offset_commit_request(); virtual bool is_offset_fetch_request(); virtual bool is_consumer_metadata_request(); -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); @@ -466,7 +466,7 @@ public: * get the correlation id of response message. */ virtual int32_t correlation_id(); -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); @@ -533,7 +533,7 @@ private: * get the raw message, bytes after the message_size. */ virtual int raw_message_size(); -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); @@ -554,7 +554,7 @@ public: virtual ~SrsKafkaRawMessageSet(); public: virtual void append(SrsKafkaRawMessage* msg); -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); @@ -585,7 +585,7 @@ public: * get the api key of request. */ virtual SrsKafkaApiKey api_key(); -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); @@ -608,7 +608,7 @@ public: * @param s an int value specifies the size of message in header. */ virtual void update_header(int s); -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); @@ -638,7 +638,7 @@ public: virtual ~SrsKafkaTopicMetadataRequest(); public: virtual void add_topic(std::string topic); -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); @@ -658,7 +658,7 @@ public: public: SrsKafkaBroker(); virtual ~SrsKafkaBroker(); -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); @@ -675,7 +675,7 @@ public: public: SrsKafkaPartitionMetadata(); virtual ~SrsKafkaPartitionMetadata(); -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); @@ -690,7 +690,7 @@ public: public: SrsKafkaTopicMetadata(); virtual ~SrsKafkaTopicMetadata(); -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); @@ -713,7 +713,7 @@ public: public: SrsKafkaTopicMetadataResponse(); virtual ~SrsKafkaTopicMetadataResponse(); -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); @@ -740,7 +740,7 @@ public: * messages in set. */ SrsKafkaRawMessageSet messages; -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); @@ -757,7 +757,7 @@ public: * messages of partitions. */ SrsKafkaArray partitions; -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); @@ -801,7 +801,7 @@ public: public: SrsKafkaProducerRequest(); virtual ~SrsKafkaProducerRequest(); -// interface ISrsCodec +// Interface ISrsCodec public: virtual int nb_bytes(); virtual srs_error_t encode(SrsBuffer* buf); diff --git a/trunk/src/protocol/srs_protocol_kbps.hpp b/trunk/src/protocol/srs_protocol_kbps.hpp index 6dcd15067..64d689307 100644 --- a/trunk/src/protocol/srs_protocol_kbps.hpp +++ b/trunk/src/protocol/srs_protocol_kbps.hpp @@ -221,14 +221,14 @@ public: * use the add_delta() is better solutions. */ virtual void sample(); -// interface ISrsProtocolStatistic +// Interface ISrsProtocolStatistic public: virtual int64_t get_send_bytes(); virtual int64_t get_recv_bytes(); -// interface ISrsKbpsDelta +// Interface ISrsKbpsDelta public: virtual void remark(int64_t* in, int64_t* out); -// interface ISrsMemorySizer +// Interface ISrsMemorySizer public: virtual int size_memory(); }; diff --git a/trunk/src/service/srs_service_http_conn.hpp b/trunk/src/service/srs_service_http_conn.hpp index 633ba8634..3bfdfb4ee 100644 --- a/trunk/src/service/srs_service_http_conn.hpp +++ b/trunk/src/service/srs_service_http_conn.hpp @@ -253,7 +253,7 @@ public: public: // Initialize the response reader with buffer. virtual srs_error_t initialize(SrsFastStream* buffer); -// interface ISrsHttpResponseReader +// Interface ISrsHttpResponseReader public: virtual bool eof(); virtual srs_error_t read(char* data, int nb_data, int* nb_read); diff --git a/trunk/src/service/srs_service_log.hpp b/trunk/src/service/srs_service_log.hpp index fc2d49198..7ed23ba32 100644 --- a/trunk/src/service/srs_service_log.hpp +++ b/trunk/src/service/srs_service_log.hpp @@ -59,7 +59,7 @@ private: public: SrsConsoleLog(SrsLogLevel l, bool u); virtual ~SrsConsoleLog(); -// interface ISrsLog +// Interface ISrsLog public: virtual srs_error_t initialize(); virtual void reopen(); diff --git a/trunk/src/service/srs_service_st.hpp b/trunk/src/service/srs_service_st.hpp index 7c1bcba2c..383b1323d 100644 --- a/trunk/src/service/srs_service_st.hpp +++ b/trunk/src/service/srs_service_st.hpp @@ -170,7 +170,7 @@ private: // Close the connection to server. // @remark User should never use the client when close it. virtual void close(); -// interface ISrsProtocolReadWriter +// Interface ISrsProtocolReadWriter public: virtual bool is_never_timeout(srs_utime_t tm); virtual void set_recv_timeout(srs_utime_t tm); From 0564cdedec588bc4e1ada68e7eced0b5bda10145 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 30 Apr 2019 08:31:36 +0800 Subject: [PATCH 18/25] Refine typo in comments. --- trunk/src/app/srs_app_source.hpp | 2 +- trunk/src/libs/srs_lib_simple_socket.cpp | 8 ++++---- trunk/src/libs/srs_lib_simple_socket.hpp | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/trunk/src/app/srs_app_source.hpp b/trunk/src/app/srs_app_source.hpp index 6e730cde6..613c7240f 100644 --- a/trunk/src/app/srs_app_source.hpp +++ b/trunk/src/app/srs_app_source.hpp @@ -229,7 +229,7 @@ public: #endif // when client send the pause message. virtual srs_error_t on_play_client_pause(bool is_pause); - // ISrsWakable +// Interface ISrsWakable public: // when the consumer(for player) got msg from recv thread, // it must be processed for maybe it's a close msg, so the cond diff --git a/trunk/src/libs/srs_lib_simple_socket.cpp b/trunk/src/libs/srs_lib_simple_socket.cpp index ac3d173f6..844932ea0 100644 --- a/trunk/src/libs/srs_lib_simple_socket.cpp +++ b/trunk/src/libs/srs_lib_simple_socket.cpp @@ -365,7 +365,7 @@ int SimpleSocketStream::connect(const char* server_ip, int port) return srs_hijack_io_connect(io, server_ip, port); } -// ISrsReader +// Interface ISrsReader srs_error_t SimpleSocketStream::read(void* buf, size_t size, ssize_t* nread) { srs_assert(io); @@ -376,7 +376,7 @@ srs_error_t SimpleSocketStream::read(void* buf, size_t size, ssize_t* nread) return srs_success; } -// ISrsProtocolReader +// Interface ISrsProtocolReader void SimpleSocketStream::set_recv_timeout(srs_utime_t tm) { srs_assert(io); @@ -395,7 +395,7 @@ int64_t SimpleSocketStream::get_recv_bytes() return srs_hijack_io_get_recv_bytes(io); } -// ISrsProtocolWriter +// Interface ISrsProtocolWriter void SimpleSocketStream::set_send_timeout(srs_utime_t tm) { srs_assert(io); @@ -424,7 +424,7 @@ srs_error_t SimpleSocketStream::writev(const iovec *iov, int iov_size, ssize_t* return srs_success; } -// ISrsProtocolReadWriter +// Interface ISrsProtocolReadWriter bool SimpleSocketStream::is_never_timeout(srs_utime_t tm) { srs_assert(io); diff --git a/trunk/src/libs/srs_lib_simple_socket.hpp b/trunk/src/libs/srs_lib_simple_socket.hpp index 16685eadf..a03fa96b5 100644 --- a/trunk/src/libs/srs_lib_simple_socket.hpp +++ b/trunk/src/libs/srs_lib_simple_socket.hpp @@ -49,21 +49,21 @@ public: virtual srs_hijack_io_t hijack_io(); virtual int create_socket(srs_rtmp_t owner); virtual int connect(const char* server, int port); -// ISrsReader +// Interface ISrsReader public: virtual srs_error_t read(void* buf, size_t size, ssize_t* nread); -// ISrsProtocolReader +// Interface ISrsProtocolReader public: virtual void set_recv_timeout(srs_utime_t tm); virtual srs_utime_t get_recv_timeout(); virtual int64_t get_recv_bytes(); -// ISrsProtocolWriter +// Interface ISrsProtocolWriter public: virtual void set_send_timeout(srs_utime_t tm); virtual srs_utime_t get_send_timeout(); virtual int64_t get_send_bytes(); virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t* nwrite); -// ISrsProtocolReadWriter +// Interface ISrsProtocolReadWriter public: virtual bool is_never_timeout(srs_utime_t tm); virtual srs_error_t read_fully(void* buf, size_t size, ssize_t* nread); From ad3749a4d5307eddf3c79da1941fd79ce0a14963 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 30 Apr 2019 08:38:57 +0800 Subject: [PATCH 19/25] Remove noisy informations. --- trunk/src/app/srs_app_config.cpp | 4 +--- trunk/src/app/srs_app_http_api.cpp | 2 -- trunk/src/app/srs_app_source.cpp | 3 +-- trunk/src/core/srs_core.hpp | 4 ---- trunk/src/main/srs_main_server.cpp | 3 +-- trunk/src/protocol/srs_rtmp_stack.cpp | 6 +----- trunk/src/service/srs_service_rtmp_conn.cpp | 4 ---- 7 files changed, 4 insertions(+), 22 deletions(-) diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 8ad0d826a..ede53a66a 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -3433,10 +3433,9 @@ srs_error_t SrsConfig::parse_argv(int& i, char** argv) void SrsConfig::print_help(char** argv) { printf( - RTMP_SIG_SRS_SERVER " " RTMP_SIG_SRS_COPYRIGHT "\n" + RTMP_SIG_SRS_SERVER "\n" "License: " RTMP_SIG_SRS_LICENSE "\n" "Primary: " RTMP_SIG_SRS_PRIMARY "\n" - "Authors: " RTMP_SIG_SRS_AUTHROS "\n" "Build: " SRS_AUTO_BUILD_DATE " Configuration:" SRS_AUTO_USER_CONFIGURE "\n" "Features:" SRS_AUTO_CONFIGURE "\n""\n" "Usage: %s [-h?vVgG] [[-t] -c ]\n" @@ -3448,7 +3447,6 @@ void SrsConfig::print_help(char** argv) " -t : test configuration file, exit(error_code).\n" " -c filename : use configuration file for SRS\n" "\n" - RTMP_SIG_SRS_WEB "\n" RTMP_SIG_SRS_URL "\n" "Email: " RTMP_SIG_SRS_EMAIL "\n" "\n" diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index b31702ef2..8671fcc62 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -552,8 +552,6 @@ srs_error_t SrsGoApiAuthors::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa data->set("primary", SrsJsonAny::str(RTMP_SIG_SRS_PRIMARY)); data->set("license", SrsJsonAny::str(RTMP_SIG_SRS_LICENSE)); - data->set("copyright", SrsJsonAny::str(RTMP_SIG_SRS_COPYRIGHT)); - data->set("authors", SrsJsonAny::str(RTMP_SIG_SRS_AUTHROS)); data->set("contributors", SrsJsonAny::str(SRS_AUTO_CONSTRIBUTORS)); return srs_api_response(w, r, obj->dumps()); diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index 1560a8794..7115c3db9 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -1591,8 +1591,7 @@ srs_error_t SrsMetaCache::update_data(SrsMessageHeader* header, SrsOnMetaDataPac // add server info to metadata metadata->metadata->set("server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER)); metadata->metadata->set("srs_primary", SrsAmf0Any::str(RTMP_SIG_SRS_PRIMARY)); - metadata->metadata->set("srs_authors", SrsAmf0Any::str(RTMP_SIG_SRS_AUTHROS)); - + // version, for example, 1.0.0 // add version to metadata, please donot remove it, for debug. metadata->metadata->set("server_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION)); diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 56a727ed4..95cd3c018 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -35,13 +35,9 @@ // The project informations, may sent to client in HTTP header or RTMP metadata. #define RTMP_SIG_SRS_KEY "SRS" #define RTMP_SIG_SRS_CODE "OuXuli" -#define RTMP_SIG_SRS_AUTHROS "winlin,wenjie.zhao" -#define RTMP_SIG_SRS_WEB "http://ossrs.net" #define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com" -#define RTMP_SIG_SRS_ROLE "cluster" #define RTMP_SIG_SRS_URL "https://github.com/ossrs/srs" #define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)" -#define RTMP_SIG_SRS_COPYRIGHT "Copyright (c) 2013-2019 " RTMP_SIG_SRS_KEY "(" RTMP_SIG_SRS_AUTHROS ")" #define RTMP_SIG_SRS_PRIMARY RTMP_SIG_SRS_KEY "/" VERSION_STABLE_BRANCH #define RTMP_SIG_SRS_HANDSHAKE RTMP_SIG_SRS_KEY "(" RTMP_SIG_SRS_VERSION ")" #define RTMP_SIG_SRS_VERSION SRS_XSTR(VERSION_MAJOR) "." SRS_XSTR(VERSION_MINOR) "." SRS_XSTR(VERSION_REVISION) diff --git a/trunk/src/main/srs_main_server.cpp b/trunk/src/main/srs_main_server.cpp index 25577f7d4..339af3357 100644 --- a/trunk/src/main/srs_main_server.cpp +++ b/trunk/src/main/srs_main_server.cpp @@ -119,8 +119,7 @@ srs_error_t do_main(int argc, char** argv) // config already applied to log. srs_trace(RTMP_SIG_SRS_SERVER ", stable is " RTMP_SIG_SRS_PRIMARY); - srs_trace("license: " RTMP_SIG_SRS_LICENSE ", " RTMP_SIG_SRS_COPYRIGHT); - srs_trace("authors: " RTMP_SIG_SRS_AUTHROS); + srs_trace("license: " RTMP_SIG_SRS_LICENSE); srs_trace("contributors: " SRS_AUTO_CONSTRIBUTORS); srs_trace("build: %s, configure:%s, uname: %s", SRS_AUTO_BUILD_DATE, SRS_AUTO_USER_CONFIGURE, SRS_AUTO_UNAME); srs_trace("configure detail: " SRS_AUTO_CONFIGURE); diff --git a/trunk/src/protocol/srs_rtmp_stack.cpp b/trunk/src/protocol/srs_rtmp_stack.cpp index 21fe1826f..5ea56cbbf 100644 --- a/trunk/src/protocol/srs_rtmp_stack.cpp +++ b/trunk/src/protocol/srs_rtmp_stack.cpp @@ -2385,15 +2385,11 @@ srs_error_t SrsRtmpServer::response_connect_app(SrsRequest *req, const char* ser data->set("srs_sig", SrsAmf0Any::str(RTMP_SIG_SRS_KEY)); data->set("srs_server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER)); data->set("srs_license", SrsAmf0Any::str(RTMP_SIG_SRS_LICENSE)); - data->set("srs_role", SrsAmf0Any::str(RTMP_SIG_SRS_ROLE)); data->set("srs_url", SrsAmf0Any::str(RTMP_SIG_SRS_URL)); data->set("srs_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION)); - data->set("srs_site", SrsAmf0Any::str(RTMP_SIG_SRS_WEB)); data->set("srs_email", SrsAmf0Any::str(RTMP_SIG_SRS_EMAIL)); - data->set("srs_copyright", SrsAmf0Any::str(RTMP_SIG_SRS_COPYRIGHT)); data->set("srs_primary", SrsAmf0Any::str(RTMP_SIG_SRS_PRIMARY)); - data->set("srs_authors", SrsAmf0Any::str(RTMP_SIG_SRS_AUTHROS)); - + if (server_ip) { data->set("srs_server_ip", SrsAmf0Any::str(server_ip)); } diff --git a/trunk/src/service/srs_service_rtmp_conn.cpp b/trunk/src/service/srs_service_rtmp_conn.cpp index 575c151c8..c447ea020 100644 --- a/trunk/src/service/srs_service_rtmp_conn.cpp +++ b/trunk/src/service/srs_service_rtmp_conn.cpp @@ -118,14 +118,10 @@ srs_error_t SrsBasicRtmpClient::do_connect_app(string local_ip, bool debug) data->set("srs_sig", SrsAmf0Any::str(RTMP_SIG_SRS_KEY)); data->set("srs_server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER)); data->set("srs_license", SrsAmf0Any::str(RTMP_SIG_SRS_LICENSE)); - data->set("srs_role", SrsAmf0Any::str(RTMP_SIG_SRS_ROLE)); data->set("srs_url", SrsAmf0Any::str(RTMP_SIG_SRS_URL)); data->set("srs_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION)); - data->set("srs_site", SrsAmf0Any::str(RTMP_SIG_SRS_WEB)); data->set("srs_email", SrsAmf0Any::str(RTMP_SIG_SRS_EMAIL)); - data->set("srs_copyright", SrsAmf0Any::str(RTMP_SIG_SRS_COPYRIGHT)); data->set("srs_primary", SrsAmf0Any::str(RTMP_SIG_SRS_PRIMARY)); - data->set("srs_authors", SrsAmf0Any::str(RTMP_SIG_SRS_AUTHROS)); // for edge to directly get the id of client. data->set("srs_pid", SrsAmf0Any::number(getpid())); data->set("srs_id", SrsAmf0Any::number(_srs_context->get_id())); From 6dbe79ad024f608ea04b63af368048d08bf7a488 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 30 Apr 2019 08:43:12 +0800 Subject: [PATCH 20/25] Remove noisy informations. --- trunk/src/app/srs_app_config.cpp | 6 +----- trunk/src/app/srs_app_http_api.cpp | 1 - trunk/src/app/srs_app_source.cpp | 1 - trunk/src/core/srs_core.hpp | 3 --- trunk/src/main/srs_main_server.cpp | 2 +- trunk/src/protocol/srs_rtmp_handshake.cpp | 3 +++ trunk/src/protocol/srs_rtmp_stack.cpp | 2 -- trunk/src/service/srs_service_rtmp_conn.cpp | 2 -- 8 files changed, 5 insertions(+), 15 deletions(-) diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index ede53a66a..c70cdb80f 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -3433,9 +3433,8 @@ srs_error_t SrsConfig::parse_argv(int& i, char** argv) void SrsConfig::print_help(char** argv) { printf( - RTMP_SIG_SRS_SERVER "\n" + RTMP_SIG_SRS_SERVER RTMP_SIG_SRS_URL "\n" "License: " RTMP_SIG_SRS_LICENSE "\n" - "Primary: " RTMP_SIG_SRS_PRIMARY "\n" "Build: " SRS_AUTO_BUILD_DATE " Configuration:" SRS_AUTO_USER_CONFIGURE "\n" "Features:" SRS_AUTO_CONFIGURE "\n""\n" "Usage: %s [-h?vVgG] [[-t] -c ]\n" @@ -3447,9 +3446,6 @@ void SrsConfig::print_help(char** argv) " -t : test configuration file, exit(error_code).\n" " -c filename : use configuration file for SRS\n" "\n" - RTMP_SIG_SRS_URL "\n" - "Email: " RTMP_SIG_SRS_EMAIL "\n" - "\n" "For example:\n" " %s -v\n" " %s -t -c " SRS_CONF_DEFAULT_COFNIG_FILE "\n" diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index 8671fcc62..a41d74d01 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -550,7 +550,6 @@ srs_error_t SrsGoApiAuthors::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessa SrsJsonObject* data = SrsJsonAny::object(); obj->set("data", data); - data->set("primary", SrsJsonAny::str(RTMP_SIG_SRS_PRIMARY)); data->set("license", SrsJsonAny::str(RTMP_SIG_SRS_LICENSE)); data->set("contributors", SrsJsonAny::str(SRS_AUTO_CONSTRIBUTORS)); diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index 7115c3db9..22b267d02 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -1590,7 +1590,6 @@ srs_error_t SrsMetaCache::update_data(SrsMessageHeader* header, SrsOnMetaDataPac // add server info to metadata metadata->metadata->set("server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER)); - metadata->metadata->set("srs_primary", SrsAmf0Any::str(RTMP_SIG_SRS_PRIMARY)); // version, for example, 1.0.0 // add version to metadata, please donot remove it, for debug. diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 95cd3c018..2da67cc29 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -35,11 +35,8 @@ // The project informations, may sent to client in HTTP header or RTMP metadata. #define RTMP_SIG_SRS_KEY "SRS" #define RTMP_SIG_SRS_CODE "OuXuli" -#define RTMP_SIG_SRS_EMAIL "winlin@vip.126.com" #define RTMP_SIG_SRS_URL "https://github.com/ossrs/srs" #define RTMP_SIG_SRS_LICENSE "The MIT License (MIT)" -#define RTMP_SIG_SRS_PRIMARY RTMP_SIG_SRS_KEY "/" VERSION_STABLE_BRANCH -#define RTMP_SIG_SRS_HANDSHAKE RTMP_SIG_SRS_KEY "(" RTMP_SIG_SRS_VERSION ")" #define RTMP_SIG_SRS_VERSION SRS_XSTR(VERSION_MAJOR) "." SRS_XSTR(VERSION_MINOR) "." SRS_XSTR(VERSION_REVISION) #define RTMP_SIG_SRS_SERVER RTMP_SIG_SRS_KEY "/" RTMP_SIG_SRS_VERSION "(" RTMP_SIG_SRS_CODE ")" diff --git a/trunk/src/main/srs_main_server.cpp b/trunk/src/main/srs_main_server.cpp index 339af3357..7bbc75998 100644 --- a/trunk/src/main/srs_main_server.cpp +++ b/trunk/src/main/srs_main_server.cpp @@ -118,7 +118,7 @@ srs_error_t do_main(int argc, char** argv) } // config already applied to log. - srs_trace(RTMP_SIG_SRS_SERVER ", stable is " RTMP_SIG_SRS_PRIMARY); + srs_trace(RTMP_SIG_SRS_SERVER); srs_trace("license: " RTMP_SIG_SRS_LICENSE); srs_trace("contributors: " SRS_AUTO_CONSTRIBUTORS); srs_trace("build: %s, configure:%s, uname: %s", SRS_AUTO_BUILD_DATE, SRS_AUTO_USER_CONFIGURE, SRS_AUTO_UNAME); diff --git a/trunk/src/protocol/srs_rtmp_handshake.cpp b/trunk/src/protocol/srs_rtmp_handshake.cpp index 5fd526cf7..87b9ea67b 100644 --- a/trunk/src/protocol/srs_rtmp_handshake.cpp +++ b/trunk/src/protocol/srs_rtmp_handshake.cpp @@ -42,6 +42,9 @@ using namespace _srs_internal; // for openssl_generate_key #include +// For randomly generate the handshake bytes. +#define RTMP_SIG_SRS_HANDSHAKE RTMP_SIG_SRS_KEY "(" RTMP_SIG_SRS_VERSION ")" + #if OPENSSL_VERSION_NUMBER < 0x10100000L static HMAC_CTX *HMAC_CTX_new(void) diff --git a/trunk/src/protocol/srs_rtmp_stack.cpp b/trunk/src/protocol/srs_rtmp_stack.cpp index 5ea56cbbf..af9850a21 100644 --- a/trunk/src/protocol/srs_rtmp_stack.cpp +++ b/trunk/src/protocol/srs_rtmp_stack.cpp @@ -2387,8 +2387,6 @@ srs_error_t SrsRtmpServer::response_connect_app(SrsRequest *req, const char* ser data->set("srs_license", SrsAmf0Any::str(RTMP_SIG_SRS_LICENSE)); data->set("srs_url", SrsAmf0Any::str(RTMP_SIG_SRS_URL)); data->set("srs_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION)); - data->set("srs_email", SrsAmf0Any::str(RTMP_SIG_SRS_EMAIL)); - data->set("srs_primary", SrsAmf0Any::str(RTMP_SIG_SRS_PRIMARY)); if (server_ip) { data->set("srs_server_ip", SrsAmf0Any::str(server_ip)); diff --git a/trunk/src/service/srs_service_rtmp_conn.cpp b/trunk/src/service/srs_service_rtmp_conn.cpp index c447ea020..366af9839 100644 --- a/trunk/src/service/srs_service_rtmp_conn.cpp +++ b/trunk/src/service/srs_service_rtmp_conn.cpp @@ -120,8 +120,6 @@ srs_error_t SrsBasicRtmpClient::do_connect_app(string local_ip, bool debug) data->set("srs_license", SrsAmf0Any::str(RTMP_SIG_SRS_LICENSE)); data->set("srs_url", SrsAmf0Any::str(RTMP_SIG_SRS_URL)); data->set("srs_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION)); - data->set("srs_email", SrsAmf0Any::str(RTMP_SIG_SRS_EMAIL)); - data->set("srs_primary", SrsAmf0Any::str(RTMP_SIG_SRS_PRIMARY)); // for edge to directly get the id of client. data->set("srs_pid", SrsAmf0Any::number(getpid())); data->set("srs_id", SrsAmf0Any::number(_srs_context->get_id())); From 2de3045b2500824241ade4080cd9c026c84f2690 Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 30 Apr 2019 08:53:51 +0800 Subject: [PATCH 21/25] Remove noisy informations. --- trunk/src/app/srs_app_config.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index c70cdb80f..326ea2071 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -3433,19 +3433,16 @@ srs_error_t SrsConfig::parse_argv(int& i, char** argv) void SrsConfig::print_help(char** argv) { printf( - RTMP_SIG_SRS_SERVER RTMP_SIG_SRS_URL "\n" - "License: " RTMP_SIG_SRS_LICENSE "\n" - "Build: " SRS_AUTO_BUILD_DATE " Configuration:" SRS_AUTO_USER_CONFIGURE "\n" - "Features:" SRS_AUTO_CONFIGURE "\n""\n" + RTMP_SIG_SRS_SERVER ", " RTMP_SIG_SRS_URL ", licensed under " RTMP_SIG_SRS_LICENSE + ", built at " SRS_AUTO_BUILD_DATE ", configured by " SRS_AUTO_USER_CONFIGURE + ", which means " SRS_AUTO_CONFIGURE "\n""\n" "Usage: %s [-h?vVgG] [[-t] -c ]\n" - "\n" "Options:\n" " -?, -h : show this help and exit(0)\n" " -v, -V : show version and exit(0)\n" " -g, -G : show server signature and exit(0)\n" " -t : test configuration file, exit(error_code).\n" " -c filename : use configuration file for SRS\n" - "\n" "For example:\n" " %s -v\n" " %s -t -c " SRS_CONF_DEFAULT_COFNIG_FILE "\n" From b02527dec079e0de5531d0ca102dcf77f7a11eca Mon Sep 17 00:00:00 2001 From: winlin Date: Tue, 30 Apr 2019 09:15:06 +0800 Subject: [PATCH 22/25] Refine usage. --- trunk/src/app/srs_app_config.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 326ea2071..b3d90a66c 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -3436,13 +3436,13 @@ void SrsConfig::print_help(char** argv) RTMP_SIG_SRS_SERVER ", " RTMP_SIG_SRS_URL ", licensed under " RTMP_SIG_SRS_LICENSE ", built at " SRS_AUTO_BUILD_DATE ", configured by " SRS_AUTO_USER_CONFIGURE ", which means " SRS_AUTO_CONFIGURE "\n""\n" - "Usage: %s [-h?vVgG] [[-t] -c ]\n" + "Usage: %s <-h?vVgG>|<[-t] -c filename>\n" "Options:\n" - " -?, -h : show this help and exit(0)\n" - " -v, -V : show version and exit(0)\n" - " -g, -G : show server signature and exit(0)\n" - " -t : test configuration file, exit(error_code).\n" - " -c filename : use configuration file for SRS\n" + " -?, -h : Show this help and exit 0.\n" + " -v, -V : Show version and exit 0.\n" + " -g, -G : Show server signature and exit 0.\n" + " -t : Test configuration file, exit with error code(0 for success).\n" + " -c filename : Use config file to start server.\n" "For example:\n" " %s -v\n" " %s -t -c " SRS_CONF_DEFAULT_COFNIG_FILE "\n" From 6730f08f454e16cefba76679534e6cb0cb2d31d7 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 5 May 2019 07:44:39 +0800 Subject: [PATCH 23/25] Refine core.hpp --- trunk/src/core/srs_core.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 2da67cc29..a59348f40 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -32,6 +32,11 @@ // The macros generated by configure script. #include +// To convert macro values to string. +// @see https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification +#define SRS_INTERNAL_STR(v) #v +#define SRS_XSTR(v) SRS_INTERNAL_STR(v) + // The project informations, may sent to client in HTTP header or RTMP metadata. #define RTMP_SIG_SRS_KEY "SRS" #define RTMP_SIG_SRS_CODE "OuXuli" @@ -44,11 +49,6 @@ #define VERSION_STABLE 2 #define VERSION_STABLE_BRANCH SRS_XSTR(VERSION_STABLE)".0release" -// To convert macro values to string. -// @see https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification -#define SRS_XSTR(v) SRS_INTERNAL_STR(v) -#define SRS_INTERNAL_STR(v) #v - // For 32bit os, 2G big file limit for unistd io, // ie. read/write/lseek to use 64bits size for huge file. #ifndef _FILE_OFFSET_BITS From ad1197e7065d893fb3d10a7097c2d4d8a3acab16 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 5 May 2019 07:45:49 +0800 Subject: [PATCH 24/25] Update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2df020941..ca6b99885 100755 --- a/README.md +++ b/README.md @@ -147,9 +147,9 @@ Please select according to languages: - [x] Enhanced complex error code with description and stack, read [#913][bug #913]. - [x] Enhanced RTMP url which supports vhost in stream, read [#1059][bug #1059]. - [x] Support origin cluster, please read [#464][bug #464], [RTMP 302][bug #92]. +- [x] Support listen at IPv4 and IPv6, read [#460][bug #460]. - [ ] Utest cover almost all kernel code. - [ ] Enhanced forwarding with vhost and variables. -- [ ] Support listen at IPv4 and IPv6, read [#460][bug #460]. - [ ] Support source cleanup for idle streams. - [ ] Support H.265 by pushing H.265 over RTMP, deliverying in HLS, read [#465][bug #465]. - [ ] Support HLS+, the HLS edge server, please read [#466][bug #466] and [#468][bug #468]. From a4160308f5cda0f0ee61940ea476db648736f4f0 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 5 May 2019 07:55:55 +0800 Subject: [PATCH 25/25] Refine comments. --- trunk/auto/auto_headers.sh | 16 ++++++++++------ trunk/auto/depends.sh | 6 +++--- trunk/src/app/srs_app_utility.cpp | 8 -------- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/trunk/auto/auto_headers.sh b/trunk/auto/auto_headers.sh index bfd650e7d..dcaba18eb 100755 --- a/trunk/auto/auto_headers.sh +++ b/trunk/auto/auto_headers.sh @@ -200,12 +200,16 @@ echo "" >> $SRS_AUTO_HEADERS_H ##################################################################################### # generated the contributors from AUTHORS.txt ##################################################################################### -SRS_CONSTRIBUTORS=`cat ../AUTHORS.txt|grep "*"|awk '{print $2}'` -echo "#define SRS_AUTO_CONSTRIBUTORS \"\\" >> $SRS_AUTO_HEADERS_H -for CONTRIBUTOR in $SRS_CONSTRIBUTORS; do - echo "${CONTRIBUTOR} \\" >> $SRS_AUTO_HEADERS_H -done -echo "\"" >> $SRS_AUTO_HEADERS_H +if [[ -f ../AUTHORS.txt ]]; then + SRS_CONSTRIBUTORS=`cat ../AUTHORS.txt|grep "*"|awk '{print $2}'` + echo "#define SRS_AUTO_CONSTRIBUTORS \"\\" >> $SRS_AUTO_HEADERS_H + for CONTRIBUTOR in $SRS_CONSTRIBUTORS; do + echo "${CONTRIBUTOR} \\" >> $SRS_AUTO_HEADERS_H + done + echo "\"" >> $SRS_AUTO_HEADERS_H +else + echo "#define SRS_AUTO_CONSTRIBUTORS \"ossrs\"" >> $SRS_AUTO_HEADERS_H +fi # new empty line to auto headers file. echo "" >> $SRS_AUTO_HEADERS_H diff --git a/trunk/auto/depends.sh b/trunk/auto/depends.sh index 63e9f707d..96f395fbe 100755 --- a/trunk/auto/depends.sh +++ b/trunk/auto/depends.sh @@ -428,15 +428,15 @@ SED="sed_utility" && echo "SED is $SED" ##################################################################################### # check the os. ##################################################################################### -# user must specifies something what a fuck, we suppport following os: -# centos/ubuntu/osx, +# Only supports: +# linux, centos/ubuntu as such, # cross build for embeded system, for example, mips or arm, # directly build on arm/mips, for example, pi or cubie, # export srs-librtmp # others is invalid. if [[ $OS_IS_UBUNTU = NO && $OS_IS_CENTOS = NO && $OS_IS_OSX = NO && $SRS_EXPORT_LIBRTMP_PROJECT = NO ]]; then if [[ $SRS_PI = NO && $SRS_CUBIE = NO && $SRS_CROSS_BUILD = NO ]]; then - echo "What a fuck, your OS `uname -s` is not supported." + echo "Your OS `uname -s` is not supported." exit 1 fi fi diff --git a/trunk/src/app/srs_app_utility.cpp b/trunk/src/app/srs_app_utility.cpp index c3f5520bf..6ea2ba0f8 100644 --- a/trunk/src/app/srs_app_utility.cpp +++ b/trunk/src/app/srs_app_utility.cpp @@ -362,7 +362,6 @@ bool get_proc_system_stat(SrsProcSystemStat& r) fclose(f); #else // TODO: FIXME: impelments it. - // Fuck all of you who use osx for a long time and never patch the osx features for srs. #endif r.ok = true; @@ -401,7 +400,6 @@ bool get_proc_self_stat(SrsProcSelfStat& r) fclose(f); #else // TODO: FIXME: impelments it. - // Fuck all of you who use osx for a long time and never patch the osx features for srs. #endif r.ok = true; @@ -520,7 +518,6 @@ bool srs_get_disk_vmstat_stat(SrsDiskStat& r) fclose(f); #else // TODO: FIXME: impelments it. - // Fuck all of you who use osx for a long time and never patch the osx features for srs. #endif r.ok = true; @@ -606,7 +603,6 @@ bool srs_get_disk_diskstats_stat(SrsDiskStat& r) fclose(f); #else // TODO: FIXME: impelments it. - // Fuck all of you who use osx for a long time and never patch the osx features for srs. #endif r.ok = true; @@ -728,7 +724,6 @@ void srs_update_meminfo() fclose(f); #else // TODO: FIXME: impelments it. - // Fuck all of you who use osx for a long time and never patch the osx features for srs. #endif r.sample_time = srsu2ms(srs_get_system_time()); @@ -948,7 +943,6 @@ void srs_update_network_devices() } #else // TODO: FIXME: impelments it. - // Fuck all of you who use osx for a long time and never patch the osx features for srs. #endif } @@ -1029,7 +1023,6 @@ void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps) } #else // TODO: FIXME: impelments it. - // Fuck all of you who use osx for a long time and never patch the osx features for srs. nb_socks = 0; nb_tcp4_hashed = 0; nb_tcp_orphans = 0; @@ -1073,7 +1066,6 @@ void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps) } #else // TODO: FIXME: impelments it. - // Fuck all of you who use osx for a long time and never patch the osx features for srs. #endif // @see: https://github.com/shemminger/iproute2/blob/master/misc/ss.c