winlin

Merge branch '2.0release' into develop

@@ -159,7 +159,7 @@ MODULE_DEPENDS=("CORE" "KERNEL") @@ -159,7 +159,7 @@ MODULE_DEPENDS=("CORE" "KERNEL")
159 ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot}) 159 ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot})
160 MODULE_FILES=("srs_rtmp_amf0" "srs_rtmp_io" "srs_rtmp_stack" 160 MODULE_FILES=("srs_rtmp_amf0" "srs_rtmp_io" "srs_rtmp_stack"
161 "srs_rtmp_handshake" "srs_rtmp_utility" "srs_rtmp_msg_array" "srs_protocol_buffer" 161 "srs_rtmp_handshake" "srs_rtmp_utility" "srs_rtmp_msg_array" "srs_protocol_buffer"
162 - "srs_raw_avc" "srs_rtsp_stack" "srs_http_stack" "srs_protocol_kbps") 162 + "srs_raw_avc" "srs_rtsp_stack" "srs_http_stack" "srs_protocol_kbps" "srs_protocol_json")
163 PROTOCOL_INCS="src/protocol"; MODULE_DIR=${PROTOCOL_INCS} . auto/modules.sh 163 PROTOCOL_INCS="src/protocol"; MODULE_DIR=${PROTOCOL_INCS} . auto/modules.sh
164 PROTOCOL_OBJS="${MODULE_OBJS[@]}" 164 PROTOCOL_OBJS="${MODULE_OBJS[@]}"
165 # 165 #
@@ -172,7 +172,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then @@ -172,7 +172,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
172 "srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" "srs_app_http_stream" 172 "srs_app_refer" "srs_app_hls" "srs_app_forward" "srs_app_encoder" "srs_app_http_stream"
173 "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config" 173 "srs_app_thread" "srs_app_bandwidth" "srs_app_st" "srs_app_log" "srs_app_config"
174 "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks" 174 "srs_app_pithy_print" "srs_app_reload" "srs_app_http_api" "srs_app_http_conn" "srs_app_http_hooks"
175 - "srs_app_json" "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge" 175 + "srs_app_ingest" "srs_app_ffmpeg" "srs_app_utility" "srs_app_dvr" "srs_app_edge"
176 "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_http_static" 176 "srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_http_static"
177 "srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds" 177 "srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds"
178 "srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call" 178 "srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call"
@@ -58,6 +58,8 @@ file @@ -58,6 +58,8 @@ file
58 ../../src/protocol/srs_rtmp_amf0.cpp, 58 ../../src/protocol/srs_rtmp_amf0.cpp,
59 ../../src/protocol/srs_protocol_buffer.hpp, 59 ../../src/protocol/srs_protocol_buffer.hpp,
60 ../../src/protocol/srs_protocol_buffer.cpp, 60 ../../src/protocol/srs_protocol_buffer.cpp,
  61 + ../../src/protocol/srs_protocol_json.hpp,
  62 + ../../src/protocol/srs_protocol_json.cpp,
61 ../../src/protocol/srs_rtmp_handshake.hpp, 63 ../../src/protocol/srs_rtmp_handshake.hpp,
62 ../../src/protocol/srs_rtmp_handshake.cpp, 64 ../../src/protocol/srs_rtmp_handshake.cpp,
63 ../../src/protocol/srs_rtmp_io.hpp, 65 ../../src/protocol/srs_rtmp_io.hpp,
@@ -109,8 +111,6 @@ file @@ -109,8 +111,6 @@ file
109 ../../src/app/srs_app_http_static.cpp, 111 ../../src/app/srs_app_http_static.cpp,
110 ../../src/app/srs_app_ingest.hpp, 112 ../../src/app/srs_app_ingest.hpp,
111 ../../src/app/srs_app_ingest.cpp, 113 ../../src/app/srs_app_ingest.cpp,
112 - ../../src/app/srs_app_json.hpp,  
113 - ../../src/app/srs_app_json.cpp,  
114 ../../src/app/srs_app_listener.hpp, 114 ../../src/app/srs_app_listener.hpp,
115 ../../src/app/srs_app_listener.cpp, 115 ../../src/app/srs_app_listener.cpp,
116 ../../src/app/srs_app_log.hpp, 116 ../../src/app/srs_app_log.hpp,
@@ -11,6 +11,7 @@ @@ -11,6 +11,7 @@
11 3C036B561B2D0AC10078E2E0 /* srs_app_http_stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C036B531B2D0AC10078E2E0 /* srs_app_http_stream.cpp */; }; 11 3C036B561B2D0AC10078E2E0 /* srs_app_http_stream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C036B531B2D0AC10078E2E0 /* srs_app_http_stream.cpp */; };
12 3C068D6A1B10149F00AA722C /* srs_protocol_kbps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C068D681B10149F00AA722C /* srs_protocol_kbps.cpp */; }; 12 3C068D6A1B10149F00AA722C /* srs_protocol_kbps.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C068D681B10149F00AA722C /* srs_protocol_kbps.cpp */; };
13 3C068D6D1B10175500AA722C /* srs_protocol_buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C068D6B1B10175500AA722C /* srs_protocol_buffer.cpp */; }; 13 3C068D6D1B10175500AA722C /* srs_protocol_buffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C068D6B1B10175500AA722C /* srs_protocol_buffer.cpp */; };
  14 + 3C0D422E1B87165900C2508B /* srs_protocol_json.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C0D422C1B87165900C2508B /* srs_protocol_json.cpp */; };
