From f32aab3d929cc13e4b9ad82a8e496b588a8128f2 Mon Sep 17 00:00:00 2001 From: winlin Date: Sat, 25 Mar 2017 17:21:39 +0800 Subject: [PATCH] For #299, refine code. --- trunk/research/arm/jmp_sp.cpp | 150 +- .../gperftools/memory.error.notcmalloc.cpp | 4 +- .../gperftools/memory.error.tcmalloc.cpp | 4 +- trunk/research/librtmp/srs_aac_raw_publish.c | 17 +- .../research/librtmp/srs_audio_raw_publish.c | 18 +- trunk/research/librtmp/srs_bandwidth_check.c | 6 +- trunk/research/librtmp/srs_detect_rtmp.c | 37 +- trunk/research/librtmp/srs_flv_injecter.c | 12 +- trunk/research/librtmp/srs_flv_parser.c | 9 +- trunk/research/librtmp/srs_h264_raw_publish.c | 12 +- trunk/research/librtmp/srs_ingest_flv.c | 51 +- trunk/research/librtmp/srs_ingest_mp4.c | 14 +- trunk/research/librtmp/srs_ingest_rtmp.c | 20 +- trunk/research/librtmp/srs_publish.c | 5 +- trunk/src/app/srs_app_async_call.cpp | 60 +- trunk/src/app/srs_app_async_call.hpp | 47 +- trunk/src/app/srs_app_bandwidth.cpp | 125 +- trunk/src/app/srs_app_bandwidth.hpp | 254 +- trunk/src/app/srs_app_caster_flv.cpp | 46 +- trunk/src/app/srs_app_caster_flv.hpp | 56 +- trunk/src/app/srs_app_config.cpp | 376 +- trunk/src/app/srs_app_config.hpp | 1083 ++-- trunk/src/app/srs_app_conn.cpp | 54 +- trunk/src/app/srs_app_conn.hpp | 122 +- trunk/src/app/srs_app_dash.cpp | 74 +- trunk/src/app/srs_app_dash.hpp | 47 +- trunk/src/app/srs_app_dvr.cpp | 126 +- trunk/src/app/srs_app_dvr.hpp | 77 +- trunk/src/app/srs_app_edge.cpp | 72 +- trunk/src/app/srs_app_edge.hpp | 124 +- trunk/src/app/srs_app_empty.cpp | 44 +- trunk/src/app/srs_app_empty.hpp | 47 +- trunk/src/app/srs_app_encoder.cpp | 90 +- trunk/src/app/srs_app_encoder.hpp | 53 +- trunk/src/app/srs_app_ffmpeg.cpp | 48 +- trunk/src/app/srs_app_ffmpeg.hpp | 53 +- trunk/src/app/srs_app_forward.cpp | 66 +- trunk/src/app/srs_app_forward.hpp | 75 +- trunk/src/app/srs_app_fragment.cpp | 44 +- trunk/src/app/srs_app_fragment.hpp | 47 +- trunk/src/app/srs_app_hds.cpp | 515 +- trunk/src/app/srs_app_hds.hpp | 54 +- trunk/src/app/srs_app_heartbeat.cpp | 50 +- trunk/src/app/srs_app_heartbeat.hpp | 53 +- trunk/src/app/srs_app_hls.cpp | 140 +- trunk/src/app/srs_app_hls.hpp | 179 +- trunk/src/app/srs_app_hourglass.cpp | 42 +- trunk/src/app/srs_app_hourglass.hpp | 48 +- trunk/src/app/srs_app_http_api.cpp | 66 +- trunk/src/app/srs_app_http_api.hpp | 48 +- trunk/src/app/srs_app_http_client.cpp | 58 +- trunk/src/app/srs_app_http_client.hpp | 47 +- trunk/src/app/srs_app_http_conn.cpp | 82 +- trunk/src/app/srs_app_http_conn.hpp | 62 +- trunk/src/app/srs_app_http_hooks.cpp | 126 +- trunk/src/app/srs_app_http_hooks.hpp | 103 +- trunk/src/app/srs_app_http_static.cpp | 70 +- trunk/src/app/srs_app_http_static.hpp | 54 +- trunk/src/app/srs_app_http_stream.cpp | 165 +- trunk/src/app/srs_app_http_stream.hpp | 126 +- trunk/src/app/srs_app_ingest.cpp | 82 +- trunk/src/app/srs_app_ingest.hpp | 59 +- trunk/src/app/srs_app_kafka.cpp | 44 +- trunk/src/app/srs_app_kafka.hpp | 45 +- trunk/src/app/srs_app_listener.cpp | 70 +- trunk/src/app/srs_app_listener.hpp | 84 +- trunk/src/app/srs_app_log.cpp | 109 +- trunk/src/app/srs_app_log.hpp | 64 +- trunk/src/app/srs_app_mpegts_udp.cpp | 188 +- trunk/src/app/srs_app_mpegts_udp.hpp | 62 +- trunk/src/app/srs_app_ng_exec.cpp | 42 +- trunk/src/app/srs_app_ng_exec.hpp | 45 +- trunk/src/app/srs_app_pithy_print.cpp | 54 +- trunk/src/app/srs_app_pithy_print.hpp | 92 +- trunk/src/app/srs_app_process.cpp | 44 +- trunk/src/app/srs_app_process.hpp | 45 +- trunk/src/app/srs_app_recv_thread.cpp | 113 +- trunk/src/app/srs_app_recv_thread.hpp | 74 +- trunk/src/app/srs_app_refer.cpp | 48 +- trunk/src/app/srs_app_refer.hpp | 55 +- trunk/src/app/srs_app_reload.cpp | 44 +- trunk/src/app/srs_app_reload.hpp | 59 +- trunk/src/app/srs_app_rtmp_conn.cpp | 250 +- trunk/src/app/srs_app_rtmp_conn.hpp | 48 +- trunk/src/app/srs_app_rtsp.cpp | 232 +- trunk/src/app/srs_app_rtsp.hpp | 84 +- trunk/src/app/srs_app_security.cpp | 48 +- trunk/src/app/srs_app_security.hpp | 76 +- trunk/src/app/srs_app_server.cpp | 174 +- trunk/src/app/srs_app_server.hpp | 178 +- trunk/src/app/srs_app_source.cpp | 174 +- trunk/src/app/srs_app_source.hpp | 335 +- trunk/src/app/srs_app_st.cpp | 50 +- trunk/src/app/srs_app_st.hpp | 48 +- trunk/src/app/srs_app_statistic.cpp | 76 +- trunk/src/app/srs_app_statistic.hpp | 122 +- trunk/src/app/srs_app_thread.cpp | 44 +- trunk/src/app/srs_app_thread.hpp | 47 +- trunk/src/app/srs_app_utility.cpp | 212 +- trunk/src/app/srs_app_utility.hpp | 224 +- trunk/src/core/srs_core.cpp | 44 +- trunk/src/core/srs_core.hpp | 56 +- trunk/src/core/srs_core_autofree.cpp | 44 +- trunk/src/core/srs_core_autofree.hpp | 48 +- trunk/src/core/srs_core_mem_watch.cpp | 44 +- trunk/src/core/srs_core_mem_watch.hpp | 48 +- trunk/src/core/srs_core_performance.cpp | 44 +- trunk/src/core/srs_core_performance.hpp | 240 +- trunk/src/kernel/srs_kernel_aac.cpp | 48 +- trunk/src/kernel/srs_kernel_aac.hpp | 61 +- trunk/src/kernel/srs_kernel_balance.cpp | 42 +- trunk/src/kernel/srs_kernel_balance.hpp | 45 +- trunk/src/kernel/srs_kernel_buffer.cpp | 48 +- trunk/src/kernel/srs_kernel_buffer.hpp | 162 +- trunk/src/kernel/srs_kernel_codec.cpp | 48 +- trunk/src/kernel/srs_kernel_codec.hpp | 84 +- trunk/src/kernel/srs_kernel_consts.cpp | 44 +- trunk/src/kernel/srs_kernel_consts.hpp | 128 +- trunk/src/kernel/srs_kernel_error.cpp | 44 +- trunk/src/kernel/srs_kernel_error.hpp | 80 +- trunk/src/kernel/srs_kernel_file.cpp | 50 +- trunk/src/kernel/srs_kernel_file.hpp | 55 +- trunk/src/kernel/srs_kernel_flv.cpp | 83 +- trunk/src/kernel/srs_kernel_flv.hpp | 173 +- trunk/src/kernel/srs_kernel_io.cpp | 44 +- trunk/src/kernel/srs_kernel_io.hpp | 50 +- trunk/src/kernel/srs_kernel_log.cpp | 46 +- trunk/src/kernel/srs_kernel_log.hpp | 92 +- trunk/src/kernel/srs_kernel_mp3.cpp | 48 +- trunk/src/kernel/srs_kernel_mp3.hpp | 67 +- trunk/src/kernel/srs_kernel_mp4.cpp | 70 +- trunk/src/kernel/srs_kernel_mp4.hpp | 100 +- trunk/src/kernel/srs_kernel_stream.cpp | 46 +- trunk/src/kernel/srs_kernel_stream.hpp | 84 +- trunk/src/kernel/srs_kernel_ts.cpp | 789 ++- trunk/src/kernel/srs_kernel_ts.hpp | 1466 +++-- trunk/src/kernel/srs_kernel_utility.cpp | 1307 +++-- trunk/src/kernel/srs_kernel_utility.hpp | 127 +- trunk/src/libs/srs_lib_bandwidth.cpp | 84 +- trunk/src/libs/srs_lib_bandwidth.hpp | 97 +- trunk/src/libs/srs_lib_simple_socket.cpp | 546 +- trunk/src/libs/srs_lib_simple_socket.hpp | 64 +- trunk/src/libs/srs_librtmp.cpp | 5142 ++++++++--------- trunk/src/libs/srs_librtmp.hpp | 2211 ++++--- trunk/src/main/srs_main_ingest_hls.cpp | 76 +- trunk/src/main/srs_main_mp4_parser.cpp | 45 +- trunk/src/main/srs_main_server.cpp | 60 +- trunk/src/protocol/srs_http_stack.cpp | 92 +- trunk/src/protocol/srs_http_stack.hpp | 189 +- trunk/src/protocol/srs_kafka_stack.cpp | 44 +- trunk/src/protocol/srs_kafka_stack.hpp | 121 +- trunk/src/protocol/srs_protocol_amf0.cpp | 136 +- trunk/src/protocol/srs_protocol_amf0.hpp | 840 ++- trunk/src/protocol/srs_protocol_format.cpp | 42 +- trunk/src/protocol/srs_protocol_format.hpp | 46 +- trunk/src/protocol/srs_protocol_io.cpp | 44 +- trunk/src/protocol/srs_protocol_io.hpp | 146 +- trunk/src/protocol/srs_protocol_json.cpp | 836 +-- trunk/src/protocol/srs_protocol_json.hpp | 97 +- trunk/src/protocol/srs_protocol_kbps.cpp | 48 +- trunk/src/protocol/srs_protocol_kbps.hpp | 136 +- trunk/src/protocol/srs_protocol_stream.cpp | 78 +- trunk/src/protocol/srs_protocol_stream.hpp | 164 +- trunk/src/protocol/srs_protocol_utility.cpp | 68 +- trunk/src/protocol/srs_protocol_utility.hpp | 142 +- trunk/src/protocol/srs_raw_avc.cpp | 148 +- trunk/src/protocol/srs_raw_avc.hpp | 148 +- trunk/src/protocol/srs_rtmp_handshake.cpp | 158 +- trunk/src/protocol/srs_rtmp_handshake.hpp | 530 +- trunk/src/protocol/srs_rtmp_msg_array.cpp | 44 +- trunk/src/protocol/srs_rtmp_msg_array.hpp | 88 +- trunk/src/protocol/srs_rtmp_stack.cpp | 696 +-- trunk/src/protocol/srs_rtmp_stack.hpp | 1190 ++-- trunk/src/protocol/srs_rtsp_stack.cpp | 374 +- trunk/src/protocol/srs_rtsp_stack.hpp | 694 ++- 175 files changed, 15529 insertions(+), 15935 deletions(-) diff --git a/trunk/research/arm/jmp_sp.cpp b/trunk/research/arm/jmp_sp.cpp index 9b1c71511..ddb3f56f2 100644 --- a/trunk/research/arm/jmp_sp.cpp +++ b/trunk/research/arm/jmp_sp.cpp @@ -1,10 +1,10 @@ /* -# see: https://github.com/ossrs/srs/issues/190 -# see: https://github.com/ossrs/srs/wiki/v1_CN_SrsLinuxArm - g++ -g -O0 -o jmp_sp jmp_sp.cpp - arm-linux-gnueabi-g++ -g -o jmp_sp jmp_sp.cpp -static - arm-linux-gnueabi-strip jmp_sp -*/ + # see: https://github.com/ossrs/srs/issues/190 + # see: https://github.com/ossrs/srs/wiki/v1_CN_SrsLinuxArm + g++ -g -O0 -o jmp_sp jmp_sp.cpp + arm-linux-gnueabi-g++ -g -o jmp_sp jmp_sp.cpp -static + arm-linux-gnueabi-strip jmp_sp + */ #include #include #include @@ -14,14 +14,14 @@ jmp_buf context; void do_longjmp() { /** - the definition of jmp_buf: - typedef struct __jmp_buf_tag jmp_buf[1]; - struct __jmp_buf_tag { - __jmp_buf __jmpbuf; - int __mask_was_saved; - __sigset_t __saved_mask; - }; - */ + the definition of jmp_buf: + typedef struct __jmp_buf_tag jmp_buf[1]; + struct __jmp_buf_tag { + __jmp_buf __jmpbuf; + int __mask_was_saved; + __sigset_t __saved_mask; + }; + */ #if defined(__amd64__) || defined(__x86_64__) // http://ftp.gnu.org/gnu/glibc/glibc-2.12.2.tar.xz // http://ftp.gnu.org/gnu/glibc/glibc-2.12.1.tar.gz @@ -38,21 +38,21 @@ void do_longjmp() */ // for glibc 2.4+, it's not possible to get and set the sp in jmp_buf /** - for example, the following is show the jmp_buf when setjmp: - (gdb) x /64xb context[0].__jmpbuf - 0x600ca0 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - 0x600ca8 : 0xf8 0xc1 0x71 0xe5 0xa8 0x88 0xb4 0x15 - 0x600cb0 : 0xa0 0x05 0x40 0x00 0x00 0x00 0x00 0x00 - 0x600cb8 : 0x90 0xe4 0xff 0xff 0xff 0x7f 0x00 0x00 - 0x600cc0 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - 0x600cc8 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - 0x600cd0 : 0xf8 0xc1 0x51 0xe5 0xa8 0x88 0xb4 0x15 - 0x600cd8 : 0xf8 0xc1 0xd9 0x2f 0xd7 0x77 0x4b 0xea - (gdb) p /x $sp - $4 = 0x7fffffffe380 - we cannot finger the sp out. - where the glibc is 2.12. - */ + for example, the following is show the jmp_buf when setjmp: + (gdb) x /64xb context[0].__jmpbuf + 0x600ca0 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x600ca8 : 0xf8 0xc1 0x71 0xe5 0xa8 0x88 0xb4 0x15 + 0x600cb0 : 0xa0 0x05 0x40 0x00 0x00 0x00 0x00 0x00 + 0x600cb8 : 0x90 0xe4 0xff 0xff 0xff 0x7f 0x00 0x00 + 0x600cc0 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x600cc8 : 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0x600cd0 : 0xf8 0xc1 0x51 0xe5 0xa8 0x88 0xb4 0x15 + 0x600cd8 : 0xf8 0xc1 0xd9 0x2f 0xd7 0x77 0x4b 0xea + (gdb) p /x $sp + $4 = 0x7fffffffe380 + we cannot finger the sp out. + where the glibc is 2.12. + */ register long int rsp0 asm("rsp"); int ret = setjmp(context); @@ -64,46 +64,46 @@ void do_longjmp() } printf("\n"); #endif - + #if defined(__arm__) /** - /usr/arm-linux-gnueabi/include/bits/setjmp.h - #ifndef _ASM - The exact set of registers saved may depend on the particular core - in use, as some coprocessor registers may need to be saved. The C - Library ABI requires that the buffer be 8-byte aligned, and - recommends that the buffer contain 64 words. The first 28 words - are occupied by v1-v6, sl, fp, sp, pc, d8-d15, and fpscr. (Note - that d8-15 require 17 words, due to the use of fstmx.) - typedef int __jmp_buf[64] __attribute__((__aligned__ (8))); - - the layout of setjmp for arm: - 0-5: v1-v6 - 6: sl - 7: fp - 8: sp - 9: pc - 10-26: d8-d15 17words - 27: fpscr - */ + /usr/arm-linux-gnueabi/include/bits/setjmp.h + #ifndef _ASM + The exact set of registers saved may depend on the particular core + in use, as some coprocessor registers may need to be saved. The C + Library ABI requires that the buffer be 8-byte aligned, and + recommends that the buffer contain 64 words. The first 28 words + are occupied by v1-v6, sl, fp, sp, pc, d8-d15, and fpscr. (Note + that d8-15 require 17 words, due to the use of fstmx.) + typedef int __jmp_buf[64] __attribute__((__aligned__ (8))); + + the layout of setjmp for arm: + 0-5: v1-v6 + 6: sl + 7: fp + 8: sp + 9: pc + 10-26: d8-d15 17words + 27: fpscr + */ /** - For example, on raspberry-pi, armv6 cpu: - (gdb) x /64xb (char*)context[0].__jmpbuf - v1, 0: 0x00 0x00 0x00 0x00 - v2, 1: 0x00 0x00 0x00 0x00 - v3, 2: 0x2c 0x84 0x00 0x00 - v4, 3: 0x00 0x00 0x00 0x00 - v5, 4: 0x00 0x00 0x00 0x00 - v6, 5: 0x00 0x00 0x00 0x00 - sl, 6: 0x00 0xf0 0xff 0xb6 - fp, 7: 0x9c 0xfb 0xff 0xbe - sp, 8: 0x88 0xfb 0xff 0xbe - pc, 9: 0x08 0x85 0x00 0x00 - (gdb) p /x $sp - $5 = 0xbefffb88 - (gdb) p /x $pc - $4 = 0x850c - */ + For example, on raspberry-pi, armv6 cpu: + (gdb) x /64xb (char*)context[0].__jmpbuf + v1, 0: 0x00 0x00 0x00 0x00 + v2, 1: 0x00 0x00 0x00 0x00 + v3, 2: 0x2c 0x84 0x00 0x00 + v4, 3: 0x00 0x00 0x00 0x00 + v5, 4: 0x00 0x00 0x00 0x00 + v6, 5: 0x00 0x00 0x00 0x00 + sl, 6: 0x00 0xf0 0xff 0xb6 + fp, 7: 0x9c 0xfb 0xff 0xbe + sp, 8: 0x88 0xfb 0xff 0xbe + pc, 9: 0x08 0x85 0x00 0x00 + (gdb) p /x $sp + $5 = 0xbefffb88 + (gdb) p /x $pc + $4 = 0x850c + */ int ret = setjmp(context); printf("setjmp func1 ret=%d\n", ret); @@ -116,23 +116,23 @@ void do_longjmp() #endif } -int main(int argc, char** argv) +int main(int argc, char** argv) { #if defined(__amd64__) || defined(__x86_64__) printf("x86_64 sizeof(long int)=%d, sizeof(long)=%d, " - "sizeof(int)=%d, __WORDSIZE=%d, __GLIBC__=%d, __GLIBC_MINOR__=%d\n", - (int)sizeof(long int), (int)sizeof(long), (int)sizeof(int), - (int)__WORDSIZE, (int)__GLIBC__, (int)__GLIBC_MINOR__); + "sizeof(int)=%d, __WORDSIZE=%d, __GLIBC__=%d, __GLIBC_MINOR__=%d\n", + (int)sizeof(long int), (int)sizeof(long), (int)sizeof(int), + (int)__WORDSIZE, (int)__GLIBC__, (int)__GLIBC_MINOR__); #else printf("arm sizeof(long int)=%d, sizeof(long)=%d, " - "sizeof(int)=%d, __GLIBC__=%d,__GLIBC_MINOR__=%d\n", - (int)sizeof(long int), (int)sizeof(long), (int)sizeof(int), - (int)__GLIBC__, (int)__GLIBC_MINOR__); + "sizeof(int)=%d, __GLIBC__=%d,__GLIBC_MINOR__=%d\n", + (int)sizeof(long int), (int)sizeof(long), (int)sizeof(int), + (int)__GLIBC__, (int)__GLIBC_MINOR__); #endif - + do_longjmp(); printf("terminated\n"); - + return 0; } diff --git a/trunk/research/gperftools/memory.error.notcmalloc.cpp b/trunk/research/gperftools/memory.error.notcmalloc.cpp index 32638bb05..49942c9a9 100644 --- a/trunk/research/gperftools/memory.error.notcmalloc.cpp +++ b/trunk/research/gperftools/memory.error.notcmalloc.cpp @@ -1,6 +1,6 @@ /** -g++ memory.error.notcmalloc.cpp -g -O0 -o memory.error.notcmalloc -*/ + g++ memory.error.notcmalloc.cpp -g -O0 -o memory.error.notcmalloc + */ #include #include #include diff --git a/trunk/research/gperftools/memory.error.tcmalloc.cpp b/trunk/research/gperftools/memory.error.tcmalloc.cpp index 32638bb05..49942c9a9 100644 --- a/trunk/research/gperftools/memory.error.tcmalloc.cpp +++ b/trunk/research/gperftools/memory.error.tcmalloc.cpp @@ -1,6 +1,6 @@ /** -g++ memory.error.notcmalloc.cpp -g -O0 -o memory.error.notcmalloc -*/ + g++ memory.error.notcmalloc.cpp -g -O0 -o memory.error.notcmalloc + */ #include #include #include diff --git a/trunk/research/librtmp/srs_aac_raw_publish.c b/trunk/research/librtmp/srs_aac_raw_publish.c index 4fe2d5842..bb58aad2c 100644 --- a/trunk/research/librtmp/srs_aac_raw_publish.c +++ b/trunk/research/librtmp/srs_aac_raw_publish.c @@ -29,11 +29,11 @@ #include #include #include - + #include "../../objs/include/srs_librtmp.h" // https://github.com/ossrs/srs/issues/212#issuecomment-64145910 -int read_audio_frame(char* data, int size, char** pp, char** frame, int* frame_size) +int read_audio_frame(char* data, int size, char** pp, char** frame, int* frame_size) { char* p = *pp; @@ -46,10 +46,10 @@ int read_audio_frame(char* data, int size, char** pp, char** frame, int* frame_s } // @see srs_audio_write_raw_frame - // each frame prefixed aac adts header, '1111 1111 1111'B, that is 0xFFF., + // each frame prefixed aac adts header, '1111 1111 1111'B, that is 0xFFF., // for instance, frame = FF F1 5C 80 13 A0 FC 00 D0 33 83 E8 5B *frame = p; - // skip some data. + // skip some data. // @remark, user donot need to do this. p += srs_aac_adts_frame_size(p, size - (p - data)); @@ -107,7 +107,7 @@ int main(int argc, char** argv) lseek(raw_fd, 0, SEEK_SET); ssize_t nb_read = 0; if ((nb_read = read(raw_fd, audio_raw, file_size)) != file_size) { - srs_human_trace("buffer %s failed, expect=%dKB, actual=%dKB.", + srs_human_trace("buffer %s failed, expect=%dKB, actual=%dKB.", raw_file, (int)(file_size / 1024), (int)(nb_read / 1024)); goto rtmp_destroy; } @@ -164,15 +164,12 @@ int main(int argc, char** argv) timestamp += time_delta; int ret = 0; - if ((ret = srs_audio_write_raw_frame(rtmp, - sound_format, sound_rate, sound_size, sound_type, - data, size, timestamp)) != 0 - ) { + if ((ret = srs_audio_write_raw_frame(rtmp, sound_format, sound_rate, sound_size, sound_type, data, size, timestamp)) != 0) { srs_human_trace("send audio raw data failed. ret=%d", ret); goto rtmp_destroy; } - srs_human_trace("sent packet: type=%s, time=%d, size=%d, codec=%d, rate=%d, sample=%d, channel=%d", + srs_human_trace("sent packet: type=%s, time=%d, size=%d, codec=%d, rate=%d, sample=%d, channel=%d", srs_human_flv_tag_type2string(SRS_RTMP_TYPE_AUDIO), timestamp, size, sound_format, sound_rate, sound_size, sound_type); diff --git a/trunk/research/librtmp/srs_audio_raw_publish.c b/trunk/research/librtmp/srs_audio_raw_publish.c index a87c87df4..c45c03a6c 100644 --- a/trunk/research/librtmp/srs_audio_raw_publish.c +++ b/trunk/research/librtmp/srs_audio_raw_publish.c @@ -29,22 +29,21 @@ #include #include #include - + #include "../../objs/include/srs_librtmp.h" // https://github.com/ossrs/srs/issues/212#issuecomment-63648892 // allspace: // Take this file as an example: https://github.com/allspace/files/blob/master/srs.pcm // It's captured using SDK callback method. I have filtered out h264 video, so it's audio only now. -// For every frame, it's a 8 bytes vendor specific header, following 160 bytes audio frame. +// For every frame, it's a 8 bytes vendor specific header, following 160 bytes audio frame. // The header part can be ignored. -int read_audio_frame(char* audio_raw, int file_size, char** pp, char** pdata, int* psize) +int read_audio_frame(char* audio_raw, int file_size, char** pp, char** pdata, int* psize) { char* p = *pp; if (file_size - (p - audio_raw) < 168) { - srs_human_trace("audio must be 160+8 bytes. left %d bytes.", - (int)(file_size - (p - audio_raw))); + srs_human_trace("audio must be 160+8 bytes. left %d bytes.", (int)(file_size - (p - audio_raw))); return - 1; } @@ -105,7 +104,7 @@ int main(int argc, char** argv) lseek(raw_fd, 0, SEEK_SET); ssize_t nb_read = 0; if ((nb_read = read(raw_fd, audio_raw, file_size)) != file_size) { - srs_human_trace("buffer %s failed, expect=%dKB, actual=%dKB.", + srs_human_trace("buffer %s failed, expect=%dKB, actual=%dKB.", raw_file, (int)(file_size / 1024), (int)(nb_read / 1024)); goto rtmp_destroy; } @@ -161,15 +160,12 @@ int main(int argc, char** argv) timestamp += time_delta; - if (srs_audio_write_raw_frame(rtmp, - sound_format, sound_rate, sound_size, sound_type, - data, size, timestamp) != 0 - ) { + if (srs_audio_write_raw_frame(rtmp, sound_format, sound_rate, sound_size, sound_type, data, size, timestamp) != 0) { srs_human_trace("send audio raw data failed."); goto rtmp_destroy; } - srs_human_trace("sent packet: type=%s, time=%d, size=%d, codec=%d, rate=%d, sample=%d, channel=%d", + srs_human_trace("sent packet: type=%s, time=%d, size=%d, codec=%d, rate=%d, sample=%d, channel=%d", srs_human_flv_tag_type2string(SRS_RTMP_TYPE_AUDIO), timestamp, size, sound_format, sound_rate, sound_size, sound_type); diff --git a/trunk/research/librtmp/srs_bandwidth_check.c b/trunk/research/librtmp/srs_bandwidth_check.c index 016fea7c0..10adadbbf 100644 --- a/trunk/research/librtmp/srs_bandwidth_check.c +++ b/trunk/research/librtmp/srs_bandwidth_check.c @@ -71,8 +71,8 @@ int do_check(srs_rtmp_t rtmp) } if ((ret = srs_rtmp_bandwidth_check(rtmp, - &start_time, &end_time, &play_kbps, &publish_kbps, - &play_bytes, &publish_bytes, &play_duration, &publish_duration)) != 0 + &start_time, &end_time, &play_kbps, &publish_kbps, &play_bytes, &publish_bytes, + &play_duration, &publish_duration)) != 0 ) { srs_human_trace("bandwidth check/test failed."); return ret; @@ -120,7 +120,7 @@ int main(int argc, char** argv) (char*)sig, NULL, NULL, (char*)ip, major, minor, revision, build, pid, cid, (int)(end_time - start_time), play_duration, publish_duration, - play_kbps, + play_kbps, publish_kbps); rtmp_destroy: diff --git a/trunk/research/librtmp/srs_detect_rtmp.c b/trunk/research/librtmp/srs_detect_rtmp.c index 6bcc64a0a..6212dc7ac 100644 --- a/trunk/research/librtmp/srs_detect_rtmp.c +++ b/trunk/research/librtmp/srs_detect_rtmp.c @@ -56,32 +56,32 @@ int main(int argc, char** argv) int duration = 0; int timeout = 0; enum srs_url_schema sus; - + printf("detect rtmp stream\n"); printf("srs(ossrs) client librtmp library.\n"); printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); if (argc <= 3) { printf("detect stream on RTMP server, print result to stderr.\n" - "Usage: %s [url_schema]\n" - " rtmp_url RTMP stream url to play\n" - " duration how long to play, in seconds, stream time.\n" - " timeout how long to timeout, in seconds, system time.\n" - " url_schema the schema of url, default to vis, can be:\n" - " normal: rtmp://vhost:port/app/stream\n" - " via : rtmp://ip:port/vhost/app/stream\n" - " vis : rtmp://ip:port/app/stream?vhost=xxx\n" - " vis2 : rtmp://ip:port/app/stream?domain=xxx\n" - "For example:\n" - " %s rtmp://127.0.0.1:1935/bravo.chnvideo.com/live/livestream 3 10\n", - argv[0], argv[0]); + "Usage: %s [url_schema]\n" + " rtmp_url RTMP stream url to play\n" + " duration how long to play, in seconds, stream time.\n" + " timeout how long to timeout, in seconds, system time.\n" + " url_schema the schema of url, default to vis, can be:\n" + " normal: rtmp://vhost:port/app/stream\n" + " via : rtmp://ip:port/vhost/app/stream\n" + " vis : rtmp://ip:port/app/stream?vhost=xxx\n" + " vis2 : rtmp://ip:port/app/stream?domain=xxx\n" + "For example:\n" + " %s rtmp://127.0.0.1:1935/bravo.chnvideo.com/live/livestream 3 10\n", + argv[0], argv[0]); exit(-1); } rtmp_url = argv[1]; duration = atoi(argv[2]); timeout = atoi(argv[3]); - + if (1) { char *p = "vis"; if (argc > 4) { @@ -102,7 +102,7 @@ int main(int argc, char** argv) } srs_human_trace("url schema: %s", p); } - + srs_human_trace("rtmp url: %s", rtmp_url); srs_human_trace("duration: %ds, timeout:%ds", duration, timeout); @@ -145,7 +145,7 @@ int main(int argc, char** argv) srs_human_trace("set url schema=%d failed, ret=%d", sus, ret); goto rtmp_destroy; } - + if ((ret = srs_rtmp_connect_app(rtmp)) != 0) { srs_human_trace("connect vhost/app failed. ret=%d", ret); goto rtmp_destroy; @@ -164,8 +164,7 @@ int main(int argc, char** argv) srs_human_trace("read packet failed. ret=%d", ret); goto rtmp_destroy; } - srs_human_trace("got packet: type=%s, time=%d, size=%d", - srs_human_flv_tag_type2string(type), timestamp, size); + srs_human_trace("got packet: type=%s, time=%d, size=%d", srs_human_flv_tag_type2string(type), timestamp, size); if (SRS_RTMP_TYPE_VIDEO == type || SRS_RTMP_TYPE_AUDIO == type) { if (time_first_packet <= 0) { @@ -231,7 +230,7 @@ rtmp_destroy: "\"remark0\": \"total = dns + tcp_connect + start_play + first_packet + last_packet\"", "\"remark1\": \"delay = stream - (time_cleanup - time_first_packet)\"", "\"remark2\": \"if code is not 0, user must ignore all data\"" - ); + ); srs_human_trace(" "); srs_human_trace("completed"); diff --git a/trunk/research/librtmp/srs_flv_injecter.c b/trunk/research/librtmp/srs_flv_injecter.c index 69a158437..f484bb057 100644 --- a/trunk/research/librtmp/srs_flv_injecter.c +++ b/trunk/research/librtmp/srs_flv_injecter.c @@ -52,7 +52,7 @@ int main(int argc, char** argv) // temp variables. int tmp_file_size = 0; char* tmp_file; - + printf("inject flv file keyframes to metadata.\n"); printf("srs(ossrs) client librtmp library.\n"); printf("version: %d.%d.%d\n", srs_version_major(), srs_version_minor(), srs_version_revision()); @@ -79,7 +79,7 @@ int main(int argc, char** argv) srs_human_trace("input: %s", in_flv_file); srs_human_trace("output: %s", out_flv_file); srs_human_trace("tmp_file: %s", tmp_file); - + ret = process(in_flv_file, tmp_file, &ic, &oc); srs_flv_close(ic); @@ -136,9 +136,9 @@ int process(const char* in_flv_file, const char* out_flv_file, srs_flv_t* pic, s *poc = oc; /** - * we use two roundtrip to avoid the paddings of metadata, - * to support large keyframes videos without padding fields. - */ + * we use two roundtrip to avoid the paddings of metadata, + * to support large keyframes videos without padding fields. + */ // build keyframes offset to metadata. if ((ret = build_keyframes(ic, &amf0_name, &amf0_data, &filepositions, &metadata_end_offset)) != 0) { return ret; @@ -319,7 +319,7 @@ int do_inject_flv(srs_flv_t ic, srs_flv_t oc, srs_amf0_t amf0_name, srs_amf0_t a if (amf0_name != NULL && amf0_data != NULL) { amf0_name_size = srs_amf0_size(amf0_name); size = amf0_name_size + srs_amf0_size(amf0_data); - + // adjust all offset of keyframes. new_metadata_end_offset = srs_flv_tellg(oc) + srs_flv_size_tag(size); // the adjust is new offset sub the old offset of metadata end. diff --git a/trunk/research/librtmp/srs_flv_parser.c b/trunk/research/librtmp/srs_flv_parser.c index c46000f65..aede604d2 100644 --- a/trunk/research/librtmp/srs_flv_parser.c +++ b/trunk/research/librtmp/srs_flv_parser.c @@ -59,7 +59,7 @@ int main(int argc, char** argv) in_flv_file = argv[1]; srs_human_trace("input: %s", in_flv_file); - + if ((flv = srs_flv_open_read(in_flv_file)) == NULL) { ret = 2; srs_human_trace("open flv file failed. ret=%d", ret); @@ -111,7 +111,7 @@ int parse_bytes(char* data, int size, char* hbuf, int hsize, char* tbuf, int tsi { memset(hbuf, 0, hsize); memset(tbuf, 0, tsize); - + if (size > 0) { digit_to_char(data, size, hbuf, hsize - 1); } @@ -119,7 +119,7 @@ int parse_bytes(char* data, int size, char* hbuf, int hsize, char* tbuf, int tsi if (size > print_size * 2) { digit_to_char(data + size - print_size, size, tbuf, tsize - 1); } - + return 0; } @@ -168,8 +168,7 @@ int parse_flv(srs_flv_t flv) char hbuf[48]; char tbuf[48]; parse_bytes(data, size, hbuf, sizeof(hbuf), tbuf, sizeof(tbuf), 16); - srs_human_raw("offset=%d, first and last 16 bytes:\n" - "[+00, +15] %s\n[-15, EOF] %s\n", (int)offset, hbuf, tbuf); + srs_human_raw("offset=%d, first and last 16 bytes:\n[+00, +15] %s\n[-15, EOF] %s\n", (int)offset, hbuf, tbuf); } else { srs_human_trace("print packet failed. ret=%d", ret); } diff --git a/trunk/research/librtmp/srs_h264_raw_publish.c b/trunk/research/librtmp/srs_h264_raw_publish.c index de43cafba..f9dc10924 100644 --- a/trunk/research/librtmp/srs_h264_raw_publish.c +++ b/trunk/research/librtmp/srs_h264_raw_publish.c @@ -29,11 +29,11 @@ #include #include #include - + #include "../../objs/include/srs_librtmp.h" int read_h264_frame(char* data, int size, char** pp, int* pnb_start_code, int fps, - char** frame, int* frame_size, int* dts, int* pts) + char** frame, int* frame_size, int* dts, int* pts) { char* p = *pp; @@ -46,7 +46,7 @@ int read_h264_frame(char* data, int size, char** pp, int* pnb_start_code, int fp } // @see srs_write_h264_raw_frames - // each frame prefixed h.264 annexb header, by N[00] 00 00 01, where N>=0, + // each frame prefixed h.264 annexb header, by N[00] 00 00 01, where N>=0, // for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40) *frame = p; p += *pnb_start_code; @@ -69,7 +69,7 @@ int read_h264_frame(char* data, int size, char** pp, int* pnb_start_code, int fp // while the dts and pts must read from encode lib or device. *dts += 1000 / fps; *pts = *dts; - + return 0; } @@ -121,8 +121,8 @@ int main(int argc, char** argv) lseek(raw_fd, 0, SEEK_SET); ssize_t nb_read = 0; if ((nb_read = read(raw_fd, h264_raw, file_size)) != file_size) { - srs_human_trace("buffer %s failed, expect=%dKB, actual=%dKB.", - raw_file, (int)(file_size / 1024), (int)(nb_read / 1024)); + srs_human_trace("buffer %s failed, expect=%dKB, actual=%dKB.", + raw_file, (int)(file_size / 1024), (int)(nb_read / 1024)); goto rtmp_destroy; } diff --git a/trunk/research/librtmp/srs_ingest_flv.c b/trunk/research/librtmp/srs_ingest_flv.c index f48b495e5..d7299cfaf 100644 --- a/trunk/research/librtmp/srs_ingest_flv.c +++ b/trunk/research/librtmp/srs_ingest_flv.c @@ -1,25 +1,25 @@ /* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + + Copyright (c) 2013-2017 SRS(ossrs) + + 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. + */ #include #include @@ -107,7 +107,7 @@ int main(int argc, char** argv) srs_human_trace("input: %s", in_flv_file); srs_human_trace("output: %s", out_rtmp_url); - + if ((flv = srs_flv_open_read(in_flv_file)) == NULL) { ret = 2; srs_human_trace("open flv file failed. ret=%d", ret); @@ -115,7 +115,7 @@ int main(int argc, char** argv) } ortmp = srs_rtmp_create(out_rtmp_url); - + ret = proxy(flv, ortmp); srs_human_trace("ingest flv to RTMP completed"); @@ -170,7 +170,7 @@ int do_proxy(srs_flv_t flv, srs_rtmp_t ortmp, int64_t re, int32_t* pstarttime, u srs_human_trace("irtmp get packet failed. ret=%d", ret); return ret; } - + if (*pstarttime < 0 && srs_utils_flv_tag_is_av(type)) { *pstarttime = *ptimestamp; } @@ -267,8 +267,7 @@ void re_cleanup(int64_t re, int32_t starttime, uint32_t time) int64_t now = srs_utils_time_ms(); int64_t diff = time - starttime - (now -re); if (diff > 0) { - srs_human_trace("re_cleanup, diff=%d, start=%d, last=%d ms", - (int)diff, starttime, time); + srs_human_trace("re_cleanup, diff=%d, start=%d, last=%d ms", (int)diff, starttime, time); usleep((useconds_t)(diff * 1000)); } } diff --git a/trunk/research/librtmp/srs_ingest_mp4.c b/trunk/research/librtmp/srs_ingest_mp4.c index e8d3e74c3..929bb830c 100644 --- a/trunk/research/librtmp/srs_ingest_mp4.c +++ b/trunk/research/librtmp/srs_ingest_mp4.c @@ -39,13 +39,13 @@ int main(int argc, char** argv) if (argc <= 2) { printf("Ingest mp4 file and publish to RTMP server\n" - "Usage: %s <-i in_mp4_file> <-y out_rtmp_url>\n" - " in_mp4_file input mp4 file, ingest from this file.\n" - " out_rtmp_url output rtmp url, publish to this url.\n" - "@remark Only support non-seek mp4, see https://github.com/ossrs/srs/issues/738#issuecomment-276343669\n" - "For example:\n" - " %s -i avatar.mp4 -y rtmp://127.0.0.1/live/livestream\n", - argv[0], argv[0]); + "Usage: %s <-i in_mp4_file> <-y out_rtmp_url>\n" + " in_mp4_file input mp4 file, ingest from this file.\n" + " out_rtmp_url output rtmp url, publish to this url.\n" + "@remark Only support non-seek mp4, see https://github.com/ossrs/srs/issues/738#issuecomment-276343669\n" + "For example:\n" + " %s -i avatar.mp4 -y rtmp://127.0.0.1/live/livestream\n", + argv[0], argv[0]); exit(-1); } diff --git a/trunk/research/librtmp/srs_ingest_rtmp.c b/trunk/research/librtmp/srs_ingest_rtmp.c index 6af36f5e5..d9d066524 100644 --- a/trunk/research/librtmp/srs_ingest_rtmp.c +++ b/trunk/research/librtmp/srs_ingest_rtmp.c @@ -49,7 +49,7 @@ int main(int argc, char** argv) srs_rtmp_t irtmp, ortmp; printf("Ingest RTMP to server like FFMPEG over srs-librtmp %d.%d.%d\n", - srs_version_major(), srs_version_minor(), srs_version_revision()); + srs_version_major(), srs_version_minor(), srs_version_revision()); if (argc <= 2) { printf("ingest RTMP and publish to RTMP server\n" @@ -57,9 +57,9 @@ int main(int argc, char** argv) " in_rtmp_url input rtmp url, ingest from this url.\n" " out_rtmp_url output rtmp url, publish to this url.\n" " verbose output verbose log.\n" - "For example:\n" - " %s -i rtmp://127.0.0.1/live/livestream -y rtmp://127.0.0.1/live/demo\n" - " %s -i rtmp://127.0.0.1/live/livestream -y rtmp://127.0.0.1/live/demo -v verbose\n", + "For example:\n" + " %s -i rtmp://127.0.0.1/live/livestream -y rtmp://127.0.0.1/live/demo\n" + " %s -i rtmp://127.0.0.1/live/livestream -y rtmp://127.0.0.1/live/demo -v verbose\n", argv[0], argv[0], argv[0]); exit(-1); } @@ -96,7 +96,7 @@ int main(int argc, char** argv) irtmp = srs_rtmp_create(in_rtmp_url); ortmp = srs_rtmp_create(out_rtmp_url); - + ret = proxy(irtmp, ortmp); srs_human_trace("proxy completed"); @@ -116,7 +116,7 @@ int proxy(srs_rtmp_t irtmp, srs_rtmp_t ortmp) char* data; uint32_t timestamp; uint64_t nb_msgs = 0; - + if ((ret = connect_ic(irtmp)) != 0) { return ret; } @@ -162,10 +162,10 @@ int proxy(srs_rtmp_t irtmp, srs_rtmp_t ortmp) if (verbose) { srs_human_trace("ortmp sent packet: type=%s, time=%d, size=%d", - srs_human_flv_tag_type2string(type), timestamp, size); + srs_human_flv_tag_type2string(type), timestamp, size); } else { srs_human_verbose("ortmp sent packet: type=%s, time=%d, size=%d", - srs_human_flv_tag_type2string(type), timestamp, size); + srs_human_flv_tag_type2string(type), timestamp, size); } } @@ -210,7 +210,7 @@ int connect_ic(srs_rtmp_t irtmp) return ret; } srs_human_trace("irtmp connect ok, ip=%s, server=%s/%d.%d.%d.%d, pid=%d, cid=%d", - ip, sig, major, minor, revision, build, pid, cid); + ip, sig, major, minor, revision, build, pid, cid); if ((ret = srs_rtmp_play_stream(irtmp)) != 0) { srs_human_trace("irtmp play stream failed. ret=%d", ret); @@ -263,7 +263,7 @@ int connect_oc(srs_rtmp_t ortmp) return ret; } srs_human_trace("ortmp connect ok, ip=%s, server=%s/%d.%d.%d.%d, pid=%d, cid=%d", - ip, sig, major, minor, revision, build, pid, cid); + ip, sig, major, minor, revision, build, pid, cid); if ((ret = srs_rtmp_publish_stream(ortmp)) != 0) { srs_human_trace("ortmp publish stream failed. ret=%d", ret); diff --git a/trunk/research/librtmp/srs_publish.c b/trunk/research/librtmp/srs_publish.c index f58f9aee4..4d1e24197 100644 --- a/trunk/research/librtmp/srs_publish.c +++ b/trunk/research/librtmp/srs_publish.c @@ -44,7 +44,7 @@ int main(int argc, char** argv) // warn it . // @see: https://github.com/ossrs/srs/issues/126 - srs_human_trace("\033[33m%s\033[0m", + srs_human_trace("\033[33m%s\033[0m", "[warning] it's only a sample to use librtmp. " "please never use it to publish and test forward/transcode/edge/HLS whatever. " "you should refer to this tool to use the srs-librtmp to publish the real media stream." @@ -81,8 +81,7 @@ int main(int argc, char** argv) if (srs_rtmp_write_packet(rtmp, type, timestamp, data, size) != 0) { goto rtmp_destroy; } - srs_human_trace("sent packet: type=%s, time=%d, size=%d", - srs_human_flv_tag_type2string(type), timestamp, size); + srs_human_trace("sent packet: type=%s, time=%d, size=%d", srs_human_flv_tag_type2string(type), timestamp, size); usleep(40 * 1000); } diff --git a/trunk/src/app/srs_app_async_call.cpp b/trunk/src/app/srs_app_async_call.cpp index fb4ebe67c..9624741a9 100644 --- a/trunk/src/app/srs_app_async_call.cpp +++ b/trunk/src/app/srs_app_async_call.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -48,24 +48,24 @@ SrsAsyncCallWorker::SrsAsyncCallWorker() SrsAsyncCallWorker::~SrsAsyncCallWorker() { srs_freep(pthread); - + std::vector::iterator it; for (it = tasks.begin(); it != tasks.end(); ++it) { ISrsAsyncCallTask* task = *it; srs_freep(task); } tasks.clear(); - + st_cond_destroy(wait); } int SrsAsyncCallWorker::execute(ISrsAsyncCallTask* t) { int ret = ERROR_SUCCESS; - + tasks.push_back(t); st_cond_signal(wait); - + return ret; } @@ -88,15 +88,15 @@ void SrsAsyncCallWorker::stop() int SrsAsyncCallWorker::cycle() { int ret = ERROR_SUCCESS; - + while (pthread->can_loop()) { if (tasks.empty()) { st_cond_wait(wait); } - + std::vector copies = tasks; tasks.clear(); - + std::vector::iterator it; for (it = copies.begin(); it != copies.end(); ++it) { ISrsAsyncCallTask* task = *it; @@ -106,7 +106,7 @@ int SrsAsyncCallWorker::cycle() srs_freep(task); } } - + return ret; } diff --git a/trunk/src/app/srs_app_async_call.hpp b/trunk/src/app/srs_app_async_call.hpp index 48cf49bb7..f35dbb8cb 100644 --- a/trunk/src/app/srs_app_async_call.hpp +++ b/trunk/src/app/srs_app_async_call.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_ASYNC_CALL_HPP #define SRS_APP_ASYNC_CALL_HPP -/* -#include -*/ #include #include diff --git a/trunk/src/app/srs_app_bandwidth.cpp b/trunk/src/app/srs_app_bandwidth.cpp index 462bfe25f..af69d1564 100644 --- a/trunk/src/app/srs_app_bandwidth.cpp +++ b/trunk/src/app/srs_app_bandwidth.cpp @@ -1,26 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -69,8 +68,8 @@ void SrsBandwidthSample::calc_kbps(int _bytes, int _duration) } /** -* recv bandwidth helper. -*/ + * recv bandwidth helper. + */ typedef bool (*_CheckPacketType)(SrsBandwidthPacket* pkt); bool _bandwidth_is_final(SrsBandwidthPacket* pkt) { @@ -134,13 +133,13 @@ int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io if (!_srs_config->get_bw_check_enabled(_req->vhost)) { return ret; } - + // validate the bandwidth check key std::string key = "key=" + _srs_config->get_bw_check_key(_req->vhost); if (_req->tcUrl.find(key) == std::string::npos) { ret = ERROR_SYSTEM_BANDWIDTH_KEY; - srs_error("check the vhost=%s %s failed, tcUrl=%s, ret=%d", - _req->vhost.c_str(), key.c_str(), _req->tcUrl.c_str(), ret); + srs_error("check the vhost=%s %s failed, tcUrl=%s, ret=%d", + _req->vhost.c_str(), key.c_str(), _req->tcUrl.c_str(), ret); return ret; } @@ -157,9 +156,9 @@ int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io if (last_check_time > 0 && time_now - last_check_time < interval_ms) { ret = ERROR_SYSTEM_BANDWIDTH_DENIED; srs_trace("reject, " - "last_check=%"PRId64", now=%"PRId64", interval=%d", - last_check_time, time_now, interval_ms); - + "last_check=%"PRId64", now=%"PRId64", interval=%d", + last_check_time, time_now, interval_ms); + _rtmp->response_connect_reject(_req, "bandcheck rejected"); return ret; } @@ -175,7 +174,7 @@ int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io // create a limit object. SrsKbps kbps; kbps.set_io(io_stat, io_stat); - + int limit_kbps = _srs_config->get_bw_check_limit_kbps(_req->vhost); SrsKbpsLimit limit(&kbps, limit_kbps); @@ -185,14 +184,14 @@ int SrsBandwidth::bandwidth_check(SrsRtmpServer* rtmp, ISrsProtocolStatistic* io int SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit) { int ret = ERROR_SUCCESS; - + SrsBandwidthSample play_sample; SrsBandwidthSample publish_sample; // timeout for a packet. _rtmp->set_send_timeout(play_sample.duration_ms * 2); _rtmp->set_recv_timeout(publish_sample.duration_ms * 2); - + // start test. srs_update_system_time_ms(); int64_t start_time = srs_get_system_time_ms(); @@ -232,15 +231,15 @@ int SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit) } srs_info("stop publish test. kbps=%d", publish_sample.kbps); - + // stop test. srs_update_system_time_ms(); int64_t end_time = srs_get_system_time_ms(); - - srs_trace("bandwidth ok. duartion=%dms(%d+%d), play=%dkbps, publish=%dkbps", - (int)(end_time - start_time), play_sample.actual_duration_ms, - publish_sample.actual_duration_ms, play_sample.kbps, - publish_sample.kbps); + + srs_trace("bandwidth ok. duartion=%dms(%d+%d), play=%dkbps, publish=%dkbps", + (int)(end_time - start_time), play_sample.actual_duration_ms, + publish_sample.actual_duration_ms, play_sample.kbps, + publish_sample.kbps); if ((ret = finial(play_sample, publish_sample, start_time, end_time)) != ERROR_SUCCESS) { return ret; @@ -248,7 +247,7 @@ int SrsBandwidth::do_bandwidth_check(SrsKbpsLimit* limit) st_usleep(_SRS_BANDWIDTH_FINAL_WAIT_MS * 1000); srs_info("BW check finished."); - + return ret; } @@ -259,18 +258,18 @@ int SrsBandwidth::play_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit) if (true) { // send start play command to client SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_start_play(); - + pkt->data->set("limit_kbps", SrsAmf0Any::number(limit->limit_kbps())); pkt->data->set("duration_ms", SrsAmf0Any::number(sample->duration_ms)); pkt->data->set("interval_ms", SrsAmf0Any::number(sample->interval_ms)); - + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send bandwidth check start play message failed. ret=%d", ret); return ret; } } srs_info("BW check play begin."); - + if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_starting_play)) != ERROR_SUCCESS) { return ret; } @@ -282,12 +281,12 @@ int SrsBandwidth::play_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit) int SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit) { int ret = ERROR_SUCCESS; - + // send play data to client int size = 1024; // TODO: FIXME: magic number char random_data[size]; memset(random_data, 'A', size); - + int data_count = 1; srs_update_system_time_ms(); int64_t starttime = srs_get_system_time_ms(); @@ -296,7 +295,7 @@ int SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit) // TODO: FIXME: use shared ptr message. SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_playing(); - + // TODO: FIXME: magic number for (int i = 0; i < data_count; ++i) { std::stringstream seq; @@ -305,7 +304,7 @@ int SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit) pkt->data->set(seq.str(), SrsAmf0Any::str(play_data.c_str())); } data_count += 2; - + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send bandwidth check play messages failed. ret=%d", ret); return ret; @@ -323,7 +322,7 @@ int SrsBandwidth::play_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit) int SrsBandwidth::play_stop(SrsBandwidthSample* sample, SrsKbpsLimit* /*limit*/) { int ret = ERROR_SUCCESS; - + if (true) { // notify client to stop play SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_play(); @@ -332,14 +331,14 @@ int SrsBandwidth::play_stop(SrsBandwidthSample* sample, SrsKbpsLimit* /*limit*/) pkt->data->set("interval_ms", SrsAmf0Any::number(sample->interval_ms)); pkt->data->set("duration_delta", SrsAmf0Any::number(sample->actual_duration_ms)); pkt->data->set("bytes_delta", SrsAmf0Any::number(sample->bytes)); - + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send bandwidth check stop play message failed. ret=%d", ret); return ret; } } srs_info("BW check stop play bytes."); - + if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stopped_play)) != ERROR_SUCCESS) { return ret; } @@ -351,22 +350,22 @@ int SrsBandwidth::play_stop(SrsBandwidthSample* sample, SrsKbpsLimit* /*limit*/) int SrsBandwidth::publish_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit) { int ret = ERROR_SUCCESS; - + if (true) { // notify client to start publish SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_start_publish(); - + pkt->data->set("limit_kbps", SrsAmf0Any::number(limit->limit_kbps())); pkt->data->set("duration_ms", SrsAmf0Any::number(sample->duration_ms)); pkt->data->set("interval_ms", SrsAmf0Any::number(sample->interval_ms)); - + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send bandwidth check start publish message failed. ret=%d", ret); return ret; } } srs_info("BW check publish begin."); - + if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_starting_publish)) != ERROR_SUCCESS) { return ret; } @@ -378,7 +377,7 @@ int SrsBandwidth::publish_start(SrsBandwidthSample* sample, SrsKbpsLimit* limit) int SrsBandwidth::publish_checking(SrsBandwidthSample* sample, SrsKbpsLimit* limit) { int ret = ERROR_SUCCESS; - + // recv publish msgs until @duration_ms ms srs_update_system_time_ms(); int64_t starttime = srs_get_system_time_ms(); @@ -409,7 +408,7 @@ int SrsBandwidth::publish_checking(SrsBandwidthSample* sample, SrsKbpsLimit* lim int SrsBandwidth::publish_stop(SrsBandwidthSample* sample, SrsKbpsLimit* /*limit*/) { int ret = ERROR_SUCCESS; - + if (true) { // notify client to stop publish SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_publish(); @@ -417,16 +416,16 @@ int SrsBandwidth::publish_stop(SrsBandwidthSample* sample, SrsKbpsLimit* /*limit pkt->data->set("interval_ms", SrsAmf0Any::number(sample->interval_ms)); pkt->data->set("duration_delta", SrsAmf0Any::number(sample->actual_duration_ms)); pkt->data->set("bytes_delta", SrsAmf0Any::number(sample->bytes)); - + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send bandwidth check stop publish message failed. ret=%d", ret); return ret; } } srs_info("BW check stop publish bytes."); - + // expect client to stop publish - // if flash client, we never expect the client stop publish bytes, + // if flash client, we never expect the client stop publish bytes, // for the flash send call packet to test publish bandwidth, // there are many many packets in the queue. // we just ignore the packet and send the bandwidth test data. @@ -444,7 +443,7 @@ int SrsBandwidth::publish_stop(SrsBandwidthSample* sample, SrsKbpsLimit* /*limit int SrsBandwidth::finial(SrsBandwidthSample& play_sample, SrsBandwidthSample& publish_sample, int64_t start_time, int64_t& end_time) { int ret = ERROR_SUCCESS; - + // send finished msg, // flash client will close connection when got this packet, // for the publish queue may contains packets. @@ -457,7 +456,7 @@ int SrsBandwidth::finial(SrsBandwidthSample& play_sample, SrsBandwidthSample& pu pkt->data->set("publish_bytes", SrsAmf0Any::number(publish_sample.bytes)); pkt->data->set("play_time", SrsAmf0Any::number(play_sample.actual_duration_ms)); pkt->data->set("publish_time", SrsAmf0Any::number(publish_sample.actual_duration_ms)); - + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send bandwidth check finish message failed. ret=%d", ret); return ret; @@ -474,7 +473,7 @@ int SrsBandwidth::finial(SrsBandwidthSample& play_sample, SrsBandwidthSample& pu } srs_info("BW check finished."); - + return ret; } diff --git a/trunk/src/app/srs_app_bandwidth.hpp b/trunk/src/app/srs_app_bandwidth.hpp index e48a50a32..15ef0f581 100644 --- a/trunk/src/app/srs_app_bandwidth.hpp +++ b/trunk/src/app/srs_app_bandwidth.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_BANDWIDTH_HPP #define SRS_APP_BANDWIDTH_HPP -/* -#include -*/ #include #include @@ -41,84 +37,84 @@ class SrsKbpsLimit; class ISrsProtocolStatistic; /** -* bandwidth check/test sample. -*/ + * 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. -*/ + * 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: @@ -129,74 +125,74 @@ public: 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 int 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 int do_bandwidth_check(SrsKbpsLimit* limit); -// play check/test, downloading bandwidth kbps. + // 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 int 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 int 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 int play_stop(SrsBandwidthSample* sample, SrsKbpsLimit* limit); -// publish check/test, publishing bandwidth kbps. + // 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 int 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 int 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 int 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 int finial(SrsBandwidthSample& play_sample, SrsBandwidthSample& publish_sample, int64_t start_time, int64_t& end_time); }; diff --git a/trunk/src/app/srs_app_caster_flv.cpp b/trunk/src/app/srs_app_caster_flv.cpp index fe515f0ff..844e8172e 100644 --- a/trunk/src/app/srs_app_caster_flv.cpp +++ b/trunk/src/app/srs_app_caster_flv.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -118,7 +118,7 @@ int SrsAppCasterFlv::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) } SrsDynamicHttpConn::SrsDynamicHttpConn(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m, string cip) - : SrsHttpConn(cm, fd, m, cip) +: SrsHttpConn(cm, fd, m, cip) { sdk = NULL; pprint = SrsPithyPrint::create_caster(); diff --git a/trunk/src/app/srs_app_caster_flv.hpp b/trunk/src/app/srs_app_caster_flv.hpp index d1320546c..4c61eee76 100644 --- a/trunk/src/app/srs_app_caster_flv.hpp +++ b/trunk/src/app/srs_app_caster_flv.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_CASTER_FLV_HPP #define SRS_APP_CASTER_FLV_HPP -/* -#include -*/ - #include #include @@ -56,7 +52,7 @@ class SrsSimpleRtmpClient; * the stream caster for flv stream over HTTP POST. */ class SrsAppCasterFlv : virtual public ISrsTcpHandler - , virtual public IConnectionManager, virtual public ISrsHttpHandler +, virtual public IConnectionManager, virtual public ISrsHttpHandler { private: std::string output; @@ -67,13 +63,13 @@ public: virtual ~SrsAppCasterFlv(); public: virtual int initialize(); -// ISrsTcpHandler + // ISrsTcpHandler public: virtual int on_tcp_client(st_netfd_t stfd); -// IConnectionManager + // IConnectionManager public: virtual void remove(SrsConnection* c); -// ISrsHttpHandler + // ISrsHttpHandler public: virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); }; diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 9605c98e3..951c83819 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -156,8 +156,8 @@ namespace _srs_internal // read total content from file. ssize_t nread = 0; if ((ret = reader.read(start, filesize, &nread)) != ERROR_SUCCESS) { - srs_error("read file read error. expect %d, actual %d bytes, ret=%d", - filesize, nread, ret); + srs_error("read file read error. expect %d, actual %d bytes, ret=%d", + filesize, nread, ret); return ret; } @@ -468,7 +468,7 @@ int srs_config_transform_vhost(SrsConfDirective* root) if (n == "time_jitter" || n == "mix_correct" || n == "atc" || n == "atc_auto" || n == "mw_latency" || n == "gop_cache" || n == "queue_length" || n == "send_min_interval" || n == "reduce_sequence_header" - ) { + ) { it = dir->directives.erase(it); SrsConfDirective* play = dir->get_or_create("play"); @@ -925,13 +925,13 @@ int SrsConfDirective::parse_conf(SrsConfigBuffer* buffer, SrsDirectiveType type) ret = read_token(buffer, args, line_start); /** - * ret maybe: - * ERROR_SYSTEM_CONFIG_INVALID error. - * ERROR_SYSTEM_CONFIG_DIRECTIVE directive terminated by ';' found - * ERROR_SYSTEM_CONFIG_BLOCK_START token terminated by '{' found - * ERROR_SYSTEM_CONFIG_BLOCK_END the '}' found - * ERROR_SYSTEM_CONFIG_EOF the config file is done - */ + * ret maybe: + * ERROR_SYSTEM_CONFIG_INVALID error. + * ERROR_SYSTEM_CONFIG_DIRECTIVE directive terminated by ';' found + * ERROR_SYSTEM_CONFIG_BLOCK_START token terminated by '{' found + * ERROR_SYSTEM_CONFIG_BLOCK_END the '}' found + * ERROR_SYSTEM_CONFIG_EOF the config file is done + */ if (ret == ERROR_SYSTEM_CONFIG_INVALID) { return ret; } @@ -958,7 +958,7 @@ int SrsConfDirective::parse_conf(SrsConfigBuffer* buffer, SrsDirectiveType type) // build directive tree. SrsConfDirective* directive = new SrsConfDirective(); - + directive->conf_line = line_start; directive->name = args[0]; args.erase(args.begin()); @@ -980,9 +980,9 @@ int SrsConfDirective::parse_conf(SrsConfigBuffer* buffer, SrsDirectiveType type) int SrsConfDirective::read_token(SrsConfigBuffer* buffer, vector& args, int& line_start) { int ret = ERROR_SUCCESS; - + char* pstart = buffer->pos; - + bool sharp_comment = false; bool d_quoted = false; @@ -1028,7 +1028,7 @@ int SrsConfDirective::read_token(SrsConfigBuffer* buffer, vector& args, return ERROR_SYSTEM_CONFIG_BLOCK_START; } srs_error("line %d: unexpected '%c'", buffer->line, ch); - return ERROR_SYSTEM_CONFIG_INVALID; + return ERROR_SYSTEM_CONFIG_INVALID; } // last charecter is space. @@ -1190,9 +1190,9 @@ void SrsConfig::unsubscribe(ISrsReloadHandler* handler) int SrsConfig::reload() { int ret = ERROR_SUCCESS; - + SrsConfig conf; - + if ((ret = conf.parse_file(config_file.c_str())) != ERROR_SUCCESS) { srs_error("ignore config reloader parse file failed. ret=%d", ret); ret = ERROR_SUCCESS; @@ -1205,7 +1205,7 @@ int SrsConfig::reload() srs_error("transform config failed. ret=%d", ret); return ret; } - + if ((ret = conf.check_config()) != ERROR_SUCCESS) { srs_error("ignore config reloader check config failed. ret=%d", ret); ret = ERROR_SUCCESS; @@ -1230,7 +1230,7 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) // DISABLED => ENABLED // ENABLED => DISABLED // ENABLED => ENABLED (modified) - + // collect all vhost names std::vector vhosts; for (int i = 0; i < (int)root->directives.size(); i++) { @@ -1254,7 +1254,7 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) // process each vhost for (int i = 0; i < (int)vhosts.size(); i++) { std::string vhost = vhosts.at(i); - + SrsConfDirective* old_vhost = old_root->get("vhost", vhost); SrsConfDirective* new_vhost = root->get("vhost", vhost); @@ -1289,7 +1289,7 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) // the auto reload configs: // publish.parse_sps - + // ENABLED => ENABLED (modified) if (get_vhost_enabled(new_vhost) && get_vhost_enabled(old_vhost)) { srs_trace("vhost %s maybe modified, reload its detail.", vhost.c_str()); @@ -1377,7 +1377,7 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) } srs_trace("vhost %s reload hls success.", vhost.c_str()); } - + // hds reload if (!srs_directive_equals(new_vhost->get("hds"), old_vhost->get("hds"))) { for (it = subscribes.begin(); it != subscribes.end(); ++it) { @@ -1389,7 +1389,7 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) } srs_trace("vhost %s reload hds success.", vhost.c_str()); } - + // dvr, only one per vhost, except the dvr_apply if (!srs_directive_equals(new_vhost->get("dvr"), old_vhost->get("dvr"), "dvr_apply")) { for (it = subscribes.begin(); it != subscribes.end(); ++it) { @@ -1473,9 +1473,9 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) continue; } srs_trace("ignore reload vhost, enabled old: %d, new: %d", - get_vhost_enabled(old_vhost), get_vhost_enabled(new_vhost)); + get_vhost_enabled(old_vhost), get_vhost_enabled(new_vhost)); } - + return ret; } @@ -1491,7 +1491,7 @@ int SrsConfig::reload_conf(SrsConfig* conf) // merge config. std::vector::iterator it; - + // never support reload: // daemon // @@ -1499,7 +1499,7 @@ int SrsConfig::reload_conf(SrsConfig* conf) // chunk_size, ff_log_dir, // bandcheck, http_hooks, heartbeat, // security - + // merge config: listen if (!srs_directive_equals(root->get("listen"), old_root->get("listen"))) { if ((ret = do_reload_listen()) != ERROR_SUCCESS) { @@ -1565,10 +1565,10 @@ int SrsConfig::reload_conf(SrsConfig* conf) if ((ret = reload_http_stream(old_root)) != ERROR_SUCCESS) { return ret; } - + // TODO: FIXME: support reload stream_caster. // TODO: FIXME: support reload kafka. - + // merge config: vhost if ((ret = reload_vhost(old_root)) != ERROR_SUCCESS) { return ret; @@ -1592,7 +1592,7 @@ int SrsConfig::reload_http_api(SrsConfDirective* old_root) SrsConfDirective* new_http_api = root->get("http_api"); SrsConfDirective* old_http_api = old_root->get("http_api"); - + // DISABLED => ENABLED if (!get_http_api_enabled(old_http_api) && get_http_api_enabled(new_http_api)) { for (it = subscribes.begin(); it != subscribes.end(); ++it) { @@ -1606,7 +1606,7 @@ int SrsConfig::reload_http_api(SrsConfDirective* old_root) return ret; } - + // ENABLED => DISABLED if (get_http_api_enabled(old_http_api) && !get_http_api_enabled(new_http_api)) { for (it = subscribes.begin(); it != subscribes.end(); ++it) { @@ -1624,7 +1624,7 @@ int SrsConfig::reload_http_api(SrsConfDirective* old_root) // ENABLED => ENABLED (modified) if (get_http_api_enabled(old_http_api) && get_http_api_enabled(new_http_api) && !srs_directive_equals(old_http_api, new_http_api) - ) { + ) { for (it = subscribes.begin(); it != subscribes.end(); ++it) { ISrsReloadHandler* subscribe = *it; if ((ret = subscribe->on_reload_http_api_enabled()) != ERROR_SUCCESS) { @@ -1679,7 +1679,7 @@ int SrsConfig::reload_http_stream(SrsConfDirective* old_root) SrsConfDirective* new_http_stream = root->get("http_server"); SrsConfDirective* old_http_stream = old_root->get("http_server"); - + // DISABLED => ENABLED if (!get_http_stream_enabled(old_http_stream) && get_http_stream_enabled(new_http_stream)) { for (it = subscribes.begin(); it != subscribes.end(); ++it) { @@ -1693,7 +1693,7 @@ int SrsConfig::reload_http_stream(SrsConfDirective* old_root) return ret; } - + // ENABLED => DISABLED if (get_http_stream_enabled(old_http_stream) && !get_http_stream_enabled(new_http_stream)) { for (it = subscribes.begin(); it != subscribes.end(); ++it) { @@ -1711,7 +1711,7 @@ int SrsConfig::reload_http_stream(SrsConfDirective* old_root) // ENABLED => ENABLED (modified) if (get_http_stream_enabled(old_http_stream) && get_http_stream_enabled(new_http_stream) && !srs_directive_equals(old_http_stream, new_http_stream) - ) { + ) { for (it = subscribes.begin(); it != subscribes.end(); ++it) { ISrsReloadHandler* subscribe = *it; if ((ret = subscribe->on_reload_http_stream_updated()) != ERROR_SUCCESS) { @@ -1765,7 +1765,7 @@ int SrsConfig::reload_transcode(SrsConfDirective* new_vhost, SrsConfDirective* o std::string vhost = new_vhost->arg0(); // to be simple: - // whatever, once tiny changed of transcode, + // whatever, once tiny changed of transcode, // restart all ffmpeg of vhost. bool changed = false; @@ -1860,8 +1860,8 @@ int SrsConfig::reload_ingest(SrsConfDirective* new_vhost, SrsConfDirective* old_ for (it = subscribes.begin(); it != subscribes.end(); ++it) { ISrsReloadHandler* subscribe = *it; if ((ret = subscribe->on_reload_ingest_removed(vhost, ingest_id)) != ERROR_SUCCESS) { - srs_error("vhost %s notify subscribes ingest=%s removed failed. ret=%d", - vhost.c_str(), ingest_id.c_str(), ret); + srs_error("vhost %s notify subscribes ingest=%s removed failed. ret=%d", + vhost.c_str(), ingest_id.c_str(), ret); return ret; } } @@ -1880,15 +1880,15 @@ int SrsConfig::reload_ingest(SrsConfDirective* new_vhost, SrsConfDirective* old_ for (it = subscribes.begin(); it != subscribes.end(); ++it) { ISrsReloadHandler* subscribe = *it; if ((ret = subscribe->on_reload_ingest_added(vhost, ingest_id)) != ERROR_SUCCESS) { - srs_error("vhost %s notify subscribes ingest=%s added failed. ret=%d", - vhost.c_str(), ingest_id.c_str(), ret); + srs_error("vhost %s notify subscribes ingest=%s added failed. ret=%d", + vhost.c_str(), ingest_id.c_str(), ret); return ret; } } srs_trace("vhost %s reload ingest=%s added success.", vhost.c_str(), ingest_id.c_str()); } } - + // for updated ingesters, restart them. for (int i = 0; i < (int)new_ingesters.size(); i++) { SrsConfDirective* new_ingester = new_ingesters.at(i); @@ -1900,20 +1900,20 @@ int SrsConfig::reload_ingest(SrsConfDirective* new_vhost, SrsConfDirective* old_ if (srs_directive_equals(new_ingester, old_ingester)) { continue; } - + // notice handler ingester removed. for (it = subscribes.begin(); it != subscribes.end(); ++it) { ISrsReloadHandler* subscribe = *it; if ((ret = subscribe->on_reload_ingest_updated(vhost, ingest_id)) != ERROR_SUCCESS) { - srs_error("vhost %s notify subscribes ingest=%s updated failed. ret=%d", - vhost.c_str(), ingest_id.c_str(), ret); + srs_error("vhost %s notify subscribes ingest=%s updated failed. ret=%d", + vhost.c_str(), ingest_id.c_str(), ret); return ret; } } srs_trace("vhost %s reload ingest=%s updated success.", vhost.c_str(), ingest_id.c_str()); } } - + srs_trace("ingest not changed for vhost=%s", vhost.c_str()); return ret; @@ -1963,7 +1963,7 @@ int SrsConfig::parse_options(int argc, char** argv) srs_error("config file not specified, see help: %s -h, ret=%d", argv[0], ret); return ret; } - + ret = parse_file(config_file.c_str()); // transform config to compatible with previous style of config. @@ -1978,7 +1978,7 @@ int SrsConfig::parse_options(int argc, char** argv) if (ret == ERROR_SUCCESS) { ret = check_config(); } - + if (ret == ERROR_SUCCESS) { srs_trace("config file is ok"); exit(0); @@ -1987,7 +1987,7 @@ int SrsConfig::parse_options(int argc, char** argv) exit(ret); } } - + //////////////////////////////////////////////////////////////////////// // check log name and level //////////////////////////////////////////////////////////////////////// @@ -2013,12 +2013,12 @@ int SrsConfig::parse_options(int argc, char** argv) int SrsConfig::initialize_cwd() { int ret = ERROR_SUCCESS; - + // cwd char cwd[256]; getcwd(cwd, sizeof(cwd)); _cwd = cwd; - + return ret; } @@ -3410,7 +3410,7 @@ int SrsConfig::parse_argv(int& i, char** argv) int ret = ERROR_SUCCESS; char* p = argv[i]; - + if (*p++ != '-') { show_help = true; return ret; @@ -3488,33 +3488,33 @@ int SrsConfig::parse_argv(int& i, char** argv) void SrsConfig::print_help(char** argv) { printf( - RTMP_SIG_SRS_SERVER" "RTMP_SIG_SRS_COPYRIGHT"\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?vVsS] [[-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" - "For srs-dolphin:\n" - " -p rtmp-port : the rtmp port to listen.\n" - " -x http-port : the http port to listen.\n" - "\n" - RTMP_SIG_SRS_WEB"\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" - " %s -c "SRS_CONF_DEFAULT_COFNIG_FILE"\n", - argv[0], argv[0], argv[0], argv[0]); + RTMP_SIG_SRS_SERVER" "RTMP_SIG_SRS_COPYRIGHT"\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?vVsS] [[-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" + "For srs-dolphin:\n" + " -p rtmp-port : the rtmp port to listen.\n" + " -x http-port : the http port to listen.\n" + "\n" + RTMP_SIG_SRS_WEB"\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" + " %s -c "SRS_CONF_DEFAULT_COFNIG_FILE"\n", + argv[0], argv[0], argv[0], argv[0]); } int SrsConfig::parse_file(const char* filename) @@ -3539,9 +3539,9 @@ int SrsConfig::parse_file(const char* filename) int SrsConfig::check_config() { int ret = ERROR_SUCCESS; - + srs_trace("srs checking config..."); - + //////////////////////////////////////////////////////////////////////// // check empty //////////////////////////////////////////////////////////////////////// @@ -3557,13 +3557,13 @@ int SrsConfig::check_config() for (int i = 0; i < (int)root->directives.size(); i++) { SrsConfDirective* conf = root->at(i); std::string n = conf->name; - if (n != "listen" && n != "pid" && n != "chunk_size" && n != "ff_log_dir" + if (n != "listen" && n != "pid" && n != "chunk_size" && n != "ff_log_dir" && n != "srs_log_tank" && n != "srs_log_level" && n != "srs_log_file" && n != "max_connections" && n != "daemon" && n != "heartbeat" && n != "http_api" && n != "stats" && n != "vhost" && n != "pithy_print_ms" && n != "http_server" && n != "stream_caster" && n != "kafka" && n != "utc_time" && n != "work_dir" && n != "asprocess" - ) { + ) { ret = ERROR_SYSTEM_CONFIG_INVALID; srs_error("unsupported directive %s, ret=%d", n.c_str(), ret); return ret; @@ -3638,7 +3638,7 @@ int SrsConfig::check_config() } } } - + //////////////////////////////////////////////////////////////////////// // check listen for rtmp. //////////////////////////////////////////////////////////////////////// @@ -3688,18 +3688,18 @@ int SrsConfig::check_config() int max_open_files = (int)sysconf(_SC_OPEN_MAX); int nb_canbe = max_open_files - nb_consumed_fds - 1; - + // for each play connections, we open a pipe(2fds) to convert SrsConsumver to io, // refine performance, @see: https://github.com/ossrs/srs/issues/194 if (nb_total >= max_open_files) { ret = ERROR_SYSTEM_CONFIG_INVALID; srs_error("invalid max_connections=%d, required=%d, system limit to %d, " - "total=%d(max_connections=%d, nb_consumed_fds=%d), ret=%d. " - "you can change max_connections from %d to %d, or " - "you can login as root and set the limit: ulimit -HSn %d", - nb_connections, nb_total + 100, max_open_files, - nb_total, nb_connections, nb_consumed_fds, - ret, nb_connections, nb_canbe, nb_total + 100); + "total=%d(max_connections=%d, nb_consumed_fds=%d), ret=%d. " + "you can change max_connections from %d to %d, or " + "you can login as root and set the limit: ulimit -HSn %d", + nb_connections, nb_total + 100, max_open_files, + nb_total, nb_connections, nb_consumed_fds, + ret, nb_connections, nb_canbe, nb_total + 100); return ret; } } @@ -3709,18 +3709,18 @@ int SrsConfig::check_config() //////////////////////////////////////////////////////////////////////// if (get_heartbeat_interval() <= 0) { ret = ERROR_SYSTEM_CONFIG_INVALID; - srs_error("directive heartbeat interval invalid, interval=%"PRId64", ret=%d", - get_heartbeat_interval(), ret); + srs_error("directive heartbeat interval invalid, interval=%"PRId64", ret=%d", + get_heartbeat_interval(), ret); return ret; } - + //////////////////////////////////////////////////////////////////////// // check stats //////////////////////////////////////////////////////////////////////// if (get_stats_network() < 0) { ret = ERROR_SYSTEM_CONFIG_INVALID; - srs_error("directive stats network invalid, network=%d, ret=%d", - get_stats_network(), ret); + srs_error("directive stats network invalid, network=%d, ret=%d", + get_stats_network(), ret); return ret; } if (true) { @@ -3729,7 +3729,7 @@ int SrsConfig::check_config() if (index >= (int)ips.size()) { ret = ERROR_SYSTEM_CONFIG_INVALID; srs_error("stats network invalid, total local ip count=%d, index=%d, ret=%d", - (int)ips.size(), index, ret); + (int)ips.size(), index, ret); return ret; } srs_warn("stats network use index=%d, ip=%s", index, ips.at(index).c_str()); @@ -3754,7 +3754,7 @@ int SrsConfig::check_config() if (get_http_api_listen().empty()) { ret = ERROR_SYSTEM_CONFIG_INVALID; srs_error("directive http_api listen invalid, listen=%s, ret=%d", - get_http_api_listen().c_str(), ret); + get_http_api_listen().c_str(), ret); return ret; } @@ -3764,10 +3764,10 @@ int SrsConfig::check_config() if (get_http_stream_listen().empty()) { ret = ERROR_SYSTEM_CONFIG_INVALID; srs_error("directive http_stream listen invalid, listen=%s, ret=%d", - get_http_stream_listen().c_str(), ret); + get_http_stream_listen().c_str(), ret); return ret; } - + //////////////////////////////////////////////////////////////////////// // check log name and level //////////////////////////////////////////////////////////////////////// @@ -3805,7 +3805,7 @@ int SrsConfig::check_config() } } } - + //////////////////////////////////////////////////////////////////////// // check vhosts. //////////////////////////////////////////////////////////////////////// @@ -3823,7 +3823,7 @@ int SrsConfig::check_config() && n != "security" && n != "http_remux" && n != "dash" && n != "http_static" && n != "hds" && n != "exec" && n != "in_ack_size" && n != "out_ack_size" - ) { + ) { ret = ERROR_SYSTEM_CONFIG_INVALID; srs_error("unsupported vhost directive %s, ret=%d", n.c_str(), ret); return ret; @@ -3834,7 +3834,7 @@ int SrsConfig::check_config() string m = conf->at(j)->name; if (m != "enabled" && m != "dvr_apply" && m != "dvr_path" && m != "dvr_plan" && m != "dvr_duration" && m != "dvr_wait_keyframe" && m != "time_jitter" - ) { + ) { ret = ERROR_SYSTEM_CONFIG_INVALID; srs_error("unsupported vhost dvr directive %s, ret=%d", m.c_str(), ret); return ret; @@ -3863,7 +3863,7 @@ int SrsConfig::check_config() string m = conf->at(j)->name; if (m != "time_jitter" && m != "mix_correct" && m != "atc" && m != "atc_auto" && m != "mw_latency" && m != "gop_cache" && m != "queue_length" && m != "send_min_interval" && m != "reduce_sequence_header" - ) { + ) { ret = ERROR_SYSTEM_CONFIG_INVALID; srs_error("unsupported vhost play directive %s, ret=%d", m.c_str(), ret); return ret; @@ -4015,13 +4015,13 @@ int SrsConfig::check_config() for (int i = 0; i < (int)vhosts.size(); i++) { SrsConfDirective* vhost = vhosts[i]; std::vector ids; - + for (int j = 0; j < (int)vhost->directives.size(); j++) { SrsConfDirective* conf = vhost->at(j); if (conf->name != "ingest") { continue; } - + std::string id = conf->arg0(); for (int k = 0; k < (int)ids.size(); k++) { if (id == ids.at(k)) { @@ -4038,24 +4038,24 @@ int SrsConfig::check_config() //////////////////////////////////////////////////////////////////////// // check chunk size //////////////////////////////////////////////////////////////////////// - if (get_global_chunk_size() < SRS_CONSTS_RTMP_MIN_CHUNK_SIZE + if (get_global_chunk_size() < SRS_CONSTS_RTMP_MIN_CHUNK_SIZE || get_global_chunk_size() > SRS_CONSTS_RTMP_MAX_CHUNK_SIZE - ) { + ) { ret = ERROR_SYSTEM_CONFIG_INVALID; - srs_error("directive chunk_size invalid, chunk_size=%d, must in [%d, %d], ret=%d", - get_global_chunk_size(), SRS_CONSTS_RTMP_MIN_CHUNK_SIZE, - SRS_CONSTS_RTMP_MAX_CHUNK_SIZE, ret); + srs_error("directive chunk_size invalid, chunk_size=%d, must in [%d, %d], ret=%d", + get_global_chunk_size(), SRS_CONSTS_RTMP_MIN_CHUNK_SIZE, + SRS_CONSTS_RTMP_MAX_CHUNK_SIZE, ret); return ret; } for (int i = 0; i < (int)vhosts.size(); i++) { SrsConfDirective* vhost = vhosts[i]; - if (get_chunk_size(vhost->arg0()) < SRS_CONSTS_RTMP_MIN_CHUNK_SIZE + if (get_chunk_size(vhost->arg0()) < SRS_CONSTS_RTMP_MIN_CHUNK_SIZE || get_chunk_size(vhost->arg0()) > SRS_CONSTS_RTMP_MAX_CHUNK_SIZE - ) { + ) { ret = ERROR_SYSTEM_CONFIG_INVALID; - srs_error("directive vhost %s chunk_size invalid, chunk_size=%d, must in [%d, %d], ret=%d", - vhost->arg0().c_str(), get_chunk_size(vhost->arg0()), SRS_CONSTS_RTMP_MIN_CHUNK_SIZE, - SRS_CONSTS_RTMP_MAX_CHUNK_SIZE, ret); + srs_error("directive vhost %s chunk_size invalid, chunk_size=%d, must in [%d, %d], ret=%d", + vhost->arg0().c_str(), get_chunk_size(vhost->arg0()), SRS_CONSTS_RTMP_MIN_CHUNK_SIZE, + SRS_CONSTS_RTMP_MAX_CHUNK_SIZE, ret); return ret; } } @@ -4078,9 +4078,9 @@ int SrsConfig::check_config() for (int j = 0; j < (int)ingesters.size(); j++) { SrsConfDirective* ingest = ingesters[j]; if (get_ingest_enabled(ingest)) { - srs_warn("ingest %s of vhost %s is disabled by configure", - ingest->arg0().c_str(), vhost->arg0().c_str() - ); + srs_warn("ingest %s of vhost %s is disabled by configure", + ingest->arg0().c_str(), vhost->arg0().c_str() + ); } } #endif @@ -4121,7 +4121,7 @@ int SrsConfig::parse_buffer(SrsConfigBuffer* buffer) set_config_directive(root, "daemon", "off"); set_config_directive(root, "srs_log_tank", "console"); } - + return ret; } @@ -4222,7 +4222,7 @@ string SrsConfig::get_work_dir() { if( !conf || conf->arg0().empty()) { return DEFAULT; } - + return conf->arg0(); return conf->arg0(); @@ -4282,12 +4282,12 @@ string SrsConfig::get_stream_caster_engine(SrsConfDirective* conf) if (!conf) { return DEFAULT; } - + conf = conf->get("caster"); if (!conf || conf->arg0().empty()) { return DEFAULT; } - + return conf->arg0(); } @@ -4314,12 +4314,12 @@ int SrsConfig::get_stream_caster_listen(SrsConfDirective* conf) if (!conf) { return DEFAULT; } - + conf = conf->get("listen"); if (!conf || conf->arg0().empty()) { return DEFAULT; } - + return ::atoi(conf->arg0().c_str()); } @@ -4430,14 +4430,14 @@ SrsConfDirective* SrsConfig::get_vhost(string vhost, bool try_default_vhost) void SrsConfig::get_vhosts(vector& vhosts) { srs_assert(root); - + for (int i = 0; i < (int)root->directives.size(); i++) { SrsConfDirective* conf = root->at(i); - + if (!conf->is_vhost()) { continue; } - + vhosts.push_back(conf); } } @@ -4738,14 +4738,14 @@ int SrsConfig::get_chunk_size(string vhost) // use the global instead. return get_global_chunk_size(); } - + conf = conf->get("chunk_size"); if (!conf || conf->arg0().empty()) { // vhost does not specify the chunk size, // use the global instead. return get_global_chunk_size(); } - + return ::atoi(conf->arg0().c_str()); } @@ -4778,12 +4778,12 @@ bool SrsConfig::get_mr_enabled(string vhost) if (!conf) { return SRS_PERF_MR_ENABLED; } - + conf = conf->get("publish"); if (!conf) { return SRS_PERF_MR_ENABLED; } - + conf = conf->get("mr"); if (!conf || conf->arg0().empty()) { return SRS_PERF_MR_ENABLED; @@ -4798,17 +4798,17 @@ int SrsConfig::get_mr_sleep_ms(string vhost) if (!conf) { return SRS_PERF_MR_SLEEP; } - + conf = conf->get("publish"); if (!conf) { return SRS_PERF_MR_SLEEP; } - + conf = conf->get("mr_latency"); if (!conf || conf->arg0().empty()) { return SRS_PERF_MR_SLEEP; } - + return ::atoi(conf->arg0().c_str()); } @@ -4823,12 +4823,12 @@ int SrsConfig::get_mw_sleep_ms(string vhost) if (!conf) { return SRS_PERF_MW_SLEEP; } - + conf = conf->get("mw_latency"); if (!conf || conf->arg0().empty()) { return SRS_PERF_MW_SLEEP; } - + return ::atoi(conf->arg0().c_str()); } @@ -4838,12 +4838,12 @@ bool SrsConfig::get_realtime_enabled(string vhost) if (!conf) { return SRS_PERF_MIN_LATENCY_ENABLED; } - + conf = conf->get("min_latency"); if (!conf || conf->arg0().empty()) { return SRS_PERF_MIN_LATENCY_ENABLED; } - + return SRS_CONF_PERFER_FALSE(conf->arg0()); } @@ -5006,7 +5006,7 @@ SrsConfDirective* SrsConfig::get_forwards(string vhost) SrsConfDirective* SrsConfig::get_vhost_http_hooks(string vhost) { SrsConfDirective* conf = get_vhost(vhost); - if (!conf) { + if (!conf) { return NULL; } @@ -5016,9 +5016,9 @@ SrsConfDirective* SrsConfig::get_vhost_http_hooks(string vhost) bool SrsConfig::get_vhost_http_hooks_enabled(string vhost) { static bool DEFAULT = false; - + SrsConfDirective* conf = get_vhost_http_hooks(vhost); - if (!conf) { + if (!conf) { return DEFAULT; } @@ -5033,7 +5033,7 @@ bool SrsConfig::get_vhost_http_hooks_enabled(string vhost) SrsConfDirective* SrsConfig::get_vhost_on_connect(string vhost) { SrsConfDirective* conf = get_vhost_http_hooks(vhost); - if (!conf) { + if (!conf) { return NULL; } @@ -5043,7 +5043,7 @@ SrsConfDirective* SrsConfig::get_vhost_on_connect(string vhost) SrsConfDirective* SrsConfig::get_vhost_on_close(string vhost) { SrsConfDirective* conf = get_vhost_http_hooks(vhost); - if (!conf) { + if (!conf) { return NULL; } @@ -5053,7 +5053,7 @@ SrsConfDirective* SrsConfig::get_vhost_on_close(string vhost) SrsConfDirective* SrsConfig::get_vhost_on_publish(string vhost) { SrsConfDirective* conf = get_vhost_http_hooks(vhost); - if (!conf) { + if (!conf) { return NULL; } @@ -5063,7 +5063,7 @@ SrsConfDirective* SrsConfig::get_vhost_on_publish(string vhost) SrsConfDirective* SrsConfig::get_vhost_on_unpublish(string vhost) { SrsConfDirective* conf = get_vhost_http_hooks(vhost); - if (!conf) { + if (!conf) { return NULL; } @@ -5073,7 +5073,7 @@ SrsConfDirective* SrsConfig::get_vhost_on_unpublish(string vhost) SrsConfDirective* SrsConfig::get_vhost_on_play(string vhost) { SrsConfDirective* conf = get_vhost_http_hooks(vhost); - if (!conf) { + if (!conf) { return NULL; } @@ -5083,7 +5083,7 @@ SrsConfDirective* SrsConfig::get_vhost_on_play(string vhost) SrsConfDirective* SrsConfig::get_vhost_on_stop(string vhost) { SrsConfDirective* conf = get_vhost_http_hooks(vhost); - if (!conf) { + if (!conf) { return NULL; } @@ -5128,12 +5128,12 @@ bool SrsConfig::get_bw_check_enabled(string vhost) if (!conf) { return DEFAULT; } - + conf = conf->get("bandcheck"); if (!conf) { return DEFAULT; } - + conf = conf->get("enabled"); if (!conf || conf->arg0().empty()) { return DEFAULT; @@ -5150,7 +5150,7 @@ string SrsConfig::get_bw_check_key(string vhost) if (!conf) { return DEFAULT; } - + conf = conf->get("bandcheck"); if (!conf) { return DEFAULT; @@ -5160,7 +5160,7 @@ string SrsConfig::get_bw_check_key(string vhost) if (!conf || conf->arg0().empty()) { return DEFAULT; } - + return conf->arg0(); } @@ -5172,7 +5172,7 @@ int SrsConfig::get_bw_check_interval_ms(string vhost) if (!conf) { return DEFAULT; } - + conf = conf->get("bandcheck"); if (!conf) { return DEFAULT; @@ -5182,7 +5182,7 @@ int SrsConfig::get_bw_check_interval_ms(string vhost) if (!conf) { return DEFAULT; } - + return (int)(::atof(conf->arg0().c_str()) * 1000); } @@ -5194,7 +5194,7 @@ int SrsConfig::get_bw_check_limit_kbps(string vhost) if (!conf) { return DEFAULT; } - + conf = conf->get("bandcheck"); if (!conf) { return DEFAULT; @@ -5204,7 +5204,7 @@ int SrsConfig::get_bw_check_limit_kbps(string vhost) if (!conf) { return DEFAULT; } - + return ::atoi(conf->arg0().c_str()); } @@ -5227,12 +5227,12 @@ bool SrsConfig::get_vhost_is_edge(SrsConfDirective* vhost) if (!conf) { return DEFAULT; } - + conf = conf->get("mode"); if (!conf || conf->arg0().empty()) { return DEFAULT; } - + return "remote" == conf->arg0(); } @@ -5617,7 +5617,7 @@ string SrsConfig::get_engine_vpreset(SrsConfDirective* conf) vector SrsConfig::get_engine_vparams(SrsConfDirective* conf) { vector vparams; - + if (!conf) { return vparams; } @@ -5882,7 +5882,7 @@ string SrsConfig::get_ingest_input_type(SrsConfDirective* conf) if (!conf) { return DEFAULT; } - + conf = conf->get("type"); if (!conf || conf->arg0().empty()) { return DEFAULT; @@ -5903,7 +5903,7 @@ string SrsConfig::get_ingest_input_url(SrsConfDirective* conf) if (!conf) { return DEFAULT; } - + conf = conf->get("url"); if (!conf || conf->arg0().empty()) { return DEFAULT; @@ -6111,7 +6111,7 @@ string SrsConfig::get_hls_entry_prefix(string vhost) if (!conf) { return DEFAULT; } - + return conf->arg0(); } @@ -6196,7 +6196,7 @@ double SrsConfig::get_hls_fragment(string vhost) if (!conf || conf->arg0().empty()) { return DEFAULT; } - + return ::atof(conf->arg0().c_str()); } @@ -6265,7 +6265,7 @@ string SrsConfig::get_hls_on_error(string vhost) if (!conf || conf->arg0().empty()) { return DEFAULT; } - + return conf->arg0(); } @@ -6374,11 +6374,11 @@ bool SrsConfig::get_hls_wait_keyframe(string vhost) SrsConfDirective *SrsConfig::get_hds(const string &vhost) { SrsConfDirective* conf = get_vhost(vhost); - + if (!conf) { return NULL; } - + return conf->get("hds"); } @@ -6390,7 +6390,7 @@ bool SrsConfig::get_hds_enabled(const string &vhost) if (!conf) { return DEFAULT; } - + conf = conf->get("enabled"); if (!conf || conf->arg0().empty()) { return DEFAULT; @@ -6615,7 +6615,7 @@ string SrsConfig::get_http_api_listen() if (!conf || conf->arg0().empty()) { return DEFAULT; } - + return conf->arg0(); } diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 4b99ec447..a0bed5343 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_CONFIG_HPP #define SRS_APP_CONFIG_HPP -/* -#include -*/ #include #include @@ -128,28 +125,28 @@ extern int srs_config_transform_vhost(SrsConfDirective* root); 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: @@ -170,16 +167,16 @@ public: */ 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(); @@ -193,32 +190,32 @@ public: virtual SrsConfDirective* copy(); // @param except the name of sub directive. virtual SrsConfDirective* copy(std::string except); -// args + // 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 + // 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 can keep it before st-thread switch, or simply never keep it. + */ class SrsConfig { -// user command + // user command private: /** * whether srs is run in dolphin mode. @@ -310,54 +307,54 @@ private: 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. */ bool show_signature; -// global env variables. + // 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 + // dolphin public: /** * whether srs is in dolphin mode. @@ -365,52 +362,52 @@ public: 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 int reload(); private: /** - * reload the vhost section of config. - */ + * reload the vhost section of config. + */ virtual int 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 int reload_conf(SrsConfig* conf); private: /** - * reload the http_api section of config. - */ + * reload the http_api section of config. + */ virtual int 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 int reload_http_stream(SrsConfDirective* old_root); /** - * reload the transcode section of vhost of config. - */ + * reload the transcode section of vhost of config. + */ virtual int 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 int 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. @@ -531,82 +528,82 @@ public: virtual std::string config(); private: /** - * parse each argv. - */ + * parse each argv. + */ virtual int 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 int parse_file(const char* filename); /** - * check the parsed config. - */ + * check the parsed config. + */ virtual int check_config(); 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 int parse_buffer(_srs_internal::SrsConfigBuffer* buffer); -// global env + // 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 + // 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 ms, - * for example, all rtmp connections only print one message - * every this interval in ms. - */ + * get pithy print pulse ms, + * for example, all rtmp connections only print one message + * every this interval in ms. + */ virtual int get_pithy_print_ms(); /** * whether use utc-time to format the time. @@ -619,37 +616,37 @@ public: virtual std::string get_work_dir(); // whether use asprocess mode. virtual bool get_asprocess(); -// stream_caster section + // 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. + // kafka section. public: /** * whether the kafka enabled. @@ -663,7 +660,7 @@ public: * get the kafka topic to use for srs. */ virtual std::string get_kafka_topic(); -// vhost specified section + // vhost specified section public: /** * get the vhost directive by vhost name. @@ -676,52 +673,52 @@ public: */ 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 @@ -729,10 +726,10 @@ public: */ virtual bool get_mix_correct(std::string vhost); /** - * get the cache queue length, in seconds. - * when exceed the queue length, drop packet util I frame. - * @remark, default 10. - */ + * get the cache queue length, in seconds. + * when exceed the queue length, drop packet util I frame. + * @remark, default 10. + */ virtual double get_queue_length(std::string vhost); /** * whether the refer hotlink-denial enabled. @@ -758,37 +755,37 @@ public: // 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. */ 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 ms for vhost. - * @param vhost, the vhost to get the mr sleep time. - */ + * get the mr sleep time in ms for vhost. + * @param vhost, the vhost to get the mr sleep time. + */ // TODO: FIXME: add utest for mr config. virtual int get_mr_sleep_ms(std::string vhost); /** - * get the mw sleep time in ms for vhost. - * @param vhost, the vhost to get the mw sleep time. - */ + * get the mw sleep time in ms for vhost. + * @param vhost, the vhost to get the mw sleep time. + */ // TODO: FIXME: add utest for mw config. virtual int get_mw_sleep_ms(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); /** @@ -813,60 +810,60 @@ public: virtual int 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 + // forward section public: /** * 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 + // 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. @@ -883,194 +880,194 @@ public: * @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 + // 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 ms. - * 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 ms. + * 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 int get_bw_check_interval_ms(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 + // 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 */ virtual std::string get_vhost_edge_transform_vhost(std::string vhost); -// vhost security section + // 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 + // 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 */ 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 + // vhost exec secion private: /** * get the exec directive of vhost. @@ -1085,56 +1082,56 @@ public: * get all exec publish directives of vhost. */ virtual std::vector get_exec_publishs(std::string vhost); -// vhost ingest section + // 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 + // 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. + // The MPEG-DASH section. private: virtual SrsConfDirective* get_dash(std::string vhost); public: @@ -1150,20 +1147,20 @@ public: virtual std::string get_dash_path(std::string vhost); // Get the path for DASH MPD, to generate the MPD file. virtual std::string get_dash_mpd_file(std::string vhost); -// hls section + // 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. @@ -1182,37 +1179,37 @@ public: */ virtual bool get_hls_ts_floor(std::string vhost); /** - * get the hls fragment time, in seconds. - */ + * get the hls fragment time, in seconds. + */ virtual double 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. */ virtual double get_hls_aof_ratio(std::string vhost); /** - * get the hls window time, in seconds. - * 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 seconds. + * a window is a set of ts, the ts collection in m3u8. + * @remark SRS will delete the ts exceed the window. + */ virtual double 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. @@ -1231,41 +1228,41 @@ public: * 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 + // 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 seconds. - */ + * get the hds fragment time, in seconds. + */ virtual double get_hds_fragment(const std::string &vhost); /** - * get the hds window time, in seconds. - * a window is a set of hds fragments. - */ + * get the hds window time, in seconds. + * a window is a set of hds fragments. + */ virtual double get_hds_window(const std::string &vhost); - -// dvr section + + // 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. @@ -1273,43 +1270,43 @@ public: */ 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 int 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 + // 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. @@ -1327,25 +1324,25 @@ public: * whether allow rpc update. */ virtual bool get_raw_api_allow_update(); -// http stream section + // 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. @@ -1353,79 +1350,79 @@ public: 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 + // 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 double 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 + // 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 ms. - */ + * get the heartbeat interval, in ms. + */ virtual int64_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 + // 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.cpp b/trunk/src/app/srs_app_conn.cpp index 36982a33d..ba0a47b11 100644 --- a/trunk/src/app/srs_app_conn.cpp +++ b/trunk/src/app/srs_app_conn.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -47,12 +47,12 @@ SrsConnection::SrsConnection(IConnectionManager* cm, st_netfd_t c, string cip) disposed = false; expired = false; create_time = srs_get_system_time_ms(); - + skt = new SrsStSocket(); kbps = new SrsKbps(); kbps->set_io(skt, skt); - - // the client thread should reap itself, + + // the client thread should reap itself, // so we never use joinable. // TODO: FIXME: maybe other thread need to stop it. // @see: https://github.com/ossrs/srs/issues/78 @@ -62,7 +62,7 @@ SrsConnection::SrsConnection(IConnectionManager* cm, st_netfd_t c, string cip) SrsConnection::~SrsConnection() { dispose(); - + srs_freep(kbps); srs_freep(skt); srs_freep(pthread); @@ -137,7 +137,7 @@ int SrsConnection::cycle() if (ret == ERROR_SOCKET_CLOSED) { srs_warn("client disconnect peer. oret=%d, ret=%d", oret, ret); } - + return ERROR_SUCCESS; } diff --git a/trunk/src/app/srs_app_conn.hpp b/trunk/src/app/srs_app_conn.hpp index 1c19e3aea..26d27965d 100644 --- a/trunk/src/app/srs_app_conn.hpp +++ b/trunk/src/app/srs_app_conn.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_CONN_HPP #define SRS_APP_CONN_HPP -/* -#include -*/ - #include #include @@ -55,34 +51,34 @@ public: }; /** -* 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 ISrsOneCycleThreadHandler, virtual public IKbpsDelta, virtual public ISrsReloadHandler { private: /** - * 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. + */ SrsOneCycleThread* pthread; /** - * the id of connection. - */ + * the id of connection. + */ int id; protected: /** - * 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. + */ st_netfd_t stfd; /** - * the ip of client. - */ + * the ip of client. + */ std::string ip; /** * whether the connection is disposed, @@ -95,8 +91,8 @@ protected: */ bool expired; /** - * the underlayer socket. - */ + * the underlayer socket. + */ SrsStSocket* skt; /** * connection total kbps. @@ -125,33 +121,33 @@ public: */ 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 int start(); // 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 int cycle(); /** - * when the thread cycle finished, thread will invoke the on_thread_stop(), - * which will remove self from server, server will remove the connection from manager - * then delete the connection. - */ + * when the thread cycle finished, thread will invoke the on_thread_stop(), + * which will remove self from server, server will remove the connection from manager + * then delete the connection. + */ virtual void on_thread_stop(); 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. @@ -159,8 +155,8 @@ public: virtual void expire(); protected: /** - * for concrete connection to do the cycle. - */ + * for concrete connection to do the cycle. + */ virtual int do_cycle() = 0; }; diff --git a/trunk/src/app/srs_app_dash.cpp b/trunk/src/app/srs_app_dash.cpp index 2a5d24348..a32f87988 100644 --- a/trunk/src/app/srs_app_dash.cpp +++ b/trunk/src/app/srs_app_dash.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -399,19 +399,19 @@ int SrsMpdWriter::write(SrsFormat* format) stringstream ss; ss << "" << endl - << "" << endl - << " " << req->stream << "/" << "" << endl - << " " << endl; + << "" << endl + << " " << req->stream << "/" << "" << endl + << " " << endl; if (format->acodec) { ss << " " << endl; ss << " " << endl; + << "initialization=\"$RepresentationID$-init.mp4\" " + << "media=\"$RepresentationID$-$Number$.m4s\" />" << endl; ss << " " << endl; ss << " " << endl; } @@ -420,14 +420,14 @@ int SrsMpdWriter::write(SrsFormat* format) int h = format->vcodec->height; ss << " " << endl; ss << " " << endl; + << "initialization=\"$RepresentationID$-init.mp4\" " + << "media=\"$RepresentationID$-$Number$.m4s\" />" << endl; ss << " " << endl; + << "width=\"" << w << "\" height=\"" << h << "\"/>" << endl; ss << " " << endl; } ss << " " << endl - << "" << endl; + << "" << endl; SrsFileWriter* fw = new SrsFileWriter(); SrsAutoFree(SrsFileWriter, fw); @@ -566,7 +566,7 @@ int SrsDashController::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* fo } bool reopen = format->video->frame_type == SrsVideoAvcFrameTypeKeyFrame - && vcurrent->duration() >= fragment; + && vcurrent->duration() >= fragment; if (reopen) { if ((ret = vcurrent->reap()) != ERROR_SUCCESS) { return ret; diff --git a/trunk/src/app/srs_app_dash.hpp b/trunk/src/app/srs_app_dash.hpp index a77ed4c90..25a3f133e 100644 --- a/trunk/src/app/srs_app_dash.hpp +++ b/trunk/src/app/srs_app_dash.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_DASH_HPP #define SRS_APP_DASH_HPP -/* -#include -*/ #include #include diff --git a/trunk/src/app/srs_app_dvr.cpp b/trunk/src/app/srs_app_dvr.cpp index 04d4bcefc..1f24c7f6e 100644 --- a/trunk/src/app/srs_app_dvr.cpp +++ b/trunk/src/app/srs_app_dvr.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -52,14 +52,14 @@ SrsDvrSegmenter::SrsDvrSegmenter() fragment = new SrsFragment(); fs = new SrsFileWriter(); jitter_algorithm = SrsRtmpJitterAlgorithmOFF; - + _srs_config->subscribe(this); } SrsDvrSegmenter::~SrsDvrSegmenter() { _srs_config->unsubscribe(this); - + srs_freep(fragment); srs_freep(jitter); srs_freep(fs); @@ -74,7 +74,7 @@ int SrsDvrSegmenter::initialize(SrsDvrPlan* p, SrsRequest* r) jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_dvr_time_jitter(req->vhost); wait_keyframe = _srs_config->get_dvr_wait_keyframe(req->vhost); - + return ret; } @@ -91,7 +91,7 @@ int SrsDvrSegmenter::open() if (fs->is_open()) { return ret; } - + string path = generate_path(); if (srs_path_exists(path)) { ret = ERROR_DVR_CANNOT_APPEND; @@ -104,7 +104,7 @@ int SrsDvrSegmenter::open() if ((ret = fragment->create_dir()) != ERROR_SUCCESS) { return ret; } - + // create jitter. srs_freep(jitter); jitter = new SrsRtmpJitter(); @@ -115,7 +115,7 @@ int SrsDvrSegmenter::open() srs_error("open file stream for file %s failed. ret=%d", path.c_str(), ret); return ret; } - + // initialize the encoder. if ((ret = open_encoder()) != ERROR_SUCCESS) { srs_error("initialize enc by fs for file %s failed. ret=%d", path.c_str(), ret); @@ -123,7 +123,7 @@ int SrsDvrSegmenter::open() } srs_trace("dvr stream %s to file %s", req->stream.c_str(), path.c_str()); - + return ret; } @@ -184,7 +184,7 @@ int SrsDvrSegmenter::close() if (!fs->is_open()) { return ret; } - + // Close the encoder, then close the fs object. if ((ret = close_encoder()) != ERROR_SUCCESS) { return ret; @@ -196,14 +196,14 @@ int SrsDvrSegmenter::close() if ((ret = fragment->rename()) != ERROR_SUCCESS) { return ret; } - + // TODO: FIXME: the http callback is async, which will trigger thread switch, // so the on_video maybe invoked during the http callback, and error. if ((ret = plan->on_reap_segment()) != ERROR_SUCCESS) { srs_error("dvr: notify plan to reap segment failed. ret=%d", ret); return ret; } - + return ret; } @@ -218,7 +218,7 @@ int SrsDvrSegmenter::on_update_duration(SrsSharedPtrMessage* msg) string SrsDvrSegmenter::generate_path() { - // the path in config, for example, + // the path in config, for example, // /data/[vhost]/[app]/[stream]/[2006]/[01]/[02]/[15].[04].[05].[999].flv std::string path_config = _srs_config->get_dvr_path(req->vhost); @@ -231,7 +231,7 @@ string SrsDvrSegmenter::generate_path() std::string flv_path = path_config; flv_path = srs_path_build_stream(flv_path, req->vhost, req->app, req->stream); flv_path = srs_path_build_timestamp(flv_path); - + return flv_path; } @@ -336,7 +336,7 @@ int SrsDvrFlvSegmenter::open_encoder() if ((ret = enc->initialize(fs)) != ERROR_SUCCESS) { return ret; } - + // write the flv header to writer. if ((ret = enc->write_header()) != ERROR_SUCCESS) { srs_error("write flv header failed. ret=%d", ret); @@ -430,7 +430,7 @@ int SrsDvrFlvSegmenter::encode_video(SrsSharedPtrMessage* video) int size = video->size; bool sh = SrsFlvVideo::sh(payload, size); bool keyframe = SrsFlvVideo::h264(payload, size) - && SrsFlvVideo::keyframe(payload, size) && !sh; + && SrsFlvVideo::keyframe(payload, size) && !sh; if (keyframe) { has_keyframe = true; @@ -630,7 +630,7 @@ int SrsDvrAsyncCallOnDvr::call() return ret; } } - + return ret; } @@ -644,7 +644,7 @@ string SrsDvrAsyncCallOnDvr::to_string() SrsDvrPlan::SrsDvrPlan() { req = NULL; - + dvr_enabled = false; segment = NULL; async = new SrsAsyncCallWorker(); @@ -663,15 +663,15 @@ int SrsDvrPlan::initialize(SrsOriginHub* h, SrsDvrSegmenter* s, SrsRequest* r) hub = h; req = r; segment = s; - + if ((ret = segment->initialize(this, r)) != ERROR_SUCCESS) { return ret; } - + if ((ret = async->start()) != ERROR_SUCCESS) { return ret; } - + return ret; } @@ -693,7 +693,7 @@ int SrsDvrPlan::on_audio(SrsSharedPtrMessage* shared_audio) if (!dvr_enabled) { return ret; } - + if ((ret = segment->write_audio(shared_audio)) != ERROR_SUCCESS) { return ret; } @@ -708,7 +708,7 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* shared_video) if (!dvr_enabled) { return ret; } - + if ((ret = segment->write_video(shared_video)) != ERROR_SUCCESS) { return ret; } @@ -719,7 +719,7 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* shared_video) int SrsDvrPlan::on_reap_segment() { int ret = ERROR_SUCCESS; - + int cid = _srs_context->get_id(); SrsFragment* fragment = segment->current(); @@ -728,7 +728,7 @@ int SrsDvrPlan::on_reap_segment() if ((ret = async->execute(new SrsDvrAsyncCallOnDvr(cid, req, fullpath))) != ERROR_SUCCESS) { return ret; } - + return ret; } @@ -766,21 +766,21 @@ int SrsDvrSessionPlan::on_publish() if (dvr_enabled) { return ret; } - + if (!_srs_config->get_dvr_enabled(req->vhost)) { return ret; } - + if ((ret = segment->close()) != ERROR_SUCCESS) { return ret; } - + if ((ret = segment->open()) != ERROR_SUCCESS) { return ret; } - + dvr_enabled = true; - + return ret; } @@ -835,21 +835,21 @@ int SrsDvrSegmentPlan::on_publish() if (dvr_enabled) { return ret; } - + if (!_srs_config->get_dvr_enabled(req->vhost)) { return ret; } - + if ((ret = segment->close()) != ERROR_SUCCESS) { return ret; } - + if ((ret = segment->open()) != ERROR_SUCCESS) { return ret; } - + dvr_enabled = true; - + return ret; } @@ -860,7 +860,7 @@ void SrsDvrSegmentPlan::on_unpublish() int SrsDvrSegmentPlan::on_audio(SrsSharedPtrMessage* shared_audio) { int ret = ERROR_SUCCESS; - + if ((ret = update_duration(shared_audio)) != ERROR_SUCCESS) { return ret; } @@ -868,14 +868,14 @@ int SrsDvrSegmentPlan::on_audio(SrsSharedPtrMessage* shared_audio) if ((ret = SrsDvrPlan::on_audio(shared_audio)) != ERROR_SUCCESS) { return ret; } - + return ret; } int SrsDvrSegmentPlan::on_video(SrsSharedPtrMessage* shared_video) { int ret = ERROR_SUCCESS; - + if ((ret = update_duration(shared_video)) != ERROR_SUCCESS) { return ret; } @@ -883,7 +883,7 @@ int SrsDvrSegmentPlan::on_video(SrsSharedPtrMessage* shared_video) if ((ret = SrsDvrPlan::on_video(shared_video)) != ERROR_SUCCESS) { return ret; } - + return ret; } @@ -909,8 +909,8 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg) char* payload = msg->payload; int size = msg->size; bool is_key_frame = SrsFlvVideo::h264(payload, size) - && SrsFlvVideo::keyframe(payload, size) - && !SrsFlvVideo::sh(payload, size); + && SrsFlvVideo::keyframe(payload, size) + && !SrsFlvVideo::sh(payload, size); if (!is_key_frame) { return ret; } @@ -971,7 +971,7 @@ SrsDvr::~SrsDvr() int SrsDvr::initialize(SrsOriginHub* h, SrsRequest* r) { int ret = ERROR_SUCCESS; - + req = r; hub = h; @@ -1027,7 +1027,7 @@ int SrsDvr::on_meta_data(SrsSharedPtrMessage* metadata) if (!actived) { return ret; } - + if ((ret = plan->on_meta_data(metadata)) != ERROR_SUCCESS) { return ret; } diff --git a/trunk/src/app/srs_app_dvr.hpp b/trunk/src/app/srs_app_dvr.hpp index 211cf48c7..e14c94a53 100644 --- a/trunk/src/app/srs_app_dvr.hpp +++ b/trunk/src/app/srs_app_dvr.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_DVR_HPP #define SRS_APP_DVR_HPP -/* -#include -*/ #include #include @@ -166,8 +163,8 @@ protected: }; /** -* the dvr async call. -*/ + * the dvr async call. + */ class SrsDvrAsyncCallOnDvr : public ISrsAsyncCallTask { private: @@ -184,7 +181,7 @@ public: /** * The DVR plan, when and how to reap segment. -*/ + */ class SrsDvrPlan : public ISrsReloadHandler { public: @@ -204,7 +201,7 @@ public: virtual int on_meta_data(SrsSharedPtrMessage* shared_metadata); virtual int on_audio(SrsSharedPtrMessage* shared_audio); virtual int on_video(SrsSharedPtrMessage* shared_video); -// Internal interface for segmenter. + // Internal interface for segmenter. public: // When segmenter close a segment. virtual int on_reap_segment(); @@ -281,23 +278,23 @@ public: */ virtual int 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 int 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 int on_audio(SrsSharedPtrMessage* shared_audio); /** - * 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 int on_video(SrsSharedPtrMessage* shared_video); // interface ISrsReloadHandler public: diff --git a/trunk/src/app/srs_app_edge.cpp b/trunk/src/app/srs_app_edge.cpp index 1d82a2778..0a3045984 100644 --- a/trunk/src/app/srs_app_edge.cpp +++ b/trunk/src/app/srs_app_edge.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -176,7 +176,7 @@ SrsEdgeIngester::SrsEdgeIngester() } SrsEdgeIngester::~SrsEdgeIngester() -{ +{ stop(); srs_freep(upstream); @@ -198,12 +198,12 @@ int SrsEdgeIngester::initialize(SrsSource* s, SrsPlayEdge* e, SrsRequest* r) int SrsEdgeIngester::start() { int ret = ERROR_SUCCESS; - + if ((ret = source->on_publish()) != ERROR_SUCCESS) { srs_error("edge pull stream then publish to edge failed. ret=%d", ret); return ret; } - + return pthread->start(); } @@ -307,7 +307,7 @@ int SrsEdgeIngester::ingest() int SrsEdgeIngester::process_publish_message(SrsCommonMessage* msg) { int ret = ERROR_SUCCESS; - + // process audio packet if (msg->header.is_audio()) { if ((ret = source->on_audio(msg)) != ERROR_SUCCESS) { @@ -332,7 +332,7 @@ int SrsEdgeIngester::process_publish_message(SrsCommonMessage* msg) } return ret; } - + // process onMetaData if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) { SrsPacket* pkt = NULL; @@ -341,7 +341,7 @@ int SrsEdgeIngester::process_publish_message(SrsCommonMessage* msg) return ret; } SrsAutoFree(SrsPacket, pkt); - + if (dynamic_cast(pkt)) { SrsOnMetaDataPacket* metadata = dynamic_cast(pkt); if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) { @@ -500,13 +500,13 @@ int SrsEdgeForwarder::cycle() SrsAutoFree(SrsPithyPrint, pprint); SrsMessageArray msgs(SYS_MAX_EDGE_SEND_MSGS); - + while (!pthread->interrupted()) { if (send_error_code != ERROR_SUCCESS) { st_usleep(SRS_EDGE_FORWARDER_TMMS * 1000); continue; } - + // read from client. if (true) { SrsCommonMessage* msg = NULL; @@ -542,7 +542,7 @@ int SrsEdgeForwarder::cycle() srs_verbose("edge no packets to push."); continue; } - + // sendout messages, all messages are freed by send_and_free_messages(). if ((ret = sdk->send_and_free_messages(msgs.msgs, count)) != ERROR_SUCCESS) { srs_error("edge publish push message to server failed. ret=%d", ret); @@ -568,7 +568,7 @@ int SrsEdgeForwarder::proxy(SrsCommonMessage* msg) || msg->header.is_set_chunk_size() || msg->header.is_window_ackledgement_size() || msg->header.is_ackledgement() - ) { + ) { return ret; } @@ -618,7 +618,7 @@ int SrsPlayEdge::on_client_play() state = SrsEdgeStatePlay; return ingester->start(); } - + return ret; } @@ -628,7 +628,7 @@ void SrsPlayEdge::on_all_client_stop() // and edge is ingesting origin stream, abort it. if (state == SrsEdgeStatePlay || state == SrsEdgeStateIngestConnected) { ingester->stop(); - + SrsEdgeState pstate = state; state = SrsEdgeStateInit; srs_trace("edge change from %d to state %d (init).", pstate, state); @@ -679,7 +679,7 @@ void SrsPublishEdge::set_queue_size(double queue_size) int SrsPublishEdge::initialize(SrsSource* source, SrsRequest* req) { int ret = ERROR_SUCCESS; - + if ((ret = forwarder->initialize(source, this, req)) != ERROR_SUCCESS) { return ret; } @@ -700,7 +700,7 @@ int SrsPublishEdge::on_client_publish() if (state != SrsEdgeStateInit) { ret = ERROR_RTMP_EDGE_PUBLISH_STATE; srs_error("invalid state for client to publish stream on edge. " - "state=%d, ret=%d", state, ret); + "state=%d, ret=%d", state, ret); return ret; } diff --git a/trunk/src/app/srs_app_edge.hpp b/trunk/src/app/srs_app_edge.hpp index f81935923..f8c1679c1 100644 --- a/trunk/src/app/srs_app_edge.hpp +++ b/trunk/src/app/srs_app_edge.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_EDGE_HPP #define SRS_APP_EDGE_HPP -/* -#include -*/ - #include #include @@ -52,12 +48,12 @@ class SrsSimpleRtmpClient; class SrsPacket; /** -* the state of edge, auto machine -*/ + * the state of edge, auto machine + */ enum SrsEdgeState { SrsEdgeStateInit = 0, - + // for play edge SrsEdgeStatePlay = 100, // play stream from origin, ingest stream @@ -68,8 +64,8 @@ enum SrsEdgeState }; /** -* the state of edge from user, manual machine -*/ + * the state of edge from user, manual machine + */ enum SrsEdgeUserState { SrsEdgeUserStateInit = 0, @@ -116,8 +112,8 @@ public: }; /** -* edge used to ingest stream from origin. -*/ + * edge used to ingest stream from origin. + */ class SrsEdgeIngester : public ISrsReusableThread2Handler { private: @@ -146,8 +142,8 @@ private: }; /** -* edge used to forward stream to origin. -*/ + * edge used to forward stream to origin. + */ class SrsEdgeForwarder : public ISrsReusableThread2Handler { private: @@ -158,15 +154,15 @@ private: 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(); @@ -185,9 +181,9 @@ public: }; /** -* play edge control service. -* downloading edge speed-up. -*/ + * play edge control service. + * downloading edge speed-up. + */ class SrsPlayEdge { private: @@ -198,31 +194,31 @@ public: 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 int initialize(SrsSource* source, SrsRequest* req); /** - * when client play stream on edge. - */ + * when client play stream on edge. + */ virtual int 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 int on_ingest_play(); }; /** -* publish edge control service. -* uploading edge speed-up. -*/ + * publish edge control service. + * uploading edge speed-up. + */ class SrsPublishEdge { private: @@ -237,16 +233,16 @@ public: virtual int initialize(SrsSource* source, SrsRequest* req); virtual bool can_publish(); /** - * when client publish stream on edge. - */ + * when client publish stream on edge. + */ virtual int on_client_publish(); /** - * proxy publish stream to edge - */ + * proxy publish stream to edge + */ virtual int 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_empty.cpp b/trunk/src/app/srs_app_empty.cpp index e1c6d37cc..1cc4b9cdb 100644 --- a/trunk/src/app/srs_app_empty.cpp +++ b/trunk/src/app/srs_app_empty.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include diff --git a/trunk/src/app/srs_app_empty.hpp b/trunk/src/app/srs_app_empty.hpp index 8ffd199c3..e8b28a451 100644 --- a/trunk/src/app/srs_app_empty.hpp +++ b/trunk/src/app/srs_app_empty.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_EMPTY_HPP #define SRS_APP_EMPTY_HPP -/* -#include -*/ #include #endif diff --git a/trunk/src/app/srs_app_encoder.cpp b/trunk/src/app/srs_app_encoder.cpp index 1bfc28eb6..a2d1302fd 100644 --- a/trunk/src/app/srs_app_encoder.cpp +++ b/trunk/src/app/srs_app_encoder.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -59,7 +59,7 @@ SrsEncoder::~SrsEncoder() int SrsEncoder::on_publish(SrsRequest* req) { int ret = ERROR_SUCCESS; - + // parse the transcode engines for vhost and app and stream. ret = parse_scope_engines(req); @@ -104,14 +104,14 @@ int SrsEncoder::cycle() srs_error("transcode ffmpeg start failed. ret=%d", ret); return ret; } - + // check ffmpeg status. if ((ret = ffmpeg->cycle()) != ERROR_SUCCESS) { srs_error("transcode ffmpeg cycle failed. ret=%d", ret); return ret; } } - + // pithy print show_encode_log_message(); @@ -122,7 +122,7 @@ void SrsEncoder::on_thread_stop() { // kill ffmpeg when finished and it alive std::vector::iterator it; - + for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) { SrsFFMPEG* ffmpeg = *it; ffmpeg->stop(); @@ -135,7 +135,7 @@ void SrsEncoder::clear_engines() for (it = ffmpegs.begin(); it != ffmpegs.end(); ++it) { SrsFFMPEG* ffmpeg = *it; - + std::string output = ffmpeg->output(); std::vector::iterator tu_it; @@ -146,7 +146,7 @@ void SrsEncoder::clear_engines() srs_freep(ffmpeg); } - + ffmpegs.clear(); } @@ -168,7 +168,7 @@ int SrsEncoder::parse_scope_engines(SrsRequest* req) if ((ret = parse_ffmpeg(req, conf)) != ERROR_SUCCESS) { if (ret != ERROR_ENCODER_LOOP) { srs_error("parse vhost scope=%s transcode engines failed. " - "ret=%d", scope.c_str(), ret); + "ret=%d", scope.c_str(), ret); } return ret; } @@ -179,7 +179,7 @@ int SrsEncoder::parse_scope_engines(SrsRequest* req) if ((ret = parse_ffmpeg(req, conf)) != ERROR_SUCCESS) { if (ret != ERROR_ENCODER_LOOP) { srs_error("parse app scope=%s transcode engines failed. " - "ret=%d", scope.c_str(), ret); + "ret=%d", scope.c_str(), ret); } return ret; } @@ -191,7 +191,7 @@ int SrsEncoder::parse_scope_engines(SrsRequest* req) if ((ret = parse_ffmpeg(req, conf)) != ERROR_SUCCESS) { if (ret != ERROR_ENCODER_LOOP) { srs_error("parse stream scope=%s transcode engines failed. " - "ret=%d", scope.c_str(), ret); + "ret=%d", scope.c_str(), ret); } return ret; } @@ -215,16 +215,16 @@ int SrsEncoder::parse_ffmpeg(SrsRequest* req, SrsConfDirective* conf) // ffmpeg std::string ffmpeg_bin = _srs_config->get_transcode_ffmpeg(conf); if (ffmpeg_bin.empty()) { - srs_trace("ignore the empty ffmpeg transcode: %s", - conf->arg0().c_str()); + srs_trace("ignore the empty ffmpeg transcode: %s", + conf->arg0().c_str()); return ret; } // get all engines. std::vector engines = _srs_config->get_transcode_engines(conf); if (engines.empty()) { - srs_trace("ignore the empty transcode engine: %s", - conf->arg0().c_str()); + srs_trace("ignore the empty transcode engine: %s", + conf->arg0().c_str()); return ret; } @@ -232,8 +232,8 @@ int SrsEncoder::parse_ffmpeg(SrsRequest* req, SrsConfDirective* conf) for (int i = 0; i < (int)engines.size(); i++) { SrsConfDirective* engine = engines[i]; if (!_srs_config->get_engine_enabled(engine)) { - srs_trace("ignore the diabled transcode engine: %s %s", - conf->arg0().c_str(), engine->arg0().c_str()); + srs_trace("ignore the diabled transcode engine: %s %s", + conf->arg0().c_str(), engine->arg0().c_str()); continue; } @@ -245,7 +245,7 @@ int SrsEncoder::parse_ffmpeg(SrsRequest* req, SrsConfDirective* conf) } return ret; } - + ffmpegs.push_back(ffmpeg); } @@ -255,7 +255,7 @@ int SrsEncoder::parse_ffmpeg(SrsRequest* req, SrsConfDirective* conf) int SrsEncoder::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsRequest* req, SrsConfDirective* engine) { int ret = ERROR_SUCCESS; - + std::string input; // input stream, from local. // ie. rtmp://localhost:1935/live/livestream @@ -269,7 +269,7 @@ int SrsEncoder::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsRequest* req, SrsConfDir input += req->vhost; input += "/"; input += req->stream; - + // stream name: vhost/app/stream for print input_stream_name = req->vhost; input_stream_name += "/"; @@ -304,14 +304,14 @@ int SrsEncoder::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsRequest* req, SrsConfDir } log_file += ".log"; } - + // important: loop check, donot transcode again. std::vector::iterator it; it = std::find(_transcoded_url.begin(), _transcoded_url.end(), input); if (it != _transcoded_url.end()) { ret = ERROR_ENCODER_LOOP; srs_trace("detect a loop cycle, input=%s, output=%s, ignore it. ret=%d", - input.c_str(), output.c_str(), ret); + input.c_str(), output.c_str(), ret); return ret; } _transcoded_url.push_back(output); @@ -329,12 +329,12 @@ int SrsEncoder::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsRequest* req, SrsConfDir void SrsEncoder::show_encode_log_message() { pprint->elapse(); - + // reportable if (pprint->can_print()) { // TODO: FIXME: show more info. - srs_trace("-> "SRS_CONSTS_LOG_ENCODER" time=%"PRId64", encoders=%d, input=%s", - pprint->age(), (int)ffmpegs.size(), input_stream_name.c_str()); + srs_trace("-> "SRS_CONSTS_LOG_ENCODER" time=%"PRId64", encoders=%d, input=%s", + pprint->age(), (int)ffmpegs.size(), input_stream_name.c_str()); } } diff --git a/trunk/src/app/srs_app_encoder.hpp b/trunk/src/app/srs_app_encoder.hpp index 78912c334..3bf047ffe 100644 --- a/trunk/src/app/srs_app_encoder.hpp +++ b/trunk/src/app/srs_app_encoder.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_ENCODER_HPP #define SRS_APP_ENCODER_HPP -/* -#include -*/ #include #ifdef SRS_AUTO_TRANSCODE @@ -42,9 +39,9 @@ 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 ISrsReusableThreadHandler { private: diff --git a/trunk/src/app/srs_app_ffmpeg.cpp b/trunk/src/app/srs_app_ffmpeg.cpp index eb0acad94..eee179bad 100644 --- a/trunk/src/app/srs_app_ffmpeg.cpp +++ b/trunk/src/app/srs_app_ffmpeg.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -145,7 +145,7 @@ int SrsFFMPEG::initialize_transcode(SrsConfDirective* engine) if (vcodec != SRS_RTMP_ENCODER_VCODEC_LIBX264) { ret = ERROR_ENCODER_VCODEC; srs_error("invalid vcodec, must be %s, actual %s, ret=%d", - SRS_RTMP_ENCODER_VCODEC_LIBX264, vcodec.c_str(), ret); + SRS_RTMP_ENCODER_VCODEC_LIBX264, vcodec.c_str(), ret); return ret; } if (vbitrate < 0) { @@ -233,7 +233,7 @@ int SrsFFMPEG::initialize_copy() vcodec = SRS_RTMP_ENCODER_COPY; acodec = SRS_RTMP_ENCODER_COPY; - + if (_output.empty()) { ret = ERROR_ENCODER_OUTPUT; srs_error("invalid empty output, ret=%d", ret); diff --git a/trunk/src/app/srs_app_ffmpeg.hpp b/trunk/src/app/srs_app_ffmpeg.hpp index b6163d815..fe008fc89 100644 --- a/trunk/src/app/srs_app_ffmpeg.hpp +++ b/trunk/src/app/srs_app_ffmpeg.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_FFMPEG_HPP #define SRS_APP_FFMPEG_HPP -/* -#include -*/ #include #ifdef SRS_AUTO_FFMPEG_STUB @@ -39,9 +36,9 @@ 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.cpp b/trunk/src/app/srs_app_forward.cpp index 1d588f2cf..129932226 100755 --- a/trunk/src/app/srs_app_forward.cpp +++ b/trunk/src/app/srs_app_forward.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -56,7 +56,7 @@ SrsForwarder::SrsForwarder(SrsOriginHub* h) req = NULL; sh_video = sh_audio = NULL; - + sdk = NULL; pthread = new SrsReusableThread2("forward", this, SRS_FORWARDER_CIMS); queue = new SrsMessageQueue(); @@ -130,13 +130,13 @@ int SrsForwarder::on_publish() if (source_ep == dest_ep) { ret = ERROR_SYSTEM_FORWARD_LOOP; - srs_warn("forward loop detected. src=%s, dest=%s, ret=%d", - source_ep.c_str(), dest_ep.c_str(), ret); + srs_warn("forward loop detected. src=%s, dest=%s, ret=%d", + source_ep.c_str(), dest_ep.c_str(), ret); return ret; } - srs_trace("start forward %s to %s, tcUrl=%s, stream=%s", - source_ep.c_str(), dest_ep.c_str(), tcUrl.c_str(), - req->stream.c_str()); + srs_trace("start forward %s to %s, tcUrl=%s, stream=%s", + source_ep.c_str(), dest_ep.c_str(), tcUrl.c_str(), + req->stream.c_str()); if ((ret = pthread->start()) != ERROR_SUCCESS) { srs_error("start srs thread failed. ret=%d", ret); @@ -156,7 +156,7 @@ void SrsForwarder::on_unpublish() int SrsForwarder::on_meta_data(SrsSharedPtrMessage* shared_metadata) { int ret = ERROR_SUCCESS; - + SrsSharedPtrMessage* metadata = shared_metadata->copy(); // TODO: FIXME: config the jitter of Forwarder. @@ -199,7 +199,7 @@ int SrsForwarder::on_audio(SrsSharedPtrMessage* shared_audio) int SrsForwarder::on_video(SrsSharedPtrMessage* shared_video) { int ret = ERROR_SUCCESS; - + SrsSharedPtrMessage* msg = shared_video->copy(); // TODO: FIXME: config the jitter of Forwarder. @@ -271,7 +271,7 @@ int SrsForwarder::forward() SrsPithyPrint* pprint = SrsPithyPrint::create_forwarder(); SrsAutoFree(SrsPithyPrint, pprint); - + SrsMessageArray msgs(SYS_MAX_FORWARD_SEND_MSGS); // update sequence header @@ -291,7 +291,7 @@ int SrsForwarder::forward() while (!pthread->interrupted()) { pprint->elapse(); - + // read from client. if (true) { SrsCommonMessage* msg = NULL; @@ -324,7 +324,7 @@ int SrsForwarder::forward() srs_verbose("no packets to forward."); continue; } - + // sendout messages, all messages are freed by send_and_free_messages(). if ((ret = sdk->send_and_free_messages(msgs.msgs, count)) != ERROR_SUCCESS) { srs_error("forwarder messages to server failed. ret=%d", ret); diff --git a/trunk/src/app/srs_app_forward.hpp b/trunk/src/app/srs_app_forward.hpp index d905fd759..e57423559 100644 --- a/trunk/src/app/srs_app_forward.hpp +++ b/trunk/src/app/srs_app_forward.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_FORWARD_HPP #define SRS_APP_FORWARD_HPP -/* -#include -*/ #include #include @@ -47,8 +44,8 @@ class SrsKbps; class SrsSimpleRtmpClient; /** -* forward the stream to other servers. -*/ + * forward the stream to other servers. + */ // TODO: FIXME: refine the error log, comments it. class SrsForwarder : public ISrsReusableThread2Handler { @@ -64,9 +61,9 @@ private: 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: @@ -79,19 +76,19 @@ public: virtual int 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 int 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 int 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 int on_video(SrsSharedPtrMessage* shared_video); // interface ISrsReusableThread2Handler. public: diff --git a/trunk/src/app/srs_app_fragment.cpp b/trunk/src/app/srs_app_fragment.cpp index 833033be8..744080a78 100644 --- a/trunk/src/app/srs_app_fragment.cpp +++ b/trunk/src/app/srs_app_fragment.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include diff --git a/trunk/src/app/srs_app_fragment.hpp b/trunk/src/app/srs_app_fragment.hpp index b80392020..c4fa2ae2a 100644 --- a/trunk/src/app/srs_app_fragment.hpp +++ b/trunk/src/app/srs_app_fragment.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_FRAGMENT_HPP #define SRS_APP_FRAGMENT_HPP -/* -#include -*/ #include #include diff --git a/trunk/src/app/srs_app_hds.cpp b/trunk/src/app/srs_app_hds.cpp index fcb6390ab..6479015b9 100644 --- a/trunk/src/app/srs_app_hds.cpp +++ b/trunk/src/app/srs_app_hds.cpp @@ -1,25 +1,26 @@ -/* -The MIT License (MIT) +/** + * The MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 (c) 2013-2017 SRS(ossrs) - -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. -*/ #include #ifdef SRS_AUTO_HDS @@ -52,37 +53,37 @@ static void update_box(char *start, int size) } char flv_header[] = {'F', 'L', 'V', - 0x01, 0x05, 0x00, 0x00, 0x00, 0x09, - 0x00, 0x00, 0x00, 0x00}; + 0x01, 0x05, 0x00, 0x00, 0x00, 0x09, + 0x00, 0x00, 0x00, 0x00}; string serialFlv(SrsSharedPtrMessage *msg) { - SrsBuffer *stream = new SrsBuffer; - - int size = 15 + msg->size; - char *byte = new char[size]; - stream->initialize(byte, size); - + SrsBuffer *stream = new SrsBuffer; + + int size = 15 + msg->size; + char *byte = new char[size]; + stream->initialize(byte, size); + // tag header long long dts = msg->timestamp; char type = msg->is_video() ? 0x09 : 0x08; - + stream->write_1bytes(type); stream->write_3bytes(msg->size); stream->write_3bytes(dts); stream->write_1bytes(dts >> 24 & 0xFF); stream->write_3bytes(0); stream->write_bytes(msg->payload, msg->size); - + // pre tag size int preTagSize = msg->size + 11; stream->write_4bytes(preTagSize); - + string ret(stream->data(), stream->size()); - + delete stream; delete [] byte; - + return ret; } @@ -90,20 +91,20 @@ class SrsHdsFragment { public: SrsHdsFragment(SrsRequest *r) - : req(r) - , index(-1) - , start_time(0) - , videoSh(NULL) - , audioSh(NULL) + : req(r) + , index(-1) + , start_time(0) + , videoSh(NULL) + , audioSh(NULL) { - + } - + ~SrsHdsFragment() { srs_freep(videoSh); srs_freep(audioSh); - + // clean msgs list::iterator iter; for (iter = msgs.begin(); iter != msgs.end(); ++iter) { @@ -111,22 +112,22 @@ public: srs_freep(msg); } } - + void on_video(SrsSharedPtrMessage *msg) { SrsSharedPtrMessage *_msg = msg->copy(); msgs.push_back(_msg); } - + void on_audio(SrsSharedPtrMessage *msg) { SrsSharedPtrMessage *_msg = msg->copy(); msgs.push_back(_msg); } - + /*! - flush data to disk. - */ + flush data to disk. + */ int flush() { string data; @@ -134,141 +135,141 @@ public: videoSh->timestamp = start_time; data.append(serialFlv(videoSh)); } - + if (audioSh) { audioSh->timestamp = start_time; data.append(serialFlv(audioSh)); } - + list::iterator iter; for (iter = msgs.begin(); iter != msgs.end(); ++iter) { SrsSharedPtrMessage *msg = *iter; data.append(serialFlv(msg)); } - + char box_header[8]; SrsBuffer ss; ss.initialize(box_header, 8); ss.write_4bytes(8 + data.size()); ss.write_string("mdat"); - + data = string(ss.data(), ss.size()) + data; - + const char *file_path = path.c_str(); int fd = open(file_path, O_WRONLY | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH); if (fd < 0) { srs_error("open fragment file failed, path=%s", file_path); return -1; } - + if (write(fd, data.data(), data.size()) != (int)data.size()) { srs_error("write fragment file failed, path=", file_path); close(fd); return -1; } close(fd); - + srs_trace("build fragment success=%s", file_path); - + return ERROR_SUCCESS; } - + /*! - calc the segment duration in milliseconds. - @return 0 if no msgs - or the last msg dts minus the first msg dts. - */ + calc the segment duration in milliseconds. + @return 0 if no msgs + or the last msg dts minus the first msg dts. + */ int duration() { int duration_ms = 0; long long first_msg_ts = 0; long long last_msg_ts = 0; - + if (msgs.size() >= 2) { SrsSharedPtrMessage *first_msg = msgs.front(); first_msg_ts = first_msg->timestamp; - + SrsSharedPtrMessage *last_msg = msgs.back(); last_msg_ts = last_msg->timestamp; - + duration_ms = last_msg_ts - first_msg_ts; } - + return duration_ms; } - + /*! - set/get index - */ + set/get index + */ inline void set_index(int idx) { char file_path[1024] = {0}; sprintf(file_path, "%s/%s/%sSeg1-Frag%d", _srs_config->get_hds_path(req->vhost).c_str() , req->app.c_str(), req->stream.c_str(), idx); - + path = file_path; index = idx; } - + inline int get_index() { return index; } - + /*! - set/get start time - */ + set/get start time + */ inline void set_start_time(long long st) { start_time = st; } - + inline long long get_start_time() { return start_time; } - + void set_video_sh(SrsSharedPtrMessage *msg) { srs_freep(videoSh); videoSh = msg->copy(); } - + void set_audio_sh(SrsSharedPtrMessage *msg) { srs_freep(audioSh); audioSh = msg->copy(); } - + string fragment_path() { return path; } - + private: SrsRequest *req; list msgs; - + /*! - the index of this fragment - */ + the index of this fragment + */ int index; long long start_time; - + SrsSharedPtrMessage *videoSh; SrsSharedPtrMessage *audioSh; string path; }; SrsHds::SrsHds() - : currentSegment(NULL) - , fragment_index(1) - , video_sh(NULL) - , audio_sh(NULL) - , hds_req(NULL) - , hds_enabled(false) +: currentSegment(NULL) +, fragment_index(1) +, video_sh(NULL) +, audio_sh(NULL) +, hds_req(NULL) +, hds_enabled(false) { - + } SrsHds::~SrsHds() @@ -281,33 +282,33 @@ int SrsHds::on_publish(SrsRequest *req) if (hds_enabled) { return ret; } - + std::string vhost = req->vhost; if (!_srs_config->get_hds_enabled(vhost)) { hds_enabled = false; return ret; } hds_enabled = true; - + hds_req = req->copy(); - + return flush_mainfest(); } int SrsHds::on_unpublish() { int ret = ERROR_SUCCESS; - + if (!hds_enabled) { return ret; } - + hds_enabled = false; - + srs_freep(video_sh); srs_freep(audio_sh); srs_freep(hds_req); - + // clean fragments list::iterator iter; for (iter = fragments.begin(); iter != fragments.end(); ++iter) { @@ -315,41 +316,41 @@ int SrsHds::on_unpublish() srs_freep(st); } fragments.clear(); - + srs_freep(currentSegment); - + srs_trace("HDS un-published"); - + return ret; } int SrsHds::on_video(SrsSharedPtrMessage* msg) { int ret = ERROR_SUCCESS; - + if (!hds_enabled) { return ret; } - + if (SrsFlvVideo::sh(msg->payload, msg->size)) { srs_freep(video_sh); video_sh = msg->copy(); } - + if (!currentSegment) { currentSegment = new SrsHdsFragment(hds_req); currentSegment->set_index(fragment_index++); currentSegment->set_start_time(msg->timestamp); - + if (video_sh) currentSegment->set_video_sh(video_sh); - + if (audio_sh) currentSegment->set_audio_sh(audio_sh); } - + currentSegment->on_video(msg); - + double fragment_duration = _srs_config->get_hds_fragment(hds_req->vhost) * 1000; if (currentSegment->duration() >= fragment_duration) { // flush segment @@ -357,51 +358,51 @@ int SrsHds::on_video(SrsSharedPtrMessage* msg) srs_error("flush segment failed."); return ret; } - + srs_trace("flush Segment success."); fragments.push_back(currentSegment); currentSegment = NULL; adjust_windows(); - + // flush bootstrap if ((ret = flush_bootstrap()) != ERROR_SUCCESS) { srs_error("flush bootstrap failed."); return ret; } - + srs_trace("flush BootStrap success."); } - + return ret; } int SrsHds::on_audio(SrsSharedPtrMessage* msg) { int ret = ERROR_SUCCESS; - + if (!hds_enabled) { return ret; } - + if (SrsFlvAudio::sh(msg->payload, msg->size)) { srs_freep(audio_sh); audio_sh = msg->copy(); } - + if (!currentSegment) { currentSegment = new SrsHdsFragment(hds_req); currentSegment->set_index(fragment_index++); currentSegment->set_start_time(msg->timestamp); - + if (video_sh) currentSegment->set_video_sh(video_sh); - + if (audio_sh) currentSegment->set_audio_sh(audio_sh); } - + currentSegment->on_audio(msg); - + double fragment_duration = _srs_config->get_hds_fragment(hds_req->vhost) * 1000; if (currentSegment->duration() >= fragment_duration) { // flush segment @@ -409,30 +410,30 @@ int SrsHds::on_audio(SrsSharedPtrMessage* msg) srs_error("flush segment failed."); return ret; } - + srs_info("flush Segment success."); - + // reset the current segment fragments.push_back(currentSegment); currentSegment = NULL; adjust_windows(); - + // flush bootstrap if ((ret = flush_bootstrap()) != ERROR_SUCCESS) { srs_error("flush bootstrap failed."); return ret; } - + srs_info("flush BootStrap success."); } - + return ret; } int SrsHds::flush_mainfest() { int ret = ERROR_SUCCESS; - + char buf[1024] = {0}; sprintf(buf, "\n" "\n\t" @@ -443,21 +444,21 @@ int SrsHds::flush_mainfest() "\n" "" , hds_req->stream.c_str(), hds_req->stream.c_str(), hds_req->stream.c_str()); - + string dir = _srs_config->get_hds_path(hds_req->vhost) + "/" + hds_req->app; if ((ret = srs_create_dir_recursively(dir)) != ERROR_SUCCESS) { srs_error("hds create dir failed. ret=%d", ret); return ret; } string path = dir + "/" + hds_req->stream + ".f4m"; - + int fd = open(path.c_str(), O_WRONLY | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH); if (fd < 0) { srs_error("open manifest file failed, path=%s", path.c_str()); ret = ERROR_HDS_OPEN_F4M_FAILED; return ret; } - + int f4m_size = strlen(buf); if (write(fd, buf, f4m_size) != f4m_size) { srs_error("write manifest file failed, path=", path.c_str()); @@ -466,33 +467,33 @@ int SrsHds::flush_mainfest() return ret; } close(fd); - + srs_trace("build manifest success=%s", path.c_str()); - + return ERROR_SUCCESS; } int SrsHds::flush_bootstrap() { int ret = ERROR_SUCCESS; - + SrsBuffer abst; - + int size = 1024*100; - + char *start_abst = new char[1024*100]; SrsAutoFreeA(char, start_abst); - + int size_abst = 0; char *start_asrt = NULL; int size_asrt = 0; char *start_afrt = NULL; int size_afrt = 0; - + if ((ret = abst.initialize(start_abst, size)) != ERROR_SUCCESS) { return ret; } - + // @see video_file_format_spec_v10_1 // page: 46 abst.write_4bytes(0); @@ -501,198 +502,198 @@ int SrsHds::flush_bootstrap() abst.write_3bytes(0x00); // Flags always 0 size_abst += 12; /*! - @BootstrapinfoVersion UI32 - The version number of the bootstrap information. - When the Update field is set, BootstrapinfoVersion - indicates the version number that is being updated. - we assume this is the last. - */ + @BootstrapinfoVersion UI32 + The version number of the bootstrap information. + When the Update field is set, BootstrapinfoVersion + indicates the version number that is being updated. + we assume this is the last. + */ abst.write_4bytes(fragment_index - 1); // BootstrapinfoVersion - + abst.write_1bytes(0x20); // profile, live, update abst.write_4bytes(1000); // TimeScale Typically, the value is 1000, for a unit of milliseconds size_abst += 9; /*! - The timestamp in TimeScale units of the latest available Fragment in the media presentation. - This timestamp is used to request the right fragment number. - The CurrentMedia Time can be the total duration. - For media presentations that are not live, CurrentMediaTime can be 0. - */ + The timestamp in TimeScale units of the latest available Fragment in the media presentation. + This timestamp is used to request the right fragment number. + The CurrentMedia Time can be the total duration. + For media presentations that are not live, CurrentMediaTime can be 0. + */ SrsHdsFragment *st = fragments.back(); abst.write_8bytes(st->get_start_time()); - + // SmpteTimeCodeOffset abst.write_8bytes(0); size_abst += 16; - + /*! - @MovieIdentifier STRING - The identifier of this presentation. - we write null string. - */ + @MovieIdentifier STRING + The identifier of this presentation. + we write null string. + */ abst.write_1bytes(0); size_abst += 1; /*! - @ServerEntryCount UI8 - The number of ServerEntryTable entries. - The minimum value is 0. - */ + @ServerEntryCount UI8 + The number of ServerEntryTable entries. + The minimum value is 0. + */ abst.write_1bytes(0); size_abst += 1; /*! - @ServerEntryTable - because we write 0 of ServerEntryCount, so this feild is ignored. - */ - + @ServerEntryTable + because we write 0 of ServerEntryCount, so this feild is ignored. + */ + /*! - @QualityEntryCount UI8 - The number of QualityEntryTable entries, which is - also the number of available quality levels. The - minimum value is 0. Available quality levels are for, - for example, multi bit rate files or trick files. - */ + @QualityEntryCount UI8 + The number of QualityEntryTable entries, which is + also the number of available quality levels. The + minimum value is 0. Available quality levels are for, + for example, multi bit rate files or trick files. + */ abst.write_1bytes(0); size_abst += 1; /*! - @QualityEntryTable - because we write 0 of QualityEntryCount, so this feild is ignored. - */ - + @QualityEntryTable + because we write 0 of QualityEntryCount, so this feild is ignored. + */ + /*! - @DrmData STRING - Null or null-terminated UTF-8 string. This string - holds Digital Rights Management metadata. - Encrypted files use this metadata to get the - necessary keys and licenses for decryption and play back. - we write null string. - */ + @DrmData STRING + Null or null-terminated UTF-8 string. This string + holds Digital Rights Management metadata. + Encrypted files use this metadata to get the + necessary keys and licenses for decryption and play back. + we write null string. + */ abst.write_1bytes(0); size_abst += 1; /*! - @MetaData STRING - Null or null-terminated UTF - 8 string that holds metadata. - we write null string. - */ + @MetaData STRING + Null or null-terminated UTF - 8 string that holds metadata. + we write null string. + */ abst.write_1bytes(0); size_abst += 1; /*! - @SegmentRunTableCount UI8 - The number of entries in SegmentRunTableEntries. - The minimum value is 1. Typically, one table - contains all segment runs. However, this count - provides the flexibility to define the segment runs - individually for each quality level (or trick file). - */ + @SegmentRunTableCount UI8 + The number of entries in SegmentRunTableEntries. + The minimum value is 1. Typically, one table + contains all segment runs. However, this count + provides the flexibility to define the segment runs + individually for each quality level (or trick file). + */ abst.write_1bytes(1); size_abst += 1; - + start_asrt = start_abst + size_abst; - + // follows by asrt abst.write_4bytes(0); abst.write_string("asrt"); size_asrt += 8; /*! - @Version UI8 - @Flags UI24 - */ + @Version UI8 + @Flags UI24 + */ abst.write_4bytes(0); size_asrt += 4; /*! - @QualityEntryCount UI8 - The number of QualitySegmen tUrlModifiers - (quality level references) that follow. If 0, this - Segment Run Table applies to all quality levels, - and there shall be only one Segment Run Table - box in the Bootstrap Info box. - */ + @QualityEntryCount UI8 + The number of QualitySegmen tUrlModifiers + (quality level references) that follow. If 0, this + Segment Run Table applies to all quality levels, + and there shall be only one Segment Run Table + box in the Bootstrap Info box. + */ abst.write_1bytes(0); size_asrt += 1; - + /*! - @QualitySegmentUrlModifiers - ignored. - */ - + @QualitySegmentUrlModifiers + ignored. + */ + /*! - @SegmentRunEntryCount - The number of items in this - SegmentRunEn tryTable. The minimum value is 1. - */ + @SegmentRunEntryCount + The number of items in this + SegmentRunEn tryTable. The minimum value is 1. + */ abst.write_4bytes(1); size_asrt += 4; /*! - @SegmentRunEntryTable - */ + @SegmentRunEntryTable + */ for (int i = 0; i < 1; ++i) { /*! - @FirstSegment UI32 - The identifying number of the first segment in the run of - segments containing the same number of fragments. - The segment corresponding to the FirstSegment in the next - SEGMENTRUNENTRY will terminate this run. - */ + @FirstSegment UI32 + The identifying number of the first segment in the run of + segments containing the same number of fragments. + The segment corresponding to the FirstSegment in the next + SEGMENTRUNENTRY will terminate this run. + */ abst.write_4bytes(1); - + /*! - @FragmentsPerSegment UI32 - The number of fragments in each segment in this run. - */ + @FragmentsPerSegment UI32 + The number of fragments in each segment in this run. + */ abst.write_4bytes(fragment_index - 1); size_asrt += 8; } - + update_box(start_asrt, size_asrt); size_abst += size_asrt; - + /*! - @FragmentRunTableCount UI8 - The number of entries in FragmentRunTable-Entries. - The min i mum value is 1. - */ + @FragmentRunTableCount UI8 + The number of entries in FragmentRunTable-Entries. + The min i mum value is 1. + */ abst.write_1bytes(1); size_abst += 1; - + // follows by afrt start_afrt = start_abst + size_abst; - + abst.write_4bytes(0); abst.write_string("afrt"); size_afrt += 8; - + /*! - @Version UI8 - @Flags UI24 - */ + @Version UI8 + @Flags UI24 + */ abst.write_4bytes(0); size_afrt += 4; /*! - @TimeScale UI32 - The number of time units per second, used in the FirstFragmentTime stamp and - Fragment Duration fields. - Typically, the value is 1000. - */ + @TimeScale UI32 + The number of time units per second, used in the FirstFragmentTime stamp and + Fragment Duration fields. + Typically, the value is 1000. + */ abst.write_4bytes(1000); size_afrt += 4; /*! - @QualityEntryCount UI8 - The number of QualitySegment Url Modifiers - (quality level references) that follow. - If 0, this Fragment Run Table applies to all quality levels, - and there shall be only one Fragment Run Table - box in the Bootstrap Info box. - */ + @QualityEntryCount UI8 + The number of QualitySegment Url Modifiers + (quality level references) that follow. + If 0, this Fragment Run Table applies to all quality levels, + and there shall be only one Fragment Run Table + box in the Bootstrap Info box. + */ abst.write_1bytes(0); size_afrt += 1; - + /*! - @FragmentRunEntryCount UI32 - The number of items in this FragmentRunEntryTable. - The minimum value is 1. - */ + @FragmentRunEntryCount UI32 + The number of items in this FragmentRunEntryTable. + The minimum value is 1. + */ abst.write_4bytes(fragments.size()); size_afrt += 4; - + list::iterator iter; for (iter = fragments.begin(); iter != fragments.end(); ++iter) { SrsHdsFragment *st = *iter; @@ -701,20 +702,20 @@ int SrsHds::flush_bootstrap() abst.write_4bytes(st->duration()); size_afrt += 16; } - + update_box(start_afrt, size_afrt); size_abst += size_afrt; update_box(start_abst, size_abst); - + string path = _srs_config->get_hds_path(hds_req->vhost) + "/" + hds_req->app + "/" + hds_req->stream +".abst"; - + int fd = open(path.c_str(), O_WRONLY | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH); if (fd < 0) { srs_error("open bootstrap file failed, path=%s", path.c_str()); ret = ERROR_HDS_OPEN_BOOTSTRAP_FAILED; return ret; } - + if (write(fd, start_abst, size_abst) != size_abst) { srs_error("write bootstrap file failed, path=", path.c_str()); close(fd); @@ -722,9 +723,9 @@ int SrsHds::flush_bootstrap() return ret; } close(fd); - + srs_trace("build bootstrap success=%s", path.c_str()); - + return ERROR_SUCCESS; } @@ -736,7 +737,7 @@ void SrsHds::adjust_windows() SrsHdsFragment *fragment = *iter; windows_size += fragment->duration(); } - + double windows_size_limit = _srs_config->get_hds_window(hds_req->vhost) * 1000; if (windows_size > windows_size_limit ) { SrsHdsFragment *fragment = fragments.front(); diff --git a/trunk/src/app/srs_app_hds.hpp b/trunk/src/app/srs_app_hds.hpp index d41fa5c86..be01dc0d9 100644 --- a/trunk/src/app/srs_app_hds.hpp +++ b/trunk/src/app/srs_app_hds.hpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_HDS_HPP #define SRS_APP_HDS_HPP @@ -40,25 +40,25 @@ class SrsHds public: SrsHds(); virtual ~SrsHds(); - + int on_publish(SrsRequest* req); int on_unpublish(); - + int on_video(SrsSharedPtrMessage* msg); int on_audio(SrsSharedPtrMessage* msg); - + private: int flush_mainfest(); int flush_bootstrap(); void adjust_windows(); - + private: std::list fragments; SrsHdsFragment *currentSegment; int fragment_index; SrsSharedPtrMessage *video_sh; SrsSharedPtrMessage *audio_sh; - + SrsRequest *hds_req; bool hds_enabled; }; diff --git a/trunk/src/app/srs_app_heartbeat.cpp b/trunk/src/app/srs_app_heartbeat.cpp index 13a14c0f4..eed82fc14 100644 --- a/trunk/src/app/srs_app_heartbeat.cpp +++ b/trunk/src/app/srs_app_heartbeat.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -55,7 +55,7 @@ void SrsHttpHeartbeat::heartbeat() srs_error("http uri parse hartbeart url failed. url=%s, ret=%d", url.c_str(), ret); return; } - + std::string ip = ""; std::string device_id = _srs_config->get_heartbeat_device_id(); @@ -86,7 +86,7 @@ void SrsHttpHeartbeat::heartbeat() ISrsHttpMessage* msg = NULL; if ((ret = http.post(uri.get_path(), req, &msg)) != ERROR_SUCCESS) { srs_info("http post hartbeart uri failed. url=%s, request=%s, ret=%d", - url.c_str(), req.c_str(), ret); + url.c_str(), req.c_str(), ret); return; } SrsAutoFree(ISrsHttpMessage, msg); @@ -97,7 +97,7 @@ void SrsHttpHeartbeat::heartbeat() } srs_info("http hook hartbeart success. url=%s, request=%s, response=%s, ret=%d", - url.c_str(), req.c_str(), res.c_str(), ret); + url.c_str(), req.c_str(), res.c_str(), ret); return; } diff --git a/trunk/src/app/srs_app_heartbeat.hpp b/trunk/src/app/srs_app_heartbeat.hpp index 34a0d09ff..4bfbe2c57 100644 --- a/trunk/src/app/srs_app_heartbeat.hpp +++ b/trunk/src/app/srs_app_heartbeat.hpp @@ -1,38 +1,35 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_HEARTBEAT_HPP #define SRS_APP_HEARTBEAT_HPP -/* -#include -*/ #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.cpp b/trunk/src/app/srs_app_hls.cpp index 2a4edd46d..37a99e951 100644 --- a/trunk/src/app/srs_app_hls.cpp +++ b/trunk/src/app/srs_app_hls.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -262,7 +262,7 @@ int SrsHlsMuxer::initialize() if ((ret = async->start()) != ERROR_SUCCESS) { return ret; } - + return ret; } @@ -274,7 +274,7 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, srs_freep(req); req = r->copy(); - + hls_entry_prefix = entry_prefix; hls_path = path; hls_ts_file = ts_file; @@ -291,7 +291,7 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, // generate the m3u8 dir and path. m3u8_url = srs_path_build_stream(m3u8_file, req->vhost, req->app, req->stream); m3u8 = path + "/" + m3u8_url; - + // when update config, reset the history target duration. max_td = (int)(fragment * _srs_config->get_hls_td_ratio(r->vhost)); @@ -317,7 +317,7 @@ int SrsHlsMuxer::segment_open() // when segment open, the current segment must be NULL. srs_assert(!current); - + // load the default acodec from config. SrsAudioCodecId default_acodec = SrsAudioCodecIdAAC; if (true) { @@ -335,7 +335,7 @@ int SrsHlsMuxer::segment_open() srs_warn("hls: use aac for other codec=%s", default_acodec_str.c_str()); } } - + // load the default vcodec from config. SrsVideoCodecId default_vcodec = SrsVideoCodecIdAVC; if (true) { @@ -463,7 +463,7 @@ bool SrsHlsMuxer::is_segment_overflow() // use N% deviation, to smoother. double deviation = hls_ts_floor? SRS_HLS_FLOOR_REAP_PERCENT * deviation_ts * hls_fragment : 0.0; srs_info("hls: dur=%"PRId64"ms, tar=%.2f, dev=%.2fms/%dp, frag=%.2f", - current->duration(), hls_fragment + deviation, deviation, deviation_ts, hls_fragment); + current->duration(), hls_fragment + deviation, deviation, deviation_ts, hls_fragment); return current->duration() >= (hls_fragment + deviation) * 1000; } @@ -499,7 +499,7 @@ bool SrsHlsMuxer::pure_audio() int SrsHlsMuxer::flush_audio(SrsTsMessageCache* cache) { int ret = ERROR_SUCCESS; - + // if current is NULL, segment is not open, ignore the flush event. if (!current) { srs_warn("flush audio ignored, for segment is not open."); @@ -519,14 +519,14 @@ int SrsHlsMuxer::flush_audio(SrsTsMessageCache* cache) // write success, clear and free the msg srs_freep(cache->audio); - + return ret; } int SrsHlsMuxer::flush_video(SrsTsMessageCache* cache) { int ret = ERROR_SUCCESS; - + // if current is NULL, segment is not open, ignore the flush event. if (!current) { srs_warn("flush video ignored, for segment is not open."); @@ -563,7 +563,7 @@ int SrsHlsMuxer::segment_close() // when close current segment, the current segment must not be NULL. srs_assert(current); - + // valid, add to segments if segment duration is ok // when too small, it maybe not enough data to play. // when too large, it maybe timestamp corrupt. @@ -577,7 +577,7 @@ int SrsHlsMuxer::segment_close() { return ret; } - + // use async to call the http hooks, for it will cause thread switch. if ((ret = async->execute(new SrsDvrAsyncCallOnHlsNotify(_srs_context->get_id(), req, current->uri))) != ERROR_SUCCESS) { return ret; @@ -586,7 +586,7 @@ int SrsHlsMuxer::segment_close() // close the muxer of finished segment. srs_freep(current->tscw); - + // rename from tmp to real path if ((ret = current->rename()) != ERROR_SUCCESS) { return ret; @@ -597,31 +597,31 @@ int SrsHlsMuxer::segment_close() } else { // reuse current segment index. _sequence_no--; - + srs_trace("Drop ts segment, sequence_no=%d, uri=%s, duration=%"PRId64"ms", current->sequence_no, current->uri.c_str(), current->duration()); - + // rename from tmp to real path if ((ret = current->unlink_tmpfile()) != ERROR_SUCCESS) { return ret; } srs_freep(current); } - + // shrink the segments. segments->shrink(hls_window * 1000); - + // refresh the m3u8, donot contains the removed ts ret = refresh_m3u8(); - + // remove the ts file. segments->clear_expired(hls_cleanup); - + // check ret of refresh m3u8 if (ret != ERROR_SUCCESS) { srs_error("refresh m3u8 failed. ret=%d", ret); return ret; } - + return ret; } @@ -660,7 +660,7 @@ int SrsHlsMuxer::_refresh_m3u8(string m3u8_file) if (segments->empty()) { return ret; } - + SrsFileWriter writer; if ((ret = writer.open(m3u8_file)) != ERROR_SUCCESS) { srs_error("open m3u8 file %s failed. ret=%d", m3u8_file.c_str(), ret); @@ -673,8 +673,8 @@ int SrsHlsMuxer::_refresh_m3u8(string m3u8_file) // #EXT-X-ALLOW-CACHE:YES\n std::stringstream ss; ss << "#EXTM3U" << SRS_CONSTS_LF - << "#EXT-X-VERSION:3" << SRS_CONSTS_LF - << "#EXT-X-ALLOW-CACHE:YES" << SRS_CONSTS_LF; + << "#EXT-X-VERSION:3" << SRS_CONSTS_LF + << "#EXT-X-ALLOW-CACHE:YES" << SRS_CONSTS_LF; srs_verbose("write m3u8 header success."); // #EXT-X-MEDIA-SEQUENCE:4294967295\n @@ -687,13 +687,13 @@ int SrsHlsMuxer::_refresh_m3u8(string m3u8_file) // #EXT-X-TARGETDURATION:4294967295\n /** - * @see hls-m3u8-draft-pantos-http-live-streaming-12.pdf, page 25 - * The Media Playlist file MUST contain an EXT-X-TARGETDURATION tag. - * Its value MUST be equal to or greater than the EXTINF duration of any - * media segment that appears or will appear in the Playlist file, - * rounded to the nearest integer. Its value MUST NOT change. A - * typical target duration is 10 seconds. - */ + * @see hls-m3u8-draft-pantos-http-live-streaming-12.pdf, page 25 + * The Media Playlist file MUST contain an EXT-X-TARGETDURATION tag. + * Its value MUST be equal to or greater than the EXTINF duration of any + * media segment that appears or will appear in the Playlist file, + * rounded to the nearest integer. Its value MUST NOT change. A + * typical target duration is 10 seconds. + */ // @see https://github.com/ossrs/srs/issues/304#issuecomment-74000081 int target_duration = (int)ceil(segments->max_duration() / 1000.0); target_duration = srs_max(target_duration, max_td); @@ -721,7 +721,7 @@ int SrsHlsMuxer::_refresh_m3u8(string m3u8_file) ss << segment->uri << SRS_CONSTS_LF; srs_verbose("write m3u8 segment uri success."); } - + // write m3u8 to writer. std::string m3u8 = ss.str(); if ((ret = writer.write((char*)m3u8.c_str(), (int)m3u8.length(), NULL)) != ERROR_SUCCESS) { @@ -778,7 +778,7 @@ int SrsHlsController::deviation() int SrsHlsController::on_publish(SrsRequest* req) { int ret = ERROR_SUCCESS; - + std::string vhost = req->vhost; std::string stream = req->stream; std::string app = req->app; @@ -818,8 +818,8 @@ int SrsHlsController::on_publish(SrsRequest* req) return ret; } srs_trace("hls: win=%.2f, frag=%.2f, prefix=%s, path=%s, m3u8=%s, ts=%s, aof=%.2f, floor=%d, clean=%d, waitk=%d, dispose=%d", - hls_window, hls_fragment, entry_prefix.c_str(), path.c_str(), m3u8_file.c_str(), - ts_file.c_str(), hls_aof_ratio, ts_floor, cleanup, wait_keyframe, hls_dispose); + hls_window, hls_fragment, entry_prefix.c_str(), path.c_str(), m3u8_file.c_str(), + ts_file.c_str(), hls_aof_ratio, ts_floor, cleanup, wait_keyframe, hls_dispose); return ret; } @@ -844,7 +844,7 @@ int SrsHlsController::on_sequence_header() { // TODO: support discontinuity for the same stream // currently we reap and insert discontinity when encoder republish, - // but actually, event when stream is not republish, the + // but actually, event when stream is not republish, the // sequence header may change, for example, // ffmpeg ingest a external rtmp stream and push to srs, // when the sequence header changed, the stream is not republish. @@ -892,7 +892,7 @@ int SrsHlsController::write_audio(SrsAudioFrame* frame, int64_t pts) return ret; } - + int SrsHlsController::write_video(SrsVideoFrame* frame, int64_t dts) { int ret = ERROR_SUCCESS; @@ -930,7 +930,7 @@ int SrsHlsController::reap_segment() // TODO: flush audio before or after segment? // TODO: fresh segment begin with audio or video? - + // close current ts. if ((ret = muxer->segment_close()) != ERROR_SUCCESS) { srs_error("m3u8 muxer close segment failed. ret=%d", ret); @@ -968,10 +968,10 @@ SrsHls::SrsHls() enabled = false; disposable = false; last_update_time = 0; - + jitter = new SrsRtmpJitter(); controller = new SrsHlsController(); - + pprint = SrsPithyPrint::create_hls(); } @@ -1026,14 +1026,14 @@ int SrsHls::cycle() int SrsHls::initialize(SrsOriginHub* h, SrsRequest* r) { int ret = ERROR_SUCCESS; - + hub = h; req = r; - + if ((ret = controller->initialize()) != ERROR_SUCCESS) { return ret; } - + return ret; } @@ -1062,7 +1062,7 @@ int SrsHls::on_publish() // ok, the hls can be dispose, or need to be dispose. disposable = true; - + return ret; } @@ -1074,7 +1074,7 @@ void SrsHls::on_unpublish() if (!enabled) { return; } - + if ((ret = controller->on_unpublish()) != ERROR_SUCCESS) { srs_error("ignore m3u8 muxer flush/close audio failed. ret=%d", ret); } @@ -1092,7 +1092,7 @@ int SrsHls::on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format) // update the hls time, for hls_dispose. last_update_time = srs_get_system_time_ms(); - + SrsSharedPtrMessage* audio = shared_audio->copy(); SrsAutoFree(SrsSharedPtrMessage, audio); @@ -1136,7 +1136,7 @@ int SrsHls::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format) // update the hls time, for hls_dispose. last_update_time = srs_get_system_time_ms(); - + SrsSharedPtrMessage* video = shared_video->copy(); SrsAutoFree(SrsSharedPtrMessage, video); @@ -1178,7 +1178,7 @@ int SrsHls::on_video(SrsSharedPtrMessage* shared_video, SrsFormat* format) void SrsHls::hls_show_mux_log() { pprint->elapse(); - + if (!pprint->can_print()) { return; } @@ -1187,8 +1187,8 @@ void SrsHls::hls_show_mux_log() // @see: https://github.com/ossrs/srs/issues/81#issuecomment-48100994 // it's ok. srs_trace("-> "SRS_CONSTS_LOG_HLS" time=%"PRId64", sno=%d, ts=%s, dur=%.2f, dva=%dp", - pprint->age(), controller->sequence_no(), controller->ts_url().c_str(), - controller->duration(), controller->deviation()); + pprint->age(), controller->sequence_no(), controller->ts_url().c_str(), + controller->duration(), controller->deviation()); } diff --git a/trunk/src/app/srs_app_hls.hpp b/trunk/src/app/srs_app_hls.hpp index c7d794d16..7026eb11f 100644 --- a/trunk/src/app/srs_app_hls.hpp +++ b/trunk/src/app/srs_app_hls.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_HLS_HPP #define SRS_APP_HLS_HPP -/* -#include -*/ #include #include @@ -54,11 +51,11 @@ 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: @@ -116,13 +113,13 @@ public: }; /** -* 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. -*/ + * 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. + */ class SrsHlsMuxer { private: @@ -176,12 +173,12 @@ public: virtual int deviation(); public: /** - * initialize the hls muxer. - */ + * initialize the hls muxer. + */ virtual int initialize(); /** - * when publish, update the config for muxer. - */ + * when publish, update the config for muxer. + */ virtual int update_config(SrsRequest* r, std::string entry_prefix, std::string path, std::string m3u8_file, std::string ts_file, double fragment, double window, bool ts_floor, double aof_ratio, @@ -192,19 +189,19 @@ public: virtual int segment_open(); virtual int 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. */ 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: /** @@ -223,22 +220,22 @@ private: }; /** -* 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. -*/ + * 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: @@ -259,39 +256,39 @@ public: virtual int deviation(); public: /** - * when publish or unpublish stream. - */ + * when publish or unpublish stream. + */ virtual int on_publish(SrsRequest* req); virtual int 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 int 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 int write_audio(SrsAudioFrame* frame, int64_t pts); /** - * write video to muxer. - */ + * write video to muxer. + */ virtual int 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 int 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: @@ -313,8 +310,8 @@ public: virtual int cycle(); public: /** - * initialize the hls by handler and source. - */ + * initialize the hls by handler and source. + */ virtual int initialize(SrsOriginHub* h, SrsRequest* r); /** * publish stream event, continue to write the m3u8, @@ -323,14 +320,14 @@ public: */ virtual int 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 int on_audio(SrsSharedPtrMessage* shared_audio, SrsFormat* format); /** * mux the video packets to ts. diff --git a/trunk/src/app/srs_app_hourglass.cpp b/trunk/src/app/srs_app_hourglass.cpp index fcf8c7f5a..6096963a4 100644 --- a/trunk/src/app/srs_app_hourglass.cpp +++ b/trunk/src/app/srs_app_hourglass.cpp @@ -1,24 +1,24 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. */ #include diff --git a/trunk/src/app/srs_app_hourglass.hpp b/trunk/src/app/srs_app_hourglass.hpp index d3ca273c3..6792d6d66 100644 --- a/trunk/src/app/srs_app_hourglass.hpp +++ b/trunk/src/app/srs_app_hourglass.hpp @@ -1,33 +1,29 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_HOURGLASS_HPP #define SRS_APP_HOURGLASS_HPP -/* -#include -*/ - #include #include @@ -62,7 +58,7 @@ public: * 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, 1000); * hg->tick(1, 3000); diff --git a/trunk/src/app/srs_app_http_api.cpp b/trunk/src/app/srs_app_http_api.cpp index aa7d1f749..951198df5 100644 --- a/trunk/src/app/srs_app_http_api.cpp +++ b/trunk/src/app/srs_app_http_api.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -151,7 +151,7 @@ int SrsGoApiRoot::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) obj->set("urls", urls); urls->set("api", SrsJsonAny::str("the api root")); - + return srs_api_response(w, r, obj->dumps()); } @@ -899,7 +899,7 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) server->on_signal(SRS_SIGNAL_RELOAD); return srs_api_response_code(w, r, ret); } - + // for rpc=query, to get the configs of server. // @param scope the scope to query for config, it can be: // global, the configs belongs to the root, donot includes any sub directives. @@ -1010,7 +1010,7 @@ int SrsGoApiRaw::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) && scope != "ff_log_dir" && scope != "srs_log_tank" && scope != "srs_log_level" && scope != "srs_log_file" && scope != "max_connections" && scope != "utc_time" && scope != "pithy_print_ms" && scope != "vhost" && scope != "dvr" - ) { + ) { ret = ERROR_SYSTEM_CONFIG_RAW_NOT_ALLOWED; srs_error("raw api query invalid scope=%s. ret=%d", scope.c_str(), ret); return srs_api_response_code(w, r, ret); @@ -1291,7 +1291,7 @@ int SrsGoApiError::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) } SrsHttpApi::SrsHttpApi(IConnectionManager* cm, st_netfd_t fd, SrsHttpServeMux* m, string cip) - : SrsConnection(cm, fd, cip) +: SrsConnection(cm, fd, cip) { mux = m; cors = new SrsHttpCorsMux(); @@ -1360,7 +1360,7 @@ int SrsHttpApi::do_cycle() if ((ret = parser->parse_message(skt, this, &req)) != ERROR_SUCCESS) { return ret; } - + // if SUCCESS, always NOT-NULL. srs_assert(req); @@ -1372,7 +1372,7 @@ int SrsHttpApi::do_cycle() if ((ret = process_request(&writer, req)) != ERROR_SUCCESS) { return ret; } - + // read all rest bytes in request body. char buf[SRS_HTTP_READ_CACHE_BYTES]; ISrsHttpResponseReader* br = req->body_reader(); @@ -1381,18 +1381,18 @@ int SrsHttpApi::do_cycle() return ret; } } - + // donot keep alive, disconnect it. // @see https://github.com/ossrs/srs/issues/399 if (!req->is_keep_alive()) { break; } } - + return ret; } -int SrsHttpApi::process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) +int SrsHttpApi::process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) { int ret = ERROR_SUCCESS; @@ -1400,8 +1400,8 @@ int SrsHttpApi::process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) srs_assert(hm); srs_trace("HTTP API %s %s, content-length=%"PRId64", chunked=%d/%d", - r->method_str().c_str(), r->url().c_str(), r->content_length(), - hm->is_chunked(), hm->is_infinite_chunked()); + r->method_str().c_str(), r->url().c_str(), r->content_length(), + hm->is_chunked(), hm->is_infinite_chunked()); // use cors server mux to serve http request, which will proxy to mux. if ((ret = cors->serve_http(w, r)) != ERROR_SUCCESS) { diff --git a/trunk/src/app/srs_app_http_api.hpp b/trunk/src/app/srs_app_http_api.hpp index 8b91deeb1..b208c8dd5 100644 --- a/trunk/src/app/srs_app_http_api.hpp +++ b/trunk/src/app/srs_app_http_api.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_HTTP_API_HPP #define SRS_APP_HTTP_API_HPP -/* -#include -*/ - #include class SrsStSocket; diff --git a/trunk/src/app/srs_app_http_client.cpp b/trunk/src/app/srs_app_http_client.cpp index aa577bbc4..b1a6d3f0a 100644 --- a/trunk/src/app/srs_app_http_client.cpp +++ b/trunk/src/app/srs_app_http_client.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -147,17 +147,17 @@ int SrsHttpClient::post(string path, string req, ISrsHttpMessage** ppmsg) int SrsHttpClient::get(string path, string req, ISrsHttpMessage** ppmsg) { *ppmsg = NULL; - + int ret = ERROR_SUCCESS; // always set the content length. headers["Content-Length"] = srs_int2str(req.length()); - + if ((ret = connect()) != ERROR_SUCCESS) { srs_warn("http connect server failed. ret=%d", ret); return ret; } - + // send POST request to uri // GET %s HTTP/1.1\r\nHost: %s\r\nContent-Length: %d\r\n\r\n%s std::stringstream ss; @@ -168,7 +168,7 @@ int SrsHttpClient::get(string path, string req, ISrsHttpMessage** ppmsg) ss << key << ": " << value << SRS_HTTP_CRLF; } ss << SRS_HTTP_CRLF << req; - + std::string data = ss.str(); if ((ret = transport->write((void*)data.c_str(), data.length(), NULL)) != ERROR_SUCCESS) { // Disconnect the transport when channel error, reconnect for next operation. @@ -176,21 +176,21 @@ int SrsHttpClient::get(string path, string req, ISrsHttpMessage** ppmsg) srs_error("write http get failed. ret=%d", ret); return ret; } - + ISrsHttpMessage* msg = NULL; if ((ret = parser->parse_message(transport, NULL, &msg)) != ERROR_SUCCESS) { srs_error("parse http post response failed. ret=%d", ret); return ret; } srs_assert(msg); - + if (ppmsg) { *ppmsg = msg; } else { srs_freep(msg); } srs_info("parse http get response success."); - + return ret; } diff --git a/trunk/src/app/srs_app_http_client.hpp b/trunk/src/app/srs_app_http_client.hpp index a492cff66..d65ddc8af 100644 --- a/trunk/src/app/srs_app_http_client.hpp +++ b/trunk/src/app/srs_app_http_client.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_HTTP_CLIENT_HPP #define SRS_APP_HTTP_CLIENT_HPP -/* -#include -*/ #include #include diff --git a/trunk/src/app/srs_app_http_conn.cpp b/trunk/src/app/srs_app_http_conn.cpp index b505de8bf..78dd99685 100644 --- a/trunk/src/app/srs_app_http_conn.cpp +++ b/trunk/src/app/srs_app_http_conn.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -83,7 +83,7 @@ int SrsHttpResponseWriter::final_request() if (!header_wrote) { write_header(SRS_CONSTS_HTTP_OK); } - + // complete the chunked encoding. if (content_length == -1) { std::stringstream ss; @@ -266,7 +266,7 @@ int SrsHttpResponseWriter::send_header(char* data, int size) // status_line ss << "HTTP/1.1 " << status << " " - << srs_generate_http_status_text(status) << SRS_HTTP_CRLF; + << srs_generate_http_status_text(status) << SRS_HTTP_CRLF; // detect content type if (srs_go_http_body_allowd(status)) { @@ -1082,7 +1082,7 @@ int SrsHttpParser::on_body(http_parser* parser, const char* at, size_t length) } SrsHttpConn::SrsHttpConn(IConnectionManager* cm, st_netfd_t fd, ISrsHttpServeMux* m, string cip) - : SrsConnection(cm, fd, cip) +: SrsConnection(cm, fd, cip) { parser = new SrsHttpParser(); cors = new SrsHttpCorsMux(); @@ -1128,11 +1128,11 @@ int SrsHttpConn::do_cycle() srs_error("http initialize http parser failed. ret=%d", ret); return ret; } - + // set the recv timeout, for some clients never disconnect the connection. // @see https://github.com/ossrs/srs/issues/398 skt->set_recv_timeout(SRS_HTTP_RECV_TMMS); - + SrsRequest* last_req = NULL; SrsAutoFree(SrsRequest, last_req); @@ -1141,59 +1141,59 @@ int SrsHttpConn::do_cycle() if ((ret = cors->initialize(http_mux, crossdomain_enabled)) != ERROR_SUCCESS) { return ret; } - + // process http messages. while (!disposed) { ISrsHttpMessage* req = NULL; - + // get a http message if ((ret = parser->parse_message(skt, this, &req)) != ERROR_SUCCESS) { break; } - + // if SUCCESS, always NOT-NULL. srs_assert(req); - + // always free it in this scope. SrsAutoFree(ISrsHttpMessage, req); - + // get the last request, for report the info of request on connection disconnect. delete last_req; SrsHttpMessage* hreq = dynamic_cast(req); last_req = hreq->to_request(hreq->host()); - + // may should discard the body. if ((ret = on_got_http_message(req)) != ERROR_SUCCESS) { break; } - + // ok, handle http request. SrsHttpResponseWriter writer(skt); if ((ret = process_request(&writer, req)) != ERROR_SUCCESS) { break; } - + // donot keep alive, disconnect it. // @see https://github.com/ossrs/srs/issues/399 if (!req->is_keep_alive()) { break; } } - + int disc_ret = ERROR_SUCCESS; if ((disc_ret = on_disconnect(last_req)) != ERROR_SUCCESS) { srs_warn("connection on disconnect peer failed, but ignore this error. disc_ret=%d, ret=%d", disc_ret, ret); } - + return ret; } -int SrsHttpConn::process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) +int SrsHttpConn::process_request(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) { int ret = ERROR_SUCCESS; - srs_trace("HTTP %s %s, content-length=%"PRId64"", - r->method_str().c_str(), r->url().c_str(), r->content_length()); + srs_trace("HTTP %s %s, content-length=%"PRId64"", + r->method_str().c_str(), r->url().c_str(), r->content_length()); // use cors server mux to serve http request, which will proxy to http_remux. if ((ret = cors->serve_http(w, r)) != ERROR_SUCCESS) { @@ -1227,7 +1227,7 @@ int SrsHttpConn::on_reload_http_stream_crossdomain() } SrsResponseOnlyHttpConn::SrsResponseOnlyHttpConn(IConnectionManager* cm, st_netfd_t fd, ISrsHttpServeMux* m, string cip) - : SrsHttpConn(cm, fd, m, cip) +: SrsHttpConn(cm, fd, m, cip) { } diff --git a/trunk/src/app/srs_app_http_conn.hpp b/trunk/src/app/srs_app_http_conn.hpp index 91c4cfe77..1a8a35fb4 100644 --- a/trunk/src/app/srs_app_http_conn.hpp +++ b/trunk/src/app/srs_app_http_conn.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_HTTP_CONN_HPP #define SRS_APP_HTTP_CONN_HPP -/* -#include -*/ - #include #include @@ -128,7 +124,7 @@ public: * initialize the response reader with buffer. */ virtual int initialize(SrsFastStream* buffer); - // interface ISrsHttpResponseReader +// interface ISrsHttpResponseReader public: virtual bool eof(); virtual int read(char* data, int nb_data, int* nb_read); @@ -173,7 +169,7 @@ private: /** * whether the body is infinite chunked. */ - bool infinite_chunked; + bool infinite_chunked; /** * whether the request indicates should keep alive * for the http connection. @@ -205,9 +201,7 @@ public: /** * set the original messages, then update the message. */ - virtual int update(std::string url, bool allow_jsonp, http_parser* header, - SrsFastStream* body, std::vector& headers - ); + virtual int update(std::string url, bool allow_jsonp, http_parser* header, SrsFastStream* body, std::vector& headers); public: virtual SrsConnection* connection(); public: @@ -230,7 +224,7 @@ public: * whether body is infinite chunked encoding. * @remark set by enter_infinite_chunked. */ - virtual bool is_infinite_chunked(); + virtual bool is_infinite_chunked(); /** * whether should keep the connection alive. */ @@ -411,10 +405,10 @@ public: virtual ~SrsHttpServer(); public: virtual int initialize(); -// ISrsHttpServeMux + // ISrsHttpServeMux public: virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); -// http flv/ts/mp3/aac stream + // http flv/ts/mp3/aac stream public: virtual int http_mount(SrsSource* s, SrsRequest* r); virtual void http_unmount(SrsSource* s, SrsRequest* r); diff --git a/trunk/src/app/srs_app_http_hooks.cpp b/trunk/src/app/srs_app_http_hooks.cpp index 384fe1dfb..03a2146a0 100644 --- a/trunk/src/app/srs_app_http_hooks.cpp +++ b/trunk/src/app/srs_app_http_hooks.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -72,7 +72,7 @@ int SrsHttpHooks::on_connect(string url, SrsRequest* req) obj->set("app", SrsJsonAny::str(req->app.c_str())); obj->set("tcUrl", SrsJsonAny::str(req->tcUrl.c_str())); obj->set("pageUrl", SrsJsonAny::str(req->pageUrl.c_str())); - + std::string data = obj->dumps(); std::string res; int status_code; @@ -80,14 +80,14 @@ int SrsHttpHooks::on_connect(string url, SrsRequest* req) SrsHttpClient http; if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { srs_error("http post on_connect uri failed. " - "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); + "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); return ret; } srs_trace("http hook on_connect success. " - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), ret); + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), ret); return ret; } @@ -108,7 +108,7 @@ void SrsHttpHooks::on_close(string url, SrsRequest* req, int64_t send_bytes, int obj->set("app", SrsJsonAny::str(req->app.c_str())); obj->set("send_bytes", SrsJsonAny::integer(send_bytes)); obj->set("recv_bytes", SrsJsonAny::integer(recv_bytes)); - + std::string data = obj->dumps(); std::string res; int status_code; @@ -116,14 +116,14 @@ void SrsHttpHooks::on_close(string url, SrsRequest* req, int64_t send_bytes, int SrsHttpClient http; if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { srs_warn("http post on_close uri failed, ignored. " - "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); + "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); return; } srs_trace("http hook on_close success. " - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), ret); + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), ret); return; } @@ -144,7 +144,7 @@ int SrsHttpHooks::on_publish(string url, SrsRequest* req) obj->set("app", SrsJsonAny::str(req->app.c_str())); obj->set("tcUrl", SrsJsonAny::str(req->tcUrl.c_str())); obj->set("stream", SrsJsonAny::str(req->stream.c_str())); - + std::string data = obj->dumps(); std::string res; int status_code; @@ -152,14 +152,14 @@ int SrsHttpHooks::on_publish(string url, SrsRequest* req) SrsHttpClient http; if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { srs_error("http post on_publish uri failed. " - "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); + "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); return ret; } srs_trace("http hook on_publish success. " - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), ret); + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), ret); return ret; } @@ -179,7 +179,7 @@ void SrsHttpHooks::on_unpublish(string url, SrsRequest* req) obj->set("vhost", SrsJsonAny::str(req->vhost.c_str())); obj->set("app", SrsJsonAny::str(req->app.c_str())); obj->set("stream", SrsJsonAny::str(req->stream.c_str())); - + std::string data = obj->dumps(); std::string res; int status_code; @@ -187,14 +187,14 @@ void SrsHttpHooks::on_unpublish(string url, SrsRequest* req) SrsHttpClient http; if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { srs_warn("http post on_unpublish uri failed, ignored. " - "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); + "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); return; } srs_trace("http hook on_unpublish success. " - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), ret); + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), ret); return; } @@ -215,7 +215,7 @@ int SrsHttpHooks::on_play(string url, SrsRequest* req) obj->set("app", SrsJsonAny::str(req->app.c_str())); obj->set("stream", SrsJsonAny::str(req->stream.c_str())); obj->set("pageUrl", SrsJsonAny::str(req->pageUrl.c_str())); - + std::string data = obj->dumps(); std::string res; int status_code; @@ -223,14 +223,14 @@ int SrsHttpHooks::on_play(string url, SrsRequest* req) SrsHttpClient http; if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { srs_error("http post on_play uri failed. " - "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); + "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); return ret; } srs_trace("http hook on_play success. " - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), ret); + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), ret); return ret; } @@ -250,7 +250,7 @@ void SrsHttpHooks::on_stop(string url, SrsRequest* req) obj->set("vhost", SrsJsonAny::str(req->vhost.c_str())); obj->set("app", SrsJsonAny::str(req->app.c_str())); obj->set("stream", SrsJsonAny::str(req->stream.c_str())); - + std::string data = obj->dumps(); std::string res; int status_code; @@ -258,14 +258,14 @@ void SrsHttpHooks::on_stop(string url, SrsRequest* req) SrsHttpClient http; if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { srs_warn("http post on_stop uri failed, ignored. " - "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); + "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); return; } srs_trace("http hook on_stop success. " - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), ret); + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), ret); return; } @@ -288,7 +288,7 @@ int SrsHttpHooks::on_dvr(int cid, string url, SrsRequest* req, string file) obj->set("stream", SrsJsonAny::str(req->stream.c_str())); obj->set("cwd", SrsJsonAny::str(cwd.c_str())); obj->set("file", SrsJsonAny::str(file.c_str())); - + std::string data = obj->dumps(); std::string res; int status_code; @@ -296,14 +296,14 @@ int SrsHttpHooks::on_dvr(int cid, string url, SrsRequest* req, string file) SrsHttpClient http; if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { srs_error("http post on_dvr uri failed, ignored. " - "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); + "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); return ret; } srs_trace("http hook on_dvr success. " - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), ret); + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), ret); return ret; } @@ -337,7 +337,7 @@ int SrsHttpHooks::on_hls(int cid, string url, SrsRequest* req, string file, stri obj->set("m3u8", SrsJsonAny::str(m3u8.c_str())); obj->set("m3u8_url", SrsJsonAny::str(m3u8_url.c_str())); obj->set("seq_no", SrsJsonAny::integer(sn)); - + std::string data = obj->dumps(); std::string res; int status_code; @@ -345,14 +345,14 @@ int SrsHttpHooks::on_hls(int cid, string url, SrsRequest* req, string file, stri SrsHttpClient http; if ((ret = do_post(&http, url, data, status_code, res)) != ERROR_SUCCESS) { srs_error("http post on_hls uri failed, ignored. " - "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); + "client_id=%d, url=%s, request=%s, response=%s, code=%d, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), status_code, ret); return ret; } srs_trace("http hook on_hls success. " - "client_id=%d, url=%s, request=%s, response=%s, ret=%d", - client_id, url.c_str(), data.c_str(), res.c_str(), ret); + "client_id=%d, url=%s, request=%s, response=%s, ret=%d", + client_id, url.c_str(), data.c_str(), res.c_str(), ret); return ret; } @@ -417,7 +417,7 @@ int SrsHttpHooks::on_hls_notify(int cid, std::string url, SrsRequest* req, std:: int spenttime = (int)(srs_update_system_time_ms() - starttime); srs_trace("http hook on_hls_notify success. client_id=%d, url=%s, code=%d, spent=%dms, read=%dB, ret=%d", - client_id, url.c_str(), msg->status_code(), spenttime, nb_read, ret); + client_id, url.c_str(), msg->status_code(), spenttime, nb_read, ret); // ignore any error for on_hls_notify. ret = ERROR_SUCCESS; diff --git a/trunk/src/app/srs_app_http_hooks.hpp b/trunk/src/app/srs_app_http_hooks.hpp index b8aae97d9..612655f07 100644 --- a/trunk/src/app/srs_app_http_hooks.hpp +++ b/trunk/src/app/srs_app_http_hooks.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_HTTP_HOOKS_HPP #define SRS_APP_HTTP_HOOKS_HPP -/* -#include -*/ #include #include @@ -38,10 +35,10 @@ 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). + */ class SrsHttpHooks { private: @@ -50,40 +47,40 @@ 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. - */ + * on_connect hook, when client connect to srs. + * @param url the api server url, to valid the client. + * ignore if empty. + */ static int 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. - */ + * 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. - */ + * on_publish hook, when client(encoder) start to publish stream + * @param url the api server url, to valid the client. + * ignore if empty. + */ static int 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. - */ + * 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. - */ + * on_play hook, when client start to play stream. + * @param url the api server url, to valid the client. + * ignore if empty. + */ static int 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. - */ + * 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. diff --git a/trunk/src/app/srs_app_http_static.cpp b/trunk/src/app/srs_app_http_static.cpp index 620cbbcb3..6978683d0 100644 --- a/trunk/src/app/srs_app_http_static.cpp +++ b/trunk/src/app/srs_app_http_static.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -52,7 +52,7 @@ using namespace std; #include SrsVodStream::SrsVodStream(string root_dir) - : SrsHttpFileServer(root_dir) +: SrsHttpFileServer(root_dir) { } @@ -73,8 +73,8 @@ int SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r if (offset > fs.filesize()) { ret = ERROR_HTTP_REMUX_OFFSET_OVERFLOW; - srs_warn("http flv streaming %s overflow. size=%"PRId64", offset=%d, ret=%d", - fullpath.c_str(), fs.filesize(), offset, ret); + srs_warn("http flv streaming %s overflow. size=%"PRId64", offset=%d, ret=%d", + fullpath.c_str(), fs.filesize(), offset, ret); return ret; } @@ -114,10 +114,10 @@ int SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r if ((ret = fs.read(sh_data, sh_size, NULL)) != ERROR_SUCCESS) { return ret; } - + // seek to data offset int64_t left = fs.filesize() - offset; - + // write http header for ts. w->header()->set_content_length((int)(sizeof(flv_header) + sh_size + left)); w->header()->set_content_type("video/x-flv"); @@ -147,7 +147,7 @@ int SrsVodStream::serve_flv_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r int SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r, string fullpath, int start, int end) { int ret = ERROR_SUCCESS; - + srs_assert(start >= 0); srs_assert(end == -1 || end >= 0); @@ -157,7 +157,7 @@ int SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r if ((ret = fs.open(fullpath)) != ERROR_SUCCESS) { return ret; } - + // parse -1 to whole file. if (end == -1) { end = (int)fs.filesize(); @@ -165,21 +165,21 @@ int SrsVodStream::serve_mp4_stream(ISrsHttpResponseWriter* w, ISrsHttpMessage* r if (end > fs.filesize() || start > end) { ret = ERROR_HTTP_REMUX_OFFSET_OVERFLOW; - srs_warn("http mp4 streaming %s overflow. size=%"PRId64", offset=%d, ret=%d", - fullpath.c_str(), fs.filesize(), start, ret); + srs_warn("http mp4 streaming %s overflow. size=%"PRId64", offset=%d, ret=%d", + fullpath.c_str(), fs.filesize(), start, ret); return ret; } - + // seek to data offset, [start, end] for range. int64_t left = end - start + 1; - + // write http header for ts. w->header()->set_content_length(left); w->header()->set_content_type("video/mp4"); - + // status code 206 to make dash.as happy. w->write_header(SRS_CONSTS_HTTP_PartialContent); - + // response the content range header. std::stringstream content_range; content_range << "bytes " << start << "-" << end << "/" << fs.filesize(); diff --git a/trunk/src/app/srs_app_http_static.hpp b/trunk/src/app/srs_app_http_static.hpp index 084551f9e..2c0a62ccc 100644 --- a/trunk/src/app/srs_app_http_static.hpp +++ b/trunk/src/app/srs_app_http_static.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_HTTP_STATIC_HPP #define SRS_APP_HTTP_STATIC_HPP -/* -#include -*/ - #include #include @@ -49,9 +45,9 @@ protected: }; /** -* 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.cpp b/trunk/src/app/srs_app_http_stream.cpp index 7c6222889..fd6489b1f 100755 --- a/trunk/src/app/srs_app_http_stream.cpp +++ b/trunk/src/app/srs_app_http_stream.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -92,7 +92,7 @@ int SrsBufferCache::start() int SrsBufferCache::dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter) { int ret = ERROR_SUCCESS; - + if (fast_cache <= 0) { srs_info("http: ignore dump fast cache."); return ret; @@ -103,8 +103,8 @@ int SrsBufferCache::dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jit return ret; } - srs_trace("http: dump cache %d msgs, duration=%dms, cache=%.2fs", - queue->size(), queue->duration(), fast_cache); + srs_trace("http: dump cache %d msgs, duration=%dms, cache=%.2fs", + queue->size(), queue->duration(), fast_cache); return ret; } @@ -127,19 +127,19 @@ int SrsBufferCache::cycle() return ret; } SrsAutoFree(SrsConsumer, consumer); - + SrsPithyPrint* pprint = SrsPithyPrint::create_http_stream_cache(); SrsAutoFree(SrsPithyPrint, pprint); SrsMessageArray msgs(SRS_PERF_MW_MSGS); - + // set the queue size, which used for max cache. // TODO: FIXME: support reload. queue->set_queue_size(fast_cache); while (true) { pprint->elapse(); - + // get messages from consumer. // each msg in msgs.msgs must be free, for the SrsMessageArray never free them. int count = 0; @@ -156,12 +156,12 @@ int SrsBufferCache::cycle() // ignore when nothing got. continue; } - + if (pprint->can_print()) { - srs_trace("-> "SRS_CONSTS_LOG_HTTP_STREAM_CACHE" http: got %d msgs, age=%d, min=%d, mw=%d", - count, pprint->age(), SRS_PERF_MW_MIN_MSGS, SRS_CONSTS_RTMP_PULSE_TMMS); + srs_trace("-> "SRS_CONSTS_LOG_HTTP_STREAM_CACHE" http: got %d msgs, age=%d, min=%d, mw=%d", + count, pprint->age(), SRS_PERF_MW_MIN_MSGS, SRS_CONSTS_RTMP_PULSE_TMMS); } - + // free the messages. for (int i = 0; i < count; i++) { SrsSharedPtrMessage* msg = msgs.msgs[i]; @@ -460,11 +460,11 @@ SrsLiveStream::~SrsLiveStream() int SrsLiveStream::update(SrsSource* s, SrsRequest* r) { int ret = ERROR_SUCCESS; - + srs_freep(req); source = s; req = r->copy(); - + return ret; } @@ -506,12 +506,12 @@ int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) } SrsAutoFree(SrsConsumer, consumer); srs_verbose("http: consumer created success."); - + SrsPithyPrint* pprint = SrsPithyPrint::create_http_stream(); SrsAutoFree(SrsPithyPrint, pprint); SrsMessageArray msgs(SRS_PERF_MW_MSGS); - + // update the statistic when source disconveried. SrsStatistic* stat = SrsStatistic::instance(); if ((ret = stat->on_client(_srs_context->get_id(), req, NULL, SrsRtmpConnPlay)) != ERROR_SUCCESS) { @@ -537,11 +537,11 @@ int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) #ifdef SRS_PERF_FAST_FLV_ENCODER SrsFastFlvStreamEncoder* ffe = dynamic_cast(enc); #endif - + // TODO: free and erase the disabled entry after all related connections is closed. while (entry->enabled) { pprint->elapse(); - + // get messages from consumer. // each msg in msgs.msgs must be free, for the SrsMessageArray never free them. int count = 0; @@ -558,10 +558,10 @@ int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) // ignore when nothing got. continue; } - + if (pprint->can_print()) { - srs_info("-> "SRS_CONSTS_LOG_HTTP_STREAM" http: got %d msgs, age=%d, min=%d, mw=%d", - count, pprint->age(), SRS_PERF_MW_MIN_MSGS, SRS_CONSTS_RTMP_PULSE_TMMS); + srs_info("-> "SRS_CONSTS_LOG_HTTP_STREAM" http: got %d msgs, age=%d, min=%d, mw=%d", + count, pprint->age(), SRS_PERF_MW_MIN_MSGS, SRS_CONSTS_RTMP_PULSE_TMMS); } // sendout all messages. @@ -574,7 +574,7 @@ int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) #else ret = streaming_send_messages(enc, msgs.msgs, count); #endif - + // free the messages. for (int i = 0; i < count; i++) { SrsSharedPtrMessage* msg = msgs.msgs[i]; @@ -622,7 +622,7 @@ SrsLiveEntry::SrsLiveEntry(std::string m) stream = NULL; cache = NULL; - + req = NULL; source = NULL; @@ -712,24 +712,24 @@ int SrsHttpStreamServer::http_mount(SrsSource* s, SrsRequest* r) srs_info("ignore mount flv stream for disabled"); return ret; } - + SrsLiveEntry* tmpl = tflvs[r->vhost]; - + std::string mount = tmpl->mount; - + // replace the vhost variable mount = srs_string_replace(mount, "[vhost]", r->vhost); mount = srs_string_replace(mount, "[app]", r->app); mount = srs_string_replace(mount, "[stream]", r->stream); - + // remove the default vhost mount mount = srs_string_replace(mount, SRS_CONSTS_RTMP_DEFAULT_VHOST"/", "/"); entry = new SrsLiveEntry(mount); - + entry->cache = new SrsBufferCache(s, r); entry->stream = new SrsLiveStream(s, r, entry->cache); - + // TODO: FIXME: maybe refine the logic of http remux service. // if user push streams followed: // rtmp://test.com/live/stream1 @@ -737,7 +737,7 @@ int SrsHttpStreamServer::http_mount(SrsSource* s, SrsRequest* r) // and they will using the same template, such as: [vhost]/[app]/[stream].flv // so, need to free last request object, otherwise, it will cause memory leak. srs_freep(tmpl->req); - + tmpl->source = s; tmpl->req = r->copy(); @@ -763,7 +763,7 @@ int SrsHttpStreamServer::http_mount(SrsSource* s, SrsRequest* r) entry->stream->update(s, r); entry->cache->update(s, r); } - + if (entry->stream) { entry->stream->entry->enabled = true; return ret; @@ -775,12 +775,12 @@ int SrsHttpStreamServer::http_mount(SrsSource* s, SrsRequest* r) void SrsHttpStreamServer::http_unmount(SrsSource* s, SrsRequest* r) { std::string sid = r->get_stream_url(); - + if (sflvs.find(sid) == sflvs.end()) { srs_info("ignore unmount flv stream for disabled"); return; } - + SrsLiveEntry* entry = sflvs[sid]; entry->stream->entry->enabled = false; } @@ -788,51 +788,51 @@ void SrsHttpStreamServer::http_unmount(SrsSource* s, SrsRequest* r) int SrsHttpStreamServer::on_reload_vhost_added(string vhost) { int ret = ERROR_SUCCESS; - + if ((ret = on_reload_vhost_http_remux_updated(vhost)) != ERROR_SUCCESS) { return ret; } - + return ret; } int SrsHttpStreamServer::on_reload_vhost_http_remux_updated(string vhost) { int ret = ERROR_SUCCESS; - + if (tflvs.find(vhost) == tflvs.end()) { if ((ret = initialize_flv_entry(vhost)) != ERROR_SUCCESS) { return ret; } - + // http mount need SrsRequest and SrsSource param, only create a mapping template entry // and do mount automatically on playing http flv if this stream is a new http_remux stream. return ret; } - + SrsLiveEntry* tmpl = tflvs[vhost]; SrsRequest* req = tmpl->req; SrsSource* source = tmpl->source; - + if (source && req) { // cleanup the exists http remux. http_unmount(source, req); } - + if (!_srs_config->get_vhost_http_remux_enabled(vhost)) { return ret; } - + string old_tmpl_mount = tmpl->mount; string new_tmpl_mount = _srs_config->get_vhost_http_remux_mount(vhost); - + /** * TODO: not support to reload different mount url for the time being. * if the mount is change, need more logical thing to deal with. * such as erase stream from sflvs and free all related resource. */ srs_assert(old_tmpl_mount == new_tmpl_mount); - + // do http mount directly with SrsRequest and SrsSource if stream is played already. if (req) { std::string sid = req->get_stream_url(); @@ -846,9 +846,9 @@ int SrsHttpStreamServer::on_reload_vhost_http_remux_updated(string vhost) // for without SrsRequest and SrsSource if stream is not played yet, do http mount automatically // when start play this http flv stream. } - + srs_trace("vhost %s http_remux reload success", vhost.c_str()); - + return ret; } @@ -867,7 +867,7 @@ int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) if (ext.empty()) { return ret; } - + // find the actually request vhost. SrsConfDirective* vhost = _srs_config->get_vhost(request->host()); if (!vhost || !_srs_config->get_vhost_enabled(vhost)) { @@ -889,7 +889,7 @@ int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) // for edge, the http stream is trigger by hstrs and mount by it, // so we only hijack when only edge and hstrs is on. entry = it->second; - + // check entry and request extension. if (entry->is_flv()) { if (ext != ".flv") { @@ -911,7 +911,7 @@ int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) return ret; } } - + // convert to concreate class. SrsHttpMessage* hreq = dynamic_cast(request); srs_assert(hreq); @@ -919,7 +919,7 @@ int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) // hijack for entry. SrsRequest* r = hreq->to_request(vhost->arg0()); SrsAutoFree(SrsRequest, r); - + std::string sid = r->get_stream_url(); // check whether the http remux is enabled, // for example, user disable the http flv then reload. @@ -935,18 +935,18 @@ int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) } } } - + SrsSource* s = NULL; if ((ret = SrsSource::fetch_or_create(r, server, &s)) != ERROR_SUCCESS) { return ret; } srs_assert(s != NULL); - + // create http streaming handler. if ((ret = http_mount(s, r)) != ERROR_SUCCESS) { return ret; } - + // use the handler if exists. if (ph) { if (sflvs.find(sid) != sflvs.end()) { @@ -958,7 +958,7 @@ int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) // trigger edge to fetch from origin. bool vhost_is_edge = _srs_config->get_vhost_is_edge(r->vhost); srs_trace("flv: source url=%s, is_edge=%d, source_id=%d[%d]", - r->get_stream_url().c_str(), vhost_is_edge, s->source_id(), s->source_id()); + r->get_stream_url().c_str(), vhost_is_edge, s->source_id(), s->source_id()); return ret; } @@ -966,7 +966,7 @@ int SrsHttpStreamServer::hijack(ISrsHttpMessage* request, ISrsHttpHandler** ph) int SrsHttpStreamServer::initialize_flv_streaming() { int ret = ERROR_SUCCESS; - + // http flv live stream mount for each vhost. SrsConfDirective* root = _srs_config->get_root(); for (int i = 0; i < (int)root->directives.size(); i++) { @@ -975,7 +975,7 @@ int SrsHttpStreamServer::initialize_flv_streaming() if (!conf->is_vhost()) { continue; } - + if ((ret = initialize_flv_entry(conf->arg0())) != ERROR_SUCCESS) { return ret; } @@ -986,19 +986,16 @@ int SrsHttpStreamServer::initialize_flv_streaming() int SrsHttpStreamServer::initialize_flv_entry(std::string vhost) { int ret = ERROR_SUCCESS; - + if (!_srs_config->get_vhost_http_remux_enabled(vhost)) { return ret; } - - SrsLiveEntry* entry = new SrsLiveEntry( - _srs_config->get_vhost_http_remux_mount(vhost) - ); - + + SrsLiveEntry* entry = new SrsLiveEntry(_srs_config->get_vhost_http_remux_mount(vhost)); + tflvs[vhost] = entry; - srs_trace("http flv live stream, vhost=%s, mount=%s", - vhost.c_str(), entry->mount.c_str()); - + srs_trace("http flv live stream, vhost=%s, mount=%s", vhost.c_str(), entry->mount.c_str()); + return ret; } diff --git a/trunk/src/app/srs_app_http_stream.hpp b/trunk/src/app/srs_app_http_stream.hpp index 3881fde09..90adc2f66 100755 --- a/trunk/src/app/srs_app_http_stream.hpp +++ b/trunk/src/app/srs_app_http_stream.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_HTTP_STREAM_HPP #define SRS_APP_HTTP_STREAM_HPP -/* -#include -*/ - #include #include @@ -38,10 +34,10 @@ class SrsFlvTransmuxer; class SrsTsTransmuxer; /** -* for the srs http stream cache, -* for example, the audio stream cache to make android(weixin) happy. -* we start a thread to shrink the queue. -*/ + * for the srs http stream cache, + * for example, the audio stream cache to make android(weixin) happy. + * we start a thread to shrink the queue. + */ class SrsBufferCache : public ISrsEndlessThreadHandler { private: @@ -64,8 +60,8 @@ public: }; /** -* the stream encoder in some codec, for example, flv or aac. -*/ + * the stream encoder in some codec, for example, flv or aac. + */ class ISrsBufferEncoder { public: @@ -73,33 +69,33 @@ public: 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 int initialize(SrsFileWriter* w, SrsBufferCache* c) = 0; /** - * write rtmp video/audio/metadata. - */ + * write rtmp video/audio/metadata. + */ virtual int write_audio(int64_t timestamp, char* data, int size) = 0; virtual int write_video(int64_t timestamp, char* data, int size) = 0; virtual int 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 int dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter) = 0; }; /** -* the flv stream encoder, remux rtmp stream to flv stream. -*/ + * the flv stream encoder, remux rtmp stream to flv stream. + */ class SrsFlvStreamEncoder : public ISrsBufferEncoder { protected: @@ -136,8 +132,8 @@ public: #endif /** -* the ts stream encoder, remux rtmp stream to ts stream. -*/ + * the ts stream encoder, remux rtmp stream to ts stream. + */ class SrsTsStreamEncoder : public ISrsBufferEncoder { private: @@ -156,8 +152,8 @@ public: }; /** -* the aac stream encoder, remux rtmp stream to aac stream. -*/ + * the aac stream encoder, remux rtmp stream to aac stream. + */ class SrsAacStreamEncoder : public ISrsBufferEncoder { private: @@ -177,8 +173,8 @@ public: }; /** -* the mp3 stream encoder, remux rtmp stream to mp3 stream. -*/ + * the mp3 stream encoder, remux rtmp stream to mp3 stream. + */ class SrsMp3StreamEncoder : public ISrsBufferEncoder { private: @@ -198,8 +194,8 @@ public: }; /** -* write stream to http response direclty. -*/ + * write stream to http response direclty. + */ class SrsBufferWriter : public SrsFileWriter { private: @@ -219,9 +215,9 @@ public: }; /** -* the flv live stream supports access rtmp in flv over http. -* srs will remux rtmp to flv streaming. -*/ + * the flv live stream supports access rtmp in flv over http. + * srs will remux rtmp to flv streaming. + */ class SrsLiveStream : public ISrsHttpHandler { private: @@ -239,8 +235,8 @@ private: }; /** -* the srs live entry -*/ + * the srs live entry + */ struct SrsLiveEntry { private: @@ -260,7 +256,7 @@ public: SrsBufferCache* cache; SrsLiveEntry(std::string m); - + bool is_flv(); bool is_ts(); bool is_mp3(); @@ -268,12 +264,12 @@ public: }; /** -* the http stream server instance, -* serve http stream, for example, flv/ts/mp3/aac live stream. -*/ + * the http stream server instance, + * serve http stream, for example, flv/ts/mp3/aac live stream. + */ // TODO: Support multiple stream. class SrsHttpStreamServer : virtual public ISrsReloadHandler - , virtual public ISrsHttpMatchHijacker +, virtual public ISrsHttpMatchHijacker { private: SrsServer* server; @@ -288,7 +284,7 @@ public: virtual ~SrsHttpStreamServer(); public: virtual int initialize(); -// http flv/ts/mp3/aac stream + // http flv/ts/mp3/aac stream public: virtual int http_mount(SrsSource* s, SrsRequest* r); virtual void http_unmount(SrsSource* s, SrsRequest* r); diff --git a/trunk/src/app/srs_app_ingest.cpp b/trunk/src/app/srs_app_ingest.cpp index cca6d1414..8697f89b8 100644 --- a/trunk/src/app/srs_app_ingest.cpp +++ b/trunk/src/app/srs_app_ingest.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -200,14 +200,14 @@ int SrsIngester::cycle() srs_error("ingest ffmpeg start failed. ret=%d", ret); return ret; } - + // check ffmpeg status. if ((ret = ingester->cycle()) != ERROR_SUCCESS) { srs_error("ingest ffmpeg cycle failed. ret=%d", ret); return ret; } } - + // pithy print show_ingest_log_message(); @@ -226,7 +226,7 @@ void SrsIngester::clear_engines() SrsIngesterFFMPEG* ingester = *it; srs_freep(ingester); } - + ingesters.clear(); } @@ -390,7 +390,7 @@ int SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, S srs_trace("empty intput type, ingest=%s. ret=%d", ingest->arg0().c_str(), ret); return ret; } - + if (srs_config_ingest_is_file(input_type)) { std::string input_url = _srs_config->get_ingest_input_url(ingest); if (input_url.empty()) { @@ -401,7 +401,7 @@ int SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, S // for file, set re. ffmpeg->set_iparams("-re"); - + if ((ret = ffmpeg->initialize(input_url, output, log_file)) != ERROR_SUCCESS) { return ret; } @@ -415,14 +415,14 @@ int SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, S // for stream, no re. ffmpeg->set_iparams(""); - + if ((ret = ffmpeg->initialize(input_url, output, log_file)) != ERROR_SUCCESS) { return ret; } } else { ret = ERROR_ENCODER_INPUT_TYPE; - srs_error("invalid ingest=%s type=%s, ret=%d", - ingest->arg0().c_str(), input_type.c_str(), ret); + srs_error("invalid ingest=%s type=%s, ret=%d", + ingest->arg0().c_str(), input_type.c_str(), ret); } // set output format to flv for RTMP @@ -442,8 +442,8 @@ int SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, S } } - srs_trace("parse success, ingest=%s, vhost=%s", - ingest->arg0().c_str(), vhost->arg0().c_str()); + srs_trace("parse success, ingest=%s, vhost=%s", + ingest->arg0().c_str(), vhost->arg0().c_str()); return ret; } @@ -451,7 +451,7 @@ int SrsIngester::initialize_ffmpeg(SrsFFMPEG* ffmpeg, SrsConfDirective* vhost, S void SrsIngester::show_ingest_log_message() { pprint->elapse(); - + if ((int)ingesters.size() <= 0) { return; } @@ -463,7 +463,7 @@ void SrsIngester::show_ingest_log_message() // reportable if (pprint->can_print()) { srs_trace("-> "SRS_CONSTS_LOG_INGESTER" time=%"PRId64", ingesters=%d, #%d(alive=%ds, %s)", - pprint->age(), (int)ingesters.size(), index, ingester->alive() / 1000, ingester->uri().c_str()); + pprint->age(), (int)ingesters.size(), index, ingester->alive() / 1000, ingester->uri().c_str()); } } @@ -485,13 +485,13 @@ int SrsIngester::on_reload_vhost_removed(string vhost) ingester->stop(); srs_trace("reload stop ingester, vhost=%s, id=%s", vhost.c_str(), ingester->uri().c_str()); - + srs_freep(ingester); // remove the item from ingesters. it = ingesters.erase(it); } - + return ret; } @@ -527,7 +527,7 @@ int SrsIngester::on_reload_ingest_removed(string vhost, string ingest_id) ingester->stop(); srs_trace("reload stop ingester, vhost=%s, id=%s", vhost.c_str(), ingester->uri().c_str()); - + srs_freep(ingester); // remove the item from ingesters. @@ -549,7 +549,7 @@ int SrsIngester::on_reload_ingest_added(string vhost, string ingest_id) } srs_trace("reload add ingester, " - "vhost=%s, id=%s", vhost.c_str(), ingest_id.c_str()); + "vhost=%s, id=%s", vhost.c_str(), ingest_id.c_str()); return ret; } @@ -557,17 +557,17 @@ int SrsIngester::on_reload_ingest_added(string vhost, string ingest_id) int SrsIngester::on_reload_ingest_updated(string vhost, string ingest_id) { int ret = ERROR_SUCCESS; - + if ((ret = on_reload_ingest_removed(vhost, ingest_id)) != ERROR_SUCCESS) { return ret; } - + if ((ret = on_reload_ingest_added(vhost, ingest_id)) != ERROR_SUCCESS) { return ret; } srs_trace("reload updated ingester, " - "vhost=%s, id=%s", vhost.c_str(), ingest_id.c_str()); + "vhost=%s, id=%s", vhost.c_str(), ingest_id.c_str()); return ret; } diff --git a/trunk/src/app/srs_app_ingest.hpp b/trunk/src/app/srs_app_ingest.hpp index d74a7c365..d9868495c 100644 --- a/trunk/src/app/srs_app_ingest.hpp +++ b/trunk/src/app/srs_app_ingest.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_INGEST_HPP #define SRS_APP_INGEST_HPP -/* -#include -*/ #include #ifdef SRS_AUTO_INGEST @@ -41,8 +38,8 @@ class SrsConfDirective; class SrsPithyPrint; /** -* ingester ffmpeg object. -*/ + * ingester ffmpeg object. + */ class SrsIngesterFFMPEG { private: @@ -70,10 +67,10 @@ public: }; /** -* 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 ISrsReusableThreadHandler, public ISrsReloadHandler { private: diff --git a/trunk/src/app/srs_app_kafka.cpp b/trunk/src/app/srs_app_kafka.cpp index e99133306..3a8dd6785 100644 --- a/trunk/src/app/srs_app_kafka.cpp +++ b/trunk/src/app/srs_app_kafka.cpp @@ -1,24 +1,24 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. */ #include @@ -519,7 +519,7 @@ int SrsKafkaProducer::on_before_cycle() int SrsKafkaProducer::on_end_cycle() { st_mutex_unlock(lock); - + return ERROR_SUCCESS; } diff --git a/trunk/src/app/srs_app_kafka.hpp b/trunk/src/app/srs_app_kafka.hpp index d2992bfc6..b80787ba9 100644 --- a/trunk/src/app/srs_app_kafka.hpp +++ b/trunk/src/app/srs_app_kafka.hpp @@ -1,32 +1,29 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_KAFKA_HPP #define SRS_APP_KAFKA_HPP -/* -#include -*/ #include #include diff --git a/trunk/src/app/srs_app_listener.cpp b/trunk/src/app/srs_app_listener.cpp index 0690827fb..4b093c47b 100755 --- a/trunk/src/app/srs_app_listener.cpp +++ b/trunk/src/app/srs_app_listener.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -72,13 +72,13 @@ SrsUdpListener::SrsUdpListener(ISrsUdpHandler* h, string i, int p) handler = h; ip = i; port = p; - + _fd = -1; _stfd = NULL; - + nb_buf = SRS_UDP_MAX_PACKET_SIZE; buf = new char[nb_buf]; - + pthread = new SrsReusableThread("udp", this); } @@ -86,14 +86,14 @@ SrsUdpListener::~SrsUdpListener() { // close the stfd to trigger thread to interrupted. srs_close_stfd(_stfd); - + pthread->stop(); srs_freep(pthread); - // st does not close it sometimes, + // st does not close it sometimes, // close it manually. close(_fd); - + srs_freepa(buf); } @@ -149,19 +149,19 @@ int SrsUdpListener::listen() return ret; } srs_verbose("create st listen thread success, ep=%s:%d", ip.c_str(), port); - + return ret; } int SrsUdpListener::cycle() { int ret = ERROR_SUCCESS; - + // TODO: FIXME: support ipv6, @see man 7 ipv6 sockaddr_in from; int nb_from = sizeof(sockaddr_in); int nread = 0; - + if ((nread = st_recvfrom(_stfd, buf, nb_buf, (sockaddr*)&from, &nb_from, ST_UTIME_NO_TIMEOUT)) <= 0) { srs_warn("ignore recv udp packet failed, nread=%d", nread); return ret; @@ -171,11 +171,11 @@ int SrsUdpListener::cycle() srs_warn("handle udp packet failed. ret=%d", ret); return ret; } - + if (SRS_UDP_PACKET_RECV_CYCLE_INTERVAL_MS > 0) { st_usleep(SRS_UDP_PACKET_RECV_CYCLE_INTERVAL_MS * 1000); } - + return ret; } @@ -184,10 +184,10 @@ SrsTcpListener::SrsTcpListener(ISrsTcpHandler* h, string i, int p) handler = h; ip = i; port = p; - + _fd = -1; _stfd = NULL; - + pthread = new SrsReusableThread("tcp", this); } diff --git a/trunk/src/app/srs_app_listener.hpp b/trunk/src/app/srs_app_listener.hpp index d63abe6ad..b495e6878 100644 --- a/trunk/src/app/srs_app_listener.hpp +++ b/trunk/src/app/srs_app_listener.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_LISTENER_HPP #define SRS_APP_LISTENER_HPP -/* -#include -*/ - #include #include @@ -38,8 +34,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. struct sockaddr_in; /** -* the udp packet handler. -*/ + * the udp packet handler. + */ class ISrsUdpHandler { public: @@ -53,20 +49,20 @@ public: virtual int on_stfd_change(st_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 int on_udp_packet(sockaddr_in* from, char* buf, int nb_buf) = 0; }; /** -* the tcp connection handler. -*/ + * the tcp connection handler. + */ class ISrsTcpHandler { public: @@ -74,14 +70,14 @@ public: virtual ~ISrsTcpHandler(); public: /** - * when got tcp client. - */ + * when got tcp client. + */ virtual int on_tcp_client(st_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 ISrsReusableThreadHandler { private: @@ -109,8 +105,8 @@ public: }; /** -* 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 ISrsReusableThreadHandler { private: diff --git a/trunk/src/app/srs_app_log.cpp b/trunk/src/app/srs_app_log.cpp index fe589cee6..625bf8948 100644 --- a/trunk/src/app/srs_app_log.cpp +++ b/trunk/src/app/srs_app_log.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -92,7 +92,7 @@ SrsFastLog::SrsFastLog() { _level = SrsLogLevel::Trace; log_data = new char[LOG_MAX_SIZE]; - + fd = -1; log_to_file_tank = false; utc = false; @@ -101,12 +101,12 @@ SrsFastLog::SrsFastLog() SrsFastLog::~SrsFastLog() { srs_freepa(log_data); - + if (fd > 0) { ::close(fd); fd = -1; } - + if (_srs_config) { _srs_config->unsubscribe(this); } @@ -118,7 +118,7 @@ int SrsFastLog::initialize() if (_srs_config) { _srs_config->subscribe(this); - + log_to_file_tank = _srs_config->get_log_tank_file(); _level = srs_get_log_level(_srs_config->get_log_level()); utc = _srs_config->get_utc_time(); @@ -156,7 +156,7 @@ void SrsFastLog::verbose(const char* tag, int context_id, const char* fmt, ...) // we reserved 1 bytes for the new line. size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap); va_end(ap); - + write_log(fd, log_data, size, SrsLogLevel::Verbose); } @@ -176,7 +176,7 @@ void SrsFastLog::info(const char* tag, int context_id, const char* fmt, ...) // we reserved 1 bytes for the new line. size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap); va_end(ap); - + write_log(fd, log_data, size, SrsLogLevel::Info); } @@ -196,7 +196,7 @@ void SrsFastLog::trace(const char* tag, int context_id, const char* fmt, ...) // we reserved 1 bytes for the new line. size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap); va_end(ap); - + write_log(fd, log_data, size, SrsLogLevel::Trace); } @@ -216,7 +216,7 @@ void SrsFastLog::warn(const char* tag, int context_id, const char* fmt, ...) // we reserved 1 bytes for the new line. size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap); va_end(ap); - + write_log(fd, log_data, size, SrsLogLevel::Warn); } @@ -236,12 +236,12 @@ void SrsFastLog::error(const char* tag, int context_id, const char* fmt, ...) // we reserved 1 bytes for the new line. size += vsnprintf(log_data + size, LOG_MAX_SIZE - size, fmt, ap); va_end(ap); - + // add strerror() to error msg. if (errno != 0) { size += snprintf(log_data + size, LOG_MAX_SIZE - size, "(%s)", strerror(errno)); } - + write_log(fd, log_data, size, SrsLogLevel::Error); } @@ -259,18 +259,18 @@ int SrsFastLog::on_reload_log_tank() if (!_srs_config) { return ret; } - + bool tank = log_to_file_tank; log_to_file_tank = _srs_config->get_log_tank_file(); - + if (tank) { return ret; } - + if (!log_to_file_tank) { return ret; } - + if (fd > 0) { ::close(fd); } @@ -299,11 +299,11 @@ int SrsFastLog::on_reload_log_file() if (!_srs_config) { return ret; } - + if (!log_to_file_tank) { return ret; } - + if (fd > 0) { ::close(fd); } @@ -337,30 +337,30 @@ bool SrsFastLog::generate_header(bool error, const char* tag, int context_id, co if (error) { if (tag) { - log_header_size = snprintf(log_data, LOG_MAX_SIZE, - "[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%d][%d] ", - 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000), + log_header_size = snprintf(log_data, LOG_MAX_SIZE, + "[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%d][%d] ", + 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000), level_name, tag, getpid(), context_id, errno); } else { - log_header_size = snprintf(log_data, LOG_MAX_SIZE, - "[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%d][%d] ", - 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000), + log_header_size = snprintf(log_data, LOG_MAX_SIZE, + "[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%d][%d] ", + 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000), level_name, getpid(), context_id, errno); } } else { if (tag) { - log_header_size = snprintf(log_data, LOG_MAX_SIZE, - "[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%d] ", - 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000), + log_header_size = snprintf(log_data, LOG_MAX_SIZE, + "[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%s][%d][%d] ", + 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000), level_name, tag, getpid(), context_id); } else { - log_header_size = snprintf(log_data, LOG_MAX_SIZE, - "[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%d] ", - 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000), + log_header_size = snprintf(log_data, LOG_MAX_SIZE, + "[%d-%02d-%02d %02d:%02d:%02d.%03d][%s][%d][%d] ", + 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, (int)(tv.tv_usec / 1000), level_name, getpid(), context_id); } } - + if (log_header_size == -1) { return false; } @@ -396,7 +396,7 @@ void SrsFastLog::write_log(int& fd, char *str_log, int size, int level) printf("\033[31m%.*s\033[0m", size, str_log); } fflush(stdout); - + return; } @@ -426,10 +426,7 @@ void SrsFastLog::open_log_file() fd = ::open(filename.c_str(), O_RDWR | O_APPEND); if(fd == -1 && errno == ENOENT) { - fd = open(filename.c_str(), - O_RDWR | O_CREAT | O_TRUNC, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH - ); + fd = open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); } } diff --git a/trunk/src/app/srs_app_log.hpp b/trunk/src/app/srs_app_log.hpp index 6c1c5adb4..4a62a7e9d 100644 --- a/trunk/src/app/srs_app_log.hpp +++ b/trunk/src/app/srs_app_log.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_LOG_HPP #define SRS_APP_LOG_HPP -/* -#include -*/ - #include #include @@ -40,9 +36,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include /** -* st thread context, get_id will get the st-thread id, -* which identify the client. -*/ + * st thread context, get_id will get the st-thread id, + * which identify the client. + */ class SrsThreadContext : public ISrsThreadContext { private: @@ -59,13 +55,13 @@ public: }; /** -* 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. -*/ + * 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. + */ class SrsFastLog : public ISrsLog, public ISrsReloadHandler { -// for utest to override + // for utest to override protected: // defined in SrsLogLevel. int _level; diff --git a/trunk/src/app/srs_app_mpegts_udp.cpp b/trunk/src/app/srs_app_mpegts_udp.cpp index 8781b1495..3c36333c2 100644 --- a/trunk/src/app/srs_app_mpegts_udp.cpp +++ b/trunk/src/app/srs_app_mpegts_udp.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -70,33 +70,33 @@ SrsMpegtsQueue::~SrsMpegtsQueue() int SrsMpegtsQueue::push(SrsSharedPtrMessage* msg) { int ret = ERROR_SUCCESS; - + // TODO: FIXME: use right way. for (int i = 0; i < 10; i++) { if (msgs.find(msg->timestamp) == msgs.end()) { break; } - + // adjust the ts, add 1ms. msg->timestamp += 1; - + if (i >= 5) { srs_warn("mpegts: free the msg for dts exists, dts=%"PRId64, msg->timestamp); srs_freep(msg); return ret; } } - + if (msg->is_audio()) { nb_audios++; } - + if (msg->is_video()) { nb_videos++; } - + msgs[msg->timestamp] = msg; - + return ret; } @@ -106,23 +106,23 @@ SrsSharedPtrMessage* SrsMpegtsQueue::dequeue() bool av_ok = nb_videos >= 2 && nb_audios >= 2; // 100 videos about 30s, while 300 audios about 30s bool av_overflow = nb_videos > 100 || nb_audios > 300; - + if (av_ok || av_overflow) { std::map::iterator it = msgs.begin(); SrsSharedPtrMessage* msg = it->second; msgs.erase(it); - + if (msg->is_audio()) { nb_audios--; } - + if (msg->is_video()) { nb_videos--; } - + return msg; } - + return NULL; } @@ -147,7 +147,7 @@ SrsMpegtsOverUdp::SrsMpegtsOverUdp(SrsConfDirective* c) SrsMpegtsOverUdp::~SrsMpegtsOverUdp() { close(); - + srs_freep(buffer); srs_freep(stream); srs_freep(context); @@ -161,20 +161,20 @@ int SrsMpegtsOverUdp::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf) { std::string peer_ip = inet_ntoa(from->sin_addr); int peer_port = ntohs(from->sin_port); - + // append to buffer. buffer->append(buf, nb_buf); - + srs_info("udp: got %s:%d packet %d/%d bytes", - peer_ip.c_str(), peer_port, nb_buf, buffer->length()); - + peer_ip.c_str(), peer_port, nb_buf, buffer->length()); + return on_udp_bytes(peer_ip, peer_port, buf, nb_buf); } int SrsMpegtsOverUdp::on_udp_bytes(string host, int port, char* buf, int nb_buf) { int ret = ERROR_SUCCESS; - + // collect nMB data to parse in a time. // TODO: FIXME: comment the following for release. //if (buffer->length() < 3 * 1024 * 1024) return ret; @@ -204,26 +204,26 @@ int SrsMpegtsOverUdp::on_udp_bytes(string host, int port, char* buf, int nb_buf) fr.close(); buffer->append(fbuf, nb_fbuf); #endif - + // find the sync byte of mpegts. char* p = buffer->bytes(); for (int i = 0; i < buffer->length(); i++) { if (p[i] != 0x47) { continue; } - + if (i > 0) { buffer->erase(i); } break; } - + // drop ts packet when size not modulus by 188 if (buffer->length() < SRS_TS_PACKET_SIZE) { srs_warn("udp: wait %s:%d packet %d/%d bytes", host.c_str(), port, nb_buf, buffer->length()); return ret; } - + // use stream to parse ts packet. int nb_packet = buffer->length() / SRS_TS_PACKET_SIZE; for (int i = 0; i < nb_packet; i++) { @@ -231,7 +231,7 @@ int SrsMpegtsOverUdp::on_udp_bytes(string host, int port, char* buf, int nb_buf) if ((ret = stream->initialize(p, SRS_TS_PACKET_SIZE)) != ERROR_SUCCESS) { return ret; } - + // process each ts packet if ((ret = context->decode(stream, this)) != ERROR_SUCCESS) { srs_warn("mpegts: ignore parse ts packet failed. ret=%d", ret); @@ -240,28 +240,28 @@ int SrsMpegtsOverUdp::on_udp_bytes(string host, int port, char* buf, int nb_buf) srs_info("mpegts: parse ts packet completed"); } srs_info("mpegts: parse udp packet completed"); - + // erase consumed bytes if (nb_packet > 0) { buffer->erase(nb_packet * SRS_TS_PACKET_SIZE); } - + return ret; } int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg) { int ret = ERROR_SUCCESS; - + pprint->elapse(); - + // about the bytes of msg, specified by elementary stream which indicates by PES_packet_data_byte and stream_id // for example, when SrsTsStream of SrsTsChannel indicates stream_type is SrsTsStreamVideoMpeg4 and SrsTsStreamAudioMpeg4, // the elementary stream can be mux in "2.11 Carriage of ISO/IEC 14496 data" in hls-mpeg-ts-iso13818-1.pdf, page 103 - // @remark, the most popular stream_id is 0xe0 for h.264 over mpegts, which indicates the stream_id is video and + // @remark, the most popular stream_id is 0xe0 for h.264 over mpegts, which indicates the stream_id is video and // stream_number is 0, where I guess the elementary is specified in annexb format(ISO_IEC_14496-10-AVC-2003.pdf, page 211). // because when audio stream_number is 0, the elementary is ADTS(ISO_IEC_14496-3-AAC-2001.pdf, page 75, 1.A.2.2 ADTS). - + // about the bytes of PES_packet_data_byte, defined in hls-mpeg-ts-iso13818-1.pdf, page 58 // PES_packet_data_byte "C PES_packet_data_bytes shall be contiguous bytes of data from the elementary stream // indicated by the packets stream_id or PID. When the elementary stream data conforms to ITU-T @@ -270,33 +270,33 @@ int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg) // 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. - + // about the bytes of stream_id, define in hls-mpeg-ts-iso13818-1.pdf, page 49 // stream_id "C 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. - + // about the stream_id table, define in Table 2-18 "C Stream_id assignments, hls-mpeg-ts-iso13818-1.pdf, page 52. - // + // // 110x xxxx // ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC // 14496-3 audio stream number x xxxx // ((sid >> 5) & 0x07) == SrsTsPESStreamIdAudio - // + // // 1110 xxxx // ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC // 14496-2 video stream number xxxx // ((stream_id >> 4) & 0x0f) == SrsTsPESStreamIdVideo - + if (pprint->can_print()) { srs_trace("<- "SRS_CONSTS_LOG_STREAM_CASTER" mpegts: got %s age=%d stream=%s, dts=%"PRId64", pts=%"PRId64", size=%d, us=%d, cc=%d, sid=%#x(%s-%d)", - (msg->channel->apply == SrsTsPidApplyVideo)? "Video":"Audio", pprint->age(), srs_ts_stream2string(msg->channel->stream).c_str(), - msg->dts, msg->pts, msg->payload->length(), msg->packet->payload_unit_start_indicator, msg->continuity_counter, msg->sid, - msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number()); + (msg->channel->apply == SrsTsPidApplyVideo)? "Video":"Audio", pprint->age(), srs_ts_stream2string(msg->channel->stream).c_str(), + msg->dts, msg->pts, msg->payload->length(), msg->packet->payload_unit_start_indicator, msg->continuity_counter, msg->sid, + msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number()); } // When the audio SID is private stream 1, we use common audio. @@ -304,29 +304,29 @@ int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg) if (msg->channel->apply == SrsTsPidApplyAudio && msg->sid == SrsTsPESStreamIdPrivateStream1) { msg->sid = SrsTsPESStreamIdAudioCommon; } - + // when not audio/video, or not adts/annexb format, donot support. if (msg->stream_number() != 0) { ret = ERROR_STREAM_CASTER_TS_ES; - srs_error("mpegts: unsupported stream format, sid=%#x(%s-%d). ret=%d", - msg->sid, msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number(), ret); + srs_error("mpegts: unsupported stream format, sid=%#x(%s-%d). ret=%d", + msg->sid, msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number(), ret); return ret; } - + // check supported codec if (msg->channel->stream != SrsTsStreamVideoH264 && msg->channel->stream != SrsTsStreamAudioAAC) { ret = ERROR_STREAM_CASTER_TS_CODEC; srs_error("mpegts: unsupported stream codec=%d. ret=%d", msg->channel->stream, ret); return ret; } - + // parse the stream. SrsBuffer avs; if ((ret = avs.initialize(msg->payload->bytes(), msg->payload->length())) != ERROR_SUCCESS) { srs_error("mpegts: initialize av stream failed. ret=%d", ret); return ret; } - + // publish audio or video. if (msg->channel->stream == SrsTsStreamVideoH264) { return on_ts_video(msg, &avs); @@ -334,7 +334,7 @@ int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg) if (msg->channel->stream == SrsTsStreamAudioAAC) { return on_ts_audio(msg, &avs); } - + // TODO: FIXME: implements it. return ret; } @@ -342,12 +342,12 @@ int SrsMpegtsOverUdp::on_ts_message(SrsTsMessage* msg) int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsBuffer* avs) { int ret = ERROR_SUCCESS; - + // ensure rtmp connected. if ((ret = connect()) != ERROR_SUCCESS) { return ret; } - + // ts tbn to flv tbn. uint32_t dts = (uint32_t)(msg->dts / 90); uint32_t pts = (uint32_t)(msg->dts / 90); @@ -369,39 +369,39 @@ int SrsMpegtsOverUdp::on_ts_video(SrsTsMessage* msg, SrsBuffer* avs) if (nal_unit_type == SrsAvcNaluTypeAccessUnitDelimiter) { continue; } - + // for sps if (avc->is_sps(frame, frame_size)) { std::string sps; if ((ret = avc->sps_demux(frame, frame_size, sps)) != ERROR_SUCCESS) { return ret; } - + if (h264_sps == sps) { continue; } h264_sps_changed = true; h264_sps = sps; - + if ((ret = write_h264_sps_pps(dts, pts)) != ERROR_SUCCESS) { return ret; } continue; } - + // for pps if (avc->is_pps(frame, frame_size)) { std::string pps; if ((ret = avc->pps_demux(frame, frame_size, pps)) != ERROR_SUCCESS) { return ret; } - + if (h264_pps == pps) { continue; } h264_pps_changed = true; h264_pps = pps; - + if ((ret = write_h264_sps_pps(dts, pts)) != ERROR_SUCCESS) { return ret; } @@ -456,11 +456,11 @@ int SrsMpegtsOverUdp::write_h264_sps_pps(uint32_t dts, uint32_t pts) h264_sps_changed = false; h264_pps_changed = false; h264_sps_pps_sent = true; - + return ret; } -int SrsMpegtsOverUdp::write_h264_ipb_frame(char* frame, int frame_size, uint32_t dts, uint32_t pts) +int SrsMpegtsOverUdp::write_h264_ipb_frame(char* frame, int frame_size, uint32_t dts, uint32_t pts) { int ret = ERROR_SUCCESS; @@ -480,7 +480,7 @@ int SrsMpegtsOverUdp::write_h264_ipb_frame(char* frame, int frame_size, uint32_t if (nal_unit_type == SrsAvcNaluTypeIDR) { frame_type = SrsVideoAvcFrameTypeKeyFrame; } - + std::string ibp; if ((ret = avc->mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) { return ret; @@ -501,12 +501,12 @@ int SrsMpegtsOverUdp::write_h264_ipb_frame(char* frame, int frame_size, uint32_t int SrsMpegtsOverUdp::on_ts_audio(SrsTsMessage* msg, SrsBuffer* avs) { int ret = ERROR_SUCCESS; - + // ensure rtmp connected. if ((ret = connect()) != ERROR_SUCCESS) { return ret; } - + // ts tbn to flv tbn. uint32_t dts = (uint32_t)(msg->dts / 90); @@ -518,14 +518,14 @@ int SrsMpegtsOverUdp::on_ts_audio(SrsTsMessage* msg, SrsBuffer* avs) if ((ret = aac->adts_demux(avs, &frame, &frame_size, codec)) != ERROR_SUCCESS) { return ret; } - + // ignore invalid frame, // * atleast 1bytes for aac to decode the data. if (frame_size <= 0) { continue; } srs_info("mpegts: demux aac frame size=%d, dts=%d", frame_size, dts); - + // generate sh. if (aac_specific_config.empty()) { std::string sh; @@ -533,28 +533,28 @@ int SrsMpegtsOverUdp::on_ts_audio(SrsTsMessage* msg, SrsBuffer* avs) return ret; } aac_specific_config = sh; - + codec.aac_packet_type = 0; - + if ((ret = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), &codec, dts)) != ERROR_SUCCESS) { return ret; } } - + // audio raw data. codec.aac_packet_type = 1; if ((ret = write_audio_raw_frame(frame, frame_size, &codec, dts)) != ERROR_SUCCESS) { return ret; } } - + return ret; } int SrsMpegtsOverUdp::write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, uint32_t dts) { int ret = ERROR_SUCCESS; - + char* data = NULL; int size = 0; if ((ret = aac->mux_aac2flv(frame, frame_size, codec, dts, &data, &size)) != ERROR_SUCCESS) { @@ -579,24 +579,24 @@ int SrsMpegtsOverUdp::rtmp_write_packet(char type, uint32_t timestamp, char* dat return ret; } srs_assert(msg); - + // push msg to queue. if ((ret = queue->push(msg)) != ERROR_SUCCESS) { srs_error("mpegts: push msg to queue failed. ret=%d", ret); return ret; } - + // for all ready msg, dequeue and send out. for (;;) { if ((msg = queue->dequeue()) == NULL) { break; } - + if (pprint->can_print()) { srs_trace("mpegts: send msg %s age=%d, dts=%"PRId64", size=%d", - msg->is_audio()? "A":msg->is_video()? "V":"N", pprint->age(), msg->timestamp, msg->size); + msg->is_audio()? "A":msg->is_video()? "V":"N", pprint->age(), msg->timestamp, msg->size); } - + // send out encoded msg. if ((ret = sdk->send_and_free_message(msg)) != ERROR_SUCCESS) { close(); @@ -610,7 +610,7 @@ int SrsMpegtsOverUdp::rtmp_write_packet(char type, uint32_t timestamp, char* dat int SrsMpegtsOverUdp::connect() { int ret = ERROR_SUCCESS; - + // Ignore when connected. if (sdk) { return ret; @@ -631,7 +631,7 @@ int SrsMpegtsOverUdp::connect() srs_error("mpegts: publish failed. ret=%d", ret); return ret; } - + return ret; } diff --git a/trunk/src/app/srs_app_mpegts_udp.hpp b/trunk/src/app/srs_app_mpegts_udp.hpp index 1179b6d47..3ac27ad36 100644 --- a/trunk/src/app/srs_app_mpegts_udp.hpp +++ b/trunk/src/app/srs_app_mpegts_udp.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_MPEGTS_UDP_HPP #define SRS_APP_MPEGTS_UDP_HPP -/* -#include -*/ - #include #ifdef SRS_AUTO_STREAM_CASTER @@ -55,10 +51,10 @@ class SrsSimpleRtmpClient; #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: @@ -75,10 +71,10 @@ public: }; /** -* the mpegts over udp stream caster. -*/ + * the mpegts over udp stream caster. + */ class SrsMpegtsOverUdp : virtual public ISrsTsHandler - , virtual public ISrsUdpHandler +, virtual public ISrsUdpHandler { private: SrsBuffer* stream; diff --git a/trunk/src/app/srs_app_ng_exec.cpp b/trunk/src/app/srs_app_ng_exec.cpp index d04ec762c..339d86f2f 100644 --- a/trunk/src/app/srs_app_ng_exec.cpp +++ b/trunk/src/app/srs_app_ng_exec.cpp @@ -1,24 +1,24 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. */ #include diff --git a/trunk/src/app/srs_app_ng_exec.hpp b/trunk/src/app/srs_app_ng_exec.hpp index 6e0180b2a..77fc5ec9a 100644 --- a/trunk/src/app/srs_app_ng_exec.hpp +++ b/trunk/src/app/srs_app_ng_exec.hpp @@ -1,32 +1,29 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_NG_EXEC_HPP #define SRS_APP_NG_EXEC_HPP -/* -#include -*/ #include #include diff --git a/trunk/src/app/srs_app_pithy_print.cpp b/trunk/src/app/srs_app_pithy_print.cpp index e44900b00..5b42a89dc 100644 --- a/trunk/src/app/srs_app_pithy_print.cpp +++ b/trunk/src/app/srs_app_pithy_print.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -74,7 +74,7 @@ int SrsStageInfo::on_reload_pithy_print() update_print_time(); return ERROR_SUCCESS; } - + static std::map _srs_stages; SrsPithyPrint::SrsPithyPrint(int _stage_id) @@ -185,9 +185,9 @@ int SrsPithyPrint::enter_stage() srs_assert(stage != NULL); client_id = stage->nb_clients++; - + srs_verbose("enter stage, stage_id=%d, client_id=%d, nb_clients=%d, time_ms=%d", - stage->stage_id, client_id, stage->nb_clients, stage->pithy_print_time_ms); + stage->stage_id, client_id, stage->nb_clients, stage->pithy_print_time_ms); return client_id; } @@ -198,9 +198,9 @@ void SrsPithyPrint::leave_stage() srs_assert(stage != NULL); stage->nb_clients--; - + srs_verbose("leave stage, stage_id=%d, client_id=%d, nb_clients=%d, time_ms=%d", - stage->stage_id, client_id, stage->nb_clients, stage->pithy_print_time_ms); + stage->stage_id, client_id, stage->nb_clients, stage->pithy_print_time_ms); } void SrsPithyPrint::elapse() diff --git a/trunk/src/app/srs_app_pithy_print.hpp b/trunk/src/app/srs_app_pithy_print.hpp index 84ae30341..9658b6649 100644 --- a/trunk/src/app/srs_app_pithy_print.hpp +++ b/trunk/src/app/srs_app_pithy_print.hpp @@ -1,40 +1,36 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_PITHY_PRINT_HPP #define SRS_APP_PITHY_PRINT_HPP -/* -#include -*/ - #include #include /** -* the stage info to calc the age. -*/ + * the stage info to calc the age. + */ class SrsStageInfo : public ISrsReloadHandler { public: @@ -63,16 +59,16 @@ public: * 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. - } + * 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 { @@ -99,25 +95,25 @@ public: 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 ms. - */ + * get the elapsed time in ms. + */ virtual int64_t age(); }; diff --git a/trunk/src/app/srs_app_process.cpp b/trunk/src/app/srs_app_process.cpp index b7b1e0f4e..7456730f5 100644 --- a/trunk/src/app/srs_app_process.cpp +++ b/trunk/src/app/srs_app_process.cpp @@ -1,24 +1,24 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. */ #include @@ -253,7 +253,7 @@ int SrsProcess::start() if (pid > 0) { is_started = true; srs_trace("fored process, pid=%d, bin=%s, stdout=%s, stderr=%s, argv=%s", - pid, bin.c_str(), stdout_file.c_str(), stderr_file.c_str(), actual_cli.c_str()); + pid, bin.c_str(), stdout_file.c_str(), stderr_file.c_str(), actual_cli.c_str()); return ret; } diff --git a/trunk/src/app/srs_app_process.hpp b/trunk/src/app/srs_app_process.hpp index 3b5381462..94c5bdfa4 100644 --- a/trunk/src/app/srs_app_process.hpp +++ b/trunk/src/app/srs_app_process.hpp @@ -1,32 +1,29 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_PROCESS_HPP #define SRS_APP_PROCESS_HPP -/* -#include -*/ #include #include diff --git a/trunk/src/app/srs_app_recv_thread.cpp b/trunk/src/app/srs_app_recv_thread.cpp index 434421cf6..74820e646 100644 --- a/trunk/src/app/srs_app_recv_thread.cpp +++ b/trunk/src/app/srs_app_recv_thread.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -65,7 +65,7 @@ SrsRecvThread::~SrsRecvThread() { // stop recv thread. stop(); - + // destroy the thread. srs_freep(trd); } @@ -93,37 +93,37 @@ void SrsRecvThread::stop_loop() int SrsRecvThread::cycle() { int ret = ERROR_SUCCESS; - + while (!trd->interrupted()) { // When the pumper is interrupted, wait then retry. if (pumper->interrupted()) { st_usleep(timeout * 1000); continue; } - + SrsCommonMessage* msg = NULL; // Process the received message. if ((ret = rtmp->recv_message(&msg)) == ERROR_SUCCESS) { ret = pumper->consume(msg); } - + if (ret != ERROR_SUCCESS) { if (!srs_is_client_gracefully_close(ret) && !srs_is_system_control_error(ret)) { srs_error("recv thread error. ret=%d", ret); } - + // Interrupt the receive thread for any error. trd->interrupt(); // Notify the pumper to quit for error. pumper->interrupt(ret); - + return ret; } srs_verbose("thread loop recv message. ret=%d", ret); } - + return ret; } @@ -148,7 +148,7 @@ void SrsRecvThread::on_thread_stop() } SrsQueueRecvThread::SrsQueueRecvThread(SrsConsumer* consumer, SrsRtmpServer* rtmp_sdk, int timeout_ms) - : trd(this, rtmp_sdk, timeout_ms) +: trd(this, rtmp_sdk, timeout_ms) { _consumer = consumer; rtmp = rtmp_sdk; @@ -158,7 +158,7 @@ SrsQueueRecvThread::SrsQueueRecvThread(SrsConsumer* consumer, SrsRtmpServer* rtm SrsQueueRecvThread::~SrsQueueRecvThread() { stop(); - + // clear all messages. std::vector::iterator it; for (it = queue.begin(); it != queue.end(); ++it) { @@ -251,17 +251,14 @@ void SrsQueueRecvThread::on_stop() rtmp->set_auto_response(true); } -SrsPublishRecvThread::SrsPublishRecvThread( - SrsRtmpServer* rtmp_sdk, - SrsRequest* _req, int mr_sock_fd, int timeout_ms, - SrsRtmpConn* conn, SrsSource* source -): trd(this, rtmp_sdk, timeout_ms) +SrsPublishRecvThread::SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, SrsRequest* _req, int mr_sock_fd, int timeout_ms, SrsRtmpConn* conn, SrsSource* source) + : trd(this, rtmp_sdk, timeout_ms) { rtmp = rtmp_sdk; - + _conn = conn; _source = source; - + recv_error_code = ERROR_SUCCESS; _nb_msgs = 0; error = st_cond_new(); @@ -269,8 +266,8 @@ SrsPublishRecvThread::SrsPublishRecvThread( req = _req; mr_fd = mr_sock_fd; - - // the mr settings, + + // the mr settings, // @see https://github.com/ossrs/srs/issues/241 mr = _srs_config->get_mr_enabled(req->vhost); mr_sleep = _srs_config->get_mr_sleep_ms(req->vhost); @@ -377,12 +374,12 @@ void SrsPublishRecvThread::on_start() { // we donot set the auto response to false, // for the main thread never send message. - + #ifdef SRS_PERF_MERGED_READ if (mr) { // set underlayer buffer size set_socket_buffer(mr_sleep); - + // disable the merge read // @see https://github.com/ossrs/srs/issues/241 rtmp->set_merge_read(true, this); @@ -398,7 +395,7 @@ void SrsPublishRecvThread::on_stop() // when thread stop, signal the conn thread which wait. // @see https://github.com/ossrs/srs/issues/244 st_cond_signal(error); - + #ifdef SRS_PERF_MERGED_READ if (mr) { // disable the merge read @@ -420,11 +417,11 @@ void SrsPublishRecvThread::on_read(ssize_t nread) } /** - * 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. - * @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. + * @see https://github.com/ossrs/srs/issues/241 + */ if (nread < SRS_MR_SMALL_BYTES) { st_usleep(mr_sleep * 1000); } @@ -438,17 +435,17 @@ int SrsPublishRecvThread::on_reload_vhost_publish(string vhost) if (req->vhost != vhost) { return ret; } - - // the mr settings, + + // the mr settings, // @see https://github.com/ossrs/srs/issues/241 bool mr_enabled = _srs_config->get_mr_enabled(req->vhost); int sleep_ms = _srs_config->get_mr_sleep_ms(req->vhost); - + // update buffer when sleep ms changed. if (mr_sleep != sleep_ms) { set_socket_buffer(sleep_ms); } - + #ifdef SRS_PERF_MERGED_READ // mr enabled=>disabled if (mr && !mr_enabled) { @@ -463,7 +460,7 @@ int SrsPublishRecvThread::on_reload_vhost_publish(string vhost) rtmp->set_merge_read(true, this); } #endif - + // update to new state mr = mr_enabled; mr_sleep = sleep_ms; @@ -505,18 +502,18 @@ void SrsPublishRecvThread::set_socket_buffer(int sleep_ms) int onb_rbuf = 0; socklen_t sock_buf_size = sizeof(int); getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &onb_rbuf, &sock_buf_size); - + // socket recv buffer, system will double it. int nb_rbuf = socket_buffer_size / 2; if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &nb_rbuf, sock_buf_size) < 0) { srs_warn("set sock SO_RCVBUF=%d failed.", nb_rbuf); } getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &nb_rbuf, &sock_buf_size); - + srs_trace("mr change sleep %d=>%d, erbuf=%d, rbuf %d=>%d, sbytes=%d, realtime=%d", - mr_sleep, sleep_ms, socket_buffer_size, onb_rbuf, nb_rbuf, - SRS_MR_SMALL_BYTES, realtime); - + mr_sleep, sleep_ms, socket_buffer_size, onb_rbuf, nb_rbuf, + SRS_MR_SMALL_BYTES, realtime); + rtmp->set_recv_buffer(nb_rbuf); } diff --git a/trunk/src/app/srs_app_recv_thread.hpp b/trunk/src/app/srs_app_recv_thread.hpp index 54d5750de..165387cbd 100644 --- a/trunk/src/app/srs_app_recv_thread.hpp +++ b/trunk/src/app/srs_app_recv_thread.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_RECV_THREAD_HPP #define SRS_APP_RECV_THREAD_HPP -/* -#include -*/ - #include #include @@ -119,11 +115,11 @@ public: }; /** -* 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: @@ -154,12 +150,12 @@ public: }; /** -* 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 +, virtual public IMergeReadHandler #endif { private: @@ -188,14 +184,12 @@ private: int cid; int ncid; public: - SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, - SrsRequest* _req, int mr_sock_fd, int timeout_ms, - SrsRtmpConn* conn, SrsSource* source); + SrsPublishRecvThread(SrsRtmpServer* rtmp_sdk, SrsRequest* _req, int mr_sock_fd, int timeout_ms, SrsRtmpConn* conn, SrsSource* source); virtual ~SrsPublishRecvThread(); public: /** - * wait for error for some timeout. - */ + * wait for error for some timeout. + */ virtual int wait(uint64_t timeout_ms); virtual int64_t nb_msgs(); virtual int error_code(); diff --git a/trunk/src/app/srs_app_refer.cpp b/trunk/src/app/srs_app_refer.cpp index 3fb16c435..2a3a0ddf9 100644 --- a/trunk/src/app/srs_app_refer.cpp +++ b/trunk/src/app/srs_app_refer.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -47,7 +47,7 @@ int SrsRefer::check(std::string page_url, SrsConfDirective* refer) for (int i = 0; i < (int)refer->args.size(); i++) { if ((ret = check_single_refer(page_url, refer->args.at(i))) == ERROR_SUCCESS) { srs_verbose("check refer success. page_url=%s, refer=%s", - page_url.c_str(), refer->args.at(i).c_str()); + page_url.c_str(), refer->args.at(i).c_str()); return ret; } } @@ -88,7 +88,7 @@ int SrsRefer::check_single_refer(std::string page_url, std::string refer) if (ret != ERROR_SUCCESS) { srs_verbose("access denied, page_url=%s, domain_name=%s, refer=%s, ret=%d", - page_url.c_str(), domain_name.c_str(), refer.c_str(), ret); + page_url.c_str(), domain_name.c_str(), refer.c_str(), ret); } return ret; diff --git a/trunk/src/app/srs_app_refer.hpp b/trunk/src/app/srs_app_refer.hpp index 6f0699359..e38592875 100644 --- a/trunk/src/app/srs_app_refer.hpp +++ b/trunk/src/app/srs_app_refer.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_REFER_HPP #define SRS_APP_REFER_HPP -/* -#include -*/ #include #include @@ -40,10 +37,10 @@ public: virtual ~SrsRefer(); public: /** - * to check the refer. - * @param page_url the client page url. - * @param refer the refer in config. - */ + * to check the refer. + * @param page_url the client page url. + * @param refer the refer in config. + */ virtual int check(std::string page_url, SrsConfDirective* refer); private: virtual int check_single_refer(std::string page_url, std::string refer); diff --git a/trunk/src/app/srs_app_reload.cpp b/trunk/src/app/srs_app_reload.cpp index 82d398bb1..2af9480b6 100644 --- a/trunk/src/app/srs_app_reload.cpp +++ b/trunk/src/app/srs_app_reload.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include diff --git a/trunk/src/app/srs_app_reload.hpp b/trunk/src/app/srs_app_reload.hpp index 1fbb30978..7e95f686e 100644 --- a/trunk/src/app/srs_app_reload.hpp +++ b/trunk/src/app/srs_app_reload.hpp @@ -1,43 +1,40 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_RELOAD_HPP #define SRS_APP_RELOAD_HPP -/* -#include -*/ #include #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.cpp b/trunk/src/app/srs_app_rtmp_conn.cpp index 20aad8663..532d92b85 100644 --- a/trunk/src/app/srs_app_rtmp_conn.cpp +++ b/trunk/src/app/srs_app_rtmp_conn.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -298,7 +298,7 @@ SrsClientInfo::~SrsClientInfo() } SrsRtmpConn::SrsRtmpConn(SrsServer* svr, st_netfd_t c, string cip) - : SrsConnection(svr, c, cip) +: SrsConnection(svr, c, cip) { server = svr; @@ -310,7 +310,7 @@ SrsRtmpConn::SrsRtmpConn(SrsServer* svr, st_netfd_t c, string cip) kbps = new SrsKbps(); kbps->set_io(skt, skt); wakable = NULL; - + mw_sleep = SRS_PERF_MW_SLEEP; mw_enabled = false; realtime = SRS_PERF_MIN_LATENCY_ENABLED; @@ -357,7 +357,7 @@ int SrsRtmpConn::do_cycle() return ret; } #endif - + rtmp->set_recv_timeout(SRS_CONSTS_RTMP_TMMS); rtmp->set_send_timeout(SRS_CONSTS_RTMP_TMMS); @@ -384,13 +384,13 @@ int SrsRtmpConn::do_cycle() } srs_info("discovery app success. schema=%s, vhost=%s, port=%d, app=%s", - req->schema.c_str(), req->vhost.c_str(), req->port, req->app.c_str()); + req->schema.c_str(), req->vhost.c_str(), req->port, req->app.c_str()); if (req->schema.empty() || req->vhost.empty() || req->port == 0 || req->app.empty()) { ret = ERROR_RTMP_REQ_TCURL; srs_error("discovery tcUrl failed. " - "tcUrl=%s, schema=%s, vhost=%s, port=%d, app=%s, ret=%d", - req->tcUrl.c_str(), req->schema.c_str(), req->vhost.c_str(), req->port, req->app.c_str(), ret); + "tcUrl=%s, schema=%s, vhost=%s, port=%d, app=%s, ret=%d", + req->tcUrl.c_str(), req->schema.c_str(), req->vhost.c_str(), req->port, req->app.c_str(), ret); return ret; } @@ -402,10 +402,10 @@ int SrsRtmpConn::do_cycle() srs_verbose("check vhost success."); srs_trace("connect app, " - "tcUrl=%s, pageUrl=%s, swfUrl=%s, schema=%s, vhost=%s, port=%d, app=%s, args=%s", - req->tcUrl.c_str(), req->pageUrl.c_str(), req->swfUrl.c_str(), - req->schema.c_str(), req->vhost.c_str(), req->port, - req->app.c_str(), (req->args? "(obj)":"null")); + "tcUrl=%s, pageUrl=%s, swfUrl=%s, schema=%s, vhost=%s, port=%d, app=%s, args=%s", + req->tcUrl.c_str(), req->pageUrl.c_str(), req->swfUrl.c_str(), + req->schema.c_str(), req->vhost.c_str(), req->port, + req->app.c_str(), (req->args? "(obj)":"null")); // show client identity if(req->args) { @@ -428,21 +428,21 @@ int SrsRtmpConn::do_cycle() srs_id = (int)prop->to_number(); } - srs_info("edge-srs ip=%s, version=%s, pid=%d, id=%d", - srs_server_ip.c_str(), srs_version.c_str(), srs_pid, srs_id); + srs_info("edge-srs ip=%s, version=%s, pid=%d, id=%d", + srs_server_ip.c_str(), srs_version.c_str(), srs_pid, srs_id); if (srs_pid > 0) { - srs_trace("edge-srs ip=%s, version=%s, pid=%d, id=%d", - srs_server_ip.c_str(), srs_version.c_str(), srs_pid, srs_id); + srs_trace("edge-srs ip=%s, version=%s, pid=%d, id=%d", + srs_server_ip.c_str(), srs_version.c_str(), srs_pid, srs_id); } } ret = service_cycle(); - + int disc_ret = ERROR_SUCCESS; if ((disc_ret = on_disconnect()) != ERROR_SUCCESS) { srs_warn("connection on disconnect peer failed, but ignore this error. disc_ret=%d, ret=%d", disc_ret, ret); } - + return ret; } @@ -457,8 +457,8 @@ int SrsRtmpConn::on_reload_vhost_removed(string vhost) } // if the vhost connected is removed, disconnect the client. - srs_trace("vhost %s removed/disabled, close client url=%s", - vhost.c_str(), req->get_stream_url().c_str()); + srs_trace("vhost %s removed/disabled, close client url=%s", + vhost.c_str(), req->get_stream_url().c_str()); // should never close the fd in another thread, // one fd should managed by one thread, we should use interrupt instead. @@ -486,7 +486,7 @@ int SrsRtmpConn::on_reload_vhost_play(string vhost) send_min_interval = v; } } - + return ret; } @@ -520,7 +520,7 @@ int SrsRtmpConn::on_reload_vhost_realtime(string vhost) srs_trace("realtime changed %d=>%d", realtime, realtime_enabled); realtime = realtime_enabled; } - + return ret; } @@ -568,9 +568,9 @@ void SrsRtmpConn::cleanup() { kbps->cleanup(); } - + int SrsRtmpConn::service_cycle() -{ +{ int ret = ERROR_SUCCESS; SrsRequest* req = info->req; @@ -586,13 +586,13 @@ int SrsRtmpConn::service_cycle() srs_error("set input window acknowledgement size failed. ret=%d", ret); return ret; } - + if ((ret = rtmp->set_peer_bandwidth((int)(2.5 * 1000 * 1000), 2)) != ERROR_SUCCESS) { srs_error("set peer bandwidth failed. ret=%d", ret); return ret; } srs_verbose("set peer bandwidth success"); - + // get the ip which client connected. std::string local_ip = srs_get_local_ip(st_netfd_fileno(stfd)); @@ -630,7 +630,7 @@ int SrsRtmpConn::service_cycle() return ret; } srs_verbose("response connect app success"); - + if ((ret = rtmp->on_bw_done()) != ERROR_SUCCESS) { srs_error("on_bw_done failed. ret=%d", ret); return ret; @@ -664,7 +664,7 @@ int SrsRtmpConn::service_cycle() continue; } - // for "some" system control error, + // for "some" system control error, // logical accept and retry stream service. if (ret == ERROR_CONTROL_RTMP_CLOSE) { // TODO: FIXME: use ping message to anti-death of socket. @@ -698,8 +698,8 @@ int SrsRtmpConn::stream_service_cycle() return ret; } req->strip(); - srs_trace("client identified, type=%s, stream_name=%s, duration=%.2f", - srs_client_type_string(info->type).c_str(), req->stream.c_str(), req->duration); + srs_trace("client identified, type=%s, stream_name=%s, duration=%.2f", + srs_client_type_string(info->type).c_str(), req->stream.c_str(), req->duration); // security check if ((ret = security->check(info->type, ip, req)) != ERROR_SUCCESS) { @@ -707,7 +707,7 @@ int SrsRtmpConn::stream_service_cycle() return ret; } srs_info("security check ok"); - + // client is identified, set the timeout to service timeout. rtmp->set_recv_timeout(SRS_CONSTS_RTMP_TMMS); rtmp->set_send_timeout(SRS_CONSTS_RTMP_TMMS); @@ -725,11 +725,11 @@ int SrsRtmpConn::stream_service_cycle() srs_error("stat client failed. ret=%d", ret); return ret; } - + bool enabled_cache = _srs_config->get_gop_cache(req->vhost); srs_trace("source url=%s, ip=%s, cache=%d, is_edge=%d, source_id=%d[%d]", - req->get_stream_url().c_str(), ip.c_str(), enabled_cache, info->edge, - source->source_id(), source->source_id()); + req->get_stream_url().c_str(), ip.c_str(), enabled_cache, info->edge, + source->source_id(), source->source_id()); source->set_cache(enabled_cache); switch (info->type) { @@ -778,7 +778,7 @@ int SrsRtmpConn::stream_service_cycle() return ret; } } - + return ret; } @@ -834,8 +834,8 @@ int SrsRtmpConn::playing(SrsSource* source) } SrsAutoFree(SrsConsumer, consumer); srs_verbose("consumer created success."); - - // use isolate thread to recv, + + // use isolate thread to recv, // @see: https://github.com/ossrs/srs/issues/217 SrsQueueRecvThread trd(consumer, rtmp, SRS_PERF_MW_SLEEP); @@ -879,7 +879,7 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, SrsQueueRe // initialize other components SrsPithyPrint* pprint = SrsPithyPrint::create_rtmp_play(); SrsAutoFree(SrsPithyPrint, pprint); - + SrsMessageArray msgs(SRS_PERF_MW_MSGS); bool user_specified_duration_to_stop = (req->duration > 0); int64_t starttime = -1; @@ -897,7 +897,7 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, SrsQueueRe set_sock_options(); srs_trace("start play smi=%.2f, mw_sleep=%d, mw_enabled=%d, realtime=%d, tcp_nodelay=%d", - send_min_interval, mw_sleep, mw_enabled, realtime, tcp_nodelay); + send_min_interval, mw_sleep, mw_enabled, realtime, tcp_nodelay); while (!disposed) { // collect elapse for pithy print. @@ -909,7 +909,7 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, SrsQueueRe srs_error("connection expired. ret=%d", ret); return ret; } - + // to use isolate thread to recv, can improve about 33% performance. // @see: https://github.com/ossrs/srs/issues/196 // @see: https://github.com/ossrs/srs/issues/217 @@ -960,28 +960,28 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, SrsQueueRe srs_error("get messages from consumer failed. ret=%d", ret); return ret; } - + // reportable if (pprint->can_print()) { kbps->sample(); srs_trace("-> "SRS_CONSTS_LOG_PLAY - " time=%"PRId64", msgs=%d, okbps=%d,%d,%d, ikbps=%d,%d,%d, mw=%d", - pprint->age(), count, - kbps->get_send_kbps(), kbps->get_send_kbps_30s(), kbps->get_send_kbps_5m(), - kbps->get_recv_kbps(), kbps->get_recv_kbps_30s(), kbps->get_recv_kbps_5m(), - mw_sleep - ); + " time=%"PRId64", msgs=%d, okbps=%d,%d,%d, ikbps=%d,%d,%d, mw=%d", + pprint->age(), count, + kbps->get_send_kbps(), kbps->get_send_kbps_30s(), kbps->get_send_kbps_5m(), + kbps->get_recv_kbps(), kbps->get_recv_kbps_30s(), kbps->get_recv_kbps_5m(), + mw_sleep + ); } // we use wait timeout to get messages, // for min latency event no message incoming, // so the count maybe zero. if (count > 0) { - srs_verbose("mw wait %dms and got %d msgs %d(%"PRId64"-%"PRId64")ms", - mw_sleep, count, - (count > 0? msgs.msgs[count - 1]->timestamp - msgs.msgs[0]->timestamp : 0), - (count > 0? msgs.msgs[0]->timestamp : 0), - (count > 0? msgs.msgs[count - 1]->timestamp : 0)); + srs_verbose("mw wait %dms and got %d msgs %d(%"PRId64"-%"PRId64")ms", + mw_sleep, count, + (count > 0? msgs.msgs[count - 1]->timestamp - msgs.msgs[0]->timestamp : 0), + (count > 0? msgs.msgs[0]->timestamp : 0), + (count > 0? msgs.msgs[count - 1]->timestamp : 0)); } if (count <= 0) { @@ -996,7 +996,7 @@ int SrsRtmpConn::do_playing(SrsSource* source, SrsConsumer* consumer, SrsQueueRe } srs_info("got %d msgs, min=%d, mw=%d", count, SRS_PERF_MW_MIN_MSGS, mw_sleep); - // only when user specifies the duration, + // only when user specifies the duration, // we start to collect the durations for each message. if (user_specified_duration_to_stop) { for (int i = 0; i < count; i++) { @@ -1053,20 +1053,20 @@ int SrsRtmpConn::publishing(SrsSource* source) } srs_verbose("check publish_refer success."); } - + if ((ret = http_hooks_on_publish()) != ERROR_SUCCESS) { srs_error("http hook on_publish failed. ret=%d", ret); return ret; } - + if ((ret = acquire_publish(source)) == ERROR_SUCCESS) { // use isolate thread to recv, // @see: https://github.com/ossrs/srs/issues/237 SrsPublishRecvThread trd(rtmp, req, st_netfd_fileno(stfd), 0, this, source); - + srs_info("start to publish stream %s success", req->stream.c_str()); ret = do_publishing(source, &trd); - + // stop isolate recv thread trd.stop(); } @@ -1079,9 +1079,9 @@ int SrsRtmpConn::publishing(SrsSource* source) if (ret != ERROR_SYSTEM_STREAM_BUSY) { release_publish(source); } - + http_hooks_on_unpublish(); - + return ret; } @@ -1092,7 +1092,7 @@ int SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread* trd) SrsRequest* req = info->req; SrsPithyPrint* pprint = SrsPithyPrint::create_rtmp_publish(); SrsAutoFree(SrsPithyPrint, pprint); - + // start isolate recv thread. if ((ret = trd->start()) != ERROR_SUCCESS) { srs_error("start isolate recv thread failed. ret=%d", ret); @@ -1117,7 +1117,7 @@ int SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread* trd) srs_trace("start publish mr=%d/%d, p1stpt=%d, pnt=%d, tcp_nodelay=%d, rtcid=%d", mr, mr_sleep, publish_1stpkt_timeout, publish_normal_timeout, tcp_nodelay, receive_thread_cid); } - + int64_t nb_msgs = 0; while (!disposed) { pprint->elapse(); @@ -1128,7 +1128,7 @@ int SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread* trd) srs_error("connection expired. ret=%d", ret); return ret; } - + // cond wait for timeout. if (nb_msgs == 0) { // when not got msgs, wait for a larger timeout. @@ -1137,7 +1137,7 @@ int SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread* trd) } else { trd->wait(publish_normal_timeout); } - + // check the thread error code. if ((ret = trd->error_code()) != ERROR_SUCCESS) { if (!srs_is_system_control_error(ret) && !srs_is_client_gracefully_close(ret)) { @@ -1145,30 +1145,30 @@ int SrsRtmpConn::do_publishing(SrsSource* source, SrsPublishRecvThread* trd) } return ret; } - + // when not got any messages, timeout. if (trd->nb_msgs() <= nb_msgs) { ret = ERROR_SOCKET_TIMEOUT; srs_warn("publish timeout %dms, nb_msgs=%"PRId64", ret=%d", - nb_msgs? publish_normal_timeout : publish_1stpkt_timeout, nb_msgs, ret); + nb_msgs? publish_normal_timeout : publish_1stpkt_timeout, nb_msgs, ret); break; } nb_msgs = trd->nb_msgs(); - + // reportable if (pprint->can_print()) { kbps->sample(); bool mr = _srs_config->get_mr_enabled(req->vhost); int mr_sleep = _srs_config->get_mr_sleep_ms(req->vhost); srs_trace("<- "SRS_CONSTS_LOG_CLIENT_PUBLISH - " time=%"PRId64", okbps=%d,%d,%d, ikbps=%d,%d,%d, mr=%d/%d, p1stpt=%d, pnt=%d", pprint->age(), - kbps->get_send_kbps(), kbps->get_send_kbps_30s(), kbps->get_send_kbps_5m(), - kbps->get_recv_kbps(), kbps->get_recv_kbps_30s(), kbps->get_recv_kbps_5m(), - mr, mr_sleep, publish_1stpkt_timeout, publish_normal_timeout - ); + " time=%"PRId64", okbps=%d,%d,%d, ikbps=%d,%d,%d, mr=%d/%d, p1stpt=%d, pnt=%d", pprint->age(), + kbps->get_send_kbps(), kbps->get_send_kbps_30s(), kbps->get_send_kbps_5m(), + kbps->get_recv_kbps(), kbps->get_recv_kbps_30s(), kbps->get_recv_kbps_5m(), + mr, mr_sleep, publish_1stpkt_timeout, publish_normal_timeout + ); } } - + return ret; } @@ -1180,8 +1180,8 @@ int SrsRtmpConn::acquire_publish(SrsSource* source) if (!source->can_publish(info->edge)) { ret = ERROR_SYSTEM_STREAM_BUSY; - srs_warn("stream %s is already publishing. ret=%d", - req->get_stream_url().c_str(), ret); + srs_warn("stream %s is already publishing. ret=%d", + req->get_stream_url().c_str(), ret); return ret; } @@ -1190,17 +1190,17 @@ int SrsRtmpConn::acquire_publish(SrsSource* source) if ((ret = source->on_edge_start_publish()) != ERROR_SUCCESS) { srs_error("notice edge start publish stream failed. ret=%d", ret); return ret; - } + } } else { if ((ret = source->on_publish()) != ERROR_SUCCESS) { srs_error("notify publish failed. ret=%d", ret); return ret; } } - + return ret; } - + void SrsRtmpConn::release_publish(SrsSource* source) { // when edge, notice edge to change state. @@ -1224,7 +1224,7 @@ int SrsRtmpConn::handle_publish_message(SrsSource* source, SrsCommonMessage* msg return ret; } SrsAutoFree(SrsPacket, pkt); - + // for flash, any packet is republish. if (info->type == SrsRtmpConnFlashPublish) { // flash unpublish. @@ -1232,7 +1232,7 @@ int SrsRtmpConn::handle_publish_message(SrsSource* source, SrsCommonMessage* msg srs_trace("flash flash publish finished."); return ERROR_CONTROL_REPUBLISH; } - + // for fmle, drop others except the fmle start packet. if (dynamic_cast(pkt)) { SrsFMLEStartPacket* unpublish = dynamic_cast(pkt); @@ -1241,11 +1241,11 @@ int SrsRtmpConn::handle_publish_message(SrsSource* source, SrsCommonMessage* msg } return ERROR_CONTROL_REPUBLISH; } - + srs_trace("fmle ignore AMF0/AMF3 command message."); return ret; } - + // video, audio, data message if ((ret = process_publish_message(source, msg)) != ERROR_SUCCESS) { srs_error("fmle process publish message failed. ret=%d", ret); @@ -1302,7 +1302,7 @@ int SrsRtmpConn::process_publish_message(SrsSource* source, SrsCommonMessage* ms return ret; } SrsAutoFree(SrsPacket, pkt); - + if (dynamic_cast(pkt)) { SrsOnMetaDataPacket* metadata = dynamic_cast(pkt); if ((ret = source->on_meta_data(msg, metadata)) != ERROR_SUCCESS) { @@ -1382,7 +1382,7 @@ int SrsRtmpConn::process_play_control_msg(SrsConsumer* consumer, SrsCommonMessag srs_error("rtmp process play client pause failed. ret=%d", ret); return ret; } - + if ((ret = consumer->on_play_client_pause(pause->is_pause)) != ERROR_SUCCESS) { srs_error("consumer process play client pause failed. ret=%d", ret); return ret; @@ -1421,14 +1421,14 @@ void SrsRtmpConn::change_mw_sleep(int sleep_ms) // 2000*5000/8=1250000B(about 1220KB). int kbps = 5000; int socket_buffer_size = sleep_ms * kbps / 8; - + // socket send buffer, system will double it. int nb_sbuf = socket_buffer_size / 2; // override the send buffer by macro. - #ifdef SRS_PERF_SO_SNDBUF_SIZE +#ifdef SRS_PERF_SO_SNDBUF_SIZE nb_sbuf = SRS_PERF_SO_SNDBUF_SIZE / 2; - #endif +#endif // set the socket send buffer when required larger buffer if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &nb_sbuf, sock_buf_size) < 0) { @@ -1436,14 +1436,14 @@ void SrsRtmpConn::change_mw_sleep(int sleep_ms) } getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &nb_sbuf, &sock_buf_size); - srs_trace("mw changed sleep %d=>%d, max_msgs=%d, esbuf=%d, sbuf %d=>%d, realtime=%d", - mw_sleep, sleep_ms, SRS_PERF_MW_MSGS, socket_buffer_size, - onb_sbuf, nb_sbuf, realtime); + srs_trace("mw changed sleep %d=>%d, max_msgs=%d, esbuf=%d, sbuf %d=>%d, realtime=%d", + mw_sleep, sleep_ms, SRS_PERF_MW_MSGS, socket_buffer_size, + onb_sbuf, nb_sbuf, realtime); #else - srs_trace("mw changed sleep %d=>%d, max_msgs=%d, sbuf %d, realtime=%d", - mw_sleep, sleep_ms, SRS_PERF_MW_MSGS, onb_sbuf, realtime); + srs_trace("mw changed sleep %d=>%d, max_msgs=%d, sbuf %d, realtime=%d", + mw_sleep, sleep_ms, SRS_PERF_MW_MSGS, onb_sbuf, realtime); #endif - + mw_sleep = sleep_ms; } @@ -1456,19 +1456,19 @@ void SrsRtmpConn::set_sock_options() tcp_nodelay = nvalue; #ifdef SRS_PERF_TCP_NODELAY int fd = st_netfd_fileno(stfd); - + socklen_t nb_v = sizeof(int); - + int ov = 0; getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &ov, &nb_v); - + int v = tcp_nodelay; // set the socket send buffer when required larger buffer if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, nb_v) < 0) { srs_warn("set sock TCP_NODELAY=%d failed.", v); } getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &v, &nb_v); - + srs_trace("set TCP_NODELAY %d=>%d", ov, v); #else srs_warn("SRS_PERF_TCP_NODELAY is disabled but tcp_nodelay configed."); @@ -1495,7 +1495,7 @@ int SrsRtmpConn::check_edge_token_traverse_auth() string server; int port = SRS_CONSTS_RTMP_DEFAULT_PORT; srs_parse_hostport(hostport, server, port); - + SrsTcpClient* transport = new SrsTcpClient(server, port, SRS_EDGE_TOKEN_TRAVERSE_TMMS); SrsAutoFree(SrsTcpClient, transport); @@ -1521,7 +1521,7 @@ int SrsRtmpConn::do_token_traverse_auth(SrsRtmpClient* client) SrsRequest* req = info->req; srs_assert(client); - + client->set_recv_timeout(SRS_CONSTS_RTMP_TMMS); client->set_send_timeout(SRS_CONSTS_RTMP_TMMS); @@ -1544,7 +1544,7 @@ int SrsRtmpConn::do_token_traverse_auth(SrsRtmpClient* client) int SrsRtmpConn::on_disconnect() { int ret = ERROR_SUCCESS; - + http_hooks_on_close(); #ifdef SRS_AUTO_KAFKA @@ -1553,9 +1553,9 @@ int SrsRtmpConn::on_disconnect() return ret; } #endif - + // TODO: implements it. - + return ret; } @@ -1592,7 +1592,7 @@ int SrsRtmpConn::http_hooks_on_connect() return ret; } } - + return ret; } @@ -1659,7 +1659,7 @@ int SrsRtmpConn::http_hooks_on_publish() return ret; } } - + return ret; } @@ -1726,7 +1726,7 @@ int SrsRtmpConn::http_hooks_on_play() return ret; } } - + return ret; } @@ -1758,7 +1758,7 @@ void SrsRtmpConn::http_hooks_on_stop() std::string url = hooks.at(i); SrsHttpHooks::on_stop(url, req); } - + return; } diff --git a/trunk/src/app/srs_app_rtmp_conn.hpp b/trunk/src/app/srs_app_rtmp_conn.hpp index 73e95a72e..3dfaf49a2 100644 --- a/trunk/src/app/srs_app_rtmp_conn.hpp +++ b/trunk/src/app/srs_app_rtmp_conn.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_RTMP_CONN_HPP #define SRS_APP_RTMP_CONN_HPP -/* -#include -*/ - #include #include diff --git a/trunk/src/app/srs_app_rtsp.cpp b/trunk/src/app/srs_app_rtsp.cpp index 950c175be..eb9e5a39a 100644 --- a/trunk/src/app/srs_app_rtsp.cpp +++ b/trunk/src/app/srs_app_rtsp.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -79,22 +79,22 @@ int SrsRtpConn::listen() int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf) { int ret = ERROR_SUCCESS; - + pprint->elapse(); - + if (true) { SrsBuffer stream; - + if ((ret = stream.initialize(buf, nb_buf)) != ERROR_SUCCESS) { return ret; } - + SrsRtpPacket pkt; if ((ret = pkt.decode(&stream)) != ERROR_SUCCESS) { srs_error("rtsp: decode rtp packet failed. ret=%d", ret); return ret; } - + if (pkt.chunked) { if (!cache) { cache = new SrsRtpPacket(); @@ -102,10 +102,10 @@ int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf) cache->copy(&pkt); cache->payload->append(pkt.payload->bytes(), pkt.payload->length()); if (!cache->completed && pprint->can_print()) { - srs_trace("<- "SRS_CONSTS_LOG_STREAM_CASTER" rtsp: rtp chunked %dB, age=%d, vt=%d/%u, sts=%u/%#x/%#x, paylod=%dB", - nb_buf, pprint->age(), cache->version, cache->payload_type, cache->sequence_number, cache->timestamp, cache->ssrc, - cache->payload->length() - ); + srs_trace("<- "SRS_CONSTS_LOG_STREAM_CASTER" rtsp: rtp chunked %dB, age=%d, vt=%d/%u, sts=%u/%#x/%#x, paylod=%dB", + nb_buf, pprint->age(), cache->version, cache->payload_type, cache->sequence_number, cache->timestamp, cache->ssrc, + cache->payload->length() + ); return ret; } } else { @@ -114,14 +114,14 @@ int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf) cache->reap(&pkt); } } - + if (pprint->can_print()) { - srs_trace("<- "SRS_CONSTS_LOG_STREAM_CASTER" rtsp: rtp #%d %dB, age=%d, vt=%d/%u, sts=%u/%u/%#x, paylod=%dB, chunked=%d", - stream_id, nb_buf, pprint->age(), cache->version, cache->payload_type, cache->sequence_number, cache->timestamp, cache->ssrc, - cache->payload->length(), cache->chunked - ); + srs_trace("<- "SRS_CONSTS_LOG_STREAM_CASTER" rtsp: rtp #%d %dB, age=%d, vt=%d/%u, sts=%u/%u/%#x, paylod=%dB, chunked=%d", + stream_id, nb_buf, pprint->age(), cache->version, cache->payload_type, cache->sequence_number, cache->timestamp, cache->ssrc, + cache->payload->length(), cache->chunked + ); } - + // always free it. SrsAutoFree(SrsRtpPacket, cache); @@ -129,7 +129,7 @@ int SrsRtpConn::on_udp_packet(sockaddr_in* from, char* buf, int nb_buf) srs_error("rtsp: process rtp packet failed. ret=%d", ret); return ret; } - + return ret; } @@ -165,43 +165,43 @@ int64_t SrsRtspJitter::timestamp() int SrsRtspJitter::correct(int64_t& ts) { int ret = ERROR_SUCCESS; - + if (previous_timestamp == 0) { previous_timestamp = ts; } - + delta = srs_max(0, (int)(ts - previous_timestamp)); if (delta > 90000) { delta = 0; } - + previous_timestamp = ts; - + ts = pts + delta; - pts = ts; - + pts = ts; + return ret; } SrsRtspConn::SrsRtspConn(SrsRtspCaster* c, st_netfd_t fd, std::string o) { output_template = o; - + session = ""; video_rtp = NULL; audio_rtp = NULL; - + caster = c; stfd = fd; skt = new SrsStSocket(); rtsp = new SrsRtspStack(skt); trd = new SrsOneCycleThread("rtsp", this); - + req = NULL; sdk = NULL; vjitter = new SrsRtspJitter(); ajitter = new SrsRtspJitter(); - + avc = new SrsRawH264Stream(); aac = new SrsRawAacStream(); acodec = new SrsRawAacStreamCodec(); @@ -213,17 +213,17 @@ SrsRtspConn::~SrsRtspConn() close(); srs_close_stfd(stfd); - + srs_freep(video_rtp); srs_freep(audio_rtp); - + srs_freep(trd); srs_freep(skt); srs_freep(rtsp); srs_freep(sdk); srs_freep(req); - + srs_freep(vjitter); srs_freep(ajitter); srs_freep(acodec); @@ -243,11 +243,11 @@ int SrsRtspConn::serve() int SrsRtspConn::do_cycle() { int ret = ERROR_SUCCESS; - + // retrieve ip of client. std::string ip = srs_get_peer_ip(st_netfd_fileno(stfd)); srs_trace("rtsp: serve %s", ip.c_str()); - + // consume all rtsp messages. for (;;) { SrsRtspRequest* req = NULL; @@ -259,7 +259,7 @@ int SrsRtspConn::do_cycle() } SrsAutoFree(SrsRtspRequest, req); srs_info("rtsp: got rtsp request"); - + if (req->is_options()) { SrsRtspOptionsResponse* res = new SrsRtspOptionsResponse((int)req->seq); res->session = session; @@ -278,7 +278,7 @@ int SrsRtspConn::do_cycle() rtsp_tcUrl = rtsp_tcUrl.substr(0, pos); } srs_parse_rtmp_url(rtsp_tcUrl, rtsp_tcUrl, rtsp_stream); - + srs_assert(req->sdp); video_id = ::atoi(req->sdp->video_stream_id.c_str()); audio_id = ::atoi(req->sdp->audio_stream_id.c_str()); @@ -289,12 +289,12 @@ int SrsRtspConn::do_cycle() h264_sps = req->sdp->video_sps; h264_pps = req->sdp->video_pps; aac_specific_config = req->sdp->audio_sh; - srs_trace("rtsp: video(#%d, %s, %s/%s), audio(#%d, %s, %s/%s, %dHZ %dchannels), %s/%s", - video_id, video_codec.c_str(), req->sdp->video_protocol.c_str(), req->sdp->video_transport_format.c_str(), - audio_id, audio_codec.c_str(), req->sdp->audio_protocol.c_str(), req->sdp->audio_transport_format.c_str(), - audio_sample_rate, audio_channel, rtsp_tcUrl.c_str(), rtsp_stream.c_str() - ); - + srs_trace("rtsp: video(#%d, %s, %s/%s), audio(#%d, %s, %s/%s, %dHZ %dchannels), %s/%s", + video_id, video_codec.c_str(), req->sdp->video_protocol.c_str(), req->sdp->video_transport_format.c_str(), + audio_id, audio_codec.c_str(), req->sdp->audio_protocol.c_str(), req->sdp->audio_transport_format.c_str(), + audio_sample_rate, audio_channel, rtsp_tcUrl.c_str(), rtsp_stream.c_str() + ); + SrsRtspResponse* res = new SrsRtspResponse((int)req->seq); res->session = session; if ((ret = rtsp->send_message(res)) != ERROR_SUCCESS) { @@ -310,7 +310,7 @@ int SrsRtspConn::do_cycle() srs_error("rtsp: alloc port failed. ret=%d", ret); return ret; } - + SrsRtpConn* rtp = NULL; if (req->stream_id == video_id) { srs_freep(video_rtp); @@ -323,18 +323,18 @@ int SrsRtspConn::do_cycle() srs_error("rtsp: rtp listen at port=%d failed. ret=%d", lpm, ret); return ret; } - srs_trace("rtsp: #%d %s over %s/%s/%s %s client-port=%d-%d, server-port=%d-%d", - req->stream_id, (req->stream_id == video_id)? "Video":"Audio", - req->transport->transport.c_str(), req->transport->profile.c_str(), req->transport->lower_transport.c_str(), - req->transport->cast_type.c_str(), req->transport->client_port_min, req->transport->client_port_max, - lpm, lpm + 1 - ); - + srs_trace("rtsp: #%d %s over %s/%s/%s %s client-port=%d-%d, server-port=%d-%d", + req->stream_id, (req->stream_id == video_id)? "Video":"Audio", + req->transport->transport.c_str(), req->transport->profile.c_str(), req->transport->lower_transport.c_str(), + req->transport->cast_type.c_str(), req->transport->client_port_min, req->transport->client_port_max, + lpm, lpm + 1 + ); + // create session. if (session.empty()) { session = "O9EaZ4bf"; // TODO: FIXME: generate session id. } - + SrsRtspSetupResponse* res = new SrsRtspSetupResponse((int)req->seq); res->client_port_min = req->transport->client_port_min; res->client_port_max = req->transport->client_port_max; @@ -358,19 +358,19 @@ int SrsRtspConn::do_cycle() } } } - + return ret; } int SrsRtspConn::on_rtp_packet(SrsRtpPacket* pkt, int stream_id) { int ret = ERROR_SUCCESS; - + // ensure rtmp connected. if ((ret = connect()) != ERROR_SUCCESS) { return ret; } - + if (stream_id == video_id) { // rtsp tbn is ts tbn. int64_t pts = pkt->timestamp; @@ -378,10 +378,10 @@ int SrsRtspConn::on_rtp_packet(SrsRtpPacket* pkt, int stream_id) srs_error("rtsp: correct by jitter failed. ret=%d", ret); return ret; } - + // TODO: FIXME: set dts to pts, please finger out the right dts. int64_t dts = pts; - + return on_rtp_video(pkt, dts, pts); } else { // rtsp tbn is ts tbn. @@ -390,10 +390,10 @@ int SrsRtspConn::on_rtp_packet(SrsRtpPacket* pkt, int stream_id) srs_error("rtsp: correct by jitter failed. ret=%d", ret); return ret; } - + return on_rtp_audio(pkt, pts); } - + return ret; } @@ -416,7 +416,7 @@ int SrsRtspConn::cycle() if (ret == ERROR_SOCKET_CLOSED) { srs_warn("client disconnect peer. ret=%d", ret); } - + return ERROR_SUCCESS; } @@ -425,22 +425,22 @@ void SrsRtspConn::on_thread_stop() if (video_rtp) { caster->free_port(video_rtp->port(), video_rtp->port() + 1); } - + if (audio_rtp) { caster->free_port(audio_rtp->port(), audio_rtp->port() + 1); } - + caster->remove(this); } int SrsRtspConn::on_rtp_video(SrsRtpPacket* pkt, int64_t dts, int64_t pts) { int ret = ERROR_SUCCESS; - + if ((ret = kickoff_audio_cache(pkt, dts)) != ERROR_SUCCESS) { return ret; } - + char* bytes = pkt->payload->bytes(); int length = pkt->payload->length(); uint32_t fdts = (uint32_t)(dts / 90); @@ -448,38 +448,38 @@ int SrsRtspConn::on_rtp_video(SrsRtpPacket* pkt, int64_t dts, int64_t pts) if ((ret = write_h264_ipb_frame(bytes, length, fdts, fpts)) != ERROR_SUCCESS) { return ret; } - + return ret; } int SrsRtspConn::on_rtp_audio(SrsRtpPacket* pkt, int64_t dts) { int ret = ERROR_SUCCESS; - + if ((ret = kickoff_audio_cache(pkt, dts)) != ERROR_SUCCESS) { return ret; } - + // cache current audio to kickoff. acache->dts = dts; acache->audio = pkt->audio; acache->payload = pkt->payload; - + pkt->audio = NULL; pkt->payload = NULL; - + return ret; } int SrsRtspConn::kickoff_audio_cache(SrsRtpPacket* pkt, int64_t dts) { int ret = ERROR_SUCCESS; - + // nothing to kick off. if (!acache->payload) { return ret; } - + if (dts - acache->dts > 0 && acache->audio->nb_samples > 0) { int64_t delta = (dts - acache->dts) / acache->audio->nb_samples; for (int i = 0; i < acache->audio->nb_samples; i++) { @@ -492,30 +492,30 @@ int SrsRtspConn::kickoff_audio_cache(SrsRtpPacket* pkt, int64_t dts) } } } - + acache->dts = 0; srs_freep(acache->audio); srs_freep(acache->payload); - + return ret; } int SrsRtspConn::write_sequence_header() { int ret = ERROR_SUCCESS; - + // use the current dts. int64_t dts = vjitter->timestamp() / 90; - + // send video sps/pps if ((ret = write_h264_sps_pps((uint32_t)dts, (uint32_t)dts)) != ERROR_SUCCESS) { return ret; } - + // generate audio sh by audio specific config. if (true) { std::string sh = aac_specific_config; - + SrsFormat* format = new SrsFormat(); SrsAutoFree(SrsFormat, format); @@ -524,12 +524,12 @@ int SrsRtspConn::write_sequence_header() } SrsAudioCodecConfig* dec = format->acodec; - + acodec->sound_format = SrsAudioCodecIdAAC; acodec->sound_type = (dec->aac_channels == 2)? SrsAudioChannelsStereo : SrsAudioChannelsMono; acodec->sound_size = SrsAudioSampleBits16bit; acodec->aac_packet_type = 0; - + static int srs_aac_srates[] = { 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, @@ -549,12 +549,12 @@ int SrsRtspConn::write_sequence_header() default: break; }; - + if ((ret = write_audio_raw_frame((char*)sh.data(), (int)sh.length(), acodec, (uint32_t)dts)) != ERROR_SUCCESS) { return ret; } } - + return ret; } @@ -582,11 +582,11 @@ int SrsRtspConn::write_h264_sps_pps(uint32_t dts, uint32_t pts) if ((ret = rtmp_write_packet(SrsFrameTypeVideo, timestamp, flv, nb_flv)) != ERROR_SUCCESS) { return ret; } - + return ret; } -int SrsRtspConn::write_h264_ipb_frame(char* frame, int frame_size, uint32_t dts, uint32_t pts) +int SrsRtspConn::write_h264_ipb_frame(char* frame, int frame_size, uint32_t dts, uint32_t pts) { int ret = ERROR_SUCCESS; @@ -600,7 +600,7 @@ int SrsRtspConn::write_h264_ipb_frame(char* frame, int frame_size, uint32_t dts, if (nal_unit_type == SrsAvcNaluTypeIDR) { frame_type = SrsVideoAvcFrameTypeKeyFrame; } - + std::string ibp; if ((ret = avc->mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) { return ret; @@ -621,7 +621,7 @@ int SrsRtspConn::write_h264_ipb_frame(char* frame, int frame_size, uint32_t dts, int SrsRtspConn::write_audio_raw_frame(char* frame, int frame_size, SrsRawAacStreamCodec* codec, uint32_t dts) { int ret = ERROR_SUCCESS; - + char* data = NULL; int size = 0; if ((ret = aac->mux_aac2flv(frame, frame_size, codec, dts, &data, &size)) != ERROR_SUCCESS) { @@ -640,13 +640,13 @@ int SrsRtspConn::rtmp_write_packet(char type, uint32_t timestamp, char* data, in } SrsSharedPtrMessage* msg = NULL; - + if ((ret = srs_rtmp_create_msg(type, timestamp, data, size, sdk->sid(), &msg)) != ERROR_SUCCESS) { srs_error("rtsp: create shared ptr msg failed. ret=%d", ret); return ret; } srs_assert(msg); - + // send out encoded msg. if ((ret = sdk->send_and_free_message(msg)) != ERROR_SUCCESS) { close(); @@ -659,7 +659,7 @@ int SrsRtspConn::rtmp_write_packet(char type, uint32_t timestamp, char* data, in int SrsRtspConn::connect() { int ret = ERROR_SUCCESS; - + // Ignore when connected. if (sdk) { return ret; @@ -671,13 +671,13 @@ int SrsRtspConn::connect() std::string schema, host, vhost, app, param; int port; srs_discovery_tc_url(rtsp_tcUrl, schema, host, vhost, app, port, param); - + // generate output by template. std::string output = output_template; output = srs_string_replace(output, "[app]", app); output = srs_string_replace(output, "[stream]", rtsp_stream); } - + // connect host. int64_t cto = SRS_CONSTS_RTMP_TMMS; int64_t sto = SRS_CONSTS_RTMP_PULSE_TMMS; @@ -695,7 +695,7 @@ int SrsRtspConn::connect() srs_error("rtsp: publish %s failed. ret=%d", url.c_str(), ret); return ret; } - + return write_sequence_header(); } @@ -726,7 +726,7 @@ SrsRtspCaster::~SrsRtspCaster() int SrsRtspCaster::alloc_port(int* pport) { int ret = ERROR_SUCCESS; - + // use a pair of port. for (int i = local_port_min; i < local_port_max - 1; i += 2) { if (!used_ports[i]) { @@ -737,7 +737,7 @@ int SrsRtspCaster::alloc_port(int* pport) } } srs_info("rtsp: alloc port=%d-%d", *pport, *pport + 1); - + return ret; } @@ -752,18 +752,18 @@ void SrsRtspCaster::free_port(int lpmin, int lpmax) int SrsRtspCaster::on_tcp_client(st_netfd_t stfd) { int ret = ERROR_SUCCESS; - + SrsRtspConn* conn = new SrsRtspConn(this, stfd, output); - + if ((ret = conn->serve()) != ERROR_SUCCESS) { srs_error("rtsp: serve client failed. ret=%d", ret); srs_freep(conn); return ret; } - + clients.push_back(conn); srs_info("rtsp: start thread to serve client."); - + return ret; } @@ -774,7 +774,7 @@ void SrsRtspCaster::remove(SrsRtspConn* conn) clients.erase(it); } srs_info("rtsp: remove connection from caster."); - + srs_freep(conn); } diff --git a/trunk/src/app/srs_app_rtsp.hpp b/trunk/src/app/srs_app_rtsp.hpp index 4a9d3314b..98fd042df 100644 --- a/trunk/src/app/srs_app_rtsp.hpp +++ b/trunk/src/app/srs_app_rtsp.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_RTSP_HPP #define SRS_APP_RTSP_HPP -/* -#include -*/ - #include #include @@ -59,8 +55,8 @@ class SrsPithyPrint; class SrsSimpleRtmpClient; /** -* a rtp connection which transport a stream. -*/ + * a rtp connection which transport a stream. + */ class SrsRtpConn: public ISrsUdpHandler { private: @@ -82,21 +78,21 @@ public: }; /** -* audio is group by frames. -*/ + * audio is group by frames. + */ struct SrsRtspAudioCache { int64_t dts; SrsAudioFrame* audio; SrsSimpleStream* payload; - + SrsRtspAudioCache(); virtual ~SrsRtspAudioCache(); }; /** -* the time jitter correct for rtsp. -*/ + * the time jitter correct for rtsp. + */ class SrsRtspJitter { private: @@ -112,8 +108,8 @@ public: }; /** -* the rtsp connection serve the fd. -*/ + * the rtsp connection serve the fd. + */ class SrsRtspConn : public ISrsOneCycleThreadHandler { private: @@ -159,7 +155,7 @@ public: virtual int serve(); private: virtual int do_cycle(); -// internal methods + // internal methods public: virtual int on_rtp_packet(SrsRtpPacket* pkt, int stream_id); // interface ISrsOneCycleThreadHandler @@ -184,8 +180,8 @@ private: }; /** -* the caster for rtsp. -*/ + * the caster for rtsp. + */ class SrsRtspCaster : public ISrsTcpHandler { private: @@ -201,18 +197,18 @@ public: 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 int 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 int on_tcp_client(st_netfd_t stfd); -// internal methods. + // internal methods. public: virtual void remove(SrsRtspConn* conn); }; diff --git a/trunk/src/app/srs_app_security.cpp b/trunk/src/app/srs_app_security.cpp index fb3cc5fb3..affbd04f2 100644 --- a/trunk/src/app/srs_app_security.cpp +++ b/trunk/src/app/srs_app_security.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -77,7 +77,7 @@ int SrsSecurity::allow_check(SrsConfDirective* rules, SrsRtmpConnType type, std: if (rule->name != "allow") { continue; } - + switch (type) { case SrsRtmpConnPlay: if (rule->arg0() != "play") { @@ -122,7 +122,7 @@ int SrsSecurity::deny_check(SrsConfDirective* rules, SrsRtmpConnType type, std:: if (rule->name != "deny") { continue; } - + switch (type) { case SrsRtmpConnPlay: if (rule->arg0() != "play") { diff --git a/trunk/src/app/srs_app_security.hpp b/trunk/src/app/srs_app_security.hpp index 81c131e51..8b6886191 100644 --- a/trunk/src/app/srs_app_security.hpp +++ b/trunk/src/app/srs_app_security.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_SECURITY_HPP #define SRS_APP_SECURITY_HPP -/* -#include -*/ - #include #include @@ -37,9 +33,9 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 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: @@ -47,22 +43,22 @@ public: 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 int 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_server.cpp b/trunk/src/app/srs_app_server.cpp index c6a55c26b..ecfae4e02 100644 --- a/trunk/src/app/srs_app_server.cpp +++ b/trunk/src/app/srs_app_server.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -92,23 +92,23 @@ using namespace std; // SRS_SYS_CYCLE_INTERVAL * SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES #define SRS_SYS_NETWORK_DEVICE_RESOLUTION_TIMES 9 -std::string srs_listener_type2string(SrsListenerType type) +std::string srs_listener_type2string(SrsListenerType type) { switch (type) { - case SrsListenerRtmpStream: - return "RTMP"; - case SrsListenerHttpApi: - return "HTTP-API"; - case SrsListenerHttpStream: - return "HTTP-Server"; - case SrsListenerMpegTsOverUdp: - return "MPEG-TS over UDP"; - case SrsListenerRtsp: - return "RTSP"; - case SrsListenerFlv: - return "HTTP-FLV"; - default: - return "UNKONWN"; + case SrsListenerRtmpStream: + return "RTMP"; + case SrsListenerHttpApi: + return "HTTP-API"; + case SrsListenerHttpStream: + return "HTTP-Server"; + case SrsListenerMpegTsOverUdp: + return "MPEG-TS over UDP"; + case SrsListenerRtsp: + return "RTSP"; + case SrsListenerFlv: + return "HTTP-FLV"; + default: + return "UNKONWN"; } } @@ -144,21 +144,21 @@ int SrsBufferListener::listen(string i, int p) ip = i; port = p; - + srs_freep(listener); listener = new SrsTcpListener(this, ip, port); - + if ((ret = listener->listen()) != ERROR_SUCCESS) { srs_error("tcp listen failed. ret=%d", ret); return ret; } srs_info("listen thread current_cid=%d, " - "listen at port=%d, type=%d, fd=%d started success, ep=%s:%d", - _srs_context->get_id(), p, type, listener->fd(), i.c_str(), p); - + "listen at port=%d, type=%d, fd=%d started success, ep=%s:%d", + _srs_context->get_id(), p, type, listener->fd(), i.c_str(), p); + srs_trace("%s listen at tcp://%s:%d, fd=%d", srs_listener_type2string(type).c_str(), ip.c_str(), port, listener->fd()); - + return ret; } @@ -170,7 +170,7 @@ int SrsBufferListener::on_tcp_client(st_netfd_t stfd) srs_warn("accept client error. ret=%d", ret); return ret; } - + return ret; } @@ -178,7 +178,7 @@ int SrsBufferListener::on_tcp_client(st_netfd_t stfd) SrsRtspListener::SrsRtspListener(SrsServer* svr, SrsListenerType t, SrsConfDirective* c) : SrsListener(svr, t) { listener = NULL; - + // the caller already ensure the type is ok, // we just assert here for unknown stream caster. srs_assert(type == SrsListenerRtsp); @@ -196,25 +196,25 @@ SrsRtspListener::~SrsRtspListener() int SrsRtspListener::listen(string i, int p) { int ret = ERROR_SUCCESS; - + // the caller already ensure the type is ok, // we just assert here for unknown stream caster. srs_assert(type == SrsListenerRtsp); ip = i; port = p; - + srs_freep(listener); listener = new SrsTcpListener(this, ip, port); - + if ((ret = listener->listen()) != ERROR_SUCCESS) { srs_error("rtsp caster listen failed. ret=%d", ret); return ret; } srs_info("listen thread listen at port=%d, type=%d, fd=%d started success, ep=%s:%d", port, type, listener->fd(), ip.c_str(), port); - + srs_trace("%s listen at tcp://%s:%d, fd=%d", srs_listener_type2string(type).c_str(), ip.c_str(), port, listener->fd()); - + return ret; } @@ -226,7 +226,7 @@ int SrsRtspListener::on_tcp_client(st_netfd_t stfd) srs_warn("accept client error. ret=%d", ret); return ret; } - + return ret; } @@ -305,34 +305,34 @@ SrsUdpStreamListener::~SrsUdpStreamListener() int SrsUdpStreamListener::listen(string i, int p) { int ret = ERROR_SUCCESS; - + // the caller already ensure the type is ok, // we just assert here for unknown stream caster. srs_assert(type == SrsListenerMpegTsOverUdp); ip = i; port = p; - + srs_freep(listener); listener = new SrsUdpListener(caster, ip, port); - + if ((ret = listener->listen()) != ERROR_SUCCESS) { srs_error("udp caster listen failed. ret=%d", ret); return ret; } srs_info("listen thread current_cid=%d, " - "listen at port=%d, type=%d, fd=%d started success, ep=%s:%d", - _srs_context->get_id(), p, type, listener->fd(), i.c_str(), p); + "listen at port=%d, type=%d, fd=%d started success, ep=%s:%d", + _srs_context->get_id(), p, type, listener->fd(), i.c_str(), p); // notify the handler the fd changed. if ((ret = caster->on_stfd_change(listener->stfd())) != ERROR_SUCCESS) { srs_error("notify handler fd changed. ret=%d", ret); return ret; } - + srs_trace("%s listen at udp://%s:%d, fd=%d", srs_listener_type2string(type).c_str(), ip.c_str(), port, listener->fd()); - + return ret; } @@ -430,7 +430,7 @@ int SrsSignalManager::start() sigaction(SRS_SIGNAL_REOPEN_LOG, &sa, NULL); srs_trace("signal installed, reload=%d, reopen=%d, grace_quit=%d", - SRS_SIGNAL_RELOAD, SRS_SIGNAL_REOPEN_LOG, SRS_SIGNAL_GRACEFULLY_QUIT); + SRS_SIGNAL_RELOAD, SRS_SIGNAL_REOPEN_LOG, SRS_SIGNAL_GRACEFULLY_QUIT); return pthread->start(); } @@ -438,7 +438,7 @@ int SrsSignalManager::start() int SrsSignalManager::cycle() { int ret = ERROR_SUCCESS; - + int signo; /* Read the next signal from the pipe */ @@ -511,7 +511,7 @@ void SrsServer::destroy() srs_freep(http_api_mux); srs_freep(http_server); srs_freep(http_heartbeat); - + #ifdef SRS_AUTO_INGEST srs_freep(ingester); #endif @@ -546,7 +546,7 @@ void SrsServer::dispose() SrsSource::dispose_all(); // @remark don't dispose all connections, for too slow. - + #ifdef SRS_AUTO_MEM_WATCH srs_memory_report(); #endif @@ -582,12 +582,12 @@ int SrsServer::initialize(ISrsServerCycle* cycle_handler) } http_heartbeat = new SrsHttpHeartbeat(); - + #ifdef SRS_AUTO_INGEST srs_assert(!ingester); ingester = new SrsIngester(); #endif - + return ret; } @@ -604,7 +604,7 @@ int SrsServer::initialize_st() // @remark, st alloc segment use mmap, which only support 32757 threads, // if need to support more, for instance, 100k threads, define the macro MALLOC_STACK. // TODO: FIXME: maybe can use "sysctl vm.max_map_count" to refine. - #define __MMAP_MAX_CONNECTIONS 32756 +#define __MMAP_MAX_CONNECTIONS 32756 if (_srs_config->get_max_connections() > __MMAP_MAX_CONNECTIONS) { ret = ERROR_ST_EXCEED_THREADS; srs_error("st mmap for stack allocation must <= %d threads, " @@ -632,7 +632,7 @@ int SrsServer::initialize_st() return ret; } srs_trace("server main cid=%d, pid=%d, ppid=%d, asprocess=%d", - _srs_context->get_id(), ::getpid(), ppid, asprocess); + _srs_context->get_id(), ::getpid(), ppid, asprocess); return ret; } @@ -653,7 +653,7 @@ int SrsServer::acquire_pid_file() std::string pid_file = _srs_config->get_pid_file(); - // -rw-r--r-- + // -rw-r--r-- // 644 int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; @@ -667,7 +667,7 @@ int SrsServer::acquire_pid_file() // require write lock struct flock lock; - + lock.l_type = F_WRLCK; // F_RDLCK, F_WRLCK, F_UNLCK lock.l_start = 0; // type offset, relative to l_whence lock.l_whence = SEEK_SET; // SEEK_SET, SEEK_CUR, SEEK_END @@ -684,7 +684,7 @@ int SrsServer::acquire_pid_file() srs_error("require lock for file %s error! ret=%#x", pid_file.c_str(), ret); return ret; } - + // truncate file if (ftruncate(fd, 0) < 0) { ret = ERROR_SYSTEM_PID_TRUNCATE_FILE; @@ -699,7 +699,7 @@ int SrsServer::acquire_pid_file() srs_error("write our pid error! pid=%s file=%s ret=%#x", pid.c_str(), pid_file.c_str(), ret); return ret; } - + // auto close when fork child process. int val; if ((val = fcntl(fd, F_GETFD, 0)) < 0) { @@ -825,7 +825,7 @@ int SrsServer::http_handle() return ret; } srs_trace("http: api mount /console to %s", dir.c_str()); - + return ret; } @@ -839,16 +839,16 @@ int SrsServer::ingest() return ret; } #endif - + return ret; } int SrsServer::cycle() { int ret = ERROR_SUCCESS; - + ret = do_cycle(); - + #ifdef SRS_AUTO_GPERF_MC destroy(); @@ -874,7 +874,7 @@ int SrsServer::cycle() void SrsServer::on_signal(int signo) -{ +{ if (signo == SRS_SIGNAL_RELOAD) { signal_reload = true; return; @@ -949,7 +949,7 @@ int SrsServer::do_cycle() srs_error("cycle handle failed. ret=%d", ret); return ret; } - + // the interval in config. int heartbeat_max_resolution = (int)(_srs_config->get_heartbeat_interval() / SRS_SYS_CYCLE_INTERVAL); @@ -970,7 +970,7 @@ int SrsServer::do_cycle() srs_trace("cleanup for gracefully terminate."); return ret; } - + // for gperf heap checker, // @see: research/gperftools/heap-checker/heap_checker.cc // if user interrupt the program, exit to check mem leak. @@ -994,7 +994,7 @@ int SrsServer::do_cycle() } srs_trace("persistence config to file success."); } - + // do reload the config. if (signal_reload) { signal_reload = false; @@ -1058,7 +1058,7 @@ int SrsServer::do_cycle() srs_info("server main thread loop"); } } - + return ret; } @@ -1146,15 +1146,15 @@ int SrsServer::listen_stream_caster() std::vector::iterator it; std::vector stream_casters = _srs_config->get_stream_casters(); - + for (it = stream_casters.begin(); it != stream_casters.end(); ++it) { SrsConfDirective* stream_caster = *it; if (!_srs_config->get_stream_caster_enabled(stream_caster)) { continue; } - + SrsListener* listener = NULL; - + std::string caster = _srs_config->get_stream_caster_engine(stream_caster); if (srs_stream_caster_is_udp(caster)) { listener = new SrsUdpCasterListener(this, SrsListenerMpegTsOverUdp, stream_caster); @@ -1168,7 +1168,7 @@ int SrsServer::listen_stream_caster() return ret; } srs_assert(listener != NULL); - + listeners.push_back(listener); int port = _srs_config->get_stream_caster_listen(stream_caster); @@ -1219,7 +1219,7 @@ void SrsServer::resample_kbps() } // TODO: FXME: support all other connections. - + // sample the kbps, get the stat. SrsKbps* kbps = stat->kbps_sample(); @@ -1265,7 +1265,7 @@ SrsConnection* SrsServer::fd2conn(SrsListenerType type, st_netfd_t stfd) srs_info("ignore empty ip client, fd=%d.", fd); return NULL; } - + // check connection limitation. int max_connections = _srs_config->get_max_connections(); if (handler && (ret = handler->on_accept_client(max_connections, (int)conns.size()) != ERROR_SUCCESS)) { @@ -1361,7 +1361,7 @@ int SrsServer::on_reload_vhost_added(std::string vhost) if ((ret = on_reload_vhost_http_updated()) != ERROR_SUCCESS) { return ret; } - + return ret; } @@ -1373,7 +1373,7 @@ int SrsServer::on_reload_vhost_removed(std::string /*vhost*/) if ((ret = on_reload_vhost_http_updated()) != ERROR_SUCCESS) { return ret; } - + return ret; } diff --git a/trunk/src/app/srs_app_server.hpp b/trunk/src/app/srs_app_server.hpp index 4b3a75cc4..65ab54587 100644 --- a/trunk/src/app/srs_app_server.hpp +++ b/trunk/src/app/srs_app_server.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_SERVER_HPP #define SRS_APP_SERVER_HPP -/* -#include -*/ - #include #include @@ -61,7 +57,7 @@ class SrsKafkaProducer; // listener type for server to identify the connection, // that is, use different type to process the connection. -enum SrsListenerType +enum SrsListenerType { // RTMP client, SrsListenerRtmpStream = 0, @@ -78,8 +74,8 @@ enum SrsListenerType }; /** -* the common tcp listener, for RTMP/HTTP server. -*/ + * the common tcp listener, for RTMP/HTTP server. + */ class SrsListener { protected: @@ -97,8 +93,8 @@ public: }; /** -* tcp listener. -*/ + * tcp listener. + */ class SrsBufferListener : virtual public SrsListener, virtual public ISrsTcpHandler { private: @@ -108,15 +104,15 @@ public: virtual ~SrsBufferListener(); public: virtual int listen(std::string ip, int port); -// ISrsTcpHandler + // ISrsTcpHandler public: virtual int on_tcp_client(st_netfd_t stfd); }; #ifdef SRS_AUTO_STREAM_CASTER /** -* the tcp listener, for rtsp server. -*/ + * the tcp listener, for rtsp server. + */ class SrsRtspListener : virtual public SrsListener, virtual public ISrsTcpHandler { private: @@ -127,7 +123,7 @@ public: virtual ~SrsRtspListener(); public: virtual int listen(std::string i, int p); -// ISrsTcpHandler + // ISrsTcpHandler public: virtual int on_tcp_client(st_netfd_t stfd); }; @@ -145,7 +141,7 @@ public: virtual ~SrsHttpFlvListener(); public: virtual int listen(std::string i, int p); -// ISrsTcpHandler + // ISrsTcpHandler public: virtual int on_tcp_client(st_netfd_t stfd); }; @@ -179,9 +175,9 @@ public: #endif /** -* 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 ISrsEndlessThreadHandler { private: @@ -210,21 +206,21 @@ private: }; /** -* the handler to the handle cycle in SRS RTMP server. -*/ + * the handler to the handle cycle in SRS RTMP server. + */ class ISrsServerCycle { public: ISrsServerCycle(); virtual ~ISrsServerCycle(); -public: +public: /** - * initialize the cycle handler. - */ + * initialize the cycle handler. + */ virtual int initialize() = 0; /** - * do on_cycle while server doing cycle. - */ + * do on_cycle while server doing cycle. + */ virtual int on_cycle() = 0; /** * callback the handler when got client. @@ -233,12 +229,12 @@ public: }; /** -* SRS RTMP server, initialize and listen, -* start connection service thread, destroy client. -*/ + * SRS RTMP server, initialize and listen, + * start connection service thread, destroy client. + */ class SrsServer : virtual public ISrsReloadHandler - , virtual public ISrsSourceHandler - , virtual public IConnectionManager +, virtual public ISrsSourceHandler +, virtual public IConnectionManager { private: // TODO: FIXME: rename to http_api @@ -250,31 +246,31 @@ private: #endif 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; @@ -286,17 +282,17 @@ public: 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, + * 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() + // server startup workflow, @see run_master() public: /** * initialize server with callback handler. @@ -311,7 +307,7 @@ public: virtual int http_handle(); virtual int ingest(); virtual int cycle(); -// server utilities. + // server utilities. public: /** * callback for signal manager got a signal. @@ -330,39 +326,39 @@ public: 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 int do_cycle(); /** - * listen at specified protocol. - */ + * listen at specified protocol. + */ virtual int listen_rtmp(); virtual int listen_http_api(); virtual int listen_http_stream(); virtual int 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 + // 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 int accept_client(SrsListenerType type, st_netfd_t stfd); private: virtual SrsConnection* fd2conn(SrsListenerType type, st_netfd_t stfd); -// IConnectionManager + // IConnectionManager public: /** * callback for connection to remove itself. diff --git a/trunk/src/app/srs_app_source.cpp b/trunk/src/app/srs_app_source.cpp index 143bdcf72..08793fd8e 100755 --- a/trunk/src/app/srs_app_source.cpp +++ b/trunk/src/app/srs_app_source.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -95,7 +95,7 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag) if (ag == SrsRtmpJitterAlgorithmOFF) { return ret; } - + // start at zero, but donot ensure monotonically increasing. if (ag == SrsRtmpJitterAlgorithmZERO) { // for the first time, last_pkt_correct_time is -1. @@ -118,18 +118,18 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag) } /** - * we use a very simple time jitter detect/correct algorithm: - * 1. delta: ensure the delta is positive and valid, - * we set the delta to DEFAULT_FRAME_TIME_MS, - * if the delta of time is nagative or greater than CONST_MAX_JITTER_MS. - * 2. last_pkt_time: specifies the original packet time, - * is used to detect next jitter. - * 3. last_pkt_correct_time: simply add the positive delta, - * and enforce the time monotonically. - */ + * we use a very simple time jitter detect/correct algorithm: + * 1. delta: ensure the delta is positive and valid, + * we set the delta to DEFAULT_FRAME_TIME_MS, + * if the delta of time is nagative or greater than CONST_MAX_JITTER_MS. + * 2. last_pkt_time: specifies the original packet time, + * is used to detect next jitter. + * 3. last_pkt_correct_time: simply add the positive delta, + * and enforce the time monotonically. + */ int64_t time = msg->timestamp; int64_t delta = time - last_pkt_time; - + // if jitter detected, reset the delta. if (delta < CONST_MAX_JITTER_MS_NEG || delta > CONST_MAX_JITTER_MS) { // use default 10ms to notice the problem of stream. @@ -137,10 +137,10 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag) delta = DEFAULT_FRAME_TIME_MS; srs_info("jitter detected, last_pts=%"PRId64", pts=%"PRId64", diff=%"PRId64", last_time=%"PRId64", time=%"PRId64", diff=%"PRId64"", - last_pkt_time, time, time - last_pkt_time, last_pkt_correct_time, last_pkt_correct_time + delta, delta); + last_pkt_time, time, time - last_pkt_time, last_pkt_correct_time, last_pkt_correct_time + delta, delta); } else { - srs_verbose("timestamp no jitter. time=%"PRId64", last_pkt=%"PRId64", correct_to=%"PRId64"", - time, last_pkt_time, last_pkt_correct_time + delta); + srs_verbose("timestamp no jitter. time=%"PRId64", last_pkt=%"PRId64", correct_to=%"PRId64"", + time, last_pkt_time, last_pkt_correct_time + delta); } last_pkt_correct_time = srs_max(0, last_pkt_correct_time + delta); @@ -284,7 +284,7 @@ int SrsMessageQueue::enqueue(SrsSharedPtrMessage* msg, bool* is_overflow) } msgs.push_back(msg); - + while (av_end_time - av_start_time > queue_size_ms) { // notice the caller queue already overflow and shrinked. if (is_overflow) { @@ -308,7 +308,7 @@ int SrsMessageQueue::dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, in srs_assert(max_count > 0); count = srs_min(max_count, nb_msgs); - + SrsSharedPtrMessage** omsgs = msgs.data(); for (int i = 0; i < count; i++) { pmsgs[i] = omsgs[i]; @@ -339,7 +339,7 @@ int SrsMessageQueue::dump_packets(SrsConsumer* consumer, bool atc, SrsRtmpJitter if (nb_msgs <= 0) { return ret; } - + SrsSharedPtrMessage** omsgs = msgs.data(); for (int i = 0; i < nb_msgs; i++) { SrsSharedPtrMessage* msg = omsgs[i]; @@ -361,7 +361,7 @@ void SrsMessageQueue::shrink() // igone the sequence header for (int i = 0; i < (int)msgs.size(); i++) { SrsSharedPtrMessage* msg = msgs.at(i); - + if (msg->is_video() && SrsFlvVideo::sh(msg->payload, msg->size)) { srs_freep(video_sh); video_sh = msg; @@ -372,11 +372,11 @@ void SrsMessageQueue::shrink() audio_sh = msg; continue; } - + srs_freep(msg); } - msgs.clear(); - + msgs.clear(); + // update av_start_time av_start_time = av_end_time; //push_back secquence header and update timestamp @@ -390,11 +390,11 @@ void SrsMessageQueue::shrink() } if (_ignore_shrink) { - srs_info("shrink the cache queue, size=%d, removed=%d, max=%.2f", - (int)msgs.size(), msgs_size - (int)msgs.size(), queue_size_ms / 1000.0); + srs_info("shrink the cache queue, size=%d, removed=%d, max=%.2f", + (int)msgs.size(), msgs_size - (int)msgs.size(), queue_size_ms / 1000.0); } else { - srs_trace("shrink the cache queue, size=%d, removed=%d, max=%.2f", - (int)msgs.size(), msgs_size - (int)msgs.size(), queue_size_ms / 1000.0); + srs_trace("shrink the cache queue, size=%d, removed=%d, max=%.2f", + (int)msgs.size(), msgs_size - (int)msgs.size(), queue_size_ms / 1000.0); } } @@ -402,7 +402,7 @@ void SrsMessageQueue::clear() { #ifndef SRS_PERF_QUEUE_FAST_VECTOR std::vector::iterator it; - + for (it = msgs.begin(); it != msgs.end(); ++it) { SrsSharedPtrMessage* msg = *it; srs_freep(msg); @@ -410,7 +410,7 @@ void SrsMessageQueue::clear() #else msgs.free(); #endif - + msgs.clear(); av_start_time = av_end_time = -1; @@ -472,7 +472,7 @@ int SrsConsumer::enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitte int ret = ERROR_SUCCESS; SrsSharedPtrMessage* msg = shared_msg->copy(); - + if (!atc) { if ((ret = jitter->correct(msg, ag)) != ERROR_SUCCESS) { srs_freep(msg); @@ -485,9 +485,9 @@ int SrsConsumer::enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitte } #ifdef SRS_PERF_QUEUE_COND_WAIT - srs_verbose("enqueue msg, time=%"PRId64", size=%d, duration=%d, waiting=%d, min_msg=%d", - msg->timestamp, msg->size, queue->duration(), mw_waiting, mw_min_msgs); - + srs_verbose("enqueue msg, time=%"PRId64", size=%d, duration=%d, waiting=%d, min_msg=%d", + msg->timestamp, msg->size, queue->duration(), mw_waiting, mw_min_msgs); + // fire the mw when msgs is enough. if (mw_waiting) { int duration_ms = queue->duration(); @@ -537,7 +537,7 @@ int SrsConsumer::dump_packets(SrsMessageArray* msgs, int& count) if (paused) { return ret; } - + // pump msgs from queue. if ((ret = queue->dump_packets(max, msgs->msgs, count)) != ERROR_SUCCESS) { return ret; @@ -553,10 +553,10 @@ void SrsConsumer::wait(int nb_msgs, int duration) st_usleep(SRS_CONSTS_RTMP_PULSE_TMMS); return; } - + mw_min_msgs = nb_msgs; mw_duration = duration; - + int duration_ms = queue->duration(); bool match_min_msgs = queue->size() > mw_min_msgs; @@ -636,7 +636,7 @@ int SrsGopCache::cache(SrsSharedPtrMessage* shared_msg) srs_verbose("gop cache is disabled."); return ret; } - + // the gop cache know when to gop it. SrsSharedPtrMessage* msg = shared_msg; @@ -673,8 +673,8 @@ int SrsGopCache::cache(SrsSharedPtrMessage* shared_msg) // clear gop cache when got key frame if (msg->is_video() && SrsFlvVideo::keyframe(msg->payload, msg->size)) { srs_info("clear gop cache when got keyframe. vcount=%d, count=%d", - cached_video_count, (int)gop_cache.size()); - + cached_video_count, (int)gop_cache.size()); + clear(); // curent msg is video frame, so we set to 1. @@ -695,11 +695,11 @@ void SrsGopCache::clear() srs_freep(msg); } gop_cache.clear(); - + cached_video_count = 0; audio_after_last_video_count = 0; } - + int SrsGopCache::dump(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm jitter_algorithm) { int ret = ERROR_SUCCESS; @@ -987,10 +987,10 @@ int SrsOriginHub::on_audio(SrsSharedPtrMessage* shared_audio) } srs_trace("%dB audio sh, codec(%d, profile=%s, %dchannels, %dkbps, %dHZ), flv(%dbits, %dchannels, %dHZ)", - msg->size, c->id, srs_aac_object2str(c->aac_object).c_str(), c->aac_channels, - c->audio_data_rate / 1000, srs_aac_srates[c->aac_sample_rate], - flv_sample_sizes[c->sound_size], flv_sound_types[c->sound_type], - srs_flv_srates[c->sound_rate]); + msg->size, c->id, srs_aac_object2str(c->aac_object).c_str(), c->aac_channels, + c->audio_data_rate / 1000, srs_aac_srates[c->aac_sample_rate], + flv_sample_sizes[c->sound_size], flv_sound_types[c->sound_type], + srs_flv_srates[c->sound_rate]); } if ((ret = hls->on_audio(msg, format)) != ERROR_SUCCESS) { @@ -1090,9 +1090,9 @@ int SrsOriginHub::on_video(SrsSharedPtrMessage* shared_video, bool is_sequence_h } srs_trace("%dB video sh, codec(%d, profile=%s, level=%s, %dx%d, %dkbps, %.1ffps, %.1fs)", - msg->size, c->id, srs_avc_profile2str(c->avc_profile).c_str(), - srs_avc_level2str(c->avc_level).c_str(), c->width, c->height, - c->video_data_rate / 1000, c->frame_rate, c->duration); + msg->size, c->id, srs_avc_profile2str(c->avc_profile).c_str(), + srs_avc_level2str(c->avc_level).c_str(), c->width, c->height, + c->video_data_rate / 1000, c->frame_rate, c->duration); } if ((ret = hls->on_video(msg, format)) != ERROR_SUCCESS) { @@ -1742,13 +1742,13 @@ int SrsSource::fetch_or_create(SrsRequest* r, ISrsSourceHandler* h, SrsSource** // should always not exists for create a source. srs_assert (pool.find(stream_url) == pool.end()); - + source = new SrsSource(); if ((ret = source->initialize(r, h)) != ERROR_SUCCESS) { srs_freep(source); return ret; } - + pool[stream_url] = source; srs_info("create new source for url=%s, vhost=%s", stream_url.c_str(), vhost.c_str()); @@ -1765,14 +1765,14 @@ SrsSource* SrsSource::fetch(SrsRequest* r) if (pool.find(stream_url) == pool.end()) { return NULL; } - + source = pool[stream_url]; - - // we always update the request of resource, + + // we always update the request of resource, // for origin auth is on, the token in request maybe invalid, // and we only need to update the token of request, it's simple. source->req->update_auth(r); - + return source; } @@ -1877,7 +1877,7 @@ SrsSource::~SrsSource() { _srs_config->unsubscribe(this); - // never free the consumers, + // never free the consumers, // for all consumers are auto free. consumers.clear(); @@ -1889,7 +1889,7 @@ SrsSource::~SrsSource() srs_freep(publish_edge); srs_freep(gop_cache); srs_freep(aggregate_stream); - + srs_freep(req); } @@ -1936,7 +1936,7 @@ int SrsSource::initialize(SrsRequest* r, ISrsSourceHandler* h) srs_assert(h); srs_assert(!req); - + handler = h; req = r->copy(); atc = _srs_config->get_atc(req->vhost); @@ -1944,7 +1944,7 @@ int SrsSource::initialize(SrsRequest* r, ISrsSourceHandler* h) if ((ret = hub->initialize(this, req)) != ERROR_SUCCESS) { return ret; } - + if ((ret = play_edge->initialize(this, req)) != ERROR_SUCCESS) { return ret; } @@ -2085,7 +2085,7 @@ bool SrsSource::can_publish(bool is_edge) if (is_edge) { return publish_edge->can_publish(); } - + return _can_publish; } @@ -2216,7 +2216,7 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) if ((ret = hub->on_audio(msg)) != ERROR_SUCCESS) { return ret; } - + // cache the sequence header of aac, or first packet of mp3. // for example, the mp3 is used for hls to write the "right" audio codec. // TODO: FIXME: to refine the stream info system. @@ -2352,7 +2352,7 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) if (is_sequence_header) { return ret; } - + // cache the last gop packets if ((ret = gop_cache->cache(msg)) != ERROR_SUCCESS) { srs_error("gop cache msg failed. ret=%d", ret); @@ -2452,7 +2452,7 @@ int SrsSource::on_aggregate(SrsCommonMessage* msg) o.header.timestamp = timestamp; o.header.stream_id = stream_id; o.header.perfer_cid = msg->header.perfer_cid; - + if (data_size > 0) { o.size = data_size; o.payload = new char[o.size]; @@ -2465,7 +2465,7 @@ int SrsSource::on_aggregate(SrsCommonMessage* msg) return ret; } stream->read_4bytes(); - + // process parsed message if (o.header.is_audio()) { if ((ret = on_audio(&o)) != ERROR_SUCCESS) { @@ -2507,7 +2507,7 @@ int SrsSource::on_publish() if ((ret = hub->on_publish()) != ERROR_SUCCESS) { return ret; } - + // notify the handler. srs_assert(handler); if ((ret = handler->on_publish(this, req)) != ERROR_SUCCESS) { @@ -2529,7 +2529,7 @@ void SrsSource::on_unpublish() // Notify the hub about the unpublish event. hub->on_unpublish(); - + // only clear the gop cache, // donot clear the sequence header, for it maybe not changed, // when drop dup sequence header, drop the metadata also. @@ -2540,7 +2540,7 @@ void SrsSource::on_unpublish() _can_publish = true; _source_id = -1; - + // notify the handler. srs_assert(handler); SrsStatistic* stat = SrsStatistic::instance(); @@ -2592,7 +2592,7 @@ int SrsSource::create_consumer(SrsConnection* conn, SrsConsumer*& consumer, bool } else { srs_trace("create consumer, ignore gop cache, jitter=%d", jitter_algorithm); } - + // for edge, when play edge stream, check the state if (_srs_config->get_vhost_is_edge(req->vhost)) { // notice edge to start for the first client. diff --git a/trunk/src/app/srs_app_source.hpp b/trunk/src/app/srs_app_source.hpp index b4d5ad3c1..2d7b06237 100644 --- a/trunk/src/app/srs_app_source.hpp +++ b/trunk/src/app/srs_app_source.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_SOURCE_HPP #define SRS_APP_SOURCE_HPP -/* -#include -*/ - #include #include @@ -67,11 +63,11 @@ 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, @@ -81,9 +77,9 @@ 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: @@ -94,22 +90,22 @@ public: 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 int correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag); /** - * get current client time, the last packet time. - */ + * get current client time, the last packet time. + */ virtual int 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: @@ -133,9 +129,9 @@ 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: @@ -153,24 +149,24 @@ public: 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 int duration(); /** - * set the queue size - * @param queue_size the queue size in seconds. - */ + * set the queue size + * @param queue_size the queue size in seconds. + */ virtual void set_queue_size(double 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 int enqueue(SrsSharedPtrMessage* msg, bool* is_overflow = NULL); /** * get packets in consumer queue. @@ -180,15 +176,15 @@ public: */ virtual int 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 int 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: /** @@ -216,8 +212,8 @@ public: }; /** -* the consumer for SrsSource, that is a play client. -*/ + * the consumer for SrsSource, that is a play client. + */ class SrsConsumer : public ISrsWakable { private: @@ -242,24 +238,24 @@ public: virtual ~SrsConsumer(); public: /** - * set the size of queue. - */ + * set the size of queue. + */ virtual void set_queue_size(double 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 int 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 int enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitterAlgorithm ag); /** * get packets in consumer queue. @@ -270,17 +266,17 @@ public: virtual int 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 duration the messgae duration to wait. - */ + * wait for messages incomming, atleast nb_msgs and in duration. + * @param nb_msgs the messages count to wait. + * @param duration the messgae duration to wait. + */ virtual void wait(int nb_msgs, int duration); #endif /** - * when client send the pause message. - */ + * when client send the pause message. + */ virtual int on_play_client_pause(bool is_pause); -// ISrsWakable + // ISrsWakable public: /** * when the consumer(for player) got msg from recv thread, @@ -291,39 +287,39 @@ public: }; /** -* 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(); @@ -334,47 +330,47 @@ public: */ 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 int 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 int 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 ms. - * @return 0 if no packets. - */ + * get the start time of gop cache, in ms. + * @return 0 if no packets. + */ virtual int64_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: @@ -382,12 +378,12 @@ public: virtual ~ISrsSourceHandler(); public: /** - * when stream start publish, mount stream. - */ + * when stream start publish, mount stream. + */ virtual int 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; }; @@ -467,7 +463,7 @@ public: virtual int on_publish(); // When stop publish stream. virtual void on_unpublish(); -// Internal callback. + // Internal callback. public: // for the SrsForwarder to callback to request the sequence headers. virtual int on_forwarder_start(SrsForwarder* forwarder); @@ -527,8 +523,8 @@ public: }; /** -* live streaming source. -*/ + * live streaming source. + */ class SrsSource : public ISrsReloadHandler { friend class SrsOriginHub; @@ -536,17 +532,17 @@ 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 int 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: /** @@ -558,9 +554,9 @@ private: static int 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, @@ -607,8 +603,8 @@ private: SrsMetaCache* meta; private: /** - * can publish, true when is not streaming - */ + * can publish, true when is not streaming + */ bool _can_publish; // last die time, when all consumers quit and no publisher, // we will remove the source when source die. @@ -621,23 +617,23 @@ public: virtual int cycle(); // remove source when expired. virtual bool expired(); -// initialize, get and setter. + // initialize, get and setter. public: /** - * initialize the hls with handlers. - */ + * initialize the hls with handlers. + */ virtual int initialize(SrsRequest* r, ISrsSourceHandler* h); // interface ISrsReloadHandler public: virtual int on_reload_vhost_play(std::string vhost); -// for the tools callback + // for the tools callback public: // source id changed. virtual int on_source_id_changed(int id); // get current source id. virtual int source_id(); virtual int pre_source_id(); -// logic data methods + // logic data methods public: virtual bool can_publish(bool is_edge); virtual int on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata); @@ -652,29 +648,26 @@ private: public: virtual int 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 int on_publish(); virtual void on_unpublish(); -// consumer methods + // 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. - */ - virtual int create_consumer( - SrsConnection* conn, SrsConsumer*& consumer, - bool ds = true, bool dm = true, bool dg = true - ); + * 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 int 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 + // internal public: // for edge, when publish edge stream, check the state virtual int on_edge_start_publish(); diff --git a/trunk/src/app/srs_app_st.cpp b/trunk/src/app/srs_app_st.cpp index 5bc2e925c..125a6d5ce 100755 --- a/trunk/src/app/srs_app_st.cpp +++ b/trunk/src/app/srs_app_st.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -501,12 +501,12 @@ int SrsTcpClient::writev(const iovec *iov, int iov_size, ssize_t* nwrite) bool srs_st_epoll_is_supported(void) { struct epoll_event ev; - + ev.events = EPOLLIN; ev.data.ptr = NULL; /* Guaranteed to fail */ epoll_ctl(-1, EPOLL_CTL_ADD, -1, &ev); - + return (errno != ENOSYS); } #endif @@ -533,7 +533,7 @@ int srs_st_init() return ret; } srs_info("st_set_eventsys to %s", st_get_eventsys_name()); - + if(st_init() != 0){ ret = ERROR_ST_INITIALIZE; srs_error("st_init failed. ret=%d", ret); diff --git a/trunk/src/app/srs_app_st.hpp b/trunk/src/app/srs_app_st.hpp index c0af8e599..116cbd6c6 100644 --- a/trunk/src/app/srs_app_st.hpp +++ b/trunk/src/app/srs_app_st.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_ST_HPP #define SRS_APP_ST_HPP -/* -#include -*/ - #include #include diff --git a/trunk/src/app/srs_app_statistic.cpp b/trunk/src/app/srs_app_statistic.cpp index c3b8cb999..ff24baeee 100644 --- a/trunk/src/app/srs_app_statistic.cpp +++ b/trunk/src/app/srs_app_statistic.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -308,15 +308,13 @@ SrsStatisticClient* SrsStatistic::find_client(int cid) return NULL; } -int SrsStatistic::on_video_info(SrsRequest* req, - SrsVideoCodecId vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level, - int width, int height -) { +int SrsStatistic::on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level, int width, int height) +{ int ret = ERROR_SUCCESS; SrsStatisticVhost* vhost = create_vhost(req); SrsStatisticStream* stream = create_stream(vhost, req); - + stream->has_video = true; stream->vcodec = vcodec; stream->avc_profile = avc_profile; @@ -328,15 +326,13 @@ int SrsStatistic::on_video_info(SrsRequest* req, return ret; } -int SrsStatistic::on_audio_info(SrsRequest* req, - SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, - SrsAacObjectType aac_object -) { +int SrsStatistic::on_audio_info(SrsRequest* req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, SrsAacObjectType aac_object) +{ int ret = ERROR_SUCCESS; SrsStatisticVhost* vhost = create_vhost(req); SrsStatisticStream* stream = create_stream(vhost, req); - + stream->has_audio = true; stream->acodec = acodec; stream->asample_rate = asample_rate; @@ -350,7 +346,7 @@ void SrsStatistic::on_stream_publish(SrsRequest* req, int cid) { SrsStatisticVhost* vhost = create_vhost(req); SrsStatisticStream* stream = create_stream(vhost, req); - + stream->publish(cid); } @@ -383,7 +379,7 @@ int SrsStatistic::on_client(int id, SrsRequest* req, SrsConnection* conn, SrsRtm SrsStatisticVhost* vhost = create_vhost(req); SrsStatisticStream* stream = create_stream(vhost, req); - + // create client if not exists SrsStatisticClient* client = NULL; if (clients.find(id) == clients.end()) { @@ -401,7 +397,7 @@ int SrsStatistic::on_client(int id, SrsRequest* req, SrsConnection* conn, SrsRtm client->type = type; stream->nb_clients++; vhost->nb_clients++; - + return ret; } @@ -411,7 +407,7 @@ void SrsStatistic::on_disconnect(int id) if ((it = clients.find(id)) == clients.end()) { return; } - + SrsStatisticClient* client = it->second; SrsStatisticStream* stream = client->stream; SrsStatisticVhost* vhost = stream->vhost; @@ -474,7 +470,7 @@ int64_t SrsStatistic::server_id() int SrsStatistic::dumps_vhosts(SrsJsonArray* arr) { int ret = ERROR_SUCCESS; - + std::map::iterator it; for (it = vhosts.begin(); it != vhosts.end(); it++) { SrsStatisticVhost* vhost = it->second; @@ -486,7 +482,7 @@ int SrsStatistic::dumps_vhosts(SrsJsonArray* arr) return ret; } } - + return ret; } @@ -500,7 +496,7 @@ int SrsStatistic::dumps_streams(SrsJsonArray* arr) SrsJsonObject* obj = SrsJsonAny::object(); arr->append(obj); - + if ((ret = stream->dumps(obj)) != ERROR_SUCCESS) { return ret; } @@ -544,7 +540,7 @@ SrsStatisticVhost* SrsStatistic::create_vhost(SrsRequest* req) vhosts[vhost->id] = vhost; return vhost; } - + vhost = rvhosts[req->vhost]; return vhost; diff --git a/trunk/src/app/srs_app_statistic.hpp b/trunk/src/app/srs_app_statistic.hpp index d6e2f6ef2..32838c9fc 100644 --- a/trunk/src/app/srs_app_statistic.hpp +++ b/trunk/src/app/srs_app_statistic.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_STATISTIC_HPP #define SRS_APP_STATISTIC_HPP -/* -#include -*/ - #include #include @@ -52,8 +48,8 @@ public: int nb_clients; public: /** - * vhost total kbps. - */ + * vhost total kbps. + */ SrsKbps* kbps; public: SrsStatisticVhost(); @@ -75,8 +71,8 @@ public: int nb_clients; public: /** - * stream total kbps. - */ + * stream total kbps. + */ SrsKbps* kbps; public: bool has_video; @@ -94,11 +90,11 @@ public: 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. - */ + * 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(); @@ -107,12 +103,12 @@ public: virtual int dumps(SrsJsonObject* obj); public: /** - * publish the stream. - */ + * publish the stream. + */ virtual void publish(int cid); /** - * close the stream. - */ + * close the stream. + */ virtual void close(); }; @@ -167,19 +163,13 @@ public: virtual SrsStatisticClient* find_client(int cid); public: /** - * when got video info for stream. - */ - virtual int on_video_info(SrsRequest* req, - SrsVideoCodecId vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level, - int width, int height - ); + * when got video info for stream. + */ + virtual int on_video_info(SrsRequest* req, SrsVideoCodecId vcodec, SrsAvcProfile avc_profile, SrsAvcLevel avc_level, int width, int height); /** - * when got audio info for stream. - */ - virtual int on_audio_info(SrsRequest* req, - SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, - SrsAacObjectType aac_object - ); + * when got audio info for stream. + */ + virtual int on_audio_info(SrsRequest* req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, SrsAacObjectType aac_object); /** * when publish stream. * @param req the request object of publish connection. @@ -187,8 +177,8 @@ public: */ virtual void on_stream_publish(SrsRequest* req, int cid); /** - * when close stream. - */ + * when close stream. + */ virtual void on_stream_close(SrsRequest* req); public: /** @@ -207,29 +197,29 @@ public: */ 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 IKbpsDelta 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 int dumps_vhosts(SrsJsonArray* arr); /** - * dumps the streams to amf0 array. - */ + * dumps the streams to amf0 array. + */ virtual int dumps_streams(SrsJsonArray* arr); /** * dumps the clients to amf0 array diff --git a/trunk/src/app/srs_app_thread.cpp b/trunk/src/app/srs_app_thread.cpp index da36c71df..55763ebd1 100755 --- a/trunk/src/app/srs_app_thread.cpp +++ b/trunk/src/app/srs_app_thread.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include diff --git a/trunk/src/app/srs_app_thread.hpp b/trunk/src/app/srs_app_thread.hpp index e2b6e0bd9..4dd5a44b8 100644 --- a/trunk/src/app/srs_app_thread.hpp +++ b/trunk/src/app/srs_app_thread.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_THREAD_HPP #define SRS_APP_THREAD_HPP -/* -#include -*/ #include #include diff --git a/trunk/src/app/srs_app_utility.cpp b/trunk/src/app/srs_app_utility.cpp index 52c447d13..5e115ac18 100644 --- a/trunk/src/app/srs_app_utility.cpp +++ b/trunk/src/app/srs_app_utility.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -246,7 +246,7 @@ int srs_kill_forced(int& pid) return ret; } - + // then, try kill by SIGKILL. if (kill(pid, SIGKILL) < 0) { return ERROR_SYSTEM_KILL; @@ -401,17 +401,17 @@ bool get_proc_system_stat(SrsProcSystemStat& r) // @see: read_stat_cpu() from https://github.com/sysstat/sysstat/blob/master/rd_stats.c#L88 // @remark, ignore the filed 10 cpu_guest_nice - sscanf(buf + 5, "%llu %llu %llu %llu %llu %llu %llu %llu %llu\n", - &r.user, - &r.nice, - &r.sys, - &r.idle, - &r.iowait, - &r.irq, - &r.softirq, - &r.steal, - &r.guest); - + sscanf(buf + 5, "%llu %llu %llu %llu %llu %llu %llu %llu %llu\n", + &r.user, + &r.nice, + &r.sys, + &r.idle, + &r.iowait, + &r.irq, + &r.softirq, + &r.steal, + &r.guest); + break; } @@ -420,7 +420,7 @@ bool get_proc_system_stat(SrsProcSystemStat& r) // 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; return true; @@ -436,23 +436,23 @@ bool get_proc_self_stat(SrsProcSelfStat& r) } fscanf(f, "%d %32s %c %d %d %d %d " - "%d %u %lu %lu %lu %lu " - "%lu %lu %ld %ld %ld %ld " - "%ld %ld %llu %lu %ld " - "%lu %lu %lu %lu %lu " - "%lu %lu %lu %lu %lu " - "%lu %lu %lu %d %d " - "%u %u %llu " - "%lu %ld", - &r.pid, r.comm, &r.state, &r.ppid, &r.pgrp, &r.session, &r.tty_nr, - &r.tpgid, &r.flags, &r.minflt, &r.cminflt, &r.majflt, &r.cmajflt, - &r.utime, &r.stime, &r.cutime, &r.cstime, &r.priority, &r.nice, - &r.num_threads, &r.itrealvalue, &r.starttime, &r.vsize, &r.rss, - &r.rsslim, &r.startcode, &r.endcode, &r.startstack, &r.kstkesp, - &r.kstkeip, &r.signal, &r.blocked, &r.sigignore, &r.sigcatch, - &r.wchan, &r.nswap, &r.cnswap, &r.exit_signal, &r.processor, - &r.rt_priority, &r.policy, &r.delayacct_blkio_ticks, - &r.guest_time, &r.cguest_time); + "%d %u %lu %lu %lu %lu " + "%lu %lu %ld %ld %ld %ld " + "%ld %ld %llu %lu %ld " + "%lu %lu %lu %lu %lu " + "%lu %lu %lu %lu %lu " + "%lu %lu %lu %d %d " + "%u %u %llu " + "%lu %ld", + &r.pid, r.comm, &r.state, &r.ppid, &r.pgrp, &r.session, &r.tty_nr, + &r.tpgid, &r.flags, &r.minflt, &r.cminflt, &r.majflt, &r.cmajflt, + &r.utime, &r.stime, &r.cutime, &r.cstime, &r.priority, &r.nice, + &r.num_threads, &r.itrealvalue, &r.starttime, &r.vsize, &r.rss, + &r.rsslim, &r.startcode, &r.endcode, &r.startstack, &r.kstkesp, + &r.kstkeip, &r.signal, &r.blocked, &r.sigignore, &r.sigcatch, + &r.wchan, &r.nswap, &r.cnswap, &r.exit_signal, &r.processor, + &r.rt_priority, &r.policy, &r.delayacct_blkio_ticks, + &r.guest_time, &r.cguest_time); fclose(f); #else @@ -620,22 +620,22 @@ bool srs_get_disk_diskstats_stat(SrsDiskStat& r) unsigned int aveq = 0; memset(name, 0, sizeof(name)); - sscanf(buf, "%4d %4d %31s %u %u %llu %u %u %u %llu %u %u %u %u", - &major, - &minor, - name, - &rd_ios, - &rd_merges, - &rd_sectors, - &rd_ticks, - &wr_ios, - &wr_merges, - &wr_sectors, - &wr_ticks, - &nb_current, - &ticks, - &aveq); - + sscanf(buf, "%4d %4d %31s %u %u %llu %u %u %u %llu %u %u %u %u", + &major, + &minor, + name, + &rd_ios, + &rd_merges, + &rd_sectors, + &rd_ticks, + &wr_ios, + &wr_merges, + &wr_sectors, + &wr_ticks, + &nb_current, + &ticks, + &aveq); + for (int i = 0; i < (int)conf->args.size(); i++) { string name_ok = conf->args.at(i); @@ -712,7 +712,7 @@ void srs_update_disk_stat() if (r.cpu.ok && r.cpu.total_delta > 0 && cpuinfo->ok && cpuinfo->nb_processors > 0 && o.ticks < r.ticks - ) { + ) { // @see: write_ext_stat() from https://github.com/sysstat/sysstat/blob/master/iostat.c#L979 // TODO: FIXME: the USER_HZ assert to 100, so the total_delta ticks *10 is ms. double delta_ms = r.cpu.total_delta * 10 / cpuinfo->nb_processors; @@ -862,7 +862,7 @@ void srs_update_platform_info() } fscanf(f, "%lf %lf\n", &r.os_uptime, &r.os_ilde_time); - + fclose(f); } @@ -875,11 +875,11 @@ void srs_update_platform_info() // @see: read_loadavg() from https://github.com/sysstat/sysstat/blob/master/rd_stats.c#L402 // @remark, we use our algorithm, not sysstat. - fscanf(f, "%lf %lf %lf\n", - &r.load_one_minutes, - &r.load_five_minutes, - &r.load_fifteen_minutes); - + fscanf(f, "%lf %lf %lf\n", + &r.load_one_minutes, + &r.load_five_minutes, + &r.load_fifteen_minutes); + fclose(f); } #else @@ -977,21 +977,21 @@ void srs_update_network_devices() static char buf[1024]; fgets(buf, sizeof(buf), f); fgets(buf, sizeof(buf), f); - + for (int i = 0; i < MAX_NETWORK_DEVICES_COUNT; i++) { if (!fgets(buf, sizeof(buf), f)) { break; } SrsNetworkDevices& r = _srs_system_network_devices[i]; - + // @see: read_net_dev() from https://github.com/sysstat/sysstat/blob/master/rd_stats.c#L786 // @remark, we use our algorithm, not sysstat. char fname[7]; sscanf(buf, "%6[^:]:%llu %lu %lu %lu %lu %lu %lu %lu %llu %lu %lu %lu %lu %lu %lu %lu\n", - fname, &r.rbytes, &r.rpackets, &r.rerrs, &r.rdrop, &r.rfifo, &r.rframe, &r.rcompressed, &r.rmulticast, - &r.sbytes, &r.spackets, &r.serrs, &r.sdrop, &r.sfifo, &r.scolls, &r.scarrier, &r.scompressed); - + fname, &r.rbytes, &r.rpackets, &r.rerrs, &r.rdrop, &r.rfifo, &r.rframe, &r.rcompressed, &r.rmulticast, + &r.sbytes, &r.spackets, &r.serrs, &r.sdrop, &r.sfifo, &r.scolls, &r.scarrier, &r.scompressed); + sscanf(fname, "%s", r.name); _nb_srs_system_network_devices = i + 1; srs_info("scan network device ifname=%s, total=%d", r.name, _nb_srs_system_network_devices); @@ -999,7 +999,7 @@ void srs_update_network_devices() r.sample_time = srs_get_system_time_ms(); r.ok = true; } - + fclose(f); } #else @@ -1016,7 +1016,7 @@ static std::map _srs_device_ifs; bool srs_net_device_is_internet(string ifname) { srs_info("check ifname=%s", ifname.c_str()); - + if (_srs_device_ifs.find(ifname) == _srs_device_ifs.end()) { return false; } @@ -1079,14 +1079,14 @@ enum { SYS_TCP_LAST_ACK, // 0x09 SYS_TCP_LISTEN, // 0x0A SYS_TCP_CLOSING, // 0x0B /* Now a valid state */ - + SYS_TCP_MAX_STATES // 0x0C /* Leave at the end! */ }; void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps) { SrsNetworkRtmpServer& r = _srs_network_rtmp_server; - + int nb_socks = 0; int nb_tcp4_hashed = 0; int nb_tcp_orphans = 0; @@ -1112,17 +1112,17 @@ void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps) if (strncmp(buf, "sockets: used ", 14) == 0) { sscanf(buf + 14, "%d\n", &nb_socks); } else if (strncmp(buf, "TCP: ", 5) == 0) { - sscanf(buf + 5, "%*s %d %*s %d %*s %d %*s %d %*s %d\n", - &nb_tcp4_hashed, - &nb_tcp_orphans, - &nb_tcp_tws, - &nb_tcp_total, - &nb_tcp_mem); + sscanf(buf + 5, "%*s %d %*s %d %*s %d %*s %d %*s %d\n", + &nb_tcp4_hashed, + &nb_tcp_orphans, + &nb_tcp_tws, + &nb_tcp_total, + &nb_tcp_mem); } else if (strncmp(buf, "UDP: ", 5) == 0) { sscanf(buf + 5, "%*s %d\n", &nb_udp4); } } - + fclose(f); } #else @@ -1166,7 +1166,7 @@ void srs_update_rtmp_server(int nb_conn, SrsKbps* kbps) } } } - + fclose(f); } #else @@ -1229,7 +1229,7 @@ void retrieve_local_ipv4_ips() p = p->ifa_next; // retrieve ipv4 addr - // ignore the tun0 network device, + // ignore the tun0 network device, // which addr is NULL. // @see: https://github.com/ossrs/srs/issues/141 if (addr && addr->sa_family == AF_INET) { @@ -1262,7 +1262,7 @@ void retrieve_local_ipv4_ips() } srs_trace(ss0.str().c_str()); srs_trace(ss1.str().c_str()); - + freeifaddrs(ifap); } @@ -1271,7 +1271,7 @@ vector& srs_get_local_ipv4_ips() if (_srs_system_ipv4_ips.empty()) { retrieve_local_ipv4_ips(); } - + return _srs_system_ipv4_ips; } @@ -1338,7 +1338,7 @@ string srs_get_public_internet_address() string srs_get_local_ip(int fd) { std::string ip; - + // discovery client information sockaddr_in addr; socklen_t addrlen = sizeof(addr); @@ -1346,19 +1346,19 @@ string srs_get_local_ip(int fd) return ip; } srs_verbose("get local ip success."); - + // ip v4 or v6 char buf[INET6_ADDRSTRLEN]; memset(buf, 0, sizeof(buf)); - + if ((inet_ntop(addr.sin_family, &addr.sin_addr, buf, sizeof(buf))) == NULL) { return ip; } - + ip = buf; - + srs_verbose("get local ip of client ip=%s, fd=%d", buf, fd); - + return ip; } @@ -1373,9 +1373,9 @@ int srs_get_local_port(int fd) srs_verbose("get local ip success."); int port = ntohs(addr.sin_port); - + srs_verbose("get local ip of client port=%s, fd=%d", port, fd); - + return port; } @@ -1390,7 +1390,7 @@ string srs_get_peer_ip(int fd) return ip; } srs_verbose("get peer name success."); - + // ip v4 or v6 char buf[INET6_ADDRSTRLEN]; memset(buf, 0, sizeof(buf)); @@ -1483,8 +1483,8 @@ void srs_api_dump_summaries(SrsJsonObject* obj) } // all data is ok? - bool ok = (r->ok && u->ok && s->ok && c->ok - && d->ok && m->ok && p->ok && nrs->ok); + bool ok = (r->ok && u->ok && s->ok && c->ok + && d->ok && m->ok && p->ok && nrs->ok); SrsJsonObject* data = SrsJsonAny::object(); obj->set("data", data); diff --git a/trunk/src/app/srs_app_utility.hpp b/trunk/src/app/srs_app_utility.hpp index 8ac48642e..b660f7905 100644 --- a/trunk/src/app/srs_app_utility.hpp +++ b/trunk/src/app/srs_app_utility.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_APP_UTILITY_HPP #define SRS_APP_UTILITY_HPP -/* -#include -*/ - #include #include @@ -48,32 +44,32 @@ class SrsJsonObject; extern int srs_socket_connect(std::string server, int port, int64_t tm, st_netfd_t* pstfd); /** -* 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 int 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); /** @@ -118,7 +114,7 @@ public: // the percent of usage. 0.153 is 15.3%. float percent; -// data of /proc/[pid]/stat + // data of /proc/[pid]/stat public: // pid %d The process ID. int pid; @@ -186,7 +182,7 @@ public: long num_threads; // itrealvalue %ld // The time in jiffies before the next SIGALRM is sent to the process due to an interval timer. Since - // kernel 2.6.17, this field is no longer maintained, and is hard coded as 0. + // kernel 2.6.17, this field is no longer maintained, and is hard coded as 0. long itrealvalue; // starttime %llu (was %lu before Linux 2.6) // The time in jiffies the process started after system boot. @@ -265,34 +261,34 @@ public: // 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: @@ -310,26 +306,26 @@ public: // previous cpu total = this->total() - total_delta int64_t total_delta; -// data of /proc/stat + // data of /proc/stat public: - // The amount of time, measured in units of USER_HZ + // The amount of time, measured in units of USER_HZ // (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), + // user mode with low priority (nice), unsigned long long nice; - // system mode, + // system mode, unsigned long long sys; // and the idle task, respectively. unsigned long long idle; - + // In Linux 2.6 this line includes three additional columns: // // iowait - time waiting for I/O to complete (since 2.5.41); unsigned long long iowait; - // irq - time servicing interrupts (since 2.6.0-test4); + // irq - time servicing interrupts (since 2.6.0-test4); unsigned long long irq; // softirq - time servicing softirqs (since 2.6.0-test4). unsigned long long softirq; @@ -339,11 +335,11 @@ public: // ating systems when running in a virtualized environment unsigned long long steal; - // Since Linux 2.6.24, there is a ninth column, + // Since Linux 2.6.24, there is a ninth column, // guest, which is the time spent running a virtual CPU for guest // operating systems under the control of the Linux kernel. unsigned long long guest; - + public: SrsProcSystemStat(); @@ -399,63 +395,63 @@ public: // @see: http://tester-higkoo.googlecode.com/svn-history/r14/trunk/Tools/iostat/iostat.c // @see: cat /proc/diskstats // - // Number of issued reads. + // Number of issued reads. // This is the total number of reads completed successfully. // Read I/O operations unsigned int rd_ios; // Number of reads merged // Reads merged unsigned int rd_merges; - // Number of sectors read. + // Number of sectors read. // This is the total number of sectors read successfully. // Sectors read unsigned long long rd_sectors; - // Number of milliseconds spent reading. - // This is the total number of milliseconds spent by all reads + // Number of milliseconds spent reading. + // This is the total number of milliseconds spent by all reads // (as measured from make_request() to end_that_request_last()). // Time in queue + service for read unsigned int rd_ticks; // - // Number of writes completed. + // Number of writes completed. // This is the total number of writes completed successfully // 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 - // reads may become one 8K read before it is ultimately - // handed to the disk, and so it will be counted (and queued) + // Number of writes merged Reads and writes which are adjacent + // 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. // Writes merged unsigned int wr_merges; - // Number of sectors written. + // Number of sectors written. // This is the total number of sectors written successfully. // Sectors written unsigned long long wr_sectors; - // Number of milliseconds spent writing . - // This is the total number of milliseconds spent by all writes + // Number of milliseconds spent writing . + // This is the total number of milliseconds spent by all writes // (as measured from make_request() to end_that_request_last()). // Time in queue + service for write unsigned int wr_ticks; // - // Number of I/Os currently in progress. - // The only field that should go to zero. - // Incremented as requests are given to appropriate request_queue_t + // Number of I/Os currently in progress. + // The only field that should go to zero. + // Incremented as requests are given to appropriate request_queue_t // and decremented as they finish. unsigned int nb_current; - // Number of milliseconds spent doing I/Os. + // Number of milliseconds spent doing I/Os. // This field is increased so long as field 9 is nonzero. // Time of requests in queue unsigned int ticks; - // Number of milliseconds spent doing I/Os. - // This field is incremented at each I/O start, I/O completion, - // I/O merge, or read of these stats by the number of I/Os in - // 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 + // Number of milliseconds spent doing I/Os. + // This field is incremented at each I/O start, I/O completion, + // I/O merge, or read of these stats by the number of I/Os in + // 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. // Average queue length unsigned int aveq; - + public: SrsDiskStat(); }; @@ -466,7 +462,7 @@ extern SrsDiskStat* srs_get_disk_stat(); extern void srs_update_disk_stat(); // stat system memory info -// @see: cat /proc/meminfo +// @see: cat /proc/meminfo class SrsMemInfo { public: @@ -478,7 +474,7 @@ public: float percent_ram; float percent_swap; -// data of /proc/meminfo + // data of /proc/meminfo public: // MemActive = MemTotal - MemFree uint64_t MemActive; @@ -507,7 +503,7 @@ extern SrsMemInfo* srs_get_meminfo(); extern void srs_update_meminfo(); // system cpu hardware info. -// @see: cat /proc/cpuinfo +// @see: cat /proc/cpuinfo // @remark, we use sysconf(_SC_NPROCESSORS_CONF) to get the cpu count. class SrsCpuInfo { @@ -515,7 +511,7 @@ public: // whether the data is ok. bool ok; -// data of /proc/cpuinfo + // data of /proc/cpuinfo public: // The number of processors configured. int nb_processors; @@ -639,14 +635,14 @@ public: int nb_conn_sys_et; // established int nb_conn_sys_tw; // time wait int nb_conn_sys_udp; // udp - + // retrieve from srs interface int nb_conn_srs; public: SrsNetworkRtmpServer(); }; - + // get network devices info, use cache to avoid performance problem. extern SrsNetworkRtmpServer* srs_get_network_rtmp_server(); // the deamon st-thread will update it. diff --git a/trunk/src/core/srs_core.cpp b/trunk/src/core/srs_core.cpp index 93a9d7f6a..cebaa5272 100644 --- a/trunk/src/core/srs_core.cpp +++ b/trunk/src/core/srs_core.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index 27ba606b7..54d168795 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_CORE_HPP #define SRS_CORE_HPP -/* -#include -*/ - // current release version #define VERSION_MAJOR 3 #define VERSION_MINOR 0 @@ -63,10 +59,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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. -*/ + * 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, // ie. read/write/lseek to use 64bits size for huge file. diff --git a/trunk/src/core/srs_core_autofree.cpp b/trunk/src/core/srs_core_autofree.cpp index 4ecc372ab..b76a2e05a 100644 --- a/trunk/src/core/srs_core_autofree.cpp +++ b/trunk/src/core/srs_core_autofree.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include diff --git a/trunk/src/core/srs_core_autofree.hpp b/trunk/src/core/srs_core_autofree.hpp index ce8d380b6..1241576fb 100644 --- a/trunk/src/core/srs_core_autofree.hpp +++ b/trunk/src/core/srs_core_autofree.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_CORE_AUTO_FREE_HPP #define SRS_CORE_AUTO_FREE_HPP -/* -#include -*/ - #include /** diff --git a/trunk/src/core/srs_core_mem_watch.cpp b/trunk/src/core/srs_core_mem_watch.cpp index 4667d22a6..5e3cb4ce2 100644 --- a/trunk/src/core/srs_core_mem_watch.cpp +++ b/trunk/src/core/srs_core_mem_watch.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include diff --git a/trunk/src/core/srs_core_mem_watch.hpp b/trunk/src/core/srs_core_mem_watch.hpp index fe8d0821e..41e8ba376 100644 --- a/trunk/src/core/srs_core_mem_watch.hpp +++ b/trunk/src/core/srs_core_mem_watch.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_CORE_MEM_WATCH_HPP #define SRS_CORE_MEM_WATCH_HPP -/* -#include -*/ - #include #ifdef SRS_AUTO_MEM_WATCH diff --git a/trunk/src/core/srs_core_performance.cpp b/trunk/src/core/srs_core_performance.cpp index cdfc72a03..29e8d7874 100644 --- a/trunk/src/core/srs_core_performance.cpp +++ b/trunk/src/core/srs_core_performance.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include diff --git a/trunk/src/core/srs_core_performance.hpp b/trunk/src/core/srs_core_performance.hpp index 6833a76d7..4446b2362 100644 --- a/trunk/src/core/srs_core_performance.hpp +++ b/trunk/src/core/srs_core_performance.hpp @@ -1,165 +1,161 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_CORE_PERFORMANCE_HPP #define SRS_CORE_PERFORMANCE_HPP -/* -#include -*/ - #include /** -* this file defines the perfromance options. -*/ + * this file defines the perfromance options. + */ /** -* 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. -* @see SrsConfig::get_mr_enabled() -* @see SrsConfig::get_mr_sleep_ms() -* @see https://github.com/ossrs/srs/issues/241 -* @example, for the default settings, this algorithm will use: -* that is, when got nread bytes smaller than 4KB, sleep(780ms). -*/ + * 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. + * @see SrsConfig::get_mr_enabled() + * @see SrsConfig::get_mr_sleep_ms() + * @see https://github.com/ossrs/srs/issues/241 + * @example, for the default settings, this algorithm will use: + * that is, when got nread bytes smaller than 4KB, sleep(780ms). + */ /** -* https://github.com/ossrs/srs/issues/241#issuecomment-65554690 -* The merged read algorithm is ok and can be simplified for: -* 1. Suppose the client network is ok. All algorithm go wrong when netowrk is not ok. -* 2. Suppose the client send each packet one by one. Although send some together, it's same. -* 3. SRS MR algorithm will read all data then sleep. -* So, the MR algorithm is: -* while true: -* read all data from socket. -* sleep a while -* For example, sleep 120ms. Then there is, and always 120ms data in buffer. -* That is, the latency is 120ms(the sleep time). -*/ + * https://github.com/ossrs/srs/issues/241#issuecomment-65554690 + * The merged read algorithm is ok and can be simplified for: + * 1. Suppose the client network is ok. All algorithm go wrong when netowrk is not ok. + * 2. Suppose the client send each packet one by one. Although send some together, it's same. + * 3. SRS MR algorithm will read all data then sleep. + * So, the MR algorithm is: + * while true: + * read all data from socket. + * sleep a while + * For example, sleep 120ms. Then there is, and always 120ms data in buffer. + * That is, the latency is 120ms(the sleep time). + */ #define SRS_PERF_MERGED_READ // the default config of mr. #define SRS_PERF_MR_ENABLED false #define SRS_PERF_MR_SLEEP 350 /** -* the MW(merged-write) send cache time in ms. -* the default value, user can override it in config. -* to improve send performance, cache msgs and send in a time. -* for example, cache 500ms videos and audios, then convert all these -* msgs to iovecs, finally use writev to send. -* @remark this largely improve performance, from 3.5k+ to 7.5k+. -* the latency+ when cache+. -* @remark the socket send buffer default to 185KB, it large enough. -* @see https://github.com/ossrs/srs/issues/194 -* @see SrsConfig::get_mw_sleep_ms() -* @remark the mw sleep and msgs to send, maybe: -* mw_sleep msgs iovs -* 350 43 86 -* 400 44 88 -* 500 46 92 -* 600 46 92 -* 700 82 164 -* 800 81 162 -* 900 80 160 -* 1000 88 176 -* 1100 91 182 -* 1200 89 178 -* 1300 119 238 -* 1400 120 240 -* 1500 119 238 -* 1600 131 262 -* 1700 131 262 -* 1800 133 266 -* 1900 141 282 -* 2000 150 300 -*/ + * the MW(merged-write) send cache time in ms. + * the default value, user can override it in config. + * to improve send performance, cache msgs and send in a time. + * for example, cache 500ms videos and audios, then convert all these + * msgs to iovecs, finally use writev to send. + * @remark this largely improve performance, from 3.5k+ to 7.5k+. + * the latency+ when cache+. + * @remark the socket send buffer default to 185KB, it large enough. + * @see https://github.com/ossrs/srs/issues/194 + * @see SrsConfig::get_mw_sleep_ms() + * @remark the mw sleep and msgs to send, maybe: + * mw_sleep msgs iovs + * 350 43 86 + * 400 44 88 + * 500 46 92 + * 600 46 92 + * 700 82 164 + * 800 81 162 + * 900 80 160 + * 1000 88 176 + * 1100 91 182 + * 1200 89 178 + * 1300 119 238 + * 1400 120 240 + * 1500 119 238 + * 1600 131 262 + * 1700 131 262 + * 1800 133 266 + * 1900 141 282 + * 2000 150 300 + */ // the default config of mw. #define SRS_PERF_MW_SLEEP 350 /** -* how many msgs can be send entirely. -* for play clients to get msgs then totally send out. -* for the mw sleep set to 1800, the msgs is about 133. -* @remark, recomment to 128. -*/ + * how many msgs can be send entirely. + * for play clients to get msgs then totally send out. + * for the mw sleep set to 1800, the msgs is about 133. + * @remark, recomment to 128. + */ #define SRS_PERF_MW_MSGS 128 /** -* whether set the socket send buffer size. -* @see https://github.com/ossrs/srs/issues/251 -*/ + * whether set the socket send buffer size. + * @see https://github.com/ossrs/srs/issues/251 + */ #define SRS_PERF_MW_SO_SNDBUF /** -* whether set the socket recv buffer size. -* @see https://github.com/ossrs/srs/issues/251 -*/ + * whether set the socket recv buffer size. + * @see https://github.com/ossrs/srs/issues/251 + */ #undef SRS_PERF_MW_SO_RCVBUF /** -* whether enable the fast vector for qeueue. -* @see https://github.com/ossrs/srs/issues/251 -*/ + * whether enable the fast vector for qeueue. + * @see https://github.com/ossrs/srs/issues/251 + */ #define SRS_PERF_QUEUE_FAST_VECTOR /** -* whether use cond wait to send messages. -* @remark this improve performance for large connectios. -* @see https://github.com/ossrs/srs/issues/251 -*/ + * whether use cond wait to send messages. + * @remark this improve performance for large connectios. + * @see https://github.com/ossrs/srs/issues/251 + */ #define SRS_PERF_QUEUE_COND_WAIT #ifdef SRS_PERF_QUEUE_COND_WAIT #define SRS_PERF_MW_MIN_MSGS 8 #endif /** -* the default value of vhost for -* SRS whether use the min latency mode. -* for min latence mode: -* 1. disable the mr for vhost. -* 2. use timeout for cond wait for consumer queue. -* @see https://github.com/ossrs/srs/issues/257 -*/ + * the default value of vhost for + * SRS whether use the min latency mode. + * for min latence mode: + * 1. disable the mr for vhost. + * 2. use timeout for cond wait for consumer queue. + * @see https://github.com/ossrs/srs/issues/257 + */ #define SRS_PERF_MIN_LATENCY_ENABLED false /** -* how many chunk stream to cache, [0, N]. -* to imporove about 10% performance when chunk size small, and 5% for large chunk. -* @see https://github.com/ossrs/srs/issues/249 -* @remark 0 to disable the chunk stream cache. -*/ + * how many chunk stream to cache, [0, N]. + * to imporove about 10% performance when chunk size small, and 5% for large chunk. + * @see https://github.com/ossrs/srs/issues/249 + * @remark 0 to disable the chunk stream cache. + */ #define SRS_PERF_CHUNK_STREAM_CACHE 16 /** -* the gop cache and play cache queue. -*/ + * the gop cache and play cache queue. + */ // whether gop cache is on. #define SRS_PERF_GOP_CACHE true // in seconds, the live queue length. #define SRS_PERF_PLAY_QUEUE 30 /** -* whether always use complex send algorithm. -* for some network does not support the complex send, -* @see https://github.com/ossrs/srs/issues/320 -*/ + * whether always use complex send algorithm. + * for some network does not support the complex send, + * @see https://github.com/ossrs/srs/issues/320 + */ //#undef SRS_PERF_COMPLEX_SEND #define SRS_PERF_COMPLEX_SEND /** @@ -170,12 +166,12 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #undef SRS_PERF_TCP_NODELAY #define SRS_PERF_TCP_NODELAY /** -* set the socket send buffer, -* to force the server to send smaller tcp packet. -* @see https://github.com/ossrs/srs/issues/320 -* @remark undef it to auto calc it by merged write sleep ms. -* @remark only apply it when SRS_PERF_MW_SO_SNDBUF is defined. -*/ + * set the socket send buffer, + * to force the server to send smaller tcp packet. + * @see https://github.com/ossrs/srs/issues/320 + * @remark undef it to auto calc it by merged write sleep ms. + * @remark only apply it when SRS_PERF_MW_SO_SNDBUF is defined. + */ #ifdef SRS_PERF_MW_SO_SNDBUF //#define SRS_PERF_SO_SNDBUF_SIZE 1024 #undef SRS_PERF_SO_SNDBUF_SIZE diff --git a/trunk/src/kernel/srs_kernel_aac.cpp b/trunk/src/kernel/srs_kernel_aac.cpp index 566b66a8c..14ef1bd0a 100644 --- a/trunk/src/kernel/srs_kernel_aac.cpp +++ b/trunk/src/kernel/srs_kernel_aac.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -82,7 +82,7 @@ int SrsAacTransmuxer::write_audio(int64_t timestamp, char* data, int size) if ((ret = stream->initialize(data, size)) != ERROR_SUCCESS) { return ret; } - + // audio decode if (!stream->require(1)) { ret = ERROR_AAC_DECODE_ERROR; @@ -103,7 +103,7 @@ int SrsAacTransmuxer::write_audio(int64_t timestamp, char* data, int size) srs_error("aac required, format=%d. ret=%d", sound_format, ret); return ret; } - + if (!stream->require(1)) { ret = ERROR_AAC_DECODE_ERROR; srs_error("aac decode aac_packet_type failed. ret=%d", ret); diff --git a/trunk/src/kernel/srs_kernel_aac.hpp b/trunk/src/kernel/srs_kernel_aac.hpp index e77dcc693..881f245cd 100644 --- a/trunk/src/kernel/srs_kernel_aac.hpp +++ b/trunk/src/kernel/srs_kernel_aac.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_KERNEL_AAC_HPP #define SRS_KERNEL_AAC_HPP -/* -#include -*/ #include #if !defined(SRS_EXPORT_LIBRTMP) @@ -58,16 +55,16 @@ public: 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 int initialize(SrsFileWriter* fs); public: /** - * write audio/video packet. - * @remark assert data is not NULL. - */ + * write audio/video packet. + * @remark assert data is not NULL. + */ virtual int write_audio(int64_t timestamp, char* data, int size); }; diff --git a/trunk/src/kernel/srs_kernel_balance.cpp b/trunk/src/kernel/srs_kernel_balance.cpp index 3568b7a3f..6055a5607 100644 --- a/trunk/src/kernel/srs_kernel_balance.cpp +++ b/trunk/src/kernel/srs_kernel_balance.cpp @@ -1,24 +1,24 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. */ #include diff --git a/trunk/src/kernel/srs_kernel_balance.hpp b/trunk/src/kernel/srs_kernel_balance.hpp index abbecadf7..3e3ce8052 100644 --- a/trunk/src/kernel/srs_kernel_balance.hpp +++ b/trunk/src/kernel/srs_kernel_balance.hpp @@ -1,32 +1,29 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_KERNEL_BALANCE_HPP #define SRS_KERNEL_BALANCE_HPP -/* -#include -*/ #include #include diff --git a/trunk/src/kernel/srs_kernel_buffer.cpp b/trunk/src/kernel/srs_kernel_buffer.cpp index f3b66dc3f..d09115f77 100644 --- a/trunk/src/kernel/srs_kernel_buffer.cpp +++ b/trunk/src/kernel/srs_kernel_buffer.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -75,11 +75,11 @@ int SrsBuffer::initialize(char* b, int nb) srs_error("stream param size must be positive. ret=%d", ret); return ret; } - + nb_bytes = nb; p = bytes = b; srs_info("init stream ok, size=%d", size()); - + return ret; } diff --git a/trunk/src/kernel/srs_kernel_buffer.hpp b/trunk/src/kernel/srs_kernel_buffer.hpp index c506eac91..a9a21a9b4 100644 --- a/trunk/src/kernel/srs_kernel_buffer.hpp +++ b/trunk/src/kernel/srs_kernel_buffer.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_KERNEL_BUFFER_HPP #define SRS_KERNEL_BUFFER_HPP -/* -#include -*/ - #include #include @@ -105,107 +101,107 @@ private: virtual void set_value(char* b, int nb_b); public: /** - * initialize the stream from bytes. - * @b, the bytes to convert from/to basic types. - * @nb, the size of bytes, total number of bytes for stream. - * @remark, stream never free the bytes, user must free it. - * @remark, return error when bytes NULL. - * @remark, return error when size is not positive. - */ + * initialize the stream from bytes. + * @b, the bytes to convert from/to basic types. + * @nb, the size of bytes, total number of bytes for stream. + * @remark, stream never free the bytes, user must free it. + * @remark, return error when bytes NULL. + * @remark, return error when size is not positive. + */ virtual int initialize(char* b, int nb); -// get the status of stream + // get the status of stream public: /** - * get data of stream, set by initialize. - * current bytes = data() + pos() - */ + * get data of stream, set by initialize. + * current bytes = data() + pos() + */ virtual char* data(); /** - * the total stream size, set by initialize. - * left bytes = size() - pos(). - */ + * the total stream size, set by initialize. + * left bytes = size() - pos(). + */ virtual int size(); /** - * tell the current pos. - */ + * tell the current pos. + */ virtual int pos(); /** - * whether stream is empty. - * if empty, user should never read or write. - */ + * whether stream is empty. + * if empty, user should never read or write. + */ virtual bool empty(); /** - * whether required size is ok. - * @return true if stream can read/write specified required_size bytes. - * @remark assert required_size positive. - */ + * whether required size is ok. + * @return true if stream can read/write specified required_size bytes. + * @remark assert required_size positive. + */ virtual bool require(int required_size); -// to change stream. + // to change stream. public: /** - * to skip some size. - * @param size can be any value. positive to forward; nagetive to backward. - * @remark to skip(pos()) to reset stream. - * @remark assert initialized, the data() not NULL. - */ + * to skip some size. + * @param size can be any value. positive to forward; nagetive to backward. + * @remark to skip(pos()) to reset stream. + * @remark assert initialized, the data() not NULL. + */ virtual void skip(int size); public: /** - * get 1bytes char from stream. - */ + * get 1bytes char from stream. + */ virtual int8_t read_1bytes(); /** - * get 2bytes int from stream. - */ + * get 2bytes int from stream. + */ virtual int16_t read_2bytes(); /** - * get 3bytes int from stream. - */ + * get 3bytes int from stream. + */ virtual int32_t read_3bytes(); /** - * get 4bytes int from stream. - */ + * get 4bytes int from stream. + */ virtual int32_t read_4bytes(); /** - * get 8bytes int from stream. - */ + * get 8bytes int from stream. + */ virtual int64_t read_8bytes(); /** - * get string from stream, length specifies by param len. - */ + * get string from stream, length specifies by param len. + */ virtual std::string read_string(int len); /** - * get bytes from stream, length specifies by param len. - */ + * get bytes from stream, length specifies by param len. + */ virtual void read_bytes(char* data, int size); public: /** - * write 1bytes char to stream. - */ + * write 1bytes char to stream. + */ virtual void write_1bytes(int8_t value); /** - * write 2bytes int to stream. - */ + * write 2bytes int to stream. + */ virtual void write_2bytes(int16_t value); /** - * write 4bytes int to stream. - */ + * write 4bytes int to stream. + */ virtual void write_4bytes(int32_t value); /** - * write 3bytes int to stream. - */ + * write 3bytes int to stream. + */ virtual void write_3bytes(int32_t value); /** - * write 8bytes int to stream. - */ + * write 8bytes int to stream. + */ virtual void write_8bytes(int64_t value); /** - * write string to stream - */ + * write string to stream + */ virtual void write_string(std::string value); /** - * write bytes to stream - */ + * write bytes to stream + */ virtual void write_bytes(char* data, int size); }; diff --git a/trunk/src/kernel/srs_kernel_codec.cpp b/trunk/src/kernel/srs_kernel_codec.cpp index d857f348e..93bdd88eb 100644 --- a/trunk/src/kernel/srs_kernel_codec.cpp +++ b/trunk/src/kernel/srs_kernel_codec.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -714,7 +714,7 @@ int SrsFormat::video_avc_demux(SrsBuffer* stream, int64_t timestamp) } srs_info("avc decoded, type=%d, codec=%d, avc=%d, cts=%d, size=%d", frame_type, codec_id, avc_packet_type, - composition_time, stream->size() - stream->pos()); + composition_time, stream->size() - stream->pos()); return ret; } @@ -1350,7 +1350,7 @@ int SrsFormat::audio_aac_demux(SrsBuffer* stream, int64_t timestamp) } srs_info("aac decoded, type=%d, codec=%d, asize=%d, rate=%d, format=%d, size=%d", sound_type, codec_id, sound_size, - sound_rate, sound_format, stream->size() - stream->pos()); + sound_rate, sound_format, stream->size() - stream->pos()); return ret; } diff --git a/trunk/src/kernel/srs_kernel_codec.hpp b/trunk/src/kernel/srs_kernel_codec.hpp index 5888fc461..f593dbd8f 100644 --- a/trunk/src/kernel/srs_kernel_codec.hpp +++ b/trunk/src/kernel/srs_kernel_codec.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_KERNEL_CODEC_HPP #define SRS_KERNEL_CODEC_HPP -/* -#include -*/ - #include #include @@ -210,7 +206,7 @@ enum SrsFrameType // set to the zero to reserved, for array map. SrsFrameTypeReserved = 0, SrsFrameTypeForbidden = 0, - + // 8 = audio SrsFrameTypeAudio = 8, // 9 = video @@ -228,19 +224,19 @@ class SrsFlvVideo public: SrsFlvVideo(); virtual ~SrsFlvVideo(); -// the following function used to finger out the flv/rtmp packet detail. + // the following function used to finger out the flv/rtmp packet detail. public: /** - * only check the frame_type, not check the codec type. - */ + * only check the frame_type, not check the codec type. + */ static bool keyframe(char* data, int size); /** - * check codec h264, keyframe, sequence header - */ + * check codec h264, keyframe, sequence header + */ static bool sh(char* data, int size); /** - * check codec h264. - */ + * check codec h264. + */ static bool h264(char* data, int size); /** * check the video RTMP/flv header info, @@ -259,7 +255,7 @@ class SrsFlvAudio public: SrsFlvAudio(); virtual ~SrsFlvAudio(); -// the following function used to finger out the flv/rtmp packet detail. + // the following function used to finger out the flv/rtmp packet detail. public: /** * check codec aac, sequence header @@ -272,16 +268,16 @@ public: }; /** -* the public data, event HLS disable, others can use it. -*/ + * the public data, event HLS disable, others can use it. + */ /** -* the flv sample rate map -*/ + * the flv sample rate map + */ extern int srs_flv_srates[]; /** -* the aac sample rate map -*/ + * the aac sample rate map + */ extern int srs_aac_srates[]; // The impossible aac sample rate index. @@ -515,7 +511,7 @@ public: */ class SrsAudioCodecConfig : public SrsCodecConfig { -// In FLV specification. + // In FLV specification. public: // The audio codec id; for FLV, it's SoundFormat. SrsAudioCodecId id; @@ -527,7 +523,7 @@ public: // TODO: FIXME: Rename to sound_channels. SrsAudioChannels sound_type; int audio_data_rate; // in bps -// In AAC specification. + // In AAC specification. public: /** * audio specified @@ -544,7 +540,7 @@ public: * channelConfiguration */ uint8_t aac_channels; -// Sequence header payload. + // Sequence header payload. public: /** * the aac extra data, the AAC sequence header, diff --git a/trunk/src/kernel/srs_kernel_consts.cpp b/trunk/src/kernel/srs_kernel_consts.cpp index 60edbdea1..918593a10 100644 --- a/trunk/src/kernel/srs_kernel_consts.cpp +++ b/trunk/src/kernel/srs_kernel_consts.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include diff --git a/trunk/src/kernel/srs_kernel_consts.hpp b/trunk/src/kernel/srs_kernel_consts.hpp index 461fc1b4f..ecd5e660a 100644 --- a/trunk/src/kernel/srs_kernel_consts.hpp +++ b/trunk/src/kernel/srs_kernel_consts.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_KERNEL_CONSTS_HPP #define SRS_KERNEL_CONSTS_HPP -/* -#include -*/ - #include /////////////////////////////////////////////////////////// @@ -52,20 +48,20 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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. // Never timeout in ms @@ -84,43 +80,43 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define SRS_CONSTS_RTMP_PULSE_TMMS (500) /** -* max rtmp header size: -* 1bytes basic header, -* 11bytes message header, -* 4bytes timestamp header, -* that is, 1+11+4=16bytes. -*/ + * 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. -*/ + * 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) /////////////////////////////////////////////////////////// diff --git a/trunk/src/kernel/srs_kernel_error.cpp b/trunk/src/kernel/srs_kernel_error.cpp index b07a4672e..fda006ef8 100644 --- a/trunk/src/kernel/srs_kernel_error.cpp +++ b/trunk/src/kernel/srs_kernel_error.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include diff --git a/trunk/src/kernel/srs_kernel_error.hpp b/trunk/src/kernel/srs_kernel_error.hpp index 52f8e50a6..b25501d7d 100644 --- a/trunk/src/kernel/srs_kernel_error.hpp +++ b/trunk/src/kernel/srs_kernel_error.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_KERNEL_ERROR_HPP #define SRS_KERNEL_ERROR_HPP -/* -#include -*/ - #include // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 @@ -162,8 +158,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ERROR_RTMP_STREAM_NOT_FOUND 2048 #define ERROR_RTMP_CLIENT_NOT_FOUND 2049 #define ERROR_OpenSslCreateHMAC 2050 -// -// system control message, +// +// system control message, // not an error, but special control logic. // // connection is redirect to another server. @@ -322,24 +318,24 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define ERROR_USER_END 9999 /** -* whether the error code is an system control error. -*/ + * whether the error code is an system control error. + */ extern bool srs_is_system_control_error(int error_code); extern bool srs_is_client_gracefully_close(int error_code); /** -@remark: use column copy to generate the new error codes. -01234567890 -01234567891 -01234567892 -01234567893 -01234567894 -01234567895 -01234567896 -01234567897 -01234567898 -01234567899 -*/ + @remark: use column copy to generate the new error codes. + 01234567890 + 01234567891 + 01234567892 + 01234567893 + 01234567894 + 01234567895 + 01234567896 + 01234567897 + 01234567898 + 01234567899 + */ #endif diff --git a/trunk/src/kernel/srs_kernel_file.cpp b/trunk/src/kernel/srs_kernel_file.cpp index 5c50b5ce9..422c75ada 100644 --- a/trunk/src/kernel/srs_kernel_file.cpp +++ b/trunk/src/kernel/srs_kernel_file.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -58,7 +58,7 @@ int SrsFileWriter::open(string p) int flags = O_CREAT|O_WRONLY|O_TRUNC; mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH; - + if ((fd = ::open(p.c_str(), flags, mode)) < 0) { ret = ERROR_SYSTEM_FILE_OPENE; srs_error("open file %s failed. ret=%d", p.c_str(), ret); @@ -82,7 +82,7 @@ int SrsFileWriter::open_append(string p) int flags = O_APPEND|O_WRONLY; mode_t mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH; - + if ((fd = ::open(p.c_str(), flags, mode)) < 0) { ret = ERROR_SYSTEM_FILE_OPENE; srs_error("open file %s failed. ret=%d", p.c_str(), ret); @@ -199,7 +199,7 @@ int SrsFileReader::open(string p) srs_error("file %s already opened. ret=%d", path.c_str(), ret); return ret; } - + if ((fd = ::open(p.c_str(), O_RDONLY)) < 0) { ret = ERROR_SYSTEM_FILE_OPENE; srs_error("open file %s failed. ret=%d", p.c_str(), ret); diff --git a/trunk/src/kernel/srs_kernel_file.hpp b/trunk/src/kernel/srs_kernel_file.hpp index 9b92bf62f..e7684293a 100644 --- a/trunk/src/kernel/srs_kernel_file.hpp +++ b/trunk/src/kernel/srs_kernel_file.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_KERNEL_FILE_HPP #define SRS_KERNEL_FILE_HPP -/* -#include -*/ #include #include @@ -39,8 +36,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #endif /** -* file writer, to write to file. -*/ + * file writer, to write to file. + */ class SrsFileWriter : public ISrsWriteSeeker { private: @@ -77,8 +74,8 @@ public: }; /** -* file reader, to read from file. -*/ + * file reader, to read from file. + */ class SrsFileReader : public ISrsReadSeeker { private: diff --git a/trunk/src/kernel/srs_kernel_flv.cpp b/trunk/src/kernel/srs_kernel_flv.cpp index fe7d9feb9..38fde8b45 100644 --- a/trunk/src/kernel/srs_kernel_flv.cpp +++ b/trunk/src/kernel/srs_kernel_flv.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -284,7 +284,7 @@ bool SrsSharedPtrMessage::check(int stream_id) // ensure the basic header is 1bytes. if (ptr->header.perfer_cid < 2) { srs_info("change the chunk_id=%d to default=%d", - ptr->header.perfer_cid, RTMP_CID_ProtocolControl); + ptr->header.perfer_cid, RTMP_CID_ProtocolControl); ptr->header.perfer_cid = RTMP_CID_ProtocolControl; } @@ -300,7 +300,7 @@ bool SrsSharedPtrMessage::check(int stream_id) bool SrsSharedPtrMessage::is_av() { return ptr->header.message_type == RTMP_MSG_AudioMessage - || ptr->header.message_type == RTMP_MSG_VideoMessage; + || ptr->header.message_type == RTMP_MSG_VideoMessage; } bool SrsSharedPtrMessage::is_audio() @@ -316,14 +316,9 @@ bool SrsSharedPtrMessage::is_video() int SrsSharedPtrMessage::chunk_header(char* cache, int nb_cache, bool c0) { if (c0) { - return srs_chunk_header_c0( - ptr->header.perfer_cid, timestamp, ptr->header.payload_length, - ptr->header.message_type, stream_id, - cache, nb_cache); + return srs_chunk_header_c0(ptr->header.perfer_cid, timestamp, ptr->header.payload_length, ptr->header.message_type, stream_id, cache, nb_cache); } else { - return srs_chunk_header_c3( - ptr->header.perfer_cid, timestamp, - cache, nb_cache); + return srs_chunk_header_c3(ptr->header.perfer_cid, timestamp, cache, nb_cache); } } @@ -718,7 +713,7 @@ int SrsFlvDecoder::initialize(ISrsReader* fr) int SrsFlvDecoder::read_header(char header[9]) { int ret = ERROR_SUCCESS; - + srs_assert(header); // TODO: FIXME: Should use readfully. @@ -739,11 +734,11 @@ int SrsFlvDecoder::read_header(char header[9]) int SrsFlvDecoder::read_tag_header(char* ptype, int32_t* pdata_size, uint32_t* ptime) { int ret = ERROR_SUCCESS; - + srs_assert(ptype); srs_assert(pdata_size); srs_assert(ptime); - + char th[11]; // tag header // read tag header @@ -775,14 +770,14 @@ int SrsFlvDecoder::read_tag_header(char* ptype, int32_t* pdata_size, uint32_t* p // TimestampExtended UI8 pp[3] = th[7]; - + return ret; } int SrsFlvDecoder::read_tag_data(char* data, int32_t size) { int ret = ERROR_SUCCESS; - + srs_assert(data); // TODO: FIXME: Should use readfully. @@ -794,13 +789,13 @@ int SrsFlvDecoder::read_tag_data(char* data, int32_t size) } return ret; - + } int SrsFlvDecoder::read_previous_tag_size(char previous_tag_size[4]) { int ret = ERROR_SUCCESS; - + srs_assert(previous_tag_size); // ignore 4bytes tag size. @@ -850,7 +845,7 @@ int SrsFlvVodStreamDecoder::initialize(ISrsReader* fr) int SrsFlvVodStreamDecoder::read_header_ext(char header[13]) { int ret = ERROR_SUCCESS; - + srs_assert(header); // @remark, always false, for sizeof(char[13]) equals to sizeof(char*) @@ -869,7 +864,7 @@ int SrsFlvVodStreamDecoder::read_header_ext(char header[13]) int SrsFlvVodStreamDecoder::read_sequence_header_summary(int64_t* pstart, int* psize) { int ret = ERROR_SUCCESS; - + srs_assert(pstart); srs_assert(psize); @@ -964,16 +959,16 @@ int SrsFlvVodStreamDecoder::seek2(int64_t offset) if (offset >= reader->filesize()) { ret = ERROR_SYSTEM_FILE_EOF; srs_warn("flv fast decoder seek overflow file, " - "size=%"PRId64", offset=%"PRId64", ret=%d", - reader->filesize(), offset, ret); + "size=%"PRId64", offset=%"PRId64", ret=%d", + reader->filesize(), offset, ret); return ret; } if (reader->seek2(offset) < 0) { ret = ERROR_SYSTEM_FILE_SEEK; srs_warn("flv fast decoder seek error, " - "size=%"PRId64", offset=%"PRId64", ret=%d", - reader->filesize(), offset, ret); + "size=%"PRId64", offset=%"PRId64", ret=%d", + reader->filesize(), offset, ret); return ret; } diff --git a/trunk/src/kernel/srs_kernel_flv.hpp b/trunk/src/kernel/srs_kernel_flv.hpp index eae10b212..b445941d5 100644 --- a/trunk/src/kernel/srs_kernel_flv.hpp +++ b/trunk/src/kernel/srs_kernel_flv.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_KERNEL_FLV_HPP #define SRS_KERNEL_FLV_HPP -/* -#include -*/ #include #include @@ -452,43 +449,43 @@ public: 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 int 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 int write_header(); virtual int 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 int 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 int write_audio(int64_t timestamp, char* data, int size); virtual int 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: @@ -516,8 +513,8 @@ private: }; /** -* decode flv file. -*/ + * decode flv file. + */ class SrsFlvDecoder { private: @@ -529,39 +526,39 @@ public: 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 int 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 int 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 int 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 int 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 int 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: @@ -573,30 +570,30 @@ public: 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 int 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 int 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 int 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 int seek2(int64_t offset); }; diff --git a/trunk/src/kernel/srs_kernel_io.cpp b/trunk/src/kernel/srs_kernel_io.cpp index 3f1c188eb..efe205838 100644 --- a/trunk/src/kernel/srs_kernel_io.cpp +++ b/trunk/src/kernel/srs_kernel_io.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include diff --git a/trunk/src/kernel/srs_kernel_io.hpp b/trunk/src/kernel/srs_kernel_io.hpp index 0e62f4de3..71982bdd5 100644 --- a/trunk/src/kernel/srs_kernel_io.hpp +++ b/trunk/src/kernel/srs_kernel_io.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_KERNEL_IO_HPP #define SRS_KERNEL_IO_HPP -/* -#include -*/ - #include // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 @@ -61,7 +57,7 @@ public: virtual ~ISrsSeeker(); public: /** - * The lseek() function repositions the offset of the file descriptor fildes to the argument offset, according to the + * The lseek() function repositions the offset of the file descriptor fildes to the argument offset, according to the * directive whence. lseek() repositions the file pointer fildes as follows: * If whence is SEEK_SET, the offset is set to offset bytes. * If whence is SEEK_CUR, the offset is set to its current location plus offset bytes. diff --git a/trunk/src/kernel/srs_kernel_log.cpp b/trunk/src/kernel/srs_kernel_log.cpp index 34cd8143e..8257b163e 100644 --- a/trunk/src/kernel/srs_kernel_log.cpp +++ b/trunk/src/kernel/srs_kernel_log.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -29,7 +29,7 @@ ISrsLog::ISrsLog() { } -ISrsLog::~ISrsLog() +ISrsLog::~ISrsLog() { } diff --git a/trunk/src/kernel/srs_kernel_log.hpp b/trunk/src/kernel/srs_kernel_log.hpp index 4d9b3e079..b9b29fd2e 100644 --- a/trunk/src/kernel/srs_kernel_log.hpp +++ b/trunk/src/kernel/srs_kernel_log.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_KERNEL_LOG_HPP #define SRS_KERNEL_LOG_HPP -/* -#include -*/ - #include #include @@ -38,14 +34,14 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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. + */ class SrsLogLevel { public: - // only used for very verbose debug, generally, + // only used for very verbose debug, generally, // we compile without this level for high performance. static const int Verbose = 0x01; static const int Info = 0x02; @@ -57,10 +53,10 @@ public: }; /** -* 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: @@ -68,8 +64,8 @@ public: virtual ~ISrsLog(); public: /** - * initialize log utilities. - */ + * initialize log utilities. + */ virtual int initialize(); /** * reopen the log file for log rotate. @@ -77,25 +73,25 @@ public: virtual void reopen(); public: /** - * log for verbose, very verbose information. - */ + * log for verbose, very verbose information. + */ virtual void verbose(const char* tag, int context_id, const char* fmt, ...); /** - * log for debug, detail information. - */ + * log for debug, detail information. + */ virtual void info(const char* tag, int context_id, const char* fmt, ...); /** - * log for trace, important information. - */ + * 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. - */ + * 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. - */ + * 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, ...); }; diff --git a/trunk/src/kernel/srs_kernel_mp3.cpp b/trunk/src/kernel/srs_kernel_mp3.cpp index b6c216837..23cf89695 100644 --- a/trunk/src/kernel/srs_kernel_mp3.cpp +++ b/trunk/src/kernel/srs_kernel_mp3.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -95,7 +95,7 @@ int SrsMp3Transmuxer::write_audio(int64_t timestamp, char* data, int size) if ((ret = stream->initialize(data, size)) != ERROR_SUCCESS) { return ret; } - + // audio decode if (!stream->require(1)) { ret = ERROR_MP3_DECODE_ERROR; @@ -116,7 +116,7 @@ int SrsMp3Transmuxer::write_audio(int64_t timestamp, char* data, int size) srs_error("mp3 required, format=%d. ret=%d", sound_format, ret); return ret; } - + if (!stream->require(1)) { ret = ERROR_MP3_DECODE_ERROR; srs_error("mp3 decode aac_packet_type failed. ret=%d", ret); diff --git a/trunk/src/kernel/srs_kernel_mp3.hpp b/trunk/src/kernel/srs_kernel_mp3.hpp index 9ddc40c3c..8805d5de6 100644 --- a/trunk/src/kernel/srs_kernel_mp3.hpp +++ b/trunk/src/kernel/srs_kernel_mp3.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_KERNEL_MP3_HPP #define SRS_KERNEL_MP3_HPP -/* -#include -*/ #include #if !defined(SRS_EXPORT_LIBRTMP) @@ -50,21 +47,21 @@ public: virtual ~SrsMp3Transmuxer(); public: /** - * initialize the underlayer file stream. - * @remark user can initialize multiple times to encode multiple mp3 files. - * @remark, user must free the @param fw, mp3 encoder never close/free it. - */ + * initialize the underlayer file stream. + * @remark user can initialize multiple times to encode multiple mp3 files. + * @remark, user must free the @param fw, mp3 encoder never close/free it. + */ virtual int initialize(SrsFileWriter* fw); public: /** - * write mp3 id3 v2.3 header. - * @see mp3.id3v2.3.0.pdf, http://id3.org/id3v2.3.0 - */ + * write mp3 id3 v2.3 header. + * @see mp3.id3v2.3.0.pdf, http://id3.org/id3v2.3.0 + */ virtual int write_header(); /** - * write audio/video packet. - * @remark assert data is not NULL. - */ + * write audio/video packet. + * @remark assert data is not NULL. + */ virtual int write_audio(int64_t timestamp, char* data, int size); }; diff --git a/trunk/src/kernel/srs_kernel_mp4.cpp b/trunk/src/kernel/srs_kernel_mp4.cpp index 99cda1cfe..c751b80f9 100644 --- a/trunk/src/kernel/srs_kernel_mp4.cpp +++ b/trunk/src/kernel/srs_kernel_mp4.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -1671,7 +1671,7 @@ int SrsMp4VideoMeidaHeaderBox::decode_header(SrsBuffer* buf) if ((ret = SrsMp4FullBox::decode_header(buf)) != ERROR_SUCCESS) { return ret; } - + graphicsmode = buf->read_2bytes(); opcolor[0] = buf->read_2bytes(); opcolor[1] = buf->read_2bytes(); @@ -3856,10 +3856,10 @@ int SrsMp4SampleManager::load_trak(map& tses, SrsFrameT { int ret = ERROR_SUCCESS; - // Samples per chunk. + // Samples per chunk. stsc->initialize_counter(); - // DTS box. + // DTS box. if ((ret = stts->initialize_counter()) != ERROR_SUCCESS) { return ret; } @@ -4015,8 +4015,7 @@ int SrsMp4Decoder::initialize(ISrsReadSeeker* rs) return ret; } -int SrsMp4Decoder::read_sample(SrsMp4HandlerType* pht, - uint16_t* pft, uint16_t* pct, uint32_t* pdts, uint32_t* ppts, uint8_t** psample, uint32_t* pnb_sample) +int SrsMp4Decoder::read_sample(SrsMp4HandlerType* pht, uint16_t* pft, uint16_t* pct, uint32_t* pdts, uint32_t* ppts, uint8_t** psample, uint32_t* pnb_sample) { int ret = ERROR_SUCCESS; @@ -4197,15 +4196,15 @@ int SrsMp4Decoder::parse_moov(SrsMp4MovieBox* moov) ss << "dur=" << mvhd->duration() << "ms"; // video codec. ss << ", vide=" << moov->nb_vide_tracks() << "(" - << srs_video_codec_id2str(vcodec) << "," << nb_avcc << "BSH" - << ")"; + << srs_video_codec_id2str(vcodec) << "," << nb_avcc << "BSH" + << ")"; // audio codec. ss << ", soun=" << moov->nb_soun_tracks() << "(" - << srs_audio_codec_id2str(acodec) << "," << nb_asc << "BSH" - << "," << srs_audio_channels2str(channels) - << "," << srs_audio_sample_bits2str(sound_bits) - << "," << srs_audio_sample_rate2str(sample_rate) - << ")"; + << srs_audio_codec_id2str(acodec) << "," << nb_asc << "BSH" + << "," << srs_audio_channels2str(channels) + << "," << srs_audio_sample_bits2str(sound_bits) + << "," << srs_audio_sample_rate2str(sample_rate) + << ")"; srs_trace("MP4 moov %s", ss.str().c_str()); @@ -4397,8 +4396,7 @@ int SrsMp4Encoder::initialize(ISrsWriteSeeker* ws) return ret; } -int SrsMp4Encoder::write_sample(SrsMp4HandlerType ht, - uint16_t ft, uint16_t ct, uint32_t dts, uint32_t pts, uint8_t* sample, uint32_t nb_sample) +int SrsMp4Encoder::write_sample(SrsMp4HandlerType ht, uint16_t ft, uint16_t ct, uint32_t dts, uint32_t pts, uint8_t* sample, uint32_t nb_sample) { int ret = ERROR_SUCCESS; diff --git a/trunk/src/kernel/srs_kernel_mp4.hpp b/trunk/src/kernel/srs_kernel_mp4.hpp index c43a501bc..ccd4eed40 100644 --- a/trunk/src/kernel/srs_kernel_mp4.hpp +++ b/trunk/src/kernel/srs_kernel_mp4.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_KERNEL_MP4_HPP #define SRS_KERNEL_MP4_HPP -/* -#include -*/ #include #include @@ -201,7 +198,7 @@ public: protected: virtual int encode_boxes(SrsBuffer* buf); virtual int decode_boxes(SrsBuffer* buf); -// Sub classes can override these functions for special codec. + // Sub classes can override these functions for special codec. protected: // The size of header, not including the contained boxes. virtual int nb_header(); @@ -243,9 +240,9 @@ protected: /** * 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 + * 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 @@ -273,9 +270,9 @@ protected: /** * 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 + * 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). */ class SrsMp4MediaDataBox : public SrsMp4Box @@ -449,8 +446,8 @@ protected: /** * 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 + * 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 @@ -568,7 +565,7 @@ protected: /** * 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. + * 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 @@ -606,8 +603,8 @@ public: /** * 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 + * 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 @@ -761,7 +758,7 @@ public: /** * 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 + * 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 @@ -785,7 +782,7 @@ protected: /** * 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 + * 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 @@ -870,8 +867,8 @@ protected: /** * 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 + * 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 @@ -894,8 +891,8 @@ protected: /** * 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 + * 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 @@ -1220,7 +1217,7 @@ protected: /** * 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 + * The sample description table gives detailed information about the coding type used, and any initialization * information needed for that coding. */ class SrsMp4SampleDescriptionBox : public SrsMp4FullBox @@ -1263,9 +1260,9 @@ struct SrsMp4SttsEntry /** * 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 + * 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 @@ -1308,11 +1305,11 @@ struct SrsMp4CttsEntry // Constructor SrsMp4CttsEntry(); }; - - /** + +/** * 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 + * 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 @@ -1669,8 +1666,7 @@ public: * @remark The decoder will generate the first two audio/video sequence header. */ virtual int 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 int parse_ftyp(SrsMp4FileTypeBox* ftyp); virtual int parse_moov(SrsMp4MovieBox* moov); diff --git a/trunk/src/kernel/srs_kernel_stream.cpp b/trunk/src/kernel/srs_kernel_stream.cpp index 32803e5a4..338f0e7e7 100755 --- a/trunk/src/kernel/srs_kernel_stream.cpp +++ b/trunk/src/kernel/srs_kernel_stream.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -65,6 +65,6 @@ void SrsSimpleStream::erase(int size) void SrsSimpleStream::append(const char* bytes, int size) { srs_assert(size > 0); - + data.insert(data.end(), bytes, bytes + size); } diff --git a/trunk/src/kernel/srs_kernel_stream.hpp b/trunk/src/kernel/srs_kernel_stream.hpp index edab88bb1..40cb3aff4 100644 --- a/trunk/src/kernel/srs_kernel_stream.hpp +++ b/trunk/src/kernel/srs_kernel_stream.hpp @@ -1,41 +1,37 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_KERNEL_STREAM_HPP #define SRS_KERNEL_STREAM_HPP -/* -#include -*/ - #include #include /** -* the simple buffer use vector to append bytes, -* it's for hls and http, and need to be refined in future. -*/ + * the simple buffer use vector to append bytes, + * it's for hls and http, and need to be refined in future. + */ class SrsSimpleStream { private: @@ -45,27 +41,27 @@ public: virtual ~SrsSimpleStream(); public: /** - * get the length of buffer. empty if zero. - * @remark assert length() is not negative. - */ + * get the length of buffer. empty if zero. + * @remark assert length() is not negative. + */ virtual int length(); /** - * get the buffer bytes. - * @return the bytes, NULL if empty. - */ + * get the buffer bytes. + * @return the bytes, NULL if empty. + */ virtual char* bytes(); /** - * erase size of bytes from begin. - * @param size to erase size of bytes. - * clear if size greater than or equals to length() - * @remark ignore size is not positive. - */ + * erase size of bytes from begin. + * @param size to erase size of bytes. + * clear if size greater than or equals to length() + * @remark ignore size is not positive. + */ virtual void erase(int size); /** - * append specified bytes to buffer. - * @param size the size of bytes - * @remark assert size is positive. - */ + * append specified bytes to buffer. + * @param size the size of bytes + * @remark assert size is positive. + */ virtual void append(const char* bytes, int size); }; diff --git a/trunk/src/kernel/srs_kernel_ts.cpp b/trunk/src/kernel/srs_kernel_ts.cpp index 94b286a6d..9fad60400 100644 --- a/trunk/src/kernel/srs_kernel_ts.cpp +++ b/trunk/src/kernel/srs_kernel_ts.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -92,14 +92,14 @@ SrsTsMessage::SrsTsMessage(SrsTsChannel* c, SrsTsPacket* p) { channel = c; packet = p; - + dts = pts = 0; sid = (SrsTsPESStreamId)0x00; continuity_counter = 0; PES_packet_length = 0; payload = new SrsSimpleStream(); is_discontinuity = false; - + start_pts = 0; write_pcr = false; } @@ -112,30 +112,30 @@ SrsTsMessage::~SrsTsMessage() int SrsTsMessage::dump(SrsBuffer* stream, int* pnb_bytes) { int ret = ERROR_SUCCESS; - + if (stream->empty()) { return ret; } - + // xB int nb_bytes = stream->size() - stream->pos(); if (PES_packet_length > 0) { nb_bytes = srs_min(nb_bytes, PES_packet_length - payload->length()); } - + if (nb_bytes > 0) { if (!stream->require(nb_bytes)) { ret = ERROR_STREAM_CASTER_TS_PSE; srs_error("ts: dump PSE bytes failed, requires=%dB. ret=%d", nb_bytes, ret); return ret; } - + payload->append(stream->data() + stream->pos(), nb_bytes); stream->skip(nb_bytes); } - + *pnb_bytes = nb_bytes; - + return ret; } @@ -250,7 +250,7 @@ SrsTsChannel* SrsTsContext::get(int pid) void SrsTsContext::set(int pid, SrsTsPidApply apply_pid, SrsTsStream stream) { SrsTsChannel* channel = NULL; - + if (pids.find(pid) == pids.end()) { channel = new SrsTsChannel(); channel->context = this; @@ -258,7 +258,7 @@ void SrsTsContext::set(int pid, SrsTsPidApply apply_pid, SrsTsStream stream) } else { channel = pids[pid]; } - + channel->pid = pid; channel->apply = apply_pid; channel->stream = stream; @@ -267,42 +267,42 @@ void SrsTsContext::set(int pid, SrsTsPidApply apply_pid, SrsTsStream stream) int SrsTsContext::decode(SrsBuffer* stream, ISrsTsHandler* handler) { int ret = ERROR_SUCCESS; - + // parse util EOF of stream. // for example, parse multiple times for the PES_packet_length(0) packet. while (!stream->empty()) { SrsTsPacket* packet = new SrsTsPacket(this); SrsAutoFree(SrsTsPacket, packet); - + SrsTsMessage* msg = NULL; if ((ret = packet->decode(stream, &msg)) != ERROR_SUCCESS) { srs_error("mpegts: decode ts packet failed. ret=%d", ret); return ret; } - + if (!msg) { continue; } SrsAutoFree(SrsTsMessage, msg); - + if ((ret = handler->on_ts_message(msg)) != ERROR_SUCCESS) { srs_error("mpegts: handler ts message failed. ret=%d", ret); return ret; } } - + return ret; } int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsVideoCodecId vc, SrsAudioCodecId ac) { int ret = ERROR_SUCCESS; - + SrsTsStream vs, as; int16_t video_pid = 0, audio_pid = 0; switch (vc) { - case SrsVideoCodecIdAVC: - vs = SrsTsStreamVideoH264; + case SrsVideoCodecIdAVC: + vs = SrsTsStreamVideoH264; video_pid = TS_VIDEO_AVC_PID; break; case SrsVideoCodecIdDisabled: @@ -321,11 +321,11 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsVideoCodec } switch (ac) { case SrsAudioCodecIdAAC: - as = SrsTsStreamAudioAAC; + as = SrsTsStreamAudioAAC; audio_pid = TS_AUDIO_AAC_PID; break; case SrsAudioCodecIdMP3: - as = SrsTsStreamAudioMp3; + as = SrsTsStreamAudioMp3; audio_pid = TS_AUDIO_MP3_PID; break; case SrsAudioCodecIdDisabled: @@ -362,7 +362,7 @@ int SrsTsContext::encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsVideoCodec return ret; } } - + // encode the media frame to PES packets over TS. if (msg->is_audio()) { return encode_pes(writer, msg, audio_pid, as, vs == SrsTsStreamReserved); @@ -385,23 +385,23 @@ int SrsTsContext::encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStrea srs_error("hls: no pmt pcr pid, vs=%d, as=%d. ret=%d", vs, as, ret); return ret; } - + int16_t pmt_number = TS_PMT_NUMBER; int16_t pmt_pid = TS_PMT_PID; if (true) { SrsTsPacket* pkt = SrsTsPacket::create_pat(this, pmt_number, pmt_pid); SrsAutoFree(SrsTsPacket, pkt); - + pkt->sync_byte = sync_byte; - + char* buf = new char[SRS_TS_PACKET_SIZE]; SrsAutoFreeA(char, buf); - + // set the left bytes with 0xFF. int nb_buf = pkt->size(); srs_assert(nb_buf < SRS_TS_PACKET_SIZE); memset(buf + nb_buf, 0xFF, SRS_TS_PACKET_SIZE - nb_buf); - + SrsBuffer stream; if ((ret = stream.initialize(buf, nb_buf)) != ERROR_SUCCESS) { return ret; @@ -418,17 +418,17 @@ int SrsTsContext::encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStrea if (true) { SrsTsPacket* pkt = SrsTsPacket::create_pmt(this, pmt_number, pmt_pid, vpid, vs, apid, as); SrsAutoFree(SrsTsPacket, pkt); - + pkt->sync_byte = sync_byte; - + char* buf = new char[SRS_TS_PACKET_SIZE]; SrsAutoFreeA(char, buf); - + // set the left bytes with 0xFF. int nb_buf = pkt->size(); srs_assert(nb_buf < SRS_TS_PACKET_SIZE); memset(buf + nb_buf, 0xFF, SRS_TS_PACKET_SIZE - nb_buf); - + SrsBuffer stream; if ((ret = stream.initialize(buf, nb_buf)) != ERROR_SUCCESS) { return ret; @@ -442,30 +442,30 @@ int SrsTsContext::encode_pat_pmt(SrsFileWriter* writer, int16_t vpid, SrsTsStrea return ret; } } - + return ret; } int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t pid, SrsTsStream sid, bool pure_audio) { int ret = ERROR_SUCCESS; - + if (msg->payload->length() == 0) { return ret; } - + if (sid != SrsTsStreamVideoH264 && sid != SrsTsStreamAudioMp3 && sid != SrsTsStreamAudioAAC) { srs_info("ts: ignore the unknown stream, sid=%d", sid); return ret; } - + SrsTsChannel* channel = get(pid); srs_assert(channel); - + char* start = msg->payload->bytes(); char* end = start + msg->payload->length(); char* p = start; - + while (p < end) { SrsTsPacket* pkt = NULL; if (p == start) { @@ -477,7 +477,7 @@ int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t p if (pure_audio && msg->is_audio()) { write_pcr = true; } - + // it's ok to set pcr equals to dts, // @see https://github.com/ossrs/srs/issues/311 // Fig. 3.18. Program Clock Reference of Digital-Video-and-Audio-Broadcasting-Technology, page 65 @@ -491,46 +491,44 @@ int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t p int64_t pcr = write_pcr? msg->dts : -1; // TODO: FIXME: finger it why use discontinuity of msg. - pkt = SrsTsPacket::create_pes_first(this, + pkt = SrsTsPacket::create_pes_first(this, pid, msg->sid, channel->continuity_counter++, msg->is_discontinuity, pcr, msg->dts, msg->pts, msg->payload->length() ); } else { - pkt = SrsTsPacket::create_pes_continue(this, - pid, msg->sid, channel->continuity_counter++ - ); + pkt = SrsTsPacket::create_pes_continue(this, pid, msg->sid, channel->continuity_counter++); } SrsAutoFree(SrsTsPacket, pkt); - + pkt->sync_byte = sync_byte; - + char* buf = new char[SRS_TS_PACKET_SIZE]; SrsAutoFreeA(char, buf); - + // set the left bytes with 0xFF. int nb_buf = pkt->size(); srs_assert(nb_buf < SRS_TS_PACKET_SIZE); - + int left = (int)srs_min(end - p, SRS_TS_PACKET_SIZE - nb_buf); int nb_stuffings = SRS_TS_PACKET_SIZE - nb_buf - left; if (nb_stuffings > 0) { // set all bytes to stuffings. memset(buf, 0xFF, SRS_TS_PACKET_SIZE); - + // padding with stuffings. pkt->padding(nb_stuffings); - + // size changed, recalc it. nb_buf = pkt->size(); srs_assert(nb_buf < SRS_TS_PACKET_SIZE); - + left = (int)srs_min(end - p, SRS_TS_PACKET_SIZE - nb_buf); nb_stuffings = SRS_TS_PACKET_SIZE - nb_buf - left; srs_assert(nb_stuffings == 0); } memcpy(buf + nb_buf, p, left); p += left; - + SrsBuffer stream; if ((ret = stream.initialize(buf, nb_buf)) != ERROR_SUCCESS) { return ret; @@ -544,14 +542,14 @@ int SrsTsContext::encode_pes(SrsFileWriter* writer, SrsTsMessage* msg, int16_t p return ret; } } - + return ret; } SrsTsPacket::SrsTsPacket(SrsTsContext* c) { context = c; - + sync_byte = 0; transport_error_indicator = 0; payload_unit_start_indicator = 0; @@ -573,16 +571,16 @@ SrsTsPacket::~SrsTsPacket() int SrsTsPacket::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) { int ret = ERROR_SUCCESS; - + int pos = stream->pos(); - + // 4B ts packet header. if (!stream->require(4)) { ret = ERROR_STREAM_CASTER_TS_HEADER; srs_error("ts: demux header failed. ret=%d", ret); return ret; } - + sync_byte = stream->read_1bytes(); if (sync_byte != 0x47) { ret = ERROR_STREAM_CASTER_TS_SYNC_BYTE; @@ -595,33 +593,33 @@ int SrsTsPacket::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) payload_unit_start_indicator = (pidv >> 14) & 0x01; transport_priority = (pidv >> 13) & 0x01; pid = (SrsTsPid)(pidv & 0x1FFF); - + int8_t ccv = stream->read_1bytes(); transport_scrambling_control = (SrsTsScrambled)((ccv >> 6) & 0x03); adaption_field_control = (SrsTsAdaptationFieldType)((ccv >> 4) & 0x03); continuity_counter = ccv & 0x0F; - + // TODO: FIXME: create pids map when got new pid. srs_info("ts: header sync=%#x error=%d unit_start=%d priotiry=%d pid=%d scrambling=%d adaption=%d counter=%d", - sync_byte, transport_error_indicator, payload_unit_start_indicator, transport_priority, pid, - transport_scrambling_control, adaption_field_control, continuity_counter); - + sync_byte, transport_error_indicator, payload_unit_start_indicator, transport_priority, pid, + transport_scrambling_control, adaption_field_control, continuity_counter); + // optional: adaptation field if (adaption_field_control == SrsTsAdaptationFieldTypeAdaptionOnly || adaption_field_control == SrsTsAdaptationFieldTypeBoth) { srs_freep(adaptation_field); adaptation_field = new SrsTsAdaptationField(this); - + if ((ret = adaptation_field->decode(stream)) != ERROR_SUCCESS) { srs_error("ts: demux af faield. ret=%d", ret); return ret; } srs_verbose("ts: demux af ok."); } - + // calc the user defined data size for payload. int nb_payload = SRS_TS_PACKET_SIZE - (stream->pos() - pos); - + // optional: payload. if (adaption_field_control == SrsTsAdaptationFieldTypePayloadOnly || adaption_field_control == SrsTsAdaptationFieldTypeBoth) { if (pid == SrsTsPidPAT) { @@ -643,13 +641,13 @@ int SrsTsPacket::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) stream->skip(nb_payload); } } - + if (payload && (ret = payload->decode(stream, ppmsg)) != ERROR_SUCCESS) { srs_error("ts: demux payload failed. ret=%d", ret); return ret; } } - + return ret; } @@ -659,38 +657,38 @@ int SrsTsPacket::size() sz += adaptation_field? adaptation_field->size() : 0; sz += payload? payload->size() : 0; - + return sz; } int SrsTsPacket::encode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + // 4B ts packet header. if (!stream->require(4)) { ret = ERROR_STREAM_CASTER_TS_HEADER; srs_error("ts: mux header failed. ret=%d", ret); return ret; } - + stream->write_1bytes(sync_byte); - + int16_t pidv = pid & 0x1FFF; pidv |= (transport_priority << 13) & 0x2000; pidv |= (transport_error_indicator << 15) & 0x8000; pidv |= (payload_unit_start_indicator << 14) & 0x4000; stream->write_2bytes(pidv); - + int8_t ccv = continuity_counter & 0x0F; ccv |= (transport_scrambling_control << 6) & 0xC0; ccv |= (adaption_field_control << 4) & 0x30; stream->write_1bytes(ccv); srs_info("ts: header sync=%#x error=%d unit_start=%d priotiry=%d pid=%d scrambling=%d adaption=%d counter=%d", - sync_byte, transport_error_indicator, payload_unit_start_indicator, transport_priority, pid, - transport_scrambling_control, adaption_field_control, continuity_counter); - + sync_byte, transport_error_indicator, payload_unit_start_indicator, transport_priority, pid, + transport_scrambling_control, adaption_field_control, continuity_counter); + // optional: adaptation field if (adaptation_field) { if ((ret = adaptation_field->encode(stream)) != ERROR_SUCCESS) { @@ -699,7 +697,7 @@ int SrsTsPacket::encode(SrsBuffer* stream) } srs_verbose("ts: mux af ok."); } - + // optional: payload. if (payload) { if ((ret = payload->encode(stream)) != ERROR_SUCCESS) { @@ -708,7 +706,7 @@ int SrsTsPacket::encode(SrsBuffer* stream) } srs_verbose("ts: mux payload ok."); } - + return ret; } @@ -717,7 +715,7 @@ void SrsTsPacket::padding(int nb_stuffings) if (!adaptation_field) { SrsTsAdaptationField* af = new SrsTsAdaptationField(this); adaptation_field = af; - + af->adaption_field_length = 0; // calc in size. af->discontinuity_indicator = 0; af->random_access_indicator = 0; @@ -727,13 +725,13 @@ void SrsTsPacket::padding(int nb_stuffings) af->splicing_point_flag = 0; af->transport_private_data_flag = 0; af->adaptation_field_extension_flag = 0; - + // consume the af size if possible. nb_stuffings = srs_max(0, nb_stuffings - af->size()); } - + adaptation_field->nb_af_reserved = nb_stuffings; - + // set payload with af. if (adaption_field_control == SrsTsAdaptationFieldTypePayloadOnly) { adaption_field_control = SrsTsAdaptationFieldTypeBoth; @@ -754,7 +752,7 @@ SrsTsPacket* SrsTsPacket::create_pat(SrsTsContext* context, int16_t pmt_number, pkt->adaptation_field = NULL; SrsTsPayloadPAT* pat = new SrsTsPayloadPAT(pkt); pkt->payload = pat; - + pat->pointer_field = 0; pat->table_id = SrsTsPsiIdPas; pat->section_syntax_indicator = 1; @@ -784,7 +782,7 @@ SrsTsPacket* SrsTsPacket::create_pmt(SrsTsContext* context, int16_t pmt_number, pkt->adaptation_field = NULL; SrsTsPayloadPMT* pmt = new SrsTsPayloadPMT(pkt); pkt->payload = pmt; - + pmt->pointer_field = 0; pmt->table_id = SrsTsPsiIdPms; pmt->section_syntax_indicator = 1; @@ -817,10 +815,10 @@ SrsTsPacket* SrsTsPacket::create_pmt(SrsTsContext* context, int16_t pmt_number, return pkt; } -SrsTsPacket* 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 -) { +SrsTsPacket* 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 + ) { SrsTsPacket* pkt = new SrsTsPacket(context); pkt->sync_byte = 0x47; pkt->transport_error_indicator = 0; @@ -833,12 +831,12 @@ SrsTsPacket* SrsTsPacket::create_pes_first(SrsTsContext* context, pkt->adaptation_field = NULL; SrsTsPayloadPES* pes = new SrsTsPayloadPES(pkt); pkt->payload = pes; - + if (pcr >= 0) { SrsTsAdaptationField* af = new SrsTsAdaptationField(pkt); pkt->adaptation_field = af; pkt->adaption_field_control = SrsTsAdaptationFieldTypeBoth; - + af->adaption_field_length = 0; // calc in size. af->discontinuity_indicator = discontinuity; af->random_access_indicator = 0; @@ -851,7 +849,7 @@ SrsTsPacket* SrsTsPacket::create_pes_first(SrsTsContext* context, af->program_clock_reference_base = pcr; af->program_clock_reference_extension = 0; } - + pes->packet_start_code_prefix = 0x01; pes->stream_id = (uint8_t)sid; pes->PES_packet_length = (size > 0xFFFF)? 0:size; @@ -873,9 +871,8 @@ SrsTsPacket* SrsTsPacket::create_pes_first(SrsTsContext* context, return pkt; } -SrsTsPacket* SrsTsPacket::create_pes_continue(SrsTsContext* context, - int16_t pid, SrsTsPESStreamId sid, uint8_t continuity_counter -) { +SrsTsPacket* SrsTsPacket::create_pes_continue(SrsTsContext* context, int16_t pid, SrsTsPESStreamId sid, uint8_t continuity_counter) +{ SrsTsPacket* pkt = new SrsTsPacket(context); pkt->sync_byte = 0x47; pkt->transport_error_indicator = 0; @@ -887,14 +884,14 @@ SrsTsPacket* SrsTsPacket::create_pes_continue(SrsTsContext* context, pkt->continuity_counter = continuity_counter; pkt->adaptation_field = NULL; pkt->payload = NULL; - + return pkt; } SrsTsAdaptationField::SrsTsAdaptationField(SrsTsPacket* pkt) { packet = pkt; - + adaption_field_length = 0; discontinuity_indicator = 0; random_access_indicator = 0; @@ -927,7 +924,7 @@ SrsTsAdaptationField::SrsTsAdaptationField(SrsTsPacket* pkt) marker_bit2 = 0; nb_af_ext_reserved = 0; nb_af_reserved = 0; - + const1_value0 = 0x3F; const1_value1 = 0x1F; const1_value2 = 0x3F; @@ -941,16 +938,16 @@ SrsTsAdaptationField::~SrsTsAdaptationField() int SrsTsAdaptationField::decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + if (!stream->require(2)) { ret = ERROR_STREAM_CASTER_TS_AF; srs_error("ts: demux af failed. ret=%d", ret); return ret; } adaption_field_length = stream->read_1bytes(); - + // When the adaptation_field_control value is '11', the value of the adaptation_field_length shall - // be in the range 0 to 182. + // be in the range 0 to 182. if (packet->adaption_field_control == SrsTsAdaptationFieldTypeBoth && adaption_field_length > 182) { ret = ERROR_STREAM_CASTER_TS_AF; srs_error("ts: demux af length failed, must in [0, 182], actual=%d. ret=%d", adaption_field_length, ret); @@ -969,7 +966,7 @@ int SrsTsAdaptationField::decode(SrsBuffer* stream) srs_info("ts: demux af empty."); return ret; } - + // the adaptation field start at here. int pos_af = stream->pos(); int8_t tmpv = stream->read_1bytes(); @@ -989,11 +986,11 @@ int SrsTsAdaptationField::decode(SrsBuffer* stream) srs_error("ts: demux af PCR_flag failed. ret=%d", ret); return ret; } - + char* pp = NULL; char* p = stream->data() + stream->pos(); stream->skip(6); - + int64_t pcrv = 0; pp = (char*)&pcrv; pp[5] = *p++; @@ -1009,14 +1006,14 @@ int SrsTsAdaptationField::decode(SrsBuffer* stream) const1_value0 = (pcrv >> 9) & 0x3F; program_clock_reference_base = (pcrv >> 15) & 0x1ffffffffLL; } - + if (OPCR_flag) { if (!stream->require(6)) { ret = ERROR_STREAM_CASTER_TS_AF; srs_error("ts: demux af OPCR_flag failed. ret=%d", ret); return ret; } - + char* pp = NULL; char* p = stream->data() + stream->pos(); stream->skip(6); @@ -1036,7 +1033,7 @@ int SrsTsAdaptationField::decode(SrsBuffer* stream) const1_value2 = (opcrv >> 9) & 0x3F; original_program_clock_reference_base = (opcrv >> 15) & 0x1ffffffffLL; } - + if (splicing_point_flag) { if (!stream->require(1)) { ret = ERROR_STREAM_CASTER_TS_AF; @@ -1053,7 +1050,7 @@ int SrsTsAdaptationField::decode(SrsBuffer* stream) return ret; } transport_private_data_length = (uint8_t)stream->read_1bytes(); - + if (transport_private_data_length> 0) { if (!stream->require(transport_private_data_length)) { ret = ERROR_STREAM_CASTER_TS_AF; @@ -1068,7 +1065,7 @@ int SrsTsAdaptationField::decode(SrsBuffer* stream) if (adaptation_field_extension_flag) { int pos_af_ext = stream->pos(); - + if (!stream->require(2)) { ret = ERROR_STREAM_CASTER_TS_AF; srs_error("ts: demux af adaptation_field_extension_flag failed. ret=%d", ret); @@ -1081,7 +1078,7 @@ int SrsTsAdaptationField::decode(SrsBuffer* stream) seamless_splice_flag = (ltwfv >> 5) & 0x01; ltw_flag = (ltwfv >> 7) & 0x01; const1_value1 = ltwfv & 0x1F; - + if (ltw_flag) { if (!stream->require(2)) { ret = ERROR_STREAM_CASTER_TS_AF; @@ -1093,7 +1090,7 @@ int SrsTsAdaptationField::decode(SrsBuffer* stream) ltw_valid_flag = (ltw_offset >> 15) &0x01; ltw_offset &= 0x7FFF; } - + if (piecewise_rate_flag) { if (!stream->require(3)) { ret = ERROR_STREAM_CASTER_TS_AF; @@ -1101,10 +1098,10 @@ int SrsTsAdaptationField::decode(SrsBuffer* stream) return ret; } piecewise_rate = stream->read_3bytes(); - + piecewise_rate &= 0x3FFFFF; } - + if (seamless_splice_flag) { if (!stream->require(5)) { ret = ERROR_STREAM_CASTER_TS_AF; @@ -1125,26 +1122,26 @@ int SrsTsAdaptationField::decode(SrsBuffer* stream) marker_bit2 = DTS_next_AU2 & 0x01; DTS_next_AU2 = (DTS_next_AU2 >> 1) & 0x7FFF; } - + nb_af_ext_reserved = adaptation_field_extension_length - (stream->pos() - pos_af_ext); stream->skip(nb_af_ext_reserved); } - + nb_af_reserved = adaption_field_length - (stream->pos() - pos_af); stream->skip(nb_af_reserved); srs_info("ts: af parsed, discontinuity=%d random=%d priority=%d PCR=%d OPCR=%d slicing=%d private=%d extension=%d/%d pcr=%"PRId64"/%d opcr=%"PRId64"/%d", - discontinuity_indicator, random_access_indicator, elementary_stream_priority_indicator, PCR_flag, OPCR_flag, splicing_point_flag, - transport_private_data_flag, adaptation_field_extension_flag, adaptation_field_extension_length, program_clock_reference_base, - program_clock_reference_extension, original_program_clock_reference_base, original_program_clock_reference_extension); - + discontinuity_indicator, random_access_indicator, elementary_stream_priority_indicator, PCR_flag, OPCR_flag, splicing_point_flag, + transport_private_data_flag, adaptation_field_extension_flag, adaptation_field_extension_length, program_clock_reference_base, + program_clock_reference_extension, original_program_clock_reference_base, original_program_clock_reference_extension); + return ret; } int SrsTsAdaptationField::size() { int sz = 2; - + sz += PCR_flag? 6 : 0; sz += OPCR_flag? 6 : 0; sz += splicing_point_flag? 1 : 0; @@ -1152,25 +1149,25 @@ int SrsTsAdaptationField::size() sz += adaptation_field_extension_flag? 2 + adaptation_field_extension_length : 0; sz += nb_af_ext_reserved; sz += nb_af_reserved; - + adaption_field_length = sz - 1; - + return sz; } int SrsTsAdaptationField::encode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + if (!stream->require(2)) { ret = ERROR_STREAM_CASTER_TS_AF; srs_error("ts: mux af failed. ret=%d", ret); return ret; } stream->write_1bytes(adaption_field_length); - + // When the adaptation_field_control value is '11', the value of the adaptation_field_length shall - // be in the range 0 to 182. + // be in the range 0 to 182. if (packet->adaption_field_control == SrsTsAdaptationFieldTypeBoth && adaption_field_length > 182) { ret = ERROR_STREAM_CASTER_TS_AF; srs_error("ts: mux af length failed, must in [0, 182], actual=%d. ret=%d", adaption_field_length, ret); @@ -1205,7 +1202,7 @@ int SrsTsAdaptationField::encode(SrsBuffer* stream) srs_error("ts: mux af PCR_flag failed. ret=%d", ret); return ret; } - + char* pp = NULL; char* p = stream->data() + stream->pos(); stream->skip(6); @@ -1215,7 +1212,7 @@ int SrsTsAdaptationField::encode(SrsBuffer* stream) int64_t pcrv = program_clock_reference_extension & 0x1ff; pcrv |= (const1_value0 << 9) & 0x7E00; pcrv |= (program_clock_reference_base << 15) & 0xFFFFFFFF8000LL; - + pp = (char*)&pcrv; *p++ = pp[5]; *p++ = pp[4]; @@ -1224,7 +1221,7 @@ int SrsTsAdaptationField::encode(SrsBuffer* stream) *p++ = pp[1]; *p++ = pp[0]; } - + if (OPCR_flag) { if (!stream->require(6)) { ret = ERROR_STREAM_CASTER_TS_AF; @@ -1234,7 +1231,7 @@ int SrsTsAdaptationField::encode(SrsBuffer* stream) stream->skip(6); srs_warn("ts: mux af ignore OPCR"); } - + if (splicing_point_flag) { if (!stream->require(1)) { ret = ERROR_STREAM_CASTER_TS_AF; @@ -1251,7 +1248,7 @@ int SrsTsAdaptationField::encode(SrsBuffer* stream) return ret; } stream->write_1bytes(transport_private_data_length); - + if (transport_private_data_length> 0) { if (!stream->require(transport_private_data_length)) { ret = ERROR_STREAM_CASTER_TS_AF; @@ -1274,7 +1271,7 @@ int SrsTsAdaptationField::encode(SrsBuffer* stream) ltwfv |= (piecewise_rate_flag << 6) & 0x40; ltwfv |= (seamless_splice_flag << 5) & 0x20; stream->write_1bytes(ltwfv); - + if (ltw_flag) { if (!stream->require(2)) { ret = ERROR_STREAM_CASTER_TS_AF; @@ -1284,7 +1281,7 @@ int SrsTsAdaptationField::encode(SrsBuffer* stream) stream->skip(2); srs_warn("ts: mux af ignore ltw"); } - + if (piecewise_rate_flag) { if (!stream->require(3)) { ret = ERROR_STREAM_CASTER_TS_AF; @@ -1294,7 +1291,7 @@ int SrsTsAdaptationField::encode(SrsBuffer* stream) stream->skip(3); srs_warn("ts: mux af ignore piecewise_rate"); } - + if (seamless_splice_flag) { if (!stream->require(5)) { ret = ERROR_STREAM_CASTER_TS_AF; @@ -1304,21 +1301,21 @@ int SrsTsAdaptationField::encode(SrsBuffer* stream) stream->skip(5); srs_warn("ts: mux af ignore seamless_splice"); } - + if (nb_af_ext_reserved) { stream->skip(nb_af_ext_reserved); } } - + if (nb_af_reserved) { stream->skip(nb_af_reserved); } srs_info("ts: af parsed, discontinuity=%d random=%d priority=%d PCR=%d OPCR=%d slicing=%d private=%d extension=%d/%d pcr=%"PRId64"/%d opcr=%"PRId64"/%d", - discontinuity_indicator, random_access_indicator, elementary_stream_priority_indicator, PCR_flag, OPCR_flag, splicing_point_flag, - transport_private_data_flag, adaptation_field_extension_flag, adaptation_field_extension_length, program_clock_reference_base, - program_clock_reference_extension, original_program_clock_reference_base, original_program_clock_reference_extension); - + discontinuity_indicator, random_access_indicator, elementary_stream_priority_indicator, PCR_flag, OPCR_flag, splicing_point_flag, + transport_private_data_flag, adaptation_field_extension_flag, adaptation_field_extension_length, program_clock_reference_base, + program_clock_reference_extension, original_program_clock_reference_base, original_program_clock_reference_extension); + return ret; } @@ -1353,7 +1350,7 @@ SrsTsPayloadPES::~SrsTsPayloadPES() int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) { int ret = ERROR_SUCCESS; - + // find the channel from chunk. SrsTsChannel* channel = packet->context->get(packet->pid); if (!channel) { @@ -1361,7 +1358,7 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) srs_error("ts: demux PES no channel for pid=%#x. ret=%d", packet->pid, ret); return ret; } - + // init msg. SrsTsMessage* msg = channel->msg; if (!msg) { @@ -1373,53 +1370,53 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) // for the PES_packet_length is 0, the first payload_unit_start_indicator always 1, // so should check for the fresh and not completed it. bool is_fresh_msg = msg->fresh(); - + // check when fresh, the payload_unit_start_indicator // should be 1 for the fresh msg. if (is_fresh_msg && !packet->payload_unit_start_indicator) { ret = ERROR_STREAM_CASTER_TS_PSE; srs_error("ts: PES fresh packet length=%d, us=%d, cc=%d. ret=%d", - msg->PES_packet_length, packet->payload_unit_start_indicator, packet->continuity_counter, - ret); + msg->PES_packet_length, packet->payload_unit_start_indicator, packet->continuity_counter, + ret); return ret; } - + // check when not fresh and PES_packet_length>0, // the payload_unit_start_indicator should never be 1 when not completed. if (!is_fresh_msg && msg->PES_packet_length > 0 && !msg->completed(packet->payload_unit_start_indicator) && packet->payload_unit_start_indicator - ) { + ) { ret = ERROR_STREAM_CASTER_TS_PSE; srs_error("ts: PES packet length=%d, payload=%d, us=%d, cc=%d. ret=%d", - msg->PES_packet_length, msg->payload->length(), packet->payload_unit_start_indicator, - packet->continuity_counter, ret); - + msg->PES_packet_length, msg->payload->length(), packet->payload_unit_start_indicator, + packet->continuity_counter, ret); + // reparse current msg. stream->skip(stream->pos() * -1); srs_freep(msg); channel->msg = NULL; return ERROR_SUCCESS; } - + // check the continuity counter if (!is_fresh_msg) { // late-incoming or duplicated continuity, drop message. // @remark check overflow, the counter plus 1 should greater when invalid. if (msg->continuity_counter >= packet->continuity_counter && ((msg->continuity_counter + 1) & 0x0f) > packet->continuity_counter - ) { + ) { srs_warn("ts: drop PES %dB for duplicated cc=%#x", msg->continuity_counter); stream->skip(stream->size() - stream->pos()); return ret; } - + // when got partially message, the continous count must be continuous, or drop it. if (((msg->continuity_counter + 1) & 0x0f) != packet->continuity_counter) { ret = ERROR_STREAM_CASTER_TS_PSE; srs_error("ts: continuity must be continous, msg=%#x, packet=%#x. ret=%d", - msg->continuity_counter, packet->continuity_counter, ret); - + msg->continuity_counter, packet->continuity_counter, ret); + // reparse current msg. stream->skip(stream->pos() * -1); srs_freep(msg); @@ -1428,25 +1425,25 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) } } msg->continuity_counter = packet->continuity_counter; - + // for the PES_packet_length(0), reap when completed. if (!is_fresh_msg && msg->completed(packet->payload_unit_start_indicator)) { // reap previous PES packet. *ppmsg = msg; channel->msg = NULL; - + // reparse current msg. stream->skip(stream->pos() * -1); return ret; } - + // contious packet, append bytes for unit start is 0 if (!packet->payload_unit_start_indicator) { if ((ret = msg->dump(stream, &nb_bytes)) != ERROR_SUCCESS) { return ret; } } - + // when unit start, parse the fresh msg. if (packet->payload_unit_start_indicator) { // 6B fixed header. @@ -1461,7 +1458,7 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) stream_id = stream->read_1bytes(); // 2B PES_packet_length = stream->read_2bytes(); - + // check the packet start prefix. packet_start_code_prefix &= 0xFFFFFF; if (packet_start_code_prefix != 0x01) { @@ -1470,12 +1467,12 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) return ret; } int pos_packet = stream->pos(); - + // @remark the sid indicates the elementary stream format. // the SrsTsPESStreamIdAudio and SrsTsPESStreamIdVideo is start by 0b110 or 0b1110 SrsTsPESStreamId sid = (SrsTsPESStreamId)stream_id; msg->sid = sid; - + if (sid != SrsTsPESStreamIdProgramStreamMap && sid != SrsTsPESStreamIdPaddingStream && sid != SrsTsPESStreamIdPrivateStream2 @@ -1484,7 +1481,7 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) && sid != SrsTsPESStreamIdProgramStreamDirectory && sid != SrsTsPESStreamIdDsmccStream && sid != SrsTsPESStreamIdH2221TypeE - ) { + ) { // 3B flags. if (!stream->require(3)) { ret = ERROR_STREAM_CASTER_TS_PSE; @@ -1499,14 +1496,14 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) PES_header_data_length = stream->read_1bytes(); // position of header start. int pos_header = stream->pos(); - + const2bits = (oocv >> 6) & 0x03; PES_scrambling_control = (oocv >> 4) & 0x03; PES_priority = (oocv >> 3) & 0x01; data_alignment_indicator = (oocv >> 2) & 0x01; copyright = (oocv >> 1) & 0x01; original_or_copy = oocv & 0x01; - + PTS_DTS_flags = (pefv >> 6) & 0x03; ESCR_flag = (pefv >> 5) & 0x01; ES_rate_flag = (pefv >> 4) & 0x01; @@ -1514,7 +1511,7 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) additional_copy_info_flag = (pefv >> 2) & 0x01; PES_CRC_flag = (pefv >> 1) & 0x01; PES_extension_flag = pefv & 0x01; - + // check required together. int nb_required = 0; nb_required += (PTS_DTS_flags == 0x2)? 5:0; @@ -1530,19 +1527,19 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) srs_error("ts: demux PES payload failed. ret=%d", ret); return ret; } - + // 5B if (PTS_DTS_flags == 0x2) { if ((ret = decode_33bits_dts_pts(stream, &pts)) != ERROR_SUCCESS) { return ret; } dts = pts; - + // update the dts and pts of message. msg->dts = dts; msg->pts = pts; } - + // 10B if (PTS_DTS_flags == 0x3) { if ((ret = decode_33bits_dts_pts(stream, &pts)) != ERROR_SUCCESS) { @@ -1551,65 +1548,65 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) if ((ret = decode_33bits_dts_pts(stream, &dts)) != ERROR_SUCCESS) { return ret; } - + // check sync, the diff of dts and pts should never greater than 1s. if (dts - pts > 90000 || pts - dts > 90000) { srs_warn("ts: sync dts=%"PRId64", pts=%"PRId64, dts, pts); } - + // update the dts and pts of message. msg->dts = dts; msg->pts = pts; } - + // 6B if (ESCR_flag) { ESCR_extension = 0; ESCR_base = 0; - + stream->skip(6); srs_warn("ts: demux PES, ignore the escr."); } - + // 3B if (ES_rate_flag) { ES_rate = stream->read_3bytes(); - + ES_rate = ES_rate >> 1; ES_rate &= 0x3FFFFF; } - + // 1B if (DSM_trick_mode_flag) { trick_mode_control = stream->read_1bytes(); - + trick_mode_value = trick_mode_control & 0x1f; trick_mode_control = (trick_mode_control >> 5) & 0x03; } - + // 1B if (additional_copy_info_flag) { additional_copy_info = stream->read_1bytes(); - + additional_copy_info &= 0x7f; } - + // 2B if (PES_CRC_flag) { previous_PES_packet_CRC = stream->read_2bytes(); } - + // 1B if (PES_extension_flag) { int8_t efv = stream->read_1bytes(); - + PES_private_data_flag = (efv >> 7) & 0x01; pack_header_field_flag = (efv >> 6) & 0x01; program_packet_sequence_counter_flag = (efv >> 5) & 0x01; P_STD_buffer_flag = (efv >> 4) & 0x01; const1_value0 = (efv >> 1) & 0x07; PES_extension_flag_2 = efv & 0x01; - + nb_required = 0; nb_required += PES_private_data_flag? 16:0; nb_required += pack_header_field_flag? 1:0; // 1+x bytes. @@ -1621,14 +1618,14 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) srs_error("ts: demux PSE ext payload failed. ret=%d", ret); return ret; } - + // 16B if (PES_private_data_flag) { srs_freepa(PES_private_data); PES_private_data = new char[16]; stream->read_bytes(PES_private_data, 16); } - + // (1+x)B if (pack_header_field_flag) { pack_field_length = stream->read_1bytes(); @@ -1645,33 +1642,33 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) stream->read_bytes(pack_field, pack_field_length); } } - + // 2B if (program_packet_sequence_counter_flag) { program_packet_sequence_counter = stream->read_1bytes(); program_packet_sequence_counter &= 0x7f; - + original_stuff_length = stream->read_1bytes(); MPEG1_MPEG2_identifier = (original_stuff_length >> 6) & 0x01; original_stuff_length &= 0x3f; } - + // 2B if (P_STD_buffer_flag) { P_STD_buffer_size = stream->read_2bytes(); - + // '01' //int8_t const2bits = (P_STD_buffer_scale >>14) & 0x03; - + P_STD_buffer_scale = (P_STD_buffer_scale >>13) & 0x01; P_STD_buffer_size &= 0x1FFF; } - + // (1+x)B if (PES_extension_flag_2) { PES_extension_field_length = stream->read_1bytes(); PES_extension_field_length &= 0x07; - + if (PES_extension_field_length > 0) { if (!stream->require(PES_extension_field_length)) { ret = ERROR_STREAM_CASTER_TS_PSE; @@ -1684,7 +1681,7 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) } } } - + // stuffing_byte nb_stuffings = PES_header_data_length - (stream->pos() - pos_header); if (nb_stuffings > 0) { @@ -1695,7 +1692,7 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) } stream->skip(nb_stuffings); } - + // PES_packet_data_byte, page58. // the packet size contains the header size. // The number of PES_packet_data_bytes, N, is specified by the @@ -1704,31 +1701,31 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) // between the last byte of the PES_packet_length field and the // first PES_packet_data_byte. /** - * when actual packet length > 0xffff(65535), - * which exceed the max uint16_t packet length, - * use 0 packet length, the next unit start indicates the end of packet. - */ + * when actual packet length > 0xffff(65535), + * which exceed the max uint16_t packet length, + * use 0 packet length, the next unit start indicates the end of packet. + */ if (PES_packet_length > 0) { int nb_packet = PES_packet_length - (stream->pos() - pos_packet); msg->PES_packet_length = srs_max(0, nb_packet); } - + // xB if ((ret = msg->dump(stream, &nb_bytes)) != ERROR_SUCCESS) { return ret; } } else if (sid == SrsTsPESStreamIdProgramStreamMap - || sid == SrsTsPESStreamIdPrivateStream2 - || sid == SrsTsPESStreamIdEcmStream - || sid == SrsTsPESStreamIdEmmStream - || sid == SrsTsPESStreamIdProgramStreamDirectory - || sid == SrsTsPESStreamIdDsmccStream - || sid == SrsTsPESStreamIdH2221TypeE - ) { + || sid == SrsTsPESStreamIdPrivateStream2 + || sid == SrsTsPESStreamIdEcmStream + || sid == SrsTsPESStreamIdEmmStream + || sid == SrsTsPESStreamIdProgramStreamDirectory + || sid == SrsTsPESStreamIdDsmccStream + || sid == SrsTsPESStreamIdH2221TypeE + ) { // for (i = 0; i < PES_packet_length; i++) { // PES_packet_data_byte // } - + // xB if ((ret = msg->dump(stream, &nb_bytes)) != ERROR_SUCCESS) { return ret; @@ -1753,14 +1750,14 @@ int SrsTsPayloadPES::decode(SrsBuffer* stream, SrsTsMessage** ppmsg) if (is_fresh_msg && msg->PES_packet_length == 0) { return ret; } - + // check msg, reap when completed. if (msg->completed(packet->payload_unit_start_indicator)) { *ppmsg = msg; channel->msg = NULL; srs_info("ts: reap msg for completed."); } - + return ret; } @@ -1770,7 +1767,7 @@ int SrsTsPayloadPES::size() PES_header_data_length = 0; SrsTsPESStreamId sid = (SrsTsPESStreamId)stream_id; - + if (sid != SrsTsPESStreamIdProgramStreamMap && sid != SrsTsPESStreamIdPaddingStream && sid != SrsTsPESStreamIdPrivateStream2 @@ -1779,11 +1776,11 @@ int SrsTsPayloadPES::size() && sid != SrsTsPESStreamIdProgramStreamDirectory && sid != SrsTsPESStreamIdDsmccStream && sid != SrsTsPESStreamIdH2221TypeE - ) { + ) { sz += 6; sz += 3; PES_header_data_length = sz; - + sz += (PTS_DTS_flags == 0x2)? 5:0; sz += (PTS_DTS_flags == 0x3)? 10:0; sz += ESCR_flag? 6:0; @@ -1792,7 +1789,7 @@ int SrsTsPayloadPES::size() sz += additional_copy_info_flag? 1:0; sz += PES_CRC_flag? 2:0; sz += PES_extension_flag? 1:0; - + if (PES_extension_flag) { sz += PES_private_data_flag? 16:0; sz += pack_header_field_flag? 1 + pack_field_length:0; // 1+x bytes. @@ -1801,37 +1798,37 @@ int SrsTsPayloadPES::size() sz += PES_extension_flag_2? 1 + PES_extension_field_length:0; // 1+x bytes. } PES_header_data_length = sz - PES_header_data_length; - + sz += nb_stuffings; - + // packet bytes } else if (sid == SrsTsPESStreamIdProgramStreamMap - || sid == SrsTsPESStreamIdPrivateStream2 - || sid == SrsTsPESStreamIdEcmStream - || sid == SrsTsPESStreamIdEmmStream - || sid == SrsTsPESStreamIdProgramStreamDirectory - || sid == SrsTsPESStreamIdDsmccStream - || sid == SrsTsPESStreamIdH2221TypeE - ) { + || sid == SrsTsPESStreamIdPrivateStream2 + || sid == SrsTsPESStreamIdEcmStream + || sid == SrsTsPESStreamIdEmmStream + || sid == SrsTsPESStreamIdProgramStreamDirectory + || sid == SrsTsPESStreamIdDsmccStream + || sid == SrsTsPESStreamIdH2221TypeE + ) { // packet bytes } else { // nb_drop } - + return sz; } int SrsTsPayloadPES::encode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + // 6B fixed header. if (!stream->require(6)) { ret = ERROR_STREAM_CASTER_TS_PSE; srs_error("ts: mux PSE failed. ret=%d", ret); return ret; } - + // 3B stream->write_3bytes(packet_start_code_prefix); // 1B @@ -1845,7 +1842,7 @@ int SrsTsPayloadPES::encode(SrsBuffer* stream) pplv = (pplv > 0xFFFF)? 0 : pplv; } stream->write_2bytes(pplv); - + // check the packet start prefix. packet_start_code_prefix &= 0xFFFFFF; if (packet_start_code_prefix != 0x01) { @@ -1853,7 +1850,7 @@ int SrsTsPayloadPES::encode(SrsBuffer* stream) srs_error("ts: mux PSE start code failed, expect=0x01, actual=%#x. ret=%d", packet_start_code_prefix, ret); return ret; } - + // 3B flags. if (!stream->require(3)) { ret = ERROR_STREAM_CASTER_TS_PSE; @@ -1879,7 +1876,7 @@ int SrsTsPayloadPES::encode(SrsBuffer* stream) stream->write_1bytes(pefv); // 1B stream->write_1bytes(PES_header_data_length); - + // check required together. int nb_required = 0; nb_required += (PTS_DTS_flags == 0x2)? 5:0; @@ -1895,14 +1892,14 @@ int SrsTsPayloadPES::encode(SrsBuffer* stream) srs_error("ts: mux PSE payload failed. ret=%d", ret); return ret; } - + // 5B if (PTS_DTS_flags == 0x2) { if ((ret = encode_33bits_dts_pts(stream, 0x02, pts)) != ERROR_SUCCESS) { return ret; } } - + // 10B if (PTS_DTS_flags == 0x3) { if ((ret = encode_33bits_dts_pts(stream, 0x03, pts)) != ERROR_SUCCESS) { @@ -1911,43 +1908,43 @@ int SrsTsPayloadPES::encode(SrsBuffer* stream) if ((ret = encode_33bits_dts_pts(stream, 0x01, dts)) != ERROR_SUCCESS) { return ret; } - + // check sync, the diff of dts and pts should never greater than 1s. if (dts - pts > 90000 || pts - dts > 90000) { srs_warn("ts: sync dts=%"PRId64", pts=%"PRId64, dts, pts); } } - + // 6B if (ESCR_flag) { stream->skip(6); srs_warn("ts: demux PES, ignore the escr."); } - + // 3B if (ES_rate_flag) { stream->skip(3); srs_warn("ts: demux PES, ignore the ES_rate."); } - + // 1B if (DSM_trick_mode_flag) { stream->skip(1); srs_warn("ts: demux PES, ignore the DSM_trick_mode."); } - + // 1B if (additional_copy_info_flag) { stream->skip(1); srs_warn("ts: demux PES, ignore the additional_copy_info."); } - + // 2B if (PES_CRC_flag) { stream->skip(2); srs_warn("ts: demux PES, ignore the PES_CRC."); } - + // 1B if (PES_extension_flag) { int8_t efv = PES_extension_flag_2 & 0x01; @@ -1957,7 +1954,7 @@ int SrsTsPayloadPES::encode(SrsBuffer* stream) efv |= (P_STD_buffer_flag << 4) & 0x10; efv |= (const1_value0 << 1) & 0xE0; stream->write_1bytes(efv); - + nb_required = 0; nb_required += PES_private_data_flag? 16:0; nb_required += pack_header_field_flag? 1+pack_field_length:0; // 1+x bytes. @@ -1972,26 +1969,26 @@ int SrsTsPayloadPES::encode(SrsBuffer* stream) stream->skip(nb_required); srs_warn("ts: demux PES, ignore the PES_extension."); } - + // stuffing_byte if (nb_stuffings) { stream->skip(nb_stuffings); srs_warn("ts: demux PES, ignore the stuffings."); } - + return ret; } int SrsTsPayloadPES::decode_33bits_dts_pts(SrsBuffer* stream, int64_t* pv) { int ret = ERROR_SUCCESS; - + if (!stream->require(5)) { ret = ERROR_STREAM_CASTER_TS_PSE; srs_error("ts: demux PSE dts/pts failed. ret=%d", ret); return ret; } - + // decode the 33bits schema. // ===========1B // 4bits const maybe '0001', '0010' or '0011'. @@ -2011,7 +2008,7 @@ int SrsTsPayloadPES::decode_33bits_dts_pts(SrsBuffer* stream, int64_t* pv) return ret; } dts_pts_30_32 = (dts_pts_30_32 >> 1) & 0x07; - + // ===========2B // 15bits DTS/PTS [29..15] // 1bit const '1' @@ -2022,7 +2019,7 @@ int SrsTsPayloadPES::decode_33bits_dts_pts(SrsBuffer* stream, int64_t* pv) return ret; } dts_pts_15_29 = (dts_pts_15_29 >> 1) & 0x7fff; - + // ===========2B // 15bits DTS/PTS [14..0] // 1bit const '1' @@ -2033,29 +2030,29 @@ int SrsTsPayloadPES::decode_33bits_dts_pts(SrsBuffer* stream, int64_t* pv) return ret; } dts_pts_0_14 = (dts_pts_0_14 >> 1) & 0x7fff; - + int64_t v = 0x00; v |= (dts_pts_30_32 << 30) & 0x1c0000000LL; v |= (dts_pts_15_29 << 15) & 0x3fff8000LL; v |= dts_pts_0_14 & 0x7fff; *pv = v; - + return ret; } int SrsTsPayloadPES::encode_33bits_dts_pts(SrsBuffer* stream, uint8_t fb, int64_t v) { int ret = ERROR_SUCCESS; - + if (!stream->require(5)) { ret = ERROR_STREAM_CASTER_TS_PSE; srs_error("ts: mux PSE dts/pts failed. ret=%d", ret); return ret; } - + char* p = stream->data() + stream->pos(); stream->skip(5); - + int32_t val = 0; val = fb << 4 | (((v >> 30) & 0x07) << 1) | 1; @@ -2068,7 +2065,7 @@ int SrsTsPayloadPES::encode_33bits_dts_pts(SrsBuffer* stream, uint8_t fb, int64_ val = (((v) & 0x7fff) << 1) | 1; *p++ = (val >> 8); *p++ = val; - + return ret; } @@ -2087,15 +2084,15 @@ SrsTsPayloadPSI::~SrsTsPayloadPSI() int SrsTsPayloadPSI::decode(SrsBuffer* stream, SrsTsMessage** /*ppmsg*/) { int ret = ERROR_SUCCESS; - + /** - * 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). - */ + * 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). + */ if (packet->payload_unit_start_indicator) { if (!stream->require(1)) { ret = ERROR_STREAM_CASTER_TS_PSI; @@ -2104,11 +2101,11 @@ int SrsTsPayloadPSI::decode(SrsBuffer* stream, SrsTsMessage** /*ppmsg*/) } pointer_field = stream->read_1bytes(); } - + // to calc the crc32 char* ppat = stream->data() + stream->pos(); int pat_pos = stream->pos(); - + // atleast 3B for all psi. if (!stream->require(3)) { ret = ERROR_STREAM_CASTER_TS_PSI; @@ -2125,19 +2122,19 @@ int SrsTsPayloadPSI::decode(SrsBuffer* stream, SrsTsMessage** /*ppmsg*/) const0_value = (slv >> 14) & 0x01; const1_value = (slv >> 12) & 0x03; section_length = slv & 0x0FFF; - + // no section, ignore. if (section_length == 0) { srs_warn("ts: demux PAT ignore empty section"); return ret; } - + if (!stream->require(section_length)) { ret = ERROR_STREAM_CASTER_TS_PSI; srs_error("ts: demux PAT section failed. ret=%d", ret); return ret; } - + // call the virtual method of actual PSI. if ((ret = psi_decode(stream)) != ERROR_SUCCESS) { return ret; @@ -2150,7 +2147,7 @@ int SrsTsPayloadPSI::decode(SrsBuffer* stream, SrsTsMessage** /*ppmsg*/) return ret; } CRC_32 = stream->read_4bytes(); - + // verify crc32. int32_t crc32 = srs_crc32_mpegts(ppat, stream->pos() - pat_pos - 4); if (crc32 != CRC_32) { @@ -2158,12 +2155,12 @@ int SrsTsPayloadPSI::decode(SrsBuffer* stream, SrsTsMessage** /*ppmsg*/) srs_error("ts: verify PSI crc32 failed. ret=%d", ret); return ret; } - + // consume left stuffings if (!stream->empty()) { int nb_stuffings = stream->size() - stream->pos(); char* stuffing = stream->data() + stream->pos(); - + // all stuffing must be 0xff. // TODO: FIXME: maybe need to remove the following. for (int i = 0; i < nb_stuffings; i++) { @@ -2172,31 +2169,31 @@ int SrsTsPayloadPSI::decode(SrsBuffer* stream, SrsTsMessage** /*ppmsg*/) break; } } - + stream->skip(nb_stuffings); } - + return ret; } int SrsTsPayloadPSI::size() { int sz = 0; - + // section size is the sl plus the crc32 section_length = psi_size() + 4; - - sz += packet->payload_unit_start_indicator? 1:0; - sz += 3; - sz += section_length; - + + sz += packet->payload_unit_start_indicator? 1:0; + sz += 3; + sz += section_length; + return sz; } int SrsTsPayloadPSI::encode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + if (packet->payload_unit_start_indicator) { if (!stream->require(1)) { ret = ERROR_STREAM_CASTER_TS_PSI; @@ -2205,11 +2202,11 @@ int SrsTsPayloadPSI::encode(SrsBuffer* stream) } stream->write_1bytes(pointer_field); } - + // to calc the crc32 char* ppat = stream->data() + stream->pos(); int pat_pos = stream->pos(); - + // atleast 3B for all psi. if (!stream->require(3)) { ret = ERROR_STREAM_CASTER_TS_PSI; @@ -2225,19 +2222,19 @@ int SrsTsPayloadPSI::encode(SrsBuffer* stream) slv |= (const0_value << 14) & 0x4000; slv |= (const1_value << 12) & 0x3000; stream->write_2bytes(slv); - + // no section, ignore. if (section_length == 0) { srs_warn("ts: mux PAT ignore empty section"); return ret; } - + if (!stream->require(section_length)) { ret = ERROR_STREAM_CASTER_TS_PSI; srs_error("ts: mux PAT section failed. ret=%d", ret); return ret; } - + // call the virtual method of actual PSI. if ((ret = psi_encode(stream)) != ERROR_SUCCESS) { return ret; @@ -2251,7 +2248,7 @@ int SrsTsPayloadPSI::encode(SrsBuffer* stream) } CRC_32 = srs_crc32_mpegts(ppat, stream->pos() - pat_pos); stream->write_4bytes(CRC_32); - + return ret; } @@ -2269,19 +2266,19 @@ SrsTsPayloadPATProgram::~SrsTsPayloadPATProgram() int SrsTsPayloadPATProgram::decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + // atleast 4B for PAT program specified if (!stream->require(4)) { ret = ERROR_STREAM_CASTER_TS_PAT; srs_error("ts: demux PAT failed. ret=%d", ret); return ret; } - + int tmpv = stream->read_4bytes(); number = (int16_t)((tmpv >> 16) & 0xFFFF); const1_value = (int16_t)((tmpv >> 13) & 0x07); pid = (int16_t)(tmpv & 0x1FFF); - + return ret; } @@ -2293,19 +2290,19 @@ int SrsTsPayloadPATProgram::size() int SrsTsPayloadPATProgram::encode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + // atleast 4B for PAT program specified if (!stream->require(4)) { ret = ERROR_STREAM_CASTER_TS_PAT; srs_error("ts: mux PAT failed. ret=%d", ret); return ret; } - + int tmpv = pid & 0x1FFF; tmpv |= (number << 16) & 0xFFFF0000; tmpv |= (const1_value << 13) & 0xE000; stream->write_4bytes(tmpv); - + return ret; } @@ -2327,16 +2324,16 @@ SrsTsPayloadPAT::~SrsTsPayloadPAT() int SrsTsPayloadPAT::psi_decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + // atleast 5B for PAT specified if (!stream->require(5)) { ret = ERROR_STREAM_CASTER_TS_PAT; srs_error("ts: demux PAT failed. ret=%d", ret); return ret; } - + int pos = stream->pos(); - + // 2B transport_stream_id = stream->read_2bytes(); @@ -2346,33 +2343,33 @@ int SrsTsPayloadPAT::psi_decode(SrsBuffer* stream) const3_value = (cniv >> 6) & 0x03; version_number = (cniv >> 1) & 0x1F; current_next_indicator = cniv & 0x01; - + // TODO: FIXME: check the indicator. // 1B section_number = stream->read_1bytes(); // 1B last_section_number = stream->read_1bytes(); - + // multiple 4B program data. int program_bytes = section_length - 4 - (stream->pos() - pos); for (int i = 0; i < program_bytes; i += 4) { SrsTsPayloadPATProgram* program = new SrsTsPayloadPATProgram(); - + if ((ret = program->decode(stream)) != ERROR_SUCCESS) { return ret; } - + // update the apply pid table. packet->context->set(program->pid, SrsTsPidApplyPMT); - + programs.push_back(program); } - + // update the apply pid table. packet->context->set(packet->pid, SrsTsPidApplyPAT); packet->context->on_pmt_parsed(); - + return ret; } @@ -2389,14 +2386,14 @@ int SrsTsPayloadPAT::psi_size() int SrsTsPayloadPAT::psi_encode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + // atleast 5B for PAT specified if (!stream->require(5)) { ret = ERROR_STREAM_CASTER_TS_PAT; srs_error("ts: mux PAT failed. ret=%d", ret); return ret; } - + // 2B stream->write_2bytes(transport_stream_id); @@ -2410,21 +2407,21 @@ int SrsTsPayloadPAT::psi_encode(SrsBuffer* stream) stream->write_1bytes(section_number); // 1B stream->write_1bytes(last_section_number); - + // multiple 4B program data. for (int i = 0; i < (int)programs.size(); i ++) { SrsTsPayloadPATProgram* program = programs.at(i); if ((ret = program->encode(stream)) != ERROR_SUCCESS) { return ret; } - + // update the apply pid table. packet->context->set(program->pid, SrsTsPidApplyPMT); } - + // update the apply pid table. packet->context->set(packet->pid, SrsTsPidApplyPAT); - + return ret; } @@ -2432,7 +2429,7 @@ SrsTsPayloadPMTESInfo::SrsTsPayloadPMTESInfo(SrsTsStream st, int16_t epid) { stream_type = st; elementary_PID = epid; - + const1_value0 = 7; const1_value1 = 0x0f; ES_info_length = 0; @@ -2447,16 +2444,16 @@ SrsTsPayloadPMTESInfo::~SrsTsPayloadPMTESInfo() int SrsTsPayloadPMTESInfo::decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + // 5B if (!stream->require(5)) { ret = ERROR_STREAM_CASTER_TS_PMT; srs_error("ts: demux PMT es info failed. ret=%d", ret); return ret; } - + stream_type = (SrsTsStream)stream->read_1bytes(); - + int16_t epv = stream->read_2bytes(); const1_value0 = (epv >> 13) & 0x07; elementary_PID = epv & 0x1FFF; @@ -2464,7 +2461,7 @@ int SrsTsPayloadPMTESInfo::decode(SrsBuffer* stream) int16_t eilv = stream->read_2bytes(); const1_value1 = (epv >> 12) & 0x0f; ES_info_length = eilv & 0x0FFF; - + if (ES_info_length > 0) { if (!stream->require(ES_info_length)) { ret = ERROR_STREAM_CASTER_TS_PMT; @@ -2475,7 +2472,7 @@ int SrsTsPayloadPMTESInfo::decode(SrsBuffer* stream) ES_info = new char[ES_info_length]; stream->read_bytes(ES_info, ES_info_length); } - + return ret; } @@ -2487,16 +2484,16 @@ int SrsTsPayloadPMTESInfo::size() int SrsTsPayloadPMTESInfo::encode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + // 5B if (!stream->require(5)) { ret = ERROR_STREAM_CASTER_TS_PMT; srs_error("ts: mux PMT es info failed. ret=%d", ret); return ret; } - + stream->write_1bytes(stream_type); - + int16_t epv = elementary_PID & 0x1FFF; epv |= (const1_value0 << 13) & 0xE000; stream->write_2bytes(epv); @@ -2504,7 +2501,7 @@ int SrsTsPayloadPMTESInfo::encode(SrsBuffer* stream) int16_t eilv = ES_info_length & 0x0FFF; eilv |= (const1_value1 << 12) & 0xF000; stream->write_2bytes(eilv); - + if (ES_info_length > 0) { if (!stream->require(ES_info_length)) { ret = ERROR_STREAM_CASTER_TS_PMT; @@ -2513,7 +2510,7 @@ int SrsTsPayloadPMTESInfo::encode(SrsBuffer* stream) } stream->write_bytes(ES_info, ES_info_length); } - + return ret; } @@ -2529,7 +2526,7 @@ SrsTsPayloadPMT::SrsTsPayloadPMT(SrsTsPacket* p) : SrsTsPayloadPSI(p) SrsTsPayloadPMT::~SrsTsPayloadPMT() { srs_freepa(program_info_desc); - + std::vector::iterator it; for (it = infos.begin(); it != infos.end(); ++it) { SrsTsPayloadPMTESInfo* info = *it; @@ -2541,14 +2538,14 @@ SrsTsPayloadPMT::~SrsTsPayloadPMT() int SrsTsPayloadPMT::psi_decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + // atleast 9B for PMT specified if (!stream->require(9)) { ret = ERROR_STREAM_CASTER_TS_PMT; srs_error("ts: demux PMT failed. ret=%d", ret); return ret; } - + // 2B program_number = stream->read_2bytes(); @@ -2564,7 +2561,7 @@ int SrsTsPayloadPMT::psi_decode(SrsBuffer* stream) // 1B last_section_number = stream->read_1bytes(); - + // 2B int16_t ppv = stream->read_2bytes(); const1_value1 = (ppv >> 13) & 0x07; @@ -2574,29 +2571,29 @@ int SrsTsPayloadPMT::psi_decode(SrsBuffer* stream) int16_t pilv = stream->read_2bytes(); const1_value2 = (pilv >> 12) & 0x0F; program_info_length = pilv & 0xFFF; - + if (program_info_length > 0) { if (!stream->require(program_info_length)) { ret = ERROR_STREAM_CASTER_TS_PMT; srs_error("ts: demux PMT program info failed. ret=%d", ret); return ret; } - + srs_freepa(program_info_desc); program_info_desc = new char[program_info_length]; stream->read_bytes(program_info_desc, program_info_length); } - + // [section_length] - 4(CRC) - 9B - [program_info_length] int ES_EOF_pos = stream->pos() + section_length - 4 - 9 - program_info_length; while (stream->pos() < ES_EOF_pos) { SrsTsPayloadPMTESInfo* info = new SrsTsPayloadPMTESInfo(); infos.push_back(info); - + if ((ret = info->decode(stream)) != ERROR_SUCCESS) { return ret; } - + // update the apply pid table switch (info->stream_type) { case SrsTsStreamVideoH264: @@ -2614,10 +2611,10 @@ int SrsTsPayloadPMT::psi_decode(SrsBuffer* stream) break; } } - + // update the apply pid table. packet->context->set(packet->pid, SrsTsPidApplyPMT); - + return ret; } @@ -2635,14 +2632,14 @@ int SrsTsPayloadPMT::psi_size() int SrsTsPayloadPMT::psi_encode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + // atleast 9B for PMT specified if (!stream->require(9)) { ret = ERROR_STREAM_CASTER_TS_PMT; srs_error("ts: mux PMT failed. ret=%d", ret); return ret; } - + // 2B stream->write_2bytes(program_number); @@ -2657,7 +2654,7 @@ int SrsTsPayloadPMT::psi_encode(SrsBuffer* stream) // 1B stream->write_1bytes(last_section_number); - + // 2B int16_t ppv = PCR_PID & 0x1FFF; ppv |= (const1_value1 << 13) & 0xE000; @@ -2667,23 +2664,23 @@ int SrsTsPayloadPMT::psi_encode(SrsBuffer* stream) int16_t pilv = program_info_length & 0xFFF; pilv |= (const1_value2 << 12) & 0xF000; stream->write_2bytes(pilv); - + if (program_info_length > 0) { if (!stream->require(program_info_length)) { ret = ERROR_STREAM_CASTER_TS_PMT; srs_error("ts: mux PMT program info failed. ret=%d", ret); return ret; } - + stream->write_bytes(program_info_desc, program_info_length); } - + for (int i = 0; i < (int)infos.size(); i ++) { SrsTsPayloadPMTESInfo* info = infos.at(i); if ((ret = info->encode(stream)) != ERROR_SUCCESS) { return ret; } - + // update the apply pid table switch (info->stream_type) { case SrsTsStreamVideoH264: @@ -2701,10 +2698,10 @@ int SrsTsPayloadPMT::psi_encode(SrsBuffer* stream) break; } } - + // update the apply pid table. packet->context->set(packet->pid, SrsTsPidApplyPMT); - + return ret; } @@ -2712,7 +2709,7 @@ SrsTsContextWriter::SrsTsContextWriter(SrsFileWriter* w, SrsTsContext* c, SrsAud { writer = w; context = c; - + acodec = ac; vcodec = vc; } @@ -2729,7 +2726,7 @@ int SrsTsContextWriter::open(string p) path = p; close(); - + // reset the context for a new ts start. context->reset(); @@ -2743,9 +2740,9 @@ int SrsTsContextWriter::open(string p) int SrsTsContextWriter::write_audio(SrsTsMessage* audio) { int ret = ERROR_SUCCESS; - - srs_info("hls: write audio pts=%"PRId64", dts=%"PRId64", size=%d", - audio->pts, audio->dts, audio->PES_packet_length); + + srs_info("hls: write audio pts=%"PRId64", dts=%"PRId64", size=%d", + audio->pts, audio->dts, audio->PES_packet_length); if ((ret = context->encode(writer, audio, vcodec, acodec)) != ERROR_SUCCESS) { srs_error("hls encode audio failed. ret=%d", ret); @@ -2759,9 +2756,9 @@ int SrsTsContextWriter::write_audio(SrsTsMessage* audio) int SrsTsContextWriter::write_video(SrsTsMessage* video) { int ret = ERROR_SUCCESS; - - srs_info("hls: write video pts=%"PRId64", dts=%"PRId64", size=%d", - video->pts, video->dts, video->PES_packet_length); + + srs_info("hls: write video pts=%"PRId64", dts=%"PRId64", size=%d", + video->pts, video->dts, video->PES_packet_length); if ((ret = context->encode(writer, video, vcodec, acodec)) != ERROR_SUCCESS) { srs_error("hls encode video failed. ret=%d", ret); @@ -2793,18 +2790,18 @@ SrsTsMessageCache::~SrsTsMessageCache() srs_freep(audio); srs_freep(video); } - + int SrsTsMessageCache::cache_audio(SrsAudioFrame* frame, int64_t dts) { int ret = ERROR_SUCCESS; - + // create the ts audio message. if (!audio) { audio = new SrsTsMessage(); audio->write_pcr = false; audio->dts = audio->pts = audio->start_pts = dts; } - + // TODO: FIXME: refine code. //audio->dts = dts; //audio->pts = audio->dts; @@ -2827,7 +2824,7 @@ int SrsTsMessageCache::cache_audio(SrsAudioFrame* frame, int64_t dts) return ret; } - + int SrsTsMessageCache::cache_video(SrsVideoFrame* frame, int64_t dts) { int ret = ERROR_SUCCESS; @@ -2838,7 +2835,7 @@ int SrsTsMessageCache::cache_video(SrsVideoFrame* frame, int64_t dts) video->write_pcr = (frame->frame_type == SrsVideoAvcFrameTypeKeyFrame); video->start_pts = dts; } - + video->dts = dts; video->pts = video->dts + frame->cts * 90; video->sid = SrsTsPESStreamIdVideoCommon; @@ -2847,14 +2844,14 @@ int SrsTsMessageCache::cache_video(SrsVideoFrame* frame, int64_t dts) if ((ret = do_cache_avc(frame)) != ERROR_SUCCESS) { return ret; } - + return ret; } int SrsTsMessageCache::do_cache_mp3(SrsAudioFrame* frame) { int ret = ERROR_SUCCESS; - + // for mp3, directly write to cache. // TODO: FIXME: implements the ts jitter. for (int i = 0; i < frame->nb_samples; i++) { @@ -2891,28 +2888,28 @@ int SrsTsMessageCache::do_cache_aac(SrsAudioFrame* frame) // fixed 7bytes header uint8_t adts_header[7] = {0xff, 0xf9, 0x00, 0x00, 0x00, 0x0f, 0xfc}; /* - // adts_fixed_header - // 2B, 16bits - int16_t syncword; //12bits, '1111 1111 1111' - int8_t ID; //1bit, '1' - int8_t layer; //2bits, '00' - int8_t protection_absent; //1bit, can be '1' - // 12bits - int8_t profile; //2bit, 7.1 Profiles, page 40 - TSAacSampleFrequency sampling_frequency_index; //4bits, Table 35, page 46 - int8_t private_bit; //1bit, can be '0' - int8_t channel_configuration; //3bits, Table 8 - int8_t original_or_copy; //1bit, can be '0' - int8_t home; //1bit, can be '0' - - // adts_variable_header - // 28bits - int8_t copyright_identification_bit; //1bit, can be '0' - int8_t copyright_identification_start; //1bit, can be '0' - int16_t frame_length; //13bits - int16_t adts_buffer_fullness; //11bits, 7FF signals that the bitstream is a variable rate bitstream. - int8_t number_of_raw_data_blocks_in_frame; //2bits, 0 indicating 1 raw_data_block() - */ + // adts_fixed_header + // 2B, 16bits + int16_t syncword; //12bits, '1111 1111 1111' + int8_t ID; //1bit, '1' + int8_t layer; //2bits, '00' + int8_t protection_absent; //1bit, can be '1' + // 12bits + int8_t profile; //2bit, 7.1 Profiles, page 40 + TSAacSampleFrequency sampling_frequency_index; //4bits, Table 35, page 46 + int8_t private_bit; //1bit, can be '0' + int8_t channel_configuration; //3bits, Table 8 + int8_t original_or_copy; //1bit, can be '0' + int8_t home; //1bit, can be '0' + + // adts_variable_header + // 28bits + int8_t copyright_identification_bit; //1bit, can be '0' + int8_t copyright_identification_start; //1bit, can be '0' + int16_t frame_length; //13bits + int16_t adts_buffer_fullness; //11bits, 7FF signals that the bitstream is a variable rate bitstream. + int8_t number_of_raw_data_blocks_in_frame; //2bits, 0 indicating 1 raw_data_block() + */ // profile, 2bits SrsAacProfile aac_profile = srs_aac_rtmp2ts(codec->aac_object); adts_header[2] = (aac_profile << 6) & 0xc0; @@ -2927,7 +2924,7 @@ int SrsTsMessageCache::do_cache_aac(SrsAudioFrame* frame) adts_header[5] = ((frame_length << 5) & 0xe0); // adts_buffer_fullness; //11bits adts_header[5] |= 0x1f; - + // copy to audio buffer audio->payload->append((const char*)adts_header, sizeof(adts_header)); audio->payload->append(sample->bytes, sample->size); @@ -3109,11 +3106,11 @@ int SrsTsTransmuxer::initialize(SrsFileWriter* fw) } writer = fw; - + srs_freep(tscw); // TODO: FIXME: Support config the codec. tscw = new SrsTsContextWriter(fw, context, SrsAudioCodecIdAAC, SrsVideoCodecIdAVC); - + if ((ret = tscw->open("")) != ERROR_SUCCESS) { return ret; } @@ -3139,7 +3136,7 @@ int SrsTsTransmuxer::write_audio(int64_t timestamp, char* data, int size) if (format->acodec->id == SrsAudioCodecIdAAC && format->audio->aac_packet_type == SrsAudioAacFrameTraitSequenceHeader) { return ret; } - + // the dts calc from rtmp/flv header. // @remark for http ts stream, the timestamp is always monotonically increase, // for the packet is filtered by consumer. @@ -3178,7 +3175,7 @@ int SrsTsTransmuxer::write_video(int64_t timestamp, char* data, int size) // ignore sequence header if (format->video->frame_type == SrsVideoAvcFrameTypeKeyFrame - && format->video->avc_packet_type == SrsVideoAvcFrameTraitSequenceHeader) { + && format->video->avc_packet_type == SrsVideoAvcFrameTraitSequenceHeader) { return ret; } @@ -3188,21 +3185,21 @@ int SrsTsTransmuxer::write_video(int64_t timestamp, char* data, int size) if ((ret = tsmc->cache_video(format->video, dts)) != ERROR_SUCCESS) { return ret; } - + return flush_video(); } int SrsTsTransmuxer::flush_audio() { int ret = ERROR_SUCCESS; - + if ((ret = tscw->write_audio(tsmc->audio)) != ERROR_SUCCESS) { return ret; } // write success, clear and free the ts message. srs_freep(tsmc->audio); - + return ret; } @@ -3216,7 +3213,7 @@ int SrsTsTransmuxer::flush_video() // write success, clear and free the ts message. srs_freep(tsmc->video); - + return ret; } diff --git a/trunk/src/kernel/srs_kernel_ts.hpp b/trunk/src/kernel/srs_kernel_ts.hpp index ed8db0f8e..d4927e3c8 100644 --- a/trunk/src/kernel/srs_kernel_ts.hpp +++ b/trunk/src/kernel/srs_kernel_ts.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_KERNEL_TS_HPP #define SRS_KERNEL_TS_HPP -/* -#include -*/ #include #if !defined(SRS_EXPORT_LIBRTMP) @@ -57,10 +54,10 @@ class SrsTsContext; #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). @@ -80,9 +77,9 @@ enum SrsTsPid }; /** -* 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 @@ -96,9 +93,9 @@ enum SrsTsScrambled }; /** -* 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 @@ -112,9 +109,9 @@ enum SrsTsAdaptationFieldType }; /** -* 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. @@ -127,8 +124,8 @@ enum SrsTsPidApply }; /** -* Table 2-29 - Stream type assignments -*/ + * Table 2-29 - Stream type assignments + */ enum SrsTsStream { // ITU-T | ISO/IEC Reserved @@ -168,8 +165,8 @@ enum SrsTsStream std::string srs_ts_stream2string(SrsTsStream stream); /** -* the ts channel. -*/ + * the ts channel. + */ struct SrsTsChannel { int pid; @@ -179,15 +176,15 @@ struct SrsTsChannel SrsTsContext* context; // for encoder. uint8_t continuity_counter; - + 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 @@ -198,23 +195,23 @@ enum SrsTsPESStreamId SrsTsPESStreamIdPaddingStream = 0xbe, // 0b10111110 // private_stream_2 SrsTsPESStreamIdPrivateStream2 = 0xbf, // 0b10111111 - + // 110x xxxx // ISO/IEC 13818-3 or ISO/IEC 11172-3 or ISO/IEC 13818-7 or ISO/IEC // 14496-3 audio stream number x xxxx // ((sid >> 5) & 0x07) == SrsTsPESStreamIdAudio // @remark, use SrsTsPESStreamIdAudioCommon as actually audio, SrsTsPESStreamIdAudio to check whether audio. SrsTsPESStreamIdAudioChecker = 0x06, // 0b110 - SrsTsPESStreamIdAudioCommon = 0xc0, - + SrsTsPESStreamIdAudioCommon = 0xc0, + // 1110 xxxx // ITU-T Rec. H.262 | ISO/IEC 13818-2 or ISO/IEC 11172-2 or ISO/IEC // 14496-2 video stream number xxxx // ((stream_id >> 4) & 0x0f) == SrsTsPESStreamIdVideo // @remark, use SrsTsPESStreamIdVideoCommon as actually video, SrsTsPESStreamIdVideo to check whether video. SrsTsPESStreamIdVideoChecker = 0x0e, // 0b1110 - SrsTsPESStreamIdVideoCommon = 0xe0, - + SrsTsPESStreamIdVideoCommon = 0xe0, + // ECM_stream SrsTsPESStreamIdEcmStream = 0xf0, // 0b11110000 // EMM_stream @@ -246,13 +243,13 @@ enum SrsTsPESStreamId }; /** -* the media audio/video message parsed from PES packet. -*/ + * the media audio/video message parsed from PES packet. + */ class SrsTsMessage { public: // decoder only, - // the ts messgae does not use them, + // the ts messgae does not use them, // for user to get the channel and packet. SrsTsChannel* channel; SrsTsPacket* packet; @@ -281,38 +278,38 @@ public: public: SrsTsMessage(SrsTsChannel* c = NULL, SrsTsPacket* p = NULL); virtual ~SrsTsMessage(); -// decoder + // decoder public: /** - * dumps all bytes in stream to ts message. - */ + * dumps all bytes in stream to ts message. + */ virtual int 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. - */ + * 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: /** @@ -324,8 +321,8 @@ public: }; /** -* the ts message handler. -*/ + * the ts message handler. + */ class ISrsTsHandler { public: @@ -333,24 +330,24 @@ public: 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 int 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 { -// codec + // codec private: std::map pids; bool pure_audio; int8_t sync_byte; -// encoder + // encoder private: // when any codec changed, write the PAT/PMT. SrsVideoCodecId vcodec; @@ -372,35 +369,35 @@ public: * reset the context for a new ts segment start. */ virtual void reset(); -// codec + // 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 + // 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 int decode(SrsBuffer* stream, ISrsTsHandler* handler); -// encode methods + // 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 int encode(SrsFileWriter* writer, SrsTsMessage* msg, SrsVideoCodecId vc, SrsAudioCodecId ac); -// drm methods + // drm methods public: /** * set sync byte of ts segment. @@ -413,97 +410,97 @@ private: }; /** -* 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; @@ -520,304 +517,297 @@ public: virtual int encode(SrsBuffer* stream); virtual void padding(int nb_stuffings); 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 - ); - 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 - ); - static SrsTsPacket* create_pes_continue(SrsTsContext* context, - int16_t pid, SrsTsPESStreamId sid, uint8_t continuity_counter - ); + 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); + 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); + static SrsTsPacket* create_pes_continue(SrsTsContext* context, + 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. - */ + * 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. - */ + * 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. - */ + * 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 /** - * The transport_private_data_length is an 8-bit field specifying the number of - * private_data bytes immediately following the transport private_data_length field. The number of private_data bytes shall - * not be such that private data extends beyond the adaptation field. - */ + * The transport_private_data_length is an 8-bit field specifying the number of + * private_data bytes immediately following the transport private_data_length field. The number of private_data bytes shall + * not be such that private data extends beyond the adaptation field. + */ uint8_t transport_private_data_length; //8bits char* 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. - */ + * 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 @@ -826,16 +816,16 @@ public: 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; @@ -850,9 +840,9 @@ public: }; /** -* 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 @@ -881,8 +871,8 @@ enum SrsTsPsiId }; /** -* 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: @@ -898,130 +888,130 @@ public: }; /** -* 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] @@ -1033,13 +1023,13 @@ public: // 15bits PTS [14..0] // 1bit const '1' 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] @@ -1051,15 +1041,15 @@ public: // 15bits DTS [14..0] // 1bit const '1' 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' @@ -1071,172 +1061,172 @@ public: // 1bit const '1' int64_t ESCR_base; //33bits 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). + */ char* PES_private_data; //128bits - + // (1+x)B /** - * This is an 8-bit field which indicates the length, in bytes, of the pack_header_field(). - */ + * This is an 8-bit field which indicates the length, in bytes, of the pack_header_field(). + */ uint8_t pack_field_length; //8bits char* pack_field; //[pack_field_length] bytes - + // 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 // 1bit const '1' /** - * This is a 7-bit field which specifies the length, in bytes, of the data following this field in - * the PES extension field up to and including any reserved bytes. - */ + * This is a 7-bit field which specifies the length, in bytes, of the data following this field in + * the PES extension field up to and including any reserved bytes. + */ uint8_t PES_extension_field_length; //7bits char* 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); @@ -1252,58 +1242,58 @@ private: }; /** -* 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); @@ -1320,30 +1310,30 @@ protected: }; /** -* 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); @@ -1356,55 +1346,55 @@ public: }; /** -* 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. @@ -1420,38 +1410,38 @@ protected: }; /** -* 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 /** - * 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 of the associated program element immediately following the ES_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 of the associated program element immediately following the ES_info_length field. + */ int16_t ES_info_length; //12bits char* ES_info; //[ES_info_length] bytes. public: @@ -1465,81 +1455,81 @@ public: }; /** -* 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. + */ uint16_t program_info_length; //12bits char* program_info_desc; //[program_info_length]bytes @@ -1579,16 +1569,16 @@ public: */ virtual int open(std::string p); /** - * write an audio frame to ts, - */ + * write an audio frame to ts, + */ virtual int write_audio(SrsTsMessage* audio); /** - * write a video frame to ts, - */ + * write a video frame to ts, + */ virtual int write_video(SrsTsMessage* video); /** - * close the writer. - */ + * close the writer. + */ virtual void close(); public: /** @@ -1612,12 +1602,12 @@ public: virtual ~SrsTsMessageCache(); public: /** - * write audio to cache - */ + * write audio to cache + */ virtual int cache_audio(SrsAudioFrame* frame, int64_t dts); /** - * write video to muxer. - */ + * write video to muxer. + */ virtual int cache_video(SrsVideoFrame* frame, int64_t dts); private: virtual int do_cache_mp3(SrsAudioFrame* frame); @@ -1648,9 +1638,9 @@ public: virtual int initialize(SrsFileWriter* fw); public: /** - * write audio/video packet. - * @remark assert data is not NULL. - */ + * write audio/video packet. + * @remark assert data is not NULL. + */ virtual int write_audio(int64_t timestamp, char* data, int size); virtual int write_video(int64_t timestamp, char* data, int size); private: diff --git a/trunk/src/kernel/srs_kernel_utility.cpp b/trunk/src/kernel/srs_kernel_utility.cpp index 80efdd0fc..e5fd68ab6 100644 --- a/trunk/src/kernel/srs_kernel_utility.cpp +++ b/trunk/src/kernel/srs_kernel_utility.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -123,7 +123,7 @@ int64_t srs_update_system_time_ms() srs_warn("gettimeofday failed, ignore"); return -1; } - + // @see: https://github.com/ossrs/srs/issues/35 // we must convert the tv_sec/tv_usec to int64_t. int64_t now_us = ((int64_t)now.tv_sec) * 1000 * 1000 + (int64_t)now.tv_usec; @@ -224,7 +224,7 @@ string srs_bool2switch(bool v) { bool srs_is_little_endian() { - // convert to network(big-endian) order, if not equals, + // convert to network(big-endian) order, if not equals, // the system is little-endian, so need to convert the int64 static int little_endian_check = -1; @@ -471,707 +471,702 @@ int srs_do_create_dir_recursively(string dir) mode_t mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IXOTH; if (::mkdir(dir.c_str(), mode) < 0) { #else - if (::mkdir(dir.c_str()) < 0) { + if (::mkdir(dir.c_str()) < 0) { #endif - if (errno == EEXIST) { - return ERROR_SYSTEM_DIR_EXISTS; + if (errno == EEXIST) { + return ERROR_SYSTEM_DIR_EXISTS; + } + + ret = ERROR_SYSTEM_CREATE_DIR; + srs_error("create dir %s failed. ret=%d", dir.c_str(), ret); + return ret; } + srs_info("create dir %s success.", dir.c_str()); - ret = ERROR_SYSTEM_CREATE_DIR; - srs_error("create dir %s failed. ret=%d", dir.c_str(), ret); return ret; } - srs_info("create dir %s success.", dir.c_str()); - return ret; -} - -bool srs_bytes_equals(void* pa, void* pb, int size) -{ - uint8_t* a = (uint8_t*)pa; - uint8_t* b = (uint8_t*)pb; - - if (!a && !b) { - return true; - } - - if (!a || !b) { - return false; - } - - for(int i = 0; i < size; i++){ - if(a[i] != b[i]){ - return false; - } - } - - return true; -} - -int srs_create_dir_recursively(string dir) -{ - int ret = ERROR_SUCCESS; - - ret = srs_do_create_dir_recursively(dir); - - if (ret == ERROR_SYSTEM_DIR_EXISTS) { - return ERROR_SUCCESS; - } - - return ret; -} - -bool srs_path_exists(std::string path) -{ - struct stat st; - - // stat current dir, if exists, return error. - if (stat(path.c_str(), &st) == 0) { - return true; - } - - return false; -} - -string srs_path_dirname(string path) -{ - std::string dirname = path; - size_t pos = string::npos; - - if ((pos = dirname.rfind("/")) != string::npos) { - if (pos == 0) { - return "/"; - } - dirname = dirname.substr(0, pos); - } - - return dirname; -} - -string srs_path_basename(string path) -{ - std::string dirname = path; - size_t pos = string::npos; - - if ((pos = dirname.rfind("/")) != string::npos) { - // the basename("/") is "/" - if (dirname.length() == 1) { - return dirname; - } - dirname = dirname.substr(pos + 1); - } - - return dirname; -} - -string srs_path_filename(string path) -{ - std::string filename = path; - size_t pos = string::npos; - - if ((pos = filename.rfind(".")) != string::npos) { - return filename.substr(0, pos); - } - - return filename; -} - -string srs_path_filext(string path) -{ - size_t pos = string::npos; - - if ((pos = path.rfind(".")) != string::npos) { - return path.substr(pos); - } - - return ""; -} - -bool srs_avc_startswith_annexb(SrsBuffer* stream, int* pnb_start_code) -{ - char* bytes = stream->data() + stream->pos(); - char* p = bytes; - - for (;;) { - if (!stream->require((int)(p - bytes + 3))) { - return false; - } + bool srs_bytes_equals(void* pa, void* pb, int size) + { + uint8_t* a = (uint8_t*)pa; + uint8_t* b = (uint8_t*)pb; - // not match - if (p[0] != (char)0x00 || p[1] != (char)0x00) { - return false; - } - - // match N[00] 00 00 01, where N>=0 - if (p[2] == (char)0x01) { - if (pnb_start_code) { - *pnb_start_code = (int)(p - bytes) + 3; - } + if (!a && !b) { return true; } - p++; + if (!a || !b) { + return false; + } + + for(int i = 0; i < size; i++){ + if(a[i] != b[i]){ + return false; + } + } + + return true; } - return false; -} - -bool srs_aac_startswith_adts(SrsBuffer* stream) -{ - char* bytes = stream->data() + stream->pos(); - char* p = bytes; + int srs_create_dir_recursively(string dir) + { + int ret = ERROR_SUCCESS; + + ret = srs_do_create_dir_recursively(dir); + + if (ret == ERROR_SYSTEM_DIR_EXISTS) { + return ERROR_SUCCESS; + } + + return ret; + } - if (!stream->require((int)(p - bytes) + 2)) { + bool srs_path_exists(std::string path) + { + struct stat st; + + // stat current dir, if exists, return error. + if (stat(path.c_str(), &st) == 0) { + return true; + } + return false; } - // matched 12bits 0xFFF, - // @remark, we must cast the 0xff to char to compare. - if (p[0] != (char)0xff || (char)(p[1] & 0xf0) != (char)0xf0) { + string srs_path_dirname(string path) + { + std::string dirname = path; + size_t pos = string::npos; + + if ((pos = dirname.rfind("/")) != string::npos) { + if (pos == 0) { + return "/"; + } + dirname = dirname.substr(0, pos); + } + + return dirname; + } + + string srs_path_basename(string path) + { + std::string dirname = path; + size_t pos = string::npos; + + if ((pos = dirname.rfind("/")) != string::npos) { + // the basename("/") is "/" + if (dirname.length() == 1) { + return dirname; + } + dirname = dirname.substr(pos + 1); + } + + return dirname; + } + + string srs_path_filename(string path) + { + std::string filename = path; + size_t pos = string::npos; + + if ((pos = filename.rfind(".")) != string::npos) { + return filename.substr(0, pos); + } + + return filename; + } + + string srs_path_filext(string path) + { + size_t pos = string::npos; + + if ((pos = path.rfind(".")) != string::npos) { + return path.substr(pos); + } + + return ""; + } + + bool srs_avc_startswith_annexb(SrsBuffer* stream, int* pnb_start_code) + { + char* bytes = stream->data() + stream->pos(); + char* p = bytes; + + for (;;) { + if (!stream->require((int)(p - bytes + 3))) { + return false; + } + + // not match + if (p[0] != (char)0x00 || p[1] != (char)0x00) { + return false; + } + + // match N[00] 00 00 01, where N>=0 + if (p[2] == (char)0x01) { + if (pnb_start_code) { + *pnb_start_code = (int)(p - bytes) + 3; + } + return true; + } + + p++; + } + return false; } - return true; -} - -// @see http://www.stmc.edu.hk/~vincent/ffmpeg_0.4.9-pre1/libavformat/mpegtsenc.c -unsigned int __mpegts_crc32(const uint8_t *data, int len) -{ + bool srs_aac_startswith_adts(SrsBuffer* stream) + { + char* bytes = stream->data() + stream->pos(); + char* p = bytes; + + if (!stream->require((int)(p - bytes) + 2)) { + return false; + } + + // matched 12bits 0xFFF, + // @remark, we must cast the 0xff to char to compare. + if (p[0] != (char)0xff || (char)(p[1] & 0xf0) != (char)0xf0) { + return false; + } + + return true; + } + + // @see http://www.stmc.edu.hk/~vincent/ffmpeg_0.4.9-pre1/libavformat/mpegtsenc.c + unsigned int __mpegts_crc32(const uint8_t *data, int len) + { + /* + * MPEG2 transport stream (aka DVB) mux + * Copyright (c) 2003 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + static const uint32_t table[256] = { + 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, + 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, + 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, + 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, + 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, + 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, + 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, + 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, + 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, + 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, + 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, + 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, + 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, + 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, + 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, + 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, + 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, + 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, + 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, + 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, + 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, + 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, + 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, + 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, + 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, + 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, + 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, + 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, + 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, + 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, + 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, + 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, + 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, + 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, + 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, + 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, + 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, + 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, + 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, + 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, + 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, + 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, + 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 + }; + + uint32_t crc = 0xffffffff; + + for (int i=0; i> 24) ^ *data++) & 0xff]; + } + + return crc; + } + + // @see https://github.com/ETrun/crc32/blob/master/crc32.c + uint32_t __crc32_ieee(uint32_t init, const uint8_t* buf, size_t nb_buf) + { + /*----------------------------------------------------------------------------*\ + * CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29. + * + * This program generates the CRC-32 values for the files named in the + * command-line arguments. These are the same CRC-32 values used by GZIP, + * PKZIP, and ZMODEM. The Crc32_ComputeBuf() can also be detached and + * used independently. + * + * THIS PROGRAM IS PUBLIC-DOMAIN SOFTWARE. + * + * Based on the byte-oriented implementation "File Verification Using CRC" + * by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67. + * + * v1.0.0: original release. + * v1.0.1: fixed printf formats. + * v1.0.2: fixed something else. + * v1.0.3: replaced CRC constant table by generator function. + * v1.0.4: reformatted code, made ANSI C. 1994-12-05. + * v2.0.0: rewrote to use memory buffer & static table, 2006-04-29. + * v2.1.0: modified by Nico, 2013-04-20 + \*----------------------------------------------------------------------------*/ + static const uint32_t table[256] = { + 0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535, + 0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD, + 0xE7B82D07,0x90BF1D91,0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D, + 0x6DDDE4EB,0xF4D4B551,0x83D385C7,0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC, + 0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,0x3B6E20C8,0x4C69105E,0xD56041E4, + 0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C, + 0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,0x26D930AC, + 0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F, + 0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB, + 0xB6662D3D,0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F, + 0x9FBFE4A5,0xE8B8D433,0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB, + 0x086D3D2D,0x91646C97,0xE6635C01,0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E, + 0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950,0x8BBEB8EA, + 0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65,0x4DB26158,0x3AB551CE, + 0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB,0x4369E96A, + 0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9, + 0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409, + 0xCE61E49F,0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81, + 0xB7BD5C3B,0xC0BA6CAD,0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739, + 0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8, + 0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,0xF00F9344,0x8708A3D2,0x1E01F268, + 0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0, + 0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,0xD6D6A3E8, + 0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B, + 0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF, + 0x4669BE79,0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703, + 0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7, + 0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A, + 0x9C0906A9,0xEB0E363F,0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE, + 0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,0x86D3D2D4,0xF1D4E242, + 0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,0x88085AE6, + 0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45, + 0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D, + 0x3E6E77DB,0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5, + 0x47B2CF7F,0x30B5FFE9,0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605, + 0xCDD70693,0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94, + 0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D + }; + + uint32_t crc = init ^ 0xFFFFFFFF; + + for (size_t i = 0; i < nb_buf; i++) { + crc = table[(crc ^ buf[i]) & 0xff] ^ (crc >> 8); + } + + return crc^0xFFFFFFFF; + } + + uint32_t srs_crc32_mpegts(const void* buf, int size) + { + return __mpegts_crc32((const uint8_t*)buf, size); + } + + uint32_t srs_crc32_ieee(const void* buf, int size, uint32_t previous) + { + return __crc32_ieee(previous, (const uint8_t*)buf, size); + } + /* - * MPEG2 transport stream (aka DVB) mux - * Copyright (c) 2003 Fabrice Bellard. + * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com) * - * This library is free software; you can redistribute it and/or + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. + * version 2.1 of the License, or (at your option) any later version. * - * This library is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - static const uint32_t table[256] = { - 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, - 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, - 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, - 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, - 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, - 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, - 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, - 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, - 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, - 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, - 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, - 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, - 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, - 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, - 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, - 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, - 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, - 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, - 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, - 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, - 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, - 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, - 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, - 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, - 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, - 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, - 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, - 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, - 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, - 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, - 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, - 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, - 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, - 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, - 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, - 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, - 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, - 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, - 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, - 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, - 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, - 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, - 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 - }; - uint32_t crc = 0xffffffff; - - for (int i=0; i> 24) ^ *data++) & 0xff]; - } - - return crc; -} - -// @see https://github.com/ETrun/crc32/blob/master/crc32.c -uint32_t __crc32_ieee(uint32_t init, const uint8_t* buf, size_t nb_buf) -{ - /*----------------------------------------------------------------------------*\ - * CRC-32 version 2.0.0 by Craig Bruce, 2006-04-29. - * - * This program generates the CRC-32 values for the files named in the - * command-line arguments. These are the same CRC-32 values used by GZIP, - * PKZIP, and ZMODEM. The Crc32_ComputeBuf() can also be detached and - * used independently. - * - * THIS PROGRAM IS PUBLIC-DOMAIN SOFTWARE. - * - * Based on the byte-oriented implementation "File Verification Using CRC" - * by Mark R. Nelson in Dr. Dobb's Journal, May 1992, pp. 64-67. - * - * v1.0.0: original release. - * v1.0.1: fixed printf formats. - * v1.0.2: fixed something else. - * v1.0.3: replaced CRC constant table by generator function. - * v1.0.4: reformatted code, made ANSI C. 1994-12-05. - * v2.0.0: rewrote to use memory buffer & static table, 2006-04-29. - * v2.1.0: modified by Nico, 2013-04-20 - \*----------------------------------------------------------------------------*/ - static const uint32_t table[256] = { - 0x00000000,0x77073096,0xEE0E612C,0x990951BA,0x076DC419,0x706AF48F,0xE963A535, - 0x9E6495A3,0x0EDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x09B64C2B,0x7EB17CBD, - 0xE7B82D07,0x90BF1D91,0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D, - 0x6DDDE4EB,0xF4D4B551,0x83D385C7,0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC, - 0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,0x3B6E20C8,0x4C69105E,0xD56041E4, - 0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C, - 0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,0x26D930AC, - 0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F, - 0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB, - 0xB6662D3D,0x76DC4190,0x01DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x06B6B51F, - 0x9FBFE4A5,0xE8B8D433,0x7807C9A2,0x0F00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB, - 0x086D3D2D,0x91646C97,0xE6635C01,0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E, - 0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950,0x8BBEB8EA, - 0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65,0x4DB26158,0x3AB551CE, - 0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB,0x4369E96A, - 0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9, - 0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409, - 0xCE61E49F,0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81, - 0xB7BD5C3B,0xC0BA6CAD,0xEDB88320,0x9ABFB3B6,0x03B6E20C,0x74B1D29A,0xEAD54739, - 0x9DD277AF,0x04DB2615,0x73DC1683,0xE3630B12,0x94643B84,0x0D6D6A3E,0x7A6A5AA8, - 0xE40ECF0B,0x9309FF9D,0x0A00AE27,0x7D079EB1,0xF00F9344,0x8708A3D2,0x1E01F268, - 0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0, - 0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,0xD6D6A3E8, - 0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B, - 0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF, - 0x4669BE79,0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703, - 0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7, - 0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,0x9B64C2B0,0xEC63F226,0x756AA39C,0x026D930A, - 0x9C0906A9,0xEB0E363F,0x72076785,0x05005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE, - 0x0CB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0x0BDBDF21,0x86D3D2D4,0xF1D4E242, - 0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,0x88085AE6, - 0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45, - 0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D, - 0x3E6E77DB,0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5, - 0x47B2CF7F,0x30B5FFE9,0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605, - 0xCDD70693,0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94, - 0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D - }; - - uint32_t crc = init ^ 0xFFFFFFFF; - - for (size_t i = 0; i < nb_buf; i++) { - crc = table[(crc ^ buf[i]) & 0xff] ^ (crc >> 8); - } - - return crc^0xFFFFFFFF; -} - -uint32_t srs_crc32_mpegts(const void* buf, int size) -{ - return __mpegts_crc32((const uint8_t*)buf, size); -} - -uint32_t srs_crc32_ieee(const void* buf, int size, uint32_t previous) -{ - return __crc32_ieee(previous, (const uint8_t*)buf, size); -} - -/* - * Copyright (c) 2006 Ryan Martell. (rdm4@martellventures.com) - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - #ifndef UINT_MAX #define UINT_MAX 0xffffffff #endif - + #ifndef AV_RB32 # define AV_RB32(x) \ (((uint32_t)((const uint8_t*)(x))[0] << 24) | \ - (((const uint8_t*)(x))[1] << 16) | \ - (((const uint8_t*)(x))[2] << 8) | \ - ((const uint8_t*)(x))[3]) + (((const uint8_t*)(x))[1] << 16) | \ + (((const uint8_t*)(x))[2] << 8) | \ + ((const uint8_t*)(x))[3]) #endif - + #ifndef AV_WL32 # define AV_WL32(p, darg) do { \ - unsigned d = (darg); \ - ((uint8_t*)(p))[0] = (d); \ - ((uint8_t*)(p))[1] = (d)>>8; \ - ((uint8_t*)(p))[2] = (d)>>16; \ - ((uint8_t*)(p))[3] = (d)>>24; \ - } while(0) + unsigned d = (darg); \ + ((uint8_t*)(p))[0] = (d); \ + ((uint8_t*)(p))[1] = (d)>>8; \ + ((uint8_t*)(p))[2] = (d)>>16; \ + ((uint8_t*)(p))[3] = (d)>>24; \ +} while(0) #endif - + # define AV_WN(s, p, v) AV_WL##s(p, v) - + # if defined(AV_WN32) && !defined(AV_WL32) # define AV_WL32(p, v) AV_WN32(p, v) # elif !defined(AV_WN32) && defined(AV_WL32) # define AV_WN32(p, v) AV_WL32(p, v) # endif - + #ifndef AV_WN32 -# define AV_WN32(p, v) AV_WN(32, p, v) + # define AV_WN32(p, v) AV_WN(32, p, v) #endif - + #define AV_BSWAP16C(x) (((x) << 8 & 0xff00) | ((x) >> 8 & 0x00ff)) #define AV_BSWAP32C(x) (AV_BSWAP16C(x) << 16 | AV_BSWAP16C((x) >> 16)) - + #ifndef av_bswap32 -static const uint32_t av_bswap32(uint32_t x) -{ - return AV_BSWAP32C(x); -} + static const uint32_t av_bswap32(uint32_t x) + { + return AV_BSWAP32C(x); + } #endif - + #define av_be2ne32(x) av_bswap32(x) - -/** - * @file - * @brief Base64 encode/decode - * @author Ryan Martell (with lots of Michael) - */ - -/* ---------------- private code */ -static const uint8_t map2[256] = -{ - 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, - - 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, - 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, - 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, - - 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, -}; - + + /** + * @file + * @brief Base64 encode/decode + * @author Ryan Martell (with lots of Michael) + */ + + /* ---------------- private code */ + static const uint8_t map2[256] = + { + 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, + + 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, + 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + + 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + }; + #define BASE64_DEC_STEP(i) do { \ bits = map2[in[i]]; \ if (bits & 0x80) \ goto out ## i; \ v = i ? (v << 6) + bits : bits; \ } while(0) - -int srs_av_base64_decode(uint8_t* out, const char* in_str, int out_size) -{ - uint8_t *dst = out; - uint8_t *end = out + out_size; - // no sign extension - const uint8_t *in = (const uint8_t*)in_str; - unsigned bits = 0xff; - unsigned v; - - while (end - dst > 3) { - BASE64_DEC_STEP(0); - BASE64_DEC_STEP(1); - BASE64_DEC_STEP(2); - BASE64_DEC_STEP(3); - // Using AV_WB32 directly confuses compiler - v = av_be2ne32(v << 8); - AV_WN32(dst, v); - dst += 3; - in += 4; - } - if (end - dst) { - BASE64_DEC_STEP(0); - BASE64_DEC_STEP(1); - BASE64_DEC_STEP(2); - BASE64_DEC_STEP(3); - *dst++ = v >> 16; - if (end - dst) - *dst++ = v >> 8; - if (end - dst) - *dst++ = v; - in += 4; - } - while (1) { - BASE64_DEC_STEP(0); - in++; - BASE64_DEC_STEP(0); - in++; - BASE64_DEC_STEP(0); - in++; - BASE64_DEC_STEP(0); - in++; - } - -out3: - *dst++ = v >> 10; - v <<= 2; -out2: - *dst++ = v >> 4; -out1: -out0: - return bits & 1 ? -1 : dst - out; -} - -/***************************************************************************** -* b64_encode: Stolen from VLC's http.c. -* Simplified by Michael. -* Fixed edge cases and made it work from data (vs. strings) by Ryan. -*****************************************************************************/ - -char* srs_av_base64_encode(char* out, int out_size, const uint8_t* in, int in_size) -{ - static const char b64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - char *ret, *dst; - unsigned i_bits = 0; - int i_shift = 0; - int bytes_remaining = in_size; - - if (in_size >= (int)(UINT_MAX / 4) || - out_size < SRS_AV_BASE64_SIZE(in_size)) - return NULL; - ret = dst = out; - while (bytes_remaining > 3) { - i_bits = AV_RB32(in); - in += 3; bytes_remaining -= 3; - *dst++ = b64[ i_bits>>26 ]; - *dst++ = b64[(i_bits>>20) & 0x3F]; - *dst++ = b64[(i_bits>>14) & 0x3F]; - *dst++ = b64[(i_bits>>8 ) & 0x3F]; - } - i_bits = 0; - while (bytes_remaining) { - i_bits = (i_bits << 8) + *in++; - bytes_remaining--; - i_shift += 8; - } - while (i_shift > 0) { - *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f]; - i_shift -= 6; - } - while ((dst - ret) & 3) - *dst++ = '='; - *dst = '\0'; - - return ret; -} - -#define SPACE_CHARS " \t\r\n" - -int av_toupper(int c) -{ - if (c >= 'a' && c <= 'z') { - c ^= 0x20; - } - return c; -} - -int ff_hex_to_data(uint8_t* data, const char* p) -{ - int c, len, v; - - len = 0; - v = 1; - for (;;) { - p += strspn(p, SPACE_CHARS); - if (*p == '\0') - break; - c = av_toupper((unsigned char) *p++); - if (c >= '0' && c <= '9') - c = c - '0'; - else if (c >= 'A' && c <= 'F') - c = c - 'A' + 10; - else - break; - v = (v << 4) | c; - if (v & 0x100) { - if (data) - data[len] = v; - len++; - v = 1; + + int srs_av_base64_decode(uint8_t* out, const char* in_str, int out_size) + { + uint8_t *dst = out; + uint8_t *end = out + out_size; + // no sign extension + const uint8_t *in = (const uint8_t*)in_str; + unsigned bits = 0xff; + unsigned v; + + while (end - dst > 3) { + BASE64_DEC_STEP(0); + BASE64_DEC_STEP(1); + BASE64_DEC_STEP(2); + BASE64_DEC_STEP(3); + // Using AV_WB32 directly confuses compiler + v = av_be2ne32(v << 8); + AV_WN32(dst, v); + dst += 3; + in += 4; } - } - return len; -} - -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 -) { - // to directly set the field. - char* pp = NULL; - - // generate the header. - char* p = cache; - - // no header. - if (nb_cache < SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE) { - return 0; + if (end - dst) { + BASE64_DEC_STEP(0); + BASE64_DEC_STEP(1); + BASE64_DEC_STEP(2); + BASE64_DEC_STEP(3); + *dst++ = v >> 16; + if (end - dst) + *dst++ = v >> 8; + if (end - dst) + *dst++ = v; + in += 4; + } + while (1) { + BASE64_DEC_STEP(0); + in++; + BASE64_DEC_STEP(0); + in++; + BASE64_DEC_STEP(0); + in++; + BASE64_DEC_STEP(0); + in++; + } + + out3: + *dst++ = v >> 10; + v <<= 2; + out2: + *dst++ = v >> 4; + out1: + out0: + return bits & 1 ? -1 : dst - out; } - // write new chunk stream header, fmt is 0 - *p++ = 0x00 | (perfer_cid & 0x3F); + /***************************************************************************** + * b64_encode: Stolen from VLC's http.c. + * Simplified by Michael. + * Fixed edge cases and made it work from data (vs. strings) by Ryan. + *****************************************************************************/ - // chunk message header, 11 bytes - // timestamp, 3bytes, big-endian - if (timestamp < RTMP_EXTENDED_TIMESTAMP) { - pp = (char*)×tamp; + char* srs_av_base64_encode(char* out, int out_size, const uint8_t* in, int in_size) + { + static const char b64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + char *ret, *dst; + unsigned i_bits = 0; + int i_shift = 0; + int bytes_remaining = in_size; + + if (in_size >= (int)(UINT_MAX / 4) || + out_size < SRS_AV_BASE64_SIZE(in_size)) + return NULL; + ret = dst = out; + while (bytes_remaining > 3) { + i_bits = AV_RB32(in); + in += 3; bytes_remaining -= 3; + *dst++ = b64[ i_bits>>26 ]; + *dst++ = b64[(i_bits>>20) & 0x3F]; + *dst++ = b64[(i_bits>>14) & 0x3F]; + *dst++ = b64[(i_bits>>8 ) & 0x3F]; + } + i_bits = 0; + while (bytes_remaining) { + i_bits = (i_bits << 8) + *in++; + bytes_remaining--; + i_shift += 8; + } + while (i_shift > 0) { + *dst++ = b64[(i_bits << 6 >> i_shift) & 0x3f]; + i_shift -= 6; + } + while ((dst - ret) & 3) + *dst++ = '='; + *dst = '\0'; + + return ret; + } + +#define SPACE_CHARS " \t\r\n" + + int av_toupper(int c) + { + if (c >= 'a' && c <= 'z') { + c ^= 0x20; + } + return c; + } + + int ff_hex_to_data(uint8_t* data, const char* p) + { + int c, len, v; + + len = 0; + v = 1; + for (;;) { + p += strspn(p, SPACE_CHARS); + if (*p == '\0') + break; + c = av_toupper((unsigned char) *p++); + if (c >= '0' && c <= '9') + c = c - '0'; + else if (c >= 'A' && c <= 'F') + c = c - 'A' + 10; + else + break; + v = (v << 4) | c; + if (v & 0x100) { + if (data) + data[len] = v; + len++; + v = 1; + } + } + return len; + } + + 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) + { + // to directly set the field. + char* pp = NULL; + + // generate the header. + char* p = cache; + + // no header. + if (nb_cache < SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE) { + return 0; + } + + // write new chunk stream header, fmt is 0 + *p++ = 0x00 | (perfer_cid & 0x3F); + + // chunk message header, 11 bytes + // timestamp, 3bytes, big-endian + if (timestamp < RTMP_EXTENDED_TIMESTAMP) { + pp = (char*)×tamp; + *p++ = pp[2]; + *p++ = pp[1]; + *p++ = pp[0]; + } else { + *p++ = 0xFF; + *p++ = 0xFF; + *p++ = 0xFF; + } + + // message_length, 3bytes, big-endian + pp = (char*)&payload_length; *p++ = pp[2]; *p++ = pp[1]; *p++ = pp[0]; - } else { - *p++ = 0xFF; - *p++ = 0xFF; - *p++ = 0xFF; - } - - // message_length, 3bytes, big-endian - pp = (char*)&payload_length; - *p++ = pp[2]; - *p++ = pp[1]; - *p++ = pp[0]; - - // message_type, 1bytes - *p++ = message_type; - - // stream_id, 4bytes, little-endian - pp = (char*)&stream_id; - *p++ = pp[0]; - *p++ = pp[1]; - *p++ = pp[2]; - *p++ = pp[3]; - - // for c0 - // chunk extended timestamp header, 0 or 4 bytes, big-endian - // - // for c3: - // chunk extended timestamp header, 0 or 4 bytes, big-endian - // 6.1.3. Extended Timestamp - // This field is transmitted only when the normal time stamp in the - // chunk message header is set to 0x00ffffff. If normal time stamp is - // set to any value less than 0x00ffffff, this field MUST NOT be - // present. This field MUST NOT be present if the timestamp field is not - // present. Type 3 chunks MUST NOT have this field. - // adobe changed for Type3 chunk: - // FMLE always sendout the extended-timestamp, - // must send the extended-timestamp to FMS, - // must send the extended-timestamp to flash-player. - // @see: ngx_rtmp_prepare_message - // @see: http://blog.csdn.net/win_lin/article/details/13363699 - // TODO: FIXME: extract to outer. - if (timestamp >= RTMP_EXTENDED_TIMESTAMP) { - pp = (char*)×tamp; + + // message_type, 1bytes + *p++ = message_type; + + // stream_id, 4bytes, little-endian + pp = (char*)&stream_id; + *p++ = pp[0]; + *p++ = pp[1]; + *p++ = pp[2]; *p++ = pp[3]; - *p++ = pp[2]; - *p++ = pp[1]; - *p++ = pp[0]; + + // for c0 + // chunk extended timestamp header, 0 or 4 bytes, big-endian + // + // for c3: + // chunk extended timestamp header, 0 or 4 bytes, big-endian + // 6.1.3. Extended Timestamp + // This field is transmitted only when the normal time stamp in the + // chunk message header is set to 0x00ffffff. If normal time stamp is + // set to any value less than 0x00ffffff, this field MUST NOT be + // present. This field MUST NOT be present if the timestamp field is not + // present. Type 3 chunks MUST NOT have this field. + // adobe changed for Type3 chunk: + // FMLE always sendout the extended-timestamp, + // must send the extended-timestamp to FMS, + // must send the extended-timestamp to flash-player. + // @see: ngx_rtmp_prepare_message + // @see: http://blog.csdn.net/win_lin/article/details/13363699 + // TODO: FIXME: extract to outer. + if (timestamp >= RTMP_EXTENDED_TIMESTAMP) { + pp = (char*)×tamp; + *p++ = pp[3]; + *p++ = pp[2]; + *p++ = pp[1]; + *p++ = pp[0]; + } + + // always has header + return (int)(p - cache); } - // always has header - return p - cache; -} - -int srs_chunk_header_c3( - int perfer_cid, uint32_t timestamp, - char* cache, int nb_cache -) { - // to directly set the field. - char* pp = NULL; - - // generate the header. - char* p = cache; - - // no header. - if (nb_cache < SRS_CONSTS_RTMP_MAX_FMT3_HEADER_SIZE) { - return 0; + int srs_chunk_header_c3(int perfer_cid, uint32_t timestamp, char* cache, int nb_cache) + { + // to directly set the field. + char* pp = NULL; + + // generate the header. + char* p = cache; + + // no header. + if (nb_cache < SRS_CONSTS_RTMP_MAX_FMT3_HEADER_SIZE) { + return 0; + } + + // write no message header chunk stream, fmt is 3 + // @remark, if perfer_cid > 0x3F, that is, use 2B/3B chunk header, + // SRS will rollback to 1B chunk header. + *p++ = 0xC0 | (perfer_cid & 0x3F); + + // for c0 + // chunk extended timestamp header, 0 or 4 bytes, big-endian + // + // for c3: + // chunk extended timestamp header, 0 or 4 bytes, big-endian + // 6.1.3. Extended Timestamp + // This field is transmitted only when the normal time stamp in the + // chunk message header is set to 0x00ffffff. If normal time stamp is + // set to any value less than 0x00ffffff, this field MUST NOT be + // present. This field MUST NOT be present if the timestamp field is not + // present. Type 3 chunks MUST NOT have this field. + // adobe changed for Type3 chunk: + // FMLE always sendout the extended-timestamp, + // must send the extended-timestamp to FMS, + // must send the extended-timestamp to flash-player. + // @see: ngx_rtmp_prepare_message + // @see: http://blog.csdn.net/win_lin/article/details/13363699 + // TODO: FIXME: extract to outer. + if (timestamp >= RTMP_EXTENDED_TIMESTAMP) { + pp = (char*)×tamp; + *p++ = pp[3]; + *p++ = pp[2]; + *p++ = pp[1]; + *p++ = pp[0]; + } + + // always has header + return (int)(p - cache); } - // write no message header chunk stream, fmt is 3 - // @remark, if perfer_cid > 0x3F, that is, use 2B/3B chunk header, - // SRS will rollback to 1B chunk header. - *p++ = 0xC0 | (perfer_cid & 0x3F); - - // for c0 - // chunk extended timestamp header, 0 or 4 bytes, big-endian - // - // for c3: - // chunk extended timestamp header, 0 or 4 bytes, big-endian - // 6.1.3. Extended Timestamp - // This field is transmitted only when the normal time stamp in the - // chunk message header is set to 0x00ffffff. If normal time stamp is - // set to any value less than 0x00ffffff, this field MUST NOT be - // present. This field MUST NOT be present if the timestamp field is not - // present. Type 3 chunks MUST NOT have this field. - // adobe changed for Type3 chunk: - // FMLE always sendout the extended-timestamp, - // must send the extended-timestamp to FMS, - // must send the extended-timestamp to flash-player. - // @see: ngx_rtmp_prepare_message - // @see: http://blog.csdn.net/win_lin/article/details/13363699 - // TODO: FIXME: extract to outer. - if (timestamp >= RTMP_EXTENDED_TIMESTAMP) { - pp = (char*)×tamp; - *p++ = pp[3]; - *p++ = pp[2]; - *p++ = pp[1]; - *p++ = pp[0]; - } - - // always has header - return p - cache; -} - diff --git a/trunk/src/kernel/srs_kernel_utility.hpp b/trunk/src/kernel/srs_kernel_utility.hpp index ea3555634..79cc2ae06 100644 --- a/trunk/src/kernel/srs_kernel_utility.hpp +++ b/trunk/src/kernel/srs_kernel_utility.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_KERNEL_UTILITY_HPP #define SRS_KERNEL_UTILITY_HPP -/* -#include -*/ - #include #include @@ -120,23 +116,23 @@ extern std::string srs_path_filename(std::string path); 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. + * 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. + * 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); @@ -146,40 +142,40 @@ extern uint32_t srs_crc32_mpegts(const void* buf, int size); extern uint32_t srs_crc32_ieee(const void* buf, int size, uint32_t previous = 0); /** -* Decode a base64-encoded string. -* -* @param out buffer for decoded data -* @param in null-terminated input string -* @param out_size size in bytes of the out buffer, must be at -* least 3/4 of the length of in -* @return number of bytes written, or a negative value in case of -* invalid input -*/ + * Decode a base64-encoded string. + * + * @param out buffer for decoded data + * @param in null-terminated input string + * @param out_size size in bytes of the out buffer, must be at + * least 3/4 of the length of in + * @return number of bytes written, or a negative value in case of + * invalid input + */ extern int srs_av_base64_decode(uint8_t* out, const char* in, int out_size); /** -* Encode data to base64 and null-terminate. -* -* @param out buffer for encoded data -* @param out_size size in bytes of the out buffer (including the -* null terminator), must be at least AV_BASE64_SIZE(in_size) -* @param in input buffer containing the data to encode -* @param in_size size in bytes of the in buffer -* @return out or NULL in case of error -*/ + * Encode data to base64 and null-terminate. + * + * @param out buffer for encoded data + * @param out_size size in bytes of the out buffer (including the + * null terminator), must be at least AV_BASE64_SIZE(in_size) + * @param in input buffer containing the data to encode + * @param in_size size in bytes of the in buffer + * @return out or NULL in case of error + */ extern char* srs_av_base64_encode(char* out, int out_size, const uint8_t* in, int in_size); /** * 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) +#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' + * output hex to data={0x13, 0x90, 0x56, 0xe5, 0xa0} + */ extern int ff_hex_to_data(uint8_t* data, const char* p); /** @@ -188,11 +184,7 @@ extern int ff_hex_to_data(uint8_t* data, const char* p); * @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 - ); +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. @@ -200,10 +192,7 @@ extern int srs_chunk_header_c0( * @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 - ); +extern int srs_chunk_header_c3(int perfer_cid, uint32_t timestamp, char* cache, int nb_cache); #endif diff --git a/trunk/src/libs/srs_lib_bandwidth.cpp b/trunk/src/libs/srs_lib_bandwidth.cpp index 68e9e3691..3805ee810 100644 --- a/trunk/src/libs/srs_lib_bandwidth.cpp +++ b/trunk/src/libs/srs_lib_bandwidth.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -39,8 +39,8 @@ using namespace std; #include /** -* recv bandwidth helper. -*/ + * recv bandwidth helper. + */ typedef bool (*_CheckPacketType)(SrsBandwidthPacket* pkt); bool _bandwidth_is_start_play(SrsBandwidthPacket* pkt) { @@ -119,18 +119,18 @@ SrsBandwidthClient::~SrsBandwidthClient() int SrsBandwidthClient::initialize(SrsRtmpClient* rtmp) { _rtmp = rtmp; - + return ERROR_SUCCESS; } int SrsBandwidthClient::bandwidth_check( - int64_t* start_time, int64_t* end_time, + int64_t* start_time, int64_t* end_time, int* play_kbps, int* publish_kbps, int* play_bytes, int* publish_bytes, int* play_duration, int* publish_duration ) { int ret = ERROR_SUCCESS; - + srs_update_system_time_ms(); *start_time = srs_get_system_time_ms(); @@ -186,7 +186,7 @@ int SrsBandwidthClient::bandwidth_check( *publish_duration = (int)prop->to_number(); } } - + srs_update_system_time_ms(); *end_time = srs_get_system_time_ms(); @@ -196,7 +196,7 @@ int SrsBandwidthClient::bandwidth_check( int SrsBandwidthClient::play_start() { int ret = ERROR_SUCCESS; - + if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_start_play)) != ERROR_SUCCESS) { return ret; } @@ -205,7 +205,7 @@ int SrsBandwidthClient::play_start() if (true) { // send start play response to server. SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_starting_play(); - + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send bandwidth check start play message failed. ret=%d", ret); return ret; @@ -225,7 +225,7 @@ int SrsBandwidthClient::play_checking() int SrsBandwidthClient::play_stop() { int ret = ERROR_SUCCESS; - + if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stop_play)) != ERROR_SUCCESS) { return ret; } @@ -234,7 +234,7 @@ int SrsBandwidthClient::play_stop() if (true) { // send stop play response to server. SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stopped_play(); - + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send bandwidth check stop play message failed. ret=%d", ret); return ret; @@ -248,7 +248,7 @@ int SrsBandwidthClient::play_stop() int SrsBandwidthClient::publish_start(int& duration_ms, int& play_kbps) { int ret = ERROR_SUCCESS; - + if (true) { SrsBandwidthPacket* pkt = NULL; if ((ret = _srs_expect_bandwidth_packet2(_rtmp, _bandwidth_is_start_publish, &pkt)) != ERROR_SUCCESS) { @@ -269,7 +269,7 @@ int SrsBandwidthClient::publish_start(int& duration_ms, int& play_kbps) if (true) { // send start publish response to server. SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_starting_publish(); - + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send bandwidth check start publish message failed. ret=%d", ret); return ret; @@ -295,14 +295,14 @@ int SrsBandwidthClient::publish_checking(int duration_ms, int play_kbps) srs_error("server must specifies the play kbp, ret=%d", ret); return ret; } - + int data_count = 1; srs_update_system_time_ms(); int64_t starttime = srs_get_system_time_ms(); while ((srs_get_system_time_ms() - starttime) < duration_ms) { // TODO: FIXME: use shared ptr message. SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_publishing(); - + // TODO: FIXME: magic number for (int i = 0; i < data_count; ++i) { std::stringstream seq; @@ -311,7 +311,7 @@ int SrsBandwidthClient::publish_checking(int duration_ms, int play_kbps) pkt->data->set(seq.str(), SrsAmf0Any::str(play_data.c_str())); } data_count += 2; - + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send bandwidth check publish messages failed. ret=%d", ret); return ret; @@ -342,14 +342,14 @@ int SrsBandwidthClient::publish_stop() if (true) { // send start publish response to server. SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stop_publish(); - + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send bandwidth check stop publish message failed. ret=%d", ret); return ret; } } srs_info("BW client stop publish request."); - + if ((ret = _srs_expect_bandwidth_packet(_rtmp, _bandwidth_is_stop_publish)) != ERROR_SUCCESS) { return ret; } @@ -358,7 +358,7 @@ int SrsBandwidthClient::publish_stop() if (true) { // send start publish response to server. SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_stopped_publish(); - + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send bandwidth check stop publish message failed. ret=%d", ret); return ret; @@ -372,7 +372,7 @@ int SrsBandwidthClient::publish_stop() int SrsBandwidthClient::final(SrsBandwidthPacket** ppkt) { int ret = ERROR_SUCCESS; - + if ((ret = _srs_expect_bandwidth_packet2(_rtmp, _bandwidth_is_finish, ppkt)) != ERROR_SUCCESS) { return ret; } @@ -381,7 +381,7 @@ int SrsBandwidthClient::final(SrsBandwidthPacket** ppkt) if (true) { // send final response to server. SrsBandwidthPacket* pkt = SrsBandwidthPacket::create_final(); - + if ((ret = _rtmp->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send bandwidth check final message failed. ret=%d", ret); return ret; diff --git a/trunk/src/libs/srs_lib_bandwidth.hpp b/trunk/src/libs/srs_lib_bandwidth.hpp index 5f2e95d1a..f0044f4a6 100644 --- a/trunk/src/libs/srs_lib_bandwidth.hpp +++ b/trunk/src/libs/srs_lib_bandwidth.hpp @@ -1,41 +1,37 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_LIB_BANDWIDTH_HPP #define SRS_LIB_BANDWIDTH_HPP -/* -#include -*/ - #include class SrsRtmpClient; class SrsBandwidthPacket; /** -* bandwith client library for srs-librtmp. -*/ + * bandwith client library for srs-librtmp. + */ class SrsBandwidthClient { private: @@ -45,44 +41,43 @@ public: virtual ~SrsBandwidthClient(); public: /** - * initialize the bandwidth check client. - */ + * initialize the bandwidth check client. + */ virtual int initialize(SrsRtmpClient* rtmp); /** - * do bandwidth check. - * - * bandwidth info: - * @param start_time, output the start time, in ms. - * @param end_time, output the end time, in ms. - * @param play_kbps, output the play/download kbps. - * @param publish_kbps, output the publish/upload kbps. - * @param play_bytes, output the play/download bytes. - * @param publish_bytes, output the publish/upload bytes. - * @param play_duration, output the play/download test duration, in ms. - * @param publish_duration, output the publish/upload test duration, in ms. - */ + * do bandwidth check. + * + * bandwidth info: + * @param start_time, output the start time, in ms. + * @param end_time, output the end time, in ms. + * @param play_kbps, output the play/download kbps. + * @param publish_kbps, output the publish/upload kbps. + * @param play_bytes, output the play/download bytes. + * @param publish_bytes, output the publish/upload bytes. + * @param play_duration, output the play/download test duration, in ms. + * @param publish_duration, output the publish/upload test duration, in ms. + */ virtual int bandwidth_check( - int64_t* start_time, int64_t* end_time, + int64_t* start_time, int64_t* end_time, int* play_kbps, int* publish_kbps, int* play_bytes, int* publish_bytes, - int* play_duration, int* publish_duration - ); + int* play_duration, int* publish_duration); private: /** - * play check/test, downloading bandwidth kbps. - */ + * play check/test, downloading bandwidth kbps. + */ virtual int play_start(); virtual int play_checking(); virtual int play_stop(); /** - * publish check/test, publishing bandwidth kbps. - */ + * publish check/test, publishing bandwidth kbps. + */ virtual int publish_start(int& duration_ms, int& play_kbps); virtual int publish_checking(int duration_ms, int play_kbps); virtual int publish_stop(); /** - * report and final packet - */ + * report and final packet + */ virtual int final(SrsBandwidthPacket** ppkt); }; diff --git a/trunk/src/libs/srs_lib_simple_socket.cpp b/trunk/src/libs/srs_lib_simple_socket.cpp index 0a3ff5195..9a4a2a579 100644 --- a/trunk/src/libs/srs_lib_simple_socket.cpp +++ b/trunk/src/libs/srs_lib_simple_socket.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -27,39 +27,39 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 #ifndef _WIN32 - #define SOCKET_ETIME EWOULDBLOCK - #define SOCKET_ECONNRESET ECONNRESET +#define SOCKET_ETIME EWOULDBLOCK +#define SOCKET_ECONNRESET ECONNRESET - #define SOCKET_ERRNO() errno - #define SOCKET_RESET(fd) fd = -1; (void)0 - #define SOCKET_CLOSE(fd) \ - if (fd > 0) {\ - ::close(fd); \ - fd = -1; \ - } \ - (void)0 - #define SOCKET_VALID(x) (x > 0) - #define SOCKET_SETUP() (void)0 - #define SOCKET_CLEANUP() (void)0 +#define SOCKET_ERRNO() errno +#define SOCKET_RESET(fd) fd = -1; (void)0 +#define SOCKET_CLOSE(fd) \ + if (fd > 0) {\ + ::close(fd); \ + fd = -1; \ + } \ + (void)0 +#define SOCKET_VALID(x) (x > 0) +#define SOCKET_SETUP() (void)0 +#define SOCKET_CLEANUP() (void)0 #else - #define SOCKET_ETIME WSAETIMEDOUT - #define SOCKET_ECONNRESET WSAECONNRESET - #define SOCKET_ERRNO() WSAGetLastError() - #define SOCKET_RESET(x) x=INVALID_SOCKET - #define SOCKET_CLOSE(x) if(x!=INVALID_SOCKET){::closesocket(x);x=INVALID_SOCKET;} - #define SOCKET_VALID(x) (x!=INVALID_SOCKET) - #define SOCKET_BUFF(x) ((char*)x) - #define SOCKET_SETUP() socket_setup() - #define SOCKET_CLEANUP() socket_cleanup() +#define SOCKET_ETIME WSAETIMEDOUT +#define SOCKET_ECONNRESET WSAECONNRESET +#define SOCKET_ERRNO() WSAGetLastError() +#define SOCKET_RESET(x) x=INVALID_SOCKET +#define SOCKET_CLOSE(x) if(x!=INVALID_SOCKET){::closesocket(x);x=INVALID_SOCKET;} +#define SOCKET_VALID(x) (x!=INVALID_SOCKET) +#define SOCKET_BUFF(x) ((char*)x) +#define SOCKET_SETUP() socket_setup() +#define SOCKET_CLEANUP() socket_cleanup() #endif // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 #ifndef _WIN32 - #include - #include - #include - #include - #include +#include +#include +#include +#include +#include #endif #include @@ -70,245 +70,245 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // when io not hijacked, use simple socket, the block sync stream. #ifndef SRS_HIJACK_IO - struct SrsBlockSyncSocket - { - SOCKET fd; - int64_t rbytes; - int64_t sbytes; - // The send/recv timeout in ms. - int64_t rtm; - int64_t stm; - - SrsBlockSyncSocket() { - stm = rtm = SRS_CONSTS_NO_TMMS; - rbytes = sbytes = 0; - - SOCKET_RESET(fd); - SOCKET_SETUP(); - } - - virtual ~SrsBlockSyncSocket() { - SOCKET_CLOSE(fd); - SOCKET_CLEANUP(); - } - }; - srs_hijack_io_t srs_hijack_io_create() - { - SrsBlockSyncSocket* skt = new SrsBlockSyncSocket(); - return skt; - } - void srs_hijack_io_destroy(srs_hijack_io_t ctx) - { - SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; - srs_freep(skt); - } - int srs_hijack_io_create_socket(srs_hijack_io_t ctx, srs_rtmp_t owner) - { - SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; - - skt->fd = ::socket(AF_INET, SOCK_STREAM, 0); - if (!SOCKET_VALID(skt->fd)) { - return ERROR_SOCKET_CREATE; - } +struct SrsBlockSyncSocket +{ + SOCKET fd; + int64_t rbytes; + int64_t sbytes; + // The send/recv timeout in ms. + int64_t rtm; + int64_t stm; - return ERROR_SUCCESS; + SrsBlockSyncSocket() { + stm = rtm = SRS_CONSTS_NO_TMMS; + rbytes = sbytes = 0; + + SOCKET_RESET(fd); + SOCKET_SETUP(); } - int srs_hijack_io_connect(srs_hijack_io_t ctx, const char* server_ip, int port) - { - SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; - - sockaddr_in addr; - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = inet_addr(server_ip); - - if(::connect(skt->fd, (const struct sockaddr*)&addr, sizeof(sockaddr_in)) < 0){ - return ERROR_SOCKET_CONNECT; + + virtual ~SrsBlockSyncSocket() { + SOCKET_CLOSE(fd); + SOCKET_CLEANUP(); + } +}; +srs_hijack_io_t srs_hijack_io_create() +{ + SrsBlockSyncSocket* skt = new SrsBlockSyncSocket(); + return skt; +} +void srs_hijack_io_destroy(srs_hijack_io_t ctx) +{ + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + srs_freep(skt); +} +int srs_hijack_io_create_socket(srs_hijack_io_t ctx, srs_rtmp_t owner) +{ + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + + skt->fd = ::socket(AF_INET, SOCK_STREAM, 0); + if (!SOCKET_VALID(skt->fd)) { + return ERROR_SOCKET_CREATE; + } + + return ERROR_SUCCESS; +} +int srs_hijack_io_connect(srs_hijack_io_t ctx, const char* server_ip, int port) +{ + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + + sockaddr_in addr; + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = inet_addr(server_ip); + + if(::connect(skt->fd, (const struct sockaddr*)&addr, sizeof(sockaddr_in)) < 0){ + return ERROR_SOCKET_CONNECT; + } + + return ERROR_SUCCESS; +} +int srs_hijack_io_read(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread) +{ + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + + int ret = ERROR_SUCCESS; + + ssize_t nb_read = ::recv(skt->fd, (char*)buf, size, 0); + + if (nread) { + *nread = nb_read; + } + + // On success a non-negative integer indicating the number of bytes actually read is returned + // (a value of 0 means the network connection is closed or end of file is reached). + if (nb_read <= 0) { + if (nb_read < 0 && SOCKET_ERRNO() == SOCKET_ETIME) { + return ERROR_SOCKET_TIMEOUT; } - return ERROR_SUCCESS; - } - int srs_hijack_io_read(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread) - { - SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; - - int ret = ERROR_SUCCESS; - - ssize_t nb_read = ::recv(skt->fd, (char*)buf, size, 0); - - if (nread) { - *nread = nb_read; + if (nb_read == 0) { + errno = SOCKET_ECONNRESET; } - // On success a non-negative integer indicating the number of bytes actually read is returned - // (a value of 0 means the network connection is closed or end of file is reached). - if (nb_read <= 0) { - if (nb_read < 0 && SOCKET_ERRNO() == SOCKET_ETIME) { - return ERROR_SOCKET_TIMEOUT; - } - - if (nb_read == 0) { - errno = SOCKET_ECONNRESET; - } - - return ERROR_SOCKET_READ; + return ERROR_SOCKET_READ; + } + + skt->rbytes += nb_read; + + return ret; +} +int srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t tm) +{ + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + + // The default for this option is zero, + // which indicates that a receive operation shall not time out. + int32_t sec = 0; + int32_t usec = 0; + + if (tm != SRS_CONSTS_NO_TMMS) { + sec = (int32_t)(tm / 1000); + usec = (int32_t)((tm % 1000)*1000); + } + + struct timeval tv = { sec , usec }; + if (setsockopt(skt->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) { + return SOCKET_ERRNO(); + } + + skt->rtm = tm; + + return ERROR_SUCCESS; +} +int64_t srs_hijack_io_get_recv_timeout(srs_hijack_io_t ctx) +{ + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + return skt->rtm; +} +int64_t srs_hijack_io_get_recv_bytes(srs_hijack_io_t ctx) +{ + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + return skt->rbytes; +} +int srs_hijack_io_set_send_timeout(srs_hijack_io_t ctx, int64_t tm) +{ + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + + // The default for this option is zero, + // which indicates that a receive operation shall not time out. + int32_t sec = 0; + int32_t usec = 0; + + if (tm != SRS_CONSTS_NO_TMMS) { + sec = (int32_t)(tm / 1000); + usec = (int32_t)((tm % 1000)*1000); + } + + struct timeval tv = { sec , usec }; + if (setsockopt(skt->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) { + return SOCKET_ERRNO(); + } + + skt->stm = tm; + + return ERROR_SUCCESS; +} +int64_t srs_hijack_io_get_send_timeout(srs_hijack_io_t ctx) +{ + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + return skt->stm; +} +int64_t srs_hijack_io_get_send_bytes(srs_hijack_io_t ctx) +{ + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + return skt->sbytes; +} +int srs_hijack_io_writev(srs_hijack_io_t ctx, const iovec *iov, int iov_size, ssize_t* nwrite) +{ + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + + int ret = ERROR_SUCCESS; + + ssize_t nb_write = ::writev(skt->fd, iov, iov_size); + + if (nwrite) { + *nwrite = nb_write; + } + + // On success, the readv() function returns the number of bytes read; + // the writev() function returns the number of bytes written. On error, -1 is + // returned, and errno is set appropriately. + if (nb_write <= 0) { + // @see https://github.com/ossrs/srs/issues/200 + if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) { + return ERROR_SOCKET_TIMEOUT; } - skt->rbytes += nb_read; - - return ret; + return ERROR_SOCKET_WRITE; } - int srs_hijack_io_set_recv_timeout(srs_hijack_io_t ctx, int64_t tm) - { - SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + + skt->sbytes += nb_write; + + return ret; +} +int srs_hijack_io_is_never_timeout(srs_hijack_io_t ctx, int64_t tm) +{ + return tm == SRS_CONSTS_NO_TMMS; +} +int srs_hijack_io_read_fully(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread) +{ + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + + int ret = ERROR_SUCCESS; + + size_t left = size; + ssize_t nb_read = 0; + + while (left > 0) { + char* this_buf = (char*)buf + nb_read; + ssize_t this_nread; - // The default for this option is zero, - // which indicates that a receive operation shall not time out. - int32_t sec = 0; - int32_t usec = 0; - - if (tm != SRS_CONSTS_NO_TMMS) { - sec = (int32_t)(tm / 1000); - usec = (int32_t)((tm % 1000)*1000); + if ((ret = srs_hijack_io_read(ctx, this_buf, left, &this_nread)) != ERROR_SUCCESS) { + return ret; } - struct timeval tv = { sec , usec }; - if (setsockopt(skt->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) { - return SOCKET_ERRNO(); + nb_read += this_nread; + left -= (size_t)this_nread; + } + + if (nread) { + *nread = nb_read; + } + skt->rbytes += nb_read; + + return ret; +} +int srs_hijack_io_write(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nwrite) +{ + SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; + + int ret = ERROR_SUCCESS; + + ssize_t nb_write = ::send(skt->fd, (char*)buf, size, 0); + + if (nwrite) { + *nwrite = nb_write; + } + + if (nb_write <= 0) { + // @see https://github.com/ossrs/srs/issues/200 + if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) { + return ERROR_SOCKET_TIMEOUT; } - skt->rtm = tm; - - return ERROR_SUCCESS; - } - int64_t srs_hijack_io_get_recv_timeout(srs_hijack_io_t ctx) - { - SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; - return skt->rtm; - } - int64_t srs_hijack_io_get_recv_bytes(srs_hijack_io_t ctx) - { - SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; - return skt->rbytes; - } - int srs_hijack_io_set_send_timeout(srs_hijack_io_t ctx, int64_t tm) - { - SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; - - // The default for this option is zero, - // which indicates that a receive operation shall not time out. - int32_t sec = 0; - int32_t usec = 0; - - if (tm != SRS_CONSTS_NO_TMMS) { - sec = (int32_t)(tm / 1000); - usec = (int32_t)((tm % 1000)*1000); - } - - struct timeval tv = { sec , usec }; - if (setsockopt(skt->fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) == -1) { - return SOCKET_ERRNO(); - } - - skt->stm = tm; - - return ERROR_SUCCESS; - } - int64_t srs_hijack_io_get_send_timeout(srs_hijack_io_t ctx) - { - SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; - return skt->stm; - } - int64_t srs_hijack_io_get_send_bytes(srs_hijack_io_t ctx) - { - SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; - return skt->sbytes; - } - int srs_hijack_io_writev(srs_hijack_io_t ctx, const iovec *iov, int iov_size, ssize_t* nwrite) - { - SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; - - int ret = ERROR_SUCCESS; - - ssize_t nb_write = ::writev(skt->fd, iov, iov_size); - - if (nwrite) { - *nwrite = nb_write; - } - - // On success, the readv() function returns the number of bytes read; - // the writev() function returns the number of bytes written. On error, -1 is - // returned, and errno is set appropriately. - if (nb_write <= 0) { - // @see https://github.com/ossrs/srs/issues/200 - if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) { - return ERROR_SOCKET_TIMEOUT; - } - - return ERROR_SOCKET_WRITE; - } - - skt->sbytes += nb_write; - - return ret; - } - int srs_hijack_io_is_never_timeout(srs_hijack_io_t ctx, int64_t tm) - { - return tm == SRS_CONSTS_NO_TMMS; - } - int srs_hijack_io_read_fully(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nread) - { - SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; - - int ret = ERROR_SUCCESS; - - size_t left = size; - ssize_t nb_read = 0; - - while (left > 0) { - char* this_buf = (char*)buf + nb_read; - ssize_t this_nread; - - if ((ret = srs_hijack_io_read(ctx, this_buf, left, &this_nread)) != ERROR_SUCCESS) { - return ret; - } - - nb_read += this_nread; - left -= (size_t)this_nread; - } - - if (nread) { - *nread = nb_read; - } - skt->rbytes += nb_read; - - return ret; - } - int srs_hijack_io_write(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nwrite) - { - SrsBlockSyncSocket* skt = (SrsBlockSyncSocket*)ctx; - - int ret = ERROR_SUCCESS; - - ssize_t nb_write = ::send(skt->fd, (char*)buf, size, 0); - - if (nwrite) { - *nwrite = nb_write; - } - - if (nb_write <= 0) { - // @see https://github.com/ossrs/srs/issues/200 - if (nb_write < 0 && SOCKET_ERRNO() == SOCKET_ETIME) { - return ERROR_SOCKET_TIMEOUT; - } - - return ERROR_SOCKET_WRITE; - } - - skt->sbytes += nb_write; - - return ret; + return ERROR_SOCKET_WRITE; } + + skt->sbytes += nb_write; + + return ret; +} #endif SimpleSocketStream::SimpleSocketStream() diff --git a/trunk/src/libs/srs_lib_simple_socket.hpp b/trunk/src/libs/srs_lib_simple_socket.hpp index 96a42b9fd..4a9a3a961 100644 --- a/trunk/src/libs/srs_lib_simple_socket.hpp +++ b/trunk/src/libs/srs_lib_simple_socket.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_LIB_SIMPLE_SOCKET_HPP #define SRS_LIB_SIMPLE_SOCKET_HPP -/* -#include -*/ - #include #include @@ -35,13 +31,13 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 #ifndef _WIN32 - #define SOCKET int +#define SOCKET int #endif /** -* simple socket stream, -* use tcp socket, sync block mode, for client like srs-librtmp. -*/ + * simple socket stream, + * use tcp socket, sync block mode, for client like srs-librtmp. + */ class SimpleSocketStream : public ISrsProtocolReaderWriter { private: @@ -53,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 + // ISrsReader public: virtual int read(void* buf, size_t size, ssize_t* nread); -// ISrsProtocolReader + // ISrsProtocolReader public: virtual void set_recv_timeout(int64_t tm); virtual int64_t get_recv_timeout(); virtual int64_t get_recv_bytes(); -// ISrsProtocolWriter + // ISrsProtocolWriter public: virtual void set_send_timeout(int64_t tm); virtual int64_t get_send_timeout(); virtual int64_t get_send_bytes(); virtual int writev(const iovec *iov, int iov_size, ssize_t* nwrite); -// ISrsProtocolReaderWriter + // ISrsProtocolReaderWriter public: virtual bool is_never_timeout(int64_t tm); virtual int read_fully(void* buf, size_t size, ssize_t* nread); diff --git a/trunk/src/libs/srs_librtmp.cpp b/trunk/src/libs/srs_librtmp.cpp index 9223f3bd5..d417ea589 100644 --- a/trunk/src/libs/srs_librtmp.cpp +++ b/trunk/src/libs/srs_librtmp.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -59,8 +59,8 @@ ISrsThreadContext* _srs_context = new ISrsThreadContext(); #define SRS_SOCKET_DEFAULT_TMMS (30 * 1000) /** -* export runtime context. -*/ + * export runtime context. + */ struct Context { // The original RTMP url. @@ -82,7 +82,7 @@ struct Context srs_url_schema schema; // The server information, response by connect app. SrsServerInfo si; - + // The extra request object for connect to server, NULL to ignore. SrsRequest* req; @@ -99,8 +99,8 @@ struct Context // the remux raw codec. SrsRawH264Stream avc_raw; SrsRawAacStream aac_raw; - - // for h264 raw stream, + + // for h264 raw stream, // @see: https://github.com/ossrs/srs/issues/66#issuecomment-62240521 SrsBuffer h264_raw_stream; // about SPS, @see: 7.3.2.1.1, ISO_IEC_14496-10-AVC-2012.pdf, page 62 @@ -153,353 +153,353 @@ struct Context // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 #ifdef _WIN32 - int gettimeofday(struct timeval* tv, struct timezone* tz) - { - time_t clock; - struct tm tm; - SYSTEMTIME win_time; +int gettimeofday(struct timeval* tv, struct timezone* tz) +{ + time_t clock; + struct tm tm; + SYSTEMTIME win_time; - GetLocalTime(&win_time); + GetLocalTime(&win_time); - tm.tm_year = win_time.wYear - 1900; - tm.tm_mon = win_time.wMonth - 1; - tm.tm_mday = win_time.wDay; - tm.tm_hour = win_time.wHour; - tm.tm_min = win_time.wMinute; - tm.tm_sec = win_time.wSecond; - tm.tm_isdst = -1; + tm.tm_year = win_time.wYear - 1900; + tm.tm_mon = win_time.wMonth - 1; + tm.tm_mday = win_time.wDay; + tm.tm_hour = win_time.wHour; + tm.tm_min = win_time.wMinute; + tm.tm_sec = win_time.wSecond; + tm.tm_isdst = -1; - clock = mktime(&tm); + clock = mktime(&tm); - tv->tv_sec = (long)clock; - tv->tv_usec = win_time.wMilliseconds * 1000; + tv->tv_sec = (long)clock; + tv->tv_usec = win_time.wMilliseconds * 1000; - return 0; + return 0; +} + +int socket_setup() +{ + WORD wVersionRequested; + WSADATA wsaData; + int err; + + /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ + wVersionRequested = MAKEWORD(2, 2); + + err = WSAStartup(wVersionRequested, &wsaData); + if (err != 0) { + /* Tell the user that we could not find a usable */ + /* Winsock DLL. */ + //printf("WSAStartup failed with error: %d\n", err); + return -1; } - - int socket_setup() - { - WORD wVersionRequested; - WSADATA wsaData; - int err; - - /* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */ - wVersionRequested = MAKEWORD(2, 2); - - err = WSAStartup(wVersionRequested, &wsaData); - if (err != 0) { - /* Tell the user that we could not find a usable */ - /* Winsock DLL. */ - //printf("WSAStartup failed with error: %d\n", err); - return -1; + return 0; +} + +int socket_cleanup() +{ + WSACleanup(); + return 0; +} + +pid_t getpid(void) +{ + return (pid_t)GetCurrentProcessId(); +} + +int usleep(useconds_t usec) +{ + Sleep((DWORD)(usec / 1000)); + return 0; +} + +ssize_t writev(int fd, const struct iovec *iov, int iovcnt) +{ + ssize_t nwrite = 0; + for (int i = 0; i < iovcnt; i++) { + const struct iovec* current = iov + i; + + int nsent = ::send(fd, (char*)current->iov_base, current->iov_len, 0); + if (nsent < 0) { + return nsent; } - return 0; - } - - int socket_cleanup() - { - WSACleanup(); - return 0; - } - - pid_t getpid(void) - { - return (pid_t)GetCurrentProcessId(); - } - - int usleep(useconds_t usec) - { - Sleep((DWORD)(usec / 1000)); - return 0; - } - - ssize_t writev(int fd, const struct iovec *iov, int iovcnt) - { - ssize_t nwrite = 0; - for (int i = 0; i < iovcnt; i++) { - const struct iovec* current = iov + i; - - int nsent = ::send(fd, (char*)current->iov_base, current->iov_len, 0); - if (nsent < 0) { - return nsent; - } - - nwrite += nsent; - if (nsent == 0) { - return nwrite; - } + + nwrite += nsent; + if (nsent == 0) { + return nwrite; + } + } + return nwrite; +} + +//////////////////////// strlcpy.c (modified) ////////////////////////// + +/* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ + +/*- + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +//#include // **** +//#include // **** +// __FBSDID("$FreeBSD: stable/9/sys/libkern/strlcpy.c 243811 2012-12-03 18:08:44Z delphij $"); // **** + +// #include // **** +// #include // **** + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ + +//#define __restrict // **** + +std::size_t strlcpy(char * __restrict dst, const char * __restrict src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0) { + while (--n != 0) { + if ((*d++ = *s++) == '\0') + break; } - return nwrite; } - //////////////////////// strlcpy.c (modified) ////////////////////////// - - /* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ - - /*- - * Copyright (c) 1998 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - - //#include // **** - //#include // **** - // __FBSDID("$FreeBSD: stable/9/sys/libkern/strlcpy.c 243811 2012-12-03 18:08:44Z delphij $"); // **** - - // #include // **** - // #include // **** - - /* - * Copy src to string dst of size siz. At most siz-1 characters - * will be copied. Always NUL terminates (unless siz == 0). - * Returns strlen(src); if retval >= siz, truncation occurred. - */ - - //#define __restrict // **** - - std::size_t strlcpy(char * __restrict dst, const char * __restrict src, size_t siz) - { - char *d = dst; - const char *s = src; - size_t n = siz; - - /* Copy as many bytes as will fit */ - if (n != 0) { - while (--n != 0) { - if ((*d++ = *s++) == '\0') - break; - } - } - - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) { - if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ - while (*s++) - ; - } - - return(s - src - 1); /* count does not include NUL */ + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; } - // http://www.cplusplus.com/forum/general/141779///////////////////////// inet_ntop.c (modified) ////////////////////////// - /* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1996-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - - // #if defined(LIBC_SCCS) && !defined(lint) // **** - //static const char rcsid[] = "$Id: inet_ntop.c,v 1.3.18.2 2005/11/03 23:02:22 marka Exp $"; - // #endif /* LIBC_SCCS and not lint */ // **** - // #include // **** - // __FBSDID("$FreeBSD: stable/9/sys/libkern/inet_ntop.c 213103 2010-09-24 15:01:45Z attilio $"); // **** - - //#define _WIN32_WINNT _WIN32_WINNT_WIN8 // **** - //#include // **** - #pragma comment(lib, "Ws2_32.lib") // **** - //#include // **** - - // #include // **** - // #include // **** - // #include // **** - - // #include // **** - - /*% - * WARNING: Don't even consider trying to compile this on a system where - * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. - */ - - static char *inet_ntop4(const u_char *src, char *dst, socklen_t size); - static char *inet_ntop6(const u_char *src, char *dst, socklen_t size); - - /* char * - * inet_ntop(af, src, dst, size) - * convert a network format address to presentation format. - * return: - * pointer to presentation format address (`dst'), or NULL (see errno). - * author: - * Paul Vixie, 1996. - */ - const char* inet_ntop(int af, const void *src, char *dst, socklen_t size) - { - switch (af) { + return(s - src - 1); /* count does not include NUL */ +} + +// http://www.cplusplus.com/forum/general/141779///////////////////////// inet_ntop.c (modified) ////////////////////////// +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1996-1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +// #if defined(LIBC_SCCS) && !defined(lint) // **** +//static const char rcsid[] = "$Id: inet_ntop.c,v 1.3.18.2 2005/11/03 23:02:22 marka Exp $"; +// #endif /* LIBC_SCCS and not lint */ // **** +// #include // **** +// __FBSDID("$FreeBSD: stable/9/sys/libkern/inet_ntop.c 213103 2010-09-24 15:01:45Z attilio $"); // **** + +//#define _WIN32_WINNT _WIN32_WINNT_WIN8 // **** +//#include // **** +#pragma comment(lib, "Ws2_32.lib") // **** +//#include // **** + +// #include // **** +// #include // **** +// #include // **** + +// #include // **** + +/*% + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static char *inet_ntop4(const u_char *src, char *dst, socklen_t size); +static char *inet_ntop6(const u_char *src, char *dst, socklen_t size); + +/* char * + * inet_ntop(af, src, dst, size) + * convert a network format address to presentation format. + * return: + * pointer to presentation format address (`dst'), or NULL (see errno). + * author: + * Paul Vixie, 1996. + */ +const char* inet_ntop(int af, const void *src, char *dst, socklen_t size) +{ + switch (af) { case AF_INET: return (inet_ntop4( (unsigned char*)src, (char*)dst, size)); // **** - #ifdef AF_INET6 - #error "IPv6 not supported" - //case AF_INET6: - // return (char*)(inet_ntop6( (unsigned char*)src, (char*)dst, size)); // **** - #endif +#ifdef AF_INET6 +#error "IPv6 not supported" + //case AF_INET6: + // return (char*)(inet_ntop6( (unsigned char*)src, (char*)dst, size)); // **** +#endif default: // return (NULL); // **** return 0 ; // **** - } - /* NOTREACHED */ } + /* NOTREACHED */ +} + +/* const char * + * inet_ntop4(src, dst, size) + * format an IPv4 address + * return: + * `dst' (as a const) + * notes: + * (1) uses no statics + * (2) takes a u_char* not an in_addr as input + * author: + * Paul Vixie, 1996. + */ +static char * inet_ntop4(const u_char *src, char *dst, socklen_t size) +{ + static const char fmt[128] = "%u.%u.%u.%u"; + char tmp[sizeof "255.255.255.255"]; + int l; - /* const char * - * inet_ntop4(src, dst, size) - * format an IPv4 address - * return: - * `dst' (as a const) - * notes: - * (1) uses no statics - * (2) takes a u_char* not an in_addr as input - * author: - * Paul Vixie, 1996. - */ - static char * inet_ntop4(const u_char *src, char *dst, socklen_t size) - { - static const char fmt[128] = "%u.%u.%u.%u"; - char tmp[sizeof "255.255.255.255"]; - int l; - - l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); // **** - if (l <= 0 || (socklen_t) l >= size) { - return (NULL); - } - strlcpy(dst, tmp, size); - return (dst); + l = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); // **** + if (l <= 0 || (socklen_t) l >= size) { + return (NULL); } - - /* const char * - * inet_ntop6(src, dst, size) - * convert IPv6 binary address into presentation (printable) format - * author: - * Paul Vixie, 1996. + strlcpy(dst, tmp, size); + return (dst); +} + +/* const char * + * inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. + */ +static char * inet_ntop6(const u_char *src, char *dst, socklen_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. */ - static char * inet_ntop6(const u_char *src, char *dst, socklen_t size) - { - /* - * Note that int32_t and int16_t need only be "at least" large enough - * to contain a value of the specified size. On some systems, like - * Crays, there is no such thing as an integer variable with 16 bits. - * Keep this in mind if you think this function should have been coded - * to use pointer overlays. All the world's not a VAX. - */ - char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; - struct { int base, len; } best, cur; - #define NS_IN6ADDRSZ 16 - #define NS_INT16SZ 2 - u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; - int i; + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; + struct { int base, len; } best, cur; +#define NS_IN6ADDRSZ 16 +#define NS_INT16SZ 2 + u_int words[NS_IN6ADDRSZ / NS_INT16SZ]; + int i; - /* - * Preprocess: - * Copy the input (bytewise) array into a wordwise array. - * Find the longest run of 0x00's in src[] for :: shorthanding. - */ - memset(words, '\0', sizeof words); - for (i = 0; i < NS_IN6ADDRSZ; i++) - words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < NS_IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + best.len = 0; + cur.base = -1; + cur.len = 0; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) best.base = -1; - best.len = 0; - cur.base = -1; - cur.len = 0; - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { - if (words[i] == 0) { - if (cur.base == -1) - cur.base = i, cur.len = 1; - else - cur.len++; - } else { - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) - best = cur; - cur.base = -1; - } - } - } - if (cur.base != -1) { - if (best.base == -1 || cur.len > best.len) - best = cur; - } - if (best.base != -1 && best.len < 2) - best.base = -1; - /* - * Format the result. - */ - tp = tmp; - for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { - /* Are we inside the best run of 0x00's? */ - if (best.base != -1 && i >= best.base && - i < (best.base + best.len)) { - if (i == best.base) - *tp++ = ':'; - continue; - } - /* Are we following an initial run of 0x00s or any real hex? */ - if (i != 0) + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) *tp++ = ':'; - /* Is this address an encapsulated IPv4? */ - if (i == 6 && best.base == 0 && (best.len == 6 || - (best.len == 7 && words[7] != 0x0001) || - (best.len == 5 && words[5] == 0xffff))) { - if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) - return (NULL); - tp += strlen(tp); - break; - } - tp += std::sprintf(tp, "%x", words[i]); // **** + continue; } - /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && (best.base + best.len) == - (NS_IN6ADDRSZ / NS_INT16SZ)) + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) *tp++ = ':'; - *tp++ = '\0'; - - /* - * Check for overflow, copy, and we're done. - */ - if ((socklen_t)(tp - tmp) > size) { - return (NULL); + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && (best.len == 6 || + (best.len == 7 && words[7] != 0x0001) || + (best.len == 5 && words[5] == 0xffff))) { + if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) + return (NULL); + tp += strlen(tp); + break; } - strcpy(dst, tmp); - return (dst); + tp += std::sprintf(tp, "%x", words[i]); // **** } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == + (NS_IN6ADDRSZ / NS_INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((socklen_t)(tp - tmp) > size) { + return (NULL); + } + strcpy(dst, tmp); + return (dst); +} #endif -int srs_librtmp_context_parse_uri(Context* context) +int srs_librtmp_context_parse_uri(Context* context) { int ret = ERROR_SUCCESS; std::string schema; srs_parse_rtmp_url(context->url, context->tcUrl, context->stream); - + // when connect, we only need to parse the tcUrl - srs_discovery_tc_url(context->tcUrl, - schema, context->host, context->vhost, context->app, context->port, - context->param); + srs_discovery_tc_url(context->tcUrl, + schema, context->host, context->vhost, context->app, context->port, + context->param); return ret; } -int srs_librtmp_context_resolve_host(Context* context) +int srs_librtmp_context_resolve_host(Context* context) { int ret = ERROR_SUCCESS; @@ -512,7 +512,7 @@ int srs_librtmp_context_resolve_host(Context* context) return ret; } -int srs_librtmp_context_connect(Context* context) +int srs_librtmp_context_connect(Context* context) { int ret = ERROR_SUCCESS; @@ -529,2308 +529,2296 @@ int srs_librtmp_context_connect(Context* context) #ifdef __cplusplus extern "C"{ #endif - -int srs_version_major() -{ - return VERSION_MAJOR; -} - -int srs_version_minor() -{ - return VERSION_MINOR; -} - -int srs_version_revision() -{ - return VERSION_REVISION; -} - -srs_rtmp_t srs_rtmp_create(const char* url) -{ - int ret = ERROR_SUCCESS; - Context* context = new Context(); - context->url = url; - - // create socket - srs_freep(context->skt); - context->skt = new SimpleSocketStream(); - - if ((ret = context->skt->create_socket(context)) != ERROR_SUCCESS) { - srs_human_error("Create socket failed, ret=%d", ret); + int srs_version_major() + { + return VERSION_MAJOR; + } + + int srs_version_minor() + { + return VERSION_MINOR; + } + + int srs_version_revision() + { + return VERSION_REVISION; + } + + srs_rtmp_t srs_rtmp_create(const char* url) + { + int ret = ERROR_SUCCESS; - // free the context and return NULL - srs_freep(context); - return NULL; - } - - return context; -} - -int srs_rtmp_set_timeout(srs_rtmp_t rtmp, int recv_timeout_ms, int send_timeout_ms) -{ - int ret = ERROR_SUCCESS; - - if (!rtmp) { - return ret; - } - - Context* context = (Context*)rtmp; - - context->stimeout = send_timeout_ms; - context->rtimeout = recv_timeout_ms; - - context->skt->set_recv_timeout(context->rtimeout); - context->skt->set_send_timeout(context->stimeout); - - return ret; -} - -void srs_rtmp_destroy(srs_rtmp_t rtmp) -{ - if (!rtmp) { - return; - } - - Context* context = (Context*)rtmp; - - srs_freep(context); -} - -int srs_rtmp_handshake(srs_rtmp_t rtmp) -{ - int ret = ERROR_SUCCESS; - - if ((ret = srs_rtmp_dns_resolve(rtmp)) != ERROR_SUCCESS) { - return ret; - } - - if ((ret = srs_rtmp_connect_server(rtmp)) != ERROR_SUCCESS) { - return ret; - } - - if ((ret = srs_rtmp_do_simple_handshake(rtmp)) != ERROR_SUCCESS) { - return ret; - } - - return ret; -} - -int srs_rtmp_dns_resolve(srs_rtmp_t rtmp) -{ - int ret = ERROR_SUCCESS; - - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - - // parse uri - if ((ret = srs_librtmp_context_parse_uri(context)) != ERROR_SUCCESS) { - return ret; - } - // resolve host - if ((ret = srs_librtmp_context_resolve_host(context)) != ERROR_SUCCESS) { - return ret; - } - - return ret; -} - -int srs_rtmp_connect_server(srs_rtmp_t rtmp) -{ - int ret = ERROR_SUCCESS; - - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - - // set timeout if user not set. - if (context->stimeout == SRS_CONSTS_NO_TMMS) { - context->stimeout = SRS_SOCKET_DEFAULT_TMMS; - context->skt->set_send_timeout(context->stimeout); - } - if (context->rtimeout == SRS_CONSTS_NO_TMMS) { - context->rtimeout = SRS_SOCKET_DEFAULT_TMMS; - context->skt->set_recv_timeout(context->rtimeout); - } - - if ((ret = srs_librtmp_context_connect(context)) != ERROR_SUCCESS) { - return ret; - } - - return ret; -} - -int srs_rtmp_do_complex_handshake(srs_rtmp_t rtmp) -{ -#ifndef SRS_AUTO_SSL - // complex handshake requires ssl - return ERROR_RTMP_HS_SSL_REQUIRE; -#endif - - int ret = ERROR_SUCCESS; - - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - - srs_assert(context->skt != NULL); - - // simple handshake - srs_freep(context->rtmp); - context->rtmp = new SrsRtmpClient(context->skt); - - if ((ret = context->rtmp->complex_handshake()) != ERROR_SUCCESS) { - return ret; - } - - return ret; -} - -int srs_rtmp_do_simple_handshake(srs_rtmp_t rtmp) -{ - int ret = ERROR_SUCCESS; - - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - - srs_assert(context->skt != NULL); - - // simple handshake - srs_freep(context->rtmp); - context->rtmp = new SrsRtmpClient(context->skt); - - if ((ret = context->rtmp->simple_handshake()) != ERROR_SUCCESS) { - return ret; - } - - return ret; -} - -int srs_rtmp_set_connect_args(srs_rtmp_t rtmp, - const char* tcUrl, const char* swfUrl, const char* pageUrl, srs_amf0_t args -) { - int ret = ERROR_SUCCESS; - - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - - srs_freep(context->req); - context->req = new SrsRequest(); - - if (args) { - context->req->args = (SrsAmf0Object*)args; - } - if (tcUrl) { - context->req->tcUrl = tcUrl; - } - if (swfUrl) { - context->req->swfUrl = swfUrl; - } - if (pageUrl) { - context->req->pageUrl = pageUrl; - } - - return ret; -} - -int srs_rtmp_set_schema(srs_rtmp_t rtmp, enum srs_url_schema schema) -{ - int ret = ERROR_SUCCESS; - - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - - context->schema = schema; - - return ret; -} - -int srs_rtmp_connect_app(srs_rtmp_t rtmp) -{ - int ret = ERROR_SUCCESS; - - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - - string tcUrl; - switch(context->schema) { - case srs_url_schema_normal: - tcUrl=srs_generate_normal_tc_url(context->ip, context->vhost, context->app, context->port, context->param); - break; - case srs_url_schema_via: - tcUrl=srs_generate_via_tc_url(context->ip, context->vhost, context->app, context->port, context->param); - break; - case srs_url_schema_vis: - case srs_url_schema_vis2: - tcUrl=srs_generate_vis_tc_url(context->ip, context->vhost, context->app, context->port, context->param); - break; - default: - break; - } - - Context* c = context; - if ((ret = context->rtmp->connect_app(c->app, tcUrl, c->req, true, &c->si)) != ERROR_SUCCESS) { - return ret; - } - - return ret; -} - -int srs_rtmp_get_server_id(srs_rtmp_t rtmp, char** ip, int* pid, int* cid) -{ - int ret = ERROR_SUCCESS; - - Context* context = (Context*)rtmp; - *pid = context->si.pid; - *cid = context->si.cid; - *ip = context->si.ip.empty()? NULL:(char*)context->si.ip.c_str(); - - return ret; -} - -int srs_rtmp_get_server_sig(srs_rtmp_t rtmp, char** sig) -{ - int ret = ERROR_SUCCESS; - - Context* context = (Context*)rtmp; - *sig = context->si.sig.empty()? NULL:(char*)context->si.sig.c_str(); - - return ret; -} - -int srs_rtmp_get_server_version(srs_rtmp_t rtmp, int* major, int* minor, int* revision, int* build) -{ - int ret = ERROR_SUCCESS; - - Context* context = (Context*)rtmp; - *major = context->si.major; - *minor = context->si.minor; - *revision = context->si.revision; - *build = context->si.build; - - return ret; -} - -int srs_rtmp_play_stream(srs_rtmp_t rtmp) -{ - int ret = ERROR_SUCCESS; - - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - - if ((ret = context->rtmp->create_stream(context->stream_id)) != ERROR_SUCCESS) { - return ret; - } - if ((ret = context->rtmp->play(context->stream, context->stream_id)) != ERROR_SUCCESS) { - return ret; - } - - return ret; -} - -int srs_rtmp_publish_stream(srs_rtmp_t rtmp) -{ - int ret = ERROR_SUCCESS; - - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - - if ((ret = context->rtmp->fmle_publish(context->stream, context->stream_id)) != ERROR_SUCCESS) { - return ret; - } - - return ret; -} - -int srs_rtmp_bandwidth_check(srs_rtmp_t rtmp, - int64_t* start_time, int64_t* end_time, - int* play_kbps, int* publish_kbps, - int* play_bytes, int* publish_bytes, - int* play_duration, int* publish_duration -) { - *start_time = 0; - *end_time = 0; - *play_kbps = 0; - *publish_kbps = 0; - *play_bytes = 0; - *publish_bytes = 0; - *play_duration = 0; - *publish_duration = 0; - - int ret = ERROR_SUCCESS; - - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - - SrsBandwidthClient client; - - if ((ret = client.initialize(context->rtmp)) != ERROR_SUCCESS) { - return ret; - } - - if ((ret = client.bandwidth_check( - start_time, end_time, play_kbps, publish_kbps, - play_bytes, publish_bytes, play_duration, publish_duration)) != ERROR_SUCCESS - ) { - return ret; - } - - return ret; -} - - -int srs_rtmp_on_aggregate(Context* context, SrsCommonMessage* msg) -{ - int ret = ERROR_SUCCESS; - - SrsBuffer aggregate_stream; - SrsBuffer* stream = &aggregate_stream; - if ((ret = stream->initialize(msg->payload, msg->size)) != ERROR_SUCCESS) { - return ret; - } - - // the aggregate message always use abs time. - int delta = -1; - - while (!stream->empty()) { - if (!stream->require(1)) { - ret = ERROR_RTMP_AGGREGATE; - srs_error("invalid aggregate message type. ret=%d", ret); - return ret; - } - int8_t type = stream->read_1bytes(); + Context* context = new Context(); + context->url = url; - if (!stream->require(3)) { - ret = ERROR_RTMP_AGGREGATE; - srs_error("invalid aggregate message size. ret=%d", ret); - return ret; - } - int32_t data_size = stream->read_3bytes(); + // create socket + srs_freep(context->skt); + context->skt = new SimpleSocketStream(); - if (data_size < 0) { - ret = ERROR_RTMP_AGGREGATE; - srs_error("invalid aggregate message size(negative). ret=%d", ret); - return ret; - } - - if (!stream->require(3)) { - ret = ERROR_RTMP_AGGREGATE; - srs_error("invalid aggregate message time. ret=%d", ret); - return ret; - } - int32_t timestamp = stream->read_3bytes(); - - if (!stream->require(1)) { - ret = ERROR_RTMP_AGGREGATE; - srs_error("invalid aggregate message time(high). ret=%d", ret); - return ret; - } - int32_t time_h = stream->read_1bytes(); - - timestamp |= time_h<<24; - timestamp &= 0x7FFFFFFF; - - // adjust abs timestamp in aggregate msg. - if (delta < 0) { - delta = (int)msg->header.timestamp - (int)timestamp; - } - timestamp += delta; - - if (!stream->require(3)) { - ret = ERROR_RTMP_AGGREGATE; - srs_error("invalid aggregate message stream_id. ret=%d", ret); - return ret; - } - int32_t stream_id = stream->read_3bytes(); - - if (data_size > 0 && !stream->require(data_size)) { - ret = ERROR_RTMP_AGGREGATE; - srs_error("invalid aggregate message data. ret=%d", ret); - return ret; - } - - // to common message. - SrsCommonMessage o; - - o.header.message_type = type; - o.header.payload_length = data_size; - o.header.timestamp_delta = timestamp; - o.header.timestamp = timestamp; - o.header.stream_id = stream_id; - o.header.perfer_cid = msg->header.perfer_cid; - - if (data_size > 0) { - o.size = data_size; - o.payload = new char[o.size]; - stream->read_bytes(o.payload, o.size); - } - - if (!stream->require(4)) { - ret = ERROR_RTMP_AGGREGATE; - srs_error("invalid aggregate message previous tag size. ret=%d", ret); - return ret; - } - stream->read_4bytes(); - - // process parsed message - SrsCommonMessage* parsed_msg = new SrsCommonMessage(); - parsed_msg->header = o.header; - parsed_msg->payload = o.payload; - parsed_msg->size = o.size; - o.payload = NULL; - context->msgs.push_back(parsed_msg); - } - - return ret; -} - -int srs_rtmp_go_packet(Context* context, SrsCommonMessage* msg, - char* type, uint32_t* timestamp, char** data, int* size, - bool* got_msg -) { - int ret = ERROR_SUCCESS; - - // generally we got a message. - *got_msg = true; - - if (msg->header.is_audio()) { - *type = SRS_RTMP_TYPE_AUDIO; - *timestamp = (uint32_t)msg->header.timestamp; - *data = (char*)msg->payload; - *size = (int)msg->size; - // detach bytes from packet. - msg->payload = NULL; - } else if (msg->header.is_video()) { - *type = SRS_RTMP_TYPE_VIDEO; - *timestamp = (uint32_t)msg->header.timestamp; - *data = (char*)msg->payload; - *size = (int)msg->size; - // detach bytes from packet. - msg->payload = NULL; - } else if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) { - *type = SRS_RTMP_TYPE_SCRIPT; - *data = (char*)msg->payload; - *size = (int)msg->size; - // detach bytes from packet. - msg->payload = NULL; - } else if (msg->header.is_aggregate()) { - if ((ret = srs_rtmp_on_aggregate(context, msg)) != ERROR_SUCCESS) { - return ret; - } - *got_msg = false; - } else { - *type = msg->header.message_type; - *data = (char*)msg->payload; - *size = (int)msg->size; - // detach bytes from packet. - msg->payload = NULL; - } - - return ret; -} - -int srs_rtmp_read_packet(srs_rtmp_t rtmp, char* type, uint32_t* timestamp, char** data, int* size) -{ - *type = 0; - *timestamp = 0; - *data = NULL; - *size = 0; - - int ret = ERROR_SUCCESS; - - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - - for (;;) { - SrsCommonMessage* msg = NULL; - - // read from cache first. - if (!context->msgs.empty()) { - std::vector::iterator it = context->msgs.begin(); - msg = *it; - context->msgs.erase(it); - } - - // read from protocol sdk. - if (!msg && (ret = context->rtmp->recv_message(&msg)) != ERROR_SUCCESS) { - return ret; - } - - // no msg, try again. - if (!msg) { - continue; - } - - SrsAutoFree(SrsCommonMessage, msg); - - // process the got packet, if nothing, try again. - bool got_msg; - if ((ret = srs_rtmp_go_packet(context, msg, type, timestamp, data, size, &got_msg)) != ERROR_SUCCESS) { - return ret; - } - - // got expected message. - if (got_msg) { - break; - } - } - - return ret; -} - -int srs_rtmp_write_packet(srs_rtmp_t rtmp, char type, uint32_t timestamp, char* data, int size) -{ - int ret = ERROR_SUCCESS; - - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - - SrsSharedPtrMessage* msg = NULL; - - if ((ret = srs_rtmp_create_msg(type, timestamp, data, size, context->stream_id, &msg)) != ERROR_SUCCESS) { - return ret; - } - - srs_assert(msg); - - // send out encoded msg. - if ((ret = context->rtmp->send_and_free_message(msg, context->stream_id)) != ERROR_SUCCESS) { - return ret; - } - - return ret; -} - -void srs_rtmp_free_packet(char* data) -{ - srs_freepa(data); -} - -srs_bool srs_rtmp_is_onMetaData(char type, char* data, int size) -{ - int ret = ERROR_SUCCESS; - - if (type != SRS_RTMP_TYPE_SCRIPT) { - return false; - } - - SrsBuffer stream; - if ((ret = stream.initialize(data, size)) != ERROR_SUCCESS) { - return false; - } - - std::string name; - if ((ret = srs_amf0_read_string(&stream, name)) != ERROR_SUCCESS) { - return false; - } - - if (name == SRS_CONSTS_RTMP_ON_METADATA) { - return true; - } - - if (name == SRS_CONSTS_RTMP_SET_DATAFRAME) { - return true; - } - - return false; -} - -/** -* directly write a audio frame. -*/ -int srs_write_audio_raw_frame(Context* context, - char* frame, int frame_size, SrsRawAacStreamCodec* codec, uint32_t timestamp -) { - int ret = ERROR_SUCCESS; - - char* data = NULL; - int size = 0; - if ((ret = context->aac_raw.mux_aac2flv(frame, frame_size, codec, timestamp, &data, &size)) != ERROR_SUCCESS) { - return ret; - } - - return srs_rtmp_write_packet(context, SRS_RTMP_TYPE_AUDIO, timestamp, data, size); -} - -/** -* write aac frame in adts. -*/ -int srs_write_aac_adts_frame(Context* context, - SrsRawAacStreamCodec* codec, char* frame, int frame_size, uint32_t timestamp -) { - int ret = ERROR_SUCCESS; - - // send out aac sequence header if not sent. - if (context->aac_specific_config.empty()) { - std::string sh; - if ((ret = context->aac_raw.mux_sequence_header(codec, sh)) != ERROR_SUCCESS) { - return ret; - } - context->aac_specific_config = sh; - - codec->aac_packet_type = 0; - - if ((ret = srs_write_audio_raw_frame(context, (char*)sh.data(), (int)sh.length(), codec, timestamp)) != ERROR_SUCCESS) { - return ret; - } - } - - codec->aac_packet_type = 1; - return srs_write_audio_raw_frame(context, frame, frame_size, codec, timestamp); -} - -/** -* write aac frames in adts. -*/ -int srs_write_aac_adts_frames(Context* context, - char sound_format, char sound_rate, char sound_size, char sound_type, - char* frames, int frames_size, uint32_t timestamp -) { - int ret = ERROR_SUCCESS; - - SrsBuffer* stream = &context->aac_raw_stream; - if ((ret = stream->initialize(frames, frames_size)) != ERROR_SUCCESS) { - return ret; - } - - while (!stream->empty()) { - char* frame = NULL; - int frame_size = 0; - SrsRawAacStreamCodec codec; - if ((ret = context->aac_raw.adts_demux(stream, &frame, &frame_size, codec)) != ERROR_SUCCESS) { - return ret; - } - - // override by user specified. - codec.sound_format = sound_format; - codec.sound_rate = sound_rate; - codec.sound_size = sound_size; - codec.sound_type = sound_type; - - if ((ret = srs_write_aac_adts_frame(context, &codec, frame, frame_size, timestamp)) != ERROR_SUCCESS) { - return ret; - } - } - - return ret; -} - -/** -* write audio raw frame to SRS. -*/ -int srs_audio_write_raw_frame(srs_rtmp_t rtmp, - char sound_format, char sound_rate, char sound_size, char sound_type, - char* frame, int frame_size, uint32_t timestamp -) { - int ret = ERROR_SUCCESS; - - Context* context = (Context*)rtmp; - srs_assert(context); - - if (sound_format == SrsAudioCodecIdAAC) { - // for aac, the frame must be ADTS format. - if (!srs_aac_is_adts(frame, frame_size)) { - return ERROR_AAC_REQUIRED_ADTS; - } - - // for aac, demux the ADTS to RTMP format. - return srs_write_aac_adts_frames(context, - sound_format, sound_rate, sound_size, sound_type, - frame, frame_size, timestamp); - } else { - // use codec info for aac. - SrsRawAacStreamCodec codec; - codec.sound_format = sound_format; - codec.sound_rate = sound_rate; - codec.sound_size = sound_size; - codec.sound_type = sound_type; - codec.aac_packet_type = 0; - - // for other data, directly write frame. - return srs_write_audio_raw_frame(context, frame, frame_size, &codec, timestamp); - } - - - return ret; -} - -/** -* whether aac raw data is in adts format, -* which bytes sequence matches '1111 1111 1111'B, that is 0xFFF. -*/ -srs_bool srs_aac_is_adts(char* aac_raw_data, int ac_raw_size) -{ - SrsBuffer stream; - if (stream.initialize(aac_raw_data, ac_raw_size) != ERROR_SUCCESS) { - return false; - } - - return srs_aac_startswith_adts(&stream); -} - -/** -* parse the adts header to get the frame size. -*/ -int srs_aac_adts_frame_size(char* aac_raw_data, int ac_raw_size) -{ - int size = -1; - - if (!srs_aac_is_adts(aac_raw_data, ac_raw_size)) { - return size; - } - - // adts always 7bytes. - if (ac_raw_size <= 7) { - return size; - } - - // last 2bits - int16_t ch3 = aac_raw_data[3]; - // whole 8bits - int16_t ch4 = aac_raw_data[4]; - // first 3bits - int16_t ch5 = aac_raw_data[5]; - - size = ((ch3 << 11) & 0x1800) | ((ch4 << 3) & 0x07f8) | ((ch5 >> 5) & 0x0007); - - return size; -} - -/** -* write h264 IPB-frame. -*/ -int srs_write_h264_ipb_frame(Context* context, - char* frame, int frame_size, uint32_t dts, uint32_t pts -) { - int ret = ERROR_SUCCESS; - - // when sps or pps not sent, ignore the packet. - // @see https://github.com/ossrs/srs/issues/203 - if (!context->h264_sps_pps_sent) { - return ERROR_H264_DROP_BEFORE_SPS_PPS; - } - - // 5bits, 7.3.1 NAL unit syntax, - // ISO_IEC_14496-10-AVC-2003.pdf, page 44. - // 5: I Frame, 1: P/B Frame - // @remark we already group sps/pps to sequence header frame; - // for I/P NALU, we send them in isolate frame, each NALU in a frame; - // for other NALU, for example, AUD/SEI, we just ignore them, because - // AUD used in annexb to split frame, while SEI generally we can ignore it. - // TODO: maybe we should group all NALUs split by AUD to a frame. - SrsAvcNaluType nut = (SrsAvcNaluType)(frame[0] & 0x1f); - if (nut != SrsAvcNaluTypeIDR && nut != SrsAvcNaluTypeNonIDR) { - return ret; - } - - // for IDR frame, the frame is keyframe. - SrsVideoAvcFrameType frame_type = SrsVideoAvcFrameTypeInterFrame; - if (nut == SrsAvcNaluTypeIDR) { - frame_type = SrsVideoAvcFrameTypeKeyFrame; - } - - std::string ibp; - if ((ret = context->avc_raw.mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) { - return ret; - } - - int8_t avc_packet_type = SrsVideoAvcFrameTraitNALU; - char* flv = NULL; - int nb_flv = 0; - if ((ret = context->avc_raw.mux_avc2flv(ibp, frame_type, avc_packet_type, dts, pts, &flv, &nb_flv)) != ERROR_SUCCESS) { - return ret; - } - - // the timestamp in rtmp message header is dts. - uint32_t timestamp = dts; - return srs_rtmp_write_packet(context, SRS_RTMP_TYPE_VIDEO, timestamp, flv, nb_flv); -} - -/** -* write the h264 sps/pps in context over RTMP. -*/ -int srs_write_h264_sps_pps(Context* context, uint32_t dts, uint32_t pts) -{ - int ret = ERROR_SUCCESS; - - // send when sps or pps changed. - if (!context->h264_sps_changed && !context->h264_pps_changed) { - return ret; - } - - // h264 raw to h264 packet. - std::string sh; - if ((ret = context->avc_raw.mux_sequence_header(context->h264_sps, context->h264_pps, dts, pts, sh)) != ERROR_SUCCESS) { - return ret; - } - - // h264 packet to flv packet. - int8_t frame_type = SrsVideoAvcFrameTypeKeyFrame; - int8_t avc_packet_type = SrsVideoAvcFrameTraitSequenceHeader; - char* flv = NULL; - int nb_flv = 0; - if ((ret = context->avc_raw.mux_avc2flv(sh, frame_type, avc_packet_type, dts, pts, &flv, &nb_flv)) != ERROR_SUCCESS) { - return ret; - } - - // reset sps and pps. - context->h264_sps_changed = false; - context->h264_pps_changed = false; - context->h264_sps_pps_sent = true; - - // the timestamp in rtmp message header is dts. - uint32_t timestamp = dts; - return srs_rtmp_write_packet(context, SRS_RTMP_TYPE_VIDEO, timestamp, flv, nb_flv); -} - -/** -* write h264 raw frame, maybe sps/pps/IPB-frame. -*/ -int srs_write_h264_raw_frame(Context* context, - char* frame, int frame_size, uint32_t dts, uint32_t pts -) { - int ret = ERROR_SUCCESS; - - // empty frame. - if (frame_size <= 0) { - return ret; - } - - // for sps - if (context->avc_raw.is_sps(frame, frame_size)) { - std::string sps; - if ((ret = context->avc_raw.sps_demux(frame, frame_size, sps)) != ERROR_SUCCESS) { - return ret; - } - - if (context->h264_sps == sps) { - return ERROR_H264_DUPLICATED_SPS; - } - context->h264_sps_changed = true; - context->h264_sps = sps; - - return ret; - } - - // for pps - if (context->avc_raw.is_pps(frame, frame_size)) { - std::string pps; - if ((ret = context->avc_raw.pps_demux(frame, frame_size, pps)) != ERROR_SUCCESS) { - return ret; - } - - if (context->h264_pps == pps) { - return ERROR_H264_DUPLICATED_PPS; - } - context->h264_pps_changed = true; - context->h264_pps = pps; - - return ret; - } - - // ignore others. - // 5bits, 7.3.1 NAL unit syntax, - // ISO_IEC_14496-10-AVC-2003.pdf, page 44. - // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame, 9: AUD - SrsAvcNaluType nut = (SrsAvcNaluType)(frame[0] & 0x1f); - if (nut != SrsAvcNaluTypeSPS && nut != SrsAvcNaluTypePPS - && nut != SrsAvcNaluTypeIDR && nut != SrsAvcNaluTypeNonIDR - && nut != SrsAvcNaluTypeAccessUnitDelimiter - ) { - return ret; - } - - // send pps+sps before ipb frames when sps/pps changed. - if ((ret = srs_write_h264_sps_pps(context, dts, pts)) != ERROR_SUCCESS) { - return ret; - } - - // ibp frame. - return srs_write_h264_ipb_frame(context, frame, frame_size, dts, pts); -} - -/** -* write h264 multiple frames, in annexb format. -*/ -int srs_h264_write_raw_frames(srs_rtmp_t rtmp, - char* frames, int frames_size, uint32_t dts, uint32_t pts -) { - int ret = ERROR_SUCCESS; - - srs_assert(frames != NULL); - srs_assert(frames_size > 0); - - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - - if ((ret = context->h264_raw_stream.initialize(frames, frames_size)) != ERROR_SUCCESS) { - return ret; - } - - // use the last error - // @see https://github.com/ossrs/srs/issues/203 - // @see https://github.com/ossrs/srs/issues/204 - int error_code_return = ret; - - // send each frame. - while (!context->h264_raw_stream.empty()) { - char* frame = NULL; - int frame_size = 0; - if ((ret = context->avc_raw.annexb_demux(&context->h264_raw_stream, &frame, &frame_size)) != ERROR_SUCCESS) { - return ret; - } - - // ignore invalid frame, - // atleast 1bytes for SPS to decode the type - if (frame_size <= 0) { - continue; - } - - // it may be return error, but we must process all packets. - if ((ret = srs_write_h264_raw_frame(context, frame, frame_size, dts, pts)) != ERROR_SUCCESS) { - error_code_return = ret; + if ((ret = context->skt->create_socket(context)) != ERROR_SUCCESS) { + srs_human_error("Create socket failed, ret=%d", ret); - // ignore known error, process all packets. - if (srs_h264_is_dvbsp_error(ret) - || srs_h264_is_duplicated_sps_error(ret) - || srs_h264_is_duplicated_pps_error(ret) - ) { + // free the context and return NULL + srs_freep(context); + return NULL; + } + + return context; + } + + int srs_rtmp_set_timeout(srs_rtmp_t rtmp, int recv_timeout_ms, int send_timeout_ms) + { + int ret = ERROR_SUCCESS; + + if (!rtmp) { + return ret; + } + + Context* context = (Context*)rtmp; + + context->stimeout = send_timeout_ms; + context->rtimeout = recv_timeout_ms; + + context->skt->set_recv_timeout(context->rtimeout); + context->skt->set_send_timeout(context->stimeout); + + return ret; + } + + void srs_rtmp_destroy(srs_rtmp_t rtmp) + { + if (!rtmp) { + return; + } + + Context* context = (Context*)rtmp; + + srs_freep(context); + } + + int srs_rtmp_handshake(srs_rtmp_t rtmp) + { + int ret = ERROR_SUCCESS; + + if ((ret = srs_rtmp_dns_resolve(rtmp)) != ERROR_SUCCESS) { + return ret; + } + + if ((ret = srs_rtmp_connect_server(rtmp)) != ERROR_SUCCESS) { + return ret; + } + + if ((ret = srs_rtmp_do_simple_handshake(rtmp)) != ERROR_SUCCESS) { + return ret; + } + + return ret; + } + + int srs_rtmp_dns_resolve(srs_rtmp_t rtmp) + { + int ret = ERROR_SUCCESS; + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + // parse uri + if ((ret = srs_librtmp_context_parse_uri(context)) != ERROR_SUCCESS) { + return ret; + } + // resolve host + if ((ret = srs_librtmp_context_resolve_host(context)) != ERROR_SUCCESS) { + return ret; + } + + return ret; + } + + int srs_rtmp_connect_server(srs_rtmp_t rtmp) + { + int ret = ERROR_SUCCESS; + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + // set timeout if user not set. + if (context->stimeout == SRS_CONSTS_NO_TMMS) { + context->stimeout = SRS_SOCKET_DEFAULT_TMMS; + context->skt->set_send_timeout(context->stimeout); + } + if (context->rtimeout == SRS_CONSTS_NO_TMMS) { + context->rtimeout = SRS_SOCKET_DEFAULT_TMMS; + context->skt->set_recv_timeout(context->rtimeout); + } + + if ((ret = srs_librtmp_context_connect(context)) != ERROR_SUCCESS) { + return ret; + } + + return ret; + } + + int srs_rtmp_do_complex_handshake(srs_rtmp_t rtmp) + { +#ifndef SRS_AUTO_SSL + // complex handshake requires ssl + return ERROR_RTMP_HS_SSL_REQUIRE; +#endif + + int ret = ERROR_SUCCESS; + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + srs_assert(context->skt != NULL); + + // simple handshake + srs_freep(context->rtmp); + context->rtmp = new SrsRtmpClient(context->skt); + + if ((ret = context->rtmp->complex_handshake()) != ERROR_SUCCESS) { + return ret; + } + + return ret; + } + + int srs_rtmp_do_simple_handshake(srs_rtmp_t rtmp) + { + int ret = ERROR_SUCCESS; + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + srs_assert(context->skt != NULL); + + // simple handshake + srs_freep(context->rtmp); + context->rtmp = new SrsRtmpClient(context->skt); + + if ((ret = context->rtmp->simple_handshake()) != ERROR_SUCCESS) { + return ret; + } + + return ret; + } + + int srs_rtmp_set_connect_args(srs_rtmp_t rtmp, + const char* tcUrl, const char* swfUrl, const char* pageUrl, srs_amf0_t args + ) { + int ret = ERROR_SUCCESS; + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + srs_freep(context->req); + context->req = new SrsRequest(); + + if (args) { + context->req->args = (SrsAmf0Object*)args; + } + if (tcUrl) { + context->req->tcUrl = tcUrl; + } + if (swfUrl) { + context->req->swfUrl = swfUrl; + } + if (pageUrl) { + context->req->pageUrl = pageUrl; + } + + return ret; + } + + int srs_rtmp_set_schema(srs_rtmp_t rtmp, enum srs_url_schema schema) + { + int ret = ERROR_SUCCESS; + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + context->schema = schema; + + return ret; + } + + int srs_rtmp_connect_app(srs_rtmp_t rtmp) + { + int ret = ERROR_SUCCESS; + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + string tcUrl; + switch(context->schema) { + case srs_url_schema_normal: + tcUrl=srs_generate_normal_tc_url(context->ip, context->vhost, context->app, context->port, context->param); + break; + case srs_url_schema_via: + tcUrl=srs_generate_via_tc_url(context->ip, context->vhost, context->app, context->port, context->param); + break; + case srs_url_schema_vis: + case srs_url_schema_vis2: + tcUrl=srs_generate_vis_tc_url(context->ip, context->vhost, context->app, context->port, context->param); + break; + default: + break; + } + + Context* c = context; + if ((ret = context->rtmp->connect_app(c->app, tcUrl, c->req, true, &c->si)) != ERROR_SUCCESS) { + return ret; + } + + return ret; + } + + int srs_rtmp_get_server_id(srs_rtmp_t rtmp, char** ip, int* pid, int* cid) + { + int ret = ERROR_SUCCESS; + + Context* context = (Context*)rtmp; + *pid = context->si.pid; + *cid = context->si.cid; + *ip = context->si.ip.empty()? NULL:(char*)context->si.ip.c_str(); + + return ret; + } + + int srs_rtmp_get_server_sig(srs_rtmp_t rtmp, char** sig) + { + int ret = ERROR_SUCCESS; + + Context* context = (Context*)rtmp; + *sig = context->si.sig.empty()? NULL:(char*)context->si.sig.c_str(); + + return ret; + } + + int srs_rtmp_get_server_version(srs_rtmp_t rtmp, int* major, int* minor, int* revision, int* build) + { + int ret = ERROR_SUCCESS; + + Context* context = (Context*)rtmp; + *major = context->si.major; + *minor = context->si.minor; + *revision = context->si.revision; + *build = context->si.build; + + return ret; + } + + int srs_rtmp_play_stream(srs_rtmp_t rtmp) + { + int ret = ERROR_SUCCESS; + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + if ((ret = context->rtmp->create_stream(context->stream_id)) != ERROR_SUCCESS) { + return ret; + } + if ((ret = context->rtmp->play(context->stream, context->stream_id)) != ERROR_SUCCESS) { + return ret; + } + + return ret; + } + + int srs_rtmp_publish_stream(srs_rtmp_t rtmp) + { + int ret = ERROR_SUCCESS; + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + if ((ret = context->rtmp->fmle_publish(context->stream, context->stream_id)) != ERROR_SUCCESS) { + return ret; + } + + return ret; + } + + int srs_rtmp_bandwidth_check(srs_rtmp_t rtmp, + int64_t* start_time, int64_t* end_time, + int* play_kbps, int* publish_kbps, + int* play_bytes, int* publish_bytes, + int* play_duration, int* publish_duration + ) { + *start_time = 0; + *end_time = 0; + *play_kbps = 0; + *publish_kbps = 0; + *play_bytes = 0; + *publish_bytes = 0; + *play_duration = 0; + *publish_duration = 0; + + int ret = ERROR_SUCCESS; + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + SrsBandwidthClient client; + + if ((ret = client.initialize(context->rtmp)) != ERROR_SUCCESS) { + return ret; + } + + if ((ret = client.bandwidth_check( + start_time, end_time, play_kbps, publish_kbps, + play_bytes, publish_bytes, play_duration, publish_duration)) != ERROR_SUCCESS + ) { + return ret; + } + + return ret; + } + + + int srs_rtmp_on_aggregate(Context* context, SrsCommonMessage* msg) + { + int ret = ERROR_SUCCESS; + + SrsBuffer aggregate_stream; + SrsBuffer* stream = &aggregate_stream; + if ((ret = stream->initialize(msg->payload, msg->size)) != ERROR_SUCCESS) { + return ret; + } + + // the aggregate message always use abs time. + int delta = -1; + + while (!stream->empty()) { + if (!stream->require(1)) { + ret = ERROR_RTMP_AGGREGATE; + srs_error("invalid aggregate message type. ret=%d", ret); + return ret; + } + int8_t type = stream->read_1bytes(); + + if (!stream->require(3)) { + ret = ERROR_RTMP_AGGREGATE; + srs_error("invalid aggregate message size. ret=%d", ret); + return ret; + } + int32_t data_size = stream->read_3bytes(); + + if (data_size < 0) { + ret = ERROR_RTMP_AGGREGATE; + srs_error("invalid aggregate message size(negative). ret=%d", ret); + return ret; + } + + if (!stream->require(3)) { + ret = ERROR_RTMP_AGGREGATE; + srs_error("invalid aggregate message time. ret=%d", ret); + return ret; + } + int32_t timestamp = stream->read_3bytes(); + + if (!stream->require(1)) { + ret = ERROR_RTMP_AGGREGATE; + srs_error("invalid aggregate message time(high). ret=%d", ret); + return ret; + } + int32_t time_h = stream->read_1bytes(); + + timestamp |= time_h<<24; + timestamp &= 0x7FFFFFFF; + + // adjust abs timestamp in aggregate msg. + if (delta < 0) { + delta = (int)msg->header.timestamp - (int)timestamp; + } + timestamp += delta; + + if (!stream->require(3)) { + ret = ERROR_RTMP_AGGREGATE; + srs_error("invalid aggregate message stream_id. ret=%d", ret); + return ret; + } + int32_t stream_id = stream->read_3bytes(); + + if (data_size > 0 && !stream->require(data_size)) { + ret = ERROR_RTMP_AGGREGATE; + srs_error("invalid aggregate message data. ret=%d", ret); + return ret; + } + + // to common message. + SrsCommonMessage o; + + o.header.message_type = type; + o.header.payload_length = data_size; + o.header.timestamp_delta = timestamp; + o.header.timestamp = timestamp; + o.header.stream_id = stream_id; + o.header.perfer_cid = msg->header.perfer_cid; + + if (data_size > 0) { + o.size = data_size; + o.payload = new char[o.size]; + stream->read_bytes(o.payload, o.size); + } + + if (!stream->require(4)) { + ret = ERROR_RTMP_AGGREGATE; + srs_error("invalid aggregate message previous tag size. ret=%d", ret); + return ret; + } + stream->read_4bytes(); + + // process parsed message + SrsCommonMessage* parsed_msg = new SrsCommonMessage(); + parsed_msg->header = o.header; + parsed_msg->payload = o.payload; + parsed_msg->size = o.size; + o.payload = NULL; + context->msgs.push_back(parsed_msg); + } + + return ret; + } + + int srs_rtmp_go_packet(Context* context, SrsCommonMessage* msg, + char* type, uint32_t* timestamp, char** data, int* size, + bool* got_msg + ) { + int ret = ERROR_SUCCESS; + + // generally we got a message. + *got_msg = true; + + if (msg->header.is_audio()) { + *type = SRS_RTMP_TYPE_AUDIO; + *timestamp = (uint32_t)msg->header.timestamp; + *data = (char*)msg->payload; + *size = (int)msg->size; + // detach bytes from packet. + msg->payload = NULL; + } else if (msg->header.is_video()) { + *type = SRS_RTMP_TYPE_VIDEO; + *timestamp = (uint32_t)msg->header.timestamp; + *data = (char*)msg->payload; + *size = (int)msg->size; + // detach bytes from packet. + msg->payload = NULL; + } else if (msg->header.is_amf0_data() || msg->header.is_amf3_data()) { + *type = SRS_RTMP_TYPE_SCRIPT; + *data = (char*)msg->payload; + *size = (int)msg->size; + // detach bytes from packet. + msg->payload = NULL; + } else if (msg->header.is_aggregate()) { + if ((ret = srs_rtmp_on_aggregate(context, msg)) != ERROR_SUCCESS) { + return ret; + } + *got_msg = false; + } else { + *type = msg->header.message_type; + *data = (char*)msg->payload; + *size = (int)msg->size; + // detach bytes from packet. + msg->payload = NULL; + } + + return ret; + } + + int srs_rtmp_read_packet(srs_rtmp_t rtmp, char* type, uint32_t* timestamp, char** data, int* size) + { + *type = 0; + *timestamp = 0; + *data = NULL; + *size = 0; + + int ret = ERROR_SUCCESS; + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + for (;;) { + SrsCommonMessage* msg = NULL; + + // read from cache first. + if (!context->msgs.empty()) { + std::vector::iterator it = context->msgs.begin(); + msg = *it; + context->msgs.erase(it); + } + + // read from protocol sdk. + if (!msg && (ret = context->rtmp->recv_message(&msg)) != ERROR_SUCCESS) { + return ret; + } + + // no msg, try again. + if (!msg) { continue; } - return ret; + SrsAutoFree(SrsCommonMessage, msg); + + // process the got packet, if nothing, try again. + bool got_msg; + if ((ret = srs_rtmp_go_packet(context, msg, type, timestamp, data, size, &got_msg)) != ERROR_SUCCESS) { + return ret; + } + + // got expected message. + if (got_msg) { + break; + } } + + return ret; } - return error_code_return; -} - -srs_bool srs_h264_is_dvbsp_error(int error_code) -{ - return error_code == ERROR_H264_DROP_BEFORE_SPS_PPS; -} - -srs_bool srs_h264_is_duplicated_sps_error(int error_code) -{ - return error_code == ERROR_H264_DUPLICATED_SPS; -} - -srs_bool srs_h264_is_duplicated_pps_error(int error_code) -{ - return error_code == ERROR_H264_DUPLICATED_PPS; -} - -srs_bool srs_h264_startswith_annexb(char* h264_raw_data, int h264_raw_size, int* pnb_start_code) -{ - SrsBuffer stream; - if (stream.initialize(h264_raw_data, h264_raw_size) != ERROR_SUCCESS) { + int srs_rtmp_write_packet(srs_rtmp_t rtmp, char type, uint32_t timestamp, char* data, int size) + { + int ret = ERROR_SUCCESS; + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + SrsSharedPtrMessage* msg = NULL; + + if ((ret = srs_rtmp_create_msg(type, timestamp, data, size, context->stream_id, &msg)) != ERROR_SUCCESS) { + return ret; + } + + srs_assert(msg); + + // send out encoded msg. + if ((ret = context->rtmp->send_and_free_message(msg, context->stream_id)) != ERROR_SUCCESS) { + return ret; + } + + return ret; + } + + void srs_rtmp_free_packet(char* data) + { + srs_freepa(data); + } + + srs_bool srs_rtmp_is_onMetaData(char type, char* data, int size) + { + int ret = ERROR_SUCCESS; + + if (type != SRS_RTMP_TYPE_SCRIPT) { + return false; + } + + SrsBuffer stream; + if ((ret = stream.initialize(data, size)) != ERROR_SUCCESS) { + return false; + } + + std::string name; + if ((ret = srs_amf0_read_string(&stream, name)) != ERROR_SUCCESS) { + return false; + } + + if (name == SRS_CONSTS_RTMP_ON_METADATA) { + return true; + } + + if (name == SRS_CONSTS_RTMP_SET_DATAFRAME) { + return true; + } + return false; } - return srs_avc_startswith_annexb(&stream, pnb_start_code); -} - -struct Mp4Context -{ - SrsFileReader reader; - SrsMp4Decoder dec; -}; - -srs_mp4_t srs_mp4_open_read(const char* file) -{ - int ret = ERROR_SUCCESS; - - Mp4Context* mp4 = new Mp4Context(); - - if ((ret = mp4->reader.open(file)) != ERROR_SUCCESS) { - srs_human_error("Open MP4 file failed, ret=%d", ret); + /** + * directly write a audio frame. + */ + int srs_write_audio_raw_frame(Context* context, char* frame, int frame_size, SrsRawAacStreamCodec* codec, uint32_t timestamp) + { + int ret = ERROR_SUCCESS; - srs_freep(mp4); - return NULL; + char* data = NULL; + int size = 0; + if ((ret = context->aac_raw.mux_aac2flv(frame, frame_size, codec, timestamp, &data, &size)) != ERROR_SUCCESS) { + return ret; + } + + return srs_rtmp_write_packet(context, SRS_RTMP_TYPE_AUDIO, timestamp, data, size); } - return mp4; -} - -void srs_mp4_close(srs_mp4_t mp4) -{ - Mp4Context* context = (Mp4Context*)mp4; - srs_freep(context); -} + /** + * write aac frame in adts. + */ + int srs_write_aac_adts_frame(Context* context, SrsRawAacStreamCodec* codec, char* frame, int frame_size, uint32_t timestamp) + { + int ret = ERROR_SUCCESS; + + // send out aac sequence header if not sent. + if (context->aac_specific_config.empty()) { + std::string sh; + if ((ret = context->aac_raw.mux_sequence_header(codec, sh)) != ERROR_SUCCESS) { + return ret; + } + context->aac_specific_config = sh; + + codec->aac_packet_type = 0; + + if ((ret = srs_write_audio_raw_frame(context, (char*)sh.data(), (int)sh.length(), codec, timestamp)) != ERROR_SUCCESS) { + return ret; + } + } + + codec->aac_packet_type = 1; + return srs_write_audio_raw_frame(context, frame, frame_size, codec, timestamp); + } -int srs_mp4_init_demuxer(srs_mp4_t mp4) -{ - int ret = ERROR_SUCCESS; - - Mp4Context* context = (Mp4Context*)mp4; - - if ((ret = context->dec.initialize(&context->reader)) != ERROR_SUCCESS) { + /** + * write aac frames in adts. + */ + int srs_write_aac_adts_frames(Context* context, char sound_format, char sound_rate, + char sound_size, char sound_type, char* frames, int frames_size, uint32_t timestamp + ) { + int ret = ERROR_SUCCESS; + + SrsBuffer* stream = &context->aac_raw_stream; + if ((ret = stream->initialize(frames, frames_size)) != ERROR_SUCCESS) { + return ret; + } + + while (!stream->empty()) { + char* frame = NULL; + int frame_size = 0; + SrsRawAacStreamCodec codec; + if ((ret = context->aac_raw.adts_demux(stream, &frame, &frame_size, codec)) != ERROR_SUCCESS) { + return ret; + } + + // override by user specified. + codec.sound_format = sound_format; + codec.sound_rate = sound_rate; + codec.sound_size = sound_size; + codec.sound_type = sound_type; + + if ((ret = srs_write_aac_adts_frame(context, &codec, frame, frame_size, timestamp)) != ERROR_SUCCESS) { + return ret; + } + } + return ret; } - return ret; -} - -int srs_mp4_read_sample(srs_mp4_t mp4, srs_mp4_sample_t* s) -{ - s->sample = NULL; - - int ret = ERROR_SUCCESS; - - Mp4Context* context = (Mp4Context*)mp4; - SrsMp4Decoder* dec = &context->dec; - - SrsMp4HandlerType ht = SrsMp4HandlerTypeForbidden; - if ((ret = dec->read_sample(&ht, &s->frame_type, &s->frame_trait, &s->dts, &s->pts, &s->sample, &s->nb_sample)) != ERROR_SUCCESS) { + /** + * write audio raw frame to SRS. + */ + int srs_audio_write_raw_frame(srs_rtmp_t rtmp, char sound_format, char sound_rate, + char sound_size, char sound_type, char* frame, int frame_size, uint32_t timestamp + ) { + int ret = ERROR_SUCCESS; + + Context* context = (Context*)rtmp; + srs_assert(context); + + if (sound_format == SrsAudioCodecIdAAC) { + // for aac, the frame must be ADTS format. + if (!srs_aac_is_adts(frame, frame_size)) { + return ERROR_AAC_REQUIRED_ADTS; + } + + // for aac, demux the ADTS to RTMP format. + return srs_write_aac_adts_frames(context, sound_format, sound_rate, sound_size, sound_type, frame, frame_size, timestamp); + } else { + // use codec info for aac. + SrsRawAacStreamCodec codec; + codec.sound_format = sound_format; + codec.sound_rate = sound_rate; + codec.sound_size = sound_size; + codec.sound_type = sound_type; + codec.aac_packet_type = 0; + + // for other data, directly write frame. + return srs_write_audio_raw_frame(context, frame, frame_size, &codec, timestamp); + } + return ret; } - if (ht == SrsMp4HandlerTypeForbidden) { - return ERROR_MP4_ILLEGAL_HANDLER; + /** + * whether aac raw data is in adts format, + * which bytes sequence matches '1111 1111 1111'B, that is 0xFFF. + */ + srs_bool srs_aac_is_adts(char* aac_raw_data, int ac_raw_size) + { + SrsBuffer stream; + + if (stream.initialize(aac_raw_data, ac_raw_size) != ERROR_SUCCESS) { + return false; + } + + return srs_aac_startswith_adts(&stream); } - if (ht == SrsMp4HandlerTypeSOUN) { - s->codec = dec->acodec; - s->sample_rate = dec->sample_rate; - s->channels = dec->channels; - s->sound_bits = dec->sound_bits; - } else { - s->codec = dec->vcodec; + /** + * parse the adts header to get the frame size. + */ + int srs_aac_adts_frame_size(char* aac_raw_data, int ac_raw_size) + { + int size = -1; + + if (!srs_aac_is_adts(aac_raw_data, ac_raw_size)) { + return size; + } + + // adts always 7bytes. + if (ac_raw_size <= 7) { + return size; + } + + // last 2bits + int16_t ch3 = aac_raw_data[3]; + // whole 8bits + int16_t ch4 = aac_raw_data[4]; + // first 3bits + int16_t ch5 = aac_raw_data[5]; + + size = ((ch3 << 11) & 0x1800) | ((ch4 << 3) & 0x07f8) | ((ch5 >> 5) & 0x0007); + + return size; } - s->handler_type = (uint32_t)ht; - return ret; -} + /** + * write h264 IPB-frame. + */ + int srs_write_h264_ipb_frame(Context* context, char* frame, int frame_size, uint32_t dts, uint32_t pts) + { + int ret = ERROR_SUCCESS; + + // when sps or pps not sent, ignore the packet. + // @see https://github.com/ossrs/srs/issues/203 + if (!context->h264_sps_pps_sent) { + return ERROR_H264_DROP_BEFORE_SPS_PPS; + } + + // 5bits, 7.3.1 NAL unit syntax, + // ISO_IEC_14496-10-AVC-2003.pdf, page 44. + // 5: I Frame, 1: P/B Frame + // @remark we already group sps/pps to sequence header frame; + // for I/P NALU, we send them in isolate frame, each NALU in a frame; + // for other NALU, for example, AUD/SEI, we just ignore them, because + // AUD used in annexb to split frame, while SEI generally we can ignore it. + // TODO: maybe we should group all NALUs split by AUD to a frame. + SrsAvcNaluType nut = (SrsAvcNaluType)(frame[0] & 0x1f); + if (nut != SrsAvcNaluTypeIDR && nut != SrsAvcNaluTypeNonIDR) { + return ret; + } + + // for IDR frame, the frame is keyframe. + SrsVideoAvcFrameType frame_type = SrsVideoAvcFrameTypeInterFrame; + if (nut == SrsAvcNaluTypeIDR) { + frame_type = SrsVideoAvcFrameTypeKeyFrame; + } + + std::string ibp; + if ((ret = context->avc_raw.mux_ipb_frame(frame, frame_size, ibp)) != ERROR_SUCCESS) { + return ret; + } + + int8_t avc_packet_type = SrsVideoAvcFrameTraitNALU; + char* flv = NULL; + int nb_flv = 0; + if ((ret = context->avc_raw.mux_avc2flv(ibp, frame_type, avc_packet_type, dts, pts, &flv, &nb_flv)) != ERROR_SUCCESS) { + return ret; + } + + // the timestamp in rtmp message header is dts. + uint32_t timestamp = dts; + return srs_rtmp_write_packet(context, SRS_RTMP_TYPE_VIDEO, timestamp, flv, nb_flv); + } -void srs_mp4_free_sample(srs_mp4_sample_t* s) -{ - srs_freepa(s->sample); -} + /** + * write the h264 sps/pps in context over RTMP. + */ + int srs_write_h264_sps_pps(Context* context, uint32_t dts, uint32_t pts) + { + int ret = ERROR_SUCCESS; + + // send when sps or pps changed. + if (!context->h264_sps_changed && !context->h264_pps_changed) { + return ret; + } + + // h264 raw to h264 packet. + std::string sh; + if ((ret = context->avc_raw.mux_sequence_header(context->h264_sps, context->h264_pps, dts, pts, sh)) != ERROR_SUCCESS) { + return ret; + } + + // h264 packet to flv packet. + int8_t frame_type = SrsVideoAvcFrameTypeKeyFrame; + int8_t avc_packet_type = SrsVideoAvcFrameTraitSequenceHeader; + char* flv = NULL; + int nb_flv = 0; + if ((ret = context->avc_raw.mux_avc2flv(sh, frame_type, avc_packet_type, dts, pts, &flv, &nb_flv)) != ERROR_SUCCESS) { + return ret; + } + + // reset sps and pps. + context->h264_sps_changed = false; + context->h264_pps_changed = false; + context->h264_sps_pps_sent = true; + + // the timestamp in rtmp message header is dts. + uint32_t timestamp = dts; + return srs_rtmp_write_packet(context, SRS_RTMP_TYPE_VIDEO, timestamp, flv, nb_flv); + } -int32_t srs_mp4_sizeof(srs_mp4_t mp4, srs_mp4_sample_t* s) -{ - if (s->handler_type == SrsMp4HandlerTypeSOUN) { - if (s->codec == SrsAudioCodecIdAAC) { - return s->nb_sample + 2; + /** + * write h264 raw frame, maybe sps/pps/IPB-frame. + */ + int srs_write_h264_raw_frame(Context* context, char* frame, int frame_size, uint32_t dts, uint32_t pts) + { + int ret = ERROR_SUCCESS; + + // empty frame. + if (frame_size <= 0) { + return ret; + } + + // for sps + if (context->avc_raw.is_sps(frame, frame_size)) { + std::string sps; + if ((ret = context->avc_raw.sps_demux(frame, frame_size, sps)) != ERROR_SUCCESS) { + return ret; + } + + if (context->h264_sps == sps) { + return ERROR_H264_DUPLICATED_SPS; + } + context->h264_sps_changed = true; + context->h264_sps = sps; + + return ret; + } + + // for pps + if (context->avc_raw.is_pps(frame, frame_size)) { + std::string pps; + if ((ret = context->avc_raw.pps_demux(frame, frame_size, pps)) != ERROR_SUCCESS) { + return ret; + } + + if (context->h264_pps == pps) { + return ERROR_H264_DUPLICATED_PPS; + } + context->h264_pps_changed = true; + context->h264_pps = pps; + + return ret; + } + + // ignore others. + // 5bits, 7.3.1 NAL unit syntax, + // ISO_IEC_14496-10-AVC-2003.pdf, page 44. + // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame, 9: AUD + SrsAvcNaluType nut = (SrsAvcNaluType)(frame[0] & 0x1f); + if (nut != SrsAvcNaluTypeSPS && nut != SrsAvcNaluTypePPS + && nut != SrsAvcNaluTypeIDR && nut != SrsAvcNaluTypeNonIDR + && nut != SrsAvcNaluTypeAccessUnitDelimiter + ) { + return ret; + } + + // send pps+sps before ipb frames when sps/pps changed. + if ((ret = srs_write_h264_sps_pps(context, dts, pts)) != ERROR_SUCCESS) { + return ret; + } + + // ibp frame. + return srs_write_h264_ipb_frame(context, frame, frame_size, dts, pts); + } + + /** + * write h264 multiple frames, in annexb format. + */ + int srs_h264_write_raw_frames(srs_rtmp_t rtmp, char* frames, int frames_size, uint32_t dts, uint32_t pts) + { + int ret = ERROR_SUCCESS; + + srs_assert(frames != NULL); + srs_assert(frames_size > 0); + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + + if ((ret = context->h264_raw_stream.initialize(frames, frames_size)) != ERROR_SUCCESS) { + return ret; + } + + // use the last error + // @see https://github.com/ossrs/srs/issues/203 + // @see https://github.com/ossrs/srs/issues/204 + int error_code_return = ret; + + // send each frame. + while (!context->h264_raw_stream.empty()) { + char* frame = NULL; + int frame_size = 0; + if ((ret = context->avc_raw.annexb_demux(&context->h264_raw_stream, &frame, &frame_size)) != ERROR_SUCCESS) { + return ret; + } + + // ignore invalid frame, + // atleast 1bytes for SPS to decode the type + if (frame_size <= 0) { + continue; + } + + // it may be return error, but we must process all packets. + if ((ret = srs_write_h264_raw_frame(context, frame, frame_size, dts, pts)) != ERROR_SUCCESS) { + error_code_return = ret; + + // ignore known error, process all packets. + if (srs_h264_is_dvbsp_error(ret) + || srs_h264_is_duplicated_sps_error(ret) + || srs_h264_is_duplicated_pps_error(ret) + ) { + continue; + } + + return ret; + } + } + + return error_code_return; + } + + srs_bool srs_h264_is_dvbsp_error(int error_code) + { + return error_code == ERROR_H264_DROP_BEFORE_SPS_PPS; + } + + srs_bool srs_h264_is_duplicated_sps_error(int error_code) + { + return error_code == ERROR_H264_DUPLICATED_SPS; + } + + srs_bool srs_h264_is_duplicated_pps_error(int error_code) + { + return error_code == ERROR_H264_DUPLICATED_PPS; + } + + srs_bool srs_h264_startswith_annexb(char* h264_raw_data, int h264_raw_size, int* pnb_start_code) + { + SrsBuffer stream; + if (stream.initialize(h264_raw_data, h264_raw_size) != ERROR_SUCCESS) { + return false; + } + + return srs_avc_startswith_annexb(&stream, pnb_start_code); + } + + struct Mp4Context + { + SrsFileReader reader; + SrsMp4Decoder dec; + }; + + srs_mp4_t srs_mp4_open_read(const char* file) + { + int ret = ERROR_SUCCESS; + + Mp4Context* mp4 = new Mp4Context(); + + if ((ret = mp4->reader.open(file)) != ERROR_SUCCESS) { + srs_human_error("Open MP4 file failed, ret=%d", ret); + + srs_freep(mp4); + return NULL; + } + + return mp4; + } + + void srs_mp4_close(srs_mp4_t mp4) + { + Mp4Context* context = (Mp4Context*)mp4; + srs_freep(context); + } + + int srs_mp4_init_demuxer(srs_mp4_t mp4) + { + int ret = ERROR_SUCCESS; + + Mp4Context* context = (Mp4Context*)mp4; + + if ((ret = context->dec.initialize(&context->reader)) != ERROR_SUCCESS) { + return ret; + } + + return ret; + } + + int srs_mp4_read_sample(srs_mp4_t mp4, srs_mp4_sample_t* s) + { + s->sample = NULL; + + int ret = ERROR_SUCCESS; + + Mp4Context* context = (Mp4Context*)mp4; + SrsMp4Decoder* dec = &context->dec; + + SrsMp4HandlerType ht = SrsMp4HandlerTypeForbidden; + if ((ret = dec->read_sample(&ht, &s->frame_type, &s->frame_trait, &s->dts, &s->pts, &s->sample, &s->nb_sample)) != ERROR_SUCCESS) { + return ret; + } + + if (ht == SrsMp4HandlerTypeForbidden) { + return ERROR_MP4_ILLEGAL_HANDLER; + } + + if (ht == SrsMp4HandlerTypeSOUN) { + s->codec = dec->acodec; + s->sample_rate = dec->sample_rate; + s->channels = dec->channels; + s->sound_bits = dec->sound_bits; + } else { + s->codec = dec->vcodec; + } + s->handler_type = (uint32_t)ht; + + return ret; + } + + void srs_mp4_free_sample(srs_mp4_sample_t* s) + { + srs_freepa(s->sample); + } + + int32_t srs_mp4_sizeof(srs_mp4_t mp4, srs_mp4_sample_t* s) + { + if (s->handler_type == SrsMp4HandlerTypeSOUN) { + if (s->codec == SrsAudioCodecIdAAC) { + return s->nb_sample + 2; + } + return s->nb_sample + 1; + } + + if (s->codec == SrsVideoCodecIdAVC) { + return s->nb_sample + 5; } return s->nb_sample + 1; } - if (s->codec == SrsVideoCodecIdAVC) { - return s->nb_sample + 5; - } - return s->nb_sample + 1; -} - -int srs_mp4_to_flv_tag(srs_mp4_t mp4, srs_mp4_sample_t* s, char* type, uint32_t* time, char* data, int32_t size) -{ - int ret = ERROR_SUCCESS; - - *time = s->dts; - - SrsBuffer p(data, size); - if (s->handler_type == SrsMp4HandlerTypeSOUN) { - *type = SRS_RTMP_TYPE_AUDIO; + int srs_mp4_to_flv_tag(srs_mp4_t mp4, srs_mp4_sample_t* s, char* type, uint32_t* time, char* data, int32_t size) + { + int ret = ERROR_SUCCESS; - // E.4.2.1 AUDIODATA, flv_v10_1.pdf, page 3 - p.write_1bytes(uint8_t(s->codec << 4) | uint8_t(s->sample_rate << 2) | uint8_t(s->sound_bits << 1) | s->channels); - if (s->codec == SrsAudioCodecIdAAC) { - p.write_1bytes(uint8_t(s->frame_trait == SrsAudioAacFrameTraitSequenceHeader? 0:1)); + *time = s->dts; + + SrsBuffer p(data, size); + if (s->handler_type == SrsMp4HandlerTypeSOUN) { + *type = SRS_RTMP_TYPE_AUDIO; + + // E.4.2.1 AUDIODATA, flv_v10_1.pdf, page 3 + p.write_1bytes(uint8_t(s->codec << 4) | uint8_t(s->sample_rate << 2) | uint8_t(s->sound_bits << 1) | s->channels); + if (s->codec == SrsAudioCodecIdAAC) { + p.write_1bytes(uint8_t(s->frame_trait == SrsAudioAacFrameTraitSequenceHeader? 0:1)); + } + + p.write_bytes((char*)s->sample, s->nb_sample); + return ret; } + // E.4.3.1 VIDEODATA, flv_v10_1.pdf, page 5 + p.write_1bytes(uint8_t(s->frame_type<<4) | s->codec); + if (s->codec == SrsVideoCodecIdAVC) { + *type = SRS_RTMP_TYPE_VIDEO; + + p.write_1bytes(uint8_t(s->frame_trait == SrsVideoAvcFrameTraitSequenceHeader? 0:1)); + // cts = pts - dts, where dts = flvheader->timestamp. + uint32_t cts = s->pts - s->dts; + p.write_3bytes(cts); + } p.write_bytes((char*)s->sample, s->nb_sample); - return ret; - } - - // E.4.3.1 VIDEODATA, flv_v10_1.pdf, page 5 - p.write_1bytes(uint8_t(s->frame_type<<4) | s->codec); - if (s->codec == SrsVideoCodecIdAVC) { - *type = SRS_RTMP_TYPE_VIDEO; - p.write_1bytes(uint8_t(s->frame_trait == SrsVideoAvcFrameTraitSequenceHeader? 0:1)); - // cts = pts - dts, where dts = flvheader->timestamp. - uint32_t cts = s->pts - s->dts; - p.write_3bytes(cts); + return ret; } - p.write_bytes((char*)s->sample, s->nb_sample); - return ret; -} - -srs_bool srs_mp4_is_eof(int error_code) -{ - return error_code == ERROR_SYSTEM_FILE_EOF; -} - -struct FlvContext -{ - SrsFileReader reader; - SrsFileWriter writer; - SrsFlvTransmuxer enc; - SrsFlvDecoder dec; -}; - -srs_flv_t srs_flv_open_read(const char* file) -{ - int ret = ERROR_SUCCESS; + srs_bool srs_mp4_is_eof(int error_code) + { + return error_code == ERROR_SYSTEM_FILE_EOF; + } - FlvContext* flv = new FlvContext(); + struct FlvContext + { + SrsFileReader reader; + SrsFileWriter writer; + SrsFlvTransmuxer enc; + SrsFlvDecoder dec; + }; - if ((ret = flv->reader.open(file)) != ERROR_SUCCESS) { - srs_human_error("Open FLV file failed, ret=%d", ret); + srs_flv_t srs_flv_open_read(const char* file) + { + int ret = ERROR_SUCCESS; - srs_freep(flv); - return NULL; - } - - if ((ret = flv->dec.initialize(&flv->reader)) != ERROR_SUCCESS) { - srs_human_error("Initialize FLV demuxer failed, ret=%d", ret); + FlvContext* flv = new FlvContext(); - srs_freep(flv); - return NULL; - } - - return flv; -} - -srs_flv_t srs_flv_open_write(const char* file) -{ - int ret = ERROR_SUCCESS; - - FlvContext* flv = new FlvContext(); - - if ((ret = flv->writer.open(file)) != ERROR_SUCCESS) { - srs_human_error("Open FLV file failed, ret=%d", ret); - - srs_freep(flv); - return NULL; - } - - if ((ret = flv->enc.initialize(&flv->writer)) != ERROR_SUCCESS) { - srs_human_error("Initilize FLV muxer failed, ret=%d", ret); - - srs_freep(flv); - return NULL; - } - - return flv; -} - -void srs_flv_close(srs_flv_t flv) -{ - FlvContext* context = (FlvContext*)flv; - srs_freep(context); -} - -int srs_flv_read_header(srs_flv_t flv, char header[9]) -{ - int ret = ERROR_SUCCESS; - - FlvContext* context = (FlvContext*)flv; - - if (!context->reader.is_open()) { - return ERROR_SYSTEM_IO_INVALID; - } - - if ((ret = context->dec.read_header(header)) != ERROR_SUCCESS) { - return ret; - } - - char ts[4]; // tag size - if ((ret = context->dec.read_previous_tag_size(ts)) != ERROR_SUCCESS) { - return ret; - } - - return ret; -} - -int srs_flv_read_tag_header(srs_flv_t flv, char* ptype, int32_t* pdata_size, uint32_t* ptime) -{ - int ret = ERROR_SUCCESS; - - FlvContext* context = (FlvContext*)flv; - - if (!context->reader.is_open()) { - return ERROR_SYSTEM_IO_INVALID; - } - - if ((ret = context->dec.read_tag_header(ptype, pdata_size, ptime)) != ERROR_SUCCESS) { - return ret; - } - - return ret; -} - -int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size) -{ - int ret = ERROR_SUCCESS; - - FlvContext* context = (FlvContext*)flv; - - if (!context->reader.is_open()) { - return ERROR_SYSTEM_IO_INVALID; - } - - if ((ret = context->dec.read_tag_data(data, size)) != ERROR_SUCCESS) { - return ret; - } - - char ts[4]; // tag size - if ((ret = context->dec.read_previous_tag_size(ts)) != ERROR_SUCCESS) { - return ret; - } - - return ret; -} - -int srs_flv_write_header(srs_flv_t flv, char header[9]) -{ - int ret = ERROR_SUCCESS; - - FlvContext* context = (FlvContext*)flv; - - if (!context->writer.is_open()) { - return ERROR_SYSTEM_IO_INVALID; - } - - if ((ret = context->enc.write_header(header)) != ERROR_SUCCESS) { - return ret; - } - - return ret; -} - -int srs_flv_write_tag(srs_flv_t flv, char type, int32_t time, char* data, int size) -{ - int ret = ERROR_SUCCESS; - - FlvContext* context = (FlvContext*)flv; - - if (!context->writer.is_open()) { - return ERROR_SYSTEM_IO_INVALID; - } - - if (type == SRS_RTMP_TYPE_AUDIO) { - return context->enc.write_audio(time, data, size); - } else if (type == SRS_RTMP_TYPE_VIDEO) { - return context->enc.write_video(time, data, size); - } else { - return context->enc.write_metadata(type, data, size); - } - - return ret; -} - -int srs_flv_size_tag(int data_size) -{ - return SrsFlvTransmuxer::size_tag(data_size); -} - -int64_t srs_flv_tellg(srs_flv_t flv) -{ - FlvContext* context = (FlvContext*)flv; - return context->reader.tellg(); -} - -void srs_flv_lseek(srs_flv_t flv, int64_t offset) -{ - FlvContext* context = (FlvContext*)flv; - context->reader.seek2(offset); -} - -srs_bool srs_flv_is_eof(int error_code) -{ - return error_code == ERROR_SYSTEM_FILE_EOF; -} - -srs_bool srs_flv_is_sequence_header(char* data, int32_t size) -{ - return SrsFlvVideo::sh(data, (int)size); -} - -srs_bool srs_flv_is_keyframe(char* data, int32_t size) -{ - return SrsFlvVideo::keyframe(data, (int)size); -} - -srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed) -{ - int ret = ERROR_SUCCESS; - - srs_amf0_t amf0 = NULL; - - SrsBuffer stream; - if ((ret = stream.initialize(data, size)) != ERROR_SUCCESS) { - return amf0; - } - - SrsAmf0Any* any = NULL; - if ((ret = SrsAmf0Any::discovery(&stream, &any)) != ERROR_SUCCESS) { - return amf0; - } - - stream.skip(-1 * stream.pos()); - if ((ret = any->read(&stream)) != ERROR_SUCCESS) { - srs_freep(any); - return amf0; - } - - if (nparsed) { - *nparsed = stream.pos(); - } - amf0 = (srs_amf0_t)any; - - return amf0; -} - -srs_amf0_t srs_amf0_create_string(const char* value) -{ - return SrsAmf0Any::str(value); -} - -srs_amf0_t srs_amf0_create_number(srs_amf0_number value) -{ - return SrsAmf0Any::number(value); -} - -srs_amf0_t srs_amf0_create_ecma_array() -{ - return SrsAmf0Any::ecma_array(); -} - -srs_amf0_t srs_amf0_create_strict_array() -{ - return SrsAmf0Any::strict_array(); -} - -srs_amf0_t srs_amf0_create_object() -{ - return SrsAmf0Any::object(); -} - -srs_amf0_t srs_amf0_ecma_array_to_object(srs_amf0_t ecma_arr) -{ - srs_assert(srs_amf0_is_ecma_array(ecma_arr)); - - SrsAmf0EcmaArray* arr = (SrsAmf0EcmaArray*)ecma_arr; - SrsAmf0Object* obj = SrsAmf0Any::object(); - - for (int i = 0; i < arr->count(); i++) { - std::string key = arr->key_at(i); - SrsAmf0Any* value = arr->value_at(i); - obj->set(key, value->copy()); - } - - return obj; -} - -void srs_amf0_free(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - srs_freep(any); -} - -int srs_amf0_size(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - return any->total_size(); -} - -int srs_amf0_serialize(srs_amf0_t amf0, char* data, int size) -{ - int ret = ERROR_SUCCESS; - - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - - SrsBuffer stream; - if ((ret = stream.initialize(data, size)) != ERROR_SUCCESS) { - return ret; - } - - if ((ret = any->write(&stream)) != ERROR_SUCCESS) { - return ret; - } - - return ret; -} - -srs_bool srs_amf0_is_string(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - return any->is_string(); -} - -srs_bool srs_amf0_is_boolean(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - return any->is_boolean(); -} - -srs_bool srs_amf0_is_number(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - return any->is_number(); -} - -srs_bool srs_amf0_is_null(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - return any->is_null(); -} - -srs_bool srs_amf0_is_object(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - return any->is_object(); -} - -srs_bool srs_amf0_is_ecma_array(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - return any->is_ecma_array(); -} - -srs_bool srs_amf0_is_strict_array(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - return any->is_strict_array(); -} - -const char* srs_amf0_to_string(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - return any->to_str_raw(); -} - -srs_bool srs_amf0_to_boolean(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - return any->to_boolean(); -} - -srs_amf0_number srs_amf0_to_number(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - return any->to_number(); -} - -void srs_amf0_set_number(srs_amf0_t amf0, srs_amf0_number value) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - any->set_number(value); -} - -int srs_amf0_object_property_count(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - srs_assert(any->is_object()); - - SrsAmf0Object* obj = (SrsAmf0Object*)amf0; - return obj->count(); -} - -const char* srs_amf0_object_property_name_at(srs_amf0_t amf0, int index) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - srs_assert(any->is_object()); - - SrsAmf0Object* obj = (SrsAmf0Object*)amf0; - return obj->key_raw_at(index); -} - -srs_amf0_t srs_amf0_object_property_value_at(srs_amf0_t amf0, int index) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - srs_assert(any->is_object()); - - SrsAmf0Object* obj = (SrsAmf0Object*)amf0; - return (srs_amf0_t)obj->value_at(index); -} - -srs_amf0_t srs_amf0_object_property(srs_amf0_t amf0, const char* name) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - srs_assert(any->is_object()); - - SrsAmf0Object* obj = (SrsAmf0Object*)amf0; - return (srs_amf0_t)obj->get_property(name); -} - -void srs_amf0_object_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - srs_assert(any->is_object()); - - SrsAmf0Object* obj = (SrsAmf0Object*)amf0; - any = (SrsAmf0Any*)value; - obj->set(name, any); -} - -void srs_amf0_object_clear(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - srs_assert(any->is_object()); - - SrsAmf0Object* obj = (SrsAmf0Object*)amf0; - obj->clear(); -} - -int srs_amf0_ecma_array_property_count(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - srs_assert(any->is_ecma_array()); - - SrsAmf0EcmaArray * obj = (SrsAmf0EcmaArray*)amf0; - return obj->count(); -} - -const char* srs_amf0_ecma_array_property_name_at(srs_amf0_t amf0, int index) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - srs_assert(any->is_ecma_array()); - - SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0; - return obj->key_raw_at(index); -} - -srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - srs_assert(any->is_ecma_array()); - - SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0; - return (srs_amf0_t)obj->value_at(index); -} - -srs_amf0_t srs_amf0_ecma_array_property(srs_amf0_t amf0, const char* name) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - srs_assert(any->is_ecma_array()); - - SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0; - return (srs_amf0_t)obj->get_property(name); -} - -void srs_amf0_ecma_array_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - srs_assert(any->is_ecma_array()); - - SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0; - any = (SrsAmf0Any*)value; - obj->set(name, any); -} - -int srs_amf0_strict_array_property_count(srs_amf0_t amf0) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - srs_assert(any->is_strict_array()); - - SrsAmf0StrictArray * obj = (SrsAmf0StrictArray*)amf0; - return obj->count(); -} - -srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - srs_assert(any->is_strict_array()); - - SrsAmf0StrictArray* obj = (SrsAmf0StrictArray*)amf0; - return (srs_amf0_t)obj->at(index); -} - -void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value) -{ - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - srs_assert(any->is_strict_array()); - - SrsAmf0StrictArray* obj = (SrsAmf0StrictArray*)amf0; - any = (SrsAmf0Any*)value; - obj->append(any); -} - -int64_t srs_utils_time_ms() -{ - return srs_update_system_time_ms(); -} - -int64_t srs_utils_send_bytes(srs_rtmp_t rtmp) -{ - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - if (!context->rtmp) { - return 0; - } - return context->rtmp->get_send_bytes(); -} - -int64_t srs_utils_recv_bytes(srs_rtmp_t rtmp) -{ - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - if (!context->rtmp) { - return 0; - } - return context->rtmp->get_recv_bytes(); -} - -int srs_utils_parse_timestamp( - uint32_t time, char type, char* data, int size, - uint32_t* ppts -) { - int ret = ERROR_SUCCESS; - - if (type != SRS_RTMP_TYPE_VIDEO) { - *ppts = time; - return ret; - } - - if (!SrsFlvVideo::h264(data, size)) { - return ERROR_FLV_INVALID_VIDEO_TAG; - } - - if (SrsFlvVideo::sh(data, size)) { - *ppts = time; - return ret; - } - - // 1bytes, frame type and codec id. - // 1bytes, avc packet type. - // 3bytes, cts, composition time, - // pts = dts + cts, or - // cts = pts - dts. - if (size < 5) { - return ERROR_FLV_INVALID_VIDEO_TAG; - } - - uint32_t cts = 0; - char* p = data + 2; - char* pp = (char*)&cts; - pp[2] = *p++; - pp[1] = *p++; - pp[0] = *p++; - - *ppts = time + cts; - - return ret; -} - -srs_bool srs_utils_flv_tag_is_ok(char type) -{ - return type == SRS_RTMP_TYPE_AUDIO || type == SRS_RTMP_TYPE_VIDEO || type == SRS_RTMP_TYPE_SCRIPT; -} - -srs_bool srs_utils_flv_tag_is_audio(char type) -{ - return type == SRS_RTMP_TYPE_AUDIO; -} - -srs_bool srs_utils_flv_tag_is_video(char type) -{ - return type == SRS_RTMP_TYPE_VIDEO; -} - -srs_bool srs_utils_flv_tag_is_av(char type) -{ - return type == SRS_RTMP_TYPE_AUDIO || type == SRS_RTMP_TYPE_VIDEO; -} - -char srs_utils_flv_video_codec_id(char* data, int size) -{ - if (size < 1) { - return 0; - } - - char codec_id = data[0]; - codec_id = codec_id & 0x0F; - - return codec_id; -} - -char srs_utils_flv_video_avc_packet_type(char* data, int size) -{ - if (size < 2) { - return -1; - } - - if (!SrsFlvVideo::h264(data, size)) { - return -1; - } - - uint8_t avc_packet_type = data[1]; - - if (avc_packet_type > 2) { - return -1; - } - - return avc_packet_type; -} - -char srs_utils_flv_video_frame_type(char* data, int size) -{ - if (size < 1) { - return -1; - } - - if (!SrsFlvVideo::h264(data, size)) { - return -1; - } - - uint8_t frame_type = data[0]; - frame_type = (frame_type >> 4) & 0x0f; - if (frame_type < 1 || frame_type > 5) { - return -1; - } - - return frame_type; -} - -char srs_utils_flv_audio_sound_format(char* data, int size) -{ - if (size < 1) { - return -1; - } - - uint8_t sound_format = data[0]; - sound_format = (sound_format >> 4) & 0x0f; - if (sound_format > 15 || sound_format == 12 || sound_format == 13) { - return -1; - } - - return sound_format; -} - -char srs_utils_flv_audio_sound_rate(char* data, int size) -{ - if (size < 1) { - return -1; - } - - uint8_t sound_rate = data[0]; - sound_rate = (sound_rate >> 2) & 0x03; - if (sound_rate > 3) { - return -1; - } - - return sound_rate; -} - -char srs_utils_flv_audio_sound_size(char* data, int size) -{ - if (size < 1) { - return -1; - } - - uint8_t sound_size = data[0]; - sound_size = (sound_size >> 1) & 0x01; - if (sound_size > 1) { - return -1; - } - - return sound_size; -} - -char srs_utils_flv_audio_sound_type(char* data, int size) -{ - if (size < 1) { - return -1; - } - - uint8_t sound_type = data[0]; - sound_type = sound_type & 0x01; - if (sound_type > 1) { - return -1; - } - - return sound_type; -} - -char srs_utils_flv_audio_aac_packet_type(char* data, int size) -{ - if (size < 2) { - return -1; - } - - if (srs_utils_flv_audio_sound_format(data, size) != 10) { - return -1; - } - - uint8_t aac_packet_type = data[1]; - if (aac_packet_type > 1) { - return -1; - } - - return aac_packet_type; -} - -char* srs_human_amf0_print(srs_amf0_t amf0, char** pdata, int* psize) -{ - if (!amf0) { - return NULL; - } - - SrsAmf0Any* any = (SrsAmf0Any*)amf0; - - return any->human_print(pdata, psize); -} - -const char* srs_human_flv_tag_type2string(char type) -{ - static const char* audio = "Audio"; - static const char* video = "Video"; - static const char* data = "Data"; - static const char* unknown = "Unknown"; - - switch (type) { - case SRS_RTMP_TYPE_AUDIO: return audio; - case SRS_RTMP_TYPE_VIDEO: return video; - case SRS_RTMP_TYPE_SCRIPT: return data; - default: return unknown; - } - - return unknown; -} - -const char* srs_human_flv_video_codec_id2string(char codec_id) -{ - static const char* h263 = "H.263"; - static const char* screen = "Screen"; - static const char* vp6 = "VP6"; - static const char* vp6_alpha = "VP6Alpha"; - static const char* screen2 = "Screen2"; - static const char* h264 = "H.264"; - static const char* unknown = "Unknown"; - - switch (codec_id) { - case 2: return h263; - case 3: return screen; - case 4: return vp6; - case 5: return vp6_alpha; - case 6: return screen2; - case 7: return h264; - default: return unknown; - } - - return unknown; -} - -const char* srs_human_flv_video_avc_packet_type2string(char avc_packet_type) -{ - static const char* sps_pps = "SH"; - static const char* nalu = "Nalu"; - static const char* sps_pps_end = "SpsPpsEnd"; - static const char* unknown = "Unknown"; - - switch (avc_packet_type) { - case 0: return sps_pps; - case 1: return nalu; - case 2: return sps_pps_end; - default: return unknown; - } - - return unknown; -} - -const char* srs_human_flv_video_frame_type2string(char frame_type) -{ - static const char* keyframe = "I"; - static const char* interframe = "P/B"; - static const char* disposable_interframe = "DI"; - static const char* generated_keyframe = "GI"; - static const char* video_infoframe = "VI"; - static const char* unknown = "Unknown"; - - switch (frame_type) { - case 1: return keyframe; - case 2: return interframe; - case 3: return disposable_interframe; - case 4: return generated_keyframe; - case 5: return video_infoframe; - default: return unknown; - } - - return unknown; -} - -const char* srs_human_flv_audio_sound_format2string(char sound_format) -{ - static const char* linear_pcm = "LinearPCM"; - static const char* ad_pcm = "ADPCM"; - static const char* mp3 = "MP3"; - static const char* linear_pcm_le = "LinearPCMLe"; - static const char* nellymoser_16khz = "NellymoserKHz16"; - static const char* nellymoser_8khz = "NellymoserKHz8"; - static const char* nellymoser = "Nellymoser"; - static const char* g711_a_pcm = "G711APCM"; - static const char* g711_mu_pcm = "G711MuPCM"; - static const char* reserved = "Reserved"; - static const char* aac = "AAC"; - static const char* speex = "Speex"; - static const char* mp3_8khz = "MP3KHz8"; - static const char* device_specific = "DeviceSpecific"; - static const char* unknown = "Unknown"; - - switch (sound_format) { - case 0: return linear_pcm; - case 1: return ad_pcm; - case 2: return mp3; - case 3: return linear_pcm_le; - case 4: return nellymoser_16khz; - case 5: return nellymoser_8khz; - case 6: return nellymoser; - case 7: return g711_a_pcm; - case 8: return g711_mu_pcm; - case 9: return reserved; - case 10: return aac; - case 11: return speex; - case 14: return mp3_8khz; - case 15: return device_specific; - default: return unknown; - } - - return unknown; -} - -const char* srs_human_flv_audio_sound_rate2string(char sound_rate) -{ - static const char* khz_5_5 = "5.5KHz"; - static const char* khz_11 = "11KHz"; - static const char* khz_22 = "22KHz"; - static const char* khz_44 = "44KHz"; - static const char* unknown = "Unknown"; - - switch (sound_rate) { - case 0: return khz_5_5; - case 1: return khz_11; - case 2: return khz_22; - case 3: return khz_44; - default: return unknown; - } - - return unknown; -} - -const char* srs_human_flv_audio_sound_size2string(char sound_size) -{ - static const char* bit_8 = "8bit"; - static const char* bit_16 = "16bit"; - static const char* unknown = "Unknown"; - - switch (sound_size) { - case 0: return bit_8; - case 1: return bit_16; - default: return unknown; - } - - return unknown; -} - -const char* srs_human_flv_audio_sound_type2string(char sound_type) -{ - static const char* mono = "Mono"; - static const char* stereo = "Stereo"; - static const char* unknown = "Unknown"; - - switch (sound_type) { - case 0: return mono; - case 1: return stereo; - default: return unknown; - } - - return unknown; -} - -const char* srs_human_flv_audio_aac_packet_type2string(char aac_packet_type) -{ - static const char* sps_pps = "SH"; - static const char* raw = "Raw"; - static const char* unknown = "Unknown"; - - switch (aac_packet_type) { - case 0: return sps_pps; - case 1: return raw; - default: return unknown; - } - - return unknown; -} - -int srs_human_format_rtmp_packet(char* buffer, int nb_buffer, char type, uint32_t timestamp, char* data, int size) -{ - int ret = ERROR_SUCCESS; - - // Initialize to empty NULL terminated string. - buffer[0] = 0; - - char sbytes[40]; - if (true) { - int nb = srs_min(8, size); - int p = 0; - for (int i = 0; i < nb; i++) { - p += snprintf(sbytes+p, 40-p, "0x%02x ", (uint8_t)data[i]); - } - } - - uint32_t pts; - if ((ret = srs_utils_parse_timestamp(timestamp, type, data, size, &pts)) != ERROR_SUCCESS) { - snprintf(buffer, nb_buffer, "Rtmp packet type=%s, dts=%d, size=%d, DecodeError, (%s), ret=%d", - srs_human_flv_tag_type2string(type), timestamp, size, sbytes, ret); - return ret; - } - - if (type == SRS_RTMP_TYPE_VIDEO) { - snprintf(buffer, nb_buffer, "Video packet type=%s, dts=%d, pts=%d, size=%d, %s(%s,%s), (%s)", - srs_human_flv_tag_type2string(type), timestamp, pts, size, - srs_human_flv_video_codec_id2string(srs_utils_flv_video_codec_id(data, size)), - srs_human_flv_video_avc_packet_type2string(srs_utils_flv_video_avc_packet_type(data, size)), - srs_human_flv_video_frame_type2string(srs_utils_flv_video_frame_type(data, size)), - sbytes); - } else if (type == SRS_RTMP_TYPE_AUDIO) { - snprintf(buffer, nb_buffer, "Audio packet type=%s, dts=%d, pts=%d, size=%d, %s(%s,%s,%s,%s), (%s)", - srs_human_flv_tag_type2string(type), timestamp, pts, size, - srs_human_flv_audio_sound_format2string(srs_utils_flv_audio_sound_format(data, size)), - srs_human_flv_audio_sound_rate2string(srs_utils_flv_audio_sound_rate(data, size)), - srs_human_flv_audio_sound_size2string(srs_utils_flv_audio_sound_size(data, size)), - srs_human_flv_audio_sound_type2string(srs_utils_flv_audio_sound_type(data, size)), - srs_human_flv_audio_aac_packet_type2string(srs_utils_flv_audio_aac_packet_type(data, size)), - sbytes); - } else if (type == SRS_RTMP_TYPE_SCRIPT) { - int nb = snprintf(buffer, nb_buffer, "Data packet type=%s, time=%d, size=%d, (%s)", - srs_human_flv_tag_type2string(type), timestamp, size, sbytes); - int nparsed = 0; - while (nparsed < size) { - int nb_parsed_this = 0; - srs_amf0_t amf0 = srs_amf0_parse(data + nparsed, size - nparsed, &nb_parsed_this); - if (amf0 == NULL) { - break; - } + if ((ret = flv->reader.open(file)) != ERROR_SUCCESS) { + srs_human_error("Open FLV file failed, ret=%d", ret); - nparsed += nb_parsed_this; - - char* amf0_str = NULL; - nb += snprintf(buffer + nb, nb_buffer - nb, "\n%s", srs_human_amf0_print(amf0, &amf0_str, NULL)) - 1; - srs_freepa(amf0_str); + srs_freep(flv); + return NULL; } - buffer[nb] = 0; - } else { - snprintf(buffer, nb_buffer, "Rtmp packet type=%#x, dts=%d, pts=%d, size=%d, (%s)", - type, timestamp, pts, size, sbytes); - } - - return ret; -} - -int srs_human_format_rtmp_packet2(char* buffer, int nb_buffer, char type, uint32_t timestamp, char* data, int size, - uint32_t pre_timestamp, int64_t pre_now, int64_t starttime, int64_t nb_packets -) { - int ret = ERROR_SUCCESS; - - // Initialize to empty NULL terminated string. - buffer[0] = 0; - - // packets interval in milliseconds. - double pi = 0; - if (pre_now > starttime) { - pi = (pre_now - starttime) / (double)nb_packets; - } - - // global fps(video and audio mixed fps). - double gfps = 0; - if (pi > 0) { - gfps = 1000 / pi; - } - - int diff = 0; - if (pre_timestamp > 0) { - diff = (int)timestamp - (int)pre_timestamp; - } - - int ndiff = 0; - if (pre_now > 0) { - ndiff = (int)(srs_utils_time_ms() - pre_now); - } - - char sbytes[40]; - if (true) { - int nb = srs_min(8, size); - int p = 0; - for (int i = 0; i < nb; i++) { - p += snprintf(sbytes+p, 40-p, "0x%02x ", (uint8_t)data[i]); - } - } - - uint32_t pts; - if ((ret = srs_utils_parse_timestamp(timestamp, type, data, size, &pts)) != ERROR_SUCCESS) { - snprintf(buffer, nb_buffer, "Rtmp packet id=%"PRId64"/%.1f/%.1f, type=%s, dts=%d, ndiff=%d, diff=%d, size=%d, DecodeError, (%s), ret=%d", - nb_packets, pi, gfps, srs_human_flv_tag_type2string(type), timestamp, ndiff, diff, size, sbytes, ret); - return ret; - } - - if (type == SRS_RTMP_TYPE_VIDEO) { - snprintf(buffer, nb_buffer, "Video packet id=%"PRId64"/%.1f/%.1f, type=%s, dts=%d, pts=%d, ndiff=%d, diff=%d, size=%d, %s(%s,%s), (%s)", - nb_packets, pi, gfps, srs_human_flv_tag_type2string(type), timestamp, pts, ndiff, diff, size, - srs_human_flv_video_codec_id2string(srs_utils_flv_video_codec_id(data, size)), - srs_human_flv_video_avc_packet_type2string(srs_utils_flv_video_avc_packet_type(data, size)), - srs_human_flv_video_frame_type2string(srs_utils_flv_video_frame_type(data, size)), - sbytes); - } else if (type == SRS_RTMP_TYPE_AUDIO) { - snprintf(buffer, nb_buffer, "Audio packet id=%"PRId64"/%.1f/%.1f, type=%s, dts=%d, pts=%d, ndiff=%d, diff=%d, size=%d, %s(%s,%s,%s,%s), (%s)", - nb_packets, pi, gfps, srs_human_flv_tag_type2string(type), timestamp, pts, ndiff, diff, size, - srs_human_flv_audio_sound_format2string(srs_utils_flv_audio_sound_format(data, size)), - srs_human_flv_audio_sound_rate2string(srs_utils_flv_audio_sound_rate(data, size)), - srs_human_flv_audio_sound_size2string(srs_utils_flv_audio_sound_size(data, size)), - srs_human_flv_audio_sound_type2string(srs_utils_flv_audio_sound_type(data, size)), - srs_human_flv_audio_aac_packet_type2string(srs_utils_flv_audio_aac_packet_type(data, size)), - sbytes); - } else if (type == SRS_RTMP_TYPE_SCRIPT) { - int nb = snprintf(buffer, nb_buffer, "Data packet id=%"PRId64"/%.1f/%.1f, type=%s, time=%d, ndiff=%d, diff=%d, size=%d, (%s)", - nb_packets, pi, gfps, srs_human_flv_tag_type2string(type), timestamp, ndiff, diff, size, sbytes); - int nparsed = 0; - while (nparsed < size) { - int nb_parsed_this = 0; - srs_amf0_t amf0 = srs_amf0_parse(data + nparsed, size - nparsed, &nb_parsed_this); - if (amf0 == NULL) { - break; - } - - nparsed += nb_parsed_this; - - char* amf0_str = NULL; - nb += snprintf(buffer + nb, nb_buffer - nb, "\n%s", srs_human_amf0_print(amf0, &amf0_str, NULL)) - 1; - srs_freepa(amf0_str); - } - buffer[nb] = 0; - } else { - snprintf(buffer, nb_buffer, "Rtmp packet id=%"PRId64"/%.1f/%.1f, type=%#x, dts=%d, pts=%d, ndiff=%d, diff=%d, size=%d, (%s)", - nb_packets, pi, gfps, type, timestamp, pts, ndiff, diff, size, sbytes); - } - - return ret; -} - -const char* srs_human_format_time() -{ - struct timeval tv; - static char buf[24]; - - memset(buf, 0, sizeof(buf)); - - // clock time - if (gettimeofday(&tv, NULL) == -1) { - return buf; - } - - // to calendar time - struct tm* tm; - if ((tm = localtime((const time_t*)&tv.tv_sec)) == NULL) { - return buf; - } - - snprintf(buf, sizeof(buf), - "%d-%02d-%02d %02d:%02d:%02d.%03d", - 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, - tm->tm_hour, tm->tm_min, tm->tm_sec, - (int)(tv.tv_usec / 1000)); - // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 - buf[sizeof(buf) - 1] = 0; - - return buf; -} - - -#ifdef SRS_HIJACK_IO -srs_hijack_io_t srs_hijack_io_get(srs_rtmp_t rtmp) -{ - if (!rtmp) { - return NULL; - } - - Context* context = (Context*)rtmp; - if (!context->skt) { - return NULL; - } - - return context->skt->hijack_io(); -} -#endif - -srs_rtmp_t srs_rtmp_create2(const char* url) -{ - Context* context = new Context(); - - // use url as tcUrl. - context->url = url; - // auto append stream. - context->url += "/livestream"; - - // create socket - srs_freep(context->skt); - context->skt = new SimpleSocketStream(); - - int ret = ERROR_SUCCESS; - if ((ret = context->skt->create_socket(context)) != ERROR_SUCCESS) { - srs_human_error("Create socket failed, ret=%d", ret); + if ((ret = flv->dec.initialize(&flv->reader)) != ERROR_SUCCESS) { + srs_human_error("Initialize FLV demuxer failed, ret=%d", ret); + + srs_freep(flv); + return NULL; + } - // free the context and return NULL + return flv; + } + + srs_flv_t srs_flv_open_write(const char* file) + { + int ret = ERROR_SUCCESS; + + FlvContext* flv = new FlvContext(); + + if ((ret = flv->writer.open(file)) != ERROR_SUCCESS) { + srs_human_error("Open FLV file failed, ret=%d", ret); + + srs_freep(flv); + return NULL; + } + + if ((ret = flv->enc.initialize(&flv->writer)) != ERROR_SUCCESS) { + srs_human_error("Initilize FLV muxer failed, ret=%d", ret); + + srs_freep(flv); + return NULL; + } + + return flv; + } + + void srs_flv_close(srs_flv_t flv) + { + FlvContext* context = (FlvContext*)flv; srs_freep(context); - return NULL; } - return context; -} - -int srs_rtmp_connect_app2(srs_rtmp_t rtmp, - char srs_server_ip[128],char srs_server[128], - char srs_primary[128], char srs_authors[128], - char srs_version[32], int* srs_id, int* srs_pid -) { - srs_server_ip[0] = 0; - srs_server[0] = 0; - srs_primary[0] = 0; - srs_authors[0] = 0; - srs_version[0] = 0; - *srs_id = 0; - *srs_pid = 0; - - int ret = ERROR_SUCCESS; - - if ((ret = srs_rtmp_connect_app(rtmp)) != ERROR_SUCCESS) { + int srs_flv_read_header(srs_flv_t flv, char header[9]) + { + int ret = ERROR_SUCCESS; + + FlvContext* context = (FlvContext*)flv; + + if (!context->reader.is_open()) { + return ERROR_SYSTEM_IO_INVALID; + } + + if ((ret = context->dec.read_header(header)) != ERROR_SUCCESS) { + return ret; + } + + char ts[4]; // tag size + if ((ret = context->dec.read_previous_tag_size(ts)) != ERROR_SUCCESS) { + return ret; + } + return ret; } - srs_assert(rtmp != NULL); - Context* context = (Context*)rtmp; - SrsServerInfo* si = &context->si; + int srs_flv_read_tag_header(srs_flv_t flv, char* ptype, int32_t* pdata_size, uint32_t* ptime) + { + int ret = ERROR_SUCCESS; + + FlvContext* context = (FlvContext*)flv; + + if (!context->reader.is_open()) { + return ERROR_SYSTEM_IO_INVALID; + } + + if ((ret = context->dec.read_tag_header(ptype, pdata_size, ptime)) != ERROR_SUCCESS) { + return ret; + } + + return ret; + } - snprintf(srs_server_ip, 128, "%s", si->ip.c_str()); - snprintf(srs_server, 128, "%s", si->sig.c_str()); - snprintf(srs_version, 32, "%d.%d.%d.%d", si->major, si->minor, si->revision, si->build); + int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size) + { + int ret = ERROR_SUCCESS; + + FlvContext* context = (FlvContext*)flv; + + if (!context->reader.is_open()) { + return ERROR_SYSTEM_IO_INVALID; + } + + if ((ret = context->dec.read_tag_data(data, size)) != ERROR_SUCCESS) { + return ret; + } + + char ts[4]; // tag size + if ((ret = context->dec.read_previous_tag_size(ts)) != ERROR_SUCCESS) { + return ret; + } + + return ret; + } - return ret; -} + int srs_flv_write_header(srs_flv_t flv, char header[9]) + { + int ret = ERROR_SUCCESS; + + FlvContext* context = (FlvContext*)flv; + + if (!context->writer.is_open()) { + return ERROR_SYSTEM_IO_INVALID; + } + + if ((ret = context->enc.write_header(header)) != ERROR_SUCCESS) { + return ret; + } + + return ret; + } + + int srs_flv_write_tag(srs_flv_t flv, char type, int32_t time, char* data, int size) + { + int ret = ERROR_SUCCESS; + + FlvContext* context = (FlvContext*)flv; + + if (!context->writer.is_open()) { + return ERROR_SYSTEM_IO_INVALID; + } + + if (type == SRS_RTMP_TYPE_AUDIO) { + return context->enc.write_audio(time, data, size); + } else if (type == SRS_RTMP_TYPE_VIDEO) { + return context->enc.write_video(time, data, size); + } else { + return context->enc.write_metadata(type, data, size); + } + + return ret; + } + + int srs_flv_size_tag(int data_size) + { + return SrsFlvTransmuxer::size_tag(data_size); + } + + int64_t srs_flv_tellg(srs_flv_t flv) + { + FlvContext* context = (FlvContext*)flv; + return context->reader.tellg(); + } + + void srs_flv_lseek(srs_flv_t flv, int64_t offset) + { + FlvContext* context = (FlvContext*)flv; + context->reader.seek2(offset); + } + + srs_bool srs_flv_is_eof(int error_code) + { + return error_code == ERROR_SYSTEM_FILE_EOF; + } + + srs_bool srs_flv_is_sequence_header(char* data, int32_t size) + { + return SrsFlvVideo::sh(data, (int)size); + } + + srs_bool srs_flv_is_keyframe(char* data, int32_t size) + { + return SrsFlvVideo::keyframe(data, (int)size); + } + + srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed) + { + int ret = ERROR_SUCCESS; + + srs_amf0_t amf0 = NULL; + + SrsBuffer stream; + if ((ret = stream.initialize(data, size)) != ERROR_SUCCESS) { + return amf0; + } + + SrsAmf0Any* any = NULL; + if ((ret = SrsAmf0Any::discovery(&stream, &any)) != ERROR_SUCCESS) { + return amf0; + } + + stream.skip(-1 * stream.pos()); + if ((ret = any->read(&stream)) != ERROR_SUCCESS) { + srs_freep(any); + return amf0; + } + + if (nparsed) { + *nparsed = stream.pos(); + } + amf0 = (srs_amf0_t)any; + + return amf0; + } + + srs_amf0_t srs_amf0_create_string(const char* value) + { + return SrsAmf0Any::str(value); + } + + srs_amf0_t srs_amf0_create_number(srs_amf0_number value) + { + return SrsAmf0Any::number(value); + } + + srs_amf0_t srs_amf0_create_ecma_array() + { + return SrsAmf0Any::ecma_array(); + } + + srs_amf0_t srs_amf0_create_strict_array() + { + return SrsAmf0Any::strict_array(); + } + + srs_amf0_t srs_amf0_create_object() + { + return SrsAmf0Any::object(); + } + + srs_amf0_t srs_amf0_ecma_array_to_object(srs_amf0_t ecma_arr) + { + srs_assert(srs_amf0_is_ecma_array(ecma_arr)); + + SrsAmf0EcmaArray* arr = (SrsAmf0EcmaArray*)ecma_arr; + SrsAmf0Object* obj = SrsAmf0Any::object(); + + for (int i = 0; i < arr->count(); i++) { + std::string key = arr->key_at(i); + SrsAmf0Any* value = arr->value_at(i); + obj->set(key, value->copy()); + } + + return obj; + } + + void srs_amf0_free(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + srs_freep(any); + } + + int srs_amf0_size(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + return any->total_size(); + } + + int srs_amf0_serialize(srs_amf0_t amf0, char* data, int size) + { + int ret = ERROR_SUCCESS; + + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + + SrsBuffer stream; + if ((ret = stream.initialize(data, size)) != ERROR_SUCCESS) { + return ret; + } + + if ((ret = any->write(&stream)) != ERROR_SUCCESS) { + return ret; + } + + return ret; + } + + srs_bool srs_amf0_is_string(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + return any->is_string(); + } + + srs_bool srs_amf0_is_boolean(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + return any->is_boolean(); + } + + srs_bool srs_amf0_is_number(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + return any->is_number(); + } + + srs_bool srs_amf0_is_null(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + return any->is_null(); + } + + srs_bool srs_amf0_is_object(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + return any->is_object(); + } + + srs_bool srs_amf0_is_ecma_array(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + return any->is_ecma_array(); + } + + srs_bool srs_amf0_is_strict_array(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + return any->is_strict_array(); + } + + const char* srs_amf0_to_string(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + return any->to_str_raw(); + } + + srs_bool srs_amf0_to_boolean(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + return any->to_boolean(); + } + + srs_amf0_number srs_amf0_to_number(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + return any->to_number(); + } + + void srs_amf0_set_number(srs_amf0_t amf0, srs_amf0_number value) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + any->set_number(value); + } + + int srs_amf0_object_property_count(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + srs_assert(any->is_object()); + + SrsAmf0Object* obj = (SrsAmf0Object*)amf0; + return obj->count(); + } + + const char* srs_amf0_object_property_name_at(srs_amf0_t amf0, int index) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + srs_assert(any->is_object()); + + SrsAmf0Object* obj = (SrsAmf0Object*)amf0; + return obj->key_raw_at(index); + } + + srs_amf0_t srs_amf0_object_property_value_at(srs_amf0_t amf0, int index) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + srs_assert(any->is_object()); + + SrsAmf0Object* obj = (SrsAmf0Object*)amf0; + return (srs_amf0_t)obj->value_at(index); + } + + srs_amf0_t srs_amf0_object_property(srs_amf0_t amf0, const char* name) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + srs_assert(any->is_object()); + + SrsAmf0Object* obj = (SrsAmf0Object*)amf0; + return (srs_amf0_t)obj->get_property(name); + } + + void srs_amf0_object_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + srs_assert(any->is_object()); + + SrsAmf0Object* obj = (SrsAmf0Object*)amf0; + any = (SrsAmf0Any*)value; + obj->set(name, any); + } + + void srs_amf0_object_clear(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + srs_assert(any->is_object()); + + SrsAmf0Object* obj = (SrsAmf0Object*)amf0; + obj->clear(); + } + + int srs_amf0_ecma_array_property_count(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + srs_assert(any->is_ecma_array()); + + SrsAmf0EcmaArray * obj = (SrsAmf0EcmaArray*)amf0; + return obj->count(); + } + + const char* srs_amf0_ecma_array_property_name_at(srs_amf0_t amf0, int index) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + srs_assert(any->is_ecma_array()); + + SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0; + return obj->key_raw_at(index); + } + + srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + srs_assert(any->is_ecma_array()); + + SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0; + return (srs_amf0_t)obj->value_at(index); + } + + srs_amf0_t srs_amf0_ecma_array_property(srs_amf0_t amf0, const char* name) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + srs_assert(any->is_ecma_array()); + + SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0; + return (srs_amf0_t)obj->get_property(name); + } + + void srs_amf0_ecma_array_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + srs_assert(any->is_ecma_array()); + + SrsAmf0EcmaArray* obj = (SrsAmf0EcmaArray*)amf0; + any = (SrsAmf0Any*)value; + obj->set(name, any); + } + + int srs_amf0_strict_array_property_count(srs_amf0_t amf0) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + srs_assert(any->is_strict_array()); + + SrsAmf0StrictArray * obj = (SrsAmf0StrictArray*)amf0; + return obj->count(); + } + + srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + srs_assert(any->is_strict_array()); + + SrsAmf0StrictArray* obj = (SrsAmf0StrictArray*)amf0; + return (srs_amf0_t)obj->at(index); + } + + void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value) + { + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + srs_assert(any->is_strict_array()); + + SrsAmf0StrictArray* obj = (SrsAmf0StrictArray*)amf0; + any = (SrsAmf0Any*)value; + obj->append(any); + } + + int64_t srs_utils_time_ms() + { + return srs_update_system_time_ms(); + } + + int64_t srs_utils_send_bytes(srs_rtmp_t rtmp) + { + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + if (!context->rtmp) { + return 0; + } + return context->rtmp->get_send_bytes(); + } + + int64_t srs_utils_recv_bytes(srs_rtmp_t rtmp) + { + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + if (!context->rtmp) { + return 0; + } + return context->rtmp->get_recv_bytes(); + } + + int srs_utils_parse_timestamp( + uint32_t time, char type, char* data, int size, + uint32_t* ppts + ) { + int ret = ERROR_SUCCESS; + + if (type != SRS_RTMP_TYPE_VIDEO) { + *ppts = time; + return ret; + } + + if (!SrsFlvVideo::h264(data, size)) { + return ERROR_FLV_INVALID_VIDEO_TAG; + } + + if (SrsFlvVideo::sh(data, size)) { + *ppts = time; + return ret; + } + + // 1bytes, frame type and codec id. + // 1bytes, avc packet type. + // 3bytes, cts, composition time, + // pts = dts + cts, or + // cts = pts - dts. + if (size < 5) { + return ERROR_FLV_INVALID_VIDEO_TAG; + } + + uint32_t cts = 0; + char* p = data + 2; + char* pp = (char*)&cts; + pp[2] = *p++; + pp[1] = *p++; + pp[0] = *p++; + + *ppts = time + cts; + + return ret; + } + + srs_bool srs_utils_flv_tag_is_ok(char type) + { + return type == SRS_RTMP_TYPE_AUDIO || type == SRS_RTMP_TYPE_VIDEO || type == SRS_RTMP_TYPE_SCRIPT; + } + + srs_bool srs_utils_flv_tag_is_audio(char type) + { + return type == SRS_RTMP_TYPE_AUDIO; + } + + srs_bool srs_utils_flv_tag_is_video(char type) + { + return type == SRS_RTMP_TYPE_VIDEO; + } + + srs_bool srs_utils_flv_tag_is_av(char type) + { + return type == SRS_RTMP_TYPE_AUDIO || type == SRS_RTMP_TYPE_VIDEO; + } + + char srs_utils_flv_video_codec_id(char* data, int size) + { + if (size < 1) { + return 0; + } + + char codec_id = data[0]; + codec_id = codec_id & 0x0F; + + return codec_id; + } + + char srs_utils_flv_video_avc_packet_type(char* data, int size) + { + if (size < 2) { + return -1; + } + + if (!SrsFlvVideo::h264(data, size)) { + return -1; + } + + uint8_t avc_packet_type = data[1]; + + if (avc_packet_type > 2) { + return -1; + } + + return avc_packet_type; + } + + char srs_utils_flv_video_frame_type(char* data, int size) + { + if (size < 1) { + return -1; + } + + if (!SrsFlvVideo::h264(data, size)) { + return -1; + } + + uint8_t frame_type = data[0]; + frame_type = (frame_type >> 4) & 0x0f; + if (frame_type < 1 || frame_type > 5) { + return -1; + } + + return frame_type; + } + + char srs_utils_flv_audio_sound_format(char* data, int size) + { + if (size < 1) { + return -1; + } + + uint8_t sound_format = data[0]; + sound_format = (sound_format >> 4) & 0x0f; + if (sound_format > 15 || sound_format == 12 || sound_format == 13) { + return -1; + } + + return sound_format; + } + + char srs_utils_flv_audio_sound_rate(char* data, int size) + { + if (size < 1) { + return -1; + } + + uint8_t sound_rate = data[0]; + sound_rate = (sound_rate >> 2) & 0x03; + if (sound_rate > 3) { + return -1; + } + + return sound_rate; + } + + char srs_utils_flv_audio_sound_size(char* data, int size) + { + if (size < 1) { + return -1; + } + + uint8_t sound_size = data[0]; + sound_size = (sound_size >> 1) & 0x01; + if (sound_size > 1) { + return -1; + } + + return sound_size; + } + + char srs_utils_flv_audio_sound_type(char* data, int size) + { + if (size < 1) { + return -1; + } + + uint8_t sound_type = data[0]; + sound_type = sound_type & 0x01; + if (sound_type > 1) { + return -1; + } + + return sound_type; + } + + char srs_utils_flv_audio_aac_packet_type(char* data, int size) + { + if (size < 2) { + return -1; + } + + if (srs_utils_flv_audio_sound_format(data, size) != 10) { + return -1; + } + + uint8_t aac_packet_type = data[1]; + if (aac_packet_type > 1) { + return -1; + } + + return aac_packet_type; + } + + char* srs_human_amf0_print(srs_amf0_t amf0, char** pdata, int* psize) + { + if (!amf0) { + return NULL; + } + + SrsAmf0Any* any = (SrsAmf0Any*)amf0; + + return any->human_print(pdata, psize); + } + + const char* srs_human_flv_tag_type2string(char type) + { + static const char* audio = "Audio"; + static const char* video = "Video"; + static const char* data = "Data"; + static const char* unknown = "Unknown"; + + switch (type) { + case SRS_RTMP_TYPE_AUDIO: return audio; + case SRS_RTMP_TYPE_VIDEO: return video; + case SRS_RTMP_TYPE_SCRIPT: return data; + default: return unknown; + } + + return unknown; + } + + const char* srs_human_flv_video_codec_id2string(char codec_id) + { + static const char* h263 = "H.263"; + static const char* screen = "Screen"; + static const char* vp6 = "VP6"; + static const char* vp6_alpha = "VP6Alpha"; + static const char* screen2 = "Screen2"; + static const char* h264 = "H.264"; + static const char* unknown = "Unknown"; + + switch (codec_id) { + case 2: return h263; + case 3: return screen; + case 4: return vp6; + case 5: return vp6_alpha; + case 6: return screen2; + case 7: return h264; + default: return unknown; + } + + return unknown; + } + + const char* srs_human_flv_video_avc_packet_type2string(char avc_packet_type) + { + static const char* sps_pps = "SH"; + static const char* nalu = "Nalu"; + static const char* sps_pps_end = "SpsPpsEnd"; + static const char* unknown = "Unknown"; + + switch (avc_packet_type) { + case 0: return sps_pps; + case 1: return nalu; + case 2: return sps_pps_end; + default: return unknown; + } + + return unknown; + } + + const char* srs_human_flv_video_frame_type2string(char frame_type) + { + static const char* keyframe = "I"; + static const char* interframe = "P/B"; + static const char* disposable_interframe = "DI"; + static const char* generated_keyframe = "GI"; + static const char* video_infoframe = "VI"; + static const char* unknown = "Unknown"; + + switch (frame_type) { + case 1: return keyframe; + case 2: return interframe; + case 3: return disposable_interframe; + case 4: return generated_keyframe; + case 5: return video_infoframe; + default: return unknown; + } + + return unknown; + } + + const char* srs_human_flv_audio_sound_format2string(char sound_format) + { + static const char* linear_pcm = "LinearPCM"; + static const char* ad_pcm = "ADPCM"; + static const char* mp3 = "MP3"; + static const char* linear_pcm_le = "LinearPCMLe"; + static const char* nellymoser_16khz = "NellymoserKHz16"; + static const char* nellymoser_8khz = "NellymoserKHz8"; + static const char* nellymoser = "Nellymoser"; + static const char* g711_a_pcm = "G711APCM"; + static const char* g711_mu_pcm = "G711MuPCM"; + static const char* reserved = "Reserved"; + static const char* aac = "AAC"; + static const char* speex = "Speex"; + static const char* mp3_8khz = "MP3KHz8"; + static const char* device_specific = "DeviceSpecific"; + static const char* unknown = "Unknown"; + + switch (sound_format) { + case 0: return linear_pcm; + case 1: return ad_pcm; + case 2: return mp3; + case 3: return linear_pcm_le; + case 4: return nellymoser_16khz; + case 5: return nellymoser_8khz; + case 6: return nellymoser; + case 7: return g711_a_pcm; + case 8: return g711_mu_pcm; + case 9: return reserved; + case 10: return aac; + case 11: return speex; + case 14: return mp3_8khz; + case 15: return device_specific; + default: return unknown; + } + + return unknown; + } + + const char* srs_human_flv_audio_sound_rate2string(char sound_rate) + { + static const char* khz_5_5 = "5.5KHz"; + static const char* khz_11 = "11KHz"; + static const char* khz_22 = "22KHz"; + static const char* khz_44 = "44KHz"; + static const char* unknown = "Unknown"; + + switch (sound_rate) { + case 0: return khz_5_5; + case 1: return khz_11; + case 2: return khz_22; + case 3: return khz_44; + default: return unknown; + } + + return unknown; + } + + const char* srs_human_flv_audio_sound_size2string(char sound_size) + { + static const char* bit_8 = "8bit"; + static const char* bit_16 = "16bit"; + static const char* unknown = "Unknown"; + + switch (sound_size) { + case 0: return bit_8; + case 1: return bit_16; + default: return unknown; + } + + return unknown; + } + + const char* srs_human_flv_audio_sound_type2string(char sound_type) + { + static const char* mono = "Mono"; + static const char* stereo = "Stereo"; + static const char* unknown = "Unknown"; + + switch (sound_type) { + case 0: return mono; + case 1: return stereo; + default: return unknown; + } + + return unknown; + } + + const char* srs_human_flv_audio_aac_packet_type2string(char aac_packet_type) + { + static const char* sps_pps = "SH"; + static const char* raw = "Raw"; + static const char* unknown = "Unknown"; + + switch (aac_packet_type) { + case 0: return sps_pps; + case 1: return raw; + default: return unknown; + } + + return unknown; + } + + int srs_human_format_rtmp_packet(char* buffer, int nb_buffer, char type, uint32_t timestamp, char* data, int size) + { + int ret = ERROR_SUCCESS; + + // Initialize to empty NULL terminated string. + buffer[0] = 0; + + char sbytes[40]; + if (true) { + int nb = srs_min(8, size); + int p = 0; + for (int i = 0; i < nb; i++) { + p += snprintf(sbytes+p, 40-p, "0x%02x ", (uint8_t)data[i]); + } + } + + uint32_t pts; + if ((ret = srs_utils_parse_timestamp(timestamp, type, data, size, &pts)) != ERROR_SUCCESS) { + snprintf(buffer, nb_buffer, "Rtmp packet type=%s, dts=%d, size=%d, DecodeError, (%s), ret=%d", + srs_human_flv_tag_type2string(type), timestamp, size, sbytes, ret); + return ret; + } + + if (type == SRS_RTMP_TYPE_VIDEO) { + snprintf(buffer, nb_buffer, "Video packet type=%s, dts=%d, pts=%d, size=%d, %s(%s,%s), (%s)", + srs_human_flv_tag_type2string(type), timestamp, pts, size, + srs_human_flv_video_codec_id2string(srs_utils_flv_video_codec_id(data, size)), + srs_human_flv_video_avc_packet_type2string(srs_utils_flv_video_avc_packet_type(data, size)), + srs_human_flv_video_frame_type2string(srs_utils_flv_video_frame_type(data, size)), + sbytes); + } else if (type == SRS_RTMP_TYPE_AUDIO) { + snprintf(buffer, nb_buffer, "Audio packet type=%s, dts=%d, pts=%d, size=%d, %s(%s,%s,%s,%s), (%s)", + srs_human_flv_tag_type2string(type), timestamp, pts, size, + srs_human_flv_audio_sound_format2string(srs_utils_flv_audio_sound_format(data, size)), + srs_human_flv_audio_sound_rate2string(srs_utils_flv_audio_sound_rate(data, size)), + srs_human_flv_audio_sound_size2string(srs_utils_flv_audio_sound_size(data, size)), + srs_human_flv_audio_sound_type2string(srs_utils_flv_audio_sound_type(data, size)), + srs_human_flv_audio_aac_packet_type2string(srs_utils_flv_audio_aac_packet_type(data, size)), + sbytes); + } else if (type == SRS_RTMP_TYPE_SCRIPT) { + int nb = snprintf(buffer, nb_buffer, "Data packet type=%s, time=%d, size=%d, (%s)", + srs_human_flv_tag_type2string(type), timestamp, size, sbytes); + int nparsed = 0; + while (nparsed < size) { + int nb_parsed_this = 0; + srs_amf0_t amf0 = srs_amf0_parse(data + nparsed, size - nparsed, &nb_parsed_this); + if (amf0 == NULL) { + break; + } + + nparsed += nb_parsed_this; + + char* amf0_str = NULL; + nb += snprintf(buffer + nb, nb_buffer - nb, "\n%s", srs_human_amf0_print(amf0, &amf0_str, NULL)) - 1; + srs_freepa(amf0_str); + } + buffer[nb] = 0; + } else { + snprintf(buffer, nb_buffer, "Rtmp packet type=%#x, dts=%d, pts=%d, size=%d, (%s)", + type, timestamp, pts, size, sbytes); + } + + return ret; + } + + int srs_human_format_rtmp_packet2(char* buffer, int nb_buffer, char type, uint32_t timestamp, char* data, int size, uint32_t pre_timestamp, int64_t pre_now, int64_t starttime, int64_t nb_packets) + { + int ret = ERROR_SUCCESS; + + // Initialize to empty NULL terminated string. + buffer[0] = 0; + + // packets interval in milliseconds. + double pi = 0; + if (pre_now > starttime) { + pi = (pre_now - starttime) / (double)nb_packets; + } + + // global fps(video and audio mixed fps). + double gfps = 0; + if (pi > 0) { + gfps = 1000 / pi; + } + + int diff = 0; + if (pre_timestamp > 0) { + diff = (int)timestamp - (int)pre_timestamp; + } + + int ndiff = 0; + if (pre_now > 0) { + ndiff = (int)(srs_utils_time_ms() - pre_now); + } + + char sbytes[40]; + if (true) { + int nb = srs_min(8, size); + int p = 0; + for (int i = 0; i < nb; i++) { + p += snprintf(sbytes+p, 40-p, "0x%02x ", (uint8_t)data[i]); + } + } + + uint32_t pts; + if ((ret = srs_utils_parse_timestamp(timestamp, type, data, size, &pts)) != ERROR_SUCCESS) { + snprintf(buffer, nb_buffer, "Rtmp packet id=%"PRId64"/%.1f/%.1f, type=%s, dts=%d, ndiff=%d, diff=%d, size=%d, DecodeError, (%s), ret=%d", + nb_packets, pi, gfps, srs_human_flv_tag_type2string(type), timestamp, ndiff, diff, size, sbytes, ret); + return ret; + } + + if (type == SRS_RTMP_TYPE_VIDEO) { + snprintf(buffer, nb_buffer, "Video packet id=%"PRId64"/%.1f/%.1f, type=%s, dts=%d, pts=%d, ndiff=%d, diff=%d, size=%d, %s(%s,%s), (%s)", + nb_packets, pi, gfps, srs_human_flv_tag_type2string(type), timestamp, pts, ndiff, diff, size, + srs_human_flv_video_codec_id2string(srs_utils_flv_video_codec_id(data, size)), + srs_human_flv_video_avc_packet_type2string(srs_utils_flv_video_avc_packet_type(data, size)), + srs_human_flv_video_frame_type2string(srs_utils_flv_video_frame_type(data, size)), + sbytes); + } else if (type == SRS_RTMP_TYPE_AUDIO) { + snprintf(buffer, nb_buffer, "Audio packet id=%"PRId64"/%.1f/%.1f, type=%s, dts=%d, pts=%d, ndiff=%d, diff=%d, size=%d, %s(%s,%s,%s,%s), (%s)", + nb_packets, pi, gfps, srs_human_flv_tag_type2string(type), timestamp, pts, ndiff, diff, size, + srs_human_flv_audio_sound_format2string(srs_utils_flv_audio_sound_format(data, size)), + srs_human_flv_audio_sound_rate2string(srs_utils_flv_audio_sound_rate(data, size)), + srs_human_flv_audio_sound_size2string(srs_utils_flv_audio_sound_size(data, size)), + srs_human_flv_audio_sound_type2string(srs_utils_flv_audio_sound_type(data, size)), + srs_human_flv_audio_aac_packet_type2string(srs_utils_flv_audio_aac_packet_type(data, size)), + sbytes); + } else if (type == SRS_RTMP_TYPE_SCRIPT) { + int nb = snprintf(buffer, nb_buffer, "Data packet id=%"PRId64"/%.1f/%.1f, type=%s, time=%d, ndiff=%d, diff=%d, size=%d, (%s)", + nb_packets, pi, gfps, srs_human_flv_tag_type2string(type), timestamp, ndiff, diff, size, sbytes); + int nparsed = 0; + while (nparsed < size) { + int nb_parsed_this = 0; + srs_amf0_t amf0 = srs_amf0_parse(data + nparsed, size - nparsed, &nb_parsed_this); + if (amf0 == NULL) { + break; + } + + nparsed += nb_parsed_this; + + char* amf0_str = NULL; + nb += snprintf(buffer + nb, nb_buffer - nb, "\n%s", srs_human_amf0_print(amf0, &amf0_str, NULL)) - 1; + srs_freepa(amf0_str); + } + buffer[nb] = 0; + } else { + snprintf(buffer, nb_buffer, "Rtmp packet id=%"PRId64"/%.1f/%.1f, type=%#x, dts=%d, pts=%d, ndiff=%d, diff=%d, size=%d, (%s)", + nb_packets, pi, gfps, type, timestamp, pts, ndiff, diff, size, sbytes); + } + + return ret; + } + + const char* srs_human_format_time() + { + struct timeval tv; + static char buf[24]; + + memset(buf, 0, sizeof(buf)); + + // clock time + if (gettimeofday(&tv, NULL) == -1) { + return buf; + } + + // to calendar time + struct tm* tm; + if ((tm = localtime((const time_t*)&tv.tv_sec)) == NULL) { + return buf; + } + + snprintf(buf, sizeof(buf), + "%d-%02d-%02d %02d:%02d:%02d.%03d", + 1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, + (int)(tv.tv_usec / 1000)); + + // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 + buf[sizeof(buf) - 1] = 0; + + return buf; + } + + +#ifdef SRS_HIJACK_IO + srs_hijack_io_t srs_hijack_io_get(srs_rtmp_t rtmp) + { + if (!rtmp) { + return NULL; + } + + Context* context = (Context*)rtmp; + if (!context->skt) { + return NULL; + } + + return context->skt->hijack_io(); + } +#endif + + srs_rtmp_t srs_rtmp_create2(const char* url) + { + Context* context = new Context(); + + // use url as tcUrl. + context->url = url; + // auto append stream. + context->url += "/livestream"; + + // create socket + srs_freep(context->skt); + context->skt = new SimpleSocketStream(); + + int ret = ERROR_SUCCESS; + if ((ret = context->skt->create_socket(context)) != ERROR_SUCCESS) { + srs_human_error("Create socket failed, ret=%d", ret); + + // free the context and return NULL + srs_freep(context); + return NULL; + } + + return context; + } + + int srs_rtmp_connect_app2(srs_rtmp_t rtmp, char srs_server_ip[128],char srs_server[128], char srs_primary[128], char srs_authors[128], char srs_version[32], int* srs_id, int* srs_pid) + { + srs_server_ip[0] = 0; + srs_server[0] = 0; + srs_primary[0] = 0; + srs_authors[0] = 0; + srs_version[0] = 0; + *srs_id = 0; + *srs_pid = 0; + + int ret = ERROR_SUCCESS; + + if ((ret = srs_rtmp_connect_app(rtmp)) != ERROR_SUCCESS) { + return ret; + } + + srs_assert(rtmp != NULL); + Context* context = (Context*)rtmp; + SrsServerInfo* si = &context->si; + + snprintf(srs_server_ip, 128, "%s", si->ip.c_str()); + snprintf(srs_server, 128, "%s", si->sig.c_str()); + snprintf(srs_version, 32, "%d.%d.%d.%d", si->major, si->minor, si->revision, si->build); + + return ret; + } + + int srs_human_print_rtmp_packet(char type, uint32_t timestamp, char* data, int size) + { + return srs_human_print_rtmp_packet3(type, timestamp, data, size, 0, 0); + } + + int srs_human_print_rtmp_packet2(char type, uint32_t timestamp, char* data, int size, uint32_t pre_timestamp) + { + return srs_human_print_rtmp_packet3(type, timestamp, data, size, pre_timestamp, 0); + } + + int srs_human_print_rtmp_packet3(char type, uint32_t timestamp, char* data, int size, uint32_t pre_timestamp, int64_t pre_now) + { + return srs_human_print_rtmp_packet4(type, timestamp, data, size, pre_timestamp, pre_now, 0, 0); + } + + int srs_human_print_rtmp_packet4(char type, uint32_t timestamp, char* data, int size, uint32_t pre_timestamp, int64_t pre_now, + int64_t starttime, int64_t nb_packets + ) { + char buffer[1024]; + int ret = srs_human_format_rtmp_packet2(buffer, sizeof(buffer), type, timestamp, data, size, pre_timestamp, pre_now, starttime, nb_packets); + srs_human_trace("%s", buffer); + return ret; + } -int srs_human_print_rtmp_packet(char type, uint32_t timestamp, char* data, int size) -{ - return srs_human_print_rtmp_packet3(type, timestamp, data, size, 0, 0); -} - -int srs_human_print_rtmp_packet2(char type, uint32_t timestamp, char* data, int size, uint32_t pre_timestamp) -{ - return srs_human_print_rtmp_packet3(type, timestamp, data, size, pre_timestamp, 0); -} - -int srs_human_print_rtmp_packet3(char type, uint32_t timestamp, char* data, int size, uint32_t pre_timestamp, int64_t pre_now) -{ - return srs_human_print_rtmp_packet4(type, timestamp, data, size, pre_timestamp, pre_now, 0, 0); -} - -int srs_human_print_rtmp_packet4(char type, uint32_t timestamp, char* data, int size, uint32_t pre_timestamp, int64_t pre_now, int64_t starttime, int64_t nb_packets) -{ - char buffer[1024]; - int ret = srs_human_format_rtmp_packet2(buffer, sizeof(buffer), type, timestamp, data, size, pre_timestamp, pre_now, starttime, nb_packets); - srs_human_trace("%s", buffer); - return ret; -} - #ifdef __cplusplus } #endif diff --git a/trunk/src/libs/srs_librtmp.hpp b/trunk/src/libs/srs_librtmp.hpp index fe5fe43a5..be6fea719 100644 --- a/trunk/src/libs/srs_librtmp.hpp +++ b/trunk/src/libs/srs_librtmp.hpp @@ -1,72 +1,68 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_LIB_RTMP_HPP #define SRS_LIB_RTMP_HPP -/* -#include -*/ - /** -* srs-librtmp is a librtmp like library, -* used to play/publish rtmp stream from/to rtmp server. -* socket: use sync and block socket to connect/recv/send data with server. -* depends: no need other libraries; depends on ssl if use srs_complex_handshake. -* thread-safe: no -*/ + * srs-librtmp is a librtmp like library, + * used to play/publish rtmp stream from/to rtmp server. + * socket: use sync and block socket to connect/recv/send data with server. + * depends: no need other libraries; depends on ssl if use srs_complex_handshake. + * thread-safe: no + */ /************************************************************* -************************************************************** -* Windows SRS-LIBRTMP pre-declare -************************************************************** -*************************************************************/ + ************************************************************** + * Windows SRS-LIBRTMP pre-declare + ************************************************************** + *************************************************************/ // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 #ifdef _WIN32 - // include windows first. - #include - // the type used by this header for windows. - typedef unsigned long long u_int64_t; - typedef u_int64_t uint64_t; - typedef long long int64_t; - typedef unsigned int u_int32_t; - typedef u_int32_t uint32_t; - typedef int int32_t; - typedef unsigned char u_int8_t; - typedef u_int8_t uint8_t; - typedef char int8_t; - typedef unsigned short u_int16_t; - typedef u_int16_t uint16_t; - typedef short int16_t; - typedef int64_t ssize_t; - struct iovec { - void *iov_base; /* Starting address */ - size_t iov_len; /* Number of bytes to transfer */ - }; +// include windows first. +#include +// the type used by this header for windows. +typedef unsigned long long u_int64_t; +typedef u_int64_t uint64_t; +typedef long long int64_t; +typedef unsigned int u_int32_t; +typedef u_int32_t uint32_t; +typedef int int32_t; +typedef unsigned char u_int8_t; +typedef u_int8_t uint8_t; +typedef char int8_t; +typedef unsigned short u_int16_t; +typedef u_int16_t uint16_t; +typedef short int16_t; +typedef int64_t ssize_t; +struct iovec { + void *iov_base; /* Starting address */ + size_t iov_len; /* Number of bytes to transfer */ +}; - // for pid. - typedef int pid_t; - pid_t getpid(void); +// for pid. +typedef int pid_t; +pid_t getpid(void); #endif #include @@ -75,1038 +71,1018 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef __cplusplus extern "C"{ #endif - -/** -* The schema of RTMP url, the following are legal urls: -* srs_url_schema_normal: rtmp://vhost:port/app/stream -* srs_url_schema_via : rtmp://ip:port/vhost/app/stream -* srs_url_schema_vis : rtmp://ip:port/app/stream?vhost=xxx -* srs_url_schema_vis2 : rtmp://ip:port/app/stream?domain=xxx -*/ -enum srs_url_schema -{ - // Forbidden. - srs_url_schema_forbidden = 0, - // Normal RTMP URL, the vhost put in host field, using DNS to resolve the server ip. - // For example, rtmp://vhost:port/app/stream - srs_url_schema_normal, - // VIA(vhost in app), the vhost put in app field. - // For example, rtmp://ip:port/vhost/app/stream - srs_url_schema_via, - // VIS(vhost in stream), the vhost put in query string, keyword use vhost=xxx. - // For example, rtmp://ip:port/app/stream?vhost=xxx - srs_url_schema_vis, - // VIS, keyword use domain=xxx. - // For example, rtmp://ip:port/app/stream?domain=xxx - srs_url_schema_vis2 -}; - -// typedefs -typedef int srs_bool; - -/************************************************************* -************************************************************** -* srs-librtmp version -************************************************************** -*************************************************************/ -extern int srs_version_major(); -extern int srs_version_minor(); -extern int srs_version_revision(); - -/************************************************************* -************************************************************** -* RTMP protocol context -************************************************************** -*************************************************************/ -// the RTMP handler. -typedef void* srs_rtmp_t; -typedef void* srs_amf0_t; -/** - * Create a RTMP handler. - * @param url The RTMP url, for example, rtmp://localhost/live/livestream - * @remark default timeout to 30s if not set by srs_rtmp_set_timeout. - * @remark default schema to srs_url_schema_normal, use srs_rtmp_set_schema to change it. - * - * @return a rtmp handler, or NULL if error occured. - */ -extern srs_rtmp_t srs_rtmp_create(const char* url); -/** - * set socket timeout - * @param recv_timeout_ms the timeout for receiving messages in ms. - * @param send_timeout_ms the timeout for sending message in ms. - * @remark user can set timeout once srs_rtmp_create/srs_rtmp_create2, - * or before srs_rtmp_handshake or srs_rtmp_dns_resolve to connect to server. - * @remark default timeout to 30s if not set by srs_rtmp_set_timeout. - * - * @return 0, success; otherswise, failed. - */ -extern int srs_rtmp_set_timeout(srs_rtmp_t rtmp, int recv_timeout_ms, int send_timeout_ms); -/** -* close and destroy the rtmp stack. -* @remark, user should never use the rtmp again. -*/ -extern void srs_rtmp_destroy(srs_rtmp_t rtmp); - -/************************************************************* -************************************************************** -* RTMP protocol stack -************************************************************** -*************************************************************/ -/** -* connect and handshake with server -* category: publish/play -* previous: rtmp-create -* next: connect-app -* -* @return 0, success; otherswise, failed. -*/ -/** -* simple handshake specifies in rtmp 1.0, -* not depends on ssl. -*/ -/** -* srs_rtmp_handshake equals to invoke: -* srs_rtmp_dns_resolve() -* srs_rtmp_connect_server() -* srs_rtmp_do_simple_handshake() -* user can use these functions if needed. -*/ -extern int srs_rtmp_handshake(srs_rtmp_t rtmp); -// parse uri, create socket, resolve host -extern int srs_rtmp_dns_resolve(srs_rtmp_t rtmp); -// connect socket to server -extern int srs_rtmp_connect_server(srs_rtmp_t rtmp); -// do simple handshake over socket. -extern int srs_rtmp_do_simple_handshake(srs_rtmp_t rtmp); -// do complex handshake over socket. -extern int srs_rtmp_do_complex_handshake(srs_rtmp_t rtmp); - -/** -* set the args of connect packet for rtmp. -* @param args, the extra amf0 object args. -* @remark, all params can be NULL to ignore. -* @remark, user should never free the args for we directly use it. -*/ -extern int srs_rtmp_set_connect_args(srs_rtmp_t rtmp, - const char* tcUrl, const char* swfUrl, const char* pageUrl, srs_amf0_t args -); + /** + * The schema of RTMP url, the following are legal urls: + * srs_url_schema_normal: rtmp://vhost:port/app/stream + * srs_url_schema_via : rtmp://ip:port/vhost/app/stream + * srs_url_schema_vis : rtmp://ip:port/app/stream?vhost=xxx + * srs_url_schema_vis2 : rtmp://ip:port/app/stream?domain=xxx + */ + enum srs_url_schema + { + // Forbidden. + srs_url_schema_forbidden = 0, + // Normal RTMP URL, the vhost put in host field, using DNS to resolve the server ip. + // For example, rtmp://vhost:port/app/stream + srs_url_schema_normal, + // VIA(vhost in app), the vhost put in app field. + // For example, rtmp://ip:port/vhost/app/stream + srs_url_schema_via, + // VIS(vhost in stream), the vhost put in query string, keyword use vhost=xxx. + // For example, rtmp://ip:port/app/stream?vhost=xxx + srs_url_schema_vis, + // VIS, keyword use domain=xxx. + // For example, rtmp://ip:port/app/stream?domain=xxx + srs_url_schema_vis2 + }; -/** - * Set the schema of URL when connect to tcUrl by srs_rtmp_connect_app. - * @param schema, The schema of URL, @see srs_url_schema. - * @return 0, success; otherswise, failed. - */ -extern int srs_rtmp_set_schema(srs_rtmp_t rtmp, enum srs_url_schema schema); + // typedefs + typedef int srs_bool; -/** - * Connect to RTMP tcUrl(Vhost/App), similar to flash AS3 NetConnection.connect(tcUrl). - * @remark When connected to server, user can retrieve informations from RTMP handler, - * for example, use srs_rtmp_get_server_id to get server ip/pid/cid. - * @return 0, success; otherswise, failed. - */ -extern int srs_rtmp_connect_app(srs_rtmp_t rtmp); + /************************************************************* + ************************************************************** + * srs-librtmp version + ************************************************************** + *************************************************************/ + extern int srs_version_major(); + extern int srs_version_minor(); + extern int srs_version_revision(); -/** - * Retrieve server ip from RTMP handler. - * @Param ip A NULL terminated string specifies the server ip. - * @Param pid An int specifies the PID of server. -1 is no PID information. - * @Param cid An int specifies the CID of connection. -1 is no CID information. - * @remark For SRS, ip/pid/cid is the UUID of a client. For other server, these values maybe unknown. - * @remark When connected to server by srs_rtmp_connect_app, the information is ready to be retrieved. - * @return 0, success; otherswise, failed. - */ -extern int srs_rtmp_get_server_id(srs_rtmp_t rtmp, char** ip, int* pid, int* cid); + /************************************************************* + ************************************************************** + * RTMP protocol context + ************************************************************** + *************************************************************/ + // the RTMP handler. + typedef void* srs_rtmp_t; + typedef void* srs_amf0_t; -/** - * Retrieve server signature from RTMP handler. - * @Param sig A NULL terminated string specifies the server signature. - * @remark When connected to server by srs_rtmp_connect_app, the information is ready to be retrieved. - * @return 0, success; otherswise, failed. - */ -extern int srs_rtmp_get_server_sig(srs_rtmp_t rtmp, char** sig); + /** + * Create a RTMP handler. + * @param url The RTMP url, for example, rtmp://localhost/live/livestream + * @remark default timeout to 30s if not set by srs_rtmp_set_timeout. + * @remark default schema to srs_url_schema_normal, use srs_rtmp_set_schema to change it. + * + * @return a rtmp handler, or NULL if error occured. + */ + extern srs_rtmp_t srs_rtmp_create(const char* url); + /** + * set socket timeout + * @param recv_timeout_ms the timeout for receiving messages in ms. + * @param send_timeout_ms the timeout for sending message in ms. + * @remark user can set timeout once srs_rtmp_create/srs_rtmp_create2, + * or before srs_rtmp_handshake or srs_rtmp_dns_resolve to connect to server. + * @remark default timeout to 30s if not set by srs_rtmp_set_timeout. + * + * @return 0, success; otherswise, failed. + */ + extern int srs_rtmp_set_timeout(srs_rtmp_t rtmp, int recv_timeout_ms, int send_timeout_ms); + /** + * close and destroy the rtmp stack. + * @remark, user should never use the rtmp again. + */ + extern void srs_rtmp_destroy(srs_rtmp_t rtmp); -/** - * Retrieve server version from RTMP handler, which in major.minor.revision.build format. - * @remark When connected to server by srs_rtmp_connect_app, the information is ready to be retrieved. - * @return 0, success; otherswise, failed. - */ -extern int srs_rtmp_get_server_version(srs_rtmp_t rtmp, int* major, int* minor, int* revision, int* build); - -/** -* play a live/vod stream. -* category: play -* previous: connect-app -* next: destroy -* @return 0, success; otherwise, failed. -*/ -extern int srs_rtmp_play_stream(srs_rtmp_t rtmp); - -/** -* publish a live stream. -* category: publish -* previous: connect-app -* next: destroy -* @return 0, success; otherwise, failed. -*/ -extern int srs_rtmp_publish_stream(srs_rtmp_t rtmp); - -/** -* do bandwidth check with srs server. -* -* bandwidth info: -* @param start_time, output the start time, in ms. -* @param end_time, output the end time, in ms. -* @param play_kbps, output the play/download kbps. -* @param publish_kbps, output the publish/upload kbps. -* @param play_bytes, output the play/download bytes. -* @param publish_bytes, output the publish/upload bytes. -* @param play_duration, output the play/download test duration, in ms. -* @param publish_duration, output the publish/upload test duration, in ms. -* -* @return 0, success; otherswise, failed. -*/ -extern int srs_rtmp_bandwidth_check(srs_rtmp_t rtmp, - int64_t* start_time, int64_t* end_time, - int* play_kbps, int* publish_kbps, - int* play_bytes, int* publish_bytes, - int* play_duration, int* publish_duration -); - -/** -* E.4.1 FLV Tag, page 75 -*/ -// 8 = audio + /************************************************************* + ************************************************************** + * RTMP protocol stack + ************************************************************** + *************************************************************/ + /** + * connect and handshake with server + * category: publish/play + * previous: rtmp-create + * next: connect-app + * + * @return 0, success; otherswise, failed. + */ + /** + * simple handshake specifies in rtmp 1.0, + * not depends on ssl. + */ + /** + * srs_rtmp_handshake equals to invoke: + * srs_rtmp_dns_resolve() + * srs_rtmp_connect_server() + * srs_rtmp_do_simple_handshake() + * user can use these functions if needed. + */ + extern int srs_rtmp_handshake(srs_rtmp_t rtmp); + // parse uri, create socket, resolve host + extern int srs_rtmp_dns_resolve(srs_rtmp_t rtmp); + // connect socket to server + extern int srs_rtmp_connect_server(srs_rtmp_t rtmp); + // do simple handshake over socket. + extern int srs_rtmp_do_simple_handshake(srs_rtmp_t rtmp); + // do complex handshake over socket. + extern int srs_rtmp_do_complex_handshake(srs_rtmp_t rtmp); + + /** + * set the args of connect packet for rtmp. + * @param args, the extra amf0 object args. + * @remark, all params can be NULL to ignore. + * @remark, user should never free the args for we directly use it. + */ + extern int srs_rtmp_set_connect_args(srs_rtmp_t rtmp, const char* tcUrl, const char* swfUrl, const char* pageUrl, srs_amf0_t args); + + /** + * Set the schema of URL when connect to tcUrl by srs_rtmp_connect_app. + * @param schema, The schema of URL, @see srs_url_schema. + * @return 0, success; otherswise, failed. + */ + extern int srs_rtmp_set_schema(srs_rtmp_t rtmp, enum srs_url_schema schema); + + /** + * Connect to RTMP tcUrl(Vhost/App), similar to flash AS3 NetConnection.connect(tcUrl). + * @remark When connected to server, user can retrieve informations from RTMP handler, + * for example, use srs_rtmp_get_server_id to get server ip/pid/cid. + * @return 0, success; otherswise, failed. + */ + extern int srs_rtmp_connect_app(srs_rtmp_t rtmp); + + /** + * Retrieve server ip from RTMP handler. + * @Param ip A NULL terminated string specifies the server ip. + * @Param pid An int specifies the PID of server. -1 is no PID information. + * @Param cid An int specifies the CID of connection. -1 is no CID information. + * @remark For SRS, ip/pid/cid is the UUID of a client. For other server, these values maybe unknown. + * @remark When connected to server by srs_rtmp_connect_app, the information is ready to be retrieved. + * @return 0, success; otherswise, failed. + */ + extern int srs_rtmp_get_server_id(srs_rtmp_t rtmp, char** ip, int* pid, int* cid); + + /** + * Retrieve server signature from RTMP handler. + * @Param sig A NULL terminated string specifies the server signature. + * @remark When connected to server by srs_rtmp_connect_app, the information is ready to be retrieved. + * @return 0, success; otherswise, failed. + */ + extern int srs_rtmp_get_server_sig(srs_rtmp_t rtmp, char** sig); + + /** + * Retrieve server version from RTMP handler, which in major.minor.revision.build format. + * @remark When connected to server by srs_rtmp_connect_app, the information is ready to be retrieved. + * @return 0, success; otherswise, failed. + */ + extern int srs_rtmp_get_server_version(srs_rtmp_t rtmp, int* major, int* minor, int* revision, int* build); + + /** + * play a live/vod stream. + * category: play + * previous: connect-app + * next: destroy + * @return 0, success; otherwise, failed. + */ + extern int srs_rtmp_play_stream(srs_rtmp_t rtmp); + + /** + * publish a live stream. + * category: publish + * previous: connect-app + * next: destroy + * @return 0, success; otherwise, failed. + */ + extern int srs_rtmp_publish_stream(srs_rtmp_t rtmp); + + /** + * do bandwidth check with srs server. + * + * bandwidth info: + * @param start_time, output the start time, in ms. + * @param end_time, output the end time, in ms. + * @param play_kbps, output the play/download kbps. + * @param publish_kbps, output the publish/upload kbps. + * @param play_bytes, output the play/download bytes. + * @param publish_bytes, output the publish/upload bytes. + * @param play_duration, output the play/download test duration, in ms. + * @param publish_duration, output the publish/upload test duration, in ms. + * + * @return 0, success; otherswise, failed. + */ + extern int srs_rtmp_bandwidth_check(srs_rtmp_t rtmp, + int64_t* start_time, int64_t* end_time, + int* play_kbps, int* publish_kbps, + int* play_bytes, int* publish_bytes, + int* play_duration, int* publish_duration); + + /** + * E.4.1 FLV Tag, page 75 + */ + // 8 = audio #define SRS_RTMP_TYPE_AUDIO 8 -// 9 = video + // 9 = video #define SRS_RTMP_TYPE_VIDEO 9 -// 18 = script data + // 18 = script data #define SRS_RTMP_TYPE_SCRIPT 18 -/** -* read a audio/video/script-data packet from rtmp stream. -* @param type, output the packet type, macros: -* SRS_RTMP_TYPE_AUDIO, FlvTagAudio -* SRS_RTMP_TYPE_VIDEO, FlvTagVideo -* SRS_RTMP_TYPE_SCRIPT, FlvTagScript -* otherswise, invalid type. -* @param timestamp, in ms, overflow in 50days -* @param data, the packet data, according to type: -* FlvTagAudio, @see "E.4.2.1 AUDIODATA" -* FlvTagVideo, @see "E.4.3.1 VIDEODATA" -* FlvTagScript, @see "E.4.4.1 SCRIPTDATA" -* User can free the packet by srs_rtmp_free_packet. -* @param size, size of packet. -* @return the error code. 0 for success; otherwise, error. -* -* @remark: for read, user must free the data. -* @remark: for write, user should never free the data, even if error. -* @example /trunk/research/librtmp/srs_play.c -* @example /trunk/research/librtmp/srs_publish.c -* -* @return 0, success; otherswise, failed. -*/ -extern int srs_rtmp_read_packet(srs_rtmp_t rtmp, - char* type, uint32_t* timestamp, char** data, int* size -); -// @Param data User should never free it anymore. -extern int srs_rtmp_write_packet(srs_rtmp_t rtmp, - char type, uint32_t timestamp, char* data, int size -); + /** + * read a audio/video/script-data packet from rtmp stream. + * @param type, output the packet type, macros: + * SRS_RTMP_TYPE_AUDIO, FlvTagAudio + * SRS_RTMP_TYPE_VIDEO, FlvTagVideo + * SRS_RTMP_TYPE_SCRIPT, FlvTagScript + * otherswise, invalid type. + * @param timestamp, in ms, overflow in 50days + * @param data, the packet data, according to type: + * FlvTagAudio, @see "E.4.2.1 AUDIODATA" + * FlvTagVideo, @see "E.4.3.1 VIDEODATA" + * FlvTagScript, @see "E.4.4.1 SCRIPTDATA" + * User can free the packet by srs_rtmp_free_packet. + * @param size, size of packet. + * @return the error code. 0 for success; otherwise, error. + * + * @remark: for read, user must free the data. + * @remark: for write, user should never free the data, even if error. + * @example /trunk/research/librtmp/srs_play.c + * @example /trunk/research/librtmp/srs_publish.c + * + * @return 0, success; otherswise, failed. + */ + extern int srs_rtmp_read_packet(srs_rtmp_t rtmp, char* type, uint32_t* timestamp, char** data, int* size); + // @Param data User should never free it anymore. + extern int srs_rtmp_write_packet(srs_rtmp_t rtmp, char type, uint32_t timestamp, char* data, int size); -/** - * Free the packet allocated by srs_rtmp_read_packet. - */ -extern void srs_rtmp_free_packet(char* data); - -/** -* whether type is script data and the data is onMetaData. -*/ -extern srs_bool srs_rtmp_is_onMetaData(char type, char* data, int size); - -/************************************************************* -************************************************************** -* audio raw codec -************************************************************** -*************************************************************/ -/** -* write an audio raw frame to srs. -* not similar to h.264 video, the audio never aggregated, always -* encoded one frame by one, so this api is used to write a frame. -* -* @param sound_format Format of SoundData. The following values are defined: -* 0 = Linear PCM, platform endian -* 1 = ADPCM -* 2 = MP3 -* 3 = Linear PCM, little endian -* 4 = Nellymoser 16 kHz mono -* 5 = Nellymoser 8 kHz mono -* 6 = Nellymoser -* 7 = G.711 A-law logarithmic PCM -* 8 = G.711 mu-law logarithmic PCM -* 9 = reserved -* 10 = AAC -* 11 = Speex -* 14 = MP3 8 kHz -* 15 = Device-specific sound -* Formats 7, 8, 14, and 15 are reserved. -* AAC is supported in Flash Player 9,0,115,0 and higher. -* Speex is supported in Flash Player 10 and higher. -* @param sound_rate Sampling rate. The following values are defined: -* 0 = 5.5 kHz -* 1 = 11 kHz -* 2 = 22 kHz -* 3 = 44 kHz -* @param sound_size Size of each audio sample. This parameter only pertains to -* uncompressed formats. Compressed formats always decode -* to 16 bits internally. -* 0 = 8-bit samples -* 1 = 16-bit samples -* @param sound_type Mono or stereo sound -* 0 = Mono sound -* 1 = Stereo sound -* @param timestamp The timestamp of audio. -* -* @example /trunk/research/librtmp/srs_aac_raw_publish.c -* @example /trunk/research/librtmp/srs_audio_raw_publish.c -* -* @remark for aac, the frame must be in ADTS format. -* @see ISO_IEC_14496-3-AAC-2001.pdf, page 75, 1.A.2.2 ADTS -* @remark for aac, only support profile 1-4, AAC main/LC/SSR/LTP, -* @see ISO_IEC_14496-3-AAC-2001.pdf, page 23, 1.5.1.1 Audio object type -* -* @see https://github.com/ossrs/srs/issues/212 -* @see E.4.2.1 AUDIODATA of video_file_format_spec_v10_1.pdf -* -* @return 0, success; otherswise, failed. -*/ -extern int srs_audio_write_raw_frame(srs_rtmp_t rtmp, - char sound_format, char sound_rate, char sound_size, char sound_type, - char* frame, int frame_size, uint32_t timestamp -); - -/** -* whether aac raw data is in adts format, -* which bytes sequence matches '1111 1111 1111'B, that is 0xFFF. -* @param aac_raw_data the input aac raw data, a encoded aac frame data. -* @param ac_raw_size the size of aac raw data. -* -* @reamrk used to check whether current frame is in adts format. -* @see ISO_IEC_14496-3-AAC-2001.pdf, page 75, 1.A.2.2 ADTS -* @example /trunk/research/librtmp/srs_aac_raw_publish.c -* -* @return 0 false; otherwise, true. -*/ -extern srs_bool srs_aac_is_adts(char* aac_raw_data, int ac_raw_size); - -/** -* parse the adts header to get the frame size, -* which bytes sequence matches '1111 1111 1111'B, that is 0xFFF. -* @param aac_raw_data the input aac raw data, a encoded aac frame data. -* @param ac_raw_size the size of aac raw data. -* -* @return failed when <=0 failed; otherwise, ok. -*/ -extern int srs_aac_adts_frame_size(char* aac_raw_data, int ac_raw_size); - -/************************************************************* -************************************************************** -* h264 raw codec -************************************************************** -*************************************************************/ -/** -* write h.264 raw frame over RTMP to rtmp server. -* @param frames the input h264 raw data, encoded h.264 I/P/B frames data. -* frames can be one or more than one frame, -* each frame prefixed h.264 annexb header, by N[00] 00 00 01, where N>=0, -* for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40) -* about annexb, @see ISO_IEC_14496-10-AVC-2003.pdf, page 211. -* @param frames_size the size of h264 raw data. -* assert frames_size > 0, at least has 1 bytes header. -* @param dts the dts of h.264 raw data. -* @param pts the pts of h.264 raw data. -* -* @remark, user should free the frames. -* @remark, the tbn of dts/pts is 1/1000 for RTMP, that is, in ms. -* @remark, cts = pts - dts -* @remark, use srs_h264_startswith_annexb to check whether frame is annexb format. -* @example /trunk/research/librtmp/srs_h264_raw_publish.c -* @see https://github.com/ossrs/srs/issues/66 -* -* @return 0, success; otherswise, failed. -* for dvbsp error, @see srs_h264_is_dvbsp_error(). -* for duplictated sps error, @see srs_h264_is_duplicated_sps_error(). -* for duplictated pps error, @see srs_h264_is_duplicated_pps_error(). -*/ -/** -For the example file: - http://winlinvip.github.io/srs.release/3rdparty/720p.h264.raw -The data sequence is: - // SPS - 000000016742802995A014016E40 - // PPS - 0000000168CE3880 - // IFrame - 0000000165B8041014C038008B0D0D3A071..... - // PFrame - 0000000141E02041F8CDDC562BBDEFAD2F..... -User can send the SPS+PPS, then each frame: - // SPS+PPS - srs_h264_write_raw_frames('000000016742802995A014016E400000000168CE3880', size, dts, pts) - // IFrame - srs_h264_write_raw_frames('0000000165B8041014C038008B0D0D3A071......', size, dts, pts) - // PFrame - srs_h264_write_raw_frames('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts) -User also can send one by one: - // SPS - srs_h264_write_raw_frames('000000016742802995A014016E4', size, dts, pts) - // PPS - srs_h264_write_raw_frames('00000000168CE3880', size, dts, pts) - // IFrame - srs_h264_write_raw_frames('0000000165B8041014C038008B0D0D3A071......', size, dts, pts) - // PFrame - srs_h264_write_raw_frames('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts) -*/ -extern int srs_h264_write_raw_frames(srs_rtmp_t rtmp, - char* frames, int frames_size, uint32_t dts, uint32_t pts -); -/** -* whether error_code is dvbsp(drop video before sps/pps/sequence-header) error. -* -* @see https://github.com/ossrs/srs/issues/203 -* @example /trunk/research/librtmp/srs_h264_raw_publish.c -* @remark why drop video? -* some encoder, for example, ipcamera, will send sps/pps before each IFrame, -* so, when error and reconnect the rtmp, the first video is not sps/pps(sequence header), -* this will cause SRS server to disable HLS. -*/ -extern srs_bool srs_h264_is_dvbsp_error(int error_code); -/** -* whether error_code is duplicated sps error. -* -* @see https://github.com/ossrs/srs/issues/204 -* @example /trunk/research/librtmp/srs_h264_raw_publish.c -*/ -extern srs_bool srs_h264_is_duplicated_sps_error(int error_code); -/** -* whether error_code is duplicated pps error. -* -* @see https://github.com/ossrs/srs/issues/204 -* @example /trunk/research/librtmp/srs_h264_raw_publish.c -*/ -extern srs_bool srs_h264_is_duplicated_pps_error(int error_code); -/** -* whether h264 raw data starts with the annexb, -* which bytes sequence matches N[00] 00 00 01, where N>=0. -* @param h264_raw_data the input h264 raw data, a encoded h.264 I/P/B frame data. -* @paam h264_raw_size the size of h264 raw data. -* @param pnb_start_code output the size of start code, must >=3. -* NULL to ignore. -* -* @reamrk used to check whether current frame is in annexb format. -* @example /trunk/research/librtmp/srs_h264_raw_publish.c -* -* @return 0 false; otherwise, true. -*/ -extern srs_bool srs_h264_startswith_annexb( - char* h264_raw_data, int h264_raw_size, - int* pnb_start_code -); + /** + * Free the packet allocated by srs_rtmp_read_packet. + */ + extern void srs_rtmp_free_packet(char* data); -/************************************************************* - ************************************************************* - * MP4 muxer and demuxer. - * @example /trunk/research/librtmp/srs_ingest_mp4.c - ************************************************************* - *************************************************************/ -typedef void* srs_mp4_t; -// The sample struct of mp4. -typedef struct { - // The handler type, it's SrsMp4HandlerType. - uint32_t handler_type; + /** + * whether type is script data and the data is onMetaData. + */ + extern srs_bool srs_rtmp_is_onMetaData(char type, char* data, int size); - // The dts in milliseconds. - uint32_t dts; - // The codec id. - // video: SrsVideoCodecId. - // audio: SrsAudioCodecId. - uint16_t codec; - // The frame trait, some characteristic: - // video: SrsVideoAvcFrameTrait. - // audio: SrsAudioAacFrameTrait. - uint16_t frame_trait; + /************************************************************* + ************************************************************** + * audio raw codec + ************************************************************** + *************************************************************/ + /** + * write an audio raw frame to srs. + * not similar to h.264 video, the audio never aggregated, always + * encoded one frame by one, so this api is used to write a frame. + * + * @param sound_format Format of SoundData. The following values are defined: + * 0 = Linear PCM, platform endian + * 1 = ADPCM + * 2 = MP3 + * 3 = Linear PCM, little endian + * 4 = Nellymoser 16 kHz mono + * 5 = Nellymoser 8 kHz mono + * 6 = Nellymoser + * 7 = G.711 A-law logarithmic PCM + * 8 = G.711 mu-law logarithmic PCM + * 9 = reserved + * 10 = AAC + * 11 = Speex + * 14 = MP3 8 kHz + * 15 = Device-specific sound + * Formats 7, 8, 14, and 15 are reserved. + * AAC is supported in Flash Player 9,0,115,0 and higher. + * Speex is supported in Flash Player 10 and higher. + * @param sound_rate Sampling rate. The following values are defined: + * 0 = 5.5 kHz + * 1 = 11 kHz + * 2 = 22 kHz + * 3 = 44 kHz + * @param sound_size Size of each audio sample. This parameter only pertains to + * uncompressed formats. Compressed formats always decode + * to 16 bits internally. + * 0 = 8-bit samples + * 1 = 16-bit samples + * @param sound_type Mono or stereo sound + * 0 = Mono sound + * 1 = Stereo sound + * @param timestamp The timestamp of audio. + * + * @example /trunk/research/librtmp/srs_aac_raw_publish.c + * @example /trunk/research/librtmp/srs_audio_raw_publish.c + * + * @remark for aac, the frame must be in ADTS format. + * @see ISO_IEC_14496-3-AAC-2001.pdf, page 75, 1.A.2.2 ADTS + * @remark for aac, only support profile 1-4, AAC main/LC/SSR/LTP, + * @see ISO_IEC_14496-3-AAC-2001.pdf, page 23, 1.5.1.1 Audio object type + * + * @see https://github.com/ossrs/srs/issues/212 + * @see E.4.2.1 AUDIODATA of video_file_format_spec_v10_1.pdf + * + * @return 0, success; otherswise, failed. + */ + extern int srs_audio_write_raw_frame(srs_rtmp_t rtmp, + char sound_format, char sound_rate, char sound_size, char sound_type, + char* frame, int frame_size, uint32_t timestamp); - // The video pts in milliseconds. Ignore for audio. - uint32_t pts; - // The video frame type, it's SrsVideoAvcFrameType. - uint16_t frame_type; + /** + * whether aac raw data is in adts format, + * which bytes sequence matches '1111 1111 1111'B, that is 0xFFF. + * @param aac_raw_data the input aac raw data, a encoded aac frame data. + * @param ac_raw_size the size of aac raw data. + * + * @reamrk used to check whether current frame is in adts format. + * @see ISO_IEC_14496-3-AAC-2001.pdf, page 75, 1.A.2.2 ADTS + * @example /trunk/research/librtmp/srs_aac_raw_publish.c + * + * @return 0 false; otherwise, true. + */ + extern srs_bool srs_aac_is_adts(char* aac_raw_data, int ac_raw_size); - // The audio sample rate, it's SrsAudioSampleRate. - uint8_t sample_rate; - // The audio sound bits, it's SrsAudioSampleBits. - uint8_t sound_bits; - // The audio sound type, it's SrsAudioChannels. - uint8_t channels; + /** + * parse the adts header to get the frame size, + * which bytes sequence matches '1111 1111 1111'B, that is 0xFFF. + * @param aac_raw_data the input aac raw data, a encoded aac frame data. + * @param ac_raw_size the size of aac raw data. + * + * @return failed when <=0 failed; otherwise, ok. + */ + extern int srs_aac_adts_frame_size(char* aac_raw_data, int ac_raw_size); - // The size of sample payload in bytes. - uint32_t nb_sample; - // The output sample data, user must free it by srs_mp4_free_sample. - uint8_t* sample; -} srs_mp4_sample_t; -/** - * Open mp4 file for muxer(write) or demuxer(read). - * @return A MP4 demuxer, NULL if failed. - */ -extern srs_mp4_t srs_mp4_open_read(const char* file); -/** - * Close the MP4 demuxer. - */ -extern void srs_mp4_close(srs_mp4_t mp4); -/** - * Initialize mp4 demuxer in non-seek mode. - * @remark Only support non-seek mode, that is fmp4 or moov before mdata. - * For the live streaming, we must feed stream frame by frame. - */ -extern int srs_mp4_init_demuxer(srs_mp4_t mp4); -/** - * Read a sample form mp4. - * @remark User can use srs_mp4_sample_to_flv_tag to convert mp4 sampel to flv tag. - * Use the srs_mp4_to_flv_tag_size to calc the flv tag data size to alloc. - */ -extern int srs_mp4_read_sample(srs_mp4_t mp4, srs_mp4_sample_t* sample); -/** - * Free the allocated mp4 sample. - */ -extern void srs_mp4_free_sample(srs_mp4_sample_t* sample); -/** - * Calc the size of flv tag, for the mp4 sample to convert to. - */ -extern int32_t srs_mp4_sizeof(srs_mp4_t mp4, srs_mp4_sample_t* sample); -/** - * Covert mp4 sample to flv tag. - */ -extern int srs_mp4_to_flv_tag(srs_mp4_t mp4, srs_mp4_sample_t* sample, char* type, uint32_t* time, char* data, int32_t size); -/* error code */ -/* whether the error code indicates EOF */ -extern srs_bool srs_mp4_is_eof(int error_code); - -/************************************************************* -************************************************************** -* flv codec -* @example /trunk/research/librtmp/srs_flv_injecter.c -* @example /trunk/research/librtmp/srs_flv_parser.c -* @example /trunk/research/librtmp/srs_ingest_flv.c -* @example /trunk/research/librtmp/srs_ingest_rtmp.c -************************************************************** -*************************************************************/ -typedef void* srs_flv_t; -/** - * Open FLV file in demux mode. - * @return A FLV demuxer, NULL if failed. - */ -extern srs_flv_t srs_flv_open_read(const char* file); -/** - * Open FlV file in mux mode. - * @return A FLV muxer, NULL if failed. - */ -extern srs_flv_t srs_flv_open_write(const char* file); -/** - * Close the FLV demuxer or muxer. - */ -extern void srs_flv_close(srs_flv_t flv); -/** -* read the flv header. 9bytes header. -* @param header, @see E.2 The FLV header, flv_v10_1.pdf in SRS doc. -* 3bytes, signature, "FLV", -* 1bytes, version, 0x01, -* 1bytes, flags, UB[5] 0, UB[1] audio present, UB[1] 0, UB[1] video present. -* 4bytes, dataoffset, 0x09, The length of this header in bytes -* -* @return 0, success; otherswise, failed. -* @remark, drop the 4bytes zero previous tag size. -*/ -extern int srs_flv_read_header(srs_flv_t flv, char header[9]); -/** -* read the flv tag header, 1bytes tag, 3bytes data_size, -* 4bytes time, 3bytes stream id. -* @param ptype, output the type of tag, macros: -* SRS_RTMP_TYPE_AUDIO, FlvTagAudio -* SRS_RTMP_TYPE_VIDEO, FlvTagVideo -* SRS_RTMP_TYPE_SCRIPT, FlvTagScript -* @param pdata_size, output the size of tag data. -* @param ptime, output the time of tag, the dts in ms. -* -* @return 0, success; otherswise, failed. -* @remark, user must ensure the next is a tag, srs never check it. -*/ -extern int srs_flv_read_tag_header(srs_flv_t flv, - char* ptype, int32_t* pdata_size, uint32_t* ptime -); -/** -* read the tag data. drop the 4bytes previous tag size -* @param data, the data to read, user alloc and free it. -* @param size, the size of data to read, get by srs_flv_read_tag_header(). -* @remark, srs will ignore and drop the 4bytes previous tag size. -*/ -extern int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size); -/** -* write the flv header. 9bytes header. -* @param header, @see E.2 The FLV header, flv_v10_1.pdf in SRS doc. -* 3bytes, signature, "FLV", -* 1bytes, version, 0x01, -* 1bytes, flags, UB[5] 0, UB[1] audio present, UB[1] 0, UB[1] video present. -* 4bytes, dataoffset, 0x09, The length of this header in bytes -* -* @return 0, success; otherswise, failed. -* @remark, auto write the 4bytes zero previous tag size. -*/ -extern int srs_flv_write_header(srs_flv_t flv, char header[9]); -/** -* write the flv tag to file. -* -* @return 0, success; otherswise, failed. -* @remark, auto write the 4bytes zero previous tag size. -*/ -/* write flv tag to file, auto write the 4bytes previous tag size */ -extern int srs_flv_write_tag(srs_flv_t flv, - char type, int32_t time, char* data, int size -); -/** -* get the tag size, for flv injecter to adjust offset, -* size = tag_header(11B) + data_size + previous_tag(4B) -* @return the size of tag. -*/ -extern int srs_flv_size_tag(int data_size); -/* file stream */ -/* file stream tellg to get offset */ -extern int64_t srs_flv_tellg(srs_flv_t flv); -/* seek file stream, offset is form the start of file */ -extern void srs_flv_lseek(srs_flv_t flv, int64_t offset); -/* error code */ -/* whether the error code indicates EOF */ -extern srs_bool srs_flv_is_eof(int error_code); -/* media codec */ -/** -* whether the video body is sequence header -* @param data, the data of tag, read by srs_flv_read_tag_data(). -* @param size, the size of tag, read by srs_flv_read_tag_data(). -*/ -extern srs_bool srs_flv_is_sequence_header(char* data, int32_t size); -/** -* whether the video body is keyframe -* @param data, the data of tag, read by srs_flv_read_tag_data(). -* @param size, the size of tag, read by srs_flv_read_tag_data(). -*/ -extern srs_bool srs_flv_is_keyframe(char* data, int32_t size); - -/************************************************************* -************************************************************** -* amf0 codec -* @example /trunk/research/librtmp/srs_ingest_flv.c -* @example /trunk/research/librtmp/srs_ingest_rtmp.c -************************************************************** -*************************************************************/ -/* the output handler. */ -typedef double srs_amf0_number; -/** -* parse amf0 from data. -* @param nparsed, the parsed size, NULL to ignore. -* @return the parsed amf0 object. NULL for error. -* @remark user must free the parsed or created object by srs_amf0_free. -*/ -extern srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed); -extern srs_amf0_t srs_amf0_create_string(const char* value); -extern srs_amf0_t srs_amf0_create_number(srs_amf0_number value); -extern srs_amf0_t srs_amf0_create_ecma_array(); -extern srs_amf0_t srs_amf0_create_strict_array(); -extern srs_amf0_t srs_amf0_create_object(); -extern srs_amf0_t srs_amf0_ecma_array_to_object(srs_amf0_t ecma_arr); -extern void srs_amf0_free(srs_amf0_t amf0); -/* size and to bytes */ -extern int srs_amf0_size(srs_amf0_t amf0); -extern int srs_amf0_serialize(srs_amf0_t amf0, char* data, int size); -/* type detecter */ -extern srs_bool srs_amf0_is_string(srs_amf0_t amf0); -extern srs_bool srs_amf0_is_boolean(srs_amf0_t amf0); -extern srs_bool srs_amf0_is_number(srs_amf0_t amf0); -extern srs_bool srs_amf0_is_null(srs_amf0_t amf0); -extern srs_bool srs_amf0_is_object(srs_amf0_t amf0); -extern srs_bool srs_amf0_is_ecma_array(srs_amf0_t amf0); -extern srs_bool srs_amf0_is_strict_array(srs_amf0_t amf0); -/* value converter */ -extern const char* srs_amf0_to_string(srs_amf0_t amf0); -extern srs_bool srs_amf0_to_boolean(srs_amf0_t amf0); -extern srs_amf0_number srs_amf0_to_number(srs_amf0_t amf0); -/* value setter */ -extern void srs_amf0_set_number(srs_amf0_t amf0, srs_amf0_number value); -/* object value converter */ -extern int srs_amf0_object_property_count(srs_amf0_t amf0); -extern const char* srs_amf0_object_property_name_at(srs_amf0_t amf0, int index); -extern srs_amf0_t srs_amf0_object_property_value_at(srs_amf0_t amf0, int index); -extern srs_amf0_t srs_amf0_object_property(srs_amf0_t amf0, const char* name); -extern void srs_amf0_object_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value); -extern void srs_amf0_object_clear(srs_amf0_t amf0); -/* ecma array value converter */ -extern int srs_amf0_ecma_array_property_count(srs_amf0_t amf0); -extern const char* srs_amf0_ecma_array_property_name_at(srs_amf0_t amf0, int index); -extern srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index); -extern srs_amf0_t srs_amf0_ecma_array_property(srs_amf0_t amf0, const char* name); -extern void srs_amf0_ecma_array_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value); -/* strict array value converter */ -extern int srs_amf0_strict_array_property_count(srs_amf0_t amf0); -extern srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index); -extern void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value); - -/************************************************************* -************************************************************** -* utilities -************************************************************** -*************************************************************/ -/** -* get the current system time in ms. -* use gettimeofday() to get system time. -*/ -extern int64_t srs_utils_time_ms(); - -/** -* get the send bytes. -*/ -extern int64_t srs_utils_send_bytes(srs_rtmp_t rtmp); - -/** -* get the recv bytes. -*/ -extern int64_t srs_utils_recv_bytes(srs_rtmp_t rtmp); - -/** -* parse the dts and pts by time in header and data in tag, -* or to parse the RTMP packet by srs_rtmp_read_packet(). -* -* @param time, the timestamp of tag, read by srs_flv_read_tag_header(). -* @param type, the type of tag, read by srs_flv_read_tag_header(). -* @param data, the data of tag, read by srs_flv_read_tag_data(). -* @param size, the size of tag, read by srs_flv_read_tag_header(). -* @param ppts, output the pts in ms, -* -* @return 0, success; otherswise, failed. -* @remark, the dts always equals to @param time. -* @remark, the pts=dts for audio or data. -* @remark, video only support h.264. -*/ -extern int srs_utils_parse_timestamp( - uint32_t time, char type, char* data, int size, - uint32_t* ppts -); + /************************************************************* + ************************************************************** + * h264 raw codec + ************************************************************** + *************************************************************/ + /** + * write h.264 raw frame over RTMP to rtmp server. + * @param frames the input h264 raw data, encoded h.264 I/P/B frames data. + * frames can be one or more than one frame, + * each frame prefixed h.264 annexb header, by N[00] 00 00 01, where N>=0, + * for instance, frame = header(00 00 00 01) + payload(67 42 80 29 95 A0 14 01 6E 40) + * about annexb, @see ISO_IEC_14496-10-AVC-2003.pdf, page 211. + * @param frames_size the size of h264 raw data. + * assert frames_size > 0, at least has 1 bytes header. + * @param dts the dts of h.264 raw data. + * @param pts the pts of h.264 raw data. + * + * @remark, user should free the frames. + * @remark, the tbn of dts/pts is 1/1000 for RTMP, that is, in ms. + * @remark, cts = pts - dts + * @remark, use srs_h264_startswith_annexb to check whether frame is annexb format. + * @example /trunk/research/librtmp/srs_h264_raw_publish.c + * @see https://github.com/ossrs/srs/issues/66 + * + * @return 0, success; otherswise, failed. + * for dvbsp error, @see srs_h264_is_dvbsp_error(). + * for duplictated sps error, @see srs_h264_is_duplicated_sps_error(). + * for duplictated pps error, @see srs_h264_is_duplicated_pps_error(). + */ + /** + For the example file: + http://winlinvip.github.io/srs.release/3rdparty/720p.h264.raw + The data sequence is: + // SPS + 000000016742802995A014016E40 + // PPS + 0000000168CE3880 + // IFrame + 0000000165B8041014C038008B0D0D3A071..... + // PFrame + 0000000141E02041F8CDDC562BBDEFAD2F..... + User can send the SPS+PPS, then each frame: + // SPS+PPS + srs_h264_write_raw_frames('000000016742802995A014016E400000000168CE3880', size, dts, pts) + // IFrame + srs_h264_write_raw_frames('0000000165B8041014C038008B0D0D3A071......', size, dts, pts) + // PFrame + srs_h264_write_raw_frames('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts) + User also can send one by one: + // SPS + srs_h264_write_raw_frames('000000016742802995A014016E4', size, dts, pts) + // PPS + srs_h264_write_raw_frames('00000000168CE3880', size, dts, pts) + // IFrame + srs_h264_write_raw_frames('0000000165B8041014C038008B0D0D3A071......', size, dts, pts) + // PFrame + srs_h264_write_raw_frames('0000000141E02041F8CDDC562BBDEFAD2F......', size, dts, pts) + */ + extern int srs_h264_write_raw_frames(srs_rtmp_t rtmp, char* frames, int frames_size, uint32_t dts, uint32_t pts); + /** + * whether error_code is dvbsp(drop video before sps/pps/sequence-header) error. + * + * @see https://github.com/ossrs/srs/issues/203 + * @example /trunk/research/librtmp/srs_h264_raw_publish.c + * @remark why drop video? + * some encoder, for example, ipcamera, will send sps/pps before each IFrame, + * so, when error and reconnect the rtmp, the first video is not sps/pps(sequence header), + * this will cause SRS server to disable HLS. + */ + extern srs_bool srs_h264_is_dvbsp_error(int error_code); + /** + * whether error_code is duplicated sps error. + * + * @see https://github.com/ossrs/srs/issues/204 + * @example /trunk/research/librtmp/srs_h264_raw_publish.c + */ + extern srs_bool srs_h264_is_duplicated_sps_error(int error_code); + /** + * whether error_code is duplicated pps error. + * + * @see https://github.com/ossrs/srs/issues/204 + * @example /trunk/research/librtmp/srs_h264_raw_publish.c + */ + extern srs_bool srs_h264_is_duplicated_pps_error(int error_code); + /** + * whether h264 raw data starts with the annexb, + * which bytes sequence matches N[00] 00 00 01, where N>=0. + * @param h264_raw_data the input h264 raw data, a encoded h.264 I/P/B frame data. + * @paam h264_raw_size the size of h264 raw data. + * @param pnb_start_code output the size of start code, must >=3. + * NULL to ignore. + * + * @reamrk used to check whether current frame is in annexb format. + * @example /trunk/research/librtmp/srs_h264_raw_publish.c + * + * @return 0 false; otherwise, true. + */ + extern srs_bool srs_h264_startswith_annexb(char* h264_raw_data, int h264_raw_size, int* pnb_start_code); -/** - * whether the flv tag specified by param type is ok. - * @return true when tag is video/audio/script-data; otherwise, false. - */ -extern srs_bool srs_utils_flv_tag_is_ok(char type); -extern srs_bool srs_utils_flv_tag_is_audio(char type); -extern srs_bool srs_utils_flv_tag_is_video(char type); -extern srs_bool srs_utils_flv_tag_is_av(char type); - -/** -* get the CodecID of video tag. -* Codec Identifier. The following values are defined: -* 2 = Sorenson H.263 -* 3 = Screen video -* 4 = On2 VP6 -* 5 = On2 VP6 with alpha channel -* 6 = Screen video version 2 -* 7 = AVC -* @return the code id. 0 for error. -*/ -extern char srs_utils_flv_video_codec_id(char* data, int size); - -/** -* get the AVCPacketType of video tag. -* The following values are defined: -* 0 = AVC sequence header -* 1 = AVC NALU -* 2 = AVC end of sequence (lower level NALU sequence ender is -* not required or supported) -* @return the avc packet type. -1(0xff) for error. -*/ -extern char srs_utils_flv_video_avc_packet_type(char* data, int size); - -/** -* get the FrameType of video tag. -* Type of video frame. The following values are defined: -* 1 = key frame (for AVC, a seekable frame) -* 2 = inter frame (for AVC, a non-seekable frame) -* 3 = disposable inter frame (H.263 only) -* 4 = generated key frame (reserved for server use only) -* 5 = video info/command frame -* @return the frame type. 0 for error. -*/ -extern char srs_utils_flv_video_frame_type(char* data, int size); - -/** -* get the SoundFormat of audio tag. -* Format of SoundData. The following values are defined: -* 0 = Linear PCM, platform endian -* 1 = ADPCM -* 2 = MP3 -* 3 = Linear PCM, little endian -* 4 = Nellymoser 16 kHz mono -* 5 = Nellymoser 8 kHz mono -* 6 = Nellymoser -* 7 = G.711 A-law logarithmic PCM -* 8 = G.711 mu-law logarithmic PCM -* 9 = reserved -* 10 = AAC -* 11 = Speex -* 14 = MP3 8 kHz -* 15 = Device-specific sound -* Formats 7, 8, 14, and 15 are reserved. -* AAC is supported in Flash Player 9,0,115,0 and higher. -* Speex is supported in Flash Player 10 and higher. -* @return the sound format. -1(0xff) for error. -*/ -extern char srs_utils_flv_audio_sound_format(char* data, int size); - -/** -* get the SoundRate of audio tag. -* Sampling rate. The following values are defined: -* 0 = 5.5 kHz -* 1 = 11 kHz -* 2 = 22 kHz -* 3 = 44 kHz -* @return the sound rate. -1(0xff) for error. -*/ -extern char srs_utils_flv_audio_sound_rate(char* data, int size); - -/** -* get the SoundSize of audio tag. -* Size of each audio sample. This parameter only pertains to -* uncompressed formats. Compressed formats always decode -* to 16 bits internally. -* 0 = 8-bit samples -* 1 = 16-bit samples -* @return the sound size. -1(0xff) for error. -*/ -extern char srs_utils_flv_audio_sound_size(char* data, int size); - -/** -* get the SoundType of audio tag. -* Mono or stereo sound -* 0 = Mono sound -* 1 = Stereo sound -* @return the sound type. -1(0xff) for error. -*/ -extern char srs_utils_flv_audio_sound_type(char* data, int size); - -/** -* get the AACPacketType of audio tag. -* The following values are defined: -* 0 = AAC sequence header -* 1 = AAC raw -* @return the aac packet type. -1(0xff) for error. -*/ -extern char srs_utils_flv_audio_aac_packet_type(char* data, int size); - -/************************************************************* -************************************************************** -* human readable print. -************************************************************** -*************************************************************/ -/** -* human readable print -* @param pdata, output the heap data, NULL to ignore. -* user must use srs_amf0_free_bytes to free it. -* @return return the *pdata for print. NULL to ignore. -*/ -extern char* srs_human_amf0_print(srs_amf0_t amf0, char** pdata, int* psize); -/** -* convert the flv tag type to string. -* SRS_RTMP_TYPE_AUDIO to "Audio" -* SRS_RTMP_TYPE_VIDEO to "Video" -* SRS_RTMP_TYPE_SCRIPT to "Data" -* otherwise, "Unknown" -* @remark user never free the return char*, -* it's static shared const string. -*/ -extern const char* srs_human_flv_tag_type2string(char type); - -/** -* get the codec id string. -* H.263 = Sorenson H.263 -* Screen = Screen video -* VP6 = On2 VP6 -* VP6Alpha = On2 VP6 with alpha channel -* Screen2 = Screen video version 2 -* H.264 = AVC -* otherwise, "Unknown" -* @remark user never free the return char*, -* it's static shared const string. -*/ -extern const char* srs_human_flv_video_codec_id2string(char codec_id); - -/** -* get the avc packet type string. -* SH = AVC sequence header -* Nalu = AVC NALU -* SpsPpsEnd = AVC end of sequence -* otherwise, "Unknown" -* @remark user never free the return char*, -* it's static shared const string. -*/ -extern const char* srs_human_flv_video_avc_packet_type2string(char avc_packet_type); - -/** -* get the frame type string. -* I = key frame (for AVC, a seekable frame) -* P/B = inter frame (for AVC, a non-seekable frame) -* DI = disposable inter frame (H.263 only) -* GI = generated key frame (reserved for server use only) -* VI = video info/command frame -* otherwise, "Unknown" -* @remark user never free the return char*, -* it's static shared const string. -*/ -extern const char* srs_human_flv_video_frame_type2string(char frame_type); - -/** -* get the SoundFormat string. -* Format of SoundData. The following values are defined: -* LinearPCM = Linear PCM, platform endian -* ADPCM = ADPCM -* MP3 = MP3 -* LinearPCMLe = Linear PCM, little endian -* NellymoserKHz16 = Nellymoser 16 kHz mono -* NellymoserKHz8 = Nellymoser 8 kHz mono -* Nellymoser = Nellymoser -* G711APCM = G.711 A-law logarithmic PCM -* G711MuPCM = G.711 mu-law logarithmic PCM -* Reserved = reserved -* AAC = AAC -* Speex = Speex -* MP3KHz8 = MP3 8 kHz -* DeviceSpecific = Device-specific sound -* otherwise, "Unknown" -* @remark user never free the return char*, -* it's static shared const string. -*/ -extern const char* srs_human_flv_audio_sound_format2string(char sound_format); - -/** -* get the SoundRate of audio tag. -* Sampling rate. The following values are defined: -* 5.5KHz = 5.5 kHz -* 11KHz = 11 kHz -* 22KHz = 22 kHz -* 44KHz = 44 kHz -* otherwise, "Unknown" -* @remark user never free the return char*, -* it's static shared const string. -*/ -extern const char* srs_human_flv_audio_sound_rate2string(char sound_rate); - -/** -* get the SoundSize of audio tag. -* Size of each audio sample. This parameter only pertains to -* uncompressed formats. Compressed formats always decode -* to 16 bits internally. -* 8bit = 8-bit samples -* 16bit = 16-bit samples -* otherwise, "Unknown" -* @remark user never free the return char*, -* it's static shared const string. -*/ -extern const char* srs_human_flv_audio_sound_size2string(char sound_size); - -/** -* get the SoundType of audio tag. -* Mono or stereo sound -* Mono = Mono sound -* Stereo = Stereo sound -* otherwise, "Unknown" -* @remark user never free the return char*, -* it's static shared const string. -*/ -extern const char* srs_human_flv_audio_sound_type2string(char sound_type); - -/** -* get the AACPacketType of audio tag. -* The following values are defined: -* SH = AAC sequence header -* Raw = AAC raw -* otherwise, "Unknown" -* @remark user never free the return char*, -* it's static shared const string. -*/ -extern const char* srs_human_flv_audio_aac_packet_type2string(char aac_packet_type); + /************************************************************* + ************************************************************* + * MP4 muxer and demuxer. + * @example /trunk/research/librtmp/srs_ingest_mp4.c + ************************************************************* + *************************************************************/ + typedef void* srs_mp4_t; + // The sample struct of mp4. + typedef struct { + // The handler type, it's SrsMp4HandlerType. + uint32_t handler_type; + + // The dts in milliseconds. + uint32_t dts; + // The codec id. + // video: SrsVideoCodecId. + // audio: SrsAudioCodecId. + uint16_t codec; + // The frame trait, some characteristic: + // video: SrsVideoAvcFrameTrait. + // audio: SrsAudioAacFrameTrait. + uint16_t frame_trait; + + // The video pts in milliseconds. Ignore for audio. + uint32_t pts; + // The video frame type, it's SrsVideoAvcFrameType. + uint16_t frame_type; + + // The audio sample rate, it's SrsAudioSampleRate. + uint8_t sample_rate; + // The audio sound bits, it's SrsAudioSampleBits. + uint8_t sound_bits; + // The audio sound type, it's SrsAudioChannels. + uint8_t channels; + + // The size of sample payload in bytes. + uint32_t nb_sample; + // The output sample data, user must free it by srs_mp4_free_sample. + uint8_t* sample; + } srs_mp4_sample_t; + /** + * Open mp4 file for muxer(write) or demuxer(read). + * @return A MP4 demuxer, NULL if failed. + */ + extern srs_mp4_t srs_mp4_open_read(const char* file); + /** + * Close the MP4 demuxer. + */ + extern void srs_mp4_close(srs_mp4_t mp4); + /** + * Initialize mp4 demuxer in non-seek mode. + * @remark Only support non-seek mode, that is fmp4 or moov before mdata. + * For the live streaming, we must feed stream frame by frame. + */ + extern int srs_mp4_init_demuxer(srs_mp4_t mp4); + /** + * Read a sample form mp4. + * @remark User can use srs_mp4_sample_to_flv_tag to convert mp4 sampel to flv tag. + * Use the srs_mp4_to_flv_tag_size to calc the flv tag data size to alloc. + */ + extern int srs_mp4_read_sample(srs_mp4_t mp4, srs_mp4_sample_t* sample); + /** + * Free the allocated mp4 sample. + */ + extern void srs_mp4_free_sample(srs_mp4_sample_t* sample); + /** + * Calc the size of flv tag, for the mp4 sample to convert to. + */ + extern int32_t srs_mp4_sizeof(srs_mp4_t mp4, srs_mp4_sample_t* sample); + /** + * Covert mp4 sample to flv tag. + */ + extern int srs_mp4_to_flv_tag(srs_mp4_t mp4, srs_mp4_sample_t* sample, char* type, uint32_t* time, char* data, int32_t size); + /* error code */ + /* whether the error code indicates EOF */ + extern srs_bool srs_mp4_is_eof(int error_code); -/** - * Format the RTMP packet to human readable buffer. - * @return Whether parse RTMP packet ok. 0, success; otherwise, failed. - */ -extern int srs_human_format_rtmp_packet(char* buffer, int nb_buffer, char type, uint32_t timestamp, char* data, int size); -extern int srs_human_format_rtmp_packet2(char* buffer, int nb_buffer, char type, uint32_t timestamp, char* data, int size, - uint32_t pre_timestamp, int64_t pre_now, int64_t starttime, int64_t nb_packets); - -/** - * Format current time to human readable string. - * @return A NULL terminated string. - */ -extern const char* srs_human_format_time(); + /************************************************************* + ************************************************************** + * flv codec + * @example /trunk/research/librtmp/srs_flv_injecter.c + * @example /trunk/research/librtmp/srs_flv_parser.c + * @example /trunk/research/librtmp/srs_ingest_flv.c + * @example /trunk/research/librtmp/srs_ingest_rtmp.c + ************************************************************** + *************************************************************/ + typedef void* srs_flv_t; + /** + * Open FLV file in demux mode. + * @return A FLV demuxer, NULL if failed. + */ + extern srs_flv_t srs_flv_open_read(const char* file); + /** + * Open FlV file in mux mode. + * @return A FLV muxer, NULL if failed. + */ + extern srs_flv_t srs_flv_open_write(const char* file); + /** + * Close the FLV demuxer or muxer. + */ + extern void srs_flv_close(srs_flv_t flv); + /** + * read the flv header. 9bytes header. + * @param header, @see E.2 The FLV header, flv_v10_1.pdf in SRS doc. + * 3bytes, signature, "FLV", + * 1bytes, version, 0x01, + * 1bytes, flags, UB[5] 0, UB[1] audio present, UB[1] 0, UB[1] video present. + * 4bytes, dataoffset, 0x09, The length of this header in bytes + * + * @return 0, success; otherswise, failed. + * @remark, drop the 4bytes zero previous tag size. + */ + extern int srs_flv_read_header(srs_flv_t flv, char header[9]); + /** + * read the flv tag header, 1bytes tag, 3bytes data_size, + * 4bytes time, 3bytes stream id. + * @param ptype, output the type of tag, macros: + * SRS_RTMP_TYPE_AUDIO, FlvTagAudio + * SRS_RTMP_TYPE_VIDEO, FlvTagVideo + * SRS_RTMP_TYPE_SCRIPT, FlvTagScript + * @param pdata_size, output the size of tag data. + * @param ptime, output the time of tag, the dts in ms. + * + * @return 0, success; otherswise, failed. + * @remark, user must ensure the next is a tag, srs never check it. + */ + extern int srs_flv_read_tag_header(srs_flv_t flv, char* ptype, int32_t* pdata_size, uint32_t* ptime); + /** + * read the tag data. drop the 4bytes previous tag size + * @param data, the data to read, user alloc and free it. + * @param size, the size of data to read, get by srs_flv_read_tag_header(). + * @remark, srs will ignore and drop the 4bytes previous tag size. + */ + extern int srs_flv_read_tag_data(srs_flv_t flv, char* data, int32_t size); + /** + * write the flv header. 9bytes header. + * @param header, @see E.2 The FLV header, flv_v10_1.pdf in SRS doc. + * 3bytes, signature, "FLV", + * 1bytes, version, 0x01, + * 1bytes, flags, UB[5] 0, UB[1] audio present, UB[1] 0, UB[1] video present. + * 4bytes, dataoffset, 0x09, The length of this header in bytes + * + * @return 0, success; otherswise, failed. + * @remark, auto write the 4bytes zero previous tag size. + */ + extern int srs_flv_write_header(srs_flv_t flv, char header[9]); + /** + * write the flv tag to file. + * + * @return 0, success; otherswise, failed. + * @remark, auto write the 4bytes zero previous tag size. + */ + /* write flv tag to file, auto write the 4bytes previous tag size */ + extern int srs_flv_write_tag(srs_flv_t flv, char type, int32_t time, char* data, int size); + /** + * get the tag size, for flv injecter to adjust offset, + * size = tag_header(11B) + data_size + previous_tag(4B) + * @return the size of tag. + */ + extern int srs_flv_size_tag(int data_size); + /* file stream */ + /* file stream tellg to get offset */ + extern int64_t srs_flv_tellg(srs_flv_t flv); + /* seek file stream, offset is form the start of file */ + extern void srs_flv_lseek(srs_flv_t flv, int64_t offset); + /* error code */ + /* whether the error code indicates EOF */ + extern srs_bool srs_flv_is_eof(int error_code); + /* media codec */ + /** + * whether the video body is sequence header + * @param data, the data of tag, read by srs_flv_read_tag_data(). + * @param size, the size of tag, read by srs_flv_read_tag_data(). + */ + extern srs_bool srs_flv_is_sequence_header(char* data, int32_t size); + /** + * whether the video body is keyframe + * @param data, the data of tag, read by srs_flv_read_tag_data(). + * @param size, the size of tag, read by srs_flv_read_tag_data(). + */ + extern srs_bool srs_flv_is_keyframe(char* data, int32_t size); + + /************************************************************* + ************************************************************** + * amf0 codec + * @example /trunk/research/librtmp/srs_ingest_flv.c + * @example /trunk/research/librtmp/srs_ingest_rtmp.c + ************************************************************** + *************************************************************/ + /* the output handler. */ + typedef double srs_amf0_number; + /** + * parse amf0 from data. + * @param nparsed, the parsed size, NULL to ignore. + * @return the parsed amf0 object. NULL for error. + * @remark user must free the parsed or created object by srs_amf0_free. + */ + extern srs_amf0_t srs_amf0_parse(char* data, int size, int* nparsed); + extern srs_amf0_t srs_amf0_create_string(const char* value); + extern srs_amf0_t srs_amf0_create_number(srs_amf0_number value); + extern srs_amf0_t srs_amf0_create_ecma_array(); + extern srs_amf0_t srs_amf0_create_strict_array(); + extern srs_amf0_t srs_amf0_create_object(); + extern srs_amf0_t srs_amf0_ecma_array_to_object(srs_amf0_t ecma_arr); + extern void srs_amf0_free(srs_amf0_t amf0); + /* size and to bytes */ + extern int srs_amf0_size(srs_amf0_t amf0); + extern int srs_amf0_serialize(srs_amf0_t amf0, char* data, int size); + /* type detecter */ + extern srs_bool srs_amf0_is_string(srs_amf0_t amf0); + extern srs_bool srs_amf0_is_boolean(srs_amf0_t amf0); + extern srs_bool srs_amf0_is_number(srs_amf0_t amf0); + extern srs_bool srs_amf0_is_null(srs_amf0_t amf0); + extern srs_bool srs_amf0_is_object(srs_amf0_t amf0); + extern srs_bool srs_amf0_is_ecma_array(srs_amf0_t amf0); + extern srs_bool srs_amf0_is_strict_array(srs_amf0_t amf0); + /* value converter */ + extern const char* srs_amf0_to_string(srs_amf0_t amf0); + extern srs_bool srs_amf0_to_boolean(srs_amf0_t amf0); + extern srs_amf0_number srs_amf0_to_number(srs_amf0_t amf0); + /* value setter */ + extern void srs_amf0_set_number(srs_amf0_t amf0, srs_amf0_number value); + /* object value converter */ + extern int srs_amf0_object_property_count(srs_amf0_t amf0); + extern const char* srs_amf0_object_property_name_at(srs_amf0_t amf0, int index); + extern srs_amf0_t srs_amf0_object_property_value_at(srs_amf0_t amf0, int index); + extern srs_amf0_t srs_amf0_object_property(srs_amf0_t amf0, const char* name); + extern void srs_amf0_object_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value); + extern void srs_amf0_object_clear(srs_amf0_t amf0); + /* ecma array value converter */ + extern int srs_amf0_ecma_array_property_count(srs_amf0_t amf0); + extern const char* srs_amf0_ecma_array_property_name_at(srs_amf0_t amf0, int index); + extern srs_amf0_t srs_amf0_ecma_array_property_value_at(srs_amf0_t amf0, int index); + extern srs_amf0_t srs_amf0_ecma_array_property(srs_amf0_t amf0, const char* name); + extern void srs_amf0_ecma_array_property_set(srs_amf0_t amf0, const char* name, srs_amf0_t value); + /* strict array value converter */ + extern int srs_amf0_strict_array_property_count(srs_amf0_t amf0); + extern srs_amf0_t srs_amf0_strict_array_property_at(srs_amf0_t amf0, int index); + extern void srs_amf0_strict_array_append(srs_amf0_t amf0, srs_amf0_t value); + + /************************************************************* + ************************************************************** + * utilities + ************************************************************** + *************************************************************/ + /** + * get the current system time in ms. + * use gettimeofday() to get system time. + */ + extern int64_t srs_utils_time_ms(); + + /** + * get the send bytes. + */ + extern int64_t srs_utils_send_bytes(srs_rtmp_t rtmp); + + /** + * get the recv bytes. + */ + extern int64_t srs_utils_recv_bytes(srs_rtmp_t rtmp); + + /** + * parse the dts and pts by time in header and data in tag, + * or to parse the RTMP packet by srs_rtmp_read_packet(). + * + * @param time, the timestamp of tag, read by srs_flv_read_tag_header(). + * @param type, the type of tag, read by srs_flv_read_tag_header(). + * @param data, the data of tag, read by srs_flv_read_tag_data(). + * @param size, the size of tag, read by srs_flv_read_tag_header(). + * @param ppts, output the pts in ms, + * + * @return 0, success; otherswise, failed. + * @remark, the dts always equals to @param time. + * @remark, the pts=dts for audio or data. + * @remark, video only support h.264. + */ + extern int srs_utils_parse_timestamp(uint32_t time, char type, char* data, int size, uint32_t* ppts); + + /** + * whether the flv tag specified by param type is ok. + * @return true when tag is video/audio/script-data; otherwise, false. + */ + extern srs_bool srs_utils_flv_tag_is_ok(char type); + extern srs_bool srs_utils_flv_tag_is_audio(char type); + extern srs_bool srs_utils_flv_tag_is_video(char type); + extern srs_bool srs_utils_flv_tag_is_av(char type); + + /** + * get the CodecID of video tag. + * Codec Identifier. The following values are defined: + * 2 = Sorenson H.263 + * 3 = Screen video + * 4 = On2 VP6 + * 5 = On2 VP6 with alpha channel + * 6 = Screen video version 2 + * 7 = AVC + * @return the code id. 0 for error. + */ + extern char srs_utils_flv_video_codec_id(char* data, int size); + + /** + * get the AVCPacketType of video tag. + * The following values are defined: + * 0 = AVC sequence header + * 1 = AVC NALU + * 2 = AVC end of sequence (lower level NALU sequence ender is + * not required or supported) + * @return the avc packet type. -1(0xff) for error. + */ + extern char srs_utils_flv_video_avc_packet_type(char* data, int size); + + /** + * get the FrameType of video tag. + * Type of video frame. The following values are defined: + * 1 = key frame (for AVC, a seekable frame) + * 2 = inter frame (for AVC, a non-seekable frame) + * 3 = disposable inter frame (H.263 only) + * 4 = generated key frame (reserved for server use only) + * 5 = video info/command frame + * @return the frame type. 0 for error. + */ + extern char srs_utils_flv_video_frame_type(char* data, int size); + + /** + * get the SoundFormat of audio tag. + * Format of SoundData. The following values are defined: + * 0 = Linear PCM, platform endian + * 1 = ADPCM + * 2 = MP3 + * 3 = Linear PCM, little endian + * 4 = Nellymoser 16 kHz mono + * 5 = Nellymoser 8 kHz mono + * 6 = Nellymoser + * 7 = G.711 A-law logarithmic PCM + * 8 = G.711 mu-law logarithmic PCM + * 9 = reserved + * 10 = AAC + * 11 = Speex + * 14 = MP3 8 kHz + * 15 = Device-specific sound + * Formats 7, 8, 14, and 15 are reserved. + * AAC is supported in Flash Player 9,0,115,0 and higher. + * Speex is supported in Flash Player 10 and higher. + * @return the sound format. -1(0xff) for error. + */ + extern char srs_utils_flv_audio_sound_format(char* data, int size); + + /** + * get the SoundRate of audio tag. + * Sampling rate. The following values are defined: + * 0 = 5.5 kHz + * 1 = 11 kHz + * 2 = 22 kHz + * 3 = 44 kHz + * @return the sound rate. -1(0xff) for error. + */ + extern char srs_utils_flv_audio_sound_rate(char* data, int size); + + /** + * get the SoundSize of audio tag. + * Size of each audio sample. This parameter only pertains to + * uncompressed formats. Compressed formats always decode + * to 16 bits internally. + * 0 = 8-bit samples + * 1 = 16-bit samples + * @return the sound size. -1(0xff) for error. + */ + extern char srs_utils_flv_audio_sound_size(char* data, int size); + + /** + * get the SoundType of audio tag. + * Mono or stereo sound + * 0 = Mono sound + * 1 = Stereo sound + * @return the sound type. -1(0xff) for error. + */ + extern char srs_utils_flv_audio_sound_type(char* data, int size); + + /** + * get the AACPacketType of audio tag. + * The following values are defined: + * 0 = AAC sequence header + * 1 = AAC raw + * @return the aac packet type. -1(0xff) for error. + */ + extern char srs_utils_flv_audio_aac_packet_type(char* data, int size); + + /************************************************************* + ************************************************************** + * human readable print. + ************************************************************** + *************************************************************/ + /** + * human readable print + * @param pdata, output the heap data, NULL to ignore. + * user must use srs_amf0_free_bytes to free it. + * @return return the *pdata for print. NULL to ignore. + */ + extern char* srs_human_amf0_print(srs_amf0_t amf0, char** pdata, int* psize); + /** + * convert the flv tag type to string. + * SRS_RTMP_TYPE_AUDIO to "Audio" + * SRS_RTMP_TYPE_VIDEO to "Video" + * SRS_RTMP_TYPE_SCRIPT to "Data" + * otherwise, "Unknown" + * @remark user never free the return char*, + * it's static shared const string. + */ + extern const char* srs_human_flv_tag_type2string(char type); + + /** + * get the codec id string. + * H.263 = Sorenson H.263 + * Screen = Screen video + * VP6 = On2 VP6 + * VP6Alpha = On2 VP6 with alpha channel + * Screen2 = Screen video version 2 + * H.264 = AVC + * otherwise, "Unknown" + * @remark user never free the return char*, + * it's static shared const string. + */ + extern const char* srs_human_flv_video_codec_id2string(char codec_id); + + /** + * get the avc packet type string. + * SH = AVC sequence header + * Nalu = AVC NALU + * SpsPpsEnd = AVC end of sequence + * otherwise, "Unknown" + * @remark user never free the return char*, + * it's static shared const string. + */ + extern const char* srs_human_flv_video_avc_packet_type2string(char avc_packet_type); + + /** + * get the frame type string. + * I = key frame (for AVC, a seekable frame) + * P/B = inter frame (for AVC, a non-seekable frame) + * DI = disposable inter frame (H.263 only) + * GI = generated key frame (reserved for server use only) + * VI = video info/command frame + * otherwise, "Unknown" + * @remark user never free the return char*, + * it's static shared const string. + */ + extern const char* srs_human_flv_video_frame_type2string(char frame_type); + + /** + * get the SoundFormat string. + * Format of SoundData. The following values are defined: + * LinearPCM = Linear PCM, platform endian + * ADPCM = ADPCM + * MP3 = MP3 + * LinearPCMLe = Linear PCM, little endian + * NellymoserKHz16 = Nellymoser 16 kHz mono + * NellymoserKHz8 = Nellymoser 8 kHz mono + * Nellymoser = Nellymoser + * G711APCM = G.711 A-law logarithmic PCM + * G711MuPCM = G.711 mu-law logarithmic PCM + * Reserved = reserved + * AAC = AAC + * Speex = Speex + * MP3KHz8 = MP3 8 kHz + * DeviceSpecific = Device-specific sound + * otherwise, "Unknown" + * @remark user never free the return char*, + * it's static shared const string. + */ + extern const char* srs_human_flv_audio_sound_format2string(char sound_format); + + /** + * get the SoundRate of audio tag. + * Sampling rate. The following values are defined: + * 5.5KHz = 5.5 kHz + * 11KHz = 11 kHz + * 22KHz = 22 kHz + * 44KHz = 44 kHz + * otherwise, "Unknown" + * @remark user never free the return char*, + * it's static shared const string. + */ + extern const char* srs_human_flv_audio_sound_rate2string(char sound_rate); + + /** + * get the SoundSize of audio tag. + * Size of each audio sample. This parameter only pertains to + * uncompressed formats. Compressed formats always decode + * to 16 bits internally. + * 8bit = 8-bit samples + * 16bit = 16-bit samples + * otherwise, "Unknown" + * @remark user never free the return char*, + * it's static shared const string. + */ + extern const char* srs_human_flv_audio_sound_size2string(char sound_size); + + /** + * get the SoundType of audio tag. + * Mono or stereo sound + * Mono = Mono sound + * Stereo = Stereo sound + * otherwise, "Unknown" + * @remark user never free the return char*, + * it's static shared const string. + */ + extern const char* srs_human_flv_audio_sound_type2string(char sound_type); + + /** + * get the AACPacketType of audio tag. + * The following values are defined: + * SH = AAC sequence header + * Raw = AAC raw + * otherwise, "Unknown" + * @remark user never free the return char*, + * it's static shared const string. + */ + extern const char* srs_human_flv_audio_aac_packet_type2string(char aac_packet_type); + + /** + * Format the RTMP packet to human readable buffer. + * @return Whether parse RTMP packet ok. 0, success; otherwise, failed. + */ + extern int srs_human_format_rtmp_packet(char* buffer, int nb_buffer, char type, uint32_t timestamp, char* data, int size); + extern int srs_human_format_rtmp_packet2(char* buffer, int nb_buffer, char type, uint32_t timestamp, char* data, int size, + uint32_t pre_timestamp, int64_t pre_now, int64_t starttime, int64_t nb_packets); + + /** + * Format current time to human readable string. + * @return A NULL terminated string. + */ + extern const char* srs_human_format_time(); #ifndef _WIN32 // for getpid. - #include +#include #endif -// The log function for librtmp. -// User can disable it by define macro SRS_DISABLE_LOG. -// Or user can directly use them, or define the alias by: -// #define trace(msg, ...) srs_human_trace(msg, ##__VA_ARGS__) -// #define warn(msg, ...) srs_human_warn(msg, ##__VA_ARGS__) -// #define error(msg, ...) srs_human_error(msg, ##__VA_ARGS__) + // The log function for librtmp. + // User can disable it by define macro SRS_DISABLE_LOG. + // Or user can directly use them, or define the alias by: + // #define trace(msg, ...) srs_human_trace(msg, ##__VA_ARGS__) + // #define warn(msg, ...) srs_human_warn(msg, ##__VA_ARGS__) + // #define error(msg, ...) srs_human_error(msg, ##__VA_ARGS__) #ifdef SRS_DISABLE_LOG - #define srs_human_trace(msg, ...) (void)0 - #define srs_human_warn(msg, ...) (void)0 - #define srs_human_error(msg, ...) (void)0 - #define srs_human_verbose(msg, ...) (void)0 - #define srs_human_raw(msg, ...) (void)0 +#define srs_human_trace(msg, ...) (void)0 +#define srs_human_warn(msg, ...) (void)0 +#define srs_human_error(msg, ...) (void)0 +#define srs_human_verbose(msg, ...) (void)0 +#define srs_human_raw(msg, ...) (void)0 #else - #include - #include - #define srs_human_trace(msg, ...) \ - fprintf(stdout, "[T][%d][%s] ", getpid(), srs_human_format_time());\ - fprintf(stdout, msg, ##__VA_ARGS__); fprintf(stdout, "\n") - #define srs_human_warn(msg, ...) \ - fprintf(stdout, "[W][%d][%s][%d] ", getpid(), srs_human_format_time(), errno); \ - fprintf(stdout, msg, ##__VA_ARGS__); \ - fprintf(stdout, "\n") - #define srs_human_error(msg, ...) \ - fprintf(stderr, "[E][%d][%s][%d] ", getpid(), srs_human_format_time(), errno);\ - fprintf(stderr, msg, ##__VA_ARGS__); \ - fprintf(stderr, " (%s)\n", strerror(errno)) - #define srs_human_verbose(msg, ...) (void)0 - #define srs_human_raw(msg, ...) printf(msg, ##__VA_ARGS__) +#include +#include +#define srs_human_trace(msg, ...) \ +fprintf(stdout, "[T][%d][%s] ", getpid(), srs_human_format_time());\ +fprintf(stdout, msg, ##__VA_ARGS__); fprintf(stdout, "\n") +#define srs_human_warn(msg, ...) \ +fprintf(stdout, "[W][%d][%s][%d] ", getpid(), srs_human_format_time(), errno); \ +fprintf(stdout, msg, ##__VA_ARGS__); \ +fprintf(stdout, "\n") +#define srs_human_error(msg, ...) \ +fprintf(stderr, "[E][%d][%s][%d] ", getpid(), srs_human_format_time(), errno);\ +fprintf(stderr, msg, ##__VA_ARGS__); \ +fprintf(stderr, " (%s)\n", strerror(errno)) +#define srs_human_verbose(msg, ...) (void)0 +#define srs_human_raw(msg, ...) printf(msg, ##__VA_ARGS__) #endif - -/************************************************************* -************************************************************** -* IO hijack, use your specified io functions. -************************************************************** - *************************************************************/ -// the void* will convert to your handler for io hijack. -typedef void* srs_hijack_io_t; + + /************************************************************* + ************************************************************** + * IO hijack, use your specified io functions. + ************************************************************** + *************************************************************/ + // the void* will convert to your handler for io hijack. + typedef void* srs_hijack_io_t; #ifdef SRS_HIJACK_IO - #ifndef _WIN32 - // for iovec. - #include - #endif +#ifndef _WIN32 + // for iovec. +#include +#endif /** - * get the hijack io object in rtmp protocol sdk. - * @remark, user should never provides this method, srs-librtmp provides it. - */ + * get the hijack io object in rtmp protocol sdk. + * @remark, user should never provides this method, srs-librtmp provides it. + */ extern srs_hijack_io_t srs_hijack_io_get(srs_rtmp_t rtmp); #endif -// define the following macro and functions in your module to hijack the io. -// the example @see https://github.com/ossrs/srs-bench -// which use librtmp but use its own io(use st also). + // define the following macro and functions in your module to hijack the io. + // the example @see https://github.com/ossrs/srs-bench + // which use librtmp but use its own io(use st also). #ifdef SRS_HIJACK_IO /** * create hijack. @@ -1186,46 +1162,46 @@ typedef void* srs_hijack_io_t; */ extern int srs_hijack_io_write(srs_hijack_io_t ctx, void* buf, size_t size, ssize_t* nwrite); #endif - -/************************************************************* -************************************************************** -* Windows SRS-LIBRTMP solution -************************************************************** -*************************************************************/ -// for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 + + /************************************************************* + ************************************************************** + * Windows SRS-LIBRTMP solution + ************************************************************** + *************************************************************/ + // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 #ifdef _WIN32 // for time. - #define _CRT_SECURE_NO_WARNINGS - #include +#define _CRT_SECURE_NO_WARNINGS +#include int gettimeofday(struct timeval* tv, struct timezone* tz); - #define PRId64 "lld" +#define PRId64 "lld" // for inet helpers. typedef int socklen_t; const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); // for mkdir(). - #include +#include // for open(). typedef int mode_t; - #define S_IRUSR 0 - #define S_IWUSR 0 - #define S_IXUSR 0 - #define S_IRGRP 0 - #define S_IWGRP 0 - #define S_IXGRP 0 - #define S_IROTH 0 - #define S_IXOTH 0 +#define S_IRUSR 0 +#define S_IWUSR 0 +#define S_IXUSR 0 +#define S_IRGRP 0 +#define S_IWGRP 0 +#define S_IXGRP 0 +#define S_IROTH 0 +#define S_IXOTH 0 // for file seek. - #include - #include - #define open _open - #define close _close - #define lseek _lseek - #define write _write - #define read _read +#include +#include +#define open _open +#define close _close +#define lseek _lseek +#define write _write +#define read _read // for socket. ssize_t writev(int fd, const struct iovec *iov, int iovcnt); @@ -1235,38 +1211,37 @@ typedef void* srs_hijack_io_t; int socket_cleanup(); // others. - #define snprintf _snprintf +#define snprintf _snprintf #endif - -/************************************************************* - ************************************************************* - * Deprecated APIs, maybe removed in future versions. - ************************************************************* - *************************************************************/ -/** - * Deprecated, for bandwidth test check only. - */ -extern srs_rtmp_t srs_rtmp_create2(const char* url); -/** - * Deprecated, use seperate function to retrieve information from rtmp, - * for example, use srs_rtmp_get_server_ip to get server ip. - */ -extern int srs_rtmp_connect_app2(srs_rtmp_t rtmp, - char srs_server_ip[128], char srs_server[128], - char srs_primary[128], char srs_authors[128], - char srs_version[32], int* srs_id, int* srs_pid -); + /************************************************************* + ************************************************************* + * Deprecated APIs, maybe removed in future versions. + ************************************************************* + *************************************************************/ + /** + * Deprecated, for bandwidth test check only. + */ + extern srs_rtmp_t srs_rtmp_create2(const char* url); + + /** + * Deprecated, use seperate function to retrieve information from rtmp, + * for example, use srs_rtmp_get_server_ip to get server ip. + */ + extern int srs_rtmp_connect_app2(srs_rtmp_t rtmp, + char srs_server_ip[128], char srs_server[128], + char srs_primary[128], char srs_authors[128], + char srs_version[32], int* srs_id, int* srs_pid); + + /** + * Deprecated, use srs_human_format_rtmp_packet instead. + */ + extern int srs_human_print_rtmp_packet(char type, uint32_t timestamp, char* data, int size); + extern int srs_human_print_rtmp_packet2(char type, uint32_t timestamp, char* data, int size, uint32_t pre_timestamp); + extern int srs_human_print_rtmp_packet3(char type, uint32_t timestamp, char* data, int size, uint32_t pre_timestamp, int64_t pre_now); + extern int srs_human_print_rtmp_packet4(char type, uint32_t timestamp, char* data, int size, uint32_t pre_timestamp, int64_t pre_now, + int64_t starttime, int64_t nb_packets); -/** - * Deprecated, use srs_human_format_rtmp_packet instead. - */ -extern int srs_human_print_rtmp_packet(char type, uint32_t timestamp, char* data, int size); -extern int srs_human_print_rtmp_packet2(char type, uint32_t timestamp, char* data, int size, uint32_t pre_timestamp); -extern int srs_human_print_rtmp_packet3(char type, uint32_t timestamp, char* data, int size, uint32_t pre_timestamp, int64_t pre_now); -extern int srs_human_print_rtmp_packet4(char type, uint32_t timestamp, char* data, int size, uint32_t pre_timestamp, int64_t pre_now, - int64_t starttime, int64_t nb_packets); - #ifdef __cplusplus } #endif diff --git a/trunk/src/main/srs_main_ingest_hls.cpp b/trunk/src/main/srs_main_ingest_hls.cpp index 5ff694ac8..50380f55e 100644 --- a/trunk/src/main/srs_main_ingest_hls.cpp +++ b/trunk/src/main/srs_main_ingest_hls.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -60,9 +60,9 @@ ISrsThreadContext* _srs_context = new ISrsThreadContext(); SrsConfig* _srs_config = NULL; /** -* main entrance. -*/ -int main(int argc, char** argv) + * main entrance. + */ +int main(int argc, char** argv) { // TODO: support both little and big endian. srs_assert(srs_is_little_endian()); @@ -124,8 +124,8 @@ public: /** * handle the aac frame, which in ADTS format(starts with FFFx). * @param duration the duration in seconds of frames. -*/ -virtual int on_aac_frame(char* frame, int frame_size, double duration) = 0; + */ + virtual int on_aac_frame(char* frame, int frame_size, double duration) = 0; }; // the context to ingest hls stream. @@ -329,14 +329,14 @@ int SrsIngestSrsInput::parseAac(ISrsAacHandler* handler, char* body, int nb_body // skip ID3. if (id0 == 0x49 && id1 == 0x44 && id2 == 0x33) { /*char id3[] = { - (char)0x49, (char)0x44, (char)0x33, // ID3 - (char)0x03, (char)0x00, // version - (char)0x00, // flags - (char)0x00, (char)0x00, (char)0x00, (char)0x0a, // size - - (char)0x00, (char)0x00, (char)0x00, (char)0x00, // FrameID - (char)0x00, (char)0x00, (char)0x00, (char)0x00, // FrameSize - (char)0x00, (char)0x00 // Flags + (char)0x49, (char)0x44, (char)0x33, // ID3 + (char)0x03, (char)0x00, // version + (char)0x00, // flags + (char)0x00, (char)0x00, (char)0x00, (char)0x0a, // size + + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // FrameID + (char)0x00, (char)0x00, (char)0x00, (char)0x00, // FrameSize + (char)0x00, (char)0x00 // Flags };*/ // atleast 10 bytes. if (!stream->require(10)) { @@ -745,9 +745,9 @@ int SrsIngestSrsOutput::on_ts_message(SrsTsMessage* msg) // ((stream_id >> 4) & 0x0f) == SrsTsPESStreamIdVideo srs_info("<- "SRS_CONSTS_LOG_STREAM_CASTER" mpegts: got %s stream=%s, dts=%"PRId64", pts=%"PRId64", size=%d, us=%d, cc=%d, sid=%#x(%s-%d)", - (msg->channel->apply == SrsTsPidApplyVideo)? "Video":"Audio", srs_ts_stream2string(msg->channel->stream).c_str(), - msg->dts, msg->pts, msg->payload->length(), msg->packet->payload_unit_start_indicator, msg->continuity_counter, msg->sid, - msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number()); + (msg->channel->apply == SrsTsPidApplyVideo)? "Video":"Audio", srs_ts_stream2string(msg->channel->stream).c_str(), + msg->dts, msg->pts, msg->payload->length(), msg->packet->payload_unit_start_indicator, msg->continuity_counter, msg->sid, + msg->is_audio()? "A":msg->is_video()? "V":"N", msg->stream_number()); // When the audio SID is private stream 1, we use common audio. // @see https://github.com/ossrs/srs/issues/740 diff --git a/trunk/src/main/srs_main_mp4_parser.cpp b/trunk/src/main/srs_main_mp4_parser.cpp index 62476888e..5efb611d1 100644 --- a/trunk/src/main/srs_main_mp4_parser.cpp +++ b/trunk/src/main/srs_main_mp4_parser.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -40,3 +40,4 @@ int main(int argc, char** argv) { return 0; } + diff --git a/trunk/src/main/srs_main_server.cpp b/trunk/src/main/srs_main_server.cpp index d5d5aa905..8583d801b 100644 --- a/trunk/src/main/srs_main_server.cpp +++ b/trunk/src/main/srs_main_server.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -31,10 +31,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. using namespace std; #ifdef SRS_AUTO_GPERF_MP - #include +#include #endif #ifdef SRS_AUTO_GPERF_CP - #include +#include #endif using namespace std; @@ -64,7 +64,7 @@ SrsConfig* _srs_config = new SrsConfig(); extern const char* _srs_version; /** -* main entrance. + * main entrance. */ int main(int argc, char** argv) { @@ -377,7 +377,7 @@ int run(SrsServer* svr) srs_error("create process error. ret=-1"); //ret=0 return -1; } - + // grandpa if(pid > 0) { int status = 0; @@ -387,7 +387,7 @@ int run(SrsServer* svr) srs_trace("grandpa process exit."); exit(0); } - + // father pid = fork(); @@ -395,12 +395,12 @@ int run(SrsServer* svr) srs_error("create process error. ret=0"); return -1; } - + if(pid > 0) { srs_trace("father process exit. ret=0"); exit(0); } - + // son srs_trace("son(deamon) process running."); @@ -414,7 +414,7 @@ int run_master(SrsServer* svr) if ((ret = svr->initialize_st()) != ERROR_SUCCESS) { return ret; } - + if ((ret = svr->initialize_signal()) != ERROR_SUCCESS) { return ret; } diff --git a/trunk/src/protocol/srs_http_stack.cpp b/trunk/src/protocol/srs_http_stack.cpp index 33b624a73..5670d8723 100644 --- a/trunk/src/protocol/srs_http_stack.cpp +++ b/trunk/src/protocol/srs_http_stack.cpp @@ -1,24 +1,24 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. */ #include @@ -247,15 +247,15 @@ int SrsHttpRedirectHandler::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessag } string msg = "Redirect to" + location; - + w->header()->set_content_type("text/plain; charset=utf-8"); w->header()->set_content_length(msg.length()); w->header()->set("Location", location); w->write_header(code); - + w->write((char*)msg.data(), (int)msg.length()); w->final_request(); - + srs_info("redirect to %s.", location.c_str()); return ret; } @@ -840,28 +840,28 @@ char* ISrsHttpMessage::http_ts_send_buffer() #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 -* 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. -*/ + * + * Additional changes are licensed under the same terms as NGINX and + * 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. + */ //#include "http_parser.h" #include #include diff --git a/trunk/src/protocol/srs_http_stack.hpp b/trunk/src/protocol/srs_http_stack.hpp index 30b40c46c..d45f94c9a 100644 --- a/trunk/src/protocol/srs_http_stack.hpp +++ b/trunk/src/protocol/srs_http_stack.hpp @@ -1,32 +1,29 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_PROTOCOL_HTTP_HPP #define SRS_PROTOCOL_HTTP_HPP -/* -#include -*/ #include // default http listen port. @@ -232,10 +229,10 @@ public: * @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 + * 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 + * or by chunked), because the sdk never know whether there is no data or * infinite chunked. */ virtual int read(char* data, int nb_data, int* nb_read) = 0; @@ -660,37 +657,37 @@ extern "C" { /* 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) \ + 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 { @@ -719,45 +716,45 @@ XX(25, PURGE, PURGE) \ * 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") + /* 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 */ diff --git a/trunk/src/protocol/srs_kafka_stack.cpp b/trunk/src/protocol/srs_kafka_stack.cpp index ddfc17d3c..f21ad90d9 100644 --- a/trunk/src/protocol/srs_kafka_stack.cpp +++ b/trunk/src/protocol/srs_kafka_stack.cpp @@ -1,24 +1,24 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. */ #include @@ -850,7 +850,7 @@ int SrsKafkaBroker::encode(SrsBuffer* buf) return ret; } buf->write_4bytes(port); - + return ret; } diff --git a/trunk/src/protocol/srs_kafka_stack.hpp b/trunk/src/protocol/srs_kafka_stack.hpp index 08ea1209a..90b9f49fd 100644 --- a/trunk/src/protocol/srs_kafka_stack.hpp +++ b/trunk/src/protocol/srs_kafka_stack.hpp @@ -1,32 +1,29 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_PROTOCOL_KAFKA_HPP #define SRS_PROTOCOL_KAFKA_HPP -/* -#include -*/ #include #include @@ -62,7 +59,7 @@ enum SrsKafkaApiKey }; /** - * These types consist of a signed integer giving a length N followed by N bytes of content. + * These types consist of a signed integer giving a length N followed by N bytes of content. * A length of -1 indicates null. string uses an int16 for its size, and bytes uses an int32. * @see https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol#AGuideToTheKafkaProtocol-ProtocolPrimitiveTypes */ @@ -117,11 +114,11 @@ public: }; /** - * This is a notation for handling repeated structures. These will always be encoded as an - * int32 size containing the length N followed by N repetitions of the structure which can - * itself be made up of other primitive types. In the BNF grammars below we will show an + * This is a notation for handling repeated structures. These will always be encoded as an + * int32 size containing the length N followed by N repetitions of the structure which can + * itself be made up of other primitive types. In the BNF grammars below we will show an * array of a structure foo as [foo]. - * + * * Usage: * SrsKafkaArray body; * body.append(new SrsKafkaBytes()); @@ -260,7 +257,7 @@ public: { return elems.at(index); } - // interface ISrsCodec +// interface ISrsCodec public: virtual int nb_bytes() { @@ -327,15 +324,15 @@ private: int32_t _size; private: /** - * This is a numeric id for the API being invoked (i.e. is it + * This is a numeric id for the API being invoked (i.e. is it * a metadata request, a produce request, a fetch request, etc). * @remark MetadataRequest | ProduceRequest | FetchRequest | OffsetRequest | OffsetCommitRequest | OffsetFetchRequest */ int16_t _api_key; /** - * This is a numeric version number for this api. We version each API and - * this version number allows the server to properly interpret the request - * as the protocol evolves. Responses will always be in the format corresponding + * This is a numeric version number for this api. We version each API and + * this version number allows the server to properly interpret the request + * as the protocol evolves. Responses will always be in the format corresponding * to the request version. Currently the supported version for all APIs is 0. */ int16_t api_version; @@ -346,7 +343,7 @@ private: */ int32_t _correlation_id; /** - * This is a user supplied identifier for the client application. + * This is a user supplied identifier for the client application. * The user can use any identifier they like and it will be used * when logging errors, monitoring aggregates, etc. For example, * one might want to monitor not just the requests per second overall, @@ -493,7 +490,7 @@ public: */ struct SrsKafkaRawMessage : public ISrsCodec { -// metadata. + // metadata. public: /** * This is the offset used in kafka as the log sequence number. When the @@ -505,15 +502,15 @@ public: * the size of this message. */ int32_t message_size; -// message. + // message. public: /** - * The CRC is the CRC32 of the remainder of the message bytes. + * The CRC is the CRC32 of the remainder of the message bytes. * This is used to check the integrity of the message on the broker and consumer. */ int32_t crc; /** - * This is a version id used to allow backwards compatible evolution + * This is a version id used to allow backwards compatible evolution * of the message binary format. The current value is 0. */ int8_t magic_byte; @@ -524,7 +521,7 @@ public: */ int8_t attributes; /** - * The key is an optional message key that was used for + * The key is an optional message key that was used for * partition assignment. The key can be null. */ SrsKafkaBytes* key; @@ -592,7 +589,7 @@ public: */ virtual void update_header(int s); /** - * get the correlation id of header for message. + * get the correlation id of header for message. */ virtual int32_t correlation_id(); /** @@ -638,7 +635,7 @@ public: * What is the host and port for each of these brokers? * This is the only request that can be addressed to any broker in the cluster. * - * Since there may be many topics the client can give an optional list of topic + * Since there may be many topics the client can give an optional list of topic * names in order to only return metadata for a subset of topics. * * @see https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol#AGuideToTheKafkaProtocol-MetadataAPI @@ -713,9 +710,9 @@ public: /** * response for the metadata request from broker. - * The response contains metadata for each partition, - * with partitions grouped together by topic. This - * metadata refers to brokers by their broker id. + * The response contains metadata for each partition, + * with partitions grouped together by topic. This + * metadata refers to brokers by their broker id. * The brokers each have a host and port. * @see https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol#AGuideToTheKafkaProtocol-MetadataResponse */ @@ -786,25 +783,25 @@ class SrsKafkaProducerRequest : public SrsKafkaRequest { public: /** - * This field indicates how many acknowledgements the servers should receive - * before responding to the request. If it is 0 the server will not send any - * response (this is the only case where the server will not reply to a request). - * If it is 1, the server will wait the data is written to the local log - * before sending a response. If it is -1 the server will block until the - * message is committed by all in sync replicas before sending a response. - * For any number > 1 the server will block waiting for this number of - * acknowledgements to occur (but the server will never wait for more + * This field indicates how many acknowledgements the servers should receive + * before responding to the request. If it is 0 the server will not send any + * response (this is the only case where the server will not reply to a request). + * If it is 1, the server will wait the data is written to the local log + * before sending a response. If it is -1 the server will block until the + * message is committed by all in sync replicas before sending a response. + * For any number > 1 the server will block waiting for this number of + * acknowledgements to occur (but the server will never wait for more * acknowledgements than there are in-sync replicas). */ int16_t required_acks; /** - * This provides a maximum time in milliseconds the server can await the receipt - * of the number of acknowledgements in RequiredAcks. The timeout is not an exact - * limit on the request time for a few reasons: (1) it does not include network - * latency, (2) the timer begins at the beginning of the processing of this request - * so if many requests are queued due to server overload that wait time will not - * be included, (3) we will not terminate a local write so if the local write - * time exceeds this timeout it will not be respected. To get a hard timeout of + * This provides a maximum time in milliseconds the server can await the receipt + * of the number of acknowledgements in RequiredAcks. The timeout is not an exact + * limit on the request time for a few reasons: (1) it does not include network + * latency, (2) the timer begins at the beginning of the processing of this request + * so if many requests are queued due to server overload that wait time will not + * be included, (3) we will not terminate a local write so if the local write + * time exceeds this timeout it will not be respected. To get a hard timeout of * this type the client should use the socket timeout. */ int32_t timeout; @@ -824,8 +821,8 @@ public: /** * the poll to discovery reponse. - * @param CorrelationId This is a user-supplied integer. It will be passed back - * in the response by the server, unmodified. It is useful for matching + * @param CorrelationId This is a user-supplied integer. It will be passed back + * in the response by the server, unmodified. It is useful for matching * request and response between the client and server. * @see https://cwiki.apache.org/confluence/display/KAFKA/A+Guide+To+The+Kafka+Protocol#AGuideToTheKafkaProtocol-Requests */ diff --git a/trunk/src/protocol/srs_protocol_amf0.cpp b/trunk/src/protocol/srs_protocol_amf0.cpp index e85a38328..6dc9b115e 100644 --- a/trunk/src/protocol/srs_protocol_amf0.cpp +++ b/trunk/src/protocol/srs_protocol_amf0.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -210,8 +210,8 @@ void srs_amf0_do_print(SrsAmf0Any* any, stringstream& ss, int level) } else if (any->is_string()) { ss << "String " << any->to_str() << endl; } else if (any->is_date()) { - ss << "Date " << std::hex << any->to_date() - << "/" << std::hex << any->to_date_time_zone() << endl; + ss << "Date " << std::hex << any->to_date() + << "/" << std::hex << any->to_date_time_zone() << endl; } else if (any->is_null()) { ss << "Null" << endl; } else if (any->is_ecma_array()) { @@ -618,7 +618,7 @@ int SrsAmf0ObjectEOF::read(SrsBuffer* stream) if (temp != 0x00) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 read object eof value check failed. " - "must be 0x00, actual is %#x, ret=%d", temp, ret); + "must be 0x00, actual is %#x, ret=%d", temp, ret); return ret; } @@ -633,7 +633,7 @@ int SrsAmf0ObjectEOF::read(SrsBuffer* stream) if (marker != RTMP_AMF0_ObjectEnd) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 check object eof marker failed. " - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_ObjectEnd, ret); + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_ObjectEnd, ret); return ret; } srs_verbose("amf0 read object eof marker success"); @@ -719,7 +719,7 @@ int SrsAmf0Object::read(SrsBuffer* stream) if (marker != RTMP_AMF0_Object) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 check object marker failed. " - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret); + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Object, ret); return ret; } srs_verbose("amf0 read object marker success"); @@ -747,7 +747,7 @@ int SrsAmf0Object::read(SrsBuffer* stream) SrsAmf0Any* property_value = NULL; if ((ret = srs_amf0_read_any(stream, &property_value)) != ERROR_SUCCESS) { srs_error("amf0 object read property_value failed. " - "name=%s, ret=%d", property_name.c_str(), ret); + "name=%s, ret=%d", property_name.c_str(), ret); srs_freep(property_value); return ret; } @@ -918,11 +918,11 @@ int SrsAmf0EcmaArray::read(SrsBuffer* stream) if (marker != RTMP_AMF0_EcmaArray) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 check ecma_array marker failed. " - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_EcmaArray, ret); + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_EcmaArray, ret); return ret; } srs_verbose("amf0 read ecma_array marker success"); - + // count if (!stream->require(4)) { ret = ERROR_RTMP_AMF0_DECODE; @@ -935,7 +935,7 @@ int SrsAmf0EcmaArray::read(SrsBuffer* stream) // value this->_count = count; - + while (!stream->empty()) { // detect whether is eof. if (srs_amf0_is_object_eof(stream)) { @@ -958,7 +958,7 @@ int SrsAmf0EcmaArray::read(SrsBuffer* stream) SrsAmf0Any* property_value = NULL; if ((ret = srs_amf0_read_any(stream, &property_value)) != ERROR_SUCCESS) { srs_error("amf0 ecma_array read property_value failed. " - "name=%s, ret=%d", property_name.c_str(), ret); + "name=%s, ret=%d", property_name.c_str(), ret); return ret; } @@ -981,7 +981,7 @@ int SrsAmf0EcmaArray::write(SrsBuffer* stream) stream->write_1bytes(RTMP_AMF0_EcmaArray); srs_verbose("amf0 write ecma_array marker success"); - + // count if (!stream->require(4)) { ret = ERROR_RTMP_AMF0_ENCODE; @@ -1130,11 +1130,11 @@ int SrsAmf0StrictArray::read(SrsBuffer* stream) if (marker != RTMP_AMF0_StrictArray) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 check strict_array marker failed. " - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_StrictArray, ret); + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_StrictArray, ret); return ret; } srs_verbose("amf0 read strict_array marker success"); - + // count if (!stream->require(4)) { ret = ERROR_RTMP_AMF0_DECODE; @@ -1147,7 +1147,7 @@ int SrsAmf0StrictArray::read(SrsBuffer* stream) // value this->_count = count; - + for (int i = 0; i < count && !stream->empty(); i++) { // property-value: any SrsAmf0Any* elem = NULL; @@ -1175,7 +1175,7 @@ int SrsAmf0StrictArray::write(SrsBuffer* stream) stream->write_1bytes(RTMP_AMF0_StrictArray); srs_verbose("amf0 write strict_array marker success"); - + // count if (!stream->require(4)) { ret = ERROR_RTMP_AMF0_ENCODE; @@ -1454,14 +1454,14 @@ int SrsAmf0Date::read(SrsBuffer* stream) if (marker != RTMP_AMF0_Date) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 check date marker failed. " - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Date, ret); + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Date, ret); return ret; } srs_verbose("amf0 read date marker success"); - + // date value - // An ActionScript Date is serialized as the number of milliseconds - // elapsed since the epoch of midnight on 1st Jan 1970 in the UTC + // An ActionScript Date is serialized as the number of milliseconds + // elapsed since the epoch of midnight on 1st Jan 1970 in the UTC // time zone. if (!stream->require(8)) { ret = ERROR_RTMP_AMF0_DECODE; @@ -1473,9 +1473,9 @@ int SrsAmf0Date::read(SrsBuffer* stream) srs_verbose("amf0 read date success. date=%"PRId64, _date_value); // time zone - // While the design of this type reserves room for time zone offset - // information, it should not be filled in, nor used, as it is unconventional - // to change time zones when serializing dates on a network. It is suggested + // While the design of this type reserves room for time zone offset + // information, it should not be filled in, nor used, as it is unconventional + // to change time zones when serializing dates on a network. It is suggested // that the time zone be queried independently as needed. if (!stream->require(2)) { ret = ERROR_RTMP_AMF0_DECODE; @@ -1501,7 +1501,7 @@ int SrsAmf0Date::write(SrsBuffer* stream) stream->write_1bytes(RTMP_AMF0_Date); srs_verbose("amf0 write date marker success"); - + // date value if (!stream->require(8)) { ret = ERROR_RTMP_AMF0_ENCODE; @@ -1511,7 +1511,7 @@ int SrsAmf0Date::write(SrsBuffer* stream) stream->write_8bytes(_date_value); srs_verbose("amf0 write date success. date=%"PRId64, _date_value); - + // time zone if (!stream->require(2)) { ret = ERROR_RTMP_AMF0_ENCODE; @@ -1642,7 +1642,7 @@ int srs_amf0_read_string(SrsBuffer* stream, string& value) if (marker != RTMP_AMF0_String) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 check string marker failed. " - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_String, ret); + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_String, ret); return ret; } srs_verbose("amf0 read string marker success"); @@ -1682,18 +1682,18 @@ int srs_amf0_read_boolean(SrsBuffer* stream, bool& value) if (marker != RTMP_AMF0_Boolean) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 check bool marker failed. " - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Boolean, ret); + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Boolean, ret); return ret; } srs_verbose("amf0 read bool marker success"); - + // value if (!stream->require(1)) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 read bool value failed. ret=%d", ret); return ret; } - + value = (stream->read_1bytes() != 0); srs_verbose("amf0 read bool value success. value=%d", value); @@ -1712,14 +1712,14 @@ int srs_amf0_write_boolean(SrsBuffer* stream, bool value) } stream->write_1bytes(RTMP_AMF0_Boolean); srs_verbose("amf0 write bool marker success"); - + // value if (!stream->require(1)) { ret = ERROR_RTMP_AMF0_ENCODE; srs_error("amf0 write bool value failed. ret=%d", ret); return ret; } - + if (value) { stream->write_1bytes(0x01); } else { @@ -1746,18 +1746,18 @@ int srs_amf0_read_number(SrsBuffer* stream, double& value) if (marker != RTMP_AMF0_Number) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 check number marker failed. " - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Number, ret); + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Number, ret); return ret; } srs_verbose("amf0 read number marker success"); - + // value if (!stream->require(8)) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 read number value failed. ret=%d", ret); return ret; } - + int64_t temp = stream->read_8bytes(); memcpy(&value, &temp, 8); @@ -1778,14 +1778,14 @@ int srs_amf0_write_number(SrsBuffer* stream, double value) stream->write_1bytes(RTMP_AMF0_Number); srs_verbose("amf0 write number marker success"); - + // value if (!stream->require(8)) { ret = ERROR_RTMP_AMF0_ENCODE; srs_error("amf0 write number value failed. ret=%d", ret); return ret; } - + int64_t temp = 0x00; memcpy(&temp, &value, 8); stream->write_8bytes(temp); @@ -1810,7 +1810,7 @@ int srs_amf0_read_null(SrsBuffer* stream) if (marker != RTMP_AMF0_Null) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 check null marker failed. " - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Null, ret); + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Null, ret); return ret; } srs_verbose("amf0 read null success"); @@ -1849,7 +1849,7 @@ int srs_amf0_read_undefined(SrsBuffer* stream) if (marker != RTMP_AMF0_Undefined) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 check undefined marker failed. " - "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Undefined, ret); + "marker=%#x, required=%#x, ret=%d", marker, RTMP_AMF0_Undefined, ret); return ret; } srs_verbose("amf0 read undefined success"); @@ -1908,13 +1908,13 @@ namespace _srs_internal // UTF8-1 = %x00-7F // TODO: support other utf-8 strings /*for (int i = 0; i < len; i++) { - char ch = *(str.data() + i); - if ((ch & 0x80) != 0) { - ret = ERROR_RTMP_AMF0_DECODE; - srs_error("ignored. only support utf8-1, 0x00-0x7F, actual is %#x. ret=%d", (int)ch, ret); - ret = ERROR_SUCCESS; - } - }*/ + char ch = *(str.data() + i); + if ((ch & 0x80) != 0) { + ret = ERROR_RTMP_AMF0_DECODE; + srs_error("ignored. only support utf8-1, 0x00-0x7F, actual is %#x. ret=%d", (int)ch, ret); + ret = ERROR_SUCCESS; + } + }*/ value = str; srs_verbose("amf0 read string data success. str=%s", str.c_str()); @@ -1952,7 +1952,7 @@ namespace _srs_internal return ret; } - bool srs_amf0_is_object_eof(SrsBuffer* stream) + bool srs_amf0_is_object_eof(SrsBuffer* stream) { // detect the object-eof specially if (stream->require(3)) { @@ -1993,7 +1993,7 @@ namespace _srs_internal return ret; } - + int srs_amf0_write_any(SrsBuffer* stream, SrsAmf0Any* value) { srs_assert(value != NULL); diff --git a/trunk/src/protocol/srs_protocol_amf0.hpp b/trunk/src/protocol/srs_protocol_amf0.hpp index 362f2a5d7..00c61d608 100644 --- a/trunk/src/protocol/srs_protocol_amf0.hpp +++ b/trunk/src/protocol/srs_protocol_amf0.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_PROTOCOL_AMF0_HPP #define SRS_PROTOCOL_AMF0_HPP -/* -#include -*/ - #include #include @@ -48,84 +44,84 @@ namespace _srs_internal } /* -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -Usages: - -1. the bytes proxy: SrsBuffer - // when we got some bytes from file or network, - // use SrsBuffer proxy to read/write bytes - - // for example, read bytes from file or network. - char* bytes = ...; - - // initialize the stream, proxy for bytes. - SrsBuffer stream; - stream.initialize(bytes); - - // use stream instead. - -2. directly read AMF0 any instance from stream: - SrsAmf0Any* pany = NULL; - srs_amf0_read_any(&stream, &pany); - -3. use SrsAmf0Any to discovery instance from stream: - SrsAmf0Any* pany = NULL; - SrsAmf0Any::discovery(&stream, &pany); - -4. directly read specified AMF0 instance value from stream: - string value; - srs_amf0_read_string(&stream, value); - -5. directly read specified AMF0 instance from stream: - SrsAmf0Any* str = SrsAmf0Any::str(); - str->read(&stream); - -6. get value from AMF0 instance: - // parse or set by other user - SrsAmf0Any* any = ...; - - if (any->is_string()) { - string str = any->to_string(); - } - -7. get complex object from AMF0 insance: - // parse or set by other user - SrsAmf0Any* any = ...; - - if (any->is_object()) { - SrsAmf0Object* obj = any->to_object(); - obj->set("width", SrsAmf0Any::number(1024)); - obj->set("height", SrsAmf0Any::number(576)); - } - -8. serialize AMF0 instance to bytes: - // parse or set by other user - SrsAmf0Any* any = ...; - - char* bytes = new char[any->total_size()]; - - SrsBuffer stream; - stream.initialize(bytes); - - any->write(&stream); - -@remark: for detail usage, see interfaces of each object. -@remark: all examples ignore the error process. -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////// -*/ + //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// + Usages: + + 1. the bytes proxy: SrsBuffer + // when we got some bytes from file or network, + // use SrsBuffer proxy to read/write bytes + + // for example, read bytes from file or network. + char* bytes = ...; + + // initialize the stream, proxy for bytes. + SrsBuffer stream; + stream.initialize(bytes); + + // use stream instead. + + 2. directly read AMF0 any instance from stream: + SrsAmf0Any* pany = NULL; + srs_amf0_read_any(&stream, &pany); + + 3. use SrsAmf0Any to discovery instance from stream: + SrsAmf0Any* pany = NULL; + SrsAmf0Any::discovery(&stream, &pany); + + 4. directly read specified AMF0 instance value from stream: + string value; + srs_amf0_read_string(&stream, value); + + 5. directly read specified AMF0 instance from stream: + SrsAmf0Any* str = SrsAmf0Any::str(); + str->read(&stream); + + 6. get value from AMF0 instance: + // parse or set by other user + SrsAmf0Any* any = ...; + + if (any->is_string()) { + string str = any->to_string(); + } + + 7. get complex object from AMF0 insance: + // parse or set by other user + SrsAmf0Any* any = ...; + + if (any->is_object()) { + SrsAmf0Object* obj = any->to_object(); + obj->set("width", SrsAmf0Any::number(1024)); + obj->set("height", SrsAmf0Any::number(576)); + } + + 8. serialize AMF0 instance to bytes: + // parse or set by other user + SrsAmf0Any* any = ...; + + char* bytes = new char[any->total_size()]; + + SrsBuffer stream; + stream.initialize(bytes); + + any->write(&stream); + + @remark: for detail usage, see interfaces of each object. + @remark: all examples ignore the error process. + //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// + */ /** -* any amf0 value. -* 2.1 Types Overview -* value-type = number-type | boolean-type | string-type | object-type -* | null-marker | undefined-marker | reference-type | ecma-array-type -* | strict-array-type | date-type | long-string-type | xml-document-type -* | typed-object-type -*/ + * any amf0 value. + * 2.1 Types Overview + * value-type = number-type | boolean-type | string-type | object-type + * | null-marker | undefined-marker | reference-type | ecma-array-type + * | strict-array-type | date-type | long-string-type | xml-document-type + * | typed-object-type + */ class SrsAmf0Any { public: @@ -133,209 +129,209 @@ public: public: SrsAmf0Any(); virtual ~SrsAmf0Any(); -// type identify, user should identify the type then convert from/to value. + // type identify, user should identify the type then convert from/to value. public: /** - * whether current instance is an AMF0 string. - * @return true if instance is an AMF0 string; otherwise, false. - * @remark, if true, use to_string() to get its value. - */ + * whether current instance is an AMF0 string. + * @return true if instance is an AMF0 string; otherwise, false. + * @remark, if true, use to_string() to get its value. + */ virtual bool is_string(); /** - * whether current instance is an AMF0 boolean. - * @return true if instance is an AMF0 boolean; otherwise, false. - * @remark, if true, use to_boolean() to get its value. - */ + * whether current instance is an AMF0 boolean. + * @return true if instance is an AMF0 boolean; otherwise, false. + * @remark, if true, use to_boolean() to get its value. + */ virtual bool is_boolean(); /** - * whether current instance is an AMF0 number. - * @return true if instance is an AMF0 number; otherwise, false. - * @remark, if true, use to_number() to get its value. - */ + * whether current instance is an AMF0 number. + * @return true if instance is an AMF0 number; otherwise, false. + * @remark, if true, use to_number() to get its value. + */ virtual bool is_number(); /** - * whether current instance is an AMF0 null. - * @return true if instance is an AMF0 null; otherwise, false. - */ + * whether current instance is an AMF0 null. + * @return true if instance is an AMF0 null; otherwise, false. + */ virtual bool is_null(); /** - * whether current instance is an AMF0 undefined. - * @return true if instance is an AMF0 undefined; otherwise, false. - */ + * whether current instance is an AMF0 undefined. + * @return true if instance is an AMF0 undefined; otherwise, false. + */ virtual bool is_undefined(); /** - * whether current instance is an AMF0 object. - * @return true if instance is an AMF0 object; otherwise, false. - * @remark, if true, use to_object() to get its value. - */ + * whether current instance is an AMF0 object. + * @return true if instance is an AMF0 object; otherwise, false. + * @remark, if true, use to_object() to get its value. + */ virtual bool is_object(); /** - * whether current instance is an AMF0 object-EOF. - * @return true if instance is an AMF0 object-EOF; otherwise, false. - */ + * whether current instance is an AMF0 object-EOF. + * @return true if instance is an AMF0 object-EOF; otherwise, false. + */ virtual bool is_object_eof(); /** - * whether current instance is an AMF0 ecma-array. - * @return true if instance is an AMF0 ecma-array; otherwise, false. - * @remark, if true, use to_ecma_array() to get its value. - */ + * whether current instance is an AMF0 ecma-array. + * @return true if instance is an AMF0 ecma-array; otherwise, false. + * @remark, if true, use to_ecma_array() to get its value. + */ virtual bool is_ecma_array(); /** - * whether current instance is an AMF0 strict-array. - * @return true if instance is an AMF0 strict-array; otherwise, false. - * @remark, if true, use to_strict_array() to get its value. - */ + * whether current instance is an AMF0 strict-array. + * @return true if instance is an AMF0 strict-array; otherwise, false. + * @remark, if true, use to_strict_array() to get its value. + */ virtual bool is_strict_array(); /** - * whether current instance is an AMF0 date. - * @return true if instance is an AMF0 date; otherwise, false. - * @remark, if true, use to_date() to get its value. - */ + * whether current instance is an AMF0 date. + * @return true if instance is an AMF0 date; otherwise, false. + * @remark, if true, use to_date() to get its value. + */ virtual bool is_date(); /** - * whether current instance is an AMF0 object, object-EOF, ecma-array or strict-array. - */ + * whether current instance is an AMF0 object, object-EOF, ecma-array or strict-array. + */ virtual bool is_complex_object(); -// get value of instance + // get value of instance public: /** - * get a string copy of instance. - * @remark assert is_string(), user must ensure the type then convert. - */ + * get a string copy of instance. + * @remark assert is_string(), user must ensure the type then convert. + */ virtual std::string to_str(); /** - * get the raw str of instance, - * user can directly set the content of str. - * @remark assert is_string(), user must ensure the type then convert. - */ + * get the raw str of instance, + * user can directly set the content of str. + * @remark assert is_string(), user must ensure the type then convert. + */ virtual const char* to_str_raw(); /** - * convert instance to amf0 boolean, - * @remark assert is_boolean(), user must ensure the type then convert. - */ + * convert instance to amf0 boolean, + * @remark assert is_boolean(), user must ensure the type then convert. + */ virtual bool to_boolean(); /** - * convert instance to amf0 number, - * @remark assert is_number(), user must ensure the type then convert. - */ + * convert instance to amf0 number, + * @remark assert is_number(), user must ensure the type then convert. + */ virtual double to_number(); /** - * convert instance to date, - * @remark assert is_date(), user must ensure the type then convert. - */ + * convert instance to date, + * @remark assert is_date(), user must ensure the type then convert. + */ virtual int64_t to_date(); virtual int16_t to_date_time_zone(); /** - * convert instance to amf0 object, - * @remark assert is_object(), user must ensure the type then convert. - */ + * convert instance to amf0 object, + * @remark assert is_object(), user must ensure the type then convert. + */ virtual SrsAmf0Object* to_object(); /** - * convert instance to ecma array, - * @remark assert is_ecma_array(), user must ensure the type then convert. - */ + * convert instance to ecma array, + * @remark assert is_ecma_array(), user must ensure the type then convert. + */ virtual SrsAmf0EcmaArray* to_ecma_array(); /** - * convert instance to strict array, - * @remark assert is_strict_array(), user must ensure the type then convert. - */ + * convert instance to strict array, + * @remark assert is_strict_array(), user must ensure the type then convert. + */ virtual SrsAmf0StrictArray* to_strict_array(); -// set value of instance + // set value of instance public: /** - * set the number of any when is_number() indicates true. - * user must ensure the type is a number, or assert failed. - */ + * set the number of any when is_number() indicates true. + * user must ensure the type is a number, or assert failed. + */ virtual void set_number(double value); -// serialize/deseriaize instance. + // serialize/deseriaize instance. public: /** - * get the size of amf0 any, including the marker size. - * the size is the bytes which instance serialized to. - */ + * get the size of amf0 any, including the marker size. + * the size is the bytes which instance serialized to. + */ virtual int total_size() = 0; /** - * read AMF0 instance from stream. - */ + * read AMF0 instance from stream. + */ virtual int read(SrsBuffer* stream) = 0; /** - * write AMF0 instance to stream. - */ + * write AMF0 instance to stream. + */ virtual int write(SrsBuffer* stream) = 0; /** - * copy current AMF0 instance. - */ + * copy current AMF0 instance. + */ virtual SrsAmf0Any* copy() = 0; /** - * human readable print - * @param pdata, output the heap data, NULL to ignore. - * @return return the *pdata for print. NULL to ignore. - * @remark user must free the data returned or output by pdata. - */ + * human readable print + * @param pdata, output the heap data, NULL to ignore. + * @return return the *pdata for print. NULL to ignore. + * @remark user must free the data returned or output by pdata. + */ virtual char* human_print(char** pdata, int* psize); /** * convert amf0 to json. */ virtual SrsJsonAny* to_json(); -// create AMF0 instance. + // create AMF0 instance. public: /** - * create an AMF0 string instance, set string content by value. - */ - static SrsAmf0Any* str(const char* value = NULL); + * create an AMF0 string instance, set string content by value. + */ + static SrsAmf0Any* str(const char* value = NULL); /** - * create an AMF0 boolean instance, set boolean content by value. - */ + * create an AMF0 boolean instance, set boolean content by value. + */ static SrsAmf0Any* boolean(bool value = false); /** - * create an AMF0 number instance, set number content by value. - */ + * create an AMF0 number instance, set number content by value. + */ static SrsAmf0Any* number(double value = 0.0); /** - * create an AMF0 date instance - */ + * create an AMF0 date instance + */ static SrsAmf0Any* date(int64_t value = 0); /** - * create an AMF0 null instance - */ + * create an AMF0 null instance + */ static SrsAmf0Any* null(); /** - * create an AMF0 undefined instance - */ + * create an AMF0 undefined instance + */ static SrsAmf0Any* undefined(); /** - * create an AMF0 empty object instance - */ + * create an AMF0 empty object instance + */ static SrsAmf0Object* object(); /** - * create an AMF0 object-EOF instance - */ + * create an AMF0 object-EOF instance + */ static SrsAmf0Any* object_eof(); /** - * create an AMF0 empty ecma-array instance - */ + * create an AMF0 empty ecma-array instance + */ static SrsAmf0EcmaArray* ecma_array(); /** - * create an AMF0 empty strict-array instance - */ + * create an AMF0 empty strict-array instance + */ static SrsAmf0StrictArray* strict_array(); -// discovery instance from stream + // discovery instance from stream public: /** - * discovery AMF0 instance from stream - * @param ppvalue, output the discoveried AMF0 instance. - * NULL if error. - * @remark, instance is created without read from stream, user must - * use (*ppvalue)->read(stream) to get the instance. - */ + * discovery AMF0 instance from stream + * @param ppvalue, output the discoveried AMF0 instance. + * NULL if error. + * @remark, instance is created without read from stream, user must + * use (*ppvalue)->read(stream) to get the instance. + */ static int discovery(SrsBuffer* stream, SrsAmf0Any** ppvalue); }; /** -* 2.5 Object Type -* anonymous-object-type = object-marker *(object-property) -* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) -*/ + * 2.5 Object Type + * anonymous-object-type = object-marker *(object-property) + * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) + */ class SrsAmf0Object : public SrsAmf0Any { private: @@ -344,13 +340,13 @@ private: private: friend class SrsAmf0Any; /** - * make amf0 object to private, - * use should never declare it, use SrsAmf0Any::object() to create it. - */ + * make amf0 object to private, + * use should never declare it, use SrsAmf0Any::object() to create it. + */ SrsAmf0Object(); public: virtual ~SrsAmf0Object(); -// serialize/deserialize to/from stream. + // serialize/deserialize to/from stream. public: virtual int total_size(); virtual int read(SrsBuffer* stream); @@ -360,59 +356,59 @@ public: * convert amf0 to json. */ virtual SrsJsonAny* to_json(); -// properties iteration + // properties iteration public: /** - * clear all propergies. - */ + * clear all propergies. + */ virtual void clear(); /** - * get the count of properties(key:value). - */ + * get the count of properties(key:value). + */ virtual int count(); /** - * get the property(key:value) key at index. - * @remark: max index is count(). - */ + * get the property(key:value) key at index. + * @remark: max index is count(). + */ virtual std::string key_at(int index); /** - * get the property(key:value) key raw bytes at index. - * user can directly set the key bytes. - * @remark: max index is count(). - */ + * get the property(key:value) key raw bytes at index. + * user can directly set the key bytes. + * @remark: max index is count(). + */ virtual const char* key_raw_at(int index); /** - * get the property(key:value) value at index. - * @remark: max index is count(). - */ + * get the property(key:value) value at index. + * @remark: max index is count(). + */ virtual SrsAmf0Any* value_at(int index); -// property set/get. + // property set/get. public: /** - * set the property(key:value) of object, - * @param key, string property name. - * @param value, an AMF0 instance property value. - * @remark user should never free the value, this instance will manage it. - */ + * set the property(key:value) of object, + * @param key, string property name. + * @param value, an AMF0 instance property value. + * @remark user should never free the value, this instance will manage it. + */ virtual void set(std::string key, SrsAmf0Any* value); /** - * get the property(key:value) of object, - * @param name, the property name/key - * @return the property AMF0 value, NULL if not found. - * @remark user should never free the returned value, copy it if needed. - */ + * get the property(key:value) of object, + * @param name, the property name/key + * @return the property AMF0 value, NULL if not found. + * @remark user should never free the returned value, copy it if needed. + */ virtual SrsAmf0Any* get_property(std::string name); /** - * get the string property, ensure the property is_string(). - * @return the property AMF0 value, NULL if not found, or not a string. - * @remark user should never free the returned value, copy it if needed. - */ + * get the string property, ensure the property is_string(). + * @return the property AMF0 value, NULL if not found, or not a string. + * @remark user should never free the returned value, copy it if needed. + */ virtual SrsAmf0Any* ensure_property_string(std::string name); /** - * get the number property, ensure the property is_number(). - * @return the property AMF0 value, NULL if not found, or not a number. - * @remark user should never free the returned value, copy it if needed. - */ + * get the number property, ensure the property is_number(). + * @return the property AMF0 value, NULL if not found, or not a number. + * @remark user should never free the returned value, copy it if needed. + */ virtual SrsAmf0Any* ensure_property_number(std::string name); /** * remove the property specified by name. @@ -421,11 +417,11 @@ public: }; /** -* 2.10 ECMA Array Type -* ecma-array-type = associative-count *(object-property) -* associative-count = U32 -* object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) -*/ + * 2.10 ECMA Array Type + * ecma-array-type = associative-count *(object-property) + * associative-count = U32 + * object-property = (UTF-8 value-type) | (UTF-8-empty object-end-marker) + */ class SrsAmf0EcmaArray : public SrsAmf0Any { private: @@ -435,13 +431,13 @@ private: private: friend class SrsAmf0Any; /** - * make amf0 object to private, - * use should never declare it, use SrsAmf0Any::ecma_array() to create it. - */ + * make amf0 object to private, + * use should never declare it, use SrsAmf0Any::ecma_array() to create it. + */ SrsAmf0EcmaArray(); public: virtual ~SrsAmf0EcmaArray(); -// serialize/deserialize to/from stream. + // serialize/deserialize to/from stream. public: virtual int total_size(); virtual int read(SrsBuffer* stream); @@ -451,67 +447,67 @@ public: * convert amf0 to json. */ virtual SrsJsonAny* to_json(); -// properties iteration + // properties iteration public: /** - * clear all propergies. - */ + * clear all propergies. + */ virtual void clear(); /** - * get the count of properties(key:value). - */ + * get the count of properties(key:value). + */ virtual int count(); /** - * get the property(key:value) key at index. - * @remark: max index is count(). - */ + * get the property(key:value) key at index. + * @remark: max index is count(). + */ virtual std::string key_at(int index); /** - * get the property(key:value) key raw bytes at index. - * user can directly set the key bytes. - * @remark: max index is count(). - */ + * get the property(key:value) key raw bytes at index. + * user can directly set the key bytes. + * @remark: max index is count(). + */ virtual const char* key_raw_at(int index); /** - * get the property(key:value) value at index. - * @remark: max index is count(). - */ + * get the property(key:value) value at index. + * @remark: max index is count(). + */ virtual SrsAmf0Any* value_at(int index); -// property set/get. + // property set/get. public: /** - * set the property(key:value) of array, - * @param key, string property name. - * @param value, an AMF0 instance property value. - * @remark user should never free the value, this instance will manage it. - */ + * set the property(key:value) of array, + * @param key, string property name. + * @param value, an AMF0 instance property value. + * @remark user should never free the value, this instance will manage it. + */ virtual void set(std::string key, SrsAmf0Any* value); /** - * get the property(key:value) of array, - * @param name, the property name/key - * @return the property AMF0 value, NULL if not found. - * @remark user should never free the returned value, copy it if needed. - */ + * get the property(key:value) of array, + * @param name, the property name/key + * @return the property AMF0 value, NULL if not found. + * @remark user should never free the returned value, copy it if needed. + */ virtual SrsAmf0Any* get_property(std::string name); /** - * get the string property, ensure the property is_string(). - * @return the property AMF0 value, NULL if not found, or not a string. - * @remark user should never free the returned value, copy it if needed. - */ + * get the string property, ensure the property is_string(). + * @return the property AMF0 value, NULL if not found, or not a string. + * @remark user should never free the returned value, copy it if needed. + */ virtual SrsAmf0Any* ensure_property_string(std::string name); /** - * get the number property, ensure the property is_number(). - * @return the property AMF0 value, NULL if not found, or not a number. - * @remark user should never free the returned value, copy it if needed. - */ + * get the number property, ensure the property is_number(). + * @return the property AMF0 value, NULL if not found, or not a number. + * @remark user should never free the returned value, copy it if needed. + */ virtual SrsAmf0Any* ensure_property_number(std::string name); }; /** -* 2.12 Strict Array Type -* array-count = U32 -* strict-array-type = array-count *(value-type) -*/ + * 2.12 Strict Array Type + * array-count = U32 + * strict-array-type = array-count *(value-type) + */ class SrsAmf0StrictArray : public SrsAmf0Any { private: @@ -520,13 +516,13 @@ private: private: friend class SrsAmf0Any; /** - * make amf0 object to private, - * use should never declare it, use SrsAmf0Any::strict_array() to create it. - */ + * make amf0 object to private, + * use should never declare it, use SrsAmf0Any::strict_array() to create it. + */ SrsAmf0StrictArray(); public: virtual ~SrsAmf0StrictArray(); -// serialize/deserialize to/from stream. + // serialize/deserialize to/from stream. public: virtual int total_size(); virtual int read(SrsBuffer* stream); @@ -536,34 +532,34 @@ public: * convert amf0 to json. */ virtual SrsJsonAny* to_json(); -// properties iteration + // properties iteration public: /** - * clear all elements. - */ + * clear all elements. + */ virtual void clear(); /** - * get the count of elements - */ + * get the count of elements + */ virtual int count(); /** - * get the elements key at index. - * @remark: max index is count(). - */ + * get the elements key at index. + * @remark: max index is count(). + */ virtual SrsAmf0Any* at(int index); -// property set/get. + // property set/get. public: /** - * append new element to array - * @param any, an AMF0 instance property value. - * @remark user should never free the any, this instance will manage it. - */ + * append new element to array + * @param any, an AMF0 instance property value. + * @remark user should never free the any, this instance will manage it. + */ virtual void append(SrsAmf0Any* any); }; /** -* the class to get amf0 object size -*/ + * the class to get amf0 object size + */ class SrsAmf0Size { public: @@ -582,50 +578,50 @@ public: }; /** -* read anything from stream. -* @param ppvalue, the output amf0 any elem. -* NULL if error; otherwise, never NULL and user must free it. -*/ + * read anything from stream. + * @param ppvalue, the output amf0 any elem. + * NULL if error; otherwise, never NULL and user must free it. + */ extern int srs_amf0_read_any(SrsBuffer* stream, SrsAmf0Any** ppvalue); /** -* read amf0 string from stream. -* 2.4 String Type -* string-type = string-marker UTF-8 -*/ + * read amf0 string from stream. + * 2.4 String Type + * string-type = string-marker UTF-8 + */ extern int srs_amf0_read_string(SrsBuffer* stream, std::string& value); extern int srs_amf0_write_string(SrsBuffer* stream, std::string value); /** -* read amf0 boolean from stream. -* 2.4 String Type -* boolean-type = boolean-marker U8 -* 0 is false, <> 0 is true -*/ + * read amf0 boolean from stream. + * 2.4 String Type + * boolean-type = boolean-marker U8 + * 0 is false, <> 0 is true + */ extern int srs_amf0_read_boolean(SrsBuffer* stream, bool& value); extern int srs_amf0_write_boolean(SrsBuffer* stream, bool value); /** -* read amf0 number from stream. -* 2.2 Number Type -* number-type = number-marker DOUBLE -*/ + * read amf0 number from stream. + * 2.2 Number Type + * number-type = number-marker DOUBLE + */ extern int srs_amf0_read_number(SrsBuffer* stream, double& value); extern int srs_amf0_write_number(SrsBuffer* stream, double value); /** -* read amf0 null from stream. -* 2.7 null Type -* null-type = null-marker -*/ + * read amf0 null from stream. + * 2.7 null Type + * null-type = null-marker + */ extern int srs_amf0_read_null(SrsBuffer* stream); extern int srs_amf0_write_null(SrsBuffer* stream); /** -* read amf0 undefined from stream. -* 2.8 undefined Type -* undefined-type = undefined-marker -*/ + * read amf0 undefined from stream. + * 2.8 undefined Type + * undefined-type = undefined-marker + */ extern int srs_amf0_read_undefined(SrsBuffer* stream); extern int srs_amf0_write_undefined(SrsBuffer* stream); @@ -633,12 +629,12 @@ extern int srs_amf0_write_undefined(SrsBuffer* stream); namespace _srs_internal { /** - * read amf0 string from stream. - * 2.4 String Type - * string-type = string-marker UTF-8 - * @return default value is empty string. - * @remark: use SrsAmf0Any::str() to create it. - */ + * read amf0 string from stream. + * 2.4 String Type + * string-type = string-marker UTF-8 + * @return default value is empty string. + * @remark: use SrsAmf0Any::str() to create it. + */ class SrsAmf0String : public SrsAmf0Any { public: @@ -646,9 +642,9 @@ namespace _srs_internal private: friend class SrsAmf0Any; /** - * make amf0 string to private, - * use should never declare it, use SrsAmf0Any::str() to create it. - */ + * make amf0 string to private, + * use should never declare it, use SrsAmf0Any::str() to create it. + */ SrsAmf0String(const char* _value); public: virtual ~SrsAmf0String(); @@ -660,12 +656,12 @@ namespace _srs_internal }; /** - * read amf0 boolean from stream. - * 2.4 String Type - * boolean-type = boolean-marker U8 - * 0 is false, <> 0 is true - * @return default value is false. - */ + * read amf0 boolean from stream. + * 2.4 String Type + * boolean-type = boolean-marker U8 + * 0 is false, <> 0 is true + * @return default value is false. + */ class SrsAmf0Boolean : public SrsAmf0Any { public: @@ -673,9 +669,9 @@ namespace _srs_internal private: friend class SrsAmf0Any; /** - * make amf0 boolean to private, - * use should never declare it, use SrsAmf0Any::boolean() to create it. - */ + * make amf0 boolean to private, + * use should never declare it, use SrsAmf0Any::boolean() to create it. + */ SrsAmf0Boolean(bool _value); public: virtual ~SrsAmf0Boolean(); @@ -687,11 +683,11 @@ namespace _srs_internal }; /** - * read amf0 number from stream. - * 2.2 Number Type - * number-type = number-marker DOUBLE - * @return default value is 0. - */ + * read amf0 number from stream. + * 2.2 Number Type + * number-type = number-marker DOUBLE + * @return default value is 0. + */ class SrsAmf0Number : public SrsAmf0Any { public: @@ -699,9 +695,9 @@ namespace _srs_internal private: friend class SrsAmf0Any; /** - * make amf0 number to private, - * use should never declare it, use SrsAmf0Any::number() to create it. - */ + * make amf0 number to private, + * use should never declare it, use SrsAmf0Any::number() to create it. + */ SrsAmf0Number(double _value); public: virtual ~SrsAmf0Number(); @@ -713,11 +709,11 @@ namespace _srs_internal }; /** - * 2.13 Date Type - * time-zone = S16 ; reserved, not supported should be set to 0x0000 - * date-type = date-marker DOUBLE time-zone - * @see: https://github.com/ossrs/srs/issues/185 - */ + * 2.13 Date Type + * time-zone = S16 ; reserved, not supported should be set to 0x0000 + * date-type = date-marker DOUBLE time-zone + * @see: https://github.com/ossrs/srs/issues/185 + */ class SrsAmf0Date : public SrsAmf0Any { private: @@ -726,13 +722,13 @@ namespace _srs_internal private: friend class SrsAmf0Any; /** - * make amf0 date to private, - * use should never declare it, use SrsAmf0Any::date() to create it. - */ + * make amf0 date to private, + * use should never declare it, use SrsAmf0Any::date() to create it. + */ SrsAmf0Date(int64_t value); public: virtual ~SrsAmf0Date(); - // serialize/deserialize to/from stream. + // serialize/deserialize to/from stream. public: virtual int total_size(); virtual int read(SrsBuffer* stream); @@ -740,28 +736,28 @@ namespace _srs_internal virtual SrsAmf0Any* copy(); public: /** - * get the date value. - */ + * get the date value. + */ virtual int64_t date(); /** - * get the time_zone. - */ + * get the time_zone. + */ virtual int16_t time_zone(); }; /** - * read amf0 null from stream. - * 2.7 null Type - * null-type = null-marker - */ + * read amf0 null from stream. + * 2.7 null Type + * null-type = null-marker + */ class SrsAmf0Null : public SrsAmf0Any { private: friend class SrsAmf0Any; /** - * make amf0 null to private, - * use should never declare it, use SrsAmf0Any::null() to create it. - */ + * make amf0 null to private, + * use should never declare it, use SrsAmf0Any::null() to create it. + */ SrsAmf0Null(); public: virtual ~SrsAmf0Null(); @@ -773,18 +769,18 @@ namespace _srs_internal }; /** - * read amf0 undefined from stream. - * 2.8 undefined Type - * undefined-type = undefined-marker - */ + * read amf0 undefined from stream. + * 2.8 undefined Type + * undefined-type = undefined-marker + */ class SrsAmf0Undefined : public SrsAmf0Any { private: friend class SrsAmf0Any; /** - * make amf0 undefined to private, - * use should never declare it, use SrsAmf0Any::undefined() to create it. - */ + * make amf0 undefined to private, + * use should never declare it, use SrsAmf0Any::undefined() to create it. + */ SrsAmf0Undefined(); public: virtual ~SrsAmf0Undefined(); @@ -796,11 +792,11 @@ namespace _srs_internal }; /** - * to ensure in inserted order. - * for the FMLE will crash when AMF0Object is not ordered by inserted, - * if ordered in map, the string compare order, the FMLE will creash when - * get the response of connect app. - */ + * to ensure in inserted order. + * for the FMLE will crash when AMF0Object is not ordered by inserted, + * if ordered in map, the string compare order, the FMLE will creash when + * get the response of connect app. + */ class SrsUnSortedHashtable { private: @@ -816,9 +812,9 @@ namespace _srs_internal virtual const char* key_raw_at(int index); virtual SrsAmf0Any* value_at(int index); /** - * set the value of hashtable. - * @param value, the value to set. NULL to delete the property. - */ + * set the value of hashtable. + * @param value, the value to set. NULL to delete the property. + */ virtual void set(std::string key, SrsAmf0Any* value); public: virtual SrsAmf0Any* get_property(std::string name); @@ -830,10 +826,10 @@ namespace _srs_internal }; /** - * 2.11 Object End Type - * object-end-type = UTF-8-empty object-end-marker - * 0x00 0x00 0x09 - */ + * 2.11 Object End Type + * object-end-type = UTF-8-empty object-end-marker + * 0x00 0x00 0x09 + */ class SrsAmf0ObjectEOF : public SrsAmf0Any { public: @@ -845,15 +841,15 @@ namespace _srs_internal virtual int write(SrsBuffer* stream); virtual SrsAmf0Any* copy(); }; - + /** - * read amf0 utf8 string from stream. - * 1.3.1 Strings and UTF-8 - * UTF-8 = U16 *(UTF8-char) - * UTF8-char = UTF8-1 | UTF8-2 | UTF8-3 | UTF8-4 - * UTF8-1 = %x00-7F - * @remark only support UTF8-1 char. - */ + * read amf0 utf8 string from stream. + * 1.3.1 Strings and UTF-8 + * UTF-8 = U16 *(UTF8-char) + * UTF8-char = UTF8-1 | UTF8-2 | UTF8-3 | UTF8-4 + * UTF8-1 = %x00-7F + * @remark only support UTF8-1 char. + */ extern int srs_amf0_read_utf8(SrsBuffer* stream, std::string& value); extern int srs_amf0_write_utf8(SrsBuffer* stream, std::string value); diff --git a/trunk/src/protocol/srs_protocol_format.cpp b/trunk/src/protocol/srs_protocol_format.cpp index 7bbf4164a..03f23e13b 100644 --- a/trunk/src/protocol/srs_protocol_format.cpp +++ b/trunk/src/protocol/srs_protocol_format.cpp @@ -1,24 +1,24 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. */ #include diff --git a/trunk/src/protocol/srs_protocol_format.hpp b/trunk/src/protocol/srs_protocol_format.hpp index 36bedbca9..4fedaa25e 100644 --- a/trunk/src/protocol/srs_protocol_format.hpp +++ b/trunk/src/protocol/srs_protocol_format.hpp @@ -1,33 +1,29 @@ -/* - The MIT License (MIT) - - Copyright (c) 2013-2017 SRS(ossrs) - - 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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_PROTOCOL_FORMAT_HPP #define SRS_PROTOCOL_FORMAT_HPP -/* -#include -*/ - #include #include diff --git a/trunk/src/protocol/srs_protocol_io.cpp b/trunk/src/protocol/srs_protocol_io.cpp index e33240d4f..194e93bee 100644 --- a/trunk/src/protocol/srs_protocol_io.cpp +++ b/trunk/src/protocol/srs_protocol_io.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include diff --git a/trunk/src/protocol/srs_protocol_io.hpp b/trunk/src/protocol/srs_protocol_io.hpp index 27d6b7e61..22e217ab4 100644 --- a/trunk/src/protocol/srs_protocol_io.hpp +++ b/trunk/src/protocol/srs_protocol_io.hpp @@ -1,96 +1,92 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_PROTOCOL_IO_HPP #define SRS_PROTOCOL_IO_HPP -/* -#include -*/ - #include #include /** -* the system io reader/writer architecture: - +---------------+ +---------------+ - | IStreamWriter | | IVectorWriter | - +---------------+ +---------------+ - | + write() | | + writev() | - +-------------+-+ ++--------------+ -+----------+ +--------------------+ /\ /\ -| IReader | | IStatistic | \ / -+----------+ +--------------------+ V -| + read() | | + get_recv_bytes() | +------+----+ -+------+---+ | + get_send_bytes() | | IWriter | - / \ +---+--------------+-+ +-------+---+ - | / \ / \ / \ - | | | | -+------+-------------+------+ ++---------------------+--+ -| IProtocolReader | | IProtocolWriter | -+---------------------------+ +-------------------------+ -| + readfully() | | + set_send_timeout() | -| + set_recv_timeout() | +-------+-----------------+ -+------------+--------------+ / \ - / \ | - | | - +--+-----------------------------+-+ - | IProtocolReaderWriter | - +----------------------------------+ - | + is_never_timeout() | - +----------------------------------+ -*/ + * the system io reader/writer architecture: + * +---------------+ +---------------+ + * | IStreamWriter | | IVectorWriter | + * +---------------+ +---------------+ + * | + write() | | + writev() | + * +-------------+-+ ++--------------+ + * +----------+ +--------------------+ /\ /\ + * | IReader | | IStatistic | \ / + * +----------+ +--------------------+ V + * | + read() | | + get_recv_bytes() | +------+----+ + * +------+---+ | + get_send_bytes() | | IWriter | + * / \ +---+--------------+-+ +-------+---+ + * | / \ / \ / \ + * | | | | + * +------+-------------+------+ ++---------------------+--+ + * | IProtocolReader | | IProtocolWriter | + * +---------------------------+ +-------------------------+ + * | + readfully() | | + set_send_timeout() | + * | + set_recv_timeout() | +-------+-----------------+ + * +------------+--------------+ / \ + * / \ | + * | | + * +--+-----------------------------+-+ + * | IProtocolReaderWriter | + * +----------------------------------+ + * | + is_never_timeout() | + * +----------------------------------+ + */ /** -* get the statistic of channel. -*/ + * get the statistic of channel. + */ class ISrsProtocolStatistic { public: ISrsProtocolStatistic(); virtual ~ISrsProtocolStatistic(); -// for protocol + // for protocol public: /** - * get the total recv bytes over underlay fd. - */ + * get the total recv bytes over underlay fd. + */ virtual int64_t get_recv_bytes() = 0; /** - * get the total send bytes over underlay fd. - */ + * get the total send bytes over underlay fd. + */ virtual int64_t get_send_bytes() = 0; }; /** -* the reader for the protocol to read from whatever channel. -*/ + * the reader for the protocol to read from whatever channel. + */ class ISrsProtocolReader : public virtual ISrsReader, public virtual ISrsProtocolStatistic { public: ISrsProtocolReader(); virtual ~ISrsProtocolReader(); -// for protocol + // for protocol public: /** * Set the timeout tm in ms for recv bytes from peer. @@ -99,26 +95,26 @@ public: virtual void set_recv_timeout(int64_t tm) = 0; /** * Get the timeout in ms for recv bytes from peer. - */ + */ virtual int64_t get_recv_timeout() = 0; -// for handshake. + // for handshake. public: /** - * read specified size bytes of data - * @param nread, the actually read size, NULL to ignore. - */ + * read specified size bytes of data + * @param nread, the actually read size, NULL to ignore. + */ virtual int read_fully(void* buf, size_t size, ssize_t* nread) = 0; }; /** -* the writer for the protocol to write to whatever channel. -*/ + * the writer for the protocol to write to whatever channel. + */ class ISrsProtocolWriter : public virtual ISrsWriter, public virtual ISrsProtocolStatistic { public: ISrsProtocolWriter(); virtual ~ISrsProtocolWriter(); -// for protocol + // for protocol public: /** * Set the timeout tm in ms for send bytes to peer. @@ -132,14 +128,14 @@ public: }; /** -* the reader and writer. -*/ + * the reader and writer. + */ class ISrsProtocolReaderWriter : public virtual ISrsProtocolReader, public virtual ISrsProtocolWriter { public: ISrsProtocolReaderWriter(); virtual ~ISrsProtocolReaderWriter(); -// for protocol + // for protocol public: /** * Whether the specified tm in ms is never timeout. diff --git a/trunk/src/protocol/srs_protocol_json.cpp b/trunk/src/protocol/srs_protocol_json.cpp index 6b50356de..b8a9273a1 100644 --- a/trunk/src/protocol/srs_protocol_json.cpp +++ b/trunk/src/protocol/srs_protocol_json.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -109,41 +109,41 @@ using namespace std; #ifdef __cplusplus extern "C" { #endif - - -typedef enum nx_json_type { - NX_JSON_NULL, // this is null value - NX_JSON_OBJECT, // this is an object; properties can be found in child nodes - NX_JSON_ARRAY, // this is an array; items can be found in child nodes - NX_JSON_STRING, // this is a string; value can be found in text_value field - NX_JSON_INTEGER, // this is an integer; value can be found in int_value field - NX_JSON_DOUBLE, // this is a double; value can be found in dbl_value field - NX_JSON_BOOL // this is a boolean; value can be found in int_value field -} nx_json_type; - -typedef struct nx_json { - nx_json_type type; // type of json node, see above - const char* key; // key of the property; for object's children only - const char* text_value; // text value of STRING node - long int_value; // the value of INTEGER or BOOL node - double dbl_value; // the value of DOUBLE node - int length; // number of children of OBJECT or ARRAY - struct nx_json* child; // points to first child - struct nx_json* next; // points to next child - struct nx_json* last_child; -} nx_json; - -typedef int (*nx_json_unicode_encoder)(unsigned int codepoint, char* p, char** endp); - -extern nx_json_unicode_encoder nx_json_unicode_to_utf8; - -const nx_json* nx_json_parse(char* text, nx_json_unicode_encoder encoder); -const nx_json* nx_json_parse_utf8(char* text); -void nx_json_free(const nx_json* js); -const nx_json* nx_json_get(const nx_json* json, const char* key); // get object's property by key -const nx_json* nx_json_item(const nx_json* json, int idx); // get array element by index - - + + + typedef enum nx_json_type { + NX_JSON_NULL, // this is null value + NX_JSON_OBJECT, // this is an object; properties can be found in child nodes + NX_JSON_ARRAY, // this is an array; items can be found in child nodes + NX_JSON_STRING, // this is a string; value can be found in text_value field + NX_JSON_INTEGER, // this is an integer; value can be found in int_value field + NX_JSON_DOUBLE, // this is a double; value can be found in dbl_value field + NX_JSON_BOOL // this is a boolean; value can be found in int_value field + } nx_json_type; + + typedef struct nx_json { + nx_json_type type; // type of json node, see above + const char* key; // key of the property; for object's children only + const char* text_value; // text value of STRING node + long int_value; // the value of INTEGER or BOOL node + double dbl_value; // the value of DOUBLE node + int length; // number of children of OBJECT or ARRAY + struct nx_json* child; // points to first child + struct nx_json* next; // points to next child + struct nx_json* last_child; + } nx_json; + + typedef int (*nx_json_unicode_encoder)(unsigned int codepoint, char* p, char** endp); + + extern nx_json_unicode_encoder nx_json_unicode_to_utf8; + + const nx_json* nx_json_parse(char* text, nx_json_unicode_encoder encoder); + const nx_json* nx_json_parse_utf8(char* text); + void nx_json_free(const nx_json* js); + const nx_json* nx_json_get(const nx_json* json, const char* key); // get object's property by key + const nx_json* nx_json_item(const nx_json* json, int idx); // get array element by index + + #ifdef __cplusplus } #endif @@ -165,15 +165,15 @@ class SrsJsonString : public SrsJsonAny { public: std::string value; - - SrsJsonString(const char* _value) + + SrsJsonString(const char* _value) { marker = SRS_JSON_String; if (_value) { value = _value; } } - virtual ~SrsJsonString() + virtual ~SrsJsonString() { } }; @@ -182,13 +182,13 @@ class SrsJsonBoolean : public SrsJsonAny { public: bool value; - - SrsJsonBoolean(bool _value) + + SrsJsonBoolean(bool _value) { marker = SRS_JSON_Boolean; value = _value; } - virtual ~SrsJsonBoolean() + virtual ~SrsJsonBoolean() { } }; @@ -197,13 +197,13 @@ class SrsJsonInteger : public SrsJsonAny { public: int64_t value; - - SrsJsonInteger(int64_t _value) + + SrsJsonInteger(int64_t _value) { marker = SRS_JSON_Integer; value = _value; } - virtual ~SrsJsonInteger() + virtual ~SrsJsonInteger() { } }; @@ -212,13 +212,13 @@ class SrsJsonNumber : public SrsJsonAny { public: double value; - - SrsJsonNumber(double _value) + + SrsJsonNumber(double _value) { marker = SRS_JSON_Number; value = _value; } - virtual ~SrsJsonNumber() + virtual ~SrsJsonNumber() { } }; @@ -477,7 +477,7 @@ SrsJsonAny* SrsJsonAny::loads(char* str) if (strlen(str) == 0) { return NULL; } - + // TODO: copy str for nx_json modify it. string s = str; const nx_json* o = nx_json_parse((char*)s.data(), 0); @@ -665,30 +665,30 @@ SrsJsonAny* SrsJsonObject::ensure_property_boolean(string name) SrsJsonAny* SrsJsonObject::ensure_property_object(string name) { SrsJsonAny* prop = get_property(name); - + if (!prop) { return NULL; } - + if (!prop->is_object()) { return NULL; } - + return prop; } SrsJsonAny* SrsJsonObject::ensure_property_array(string name) { SrsJsonAny* prop = get_property(name); - + if (!prop) { return NULL; } - + if (!prop->is_array()) { return NULL; } - + return prop; } @@ -794,365 +794,365 @@ SrsAmf0Any* SrsJsonArray::to_amf0() #ifdef __cplusplus extern "C" { #endif - - + + #include #include #include #include - -//#include "nxjson.h" - -// redefine NX_JSON_CALLOC & NX_JSON_FREE to use custom allocator + + //#include "nxjson.h" + + // redefine NX_JSON_CALLOC & NX_JSON_FREE to use custom allocator #ifndef NX_JSON_CALLOC #define NX_JSON_CALLOC() calloc(1, sizeof(nx_json)) #define NX_JSON_FREE(json) free((void*)(json)) #endif - -// redefine NX_JSON_REPORT_ERROR to use custom error reporting + + // redefine NX_JSON_REPORT_ERROR to use custom error reporting #ifndef NX_JSON_REPORT_ERROR #define NX_JSON_REPORT_ERROR(msg, p) srs_warn("NXJSON PARSE ERROR (%d): " msg " at %s", __LINE__, p) #endif - + #define IS_WHITESPACE(c) ((unsigned char)(c)<=(unsigned char)' ') - -static const nx_json dummy={ NX_JSON_NULL }; - -static nx_json* create_json(nx_json_type type, const char* key, nx_json* parent) { - nx_json* js=(nx_json*)NX_JSON_CALLOC(); - memset(js, 0, sizeof(nx_json)); - assert(js); - js->type=type; - js->key=key; - if (!parent->last_child) { - parent->child=parent->last_child=js; - } - else { - parent->last_child->next=js; - parent->last_child=js; - } - parent->length++; - return js; -} - -void nx_json_free(const nx_json* js) { - nx_json* p=js->child; - nx_json* p1; - while (p) { - p1=p->next; - nx_json_free(p); - p=p1; - } - NX_JSON_FREE(js); -} - -static int unicode_to_utf8(unsigned int codepoint, char* p, char** endp) { - // code from http://stackoverflow.com/a/4609989/697313 - if (codepoint<0x80) *p++=codepoint; - else if (codepoint<0x800) *p++=192+codepoint/64, *p++=128+codepoint%64; - else if (codepoint-0xd800u<0x800) return 0; // surrogate must have been treated earlier - else if (codepoint<0x10000) *p++=224+codepoint/4096, *p++=128+codepoint/64%64, *p++=128+codepoint%64; - else if (codepoint<0x110000) *p++=240+codepoint/262144, *p++=128+codepoint/4096%64, *p++=128+codepoint/64%64, *p++=128+codepoint%64; - else return 0; // error - *endp=p; - return 1; -} - -nx_json_unicode_encoder nx_json_unicode_to_utf8=unicode_to_utf8; - -static inline int hex_val(char c) { - if (c>='0' && c<='9') return c-'0'; - if (c>='a' && c<='f') return c-'a'+10; - if (c>='A' && c<='F') return c-'A'+10; - return -1; -} - -static char* unescape_string(char* s, char** end, nx_json_unicode_encoder encoder) { - char* p=s; - char* d=s; - char c; - while ((c=*p++)) { - if (c=='"') { - *d='\0'; - *end=p; - return s; - } - else if (c=='\\') { - switch (*p) { - case '\\': - case '/': - case '"': - *d++=*p++; - break; - case 'b': - *d++='\b'; p++; - break; - case 'f': - *d++='\f'; p++; - break; - case 'n': - *d++='\n'; p++; - break; - case 'r': - *d++='\r'; p++; - break; - case 't': - *d++='\t'; p++; - break; - case 'u': { // unicode - if (!encoder) { - // leave untouched - *d++=c; - break; - } - char* ps=p-1; - int h1, h2, h3, h4; - if ((h1=hex_val(p[1]))<0 || (h2=hex_val(p[2]))<0 || (h3=hex_val(p[3]))<0 || (h4=hex_val(p[4]))<0) { - NX_JSON_REPORT_ERROR("invalid unicode escape", p-1); - return 0; - } - unsigned int codepoint=h1<<12|h2<<8|h3<<4|h4; - if ((codepoint & 0xfc00)==0xd800) { // high surrogate; need one more unicode to succeed - p+=6; - if (p[-1]!='\\' || *p!='u' || (h1=hex_val(p[1]))<0 || (h2=hex_val(p[2]))<0 || (h3=hex_val(p[3]))<0 || (h4=hex_val(p[4]))<0) { - NX_JSON_REPORT_ERROR("invalid unicode surrogate", ps); - return 0; - } - unsigned int codepoint2=h1<<12|h2<<8|h3<<4|h4; - if ((codepoint2 & 0xfc00)!=0xdc00) { - NX_JSON_REPORT_ERROR("invalid unicode surrogate", ps); - return 0; - } - codepoint=0x10000+((codepoint-0xd800)<<10)+(codepoint2-0xdc00); - } - if (!encoder(codepoint, d, &d)) { - NX_JSON_REPORT_ERROR("invalid codepoint", ps); - return 0; - } - p+=5; - break; - } - default: { - // leave untouched - *d++=c; - break; - } - } - } - else { - *d++=c; - } - } - NX_JSON_REPORT_ERROR("no closing quote for string", s); - return 0; -} - -static char* skip_block_comment(char* p) { - // assume p[-2]=='/' && p[-1]=='*' - char* ps=p-2; - if (!*p) { - NX_JSON_REPORT_ERROR("endless comment", ps); - return 0; - } - REPEAT: - p=strchr(p+1, '/'); - if (!p) { - NX_JSON_REPORT_ERROR("endless comment", ps); - return 0; - } - if (p[-1]!='*') goto REPEAT; - return p+1; -} - -static char* parse_key(const char** key, char* p, nx_json_unicode_encoder encoder) { - // on '}' return with *p=='}' - char c; - while ((c=*p++)) { - if (c=='"') { - *key=unescape_string(p, &p, encoder); - if (!*key) return 0; // propagate error - while (*p && IS_WHITESPACE(*p)) p++; - if (*p==':') return p+1; - NX_JSON_REPORT_ERROR("unexpected chars", p); - return 0; - } - else if (IS_WHITESPACE(c) || c==',') { - // continue - } - else if (c=='}') { - return p-1; - } - else if (c=='/') { - if (*p=='/') { // line comment - char* ps=p-1; - p=strchr(p+1, '\n'); - if (!p) { - NX_JSON_REPORT_ERROR("endless comment", ps); - return 0; // error - } - p++; - } - else if (*p=='*') { // block comment - p=skip_block_comment(p+1); - if (!p) return 0; - } - else { - NX_JSON_REPORT_ERROR("unexpected chars", p-1); - return 0; // error - } - } - else { - NX_JSON_REPORT_ERROR("unexpected chars", p-1); - return 0; // error - } - } - NX_JSON_REPORT_ERROR("unexpected chars", p-1); - return 0; // error -} - -static char* parse_value(nx_json* parent, const char* key, char* p, nx_json_unicode_encoder encoder) { - nx_json* js; - while (1) { - switch (*p) { - case '\0': - NX_JSON_REPORT_ERROR("unexpected end of text", p); - return 0; // error - case ' ': case '\t': case '\n': case '\r': - case ',': - // skip - p++; - break; - case '{': - js=create_json(NX_JSON_OBJECT, key, parent); - p++; - while (1) { - const char* new_key; - p=parse_key(&new_key, p, encoder); - if (!p) return 0; // error - if (*p=='}') return p+1; // end of object - p=parse_value(js, new_key, p, encoder); - if (!p) return 0; // error - } - case '[': - js=create_json(NX_JSON_ARRAY, key, parent); - p++; - while (1) { - p=parse_value(js, 0, p, encoder); - if (!p) return 0; // error - if (*p==']') return p+1; // end of array - } - case ']': - return p; - case '"': - p++; - js=create_json(NX_JSON_STRING, key, parent); - js->text_value=unescape_string(p, &p, encoder); - if (!js->text_value) return 0; // propagate error - return p; - case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - { - js=create_json(NX_JSON_INTEGER, key, parent); - char* pe; - js->int_value=strtol(p, &pe, 0); - if (pe==p) { - NX_JSON_REPORT_ERROR("invalid number", p); - return 0; // error - } - if (*pe=='.' || *pe=='e' || *pe=='E') { // double value - js->type=NX_JSON_DOUBLE; - js->dbl_value=strtod(p, &pe); - if (pe==p) { - NX_JSON_REPORT_ERROR("invalid number", p); - return 0; // error - } - } - else { - js->dbl_value=js->int_value; - } - return pe; - } - case 't': - if (!strncmp(p, "true", 4)) { - js=create_json(NX_JSON_BOOL, key, parent); - js->int_value=1; - return p+4; - } - NX_JSON_REPORT_ERROR("unexpected chars", p); - return 0; // error - case 'f': - if (!strncmp(p, "false", 5)) { - js=create_json(NX_JSON_BOOL, key, parent); - js->int_value=0; - return p+5; - } - NX_JSON_REPORT_ERROR("unexpected chars", p); - return 0; // error - case 'n': - if (!strncmp(p, "null", 4)) { - create_json(NX_JSON_NULL, key, parent); - return p+4; - } - NX_JSON_REPORT_ERROR("unexpected chars", p); - return 0; // error - case '/': // comment - if (p[1]=='/') { // line comment - char* ps=p; - p=strchr(p+2, '\n'); - if (!p) { - NX_JSON_REPORT_ERROR("endless comment", ps); - return 0; // error - } - p++; - } - else if (p[1]=='*') { // block comment - p=skip_block_comment(p+2); - if (!p) return 0; + + static const nx_json dummy={ NX_JSON_NULL }; + + static nx_json* create_json(nx_json_type type, const char* key, nx_json* parent) { + nx_json* js=(nx_json*)NX_JSON_CALLOC(); + memset(js, 0, sizeof(nx_json)); + assert(js); + js->type=type; + js->key=key; + if (!parent->last_child) { + parent->child=parent->last_child=js; } else { - NX_JSON_REPORT_ERROR("unexpected chars", p); - return 0; // error + parent->last_child->next=js; + parent->last_child=js; } - break; - default: - NX_JSON_REPORT_ERROR("unexpected chars", p); + parent->length++; + return js; + } + + void nx_json_free(const nx_json* js) { + nx_json* p=js->child; + nx_json* p1; + while (p) { + p1=p->next; + nx_json_free(p); + p=p1; + } + NX_JSON_FREE(js); + } + + static int unicode_to_utf8(unsigned int codepoint, char* p, char** endp) { + // code from http://stackoverflow.com/a/4609989/697313 + if (codepoint<0x80) *p++=codepoint; + else if (codepoint<0x800) *p++=192+codepoint/64, *p++=128+codepoint%64; + else if (codepoint-0xd800u<0x800) return 0; // surrogate must have been treated earlier + else if (codepoint<0x10000) *p++=224+codepoint/4096, *p++=128+codepoint/64%64, *p++=128+codepoint%64; + else if (codepoint<0x110000) *p++=240+codepoint/262144, *p++=128+codepoint/4096%64, *p++=128+codepoint/64%64, *p++=128+codepoint%64; + else return 0; // error + *endp=p; + return 1; + } + + nx_json_unicode_encoder nx_json_unicode_to_utf8=unicode_to_utf8; + + static inline int hex_val(char c) { + if (c>='0' && c<='9') return c-'0'; + if (c>='a' && c<='f') return c-'a'+10; + if (c>='A' && c<='F') return c-'A'+10; + return -1; + } + + static char* unescape_string(char* s, char** end, nx_json_unicode_encoder encoder) { + char* p=s; + char* d=s; + char c; + while ((c=*p++)) { + if (c=='"') { + *d='\0'; + *end=p; + return s; + } + else if (c=='\\') { + switch (*p) { + case '\\': + case '/': + case '"': + *d++=*p++; + break; + case 'b': + *d++='\b'; p++; + break; + case 'f': + *d++='\f'; p++; + break; + case 'n': + *d++='\n'; p++; + break; + case 'r': + *d++='\r'; p++; + break; + case 't': + *d++='\t'; p++; + break; + case 'u': { // unicode + if (!encoder) { + // leave untouched + *d++=c; + break; + } + char* ps=p-1; + int h1, h2, h3, h4; + if ((h1=hex_val(p[1]))<0 || (h2=hex_val(p[2]))<0 || (h3=hex_val(p[3]))<0 || (h4=hex_val(p[4]))<0) { + NX_JSON_REPORT_ERROR("invalid unicode escape", p-1); + return 0; + } + unsigned int codepoint=h1<<12|h2<<8|h3<<4|h4; + if ((codepoint & 0xfc00)==0xd800) { // high surrogate; need one more unicode to succeed + p+=6; + if (p[-1]!='\\' || *p!='u' || (h1=hex_val(p[1]))<0 || (h2=hex_val(p[2]))<0 || (h3=hex_val(p[3]))<0 || (h4=hex_val(p[4]))<0) { + NX_JSON_REPORT_ERROR("invalid unicode surrogate", ps); + return 0; + } + unsigned int codepoint2=h1<<12|h2<<8|h3<<4|h4; + if ((codepoint2 & 0xfc00)!=0xdc00) { + NX_JSON_REPORT_ERROR("invalid unicode surrogate", ps); + return 0; + } + codepoint=0x10000+((codepoint-0xd800)<<10)+(codepoint2-0xdc00); + } + if (!encoder(codepoint, d, &d)) { + NX_JSON_REPORT_ERROR("invalid codepoint", ps); + return 0; + } + p+=5; + break; + } + default: { + // leave untouched + *d++=c; + break; + } + } + } + else { + *d++=c; + } + } + NX_JSON_REPORT_ERROR("no closing quote for string", s); + return 0; + } + + static char* skip_block_comment(char* p) { + // assume p[-2]=='/' && p[-1]=='*' + char* ps=p-2; + if (!*p) { + NX_JSON_REPORT_ERROR("endless comment", ps); + return 0; + } + REPEAT: + p=strchr(p+1, '/'); + if (!p) { + NX_JSON_REPORT_ERROR("endless comment", ps); + return 0; + } + if (p[-1]!='*') goto REPEAT; + return p+1; + } + + static char* parse_key(const char** key, char* p, nx_json_unicode_encoder encoder) { + // on '}' return with *p=='}' + char c; + while ((c=*p++)) { + if (c=='"') { + *key=unescape_string(p, &p, encoder); + if (!*key) return 0; // propagate error + while (*p && IS_WHITESPACE(*p)) p++; + if (*p==':') return p+1; + NX_JSON_REPORT_ERROR("unexpected chars", p); + return 0; + } + else if (IS_WHITESPACE(c) || c==',') { + // continue + } + else if (c=='}') { + return p-1; + } + else if (c=='/') { + if (*p=='/') { // line comment + char* ps=p-1; + p=strchr(p+1, '\n'); + if (!p) { + NX_JSON_REPORT_ERROR("endless comment", ps); + return 0; // error + } + p++; + } + else if (*p=='*') { // block comment + p=skip_block_comment(p+1); + if (!p) return 0; + } + else { + NX_JSON_REPORT_ERROR("unexpected chars", p-1); + return 0; // error + } + } + else { + NX_JSON_REPORT_ERROR("unexpected chars", p-1); + return 0; // error + } + } + NX_JSON_REPORT_ERROR("unexpected chars", p-1); return 0; // error } - } -} - -const nx_json* nx_json_parse_utf8(char* text) { - return nx_json_parse(text, unicode_to_utf8); -} - -const nx_json* nx_json_parse(char* text, nx_json_unicode_encoder encoder) { - nx_json js; - memset(&js, 0, sizeof(nx_json)); - if (!parse_value(&js, 0, text, encoder)) { - if (js.child) nx_json_free(js.child); - return 0; - } - return js.child; -} - -const nx_json* nx_json_get(const nx_json* json, const char* key) { - if (!json || !key) return &dummy; // never return null - nx_json* js; - for (js=json->child; js; js=js->next) { - if (js->key && !strcmp(js->key, key)) return js; - } - return &dummy; // never return null -} - -const nx_json* nx_json_item(const nx_json* json, int idx) { - if (!json) return &dummy; // never return null - nx_json* js; - for (js=json->child; js; js=js->next) { - if (!idx--) return js; - } - return &dummy; // never return null -} - - + + static char* parse_value(nx_json* parent, const char* key, char* p, nx_json_unicode_encoder encoder) { + nx_json* js; + while (1) { + switch (*p) { + case '\0': + NX_JSON_REPORT_ERROR("unexpected end of text", p); + return 0; // error + case ' ': case '\t': case '\n': case '\r': + case ',': + // skip + p++; + break; + case '{': + js=create_json(NX_JSON_OBJECT, key, parent); + p++; + while (1) { + const char* new_key; + p=parse_key(&new_key, p, encoder); + if (!p) return 0; // error + if (*p=='}') return p+1; // end of object + p=parse_value(js, new_key, p, encoder); + if (!p) return 0; // error + } + case '[': + js=create_json(NX_JSON_ARRAY, key, parent); + p++; + while (1) { + p=parse_value(js, 0, p, encoder); + if (!p) return 0; // error + if (*p==']') return p+1; // end of array + } + case ']': + return p; + case '"': + p++; + js=create_json(NX_JSON_STRING, key, parent); + js->text_value=unescape_string(p, &p, encoder); + if (!js->text_value) return 0; // propagate error + return p; + case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + { + js=create_json(NX_JSON_INTEGER, key, parent); + char* pe; + js->int_value=strtol(p, &pe, 0); + if (pe==p) { + NX_JSON_REPORT_ERROR("invalid number", p); + return 0; // error + } + if (*pe=='.' || *pe=='e' || *pe=='E') { // double value + js->type=NX_JSON_DOUBLE; + js->dbl_value=strtod(p, &pe); + if (pe==p) { + NX_JSON_REPORT_ERROR("invalid number", p); + return 0; // error + } + } + else { + js->dbl_value=js->int_value; + } + return pe; + } + case 't': + if (!strncmp(p, "true", 4)) { + js=create_json(NX_JSON_BOOL, key, parent); + js->int_value=1; + return p+4; + } + NX_JSON_REPORT_ERROR("unexpected chars", p); + return 0; // error + case 'f': + if (!strncmp(p, "false", 5)) { + js=create_json(NX_JSON_BOOL, key, parent); + js->int_value=0; + return p+5; + } + NX_JSON_REPORT_ERROR("unexpected chars", p); + return 0; // error + case 'n': + if (!strncmp(p, "null", 4)) { + create_json(NX_JSON_NULL, key, parent); + return p+4; + } + NX_JSON_REPORT_ERROR("unexpected chars", p); + return 0; // error + case '/': // comment + if (p[1]=='/') { // line comment + char* ps=p; + p=strchr(p+2, '\n'); + if (!p) { + NX_JSON_REPORT_ERROR("endless comment", ps); + return 0; // error + } + p++; + } + else if (p[1]=='*') { // block comment + p=skip_block_comment(p+2); + if (!p) return 0; + } + else { + NX_JSON_REPORT_ERROR("unexpected chars", p); + return 0; // error + } + break; + default: + NX_JSON_REPORT_ERROR("unexpected chars", p); + return 0; // error + } + } + } + + const nx_json* nx_json_parse_utf8(char* text) { + return nx_json_parse(text, unicode_to_utf8); + } + + const nx_json* nx_json_parse(char* text, nx_json_unicode_encoder encoder) { + nx_json js; + memset(&js, 0, sizeof(nx_json)); + if (!parse_value(&js, 0, text, encoder)) { + if (js.child) nx_json_free(js.child); + return 0; + } + return js.child; + } + + const nx_json* nx_json_get(const nx_json* json, const char* key) { + if (!json || !key) return &dummy; // never return null + nx_json* js; + for (js=json->child; js; js=js->next) { + if (js->key && !strcmp(js->key, key)) return js; + } + return &dummy; // never return null + } + + const nx_json* nx_json_item(const nx_json* json, int idx) { + if (!json) return &dummy; // never return null + nx_json* js; + for (js=json->child; js; js=js->next) { + if (!idx--) return js; + } + return &dummy; // never return null + } + + #ifdef __cplusplus } #endif diff --git a/trunk/src/protocol/srs_protocol_json.hpp b/trunk/src/protocol/srs_protocol_json.hpp index 7a4e16924..0bceb62e3 100644 --- a/trunk/src/protocol/srs_protocol_json.hpp +++ b/trunk/src/protocol/srs_protocol_json.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_PROTOCOL_JSON_HPP #define SRS_PROTOCOL_JSON_HPP -/* -#include -*/ #include #include @@ -68,8 +65,8 @@ class SrsJsonAny { public: char marker; -// donot directly create this object, -// instead, for examle, use SrsJsonAny::str() to create a concreated one. + // donot directly create this object, + // instead, for examle, use SrsJsonAny::str() to create a concreated one. protected: SrsJsonAny(); public: @@ -84,40 +81,40 @@ public: 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(); virtual SrsAmf0Any* to_amf0(); public: - static SrsJsonAny* str(const char* value = NULL); + static SrsJsonAny* str(const char* value = NULL); static SrsJsonAny* boolean(bool value = false); static SrsJsonAny* integer(int64_t value = 0); static SrsJsonAny* number(double value = 0.0); @@ -126,9 +123,9 @@ public: static SrsJsonArray* array(); public: /** - * read json tree from str:char* - * @return json object. NULL if error. - */ + * read json tree from str:char* + * @return json object. NULL if error. + */ static SrsJsonAny* loads(char* str); }; @@ -167,7 +164,7 @@ class SrsJsonArray : public SrsJsonAny { private: std::vector properties; - + private: // use SrsJsonAny::array() to create it. friend class SrsJsonAny; diff --git a/trunk/src/protocol/srs_protocol_kbps.cpp b/trunk/src/protocol/srs_protocol_kbps.cpp index 4693430de..1f8b8e256 100644 --- a/trunk/src/protocol/srs_protocol_kbps.cpp +++ b/trunk/src/protocol/srs_protocol_kbps.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -208,7 +208,7 @@ int64_t SrsKbps::get_send_bytes() // When no active session, the last_bytes record the last valid bytes. // TODO: Maybe the bellow bytes is zero, because the ios.io.out is NULL. bytes += os.last_bytes - os.io_bytes_base; - + return bytes; } @@ -230,7 +230,7 @@ int64_t SrsKbps::get_recv_bytes() // When no active session, the last_bytes record the last valid bytes. // TODO: Maybe the bellow bytes is zero, because the ios.io.out is NULL. bytes += is.last_bytes - is.io_bytes_base; - + return bytes; } diff --git a/trunk/src/protocol/srs_protocol_kbps.hpp b/trunk/src/protocol/srs_protocol_kbps.hpp index 7e7d9012a..f49c7626a 100644 --- a/trunk/src/protocol/srs_protocol_kbps.hpp +++ b/trunk/src/protocol/srs_protocol_kbps.hpp @@ -1,41 +1,37 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_PROTOCOL_KBPS_HPP #define SRS_PROTOCOL_KBPS_HPP -/* -#include -*/ - #include #include /** -* a kbps sample, for example, 1minute kbps, -* 10minute kbps sample. -*/ + * a kbps sample, for example, 1minute kbps, + * 10minute kbps sample. + */ class SrsKbpsSample { public: @@ -47,20 +43,20 @@ public: }; /** -* a slice of kbps statistic, for input or output. -* a slice contains a set of sessions, which has a base offset of bytes, -* where a slice is: -* starttime(oldest session startup time) -* bytes(total bytes of previous sessions) -* io_bytes_base(bytes offset of current session) -* last_bytes(bytes of current session) -* so, the total send bytes now is: -* send_bytes = bytes + last_bytes - io_bytes_base -* so, the bytes sent duration current session is: -* send_bytes = last_bytes - io_bytes_base -* @remark use set_io to start new session. -* @remakr the slice is a data collection object driven by SrsKbps. -*/ + * a slice of kbps statistic, for input or output. + * a slice contains a set of sessions, which has a base offset of bytes, + * where a slice is: + * starttime(oldest session startup time) + * bytes(total bytes of previous sessions) + * io_bytes_base(bytes offset of current session) + * last_bytes(bytes of current session) + * so, the total send bytes now is: + * send_bytes = bytes + last_bytes - io_bytes_base + * so, the bytes sent duration current session is: + * send_bytes = last_bytes - io_bytes_base + * @remark use set_io to start new session. + * @remakr the slice is a data collection object driven by SrsKbps. + */ class SrsKbpsSlice { private: @@ -102,13 +98,13 @@ public: }; /** -* the interface which provices delta of bytes. -* for a delta, for example, a live stream connection, we can got the delta by: -* IKbpsDelta* delta = ...; -* delta->resample(); -* kbps->add_delta(delta); -* delta->cleanup(); -*/ + * the interface which provices delta of bytes. + * for a delta, for example, a live stream connection, we can got the delta by: + * IKbpsDelta* delta = ...; + * delta->resample(); + * kbps->add_delta(delta); + * delta->cleanup(); + */ class IKbpsDelta { public: @@ -116,17 +112,17 @@ public: virtual ~IKbpsDelta(); public: /** - * resample to generate the value of delta bytes. - */ + * resample to generate the value of delta bytes. + */ virtual void resample() = 0; /** - * get the send or recv bytes delta. - */ + * get the send or recv bytes delta. + */ virtual int64_t get_send_bytes_delta() = 0; virtual int64_t get_recv_bytes_delta() = 0; /** - * cleanup the value of delta bytes. - */ + * cleanup the value of delta bytes. + */ virtual void cleanup() = 0; }; @@ -188,9 +184,9 @@ public: virtual void set_io(ISrsProtocolStatistic* in, ISrsProtocolStatistic* out); public: /** - * get total kbps, duration is from the startup of io. - * @remark, use sample() to update data. - */ + * get total kbps, duration is from the startup of io. + * @remark, use sample() to update data. + */ virtual int get_send_kbps(); virtual int get_recv_kbps(); // 30s @@ -211,19 +207,19 @@ public: virtual void cleanup(); public: /** - * add delta to kbps clac mechenism. - * we donot know the total bytes, but know the delta, for instance, - * for rtmp server to calc total bytes and kbps. - * @remark user must invoke sample() to calc result after invoke this method. - * @param delta, assert should never be NULL. - */ + * add delta to kbps clac mechenism. + * we donot know the total bytes, but know the delta, for instance, + * for rtmp server to calc total bytes and kbps. + * @remark user must invoke sample() to calc result after invoke this method. + * @param delta, assert should never be NULL. + */ virtual void add_delta(IKbpsDelta* delta); /** - * resample all samples, ignore if in/out is NULL. - * used for user to calc the kbps, to sample new kbps value. - * @remark if user, for instance, the rtmp server to calc the total bytes, - * use the add_delta() is better solutions. - */ + * resample all samples, ignore if in/out is NULL. + * used for user to calc the kbps, to sample new kbps value. + * @remark if user, for instance, the rtmp server to calc the total bytes, + * use the add_delta() is better solutions. + */ virtual void sample(); // interface ISrsMemorySizer public: diff --git a/trunk/src/protocol/srs_protocol_stream.cpp b/trunk/src/protocol/srs_protocol_stream.cpp index de0887804..2c367c181 100755 --- a/trunk/src/protocol/srs_protocol_stream.cpp +++ b/trunk/src/protocol/srs_protocol_stream.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -84,13 +84,13 @@ void SrsFastStream::set_buffer(int buffer_size) { // never exceed the max size. if (buffer_size > SRS_MAX_SOCKET_BUFFER) { - srs_warn("limit the user-space buffer from %d to %d", - buffer_size, SRS_MAX_SOCKET_BUFFER); + srs_warn("limit the user-space buffer from %d to %d", + buffer_size, SRS_MAX_SOCKET_BUFFER); } // the user-space buffer size limit to a max value. int nb_resize_buf = srs_min(buffer_size, SRS_MAX_SOCKET_BUFFER); - + // only realloc when buffer changed bigger if (nb_resize_buf <= nb_buffer) { return; @@ -120,7 +120,7 @@ char* SrsFastStream::read_slice(int size) char* ptr = p; p += size; - + return ptr; } @@ -134,16 +134,16 @@ void SrsFastStream::skip(int size) int SrsFastStream::grow(ISrsReader* reader, int required_size) { int ret = ERROR_SUCCESS; - + // already got required size of bytes. if (end - p >= required_size) { return ret; } - + // must be positive. srs_assert(required_size > 0); - - // the free space of buffer, + + // the free space of buffer, // buffer = consumed_bytes + exists_bytes + free_space. int nb_free_space = (int)(buffer + nb_buffer - end); @@ -154,7 +154,7 @@ int SrsFastStream::grow(ISrsReader* reader, int required_size) // resize the space when no left space. if (nb_free_space < required_size - nb_exists_bytes) { srs_verbose("move fast buffer %d bytes", nb_exists_bytes); - + // reset or move to get more space. if (!nb_exists_bytes) { // reset when buffer is empty. @@ -172,12 +172,12 @@ int SrsFastStream::grow(ISrsReader* reader, int required_size) nb_free_space = (int)(buffer + nb_buffer - end); if (nb_free_space < required_size - nb_exists_bytes) { ret = ERROR_READER_BUFFER_OVERFLOW; - srs_error("buffer overflow, required=%d, max=%d, left=%d, ret=%d", - required_size, nb_buffer, nb_free_space, ret); + srs_error("buffer overflow, required=%d, max=%d, left=%d, ret=%d", + required_size, nb_buffer, nb_free_space, ret); return ret; } } - + // buffer is ok, read required size of bytes. while (end - p < required_size) { ssize_t nread; @@ -187,11 +187,11 @@ int SrsFastStream::grow(ISrsReader* reader, int required_size) #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. - * @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. + * @see https://github.com/ossrs/srs/issues/241 + */ if (merged_read && _handler) { _handler->on_read(nread); } diff --git a/trunk/src/protocol/srs_protocol_stream.hpp b/trunk/src/protocol/srs_protocol_stream.hpp index 30979dfe9..e59dd049f 100644 --- a/trunk/src/protocol/srs_protocol_stream.hpp +++ b/trunk/src/protocol/srs_protocol_stream.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_PROTOCOL_STREAM_HPP #define SRS_PROTOCOL_STREAM_HPP -/* -#include -*/ - #include #include @@ -36,11 +32,11 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #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. -* @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. + * @see https://github.com/ossrs/srs/issues/241 + */ class IMergeReadHandler { public: @@ -48,24 +44,24 @@ public: virtual ~IMergeReadHandler(); public: /** - * when read from channel, notice the merge handler to sleep for - * some small bytes. - * @remark, it only for server-side, client srs-librtmp just ignore. - */ + * when read from channel, notice the merge handler to sleep for + * some small bytes. + * @remark, it only for server-side, client srs-librtmp just ignore. + */ virtual void on_read(ssize_t nread) = 0; }; #endif /** -* the buffer provices bytes cache for protocol. generally, -* protocol recv data from socket, put into buffer, decode to RTMP message. -* Usage: -* ISrsReader* r = ......; -* SrsFastStream* fb = ......; -* fb->grow(r, 1024); -* char* header = fb->read_slice(100); -* char* payload = fb->read_payload(924); -*/ + * the buffer provices bytes cache for protocol. generally, + * protocol recv data from socket, put into buffer, decode to RTMP message. + * Usage: + * ISrsReader* r = ......; + * SrsFastStream* fb = ......; + * fb->grow(r, 1024); + * char* header = fb->read_slice(100); + * char* payload = fb->read_payload(924); + */ // TODO: FIXME: add utest for it. class SrsFastStream { @@ -92,64 +88,64 @@ public: virtual ~SrsFastStream(); public: /** - * get the size of current bytes in buffer. - */ + * get the size of current bytes in buffer. + */ virtual int size(); /** - * get the current bytes in buffer. - * @remark user should use read_slice() if possible, - * the bytes() is used to test bytes, for example, to detect the bytes schema. - */ + * get the current bytes in buffer. + * @remark user should use read_slice() if possible, + * the bytes() is used to test bytes, for example, to detect the bytes schema. + */ virtual char* bytes(); /** - * create buffer with specifeid size. - * @param buffer the size of buffer. ignore when smaller than SRS_MAX_SOCKET_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. ignore when smaller than SRS_MAX_SOCKET_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_buffer(int buffer_size); public: /** - * read 1byte from buffer, move to next bytes. - * @remark assert buffer already grow(1). - */ + * read 1byte from buffer, move to next bytes. + * @remark assert buffer already grow(1). + */ virtual char read_1byte(); /** - * read a slice in size bytes, move to next bytes. - * user can use this char* ptr directly, and should never free it. - * @remark user can use the returned ptr util grow(size), - * for the ptr returned maybe invalid after grow(x). - */ + * read a slice in size bytes, move to next bytes. + * user can use this char* ptr directly, and should never free it. + * @remark user can use the returned ptr util grow(size), + * for the ptr returned maybe invalid after grow(x). + */ virtual char* read_slice(int size); /** - * skip some bytes in buffer. - * @param size the bytes to skip. positive to next; negative to previous. - * @remark assert buffer already grow(size). - * @remark always use read_slice to consume bytes, which will reset for EOF. - * while skip never consume bytes. - */ + * skip some bytes in buffer. + * @param size the bytes to skip. positive to next; negative to previous. + * @remark assert buffer already grow(size). + * @remark always use read_slice to consume bytes, which will reset for EOF. + * while skip never consume bytes. + */ virtual void skip(int size); public: /** - * grow buffer to the required size, loop to read from skt to fill. - * @param reader, read more bytes from reader to fill the buffer to required size. - * @param required_size, loop to fill to ensure buffer size to required. - * @return an int error code, error if required_size negative. - * @remark, we actually maybe read more than required_size, maybe 4k for example. - */ + * grow buffer to the required size, loop to read from skt to fill. + * @param reader, read more bytes from reader to fill the buffer to required size. + * @param required_size, loop to fill to ensure buffer size to required. + * @return an int error code, error if required_size negative. + * @remark, we actually maybe read more than required_size, maybe 4k for example. + */ virtual int grow(ISrsReader* reader, int required_size); 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 - * @remark the merged read is optional, ignore if not specifies. - */ + * 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 + * @remark the merged read is optional, ignore if not specifies. + */ virtual void set_merge_read(bool v, IMergeReadHandler* handler); #endif }; diff --git a/trunk/src/protocol/srs_protocol_utility.cpp b/trunk/src/protocol/srs_protocol_utility.cpp index b3ac46cfa..138db127e 100644 --- a/trunk/src/protocol/srs_protocol_utility.cpp +++ b/trunk/src/protocol/srs_protocol_utility.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -82,10 +82,10 @@ void srs_vhost_resolve(string& vhost, string& app, string& param) } void srs_discovery_tc_url( - string tcUrl, - string& schema, string& host, string& vhost, - string& app, int& port, string& param -) { + string tcUrl, + string& schema, string& host, string& vhost, + string& app, int& port, string& param + ) { size_t pos = std::string::npos; std::string url = tcUrl; @@ -100,19 +100,19 @@ void srs_discovery_tc_url( url = url.substr(host.length() + 1); srs_info("discovery host=%s", host.c_str()); } - + port = SRS_CONSTS_RTMP_DEFAULT_PORT; if ((pos = host.find(":")) != std::string::npos) { srs_parse_hostport(host, host, port); srs_info("discovery host=%s, port=%d", host.c_str(), port); } - + if (url.empty()) { app = SRS_CONSTS_RTMP_DEFAULT_APP; } else { app = url; } - + vhost = host; srs_vhost_resolve(vhost, app, param); } @@ -232,22 +232,22 @@ int srs_do_rtmp_create_msg(char type, uint32_t timestamp, char* data, int size, srs_error("rtmp unknown tag type=%#x. ret=%d", type, ret); return ret; } - + *ppmsg = msg; - + return ret; } int srs_rtmp_create_msg(char type, uint32_t timestamp, char* data, int size, int stream_id, SrsSharedPtrMessage** ppmsg) { int ret = ERROR_SUCCESS; - + // only when failed, we must free the data. if ((ret = srs_do_rtmp_create_msg(type, timestamp, data, size, stream_id, ppmsg)) != ERROR_SUCCESS) { srs_freepa(data); return ret; } - + return ret; } @@ -275,7 +275,7 @@ string srs_generate_stream_url(string vhost, string app, string stream) url += app; url += "/"; url += stream; - + return url; } diff --git a/trunk/src/protocol/srs_protocol_utility.hpp b/trunk/src/protocol/srs_protocol_utility.hpp index 68816b4e1..728fcea86 100644 --- a/trunk/src/protocol/srs_protocol_utility.hpp +++ b/trunk/src/protocol/srs_protocol_utility.hpp @@ -1,32 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_PROTOCOL_UTILITY_HPP #define SRS_PROTOCOL_UTILITY_HPP -/* -#include -*/ #include // for srs-librtmp, @see https://github.com/ossrs/srs/issues/213 @@ -46,100 +43,75 @@ class SrsCommonMessage; class ISrsProtocolReaderWriter; /** -* parse the tcUrl, output the schema, host, vhost, app and port. -* @param tcUrl, the input tcUrl, for example, -* rtmp://192.168.1.10:19350/live?vhost=vhost.ossrs.net -* @param schema, for example, rtmp -* @param host, for example, 192.168.1.10 -* @param vhost, for example, vhost.ossrs.net. -* vhost default to host, when user not set vhost in query of app. -* @param app, for example, live -* @param port, for example, 19350 -* default to 1935 if not specified. -* param param, for example, vhost=vhost.ossrs.net -*/ -extern void srs_discovery_tc_url( - std::string tcUrl, - std::string& schema, std::string& host, std::string& vhost, - std::string& app, int& port, std::string& param -); + * parse the tcUrl, output the schema, host, vhost, app and port. + * @param tcUrl, the input tcUrl, for example, + * rtmp://192.168.1.10:19350/live?vhost=vhost.ossrs.net + * @param schema, for example, rtmp + * @param host, for example, 192.168.1.10 + * @param vhost, for example, vhost.ossrs.net. + * vhost default to host, when user not set vhost in query of app. + * @param app, for example, live + * @param port, for example, 19350 + * default to 1935 if not specified. + * param param, for example, vhost=vhost.ossrs.net + */ +extern void srs_discovery_tc_url(std::string tcUrl, std::string& schema, std::string& host, std::string& vhost, std::string& app, int& port, std::string& param); // parse query string to map(k,v). // must format as key=value&...&keyN=valueN extern void srs_parse_query_string(std::string q, std::map& query); /** -* generate ramdom data for handshake. -*/ + * generate ramdom data for handshake. + */ extern void srs_random_generate(char* bytes, int size); /** -* generate the tcUrl. -* @param param, the app parameters in tcUrl. for example, ?key=xxx,vhost=xxx -* @return the tcUrl generated from ip/vhost/app/port. -* @remark when vhost equals to __defaultVhost__, use ip as vhost. -* @remark ignore port if port equals to default port 1935. -*/ -extern std::string srs_generate_tc_url( - std::string ip, std::string vhost, std::string app, int port, - std::string param -); + * generate the tcUrl. + * @param param, the app parameters in tcUrl. for example, ?key=xxx,vhost=xxx + * @return the tcUrl generated from ip/vhost/app/port. + * @remark when vhost equals to __defaultVhost__, use ip as vhost. + * @remark ignore port if port equals to default port 1935. + */ +extern std::string srs_generate_tc_url(std::string ip, std::string vhost, std::string app, int port, std::string param); /** * srs_detect_tools generate the normal tcUrl */ -extern std::string srs_generate_normal_tc_url( - std::string ip, std::string vhost, std::string app, int port, std::string param); +extern std::string srs_generate_normal_tc_url(std::string ip, std::string vhost, std::string app, int port, std::string param); /** * srs_detect_tools generate the normal tcUrl */ -extern std::string srs_generate_via_tc_url( - std::string ip, std::string vhost, std::string app, int port, std::string param); +extern std::string srs_generate_via_tc_url(std::string ip, std::string vhost, std::string app, int port, std::string param); /** * srs_detect_tools generate the vis/vis2 tcUrl */ -extern std::string srs_generate_vis_tc_url( - std::string ip, std::string vhost, std::string app, int port, std::string param); +extern std::string srs_generate_vis_tc_url(std::string ip, std::string vhost, std::string app, int port, std::string param); /** -* create shared ptr message from bytes. -* @param data the packet bytes. user should never free it. -* @param ppmsg output the shared ptr message. user should free it. -*/ -extern int srs_rtmp_create_msg( - char type, uint32_t timestamp, char* data, int size, int stream_id, - SrsSharedPtrMessage** ppmsg -); -extern int srs_rtmp_create_msg( - char type, uint32_t timestamp, char* data, int size, int stream_id, - SrsCommonMessage** ppmsg -); + * create shared ptr message from bytes. + * @param data the packet bytes. user should never free it. + * @param ppmsg output the shared ptr message. user should free it. + */ +extern int srs_rtmp_create_msg(char type, uint32_t timestamp, char* data, int size, int stream_id, SrsSharedPtrMessage** ppmsg); +extern int srs_rtmp_create_msg(char type, uint32_t timestamp, char* data, int size, int stream_id, SrsCommonMessage** ppmsg); // get the stream identify, vhost/app/stream. -extern std::string srs_generate_stream_url( - std::string vhost, std::string app, std::string stream -); +extern std::string srs_generate_stream_url(std::string vhost, std::string app, std::string stream); // parse the rtmp url to tcUrl/stream, // for example, rtmp://v.ossrs.net/live/livestream to // tcUrl: rtmp://v.ossrs.net/live // stream: livestream -extern void srs_parse_rtmp_url( - std::string url, std::string& tcUrl, std::string& stream -); +extern void srs_parse_rtmp_url(std::string url, std::string& tcUrl, std::string& stream); // genereate the rtmp url, for instance, rtmp://server:port/app...vhost...vhost/stream -extern std::string srs_generate_rtmp_url( - std::string server, int port, std::string vhost, std::string app, std::string stream -); +extern std::string srs_generate_rtmp_url(std::string server, int port, std::string vhost, std::string app, std::string stream); // write large numbers of iovs. -extern int srs_write_large_iovs( - ISrsProtocolReaderWriter* skt, iovec* iovs, int size, - ssize_t* pnwrite = NULL -); +extern int srs_write_large_iovs(ISrsProtocolReaderWriter* skt, iovec* iovs, int size, ssize_t* pnwrite = NULL); // join string in vector with indicated separator extern std::string srs_join_vector_string(std::vector& vs, std::string separator); diff --git a/trunk/src/protocol/srs_raw_avc.cpp b/trunk/src/protocol/srs_raw_avc.cpp index 7ddb76e59..26a20ac51 100644 --- a/trunk/src/protocol/srs_raw_avc.cpp +++ b/trunk/src/protocol/srs_raw_avc.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -44,10 +44,10 @@ SrsRawH264Stream::~SrsRawH264Stream() int SrsRawH264Stream::annexb_demux(SrsBuffer* stream, char** pframe, int* pnb_frame) { int ret = ERROR_SUCCESS; - + *pframe = NULL; *pnb_frame = 0; - + while (!stream->empty()) { // each frame must prefixed by annexb format. // about annexb, @see ISO_IEC_14496-10-AVC-2003.pdf, page 211. @@ -71,7 +71,7 @@ int SrsRawH264Stream::annexb_demux(SrsBuffer* stream, char** pframe, int* pnb_fr *pframe = stream->data() + start; break; } - + return ret; } @@ -79,11 +79,11 @@ bool SrsRawH264Stream::is_sps(char* frame, int nb_frame) { srs_assert(nb_frame > 0); - // 5bits, 7.3.1 NAL unit syntax, + // 5bits, 7.3.1 NAL unit syntax, // ISO_IEC_14496-10-AVC-2003.pdf, page 44. // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame uint8_t nal_unit_type = (char)frame[0] & 0x1f; - + return nal_unit_type == 7; } @@ -91,23 +91,23 @@ bool SrsRawH264Stream::is_pps(char* frame, int nb_frame) { srs_assert(nb_frame > 0); - // 5bits, 7.3.1 NAL unit syntax, + // 5bits, 7.3.1 NAL unit syntax, // ISO_IEC_14496-10-AVC-2003.pdf, page 44. // 7: SPS, 8: PPS, 5: I Frame, 1: P Frame uint8_t nal_unit_type = (char)frame[0] & 0x1f; - + return nal_unit_type == 8; } int SrsRawH264Stream::sps_demux(char* frame, int nb_frame, string& sps) { int ret = ERROR_SUCCESS; - + // atleast 1bytes for SPS to decode the type, profile, constrain and level. if (nb_frame < 4) { return ret; } - + sps = ""; if (nb_frame > 0) { sps.append(frame, nb_frame); @@ -117,31 +117,31 @@ int SrsRawH264Stream::sps_demux(char* frame, int nb_frame, string& sps) if (sps.empty()) { return ERROR_STREAM_CASTER_AVC_SPS; } - + return ret; } int SrsRawH264Stream::pps_demux(char* frame, int nb_frame, string& pps) { int ret = ERROR_SUCCESS; - + pps = ""; if (nb_frame > 0) { pps.append(frame, nb_frame); } - + // should never be empty. if (pps.empty()) { return ERROR_STREAM_CASTER_AVC_PPS; } - + return ret; } int SrsRawH264Stream::mux_sequence_header(string sps, string pps, uint32_t dts, uint32_t pts, string& sh) { int ret = ERROR_SUCCESS; - + // 5bytes sps/pps header: // configurationVersion, AVCProfileIndication, profile_compatibility, // AVCLevelIndication, lengthSizeMinusOne @@ -153,24 +153,24 @@ int SrsRawH264Stream::mux_sequence_header(string sps, string pps, uint32_t dts, // numOfPictureParameterSets, pictureParameterSetLength // Nbytes of pps: // pictureParameterSetNALUnit - int nb_packet = 5 - + 3 + (int)sps.length() - + 3 + (int)pps.length(); + int nb_packet = 5 + + 3 + (int)sps.length() + + 3 + (int)pps.length(); char* packet = new char[nb_packet]; SrsAutoFreeA(char, packet); - + // use stream to generate the h264 packet. SrsBuffer stream; if ((ret = stream.initialize(packet, nb_packet)) != ERROR_SUCCESS) { return ret; } - // decode the SPS: + // decode the SPS: // @see: 7.3.2.1.1, ISO_IEC_14496-10-AVC-2012.pdf, page 62 if (true) { srs_assert((int)sps.length() >= 4); char* frame = (char*)sps.data(); - + // @see: Annex A Profiles and levels, ISO_IEC_14496-10-AVC-2003.pdf, page 205 // Baseline profile profile_idc is 66(0x42). // Main profile profile_idc is 77(0x4d). @@ -215,14 +215,14 @@ int SrsRawH264Stream::mux_sequence_header(string sps, string pps, uint32_t dts, // pictureParameterSetNALUnit stream.write_string(pps); } - + // TODO: FIXME: for more profile. // 5.3.4.2.1 Syntax, ISO_IEC_14496-15-AVC-format-2012.pdf, page 16 // profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || profile_idc == 144 - + sh = ""; sh.append(packet, nb_packet); - + return ret; } @@ -243,21 +243,21 @@ int SrsRawH264Stream::mux_ipb_frame(char* frame, int nb_frame, string& ibp) if ((ret = stream.initialize(packet, nb_packet)) != ERROR_SUCCESS) { return ret; } - + // 5.3.4.2.1 Syntax, ISO_IEC_14496-15-AVC-format-2012.pdf, page 16 // lengthSizeMinusOne, or NAL_unit_length, always use 4bytes size uint32_t NAL_unit_length = nb_frame; - // mux the avc NALU in "ISO Base Media File Format" + // mux the avc NALU in "ISO Base Media File Format" // from ISO_IEC_14496-15-AVC-format-2012.pdf, page 20 // NALUnitLength stream.write_4bytes(NAL_unit_length); // NALUnit stream.write_bytes(frame, nb_frame); - + ibp = ""; ibp.append(packet, nb_packet); - + return ret; } @@ -282,9 +282,9 @@ int SrsRawH264Stream::mux_avc2flv(string video, int8_t frame_type, int8_t avc_pa // AVCPacketType *p++ = avc_packet_type; - + // CompositionTime - // pts = dts + cts, or + // pts = dts + cts, or // cts = pts - dts. // where cts is the header in rtmp video packet payload header. uint32_t cts = pts - dts; @@ -295,10 +295,10 @@ int SrsRawH264Stream::mux_avc2flv(string video, int8_t frame_type, int8_t avc_pa // h.264 raw data. memcpy(p, video.data(), video.length()); - + *flv = data; *nb_flv = size; - + return ret; } @@ -358,9 +358,9 @@ int SrsRawAacStream::adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame int8_t protection_absent = pav & 0x01; /** - * ID: MPEG identifier, set to '1' if the audio data in the ADTS stream are MPEG-2 AAC (See ISO/IEC 13818-7) - * and set to '0' if the audio data are MPEG-4. See also ISO/IEC 11172-3, subclause 2.4.2.3. - */ + * ID: MPEG identifier, set to '1' if the audio data in the ADTS stream are MPEG-2 AAC (See ISO/IEC 13818-7) + * and set to '0' if the audio data are MPEG-4. See also ISO/IEC 11172-3, subclause 2.4.2.3. + */ if (id != 0x01) { srs_info("adts: id must be 1(aac), actual 0(mp4a). ret=%d", ret); @@ -447,22 +447,22 @@ int SrsRawAacStream::adts_demux(SrsBuffer* stream, char** pframe, int* pnb_frame codec.sound_type = srs_max(0, srs_min(1, channel_configuration - 1)); // TODO: FIXME: finger it out the sound size by adts. codec.sound_size = 1; // 0(8bits) or 1(16bits). - + // frame data. *pframe = stream->data() + stream->pos(); *pnb_frame = raw_data_size; stream->skip(raw_data_size); - + break; } - + return ret; } int SrsRawAacStream::mux_sequence_header(SrsRawAacStreamCodec* codec, string& sh) { int ret = ERROR_SUCCESS; - + // only support aac profile 1-4. if (codec->aac_object == SrsAacObjectTypeReserved) { return ERROR_AAC_DATA_INVALID; @@ -471,22 +471,22 @@ int SrsRawAacStream::mux_sequence_header(SrsRawAacStreamCodec* codec, string& sh SrsAacObjectType audioObjectType = codec->aac_object; char channelConfiguration = codec->channel_configuration; char samplingFrequencyIndex = codec->sampling_frequency_index; - + // override the aac samplerate by user specified. // @see https://github.com/ossrs/srs/issues/212#issuecomment-64146899 switch (codec->sound_rate) { - case SrsAudioSampleRate11025: + case SrsAudioSampleRate11025: samplingFrequencyIndex = 0x0a; break; - case SrsAudioSampleRate22050: + case SrsAudioSampleRate22050: samplingFrequencyIndex = 0x07; break; - case SrsAudioSampleRate44100: + case SrsAudioSampleRate44100: samplingFrequencyIndex = 0x04; break; default: break; } - + sh = ""; - + char ch = 0; // @see ISO_IEC_14496-3-AAC-2001.pdf // AudioSpecificConfig (), page 33 @@ -494,7 +494,7 @@ int SrsRawAacStream::mux_sequence_header(SrsRawAacStreamCodec* codec, string& sh // audioObjectType; 5 bslbf ch = (audioObjectType << 3) & 0xf8; // 3bits left. - + // samplingFrequencyIndex; 4 bslbf ch |= (samplingFrequencyIndex >> 1) & 0x07; sh += ch; @@ -503,31 +503,31 @@ int SrsRawAacStream::mux_sequence_header(SrsRawAacStreamCodec* codec, string& sh return ERROR_AAC_DATA_INVALID; } // 7bits left. - + // channelConfiguration; 4 bslbf ch |= (channelConfiguration << 3) & 0x78; // 3bits left. - + // GASpecificConfig(), page 451 // 4.4.1 Decoder configuration (GASpecificConfig) // frameLengthFlag; 1 bslbf // dependsOnCoreCoder; 1 bslbf // extensionFlag; 1 bslbf sh += ch; - + return ret; } int SrsRawAacStream::mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec* codec, uint32_t dts, char** flv, int* nb_flv) { int ret = ERROR_SUCCESS; - + char sound_format = codec->sound_format; char sound_type = codec->sound_type; char sound_size = codec->sound_size; char sound_rate = codec->sound_rate; char aac_packet_type = codec->aac_packet_type; - + // for audio frame, there is 1 or 2 bytes header: // 1bytes, SoundFormat|SoundRate|SoundSize|SoundType // 1bytes, AACPacketType for SoundFormat == 10, 0 is sequence header. @@ -550,10 +550,10 @@ int SrsRawAacStream::mux_aac2flv(char* frame, int nb_frame, SrsRawAacStreamCodec } memcpy(p, frame, nb_frame); - + *flv = data; *nb_flv = size; - + return ret; } diff --git a/trunk/src/protocol/srs_raw_avc.hpp b/trunk/src/protocol/srs_raw_avc.hpp index 8d5223f1d..c0831de7e 100644 --- a/trunk/src/protocol/srs_raw_avc.hpp +++ b/trunk/src/protocol/srs_raw_avc.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_PROTOCOL_RAW_AVC_HPP #define SRS_PROTOCOL_RAW_AVC_HPP -/* -#include -*/ - #include #include @@ -37,8 +33,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. class SrsBuffer; /** -* the raw h.264 stream, in annexb. -*/ + * the raw h.264 stream, in annexb. + */ class SrsRawH264Stream { public: @@ -46,51 +42,51 @@ public: 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 int 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 int sps_demux(char* frame, int nb_frame, std::string& sps); virtual int 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. - */ + * 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 int 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. - */ + * 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 int 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 int 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; @@ -98,7 +94,7 @@ struct SrsRawAacStreamCodec int8_t sampling_frequency_index; int8_t channel_configuration; int16_t frame_length; - + char sound_format; char sound_rate; char sound_size; @@ -108,8 +104,8 @@ struct SrsRawAacStreamCodec }; /** -* the raw aac stream, in adts. -*/ + * the raw aac stream, in adts. + */ class SrsRawAacStream { public: @@ -117,27 +113,27 @@ public: 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 int 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. - */ + * 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 int 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 int 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.cpp b/trunk/src/protocol/srs_rtmp_handshake.cpp index 694c62275..13b7040da 100644 --- a/trunk/src/protocol/srs_rtmp_handshake.cpp +++ b/trunk/src/protocol/srs_rtmp_handshake.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -137,7 +137,7 @@ namespace _srs_internal 0x93, 0xB8, 0xE6, 0x36, 0xCF, 0xEB, 0x31, 0xAE }; // 62 - int do_openssl_HMACsha256(HMAC_CTX* ctx, const void* data, int data_size, void* digest, unsigned int* digest_size) + int do_openssl_HMACsha256(HMAC_CTX* ctx, const void* data, int data_size, void* digest, unsigned int* digest_size) { int ret = ERROR_SUCCESS; @@ -145,7 +145,7 @@ namespace _srs_internal ret = ERROR_OpenSslSha256Update; return ret; } - + if (HMAC_Final(ctx, (unsigned char *) digest, digest_size) < 0) { ret = ERROR_OpenSslSha256Final; return ret; @@ -154,11 +154,11 @@ namespace _srs_internal return ret; } /** - * sha256 digest algorithm. - * @param key the sha256 key, NULL to use EVP_Digest, for instance, - * hashlib.sha256(data).digest(). - */ - int openssl_HMACsha256(const void* key, int key_size, const void* data, int data_size, void* digest) + * sha256 digest algorithm. + * @param key the sha256 key, NULL to use EVP_Digest, for instance, + * hashlib.sha256(data).digest(). + */ + int openssl_HMACsha256(const void* key, int key_size, const void* data, int data_size, void* digest) { int ret = ERROR_SUCCESS; @@ -180,8 +180,8 @@ namespace _srs_internal // use key-data to digest. HMAC_CTX *ctx = HMAC_CTX_new(); if (ctx == NULL) { - ret = ERROR_OpenSslCreateHMAC; - return ret; + ret = ERROR_OpenSslCreateHMAC; + return ret; } // @remark, if no key, use EVP_Digest to digest, // for instance, in python, hashlib.sha256(data).digest(). @@ -207,13 +207,13 @@ namespace _srs_internal return ret; } - #define RFC2409_PRIME_1024 \ - "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ - "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ - "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ - "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ - "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \ - "FFFFFFFFFFFFFFFF" +#define RFC2409_PRIME_1024 \ +"FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" \ +"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" \ +"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" \ +"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ +"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" \ +"FFFFFFFFFFFFFFFF" SrsDH::SrsDH() { @@ -326,26 +326,26 @@ namespace _srs_internal //1. Create the DH if ((pdh = DH_new()) == NULL) { - ret = ERROR_OpenSslCreateDH; + ret = ERROR_OpenSslCreateDH; return ret; } - + //2. Create his internal p and g BIGNUM *p, *g; if ((p = BN_new()) == NULL) { - ret = ERROR_OpenSslCreateP; + ret = ERROR_OpenSslCreateP; return ret; } if ((g = BN_new()) == NULL) { - ret = ERROR_OpenSslCreateG; + ret = ERROR_OpenSslCreateG; BN_free(p); return ret; } DH_set0_pqg(pdh, p, NULL, g); - + //3. initialize p and g, @see ./test/ectest.c:260 if (!BN_hex2bn(&p, RFC2409_PRIME_1024)) { - ret = ERROR_OpenSslParseP1024; + ret = ERROR_OpenSslParseP1024; return ret; } // @see ./test/bntest.c:1764 @@ -353,10 +353,10 @@ namespace _srs_internal ret = ERROR_OpenSslSetG; return ret; } - + // 4. Set the key length DH_set_length(pdh, bits_count); - + // 5. Generate private and public key // @see ./test/dhtest.c:152 if (!DH_generate_key(pdh)) { @@ -405,7 +405,7 @@ namespace _srs_internal // the key must be 764 bytes. srs_assert(stream->require(764)); - + // read the last offset first, 760-763 stream->skip(764 - sizeof(int32_t)); offset = stream->read_4bytes(); @@ -445,7 +445,7 @@ namespace _srs_internal valid_offset += *pp++; valid_offset += *pp++; valid_offset += *pp++; - + return valid_offset % max_offset_size; } @@ -480,7 +480,7 @@ namespace _srs_internal srs_freepa(random0); srs_freepa(random1); } - + int digest_block::parse(SrsBuffer* stream) { int ret = ERROR_SUCCESS; @@ -522,7 +522,7 @@ namespace _srs_internal valid_offset += *pp++; valid_offset += *pp++; valid_offset += *pp++; - + return valid_offset % max_offset_size; } @@ -592,7 +592,7 @@ namespace _srs_internal int c1s1_strategy::s1_create(c1s1* owner, c1s1* c1) { int ret = ERROR_SUCCESS; - + SrsDH dh; // ensure generate 128bytes public key. @@ -607,13 +607,13 @@ namespace _srs_internal srs_error("calc s1 key failed. ret=%d", ret); return ret; } - + // although the public key is always 128bytes, but the share key maybe not. // we just ignore the actual key size, but if need to use the key, must use the actual size. // TODO: FIXME: use the actual key size. //srs_assert(pkey_size == 128); srs_verbose("calc s1 key success."); - + char* s1_digest = NULL; if ((ret = calc_s1_digest(owner, s1_digest)) != ERROR_SUCCESS) { srs_error("calc s1 digest failed. ret=%d", ret); @@ -652,14 +652,14 @@ namespace _srs_internal int c1s1_strategy::calc_c1_digest(c1s1* owner, char*& c1_digest) { int ret = ERROR_SUCCESS; - + /** - * c1s1 is splited by digest: - * c1s1-part1: n bytes (time, version, key and digest-part1). - * digest-data: 32bytes - * c1s1-part2: (1536-n-32)bytes (digest-part2) - * @return a new allocated bytes, user must free it. - */ + * c1s1 is splited by digest: + * c1s1-part1: n bytes (time, version, key and digest-part1). + * digest-data: 32bytes + * c1s1-part2: (1536-n-32)bytes (digest-part2) + * @return a new allocated bytes, user must free it. + */ char* c1s1_joined_bytes = new char[1536 -32]; SrsAutoFreeA(char, c1s1_joined_bytes); if ((ret = copy_to(owner, c1s1_joined_bytes, 1536 - 32, false)) != ERROR_SUCCESS) { @@ -680,14 +680,14 @@ namespace _srs_internal int c1s1_strategy::calc_s1_digest(c1s1* owner, char*& s1_digest) { int ret = ERROR_SUCCESS; - + /** - * c1s1 is splited by digest: - * c1s1-part1: n bytes (time, version, key and digest-part1). - * digest-data: 32bytes - * c1s1-part2: (1536-n-32)bytes (digest-part2) - * @return a new allocated bytes, user must free it. - */ + * c1s1 is splited by digest: + * c1s1-part1: n bytes (time, version, key and digest-part1). + * digest-data: 32bytes + * c1s1-part2: (1536-n-32)bytes (digest-part2) + * @return a new allocated bytes, user must free it. + */ char* c1s1_joined_bytes = new char[1536 -32]; SrsAutoFreeA(char, c1s1_joined_bytes); if ((ret = copy_to(owner, c1s1_joined_bytes, 1536 - 32, false)) != ERROR_SUCCESS) { @@ -701,7 +701,7 @@ namespace _srs_internal return ret; } srs_verbose("digest calculated for s1"); - + return ret; } @@ -711,7 +711,7 @@ namespace _srs_internal // 4bytes time stream->write_4bytes(owner->time); - + // 4bytes version stream->write_4bytes(owner->version); } @@ -800,7 +800,7 @@ namespace _srs_internal if ((ret = stream.initialize(_c1s1 + 8 + 764, 764)) != ERROR_SUCCESS) { return ret; } - + if ((ret = digest.parse(&stream)) != ERROR_SUCCESS) { srs_error("parse the c1 digest failed. ret=%d", ret); return ret; @@ -860,7 +860,7 @@ namespace _srs_internal if ((ret = stream.initialize(_c1s1 + 8, 764)) != ERROR_SUCCESS) { return ret; } - + if ((ret = digest.parse(&stream)) != ERROR_SUCCESS) { srs_error("parse the c1 digest failed. ret=%d", ret); return ret; @@ -966,7 +966,7 @@ namespace _srs_internal } else { payload = new c1s1_strategy_schema1(); } - + return payload->parse(_c1s1, size); } @@ -983,7 +983,7 @@ namespace _srs_internal // client c1 time and version time = (int32_t)::time(NULL); version = 0x80000702; // client c1 version - + // generate signature by schema srs_freep(payload); if (schema == srs_schema0) { @@ -1181,7 +1181,7 @@ int SrsSimpleHandshake::handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsP if ((ret = hs_bytes->read_c0c1(io)) != ERROR_SUCCESS) { return ret; } - + // plain text required. if (hs_bytes->c0c1[0] != 0x03) { ret = ERROR_RTMP_PLAIN_REQUIRED; @@ -1274,7 +1274,7 @@ int SrsComplexHandshake::handshake_with_client(SrsHandshakeBytes* /*hs_bytes*/, int SrsComplexHandshake::handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReaderWriter* io) { int ret = ERROR_SUCCESS; - + ssize_t nsize; if ((ret = hs_bytes->read_c0c1(io)) != ERROR_SUCCESS) { @@ -1382,7 +1382,7 @@ int SrsComplexHandshake::handshake_with_server(SrsHandshakeBytes* /*hs_bytes*/, int SrsComplexHandshake::handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReaderWriter* io) { int ret = ERROR_SUCCESS; - + ssize_t nsize; // complex handshake @@ -1399,7 +1399,7 @@ int SrsComplexHandshake::handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrs if ((ret = c1.dump(hs_bytes->c0c1 + 1, 1536)) != ERROR_SUCCESS) { return ret; } - + // verify c1 bool is_valid; if ((ret = c1.c1_validate_digest(is_valid)) != ERROR_SUCCESS || !is_valid) { @@ -1439,12 +1439,12 @@ int SrsComplexHandshake::handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrs if ((ret = hs_bytes->create_c2()) != ERROR_SUCCESS) { return ret; } - + c2s2 c2; if ((ret = c2.c2_create(&s1)) != ERROR_SUCCESS) { return ret; } - + if ((ret = c2.dump(hs_bytes->c2, 1536)) != ERROR_SUCCESS) { return ret; } diff --git a/trunk/src/protocol/srs_rtmp_handshake.hpp b/trunk/src/protocol/srs_rtmp_handshake.hpp index fec5c96a0..a60c83e01 100644 --- a/trunk/src/protocol/srs_rtmp_handshake.hpp +++ b/trunk/src/protocol/srs_rtmp_handshake.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_PROTOCOL_HANDSHAKE_HPP #define SRS_PROTOCOL_HANDSHAKE_HPP -/* -#include -*/ - #include class ISrsProtocolReaderWriter; @@ -43,15 +39,15 @@ class SrsBuffer; namespace _srs_internal { // the digest key generate size. - #define SRS_OpensslHashSize 512 +#define SRS_OpensslHashSize 512 extern uint8_t SrsGenuineFMSKey[]; extern uint8_t SrsGenuineFPKey[]; int openssl_HMACsha256(const void* key, int key_size, const void* data, int data_size, void* digest); int openssl_generate_key(char* public_key, int32_t size); /** - * the DH wrapper. - */ + * the DH wrapper. + */ class SrsDH { private: @@ -63,61 +59,61 @@ namespace _srs_internal 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 int 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 int 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 int copy_shared_key(const char* ppkey, int32_t ppkey_size, char* skey, int32_t& skey_size); private: virtual int do_initialize(); }; /** - * the schema type. - */ - enum srs_schema_type + * the schema type. + */ + enum srs_schema_type { srs_schema_invalid = 2, /** - * key-digest sequence - */ + * key-digest sequence + */ srs_schema0 = 0, /** - * digest-key sequence - * @remark, FMS requires the schema1(digest-key), or connect failed. - */ - // + * 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 - */ + * 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: @@ -149,13 +145,13 @@ namespace _srs_internal }; /** - * 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 - */ + * 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: @@ -189,10 +185,10 @@ namespace _srs_internal 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: @@ -203,113 +199,113 @@ namespace _srs_internal 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 int 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. - */ + * server: parse the c1s1, discovery the key and digest by schema. + * use the c1_validate_digest() to valid the digest of c1. + */ virtual int 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 - */ + * 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 int c1_create(c1s1* owner); /** - * server: validate the parsed c1 schema - */ + * server: validate the parsed c1 schema + */ virtual int 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. - */ + * 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 int s1_create(c1s1* owner, c1s1* c1); /** - * server: validate the parsed s1 schema - */ + * server: validate the parsed s1 schema + */ virtual int s1_validate_digest(c1s1* owner, bool& is_valid); public: /** - * calc the digest for c1 - */ + * calc the digest for c1 + */ virtual int calc_c1_digest(c1s1* owner, char*& c1_digest); /** - * calc the digest for s1 - */ + * calc the digest for s1 + */ virtual int 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 int 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 - */ + * c1s1 schema0 + * key: 764bytes + * digest: 764bytes + */ class c1s1_strategy_schema0 : public c1s1_strategy { public: @@ -323,10 +319,10 @@ namespace _srs_internal }; /** - * c1s1 schema1 - * digest: 764bytes - * key: 764bytes - */ + * c1s1 schema1 + * digest: 764bytes + * key: 764bytes + */ class c1s1_strategy_schema1 : public c1s1_strategy { public: @@ -338,20 +334,20 @@ namespace _srs_internal public: virtual int 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 - */ + * 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 + */ class c1s1 { public: @@ -366,91 +362,91 @@ namespace _srs_internal 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 int 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. - */ + * 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 int 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 - */ + * 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 int c1_create(srs_schema_type _schema); /** - * server: validate the parsed c1 schema - */ + * server: validate the parsed c1 schema + */ virtual int 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. - */ + * 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 int s1_create(c1s1* c1); /** - * server: validate the parsed s1 schema - */ + * server: validate the parsed s1 schema + */ virtual int 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: @@ -461,44 +457,44 @@ namespace _srs_internal virtual ~c2s2(); public: /** - * copy to bytes. - * @param size, must always be 1536. - */ + * copy to bytes. + * @param size, must always be 1536. + */ virtual int dump(char* _c2s2, int size); /** - * parse the c2s2 - * @param size, must always be 1536. - */ + * parse the c2s2 + * @param size, must always be 1536. + */ virtual int 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 int c2_create(c1s1* s1); /** - * validate the c2 from client. - */ + * validate the c2 from client. + */ virtual int 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 + * + * // 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 int s2_create(c1s1* c1); /** - * validate the s2 from server. - */ + * validate the s2 from server. + */ virtual int s2_validate(c1s1* c1, bool& is_valid); }; } @@ -506,10 +502,10 @@ namespace _srs_internal #endif /** -* 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: @@ -517,17 +513,17 @@ public: virtual ~SrsSimpleHandshake(); public: /** - * simple handshake. - */ + * simple handshake. + */ virtual int handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReaderWriter* io); virtual int handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReaderWriter* io); }; /** -* rtmp complex handshake, -* @see also crtmp(crtmpserver) or librtmp, -* @see also: http://blog.csdn.net/win_lin/article/details/13006803 -*/ + * rtmp complex handshake, + * @see also crtmp(crtmpserver) or librtmp, + * @see also: http://blog.csdn.net/win_lin/article/details/13006803 + */ class SrsComplexHandshake { public: @@ -535,12 +531,12 @@ public: 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 int handshake_with_client(SrsHandshakeBytes* hs_bytes, ISrsProtocolReaderWriter* io); virtual int handshake_with_server(SrsHandshakeBytes* hs_bytes, ISrsProtocolReaderWriter* io); }; diff --git a/trunk/src/protocol/srs_rtmp_msg_array.cpp b/trunk/src/protocol/srs_rtmp_msg_array.cpp index 184d4cdeb..ee3188156 100644 --- a/trunk/src/protocol/srs_rtmp_msg_array.cpp +++ b/trunk/src/protocol/srs_rtmp_msg_array.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include diff --git a/trunk/src/protocol/srs_rtmp_msg_array.hpp b/trunk/src/protocol/srs_rtmp_msg_array.hpp index 2dbee101d..27d044ecf 100644 --- a/trunk/src/protocol/srs_rtmp_msg_array.hpp +++ b/trunk/src/protocol/srs_rtmp_msg_array.hpp @@ -1,74 +1,70 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_PROTOCOL_MESSAGE_ARRAY_HPP #define SRS_PROTOCOL_MESSAGE_ARRAY_HPP -/* -#include -*/ - #include 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 the msg in 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 the msg in 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.cpp b/trunk/src/protocol/srs_rtmp_stack.cpp index bd0cd9bac..6bdc23c75 100644 --- a/trunk/src/protocol/srs_rtmp_stack.cpp +++ b/trunk/src/protocol/srs_rtmp_stack.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -52,13 +52,13 @@ using namespace std; #define SRS_MIN_RECV_TIMEOUT_US (int64_t)(60*1000*1000LL) /**************************************************************************** -***************************************************************************** -****************************************************************************/ + ***************************************************************************** + ****************************************************************************/ /** -* 6.1.2. Chunk Message Header -* There are four different formats for the chunk message header, -* selected by the "fmt" field in the chunk basic header. -*/ + * 6.1.2. Chunk Message Header + * There are four different formats for the chunk message header, + * selected by the "fmt" field in the chunk basic header. + */ // 6.1.2.1. Type 0 // Chunks of Type 0 are 11 bytes long. This type MUST be used at the // start of a chunk stream, and whenever the stream timestamp goes @@ -95,13 +95,13 @@ using namespace std; #define RTMP_FMT_TYPE3 3 /**************************************************************************** -***************************************************************************** -****************************************************************************/ + ***************************************************************************** + ****************************************************************************/ /** -* band width check method name, which will be invoked by client. -* band width check mothods use SrsBandwidthPacket as its internal packet type, -* so ensure you set command name when you use it. -*/ + * band width check method name, which will be invoked by client. + * band width check mothods use SrsBandwidthPacket as its internal packet type, + * so ensure you set command name when you use it. + */ // server play control #define SRS_BW_CHECK_START_PLAY "onSrsBandCheckStartPlayBytes" #define SRS_BW_CHECK_STARTING_PLAY "onSrsBandCheckStartingPlayBytes" @@ -126,8 +126,8 @@ using namespace std; #define SRS_BW_CHECK_PUBLISHING "onSrsBandCheckPublishing" /**************************************************************************** -***************************************************************************** -****************************************************************************/ + ***************************************************************************** + ****************************************************************************/ SrsPacket::SrsPacket() { @@ -255,7 +255,7 @@ SrsProtocol::~SrsProtocol() SrsChunkStream* stream = it->second; srs_freep(stream); } - + chunk_streams.clear(); } @@ -386,8 +386,8 @@ int SrsProtocol::recv_message(SrsCommonMessage** pmsg) if (msg->size <= 0 || msg->header.payload_length <= 0) { srs_trace("ignore empty message(type=%d, size=%d, time=%"PRId64", sid=%d).", - msg->header.message_type, msg->header.payload_length, - msg->header.timestamp, msg->header.stream_id); + msg->header.message_type, msg->header.payload_length, + msg->header.timestamp, msg->header.stream_id); srs_freep(msg); continue; } @@ -398,9 +398,9 @@ int SrsProtocol::recv_message(SrsCommonMessage** pmsg) return ret; } - srs_verbose("got a msg, cid=%d, type=%d, size=%d, time=%"PRId64, - msg->header.perfer_cid, msg->header.message_type, msg->header.payload_length, - msg->header.timestamp); + srs_verbose("got a msg, cid=%d, type=%d, size=%d, time=%"PRId64, + msg->header.perfer_cid, msg->header.message_type, msg->header.payload_length, + msg->header.timestamp); *pmsg = msg; break; } @@ -419,7 +419,7 @@ int SrsProtocol::decode_message(SrsCommonMessage* msg, SrsPacket** ppacket) srs_assert(msg->size > 0); SrsBuffer stream; - + // initialize the decode stream for all message, // it's ok for the initialize if fast and without memory copy. if ((ret = stream.initialize(msg->payload, msg->size)) != ERROR_SUCCESS) { @@ -451,7 +451,7 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) int c0c3_cache_index = 0; char* c0c3_cache = out_c0c3_caches + c0c3_cache_index; - + // try to send use the c0c3 header cache, // if cache is consumed, try another loop. for (int i = 0; i < nb_msgs; i++) { @@ -460,13 +460,13 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) if (!msg) { continue; } - + // ignore empty message. if (!msg->payload || msg->size <= 0) { srs_info("ignore empty message."); continue; } - + // p set to current write position, // it's ok when payload is NULL and size is 0. char* p = msg->payload; @@ -495,10 +495,10 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) // for we donot know how many messges maybe to send entirely, // we just alloc the iovs, it's ok. if (iov_index >= nb_out_iovs - 2) { - srs_warn("resize iovs %d => %d, max_msgs=%d", - nb_out_iovs, nb_out_iovs + SRS_CONSTS_IOVS_MAX, - SRS_PERF_MW_MSGS); - + srs_warn("resize iovs %d => %d, max_msgs=%d", + nb_out_iovs, nb_out_iovs + SRS_CONSTS_IOVS_MAX, + SRS_PERF_MW_MSGS); + nb_out_iovs += SRS_CONSTS_IOVS_MAX; int realloc_size = sizeof(iovec) * nb_out_iovs; out_iovs = (iovec*)realloc(out_iovs, realloc_size); @@ -507,7 +507,7 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) // to next pair of iovs iov_index += 2; iovs = out_iovs + iov_index; - + // to next c0c3 header cache c0c3_cache_index += nbh; c0c3_cache = out_c0c3_caches + c0c3_cache_index; @@ -519,8 +519,8 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) if (c0c3_left < SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE) { // only warn once for a connection. if (!warned_c0c3_cache_dry) { - srs_warn("c0c3 cache header too small, recoment to %d", - SRS_CONSTS_C0C3_HEADERS_MAX + SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE); + srs_warn("c0c3 cache header too small, recoment to %d", + SRS_CONSTS_C0C3_HEADERS_MAX + SRS_CONSTS_RTMP_MAX_FMT0_HEADER_SIZE); warned_c0c3_cache_dry = true; } @@ -529,8 +529,8 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) if ((ret = do_iovs_send(out_iovs, iov_index)) != ERROR_SUCCESS) { return ret; } - - // reset caches, while these cache ensure + + // reset caches, while these cache ensure // atleast we can sendout a chunk. iov_index = 0; iovs = out_iovs + iov_index; @@ -547,8 +547,8 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) return ret; } srs_info("mw %d msgs in %d iovs, max_msgs=%d, nb_out_iovs=%d", - nb_msgs, iov_index, SRS_PERF_MW_MSGS, nb_out_iovs); - + nb_msgs, iov_index, SRS_PERF_MW_MSGS, nb_out_iovs); + return do_iovs_send(out_iovs, iov_index); #else // try to send use the c0c3 header cache, @@ -559,13 +559,13 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) if (!msg) { continue; } - + // ignore empty message. if (!msg->payload || msg->size <= 0) { srs_info("ignore empty message."); continue; } - + // p set to current write position, // it's ok when payload is NULL and size is 0. char* p = msg->payload; @@ -593,7 +593,7 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) // consume sendout bytes. p += payload_size; - + if ((ret = skt->writev(iovs, 2, NULL)) != ERROR_SUCCESS) { if (!srs_is_client_gracefully_close(ret)) { srs_error("send packet with writev failed. ret=%d", ret); @@ -604,7 +604,7 @@ int SrsProtocol::do_send_messages(SrsSharedPtrMessage** msgs, int nb_msgs) } return ret; -#endif +#endif } int SrsProtocol::do_iovs_send(iovec* iovs, int size) @@ -662,13 +662,13 @@ int SrsProtocol::do_simple_send(SrsMessageHeader* mh, char* payload, int size) int nbh = 0; if (p == payload) { nbh = srs_chunk_header_c0( - mh->perfer_cid, (uint32_t)mh->timestamp, mh->payload_length, - mh->message_type, mh->stream_id, - c0c3, sizeof(c0c3)); + mh->perfer_cid, (uint32_t)mh->timestamp, mh->payload_length, + mh->message_type, mh->stream_id, + c0c3, sizeof(c0c3)); } else { nbh = srs_chunk_header_c3( - mh->perfer_cid, (uint32_t)mh->timestamp, - c0c3, sizeof(c0c3)); + mh->perfer_cid, (uint32_t)mh->timestamp, + c0c3, sizeof(c0c3)); } srs_assert(nbh > 0);; @@ -741,7 +741,7 @@ int SrsProtocol::do_decode_message(SrsMessageHeader& header, SrsBuffer* stream, std::string request_name = requests[transactionId]; srs_verbose("AMF0/AMF3 request parsed. request_name=%s", request_name.c_str()); - + if (request_name == RTMP_AMF0_COMMAND_CONNECT) { srs_info("decode the AMF0/AMF3 response command(%s message).", request_name.c_str()); *ppacket = packet = new SrsConnectAppResPacket(); @@ -751,16 +751,16 @@ int SrsProtocol::do_decode_message(SrsMessageHeader& header, SrsBuffer* stream, *ppacket = packet = new SrsCreateStreamResPacket(0, 0); return packet->decode(stream); } else if (request_name == RTMP_AMF0_COMMAND_RELEASE_STREAM - || request_name == RTMP_AMF0_COMMAND_FC_PUBLISH - || request_name == RTMP_AMF0_COMMAND_UNPUBLISH) { + || request_name == RTMP_AMF0_COMMAND_FC_PUBLISH + || request_name == RTMP_AMF0_COMMAND_UNPUBLISH) { srs_info("decode the AMF0/AMF3 response command(%s message).", request_name.c_str()); *ppacket = packet = new SrsFMLEStartResPacket(0); return packet->decode(stream); } else { ret = ERROR_RTMP_NO_REQUEST; srs_error("decode AMF0/AMF3 request failed. " - "request_name=%s, transactionId=%.2f, ret=%d", - request_name.c_str(), transactionId, ret); + "request_name=%s, transactionId=%.2f, ret=%d", + request_name.c_str(), transactionId, ret); return ret; } } @@ -809,17 +809,17 @@ int SrsProtocol::do_decode_message(SrsMessageHeader& header, SrsBuffer* stream, *ppacket = packet = new SrsOnMetaDataPacket(); return packet->decode(stream); } else if(command == SRS_BW_CHECK_FINISHED - || command == SRS_BW_CHECK_PLAYING - || command == SRS_BW_CHECK_PUBLISHING - || command == SRS_BW_CHECK_STARTING_PLAY - || command == SRS_BW_CHECK_STARTING_PUBLISH - || command == SRS_BW_CHECK_START_PLAY - || command == SRS_BW_CHECK_START_PUBLISH - || command == SRS_BW_CHECK_STOPPED_PLAY - || command == SRS_BW_CHECK_STOP_PLAY - || command == SRS_BW_CHECK_STOP_PUBLISH - || command == SRS_BW_CHECK_STOPPED_PUBLISH - || command == SRS_BW_CHECK_FINAL) + || command == SRS_BW_CHECK_PLAYING + || command == SRS_BW_CHECK_PUBLISHING + || command == SRS_BW_CHECK_STARTING_PLAY + || command == SRS_BW_CHECK_STARTING_PUBLISH + || command == SRS_BW_CHECK_START_PLAY + || command == SRS_BW_CHECK_START_PUBLISH + || command == SRS_BW_CHECK_STOPPED_PLAY + || command == SRS_BW_CHECK_STOP_PLAY + || command == SRS_BW_CHECK_STOP_PUBLISH + || command == SRS_BW_CHECK_STOPPED_PUBLISH + || command == SRS_BW_CHECK_FINAL) { srs_info("decode the AMF0/AMF3 band width check message."); *ppacket = packet = new SrsBandwidthPacket(); @@ -954,8 +954,8 @@ int SrsProtocol::recv_interlaced_message(SrsCommonMessage** pmsg) // already init, use it direclty chunk = cs_cache[cid]; srs_verbose("cached chunk stream: fmt=%d, cid=%d, size=%d, message(type=%d, size=%d, time=%"PRId64", sid=%d)", - chunk->fmt, chunk->cid, (chunk->msg? chunk->msg->size : 0), chunk->header.message_type, chunk->header.payload_length, - chunk->header.timestamp, chunk->header.stream_id); + chunk->fmt, chunk->cid, (chunk->msg? chunk->msg->size : 0), chunk->header.message_type, chunk->header.payload_length, + chunk->header.timestamp, chunk->header.stream_id); } else { // chunk stream cache miss, use map. if (chunk_streams.find(cid) == chunk_streams.end()) { @@ -967,11 +967,11 @@ int SrsProtocol::recv_interlaced_message(SrsCommonMessage** pmsg) } else { chunk = chunk_streams[cid]; srs_verbose("cached chunk stream: fmt=%d, cid=%d, size=%d, message(type=%d, size=%d, time=%"PRId64", sid=%d)", - chunk->fmt, chunk->cid, (chunk->msg? chunk->msg->size : 0), chunk->header.message_type, chunk->header.payload_length, - chunk->header.timestamp, chunk->header.stream_id); + chunk->fmt, chunk->cid, (chunk->msg? chunk->msg->size : 0), chunk->header.message_type, chunk->header.payload_length, + chunk->header.timestamp, chunk->header.stream_id); } } - + // chunk stream message header if ((ret = read_message_header(chunk, fmt)) != ERROR_SUCCESS) { if (ret != ERROR_SOCKET_TIMEOUT && !srs_is_client_gracefully_close(ret)) { @@ -980,9 +980,9 @@ int SrsProtocol::recv_interlaced_message(SrsCommonMessage** pmsg) return ret; } srs_verbose("read message header success. " - "fmt=%d, ext_time=%d, size=%d, message(type=%d, size=%d, time=%"PRId64", sid=%d)", - fmt, chunk->extended_timestamp, (chunk->msg? chunk->msg->size : 0), chunk->header.message_type, - chunk->header.payload_length, chunk->header.timestamp, chunk->header.stream_id); + "fmt=%d, ext_time=%d, size=%d, message(type=%d, size=%d, time=%"PRId64", sid=%d)", + fmt, chunk->extended_timestamp, (chunk->msg? chunk->msg->size : 0), chunk->header.message_type, + chunk->header.payload_length, chunk->header.timestamp, chunk->header.stream_id); // read msg payload from chunk stream. SrsCommonMessage* msg = NULL; @@ -996,63 +996,63 @@ int SrsProtocol::recv_interlaced_message(SrsCommonMessage** pmsg) // not got an entire RTMP message, try next chunk. if (!msg) { srs_verbose("get partial message success. size=%d, message(type=%d, size=%d, time=%"PRId64", sid=%d)", - (msg? msg->size : (chunk->msg? chunk->msg->size : 0)), chunk->header.message_type, chunk->header.payload_length, - chunk->header.timestamp, chunk->header.stream_id); + (msg? msg->size : (chunk->msg? chunk->msg->size : 0)), chunk->header.message_type, chunk->header.payload_length, + chunk->header.timestamp, chunk->header.stream_id); return ret; } *pmsg = msg; srs_info("get entire message success. size=%d, message(type=%d, size=%d, time=%"PRId64", sid=%d)", - (msg? msg->size : (chunk->msg? chunk->msg->size : 0)), chunk->header.message_type, chunk->header.payload_length, - chunk->header.timestamp, chunk->header.stream_id); - + (msg? msg->size : (chunk->msg? chunk->msg->size : 0)), chunk->header.message_type, chunk->header.payload_length, + chunk->header.timestamp, chunk->header.stream_id); + return ret; } /** -* 6.1.1. Chunk Basic Header -* The Chunk Basic Header encodes the chunk stream ID and the chunk -* type(represented by fmt field in the figure below). Chunk type -* determines the format of the encoded message header. Chunk Basic -* Header field may be 1, 2, or 3 bytes, depending on the chunk stream -* ID. -* -* The bits 0-5 (least significant) in the chunk basic header represent -* the chunk stream ID. -* -* Chunk stream IDs 2-63 can be encoded in the 1-byte version of this -* field. -* 0 1 2 3 4 5 6 7 -* +-+-+-+-+-+-+-+-+ -* |fmt| cs id | -* +-+-+-+-+-+-+-+-+ -* Figure 6 Chunk basic header 1 -* -* Chunk stream IDs 64-319 can be encoded in the 2-byte version of this -* field. ID is computed as (the second byte + 64). -* 0 1 -* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 -* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -* |fmt| 0 | cs id - 64 | -* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -* Figure 7 Chunk basic header 2 -* -* Chunk stream IDs 64-65599 can be encoded in the 3-byte version of -* this field. ID is computed as ((the third byte)*256 + the second byte -* + 64). -* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 -* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -* |fmt| 1 | cs id - 64 | -* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ -* Figure 8 Chunk basic header 3 -* -* cs id: 6 bits -* fmt: 2 bits -* cs id - 64: 8 or 16 bits -* -* Chunk stream IDs with values 64-319 could be represented by both 2- -* byte version and 3-byte version of this field. -*/ + * 6.1.1. Chunk Basic Header + * The Chunk Basic Header encodes the chunk stream ID and the chunk + * type(represented by fmt field in the figure below). Chunk type + * determines the format of the encoded message header. Chunk Basic + * Header field may be 1, 2, or 3 bytes, depending on the chunk stream + * ID. + * + * The bits 0-5 (least significant) in the chunk basic header represent + * the chunk stream ID. + * + * Chunk stream IDs 2-63 can be encoded in the 1-byte version of this + * field. + * 0 1 2 3 4 5 6 7 + * +-+-+-+-+-+-+-+-+ + * |fmt| cs id | + * +-+-+-+-+-+-+-+-+ + * Figure 6 Chunk basic header 1 + * + * Chunk stream IDs 64-319 can be encoded in the 2-byte version of this + * field. ID is computed as (the second byte + 64). + * 0 1 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |fmt| 0 | cs id - 64 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * Figure 7 Chunk basic header 2 + * + * Chunk stream IDs 64-65599 can be encoded in the 3-byte version of + * this field. ID is computed as ((the third byte)*256 + the second byte + * + 64). + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |fmt| 1 | cs id - 64 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * Figure 8 Chunk basic header 3 + * + * cs id: 6 bits + * fmt: 2 bits + * cs id - 64: 8 or 16 bits + * + * Chunk stream IDs with values 64-319 could be represented by both 2- + * byte version and 3-byte version of this field. + */ int SrsProtocol::read_basic_header(char& fmt, int& cid) { int ret = ERROR_SUCCESS; @@ -1073,7 +1073,7 @@ int SrsProtocol::read_basic_header(char& fmt, int& cid) srs_verbose("basic header parsed. fmt=%d, cid=%d", fmt, cid); return ret; } - + // 64-319, 2B chunk header if (cid == 0) { if ((ret = in_buffer->grow(skt, 1)) != ERROR_SUCCESS) { @@ -1086,7 +1086,7 @@ int SrsProtocol::read_basic_header(char& fmt, int& cid) cid = 64; cid += (uint8_t)in_buffer->read_1byte(); srs_verbose("2bytes basic header parsed. fmt=%d, cid=%d", fmt, cid); - // 64-65599, 3B chunk header + // 64-65599, 3B chunk header } else if (cid == 1) { if ((ret = in_buffer->grow(skt, 2)) != ERROR_SUCCESS) { if (ret != ERROR_SOCKET_TIMEOUT && !srs_is_client_gracefully_close(ret)) { @@ -1108,47 +1108,47 @@ int SrsProtocol::read_basic_header(char& fmt, int& cid) } /** -* parse the message header. -* 3bytes: timestamp delta, fmt=0,1,2 -* 3bytes: payload length, fmt=0,1 -* 1bytes: message type, fmt=0,1 -* 4bytes: stream id, fmt=0 -* where: -* fmt=0, 0x0X -* fmt=1, 0x4X -* fmt=2, 0x8X -* fmt=3, 0xCX -*/ + * parse the message header. + * 3bytes: timestamp delta, fmt=0,1,2 + * 3bytes: payload length, fmt=0,1 + * 1bytes: message type, fmt=0,1 + * 4bytes: stream id, fmt=0 + * where: + * fmt=0, 0x0X + * fmt=1, 0x4X + * fmt=2, 0x8X + * fmt=3, 0xCX + */ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt) { int ret = ERROR_SUCCESS; /** - * we should not assert anything about fmt, for the first packet. - * (when first packet, the chunk->msg is NULL). - * the fmt maybe 0/1/2/3, the FMLE will send a 0xC4 for some audio packet. - * the previous packet is: - * 04 // fmt=0, cid=4 - * 00 00 1a // timestamp=26 - * 00 00 9d // payload_length=157 - * 08 // message_type=8(audio) - * 01 00 00 00 // stream_id=1 - * the current packet maybe: - * c4 // fmt=3, cid=4 - * it's ok, for the packet is audio, and timestamp delta is 26. - * the current packet must be parsed as: - * fmt=0, cid=4 - * timestamp=26+26=52 - * payload_length=157 - * message_type=8(audio) - * stream_id=1 - * so we must update the timestamp even fmt=3 for first packet. - */ + * we should not assert anything about fmt, for the first packet. + * (when first packet, the chunk->msg is NULL). + * the fmt maybe 0/1/2/3, the FMLE will send a 0xC4 for some audio packet. + * the previous packet is: + * 04 // fmt=0, cid=4 + * 00 00 1a // timestamp=26 + * 00 00 9d // payload_length=157 + * 08 // message_type=8(audio) + * 01 00 00 00 // stream_id=1 + * the current packet maybe: + * c4 // fmt=3, cid=4 + * it's ok, for the packet is audio, and timestamp delta is 26. + * the current packet must be parsed as: + * fmt=0, cid=4 + * timestamp=26+26=52 + * payload_length=157 + * message_type=8(audio) + * stream_id=1 + * so we must update the timestamp even fmt=3 for first packet. + */ // fresh packet used to update the timestamp even fmt=3 for first packet. // fresh packet always means the chunk is the first one of message. bool is_first_chunk_of_msg = !chunk->msg; - // but, we can ensure that when a chunk stream is fresh, + // but, we can ensure that when a chunk stream is fresh, // the fmt must be 0, a new stream. if (chunk->msg_count == 0 && fmt != RTMP_FMT_TYPE0) { // for librtmp, if ping, it will send a fresh stream with fmt=1, @@ -1164,18 +1164,18 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt) } else { // must be a RTMP protocol level error. ret = ERROR_RTMP_CHUNK_START; - srs_error("chunk stream is fresh, fmt must be %d, actual is %d. cid=%d, ret=%d", - RTMP_FMT_TYPE0, fmt, chunk->cid, ret); + srs_error("chunk stream is fresh, fmt must be %d, actual is %d. cid=%d, ret=%d", + RTMP_FMT_TYPE0, fmt, chunk->cid, ret); return ret; } } - + // when exists cache msg, means got an partial message, // the fmt must not be type0 which means new message. if (chunk->msg && fmt == RTMP_FMT_TYPE0) { ret = ERROR_RTMP_CHUNK_START; srs_error("chunk stream exists, " - "fmt must not be %d, actual is %d. ret=%d", RTMP_FMT_TYPE0, fmt, ret); + "fmt must not be %d, actual is %d. ret=%d", RTMP_FMT_TYPE0, fmt, ret); return ret; } @@ -1184,7 +1184,7 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt) chunk->msg = new SrsCommonMessage(); srs_verbose("create message for new chunk, fmt=%d, cid=%d", fmt, chunk->cid); } - + // read message header from socket to buffer. static char mh_sizes[] = {11, 7, 3, 0}; int mh_size = mh_sizes[(int)fmt]; @@ -1198,21 +1198,21 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt) } /** - * parse the message header. - * 3bytes: timestamp delta, fmt=0,1,2 - * 3bytes: payload length, fmt=0,1 - * 1bytes: message type, fmt=0,1 - * 4bytes: stream id, fmt=0 - * where: - * fmt=0, 0x0X - * fmt=1, 0x4X - * fmt=2, 0x8X - * fmt=3, 0xCX - */ + * parse the message header. + * 3bytes: timestamp delta, fmt=0,1,2 + * 3bytes: payload length, fmt=0,1 + * 1bytes: message type, fmt=0,1 + * 4bytes: stream id, fmt=0 + * where: + * fmt=0, 0x0X + * fmt=1, 0x4X + * fmt=2, 0x8X + * fmt=3, 0xCX + */ // see also: ngx_rtmp_recv if (fmt <= RTMP_FMT_TYPE2) { char* p = in_buffer->read_slice(mh_size); - + char* pp = (char*)&chunk->header.timestamp_delta; pp[2] = *p++; pp[1] = *p++; @@ -1266,13 +1266,13 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt) // for a message, if msg exists in cache, the size must not changed. // always use the actual msg size to compare, for the cache payload length can changed, - // for the fmt type1(stream_id not changed), user can change the payload + // for the fmt type1(stream_id not changed), user can change the payload // length(it's not allowed in the continue chunks). if (!is_first_chunk_of_msg && chunk->header.payload_length != payload_length) { ret = ERROR_RTMP_PACKET_SIZE; srs_error("msg exists in chunk cache, " - "size=%d cannot change to %d, ret=%d", - chunk->header.payload_length, payload_length, ret); + "size=%d cannot change to %d, ret=%d", + chunk->header.payload_length, payload_length, ret); return ret; } @@ -1285,25 +1285,25 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt) pp[1] = *p++; pp[2] = *p++; pp[3] = *p++; - srs_verbose("header read completed. fmt=%d, mh_size=%d, ext_time=%d, time=%"PRId64", payload=%d, type=%d, sid=%d", - fmt, mh_size, chunk->extended_timestamp, chunk->header.timestamp, chunk->header.payload_length, - chunk->header.message_type, chunk->header.stream_id); + srs_verbose("header read completed. fmt=%d, mh_size=%d, ext_time=%d, time=%"PRId64", payload=%d, type=%d, sid=%d", + fmt, mh_size, chunk->extended_timestamp, chunk->header.timestamp, chunk->header.payload_length, + chunk->header.message_type, chunk->header.stream_id); } else { - srs_verbose("header read completed. fmt=%d, mh_size=%d, ext_time=%d, time=%"PRId64", payload=%d, type=%d", - fmt, mh_size, chunk->extended_timestamp, chunk->header.timestamp, chunk->header.payload_length, - chunk->header.message_type); + srs_verbose("header read completed. fmt=%d, mh_size=%d, ext_time=%d, time=%"PRId64", payload=%d, type=%d", + fmt, mh_size, chunk->extended_timestamp, chunk->header.timestamp, chunk->header.payload_length, + chunk->header.message_type); } } else { - srs_verbose("header read completed. fmt=%d, mh_size=%d, ext_time=%d, time=%"PRId64"", - fmt, mh_size, chunk->extended_timestamp, chunk->header.timestamp); + srs_verbose("header read completed. fmt=%d, mh_size=%d, ext_time=%d, time=%"PRId64"", + fmt, mh_size, chunk->extended_timestamp, chunk->header.timestamp); } } else { // update the timestamp even fmt=3 for first chunk packet if (is_first_chunk_of_msg && !chunk->extended_timestamp) { chunk->header.timestamp += chunk->header.timestamp_delta; } - srs_verbose("header read completed. fmt=%d, size=%d, ext_time=%d", - fmt, mh_size, chunk->extended_timestamp); + srs_verbose("header read completed. fmt=%d, size=%d, ext_time=%d", + fmt, mh_size, chunk->extended_timestamp); } // read extended-timestamp @@ -1319,45 +1319,45 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt) // the ptr to the slice maybe invalid when grow() // reset the p to get 4bytes slice. char* p = in_buffer->read_slice(4); - + uint32_t timestamp = 0x00; char* pp = (char*)×tamp; pp[3] = *p++; pp[2] = *p++; pp[1] = *p++; pp[0] = *p++; - + // always use 31bits timestamp, for some server may use 32bits extended timestamp. // @see https://github.com/ossrs/srs/issues/111 timestamp &= 0x7fffffff; /** - * RTMP specification and ffmpeg/librtmp is false, - * but, adobe changed the specification, so flash/FMLE/FMS always true. - * default to true to support flash/FMLE/FMS. - * - * ffmpeg/librtmp may donot send this filed, need to detect the value. - * @see also: http://blog.csdn.net/win_lin/article/details/13363699 - * compare to the chunk timestamp, which is set by chunk message header - * type 0,1 or 2. - * - * @remark, nginx send the extended-timestamp in sequence-header, - * and timestamp delta in continue C1 chunks, and so compatible with ffmpeg, - * that is, there is no continue chunks and extended-timestamp in nginx-rtmp. - * - * @remark, srs always send the extended-timestamp, to keep simple, - * and compatible with adobe products. - */ + * RTMP specification and ffmpeg/librtmp is false, + * but, adobe changed the specification, so flash/FMLE/FMS always true. + * default to true to support flash/FMLE/FMS. + * + * ffmpeg/librtmp may donot send this filed, need to detect the value. + * @see also: http://blog.csdn.net/win_lin/article/details/13363699 + * compare to the chunk timestamp, which is set by chunk message header + * type 0,1 or 2. + * + * @remark, nginx send the extended-timestamp in sequence-header, + * and timestamp delta in continue C1 chunks, and so compatible with ffmpeg, + * that is, there is no continue chunks and extended-timestamp in nginx-rtmp. + * + * @remark, srs always send the extended-timestamp, to keep simple, + * and compatible with adobe products. + */ uint32_t chunk_timestamp = (uint32_t)chunk->header.timestamp; /** - * if chunk_timestamp<=0, the chunk previous packet has no extended-timestamp, - * always use the extended timestamp. - */ + * if chunk_timestamp<=0, the chunk previous packet has no extended-timestamp, + * always use the extended timestamp. + */ /** - * about the is_first_chunk_of_msg. - * @remark, for the first chunk of message, always use the extended timestamp. - */ + * about the is_first_chunk_of_msg. + * @remark, for the first chunk of message, always use the extended timestamp. + */ if (!is_first_chunk_of_msg && chunk_timestamp > 0 && chunk_timestamp != timestamp) { mh_size -= 4; in_buffer->skip(-4); @@ -1375,9 +1375,9 @@ int SrsProtocol::read_message_header(SrsChunkStream* chunk, char fmt) // 3. Byte Order, Alignment, and Time Format // Because timestamps are generally only 32 bits long, they will roll // over after fewer than 50 days. - // + // // but, its sample says the timestamp is 31bits: - // An application could assume, for example, that all + // An application could assume, for example, that all // adjacent timestamps are within 2^31 milliseconds of each other, so // 10000 comes after 4000000000, while 3000000000 comes before // 4000000000. @@ -1410,12 +1410,12 @@ int SrsProtocol::read_message_payload(SrsChunkStream* chunk, SrsCommonMessage** // empty message if (chunk->header.payload_length <= 0) { srs_trace("get an empty RTMP " - "message(type=%d, size=%d, time=%"PRId64", sid=%d)", chunk->header.message_type, - chunk->header.payload_length, chunk->header.timestamp, chunk->header.stream_id); + "message(type=%d, size=%d, time=%"PRId64", sid=%d)", chunk->header.message_type, + chunk->header.payload_length, chunk->header.timestamp, chunk->header.stream_id); *pmsg = chunk->msg; chunk->msg = NULL; - + return ret; } srs_assert(chunk->header.payload_length > 0); @@ -1423,9 +1423,9 @@ int SrsProtocol::read_message_payload(SrsChunkStream* chunk, SrsCommonMessage** // the chunk payload size. int payload_size = chunk->header.payload_length - chunk->msg->size; payload_size = srs_min(payload_size, in_chunk_size); - srs_verbose("chunk payload size is %d, message_size=%d, received_size=%d, in_chunk_size=%d", - payload_size, chunk->header.payload_length, chunk->msg->size, in_chunk_size); - + srs_verbose("chunk payload size is %d, message_size=%d, received_size=%d, in_chunk_size=%d", + payload_size, chunk->header.payload_length, chunk->msg->size, in_chunk_size); + // create msg payload if not initialized if (!chunk->msg->payload) { chunk->msg->create_payload(chunk->header.payload_length); @@ -1447,17 +1447,17 @@ int SrsProtocol::read_message_payload(SrsChunkStream* chunk, SrsCommonMessage** if (chunk->header.payload_length == chunk->msg->size) { *pmsg = chunk->msg; chunk->msg = NULL; - srs_verbose("get entire RTMP message(type=%d, size=%d, time=%"PRId64", sid=%d)", - chunk->header.message_type, chunk->header.payload_length, - chunk->header.timestamp, chunk->header.stream_id); + srs_verbose("get entire RTMP message(type=%d, size=%d, time=%"PRId64", sid=%d)", + chunk->header.message_type, chunk->header.payload_length, + chunk->header.timestamp, chunk->header.stream_id); return ret; } - srs_verbose("get partial RTMP message(type=%d, size=%d, time=%"PRId64", sid=%d), partial size=%d", - chunk->header.message_type, chunk->header.payload_length, - chunk->header.timestamp, chunk->header.stream_id, - chunk->msg->size); - + srs_verbose("get partial RTMP message(type=%d, size=%d, time=%"PRId64", sid=%d), partial size=%d", + chunk->header.message_type, chunk->header.payload_length, + chunk->header.timestamp, chunk->header.stream_id, + chunk->msg->size); + return ret; } @@ -1466,7 +1466,7 @@ int SrsProtocol::on_recv_message(SrsCommonMessage* msg) int ret = ERROR_SUCCESS; srs_assert(msg != NULL); - + // try to response acknowledgement if ((ret = response_acknowledgement_message()) != ERROR_SUCCESS) { return ret; @@ -1503,7 +1503,7 @@ int SrsProtocol::on_recv_message(SrsCommonMessage* msg) if (pkt->ackowledgement_window_size > 0) { in_ack_size.window = (uint32_t)pkt->ackowledgement_window_size; // @remark, we ignore this message, for user noneed to care. - // but it's important for dev, for client/server will block if required + // but it's important for dev, for client/server will block if required // ack msg not arrived. srs_info("set ack window size to %d", pkt->ackowledgement_window_size); } else { @@ -1514,28 +1514,28 @@ int SrsProtocol::on_recv_message(SrsCommonMessage* msg) case RTMP_MSG_SetChunkSize: { SrsSetChunkSizePacket* pkt = dynamic_cast(packet); srs_assert(pkt != NULL); - + // for some server, the actual chunk size can greater than the max value(65536), // so we just warning the invalid chunk size, and actually use it is ok, // @see: https://github.com/ossrs/srs/issues/160 - if (pkt->chunk_size < SRS_CONSTS_RTMP_MIN_CHUNK_SIZE - || pkt->chunk_size > SRS_CONSTS_RTMP_MAX_CHUNK_SIZE) + if (pkt->chunk_size < SRS_CONSTS_RTMP_MIN_CHUNK_SIZE + || pkt->chunk_size > SRS_CONSTS_RTMP_MAX_CHUNK_SIZE) { srs_warn("accept chunk=%d, should in [%d, %d], please see #160", - pkt->chunk_size, SRS_CONSTS_RTMP_MIN_CHUNK_SIZE, SRS_CONSTS_RTMP_MAX_CHUNK_SIZE); + pkt->chunk_size, SRS_CONSTS_RTMP_MIN_CHUNK_SIZE, SRS_CONSTS_RTMP_MAX_CHUNK_SIZE); } - + // @see: https://github.com/ossrs/srs/issues/541 if (pkt->chunk_size < SRS_CONSTS_RTMP_MIN_CHUNK_SIZE) { ret = ERROR_RTMP_CHUNK_SIZE; srs_error("chunk size should be %d+, value=%d. ret=%d", - SRS_CONSTS_RTMP_MIN_CHUNK_SIZE, pkt->chunk_size, ret); + SRS_CONSTS_RTMP_MIN_CHUNK_SIZE, pkt->chunk_size, ret); return ret; } in_chunk_size = pkt->chunk_size; srs_info("in.chunk=%d", pkt->chunk_size); - + break; } case RTMP_MSG_UserControlMessage: { @@ -1545,7 +1545,7 @@ int SrsProtocol::on_recv_message(SrsCommonMessage* msg) if (pkt->event_type == SrcPCUCSetBufferLength) { in_buffer_length = pkt->extra_data; srs_info("buffer=%d, in.ack=%d, out.ack=%d, in.chunk=%d, out.chunk=%d", pkt->extra_data, - in_ack_size.window, out_ack_size.window, in_chunk_size, out_chunk_size); + in_ack_size.window, out_ack_size.window, in_chunk_size, out_chunk_size); } if (pkt->event_type == SrcPCUCPingRequest) { if ((ret = response_ping_message(pkt->event_data)) != ERROR_SUCCESS) { @@ -1690,7 +1690,7 @@ void SrsProtocol::print_debug_info() if (show_debug_info) { show_debug_info = false; srs_trace("protocol in.buffer=%d, in.ack=%d, out.ack=%d, in.chunk=%d, out.chunk=%d", in_buffer_length, - in_ack_size.window, out_ack_size.window, in_chunk_size, out_chunk_size); + in_ack_size.window, out_ack_size.window, in_chunk_size, out_chunk_size); } } @@ -2195,7 +2195,7 @@ int SrsRtmpClient::connect_app(string app, string tcUrl, SrsRequest* r, bool dsu if (si) { srs_trace("connected, version=%d.%d.%d.%d, ip=%s, pid=%d, id=%d, dsu=%d", - si->major, si->minor, si->revision, si->build, si->ip.c_str(), si->pid, si->cid, dsu); + si->major, si->minor, si->revision, si->build, si->ip.c_str(), si->pid, si->cid, dsu); } else { srs_trace("connected, dsu=%d", dsu); } @@ -2243,8 +2243,8 @@ int SrsRtmpClient::play(string stream, int stream_id) pkt->stream_name = stream; if ((ret = protocol->send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) { srs_error("send play stream failed. " - "stream=%s, stream_id=%d, ret=%d", - stream.c_str(), stream_id, ret); + "stream=%s, stream_id=%d, ret=%d", + stream.c_str(), stream_id, ret); return ret; } } @@ -2260,8 +2260,8 @@ int SrsRtmpClient::play(string stream, int stream_id) if ((ret = protocol->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send set buffer length failed. " - "stream=%s, stream_id=%d, bufferLength=%d, ret=%d", - stream.c_str(), stream_id, buffer_length_ms, ret); + "stream=%s, stream_id=%d, bufferLength=%d, ret=%d", + stream.c_str(), stream_id, buffer_length_ms, ret); return ret; } } @@ -2272,8 +2272,8 @@ int SrsRtmpClient::play(string stream, int stream_id) pkt->chunk_size = SRS_CONSTS_RTMP_SRS_CHUNK_SIZE; if ((ret = protocol->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send set chunk size failed. " - "stream=%s, chunk_size=%d, ret=%d", - stream.c_str(), SRS_CONSTS_RTMP_SRS_CHUNK_SIZE, ret); + "stream=%s, chunk_size=%d, ret=%d", + stream.c_str(), SRS_CONSTS_RTMP_SRS_CHUNK_SIZE, ret); return ret; } } @@ -2291,8 +2291,8 @@ int SrsRtmpClient::publish(string stream, int stream_id) pkt->chunk_size = SRS_CONSTS_RTMP_SRS_CHUNK_SIZE; if ((ret = protocol->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send set chunk size failed. " - "stream=%s, chunk_size=%d, ret=%d", - stream.c_str(), SRS_CONSTS_RTMP_SRS_CHUNK_SIZE, ret); + "stream=%s, chunk_size=%d, ret=%d", + stream.c_str(), SRS_CONSTS_RTMP_SRS_CHUNK_SIZE, ret); return ret; } } @@ -2303,8 +2303,8 @@ int SrsRtmpClient::publish(string stream, int stream_id) pkt->stream_name = stream; if ((ret = protocol->send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) { srs_error("send publish message failed. " - "stream=%s, stream_id=%d, ret=%d", - stream.c_str(), stream_id, ret); + "stream=%s, stream_id=%d, ret=%d", + stream.c_str(), stream_id, ret); return ret; } } @@ -2323,7 +2323,7 @@ int SrsRtmpClient::fmle_publish(string stream, int& stream_id) SrsFMLEStartPacket* pkt = SrsFMLEStartPacket::create_release_stream(stream); if ((ret = protocol->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send FMLE publish " - "release stream failed. stream=%s, ret=%d", stream.c_str(), ret); + "release stream failed. stream=%s, ret=%d", stream.c_str(), ret); return ret; } } @@ -2333,7 +2333,7 @@ int SrsRtmpClient::fmle_publish(string stream, int& stream_id) SrsFMLEStartPacket* pkt = SrsFMLEStartPacket::create_FC_publish(stream); if ((ret = protocol->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send FMLE publish " - "FCPublish failed. stream=%s, ret=%d", stream.c_str(), ret); + "FCPublish failed. stream=%s, ret=%d", stream.c_str(), ret); return ret; } } @@ -2344,7 +2344,7 @@ int SrsRtmpClient::fmle_publish(string stream, int& stream_id) pkt->transaction_id = 4; if ((ret = protocol->send_and_free_packet(pkt, 0)) != ERROR_SUCCESS) { srs_error("send FMLE publish " - "createStream failed. stream=%s, ret=%d", stream.c_str(), ret); + "createStream failed. stream=%s, ret=%d", stream.c_str(), ret); return ret; } } @@ -2360,7 +2360,7 @@ int SrsRtmpClient::fmle_publish(string stream, int& stream_id) SrsAutoFree(SrsCommonMessage, msg); SrsAutoFree(SrsCreateStreamResPacket, pkt); srs_info("get create stream response message"); - + stream_id = (int)pkt->stream_id; } @@ -2370,7 +2370,7 @@ int SrsRtmpClient::fmle_publish(string stream, int& stream_id) pkt->stream_name = stream; if ((ret = protocol->send_and_free_packet(pkt, stream_id)) != ERROR_SUCCESS) { srs_error("send FMLE publish publish failed. " - "stream=%s, stream_id=%d, ret=%d", stream.c_str(), stream_id, ret); + "stream=%s, stream_id=%d, ret=%d", stream.c_str(), stream_id, ret); return ret; } } @@ -2528,9 +2528,9 @@ int SrsRtmpServer::connect_app(SrsRequest* req) srs_info("get connect app message params success."); - srs_discovery_tc_url(req->tcUrl, - req->schema, req->host, req->vhost, req->app, req->port, - req->param); + srs_discovery_tc_url(req->tcUrl, + req->schema, req->host, req->vhost, req->app, req->port, + req->param); req->strip(); return ret; @@ -2568,7 +2568,7 @@ int SrsRtmpServer::set_peer_bandwidth(int bandwidth, int type) return ret; } srs_info("send set bandwidth message " - "success. bandwidth=%d, type=%d", bandwidth, type); + "success. bandwidth=%d, type=%d", bandwidth, type); return ret; } @@ -2684,7 +2684,7 @@ void SrsRtmpServer::response_connect_reject(SrsRequest* /*req*/, const char* des return; } srs_info("send connect app response rejected message success."); - + return; } @@ -2715,7 +2715,7 @@ int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string& } return ret; } - + SrsAutoFree(SrsCommonMessage, msg); SrsMessageHeader& h = msg->header; @@ -2725,7 +2725,7 @@ int SrsRtmpServer::identify_client(int stream_id, SrsRtmpConnType& type, string& if (!h.is_amf0_command() && !h.is_amf3_command()) { srs_trace("identify ignore messages except " - "AMF0/AMF3 command message. type=%#x", h.message_type); + "AMF0/AMF3 command message. type=%#x", h.message_type); continue; } @@ -2841,7 +2841,7 @@ int SrsRtmpServer::start_play(int stream_id) // |RtmpSampleAccess(false, false) if (true) { SrsSampleAccessPacket* pkt = new SrsSampleAccessPacket(); - + // allow audio/video sample. // @see: https://github.com/ossrs/srs/issues/49 pkt->audio_sample_access = true; @@ -2952,7 +2952,7 @@ int SrsRtmpServer::start_fmle_publish(int stream_id) SrsAutoFree(SrsCommonMessage, msg); SrsAutoFree(SrsFMLEStartPacket, pkt); - + fc_publish_tid = pkt->transaction_id; } // FCPublish response @@ -3139,17 +3139,17 @@ int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int } return ret; } - + SrsAutoFree(SrsCommonMessage, msg); SrsMessageHeader& h = msg->header; if (h.is_ackledgement() || h.is_set_chunk_size() || h.is_window_ackledgement_size() || h.is_user_control_message()) { continue; } - + if (!h.is_amf0_command() && !h.is_amf3_command()) { srs_trace("identify ignore messages except " - "AMF0/AMF3 command message. type=%#x", h.message_type); + "AMF0/AMF3 command message. type=%#x", h.message_type); continue; } @@ -3158,7 +3158,7 @@ int SrsRtmpServer::identify_create_stream_client(SrsCreateStreamPacket* req, int srs_error("identify decode message failed. ret=%d", ret); return ret; } - + SrsAutoFree(SrsPacket, pkt); if (dynamic_cast(pkt)) { @@ -3219,7 +3219,7 @@ int SrsRtmpServer::identify_play_client(SrsPlayPacket* req, SrsRtmpConnType& typ duration = req->duration; srs_info("identity client type=play, stream_name=%s, duration=%.2f", stream_name.c_str(), duration); - + return ret; } @@ -3241,7 +3241,7 @@ SrsConnectAppPacket::~SrsConnectAppPacket() int SrsConnectAppPacket::decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { srs_error("amf0 decode connect command_name failed. ret=%d", ret); return ret; @@ -3249,7 +3249,7 @@ int SrsConnectAppPacket::decode(SrsBuffer* stream) if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_CONNECT) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 decode connect command_name failed. " - "command_name=%s, ret=%d", command_name.c_str(), ret); + "command_name=%s, ret=%d", command_name.c_str(), ret); return ret; } @@ -3262,7 +3262,7 @@ int SrsConnectAppPacket::decode(SrsBuffer* stream) if (transaction_id != 1.0) { ret = ERROR_RTMP_AMF0_DECODE; srs_warn("amf0 decode connect transaction_id failed. " - "required=%.1f, actual=%.1f, ret=%d", 1.0, transaction_id, ret); + "required=%.1f, actual=%.1f, ret=%d", 1.0, transaction_id, ret); ret = ERROR_SUCCESS; } @@ -3378,7 +3378,7 @@ SrsConnectAppResPacket::~SrsConnectAppResPacket() int SrsConnectAppResPacket::decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { srs_error("amf0 decode connect command_name failed. ret=%d", ret); return ret; @@ -3386,7 +3386,7 @@ int SrsConnectAppResPacket::decode(SrsBuffer* stream) if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_RESULT) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 decode connect command_name failed. " - "command_name=%s, ret=%d", command_name.c_str(), ret); + "command_name=%s, ret=%d", command_name.c_str(), ret); return ret; } @@ -3399,7 +3399,7 @@ int SrsConnectAppResPacket::decode(SrsBuffer* stream) if (transaction_id != 1.0) { ret = ERROR_RTMP_AMF0_DECODE; srs_warn("amf0 decode connect transaction_id failed. " - "required=%.1f, actual=%.1f, ret=%d", 1.0, transaction_id, ret); + "required=%.1f, actual=%.1f, ret=%d", 1.0, transaction_id, ret); ret = ERROR_SUCCESS; } @@ -3445,8 +3445,8 @@ int SrsConnectAppResPacket::get_message_type() int SrsConnectAppResPacket::get_size() { - return SrsAmf0Size::str(command_name) + SrsAmf0Size::number() - + SrsAmf0Size::object(props) + SrsAmf0Size::object(info); + return SrsAmf0Size::str(command_name) + SrsAmf0Size::number() + + SrsAmf0Size::object(props) + SrsAmf0Size::object(info); } int SrsConnectAppResPacket::encode_packet(SrsBuffer* stream) @@ -3469,14 +3469,14 @@ int SrsConnectAppResPacket::encode_packet(SrsBuffer* stream) srs_error("encode props failed. ret=%d", ret); return ret; } - + srs_verbose("encode props success."); if ((ret = info->write(stream)) != ERROR_SUCCESS) { srs_error("encode info failed. ret=%d", ret); return ret; } - + srs_verbose("encode info success."); srs_info("encode connect app response packet success."); @@ -3501,7 +3501,7 @@ SrsCallPacket::~SrsCallPacket() int SrsCallPacket::decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { srs_error("amf0 decode call command_name failed. ret=%d", ret); return ret; @@ -3509,7 +3509,7 @@ int SrsCallPacket::decode(SrsBuffer* stream) if (command_name.empty()) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 decode call command_name failed. " - "command_name=%s, ret=%d", command_name.c_str(), ret); + "command_name=%s, ret=%d", command_name.c_str(), ret); return ret; } @@ -3695,7 +3695,7 @@ SrsCreateStreamPacket::~SrsCreateStreamPacket() int SrsCreateStreamPacket::decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { srs_error("amf0 decode createStream command_name failed. ret=%d", ret); return ret; @@ -3703,7 +3703,7 @@ int SrsCreateStreamPacket::decode(SrsBuffer* stream) if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_CREATE_STREAM) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 decode createStream command_name failed. " - "command_name=%s, ret=%d", command_name.c_str(), ret); + "command_name=%s, ret=%d", command_name.c_str(), ret); return ret; } @@ -3735,7 +3735,7 @@ int SrsCreateStreamPacket::get_message_type() int SrsCreateStreamPacket::get_size() { return SrsAmf0Size::str(command_name) + SrsAmf0Size::number() - + SrsAmf0Size::null(); + + SrsAmf0Size::null(); } int SrsCreateStreamPacket::encode_packet(SrsBuffer* stream) @@ -3781,7 +3781,7 @@ SrsCreateStreamResPacket::~SrsCreateStreamResPacket() int SrsCreateStreamResPacket::decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { srs_error("amf0 decode createStream command_name failed. ret=%d", ret); return ret; @@ -3789,7 +3789,7 @@ int SrsCreateStreamResPacket::decode(SrsBuffer* stream) if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_RESULT) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 decode createStream command_name failed. " - "command_name=%s, ret=%d", command_name.c_str(), ret); + "command_name=%s, ret=%d", command_name.c_str(), ret); return ret; } @@ -3826,7 +3826,7 @@ int SrsCreateStreamResPacket::get_message_type() int SrsCreateStreamResPacket::get_size() { return SrsAmf0Size::str(command_name) + SrsAmf0Size::number() - + SrsAmf0Size::null() + SrsAmf0Size::number(); + + SrsAmf0Size::null() + SrsAmf0Size::number(); } int SrsCreateStreamResPacket::encode_packet(SrsBuffer* stream) @@ -3878,23 +3878,23 @@ SrsCloseStreamPacket::~SrsCloseStreamPacket() int SrsCloseStreamPacket::decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { srs_error("amf0 decode closeStream command_name failed. ret=%d", ret); return ret; } - + if ((ret = srs_amf0_read_number(stream, transaction_id)) != ERROR_SUCCESS) { srs_error("amf0 decode closeStream transaction_id failed. ret=%d", ret); return ret; } - + if ((ret = srs_amf0_read_null(stream)) != ERROR_SUCCESS) { srs_error("amf0 decode closeStream command_object failed. ret=%d", ret); return ret; } srs_info("amf0 decode closeStream packet success"); - + return ret; } @@ -3913,19 +3913,19 @@ SrsFMLEStartPacket::~SrsFMLEStartPacket() int SrsFMLEStartPacket::decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { srs_error("amf0 decode FMLE start command_name failed. ret=%d", ret); return ret; } - if (command_name.empty() - || (command_name != RTMP_AMF0_COMMAND_RELEASE_STREAM - && command_name != RTMP_AMF0_COMMAND_FC_PUBLISH - && command_name != RTMP_AMF0_COMMAND_UNPUBLISH) - ) { + if (command_name.empty() + || (command_name != RTMP_AMF0_COMMAND_RELEASE_STREAM + && command_name != RTMP_AMF0_COMMAND_FC_PUBLISH + && command_name != RTMP_AMF0_COMMAND_UNPUBLISH) + ) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 decode FMLE start command_name failed. " - "command_name=%s, ret=%d", command_name.c_str(), ret); + "command_name=%s, ret=%d", command_name.c_str(), ret); return ret; } @@ -3962,7 +3962,7 @@ int SrsFMLEStartPacket::get_message_type() int SrsFMLEStartPacket::get_size() { return SrsAmf0Size::str(command_name) + SrsAmf0Size::number() - + SrsAmf0Size::null() + SrsAmf0Size::str(stream_name); + + SrsAmf0Size::null() + SrsAmf0Size::str(stream_name); } int SrsFMLEStartPacket::encode_packet(SrsBuffer* stream) @@ -4038,7 +4038,7 @@ SrsFMLEStartResPacket::~SrsFMLEStartResPacket() int SrsFMLEStartResPacket::decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { srs_error("amf0 decode FMLE start response command_name failed. ret=%d", ret); return ret; @@ -4046,7 +4046,7 @@ int SrsFMLEStartResPacket::decode(SrsBuffer* stream) if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_RESULT) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 decode FMLE start response command_name failed. " - "command_name=%s, ret=%d", command_name.c_str(), ret); + "command_name=%s, ret=%d", command_name.c_str(), ret); return ret; } @@ -4083,7 +4083,7 @@ int SrsFMLEStartResPacket::get_message_type() int SrsFMLEStartResPacket::get_size() { return SrsAmf0Size::str(command_name) + SrsAmf0Size::number() - + SrsAmf0Size::null() + SrsAmf0Size::undefined(); + + SrsAmf0Size::null() + SrsAmf0Size::undefined(); } int SrsFMLEStartResPacket::encode_packet(SrsBuffer* stream) @@ -4136,7 +4136,7 @@ SrsPublishPacket::~SrsPublishPacket() int SrsPublishPacket::decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { srs_error("amf0 decode publish command_name failed. ret=%d", ret); return ret; @@ -4144,7 +4144,7 @@ int SrsPublishPacket::decode(SrsBuffer* stream) if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_PUBLISH) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 decode publish command_name failed. " - "command_name=%s, ret=%d", command_name.c_str(), ret); + "command_name=%s, ret=%d", command_name.c_str(), ret); return ret; } @@ -4186,8 +4186,8 @@ int SrsPublishPacket::get_message_type() int SrsPublishPacket::get_size() { return SrsAmf0Size::str(command_name) + SrsAmf0Size::number() - + SrsAmf0Size::null() + SrsAmf0Size::str(stream_name) - + SrsAmf0Size::str(type); + + SrsAmf0Size::null() + SrsAmf0Size::str(stream_name) + + SrsAmf0Size::str(type); } int SrsPublishPacket::encode_packet(SrsBuffer* stream) @@ -4234,7 +4234,7 @@ SrsPausePacket::SrsPausePacket() command_name = RTMP_AMF0_COMMAND_PAUSE; transaction_id = 0; command_object = SrsAmf0Any::null(); - + time_ms = 0; is_pause = true; } @@ -4247,7 +4247,7 @@ SrsPausePacket::~SrsPausePacket() int SrsPausePacket::decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { srs_error("amf0 decode pause command_name failed. ret=%d", ret); return ret; @@ -4255,7 +4255,7 @@ int SrsPausePacket::decode(SrsBuffer* stream) if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_PAUSE) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 decode pause command_name failed. " - "command_name=%s, ret=%d", command_name.c_str(), ret); + "command_name=%s, ret=%d", command_name.c_str(), ret); return ret; } @@ -4289,7 +4289,7 @@ SrsPlayPacket::SrsPlayPacket() command_name = RTMP_AMF0_COMMAND_PLAY; transaction_id = 0; command_object = SrsAmf0Any::null(); - + start = -2; duration = -1; reset = true; @@ -4303,7 +4303,7 @@ SrsPlayPacket::~SrsPlayPacket() int SrsPlayPacket::decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { srs_error("amf0 decode play command_name failed. ret=%d", ret); return ret; @@ -4311,7 +4311,7 @@ int SrsPlayPacket::decode(SrsBuffer* stream) if (command_name.empty() || command_name != RTMP_AMF0_COMMAND_PLAY) { ret = ERROR_RTMP_AMF0_DECODE; srs_error("amf0 decode play command_name failed. " - "command_name=%s, ret=%d", command_name.c_str(), ret); + "command_name=%s, ret=%d", command_name.c_str(), ret); return ret; } @@ -4338,7 +4338,7 @@ int SrsPlayPacket::decode(SrsBuffer* stream) srs_error("amf0 decode play duration failed. ret=%d", ret); return ret; } - + if (stream->empty()) { return ret; } @@ -4365,7 +4365,7 @@ int SrsPlayPacket::decode(SrsBuffer* stream) return ret; } } - + srs_info("amf0 decode play packet success"); return ret; @@ -4384,7 +4384,7 @@ int SrsPlayPacket::get_message_type() int SrsPlayPacket::get_size() { int size = SrsAmf0Size::str(command_name) + SrsAmf0Size::number() - + SrsAmf0Size::null() + SrsAmf0Size::str(stream_name); + + SrsAmf0Size::null() + SrsAmf0Size::str(stream_name); if (start != -2 || duration != -1 || !reset) { size += SrsAmf0Size::number(); @@ -4479,7 +4479,7 @@ int SrsPlayResPacket::get_message_type() int SrsPlayResPacket::get_size() { return SrsAmf0Size::str(command_name) + SrsAmf0Size::number() - + SrsAmf0Size::null() + SrsAmf0Size::object(desc); + + SrsAmf0Size::null() + SrsAmf0Size::object(desc); } int SrsPlayResPacket::encode_packet(SrsBuffer* stream) @@ -4541,7 +4541,7 @@ int SrsOnBWDonePacket::get_message_type() int SrsOnBWDonePacket::get_size() { return SrsAmf0Size::str(command_name) + SrsAmf0Size::number() - + SrsAmf0Size::null(); + + SrsAmf0Size::null(); } int SrsOnBWDonePacket::encode_packet(SrsBuffer* stream) @@ -4598,7 +4598,7 @@ int SrsOnStatusCallPacket::get_message_type() int SrsOnStatusCallPacket::get_size() { return SrsAmf0Size::str(command_name) + SrsAmf0Size::number() - + SrsAmf0Size::null() + SrsAmf0Size::object(data); + + SrsAmf0Size::null() + SrsAmf0Size::object(data); } int SrsOnStatusCallPacket::encode_packet(SrsBuffer* stream) @@ -4651,17 +4651,17 @@ SrsBandwidthPacket::~SrsBandwidthPacket() int SrsBandwidthPacket::decode(SrsBuffer *stream) { int ret = ERROR_SUCCESS; - + if ((ret = srs_amf0_read_string(stream, command_name)) != ERROR_SUCCESS) { srs_error("amf0 decode bwtc command_name failed. ret=%d", ret); return ret; } - + if ((ret = srs_amf0_read_number(stream, transaction_id)) != ERROR_SUCCESS) { srs_error("amf0 decode bwtc transaction_id failed. ret=%d", ret); return ret; } - + if ((ret = srs_amf0_read_null(stream)) != ERROR_SUCCESS) { srs_error("amf0 decode bwtc command_object failed. ret=%d", ret); return ret; @@ -4675,9 +4675,9 @@ int SrsBandwidthPacket::decode(SrsBuffer *stream) return ret; } } - + srs_info("decode SrsBandwidthPacket success."); - + return ret; } @@ -4694,7 +4694,7 @@ int SrsBandwidthPacket::get_message_type() int SrsBandwidthPacket::get_size() { return SrsAmf0Size::str(command_name) + SrsAmf0Size::number() - + SrsAmf0Size::null() + SrsAmf0Size::object(data); + + SrsAmf0Size::null() + SrsAmf0Size::object(data); } int SrsBandwidthPacket::encode_packet(SrsBuffer* stream) @@ -4930,7 +4930,7 @@ int SrsSampleAccessPacket::get_message_type() int SrsSampleAccessPacket::get_size() { return SrsAmf0Size::str(command_name) - + SrsAmf0Size::boolean() + SrsAmf0Size::boolean(); + + SrsAmf0Size::boolean() + SrsAmf0Size::boolean(); } int SrsSampleAccessPacket::encode_packet(SrsBuffer* stream) @@ -4979,7 +4979,7 @@ int SrsOnMetaDataPacket::decode(SrsBuffer* stream) srs_error("decode metadata name failed. ret=%d", ret); return ret; } - + // ignore the @setDataFrame if (name == SRS_CONSTS_RTMP_SET_DATAFRAME) { if ((ret = srs_amf0_read_string(stream, name)) != ERROR_SUCCESS) { @@ -5009,7 +5009,7 @@ int SrsOnMetaDataPacket::decode(SrsBuffer* stream) if (any->is_ecma_array()) { SrsAmf0EcmaArray* arr = any->to_ecma_array(); - + // if ecma array, copy to object. for (int i = 0; i < arr->count(); i++) { metadata->set(arr->key_at(i), arr->value_at(i)->copy()); @@ -5109,7 +5109,7 @@ int SrsSetWindowAckSizePacket::encode_packet(SrsBuffer* stream) stream->write_4bytes(ackowledgement_window_size); srs_verbose("encode ack size packet " - "success. ack_size=%d", ackowledgement_window_size); + "success. ack_size=%d", ackowledgement_window_size); return ret; } @@ -5167,7 +5167,7 @@ int SrsAcknowledgementPacket::encode_packet(SrsBuffer* stream) stream->write_4bytes(sequence_number); srs_verbose("encode acknowledgement packet " - "success. sequence_number=%d", sequence_number); + "success. sequence_number=%d", sequence_number); return ret; } @@ -5268,7 +5268,7 @@ int SrsSetPeerBandwidthPacket::encode_packet(SrsBuffer* stream) stream->write_1bytes(type); srs_verbose("encode set bandwidth packet " - "success. bandwidth=%d, type=%d", bandwidth, type); + "success. bandwidth=%d, type=%d", bandwidth, type); return ret; } @@ -5322,8 +5322,8 @@ int SrsUserControlPacket::decode(SrsBuffer* stream) } srs_info("decode user control success. " - "event_type=%d, event_data=%d, extra_data=%d", - event_type, event_data, extra_data); + "event_type=%d, event_data=%d, extra_data=%d", + event_type, event_data, extra_data); return ret; } @@ -5372,7 +5372,7 @@ int SrsUserControlPacket::encode_packet(SrsBuffer* stream) } else { stream->write_4bytes(event_data); } - + // when event type is set buffer length, // write the extra buffer length. if (event_type == SrcPCUCSetBufferLength) { @@ -5381,7 +5381,7 @@ int SrsUserControlPacket::encode_packet(SrsBuffer* stream) } srs_verbose("encode user control packet success. " - "event_type=%d, event_data=%d", event_type, event_data); + "event_type=%d, event_data=%d", event_type, event_data); return ret; } diff --git a/trunk/src/protocol/srs_rtmp_stack.hpp b/trunk/src/protocol/srs_rtmp_stack.hpp index 83f2f5d20..9264bbcad 100644 --- a/trunk/src/protocol/srs_rtmp_stack.hpp +++ b/trunk/src/protocol/srs_rtmp_stack.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_PROTOCOL_RTMP_HPP #define SRS_PROTOCOL_RTMP_HPP -/* -#include -*/ - #include #include @@ -122,8 +118,8 @@ class IMergeReadHandler; #define StatusCodeUnpublishSuccess "NetStream.Unpublish.Success" /**************************************************************************** -***************************************************************************** -****************************************************************************/ + ***************************************************************************** + ****************************************************************************/ /** * the decoded message payload. @@ -180,10 +176,10 @@ protected: }; /** -* 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: @@ -198,37 +194,37 @@ private: AckWindowSize(); }; -// peer in/out + // peer in/out private: /** - * underlayer socket object, send/recv bytes. - */ + * underlayer socket object, send/recv bytes. + */ ISrsProtocolReaderWriter* skt; /** - * requests sent out, used to build the response. - * key: transactionId - * value: the request command name - */ + * requests sent out, used to build the response. + * key: transactionId + * value: the request command name + */ std::map requests; -// peer in + // peer in private: /** - * chunk stream to decode RTMP messages. - */ + * 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. - */ + * bytes buffer cache, recv from skt, provide services for stream. + */ SrsFastStream* in_buffer; /** - * input chunk size, default to 128, set by peer packet. - */ + * 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. @@ -241,92 +237,92 @@ private: // 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 + // 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. - */ + * 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. bool warned_c0c3_cache_dry; /** - * output chunk size, default to 128, set by config. - */ + * output chunk size, default to 128, set by config. + */ int32_t out_chunk_size; public: SrsProtocol(ISrsProtocolReaderWriter* 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 int 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 ms. - * if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. - */ + * set/get the recv timeout in ms. + * if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. + */ virtual void set_recv_timeout(int64_t tm); virtual int64_t get_recv_timeout(); /** - * set/get the send timeout in ms. - * if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. - */ + * set/get the send timeout in ms. + * if timeout, recv/send message return ERROR_SOCKET_TIMEOUT. + */ virtual void set_send_timeout(int64_t tm); virtual int64_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: @@ -339,46 +335,46 @@ public: virtual int 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 int 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 int 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 int 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 int 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 int send_and_free_packet(SrsPacket* packet, int stream_id); public: /** @@ -426,9 +422,9 @@ public: T* pkt = dynamic_cast(packet); if (!pkt) { - srs_info("drop message(type=%d, size=%d, time=%"PRId64", sid=%d).", - msg->header.message_type, msg->header.payload_length, - msg->header.timestamp, msg->header.stream_id); + srs_info("drop message(type=%d, size=%d, time=%"PRId64", sid=%d).", + msg->header.message_type, msg->header.payload_length, + msg->header.timestamp, msg->header.stream_id); srs_freep(msg); srs_freep(packet); continue; @@ -443,65 +439,65 @@ public: } 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 int 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 int do_iovs_send(iovec* iovs, int size); /** - * underlayer api for send and free packet. - */ + * underlayer api for send and free packet. + */ virtual int 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 int do_simple_send(SrsMessageHeader* mh, char* payload, int size); /** - * imp for decode_message - */ + * imp for decode_message + */ virtual int 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 int 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 int 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 int 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 int read_message_payload(SrsChunkStream* chunk, SrsCommonMessage** pmsg); /** - * when recv message, update the context. - */ + * when recv message, update the context. + */ virtual int on_recv_message(SrsCommonMessage* msg); /** - * when message sentout, update the context. - */ + * when message sentout, update the context. + */ virtual int on_send_packet(SrsMessageHeader* mh, SrsPacket* packet); private: /** - * auto response the ack message. - */ + * auto response the ack message. + */ virtual int response_acknowledgement_message(); /** - * auto response the ping message. - */ + * auto response the ping message. + */ virtual int response_ping_message(int32_t timestamp); private: virtual void print_debug_info(); @@ -698,7 +694,7 @@ protected: public: SrsRtmpClient(ISrsProtocolReaderWriter* skt); virtual ~SrsRtmpClient(); -// protocol methods proxy + // protocol methods proxy public: virtual void set_recv_timeout(int64_t tm); virtual void set_send_timeout(int64_t tm); @@ -999,40 +995,40 @@ private: }; /** -* 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 int 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(); @@ -1041,37 +1037,37 @@ protected: virtual int 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. - */ + * _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 int 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(); @@ -1081,40 +1077,40 @@ protected: }; /** -* 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 int 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(); @@ -1123,33 +1119,33 @@ protected: virtual int 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(); @@ -1159,35 +1155,35 @@ protected: }; /** -* 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 int 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(); @@ -1196,35 +1192,35 @@ protected: virtual int 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. - */ + * _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 int 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(); @@ -1234,104 +1230,104 @@ protected: }; /** -* 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 int decode(SrsBuffer* stream); }; /** -* FMLE start publish: ReleaseStream/PublishStream -*/ + * FMLE start publish: ReleaseStream/PublishStream + */ 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 int 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 int 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 int 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(); @@ -1341,52 +1337,52 @@ protected: }; /** -* 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 int 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(); @@ -1396,116 +1392,116 @@ protected: }; /** -* 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 int 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 int 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(); @@ -1515,37 +1511,37 @@ protected: }; /** -* 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(); @@ -1555,28 +1551,28 @@ protected: }; /** -* 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(); @@ -1586,35 +1582,35 @@ protected: }; /** -* 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(); @@ -1624,47 +1620,47 @@ protected: }; /** -* 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 int 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 int encode_packet(SrsBuffer* stream); -// help function for bandwidth packet. + // help function for bandwidth packet. public: virtual bool is_start_play(); virtual bool is_starting_play(); @@ -1693,26 +1689,26 @@ private: }; /** -* 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(); @@ -1722,32 +1718,32 @@ protected: }; /** -* 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(); @@ -1757,29 +1753,29 @@ protected: }; /** -* 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 int 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(); @@ -1789,10 +1785,10 @@ protected: }; /** -* 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: @@ -1800,10 +1796,10 @@ public: public: SrsSetWindowAckSizePacket(); virtual ~SrsSetWindowAckSizePacket(); -// decode functions for concrete packet to override. + // decode functions for concrete packet to override. public: virtual int 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(); @@ -1813,10 +1809,10 @@ protected: }; /** -* 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: @@ -1824,10 +1820,10 @@ public: public: SrsAcknowledgementPacket(); virtual ~SrsAcknowledgementPacket(); -// decode functions for concrete packet to override. + // decode functions for concrete packet to override. public: virtual int 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(); @@ -1837,25 +1833,25 @@ protected: }; /** -* 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 int 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(); @@ -1875,10 +1871,10 @@ enum SrsPeerBandwidthType }; /** -* 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: @@ -1888,7 +1884,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(); @@ -1903,74 +1899,74 @@ enum SrcPCUCEventType // 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, /** @@ -1982,30 +1978,30 @@ enum SrcPCUCEventType }; /** -* 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. @@ -2014,16 +2010,16 @@ public: */ 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 int 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.cpp b/trunk/src/protocol/srs_rtsp_stack.cpp index de46b6844..8d518d247 100644 --- a/trunk/src/protocol/srs_rtsp_stack.cpp +++ b/trunk/src/protocol/srs_rtsp_stack.cpp @@ -1,25 +1,25 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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. + */ #include @@ -48,50 +48,50 @@ string srs_generate_rtsp_status_text(int status) { static std::map _status_map; if (_status_map.empty()) { - _status_map[SRS_CONSTS_RTSP_Continue] = SRS_CONSTS_RTSP_Continue_str; - _status_map[SRS_CONSTS_RTSP_OK] = SRS_CONSTS_RTSP_OK_str; - _status_map[SRS_CONSTS_RTSP_Created] = SRS_CONSTS_RTSP_Created_str; - _status_map[SRS_CONSTS_RTSP_LowOnStorageSpace] = SRS_CONSTS_RTSP_LowOnStorageSpace_str; - _status_map[SRS_CONSTS_RTSP_MultipleChoices] = SRS_CONSTS_RTSP_MultipleChoices_str; - _status_map[SRS_CONSTS_RTSP_MovedPermanently] = SRS_CONSTS_RTSP_MovedPermanently_str; - _status_map[SRS_CONSTS_RTSP_MovedTemporarily] = SRS_CONSTS_RTSP_MovedTemporarily_str; - _status_map[SRS_CONSTS_RTSP_SeeOther] = SRS_CONSTS_RTSP_SeeOther_str; - _status_map[SRS_CONSTS_RTSP_NotModified] = SRS_CONSTS_RTSP_NotModified_str; - _status_map[SRS_CONSTS_RTSP_UseProxy] = SRS_CONSTS_RTSP_UseProxy_str; - _status_map[SRS_CONSTS_RTSP_BadRequest] = SRS_CONSTS_RTSP_BadRequest_str; - _status_map[SRS_CONSTS_RTSP_Unauthorized] = SRS_CONSTS_RTSP_Unauthorized_str; - _status_map[SRS_CONSTS_RTSP_PaymentRequired] = SRS_CONSTS_RTSP_PaymentRequired_str; - _status_map[SRS_CONSTS_RTSP_Forbidden] = SRS_CONSTS_RTSP_Forbidden_str; - _status_map[SRS_CONSTS_RTSP_NotFound] = SRS_CONSTS_RTSP_NotFound_str; - _status_map[SRS_CONSTS_RTSP_MethodNotAllowed] = SRS_CONSTS_RTSP_MethodNotAllowed_str; - _status_map[SRS_CONSTS_RTSP_NotAcceptable] = SRS_CONSTS_RTSP_NotAcceptable_str; - _status_map[SRS_CONSTS_RTSP_ProxyAuthenticationRequired] = SRS_CONSTS_RTSP_ProxyAuthenticationRequired_str; - _status_map[SRS_CONSTS_RTSP_RequestTimeout] = SRS_CONSTS_RTSP_RequestTimeout_str; - _status_map[SRS_CONSTS_RTSP_Gone] = SRS_CONSTS_RTSP_Gone_str; - _status_map[SRS_CONSTS_RTSP_LengthRequired] = SRS_CONSTS_RTSP_LengthRequired_str; - _status_map[SRS_CONSTS_RTSP_PreconditionFailed] = SRS_CONSTS_RTSP_PreconditionFailed_str; - _status_map[SRS_CONSTS_RTSP_RequestEntityTooLarge] = SRS_CONSTS_RTSP_RequestEntityTooLarge_str; - _status_map[SRS_CONSTS_RTSP_RequestURITooLarge] = SRS_CONSTS_RTSP_RequestURITooLarge_str; - _status_map[SRS_CONSTS_RTSP_UnsupportedMediaType] = SRS_CONSTS_RTSP_UnsupportedMediaType_str; - _status_map[SRS_CONSTS_RTSP_ParameterNotUnderstood] = SRS_CONSTS_RTSP_ParameterNotUnderstood_str; - _status_map[SRS_CONSTS_RTSP_ConferenceNotFound] = SRS_CONSTS_RTSP_ConferenceNotFound_str; - _status_map[SRS_CONSTS_RTSP_NotEnoughBandwidth] = SRS_CONSTS_RTSP_NotEnoughBandwidth_str; - _status_map[SRS_CONSTS_RTSP_SessionNotFound] = SRS_CONSTS_RTSP_SessionNotFound_str; - _status_map[SRS_CONSTS_RTSP_MethodNotValidInThisState] = SRS_CONSTS_RTSP_MethodNotValidInThisState_str; - _status_map[SRS_CONSTS_RTSP_HeaderFieldNotValidForResource] = SRS_CONSTS_RTSP_HeaderFieldNotValidForResource_str; - _status_map[SRS_CONSTS_RTSP_InvalidRange] = SRS_CONSTS_RTSP_InvalidRange_str; - _status_map[SRS_CONSTS_RTSP_ParameterIsReadOnly] = SRS_CONSTS_RTSP_ParameterIsReadOnly_str; - _status_map[SRS_CONSTS_RTSP_AggregateOperationNotAllowed] = SRS_CONSTS_RTSP_AggregateOperationNotAllowed_str; - _status_map[SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed] = SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed_str; - _status_map[SRS_CONSTS_RTSP_UnsupportedTransport] = SRS_CONSTS_RTSP_UnsupportedTransport_str; - _status_map[SRS_CONSTS_RTSP_DestinationUnreachable] = SRS_CONSTS_RTSP_DestinationUnreachable_str; - _status_map[SRS_CONSTS_RTSP_InternalServerError] = SRS_CONSTS_RTSP_InternalServerError_str; - _status_map[SRS_CONSTS_RTSP_NotImplemented] = SRS_CONSTS_RTSP_NotImplemented_str; - _status_map[SRS_CONSTS_RTSP_BadGateway] = SRS_CONSTS_RTSP_BadGateway_str; - _status_map[SRS_CONSTS_RTSP_ServiceUnavailable] = SRS_CONSTS_RTSP_ServiceUnavailable_str; - _status_map[SRS_CONSTS_RTSP_GatewayTimeout] = SRS_CONSTS_RTSP_GatewayTimeout_str; - _status_map[SRS_CONSTS_RTSP_RTSPVersionNotSupported] = SRS_CONSTS_RTSP_RTSPVersionNotSupported_str; - _status_map[SRS_CONSTS_RTSP_OptionNotSupported] = SRS_CONSTS_RTSP_OptionNotSupported_str; + _status_map[SRS_CONSTS_RTSP_Continue] = SRS_CONSTS_RTSP_Continue_str; + _status_map[SRS_CONSTS_RTSP_OK] = SRS_CONSTS_RTSP_OK_str; + _status_map[SRS_CONSTS_RTSP_Created] = SRS_CONSTS_RTSP_Created_str; + _status_map[SRS_CONSTS_RTSP_LowOnStorageSpace] = SRS_CONSTS_RTSP_LowOnStorageSpace_str; + _status_map[SRS_CONSTS_RTSP_MultipleChoices] = SRS_CONSTS_RTSP_MultipleChoices_str; + _status_map[SRS_CONSTS_RTSP_MovedPermanently] = SRS_CONSTS_RTSP_MovedPermanently_str; + _status_map[SRS_CONSTS_RTSP_MovedTemporarily] = SRS_CONSTS_RTSP_MovedTemporarily_str; + _status_map[SRS_CONSTS_RTSP_SeeOther] = SRS_CONSTS_RTSP_SeeOther_str; + _status_map[SRS_CONSTS_RTSP_NotModified] = SRS_CONSTS_RTSP_NotModified_str; + _status_map[SRS_CONSTS_RTSP_UseProxy] = SRS_CONSTS_RTSP_UseProxy_str; + _status_map[SRS_CONSTS_RTSP_BadRequest] = SRS_CONSTS_RTSP_BadRequest_str; + _status_map[SRS_CONSTS_RTSP_Unauthorized] = SRS_CONSTS_RTSP_Unauthorized_str; + _status_map[SRS_CONSTS_RTSP_PaymentRequired] = SRS_CONSTS_RTSP_PaymentRequired_str; + _status_map[SRS_CONSTS_RTSP_Forbidden] = SRS_CONSTS_RTSP_Forbidden_str; + _status_map[SRS_CONSTS_RTSP_NotFound] = SRS_CONSTS_RTSP_NotFound_str; + _status_map[SRS_CONSTS_RTSP_MethodNotAllowed] = SRS_CONSTS_RTSP_MethodNotAllowed_str; + _status_map[SRS_CONSTS_RTSP_NotAcceptable] = SRS_CONSTS_RTSP_NotAcceptable_str; + _status_map[SRS_CONSTS_RTSP_ProxyAuthenticationRequired] = SRS_CONSTS_RTSP_ProxyAuthenticationRequired_str; + _status_map[SRS_CONSTS_RTSP_RequestTimeout] = SRS_CONSTS_RTSP_RequestTimeout_str; + _status_map[SRS_CONSTS_RTSP_Gone] = SRS_CONSTS_RTSP_Gone_str; + _status_map[SRS_CONSTS_RTSP_LengthRequired] = SRS_CONSTS_RTSP_LengthRequired_str; + _status_map[SRS_CONSTS_RTSP_PreconditionFailed] = SRS_CONSTS_RTSP_PreconditionFailed_str; + _status_map[SRS_CONSTS_RTSP_RequestEntityTooLarge] = SRS_CONSTS_RTSP_RequestEntityTooLarge_str; + _status_map[SRS_CONSTS_RTSP_RequestURITooLarge] = SRS_CONSTS_RTSP_RequestURITooLarge_str; + _status_map[SRS_CONSTS_RTSP_UnsupportedMediaType] = SRS_CONSTS_RTSP_UnsupportedMediaType_str; + _status_map[SRS_CONSTS_RTSP_ParameterNotUnderstood] = SRS_CONSTS_RTSP_ParameterNotUnderstood_str; + _status_map[SRS_CONSTS_RTSP_ConferenceNotFound] = SRS_CONSTS_RTSP_ConferenceNotFound_str; + _status_map[SRS_CONSTS_RTSP_NotEnoughBandwidth] = SRS_CONSTS_RTSP_NotEnoughBandwidth_str; + _status_map[SRS_CONSTS_RTSP_SessionNotFound] = SRS_CONSTS_RTSP_SessionNotFound_str; + _status_map[SRS_CONSTS_RTSP_MethodNotValidInThisState] = SRS_CONSTS_RTSP_MethodNotValidInThisState_str; + _status_map[SRS_CONSTS_RTSP_HeaderFieldNotValidForResource] = SRS_CONSTS_RTSP_HeaderFieldNotValidForResource_str; + _status_map[SRS_CONSTS_RTSP_InvalidRange] = SRS_CONSTS_RTSP_InvalidRange_str; + _status_map[SRS_CONSTS_RTSP_ParameterIsReadOnly] = SRS_CONSTS_RTSP_ParameterIsReadOnly_str; + _status_map[SRS_CONSTS_RTSP_AggregateOperationNotAllowed] = SRS_CONSTS_RTSP_AggregateOperationNotAllowed_str; + _status_map[SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed] = SRS_CONSTS_RTSP_OnlyAggregateOperationAllowed_str; + _status_map[SRS_CONSTS_RTSP_UnsupportedTransport] = SRS_CONSTS_RTSP_UnsupportedTransport_str; + _status_map[SRS_CONSTS_RTSP_DestinationUnreachable] = SRS_CONSTS_RTSP_DestinationUnreachable_str; + _status_map[SRS_CONSTS_RTSP_InternalServerError] = SRS_CONSTS_RTSP_InternalServerError_str; + _status_map[SRS_CONSTS_RTSP_NotImplemented] = SRS_CONSTS_RTSP_NotImplemented_str; + _status_map[SRS_CONSTS_RTSP_BadGateway] = SRS_CONSTS_RTSP_BadGateway_str; + _status_map[SRS_CONSTS_RTSP_ServiceUnavailable] = SRS_CONSTS_RTSP_ServiceUnavailable_str; + _status_map[SRS_CONSTS_RTSP_GatewayTimeout] = SRS_CONSTS_RTSP_GatewayTimeout_str; + _status_map[SRS_CONSTS_RTSP_RTSPVersionNotSupported] = SRS_CONSTS_RTSP_RTSPVersionNotSupported_str; + _status_map[SRS_CONSTS_RTSP_OptionNotSupported] = SRS_CONSTS_RTSP_OptionNotSupported_str; } std::string status_text; @@ -104,7 +104,7 @@ string srs_generate_rtsp_status_text(int status) return status_text; } -std::string srs_generate_rtsp_method_str(SrsRtspMethod method) +std::string srs_generate_rtsp_method_str(SrsRtspMethod method) { switch (method) { case SrsRtspMethodDescribe: return SRS_METHOD_DESCRIBE; @@ -129,12 +129,12 @@ SrsRtpPacket::SrsRtpPacket() extension = 0; csrc_count = 0; marker = 1; - + payload_type = 0; sequence_number = 0; timestamp = 0; ssrc = 0; - + payload = new SrsSimpleStream(); audio = new SrsAudioFrame(); chunked = false; @@ -158,7 +158,7 @@ void SrsRtpPacket::copy(SrsRtpPacket* src) sequence_number = src->sequence_number; timestamp = src->timestamp; ssrc = src->ssrc; - + chunked = src->chunked; completed = src->completed; @@ -169,7 +169,7 @@ void SrsRtpPacket::copy(SrsRtpPacket* src) void SrsRtpPacket::reap(SrsRtpPacket* src) { copy(src); - + srs_freep(payload); payload = src->payload; src->payload = NULL; @@ -182,112 +182,112 @@ void SrsRtpPacket::reap(SrsRtpPacket* src) int SrsRtpPacket::decode(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + // 12bytes header if (!stream->require(12)) { ret = ERROR_RTP_HEADER_CORRUPT; srs_error("rtsp: rtp header corrupt. ret=%d", ret); return ret; } - + int8_t vv = stream->read_1bytes(); version = (vv >> 6) & 0x03; padding = (vv >> 5) & 0x01; extension = (vv >> 4) & 0x01; csrc_count = vv & 0x0f; - + int8_t mv = stream->read_1bytes(); marker = (mv >> 7) & 0x01; payload_type = mv & 0x7f; - + sequence_number = stream->read_2bytes(); timestamp = stream->read_4bytes(); ssrc = stream->read_4bytes(); - + // TODO: FIXME: check sequence number. - + // video codec. if (payload_type == 96) { return decode_96(stream); } else if (payload_type == 97) { return decode_97(stream); } - + return ret; } int SrsRtpPacket::decode_97(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + // atleast 2bytes content. if (!stream->require(2)) { ret = ERROR_RTP_TYPE97_CORRUPT; srs_error("rtsp: rtp type97 corrupt. ret=%d", ret); return ret; } - + int8_t hasv = stream->read_1bytes(); int8_t lasv = stream->read_1bytes(); uint16_t au_size = ((hasv << 5) & 0xE0) | ((lasv >> 3) & 0x1f); - + if (!stream->require(au_size)) { ret = ERROR_RTP_TYPE97_CORRUPT; srs_error("rtsp: rtp type97 au_size corrupt. ret=%d", ret); return ret; } - + int required_size = 0; - + // append left bytes to payload. payload->append( - stream->data() + stream->pos() + au_size, - stream->size() - stream->pos() - au_size - ); + stream->data() + stream->pos() + au_size, + stream->size() - stream->pos() - au_size + ); char* p = payload->bytes(); - + for (int i = 0; i < au_size; i += 2) { hasv = stream->read_1bytes(); lasv = stream->read_1bytes(); - + uint16_t sample_size = ((hasv << 5) & 0xE0) | ((lasv >> 3) & 0x1f); // TODO: FIXME: finger out how to parse the size of sample. if (sample_size < 0x100 && stream->require(required_size + sample_size + 0x100)) { sample_size = sample_size | 0x100; } - + char* sample = p + required_size; required_size += sample_size; - + if (!stream->require(required_size)) { ret = ERROR_RTP_TYPE97_CORRUPT; srs_error("rtsp: rtp type97 samples corrupt. ret=%d", ret); return ret; } - + if ((ret = audio->add_sample(sample, sample_size)) != ERROR_SUCCESS) { srs_error("rtsp: rtp type97 add sample failed. ret=%d", ret); return ret; } } - + // parsed ok. completed = true; - + return ret; } int SrsRtpPacket::decode_96(SrsBuffer* stream) { int ret = ERROR_SUCCESS; - + // atleast 2bytes content. if (!stream->require(2)) { ret = ERROR_RTP_TYPE96_CORRUPT; srs_error("rtsp: rtp type96 corrupt. ret=%d", ret); return ret; } - + // frame type // 0... .... reserverd // .11. .... NALU[0]&0x60 @@ -296,7 +296,7 @@ int SrsRtpPacket::decode_96(SrsBuffer* stream) int8_t ftv = stream->read_1bytes(); int8_t nalu_0x60 = ftv & 0x60; int8_t fu_indicator = ftv & 0x1c; - + // nri, whatever // 10.. .... first chunk. // 00.. .... continous chunk. @@ -307,12 +307,12 @@ int SrsRtpPacket::decode_96(SrsBuffer* stream) bool last_chunk = (nriv & 0xC0) == 0x40; bool contious_chunk = (nriv & 0xC0) == 0x00; int8_t nalu_0x1f = nriv & 0x1f; - + // chunked, generate the first byte NALU. if (fu_indicator == 0x1c && (first_chunk || last_chunk || contious_chunk)) { chunked = true; completed = last_chunk; - + // generate and append the first byte NALU. if (first_chunk) { int8_t nalu_byte0 = nalu_0x60 | nalu_0x1f; @@ -322,12 +322,12 @@ int SrsRtpPacket::decode_96(SrsBuffer* stream) payload->append(stream->data() + stream->pos(), stream->size() - stream->pos()); return ret; } - + // no chunked, append to payload. stream->skip(-2); payload->append(stream->data() + stream->pos(), stream->size() - stream->pos()); completed = true; - + return ret; } @@ -343,18 +343,18 @@ SrsRtspSdp::~SrsRtspSdp() int SrsRtspSdp::parse(string token) { int ret = ERROR_SUCCESS; - + if (token.empty()) { srs_info("rtsp: ignore empty token."); return ret; } size_t pos = string::npos; - + char* start = (char*)token.data(); char* end = start + (int)token.length(); char* p = start; - + // key, first 2bytes. // v=0 // o=- 0 0 IN IP4 127.0.0.1 @@ -374,13 +374,13 @@ int SrsRtspSdp::parse(string token) // a=control:streamid=1 char key = p[0]; p += 2; - + // left bytes as attr string. std::string attr_str; if (end - p) { attr_str.append(p, end - p); } - + // parse the attributes from left bytes. std::vector attrs; while (p < end) { @@ -395,7 +395,7 @@ int SrsRtspSdp::parse(string token) } p++; } - + // parse the first attr as desc, update the first elem for desc. // for example, the value can be "tool", "AS", "rtpmap", "fmtp", "control" std::string desc_key; @@ -410,7 +410,7 @@ int SrsRtspSdp::parse(string token) desc_key = attr; } } - + // interpret the attribute according by key. switch (key) { case 'v': version = attr_str; break; @@ -492,7 +492,7 @@ int SrsRtspSdp::parse(string token) case 't': default: break; } - + return ret; } @@ -502,7 +502,7 @@ int SrsRtspSdp::parse_fmtp_attribute(string attr) size_t pos = string::npos; std::string token = attr; - + while (!token.empty()) { std::string item = token; if ((pos = item.find(";")) != string::npos) { @@ -511,13 +511,13 @@ int SrsRtspSdp::parse_fmtp_attribute(string attr) } else { token = ""; } - + std::string item_key = item, item_value; if ((pos = item.find("=")) != string::npos) { item_key = item.substr(0, pos); item_value = item.substr(pos + 1); } - + if (state == SrsRtspSdpStateVideo) { if (item_key == "packetization-mode") { video_packetization_mode = item_value; @@ -548,7 +548,7 @@ int SrsRtspSdp::parse_fmtp_attribute(string attr) srs_error("rtsp: audio config failed. ret=%d", ret); return ret; } - + char* tmp_sh = new char[item_value.length()]; SrsAutoFreeA(char, tmp_sh); int nb_tmp_sh = ff_hex_to_data((uint8_t*)tmp_sh, item_value.c_str()); @@ -557,7 +557,7 @@ int SrsRtspSdp::parse_fmtp_attribute(string attr) } } } - + return ret; } @@ -567,7 +567,7 @@ int SrsRtspSdp::parse_control_attribute(string attr) size_t pos = string::npos; std::string token = attr; - + while (!token.empty()) { std::string item = token; if ((pos = item.find(";")) != string::npos) { @@ -576,13 +576,13 @@ int SrsRtspSdp::parse_control_attribute(string attr) } else { token = ""; } - + std::string item_key = item, item_value; if ((pos = item.find("=")) != string::npos) { item_key = item.substr(0, pos); item_value = item.substr(pos + 1); } - + if (state == SrsRtspSdpStateVideo) { if (item_key == "streamid") { video_stream_id = item_value; @@ -593,7 +593,7 @@ int SrsRtspSdp::parse_control_attribute(string attr) } } } - + return ret; } @@ -602,16 +602,16 @@ string SrsRtspSdp::base64_decode(string value) if (value.empty()) { return ""; } - + int nb_output = (int)(value.length() * 2); uint8_t* output = new uint8_t[nb_output]; SrsAutoFreeA(uint8_t, output); - + int ret = srs_av_base64_decode(output, (char*)value.c_str(), nb_output); if (ret <= 0) { return ""; } - + std::string plaintext; plaintext.append((char*)output, ret); return plaintext; @@ -633,7 +633,7 @@ int SrsRtspTransport::parse(string attr) size_t pos = string::npos; std::string token = attr; - + while (!token.empty()) { std::string item = token; if ((pos = item.find(";")) != string::npos) { @@ -642,13 +642,13 @@ int SrsRtspTransport::parse(string attr) } else { token = ""; } - + std::string item_key = item, item_value; if ((pos = item.find("=")) != string::npos) { item_key = item.substr(0, pos); item_value = item.substr(pos + 1); } - + if (transport.empty()) { transport = item_key; if ((pos = transport.find("/")) != string::npos) { @@ -660,7 +660,7 @@ int SrsRtspTransport::parse(string attr) profile = profile.substr(0, pos); } } - + if (item_key == "unicast" || item_key == "multicast") { cast_type = item_key; } else if (item_key == "mode") { @@ -676,7 +676,7 @@ int SrsRtspTransport::parse(string attr) client_port_max = ::atoi(eport.c_str()); } } - + return ret; } @@ -728,33 +728,33 @@ SrsRtspResponse::~SrsRtspResponse() int SrsRtspResponse::encode(stringstream& ss) { int ret = ERROR_SUCCESS; - + // status line - ss << SRS_RTSP_VERSION << SRS_RTSP_SP - << status << SRS_RTSP_SP - << srs_generate_rtsp_status_text(status) << SRS_RTSP_CRLF; - + ss << SRS_RTSP_VERSION << SRS_RTSP_SP + << status << SRS_RTSP_SP + << srs_generate_rtsp_status_text(status) << SRS_RTSP_CRLF; + // cseq ss << SRS_RTSP_TOKEN_CSEQ << ":" << SRS_RTSP_SP << seq << SRS_RTSP_CRLF; - + // others. ss << "Cache-Control: no-store" << SRS_RTSP_CRLF - << "Pragma: no-cache" << SRS_RTSP_CRLF - << "Server: " << RTMP_SIG_SRS_SERVER << SRS_RTSP_CRLF; - + << "Pragma: no-cache" << SRS_RTSP_CRLF + << "Server: " << RTMP_SIG_SRS_SERVER << SRS_RTSP_CRLF; + // session if specified. if (!session.empty()) { ss << SRS_RTSP_TOKEN_SESSION << ":" << session << SRS_RTSP_CRLF; } - + if ((ret = encode_header(ss)) != ERROR_SUCCESS) { srs_error("rtsp: encode header failed. ret=%d", ret); return ret; }; - + // header EOF. ss << SRS_RTSP_CRLF; - + return ret; } @@ -765,7 +765,7 @@ int SrsRtspResponse::encode_header(std::stringstream& ss) SrsRtspOptionsResponse::SrsRtspOptionsResponse(int cseq) : SrsRtspResponse(cseq) { - methods = (SrsRtspMethod)(SrsRtspMethodDescribe | SrsRtspMethodOptions + methods = (SrsRtspMethod)(SrsRtspMethodDescribe | SrsRtspMethodOptions | SrsRtspMethodPause | SrsRtspMethodPlay | SrsRtspMethodSetup | SrsRtspMethodTeardown | SrsRtspMethodAnnounce | SrsRtspMethodRecord); } @@ -789,9 +789,9 @@ int SrsRtspOptionsResponse::encode_header(stringstream& ss) SrsRtspMethodSetParameter, SrsRtspMethodTeardown, }; - + ss << SRS_RTSP_TOKEN_PUBLIC << ":" << SRS_RTSP_SP; - + bool appended = false; int nb_methods = (int)(sizeof(rtsp_methods) / sizeof(SrsRtspMethod)); for (int i = 0; i < nb_methods; i++) { @@ -799,7 +799,7 @@ int SrsRtspOptionsResponse::encode_header(stringstream& ss) if (((int)methods & (int)method) != (int)method) { continue; } - + if (appended) { ss << ", "; } @@ -807,7 +807,7 @@ int SrsRtspOptionsResponse::encode_header(stringstream& ss) appended = true; } ss << SRS_RTSP_CRLF; - + return ERROR_SUCCESS; } @@ -824,10 +824,10 @@ SrsRtspSetupResponse::~SrsRtspSetupResponse() int SrsRtspSetupResponse::encode_header(stringstream& ss) { ss << SRS_RTSP_TOKEN_SESSION << ":" << SRS_RTSP_SP << session << SRS_RTSP_CRLF; - ss << SRS_RTSP_TOKEN_TRANSPORT << ":" << SRS_RTSP_SP - << "RTP/AVP;unicast;client_port=" << client_port_min << "-" << client_port_max << ";" - << "server_port=" << local_port_min << "-" << local_port_max - << SRS_RTSP_CRLF; + ss << SRS_RTSP_TOKEN_TRANSPORT << ":" << SRS_RTSP_SP + << "RTP/AVP;unicast;client_port=" << client_port_min << "-" << client_port_max << ";" + << "server_port=" << local_port_min << "-" << local_port_max + << SRS_RTSP_CRLF; return ERROR_SUCCESS; } @@ -845,29 +845,29 @@ SrsRtspStack::~SrsRtspStack() int SrsRtspStack::recv_message(SrsRtspRequest** preq) { int ret = ERROR_SUCCESS; - + SrsRtspRequest* req = new SrsRtspRequest(); if ((ret = do_recv_message(req)) != ERROR_SUCCESS) { srs_freep(req); return ret; } - + *preq = req; - + return ret; } int SrsRtspStack::send_message(SrsRtspResponse* res) { int ret = ERROR_SUCCESS; - + std::stringstream ss; // encode the message to string. res->encode(ss); - + std::string str = ss.str(); srs_assert(!str.empty()); - + if ((ret = skt->write((char*)str.c_str(), (int)str.length(), NULL)) != ERROR_SUCCESS) { if (!srs_is_client_gracefully_close(ret)) { srs_error("rtsp: send response failed. ret=%d", ret); @@ -875,14 +875,14 @@ int SrsRtspStack::send_message(SrsRtspResponse* res) return ret; } srs_info("rtsp: send response ok"); - + return ret; } int SrsRtspStack::do_recv_message(SrsRtspRequest* req) { int ret = ERROR_SUCCESS; - + // parse request line. if ((ret = recv_token_normal(req->method)) != ERROR_SUCCESS) { if (!srs_is_client_gracefully_close(ret)) { @@ -890,21 +890,21 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req) } return ret; } - + if ((ret = recv_token_normal(req->uri)) != ERROR_SUCCESS) { if (!srs_is_client_gracefully_close(ret)) { srs_error("rtsp: parse uri failed. ret=%d", ret); } return ret; } - + if ((ret = recv_token_eof(req->version)) != ERROR_SUCCESS) { if (!srs_is_client_gracefully_close(ret)) { srs_error("rtsp: parse version failed. ret=%d", ret); } return ret; } - + // parse headers. for (;;) { // parse the header name @@ -920,7 +920,7 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req) } return ret; } - + // parse the header value according by header name if (token == SRS_RTSP_TOKEN_CSEQ) { std::string seq; @@ -986,7 +986,7 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req) } } } - + // for setup, parse the stream id from uri. if (req->is_setup()) { size_t pos = string::npos; @@ -997,14 +997,14 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req) req->stream_id = ::atoi(stream_id.c_str()); srs_info("rtsp: setup stream id=%d", req->stream_id); } - + // parse rdp body. long consumed = 0; while (consumed < req->content_length) { if (!req->sdp) { req->sdp = new SrsRtspSdp(); } - + int nb_token = 0; std::string token; if ((ret = recv_token_util_eof(token, &nb_token)) != ERROR_SUCCESS) { @@ -1014,7 +1014,7 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req) return ret; } consumed += nb_token; - + if ((ret = req->sdp->parse(token)) != ERROR_SUCCESS) { srs_error("rtsp: sdp parse token failed, token=%s. ret=%d", token.c_str(), ret); return ret; @@ -1022,16 +1022,16 @@ int SrsRtspStack::do_recv_message(SrsRtspRequest* req) srs_info("rtsp: %s", token.c_str()); } srs_info("rtsp: sdp parsed, size=%d", consumed); - + return ret; } int SrsRtspStack::recv_token_normal(std::string& token) { int ret = ERROR_SUCCESS; - + SrsRtspTokenState state; - + if ((ret = recv_token(token, state)) != ERROR_SUCCESS) { if (ret == ERROR_RTSP_REQUEST_HEADER_EOF) { return ret; @@ -1041,22 +1041,22 @@ int SrsRtspStack::recv_token_normal(std::string& token) } return ret; } - + if (state != SrsRtspTokenStateNormal) { ret = ERROR_RTSP_TOKEN_NOT_NORMAL; srs_error("rtsp: parse normal token failed, state=%d. ret=%d", state, ret); return ret; } - + return ret; } int SrsRtspStack::recv_token_eof(std::string& token) { int ret = ERROR_SUCCESS; - + SrsRtspTokenState state; - + if ((ret = recv_token(token, state)) != ERROR_SUCCESS) { if (ret == ERROR_RTSP_REQUEST_HEADER_EOF) { return ret; @@ -1066,22 +1066,22 @@ int SrsRtspStack::recv_token_eof(std::string& token) } return ret; } - + if (state != SrsRtspTokenStateEOF) { ret = ERROR_RTSP_TOKEN_NOT_NORMAL; srs_error("rtsp: parse eof token failed, state=%d. ret=%d", state, ret); return ret; } - + return ret; } int SrsRtspStack::recv_token_util_eof(std::string& token, int* pconsumed) { int ret = ERROR_SUCCESS; - + SrsRtspTokenState state; - + // use 0x00 as ignore the normal token flag. if ((ret = recv_token(token, state, 0x00, pconsumed)) != ERROR_SUCCESS) { if (ret == ERROR_RTSP_REQUEST_HEADER_EOF) { @@ -1092,32 +1092,32 @@ int SrsRtspStack::recv_token_util_eof(std::string& token, int* pconsumed) } return ret; } - + if (state != SrsRtspTokenStateEOF) { ret = ERROR_RTSP_TOKEN_NOT_NORMAL; srs_error("rtsp: parse eof token failed, state=%d. ret=%d", state, ret); return ret; } - + return ret; } int SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch, int* pconsumed) { int ret = ERROR_SUCCESS; - + // whatever, default to error state. state = SrsRtspTokenStateError; - + // when buffer is empty, append bytes first. bool append_bytes = buf->length() == 0; - + // parse util token. for (;;) { // append bytes if required. if (append_bytes) { append_bytes = false; - + char buffer[SRS_RTSP_BUFFER]; ssize_t nb_read = 0; if ((ret = skt->read(buffer, SRS_RTSP_BUFFER, &nb_read)) != ERROR_SUCCESS) { @@ -1127,19 +1127,19 @@ int SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char return ret; } srs_info("rtsp: io read %d bytes", nb_read); - + buf->append(buffer, nb_read); } - + // parse one by one. char* start = buf->bytes(); char* end = start + buf->length(); char* p = start; - + // find util SP/CR/LF, max 2 EOF, to finger out the EOF of message. for (; p < end && p[0] != normal_ch && p[0] != SRS_RTSP_CR && p[0] != SRS_RTSP_LF; p++) { } - + // matched. if (p < end) { // finger out the state. @@ -1160,11 +1160,11 @@ int SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char } else { ret = ERROR_RTSP_REQUEST_HEADER_EOF; } - + // ignore SP/CR/LF for (int i = 0; i < 2 && p < end && (p[0] == normal_ch || p[0] == SRS_RTSP_CR || p[0] == SRS_RTSP_LF); p++, i++) { } - + // consume the token bytes. srs_assert(p - start); buf->erase(p - start); @@ -1173,11 +1173,11 @@ int SrsRtspStack::recv_token(std::string& token, SrsRtspTokenState& state, char } break; } - + // append more and parse again. append_bytes = true; } - + return ret; } diff --git a/trunk/src/protocol/srs_rtsp_stack.hpp b/trunk/src/protocol/srs_rtsp_stack.hpp index ef27a51af..59faab5a8 100644 --- a/trunk/src/protocol/srs_rtsp_stack.hpp +++ b/trunk/src/protocol/srs_rtsp_stack.hpp @@ -1,33 +1,29 @@ -/* -The MIT License (MIT) - -Copyright (c) 2013-2017 SRS(ossrs) - -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 MIT License (MIT) + * + * Copyright (c) 2013-2017 SRS(ossrs) + * + * 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 SRS_PROTOCOL_RTSP_HPP #define SRS_PROTOCOL_RTSP_HPP -/* -#include -*/ - #include #if !defined(SRS_EXPORT_LIBRTMP) @@ -85,37 +81,37 @@ class ISrsProtocolReaderWriter; #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, @@ -132,161 +128,161 @@ enum SrsRtspMethod }; /** -* 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 eld identi es the version of RTP. The version de ned by this speci cation is two (2). - * (The value 1 is used by the rst draft version of RTP and the value 0 is used by the protocol - * initially implemented in the \vat" audio tool.) - */ + * 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 xed block sizes or for carrying several RTP packets in a - * lower-layer protocol data unit. - */ + * 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 xed header must be followed by exactly one header extension, - * with a format de ned in Section 5.3.1. - */ + * 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 identi ers that follow the xed header. - */ + * 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 de ned by a pro le. It is intended to allow signi cant - * events such as frame boundaries to be marked in the packet stream. A pro le may de ne - * additional marker bits or specify that there is no marker bit by changing the number of bits - * in the payload type eld (see Section 5.3). - */ + * 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 eld identi es the format of the RTP payload and determines its interpretation by the - * application. A pro le may specify a default static mapping of payload type codes to payload - * formats. Additional payload type codes may be de ned dynamically through non-RTP means - * (see Section 3). A set of default mappings for audio and video is speci ed in the companion - * RFC 3551 [1]. An RTP source may change the payload type during a session, but this eld - * 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. - */ + * 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]. - */ + * 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 rst 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 speci ed statically in the pro le - * or payload format speci cation that de nes the format, or may be speci ed dynamically for - * payload formats de ned 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 xed-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 di erent media streams may advance at di erent rates and usually - * have independent, random o sets. Therefore, although these timestamps are sucient to - * reconstruct the timing of a single stream, directly comparing RTP timestamps from di erent - * media is not e ective 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 de nition 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 signi cance - * 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 di erent 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. - */ + * 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 eld identi es the synchronization source. This identi er should be chosen - * randomly, with the intent that no two synchronization sources within the same RTP session - * will have the same SSRC identi er. An example algorithm for generating a random identi er - * is presented in Appendix A.6. Although the probability of multiple sources choosing the same - * identi er 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 identi er. If - * a source changes its source transport address, it must also choose a new SSRC identi er to - * avoid being interpreted as a looped source (see Section 8.2). - */ + * 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. SrsSimpleStream* payload; // whether transport in chunked payload. @@ -295,26 +291,26 @@ public: // 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 int decode(SrsBuffer* stream); private: virtual int decode_97(SrsBuffer* stream); @@ -322,23 +318,23 @@ private: }; /** -* 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; @@ -346,22 +342,22 @@ public: 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; @@ -374,8 +370,8 @@ public: 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; @@ -396,33 +392,33 @@ public: virtual ~SrsRtspSdp(); public: /** - * parse a line of token for sdp. - */ + * parse a line of token for sdp. + */ virtual int 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 int 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 int 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: @@ -456,78 +452,78 @@ public: virtual ~SrsRtspTransport(); public: /** - * parse a line of token for transport. - */ + * parse a line of token for transport. + */ virtual int 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(); @@ -540,78 +536,78 @@ public: }; /** -* 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 int encode(std::stringstream& ss); protected: /** - * sub classes override this to encode the headers. - */ + * sub classes override this to encode the headers. + */ virtual int 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); @@ -621,16 +617,16 @@ protected: }; /** -* 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: @@ -651,64 +647,64 @@ protected: }; /** -* the rtsp protocol stack to parse the rtsp packets. -*/ + * the rtsp protocol stack to parse the rtsp packets. + */ class SrsRtspStack { private: /** - * cached bytes buffer. - */ + * cached bytes buffer. + */ SrsSimpleStream* buf; /** - * underlayer socket object, send/recv bytes. - */ + * underlayer socket object, send/recv bytes. + */ ISrsProtocolReaderWriter* skt; public: SrsRtspStack(ISrsProtocolReaderWriter* 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 int 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 int send_message(SrsRtspResponse* res); private: /** - * recv the rtsp message. - */ + * recv the rtsp message. + */ virtual int 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 int 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 int 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 int 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 int recv_token(std::string& token, SrsRtspTokenState& state, char normal_ch = SRS_RTSP_SP, int* pconsumed = NULL); };