14 3C0E1B8D1B0F5ADF003ADEF7 /* srs_http_stack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C0E1B8B1B0F5ADF003ADEF7 /* srs_http_stack.cpp */; }; 15 3C0E1B8D1B0F5ADF003ADEF7 /* srs_http_stack.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C0E1B8B1B0F5ADF003ADEF7 /* srs_http_stack.cpp */; };
15 3C1231F61AAE652D00CE8F6C /* srs_core_autofree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F01AAE652C00CE8F6C /* srs_core_autofree.cpp */; }; 16 3C1231F61AAE652D00CE8F6C /* srs_core_autofree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F01AAE652C00CE8F6C /* srs_core_autofree.cpp */; };
16 3C1231F71AAE652D00CE8F6C /* srs_core_performance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F21AAE652C00CE8F6C /* srs_core_performance.cpp */; }; 17 3C1231F71AAE652D00CE8F6C /* srs_core_performance.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1231F21AAE652C00CE8F6C /* srs_core_performance.cpp */; };
@@ -52,7 +53,6 @@ @@ -52,7 +53,6 @@
52 3C1232A11AAE81D900CE8F6C /* srs_app_http_conn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232661AAE81D900CE8F6C /* srs_app_http_conn.cpp */; }; 53 3C1232A11AAE81D900CE8F6C /* srs_app_http_conn.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232661AAE81D900CE8F6C /* srs_app_http_conn.cpp */; };
53 3C1232A21AAE81D900CE8F6C /* srs_app_http_hooks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232681AAE81D900CE8F6C /* srs_app_http_hooks.cpp */; }; 54 3C1232A21AAE81D900CE8F6C /* srs_app_http_hooks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232681AAE81D900CE8F6C /* srs_app_http_hooks.cpp */; };
54 3C1232A41AAE81D900CE8F6C /* srs_app_ingest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */; }; 55 3C1232A41AAE81D900CE8F6C /* srs_app_ingest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */; };
55 - 3C1232A51AAE81D900CE8F6C /* srs_app_json.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C12326E1AAE81D900CE8F6C /* srs_app_json.cpp */; };  
56 3C1232A71AAE81D900CE8F6C /* srs_app_listener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232721AAE81D900CE8F6C /* srs_app_listener.cpp */; }; 56 3C1232A71AAE81D900CE8F6C /* srs_app_listener.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232721AAE81D900CE8F6C /* srs_app_listener.cpp */; };
57 3C1232A81AAE81D900CE8F6C /* srs_app_log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232741AAE81D900CE8F6C /* srs_app_log.cpp */; }; 57 3C1232A81AAE81D900CE8F6C /* srs_app_log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232741AAE81D900CE8F6C /* srs_app_log.cpp */; };
58 3C1232A91AAE81D900CE8F6C /* srs_app_mpegts_udp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232761AAE81D900CE8F6C /* srs_app_mpegts_udp.cpp */; }; 58 3C1232A91AAE81D900CE8F6C /* srs_app_mpegts_udp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3C1232761AAE81D900CE8F6C /* srs_app_mpegts_udp.cpp */; };
@@ -131,6 +131,8 @@ @@ -131,6 +131,8 @@
131 3C068D691B10149F00AA722C /* srs_protocol_kbps.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_protocol_kbps.hpp; path = ../../../src/protocol/srs_protocol_kbps.hpp; sourceTree = "<group>"; }; 131 3C068D691B10149F00AA722C /* srs_protocol_kbps.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_protocol_kbps.hpp; path = ../../../src/protocol/srs_protocol_kbps.hpp; sourceTree = "<group>"; };
132 3C068D6B1B10175500AA722C /* srs_protocol_buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_protocol_buffer.cpp; path = ../../../src/protocol/srs_protocol_buffer.cpp; sourceTree = "<group>"; }; 132 3C068D6B1B10175500AA722C /* srs_protocol_buffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_protocol_buffer.cpp; path = ../../../src/protocol/srs_protocol_buffer.cpp; sourceTree = "<group>"; };
133 3C068D6C1B10175500AA722C /* srs_protocol_buffer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_protocol_buffer.hpp; path = ../../../src/protocol/srs_protocol_buffer.hpp; sourceTree = "<group>"; }; 133 3C068D6C1B10175500AA722C /* srs_protocol_buffer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_protocol_buffer.hpp; path = ../../../src/protocol/srs_protocol_buffer.hpp; sourceTree = "<group>"; };
  134 + 3C0D422C1B87165900C2508B /* srs_protocol_json.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_protocol_json.cpp; path = ../../../src/protocol/srs_protocol_json.cpp; sourceTree = "<group>"; };
  135 + 3C0D422D1B87165900C2508B /* srs_protocol_json.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_protocol_json.hpp; path = ../../../src/protocol/srs_protocol_json.hpp; sourceTree = "<group>"; };
134 3C0E1B8B1B0F5ADF003ADEF7 /* srs_http_stack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_http_stack.cpp; path = ../../../src/protocol/srs_http_stack.cpp; sourceTree = "<group>"; }; 136 3C0E1B8B1B0F5ADF003ADEF7 /* srs_http_stack.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_http_stack.cpp; path = ../../../src/protocol/srs_http_stack.cpp; sourceTree = "<group>"; };
135 3C0E1B8C1B0F5ADF003ADEF7 /* srs_http_stack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_http_stack.hpp; path = ../../../src/protocol/srs_http_stack.hpp; sourceTree = "<group>"; }; 137 3C0E1B8C1B0F5ADF003ADEF7 /* srs_http_stack.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_http_stack.hpp; path = ../../../src/protocol/srs_http_stack.hpp; sourceTree = "<group>"; };
136 3C1231E51AAE64A400CE8F6C /* srs_xcode */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = srs_xcode; sourceTree = BUILT_PRODUCTS_DIR; }; 138 3C1231E51AAE64A400CE8F6C /* srs_xcode */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = srs_xcode; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -214,8 +216,6 @@ @@ -214,8 +216,6 @@
214 3C1232691AAE81D900CE8F6C /* srs_app_http_hooks.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_http_hooks.hpp; path = ../../../src/app/srs_app_http_hooks.hpp; sourceTree = "<group>"; }; 216 3C1232691AAE81D900CE8F6C /* srs_app_http_hooks.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_http_hooks.hpp; path = ../../../src/app/srs_app_http_hooks.hpp; sourceTree = "<group>"; };
215 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_ingest.cpp; path = ../../../src/app/srs_app_ingest.cpp; sourceTree = "<group>"; }; 217 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_ingest.cpp; path = ../../../src/app/srs_app_ingest.cpp; sourceTree = "<group>"; };
216 3C12326D1AAE81D900CE8F6C /* srs_app_ingest.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_ingest.hpp; path = ../../../src/app/srs_app_ingest.hpp; sourceTree = "<group>"; }; 218 3C12326D1AAE81D900CE8F6C /* srs_app_ingest.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_ingest.hpp; path = ../../../src/app/srs_app_ingest.hpp; sourceTree = "<group>"; };
217 - 3C12326E1AAE81D900CE8F6C /* srs_app_json.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_json.cpp; path = ../../../src/app/srs_app_json.cpp; sourceTree = "<group>"; };  
218 - 3C12326F1AAE81D900CE8F6C /* srs_app_json.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_json.hpp; path = ../../../src/app/srs_app_json.hpp; sourceTree = "<group>"; };  
219 3C1232721AAE81D900CE8F6C /* srs_app_listener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_listener.cpp; path = ../../../src/app/srs_app_listener.cpp; sourceTree = "<group>"; }; 219 3C1232721AAE81D900CE8F6C /* srs_app_listener.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_listener.cpp; path = ../../../src/app/srs_app_listener.cpp; sourceTree = "<group>"; };
220 3C1232731AAE81D900CE8F6C /* srs_app_listener.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_listener.hpp; path = ../../../src/app/srs_app_listener.hpp; sourceTree = "<group>"; }; 220 3C1232731AAE81D900CE8F6C /* srs_app_listener.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = srs_app_listener.hpp; path = ../../../src/app/srs_app_listener.hpp; sourceTree = "<group>"; };
221 3C1232741AAE81D900CE8F6C /* srs_app_log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_log.cpp; path = ../../../src/app/srs_app_log.cpp; sourceTree = "<group>"; }; 221 3C1232741AAE81D900CE8F6C /* srs_app_log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = srs_app_log.cpp; path = ../../../src/app/srs_app_log.cpp; sourceTree = "<group>"; };
@@ -496,6 +496,8 @@ @@ -496,6 +496,8 @@
496 3C0E1B8C1B0F5ADF003ADEF7 /* srs_http_stack.hpp */, 496 3C0E1B8C1B0F5ADF003ADEF7 /* srs_http_stack.hpp */,
497 3C068D6B1B10175500AA722C /* srs_protocol_buffer.cpp */, 497 3C068D6B1B10175500AA722C /* srs_protocol_buffer.cpp */,
498 3C068D6C1B10175500AA722C /* srs_protocol_buffer.hpp */, 498 3C068D6C1B10175500AA722C /* srs_protocol_buffer.hpp */,
  499 + 3C0D422C1B87165900C2508B /* srs_protocol_json.cpp */,
  500 + 3C0D422D1B87165900C2508B /* srs_protocol_json.hpp */,
499 3C068D681B10149F00AA722C /* srs_protocol_kbps.cpp */, 501 3C068D681B10149F00AA722C /* srs_protocol_kbps.cpp */,
500 3C068D691B10149F00AA722C /* srs_protocol_kbps.hpp */, 502 3C068D691B10149F00AA722C /* srs_protocol_kbps.hpp */,
501 3C12322D1AAE81A400CE8F6C /* srs_raw_avc.cpp */, 503 3C12322D1AAE81A400CE8F6C /* srs_raw_avc.cpp */,
@@ -563,8 +565,6 @@ @@ -563,8 +565,6 @@
563 3C036B541B2D0AC10078E2E0 /* srs_app_http_stream.hpp */, 565 3C036B541B2D0AC10078E2E0 /* srs_app_http_stream.hpp */,
564 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */, 566 3C12326C1AAE81D900CE8F6C /* srs_app_ingest.cpp */,
565 3C12326D1AAE81D900CE8F6C /* srs_app_ingest.hpp */, 567 3C12326D1AAE81D900CE8F6C /* srs_app_ingest.hpp */,
566 - 3C12326E1AAE81D900CE8F6C /* srs_app_json.cpp */,  
567 - 3C12326F1AAE81D900CE8F6C /* srs_app_json.hpp */,  
568 3C1232721AAE81D900CE8F6C /* srs_app_listener.cpp */, 568 3C1232721AAE81D900CE8F6C /* srs_app_listener.cpp */,
569 3C1232731AAE81D900CE8F6C /* srs_app_listener.hpp */, 569 3C1232731AAE81D900CE8F6C /* srs_app_listener.hpp */,
570 3C1232741AAE81D900CE8F6C /* srs_app_log.cpp */, 570 3C1232741AAE81D900CE8F6C /* srs_app_log.cpp */,
@@ -862,12 +862,12 @@ @@ -862,12 +862,12 @@
862 3C689F961AB6AAAC00C9CEEE /* event.c in Sources */, 862 3C689F961AB6AAAC00C9CEEE /* event.c in Sources */,
863 3C1232A81AAE81D900CE8F6C /* srs_app_log.cpp in Sources */, 863 3C1232A81AAE81D900CE8F6C /* srs_app_log.cpp in Sources */,
864 3C1232A41AAE81D900CE8F6C /* srs_app_ingest.cpp in Sources */, 864 3C1232A41AAE81D900CE8F6C /* srs_app_ingest.cpp in Sources */,
  865 + 3C0D422E1B87165900C2508B /* srs_protocol_json.cpp in Sources */,
865 3C1232B41AAE81D900CE8F6C /* srs_app_st.cpp in Sources */, 866 3C1232B41AAE81D900CE8F6C /* srs_app_st.cpp in Sources */,
866 3C1232481AAE81A400CE8F6C /* srs_rtmp_stack.cpp in Sources */, 867 3C1232481AAE81A400CE8F6C /* srs_rtmp_stack.cpp in Sources */,
867 3C1232B01AAE81D900CE8F6C /* srs_app_security.cpp in Sources */, 868 3C1232B01AAE81D900CE8F6C /* srs_app_security.cpp in Sources */,
868 3C12322B1AAE814D00CE8F6C /* srs_kernel_utility.cpp in Sources */, 869 3C12322B1AAE814D00CE8F6C /* srs_kernel_utility.cpp in Sources */,
869 3C12324A1AAE81A400CE8F6C /* srs_rtsp_stack.cpp in Sources */, 870 3C12324A1AAE81A400CE8F6C /* srs_rtsp_stack.cpp in Sources */,
870 - 3C1232A51AAE81D900CE8F6C /* srs_app_json.cpp in Sources */,  
871 3C36DB5D1ABD1CB90066CCAF /* srs_librtmp.cpp in Sources */, 871 3C36DB5D1ABD1CB90066CCAF /* srs_librtmp.cpp in Sources */,
872 3C12329F1AAE81D900CE8F6C /* srs_app_http_api.cpp in Sources */, 872 3C12329F1AAE81D900CE8F6C /* srs_app_http_api.cpp in Sources */,
873 3C1EE6AE1AB1055800576EE9 /* srs_app_hds.cpp in Sources */, 873 3C1EE6AE1AB1055800576EE9 /* srs_app_hds.cpp in Sources */,
@@ -40,7 +40,7 @@ using namespace std; @@ -40,7 +40,7 @@ using namespace std;
40 #include <srs_kernel_file.hpp> 40 #include <srs_kernel_file.hpp>
41 #include <srs_rtmp_amf0.hpp> 41 #include <srs_rtmp_amf0.hpp>
42 #include <srs_kernel_stream.hpp> 42 #include <srs_kernel_stream.hpp>
43 -#include <srs_app_json.hpp> 43 +#include <srs_protocol_json.hpp>
44 #include <srs_app_utility.hpp> 44 #include <srs_app_utility.hpp>
45 45
46 // update the flv duration and filesize every this interval in ms. 46 // update the flv duration and filesize every this interval in ms.
@@ -32,7 +32,7 @@ using namespace std; @@ -32,7 +32,7 @@ using namespace std;
32 #include <srs_kernel_log.hpp> 32 #include <srs_kernel_log.hpp>
33 #include <srs_app_config.hpp> 33 #include <srs_app_config.hpp>
34 #include <srs_app_http_client.hpp> 34 #include <srs_app_http_client.hpp>
35 -#include <srs_app_json.hpp> 35 +#include <srs_protocol_json.hpp>
36 #include <srs_app_utility.hpp> 36 #include <srs_app_utility.hpp>
37 #include <srs_core_autofree.hpp> 37 #include <srs_core_autofree.hpp>
38 #include <srs_app_http_conn.hpp> 38 #include <srs_app_http_conn.hpp>
@@ -33,7 +33,7 @@ using namespace std; @@ -33,7 +33,7 @@ using namespace std;
33 #include <srs_kernel_error.hpp> 33 #include <srs_kernel_error.hpp>
34 #include <srs_app_st.hpp> 34 #include <srs_app_st.hpp>
35 #include <srs_core_autofree.hpp> 35 #include <srs_core_autofree.hpp>
36 -#include <srs_app_json.hpp> 36 +#include <srs_protocol_json.hpp>
37 #include <srs_kernel_utility.hpp> 37 #include <srs_kernel_utility.hpp>
38 #include <srs_app_utility.hpp> 38 #include <srs_app_utility.hpp>
39 #include <srs_app_statistic.hpp> 39 #include <srs_app_statistic.hpp>
@@ -112,6 +112,7 @@ int SrsGoApiV1::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) @@ -112,6 +112,7 @@ int SrsGoApiV1::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
112 << SRS_JFIELD_STR("requests", "the request itself, for http debug") << SRS_JFIELD_CONT 112 << SRS_JFIELD_STR("requests", "the request itself, for http debug") << SRS_JFIELD_CONT
113 << SRS_JFIELD_STR("vhosts", "dumps vhost to json") << SRS_JFIELD_CONT 113 << SRS_JFIELD_STR("vhosts", "dumps vhost to json") << SRS_JFIELD_CONT
114 << SRS_JFIELD_STR("streams", "dumps streams to json") << SRS_JFIELD_CONT 114 << SRS_JFIELD_STR("streams", "dumps streams to json") << SRS_JFIELD_CONT
  115 + << SRS_JFIELD_STR("clients", "dumps clients to json") << SRS_JFIELD_CONT
115 << SRS_JFIELD_ORG("test", SRS_JOBJECT_START) 116 << SRS_JFIELD_ORG("test", SRS_JOBJECT_START)
116 << SRS_JFIELD_STR("requests", "show the request info") << SRS_JFIELD_CONT 117 << SRS_JFIELD_STR("requests", "show the request info") << SRS_JFIELD_CONT
117 << SRS_JFIELD_STR("errors", "always return an error 100") << SRS_JFIELD_CONT 118 << SRS_JFIELD_STR("errors", "always return an error 100") << SRS_JFIELD_CONT
@@ -442,17 +443,45 @@ SrsGoApiVhosts::~SrsGoApiVhosts() @@ -442,17 +443,45 @@ SrsGoApiVhosts::~SrsGoApiVhosts()
442 443
443 int SrsGoApiVhosts::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) 444 int SrsGoApiVhosts::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
444 { 445 {
445 - std::stringstream data;  
446 - SrsStatistic* stat = SrsStatistic::instance();  
447 - int ret = stat->dumps_vhosts(data); 446 + int ret = ERROR_SUCCESS;
448 447
  448 + SrsStatistic* stat = SrsStatistic::instance();
449 std::stringstream ss; 449 std::stringstream ss;
450 450
451 - ss << SRS_JOBJECT_START  
452 - << SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT  
453 - << SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT  
454 - << SRS_JFIELD_ORG("vhosts", data.str())  
455 - << SRS_JOBJECT_END; 451 + // path: {pattern}{vhost_id}
  452 + // e.g. /api/v1/vhosts/100 pattern= /api/v1/vhosts/, vhost_id=100
  453 + int vid = r->parse_rest_id(entry->pattern);
  454 + SrsStatisticVhost* vhost = NULL;
  455 +
  456 + if (vid > 0 && (vhost = stat->find_vhost(vid)) == NULL) {
  457 + ret = ERROR_RTMP_STREAM_NOT_FOUND;
  458 + srs_error("vhost id=%d not found. ret=%d", vid, ret);
  459 + return srs_http_response_code(w, ret);
  460 + }
  461 +
  462 + if (r->is_http_get()) {
  463 + std::stringstream data;
  464 +
  465 + if (!vhost) {
  466 + ret = stat->dumps_vhosts(data);
  467 +
  468 + ss << SRS_JOBJECT_START
  469 + << SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT
  470 + << SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT
  471 + << SRS_JFIELD_ORG("vhosts", data.str())
  472 + << SRS_JOBJECT_END;
  473 + } else {
  474 + ret = vhost->dumps(data);
  475 +
  476 + ss << SRS_JOBJECT_START
  477 + << SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT
  478 + << SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT
  479 + << SRS_JFIELD_ORG("vhost", data.str())
  480 + << SRS_JOBJECT_END;
  481 + }
  482 +
  483 + return srs_http_response_json(w, ss.str());
  484 + }
456 485
457 return srs_http_response_json(w, ss.str()); 486 return srs_http_response_json(w, ss.str());
458 } 487 }
@@ -468,63 +497,114 @@ SrsGoApiStreams::~SrsGoApiStreams() @@ -468,63 +497,114 @@ SrsGoApiStreams::~SrsGoApiStreams()
468 int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) 497 int SrsGoApiStreams::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
469 { 498 {
470 int ret = ERROR_SUCCESS; 499 int ret = ERROR_SUCCESS;
  500 +
471 SrsStatistic* stat = SrsStatistic::instance(); 501 SrsStatistic* stat = SrsStatistic::instance();
472 std::stringstream ss; 502 std::stringstream ss;
  503 +
  504 + // path: {pattern}{stream_id}
  505 + // e.g. /api/v1/streams/100 pattern= /api/v1/streams/, stream_id=100
  506 + int sid = r->parse_rest_id(entry->pattern);
  507 +
  508 + SrsStatisticStream* stream = NULL;
  509 + if (sid >= 0 && (stream = stat->find_stream(sid)) == NULL) {
  510 + ret = ERROR_RTMP_STREAM_NOT_FOUND;
  511 + srs_error("stream stream_id=%d not found. ret=%d", sid, ret);
  512 + return srs_http_response_code(w, ret);
  513 + }
473 514
474 if (r->is_http_delete()) { 515 if (r->is_http_delete()) {
475 - // path: {pattern}{stream_id}  
476 - // e.g. /api/v1/streams/100 pattern= /api/v1/streams/, stream_id=100  
477 - string sid = r->path().substr((int)entry->pattern.length());  
478 - if (sid.empty()) {  
479 - ret = ERROR_REQUEST_DATA;  
480 - srs_error("invalid param, stream_id=%s. ret=%d", sid.c_str(), ret);  
481 -  
482 - ss << SRS_JOBJECT_START  
483 - << SRS_JFIELD_ERROR(ret)  
484 - << SRS_JOBJECT_END;  
485 -  
486 - return srs_http_response_json(w, ss.str()); 516 + srs_assert(stream);
  517 +
  518 + SrsSource* source = SrsSource::fetch(stream->vhost->vhost, stream->app, stream->stream);
  519 + if (!source) {
  520 + ret = ERROR_SOURCE_NOT_FOUND;
  521 + srs_warn("source not found for sid=%d", sid);
  522 + return srs_http_response_code(w, ret);
487 } 523 }
488 -  
489 - int stream_id = ::atoi(sid.c_str());  
490 - SrsStatisticStream* stream = stat->find_stream(stream_id);  
491 - if (stream == NULL) {  
492 - ret = ERROR_RTMP_STREAM_NOT_FOUND;  
493 - srs_error("stream stream_id=%s not found. ret=%d", sid.c_str(), ret);  
494 - 524 +
  525 + source->set_expired();
  526 + srs_warn("disconnent stream=%d successfully. vhost=%s, app=%s, stream=%s.",
  527 + sid, stream->vhost->vhost.c_str(), stream->app.c_str(), stream->stream.c_str());
  528 + return srs_http_response_code(w, ret);
  529 + } else if (r->is_http_get()) {
  530 + std::stringstream data;
  531 +
  532 + if (!stream) {
  533 + ret = stat->dumps_streams(data);
  534 +
495 ss << SRS_JOBJECT_START 535 ss << SRS_JOBJECT_START
496 - << SRS_JFIELD_ERROR(ret)  
497 - << SRS_JOBJECT_END;  
498 -  
499 - return srs_http_response_json(w, ss.str());  
500 - }  
501 -  
502 - SrsSource* source = SrsSource::fetch(stream->vhost->vhost, stream->app, stream->stream);  
503 - if (source) {  
504 - source->set_expired();  
505 - srs_warn("disconnent stream=%d successfully. vhost=%s, app=%s, stream=%s.",  
506 - stream_id, stream->vhost->vhost.c_str(), stream->app.c_str(), stream->stream.c_str()); 536 + << SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT
  537 + << SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT
  538 + << SRS_JFIELD_ORG("streams", data.str())
  539 + << SRS_JOBJECT_END;
507 } else { 540 } else {
508 - ret = ERROR_SOURCE_NOT_FOUND; 541 + ret = stream->dumps(data);
  542 +
  543 + ss << SRS_JOBJECT_START
  544 + << SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT
  545 + << SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT
  546 + << SRS_JFIELD_ORG("stream", data.str())
  547 + << SRS_JOBJECT_END;
509 } 548 }
  549 +
  550 + return srs_http_response_json(w, ss.str());
  551 + }
  552 +
  553 + return ret;
  554 +}
  555 +
  556 +SrsGoApiClients::SrsGoApiClients()
  557 +{
  558 +}
510 559
511 - ss << SRS_JOBJECT_START  
512 - << SRS_JFIELD_ERROR(ret)  
513 - << SRS_JOBJECT_END; 560 +SrsGoApiClients::~SrsGoApiClients()
  561 +{
  562 +}
514 563
515 - return srs_http_response_json(w, ss.str());  
516 - } else { 564 +int SrsGoApiClients::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
  565 +{
  566 + int ret = ERROR_SUCCESS;
  567 +
  568 + SrsStatistic* stat = SrsStatistic::instance();
  569 + std::stringstream ss;
  570 +
  571 + // path: {pattern}{client_id}
  572 + // e.g. /api/v1/clients/100 pattern= /api/v1/clients/, client_id=100
  573 + int cid = r->parse_rest_id(entry->pattern);
  574 +
  575 + SrsStatisticClient* client = NULL;
  576 + if (cid >= 0 && (client = stat->find_client(cid)) == NULL) {
  577 + ret = ERROR_RTMP_STREAM_NOT_FOUND;
  578 + srs_error("stream client_id=%d not found. ret=%d", cid, ret);
  579 + return srs_http_response_code(w, ret);
  580 +
  581 + }
  582 +
  583 + if (r->is_http_get()) {
517 std::stringstream data; 584 std::stringstream data;
518 - int ret = stat->dumps_streams(data);  
519 585
520 - ss << SRS_JOBJECT_START  
521 - << SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT  
522 - << SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT  
523 - << SRS_JFIELD_ORG("streams", data.str())  
524 - << SRS_JOBJECT_END; 586 + if (!client) {
  587 + ret = stat->dumps_clients(data, 0, 10);
  588 +
  589 + ss << SRS_JOBJECT_START
  590 + << SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT
  591 + << SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT
  592 + << SRS_JFIELD_ORG("clients", data.str())
  593 + << SRS_JOBJECT_END;
  594 + } else {
  595 + ret = client->dumps(data);
  596 +
  597 + ss << SRS_JOBJECT_START
  598 + << SRS_JFIELD_ERROR(ret) << SRS_JFIELD_CONT
  599 + << SRS_JFIELD_ORG("server", stat->server_id()) << SRS_JFIELD_CONT
  600 + << SRS_JFIELD_ORG("client", data.str())
  601 + << SRS_JOBJECT_END;
  602 + }
525 603
526 return srs_http_response_json(w, ss.str()); 604 return srs_http_response_json(w, ss.str());
527 } 605 }
  606 +
  607 + return ret;
528 } 608 }
529 609
530 SrsGoApiError::SrsGoApiError() 610 SrsGoApiError::SrsGoApiError()
@@ -537,15 +617,7 @@ SrsGoApiError::~SrsGoApiError() @@ -537,15 +617,7 @@ SrsGoApiError::~SrsGoApiError()
537 617
538 int SrsGoApiError::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) 618 int SrsGoApiError::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
539 { 619 {
540 - std::stringstream ss;  
541 -  
542 - ss << SRS_JOBJECT_START  
543 - << SRS_JFIELD_ERROR(100) << SRS_JFIELD_CONT  
544 - << SRS_JFIELD_STR("msg", "SRS demo error.") << SRS_JFIELD_CONT  
545 - << SRS_JFIELD_STR("path", r->path())  
546 - << SRS_JOBJECT_END;  
547 -  
548 - return srs_http_response_json(w, ss.str()); 620 + return srs_http_response_code(w, 100);
549 } 621 }
550 622
551 623
@@ -159,6 +159,15 @@ public: @@ -159,6 +159,15 @@ public:
159 virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r); 159 virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
160 }; 160 };
161 161
  162 +class SrsGoApiClients : public ISrsHttpHandler
  163 +{
  164 +public:
  165 + SrsGoApiClients();
  166 + virtual ~SrsGoApiClients();
  167 +public:
  168 + virtual int serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r);
  169 +};
  170 +
162 class SrsGoApiError : public ISrsHttpHandler 171 class SrsGoApiError : public ISrsHttpHandler
163 { 172 {
164 public: 173 public:
@@ -654,6 +654,7 @@ string SrsHttpMessage::uri() @@ -654,6 +654,7 @@ string SrsHttpMessage::uri()
654 654
655 uri += host(); 655 uri += host();
656 uri += path(); 656 uri += path();
  657 +
657 return uri; 658 return uri;
658 } 659 }
659 660
@@ -677,6 +678,21 @@ string SrsHttpMessage::ext() @@ -677,6 +678,21 @@ string SrsHttpMessage::ext()
677 return _ext; 678 return _ext;
678 } 679 }
679 680
  681 +int SrsHttpMessage::parse_rest_id(string pattern)
  682 +{
  683 + string p = _uri->get_path();
  684 + if (p.length() <= pattern.length()) {
  685 + return -1;
  686 + }
  687 +
  688 + string id = p.substr((int)pattern.length());
  689 + if (!id.empty()) {
  690 + return ::atoi(id.c_str());
  691 + }
  692 +
  693 + return -1;
  694 +}
  695 +
680 int SrsHttpMessage::body_read_all(string& body) 696 int SrsHttpMessage::body_read_all(string& body)
681 { 697 {
682 int ret = ERROR_SUCCESS; 698 int ret = ERROR_SUCCESS;
@@ -246,6 +246,10 @@ public: @@ -246,6 +246,10 @@ public:
246 virtual std::string host(); 246 virtual std::string host();
247 virtual std::string path(); 247 virtual std::string path();
248 virtual std::string ext(); 248 virtual std::string ext();
  249 + /**
  250 + * get the RESTful matched id.
  251 + */
  252 + virtual int parse_rest_id(std::string pattern);
249 public: 253 public:
250 /** 254 /**
251 * read body to string. 255 * read body to string.
@@ -31,7 +31,7 @@ using namespace std; @@ -31,7 +31,7 @@ using namespace std;
31 #include <srs_kernel_error.hpp> 31 #include <srs_kernel_error.hpp>
32 #include <srs_rtmp_stack.hpp> 32 #include <srs_rtmp_stack.hpp>
33 #include <srs_app_st.hpp> 33 #include <srs_app_st.hpp>
34 -#include <srs_app_json.hpp> 34 +#include <srs_protocol_json.hpp>
35 #include <srs_app_dvr.hpp> 35 #include <srs_app_dvr.hpp>
36 #include <srs_app_http_client.hpp> 36 #include <srs_app_http_client.hpp>
37 #include <srs_core_autofree.hpp> 37 #include <srs_core_autofree.hpp>
@@ -773,10 +773,10 @@ int SrsServer::http_handle() @@ -773,10 +773,10 @@ int SrsServer::http_handle()
773 if ((ret = http_api_mux->handle("/", new SrsHttpNotFoundHandler())) != ERROR_SUCCESS) { 773 if ((ret = http_api_mux->handle("/", new SrsHttpNotFoundHandler())) != ERROR_SUCCESS) {
774 return ret; 774 return ret;
775 } 775 }
776 - if ((ret = http_api_mux->handle("/api", new SrsGoApiApi())) != ERROR_SUCCESS) { 776 + if ((ret = http_api_mux->handle("/api/", new SrsGoApiApi())) != ERROR_SUCCESS) {
777 return ret; 777 return ret;
778 } 778 }
779 - if ((ret = http_api_mux->handle("/api/v1", new SrsGoApiV1())) != ERROR_SUCCESS) { 779 + if ((ret = http_api_mux->handle("/api/v1/", new SrsGoApiV1())) != ERROR_SUCCESS) {
780 return ret; 780 return ret;
781 } 781 }
782 if ((ret = http_api_mux->handle("/api/v1/versions", new SrsGoApiVersion())) != ERROR_SUCCESS) { 782 if ((ret = http_api_mux->handle("/api/v1/versions", new SrsGoApiVersion())) != ERROR_SUCCESS) {
@@ -800,12 +800,15 @@ int SrsServer::http_handle() @@ -800,12 +800,15 @@ int SrsServer::http_handle()
800 if ((ret = http_api_mux->handle("/api/v1/authors", new SrsGoApiAuthors())) != ERROR_SUCCESS) { 800 if ((ret = http_api_mux->handle("/api/v1/authors", new SrsGoApiAuthors())) != ERROR_SUCCESS) {
801 return ret; 801 return ret;
802 } 802 }
803 - if ((ret = http_api_mux->handle("/api/v1/vhosts", new SrsGoApiVhosts())) != ERROR_SUCCESS) { 803 + if ((ret = http_api_mux->handle("/api/v1/vhosts/", new SrsGoApiVhosts())) != ERROR_SUCCESS) {
804 return ret; 804 return ret;
805 } 805 }
806 if ((ret = http_api_mux->handle("/api/v1/streams/", new SrsGoApiStreams())) != ERROR_SUCCESS) { 806 if ((ret = http_api_mux->handle("/api/v1/streams/", new SrsGoApiStreams())) != ERROR_SUCCESS) {
807 return ret; 807 return ret;
808 } 808 }
  809 + if ((ret = http_api_mux->handle("/api/v1/clients/", new SrsGoApiClients())) != ERROR_SUCCESS) {
  810 + return ret;
  811 + }
809 812
810 // test the request info. 813 // test the request info.
811 if ((ret = http_api_mux->handle("/api/v1/test/requests", new SrsGoApiRequests())) != ERROR_SUCCESS) { 814 if ((ret = http_api_mux->handle("/api/v1/test/requests", new SrsGoApiRequests())) != ERROR_SUCCESS) {
@@ -28,7 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -28,7 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 using namespace std; 28 using namespace std;
29 29
30 #include <srs_rtmp_stack.hpp> 30 #include <srs_rtmp_stack.hpp>
31 -#include <srs_app_json.hpp> 31 +#include <srs_protocol_json.hpp>
32 #include <srs_protocol_kbps.hpp> 32 #include <srs_protocol_kbps.hpp>
33 #include <srs_app_conn.hpp> 33 #include <srs_app_conn.hpp>
34 #include <srs_app_config.hpp> 34 #include <srs_app_config.hpp>
@@ -47,6 +47,8 @@ SrsStatisticVhost::SrsStatisticVhost() @@ -47,6 +47,8 @@ SrsStatisticVhost::SrsStatisticVhost()
47 47
48 kbps = new SrsKbps(); 48 kbps = new SrsKbps();
49 kbps->set_io(NULL, NULL); 49 kbps->set_io(NULL, NULL);
  50 +
  51 + nb_clients = 0;
50 } 52 }
51 53
52 SrsStatisticVhost::~SrsStatisticVhost() 54 SrsStatisticVhost::~SrsStatisticVhost()
@@ -54,6 +56,33 @@ SrsStatisticVhost::~SrsStatisticVhost() @@ -54,6 +56,33 @@ SrsStatisticVhost::~SrsStatisticVhost()
54 srs_freep(kbps); 56 srs_freep(kbps);
55 } 57 }
56 58
  59 +int SrsStatisticVhost::dumps(stringstream& ss)
  60 +{
  61 + int ret = ERROR_SUCCESS;
  62 +
  63 + // dumps the config of vhost.
  64 + bool hls_enabled = _srs_config->get_hls_enabled(vhost);
  65 + bool enabled = _srs_config->get_vhost_enabled(vhost);
  66 +
  67 + ss << SRS_JOBJECT_START
  68 + << SRS_JFIELD_ORG("id", id) << SRS_JFIELD_CONT
  69 + << SRS_JFIELD_STR("name", vhost) << SRS_JFIELD_CONT
  70 + << SRS_JFIELD_BOOL("enabled", enabled) << SRS_JFIELD_CONT
  71 + << SRS_JFIELD_ORG("clients", nb_clients) << SRS_JFIELD_CONT
  72 + << SRS_JFIELD_ORG("send_bytes", kbps->get_send_bytes()) << SRS_JFIELD_CONT
  73 + << SRS_JFIELD_ORG("recv_bytes", kbps->get_recv_bytes()) << SRS_JFIELD_CONT
  74 + << SRS_JFIELD_NAME("hls") << SRS_JOBJECT_START
  75 + << SRS_JFIELD_BOOL("enabled", hls_enabled);
  76 + if (hls_enabled) {
  77 + ss << SRS_JFIELD_CONT;
  78 + ss << SRS_JFIELD_ORG("fragment", _srs_config->get_hls_fragment(vhost));
  79 + }
  80 + ss << SRS_JOBJECT_END
  81 + << SRS_JOBJECT_END;
  82 +
  83 + return ret;
  84 +}
  85 +
57 SrsStatisticStream::SrsStatisticStream() 86 SrsStatisticStream::SrsStatisticStream()
58 { 87 {
59 id = srs_generate_id(); 88 id = srs_generate_id();
@@ -73,6 +102,8 @@ SrsStatisticStream::SrsStatisticStream() @@ -73,6 +102,8 @@ SrsStatisticStream::SrsStatisticStream()
73 102
74 kbps = new SrsKbps(); 103 kbps = new SrsKbps();
75 kbps->set_io(NULL, NULL); 104 kbps->set_io(NULL, NULL);
  105 +
  106 + nb_clients = 0;
76 } 107 }
77 108
78 SrsStatisticStream::~SrsStatisticStream() 109 SrsStatisticStream::~SrsStatisticStream()
@@ -80,6 +111,48 @@ SrsStatisticStream::~SrsStatisticStream() @@ -80,6 +111,48 @@ SrsStatisticStream::~SrsStatisticStream()
80 srs_freep(kbps); 111 srs_freep(kbps);
81 } 112 }
82 113
  114 +int SrsStatisticStream::dumps(stringstream& ss)
  115 +{
  116 + int ret = ERROR_SUCCESS;
  117 +
  118 + ss << SRS_JOBJECT_START
  119 + << SRS_JFIELD_ORG("id", id) << SRS_JFIELD_CONT
  120 + << SRS_JFIELD_STR("name", stream) << SRS_JFIELD_CONT
  121 + << SRS_JFIELD_ORG("vhost", vhost->id) << SRS_JFIELD_CONT
  122 + << SRS_JFIELD_STR("app", app) << SRS_JFIELD_CONT
  123 + << SRS_JFIELD_ORG("clients", nb_clients) << SRS_JFIELD_CONT
  124 + << SRS_JFIELD_ORG("send_bytes", kbps->get_send_bytes()) << SRS_JFIELD_CONT
  125 + << SRS_JFIELD_ORG("recv_bytes", kbps->get_recv_bytes()) << SRS_JFIELD_CONT
  126 + << SRS_JFIELD_ORG("live_ms", srs_get_system_time_ms()) << SRS_JFIELD_CONT
  127 + << SRS_JFIELD_STR("status", status) << SRS_JFIELD_CONT;
  128 +
  129 + if (!has_video) {
  130 + ss << SRS_JFIELD_NULL("video") << SRS_JFIELD_CONT;
  131 + } else {
  132 + ss << SRS_JFIELD_NAME("video") << SRS_JOBJECT_START
  133 + << SRS_JFIELD_STR("codec", srs_codec_video2str(vcodec)) << SRS_JFIELD_CONT
  134 + << SRS_JFIELD_STR("profile", srs_codec_avc_profile2str(avc_profile)) << SRS_JFIELD_CONT
  135 + << SRS_JFIELD_ORG("level", srs_codec_avc_level2str(avc_level))
  136 + << SRS_JOBJECT_END
  137 + << SRS_JFIELD_CONT;
  138 + }
  139 +
  140 + if (!has_audio) {
  141 + ss << SRS_JFIELD_NULL("audio");
  142 + } else {
  143 + ss << SRS_JFIELD_NAME("audio") << SRS_JOBJECT_START
  144 + << SRS_JFIELD_STR("codec", srs_codec_audio2str(acodec)) << SRS_JFIELD_CONT
  145 + << SRS_JFIELD_ORG("sample_rate", (int)flv_sample_rates[asample_rate]) << SRS_JFIELD_CONT
  146 + << SRS_JFIELD_ORG("channel", (int)asound_type + 1) << SRS_JFIELD_CONT
  147 + << SRS_JFIELD_STR("profile", srs_codec_aac_object2str(aac_object))
  148 + << SRS_JOBJECT_END;
  149 + }
  150 +
  151 + ss << SRS_JOBJECT_END;
  152 +
  153 + return ret;
  154 +}
  155 +
83 void SrsStatisticStream::publish() 156 void SrsStatisticStream::publish()
84 { 157 {
85 status = STATISTIC_STREAM_STATUS_PUBLISHING; 158 status = STATISTIC_STREAM_STATUS_PUBLISHING;
@@ -92,6 +165,26 @@ void SrsStatisticStream::close() @@ -92,6 +165,26 @@ void SrsStatisticStream::close()
92 status = STATISTIC_STREAM_STATUS_IDLING; 165 status = STATISTIC_STREAM_STATUS_IDLING;
93 } 166 }
94 167
  168 +SrsStatisticClient::SrsStatisticClient()
  169 +{
  170 + id = 0;
  171 +}
  172 +
  173 +SrsStatisticClient::~SrsStatisticClient()
  174 +{
  175 +}
  176 +
  177 +int SrsStatisticClient::dumps(stringstream& ss)
  178 +{
  179 + int ret = ERROR_SUCCESS;
  180 +
  181 + ss << SRS_JOBJECT_START
  182 + << SRS_JFIELD_ORG("id", id)
  183 + << SRS_JOBJECT_END;
  184 +
  185 + return ret;
  186 +}
  187 +
95 SrsStatistic* SrsStatistic::_instance = new SrsStatistic(); 188 SrsStatistic* SrsStatistic::_instance = new SrsStatistic();
96 189
97 SrsStatistic::SrsStatistic() 190 SrsStatistic::SrsStatistic()
@@ -107,14 +200,14 @@ SrsStatistic::~SrsStatistic() @@ -107,14 +200,14 @@ SrsStatistic::~SrsStatistic()
107 srs_freep(kbps); 200 srs_freep(kbps);
108 201
109 if (true) { 202 if (true) {
110 - std::map<std::string, SrsStatisticVhost*>::iterator it; 203 + std::map<int64_t, SrsStatisticVhost*>::iterator it;
111 for (it = vhosts.begin(); it != vhosts.end(); it++) { 204 for (it = vhosts.begin(); it != vhosts.end(); it++) {
112 SrsStatisticVhost* vhost = it->second; 205 SrsStatisticVhost* vhost = it->second;
113 srs_freep(vhost); 206 srs_freep(vhost);
114 } 207 }
115 } 208 }
116 if (true) { 209 if (true) {
117 - std::map<std::string, SrsStatisticStream*>::iterator it; 210 + std::map<int64_t, SrsStatisticStream*>::iterator it;
118 for (it = streams.begin(); it != streams.end(); it++) { 211 for (it = streams.begin(); it != streams.end(); it++) {
119 SrsStatisticStream* stream = it->second; 212 SrsStatisticStream* stream = it->second;
120 srs_freep(stream); 213 srs_freep(stream);
@@ -127,6 +220,11 @@ SrsStatistic::~SrsStatistic() @@ -127,6 +220,11 @@ SrsStatistic::~SrsStatistic()
127 srs_freep(client); 220 srs_freep(client);
128 } 221 }
129 } 222 }
  223 +
  224 + vhosts.clear();
  225 + rvhosts.clear();
  226 + streams.clear();
  227 + rstreams.clear();
130 } 228 }
131 229
132 SrsStatistic* SrsStatistic::instance() 230 SrsStatistic* SrsStatistic::instance()
@@ -134,16 +232,29 @@ SrsStatistic* SrsStatistic::instance() @@ -134,16 +232,29 @@ SrsStatistic* SrsStatistic::instance()
134 return _instance; 232 return _instance;
135 } 233 }
136 234
137 -SrsStatisticStream* SrsStatistic::find_stream(int stream_id) 235 +SrsStatisticVhost* SrsStatistic::find_vhost(int vid)
  236 +{
  237 + std::map<int64_t, SrsStatisticVhost*>::iterator it;
  238 + if ((it = vhosts.find(vid)) != vhosts.end()) {
  239 + return it->second;
  240 + }
  241 + return NULL;
  242 +}
  243 +
  244 +SrsStatisticStream* SrsStatistic::find_stream(int sid)
  245 +{
  246 + std::map<int64_t, SrsStatisticStream*>::iterator it;
  247 + if ((it = streams.find(sid)) != streams.end()) {
  248 + return it->second;
  249 + }
  250 + return NULL;
  251 +}
  252 +
  253 +SrsStatisticClient* SrsStatistic::find_client(int cid)
138 { 254 {
139 std::map<int, SrsStatisticClient*>::iterator it; 255 std::map<int, SrsStatisticClient*>::iterator it;
140 - for (it = clients.begin(); it != clients.end(); it++) {  
141 - SrsStatisticClient* client = it->second;  
142 - SrsStatisticStream* stream = client->stream;  
143 -  
144 - if (stream_id == stream->id) {  
145 - return stream;  
146 - } 256 + if ((it = clients.find(cid)) != clients.end()) {
  257 + return it->second;
147 } 258 }
148 return NULL; 259 return NULL;
149 } 260 }
@@ -215,6 +326,10 @@ int SrsStatistic::on_client(int id, SrsRequest* req) @@ -215,6 +326,10 @@ int SrsStatistic::on_client(int id, SrsRequest* req)
215 } else { 326 } else {
216 client = clients[id]; 327 client = clients[id];
217 } 328 }
  329 +
  330 + // got client.
  331 + stream->nb_clients++;
  332 + vhost->nb_clients++;
218 333
219 return ret; 334 return ret;
220 } 335 }
@@ -222,12 +337,19 @@ int SrsStatistic::on_client(int id, SrsRequest* req) @@ -222,12 +337,19 @@ int SrsStatistic::on_client(int id, SrsRequest* req)
222 void SrsStatistic::on_disconnect(int id) 337 void SrsStatistic::on_disconnect(int id)
223 { 338 {
224 std::map<int, SrsStatisticClient*>::iterator it; 339 std::map<int, SrsStatisticClient*>::iterator it;
225 - it = clients.find(id);  
226 - if (it != clients.end()) {  
227 - SrsStatisticClient* client = it->second;  
228 - srs_freep(client);  
229 - clients.erase(it); 340 + if ((it = clients.find(id)) == clients.end()) {
  341 + return;
230 } 342 }
  343 +
  344 + SrsStatisticClient* client = it->second;
  345 + SrsStatisticStream* stream = client->stream;
  346 + SrsStatisticVhost* vhost = stream->vhost;
  347 +
  348 + srs_freep(client);
  349 + clients.erase(it);
  350 +
  351 + stream->nb_clients--;
  352 + vhost->nb_clients--;
231 } 353 }
232 354
233 void SrsStatistic::kbps_add_delta(SrsConnection* conn) 355 void SrsStatistic::kbps_add_delta(SrsConnection* conn)
@@ -256,14 +378,14 @@ SrsKbps* SrsStatistic::kbps_sample() @@ -256,14 +378,14 @@ SrsKbps* SrsStatistic::kbps_sample()
256 { 378 {
257 kbps->sample(); 379 kbps->sample();
258 if (true) { 380 if (true) {
259 - std::map<std::string, SrsStatisticVhost*>::iterator it; 381 + std::map<int64_t, SrsStatisticVhost*>::iterator it;
260 for (it = vhosts.begin(); it != vhosts.end(); it++) { 382 for (it = vhosts.begin(); it != vhosts.end(); it++) {
261 SrsStatisticVhost* vhost = it->second; 383 SrsStatisticVhost* vhost = it->second;
262 vhost->kbps->sample(); 384 vhost->kbps->sample();
263 } 385 }
264 } 386 }
265 if (true) { 387 if (true) {
266 - std::map<std::string, SrsStatisticStream*>::iterator it; 388 + std::map<int64_t, SrsStatisticStream*>::iterator it;
267 for (it = streams.begin(); it != streams.end(); it++) { 389 for (it = streams.begin(); it != streams.end(); it++) {
268 SrsStatisticStream* stream = it->second; 390 SrsStatisticStream* stream = it->second;
269 stream->kbps->sample(); 391 stream->kbps->sample();
@@ -283,29 +405,17 @@ int SrsStatistic::dumps_vhosts(stringstream& ss) @@ -283,29 +405,17 @@ int SrsStatistic::dumps_vhosts(stringstream& ss)
283 int ret = ERROR_SUCCESS; 405 int ret = ERROR_SUCCESS;
284 406
285 ss << SRS_JARRAY_START; 407 ss << SRS_JARRAY_START;
286 - std::map<std::string, SrsStatisticVhost*>::iterator it; 408 + std::map<int64_t, SrsStatisticVhost*>::iterator it;
287 for (it = vhosts.begin(); it != vhosts.end(); it++) { 409 for (it = vhosts.begin(); it != vhosts.end(); it++) {
288 SrsStatisticVhost* vhost = it->second; 410 SrsStatisticVhost* vhost = it->second;
  411 +
289 if (it != vhosts.begin()) { 412 if (it != vhosts.begin()) {
290 ss << SRS_JFIELD_CONT; 413 ss << SRS_JFIELD_CONT;
291 } 414 }
292 415
293 - // dumps the config of vhost.  
294 - bool hls_enabled = _srs_config->get_hls_enabled(vhost->vhost);  
295 -  
296 - ss << SRS_JOBJECT_START  
297 - << SRS_JFIELD_ORG("id", vhost->id) << SRS_JFIELD_CONT  
298 - << SRS_JFIELD_STR("name", vhost->vhost) << SRS_JFIELD_CONT  
299 - << SRS_JFIELD_ORG("send_bytes", vhost->kbps->get_send_bytes()) << SRS_JFIELD_CONT  
300 - << SRS_JFIELD_ORG("recv_bytes", vhost->kbps->get_recv_bytes()) << SRS_JFIELD_CONT  
301 - << SRS_JFIELD_NAME("hls") << SRS_JOBJECT_START  
302 - << SRS_JFIELD_BOOL("enabled", hls_enabled);  
303 - if (hls_enabled) {  
304 - ss << SRS_JFIELD_CONT;  
305 - ss << SRS_JFIELD_ORG("fragment", _srs_config->get_hls_fragment(vhost->vhost)); 416 + if ((ret = vhost->dumps(ss)) != ERROR_SUCCESS) {
  417 + return ret;
306 } 418 }
307 - ss << SRS_JOBJECT_END  
308 - << SRS_JOBJECT_END;  
309 } 419 }
310 ss << SRS_JARRAY_END; 420 ss << SRS_JARRAY_END;
311 421
@@ -317,61 +427,47 @@ int SrsStatistic::dumps_streams(stringstream& ss) @@ -317,61 +427,47 @@ int SrsStatistic::dumps_streams(stringstream& ss)
317 int ret = ERROR_SUCCESS; 427 int ret = ERROR_SUCCESS;
318 428
319 ss << SRS_JARRAY_START; 429 ss << SRS_JARRAY_START;
320 - std::map<std::string, SrsStatisticStream*>::iterator it; 430 + std::map<int64_t, SrsStatisticStream*>::iterator it;
321 for (it = streams.begin(); it != streams.end(); it++) { 431 for (it = streams.begin(); it != streams.end(); it++) {
322 SrsStatisticStream* stream = it->second; 432 SrsStatisticStream* stream = it->second;
  433 +
323 if (it != streams.begin()) { 434 if (it != streams.begin()) {
324 ss << SRS_JFIELD_CONT; 435 ss << SRS_JFIELD_CONT;
325 } 436 }
326 437
327 - int client_num = 0;  
328 - std::map<int, SrsStatisticClient*>::iterator it_client;  
329 - for (it_client = clients.begin(); it_client != clients.end(); it_client++) {  
330 - SrsStatisticClient* client = it_client->second;  
331 - if (client->stream == stream) {  
332 - client_num++;  
333 - } 438 + if ((ret = stream->dumps(ss)) != ERROR_SUCCESS) {
  439 + return ret;
334 } 440 }
  441 + }
  442 + ss << SRS_JARRAY_END;
  443 +
  444 + return ret;
  445 +}
335 446
336 - ss << SRS_JOBJECT_START  
337 - << SRS_JFIELD_ORG("id", stream->id) << SRS_JFIELD_CONT  
338 - << SRS_JFIELD_STR("name", stream->stream) << SRS_JFIELD_CONT  
339 - << SRS_JFIELD_ORG("vhost", stream->vhost->id) << SRS_JFIELD_CONT  
340 - << SRS_JFIELD_STR("app", stream->app) << SRS_JFIELD_CONT  
341 - << SRS_JFIELD_ORG("clients", client_num) << SRS_JFIELD_CONT  
342 - << SRS_JFIELD_ORG("send_bytes", stream->kbps->get_send_bytes()) << SRS_JFIELD_CONT  
343 - << SRS_JFIELD_ORG("recv_bytes", stream->kbps->get_recv_bytes()) << SRS_JFIELD_CONT  
344 - << SRS_JFIELD_ORG("live_ms", srs_get_system_time_ms()) << SRS_JFIELD_CONT  
345 - << SRS_JFIELD_STR("status", stream->status) << SRS_JFIELD_CONT;  
346 -  
347 - if (!stream->has_video) {  
348 - ss << SRS_JFIELD_NULL("video") << SRS_JFIELD_CONT;  
349 - } else {  
350 - ss << SRS_JFIELD_NAME("video")  
351 - << SRS_JOBJECT_START  
352 - << SRS_JFIELD_STR("codec", srs_codec_video2str(stream->vcodec)) << SRS_JFIELD_CONT  
353 - << SRS_JFIELD_STR("profile", srs_codec_avc_profile2str(stream->avc_profile)) << SRS_JFIELD_CONT  
354 - << SRS_JFIELD_ORG("level", srs_codec_avc_level2str(stream->avc_level))  
355 - << SRS_JOBJECT_END  
356 - << SRS_JFIELD_CONT; 447 +int SrsStatistic::dumps_clients(stringstream& ss, int start, int count)
  448 +{
  449 + int ret = ERROR_SUCCESS;
  450 +
  451 + ss << SRS_JARRAY_START;
  452 + std::map<int, SrsStatisticClient*>::iterator it = clients.begin();
  453 + for (int i = 0; i < count && it != clients.end(); it++) {
  454 + if (i < start) {
  455 + continue;
357 } 456 }
358 -  
359 - if (!stream->has_audio) {  
360 - ss << SRS_JFIELD_NULL("audio");  
361 - } else {  
362 - ss << SRS_JFIELD_NAME("audio")  
363 - << SRS_JOBJECT_START  
364 - << SRS_JFIELD_STR("codec", srs_codec_audio2str(stream->acodec)) << SRS_JFIELD_CONT  
365 - << SRS_JFIELD_ORG("sample_rate", (int)flv_sample_rates[stream->asample_rate]) << SRS_JFIELD_CONT  
366 - << SRS_JFIELD_ORG("channel", (int)stream->asound_type + 1) << SRS_JFIELD_CONT  
367 - << SRS_JFIELD_STR("profile", srs_codec_aac_object2str(stream->aac_object))  
368 - << SRS_JOBJECT_END; 457 +
  458 + SrsStatisticClient* client = it->second;
  459 +
  460 + if (i != start) {
  461 + ss << SRS_JFIELD_CONT;
369 } 462 }
370 463
371 - ss << SRS_JOBJECT_END; 464 + if ((ret = client->dumps(ss)) != ERROR_SUCCESS) {
  465 + return ret;
  466 + }
372 } 467 }
373 ss << SRS_JARRAY_END; 468 ss << SRS_JARRAY_END;
374 469
  470 +
375 return ret; 471 return ret;
376 } 472 }
377 473
@@ -380,14 +476,15 @@ SrsStatisticVhost* SrsStatistic::create_vhost(SrsRequest* req) @@ -380,14 +476,15 @@ SrsStatisticVhost* SrsStatistic::create_vhost(SrsRequest* req)
380 SrsStatisticVhost* vhost = NULL; 476 SrsStatisticVhost* vhost = NULL;
381 477
382 // create vhost if not exists. 478 // create vhost if not exists.
383 - if (vhosts.find(req->vhost) == vhosts.end()) { 479 + if (rvhosts.find(req->vhost) == rvhosts.end()) {
384 vhost = new SrsStatisticVhost(); 480 vhost = new SrsStatisticVhost();
385 vhost->vhost = req->vhost; 481 vhost->vhost = req->vhost;
386 - vhosts[req->vhost] = vhost; 482 + rvhosts[req->vhost] = vhost;
  483 + vhosts[vhost->id] = vhost;
387 return vhost; 484 return vhost;
388 } 485 }
389 486
390 - vhost = vhosts[req->vhost]; 487 + vhost = rvhosts[req->vhost];
391 488
392 return vhost; 489 return vhost;
393 } 490 }
@@ -399,17 +496,18 @@ SrsStatisticStream* SrsStatistic::create_stream(SrsStatisticVhost* vhost, SrsReq @@ -399,17 +496,18 @@ SrsStatisticStream* SrsStatistic::create_stream(SrsStatisticVhost* vhost, SrsReq
399 SrsStatisticStream* stream = NULL; 496 SrsStatisticStream* stream = NULL;
400 497
401 // create stream if not exists. 498 // create stream if not exists.
402 - if (streams.find(url) == streams.end()) { 499 + if (rstreams.find(url) == rstreams.end()) {
403 stream = new SrsStatisticStream(); 500 stream = new SrsStatisticStream();
404 stream->vhost = vhost; 501 stream->vhost = vhost;
405 stream->stream = req->stream; 502 stream->stream = req->stream;
406 stream->app = req->app; 503 stream->app = req->app;
407 stream->url = url; 504 stream->url = url;
408 - streams[url] = stream; 505 + rstreams[url] = stream;
  506 + streams[stream->id] = stream;
409 return stream; 507 return stream;
410 } 508 }
411 509
412 - stream = streams[url]; 510 + stream = rstreams[url];
413 511
414 return stream; 512 return stream;
415 } 513 }
@@ -47,6 +47,7 @@ struct SrsStatisticVhost @@ -47,6 +47,7 @@ struct SrsStatisticVhost
47 public: 47 public:
48 int64_t id; 48 int64_t id;
49 std::string vhost; 49 std::string vhost;
  50 + int nb_clients;
50 public: 51 public:
51 /** 52 /**
52 * vhost total kbps. 53 * vhost total kbps.
@@ -55,6 +56,8 @@ public: @@ -55,6 +56,8 @@ public:
55 public: 56 public:
56 SrsStatisticVhost(); 57 SrsStatisticVhost();
57 virtual ~SrsStatisticVhost(); 58 virtual ~SrsStatisticVhost();
  59 +public:
  60 + virtual int dumps(std::stringstream& ss);
58 }; 61 };
59 62
60 struct SrsStatisticStream 63 struct SrsStatisticStream
@@ -66,6 +69,7 @@ public: @@ -66,6 +69,7 @@ public:
66 std::string stream; 69 std::string stream;
67 std::string url; 70 std::string url;
68 std::string status; 71 std::string status;
  72 + int nb_clients;
69 public: 73 public:
70 /** 74 /**
71 * stream total kbps. 75 * stream total kbps.
@@ -94,6 +98,8 @@ public: @@ -94,6 +98,8 @@ public:
94 SrsStatisticStream(); 98 SrsStatisticStream();
95 virtual ~SrsStatisticStream(); 99 virtual ~SrsStatisticStream();
96 public: 100 public:
  101 + virtual int dumps(std::stringstream& ss);
  102 +public:
97 /** 103 /**
98 * publish the stream. 104 * publish the stream.
99 */ 105 */
@@ -109,6 +115,11 @@ struct SrsStatisticClient @@ -109,6 +115,11 @@ struct SrsStatisticClient
109 public: 115 public:
110 SrsStatisticStream* stream; 116 SrsStatisticStream* stream;
111 int id; 117 int id;
  118 +public:
  119 + SrsStatisticClient();
  120 + virtual ~SrsStatisticClient();
  121 +public:
  122 + virtual int dumps(std::stringstream& ss);
112 }; 123 };
113 124
114 class SrsStatistic 125 class SrsStatistic
@@ -117,10 +128,19 @@ private: @@ -117,10 +128,19 @@ private:
117 static SrsStatistic *_instance; 128 static SrsStatistic *_instance;
118 // the id to identify the sever. 129 // the id to identify the sever.
119 int64_t _server_id; 130 int64_t _server_id;
120 - // key: vhost name, value: vhost object.  
121 - std::map<std::string, SrsStatisticVhost*> vhosts;  
122 - // key: stream url, value: stream object.  
123 - std::map<std::string, SrsStatisticStream*> streams; 131 +private:
  132 + // key: vhost id, value: vhost object.
  133 + std::map<int64_t, SrsStatisticVhost*> vhosts;
  134 + // key: vhost url, value: vhost Object.
  135 + // @remark a fast index for vhosts.
  136 + std::map<std::string, SrsStatisticVhost*> rvhosts;
  137 +private:
  138 + // key: stream id, value: stream Object.
  139 + std::map<int64_t, SrsStatisticStream*> streams;
  140 + // key: stream url, value: stream Object.
  141 + // @remark a fast index for streams.
  142 + std::map<std::string, SrsStatisticStream*> rstreams;
  143 +private:
124 // key: client id, value: stream object. 144 // key: client id, value: stream object.
125 std::map<int, SrsStatisticClient*> clients; 145 std::map<int, SrsStatisticClient*> clients;
126 // server total kbps. 146 // server total kbps.
@@ -131,7 +151,10 @@ private: @@ -131,7 +151,10 @@ private:
131 public: 151 public:
132 static SrsStatistic* instance(); 152 static SrsStatistic* instance();
133 public: 153 public:
134 - virtual SrsStatisticStream* find_stream(int stream_id); 154 + virtual SrsStatisticVhost* find_vhost(int vid);
  155 + virtual SrsStatisticStream* find_stream(int sid);
  156 + virtual SrsStatisticClient* find_client(int cid);
  157 +public:
135 /** 158 /**
136 * when got video info for stream. 159 * when got video info for stream.
137 */ 160 */
@@ -192,6 +215,12 @@ public: @@ -192,6 +215,12 @@ public:
192 * dumps the streams to sstream in json. 215 * dumps the streams to sstream in json.
193 */ 216 */
194 virtual int dumps_streams(std::stringstream& ss); 217 virtual int dumps_streams(std::stringstream& ss);
  218 + /**
  219 + * dumps the clients to sstream in json.
  220 + * @param start the start index, from 0.
  221 + * @param count the max count of clients to dump.
  222 + */
  223 + virtual int dumps_clients(std::stringstream& ss, int start, int count);
195 private: 224 private:
196 virtual SrsStatisticVhost* create_vhost(SrsRequest* req); 225 virtual SrsStatisticVhost* create_vhost(SrsRequest* req);
197 virtual SrsStatisticStream* create_stream(SrsStatisticVhost* vhost, SrsRequest* req); 226 virtual SrsStatisticStream* create_stream(SrsStatisticVhost* vhost, SrsRequest* req);
@@ -43,7 +43,7 @@ using namespace std; @@ -43,7 +43,7 @@ using namespace std;
43 #include <srs_kernel_utility.hpp> 43 #include <srs_kernel_utility.hpp>
44 #include <srs_kernel_error.hpp> 44 #include <srs_kernel_error.hpp>
45 #include <srs_protocol_kbps.hpp> 45 #include <srs_protocol_kbps.hpp>
46 -#include <srs_app_json.hpp> 46 +#include <srs_protocol_json.hpp>
47 #include <srs_kernel_stream.hpp> 47 #include <srs_kernel_stream.hpp>
48 48
49 // the longest time to wait for a process to quit. 49 // the longest time to wait for a process to quit.
@@ -32,6 +32,7 @@ using namespace std; @@ -32,6 +32,7 @@ using namespace std;
32 #include <srs_kernel_log.hpp> 32 #include <srs_kernel_log.hpp>
33 #include <srs_kernel_utility.hpp> 33 #include <srs_kernel_utility.hpp>
34 #include <srs_kernel_file.hpp> 34 #include <srs_kernel_file.hpp>
  35 +#include <srs_protocol_json.hpp>
35 36
36 #define SRS_HTTP_DEFAULT_PAGE "index.html" 37 #define SRS_HTTP_DEFAULT_PAGE "index.html"
37 38
@@ -143,6 +144,17 @@ int srs_http_response_json(ISrsHttpResponseWriter* w, string data) @@ -143,6 +144,17 @@ int srs_http_response_json(ISrsHttpResponseWriter* w, string data)
143 return w->write((char*)data.data(), (int)data.length()); 144 return w->write((char*)data.data(), (int)data.length());
144 } 145 }
145 146
  147 +int srs_http_response_code(ISrsHttpResponseWriter* w, int code)
  148 +{
  149 + std::stringstream ss;
  150 +
  151 + ss << SRS_JOBJECT_START
  152 + << SRS_JFIELD_ERROR(code)
  153 + << SRS_JOBJECT_END;
  154 +
  155 + return srs_http_response_json(w, ss.str());
  156 +}
  157 +
146 SrsHttpHeader::SrsHttpHeader() 158 SrsHttpHeader::SrsHttpHeader()
147 { 159 {
148 } 160 }
@@ -78,6 +78,11 @@ class ISrsHttpResponseWriter; @@ -78,6 +78,11 @@ class ISrsHttpResponseWriter;
78 78
79 // helper function: response in json format. 79 // helper function: response in json format.
80 extern int srs_http_response_json(ISrsHttpResponseWriter* w, std::string data); 80 extern int srs_http_response_json(ISrsHttpResponseWriter* w, std::string data);
  81 +/**
  82 + * response a typical code object, for example:
  83 + * {code : 100}
  84 + */
  85 +extern int srs_http_response_code(ISrsHttpResponseWriter* w, int code);
81 86
82 // get the status text of code. 87 // get the status text of code.
83 extern std::string srs_generate_http_status_text(int status); 88 extern std::string srs_generate_http_status_text(int status);
@@ -488,6 +493,14 @@ public: @@ -488,6 +493,14 @@ public:
488 virtual std::string host() = 0; 493 virtual std::string host() = 0;
489 virtual std::string path() = 0; 494 virtual std::string path() = 0;
490 virtual std::string ext() = 0; 495 virtual std::string ext() = 0;
  496 + /**
  497 + * get the RESTful id,
  498 + * for example, pattern is /api/v1/streams, path is /api/v1/streams/100,
  499 + * then the rest id is 100.
  500 + * @param pattern the handler pattern which will serve the request.
  501 + * @return the REST id; -1 if not matched.
  502 + */
  503 + virtual int parse_rest_id(std::string pattern) = 0;
491 public: 504 public:
492 /** 505 /**
493 * read body to string. 506 * read body to string.
@@ -21,7 +21,7 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN @@ -21,7 +21,7 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */ 22 */
23 23
24 -#include <srs_app_json.hpp> 24 +#include <srs_protocol_json.hpp>
25 25
26 using namespace std; 26 using namespace std;
27 27
@@ -21,11 +21,11 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN @@ -21,11 +21,11 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */ 22 */
23 23
24 -#ifndef SRS_APP_JSON_HPP  
25 -#define SRS_APP_JSON_HPP 24 +#ifndef SRS_PROTOCOL_JSON_HPP
  25 +#define SRS_PROTOCOL_JSON_HPP
26 26
27 /* 27 /*
28 -#include <srs_app_json.hpp> 28 +#include <srs_protocol_json.hpp>
29 */ 29 */
30 #include <srs_core.hpp> 30 #include <srs_core.hpp>
31 31